PostgreSQL10基礎(6)Analyze和Vacuum

參考文檔

  • https://www.postgresql.org/docs/10/sql-analyze.html
  • https://www.postgresql.org/docs/10/routine-vacuuming.html
  • https://www.postgresql.org/docs/10/sql-vacuum.html
  • https://www.postgresql.org/docs/10/runtime-config-autovacuum.html
  • https://www.postgresql.org/docs/10/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST

Analyze

Analyze命令用於統計數據庫表數據,統計結果存儲到pg_statistic系統表中。數據庫進行基於成本的優化(CBO)時通過統計數據優化SQL語句的解釋計劃。

命令

ANALYZE [ VERBOSE ] [ table_name [ ( column_name [, ...] ) ] ]
  • VERBOSE:顯示處理信息
  • table_name:指定分析的表,如果未指定將分析當前數據庫(邏輯庫)中所有常規表、分區表、物化視圖。分區表及其子表將被分析
  • column_name:指定分析的列名,可以用逗號分割多列,默認對所有列分析

權限說明

  • 表的所有者或者超級用戶可以執行analyze命令
  • 數據庫所有者也可以分析庫中的所有表
  • 不具備權限的表將被跳過分析

影響

Analyze只需要獲取一個read鎖,不會影響表的正常讀寫。

統計量

analyze默認統計most_common_vals(最常見值)和histogram_bounds(區間內含有相似數據條數的值列表)100個

可以通過設置全局變量default_statistics_target修改統計信息量(默認值100)

可以通過alter table XX alter column XX set STATISTICS 來設置每個列的統計量,值在0-10000之間,-1表示使用default_statistics_target值

建議

大量讀的數據庫可以每天在低負載時運行Analyze(大量更新活動將不夠頻繁)

Vacuum

Vacuum用於清理死亡元組佔用的存儲空間,默認刪除或因更新過期(爲了MVVC)的元組不會被物理刪除。因此需要週期性的進行Vacuum,尤其是頻繁更新的表

命令

VACUUM [ ( { FULL | FREEZE | VERBOSE | ANALYZE | DISABLE_PAGE_SKIPPING } [, ...] ) ] [ table_name [ (column_name [, ...] ) ] ]
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ table_name ]
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ table_name [ (column_name [, ...] ) ] ]
  • FULL:
    • 不加full時,Vacuum標記過期磁盤空間爲可用,用於該表以後重用,但磁盤不會釋放給操作系統,執行Vacuum操作不會影響表的讀寫。
    • 加full時,Vacuum將表數據複製到另外一塊磁盤空間,負責完成後刪除老的磁盤空間。老空間將被釋放給操作系統,但需要足夠的磁盤空間才能完成操作。且操作執行時添加exclusive lock在表上,表將無法正常讀寫。
  • ANALYZE:同時執行Vacuum和analyze
  • VERBOSE:顯示處理信息
  • table_name:如果未指定將清掃當前數據庫(邏輯庫)中所有常規表、分區表、物化視圖。分區表及其子表將被清掃。
  • column_name:指定分析的列名,可以用逗號分割多列,默認對所有列分析
  • FREEZE和DISABLE_PAGE_SKIPPING在此不做詳細介紹

權限說明

  • 表的所有者或者超級用戶可以執行vacuum命令
  • 數據庫所有者也可以清掃庫中的所有表
  • 不具備權限的表將被跳過清掃

影響

FULL會影響表的正常讀寫。

建議

  • 生產數據庫建議頻繁Vacuum(至少每晚)以清理死亡行。
  • 大量添加或刪除行後建議進行VACUUM ANALYZE
  • FULL不建議日常使用,因爲會縮表,但可以降低磁盤佔用
  • Vacuum會消耗IO,可以使用基於消耗的Vacuum延遲功能

Cost-based Vacuum Delay

當執行Vacuum和analyze時,系統維護一個內部計數器記錄消耗的IO。當消耗達到acuum_cost_limit時,將停止執行命令vacuum_cost_delay毫秒,然後重新計數。

此功能的目的是降低Vacuum和Analyze操作對系統的性能影響。默認功能關閉,可以設置vacuum_cost_delay大於0開啓

  • vacuum_cost_delay:單位毫秒,vacuum休眠時長,默認爲0,將禁用此功能。設置爲大於0值將開啓功能。建議設置爲10或20.
  • vacuum_cost_page_hit:vacuum命中shared buffer緩存,並鎖定緩存的成本,默認爲1
  • vacuum_cost_page_miss:當Vacuum必須讀取磁盤時的成本,默認爲10
  • vacuum_cost_page_dirty: 當vacuum修改block的成本,默認20
  • vacuum_cost_limit:vacuum觸發休眠的成本,默認200。

自動清理和自動分析

