dgmgrl一键failover需主库不可用、备库日志同步完整且flashback已开启,缺一不可;否则原主库无法reinstate。ora-16657或“not allowed”是broker拒绝强制切换的明确信号,主因包括备库未启用flashback、非physical standby状态、broker配置未生效或监听缺失_dgmgrl服务。
能直接用 dgmgrl 一键 failover,但前提是主库已不可用、备库日志同步完整、且 flashback 已开启——缺一不可,否则切换后原主库无法 reinstate 回备库角色。
为什么 failover to xxx 报 ORA-16657 或 “not allowed”
这不是命令写错了,而是 DG Broker 拒绝执行强制切换的明确信号。常见原因有:
-
FLASHBACK DATABASE在备库(或原主库)未启用:DG Broker 的failover默认依赖闪回日志做后续reinstate,没开就报错;必须先在备库上执行ALTER DATABASE FLASHBACK ON; - 备库状态不是
PHYSICAL STANDBY:比如误启用了SNAPSHOT STANDBY,需先切回:ALTER DATABASE CONVERT TO PHYSICAL STANDBY; - Broker 配置未生效:
dg_broker_start=TRUE在主备两端都得设,且DMON进程必须运行(查ps -ef | grep dmon) - 监听里缺
_DGMGRLservice:12.1+ 虽不强制要求静态注册,但如果用DGMGRL重启实例(比如 failover 后要拉起原主库),没这个 service 就连不上
执行 failover to <db_unique_name></db_unique_name> 前必须确认的三件事
别跳过验证,否则 failover 中断后可能要重建备库:
- 检查备库是否已应用完所有可得日志:
SELECT PROCESS, STATUS, SEQUENCE#, BLOCK# FROM V$MANAGED_STANDBY WHERE PROCESS IN ('MRP0', 'RFS');——MRP0状态应为APPLYING_LOG,且SEQUENCE#接近主库当前归档最大号(若主库还能连) - 确认无归档缺口:
SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP;—— 返回空集才算安全 - 验证备库是否“Ready for Failover”:
DGMGRL> VALIDATE DATABASE "<standby_db_unique_name>";</standby_db_unique_name>—— 输出里必须含Ready for Failover: Yes (Primary Running)或(Primary Not Running),前者表示主库还活着但可被覆盖,后者才是真故障场景
failover to 成功后,原主库怎么加回来?
这步最容易被忽略,但恰恰决定整个 DG 架构能否快速恢复双节点保护:
- 原主库启动到
MOUNT状态后,必须立刻执行REINSTATE DATABASE "<original_primary_db_unique_name>"</original_primary_db_unique_name>,而不是手动建备库 -
REINSTATE成功的前提是:原主库开启了FLASHBACK,且DB_RECOVERY_FILE_DEST里还保留着足够多的闪回日志(建议至少保留 2 小时以上) - 如果
REINSTATE报ORA-16661: the standby database needs to be reinstated,说明 Broker 已识别出该库身份,但还没触发动作——此时再跑一遍REINSTATE命令即可,不用重启 - 切记:
REINSTATE是 Broker 级操作,不能用 SQL*Plus 执行;且必须从当前主库(即刚 failover 成功的那个库)的DGMGRL连上去发命令
真正麻烦的从来不是 failover 那条命令,而是切换后原主库的 reinstate 是否能自动完成——它高度依赖闪回配置的完备性、FRA 空间余量、以及 Broker 元数据的一致性。线上环境务必提前演练整套流程,而不是只测“切得过去”。











