欢迎光临好主题官网!致力于 WordPress 企业主题定制开发及 WP外贸模板下载。

WordPress 服务器优化实战教程:4GB 内存 Ubuntu + 宝塔面板,排查 MySQL 被 OOM 杀死的问题

文章目录

一、为什么 WordPress 网站需要进行服务器优化?

WordPress 网站出现访问缓慢、后台卡顿、页面偶尔无法打开,甚至数据库突然停止运行等问题时,很多站长的第一反应是升级服务器配置。

但服务器性能问题不一定是硬件资源不足,也可能是 PHP-FPM 进程数量过多、MySQL 内存配置不合理、并发请求集中到达,或者系统缺少应对内存压力的缓冲机制。

尤其是使用宝塔面板部署 WordPress 的服务器,通常同时运行以下服务:

  • Nginx:负责处理 HTTP/HTTPS 请求。
  • PHP-FPM:执行 WordPress 的 PHP 程序。
  • MySQL:负责存储 WordPress 文章、页面、用户、订单等数据。
  • Redis:用于对象缓存等场景。
  • 宝塔面板及其后台服务:负责网站、数据库、计划任务等管理功能。
  • 系统监控、安全防护及云厂商相关服务。

这些服务共享服务器的 CPU、内存和磁盘资源。如果没有合理控制进程数量和内存使用,就可能出现某个服务占用资源过多,导致其他服务受到影响的情况。

本文记录一次实际的 WordPress 服务器排查过程,介绍如何通过 Linux 系统命令、PHP-FPM 配置、MySQL 状态和系统日志定位问题,并在不进行大规模改动的前提下完成第一阶段优化。

二、本次服务器环境与问题背景

本次优化的服务器环境如下:

项目 实际环境
操作系统 Ubuntu Linux
服务器 CPU 2 核
服务器内存 4GB
网站管理面板 宝塔面板
Web 服务器 Nginx
网站程序 WordPress
PHP 版本 PHP 8.4
数据库 MySQL
缓存服务 Redis
网站数量 2 个 WordPress 网站
网站流量 整体较低
Swap 优化前未配置

虽然服务器拥有 4GB 内存,但 Linux 系统实际可用的物理内存会受到内核、系统服务和其他进程占用的影响,因此不能简单地把 4GB 全部视为网站可使用的内存。

本次排查中最值得关注的问题,并不是单纯的页面加载速度,而是系统日志中出现了多次内存不足记录。

日志显示,Linux 内核曾在多个时间点触发 OOM(Out Of Memory)机制,并终止了 MySQL 进程。

这说明服务器曾经出现严重的内存压力,导致数据库进程被系统强制结束。

对于 WordPress 网站来说,数据库异常退出可能进一步导致:

  • 网站页面无法正常读取数据库。
  • WordPress 后台无法登录或加载。
  • 网站出现数据库连接错误。
  • 访问过程中出现 500 错误或其他异常。
  • 数据库服务需要重新启动后才能恢复正常。

需要注意:OOM 记录能够证明系统当时发生过内存不足并触发了进程终止,但不能单凭日志认定唯一根因就是 PHP-FPM。 MySQL、PHP-FPM、其他后台服务和突发并发请求,都可能参与造成内存压力。

因此,正确的优化方式应当是先检查证据,再调整配置,而不是直接修改所有服务参数。

三、第一步:检查服务器整体内存使用情况

1. 使用 free 查看内存状态

登录服务器 SSH,执行:

free -h

该命令可以快速查看物理内存、缓存和 Swap 使用情况。

重点关注以下字段:

  • total:系统识别的总内存。
  • used:当前使用的内存统计值。
  • free:完全空闲的内存。
  • buff/cache:用于缓冲和缓存的内存。
  • available:系统估算当前可以提供给新程序使用的内存。
  • Swap:交换空间的总量和使用情况。

本次优化后,服务器的内存状态大致如下:

Mem:   total 3.5Gi  used 1.1Gi  free 1.7Gi
       buff/cache 1.1Gi  available 2.4Gi

Swap:  0B

