是图中的黄色部分;
3. 持久化到磁盘,对应的是hard disk,也就是图中的绿色部分。
日志写到redo log buffer是很快的,wirte到page cache也差不多,但是持久化到磁盘的速度就慢
多了。
为了控制redo log的写入策略,InnoDB提供了innodb_flush_log_at_trx_commit参数,它有三种
可能取值:
1. 设置为0的时候,表示每次事务提交时都只是把redo log留在redo log buffer中;
2. 设置为1的时候,表示每次事务提交时都将redo log直接持久化到磁盘;
3. 设置为2的时候,表示每次事务提交时都只是把redo log写到page cache。
InnoDB有一个后台线程,每隔1秒,就会把redo log buffer中的日志,调用write写到文件系统的
page cache,然后调用fsync持久化到磁盘。
注意,事务执行中间过程的redo log也是直接写在redo log buffer中的,这些redo log也会被后台
线程一起持久化到磁盘。也就是说,一个没有提交的事务的redo log,也是可能已经持久化到磁
盘的。
实际上,除了后台线程每秒一次的轮询操作外,还有两种场景会让一个没有提交的事务的redo
log写入到磁盘中。
1. 一种是,一种是, redo log bufferredo log buffer占用的空间即将达到占用的空间即将达到 innodb_log_buffer_size innodb_log_buffer_size一半的时候,一半的时候,
后台线程会主动写盘。后台线程会主动写盘。注意,由于这个事务并没有提交,所以这个写盘动作只是write,而
没有调用fsync,也就是只留在了文件系统的page cache。
2. 另一种是,并行的事务提交的时候,顺带将这个事务的另一种是,并行的事务提交的时候,顺带将这个事务的redo log bufferredo log buffer持久化到磁持久化到磁
盘。盘。假设一个事务A执行到一半,已经写了一些redo log到buffer中,这时候有另外一个线程
的事务B提交,如果innodb_flush_log_at_trx_commit设置的是1,那么按照这个参数的逻
辑,事务B要把redo log buffer里的日志全部持久化到磁盘。这时候,就会带上事务A在redo
log buffer里的日志一起持久化到磁盘。
这里需要说明的是,我们介绍两阶段提交的时候说过,时序上redo log先prepare, 再写binlog,
最后再把redo log commit。
如果把innodb_flush_log_at_trx_commit设置成1,那么redo log在prepare阶段就要持久化一次,
因为有一个崩溃恢复逻辑是要依赖于prepare 的redo log,再加上binlog来恢复的。(如果你印象
有点儿模糊了,可以再回顾下第15篇文章中的相关内容)。