ORA-01155表示数据库正进行启动、关闭、装载或卸载等全局状态变更,此时并发执行需特定实例状态的操作(如ALTER TABLESPACE ONLINE)会被拒绝;应等待v$instance.status变为OPEN后再操作,或检查alert.log确认是否由底层ORA-01157等错误导致卡在MOUNTED状态。

ORA-01155 是数据库状态冲突,不是表空间问题
报 ORA-01155 时,你根本别去碰表空间——这个错误和表空间 ONLINE/OFFLINE 操作完全无关。它只说明:数据库正在执行 STARTUP、SHUTDOWN、ALTER DATABASE MOUNT 或 ALTER DATABASE OPEN 这类全局状态变更,而你同时发了另一个需要特定实例状态的命令(比如 ALTER TABLESPACE ... ONLINE)。Oracle 拒绝并发状态操作,这是保护机制,不是故障。
常见触发场景:
- 在
sqlplus / as sysdba里刚敲完STARTUP就立刻切窗口执行ALTER TABLESPACE users ONLINE - 脚本里没加等待逻辑,
STARTUP和后续 DDL 在毫秒级内连续发出 - 应用连接池未关闭,旧连接残留并尝试执行 DDL,而 DBA 正在重启实例
怎么确认是不是真卡在 ORA-01155?
先查实例当前状态,别猜:
SELECT status, database_status, instance_role FROM v$instance;
如果 status 是 MOUNTED 或 OPENING,而你执行的是 ALTER TABLESPACE ... ONLINE,那 100% 是这个错。此时强行重试只会重复报错。
真正该做的只有两件事:
- 等
v$instance.status变成OPEN再操作 - 如果等太久(比如超过 2 分钟),查
SELECT * FROM v$session WHERE status = 'ACTIVE' AND program LIKE '%ora_%'看是否有卡住的后台进程;必要时用SHUTDOWN ABORT强制终止,再干净重启
别把 ORA-01155 和 ORA-01157 混了
这两个错误名字像,但完全不搭界:ORA-01157 才是表空间/数据文件层面的问题(比如磁盘满、文件损坏、块大小不匹配),它会连带报出 ORA-01110 指向具体文件路径;而 ORA-01155 根本不关心文件,只认实例状态。
如果你看到 ORA-01155 后紧接着又出现 ORA-01157,大概率是第一次 STARTUP 因底层文件问题失败,实例卡在 MOUNTED 状态,你又立刻发了第二个 STARTUP,这才触发 ORA-01155。此时根因在 ORA-01157,得先看 alert.log 里第一个报错是什么。
脚本里怎么安全处理?
写自动化脚本时,不能假设 STARTUP 立刻完成。必须加轮询和超时:
BEGIN<br> FOR i IN 1..60 LOOP<br> SELECT status INTO v_stat FROM v$instance;<br> EXIT WHEN v_stat = 'OPEN';<br> DBMS_LOCK.SLEEP(2);<br> END LOOP;<br>EXCEPTION WHEN NO_DATA_FOUND THEN NULL;<br>END;
或者用操作系统命令判断:
until sqlplus -s / as sysdba <<EOF<br> SELECT status FROM v\$instance WHERE status = 'OPEN';<br> EXIT<br>EOF<br>| grep -q 'OPEN'; do sleep 1; done
最常被忽略的一点:ORA-01155 不代表数据库坏了,但它暴露了操作节奏失控——要么是人工操作太急,要么是脚本缺乏状态同步机制。修复重点不在 SQL,而在流程控制。


















