在Oracle RAC环境下,在配置TAF(Transparent Application Failover)之后,如果一个节点上的实例出现了故障,Oracle会自动将会话迁移到另一个实例上。
进行TAF配置,要在客户端的tnsname.ora中添加如下的关键参数:
( failover_mode = ( type =select) ( method = basic ) )
下面分别对是否在客户端配置TAF的情况进行测试:
一、不配置TAF的情况
1、客户端的tnsname.ora配置如下:
RACDB =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.171)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = racdb.chenxu.yo2.cn)
)
)
2、连接数据库,检查实例信息
SQL> conn sys/chenxu@racdb as sysdba
已连接。
SQL> show parameter instance_name
NAMETYPEVALUE
------------------------------------ ----------- ------------------------------
instance_namestringRACDB2
3、关闭实例RACDB2
[root@NODE01 bin]# ./srvctl status database -d racdb
Instance RACDB1 is running on node node01
Instance RACDB2 is running on node node02
[root@NODE01 bin]#
[root@NODE01 bin]#./srvctl stop instance -d racdb -i racdb2
[root@NODE01 bin]#
[root@NODE01 bin]# ./srvctl status database -d racdb
Instance RACDB1 is running on node node01
Instance RACDB2 is not running on node node02
4、再次检查刚才连接的会话
SQL> select instance_name from v$instance;
select instance_name from v$instance
*
第1行出现错误:
ORA-03113:通信通道的文件结束
SQL> select instance_name from v$instance;
ERROR:
ORA-03114:未连接到ORALCE
可以看到执行操作后,Oracle会报上面的错误。
二、配置TAF的情况
1、下面在客户端的tnsname.ora文件中配置TAF,内容如下:
RACDB =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.171)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = racdb.chenxu.yo2.cn)
( failover_mode = ( type = select ) ( method = basic ) )
)
)
2、重新开启实例
[root@NODE01 bin]# ./srvctl start instance -d racdb -i racdb2
[root@NODE01 bin]#
[root@NODE01 bin]# ./srvctl status database -d racdb
Instance RACDB1 is running on node node01
Instance RACDB2 is running on node node02
3、重新登陆,检查实例信息
SQL> conn sys/chenxu@racdb as sysdba
已连接。
SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
RACDB2
4、再次关闭实例RACDB2
[root@NODE01 bin]# ./srvctl stop instance -d racdb -i racdb2
[root@NODE01 bin]# ./srvctl status database -d racdb
Instance RACDB1 is running on node node01
Instance RACDB2 is not running on node node02
5、检查刚才的连接的会话
SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
RACDB1#可以看到由原来的RACDB2变成RACDB1
可知,在没有运行事务的操作下,可以无缝地切换到另一个节点上。
三、配置TAF后,当运行事务时候,能否进行切换?
在实际的使用环境中,有些正在进行的事务,如一个节点上正在执行的DML是无法采用以上的方法切换的。下面针对这种情况进行测试:
1、两个实例都开启后,客户端连接,并执行DML语句
SQL> conn sys/chenxu@racdb as sysdba
已连接。
SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
RACDB2
SQL> create table test as select * from dba_objects;
表已创建。
SQL> insert into test select * from dba_objects;#进行DML操作
已创建50393行。
2、关闭当前连接的实例RACDB2
[root@NODE01 bin]# ./srvctl stop instance -d racdb -i racdb2
[root@NODE01 bin]# ./srvctl status database -d racdb
Instance RACDB1 is running on node node01
Instance RACDB2 is not running on node node02
3、检查刚才的连接的会话
SQL> select instance_name from v$instance;
select instance_name from v$instance
*
第1行出现错误:
ORA-25402:事务处理必须重新运行
SQL> select count(*) from test;
select count(*) from test
*
第1行出现错误:
ORA-25402:事务处理必须重新运行
SQL> commit;
commit
*
第1行出现错误:
ORA-25402:事务处理必须重新运行
SQL> rollback;
回退已完成。
SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
RACDB1#在rollback之后,切换到实例RACDB1
SQL> select count(*) from test;
COUNT(*)
----------
50393#已经回滚到建表时候的那些数据
所以,该测试说明了Oracle不能切换正在执行DML语句的情况,因为未完成的事务可能需要回滚。也就是只要没有获得的事务存在,就可以动态的切换过去。