楼主: nboding

[HA] DG切换后IP问题

[复制链接]
论坛徽章:
5
双黄蛋
日期:2011-07-05 09:45:13咸鸭蛋
日期:2011-07-12 23:03:41ITPUB十周年纪念徽章
日期:2011-11-01 16:25:22双黄蛋
日期:2011-12-26 15:28:03ITPUB 11周年纪念徽章
日期:2012-10-09 18:13:33
11#
发表于 2011-7-5 09:43 | 只看该作者
配置一个额外的IP,切换库的时候,切换IP地址

使用道具 举报

回复
论坛徽章:
40
ITPUB元老
日期:2011-07-08 18:04:16紫蛋头
日期:2012-12-05 21:25:20鲜花蛋
日期:2012-12-12 10:09:59灰彻蛋
日期:2013-01-06 12:21:11蛋疼蛋
日期:2013-02-20 13:13:212013年新春福章
日期:2013-02-25 14:51:24茶鸡蛋
日期:2013-04-18 15:54:10兰博基尼
日期:2013-08-06 16:35:32雪佛兰
日期:2013-08-06 17:13:19福特
日期:2013-08-27 12:05:26
12#
发表于 2011-7-5 21:28 | 只看该作者
人气不旺啊

使用道具 举报

回复
论坛徽章:
0
13#
 楼主| 发表于 2011-7-6 15:31 | 只看该作者

回复 #11 Cloudhorizon 的帖子

所答非所问啊

使用道具 举报

回复
论坛徽章:
0
14#
 楼主| 发表于 2011-7-6 15:31 | 只看该作者

回复 #12 valiancy 的帖子

求给力

使用道具 举报

回复
论坛徽章:
16
2009日食纪念
日期:2015-08-13 16:27:552011新春纪念徽章
日期:2015-08-13 16:27:552010广州亚运会纪念徽章:皮划艇
日期:2015-08-13 16:27:552010世博会纪念徽章
日期:2015-08-13 16:27:55ITPUB9周年纪念徽章
日期:2015-08-13 16:27:55ITPUB9周年纪念徽章
日期:2015-08-13 16:27:55数据库板块每日发贴之星
日期:2015-08-13 16:27:552010新春纪念徽章
日期:2015-08-13 16:27:55生肖徽章2007版:虎
日期:2015-08-13 16:27:55ITPUB8周年纪念徽章
日期:2015-08-13 16:27:55
15#
发表于 2011-7-8 07:18 | 只看该作者
可以指定一个服务IP

使用道具 举报

回复
论坛徽章:
0
16#
 楼主| 发表于 2011-7-10 09:49 | 只看该作者

回复 #15 ludal 的帖子

没太理解你的意思 能否详细说下

使用道具 举报

回复
论坛徽章:
0
17#
发表于 2011-7-23 13:52 | 只看该作者
Switchover无损转换,通常是用户手动触发或者有计划的让其自动触发,比如硬件升级啦,软件升级啦之类的。Switchover又不会自动,一般是手动。既然已经是手动了,再手动改一下F5上的配置也不过是举手之劳了。

使用道具 举报

回复
论坛徽章:
0
18#
发表于 2011-7-23 14:27 | 只看该作者
http://ppgunjack.iteye.com/blog/1058610
使用dataguard作为HA方案,要解决的一个问题在于:后台数据库发生了切换,client连接如何做到自动切到新的primary数据库上?

如果做通用的方案,需要客户端自己提供自动重连的能力,这点大多数java的occi的连接池都有实现。

但这些已有实现大多是对同一连接配置发起重连,所以需要考虑为application提供透明的连接方式,而不让应用看到具体dataguard的多个ip和service name,这就需要做些额外的配置工作。

一种方式通过vip,真实转发的ip只挂靠在有效数据库的ip上。这种方式切换发生后,application在断连的旧connection上发起dml会获得ORA-3113 "end of file on communication channel"的错误,此时application可以尝试重连机制和新的primary建立连接。

