服务公告

服务公告 > 常见问题 > MySQL 表锁住了:metadata lock 等待的处理

MySQL 表锁住了:metadata lock 等待的处理

发布时间:2026-10-15 14:34
## 症状现象 网站突然整站卡住,所有涉及某张表的查询都挂起,应用连接池迅速耗尽,其他表还正常。登进数据库 show processlist,一眼看到一串 Waiting for table metadata lock 状态的连接:它们在等一张表的元数据锁。元数据锁保护表结构变更期间的一致性,只要有一个事务还握着这张表的锁,后面的 DDL 与新查询全部排队。与它一字之差的还有行锁等待:表现是特定业务卡而全库不卡,处理路径不同,先分清是哪种。 ## 定位:找到堵点 排队的不是肇事者,源头是最早的那个事务。两条命令锁定: ```sql SHOW PROCESSLIST; SELECT * FROM information_schema.innodb_trx ORDER BY trx_started; ``` processlist 里找状态不是 Waiting 且时间最久的;innodb_trx 按 trx_started 排序,最早开启、迟迟不提交的事务就是堵点。performance_schema 的元数据锁视图还能直接看到谁持锁谁等待,信息更直观,熟悉后优先用它。典型场景还原:某个会话开了事务(显式事务或关闭自动提交后忘记提交),中间跑了查询就挂着不管;此时有人执行 ALTER TABLE 加字段,DDL 需要排他元数据锁,被那个长事务挡住;DDL 一排队,后续所有对该表的查询跟着排队,整站雪崩。 ## 处理:杀源头,救排队 处理顺序不能反:先 KILL 掉那个长事务(或 DDL),锁链解除,排队的连接自动放行。只杀排队的连接是无效操作,队列立刻补上新的等待。kill 掉源头事务后观察 processlist 清空,应用恢复。每一次 kill 的动作记进工单,复盘时需要还原每一步。若 DDL 被杀,改在业务低峰重试,并先确认没有别的长事务。 ## 预防建议 治本是管理长事务:应用侧确保事务尽快提交,框架的连接归还时重置状态;监控 innodb_trx 里运行超过一分钟的事务并告警;交互式客户端查完就退出,别挂着会话过夜。DDL 操作规范化:变更窗口执行、事先检查长事务、大表用在线变更工具平滑加列。顺云云服务器上跑 MySQL,把长事务监控纳入巡检,元数据锁这类"一个会话挂全站"的事故就能提前拆雷。上线流程里给 DDL 加一道检查:执行前跑一遍长事务查询,红灯就不发版。