项目场景:
提示:这里简述项目相关背景:
项目定时任务框架采用Quartz实现调度
问题描述
在生产中,出现服务假死问题,重启服务时失败,抛出异常
TaskUtil: 暂停任务失败,失败信息:
Failure obtaining db row lock: Lock wait timeout exceeded; try restarting transaction
原因分析:
根据异常信息定位问题
lock wait timeout exceeded; try restarting transaction
Mysql出现锁等待,由于加锁语句导致事务挂起,锁一下处于等待中,导致调度服务启动失败。
解决方案:
- 排查mysql处于等待锁的事务
- 处理挂起事务
方案一
information_schema
数据库保存了MySQL服务器所有数据库的信息,本次用到如下三个表
innodb_trx 当前运行的所有事务
innodb_locks 当前出现的锁
innodb_lock_waits 锁等待的对应关系
- 如果数据库中有锁的话,我们可以使用这条语句来查看,找到等待锁的线程id,杀掉
select * from information_schema.innodb_trx
kill 线程id
方案二
如果上述方案,没有解决问题,可以尝试下如下方案:
- 查询下当前库正在运行的线程的各种信息,建议查询时添加where条件,指定用户和库
SELECT * from information_schema.`PROCESSLIST` [where db ='dbname' and user = 'username'];
- 找到可疑线程,注意甄别,不要
误杀
核心线程,比如主从同步,或者其他应用进程,定位尽量加指定库和指定用户,缩小范围
-
kill 掉可疑线程
kill ID
拓展:本次涉及到的表字段说明
innodb_trx
desc information_schema.innodb_trx;
innodb_locks
desc information_schema.innodb_locks;
innodb_lock_waits
desc information_schema.innodb_lock_waits