在
以前
表的剩余空間的管理與分配都是由鏈接列表freelist來完成的
因為freelist存在串行的問題因此容易引起往往容易引起段頭的爭用與空間的浪費(其實這一點並不明顯)
最主要的還是因為需要DBA 花費大量的精力去管理這些爭用並監控表的空間利用
自動段空間管理(ASSM)
它首次出現在Oracle
裡
有了ASSM
鏈接列表freelist被位圖所取代
它是一個二進制的數組
能夠迅速有效地管理存儲擴展和剩余區塊(free block)
因此能夠改善分段存儲本質
ASSM表空間上創建的段還有另外一個稱呼叫Bitmap Managed Segments(BMB 段)
讓我們看看位圖freelist是如何實現的
我會從使用區段空間管理自動參數創建tablespace開始
create tablespace demo
datafile
/ora
/oem/demo
dbf
size
m
EXTENT MANAGEMENT LOCAL
Turn on LMT
SEGMENT SPACE MANAGEMENT AUTO
Turn on ASSM;
一旦你定義好了tablespace
那麼表和索引就能夠使用各種方法很容易地被移動到新的tablespace裡
帶有ASSM的本地管理tablespace會略掉任何為PCTUSED
NEXT和FREELISTS所指定的值
當表格或者索引被分配到這個tablespace以後
用於獨立對象的PCTUSED的值會被忽略
而Oracle
i會使用位圖數組來自動地管理tablespace裡表格和索引的freelist
對於在LMT的tablespace內部創建的表格和索引而言
這個NEXT擴展子句是過時的
因為由本地管理的tablespace會管理它們
但是
INITIAL參數仍然是需要的
因為Oracle不可能提前知道初始表格加載的大小
對於ASSM而言
INITIAL最小的值是三個塊
新的管理機制用位圖來跟蹤或管理每個分配到對象的塊
每個塊有多少剩余空間根據位圖的狀態來確定
如>
%
%
%
%
%和<
%
也就是說位圖其實采用了四個狀態位來代替以前的pctused
什麼時候該利用該數據塊則由設定的pctfree來確定
使用ASSM的一個巨大優勢是
位圖freelist肯定能夠減輕緩沖區忙等待(buffer busy wait)的負擔
這個問題在Oracle
i以前的版本裡曾是一個嚴重的問題
在沒有多個freelist的時候
每個Oracle表格和索引在表格的頭部都曾有一個數據塊
用來管理對象所使用的剩余區塊
並為任何SQL插入聲明所創建的新數據行提供數據塊
當數據緩沖內的數據塊由於被另一個DML事務處理鎖定而無法使用的時候
緩沖區忙等待就會發生
當你需要將多個任務插入到同一個表格裡的時候
這些任務就被強制等待
而同時Oracle會在同時分派剩余的區塊
一次一個
有了ASSM之後
Oracle宣稱顯著地提高了DML並發操作的性能
因為(同一個)位圖的不同部分可以被同時使用
這樣就消除了尋找剩余空間的串行化
根據Oracle的測試結果
使用位圖freelist會消除所有分段頭部(對資源)的爭奪
還能獲得超快的並發插入操作
盡管ASSM顯示出了令人激動的特性並能夠簡化Oracle DBA的工作
但是Oracle
i的位圖分段管理還是有一些局限性的
· 一旦DBA被分配之後
它就無法控制tablespace內部的獨立表格和索引的存儲行為
· 大型對象不能夠使用ASSM
而且必須為包含有LOB數據類型的表格創建分離的tablespace
· 你不能夠使用ASSM創建臨時的tablespace
這是由排序時臨時分段的短暫特性所決定的
· 只有本地管理的tablespace才能夠使用位圖分段管理
· 使用超高容量的DML(例如INSERT
UPDATE和DELETE等)的時候可能會出現性能上的問題
我們先創建一個本地管理的表空間
采用段自動管理方式
create tablespace demo
datafile
/ora
/oem/demo
dbf
size
m
EXTENT MANAGEMENT LOCAL
一定是本地管理
SEGMENT SPACE MANAGEMENT AUTO;
ASSM管理的標志
創建同樣一個表
SQL> create table demotab ( x number ) tablespace demo
storage (initial
K);
Table created
我們指定初試區間大小是
K
SQL> select t
table_name
t
initial_extent
t
next_extent
t
pct_free
t
pct_used from user_tables t where t
table_name =
DEMOTAB
;
TABLE_NAME INITIAL_EXTENT NEXT_EXTENT PCT_FREE PCT_USED
DEMOTAB
可以看到
NEXT_EXTENT與PCT_USED都為空
執行該過程
檢查表的初始狀態
SQL> exec show_space(
demotab
);
Total Blocks
Total Bytes
Unused Blocks
Unused Bytes
Last Used Ext FileId
Last Used Ext BlockId
Last Used Block
從這裡我們能看到一些該表的特性
其中最引人注意的就是表頭了
占用了三個塊的大小(
)
另外一個注意的地方就是該表從第
個塊開始
但是實際上這裡是錯誤的
應當是從第
個塊開始
文件頭占用了
K的空間等於
個塊
我們從dba_extent中也能看到這樣的信息
實際上是從第
個塊開始的
SQL> select t
segment_name
t
extent_id
t
block_id from dba_extents t where t
segment_name =
DEMOTAB
;
SEGMENT_NAME EXTENT_ID BLOCK_ID
DEMOTAB
DEMOTAB
……
從這裡可以看到
第一個區間的開始塊是
我直接開始分析第
個塊(段頭)
SQL> alter system dump datafile
block
;
System altered
SQL> alter system dump datafile
block
;
System altered
SQL> alter system dump datafile
block
;
System altered
Start dump data blocks tsn:
file#:
minblk
maxblk
buffer tsn:
rdba:
x
(
/
)
scn:
x
a
c seq:
x
flg:
x
tail:
x
a
c
frmt:
x
chkval:
x
a
type:
x
=FIRST LEVEL BITMAP BLOCK
Dump of First Level Bitmap Block
nbits :
nranges:
parent dba:
x
a poffset:
unformatted:
total:
first useful block:
owning instance :
instance ownership changed at
Last successful Search
Freeness Status: nf
nf
nf
nf
Extent Map Block Offset:
First free datablock :
Bitmap block lock opcode
Locker xid: :
x
Highwater::
x
c ext#:
blk#:
ext size:
#blocks in seg
hdr
s freelists:
#blocks below:
mapblk
x
offset:
HWM Flag: HWM Set
DBA Ranges :
x
Length:
Offset:
x
Length:
Offset:
:Metadata
:Metadata
:Metadata
:unformatted
:unformatted
:unformatted
:unformatted
:unformatted
:unformatted
:unformatted
:unformatted
:unformatted
:unformatted
:unformatted
:unformatted
:unformatted
End dump data blocks tsn:
file#:
minblk
maxblk
Start dump data blocks tsn:
file#:
minblk
maxblk
buffer tsn:
rdba:
x
a (
/
)
scn:
x
a
seq:
x
flg:
x
tail:
x
a
frmt:
x
chkval:
x
type:
x
=SECOND LEVEL BITMAP BLOCK
Dump of Second Level Bitmap Block
number:
nfree:
ffree:
pdba:
x
b
opcode:
xid:
L
Ranges :
x
Free:
Inst:
x
Free:
Inst:
x
Free:
Inst:
x
Free:
Inst:
x
Free:
Inst:
x
Free:
Inst:
x
Free:
Inst:
x
Free:
Inst:
End dump data blocks tsn:
file#:
minblk
maxblk
Start dump data blocks tsn:
file#:
minblk
maxblk
buffer tsn:
rdba:
x
b (
/
)
scn:
x
a
d seq:
x
flg:
x
tail:
x
a
d
frmt:
x
chkval:
x
type:
x
=PAGETABLE SEGME
From:http://tw.wingwit.com/Article/program/Oracle/201311/16726.html