從底向上瞭解DML操作

sundog315發表於2010-03-24

些這些東西,擴充套件自這個帖子:[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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章