PostgreSQL技術大講堂 - 第18講:Tuning Autovacuum
最新學訊:近期OCP認證正在報名中,因考試人員較多請盡快報名獲取最近考試時間,報名費用請聯系在線老師,甲骨文官方認證,報名從速!
我要咨詢
PostgreSQL從小白到專家,是從入門逐漸能力提升的一個系列教程,內容包括對PG基礎的認知、包括安裝使用、包括角色權限、包括維護管理、、等內容,希望對熱愛PG、學習PG的同學們有幫助,歡迎持續關注CUUG PG技術大講堂。
Part 18:Vacuum空間管理工具
內容1:什么是 autovacuum?
內容2:為什么需要 autovacuum?
內容3:調整Autovacuum
內容4:記錄autovacuum
內容5:什么時候在表上做autovacuum?
什么是 autovacuum?
Autovacuum是啟動PostgreSQL時自動啟動的后臺實用程序進程之一
在生產系統中不應該將其設置為關閉
autovacuum = on # ( ON by default )
track_counts = on # ( ON by default )
為什么需要 autovacuum?
需要vacuum來移除死元組
防止死元組膨脹
更新表的統計信息進行分析,以便提供優化器使用
autovacuum launcher使用Stats Collector的后臺進程收集的信息來確定autovacuum的候選表列表
記錄autovacuum
log_autovacuum_min_duration
-1 :表示不記錄
0 :表示記錄所有的
'250ms' # Or 1s, 1min, 1h, 1d :表示記錄真空操作時間大于此值的操作
什么時候做autovacuum?
1、Autovacuum操作的實際內容:1)vacuum; 2)Analyze
2、Autovacuum vacuum觸發條件(如果由于更新和刪除,表中的實際死元組數超過此有效閾值,則該表將成為autovacuum的候選表):
Autovacuum VACUUM thresold for a table = autovacuum_vacuum_scale_factor * number of tuples + autovacuum_vacuum_threshold
3、Autovacuum ANALYZE觸發條件(自上次分析以來插入/刪除/更新總數超過此閾值的任何表都有資格進行autovacuum分析)
Autovacuum ANALYZE threshold for a table = autovacuum_analyze_scale_factor * number of tuples + autovacuum_analyze_threshold
舉個栗子:
Employee = 1000行
以上述數學公式為參考:
Table:employee成為autovacuum Vacuum的候選者,當下面的條件滿足時:
Total number of Obsolete records = (0.2 * 1000) + 50 = 250
Table:employee 成為 autovacuum ANALYZE 候選者,當下面的條件滿足時:
Total number of Inserts/Deletes/Updates = (0.1 * 1000) + 50 = 150
Is A Problem?
· 這是不是一個問題?
1:Table1= 100行
其觸發分析和vacuum的閾值分別是:60和70
2:Table2=100萬行
其觸發分析和vacuum的閾值分別是:100050和200050
如果兩張表都做同樣數量的dml操作,T1 觸發Autovacuum是T2的2857倍!!!
pg_stat_user_tables
· 如何確定需要調整其autovacuum setting的表?
為了單獨調整表的autovacuum,必須知道一段時間內表上的插入/刪除/更新數。
SELECT n_tup_ins as "inserts",n_tup_upd as "updates",n_tup_del as "deletes",n_live_tup as "live_tuples", n_dead_tup as "dead_tuples"
FROM pg_stat_user_tables
WHERE schemaname = 'scott' and relname = 'employee';
inserts | updates | deletes | live_tuples | dead_tuples
---------+---------+---------+-------------+-------------
30 | 40 | 9 | 21 | 49
表autovacuum setting的設置
可以通過設置單個表的存儲參數來重寫此行為,這樣會忽略全局設置。
postgres=# alter table percona.employee set (autovacuum_vacuum_threshold = 100);
postgres=# alter table percona.employee set (autovacuum_vacuum_scale_factor=0);
postgres=#
postgres=# \d+ percona.employee
Table "percona.employee"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+---------+--------------+-------------
id | integer | | | | plain | |
Options: autovacuum_vacuum_threshold=100, autovacuum_vacuum_scale_factor = 0
只要有超過100條過時的記錄,運行autovacuum vacuum.
autovacuum_max_workers
· 一次可以運行多少個autovacuum過程
1、在可能包含多個數據庫的實例/群集上,一次運行的autovacuum進程數不能超過下面參數設置的值:
autovacuum_max_workers = 3 (Default)
2、啟動下一個autovacuum之前的等待時間:
autovacuum_naptime= 1min
(autovacuum_naptime/N)
其中N是實例中數據庫的總數
· 真空IO是密集型的嗎?
1、autovacuum可以看作是一種清潔工作
2、是一個IO密集型操作
3、設置了一些參數來最小化真空對IO的影響· 以下是用于調整autovacuumIO的參數
autovacuum_vacuum_cost_limit : autovacuum可達到的總成本限制(結合所有autovacuum作業)
autovacuum_vacuum_cost_delay : 當一個清理工作達到autovacuum_vacuum_cost_limit指定的成本限制時,autovacuum將休眠數毫秒
vacuum_cost_page_hit : 讀取已在共享緩沖區中且不需要磁盤讀取的頁的成本.
vacuum_cost_page_miss : 獲取不在共享緩沖區中的頁的成本.
vacuum_cost_page_dirty : 在每一頁中發現死元組時寫入該頁的成本.
上面參數默認的值考慮如下:
autovacuum_vacuum_cost_limit = -1 (So, it defaults to vacuum_cost_limit) = 200
autovacuum_vacuum_cost_delay = 20ms
vacuum_cost_page_hit = 1
vacuum_cost_page_miss = 10
vacuum_cost_page_dirty = 20
· 讓我們想象一下1秒后會發生什么。(1秒=1000毫秒)
在讀取延遲為0毫秒的最佳情況下,autovacuum可以喚醒并進入睡眠50次(1000毫秒/20毫秒),因為喚醒之間的延遲需要20毫秒。
1 second = 1000 milliseconds = 50 * autovacuum_vacuum_cost_delay
由于在共享緩沖區中每次讀取一個頁面的相關成本是1,因此在每個喚醒中可以讀取200個頁面(因為上面把總成本限制設置為200),在50個喚醒中可以讀取50*200個頁面。
如果在共享緩沖區中找到了所有具有死元組的頁,并且autovacuum代價延遲為20毫秒,則它可以在每一輪中讀取:((200/ vacuum_cost_page_hit)*8)KB,這需要等待autovacuum代價延遲時間量。
因此,考慮到塊大小為8192字節,autovacuum最多可以讀取:50*200*8kb=78.13mb/s(如果在共享緩沖區中已經找到塊)。
如果塊不在共享緩沖區中,需要從磁盤提取,則autovacuum可以讀取:50*(200/ vacuum_cost_page_miss)*8)KB=7.81 MB/秒。
現在,為了從頁/塊中刪除死元組,寫操作的開銷是:vacuum_cost_page_dirty,默認設置為20
一個auto vacuum每秒最多可以寫/臟:50*(200/ vacuum_cost_page_dirty)*8)KB=3.9mb/秒。
· 謹慎設置autovacuum_max_workers
通常, autovacuum_vacuum_cost_limit成本平均分配給實例中運行的所有autovacuum過程的autovacuum_max_workers數。
因此,增加autovacuum_max_workers可能會延遲當前運行的autovacuum workers的autovacuum執行。
而增加autovacuum_vacuum_cost_limit可能會導致IO瓶頸。
可以通過設置單個表的存儲參數來重寫此行為,這樣會忽略全局設置。

以上就是Part 18 - Tuning Autovacuum 的內容,往期視頻,聯系cuug咨詢老師,歡迎進群一起探討交流QQ客服:2036105272 PG交流群釘釘交流群:35822460