ora-16775是data guard broker因备库未满足安全切换条件(如mrp未运行、归档未应用完、log_archive_dest_2异常等)而主动拒绝switchover的保护性警告,非配置错误,需先验证并修复底层状态再重试。

ORA-16775 不是配置写错了,而是 Data Guard Broker 明确告诉你:“备库还没准备好,现在切过去会丢数据”。
ORA-16775 的真实含义:Broker 的安全拦截,不是状态异常
这个错误常被误当成“配置没对”或“命令敲错了”,其实它压根不检查你的 DGMGRL 语法。它是 Broker 在执行 SWITCHOVER TO 前,主动扫描底层状态后触发的保护性拒绝。核心逻辑就一条:只要它发现备库还没应用完所有归档、或者 MRP 没在跑,就直接拦住,不让你点火。
常见表现包括:
- 你在
DGMGRL里敲SWITCHOVER TO 'standby_db',立刻报ORA-16775,但SHOW DATABASE VERBOSITY 'standby_db'看起来“一切正常” - 主库
V$DATABASE.SWITCHOVER_STATUS是TO STANDBY,但备库V$DATABASE.SWITCHOVER_STATUS却卡在NOT ALLOWED或SESSIONS ACTIVE(即使V$SESSION查不到活跃会话) - 备库
V$MANAGED_STANDBY里没有APPLYING_LOG进程,或者STATUS是WAIT_FOR_LOG
最常踩的三个底层状态坑
Broker 判断是否“允许切换”,只看这三件事有没有干净落地。漏一个,ORA-16775 就稳稳等着你:
- 备库必须已应用完所有接收到的归档:
SELECT MAX(SEQUENCE#), APPLIED FROM V$ARCHIVED_LOG GROUP BY APPLIED—— 确保APPLIED = 'YES'的最大SEQUENCE#和主库当前V$ARCHIVE_DEST_STATUS.ARCHIVED_SEQ#一致 - 备库恢复模式必须是实时应用:
SELECT RECOVERY_MODE FROM V$ARCHIVE_DEST_STATUS WHERE DEST_ID = 2必须返回MANAGED REAL TIME APPLY,不是IDLE、ERROR或空 - 主库归档目标必须启用且无错:
SELECT STATUS, ERROR FROM V$ARCHIVE_DEST_STATUS WHERE DEST_ID = 2中STATUS是VALID,ERROR列为空;同时LOG_ARCHIVE_DEST_STATE_2必须是ENABLE
DGMGRL 里“强制重置”的实际动作是什么
所谓“强制”,不是跳过检查,而是让 Broker 刷新缓存、重新评估。它不提供 --force 开关,真正有效的操作只有:
- 先在备库手动启动应用(如果 MRP 没跑):
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT; - 在 DGMGRL 中对备库执行:
EDIT DATABASE 'standby_db' SET STATE = 'ONLINE';(如果显示UNKNOWN或OFFLINE) - 再执行:
ENABLE DATABASE 'standby_db';(仅当之前被DISABLE过) - 最后重试:
SWITCHOVER TO 'standby_db';—— 此时 Broker 会重新拉取V$视图,而不是读旧缓存
注意:REINSTATE 不解决 ORA-16775,那是给 Failover 后修复断连用的;ENABLE 也不是万能钥匙,如果底层状态没达标,它只会报更具体的错误,比如 ORA-16778(日志应用延迟超限)。
最容易被忽略的细节:控制文件里的“陈旧角色信息”
哪怕所有进程都跑着、归档也都应用完了,备库控制文件里残留的旧角色标记仍会让 Broker 拒绝切换。典型表现是:V$DATABASE.SWITCHOVER_STATUS 显示 NOT ALLOWED,但查不到任何阻塞会话。
这时必须确认:
- 备库是否曾被手工执行过
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY但中途失败?这种操作可能让控制文件卡在中间态 - 用
ALTER DATABASE ACTIVATE PHYSICAL STANDBY DATABASE强制激活过?那会彻底破坏 DG 关系,Broker 不再信任该库 - 最稳妥的验证方式:在备库上执行
SELECT CONTROLFILE_TYPE FROM V$DATABASE;—— 返回必须是STANDBY,不是PRIMARY;如果是后者,说明控制文件已被污染,需重建











