在 Postgres 中,每天添加/刪除數千行的大表(數億行)的自動清理策略應該是什麼?
我有一張很大的桌子,每天有很多用於讀取、插入和刪除的流量。目前,它有 3.92 億個活元組和 2700 萬個死元組。真空設置(
autovacuum_vacuum_threshold
、autovacuum_vacuum_scale_factor
等)設置為預設值。有時我確實遇到了一些性能問題,這些問題使查詢持續 > 2 分鐘,而它們通常需要幾秒鐘。
起初,我會考慮將真空比例因子從目前的 0.2 降低到 0.05 甚至 0.01。但是,因為 autovacuum 每天已經執行了好幾次(它們可能會執行一段時間,>1 小時),我不確定降低比例因子是否會使情況變得更糟,因為它會執行得更頻繁,儘管這意味著autovacuum 將處理的死元組數量減少。
乍一看,您的桌子看起來不錯。如果 autovacuum 完成並且您的死元組少於 30%,我認為無需擔心。
您可能想使用
pgstattuple
擴展來檢查表是否有大量可用空間;如果是的話,這將表明使 autovacuum 更快。這裡的關鍵字更快:您必須為此降低
autovacuum_vacuum_cost_delay
或增加autovacuum_vacuum_cost_limit
。讓 autovacuum 更頻繁地執行不會有任何好處。但是,如果您已經遇到 autovacuum 與目前一樣快的性能問題,我會不理會這些設置。
每天添加/刪除的數千行並不是很多。如果它有 3.92 億個活動元組,並且在預設設置下每天會觸發多次 autovacuum,那一定意味著每天添加/刪除數以億計的行。
所有這些變化是集中在表格的一個部分,還是均勻分佈在整個表格中?也許您可以分區以將最熱門的元組分組在一起?
您的查詢是否受益於僅索引掃描?如果是這樣,讓 autovac 更具侵略性可能是有意義的。但如果不是這樣,除了消耗更多 IO 之外,沒有理由認為讓它比預設設置更具侵略性會完成很多事情。
您確實需要在行為中擷取緩慢的查詢,以了解它為何緩慢。一種有用的方法是使用 auto_explain。讓 log_analyze=on 真的會減慢整個系統的速度,尤其是在較舊的核心/硬體上,它們對時鐘的訪問速度很慢。但是 log_timing=off 彌補了大部分減速,同時保留了許多有價值的資訊。
track_io_timing=on shared_preload_libraries = 'pg_stat_statements,auto_explain' auto_explain.log_min_duration = '20s' auto_explain.log_analyze=on auto_explain.log_timing=off -- if ./pg_test_timing indicate a slow clock. auto_explain.log_buffers=on auto_explain.log_nested_statements=on