1. 程式人生 > >Percona Toolkit使用之pt-kill

Percona Toolkit使用之pt-kill

     pt-kill的功能是殺死匹配一定條件的MySQL查詢。

     用法如下:

pt-kill [OPTIONS] [DSN]

     pt-kill殺死MySQL連線。如果沒有給出檔案,pt-kill連線到MySQL然後從“ SHOW PROCESSLIST ”命令輸出中獲取查詢。否則,就從包含有“ SHOW PROCESSLIST ”輸出的一個或者多個檔案中讀取查詢。如果檔案是“ - ”,pt-kill從STDIN讀取輸入。

     ①kill執行時間超過60s的查詢:

pt-kill --busy-time 60 --kill

     ②條件同上,但是隻print不kill:

pt-kill --busy-time 60 --print

     ③每10s一次找出和kill所有的睡眠程序:

pt-kill --match-command Sleep --kill --victims all --interval 10

     ④列印所有的登入程序:

pt-kill --match-state login --print --victims all

     ⑤找出剛才程序列表裡的哪些查詢匹配條件:

mysql -e "SHOW PROCESSLIST" > proclist.txt
pt-kill --test-matching proclist.txt --busy-time 60 --print

     pt-kill從“ SHOW PROCESSLIST ”中捕捉查詢,篩選,然後kill或者print。這在一些圈子中也被稱為“慢查詢狙擊手”。這個想法出於找出可能消耗太多資源的查詢,然後殺死它們。

     簡單起見,我們討論kill查詢的情況,當然它們也可能僅僅被print(或者未來一些其他的動作),依賴於給出的是什麼選項。

     pt-kill通常連線到MySQL從“ SHOW PROCESSLIST ”裡獲取查詢。或者,也可以從檔案裡面讀取“ SHOW PROCESSLIST ”輸出。在這種情況下,pt-kill不會連線到MySQL,“ --kill ”選項也不會起作用。當讀取檔案時你需要改用“ --print ”選項。通過使用“ --test-matching ”選項讀取檔案,允許你捕捉“ SHOW PROCESSLIST ”後再使用pt-kill測試,這確保你的條件匹配kill恰當的查詢。有很多特殊的規則需要遵守,例如“不要kill複製執行緒”,所以請小心翼翼不要去kill重要的活動。

     需要知道的兩個重要選項是“ --busy-time ”和“ --victims ”。

     首先,鑑於所有的匹配 / 篩選選項從“ SHOW PROCESSLIST ”裡面匹配對應的結果(e.g.“ --match-command ”選項匹配查詢裡的“ Command ”值),“ Time ”值通過“ --busy-time ”選項匹配。參見“ --interval ”。其次,“ --victims ”控制從每個類別裡面匹配的哪些查詢會被kill。預設情況下,最長時間值開銷的查詢(最早的查詢)被kill。

     通常你需要至少指定一個match選項,否則不會有查詢被匹配到。或者,你可以指定“ --match-all ”選項來匹配沒有被“ --ignore ”選項忽略的所有查詢。

     通過幾個步驟來確定哪些查詢被kill(或者print——指定了什麼動作)。第一步是把查詢分組為類別。“ --group-by ”選項控制分組行為。預設情況下,該選項沒有值,所以所有的查詢被分組到一個預設的類別。所有型別的匹配和篩選操作(第二步)被應用到每一個類別。因此,你可能需要對查詢分組,以匹配 / 篩選一些種類,而不是另外其他。第二步是匹配。匹配意味著過濾,因為如果一個查詢不能匹配條件,它將被從自己的類別中移除。第三步是選擇倒黴鬼,也就是每個類別中的哪些查詢將被kill。第四步也就是最後一步是對所有類別中匹配的所有查詢執行一些操作。

     如果只給出“ --kill ”選項,將沒有輸出。如果只給出“ --print ”選項,將打印出加了時間戳的將被kill的每條查詢,如下所示。如果同時給出“ --kill ”和“ --print ”選項,匹配的查詢將被kill,並且每個列印一行。

# 2009-07-15T15:04:01 KILL 8 (Query 42 sec) SELECT * FROM huge_table

     以下為個人本地環境的測試資料。

     print執行時間超過11s的查詢。

mysql> SHOW FULL PROCESSLIST;
+----+------+---------------------+------+---------+------+------------+-----------------------+
| Id | User | Host                | db   | Command | Time | State      | Info                  |
+----+------+---------------------+------+---------+------+------------+-----------------------+
| 12 | root | localhost           | NULL | Query   |    0 | starting   | SHOW FULL PROCESSLIST |
| 21 | root | 192.168.112.1:60537 | NULL | Query   |    6 | User sleep | DO SLEEP(1111)        |
+----+------+---------------------+------+---------+------+------------+-----------------------+
2 rows in set (0.00 sec)

