其实谈不上是陷阱,只是不注意的话,很容易出现配置错误。
这一篇介绍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