从这组数据可以看出,服务器重启相关服务后,系统可用内存约为 2.4GiB,整体内存压力暂时不大。

不过,这只是当前时刻的快照,不能证明此前的内存问题已经永久解决。

实战建议:判断 Linux 内存是否紧张时,应优先观察 available,不能只看 free。 Linux 会主动利用空闲内存进行缓存,因此 free 较低并不一定代表系统内存不足。

2. 使用 top 观察进程

执行:

top

进入交互界面后,重点查看:

  • %CPU:进程 CPU 使用率。
  • %MEM:进程内存占比。
  • RES:进程实际驻留的物理内存。
  • COMMAND:进程名称。

如果希望直接按照内存占用排序,可以执行:

ps -eo pid,ppid,%mem,rss,comm,args --sort=-rss | head -20

其中,rss 的单位为 KB,表示进程驻留物理内存的大小。

本次排查中,MySQL 是需要重点关注的进程之一,部分 PHP-FPM 子进程也占用了较多内存。

这里需要注意一个细节:不能简单地把所有进程的 RSS 相加,就认为这等于服务器真实使用的物理内存。 不同进程可能共享部分内存映射,直接相加可能重复计算。

因此,应结合 free -h、进程列表和系统日志综合判断。

四、第二步:通过 Linux 日志确认是否发生过 OOM

如果服务器出现过数据库突然停止、PHP-FPM 子进程异常退出等情况,应检查内核日志。

执行:

journalctl -k --since "today" | grep -Ei \
'out of memory|oom-kill|killed process'

也可以使用:

dmesg -T | grep -Ei \
'out of memory|oom-kill|killed process'

具体可用日志取决于系统日志保留情况、权限以及内核配置。

如果发现类似以下信息:

Out of memory: Killed process ... (mysqld)

就说明 Linux 内核在内存不足时终止了 MySQL 进程。

这与普通的 PHP 报错、Nginx 访问错误并不相同。OOM 是操作系统层面的内存管理事件,应该从整个服务器的资源分配入手排查。

如何理解 OOM?

可以把服务器物理内存理解为一个有限的资源池。

假设服务器同时运行:

  • MySQL 数据库。
  • 多个 PHP-FPM 子进程。
  • Nginx 工作进程。
  • Redis。
  • 宝塔面板。
  • 其他系统服务。

当这些进程在同一时间需要较多内存,而系统无法满足分配需求时,Linux 可能触发 OOM Killer,选择一个进程终止,以缓解内存压力。

这并不意味着被终止的进程一定是内存使用最多的进程,也不代表该进程本身存在程序错误。

因此,看到 MySQL 被杀死后,不应该直接认定数据库有故障,更不能仅凭这一条记录就判断一定需要升级服务器。

本次排查确认了服务器历史上存在多次 MySQL 被 OOM 机制终止的记录。接下来,需要重点检查 PHP-FPM 的进程管理参数和 MySQL 的内存配置。

五、第三步:合理调整 PHP-FPM 进程数量

PHP-FPM 是 WordPress 服务器内存优化中非常重要的一环。

当用户访问 WordPress 页面时,如果请求需要执行 PHP 程序,通常会由 PHP-FPM 子进程负责处理。

如果同时存在大量 PHP 请求,PHP-FPM 可能启动多个子进程。每个子进程都需要占用一定内存,因此子进程数量会直接影响服务器的内存压力。

1. 查看 PHP-FPM 配置

本次服务器使用 PHP 8.4,配置文件路径为:

/www/server/php/84/etc/php-fpm.conf

在宝塔面板中,也可以通过对应 PHP 版本的配置管理入口检查相关参数。

重点关注:

pm = dynamic
pm.max_children = 12
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5
pm.max_requests = 500

这些参数分别表示:

参数 作用
pm 选择 PHP-FPM 的进程管理模式
pm.max_children 允许同时存在的最大子进程数
pm.start_servers 动态模式启动时创建的子进程数
pm.min_spare_servers 尽量保持的最少空闲子进程数
pm.max_spare_servers 尽量保持的最多空闲子进程数
pm.max_requests 单个子进程处理指定数量的请求后重新创建

