真正反映应用延迟的是V$LOGSTDBY_STATS中name='apply lag'行的value值,单位为秒,表示已提交但未应用的redo时间差;需结合V$LOGSTDBY_PROGRESS和V$DATABASE.current_scn交叉验证。
查 V$LOGSTDBY_STATS 里哪个字段真正反映应用延迟
很多人一上来就扫 v$logstdby_stats 全表,盯着 value 列看数字大小,结果误判。真正代表“当前应用队列积压时长”的是 value 字段中 name = 'apply lag' 这一行的值——它单位是秒,且是实时估算的已提交但未应用的 redo 时间差。
容易踩的坑:
-
name = 'time computed'是该统计值的计算时间戳,不是延迟本身 -
name = 'transaction count'或'applied scn'看起来相关,但不能直接换算成秒级延迟 - 如果数据库刚启库或逻辑备库暂停过,
apply lag可能为0或NULL,不代表没延迟,得结合V$LOGSTDBY_PROGRESS的applied_scn和主库V$DATABASE.current_scn手动比对
用 DBMS_LOGSTDBY.SPACE_TRANSACTION 定位卡住的事务
当 apply lag 持续上涨,说明有事务在备库卡住了。这时候光看统计没用,得进事务内部查原因。Oracle 提供了 DBMS_LOGSTDBY.SPACE_TRANSACTION 过程,可强制让逻辑备库把当前阻塞应用的事务信息写进 alert 日志。
实操建议:
- 先确认逻辑备库状态:查
V$LOGSTDBY.STATE必须是APPLYING,否则调不生效 - 执行:
EXEC DBMS_LOGSTDBY.SPACE_TRANSACTION;
不要加参数,加了反而可能报ORA-31672 - 立刻去备库 alert 日志搜
Transaction ID和SQL Text,通常会看到类似INSERT /*+ APPEND */或带LOB操作的语句——这类语句在逻辑备库上默认被跳过或需额外配置才能应用
V$LOGSTDBY_PROGRESS 和 V$LOGSTDBY 要交叉验证
V$LOGSTDBY_STATS 给的是延迟估算,但不够细;V$LOGSTDBY_PROGRESS 显示 SCN 进度,V$LOGSTDBY 显示当前线程和状态,三者必须对照着看,否则容易漏掉“假同步”。
关键点:
-
V$LOGSTDBY_PROGRESS.applied_scn和主库V$DATABASE.current_scn差值超过 10 万,基本确认存在实质性延迟(即使apply lag显示 0) -
V$LOGSTDBY.EVENT列如果长期是waiting for log,说明归档还没传过来,问题不在应用层而在传输层 -
V$LOGSTDBY.SKIP_TRANSACTION非空,说明有事务被显式跳过,这些事务不会计入apply lag,但会导致数据不一致——得查DBA_LOGSTDBY_SKIP确认是否合理
监控脚本里别只取快照,要算变化率
单纯每 5 分钟查一次 V$LOGSTDBY_STATS 的 apply lag 值,看不出趋势。比如从 120 秒涨到 180 秒,表面只多 1 分钟,但如果这 60 秒里 applied_scn 几乎没动,说明应用已近乎停滞。
推荐做法:
- 每次采集至少记录三样:
apply lag值、V$LOGSTDBY_PROGRESS.applied_scn、采集时间戳 - 连续两次采集间,若
apply lag↑ 且applied_scnΔ - 避免用
DBMS_SCHEDULER直接跑 PL/SQL 查询——逻辑备库高负载时,调度任务自身可能被阻塞,改用外部 shell +sqlplus -S更稳
延迟分析最麻烦的地方不在查哪张视图,而在于 Oracle 对“应用完成”的定义本身是松散的:SCN 推进、事务提交、日志应用、索引更新……这些动作未必原子发生。所以任何单点指标都只是线索,不是结论。










