TAF需在tnsnames.ora中显式配置完整FAILOVER_MODE块(含TYPE、METHOD、BACKUP三项),仅设FAILOVER=ON无效;Java应用还需启用oracle.net.enableOob=true且使用支持TAF的JDBC驱动。
taf 不是加个 failover=on 就能用的,必须在连接描述符中显式配置完整的 failover_mode,否则连接建立后节点宕机,会话直接断开,应用收 ora-03113 或 ora-03114,不会自动切走。
tnsnames.ora 里必须配齐 FAILOVER_MODE 的三个子参数
只写 FAILOVER=ON 或只写 BACKUP=xxx 都无效。Oracle 客户端只认嵌套在 CONNECT_DATA 或 ADDRESS_LIST 下的完整 FAILOVER_MODE 块,且以下三项缺一不可:
-
TYPE:必须是SESSION(重连即恢复会话)或SELECT(还能继续取SELECT结果集) -
METHOD:必须是BASIC(连接失败后主动重试)或PRECONNECT(预连备用实例,内存/连接数开销大) -
BACKUP:必须指定一个有效的备用连接描述符名(如ORCL_2),且该描述符本身也得带FAILOVER_MODE
错误示例:(FAILOVER_MODE=(BACKUP=ORCL_2)) —— 缺 TYPE 和 METHOD,TAF 不生效。
正确写法:(FAILOVER_MODE=(TYPE=SELECT)(METHOD=BASIC)(BACKUP=ORCL_2))
ADDRESS_LIST 顺序决定 failover 路径和重试起点
客户端发起连接时,按 ADDRESS_LIST 中地址的**从上到下顺序**逐个尝试;故障转移时,也按这个顺序找下一个可用地址。不是“随机挑”或“轮询”。
- 如果第一个地址对应已宕机节点,但没配
FAILOVER_MODE,就卡住报错,不会往下试 - 如果配了
FAILOVER_MODE且BACKUP指向另一个描述符,那失败后会跳转到那个描述符,而不是本列表的第二个ADDRESS - 多个
ADDRESS并列写在同一个DESCRIPTION里(无ADDRESS_LIST包裹),属于 connect-time failover,不触发 TAF 逻辑
所以,要走 TAF,推荐结构是:每个主备描述符单独定义,BACKUP 显式指向对方,形成闭环。
RETRIES 和 DELAY 参数直接影响故障感知时间
FAILOVER_MODE 可选配 RETRIES 和 DELAY,它们控制重试行为:
-
RETRIES=n:最多重试 n 次(默认 5) -
DELAY=s:每次重试前等待 s 秒(默认 1) - 总超时 ≈
RETRIES × DELAY,设太大(如RETRIES=300, DELAY=10)会导致故障后近 50 分钟无响应 - 设太小(如
DELAY=1)可能在实例刚重启、监听未就绪时反复失败,反而拖慢恢复
生产建议值:RETRIES=30, DELAY=3(约 90 秒内完成探测与切换),既避开瞬时抖动,又不至于挂太久。
Java 应用必须显式启用 TAF 支持
JDBC Thin 驱动默认不处理 TAF 回调,即使 tnsnames.ora 配对了,SELECT 语句在故障时仍会中断。必须满足两个条件:
- 使用支持 TAF 的 JDBC 驱动(Oracle 12c+ 的
ojdbc8.jar及以上) - 连接 URL 中显式开启:追加
;oracle.net.enableOob=true;oracle.net.tnsAdmin=/path/to/network/admin,或代码中设置connProps.put("oracle.net.enableOob", "true") - 若用 UCP 连接池,还需调用
setFastConnectionFailoverEnabled(true)
漏掉 enableOob=true,TAF 就只是“纸上配置”,服务器发来的故障通知根本进不到 Java 客户端线程里。
最常被忽略的一点:TAF 是客户端行为,但服务器端 service 层级的配置(如 srvctl add service -P BASIC)会覆盖客户端 tnsnames.ora 中的 FAILOVER_MODE。如果两边都配了,优先以服务端为准 —— 所以排查 TAF 失效时,先查 dba_services 里的 FAILOVER_METHOD 和 FAILOVER_TYPE 字段,别只盯着本地文件。











