MySQL 占用 CPU 过高问题定位及优化( 三 )


mysql [localhost:5727] {msandbox} ((none)) > select * from information_schema.processlist;+----+----------+-----------+------+---------+------+--------------+----------------------------------------------+| ID | USER| HOST| DB| COMMAND | TIME | STATE| INFO|+----+----------+-----------+------+---------+------+--------------+----------------------------------------------+|5 | msandbox | localhost | test | Query|2 | Sending data | select * from t_cpu order by rand() limit 1||6 | msandbox | localhost | NULL | Query|0 | executing| select * from information_schema.processlist ||4 | msandbox | localhost | NULL | Sleep| 1401 || NULL||3 | msandbox | localhost | test | Sleep| 1405 || NULL|+----+----------+-----------+------+---------+------+--------------+----------------------------------------------+4 rows in set (0.00 sec)参数说明:

  • id:标识位,MySQL 进程 ID,使用 kill id,可以杀掉某一个进程
  • user:当前连接的用户
  • host:当前连接的主机
  • db:连接的数据库
  • command:执行的数据库操作类型
  • sleep:休眠状态
  • Query:查询状态
  • connect:连接状态
  • time:已经执行的时间,单位秒
  • info:已经执行的 SQL
  • state:SQL 执行的状态,结果是 SQL 语句整个执行状态中的一个,其中包含很多状态,我们整理如下表:
MySQL 5.7 官方参考MySQL 8.0 官方参考
状态
含义
After create
当线程使用函数创建表(包括内部临时表)最后阶段会出现这个状态,即使由于某些错误未能创建成功,也会标识该状态
altering table
服务端正在执行 ALTER TABLE
Analyzing
线程正在计算 MyISAM 引擎表键值分布(例如 ANALYZE TABLE)
checking permissions
线程正在检查服务端是否有执行语句所需要的的权限
Checking table
线程正在执行表的检查工作
cleaning up
线程已经处理了一个命令,并准备释放内存并重置某些状态
Closing tables
线程正在将表中修改的数据刷新到磁盘,同时正在关闭已经用完的表 。是一个能很快完成的动作,如果持续完不成,需要确认磁盘空间是否用满或者磁盘使用的负载很高
converting HEAP to ondisk
线程正在将内部临时表从 MEMORY 表转换为磁盘表
copy to tmp table
线程正在执行一个 ALTER TABLE 语句 。在创建一个新表,然后将老表记录复制到新表之前将是此状态
Copying to group table
如果语句具有不同的条件 ORDER BY 和 GROUP BY 标准,则按组对行进行排序并将其复制到临时表
Copying to tmp table
服务端正在复制到内存中的临时表
Copying to tmp table on disk
服务端正在复制到磁盘上的临时表,临时结果集变的太大(参考 8.4.4 节,MySQL 内部临时表的使用),线程正在将临时表从内存更改为基于磁盘的格式来节省内存
Creating index
线程正在执行 MyISAM 表的 ALTER TABLE ... ENABLE KEYS
Creating sort index
线程正在处理 SELECT 使用内部临时表
creating table
线程正在创建表,包括创建临时表
Creating tmp table
线程正在内存中或者磁盘上创建临时表,如果临时表在内存中创建之后转换到磁盘,状态为 Copying to tmp table on disk
committing alter table to storage engine
服务端完成 ALTER TABLE 并提交结果
deleting from main table
服务端正在执行多表删除的第一部分,仅删除第一个表,保存列和偏移量用于删除其他表
deleting from reference tables
服务端正在执行多表删除的第二部分,在其他表中删除匹配的行
discard_or_import_tablespace
线程正在执行 ALTER TABLE ... DISCARD TABLESPACE or ALTER TABLE ... IMPORT TABLESPACE 语句
end
结束状态,结束之前需要清理 ALTER TABLE, CREATE VIEW, DELETE, INSERT, SELECT, or UPDATE
executing
线程正在执行语句
Execution of init_command
线程正在执行变量 init_command system 中的语句
freeing items
线程执行了一条命令,在此期间完成了一些项目的资源释放,涉及如查询缓存,这个状态之后通常为 cleaning up
FULLTEXT initialization
服务端正在准备执行 natural-language 的全文检索
init
该状态在 ALTER TABLE, DELETE, INSERT, SELECT, or UPDATE 初始化之前,服务端在该状态下会刷新二进制日志和 InnoDB 日志,清理查询缓存
Killed
有发送了一个 KILL 线程的请求,下次终止前会检查 kill 标志位 。MySQL 会在每次主循环中检查 kill 标志位,有时该线程并不能立马杀掉会保留短暂时间,如果该线程被其他线程锁定,那么 kill 会在锁释放后生效


推荐阅读