您在这里:首页 > 学员专区 > 技术文章
Oracle视频
Oracle
CUUG课程

Oracle RAC 环境下的连接管理(二)


三、接着介绍 Connect Time Load Balancing

Connect Time Load Balancing 就是指不从连接池中取得已有连接,而是直接连接 Oracle 数据库时的 Load Balance。Connect Time Load Balancing 又细分为两种,分别是客户端的 Connect Time Load Balancing 和 Server 端的 Connect Time Load Balancing。

Oracle RAC 11gR2 之前,客户端的 Connect Time Load Balancing 非常容易实现,只需要在相关的 tnsnames.ora 中指定多个 vip,同时指定 LOAD_BALANCE=ON 就好了。如下所示:

(DESCRIPTION=

(ADDRESS_LIST=

(LOAD_BALANCE=ON)

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

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

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

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

(CONNECT_DATA=(SERVICE_NAME=RAC10g))

这样客户端在连接的时候,会随机地从上述 4 个 VIP 地址中选一个来连接 Oracle 数据库以达到 Load Balance 的目的。

之前已经提到,Oracle RAC 11gR2 中引入了 SCAN(Single Client Access Name),并且客户端缺省是通过 SCAN 来连接整个 RAC 环境的,如果使用了 DNS 或者 GNS (Grid Naming Service),那么最多可以有 3 个 SCAN VIP 和 3 个 SCAN Listener;如果没有使用 DNS 或者 GNS,而是选择使用 hosts 文件,则只会有 1 个 SCAN VIP 和 1 个 SCAN Listener。

这里假设你在 tnsnames.ora 中这样配置:

(DESCRIPTION =

(LOAD_BALANCE=ON)

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

(CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME =RAC11g)))

严格意义上说,只有在 RAC 环境有 1 个以上 SCAN VIP 的时候,上述 LOAD_BALANCE=ON 才有意义——它表示的是客户端在连接 Oracle 11gR2 RAC 的时候,会随机的选择三个 SCAN VIP 中的一个来连接,所以 Oracle 11gR2 RAC 的客户端 Connect Time Load Balancing 实际上是针对 SCAN VIP 而言的,而不是像 Oracle RAC 10gR2 /9iR2 那样直接针对 RAC 节点的 VIP(Oracle RAC 9iR2 里没有 VIP,此时 Connect Time Load Balancing 是针对 public ip)。

当使用了 hosts 文件来指定 SCAN VIP 的时候,客户端 Connect Time Load Balancing 实际上是不存在的,因为现在整个 RAC 环境只有 1 个 SCAN VIP。

现在再来介绍一下 Server 端的 Connect Time Load Balancing。Server 端的 Connect Time Load Balancing 相对来说要复杂一些,下面针对 Oracle 数据库不同的版本来分别加以说明。

首先要说明的是:无论是 Oracle RAC 9iR2/10gR2,还是 Oracle RAC 11gR2,它们的 Server 端 Connect Time Load Balancing 都是通过联合使用 local_listener 和 remote_listener 来实现的。

先来介绍 Oracle RAC 9iR2 下的 Server 端 Connect Time Load Balancing:

这里假设是一个 4 节点的 Oracle RAC 9iR2,tnsnames.ora 中的连接串是如下这样:

(DESCRIPTION=

(FAILOVER=ON)

(ADDRESS_LIST=

(LOAD_BALANCE=ON)

(ADDRESS=(PROTOCOL=TCP)(HOST=RAC1-ip)(PORT=1521))

(ADDRESS=(PROTOCOL=TCP)(HOST=RAC2-ip)(PORT=1521))

(ADDRESS=(PROTOCOL=TCP)(HOST=RAC3-ip)(PORT=1521))

(ADDRESS=(PROTOCOL=TCP)(HOST=RAC4-ip)(PORT=1521))

(CONNECT_DATA=(SERVICE_NAME=RAC9i))

再在各个节点的 tnsnames.ora 中加入如下设置:

LISTENER_RAC1 =

(ADDRESS = (PROTOCOL = TCP)(HOST = RAC1-ip)(PORT = 1521))

LISTENER_RAC2 =

(ADDRESS = (PROTOCOL = TCP)(HOST = RAC2-ip)(PORT = 1521))

LISTENER_RAC3 =

(ADDRESS = (PROTOCOL = TCP)(HOST = RAC3-ip)(PORT = 1521))

LISTENER_RAC4 =

(ADDRESS = (PROTOCOL = TCP)(HOST = RAC4-ip)(PORT = 1521))

LISTENERS_RAC =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = RAC1-ip)(PORT = 1521))

(ADDRESS = (PROTOCOL = TCP)(HOST = RAC2-ip)(PORT = 1521))

(ADDRESS = (PROTOCOL = TCP)(HOST = RAC3-ip)(PORT = 1521))

(ADDRESS = (PROTOCOL = TCP)(HOST = RAC4-ip)(PORT = 1521))

然后只需要在初始化参数文件里加入如下设置就能实现 Server 端 Connect Time Load Balancing 了:

RAC1.local_listener=LISTENER_RAC1

RAC2.local_listener=LISTENER_RAC2

RAC3.local_listener=LISTENER_RAC3

RAC4.local_listener=LISTENER_RAC4

*.remote_listener=LISTENERS_RAC

当做了上述设置后,上述 4 个节点的 listener 实际上除了知道本节点负载的情况之外,同时也知道了其余节点的负载情况。所以当先经过一层客户端的 Connect Time Load Balancing,比如这里随机地连到了第二个节点上的 listener(即 LISTENER_RAC2)上,当 LISTENER_RAC2 发现自身的负载较高,是有可能把你的连接请求转移(redirect)到其余负载较低的节点的 listener 上的——这就是所谓的第二层 Load Balancing,也就是 server 端的 Connect Time Load Balancing。

Oracle RAC 9iR2 里 server 端的 Connect Time Load Balancing 的依据是各节点 CPU 的负载(CPU runqueue-based load)或各节点所连接的 session 的数量。我们可以在相应节点的 listener.ora 中通过参数 prefer_least_loaded_node_<LISTENER_NAME>来控制 Oracle RAC 9iR2 数据库到底采用哪种判断依据。prefer_least_loaded_node_ <LISTENER_NAME>的默认值是 on,意味着 Listener 会把连接转移(redirect)到 CPU 负载较低的节点,即这种情况下判断负载的依据是各节点 CPU 的负载情况;如果把它设为 off,则意味着 Listener 在转移(redirect)连接的时候会考虑各个节点已连接 session 的数量并且会尽量保证各个节点所连接 session 数量的均衡,即这种情况下判断负载的依据是各节点已连接 session 的数量。

接着再来看 Oracle RAC 10gR2 下的 Server 端 Connect Time Load Balancing。Oracle RAC 10gR2 里 Server 端 Connect Time Load Balancing 也是通过联合使用 local_listener 和 remote_listener 来实现的,只不过 Oracle RAC 10gR2 里引入了 VIP,所以这里 local_listener 和 remote_listener 一定是要监听 VIP,而不是像 Oracle RAC 9iR2 那样监听 public ip 了。

这里假设是一个 4 节点的 Oracle RAC 10gR2,tnsnames.ora 中的连接串是如下所示(注意这里的连接地址已经是 VIP 了):

(DESCRIPTION=

(FAILOVER=ON)

(ADDRESS_LIST=

(LOAD_BALANCE=ON)

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

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

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

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

(CONNECT_DATA=(SERVICE_NAME=RAC10g))

再在各个节点的 tnsnames.ora 中加入如下设置(注意这里监听的已经是 VIP了):

LISTENER_RAC1 =

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

LISTENER_RAC2 =

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

LISTENER_RAC3 =

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

LISTENER_RAC4 =

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

LISTENERS_RAC =

(ADDRESS_LIST =

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

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

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

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

然后只需要在初始化参数文件里加入如下设置就能实现 Server 端 Connect Time Load Balancing 了:

RAC1.local_listener=LISTENER_RAC1

RAC2.local_listener=LISTENER_RAC2

RAC3.local_listener=LISTENER_RAC3

RAC4.local_listener=LISTENER_RAC4

*.remote_listener=LISTENERS_RAC

当做了上述设置后,与 Oracle RAC 9iR2 一样,也可以实现 Server 端 Connect Time Load Balancing。只不过这里判断负载的依据有了变化。(注:如果客户端不能解析 RAC1-vip 这样的主机名,则在连接时很可能报 ORA-12545 错误,local_listener 对应的 TNS 配置中应该使用 VIP 地址,而不要用主机名,这里写主机名只是出于演示的目的)

Oracle 10g 引入了 Service,所以在 Oracle 10g 里,判断负载的依据就跟 Service 绑定在了一起。Oracle RAC 10gR2 里 Server 端 Connect Time Load Balancing 判断负载的依据是由相关 service 的参数 CLB_GOAL 和 GOAL 联合来决定的。

Oracle RAC 10gR2 里的负载可以通过 v$servicemetric 来查看:

SQL> desc v$servicemetric;

Name              Type         Nullable Default Comments

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

BEGIN_TIME        DATE         Y

END_TIME          DATE         Y

INTSIZE_CSEC      NUMBER       Y

GROUP_ID          NUMBER       Y

SERVICE_NAME_HASH NUMBER       Y

SERVICE_NAME      VARCHAR2(64) Y

CTMHASH           NUMBER       Y

ELAPSEDPERCALL    NUMBER       Y

CPUPERCALL        NUMBER       Y

DBTIMEPERCALL     NUMBER       Y

CALLSPERSEC       NUMBER       Y

DBTIMEPERSEC      NUMBER       Y

GOODNESS          NUMBER       Y

DELTA             NUMBER       Y

FLAGS             NUMBER       Y

其中每个 service 在 v$servicemetric 里会对应两条记录,一条记录每5秒采样一次,另外一条记录每 60 秒采样一次。

这里衡量每个 service 的负载情况,主要是通过 GOODNESS、DELTA和FLAGS 这三列来说明的,如下是它们各自的含义:

GOODNESS 表示这个节点成为 Server 端 Connect Time Load Balancing 的目标节点的可能性,这个值越高,可能性就越低。即这个 service 在某个节点上的 GOODNESS 的值越大,则表明这个节点的负载越重,这个节点成为 Server 端 Connect Time Load Balancing 的目标节点的可能性就越低。

DELTA 表示当节点增加了一个额外的 session 后对负载增加情况的估算。

FLAGS 是一个标志位,它的各个值的含义如下:

0 – all good

1 – blocked

2 – crossed threshold

4 – goodness unknown (usually when no sessions connected)

每个 service 所对应的 CLB_GOAL 实际上表示 Client Load Balance Goal,它的值要么为 LONG,要么为 SHORT,默认值是 LONG。

LONG 和 SHORT 的区别是:LONG 是 CLB_GOAL 的缺省值,通常用于那些需要长时间保持的连接,比如一些第三方的连接池或者 SQL*Form 应用;而 SHORT 则通常用于那些连接持续时间较短的应用,如果使用了支持订阅 LBA(Load Balancing Advisory)的连接池,则应该把 CLB_GOAL 的值设为 SHORT。

如果一个 service 的 CLB_GOAL 被设为 LONG,则意味着衡量这个 service 所在节点的负载情况是依据连接到这个节点的 session 的数量,此时与 CLB_GOAL 相对应的另外一个参数 GOAL 的设置将不再生效。

如果你把一个 service 的 CLB_GOAL 设为 SHORT,则意味着衡量这个 service 的负载情况是依据 LBA,在根据 LBA 判断负载情况时根据对应 service 的 GOAL 的设置的值的不同,又可以细分为是依据 SERVICE_TIME 还是依据 THROUGHPUT。也就是说,每个 service 所对应的 GOAL 实际上表示 LBA GOAL,它的值要么为 THROUGHPUT,要么为 SERVICE_TIME,要么是 NONE,GOAL 的默认值是 NONE。即当你把 CLB_GOAL 设为 SHORT 后,这种情况下 Server 端 Connect Time Load Balancing 判断负载的依据就是由 GOAL 的设置来决定了。

GOAL 所对应的三个值 THROUGHPUT、SERVICE_TIME 和 NONE 的区别是:

THROUGHPUT:表示判断负载的依据是吞吐量(THROUGHPUT),这通常用于那些并发的 transaction 具有相似的完成时间、相似的完成速率的系统,比如在线交易系统;

SERVICE_TIME:表示判断负载的依据是响应时间(response time),这通常用于那些并发的 transaction 具有不同的完成时间、不同的完成速率的系统,比如在线购物系统,不同的人完成一次在线购物,所购买的产品、所耗费的时间可能有很大差异;

NONE:表示不启用 LBA。

如果再结合 service 的 CLB_GOAL 和 GOAL,以及 v$servicemetric,就可以归纳出 Oracle RAC 10gR2 里 Server 端 Connect Time Load Balancing 判断负载的依据:

1、Oracle RAC 10gR2 里 Server 端 Connect Time Load Balancing 默认情况下判断负载的依据是连接到每个节点的 session 的数量,即当 CLB_GOAL 为默认值 LONG 的时候,v$servicemetric 的对应 service 的 GOODNESS=number of connected sessions,DELTA=1,注意此时 LBA 并没有启用;

2、Oracle RAC 10gR2 里如果把 service 的 CLB_GOAL 设为 SHORT,同时把 GOAL 设为 THROUGHPUT 或 SERVICE_TIME,则意味着 Server 端 Connect Time Load Balancing 判断节点负载的依据是 LBA。此时如果 GOAL 设为 THROUGHPUT,则 v$servicemetric 的对应 service 的 GOODNESS 值是根据 CPUPERCALL 和 DBTIMEPERCALL 来计算;如果 GOAL 设为 SERVICE_TIME,则 v$servicemetric 的对应 service 的 GOODNESS 值是根据 CALLSPERSEC 和 DBTIMEPERSEC 来计算。

接下来再看一下 Oracle RAC 11gR2 下的 Server 端 Connect Time Load Balancing:

Oracle RAC 11gR2 下的 Server 端 Connect Time Load Balancing 和 Oracle RAC 10gR2 下的 Server 端 Connect Time Load Balancing 类似,只不过因为 Oracle RAC 11gR2 里引入了 SCAN,所以 Oracle RAC 11gR2 环境下 remote_listener 应设置为 SCAN:port。

这里假设是一个 4 节点的 Oracle RAC 11gR2 环境,tnsnames.ora 中的连接串是如下这样:

(DESCRIPTION =

(FAILOVER=ON)(LOAD_BALANCE=ON)

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

(CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME =RAC11g)))

再在各个节点的 tnsnames.ora 中加入如下设置(注意这里监听的是各个节点的 VIP):

LISTENER_RAC1 =

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

LISTENER_RAC2 =

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

LISTENER_RAC3 =

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

LISTENER_RAC4 =

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

然后只需要在初始化参数文件里加入如下设置就能实现 Server 端 Connect Time Load Balancing 了:

RAC1.local_listener=LISTENER_RAC1

RAC2.local_listener=LISTENER_RAC2

RAC3.local_listener=LISTENER_RAC3

RAC4.local_listener=LISTENER_RAC4

*.remote_listener= MySCAN:1521

当做了上述设置后,Oracle 11gR2 RAC 的 Server 端 Connect Time Load Balancing 也就配好了。此时所有的 SCAN Listener 实际上是都知道所有RAC节点的负载情况的。当先经过一层客户端的 Connect Time Load Balancing,比如这里随机的连到了第二个 SCAN VIP 所对应的 SCAN Listener 上后,这时候这个 SCAN Listener 会选择一个实际负载较低的 RAC 节点,然后把连接请求转移(redirect)到这个负载较低的 RAC 节点的 Local Listener 上——这就是 Oracle RAC 11gR2 的 server 端的 Connect Time Load Balancing。

实际上,local_listener 和 remote_listener 支持复杂的连接串的写法。所以,可以在初始化参数里面直接设置 local_listener 和 remote_listener,而不需要在 $ORACLE_HOME/network/admin 下的 tnsnames.ora 中做上述设置。

来看一个两节点的 Oracle 11gR2 RAC 的实例。这个环境中用了 hosts 文件,hosts 文件内容如下所示:

10.1.15.64  P550-05-LA

10.1.15.84  P550-05-LA-vip

9.2.1.64    P550-05-LA-priv

10.1.15.65  P550-05-LB

10.1.15.85  P550-05-LB-vip

9.2.1.65    P550-05-LB-priv

10.1.15.86  nbsdev-scan

从上述内容可以看到,现在节点 1 的 vip 是 10.1.15.84,节点 2 的 vip 是 10.1.15.85,整个 RAC 环境的 SCAN vip 是 10.1.15.86。

先登陆节点 1,看一下节点 1 上的 local_listener 和 remote_listener 的设置: SQL> show parameter instance_name;

NAME                                 TYPE        VALUE

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

instance_name                        string      NBSDEV1

SQL> show parameter local_listener;

NAME                                 TYPE        VALUE

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

local_listener                       string      (DESCRIPTION=(ADDRESS_LIST=

(ADDRESS=(PROTOCOL=TCP)(HOST=10.1.15.84)(PORT=1522))))

SQL> show parameter remote_listener;

NAME                                 TYPE        VALUE

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

remote_listener                      string      nbsdev-scan:1522

再登陆节点 2,看一下节点 2 上的 local_listener 和 remote_listener 的设置: SQL> show parameter instance_name;

NAME                                 TYPE        VALUE

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

instance_name                        string      NBSDEV2

SQL> show parameter local_listener;

NAME                                 TYPE        VALUE

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

local_listener                       string      (DESCRIPTION=(ADDRESS_LIST=(ADDRESS=

(PROTOCOL=TCP)(HOST=10.1.15.85)(PORT=1522))))

SQL> show parameter remote_listener;

NAME                                 TYPE        VALUE

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

remote_listener                      string      nbsdev-scan:1522

上述环境 server 端的 Connect Time Load Balancing 实际上已经配置好了,但从如下内容可以看到,我们并没有在 $ORACLE_HOME/network/admin 下的 tnsnames.ora 中配置相关的 local_listener 和 remote_listener:

ora11g:/nbsdu01/app/oracle/product/11.2/network/admin>cat tnsnames.ora

# tnsnames.ora Network Configuration File: /nbsdu01/app/oracle/product/11.2/network/

admin/tnsnames.ora

# Generated by Oracle configuration tools.

NBSDEV =

(DESCRIPTION =

(ADDRESS = (PROTOCOL = TCP)(HOST = nbsdev-scan)(PORT = 1522))

(CONNECT_DATA =

(SERVER = DEDICATED)

(SERVICE_NAME = NBSDEV)

 

四、最后来介绍 Runtime Connection Load Balancing

Runtime Connection Load Balancing 是指从连接池中取得已有连接时的 Connection Load Balancing。

之前无论是 Oracle RAC 9iR2/10gR2,还是 Oracle RAC 11gR2,在存在连接池的情况下,单纯的 server 端的 Connect Time Load Balancing 并不能保证当应用需要从连接池里取得一个已有连接的时候,这个连接就指向了节点负载较低的那个节点。因为这个时候应用从连接池里取得的连接很可能就是连接池初始化的时候形成的连接,只是反映了连接池初始化那个时间点的各个节点的负载情况,而随着时间的推移,各个节点的负载情况可能发生了很大的变化,所以这种情况下连接池的连接很可能并不是真正的 Load Balance。

实际上 FAN 就是为了解决上述问题而设计的。能支持 FAN events 的连接池通过订阅 FAN HA events,就可以保证当应用需要从连接池里取得一个已有连接的时候,这个连接肯定是有效的连接,不会指向那些 service 宕掉或者 instance 崩溃的节点(之前已经提到过,这是通过 FCF 来实现的:当支持 FAN events 的连接池接收到包含 instance/service 宕掉的 FAN HA events 后,原先 cache 在连接池里的跟这个 instance/service 相关的连接马上会被标记为失效,同时这些连接会被清除);另外一个方面,能支持 FAN events 的连接池通过订阅 LBA events,就能近乎实时地知道各个 RAC 节点实际的负载情况,所以当应用需要从连接池里取得一个已有连接的时候,连接池就能提供给用户一个真正的负载较低的 RAC 节点,这样就实现了真正的 Runtime Connection Load Balancing。

现在介绍两个通过订阅 LBA events 实现 Runtime Connection Load Balancing 的例子。

例三:JDBC Runtime Connection Load Balancing

这里的 JDBC 连接是指 JDBC thin 连接,要实现 JDBC Runtime Connection Load Balancing,只需要做如下两步即可:

1、首先要按照“例一:JDBC Fast Connection Failover (FCF)”里那样把 JDBC FCF 设置好;

2、启用 LBA events:

srvctl modify service -d RAC11g -s Email -B SERVICE_TIME -j SHORT

这里首先把 CLB_GOAL 设置成了 SHORT,接着把 GOAL 设置成了 SERVICE_TIME,这两者缺一不可,CLB_GOAL 和 GOAL 的各个值的详细含义已经在 Connect Time Load Balancing 里详细解释过,这里不再赘述。

例四:ODP.NET Runtime Connection Load Balancing

ODP.NET的Runtime Connection Load Balancing的 启用跟“例二:ODP.NET Fast Connection Failover (FCF)”里的步骤类似,只需要做如下 4 步就好,注意这里第 1 步和第 4 步跟“例二:ODP.NET Fast Connection Failover (FCF)”里的相应步骤是不一样的:

1、把对应 service的AQ Notification 打开,同时设置 CLB_GOAL和GOAL:

srvctl modify service -d RAC11g -s Email -q TRUE -B SERVICE_TIME -j SHORT

2、把 aq_tm_processes 的值设为 1;

3、赋予指定用户 de-queue 的权限:

exec dbms_aqadm.grant_queue_privilege('DEQUEUE','SYS.SYS$SERVICE_METRICS', <your username=>);

4、在。NET连接串里设置 Load Balancing=true,如下所示:

con.ConnectionString =

"User Id=user_name;Password=password;Data Source=odpapp;" +

"Min Pool Size=10;Connection Lifetime=120;Connection Timeout=60;" +

"Load Balancing=true;Incr Pool Size=5;Decr Pool Size=2";

至此我们已经详细的描述了 RAC 环境下的连接管理。

作为这篇文章的结束,最后我们来阐述一下如何在 Oracle 数据库里设置 TCP timeout。

1、32 位 Windows上Oracle 数据库 11.2.0.1 默认的操作系统TNS连接 timeout 的时间大概是 20 秒:

16:27:26 SQL> conn scott/tiger@cuihua112;

ERROR:

ORA-12170: TNS: 连接超时

16:27:49 SQL>

这里可以看到,从开始连接到连接超时的间隔时间是 23 秒,去掉输入上述连接串“conn scott/tiger@cuihua112”所耗费的时间,可以知道在 32 位 Windows上Oracle 数据库 11.2.0.1 默认的操作系统TNS连接 timeout 的时间大概是 20 秒。

2、修改一下 client 端 sqlnet.ora 文件,将 TNS 连接 timeout 时间修改为 5 秒(这是通过设置 SQLNET.OUTBOUND_CONNECT_TIMEOUT 来实现的):

# sqlnet.ora Network Configuration File:

C:\app\cuihua\product\11.2.0\dbhome_1\network\admin\sqlnet.ora

# Generated by Oracle configuration tools.

# This file is actually generated by netca. But if customers choose to

# install "Software Only", this file wont exist and without the native

# authentication, they will not be able to connect to the database on NT.

SQLNET.AUTHENTICATION_SERVICES= (NTS)

SQLNET.OUTBOUND_CONNECT_TIMEOUT = 5

NAMES.DIRECTORY_PATH= (TNSNAMES, EZCONNECT)

从如下结果可以看到,从开始连接到连接超时的间隔时间是 7 秒,去掉输入上述连接串“conn scott/tiger@cuihua112”所耗费的时间,可以知道上述 5 秒超时的设置确实生效了。

16:28:34 SQL> conn scott/tiger@cuihua112;

ERROR:

ORA-12170: TNS: 连接超时

16:28:41 SQL>

3、注释掉上述 SQLNET.OUTBOUND_CONNECT_TIMEOUT = 5,在 tnsnames.ora 的 cuihua112 的连接串中将 TNS 连接 timeout 时间设置为 15 秒:

CUIHUA112 =

(DESCRIPTION =

(CONNECT_TIMEOUT=5)(RETRY_COUNT=2)

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

(CONNECT_DATA =

(SERVER = DEDICATED)

(SERVICE_NAME = cuihua112)

从如下结果可以看到,从开始连接到连接超时的间隔时间是 17 秒,去掉输入上述连接串“conn scott/tiger@cuihua112”所耗费的时间,可以知道上述 15 秒超时的设置确实生效了。

16:31:08 SQL> conn scott/tiger@cuihua112;

ERROR:

ORA-12170: TNS: 连接超时

16:31:25 SQL>

4、同时启用 SQLNET.OUTBOUND_CONNECT_TIMEOUT = 5 和上述 cuihua112 的连接串,从结果里可以看到,tnsnames.ora 中的设置取代了(override)了 sqlnet.ora 中的 TNS 连接 timeout 的设置。即在同时启用的情况下,现在的 TNS 连接 timeout 设置还是为 15 秒。

16:33:12 SQL> conn scott/tiger@cuihua112;

ERROR:

ORA-12170: TNS: 连接超时

16:33:29 SQL>

这里可以看到,从开始连接到连接超时的间隔时间是 17 秒,去掉输入上述连接串“conn scott/tiger@cuihua112”所耗费的时间,可以知道是 15 秒超时的设置生效了。

5、在 tnsnames.ora 的 cuihua112 的连接串中将 TNS 连接 timeout 时间设置为 40 秒,这已经超过了 TNS 连接默认的 timeout 值,从如下测试里可以看到,Oracle 数据库会以 tnsnames.ora 中的设置为准(当然,这里前提条件是单次连接的 CONNECT_TIMEOUT 设置不要超过操作系统 TNS 连接默认的 timeout 值,如果超过了则 CONNECT_TIMEOUT 设置失效,但 RETRY_COUNT 的设置依然有效)。

CUIHUA112 =

(DESCRIPTION =

(CONNECT_TIMEOUT=10)(RETRY_COUNT=3)

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

(CONNECT_DATA =

(SERVER = DEDICATED)

(SERVICE_NAME = cuihua112)

这里 CONNECT_TIMEOUT 设置为 10 秒,RETRY_COUNT 设置为 3,实际上就将 TNS 连接 timeout 时间设置成了40秒

16:52:52 SQL> conn scott/tiger@cuihua112;

ERROR:

ORA-12170: TNS: 连接超时

16:53:33 SQL>

这里可以看到,从开始连接到连接超时的间隔时间是 41 秒,去掉输入上述连接串“conn scott/tiger@cuihua112”所耗费的时间,可以知道是 40 秒超时的设置生效了。

五、总结

这篇文章详细介绍了 RAC 环境下的连接管理及其相关内容,主要针对 RAC 环境下连接管理所涉及到的 Connect Time Load Balancing、Runtime Connection Load Balancing、Connect Time Connection Failover 和 Runtime Connection Failover 等内容,同时也描述了包括 TAF、ONS、FCF、FAN 和 LBA 等其它一些相关内容。

 


(文章来自网络,如有侵权请来信告知,本站将在第一时间删除。)

相关文章 [上一篇] Oracle RAC 环境下的连接管理(一)
010-88589926(88587026)
CUUG热门培训课程
Oracle DBA就业培训
CUUG名师
网络课程
技术沙龙
最新动态

总机:(010)-88589926,88589826,88587026 QQ讨论群:243729577 182441349 邮箱:cuug_bj@cuug.com
通信地址:北京市海淀区紫竹院路98号北京化工大学科技园609室(CUUG)邮政编码:100089 
中国UNIX用户协会 Copyright 2010  ALL Rights Reserved 北京神脑资讯技术有限公司
京ICP备11008061号  京公网安备110108006275号