欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Lock wait timeout exceeded; try restarting transaction

程序员文章站 2024-01-12 16:23:04
...

Lock wait timeout exceeded; try restarting transaction

1.前言

今天线上环境日志,突然出现一个错误:Lock wait timeout exceeded; try restarting transaction)。凭经验可以推断,这是有某个事务直接时间太长没有提交,导致其他事务等待超时了。那么具体怎么排查呢?

今天我在做一个关于事务的小测试。

表结构:

CREATE TABLE `test` (
  `id` int(11) NOT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `test` VALUES ('1', '1');
INSERT INTO `test` VALUES ('2', '1');

然后我在一个窗口中执行:

第一个窗口:

BEGIN;
 UPDATE test SET age =2 where id =1;

第二个窗口:

BEGIN;
 UPDATE test SET age =3 where id =1;
COMMIT;

然后先执行第一个窗口,再执行第二个窗口

看到第二个窗口会一直阻塞等待,最后抛出异常:

Lock wait timeout exceeded; try restarting transaction

2.原因探查

我们可以通过到information_schema 中来进行查找。

  • innodb_trx 当前运行的所有事务
  • innodb_locks 当前出现的锁
  • innodb_lock_waits 锁等待的对应关系

所以我们先查看

select * from information_schema.innodb_trx;

结果如下:

Lock wait timeout exceeded; try restarting transaction

看到当前有两个事务,一个运行中,一个LOCK WAIT,锁等待,即等待获取锁。从这里,我们看到事务的id、事务开始时间、事务的线程id;

然后我们再执行下面的语句:

select * from information_schema.innodb_locks ;

结果如下:
Lock wait timeout exceeded; try restarting transaction

最后我们再执行下面的语句:

select * from information_schema.innodb_lock_waits  ;

结果如下:

Lock wait timeout exceeded; try restarting transaction

所以,如果我们看到一个事务执行时间太长,我们可以杀掉这个事务,

怎么杀掉事务:

比如这个,我们看到trx_id=4F3E的事务一直运行中,执行时间比较长,所以可以把它kill掉。这个事务的线程id=839,

所以我们直接执行:

kill 839

然后我们看到第一个第二个窗口停止等待,事务提交。