參數說明:
不管在官網還是其他網站上均能看到innodb_flush_log_at_trx_commit=【0,1,2】三種值:
innodb_flush_log_at_trx_commit = 0 :每秒將日志緩沖區寫入log file,並同時flush到磁盤。跟事務提交無關。在機器crash並重啟后,會丟失一秒的事務日志數據(並不一定是1s,也許會有延遲,跟操作系統調度有關)。
innodb_flush_log_at_trx_commit = 1:每次事務提交將日志緩沖區寫入log file,並同時flush到磁盤。(crash不會丟失事務日志)
innodb_flush_log_at_trx_commit = 2:每次事務提交將日志緩沖區寫入log file,每秒flush一次到磁盤。(crash有可能丟失數據)
測試驗證:
環境說明:
操作系統:windows 7 MySQL:5.6.26
准備:
-- 建立測試表 use test create table t_innodb (a int) engine=innodb; create table t_myisam (a int) engine=myisam; -- 建立插入數據存儲過程 delimiter // create procedure insert_testdata(p1 int) begin set @x:=0; repeat set @x:=@x+1; insert into t_myisam values (@x); insert into t_innodb values (@x); commit; until @x>p1 end repeat; end // delimiter ;
(1)innodb_flush_log_at_trx_commit = 0 測試
net stop mysql --停止Mysql服務 更新my.ini innodb_flush_log_at_trx_commit = 0 --更新innodb_flush_log_at_trx_commit = 0 net start mysql --重新啟動Mysql服務
mysql -u root -p
use test
call insert_testdata(1000000);
將mysqld進程殺掉。模擬crash場景。
net start mysql
結果截圖:




(2)innodb_flush_log_at_trx_commit = 1 測試
truncate table t_innodb; truncate table t_myisam; net stop mysql 更新my.ini innodb_flush_log_at_trx_commit = 1 net start mysql mysql -u root -p use test call test_insertdata(1000000); 將mysqld進程殺掉。模擬crash場景。

(3)innodb_flush_log_at_trx_commit = 2 測試
truncate table t_innodb; truncate table t_myisam; net stop mysql 更新my.ini innodb_flush_log_at_trx_commit = 2 net start mysql mysql -u root -p use test call insert_testdata(1000000);
將mysqld進程殺掉。模擬crash場景。
重啟后,數據未丟失。


再次 call insert_testdata(1000000); 將mysqld進程殺掉。模擬crash場景。丟失一條數據。


注意:
大家肯定記得還有控制二進制日志的 sync_binlog 參數,而且還會很容易混淆,下面談一談sync_binlog:
sync_binlog = 0 (mysql默認值 )由文件系統決定將binlog同步到硬盤。
sync_binlog = 1 每提交一次事務,寫一次binlog,並使用fdatasync()同步到硬盤。
sync_binlog > 1 每提交一次事務,寫一次binlog,達到sync_binlog 設定的值后,調用fdatasync()同步到硬盤。
(1)如果在主從復制架構下:
在 sync_logbin = 1 的情況下, 每次提交事務都會同步到磁盤,保證日志的持久性,也可以保證主從復制的一致性 。
在 sync_logbin = 0,或者>1的值,很有可能機器出現crash,日志並沒有同步到磁盤,重啟后,二進制日志的position比備庫同步過去的position小,造成數據不一致情況。
(2)沒有主從架構,單獨數據庫實例:
在 sync_logbin = 1 的情況下, 每次提交事務都會同步到磁盤,保證日志的持久性,能夠保證存儲下了所有提交的事務 。能夠用來進行恢復。
在 sync_logbin = 0,或者>1的值,很有可能機器出現crash,日志並沒有同步到磁盤,重啟后,二進制日志很可能丟失已提交事務,所以不能用來進行恢復操作,因為它有丟失事務。
總結:
innodb_flush_log_at_trx_commit 參數對數據完整性有非常大的作用,強烈建議使用 innodb_flush_log_at_trx_commit = 1 ; sync_binlog = 1 ; --雖然會很影響性能,但是對於數據很重要的情況下,必須設置。