表膨胀处理

最近更新时间:2025-09-29 16:33:32

我的收藏
云数据库 PostgreSQL 支持通过插件 pg_repack 在线清理表空间,有效解决因对全表大量更新等操作引起的表膨胀问题。与 CLUSTERVACUUM 不同,pg_repack 在线运行,处理过程中无需在已处理的表上持有独占锁,同时 pg_repack 启动效率高,性能与直接使用 CLUSTER 相当。本文将详细介绍如何通过 pg_repack 处理表膨胀。更多的 pg_repack 使用场景请参考 官方文档
注意:
pg_repack 需要额外的存储空间。全表 repack 时,剩余存储空间大小需要至少是待 repack 表大小的2倍,请提前升级云数据库 PostgreSQL 实例配置。
pg_repack 无法操作临时表、无法操作 GiST 索引。
pg_repack 运行时会持有 ACCESS SHARE 锁,无法对 repack 操作中的表执行 DDL。
重建表和索引时会占用较多的磁盘 IO,请在业务低峰期执行。
目标表必须具有 PRIMARY KEY,或者至少在 NOT NULL 列上具有 UNIQUE 总索引。

前置条件

已有一个云数据库 PostgreSQL 实例,创建请参考 创建 PostgreSQL 实例
该实例已安装 pg_repack 插件,安装请参考 如何在云数据库 PostgreSQL 实例中创建插件
已有一台云服务器 CVM ,该云服务器跟云数据库 PostgreSQL 实例在同一个 VPC 网络。Linux 系统的云服务器配置请参见 快速配置 Linux 云服务器
云服务器 CVM 实例已安装 psql 客户端,详细安装教程请参考 PostgreSQL 官方文档

安装客户端

使用之前请先在云服务器上安装客户端,点击 安装包下载地址,并上传安装包进行安装。
unzip pg_repack-1.5.2.zip
cd pg_repack-1.5.2
make && make install

清理单表

-- 检查但不执行
pg_repack -k --dry-run --no-order -h 10.*.*.* -p 5432 -U user -d database -t schema1.table1
-- 检查并执行
pg_repack -k --no-order -h 10.*.*.* -p 5432 -U user -d database -t schema1.table1

清理单个 schema

-- 检查但不执行
pg_repack -k --dry-run --no-order -h 10.*.*.* -p 5432 -U user -d database -c schema
-- 检查并执行
pg_repack -k --no-order -h 10.*.*.* -p 5432 -U user -d database -c schema

清理单个库

-- 检查但不执行
pg_repack -k --dry-run --no-order -h 10.*.*.* -p 5432 -U user -d database
-- 检查并执行
pg_repack -k --no-order -h 10.*.*.* -p 5432 -U user -d database

清理整个实例(仅清理安装 pg_repack 插件的数据库)

-- 检查但不执行
pg_repack -k --dry-run --no-order -h 10.*.*.* -p 5432 -U user -a
-- 检查并执行
pg_repack -k --no-order -h 10.*.*.* -p 5432 -U user -a

检查清理效果

-- 查看库大小top,sql如下:
select datname,pg_size_pretty(pg_database_size(datname)) from pg_database order by pg_database_size(datname) desc;
-- 查看库中表大小top,sql如下:
SELECT relname AS table_name, pg_size_pretty(pg_total_relation_size(relid)) AS total_size FROM pg_catalog.pg_statio_user_tables ORDER BY pg_total_relation_size(relid) DESC;
-- 查看特定表的大小,sql如下:
select pg_size_pretty(pg_total_relation_size('pgtest'));