手动修复 ORA-16037 导致 Oracle 12c DG 同步无法识别

作者:技术拾光时间:2026-07-20 08:38:14浏览:650

ORA-16037并非故障,仅为备库取消恢复操作的标准回执,但可能掩盖归档断点或MRP挂起。修复需检查V$ARCHIVE_DEST_STATUS状态、V$MANAGED_STANDBY中MRP0进程状态及归档连续性,确保备库处于MOUNT状态、SRL组数足够,并执行带USINGCURRENTLOGFILEDISCONNECT的恢复命令。

ORA-16037到底是不是故障?一句话说清楚:它不是。这个错误只是备库告警日志里的一条普通记录,告诉你“上一次的恢复操作被人为取消了”。它并不报错、不阻塞、不损坏数据——但好多人一看到它就紧张,以为同步挂了。其实真要担心的,是它背后藏着的归档断点或MRPS挂起状态。

手动修复 ORA-16037 导致 Oracle 12c DG 同步无法识别

为什么ORA-16037总出现在备库告警日志里

这个错误本质上就是 ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL 这条命令执行后的标准回执。你手动取消一次,它就刷一条,根本算不上故障。但问题在于:很多人看见它之后,以为同步就到此为止了,没接着执行 START APPLY;或者虽然执行了启动命令,但启动过程出了其他错误,却没暴露出来。

所以,面对ORA-16037,真正该做的是:

  • 首选去查一下V$ARCHIVE_DEST_STATUS的状态——STATUS列是不是VALID?ERROR字段是不是空的?非空才是真有问题。
  • 再查V$MANAGED_STANDBY,看PROCESS列里MRP0的状态。如果它是APPLYING_LOG,OK;如果它显示的是WAIT_FOR_LOG或者直接就是NOT ACTIVE,那就说明恢复根本没跑起来。
  • 注意一条陷阱:ORA-16037单独出现时,你从V$ARCHIVED_LOG查APPLIED字段,很可能能看到大片的YES。千万别被这个迷惑了——它只代表之前应用的日志没问题,不代表现在同步还活着。

ORA-16037后同步“无法识别”的真实原因

它就像个信号灯,告诉你“前面可能挡路了”,但真正让备库看起来失联的,是它下面掩盖的三类断点:

  • 主库的LOG_ARCHIVE_DEST_2配置里,VALID_NOW或者DELAY参数可能被意外启用了。这会导致归档不再实时推送过去,备库自然就断流了。
  • 主备归档日志之间可能存在Gap。比如主库的SEQUENCE# = 1319这个归档,主库自己已经归档了,但备库没收到。MRP一启动就卡在那里,但错误消息可能刷到trace文件里,而不是alert.log——所以你盯着alert.log根本看不到。
  • 备库的控制文件可能没包含主库最新日志组的信息。比如主库刚加了GROUP 4,备库的v$log里却根本没有这一组。MRP尝试应用包含这个日志切换的归档时,就会直接挂起,报的通常是ORA-00313,而不是你预期的ORA-16037。

手动修复步骤:从cancel到apply的闭环操作

修复可不是简单地执行一个CANCEL再打一个START APPLY就能解决的。你得确保环境就绪再推进:

  • 先确认备库处于MOUNT状态:SELECT OPEN_MODE FROM V$DATABASE必须返回MOUNTED。如果返回的是READ ONLY,你得先SHUTDOWN IMMEDIATE; STARTUP MOUNT。
  • 检查归档传输通道是否通畅:SELECT DEST_ID, STATUS, ERROR FROM V$ARCHIVE_DEST_STATUS WHERE DEST_ID = 2——如果你的配置不是默认到底2的话,记得改一下ID。如果ERROR非空,优先去解决ORA-16047或ORA-16057这类网络或配置错误。
  • 确认归档没有Gap:用SELECT THREAD#, MIN(SEQUENCE#), MAX(SEQUENCE#) FROM V$ARCHIVED_LOG GROUP BY THREAD#,对比主备库结果是否连续。如果备库缺了某一段,你需要手动从主库拷贝并注册。
  • 最后执行恢复时,带上两个关键参数:USING CURRENT LOGFILE和DISCONNECT。完整命令是ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT;如果不加这两个参数,恢复会在前台阻塞,而且一旦断开连接,进程容易被系统kill掉。

容易忽略的两个硬性依赖

就算所有命令都敲对了,下面这两点如果不满足,MRP也绝不会真正跑起来:

  • 备库必须有可用的STANDBY REDO LOG(SRL),而且组数必须≥主库在线日志组数。用SELECT GROUP#, THREAD#, BYTES FROM V$STANDBY_LOG查一下,如果结果为空或者数量不够,START APPLY基本就是静默失败。
  • 主库的LOG_ARCHIVE_DEST_2必须启用SYNC或ASYNC模式,而且不能带NOAFFIRM(除非你们已经评估过丢失风险)。如果配置为LGWR SYNC NOAFFIRM但备库没有SRL,LGWR会无限等待,最终超时并停止归档——这个坑踩过的人不少。

修复不是改一个参数或敲一条命令的事。关键在确认MRPs进程是否真正接管日志流——盯住V$MANAGED_STANDBY里的MRP0状态,比反复看alert.log里的ORA-16037有用得多。鉴于此,下次在告警日志里看到ORA-16037时,不妨先问自己一句:MRP0现在在干嘛?