| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> 深入理解 MySQL 的 MVCC 机制 -> 正文阅读 |
|
[大数据]深入理解 MySQL 的 MVCC 机制 |
undo log undo log是回滚日志,有两个作用:提供回滚操作和多个行版本控制(MVCC)。 在数据修改的时候,不仅记录了redo,还记录了相对应的undo,如果因为某些原因导致事务失败或回滚了,可以借助该undo进行回滚。 undo log和redo log记录物理日志不一样。undo log主要记录的是数据的逻辑变化,它是逻辑日志。 可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。 当执行rollback时,就可以从undo log中的逻辑记录读取到相应的内容并进行回滚。 多行版本控制(MVCC)的时候,也是通过undo log来实现的: 当读取的某一行被其他事务锁定时,它可以从undo log中分析出该行记录以前的数据是什么,从而提供该行版本信息,让用户实现非锁定一致性读取。 MySQL 事务隔离级别除了redo log 和undo log 以外,另一个你在学习MVCC 之前不得不了解的知识,就是隔离级别。隔离级别是相当基础的知识,所以这里我们快速复习下就好。 ? 注:MySQL 的默认隔离级别为 并且在MySQL中 repeatable-read级别还可以处理幻读,这是 MySQL独有的 next-keylock 实现的。 不同的数据库厂商对 SQL标准 中规定的四种隔离级别支持不一样: Oracle 就只支持 read-committed 和 serializable 隔离级别。 MVCC 只在read-committed和repeatable-read 两个隔离级别下工作,其他两个隔离级别: read-uncommitted,总是读取最新的数据行,而不会读当前事务版本的数据行。 serializable,则会对所有读取的行都加锁, 和 MVCC不兼容。 MVCC原理版本链MySQL的每行记录逻辑上其实是一个链表。 MySQL行记录中除了记录业务数据外,还有隐藏的 trx_id 和 roll_ptr
? 当然,这个链表存在于 undo log 中,和最新版本的数据不在一起。 每次更新后,都会将旧值放到一条 undo log 中,就算是该记录的一个旧版本,随着更新次数的增多,所有的版本都会被roll_ptr 属性连接成一个链表,我们把这个链表称之为版本链,版本链的头节点就是当前记录最新的值。 另外,每个版本中还包含生成该版本时对应的 事务id(trx_id),这个信息很重要,我们稍后就会用到。 ReadView说完了undo log,再来说说 ReadView。前面我们说过: 对于使用 read-committed 和 repeatable-read 隔离级别的事务来说,都必须保证读到已经提交了的事务修改过的记录,也就是说假如另一个事务已经修改了记录但是尚未提交,是不能直接读取最新版本的记录的。 核心问题就是:需要判断一下,版本链中的哪个版本是当前事务可见的。 为此,InnoDB提出了一个ReadView的概念,这个ReadView 中有个 id 列表 继续用之前的例子来理解一下 ReadView 和 trx_ids。 提交trx_id是2的记录后,接着有一个trx_id为3的事务,修改 name为源宝3,但是事务还没提交。
则此时的版本链是︰ 显然,此时的 trx_ids 为 [ 3 ] ? 如果另一个事务查询id为1的记录,因为trx_ids当前只有事务 trx_id 为 3 的事务,而 trx_ids 的意义是记录未完成的事务。在这里,事务未完成,所以该条记录不可见,继续查询下—条,结果返回源宝2。 这时我把 trx_id 为 3 的事务提交了,并且新建了一个 trx_id 为 4 也修改 id 为 1 的记录name=源宝4,并且不提交事务。 update user set name = '源宝 4 ' where id = 1 这时候版本链就是︰ ? read-committed —— 每次查询数据前都生成一个 ReadView trx_ids 将更新为[ 4 ],版本链通过 trx_id 对比查找到的结果就是源宝3。 repeatable-read —— 在第一次查询数据时生成一个 ReadView,之后的读都复用之前的。 不会有重建的 ReadView , trx_ids 还是 [ 3 ],MySQL 认为事务3未完成,所以 select 的结果是源宝2。第2次 select 结果和第1次一样,所以叫可重复读。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 13:20:43- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |