<p>OEM默认不监控ORA-16XXX类Data Guard错误,因其“Critical Alert for Data Guard Errors”规则未包含ORA-16%模式,且该类错误不写入ADR而直写V$DATAGUARD_STATUS,必须通过自定义SQL查询指标(SELECT MESSAGE FROM V$DATAGUARD_STATUS WHERE TIMESTAMP > SYSDATE - 1/1440 AND DEST_ID IS NOT NULL AND UPPER(MESSAGE) LIKE '%ORA-16%')并配合指纹去重与静默期机制实现有效告警。</p>
oem 默认不监控 ora-16xxx 类 data guard 错误,必须手动配置 sql 查询类指标,否则告警形同虚设。
为什么 OEM 的“Critical Alert for Data Guard Errors”规则没用
OEM 自带的该规则默认只匹配 ORA-00600、ORA-07445 等核心内核错误,**完全不包含 ORA-16% 模式**。Data Guard 传输/应用层报错(如 ORA-16057、ORA-16191)根本不会触发——它压根没被纳入匹配范围。
更关键的是:DBA_OUTSTANDING_ALERTS 视图对这类错误“视而不见”,因为 ORA-16XXX 不走 ADR 告警通道,而是直接写入 V$DATAGUARD_STATUS。依赖 OEM 默认逻辑等于放弃实时感知。
必须用 V$DATAGUARD_STATUS 写自定义 SQL 指标
在 OEM 中添加指标的路径是:Setup → Monitoring → Metric and Policy Settings → Add Metric,类型选 SQL Query。
查询语句必须满足三个硬性条件:
SELECT MESSAGE FROM V$DATAGUARD_STATUS WHERE TIMESTAMP > SYSDATE - 1/1440 AND DEST_ID IS NOT NULL AND UPPER(MESSAGE) LIKE '%ORA-16%'- 不能用
TO_DATE或TRUNC(TIMESTAMP),否则V$DATAGUARD_STATUS上的隐式索引失效,全表扫描拖慢响应 - 必须加
DEST_ID IS NOT NULL过滤主库本地日志条目——主库视图里也会混入少量无意义的 ORA-16XXX 记录
验证命令可直接粘贴进终端:
sqlplus -s / as sysdba <<EOF SELECT MESSAGE FROM V$DATAGUARD_STATUS WHERE TIMESTAMP > SYSDATE - 1/1440 AND DEST_ID IS NOT NULL AND UPPER(MESSAGE) LIKE '%ORA-16%'; EOF
脚本告警必须做防抖,否则运维会被短信刷爆
同一网络抖动可能让 V$DATAGUARD_STATUS 在 60 秒内刷出 20+ 条重复 ORA-16191,不做控制就是告警海啸。
上线前至少补上三道防抖:
- 用
/tmp/dg_ora16_alert.lock文件锁 +stat -c '%Y'判断是否超时(>300 秒),防并发执行 - 对
MESSAGE字段做指纹化:用echo "$msg" | md5sum | cut -d' ' -f1生成唯一哈希,只对新指纹发告警 - 设置静默期:首次告警后写入
/tmp/dg_ora16_last_alert时间戳,后续 900 秒(15 分钟)内相同指纹直接跳过
图形界面看着省事,但 OEM 对 Data Guard 的监控本质是“半残废状态”——所有关键告警都得靠自己填 SQL、设防抖、盯锁文件。漏掉任意一环,容灾环境就变成“看起来正常,其实早已断连”的黑盒。


















