MySQL服务器CPU占用过高
CPU占用过高的可能性
- 1、占用CPU的进程不是MySQL的进程
- 将占用CPU的进程与MySQL进程安装到不同的机器
- 限制进程的资源占用
- 2、正在进行大TPS的操作
- 可以通过
show status
来查看QPS - 通过调整程序,尽力降低TPS。比如循环通过ID查询,可以使用 ID IN,将多条SQL整合成一条加载到程序中再处理
- 通过缓存,降低数据库的QPS
- 升级CPU
- 3、函数/排序/类型转化/逻辑IO访问
- 先定位到占用资源较多的SQL,然后优化SQL
- 减少逻辑运算量
避免使用函数
,将运算转移至易扩展的应用服务器中 如substr等字符运算,dateadd/datesub等日期运算,abs等数学函数减少排序
,利用索引取得有序数据或避免不必要排序 如union all代替 union,order by 索引字段等禁止类型转换
,使用合适类型并保证传入参数类型与数据库字段类型绝对一致 如数字用tiny/int/bigint等,必需转换的在传入数据库之前在应用中转好简单类型
,尽量避免复杂类型,降低由于复杂类型带来的附加运算。更小的数据类型占用更少的磁盘、内存、cpu缓存和cpu周期
- 减少逻辑IO量
索引
:优化索引,减少不必要的表扫描 如增加索引,调整组合索引字段顺序,去除选择性很差的索引字段等等表
:合理拆分,适度冗余 如将很少使用的大字段拆分到独立表,非常频繁的小字段冗余到“引用表”SQL
:调整SQL写法,充分利用现有索引,避免不必要的扫描,排序及其他操作 如减少复杂join,减少order by,尽量union all,避免子查询等数据类型
:够用就好,减少不必要使用大字段 如tinyint够用就别总是int,int够用也别老bigint,date够用也别总是timestamp
- 减少query请求量
- 适当缓存,降低缓存数据粒度,对静态并被频繁请求的数据进行适当的缓存
- 优化实现,尽量去除不必要的重复请求 如禁止同一页面多次重复请求相同数据的问题,通过跨页面参数传递减少访问等
- 合理需求,评估需求产出比,对产出比极端底下的需求合理去除
- 4、等待IO请求的完成:此时CPU实际上空闲
- 优化SQL。减少扫描行数
- 升级SSD
- 5、慢SQL查询过多
- 定位慢SQL,优化SQL
1、排查占用CPU的进程
- 如果大量占用CPU的进程不是MySQL的进程,则不是MySQL的问题导致CPU占用飙升
2、找到占用CPU高的线程
- 根据进程ID找到占用CPU高的线程
ps -mp $pid -o THREAD,tid | sort -r
top -Hp $pid
3、查找mysql中对应的线程ID
- 根据操作系统线程ID,查看mysql数据库中对应的线程ID
mysql> select thread_id,name ,PROCESSLIST_ID,THREAD_OS_ID from performance_schema.threads where THREAD_OS_ID = 3694; +-----------+---------------------------------------------+----------------+--------------+ | thread_id | name | PROCESSLIST_ID | THREAD_OS_ID | +-----------+---------------------------------------------+----------------+--------------+ | 84 | thread/sql/one_connection | 15 | 3694 | +-----------+---------------------------------------------+----------------+--------------+ 1 rows in set (0.00 sec)
4、获取对应的sql
- 根据mysql数据库的线程ID获取sql
mysql> select sql_text from performance_schema.events_statements_current where thread_id = 84; +----------+ | sql_text | +----------+ | ...... | +----------+ 1 row in set (0.00 sec)