pg_savior
概览
| 扩展包名 | 版本 | 分类 | 许可证 | 语言 |
|---|---|---|---|---|
pg_savior | 0.1.0 | ADMIN | Apache-2.0 | C |
| ID | 扩展名 | Bin | Lib | Load | Create | Trust | Reloc | 模式 |
|---|---|---|---|---|---|---|---|---|
| 5810 | pg_savior | 否 | 是 | 否 | 是 | 否 | 是 | - |
| 相关扩展 | table_log safeupdate pg_drop_events pg_strict pgmemento pgaudit pg_cheat_funcs pg_crash pg_dirtyread block_copy_command |
|---|
-tuplestore_donestoring , breaks on pg18 @ el
版本
| 类型 | 仓库 | 版本 | PG 大版本 | 包名 | 依赖 |
|---|---|---|---|---|---|
| EXT | PIGSTY | 0.1.0 | 1817161514 | pg_savior | - |
| RPM | PIGSTY | 0.1.0 | 1817161514 | pg_savior_$v | - |
| DEB | PIGSTY | 0.1.0 | 1817161514 | postgresql-$v-pg-savior | - |
构建
您可以使用 pig build 命令构建 pg_savior 扩展的 RPM / DEB 包:
安装
您可以直接安装 pg_savior 扩展包的预置二进制包,首先确保 PGDG 和 PIGSTY 仓库已经添加并启用:
使用 pig 或者是 apt/yum/dnf 安装扩展:
创建扩展:
用法
来源:README, release 0.1.0, PGXN 0.1.0, SQL file, C source, pg_savior.control
pg_savior 是一个 PostgreSQL 安全扩展,用于在执行前阻止特定高风险 DML 和 DDL 语句。版本 0.1.0 是有意发布到 PGXN 的版本,并且相对 0.0.1 进行了重大重写;README 仍将其标记为 pre-1.0,且未准备好用于生产。
激活
仅执行 CREATE EXTENSION 不会激活检查。SQL 文件只说明保护逻辑位于已加载的 shared library 中,因此每个 backend 都必须通过一种上游支持的路径加载 pg_savior:
集群级激活使用 shared_preload_libraries,并需要重启 PostgreSQL:
新连接的会话级激活可以在 config reload 后使用 session_preload_libraries:
开发或测试会话可以手动加载 library:
library 加载后,_PG_init 会为该 backend 安装 post_parse_analyze_hook、ExecutorStart_hook 和 ProcessUtility_hook。
DML 保护
pg_savior 会阻止没有 WHERE 子句的 DELETE 和 UPDATE 语句。parser hook 检查分析后的 Query tree 并抛出 ERROR,因此事务会中止,应用会看到失败。
可选的行数保护适用于 planner estimate 超过 pg_savior.max_rows_affected 的 DELETE 和 UPDATE 语句。它从 ExecutorStart_hook 运行,在规划之后、触碰 tuple 之前生效。
DDL 保护
ProcessUtility_hook 只保护上游列出的 DDL 操作:
- 没有
CONCURRENTLY的CREATE INDEX总是被阻止。 DROP DATABASE总是被阻止。- 当目标表大于
pg_savior.large_table_threshold_rows时,ALTER TABLE ADD COLUMN ... DEFAULT被阻止。 - 大表上的
ALTER TABLE ALTER COLUMN TYPE被阻止。 - 当任一目标表是大表时,
TRUNCATE被阻止。 - 当任一目标表是大表时,
DROP TABLE被阻止。
大表检查使用 pg_class.reltuples > pg_savior.large_table_threshold_rows。
配置
所有已文档化的 GUC 都是 session-scoped USERSET 变量:
| GUC | 默认值 | 作用 |
|---|---|---|
pg_savior.enabled | on | 总开关;为 off 时不运行检查。 |
pg_savior.bypass | off | 允许当前 session 跳过保护。 |
pg_savior.max_rows_affected | 0 | 当估计的 DELETE/UPDATE 行数高于该值时阻止;0 禁用该检查。 |
pg_savior.large_table_threshold_rows | 1000000 | 为受保护的大表 DDL 操作定义 “large”。 |
有意绕过一个事务时使用 SET LOCAL:
注意事项
- 保护生效前,library 必须先在 backend 中加载;
CREATE EXTENSION pg_savior只注册扩展元数据。 - 行数保护和大表保护依赖 planner/catalog estimate。近期变更导致 estimate 过期时,应运行
ANALYZE。 UPDATE覆盖范围限于无保护的UPDATE和可选 planner-estimate 阈值;README 未声称会语义审查每个WHEREpredicate。- DDL 覆盖范围限于列出的
ProcessUtility_hookcase。不要假设其他 schema 变更会被阻止。 ADD COLUMN ... DEFAULT保护较保守,会阻止大表上的任何 default,包括较新 PostgreSQL 版本可能无需 full table rewrite 处理的 non-volatile default。