资讯动态

线上服务器CPU飙高排查与MySQL性能优化实战

发布时间:2026/8/9 8:21:13 来源:尧图企业网站定制
1. 线上服务器CPU暴涨排查指南从系统到MySQL层最近在排查一个线上服务器CPU持续飙高的问题从系统层面一直追踪到MySQL数据库层最终定位到几个隐蔽但致命的性能陷阱。这类问题在电商大促、秒杀活动期间尤为常见这里把完整的排查思路和实战经验整理成指南涵盖从系统工具使用到MySQL参数调优的全链路分析方法。2. 系统层排查三板斧2.1 快速定位问题进程当收到服务器CPU告警时我习惯用这个组合命令快速抓取异常进程top -c -H -p $(pgrep -d, -f 关键服务名) # 监控特定服务的所有线程 ps -eo pid,pcpu,pmem,args --sort-pcpu | head -20 # CPU占用TOP20关键技巧通过-H参数显示线程级数据配合-p过滤特定服务。曾经有个案例表面是Java进程吃CPU实际是其中某个处理XML的线程卡死。2.2 火焰图精准分析对于Java/Python等应用我必用火焰图定位热点代码。以Java为例# 采集数据采样30秒 perf record -F 99 -p PID -g -- sleep 30 # 生成火焰图 perf script | stackcollapse-perf.pl | flamegraph.pl flame.svg常见模式解读宽平顶单一函数长时间执行如正则匹配细长塔深层调用栈可能递归问题锯齿状频繁上下文切换锁竞争典型特征2.3 系统级瓶颈检查通过mpstat -P ALL 2观察各核负载均衡情况时要特别注意%sys过高可能是系统调用频繁或上下文切换过多%iowait突增往往伴随磁盘IO瓶颈%soft异常中断处理消耗CPU常见于网络密集型应用3. MySQL层深度排查3.1 实时会话分析这套组合拳我用了五年依然有效-- 查看当前运行中的SQL8.0版本 SELECT * FROM performance_schema.threads WHERE PROCESSLIST_COMMAND ! Sleep\G -- 经典慢查询识别重点关注Rows_examined SELECT * FROM sys.statement_analysis ORDER BY avg_latency DESC LIMIT 10;血泪教训曾遇到一个WHERE status IN(...)查询由于缺失复合索引导致全表扫描在2000万数据量下CPU直接打满。3.2 锁等待诊断通过SHOW ENGINE INNODB STATUS查看LATEST DETECTED DEADLOCK段时要特别关注lock_mode X排他锁竞争index PRIMARY主键争用WAITING FOR THIS LOCK阻塞链源头3.3 参数调优实战这几个参数调优效果立竿见影# 连接数相关根据机器配置调整 thread_pool_size 16 # 通常设为核心数*2 table_open_cache 4000 # 查询优化 optimizer_search_depth 5 # 避免过度优化消耗 range_optimizer_max_mem_size 32M # 范围查询内存限制4. 经典案例库4.1 隐式类型转换灾难某次CPU飙高发现如下SQLSELECT * FROM orders WHERE user_id 10086 # user_id是int类型虽然查询很快但高峰期QPS达到2000时类型转换消耗了15%的CPU资源。通过EXPLAIN FORMATJSON看到warning字段才暴露问题。4.2 子查询爆炸一个统计报表SQL导致CPU持续100%SELECT COUNT(*) FROM ( SELECT DISTINCT user_id FROM logs WHERE create_time DATE_SUB(NOW(), INTERVAL 1 DAY) ) t优化方案-- 改用物化视图定时更新 CREATE TABLE daily_uv ( day_date DATE PRIMARY KEY, uv_count INT );5. 长效监控体系5.1 Prometheus关键指标这些指标我设置了智能报警process_cpu_seconds_total进程累计CPU时间mysql_global_status_innodb_row_lock_waits行锁等待mysql_slow_queries慢查询增长趋势5.2 自研诊断工具包分享我的常用脚本#!/bin/bash # 自动抓取诊断包 ts$(date %F_%H%M) mkdir -p /tmp/diag_$ts # 采集系统状态 top -b -n 3 /tmp/diag_$ts/top.log vmstat 1 60 /tmp/diag_$ts/vmstat.log # 抓取MySQL现场 mysql -e SHOW FULL PROCESSLIST /tmp/diag_$ts/processlist.log mysqldumpslow -s t /var/log/mysql-slow.log /tmp/diag_$ts/slow_analyze.log6. 避坑指南不要盲目加索引曾经给一个枚举字段加索引反而导致UPDATE变慢30%慎用ORWHERE a1 OR b2在5.7版本会导致全表扫描连接池大小建议公式(核心数 * 2) 有效磁盘数监控死角8.0版本前注意tmp_table_size溢出到磁盘的情况最后分享一个诊断口诀一查进程二看锁慢查索引少不了参数调优要谨慎监控体系不能少。遇到CPU问题按这个顺序排查基本能解决90%的线上故障。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价