本质是MRP进程消费能力低于LGWR/RFS生产速率,需先区分传输慢还是应用慢:RFS为IDLE但transport lag>0说明日志已传完,问题在备库应用侧;MRP0为WAIT_FOR_LOG说明未启用real-time apply;APPLYING_LOG卡住则查I/O、SQL层及并行度。

备库日志应用速度跟不上主库生成速度,本质是MRP进程的消费能力低于LGWR/RFS的生产速率——这不是配置“没开对”,而是I/O、SQL回放、并行度或资源争用等多层瓶颈叠加的结果。
查清到底是传输慢还是应用慢
先别急着调参数。V$DATAGUARD_STATS里的transport lag和apply lag可能失真,得看底层进程状态:
-
RFS状态为IDLE但transport lag > 0→ 日志已传完,问题在备库应用侧 -
MRP0状态为WAIT_FOR_LOG→ 不是没日志,是没启用实时应用(real-time apply),它在等当前联机日志归档后才开始处理 -
MRP0状态为APPLYING_LOG但SEQUENCE#长期卡住不动 → 真正的应用瓶颈,重点查I/O和SQL层
执行:SELECT process, status, sequence#, thread# FROM V$MANAGED_STANDBY;,只盯MRP0和RFS两行。
禁用STANDBY_FILE_MANAGEMENT=AUTO(除非真需要)
这个参数默认开启时,每次日志应用都要触发字典查询+文件存在性检查,尤其在频繁建表/分区场景下,会把MRP拖成单线程爬行。
- 查当前值:
SHOW PARAMETER STANDBY_FILE_MANAGEMENT - 临时关闭:
ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=MANUAL SCOPE=BOTH; - 注意:关掉后若主库新增数据文件,需手动在备库创建,但绝大多数OLTP场景根本不需要自动管理
关掉后观察V$MANAGED_STANDBY中APPLYING_LOG的SEQUENCE#推进速度,常有2–5倍提升。
确认并启用Real-Time Apply(必须配SRL)
不启用real-time apply,MRP只能等归档日志落盘后再读取,白白增加几百毫秒到数秒延迟,尤其在小日志文件+高切换频率下更明显。
- 检查是否有standby redo log:
SELECT GROUP#, THREAD#, SEQUENCE#, STATUS FROM V$STANDBY_LOG;,状态不能是UNASSIGNED - 若无SRL,先加(组数 ≥ 主库online redo log组数+1,大小 ≥ 主库最大redo log):
ALTER DATABASE ADD STANDBY LOGFILE GROUP 4 ('+DATA') SIZE 2G; - 启用实时应用:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT;
执行后V$MANAGED_STANDBY里MRP0的STATUS应变为APPLYING_LOG且SEQUENCE#持续增长,不再停在WAIT_FOR_LOG。
并行应用不是越多越好,但默认单线程肯定不够
Oracle 12c+支持并行恢复,但默认仍是单MRP进程串行回放。遇到批量DML、索引重建或大事务,很容易积压。
- 查当前并行度:
SHOW PARAMETER parallel_max_servers(它限制了MRP能拉起的最大应用线程数) - 稳妥起步值:
ALTER SYSTEM SET parallel_max_servers=8 SCOPE=BOTH;(从4或8开始,勿超CPU核心数) - 避免隐含参数:
_maximum_parallel_apply_servers慎用,容易引发latch争用 - 验证效果:查
V$LOGSTDBY_PROCESS,看TYPE=COORDINATOR和APPLIER的数量是否匹配设定
真正卡顿往往不在并行度,而在单个APPLIER线程被大事务阻塞——所以同步期间要避免主库执行超长事务,这是比调参更有效的手段。
最易被忽略的一点:备库DB_RECOVERY_FILE_DEST和DB_CREATE_FILE_DEST如果落在NFS、低IOPS云盘或共享存储上,MRP的归档读取+重做应用会直接退化为磁盘IO瓶颈。必须确保这两路径指向本地高性能SSD,且SPACE_USED / SPACE_LIMIT 。











