PostgreSQL FSM(Free Space Map) 原始碼解讀

jesselyu發表於2015-01-01

PostgreSQL FSM(Free Space Map) 原始碼解讀

一、FSM設計目的

FSM,即空閒空間管理的設計初衷是為了能夠快速找到一個頁是否有足夠的自由空間用來容納新增的資料。如果沒有這樣的頁,則分配新頁。在PG 8.4版本以後,每個relation有自己獨立的的FSM空間(以_fsm後輟的檔案)


fsm檔案:

二、FSM原理


FSM總體設計上採用binary tree和High-level兩種演算法。


1. Binray tree

一個relation的每個heap page 用一個map byte表示,即8位。這也相當於將一個page的空閒空間(map value) 分為256檔位。按當前 page size 8K來算, 8K/256=32;即32位元組一個檔位。

PG只是用來粗略記錄每個頁的剩餘空間,並不會精確記錄真實有多少空間可用。

如下圖所示:


目前PG 一個relation最大支援2的32次方個page,一個page size 8K 計算,即4G*8k=32T。為了存放這麼多塊,三層樹結構,至少每個FSM page需要1626個slot。

1626*1626*1626>=2^32。

原始碼中一個relation 最大BlockNumber定義:


一個葉子節點對應一個relation heap page。分支節點代表自己所有子節點中剩餘空間的最大值。如:



假設,我們需要94個位元組,那麼可以算出map value 為:94+31/32=3.90625(演算法如下圖)。此時查詢map value為4的值,先從root節點頂層開始,一直找到底層。

請求空間時map value演算法:


以上面的樹為例,那麼分配之後的樹將變成下面的形態。即以冒泡的形式依次修改父節點branch的值。

 

總結:採用二叉樹後,只需要比較下root節點就可以判斷此頁剩餘空間是否滿足空間請求。


2. High-level演算法

    上面的演算法假設只有一個FSM page,但是事實上,隨著表的增大,FSM 本身也會變大。FSM 樹變大後,將會超出一個page 8K的容量。所以這時就引入High-level的演算法,

解決FSM跨page的問題。從上面分析得知,一個relation最大可以有2^32次方,即4G個page。如果層數保持在3層,那麼至少每層需要1626個slot來儲存 heap page的map value值。即,1626*1626*1626>=2^32。事實上一個FSM page可以儲存 (8k-page header)/2~=4000 個 heap page的map value。那麼三層結構可以儲存 4000*4000*400>>2^32個。
所以PG用三層的High-level樹來記錄一個表是足夠的。High-level樹跟FSM low level結構相似,只是High-level的葉子節點指向FSM page (Low-level)的root節點。

    PG用fsm_set_avail()和fsm_search_avail()封裝了自由空間查詢功能和FSM page的結構樹,使得High-level訪問 FSM page看起來像個黑盒。



總結:1.PG在查詢空閒時,先比較root,如果申請的map value比root小,則此頁能滿足,不然申請新heap page。

        使用後,修改leaf節點值,以冒泡方式,依次修改父節點以至root節點。


      2.VACUUM操作時,修改葉子節點值,再以冒泡方式,依次修改父節點以至root節點。


      3.在查詢空閒塊時,會有鎖,尤其是父級page會有share lock;如果是冒泡修改父級page時,會有exclusive lock。

        樹形結構在查詢上有優點;但併發上,這也是這種結構帶來的劣勢。

      




來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30088583/viewspace-1387176/,如需轉載,請註明出處,否則將追究法律責任。

相關文章