參數說明
innodb_flush_log_at_trx_commit和sync_binlog 兩個參數是控制MySQL 磁盤寫入策略以及數據安全性的關鍵參數,不同參數設置對磁盤IO影響不同。
參數innodb_flush_log_at_trx_commit
innodb_flush_log_at_trx_commit=0:每秒一次將Log Buffer中數據寫入到Log File中,並且Flush到磁盤。事務提交不會主動觸發寫磁盤操作。 innodb_flush_log_at_trx_commit=1:每次事務提交時將Log Buffer數據寫入到Log File中,並且Flush到磁盤。 innodb_flush_log_at_trx_commit=2:每次事務提交時將Log Buffer數據寫入到Log File中,但不立即Flush到磁盤,MySQL會每秒一次刷新到磁盤。 由於進程調度問題,每條一次操作不能保證每一秒都執行一次。 當innodb_flush_log_at_trx_commit=0時,最近一秒的事務日志存在MySQL的Log Buffer中,無論時MySQL實例停止還是MySQL服務器宕機,都會導致最近一秒的事務日志丟失。 當innodb_flush_log_at_trx_commit=1時,最近一秒的事務日志存在操作系統的文件緩存中,MySQL實例停止不會導致事務日志丟失,但MySQL服務器宕機會導致最近一秒事務日志丟失。
上述的一秒一次刷新,取決於參數innodb_flush_log_at_timeout默認值為1,DDL或其他InnoDB內部操作並不受參數innodb_flush_log_at_trx_commit的限制。
圖片來源於:https://www.h3399.cn/201809/614170.html
參數sync_binlog:
sync_binlog=0:每次事務提交后,將Binlog Cache中的數據寫入到Binlog文件,但不立即刷新到磁盤。由文件系統(file system)決定何時刷新到磁盤中。 sync_binlog=N:每N次事務提交后,將Binlog Cache中的數據寫入到Binlog文件,調用fdatasync()函數將數據刷新到磁盤中。
當sync_binlog=0(默認設置)時,不會執行強制刷盤指令,性能最好同時風險最高。
當sync_binlog=N時,當MySQL服務器宕機后,會導致最近N個事務的BINLOG丟失。
BINLOG和REDO/UNDO LOG的區別
1、處理層次不同,REDO/UNDO LOG由Innodb存儲引擎處理,而BINLOG由MySQL 服務層處理。 2、記錄內容不同,REDO/UNDO LOG記錄的數據頁的修改情況,REDO LOG采用物理日志+邏輯日志的方式存儲,UNDO LOG采用邏輯日志方式存儲,用於保證數據一致性;而BINLOG日志記錄的事務操作的內容,用於主從復制。 3、記錄時機不同,REDO/UNDO LOG在事務的執行過程中不斷生成和寫入,而BINLOG在事務最終COMMIT前寫入。 4、涉及到數據更新的SELECT操作會被記錄到BINLOG中(基於語句格式復制)。 5、BINLOG刷新到磁盤的行為由參數sync_binlog決定,而REDO LOG寫入磁盤的行為受參數innodb_flush_log_at_trx_commit的影響。
6、可以通過會話級參數SQL_LOG_BIN來設置某事務不生成BINLOG,但不能通過參數控制是否生成事務日志。
某台從庫存在嚴重的復制延遲,調整參數后性能變化:
1、主庫(MySQL 5.5版本)凌晨2點開始清理歷史數據。 2、從庫(MySQL 5.7版本)開啟多線程復制,但由於從庫做多源復制且單線程復制(主庫MySQL 5.5),磁盤使用率飆升至80%,出現復制延遲。 3、從庫在08:35調整參數為雙0,CPU使用率從3%提升至7%,磁盤使用率從75%降至8%,磁盤寫次數從8500下降至2200,復制延遲開始下降。 4、從庫在08:51復制無延遲,積壓時間被消費完,CPU使用率恢復至1%,磁盤使用率從8%降至1%,磁盤寫次數從2200下降至300。 5、從庫在09:01調整參數為雙1,CPU使用率無變化,磁盤使用率從1%升至8%,磁盤寫次數從300升職2200。
IOPS測試
創建測試表:
## 創建測試表 CREATE TABLE `tb003` ( `ID` bigint(20) NOT NULL AUTO_INCREMENT, `C1` int(11) DEFAULT NULL, `DT` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`ID`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
創建測試腳本:
#!/bin/bash for i in $(seq 1 10000) do /export/servers/mysql/bin/mysql --host='127.0.0.1' --port=3358 --user='root' --password="root_psw" -e 'insert into db001.tb003(c1)values(0);' 1>/dev/nul 2>&1 done
運行測試腳本發現,每秒執行230個左右事務,使用iostat -dxk 1查看發現服務器每秒寫1380,事務提交次數和每秒IO寫次數的比約為1:6。