ora-16000不是故障,而是物理备库以只读模式正常打开的状态提示;需确认mrp进程是否处于applying_log状态、主库是否启用force logging及archivelog,且应使用open read only with apply启动adg,而非在备库执行写操作或修改只读设置。
ora-16000不是故障,是物理备库正常状态的明确提示
看到 ora-16000: database open for read-only access 不用重启、不用改参数、更不要执行 alter database open read write——这说明你的物理备库已按设计正确打开为只读模式。它不是同步失败的信号,而是 active data guard 正常运行的前提。真正要确认的,是日志是否在实时应用,而不是“能不能写”。
检查MRP进程是否真正在 APPLY_LOG,而非仅接收日志
很多团队误以为 RFS 进程 RUNNING 就代表同步正常,但 RFS 只负责接收归档日志,不负责应用。必须验证 MRP0 是否处于活跃应用状态:
- 执行
SELECT PROCESS, STATUS, THREAD#, SEQUENCE#, BLOCK# FROM V$MANAGED_STANDBY WHERE PROCESS = 'MRP0'; - 期望结果:STATUS 为
APPLYING_LOG,且SEQUENCE#持续递增(不是卡在某个值) - 若返回空行或 STATUS 是
WAIT_FOR_LOG,说明 MRP 未启动;常见原因包括:备库仍处于MOUNT状态、主库未启用FORCE LOGGING、或存在未解决的归档 GAP(可用SELECT * FROM V$ARCHIVE_GAP;检查)
OPEN READ ONLY WITH APPLY 才是 ADG 启动的正确姿势
Oracle 19c/12c+ 支持两种只读打开方式,选错会导致“开了库却没同步”:
-
ALTER DATABASE OPEN READ ONLY:仅打开只读实例,MRP 默认不自动启动,需额外手动执行RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT; -
ALTER DATABASE OPEN READ ONLY WITH APPLY:一步到位,等价于上述两步合并,会立即启动 MRP 并保持实时日志应用——这才是 ADG 的标准启用方式 - 注意:即使执行了
OPEN READ ONLY WITH APPLY,MRP 仍不 RUNNING,大概率是归档中断或存在 GAP,不能归因于打开方式本身
ORA-04045 + ORA-16000 组合报错,本质是视图/同义词失效触发了只读限制
这类组合错误(如 ORA-04045 在重新编译 V_PAYMENT_NCC 时出错,附带 ORA-16000)不是同步问题,而是查询触发了隐式对象验证——而只读库禁止更新数据字典表(如 SYS.SYNSET 或 DEPENDENCY$)。
- 根本解法:在主库上修复对象,而非在备库操作
- 批量编译失效视图:
SELECT 'ALTER VIEW ' || OWNER || '.' || OBJECT_NAME || ' COMPILE;' FROM DBA_OBJECTS WHERE OBJECT_TYPE = 'VIEW' AND STATUS = 'INVALID'; - 或直接调用:
EXEC DBMS_UTILITY.COMPILE_SCHEMA('SCHEMA_NAME'); - 特别注意:含多个 DBLINK 的视图或 SQL,在只读库中执行前必须显式设置事务为只读:
SET TRANSACTION READ ONLY;,否则第二次 DBLINK 调用就会触发ORA-16000
最易被忽略的一点:ORA-16000 出现时,第一反应不该是“怎么让它变可写”,而是“谁在试图写”——是应用连错了库?脚本误跑在备库?还是视图定义依赖了已失效的对象?定位到具体触发语句,比盲目调整数据库状态有效得多。











