TAF在Oracle 12c RAC中必须用服务端方式配置才可靠,因客户端tnsnames.ora中的FAILOVER_MODE会被服务端设置完全覆盖,且若listener.ora存在SID_LIST静态注册则TAF直接禁用;JDBC Thin驱动不支持TAF,须用OCI或UCP;srvctl创建服务时必须指定-P BASIC和-r实例列表,并调用dbms_service.modify_service显式启用SELECT模式及AQ通知。
taf 在 oracle 12c rac 中必须用服务端(server-side)方式配置才可靠,客户端 tnsnames.ora 里的 failover_mode 会被覆盖,且容易因 listener 静态注册失效。
为什么不能只配客户端 tnsnames.ora
Oracle 官方明确说明:如果同时配置了客户端 TNS 和服务端 service 属性,服务端设置永远优先并完全覆盖客户端配置。更关键的是,若 listener.ora 中存在 SID_LIST 下的 GLOBAL_DBNAME 静态注册,TAF 会直接被禁用——这个错误在 12c 中依然常见,但报错不明显,只会表现为故障时不切换。
- 客户端配置仅在无服务端配置时生效,实际生产环境几乎不用
-
FAILOVER=ON或LOAD_BALANCE=ON是连接时故障转移/负载均衡,和 TAF(会话建立后的自动重连)无关 - JDBC Thin 驱动不支持 TAF,必须用 OCI(即
oracle.jdbc.driver.OracleDriver+ Oracle Client)或 UCP 连接池
srvctl 创建服务时必须指定 -P BASIC 和 -r 实例列表
12c 的 srvctl add service 命令中,-P 参数决定 failover method,必须显式设为 BASIC(不是默认值),否则后续 dbms_service.modify_service 无法启用 select 模式;-r 列出 preferred instances,是 TAF 实际生效的前提。
- 命令示例:
srvctl add service -d orcl -s app_taf -r "orcl1,orcl2" -P BASIC - 不能漏掉
-r;只写-a(available)没用,TAF 不走 available 列表 - 服务名(
app_taf)需与应用连接字符串中的SERVICE_NAME完全一致
dbms_service.modify_service 必须调用且参数不可缺
刚用 srvctl 创建的服务,dba_services 视图里 failover_method 和 failover_type 默认都是 NONE。必须执行 PL/SQL 调用 dbms_service.modify_service 才真正启用 TAF。
- 关键参数必须全设:
failover_method => dbms_service.failover_method_basic、failover_type => dbms_service.failover_type_select、failover_retries => 180、failover_delay => 5 -
aq_ha_notifications => true要开启,否则服务器无法主动通知客户端故障 - 执行后查
dba_services,确认METHOD是BASIC、TYPE是SELECT、AQNOT是YES
验证 TAF 是否真生效:别只看连接成功
连接成功不代表 TAF 生效。必须模拟实例宕机并观察会话行为——尤其注意 V$SESSION.FAILED_OVER 字段和 SELECT 是否中断。
- 连接后立即查:
SELECT SERVICE_NAME, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER FROM V$SESSION WHERE SID = SYS_CONTEXT('USERENV','SID'); - 正常应返回
FAILOVER_TYPE='SELECT'、FAILED_OVER='NO' - 手动 kill 当前实例进程后,再执行长查询(如
SELECT * FROM big_table),若返回行数连续、FAILED_OVER变为YES,才算真正生效 - DML 事务一定会回滚,TAF 不保证事务延续性,这点常被误认为“配置失败”
最易忽略的是 listener.ora 里的静态注册和 JDBC 驱动类型——哪怕所有 service 参数都对,这两处任一出错,TAF 就静默失效,现象就是实例挂了连接直接断开,毫无重试。


















