做者:Laurenz Albe是CYBERTEC的高級顧問和支持工程師。自2006年以來,他一直在PostgreSQL上工做併爲PostgreSQL作貢獻。
sql
譯者:類延良,任職於瀚高基礎軟件股份有限公司,PostgreSQL數據庫技術愛好者,10g &11g OCM,OGG認證專家。數據庫
在許多PostgreSQL數據庫中,您無需考慮或擔憂調整autovacuum。它會在後臺自動運行,並在不妨礙您的狀況下進行清理。安全
可是有時默認配置還不夠好,您必須調整autovacuum以使其正常工做。本文介紹了一些典型的問題方案,並介紹了在這些狀況下的處理方法。session
autovacuum的任務併發
有許多autovacuum的配置參數,這會使調整變得複雜。主要緣由是autovacuum具備許多不一樣的任務。從某種意義上說,autovacuum必須解決由PostgreSQL的多版本併發控制(MVCC)實現引發的全部問題:ide
根據這些功能中的哪一個會致使問題,您須要不一樣的方法來調整autovacuum。函數
調整autovacuum以清除死元組post
最有名的autovacuum任務是清理UPDATE或DELETE操做中的死元組。若是autovacuum不能跟上清理死元組的速度,則應遵循如下三個調整步驟:網站
確保沒有任何東西能夠阻止autovacuum回收死元組spa
檢查 防止vacuum清除死元組的已知緣由
https://www.cybertec-postgresql.com/en/reasons-why-vacuum-wont-remove-dead-rows/罪魁禍首一般是長期事務。除非您能夠消除這些障礙,不然調整autovacuum將無用。
若是您不能從根本上解決問題,則可使用配置參數
idle_in_transaction_session_timeout使PostgreSQL終止會話,這些會話在事務中處於「idle in transaction」的時間過長。這會在客戶端致使錯誤,可是若是您沒有其餘方法能夠保持數據庫正常運行,這多是有道理的。一樣,要解決長期運行的query,可使用statement_timeout配置參數。
調整autovacuum以使其運行更快
若是autovacuum沒法跟上清理死元組的速度,那麼解決方案就是使其工做更快。這看起來彷佛很明顯,可是許多人陷入了使autovacuum更早開始或更頻繁運行將解決問題的陷阱。
VACUUM是一項耗費資源的操做,所以默認狀況下,autovacuum操做的速度故意下降。目的是使其在後臺運行而不妨礙正常的數據庫操做。可是,若是您的工做負載建立了不少死元組,那麼您將不得不使其更具侵略性:
設置autovacuum_vacuum_cost_delay爲零將使autovacuum與手動VACUUM速度同樣快,即儘量快。
因爲並不是全部表都以相同的速度增加死元組,所以一般最好不要更改中的全局設置postgresql.conf,而要單獨更改繁忙表的設置:
ALTER TABLE busy_table SET (autovacuum_vacuum_cost_delay = 1);
對錶進行分區還能夠幫助更快地完成工做。請參閱本文partition部分了解更多信息。
更改工做負載,以便生成更少的死元組
若是沒有其餘效果,則必須看到生成的死元組更少。也許將幾個UPDATE合併爲一行UPDATE一般,您可使用「 HOT更新」來顯着減小死元組的數量:
而後,任何SELECT或DML語句均可以清除死元組,而對VACUUM的需求則更少。
調整僅索引掃描的autovacuum
索引掃描的昂貴部分是查找實際的錶行。若是您想要的全部列都在索引中,則徹底不須要訪問該表。可是在PostgreSQL中,您還必須檢查一個元組是否可見,而且該信息僅存儲在表中。
爲了解決這個問題,PostgreSQL對每一個表都有一個「可見性圖」(visibility map)。若是一個表塊在可見性圖(visibility map)中被標記爲「全部可見」,則沒必要訪問該表以獲取可見性信息。
所以,要得到真正的僅索引掃描,autovacuum必須處理表並常常更新可見性圖(visibility map)。爲此,如何配置autovacuum取決於查詢收到的數據修改類型:
爲接收UPDATEs或DELETEs的表的僅索引掃描調整autovacuum
爲此,您能夠減小表的存儲參數autovacuum_vacuum_scale_factor,例如
ALTER TABLE mytable SET (autovacuum_vacuum_scale_factor = 0.01);
按照如上所述加快autovacuum是一個好主意。
調整僅接收INSERTs的表的僅索引掃描的autovacuum
從v13開始,這很簡單:對配置參數autovacuum_vacuum_insert_scale_factor進行調整,調整方法是如上所示對autovacuum_vacuum_scale_factor的調整。
對於較舊的PostgreSQL版本,您能夠作的最好方法就是下降autovacuum_freeze_max_age,最佳值取決於您使用事務id的速率,若是您天天消耗100000個事務id,而且但願天天自動清理table,則能夠進行以下設置:
ALTER TABLE insert_only SET (autovacuum_freeze_max_age = 100000);
要測量事務ID消耗的速率,請在一個長的時間間隔內使用兩次txid_current()函數(或者從V13開始的pg_current_xact_id()函數),而後取其差值。
調整autovacuum以免事務迴繞問題
正常時,autovacuum關心並啓動一個特殊的「anti-warparound」 autovacuum worker,不論一個表中最老的transaction id比autovacuum_freeze_max_age參數值更老或者一個表中的最老的multiact比autovacuum_multixact_freeze_max_age 參數值更老
確保anti-wraparound vacuum能夠freeze掉全部表中的行
再次強調,你不得不確保:沒有阻塞autovacuum進行freeze老元組和改進pg_database.datfrozenxid 以及pg_database.datminmxid。這些阻塞者包括:
爲了防止數據損壞,請使用更好的硬件,並老是運行最新的PostgrSQL的次要版本。
爲接收updates或者Deletes的tables調優anti-wraparound vacuum
在接收updates或者deletes的table上,你不得不作的一切是看autovacuum正在運行,而且足夠快以便及時完成(參見上文)
爲接收inserts的tables調優anti-wraparound vacuum
從PostgreSQL v13開始,在這種狀況下沒有特殊考慮,由於您也能夠在此類表上按期運行autovacuum。
在此以前,僅插入表是有問題的:因爲沒有死元組,所以永遠不會觸發正常的autovacuum運行。
而後,一旦autovacuum_freeze_max_age或autovacuum_multixact_freeze_max_age超過該值,您可能會忽然得到大量的autovacuum運行,從而凍結整個大表,花費很長時間並致使大量的I / O。
爲避免這種狀況,請減小autovacuum_freeze_max_age該表:
ALTER TABLE insert_only SET (autovacuum_freeze_max_age = 10000000);
分區
對於很大的表,建議使用分區。這樣作的好處是您可讓多個autovacuum workers 並行處理多個分區,所以整個分區表的完成速度比單個autovacuum worker快。
若是您有多個分區,則應增長autovacuum_max_workers,該參數是指autovacuum workers的最大數量。
只要更新影響全部分區,分區還能夠幫助清理接收大量更新的表。
調優autoanalyze
更新表統計信息是自動清理的「輔助工做」。
您知道,若是您的查詢計劃在手工對錶執行ANALYZE後變得更好,那麼自動統計信息收集將不會常常發生。
在這種狀況下,您能夠下降autovacuum_analyze_scale_factor以使autoanalyze更頻繁地處理表:
ALTER TABLE mytable SET (autovacuum_analyze_scale_factor = 0.02);
另外一種選擇是不使用scale factor,而是使用set autovacuum_analyze_threshold,以便每當固定數量的行發生更改時,就計算表統計信息。
例如,要配置每當超過一百萬行更改時要分析的表:
ALTER TABLE mytable SET ( autovacuum_analyze_scale_factor = 0, autovacuum_analyze_threshold = 1000000 );
結論
根據您的特定問題和PostgreSQL版本,有不一樣的調整開關可使autovacuum正確執行其工做。autovacuum的許多任務和許多配置參數並無使它變得更容易。
若是本文中的提示還不夠,請考慮尋求專業諮詢
(https://www.cybertec-postgresql.com/en/services/postgresql-consulting/)
原文連接:
https://www.cybertec-postgresql.com/en/tuning-autovacuum-postgresql/
更多精彩內容,請關注如下平臺、網站:
中國Postgre SQL分會官方公衆號(技術文章、技術活動):
開源軟件聯盟PostgreSQL分會
中國Postgre SQL分會技術問答社區:
中國Postgre SQL分會官方網站: