其实谈不上是陷阱,只是不注意的话,很容易出现配置错误。

这一篇介绍LOAD_BALANCE和FAILOVER配合可能导致的错误。


当服务名同时配置了LOAD_BALANCE和FAILOVER时:

TESTRAC =

 (DESCRIPTION =

   (ADDRESS_LIST =

     (ADDRESS = (PROTOCOL = TCP)(HOST = 172.25.198.224)(PORT = 1521))

     (ADDRESS = (PROTOCOL = TCP)(HOST = 172.25.198.225)(PORT = 1521))

     (LOAD_BALANCE = ON)

     (FAILOVER = OFF)

   )

   (CONNECT_DATA =

     (SERVICE_NAME = TESTRAC)

   )

 )

且配置了REMOTE_LISTENER参数:

SQL> SELECT INSTANCE_NAME FROM V$INSTANCE;

INSTANCE_NAME

----------------

testrac1

SQL> SHOW PARAMETER REMOTE_LISTENER

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

remote_listener                      string      LISTENERS_TESTRAC

检查实例2:

SQL> SELECT INSTANCE_NAME FROM V$INSTANCE;

INSTANCE_NAME

----------------

testrac2

SQL> SHOW PARAMETER REMOTE_LISTENER

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

remote_listener                      string      LISTENERS_TESTRAC

数据库服务器上两个节点的TNSNAMES中LISTENERS_TESTRAC的配置均为:

LISTENERS_TESTRAC =

 (ADDRESS_LIST =

   (ADDRESS = (PROTOCOL = TCP)(HOST = racnode1-vip)(PORT = 1521))

   (ADDRESS = (PROTOCOL = TCP)(HOST = racnode2-vip)(PORT = 1521))

 )

当实例2被关闭,并不会导致连接错误:

bash-2.03$ srvctl stop inst -d testrac -i testrac2

连接服务名:

SQL> CONN YANGTK/YANGTK@TESTRAC

已连接。

SQL> SELECT INSTANCE_NAME FROM V$INSTANCE;

INSTANCE_NAME

----------------

testrac1

SQL> CONN YANGTK/YANGTK@TESTRAC

已连接。

SQL> SELECT INSTANCE_NAME FROM V$INSTANCE;

INSTANCE_NAME

----------------

testrac1

SQL> CONN YANGTK/YANGTK@TESTRAC

已连接。

SQL> SELECT INSTANCE_NAME FROM V$INSTANCE;

INSTANCE_NAME

----------------

testrac1

但是如果实例2没有问题,只是实例2的监听关闭,那么这个服务名的配置可能会导致错误:

bash-2.03$ srvctl start inst -d testrac -i testrac2

bash-2.03$ srvctl stop listener -n racnode2

再次测试连接:

SQL> CONN YANGTK/YANGTK@TESTRAC

已连接。

SQL> SELECT INSTANCE_NAME FROM V$INSTANCE;

INSTANCE_NAME

----------------

testrac1

SQL> CONN YANGTK/YANGTK@TESTRAC

ERROR:

ORA-12541: TNS:无监听程序


警告:您不再连接到ORACLE。

SQL> CONN YANGTK/YANGTK@TESTRAC

ERROR:

ORA-12541: TNS:无监听程序


SQL> CONN YANGTK/YANGTK@TESTRAC

已连接。

SQL> SELECT INSTANCE_NAME FROM V$INSTANCE;

INSTANCE_NAME

----------------

testrac1

导致这个问题的原因是由于配置REMOTE_LISTENER后,虽然实例2对应节点的监听关闭,但是实例1所在节点的监听仍然包含实例2上的信息,因此连接时负载均衡仍然会考虑实例2,当节点1上的监听将连接发到节点2的监听时碰到了错误,而静态FAILOVER又没有启动,因此出现了错误。

这种情况下,如果修改服务名设置FAILOVER为ON,那么可以避免错误的产生:

TESTRAC =

 (DESCRIPTION =

   (ADDRESS_LIST =

     (ADDRESS = (PROTOCOL = TCP)(HOST = 172.25.198.224)(PORT = 1521))

     (ADDRESS = (PROTOCOL = TCP)(HOST = 172.25.198.225)(PORT = 1521))

     (LOAD_BALANCE = ON)

     (FAILOVER = ON)

   )

   (CONNECT_DATA =

     (SERVICE_NAME = TESTRAC)

   )

 )

测试连接:

SQL> CONN YANGTK/YANGTK@TESTRAC

已连接。

SQL> SELECT INSTANCE_NAME FROM V$INSTANCE;

INSTANCE_NAME

----------------

testrac1

SQL> CONN YANGTK/YANGTK@TESTRAC

已连接。

SQL> SELECT INSTANCE_NAME FROM V$INSTANCE;

INSTANCE_NAME

----------------

testrac1

SQL> CONN YANGTK/YANGTK@TESTRAC

已连接。

SQL> SELECT INSTANCE_NAME FROM V$INSTANCE;

INSTANCE_NAME

----------------

testrac1

这时,仍然有部分连接会尝试实例2,但是在碰到错误后,会自动连接到实例1上。



oracle视频教程请关注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html