快速上手
Module:
Pigsty 让您可以直接在 PGSQL
集群中,通过声明式的方式下载,安装,加载,启用 PostgreSQL 扩展。
开箱即用
Pigsty 为用户封装了扩展管理的复杂度,用户无需了解细节,只要在配置文件中按需进行声明即可:
例如,下面的配置文件片段声明了一个 PostgreSQL 集群,下载 并 安装 了三个额外的扩展插件,动态 加载 了三个扩展,并 启用 了三个扩展。
all:
children:
pg-meta:
hosts: {10.10.10.10: { pg_seq: 1, pg_role: primary }}
vars:
pg_cluster: pg-meta
pg_databases: {name: meta, extensions: [ postgis, timescaledb, vector ]} # 动态启用三个扩展(这里使用扩展名,而非扩展包名)
pg_libs: 'timescaledb, pg_stat_statements, auto_explain' # 动态加载三个扩展(后两个为 PG 自带扩展,无需专门下载安装)
pg_extensions: [ pgsql-main, postgis pgvector timescaledb ] # 额外安装三个扩展(默认大版本 PG 17,pgsql-main 为内核)
repo_extra_packages: [ postgis, timescaledb, vector ] # 额外下载三个扩展(全局参数)
执行 ./install.yml
剧本,本地仓库中将下载这三个额外扩展,创建的 PostgreSQL 集群 pg-meta
中将自动安装,加载,启用上述扩展。
关键问题
想要在 PostgreSQL 集群中使用扩展(Extension),通常涉及到 下载、安装、加载、启用 四个核心问题:
-
在 Pigsty 默认在线安装时,只会下载当前 PG 大版本对应的三个默认扩展(
pg_repack
,wal2json
,pgvector
)。如果您想要下载更多扩展,将其加入
repo_extra_packages
中即可。您可以加入扩展包名,或者直接指定扩展类目进行批量下载。 -
在 Pigsty 配置模板中的样例集群中,已经提供了完整可用的扩展清单,您只需要将想要 安装 的扩展,添加到
pg_extensions
中即可。如果您想要在集群创建完毕后,安装额外的扩展,那么在配置完毕后,执行
./pgsql.yml -t pg_extension
子任务即可。 -
一小部分使用了 PostgreSQL 钩子函数的扩展,需要动态加载并 重启 数据库后才可以启用,您需要将这些扩展添加到
pg_libs
中,并在重启数据库后生效。如果您的数据库集群已经创建完毕,那么需要 配置现有集群 的
shared_preload_libraries
参数,并重启数据库集群后生效。 -
启用哪些扩展:
pg_databases.extensions
绝大多数扩展在安装之后,都需要执行
CREATE EXTENSION
DDL 语句,才会真实在具体的数据库中被创建并启用。您可以手工执行此 DDL,或者在
pg_datbasese.extensions
中显式指定要在数据库中启用的扩展列表,这些扩展会在集群初始化时自动启用。
扩展包名
您可能注意到,在加载,启用扩展时,使用的是“扩展名”(ext
),而在下载,安装扩展时,使用的是“扩展包名”(pkg
)。
例如,向量数据库扩展 PGVECTOR 的扩展名是 vector
,而扩展包名是 pgvector
。
flowchart LR ext[( EXTNAME )] -- "n:1" --> pkg[( PKGNAME )] pkg[( PKGNAME )] -- "1:n" --> packages[( RPM/DEB )]
这里的扩展包名是由 Pigsty 添加的额外抽象层,解决了不同操作系统发行版的扩展包名差异问题,在绝大部分情况下,扩展名(ext
)与扩展包名(pkg
)是相同的。
但是一个扩展包可能包含多个扩展,例如 postgis
扩展包中就包含了 postgis
与 其他六个扩展。
多个扩展(ext
)可能对应同一个扩展包(pkg
),此外,有些扩展名与操作系统发行版自带的软件包名有冲突,因此您需要使用扩展包名(pkg
)来下载,安装扩展。
在 Pigsty 中,您可以在 repo_extra_packages
, pg_packages
, pg_extensions
等下载安装相关参数中使用扩展包名(pkg
),例如要安装 postgis
扩展,您可以使用:
- Pigsty 提供的 标准扩展包名 ,Pigsty 会自动根据活跃 PG 大版本与操作系统 翻译 为对应的 RPM/DEB 包名。
- 带有
$v
占位符的包名,Pigsty 会自动使用pg_version
的值替换占位符。 - 原始的操作系统 RPM/DEB 包名,您可以在包名中使用
*
通配符,或依次指定每个包名。
postgis # 指定扩展包别名,自动翻译为 DEB/RPM 包名,与当前活跃 PG 大版本
postgis35_$v* # 指定 RPM 包名模式,同时使用 PG 大版本号占位符 $v
postgis35_15* # 直接指定 RPM 包名名称
postgresql-$v-postgis-3* # 指定 DEB 包名模式,同时使用 PG 大版本号占位符 $v
postgresql-14-postgis-3* # 直接指定 DEB 包名称
Pigsty 中所有可用扩展的扩展包名与扩展名之间的映射关系,可以查询 扩展列表 页面。 此外,一个扩展包在不同的操作系统和 PostgreSQL 大版本组合下,也会对应不同的具体 RPM/DEB 包名。
我们建议使用 Pigsty 提供的标准化扩展名(pkg
)来下载安装扩展,在不同的操作系统发行版中,
Pigsty 将标准扩展名翻译为对应 PG 大版本的 RPM / DEB 包名,并填充 PG 大版本号,这样您就无需关心不同 OS/PG 组合的扩展包名差异了。
尽管如此,不同操作系统与芯片架构上可用的扩展仍然会有略微差异,具体操作系统发行版可用的扩展列表,下面的配置文件为权威参考:
- EL8 : x86_64 , aarch64
- EL9 : x86_64 , aarch64
- D12 : x86_64 , aarch64
- U22 : x86_64 , aarch64
- U24 : x86_64 , aarch64
Pigsty 尽最大努力对齐 EL 操作系统与 Debian 操作系统生态的 PostgreSQL 扩展,但仍有少量扩展因为各种原因难以/尚未移植, 请参考 RPM扩展列表 与 DEB扩展列表 了解更多信息。
复杂案例
下面是一个具体的例子:自建 Supabase 使用到的 app/supa
配置模板:
Supabase 是一个封装 PostgreSQL 作为底层存储的“上层抽象数据库”,它深度使用了 PostgreSQL 的扩展机制,以下片段定义了 Supabase 需要的扩展:
all:
children:
# pg-meta, the underlying postgres database for supabase
pg-meta:
hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
vars:
pg_cluster: pg-meta
pg_users:
# supabase roles: anon, authenticated, dashboard_user
- { name: anon ,login: false }
- { name: authenticated ,login: false }
- { name: dashboard_user ,login: false ,replication: true ,createdb: true ,createrole: true }
- { name: service_role ,login: false ,bypassrls: true }
# supabase users: please use the same password
- { name: supabase_admin ,password: 'DBUser.Supa' ,pgbouncer: true ,inherit: true ,roles: [ dbrole_admin ] ,superuser: true ,replication: true ,createdb: true ,createrole: true ,bypassrls: true }
- { name: authenticator ,password: 'DBUser.Supa' ,pgbouncer: true ,inherit: false ,roles: [ dbrole_admin, authenticated ,anon ,service_role ] }
- { name: supabase_auth_admin ,password: 'DBUser.Supa' ,pgbouncer: true ,inherit: false ,roles: [ dbrole_admin ] ,createrole: true }
- { name: supabase_storage_admin ,password: 'DBUser.Supa' ,pgbouncer: true ,inherit: false ,roles: [ dbrole_admin, authenticated ,anon ,service_role ] ,createrole: true }
- { name: supabase_functions_admin ,password: 'DBUser.Supa' ,pgbouncer: true ,inherit: false ,roles: [ dbrole_admin ] ,createrole: true }
- { name: supabase_replication_admin ,password: 'DBUser.Supa' ,replication: true ,roles: [ dbrole_admin ]}
- { name: supabase_read_only_user ,password: 'DBUser.Supa' ,bypassrls: true ,roles: [ dbrole_readonly, pg_read_all_data ] }
pg_databases:
- name: postgres
baseline: supabase.sql
owner: supabase_admin
comment: supabase postgres database
schemas: [ extensions ,auth ,realtime ,storage ,graphql_public ,supabase_functions ,_analytics ,_realtime ]
extensions: # 这里定义了在 postgres 数据库中 创建启用 的扩展列表
- { name: pgcrypto ,schema: extensions } # 加密函数
- { name: pg_net ,schema: extensions } # 异步 HTTP
- { name: pgjwt ,schema: extensions } # PostgreSQL 的 JSON Web Token API
- { name: uuid-ossp ,schema: extensions } # 生成通用唯一标识符 (UUID)
- { name: pgsodium } # pgsodium 是 PostgreSQL 的现代加密库
- { name: supabase_vault } # Supabase 保险库扩展
- { name: pg_graphql } # pg_graphql: GraphQL 支持
- { name: pg_jsonschema } # pg_jsonschema: 验证 JSON 模式
- { name: wrappers } # wrappers: 外部数据包装器集合
- { name: http } # http: 允许在数据库内检索网页
- { name: pg_cron } # pg_cron: PostgreSQL 的任务调度器
- { name: timescaledb } # timescaledb: 支持时间序列数据的可扩展插入和复杂查询
- { name: pg_tle } # pg_tle: PostgreSQL 的可信语言扩展
- { name: vector } # pgvector: 向量相似性搜索
- { name: pgmq } # pgmq: 类似 AWS SQS 和 RSMQ 的轻量级消息队列
# supabase required extensions
pg_libs: 'timescaledb, plpgsql, plpgsql_check, pg_cron, pg_net, pg_stat_statements, auto_explain, pg_tle, plan_filter'
pg_parameters:
cron.database_name: postgres
pgsodium.enable_event_trigger: off
pg_hba_rules: # supabase hba rules, require access from docker network
- { user: all ,db: postgres ,addr: intra ,auth: pwd ,title: 'allow supabase access from intranet' }
- { user: all ,db: postgres ,addr: 172.17.0.0/16 ,auth: pwd ,title: 'allow access from local docker network' }
node_crontab: [ '00 01 * * * postgres /pg/bin/pg-backup full' ] # make a full backup every 1am
vars: # 全局参数配置
pg_version: 17
repo_modules: node,pgsql,infra,docker
repo_packages: [node-bootstrap, infra-package, infra-addons, node-package1, node-package2, pgsql-utility, docker ]
repo_extra_packages: [pg17-core ,pg17-time ,pg17-gis ,pg17-rag ,pg17-fts ,pg17-olap ,pg17-feat ,pg17-lang ,pg17-type ,pg17-util ,pg17-func ,pg17-admin ,pg17-stat ,pg17-sec ,pg17-fdw ,pg17-sim ,pg17-etl ]
pg_extensions: [pg17-time ,pg17-gis ,pg17-rag ,pg17-fts ,pg17-feat ,pg17-lang ,pg17-type ,pg17-util ,pg17-func ,pg17-admin ,pg17-stat ,pg17-sec ,pg17-fdw ,pg17-sim ,pg17-etl ] #,pg17-olap]
在这里,我们声明了一个名为 pg-meta
的 PostgreSQL 集群,它使用默认的 postgres
数据库作为定制对象。
- 在
repo_extra_packages
按照 16 大分类分类批量下载所有可用扩展,而不是一个一个指定下载 - 在
pg_extensions
中指定需要安装的扩展包,这里按照了除了pg17-olap
以外的所有扩展包 - 在
pg_libs
中对 Supabase 需要用到的扩展进行动态加载 - 在
pg_parameters
中指定扩展所需的配置参数,例如pgsodium
与pg_cron
扩展所必须的配置参数 - 在
pg_databases.extensions
中指定将扩展安装到哪个模式(schema
)中
在 baseline: supabase.sql
中,还包含了其他对扩展进行自定义配置的 SQL Migration 逻辑。
最终,用户只需要执行 ./install.yml
,Supabase 所需的 PostgreSQL 集群就能被创建出来并开箱即用了!