閱讀本文大概需要 2.8 分鐘。
MySQL 對我說 「Too young, too naive!"
大概過程
在測試環境 Docker 容器中,在跨進程調用服務的時候,A 應用通過 Dubbo 調用 B 應用的 RPC 介面,發現 B 應用介面超時錯誤,接著通過 debug 和日誌,發現具體耗時的地方在於一句簡單 SQL 執行,但是耗時超過 1000ms。
通過查看資料庫的進程列表,發現是有死鎖鎖表了,很多進程狀態 status 處於 sending data,最後為鎖住的表添加索引,並且 kill 掉阻塞的請求,解除死鎖,服務速度恢復正常。
下面記錄的是大致排查過程:
通過觀察業務代碼,確認沒有內存溢出或者其它事務問題,於是只能考慮 Docker 環境的資料庫和 jvm 底層詳情了。
使用 Druid 監控 SQL 執行狀態
通過日誌,發現有一句 SQL 嚴重超時,一句簡單 SQL,原本是批量插入多條記錄,為了定位問題,測試時 Mybatis 只插入一條記錄,但即便如此,還是耗時 10 秒。