> 数据库 > Oracle >

oracle11g dataguard完全手册2--switchover

四、switchover主备切换
         DG的主要用途是HA高可用性,既然已经搭建好了主备环境,那现实环境中可能存在以下几种情况。
  由于某种原因我们需要切换主备身份,即主备切换(Switchover)
  主库故障,需要启用备库为主库,即故障转移(Failover)
  客户端实现自动的故障转移-客户端故障转移(Client Failover)
  下面就这几种情况以及使用闪回数据库重建库,活动数据卫士(Active Data Guard),进行讨论。

   1.查看库所在的保护模式和身份
   sql>select protection_mode,protection_level from v$database; --默认是最大性能模式(maximum performance)
   sql>select database_role from v$database; --主库是primary备库是physical standby
          SQL > alter database set standby database to maximize protection;    --最大保护
          SQL > alter database set standby database to maximize availability;  --最高可用性
          SQL > alter database set standby database to maximize performance;   --最高性能
   这里简要说明下这几种保护模式的区别:
   最大保护:这种模式能够确保绝无数据丢失。要实现这一步当然是有代价的,它要求所有的事务在提交前其 redo 不仅
              被写入到本地的 online redo log,还要同时提交到 standby 数据库的 standbyredo log,并确认 redo 数据至少在一
              个 standby 数据库可用(如果有多个的话),然后才会在 primary 数据库上提交。如果出现了什么故障导致 standby
               数据库不可用的话,primary 数据库会被 shutdown。
   最高性能:这种模式提供在不影响 primary 数据库性能前提下最高级别的数据保护策略。事务可以随时提交,当前
               primary 数据库的 redo 数据也需要至少写入一个 standby 数据库,不过这种写入可以是不同步的。
               如果网络条件理想的话, 这种模式能够提供类似最高可用性的数据保护而仅对 primary 数据库有轻微的性能影响。
   最高可用性:这种模式提供在不影响 primary 数据库可用前提下最高级别的数据保护策略。 其实现方式与最大保护模式类
               似,也是要求所有事务在提交前必须保障 redo 数据至少在一个 standby 数据库可用,不过与之不同的是,如果
               出现故障导入无法同时写入 standby 数据库 redo log,primary 数据库并不会 shutdown,而是自动转为最高性能
               模式,等 standby 数据库恢复正常之后,它又会再自动转换成最高可用性模式。

 2.故障转移配置
   现在你已经配好了一个物理备库,你可能想试试主备切换(switchover),甚至故障转移(failover),但你先得确定客户端会跟着切换和转移。
   我们需要配置数据库和客户端来支持这些功能。要确定你的客户端能连接到正确的数据库,你要在数据库里配置一个支持故障转移的服务,
   并配置客户端的 TNS,让它知道如何在一个 Data Guard 集群里找到主库。

   (1)主库创建自动转移服务:
      此服务在数据库出现故障时会发送通知给客户端,允许查询语句在故障转移发生后继续运行。
      我使用命名 SID_RW 显示这时一个可读写的数据库(主库)。
    begin
     DBMS_SERVICE.CREATE_SERVICE (
  service_name => 'orcl_RW',
  network_name => 'orcl_RW',
  aq_ha_notifications => TRUE,
  failover_method => 'BASIC',
  failover_type => 'SELECT',
  failover_retries => 30,
  failover_delay => 5);
    end; /

    (2)创建存储过程确保只在主库运行
      我们创建一个存储过程来实现此目的,如果当前数据库是主库它就启动此服务,如果是备库就停止。
       create or replace procedure cmc_taf_service_proc
       is
      v_role VARCHAR(30);
  begin
      select DATABASE_ROLE into v_role from V$DATABASE;
      if v_role = 'PRIMARY' then
   DBMS_SERVICE.START_SERVICE('orcl_RW');
      else
   DBMS_SERVICE.STOP_SERVICE('orcl_RW');
      end if;
  end;
  /

     (3)创建触发器(2个)来确保服务可以运行
        创建两个触发器,让数据库在启动和角色转换时运行此存储过程。注意有的文档说是建立一个,那可能会导致你
        在重启你的数据库时,它不会重启故障转移服务
         create or replace TRIGGER cmc_taf_service_trg_startup
  after startup on database
  begin
      cmc_taf_service_proc;
  end;
  /

  create or replace TRIGGER cmc_taf_manage_trg_rolechange
  after db_role_change on database
  begin
      cmc_taf_service_proc;
  end;
  /

            (4)启动服务
       我们执行一次存储过程,确定服务正在运行,并归档当前日志,让以上更改同步到备库。
       SQL> exec cmc_taf_service_proc;
              SQL> alter system archive log current;
              查看服务信息
       SQL> show parameter service_names

      (5)客户端配置TNS
        服务名存在还不够,你必须配置客户端的 TNS 名去连接它。客户端的 TNS 名应该类似如下:
        orcl_RW =
    (DESCRIPTION =
      (ADDRESS_LIST=
   (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.215.101)(PORT = 1521))
   (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.215.102)(PORT = 1521))
      )
      (CONNECT_DATA = (SERVICE_NAME = orcl_RW)
   (FAILOVER_MODE=(TYPE=SELECT)(METHOD=BASIC)(RETRIES=30)(DELAY=5))
      )
    )
       当你的客户端使用新 TNS 名后,它们能在主备切换和故障转移操作后找到主库。如果客户端在运行一个查询,
       并且没有 DML 是在一个交易中,那在发生切换操作后,只要主备转换和故障转移在超过最大重试次数前完成,
       这个查询会继续工作,只是会有延迟。你应该多做几次切换实验,以确定 RETRIES 和 DELAY 参数如何设置合适。
       如果有一个正在进行中的交易,当客户端连接到新的主库后,
       查询将报错(`ORA-25403: transaction must roll back),并回滚。
  
  3.主备切换switchover
    (1)主库确认没有日志缺口
       SQL> select STATUS, GAP_STATUS from V$ARCHIVE_DEST_STATUS where DEST_ID = 2;
       应该返回 VALID 和 NO GAP。
    (2)查询v$tempfile视图确认备库的临时文件和主库一样。
    (3)确认所有重做日志都已在备库应用,查询备库
       SQL> select NAME, VALUE, DATUM_TIME from V$DATAGUARD_STATS;
       不应该返回 transport lag 或 apply lag, finish time 应该为0.
              关于V$DATAGUARD_STATS是这样描述的:
       该动态性能视图显示出在主库上产生了多少重做日志数据,但是还没有被备库所应用。
       所以,通过查询该视图可以基本确定如果万一主库出现崩溃的话,备库上将丢失多少重做日志数据。
       我们可以在一套Dataguard环境下的任一备库的实例上从该视图里获取相关信息,
       然而,在主库的实例上查询该视图返回的信息都将是空。也就是说,只可以从备库的实例上查询V$DATAGUARD_STATS,
       从主库实例上是看不到任何有用信息的。
              NAME:
  apply lag,该值表示在通过在备库上应用主库传递过来的重做日志与主库同步所延迟的时间。 
  transport lag,该值表示在单位时间内主库上产生的重做日志还没有传输到备库上,或者主库上产生的重做日志还没有被备库所应用。 
  apply finish time,该值表示在备库上完成应用重做日志所需要的时间。
  estimated startup time,该值表示启动和打开物理备库所需要的时间,该字段不是适用于逻辑备库。 
  standby has been open,该值表示物理备库自从上次启动以来,是否以OPEN READ ONLY方式打开过?
  该参数值如果是Y,现在需要做FAILOVER,那么就需要先将该物理备库shutdown然后以OPEN READ WRITE方式打开。
  11g的dataguard可以一边OPEN READ ONLY,一边执行redo apply,也就是11g 的ACTIVE Dataguard。 
       VALUE:给出各个参数的值。如第1个查询中的,apply finish time值为+00 00:00:00.1,说明该物理备库需要0.1秒的时间来完成应用剩余的重做日志数据。
              UNIT:各个参数的时间单元。
              TIME_COMPUTED:物理备库上估算各个参数的本地时间。
              DATUM_TIME:在物理备库上获取元数据来估算  APPLY LAG 和 TRANSPORT LAG 这两个参数值的本地时间。如果从多次查询中看到该时间值对应的APPLY LAG 和 TRANSPORT LAG 这两个参数值保持不变的话,那么就说明该物理备库已经停止从主库接收到重做数据!该字段是11g中新出现的。

 


    (4)确认主库可以进行角色切换,查询主库
       SQL> select SWITCHOVER_STATUS from V$DATABASE;
       如果返回 TO STANDBY 或 SESSIONS ACTIVE,那么主库就可以进行切换
    (5)切换
      <1>切换主库为备库命令为:
       如果执行为TO STANDB执行
                SQL> alter database commit to switchover to physical standby ;
                SQL> shutdown immediate;
                SQL> startup mount;
       如果为SESSIONS ACTIVE执行
         SQL> alter database commit to switchover to physical standby with session shutdown;
         SQL> shutdown immediate;
         SQL> startup mount;

    <2>查询备库是否可以切换为主库,查询备库:
                SQL> select SWITCHOVER_STATUS from V$DATABASE;
  如果返回 TO PRIMARY 或 SESSIONS ACTIVE,就可以切换。如果返回 SWITCHOVER LATENT 或 SWITCHOVER PENDING,就要去检查告警日志,
  看有什么问题,一般是需要应用一些日志。如果是需要应用日志的话,在备库执行如下命令:
                SQL> recover standby database using backup controlfile;
  完成应用后,会变成 TO PRIMARY 或 SESSIONS ACTIVE状态。
                或者alter database recover managed standby database disconnect from session;
                    alter database recover managed standby database cancel;

              切换备库为主库了:
         SQL> select SWITCHOVER_STATUS from V$DATABASE;
      如果是TO_PRIMARY 执行下面的
         sql> alter database commit to switchover to primary;
        SQL> alter database open;
       如果是SESSIONS ACTIVE,执行下面的:
         SQL> alter database commit to switchover to primary with session shutdown;
          SQL> alter database open;
       备库(现在的备库即101)上启用日志应用:
         SQL> alter database recover managed standby database using current logfile disconnect from session;


  此时在现在的备库101上执行:
   sql>select SWITCHOVER_STATUS,DATABASE_ROLE from V$DATABASE;  --not allowed PHYSICAL STANDBY 
   ora-16014错误,删除standby logfile然后alter database clear logfile清理数据库
   从现在102主库上alter system switch logfile手工触发去传输standby logfile
   注意的是:如果现在把101在切换回主库,102成从库。按照正常操作,先切换现在的主库102成从库,当操作完成的时候,101的 SWITCHOVER_STATUS就成
   to_primary也就是说可以切换成主库了。
  现在的主库102上执行:
   sql> select SWITCHOVER_STATUS,DATABASE_ROLE from V$DATABASE; --RESOLVABLE GAP PRIMARY
   检查alert日志发现ora-00312错误,删除错误的log日志,后状态为TO STANDBY,PRIMARY
   sql>startup mount;
                 sql>alter database clear logfile '*****.LOG';
                 sql>alter database open


      (6)问题
           如果主备库的sequence#不同,而且主库切换switch logfile也不能传送到备库,可用下面的办法
          手工同步归档日志文件到备库,然后在备库执行
            sql>alter database register logfile '/opt/oracle/oradata/orcl/archive1/'
   会报错,不需要管,会提示可以注册的已经注册进去了
            sql>select sequence#,first_change#,next_change#,applied,activation# from v$archived_log;
    检查主备库sequence#,然后主库切换logfile可以看到已经可以同步了



(责任编辑:IT)