PostgreSQL VACUUM

2021-09-13 15:20 更新

VACUUM — 垃圾收集并根據(jù)需要分析一個(gè)數(shù)據(jù)庫(kù)

大綱

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 [, ...] ) ]

描述

VACUUM收回由死亡元組占用的存儲(chǔ)空間。在通常的PostgreSQL操作中,被刪除或者被更新廢棄的元組并沒(méi)有在物理上從它們的表中移除,它們將一直存在直到一次VACUUM被執(zhí)行。因此有必要周期性地做VACUUM,特別是在頻繁被更新的表上。

在沒(méi)有table_and_columns列表的情況下,VACUUM會(huì)處理當(dāng)前用戶具有清理權(quán)限的當(dāng)前數(shù)據(jù)庫(kù)中的每一個(gè)表和物化視圖。如果給出一個(gè)列表,VACUUM可以只處理列表中的那些表。

VACUUM ANALYZE對(duì)每一個(gè)選定的表ANALYZE。這是兩種命令的一種方便的組合形式,可以用于例行的維護(hù)腳本。其處理細(xì)節(jié)可參考ANALYZE。

簡(jiǎn)單的 VACUUM(不帶FULL)簡(jiǎn)單地收回空間并使其可以被重用。這種形式的命令可以和表的普通讀寫操作并行,因?yàn)樗粫?huì)獲得一個(gè)排他鎖。但是,這種形式中額外的空間并沒(méi)有被還給操作系統(tǒng)(在大多數(shù)情況下),它僅僅被保留在同一個(gè)表中以備重用。它還允許我們利用多個(gè) CPU 來(lái)處理索引。 此功能稱為parallel vacuum。要禁用此功能,可以使用 PARALLEL選項(xiàng)并將并行工作程序指定為零。VACUUM FULL將表的整個(gè)內(nèi)容重寫到一個(gè)新的磁盤文件中,并且不包含額外的空間,這使得沒(méi)有被使用的空間被還給操作系統(tǒng)。這種形式的命令更慢并且在其被處理時(shí)要求在每個(gè)表上保持一個(gè)排他鎖。

當(dāng)選項(xiàng)列表被包圍在圓括號(hào)中時(shí),選項(xiàng)可以被寫成任何順序。如果沒(méi)有圓括號(hào),選項(xiàng)必須嚴(yán)格按照上面所展示的順序指定。有圓括號(hào)的語(yǔ)法在PostgreSQL 9.0時(shí)被加入,無(wú)圓括號(hào)的語(yǔ)法則被廢棄。

參數(shù)

FULL

選擇完全清理,它可以收回更多空間,并且需要更長(zhǎng)時(shí)間和表上的排他鎖。這種方法還需要額外的磁盤空間,因?yàn)樗鼤?huì)創(chuàng)建該表的一個(gè)新拷貝,并且在操作完成之前都不會(huì)釋放舊的拷貝。通常這種方法只用于需要從表中收回?cái)?shù)量龐大的空間時(shí)。

FREEZE

選擇激進(jìn)的元組凍結(jié)。指定FREEZE 等價(jià)于參數(shù)vacuum_freeze_min_agevacuum_freeze_table_age設(shè)置為0的 VACUUM。當(dāng)表被重寫時(shí)總是會(huì)執(zhí)行激進(jìn)的凍結(jié), 因此指定FULL時(shí)這個(gè)選項(xiàng)是多余的。

VERBOSE

為每個(gè)表打印一份詳細(xì)的清理活動(dòng)報(bào)告。

ANALYZE

更新優(yōu)化器用以決定最有效執(zhí)行一個(gè)查詢的方法的統(tǒng)計(jì)信息。

DISABLE_PAGE_SKIPPING

