mysql表被锁了怎么办:先查锁源再手动终止锁进程

mysql表被锁了怎么办:先查锁源再手动终止锁进程

线上业务突然大面积超时,新增、修改数据全部失败,翻遍服务端日志,所有请求都卡在数据写入环节,情急之下满脑子都是mysql表被锁了怎么办,第一次遇上生产环境锁表事故,完全没提前预案,只能硬着头皮现场排查抢修。

重启根本没用。

折腾好久才搞明白,表锁故障和数据库宕机是两码事,盲目重启是最蠢的操作。当时第一反应就是重启mysql服务,想着能一键解决所有异常,结果连续重启两次,问题不仅没解决,反而让堆积的未提交事务开始集中回滚,数据库负载直接飙升,原本只是锁表阻塞的业务,直接变成了全线卡顿,运维告警消息不停弹窗,白白浪费了十多分钟的黄金排查时间,让原本简单的小故障持续恶化。

没有纠结晦涩的底层原理,直接上手实操排查锁源,最先执行的是show open tables where in_use>0;这个指令特别直白,能直接筛选出当前正在被占用、处于锁定状态的数据表,执行之后屏幕上只跳出了一个业务核心表,精准定位到故障对象,不用在几十张数据表里面盲目排查,极大缩减了排查的时间成本。

找准锁表的表之后,就要揪出对应的阻塞进程。

紧接着输入show processlist;查看数据库所有活跃线程,重点盯着状态栏的内容,只要看到标注着Waiting for table metadata lock的线程,就是造成锁表的元凶。当时一眼就看到一条停留了二十多分钟的线程,状态一直挂着阻塞,溯源之后发现是运营人员早前做的批量数据更新操作,中途直接关闭了操作页面,没有手动提交事务,也没有触发回滚,这个悬空的事务就一直死死占着数据表权限,堵住了所有后续的读写请求,这也是这次锁表的核心原因。

确定问题进程ID后,操作特别简单,直接执行kill+进程ID的指令就行。当时敲下回车的一瞬间,数据库的阻塞状态瞬间解除,持续了半个多小时的接口超时问题彻底消失,前台用户的操作请求全部恢复正常,后台数据写入、更新功能也顺利回归,整个修复过程也就几十秒。

其实绝大多数普通的mysql表锁问题,都不是配置参数、版本兼容这类复杂问题,基本都是人为中断操作、长事务未关闭、批量操作卡死导致的,完全不需要修改数据库配置文件,不用做复杂的参数调试,找对阻塞进程直接终止,就能快速恢复业务,根本不用大动干戈调整环境。

那天处理完故障,就坐在工位上盯着数据库的负载监控,看着波动的曲线慢慢趋于平稳,直到所有告警全部清零,才抬手关掉了监控页面。

了解更多百科知识请访问 百科