- 论坛徽章:
- 0
|
今天有空又做了一次Oracle 10g跨越Resetlogs时间点进行恢复,对于其中日志推进的问题,以及如何跨越的,进行了最大限度的求证。
C:\Documents and Settings\Administrator>rman target /
恢复管理器: Release 11.1.0.6.0 - Production on 星期二 12月 30 21:13:46 2008
Copyright (c) 1982, 2007, Oracle. All rights reserved.
连接到目标数据库: ORCL (DBID=1202355191)
RMAN> backup database plus archivelog delete all input;
(字数限制,过程略)
恢复管理器完成。
SQL> alter system switch logfile; -----这里切换到了序列第60的日志,之前的序列为59
系统已更改。
SQL> select count(*) from t;
select count(*) from t
*
第 1 行出现错误:
ORA-00942: 表或视图不存在
SQL> select * from nam.t;
ID TDATE TSCN
---------- -------------- ----------
1 30-12月-08 393466
2 30-12月-08 393466
3 30-12月-08 393466
4 30-12月-08 393466
5 30-12月-08 393466
6 30-12月-08 393466
7 30-12月-08 393466
8 30-12月-08 393466
9 30-12月-08 393466
10 30-12月-08 393466
已选择10行。
SQL> conn nam/nam
已连接。
SQL> begin
2 for i in 11 .. 20 loop
3 insert into t values(i,sysdate,dbms_flashback.get_system_change_number);
4 end loop;
5 commit;
6 end;
7 /
PL/SQL 过程已成功完成。
SQL> alter system switch logfile; -----这里切换到了序列第61的日志,之前的序列为60
系统已更改。
SQL> begin
2 for i in 21 .. 30 loop
3 insert into t values(i,sysdate,dbms_flashback.get_system_change_number);
4 end loop;
5 commit;
6 end;
7 /
PL/SQL 过程已成功完成。
SQL> alter system switch logfile; -----这里切换到了序列第62的日志,之前的序列为61
系统已更改。
SQL> select * from t;
ID TDATE TSCN
---------- -------------- ----------
12 30-12月-08 393652
13 30-12月-08 393652
14 30-12月-08 393652
15 30-12月-08 393652
16 30-12月-08 393652
17 30-12月-08 393652
18 30-12月-08 393652
19 30-12月-08 393652
20 30-12月-08 393652
21 30-12月-08 393667
22 30-12月-08 393667
ID TDATE TSCN
---------- -------------- ----------
23 30-12月-08 393667
24 30-12月-08 393667
25 30-12月-08 393667
26 30-12月-08 393667
27 30-12月-08 393667
28 30-12月-08 393667
29 30-12月-08 393667
30 30-12月-08 393667
1 30-12月-08 393466
2 30-12月-08 393466
3 30-12月-08 393466
ID TDATE TSCN
---------- -------------- ----------
4 30-12月-08 393466
5 30-12月-08 393466
6 30-12月-08 393466
7 30-12月-08 393466
8 30-12月-08 393466
9 30-12月-08 393466
10 30-12月-08 393466
11 30-12月-08 393652
已选择30行。
SQL> archive log list;
数据库日志模式 存档模式
自动存档 启用
存档终点 USE_DB_RECOVERY_FILE_DEST
最早的联机日志序列 60
下一个存档日志序列 62
当前日志序列 62
C:\Documents and Settings\Administrator>set nls_date_format=yyyy-mm-dd hh24:mi:ss
SQL> select recid,stamp,first_time,sequence# from v$log_history where recid > 94
;
RECID STAMP FIRST_TIME SEQUENCE#
---------- ---------- ------------------- ----------
95 674860547 2008-12-30 21:14:09 58
96 674860657 2008-12-30 21:15:46 59
97 674860793 2008-12-30 21:17:37 60
98 674860817 2008-12-30 21:19:53 61
现在测试恢复到60的之前状态,NAM.T应该只有10条记录。
关闭数据库,删除数据文件。
SQL> shutdown abort;
ORACLE 例程已经关闭。
RMAN> startup mount;
Oracle 实例已启动
数据库已装载
系统全局区域总计 535662592 字节
Fixed Size 1334380 字节
Variable Size 213910420 字节
Database Buffers 314572800 字节
Redo Buffers 5844992 字节
RMAN> run {
2> set until sequence 60 thread 1;
3> restore database;
4> recover database;
5> }
正在执行命令: SET until clause
使用目标数据库控制文件替代恢复目录
启动 restore 于 30-12月-08
分配的通道: ORA_DISK_1
通道 ORA_DISK_1: SID=154 设备类型=DISK
通道 ORA_DISK_1: 正在开始还原数据文件备份集
通道 ORA_DISK_1: 正在指定从备份集还原的数据文件
通道 ORA_DISK_1: 将数据文件 00001 还原到 G:\ORADATA\ORCL\SYSTEM01.DBF
通道 ORA_DISK_1: 将数据文件 00002 还原到 G:\ORADATA\ORCL\SYSAUX01.DBF
通道 ORA_DISK_1: 将数据文件 00003 还原到 G:\ORADATA\ORCL\UNDOTBS01.DBF
通道 ORA_DISK_1: 将数据文件 00004 还原到 G:\ORADATA\ORCL\USERS01.DBF
通道 ORA_DISK_1: 将数据文件 00005 还原到 G:\ORADATA\ORCL\NAM01.DBF
通道 ORA_DISK_1: 正在读取备份片段 G:\BACKUP\B_20081230_43_1
通道 ORA_DISK_1: 段句柄 = G:\BACKUP\B_20081230_43_1 标记 = TAG20081230T211418
通道 ORA_DISK_1: 已还原备份片段 1
通道 ORA_DISK_1: 还原完成, 用时: 00:01:06
完成 restore 于 30-12月-08
启动 recover 于 30-12月-08
使用通道 ORA_DISK_1
正在开始介质的恢复
线程 1 序列 59 的归档日志已作为文件 G:\FLASH_RECOVERY_AREA\ORCL\ARCHIVELOG\2008_
12_30\O1_MF_1_59_4ON7VKC7_.ARC 存在于磁盘上
通道 ORA_DISK_1: 正在开始将归档日志还原到默认目标
通道 ORA_DISK_1: 正在还原归档日志
归档日志线程=1 序列=58
通道 ORA_DISK_1: 正在读取备份片段 G:\BACKUP\B_20081230_44_1
通道 ORA_DISK_1: 段句柄 = G:\BACKUP\B_20081230_44_1 标记 = TAG20081230T211549
通道 ORA_DISK_1: 已还原备份片段 1
通道 ORA_DISK_1: 还原完成, 用时: 00:00:01
归档日志文件名=G:\FLASH_RECOVERY_AREA\ORCL\ARCHIVELOG\2008_12_30\O1_MF_1_58_4ON9
H4QG_.ARC 线程=1 序列=58
通道 default: 正在删除归档日志
归档日志文件名=G:\FLASH_RECOVERY_AREA\ORCL\ARCHIVELOG\2008_12_30\O1_MF_1_58_4ON9
H4QG_.ARC RECID=208 STAMP=674862308
归档日志文件名=G:\FLASH_RECOVERY_AREA\ORCL\ARCHIVELOG\2008_12_30\O1_MF_1_59_4ON7
VKC7_.ARC 线程=1 序列=59
介质恢复完成, 用时: 00:00:02
完成 recover 于 30-12月-08
RMAN> alter database open resetlogs;
数据库已打开
RMAN> exit
恢复管理器完成。
-------检查状态
SQL> conn nam/nam
已连接。
SQL> select * from t;
ID TDATE TSCN
---------- ------------------- ----------
1 2008-12-30 21:12:49 393466
2 2008-12-30 21:12:49 393466
3 2008-12-30 21:12:49 393466
4 2008-12-30 21:12:49 393466
5 2008-12-30 21:12:49 393466
6 2008-12-30 21:12:49 393466
7 2008-12-30 21:12:49 393466
8 2008-12-30 21:12:49 393466
9 2008-12-30 21:12:49 393466
10 2008-12-30 21:12:49 393466
已选择10行。
SQL> create tt as select * from t;
create tt as select * from t
*
第 1 行出现错误:
ORA-00901: 无效 CREATE 命令
SQL> create table tt as select * from t;
表已创建。
SQL> alter system switch logfile;
系统已更改。
SQL> select count(*) from tt;
COUNT(*)
----------
10
SQL> insert into tt select * from tt;
已创建10行。
SQL> commit;
提交完成。
SQL> alter system switch logfile;
系统已更改。
SQL> select recid,stamp,first_time,sequence# from v$log_history where recid > 94;
RECID STAMP FIRST_TIME SEQUENCE#
---------- ---------- ------------------- ----------
95 674860547 2008-12-30 21:14:09 58
96 674860657 2008-12-30 21:15:46 59
97 674860793 2008-12-30 21:17:37 60
98 674860817 2008-12-30 21:19:53 61
99 674863695 2008-12-30 21:45:23 1
100 674863732 2008-12-30 22:08:15 2
已选择6行。
SQL>
此时,日志的RECID继续增长,控制文件保留了归档日志的序列,这也就证明了resetlogs的恢复成为可能(引用EYGLE的原话)
再次删除所有数据文件,再次恢复(注意,10g之前使用当前resetlogs过的控制文件是不能够恢复以前的备份)
RMAN> startup mount;
Oracle 实例已启动
数据库已装载
系统全局区域总计 535662592 字节
Fixed Size 1334380 字节
Variable Size 213910420 字节
Database Buffers 314572800 字节
Redo Buffers 5844992 字节
RMAN> run {
2> restore database;
3> recover database;
4> }
启动 restore 于 2008-12-30 22:29:39
使用目标数据库控制文件替代恢复目录
分配的通道: ORA_DISK_1
通道 ORA_DISK_1: SID=154 设备类型=DISK
通道 ORA_DISK_1: 正在开始还原数据文件备份集
通道 ORA_DISK_1: 正在指定从备份集还原的数据文件
通道 ORA_DISK_1: 将数据文件 00001 还原到 G:\ORADATA\ORCL\SYSTEM01.DBF
通道 ORA_DISK_1: 将数据文件 00002 还原到 G:\ORADATA\ORCL\SYSAUX01.DBF
通道 ORA_DISK_1: 将数据文件 00003 还原到 G:\ORADATA\ORCL\UNDOTBS01.DBF
通道 ORA_DISK_1: 将数据文件 00004 还原到 G:\ORADATA\ORCL\USERS01.DBF
通道 ORA_DISK_1: 将数据文件 00005 还原到 G:\ORADATA\ORCL\NAM01.DBF
通道 ORA_DISK_1: 正在读取备份片段 G:\BACKUP\B_20081230_43_1
通道 ORA_DISK_1: 段句柄 = G:\BACKUP\B_20081230_43_1 标记 = TAG20081230T211418
通道 ORA_DISK_1: 已还原备份片段 1
通道 ORA_DISK_1: 还原完成, 用时: 00:01:16
完成 restore 于 2008-12-30 22:31:00
启动 recover 于 2008-12-30 22:31:00
使用通道 ORA_DISK_1
正在开始介质的恢复
线程 1 序列 59 的归档日志已作为文件 G:\FLASH_RECOVERY_AREA\ORCL\ARCHIVELOG\2008_
12_30\O1_MF_1_59_4ON7VKC7_.ARC 存在于磁盘上
线程 1 序列 1 的归档日志已作为文件 G:\FLASH_RECOVERY_AREA\ORCL\ARCHIVELOG\2008_1
2_30\O1_MF_1_1_4ONBTHQX_.ARC 存在于磁盘上
线程 1 序列 2 的归档日志已作为文件 G:\FLASH_RECOVERY_AREA\ORCL\ARCHIVELOG\2008_1
2_30\O1_MF_1_2_4ONBVNPY_.ARC 存在于磁盘上
通道 ORA_DISK_1: 正在开始将归档日志还原到默认目标
通道 ORA_DISK_1: 正在还原归档日志
归档日志线程=1 序列=58
通道 ORA_DISK_1: 正在读取备份片段 G:\BACKUP\B_20081230_44_1
通道 ORA_DISK_1: 段句柄 = G:\BACKUP\B_20081230_44_1 标记 = TAG20081230T211549
通道 ORA_DISK_1: 已还原备份片段 1
通道 ORA_DISK_1: 还原完成, 用时: 00:00:02
归档日志文件名=G:\FLASH_RECOVERY_AREA\ORCL\ARCHIVELOG\2008_12_30\O1_MF_1_58_4OND
570H_.ARC 线程=1 序列=58
通道 default: 正在删除归档日志
归档日志文件名=G:\FLASH_RECOVERY_AREA\ORCL\ARCHIVELOG\2008_12_30\O1_MF_1_58_4OND
570H_.ARC RECID=215 STAMP=674865063
归档日志文件名=G:\FLASH_RECOVERY_AREA\ORCL\ARCHIVELOG\2008_12_30\O1_MF_1_59_4ON7
VKC7_.ARC 线程=1 序列=59
介质恢复完成, 用时: 00:00:06
完成 recover 于 2008-12-30 22:31:10
RMAN> alter database open;
数据库已打开
RMAN>
SQL> select count(*) from t;
COUNT(*)
----------
10
SQL> select count(*) from tt;
COUNT(*)
----------
20
SQL>
跳过了第60个日志到第62个日志,然后正确应用了1-2的日志。
到这里我在想,这种恢复手段的应用范围,也许这样做的目的仅仅是为了备份一次,然后做了不完全恢复,再继续使用数据库但是没有备份,那么恢复的时候自然就跳过了resetlogs的那些个日志,控制文件里面应该记录的信息就应该包含被resetlogs的日志序列,这样恢复时自然会跳过。
SQL> select recid,stamp,first_time,first_change#,sequence# from v$log_history wh
ere recid > 94;
RECID STAMP FIRST_TIME FIRST_CHANGE# SEQUENCE#
---------- ---------- ------------------- ------------- ----------
95 674860547 2008-12-30 21:14:09 393517 58
96 674860657 2008-12-30 21:15:46 393559 59
97 674860793 2008-12-30 21:17:37 393610 60
98 674860817 2008-12-30 21:19:53 393662 61
99 674863695 2008-12-30 21:45:23 393611 1
100 674863732 2008-12-30 22:08:15 398609 2
101 674865190 2008-12-30 22:08:52 398626 3
已选择7行。
SQL>
注意,60的起始SCN和1的起始SCN是连在一起的,也就是说,从60开始的后续SCN是作废的。
于是,我DMUP了控制文件:
***************************************************************************
REDO THREAD RECORDS
***************************************************************************
(size = 256, compat size = 256, section max = 8, section in-use = 1,
last-recid= 0, old-recno = 0, last-recno = 0)
(extent = 1, blkno = 9, numrecs = 
THREAD #1 - status:0xf thread links forward:0 back:0
#logs:3 first:1 last:3 current:1 last used seq#:0x4
enabled at scn: 0x0000.0006018b 12/30/2008 21:45:23
disabled at scn: 0x0000.00000000 01/01/1988 00:00:00
opened at 12/30/2008 22:33:10 by instance orcl
Checkpointed at scn: 0x0000.00066649 12/30/2008 22:33:10
thread:1 rba 0x4.2.10)
这一段信息让我恍然大悟,跨越恢复时,应该按照SCN进行日志推进,查看v$archived_log
SQL> select stamp,
2 sequence#,
3 first_change#,
4 first_time,
5 next_change#,
6 end_of_redo_type
7 from v$archived_log x
8 where x.stamp > 674860547
9 order by first_change#
10 /
STAMP SEQUENCE# FIRST_CHANGE# FIRST_TIME NEXT_CHANGE# END_OF_REDO_TYPE
---------- ---------- ------------- ----------- ------------ ----------------
674860548 58 393517 2008-12-30 393559
674860548 58 393517 2008-12-30 393559
674865063 58 393517 2008-12-30 393559
674862308 58 393517 2008-12-30 393559
674860657 59 393559 2008-12-30 393610
674860657 59 393559 2008-12-30 393610
674860794 60 393610 2008-12-30 393662
674860794 60 393610 2008-12-30 393662
674863696 1 393611 2008-12-30 398609
674863696 1 393611 2008-12-30 398609
674860818 61 393662 2008-12-30 393676
674860818 61 393662 2008-12-30 393676
674862324 62 393676 2008-12-30 394231 RESETLOGS
674862324 62 393676 2008-12-30 394231 RESETLOGS
674863733 2 398609 2008-12-30 398626
674863733 2 398609 2008-12-30 398626
674865192 3 398626 2008-12-30 419400
674865192 3 398626 2008-12-30 419400
18 rows selected
SQL>
把当前日志归档后,再次DUMP控制文件
SQL> alter system archive log current;
系统已更改。
SQL> alter system switch logfile;
系统已更改。
SQL> alter system switch logfile;
系统已更改。
SQL> alter system switch logfile;
系统已更改。
SQL> alter session set events 'immediate trace name CONTROLF level 4';
会话已更改。
SQL> select d.value || '/' || lower(rtrim(i.instance, chr(0))) || '_ora_' ||
2 p.spid || '.trc' trace_file_name
3 from (select p.spid
4 from v$mystat m, v$session s, v$process p
5 where m.statistic# = 1
6 and s.sid = m.sid
7 and p.addr = s.paddr) p,
8 (select t.instance
9 from v$thread t, v$parameter v
10 where v.name = 'thread'
11 and (v.value = 0 or t.thread# = to_number(v.value))) i,
12 (select value from v$parameter where name = 'user_dump_dest') d
13 /
TRACE_FILE_NAME
-------------------------------------------------------------------------------
e:\oracle\diag\rdbms\orcl\orcl\trace/orcl_ora_2884.trc
SQL>
看一下信息,注意Checkpointed at scn
***************************************************************************
REDO THREAD RECORDS
***************************************************************************
(size = 256, compat size = 256, section max = 8, section in-use = 1,
last-recid= 0, old-recno = 0, last-recno = 0)
(extent = 1, blkno = 9, numrecs = 
THREAD #1 - status:0xf thread links forward:0 back:0
#logs:3 first:1 last:3 current:3 last used seq#:0x9
enabled at scn: 0x0000.0006018b 12/30/2008 21:45:23
disabled at scn: 0x0000.00000000 01/01/1988 00:00:00
opened at 12/30/2008 22:33:10 by instance orcl
Checkpointed at scn: 0x0000.00066d55 12/30/2008 23:18:13
thread:1 rba 0x9.2.10)
第一次DUMP信息 Checkpointed at scn 0x0000.00066649,第二次Checkpointed at scn 0x0000.00066d55,但是,enabled at scn: 0x0000.0006018b没有变化。
继续DUMP序列为60的归档文件
SQL> select stamp,
2 NAME,
3 sequence#
4 from v$archived_log
5 where sequence#=60
6 /
STAMP NAME SEQUENCE#
---------- -------------------------------------------------------------------------------- ----------
674860794 E:\ORACLE\PRODUCT\11.1.0\DB_1\RDBMS\ARC00060_0674761419.001 60
674860794 G:\FLASH_RECOVERY_AREA\ORCL\ARCHIVELOG\2008_12_30\O1_MF_1_60_4ON7ZSRF_.ARC 60
SQL> alter system dump logfile 'E:\ORACLE\PRODUCT\11.1.0\DB_1\RDBMS\ARC00060_067
4761419.001';
系统已更改。
SQL> select d.value || '/' || lower(rtrim(i.instance, chr(0))) || '_ora_' ||
2 p.spid || '.trc' trace_file_name
3 from (select p.spid
4 from v$mystat m, v$session s, v$process p
5 where m.statistic# = 1
6 and s.sid = m.sid
7 and p.addr = s.paddr) p,
8 (select t.instance
9 from v$thread t, v$parameter v
10 where v.name = 'thread'
11 and (v.value = 0 or t.thread# = to_number(v.value))) i,
12 (select value from v$parameter where name = 'user_dump_dest') d
13 /
TRACE_FILE_NAME
--------------------------------------------------------------------------------
e:\oracle\diag\rdbms\orcl\orcl\trace/orcl_ora_3236.trc
SQL>
把59也DUMP一下,比较其中信息:
60记录的信息比59的要多了很多,但我没发现有什么特别有价值的信息。。看一下控制文件记录的数据文件部分:
***************************************************************************
DATA FILE RECORDS
***************************************************************************
(size = 520, compat size = 520, section max = 100, section in-use = 6,
last-recid= 23, old-recno = 0, last-recno = 0)
(extent = 1, blkno = 11, numrecs = 100)
DATA FILE #1:
(name # G:\ORADATA\ORCL\SYSTEM01.DBF
creation size=0 block size=8192 status=0xe head=8 tail=8 dup=1
tablespace 0, index=1 krfil=1 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:185 scn: 0x0000.00066649 12/30/2008 22:33:10
Stop scn: 0xffff.ffffffff 12/30/2008 22:28:36
Creation Checkpointed at scn: 0x0000.0000000b 12/27/2008 13:48:04
thread:0 rba 0x0.0.0)
所以,我想,ORACLE是怎么判断跨越恢复的呢,第一,肯定是按SCN来推进的,那么,是怎么衔接的呢?应该是控制文件在请求日志推进时首先比较了restore出来的数据文件头记录的scn,之后和自己记录的数据文件scn做比较,确定恢复的范围。然后再根据自己记录的enabled at scn: 0x0000.0006018b为归档日志的衔接标志,当从历史归档日志中恢复到0x0000.0006018a时后续部分将不再恢复,转向控制文件中记录的0x0000.0006018b所对应的新序列日志(可能是归档,也可能是REDO)。启动数据库后,v$archived_log里end_of_redo_type字段信息,应该也是比较scn得出的结果,将first_change#与enabled at scn衔接的日志之后的未重置序列号的日志全部标记上RESETLOGS(比如本案例中,60的first_change#是0x0000.0006018a,和控制文件中的enabled at scn: 0x0000.0006018b衔接,所以60之后的两个日志,不包含60,都被注上了标记RESETLOGS,虽然60没有被著名标记,由于SCN的关系,它其实也是个废的)。
这只是我能力范围内最大限度的求证了,希望大家指正。 |
|