今天和大家分享一下undo log日志的知识点
1.什么是undo log?
撤销日志,在数据库事务开始之前,mysql会去记录更新前的数据到undo log文件中。如果事务回滚或者数据库崩溃时,可以利用undo log日志中记录的日志信息进行回退。同时也可以提供多版本并发控制下的读(mvcc)。(具体的mvcc实现机制详解看这篇博客)
2.undo log生命周期
undo log产生: 在事务开始之前生成
undo log销毁: 当事务提交之后,undo log并不能立马被删除,而是放入待清理的链表,由purge线程判断是否由其他事务在使用undo段中表的上一个事务之前的版本信息,决定是否可以清理undo log的日志空间。
注意: undo log也会生产redo log,undo log也要实现持久性保护。
3. uodo log日志的作用
首先简单说一下undolog 和redo log的区别
undo log是逻辑日志,实现事务的原子性
undo log记录的是事务[开始前]的数据状态,记录的是更新之前的值
undo log实现事务的原子性(提供回滚)
redo log是物理日志,实现事务的持久性
redo log记录的是事务[完成后]的数据状态,记录的是更新之后的值
redo log实现事务的持久性(保证数据的完整性)
1.undo log日志可以实现事务的回滚操作
我们在进行数据更新操作的时候,不仅会记录redo log,还会记录undo log,如果因为某些原因导致事务回滚,那么这个时候mysql就要执行回滚(rollback)操作,利用undo log将数据恢复到事务开始之前的状态。
如我们执行下面一条删除语句:
delete from book where id = 1;
那么此时undo log会生成一条与之相反的insert 语句【反向操作的语句】,在需要进行事务回滚的时候,直接执行该条sql,可以将数据完整还原到修改前的数据,从而达到事务回滚的目的。
再比如我们执行一条update语句:
update book set name = "三国" where id = 1; ---修改之前name=西游记
此时undo log会记录一条相反的update语句,如下:
update book set name = "西游记" where id = 1;
如果这个修改出现异常,可以使用undo log日志来实现回滚操作,以保证事务的一致性。
2.undo log实现多版本并发控制 mvcc
具体的mvcc实现机制详解看这篇博客
4. uodo log的工作原理
如上图所示:
当事务a进行一个update操作,将id=1修改成id=2。首先会修改buffer pool中的缓存数据,同时会将旧数据备份到undo log buffer中,记录的是还原操作的sql语句。此时如果事务b要查询修改的数据,但是事务a还没有提交,那么事务b就会从undo log buffer中,查询到事务a修改之前的数据,也就是id=1。此时undo log buffer会将数据持久化到undo log日志中(落盘操作)。undo日志持久化之后,才会将数据真正写入磁盘中,也就是写入ibd的文件中。最后才会执行事务的提交。
5. uodo log的存储机制
具体参数存储形式如上图所示
6. uodo log的配置参数
innodb_max_undo_log_size: undo日志文件的最大值,默认1gb,初始化大小10m
innodb_undo_log_truncate: 标识是否开启自动收缩undo log表空间的操作
innodb_undo_tablespaces: 设置独立表空间的个数,默认为0,标识不开启独立表空间,undo日志保存在ibdata1中
innodb_undo_directory: undo日志存储的目录位置
innodb_undo_logs: 回滚的个数 默认128