MySQL InnoDB 存储引擎使用 MVCC 机制来提供一致性非锁定读((consistent nonlocking read).
为方便演示, 下面图中:
黄色部分表示重做日志(UNDO LOG)
绿色部分表示正常数据
红色部分表示已删除数据
假设现在有表 TB001, 其表结构为:
- CREATE TABLE `TB001` (
- `ID` VARCHAR(20) NOT NULL,
- `C1` VARCHAR(20) NOT NULL,
- `C2` VARCHAR(20) NOT NULL,
- PRIMARY KEY (`ID`),
- KEY `IDX_C1` (`C1`)
- ) ENGINE=INNODB DEFAULT CHARSET=utf8;
步骤 1: 事务 TX1001 在 12:00 时插入一条记录
- INSERT INTO TB001(ID,C1,C2)
- VALUES('AA0001','BB0001','CC0001');
在主键索引 / 二级索引 / 重做日志中数据如下:
步骤 2: 事务 TX1003 更新数据但未提交:
- UPDATE TB001
- SET C2='CC1111'
- WHERE ID='AA0001'
步骤 3: 事务 TX99999999999 开启可重复读事务, 开启事务执行第一条 SQL 语句时:
A, 当前所有 TX1001 及之前事务都已提交, 则事务低水位线为 TX1001
B, 当前写事务最大 ID 为 TX1004, 则事务高水位线 TX1005
C, 事务 TX1002 和 TX1004 都已提交
D, 事务 TX1003 未提交, 则活跃事务集为(TX1003)
步骤 4: 事务 TX1003 提交更新, 更新后在主键索引 / 二级索引 / 重做日志中数据如下:
步骤 5: 事务 TX1005 执行更新并提交:
- UPDATE TB001
- SET C1='BB1111'
- WHERE ID='AA0001'
更新后在主键索引 / 二级索引 / 重做日志中数据如下:
步骤 6: 事务 TX1007 执行删除并提交:
- DELETE FROM TB0001
- WHERE ID='AA0001'
更新后在主键索引 / 二级索引 / 重做日志中数据如下:
步骤 7: 事务 TX99999999999 执行查询:
- SELECT *
- FROM TB001
- WHERE C1='BB0001'
查询如何执行呢?
1, 首先当前二级索引 IDX_C1 上有两条已标记为删除的记录 (C1=BB0001,ID=AA001) 和(C1=BB1111,ID=AA0001)
2, 通过在索引 IDX_C1 按 C1='BB0001'查找可以找到已标记为删除的记录(C1=BB0001,ID=AA001)
3, 根据索引记录的 ID=AA0001 在主键索引上找到已删除记录(ID=AA0001,C1=BB1111,C2=CC1111,TRX=TX1007,RBP=RP1007)
4, 步骤 3 中找到的记录版本为 TX1007, 超过事务 TX99999999999 的高水位线 TX1005, 版本不满足, 按照回滚指针 RP1007 去 UNDO 日志中查找
5, 在 UNDO 日志中找到(TX1005,RPT=RP1005,ID=AA001,C1=BB1111,C2=CC11111), 和步骤 3 中记录合并得(TX1005,RPT=RP1005,ID=AA001,C1=BB1111,C2=CC11111)
6, 步骤 5 找到记录版本为 TX1005, 等于事务 TX99999999999 的高水位线, 版本不满足, 按照回滚指针 RP1005 去 UNDO 日志中查找上一版本
7, 在 UNDO 日志中找到(TX1003,RPT=RP1003,ID=AA001,C1=BB0001), 和步骤 5 中记录合并得(TX1003,RPT=RP1003,ID=AA001,C1=BB0001,C2=CC11111)
8, 步骤 5 找到记录版本为 TX1003, 虽然高于 "低水位线" 和低于 "高水位线", 但在活跃事务集 (TX1003) 中, 版本不满足, 按照回滚指针 RP1003 去 UNDO 日志中查找上一版本
9, 在 UNDO 日志中找到(TX1001,RPT=RP1001,ID=AA001,C2=CC001), 与步骤 7 中记录合并得(TX1001,RPT=RP1001,C1=BB0001,ID=AA001,C2=CC001)
10, 步骤 9 找到的记录版本为 TX1001 等于 "低水位线", 版本满足, 将记录 (TX1001,RPT=RP1001,C1=BB0001,ID=AA001,C2=CC001) 返回给查询客户端.
11, 查询结束.
MySQL InnoDB Engine-- 多版本一致性视图(MVCC)
来源: http://www.bubuko.com/infodetail-3379406.html