使用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配置成

  1. MYAPP =
  2. (DESCRIPTION =
  3. (ADDRESS_LIST =
  4. (ADDRESS = (PROTOCOL = TCP)(HOST = HostA)(PORT = 1521))
  5. (ADDRESS = (PROTOCOL = TCP)(HOST = HostB)(PORT = 1521))
  6. )
  7. (CONNECT_DATA =
  8. (SERVICE_NAME = <span style="color: #ff0000;">myapp</span>)
  9. )
  10. )

2.在primary数据库运行

  1. begin
  2. dbms_service.create_service('myapp','myapp');
  3. end;
  4. /
  5. begin
  6. DBMS_SERVICE.START_SERVICE('myapp');
  7. end;
  8. /

3.在primary数据库创建触发器:

  1. create trigger myapptrigg after startup on database
  2. declare
  3. v_role varchar(30);
  4. begin
  5. select database_role into v_role from v$database;
  6. if v_role = 'PRIMARY' then
  7. DBMS_SERVICE.START_SERVICE('myapp');
  8. else
  9. DBMS_SERVICE.STOP_SERVICE('myapp');
  10. end if;
  11. end;
  12. /

解释下:这个方案的思路就是将两边的数据库的service name都设置成'myapp',当发生切换时,由触发器在数据库startup的时候把primary的实例以'myapp'的名字暴露,而把 standby的'myapp'服务名给停掉,这样任何时刻只有主节点暴露名字为'myapp'的服务。

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

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

  1. begin
  2. dbms_service.modify_service
  3. ('myapp',
  4. FAILOVER_METHOD => 'BASIC',
  5. FAILOVER_TYPE => 'SELECT',
  6. FAILOVER_RETRIES => 200,
  7. FAILOVER_DELAY => 1);
  8. end;
  9. /

