这段时间一直在做ORACLE STANDBY的FAILOVER,在网上看见一篇文章,是讲怎样减少failover时的数据损失。我照这篇文章一直做下去,但是做到运行切换的命令时,老是报错,到网上找了很多的文章也不能解决问题,最后终于出绝招了~~~
以下是引用的文章,我照这他的做法一路做下去
==============================================================
减少Data Guard做Failover时的数据损失
如果我们的DG的主库发生了当库,我们怎么样做failover,才能保证最少数据的丢失?
我们把数据分成3类:
1.是已经arch传到备库,并且已经apply的数据,这些数据是正常传输的数据,平时数据就是在这么做的。
2.是还未传输到备库的日志,此时这部分日志还没被apply,但是arch已经在主库上产生,但是由于网络的原因,还没传输到备库。
3.是还在redo中的日志,这些记录已经commit,但是还未被切换到arch,即只在主库的redolog上,连主库上的arch都不存在。
我们通过一个小实验来模拟数据的恢复:
插入一条正常的数据,并且arch正常传输到备机apply:
SQL> insert into test values (1);
已创建 1 行。
SQL> commit;
提交完成。
SQL> alter system checkpoint;
系统已更改。
SQL> alter system switch logfile;
系统已更改。
SQL> select max(SEQUENCE#) from v$archived_log;
MAX(SEQUENCE#)
--------------
341
SQL> --341 transmit to standby
现在我们中断网络,模拟arch无法正常传输到备机:
SQL> --now broken network connection
SQL> insert into test values (2);
已创建 1 行。
SQL> commit;
提交完成。
SQL> alter system checkpoint;
系统已更改。
SQL> alter system switch logfile;
系统已更改。
SQL> select max(SEQUENCE#) from v$archived_log;
MAX(SEQUENCE#)
--------------
342
已用时间: 00: 00: 01.07
SQL> --value "2" in arch 342 but not transmit to standby
最后,我们模拟插入记录3后,当完成commit后,突然宕机(shutdown abort):
SQL> insert into test values (3);
已创建 1 行。
SQL> commit;
提交完成。
SQL> 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
SQL> conn / as sysdba
已连接。
SQL> shutdown abort
ORACLE 例程已经关闭。
SQL> --value "3" in redolog not in arch
ok,我们假设主库已经宕机,不能再起到primary的作用,而我们现在有3条记录:
test表中的三行记录:
ID
———-
123
那么在备机中,我们如何将这些数据恢复呢?
主要的步骤有以下几步:
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的记录
SQL> alter database recover managed standby database cancel;
数据库已更改。
SQL> alter database open read only;
数据库已更改。
SQL> conn user/pwd
已连接。
SQL> select * from test;
ID
----------
1
开始进行恢复,先恢复arch中的记录,此时主库的arch和redo已经通过ftp传输到’D:oraclefrom_primary’目录:
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:ORACLEARCHORALOCALORALOCAL_001_00342.ARC
ORA-00280: 更改 5997726 对于线程 1 是按序列 # 342 进行的
指定日志: {=suggested | filename | AUTO | CANCEL}
auto
ORA-00308: 无法打开存档日志 'D:ORACLEARCHORALOCALORALOCAL_001_00342.ARC'
ORA-27041: 无法打开文件
OSD-04002: 无法打开文件
O/S-Error: (OS 2) 系统找不到指定的文件。
ORA-00308: 无法打开存档日志 'D:ORACLEARCHORALOCALORALOCAL_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:ORACLEARCHORALOCALORALOCAL_001_00342.ARC
ORA-00280: 更改 5997726 对于线程 1 是按序列 # 342 进行的
指定日志: {=suggested | filename | AUTO | CANCEL}
D:oraclefrom_primaryORALOCAL_001_00342.ARC
ORA-00279: 更改 5997969 (在 11/30/2007 00:37:11 生成) 对于线程 1 是必需的
ORA-00289: 建议: D:ORACLEARCHORALOCALORALOCAL_001_00343.ARC
ORA-00280: 更改 5997969 对于线程 1 是按序列 # 343 进行的
ORA-00278: 此恢复不再需要日志文件
'D:oraclefrom_primaryORALOCAL_001_00342.ARC'
进行redolog的恢复,接着刚刚的步骤不要退出,提示输入filename的时候输入redolog的位置,由于之前我已经知道在shutdown abort之前,redo 2是current的redo,所以我们直接代入redo2,如果不知道是那个redolog是current的,可以逐个代入:
指定日志: {=suggested | filename | AUTO | CANCEL}
D:oraclefrom_primaryREDO201.LOG
已应用的日志。
完成介质恢复。
SQL>
SQL>
在failover到主库前,我们可以看看这次实验的3条数据是否都转移到备库上来了:
SQL> alter database open read only;
数据库已更改。
SQL> conn hejianmin/hejianmin
已连接。
SQL> select * from test;
ID
----------
1
2
3
==================================================================
在完成数据的恢复之后准备开始切换了:
SQL> alter database recover managed standby database finish;
alter database recover managed standby database finish
*
ERROR at line 1:
ORA-01547: warning: RECOVER succeeded but OPEN RESETLOGS would get error below
ORA-00354: corrupt redo log block header
ORA-00353: log corruption near block 2 change 182502 time 01/03/2008 14:17:40
ORA-00312: online log 4 thread 1: '/dev/raw/raw15'
在查找了很多资料之后也不能解决该问题,最后解决的步骤如下:
1、先关掉数据库
SQL >shutdown immediate
2、将数据库重新启动
SQL >startup
3、尝试向TEST表插入数据
SQL >insert into test values(4);
结果报错,说数据库处于只读模式下,是因为现在数据库的控制文件还是备用数据库的控制文件,备用数据库就只能处于只读模式下
4、创建重建控制文件的脚本到跟踪文件
SQL >alter database create controlfile to trace;
5、到$ORACLE_BASE/admin/udump下面找到重建控制文件的脚本
CREATE CONTROLFILE REUSE DATABASE "CRM" RESETLOGS ARCHIVELOG
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 8
MAXLOGHISTORY 292
LOGFILE
GROUP 1 (
'/dev/raw/raw1',
'/data/redolog/redo1_2.dbf'
) SIZE 50M,
GROUP 2 (
'/dev/raw/raw2',
'/data/redolog/redo2_2.dbf'
) SIZE 50M,
GROUP 3 (
'/dev/raw/raw3',
'/data/redolog/redo3_2.dbf'
) SIZE 50M
-- STANDBY LOGFILE
DATAFILE
'/dev/raw/raw8',
'/dev/raw/raw11',
'/dev/raw/raw7',
'/dev/raw/raw13'
CHARACTER SET ZHS16GBK
;
6、关闭数据库并启动到NOMOUNT状态
SQL >startup nomount force
7、运行重建控制文件的脚本
SQL >CREATE CONTROLFILE REUSE DATABASE "CRM" RESETLOGS ARCHIVELOG
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 8
MAXLOGHISTORY 292
LOGFILE
GROUP 1 (
'/dev/raw/raw1',
'/data/redolog/redo1_2.dbf'
) SIZE 50M,
GROUP 2 (
'/dev/raw/raw2',
'/data/redolog/redo2_2.dbf'
) SIZE 50M,
GROUP 3 (
'/dev/raw/raw3',
'/data/redolog/redo3_2.dbf'
) SIZE 50M
-- STANDBY LOGFILE
DATAFILE
'/dev/raw/raw8',
'/dev/raw/raw11',
'/dev/raw/raw7',
'/dev/raw/raw13'
CHARACTER SET ZHS16GBK
;
8、以RESETLOGS打开数据库
SQL > alter database open resetlogs;
9、尝试向TEST表插入数据
SQL> insert into test values(4);
1 row created.
10、查看数据库的角色
SQL> SELECT DATABASE_ROLE FROM V$DATABASE;
DATABASE_ROLE
----------------
PRIMARY
11、成功了,最后就是把DG的归档路径设置成DEFER
SQL> alter system set log_archive_dest_state_2=defer;
System altered.
OK,打完收工!
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9821375/viewspace-996406/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/9821375/viewspace-996406/