帮你快速理解、总结文档立即下载

pg_squeeze

最近更新时间:2026-09-16 11:44:01
我的收藏
本文为您介绍 pg_squeeze 插件的简介及使用方法。

概述

pg_squeeze 是表空间收缩插件,用于回收表中因删除、更新产生的膨胀空间,无需长时间持有锁即可在线重建表。

支持版本

PostgreSQL 版本
内核版本
PostgreSQL 11
v11.22_r1.35及以上
PostgreSQL 12
v12.22_r1.37及以上
PostgreSQL 13
v13.22_r1.32及以上
PostgreSQL 14
v14.22_r1.42及以上
PostgreSQL 15
v15.14_r1.27及以上
PostgreSQL 16
v16.10_r1.22及以上
PostgreSQL 17
v17.9_r1.16及以上
PostgreSQL 18
v18.3_r1.6及以上
说明:
您可在控制台实例详情页查看当前实例的内核版本,或执行 SHOW tencentdb_version; 查询。

插件简介

表在频繁的更新、删除操作后,会产生大量死元组和空闲空间,导致表体积膨胀、查询变慢。pg_squeeze 通过在线重建表的方式回收这些空间,收缩过程中对业务的读写影响较小。

环境准备

加载插件

pg_squeeze 是需要预加载的插件,使用前请先在控制台参数设置的 shared_preload_libraries 参数中勾选 pg_squeeze,保存后重启实例。参数设置方法可参考 设置实例参数
注意:
以下参数需正确配置,否则会导致实例重启失败:
squeeze.worker_autostart:自动启动 worker 的数据库列表,需配置为实例中实际存在的数据库。该参数不能设置为空。
squeeze.worker_role:worker 连接数据库使用的角色,需配置为实例中已存在且具备目标表访问权限的角色。该参数不能设置为空。

创建扩展

连接到需要使用的数据库,执行以下语句创建扩展:
postgres=> CREATE EXTENSION pg_squeeze;
CREATE EXTENSION
说明:
pg_squeeze 的扩展安装在 squeeze 模式下,创建时需要当前数据库的 CREATE 权限,请使用具备建库权限的账号在对应数据库执行。

收缩膨胀表

确认表有主键

pg_squeeze 需要依赖主键或唯一索引来定位行,请确认目标表存在主键或唯一索引。

执行收缩

以下示例演示完整的收缩流程。先建表、插入数据,再删除一半制造膨胀:
postgres=> CREATE TABLE bloat_test(id int PRIMARY KEY, data text);
CREATE TABLE
postgres=> INSERT INTO bloat_test SELECT i, repeat('x', 200) FROM generate_series(1, 10000) AS i;
INSERT 0 10000
postgres=> DELETE FROM bloat_test WHERE id % 2 = 0;
DELETE 5000
postgres=> SELECT pg_size_pretty(pg_total_relation_size('bloat_test')) AS size_after_delete;
size_after_delete
-------------------
2632 kB
(1 row)
删除一半数据后,表仍占用2632kB。执行收缩:
postgres=> SELECT squeeze.squeeze_table('public', 'bloat_test');
squeeze_table
---------------

(1 row)
postgres=> SELECT pg_size_pretty(pg_total_relation_size('bloat_test')) AS size_after_squeeze;
size_after_squeeze
--------------------
1696 kB
(1 row)
收缩后表大小降为1696kB,空间得到回收。

查看表膨胀情况

使用 pgstattuple_approx 函数查看表的膨胀情况:
postgres=> SELECT * FROM squeeze.pgstattuple_approx('public.bloat_test');
table_len | scanned_percent | approx_tuple_count | approx_tuple_len | approx_tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | approx_free_space | approx_free_percent
-----------+-----------------+--------------------+------------------+----------------------+------------------+----------------+--------------------+-------------------+---------------------
1212416 | 0 | 5000 | 1185920 | 97.81461148648648 | 0 | 0 | 0 | 26496 | 2.1853885135135136
(1 row)
字段说明:
字段
说明
table_len
表总大小(字节)
approx_tuple_count
有效元组数量
dead_tuple_count
死元组数量
approx_free_space
可回收的空闲空间(字节)
approx_free_percent
空闲空间占比
收缩后 dead_tuple_count 为0,approx_free_percent 很低,说明膨胀空间已回收。

自动收缩配置

pg_squeeze 的后台进程会自动收缩配置的表,完整配置包括两部分:
1. 启动后台 worker:通过 squeeze.worker_autostart 参数指定需要自动清理的数据库,squeeze.worker_role 参数指定 worker 连接数据库使用的角色。这两个参数修改后需重启实例。
2. 配置收缩表:在 squeeze.tables 表中添加需要自动收缩的表:
postgres=> \\d squeeze.tables
squeeze.tables 表主要字段说明:
字段
说明
tabschema / tabname
模式名 / 表名
min_size
触发收缩的最小表大小(MB)
free_space_extra
空闲空间超过该百分比时触发收缩
vacuum_max_age
判断上次 VACUUM 后空闲空间映射(FSM)是否仍新鲜的最大时长;超过后需重新评估膨胀
schedule
收缩调度配置

参数说明

pg_squeeze 的相关参数如下:
参数
默认值
级别
说明
squeeze.worker_autostart
postmaster
自动启动 worker 的数据库列表(逗号分隔)
squeeze.worker_role
postmaster
worker 连接数据库使用的角色
squeeze.workers_per_database
1
postmaster
每个数据库的最大 worker 进程数
squeeze.wait_lock_time
1000ms
sighup
等待锁的最大时间
squeeze.max_xlock_time
0
userset
表独占锁的最长时间,0表示不限制
squeeze.quick_quit
false
userset
立即停止当前收缩
说明:
squeeze.worker_autostartsqueeze.worker_role 属于 postmaster 级别,修改后需重启实例生效。参数的具体修改方式可参考 设置实例参数

常见问题

Q:执行 squeeze_table 时报 has no identity index?

A:pg_squeeze 依赖主键或唯一索引来定位行。请为目标表添加主键或唯一索引后再收缩。

Q:收缩过程中会影响业务读写吗?

A:pg_squeeze 采用在线重建方式,收缩期间表仍可正常读写,仅会在最后切换表时短暂加锁,对业务影响较小。

相关参考