更新时间:2026-07-03 GMT+08:00
分享

CPU飙升

场景描述

导致CPU使用率非预期增长的情况比较复杂,本文主要针对比较常见的几个现象进行说明,包括慢查询、SQL写法、活跃线程高以及统计信息过期。

表1 CPU使用率飙升原因分析

原因类别

核心问题描述

典型特征

慢SQL与索引缺失

SQL执行效率低下,多为全表扫描或扫描行数巨大,导致逻辑读过高。

慢SQL日志增多,InnoDB逻辑读速率突增。

SQL写法不当导致索引失效

SQL写法问题导致索引未被使用,如隐式类型转换、函数操作等。

CPU飙升但无明显的慢SQL记录,执行计划显示type=ALL。

活跃会话陡增

业务并发请求暴增,或存在大量锁等待导致线程堆积,上下文切换加剧。

活跃连接数(Threads_running)突增,QPS并不高。

统计信息过期或自动收集

优化器基于过时统计信息生成错误执行计划,或因收集任务本身消耗资源。

执行计划突然变更,或在维护窗口期CPU周期性飙升。

慢SQL与索引缺失

  • 问题描述

    数据库CPU使用率突然升高,但未伴随业务量突增。

  • 原因分析

    查看CPU使用率监控曲线,关联分析同一时间点的慢日志个数统计和InnoDB逻辑读速率。若趋势一致,基本可以定位为慢SQL导致。

    支持在TaurusDB控制台的智能DBA助手查看慢SQL情况,如果慢查询中有数据,需要对这些数据进行分析。如果在慢日志明细页签中,扫描行远远大于返回行数,则说明是慢SQL导致的CPU使用率升高。

  • 优化建议
    表2 优化建议

    优化建议

    详细说明

    索引优化

    1. 添加缺失索引:
      • 通过SHOW INDEX FROM t1;检查WHERE条件列是否已建索引。
      • 使用ALTER TABLE t1 ADD KEY idx_col (col);为高频查询字段创建索引。
    2. 验证索引生效:

      通过EXPLAIN + SQL确认执行计划是否使用新索引。

    统计信息更新

    1. 手动更新统计信息:
      • 执行ANALYZE TABLE t1;重新生成统计信息,纠正错误执行计划。
      • 通过EXPLAIN再次验证索引选择是否恢复。
    2. 配置自动更新:

      对频繁变更的表,编写自动化脚本在业务低峰期定期执行ANALYZE TABLE。

    扩容或读写分离

    应急措施

    1. 实时监控:

      通过SHOW PROCESSLIST检查当前会话状态,定位性能问题会话,运行状态为Sending data、Copying to tmp table、Copying to tmp table on disk、Sorting result、Using filesort的查询会话可能包含性能问题。

    2. SQL限流与会话管理:
      • 通过TaurusDB控制台的SQL限流功能临时阻断烂SQL。详细内容请参见SQL限流
      • 终止异常会话(如Sending data、Using filesort状态)。详细内容请参见手动Kill会话

    预防策略

    新业务上线前,通过EXPLAIN和SQL诊断工具分析执行计划,提前添加复合索引(遵循最左前缀原则)。

SQL写法不当导致索引失效

  • 问题描述

    出现CPU飙升但慢日志中并无耗时较长的SQL,可能是因为高频执行的简单SQL因写法问题走了错误的执行计划(如全表扫描)。

    常见场景:隐式类型转换、索引列使用函数、LIKE后缀匹配等。

  • 原因分析
    从TOP SQL模板,或慢SQL模板中抓取执行次数多且执行时间长的SQL,仔细对比SQL语句中传入的参数类型与表字段定义。一般涉及如下几种问题:
    • 隐式类型转换:字段类型与传入参数类型不一致(如VARCHAR字段传入INT值)。
    • 索引列使用函数:如WHERE DATE(create_time) = ...导致索引失效。
    • LIKE后缀匹配:LIKE '%test'无法利用索引,需改用前缀匹配(如LIKE 'test%')。
    • NOT IN/NOT EXISTS:在子查询含 NULL 值时语义不同且可能导致全表扫描,建议改写为LEFT JOIN ... IS NULL。
  • 优化建议
    表3 优化建议

    优化建议

    详细说明

    避免索引列函数操作

    避免在WHERE条件中对索引列使用函数或表达式,可将函数运算移至等号右侧,例如:

    • 优化前
      WHERE DATE(create_time) ='2026-03-12'
    • 优化后
      WHERE create_time >= '2026-03-12 00:00:00'AND create_time < '2026-03-13 00:00:00'

    强制类型匹配

    确保参数类型与字段定义一致(如VARCHAR字段传入字符串值)。

    优化LIKE查询

    优先使用前缀匹配(如LIKE 'test%'),避免后缀或中间匹配。

    改写NOT IN/NOT EXISTS

    使用LEFT JOIN ... IS NULL或覆盖索引替代。

    定期分析执行计划

    使用EXPLAIN验证索引是否生效,结合开源pt-query-digest分析慢日志。

    紧急处理

    • MySQL中临时指定索引:FORCE INDEX (index_name)。
    • 更新统计信息:ANALYZE TABLE table_name

活跃会话陡增

  • 问题描述

    查看数据库监控中的活跃连接数,如果CPU飙升时,QPS(每秒查询数)变化不大,但活跃连接数暴涨,说明存在大量并发会话在争抢资源或处于锁等待状态。单条SQL执行效率正常,但高并发涌入导致CPU频繁上下文切换,引发资源争抢和请求堆积。

  • 原因分析
    • 高并发与资源争抢
      • 即使单条SQL不慢,瞬间高并发涌入会导致CPU频繁切换线程,消耗大量资源。
      • 1个CPU核心在同一时间只能处理1个请求,高并发下通过时间片轮转处理,但频繁切换会显著增加CPU负载。您可以登录TaurusDB管理控制台,单击实例名称,进入“实例概览”页面。在左侧导航栏选择“智能DBA助手”下的“实时会话”,查看活跃会话情况。
    • 锁等待与连接风暴
      • 业务洪峰导致连接数激增,大量会话争抢锁资源,形成请求堆积。
      • 应用侧连接池配置过大,可能引发连接风暴(如短时间建立大量连接)。
    • 实例资源瓶颈

      活跃线程与CPU负载长期居高不下,说明实例资源(CPU/内存)已接近或达到上限。此时建议对集群进行扩容操作。

  • 优化建议
    表4 优化建议

    优化建议

    详细说明

    扩容或读写分离

    应用侧优化

    • 调整连接池配置:避免连接数设置过大,合理限制最大连接数(如max_connections)。
    • SQL限流:对异常流量(如前端连接风暴)通过SQL限流拒绝请求,详细内容请参考SQL限流
    • 智能Kill会话:按照智能Kill会话规则判断满足条件的会话,自动kill排名前三的组内的所有会话,详细内容请参考智能Kill会话
    • 自治限流:通过预先设置CPU阈值、可允许最大活跃连接数、事件持续时间及最大并发数等前置条件,当相关条件满足时系统会对会话进行自动流控,详细内容请参考配置自治限流

    监控与诊断

    • 通过登录控制台,单击实例名称,进入“实例概览”页面。选择“智能DBA助手 > 实时会话”模块,定期检查TaurusDB控制台的活跃会话状态,定位锁等待或资源争抢的SQL。
    • 若CPU负载高且活跃线程未缓解,需结合应用侧日志排查业务堆积问题。

统计信息过期或自动收集

  • 问题描述

    某类SQL在未发生业务逻辑变更的情况下,突然执行效率下降数倍。通过EXPLAIN命令发现执行计划异常(如从索引扫描变为全表扫描)。查询数据库统计信息更新时间,发现统计信息未及时更新,导致优化器选择错误的执行计划。

  • 原因分析
    • 统计信息过旧
      • 表数据快速变化,但统计信息未自动更新。
      • 自动收集统计信息的任务在业务高峰期运行,消耗大量CPU资源,影响业务性能。
    • 基数估算错误

      优化器依赖统计信息估算数据分布,若统计信息过旧,可能导致索引选择错误(从索引扫描变为全表扫描)。

    • 参数配置问题

      innodb_stats_persistent_sample_pages采样页数不足,导致统计信息精度低。

  • 优化建议
    表5 优化建议

    优化建议

    详细说明

    手动更新统计信息

    • 对性能变差的SQL,执行ANALYZE TABLE table_name重新生成统计信息。
    • 通过EXPLAIN验证执行计划是否恢复为预期索引。

    配置自动更新机制

    对频繁变更的表,在业务低峰期定期执行ANALYZE TABLE,避免高峰期资源争抢。

    优化统计信息精度

    • 提交工单调整innodb_stats_persistent_sample_pages参数,增加采样页数(如从20提升至100),提高统计信息准确性。
    • 提交工单确认innodb_stats_persistent参数值为ON,确保统计信息持久化存储(避免重启后丢失)。

相关文档