MySQL Semaphore wait has lasted使用詳解
MySQL 5.7.19 版本出現(xiàn) Semaphore wait has lasted > 600 seconds 錯誤,意味著 InnoDB 內(nèi)部某些線程等待信號量超過了10分鐘,導致數(shù)據(jù)庫掛起崩潰。
針對這個問題,排查和定位的思路及步驟如下:
1. 理解信號量(Semaphore)和等待的背景
- InnoDB 通過信號量機制保護共享資源訪問,例如緩沖池頁、鎖、事務信息等。
- 長時間等待信號量一般是死鎖、資源競爭、內(nèi)部異?;騃O瓶頸導致的。
- 錯誤日志中會列出等待信號量的線程堆棧位置(源碼文件 + 行號),有助定位是哪類資源阻塞。
2. 收集環(huán)境與上下文信息
MySQL版本:
- 5.7.19,是較早的5.7版本,InnoDB還有一些已修復的問題,建議考慮升級。
服務器硬件與資源狀況:
- CPU、內(nèi)存利用率
- 磁盤IO狀況(IOPS、延遲)
數(shù)據(jù)庫負載情況:
- 并發(fā)連接數(shù)
- 讀寫比例
- 是否有長事務/大事務
具體業(yè)務場景:
- 當時運行什么SQL,是否有大量INSERT/UPDATE/DELETE
- 是否有DDL操作(alter、drop)
3. 查看MySQL錯誤日志和InnoDB狀態(tài)
a. 錯誤日志中的關鍵信息
確認報錯線程對應的源碼文件和行號:
mtr0mtr.cc,row0ins.cc 等,分別代表:
mtr0mtr.cc:多版本事務相關管理(Mini-transaction)row0ins.cc:行插入相關代碼
這些提示可能表明在插入操作中出現(xiàn)了阻塞。
b. 通過SHOW ENGINE INNODB STATUS\G觀察
- 鎖等待情況(LATEST DETECTED DEADLOCK)
- 當前活躍事務列表
- semaphore wait 信息(
SEMAPHORE WAIT塊) - 主線程或阻塞線程的詳細信息
4. 結(jié)合源碼行號,定位具體阻塞點
可以通過查看5.7.19版本源碼對應文件(MySQL官方github或者源碼包)定位:
mtr0mtr.cc line 567
涉及Mini-transaction相關鎖等待,可能是InnoDB內(nèi)部的metadata鎖或緩沖池訪問競爭。
row0ins.cc line 193
插入行時等待信號量,可能是插入緩沖區(qū)競爭或插入鎖等待。
5. 重點排查方向
5.1 長事務導致鎖資源占用
SHOW PROCESSLIST看是否存在長時間未提交的事務。INFORMATION_SCHEMA.INNODB_TRX查看當前活動事務。- 關閉長事務或者合理設置事務超時。
5.2 高并發(fā)寫入導致緩沖池爭用
高并發(fā)大批量寫入,緩沖池頁鎖爭用嚴重。
調(diào)整 InnoDB 參數(shù),如:
innodb_thread_concurrencyinnodb_lock_wait_timeoutinnodb_buffer_pool_size(確保足夠大,避免頻繁刷盤)
5.3 磁盤IO瓶頸
- 使用系統(tǒng)工具(
iostat,vmstat)檢查磁盤負載和延遲。 - 高IO延遲會導致InnoDB鎖等待。
5.4 表空間或數(shù)據(jù)頁損壞
- 使用
CHECK TABLE檢查相關表。 - 參考錯誤日志是否有提示頁損壞。
6. 其他診斷技巧
6.1 啟用詳細InnoDB調(diào)試日志
啟動MySQL時添加:
[mysqld] innodb_print_all_deadlocks=ON innodb_lock_wait_timeout=50
查看死鎖詳細信息。
6.2 使用性能Schema定位鎖等待
- 查詢
performance_schema.data_locks和performance_schema.data_lock_waits,定位鎖資源。
7. 解決建議總結(jié)
| 問題點 | 排查方法 | 解決措施 |
|---|---|---|
| 長事務占用鎖 | SHOW PROCESSLIST, INNODB_TRX | 關閉或優(yōu)化長事務,合理拆分事務 |
| 高并發(fā)寫壓力大 | 觀察緩沖池爭用,線程鎖等待 | 優(yōu)化參數(shù),分批寫入,升級版本 |
| 磁盤IO瓶頸 | iostat, vmstat | 優(yōu)化存儲,使用SSD,提高IO性能 |
| 表空間或頁損壞 | CHECK TABLE, innodb_force_recovery嘗試 | 恢復數(shù)據(jù),導出備份,重建表空間 |
| InnoDB版本缺陷 | 官方Bug報告,源碼分析 | 升級MySQL版本到最新穩(wěn)定版 |
8. 典型診斷命令舉例
-- 查看當前阻塞事務 SELECT * FROM information_schema.innodb_trx\G; -- 查看當前等待鎖的線程 SELECT * FROM performance_schema.data_locks WHERE LOCK_STATUS='WAITING'; -- 查看進程列表,看長時間執(zhí)行的SQL SHOW FULL PROCESSLIST; -- 查看死鎖日志(在錯誤日志中) -- 或啟用 innodb_print_all_deadlocks=ON 后捕獲
總結(jié)
先從當前活躍事務和鎖等待入手排查。
結(jié)合InnoDB狀態(tài)和系統(tǒng)IO性能分析瓶頸。
若懷疑數(shù)據(jù)損壞,嘗試使用 innodb_force_recovery。
5.7.19版本較老,建議升級至5.7較新版本,或者8.0版本,獲得更多穩(wěn)定性和bug修復。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
- 解決mysql插入數(shù)據(jù)鎖等待超時報錯:Lock?wait?timeout?exceeded;try?restarting?transaction
- MySQL數(shù)據(jù)庫wait_timeout參數(shù)詳細介紹
- MySQL鎖等待超時問題的原因和解決方案(Lock wait timeout exceeded; try restarting transaction)
- mysql死鎖(dead lock)與鎖等待(lock wait)的出現(xiàn)解決
- MySQL Lock wait timeout exceeded錯誤解決
- mysql之連接超時wait_timeout問題及解決方案
- MySQL出現(xiàn)"Lock?wait?timeout?exceeded"錯誤的原因是什么詳解
相關文章
Mysql錯誤Every derived table must have its own alias解決方法
這篇文章主要介紹了Mysql錯誤Every derived table must have its own alias解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-08-08
mysql中整數(shù)數(shù)據(jù)類型tinyint詳解
大家好,本篇文章主要講的是mysql中整數(shù)數(shù)據(jù)類型tinyint詳解,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12
Centos7使用yum安裝Mysql5.7.19的詳細步驟
本篇文章主要介紹了Centos7使用yum安裝Mysql5.7.19的詳細步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-09-09

