關於MySQL慢日志,你想知道的都在這
https://mp.weixin.qq.com/s/Ifbq0Dk13SO3WVghqWVUbA
作者介紹
鄒鵬,現任職於騰訊雲數據庫團隊,負責騰訊雲數據庫MySQL中間件研發,多年的數據庫、網絡安全研發經驗,對雲計算平台的網絡、計算、存儲、安全有着深入的了解,在MySQL的高可用、高可靠、中間件方面有豐富的經驗。
目錄:
什么是慢日志?
什么情況下產生慢日志?
慢日志相關參數
慢日志輸出內容
慢日志分析工具
慢日志的清理與備份
一、什么是慢日志?
MySQL的慢查詢日志是MySQL提供的一種日志記錄,它用來記錄在MySQL中響應時間超過閥值的語句,具體指運行時間超過long_query_time值的SQL,則會被記錄到慢查詢日志中。long_query_time的默認值為10,意思是運行10s以上的語句。
默認情況下,MySQL數據庫並不啟動慢查詢日志,需要我們手動來設置這個參數,當然,如果不是調優需要的話,一般不建議啟動該參數,因為開啟慢查詢日志或多或少會帶來一定的性能影響。慢查詢日志支持將日志記錄寫入文件,也支持將日志記錄寫入數據庫表。
5.6官方說明:https://dev.mysql.com/doc/refman/5.6/en/slow-query-log.html
5.7官方說明:https://dev.mysql.com/doc/refman/5.7/en/slow-query-log.html
二、什么情況下產生慢日志?
看圖說話,有很多開關影響着慢日志的生成,相關的參數后面會挨個說明。從上圖可以看出慢日志輸出的內容有兩個,第一執行時間過長(大於設置的long_query_time閾值);第二未使用索引,或者未使用最優的索引。
這兩種日志默認情況下都沒有打開,特別是未使用索引的日志,因為這一類的日志可能會有很多,所以還有個特別的開關log_throttle_queries_not_using_indexes用於限制每分鍾輸出未使用索引的日志數量。
關鍵代碼如下:
Slow log調用棧(MySQL 5.6.34 ):
三、慢日志相關參數
以上應該是最完整的和慢日志相關的所有參數,大多數參數都有前置條件,所以在使用的時候可以參照上面的流程圖。
5.6官方文檔:
1、https://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html
2、https://dev.mysql.com/doc/refman/5.6/en/server-options.html
四、慢日志輸出內容
第一行:標記日志產生的時間,准確說是SQL執行完成的時間點,改行記錄每一秒只打印一條。
第二行:客戶端的賬戶信息,兩個用戶名(第一個是授權賬戶,第二個為登錄賬戶),客戶端IP地址,還有mysqld的線程ID。
第三行:查詢執行的信息,包括查詢時長,鎖持有時長,返回客戶端的行數,掃描行數。通常我需要優化的就是最后一個內容,盡量減少SQL語句掃描的數據行數。
第四行:通過代碼看,貌似和第一行的時間沒有區別。
第五話:最后就是產生慢查詢的SQL語句。
--log-short-format=true:
如果mysqld啟動時指定了--log-short-format參數,則不會輸出第一、第二行。
log-queries-not-using-indexes=on
log_throttle_queries_not_using_indexes > 0 :
如果啟用了以上兩個參數,每分鍾超過log_throttle_queries_not_using_indexes配置的未使用索引的慢日志將會被抑制,被抑制的信息會被匯總,每分鍾輸出一次。
格式如下:
五、慢日志分析工具
官方自帶工具: mysqldumpslow
開源工具:mysqlsla
percona-toolkit:工具包中的pt-query-digest工具可以分析匯總慢查詢信息,具體邏輯可以看SlowLogParser這個函數。
總的來說,MySQL的日志內容本身不復雜,上面3個工具都是用perl腳本實現,代碼行數不超過200行,有興趣的同學也可以自己嘗試着解析下。
詳情可以參閱下這篇文章:
《MySQL 慢查詢設置和分析工具 》:
https://flyerboy.github.io/2016/12/23/mysql_slow/
以上工具可以支撐慢日志的常用統計,但是當我們需要做到SQL級別的統計時,我們還需要取解析SQL把參數提取出來。
六、慢日志的清理與備份
刪除:直接刪除慢日志文件,執行flush logs(必須的)。
備份:先用mv重命名文件(不要跨分區),然后執行flush logs(必須的)。
另外修改系統變量slow_query_log_file也可以立即生效;
執行flush logs,系統會先close當前的句柄,然后重新open;mv , rm日志文件系統並不會報錯,具體的原因可以Google下linux i_count i_nlink ;