TAF生效必须配齐FAILOVER_MODE(嵌套在ADDRESS_LIST或CONNECT_DATA下)、TYPE=SESSION、METHOD=BASIC;ADDRESS_LIST顺序决定故障转移路径;RETRIES与DELAY需合理设置(如RETRIES=30, DELAY=3);Java/OCI客户端须显式启用TAF支持。
tnsnames.ora 里 TAF 配置必须写对这三处参数
透明应用故障转移(taf)不是加个 failover=on 就能用的。实际连不上、切不走、卡住不重试,八成是这三个参数没配齐或值不合理:failover_mode、type、method。缺一个,taf 就算声明了也等于没开。
常见错误现象:应用连接 RAC 主库后,主库实例宕机,连接直接报 ORA-03113: end-of-file on communication channel,而不是自动切到备库继续执行——说明 TAF 根本没生效。
-
FAILOVER_MODE必须显式嵌套在ADDRESS_LIST或CONNECT_DATA下,不能只写在顶层 -
TYPE推荐用SESSION(会话级切换),别用SELECT(仅对查询有效,且要求客户端支持游标保持) -
METHOD选BASIC(连接时预连备用地址),别用PRECONNECT(启动时就建两套连接,资源开销大且易因网络抖动失败)
ADDRESS_LIST 顺序决定 failover 路径和重试行为
RAC 的 TAF 故障转移路径,完全由 ADDRESS_LIST 中 ADDRESS 的排列顺序决定。不是“谁快连谁”,而是“从上往下试,第一个通的用,挂了才切下一个”。顺序错了,failover 就会绕远路甚至失败。
使用场景:比如两个节点分别在不同机房,你希望优先走同城节点,跨城节点只作兜底——那就必须把同城的 ADDRESS 放前面。
- 每个
ADDRESS必须带独立的(HOST=...)(PORT=...)(PROTOCOL=TCP),不能共用 - 不要把两个节点塞进同一个
ADDRESS;TAF 不识别逗号分隔的 host 列表 - 如果用了 SCAN 地址,它只能出现在第一个
ADDRESS,否则 TAF 无法解析后续节点位置
示例片段(正确):
RACDB =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac-scan.example.com)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = node2-vip.example.com)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = racdb)
(FAILOVER_MODE =
(TYPE = SESSION)
(METHOD = BASIC)
(RETRIES = 180)
(DELAY = 5)
)
)
)
RETRIES 和 DELAY 参数直接影响故障感知时间
TAF 不是秒切。从主库宕机到应用拿到新连接,中间要等 RETRIES × DELAY 秒。默认 RETRIES=0 表示只试一次,失败就报错;DELAY=0 会疯狂重连,打爆监听器。
性能影响:设太大(比如 RETRIES=300, DELAY=10)会导致故障后长达 50 分钟无响应;设太小(如 DELAY=1)又可能在实例重启过程中反复失败,拖慢恢复。
- 生产建议值:
RETRIES=30(约 2–5 分钟总等待)、DELAY=3(避免瞬时抖动误判) -
RETRIES是对整个ADDRESS_LIST的总尝试次数,不是每个地址单独计数 - 如果底层网络有防火墙或负载均衡器,
DELAY建议 ≥2 秒,避开其连接清理周期
Java / OCI 客户端必须显式启用 TAF 才认 tnsnames.ora 设置
tnsnames.ora 配好了,但 Java 应用还是不切?大概率是 JDBC 没打开 TAF 开关。Oracle JDBC 驱动默认忽略 FAILOVER_MODE,必须靠连接属性强制激活。
常见错误现象:SQL*Plus 能切,但 Spring Boot 应用连不上就报错——驱动层根本没读取或应用 TAF 配置。
- JDBC URL 加
;oracle.net.enableOob=true;oracle.net.timeout=60000(OoB 是 TAF 心跳基础) - DataSource 初始化时设
setConnectionProperties("oracle.jdbc.tafEnabled=true") - OCI 客户端(如 Pro*C)需在编译时链接
-lclntsh,且运行时TNS_ADMIN环境变量必须指向含正确 tnsnames.ora 的目录
没做这一步,tnsnames.ora 写得再准,TAF 对应用来说就是不存在。
最常被忽略的是客户端兼容性:12c 以后的 JDBC 驱动对 SELECT type 的 TAF 支持变弱,Session 级仍是唯一稳定选择。别在升级驱动后还沿用老文档里的 TYPE=SELECT 示例。










