若MySQL出现响应慢、超时或“Lock wait timeout exceeded”报错,可能由表级锁阻塞或死锁引起,可通过四类方法排查:一、用INNODB_TRX等系统视图实时查锁与死锁;二、启用慢查询日志并过滤含lock/wait/for update的SQL;三、部署pt-deadlock-logger自动捕获结构化死锁日志;四、用宝塔计划任务定时导出锁状态快照。

如果您在宝塔面板环境下运行MySQL数据库,但发现查询响应缓慢、部分操作长时间无返回或应用报错提示“Lock wait timeout exceeded”,则可能是由于表级锁阻塞或事务间发生死锁所致。以下是监控MySQL锁表与死锁情况的具体方法:
一、通过MySQL内置命令实时查看锁等待与死锁信息
该方法直接连接MySQL服务器,利用系统视图获取当前锁状态和最近死锁日志,无需额外安装组件,适用于所有MySQL 5.5及以上版本。
1、使用SSH登录服务器,执行命令进入MySQL客户端:mysql -u root -p,输入宝塔面板中设置的MySQL root密码。
2、执行查询语句获取当前被阻塞的事务及锁等待关系:SELECT * FROM information_schema.INNODB_TRX\G;
3、查看当前所有锁信息(包括行锁、表锁):SELECT * FROM information_schema.INNODB_LOCKS\G;
4、查看锁等待链路(显示哪个事务在等待哪个锁):SELECT * FROM information_schema.INNODB_LOCK_WAITS\G;
5、查看最近一次死锁详细信息(仅保留最后一次):SHOW ENGINE INNODB STATUS\G;,在输出结果中查找“LATEST DETECTED DEADLOCK”段落。
二、启用MySQL慢查询日志并过滤锁相关SQL
该方法通过记录执行时间超阈值且含锁操作的SQL语句,辅助定位长期持有锁或未提交事务的源头,需配合日志分析工具使用。
1、在宝塔面板中进入【软件商店】→ 找到已安装的MySQL → 点击【设置】→ 【配置修改】。
2、在配置文件中找到slow_query_log行,将其值设为ON;若不存在则手动添加:slow_query_log = ON。
3、设置慢查询阈值(单位秒),例如锁定类操作通常耗时较长,可设为1秒:long_query_time = 1。
4、指定慢日志路径,确保目录可写,例如:slow_query_log_file = /www/server/data/mysql-slow.log。
5、保存配置后,点击【重启】MySQL服务使配置生效。
6、使用命令实时追踪新增的慢查询记录:tail -f /www/server/data/mysql-slow.log | grep -i "lock\|wait\|for update\|select ... for update"。
三、部署pt-deadlock-logger工具自动捕获死锁事件
该方法借助Percona Toolkit中的专用工具,以守护进程方式持续轮询INNODB_STATUS,将每次死锁信息结构化写入本地表或日志文件,适合需要长期归档分析的场景。
1、通过SSH执行命令下载并安装Percona Toolkit:wget https://downloads.percona.com/downloads/percona-toolkit/3.5.4/binary/debian/bionic/x86_64/percona-toolkit_3.5.4-1.bionic_amd64.deb && apt install -y ./percona-toolkit_3.5.4-1.bionic_amd64.deb。
2、创建用于存储死锁日志的数据库和表:mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS pt; CREATE TABLE IF NOT EXISTS pt.deadlocks (serverid VARCHAR(32), ts TIMESTAMP, thread_id BIGINT, txn_id BIGINT, txn_time INT, user VARCHAR(32), hostname VARCHAR(32), ip VARCHAR(46), db VARCHAR(64), tbl VARCHAR(64), idx VARCHAR(64), lock_type VARCHAR(32), lock_mode VARCHAR(32), lock_id VARCHAR(128), lock_trx_id BIGINT, pid INT, program_name VARCHAR(128), query TEXT, PRIMARY KEY(serverid, ts));"。
3、执行死锁日志采集命令(后台运行):nohup pt-deadlock-logger --user=root --password=your_mysql_root_password --dest D=pt,t=deadlocks --interval=30 --run-time=86400 --daemonize &,其中your_mysql_root_password需替换为实际密码。
4、验证数据是否写入:mysql -u root -p -e "SELECT * FROM pt.deadlocks ORDER BY ts DESC LIMIT 5;"。
四、利用宝塔面板计划任务定期导出锁状态快照
该方法将锁信息采集过程脚本化,并通过宝塔计划任务定时执行,生成带时间戳的文本快照,便于人工比对锁状态变化趋势。
1、新建Shell脚本文件:vi /www/server/script/check_mysql_lock.sh。
2、在编辑器中写入以下内容(注意替换your_password为真实MySQL root密码):#!/bin/bash\nDATE=$(date +\%Y\%m\%d_\%H\%M\%S)\nmysql -uroot -pyour_password -e "SELECT trx_id,trx_state,trx_started,trx_wait_started,TRX_QUERY FROM information_schema.INNODB_TRX WHERE trx_state='LOCK WAIT' OR trx_wait_started IS NOT NULL;" > /www/server/script/lock_wait_${DATE}.log\nmysql -uroot -pyour_password -e "SHOW ENGINE INNODB STATUS\G" | grep -A 20 "LATEST DETECTED DEADLOCK" > /www/server/script/deadlock_${DATE}.log。
3、赋予脚本执行权限:chmod +x /www/server/script/check_mysql_lock.sh。
4、进入宝塔面板【计划任务】→ 【添加计划任务】→ 类型选择【Shell脚本】→ 执行周期设为每10分钟一次 → 脚本内容填写:/www/server/script/check_mysql_lock.sh。
5、保存后等待首次执行完成,检查/www/server/script/目录下是否生成形如lock_wait_20240520_143000.log的文件。