通常,VACUUM將基于可見性映射跳過(guò)頁(yè)面。已知所有元組都被凍結(jié)的頁(yè)面總是會(huì)被跳過(guò),而那些所有元組對(duì)所有事務(wù)都可見的頁(yè)面則可能會(huì)被跳過(guò)(除非執(zhí)行的是激進(jìn)的清理)。此外,除非在執(zhí)行激進(jìn)的清理時(shí),一些頁(yè)面也可能會(huì)被跳過(guò),這樣可避免等待其他頁(yè)面完成對(duì)其使用。這個(gè)選項(xiàng)禁用所有的跳過(guò)頁(yè)面的行為,其意圖是只在可見性映射內(nèi)容被懷疑時(shí)使用,這種情況只有在硬件或者軟件問(wèn)題導(dǎo)致數(shù)據(jù)庫(kù)損壞時(shí)才會(huì)發(fā)生。

SKIP_LOCKED

規(guī)定VACUUM在開始處理關(guān)系時(shí)不等待任何沖突鎖被釋放:如果關(guān)系不能立即鎖定而不等待,則跳過(guò)關(guān)系。 請(qǐng)注意即使采用此選項(xiàng),VACUUM在打開關(guān)系的索引時(shí)仍可能阻塞。 此外,VACUUM ANALYZE在從分區(qū)、繼承子表和某些類型的外表獲取示例行時(shí),仍然可能阻塞。 還有,雖然VACUUM通常處理指定分區(qū)表的所有分區(qū),但如果分區(qū)表上的鎖沖突, 此選項(xiàng)將導(dǎo)致VACUUM跳過(guò)所有分區(qū)。

INDEX_CLEANUP

規(guī)定VACUUM嘗試刪除指向死元組的索引條目。 這通常是所需的行為,并且是默認(rèn)行為,除非將vacuum_index_cleanup 選項(xiàng)設(shè)置為 false,對(duì)要被清空的表。 如果需要盡快運(yùn)行清空操作的話,將此選項(xiàng)設(shè)置為 false 可能很有用,例如,為了避免即將發(fā)生的事務(wù) ID 回繞[wraparound](請(qǐng)參閱 第 24.1.5 節(jié))。 但是,如果不定期執(zhí)行索引清理,性能可能會(huì)受到影響,因?yàn)殡S著表的修改,索引將累積死元組,并且表本身將累積死行指針,在索引清理完成之前都無(wú)法刪除。 此選項(xiàng)對(duì)于沒(méi)有索引的表無(wú)效,如果使用 FULL 選項(xiàng),則忽略此選項(xiàng)。

TRUNCATE

指定VACUUM嘗試截?cái)啾砟┪驳娜魏慰枕?yè),并允許將截?cái)囗?yè)的磁盤空間返回到操作系統(tǒng)。 這通常是所需的行為,并且是默認(rèn)行為,除非將vacuum_truncate選項(xiàng)設(shè)置為 false,對(duì)要被清空的表。 將此選項(xiàng)設(shè)置為 false 可能有助于避免ACCESS EXCLUSIVE鎖定需要截?cái)嗟谋?。如果使?code class="literal">FULL選項(xiàng),則忽略此選項(xiàng)。

PARALLEL

使用integer后臺(tái)處理器并行執(zhí)行VACUUM 的索引真空和索引清理階段(每個(gè)真空階段的詳細(xì)信息請(qǐng)參考表 27.37))。 用于執(zhí)行操作的處理器數(shù)量等于關(guān)系上支持并行清理的索引數(shù)量,該數(shù)量受 PARALLEL選項(xiàng)指定的工人數(shù)量的限制,如果有的話,該數(shù)量還受到max_parallel_maintenance_workers限制。 當(dāng)且僅當(dāng)索引的大小大于min_parallel_index_scan_size時(shí),索引才能參與并行清理。 請(qǐng)注意,不保證在執(zhí)行期間會(huì)使用integer中指定的并行工作線程數(shù)。 清理運(yùn)行時(shí)可能需要比指定的更少的處理器,甚至根本沒(méi)有處理器。每個(gè)索引只能使用一名處理器。 所以只有當(dāng)表中至少有2索引時(shí)才會(huì)啟動(dòng)并行工作程序。 在每個(gè)階段開始之前啟動(dòng)清理工作進(jìn)程,并在階段結(jié)束時(shí)退出。這些行為可能會(huì)在未來(lái)的版本中發(fā)生變化。 此選項(xiàng)不能與FULL選項(xiàng)一起使用。

