遇到ORA-00845错误时,查阅官方文档会发现解释其实很简单:/dev/shm这个tmpfs挂载点的可用空间,小于MEMORY_TARGET或MEMORY_MAX_TARGET两者中的较大值。但这并不意味着Oracle配置有误,而是AMM(自动内存管理)在启动时检测到内存分配条件不满足,直接选择拒绝加载实例。
从实际数据来看,当你设置了几十GB的MEMORY_TARGET,而/dev/shm只有64MB或512MB时,系统会直接报错。这个坑我在多台机器上都踩过,几乎无一幸免。

确认 /dev/shm 当前大小和 Oracle 内存参数
先别急着动手修改。通过以下两条命令快速确认一下,是否正好掉进了这个常见陷阱:
- 执行
df -h /dev/shm——如果显示结果为64M、512M,或者明显小于你的MEMORY_TARGET,那么问题就在这里。 - 以
sysdba身份登录后,运行show parameter memory_target和show parameter memory_max_target,记录下这两个参数值(单位为字节,对比时直接看GB更为直观)。 - 一个关键要点:Oracle实际需要的
/dev/shm空间,大约等于1.2倍max(MEMORY_TARGET, MEMORY_MAX_TARGET)。“刚好相等”往往是不够用的。
永久修改 /etc/fstab 才是唯一可靠的方式
不少文章会教你临时挂载:mount -o remount,size=4G /dev/shm。但这个方法重启后就失效了。原因在于Oracle启动的时机通常早于systemd的mount单元,很容易在重新挂载之前就读取到旧尺寸。
唯一可靠的解决方案,还是修改/etc/fstab:
- 编辑
/etc/fstab,添加或修正这一行配置:tmpfs /dev/shm tmpfs size=4G,mode=1777 0 0(将4G替换为你的目标值,建议设置为≥1.5倍较大内存参数)。 - 注意:这里不能写成
defaults。tmpfs的defaults不包含size=参数,结果仍然会是默认的64MB或2GB(具体取决于发行版)。 - 修改完成后立即验证:
sudo umount /dev/shm && sudo mount /dev/shm,然后执行df -h /dev/shm和mount | grep shm确认size已经生效。 - 在某些RHEL/CentOS/Oracle Linux 7+的环境中,
systemd-tmpfiles可能会覆盖fstab中的设置。需要同步执行:sudo systemctl mask dev-shm.mount。
容器、SELinux和ksm是隐形的拦路虎
即使df -h /dev/shm显示的大小已经正确,Oracle仍然报ORA-00845错误,这时就需要考虑底层机制在“看不见的地方”卡住了:
- Docker/Podman容器内的Oracle:在宿主机上修改
/dev/shm完全不起作用。必须在启动容器时显式添加--shm-size=4G参数。 - SELinux启用状态下,Oracle可能被禁止访问扩展后的shm。检查方法:
getsebool virt_use_shm。如果显示为off,执行setsebool -P virt_use_shm on启用。 - Oracle Linux上如果启用了ksm(内核同页合并),可能会干扰大页共享内存的分配。临时禁用方法:
echo 0 | sudo tee /sys/kernel/mm/ksm/run。 - 权限也需要核实:
ls -ld /dev/shm应显示drwxrwxrwt,且oracle用户属组需要具备写入权限。如果手动执行过chown,记得要复位。
最容易被忽略的是挂载时机。/dev/shm必须在Oracle实例启动之前完成挂载。cloud-init、minimal systemd配置或者某些容器初始化流程可能导致它延迟挂载,结果Oracle读取到的是空的或者极小的shm。可以查看systemd-analyze blame | grep shm,如果挂载耗时排在oracle.service之后,就需要调整依赖关系,或者通过Before=oracle.service显式声明启动顺序。
