在我們了解如何調整 PostgreSQL Auto-vacuum之前,讓我們簡要了解一下 PostgreSQL 中VACUUM 的重要性。

為什么需要 Autovacuum?
在 PostgreSQL 中,被刪除或修改的行并沒有完全刪除。相反,它們被標記為死元組。換句話說,PostgreSQL 不會物理刪除這些行,而是在它們上放置一個標記,以防止將來的查詢返回或訪問死元組。
死元組消耗存儲空間,導致數據庫膨脹。數據庫臃腫是數據庫服務器性能不佳的主要原因之一(不包括其他架構原因)。為了防止死行占用過多的存儲空間,我們需要運行一個后臺進程來恢復死行或元組占用的存儲空間。
PostgreSQL 提供了刪除死行或元組的VACUUM命令和VACUUM ANALYZE命令。但是,這兩個命令的操作方式不同。
VACUUM命令僅關注刪除死行以恢復存儲空間,同時VACUUM ANALYZE命令刪除死行占用的存儲空間,并更新查詢計劃器使用的統計信息以選擇或選擇執行查詢的最有效計劃。
還有其他參數,例如FULL, FREEZE, DISABLE_PAGE_SKIPPING,我們可以對PostgreSQL中的表級別運行VACUUM任務。
PostgresqL文檔(https://www.postgresql.org/docs/13/runtime-config-autovacuum.html)包含用于自定義清理任務的附加參數。
可見性映射在VACUUM 處理中的作用
早于 8.4 版的 Postgres 版本在清理死元組方面表現不佳。通過以下步驟對表進行清理:
- Postgres 掃描所有表以獲取所有死元組并在必要時凍結舊元組。
- 刪除指向相應死元組的索引元組。
- 刪除死元組、更新活動元組、清理索引和更新表統計信息。
然而,可見性映射的引入改進了 Postgresql 中的VACUUM 處理。可見性映射確定表文件中的每個頁面是否有死元組。VACUUM 處理會跳過沒有死元組的頁面。在這種情況下不需要掃描表。
配置 Postgres Autovacuum相關參數
讓我們討論如何在 PostgreSQL 中使用以下參數適當地調整Autovacuum。
auto_vacuum:此參數是布爾類型:ON或OFF。默認值為ON。在這種情況下,服務器啟動autovacuum守護程序。此外,PostgreSQL建議必須啟用track_counts參數才能使Autovacuum正常工作。
track_counts 參數允許收集有關數據庫活動的統計信息。
即使您決定設置auto_vacuum為OFF,如果迫切需要阻止事務環繞 ID,PostgreSQL 也會啟動一個Autovacuum進程。
log_autovacuum_min_duration :在指定的時間內記錄清理任務。如果要跟蹤或記錄 autovacuum 任務的活動,此參數很有幫助。例如,您想檢查是否有一個 autovacuum 任務由于不存在的關系而沒有運行或執行。設置值以-1記錄此類信息。
autovacuum_max_workers : autovacuum workers/進程與autovacuum 啟動器不同。autovacuum啟動器查找需要清理的表/關系,然后啟動Autovacuum 工作程序以處理選定的表/關系。根據分配給此參數的 INTEGER 值,假設有四個worker。啟動器啟動四個worker在選定的表上工作。autovacuum_max_workers的默認值為3。如果您正在處理許多死元組,我們建議您增加worker的數量以加速VACUUM處理。否則,默認值是可以的。
autovacuum_naptime : 這個參數定義了 autovacuum 啟動器的休眠時間。因此,假設我們希望啟動器每兩分鐘檢查一次數據庫以發出VACUUM和ANALYZE,我們可以將的autovacuum_naptime整數值設置為2。設置適當的休眠時間可以防止與其他后臺 Postgres 進程爭用資源,因為VACUUM處理是定期初始化的。請注意,此參數與 autovacuum worker 無關,而是與啟動器相關。
autovacuum_vacuum_threshold:此參數定義了在 PostgreSQL 表上觸發VCACUUM命令的閾值。所以假設你想VACUUM用 100 個死元組觸發命令表。您可以將整數值設置為 100。默認值為 50 個已刪除/更新的元組/行。此參數指定刪除/更新元組/行的最小閾值。
當dead_tuple超過autovacuum_vacuum_scale_factor×表上記錄+autovacuum_vacuum_threshold的時候就會觸發對表的vacuum
autovacuum_vacuum_insert_threshold: 這個參數類似autovacuum_vacuum_threshold。唯一的區別是插入元組/行而不是更新/刪除的行/元組。默認值為 1000 個元組。但是,如果指定了 -1,autovacuum 將不會VACUUM在任何選定的表上啟動命令。如果有足夠的資源可用于清理,您可以增加autovacuum_vacuum_insert_threshold參數的值。如果不是的話,我們建議您不要調整默認值。
autovacuum_analyze_threshold:此參數指定在選定表上啟動或觸發ANALYZE命令的插入、更新或刪除元組的最小或最少數量。默認值為 50 個元組/行。
假設您的 Postgres 服務器運行在具有多個更快內核的平臺上,建議增加默認值讓ANALYZE頻繁運行或執行命令,因為查詢計劃器依賴于ANALYZE命令產生的統計結果來選擇最有效的查詢執行計劃。因此,如果pg_statistic系統目錄中的結果不是最新的,則查詢計劃器無法為查詢選擇最有效的執行計劃。
autovacuum_vacuum_scale_factor:此參數基本上指定了決定何時觸發VACUUM命令的表大小的一部分。它被添加到參數autovacuum_vacuum_threshold中。默認值 20% 是可選的,適用于處理速度最低的數據平臺。
autovacuum_vacuum_insert_scale_factor:這個參數和我們之前討論的參數類似。唯一的區別是這個參數被添加到autovacuum_vacuum_insert_threshold參數而不是autovacuum_vacuum_threshold參數中。
autovacuum_analyze_scale_factor:此參數指定包含在autovacuum_analyze_threshold參數中的表大小的一部分,以決定何時執行ANALYZE命令。默認值為 0.1 或 10%。同樣,如果 Postgres 在多核服務器上運行,建議增加默認值,因為更新的統計信息可以提高查詢性能。
autovacuum_freeze_max_age:此參數指定pg_class.relfrozenxid列的最大值,以防止表內的事務回繞。該VACUUM命令被執行或觸發以凍結舊行或將舊行轉換為凍結行該事務的默認值是2億個事務。我們建議默認值適用于大多數情況。
autovacuum_multixact_freeze_min_age:此參數與我們剛剛討論的上一個參數相似,但它側重于在觸發命令之前 multixact 的最小值,VACUUM以防止表內的 multixact ID 回繞。此參數的默認值為 4 億個 mutlixact。
請注意,multixact在 Postgres 中是指多個事務同時鎖定一行。
autovacuum_vacuum_cost_delay:該參數用于防止autovacuum worker超出參數指定的工作點autovacuum_vacuum_cost_limit。建議不要增加此參數的值,以防止worker過度消耗操作系統資源,避免資源爭用。
autovacuum_vacuum_cost_limit:此參數可防止 autovacuum worker 消耗過多的可用操作系統資源。如果您正在處理大表,建議將參數的值設置為 0,以避免表膨脹。但是,如果您正在處理小表,則可以將其設置為 -1,以允許其他 cpu 內核專注于其他高優先級處理任務。
我們不建議您嚴格按照上述說明為 PostgreSQL 調整 autovacuum。但是,您可以使用這些步驟來了解 autovaccum 在 PostgreSQL 中的工作原理,并根據自己的喜好對其進行調整。
結論
正確配置 autovacuum 對于避免死元組導致性能下降很重要。如果您需要有關正確調整它的建議,請考慮我們的PostgreSQL Health Check。(https://vettabase.com/blog/services/health-checks/postgresql/)
原文鏈接:https://vettabase.com/blog/tuning-postgresql-auto-vacuum/?utm_source=rss&utm_medium=rss&utm_campaign=tuning-postgresql-auto-vacuum
作者:Michael Aboagye
譯者:閻書利




