速卖通素材
奋斗

Nginx + PHP-FPM + MySQL部署WordPress后MySQL CPU占用异常如何诊断?

服务器

在 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”未分页查询
    解决方案:

    1. 为该字段添加全文索引或使用 Elasticsearch
    2. 替换相关插件为支持缓存的版本
    3. 启用 Redis 缓存对象
      结果:CPU 降至 15% 以下

📚 参考资源

  • WordPress Performance Guide
  • MySQL Slow Query Log Analysis
  • Query Monitor Plugin
  • Redis Object Cache Plugin

通过以上系统化诊断流程,你可以精准定位 MySQL CPU 高的根本原因,并采取针对性优化措施,显著提升 WordPress 站点性能与稳定性。

未经允许不得转载:轻量云Cloud » Nginx + PHP-FPM + MySQL部署WordPress后MySQL CPU占用异常如何诊断?