為什麼 autovacuum 在整個數據庫的 VACUUM FREEZE 期間執行?
我有一個 14.7 TB Postgres(9.1) 數據庫,它必須長時間承受大量寫入。我知道我需要密切管理我的事務 ID 以防止數據庫鎖定。最近我注意到查詢速度變慢了,並且看到在我們的大型只讀表上執行了多個自動清理,並帶有“(防止迴繞)”下標。我停止了正在執行的軟體並執行了一個
vacuumdb -F -a
命令。但是,當我執行時,select current_query from pg_stat_activity
我看到 autovacuum 程序仍在執行,即使在手動清理期間也是如此。我嘗試殺死 autovacuumsselect pg_cancel_backend(pid)
並且它們死了,但隨後立即重新啟動。我的問題:
- autovacuum 是否應該在手動數據庫清理期間繼續執行?
- 如何有效地停止這些 autovacuum 程序?
- 為什麼這些 autovacuums 會繼續在只讀表上執行?有什麼可以吸塵的?
Autovacuum 是由表上的表統計資訊觸發的,只要你手動
VACUUM (FREEZE)
不做,這些是不會更新的。這就是為什麼反環繞自動清理程序仍將啟動的原因。但這不是什麼大問題:
VACUUM
任何時候只有一個人可以在桌子上跑步。現在,anti-wraparound autovacuum 工作人員在阻止另一個程序時不會放棄,在這種情況下是你的手冊VACUUM
。但是如果你殺死了反環繞自動清理工作者,你的手冊VACUUM
會獲得鎖定,現在它是被重新啟動的反環繞自動清理工作者被阻止。查看pg_locks
以驗證它們是否正在等待鎖定 (granted = FALSE
)。現在您
vacuumdb
一個接一個地處理一個表,因此您必須準備好在它開始處理下一個表並被那裡的新 autovacuum 工作人員阻止時立即殺死它。
VACUUM
在那些大型只讀表上手動啟動可能比使用更容易vacuumdb
,因為這樣您就可以控制何時清空哪個表。確保設置
maintenance_work_mem
高以加快速度VACUUM
。您還應該autovacuum_vacuum_cost_delay
至少在這些大表上設置為 2ms 或更低,以便將來的 autovacuum 執行更快地完成。為了減少未來的痛苦,
autovacuum_freeze_max_age
大幅降低受影響的桌子。然後下一個反環繞真空將更快啟動並且完成得更快。最重要的是,盡快升級到 v13,因為從該版本開始,僅插入表也將定期進行清理,這應該可以解決問題。