今天在测试环境上发现用户第三方登录出现问题,服务器日志报错如下:
出现这个问题感觉还是挺疑惑的,因为测试环境已经稳定运行了几个月的时间,一直没有出现过mysql事务锁的问题,于是开始着手查问题。
针对Lock wait timeout exceeded; try restarting transaction的错误出现的原因一般有:
先从mysql角度来对问题进行分析,查看mysql server上的事务情况和锁的情况以及锁等待的情况。
SHOW PROCESSLIST;
输出结果为:
select * from informationschema.innodbtrx
其中字段说明如下(这里只简要列举关键的几个字段,需要了解更多的请自行到官网查询):
在我们的环境中执行后,结果为:
对比可以看到,记录的状态都为RUNNING,也就是正在执行的事务,并没有锁。
如果是事务锁定的情况如何解决?看事务表INNODB_TRX,里面是否有正在锁定的事务线程,看看ID是否在show processlist里面的sleep线程中,如果是,就证明这个sleep的线程事务一直没有commit或者rollback而是卡住了,我们需要手动kill掉。
SELECT * FROM informationschema.INNODBLOCKs;
可以看到锁也是没有的。
SELECT * FROM informationschema.INNODBLOCK_waits;
当前环境中也并无锁等待情况,这时就开始往其他方面分析了。
由于当前测试环境是一个mysql的主从环境,所以会有很多的binlog日志,所以猜测是不是因为binlog空间占用太多的原因。进入mysql存储目录后发现:
可以看到binlog日志文件应该是已经及时被定时清理了,但是mysqld.log和slow.log都比较大,查看mysqld.log,会发现有大量的:
经过定位,发现这个是一个同事最近在调整的统计信息的定时任务,不小心把定时任务的频率调大了,导致频繁刷mysqld.log,定时任务频率恢复正常后,log日志不再增长。slow.log也是因为统计信息中的一些sql的问题导致的。
清空这两个文件:
echo > mysqld.logecho > slow.log
清空成功后,再尝试登录时,成功了。
虽然这里不是binlog的问题,但是还是有必要在这里安利下binlog的管理方法:
更多可以参考:https://blog.csdn.net/atco/article/details/24259333
出现Lock wait timeout exceeded; try restarting transaction的原因一般为: