线上MySQL数据库CPU占有率飙升问题的排查思路

线上MySQL数据库CPU占有率飙升问题的排查思路
最新回答
爱你,谁负了谁

2023-11-25 17:19:02

线上MySQL数据库CPU占有率飙升的排查需结合系统观察、工具定位及配置优化,核心流程如下

一、定位高CPU消耗的直接原因
  1. 未优化的复杂查询

    表现:大表全表扫描、多表关联未走索引、涉及排序(ORDER BY)、分组(GROUP BY)、DISTINCT/UNION等操作。

    影响:数据量增大或并发升高时,CPU需加载大量数据到内存/磁盘计算,导致飙升。

    案例:缺少复合索引的报表查询可能直接打满CPU。

  2. 高并发短连接

    表现:应用未正确使用连接池或配置不当,导致MySQL频繁建立/销毁连接。

    影响:连接认证、线程上下文切换等操作增加CPU负担。

  3. 大量写入操作

    表现:表索引过多时,INSERT/UPDATE/DELETE需更新索引,高并发或大事务会加剧锁竞争、日志刷盘。

    影响:索引维护和I/O操作推高CPU使用率。

  4. 统计信息过时

    表现:查询优化器基于不准确统计信息选择次优执行计划。

    影响:低效查询消耗更多CPU资源(如导航系统使用过时地图规划拥堵路线)。

  5. 系统资源瓶颈

    表现:内存不足导致SWAP交换、磁盘I/O成为瓶颈。

    影响:CPU“忙等”I/O完成,实际计算效率低下。

二、通过MySQL工具快速定位问题查询
  1. SHOW FULL PROCESSLIST

    作用:列出所有运行线程,关注Time(长事务/慢查询)、State(如Sending data、Sorting result、Copying to tmp table、Locked等)。

    示例:SHOW FULL PROCESSLIST;

  2. 慢查询日志(Slow Query Log)

    配置:slow_query_log = 1slow_query_log_file = /var/log/mysql/mysql-slow.loglong_query_time = 1log_queries_not_using_indexes = 1

    分析工具

    mysqldumpslow(官方工具)

    pt-query-digest(Percona Toolkit,支持聚合分析频率、总耗时、平均耗时及执行计划摘要)。

  3. Performance Schema与Sys Schema

    作用:追踪语句、阶段、文件I/O等性能数据。

    示例查询

    高总耗时查询:SELECT digest_text, count_star, sum_timer_wait/1000000000000 AS total_secondsFROM sys.statements_with_errors_or_warningsORDER BY sum_timer_wait DESCLIMIT 10;

    全表扫描查询:SELECT db, query, full_scan, exec_count, total_latencyFROM sys.statements_with_full_table_scansORDER BY total_latency DESCLIMIT 10;

  4. EXPLAIN分析执行计划

    关键字段

    type(访问类型:ALL全表扫描、index全索引扫描、ref/eq_ref较好、const最佳)。

    rows(预计扫描行数)。

    Extra(如Using filesort、Using temporary提示需优化索引)。

    示例:EXPLAIN SELECT * FROM your_table WHERE your_column = 'value';

三、系统与配置层面优化
  1. 硬件资源瓶颈

    CPU:核心数不足或主频过低。

    内存:innodb_buffer_pool_size过小导致频繁磁盘I/O(建议设为物理内存的50%-70%)。

    磁盘I/O:使用iostat检查磁盘性能,避免因I/O等待导致CPU空转。

  2. MySQL配置参数

    关键参数

    max_connections:过高会增加线程管理开销,需合理设置并配合连接池。

    tmp_table_size/max_heap_table_size:增大以避免磁盘临时表创建。

    thread_cache_size:缓存空闲线程,减少频繁创建/销毁。

    sync_binlog/innodb_flush_log_at_trx_commit:权衡数据安全性与写入性能(谨慎调整)。

    query_cache_size:现代版本建议禁用(设为0)或保持很小。

  3. 操作系统配置

    文件句柄限制:通过ulimit -n检查,避免MySQL无法打开足够文件。

    SWAP空间:过度使用表明内存不足,需优化内存配置。

    I/O调度器:选择deadline或noop(优于cfq)。

    透明大页(THP):禁用以避免性能下降。

  4. 应用层行为

    连接池使用:确保应用正确配置连接池,避免短连接爆发。

    事务管理:避免长时间未提交的大事务。

    N+1查询问题:减少循环中多次查询,优化为批量操作。

四、总结

排查MySQL CPU飙升需由表及里、层层深入

  1. 通过工具定位高消耗查询;
  2. 分析执行计划优化索引;
  3. 检查系统资源与配置参数;
  4. 协同开发团队优化应用层逻辑。核心原则:无固定解决方案,需持续分析、优化与迭代。