1. 程式人生 > >MySQL分析數據運行狀態利器【SHOW PROCESSLIST】

MySQL分析數據運行狀態利器【SHOW PROCESSLIST】

說明 ner har table sent pos 意思 schema root

這個博文,將只是簡單的記錄一下,我們的數據庫操作和使用中,加索引加不上去,分析的過程,其實比較簡單,就是看有沒有連接進程還在操作表。有的話,將其停掉(不影響業務的場景下)。

今天的主角是:

SHOW [FULL] PROCESSLIST

官方文檔的描述如下:

SHOW PROCESSLIST shows you which threads are running. You can also get this information from the
INFORMATION_SCHEMA PROCESSLIST table or the mysqladmin processlist command. If you have
the PROCESS privilege, you can see all threads. Otherwise, you can see only your own threads (that 
is, threads associated with the MySQL account that you are using). If you do not use the FULL keyword, only the first 100 characters of each statement are shown in the Info field.

意思就是說上述指令是用來查看那些線程正在運行,你也可以得到這些信息,從INFORMATION_SCHEMA PROCESSLIST這個表,或者通過mysqladmin processlist指令。如果你有PROCESS權限,你可以查看所有的線程。否則,你只能查看你自己當前賬戶的線程。如果你沒有使用FULL關鍵字,你只能查看每個記錄中Info字段裏面的前100個字符

具體操作:

mysql> show processlist;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    46661
Current database: advsql

+-------+-----------+-------------------+--------+---------+-------+-------+------------------+
| Id    | User      | Host              | db     | Command | Time  | State | Info             |
+-------+-----------+-------------------+--------+---------+-------+-------+------------------+
| 46586
| tkcssuser | 10.90.13.61:55838 | tkcss | Sleep | 42 | | NULL | | 46660 | tkcssuser | 10.90.13.8:52008 | tkcss | Sleep | 11041 | | NULL | | 46661 | root | localhost | advsql | Query | 0 | init | show processlist | +-------+-----------+-------------------+--------+---------+-------+-------+------------------+ 3 rows in set (0.01 sec)

通過查詢information_schema的processlist表:

mysql> select * from information_schema.processlist;
+-------+-----------+-------------------+--------+---------+-------+-----------+----------------------------------------------+
| ID    | USER      | HOST              | DB     | COMMAND | TIME  | STATE     | INFO                                         |
+-------+-----------+-------------------+--------+---------+-------+-----------+----------------------------------------------+
| 46661 | root      | localhost         | advsql | Query   |     0 | executing | select * from information_schema.processlist |
| 46586 | tkcssuser | 10.90.13.61:55838 | tkcss  | Sleep   |   279 |           | NULL                                         |
| 46660 | tkcssuser | 10.90.13.8:52008  | tkcss  | Sleep   | 11578 |           | NULL                                         |
+-------+-----------+-------------------+--------+---------+-------+-----------+----------------------------------------------+
3 rows in set (0.00 sec)

或者mysqladmin processlist指令:

[root@localhost ~]# mysqladmin processlist -u root -p 
Enter password: 
+-------+-----------+-------------------+--------+---------+-------+-------+------------------+
| Id    | User      | Host              | db     | Command | Time  | State | Info             |
+-------+-----------+-------------------+--------+---------+-------+-------+------------------+
| 46586 | tkcssuser | 10.90.13.61:55838 | tkcss  | Sleep   | 138   |       |                  |
| 46660 | tkcssuser | 10.90.13.8:52008  | tkcss  | Sleep   | 12037 |       |                  |
| 46661 | root      | localhost         | advsql | Sleep   | 459   |       |                  |
| 46662 | root      | localhost         |        | Query   | 0     | init  | show processlist |
+-------+-----------+-------------------+--------+---------+-------+-------+------------------+

關於這個命令的價值,官方的介紹如下:

The SHOW PROCESSLIST statement is very useful if you get the “too many connections” error message
and want to find out what is going on. MySQL reserves one extra connection to be used by accounts that
have the SUPER privilege, to ensure that administrators should always be able to connect and check the
system (assuming that you are not giving this privilege to all your users).

Threads can be killed with the KILL statement.

運行的線程,可以通過KILL指令將其殺掉。這個信息非常重要。

