oracle data guard 无法原生支持同城双活,因其物理备库要求数据文件结构一致,逻辑备库缺乏冲突检测与自动合并机制,两地同时写同一行必然导致ora-01555或事务回滚。

Oracle Data Guard 本身不支持真正的“同城双活”(即两地同时读写同一套逻辑数据),它只能实现主库读写 + 备库只读/恢复,所谓“双活”必须靠上层应用或分布式中间件做数据分片、路由隔离来规避冲突。异地容灾则完全可行,且是 Data Guard 最成熟的应用场景。
为什么 Oracle Data Guard 无法原生支持同城双活
Data Guard 的物理备库(Physical Standby)基于块级重做日志应用,要求主备库数据文件结构完全一致;逻辑备库(Logical Standby)虽可读写,但限制极多:DBMS_LOGSTDBY.SKIP 配置复杂、不支持大对象类型、DDL 同步需显式启用且易出错。更重要的是,Data Guard 没有内置的冲突检测与自动合并机制——两地同时写同一张表的同一行,必然导致 ORA-01555 或事务回滚,这不是配置能绕开的架构约束。
常见错误现象包括:
- 启用了
LOG_ARCHIVE_DEST_n的SYNC模式后,主库提交变慢甚至超时 - 逻辑备库开启 DML 后,
SELECT * FROM DBA_LOGSTDBY_EVENTS显示大量duplicate key或constraint violation - 误将逻辑备库当作第二个主库直接连应用,结果部分事务静默失败
同城双活必须配合应用层改造
真正落地的“同城双活”,本质是把 Data Guard 当作底层强同步通道,上层用其他手段实现业务级双写隔离:
- 按业务域拆分:例如 A 地中心处理华东用户订单,B 地中心处理华北用户订单,共用一套数据库集群(如 RAC),但 Data Guard 只用于跨城灾备
- 按表拆分:A 地写
orders_sh,B 地写orders_bj,再通过物化视图或 CDC 工具做汇总,此时 Data Guard 同步的是物理副本,不干涉写逻辑 - 使用 GoldenGate 或 OGG Microservices 替代 Data Guard 做逻辑复制,配合自定义冲突解决策略(如时间戳优先、站点优先)
注意:ACTIVE DATA GUARD 模式下备库可读,但不能写——它只是“读扩展”,不是“写双活”。很多团队混淆了这个概念,上线后才发现报表查询压垮备库,主库反而因 ARCH 进程阻塞变慢。
异地容灾中 Data Guard 的关键配置取舍
异地距离超过 200km 后,网络延迟会显著影响同步模式选择:
- 若要求
RPO=0(零数据丢失),必须用SYNC模式,但仅限同城(≤5ms RTT)。跨省/跨区域部署时,主库事务提交会被卡在等待备库 ACK,吞吐量断崖下跌 - 推荐方案:同城用
SYNC+FAST START FAILOVER实现秒级切换;异地用ASYNC+FAR SYNC INSTANCE(远端同步实例)兼顾 RPO 与性能。FAR SYNC 不存数据,只转发重做流,延迟可控 -
LOG_ARCHIVE_DEST_2中务必设置REOPEN=60和MAX_FAILURE=3,避免专线抖动导致归档中断后主库挂起
典型错误是把异地备库也配成 SYNC,结果生产库 COMMIT 响应时间从 5ms 涨到 200ms+,APM 监控直接告警。
切换演练中最容易被忽略的细节
日常运维中,SWITCHOVER 和 FAILOVER 的操作差异常被轻视:
-
SWITCHOVER是计划内切换,要求主备库状态均为OPEN且STATUS = 'TO STANDBY',执行前必须确认所有归档已应用完毕(查V$ARCHIVE_GAP) -
FAILOVER是故障后强制接管,备库会丢弃未接收的重做,可能丢失最后几秒事务。执行后必须立刻重建主库为新备库,否则形成单点 - 切换后 DNS 或负载均衡器不会自动更新,应用连接串仍指向旧地址——这是 70% 的“切换成功但业务不通”问题根源
真实案例里,某银行在年度灾备演练中完成 FAILOVER,却因未更新 F5 的 pool member,流量仍在打向已关机的原主库,整整 18 分钟无响应才人工介入。











