轉:mysql show processlist命令 詳解

轉自:http://renxiangzyq.iteye.com/blog/835397php

processlist 命令的輸出結果顯示了有哪些線程在運行,能夠幫助識別出有問題的查詢語句,兩種方式使用這個命令。html

1.        進入 mysql/bin 目錄下輸入 mysqladmin processlist;mysql

2.        啓動 mysql ,輸入 show processlist;linux

若是有 SUPER 權限,則能夠看到所有的線程,不然,只能看到本身發起的線程(這是指,當前對應的 MySQL 賬戶運行的線程)。sql

獲得數據形式以下(只截取了三 條):數據庫

mysql> show processlist;緩存

+-----+-------------+--------------------+-------+---------+-------+----------------------------------+----------服務器

| Id | User  | Host             | db    | Command | Time| State      | Info                                                                                            ide

+-----+-------------+--------------------+-------+---------+-------+----------------------------------+----------優化

|207|root  |192.168.0.20:51718 |mytest | Sleep     | 5     |          | NULL                                                                                                  

|208|root  |192.168.0.20:51719 |mytest | Sleep    | 5    |          | NULL        

|220|root  |192.168.0.20:51731 |mytest |Query    | 84   | Locked  |

select bookname,culture,value,type  from book where id=001

先簡單說一下各列的含義和用途,第一列, id , 不用說了吧,一個標識,你要 kill 一個語句的時候頗有用。 user列, 顯示單前用戶,若是不是 root ,這個命令就只顯示你權限範圍內的 sql 語 句。 host 列,顯示這個語句是從哪一個 ip 的哪 個端口上發出的。呵呵,能夠用來追蹤出問題語句的用戶。 db 列,顯示這個進程目前鏈接的是 哪一個數據庫 command 列,顯示當前鏈接的執行的命令,通常就是休眠( sleep ),查詢( query ),鏈接( connect )。 time 列,此這個狀態持續的時間,單位是秒。 state 列,顯示使用當前鏈接的 sql 語句的狀態,很重要的列,後續會有全部的狀態的描述,請注意, state 只是語句執行中的某一個狀態,一個 sql 語 句,已查詢爲例,可能須要通過 copying to tmp table ,Sorting result , Sending data 等狀態才 能夠完成, info 列,顯示這個 sql 語 句,由於長度有限,因此長的 sql 語句就顯示不全,可是一個判斷問題語句的重要依據。

這個命令中最關鍵的就是 state 列, mysql 列出的狀態主要有如下幾 種:

 Checking table
 正在檢查數據表(這是自動的)。 

 Closing tables
 正在將表中修改的數據刷新到磁盤中,同時正在關閉已經用完的表。這是一個很快的操做,若是不是這 樣的話,就應該確認磁盤空間是否已經滿了或者磁盤是否正處於重負中。 

 Connect Out
 複製從服務器正在鏈接主服務器。 

 Copying to tmp table on disk
 因爲臨時結果集大 於 tmp_table_size ,正在將臨時表從內存存儲轉爲磁盤存儲以此節省內存。 

 Creating tmp table
 正在建立臨時表以存放部分查詢結果。 

 deleting from main table
 服務器正在執行多表刪除中 的第一部分,剛刪除第一個表。 

 deleting from reference tables
 服務器正在執行多表刪除中的第二部 分,正在刪除其餘 表的記錄。 

 Flushing tables
 正在執行 FLUSH TABLES ,等待其餘線程關閉數據表。 

 Killed
 發送了一個 kill 請 求給某線程,那麼這個線程將會檢查 kill 標誌位,同時會放棄下一個 kill 請 求。 MySQL 會在每次的主循環中檢查 kill 標 志位,不過有些狀況下該線程可能會過一小段才能死掉。若是該線程程被其餘線程鎖住了,那麼 kill請 求會在鎖釋放時立刻生效。 

 Locked
 被其餘查詢鎖住了。 

 Sending data
 正在處理 SELECT 查詢的記錄,同時正在把結果發送給客戶端。 

 Sorting for group
 正在爲 GROUP BY 作排序。 

 Sorting for order
 正在爲 ORDER BY 作排序。 

 Opening tables
 這個過程應該會很快,除非受到其餘因素的干擾。例如,在執 ALTER TABLE 或 LOCK TABLE 語句行完以 前,數據表沒法被其餘線程打開。 正嘗試打開一個表。 

 Removing duplicates
 正在執行一個 SELECT DISTINCT 方式的查詢,可是 MySQL 無 法在前一個階段優化掉那些重複的記錄。所以, MySQL須要再次去掉重複的記錄,而後再 把結果發送給客戶端。 

 Reopen table
 得到了對一個表的鎖,可是必須在表結構修改以後才能得到這個鎖。已經釋放鎖,關閉數據表,正嘗試 從新打開數據表。 

 Repair by sorting
 修復指令正在排序以建立索引。 

 Repair with keycache
 修復指令正在利用索引緩存一個 一個地建立新索引。它會比 Repair by sorting 慢些。 

 Searching rows for update
 正在講符合條件的記錄找 出來以備更新。它必須在 UPDATE 要修改相關的記錄以前就完成了。 

 Sleeping
 正在等待客戶端發送新請求 