其中,pm.max_children 是内存控制的重要参数。

如果设置得过大,PHP-FPM 在并发请求增加时可能占用过多内存;如果设置得过小,则可能出现请求排队、响应时间增加等问题。

2. 为什么不能把 max_children 设置得越大越好?

假设一个 PHP-FPM 子进程在高负载时占用约 120MB 内存。

如果允许 30 个子进程同时运行,仅按这个示例估算,就可能需要:

120MB × 30 = 3600MB

这还没有计算 MySQL、Nginx、Redis、操作系统和宝塔面板的内存占用。

需要说明的是,120MB 只是用于说明问题的示例,并不是每个 PHP-FPM 子进程的固定内存消耗。实际占用会随着主题、插件、请求内容和 PHP 执行路径变化。

对于 4GB 内存服务器,如果直接把 pm.max_children 设置得很高,就可能在流量突然增加时造成内存竞争。

3. 本次调整后的参数

本次排查后,PHP-FPM 采用了以下配置:

pm = dynamic
pm.max_children = 12
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5
pm.max_requests = 500

调整思路是:

  1. 限制 PHP-FPM 的最大子进程数量。
  2. 保持适当的初始进程数,避免不必要的空闲进程长期占用资源。
  3. 设置合理的空闲进程范围。
  4. 通过 pm.max_requests 限制单个子进程持续处理请求的数量。

pm.max_requests = 500 并不意味着每个子进程必然存在内存泄漏。它是一种进程回收机制,可以帮助缓解某些第三方扩展或长期运行代码可能造成的内存持续增长。

4. 为什么选择 12 个子进程?

12 并不是所有 4GB WordPress 服务器都适用的固定标准,而是本次环境采用的第一阶段控制值。

合理的最大子进程数应该根据以下因素计算:

  • 系统和后台服务的基础内存占用。
  • MySQL 的实际内存使用。
  • PHP-FPM 子进程在真实请求中的内存分布。
  • 网站并发量和请求复杂度。
  • 系统需要保留的安全余量。

如果后续发现 PHP-FPM 进程经常达到上限,并且请求排队明显,就需要结合访问量和响应时间进一步评估,而不是直接把上限恢复到 50。

5. 修改配置后如何验证?

保存配置后,先检查配置文件语法:

/www/server/php/84/sbin/php-fpm -t

如果检查通过,再通过宝塔面板重启 PHP 8.4 的 PHP-FPM 服务。

随后执行:

ps -eo pid,ppid,%mem,rss,comm,args --sort=-rss | head -20

查看当前进程数量:

ps -eo args | grep -c '^php-fpm: pool www$'

需要注意,该统计方式针对进程命令行符合 php-fpm: pool www 的子进程;如果服务器有多个 PHP-FPM 池,或进程命名方式不同,应调整筛选条件。

本次重启后,PHP-FPM 子进程数量回到了较低水平。结合系统可用内存增加的情况,说明当前内存状态得到改善,但仍需持续观察,才能判断调整是否长期有效。

六、第四步:检查 MySQL,不要盲目修改数据库参数

PHP-FPM 限流之后,下一步是检查 MySQL 的运行状态和内存配置。

WordPress 的文章、页面、用户、菜单、WooCommerce 商品和订单等数据都可能依赖数据库。数据库异常退出会直接影响网站正常运行。

1. 检查 MySQL 进程的内存使用

可以执行:

ps -eo pid,ppid,%mem,rss,comm,args --sort=-rss | grep -E 'mysqld|PID'

也可以直接查看进程:

ps aux | grep '[m]ysqld'

本次优化后,MySQL 主进程的 RSS 约为 340MB 左右。该数值只是当时的进程内存快照,不代表 MySQL 的固定内存需求,也不能单凭它判断数据库参数是否合理。

数据库的内存消耗可能受到以下因素影响:

  • InnoDB Buffer Pool 大小。
  • 同时连接的客户端数量。
  • 每个连接的执行缓冲区。
  • 临时表及排序操作。
  • 表缓存和其他内部数据结构。
  • 查询负载与存储引擎行为。

