pg_kpart
拒绝未使用分区键的全分区扫描查询
仓库
hexacluster/pg_kpart
https://github.com/hexacluster/pg_kpart
源码
pg_kpart-1.0.tar.gz
pg_kpart-1.0.tar.gz
概览
| 扩展包名 | 版本 | 分类 | 许可证 | 语言 |
|---|---|---|---|---|
pg_kpart | 1.0 | SEC | ISC | C |
| ID | 扩展名 | Bin | Lib | Load | Create | Trust | Reloc | 模式 |
|---|---|---|---|---|---|---|---|---|
| 7450 | pg_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 大版本 | 包名 | 依赖 |
|---|---|---|---|---|---|
| EXT | PIGSTY | 1.0 | 1817161514 | pg_kpart | - |
| RPM | PIGSTY | 1.0 | 1817161514 | pg_kpart_$v | - |
| DEB | PIGSTY | 1.0 | 1817161514 | postgresql-$v-pg-kpart | - |
构建
您可以使用 pig build 命令构建 pg_kpart 扩展的 RPM / DEB 包:
pig build pkg pg_kpart # 构建 RPM / DEB 包
安装
您可以直接安装 pg_kpart 扩展包的预置二进制包,首先确保 PGDG 和 PIGSTY 仓库已经添加并启用:
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_level 为 error 的情况下捕获这些错误。
配置索引与注意事项
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和不带EXPLAIN的ANALYZE。它依赖于PostgreSQL计划剪裁的结果,而不是对WHERE子句的文本检查。 - 上游v1.0在PostgreSQL 14及更高版本上进行了测试。