前言: 在block内部oracle的数据到底是怎么存储的,通过rowid方式的时候又是怎样的,insert/delete/update发生的时候又是怎样的,想仔细探讨一下
先交代block里面数据的基本结构:
SQL> create table tn(a number, b varchar2(1000));
Table created.
SQL> insert into tn select rownum, 'wwweeerrrttt' from all_tables where rownum < 11;
10 rows created.
SQL> commit;
Commit complete.
SQL> exec show_space('tn');
Free Blocks.............................1
Total Blocks............................16
Total Bytes.............................131072
Unused Blocks...........................14
Unused Bytes............................114688
Last Used Ext FileId....................3
Last Used Ext BlockId...................1954
Last Used Block.........................2
SQL> alter system dump datafile 3 block 1955;
System altered.
Block header dump: 0x00c007a3
Object id on Block? Y
seg/obj: 0x66b7 csc: 0x00.1891b8a itc: 1 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 xid: 0x0001.011.000000e8 uba: 0x00803494.0147.07 --U- 10 fsc 0x0000.01891b8c
data_block_dump
===============
tsiz: 0x1fb8
hsiz: 0x26
pbl: 0x0ba76c44
bdba: 0x00c007a3
flag=-----------
ntab=1
nrow=10
frre=-1
fsbo=0x26
fseo=0x1efa
avsp=0x1ed4
tosp=0x1ed4
0xeti[0] nrow=10 offs=0 本块存在10条记录
0x12: pri[0] offs=0x1efa ---- 记录的起始物理位置
0x14: pri[1] offs=0x1f0d
0x16: pri[2] offs=0x1f20
0x18: pri[3] offs=0x1f33
0x1a: pri[4] offs=0x1f46
0x1c: pri[5] offs=0x1f59
0x1e: pri[6] offs=0x1f6c
0x20: pri[7] offs=0x1f7f
0x22: pri[8] offs=0x1f92
0x24: pri[9] offs=0x1fa5
block_row_dump:
tab 0, row 0, @0x1efa tl: 19 fb: --H-FL-- lb: 0x1 cc: 2 --- -- lb: 表示属于XID 0x1,cc 表示有2个字段
col 0: [ 2] c1 02 ---- 字段1 长度为2,数据为 c1 02
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74 ---- 字段而长度 12
tab 0, row 1, @0x1f0d
tl: 19 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 03
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 2, @0x1f20
tl: 19 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 04
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 3, @0x1f33
tl: 19 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 05
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 4, @0x1f46
tl: 19 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 06
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 5, @0x1f59
tl: 19 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 07
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 6, @0x1f6c
tl: 19 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 08
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 7, @0x1f7f
tl: 19 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 09
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 8, @0x1f92
tl: 19 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 0a
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 9, @0x1fa5
tl: 19 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 0b
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
end_of_block_dump
End dump data blocks tsn: 2 file#: 3 minblk 1954 maxblk 1955
SQL> delete from tn where a =8 or a = 7;
2 rows deleted.
SQL> commit;
Commit complete.
SQL> alter system dump datafile 3 block 1955;
System altered.
删除2条记录后我们来看block中的变化
Block header dump: 0x00c007a3
Object id on Block? Y
seg/obj: 0x66b7 csc: 0x00.1891b8d itc: 1 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 xid: 0x0002.01a.000000e9 uba: 0x00800314.00d0.24 --U- 2 fsc 0x0022.01891b8f
data_block_dump
===============
tsiz: 0x1fb8
hsiz: 0x26
pbl: 0x0ba76c44
bdba: 0x00c007a3
flag=-----------
ntab=1
nrow=10
frre=-1
fsbo=0x26
fseo=0x1efa
avsp=0x1ed4
tosp=0x1efa
0xe: pti[0] nrow=10 offs=0
0x12: pti[0] offs=0x1efa
0x14: pti[1] offs=0x1f0d
0x16: pti[2] offs=0x1f20
0x18: pti[3] offs=0x1f33
0x1a: pti[4] offs=0x1f46
0x1c: pti[5] offs=0x1f59
0x1e: pti[6] offs=0x1f6c --- 这里暂时没有发生变化
0x20: pti[7] offs=0x1f7f --- 这里暂时没有发生变化
0x22: pti[8] offs=0x1f92
0x24: pti[9] offs=0x1fa5
block_row_dump:
tab 0, row 0, @0x1efa
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 1, @0x1f0d
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 03
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 2, @0x1f20
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 04
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 3, @0x1f33
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 05
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 4, @0x1f46
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 06
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 5, @0x1f59
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 07
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 6, @0x1f6c
tl: 2 fb: --HDFL-- lb: 0x1 ----记录已经被删除
tab 0, row 7, @0x1f7f
tl: 2 fb: --HDFL-- lb: 0x1 ----记录已经被删除
tab 0, row 8, @0x1f92
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 0a
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 9, @0x1fa5
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 0b
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
end_of_block_dump
End dump data blocks tsn: 2 file#: 3 minblk 1955 maxblk 1955
SQL> insert into tn values(19,'q');
1 row created.
SQL> commit;
Commit complete.
SQL> alter system dump datafile 3 block 1955;
System altered.
插入一条记录,我们再看
Block header dump: 0x00c007a3
Object id on Block? Y
seg/obj: 0x66b7 csc: 0x00.1891b90 itc: 1 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 xid: 0x0003.054.000000e8 uba: 0x00800da8.00d9.19 --U- 1 fsc 0x0000.01891b91
data_block_dump
===============
tsiz: 0x1fb8
hsiz: 0x28
pbl: 0x0ba76c44
bdba: 0x00c007a3
flag=-----------
ntab=1
nrow=11
frre=6
fsbo=0x28
fseo=0x1ef2
avsp=0x1eef
tosp=0x1eef
0xe: pti[0] nrow=11 offs=0
0x12: pti[0] offs=0x1efa
0x14: pti[1] offs=0x1f0d
0x16: pti[2] offs=0x1f20
0x18: pti[3] offs=0x1f33
0x1a: pti[4] offs=0x1f46
0x1c: pti[5] offs=0x1f59
0x1e: pti[6] sfll=7 ----被删除
0x20: pti[7] sfll=-1 ------被删除
0x22: pti[8] offs=0x1f92
0x24: pti[9] offs=0x1fa5
0x26: pti[10] offs=0x1ef2 --------新插入记录
block_row_dump:
tab 0, row 0, @0x1efa
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 1, @0x1f0d
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 03
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 2, @0x1f20
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 04
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 3, @0x1f33
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 05
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 4, @0x1f46
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 06
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 5, @0x1f59
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 07
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74 ---- row 6,7 已经被清除
tab 0, row 8, @0x1f92
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 0a
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 9, @0x1fa5
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 0b
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 10, @0x1ef2 ----------------------------新插入记录
tl: 8 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 14
col 1: [ 1] 71
end_of_block_dump
End dump data blocks tsn: 2 file#: 3 minblk 1955 maxblk 1955
SQL> insert into tn values(19,'qqq');
1 row created.
SQL> commit;
Commit complete.
SQL> alter system dump datafile 3 block 1955;
System altered.
再插入记录我们来看
Block header dump: 0x00c007a3
Object id on Block? Y
seg/obj: 0x66b7 csc: 0x00.1891b92 itc: 1 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 xid: 0x0004.02e.000000e7 uba: 0x00800617.00df.1c --U- 1 fsc 0x0000.01891b94
data_block_dump
===============
tsiz: 0x1fb8
hsiz: 0x28
pbl: 0x0ba76c44
bdba: 0x00c007a3
flag=-----------
ntab=1
nrow=11
frre=7
fsbo=0x28
fseo=0x1ee8
avsp=0x1ee5
tosp=0x1ee5
0xe: pti[0] nrow=11 offs=0
0x12: pti[0] offs=0x1efa
0x14: pti[1] offs=0x1f0d
0x16: pti[2] offs=0x1f20
0x18: pti[3] offs=0x1f33
0x1a: pti[4] offs=0x1f46
0x1c: pti[5] offs=0x1f59
0x1e: pti[6] offs=0x1ee8 ------ 新插入记录使用了新的空间,注意 offs 表示物理位置
0x20: pti[7] sfll=-1
0x22: pti[8] offs=0x1f92
0x24: pti[9] offs=0x1fa5
0x26: pti[10] offs=0x1ef2
block_row_dump:
tab 0, row 0, @0x1efa
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 1, @0x1f0d
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 03
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 2, @0x1f20
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 04
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 3, @0x1f33
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 05
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 4, @0x1f46
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 06
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 5, @0x1f59
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 07
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 6, @0x1ee8 ------------------------新插入记录
tl: 10 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 14
col 1: [ 3] 71 71 71
tab 0, row 8, @0x1f92
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 0a
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 9, @0x1fa5
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 0b
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 10, @0x1ef2
tl: 8 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 14
col 1: [ 1] 71
end_of_block_dump
End dump data blocks tsn: 2 file#: 3 minblk 1955 maxblk 1955
SQL> update tn set b = 'qqqqqq' where a = 19;
2 rows updated.
SQL> commit;
Commit complete.
SQL> alter system dump datafile 3 block 1955;
System altered.
更新新插入的两条记录
Block header dump: 0x00c007a3
Object id on Block? Y
seg/obj: 0x66b7 csc: 0x00.1891b95 itc: 1 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 xid: 0x0005.047.000000e7 uba: 0x00803819.0154.04 --U- 2 fsc 0x0000.01891b97
data_block_dump
===============
tsiz: 0x1fb8
hsiz: 0x28
pbl: 0x0ba76c44
bdba: 0x00c007a3
flag=-----------
ntab=1
nrow=11
frre=7
fsbo=0x28
fseo=0x1ece
avsp=0x1ede
tosp=0x1ede
0xe: pti[0] nrow=11 offs=0
0x12: pti[0] offs=0x1efa
0x14: pti[1] offs=0x1f0d
0x16: pti[2] offs=0x1f20
0x18: pti[3] offs=0x1f33
0x1a: pti[4] offs=0x1f46
0x1c: pti[5] offs=0x1f59
0x1e: pti[6] offs=0x1edb --------首先更新这条, 更新后由于原来地方空间不足,被挪到了0x26: pti[10] offs=0x1ef2 之上
0x20: pti[7] sfll=-1
0x22: pti[8] offs=0x1f92
0x24: pti[9] offs=0x1fa5
0x26: pti[10] offs=0x1ece ------- 更新后又由于先更新了0x1e: pti[6],位置不足,又挪到了0x1ece
block_row_dump:
tab 0, row 0, @0x1efa
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 1, @0x1f0d
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 03
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 2, @0x1f20
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 04
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 3, @0x1f33
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 05
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 4, @0x1f46
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 06
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 5, @0x1f59
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 07
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 6, @0x1edb
tl: 13 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 14
col 1: [ 6] 71 71 71 71 71 71
tab 0, row 8, @0x1f92
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 0a
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 9, @0x1fa5
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 0b
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 10, @0x1ece
tl: 13 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 14
col 1: [ 6] 71 71 71 71 71 71
end_of_block_dump
End dump data blocks tsn: 2 file#: 3 minblk 1955 maxblk 1955
SQL> update tn set b = 'qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq' where a = 19;
2 rows updated.
SQL> commit;
Commit complete.
SQL> alter system dump datafile 3 block 1955;
System altered.
继续更新一次看看,又重复了上面的步骤,提升了 物理位置
Block header dump: 0x00c007a3
Object id on Block? Y
seg/obj: 0x66b7 csc: 0x00.1891b98 itc: 1 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 xid: 0x0006.044.000000f2 uba: 0x00801660.00da.0f --U- 2 fsc 0x0000.01891b99
data_block_dump
===============
tsiz: 0x1fb8
hsiz: 0x28
pbl: 0x0ba76c44
bdba: 0x00c007a3
flag=-----------
ntab=1
nrow=11
frre=7
fsbo=0x28
fseo=0x1de0
avsp=0x1e0a
tosp=0x1e0a
0xe: pti[0] nrow=11 offs=0
0x12: pti[0] offs=0x1efa
0x14: pti[1] offs=0x1f0d
0x16: pti[2] offs=0x1f20
0x18: pti[3] offs=0x1f33
0x1a: pti[4] offs=0x1f46
0x1c: pti[5] offs=0x1f59
0x1e: pti[6] offs=0x1e57 -------发生变化
0x20: pti[7] sfll=-1
0x22: pti[8] offs=0x1f92
0x24: pti[9] offs=0x1fa5
0x26: pti[10] offs=0x1de0 ------ 发生变化
block_row_dump:
tab 0, row 0, @0x1efa
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 1, @0x1f0d
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 03
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 2, @0x1f20
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 04
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 3, @0x1f33
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 05
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 4, @0x1f46
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 06
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 5, @0x1f59
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 07
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 6, @0x1e57
tl: 119 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 14
col 1: [112] ---------------数据长度大大增加
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71
tab 0, row 8, @0x1f92
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 0a
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 9, @0x1fa5
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 0b
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 10, @0x1de0
tl: 119 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 14
col 1: [112] ---------------数据长度大大增加
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71
end_of_block_dump
End dump data blocks tsn: 2 file#: 3 minblk 1955 maxblk 1955
SQL> alter table tn add ( c varchar2(30));
Table altered.
SQL> alter system dump datafile 3 block 1955;
System altered.
给表增加一个字段,我们发现数据没有变化
Block header dump: 0x00c007a3
Object id on Block? Y
seg/obj: 0x66b7 csc: 0x00.1891b98 itc: 1 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 xid: 0x0006.044.000000f2 uba: 0x00801660.00da.0f --U- 2 fsc 0x0000.01891b99
data_block_dump
===============
tsiz: 0x1fb8
hsiz: 0x28
pbl: 0x0ba76c44
bdba: 0x00c007a3
flag=-----------
ntab=1
nrow=11
frre=7
fsbo=0x28
fseo=0x1de0
avsp=0x1e0a
tosp=0x1e0a
0xe: pti[0] nrow=11 offs=0
0x12: pti[0] offs=0x1efa
0x14: pti[1] offs=0x1f0d
0x16: pti[2] offs=0x1f20
0x18: pti[3] offs=0x1f33
0x1a: pti[4] offs=0x1f46
0x1c: pti[5] offs=0x1f59
0x1e: pti[6] offs=0x1e57
0x20: pti[7] sfll=-1
0x22: pti[8] offs=0x1f92
0x24: pti[9] offs=0x1fa5
0x26: pti[10] offs=0x1de0
block_row_dump:
tab 0, row 0, @0x1efa
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 1, @0x1f0d
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 03
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 2, @0x1f20
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 04
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 3, @0x1f33
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 05
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 4, @0x1f46
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 06
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 5, @0x1f59
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 07
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 6, @0x1e57
tl: 119 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 14
col 1: [112]
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71
tab 0, row 8, @0x1f92
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 0a
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 9, @0x1fa5
tl: 19 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 0b
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
tab 0, row 10, @0x1de0
tl: 119 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 14
col 1: [112]
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71
end_of_block_dump
End dump data blocks tsn: 2 file#: 3 minblk 1955 maxblk 1955
SQL> update tn set c = 'p';
10 rows updated.
SQL> commit;
Commit complete.
SQL> alter system dump datafile 3 block 1955;
System altered.
更新增加的字段,我们发现所有的行都被提升了物理位置
Block header dump: 0x00c007a3
Object id on Block? Y
seg/obj: 0x66b7 csc: 0x00.1891b9c itc: 1 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 xid: 0x0001.00a.000000e8 uba: 0x00803494.0147.11 --U- 10 fsc 0x0000.01891b9e
data_block_dump
===============
tsiz: 0x1fb8
hsiz: 0x28
pbl: 0x0ba76c44
bdba: 0x00c007a3
flag=-----------
ntab=1
nrow=11
frre=7
fsbo=0x28
fseo=0x1c46
avsp=0x1df6
tosp=0x1df6
0xe: pti[0] nrow=11 offs=0
0x12: pti[0] offs=0x1dcb ---------所有行的物理位置都发生了变化,因为原来的位置装不下多出来的数据了
0x14: pti[1] offs=0x1db6
0x16: pti[2] offs=0x1da1
0x18: pti[3] offs=0x1d8c
0x1a: pti[4] offs=0x1d77
0x1c: pti[5] offs=0x1d62
0x1e: pti[6] offs=0x1ce9
0x20: pti[7] sfll=-1
0x22: pti[8] offs=0x1cd4
0x24: pti[9] offs=0x1cbf
0x26: pti[10] offs=0x1c46
block_row_dump:
tab 0, row 0, @0x1dcb
tl: 21 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 02
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
col 2: [ 1] 70
tab 0, row 1, @0x1db6
tl: 21 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 03
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
col 2: [ 1] 70
tab 0, row 2, @0x1da1
tl: 21 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 04
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
col 2: [ 1] 70
tab 0, row 3, @0x1d8c
tl: 21 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 05
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
col 2: [ 1] 70
tab 0, row 4, @0x1d77
tl: 21 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 06
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
col 2: [ 1] 70
tab 0, row 5, @0x1d62
tl: 21 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 07
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
col 2: [ 1] 70
tab 0, row 6, @0x1ce9
tl: 121 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 14
col 1: [112]
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71
col 2: [ 1] 70
tab 0, row 8, @0x1cd4
tl: 21 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 0a
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
col 2: [ 1] 70
tab 0, row 9, @0x1cbf
tl: 21 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 0b
col 1: [12] 77 77 77 65 65 65 72 72 72 74 74 74
col 2: [ 1] 70
tab 0, row 10, @0x1c46
tl: 121 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 14
col 1: [112]
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71
71 71 71 71 71 71 71 71 71 71 71 71
col 2: [ 1] 70
end_of_block_dump
End dump data blocks tsn: 2 file#: 3 minblk 1955 maxblk 1955
SQL> update tn set b = lpad('sd',999);
10 rows updated.
SQL> commit;
Commit complete.
SQL> alter system dump datafile 3 block 1955;
System altered.
SQL> update tn set b ='qqqqqqq';
10 rows updated.
SQL> commit;
Commit complete.
SQL> alter system dump datafile 3 block 1955;
System altered.
首先更新到让记录发生了行迁移,然后再更新回来,因为这时数据太大,就不把发生迁移后的数据全部贴出来,给个再更新回来的结果
Block header dump: 0x00c007a3
Object id on Block? Y
seg/obj: 0x66b7 csc: 0x00.1891ba5 itc: 1 flg: O typ: 1 - DATA
fsl: 1 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 xid: 0x0004.047.000000e7 uba: 0x00800618.00df.08 --U- 11 fsc 0x1b2e.01891ba7
data_block_dump
===============
tsiz: 0x1fb8
hsiz: 0x28
pbl: 0x0ba76c44
bdba: 0x00c007a3
flag=-----------
ntab=1
nrow=11
frre=7
fsbo=0x28
fseo=0x2f6
avsp=0x3d0
tosp=0x1efe
0xe: pti[0] nrow=11 offs=0
0x12: pti[0] offs=0x35c -------位置都发生了变化
0x14: pti[1] offs=0x34b
0x16: pti[2] offs=0x33a
0x18: pti[3] offs=0x329
0x1a: pti[4] offs=0x318
0x1c: pti[5] offs=0x307
0x1e: pti[6] offs=0x2f6
0x20: pti[7] sfll=-1
0x22: pti[8] offs=0x7f0
0x24: pti[9] offs=0x7da
0x26: pti[10] offs=0x760
block_row_dump:
tab 0, row 0, @0x35c
tl: 17 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 02
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 1, @0x34b
tl: 17 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 03
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 2, @0x33a
tl: 17 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 04
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 3, @0x329
tl: 17 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 05
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 4, @0x318
tl: 17 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 06
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 5, @0x307
tl: 17 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 07
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 6, @0x2f6
tl: 17 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 14
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 8, @0x7f0 -------------- 从row 8 --- row 10 的记录已经迁移到新的block中,这里保留的是新块的物理位置
tl: 9 fb: --H----- lb: 0x1 cc: 0
nrid: 0x00c007a4.0 ------------ 迁移到了 block编号为 0x00c007a4 的块中的 row 0 (本块为 0x00c007a3)
tab 0, row 9, @0x7da
tl: 9 fb: --H----- lb: 0x1 cc: 0
nrid: 0x00c007a4.1 迁移到了 block编号为 0x00c007a4 的块中的 row 1 (本块为 0x00c007a3)
tab 0, row 10, @0x760
tl: 9 fb: --H----- lb: 0x1 cc: 0
nrid: 0x00c007a4.2 迁移到了 block编号为 0x00c007a4 的块中的 row 2 (本块为 0x00c007a3)
end_of_block_dump
End dump data blocks tsn: 2 file#: 3 minblk 1955 maxblk 1955
SQL> insert into tn values(1,1,1);
1 row created.
SQL> commit;
Commit complete.
SQL> alter system dump datafile 3 block 1955;
System altered.
再插入记录,我们看看位置,我们发现该块并没有被插入记录,记录是插入到了 另外一个块(虽然该块现在空间使用率并不高)
这是因为在update的时候先脱离了freelist然后又回到freelist了,排在了 block 1956 之后
Block header dump: 0x00c007a3
Object id on Block? Y
seg/obj: 0x66b7 csc: 0x00.1891ba5 itc: 1 flg: O typ: 1 - DATA
fsl: 1 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 xid: 0x0004.047.000000e7 uba: 0x00800618.00df.08 --U- 11 fsc 0x1b2e.01891ba7
data_block_dump
===============
tsiz: 0x1fb8
hsiz: 0x28
pbl: 0x0ba76c44
bdba: 0x00c007a3
flag=-----------
ntab=1
nrow=11
frre=7
fsbo=0x28
fseo=0x2f6
avsp=0x3d0
tosp=0x1efe
0xe: pti[0] nrow=11 offs=0
0x12: pti[0] offs=0x35c
0x14: pti[1] offs=0x34b
0x16: pti[2] offs=0x33a
0x18: pti[3] offs=0x329
0x1a: pti[4] offs=0x318
0x1c: pti[5] offs=0x307
0x1e: pti[6] offs=0x2f6
0x20: pti[7] sfll=-1
0x22: pti[8] offs=0x7f0
0x24: pti[9] offs=0x7da
0x26: pti[10] offs=0x760
block_row_dump:
tab 0, row 0, @0x35c
tl: 17 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 02
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 1, @0x34b
tl: 17 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 03
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 2, @0x33a
tl: 17 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 04
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 3, @0x329
tl: 17 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 05
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 4, @0x318
tl: 17 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 06
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 5, @0x307
tl: 17 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 07
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 6, @0x2f6
tl: 17 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 14
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 8, @0x7f0
tl: 9 fb: --H----- lb: 0x1 cc: 0
nrid: 0x00c007a4.0
tab 0, row 9, @0x7da
tl: 9 fb: --H----- lb: 0x1 cc: 0
nrid: 0x00c007a4.1
tab 0, row 10, @0x760
tl: 9 fb: --H----- lb: 0x1 cc: 0
nrid: 0x00c007a4.2
end_of_block_dump
End dump data blocks tsn: 2 file#: 3 minblk 1955 maxblk 1955
SQL> insert into tn select 1,1,1 from all_objects where rownum < 1001;
1000 rows created.
SQL> commit;
Commit complete.
SQL> alter system dump datafile 3 block 1955;
System altered.
SQL>
再插入1000条记录,我们发现其中600条插到了 block 1956中,而本块只插入了400条,这是因为freelist中的顺序问题
并且我们发现,本块中原来存在的记录已经完全重新组织过,物理位置都因为insert而发生了变化
也就是说oracle 的 block中的记录物理位置是可能重组的,但不变的是 行号,这个行号和物理位置记录在 前部,供通过
rowid 查询的时候快速定位
Block header dump: 0x00c007a3
Object id on Block? Y
seg/obj: 0x66b7 csc: 0x00.1891bab itc: 1 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 xid: 0x0006.01e.000000f2 uba: 0x00801660.00da.14 --U- 400 fsc 0x0000.01891bad
data_block_dump
===============
tsiz: 0x1fb8
hsiz: 0x346
pbl: 0x0ba76c44
bdba: 0x00c007a3
flag=-----------
ntab=1
nrow=410
frre=-1
fsbo=0x346
fseo=0xf86
avsp=0xc40
tosp=0xc40
0xe: pti[0] nrow=410 offs=0
0x12: pti[0] offs=0x1fa7 先前的7条记录物理位置已经发生变化但是行号没有改变
0x14: pti[1] offs=0x1f96 先前的7条记录物理位置已经发生变化但是行号没有改变
0x16: pti[2] offs=0x1f85 先前的7条记录物理位置已经发生变化但是行号没有改变
0x18: pti[3] offs=0x1f74 先前的7条记录物理位置已经发生变化但是行号没有改变
0x1a: pti[4] offs=0x1f63 先前的7条记录物理位置已经发生变化但是行号没有改变
0x1c: pti[5] offs=0x1f52 先前的7条记录物理位置已经发生变化但是行号没有改变
0x1e: pti[6] offs=0x1f41 先前的7条记录物理位置已经发生变化但是行号没有改变
0x20: pti[7] offs=0x18b4 该行号已经被新的记录插入
0x22: pti[8] offs=0x1f38 该行迁移发生的记录没有发生变化,这是因为这样不用更新索引
0x24: pti[9] offs=0x1f2f 该行迁移发生的记录没有发生变化,这是因为这样不用更新索引
0x26: pti[10] offs=0x1f26 该行迁移发生的记录没有发生变化,这是因为这样不用更新索引
0x28: pti[11] offs=0x18be 新插入的记录
0x2a: pti[12] offs=0x18c8 新插入的记录
0x2c: pti[13] offs=0x18d2 新插入的记录
0x2e: pti[14] offs=0x18dc 新插入的记录
0x30: pti[15] offs=0x18e6 新插入的记录
0x32: pti[16] offs=0x18f0 新插入的记录
0x34: pti[17] offs=0x18fa 新插入的记录
0x36: pti[18] offs=0x1904 新插入的记录
……………………………………………………
省略掉一些
block_row_dump:
tab 0, row 0, @0x1fa7
tl: 17 fb: --H-FL-- lb: 0x0 cc: 3
col 0: [ 2] c1 02
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 1, @0x1f96
tl: 17 fb: --H-FL-- lb: 0x0 cc: 3
col 0: [ 2] c1 03
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 2, @0x1f85
tl: 17 fb: --H-FL-- lb: 0x0 cc: 3
col 0: [ 2] c1 04
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 3, @0x1f74
tl: 17 fb: --H-FL-- lb: 0x0 cc: 3
col 0: [ 2] c1 05
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 4, @0x1f63
tl: 17 fb: --H-FL-- lb: 0x0 cc: 3
col 0: [ 2] c1 06
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 5, @0x1f52
tl: 17 fb: --H-FL-- lb: 0x0 cc: 3
col 0: [ 2] c1 07
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 6, @0x1f41
tl: 17 fb: --H-FL-- lb: 0x0 cc: 3
col 0: [ 2] c1 14
col 1: [ 7] 71 71 71 71 71 71 71
col 2: [ 2] 70 70
tab 0, row 7, @0x18b4
tl: 10 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 02
col 1: [ 1] 31
col 2: [ 1] 31
tab 0, row 8, @0x1f38
tl: 9 fb: --H----- lb: 0x0 cc: 0
nrid: 0x00c007a4.0
tab 0, row 9, @0x1f2f
tl: 9 fb: --H----- lb: 0x0 cc: 0
nrid: 0x00c007a4.1
tab 0, row 10, @0x1f26
tl: 9 fb: --H----- lb: 0x0 cc: 0
nrid: 0x00c007a4.2
tab 0, row 11, @0x18be
tl: 10 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 02
col 1: [ 1] 31
col 2: [ 1] 31
tab 0, row 12, @0x18c8
tl: 10 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 02
col 1: [ 1] 31
col 2: [ 1] 31
tab 0, row 13, @0x18d2
tl: 10 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 02
col 1: [ 1] 31
col 2: [ 1] 31
tab 0, row 14, @0x18dc
tl: 10 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 02
col 1: [ 1] 31
col 2: [ 1] 31
tab 0, row 15, @0x18e6
tl: 10 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 02
col 1: [ 1] 31
col 2: [ 1] 31
tab 0, row 16, @0x18f0
tl: 10 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 02
col 1: [ 1] 31
省略掉后面重复的数据
一个行跨越block的例子
注意,其中有字段跨越了 block
由这个例子可以看出,一个行在写入的时候实际上数据是倒着写的
假设存在着字段 1,2,3,4,5
先写字段5--4---3--2---1
当跨越block的时候,是字段1和2的前24字节在相临的第二个block
也就是说连字段数据都是靠近末尾部分先写进block
而行若存在索引,则rowid 指向的block实际上应该是在 第二个block,第二个block保存着剩下部分数据的指针
SQL> create table blocks(a char(2000),b char(2000), c char(2000),d char(2000),e char(2000));
Table created.
SQL> set serverout on
SQL> exec show_space('blocks');
Free Blocks.............................0
Total Blocks............................16
Total Bytes.............................131072
Unused Blocks...........................15
Unused Bytes............................122880
Last Used Ext FileId....................3
Last Used Ext BlockId...................32226
Last Used Block.........................1
PL/SQL procedure successfully completed.
SQL> insert into blocks values (1,1,1,1,1);
1 row created.
SQL> commit;
Commit complete.
SQL> alter system dump datafile 3 block min 32227 block max 32228;
System altered.
*** 2003-04-15 14:54:39.078
Start dump data blocks tsn: 2 file#: 3 minblk 32227 maxblk 32228
buffer tsn: 2 rdba: 0x00c07de3 (3/32227)
scn: 0x0000.01892035 seq: 0x01 flg: 0x02 tail: 0x20350601
frmt: 0x02 chkval: 0x0000 type: 0x06=trans data
Block header dump: 0x00c07de3
Object id on Block? Y
seg/obj: 0x66c3 csc: 0x00.1892033 itc: 1 flg: - typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 xid: 0x0003.01d.000000e9 uba: 0x00800dac.00d9.28 --U- 1 fsc 0x0000.01892035
data_block_dump
===============
tsiz: 0x1fb8
hsiz: 0x14
pbl: 0x02556c44
bdba: 0x00c07de3
flag=-----------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0x81
avsp=0x6d
tosp=0x6d
0xeti[0] nrow=1 offs=0 本块只有一条记录
0x12ri[0] offs=0x81 本记录从 本块的 129个字节为开始 0x81 = 8*16 + 1 = 129
block_row_dump:
tab 0, row 0, @0x81
tl: 7991 本block中 行长度为 7991, 7991 + 129 = 8192 = block_size 8k fb: -----LP- lb: 0x1 cc: 4 (本block包含4个字段内容)
col 0: [1976] ------这里只存放了本字段的后1976个字节
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
************************************************************************* ------- 表示省略相同部分数据的显示
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20
col 1: [2000]
31 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
***********************************************************************
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
col 2: [2000]
31 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
**********************************************************************
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
col 3: [2000]
31 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
*************************************************************************
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
end_of_block_dump
buffer tsn: 2 rdba: 0x00c07de4 (3/32228)
scn: 0x0000.01892035 seq: 0x01 flg: 0x02 tail: 0x20350601
frmt: 0x02 chkval: 0x0000 type: 0x06=trans data
Block header dump: 0x00c07de4
Object id on Block? Y
seg/obj: 0x66c3 csc: 0x00.1892033 itc: 1 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 xid: 0x0003.01d.000000e9 uba: 0x00800dac.00d9.29 --U- 1 fsc 0x0000.01892035
data_block_dump
===============
tsiz: 0x1fb8
hsiz: 0x14
pbl: 0x02556c44
bdba: 0x00c07de4
flag=-----------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0x17c3
avsp=0x17af
tosp=0x17af
0xeti[0] nrow=1 offs=0
0x12ri[0] offs=0x17c3
block_row_dump:
tab 0, row 0, @0x17c3
tl: 2037 fb: --H-F--N lb: 0x1 cc: 2 -----本block只保存着本行的2个字段 ,关于 fb 的内容偶暂时不能解读,应该跟 行迁移 和行连接有关
nrid: 0x00c07de3.0 ------- 表示存在着部分数据在 block 0x00c07de3 的 row 0 的行上
col 0: [2000]
31 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
**************************************************************************
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
col 1: [24] ---第二个字段在本块只保存了24个字节
31 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
end_of_block_dump
End dump data blocks tsn: 2 file#: 3 minblk 32227 maxblk 32228
最后结论
1: 当block中开始插入数据的时候,正常插入
2:当删除记录后的空间,如果新插入的数据能容纳进去,则重用
3: 当更新的时候,如果 row 长度没有增加,则位置不变,如果长度增加,则被迁移到整个块的最前记录之前(靠近 block header 一侧)
4:当发生行迁移的时候,在原物理位置保留 迁移后的 block位置和 row number
5:当block重新返回freelist 再插入记录的时候,可能发生block数据的重组(row number不变但是物理位置发生变化),到底什么时候重组,我发现,在block中空间比较零散或者被使用的少部分空间位于block的header一侧而tail一侧是空闲的话,在insert的时候会导致空间重构,也就是说原来在靠近header一侧位置存储的数据,在insert发生之前被 迁移 到block的tail位置,发生了空间的重组,事实上,当插入数据或者update的时候,若块中总剩余空间足够但是都是很零碎的,而零碎空间无法容纳则也发生块内重构,这样在本质上就是block内空间的重组,也就是说 在block级别的空间重组是自动的,而segment 级别的就必须采用exp/imp, alter ...... move ,ctas 等等方式
原文参考: http://www.itpub.net/showthread.php?threadid=112239