有时候希望连接RAC数据库时,只连接到其中某个实例。但是要实现这个目的,并不是仅仅通过设置TNSNAMES.ORA中服务名地址列表就可以实现的。
这篇描述通过INSTANCE_NAME来实现目标。
测试环境10.2.0.3 Rac for Solaris for sparc 64:
SQL> SELECT NAME FROM V$DATABASE;
NAME
---------
TESTRAC
SQL> SELECT INSTANCE_NUMBER, INSTANCE_NAME FROM V$INSTANCE;
INSTANCE_NUMBER INSTANCE_NAME
--------------- ----------------
1 testrac1
SQL> SELECT INSTANCE_NUMBER, INSTANCE_NAME FROM GV$INSTANCE;
INSTANCE_NUMBER INSTANCE_NAME
--------------- ----------------
1 testrac1
2 testrac2
为了避免出现ORA-12545错误,在两个节点分别设置了LOCAL_LISTENER初始化参数:
SQL> ALTER SYSTEM
2 SET LOCAL_LISTENER = '(ADDRESS = (PROTOCOL = TCP)(HOST = 172.25.198.224)(PORT = 1521))'
3 SID = 'testrac1';
系统已更改。
节点2:
SQL> SELECT INSTANCE_NAME FROM V$INSTANCE;
INSTANCE_NAME
----------------
testrac2
SQL> ALTER SYSTEM
2 SET LOCAL_LISTENER = '(ADDRESS = (PROTOCOL = TCP)(HOST = 172.25.198.225)(PORT = 1521))'
3 SID = 'testrac2';
系统已更改。
分别检查两个节点上LISTENER相关的配置,节点1:
SQL> SHOW PARAMETER LISTENER
NAME TYPE VALUE
---------------- ----------- ------------------------------
local_listener string (ADDRESS = (PROTOCOL = TCP)(HOST = 172.25.198.224)(PORT = 1521))
remote_listener string LISTENERS_TESTRAC
节点2:
SQL> SHOW PARAMETER LISTENER
NAME TYPE VALUE
---------------- ----------- ------------------------------
local_listener string (ADDRESS = (PROTOCOL = TCP)(HOST = 172.25.198.225)(PORT = 1521))
remote_listener string LISTENERS_TESTRAC
其中REMOTE_LISTENER设置的值是TNSNAMES.ORA中配置的服务名,节点1上的TNSNAMES.ORA配置为:
LISTENER_TESTRAC2 =
(ADDRESS = (PROTOCOL = TCP)(HOST = racnode2-vip)(PORT = 1521))
LISTENER_TESTRAC1 =
(ADDRESS = (PROTOCOL = TCP)(HOST = racnode1-vip)(PORT = 1521))
TESTRAC2 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = racnode2-vip)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = testrac)
(INSTANCE_NAME = testrac2)
)
)
TESTRAC1 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = racnode1-vip)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = testrac)
(INSTANCE_NAME = testrac1)
)
)
TESTRAC =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = racnode1-vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = racnode2-vip)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = testrac)
)
)
LISTENERS_TESTRAC =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = racnode1-vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = racnode2-vip)(PORT = 1521))
)
节点2上的TNSNAMES.ORA配置为:
LISTENER_TESTRAC2 =
(ADDRESS = (PROTOCOL = TCP)(HOST = racnode2-vip)(PORT = 1521))
LISTENER_TESTRAC1 =
(ADDRESS = (PROTOCOL = TCP)(HOST = racnode1-vip)(PORT = 1521))
TESTRAC2 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = racnode2-vip)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = testrac)
(INSTANCE_NAME = testrac2)
)
)
TESTRAC1 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = racnode1-vip)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = testrac)
(INSTANCE_NAME = testrac1)
)
)
TESTRAC =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = racnode1-vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = racnode2-vip)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = testrac)
)
)
LISTENERS_TESTRAC =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = racnode1-vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = racnode2-vip)(PORT = 1521))
)
在本地测试连接,本地TNSNAMES.ORA文件中TESTRAC服务名配置为:
TESTRAC =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.25.198.224)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.25.198.225)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = TESTRAC)
)
)
下面尝试多次连接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
----------------
testrac2
将TESTRAC配置中的地址去掉一个,结果仍然如此:
TESTRAC =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.25.198.224)(PORT = 1521))
)
(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
----------------
testrac2
可以看到,即使TNSNAMES.ORA中配置了一个节点的地址,通过这个服务名访问RAC数据库,还是可能连接到两个实例上的。
为了确保通过服务名只连接到一个实例,需要在CONNECT_DATA中不仅仅指定SERVICE_NAME,同时还需要指定INSTANCE_NAME参数:
TESTRAC =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.25.198.224)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = TESTRAC)
(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
SQL> CONN YANGTK/YANGTK@TESTRAC
已连接。
SQL> SELECT INSTANCE_NAME FROM V$INSTANCE;
INSTANCE_NAME
----------------
testrac1
oracle视频教程请关注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html