2020年9月23日 星期三

5.5 Oracle Data Block

Oracle Data Block 為儲存資料的最小邏輯單位, Oracle 資料庫的所有資料最終都是存放在 Oracle Data Block 當中,而一個 Data Block 在結構上可以分為 Block Header 與 Footer 兩部分:

Block Header 記錄著此 Block 的系統資訊,包括 Block 的空間使用率、interested transaction list (ITL) 、 data block address (dba, 表示 Oracle Data Block 存放在作業系統的上的實體位址)…等,Block Footer 為資料存放的地方,我們可以想像 Block 是一個水桶,儲存的資料為水桶裡面的水位, Block 的使用就猶如倒水一般的把資料從最底下慢慢的往上填滿。


對於 Data Block 的空間使用方式由 pctfree 與 pctused 兩個參數來控制:

  • PCTFREE:

表示要為這個 Block 保留多少百分比的空間,此參數預設為 10 ,表示一個 Block 的使用率需保留 10% 的可用空間,也就是當 Block 的水位(使用率)達到 90% 的時候就表示這個 Block 已經填滿了。保留這 10% 的可用空間是要為將來資料的 update 所使用, update 其實就是一個 insert 與 delete 的過程,所以需要保留一定的可用空間來容納新資料,如果保留的可用空間不夠,就會產生 row migrate 的情況。當然如果在規劃上確保資料將來不會被 update ,那麼也可以將 pctfree 設定為 0 ,讓 Data Block 的使用率達到 100% 。


  • PCTUSED:

隨著資料庫的運行,資料有可能被新增、刪除、修改,那麼在甚麼情況下一個 Data Block 才有可能再被重複使用? pctused 就是用來決定此 Block 是否能夠再被使用的參數。隨著資料的刪除,一個 Block 的水位也會越來越低,當水位低於 pctused 設定的水準時,就將此 Block 視為空 Block 可再度被使用。 pctused 預設為 40 ,也就是說當一個 Block 的使用率小於 40% 時,就可以再度的被使用。


舉例來說,假定 PCTFREE 為 20 、 PCTUSED 為 10 ,那麼就可以將一個空的 Block 從 0 開始填資料直到此 Block的使用率達到 80% 為止,之後就不再允許資料放入此 Block ,未來此 Block 的資料必須一直減少到只剩下 10% 的使用率時,才可以允許再有資料放進來。


由於 pctfree 與 pctused 兩個參數控制著 Block 空間的使用率,如果設置不當的話容易產生 Row Chain 與 Row Migrate 兩個現象。


Row Chain 表示一個 Block 無法容納下一整筆的資料,需要分散在多個 Block 上放置,有可能是資料本身長度過長,或是 Block 的可使用率太低:

假如 pctfree 設置過大,一個 Block 需保留較多的可用空間,相對的能使用的空間就變少,這樣就有可能因為一個 Block 的可使用率太低而造成 Row Chain 的情況。


Row Migrate 表示一個 Block 無法容納下 update 的資料,必須尋找可用空間足夠的 Block 來容納此 Block 的所有資料,然後把新舊資料一併的搬過去:

假如 pctfree 設置過小,那麼就容易造成 Block 保留的可用空間容納不下 update 的新資料而造成 Row Migrate 的情形。


一般來說,如果 update 會造成資料的長度增加,那麼建議將 pctfree 的設置大於預設值,避免因資料長度的增加而造成 Row Migrate 的情況;如果資料的 update 頻率不高,那麼可以將 pctfree 的設置小於預設值,這樣可以增加 Data Block 的可使用率;如果沒有辦法預期資料是否被 update ,那麼就建議使用預設值就好了。


除了 pctfree 與 pctused 是用來控制 Block 的空間使用率外,另外還有兩個參數 initrans 與 maxtrans 控制著同時有多少人可以來更新這個 Block。


當一個 Block 裡面的資料需要被異動時,它必須要知道此筆 row 是被哪一個事務(transaction) 所異動,因此 Data Block 會記載著所有要來異動它的事物(transaction) ,這個記錄就稱作 interested transaction list (ITL) 。當一個 Data Block 接受到一個事務(transaction)來請求資料的異動時, Data Block 會於 Block Header 中分配一個約 23 bytes 的空間專門來記錄這個事務(transaction)的資訊,而這個空間就稱作 ITL Slot,當一個交易(transaction)獲得 ITL Slot 之後,它才有權利請求 row lock 來異動資料。

參數 initrans 表示 Block 起始配置的 ITL Slot 數量,而 maxtrans 表示最大可配置的 ITL Slot 數量,此兩個參數最小可設為 1 最大 255,預設 Table 的 initrans 為 1 、 Index 的 initrans 為 2 ,而自 Oracle 10g 之後, maxtrans 已自動配置為 255 了。當一個交易(transaction)佔用了一個 ITL Slot 且尚未 commit,此時又有另一個交易(transaction)進來,如果沒有可用的 ITL Slot ,它就必須等待其他的交易(transaction)完成 commit 後釋出 ITL Slot,或是等待 Block 配置一個新的 ITL Slot,這個時候就會產生 enq: TX - allocate ITL entry 這個等待事件。如果這個事件發生頻率很高且等待時間過長,就要考慮增加 initrans ,起始就分配多一點的 ITL Slot 來避免這個等待的發生。


Data Block 相關參數的設定是在建立 Table時所附加,例如建立一個 Table T1 ,設定 pctfree 20 、 pctused 40 且 initrans 4:

SQL> create table t1(a varchar2(20),b number) 

pctfree 20 pctused 40 initrans 4;


而建立 Index 時只能設定 initrans 屬性:


如果要修改屬性,可以使用 alter 命令來修改,例如將 T1 設定為 pctfree 10 、 pctused 20 且 initrans 2:


介紹完這些參數之後,最主要的還是要了解一個應用系統的特性,為 OLTP 系統或是 OLAP 系統 ? 資料頻不頻繁被異動 ? 資料成長速度快不快 ? 資料的屬性為何 ? 這樣才能在系統建置的初期來客制化這些參數,進而達到最佳化的結果。





沒有留言:

張貼留言