MySQL5.6 Waiting for Commit Lock

mysql  Bug#19843808 自动修复记录

 

MySQL5.6和Xtrabackup之间存在一个bug,这个bug在5.6.23中已经修复。

 

Xtrabackup备份的时候执行flushs tables with read lock和show slave status会有可能和SQL Thread形成死锁,导致SQL Thread一直被卡主,STOP也没有用,Kill我们测试会丢失数据,只有Restart Server才行。

原因是SQL Thread的DML操作完成之后,持有rli->data_lock锁,commit的时候等待DML_COMMIT,而flush tables with read lock之后执行的show slave status会等待rli->data_lock;修复方法是rli->data_lock锁周期只在DML操作期间持有。

 

第一次遇到这个问题,开始还以为是zabbix出现问题,一把叫来了监控,直接说,主业务库中zabbix用户大量执行show slave status 导致数据库卡死。后面就发现监控说话一直抖。好吧,不吓人了,开始解决问题,言归正传:

 

1  show processlist  找到waiting for commit lock 的线程号,然后直接kill。这个是罪魁祸首,虽然他也是无辜的。

2. 执行上面一步后,其实sql线程已经挂了,这里需要stop slave

3. start slave

4.结束

<think>嗯,用户遇到了数据库锁表的问题,需要解决方法和优化方案。首先,我得回忆一下数据库锁表的原因。根据引用[3],锁表可能由长事务、DDL操作、锁竞争和锁超时引起。比如,当有一个长时间运行的事务在操作大表时,执行ALTER语句修改表结构可能会被阻塞,导致锁表。 接下来,用户需要具体的解决步骤。根据引用[4],可以先用SQL查询information_schema.processlist来找出正在运行的长时间查询,然后终止相关进程。这应该是第一步的排查方法。另外,引用[2]提到了使用乐观锁和减小锁粒度,这可能是在优化时需要考虑的。 然后要考虑优化方案。事务拆分和锁粒度调整是关键,比如将大事务拆分成小事务,避免长时间占用锁。读写分离和分库分表也能有效减少锁竞争,引用[1]提到根据业务需求优化表结构,可能包括索引优化和避免全表扫描。此外,硬件升级也是最后的手段,但需要结合具体情况。 用户可能还需要预防措施,比如监控和超时设置。引用[3]提到的锁超时配置,设置innodb_lock_wait_timeout参数可以自动释放锁,避免长时间阻塞。同时,开发规范如避免在高峰时段执行DDL操作也很重要。 最后,要确保回答结构清晰,分步骤说明,并结合引用内容自然标注来源。可能还需要生成相关问题,帮助用户进一步理解锁表问题和优化策略。</think>### 数据库锁表问题解决方案及优化方案 #### 一、锁表问题排查步骤 1. **定位阻塞进程** 执行以下SQL查询当前活跃的非睡眠进程,按执行时间排序,优先处理耗时长的操作[^4]: ```sql SELECT * FROM information_schema.processlist WHERE command NOT IN ('Sleep') ORDER BY time DESC; ``` 重点关注`State`列显示"Waiting for table metadata lock"或"Locked"状态的进程。 2. **终止阻塞操作** 确认非关键进程后,通过`KILL [process_id]`终止阻塞的会话。例如: ```sql KILL 12345; -- 替换为实际的进程ID ``` 3. **分析锁表原因** - **长事务**:检查是否有未提交的事务长时间占用锁资源[^3] - **DDL操作**:确认是否在业务高峰期执行表结构变更操作[^3] - **锁竞争**:检查多个事务对同一资源的争用情况[^2] #### 二、优化方案 1. **事务优化** - **拆分大事务**:将长时间运行的事务拆分为多个小事务,减少锁持有时间 - **设置超时**:配置`innodb_lock_wait_timeout`参数(默认50秒),超时自动释放锁[^3] - **及时提交**:避免在事务中执行无关操作后延迟提交 2. **锁机制优化** - **降低锁粒度**:优先使用行级锁代替表级锁 - **乐观锁替代**:对非强一致性场景使用版本号控制 - **读写分离**:通过主从架构将读操作分流到从库 3. **DDL操作规范** - **避开高峰期**:在业务低峰期执行`ALTER TABLE`等操作 - **使用在线DDL**:MySQL 5.6+支持`ALGORITHM=INPLACE`方式减少锁表时间 - **监控元数据锁**:通过`performance_schema.metadata_locks`表监控DDL锁状态 4. **架构优化** - **分库分表**:对大数据量表进行水平拆分,减少单表争用 - **缓存层**:使用Redis等缓存高频查询数据,降低数据库压力 - **异步处理**:将非实时操作转为消息队列异步执行 #### 三、预防措施 1. **监控体系** - 部署监控系统实时跟踪`Innodb_row_lock_waits`等指标 - 设置锁等待时间阈值报警(如 > 30秒) 2. **开发规范** ```sql -- 事务模版示例 START TRANSACTION; -- 核心操作放在事务后半段 UPDATE accounts SET balance = balance - 100 WHERE user_id = 1; -- 尽快提交 COMMIT; ``` 3. **索引优化** 添加合适的索引避免全表扫描,特别注意: - WHERE条件字段 - JOIN关联字段 - ORDER BY/GROUP BY字段[^1] #### 四、紧急处理流程 1. 通过`SHOW ENGINE INNODB STATUS`获取详细锁信息 2. 使用`sys.innodb_lock_waits`视图快速定位阻塞关系 3. 优先终止持有锁且未在工作的会话
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值