UndoLog 包括哪些东西 写入时机 如何回滚数据
1. 概念
Undo log 是mysql中比较重要的事务日志之一,顾名思义,undo log是一种用于撤销回退的日志,在事务每提交之前,mysql会先记录更新前的数据到undo log日志文件中。当事务回滚时或者数据库崩溃时,可以利用undo log进行回退。
2. undo log的作用
提供回滚操作 保证事务的原子性:
当在进行数据更新操作时,不仅会记录redo log 还会记录undo log 如果因为某些原因导致事务回滚,那么这个时候mysql就要执行回滚操作,利用undo log将数据恢复到事务开始之前的状态。
在执行一条sql语句时,undo log会记录一条对应的反向操作的语句,以保证事务回滚时将数据还原回去。
提供多版本控制MVCC,使用undo log 实现mvcc
在mysql数据库InnoDB存储引擎中,使用undo Log来实现多版本并发控制。当读取的某一行被其他事务锁定时,它可以从undo Log中分析出该记录之前的数据版本是怎样的,从而让用户能够读取到当前事务操作之前的数据【快照读】.
3. Undo Log 的存储
undo log中不仅存放着数据更新前的记录,号记录着RowID、事务ID,回滚指针。其中事务ID每次递增,回滚指针第一次如果是insert语句的话,回滚指针为NULL,第二次update之后的undo log的回滚指针就会指向刚刚那一天 undo Log日志,一次类推,就会形成一条undo log回滚链,方便找到该条记录的历史版本
4. undo log的工作原理
在更新数据之前,MySQL会提前生成undo Log日志,当事务提交时,并不会立即删除undo log ,因为后面有可能需要进行回滚操作,要执行回滚操作时,从缓存中读取数据。undo log日志的删除是通过后台purge线程进行回收处理的
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
- 事务开始
- 记录A= 1到uedo log
- 修改A = 3
- 记录 B = 2 到uedo log
- 修改B = 4
- 将undo log写到磁盘 ——undo log 持久化
- 将数据写到磁盘——数据持久化
- 事务提交——提交事务
之前能同时保证原子性和持久化,是因为以下特点:
- 更新数据前记录undo log
- 为了保证持久性,必须将数据在事务提交前写到磁盘,只要事务成功提交,数据必然已经持久化到磁盘
- undo log必须先于数据持久化到磁盘。如果7,8之间发生系统崩溃,undo log 是完整的,可以用来回滚
- 如果在A-F之间发生系统崩溃,因为数据没有持久化到磁盘,所以磁盘上的数据还是保持在事务开始前的状态。
缺陷:每个事务提交前将数据和undo log写入磁盘,这样会导致大量的磁盘io,因此性能较差。如果能够将数据缓存一段时间,就能减少io 提高性能,但是这样会失去事务的持久性。
undo日志属于逻辑日志,redo是物理日志,所谓逻辑日志是undo log是记录一个操作过程,不会物理删除undo log,sql执行delete或者update操作都会记录一条undo日志。