突然发现测试环境的所有都登录不上去了,接口返回 504,
查看日志发现报的事务回滚异常,
因为使用的数据库为mysql,而InnoDB表类型会出现锁等待的情况,在出现锁等待时,会根据参数innodb_lock_wait_timeout(默认50s)的配置,判断是否需要进行timeout的操作,如果等待时间超过了设置的时间就会报错。
所以刚开始以为是锁表了,然后在information_schema查询了数据库的使用情况,information_schema这张数据表保存了MySQL服务器所有数据库的信息。
可以使用这个三张表的信息排查问题:
1、innodb_trx ## 当前运行的所有事务
2、innodb_locks ## 当前出现的锁
3、innodb_lock_waits ## 锁等待的对应关系
可以使用这条语句查看数据库当前的锁信息:
select * from information_schema.innodb_trx
发现有几条trx_stale为LOCK WAIT的数据,然后通过执行: kill 线程id号; 杀掉进程后发现马上又出现了,然后考虑到有可能是定时任务在跑。
最后发现是测试环境的数据库因为数据库备份策略没有删除老的备份数据导致测试环境的服务器磁盘被占满了,清除磁盘后,正常了。
异常过程中,mysql 读正常,无法写入。
总结列举锁等待超时出现的情况:
1、在同一事务内先后对同一条数据进行插入和更新操作
2、多台服务器操作同一数据库
3、瞬时出现高并发现象,spring事务造成数据库死锁,后续操作超时抛出异常
4、事务A对记录C进行更新/删除操作的请求未commit时,事务B也对记录C进行更新/删除操作。此时,B会等A提交事务,释放行锁。当等待时间超过innodb_lock_wait_timeout设置值时,会产生“LOCK WAIT”事务。
5、数据库内存不足,导致无法执行写操作。