Docker 容器频繁 OOM Killer 被杀?记一次达梦数据库在 2GiB 低配服务器上的内存调优实战 引言个人学习环境中我使用一台阿里云 2 核 2GiB 的 ECS 实例Alibaba Cloud Linux 3.2104搭建达梦数据库DM8容器。系统平稳运行一段时间后容器突然异常退出且多次重启后仍会在数小时或一天内再次停止。本文记录了我从问题现象、日志分析、参数调优到最终稳定运行的完整排查与解决过程希望能为在低配环境上运行内存敏感型容器的同学提供参考。问题现象与需求描述我的服务器上通过 Docker 运行了多个容器其中包括两个 SVN 服务和一个达梦数据库容器镜像dm8:v1.0镜像大小约 12.7GB。某天发现达梦容器处于停止状态执行docker ps -a看到状态为Exited (137)。需求很明确个人学习使用保持低配能持续稳定运行即可不追求高性能。多次试错与排查过程第一步查看容器状态和退出码[rootiZwz9i0ey3mo5h7inxu74uZ ~]# docker ps -a | grep dm88826bc8c7edb dm8:v1.0/opt/dmdbms/bin/dms…16hours ago Exited(137)10hours ago dm8退出码 137 在 Docker 中代表 128 9即容器进程收到了 SIGKILL 信号是被强制杀死的而非正常退出。这让我迅速将怀疑对象锁定在宿主机内存不足导致的 OOM Killer上。第二步检查容器日志dockerlogs 8826bc8c7edb--tail50日志反复出现类似以下的 checkpoint 信息并未显式报错checkpoint generate by ckpt_interval checkpoint begin, used_space[0], free_space[8589926400]... checkpoint requested by INI_INTERVAL, rlog free space[8589926400], used space[0]这表明容器内部数据库进程自身未崩溃更可能是外部因素强制终止。第三步查看宿主机内存和 Swap 状态free-h输出显示total used free shared buff/cache available Mem: 1.8Gi 505Mi 980Mi 2.0Mi 529Mi 1.3Gi Swap: 0B 0B 0B物理内存仅 1.8Gi而Swap 为 0意味着物理内存用尽后没有任何缓冲空间内核只能选择杀掉最耗内存的进程。第四步确认 OOM 事件dmesg|grep-ikill\|oom|tail-20关键输出[4238478.420807] oom-kill:constraintCONSTRAINT_NONE,nodemask(null),cpuset/,mems_allowed0,global_oom,task_memcg/docker/8826bc8c7edb...,taskdmserver,pid150061,uid0 [4238478.420988] Out of memory: Killed process 150061 (dmserver) total-vm:4578400kB, anon-rss:889708kB, file-rss:3440kB, shmem-rss:0kB, UID:0 pgtables:2596kB oom_score_adj:0确凿证据内核因全局内存不足杀死了达梦数据库进程 dmserver其 RSS 约为 890MiB加上系统和其他容器耗尽物理内存。第五步尝试调优达梦内存参数达梦数据库的配置文件为 dm.ini位于容器内的 /opt/dmdbms/data/DAMENG/dm.ini。由于容器已停止我先将其拷贝到宿主机修改后再复制回去。dockercp8826bc8c7edb:/opt/dmdbms/data/DAMENG/dm.ini ./dm.ini修改以下关键内存参数单位为 MB参数原值约修改后作用MEMORY_POOL20064初始内存池大小BUFFER1000100数据缓冲区核心消耗大户MAX_SESSIONS10020最大连接数使用 sed 命令快速修改sed-is/^MEMORY_POOL .*/MEMORY_POOL 64/./dm.inised-is/^BUFFER .*/BUFFER 100/./dm.inised-is/^MAX_SESSIONS .*/MAX_SESSIONS 20/./dm.ini然后将修改后的文件复制回容器dockercp./dm.ini 8826bc8c7edb:/opt/dmdbms/data/DAMENG/dm.ini第六步创建 Swap 空间关键一步由于物理内存只有 2GiB即便降低达梦内存仍可能被系统 OOM因此必须启用 Swap 作为缓冲。我创建了一个 2GB 的 Swap 文件并永久启用ddif/dev/zeroof/swapfilebs1Mcount2048chmod600/swapfilemkswap/swapfileswapon/swapfileecho/swapfile none swap sw 0 0/etc/fstab第七步设置容器自动重启为防止意外退出设置 Docker 重启策略dockerupdate--restartunless-stopped 8826bc8c7edb第八步启动容器并验证dockerstart 8826bc8c7edb查看容器状态和资源占用dockerpsdockerstats 8826bc8c7edb --no-stream输出显示CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS 8826bc8c7edb dm8 0.04% 601.6MiB / 1.827GiB 32.15% 3.11MB / 3.16MB 93.3MB / 1.77MB 111达梦实际物理内存占用约600MiB远低于之前的 900MiB且 Swap 暂未使用说明当前内存压力完全可控。此后容器持续运行未再退出。最终实现方案完整代码1. 调优达梦内存参数将容器内 dm.ini 中以下参数调整为低配值可根据实际情况进一步微调ini MEMORY_POOL64BUFFER100MAX_SESSIONS20若容器未启动可用 docker cp 拷贝出来修改再拷回。2. 创建并启用 Swap永久# 创建 2GB swap 文件ddif/dev/zeroof/swapfilebs1Mcount2048chmod600/swapfilemkswap/swapfileswapon/swapfile# 开机自动挂载echo/swapfile none swap sw 0 0/etc/fstab3. 设置容器自动重启dockerupdate--restartunless-stoppedcontainer_id问题根源总结与避坑要点根源总结物理内存严重不足2GiB 的服务器运行达梦数据库其默认配置的内存池BUFFER 等会占用 1GiB 以上加系统和其他容器极易触发 OOM。未配置 SwapLinux 在没有 Swap 的情况下一旦物理内存耗尽内核会直接杀死最耗内存的进程OOM Killer导致容器异常退出状态码 137。容器缺乏自动恢复机制未设置 --restart 策略退出后需手动干预。避坑要点容器退出码 137 基本等同于被强制杀死优先怀疑内存不足或 OOM。查看 dmesg 可快速确认是否存在 OOM 事件比盲目查应用日志更高效。达梦数据库在低配环境必须手动调低 BUFFER这是最有效的内存控制参数。Swap 是低配服务器的“救命稻草”虽然性能下降但换来了稳定性适合学习/测试环境。设置 --restart unless-stopped 是容器生产实践的标配避免单点故障后无人值守。结语通过这次排查我深刻体会到在资源受限的环境中“稳定”比“性能”更重要。从诊断 OOM、调整数据库参数、启用 Swap到设置自动重启每一步都环环相扣。最终达梦容器以 600MiB 内存稳定运行完美满足个人学习需求。希望本文能帮助遇到类似问题的同学少走弯路快速定位并解决 Docker 容器因内存不足而被杀的难题。