undo log是mysql中比较重要的事务日志之一,顾名思义,undo log是一种用于撤销回退的日志,在事务没提交之前,MySQL会先记录更新前的数据到 undo log日志文件里面,当事务回滚时或者数据库崩溃时,可以利用 undo log来进行回退。
在更新数据之前,MySQL会提前生成undo log日志,当事务提交的时候,并不会立即删除undo log,因为后面可能需要进行回滚操作,要执行回滚(rollback)操作时,从缓存中读取数据。undo log日志的删除是通过通过后台purge线程进行回收处理的。
下面这个图是个好图,能更好的帮助大家理解,放大看一下就好理解了。
undo log是InnoDB事务特性的重要组成部分。当对记录做增删改操作就会产生undo记录,undo记录会记录到单独的表空间中。
首先,在MySQL5.6之前所有的undo log全部存储在系统表空间中(ibdata1);但是从5.6开始也可以使用独立表空间来存储undo log。
当前版本InnoDB默认有两个undo tablespace,也可以使用CREATE UNDO TABLESPACE
语句动态添加,最大128个;每个undo tablespace至多可以有TRX_SYS_N_RSEGS(128)
个回滚段。
InnoDB在undo tablespace中使用回滚段来组织undo log。同时为了保证事务的并发操作,在写undo log时不产生冲突,InnoDB使用 回滚段 来维护undo log的并发写入和持久化;而每个回滚段 又有多个undo log slot。通常通过Rollback Segment Header来管理回滚段,Rollback Segment Header通常在回滚段的第一个页,具体结构如下:
Rollback Segment Header里面最重要的两部分就是history list与undo slot directory。
其中history list把所有已经提交但还没有被purge事务的undo log串联起来,purge线程可以通过此list对没有事务使用的undo log进行purge。
每个事务在需要记录undo log时都会申请一个或两个slot
(insert/update分开),同时把事务的第一个undo page放入对应slot中;所以理论上InnoDB允许的最大事务并发数为128(undo tablespace
) * 128(Rollback Segment
) * 1024(TRX_RSEG_UNDO_SLOTS
)。下面我们进一步介绍undo log在磁盘上如何记录。
说道这里,基本上就理解差不多了,就不往下拓展了,没必要。知道是用于回滚的就行了。
有兴趣的可以继续深入探讨啊,我只是知识的使用者,不是创造者。希望多少能帮助到大家的面试。