Mysql show processlist 排查问题
一、命令概述:
mysql show full processlist 用来查看当前线程处理情况,具体信息请参考官网:https://dev.mysql.com/doc/refman/5.7/en/show-processlist.html
show full processlist 返回的结果是实时变化的,是对mysql链接执行的现场快照,所以用来处理突发事件非常有用。
一般用到 show processlist
或 show full processlist
都是为了查看当前 mysql 是否有压力,都在跑什么语句,当前语句耗时多久了,有没有什么慢 SQL 正在执行之类的
可以看到总共有多少链接数,哪些线程有问题(time是执行秒数,时间长的就应该多注意了),然后可以把有问题的线程 kill 掉,这样可以临时解决一些突发性的问题。
有时候一个快照可能看不出什么问题,那么可以频发的刷新试试
二、命令详解:
下面来看一下运行:show full processlist命令的详解,我们可以通过三种方式来查看命令运行的结果:
1、通过SHOW FULL PROCESSLIST命令查看:
mysql> SHOW FULL PROCESSLIST\G *************************** 1. row *************************** Id: 1 User: system user Host: db: NULL Command: Connect Time: 1030455 State: Waiting for master to send event Info: NULL *************************** 2. row *************************** Id: 2 User: system user Host: db: NULL Command: Connect Time: 1004 State: Has read all relay log; waiting for the slave I/O thread to update it Info: NULL *************************** 3. row
2、通过查询链接线程相关的表来查看快照
select id, db, user, host, command, time, state, info from information_schema.processlist order by time desc
3、通过navicat中的【工具】=> 【服务器监控】进行查看结果如下:
下面针对每列做下介绍:
Id:链接mysql 服务器线程的唯一标识,可以通过kill来终止此线程的链接。
User:当前线程链接数据库的用户
Host:显示这个语句是从哪个ip 的哪个端口上发出的。可用来追踪出问题语句的用户
db: 线程链接的数据库,如果没有则为null
Command: 显示当前连接的执行的命令,一般就是休眠或空闲(sleep),查询(query),连接(connect)
Time: 线程处在当前状态的时间,单位是秒
State:显示使用当前连接的sql语句的状态,很重要的列,后续会有所有的状态的描述,请注意,state只是语句执行中的某一个状态,一个 sql语句,已查询为例,可能需要经过copying to tmp table,Sorting result,Sending data等状态才可以完成
Info: 线程执行的sql语句,如果没有语句执行则为null。这个语句可以使客户端发来的执行语句也可以是内部执行的语句
由于Command的状态大部分都是sleep对我们分析问题没什么作用,所以我们可以通过如下语句来排除sleep状态的线程:
-- 查询非 Sleep 状态的链接,按消耗时间倒序展示,自己加条件过滤 select id, db, user, host, command, time, state, info from information_schema.processlist where command != 'Sleep' order by time desc
这样就过滤出来哪些是正在干活的,然后按照消耗时间倒叙展示,排在最前面的,极大可能就是有问题的链接了,然后查看 info 一列,就能看到具体执行的什么 SQL 语句了,针对分析
三、kill 使用
通过前面的查询,我们查到了问题sql,通常会kill掉这个链接的线程,具体看官网文档:https://dev.mysql.com/doc/refman/5.7/en/kill.html
执行语句如下:
-- 查询执行时间超过2分钟的线程,然后拼接成 kill 语句 select concat('kill ', id, ';') from information_schema.processlist where command != 'Sleep' and time > 2*60 order by time desc
在下一步我就不用说了吧,把拼接 kill 的执行结果跑一遍就搞定了,这个有时候非常好用,谁用谁知道
四、常见问题
一些问题会导致连锁反应,而且不太好定位,有时候以为是慢查询,很可能是大多时间是在等在CPU、内存资源的释放,所以有时候同一个查询消耗的时间有时候差异很大
总结了一些常见问题:
- CPU报警:很可能是 SQL 里面有较多的计算导致的
- 连接数超高:很可能是有慢查询,然后导致很多的查询在排队,排查问题的时候可以看到”事发现场“类似的 SQL 语句一大片,那么有可能是没有索引或者索引不好使,可以用:
explain
分析一下 SQL 语句
参考:
https://xu3352.github.io/mysql/2017/07/08/msyql-show-full-processlist
https://my.oschina.net/mkh/blog/298036