如果我们的DG的主库发生了当库,我们怎么样做failover,才能保证最少数据的丢失?
我们把数据分成3类:
1.是已经arch传到备库,并且已经apply的数据——ok,这些数据是正常传输的数据,平时数据就是在这么做的。
2.是还未传输到备库的日志,此时这部分日志还没被apply,但是arch已经在主库上产生,但是由于网络的原因,还没传输到备库。
3.是还在redo中的日志,这些记录已经commit,但是还未被切换到arch,即只在主库的redolog上,连主库上的arch都不存在。
我们通过一个小实验来模拟数据的恢复:
插入一条正常的数据,并且arch正常传输到备机apply:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
sys@ORALOCAL(192.168.0.12)> insert into xxx values (1); 已创建 1 行。 已用时间: 00: 00: 00.09 sys@ORALOCAL(192.168.0.12)> commit; 提交完成。 已用时间: 00: 00: 00.09 sys@ORALOCAL(192.168.0.12)> alter system checkpoint; 系统已更改。 已用时间: 00: 00: 03.06 sys@ORALOCAL(192.168.0.12)> alter system switch logfile; 系统已更改。 已用时间: 00: 00: 01.05 sys@ORALOCAL(192.168.0.12)> select max(SEQUENCE#) from v$archived_log; MAX(SEQUENCE#) -------------- 341 已用时间: 00: 00: 01.07 sys@ORALOCAL(192.168.0.12)> --341 transmit to standby |
现在我们中断网络,模拟arch无法正常传输到备机:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
sys@ORALOCAL(192.168.0.12)> --now broken network connection sys@ORALOCAL(192.168.0.12)> insert into xxx values (2); 已创建 1 行。 已用时间: 00: 00: 00.09 sys@ORALOCAL(192.168.0.12)> commit; 提交完成。 已用时间: 00: 00: 00.09 sys@ORALOCAL(192.168.0.12)> alter system checkpoint; 系统已更改。 已用时间: 00: 00: 03.00 sys@ORALOCAL(192.168.0.12)> alter system switch logfile; 系统已更改。 已用时间: 00: 00: 01.05 sys@ORALOCAL(192.168.0.12)> select max(SEQUENCE#) from v$archived_log; MAX(SEQUENCE#) -------------- 342 已用时间: 00: 00: 01.07 sys@ORALOCAL(192.168.0.12)> --value "2" in arch 342 but not transmit to standby |
最后,我们模拟插入记录3后,当完成commit后,突然宕机(shutdown abort):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
sys@ORALOCAL(192.168.0.12)> insert into xxx values (3); 已创建 1 行。 已用时间: 00: 00: 00.09 sys@ORALOCAL(192.168.0.12)> commit; 提交完成。 已用时间: 00: 00: 00.09 sys@ORALOCAL(192.168.0.12)> select * from v$log; GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIME ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ---------- 1 1 341 10485760 3 YES INACTIVE 5997568 30-11月-07 2 1 343 10485760 3 NO CURRENT 5997969 30-11月-07 3 1 342 10485760 3 YES INACTIVE 5997726 30-11月-07 已用时间: 00: 00: 02.03 sys@ORALOCAL(192.168.0.12)> shutdown abort ORA-01031: 权限不足 sys@ORALOCAL(192.168.0.12)> conn / as sysdba 已连接。 sys@ORALOCAL(192.168.0.12)> shutdown abort ORACLE 例程已经关闭。 sys@ORALOCAL(192.168.0.12)> --value "3" in redolog not in arch |
ok,我们假设主库已经宕机,不能再起到primary的作用,而我们现在有3条记录:
xxx表中的三行记录:
ID
———-
1<-----正常传输到备机且apply。
2<-----因为网络中断,只是在主库生成arch但未传输到备机,未被apply。
3<-----记录commit后,主库宕机,存在在redolog中,连主库的arch都没到。
那么在备机中,我们如何将这些数据恢复呢?
主要的步骤有以下几步:
1.传输主库和备库差异的archlog
2.传输主库的redolog
3.alter database recover managed standby database cancel;
3.recover standby database;
4.做failover:
alter database recover managed standby database finish;
or
alter database recover managed standby database finish skip standby logfile;
alter database commit to switchover to primary;
shutdown immediate;
startup;
其他的步骤不多说了,这里主要演示下恢复上述的三行记录:
在备库:
我们看到最开始,备库只有一条记录,即正常传输arch的记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
SQL> alter database recover managed standby database cancel; 数据库已更改。 SQL> alter database open read only; 数据库已更改。 SQL> conn user/pwd 已连接。 SQL> select * from xxx; ID ---------- 1 |
开始进行恢复,先恢复arch中的记录,此时主库的arch和redo已经通过ftp传输到'D:\oracle\from_primary\'目录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
SQL> conn / as sysdba 已连接。 SQL> alter database recover managed standby database disconnect from session; 数据库已更改。 SQL> alter database recover managed standby database cancel; 数据库已更改。 SQL> recover standby database; ORA-00279: 更改 5997726 (在 11/30/2007 00:35:37 生成) 对于线程 1 是必需的 ORA-00289: 建议: D:\ORACLE\ARCH\ORALOCAL\ORALOCAL_001_00342.ARC ORA-00280: 更改 5997726 对于线程 1 是按序列 # 342 进行的 指定日志: {<RET>=suggested | filename | AUTO | CANCEL} auto ORA-00308: 无法打开存档日志 'D:\ORACLE\ARCH\ORALOCAL\ORALOCAL_001_00342.ARC' ORA-27041: 无法打开文件 OSD-04002: 无法打开文件 O/S-Error: (OS 2) 系统找不到指定的文件。 ORA-00308: 无法打开存档日志 'D:\ORACLE\ARCH\ORALOCAL\ORALOCAL_001_00342.ARC' ORA-27041: 无法打开文件 OSD-04002: 无法打开文件 O/S-Error: (OS 2) 系统找不到指定的文件。 SQL> recover standby database; ORA-00279: 更改 5997726 (在 11/30/2007 00:35:37 生成) 对于线程 1 是必需的 ORA-00289: 建议: D:\ORACLE\ARCH\ORALOCAL\ORALOCAL_001_00342.ARC ORA-00280: 更改 5997726 对于线程 1 是按序列 # 342 进行的 指定日志: {<RET>=suggested | filename | AUTO | CANCEL} D:\oracle\from_primary\ORALOCAL_001_00342.ARC ORA-00279: 更改 5997969 (在 11/30/2007 00:37:11 生成) 对于线程 1 是必需的 ORA-00289: 建议: D:\ORACLE\ARCH\ORALOCAL\ORALOCAL_001_00343.ARC ORA-00280: 更改 5997969 对于线程 1 是按序列 # 343 进行的 ORA-00278: 此恢复不再需要日志文件 'D:\oracle\from_primary\ORALOCAL_001_00342.ARC' |
进行redolog的恢复,接着刚刚的步骤不要退出,提示输入filename的时候输入redolog的位置,由于之前我已经知道在shutdown abort之前,redo 2是current的redo,所以我们直接代入redo2,如果不知道是那个redolog是current的,可以逐个代入:
1 2 3 4 5 6 |
指定日志: {<RET>=suggested | filename | AUTO | CANCEL} D:\oracle\from_primary\REDO201.LOG 已应用的日志。 完成介质恢复。 SQL> SQL> |
在failover到主库前,我们可以看看这次实验的3条数据是否都转移到备库上来了:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
SQL> alter database open read only; 数据库已更改。 SQL> conn hejianmin/hejianmin 已连接。 SQL> select * from xxx; ID ---------- 1 2 3 |
我们看到,三种情况的数据都已经在备库中恢复,这下可以放心的将备库failover成主库了。当然failover之后,还有重建DG等工作,这些可以参照我之前的用rman在线重建DG的文章。
2条评论
我第一个来看,学习一下。
关键字与online redo logfile的保护,最好在存储和主机本地硬盘都有至少一个member,这样不管存储挂还是主机挂,至少还有一份可用的redo,就不会丢数据