Oracle RAC TAF如何配置才能自动重连

作者:袖梨 2026-08-25

TAF自动重连的前提是FAILOVER_MODE必须作为CONNECT_DATA的直接子项,包含TYPE和METHOD等完整参数,且不能仅依赖FAILOVER=ON;位置错误或缺失关键参数将导致Oracle Net静默忽略,故障时连接直接中断。

TAF 能自动重连的前提是:客户端 tnsnames.ora 中必须显式配置 FAILOVER_MODE,且嵌套在 CONNECT_DATA 内部;只写 FAILOVER=ON 或漏掉 FAILOVER_MODE,连接建立后节点宕机就直接断开。

tnsnames.ora 必须这样写,否则 TAF 不生效

常见错误是把 FAILOVER_MODE 放在 DESCRIPTION 层级下(Oracle 会静默忽略),或误以为 FAILOVER=ON 就等于启用了运行时故障转移——其实它只控制建连阶段的地址轮询。

  1. FAILOVER_MODE 必须紧贴 CONNECT_DATA,不能缩进错层
  2. 必须包含 TYPEMETHOD 两个必需子项,例如:(TYPE=session)(METHOD=basic)
  3. RETRIESDELAY 建议显式设值(如 (RETRIES=3)(DELAY=5)),避免依赖驱动默认行为(ojdbc6 默认 RETRIES=0,即不重试)
  4. 示例正确结构:
myrac = (DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = node1-vip)(PORT = 1521))(ADDRESS = (PROTOCOL = TCP)(HOST = node2-vip)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = myservice)(SERVER = DEDICATED)(FAILOVER_MODE = (TYPE = session)(METHOD = basic)(RETRIES = 3)(DELAY = 5))))

TYPE=session 还是 TYPE=select?别乱配

TYPE=select 看似“无缝”,但代价高、适用场景窄,多数应用反而该用 TYPE=session

  1. TYPE=session:故障后会话重建,未提交事务回滚,所有 SELECT 需重发——这是 OLTP 应用的标准行为,资源开销低,兼容性好
  2. TYPE=select:仅对执行中未完成的长查询(如报表导出、ETL 抽取)有意义;要求 Oracle 在 PGA 中保留游标上下文(每会话多占 2–5 MB),高并发下易触发内存压力
  3. 如果应用层已做重试(如 Spring 的 @Retryable),再配 TYPE=select 属于冗余,且故障恢复路径更难排查
  4. ALTER SESSION、临时表、未提交的 DML 都不会被 TAF 保留,无论选哪种 TYPE

METHOD=basic vs METHOD=preconnect:资源和启动速度的权衡

METHOD=preconnect 不是“更快”,而是“更耗资源”,WebLogic/Tomcat 连接池初始化失败常源于此。

  1. METHOD=basic(推荐):首次只连一个实例;故障时按 DELAY/RETRIES 尝试切换——延迟可控(比如 5 秒 × 3 次 = 最多 15 秒不可用),连接数不翻倍
  2. METHOD=preconnect:连接池创建单个逻辑连接时,会同时连所有 RAC 实例(4 节点 → 单连接占 4 个物理连接),极易触发 ORA-12516(监听器 handler 耗尽)或数据库 PROCESSES 参数超限
  3. 某些旧版驱动(如 ojdbc6)在 PRECONNECT 模式下会卡在 DNS 解析,尤其当 VIP 未正确写入 /etc/hosts
  4. WebLogic 默认用 BASIC,除非你明确压测验证过 PRECONNECT 在你的负载下稳定且资源充足

服务端 TAF 可以省客户端配置,但有硬前提

想让客户端完全不用改 tnsnames.ora,必须在数据库侧用 srvctl 创建带 TAF 属性的服务,并确保客户端连的是这个 service name。

  1. 服务创建命令必须带 -P basic-P preconnect,例如:srvctl add service -d mydb -s mytaf -r "inst1" -a "inst2" -P basic
  2. 之后需用 dbms_service.modify_service 设置 failover_typefailover_method,仅靠 srvctl 不足
  3. 客户端连接串里 SERVICE_NAME 必须匹配该服务名,且监听器必须已注册该服务(lsnrctl status 可查)
  4. 服务端 TAF 对 JDBC 驱动版本有要求:ojdbc8+ 支持完整语义;ojdbc6 对 SELECT 类型支持不稳定,容易 fallback 到 session 行为

真正决定 TAF 是否起作用的,不是有没有写 FAILOVER=ON,而是 FAILOVER_MODE 是否存在、位置是否正确、参数是否完整。很多线上故障回溯发现,tnsnames.ora 文件里只有一行 FAILOVER=ON,其余全靠猜——这等于没配。

相关文章

精彩推荐