undo log是mysql中比较重要的事务日志之一,顾名思义,undo log是一种用于撤销回退的日志,在事务没提交之前,MySQL会先记录更新前的数据到 undo log日志文件里面,当事务回滚时或者数据库崩溃时,可以利用 undo log来进行回退。
在MySQL中,undo log日志的作用主要有两个:
1、提供回滚操作【undo log实现事务的原子性】
我们在进行数据更新操作的时候,不仅会记录redo log,还会记录undo log,如果因为某些原因导致事务回滚,那么这个时候MySQL就要执行回滚(rollback)操作,利用undo log将数据恢复到事务开始之前的状态。
如我们执行下面一条删除语句:

如上图,可以看到,undo log日志里面不仅存放着数据更新前的记录,还记录着RowID、事务ID、回滚指针。其中事务ID每次递增,回滚指针第一次如果是insert语句的话,回滚指针为NULL,第二次update之后的undo log的回滚指针就会指向刚刚那一条undo log日志,依次类推,就会形成一条undo log的回滚链,方便找到该条记录的历史版本。
在更新数据之前,MySQL会提前生成undo log日志,当事务提交的时候,并不会立即删除undo log,因为后面可能需要进行回滚操作,要执行回滚(rollback)操作时,从缓存中读取数据。undo log日志的删除是通过通过后台purge线程进行回收处理的。
同样,通过一张图来理解undo log的工作原理。

如上图:
1、事务A执行update操作,此时事务还没提交,会将数据进行备份到对应的undo buffer,然后由undo buffer持久化到磁盘中的undo log文件中,此时undo log保存了未提交之前的操作日志,接着将操作的数据,也就是Teacher表的数据持久保存到InnoDB的数据文件IBD。
2、此时事务B进行查询操作,直接从undo buffer缓存中进行读取,这时事务A还没提交事务,如果要回滚(rollback)事务,是不读磁盘的,先直接从undo buffer缓存读取。
用undo log实现原子性和持久化的事务的简化过程:
假设有A、B两个数据,值分别为1,2。
之所以能同时保证原子性和持久化,是因为以下特点:
缺陷:每个事务提交前将数据和undo log写入磁盘,这样会导致大量的磁盘IO,因此性能较差。 如果能够将数据缓存一段时间,就能减少IO提高性能,但是这样就会失去事务的持久性。
undo日志属于逻辑日志,redo是物理日志,所谓逻辑日志是undo log是记录一个操作过程,不会物理删除undo log,sql执行delete或者update操作都会记录一条undo日志。
指定undo log日志的存储目录,默认值为./。
在MySQL5.6版本之后,可以通过此参数自定义多少个rollback segment,默认值为128。
指定undo log平均分配到多少个表空间文件中,默认值为0,即全部写入一个文件中。不建议修改为非0值,我们直接使用默认值即可。
在InnoDB存储引擎中,在启动日志中也会提示:不建议修改 innodb_undo_tablespaces为非0的值。
附录:参考资料
《MySQL技术内幕(第5版)》
到此这篇关于MySQL回滚日志(undo log)的文章就介绍到这了,更多相关MySQL回滚日志undo log内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!