fan生效需服务端推送事件、客户端ons通道畅通、连接池显式启用fcf三者缺一不可;仅设fanenabled=true无效,必须验证跨节点ons互通、service已启动且failover_type非none、禁用tns层干扰参数。

FAN 不是设个 fanEnabled=true 就能自动工作的,必须服务端推送事件、客户端 ONS 通道通、连接池显式启用 FCF,三者缺一不可。
为什么 setProperty("oracle.jdbc.fanEnabled", "true") 后仍无故障切换?
FAN 依赖底层 ONS(Oracle Notification Service)通道接收 RAC 推送的 DOWN/UP 事件。只改 JDBC 属性,但 ONS 根本没通或没收到事件,连接池就只能等超时或抛 ORA-03113。
-
onsctl ping成功 ≠ FAN 可用:必须逐节点验证跨节点通信,例如onsctl ping -h rac2 -p 6113(替换为真实节点名和端口) -
$CRS_HOME/opmn/conf/ons.config中的remoteport必须与racgons add_config注册的端口完全一致;所有节点的localport不能重复(默认 6113,冲突会导致事件丢弃) - ONS 必须由 CRS 管理启动:
crsctl start resource ora.ons;手动运行$ORACLE_HOME/bin/onsctl start会加载错误实例,无法接收 RAC 内部事件 - 查
$CRS_HOME/log/<host>/client/ons.log</host>,若出现Connection refused或Failed to connect to remote host,说明 ONS 联通失败,FAN 事件根本发不出去
JDBC 连接字符串里加 FAILOVER=ON 有用吗?
没用。这是常见误解。FAILOVER=ON 属于 TNS 层 Connect-time Failover,只影响初始建连;而 FAN/FCF 是运行时事件驱动机制,两者互不感知。
- 启用 FCF 必须显式设置:
connection.setProperty("oracle.jdbc.fanEnabled", "true")(JDBC Thin)或 UCP 中调用setFastConnectionFailoverEnabled(true) - 连接字符串中禁止含
LOAD_BALANCE=ON或FAILOVER=ON——这些参数会干扰 FCF 的事件响应路径,尤其在 SCAN 场景下导致连接被路由到已宕机实例 - 必须使用
SERVICE_NAME对应 RAC 中状态为ENABLED的 service(查srvctl config service -d <db></db>),且该 service 的FAILOVER_TYPE不能是NONE,应设为SELECT或SESSION - 若用 UCP,务必关闭隐式缓存:
setImplicitCachingEnabled(false),否则 FCF 事件触发后连接不会被及时清理
srvctl add service 后服务没起来,应用连不上怎么办?
srvctl add service 只注册元数据,不启动服务——这是绝大多数人报 ORA-12514 的根本原因。
- 先确认服务是否已启动:
srvctl status service -d <db_name> -s <service_name></service_name></db_name>;若显示 “not running”,必须手动执行srvctl start service -d <db_name> -s <service_name></service_name></db_name> - 再检查监听器是否识别该服务:
lsnrctl services <listener_name></listener_name>(默认监听器名通常是LISTENER) - 服务启动依赖实例在线,用
srvctl status instance -d <db_name></db_name>确认目标实例状态 - 业务连接必须用
SERVICE_NAME,别碰INSTANCE_NAME或SID;写INSTANCE_NAME会绕过 service 机制,彻底失去故障转移、TAF、CLB 等所有 RAC 能力
真正让 FAN 生效的关键点,往往卡在 ONS 跨节点通信验证和 service 的实际启动状态上——这两步跳过,后面所有 JDBC 配置都只是摆设。











