tnsnames.ora中服务名必须与DB_UNIQUE_NAME逻辑一致、被lsnrctl status识别、且HOST/PORT与listener.ora匹配,RAC环境须用SCAN名并统一配置,Broker的CONNECT IDENTIFIER严格依赖该文件解析。

tnsnames.ora 文件里配错服务名,dgmgrl 就连不上备库,后续所有操作都会卡在“连接失败”或“ORA-12154: TNS:could not resolve the connect identifier”——这是最常见的起步拦路虎。配置本身不难,但必须和实际监听、数据库实例、Broker三者对齐。
tnsnames.ora 中主备服务名怎么写才有效?
服务名不是随便起的,它要被 lsnrctl status 看见、被 sqlplus /@service_name 连上、被 dgmgrl 识别为合法目标。关键点有三个:
- 每个数据库(主库和备库)都要在各自节点的
$ORACLE_HOME/network/admin/tnsnames.ora里定义对方的服务名,不能只配一边 - 服务名必须和
DB_UNIQUE_NAME保持逻辑一致(比如主库DB_UNIQUE_NAME=sales,对应服务名建议叫sales_svc,而不是sales或sales_primary) - HOST 地址必须是对方监听器实际运行的 IP 或主机名,且端口(
PORT=1521)与listener.ora中一致;如果用了 SCAN,就填 SCAN VIP,别填单节点 VIP
示例(主库节点上的 tnsnames.ora 片段):
SALESDR_SVC =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = standby-scan.example.com)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = salesdr_svc)
(UR=A)
)
)
注意 (UR=A):这是强制绕过 service registration 的关键,避免因监听未注册服务而连接失败。
为什么 dgmgrl connect sys@sales_svc 报 ORA-12514?
这个错误说明监听器收到了连接请求,但没找到对应的服务名注册项。常见原因不是服务名写错了,而是:
- 备库实例没启动,或者启动了但没注册到监听器(检查
alter system register;或重启监听) -
local_listener参数没设,导致实例启动后无法主动向监听注册(查show parameter local_listener) - 服务名在
tnsnames.ora里拼写和DGMGRL中用的不一致(比如大小写、下划线位置) - 主库和备库的
DB_DOMAIN不同,而服务名没带域名后缀(如sales_svc.example.com),导致解析失败
Broker 配置里 SERVICE 名字必须和 tnsnames.ora 一致吗?
必须一致。Broker 启动 LOG_ARCHIVE_DEST_n 时,会直接把你在 ADD DATABASE 命令里写的 SERVICE 当作 TNS 别名去解析。例如:
DGMGRL> ADD DATABASE salesdr AS PRIMARY DATABASE IS sales CONNECT IDENTIFIER IS salesdr_svc;
这里的 salesdr_svc 必须能在当前节点的 tnsnames.ora 中查到完整定义。Broker 不会自己拼接或补全,也不会读取 service_names 参数值。
另外注意:CONNECT IDENTIFIER 是 Broker 内部使用的逻辑标识,和数据库实际的 SERVICE_NAMES 参数无关,但它最终依赖的是本地 tnsnames.ora 解析结果。
RAC 环境下服务名要额外注意什么?
RAC 主库或备库都涉及多个实例和 SCAN,容易出问题:
- 不要用单节点 VIP 或 localhost,一律用 SCAN 名(如
primary-scan.example.com) - 确保所有 RAC 节点上的
tnsnames.ora内容完全一致,尤其是备库节点也要能解析主库 SCAN - 如果用了 Oracle ASM 存放密码文件,确认
remote_login_passwordfile=EXCLUSIVE且密码文件已同步到备库(否则sys@salesdr_svc会被拒绝) -
DB_UNIQUE_NAME和INSTANCE_NAME在 RAC 中可以不同,但 Broker 只认DB_UNIQUE_NAME,服务名应与其对齐
最省事的做法:在主备所有节点统一用 DB_UNIQUE_NAME + _svc 命名服务,并确保 tnsnames.ora 每处都严格一致——少一个字符,dgmgrl 就进不了下一步。


















