快速上手

如何在 Pigsty 中,通过开箱即用的方式安装并启用 PostgreSQL 扩展插件?

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),通常涉及到 下载安装加载启用 四个核心问题:

  • 怎样下载扩展repo_extra_packages

    在 Pigsty 默认在线安装时,只会下载当前 PG 大版本对应的三个默认扩展(pg_repack, wal2json, pgvector)。

    如果您想要下载更多扩展,将其加入 repo_extra_packages 中即可。您可以加入扩展包名,或者直接指定扩展类目进行批量下载。

  • 安装哪些扩展pg_extensions

    在 Pigsty 配置模板中的样例集群中,已经提供了完整可用的扩展清单,您只需要将想要 安装 的扩展,添加到 pg_extensions 中即可。

    如果您想要在集群创建完毕后,安装额外的扩展,那么在配置完毕后,执行 ./pgsql.yml -t pg_extension 子任务即可。

  • 加载哪些扩展pg_libs

    一小部分使用了 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 组合的扩展包名差异了。

尽管如此,不同操作系统与芯片架构上可用的扩展仍然会有略微差异,具体操作系统发行版可用的扩展列表,下面的配置文件为权威参考:

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 中指定扩展所需的配置参数,例如 pgsodiumpg_cron 扩展所必须的配置参数
  • pg_databases.extensions 中指定将扩展安装到哪个模式(schema)中

baseline: supabase.sql 中,还包含了其他对扩展进行自定义配置的 SQL Migration 逻辑。

最终,用户只需要执行 ./install.yml ,Supabase 所需的 PostgreSQL 集群就能被创建出来并开箱即用了!





最后修改 2025-03-21: replace vonng to pgsty (35fb95c)