redo
在innodb存儲引擎中,事務日志通過重做(redo)日志文件和InnoDB存儲引擎的日志緩沖(InnoDB Log Buffer)來實現。當開始一個事務時,會記錄該事務的一個LSN(Log Sequence Number,日志序列號);當事務執行時,會往InnoDB存儲引擎的日志緩沖里插入事務日志;當事務提交時必須將InnoDB存儲引擎的日志緩沖寫到磁盤(默認的實現,即innodb_flush_log_at_trx_commit=1)。也就是在寫數據前,需要先寫日志,這種方式稱為預寫日志方式(Write-Ahead Logging,WAL)。
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 status\G;
······
---
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 number的LSN為113047672789, Log flushed up to的LSN為113047672789, Last checkpoint at的LSN為113047174608,可以把 Log flushed up to和 Last checkpoint at的差值498181(~486.5K)理解為重做日志產生的增量(以字節為單位)。
雖然在上面的例子中, Log sequence number和 Log flushed up to的值是相等的,但是在實際的生產環境中,該值有可能是不同的。因為在一個事務中從日志緩沖刷新到重做日志文件,并不只是在事務提交時發生,每秒都會有從日志緩沖刷新到重做日志文件的動作(這部分內容我們在362小節已經講解過了)。下面是一個生產環境下重做日志的信息:
mysql> show engine innodb status\G;
······
---
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 number、Log flushed up to、Last checkpoint at個值可能是不同的。
轉載于:https://www.cnblogs.com/5945yang/p/11061669.html
總結
- 上一篇: 数据与计算机通信复习重点
- 下一篇: 【Python】对象、类、元类