MySql 锁表排查

当 MySQL 更新表结构(如执行 ALTER TABLE)长时间未完成时,很可能是由于表被锁或存在阻塞操作。以下是判断和排查锁表问题的步骤:


1. 检查当前运行的进程

使用 SHOW PROCESSLIST 查看所有正在执行的查询,寻找可能阻塞 DDL 操作的会话:

sql

复制

SHOW FULL PROCESSLIST;
  • 重点关注 State 列中的 Waiting for table metadata lock 或长时间运行的查询。
  • 记录 Id 和 Time 异常的会话(尤其是长时间未完成的 SELECTUPDATE 或未提交的事务)。

2. 检查未提交的事务

未提交的事务可能持有元数据锁,导致 DDL 操作阻塞。查询 INFORMATION_SCHEMA.INNODB_TRX

sql

复制

SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
  • 观察是否有长时间运行的事务(trx_started 时间较早且未结束)。
  • 记录 trx_mysql_thread_id(对应 SHOW PROCESSLIST 中的 Id)。

3. 检查元数据锁(Metadata Locks)

MySQL 5.7+ 可通过 performance_schema 查看元数据锁:

sql

复制

SELECT * FROM performance_schema.metadata_locks 
WHERE OBJECT_SCHEMA = 'your_database' AND OBJECT_NAME = 'your_table';
  • 关注 LOCK_TYPE 为 SHARED_READ/SHARED_WRITE 或 EXCLUSIVE 的锁。
  • EXCLUSIVE 锁表示 DDL 操作正在等待获取锁,而其他会话可能持有冲突锁。

4. 查看 InnoDB 引擎状态

执行以下命令获取详细的锁和事务信息:

sql

复制

SHOW ENGINE INNODB STATUS\G

在输出结果的 TRANSACTIONS 和 LATEST DETECTED DEADLOCK 部分查找锁冲突线索。


5. 终止阻塞的会话

如果确认某个会话阻塞了 DDL 操作,可使用 KILL 命令终止它:

sql

复制

KILL [session_id]; -- 替换为实际的进程 ID

注意:需谨慎操作,避免终止核心业务会话。


6. 预防锁表的建议

  • 使用在线 DDL 工具:如 pt-online-schema-change(Percona Toolkit),可在不锁表的情况下修改表结构。
  • 选择合适时机:在低峰期执行 DDL,减少对业务的影响。
  • 控制事务:避免长事务,确保事务及时提交。
  • 监控工具:使用 Prometheus + Grafana 或 Percona Monitoring 监控数据库锁状态。

总结

通过检查进程列表、未提交事务和元数据锁,可以定位到导致 DDL 操作阻塞的源头。如果确认是锁表问题,终止阻塞会话或优化事务逻辑即可解决。对于频繁修改表结构的需求,建议使用在线 DDL 工具降低影响。

上一篇
下一篇