diff --git a/mysql/mysql文档/mysql_事务.md b/mysql/mysql文档/mysql_事务.md index 87f7922..5e42e10 100644 --- a/mysql/mysql文档/mysql_事务.md +++ b/mysql/mysql文档/mysql_事务.md @@ -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,结构如下: + +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 Node:undo 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,示例如下: + +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。 @@ -400,9 +438,4 @@ delete from t where a=1; 是否可以对记录进行物理删除由purge来决定,若某行记录不被其他任何事务引用,可以执行物理delete操作。 #### history -innodb存储引擎中维护了一个history列表,其`根据事务的提交顺序`对undo log进行链接,`在history list中,先提交的事务其undo log位于history list的尾端`。 - - - - - +innodb存储引擎中维护了一个history列表,其`根据事务的提交顺序`对undo log进行链接,`在history list中,先提交的事务其undo log位于history list的尾端`。 \ No newline at end of file