日前一次一个朋友装完一套rac后,客户端连接rac数据库时候报错,错误如下:
ORA-12545: Connect failed because target host or object does not exist./pre>
Rac的监听机制我就不解释了,12545的错误基本和Tnsnames里的连接通配符里的host设置有关,刚装完的rac报错,大部分都是因为采用了节点的hostname作为解析字符串中的host,而客户端一般从业务的连续冗余性角度应该要用vip对应的ip或者hostname来匹配网络连接字符串,这2者不一致导致了12545的出现;当然也有可能是设置了VIP,但是客户端与服务端的VIP无法通信,也会造成ora-12545的错误,这种情况是因为负载均衡打开来后,listener会分配新的请求进程到负载较低的节点,如果负载低的节点正好和客户端无法通信,就造成了12545的错误。现在问题基本上解决思路就有一些了,遇到rac的这个错误,首先就是检查你本机的local_listener,remote_listener是否设置的对应host为其他的错误的ip或者主机名,一般新装的rac这个一般都为localhost。明白了为题所在,解决思路也就出来了,只要把实例的local_listener设置为对应vip,客户端采用vip的解析方式即可解决,也应配合检查rac的配置以及TAF和LOAD BLANCE的开启情况。
这个情况一般出现在刚装完rac之后。报错如果采用trace level 16的跟踪可以发现类似如下的日志:
[05-APR-2004 11:32:55] nttbnd2addr: looking up IP addr for host: myhost.oracle.com [05-APR-2014 11:32:55] nttbnd2addr: *** hostname lookup failure! *** [05-APR-2014 11:32:55] nttbnd2addr: exit [05-APR-2014 11:32:55] nserror: nsres: id=0, op=77, ns=12545, ns2=12560; nt[0]=515, nt[1]=145, nt[2]=0; ora[0]=0, ora[1]=0, ora[2]=0 [05-APR-2014 11:32:55] nsmfr: 207 bytes at 0xf2a18 [05-APR-2014 11:32:55] nsmfr: 140 bytes at 0xef078 [05-APR-2014 11:32:55] nladtrm: entry [05-APR-2014 11:32:55] nladtrm: exit [05-APR-2014 11:32:55] nioqper: error from nscall [05-APR-2014 11:32:55] nioqper: nr err code: 0 [05-APR-2014 11:32:55] nioqper: ns main err code: 12545 [05-APR-2014 11:32:55] nioqper: ns (2) err code: 12560 [05-APR-2014 11:32:55] nioqper: nt main err code: 515 [05-APR-2014 11:32:55] nioqper: nt (2) err code: 145 [05-APR-2014 11:32:55] nioqper: nt OS err code: 0 [05-APR-2014 11:32:55] niomapnserror: entry [05-APR-2014 11:32:55] niqme: entry [05-APR-2014 11:32:55] niqme: reporting NS-12545 error as ORA-12545 [05-APR-2014 11:32:55] niqme: exit [05-APR-2014 11:32:55] niomapnserror: returning error 12545 [05-APR-2014 11:32:55] niomapnserror: exit [05-APR-2014 11:32:55] niotns: Couldn't connect, returning 12545 ...
正确的local_listener配置为如下:
alter system set local_listener='(ADDRESS =(PROTOCOL=TCP)(HOST=vip_host1)(PORT=1521))' scope=both sid='luda1'; alter system set local_listener='(ADDRESS =(PROTOCOL=TCP)(HOST=vip_host2)(PORT=1521))' scope=both sid='luda2';
客户端采用VIP的解析方式:
LUDA = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = vip_host1)(PORT = 1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = vip_host2)(PORT = 1521)) (LOAD_BALANCE=YES) (CONNECT_DATA= (SERVER=DEDICATED) (SERVICE_NAME=LUDA) ) )