MVCC 原理

简介: MVCC 原理

MVCC 原理



事务的4个隔离级别


  • 读未提交
  • 读已提交
  • 可重复读
  • 串行化


640.png


  • 什么是脏读

简单说,读了一条未提交的数据

  • 什么是不可重复读?

一个事务读取了另外一个事务修改后记录 强调的是 update 和delete ,只需要锁住满足条件的记录即可

  • 什么是幻读

一个事务读取了另外一个事务插入的数据,强调的是 insert ,要锁住满足条件及相近的记录。

MYSQL 中默认的隔离级别是可重复读,可解决脏读和不可重复读的问题。但是不能解决幻读的问题。 Oracle 默认的是Read Commit 读已提交,可以避免脏读的问题。


MVCC 用来解决什么问题?


一般解决不可重复读和幻读问题,是采用锁机制实现,有没有一种乐观锁的问题去处理,可以采用 MVCC 机制的设计,可以用来解决这个问题。取代行锁,降低系统开销。


MVCC 是啥?


MVCC 的英文全称是 Multiversion Concurrency Control ,中文意思是多版本并发控制技术。原理是,通过数据行的多个版本管理来实现数据库的并发控制,简单来说就是保存数据的历史版本。可以通过比较版本号决定数据是否显示出来。读取数据的时候不需要加锁可以保证事务的隔离效果。


MVCC 可以解决什么问题?


  • 读写之间阻塞的问题,通过 MVCC 可以让读写互相不阻塞,读不相互阻塞,写不阻塞读,这样可以提升数据并发处理能力。
  • 降低了死锁的概率,这个是因为 MVCC 采用了乐观锁的方式,读取数据时,不需要加锁,写操作,只需要锁定必要的行。
  • 解决了一致性读的问题,当我们朝向某个数据库在时间点的快照是,只能看到这个时间点之前事务提交更新的结果,不能看到时间点之后事务提交的更新结果。


什么是快照读?


快照读,读取的是快照数据,不加锁的简单 Select 都属于快照读.


SELECT * FROM player WHERE ...

什么是当前读?


当前读就是读的是最新数据,而不是历史的数据,加锁的 SELECT,或者对数据进行增删改都会进行当前读。


SELECT * FROM player LOCK IN SHARE MODE;
SELECT FROM player FOR UPDATE;
INSERT INTO player values ...
DELETE FROM player WHERE ...
UPDATE player SET ...

InnoDB 的 MVCC 是如何实现的?


InnoDB 是如何存储记录多个版本的?这些数据是 事务版本号,行记录中的隐藏列和Undo Log。


事务版本号


每开启一个日志,都会从数据库中获得一个事务ID(也称为事务版本号),这个事务 ID 是自增的,通过 ID 大小,可以判断事务的时间顺序。


行记录的隐藏列


  1. row_id :隐藏的行 ID ,用来生成默认的聚集索引。如果创建数据表时没指定聚集索引,这时 InnoDB 就会用这个隐藏 ID 来创建聚集索引。采用聚集索引的方式可以提升数据的查找效率。
  2. trx_id: 操作这个数据事务 ID ,也就是最后一个对数据插入或者更新的事务 ID 。
  3. roll_ptr:回滚指针,指向这个记录的 Undo Log 信息。


640.png

Undo Log

InnoDB 将行记录快照保存在 Undo Log 里。


640.png


数据行通过快照记录都通过链表的结构的串联了起来,每个快照都保存了 trx_id 事务ID,如果要找到历史快照,就可以通过遍历回滚指针的方式进行查找。


Read View 是啥?


如果一个事务要查询行记录,需要读取哪个版本的行记录呢?Read View 就是来解决这个问题的。Read View 可以帮助我们解决可见性问题。Read View 保存了当前事务开启时所有活跃的事务列表。换个角度,可以理解为: Read View 保存了不应该让这个事务看到的其他事务 ID 列表。


  1. trx_ids 系统当前正在活跃的事务ID集合。
  2. low_limit_id ,活跃事务的最大的事务 ID。
  3. up_limit_id 活跃的事务中最小的事务 ID。
  4. creator_trx_id,创建这个 ReadView 的事务ID。


ReadView

640.png


