mysql慢查询排查
第一步:查看当前正在运行的事务状态
select trx_state,trx_started,trx_mysql_thread_id,trx_query from information_schema.innodb_trx;
其中:
trx_state
:事务状态trx_started
:事务启动时间trx_mysql_thread_id
:事务的线程idtrx_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执行语句,会导致日志文件过大,以及执行速度变慢,应在查询后及时关闭。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论