mysql> system pt-kill -h192.168.112.129 -P3306 -uroot -p123456 --busy-time=11 --print
# 2018-04-07T00:23:03 KILL 21 (Query 21 sec) DO SLEEP(1111)

     kill執行時間超過11s的查詢。

mysql> SHOW FULL PROCESSLIST;
+----+------+---------------------+------+---------+------+------------+-----------------------+
| Id | User | Host                | db   | Command | Time | State      | Info                  |
+----+------+---------------------+------+---------+------+------------+-----------------------+
| 12 | root | localhost           | NULL | Query   |    0 | starting   | SHOW FULL PROCESSLIST |
| 24 | root | 192.168.112.1:60591 | NULL | Query   |   50 | User sleep | DO SLEEP(1111)        |
+----+------+---------------------+------+---------+------+------------+-----------------------+
2 rows in set (0.00 sec)

mysql> system pt-kill -h192.168.112.129 -P3306 -uroot -p123456 --busy-time=11 --kill

^Cmysql> 
mysql> SHOW FULL PROCESSLIST;
+----+------+-----------+------+---------+------+----------+-----------------------+
| Id | User | Host      | db   | Command | Time | State    | Info                  |
+----+------+-----------+------+---------+------+----------+-----------------------+
| 12 | root | localhost | NULL | Query   |    0 | starting | SHOW FULL PROCESSLIST |
+----+------+-----------+------+---------+------+----------+-----------------------+
1 row in set (0.00 sec)

     每隔11s執行kill所有的“Command”條件為“Query”的查詢。

mysql> SHOW FULL PROCESSLIST;
+----+------+---------------------+------+---------+------+------------+-----------------------+
| Id | User | Host                | db   | Command | Time | State      | Info                  |
+----+------+---------------------+------+---------+------+------------+-----------------------+
|  3 | root | localhost           | NULL | Query   |    0 | starting   | SHOW FULL PROCESSLIST |
|  4 | root | 192.168.112.1:60861 | NULL | Query   |   54 | User sleep | DO SLEEP(1111)        |
+----+------+---------------------+------+---------+------+------------+-----------------------+
2 rows in set (0.00 sec)

mysql> system pt-kill -h192.168.112.129 -P3306 -uroot -p123456 --match-command=Query --victims=all --interval=11 --kill
^Cmysql> 
mysql> SHOW FULL PROCESSLIST;
+----+------+-----------+------+---------+------+----------+-----------------------+
| Id | User | Host      | db   | Command | Time | State    | Info                  |
+----+------+-----------+------+---------+------+----------+-----------------------+
|  3 | root | localhost | NULL | Query   |    0 | starting | SHOW FULL PROCESSLIST |
+----+------+-----------+------+---------+------+----------+-----------------------+
1 row in set (0.00 sec)

     print所以“State”條件為“User sleep”的查詢。

mysql> SHOW FULL PROCESSLIST;
+----+------+---------------------+------+---------+------+------------+-----------------------+
| Id | User | Host                | db   | Command | Time | State      | Info                  |
+----+------+---------------------+------+---------+------+------------+-----------------------+
|  3 | root | localhost           | NULL | Query   |    0 | starting   | SHOW FULL PROCESSLIST |
|  7 | root | 192.168.112.1:60976 | NULL | Query   |   38 | User sleep | DO SLEEP(1111)        |
+----+------+---------------------+------+---------+------+------------+-----------------------+
2 rows in set (0.00 sec)

mysql> system pt-kill -h192.168.112.129 -P3306 -uroot -p123456 --match-state='User sleep' --victims=all --print
# 2018-04-07T00:30:40 KILL 7 (Query 54 sec) DO SLEEP(1111)

     從程序列表檔案裡找出執行時間超過11s的查詢print出來。

mysql> SHOW FULL PROCESSLIST;
+----+------+---------------------+------+---------+------+------------+-----------------------+
| Id | User | Host                | db   | Command | Time | State      | Info                  |
+----+------+---------------------+------+---------+------+------------+-----------------------+
|  3 | root | localhost           | NULL | Query   |    0 | starting   | SHOW FULL PROCESSLIST |
|  7 | root | 192.168.112.1:60976 | NULL | Query   |  120 | User sleep | DO SLEEP(1111)        |
+----+------+---------------------+------+---------+------+------------+-----------------------+
2 rows in set (0.00 sec)

mysql> system mysql -e "SHOW PROCESSLIST" > proclist.txt
mysql> system pt-kill --test-matching=proclist.txt --busy-time=11 --print
# 2018-04-07T00:32:03 KILL 7 (Query 121 sec) DO SLEEP(1111)

參考: