pg_kpart

拒绝未使用分区键的全分区扫描查询

概览

扩展包名版本分类许可证语言
pg_kpart1.0SECISCC
ID扩展名BinLibLoadCreateTrustReloc模式
7450pg_kpart-
相关扩展pg_partman pg_fkpart plan_filter pg_hint_plan citus timescaledb

Planner hook must be loaded through shared_preload_libraries or session_preload_libraries; CREATE EXTENSION is optional.

版本

类型仓库版本PG 大版本包名依赖
EXTPIGSTY1.01817161514pg_kpart-
RPMPIGSTY1.01817161514pg_kpart_$v-
DEBPIGSTY1.01817161514postgresql-$v-pg-kpart-
OS / PGPG18PG17PG16PG15PG14
el8.x86_64
el8.aarch64
el9.x86_64
el9.aarch64
el10.x86_64
el10.aarch64
d12.x86_64
d12.aarch64
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
d13.x86_64
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
d13.aarch64
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
u22.x86_64
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
u22.aarch64
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
u24.x86_64
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
u24.aarch64
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
u26.x86_64
u26.aarch64
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0
PIGSTY 1.0

构建

您可以使用 pig build 命令构建 pg_kpart 扩展的 RPM / DEB 包:

pig build pkg pg_kpart         # 构建 RPM / DEB 包

安装

您可以直接安装 pg_kpart 扩展包的预置二进制包,首先确保 PGDGPIGSTY 仓库已经添加并启用:

pig repo add pgsql -u          # 添加仓库并更新缓存

使用 pig 或者是 apt/yum/dnf 安装扩展:

pig install pg_kpart;          # 当前活跃 PG 版本安装
pig ext install -y pg_kpart -v 18  # PG 18
pig ext install -y pg_kpart -v 17  # PG 17
pig ext install -y pg_kpart -v 16  # PG 16
pig ext install -y pg_kpart -v 15  # PG 15
pig ext install -y pg_kpart -v 14  # PG 14
dnf install -y pg_kpart_18       # PG 18
dnf install -y pg_kpart_17       # PG 17
dnf install -y pg_kpart_16       # PG 16
dnf install -y pg_kpart_15       # PG 15
dnf install -y pg_kpart_14       # PG 14
apt install -y postgresql-18-pg-kpart   # PG 18
apt install -y postgresql-17-pg-kpart   # PG 17
apt install -y postgresql-16-pg-kpart   # PG 16
apt install -y postgresql-15-pg-kpart   # PG 15
apt install -y postgresql-14-pg-kpart   # PG 14

预加载配置

shared_preload_libraries = 'pg_kpart';

用法

来源:

pg_kpart 防止了对分表表进行全表扫描的意外查询,而这些查询没有有效的分区剪裁。其规划器钩子可以在执行前发出警告、告警或记录日志。功能单元是预加载的库;无需创建任何SQL对象,并且上游仅将 CREATE EXTENSION 描述为可选的系统目录注册。

启用与部署

为了集群范围内的强制执行,可以预加载库并重启PostgreSQL:

shared_preload_libraries = 'pg_kpart'

也可以在无需服务器重启的情况下,选择性地加载会话或数据库:

session_preload_libraries = 'pg_kpart'

在强制错误之前,以审计模式开始:

ALTER SYSTEM SET pg_kpart.message_level = 'warning';
SELECT pg_reload_conf();

一旦观察到的查询被理解,可以设置 pg_kpart.message_level = 'error'

范围与行为

-- Check only these tables and their sub-partitions.
ALTER SYSTEM SET pg_kpart.blacklisted =
    'public.measurement, public.orders';

-- Or check all partitioned tables except selected hierarchies.
ALTER SYSTEM SET pg_kpart.whitelisted = 'public.audit_log';
SELECT pg_reload_conf();
-- Partition key is logdate.
SELECT * FROM measurement WHERE city_id = 5;              -- violation
SELECT * FROM measurement WHERE logdate = DATE '2026-07-01'; -- pruned, allowed
SELECT * FROM measurement WHERE logdate = $1;             -- runtime pruning, allowed

违反规则将使用SQLSTATE FS001,应用程序可以在 message_levelerror 的情况下捕获这些错误。

配置索引与注意事项

  • pg_kpart.enabled: 主控开关,默认值为 on
  • pg_kpart.message_level: 可以设置为 error, warning, notice, log 等其他PostgreSQL消息级别。
  • pg_kpart.min_partitions: 检查的最小叶分区数量,默认值为 2
  • pg_kpart.check_superuser: 默认情况下,超级用户绕过检查。
  • pg_kpart.blacklisted: 当非空时,仅检查命名层次结构,并忽略 whitelisted
  • pg_kpart.whitelisted: 在未设置黑名单的情况下,免于检查的层次结构。
  • 如果谓词的范围仍然包括所有分区,则即使提到分区键也会被视为全表扫描并被拒绝。
  • 规划器钩子也适用于 UPDATE, DELETE 和不带 EXPLAINANALYZE。它依赖于PostgreSQL计划剪裁的结果,而不是对 WHERE 子句的文本检查。
  • 上游v1.0在PostgreSQL 14及更高版本上进行了测试。