fan不是开箱即用功能,必须显式配置ons(由crs启动且跨节点互通)、数据库服务(启用fan且failover_type为select/session)及客户端(fanenabled=true、禁用tns干扰参数、ucp需额外设置),三者缺一不可。
fan 不是开箱即用的功能,必须显式配置 ons、服务、客户端三端,缺一不可;只配 jdbc 连接字符串里的 fanenabled=true 会完全失效。
ONS 必须由 CRS 管理启动,且跨节点互通
手动运行 onsctl start 或依赖本地进程响应(如 onsctl ping 成功)不代表 FAN 可用。ONS 是集群级服务,必须由 Oracle Clusterware 统一管控:
-
crsctl start resource ora.ons是唯一合规启动方式;手动启动的 ONS 使用错误的$ORACLE_HOME,无法接收 RAC 内部事件 - 验证互通不能只跑
onsctl ping,必须逐节点执行:onsctl ping -h node2 -p 6113(端口需与$CRS_HOME/opmn/conf/ons.config中remoteport一致) - 所有节点的
localport不能冲突(默认 6113),否则$CRS_HOME/log/<host>/client/ons.log</host>会出现Connection refused或Failed to connect to remote host
数据库服务必须启用 FAN 且 failover_type 合法
FAN 事件只从启用了 FAN 的 service 发出,不是所有 service 都默认支持:
- 查服务状态:
srvctl config service -d <db></db>,确认目标 service 的ENABLED列为YES - service 的
FAILOVER_TYPE必须设为SELECT或SESSION;NONE会彻底屏蔽 FAN 事件 - 创建或修改 service 时需显式指定:
srvctl modify service -d <db> -s <svc> -f -y SELECT</svc></db>(-f表示启用 FAN)
JDBC 客户端启用 FCF 的关键参数组合
FCF 不是“自动重连”,而是事件驱动的连接池自愈,配置错一个参数就退化为普通轮询:
- 必须显式设置:
connection.setProperty("oracle.jdbc.fanEnabled", "true");仅在连接字符串加FAILOVER=ON无效,且会干扰 FCF 路径 - 禁用 TNS 层干扰:
LOAD_BALANCE=ON和FAILOVER=ON不能出现在连接字符串中,尤其在 SCAN 场景下会导致连接被路由到已宕机实例 - 若用 UCP(Universal Connection Pool),还需调用:
pool.setFastConnectionFailoverEnabled(true),并禁用隐式缓存:pool.setImplicitCachingEnabled(false) - 确保 classpath 包含
simplefan.jar或ons.jar;缺失则fanEnabled=true静默失败
验证 FAN 是否真正生效的三个硬指标
不要依赖日志里“ONS connected”这种模糊提示,要抓实际事件流:
- 在客户端机器运行
fanwatcher工具,观察是否收到FANHA类事件(如DOWN/UP);没输出说明 ONS 未通或 service 未启用 FAN - 模拟实例宕机(
srvctl stop instance -i <inst> -d <db></db></inst>),检查应用连接池是否在 2–5 秒内清理失效连接并建立新会话——超时或卡住说明 FCF 未触发 - 查数据库侧:
select * from gv$session where username = '...' and status = 'INACTIVE',若故障后仍存在大量 stale session,基本可判定 FAN 事件未送达客户端
最容易被忽略的是 ONS 的启动方式和 service 的 -f 标志:前者决定事件能否发出,后者决定事件是否生成。这两步任一遗漏,后续所有客户端配置都只是无意义的空转。











