Oracle RAC透明切换依赖客户端配置而非数据库自动接管,必须启用FAN和TAF、使用SCAN地址、禁用连接池主动验证,并区分SELECT与DML场景。
Oracle RAC透明切换依赖的是客户端连接层,不是数据库自动“接管”
oracle rac 本身不提供应用侧的“无缝切换”——它只保证实例故障时服务仍可用;真正实现连接自动重路由、sql 不中断重试、事务不报错,靠的是客户端配置。如果应用直连单个 vip 或用 jdbc:oracle:thin:@host:1521:orcl 这种硬编码方式,rac 故障时必然报 io error: connection reset 或 ora-01033: oracle initialization or shutdown in progress,根本谈不上透明。
关键判断:是否启用 Oracle Net 的 Fast Application Notification(FAN)和 Transparent Application Failover(TAF),并配合连接池正确解析 SCAN 和 VIP 列表。
必须用 SCAN 地址 + TAF 配置,不能只靠 JDBC URL 拼接多个 host
SCAN(Single Client Access Name)是 RAC 对外统一入口,DNS 解析为 3 个 VIP(默认),客户端通过它才能动态感知节点增减和状态变化。只写死多个 IP 或 host,在节点宕机后 DNS 缓存未过期时仍会尝试连已下线节点,导致超时或失败。
实操建议:
- 数据库连接字符串必须基于 SCAN,例如:
jdbc:oracle:thin:@scan.example.com:1521/ORCL(注意用/ORCL而非:ORCL,这是服务名模式,支持动态服务注册) - 在
tnsnames.ora中显式定义含 TAF 的条目(即使应用用 JDBC,部分驱动仍读取该文件):(DESCRIPTION= (ADDRESS=(PROTOCOL=TCP)(HOST=scan.example.com)(PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=ORCL)(FAILOVER_MODE=(TYPE=SELECT)(METHOD=BASIC)(RETRIES=180)(DELAY=5))) )
- JDBC 连接池(如 HikariCP、Druid)需开启 Oracle 特定参数:
oracle.net.disableOob=true(避免紧急中断干扰 TAF)、oracle.jdbc.fanEnabled=true(启用 FAN 事件监听)
HikariCP / Druid 连接池必须关闭“连接有效性验证”,改用 Oracle FAN 通知
很多团队习惯在连接池里配 connection-test-query=SELECT 1 FROM DUAL 或 validation-timeout,这在 RAC 切换瞬间反而造成雪崩:所有连接并发探测,加重故障节点负担,且无法区分“临时网络抖动”和“实例已死”。Oracle 推荐路径是关闭主动探测,信任 FAN 发出的 UP/DOWN 事件来清理连接。
实操建议:
- HikariCP 中禁用验证:
connection-test-query留空,connection-timeout设为 30000,validation-timeout设为 3000 - Druid 中设置:
testWhileIdle=false、testOnBorrow=false、testOnReturn=false,同时开启useOracleUCP=true(若集成 Oracle UCP 库) - 确保应用 classpath 包含
ojdbc8.jar(≥12.2)和simplefan.jar(FAN 支持必需)
TAF 只对 SELECT 有效,UPDATE/DELETE/INSERT 默认不重试,事务需应用层兜底
这是最容易被忽略的盲区:FAILOVER_MODE=(TYPE=SELECT) 是默认且最安全的配置,但它的含义很明确——仅对纯查询语句做会话级重连与结果集续读;一旦执行了 DML 或开启了事务,TAF 不会帮你回滚或重放,连接断开后直接抛 SQLException。也就是说,“透明”是有边界的。
实操建议:
- 业务上区分“只读场景”和“读写场景”:报表类请求走 TAF+SELECT 模式;订单类请求必须自行捕获
SQLState=60(ORA-03113/ORA-03114)等错误,触发本地重试逻辑(带幂等 key) - 不要依赖 TAF 实现分布式事务一致性;RAC 内部用 Cache Fusion 同步数据块,但跨实例的事务提交仍受
commit_write和网络延迟影响 - 监控项要包含
DBA_FAN_LOG_HISTORY视图,确认 FAN 事件是否真实送达应用节点(常因防火墙拦截 UDP 5800 端口而静默失败)
真正落地时,90% 的“切换不透明”问题出在连接池没关掉健康检查、SCAN DNS TTL 设得过大、或者忘了部署 simplefan.jar。FAN 不是开关一开就生效的魔法,它是一套需要端到端验证的事件链路。


















