首页 数据库 mysql教程 Data Guard环境做到Client的自动切换

Data Guard环境做到Client的自动切换

Jun 07, 2016 pm 05:36 PM

使用Data guard作为HA方案,要解决的一个问题在于:后台数据库发生了主备切换,client连接如何做到自动切到新的primary数据库上?

使用Data guard作为HA方案,要解决的一个问题在于:后台数据库发生了主备切换,client连接如何做到自动切到新的primary数据库上?
 
如果做通用的方案,需要客户端自己提供自动重连的能力,这点大多数java的occi的连接池都有实现。
 
但这些已有实现大多是对同一连接配置发起重连,所以需要考虑为application提供透明的连接方式,而不让应用看到具体data guard的多个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配置成
 
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数据库运行
 
 begin
  dbms_service.create_service("myapp","myapp");
 end;
 /
 begin
  DBMS_SERVICE.START_SERVICE("myapp");
 end;
 /
 
 3.在primary数据库创建触发器:
 
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上做任何设置,因为data guard会自动将变化同步到standby数据库。
 
通过在primary数据库运行下面程序,可以让客户端在做select的时候甚至意识不到数据库的切换:
 
begin
  dbms_service.modify_service
  ("myapp",
  FAILOVER_METHOD => "BASIC",
  FAILOVER_TYPE => "SELECT",
  FAILOVER_RETRIES => 200,
  FAILOVER_DELAY => 1);
 end;
 /
 
注意如果在切换时有comit的提交事务发生,还是会出现失误提交失败,要求回滚的情况。
 
 
 
下面tns是另一种配置方式(类似rac的failover配置思想),,使用这种方式,不需要在Oracle server中运行任何plsql脚本,在DESCRIPTION_LIST中的两个数据库甚至根本不需要处于data guard中,可以是任意两个数据库。driver会按顺序遍历list中的数据库,一直到能连接上为止。
 
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的那个数据库。

推荐阅读:

RMAN 配置归档日志删除策略

Oracle基础教程之通过RMAN复制数据库

RMAN备份策略制定参考内容

RMAN备份学习笔记

Oracle数据库备份加密 RMAN加密

linux

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何使用Alter Table语句在MySQL中更改表? 如何使用Alter Table语句在MySQL中更改表? Mar 19, 2025 pm 03:51 PM

本文讨论了使用MySQL的Alter Table语句修改表,包括添加/删除列,重命名表/列以及更改列数据类型。

如何为MySQL连接配置SSL/TLS加密? 如何为MySQL连接配置SSL/TLS加密? Mar 18, 2025 pm 12:01 PM

文章讨论了为MySQL配置SSL/TLS加密,包括证书生成和验证。主要问题是使用自签名证书的安全含义。[角色计数:159]

哪些流行的MySQL GUI工具(例如MySQL Workbench,PhpMyAdmin)是什么? 哪些流行的MySQL GUI工具(例如MySQL Workbench,PhpMyAdmin)是什么? Mar 21, 2025 pm 06:28 PM

文章讨论了流行的MySQL GUI工具,例如MySQL Workbench和PhpMyAdmin,比较了它们对初学者和高级用户的功能和适合性。[159个字符]

您如何处理MySQL中的大型数据集? 您如何处理MySQL中的大型数据集? Mar 21, 2025 pm 12:15 PM

文章讨论了处理MySQL中大型数据集的策略,包括分区,碎片,索引和查询优化。

说明InnoDB全文搜索功能。 说明InnoDB全文搜索功能。 Apr 02, 2025 pm 06:09 PM

InnoDB的全文搜索功能非常强大,能够显着提高数据库查询效率和处理大量文本数据的能力。 1)InnoDB通过倒排索引实现全文搜索,支持基本和高级搜索查询。 2)使用MATCH和AGAINST关键字进行搜索,支持布尔模式和短语搜索。 3)优化方法包括使用分词技术、定期重建索引和调整缓存大小,以提升性能和准确性。

如何使用Drop Table语句将表放入MySQL中? 如何使用Drop Table语句将表放入MySQL中? Mar 19, 2025 pm 03:52 PM

本文讨论了使用Drop Table语句在MySQL中放下表,并强调了预防措施和风险。它强调,没有备份,该动作是不可逆转的,详细介绍了恢复方法和潜在的生产环境危害。

您如何用外国钥匙代表关系? 您如何用外国钥匙代表关系? Mar 19, 2025 pm 03:48 PM

文章讨论了使用外国密钥来代表数据库中的关系,重点是最佳实践,数据完整性和避免的常见陷阱。

如何在JSON列上创建索引? 如何在JSON列上创建索引? Mar 21, 2025 pm 12:13 PM

本文讨论了在PostgreSQL,MySQL和MongoDB等各个数据库中的JSON列上创建索引,以增强查询性能。它解释了索引特定的JSON路径的语法和好处,并列出了支持的数据库系统。

See all articles