Failover时出现脑裂是因为主库仅网络隔离未真正宕机,仍可写入,而备库已升为新主并接受写请求,导致双主同时写同一存储,破坏数据一致性;必须立即shutdown abort原主库并清理进程与ASM挂载。

Failover 时为什么会出现脑裂
Failover 是主库彻底不可用后的强制接管,它不等备库完全同步就升级角色——这意味着原主库若只是网络隔离(而非宕机),可能仍在写数据,而备库已自认为是新主库。两边同时写同一套共享存储或 ASM 磁盘组,就会破坏数据一致性,这就是脑裂。
典型诱因包括:
– 主库节点因私网中断被驱逐,但数据库进程未真正终止(如 CRS 资源残留、sqlplus / as sysdba 手动启库)
– 备库启用 ALTER DATABASE ACTIVATE PHYSICAL STANDBY 后,原主库网络恢复却未被强制 shutdown
– 使用非 Broker 方式手动 Failover,漏掉清理原主库归档路径、禁用监听、关闭 LNS 进程等关键步骤
必须禁用原主库的 Redo 生成能力
Failover 后第一件事不是查数据,而是确保原主库再也写不出一丁点 Redo。否则只要它还在 mount 状态,就可能产生分裂写入。
- 立刻在原主库执行:
SHUTDOWN ABORT,不要用SHUTDOWN IMMEDIATE—— 后者可能卡在等待归档完成 - 确认 CRS 已释放资源:
crsctl stat res -t | grep <code>db_unique_name应无 ONLINE 状态实例 - 检查操作系统级进程:
ps -ef | grep pmon | grep <code>db_unique_name,残留pmon必须 kill -9 - 若使用 ASM,还需确认
+DATA等磁盘组未被原主库挂载:asmcmd lsdg在其他节点验证
Broker 环境下 Failover 的安全边界在哪
Broker 不会自动停原主库,它只管“把备库升上去”。是否脑裂,取决于你有没有在 DGMGRL 执行 FAILOVER TO 前,人工切断原主库所有输入输出。
正确操作链是:
- 先确认主库真死:
srvctl status database -d <code>db_unique_name返回 FAILED,且crsctl check crs在该节点失败 - 再进
dgmgrl /,运行FAILOVER TO <code>standby_db_name(注意不是SWITCHOVER) - Failover 完成后,立即登录原主库所在主机,执行
srvctl stop database -d <code>db_unique_name;若失败,直接shutdown abort - 最后验证:
SELECT DATABASE_ROLE, OPEN_MODE FROM V$DATABASE在两边都查——新主库应为PRIMARY+READ WRITE,原主库必须报错 ORA-01034 或返回空行
为什么单靠 ALTER DATABASE ACTIVATE 最危险
这条命令绕过 Broker 和 Clusterware,是纯 SQL 层激活,它不会通知 OCR、不会清理远端监听、也不会重置控制文件中的 Data Guard 配置位。一旦原主库稍后恢复,v$database.database_role 仍显示 PRIMARY,而新主库也显示 PRIMARY,两个“主库”对同一个 db_unique_name 发起归档注册,ASM 中的归档日志路径开始冲突,MRP 进程在两边都尝试应用对方日志——此时脑裂已发生,且难以回退。
真正安全的做法永远是:用 Broker 触发 Failover,再人工强杀原主库进程并卸载 ASM 磁盘组。任何跳过这一步的“快速恢复”,都是在给后续数据校验埋雷。


















