failover容易理解,案例也容易构造
load_balance不太容易弄,还好都清楚了。
[@more@]FAILOVER特性介绍
1.connect-time failover
8i提出来这个特性,为后来事先TAF打下了基础。
connect-time failover只是在连接的时侯选择能连上的实例进行连接
,只是在连接时做判断。042有个题目考得就是这个知识点。
connect-time failover的实现就是在tns配置文件里写多个地址列表就可以,
本身oracle默认FAILOVER=ON
Your database is not configured for session failover. Your tnsnames.ora file contains the following
details:
test.us.oracle.com=
(DESCRIPTION=
(ADDRESS_LIST=
(LOAD_BALANCE=off)
(FAILOVER=ON)
(ADDRESS=(PROTOCOL=tcp)(HOST=test1server)(PORT=1521))
(ADDRESS=(PROTOCOL=tcp)(HOST=test2server)(PORT=1521)))
(CONNECT_DATA=(SERVICE_NAME=test.us.oracle.com))
)
Which feature is enabled in this case?
Testinside
| English | Chinese(Traditional) | Chinese(Simplified) | 10
TestInside
Information Co., Ltd. All rights reserved.
A. Load balancing
B. Instance failover
C. Database failover
D. Connecttime
failover
E. Transparent Application Failover (TAF)
Answer: D
--=========================
2.CLIENT TAF(Transparent Application Failover)
9i通过在client段的tns里配置FAILOVER=ON以及相关的属性来实现
连接实例出现问题之后应用可以透明的切换到其他实例上,具体配置如下:
ASMDB_TAF =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = nodel-vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = node2-vip)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ASMDB)
(FAILOVER_MODE =
(TYPE = SELECT)
(METHOD = BASIC)
(RETRIES = 180)
(DELAY = 5)
)
)
)
--========================
测试如下:
C:>sqlplus sys/system@asmdb_taf as sysdba
SQL*Plus: Release 10.2.0.1.0 - Production on Mon Mar 26 11:19:01 2012
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, Real Application Clusters, OLAP and Data Mining options
SQL> select sid,failover_type,failover_method,failed_over,
2 instance_name from v$session,v$instance where sid=(select distinct sid from v$mystat);
SID FAILOVER_TYPE FAILOVER_M FAI INSTANCE_NAME
---------- ------------- ---------- --- ----------------
131 SELECT BASIC NO asmdb1
SQL>
--=======================
[oracle@node1 admin]$ srvctl stop instance -d asmdb -i asmdb1 -o abort
[oracle@node1 admin]$ srvctl status database -d asmdb
Instance asmdb1 is not running on node node1
Instance asmdb2 is running on node node2
[oracle@node1 admin]$
--================================
SQL> select sid,failover_type,failover_method,failed_over,
2 instance_name from v$session,v$instance where sid=(select distinct sid from v$mystat);
SID FAILOVER_TYPE FAILOVER_M FAI INSTANCE_NAME
---------- ------------- ---------- --- ----------------
131 SELECT BASIC YES asmdb2
SQL>
很显然shutdown实例1之后,自动连接到了实例2上,同时在tns中的
asmdb_taf的配置信息如FAILOVER_TYPE,failover_method等特性都体现了出来,
另外failed_over也变成了YES,这就是通过client端tns中配置实现的TAF。
3.SERVER TAF(Transparent Application Failover)
client端TAF需要在client端的TAF中配置,如果client端很多那么配置起来
比较麻烦,另外如果一旦server端有啥变化需要修改,那么修改很多client
端的tns也比较麻烦,从10g开始支持在server端设置services的属性来
实现TAF。测试过程如下:
--==================================
先启动刚才停掉的实例1
[oracle@node1 admin]$ srvctl start instance -d asmdb -i asmdb1
[oracle@node1 admin]$
修改services的taf属性:
SQL> begin
2 dbms_service.modify_service(
3 service_name=>'asmdb',
4 failover_method=>dbms_service.failover_method_basic,
5 failover_type=>dbms_service.failover_type_session,
6 failover_retries=>10,
7 failover_delay=>5
8 );
9 end;
10 /
PL/SQL procedure successfully completed.
SQL>
--===========================
tns中asmdb的配置信息如下,没有设置任何taf属性:
ASMDB =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = node1-vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = node2-vip)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = asmdb)
)
)
--==================================
SQL> select sid,failover_type,failover_method,failed_over,
2 instance_name from v$session,v$instance where sid=(select distinct sid from v$mystat);
SID FAILOVER_TYPE FAILOVER_M FAI INSTANCE_NAME
---------- ------------- ---------- --- ----------------
142 SESSION BASIC NO asmdb1
SQL>
--停止实例1
[oracle@node1 admin]$ srvctl stop instance -d asmdb -i asmdb1 -o abort
[oracle@node1 admin]$
SQL> select sid,failover_type,failover_method,failed_over,
2 instance_name from v$session,v$instance where sid=(select distinct sid from v$mystat);
select sid,failover_type,failover_method,failed_over,
*
ERROR at line 1:
ORA-25408: can not safely replay call
SQL> select sid,failover_type,failover_method,failed_over,
2 instance_name from v$session,v$instance where sid=(select distinct sid from v$mystat);
SID FAILOVER_TYPE FAILOVER_M FAI INSTANCE_NAME
---------- ------------- ---------- --- ----------------
131 SESSION BASIC YES asmdb2
SQL>
很显然也切换到实例2,不过中间出现了一个错误提示ORA-25408
--==================================
LOAD_BALANCE特性介绍
1.CLIENT LOAD_BALANCE
CLIENT LOAD_BALANCE是在client端的tns中通过增加
(LOAD_BALANCE = yes)来实现的,设置CLIENT LOAD_BALANCE
之后listener在路由client端连接请求时会随机选择几个实例。
下面是测试过程,先屏蔽之前测试启用的load balance advisor功能。
--=============================
client端tns中asm的配置信息如下:
ASMDB =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = node1-vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = node2-vip)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = asmdb)
)
)
--=============================
SQL> select name,goal,clb_goal from dba_services where name='asmdb';
NAME GOAL CLB_G
-------------------- ------------ -----
asmdb SERVICE_TIME SHORT
SQL> exec dbms_service.modify_service(service_name=>'asmdb',goal=>dbms_service.goal_none,clb_goal=>dbms_service.clb_goal_long);
PL/SQL procedure successfully completed.
SQL> select name,goal,clb_goal from dba_services where name='asmdb';
NAME GOAL CLB_G
-------------------- ------------ -----
asmdb NONE LONG
SQL>
--=============================
为了不影响测试效果同时屏蔽server端load balance:
SQL> show parameter remote_listener
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
remote_listener string LISTENERS_ASMDB
SQL> alter system set remote_listener='' sid='*';
System altered.
SQL>
--======================
为了保证测试效果,重启db和listener,正常重启service和listener就可以了
,但是由于我使用的service是db default的service不能通过srvctl重启,所以
需要重启db。
--======================
重启使用的3个脚本如下:
[oracle@node1 sess_lb_script]$ more test.sql
select instance_name from v$instance;
exit
[oracle@node1 sess_lb_script]$ more test.sh
#!/bin/sh
#Usage:test rawdb 4000
count=0
while [ $count -lt $2 ]
do
count=`expr $count + 1`
sqlplus -s system/system@$1 @/home/oracle/sess_lb_script/test.sql
#sleep 1
done
[oracle@node1 sess_lb_script]$ more sess_count.sh
grep asmdb1 test.log|wc -l
grep asmdb2 test.log|wc -l
[oracle@node1 sess_lb_script]$
--==============================
测试过程如下:
首先清空日志文件test.log
[oracle@node1 sess_lb_script]$ cat /dev/null > test.log
[oracle@node1 sess_lb_script]$ ls -l test.log
-rwxrwxrwx 1 oracle oinstall 0 Mar 26 09:51 test.log
[oracle@node1 sess_lb_script]$
同时做400个连接:
[oracle@node1 sess_lb_script]$ ./test.sh asmdb 400 > test.log
[oracle@node1 sess_lb_script]$ ./sess_count.sh
189
211
[oracle@node1 sess_lb_script]$
这里我们看到连接到asmdb1和asmdb2上的session分部是189和211,
这就是一个随机的选择,没有考虑任何其他负载等因素。
2.SERVER LOAD_BALANCE
SERVER端LOAD_BALANCE如果不启用10gR2提供的load balance advisor
特性,其实就是一个session balance。SERVER LOAD_BALANCE是通过
设置参数remote_listener来实现的,在测试client load balance时
把默认启用的SERVER LOAD_BALANCE通过修改参数remote_listener为null值
屏蔽了,下面启用SERVER LOAD_BALANCE:
SQL> alter system set remote_listener='LISTENERS_ASMDB' sid='*';
System altered.
SQL>
为了保证效果可以考虑重启listener,通过lsnrctl services
观查发现不重启也可以,SERVER LOAD_BALANCE的原理是当listener
理由client连接请求时会判断到底哪个实例上的session数量多,listener
会把client的连接请求路由到session数少的一个实例上从而尽可能的
平衡session数量,其实是一种假象load balance,因为session数毕竟
不能真实的反应负载,这种测试需要借助listener log,因为client端
连接db时在本地实例的listener.log里会记录下面信息:
--========================
26-MAR-2012 01:22:43 * (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=asmdb)(CID=(PROGRAM=sqlplus@node1)(HOST=node1)(USER=oracle))) * (ADDRESS=(PROTOCOL=tcp)(HOST=143.168.0.14)(PORT=35805)) * establish * asmdb * 0
--========================
注意这里的establish关键字。
如果是其他实例的listener路由过来的连接,那么会在本地实例的listener.log中
存在如下信息:
--=================================
26-MAR-2012 01:22:46 * (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=asmdb)(CID=(PROGRAM=sqlplus@node1)(HOST=node1)(USER=oracle))(INSTANCE_NAME=asmdb1)) * (ADDRESS=(PROTOCOL=tcp)(HOST=143.168.0.14)(PORT=35837)) * establish * asmdb * 0
--=================================
区别在于多了(INSTANCE_NAME=asmdb1),但是在listener.log中并没有体现出来
是由哪个实例的listener路由过来的,所以这种办法仅适用于2个节点的rac测试
SERVER LOAD_BALANCE
--==========================
下面是测试需要的脚本:
[oracle@node1 sess_lb_script]$ more test.sql
select instance_name from v$instance;
exit
[oracle@node1 sess_lb_script]$ more test.sh
#!/bin/sh
#Usage:test rawdb 4000
count=0
while [ $count -lt $2 ]
do
count=`expr $count + 1`
sqlplus -s system/system@$1 @/home/oracle/sess_lb_script/test.sql
#sleep 1
done
[oracle@node1 sess_lb_script]$ more sess_count.sh
grep asmdb1 test.log|wc -l
grep asmdb2 test.log|wc -l
[oracle@node1 sess_lb_script]$ more log_count.sh
grep establish /app/oracle/product/10.2.0/db_1/network/log/listener_node1.log|wc -l
grep INSTANCE_NAME=asmdb1 /app/oracle/product/10.2.0/db_1/network/log/listener_node1.log|wc -l
grep INSTANCE_NAME=asmdb2 /app/oracle/product/10.2.0/db_1/network/log/listener_node1.log|wc -l
[oracle@node1 sess_lb_script]$
--=============================
下面是测试过程:
首先清空2个节点上的listener.log
[root@node1 log]# cat /dev/null > listener_node1.log
[root@node1 log]# ls -l
total 12
-rw-r--r-- 1 oracle oinstall 0 Mar 26 10:19 listener_node1.log
[root@node2 log]# cat /dev/null > listener_node2.log
[root@node2 log]# ls -l
total 0
-rw-r--r-- 1 oracle oinstall 0 Mar 26 10:20 listener_node2.log
[root@node2 log]#
[oracle@node1 sess_lb_script]$ cat /dev/null > test.log
[oracle@node1 sess_lb_script]$ ./test.sh asmdb 400 > test.log
[oracle@node1 sess_lb_script]$ ./sess_count.sh
70
330
--======================
看好了,这是node1上的listener.log
[oracle@node1 sess_lb_script]$ ./log_count.sh
264
64
0
--===================================
这是node2上的listener.log
[oracle@node2 sess_lb_script]$ ./log_count.sh
394
194
0
[oracle@node2 sess_lb_script]$
[oracle@node1 sess_lb_script]$
这里效果不加,400个请求,asmdb1上连接了70个,asmdb2上连接了330个;
很显然asmdb1一共接收了264个连接请求,但是asmdb2的listener路由过来64个
连接请求。asmdb2一共连接了394个连接请求,asmdb1的listener路由过来
194个连接请求。这样:
264 - 194 =70
394 - 64 = 330
没有得到预想的session balance。
--==========================
重启listener同时屏蔽client端load balance的影响,再次测试看看效果:
注释tns中asmdb中的(LOAD_BALANCE = yes)
[oracle@node2 sess_lb_script]$ srvctl stop listener -n node1
[oracle@node2 sess_lb_script]$ srvctl stop listener -n node2
[oracle@node2 sess_lb_script]$ srvctl start listener -n node1
[oracle@node2 sess_lb_script]$ srvctl start listener -n node2
[oracle@node2 sess_lb_script]$
--==========================
清掉listener.ora以及test.log
[oracle@node1 sess_lb_script]$ ./test.sh asmdb 400 > test.log
[oracle@node1 sess_lb_script]$ ./sess_count.sh
62
338
[oracle@node1 sess_lb_script]$ ./log_count.sh
400
0
0
[oracle@node1 sess_lb_script]$
[oracle@node2 sess_lb_script]$ ./log_count.sh
338
338
0
[oracle@node2 sess_lb_script]$
这个更有意思了,node1接收到了400个连接请求路由给node2 338个
自己保留了62个。
3.激活load balance advisor来观查一下测试效果
待续
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/19602/viewspace-1057716/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/19602/viewspace-1057716/