當前位置:成語大全網 - 新華字典 - 詳解Oracle本地管理表空間

詳解Oracle本地管理表空間

  名詞解釋與約定表空間(Tablespace) 為數據庫提供使用空間的邏輯結構 其對應物理結構是數據文件 壹個表空間可以包含多個數據文件

 本地管理表空間(Locally Managed Tablespace簡稱LMT) i以後出現的壹種新的表空間的管理模式 通過本地位圖來管理表空間的空間使用

 字典管理表空間(Dictionary Managed Tablespace簡稱DMT) i以前包括以後都還可以使用的壹種表空間管理模式 通過數據字典管理表空間的空間使用

 段(Segment) 數據庫壹種邏輯結構 如表段 索引段 回滾段等 段存在於表空間中 並對應壹定的存儲空間

 區間 可以簡稱區(Extent) 段的存儲可以分成壹個或多個區間 每個區間占用壹定數量的數據塊(block) 在本地管理的表空間中 表空間的Extent就對應段的Extent 塊(Block) 數據庫最小的存儲單位 在本文中Block的大小約定為 字節

 位(Bit) 本地管理表空間的空間管理單位 壹個位可能等於壹個區間 也可能多個位組成壹個區間

  本地管理表空間 語法在Oracle I的版本中 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/demo dbf size m extent management local uniform size k ORA 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/demo dbf size m extent management local uniform size k Tablespace created SQL> select a initial_extent / INIT_EXTENT(K) ? a next_extent / NEXT_EXTENT(K) from user_tablespaces a where a tablespace_name = DEMO INIT_EXTENT(K) NEXT_EXTENT(K)

 

  SQL> create table demotab (x number) tablespace demo Table created SQL> select a table_name ? a initial_extent / INIT_EXTENT(K) ? a next_extent / NEXT_EXTENT(K) from user_tables a where a table_name = DEMOTAB TABLE_NAME INIT_EXTENT(K) NEXT_EXTENT(K)

 

 DEMOTAB ? 註意 建表時沒有存儲參數initial時 初始化區與下壹個區的大小都是 k 與uniform size的大小壹樣的

 SQL> select a bytes / INIT_EXTENT(K) from user_extents a where a segment_name = DEMOTAB and a extent_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 a table_name ? a initial_extent / INIT_EXTENT(K) ? a next_extent / NEXT_EXTENT(K) from user_tables a where a table_name = DEMOTAB _ TABLE_NAME INIT_EXTENT(K) NEXT_EXTENT(K)

 

 DEMOTAB _ ? 註意 此時INIT_EXTENT為 不是initial參數的 SQL> select a bytes / INIT_EXTENT(K) from user_extents a where a segment_name = DEMOTAB _ and a extent_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 a table_name ? a initial_extent / INIT_EXTENT(K) ? a next_extent / NEXT_EXTENT(K) from user_tables a where a table_name = DEMOTAB _ TABLE_NAME INIT_EXTENT(K) NEXT_EXTENT(K)

 

 DEMOTAB _ 註意 initial > uniform size時 初始化區的大小initial的大小

 SQL> select a bytes / INIT_EXTENT(K) from user_extents a where a segment_name = DEMOTAB _ and a extent_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/demoa dbf size m extent management local autoallocate Tablespace created SQL> select a initial_extent / INIT_EXTENT(K) ? a next_extent / NEXT_EXTENT(K) from user_tablespaces a where a tablespace_name = DEMOA INIT_EXTENT(K) NEXT_EXTENT(K)

 

  SQL> create table demoatab(x number) tablespace demoa Table created SQL> select a table_name ? a initial_extent / INIT_EXTENT(K) ? a next_extent / NEXT_EXTENT(K) from user_tables a where a table_name = DEMOATAB TABLE_NAME INIT_EXTENT(K) NEXT_EXTENT(K)

 

 DEMOATAB SQL> select count(*) from user_extents where segment_name = DEMOATAB COUNT(*)

 

 

 SQL> select a segment_name a bytes a blocks from user_extents a where a segment_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 a table_name ? a initial_extent / INIT_EXTENT(K) ? a next_extent / NEXT_EXTENT(K) from user_tables a where a table_name = DEMOATAB_ TABLE_NAME INIT_EXTENT(K) NEXT_EXTENT(K)

 

 DEMOATAB_ ? SQL> select a bytes / INIT_EXTENT(K) from user_extents a where a segment_name = DEMOATAB_ and a extent_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 a table_name ? a initial_extent / INIT_EXTENT(K) ? a next_extent / NEXT_EXTENT(K) from user_tables a where a table_name = DEMOATAB_ TABLE_NAME? INIT_EXTENT(K) NEXT_EXTENT(K)

 

 DEMOATAB_ SQL> select a bytes / INIT_EXTENT(K) from user_extents a where a segment_name = DEMOATAB_ and a extent_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$datafile FILE# NAME—— /oradata/LTEST/datafile/o _mf_system_ q w_ dbf /oradata/LTEST/datafile/o _mf_undotbs _ q ct_ dbf /oradata/LTEST/datafile/o _mf_sysaux_ q _ dbf /oradata/LTEST/datafile/o _mf_users_ q do_ dbf /oradata/LTEST/datafile/o _mf_example_ q jt _ dbf /oradata/LTEST/datafile/o _mf_bigtbs_ ct vw x_ dbf /oradata/ltest/demo dbf /oradata/ltest/demo dbf /oradata/ltest/demoa dbf 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 x ee d seq x flg x tail xee d e frmt x cval x e type x e=KTFB Bitmapped File Space Bitmap Hex dump of block st= typ_found= Dump of memory from x EFC to x F C EFC A E EE D ? [……] EFC E C ? [ C……] EFC F F ? [……] EFC FF ? [……] EFC ? [……] Repeat times F BF EE D E ? [……] File Space Bitmap Block BitMap Control ? 這句話說明該塊還是位圖區( 塊都這樣子 可dump每個塊出來驗證)

 RelFno BeginBlock Flag First Free F F (*** 行)

  ……

  End dump data blocks tsn file# minblk maxblk

 *** 行 每行 個字節 每個字節 位 ***有位數 * * = 前面兩節的內容是 F F => => 個位為 與下面通過user_extents算出來的壹樣 還有空閑區***有 = (註意 位大小為 的個數與extent個數相等 只是壹個巧合 因為位圖管理中位大小為 對應的是 個block的使用情況 當壹個區的分配大小不為 個block時 比如 個block時 兩者就不會相等了 )

 可看表空間DEMO 中已經用了幾個區

 SQL> select count(*) from user_extents a where a tablespace_name = DEMO COUNT(*)

 

  先擴展後 再dump第三個塊SQL> alter table demotab allocate extent Table altered SQL> alter system dump datafile block System altered

 Dump出來的信息如下 Start dump data blocks tsn file# minblk maxblk buffer tsn rdba x ( / )

 scn x fc f seq x flg x tail xfc f e frmt x cval x type x e=KTFB Bitmapped File Space Bitmap Hex dump of block st= typ_found= Dump of memory from x EFC to x F C EFC A E FC F ? [……O……] EFC C ? [……] EFC F F ? [……] EFC FF ? [……] EFC ? [……] Repeat times F BF FC F E ? [……O ] File Space Bitmap Block BitMap Control RelFno BeginBlock Flag First Free F F ……

  End dump data blocks tsn file# minblk maxblk

 前面兩節的內容是 F F => => 個位為 說明通過語句 alter table demotab allocate extent 又增加了壹個區的分配

  Dump數據文件中數據信息(比如第 個塊)

 查看dba_extents視圖 也可以發現表DEMOTAB 從第 個塊開始分配第壹個區

 SQL> select a segment_name a file_id a block_id a extent_id from dba_extents a where a segment_name = DEMOTAB SEGMENT_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 x fc f seq x flg x tail xfc f frmt x cval x aaf type x =FIRST LEVEL BITMAP BLOCK Hex dump of block st= typ_found= Dump of memory from x EFC to x F C EFC A FC F ? [ ……O……] EFC AAF ? [ Z……] EFC ? [……] Repeat times EFC ? [……] EFC FFFFFFFF D ? [……] EFC ? [……] EFC ? [……] EFC C ? […… ……] EFC A ? [……] EFCA C ? [……] EFCB ? [……] EFCC CE D ? [m……] EFCD ? [……] EFCE ? [……] EFCF ? [……] Repeat times EFD ? [……] EFD ? [……] Repeat times F BF FC F ? […… O ] 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 c Inc # Objd HWM Flag HWM Set Highwater ? x c? ext# ? blk# ? ext size #blocks in seg hdr s 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

 

lishixinzhi/Article/program/Oracle/201311/16723