PostgreSQL 19 用 REPACK 統一 VACUUM FULL 與 CLUSTER,Beta 4 同時撤回四項已定案功能
PostgreSQL Global Development Group · 2026-09-24
PostgreSQL 19 新增的 REPACK 指令,把長年並存、功能重疊卻命名各異的 VACUUM FULL 與 CLUSTER 合併成一個指令,並補上兩者過去都沒有的 CONCURRENTLY 選項,可以在不鎖死讀寫的情況下重整表格。這是 PostgreSQL 19 Beta 4 於 2026 年 9 月 24 日由 PostgreSQL Global Development Group 釋出時公告的變動之一,同一份公告也宣布撤回四項原本已合併進主線的功能。
核心改動:REPACK 取代 VACUUM FULL 與 CLUSTER
原本的問題在於,VACUUM FULL 重寫整張表以釋放磁碟空間,CLUSTER 依索引順序重新排列資料列,兩者做的事情高度重疊,卻各自要記一套指令、鎖定行為與磁碟需求;更麻煩的是兩者都得取得 ACCESS EXCLUSIVE 鎖,執行期間整張表完全不能讀寫,大表在正式環境幾乎排不進維護窗口。release notes 原文寫道:「The two former commands did similar things, but with confusing names, so unify them as REPACK. The old commands have been retained for compatibility.」
新指令由 Antonin Houska、Mihail Nikalayeu、Álvaro Herrera 開發,CONCURRENTLY 選項是這次改動的重點,可以在不阻擋讀寫的前提下完成表格重整,並新增伺服器變數 max_repack_replication_slots 控制搭配用的複製槽上限。
-- PostgreSQL 18 及更早
VACUUM FULL orders; -- 釋放空間,整表鎖死
CLUSTER orders USING orders_pkey; -- 依索引重排,同樣整表鎖死
-- PostgreSQL 19
REPACK orders; -- 等同舊的 VACUUM FULL
REPACK orders USING INDEX orders_pkey; -- 等同舊的 CLUSTER
REPACK CONCURRENTLY orders; -- 新增:不鎖讀寫完成重整autovacuum 從隱性排序改成顯性計分
舊版 autovacuum 要決定先處理哪張表,靠的是內部隱性的啟發式規則,DBA 很難預測、更難調整「為什麼這張大表一直排不到」的順序問題,尤其是多張表同時逼近 freeze 門檻時。PG19 新增了一套計分系統,依 freeze、multixact freeze、vacuum 需求、insert 活動、analyze 需求分別給權重再排出處理順序,由 Nathan Bossart 開發,並新增五個對應的 GUC:autovacuum_freeze_score_weight、autovacuum_multixact_freeze_score_weight、autovacuum_vacuum_score_weight、autovacuum_vacuum_insert_score_weight、autovacuum_analyze_score_weight。同一批改動也讓 autovacuum 能用平行 worker 處理一張表的多個索引。
| 項目 | PostgreSQL 18 以前 | PostgreSQL 19 |
|---|---|---|
| 表格處理順序 | 內部隱性啟發式,無法調整 | 五種權重計分,可用 GUC 調整 |
| 索引 vacuum | 單一 worker 依序處理 | 可用平行 worker 處理多個索引 |
release notes 同時列出「Improve performance of foreign key constraint checks」(Junwang Zhao、Amit Langote、Chao Li),但沒有說明改動細節,只確認外鍵約束檢查的效能有提升。
影響範圍:Beta 4 也撤回了四項原本已定案的功能
正在 Beta 環境測試 PostgreSQL 19 的團隊要特別注意:Beta 4 公告列出四項原本已合併進主線、這次整批撤回的功能——SQL/PGQ 屬性圖查詢、線上啟用停用 data checksums、FOR PORTION OF 時態更新刪除,以及 ALTER TABLE ... MERGE PARTITIONS / SPLIT PARTITIONS。如果已經在評估或試用這幾項,19 正式版不會出現它們。同一批公告也移除了三個函式:pg_get_role_ddl()、pg_get_tablespace_ddl()、pg_get_database_ddl(),Beta 期間若測試腳本用到這三個函式取 DDL,升級後會直接報錯,得改用其他方式取得。
對計畫用 REPACK CONCURRENTLY 的團隊,該檢查複製拓樸下 max_repack_replication_slots 的預設值是否足夠;對 freeze 或 insert 密集的大表,值得重新檢視五個新的 *_score_weight GUC 是否要從預設值調整,而不是等正式版上線才發現排程順序變了。
原始來源:PostgreSQL 19 Beta 4 Released!、PostgreSQL 19 Release Notes