PostgreSQL vacuum原理—vacuum揭秘

jesselyu發表於2015-04-26

    在前面兩個章節中,我們講了vacuum的一些重要引數“PostgreSQL vacuum原理一功能與引數”以及PG發起vacuum的流程“PostgreSQL vacuum原理—啟動機制”。這個章節我們重要講下vacuum 的實現,

主要分為vacuum full和lazy vacuum。

 

1.vacumm full

    vacuum full會鎖表和索引,而且是“AccessExclusiveLock”級別的。其實vacuum full會重建整個表,這個的功能實現在cluster.c檔案中,因為其行業相當於是一個cluster重建的一個變種。

建臨時表階段:PG會新表一個以”pg_temp_%u”的臨時表,臨時表繼承老表所有屬性。”%u”是老表的OID。如果使用者表有名字與這個臨時表相同的,那麼就會失敗。另外臨時表的OID是relfilenode。 這個階段,會對pg_class申請“RowExclusiveLock”鎖,因為需要插入條目;也會做表名檢查,檢查是否與現有表名衝突。

copy資料階段:然後將原來的資料copy到temp表中。對臨時表,老表以及索引都以“AccessExclusiveLock”模式開啟。另外對於toast,只是lock,不開啟。在這個過程中完成Dead Tuple的清理。

swap表階段:最後做一個swap table操作,新表將老表替換掉。交換隻是將物理檔案進行交換。reltablespace和relfilenode進行交換,會對pg_class再次申請“RowExclusiveLock”鎖。

重建索引階段:是在交換之後完成的,重建索引時,會更新一些統計資訊。對錶申請“ShareLock”鎖。

刪除臨時表階段:索引重建完成後,將帶有老物理檔案的新臨時表進行刪除。

 

image

 

2. lazy vacumm

    PG在lazy vaccum之前,會先判斷此次vacuum是full scan還是part scan。判斷靠vacuum_freeze_table_age引數,它只與newest xid和relfrozenxid比較,

公式為:relfrozenxid < newestxid - vacuum_freeze_table_age

演變後:vacuum_freeze_table_age < newestxid - relfrozenxid

vacuum_freeze_table_age預設值為150million。因此如果一個表在pg_class中的relfrozenxid比newestxid小150million時,就會觸發全表掃描,完成後更新pg_class中的relfrozenxid。

vacuum_freeze_table_age的最大值是0.95*autovacuum_freeze_max_age。

新的凍結relfroenxid的計算需要靠以下公式的運算結果來判斷:

oldestXmin – vacuum_freeze_min_age

上面公式演變後成: autovacuum_freeze_max_age - vacuum_freeze_min_age < newest xid – oldestXmin

relfrozenxin取值? 公式成立 公式不成立
full scan oldestXmin,說明oldestXmin過老 oldestXmin-vacuum_freeze_min_age,如果是負值,返回3
part scan 0 0

從上面可以知道,part scan是不會更新pg_class中的relfrozenxid值的,只有full scan會去更新。原因很簡單,part scan實際上只是清理dead tuple,FSM(Free Space Map)和標記visibility map。
預設情況下,autovacuum_freeze_max_age 的值為200million,vacuum_freeze_min_age 為50million。那也就是說oldest xid與newest xid的差距不能大於150million。

否則,PG就認為oldestXmin已經太老了,就會提示使用者儘量關閉事務,以免發生xid迴圈使用的問題(wraparound transaction xid)。

對於一個系統,如果每秒事務量為1W tps,可以支援15000秒,也就是4個小時左右。vacuum_freeze_min_age 的最大值不能超過autovacuum_freeze_max_age/2,也就是100million。

 對於multixid的凍結,也是同樣的計算方法,只不過autovacuum_multixact_freeze_max_age的值為400million,

PG用這個方法,完美解決了wraparound 問題。

 

image

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

相關文章