innodb_flush_log_at_trx_commit和sync_binlog innodb_flush_method _人人IT網
innodb_flush_log_at_trx_commit
主要控制了innodb將log buffer中的數據寫入日志文件並flush磁盤的時間點,取值分別為0、1、2三個。
0,表示當事務提交時,不做日志寫入操作,而是每秒鍾將log buffer中的數據寫入日志文件並flush磁盤一次;
1,則在每秒鍾或是每次事物的提交都會引起日志文件寫入、flush磁盤的操作,確保了事務的ACID;
設置為2,每次事務提交引起寫入日志文件的動作,但每秒鍾完成一次flush磁盤操作。
顯然,設置為0或2可以減小系統的io壓力,特別是0時,速度最快,提高mysql寫操作的吞吐量,但mysql或操作系統的崩潰、斷電都可能會引起數據的丟失,設置為2時os的崩潰和斷電可能會引起數據的丟失。
innodb_flush_method
影響了服務器flush數據或日志文件的方法。有三個選值:
預設的default,innodb使用fsync()函數flush數據和日志文件;
O_DIRECT,innodb使用O_DIRECT的方式打開數據文件,並使用fsync()函數flush數據和日志文件;
O_DSYNC,innodb使用O_SYNC打開並flush日志文件,使用fsync()函數flush數據文件。
注:在類unix操作系統中,文件的打開方式為O_DIRECT會最小化緩沖對io的影響,該文件的io是直接在用戶空間的buffer上操作的,並且io操作是同步的,因此不管是read()系統調用還是write()系統調用,數據都保證是從磁盤上讀取的;O_SYNC方式表示以同步io的方式打開文件,任何寫操作都將阻塞到數據寫入物理磁盤後才返回。fsync(int filedes)函數只對由文件描述符filedes指定的單一文件起作用,並且等待寫磁盤操作結束,然後返回。fdatasync(int filedes)函數類似於fsync,但它只影響文件的數據部分。而除數據外,fsync還會同步更新文件的元信息到磁盤。
sync_binlog:
sync_binlog=N表示每寫緩沖N次,就同步到磁盤,對於innodb事務,即使事務還未commit,sync_binlog=1時,還會寫日志。如果此時崩潰,這個事務會被回滾,但binlog已經記錄了該事務信息,無法回滾。可以通過設置:innodb_support_xa=1解決。
影響了binary log的flush,當為1時,每個事物提交後,mysql將用fdatasync()函數將二進制日志同步到磁盤上;當為0時,mysql不會做額外的flush,而是依靠os的flush。
做過一些相應的測試,獲得一些以上三參數搭配使用的結論:
1)O_DIRECT的flush_method更適合於操作系統內存有限的情況下(可以避免不必要的對交換空間的讀寫操作),否則,它會由於禁用了os的緩沖降低對數據的讀寫操作的效能。
2)Sync_binlog為1時,每個含有修改操作的事物提交後,mysql將把二進制日志同步到磁盤上,增大了io壓力,引起相應瓶頸,會降低對數據寫操作的效率。而select操作不寫入binary log,所以不受任何影響。
3)對於innodb_flush_log_at_trx_commit與innodb_flush_method的不同組合(0|1|2,default|O_DSYNC)(對於O_DIRECT的情況特殊,已經在1)中單獨做了總結在此不累述)分析得:
①(0, default)每秒鍾調用fsync()同步一次innodb logfile,io壓力小,性能高,但可能損失數據;
②(1, default)每秒鍾和每次commit調用fsync()同步一次innodb logfile,保證數據完整的同時,加大了io壓力,吞吐量相對低;
③(2, default)速度介於前兩者之間,也不能完全保證數據的安全;
④(0,O_DSYNC)每秒同步日志及數據文件,吞吐量等情況應與(0, default)基本一致;
⑤(1,O_DSYNC)每秒鍾和每次commit同步數據及日志文件,相應於(1, default)情況一致;
⑥(2,O_DSYNC)雖然innodb_flush_log_at_trx_commit設置為2,innodb被告知每次事務提交引起寫入日志文件的動作,每秒鍾完成一次flush磁盤操作,但由於O_DSYNC的設置使得os對日志自動做了同步工作,所以吞吐量等情況與(1, default)和(1,O_DSYNC)相一致。