Linux中國

怎樣把壞的MySQL查詢找到並殺死?

為了瀏覽當前正在運行的查詢,登陸到MySQL終端,然後運行『show processlist』命令:

mysql> show processlist; 

+--------+--------+-----------------+---------+---------+-------+-------+------------------+-----------+---------------+-----------+
| Id     | User   | Host            | db      | Command | Time  | State | Info             | Rows_sent | Rows_examined | Rows_read |
+--------+--------+-----------------+---------+---------+-------+-------+------------------+-----------+---------------+-----------+
|  78233 | root   | 127.0.0.1:37527 | mysql   | Sleep   | 16474 |       | NULL             |         6 |             6 |         6 |
|  84546 | root   | 127.0.0.1:48593 | mysql   | Sleep   | 13237 |       | NULL             |         2 |             2 |         2 |
| 107083 | root   | 127.0.0.1:56451 | mysql   | Sleep   | 15488 |       | NULL             |         1 |           121 |       121 |
| 131455 | root   | 127.0.0.1:48550 | NULL    | Query   |     0 | NULL  | show processlist |         0 |             0 |         0 |
+--------+--------+-----------------+---------+---------+-------+-------+------------------+-----------+---------------+-----------+
4 rows in set (0.03 sec)

首先你應該查看'Time'項,這裡記錄了進程執行 "做其當做的事情" 操作的秒數。『command』項處於『Sleep』 狀態的進程表示其正在等待接受查詢,因此,它並沒有消耗任何資源。對於其他任何進程而言,『Time』超過一定的秒數表明出現問題。

在上面的例子中,唯一運行的查詢是我們的『show processlist』命令。讓我們來看看如果我們有一個寫的很爛的查詢是怎麼樣的:

mysql> show processlist; 

+--------+--------+-----------------+-----------+---------+-------+--------------+----------------------------------+-----------+---------------+-----------+
| Id     | User   | Host            | db        | Command | Time  | State        | Info                             | Rows_sent | Rows_examined | Rows_read |
+--------+--------+-----------------+-----------+---------+-------+--------------+----------------------------------+-----------+---------------+-----------+
|  78233 | root   | 127.0.0.1:37527 | example   | Sleep   | 18046 |              | NULL                             |         6 |             6 |         6 |
|  84546 | root   | 127.0.0.1:48593 | example   | Sleep   | 14809 |              | NULL                             |         2 |             2 |         2 |
| 107083 | root   | 127.0.0.1:56451 | example   | Sleep   | 17060 |              | NULL                             |         1 |           121 |       121 |
| 132033 | root   | 127.0.0.1:54642 | example   | Query   |    27 | Sending data | select max(subtotal) from orders |         0 |             0 |         0 |
| 133933 | root   | 127.0.0.1:48679 | NULL      | Query   |     0 | NULL         | show processlist                 |         0 |             0 |         0 |
| 134122 | root   | 127.0.0.1:49264 | example   | Sleep   |     0 |              | NULL                             |         0 |             0 |         0 |
+--------+--------+-----------------+-----------+---------+-------+--------------+----------------------------------+-----------+---------------+-----------+
6 rows in set (0.00 sec)

啊哈!現在我們看到有一個查詢運行了將近30秒。如果我們不想讓它的進程繼續運行,可以將它的'Id'傳遞給kill命令:

mysql> kill 132033;
Query OK, 0 rows affected (0.00 sec)
mysql> 

(注意 由於我們沒有改變任何數據,MySQL總是報告0行被影響。)

明智的使用kill命令能夠清除積壓的查詢。然而,要記住的是,那不是一種永久的方法 - 如果這些查詢來自你的程序,你需要去重寫它們,或者將繼續看到相同的問題不斷出現。

另請參閱

關於不同『命令』的MySQL文檔:

via: http://xmodulo.com/2014/07/find-kill-misbehaving-mysql-queries.html

譯者:hunanchenxingyu 校對:wxy

本文由 LCTT 原創翻譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的電子郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國