assm下oracle為什麼為segment提供了shrink功能

warehouse發表於2009-10-10
透過試驗簡單的測試了一下assm下segment的space的分配和使用[@more@]

SQL> select tablespace_name,segment_space_management from dba_tablespaces;

TABLESPACE_NAME SEGMEN
------------------------------ ------
SYSTEM MANUAL
UNDOTBS1 MANUAL
SYSAUX AUTO
TEMP MANUAL
USERS AUTO
--users標空間是assm,system標空間是mssm,下面測試是建立的表放在這2個標空間中
SQL> create table t(id int , name varchar2(4000)) pctfree 50 tablespace users;

表已建立。

SQL> insert into t values(1,rpad('a',4000,'*'));

已建立 1 行。

SQL> insert into t values(2,rpad('b',4000,'*'));

已建立 1 行。

SQL> insert into t values(3,rpad('c',4000,'*'));

已建立 1 行。

SQL> commit;

提交完成。

SQL> select id,substr(name,1,1),rowid,dbms_rowid.rowid_relative_fno(rowid) fno,d
bms_rowid.rowid_block_number(rowid) bno from t;

ID SU ROWID FNO BNO
---------- -- ------------------ ---------- ----------
2 b AAAC4KAAEAAAAE0AAA 4 308
3 c AAAC4KAAEAAAAE1AAA 4 309
1 a AAAC4KAAEAAAAE4AAA 4 312

SQL> analyze table t compute statistics ;

表已分析。

SQL> select blocks,empty_blocks from dba_tables where table_name='T' and owner='
SYS';

BLOCKS EMPTY_BLOCKS
---------- ------------
5 3
--只插入3條資料,hwm下居然就有5個block了?
SQL> select block_id,blocks from dba_extents where owner='SYS' and segment_name=
'T';

BLOCK_ID BLOCKS
---------- ----------
305 8

SQL> select header_block from dba_segments where owner='SYS' and segment_name='T
';

HEADER_BLOCK
------------
307

SQL>
--顯然block#:305,306,307是metadata,308~312可以供我們插入資料使用
SQL> alter system dump datafile 4 block 307;

系統已更改。

SQL> analyze table t compute statistics ;

表已分析。
SQL> select blocks,empty_blocks from dba_tables where table_name='T' and owner='
SYS';

BLOCKS EMPTY_BLOCKS
---------- ------------
5 3

SQL> insert into t values(4,rpad('d',4000,'*'));

已建立 1 行。

SQL> commit;

提交完成。

SQL> analyze table t compute statistics ;

表已分析。

SQL> select blocks,empty_blocks from dba_tables where table_name='T' and owner='
SYS';

BLOCKS EMPTY_BLOCKS
---------- ------------
5 3

SQL> select id,substr(name,1,1),rowid,dbms_rowid.rowid_relative_fno(rowid) fno,d
bms_rowid.rowid_block_number(rowid) bno from t;

ID SU ROWID FNO BNO
---------- -- ------------------ ---------- ----------
2 b AAAC4KAAEAAAAE0AAA 4 308
3 c AAAC4KAAEAAAAE1AAA 4 309
4 d AAAC4KAAEAAAAE3AAA 4 311
1 a AAAC4KAAEAAAAE4AAA 4 312

SQL> insert into t values(5,rpad('e',4000,'*'));

已建立 1 行。

SQL> commit;

提交完成。

SQL> analyze table t compute statistics ;

表已分析。

SQL> select blocks,empty_blocks from dba_tables where table_name='T' and owner='
SYS';

BLOCKS EMPTY_BLOCKS
---------- ------------
5 3

SQL> select id,substr(name,1,1),rowid,dbms_rowid.rowid_relative_fno(rowid) fno,d
bms_rowid.rowid_block_number(rowid) bno from t;

ID SU ROWID FNO BNO
---------- -- ------------------ ---------- ----------
2 b AAAC4KAAEAAAAE0AAA 4 308
3 c AAAC4KAAEAAAAE1AAA 4 309
5 e AAAC4KAAEAAAAE2AAA 4 310
4 d AAAC4KAAEAAAAE3AAA 4 311
1 a AAAC4KAAEAAAAE4AAA 4 312

SQL> insert into t values(6,rpad('f',4000,'*'));

已建立 1 行。

SQL> commit;

提交完成。

