ADG备库查询慢主因是I/O、日志应用或SCN同步瓶颈,非SQL本身问题;需优先查gv$session非空闲等待事件、v$managed_standby中MRP0状态及SCN差值估算真实延迟。

ADG备库查询慢,八成不是SQL本身的问题,而是被卡在I/O、日志应用或SCN同步环节。直接看执行计划往往白费功夫——得先盯住等待事件。
查备库当前会话的非空闲等待事件
备库上慢查询的真实瓶颈,藏在gv$session的wait_class里。别只看单条SQL的执行时间,先确认它到底在等什么:
SELECT inst_id, sql_id, event, state, seconds_in_wait FROM gv$session WHERE wait_class 'Idle' AND status = 'ACTIVE' ORDER BY seconds_in_wait DESC;- 重点过滤
log file sync(主库提交卡点)、gc cr request(RAC跨节点读一致性请求)、db file sequential/scattered read(物理读慢)这几类 - 如果大量会话卡在
standby query scn wait或read by other session,说明SCN没跟上,不是SQL问题,是MRP进程拖了后腿
确认MRP0进程是否真正在应用日志
备库开成READ ONLY WITH APPLY不等于MRP就在干活。很多“慢”源于日志压根没应用,查询只能卡在当前SCN位置不动:
- 查
v$managed_standby:必须看到PROCESS = 'MRP0'且STATUS = 'APPLYING_LOG',SEQUENCE#持续递增 - 如果
STATUS是WAIT_FOR_LOG或IDLE,检查transport lag和apply lag是否为+00 00:00:00——不是零,就说明归档没传过来或MRP挂了 - 特别注意RAC环境:MRP只在一个实例上运行,其他节点查
v$managed_standby看不到MRP0,别误判
用SCN差值代替V$DATAGUARD_STATS估算延迟
V$DATAGUARD_STATS里的apply lag是Oracle自己估的,不准。真实延迟得靠SCN比对:
- 主库执行:
SELECT DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER FROM DUAL; - 立刻(1秒内)在备库执行同样语句
- 两SCN差值 ÷ 每秒SCN增速(查
SELECT VALUE FROM V$DATAGUARD_STATS WHERE NAME = 'estimated startup time'反推,通常1~5万/秒)≈ 真实延迟秒数 - 如果备库SCN长时间不涨,
v$managed_standby里MRP0的PROCESS列可能显示UNKNOWN或DEAD,这时要查alert.log里是否有ORA-16047、ORA-16191等错误
排查三个高频等待事件组合
ADG备库慢,80%以上由以下三类等待叠加导致,比调SQL优先级更高:
-
log file parallel write:备库写standby redo太慢,检查存储I/O吞吐、ASM磁盘组争用、DB_CREATE_FILE_DEST所在磁盘是否满 -
enq: TX - row lock contention:开了Active Data Guard但应用还在备库做DML(比如忘了设READ ONLY),或有未提交事务残留 -
DFS lock handle:RAC环境下节点间资源协调卡住,常见于参数_gc_policy_time过小或cluster_interconnects配置异常
真正卡点往往不在SQL文本里,而在MRP是否活着、SCN是否动、I/O是否堵——这些不确认清楚,优化器统计信息重收集、加索引、改hint全白搭。


















