資料區塊概述
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)
2.2.1 資料區塊結構
在Oracle中,不論資料區塊中儲存的是表(table)、索引(index)或簇表(clustered data),其內部結構都是類似的。圖2-2 說明了資料區塊的結構。
圖2-2 資料區塊結構
本圖顯示了資料區塊的各個組成部分,包括:資料區塊頭(包括標準內容和可變內容)(common and variable header),表目錄區(table directory),行目錄區(row directory),可用空間區(free space),行資料區(row data)。以下各節將分別講解各個組成部分。圖中兩個箭頭表示一個資料區塊中的可用空間區的容量是可變的。
2.2.1.1 資料區塊頭(包括標準內容和可變內容)
資料區塊頭(header)中包含了此資料區塊的概要資訊,例如塊地址(block address)及此資料區塊所屬的段(segment)的類型(例如,表或索引)。
2.2.1.2 表目錄區
如果一個資料表在此資料區塊中儲存了資料行,那麼資料表的資訊將被記錄在資料區塊的表目錄區(table directory)中。
2.2.1.3 行目錄區
此地區包含資料區塊中儲存的資料行的資訊(每個資料行片斷(row piece) 在行資料區(row data area)中的地址)。[一個資料區塊中可能儲存一個完整的資料行,也可能只儲存資料行的一部分 ,所以文中使用row piece]
當一個資料區塊(data block)的行目錄區(row directory)空間被使用後,即使資料行被刪除(delete),行目錄區空間也不會被回收。舉例來說,當一個曾經包含50條記錄的資料區塊被清空後,其塊頭(header)的行目錄區仍然佔用100位元組(byte)的空間。只有在資料區塊中插入(insert)新資料時,行目錄區空間才會被 重新利用。
2.2.1.4 管理開銷
資料區塊頭(data block header),表目錄區(table directory),行目錄區(row directory)被統稱為管理開銷(overhead)。其中 有些開銷的容量是固定的;而有些開銷的總容量是可變的。資料區塊中固定及可變管理開銷的容量平均在84到107位元組(byte)之間。
2.2.1.5 行資料
資料區塊(data block)中行資料區(row data)包含了表或索引的實際資料。一個資料行可以跨多個資料區塊。這就出現了“行連結(Row Chaining)及行遷移(Row Migrating)
2.2.1.6 可用空間區
在插入新資料行,或在更新資料行需要更多空間時(例如,原來某行最後一個欄位為空白(trailing null),現在要更新為非空值),將 使用可用空間區(free space)中的空間。
如果一個資料區塊(data block)屬於表或簇表的資料區段(data segment),或屬於索引的索引段(index segment),那麼在其可用空間區中還可能會儲存事務條目(transaction entry)。如果一個資料區塊中的資料行(row)正在由 INSERT,UPDATE,DELETE,及 SELECT...FOR UPDATE 語句訪問,此資料區塊中就需要儲存事務條目。事務條目所需的儲存空間依據作業系統而定。在常見的作業系統中事務條目大約需要有兩種SQL語句可以增加資料區塊中的可用空間:分別是
DELETE 語句,和將現有資料值更新為佔用容量更小值的 UPDATE 語句。在以下兩種條件下,上述兩中操作釋放的空間可以被後續的 INSERT 語句使用:
如果 INSERT 語句與上述兩種操作在同一事務(transaction)中,且位於釋放空間的語句之後,那麼 INSERT 語句可以使用被釋放的空間。
如果 INSERT 語句與釋放空間的語句在不同的事務中(比如兩者是由不同的使用者提交的),那麼只有在釋放空間的語句提交後,且插入資料必需使用此資料區塊時,INSERT 語句才會使用被釋放的空間。
資料區塊(data block)中被釋放出的空間未必與可用空間區(free space)相連續。Oracle在滿足以下條件時才會將釋放的空間合并到可用空間區:(1)INSERT 或 UPDATE 語句選中了一個有足夠可用空間容納新資料的資料區塊,(2)但是此塊中的可用空間不連續,資料無法被寫入到資料區塊中連續的空間裡。Oracle只在 滿足上述條件時才對資料區塊中的可用空間進行合并,這樣做是為了避免過於頻繁的空間合并工作影響資料庫效能。
佔用232.2.2.2 行連結(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)。
另見:
1. “資料行結構與長度”瞭解關於資料行結構的資訊
2. “資料行的 Rowid”瞭解關於 rowid 的資訊
3. “物理 Rowid”瞭解關於 rowid 的資訊
Oracle Database Performance Tuning Guide 瞭解如何減少行連結與行遷移,以便提高系統I/O效能位元組(byte)。
2.2.3 PCTFREE,PCTUSED,及行連結(Row Chaining)
在手動管理的資料表空間(manually managed tablespaces)中,使用者可以使用 PCTFREE 和 PCTUSED 這兩個儲存管理參數來控制對某段(segment)進行插入和更新操作時,如何利用屬於此段的資料區塊(data block)中的可用空間。使用者也可以在建立或修改索引時為其設定 PCTFREE 參數(索引儲存在索引段(index segment)中)。
提示:
本節的內容並不適用於 LOB 資料類型(BLOB,CLOB,NCLOB,及 BFILE)。 這些類型的資料存放區時不使用 PCTFREE 參數及可用塊列表(free list)。
2.2.3.1 PCTFREE 參數
PCTFREE 參數用來設定一個資料區塊(data block)中至少需要保留(reserve)多少可用空間(百分比值),為資料區塊中已有資料更新時可能發生的資料量增長做準備。例如,當使用者用 CREATE TABLE 語句建立表時指定了以下參數:
PCTFREE 20
這個參數設定了此表對應的資料區段(data segment)中的每個資料區塊(data block)至少保留20%的可用空間,以備塊中已有資料更新時使用。只要資料區塊中行資料區與資料區塊頭的容量之和不超過資料區塊總容量的80%,使用者就可以向其中插入新資料,資料行被放入行資料區(row data area),相關資訊被寫入資料區塊頭(overhead area)。圖 2-3 說明了 PCTFREE 的作用。
PCTUSED 參數
PCTUSED 參數用於決定一個資料區塊(data block)是否可被用於插入新資料,她的依據是資料區(row data)與資料區塊頭(overhead)的容量之和占資料區塊全部容量的最大百分比。當一個資料區塊中的可用空間比例小於 PCTFREE 參數的規定時,Oracle就認為此資料區塊無法被用於插入新資料,直到資料區塊中的佔用容量比例小於 PCTUSED 參數的限定。在佔用容量比例大於 PCTUSED 參數的限定之前,Oracle只在更新資料區塊內已有資料時才會使用此資料區塊的可用空間。例如,當使用者用
CREATE TABLE 語句建立表時指定了以下參數:
PCTUSED 40
在例子中,當此表的某資料區塊佔用容量比例高於40%時,Oracle不會將此資料區塊用於插入新資料行(假設此資料區塊的可用空間曾經低於 PCTFREE 的限定)。圖 2-4 說明了 PCTUSED 的作用。
圖 2-4
PCTFREE 和 PCTUSED 如何協同發揮作用
PCTFREE 和 PCTUSED 共同作用可以最佳化資料區塊(data block)的空間使用。
PCTFREE 和 PCTUSED 如何共同作用以管理資料區塊(data block)可用空間的使用。
在第一步中,資料區塊佔用空間比例小於80%時才能插入新資料,因為 PCTFREE 參數限定必須保留20%的可用空間用於塊內已有資料的更新。
在第二步中,對資料區塊中已有資料的更新操作可以使用資料區塊中的保留空間。只有當資料區塊內的佔用空間比例低於40%時才能向其中插入新資料。
在第三步中,當資料區塊內的佔用空間比例低於40%時,此資料區塊再次可以被用於插入新資料。
在第四步中,資料區塊佔用空間比例小於80%時才能插入新資料,因為 PCTFREE 參數限定必須保留20%的可用空間用於塊內已有資料的更新。此過程如此往複迴圈。
在新分配的資料區塊中(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)的頭部,如果當前事務還需要寫入資料,此塊將被首先使用。當事務提交後,此資料區塊中的可用空間還可被其他事務使用。
2.3 資料擴充概述
資料擴充(extent)是由一組連續的資料區塊(data block)構成的資料庫邏輯儲存分配單位。而段(segment)則是由一個或多個資料擴充構成。當一個段中已有空間已經用完,Oracle為這個段分配新的資料擴充。
2.3.1 資料擴充何時被分配
當使用者建立資料表時,Oracle為此表的資料區段(data segment)分配一個包含若干資料區塊(data block)的初始資料擴充(initial extent)。雖然此時資料表中還沒有資料,但是在此初始資料擴充中的資料區塊已經為插入新資料做好了準備。
如果一個段(segment)的初始資料擴充(initial extent)中的資料區塊(data block)都已裝滿,且有新資料插入需要空間時,Oracle自動為這個段分配一個增量資料擴充(incremental extent)。增量資料擴充是一個段中繼已有資料擴充之後分配的後續資料擴充,她的容量大於或等於之前的資料擴充。
為了管理的需要,每個段(segment)的段頭(header block)中包含一個記錄此段所有資料擴充(extent)的目錄。