ora-16000 表示数据库以只读模式打开,是dg备库正常状态提示而非错误;因其默认仅支持read only或read only with apply模式,执行alter database open未指定只读时触发该提示。
ora-16000 是什么,为什么备库打开会报这个错
ORA-16000 的完整提示是 “database open for read-only access”,它不是传统意义上的“错误”,而是 Oracle 在备库处于只读模式时主动抛出的状态提示。但很多 DBA 看到 ORA 开头就以为是异常,尤其当应用连接失败或脚本中断时误判为故障。
根本原因是:DG 备库默认只能以 READ ONLY 或 READ ONLY WITH APPLY 模式打开,不能像主库那样用 OPEN(即读写模式)。如果执行了 ALTER DATABASE OPEN 而没显式指定只读,Oracle 会拒绝并报 ORA-16000。
常见触发场景包括:
- 手动执行
STARTUP后未加MOUNT,直接ALTER DATABASE OPEN - 使用 Data Guard Broker 的
EDIT DATABASE ... SET STATE = 'ONLINE'但未确认当前保护模式和打开状态 - 脚本中硬编码
STARTUP OPEN,没适配备库角色
如何正确以只读方式打开 DG 备库
核心操作就是明确告诉 Oracle:我要只读,且允许日志应用继续跑。最稳妥的组合是 OPEN READ ONLY + RECOVER MANAGED STANDBY DATABASE DISCONNECT。
实操步骤如下:
- 确保数据库已
MOUNT(不是NOMOUNT):用STARTUP MOUNT或先SHUTDOWN IMMEDIATE再STARTUP MOUNT - 检查当前角色:
SELECT DATABASE_ROLE FROM V$DATABASE;必须返回PHYSICAL STANDBY - 以只读方式打开:
ALTER DATABASE OPEN READ ONLY; - 启动实时日志应用(可选但推荐):
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT;
READ ONLY WITH APPLY 是 12c 引入的语法糖,等价于上面两步合并,但底层仍是分开执行;11g 及更早版本不支持该短语,必须分步。
READ ONLY vs READ ONLY WITH APPLY:差别在哪 这两个模式都满足只读要求,但日志应用行为不同,直接影响数据延迟和可用性。
关键区别:
-
OPEN READ ONLY:数据库只读,但日志应用进程(MRP)默认停止 —— 即使之前在运行,open 后也会中断。此时备库数据停留在 open 时刻,不再同步新归档 -
OPEN READ ONLY WITH APPLY(12c+):一步完成只读打开 + 自动启动 MRP,持续应用日志,保持低延迟。但需注意:该模式下无法执行 DML、DDL,也不能开启闪回查询(FLASHBACK QUERY)
V$MANAGED_STANDBY 中 PROCESS 列会显示为空或只有 LNS/RFS,没有 MRP0。
容易被忽略的权限与状态检查点
ORA-16000 本身不阻断操作,但背后常隐藏配置疏漏。真正影响业务的是后续连不上、查不到新数据。
务必验证以下几点:
- 确认
LOG_ARCHIVE_DEST_n中的VALID_FOR设置是否包含(STANDBY_LOGFILE,STANDBY_ROLE),否则 RFS 进程可能收不到归档 - 检查
V$ARCHIVE_DEST_STATUS的STATUS是否为VALID,ERROR列是否为空 - 如果启用 ADG(Active Data Guard),需确保已购买对应许可,否则
OPEN READ ONLY WITH APPLY会静默失败(日志里报ORA-16004或ORA-00344) - 监听器配置中,
SERVICE_NAME应指向DB_UNIQUE_NAME对应的服务,而非主库名 —— 否则客户端可能连错实例
READ ONLY WITH APPLY 的绑定关系最容易被忽略:没许可时强行执行该命令不会报错,但 MRP 实际不工作,V$DATAGUARD_STATS 中 APPLY_LAG 持续增长,而你可能还在查 V$DATABASE.OPEN_MODE 确认“已经打开了”。











