ITPub博客

首页 > 数据库 > Oracle > 从底向上了解DML操作

从底向上了解DML操作

原创 Oracle 作者:sundog315 时间:2010-03-24 21:47:52 0 删除 编辑

些这些东西,扩展自这个帖子:[url=http://www.itpub.net/viewthread.php?tid=1266978&extra=&page=1]http://www.itpub.net/viewthread.php?tid=1266978&extra=&page=1[/url]

[b]Insert、update、delete,DML操作,大家耳熟能详,使用上也是非常熟练,但是,对于这些操作,oracle在存储底层,也就是在Block里是如何处理的呢?
我们来做个实验,首先,交代环境:[/b]
[font=宋体]SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 – Production

SQL> select t.default_tablespace
2 from dba_users t
3 where t.username='SYS';

DEFAULT_TABLESPACE
------------------------------
SYSTEM

SQL> select t.segment_space_management
2 from dba_tablespaces t
3 where t.tablespace_name='SYSTEM';

SEGMEN
------
MANUAL[/font]

[b]创建测试表:[/b]
[font=宋体]SQL> conn / as sysdba
已连接。
SQL> set autocommit on[/font]
[b]不考虑事务的影响。[/b]

[font=宋体]SQL> create table tt (id number,text varchar2(200));

表已创建。

SQL> alter table tt pctfree 98 pctused 1;

表已更改。[/font]
[b]人为的修改pctfree,pctused,减少Insert能够利用的空间。[/b]

[font=宋体]SQL> insert into tt values(1,'abcdefg');

已创建 1 行。

提交完成。
SQL> select t.header_file,t.header_block from dba_segments t
2 where t.segment_name='TT';

HEADER_FILE HEADER_BLOCK
----------- ------------
1 134577

SQL> alter system dump datafile 1 block 134578;

系统已更改。[/font]

[@more@]

[b]看看Block的内容[/b]
...
75C41D0 000A82FE 00C01145 00C01143 010512FA [....E...C.......]
75C41E0 07B50002 0007002C 020C0008 012CFFF6 [....,.........,.]
75C41F0 02C10202 63626107 67666564 34810605 [.....abcdefg...4]
Block header dump: 0x00420db2
Object id on Block? Y
seg/obj: 0xbf0e csc: 0x00.d3478 itc: 2 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01

Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0008.010.000001ab 0x0080007c.009a.3e --U- 1 fsc 0x0000.000d3481
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000

data_block_dump,data header at 0x75c225c
===============
tsiz: 0x1fa0
hsiz: 0x14
pbl: 0x075c225c
bdba: 0x00420db2
76543210
flag=--------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0x1f92
avsp=0x1f7e
tosp=0x1f7e
0xe:pti[0] nrow=1 offs=0
0x12:pri[0] offs=0x1f92
block_row_dump:
tab 0, row 0, @[color=Red]0x1f92[/color]
tl: 14 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 02
col 1: [ 7] 61 62 63 64 65 66 67
end_of_block_dump

[b]插入一行数据,从block的底端开始填充,行偏移量为[color=Red]0x1f92[/color],下面我们做一下update,更新ID列内容:[/b]

[font=宋体]SQL> conn / as sysdba
已连接。
SQL> update tt set id = 1000000000;

已更新 1 行。

提交完成。
SQL> alter system dump datafile 1 block 134578;

系统已更改。[/font]
7B641E0 07B50002 0007002C 020C0008 022CFFF6 [....,.........,.]
7B641F0 [color=Red]0BC5[/color]0202 63626107 67666564 35000602 [.....abcdefg...5]
Block header dump: 0x00420db2
Object id on Block? Y
seg/obj: 0xbf0e csc: 0x00.d34ff itc: 2 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01

Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0008.010.000001ab 0x0080007c.009a.3e C--- 0 scn 0x0000.000d3481
0x02 0x0001.007.00000141 0x00804714.0089.2b --U- 1 fsc 0x0000.000d3500

data_block_dump,data header at 0x7b6225c
===============
tsiz: 0x1fa0
hsiz: 0x14
pbl: 0x07b6225c
bdba: 0x00420db2
76543210
flag=--------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0x1f92
avsp=0x1f7e
tosp=0x1f7e
0xe:pti[0] nrow=1 offs=0
0x12:pri[0] offs=[color=Red]0x1f92[/color]
block_row_dump:
tab 0, row 0, @0x1f92
tl: 14 fb: --H-FL-- lb: 0x2 cc: 2
col 0: [ 2] [color=Red] c5 0b[/color]
col 1: [ 7] 61 62 63 64 65 66 67
end_of_block_dump

[b]记录位置没有变化,行偏移量仍然为[color=Red]0x1f92[/color],仅仅是列值发生了变化。[/b]

[b]那么,我们修改一下text字段,我们改小这个字段的值,理想状况下,oracle也可以直接修改列值,这样,空间利用最高,我们来看看实际的情况:[/b]

[font=宋体]SQL> conn / as sysdba
已连接。
SQL> update tt set text = 'abc';

已更新 1 行。

提交完成。
SQL> alter system dump datafile 1 block 134578;

系统已更改。[/font]

75C41E0 07B50002 0202012C 61030BC5 002C6362 [....,......abc,.]
75C41F0 0BC50202 63626107 67666564 35E10602 [.....abcdefg...5]
Block header dump: 0x00420db2
Object id on Block? Y
seg/obj: 0xbf0e csc: 0x00.d35e0 itc: 2 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01

Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0001.029.00000140 0x00804714.0089.38 --U- 1 fsc 0x0004.000d35e1
0x02 0x0001.007.00000141 0x00804714.0089.2b C--- 0 scn 0x0000.000d3500

data_block_dump,data header at 0x75c225c
===============
tsiz: 0x1fa0
hsiz: 0x14
pbl: 0x075c225c
bdba: 0x00420db2
76543210
flag=--------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0x1f88
avsp=0x1f7e
tosp=0x1f82
0xe:pti[0] nrow=1 offs=0
0x12:pri[0] offs=0x1f88
block_row_dump:
tab 0, row 0, @[color=Red]0x1f88[/color]
tl: 10 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c5 0b
col 1: [ 3] 61 62 63
end_of_block_dump

[b]完全没有按照预想的来,oracle 仅仅是在空闲的空间复制了一条记录,将text列值修改为update后的值,并修改了行偏移量,现在,这行数据的偏移量为[color=Red]0x1f88[/color],原[color=Red]0x1f92[/color]的空间现在就成了空闲空间。[/b]

[b]再插入两行:[/b]

[font=宋体]SQL> insert into tt values (2,'abcdefg');

已创建 1 行。

提交完成。
SQL> insert into tt values (3,'abcdefg');

已创建 1 行。

提交完成。
SQL> conn / as sysdba
已连接。
SQL> alter system dump datafile 1 block 134578;

系统已更改。[/font]

48441C0 00000000 00000000 0202012C 610704C1 [........,......a]
48441D0 65646362 002C6766 03C10202 63626107 [bcdefg,......abc]
48441E0 67666564 0202002C 61030BC5 002C6362 [defg,......abc,.]
48441F0 0BC50202 63626107 67666564 1B980602 [.....abcdefg....]
Block header dump: 0x00420db2
Object id on Block? Y
seg/obj: 0xbf1e csc: 0x00.e1b97 itc: 2 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01

Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0006.005.000001ba 0x00800e7f.00c7.2f --U- 1 fsc 0x0000.000e1b98
0x02 0x0003.029.000001c1 0x00800eeb.00a6.28 C--- 0 scn 0x0000.000e1b96

data_block_dump,data header at 0x484225c
===============
tsiz: 0x1fa0
hsiz: 0x18
pbl: 0x0484225c
bdba: 0x00420db2
76543210
flag=--------
ntab=1
nrow=3
frre=-1
fsbo=0x18
fseo=0x1f6c
avsp=0x1f62
tosp=0x1f62
0xe:pti[0] nrow=3 offs=0
0x12:pri[0] offs=0x1f88
0x14:pri[1] offs=0x1f7a
0x16:pri[2] offs=0x1f6c
block_row_dump:
tab 0, row 0, @0x1f88
tl: 10 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c5 0b
col 1: [ 3] 61 62 63
tab 0, row 1, @0x1f7a
tl: 14 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 03
col 1: [ 7] 61 62 63 64 65 66 67
tab 0, row 2, @[color=Red]0x1f6c[/color]
tl: 14 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 04
col 1: [ 7] 61 62 63 64 65 66 67
end_of_block_dump

[b]不会利用到上步空闲出来的空间。新纪录的行偏移为[color=Red]0x1f6c[/color]
把第二行的text列内容改大,按照道理,现在的空间肯定是放不下的,需要重新分配空间:[/b]

[font=宋体]SQL> update tt set text='abcdefghijklmnopqrstuvwxyz' where id = 2;

已更新 1 行。

提交完成。
SQL> conn / as sysdba
已连接。
SQL> alter system dump datafile 1 block 134578;

系统已更改。[/font]

48441A0 00000000 2C000000 C1020202 62611A03 [.......,......ab]
48441B0 66656463 6A696867 6E6D6C6B 7271706F [cdefghijklmnopqr]
48441C0 76757473 7A797877 0202012C 610704C1 [stuvwxyz,......a]
48441D0 65646362 002C6766 03C10202 63626107 [bcdefg,......abc]
48441E0 67666564 0202002C 61030BC5 002C6362 [defg,......abc,.]
48441F0 0BC50202 63626107 67666564 1BB90602 [.....abcdefg....]
Block header dump: 0x00420db2
Object id on Block? Y
seg/obj: 0xbf1e csc: 0x00.e1b97 itc: 2 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01

Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0006.005.000001ba 0x00800e7f.00c7.2f --U- 1 fsc 0x0000.000e1b98
0x02 0x0003.006.000001c1 0x00800eeb.00a6.29 --U- 1 fsc 0x0000.000e1bb9

data_block_dump,data header at 0x484225c
===============
tsiz: 0x1fa0
hsiz: 0x18
pbl: 0x0484225c
bdba: 0x00420db2
76543210
flag=--------
ntab=1
nrow=3
frre=-1
fsbo=0x18
fseo=0x1f4b
avsp=0x1f4f
tosp=0x1f4f
0xe:pti[0] nrow=3 offs=0
0x12:pri[0] offs=0x1f88
0x14:pri[1] offs=0x1f4b
0x16:pri[2] offs=0x1f6c
block_row_dump:
tab 0, row 0, @0x1f88
tl: 10 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c5 0b
col 1: [ 3] 61 62 63
tab 0, row 1, @[color=Red]0x1f4b[/color]
tl: 33 fb: --H-FL-- lb: 0x2 cc: 2
col 0: [ 2] c1 03
col 1: [26]
61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79
7a
tab 0, row 2, @0x1f6c
tl: 14 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 04
col 1: [ 7] 61 62 63 64 65 66 67
end_of_block_dump

[b]Ok,这次没有问题,又分配了空间,虽然行数还是2,但偏移量变为0x1f4b。
再整几行[/b]

[font=宋体]SQL> insert into tt values (1,'abc');
已创建 1 行。
提交完成。
SQL> /
已创建 1 行。
提交完成。
SQL> /
已创建 1 行。
提交完成。
SQL> /
已创建 1 行。
提交完成。
SQL> /
已创建 1 行。
提交完成。
SQL> /
已创建 1 行。
提交完成。
SQL> /
已创建 1 行。
提交完成。
SQL> /
已创建 1 行。
提交完成。
SQL> /
已创建 1 行。
提交完成。
SQL> /
已创建 1 行。
提交完成。
SQL> /
已创建 1 行。
提交完成。

[b]够多了,现在应该占用两个块了。[/b]
SQL> alter system dump datafile 1 block 134578;

系统已更改。

SQL> alter system dump datafile 1 block 134579;

系统已更改。[/font]

[b]block 134578:[/b]
7744160 00000000 00000000 2C000000 C1020200 [...........,....]
7744170 62610302 02002C63 0302C102 2C636261 [..abc,......abc,]
7744180 C1020200 62610302 02002C63 0302C102 [......abc,......]
7744190 2C636261 C1020200 62610302 02002C63 [abc,......abc,..]
77441A0 0302C102 2C636261 C1020200 62611A03 [....abc,......ab]
77441B0 66656463 6A696867 6E6D6C6B 7271706F [cdefghijklmnopqr]
77441C0 76757473 7A797877 0202002C 610704C1 [stuvwxyz,......a]
77441D0 65646362 002C6766 03C10202 63626107 [bcdefg,......abc]
77441E0 67666564 0202002C 61030BC5 002C6362 [defg,......abc,.]
77441F0 0BC50202 63626107 67666564 1BD70601 [.....abcdefg....]
Block header dump: 0x00420db2
Object id on Block? Y
seg/obj: 0xbf1e csc: 0x00.e1bd6 itc: 2 flg: - typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01

Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0005.023.000001cb 0x00800fb0.00a8.0a C--- 0 scn 0x0000.000e1bd1
0x02 0x0008.00d.000001c4 0x0080118e.00a3.28 C--- 0 scn 0x0000.000e1bd5

data_block_dump,data header at 0x774225c
===============
tsiz: 0x1fa0
hsiz: 0x24
pbl: 0x0774225c
bdba: 0x00420db2
76543210
flag=--------
ntab=1
[color=Red]nrow=9[/color]
frre=-1
fsbo=0x24
fseo=0x1f0f
avsp=0x1f07
tosp=0x1f07
0xe:pti[0] nrow=9 offs=0
0x12:pri[0] offs=0x1f88
0x14:pri[1] offs=0x1f4b
0x16:pri[2] offs=0x1f6c
0x18:pri[3] offs=0x1f41
0x1a:pri[4] offs=0x1f37
0x1c:pri[5] offs=0x1f2d
0x1e:pri[6] offs=0x1f23
0x20:pri[7] offs=0x1f19
0x22:pri[8] offs=0x1f0f
block_row_dump:
tab 0, row 0, @0x1f88
tl: 10 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c5 0b
col 1: [ 3] 61 62 63
tab 0, row 1, @0x1f4b
tl: 33 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 03
col 1: [26]
61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79
7a
tab 0, row 2, @0x1f6c
tl: 14 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 04
col 1: [ 7] 61 62 63 64 65 66 67
tab 0, row 3, @0x1f41
tl: 10 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [ 3] 61 62 63
tab 0, row 4, @0x1f37
tl: 10 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [ 3] 61 62 63
tab 0, row 5, @0x1f2d
tl: 10 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [ 3] 61 62 63
tab 0, row 6, @0x1f23
tl: 10 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [ 3] 61 62 63
tab 0, row 7, @0x1f19
tl: 10 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [ 3] 61 62 63
tab 0, row 8, @0x1f0f
tl: 10 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [ 3] 61 62 63
end_of_block_dump

[b]block 134579:[/b]
77441C0 00000000 00000000 012C0000 02C10202 [..........,.....]
77441D0 63626103 0202002C 610302C1 002C6362 [.abc,......abc,.]
77441E0 02C10202 63626103 0202002C 610302C1 [.....abc,......a]
77441F0 002C6362 02C10202 63626103 1BDF0602 [bc,......abc....]
Block header dump: 0x00420db3
Object id on Block? Y
seg/obj: 0xbf1e csc: 0x00.e1bde itc: 2 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01

Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0007.027.00000155 0x00800cf2.00a1.04 --U- 1 fsc 0x0000.000e1bdf
0x02 0x0008.015.000001c4 0x0080118e.00a3.29 C--- 0 scn 0x0000.000e1bdd

data_block_dump,data header at 0x774225c
===============
tsiz: 0x1fa0
hsiz: 0x1c
pbl: 0x0774225c
bdba: 0x00420db3
76543210
flag=--------
ntab=1
[color=Red]nrow=5[/color]
frre=-1
fsbo=0x1c
fseo=0x1f6e
avsp=0x1f52
tosp=0x1f52
0xe:pti[0] nrow=5 offs=0
0x12:pri[0] offs=0x1f96
0x14:pri[1] offs=0x1f8c
0x16:pri[2] offs=0x1f82
0x18:pri[3] offs=0x1f78
0x1a:pri[4] offs=0x1f6e
block_row_dump:
tab 0, row 0, @0x1f96
tl: 10 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [ 3] 61 62 63
tab 0, row 1, @0x1f8c
tl: 10 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [ 3] 61 62 63
tab 0, row 2, @0x1f82
tl: 10 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [ 3] 61 62 63
tab 0, row 3, @0x1f78
tl: 10 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [ 3] 61 62 63
tab 0, row 4, @0x1f6e
tl: 10 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 02
col 1: [ 3] 61 62 63
end_of_block_dump

[b]恩,已经分为两个block了,现在,我们测试一下pctrfree,pctused的作用。我们将所有id=1的数据的text列值都改成’abcdefghijklmnopqrstuvwxyz’,都比以前的长,但是,由于我们的pctfree设置的很大,理论上应该是不会造成行链接。[/b]

[font=宋体]SQL> update tt set text='abcdefghijklmnopqrstuvwxyz' where id = 1;

已更新12行。

提交完成。
SQL> alter system dump datafile 1 block 134578;

系统已更改。

SQL> alter system dump datafile 1 block 134579;

系统已更改。[/font]

[b]我们只列出第一个块的内容:[/b]
77440A0 00000000 02012C00 1A02C102 64636261 [.....,......abcd]
77440B0 68676665 6C6B6A69 706F6E6D 74737271 [efghijklmnopqrst]
77440C0 78777675 012C7A79 02C10202 6362611A [uvwxyz,......abc]
77440D0 67666564 6B6A6968 6F6E6D6C 73727170 [defghijklmnopqrs]
77440E0 77767574 2C7A7978 C1020201 62611A02 [tuvwxyz,......ab]
77440F0 66656463 6A696867 6E6D6C6B 7271706F [cdefghijklmnopqr]
7744100 76757473 7A797877 0202012C 611A02C1 [stuvwxyz,......a]
7744110 65646362 69686766 6D6C6B6A 71706F6E [bcdefghijklmnopq]
7744120 75747372 79787776 02012C7A 1A02C102 [rstuvwxyz,......]
7744130 64636261 68676665 6C6B6A69 706F6E6D [abcdefghijklmnop]
7744140 74737271 78777675 012C7A79 02C10202 [qrstuvwxyz,.....]
7744150 6362611A 67666564 6B6A6968 6F6E6D6C [.abcdefghijklmno]
7744160 73727170 77767574 2C7A7978 C1020200 [pqrstuvwxyz,....]
7744170 62610302 02002C63 0302C102 2C636261 [..abc,......abc,]
7744180 C1020200 62610302 02002C63 0302C102 [......abc,......]
7744190 2C636261 C1020200 62610302 02002C63 [abc,......abc,..]
77441A0 0302C102 2C636261 C1020200 62611A03 [....abc,......ab]
77441B0 66656463 6A696867 6E6D6C6B 7271706F [cdefghijklmnopqr]
77441C0 76757473 7A797877 0202002C 610704C1 [stuvwxyz,......a]
77441D0 65646362 002C6766 03C10202 63626107 [bcdefg,......abc]
77441E0 67666564 0202002C 61030BC5 002C6362 [defg,......abc,.]
77441F0 0BC50202 63626107 67666564 1C080607 [.....abcdefg....]
Block header dump: 0x00420db2
Object id on Block? Y
seg/obj: 0xbf1e csc: 0x00.e1bd6 itc: 2 flg: - typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01

Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0002.000.000001c0 0x008010a4.011f.13 --U- 6 fsc 0x0000.000e1c08
0x02 0x0008.00d.000001c4 0x0080118e.00a3.28 C--- 0 scn 0x0000.000e1bd5

data_block_dump,data header at 0x774225c
===============
tsiz: 0x1fa0
hsiz: 0x24
pbl: 0x0774225c
bdba: 0x00420db2
76543210
flag=--------
ntab=1
nrow=9
frre=-1
fsbo=0x24
fseo=0x1e49
avsp=0x1e7d
tosp=0x1e7d
0xe:pti[0] nrow=9 offs=0
0x12:pri[0] offs=0x1f88
0x14:pri[1] offs=0x1f4b
0x16:pri[2] offs=0x1f6c
0x18:pri[3] offs=0x1eee
0x1a:pri[4] offs=0x1ecd
0x1c:pri[5] offs=0x1eac
0x1e:pri[6] offs=0x1e8b
0x20:pri[7] offs=0x1e6a
0x22:pri[8] offs=0x1e49
block_row_dump:
tab 0, row 0, @0x1f88
tl: 10 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c5 0b
col 1: [ 3] 61 62 63
tab 0, row 1, @0x1f4b
tl: 33 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 03
col 1: [26]
61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79
7a
tab 0, row 2, @0x1f6c
tl: 14 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 04
col 1: [ 7] 61 62 63 64 65 66 67
tab 0, row 3, @0x1eee
tl: 33 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 02
col 1: [26]
61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79
7a
tab 0, row 4, @0x1ecd
tl: 33 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 02
col 1: [26]
61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79
7a
tab 0, row 5, @0x1eac
tl: 33 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 02
col 1: [26]
61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79
7a
tab 0, row 6, @0x1e8b
tl: 33 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 02
col 1: [26]
61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79
7a
tab 0, row 7, @0x1e6a
tl: 33 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 02
col 1: [26]
61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79
7a
tab 0, row 8, @0x1e49
tl: 33 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 02
col 1: [26]
61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79
7a
end_of_block_dump

[b]pctfree足够大,update又是复制了新行并更改了偏移量。
OK,试一下删除:[/b]

[font=宋体]SQL> connect / as sysdba
已连接。
SQL> delete tt where id=1;

已删除12行。

提交完成。
SQL> alter system dump datafile 1 block 134578;

系统已更改。[/font]

48840A0 00000000 02023C00 1A02C102 64636261 [.....<......abcd]
48840B0 68676665 6C6B6A69 706F6E6D 74737271 [efghijklmnopqrst]
48840C0 78777675 023C7A79 02C10202 6362611A [uvwxyz<......abc]
48840D0 67666564 6B6A6968 6F6E6D6C 73727170 [defghijklmnopqrs]
48840E0 77767574 3C7A7978 C1020202 62611A02 [tuvwxyz<......ab]
48840F0 66656463 6A696867 6E6D6C6B 7271706F [cdefghijklmnopqr]
4884100 76757473 7A797877 0202023C 611A02C1 [stuvwxyz<......a]
4884110 65646362 69686766 6D6C6B6A 71706F6E [bcdefghijklmnopq]
4884120 75747372 79787776 02023C7A 1A02C102 [rstuvwxyz<......]
4884130 64636261 68676665 6C6B6A69 706F6E6D [abcdefghijklmnop]
4884140 74737271 78777675 023C7A79 02C10202 [qrstuvwxyz<.....]
4884150 6362611A 67666564 6B6A6968 6F6E6D6C [.abcdefghijklmno]
4884160 73727170 77767574 2C7A7978 C1020200 [pqrstuvwxyz,....]
4884170 62610302 02002C63 0302C102 2C636261 [..abc,......abc,]
4884180 C1020200 62610302 02002C63 0302C102 [......abc,......]
4884190 2C636261 C1020200 62610302 02002C63 [abc,......abc,..]
48841A0 0302C102 2C636261 C1020200 62611A03 [....abc,......ab]
48841B0 66656463 6A696867 6E6D6C6B 7271706F [cdefghijklmnopqr]
48841C0 76757473 7A797877 0202002C 610704C1 [stuvwxyz,......a]
48841D0 65646362 002C6766 03C10202 63626107 [bcdefg,......abc]
48841E0 67666564 0202002C 61030BC5 002C6362 [defg,......abc,.]
48841F0 0BC50202 63626107 67666564 1C590608 [.....abcdefg..Y.]
Block header dump: 0x00420db2
Object id on Block? Y
seg/obj: 0xbf1e csc: 0x00.e1c57 itc: 2 flg: O typ: 1 - DATA
fsl: 2 fnx: 0x0 ver: 0x01

Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0002.000.000001c0 0x008010a4.011f.13 C--- 0 scn 0x0000.000e1c08
0x02 0x000a.002.0000014e 0x00801017.008c.2a --U- 7 fsc 0x00ba.000e1c59

data_block_dump,data header at 0x488225c
===============
tsiz: 0x1fa0
hsiz: 0x24
pbl: 0x0488225c
bdba: 0x00420db2
76543210
flag=--------
ntab=1
nrow=9
frre=-1
fsbo=0x24
fseo=0x1e49
avsp=0x1e7d
tosp=0x1f43
0xe:pti[0] nrow=9 offs=0
0x12:pri[0] offs=0x1f88
0x14:pri[1] offs=0x1f4b
0x16:pri[2] offs=0x1f6c
0x18:pri[3] offs=0x1eee
0x1a:pri[4] offs=0x1ecd
0x1c:pri[5] offs=0x1eac
0x1e:pri[6] offs=0x1e8b
0x20:pri[7] offs=0x1e6a
0x22:pri[8] offs=0x1e49
block_row_dump:
tab 0, row 0, @0x1f88
tl: 10 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c5 0b
col 1: [ 3] 61 62 63
tab 0, row 1, @0x1f4b
tl: 33 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 03
col 1: [26]
61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79
7a
tab 0, row 2, @0x1f6c
tl: 14 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 04
col 1: [ 7] 61 62 63 64 65 66 67
tab 0, row 3, @0x1eee
tl: 2 fb: --H[color=Red]D[/color]FL-- lb: 0x2
tab 0, row 4, @0x1ecd
tl: 2 fb: --H[color=Red]D[/color]FL-- lb: 0x2
tab 0, row 5, @0x1eac
tl: 2 fb: --H[color=Red]D[/color]FL-- lb: 0x2
tab 0, row 6, @0x1e8b
tl: 2 fb: --H[color=Red]D[/color]FL-- lb: 0x2
tab 0, row 7, @0x1e6a
tl: 2 fb: --H[color=Red]D[/color]FL-- lb: 0x2
tab 0, row 8, @0x1e49
tl: 2 fb: --H[color=Red]D[/color]FL-- lb: 0x2
end_of_block_dump

[b]数据都还在,只不过,被删除数据的标志位上多了个D,表明该数据已被删除了。
那么,这些标志位都是什么意思呢?[/b]

H Head of row piece
K Cluster key
D Deleted row
F First data piece
L Last data piece
P First column continues from previous location

[b]把TEXT列改大修改一个大的值,看会不会覆盖掉已DELETE的记录:[/b]
[font=宋体]SQL> alter table TT modify TEXT VARCHAR2(4000);

表已更改。
SQL> update tt set text=lpad('a',4000) where id=2;

已更新 1 行。

提交完成。

SQL> conn / as sysdba
已连接。
SQL> alter system dump datafile 1 block 134578;

系统已更改。[/font]
7703100 A0FE03C1 2020200F 20202020 20202020 [..... ]
7703110 20202020 20202020 20202020 20202020 [ ]
Repeat 248 times
77040A0 20202020 02023C61 1A02C102 64636261 [ a<......abcd]
77040B0 68676665 6C6B6A69 706F6E6D 74737271 [efghijklmnopqrst]
77040C0 78777675 023C7A79 02C10202 6362611A [uvwxyz<......abc]
77040D0 67666564 6B6A6968 6F6E6D6C 73727170 [defghijklmnopqrs]
77040E0 77767574 3C7A7978 C1020202 62611A02 [tuvwxyz<......ab]
77040F0 66656463 6A696867 6E6D6C6B 7271706F [cdefghijklmnopqr]
7704100 76757473 7A797877 0202023C 611A02C1 [stuvwxyz<......a]
7704110 65646362 69686766 6D6C6B6A 71706F6E [bcdefghijklmnopq]
7704120 75747372 79787776 02023C7A 1A02C102 [rstuvwxyz<......]
7704130 64636261 68676665 6C6B6A69 706F6E6D [abcdefghijklmnop]
7704140 74737271 78777675 023C7A79 02C10202 [qrstuvwxyz<.....]
7704150 6362611A 67666564 6B6A6968 6F6E6D6C [.abcdefghijklmno]
7704160 73727170 77767574 2C7A7978 C1020200 [pqrstuvwxyz,....]
7704170 62610302 02002C63 0302C102 2C636261 [..abc,......abc,]
7704180 C1020200 62610302 02002C63 0302C102 [......abc,......]
7704190 2C636261 C1020200 62610302 02002C63 [abc,......abc,..]
77041A0 0302C102 2C636261 C1020200 62611A03 [....abc,......ab]
77041B0 66656463 6A696867 6E6D6C6B 7271706F [cdefghijklmnopqr]
77041C0 76757473 7A797877 0202002C 610704C1 [stuvwxyz,......a]
77041D0 65646362 002C6766 03C10202 63626107 [bcdefg,......abc]
77041E0 67666564 0202002C 61030BC5 002C6362 [defg,......abc,.]
77041F0 0BC50202 63626107 67666564 1C820602 [.....abcdefg....]
Block header dump: 0x00420db2
Object id on Block? Y
seg/obj: 0xbf1e csc: 0x00.e1c57 itc: 2 flg: O typ: 1 - DATA
fsl: 2 fnx: 0x0 ver: 0x01

Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0005.01a.000001cd 0x00800fb0.00a8.0f --U- 1 fsc 0x0000.000e1c82
0x02 0x000a.002.0000014e 0x00801017.008c.2a --U- 7 fsc 0x00ba.000e1c59

data_block_dump,data header at 0x770225c
===============
tsiz: 0x1fa0
hsiz: 0x24
pbl: 0x0770225c
bdba: 0x00420db2
76543210
flag=--------
ntab=1
nrow=9
frre=-1
fsbo=0x24
fseo=0xea0
avsp=0xef5
tosp=0xfbb
0xe:pti[0] nrow=9 offs=0
0x12:pri[0] offs=0x1f88
0x14:pri[1] offs=0xea0
0x16:pri[2] offs=0x1f6c
0x18:pri[3] offs=0x1eee
0x1a:pri[4] offs=0x1ecd
0x1c:pri[5] offs=0x1eac
0x1e:pri[6] offs=0x1e8b
0x20:pri[7] offs=0x1e6a
0x22:pri[8] offs=0x1e49
block_row_dump:
tab 0, row 0, @0x1f88
tl: 10 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c5 0b
col 1: [ 3] 61 62 63
tab 0, row 1, @0xea0
tl: 4009 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 03
col 1: [4000]
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20

20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61
tab 0, row 2, @0x1f6c
tl: 14 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 04
col 1: [ 7] 61 62 63 64 65 66 67
tab 0, row 3, @0x1eee
tl: 2 fb: --HDFL-- lb: 0x2
tab 0, row 4, @0x1ecd
tl: 2 fb: --HDFL-- lb: 0x2
tab 0, row 5, @0x1eac
tl: 2 fb: --HDFL-- lb: 0x2
tab 0, row 6, @0x1e8b
tl: 2 fb: --HDFL-- lb: 0x2
tab 0, row 7, @0x1e6a
tl: 2 fb: --HDFL-- lb: 0x2
tab 0, row 8, @0x1e49
tl: 2 fb: --HDFL-- lb: 0x2
end_of_block_dump

[b]block中的空闲空间仍然够,数据还是9行,删除的记录还在,我们再改一个。[/b]

[font=宋体]SQL> update tt set text=lpad('a',4000) where id=1000000000;

已更新 1 行。

提交完成。
SQL> alter system dump datafile 1 block 134578;

系统已更改。[/font]
7702290 00000000 00000000 00000000 0202022C [............,...]
77022A0 A0FE0BC5 2020200F 20202020 20202020 [..... ]
77022B0 20202020 20202020 20202020 20202020 [ ]
Repeat 248 times
7703240 20202020 02002C61 0704C102 64636261 [ a,......abcd]
7703250 2C676665 C1020200 0FA0FE03 20202020 [efg,........ ]
7703260 20202020 20202020 20202020 20202020 [ ]
Repeat 248 times
77041F0 20202020 20202020 61202020 1CA00602 [ a....]
Block header dump: 0x00420db2
Object id on Block? Y
seg/obj: 0xbf1e csc: 0x00.e1c9f itc: 2 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01

Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0005.01a.000001cd 0x00800fb0.00a8.0f C--- 0 scn 0x0000.000e1c82
0x02 0x0003.01b.000001c1 0x00800eeb.00a6.2d --U- 1 fsc 0x0000.000e1ca0

data_block_dump,data header at 0x770225c
===============
tsiz: 0x1fa0
hsiz: 0x18
pbl: 0x0770225c
bdba: 0x00420db2
76543210
flag=--------
ntab=1
nrow=3
frre=-1
fsbo=0x18
fseo=0x40
avsp=0x28
tosp=0x28
0xe:pti[0] nrow=3 offs=0
0x12:pri[0] offs=0x40
0x14:pri[1] offs=0xff7
0x16:pri[2] offs=0xfe9
block_row_dump:
tab 0, row 0, @0x40
tl: 4009 fb: --H-FL-- lb: 0x2 cc: 2
col 0: [ 2] c5 0b
col 1: [4000]
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20

20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61
tab 0, row 1, @0xff7
tl: 4009 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 03
col 1: [4000]
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20

20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61
tab 0, row 2, @0xfe9
tl: 14 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 04
col 1: [ 7] 61 62 63 64 65 66 67
end_of_block_dump

[font=宋体]列 前偏移量 后偏移量 Id存储值
row 0 0x1f88 0x40 C50B
row 1 0xea0 0xff7 C103
row 2 0x1f6c 0xfe9 C104
row 3 0x1eee - -
row 4 0x1ecd - -
row 5 0x1eac - -
row 6 0x1e8b - -
row 7 0x1e6a - -
row 8 0x1e49 - -[/font]

[b]这回是真的给覆盖了,block里的行记录现在是3了,前面标志位有D的记录已经完全被覆盖了。
从这里,我们可以看出,如果记录刚刚被删除,并且没有被其他记录的update覆盖前,数据还存在,并且,可以通过底层的工具恢复出来。但是,一旦别的记录update,并且空间不足时,数据将被彻底覆盖。因此,如果一旦发现重要的数据被误删除,并且没有备份的话,当务之急就是关闭应用,乃至数据库服务器,防止数据被彻底覆盖:)[/b]

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

请登录后发表评论 登录
全部评论

注册时间:2010-01-05

  • 博文量
    126
  • 访问量
    510799