在MySQL的慢查詢日志中出現只有commit,但是沒有任何其它SQL的這種現象到底是一個什么情況呢?如下截圖所示(沒有優化前的一個Zabbix資料庫)

其實在慢查詢日志中出現commit,就是因為事務提交(commit)的時間過長,至于為什么commit的時間過長,可能有下面一些原因:
1:磁盤IO過載時或者發生故障的時候,因此在事務完成時進行重繪(flush)需要很長時間,
2:二進制日志輪換(Rotate)時,在二進制日志輪換完成之前,無法提交其他任何事務,這個會引起事務提交出現短暫的停頓/卡頓,尤其當二進制日志過大或者IO性能差的時候,這個停頓可能更長,導致commit的時間超過引數long_query_time的值,從而commit陳述句出現在慢查詢日志,
3: MySQL的系統引數innodb_flush_log_at_trx_commit、sync_binlog、max_binlog_size的設定可能會引起這種現象,但是注意,并不是說設這些引數的某個設定就一定會引起這個現象,而是說在某種取值下,在磁盤IO過載,業務暴增等一系列的綜合因素影響下,會增加這種現象出現的概率,
舉個例子,將MySQL配置為sync_binlog = 0的情況下,這可能導致作業系統快取整個二進制日志,甚至使用最快的磁盤,默認情況下,最大二進制日志大小為1G,如果所有日志均已快取,則需要一些時間才能寫出, 在這種情況下,沒有其他事務可以提交,那么就可能出現commit耗時變長的情況,而如果將max_binlog_size設定小一些,那么就緩解這種情況,
4:事務過大,導致事務提交的時候,需要等候的時間過長,尤其是發生二進制日志輪換時,
下面我們構造一個這樣的例子,準備測驗環境,如下所示,當然這個實驗受資料量,表的結構,還有MySQL的引數等很多因素的影響,下面實驗僅僅說明一個超大的事務可能出現這種現象,在你的測驗環境中,根據實驗情況進行調整,
create table test(id int auto_increment primary key, name varchar(32));
delimiter &&
drop procedure if exists prc_insert;
create procedure prc_insert(in row_cnt int)
begindeclare i int;
set i=1;while i < row_cnt do insert into test(name)SELECT CONCAT('KERRY', cast(i as char));
set i = i+1;end while;
end &&delimiter ;
準備好上面的表以及存盤程序后,然后我們在下面事務中執行下面腳本
mysql> set session autocommit=0;
Query OK, 0 rows affected (0.00 sec)mysql> call prc_insert(10000000);Query OK, 1 row affected (7 min 1.31 sec)
mysql> commit;Query OK, 0 rows affected (32.24 sec)mysql>
在上面SQL執行的時候,使用下面腳本一直觀察慢查詢日志,就會發現它會出現只有commit的這種現象,如下截圖所示
# tail -60f /mysql_data/mysql/KerryDB-slow.log

對于這種現象,那么有什么解決方案嗎? 像我維護的zabbix系統,通過使用磁區表方案后,與那些大表相關的SQL性能變好,那么就很少出現這種現象,其實除了優化SQL外,還有一些解決方案,參考下面官方檔案,
Commit Takes Too Long Time (Doc ID 1925395.1)
![]()
|
In this Document
APPLIES TO: MySQL Server - Version 4.1 and later SYMPTOMS Following symptoms may be observed:
CAUSE Disk is overloaded or malfunctioning, so flushing on transaction completion takes long time. SOLUTION - Address problem to Hardware Admins to confirm whether disk partition with InnoDB logs is overloaded or malfunctioning. - Reduce load from physical disk partition, e.g. introducing fast dedicated physical disk for InnoDB logs or moving tmpdir to dedicated disk if it causes high load, etc. - Consider reducing durability of data by implementing less safe configuration for innodb_flush_log_at_trx_commit and sync_binlog if that suits your system (i.e. data loss is not critical or will not happen because of hardware/OS configuration: e.g. if you may rely on your OS to always shutdown properly). In case if problem happens with sync_binlog=0, consider reducing max_binlog_size to decrease amount of flushed data during binlog rotation. |
參考資料:
https://support.oracle.com/epmos/faces/DocumentDisplay?_afrLoop=430623618290439&parent=EXTERNAL_SEARCH&sourceId=PROBLEM&id=1925395.1&_afrWindowMode=0&_adf.ctrl-state=1008ex2pna_4
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/238463.html
標籤:MySQL
上一篇:MySQL資料歸檔小工具推薦--mysql_archiver
下一篇:ora2pg簡單使用
