Oracle Data Guard日志应用延迟如何排查?

作者:袖梨 2026-08-17

备库未启用Active Data Guard导致查询不同步,根本原因是处于READ ONLY而非READ ONLY WITH APPLY模式,MRP0进程未运行、SCN停滞;必须执行ALTER DATABASE OPEN READ ONLY并验证v$database中database_role为PHYSICAL STANDBY、open_mode为READ ONLY WITH APPLY,同时确认v$managed_standby中MRP0状态为APPLYING_LOG且存在standby redo log,启用real-time apply(ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT),并通过主备库同步SCN差值计算真实延迟,业务层应使用AS OF SCN精确查询一致性快照。

备库没开 Active Data Guard,查询根本不同步

备库处于 READ ONLY 模式(不是 READ ONLY WITH APPLY),说明 ADG 没启用。此时 MRP0 进程不会运行,日志不应用,SCN 完全停滞——所有“查不到新数据”问题都源于此。

必须执行:ALTER DATABASE OPEN READ ONLY;,然后立刻验证:SELECT database_role, open_mode FROM v$database; 返回 PHYSICAL STANDBYREAD ONLY WITH APPLY 才算成功。

常见错误:

  1. 只执行了 OPEN READ ONLY,但没确认 v$managed_standby 中是否存在 MRP0 进程且状态为 APPLYING_LOG
  2. 误以为 v$dataguard_stats.apply_lag 是实时值,其实它依赖 TIME_COMPUTED 时间戳;若该字段是 10 分钟前的值,apply_lag=0 也毫无意义
  3. RAC 环境下只在一个实例上执行命令,其他实例仍卡在 READ ONLY

MRP0 卡在 WAIT_FOR_LOG,说明没启用 real-time apply

MRP0 状态为 WAIT_FOR_LOG,不是传输失败,而是它在等主库把当前联机日志归档后才开始应用——这是默认行为。要让它实时拉取并应用 current logfile,必须配好 standby redo log(SRL)并启用 real-time apply。

检查步骤:

  1. v$standby_log:确保至少有 3 组 SRL,且 STATUS 不是 UNASSIGNED;若为 UNASSIGNED,需重启 MRP 或重建 SRL
  2. 确认主库 LOG_ARCHIVE_DEST_nLGWR SYNCLGWR ASYNC,不能只用 ARCH 模式
  3. 执行:ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT; —— 此命令会强制启用 real-time apply,但前提是 SRL 已就位

注意:DELAY= 参数在此模式下会被忽略,alert log 里会出现 “DELAY … ignored” 提示。

真实延迟得看 SCN,别信 v$dataguard_stats 的估算值

v$dataguard_stats.apply_lag 是基于统计模型的估算,误差可能达数分钟。真正决定“查不查得到”的,是备库当前已应用的 SCN 是否 ≥ 主库提交时的 SCN。

实操方法:

  1. 主库执行:SELECT DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER FROM DUAL; 记下结果(如 123456789)
  2. **立刻** 在备库执行同样语句(间隔控制在 1 秒内)
  3. 差值 ÷ 每秒 SCN 增速 ≈ 真实延迟秒数;SCN 增速可查:SELECT VALUE FROM V$DATAGUARD_STATS WHERE NAME = 'estimated startup time';(通常 1~5 万/秒)

关键约束:

  1. 备库执行 DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER 需要有 FLASHBACK ANY TABLE 权限
  2. 若备库 SCN 长期不动,直接查 v$managed_standbyMRP0PROCESSSTATUS 列,大概率是卡住或未启动

业务端需要“看到某时刻主库状态”,不能等自动同步

当主库刚提交一笔交易并返回 SCN,而备库应用还没跟上时,应用层不能被动等待,应主动用 AS OF SCN 查询。

例如主库返回 SCN=123456789,备库尚未应用到该点,但业务需要读取该 SCN 对应的一致性快照:

SELECT * FROM orders AS OF SCN 123456789 WHERE order_id = 1001;

这绕过了备库当前同步进度,直接从已应用的日志中构造一致性视图。

容易被忽略的点:

  1. AS OF SCN 查询要求备库已应用到该 SCN 或更高值;若 SCN 过新(比如 123456790),会报错 ORA-01466
  2. 该语法在备库上有效,但必须确保 undo_retention 足够长,否则旧 SCN 对应的 undo 数据已被覆盖
  3. 不要在应用层做“轮询等待 SCN 达到”,而是由主库在 commit 后显式返回 SCN,供下游直接使用

相关文章

精彩推荐