數據塊概述Oracle對數據庫數據文件(datafile)中的存儲空間進行管理的單位是數據塊(data block)數據塊是數據庫中最小的(邏輯)數據單位與數據塊對應的所有數據在操作系統級的最小物理存儲單位是字節(byte)每種操作系統都有一個被稱為塊容量(block size)的參數Oracle每次獲取數據時總是訪問整個數(Oracle)數據塊而不是按照操作系統塊的容量訪問數據
數據庫中標准的數據塊(data block)容量是由初始化參數 DB_BLOCK_SIZE 指定的除此之外用戶還可以指定五個非標准的數據塊容量(nonstandard block size)數據塊容量應該設為操作系統塊容量的整數倍(同時小於數據塊容量的最大限制)以便減少不必要的I/O操作Oracle數據塊是Oracle可以使用和分配的最小存儲單位
另見針對特定操作系統的Oracle文檔中包含更多有關數據塊容量(data block size)的信息多種數據塊容量(Multiple Block Sizes)
數據塊結構在Oracle中不論數據塊中存儲的是表(table)索引(index)或簇表(clustered data)其內部結構都是類似的圖 說明了數據塊的結構
本圖顯示了數據塊的各個組成部分包括數據塊頭(包括標准內容和可變內容)(common and variable header)表目錄區(table directory)行目錄區(row directory)可用空間區(free space)行數據區(row data)以下各節將分別講解各個組成部分圖中兩個箭頭表示一個數據塊中的可用空間區的容量是可變的
數據塊頭(包括標准內容和可變內容)
數據塊頭(header)中包含了此數據塊的概要信息例如塊地址(block address)及此數據塊所屬的段(segment)的類型(例如表或索引)
表目錄區如果一個數據表在此數據塊中儲存了數據行那麼數據表的信息將被記錄在數據塊的表目錄區(table directory)中
行目錄區
此區域包含數據塊中存儲的數據行的信息(每個數據行片斷(row piece) 在行數據區(row data area)中的地址)[一個數據塊中可能保存一個完整的數據行也可能只保存數據行的一部分 所以文中使用row piece]
當一個數據塊(data block)的行目錄區(row directory)空間被使用後即使數據行被刪除(delete)行目錄區空間也不會被回收舉例來說當一個曾經包含條記錄的數據塊被清空後其塊頭(header)的行目錄區仍然占用字節(byte)的空間只有在數據塊中插入(insert)新數據時行目錄區空間才會被 重新利用
管理開銷數據塊頭(data block header)表目錄區(table directory)行目錄區(row directory)被統稱為管理開銷(overhead)其中 有些開銷的容量是固定的而有些開銷的總容量是可變的數據塊中固定及可變管理開銷的容量平均在到字節(byte)之間
行數據數據塊(data block)中行數據區(row data)包含了表或索引的實際數據一個數據行可以跨多個數據塊這就出現了行鏈接(Row Chaining)及行遷移(Row Migrating)
可用空間區在插入新數據行或在更新數據行需要更多空間時(例如原來某行最後一個字段為空(trailing null)現在要更新為非空值)將 使用可用空間區(free space)中的空間
如果一個數據塊(data block)屬於表或簇表的數據段(data segment)或屬於索引的索引段(index segment)那麼在其可用空間區中還可能會存儲事務條目(transaction entry)如果一個數據塊中的數據行(row)正在由 INSERTUPDATEDELETE及 SELECT……FOR UPDATE 語句訪問此數據塊中就需要保存事務條目事務條目所需的存儲空間依據操作系統而定在常見的操作系統中事務條目大約需要有兩種SQL語句可以增加數據塊中的可用空間分別是 DELETE 語句和將現有數據值更新為占用容量更小值的 UPDATE 語句在以下兩種條件下上述兩中操作釋放的空間可以被後續的 INSERT 語句使用
如果 INSERT 語句與上述兩種操作在同一事務(transaction)中且位於釋放空間的語句之後那麼 INSERT 語句可以使用被釋放的空間
如果 INSERT 語句與釋放空間的語句在不同的事務中(比如兩者是由不同的用戶提交的)那麼只有在釋放空間的語句提交後且插入數據必需使用此數據塊時INSERT 語句才會使用被釋放的空間
數據塊(data block)中被釋放出的空間未必與可用空間區(free space)相連續Oracle在滿足以下條件時才會將釋放的空間合並到可用空間區()INSERT 或 UPDATE 語句選中了一個有足夠可用空間容納新數據的數據塊()但是此塊中的可用空間不連續數據無法被寫入到數據塊中連續的空間裡Oracle只在 滿足上述條件時才對數據塊中的可用空間進行合並這樣做是為了避免過於頻繁的空間合並工作影響數據庫性能
占用 行鏈接(Row Chaining)及行遷移(Row Migrating)
有兩種情況會導致表中某行數據過大一個數據塊(data block)無法容納第一種情況當一行數據被插入時一個數據塊就無法容納在這種情況下Oracle將這行數據存儲在段內的一個數據塊鏈(chain)中在插入數據量大的行時常會發生行鏈接(row chaining)例如一個包含數據類型為 LONG 或 LONG RAW 列的數據行此時行鏈接不可避免
第二種情況原本存儲在一個數據塊(data block)內的數據行因為更新操作導致長度增長而所在數據塊的可用空間也不能容納增長後的數據行在這種情況下Oracle將此行數據遷移(migrate)到新的數據塊中Oracle在被遷移數據行原來所在位置保存一個指向新數據塊的指針被遷移數據行的 rowid 保持不變
當數據行發生鏈接(chain)或遷移(migrate)時對其訪問將會造成 I/O 性能降低因為Oracle為獲取這些數據行的數據時必須訪問更多的數據塊(data block)
另見 數據行結構與長度了解關於數據行結構的信息 數據行的 Rowid了解關於 rowid 的信息 物理 Rowid了解關於 rowid 的信息Oracle Database Performance Tuning Guide 了解如何減少行鏈接與行遷移以便提高系統I/O性能字節(byte)
PCTFREEPCTUSED及行鏈接(Row Chaining)
在手動管理的表空間(manually managed tablespaces)中用戶可以使用 PCTFREE 和 PCTUSED 這兩個存儲管理參數來控制對某段(segment)進行插入和更新操作時如何利用屬於此段的數據塊(data block)中的可用空間用戶也可以在創建或修改索引時為其設定 PCTFREE 參數(索引存儲在索引段(index segment)中)
提示
本節的內容並不適用於 LOB 數據類型(BLOBCLOBNCLOB及 BFILE) 這些類型的數據存儲時不使用 PCTFREE 參數及可用塊列表(free list)
PCTFREE 參數PCTFREE 參數用來設置一個數據塊(data block)中至少需要保留(reserve)多少可用空間(百分比值)為數據塊中已有數據更新時可能發生的數據量增長做准備例如當用戶用 CREATE TABLE 語句創建表時指定了以下參數PCTFREE 這個參數設定了此表對應的數據段(data segment)中的每個數據塊(data block)至少保留%的可用空間以備塊中已有數據更新時使用只要數據塊中行數據區與數據塊頭的容量之和不超過數據塊總容量的%用戶就可以向其中插入新數據數據行被放入行數據區(row data area)相關信息被寫入數據塊頭(overhead area)圖 說明了 PCTFREE 的作用
PCTUSED 參數PCTUSED 參數用於決定一個數據塊(data block)是否可被用於插入新數據她的依據是數據區(row data)與數據塊頭(overhead)的容量之和占數據塊全部容量的最大百分比當一個數據塊中的可用空間比例小於 PCTFREE 參數的規定時Oracle就認為此數據塊無法被用於插入新數據直到數據塊中的占用容量比例小於 PCTUSED 參數的限定在占用容量比例大於 PCTUSED 參數的限定之前Oracle只在更新數據塊內已有數據時才會使用此數據塊的可用空間例如當用戶用 CREATE TABLE 語句創建表時指定了以下參數PCTUSED 在例子中當此表的某數據塊占用容量比例高於%時Oracle不會將此數據塊用於插入新數據行(假設此數據塊的可用空間曾經低於 PCTFREE 的限定)圖 說明了 PCTUSED 的作用
PCTFREE 和 PCTUSED 如何協同發揮作用PCTFREE 和 PCTUSED 共同作用可以優化數據塊(data block)的空間使用
PCTFREE 和 PCTUSED 如何共同作用以管理數據塊(data block)可用空間的使用
在第一步中數據塊占用空間比例小於%時才能插入新數據因為 PCTFREE 參數限定必須保留%的可用空間用於塊內已有數據的更新
在第二步中對數據塊中已有數據的更新操作可以使用數據塊中的保留空間只有當數據塊內的占用空間比例低於%時才能向其中插入新數據
在第三步中當數據塊內的占用空間比例低於%時此數據塊再次可以被用於插入新數據
在第四步中數據塊占用空間比例小於%時才能插入新數據因為 PCTFREE 參數限定必須保留%的可用空間用於塊內已有數據的更新此過程如此往復循環
在新分配的數據塊中(data block)可用於插入(insert)數據的空間等於數據塊總容量減去數據塊頭(block overhead)再減去預留可用空間(PCTFREE)而更新(update)數據塊內已有數據可使用數據塊中的所有可用空間因此更新操作能夠使數據塊內的可用空間低於的 PCTFREE 限制因為這些空間是專為更新操作而預留的
在每個數據段(data segment)與索引段(index segment)中Oracle管理著一個或多個可用塊列表(free list)——其中列出了所有屬於此段的數據擴展(extent)且可用空間比例大於 PCTFREE 限定的數據塊這些塊可以被插入(insert)操作使用當用戶提交了 INSERT 語句後Oracle從可用塊列表中選擇第一個有效的數據塊使用如果此數據塊的可用空間不夠容納 INSERT 語句提交的數據且此塊的占用容量已經超過PCTUSED 的限定Oracle就將其從可用塊列表中移出一個段可以同時使用多個可用塊列表以減少對一個表進行並發插入(concurrent insert)時產生的競爭
當用戶提交了 DELETE 或 UPDATE 語句後Oracle處理語句並檢查相關數據塊中的占用空間比例是否小於 PCTUSED 的規定如果滿足那麼這個數據塊就被放入當前事務(transaction)正在使用的可用塊列表(free list)的頭部如果當前事務還需要寫入數據此塊將被首先使用當事務提交後此數據塊中的可用空間還可被其他事務使用
數據擴展概述數據擴展(extent)是由一組連續的數據塊(data block)構成的數據庫邏輯存儲分配單位而段(segment)則是由一個或多個數據擴展構成當一個段中已有空間已經用完Oracle為這個段分配新的數據擴展
數據擴展何時被分配當用戶創建數據表時Oracle為此表的數據段(data segment)分配一個包含若干數據塊(data block)的初始數據擴展(initial extent)雖然此時數據表中還沒有數據但是在此初始數據擴展中的數據塊已經為插入新數據做好了准備
如果一個段(segment)的初始數據擴展(initial extent)中的數據塊(data block)都已裝滿且有新數據插入需要空間時Oracle自動為這個段分配一個增量數據擴展(incremental extent)增量數據擴展是一個段中繼已有數據擴展之後分配的後續數據擴展她的容量大於或等於之前的數據擴展
為了管理的需要每個段(segment)的段頭(header block)中包含一個記錄此段所有數據擴展(extent)的目錄
From:http://tw.wingwit.com/Article/program/Oracle/201311/16534.html