背景
在MySQL生產環境使用中,肯定會遇到thread_running突然升高問題。thread_running突然升高原因有很多,常見是慢sql,慢sql一般通過show processlist就可已找出執行慢sql和執行的id,今天來說明下由於程序中事務未完成,而導致事務持有鎖未釋放,從而使thread_running突然升高的問題排查。
解決方案
查找問題事務
當thread_running突然升高而show processlit看不到正在執行的慢sql時,則可以通過show engine innodb status中Lock waits for transactions片段去查看是否有正在執行中的事務(下面就是事務正在運行且持續20s),這種情況可能就是有問題的,但有可能不是真正的阻塞線程事務,一般阻塞線程的事務的執行時間是最長的,我們一般只需要把這個片段信息翻到最下面就可以找到有問題的事務,一般只需要將問題事務所在的線程id kill掉即可。
---TRANSACTION 1949, ACTIVE 20 sec
查找阻塞事務執行的sql
查找阻塞事務執行的sql目的是為了方便定位程序哪個部分是有異常的(需要在被kill掉之前進行查找)。程序員在事務運行過程中做了一些其他操作,比如外部服務網絡請求(由於是外部服務我們沒辦法進行控制,一次網絡請求超時就會導致事務運行時間邊長)。
查找阻塞事務的sql可以參考mysql手冊中14.16.2章節,通過下列sql即可查出阻塞事務執行的sql。(從show engine innodb status中看到active的事務的thread_id就是表threads的PROCESSLIST_ID)
SELECT THREAD_ID FROM performance_schema.threads WHERE PROCESSLIST_ID = 6;
SELECT THREAD_ID, SQL_TEXT FROM performance_schema.events_statements_history
WHERE THREAD_ID = 28 ORDER BY EVENT_ID;