备库执行ALTER DATABASE OPEN READ ONLY失败的典型原因是MRP未达APPLYING_LOG状态、归档未同步(SEQUENCE#差值>1)或未启用ADG许可;必须确保OPEN_MODE=MOUNTED、MRP0状态为APPLYING_LOG且已购买并启用Active Data Guard。

备库执行 ALTER DATABASE OPEN READ ONLY 失败的典型原因
这不是配置完 DG 就能直接打开的问题。常见报错是 ORA-16004: backup database requires recovery 或 ORA-01153: an incompatible media recovery is active,本质是备库还没准备好——MRP 进程还在跑,但数据库状态没达到“可安全只读”的临界点。
关键判断依据不是“有没有配 DG”,而是:V$DATABASE.OPEN_MODE 必须是 MOUNTED(不能是 READ ONLY 或 READ WRITE),且 V$MANAGED_STANDBY.PROCESS = 'MRP0' 的 STATUS 为 APPLYING_LOG,同时归档日志应用无积压。
- 先查同步进度:
SELECT MAX(SEQUENCE#) FROM V$ARCHIVED_LOG WHERE APPLIED='YES'和主库SELECT MAX(SEQUENCE#) FROM V$LOG_HISTORY对比,差值 ≤ 1 才算基本同步完成 - 再确认 MRP 状态:
SELECT PROCESS, STATUS, SEQUENCE# FROM V$MANAGED_STANDBY WHERE PROCESS = 'MRP0',必须返回APPLYING_LOG - 只有这时执行
ALTER DATABASE OPEN READ ONLY才会成功;否则说明 ADG 许可未启用或实时应用没开
没买 ADG 许可,READ ONLY WITH APPLY 就不可能生效
很多人以为配好 DG、启动 MRP 就能“边同步边只读”,结果发现 V$DATABASE.OPEN_MODE 始终卡在 MOUNTED,或者一执行 ALTER DATABASE OPEN READ ONLY 就报错。根本原因是:Active Data Guard 是单独许可项,不是 DG 自带功能。
ADG 的作用是让物理备库在 APPLYING_LOG 状态下保持 OPEN,即 READ ONLY WITH APPLY。没这个许可,MRP 一启动,数据库就自动切回 MOUNTED;你手动 OPEN READ ONLY,MRP 就会被强制停掉,同步中断。
- 检查是否启用 ADG:
SELECT DATABASE_ROLE, OPEN_MODE, PROTECTION_MODE FROM V$DATABASE,返回PHYSICAL STANDBY+READ ONLY WITH APPLY才是真 ADG - 如果返回
MOUNTED,即使 MRP 在跑,也说明 ADG 没激活——得确认许可证已安装并启用 - Oracle 不会主动提示“缺 ADG 许可”,只会让你卡在各种
ORA-错误里
tnsnames.ora 指向备库却连回主库?服务名没隔离
客户端配置了备库 IP 和端口,但 SELECT * FROM V$INSTANCE 一查发现连的是主库实例。这不是网络通不通的问题,而是 SERVICE_NAME 冲突——主备库默认都注册了同名服务(比如 orcl),TNS 解析时负载仍打到主库监听器上。
必须给备库单独注册一个只读服务名,并确保监听器识别它。否则所有发往 SERVICE_NAME=orcl 的连接,Oracle 都按主库优先路由。
- 在备库执行:
ALTER SYSTEM SET SERVICE_NAMES='orcl_ro' SCOPE=BOTH - 重启监听器或执行
lsnrctl reload,然后lsnrctl services确认输出里有orcl_ro且状态为READY - 客户端
tnsnames.ora新增独立条目,CONNECT_DATA中SERVICE_NAME必须填orcl_ro,不能复用主库的服务名
分布式查询前漏掉 ALTER DATABASE SET TRANSACTION READ ONLY
在备库上跑跨库关联查询(比如 SELECT * FROM t1@dblink JOIN t2)时,即使备库已是 READ ONLY WITH APPLY,也会报 ORA-01031: insufficient privileges 或直接 hang 住。这不是权限问题,而是 Oracle 要求显式声明事务隔离级别。
只读备库对分布式事务支持有限,必须提前设置当前会话为只读事务模式,否则底层无法协调跨库一致性校验。
- 连接备库后,第一件事不是查表,而是执行:
ALTER DATABASE SET TRANSACTION READ ONLY - 该语句只对当前会话生效,每次新连接都要重设
- 不设这句,哪怕单表查询正常,只要涉及 DB Link 或全局事务上下文,就会失败
ADG 的核心门槛不在技术配置,而在许可和细节意识:MRP 进程状态、服务名隔离、只读事务声明——三者缺一不可。最容易被忽略的是服务名复用,因为错误现象看起来像网络问题,实际根源在监听器注册层面。


















