最可靠监控方式是查备库v$dataguard_stats视图,因其官方保证始终可查、不依赖时间函数或db link;需用extract转换transport lag和apply lag为秒,并加where条件过滤,空结果说明mrp未运行或dg异常。
能监控,但必须绕开 scn_to_timestamp 在备库不可用的硬伤,且不能依赖主库直连备库的 db link(容易失效)。
为什么直接查 v$dataguard_stats 最可靠
这是 Oracle 官方唯一保证在物理备库上始终可查、无需额外配置的视图。它不依赖时间函数或跨库连接,只读本地 SGA 数据,稳定性高。v$dataguard_stats 中的 'transport lag' 和 'apply lag' 字段是真实延迟值,单位为 interval,需转换成秒才能做阈值判断。
- 脚本中必须用
EXTRACT(DAY FROM ...)*86400 + EXTRACT(HOUR FROM ...)*3600 + ...手动转秒,不能靠TO_NUMBER或字符串截取——interval 格式可能带负号或微秒,截取易错 - 查询必须加
WHERE NAME IN ('transport lag','apply lag'),否则会返回一堆无关统计项(如estimated startup time),干扰解析 - 如果查不到数据(空结果集),说明 MRP 进程没运行,或 DG 配置异常,脚本应立即报错退出,而不是默认填 0
如何避免脚本在备库上执行失败
Oracle 11g 备库默认只允许 SELECT,很多 DBA 习惯用 / as sysdba 登录,但在只读备库上会报 ORA-01031: insufficient privileges。必须显式指定账户和密码,且该账户需有 SELECT_CATALOG_ROLE。
- 不要用
sqlplus -S "/ as sysdba",改用sqlplus -S username/password@tns_alias - tns_alias 必须指向本地监听(不是主库),且
tnsnames.ora中对应条目要含UR=A(允许只读连接) - 脚本开头加
set heading off pagesize 0 feedback off verify off,否则输出含列头、分页符,后续awk解析会错位 - 别把 SQL 写进
heredoc后直接重定向到文件——spool在只读备库上可能被禁用;改用sqlplus ... 管道处理
报警阈值怎么设才不误报
延迟秒数不是越小越好。网络抖动、I/O 短暂阻塞都会导致 apply lag 瞬间跳到 3–5 秒。盲目设 2 秒告警,每天会收到几十封邮件。
- 建议按场景分级:
v_delay_time_warning=300(5 分钟)用于日常告警,v_delay_time_critical=1800(30 分钟)触发紧急响应 - 必须连续 3 次检测超阈值才发邮件,避免单次瞬时延迟误报;可用
tail -n 3 delay_history.log | awk '{sum+=$1} END{print sum/3}'算滑动均值 - 检查前先确认 MRP 是否存活:
ps -ef | grep mrp | grep -v grep,如果进程不存在,延迟必然无限大,此时应优先重启恢复,而非发延迟告警
真正麻烦的不是写脚本,而是备库上 v$dataguard_stats 的 TIME_COMPUTED 字段更新不及时——它依赖 MRP 心跳,默认每 5 分钟刷新一次。如果你在延迟刚发生时立刻跑脚本,可能拿到的是 4 分钟前的旧值。这点必须写进监控 SOP,不能只靠单次快照判断。











