1、什么是redo log
redo log叫做重做日志,是保证事务持久性的重要机制。当mysql服务器意外崩溃或者宕机后,保证已经提交的事务,确定持久化到磁盘中的一种措施。
2、为什么需要redo log
innodb是以页为单位来管理存储空间的,任何的增删改差操作最终都会操作完整的一个页,会将整个页加载到buffer pool中,然后对需要修改的记录进行修改,修改完毕不会立即刷新到磁盘,因为此时的刷新是一个随机io,而且仅仅修改了一条记录,刷新一个完整的数据页的话过于浪费了。但是如果不立即刷新的话,数据此时还在内存中,如果此时发生系统崩溃最终数据会丢失的,因此权衡利弊,引入了redo log,也就是说,修改完后,不立即刷新,而是记录一条日志,日志内容就是记录哪个页面,多少偏移量,什么数据发生了什么变更。这样即使系统崩溃,再恢复后,也可以根据redo日志进行数据恢复。另外,redo log是循环写入固定的文件,是顺序写入磁盘的。
3、以组的方式写入
在一个事物中,可能会发生多次的数据修改,对应的就是多个数据页多个偏移量位置的字段变更,也就是说会产生多条redo log,而且因为在同一个事物中,这些redo log,也是不可再分的,也就是说,一个组的redo log在持久化的时候,不能部分成功,部分失败,否则的话,就会破坏事务的原子性。另外为了提升性能redo log是按照块组织在一起,然后写入到磁盘中的,类似于数据的页,而且引入了redo log buffer,默认的大小为16MB。buffer中分了很多的block,每个block的大小为512kb,每一个事务产生的所有redo log称为一个group。
4、redo log的刷盘时机
redo log听着挺厉害的,但是刚开始也是在内存中的一个东西,万一,还没有持久化到磁盘就发生了系统崩溃怎么处理。这个便于redo log的刷盘时机有关:通过一个参数控制:innodb_flush_log_at_trx_commit
- 1、commit的时候进行刷盘:这也是最保险的,因为如果这个时候崩溃了代表没有commit成功,因此,也不用恢复什么数据。
- 2、commit的时候,只是刷新近os的内核缓冲区,具体的刷盘时机不确定。
- 0、后台线程,每s刷新一次到磁盘中。
为了保证事务的持久性,推荐使用1.
5、一条更新语句的执行步骤
update table set id = 10 where id = 1;
- 连接数据库 …
- 判断id=1的这条记录在不在buffer pool中,在的话之间更新,否则从磁盘中加载到buffer pool中,然后进行更新
- 将这个更新操作记录到redo log中,记录的是一个物理日志。此时redo log是一个prepare状态
- 记录该操作的binlog,并且将binlog刷盘
- 提交事务,对redo log进行提交。
7、Mysql的两阶段提交
对于Mysql Innodb存储引擎而言,每次修改后,不仅需要记录Redo log还需要记录Binlog,而且这两个操作必须保证同时成功或者同时失败,否则就会造成数据不一致。为此Mysql引入两阶段提交。
1、如果先写redolog再写binlog
2、先写binlog再写redolog
3、两阶段提交
6、总结