因此,数据库配置优化需要结合实际参数和状态,而不能只看进程 RSS。

2. 为什么 MySQL 命令出现 Access denied?

本次排查曾执行:

/www/server/mysql/bin/mysql -Nse "SELECT VERSION();"

结果返回:

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

这条错误的意思是:客户端没有提供密码,而 MySQL 拒绝了当前登录尝试。

这不等于 MySQL 服务没有启动,也不代表数据库损坏。

如果宝塔面板中的数据库服务显示正常,就应该继续使用正确的数据库认证方式,而不是因为这条错误就重置 root 密码或修改数据库权限。

如果已经知道正确密码,可以使用交互式登录方式:

/www/server/mysql/bin/mysql -uroot -p

输入密码后,再执行数据库检查命令。密码应在提示时输入,不要直接写进命令行或公开粘贴到聊天记录中。

3. 查询 MySQL 内存相关配置

成功登录后,可以执行:

SHOW VARIABLES WHERE Variable_name IN (
  'innodb_buffer_pool_size',
  'max_connections',
  'thread_cache_size',
  'table_open_cache',
  'sort_buffer_size',
  'join_buffer_size',
  'read_buffer_size',
  'read_rnd_buffer_size',
  'tmp_table_size',
  'max_heap_table_size'
);

这组参数有助于了解数据库的内存配置。

尤其要注意:sort_buffer_size、join_buffer_size 等部分缓冲区可能按连接或操作分配。它们并不一定会在 MySQL 启动时一次性全部占用,但在高并发或复杂查询场景下,设置过大可能增加峰值内存消耗。

不要把所有参数简单相加后当作 MySQL 必然使用的内存,也不要因为服务器只有 4GB 内存就随意将所有参数改成极小值。

4. 查询数据库连接与运行状态

继续执行:

SHOW GLOBAL STATUS WHERE Variable_name IN (
  'Threads_connected',
  'Threads_running',
  'Max_used_connections',
  'Connections',
  'Uptime'
);

这些指标可以帮助判断:

  • Threads_connected:当前连接数。
  • Threads_running:当前正在执行任务的线程数。
  • Max_used_connections:服务器启动以来达到过的最大并发连接数。
  • Connections:服务器启动以来的连接尝试次数。
  • Uptime:本次启动后持续运行的时间。

如果最大连接数长期很低,并不意味着可以无限降低 max_connections;如果连接数持续接近上限,也不代表应该直接将其调大。

应该结合实际访问量、慢查询和 PHP-FPM 并发情况判断。

本次优化阶段没有贸然修改 MySQL 内存参数,而是先恢复并确认数据库服务运行正常,将数据库参数审计留作后续有数据支撑的优化步骤。

这种做法可以降低因盲目修改参数引发新问题的风险。

七、第五步:检查 MySQL 服务是否正常运行

完成 PHP-FPM 调整后,本次排查重新检查了 MySQL 服务。

在宝塔环境中,可以先通过面板查看数据库运行状态;也可以使用系统服务命令进行检查:

systemctl status mysqld

部分宝塔安装环境可能使用不同的服务名称或启动脚本。如果 mysqld 这个服务名称不存在,应先通过宝塔面板确认实际服务管理方式,而不是直接认定数据库故障。

本次服务器的 MySQL 服务随后恢复为 active (running) 状态。

还可以查看近期服务日志:

journalctl -u mysqld -n 60 --no-pager

如果想确认近期是否仍有新的 OOM 事件,可以执行:

journalctl -k --since "1 hour ago" | grep -Ei \
'out of memory|oom-kill|killed process'

没有输出,表示在所查询的日志范围内没有匹配到这些记录,但不能证明服务器从未出现过内存问题,也不能替代持续监控。

八、第六步:检查 Redis 和 Nginx,避免不必要的改动

除了 PHP-FPM 和 MySQL,本次也考虑了 Redis、Nginx 等服务的资源使用。

1. Redis 不要随意清空

Redis 可以用于 WordPress 对象缓存或其他缓存功能。

如果 Redis 正在被网站使用,直接执行清空数据库的命令可能导致缓存丢失,甚至影响依赖 Redis 保存的数据。

