前言
Undo log
是InnoDB MVCC
事务特性的重要组成部分
,同时可以提供数据回滚
。当我们对记录做了变更操作
时就会产生undo记录
,Undo记录默认被记录到系统表空间(ibdata)中,但从5.6
开始,也可以使用独立的Undo 表空间
。
Undo记录中存储的是老版本数据
,当一个旧的事务
需要读取数据
时,为了能读取到老版本的数据,需要顺着undo链
找到满足其可见性的记录
。当版本链很长时,通常可以认为这是个比较耗时的操作(例如bug#69812)。如果因为某些原因导致事务失败或回滚
了,可以借助
该undo进行回滚
。
大多数对数据的变更操作
包括INSERT/DELETE/UPDATE
,其中INSERT
操作在事务提交前只对当前事务可见,因此产生的Undo日志可以在事务提交后直接删除
(谁会对刚插入的数据有可见性需求呢!!),而对于UPDATE/DELETE
则需要维护多版本
信息,在InnoDB里,UPDATE和DELETE操作产生的Undo日志被归成一类,即update_undo
。
本文是对整个Undo生命周期过程的阐述,代码分析基于当前最新的MySQL5.7版本。
Undo Log
undo log和redo log记录物理日志
不一样,它是逻辑日志
。可以认为当delete
一条记录时,undo log中会记录一条对应的insert
记录,反之亦然,当update
一条记录时,它记录一条对应相反的update
记录。当执行rollback时,就可以从undo log中的逻辑记录读取到相应
的内容并进行回滚
。有时候应用到行版本控制
的时候,也是通过undo log来实现的:当读取的某一行被其他事务锁定时,它可以从undo log中分析出该行记录的历史数据
是什么,让用户实现非锁定一致性
读取。
为了保证事务并发操作时,在写各自的undo log时不产生冲突,InnoDB采用回滚段
的方式来维护undo log的并发写入和持久化。回滚段实际上是一种 Undo 文件组织方式
,每个回滚段
由1024
个undo log slot
组成。每个undo操作
在记录的时候占用一个undo log slot
。另外,undo log也会产生redo log
,因为undo log也要实现持久性
保护。
存储
MySQL5.5以后可以支持128个rollback segment,即支持128*1024个undo操作,还可以通过变量innodb_undo_logs
(5.6版本以前该变量是 innodb_rollback_segments )自定义
多少个rollback segment
,默认值为128
。undo log默认存放
在共享表空间
中。如果开启了innodb_file_per_table
,将放在每个表的.ibd
文件中。
在MySQL5.6中,undo的存放位置还可以通过变量 innodb_undo_directory
来自定义存放目录
,默认值为"."表示datadir。
默认rollback segment全部写在一个文件中,但可以通过设置变量 innodb_undo_tablespaces
平均分配到多少个文件中。该变量默认值为0
,即全部写入一个表空间文件
。该变量为静态变量,只能在数据库示例停止状态下修改,如写入配置文件或启动时带上对应参数。但是innodb存储引擎在启动过程中提示,不建议修改为非0
的值
delete/update操作的内部机制
当事务提交
的时候,innodb不会立即删除
undo log,因为后续
还可能会用到undo log,如隔离级别为repeatable read
时,事务读取
的都是开启事务时
的最新提交行版本
,只要该事务不结束
,该行版本就不能删除
,即undo log不能删除。
但是在事务提交
的时候,会将该事务对应的undo log放入到删除列表
中,未来通过purge来删除
。并且提交事务时,还会判断undo log分配的页是否可以重用
,如果可以重用,则会分配给后面来的事务,避免
为每个独立的事务分配独立的undo log页
而浪费存储空间和性能
。
通过undo log记录delete和update操作的结果发现:(insert操作无需分析,就是插入行而已)
delete
操作实际上不会直接删除
,而是将delete对象打上delete flag
,标记为删除,最终
的删除操作是purge
线程完成的。update
分为两种
情况:update的列是否是主键列
。- 如果
不是主键列
,在undo log中直接反向记录
是如何update
的。即update是直接进行的。 - 如果
是主键列
,update分两部执行:先删除
该行,再插入
一行目标行。
- 如果
参考undo数据结构:http://mysql.taobao.org/monthly/2015/04/01/
本文参考:https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html