在之前事务的介绍中我们知道了事务的4个特性(ACID),我们知道隔离性其实就是通过添加各种锁来保证,这次我们来看一下用来保证事务其他3个特性的日志Redo,Undo。
在我们了解这两种日志之前,我们先来了解一下Mysql的结构
Redo的作用
Redo log的主要作用是用于数据库的崩溃恢复
Redo的组成
- 存储在内存中的重做日志缓冲redo log buffer
- 存储在磁盘中的重做的日志文件redo log file
Redo的执行流程
从图中我们可以Redo 是如何执行的
- 从磁盘中获取事务中准备执行的数据
- 生成一条重做日志写入log buffer中,这里的数据是修改后的
- 事务commit时,将log buffer中的内容刷新到log file中,采用追加的方式,通常redo log file的文件数量为2个,写满之后在第一个的开头继续写
- 定期将修改后的内容刷新到磁盘
从上面我们大致可以了解到事务在进行提交之前会先将log buffer中的内容写入log file,然后将数据刷新到磁盘中,这些步骤(也就是图中的步骤3,4)都走完才算是真正的提交完成,也就是在持久化到磁盘中之前先日志持久化。步骤3中从log buffer更新内容到log file这中间需要经过我们的操作系统进行fsync操作,我们将其称为OS Buffer。
在概念上,innodb通过force log at commit机制实现事务的持久性,即在事务提交的时候,必须先将该事务的所有事务日志写入到磁盘上的redo log file和undo log file中进行持久化。
我们在提交事务也就是commit时,执行上图中的2,3,4步骤可以通过设置innodb_flush_log_at_trx_commit 来决定(默认为1)
- 为0时,步骤3,步骤4(大约)每秒执行一次,也就是说数据是每秒刷新到磁盘中的,如果系统崩溃那么将会丢失1秒钟的数据(事务提交与刷新数据到磁盘没有关系)
- 为1时,每次提交时都会执行步骤3,步骤4,这种方式非常的安全,只有提交才会进行操作,不过非常的损耗资源
- 为2时,每次提交时都会执行步骤3,不过步骤4会每秒刷新到磁盘(相比于0较为安全,MySQL数据库宕机时 不会丢失事务,只有系统崩溃才会丢失数据)
Undo的作用
- 用于事务回滚
- MVCC
undo日志,只将数据库逻辑地恢复到原来的样子,在回滚的时候,它实际上是做的相反的工作,比如一条INSERT ,对应一条 DELETE,对于每个UPDATE,对应一条相反的 UPDATE,将修改前的行放回去。undo日志用于事务的回滚操作进而保障了事务的原子性。
undo log只有在修改聚簇索引时才会记录