检查备库同步延迟最简SQL是SELECT NAME,VALUE,UNIT FROM v$dataguard_stats WHERE NAME IN('apply_lag','transport_lag');再查SELECT STATUS,GAP_STATUS,ERROR FROM v$archive_dest_status WHERE DEST_ID=2。

检查备库同步延迟的最简SQL语句
直接查 v$archive_dest_status 和 v$dataguard_stats 是最快的方式,但要注意字段含义容易混淆:APPLY_LAG 是应用延迟(单位秒),TRANSPORT_LAG 是传输延迟,而 VALUE 列在不同视图中类型不一致。生产环境建议统一用以下组合判断:
SELECT NAME, VALUE, UNIT FROM v$dataguard_stats WHERE NAME IN ('apply_lag','transport_lag');-
SELECT STATUS, GAP_STATUS, ERROR FROM v$archive_dest_status WHERE DEST_ID = 2;(假设备库是DEST_ID=2) - 若
GAP_STATUS返回RESOLVING或ERROR,说明归档传输已中断,不能只看APPLY_LAG数值
用shell脚本封装健康检查并触发告警
单纯查SQL不够,必须结合退出码和日志上下文。下面这个脚本片段能避免“假阴性”:
sqlplus -s / as sysdba << 'EOF' SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF SPOOL /tmp/dg_check.log SELECT CASE WHEN (SELECT VALUE FROM v$dataguard_stats WHERE NAME='apply_lag') > 300 THEN 'CRITICAL' ELSE 'OK' END FROM DUAL; SELECT CASE WHEN STATUS != 'VALID' OR GAP_STATUS != 'RESOLVED' THEN 'GAP_ERROR' ELSE 'NO_GAP' END FROM v$archive_dest_status WHERE DEST_ID = 2; SPOOL OFF EXIT EOF <p>if grep -q "CRITICAL|GAP_ERROR" /tmp/dg_check.log; then echo "$(date): DG delay > 5min or gap detected" | mail -s "ORA-DG ALERT" dba@company.com fi
- 注意使用
SET ... OFF关闭所有格式化输出,否则grep会匹配到空行或分隔符 -
sqlplus -s的-s参数必须加,否则输出含连接提示,干扰解析 - 不要依赖
sqlplus的返回值:即使SQL报错,只要进程没崩溃,返回码仍是0
crontab定时执行时的权限与环境陷阱
很多脚本在手动运行时正常,加入 crontab 后失效,根本原因是环境变量缺失。Oracle用户下的定时任务必须显式加载:
- 在脚本开头强制 source
$ORACLE_HOME/bin/oraenv,或至少设置export ORACLE_SID=your_primary、export ORACLE_HOME=/u01/app/oracle/product/19c/dbhome_1 -
crontab -e中不要写成0 */2 * * * ./check_dg.sh,而要写成0 */2 * * * /bin/bash -l -c '/home/oracle/scripts/check_dg.sh',其中-l表示登录shell,能读取~/.bash_profile - 避免在脚本里用
tnsping或lsnrctl:这些命令依赖$TNS_ADMIN,cron默认不加载网络配置
为什么不能只依赖 DBA_LOGSTDBY_PROGRESS
这个视图只对逻辑备库有效,物理备库查它永远返回空。19c环境下,物理备库占绝对主流,但很多人复制网上脚本时不加区分。正确做法是先确认备库类型:
SELECT DATABASE_ROLE, PROTECTION_MODE, OPEN_MODE FROM v$database;
- 返回
PHYSICAL STANDBY时,必须用v$managed_standby查当前接收/应用的序列号:SELECT PROCESS, STATUS, SEQUENCE#, BLOCK# FROM v$managed_standby WHERE PROCESS IN ('RFS','MRP0'); - 若
MRP0.STATUS是APPLYING_LOG但SEQUENCE#长时间不增长,说明应用卡住,此时v$dataguard_stats.APPLY_LAG可能仍显示0——这是最危险的静默故障
实际部署中,最常被忽略的是备库监听状态和归档目录空间。哪怕SQL检查全绿,如果备库的 DB_RECOVERY_FILE_DEST 满了,ARCHIVE_LAG_TARGET 会自动停传归档,且不会在 v$dataguard_stats 中体现。这类问题必须配合 df -h 和 lsnrctl status 做交叉验证。


