這裏,可以看到SHOW PROCESSLIST指令裏面的輸出內容,有幾個字段,下面給予解釋說明,只有搞清楚了這些字段的含義,才對我們的實際項目問題分析才有價值:

  • Id:

    The connection identifier. This is the same type of value displayed in the ID column of the
    INFORMATION_SCHEMA.PROCESSLIST table, the PROCESSLIST_ID column of the Performance
    Schema threads table, and returned by the CONNECTION_ID() function.

  • User:

    The MySQL user who issued the statement. If this is system user, it refers to a nonclient thread
    spawned by the server to handle tasks internally. This could be the I/O or SQL thread used on replication
    slaves or a delayed-row handler. unauthenticated user refers to a thread that has become
    associated with a client connection but for which authentication of the client user has not yet been done.
    event_scheduler refers to the thread that monitors scheduled events. For system user, there is no
    host specified in the Host column.

  • Host:

    The host name of the client issuing the statement (except for system user where there is no host).
    SHOW PROCESSLIST reports the host name for TCP/IP connections in host_name:client_port
    format to make it easier to determine which client is doing what.

  • db:

   The default database, if one is selected, otherwise NULL.

  • Command:

   The type of command the thread is executing. 例如上面的例子中,Sleep,或者Query

  • Time:

    The time in seconds that the thread has been in its current state. For a slave SQL thread, the value is
    the number of seconds between the timestamp of the last replicated event and the real time of the slave
    machine.

  • State:

    Most states correspond to very quick operations. If a thread stays in a given state for many seconds,
    there might be a problem that needs to be investigated.

   An action, event, or state that indicates what the thread is doing.

  • Info:

    The statement the thread is executing, or NULL if it is not executing any statement. The statement might
    be the one sent to the server, or an innermost statement if the statement executes other statements. For
    example, if a CALL statement executes a stored procedure that is executing a SELECT statement, the
    Info value shows the SELECT statement.

上述信息的解釋當中,對於我們分析問題,尤為重要的是Id,Host,Time,State以及Info字段。這幾個當中,第一眼能讓我們看出問題的是Time,State和Info字段。我們若想看得更詳細的Info字段,請用SHOW FULL PROCESSLIST指令。註意前面的命令解釋內容。

我們線上的一個問題,就是加索引加不上去,我們將應用停掉還是加不上去,通過SHOW PROCESSLIST指令,發現有好多線程Command處於Query狀態。最長的Time字段顯示達到230172seconds,換算成小時,都63個小時,見鬼啊!!!!(這個地方有疑問

為了解決問題,立即調用KILL指令,前面介紹時提到的。

KILL [CONNECTION | QUERY] processlist_id

官方介紹:

Each connection to mysqld runs in a separate thread. You can kill a thread with the KILL
processlist_id statement.

參數中的processlist_id,來源於show processlist結果列表中的id字段。

kill指令支持兩個可選參數,CONNECTION以及QUERY。

? KILL CONNECTION is the same as KILL with no modifier: It terminates the connection associated with
the given processlist_id, after terminating any statement the connection is executing.
? KILL QUERY terminates the statement the connection is currently executing, but leaves the connection
itself intact.

很簡單,connection選項,kill的時候,將連接也斷掉,而query選項,kill的過程只是將該指令殺掉,連接還保持。 kill指令不指定connection或者query選項時,默認是connection。

到此,今天要介紹的MySQL的查看數據運行連接狀態的內容到此結束。

最後補充一點的是,前面提到的“這個地方有疑問”,真是有疑問,我們的應用3臺服務器,6個tomcat應用,全部殺進程停掉了,為何最終SHOW PROCESSLIST裏面還會出現有正在運行的QUERY,而且time都是20多萬秒,難道一個select要查幾天?如下圖:

技術分享圖片

我們的應用在3天內,兩個晚上,每天都會殺掉應用,做版本更新操作,怎麽說,select也不會出現20多萬秒吧?有誰能幫忙分析下,我的懷疑是這些被show processlist查出來的進程,在執行query的時候,MySQL內部發生死鎖導致的,數據狀態顯示這個查詢一直在,沒有結束,因為死鎖,若不殺進程,那個Time顯示的時間將會更長。。。

還請高手幫忙分析或者給予一些線索。

MySQL分析數據運行狀態利器【SHOW PROCESSLIST】