redo

innodb存储引擎中,事务日志通过重做(redo)日志文件和InnoDB存储引擎的日志缓冲(InnoDB Log Buffer)来实现。当开始一个事务时,会记录该事务的一个LSN(Log Sequence Number,日志序列号);当事务执行时,会往InnoDB存储引擎的日志缓冲里插入事务日志;当事务提交时必须将InnoDB存储引擎的日志缓冲写到磁盘(默认的实现,即innodb_flush_log_at_trx_commit=1)。也就是在写数据前,需要先写日志,这种方式称为预写日志方式(Write-Ahead LoggingWAL)

InnoDB存储引擎通过预写日志的方式来保证事务的完整性。这意味着磁盘上存储的数据页和内存缓冲池的页是不同步的,对于内存缓冲池中页的修改,先是写入重做日志文件,然后再写入磁盘,因此是一种异步的方式。可以通过命令show engine innodb status来观察当前磁盘和日志的差距

首先建立一张表z,然后建立一个往表z中导入数据的存储过程load test。通过命令SHOW ENGINE INNODB STATUS观察当前的重做日志情况:

 

Log sequence number表示当前的ISN, Log flushed up to表示刷新到重做日志文件的LSN, Last checkpoint at表示刷新到磁盘的LSN。因为当前没有任何操作,所以这三者的值是一样的。接着开始导入10000条记录:

mysql>call load test(10000);

mysql> show engine innodb statusG;

······

---

LOG

---

Log sequence number 11 3047672789

Log flushed up to 11 3047672789

Last checkpoint at 11 3047174608

0 pending log writes, 0 pending chkp writes

143 log i/o' s done, 0.08 log i/o' s second

······

1 row in set (0.00 sec)

这次SHOW ENGINE INNODB STATUS的结果就不同了, Log sequence numberLSN113047672789, Log flushed up toLSN113047672789Last checkpoint atLSN113047174608,可以把 Log flushed up toLast checkpoint at的差值498181(~486.5K)理解为重做日志产生的增量(以字节为单位)

虽然在上面的例子中, Log sequence numberLog flushed up to的值是相等的,但是在实际的生产环境中,该值有可能是不同的。因为在一个事务中从日志缓冲刷新到重做日志文件,并不只是在事务提交时发生,每秒都会有从日志缓冲刷新到重做日志文件的动作(这部分内容我们在362小节已经讲解过了)。下面是一个生产环境下重做日志的信息:

mysql> show engine innodb statusG;

······

---

LOG

---

Log sequence number 203318213447

Log flushed up to 203318213326

Last checkpoint at 203252831194

1 pending log writes, 0 pending chkp writes

103447 log i/o' s done, 7.00 log i/o' s second

······

1 row in set (0.00 sec)

可以看到,在生产环境下Log sequence numberLog flushed up toLast checkpoint at个值可能是不同的。

原文地址:https://www.cnblogs.com/5945yang/p/11061669.html