开发者

MySQL Semaphore wait has lasted使用详解

目录
  • 1. 理解信号量(Semaphore)和等待的背景
  • 2. 收集环境与上下文信息
  • 3. 查看mysql错误日志和InnoDB状态
    • a. 错误日志中的关键信息
    • b. 通过SHOW ENGINE INNODB STATUS\G观察
  • 4. 结合源码行号,定位具体阻塞点
    • 5. 重点排查方向
      • 5.1 长事务导致锁资源占用
      • 5.2 高并发写入导致缓冲池争用
      • 5.3 磁盘IO瓶颈
      • 5.4 表空间或数据页损坏
    • 6. 其他诊断技巧
      • 6.1 启用详细InnoDB调试日志
      • 6.2 使用性能Schema定位锁等待
    • 7. 解决建议总结
      • 8. 典型诊断命令举例
        • 总结

          MySQL 5.7.19 版本出现 Semaphore wait has lasted > 600 seconds 错误,意味着 InnoDB 内部某些线程等待信号量超过了10分钟,导致数据库挂起崩溃。

          针对这个问题,排查和定位的思路及步骤如下:

          1. 理解信号量(Semaphore)和等待的背景

          • InnoDB 通过信号量机制保护共享资源访问,例如缓冲池页、锁、事务信息等
          • 长时间等待信号量一般是死锁、资源竞争、内部异常或IO瓶颈导致的。
          • 错误日志中会列出等待信号量的线程堆栈位置(源码文件 + 行号),有助定位是哪类资源阻塞。

          2. 收集环境与上下文信息

          MySQL版本

          • 5.7.19,是较早的5.7版本,InnoDB还有一些已修复的问题,建议考虑升级。

          服务器硬件与资源状况

          • CPU、内存利用率
          • 磁盘IO状况(IOPS、延迟)

          数据库负载情况编程

          • 并发连接数
          • 读写比例
          • 是否有长事务/大事务

          具体业务场景

          • 当时运行什么SQL,是否有大量INSERT/UPDATE/DELETE
          • 是否有DDL操作(alter、drop)

          3. 查看MySQL错误日志和InnoDB状态

          a. 错误日志中的关键信息

          确认报错线程对应的源码文件和行号:

          mtr0mtr.ccrow0ins.cc 等,分别代表:

          • mtr0mtr.cc:多版本事务相关管理(Mini-transaction)
          • row0ins.cc:行插入相关代码

          这些提示可能表明在插入操作中出现了阻塞。

          b. 通过SHOW ENGINE INNODB STATUS\G观察

          • 锁等待情况(LATEST DETECTED DEADLOCK)
          • 当前活跃事务列表
          • semaphore wait 信息(SEMAPHORE WAIT块)
          • 主线程或阻塞线程的详细信息

          4. 结合源码行号,定位具体阻塞点

          可以通过查看5.7.19版本源码对应文件(MySQL官方github或者源码包)定位:

          • mtr0mtr.cc line 567

          涉及Mini-transaction相关锁等待,可能是InnoDB内部的metadata锁或缓冲池访问竞争。

          • row0ins.cc line 193

          插入行时等待信号量,可能是插入缓冲区竞争或插入锁等待。

          5. 重点排查方向

          5.1 长事务导致锁资源占用

          • SHOW PROCESSLIST 看是否存在长时间未提交的事务。
          • INFORMATION_SCHEMA.INNODB_TRX 查看当前活动事务。
          • 关闭长事务或者合理设置事务超时。

          5.2 高并发写入导致缓冲池争用

          高并发大批量写入,缓冲池页锁争用严重。

          调整 InnoDB 参数,如:

          • innodb_thread_concurrency
          • innodb_lock_wait_timeout
          • innodb编程客栈_buffer_pool_size (确保足够大,避免频繁刷盘)

          5.3 磁盘IO瓶颈

          • 使用系统工具(IOStat, vmstat)检查磁盘负载和延迟。
          • 高IO延迟会导致InnoDB锁等待。

          5.4 表空间或数据页损坏

          • 使用 CHECK TABLE 检查相关表。
          • 参考错误日志是否有提示页损坏。

          6. 其他诊断技巧

          6.1 启用详细InnoDB调试日志

          启动MySQL时添加:

          [androidmysqld]
          innodb_print_all_deadlocks=ON
          innodb_lock_wait_timeout=50
          

          查看死锁详细信息。

          6.2 使用性能Schempythona定位锁等待

          • 查询 performance_schema.data_locksperformance_schema.data_lock_waits ,定位锁资源。

          7. 解决建议总结

          问题点排查方法解决措施
          长事务占用锁SHOW PROCESSLIST, INNODB_TRX关闭或优化长事务,合理拆分事务
          高并发写压力大观察缓冲池争用,线程锁等待优化参数,分批写入,升级版本
          磁盘IO瓶颈iostat, vmstat优化存储,使用SSD,提高IO性编程
          表空间或页损坏CHECK TABLE, innodb_force_recovery尝试恢复数据,导出备份,重建表空间
          InnoDB版本缺陷官方Bug报告,源码分析升级MySQL版本到最新稳定版

          8. 典型诊断命令举例

          -- 查看当前阻塞事务
          SELECT * FROM information_schema.innodb_trx\G;
          
          -- 查看当前等待锁的线程
          SELECT * FROM performance_schema.data_locks WHERE LOCK_STATUS='WAITING';
          
          -- 查看进程列表,看长时间执行的SQL
          SHOW FULL PROCESSLIST;
          
          -- 查看死锁日志(在错误日志中)
          -- 或启用 innodb_print_all_deadlocks=ON 后捕获
          

          总结

          先从当前活跃事务和锁等待入手排查。

          结合InnoDB状态和系统IO性能分析瓶颈。

          若怀疑数据损坏,尝试使用 innodb_force_recovery

          5.7.19版本较老,建议升级至5.7较新版本,或者8.0版本,获得更多稳定性和bug修复。

          以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

          0

          上一篇:

          下一篇:

          精彩评论

          暂无评论...
          验证码 换一张
          取 消

          最新数据库

          数据库排行榜