首页 > 数据库 > Oracle > RAC连接中TNSNAMES需注意的问题
Oracle RAC中的LOAD_BALANCE参数和FAILOVER参数的默认值为。
LOAD_BALANCE参数:在DESCRIPTION_LIST层为ON,而在DESCRIPTION和ADDRESS_LIST默认值都是OFF。
FAILOVER参数:在DESCRIPTION_LIST、DESCRIPTION和ADDRESS_LIST层的默认值都是ON;
注意这些参数的默认值可能会帮助你避免一些”奇怪”的问题。
[@more@]1、指定了INSTANCE_NAME参数仍然会连接到两个实例上
DFKZYK1 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.31)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.32)(PORT = 1521))
(LOAD_BALANCE = ON)
)
(CONNECT_DATA =
(SERVICE_NAME = DFKZYK)
(INSTANCE_NMAE = DFKZYK1)
)
)
下面测试连接:
SQL> CONN SYS/TANGYUN@DFKZYK1
已连接。
SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
dfkzyk2
SQL> CONN SYS/TANGYUN@DFKZYK1
已连接。
SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
dfkzyk2
SQL> CONN SYS/TANGYUN@DFKZYK1
已连接。
SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
dfkzyk1
这个问题也是一次偶然的发现,明明配的是实例1却连接到实例2上去。之前一直都是这样配都没有出现过这样的问题,想了很多种可能性,还是没有想明白为什么,最后细细检查才发现是INSTANCE_NAME写成了INSTANCE_NMAE,参数写错了,但是Oracle却没有检查错误,而是直接忽略掉这个参数,导致问题很难被发现。
2、LOAD_BALANCE参数的没有起作用
DFKZYK =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.31)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.32)(PORT = 1521))
)
(LOAD_BALANCE = ON)
(CONNECT_DATA =
(SERVICE_NAME = DFKZYK)
)
)
数据库的LOCAL_LISTENER参数设置已经被取消:
SQL> CONN SYS/TANGYUN@DFKZYK
已连接。
SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
dfkzyk2
SQL> SHOW PARAMETER LOCAL_LISTENER;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
local_listener string
SQL> CONN SYS/TANGYUN@DFKZYK
已连接。
SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
dfkzyk1
SQL> SHOW PARAMETER LOCAL_LISTENER;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
local_listener string
在不设置LOCAL_LISTENER参数偶尔会出现连接失败,LOAD_BALANCE参数设置没有生效,无论设置为ON或OFF,都不会影响数据库的连接。测试了多次后才注意到,LOAD_BALANCE参数添加位置错误,这里使用了ADDRESS_LIST并添加了括号,而LOAD_BALANCE参数没有放到括号中,使得这个设置对于ADDRESS_LIST中的配置无效,而默认LOAD_BALANCE为ON,因此LOAD_BALANCE设置仍然可以生效。
正确的设置应该是:
DFKZYK =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.31)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.32)(PORT = 1521))
(LOAD_BALANCE = ON)
)
(CONNECT_DATA =
(SERVICE_NAME = DFKZYK)
)
)
需要注意的是,不仅LOAD_BALANCE参数,FAILOVER参数也有生效区间的问题,这两个参数在DESCRIPTION_LIST、DESCRIPTION和ADDRESS_LIST三个层面都可以生效,因此在设置参数的时候一点要注意是否参数设置在指定层面上。
当服务名同时配置了LOAD_BALANCE和FAILOVER时:
DFKZYK =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.31)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.32)(PORT = 1521))
(LOAD_BALANCE = ON)
(FAILOVER=OFF)
)
(CONNECT_DATA =
(SERVICE_NAME = DFKZYK)
)
)
且配置LOCAL_LISTENER参数时。
SQL> CONN SYS/TANGYUN@DFKZYK
已连接。
SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
dfkzyk2
SQL> SHOW PARAMETER LOCAL_LISTENER;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
local_listener string NODE2
SQL> CONN SYS/TANGYUN@DFKZYK
已连接。
SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
dfkzyk1
SQL> SHOW PARAMETER LOCAL_LISTENER;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
local_listener string NODE1
数据库服务器上两个节点的TNSNAMES中NODE1(节点1)和NODE2(节点2)中的配置均为:
NODE1/NODE2 =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = node1-vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = node2-vip)(PORT = 1521))
)
当实例1宕机时并不出现问题,但是当实例1没有问题,但是监听宕掉时,这个服务名的配置可能会偶尔连接不上:
SQL> CONN SYS/TANGYUN@DFKZYK
ERROR:
ORA-12541: TNS: 无监听程序
警告: 您不再连接到 ORACLE。
SQL> CONN SYS/TANGYUN@DFKZYK
已连接。
SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
dfkzyk2
SQL> CONN SYS/TANGYUN@DFKZYK
已连接。
SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
dfkzyk2
SQL> CONN SYS/TANGYUN@DFKZYK
ERROR:
ORA-12541: TNS: 无监听程序
警告: 您不再连接到 ORACLE。
导致这个问题的原因是由于配置LOCAL_LISTENER后,虽然实例1对应节点的监听关闭,但是实例2所在节点的监听仍然包含实例2上的信息,因此连接时负载均衡仍然会考虑实例1,当节点2上的监听将连接发到节点1的监听时碰到了错误,而静态FAILOVER又没有启动,因此出现了错误。
这种情况下,如果修改服务名设置FAILOVER为ON,那么可以避免错误的产生:
DFKZYK =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.31)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.48.1.32)(PORT = 1521))
(LOAD_BALANCE = ON)
(FAILOVER=ON)
)
(CONNECT_DATA =
(SERVICE_NAME = DFKZYK)
)
)
这样,仍然有部分连接会尝试实例1,但是在碰到错误后,会自动连接到实例2上。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/24930246/viewspace-1041678/ ,如需转载,请注明出处,否则将追究法律责任。