主库switchover_status必须为to standby或sessions active才可切换,若为not allowed则说明redo未传完,需检查v$archive_dest_status;备库状态需待主库执行切换并重启至mount后才变为to primary,且须确保mrp进程运行、apply lag与transport lag均为+00 00:00:00。

能直接用 ALTER DATABASE COMMIT TO SWITCHOVER 完成,但前提是主备状态都“干净”——否则不是报错就是切完数据不一致。
怎么确认主库允许切换(switchover_status)
主库上查 v$database,关键就看 switchover_status 字段:
- 显示
TO STANDBY:最理想,可直接切 - 显示
SESSIONS ACTIVE:有活跃会话,加WITH SESSION SHUTDOWN强制断开 - 显示
NOT ALLOWED:别硬切,说明 Redo 没传完或归档目标异常,先查v$archive_dest_status的STATUS和ERROR列
顺手再跑一句:SELECT STATUS, GAP_STATUS FROM v$archive_dest_status WHERE DEST_ID = 2。如果 GAP_STATUS 是 RESOLVABLE GAP 或 ERROR,得先补日志或修归档路径。
为什么备库 switchover_status 长期是 NOT ALLOWED
这不是 bug,是正常现象——备库只有在主库发出 END OF REDO 标记并完成接收后,状态才会变成 TO PRIMARY。所以你不能一上来就查备库,得等主库执行完切换命令、关闭实例、重启到 MOUNT 状态之后,再去查备库。
常见误操作:
- 主库还没执行
COMMIT TO SWITCHOVER,就跑去备库查状态 - 主库切完没重启到
MOUNT,备库控制文件里没收到角色变更信号 - 备库的 MRP 进程没在运行:
SELECT PROCESS, STATUS FROM v$managed_standby里没有APPLYING_LOG
ORA-16775 不是配置错,是 Broker 在拦你
这个错误本质是 Data Guard Broker 主动拒绝切换,意思是:“我检查过了,备库还没应用完所有日志,现在切过去不安全”。它不关心你参数写没写对,只认实际状态。
必须验证的三件事:
- 备库上:
SELECT MAX(SEQUENCE#), APPLIED FROM v$archived_log GROUP BY APPLIED→ 确保APPLIED = 'YES'的最大序号和主库当前v$archive_dest_status中的ARCHIVED_THREAD#一致 - 备库是否实时应用:
SELECT RECOVERY_MODE FROM v$archive_dest_status WHERE DEST_ID = 2必须返回MANAGED REAL TIME APPLY - 主库
LOG_ARCHIVE_DEST_STATE_2必须是ENABLE,且switchover_status是TO STANDBY
验证完再进 dgmgrl 执行 VALIDATE DATABASE 'standby_db_name',看到 Configuration status: SUCCESS 才算真正准备好。
切完立刻要干的三件事
新主库打开后,别急着放流量:
- 立刻查
v$database.database_role,确认是PRIMARY - 立刻查
v$dataguard_stats里的apply lag和transport lag,必须都是+00 00:00:00 - 立刻在新备库上启动实时应用:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT—— 注意不是STARTUP MOUNT后就完事,这句漏了,新备库就停在 mount 状态不动
最容易被忽略的是:切换后原主库(现备库)的 log_archive_dest_2 参数还指向旧主库地址,不改的话归档会失败。必须同步更新为指向新主库,否则下次切回去又卡住。











