ORA-00304 是因 instance_number 冲突且 Oracle 无法识别同号实例所致,本质是启动协调失败而非数据库损坏;常见于 RAC 异常宕机残留资源或 cluster_database 配置错误。
ORA-00304 是什么,为什么不能直接重启实例
ora-00304 报错本质是 startup 时发现已有实例在用同一个 instance_number,但该实例没正常注册到集群或共享内存里,导致 oracle 认为“想用的编号被占着,可又找不到活的进程”。不是数据库坏了,而是启动协调机制卡住了。
常见诱因:RAC 环境中一个节点异常宕机后残留了 sga 或 semaphore,或者单实例用了 cluster_database=TRUE 却没配 CRS;也可能是 DBA 手动改过 instance_number 参数但没清理干净。
- 别急着
shutdown abort再试——如果真有另一个实例在跑,强杀会丢数据 - 别盲目删
/dev/shm下文件——Oracle 12c+ 默认用tmpfs,乱删可能让其他实例崩溃 - 检查前先确认是不是 RAC:查
v$option里Oracle Real Application Clusters是否为TRUE
查清到底有没有“活着的同号实例”
核心动作不是看进程,而是看 Oracle 自己认不认那个实例。靠 ps -ef | grep ora_ 容易误判,因为残留的 ora_pmon_* 进程可能只是僵尸。
更可靠的三步验证:
- 连上本机
sqlplus / as sysdba,执行SELECT instance_name, instance_number, status FROM gv$instance;—— 如果返回空或只有一行,说明 Oracle 没感知到冲突实例 - 查系统级资源:运行
ipcs -m(共享内存)和ipcs -s(信号量),找 key 和 owner 匹配你ORACLE_SID的条目;若有,记下id - 再查
cat /proc/*/environ 2>/dev/null | grep -z ORACLE_SID | grep -z "your_sid",确认是否有残留进程真正持有环境变量
清理残留资源的实操顺序(别颠倒)
顺序错了可能触发 ORA-27300 或挂起新实例。必须按“信号量 → 共享内存 → 临时文件”走。
- 先删信号量:
ipcs -s | awk '$2 ~ /^0x/ {print $2}' | xargs -I{} ipcs -s -i {} | grep "your_sid" | awk '{print $2}' | xargs -r ipcrm -s - 再删共享内存段:
ipcs -m | awk '$2 ~ /^0x/ {print $2}' | xargs -I{} ipcs -m -i {} | grep "your_sid" | awk '{print $2}' | xargs -r ipcrm -m - 最后清
/var/tmp/.oracle/和/tmp/.oracle/下以oradism_、snp_开头的 socket 文件(不是所有版本都有,但 19c+ 常见)
注意:ipcrm 命令对 root 权限敏感,普通 oracle 用户只能删自己创建的;如果提示 Operation not permitted,得切 root 执行。
启动前必须核对的两个参数
instance_number 和 cluster_database 不匹配是 ORA-00304 的隐形推手。尤其在从单机迁 RAC 或反向操作后容易遗留配置。
- 查当前 spfile 里值:
SHOW PARAMETER instance_number和SHOW PARAMETER cluster_database - 如果确定是单实例,
cluster_database必须为FALSE;设成TRUE却没搭 CRS,Oracle 启动时就会去查 OCR,查不到就报 ORA-00304 -
instance_number在单实例中默认是 1,除非你明确需要多实例共存(如测试环境),否则别手动改;改了就得同步清理对应资源
改参数要用 ALTER SYSTEM SET ... SCOPE=SPFILE,改完必须重启监听和实例才生效,光 reload 不管用。
最常被跳过的一步:改完参数后没检查 $ORACLE_HOME/dbs/init<sid>.ora 是否还硬编码了旧值——spfile 优先级虽高,但某些异常启动路径会 fallback 到 pfile。

