在f5上可以通过设置心跳sql和期望的返回结果内容,以类似ping方式获取远端数据库是否可用,来决定ip是否应该转发到该物理ip上。

另一种方式是通过设置tns和数据库暴露的service name来访问,通过合理设置,甚至可以做到在发生切换时的select操作仅仅被阻塞一会,而完全意识不到数据库已经完成了主备切换。

步骤如下:

1.客户端的tnsnames.ora中tns配置成

Xml代码  
MYAPP =   
(DESCRIPTION =   
(ADDRESS_LIST =   
(ADDRESS = (PROTOCOL = TCP)(HOST = HostA)(PORT = 1521))   
(ADDRESS = (PROTOCOL = TCP)(HOST = HostB)(PORT = 1521))   
)   
(CONNECT_DATA =   
(SERVICE_NAME = <SPAN style="COLOR: #ff0000">myapp</SPAN>)   
)   
)  

MYAPP =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = HostA)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = HostB)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = myapp)
)
)



2.在primary数据库运行

Sql代码  
begin  
dbms_service.create_service('myapp','myapp');   
end;   
/   
begin  
DBMS_SERVICE.START_SERVICE('myapp');   
end;   
/  

begin
dbms_service.create_service('myapp','myapp');
end;
/
begin
DBMS_SERVICE.START_SERVICE('myapp');
end;
/ 3.在primary数据库创建触发器:

Sql代码  
create trigger myapptrigg after startup on database  
declare  
v_role varchar(30);   
begin  
select database_role into v_role from v$database;   
if v_role = 'PRIMARY' then  
DBMS_SERVICE.START_SERVICE('myapp');   
else  
DBMS_SERVICE.STOP_SERVICE('myapp');   
end if;   
end;   
/  

create trigger myapptrigg after startup on database
declare
v_role varchar(30);
begin
select database_role into v_role from v$database;
if v_role = 'PRIMARY' then
DBMS_SERVICE.START_SERVICE('myapp');
else
DBMS_SERVICE.STOP_SERVICE('myapp');
end if;
end;
/解释下:这个方案的思路就是将两边的数据库的service name都设置成'myapp',当发生切换时,由触发器在数据库startup的时候把primary的实例以'myapp'的名字暴露,而把standby的'myapp'服务名给停掉,这样任何时刻只有主节点暴露名字为'myapp'的服务。

注意这里的plsql都是跑在primary,无需在standby上做任何设置,因为dataguard会自动将变化同步到standby数据库。

通过在primary数据库运行下面程序,可以让客户端在做select的时候甚至意识不到数据库的切换:

Sql代码  
begin  
dbms_service.modify_service   
('myapp',   
FAILOVER_METHOD => 'BASIC',   
FAILOVER_TYPE => 'SELECT',   
FAILOVER_RETRIES => 200,   
FAILOVER_DELAY => 1);   
end;   
/  

begin
dbms_service.modify_service
('myapp',
FAILOVER_METHOD => 'BASIC',
FAILOVER_TYPE => 'SELECT',
FAILOVER_RETRIES => 200,
FAILOVER_DELAY => 1);
end;
/注意如果在切换时有comit的提交事务发生,还是会出现失误提交失败,要求回滚的情况。



下面tns是另一种配置方式,使用这种方式,不需要在oracle server中跑任何plsql脚本,在DESCRIPTION_LIST中的两个数据库甚至根本不需要处于dataguard中,可以是任意两个数据库。driver会按顺序遍历list中的数据库,一直到能连接上为止。

Xml代码  
MYAPP =   
(DESCRIPTION_LIST=   
(LOAD_BALANCE=off)   
  (FAILOVER=on)   
  (DESCRIPTION =(CONNECT_TIMEOUT=5)(TRANSPORT_CONNECT_TIMEOUT=3)(RETRY_COUNT=10)   
    (ADDRESS_LIST =   
      (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))   
    )   
    (CONNECT_DATA =   
      (SERVICE_NAME = myapp1)   
    )   
  )   
  (DESCRIPTION =(CONNECT_TIMEOUT=5)(TRANSPORT_CONNECT_TIMEOUT=3)(RETRY_COUNT=10)   
    (ADDRESS_LIST =   
      (ADDRESS = (PROTOCOL = TCP)(HOST = otherIP)(PORT = 1521))   
    )   
    (CONNECT_DATA =   
      (SERVICE_NAME = myapp2)   
    )   
  )   
)  

