系统环境:
操作系统:OEL6.5
Oracle:Oracle 11gR2
DG的架构模式为Physical DG,数据保护模式为:MaxAvailability
1)首先在主库上创建两个服务用于TAF的service
这两个服务在数据库出现故障时会发送通知给客户端,允许查询语句在故障转移发生后继续运行。
--使用sys用户执行
--用于在主库上启动的服务
begin
DBMS_SERVICE.CREATE_SERVICE(service_name => 'dg_taf_prm',
network_name =>'dg_taf_prm',
aq_ha_notifications => TRUE,
failover_method => 'BASIC',
failover_type =>'SELECT',
failover_retries => 30,
failover_delay => 5);
end;
/
--用于在备库上启动的服务
begin
DBMS_SERVICE.CREATE_SERVICE(service_name => 'dg_taf_std',
network_name =>'dg_taf_std',
aq_ha_notifications => TRUE,
failover_method => 'BASIC',
failover_type =>'SELECT',
failover_retries => 30,
failover_delay => 5);
end;
/
2)建立一个存储过程,用于调用service,确保只在主库运行
创建一个存储过程来实现此目的:
如果当前数据库是主库它就启动dg_taf_prm服务,停止dg_taf_std;
如果当前数据库是备库它就启动dg_taf_std服务,停止dg_taf_prm。
--使用sys用户执行
create or replace procedurep_dg_taf is
v_role VARCHAR(30);
begin
select DATABASE_ROLE into v_role from V$DATABASE;
if v_role = 'PRIMARY' then
begin
DBMS_SERVICE.STOP_SERVICE('dg_taf_std');
exception
when others then
null;
end;
begin
DBMS_SERVICE.START_SERVICE('dg_taf_prm');
exception
when others then
null;
end;
else
begin
DBMS_SERVICE.STOP_SERVICE('dg_taf_prm');
exception
when others then
null;
end;
begin
DBMS_SERVICE.START_SERVICE('dg_taf_std');
exception
when others then
null;
end;
end if;
end;
/
3)创建2个触发器来确保服务可以运行
创建两个触发器,让数据库在启动和角色转换时运行此存储过程。
--使用sys用户执行
create or replace TRIGGER tri_dg_taf_startup
after startup on database
begin
p_dg_taf;
end;
/
--使用sys用户执行
create or replace TRIGGER tri_dg_taf_rolechange
after db_role_change on database
begin
p_dg_taf;
end;
/
当数据库切换后,如果是主库则执行存储过程。
4)客户端tnsnames 配置
连接主库的客户端tnsnames 配置:
DG_TAF_PRM =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST =10.1.5.8)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST =10.1.5.9)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = dg_taf_prm)
(FAILOVER_MODE =(TYPE = SESSION)(METHOD =BASIC)(RETRIES = 180)(DELAY = 5))
)
)
连接备库的客户端tnsnames 配置:
DG_TAF_STD =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST =10.1.5.9)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST =10.1.5.8)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = dg_taf_std)
(FAILOVER_MODE =(TYPE = SESSION)(METHOD =BASIC)(RETRIES = 180)(DELAY = 5))
)
)
注:10.1.5.8 是当前主库,10.1.5.9 是当前备库
1. 首先在主备库上执行该存储过程(或者重启数据库,在启动数据库时会触发执行p_dg_taf的触发器)
主库:
--使用sys用户执行
execute p_dg_taf;
--在主库做日志的切换,将变化应用到备库
alter system switch logfile;
备库:
--使用sys用户执行
execute p_dg_taf;
此时主库监听状态:
[oracle@host8 ~]$ lsnrctlstatus
服务摘要..
服务 "+ASM" 包含 1 个实例。
实例 "+ASM", 状态 READY, 包含此服务的 1 个处理程序...
服务 "dg_taf_prm" 包含 1 个实例。
实例 "orcl", 状态 READY, 包含此服务的 1 个处理程序...
服务 "orcl" 包含 1 个实例。
实例 "orcl", 状态 READY, 包含此服务的 1 个处理程序...
服务 "orclXDB" 包含 1 个实例。
实例 "orcl", 状态 READY, 包含此服务的 1 个处理程序...
服务 "orcl_DGB" 包含 1 个实例。
实例 "orcl", 状态 READY, 包含此服务的 1 个处理程序...
此时备库监听状态:
[oracle@host9 ~]$ lsnrctlstatus
服务摘要..
服务 "+ASM" 包含 1 个实例。
实例 "+ASM", 状态 READY, 包含此服务的 1 个处理程序...
服务 "dg_taf_std" 包含 1 个实例。
实例 "orcl2",状态 READY, 包含此服务的 1 个处理程序...
服务 "orcl2" 包含 1 个实例。
实例 "orcl2",状态 READY, 包含此服务的 1 个处理程序...
服务 "orcl2_DGB" 包含 1 个实例。
实例 "orcl2",状态 READY, 包含此服务的 1 个处理程序...
2. 在备库查询
SQL> select trigger_namefrom dba_triggers where trigger_name like '%DG%';
TRIGGER_NAME
---------------------------------------------------------------------------
TRI_DG_TAF_STARTUP
TRI_DG_TAF_ROLECHANGE
3. 客户端连接测试
连接主库:
$ sqlplus system/xxxxx@dg_taf_prm
set lines 300
show parameter name
SQL> selectopen_mode,DATABASE_ROLE from v$database;
OPEN_MODE DATABASE_ROLE
------------------------------------------------------------------------------
READ WRITE PRIMARY
连接备库:
$ sqlplussystem/xxxxx@dg_taf_std
set lines 300
show parameter name
SQL> selectopen_mode,DATABASE_ROLE from v$database;
OPEN_MODE DATABASE_ROLE
-------------------------------------------------------------------------------
READ ONLY WITH APPLY PHYSICAL STANDBY
4、主备库切换后的TAF测试之连接测试:
1)主库切换成备库:
ALTER DATABASE COMMIT TOSWITCHOVER TO PHYSICAL STANDBY WITH SESSION SHUTDOWN;
2) 备库切换成主库:
ALTER DATABASE COMMIT TOSWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN;
--可再次通过步骤3的测试查看主库连接情况
这样,在swichover或failover切换后,在不改变应用连接的情况下,在数据库上就完成的服务的连接的改变,主库始终用于连接服务dg_taf_prm,备库始终连接服务dg_taf_std
如果想实现多个备库连接的负载均衡,可以这样配置
连接多个备库的客户端tnsnames 配置
DG_TAF_STD =
(DESCRIPTION =
(LOAD_BALANCE = ON)
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST =10.1.5.9)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST =10.1.5.10)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST =10.1.5.11)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = dg_taf_std)
(FAILOVER_MODE =(TYPE = SESSION)(METHOD =BASIC)(RETRIES = 180)(DELAY = 5))
)
)
问题1:
备注:ORA-25408: 无法安全重放调用 参考:http://www.itpub.net/thread-1327198-1-1.html 把TYPE 改为= SELECT后,坏节点的库启动后,会话不会转到修好的坏节点上。
问题2
对于执行存储过程后,service_name变了的问题,如下:
SQL> show parameterservice_names
NAME TYPE VALUE
-------------------------------------------------------------------- ------------------------------
service_names string orcl
SQL> show parameterservice_names
NAME TYPE VALUE
-------------------------------------------------------------------- ------------------------------
service_names string dg_taf_prm
SQL> alter system setservice_names='orcl';
SQL> execute p_dg_taf;
SQL> show parameterservice_names
NAME TYPE VALUE
--------------------------------------------------------------------- ------------------------------
service_names string orcl, dg_taf_prm
注:
作者:客居天涯 发布日期:2014-04-2408:51:34
此篇文章为转载,感谢客居天涯的原创,同事测试改编,也经过我的测试和修改。