來自數據庫的高 autovacuum CPU/IO 使用率,超過 10k 只追加表
在我的系統中,我有超過 10k 個非常相似的表,我只在這些表中執行插入操作,並通過每天一次的 cron 計劃刪除舊數據。
這些插入每分鐘發生一次,平均每個表有 5 行插入到單個插入查詢中,這意味著每分鐘大約 50k 行。
我看到的問題是
stats collector
(我禁用了除 track_counts 之外的所有統計資訊)一直使用大量 CPU 和 IO。同樣的情況也會發生,
autovacuum
它也會為自己使用大量的 PC 資源。另一個問題是它們似乎永遠不會停止,只要我總是以上面顯示的速率添加新數據,它們就會一直執行
autovacuum
。stats collector
如果我禁用
track_counts
andautovacuum
,它會完全解決我的問題,數據庫大部分時間都處於空閒狀態。這種方法的問題是我顯然不再跑步
vacuum
了。所以,我的問題是,對於我的案例來說,完全禁用
autovacuum
並VACUUM FULL
在我的 cron 腳本刪除舊數據後執行是否是一個很好的解決方案?這意味著我每天會為每個表觸發一次完整的真空查詢。如果沒有,您是否對 postgres 配置更改有一些建議,以在不禁用的情況下改善情況
autovacuum
?這是我的 postgresql.conf 的一部分(如果需要,請隨時詢問有關它的更多資訊):
track_activities = off track_counts = on track_io_timing = off track_functions = none log_parser_stats = off log_planner_stats = off log_executor_stats = off log_statement_stats = off #------------------------------------------------------------------------------ # AUTOVACUUM #------------------------------------------------------------------------------ autovacuum = on log_autovacuum_min_duration = -1 autovacuum_max_workers = 6 autovacuum_naptime = 3600
對於僅附加表或大表的情況,我已經看到了一些答案,但我認為我看到了這個問題,因為在我的情況下,我有很多表。
另外,為了完整起見,我在 Postgres 12 中執行數據庫,並在 docker 內使用擴展 TimescaleDB 1.7.1。
你有多少張超過 10k 的桌子?10k和無窮大之間有很大的空間。
如果我禁用 track_counts 和 autovacuum,它會完全解決我的問題,
如果只禁用 autovacuum 並保持 track_counts 開啟,是否也能解決問題?
所以,我的問題是,在我的 cron 腳本刪除舊數據後,完全禁用 autovacuum 並執行 VACUUM FULL 是否是一個很好的解決方案?
為什麼 VACUUM FULL 而不是正常的 VACUUM ANALYZE?VACUUM FULL 似乎太過分了。我寧願深入了解根本上正在發生的事情,但這樣做也可以。只要工作不會在不被注意的情況下中斷。
禁用 autovacuum 是一個非常糟糕的主意。Autovacuum 刪除死線並更新統計資訊。禁用 autovacuum 會很快導致性能下降。此外,當 autovacuum 被禁用時,你遲早會遇到環繞問題。
既然你使用的是 TimescaleDB,為什麼不使用drop_chunks()函式來刪除舊數據呢?這將顯著減少對錶執行真空的需要。但是,autovacuum 仍然需要處理表以防止我在上面寫的環繞。另外,可以改變chunk的大小,讓autovacuum要處理的數據大小不會那麼大。
autovacuum 設置沒有通用值。嘗試調整以下設置以獲得最佳性能:
autovacuum_vacuum_threshold autovacuum_vacuum_scale_factor autovacuum_vacuum_cost_delay
對於統計:
autovacuum_analyze_threshold autovacuum_analyze_scale_factor
您還可以為 autovacuum 守護程序配置成本參數以處理頁面:
vacuum_cost_page_hit vacuum_cost_page_miss vacuum_cost_page_dirty vacuum_cost_limit