最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Oracle RAC TAF如何配置才能自动重连
时间:2026-08-25 09:21:48 编辑:袖梨 来源:一聚教程网
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 就等于启用了运行时故障转移——其实它只控制建连阶段的地址轮询。
-
FAILOVER_MODE必须紧贴CONNECT_DATA,不能缩进错层 - 必须包含
TYPE和METHOD两个必需子项,例如:(TYPE=session)(METHOD=basic) -
RETRIES和DELAY建议显式设值(如(RETRIES=3)(DELAY=5)),避免依赖驱动默认行为(ojdbc6 默认 RETRIES=0,即不重试) - 示例正确结构:
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。
-
TYPE=session:故障后会话重建,未提交事务回滚,所有SELECT需重发——这是 OLTP 应用的标准行为,资源开销低,兼容性好 -
TYPE=select:仅对执行中未完成的长查询(如报表导出、ETL 抽取)有意义;要求 Oracle 在 PGA 中保留游标上下文(每会话多占 2–5 MB),高并发下易触发内存压力 - 如果应用层已做重试(如 Spring 的
@Retryable),再配TYPE=select属于冗余,且故障恢复路径更难排查 -
ALTER SESSION、临时表、未提交的 DML 都不会被 TAF 保留,无论选哪种 TYPE
METHOD=basic vs METHOD=preconnect:资源和启动速度的权衡
METHOD=preconnect 不是“更快”,而是“更耗资源”,WebLogic/Tomcat 连接池初始化失败常源于此。
-
METHOD=basic(推荐):首次只连一个实例;故障时按DELAY/RETRIES尝试切换——延迟可控(比如 5 秒 × 3 次 = 最多 15 秒不可用),连接数不翻倍 -
METHOD=preconnect:连接池创建单个逻辑连接时,会同时连所有 RAC 实例(4 节点 → 单连接占 4 个物理连接),极易触发ORA-12516(监听器 handler 耗尽)或数据库PROCESSES参数超限 - 某些旧版驱动(如 ojdbc6)在
PRECONNECT模式下会卡在 DNS 解析,尤其当 VIP 未正确写入/etc/hosts - WebLogic 默认用
BASIC,除非你明确压测验证过PRECONNECT在你的负载下稳定且资源充足
服务端 TAF 可以省客户端配置,但有硬前提
想让客户端完全不用改 tnsnames.ora,必须在数据库侧用 srvctl 创建带 TAF 属性的服务,并确保客户端连的是这个 service name。
- 服务创建命令必须带
-P basic或-P preconnect,例如:srvctl add service -d mydb -s mytaf -r "inst1" -a "inst2" -P basic - 之后需用
dbms_service.modify_service设置failover_type和failover_method,仅靠srvctl不足 - 客户端连接串里
SERVICE_NAME必须匹配该服务名,且监听器必须已注册该服务(lsnrctl status可查) - 服务端 TAF 对 JDBC 驱动版本有要求:ojdbc8+ 支持完整语义;ojdbc6 对
SELECT类型支持不稳定,容易 fallback 到 session 行为
真正决定 TAF 是否起作用的,不是有没有写 FAILOVER=ON,而是 FAILOVER_MODE 是否存在、位置是否正确、参数是否完整。很多线上故障回溯发现,tnsnames.ora 文件里只有一行 FAILOVER=ON,其余全靠猜——这等于没配。