启用active data guard必须严格按三步顺序执行:停恢复→开只读→重启实时应用;跳过任一步,备库将卡在read only或mounted状态,无法查到新数据。
能直接用,但必须按顺序做对三步:停恢复 → 开只读 → 重启实时应用。跳过任意一步,备库就卡在 read only 或 mounted 状态,查不到新数据。
备库当前状态必须是 MOUNTED 且正在应用 Redo
Active Data Guard 不是“打开就能用”的功能,它依赖物理备库已处于 Data Guard 同步流程中。常见错误是直接在 OPEN 状态下尝试启用,结果报错 ORA-16139: media recovery required 或 ORA-10458: standby database requires recovery。
确认方式:
SELECT open_mode, database_role, protection_mode FROM v$database;
正确输出应为:
OPEN_MODE DATABASE_ROLE PROTECTION_MODE -------------- ----------------- -------------------- MOUNTED PHYSICAL STANDBY MAXIMUM PERFORMANCE
- 如果
open_mode是READ ONLY,说明之前已手动开过,但没重启 Redo Apply,此时查询会滞后(甚至完全不更新) - 如果
database_role不是PHYSICAL STANDBY,可能是控制文件未正确识别为备库,需检查DB_UNIQUE_NAME和LOG_ARCHIVE_CONFIG -
PROTECTION_MODE可以是任意一种(MAXIMUM PERFORMANCE最常用),但不能是MAXIMUM PROTECTION—— 它强制主备同步写,ADG 的只读查询可能因等待超时失败
启用 ADG 的三步命令不可颠倒
顺序错或漏掉 DISCONNECT,会导致会话挂起、Redo Apply 停滞,报表看到的永远是旧数据。
- 第一步:停止当前 Redo 应用
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL; - 第二步:以只读模式打开数据库
ALTER DATABASE OPEN READ ONLY;
注意不是ALTER DATABASE OPEN;—— 缺少READ ONLY会报ORA-16004: backup database requires recovery - 第三步:重新启用实时 Redo 应用(关键!)
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT;DISCONNECT必须带上,否则会话独占前台,后续无法执行其他命令;USING CURRENT LOGFILE表示启用实时传输(Real-Time Apply),没有它,备库只能等归档日志落盘后才应用,延迟可达分钟级
执行完后验证:
SELECT open_mode, database_role FROM v$database;
期望输出:READ ONLY WITH APPLY —— 这个状态才是真正的 Active Data Guard。
只读模式下哪些操作会失败
ADG 备库不是“功能完整的库”,很多看似只读的操作实际隐含写行为,会在执行时报错。
-
SELECT本身安全,但带ORDER BY/GROUP BY/WITH的复杂查询也允许(只要不碰本地对象) -
SELECT seq.NEXTVAL FROM DUAL会失败 —— 序列值生成需更新数据字典,备库只读禁止任何 DML -
CREATE GLOBAL TEMPORARY TABLE允许,但INSERT INTO tmp_table报ORA-16000: database open for read-only access -
SELECT * FROM dba_tables可以,但SELECT * FROM v$session返回的是备库自身会话信息,不是主库的 - 通过 DBLINK 写主库(如
INSERT INTO remote_table@primary_db VALUES(...))允许,但反向从主库连备库写会失败(备库不接受入向修改)
延迟监控和常见卡点
报表业务最怕“查到的数据不是最新的”。ADG 延迟不是网络抖动那么简单,得盯两个视图:
- 看实时延迟:
SELECT VALUE FROM V$DATAGUARD_STATS WHERE NAME = 'apply lag';
单位是秒,超过 30 秒就要排查 - 看历史延迟分布:
SELECT * FROM V$STANDBY_EVENT_HISTOGRAM WHERE NAME = 'apply lag' AND COUNT > 0; - 典型卡点:
– 备库 CPU 满载(top -H查ora_mrp0_*进程)
– 主库未配置 Standby Redo Log(V$STANDBY_LOG为空),导致无法 Real-Time Apply
–COMPATIBLE参数低于11.0.0(查SELECT VALUE FROM V$PARAMETER WHERE NAME = 'compatible';)
真正麻烦的是 RAC 环境:如果负责应用 Redo 的实例宕了,其余只读实例会被 Oracle 自动置为 MOUNTED,必须人工切到另一个实例上执行第三步命令 —— 这个切换动作不会自动发生,也没告警,报表服务会静默中断。











