MySQL 執行Kill命令后,執行命令為啥沒馬上停止?


這些“kill 不掉”的情況,其實是因為發送 kill 命令的客戶端,並沒有強行停止目標線程的執行,而只是設置了個狀態,並喚醒對應的線程。而被 kill 的線程,需要執行到判斷狀態的“埋點”,才會開始進入終止邏輯階段。並且,終止邏輯本身也是需要耗費時間的。

kill 命令

MySQL 提供了 kill query + 線程 id 和 kill [connection] + 線程id 兩種停止執行命令的指令。
kill connection 中的 connection 可以省略。

kill connection 命令執行過程:
1、把線程狀態設置為KILL_CONNECTION
2、關閉請求線程的網絡連接。此時show processlist的顯示結果為Killed。主要原因是如果一個線程的狀態是KILL_CONNECTION, 就把Command列顯示成Killed。

kill connection 先把客戶端的sql連接斷開,后續執行流程走kill query

kill 命令的運行原理

將執行線程的運行狀態改成THD::KILL_QUERY狀態,並向執行線程發一個信號,這個信號有點像 我們用kill -9 向操作系統發送終止信號。

另外kill connection 會斷開網絡連接,然后客戶端會重新在一個線程發送kill query命令,show processlist會將kill connection的狀態顯示為Killed。然而其實innodb 可能因為io繁忙,鎖等待,並發線程數不夠,而沒有機會終止當前線程。出現這種情況,及時騰出系統資源,比如IO,終止掉其他線程,增大innodb_thread_concurrency, 然后等待線程執行完畢。
總而言之可以分成兩大類:

  • 線程沒有執行到判斷線程狀態的邏輯
  • 終止邏輯耗時太長:
  • kill超大事務,回滾時需要回收事務期間生成的數據包版本,耗時很長;
  • DDL命令執行到最后階段,如果被kill, 需要刪除中間過程的臨時文件,也可能受IO資源影響耗時較久。
  • 大查詢回滾,如果查詢過程中生成了比較大的臨時文件,加上此時文件系統壓力大,刪除臨時文件可能需要等待IO資源,導致耗時較長。

這也是碰到一個被Killed事務一直處於回滾狀態時,此時重啟MySQL線程也沒用,重啟后事務還是會回滾。

其他

如果數據集的表很多,比如6萬多表,客戶端連接上去時,需要初始化本地資源,用來支持命令行不全表名,這個時候可以通過 -A 參數略過。

另外--quick 可以達跳過自動補全功能,quick指的時加速客戶端的目的,此時客戶端放棄為請求結果使用本地緩存的策略,而是不緩存,讀一個處理一個,這樣反而會影響服務端的吞吐量。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM