MySQL对CPU的占用率很高怎么处理

一、确认与定位

  1. 确认整体 CPU 使用情况

    top -b -n1 | head -n15
    
    • 观察 MySQL (mysqld) 进程所占的 %CPU

    • 如果是多核系统,关注总和以及单核是否满载。

  2. 查看系统负载

    uptime
    • Load Average 长期高于 CPU 核数,说明系统压力大。

  3. 查看其它进程情况

    ps aux --sort=-%cpu | head -n10
    • 确认是否仅 MySQL 占用高,或与其它进程有关。


二、操作系统层面排查

  1. 磁盘 I/O 瓶颈

    iostat -xz 1 3
    • 查看 %iowait,若较高(>20%),需检查磁盘性能。

  2. 内存/交换分区

    free -m 
    vmstat 1 5
    • 确认是否发生大量 swap 使用或频繁换页,导致 CPU 等待。

  3. 网络状况(如果应用有大量远程访问)

    netstat -anp | grep ESTABLISHED | wc -l
    • 检查连接数和网络丢包。


三、MySQL 层面初步诊断

  1. 查看当前线程状态

    SHOW PROCESSLIST;
    • 查找 State 长时间处于 Copying to tmp tableSorting resultLocked 等状态的线程。

    • 批量终止阻塞的查询

      -- 1. 把所有超时(>60秒)的会话拼成一条 KILL 语句串
      SELECT 
        GROUP_CONCAT(CONCAT('KILL ', id) SEPARATOR ';')
      INTO @kill_stmt
      FROM information_schema.processlist
      WHERE TIME > 60;
      
      -- 2. (可选)查看一下拼出来的字符串
      SELECT @kill_stmt;
      
      -- 3. PREPARE 并执行
      PREPARE stmt FROM @kill_stmt;
      EXECUTE stmt;
      DEALLOCATE PREPARE stmt;

  2. 查看全局状态指标

    SHOW GLOBAL STATUS LIKE 'Threads_connected';
    SHOW GLOBAL STATUS LIKE 'Threads_running';
    SHOW GLOBAL STATUS LIKE 'Innodb_rows_read';
    SHOW GLOBAL STATUS LIKE 'Slow_queries';
    
    • 关注活动线程数、慢查询数量变化趋势。

  3. 查看全局变量配置

    SHOW VARIABLES WHERE Variable_name IN (
      'innodb_buffer_pool_size',
      'innodb_buffer_pool_instances',
      'query_cache_size',
      'max_connections',
      'innodb_thread_concurrency'
    );
    
    • 与服务器内存、连接量匹配是否合理。


四、慢查询与热点 SQL 排查

  1. 开启慢查询日志

    SET GLOBAL slow_query_log = ON;
    SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
    SET GLOBAL long_query_time = 1;  -- 记录超过1秒的查询
    
  2. 分析慢查询日志
    使用 pt-query-digest(Percona 工具):

    pt-query-digest /var/log/mysql/slow.log > slow_report.txt
    
    • 排名前若干耗时、执行次数多的 SQL。

  3. 实时监控

    #从MySQL的性能监控系统中获取当前正在执行的SQL语句的性能数据,并按执行时间排序显示最耗时的10条语句。
    SELECT * 
    FROM performance_schema.events_statements_current
    ORDER BY TIMER_WAIT DESC
    LIMIT 10;
    
    
    • Performance Schema 可实时查看最耗时的语句。


五、索引与执行计划优化

  1. 查看慢查询执行计划

    EXPLAIN SELECT …;
    • 观察是否使用全表扫描(type = ALL)、临时表、文件排序等。

  2. 创建或调整索引

    • 针对 EXPLAIN 中出现的 possible_keyskey_len,增加或优化索引。

    • 避免对低基数列或频繁更新列建索引。

  3. SQL 重写

    • 拆分复杂查询、避免子查询,使用 JOIN、分批查询等方式降低单条 SQL 负载。


六、MySQL 配置调优

  1. InnoDB 缓冲池

    [mysqld]
    innodb_buffer_pool_size = 70% * total_ram
    innodb_buffer_pool_instances = 根据缓冲池大小适当设置(一般每实例1–2GB)
    
  2. 线程并发

    innodb_thread_concurrency = CPU_核数 * 2
  3. 查询缓存(MySQL 5.7 或更低)

    • 如果写操作频繁,可考虑关闭:

      query_cache_type = 0
      query_cache_size = 0
      
  4. 临时表与排序限制

    sort_buffer_size = 2M
    tmp_table_size = 64M
    max_heap_table_size = 64M
    
  5. 连接数控制

    max_connections = 根据业务高峰评估,避免过多连接导致上下文切换
    

修改完毕后,重启或动态生效:

systemctl restart mysqld
-- 或 --
SET GLOBAL innodb_buffer_pool_size = …;

七、资源隔离与硬件扩展

  1. CPU 亲和/资源隔离

    • 在多实例部署或虚拟化环境中,可通过 taskset、cgroups 对 mysqld 进程限流。

  2. 读写分离

    • 部署主从或中间件(如 ProxySQL),将读压力分散到只读从库。

  3. 硬件升级

    • 如果长期高负载且业务持续增长,可考虑增加 CPU 核数、提升 I/O 性能(NVMe)、扩充内存。


八、持续监控与预警

  1. 监控指标

    • 重点监控:CPU、Load、慢查询数、活跃连接数、Buffer Pool 命中率、锁等待、I/O 等。

    • 推荐工具:Prometheus+Grafana、Zabbix、Percona Monitoring and Management (PMM)。

  2. 预警配置

    • 针对关键指标设置报警阈值(如 CPU 超过80%、慢查询数突增)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值