Row Flag Structure
在看一个数据块的dump文件的时候,经常会发现类似如下的信息...
tl: 12 fb: --H-FL-- lb: 0x1 cc: 2
其中fb, lb, cc就是每一行数据头的信息,分别表示Row Flag, Lock Byte (ITL entry), Column Count. (tl, 应该表示每一行数据实际占用的空间大小,包括row header, 每一个column实际占用的字节数,和用来存储每个column长度的overhead。 tl的信息并没有实际存储。)
那么ROW Flag中的8个bit分别表示什么意思呢 (例如这里的H, F, L)?
---------------------------------------------------------------------------------------------------------------------
这8个bit从高到低依次是:
(128) : Cluster Key
(64) : Cluster Table Member
(32) : Header of row piece
(16): Deleted
(8) : First data piece
(4) : Last data piece
(2) : First column continues from previous piece
(1) : Last column continues in next piece
----------------------------------------------------------------------------------------------------------------------
因此,如果表中的一行记录完全处于一个block中(没有出现row chain, row migration), 不是属于聚簇表,也没有被删除,那么这一行数据的flag应该就是
32 (Header of row piece) + 8 (First data piece) + 4 (Last data piece) = 44 (0x2c), 这个也就是在dump文件中看到的标识--H-FL--
Recover Deleted Rows
SQL> select * from test;
ID NAME
---------- ----------
1 Frank
2 Fraud
SQL> alter system dump datafile 4 block 388;
block_row_dump:
tab 0, row 0, @0x1f8c
tl: 12 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 02
col 1: [ 5] 46 72 61 6e 6b
tab 0, row 1, @0x1f80
tl: 12 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 03
col 1: [ 5] 46 72 61 75 64
SQL> delete from test where id = 2;
1 row deleted.
SQL> commit;
Commit complete.
SQL> alter system dump datafile 4 block 388;
System altered.
block_row_dump:
tab 0, row 0, @0x1f8c
tl: 12 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [ 5] 46 72 61 6e 6b
tab 0, row 1, @0x1f80
tl: 2 fb: --HDFL-- lb: 0x2
end_of_block_dump
BBED> set dba 4, 388
DBA 0x01000184 (16777604 4,388)
BBED> p kdbr
sb2 kdbr[0] @118 8076
sb2 kdbr[1] @120 8064
BBED> p *kdbr[1]
rowdata[0]
----------
ub1 rowdata[0] @8164 0x3c
BBED> x /rnc
rowdata[0] @8164
----------
flag@8164: 0x3c (KDRHFL, KDRHFF, KDRHFD, KDRHFH)
lock@8165: 0x02
cols@8166: 0
BBED> dump /v dba 4, 388 offset 8164
File: /u01/app/oracle/oradata/orcl/users01.dbf (4)
Block: 388 Offsets: 8164 to 8191 Dba:0x01000184
-------------------------------------------------------
3c020202 c1030546 72617564 2c000202 l <...�..Fraud,...
c1020546 72616e6b 01069bdb l �..Frank...
<16 bytes per line>
BBED>
BBED> modify /x 2c offset 8164
File: /u01/app/oracle/oradata/orcl/users01.dbf (4)
Block: 388 Offsets: 8164 to 8191 Dba:0x01000184
------------------------------------------------------------------------
2c020202 c1030546 72617564 2c000202 c1020546 72616e6b 01069bdb
<32 bytes per line>
BBED> dump /v dba 4, 388 offset 8164
File: /u01/app/oracle/oradata/orcl/users01.dbf (4)
Block: 388 Offsets: 8164 to 8191 Dba:0x01000184
-------------------------------------------------------
2c020202 c1030546 72617564 2c000202 l ,...�..Fraud,...
c1020546 72616e6b 01069bdb l �..Frank...
<16 bytes per line>
BBED> p *kdbr[1]
rowdata[0]
----------
ub1 rowdata[0] @8164 0x2c
BBED> x /r
rowdata[0] @8164
----------
flag@8164: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8165: 0x02
cols@8166: 2
col 0[2] @8167: 0xc1 0x03
col 1[5] @8170: 0x46 0x72 0x61 0x75 0x64
BBED> x /rnc
rowdata[0] @8164
----------
flag@8164: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8165: 0x02
cols@8166: 2
col 0[2] @8167: 2
col 1[5] @8170: Fraud
BBED> sum dba 4, 388 apply
Check value for File 4, Block 388:
current = 0x4fb9, required = 0x4fb9
SQL> alter system flush buffer_cache;
System altered.
SQL> select * from test;
ID NAME
---------- ----------
1 Frank
2 Fraud
SQL>