名詞解釋與約定表空間(Tablespace)為數據庫提供使用空間的邏輯結構其對應物理結構是數據文件一個表空間可以包含多個數據文件
本地管理表空間(Locally Managed Tablespace簡稱LMT)i以後出現的一種新的表空間的管理模式通過本地位圖來管理表空間的空間使用
字典管理表空間(DictionaryManaged Tablespace簡稱DMT)i以前包括以後都還可以使用的一種表空間管理模式通過數據字典管理表空間的空間使用
段(Segment)數據庫一種邏輯結構如表段索引段回滾段等段存在於表空間中並對應一定的存儲空間
區間可以簡稱區(Extent)段的存儲可以分成一個或多個區間每個區間占用一定數量的數據塊(block)在本地管理的表空間中表空間的Extent就對應段的Extent塊(Block)數據庫最小的存儲單位在本文中Block的大小約定為字節
位(Bit)本地管理表空間的空間管理單位一個位可能等於一個區間也可能多個位組成一個區間
本地管理表空間 語法在OracleI的版本中Oracle推出了一種全新的表空間管理方式本地化管理的表空間所謂本地化管理就是指Oracle不再利用數據字典表來記錄Oracle表空間裡面的區的使用狀況而是在每個表空間的數據文件的頭部加入了一個位圖區在其中記錄每個區的使用狀況每當一個區被使用或者被釋放以供重新使用時Oracle都會更新數據文件頭部的這個記錄反映這個變化
本地化管理的表空間的創建過程語法CREATE TABLESPACE 表空間名字 DATAFILE 數據文件詳細信息 [EXTENT MANAGEMENT { LOCAL {AUTOALLOCATE | UNIFORM [SIZE INTETER [K|M] ] } } ]關鍵字EXTENT MANAGEMENT LOCAL 指定這是一個本地化管理的表空間對於系統表空間只能在創建數據庫的時候指定EXTENT MANGEMENT LOCAL因為它是數據庫創建時建立的第一個表空間
在i中字典管理還是默認的管理方式當選擇了LOCAL關鍵字即表明這是一個本地管理的表空間當然還可以繼續選擇更細的管理方式是AUTOALLOCATE 還是 UNIFORM若為AUTOALLOCATE則表明讓Oracle來決定區塊的使用辦法若選擇了UNIFORM則還可以詳細指定每個區塊的大小若不加指定則為每個區使用M大小
本地管理優點 本地化管理的表空間避免了遞歸的空間管理操作而這種情況在數據字典管理的表空間是經常出現的當表空間裡的區的使用狀況發生改變時數據字典的表的信息發生改變從而同時也使用了在系統表空間裡的回滾段
本地化管理的表空間避免了在數據字典相應表裡面寫入空閒空間已使用空間的信息從而減少了數據字典表的競爭提高了空間管理的並發性 區的本地化管理自動跟蹤表空間裡的空閒塊減少了手工合並自由空間的需要
表空間裡的區的大小可以選擇由Oracle系統來決定或者由數據庫管理員指定一個統一的大小避免了字典表空間一直頭疼的碎片問題
從由數據字典來管理空閒塊改為由數據文件的頭部記錄來管理空閒塊這樣避免產生回滾信息不再使用系統表空間裡的回滾段因為由數據字典來管理的話它會把相關信息記在數據字典的表裡從而產生回滾信息
由於這種表空間的以上特性所以它支持在一個表空間裡邊進行更多的並發操作並減少了對數據字典的依賴
本地管理表空間管理機制表空間是一種為段(表索引等)提供空間的邏輯結構所以當在表空間中增加刪除段的時候數據庫就必須跟蹤這些空間的使用
如下例所示假定一個新創建的表空間包含了五個表表一……表二……表三……表四……表五……未用空間當我們刪除表四的時候就有如下結果表一……表二……表三……空閒空間段……表五……未用空間很明顯ORACLE需要有一個機制來管理表空間中各數據文件的這些分配的或未分配的空間為了跟蹤這些可以使用的空間(包括未分配使用的和可以重復使用的)對於每一個空間我們必須知道這個可用空間位於什麼數據文件這個空間的尺寸是多大如果它在用了是哪一個段占用的這個空間直到i之前所有的表空間都是采用字典管理模式為了確保能保存以上的信息ORACLE用了兩個數據字典表UET$(已使用的區間)或FET$(空閒空間)SQL> desc UET$ Name Type Nullable Default Comments
SEGFILE# NUMBER SEGBLOCK# NUMBER EXT# NUMBER TS# NUMBER FILE# NUMBER BLOCK# NUMBER LENGTH NUMBER
SQL> desc FET$ Name Type Nullable Default Comments
TS# NUMBER FILE# NUMBER BLOCK# NUMBER LENGTH NUMBER查詢該表可以看到每個使用空間或空閒空間(不一定是一個extent可以是多個extent)都在該表中對應了一行它的工作方式是當一個段被刪除的時候ORACLE就移動UET$中相應的行到FET$這個過程的發生是連續的而且可能發生等待當並發性很高的時候數據字典的爭用就來了另外有一個問題就是當表的空間很不連續或表空間有大量的碎片引起這兩個表的增大那麼也就會引起數據庫性能上的下降
本地管理表空間正是為了解決這一問題來的在表空間的空間管理上ORACLE將存儲信息保存在表空間的頭部的位圖中而不是保存在數據字典中通過這樣的方式在分配回收空間的時候表空間就可以獨立的完成操作也不用與其它對象關系
下面就讓我們進入到本地管理表空間的內部看看ORACLE是怎麼實現這一工作的
用Uniform方式的本地管理表空間 當uniform size值太小時SQL> create tablespace demo datafile /oradata/ltest/demodbf size m extent management local uniform size kORA Uniform size for auto segment space managed tablespace should have at least blocks注意 我實驗環境block為k 所以uniform size至少為k 當storage參數中的initial為空時SQL> create tablespace demo datafile /oradata/ltest/demodbf size m extent management local uniform size kTablespace created SQL> select ainitial_extent / INIT_EXTENT(K) anext_extent / NEXT_EXTENT(K) from user_tablespaces a where atablespace_name = DEMOINIT_EXTENT(K) NEXT_EXTENT(K)
SQL> create table demotab(x number) tablespace demoTable created SQL> select atable_name ainitial_extent / INIT_EXTENT(K) anext_extent / NEXT_EXTENT(K) from user_tables a where atable_name = DEMOTABTABLE_NAME INIT_EXTENT(K) NEXT_EXTENT(K)
DEMOTAB 注意 建表時沒有存儲參數initial時 初始化區與下一個區的大小都是k 與uniform size的大小一樣的
SQL> select abytes / INIT_EXTENT(K) from user_extents a where asegment_name = DEMOTAB and aextent_id = INIT_EXTENT(K)
SQL> select count(*) from user_extents where segment_name = DEMOTABCOUNT(*)
注意 在該段中 產生一個區
當initial < uniform size時SQL> create table demotab_(x number) tablespace demo storage (initial K next k)Table created SQL> select atable_name ainitial_extent / INIT_EXTENT(K) anext_extent / NEXT_EXTENT(K) from user_tables a where atable_name = DEMOTAB_TABLE_NAME INIT_EXTENT(K) NEXT_EXTENT(K)
DEMOTAB_ 注意 此時INIT_EXTENT為 不是initial參數的 SQL> select abytes / INIT_EXTENT(K) from user_extents a where asegment_name = DEMOTAB_ and aextent_id = INIT_EXTENT(K)
SQL> select count(*) from user_extents where segment_name = DEMOTAB_COUNT(*)
當initial > uniform size時SQL> create table demotab_(x number) tablespace demo storage (initial K next k)Table created SQL> select atable_name ainitial_extent / INIT_EXTENT(K) anext_extent / NEXT_EXTENT(K) from user_tables a where atable_name = DEMOTAB_TABLE_NAME INIT_EXTENT(K) NEXT_EXTENT(K)
DEMOTAB_ 注意 initial > uniform size時 初始化區的大小initial的大小
SQL> select abytes / INIT_EXTENT(K) from user_extents a where asegment_name = DEMOTAB_ and aextent_id = INIT_EXTENT(K)
SQL> select count(*) from user_extents where segment_name = DEMOTAB_COUNT(*)
注意 此時分配的區已經不是個了 是個 在這種情況下initial就有起做作用 分配區的數量為 取整(initial/uniform size) +
結論 在uniform size時 initial不管為多少時 這個段的每一個區大小都為uniform size的大小
用autoallocate方式的本地管理表空間 當storage參數中的initial為空時SQL> create tablespace demoa datafile /oradata/ltest/demoadbf size m extent management local autoallocateTablespace created SQL> select ainitial_extent / INIT_EXTENT(K) anext_extent / NEXT_EXTENT(K) from user_tablespaces a where atablespace_name = DEMOAINIT_EXTENT(K) NEXT_EXTENT(K)
SQL> create table demoatab(x number) tablespace demoaTable created SQL> select atable_name ainitial_extent / INIT_EXTENT(K) anext_extent / NEXT_EXTENT(K) from user_tables a where atable_name = DEMOATABTABLE_NAME INIT_EXTENT(K) NEXT_EXTENT(K)
DEMOATAB SQL> select count(*) from user_extents where segment_name = DEMOATABCOUNT(*)
SQL> select asegment_name abytes ablocks from user_extents a where asegment_name = DEMOATAB_SEGMENT_NA BYTES BLOCKS
DEMOATAB_ DEMOATAB_ rows selected當自動分配時發現開始第一個區分配個塊(K) 到區開始 每個區分配個塊(大小M) 我做過實驗當initial足夠大時 第一個區的大小不一定都是K 可以是M M M 甚至是M 當initial < uniform size時SQL> create table demoatab_(x number) tablespace demoa storage (initial K next k)Table created SQL> select atable_name ainitial_extent / INIT_EXTENT(K) anext_extent / NEXT_EXTENT(K) from user_tables a where atable_name = DEMOATAB_TABLE_NAME INIT_EXTENT(K) NEXT_EXTENT(K)
DEMOATAB_ SQL> select abytes / INIT_EXTENT(K) from user_extents a where asegment_name = DEMOATAB_ and aextent_id = INIT_EXTENT(K)
SQL> select count(*) from user_extents where segment_name = DEMOATAB_COUNT(*)
當initial > uniform size時SQL> create table demoatab_(x number) tablespace demoa storage (initial K next k)Table created SQL> select atable_name ainitial_extent / INIT_EXTENT(K) anext_extent / NEXT_EXTENT(K) from user_tables a where atable_name = DEMOATAB_TABLE_NAME INIT_EXTENT(K) NEXT_EXTENT(K)
DEMOATAB_ SQL> select abytes / INIT_EXTENT(K) from user_extents a where asegment_name = DEMOATAB_ and aextent_id = INIT_EXTENT(K)
SQL> select count(*) from user_extents where segment_name = DEMOATAB_COUNT(*)
結論 ORACLE通過強制性的手段使本地管理表空間中的所有Extent是同樣大小的 盡管可能自定義了不同的存儲參數 在自動分配的本地管理的表空間中 區間尺寸可能由以下尺寸組成K M M M 甚至是M 但是不管多大 都有一個通用尺寸k 所以K就是該表空間的位大小
檢查uet$與fet$是否有數據SQL> select file# name from v$datafileFILE# NAME—— /oradata/LTEST/datafile/o_mf_system_qw_dbf /oradata/LTEST/datafile/o_mf_undotbs_qct_dbf /oradata/LTEST/datafile/o_mf_sysaux_q_dbf /oradata/LTEST/datafile/o_mf_users_qdo_dbf /oradata/LTEST/datafile/o_mf_example_qjt_dbf /oradata/LTEST/datafile/o_mf_bigtbs_ctvwx_dbf /oradata/ltest/demodbf /oradata/ltest/demodbf /oradata/ltest/demoadbf rows selected可以檢查uet$與fet$ SQL> select count(*) from uet$ where file# = COUNT(*)
SQL> select count(*) from fet$ where file# = COUNT(*)
采用本地管理的表空間 這兩張視圖中沒有數據 下面就通過Dump塊的信息 來進一步分析本地管理表空間的特點
Dump數據文件中位圖信息(第個塊到第個塊)
dump第三個塊數據文件的前兩個塊是文件頭 所以dump第個塊 從第個塊到第個塊是該數據文件的數據文件的位圖區 如果db_block_size為 那麼占用的空間為K 文也用另一種不是很嚴謹的方法驗證了占用K大小的問題
SQL> alter system dump datafile block System altered Dump出來的信息如下Start dump data blocks tsn file# minblk maxblk buffer tsn rdba x (/)
scn xeed seq x flg x tail xeede frmt x chkval xe type xe=KTFB Bitmapped File Space Bitmap Hex dump of block st= typ_found= Dump of memory from xEFC to xFC EFC AE EED [……] EFC E C [C……] EFC FF [……] EFC FF [……] EFC [……] Repeat times FBF EEDE [……] File Space Bitmap BlockBitMap Control 這句話說明該塊還是位圖區(塊都這樣子 可dump每個塊出來驗證)
RelFno BeginBlock Flag First Free FF (共行)
……
End dump data blocks tsn file# minblk maxblk
共行 每行個字節 每個字節位 共有位數 * * = 前面兩節的內容是 FF => => 個位為 與下面通過user_extents算出來的一樣 還有空閒區共有 = (注意 位大小為的個數與extent個數相等 只是一個巧合 因為位圖管理中位大小為對應的是個block的使用情況 當一個區的分配大小不為個block時 比如個block時 兩者就不會相等了)
可看表空間DEMO中已經用了幾個區
SQL> select count(*) from user_extents a where atablespace_name = DEMOCOUNT(*)
先擴展後 再dump第三個塊SQL> alter table demotab allocate extentTable altered SQL> alter system dump datafile block System altered
Dump出來的信息如下Start dump data blocks tsn file# minblk maxblk buffer tsn rdba x (/)
scn xfcf seq x flg x tail xfcfe frmt x chkval x type xe=KTFB Bitmapped File Space Bitmap Hex dump of block st= typ_found= Dump of memory from xEFC to xFC EFC AE FCF [……O……] EFC C [……] EFC FF [……] EFC FF [……] EFC [……] Repeat times FBF FCFE [……O] File Space Bitmap BlockBitMap ControlRelFno BeginBlock Flag First Free FF ……
End dump data blocks tsn file# minblk maxblk
前面兩節的內容是 FF => => 個位為說明通過語句alter table demotab allocate extent 又增加了一個區的分配
Dump數據文件中數據信息(比如第個塊)
查看dba_extents視圖 也可以發現表DEMOTAB從第個塊開始分配第一個區
SQL> select asegment_name afile_id ablock_id aextent_id from dba_extents a where asegment_name = DEMOTABSEGMENT_NAME FILE_ID BLOCK_ID EXTENT_ID
DEMOTAB DEMOTAB
Dump第個塊 這個塊相當表頭的信息
SQL> alter system dump datafile block System altered Dump出來的信息如下Start dump data blocks tsn file# minblk maxblk buffer tsn rdba x (/)
scn xfcf seq x flg x tail xfcf frmt x chkval xaaf type x=FIRST LEVEL BITMAP BLOCK Hex dump of block st= typ_found= Dump of memory from xEFC to xFC EFC A FCF [ ……O……] EFC AAF [Z……] EFC [……] Repeat times EFC [……] EFC FFFFFFFF D [……] EFC [……] EFC [……] EFC C […………] EFC A [……] EFCA C [……] EFCB [……] EFCC CED [m……] EFCD [……] EFCE [……] EFCF [……] Repeat times EFD [……] EFD [……] Repeat times FBF FCF […… O] Dump of First Level Bitmap Block
nbits nranges parent dba xa 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 xc Inc # Objd HWM Flag HWM Set Highwater xc ext# blk# ext size #blocks in seg hdrs freelists #blocks below mapblk x offset
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
From:http://tw.wingwit.com/Article/program/Oracle/201311/16723.html