undo log 基本概念
undo log是一种用于撤销回退的日志,在数据库事务开始之前,MySQL会先记录更新前的数据到undo log日志文件里面,当事务回滚时或者数据库崩溃时,可以利用 undo log来进行回退
Undo Log产生和销毁:Undo Log在事务开始前产生;事务在提交时,并不会立刻删除undo log,innodb会将该事务对应的undo log放入到删除列表中,后面会通过后台线程purge thread进
行回收处理
注意: undo log也会产生redo log,因为undo log也要实现持久性保护
undo log的作用
-
提供回滚操作【undo log实现事务的原子性】
在数据修改的时候,不仅记录了redo log,还记录了相对应的undo log,如果因为某些原因导致事务执行失败了,可以借助undo log进行回滚
undo log 和 redo log 记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时, undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录
-
提供多版本控制(MVCC)【undo log实现多版本并发控制(MVCC)】
MVCC,即多版本控制。在MySQL数据库InnoDB存储引擎中,用undo Log来实现多版本并发控制(MVCC)。当读取的某一行被其他事务锁定时,它可以从undo log中分析出该行记录以前的数据版本是怎样的,从而让用户能够读取到当前事务操作之前的数据【快照读】
快照读: SQL读取的数据是快照版本【可见版本】,也就是历史版本,不用加锁,普通的SELECT就是快照读
当前读: SQL读取的数据是最新版本(最新版本指的是修改且已经提交的数据)。除了在执行修改语句的时候,需要执行当前读,然后再更新数据之外,select语句也有可能是当前读,比如: select … lock in share mode、select … for update
undo log 的工作原理
在更新数据之前,MySQL会提前生成undo log日志,当事务提交的时候,并不会立即删除undo log,因为后面可能需要进行回滚操作,要执行回滚(rollback)操作时,从缓存中读取数据。undo log日志的删除是通过通过后台purge线程进行回收处理的
- 事务A执行update更新操作,在事务没有提交之前,会将旧版本数据备份到对应的undo buffer中,然后再由undo buffer持久化到磁盘中的undo log文件中, 之后才会对user进行更新操作,然后持久化到磁盘
- 在事务A执行的过程中,事务B对User进行了查询
undo log的存储机制
为了保证事务并发操作时,在写各自的undo log时不产生冲突,InnoDB采用回滚段的方式来维护undo log的并发写入和持久化
rollback segment 称为回滚段 共有128个,每个回滚段中有1024个 undo log segment ,即支持 128*1024 个 undo 操作,最多支持131072个并发事务执行