navicat填tns名称时,实际连接的是tnsnames.ora中该别名定义的首个可用节点,具体路由由oracle instant client解析并按failover_mode等参数执行负载均衡或故障转移。

Navicat 里填 TNS 名称时,实际连的是哪个节点?
Navicat 本身不解析 tnsnames.ora,它依赖 Oracle 客户端(如 Oracle Instant Client)完成 TNS 解析和连接路由。你填的 TNS_NAME 是传给客户端的字符串,最终由客户端根据本地 tnsnames.ora 文件里的定义决定连接行为——比如是否启用 LOAD_BALANCE=on、FAILOVER=on,以及列出的多个地址如何轮询或故障转移。
这意味着:TNS 连接能否真正实现 RAC 高可用,不取决于 Navicat 设置,而取决于你安装的 Oracle 客户端版本、tnsnames.ora 内容是否正确配置了多个实例地址和 failover 参数。
- 必须使用与 Navicat 架构一致的客户端(32 位 Navicat → 32 位 Instant Client);否则会报
can not load oci.dll 193 -
tnsnames.ora中每个ADDRESS应指向不同 RAC 节点的监听地址(非 SCAN IP),SCAN IP 在部分旧版客户端中支持不稳定 - 务必包含
FAILOVER_MODE=(TYPE=select)(METHOD=basic)(RETRIES=3)(DELAY=5),否则查询中断后不会自动切节点
在 Navicat 中启用 Oracle 客户端的具体路径设置
Navicat 不会自动找系统环境变量里的 ORACLE_HOME 或 TNS_ADMIN。你必须手动指定 Instant Client 的根目录,且该目录下需存在 tnsnames.ora 和 oci.dll(Windows)或 libclntsh.dylib(macOS)。
操作路径:连接 > Oracle > 高级 > 使用 Oracle 客户端 → 勾选并填写完整路径,例如:
C:\oracle\instantclient_21_12
这个路径下必须有:
-
tnsnames.ora(不能放在子目录,也不能用符号链接) -
oci.dll(Windows)或libclntsh.dylib(macOS) - 如果用了 Wallet 认证,还需
sqlnet.ora和 wallet 目录
填错路径或文件缺失,Navicat 会静默失败,只显示“连接被拒绝”或空白错误提示,不会说明是客户端加载问题。
tnsnames.ora 中 RAC 连接串的关键字段不能少
一个能支撑 RAC 故障切换的最小可用 TNS 条目,至少要包含两个 ADDRESS、CONNECT_DATA 的 SERVICE_NAME + FAILOVER_MODE。下面是一个生产环境验证过的模板:
MYRAC =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac-node1-vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = rac-node2-vip)(PORT = 1521))
(CONNECT_DATA =
(SERVICE_NAME = orcl)
(FAILOVER_MODE =
(TYPE = SELECT)
(METHOD = BASIC)
(RETRIES = 3)
(DELAY = 5)
)
)
)
注意几个易错点:
- 不要用 SCAN IP 替代节点 VIP,尤其在 Instant Client 21c 以前版本中,SCAN 解析可能失败
-
TYPE=SELECT表示只对查询类语句做重连;如果是 DML 报错,仍需应用层捕获并重试 - Navicat 执行长事务时若主节点宕机,当前连接会断开,但新查询会自动路由到存活节点——前提是你的 TNS 配置生效且客户端已加载
测试 RAC 故障转移是否真起作用
光看 Navicat “连接测试”成功没用,那只是建立初始连接。要验证高可用,得模拟真实故障场景:
- 在 Navicat 中执行一个持续 30 秒的
SELECT * FROM v$session查询 - 同时在 RAC 主节点上执行
srvctl stop instance -i orcl1 -d orcl - 观察 Navicat 查询是否中断;若未中断且返回结果,说明 FAILOVER_MODE 生效
- 再查
SELECT instance_name FROM v$instance,确认当前连接已落到另一个节点
很多团队卡在这一步才发现:TNS 配置写了 FAILOVER,但客户端没启用,或者 Navicat 没指向正确的 tnsnames.ora ——它根本就没读那个文件。











