前些天在查看關於innodb_flush_log_at_trx_commit的官網解釋時產生了一些疑問,關於innodb_flush_log_at_trx_commit參數的詳細解釋參見官網: https://dev.mysql.com/doc/refman/5.7/en/innodb-parame ...
前些天在查看關於innodb_flush_log_at_trx_commit的官網解釋時產生了一些疑問,關於
innodb_flush_log_at_trx_commit參數的詳細解釋參見官網:
https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit
其中有一段是這麼寫的: With a value of 2, the contents of theInnoDB
log buffer are written to the log file after each transaction commit and the log file is flushed to disk approximately once per second.
意思是:如果innodb_flush_log_at_trx_commit的值設為2,那麼log buffer里的內容會在每次提交時被寫入log file,然後logfile也會被flush到disk。
由於innodb的log file據我所知是在硬碟上的ib_logfile,所以對於這裡的log file被flush到disk很疑惑,難道log buffer和disk之間還存在了一層可以緩存log file的結構?
在查閱了大量中英文資料後,總算有了初步的瞭解,暫總結於此。
一、名詞解釋
在innodb存儲引擎中,有一種獨有的log file,即redo log file,因此對於innodb存儲引擎來說,就存在兩種logfile:redo log和binlog.
redo log:即data目錄下的ib_logfile0,ib_logfile1(個數由innodb_log_files_in_group控制),innodb存儲引擎特有,在記憶體中有相應的redo log buffer。
因此寫redo時的3層結構為:redo log buffer--->文件系統緩存中的redo logfile--->disk上的redo log file
binlog:預設在data目錄下,也可以通過log_bin參數直接指定路徑,文件名為預設為<hostname>-bin首碼的文件,在記憶體中沒有log buffer。
因此寫binlog時的2層結構為:文件系統緩存中的binlog--->disk上的binlog
二、二階段日誌寫的流程
原圖來自:https://jin-yang.github.io/post/mysql-group-commit.html

- 此值為0表示:redo log buffer的內容每秒會被寫入文件系統緩存的redo log里,同時被flush(固化)到disk上的redo log file中。
- 此值為1表示:redo log buffer的內容會在事務commit時被寫入文件系統緩存的redo log里,同時被flush(固化)到disk上的redo log file中。
- 此值為2表示:redo log buffer的內容會在事務commit時被寫入文件系統緩存的redo log里,而文件系統緩存的redo log每秒一次被flush(固化)到disk上的redo log file中。
- sync_binlog=0:表示fsync()的調用完全交給操作系統,即文件系統緩存中的binlog是否刷新到disk完全由操作系統控制。
- sync_binlog=1:表示在事務提交時,binlog一定會被固化到disk
- sync_binlog=N(N>1):資料庫崩潰時,可能會丟失N-1個事務,具體原理也詳見https://jin-yang.github.io/post/mysql-group-commit.html