本文介紹了VACUUM的簡介、語法以及示例等內容。
簡介
VACUUM
收回由死亡元組占用的存儲空間。在通常的操作中,被刪除或者被更新廢棄的元組并沒有在物理上從它們的表中移除,它們將一直存在直到一次VACUUM
被執行。因此有必要周期性地做VACUUM
,特別是在頻繁被更新的表上。
在沒有 table_and_columns
列表的情況下,VACUUM
會處理當前用戶具有清理權限的當前數據庫中的每一個表和物化視圖。如果給出一個列表,VACUUM
可以只處理列表中的那些表。
VACUUM ANALYZE
對每一個選定的表ANALYZE
。這是兩種命令的一種方便的組合形式,可以用于例行的維護腳本。其處理細節可參考 ANALYZE 。
簡單的 VACUUM
(不帶FULL
)簡單地收回空間并使其可以被重用。這種形式的命令可以和表的普通讀寫操作并行,因為它不會獲得一個排他鎖。但是,這種形式中額外的空間并沒有被還給操作系統(在大多數情況下),它僅僅被保留在同一個表中以備重用。它還允許我們利用多個 CPU 來處理索引。 此功能稱為parallel vacuum。要禁用此功能,可以使用PARALLEL
選項并將并行工作程序指定為零。VACUUM FULL
將表的整個內容重寫到一個新的磁盤文件中,并且不包含額外的空間,這使得沒有被使用的空間被還給操作系統。這種形式的命令更慢并且在其被處理時要求在每個表上保持一個排他鎖。
當選項列表被包圍在圓括號中時,選項可以被寫成任何順序。
語法
VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]
其中option可以是下列之一:
FULL [ boolean ]
FREEZE [ boolean ]
VERBOSE [ boolean ]
ANALYZE [ boolean ]
DISABLE_PAGE_SKIPPING [ boolean ]
SKIP_LOCKED [ boolean ]
INDEX_CLEANUP [ boolean ]
TRUNCATE [ boolean ]
PARALLEL integer
而table_and_columns是:
table_name [ ( column_name [, ...] ) ]
參數說明
FULL
選擇“完全”清理,它可以收回更多空間,并且需要更長時間和表上的排他鎖。這種方法還需要額外的磁盤空間,因為它會創建該表的一個新拷貝,并且在操作完成之前都不會釋放舊的拷貝。通常這種方法只用于需要從表中收回數量龐大的空間時。FREEZE
選擇激進的元組“凍結”。指定FREEZE
等價于參數 vacuum_freeze_min_age 和 vacuum_freeze_table_age 設置為 0 的VACUUM
。當表被重寫時總是會執行激進的凍結, 因此指定FULL
時這個選項是多余的。VERBOSE
為每個表打印一份詳細的清理活動報告。ANALYZE
更新優化器用以決定最有效執行一個查詢方法的統計信息。DISABLE_PAGE_SKIPPING
通常,VACUUM
將基于可見性映射跳過頁面。已知所有元組都被凍結的頁面總是會被跳過,而那些所有元組對所有事務都可見的頁面則可能會被跳過(除非執行的是激進的清理)。此外,除非在執行激進的清理時,一些頁面也可能會被跳過,這樣可避免等待其他頁面完成對其使用。這個選項禁用所有的跳過頁面的行為,其意圖是只在可見性映射內容被懷疑時使用,這種情況只有在硬件或者軟件問題導致數據庫損壞時才會發生。SKIP_LOCKED
規定VACUUM
在開始處理關系時不等待任何沖突鎖被釋放:如果關系不能立即鎖定而不等待,則跳過關系。 請注意即使采用此選項,VACUUM
在打開關系的索引時仍可能阻塞。 此外,VACUUM ANALYZE
在從分區、繼承子表和某些類型的外表獲取示例行時,仍然可能阻塞。 還有,雖然VACUUM
通常處理指定分區表的所有分區,但如果分區表上的鎖沖突, 此選項將導致VACUUM
跳過所有分區。INDEX_CLEANUP
規定VACUUM
嘗試刪除指向死元組的索引條目。 這通常是所需的行為,并且是默認行為,除非將vacuum_index_cleanup
選項設置為 false,對要被清空的表。 如果需要盡快運行清空操作的話,將此選項設置為 false 可能很有用,例如,為了避免即將發生的事務 ID 回繞[wraparound]。 但是,如果不定期執行索引清理,性能可能會受到影響,因為隨著表的修改,索引將累積死元組,并且表本身將累積死行指針,在索引清理完成之前都無法刪除。 此選項對于沒有索引的表無效,如果使用FULL
選項,則忽略此選項。TRUNCATE
指定VACUUM
嘗試截斷表末尾的任何空頁,并允許將截斷頁的磁盤空間返回到操作系統。 這通常是所需的行為,并且是默認行為,除非將vacuum_truncate
選項設置為 false,對要被清空的表。 將此選項設置為 false 可能有助于避免ACCESS EXCLUSIVE
鎖定需要截斷的表。如果使用FULL
選項,則忽略此選項。PARALLEL
使用integer
后臺處理器并行執行VACUUM
的索引真空和索引清理階段。 用于執行操作的處理器數量等于關系上支持并行清理的索引數量,該數量受PARALLEL
選項指定的工人數量的限制,如果有的話,該數量還受到max_parallel_maintenance_workers限制。 當且僅當索引的大小大于min_parallel_index_scan_size時,索引才能參與并行清理。 請注意,不保證在執行期間會使用integer
中指定的并行工作線程數。 清理運行時可能需要比指定的更少的處理器,甚至根本沒有處理器。每個索引只能使用一名處理器。 所以只有當表中至少有2
索引時才會啟動并行工作程序。 在每個階段開始之前啟動清理工作進程,并在階段結束時退出。這些行為可能會在未來的版本中發生變化。 此選項不能與FULL
選項一起使用。boolean
指定打開還是關閉所選選項。你可以寫入TRUE
、ON
或1
以啟用該選項,以及FALSE
、OFF
或0
來禁用它。 在TRUE
被假定的情況下,boolean
值也可以被省略。integer
指定傳遞給所選選項的非負整數值。table_name
要清理的表或物化視圖的名稱(可以有模式修飾)。如果指定的表是一個分區表,則它所有的葉子分區也會被清理。column_name
要分析地指定列的名稱。缺省是所有列。如果指定了一個列的列表,則ANALYZE
也必須被指定。
輸出
如果聲明了VERBOSE
,VACUUM
會發出進度消息來表明當前正在處理哪個表。各種有關這些表的統計信息也會打印出來。
說明
要清理一個表,操作者通常必須是表的擁有者或者超級用戶。但是,數據庫擁有者被允許清理他們的數據庫中除了共享目錄之外的所有表(對于共享目錄的限制意味著一個真正的數據庫范圍的VACUUM
只能被超級用戶執行)。VACUUM
將會跳過執行者不具備清理權限的表。
VACUUM
不能在一個事務塊內被執行。
對具有 GIN 索引的表,VACUUM
(任何形式)也會通過將待處理索引項移動到主要 GIN 索引結構中的合適位置來完成任何待處理的索引插入。
我們建議經常清理活動的生產數據庫(至少每晚一次),以保證移除失效的行。在增加或刪除了大量行之后, 對受影響的表執行VACUUM ANALYZE
命令是一個很好的做法。這樣做將把最近的更改更新到系統目錄,并且允許 PolarDB查詢規劃器在規劃用戶查詢時做出更好的選擇。
日常使用時,不推薦FULL
選項,但在特殊情況時它會有用。一個例子是當你刪除或者更新了一個表中的絕大部分行時,如果你希望在物理上收縮表以減少磁盤空間占用并且允許更快的表掃描,則該選項是比較合適的。VACUUM FULL
通常會比簡單VACUUM
更多地收縮表。
PARALLEL
選項僅用于清理目的。如果此選項與ANALYZE
選項一起指定,則不會影響ANALYZE
。
VACUUM
會導致 I/O 流量的大幅度增加,這可能導致其他活動會話性能變差。因此,有時建議使用基于代價的清理延遲特性。 對于并行清理,每個處理器的睡眠與該處理器完成的工作成比例。
PolarDB包括了一個“autovacuum”工具,它可以自動進行例行的清理維護。
示例
清理單一表onek
,為優化器分析它并且打印出詳細的清理活動報告:
VACUUM (VERBOSE, ANALYZE) onek;