MySQL慢查询问题排查方式
作者:山林竹笋
文章介绍了MySQL慢查询排查的步骤,包括查看当前正在运行的事务状态、查看线程状态、杀死线程、辅助判断命令、开启慢查询日志和开启通用查询日志
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执行语句,会导致日志文件过大,以及执行速度变慢,应在查询后及时关闭。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。