数据库进程设oom_score_adj=-1000可完全豁免oom killer,需通过echo -1000 > /proc/[pid]/oom_score_adj临时生效,或在systemd服务中配置oomscoreadjust=-1000持久化,并建议配合cgroup内存限制防止单点失控。

直接修改进程的 oom_score_adj 值是最常用、最有效的方式,让数据库进程在内存紧张时被 OOM Killer 优先跳过。
给数据库进程设置豁免分值
Linux 内核通过 /proc/[pid]/oom_score_adj 控制单个进程的“可杀性”。取值范围是 -1000 到 +1000,-1000 表示完全豁免(内核不会选择它)。
- 先查出数据库进程 PID,例如 MySQL:
pidof mysqld或pgrep -f "mysql" - 写入豁免值(需 root 权限):
echo -1000 | sudo tee /proc/$(pidof mysqld)/oom_score_adj - 验证是否生效:
cat /proc/$(pidof mysqld)/oom_score_adj应输出-1000
让保护长期生效(systemd 服务)
临时写入只对当前运行有效。若数据库由 systemd 管理(如大多数 CentOS/RHEL/Ubuntu 系统),应在服务单元中固化配置。
- 编辑服务文件,例如:
sudo systemctl edit mysql.service - 添加以下内容:
[Service]
OOMScoreAdjust=-1000 - 重载并重启服务:
sudo systemctl daemon-reload<br>sudo systemctl restart mysql
配合内存限制防止单一进程耗尽资源
仅设 -1000 不能阻止进程本身因内存泄漏或配置错误占满内存——它只是“不被杀”,但可能拖垮整个系统。建议叠加 cgroup 限制。
- 创建 memory cgroup 并设上限(如 4GB):
sudo cgcreate -g memory:/db_service<br>echo "4G" | sudo tee /sys/fs/cgroup/memory/db_service/memory.limit_in_bytes
- 把数据库进程加入该组:
echo $(pidof mysqld) | sudo tee /sys/fs/cgroup/memory/db_service/cgroup.procs - 更推荐在启动脚本或 systemd 中用
MemoryLimit=4G直接配置(systemd v229+ 支持)
检查与监控是否真正起效
保护不是一劳永逸,要定期确认机制仍在运行。
- 查看当前 OOM 分数排名:
ps -eo pid,comm,oom_score,oom_score_adj --sort=-oom_score | head -10
确认数据库进程的oom_score显著低于其他高内存进程 - 检查内核日志是否有新 OOM 记录:
dmesg -T | grep -i "out of memory" - 观察
/proc/meminfo中MemAvailable和SwapFree是否持续偏低——说明内存压力真实存在,保护策略正在应对实际风险











