作者:dbtan |【转载时请以超链接形式标明文章出处作者信息】


为什么热备份期间产生的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 -