ORA-00845 报错时 /dev/shm 空间确实不够
这个错误不是 oracle 在“瞎报”,而是它启动时检查 /dev/shm 大小,发现低于 memory_target 或 memory_max_target 值就直接拒绝启动。linux 默认挂载的 /dev/shm 通常是 64mb,而现代 oracle 实例动辄要 2gb+ 共享内存,不调必报错。
关键判断点:不是看物理内存剩多少,而是看 /dev/shm 这个 tmpfs 挂载点的大小。用 df -h /dev/shm 看,如果显示 64M 或远小于你的 memory_target,就是它了。
改之前先确认 Oracle 参数:查 show parameter memory_target 和 show parameter memory_max_target目标值必须 ≥ 两者中较大者(单位是字节,但 mount 命令里用 size=2G 这种写法)临时生效用 sudo mount -o remount,size=2G /dev/shm,但重启后失效永久生效要改 /etc/fstab,加一行:tmpfs /dev/shm tmpfs size=2G 0 0
fstab 修改后重启没生效?检查挂载顺序和覆盖项
/dev/shm 是内核自动挂载的,如果 /etc/fstab 写得不对,系统可能跳过或被其他挂载覆盖。常见坑是:参数写成 defaults 而没显式写 size,或者用了 noauto、bind 这类干扰项。
执行 cat /proc/mounts | grep shm,确认输出里 size=2097152k(即 2G)这类参数真实存在如果看到 size=65536k,说明 fstab 没生效,检查是否漏了 tmpfs 类型字段,或行尾多了空格/注释符号某些发行版(如 RHEL 7+/CentOS 7+)会通过 systemd-tmpfiles 自动重置 /dev/shm,此时需同时禁用:sudo systemctl mask dev-shm.mount改完 fstab 后别只 reboot,先 sudo umount /dev/shm && sudo mount /dev/shm 测试是否能立刻挂上新大小
Oracle 启动仍报 ORA-00845?检查是不是 SELinux 或容器环境
即使 /dev/shm 大小正确,SELinux 的策略或容器(Docker/Podman)默认限制也会导致 Oracle 无法使用全部空间。这不是 Oracle 的 bug,是底层隔离机制在“拦路”。
SELinux 下运行 getsebool virt_use_shm,若为 off,需开:sudo setsebool -P virt_use_shm onDocker 启动容器时,必须显式挂载 shm:docker run –shm-size=2G …,光改宿主机 /dev/shm 对容器内无效Oracle Linux 上启用了 ksm(Kernel Samepage Merging)有时会干扰大页共享内存分配,可临时关:echo 0 | sudo tee /sys/kernel/mm/ksm/run确认 Oracle 用户对 /dev/shm 有读写权限 —— 一般没问题,但如果手动 chown 过就可能卡住
为什么不能直接设成 16G?注意 tmpfs 的内存占用特性
/dev/shm 是 tmpfs 文件系统,它用的是物理内存 + swap,不是“按需分配”。设成 16G 不代表立刻吃掉 16G 内存,但上限锁死了,且 Oracle 会尝试一次性分配接近该值的共享内存段。一旦物理内存紧张,容易触发 OOM killer 杀掉 Oracle 进程。
保守做法:设为 memory_max_target 的 1.2 倍(比如 max 是 8G,就设 9G~10G),留点余量给其他进程不要盲目设成系统总内存的 50%,尤其当机器还跑其他服务(比如 Web 服务器、监控 agent)时如果数据库用的是大页(use_large_pages=only),/dev/shm 实际用量会下降,但 ORA-00845 校验逻辑仍以 memory_target 为准,所以该调还得调生产环境上线前,用 ipcs -lm 看 shared memory limits,确保 max seg size 和 max total shared memory 也够用
真正麻烦的不是调数字,而是你改完 fstab、确认了 mount 输出、甚至重启了机器,结果 Oracle 还在报错——这时候大概率是 SELinux 或容器层在背后悄悄否决了你的配置。得一层层敲命令验证,而不是只信“我改过了”。

评论(0)