oracleHA高可用性详解
一、ha
failover,oracle rac的高可用性的技术基础是failover,就是指集群中的热河一个节点的故障都不会影响到用户的使用,连接到故障节点的用户会被自动转移到健康节点,从用户高手而言感觉不到这种切换,这个功能在oracle中被称作failover(故障转移)。
oracle rac的failover可以细分为3中,分别是:
(1) client-side connect time failover;
(2) taf;
(3) server-side taf;
注意:
不要再listener.ora中设置global_db_name,因为这个参数会禁用connect-time failover和transparentapplication failover。
client-side connect time failover
client-side connect timefailover的含义是:如果客户端tnsname中配置了多个地址,用户发起请求时,会先尝试连接地址表中的第一个地址,如果这个连接尝试失败,则会继续尝试使用第二个地址,直至连接成功或者遍历了所有的地址。
这种failover的特点从他的名称中“connect time”就表达的很清楚了,只在建立连接的那一时刻起作用。也就是说这种failover方式只在发起连接时采取感知节点故障,如果发现节点没有响应,则自动尝试地址列表的下一个地址。一旦连接建立以后,节点出现故障都不会做处理,从客户端的表现来看就是断开,用户程序必须重新建立连接。
启用这种failover的方法就是在客户端的tnsnames.ora中添加failover=on条目,这个参数默认就是on,所以即使不添加这个条目,客户端也会获得这种failover能力。
taf(transparent apllication failover)
从上文对client-side connecttime failover特点的分析可以看出,这种failover的意义有限。下载大部分流行的应用(比如weblogic,jboss)都是启动时就建立若干到的长连接,在应用程序整个生命周期内重用这些连接。client-side connect time failover的工作方式是它对应用程序的可用性没有极大地帮助。
从8.1.5版本oracle引入了新的failover机制taf.所谓taf,就是连接建立以后,应用程序运行过程中,如果某个实例发生故障,连接到这个实例上的用户会被自动迁移到其他的健康实例上。对于应用程序而言,这个千亿过程透明、不需要用户的介入,当然这种透明也是有引号的,因为用户的未提交事务会回滚。相对于client-side connect time failover的用户程序被中断、抛出连接错误、用户必须中期应用程序,taf这种方式在提高应用程序ha能力上无疑是前进了一大步。
taf的配置也很简单,只需要在客户端的tnsnames.ora中添加failover_mode配置项,这个条目有4个子项目需要定义。
frac =
(description =
(address = (protocol = tcp)(host = frac1-vip)(port = 1521))
(address = (protocol = tcp)(host = frac2-vip)(port = 1521))
(load_balance=yes)
(
connect_data=
(server=dedicated)
(service_name=frac)
(
failover_mode=
(type=session)
(method=basic)
(retries=180)
(delay=5)
)
)
)
(1) method选项用于定义何时创建到其他实例的连接,有basic和perconnect两个选项值。
a. basic是指在感知到节点故障时才创建到其他实例的连接。
b. perconnect是在最初建立连接时就同时建立到所有实例的连接,当发生故障时,立刻就可以切换到其他链路上。
两种方法的不同很容易比较。basic方式在faiover时会有时间言辞,perconnect方式虽然没有时间言辞,但是再建立多个冗余两节会消耗更多的资源,两者就是用时间换资源和资源换时间的区别。
(2) type选项用于定于发生故障时对完成的sql语句如何处理,其有两种类型:session和select。
这两种方式对于未提交的事务都自动回滚。区别在于对于select语句的处理,对于select类型,用户正在执行的select语句也会被转移到新的实力上,在新节点上继续返回后续结果集,而已经返回的记录结果集抛弃。
假设用户正在节点1上执行查询,整个结果集共有100条记录,现在一从节点1上返回10条记录,这时节点1宕机,用户连接被转移到节点2上,如果是session方式则需要重新执行查询语句;如果是select方式会从节点2上继续返回剩下的90条记录,二已经从节点1返回的10条记录不会重复返回给用户,对于用户而言感觉不到这种切换。
很显然为了实现select方式,oracle必须为每个session保存更多的内容,包括游标、用户、上下文等,需要更多的资源也是用资源换时间的方案。
(3) delay和retries这两个参数和简单,代表着重试时间间隔和重试次数。
failover(taf)的测试借助于前面监听和tnsnames的配置,而在11g r2没有引入之前出现故障用的是直接用集群的vip“漂”进行故障转移,而在11g r2以后,引入了一个新的ip,即scan(singleclient access name)ip,scan是一个域名,可以解析1到3个scan ip,客户端可以通过scan名解析来访问数据库,其好处就是添加和删除节点时不需要再有额外的客户端维护,大大减少了维护方面的繁琐工作。
在集群环境中,我们配置的客户端是以scan ip的方式进行配置的。当我们某个用户在外面连接进来的时候,集群会自动的根据负载把该会话连接到一个特定的实例,如果该会话正在select一个表,还未完成,该实例宕机了,oracle会自动将故障节点的失误切换到另一个实例中执行,这样的切换对于用户来说是透明的。用户不会感觉到异常,所执行操作也将返回正常的结果,这个也是rac集群的高可用性所在。以下是在session模式做的网络failover测试;
首先用户用客户端服务进行连接:
[oracle@frac1admin]$ sqlplus scott/oracle@frac
sql*plus: release11.2.0.3.0 production on wed apr 16 01:55:37 2014
copyright (c) 1982,2011, oracle. all rights reserved.
connected to:
oracle database 11genterprise edition release 11.2.0.3.0 - 64bit production
with thepartitioning, real application clusters, automatic storage management, olap,
data mining and realapplication testing options
sql> showparameter instance_name
name type value
---------------------------------------------------------- ------------------------------
instance_name string frac2
sql> create tablebig_a as select * from dba_objects;
sql>insert intobig_a select * from big_a;
为了保证数据的充足性,多执行几次上面insert语句,由于磁盘空间限制,我在此执行了4次,共1203888条记录。
由以上信息可知用户连接到frac2实例,此时可以执行一些dml操作:
sql> selectobject_type,count(*) from big_a group by object_type;
在查询未完成之前,把frac2实例进行宕机,会返回如下错误:
sql> shutdownabort;
oracle instance shutdown.
sql> selectobject_type,count(*) from dba_objects group by object_type;
selectobject_type,count(*) from dba_objects group by object_type
*
error at line 1:
ora-25408: can notsafely replay call
再次查看的是时候发现已经把会话自动切换到frac1实例:
sql> /
object_type count(*)
------------------------------------------------
edition 1
index partition 302
tablesubpartition 32
consumer group 25
sequence 229
table 2936
index 5266
synonym 28152
view 5186
function 305
java class 23165
java source 2
indextype 9
cluster 10
type 2913
resource plan 10
job 14
evaluationcontext 15
45 rows selected.
sql> showparameter instance_name;
name type value
---------------------------------------------------------------------------- ------
instance_name string frac1
sql> !hostname
frac1
server-side taf
第三种方式是server-side taf,但从名字上就可以猜出这种方式和之前的taf有一定的关系。事实上也是这样,可以把server-side taf看做是taf的一个变种。首先server-side taf也是taf,所有taf的特点他都具有;其次,这种taf是在服务器上配置,而不像taf是在客户端配置的。
前面介绍的client-side taf,配置过程需要修改客户端tnsnames.ora文件,如果有很多客户端使用这个数据库,那么每次微小的参数调整都要把书友计算机更改一遍,即低效又易出错。而server-side taf通过结合service,在数据库里保存fail_mode的配置,把所有的taf配置保存在数据字典里,从而省去了客户端的配置工作,现在客户端的tns文件就不需要任何taf的配置选项。
从配置参数而言,service-side taf相比多了一个instance role(实力角色)的概念。所谓实力角色,就是当有多个instance参与一个service时,可以配置有限使用哪一个instance为用户提供服务。用户总共有两种可选角色。
a. preferred:首选实例,会优先选择拥有这个角色的实例提供服务。
b. avilable:后备实例,用户会优先连接preferrd的instance,当preferred的instance不可用时,才会被转移到avilable的实例上。
要想使用server-side taf必须配置server。server可以在创建数据库时创建,也可以在数据库创建之后修改;既可以通过配置向导也可以通过命令行方式配置。下面分别演示用dbca和手工两种方式配置service的过程。