如果当前事务的 creator_trx_id 想要读取某个行记录,这个行记录ID 的trx_id ,这样会有以下的情况:


  • 如果 trx_id < 活跃的最小事务ID(up_limit_id),也就是说这个行记录在这些活跃的事务创建前就已经提交了,那么这个行记录对当前事务是可见的。
  • 如果trx_id > 活跃的最大事务ID(low_limit_id),这个说明行记录在这些活跃的事务之后才创建,说明这个行记录对当前事务是不可见的。
  • 如果 up_limit_id < trx_id <low_limit_id,说明该记录需要在 trx_ids 集合中,可能还处于活跃状态,因此我们需要在 trx_ids 集合中遍历 ,如果trx_id 存在于 trx_ids 集合中,证明这个事务 trx_id 还处于活跃状态,不可见,否则 ,trx_id 不存在于 trx_ids 集合中,说明事务trx_id 已经提交了,这行记录是可见的。


如何查询一条记录


  1. 获取事务自己的版本号,即 事务ID
  2. 获取 Read View
  3. 查询得到的数据,然后 Read View 中的事务版本号进行比较。
  4. 如果不符合 ReadView 规则, 那么就需要 UndoLog 中历史快照;
  5. 最后返回符合规则的数据

InnoDB 实现多版本控制 (MVCC)是通过 ReadView+ UndoLog 实现的,UndoLog 保存了历史快照,ReadView 规则帮助判断当前版本的数据是否可见。


总结


  • 如果事务隔离级别是 ReadCommit ,一个事务的每一次 Select 都会去查一次ReadView ,每次查询的Read View 不同,就可能会造成不可重复读或者幻读的情况。
  • 如果事务的隔离级别是可重读,为了避免不可重读读,一个事务只在第一次 Select 的时候会获取一次Read View ,然后后面索引的Select 会复用这个 ReadView.
相关文章
|
安全 前端开发 网络安全
【Azure App Service】访问App Service应用报错 SSL: WRONG_VERSION_NUMBER(上海蓝云阻断页)
在Azure App Service上部署的应用遇到`SSL: WRONG_VERSION_NUMBER`错误。问题可能由不兼容的TLS版本引起,但即使将最小入站TLS版本改为1.2,问题仍存在。实际原因是上海蓝云的阻断页面,表明网站未完成ICP备案或有安全规定限制。解决方案包括:1) 对App Service绑定自定义域名并进行ICP备案,或2) 使用Application Gateway处理公网请求。在复杂环境中,需仔细排查和适配规则。
497 11
|
数据采集 存储 NoSQL
提高爬虫性能的 5 个关键技巧:从并发到异步执行
本文介绍了提高网络爬虫性能的五个关键技巧:并发请求、异步执行、使用代理IP、限制请求频率与休眠时间、优化数据提取与存储。结合拼多多的实际案例,展示了如何通过这些技术优化爬虫效率,确保数据采集的高效性和稳定性。
866 0
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的在线电影票购买系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的在线电影票购买系统的详细设计和实现(源码+lw+部署文档+讲解等)
191 1
|
安全 Java 调度
Java Queue深度解析:LinkedList为何成为队列的最佳实践?
【6月更文挑战第18天】Java的`LinkedList`适合作为队列,因其双向链表结构支持O(1)的头尾操作。非线程安全的`LinkedList`在单线程环境下效率高,多线程时可通过`Collections.synchronizedList`封装。此外,它还可兼做栈和双端队列,提供任务调度的高效解决方案。
259 3
|
算法 关系型数据库 MySQL
深入理解MySQL中的JOIN算法
深入理解MySQL中的JOIN算法
|
人工智能 文字识别 自然语言处理
准确高效的TextIn文档解析:一项开发痛点的解决方案
企业在构建知识库问答系统时面临挑战,尤其是处理扫描文档和手写内容。传统OCR工具和开源方法在准确性和速度上不足。专业长文档解析成为关键,其中TextIn平台的文档解析服务脱颖而出。该服务能快速将PDF转为Markdown,提高处理速度和准确性,尤其适合处理复杂布局的长文档。通过实际测试,TextIn能有效增强LLM问答系统的性能,解决无法正确解析的问题。目前TextIn处于内测阶段,提供每周7000页的免费试用额度,开发者可通过其官网或“合研社”公众号了解更多信息和获取接口文档。
|
图形学
【用unity实现100个游戏之15】开发一个类保卫萝卜的Unity2D塔防游戏3(附项目源码)
【用unity实现100个游戏之15】开发一个类保卫萝卜的Unity2D塔防游戏3(附项目源码)
669 0
|
JavaScript 安全 Java
Spring Boot中的版本兼容性处理
Spring Boot中的版本兼容性处理
1156 0
|
存储 NoSQL 测试技术
记一次业务系统登录报错404问题排查与解决实践
业务系统登录报错404问题排查与解决实践过程记录总结
记一次业务系统登录报错404问题排查与解决实践

热门文章

最新文章