PostgreSQL vacuum原理一功能與參數
從上篇“PostgreSQL MVCC 源碼實現 【】”中,我們知道,PG並沒有像Oracle那樣的undo來存放舊版本;而是將舊版本直接存放於relation檔案中。那麼帶來的問題就是dead tuple過多,導致relation檔案不斷增大而帶來空間膨脹問題。為瞭解決這個問題,PG中引入了vacuum後台進程,專門來清理這些dead tuple,並回縮空間。當然vacuum的作用不僅在此,它還有以下其它功能:
一、vacuum的功能
1.回收空間
這個通常是大家最容易想起來的功能。回收空間,將dead tuple清理掉。但是已經分配的空間,一般不會釋放掉。除非做vacuum full,但是需要exclusive lock。一般不太建議,因為如果表最終還是會漲到這個高水位上,經常做vacuum full意義不是非常大。一般合理設定vacuum參數,進行常規vacuum也就夠了。
2.凍結tuple的xid
PG會在每條記錄(tuple)的header中,存放xmin,xmax資訊(增刪改事務ID)。transactionID的最大值為2的32次,即無符整形來表示。當transactionID超過此最大值後,會迴圈使用。
這會帶來一個問題:就是最新事務的transactionID會小於老事務的transactionID。如果這種情況發生後,PG就沒有辦法按transactionID來區分事務的先後,也沒有辦法實現MVCC了。因此PG用vacuum後台進程,按一定的周期和演算法觸發vacuum動作,將過老的tuple的header中的事務ID進行凍結。凍結事務ID,即將事務ID設定為“2”(“0”表示無效事務ID;“1”表示bootstrap,即初始化;“3”表示最小的事務ID)。PG認為被凍結的事務ID比任何事務都要老。這樣就不會出現上面的這種情況了。
3.更新統計資料
vacuum analyze時,會更新統計資料,讓PG的planner能夠算出更準確的執行計畫。autovacuum_analyze_threshold和autovacuum_analyze_scale_factor參數可以控制analyze的觸發的頻率。
4.更新visibility map
在PG中,有一個visibility map用來標記那些page中是沒有dead tuple的。這有兩個好處,一是當vacuum進行scan時,直接可以跳過這些page。二是進行index-only scan時,可以先檢查下visibility map。這樣減少fetch tuple時的可見度判斷,從而減少IO操作,提高效能。另外visibility map相對整個relation,還是小很多,可以cache到記憶體中。
二、vacuum參數介紹
autovacuum有好多參數,用來控制其行為,大致有以下幾個:
• autovacuum:預設為on,表示是否開起autovacuum。預設開起。特別的,當需要凍結xid時,儘管此值為off,PG也會進行vacuum。
• autovacuum_naptime:下一次vacuum的時間,預設1min。 這個naptime會被vacuum launcher分配到每個DB上。autovacuum_naptime/num of db。
• log_autovacuum_min_duration:記錄autovacuum動作到記錄檔,當vacuum動作超過此值時。 “-1”表示不記錄。“0”表示每次都記錄。
• autovacuum_max_workers:最大同時啟動並執行worker數量,不包含launcher本身。
• autovacuum_vacuum_threshold:預設50。與autovacuum_vacuum_scale_factor配合使用, autovacuum_vacuum_scale_factor預設值為20%。當update,delete的tuples數量超過autovacuum_vacuum_scale_factor*table_size+autovacuum_vacuum_threshold時,進行vacuum。如果要使vacuum工作勤奮點,則將此值改小。
• autovacuum_analyze_threshold:預設50。與autovacuum_analyze_scale_factor配合使用, autovacuum_analyze_scale_factor預設10%。當update,insert,delete的tuples數量超過autovacuum_analyze_scale_factor*table_size+autovacuum_analyze_threshold時,進行analyze。
• autovacuum_freeze_max_age和autovacuum_multixact_freeze_max_age:前面一個200 million,後面一個400 million。離下一次進行xid凍結的最大事務數。
• autovacuum_vacuum_cost_delay:如果為-1,取vacuum_cost_delay值。
• autovacuum_vacuum_cost_limit:如果為-1,到vacuum_cost_limit的值,這個值是所有worker的累加值。
基於代價的vacuum參數:
• vacuum_cost_delay :計算每個毫秒層級所允許消耗的最大IO,vacuum_cost_limit/vacuum_cost_dely。 預設vacuum_cost_delay為20毫秒。
• vacuum_cost_page_hit :vacuum時,page在buffer中命中時,所花的代價。預設值為1。
• vacuum_cost_page_miss:vacuum時,page不在buffer中,需要從磁碟中讀入時的代價預設為10。 vacuum_cost_page_dirty:當vacuum時,修改了clean的page。這說明需要額外的IO去刷髒塊到磁碟。預設值為20。
• vacuum_cost_limit:當超過此值時,vacuum會sleep。預設值為200。
把上面每個cost值調整的小點,然後把limit值調的大些,可以延長每次vacuum的時間。這樣做,如果在高負載的系統當中,可能IO會有所影響,因vacuum。但是對於表實體儲存體空間的增長會有所減緩。
在下一篇重點將在源碼實現上。見
------------------------------------華麗麗的分割線------------------------------------
CentOS 6.3環境下yum安裝PostgreSQL 9.3
PostgreSQL緩衝詳述
Windows平台編譯 PostgreSQL
Ubuntu下LAPP(Linux+Apache+PostgreSQL+PHP)環境的配置與安裝
Ubuntu上的phppgAdmin安裝及配置
CentOS平台下安裝PostgreSQL9.3
PostgreSQL配置Streaming Replication叢集
如何在CentOS 7/6.5/6.4 下安裝PostgreSQL 9.3 與 phpPgAdmin
------------------------------------華麗麗的分割線------------------------------------
PostgreSQL 的詳細介紹:請點這裡
PostgreSQL 的:請點這裡
本文永久更新連結地址: