innodb_flush_log_at_trx_commit和sync_binlog參數詳解

innodb_flush_log_at_trx_commit和sync_binlog是MySQL innodb引擎的兩個重要的參數,其中innodb_flush_log_at_trx_commit是將事務日誌從innodb log buffer寫入到redo log中,sync_binlog是將二進制日誌文件刷新到磁盤上。

innodb事務日誌redo,binlog邏輯過程如下:
1.事務寫入redo log buffer中;
2.將log buffer刷新到redo log中,不過會先寫一個TX PREPARE標記;
3.寫binlog
4.在redo log中寫入TX COMMIT標記;
5.將寫binlog成功的標記寫入redo log。

參數解析如下: 
innodb_flush_log_at_trx_commit = N: 

N=0    每隔一秒,把事務日誌緩存區的數據寫到日誌文件中,以及把日誌文件的數據刷新到磁盤上;
   log buffer 會 每秒寫入到日誌文件並刷寫(flush)到磁盤。但每次事務提交不會有任何影響,也就是 log buffer 的刷寫操作和事務提交操作沒有關係。在這種情況下,MySQL性能最好,但如果 mysqld 進程崩潰,通常會導致最後 1s 的日誌丟失。
   
N=1    每個事務提交時候,把事務日誌從緩存區寫到日誌文件中,並且刷新日誌文件的數據到磁盤上; 
    當取值爲 1 時,每次事務提交時,log buffer 會被寫入到日誌文件並刷寫到磁盤。這也是默認值。這是最安全的配置,但由於每次事務都需要進行磁盤I/O,所以也最慢。

N=2    每事務提交的時候,把事務日誌數據從緩存區寫到日誌文件中;每隔一秒,刷新一次日誌文件,但不一定刷新到磁盤上,而是取決於操作系統的調度; 
    當取值爲 2 時,每次事務提交會寫入日誌文件,但並不會立即刷寫到磁盤,日誌文件會每秒刷寫一次到磁盤。這時如果 mysqld 進程崩潰,由於日誌已經寫入到系統緩存,所以並不會丟失數據;在操作系統崩潰的情況下,通常會導致最後 1s 的日誌丟失。 
上面說到的「最後 1s」並不是絕對的,有的時候會丟失 更多數據。有時候由於調度的問題,每秒刷寫(once-per-second flushing)並不能保證 100% 執行。對於一些數據一致性和完整性要求不高的應用,配置爲 2 就足夠了;如果爲了最高性能,可以設置爲 0。有些應用,如支付服務,對一致性和完整性要求很高,所以即使最慢,也最好設置爲 1. 
      當我們設置爲2 的時候,Log Thread 會在我們每次事務結束的時候將數據寫入事務日誌,但是這裏的寫入僅僅是調用了文件系統的文件寫入操作。而我們的文件系統都是有緩存機制的,所以Log Thread 的這個寫入並不能保證內容真的已經寫入到物理磁盤上面完成持久化的動作。文件系統什麼時候會將緩存中的這個數據同步到物理磁盤文件Log Thread 就完全不知道了。所以,當設置爲2 的時候,MySQL Crash 並不會造成數據的丟失,但是OS Crash 或者是主機斷電後可能丟失的數據量就完全控制在文件系統上了。各種文件系統對於自己緩存的刷新機制各不一樣,大家可以自行參閱相關的手冊。 
     
sync_binlog =  N: 

N>0    每向二進制日誌文件寫入N條SQL或N個事務後,則把二進制日誌文件的數據刷新到磁盤上; 
N=0    不主動刷新二進制日誌文件的數據到磁盤上,而是由操作系統決定; 

推薦配置組合: 

N=1,1  — 適合數據安全性要求非常高,而且磁盤IO寫能力足夠支持業務,比如充值消費系統; 
N=1,0  — 適合數據安全性要求高,磁盤IO寫能力支持業務不富餘,允許備庫落後或無複製; 
N=2,0或2,m(0<m<100)  — 適合數據安全性有要求,允許丟失一點事務日誌,複製架構的延遲也能接受; 
N=0,0  — 磁盤IO寫能力有限,無複製或允許複製延遲稍微長點能接受,例如:日誌性登記業務; 
  當兩個參數設置爲雙1的時候,寫入性能最差,sync_binlog=N (N>1 ) innodb_flush_log_at_trx_commit=2 時,(在當前模式下)MySQL的寫操作才能達到最高性能。 

數據安全性
 
當innodb_flush_log_at_trx_commit和sync_binlog  都爲1時是最安全的,在mysqld 服務崩潰或者服務器主機crash的情況下,binary log 只有可能丟失最多一個語句或者一個事務。但是魚與熊掌不可兼得,都爲1會導致頻繁的IO操作,因此該模式也是最慢的一種方式。 
當innodb_flush_log_at_trx_commit設置爲0,mysqld進程的崩潰會導致上一秒鐘所有事務數據的丟失。 
當innodb_flush_log_at_trx_commit設置爲2,只有在操作系統崩潰或者系統掉電的情況下,上一秒鐘所有事務數據纔可能丟失。 

雙1適合數據安全性要求非常高,而且磁盤IO寫能力足夠支持業務,比如訂單,交易,充值,支付消費系統。雙1模式下,當磁盤IO無法滿足業務需求時,推薦的做法是innodb_flush_log_at_trx_commit=2 ,sync_binlog=N (N爲500 或1000) 且使用帶蓄電池後備電源的緩存cache,防止系統斷電異常。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章