說明
- Mysql的查詢訊日志是Mysql提供的一種日志記錄,它用來記錄在Mysql中響應時間超過門檻值的語句
- 具體指運作時間超過long_query_time值得SQL,則會被記錄到慢查詢日志中。long_query_time的預設為10,意識是運作10秒以上的語句。
- 由它來看那些SQL語句超出了我們的最大忍耐值,比如一條SQL執行超過了5秒,我們就算慢查詢,我們就可以結合Explain進行分析。
檢視是否開啟及如何開啟
預設Mysql沒有開啟慢查詢,需要我們說動設定這個參數。當然,如果不是調優需要的話,一般不建議開啟該參數,因為開啟慢查詢日志會或多或少帶來一定的性能影響。慢查詢日志支援将日志寫入檔案。
進入mysql終端檢視是否開啟(我這裡都是自己改過的)
mysql
上面查詢結果第一行,這裡是開啟的,第二行是預設查詢路徑檔案名。
mysql> set global slow_query_log = 0|1; //設定開啟或者關閉,0為關閉,1為開啟
如果使用set global slow_query_log 指令開啟慢查詢日志,隻對
目前資料庫生效,如果Mysql重新開機後則會失效。
補充:如果通過終端指令設定的話,再查詢是看不到修改結果的,需要新開啟一個視窗檢視即可。
如果要永久生效,必須修改my.cnf配置檔案(其他系統變量也是如此),
修改my.cnf檔案,[mysqld]下增加和修改參數slow_query_log和slow_query_log_file後,然後重新開機MySQL伺服器,也即将如下兩行配置進my.cnf檔案
slow_query_log = 1
slow_query_log_file = /data/mysql/mysql-slow.log
[mysqld]
slow_query_log = 1
long_query_time = 1
slow_query_log_file = /data/mysql/mysql-slow.log
關于慢查詢的參數slow_query_log_file,它指定慢查詢日志檔案的存放路徑,
系統預設會給一個預設的host_name_show.log(如果沒有指定參數slow_query_log_file的話)。
那麼開啟了慢日志後,怎麼樣的SQL才會記錄到慢查詢當中呢?
- 這個是由參數long_query_time控制,預設情況下long_query_time的值是10秒。
- 指令SHOW VARIABLES LIKE 'long_query_time';
mysql> show variables like 'long_query_time';
+-----------------+----------+
| Variable_name | Value |
+-----------------+----------+
| long_query_time | 10.00000 |
+-----------------+----------+
可以使用指令修改,也可以在my.cnf參數裡面修改,修改完記得習慣性重新開機服務。還是那句話,不建議生産環境開啟。
mysql
假如SQL運作時間剛好等于long_query_time的情況,并不會被記錄下來,也就是說,在Mysql源碼裡是
判斷大于long_query_time,而非大于等于。Case
- 檢視目前多少秒算慢:SHOW VARIABLES LIKE 'long_query_time%';
- 設定慢的阙值時間:set global long_query_time=3;
- 為什麼設定後看不出變化:
- 需要重新連接配接或新開一個回話才能看到修改值; SHOW VARIABLES LIKE 'long_query_time%';
- SHOW GLOBAL VARIABLES LIKE 'long_query_time%';
- 記錄慢SQL并後續分析:select sleep(4);
檢視慢查詢日志檔案
# cat /data/mysql/mysql-slow.log
#
# select sleep(5);
# Time: 2018-01-20T18:10:24.443517Z
# [email protected]: root[root] @ localhost [] Id: 3
# Query_time: 5.000564 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 0
use test_db; #使用的資料庫
SET timestamp=1524276624; #時間戳
select sleep(5); #問題SQL
以上資訊包括實際查詢時間5.000564秒,時間戳timestamp=1524276624,還有庫test_db,出問題的SQL。
- 檢視目前系統中多少條滿記錄:show global status like '%Slow_queries%';
mysql> show global status like '%Slow_queries%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Slow_queries | 1 |
+---------------+-------+
1 row in set (0.03 sec)
可以作為系統健康檢查度來查詢。(什麼意思:如果系統裡面充滿了大量的慢SQL,都超過阙值,這時系統就需要及時優化)
配置版show_query_log = 1;
show_query_log_file=/var/lib/mysql/mysql_slow.log
log_query_time=3;
log_output=FILE
mysqldumpslow用法講解
- 在生産環境中,如果要手動分析日志,查找、分析SQL,顯然是一個體力活,MySQL提供了日志分析工具mysqldumpslow。
上面測試的慢查詢SQL隻有一條,假如在實際的生産環境中,慢查詢SQL遠遠高于測試的數量,十幾條甚至幾十條,假如幾條慢查詢出現的頻率很高,我們能做到根據輕重優先級來分析并排除那是不是更好?那麼就用到了mysqldumpslow
[[email protected] mysql]# mysqldumpslow --help ----------------------------------------------------//執行指令
Usage: mysqldumpslow [ OPTS... ] [ LOGS... ]
Parse and summarize the MySQL slow query log. Options are
--verbose verbose
--debug debug
--help write this text to standard output
-v verbose
-d debug
-s ORDER what to sort by (al, at, ar, c, l, r, t), 'at' is default
al: average lock time
ar: average rows sent
at: average query time
c: count
l: lock time
r: rows sent
t: query time
-r reverse the sort order (largest last instead of first)
-t NUM just show the top n queries
-a don't abstract all numbers to N and strings to 'S'
-n NUM abstract numbers with at least n digits within names
-g PATTERN grep: only consider stmts that include this string
-h HOSTNAME hostname of db server for *-slow.log filename (can be wildcard),
default is '*', i.e. match all
-i NAME name of server instance (if using mysql.server startup script)
-l don't subtract lock time from total time
s:是表示按照何種方式排序
c:通路次數
i:鎖定時間
r:傳回記錄
t:查詢時間
al:平均鎖定時間
ar:平均傳回記錄數
at:平均查詢時間
t:即為傳回前面多少條資料
g:後邊搭配一個正則比對模式,大小寫不敏感
mysqldumpslow -s r -t 10 /data/mysql/mysql-slow.log //得到傳回記錄集最多的10個SQL
mysqldumpslow -s c -t 10 /data/mysql/mysql-slow.log //得到通路次數最多的10個SQL
mysqldumpslow -s t -t 10 -g "left join" /data/mysql/mysql-slow.log //得到按照時間排序的前10條裡面含有做了連接配接的查詢SQL
mysqldumpslow -s r -t 10 /data/mysql/mysql-slow.log | more //另外建議在使用這些指令時結合|和more使用,否則有可能出現爆屏情況
OK~既然學習了,就運用到實際工作中吧~