在 Nginx + PHP-FPM + MySQL 部署 WordPress 后,若出现 MySQL CPU 占用异常(如长期高于 80%~100%,或突发峰值),通常不是单一组件问题,而是查询效率、配置不当、缓存缺失或攻击/插件冲突共同作用的结果。以下是系统化的诊断与解决步骤:
🔍 一、初步判断:CPU 高是持续还是突发?
| 现象 | 可能原因 |
|---|---|
| 持续高负载 | 缺少缓存、慢查询多、连接数过多、索引缺失 |
| 突发高峰 | 流量激增、恶意爬虫、插件执行复杂操作(如导出、备份)、WP-Cron 堆积 |
| 夜间/定时高峰 | WP-Cron 任务、备份脚本、日志清理等定时任务 |
🧰 二、诊断步骤
✅ 1. 确认 MySQL 是否真的高 CPU
# 查看 MySQL 进程 CPU 使用率
top -p $(pgrep mysqld)
# 或使用 htop / glances 更直观
htop
⚠️ 注意:有时高 CPU 来自应用层(PHP 解析 SQL 耗时),而非 MySQL 本身。需结合
slow_query_log和performance_schema判断。
✅ 2. 启用并分析慢查询日志(Slow Query Log)
开启慢查询日志(my.cnf / my.ini)
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1 # 超过1秒的查询记录为慢查询
log_queries_not_using_indexes = 1 # 记录未使用索引的查询
重启 MySQL 后生效。
分析慢查询
# 安装 mysqldumpslow 工具(通常已自带)
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log
重点关注:
- 哪些 SQL 语句执行时间长?
- 是否缺少索引?
- 是否全表扫描?
✅ 3. 检查当前活跃查询
-- 查看当前正在执行的查询
SHOW PROCESSLIST;
-- 或使用 performance_schema(MySQL 5.7+)
SELECT * FROM performance_schema.events_statements_current
WHERE THREAD_ID IN (
SELECT THREAD_ID FROM performance_schema.threads WHERE PROCESSLIST_ID IS NOT NULL
);
关注:
State字段:如Sending data,Copying to tmp table,Sorting result表示性能瓶颈。Time字段:长时间运行的查询。
✅ 4. 检查 WordPress 层面的问题
a. 禁用 WP-Cron 并改用系统 cron
WordPress 默认通过 HTTP 请求触发 wp-cron.php,在高并发下会频繁启动 PHP 进程,间接导致大量数据库查询。
修改 wp-config.php:
define('DISABLE_WP_CRON', true);
然后设置系统 crontab:
# 每10分钟执行一次
*/10 * * * * cd /path/to/wordpress && php wp-cron.php
b. 检查插件列表
某些插件(如 SEO 插件、统计插件、备份插件、安全插件)会在每次页面加载时执行复杂查询。
临时排查方法:
- 停用所有非核心插件,观察 CPU 是否下降。
- 逐个启用,定位问题插件。
c. 检查主题代码
自定义主题中若有直接调用 WP_Query 且未分页、无缓存,也可能导致高负载。
✅ 5. 检查数据库索引
登录 MySQL,对常见表检查索引:
SHOW INDEX FROM wp_posts;
SHOW INDEX FROM wp_postmeta;
SHOW INDEX FROM wp_comments;
常见缺失索引场景:
wp_postmeta.meta_key常用于LIKE或=查询,但若无索引则全表扫描。wp_posts.post_status,post_type等常用过滤字段应有索引。
💡 WordPress 核心表通常有基本索引,但自定义 meta 查询极易引发性能问题。
可使用插件如 Query Monitor 实时查看 SQL 查询及其耗时。
✅ 6. 检查 PHP-FPM 与 Nginx 配置
虽然不直接影响 MySQL CPU,但低效的 PHP 处理会导致更多请求堆积,进而增加数据库压力。
检查项:
- PHP-FPM 子进程数是否合理?
- OPcache 是否启用?
- Nginx 是否启用了 gzip、缓存静态资源?
✅ 7. 检查是否有恶意流量或爬虫
# 查看 Nginx 访问日志,高频 IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
若发现大量异常请求(如 /xmlrpc.php, /wp-login.php),考虑:
- 禁用 XML-RPC
- 限制登录尝试
- 使用 Cloudflare 等 WAF 防护
✅ 8. 检查 MySQL 配置参数
关键参数建议值(根据服务器内存调整):
[mysqld]
innodb_buffer_pool_size = 70% of RAM # 例如 8GB 内存设 5G
innodb_log_file_size = 256M
max_connections = 200 # 根据 PHP-FPM pm.max_children 调整
query_cache_type = 0 # MySQL 5.7+ 已废弃,勿用
thread_cache_size = 16
tmp_table_size = 64M
max_heap_table_size = 64M
❗ 错误配置(如 buffer pool 过小)会导致频繁磁盘 I/O,推高 CPU。
✅ 9. 使用监控工具辅助诊断
推荐工具:
- Percona Monitoring and Management (PMM):可视化 MySQL 性能
- Prometheus + Grafana:自定义指标监控
- mysqltuner.pl:一键评估 MySQL 配置合理性
wget https://raw.githubusercontent.com/AllanBique/mysqltuner-perl/master/mysqltuner.pl
perl mysqltuner.pl
🛠️ 三、优化建议汇总
| 类别 | 措施 |
|---|---|
| 数据库 | 添加缺失索引、优化慢查询、调整 InnoDB 参数 |
| WordPress | 禁用 WP-Cron、停用低效插件、启用对象缓存(Redis/Memcached) |
| 缓存 | 启用 Redis Object Cache、OPcache、Nginx 静态文件缓存 |
| 架构 | 读写分离(主从)、CDN 提速静态资源、负载均衡 |
| 安全 | 禁用 xmlrpc.php、限制登录、防火墙规则 |
📌 四、快速自查清单
✅ 是否启用慢查询日志?
✅ 是否分析过最耗时的 10 条 SQL?
✅ 是否禁用 WP-Cron 并改用系统 cron?
✅ 是否停用可疑插件测试?
✅ 是否检查了 wp_postmeta 等表的索引?
✅ 是否启用了 Redis/Object Cache?
✅ 是否检查了 PHP-FPM 和 Nginx 配置?
✅ 是否安装了 Query Monitor 插件?
✅ 五、示例:典型高 CPU 根因案例
场景:某博客日均 PV 5000,MySQL CPU 长期 90%+
诊断结果:
- 慢查询日志显示大量
SELECT * FROM wp_postmeta WHERE meta_value LIKE '%keyword%'meta_value无索引 → 全表扫描- 插件“Related Posts”未分页查询
解决方案:
- 为该字段添加全文索引或使用 Elasticsearch
- 替换相关插件为支持缓存的版本
- 启用 Redis 缓存对象
结果:CPU 降至 15% 以下
📚 参考资源
- WordPress Performance Guide
- MySQL Slow Query Log Analysis
- Query Monitor Plugin
- Redis Object Cache Plugin
通过以上系统化诊断流程,你可以精准定位 MySQL CPU 高的根本原因,并采取针对性优化措施,显著提升 WordPress 站点性能与稳定性。
轻量云Cloud