doc: 阅读mysql undo log文档

This commit is contained in:
asahi
2025-08-05 21:05:17 +08:00
parent d3e1f2b5c3
commit caf011a1fc

View File

@@ -379,6 +379,44 @@ undo log中主要存储旧的col值用于在回滚或mvcc时为undo操作提
- `TRX_UNDO_DEL_MARK_REC`类型的记录,对应`将原记录标记为删除`的回滚
- `TRX_UNDO_INSERT_REC`类型的记录,标记对`新纪录`的插入回滚
> 对于insert/update undo log record每条undo record均只针对一条记录。故而当一条sql语句对多行记录进行删除/更改时会生成多条insert/update undo record。
### undo log组织形式
上述内容介绍了undo log record的格式为了对undo log records进行高效率的访问和管理undo log record应当以适当的形式被组织。
#### undo log的逻辑组织方式
每个事务都会修改一系列的records并产生相应的undo log records事务对应的undo log由这些undo log records组成。
undo log除了由undo log record组成外其还包含了一个undo log header结构如下
<img src="https://yqintl.alicdn.com/4eeedc0d845c26417e570782cb01824f98d7dcd3.png" alt="3" title="3">
如上述结构所示undo log header中包含如下部分
- trx id: 事务id用于标识产生该undo log的事务
- trx no: trx no用于表示事务的提交顺序header中trx no并非一定有值在事务提交前该field未定义当事务提交后该field会被填充
- `trx no`用于判断`是否purge应当被执行`
- delete mark: 判断是否undo log中存在`TRX_UNDO_DEL_MARK_REC`类型的undo record从而在purge时避免扫描
- log start offset: 该field记录了undo log header结尾的位置便于后续对undo log header进行拓展
- History List Nodeundo log通过该结构挂载到History List中
> 故而undo log就粒度存在两种结构
> - undo record: 记录每行数据的历史版本行数据通过维护undo record chain来还原历史版本
> - undo log: 针对事务级别每个undo log由undo log header和多个undo records组成并且undo log会根据事务的提交顺序被挂载到history list中
##### record versions
如果多个事务针对同一条record进行了修改串行那么每个事务对record造成的修改都会生成不同的版本version不同的版本之间通过链表进行链接用于后续的mvcc示例如下
<img src="https://yqintl.alicdn.com/ee4f6e18f7fb39e128e06d26daed3432ff203390.png" alt="4" title="4">
如上所示,事务`I, J, K`都对`id=1`的记录进行了操作,其操作顺序如下:
1. 事务I插入了id为1的记录并且将`a`的值设置为A
2. 事务J将id为1记录的`a`修改为了B
3. 事务K将id为1记录的`a`修改为了C
事务I, J, K都有其事务对应的undo log并且每个undo log都拥有对应的undo log header和undo log records。
通过index中的记录及其rollptr引用的链表可以对记录关联的`I, J, K`三个版本进行还原。
### purge
`t`中,`a`为聚簇索引,`b`为辅助索引若执行如下sql
```sql
@@ -386,7 +424,7 @@ delete from t where a=1;
```
上述语句造成的修改如下:
- 将主键`a`为1的记录标记为delete将记录`delete flag`设置为1聚簇索引中的数据并没有被实际物理删除`且会生成针对聚簇索引的undo log`
- 将主键`a`为1的记录标记为delete将记录`delete flag`设置为1聚簇索引中的数据并没有被实际物理删除`且会生成针对聚簇索引的undo log`。当事务发生回滚时,仅需将`delete flag`重新设置为0即可完成对删除的回滚。
- 对于辅助索引中满足`a=1`的记录,同样不会做任何处理,`也不会产生针对辅助索引的undo log`
> undo log只针对聚簇索引生成对于辅助索引的变化并不会生成对应的undo log。
@@ -401,8 +439,3 @@ delete from t where a=1;
#### history
innodb存储引擎中维护了一个history列表`根据事务的提交顺序`对undo log进行链接`在history list中先提交的事务其undo log位于history list的尾端`