MySQL Binlog--事務日志和BINLOG落盤參數對磁盤IO的影響


參數說明

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。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM