WordPress + MySQL 在 Linux 服务器上 CPU 持续飙高是一个常见但需系统性排查的问题。以下是结构化、可操作的排查与优化指南,涵盖快速诊断 → 定位瓶颈 → 针对性修复 → 长期防护:
🔍 一、快速定位:先确定「谁」在吃 CPU?
✅ 步骤 1:确认是 PHP(Web 层)还是 MySQL(数据库层)主导?
# 查看整体 CPU 占用(重点关注 %CPU 列)
top -c
# 或更清晰地按 CPU 排序(按 P 键可排序)
htop # (推荐安装:apt install htop / yum install htop)
# 快速抓取前 10 高 CPU 进程
ps aux --sort=-%cpu | head -11
- ❗ 若大量
php-fpm/apache2/nginx: worker进程占 CPU → PHP/应用层问题 - ❗ 若
mysqld进程持续 >80% CPU → MySQL 瓶颈(最常见!) - ❗ 若
cron、wp-cron.php频繁运行 → WP-Cron 机制失控
🐬 二、MySQL 高 CPU 的深度排查(占 70%+ 场景)
✅ 1. 实时查看慢查询 & 活跃连接
# 进入 MySQL
mysql -u root -p
# 查看当前正在执行的高耗时 SQL(重点关注 Time > 5s, State=Sending data/Sorting result)
SHOW PROCESSLIST;
# 更详细(含完整 SQL)
SHOW FULL PROCESSLIST;
✅ 2. 启用并分析慢查询日志(关键!)
-- 检查是否启用慢日志
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'long_query_time'; -- 默认 10s,建议调为 1~2s
-- 临时启用(重启后失效)
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2;
-- 查看慢日志路径
SHOW VARIABLES LIKE 'slow_query_log_file';
-- 通常为 /var/lib/mysql/your-hostname-slow.log
👉 分析慢日志(安装 mysqldumpslow 或用 pt-query-digest):
# 安装 Percona Toolkit(强烈推荐)
sudo apt install percona-toolkit # Ubuntu/Debian
sudo yum install percona-toolkit # CentOS/RHEL
# 分析 TOP 10 最耗时查询
pt-query-digest /var/lib/mysql/*.log | head -50
⚠️ 常见罪魁祸首 SQL:
SELECT * FROM wp_posts WHERE post_status = 'publish' ORDER BY post_date DESC LIMIT 0, 20
→ 缺少post_status + post_date复合索引!JOIN wp_postmeta无索引关联字段(如meta_key未建索引)- 插件(如 WPML、SEO 插件、统计插件)触发全表扫描
✅ 3. 检查索引缺失 & 表碎片
-- 检查 wp_posts 表是否有必要索引(重点!)
SHOW INDEX FROM wp_posts;
-- ✅ 应有:(post_status, post_date)、(post_status, post_name)、(post_author, post_status)
-- 检查 wp_postmeta 是否对 meta_key 建了索引(默认没有!)
SHOW INDEX FROM wp_postmeta;
-- ❌ 若无 `meta_key` 索引 → 立即添加(大量插件依赖此字段):
ALTER TABLE wp_postmeta ADD INDEX idx_meta_key (meta_key);
-- 检查表碎片率(>20% 建议优化)
SELECT
table_name,
round(((data_length + index_length) / 1024 / 1024), 2) as size_mb,
round((data_free / 1024 / 1024), 2) as free_mb,
round((data_free / (data_length + index_length)) * 100, 2) as frag_pct
FROM information_schema.tables
WHERE table_schema = 'your_wp_db_name' AND table_name LIKE 'wp_%'
ORDER BY frag_pct DESC;
✅ 4. MySQL 配置优化(/etc/mysql/my.cnf 或 /etc/my.cnf)
[mysqld]
# 关键调优项(根据内存调整!例如 4GB 内存服务器)
innodb_buffer_pool_size = 2G # ≈ 总内存 50~75%,必须设!
innodb_log_file_size = 256M # 提升写性能(需安全重建)
query_cache_type = 0 # ⚠️ MySQL 8.0+ 已移除;5.7 及以下建议关闭(易成瓶颈)
max_connections = 100 # 防止连接数爆炸
tmp_table_size = 64M
max_heap_table_size = 64M
sort_buffer_size = 4M # 避免磁盘排序
read_buffer_size = 2M
table_open_cache = 400
✅ 修改后重启:
sudo systemctl restart mysql
✅ 验证生效:mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
🐘 三、PHP/WordPress 层高 CPU 排查
✅ 1. 检查 PHP-FPM 状态(Nginx/Apache 下)
# 查看 PHP-FPM 进程数和状态
sudo systemctl status php*-fpm # 如 php7.4-fpm 或 php8.1-fpm
# 查看 FPM 慢日志(关键!)
# 编辑 /etc/php/*/fpm/pool.d/www.conf:
; slowlog = /var/log/php-fpm-slow.log
; request_slowlog_timeout = 5s
# 重启后观察该日志,定位卡住的 PHP 脚本(如某个插件 API 调用超时)
# 查看当前 PHP 请求堆栈(需启用 xdebug 或使用 strace)
sudo strace -p $(pgrep -f "php-fpm: pool www" | head -1) -s 200 -e trace=network 2>&1 | head -20
✅ 2. WordPress 特定问题排查
| 问题类型 | 检查方法 | 解决方案 |
|---|---|---|
| 插件冲突 | 启用 WP_DEBUG + SAVEQUERIES,或使用 Query Monitor 插件 |
禁用所有插件 → 逐个启用测试;重点关注:SEO 插件(Yoast/Squirrly)、缓存插件(WP Super Cache)、多语言(WPML)、统计(MonsterInsights) |
| 主题漏洞 | 切换到默认主题(Twenty Twenty-Four)测试 | 检查主题 functions.php 中是否有死循环、wp_get_recent_posts() 无分页、get_posts() 未加 posts_per_page 限制 |
| WP-Cron 拥塞 | 访问 wp-admin/tools.php?page=crontrol_admin_manage_page(需 Crontrol 插件) |
✅ 禁用内置 cron,改用系统 cron:0,15,30,45 * * * * cd /var/www/html; wp cron event run --due-now >/dev/null 2>&1并在 wp-config.php 加:define('DISABLE_WP_CRON', true); |
| XML-RPC 暴力攻击 | grep "xmlrpc.php" /var/log/nginx/access.log | wc -l(异常高) |
✅ Nginx 屏蔽:location ~ ^/xmlrpc.php$ { deny all; } 或用 Wordfence/All In One WP Security |
✅ 3. PHP 配置优化(/etc/php/*/fpm/php.ini)
memory_limit = 256M
max_execution_time = 120
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
opcache.revalidate_freq=60
realpath_cache_size=4096K
realpath_cache_ttl=600
✅ 重启 PHP-FPM:
sudo systemctl restart php*-fpm
🛡 四、长效防护与监控(防复发)
| 工具 | 用途 | 命令/配置 |
|---|---|---|
mysqltuner.pl |
MySQL 健康诊断 | wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl && perl mysqltuner.pl |
ngxtop |
实时分析 Nginx 日志(发现恶意爬虫/IP) | pip3 install ngxtop && ngxtop -l '/var/log/nginx/access.log' |
glances |
全面系统监控(CPU/内存/IO/网络) | pip install glances && glances |
| Prometheus + Grafana | 生产级监控(推荐) | 监控 MySQL QPS、Slow Queries、PHP-FPM Active Processes |
| 自动清理 | 防止垃圾数据拖垮 DB | 定期清理:wp post delete $(wp post list --post_type='revision' --format=ids) --force(用 WP-CLI) |
✅ 终极检查清单(5分钟速查)
- ✅
top看清是 mysqld 还是 php-fpm 主导? - ✅
SHOW PROCESSLIST;找出卡住的 SQL; - ✅
pt-query-digest分析慢日志,修复 TOP 3 慢查询(加索引!); - ✅
wp-config.php加define('WP_DEBUG', false);和define('DISABLE_WP_CRON', true);; - ✅ 检查
wp_postmeta.meta_key是否有索引?→ALTER TABLE wp_postmeta ADD INDEX idx_meta_key (meta_key); - ✅
innodb_buffer_pool_size是否设为内存 50~75%? - ✅ 禁用所有插件,切换默认主题,确认是否恢复 → 定位问题源。
💡 附:紧急降载(临时保命)
若 CPU 100% 无法登录,立即执行:
# 临时限制 MySQL CPU(需 cgroups v1,Ubuntu 18.04+/CentOS 7+)
sudo cgcreate -g cpu:/mysql-limited
echo 50000 | sudo tee /sys/fs/cgroup/cpu/mysql-limited/cpu.cfs_quota_us # 50% CPU
sudo cgclassify -g cpu:mysql-limited $(pgrep mysqld)
✅ 更推荐:直接重启 MySQL(
sudo systemctl restart mysql),再逐步优化。
如需进一步协助,请提供:
top截图或ps aux --sort=-%cpu | head -10输出mysql> SHOW VARIABLES LIKE 'innodb_buffer_pool_size';mysql> SELECT COUNT(*) FROM wp_posts;(数据量级)- 使用的缓存插件/CDN/主机类型(VPS?共享主机?云厂商?)
我可以帮你定制优化脚本或 SQL 修复语句 👇
需要我为你生成 一键诊断脚本 或 MySQL 索引优化 SQL 批处理 吗?
云服务器