SQL> analyze table t compute statistics ;

表已分析。

SQL> select blocks,empty_blocks from dba_tables where table_name='T' and owner='
SYS';

BLOCKS EMPTY_BLOCKS
---------- ------------
13 3
--這裡有意思的事兒出現了,assm時系統自動分配extent之後,把這個extent所包含的blocks全部納入hwm之下了,這一點和
mssm不同,mssm時block只有被使用過時被看作是在hwm之下
SQL> select id,substr(name,1,1),rowid,dbms_rowid.rowid_relative_fno(rowid) fno,d
bms_rowid.rowid_block_number(rowid) bno from t;

ID SU ROWID FNO BNO
---------- -- ------------------ ---------- ----------
2 b AAAC4KAAEAAAAE0AAA 4 308
3 c AAAC4KAAEAAAAE1AAA 4 309
5 e AAAC4KAAEAAAAE2AAA 4 310
4 d AAAC4KAAEAAAAE3AAA 4 311
1 a AAAC4KAAEAAAAE4AAA 4 312
6 f AAAC4KAAEAAAAE/AAA 4 319

已選擇6行。

SQL> delete from t where id=2;

已刪除 1 行。

SQL> commit;

提交完成。

SQL> insert into t values(7,rpad('g',4000,'*'));

已建立 1 行。

SQL> commit;

提交完成。

SQL> analyze table t compute statistics ;

表已分析。

SQL> select blocks,empty_blocks from dba_tables where table_name='T' and owner='
SYS';

BLOCKS EMPTY_BLOCKS
---------- ------------
13 3

SQL> select id,substr(name,1,1),rowid,dbms_rowid.rowid_relative_fno(rowid) fno,d
bms_rowid.rowid_block_number(rowid) bno from t;

ID SU ROWID FNO BNO
---------- -- ------------------ ---------- ----------
3 c AAAC4KAAEAAAAE1AAA 4 309
5 e AAAC4KAAEAAAAE2AAA 4 310
4 d AAAC4KAAEAAAAE3AAA 4 311
1 a AAAC4KAAEAAAAE4AAA 4 312
7 g AAAC4KAAEAAAAE5AAA 4 313
6 f AAAC4KAAEAAAAE/AAA 4 319

已選擇6行。

SQL> insert into t values(8,rpad('g',4000,'*'));

已建立 1 行。

SQL> insert into t values(9,rpad('g',4000,'*'));

已建立 1 行。

SQL> insert into t values(10,rpad('g',4000,'*'));

已建立 1 行。

SQL> insert into t values(11,rpad('g',4000,'*'));

已建立 1 行。

SQL> insert into t values(12,rpad('g',4000,'*'));

已建立 1 行。

SQL> insert into t values(13,rpad('g',4000,'*'));

已建立 1 行。

SQL> commit;

提交完成。

SQL> analyze table t compute statistics ;

表已分析。

SQL> select blocks,empty_blocks from dba_tables where table_name='T' and owner='
SYS';

BLOCKS EMPTY_BLOCKS
---------- ------------
13 3

SQL> select id,substr(name,1,1),rowid,dbms_rowid.rowid_relative_fno(rowid) fno,d
bms_rowid.rowid_block_number(rowid) bno from t;

ID SU ROWID FNO BNO
---------- -- ------------------ ---------- ----------
3 c AAAC4KAAEAAAAE1AAA 4 309
5 e AAAC4KAAEAAAAE2AAA 4 310
4 d AAAC4KAAEAAAAE3AAA 4 311
1 a AAAC4KAAEAAAAE4AAA 4 312
7 g AAAC4KAAEAAAAE5AAA 4 313
8 g AAAC4KAAEAAAAE6AAA 4 314
9 g AAAC4KAAEAAAAE7AAA 4 315
10 g AAAC4KAAEAAAAE8AAA 4 316
11 g AAAC4KAAEAAAAE9AAA 4 317
12 g AAAC4KAAEAAAAE+AAA 4 318
6 f AAAC4KAAEAAAAE/AAA 4 319

ID SU ROWID FNO BNO
---------- -- ------------------ ---------- ----------
13 g AAAC4KAAEAAAAFAAAA 4 320

已選擇12行。

SQL> insert into t values(14,rpad('g',4000,'*'));

已建立 1 行。

SQL> commit;

提交完成。

