RDS PostgreSQL支持使用pg_squeeze插件,該插件提供了一種在線重新組織和清理表的功能,在不影響在線讀寫的前提下,減少表和索引占用的空間,提高空間利用率。
您可以加入RDS PostgreSQL插件交流釘釘群(103525002795),進行咨詢、交流和反饋,獲取更多關于插件的信息。
前提條件
背景信息
PostgreSQL使用MVCC(Multi-Version Concurrency Control)來允許多個事務同時讀取數據庫中的同一數據而不發生沖突。在此模型中,當數據被更新(UPDATE)或刪除(DELETE)時,原始數據不會被直接覆蓋或刪除,而是會被標記為死元組(dead tuple)。這些死元組對于新事務是不可見的,但是它們仍舊占據著磁盤空間,導致了表的膨脹。
使用autovacuum
等方式清理完死元組后,表膨脹并不會完全消失,因為死元組之前占用的空間并未立即被重新使用。當這些空閑空間非常多時,也會引起表膨脹。目前社區提供了vacuum full
命令來回收這些空閑空間,然而這一操作會使用最高級別的互斥鎖來鎖定表,導致在vacuum full
期間無法訪問該表。
功能介紹
pg_squeeze插件通過創建表的一個壓縮副本來重建表,可以去除表中未使用的磁盤空間,具有如下優勢:
在線清理,不阻塞讀寫。
無需通過客戶端,直接執行SQL即可操作。
應用場景
對表進行了頻繁的增刪改操作,導致表的膨脹率較高。
通過以下SQL語句,可以檢測表的膨脹率:
CREATE EXTENSION pgstattuple; --create extension
select *, 1.0 - tuple_len::numeric / table_len as bloat from pgstattuple('your_relation');
表膨脹率指表中未使用空間占總空間的比例,計算方式為:
1 - 活元組空間/表的總空間
。執行此操作會進行全表掃描。
注意事項
被清理的表必須具備唯一鍵。
執行清理時會消耗大量的IO,建議在業務低峰期運行。
創建和刪除插件
創建插件:
CREATE EXTENSION pg_squeeze;
說明如果需要清理多個數據庫下的表,需要在每個目標數據庫中創建該插件。
刪除插件:
DROP EXTENSION pg_squeeze;
使用示例
清理前,需要在目標數據庫中創建插件。
臨時清理
例如,清理public schema下的表bar
。
SELECT squeeze.squeeze_table('public', 'bar');
自動檢測并清理
創建自動清理任務。
例如,在每周三和周五的22:30,自動清理public schema下的表
foo
。說明創建自動清理任務的詳細語法請參見pg_squeeze。
只能清理當前數據庫下的表。
INSERT INTO squeeze.tables (tabschema, tabname, schedule) VALUES ('public', 'foo', ('{30}', '{22}', NULL, NULL, '{3, 5}'));
開啟自動清理任務。
手動開啟自動清理任務
執行以下SQL手動開啟自動清理任務,只能清理當前數據庫下的表。
SELECT squeeze.start_worker(); -- 開啟
關閉自動清理任務。
SELECT squeeze.stop_worker(); -- 關閉
自動開啟自動清理任務
在RDS控制臺配置參數并重啟數據庫,自動開啟清理任務。配置參數的詳細操作請參見設置實例參數。
例如,以rds_superuser的身份(必須是高權限用戶)清理數據庫
database1
和database2
:說明清理前,已分別在數據庫
database1
和database2
中創建了pg_squeeze插件,詳情請參見創建和刪除插件。squeeze.worker_autostart = 'database1 database2' squeeze.worker_role = rds_superuser
相關文檔
更多信息請參見pg_squeeze。