因此,排查过程中应先查看 Redis 的实际内存使用、配置和用途,再决定是否调整。

本次检查中,Redis 的内存占用较低,没有证据表明它是当前内存问题的主要来源,因此没有执行清空缓存或修改淘汰策略等操作。

2. Nginx 不需要因为 OOM 就盲目调整

Nginx 通常负责接收 HTTP/HTTPS 请求并将需要动态处理的请求交给 PHP-FPM。

如果 Nginx 的 CPU 和内存使用正常,网站访问也没有明显的连接瓶颈,就不应为了所谓的性能优化而随意增加工作进程、连接数或缓存参数。

应当先检查:

ps -eo pid,ppid,%mem,rss,comm,args --sort=-rss | head -20

并结合 Nginx 错误日志、访问日志以及实际响应时间判断是否需要调整。

本次问题的直接证据指向系统历史上发生过内存不足,而不是已经证实 Nginx 存在配置错误,因此没有把 Nginx 配置作为第一阶段的主要修改对象。

九、第七步:为什么建议考虑配置 Swap?

本次服务器的物理内存约为 4GB,但没有配置 Swap。

Swap 是 Linux 使用磁盘空间作为交换空间的一种机制。当系统内存承压时,内核可以在符合条件的情况下将部分内存页换出到交换空间,以缓解瞬时的物理内存压力。

对于运行 WordPress、MySQL 和 PHP-FPM 的小内存服务器,适当配置 Swap 可以作为额外的缓冲手段。

但需要明确:

  • Swap 不能代替物理内存。
  • 大量使用 Swap 可能造成明显的性能下降。
  • 配置 Swap 并不能解决内存泄漏或不合理的进程配置。
  • 如果系统持续发生内存压力,仍应查明真正的内存消耗来源。

对于本次 4GB 内存服务器,可以在确认磁盘空间、系统状态和业务需求后,考虑配置约 2GB 的 Swap 作为后续防护措施。

本次第一阶段没有把创建 Swap 作为已经完成的操作。是否实施,应根据服务器当前状态和后续观察结果决定。

十、第八步:建立一套简单有效的日常检查方法

服务器优化不能只在出问题时执行一次命令。更合理的方式是建立一套低成本的检查流程,在出现异常时能够快速定位。

1. 查看内存

free -h

重点观察 available 是否持续下降,以及 Swap 是否出现持续增长。

2. 查看内存占用最高的进程

ps -eo pid,ppid,%mem,rss,comm,args --sort=-rss | head -20

用于确认当前是 MySQL、PHP-FPM 还是其他进程占用了较多内存。

3. 查看系统负载

uptime

结合 CPU 核心数量、进程状态和实际请求量判断是否存在持续的系统负载压力。

负载高不一定意味着 CPU 已经跑满,也可能与进程等待、I/O 等因素有关,因此需要结合其他指标分析。

4. 检查近期 OOM 记录

journalctl -k --since "24 hours ago" | grep -Ei \
'out of memory|oom-kill|killed process'

如果日志中再次出现 MySQL 或 PHP-FPM 被终止的记录,应保存相关时间段的日志,并对照当时的内存状态进行分析。

5. 检查服务状态

systemctl status mysqld

如果实际服务名称不同,则以宝塔面板中显示的服务名称为准。

PHP-FPM 也应通过对应 PHP 版本的服务管理入口确认运行状态。

6. 检查网站是否正常

除了系统指标,还应进行真实业务验证:

  • 首页能否正常访问。
  • WordPress 后台能否登录。
  • 文章和页面是否能够打开。
  • 涉及数据库写入的功能是否正常。
  • 网站日志中是否持续出现 PHP Fatal error 或数据库连接错误。

系统内存恢复正常,不代表所有业务功能都已经验证通过。

十一、这次优化为什么没有一次性修改所有参数?

本次优化采取了分阶段处理的方式。

