oracle容器化部署需对齐三层边界:docker的--shm-size与--memory限制、宿主机内核的kernel.shmmax/shmall参数、oracle的sga_target/pga_aggregate_target配置,缺一导致ora-27102或sga分配异常。

Oracle 容器化部署(如 Docker 或 Kubernetes)时,内存和共享内存配置不当会导致实例启动失败、SGA 分配异常或 ORA-27102: out of memory 错误。关键不是“配多少”,而是“怎么配才让 Oracle 进程真正拿到它要的共享内存”。
容器里启动 Oracle 实例报 ORA-27102,大概率是 shm 太小
Oracle 启动时依赖 /dev/shm 作为 SGA 的底层载体(尤其在 AMM/ASMM 模式下)。Docker 默认只给 /dev/shm 64MB,远低于 Oracle 最小需求(哪怕只是单实例开发库,SGA_TARGET 设为 1G 时也至少需要 1.2G shm 空间)。
- 必须显式挂载并扩大
/dev/shm:用--shm-size=2g启动容器,不能靠-v /dev/shm:/dev/shm继承宿主机大小(Docker 会截断) - Kubernetes 中需在
securityContext下设置shmVolume并指定sizeLimit,例如shmVolume.sizeLimit: "2Gi" - 验证是否生效:
docker exec -it <container> df -h /dev/shm</container>,输出应接近你设定的值,而非 64M
memory_limit 和 sga_target / pga_aggregate_target 的关系别搞反
容器的内存限制(如 --memory=4g)是硬上限,而 Oracle 的 SGA_TARGET 和 PGA_AGGREGATE_TARGET 是“目标值”,不是固定占用。如果两者加起来超过容器内存限制,Oracle 可能因 OOM 被 kill,或启动时直接拒绝初始化。
- 保守起见,设
SGA_TARGET + PGA_AGGREGATE_TARGET ≤ 0.8 × 容器 memory limit(预留 20% 给 OS、后台进程、UGA 等) - 禁用 AMM(即设
MEMORY_TARGET=0),改用 ASMM 模式:只设SGA_TARGET和PGA_AGGREGATE_TARGET,避免 Oracle 在容器内动态跨区挪内存引发不可控 OOM - 若必须用 AMM,
MEMORY_TARGET必须 ≤ 容器--memory值,且MEMORY_MAX_TARGET不可大于MEMORY_TARGET
Oracle 容器启动时找不到共享内存段?检查 IPC namespace 配置
Docker 默认启用 IPC namespace 隔离,导致 Oracle 实例无法看到宿主机或其他容器的共享内存段——这本身是安全行为,但如果你依赖外部工具(如 ipcs 调试)或跨容器通信(如 RAC 场景),就会出问题。
- 单实例场景下无需改动,默认 IPC isolation 是 OK 的
- 若需复用宿主机 shm(不推荐生产),启动时加
--ipc=host,但会削弱隔离性 - RAC 容器集群必须用
--ipc=container:<rac-node-1></rac-node-1>让所有节点共享同一 IPC namespace,否则ora.cssd无法建立心跳 -
ipcs -m在容器内执行,应能看到 Oracle 创建的 key=0x00000000 类型的共享内存段;看不到说明 shm 挂载或权限有问题
Linux 内核参数在容器里不自动继承,得提前调
容器共享宿主机内核,但 kernel.shmmax、kernel.shmall 等参数仍由宿主机控制。如果宿主机这些值过小(比如 shmmax=33554432 即 32MB),即使容器挂了 2G shm,Oracle 也会因内核拒绝大段分配而报错。
- 检查宿主机:
sysctl kernel.shmmax,建议 ≥ 4GB(即4294967296) - 临时生效:
sysctl -w kernel.shmmax=4294967296 - 永久生效:写入
/etc/sysctl.conf并sysctl -p - 注意:
shmall应 ≥shmmax / PAGE_SIZE(通常 PAGE_SIZE=4096,所以 4GB 对应 shmall ≥ 1048576)











