服务器再一次的“假死”崩溃


一查,还是MySQL的老毛病,触发了OOM-Killer,进而导致面板离线。

轻量应用服务器内存耗尽导致服务不可用的故障排查与处理


1. 故障现象与初步判断

1.1 故障描述

2026年8月5日上午11:14左右,某运行于阿里云轻量应用服务器上的网站出现无法访问的现象。具体表现为:

  • 网站页面无法打开,浏览器提示连接超时或无法建立连接;
  • 服务器上的宝塔面板无法登录,显示“面板离线”;
  • 登录阿里云轻量应用服务器控制台,实例状态显示为“运行中”。

1.2 初步判断

阿里云控制台显示的“运行中”仅代表虚拟机实例通电且操作系统内核仍在运行,并不代表内部业务服务正常。出现“控制台在线但业务全挂”的典型情形包括:

  • 关键进程(如Web服务器、数据库)崩溃或被系统终止;
  • 系统资源耗尽,无法响应新请求;
  • 磁盘空间或索引节点(Inode)已满;
  • 内核因内存不足触发OOM-Killer机制。

本次故障的首要排查方向应聚焦于系统日志资源状态


2. 排查过程

2.1 查看系统日志定位根因

登录服务器SSH后,首先查看系统日志中的错误、内存溢出(OOM)及进程被杀的记录。

执行命令:

sudo grep -i "killed process\|oom\|panic" /var/log/messages | tail -20

输出结果(关键部分摘录):

时间戳关键信息
Aug 5 10:59:19php-fpm invoked oom-killer
Aug 5 10:59:19Out of memory: Killed process 1977 (mysqld)
Aug 5 11:14:36php-fpm invoked oom-killer
Aug 5 11:14:40Out of memory: Killed process 15057 (mysqld)

2.2 根因确认

日志清晰表明:

  1. 触发机制:Linux内核的OOM-Killer(内存溢出杀手)被频繁触发。
  2. 直接后果:MySQL(mysqld)进程被内核强制终止以释放内存。
  3. 连锁反应:MySQL终止后,所有依赖数据库的网站和宝塔面板均无法正常工作,表现为“离线”或“无法访问”。
  4. 爆发时间点:8月5日上午10:59和11:14连续两次触发OOM,最终表现为服务完全不可用。

3. 根因分析

3.1 什么是OOM-Killer

OOM-Killer是Linux内核的一种保护机制。当系统物理内存耗尽时,内核会依据各进程的“不良程度”评分,选择一个进程强制杀掉,以回收内存,避免整个操作系统崩溃。

3.2 为什么总是MySQL被杀

从日志可见,被杀进程均为mysqld。原因包括:

  • MySQL是服务器上内存占用最大的进程;
  • 在高并发查询或大量数据库连接场景下,MySQL内存消耗会急剧上升;
  • OOM-Killer在评分时,倾向于选择内存占用最高且非系统关键进程,MySQL首当其冲。

3.3 为什么会“以前没事,最近才出问题”

这是运维中常见的情况,原因通常属于以下几类:

原因类别具体说明
数据量增长网站数据随时间累积,MySQL缓冲池需求增加
访问量增长用户或爬虫流量上升,PHP进程增多,挤占内存
系统累积效应内存碎片、缓存堆积,可用内存逐渐减少至临界点
定时任务叠加每日特定时段(如备份、日志切割)与业务高峰重叠,瞬时内存需求骤增

3.4 服务器配置与内存压力分析

通过free -h命令查看服务器内存状态:

指标数值说明
物理内存总量757 Mi约等于1GB
已用物理内存334 Mi不含缓存
可用物理内存304 Mi实际可分配给新进程的内存
Swap总量3.0 Gi已配置虚拟内存
Swap已用207 Mi说明物理内存早已不足,系统被迫使用硬盘作内存

核心结论:该轻量服务器配置为1GB内存,但同时运行了MySQL、PHP-FPM、Nginx及宝塔面板,内存资源已达极限。每天上午业务高峰期(约10:30-11:30)内存耗尽并触发OOM,是必然结果。


4. 解决方案

4.1 临时止血措施(已完成)

操作目的执行命令
清理系统缓存释放被缓存占用的物理内存,降低Swap压力sync && echo 3 > /proc/sys/vm/drop_caches

效果:Swap使用量从468Mi降至207Mi,系统响应速度明显改善。

4.2 应用层优化(治本)

4.2.1 MySQL内存限制

通过宝塔面板或直接修改配置文件/etc/my.cnf,调整以下参数:

参数原值(典型)建议值说明
innodb_buffer_pool_size256M或更高128MInnoDB存储引擎缓存池大小,是MySQL最大内存消耗项
performance_schemaONOFF关闭性能监控表,可释放约100MB内存

操作路径(宝塔面板):软件商店 → MySQL → 设置 → 性能调整 → 修改上述参数 → 重启MySQL。

4.2.2 PHP-FPM进程数限制

参数建议值说明
pm.max_children10最大子进程数,1GB内存下安全阈值为10-15

操作路径(宝塔面板):软件商店 → PHP → 设置 → 性能调整 → 修改pm.max_children → 重载PHP配置。

4.3 长期根本性方案

方案说明优先级
升级服务器配置将轻量应用服务器内存升级至2GB或以上高(物理层面解决)
启用Redis缓存减少MySQL直接查询压力,降低数据库内存占用
优化慢查询检查并优化MySQL慢查询日志中的SQL语句
配置监控告警阿里云云监控或宝塔面板设置内存使用率告警(如>85%)高(预防复发)

5. 总结与经验

5.1 故障时间线

flowchart TD
    A[上午10:59 业务流量逐渐上升] --> B[10:59 物理内存耗尽]
    B --> C[内核触发 OOM-Killer]
    C --> D[MySQL 进程被强制终止]
    D --> E[网站/宝塔面板无法访问]
    E --> F[阿里云控制台仍显示“运行中”]
    F --> G[用户感知为“服务器离线”]
    
    H[11:14 新MySQL进程启动后再次触发OOM] --> I[MySQL再次被杀]
    I --> J[11:14 业务高峰,系统彻底无法响应]
    J --> K[11:18 运维人员手动重启服务器恢复服务]

5.2 核心结论

  1. 现象不等于根因:控制台显示“在线”不代表服务可用,必须深入系统层面排查。
  2. 日志是运维的第一手证据/var/log/messages中的OOM日志直接锁定真凶,避免了盲目重启的无效循环。
  3. 配置需匹配硬件:1GB内存运行MySQL+PHP+面板属于“超配”,必须通过限制各进程内存上限来维持稳定。
  4. Swap是缓冲垫,不是解决方案:Swap虽能延缓OOM发生,但磁盘IO远慢于内存,过度依赖Swap会导致服务响应极慢,甚至引发连锁OOM。

5.3 后续行动建议

  • 短期内执行上述MySQL和PHP配置优化,并观察3-5天;
  • 中长期规划服务器配置升级,或迁移至云数据库RDS以分离数据库服务;
  • 配置内存使用率监控告警,在故障发生前提前介入。

本文基于真实故障排查过程整理,所有日志输出、命令执行及配置调整均经过实际验证。

封面

声明:三二一的一的二|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - 服务器再一次的“假死”崩溃


三二一的一的二