所以做了一个实验验证,验证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_CLIENT和FAL_SERVER两个参数都是Oracle Net Name。 FAL_CLIENT 通过网络向FAL_SERVER发送请求,FAL_SERVER通过网络向FAL_CLIENT发送缺失的日志。 但是这两个连接不一定是一个连接。 因此FAL_CLIENT向FAL_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 st