SQL> analyze table t compute statistics ;

表已分析。

SQL> select blocks,empty_blocks from dba_tables where table_name='T' and owner='
SYS';

BLOCKS EMPTY_BLOCKS
---------- ------------
13 3

SQL> select id,substr(name,1,1),rowid,dbms_rowid.rowid_relative_fno(rowid) fno,d
bms_rowid.rowid_block_number(rowid) bno from t;

ID SU ROWID FNO BNO
---------- -- ------------------ ---------- ----------
14 g AAAC4KAAEAAAAE0AAA 4 308
3 c AAAC4KAAEAAAAE1AAA 4 309
5 e AAAC4KAAEAAAAE2AAA 4 310
4 d AAAC4KAAEAAAAE3AAA 4 311
1 a AAAC4KAAEAAAAE4AAA 4 312
7 g AAAC4KAAEAAAAE5AAA 4 313
8 g AAAC4KAAEAAAAE6AAA 4 314
9 g AAAC4KAAEAAAAE7AAA 4 315
10 g AAAC4KAAEAAAAE8AAA 4 316
11 g AAAC4KAAEAAAAE9AAA 4 317
12 g AAAC4KAAEAAAAE+AAA 4 318

ID SU ROWID FNO BNO
---------- -- ------------------ ---------- ----------
6 f AAAC4KAAEAAAAE/AAA 4 319
13 g AAAC4KAAEAAAAFAAAA 4 320

已選擇13行。
--透過上面連續插入的id=8~13共6條資料我們發現hwm之下如果有"new"block(從未被使用),那麼
oracle優先使用這些block,如果這些block被用完之後,會重新使用被釋放出來的block:如308)
SQL> insert into t values(15,rpad('g',4000,'*'));

已建立 1 行。

SQL> commit;

提交完成。

SQL> analyze table t compute statistics ;

表已分析。

SQL> select blocks,empty_blocks from dba_tables where table_name='T' and owner='
SYS';

BLOCKS EMPTY_BLOCKS
---------- ------------
20 4

SQL>
SQL> select extent_id ,block_id, blocks from dba_extents where owner='SYS' and s
egment_name='T';

EXTENT_ID BLOCK_ID BLOCKS
---------- ---------- ----------
0 305 8
1 313 8
2 321 8

SQL>
--我們手動為segment分配的extent所包含的block在沒有被使用之前始終還是在hwm之上這一點和
mssm一樣;透過測試發現assm下如果extent始終是系統分配給segment的,也就是說沒有我們手動分配干預,那麼在hwm
之上的block全部是metadata所使用的,難怪在assm下oracle為段提供了shrink功能,因為assm下hwm下的free block似乎比
mssm下hwm下的free block"更多"...
SQL> alter table t allocate extent (size 64k datafile 'C:oradataTESTusers01.d
bf');

表已更改。

SQL> select extent_id ,block_id, blocks from dba_extents where owner='SYS' and s
egment_name='T';

EXTENT_ID BLOCK_ID BLOCKS
---------- ---------- ----------
0 305 8
1 313 8
2 321 8
3 329 8

SQL> analyze table t compute statistics ;

表已分析。

SQL> select blocks,empty_blocks from dba_tables where table_name='T' and owner='
SYS';

BLOCKS EMPTY_BLOCKS
---------- ------------
20 12

SQL>
--================================
SQL> create table tt(id int ,name varchar2(4000)) pctfree 50 tablespace system;

表已建立。
SQL> insert into tt values(1,rpad('a',4000,'*'));

已建立 1 行。

SQL> commit;

提交完成。

SQL> analyze table tt compute statistics ;

表已分析。

SQL> select blocks,empty_blocks from dba_tables where table_name='TT' and owner=
'SYS';

BLOCKS EMPTY_BLOCKS
---------- ------------
1 6

SQL> insert into tt values(2,rpad('a',4000,'*'));

已建立 1 行。

SQL> commit;

提交完成。

SQL> analyze table tt compute statistics ;

表已分析。

SQL> select blocks,empty_blocks from dba_tables where table_name='TT' and owner=
'SYS';

BLOCKS EMPTY_BLOCKS
---------- ------------
2 5
--很顯然在mssm下只有block在被使用之後才被移動到hwm之下

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/19602/viewspace-1027704/,如需轉載,請註明出處,否則將追究法律責任。

相關文章