在生产环境中发布和维护自定义 SQL 对象时,最佳工程实践是将所有相关的函数、类型、表和视图统一打包为扩展(Extension)。
一个合法的扩展至少包含两个核心物理文件:一个控制文件(extension_name.control)以及一个包含对象创建 SQL 语法的安装脚本(extension_name--version.sql)。控制文件存放在 SHAREDIR/extension/ 目录下,支持以下核心配置参数:
directory指定安装脚本文件所在的目录路径。
default_version指定该扩展的默认安装版本号(如 1.0)。
comment对该扩展功能与用途的注释说明字符串。
encoding指定 SQL 安装脚本所使用的字符集编码。
module_pathname在 SQL 安装脚本中替代 MODULE_PATHNAME 宏的具体共享库路径。
requires以逗号分隔声明当前扩展依赖的前置依赖扩展清单。
no_relocate禁止将特定对象重定位至其他模式。
superuser布尔值,指定安装或升级该扩展是否必须具备超级用户权限。
trusted指定该扩展是否被标记为受信任扩展,受信任扩展允许具备数据库 CREATE 权限的非超级用户直接安装。
relocatable布尔值,指定扩展是否支持通过 ALTER EXTENSION ... SET SCHEMA 自由重定位至其他模式。
schema显式限定扩展必须安装到的目标模式名称。
可重定位(Relocatable)扩展允许用户在执行 CREATE EXTENSION ... SCHEMA ... 时任意指定安装模式,或在安装后整体移动模式。编写可重定位扩展时,SQL 脚本内部引用自身对象时应避免硬编码模式前缀。
若扩展创建了保存用户配置数据的数据表,为了使 pg_dump 在逻辑备份时能够正确转储这些配置表的数据内容,可以通过调用 pg_extension_config_dump() 将其注册为扩展配置表。
扩展支持多版本增量升级。通过提供形如 extension--1.0--1.1.sql 的升级脚本,用户执行 ALTER EXTENSION name UPDATE TO '1.1' 时系统会自动按序应用差异补丁。
升级脚本仅需包含从旧版本演进到新版本所必需的 DDL 增量修改语句,无需重复执行基础建表操作。
在安装和维护扩展时需格外关注安全权限与搜索路径(search_path)。
扩展中的 C 语言函数在服务器后台进程中以操作系统数据库用户的物理权限直接运行,能够直接访问内存与本地文件系统。因此必须严格防范缓冲区溢出与非法内存越界访问。
在编写扩展安装 SQL 脚本时,必须防范搜索路径投毒攻击。建议在脚本头部显式锁定 search_path,并在引用所有对象时使用限定名称。
以下展示一个极简的扩展定义示例:
-- pair.control comment = '简单键值对数据类型扩展' default_version = '1.0' relocatable = true
-- pair--1.0.sql
CREATE TYPE pair AS (k text, v text);
CREATE FUNCTION make_pair(text, text) RETURNS pair
AS 'MODULE_PATHNAME', 'make_pair'
LANGUAGE C IMMUTABLE STRICT;