TAF生效必须在tnsnames.ora中将FAILOVER_MODE嵌套于CONNECT_DATA下,且配齐TYPE=SESSION、METHOD=BASIC;ADDRESS_LIST顺序决定故障转移路径,RETRIES与DELAY需合理设置(如180×3),Java应用还需连接串显式启用FAILOVER=true及完整FAILOVER_MODE参数。
taf 不是加个 failover=on 就能用的,tnsnames.ora 里漏掉 failover_mode 块、或 type/method 写错,连接照样报 ora-03113,根本不会切。
tnsnames.ora 中 FAILOVER_MODE 必须嵌套在 CONNECT_DATA 下
很多人把 FAILOVER_MODE 直接写在 DESCRIPTION 顶层,或者塞进 ADDRESS_LIST 里——Oracle Net 完全不认。它只接受一种位置:CONNECT_DATA 的子块。
- ✅ 正确位置:
(CONNECT_DATA = (SERVICE_NAME = mydb) (FAILOVER_MODE = (TYPE = SESSION) (METHOD = BASIC) ...)) - ❌ 错误写法:
(DESCRIPTION = (FAILOVER_MODE = ...) (ADDRESS_LIST = ...))—— 这个参数会被静默忽略 - ❌ 错误写法:
(ADDRESS_LIST = (FAILOVER_MODE = ...) (ADDRESS = ...))—— 同样无效
TYPE 和 METHOD 必须配对选对,否则 TAF 形同虚设
TYPE=SELECT 和 TYPE=SESSION 行为差异极大,不是“功能更强”就该选 SELECT;METHOD=PRECONNECT 看似稳妥,实则容易因网络抖动导致启动失败。
-
TYPE=SESSION:会话级重连,事务中断、连接重建,适用绝大多数业务(如增删改) -
TYPE=SELECT:仅对正在执行的SELECT语句透明续跑,要求客户端支持游标保持(JDBC 需 ojdbc8+ 且显式配置),否则仍抛异常 -
METHOD=BASIC:连接时才去探活备用地址,轻量、可靠,推荐首选 -
METHOD=PRECONNECT:启动时就建两套连接,资源开销大,且任一节点短暂不可达就会让整个连接初始化失败
ADDRESS_LIST 顺序决定 failover 路径,SCAN 地址只能放第一个
TAF 故障转移不是负载均衡,它严格按 ADDRESS_LIST 从上到下尝试——第一个通就用,挂了才试第二个。顺序错了,可能绕到跨机房节点才切,延迟飙升。
- SCAN 地址(如
rac-scan.example.com)必须放在ADDRESS_LIST第一个ADDRESS,否则 Oracle Net 解析不到其余节点 VIP,后续地址直接被跳过 - 每个
ADDRESS必须独立写全:(PROTOCOL=TCP)(HOST=...)(PORT=...),不能合并 host 列表或复用 PORT - 别指望 “自动选快的”,TAF 没有健康检查心跳,只依赖连接建立是否成功
RETRIES 和 DELAY 不是越大越好,卡住和秒切之间只差一个乘积
从主库宕机到应用拿到新连接,耗时 ≈ RETRIES × DELAY 秒。设成 RETRIES=300, DELAY=10,就是整整 50 分钟无响应——而多数业务超时才 30 秒。
- 默认
RETRIES=0:只试一次,失败立刻报错(等价于没开 TAF) - 推荐起点:
RETRIES=180, DELAY=3→ 总等待约 9 分钟,覆盖常见实例重启窗口 -
DELAY=0危险:会瞬间发大量连接请求,可能打爆监听器或触发防火墙限流
最容易被忽略的是:服务端 DBA_SERVICES 里的 FAILOVER_TYPE 和客户端 tnsnames.ora 必须一致;Java 应用还额外依赖 JDBC 连接串里带 FAILOVER=true 和完整 FAILOVER_MODE 参数——光改 tnsnames 文件,JDBC 层照样不走 TAF 路径。


















