为什么热备份期间产生的Redo要比正常时多:
我们还要知道的是,在数据库处于热备份(使用Begin Backup进行备份时)状态时,会产生了比平常更多的日志。这是因为在热备份期间,Oracle为了解决SPLIT BLOCK的问题,需要在日志文件中记录修改的行所在的数据块的前镜像(image),而不仅仅是修改信息。为了理解这段话,我们还要简单介绍一下SPLIT BLOCK的概念。
在这种情况下,可能出现如下状况。
当拷贝数据文件的同时,数据库正好向数据文件写数据。这就使得拷贝的文件中包含这样的database block,它的一部分OS block来自于数据库向数据文件(这个db block)写操作之前,另一部分来自于写操作之后。对于数据库来说,这个database block本身并不一致,而是一个分裂块(SPLIT BLOCK)。这样的分裂块在恢复时并不可用(会提示corrupted block)。
所以,在热备状态下,对于变更的数据,Oracle需要在日志中记录整个变化的数据块的前镜像。这样如果在恢复的过程中,数据文件中出现分裂块,Oracle就可以通过日志文件中的数据块的前镜像覆盖备份,以完成恢复。
来看一下测试,首先通过SYS用户连接数据库,确认SCOTT用户连接信息及日志信息:
sys@TQGZS> alter system switch logfile;
System altered.
sys@TQGZS> select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM
---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ---------
1 1 127 52428800 1 NO CURRENT 6260014 19-DEC-09
3 1 126 52428800 1 YES ACTIVE 6258955 19-DEC-09
2 1 123 52428800 1 YES INACTIVE 6258684 19-DEC-09
sys@TQGZS> select sid,serial#,username from v$session where username='SCOTT';
SID SERIAL# USERNAME
---------- ---------- ----------
157 142 SCOTT
然后看一下正常情况下的日志生成:
scott@TQGZS> @mystat "redo size"
NAME VALUE
---------------------------------------- ------------
redo size 0
scott@TQGZS> update emp set sal=1000 where empno=7369;
1 row updated.
scott@TQGZS> commit;
Commit complete.
scott@TQGZS> @mystat2.sql
NAME V DIFF
---------------------------------------- ---------- ----------------
redo size 468 468
正常的更新操作,大约生成了468bytes的日志。然后用SYS用户,将EMP表所在USERS表空间置于热备份模式:
sys@TQGZS> alter tablespace users begin backup;
Tablespace altered.
使用SCOTT用户进行同样操作:
scott@TQGZS> @mystat "redo size"
NAME VALUE
---------------------------------------- ------------
redo size 468
scott@TQGZS> update emp set sal=1000 where empno=7369;
1 row updated.
scott@TQGZS> commit;
Commit complete.
scott@TQGZS> @mystat2.sql
NAME V DIFF
---------------------------------------- ---------- ----------------
redo size 9300 8,832
注意到这一次,生成了8832 bytes的重做日志,这个日志量较上次正常模式下大约多出了一个Block的数量。然后可以用SYS用户转储日志文件,看一下多出来的日志到底是什么内容:
sys@TQGZS> alter system dump logfile '/u01/oracle/oradata/tqgzs/redo01.log';
System altered.
sys@TQGZS> @gettrcname.sql
TRACE_FILE
------------------------------------------------------------
/u01/oracle/admin/tqgzs/udump/tqgzs_ora_3895.trc
检查相关信息,注意到较常规状态下,增加了“Log block image redo entry”部分,这一部分就是在热备份时产生的额外日志信息:
REDO RECORD - Thread:1 RBA: 0x00007f.000002b4.0010 LEN: 0x2050 VLD: 0x05
SCN: 0x0000.005f879d SUBSCN: 1 12/19/2009 17:42:07
CHANGE #1 TYP:3 CLS: 1 AFN:4 DBA:0x0100001e OBJ:54716 SCN:0x0000.005f8704 SEQ: 2 OP:18.1
Log block image redo entry
Dump of memory from 0xAE18A220 to 0xAE18C208
AE18A220 00000001 0000D5BC 005F8702 00000000 [.........._.....]
AE18A230 00320002 01000019 00000004 0000040A [..2.............]
AE18A240 008001BF 004201B4 00008000 00229428 [......B.....(.".]
AE18A250 00030007 0000158C 008068FD 00170718 [.........h......]
AE18A260 00002001 005F8704 00000000 00000000 [. ...._.........]
AE18A270 000C0100 002AFFFF 1D851DAF 00001D85 [......*.........]
AE18A280 1F72000C 1F1C1F47 1EC61EF3 1E741E9D [..r.G.........t.]
AE18A290 1E231E4E 1DD61DFD 00001DAF 00000000 [N.#.............]
AE18A2A0 00000000 00000000 00000000 00000000 [................]
Repeat 470 times
AE18C010 00000000 00000000 00000000 2C000000 [...............,]
AE18C020 C2030800 4D062350 454C4C49 4C430552 [....P#.MILLER.CL]
AE18C030 034B5245 07534EC2 1701B677 02010101 [ERK..NS.w.......]
……
AE18C1D0 B5770763 01011402 11C20201 0204C202 [c.w.............]
AE18C1E0 022C1FC1 4AC20308 4D530546 05485449 [..,....JF.SMITH.]
AE18C1F0 52454C43 50C2034B B4770703 0101110C [CLERK..P..w.....]
AE18C200 0BC20201 15C102FF [........]
Dump of memory from 0xAE18C208 to 0xAE18C209
AE18C200 002C5906 [.Y,.]REDO RECORD - Thread:1 RBA: 0x00007f.000002c4.0160 LEN: 0x01a4 VLD: 0x01
SCN: 0x0000.005f879d SUBSCN: 1 12/19/2009 17:42:07
CHANGE #1 TYP:0 CLS:17 AFN:2 DBA:0x00800009 OBJ:4294967295 SCN:0x0000.005f874f SEQ: 2 OP:5.2
ktudh redo: slt: 0x0007 sqn: 0x0000159f flg: 0x0012 siz: 152 fbi: 0
uba: 0x008015bd.0643.09 pxid: 0x0000.000.00000000
CHANGE #2 TYP:0 CLS:18 AFN:2 DBA:0x008015bd OBJ:4294967295 SCN:0x0000.005f874f SEQ: 3 OP:5.1
ktudb redo: siz: 152 spc: 7038 flg: 0x0012 seq: 0x0643 rec: 0x09
xid: 0x0001.007.0000159f
ktubl redo: slt: 7 rci: 0 opc: 11.1 objn: 54716 objd: 54716 tsn: 4
Undo type: Regular undo Begin trans Last buffer split: No
Temp Object: No
Tablespace Undo: No
0x00000000 prev ctl uba: 0x008015bd.0643.06
prev ctl max cmt scn: 0x0000.005f8265 prev tx cmt scn: 0x0000.005f8279
txn start scn: 0xffff.ffffffff logon user: 54 prev brb: 8394171 prev bcl: 0 KDO undo record:
KTB Redo
op: 0x04 ver: 0x01
op: L itl: xid: 0x0004.000.0000040a uba: 0x008001bf.01b4.42
flg: C--- lkc: 0 scn: 0x0000.00229428
KDO Op code: URP row dependencies Disabled
xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x0100001e hdba: 0x0100001b
itli: 1 ispac: 0 maxfr: 4858
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0 ckix: 191
ncol: 8 nnew: 1 size: 0
Vector content:
col 5: [ 2] c2 0b
CHANGE #3 TYP:2 CLS: 1 AFN:4 DBA:0x0100001e OBJ:54716 SCN:0x0000.005f8704 SEQ: 2 OP:11.5
KTB Redo
op: 0x11 ver: 0x01
op: F xid: 0x0001.007.0000159f uba: 0x008015bd.0643.09
Block cleanout record, scn: 0x0000.005f879d ver: 0x01 opt: 0x02, entries follow...
itli: 2 flg: 2 scn: 0x0000.005f8704
KDO Op code: URP row dependencies Disabled
xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x0100001e hdba: 0x0100001b
itli: 1 ispac: 0 maxfr: 4858
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 1 ckix: 191
ncol: 8 nnew: 1 size: 0
Vector content:
col 5: [ 2] c2 0b
在Oracle数据库内部,存在一个隐含参数控制这个行为:
sys@TQGZS> @GetParDescrb.sql
Enter value for par: _log_blocks_during_backup
old 4: AND x.ksppinm LIKE '%&par%'
new 4: AND x.ksppinm LIKE '%_log_blocks_during_backup%'
NAME VALUE DESCRIB
------------------------------ -------------------- ------------------------------------------------------------
_log_blocks_during_backup TRUE log block images when changed during backup
这个参数缺省值为TRUE,设置在热备份期间允许在Redo中记录数据块信息,如果数据库块大小等于操作系统块大小,则可以设置该参数为False,减少热备期间数据库的负担(这种情况极为少见)。
分裂块产生的根本原因在于备份过程中引入了操作系统工具(如:cp工具等),操作系统工具无法保证Oracle数据块的一致性。如果使用RMAN备份,由于RMAN可以通过反复读取获得一致的Block,从而可以避免SPLIT BLOCK的生成,所以不会产生额外的Redo。所以我们建议,在备份时(特别是繁忙的数据库),应该尽量采用RMAN备份。
- The End -