.
  
System lock
 正在等待取得一個外部的系統鎖。若是當前沒有運行多個 mysqld 服務器同時請求同一個表,那麼能夠經過增長 --skip-external-locking 參數來禁止外部系統鎖。 

 Upgrading lock
  INSERT DELAYED 正在 嘗試取得一個鎖表以插入新記錄。 

 Updating
 正在搜索匹配的記錄,而且修改它們。 

 User Lock
 正在等待 GET_LOCK() 。 

 Waiting for tables
 該線程獲得通知,數據表結構已經被修改了,須要從新打開數據表以取得新的結構。而後,爲了能的重 新打開數據表,必須等到全部其餘線程關閉這個表。如下幾種狀況下會產生這個通知: FLUSH TABLES tbl_name, ALTER TABLE, RENAME TABLE, REPAIR TABLE, ANALYZE TABLE, 或 OPTIMIZE TABLE 。 

 waiting for handler insert
  INSERT DELAYED 已經處理完了全部待處理的插入操做,正在等待新的請求。 

 大 部分狀態對應很快的操做,只要有一個線程保持同一個狀態好幾秒鐘,那麼多是有問題發生了,須要檢查一下。 
 還 有其餘的狀態沒在上面中列出來,不過它們大部分只是在查看服務器是否有存在錯誤是才用得着。

mysql 手冊裏有全部狀態的說明,連接以下: http://dev.mysql.com/doc/refman/5.0/en/general-thread-states.html

中文說明取自 http://www.linuxpk.com/5747.html

 

 

當MySQL繁忙的時候運行show processlist,會發現有不少行輸出,每行輸出對應一個MySQL鏈接。怎麼診斷髮起鏈接的進程是哪一個?它當前正在幹嗎呢?

首先,須要經過TCP Socket而不是Unix Socket鏈接MySQL,這樣在show processlist的輸出中就會有來源端口號。以下,

mysql> show processlist;
+——–+——–+—————–+——+———+——+——-+——————+
| Id | User | Host | db | Command | Time | State | Info |
+——–+——–+—————–+——+———+——+——-+——————+
| 277801 | mydbuser | localhost:35558 | mydb | Sleep | 1 | | NULL |
| 277804 | mydbuser | localhost:35561 | mydb | Sleep | 1 | | NULL |
| 277805 | mydbuser | localhost:35562 | mydb | Sleep | 0 | | NULL |
+——–+——–+—————–+——+———+——+——-+——————+

在Host列有來源IP和端口號,而後咱們從鏈接機器查看端口號是誰打開的,

[root@localhost ~]# netstat -ntp | grep 35558
… 124.115.0.68:35558 ESTABLISHED 18783/httpd

可知進程18783發起的MySQL鏈接來源端口是35558,而後就能夠用strace觀察這個進程了。若是是Apache的PHP腳本,還能夠 用proctitle模塊( http://pecl.php.net/package/proctitle/ )設置腳本的狀態信息。

lsof也能根據端口號顯示進程號,細節請參考手冊。http://www.mysqlperformanceblog.com/2007/02/08/debugging-sleeping-connections-with-mysql/

相關文章
相關標籤/搜索