ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Oracle热备份原理分析

Oracle热备份原理分析

原创 Linux操作系统 作者:tolywang 时间:2007-05-11 00:00:00 0 删除 编辑

数据库要求在自动归档模式下。

假设开始对 users 表空间文件进行begin backup 。

我们查看 dba_data_files , v$backup 来观察数据文件备份状态变化 。

sql> alter tablespace users begin backup;
tablespace altered.

sql> list
1 select d.file_name filename,d.tablespace_name ts_name,b.status
2 from dba_data_files d,v$backup b
3* where d.file_id=b.file#
sql> /


filename ts_name status
---------------------------------------- ---------- ------------------
/u02/oradata/sales/system01.dbf system not active
/u02/oradata/sales/undotbs01.dbf undotbs1 not active
/u02/oradata/sales/sysaux01.dbf sysaux not active
/u02/oradata/sales/users01.dbf users active
/u02/oradata/sales/example01.dbf example not active

users 表空间文件处于backup 状态 (active) . 这个时候到底数据库作了些什么? 我们执行alter tablespace users begin backup 的时候锁定了users表空间对应的数据文件头的change scn ( 见下面查询的 sql>select name,tablespace_name,status,checkpoint_change# from v$datafile_header; 中users 文件的 checkpoint_change# )。

首先考虑一下数据库怎么用日志文件做恢复:查找不一致的数据文件(根据文件头中旧的scn)

如果锁定了文件头,这个文件头中的scn就不会改变(当然了数据块还是会变化的,还可以做读写)。

然后就会应用这个scn到现在的日志。那我锁定了scn,不管你后边怎么修改,

总之做恢复的时候是应用锁定的时候的scn一直到现在的日志(完全恢复的话)

举个例子:

a,b两个数据文件,把a置于备份模式,b正常

这时候两个change scn都是100,然后开始备份

这期间有数据库的修改,备份完成的时候,scn变成了200。但是由于a的备份模式,

所以a的文件头中记录的scn还是100,b是200。

某个时间,假设scn 500

这时候a丢失

copy回a的备份,然后recover,完全恢复的话数据库就应用100—500这段的日志,自然也就不会丢失数据了。

因为不管在我copy备份的过程中你做什么操作,总之都在锁定的时change scn之后,

所以应用的日志就不会有遗漏了。这时候应该能理解为什么要数据库处于archived模式了

看看数据文件头的change scn


sql>select name,tablespace_name,status,checkpoint_change# from v$datafile_header;
name tablespace status checkpoint_change#
-------------------------------- ---------- -------------- ------------------
/u02/oradata/sales/system01.dbf system online 545926
/u02/oradata/sales/undotbs01.dbf undotbs1 online 545926
/u02/oradata/sales/sysaux01.dbf sysaux online 545926
/u02/oradata/sales/users01.dbf users online 545498
/u02/oradata/sales/example01.dbf example online 545926
/u02/oradata/sales/perfstat.dbf perfstat online 545926

6 rows selected.


显然,在将users表空间置于backup状态的时候,相应的datafile的文件头的scn就不会再发生改变,

发生检查点也不会改变。


sql> alter system checkpoint;
system altered.

sql> select name,tablespace_name,status,checkpoint_change# from v$datafile_header;
name tablespace status checkpoint_change#
-------------------------------- ---------- -------------- ------------------

/u02/oradata/sales/system01.dbf system online 546196
/u02/oradata/sales/undotbs01.dbf undotbs1 online 546196
/u02/oradata/sales/sysaux01.dbf sysaux online 546196
/u02/oradata/sales/users01.dbf users online 545498
/u02/oradata/sales/example01.dbf example online 546196
/u02/oradata/sales/perfstat.dbf perfstat online 546196

6 rows selected.


下面end backup,看看scn


sql> alter tablespace users end backup;
tablespace altered.

sql> alter system checkpoint;
system altered.

sql>select name,tablespace_name,status,checkpoint_change# from v$datafile_header;

name tablespace status checkpoint_change#
-------------------------------- ---------- -------------- ------------------
/u02/oradata/sales/system01.dbf system online 546467
/u02/oradata/sales/undotbs01.dbf undotbs1 online 546467
/u02/oradata/sales/sysaux01.dbf sysaux online 546467
/u02/oradata/sales/users01.dbf users online 546467
/u02/oradata/sales/example01.dbf example online 546467
/u02/oradata/sales/perfstat.dbf perfstat online 546467

6 rows selected.

===============================================================

当数据文件置于backup模式时,oracle会去锁定数据文件头,这时候数据库发生检查点的话将不会修改文件头的checkpoint scn,而只是增加checkpoint cnt,所以不管执行cp的时候操作系统块的拷贝顺序是如何,oracle总会从文件头的scn开始恢复,这样的话也就避免了数据丢失和数据块corruption.如果大家用的是rman来备份,那么就不会有这个问题,因为rman备份的时候rman会去对比数据块的头尾标志,如果发现不一致,那么它将会再去读这个块,直到读到一致的块才往备份集里写。

但是alter tablespace XXX begin backup带来的另一个问题是会导致产生多余的日志,通过一个小小的试验就可以证明这一点。

SQL> select name,value from v$sysstat where name='redo size';

NAME VALUE
---------------------------------------------------------------- ----------
redo size 43408

SQL> update test set a=a;

1 row updated.

SQL> commit;

Commit complete.

SQL> select name,value from v$sysstat where name='redo size';

NAME VALUE
---------------------------------------------------------------- ----------
redo size 44060

SQL> ALTER SYSTEM DUMP LOGFILE '/netappredo/redo05.log';

System altered.

一个update的动作产生44060-43408=652bytes的redo

把表空间置为backup mode

SQL> alter tablespace test begin backup;

Tablespace altered.

SQL> select name,value from v$sysstat where name='redo size';

NAME VALUE
---------------------------------------------------------------- ----------
redo size 44732

SQL> update test set a=a;

1 row updated.

SQL> commit;

Commit complete.

SQL> select name,value from v$sysstat where name='redo size';

NAME VALUE
---------------------------------------------------------------- ----------
redo size 53560

SQL> alter tablespace test end backup;

Tablespace altered.

一个update的动作产生53560-44732=8828bytes的redo


看看到底是记了些什么?


SQL> ALTER SYSTEM DUMP LOGFILE '/netappredo/redo05.log';

System altered.

REDO RECORD - Thread:2 RBA: 0x00004e.000000b0.0128 LEN: 0x01b0 VLD: 0x01
SCN: 0x0000.19ed24f7 SUBSCN: 1 06/29/2004 15:05:32
CHANGE #1 TYP:0 CLS:29 AFN:33 DBA:0x08400029 SCN:0x0000.19ed24f2 SEQ: 1 OP:5.2
...... (改动向量1,记载对undo header事务表的修改)
CHANGE #2 TYP:0 CLS:30 AFN:33 DBA:0x0840002e SCN:0x0000.19ed24f0 SEQ: 1 OP:5.1
...... (改动向量2,记载对undo block的修改)
CHANGE #3 TYP:2 CLS: 1 AFN:51 DBA:0x0cc0000f SCN:0x0000.19ed24e8 SEQ: 1 OP:11.5
KTB Redo (改动向量3,记载对数据块的修改,也就是在数据块上执行update test set a=a)
op: 0x11 ver: 0x01
op: F xid: 0x0007.001.00014ece uba: 0x0840002e.0859.38
Block cleanout record, scn: 0x0000.19ed24f7 ver: 0x01 opt: 0x02, entries follow...
itli: 1 flg: 2 scn: 0x0000.19ed24e8
KDO Op code: URP row dependencies Disabled
xtype: XA bdba: 0x0cc0000f hdba: 0x0cc0000b
itli: 2 ispac: 0 maxfr: 4858
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 2 ckix: 0
ncol: 1 nnew: 1 size: 0
col 0: [ 2] c1 02
CHANGE #4 MEDIA RECOVERY MARKER SCN:0x0000.00000000 SEQ: 0 OP:5.20
......(改动向量4,一些标记)


我们看到了正常的日志记录,此外还有些block cleanout及回滚段改变的日志记录,但是相比较不是backup模式的日志来说多了这一部分。
Log block image redo entry
Dump of memory from 0x0AE48820 to 0x0AE4A808
AE48820 00280001 00002C32 19ED24E6 1FE80000 [..(.2,...$......]
AE48830 00321F02 0CC00009 00210005 000307F1 [..2.......!.....]
AE48840 0840000E 0021100C 00002001 19ED24E8 [..@...!.. ...$..]
AE48850 001F0016 0001A94C 0840007C 000D0C08 [....L...|.@.....]
AE48860 00008000 19ED2468 00000000 00000000 [....h$..........]
AE48870 00020100 00160001 1F791F8C 00001F79 [..........y.y...]
AE48880 1F920002 0F88FFFF 0ED00F2C 0E180E74 [........,...t...]
AE48890 0D600DBC 0CA80D04 0BF00C4C 0B380B94 [..`.....L.....8.]
AE488A0 0A800ADC 09C80A24 0910096C 085808B4 [....$...l.....X.]
AE488B0 07A007FC 06E40744 06240684 056405C4 [....D.....$...d.]
......
这一部分是对更改的数据块做的一个镜像,把这个块完全记录到redo里面去了,但是为什么要这么做呢。
这就又牵扯到一个概念,'block split',当数据文件在备份cp时,因为oracle数据块和操作系统块的差异,一个数据块可能由16个操作系统块组成(8k 数据块,512bytes 系统块),这样的话可能出现一个数据块包含了几个不同版本的操作系统块,会导致数据块的不一致,所以在备份模式下如果有语句对备份块产生更新,那么oracle会先把当前块复制一份到redo,当恢复的时候如果碰到数据块不一致就从redo把这个镜像拷贝回去,然后在这个一致性的镜像开始恢复。 如果使用rman来备份可以避免产生过多的块,就像上面所说的,rman会去建议块的一致性,所以不用复制镜像块到日志。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/35489/viewspace-84624/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
Oracle , MySQL, SAP IQ, SAP HANA, PostgreSQL, Tableau 技术讨论,希望在这里一起分享知识,讨论技术,畅谈人生 。

注册时间:2007-12-10

  • 博文量
    5595
  • 访问量
    13207536