第一阶段完成的工作包括:

  1. 通过 Linux 日志确认服务器历史上出现过 OOM 事件。
  2. 确认 MySQL 曾被内核终止。
  3. 将 PHP-FPM 最大子进程数从原先较高的设置调整为 12。
  4. 将 PHP-FPM 的启动进程数、空闲进程范围和请求回收参数调整到更适合当前环境的值。
  5. 重启相关服务后检查系统内存状态。
  6. 确认 MySQL 服务重新处于运行状态。
  7. 检查 Redis、Nginx 等服务,没有对缺乏问题证据的配置进行大规模修改。

调整后,服务器的 MemAvailable 约为 2.4GiB,MySQL 进程 RSS 约为 340MB,PHP-FPM 子进程数量也回到了较低水平。

这表明当时的系统状态有所改善,但还不能证明历史 OOM 问题已经彻底根除。尤其是 MySQL 的详细内存配置尚未完成审计,服务器也需要经过一段时间的实际运行观察。

因此,本次优化暂时在这里收尾,后续如果再次出现内存异常,再根据新的日志和指标进行针对性处理。

这种方式比同时修改 PHP-FPM、MySQL、Redis、Nginx 等所有配置更容易验证效果,也更方便在出现问题时定位变更来源。

十二、WordPress 服务器优化的几个常见误区

误区一:内存不足就必须升级服务器

升级硬件有时是正确的选择,但应先确认是否存在明显不合理的进程配置、内存泄漏或突发并发问题。

如果只是 PHP-FPM 最大子进程数设置过高,合理限制进程可能就能改善内存压力。

当然,如果业务并发量已经超过现有服务器的承载能力,最终仍可能需要升级配置。

误区二:MySQL 被杀死就说明数据库坏了

MySQL 被 OOM Killer 终止,通常说明系统当时存在严重的内存压力。

这与数据库数据损坏不是同一回事。应先确认服务状态、日志和数据可用性,再决定是否需要进一步检查数据库。

误区三:PHP-FPM 子进程越多,网站速度越快

更多子进程可以提升一定程度的并发处理能力,但也会增加潜在的内存消耗。

对于小内存服务器,进程数量与单进程内存占用需要共同评估。

误区四:只要 free 很低,服务器就缺内存

Linux 会利用空闲内存进行缓存。分析内存压力时,应结合 available、Swap、进程 RSS 和 OOM 日志,而不是只看 free 一项。

误区五:为了优化必须修改所有服务

没有问题证据时,不应随意修改数据库权限、清空 Redis、调整 Nginx 全局配置,或大规模更改 MySQL 参数。

每次尽量只调整少量相关配置,并在修改后进行验证,才是更可控的运维方法。

十三、总结:先稳定运行,再进行下一阶段优化

本次 WordPress 服务器优化的核心,不是追求某个固定的内存使用比例,也不是把所有服务参数调整到网上流传的所谓最佳值,而是通过实际日志和运行数据确定问题。

对于 2 核 CPU、4GB 内存、运行两个低流量 WordPress 网站的 Ubuntu 服务器,合理控制 PHP-FPM 并发进程,是一个具有实际价值的第一阶段优化措施。

与此同时,MySQL 内存配置、Swap、防护措施和持续监控仍然需要根据后续运行数据逐步评估。

如果服务器在接下来的运行过程中保持稳定,就没有必要为了优化而不断改动配置;如果再次出现 OOM、数据库异常退出或内存持续下降,则应保存日志、记录发生时间,并根据当时的系统状态继续排查。

WordPress 服务器优化的正确顺序是:发现问题、收集证据、定位瓶颈、进行小范围调整、验证效果、持续观察。

对生产环境而言,稳定性、可验证性和可回滚性,往往比一次性修改大量参数更重要。

本文由 好主题 原创整理,致力于分享实用的 WordPress 建站知识与主题开发经验。 我们专注于提供高质量的 WordPress企业主题 资源,帮助中小企业轻松构建专业网站。 转载请注明来源,并保留原文链接,感谢您的支持与理解。

联系我们

教程看不懂?联系我们免费为您解答!免费助力个人,小企站点!

客服微信
相关文章
主题推荐

会员注册

成为会员,获得更多专属优惠!

验证码: 加载中... =

已有账号?
还没有账号?