參數

  • autovacuum:布爾值,表示是否啓用自動清掃進程,默認打開。但當track_count(默認開啓)也被開啓時才能啓用
  • log_autovacuum_min_duration: 整型,自動掃描被記錄的最少耗時(毫秒),設置爲0將記錄所有自動清掃操作。默認爲-1,禁用日誌記錄。
  • autovacuum_max_workers:設置自動清掃進程的最大數量,默認爲3.
  • autovacuum_naptime:設置在一個數據庫上執行兩次自動清掃動作的最小間隔時間,單位爲秒,默認60
  • autovacuum_vacuum_threshold:設置在一張表上觸發Vacuum操作的最小更新或刪除元組數,默認50
  • autovacuum_analyze_threshold:設置在一張表上觸發analyze操作的最小更新或刪除元組數,默認50
  • autovacuum_vacuum_scale_factor:設置在一張表上觸發Vacuum操作的最小變更百分比,默認0.2(表有20%的變動),可以設置系統級參數,也可以爲每張表設置獨立值。
  • autovacuum_analyze_scale_factor:設置在一張表上觸發analyze操作的最小變更百分比,默認0.1(表有10%的變動),可以設置系統級參數,也可以爲每張表設置獨立值。
  • autovacuum_vacuum_cost_delay:設置基於成本的延遲,單位毫秒,如果值爲-1,則使用vacuum_cost_delay值,默認爲20。可以設置系統級參數,也可以爲每張表設置獨立值。
  • autovacuum_vacuum_cost_limit:觸發延遲的成本數,默認爲-1,表示使用vacuum_cost_limit值。可以設置系統級參數,也可以爲每張表設置獨立值。

另外自動清理還將清理事務ID,防止其超過最大值。該清理無法被關閉。

觸發條件

  • autovacuum和track_count都被打開
  • 清掃條件:元組增刪改數量>autovacuum_analyze_threshold + autovacuum_vacuum_scale_factor * 總元祖數
  • 自動分析條件: 元組增刪改數量>autovacuum_analyze_threshold + autovacuum_analyze_scale_factor * 總元祖數

進程

數據庫將自動每隔autovacuum_naptime秒在每一個邏輯庫啓動一個進程,但總數不能大於autovacuum_max_workers,如果有等待處理的數據庫,進程將在處理完一個庫後立即處理下一個。

每個進程都將檢查數據庫中每張表,判斷是否需要執行vacuum和/或analyze

執行情況

歷史執行視圖pg_stat_all_tables

select relid,schemaname,relname,last_vacuum,vacuum_count,last_autovacuum,autovacuum_count,last_analyze,analyze_count,last_autoanalyze,autoanalyze_count from pg_stat_all_tables

每張表一條記錄

  • last_vacuum:上次手動vacuum時間
  • vacuum_count:總計手動vacuum次數
  • last_autovacuum:上次自動vacuum時間
  • autovacuum_count:總計自動vacuum次數
  • last_analyze:上次手動analyze時間
  • analyze_count:總計手動analyze次數
  • last_autoanalyze:上次自動analyze時間
  • autoanalyze_count:總計自動analyze次數

該視圖還有其他有助於性能分析的字段

  • seq_scan:順序掃描次數
  • seq_tup_read:順序掃描讀取的存活行數
  • idx_scan:索引掃描次數
  • idx_tup_read:索引掃描讀取的存活行數
  • n_tup_ins:插入的行數
  • n_tup_upd:更新的行數
  • n_tup_del:刪除的行數
  • n_live_tup:存活行數
  • n_dead_tup:死亡行數
  • n_mod_since_analyze:上次分析以來修改的行數

執行過程視圖pg_stat_progress_vacuum

9.6版本新增
字段說明:

  • pid:進程ID
  • datid:數據庫OID
  • datname: 數據庫名稱
  • relid:當前Vacuum的表ID
  • phrase:處理階段,見下文
  • heap_blks_total:表中總heap block數量
  • heap_blks_scanned:被掃描的數量,可用性視圖會協助跳過一部分block
  • heap_blks_vacuumed:完成清掃的數量
  • index_vacuum_count:完成索引清掃次數
  • max_dead_tuples:執行一次索引清掃前遇到的最大死亡元組數量,基於maintenance_work_mem.
  • num_dead_tuples:上次索引清掃後找到的死亡元組數量

階段說明

  • initializing:準備掃描heap
  • scanning heap:掃描heap,會對每個頁進行修剪和整理,可能執行凍結操作。heap_blks_scanned列可以觀察執行進度。如果維護內存不足,可能執行多次
  • vacuuming indexes:清掃索引。如果表有索引,將最少執行一次本動作。
  • vacuuming heap:清掃heap,每次清掃索引後進行
  • cleaning up indexes:清理索引。在所有heap掃描完成,所有索引和heap被vacuum完成後執行
  • truncating heap:縮減heap以歸還處於表最後位置的空頁面到操作系統。磁盤空閒將增大,但只有空頁面位於最後位置纔會被歸還
  • performing final cleanup:執行最後的清理,此階段將清理free space map,更新statistics視圖
graph LR
初始化-->掃描堆
掃描堆-->清理索引
清理索引-->清理堆
清理堆-->掃描堆
清理堆-->最終清理索引
最終清理索引-->縮減堆
縮減堆-->清理完成

總結

通過pg_stat_all_tables視圖發現默認設置下Vacuum和Analyze執行不夠頻繁,可以考慮定時每日清理+大量操作後清理,並通過延遲清理功能降低對生產系統性能影響

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章