Oracle Data Guard本身不接管连接路由,应用连接无法自动迁移,必须依赖客户端重连机制或service_name动态绑定;tnsnames.ora中ADDRESS_LIST仅影响初始连接,不支持已建立会话的重定向。

应用连接无法自动迁移,必须依赖客户端重连机制或服务名动态绑定,Oracle Data Guard 本身不接管连接路由。
tnsnames.ora 配置 ADDRESS_LIST 不等于自动故障转移
很多人误以为在 tnsnames.ora 中写多个 ADDRESS 就能自动切到新主库——实际不会。Oracle 客户端按顺序尝试连接,只在首次建立连接时轮询,已建立的连接不会因主备切换而重定向。
- 旧连接在切换后执行 SQL 会收到
ORA-03113或ORA-01033,此时必须由应用层捕获并主动关闭重连 - Java 应用若使用 HikariCP、UCP 等连接池,需开启
connection-test-query和validation-timeout,否则失效连接可能长期滞留 - Oracle UCP 支持
FAILOVER_TYPE=SELECT和FAILOVER_RETRIES,但仅对新连接生效,不恢复旧会话
service_name 动态启停是透明切换的关键
真正让应用“感觉不到切换”的核心,是让主备库共用同一个 SERVICE_NAME,且仅主库运行该服务。
- 在主库执行:
DBMS_SERVICE.START_SERVICE('myapp');在备库执行:DBMS_SERVICE.STOP_SERVICE('myapp') - 用触发器自动管理:
CREATE TRIGGER myapptrig AFTER STARTUP ON DATABASE,启动时查v$database.database_role决定启停 - 注意:
DBMS_SERVICE操作需ADMINISTER DATABASE TRIGGER权限,且不能在 RAC 的所有实例上同时启用同一 service(会冲突) - 客户端 TNS 中仍只需配置一个 service:
(SERVICE_NAME = myapp),无需写两个 host
Observer + Fast-Start Failover 只解决主库宕机,不解决网络闪断或误操作
启用 Fast-Start Failover 后,observer 进程可自动触发切换,但前提是主库完全不可达(如进程崩溃、主机下线)。它对以下情况无效:
- DBA 手动执行
SWITCHOVER,observer 默认不介入(需显式配置FSFO ENABLE并设AUTO_FAILBACK) - 网络分区导致 observer 与主库失联,可能引发脑裂,必须设置
LOGXPT_MODE为SYNC+REDO TRANSPORT USER权限校验 - 切换后,observer 不会通知客户端,所有连接仍需靠客户端自身重连逻辑恢复
最容易被忽略的是:TNS 配置里的 LOAD_BALANCE=on 或 FAILOVER=on 只影响连接建立阶段,不提供会话级重路由能力。真正在生产环境做到“无感”,必须组合 service_name 动态控制 + 连接池健康检测 + 应用层超时重试,三者缺一不可。


