注意如果在切换时有comit的提交事务发生,还是会出现失误提交失败,要求回滚的情况。

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

  1. MYAPP =
  2. (DESCRIPTION_LIST=
  3. (LOAD_BALANCE=off)
  4. (FAILOVER=on)
  5. (DESCRIPTION =(CONNECT_TIMEOUT=5)(TRANSPORT_CONNECT_TIMEOUT=3)(RETRY_COUNT=10)
  6. (ADDRESS_LIST =
  7. (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
  8. )
  9. (CONNECT_DATA =
  10. (SERVICE_NAME = myapp1)
  11. )
  12. )
  13. (DESCRIPTION =(CONNECT_TIMEOUT=5)(TRANSPORT_CONNECT_TIMEOUT=3)(RETRY_COUNT=10)
  14. (ADDRESS_LIST =
  15. (ADDRESS = (PROTOCOL = TCP)(HOST = otherIP)(PORT = 1521))
  16. )
  17. (CONNECT_DATA =
  18. (SERVICE_NAME = myapp2)
  19. )
  20. )
  21. )

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

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的那个数据库。

dataGuard client 自动切换的更多相关文章

  1. DataGuard failover dg role自动切换模式测试

    1,在脚本中代入create db flash backup point for recover dg 2,测试前主备库状态(备库现角色验证,主库监听状态-->有意stop) 主要验证思路, 脚 ...

  2. Linux -- 之HDFS实现自动切换HA(全新HDFS)

    Linux -- 之HDFS实现自动切换HA(全新HDFS) JDK规划 1.7及以上  https://blog.csdn.net/meiLin_Ya/article/details/8065094 ...

  3. 协程-遇到I/O自动切换

    参考博客:http://www.cnblogs.com/alex3714/articles/5248247.html 一.前言 Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步 ...

  4. Mycat主从模式下的读写分离与自动切换

    1. 机器环境 192.168.2.136 mycat1 192.168.2.134 mydb1 192.168.2.135 mydb2 2在mysql1.mysql2上安装mysql 更改root用 ...

  5. 协程:gevent模块,遇到i/o自动切换任务 038

    协程 : gevent模块,遇到io自动切换任务 from gevent import monkey;monkey.patch_all() # 写在最上面 这样后面的所有阻塞就全部能够识别了 impo ...

  6. 【python】-- 协程介绍及基本示例、协程遇到IO操作自动切换、协程(gevent)并发爬网页

    协程介绍及基本示例 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是协程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他 ...

  7. 原生js+css3实现图片自动切换,图片轮播

    运用CSS3transition及opacity属性 制作图片轮播动画 自己这两天根据用js来控制触发CSS3中transition属性,从而写出来的以CSS3动画为基础,js控制过程的图片轮播 运用 ...

  8. 获取bing.com的图片并在gnome3中设置自动切换

    发现 bing.com 上的图片很好看,因此打算每天把 bing.com 的图片下载下来,用作桌面. 需要做的是两个部分,爬取图片到目录和设置目录图片为桌面背景并可以自动切换. 第一部分,下载图片,使 ...

  9. 在 Visual Studio 等编辑器/IDE中自动切换输入法,不需要手动的有没有?

    使用Visual Studio写代码,经常遇到的一个问题就是切换中文输入法麻烦,输入完注释//,要切换到中文,输入完引号,要输入中文,然后还需要切换回来,有没有? 有时候中文输入法忽然失效有没有?明明 ...

随机推荐

  1. 下载PHPDroid: 基于WebView和PHP内置HTTP服务器开发Android应用

    基于Android上的PHP(比如我打包的PHPDroid),寥寥几行PHP代码,就能实现一个支持无线局域网用浏览器访问的Android手机的Shell,用于执行命令和PHP代码.       个人在 ...

  2. 习惯使用断言Assert

    一直在给党做项目,我们这些可怜兮兮的学生都没太多时间安排自己的活动了,写个blog都要在中午休息的时间. 项目用的是.NET,本来也想分享一些干货点的东西,但博客园里的前辈把这类文章已经分享泛滥了,想 ...

  3. 为Delphi程序增加UAC功能

    相关资料:http://bbs.csdn.net/topics/320071356# 操作方法: 在Source\VCL目录下应该有这样两个文件sample.manifest和WindowsXP.rc ...

  4. 30分钟学会使用grunt打包前端代码【mark】

    grunt 是一套前端自动化工具,一个基于nodeJs的命令行工具,一般用于:① 压缩文件② 合并文件③ 简单语法检查 对于其他用法,我还不太清楚,我们这里简单介绍下grunt的压缩.合并文件,初学, ...

  5. iOS 开发的几种手势

    今天为大家介绍一下IOS 的七种手势,手势在开发中经常用到,所以就简单 通俗易懂的说下, 话不多说,直接看代码: // 初始化一个UIimageView UIImageView *imageView ...

  6. (转)iOS开发ARC内存管理技术要点

    转自:http://www.cnblogs.com/flyFreeZn/p/4264220.html 本文来源于我个人的ARC学习笔记,旨在通过简明扼要的方式总结出iOS开发中ARC(Automati ...

  7. kindeditor更改图片上传时网络图片的路径

    当我们想要使用kindeditor的图片上传功能时,有两种选择图片方式,一种是本地选择,一种是在图片空间中选择,图片空间的默认地址是server上的/kindeditor/attached/image ...

  8. 华为OJ机试训练(一)

    题目1 -- 通过输入英文句子.将每一个单词反过来,标点符号顺序不变.非26个字母且非标点符号的情况就可以标识单词结束. 标点符号包含,.!? 比如输入:Hello, I need an apple. ...

  9. mybatisnet轻量级ORM框架

    https://code.google.com/p/mybatisnet/source/checkout http://blog.csdn.net/arvinstudy/article/details ...

  10. Apache经常使用配置

      Apache採用IBM HTTPServer,内核为Apache/2.0.47 Server version: IBM_HTTP_Server/6.1.0.13 Apache/2.0.47   查 ...