而在failover的实现中,还是有一定的使用限定,比如11g中默认的scan-ip的实现其实还是默认没有failover的选项,如果两个节点,某个节点挂了,那么原有的连接中继续查询就会提示session已经断开,需要重连。
很多应用都在这样使用scan-ip,也都相安无事,所以对于failover的选择还是有一定选择空间,如果说failover的实现方式,简单来说,主要就是通过换取时间,或者换取资源来实现。
怎么理解呢。
假设我们存在两个节点,如果某个session连接到了节点2,突然节点2挂了,那么故障转移的方式就有通过换取时间或者换取资源。
比如说换取时间,为了更快达到failover的速度,failover method 有preconnect,这种预连接方式还是会占用较多的资源使用,在各个节点上还是会预先占用一部分额外的资源,在切换时会相对更加平滑,速度更快。这种就是preconect的方式
另外一种情况,则在发生failover的情况时,再去切换对应的资源,中间会有一些卡顿,但是对于资源的相对来说要小很多。这种就是默认的basic模式。
failover method侧重于用户对于何时创建到实例的连接,即basic方式会在故障发生时采取判断,有一种delay的味道,而preconnect则是未雨绸缪,先准备后,在出现故障的时候,能够更快切换,从实际的应用来说,还是basic这种方式更加通用。
而对于failover的类型来说,rac的实现更加丰富而且灵活,这在别的数据库中真是不可想象。这个时候它的粒度就在于用户对于sql的执行情况进行控制。
比如说,我们有个很大的查询在节点2上进行,结果节点2突然挂了,然后这个时候,failover的类型就有两种,即对于正在执行的查询,比如说有1万条数据,结果刚好故障发生的时候查出了8000条,那么剩下的2000该怎么处理。
一种方式就是使用select,即会完成故障切换,继续把剩下的2000条记录返回,当然中间会有一些上下文环境的切换,对于用户基本还是透明的,但是会有一定的延时。
另外一种是直接断开连接,要求重新查询。这种type是session
在10g版本中借助于vip的配置达到load balance+failover的配置如下:
racdb =
(DESCRIPTION =
(ADDRESS= (PROTOCOL= TCP)(HOST=192.168.3.101)(PORT= 1521))
(ADDRESS= (PROTOCOL= TCP)(HOST=192.168.3.201)(PORT= 1521))
(LOAD_BALANCE = yes)
(FAILOVER = ON)
(CONNECT_DATA =
(SERVER= DEDICATED)
(SERVICE_NAME = racdb)
(FAILOVER_MODE =
(TYPE= SELECT)
(METHOD= BASIC)
(RETRIES = 30)
(DELAY = 5))))
当然有一个不同之处是在10g中我们可以直接通过dbca来完成配置,就是简单清晰。
在11g中,只能借助于命令或者EM来实现了。不知道为什么把这块功能的图形界面部分给去掉了。
通过命令其实也不算麻烦,我们可以使用下面的方式做一个简单的配置。
比如我们选择failover_mode为basic创建的taf为racdb_taf
srvctl add service -d RACDB -s racdb_taf -r "RACDB1,RACDB2" -P BASIC
bash-4.1$ crs_stat -t|grep taf
Name Type Target State Host
------------------------------------------------------------
ora....taf.svc ora....ce.type OFFLINE OFFLINE
我们手工开启
srvctl start service -d RACDB -s racdb_taf
然后通过dbms_service来配置更多的属性。
execute dbms_service.modify_service (service_name => 'racdb_taf', aq_ha_notifications => true, failover_method => dbms_service.failover_method_basic, failover_type => dbms_service.failover_type_select, failover_retries => 181,failover_delay => 5,clb_goal => dbms_service.clb_goal_long);
在数据库中可以简单查看相关的service情况。
SQL> select service_id ,name from dba_services ;
SERVICE_ID NAME
---------- ----------------------------------------------------------------
1 SYS$BACKGROUND
2 SYS$USERS
3 racdb_taf
5 RACDBXDB
6 RACDB
select name, failover_method, failover_type, failover_retries,goal, clb_goal,aq_ha_notifications from dba_services where service_id =3;