boolean

指定打開還是關(guān)閉所選選項(xiàng)。你可以寫入TRUE、ON1以啟用該選項(xiàng),以及FALSEOFF0來(lái)禁用它。 在TRUE被假定的情況下, boolean 值也可以被省略。

integer

指定傳遞給所選選項(xiàng)的非負(fù)整數(shù)值。

table_name

要清理的表或物化視圖的名稱(可以有模式修飾)。如果指定的表示一個(gè)分區(qū)表,則它所有的葉子分區(qū)也會(huì)被清理。

column_name

要分析的指定列的名稱。缺省是所有列。如果指定了一個(gè)列的列表,則ANALYZE也必須被指定。

輸出

如果聲明了VERBOSEVACUUM會(huì)發(fā)出進(jìn)度消息來(lái)表明當(dāng)前正在處理哪個(gè)表。各種有關(guān)這些表的統(tǒng)計(jì)信息也會(huì)打印出來(lái)。

注意

要清理一個(gè)表,操作者通常必須是表的擁有者或者超級(jí)用戶。但是,數(shù)據(jù)庫(kù)擁有者被允許清理他們的數(shù)據(jù)庫(kù)中除了共享目錄之外的所有表(對(duì)于共享目錄的限制意味著一個(gè)真正的數(shù)據(jù)庫(kù)范圍的VACUUM只能被超級(jí)用戶執(zhí)行)。VACUUM將會(huì)跳過(guò)執(zhí)行者不具備清理權(quán)限的表。

VACUUM不能在一個(gè)事務(wù)塊內(nèi)被執(zhí)行。

對(duì)具有GIN索引的表,VACUUM(任何形式)也會(huì)通過(guò)將待處理索引項(xiàng)移動(dòng)到主要GIN索引結(jié)構(gòu)中的合適位置來(lái)完成任何待處理的索引插入。詳見第 66.4.1 節(jié)。

我們建議經(jīng)常清理活動(dòng)的生產(chǎn)數(shù)據(jù)庫(kù)(至少每晚一次),以保證移除失效的行。在增加或刪除了大量行之后, 對(duì)受影響的表執(zhí)行VACUUM ANALYZE命令是一個(gè)很好的做法。這樣做將把最近的更改更新到系統(tǒng)目錄,并且允許 PostgreSQL查詢規(guī)劃器在規(guī)劃用戶查詢時(shí)做出更好的選擇。

日常使用時(shí),不推薦FULL選項(xiàng),但在特殊情況時(shí)它會(huì)有用。一個(gè)例子是當(dāng)你刪除或者更新了一個(gè)表中的絕大部分行時(shí),如果你希望在物理上收縮表以減少磁盤空間占用并且允許更快的表掃描,則該選項(xiàng)是比較合適的。VACUUM FULL通常會(huì)比簡(jiǎn)單VACUUM更多地收縮表。

PARALLEL選項(xiàng)僅用于清理目的。如果此選項(xiàng)與ANALYZE選項(xiàng)一起指定,則不會(huì)影響ANALYZE。

VACUUM會(huì)導(dǎo)致I/O流量的大幅度增加,這可能導(dǎo)致其他活動(dòng)會(huì)話性能變差。因此,有時(shí)建議使用基于代價(jià)的清理延遲特性。 對(duì)于并行清理,每個(gè)處理器的睡眠與該處理器完成的工作成比例。詳情請(qǐng)參閱第 19.4.4 節(jié)。

PostgreSQL包括了一個(gè)autovacuum工具,它可以自動(dòng)進(jìn)行例行的清理維護(hù)。關(guān)于自動(dòng)和手動(dòng)清理的更多信息請(qǐng)見第 24.1 節(jié)。

例子

清理單一表onek,為優(yōu)化器分析它并且打印出詳細(xì)的清理活動(dòng)報(bào)告:

VACUUM (VERBOSE, ANALYZE) onek;

兼容性

在SQL標(biāo)準(zhǔn)中沒(méi)有VACUUM語(yǔ)句。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)