innodb_flush_log_at_trx_commit和sync_binlog 兩個參數是控制mysql 磁盤寫入政策以及資料安全性的關鍵參數。本文從參數含義,性能,安全角度闡述兩個參數為不同的值時對db 性能,資料的影響.
一 參數意義
<b>innodb_flush_log_at_trx_commit</b>
如果innodb_flush_log_at_trx_commit設定為0,log buffer将每秒一次地寫入log file中,并且log file的flush(刷到磁盤)操作同時進行.該模式下,在事務送出的時候,不會主動觸發寫入磁盤的操作。
如果innodb_flush_log_at_trx_commit設定為1,每次事務送出時mysql都會把log buffer的資料寫入log file,并且flush(刷到磁盤)中去.
如果innodb_flush_log_at_trx_commit設定為2,每次事務送出時mysql都會把log buffer的資料寫入log file.但是flush(刷到磁盤)操作并不會同時進行。該模式下,mysql會每秒執行一次 flush(刷到磁盤)操作。
注意:
由于程序排程政策問題,這個“每秒執行一次 flush(刷到磁盤)操作”并不是保證100%的“每秒”。
<b>sync_binlog</b>
sync_binlog 的預設值是0,像作業系統刷其他檔案的機制一樣,mysql不會同步到磁盤中去而是依賴作業系統來重新整理binary log。
當sync_binlog =n (n>0) ,mysql 在每寫 n次 二進制日志binary log時,會使用fdatasync()函數将它的寫二進制日志binary log同步到磁盤中去。
注:
如果啟用了autocommit,那麼每一個語句statement就會有一次寫操作;否則每個事務對應一個寫操作。
根據上述描述,我做了一張圖,可以友善大家檢視。
二 性能
兩個參數在不同值時對db的純寫入的影響表現如下:
測試場景1
innodb_flush_log_at_trx_commit=2
sync_binlog=1000
測試場景2
innodb_flush_log_at_trx_commit=1
測試場景3
sync_binlog=1
測試場景4
innodb_flush_log_at_trx_commit=1
測試場景5
sync_binlog=1000
場景
tps
場景1
41000
場景2
33000
場景3
26000
場景4
由此可見,當兩個參數設定為雙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 隻有可能丢失最多一個語句或者一個事務。但是魚與熊掌不可兼得,雙11 會導緻頻繁的io操作,是以該模式也是最慢的一種方式。
當innodb_flush_log_at_trx_commit設定為0,mysqld程序的崩潰會導緻上一秒鐘所有事務資料的丢失。
當innodb_flush_log_at_trx_commit設定為2,隻有在作業系統崩潰或者系統掉電的情況下,上一秒鐘所有事務資料才可能丢失。
雙1适合資料安全性要求非常高,而且磁盤io寫能力足夠支援業務,比如訂單,交易,充值,支付消費系統。雙1模式下,當磁盤io無法滿足業務需求時 比如11.11 活動的壓力。推薦的做法是 innodb_flush_log_at_trx_commit=2 ,sync_binlog=n (n為500 或1000) 且使用帶蓄電池後備電源的緩存cache,防止系統斷電異常。
四 小結
系統性能和資料安全是業務系統高可用穩定的必要因素。我們對系統的優化需要尋找一個平衡點,合适的才是最好的,根據不同的業務場景需求,可以将兩個參數做組合調整,以便是db系統的性能達到最優化。