undo的日志是干什么用的
undo.log从字面意义来讲是撤销日志, 用于事务当中, 当事务开始时,会事先把需要反向操作的记录写到日志文件文件当中, 备份好,当事务进行回滚或者数据库崩溃的时候用于事务回滚。目的是是实现事务的原子性,以及多版本并发控制的快照读
存储方式
undo.log 的存储是由innodb存储引擎实现的, 数据结构是回滚段,每个回滚段有1024个undo log segment, 从5.5版本后支持128个日志回滚段,之前版本仅支持1个日志回滚段
工作原理
在事务开始的时候,将会对更新的数据就产生undo.log 日志, 事务提交后,将事务对应的undo.log保存在删除的列表当中,后台线程进行回收处理。两个事务读取相同的查询操作时候,前一个事务会把数据进行备份,备份到undo.log buffer,后一个事务是直接读undo buffer缓冲中读取。
undo.log 的清理
undo.log分为insert undo.log 和 update undo.log , 其中前者仅用于回滚,当事务提交后,会立即删除掉该日志。而后者不仅会被用于回滚,同时也会作为MVCC快照读的版本内容。 如果事务发生回滚后, 会立马删除掉对于的回滚日志。如果事务是提交完成的情况, 这个时候insert undo.log会立即删除,而update undo.log 只有等没有没有活跃事务存在的情况下,后台purge线程才会清除掉该日志。其中purge线程是mysql一个周期垃圾回收线程。
Buffer Pool redo.log bin.log undo.log 的协同工作
- buffer pool 完成所有增删改操作
- undo.log 记录数据操作之前的样子
- redo.log 记录数据操作之后的样子
- bin.log 记录整个操作过程的样子
一个事务提交的过程:
首先执行器去根据执行计划,查询相关数据, 最初会去从buffer pool缓冲池当中获取,当数据存在,直接使用。如果数据不存在,则去磁盘读取,并加载到buffer pool当中,在这个过程当中开始写入undo.log日志。 更新的操作也是在buffer pool当中完成的, 同时将更新后的数据写到redo log buffer中。 待提交事务,这个时候会进行一下操作, 1 将redo.log buffer 刷入到redo.log日志文件当中,2. 将本次操作记录到bin log日志文件当中, 3. 将bin log 文件名字和更新内容的位置记录当redo.log 当中, 然后在redo.log中添加commit 标记