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 timeFailover的含义是:如果客户端tnsname中配置了多个地址,用户发起请求时,会先尝试连接地址表中的第一个地址,如果这个连接尝试失败,则会继续尝试使用第二个地址,直至连接成功或者遍历了所有的地址。
这种Failover的特点从他的名称中“connect time”就表达的很清楚了,只在建立连接的那一时刻起作用。也就是说这种Failover方式只在发起连接时采取感知节点故障,如果发现节点没有响应,则自动尝试地址列表的下一个地址。一旦连接建立以后,节点出现故障都不会做处理,从客户端的表现来看就是断开,用户程序必须重新建立连接。
启用这种Failover的方法就是在客户端的tnsnames.ora中添加FAILOVER=ON条目,这个参数默认就是ON,所以即使不添加这个条目,客户端也会获得这种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,但从名字上就可以猜出这种方式和之前的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的过程。
实例1作为首选实例,TAF police选择basic,参考上图;
查看配置信息:
[root@felix1bin]# ./srvctl config service -d felix -h
Usage:srvctl config service -d <name> [-s <service_name>] [-a] [-S<level>]
-d <name> Unique name for the database
-s <service> Service name
-a Additional attributes
-S <level> Additional information for EM Console
-h Print usage
[root@felix1bin]# ./srvctl config service -d felix
taf_server PREF: felix1 AVAIL: felix2
[root@felix1 bin]#
[root@felix1 bin]# ./srvctl config service -dfelix -s taf_server -a
taf_server PREF: felix1 AVAIL: felix2 TAF:basic
[root@felix1 bin]#
除了用DBCA图形方式,还可以使用命令方式配置service,这种方法对于维护远程尤其有用。无论是创建还是维护都是用一个命令srvctl,先看一下srvctl命令和service相关的语法,如下:
[oracle@felix1 ~]$ srvctl add service -h
Usage: srvctl add service -d <name> -s<service_name> -r "<preferred_list>" [-a"<available_list>"] [-P <TAF_policy>]
-d<name> Unique name forthe database
-s<service> Service name
-r"<pref_list>" List ofpreferred instances
-a"<avail_list>" List ofavailable instances
-P<TAF_policy> TAF policy (NONE,BASIC, or PRECONNECT)
Usage: srvctl add service -d <name> -s<service_name> -u {-r "<new_pref_inst>" | -a"<new_avail_inst>"}
-d<name> Unique name forthe database
-s <service> Service name
-u Add a new instance to serviceconfiguration
-r<new_pref_inst> Name of newpreferred instance
-a<new_avail_inst> Name of new available instance
-h Print usage
[oracle@felix1 ~]$
示例如下:
Felix1,felix2为实例名;Felix是数据库名;策略是:BASIC
[oracle@felix1~]$ srvctl add service -d felix -s taf_srvctl -r felix2 -a felix1 -P BASIC
[oracle@felix1~]$
[oracle@felix1 ~]$ srvctl config service -d felix-a
taf_server PREF: felix1 AVAIL: felix2 TAF: basic
taf_srvctl PREF: felix2 AVAIL: felix1 TAF: BASIC
[oracle@felix1 ~]$
[oracle@felix1 ~]$ srvctl config service -d felix-h
Usage: srvctl config service -d <name> [-s<service_name>] [-a] [-S <level>]
-d<name> Unique name for the database
-s<service> Service name
-a Additional attributes
-S<level> Additionalinformation for EM Console
-h Print usage
[oracle@felix1 ~]$
如果不指定“-s service_name”,就会显示所有的service配置,这些配置只包括preferred和avilable instance。使用-a选项,还会显示TAF的信息。
数据库启动时,会自动启动所有的service。有时为了维护的需要,需要禁用这个特性。在维护完成之后再启动这个特性。
[oracle@felix1 ~]$ srvctl disable service -h
Usage: srvctl disable service -d <name> -s"<service_name_list>" [-i <inst_name>]
-d<name> Unique name forthe database
-s"<serv,...>" Commaseparated service names
-i<inst> Instance name
-h Print usage
[oracle@felix1 ~]$
[oracle@felix1 ~]$ srvctl disable service -d felix-s taf_server -i felix1
[oracle@felix1 ~]$ srvctl config service -d felix-a
taf_server PREF: felix1 AVAIL: felix2 TAF: basic
Service taf_server is disabled on instance(s) felix1.
taf_srvctl PREF: felix2 AVAIL: felix1 TAF: BASIC
[oracle@felix1 ~]$
[oracle@felix1 ~]$ srvctl disable service -d felix-s taf_server
PRKP-1024 : The service taf_server is stillrunning.
[oracle@felix1 ~]$ srvctl stop service -h
Usage: srvctl stop service -d <name> [-s"<service_name_list>" [-i <inst_name>]] [-f]
-d<name> Unique name forthe database
-s"<serv,...>" Commaseparated service names
-i<inst> Instance name
-f Disconnect all sessionsduring stop or relocate service operations
-h Print usage
[oracle@felix1 ~]$ srvctl stop service -d felix -staf_server
[oracle@felix1 ~]$ srvctl config service -d felix-a
taf_server PREF: felix1 AVAIL: felix2 TAF: basic
taf_srvctl PREF: felix2 AVAIL: felix1 TAF: BASIC
[oracle@felix1 ~]$ srvctl disable service -d felix-s taf_server
[oracle@felix1 ~]$ srvctl config service -d felix-a
taf_server PREF: felix1 AVAIL: felix2 TAF: basic
Service taf_server is disabled.
taf_srvctl PREF: felix2 AVAIL: felix1 TAF: BASIC
[oracle@felix1 ~]$
[oracle@felix1 ~]$ srvctl start service -h
Usage: srvctl start service -d <name> [-s"<service_name_list>" [-i <inst_name>]] [-o<start_options>]
-d<name> Unique name forthe database
-s"<serv,...>" Commaseparated service names
-i<inst> Instance name
-o<start_options> Options to startupcommand (e.g. open, mount, or nomount)
-h Print usage
[oracle@felix1 ~]$
[oracle@felix1 ~]$ srvctl start service -d felix -s taf_server
[oracle@felix1 ~]$
[oracle@felix1 ~]$ srvctl status service -h
Usage: srvctl status service -d <name> [-s"<service_name_list>"] [-f] [-v] [-S <level>]
-d<name> Unique name forthe database
-s"<serv,...>" Comma separatedservice names
-f Include disabled applications
-v Verbose output
-S<level> Additionalinformation for EM Console
-h Print usage
[oracle@felix1 ~]$
[oracle@felix1 ~]$ srvctl status service -d felix -s taf_server -f -v
Service taf_server is running on instance(s)felix2
[oracle@felix1 ~]$ srvctl status service -d felix -s taf_server -f -v -S 3
#@=info: operation={status} config={full}ver={10.2.0.0.0}
#@=service[0]: name={taf_server} enabled={true}pref={felix1} avail={felix2} disabled_insts={felix1} tafpolicy={basic}type={user}
#@=service[1]: name={felix} enabled={true}pref={felix1, felix2} avail={} disabled_insts={} tafpolicy={NONE}type={internal}
Service taf_server is running on instance(s)felix2
#@=result[0]: up={felix2} down={felix1}disabled={felix1} unknown={}
#@=result[1]: up={felix1, felix2} down={}disabled={} unknown={}
#@=done: status={0}
[oracle@felix1 ~]$
[oracle@felix1 ~]$ srvctl remove service -h
Usage: srvctl remove service -d <name> -s<service_name> [-i <inst_name>] [-f]
-d<name> Unique name forthe database
-s<service> Service name
-i<inst> Instance name
-f Force remove
-h Print usage
[oracle@felix1 ~]$
[oracle@felix1 ~]$ srvctl status service -d felix
Service taf_server is running oninstance(s) felix1
Service taf_srvctl is not running.
[oracle@felix1 ~]$ srvctl remove service -d felix-s taf_server -i felix1
taf_server PREF: felix1 AVAIL: felix2
Remove service taf_server from the instancefelix1? (y/[n]) y
PRKP-1024 : The service taf_server is still running.
[oracle@felix1 ~]$
[oracle@felix1 ~]$ srvctl remove service -d felix-s taf_srvctl -i felix1
taf_srvctl PREF: felix2 AVAIL: felix1
Remove service taf_srvctl from the instancefelix1? (y/[n]) y
PRKP-1067 : Instance felix1 is the last availableinstance for service taf_srvctl. Try modify service instead.
[oracle@felix1 ~]$ srvctl config service -d felix -a
taf_server PREF: felix1 AVAIL: felix2 TAF: basic
taf_srvctl PREF: felix2 AVAIL: felix1 TAF: BASIC
[oracle@felix1 ~]$
[oracle@felix1 ~]$ srvctl remove service -d felix -staf_srvctl -f
[oracle@felix1 ~]$ srvctl config service -d felix -a
taf_server PREF: felix1 AVAIL: felix2 TAF: basic
[oracle@felix1 ~]$ srvctl remove service -d felix-s taf_server -f
PRKP-1024: The service taf_server is still running.
[oracle@felix1 ~]$ srvctl stop service -d felix -staf_server
[oracle@felix1 ~]$ srvctl remove service -d felix-s taf_server -f
[oracle@felix1 ~]$ srvctl config service -d felix -a
[oracle@felix1 ~]$
[oracle@felix1 ~]$ srvctl modify service -h
Usage: srvctl modify service -d <name> -s<service_name> -i <old_inst_name> -t <new_inst_name> [-f]
-d<name> Unique name forthe database
-s<service> Service name
-i<old_inst> Old instance name
-t<new_inst> New instance name
-f Disconnect all sessionsduring stop or relocate service operations
Usage: srvctl modify service -d <name> -s<service_name> -i <avail_inst_name> -r [-f]
-d<name> Unique name forthe database
-s<service> Service name
-i<inst> Instance name
-r Upgrade instance to preferred
-f Disconnect all sessionsduring stop or relocate service operations
Usage: srvctl modify service -d <name> -s<service_name> -n -i <prefered_inst> [-a <available_list>][-f]
-d<name> Unique name forthe database
-s<service> Service name
-n Modify service configuration
-r"<pref_list>" List ofpreferred instances
-a"<avail_list>" List ofavailable instances
-f Disconnect all sessions during stopor relocate service operations
Usage: srvctl modify service -d <name> -s<service_name> -P <TAF_policy> [-f]
-d<name> Unique name forthe database
-s<service> Service name
-P<TAF_policy> TAF policy (NONE,BASIC, or PRECONNECT)
-f Disconnect all sessionsduring stop or relocate service operations
-h Print usage
[oracle@felix1 ~]$
[oracle@felix2 ~]$ srvctl modify service -d felix-s taf_srvctl -n -i felix1,felix2 -f
[oracle@felix2 ~]$ srvctl config service -d felix -a
taf_srvctlPREF: felix1 felix2 AVAIL: TAF: basic
[oracle@felix2 ~]$
在使用srvctl创建service时,需要注意TAF策略选项必须通过dbms_service包来配置。下面例子演示了如何创建一个服务felix_ora:
SQL> show parameter service
NAME TYPE VALUE
------------------------------------ -----------------------------------------
service_names string felix
SQL>
[oracle@felix1 ~]$ srvctl add service -d felix -s felix_ora -r felix1 -a felix2 -P BASIC
[oracle@felix1 ~]$
[oracle@felix1 ~]$ srvctl config service -d felix-a
felix_ora PREF: felix1 AVAIL: felix2 TAF: BASIC
[oracle@felix1 ~]$ srvctl status service -d felix
Service felix_ora is not running.
[oracle@felix1 ~]$
[oracle@felix1 ~]$ crs_stat -t -v
Name Type R/RA F/FT Target State Host
----------------------------------------------------------------------
ora.felix.db application 0/0 0/1 ONLINE ONLINE felix1
ora....x1.inst application 0/5 0/0 ONLINE ONLINE felix1
ora....x2.inst application 0/5 0/0 ONLINE ONLINE felix2
ora...._ora.cs application 0/0 0/1 OFFLINE OFFLINE
ora....ix1.srv application 0/0 0/0 OFFLINE OFFLINE
ora....SM1.asm application 0/5 0/0 ONLINE ONLINE felix1
ora....X1.lsnr application 0/5 0/0 ONLINE ONLINE felix1
ora.felix1.gsd application 0/5 0/0 ONLINE ONLINE felix1
ora.felix1.ons application 0/3 0/0 ONLINE ONLINE felix1
ora.felix1.vip application 0/0 0/0 ONLINE ONLINE felix1
ora....SM2.asm application 0/5 0/0 ONLINE ONLINE felix2
ora....X2.lsnr application 0/5 0/0 ONLINE ONLINE felix2
ora.felix2.gsd application 0/5 0/0 ONLINE ONLINE felix2
ora.felix2.ons application 0/3 0/0 ONLINE ONLINE felix2
ora.felix2.vip application 0/0 0/0 ONLINE ONLINE felix2
[oracle@felix1 ~]$
[oracle@felix1 ~]$ srvctl enable service -d felix-s felix_ora
PRKP-1018 : Service felix_ora already enabled.
[oracle@felix1 ~]$
[oracle@felix1 ~]$ srvctl start service -d felix -s felix_ora
[oracle@felix1 ~]$
[oracle@felix1 ~]$ srvctl status service -d felix -s felix_ora
Service felix_ora is running on instance(s) felix1
[oracle@felix1 ~]$
[oracle@felix2 ~]$ crs_stat -t -v
Name Type R/RA F/FT Target State Host
----------------------------------------------------------------------
ora.felix.db application 0/0 0/1 ONLINE ONLINE felix1
ora....x1.inst application 0/5 0/0 ONLINE ONLINE felix1
ora....x2.inst application 0/5 0/0 ONLINE ONLINE felix2
ora...._ora.cs application 0/0 0/1 ONLINE ONLINE felix1
ora....ix1.srv application 0/0 0/0 ONLINE ONLINE felix1
ora....SM1.asm application 0/5 0/0 ONLINE ONLINE felix1
ora....X1.lsnr application 0/5 0/0 ONLINE ONLINE felix1
ora.felix1.gsd application 0/5 0/0 ONLINE ONLINE felix1
ora.felix1.ons application 0/3 0/0 ONLINE ONLINE felix1
ora.felix1.vip application 0/0 0/0 ONLINE ONLINE felix1
ora....SM2.asm application 0/5 0/0 ONLINE ONLINE felix2
ora....X2.lsnr application 0/5 0/0 ONLINE ONLINE felix2
ora.felix2.gsd application 0/5 0/0 ONLINE ONLINE felix2
ora.felix2.ons application 0/3 0/0 ONLINE ONLINE felix2
ora.felix2.vip application 0/0 0/0 ONLINE ONLINE felix2
[oracle@felix2 ~]$
说明已经全部启动了;
新建的服务会自动添加到初始化参数文件中:
SQL> show parameter service
NAME TYPE VALUE
------------------------------------ -----------------------------------------
service_names string felix, felix_ora
SQL>
begin
dbms_service.modify_service(service_name =>'felix_ora',
failover_method =>dbms_service.failover_method_basic,
failover_type =>dbms_service.failover_type_select,
failover_retries =>180,
failover_delay =>5);
end;
/
PL/SQL procedure successfully completed.
8.确认以生效
Set lines 1000 pages 1000
col name for a50
col clb_goal for a15
col FAILOVER_METHOD for a15
col failover_type for a20;
SQL> selectname,failover_method,failover_type,clb_goal from dba_services;
NAME FAILOVER_METHOD FAILOVER_TYPE CLB_GOAL
----------------------------------------------------------------- -------------------- ---------------
SYS$BACKGROUND SHORT
SYS$USERS SHORT
seeddataXDB LONG
seeddata.regress.rdbms.dev.us.oracle.com LONG
felixXDB LONG
felix LONG
taf_server LONG
taf_srvctl LONG
felix_ora BASIC SELECT LONG
9 rows selected.
[oracle@felix1 ~]$ srvctl config service -d felix -a
felix_ora PREF: felix1 AVAIL: felix2 TAF: BASIC
[oracle@felix1 ~]$
无论是通过DBCA图形化工具还是srvctl手工方式创建service,有以下几点需要注意:
1. 数据库的服务名是用service_name参数来指定的,一个数据库可以有多个服务名,但是service_name最长4KB,不要手工修改这个参数。
2. 最多可以创建64个service,每个数据库有两个隐含的service,因此留给用户的就只有62个service。不能修改这两个隐含service的配置,并且也不能手动启动或者停止这两个服务,这两个隐含service分别是SYS$BACKUPGROUD和SYS$USERS。
3. 当使用DBCA配置service时,DBCA会自动更新OCR,启动service,当删除service时,会停止service并更新OCR。
4. 使用SRVCTL这个工具时,命令只会更新OCR中的配置不会更细data dictionary和listener中信息;因此需要使用dbms_sercice包来更新datadictionary,手工更改listener配置文件这里推荐使用DBCA工具来配置更改SERVICE配置。
5. 如果客户端想要通过sercice方式连接数据库,需要在TNS条目中使用service_name方式引用数据库,见下面例子中的粗体部分:
TAF_SERVER =
(DESCRIPTION =
(ADDRESS= (PROTOCOL = TCP)(HOST = felix1-vip)(PORT = 1521))
(ADDRESS= (PROTOCOL = TCP)(HOST = felix2-vip)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = taf_server)
(FAILOVER_MODE =
(TYPE = SELECT)
(METHOD = BASIC)
(RETRIES = 180)
(DELAY = 5)
)
)
)
注意:
无论使用DBCA还是srvctl命令来配置service,都无法配置TAF的type,delay,retries这三个属性,必须使用dbms_service包来修改这些属性。
在oracle 10g中配置Server-Side TAF之后,客户端甚至都不需要tnsnames.ora文件而是使用Oracle 10g提供的新连接方法Easy Connect Naming Methods。这一届就使用这种方法来测试Server-SideTAF.测试之前可以把客户端的tnsnames.ora文件改名存放,以保证客户端在没有TNS的情况下进行这个测试。使用Easy Connecting Methods时的连接串格式如下:
username/password@[//]host[:port][/service_name]
[root@felix1 bin]# cat /etc/hosts
127.0.0.1 localhost
192.168.10.101 felix1
192.168.10.111 felix1-vip
192.168.20.30 felix1-priv
192.168.10.102 felix2
192.168.10.122 felix2-vip
192.168.20.40 felix2-priv
[root@felix1 bin]#
[oracle@felix1 ~]$sqlplus scott/oracle@felix1-vip/felix_ora
SQL*Plus: Release 10.2.0.5.0 - Production on ThuMay 29 23:01:49 2014
Copyright (c) 1982, 2010, Oracle. All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release10.2.0.5.0 - Production
With the Partitioning, Real Application Clusters,OLAP, Data Mining
and Real Application Testing options
SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
felix2
SQL>
可以看到连接到实例2上了
SQL> select name,failover_method,failover_type,clb_goal from dba_services;
NAME FAILOVER_METHOD FAILOVER_TYPE CLB_GOAL
----------------------------------------------------------------- -------------------- ---------------
SYS$BACKGROUND SHORT
SYS$USERS SHORT
seeddataXDB LONG
seeddata.regress.rdbms.dev.us.oracle.com LONG
felixXDB LONG
felix LONG
taf_server LONG
taf_srvctl LONG
felix_ora BASIC SELECT LONG
9 rows selected.
SQL> select pid,spid from v$process
where addr in
(select paddr from v$session whereusername='SCOTT');
PIDSPID
---------- ------------
298154
SQL>
该连接对应的OS进程PID=8154,在OS上杀掉这个进程:
[root@felix2 ~]# ps -ef | grep 8154 |grep -v grep
oracle 8154 1 0 23:01 ? 00:00:00 oraclefelix2 (LOCAL=NO)
[root@felix2 ~]# kill -9 8154
[root@felix2 ~]#
SQL> select instance_name from v$instance;
select instance_name from v$instance
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
等一会儿再在会话中执行
SQL> /
INSTANCE_NAME
----------------
felix2
SQL> /
注意:
(感觉这个实验似乎有些问题,实验时候还是failover到实例2上了,但是我做了一个把实例2shutdown abort的实验,结果如下:
SQL>/
INSTANCE_NAME
----------------
felix1
这次正确failover到了实例2上,kill会话这个实验有所不当,建议用abort;
)
[oracle@felix1 ~]$ srvctl stop service -d felix -s felix_ora
[oracle@felix1 ~]$ srvctl status service -d felix -s felix_ora
Service felix_ora is not running.
[oracle@felix1 ~]$ srvctl remove service -d felix -s felix_ora
felix_ora PREF: felix1 AVAIL: felix2
Remove service felix_ora from the database felix?(y/[n]) y
[oracle@felix1 ~]$ srvctl config service -d felix -a
[oracle@felix1 ~]$
注意:OCR中的内容被删除完了,但是数据字典里还有Service的内容,继续清除数据字典里的内容。查看数据字典内容:
SQL> selectname,failover_method,failover_type,clb_goal from dba_services;
NAME FAILOVER_METHOD FAILOVER_TYPE CLB_GOAL
----------------------------------------------------------------- -------------------- ---------------
SYS$BACKGROUND SHORT
SYS$USERS SHORT
seeddataXDB LONG
seeddata.regress.rdbms.dev.us.oracle.com LONG
felixXDB LONG
felix LONG
taf_server LONG
taf_srvctl LONG
felix_ora BASIC SELECT LONG
9 rows selected.
SQL>
删除数据字典内容:
Begin
Dbms_service.delete_service(service_name=>’felix_ora’);
End;
SQL>begin
2 dbms_service.delete_service(service_name=>'felix_ora');
3 end;
4 /
PL/SQLprocedure successfully completed.
SQL>
在此查询数据字典:
SQL> select name,failover_method,failover_type,clb_goalfrom dba_services;
NAME FAILOVER_METHOD FAILOVER_TYPE CLB_GOAL
----------------------------------------------------------------- -------------------- ---------------
SYS$BACKGROUND SHORT
SYS$USERS SHORT
seeddataXDB LONG
seeddata.regress.rdbms.dev.us.oracle.com LONG
felixXDB LONG
felix LONG
6 rows selected.
此时,已经清除干净!!