MYAPP =
(DESCRIPTION_LIST=
(LOAD_BALANCE=off)
  (FAILOVER=on)
  (DESCRIPTION =(CONNECT_TIMEOUT=5)(TRANSPORT_CONNECT_TIMEOUT=3)(RETRY_COUNT=10)
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = myapp1)
    )
  )
  (DESCRIPTION =(CONNECT_TIMEOUT=5)(TRANSPORT_CONNECT_TIMEOUT=3)(RETRY_COUNT=10)
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = otherIP)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = myapp2)
    )
  )
)

这种方式需要注意的地方:

1.jdbc必须走oci的方式,如果为jdbc:thin+tns方式,则会出现

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 545
at oracle.net.nl.NVTokens.parseTokens(Unknown Source)
at oracle.net.nl.NVFactory.createNVPair(Unknown Source)


其原因在于jdbc的driver本身无法识别这种格式的tns内容。

此时即使以jdbc:thin+tns的方式访问其他正常的tns也会一样抛出这个错误,因为这导致了jdbc根本无法正确解析整个tnsnames.ora文件。

而jdbc:oci实际上负责解析tnsnames.ora和处理通信的是依赖oci.lib,因此就不存在这个问题。

2.这种配置适用于任何依赖oci通信的客户端,包括oci,occi,一些基于它们的wrap库,以及pl/sql developer此类的工具软件。

3.注意如果连接的数据库组属于manually switch的模式,而不是fail down导致的切换,比如tns中的a数据库是mount状态,b是primary,而tns的列表顺序是先a后b,则会出现尽管客户端连a时,抛出ORA-0133错误,但是不会按顺序去尝试连接b。

原因是在处理这个链接时,oci客户端会尝试通过listener和service建立连接。

如果listener是关闭的,或者客户端能连上listener但是找不到对应service,则都会尝试连接处于第二个的b,但是如果通过listener找到了对端的service,只是无法建立连接(如数据库处于mount状态),则此时不会尝试连接b,而直接会以抛出

ORA-0133:ORACLE initialization or shutdown in progress

终止连接尝试。

所以在使用这种tns的时候要确保通过tns列表能访问到的所有数据库都不会一直处于mount状态,否则连接它会打断对后面正常open数据库的连接尝试。

这也是为何手动切换的dataguard数据库,客户端不能依赖这种tns配置方法做自动切换,因为手动切换的dataguard数据库状态肯定是一个open一个mount,如果mount处于tns的列表靠前的位置,在连接它失败后会抛出ORA-0133异常阻止客户端尝试连接正常open的那个数据库。

使用道具 举报

回复
论坛徽章:
317
季节之章:春
日期:2012-06-20 17:38:14季节之章:夏
日期:2012-06-12 10:49:25季节之章:秋
日期:2012-06-12 10:49:25季节之章:冬
日期:2012-06-12 10:49:25马上有钱
日期:2014-06-16 15:59:19蓝色妖姬
日期:2012-05-19 11:02:10蓝色妖姬
日期:2012-06-12 11:21:48蓝色妖姬
日期:2012-06-12 11:21:48玉兔
日期:2012-07-27 11:00:12玉兔
日期:2012-08-05 10:00:09
19#
发表于 2011-7-23 17:09 | 只看该作者
好复杂啊
有没有简单点的。采用虚拟IP怎么实现呢,非要配置HA么

使用道具 举报

回复
论坛徽章:
0
20#
 楼主| 发表于 2011-7-25 17:45 | 只看该作者

回复 #18 pengle44 的帖子

谢谢你的精彩回复  
还有问题请教下,如果我采用HA的方式,是否能通过配置两个listener来实现,主库的监听是打开的,当发生切换时将vip切过去同时启动新的监听。

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表