物理Data Guard 下Failover 时Redo 的处理问题


和老大讨论了一下Oracle Data Guard redo 的问题。 Data Guard 环境下,归档文件是可以在备库应用的。 假如主库直接crash后,无法登陆,这时在将备库切换为主库的时候,如何处理主库的redo 就是关键。 因为这里的数据就是可能丢失的数据。

 

所以做了一个实验验证,验证redo 的处理。即将主库的redo 直接copy到备库,然后通过recover 来应用redo,等应用结束之后,在启动备库。这样就不会造成数据丢失。

 

当然,如果在Data Guard 中采用Maximum Protection 模式的化,也不会造成数据丢失,但是这种对主库的影响较大。 模式这块参考 

Oracle Data Guard 理论知识

 

 

 

一. 先看archive gap 的情况:

 

Primary Database的某些日志没有成功发送到Standby Database 这时候发生饿了归档裂缝(Archive Gap)。缺失的这些日志就是裂缝(Gap)。 Data Guard能够自动检测,解决归档裂缝,不需要DBA的介入。这需要配置FAL_CLIENT FAL_SERVER 这两个参数(FAL: Fetch Archive Log)。从FAL 这个名字可以看出,这个过程是Standby Database主动发起的“取”日志的过程,Standby Database 就是FAL_CLIENT. 它是从FAL_SERVER中取这些Gap 10g中,这个FAL_SERVER可以是Primary Database 也可以是其他的Standby Database 如:FAL_SERVER='PR1,ST1,ST2';

 

FAL_CLIENTFAL_SERVER两个参数都是Oracle Net Name FAL_CLIENT 通过网络向FAL_SERVER发送请求,FAL_SERVER通过网络向FAL_CLIENT发送缺失的日志。 但是这两个连接不一定是一个连接。 因此FAL_CLIENTFAL_SERVER发送请求时,会携带FAL_CLIENT参数值,用来告诉FAL_SERVER应该向哪里发送缺少的日志。 这个参数值也是一个Oracle Net Name,这个Name是在FAL_SERVER上定义的,用来指向FAL_CLIENT.

 

 

除了自动地日志缺失解决,DBA 也可以手工解决。 具体操作步骤如下:

 

1 查看是否有日志GAP

    SQL> SELECT UNIQUE THREAD#, MAX(SEQUENCE#) OVER(PARTITION BY THREAD#) LAST FROM V$ARCHIVED_LOG;

  SQL> SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP;

2 如果有,则拷贝过来

3 手工的注册这些日志:

SQL> ALTER DATABASE REGISTER LOGFILE '路径';

 

 

二. Redo 文件

       一般情况下,都是redo 文件满了之后才会进行归档,在Data Guard 环境下,是通过这些归档文件来同步数据。 现在假如我们刚归档完一次。 这时进行了一些事务的提交操作。 主库恰好在这个时候crach掉了。 而且无法登陆。 如果我们仅靠归档来进行Failover 肯定是会有数据丢失的。

 

       我们可以在Failover 之前将主库的redo copy过来,在apply一下。 下面的实验就是来验证这个问题。 关于Data Guard 环境下的switchover Failover 知识,参考我的Blog

       Oracle Data Guard Linux 平台 Physical Standby 搭建实例

这篇 的最后部分有这两种切换的说明。

 

 

2.1 现在主库进行相关操作:

 

SQL> select max(sequence#) from v$archived_log;

MAX(SEQUENCE#)

--------------

            13

SQL> alter system switch logfile;

System altered.

SQL> select max(sequence#) from v$archived_log;

MAX(SEQUENCE#)

--------------

            14

SQL> create table dave (id number,name varchar(20));

Table created.

SQL> insert into dave values(1,'dave');

1 row created.

SQL> commit;

Commit complete.

SQL> shutdown immediate

Database closed.

Database dismounted.

ORACLE instance shut down.

SQL>

 

 

在主库,我们先将日志归档,然后创建了一张表Dave,并插入了一条数据。最后把实例shutdown 来模拟主库crash的情况。

 

 

SQL> select sequence#,applied from v$archived_log;

 

 SEQUENCE# APP

---------- ---

         8 YES

         9 YES

        10 YES

        11 YES

        12 YES

        13 YES

        14 YES

        15 YES

        16 YES

 

从这个日志里可以看出,主库刚才16档已经应用过了。 如果没有应用,我们可以手动注册一下。 命令:SQL> ALTER DATABASE REGISTER LOGFILE '路径';

 

 

我们将主库的redo 文件copy到备库的对应目录:

 

[oracle@dg1 orcl]$ scp redo01.log 192.168.6.3://u01/app/oracle/oradata/orcl/

oracle@192.168.6.3's password:

redo01.log                        100%   50MB 368.4KB/s   02:19   

[oracle@dg1 orcl]$ scp redo02.log 192.168.6.3://u01/app/oracle/oradata/orcl/

oracle@192.168.6.3's password:

redo02.log                       100%   50MB 517.2KB/s   01:39   

[oracle@dg1 orcl]$ scp redo03.log 192.168.6.3://u01/app/oracle/oradata/orcl/

oracle@192.168.6.3's password:

redo03.log                      100%   50MB 445.2KB/s   01:55   

[oracle@dg1 orcl]$

 

 

2.2 在备库应用这些redo

      

SQL> select sequence#,applied from v$archived_log;

 

 SEQUENCE# APP

---------- ---

         8 YES

         9 YES

        10 YES

        11 YES

        12 YES

        13 YES

        14 YES

        15 YES

        16 YES

 

9 rows selected.

 

SQL> alter database recover managed standby database cancel;

 

Database altered.

 

SQL> recover standby database until cancel;

ORA-00279: change 509016 generated at 11/05/2010 11:40:27 needed for thread 1

ORA-00289: suggestion : /u01/archive/1_17_734225750.dbf

ORA-00280: change 509016 for thread 1 is in sequence #17

-- 默认情况下会提示需要归档17 实际上这个序列为17的归档还没有生成,我们忽略它,使用我们刚才copy过来的redo 日志来恢复。

 

Specify log: {<RET>=suggested | filename | AUTO | CANCEL}

/u01/app/oracle/oradata/orcl/redo01.log   -- 注意, 这个位置是我手动写的

Log applied.

Media recovery complete.

 

--这里是运气好,一次就搞定了。 实际上有三个redo,我们也是不确定使用哪个redo的,只能一个一个试了。

 

SQL> recover standby database until cancel;

ORA-00279: change 509209 generated at 11/05/2010 11:46:35 needed for thread 1

ORA-00289: suggestion : /u01/archive/1_17_734225750.dbf

ORA-00280: change 509209 for thread 1 is in sequence #17

 

Specify log: {<RET>=suggested | filename | AUTO | CANCEL}

/u01/app/oracle/oradata/orcl/redo02.log

ORA-00310: archived log contains sequence 15; sequence 17 required

ORA-00334: archived log: '/u01/app/oracle/oradata/orcl/redo02.log'

  • 1
  • 2
  • 下一页

相关内容