作者:洪斌
愛可生南區負責人兼技術服務總監,MySQL ACE,擅長數據庫架構規劃、故障診斷、性能優化分析,實踐經驗豐富,幫助各行業客戶解決 MySQL 技術問題,爲金融、運營商、互聯網等行業客戶提供 MySQL 整體解決方案。
本文來源:轉載自公衆號-玩轉MySQL
*愛可生開源社區出品,原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。
你是否會經常遇到 MySQL hang 了而不知所措?面對繁雜的 callstack 信息如何才能快速分析出原因?
本文將通過一個案例,介紹如何快速分析這類問題的方法。
當我們遇到 MySQL hang 的場景時,大概率是程序內部發生了 mutex 衝突造成的。這時我們需要在重啓服務前,先蒐集 callstack 信息。
pstack `pidof mysqld` > mysql_callstack
注意:mysqld 需要包含符號表
有了 callstack 信息,我們便可以開始進行分析了。
分析步驟
1. 首先,在 callstack 日誌篩選出每個線程調用 inline_mysql_mutex_lock 前的函數,以及對應的 mutex 代碼位置,此處便是線程在等待的 mutex。
2. 然後,從該函數向前遍歷每個函數調用,尋找這些函數,看已經成功獲得哪些 mutex。
這裏我用腳本對日誌進行格式化處理,將每個函數都映射到了 github 的代碼位置,點擊鏈接可以直接跳轉,使用 Chrome 瀏覽器配合 sourcegraph 查看代碼也很香。
總結
由於 show binlog logs 操作、purge binlog 以及從讀取 performance_schema 讀取會話變量幾個操作並行發生產生 mutex 衝突,導致無法新建連接請求。
-
show binary logs,持有 LOCK_log,等待 LOCK_index
-
binlog purge,持有 LOCK_index, 等待 LOCK_thd_data
-
讀取 performance_schema.session_variables,持有 LOCK_thd_data, LOCK_global_system_variables, 等待 LOCK_log
-
新建連接,等待 LOCK_global_system_variables
最終確認是 binlog_transaction_dependency_* 變量的讀取需要獲取 LOCK_log 鎖,此處容易造成死鎖,MySQL 5.7.25 修復了此問題。
點擊原文鏈接,查看分析腳本
本文分享自微信公衆號 - 愛可生開源社區(ActiontechOSS)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。