第一步:查看当前正在运行的事务状态
select trx_state,trx_started,trx_mysql_thread_id,trx_query from information_schema.innodb_trx;
|
其中:
Trx_state:事务状态
Trx_started:事务启动时间
Trx_mysql_thread_id:事务的线程id
Trx_query: 事务当前执行的查询sql
当Trx_state的值为:“LOCK_WAIT”时,说明发生了锁等待。等待时间过长可能导致程序返回失败。
示例:
第二步:查看线程状态
show processlist;
|
返回结果包括:id,host,db,Command,Time,State等。找到id等于第一步中的trx_mysql_thread_id对应的记录,如果Command是“Sleep”。说明这个线程的事务一直没有提交或者卡住了。我们需要手动kill掉。
第三步:杀死线程
Kill id
|
在mysql客户端执行上面的命令杀死线程。
一般使用以上的命令足以判断是否是因为事务等待问题发生错误。
第四步,辅助判断命令
此外,以下命令也可以辅助判断:
1. 查询行锁状态:
show status like 'InnoDB_row_lock%';
|
返回中,Innodb_row_lock_current_waits显示正在等待行锁的数量。
2. 查询当前使用的锁
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
|
Mysql8中对应为:
select * from performance_schema.data_locks;
|
3. 查询锁等待的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
|
Mysql8中对应为:
select * from performance_schema.data_lock_waits;
|
4. 查询当前被锁的表
show OPEN TABLES where In_use > 0;
|
5. 查询最近一次的死锁记录日志
show engine innodb status
|
可以导出到本地查看:
mysql -u root -p --execute="show engine innodb status \G" > /root/test.log
|
根据以上命令,找到结果中存在等待异常的trx_id即事务id,再回到第一步,从当前事务列表中找到对应事务,然后杀死对应线程。
第五步,开启慢查询日志
通过慢查询日志,记录执行时间超时的sql语句。超时默认是10秒。
1. 查看慢查询日志是否开启,并开启日志
show variables like '%query%';
|
返回中,slow_query_log为“OFF”,表示关闭。开启日志:
set global slow_query_log='ON';
|
第六步,开启通用查询日志
1. 查看通用查询日志是否开启
show variables like '%general%';
|
返回中,general_log为“OFF”,表示关闭。开启日志:
set global general_log='ON'
|
注意,通用日志会记录所有的sql执行语句,会导致日志文件过大,以及执行速度变慢,应在查询后及时关闭。