ORA-16037实为MRP被人工CANCEL后残留状态干扰RFS初始化,与RFS崩溃无关;需先查V$MANAGED_STANDBY确认MRP状态,再执行ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT重启MRP。

ORA-16037 不是 RFS 崩溃,而是 MRP 被人工中断后残留状态干扰了 RFS 初始化
ORA-16037 错误的真实来源
这个错误信息 ORA-16037: user requested cancel of managed recovery operation 看似指向 RFS 进程异常,实则和 RFS 无关。它本质是 MRP(Media Recovery Process)被手动执行过 ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL; 后留下的“未清理痕迹”。RFS 在后续尝试初始化或重连时,读到控制文件中残留的“MRP 已取消”标记,就直接报这个错并退出。
常见诱因包括:
- 运维人员为排查问题临时停掉 MRP,但忘记再启,或脚本执行后未清理状态
- DG Broker 操作失败(如
switchover卡住)触发自动 cancel,但后续未手工恢复 - 监控脚本定期检查同步状态时,误用
CANCEL而非只查不改
为什么 RFS 会反复报这个错而不是自动恢复
RFS 是接收进程,本身不维护恢复状态;它依赖控制文件里 MRP 的角色和状态字段来决定是否可写入 standby redo log。一旦控制文件中 recovery_status 或相关位图被设为 “canceled”,RFS 就拒绝继续服务——这不是 bug,是 Oracle 的安全设计:防止在恢复中断状态下误收日志造成数据不一致。
关键点:
- 重启数据库或 kill -9 RFS 进程无效:新 RFS 启动后仍读取同一份控制文件
- 不能靠等待自动恢复:控制文件状态不会自行回滚
- 必须显式重置 MRP 状态,而非只重启进程
如何确认并清除这个干扰状态
先在备库查当前恢复状态:
SELECT process, status, thread#, sequence#, client_process FROM v$managed_standby WHERE process = 'MRP0';
若返回空或 status 为 NOT APPLYING,基本可确认 MRP 处于 canceled 态。接着执行:
- 确保归档已传全:查
v$archived_log中最大next_change#是否等于v$log_history最新值 - 强制重启 MRP:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION; - 观察 alert 日志是否出现 “Media Recovery Start” 和后续应用日志记录
- 5 分钟后再次查
v$managed_standby,确认 MRP0status变为APPLYING_LOG
如果执行 USING CURRENT LOGFILE 报错(如 ORA-16025),说明控制文件里还残留旧的 standby redo log 组引用,需先 ALTER DATABASE DROP STANDBY LOGFILE GROUP X; 清理无效组,再重建。
容易被忽略的细节
这个错误常和 ORA-16778(redo transport error)一起出现,但二者因果关系容易颠倒:不是传输失败导致 MRP 中断,而是 MRP 被 cancel 后,RFS 拒绝接收新日志,才让主库 ARCH 认为“投递失败”。所以排查顺序必须是:先看备库 MRP 状态 → 再看 RFS 是否在运行 → 最后才查主库归档链路。任何跳过状态确认、直接清归档或重启实例的操作,都是在掩盖症状而非解决问题。


















