如何配置RAC应用的透明应用故障转移TAF_tnsnames.ora failover设置

6次阅读

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_modetypemethod。缺一个,taf 就算声明了也等于没开。

常见错误现象:应用连接 RAC 主库后,主库实例宕机,连接直接报 ORA-03113: end-of-file on communication channel,而不是自动切到备库继续执行——说明 TAF 根本没生效。

  • FAILOVER_MODE 必须显式嵌套在 ADDRESS_LISTCONNECT_DATA 下,不能只写在顶层
  • TYPE 推荐用 SESSION(会话级切换),别用 select(仅对查询有效,且要求客户端支持游标保持)
  • METHODBASIC(连接时预连备用地址),别用 PRECONNECT(启动时就建两套连接,资源开销大且易因网络抖动失败)

ADDRESS_LIST 顺序决定 failover 路径和重试行为

RAC 的 TAF 故障转移路径,完全由 ADDRESS_LISTADDRESS 的排列顺序决定。不是“谁快连谁”,而是“从上往下试,第一个通的用,挂了才切下一个”。顺序错了,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 示例。

text=ZqhQzanResources