内存刷新机制
red log buffer、data buffer、binlog cache。在O和M中,講究日志先行策略,就是一條DML語句進入數據庫之后,都會先寫日志,再寫數據文件。
1.red log,
重做日志文件,用于記錄事務操作的變化,記錄的是數據修改之后的值,不管事務是否提交都會記錄下來。在實例和介質失敗時,重做日志文件就能派上用場,如數據庫掉電,InnoDB存儲引擎會使用重做日志恢復到掉電前的時刻,以此來保證數據的完整性。
默認情況下至少有兩個red log文件,在磁盤上用ib_logfile(0-N)命名。
red log寫的方式是順序和循環寫,當寫滿最后一個文件時,會重新從第一個文件開始寫,寫滿日志文件會產生切換操作,并執行 checkpoint,觸發臟頁的刷新。MySQL數據庫重啟過程中,如果參數文件中的red log值大小與當前redo log值不一致,會把現有redo log 刪除,并按照參數文件中設置的大小,重新生成新的redo log文件。
(1)在磁盤中生成 red log文件之前,數據是先寫在red log buffer中的。
- 通過innodb_flush_log_at_trx_commit參數來控制。該參數分別為0,1,2
- 0的含義:red log thread每隔1秒會將red log buffer中的數據寫入red log文件,同時進行刷盤操作。保證數據確實寫入磁盤。在此參數下,每次事務提交并不會觸發red log thread將日志緩沖中的數據寫入red log文件。
- 1的含義:每次事務提交時,都會觸發redo log thread將日志緩沖中的數據寫入文件,并flush到磁盤。該設置下是最安全的模式。保證數據庫在主機斷電,OS crash下不會丟失任何已提交的數據。
- 2的含義:每次事務提交時,都會把redo log buffer的數據寫入redo log 文件,但是不會同時刷新到磁盤。
三種模式下:
0性能最好,但是不安全,MySQL進程一旦崩潰會導致丟失一秒的數據。
1是安生性最高,但數據庫性能最慢。
2是介于兩者之間。
(2)master thread:每秒進行刷新
(3)redo log buffer:使用超過一半的時候會觸發刷新。
?
2.binlog
DML語句既會寫red log 文件,也會寫binlog文件。功能主要用于備份恢復和主從復制。
從binlog cache刷新到磁盤的binlog文件中,需要通過sync_binlog參數來決定。
a.sync_binlog=0,當事務提交之后,MySQL不做fsync之類的磁盤同步指令刷新binlog_cache中的信息來到磁盤,而讓Filesystem自行決定什么時候來做同步,或都cache滿了之后才同步到磁盤。
b.sync_binlog=N,每進行N次事務提交之后,MySQL將進行一次fsync之類的磁盤同步指令來將binlog_cache中的數據強制寫入磁盤。
?
++++++++++++++++++++++++++++++++++red log和binlog區別++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
兩都都是記錄了對數據真實的修改的語句。同時有以下區別:
1.記錄內容的不同。
binlog是邏輯日志,記錄所有數據的改變信息。
red log記錄的是物理日志,記錄所有InnoDB表數據的變化。
?
2.記錄內容的時間不同。
binlog 記錄commit完畢之后的DML和DDLSQL語句。
red log記錄事務發起之后的DML和DDL SQL語句。
3.文件使用方式的不同。
binlog不是循環使用,在寫滿或者實例重啟之后,會生成新的binlog文件。
red log是循環使用,最后一個文件寫滿之后,會重新寫第一個文件。
?
4.作用不同。
binlog可以作為恢復數據使用,主從復制搭建。
red log作為異常宕機中都介質故障后的數據恢復使用。
?
有以下關聯:
在主從環境中,從庫需要通過二進制日志來應用主庫提交的事務,但如果主庫red log已經提交而二進制日志沒有保持一致,則會造成從庫數據丟失,主從數據不一致的情況,見以下分析:
MySQL兩階段提交過程:
a.準備階段(transaction prepare):事務SQL語句先寫入redo log buffer,然后做一個事務準備標記,再將log buffer中的數據刷新到redo log.
b.提交階段(commit):將事務產生的binlog寫入文件,刷入磁盤。
再在redo log中做一個事務提交的標記,并把binlog寫成功的標記也一并寫入red log文件。
結合以下兩場景分析兩階段如何保持數據庫的一致性:
Sense one:
準備階段,redo log刷新到磁盤了,但是binlog寫盤前發生了MySQL實例crash,這是會發生怎么的操作呢?
即使redo log寫盤成功了,但由于binlog未寫入成功,我們需要執行回滾操作來保證數據的一致性。
?
Sense two:
提交階段,binlog寫盤成功了,此時MySQL實例發生crash,此時binlog已經確保寫成功了,我們在重啟實例進行恢復時,只需要讓redo log重做一次就可以了。
總結一下:
其實只要binlog寫入完成,則在主從復制環境中,都會正常完成事務。
最后看一下臟頁的刷新條件:
(1)重做日志ib_logfile文件寫滿后,在切換的過程中會執行checkpoint,會觸發臟頁的刷新。
(2)通過innodb_max_dirty_pages_pct參數的值控制。該參數是指在buffer pool中dirty page所占的百分比,達到設置的值,就會觸發臟頁的刷新。
(3)由innodb_adaptive_flushing參數控制。
轉載于:https://www.cnblogs.com/chinaops/p/9634780.html
總結
- 上一篇: 消息称iPhone 15 Pro Max
- 下一篇: 创新打底,亚信科技整体业绩稳增,新业务持