Lock wait timeout exceeded; try restarting transaction 是 MySQL 中常见的并发错误,意味着当前事务在尝试获取行锁时,等待时间超过了系统设定的阈值(默认为 50 秒),从而被 MySQL 主动终止并回滚。
这通常是数据库磁盘满载 或锁竞争问题导致的。
以MySQL5.7为例
第一种情况------锁竞争
第一步:查找阻塞源(谁持有了锁?)
执行以下 SQL,找出正在等待锁的事务以及阻塞它的事务:
sql
SELECT
r.trx_id AS waiting_trx_id,
r.trx_mysql_thread_id AS waiting_thread_id,
r.trx_query AS waiting_query, -- 被阻塞的SQL
b.trx_id AS blocking_trx_id,
b.trx_mysql_thread_id AS blocking_thread_id,
b.trx_query AS blocking_query -- 持有锁的SQL (若为NULL,说明该事务当前空闲但未提交)
FROM information_schema.INNODB_TRX r
JOIN information_schema.INNODB_LOCK_WAITS w ON r.trx_id = w.requesting_trx_id
JOIN information_schema.INNODB_TRX b ON b.trx_id = w.blocking_trx_id;
**重点关注 blocking_query**:
- 如果有具体 SQL,说明该 SQL 所在的事务持有了锁。
- 如果为
NULL,说明该事务之前执行过 SQL,现在处于空闲状态(Sleep),但事务未提交,依然持有锁。
第二步:找到第一步中查出的 blocking_thread_id,执行 Kill 命令释放锁
sql
KILL <blocking_thread_id>;
注意:不要 Kill 报错的那个线程(waiting_thread),因为它已经被 MySQL 终止了。必须 Kill 持有锁的线程。
至此Lock wait timeout exceeded; try restarting transaction 问题应该已经得到解决,后期记得优化该SQL,如果问题还没的到解决则可能是MySQL宿主机的云盘满了(自己在服务器安装的MySQL数据库)
第二种情况------磁盘满载
第一步:分析磁盘满载原因
由于数据库开启了主从复制,保留了binlog的二进制文件,同时主库还从三方库定时同步数据,这就导致不停地产生binlog二进制文件,500GB的数据盘一周就被binlog二进制文件占满了(阔怕)
第二步:找到binlog二进制文件
执行以下命令查看分区的总体使用情况:
bash
df -h
定位到被占满的分区后,比如data区被占满了,执行以下命令逐层查看 /data 下各子目录的大小,定位占用空间最大的位置,最终定位到存放binlog二进制文件的目录:
bash
du -sh /data/* | sort -rh
第三步:删除历史binlog二进制文件,建议保留最新的binlog二进制文件,其余的都删掉,如果配置了主从复制则最新的那个binlog二进制文件一定别删,否则还得重新配置主从复制
bash
# 例如binlog二进制文件是mysql-bin.00001
rm -f /data/mysql/data/mysql-bin.00001
第四步:配置 Binlog 自动过期,编辑/etc/my.cnf,添加如下参数
bash
[mysqld]
expire_logs_days = 7 # 根据业务需求调整保留天数
第五步:重启mysql
bash
systemctl restart mysql
启动报错一,如下,说明把最新的mysql-bin.000464二进制文件删除了,MySQL 在启动时尝试读取二进制日志索引中记录的最新 binlog 文件,但该文件不存在:
bash
2026-06-16T02:05:46.755343Z 0 [ERROR] Failed to open log (file './mysql-bin.000464', errno 2)
2026-06-16T02:05:46.755350Z 0 [ERROR] Could not open log file
解决办法有两个方案
方案一:修正 Binlog 索引文件(推荐)
bash
vim /data/mysql/data/mysql-bin.index
# 删除缺失文件的行,保存退出
- 删除索引文件中指向不存在文件的行。
- 若
mysql-bin.000464确实被误删,且你不需要该日志之后的数据恢复,请删除索引中从mysql-bin.000464开始的所有行。 - 注意:确保索引中保留的最后一个文件在磁盘上是真实存在的。
- 重新启动 MySQL
方案二:重置 Binlog(若无需保留旧日志)
bash
#清空binlog文件和删除索引文件
rm -f /data/mysql/data/mysql-bin.index
rm -f /data/mysql/data/mysql-bin.*
- 清空binlog文件和删除索引文件
- 重启MySQL,MySQL 启动时会自动创建新的
mysql-bin.000001和索引文件。
启动报错二,如下:
bash
ERROR! The server quit without updating PID file (/data/mysql/data/deploy-test-prd-x8601.pid).
解决方法,清理残留 PID 文件和err文件
bash
rm -f /data/mysql/data/deploy-test-prd-x8601.pid
rm -f /data/mysql/data/deploy-test-prd-x8601.err
- 重启MySQL