在使用Oracle数据库进行跨库操作的时候,数据链是常见的实现方式,但不少用户都遇到过使用数据链时报错ORA-12545或者TNS-12545的情况,这类错误会直接阻断跨库查询、数据同步等业务的执行。下面我们先来看这类错误的基本信息,再学习如何重现和解决。

错误基本信息
ORA-12545和TNS-12545本质是同一类错误,官方描述为Connect_failed_because_target_host_or_object_does_not_exist,翻译过来就是连接失败,因为目标主机或者对象不存在。常见触发场景包括目标数据库服务未启动、网络不通、TNS配置错误、数据链指向的配置有误等。
问题重现步骤
要稳定重现这个错误,可以按照以下步骤操作,环境需要准备两台可以互相网络通信的Oracle数据库服务器,分别为本地库和目标库。
场景一:目标服务未启动导致报错
我们先确认目标库的服务是正常运行的,然后执行以下步骤:
- 登录本地Oracle数据库,使用sys用户或者有权限的用户操作
- 先创建一个指向目标库的数据链,配置正确的TNS别名
- 停止目标库的监听服务和数据库实例服务
- 在本地库执行跨库查询,比如查询目标库的dual表
此时就会触发ORA-12545/TNS-12545错误,错误提示类似:
ORA-12545: 连接失败,因为目标主机或对象不存在 ORA-12545: Connect failed because target host or object does not exist
场景二:TNS配置错误导致报错
如果目标库服务正常运行,但是TNS配置有误,也可以复现该错误:
- 登录本地数据库服务器,修改tnsnames.ora文件,将目标库的TNS别名对应的HOST改成不存在的IP地址,或者PORT改成目标库未监听的端口
- 保存tnsnames.ora文件,不需要重启本地监听,Oracle会动态读取配置
- 在本地库执行跨库查询操作
同样会触发ORA-12545/TNS-12545错误。
解决方法
针对不同的触发原因,我们可以采用对应的解决方式,按照以下顺序排查效率更高。
第一步:检查目标库服务状态
先登录目标数据库服务器,检查数据库实例和监听服务是否正常运行:
-- 检查监听状态 lsnrctl status -- 检查数据库实例状态 sqlplus / as sysdba select status from v$instance;
如果监听未启动,执行lsnrctl start启动监听;如果数据库实例未启动,执行startup启动实例。启动后回到本地库重新测试数据链。
第二步:检查网络连通性
如果目标服务正常,需要检查本地库到目标库的网络是否通畅,使用ping命令测试IP连通性,使用telnet命令测试端口连通性:
-- 测试IP连通性,替换为目标库实际IP ping 192.168.0.100 -- 测试端口连通性,替换为目标库实际端口,默认1521 telnet 192.168.0.100 1521
如果ping不通,检查防火墙规则、网络路由是否正确;如果端口不通,检查目标库监听配置的端口是否和测试的一致,防火墙是否放通了对应端口。
第三步:校核TNS配置
登录本地数据库服务器,查看tnsnames.ora文件,确认目标库的TNS配置是否正确,重点关注以下参数:
| 参数 | 说明 |
|---|---|
| HOST | 目标数据库的IP地址或者主机名,主机名需要确保本地可以解析 |
| PORT | 目标数据库监听的端口,需要和目标库监听配置的端口一致 |
| SERVICE_NAME | 目标数据库的服务名,需要和目标库配置的服务名一致,不要和SID混淆 |
修改完tnsnames.ora后,可以使用tnsping命令测试TNS配置是否生效:
-- 替换为目标库的TNS别名 tnsping target_db
如果tnsping返回成功,说明TNS配置正确,否则需要重新调整配置。
第四步:检查数据链配置
如果以上都正常,需要检查本地库的数据链配置是否正确,查询数据链的定义:
-- 查询当前用户下的数据链 select db_link, username, host from user_db_links; -- 如果是管理员,可以查询所有数据链 select owner, db_link, username, host from dba_db_links;
确认数据链的host字段对应的TNS别名是否存在且配置正确,如果数据链使用的是完整连接描述符而不是TNS别名,检查描述符里的参数是否和TNS配置一致。如果需要修改数据链,可以先删除再重建:
-- 删除数据链,替换为实际的数据链名称 drop database link test_link; -- 重建数据链,替换为实际参数 create database link test_link connect to target_user identified by target_password using 'target_tns_alias';
第五步:检查权限配置
如果以上步骤都没有问题,还需要确认连接目标库的用户是否有对应的权限,目标库的用户需要有被访问对象的查询或者操作权限,同时本地库的用户需要有创建和使用数据链的权限。如果权限不足,需要在对应库给用户授权:
-- 目标库给用户授权,比如授权查询某张表 grant select on target_table to target_user; -- 本地库给用户授权创建数据链 grant create database link to local_user;
验证解决结果
完成以上所有排查和修改后,在本地库重新执行跨库查询,验证数据链是否可以正常使用:
-- 替换为实际的数据链名称和表名 select * from dual@test_link;
如果查询返回正常结果,说明ORA-12545/TNS-12545错误已经解决,数据链可以正常使用。