【数据库死锁】线上问题之数据库死锁

原本平静的一天,惊现生产项目瘫痪问题,马上打开日志,发现后台日志提示了多个“com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction”

大概去了解一下这个异常:

解释:MYSQL事务回滚异常,超过锁等待超时;尝试重新启动事务
原因:执行update的SQL语句时,由于表被锁座,无法更新,导致时间超时;
此时在数据库对当前表进行update语句更新时,会提示:时间超时
当执行一个方法请求到数据库,抛出当前异常时,即使定位到执行的是哪一条SQL语句。确定是哪一张表;
MYSQL中手动执行该update语句时,提示:失败,等待锁超时;

解决方案:
1.查看数据库被锁表的进程,若表被锁住,可以查看到当前锁表的进程信息,若表被一直锁住不释放,则信息会一直存在;
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
2.找到当前锁表的进程ID,即:trx_mysql_thread_id,将其终止
kill 进程ID;
此时当前表会被释放,即可正常进行update操作。

以上只是解决锁表的临时解决方案,并不推荐,应该从造成锁表的原因去调整,避免后续执行方法时也会锁表;

实际问题

但是当时的实际情况是,确实有很多被锁的事务,对应了多张表,但是查看代码,并没有添加事务,重启服务也没有解决这个问题,想到肯能是数据库服务的问题,最后一看,数据库的服务器内存满了…

扩展

  1. 查看未提交的事务
    select * from information_schema.INNODB_TRX;

  2. 查看正在锁的事务
    SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;

  3. 查看正在等待锁的事务
    SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;

  4. 查看进程
    show processlist

  5. 查看是否锁表
    show open tables where in_use > 0

  6. 杀死被锁的进程
    trx_mysql_thread_id为被锁的事务id,可以使用kill 线程id 杀死对应的线程,达到释放锁效果

参考

生产异常 Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceed

mysql查询死锁sql

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值