跳转到主要内容

这是本节的多页打印视图。 .

返回本页常规视图.

内核

您可以在 Pigsty 中使用特殊风味的 PostgreSQL 内核分支替代原生内核。

Pigsty 支持各种 PostgreSQL 内核和兼容分支, 使您能够模拟不同的数据库系统,同时利用 PostgreSQL 的生态系统。 每个内核都能提供独特的功能和兼容性层。

数据库内核

PostgreSQL

带有 437 个扩展插件的原生 PostgreSQL 内核

Citus

PG 原生分布式扩展

Babelfish

SQL Server 线缆协议兼容

IvorySQL

Oracle 语法和 PL/SQL 兼容

OpenHalo

MySQL 线缆协议兼容

Percona

透明加密内核

OrioleDB

OLTP 优化的云原生存储引擎

PolarDB PG

类 Aurora RAC 风味的信创内核

Supabase

后端即服务,自托管 Firebase

FerretDB

MongoDB 线缆协议兼容的内核


选择合适的内核

内核 关键特性 描述
PostgreSQL 原始版本 原版 PostgreSQL 配备 437 扩展
Citus 水平扩展 通过原生扩展实现分布式 PostgreSQL
WiltonDB SQL Server 迁移 SQL Server 线协议兼容
IvorySQL Oracle 迁移 Oracle 语法和 PL/SQL 兼容
OpenHalo MySQL 迁移 MySQL 线协议兼容
Percona 透明数据加密 带有 pg_tde 的 Percona 发行版
FerretDB MongoDB 迁移 MongoDB 线协议兼容
OrioleDB OLTP 优化 Zheap,无膨胀,S3 存储
PolarDB Aurora 风格 RAC RAC,中国国产合规
Supabase 后端即服务 基于 PostgreSQL 的 BaaS,Firebase 替代方案
Cloudberry MPP 数厂与数据分析 大规模并行处理数据仓库(等待2.0GA)

Citus(分布式)

Citus 原生分布式

Citus 将 PostgreSQL 转换为分布式数据库系统,实现跨多个节点的水平扩展。使用 Pigsty 部署原生 HA Citus 集群以获得更好的吞吐量和性能。

关键特性

  • 分布式表:自动将表分片到工作节点
  • 分布式查询:在整个集群中执行查询
  • 高可用性:内置复制和故障转移功能
  • 实时分析:处理事务和分析工作负载
  • Postgres 兼容性:保持完整的 PostgreSQL 功能兼容性

用例

  • 需要水平扩展的多租户 SaaS 应用程序
  • 大型数据集的实时分析
  • 高吞吐量 OLTP 工作负载
  • 需要扩展超出单节点限制的应用程序
说明

需要规划:正确的分片键选择对于最佳性能和避免跨分片查询至关重要。

Babelfish(MSSQL)

Babelfish SQL Server 线缆协议兼容

使用 WiltonDB 和 Babelfish 创建 SQL Server 兼容的 PostgreSQL 集群,提供与 Microsoft SQL Server 的线协议级别兼容性。

关键特性

  • T-SQL 支持:原生执行 T-SQL 查询
  • 线协议兼容性:使用 SQL Server 驱动程序和工具连接
  • 存储过程:支持 T-SQL 存储过程和函数
  • 数据类型:与 SQL Server 数据类型和行为兼容
  • 迁移工具:简化从 SQL Server 环境的迁移

用例

  • 将传统 SQL Server 应用程序迁移到 PostgreSQL
  • 需要 SQL Server 兼容性的多数据库环境
  • 在保持应用程序兼容性的同时降低成本
  • 从 SQL Server 到开源替代方案的云迁移
说明

迁移路径:非常适合希望降低许可成本同时保持现有 SQL Server 应用程序兼容性的组织。


IvorySQL(Oracle)

Babelfish Oracle Grammar Compatible

使用 IvorySQL 内核运行 Oracle 兼容的 PostgreSQL 集群,由瀚高开源,提供 Oracle 语法和功能兼容性。

关键特性

  • PL/SQL 支持:以最少的修改执行 PL/SQL 代码
  • Oracle 语法:支持 Oracle 特定的 SQL 语法和函数
  • 包支持:Oracle 风格的包和过程定义
  • 数据类型:Oracle 兼容的数据类型和行为

用例

  • Oracle 数据库迁移项目
  • 寻求 Oracle 功能兼容性的组织
  • 在保持 Oracle 功能的同时进行成本优化
  • 需要 Oracle 兼容性的开发环境
说明

企业焦点:对于在 Oracle 上有重大投资并寻求迁移路径的企业特别有价值。


OpenHalo(MySQL)

OpenHalo MySQL Wire-Compatible

OpenHalo 内核提供 MySQL 兼容的 PostgreSQL 功能,可使用标准 MySQL 客户端和协议访问。

关键特性

  • MySQL 协议:与 MySQL 协议的线级别兼容性
  • 客户端兼容性:使用现有的 MySQL 驱动程序和工具
  • SQL 方言:支持 MySQL 特定的 SQL 语法
  • 迁移支持:简化从 MySQL 环境的迁移
  • 生态系统集成:在保持 MySQL 兼容性的同时利用 PostgreSQL 的高级功能

用例

  • MySQL 应用程序迁移到 PostgreSQL
  • 需要 MySQL 兼容性的多数据库环境
  • 在保持 MySQL 接口的同时利用 PostgreSQL 功能
  • 从 MySQL 到 PostgreSQL 的渐进式迁移策略
说明

早期阶段:目前处于实验阶段 - 在生产使用前请彻底评估。


OrioleDB(OLTP)

OrioleDB OLTP Optimized Cloud Native

为 OLTP 工作负载优化的 PostgreSQL 存储引擎,消除事务 ID 回绕问题和表膨胀,同时支持云存储。

与 PostgreSQL 17 兼容,在所有支持的平台上可用。

关键特性

  • 无 XID 回绕:消除事务 ID 回绕维护
  • 无表膨胀:高级存储管理防止表膨胀
  • 云存储:对 S3 兼容对象存储的原生支持
  • OLTP 优化:专为事务工作负载设计
  • 改进性能:更好的空间利用率和查询性能

用例

  • 高频事务应用程序
  • 需要对象存储的云原生部署
  • 受 PostgreSQL 维护开销影响的应用程序
  • 需要无需清理周期的一致性能的系统
说明

早期阶段:目前处于 Beta 阶段 - 在生产使用前请彻底评估。


PolarDB PG(RAC)

PolarDB Aurora Flavor RAC

用 PolarDB PG 替换原版 PostgreSQL,这是一个开源的类 Aurora 解决方案,类似于具有共享存储架构的 Oracle RAC。

关键特性

  • 共享存储:多个计算节点共享同一存储层
  • 读取扩展:无需存储复制即可添加读副本
  • 快速恢复:通过共享存储架构快速恢复
  • 成本效率:通过共享降低存储成本
  • 高可用性:内置故障转移和灾难恢复

用例

  • 需要极端读取可扩展性的应用程序
  • 需要高可用性的成本敏感部署
  • 具有共享存储基础设施的云环境
  • 具有可变读写模式的工作负载
说明

云架构:专为具有分离计算和存储的云环境设计。


Supabase(Firebase)

Supabase Backend as a Service

使用现有托管的 HA PostgreSQL 集群自托管 Supabase,使用 docker-compose 启动无状态组件以获得完整的 Firebase 替代方案。

关键特性

  • 实时 API:自动生成的 REST 和 GraphQL API
  • 实时订阅:基于 WebSocket 的实时数据同步
  • 身份验证:内置用户身份验证和授权
  • 存储:具有 CDN 功能的文件存储
  • 边缘函数:用于自定义逻辑的无服务器函数

用例

  • 使用后端即服务进行快速应用程序开发
  • AI / Agent / SaaS 应用快速原型设计
  • 需要即时数据同步的实时应用程序
  • 需要身份验证和存储的移动和 Web 应用程序
说明

全栈:提供以 PostgreSQL 为基础的完整后端解决方案。


Greenplum(MPP)

Cloudberry MPP Data Warehouse

使用 Pigsty 部署和监控 Greenplum/YMatrix MPP 集群,用于大规模分析处理和数据仓库。

关键特性

  • 大规模并行处理:在多个节点间分布查询
  • 列式存储:为分析工作负载优化的存储
  • 高级分析:内置机器学习和统计函数
  • PB 级扩展:通过线性可扩展性处理大规模数据集
  • 标准 SQL:与 PostgreSQL 兼容的完整 SQL 合规性

用例

  • 数据仓库和商业智能
  • 大规模分析和报告
  • 大数据集上的机器学习
  • 企业数据平台的 ETL 处理
说明

企业分析:专为需要大规模并行处理能力的企业级分析工作负载而设计。

1 - PostgreSQL

带有 437 扩展的原版 PostgreSQL 内核

PostgreSQL 是世界上最先进和最受欢迎的开源数据库。

Pigsty 支持 PostgreSQL 13 ~ 18,并提供 437 个 PG 扩展。


快速开始

使用 pgsql 配置模板 安装 Pigsty。

./configure -c pgsql     # 使用 postgres 内核
./install.yml            # 使用 pigsty 设置一切

大多数配置模板默认使用 PostgreSQL 内核,例如:

  • meta : 默认,带有核心扩展(vector、postgis、timescale)的 postgres
  • rich : 安装了所有扩展的 postgres
  • slim : 仅 postgres,无监控基础设施
  • full : 用于 HA 演示的 4 节点沙盒
  • pgsql : 最小的 postgres 内核配置示例

配置

原版 PostgreSQL 内核不需要特殊调整:

pg-meta:
  hosts:
    10.10.10.10: { pg_seq: 1, pg_role: primary }
  vars:
    pg_cluster: pg-meta
    pg_users:
      - { name: dbuser_meta ,password: DBUser.Meta   ,pgbouncer: true ,roles: [dbrole_admin   ] ,comment: pigsty admin user }
      - { name: dbuser_view ,password: DBUser.Viewer ,pgbouncer: true ,roles: [dbrole_readonly] ,comment: read-only viewer  }
    pg_databases:
      - { name: meta, baseline: cmdb.sql ,comment: pigsty meta database ,schemas: [pigsty] ,extensions: [ vector ]}
    pg_hba_rules:
      - { user: dbuser_view , db: all ,addr: infra ,auth: pwd ,title: 'allow grafana dashboard access cmdb from infra nodes' }
    node_crontab: [ '00 01 * * * postgres /pg/bin/pg-backup full' ] # 每天凌晨 1 点进行全量备份
    pg_packages: [ pgsql-main, pgsql-common ]   # pg 内核和通用工具
    #pg_extensions: [ pg18-time ,pg18-gis ,pg18-rag ,pg18-fts ,pg18-olap ,pg18-feat ,pg18-lang ,pg18-type ,pg18-util ,pg18-func ,pg18-admin ,pg18-stat ,pg18-sec ,pg18-fdw ,pg18-sim ,pg18-etl]

版本选择

要使用不同的 PostgreSQL 主版本,您可以使用 -v 参数进行配置:

./configure -c pgsql            # 默认就是 postgresql 18,无需显式指定
./configure -c pgsql -v 17      # 使用 postgresql 17
./configure -c pgsql -v 16      # 使用 postgresql 16
./configure -c pgsql -v 15      # 使用 postgresql 15
./configure -c pgsql -v 14      # 使用 postgresql 14
./configure -c pgsql -v 13      # 使用 postgresql 13

如果 PostgreSQL 集群已经安装,您需要在安装新版本之前卸载它:

./pgsql-rm.yml # -l pg-meta

扩展生态

Pigsty 为 PostgreSQL 提供了丰富的扩展生态,包括:

  • 时序类:timescaledb, pg_cron, periods
  • 地理类:postgis, h3, pgrouting
  • 向量类:pgvector, pgml, vchord
  • 搜索类:pg_trgm, zhparser, pgroonga
  • 分析类:citus, pg_duckdb, pg_analytics
  • 特性类:age, pg_graphql, rum
  • 语言类:plpython3u, pljava, plv8
  • 类型类:hstore, ltree, citext
  • 工具类:http, pg_net, pgjwt
  • 函数类:pgcrypto, uuid-ossp, pg_uuidv7
  • 管理类:pg_repack, pgagent, pg_squeeze
  • 统计类:pg_stat_statements, pg_qualstats, auto_explain
  • 安全类:pgaudit, pgcrypto, pgsodium
  • 外部类:postgres_fdw, mysql_fdw, oracle_fdw
  • 兼容类:orafce, babelfishpg_tds
  • 数据类:pglogical, wal2json, decoderbufs

详情请参考 扩展目录

2 - Citus

PostgreSQL 分片的原生分布式扩展

Citus 是一个 PostgreSQL 扩展,它将 PostgreSQL 转换为分布式数据库,能够跨多个节点水平扩展以处理大量数据和查询。

自 Patroni v3.0 以来,已原生支持 Citus 高可用性,简化了 Citus 集群的设置。Pigsty 也为此提供原生支持。

Pigsty v3.7.0 的 Citus 模板固定使用 PostgreSQL 17;该版本没有 PostgreSQL 18 的 Citus 软件包。


Citus 集群

Pigsty 原生支持 Citus。参考 conf/citus.yml

此示例使用四节点沙盒,包含一个名为 pg-citus 的 Citus 集群,由一个双节点协调器集群 pg-citus0 和两个工作节点集群 pg-citus1pg-citus2 组成。

pg-citus:
  hosts:
    10.10.10.10: { pg_group: 0, pg_cluster: pg-citus0 ,pg_vip_address: 10.10.10.2/24 ,pg_seq: 1, pg_role: primary }
    10.10.10.11: { pg_group: 0, pg_cluster: pg-citus0 ,pg_vip_address: 10.10.10.2/24 ,pg_seq: 2, pg_role: replica }
    10.10.10.12: { pg_group: 1, pg_cluster: pg-citus1 ,pg_vip_address: 10.10.10.3/24 ,pg_seq: 1, pg_role: primary }
    10.10.10.13: { pg_group: 2, pg_cluster: pg-citus2 ,pg_vip_address: 10.10.10.4/24 ,pg_seq: 1, pg_role: primary }
  vars:
    pg_mode: citus                            # pgsql 集群模式:citus
    pg_version: 17                            # v3.7.0 没有 PG18 的 Citus 软件包
    pg_shard: pg-citus                        # Citus 分片名称:pg-citus
    pg_primary_db: citus                      # Citus 使用的主数据库
    pg_vip_enabled: true                      # 为 Citus 集群启用 VIP
    pg_vip_interface: eth1                    # 所有成员的 VIP 接口
    pg_dbsu_password: DBUser.Postgres         # Citus 集群的所有 DBSU 密码
    pg_extensions: [ citus, postgis, pgvector, topn, pg_cron, hll ]  # 安装这些扩展
    pg_libs: 'citus, pg_cron, pg_stat_statements' # Citus 将由 Patroni 自动添加
    pg_users: [{ name: dbuser_citus ,password: DBUser.Citus ,pgbouncer: true ,roles: [ dbrole_admin ]    }]
    pg_databases: [{ name: citus ,owner: dbuser_citus ,extensions: [ citus, vector, topn, pg_cron, hll ] }]
    pg_parameters:
      cron.database_name: citus
      citus.node_conninfo: 'sslmode=require sslrootcert=/pg/cert/ca.crt sslmode=verify-full'
    pg_hba_rules:
      - { user: 'all' ,db: all  ,addr: 127.0.0.1/32  ,auth: ssl   ,title: 'all user ssl access from localhost' }
      - { user: 'all' ,db: all  ,addr: intra         ,auth: ssl   ,title: 'all user ssl access from intranet'  }

与标准 PostgreSQL 集群相比,Citus 集群配置有一些特定要求。首先,确保 Citus 扩展被下载、安装、加载和启用。这涉及以下四个参数:

  • repo_packages:必须包含 citus 扩展,或者您需要使用带有 Citus 扩展的 PostgreSQL 离线包。
  • pg_extensions:必须包含 citus 扩展,意味着您需要在每个节点上安装 citus 扩展。
  • pg_libs:必须包含 citus 扩展,且必须在列表中排第一,但现在 Patroni 会自动处理。
  • pg_databases:定义安装了 citus 扩展的主数据库。

另外,确保 Citus 集群的配置正确:

  • pg_mode:必须设置为 citus 以告知 Patroni 使用 Citus 模式。
  • pg_primary_db:指定主数据库名称,该数据库必须安装 citus 扩展(此处命名为 citus)。
  • pg_shard:指定统一名称作为所有水平分片 PG 集群的前缀(例如,pg-citus)。
  • pg_group:指定分片编号,协调器集群从零开始,工作节点集群递增。
  • pg_cluster:必须匹配 [pg_shard] 和 [pg_group] 的组合。
  • pg_dbsu_password:设置非空明文密码以确保 Citus 正常运行。
  • pg_parameters:建议设置 citus.node_conninfo 参数,强制 SSL 访问并要求节点间客户端证书验证。

配置完成后,使用 pgsql.yml 部署 Citus 集群,就像常规 PostgreSQL 集群一样。


管理 Citus 集群

定义 Citus 集群后,使用相同的剧本 pgsql.yml 部署 Citus 集群:

./pgsql.yml -l pg-citus    # 部署 Citus 集群 pg-citus

任何 DBSU 用户(postgres)都可以使用 patronictl(别名:pg)列出 Citus 集群的状态:

$ pg list
+ Citus cluster: pg-citus ----------+---------+-----------+----+-----------+--------------------+
| Group | Member      | Host        | Role    | State     | TL | Lag in MB | Tags               |
+-------+-------------+-------------+---------+-----------+----+-----------+--------------------+
|     0 | pg-citus0-1 | 10.10.10.10 | Leader  | running   |  1 |           | clonefrom: true    |
|       |             |             |         |           |    |           | conf: tiny.yml     |
|       |             |             |         |           |    |           | spec: 20C.40G.125G |
|       |             |             |         |           |    |           | version: '17'      |
+-------+-------------+-------------+---------+-----------+----+-----------+--------------------+
|     1 | pg-citus1-1 | 10.10.10.11 | Leader  | running   |  1 |           | clonefrom: true    |
|       |             |             |         |           |    |           | conf: tiny.yml     |
|       |             |             |         |           |    |           | spec: 10C.20G.125G |
|       |             |             |         |           |    |           | version: '17'      |
+-------+-------------+-------------+---------+-----------+----+-----------+--------------------+
|     2 | pg-citus2-1 | 10.10.10.12 | Leader  | running   |  1 |           | clonefrom: true    |
|       |             |             |         |           |    |           | conf: tiny.yml     |
|       |             |             |         |           |    |           | spec: 10C.20G.125G |
|       |             |             |         |           |    |           | version: '17'      |
+-------+-------------+-------------+---------+-----------+----+-----------+--------------------+
|     2 | pg-citus2-2 | 10.10.10.13 | Replica | streaming |  1 |         0 | clonefrom: true    |
|       |             |             |         |           |    |           | conf: tiny.yml     |
|       |             |             |         |           |    |           | spec: 10C.20G.125G |
|       |             |             |         |           |    |           | version: '17'      |
+-------+-------------+-------------+---------+-----------+----+-----------+--------------------+

每个水平分片集群都可以作为单独的 PGSQL 集群处理,使用 pgpatronictl)命令管理。注意使用 pg 管理 Citus 集群时,必须使用 --group 参数指定集群分片编号:

pg list pg-citus --group 0   # 使用 --group 0 指定分片编号

Citus 有一个名为 pg_dist_node 的系统表来记录节点信息,Patroni 会自动维护。

PGURL=postgres://postgres:[email protected]/citus

psql $PGURL -c 'SELECT * FROM pg_dist_node;'       # 查看节点信息

另外,您可以查看用户认证信息(仅限超级用户):

$ psql $PGURL -c 'SELECT * FROM pg_dist_authinfo;'   # 查看节点认证信息(仅超级用户)

然后您可以使用常规业务用户(例如,具有 DDL 权限的 dbuser_citus)访问 Citus 集群:

psql postgres://dbuser_citus:[email protected]/citus -c 'SELECT * FROM pg_dist_node;'

使用 Citus 集群

使用 Citus 集群时,我们强烈建议阅读 Citus 官方文档 了解其架构和核心概念。

关键是理解 Citus 中五种类型的表、它们的特征和用例:

  • 分布式表
  • 引用表
  • 本地表
  • 本地管理表
  • 模式表

在协调器节点上,您可以创建分布式表和引用表,并从任何数据节点查询它们。自版本 11.2 以来,任何 Citus 数据库节点都可以充当协调器。

我们可以使用 pgbench 创建一些表,将主表(pgbench_accounts)分布到各个节点,并将其他较小的表用作引用表:

PGURL=postgres://dbuser_citus:[email protected]/citus
pgbench -i $PGURL

psql $PGURL <<-EOF
SELECT create_distributed_table('pgbench_accounts', 'aid'); SELECT truncate_local_data_after_distributing_table('public.pgbench_accounts');
SELECT create_reference_table('pgbench_branches')         ; SELECT truncate_local_data_after_distributing_table('public.pgbench_branches');
SELECT create_reference_table('pgbench_history')          ; SELECT truncate_local_data_after_distributing_table('public.pgbench_history');
SELECT create_reference_table('pgbench_tellers')          ; SELECT truncate_local_data_after_distributing_table('public.pgbench_tellers');
EOF

运行读写基准测试:

pgbench -nv -P1 -c10 -T500 postgres://dbuser_citus:[email protected]/citus      # 直连协调器 5432 端口
pgbench -nv -P1 -c10 -T500 postgres://dbuser_citus:[email protected]:6432/citus # 通过连接池,减少客户端连接数压力,可以有效提高整体吞吐。
pgbench -nv -P1 -c10 -T500 postgres://dbuser_citus:[email protected]/citus      # 任意 primary 节点都可以作为 coordinator
pgbench --select-only -nv -P1 -c10 -T500 postgres://dbuser_citus:[email protected]/citus # 可以发起只读查询

生产部署

生产环境的 Citus 部署通常需要为协调器和每个工作节点集群提供物理复制。

例如,在 simu.yml 中有一个 10 节点集群:

pg-citus: # citus 组
  hosts:
    10.10.10.50: { pg_group: 0, pg_cluster: pg-citus0 ,pg_vip_address: 10.10.10.60/24 ,pg_seq: 0, pg_role: primary }
    10.10.10.51: { pg_group: 0, pg_cluster: pg-citus0 ,pg_vip_address: 10.10.10.60/24 ,pg_seq: 1, pg_role: replica }
    10.10.10.52: { pg_group: 1, pg_cluster: pg-citus1 ,pg_vip_address: 10.10.10.61/24 ,pg_seq: 0, pg_role: primary }
    10.10.10.53: { pg_group: 1, pg_cluster: pg-citus1 ,pg_vip_address: 10.10.10.61/24 ,pg_seq: 1, pg_role: replica }
    10.10.10.54: { pg_group: 2, pg_cluster: pg-citus2 ,pg_vip_address: 10.10.10.62/24 ,pg_seq: 0, pg_role: primary }
    10.10.10.55: { pg_group: 2, pg_cluster: pg-citus2 ,pg_vip_address: 10.10.10.62/24 ,pg_seq: 1, pg_role: replica }
    10.10.10.56: { pg_group: 3, pg_cluster: pg-citus3 ,pg_vip_address: 10.10.10.63/24 ,pg_seq: 0, pg_role: primary }
    10.10.10.57: { pg_group: 3, pg_cluster: pg-citus3 ,pg_vip_address: 10.10.10.63/24 ,pg_seq: 1, pg_role: replica }
    10.10.10.58: { pg_group: 4, pg_cluster: pg-citus4 ,pg_vip_address: 10.10.10.64/24 ,pg_seq: 0, pg_role: primary }
    10.10.10.59: { pg_group: 4, pg_cluster: pg-citus4 ,pg_vip_address: 10.10.10.64/24 ,pg_seq: 1, pg_role: replica }
  vars:
    pg_mode: citus                            # pgsql 集群模式:citus
    pg_version: 17                            # v3.7.0 没有 PG18 的 Citus 软件包
    pg_shard: pg-citus                        # citus 分片名称:pg-citus
    pg_primary_db: citus                      # citus 使用的主数据库
    pg_vip_enabled: true                      # 为 citus 集群启用 vip
    pg_vip_interface: eth1                    # 所有成员的 vip 接口
    pg_dbsu_password: DBUser.Postgres         # 为 citus 启用 dbsu 密码访问
    pg_extensions: [ citus, postgis, pgvector, topn, pg_cron, hll ]  # 安装这些扩展
    pg_libs: 'citus, pg_cron, pg_stat_statements' # citus 将由 patroni 自动添加
    pg_users: [{ name: dbuser_citus ,password: DBUser.Citus ,pgbouncer: true ,roles: [ dbrole_admin ]    }]
    pg_databases: [{ name: citus ,owner: dbuser_citus ,extensions: [ citus, vector, topn, pg_cron, hll ] }]
    pg_parameters:
      cron.database_name: citus
      citus.node_conninfo: 'sslrootcert=/pg/cert/ca.crt sslmode=verify-full'
    pg_hba_rules:
      - { user: 'all' ,db: all  ,addr: 127.0.0.1/32  ,auth: ssl   ,title: 'all user ssl access from localhost' }
      - { user: 'all' ,db: all  ,addr: intra         ,auth: ssl   ,title: 'all user ssl access from intranet'  }

我们将在后续教程中涵盖一系列高级主题:

  • 读写分离
  • 故障转移处理
  • 一致性备份和恢复
  • 高级监控和故障排除
  • 连接池

3 - Babelfish

PostgreSQL 上的 MS SQL Server 线协议兼容性

Pigsty 允许用户使用 Babelfish 和 WiltonDB 创建与 Microsoft SQL Server 兼容的 PostgreSQL 集群!

  • Babelfish:由 AWS 开源的 MSSQL(Microsoft SQL Server)兼容性扩展
  • WiltonDB:专注于集成 Babelfish 的 PostgreSQL 内核发行版

Babelfish 是一个 PostgreSQL 扩展,但它运行在经过轻微修改的 PostgreSQL 内核分支上,WiltonDB 在 EL/Ubuntu 系统上提供编译后的内核二进制文件和扩展二进制包。

Pigsty 可以用 WiltonDB 替换原生 PostgreSQL 内核,提供开箱即用的 MSSQL 兼容集群,以及常见 PostgreSQL 集群支持的所有功能,如 HA、PITR、IaC、监控等。

WiltonDB 与 PostgreSQL 15 非常相似,但不能直接使用原版 PostgreSQL 扩展。WiltonDB 有几个重新编译的扩展,如 system_statspg_hint_plantds_fdw

集群将监听默认的 PostgreSQL 端口和默认的 MSSQL 1433 端口,通过 TDS WireProtocol 在此端口上提供 MSSQL 服务。您可以使用任何 MSSQL 客户端连接到 Pigsty 提供的 MSSQL 服务,例如 SQL Server Management Studio,或使用 sqlcmd 命令行工具。


快速开始

使用 mssql 配置模板 安装 Pigsty。

curl -fsSL https://repo.pigsty.io/get | bash -s v3.7.0; cd ~/pigsty;
./configure -c mssql     # 使用 mssql (babelfish) 模板
./install.yml            # 使用 pigsty 安装一切

对于生产部署,请确保在运行 install 剧本之前修改 pigsty.yml 配置中的密码参数。


注意事项

在安装和部署 MSSQL 模块时,请特别注意以下几点:

  • WiltonDB 在 EL(7/8/9)和 Ubuntu(20.04/22.04)上可用,但在 Debian 系统上不可用
  • WiltonDB 目前基于 PostgreSQL 15 编译,因此您需要指定 pg_version: 15
  • 在 EL 系统上,wiltondb 二进制文件默认安装在 /usr/bin/ 目录中,而在 Ubuntu 系统上,它安装在 /usr/lib/postgresql/15/bin/ 目录中,这与官方 PostgreSQL 二进制文件位置不同。
  • 在 WiltonDB 兼容模式下,HBA 密码认证规则需要使用 md5 而不是 scram-sha-256。因此,您需要覆盖 Pigsty 的默认 HBA 规则集,并在 dbrole_readonly 通配符认证规则之前插入 SQL Server 所需的 md5 认证规则。
  • WiltonDB 只能为主数据库启用,您应该指定一个用户作为 Babelfish 超级用户,允许 Babelfish 创建数据库和用户。默认是 mssqldbuser_myssql。如果您更改了这个,您还应该修改 files/mssql.sql 中的用户。
  • WiltonDB TDS 线协议兼容性插件 babelfishpg_tds 需要在 shared_preload_libraries 中启用。
  • 启用 WiltonDB 扩展后,它监听默认的 MSSQL 端口 1433。您可以覆盖 Pigsty 的默认服务定义,将 primaryreplica 服务重定向到端口 1433 而不是 5432 / 6432 端口。

需要为 MSSQL 数据库集群配置以下参数:

pg-meta:
  hosts:
    10.10.10.10: { pg_seq: 1, pg_role: primary }
  vars:
    pg_cluster: pg-meta
    pg_users:
      - {name: dbuser_mssql ,password: DBUser.MSSQL ,superuser: true, pgbouncer: true ,roles: [dbrole_admin], comment: superuser & owner for babelfish  }
    pg_databases:
      - name: mssql
        baseline: mssql.sql
        extensions: [uuid-ossp, babelfishpg_common, babelfishpg_tsql, babelfishpg_tds, babelfishpg_money, pg_hint_plan, system_stats, tds_fdw]
        owner: dbuser_mssql
        parameters: { 'babelfishpg_tsql.migration_mode' : 'multi-db' }
        comment: babelfish cluster, a MSSQL compatible pg cluster
    node_crontab: [ '00 01 * * * postgres /pg/bin/pg-backup full' ] # 每天凌晨 1 点进行全量备份

    # Babelfish / WiltonDB 临时设置
    pg_mode: mssql                     # Microsoft SQL Server 兼容模式
    pg_version: 15
    pg_packages: [ wiltondb, pgsql-common, sqlcmd ]
    pg_libs: 'babelfishpg_tds, pg_stat_statements, auto_explain' # 将 timescaledb 添加到 shared_preload_libraries
    pg_default_hba_rules: # 覆盖 babelfish 集群的默认 HBA 规则
      - { user: '${dbsu}'    ,db: all         ,addr: local     ,auth: ident ,title: 'dbsu access via local os user ident' }
      - { user: '${dbsu}'    ,db: replication ,addr: local     ,auth: ident ,title: 'dbsu replication from local os ident' }
      - { user: '${repl}'    ,db: replication ,addr: localhost ,auth: pwd   ,title: 'replicator replication from localhost' }
      - { user: '${repl}'    ,db: replication ,addr: intra     ,auth: pwd   ,title: 'replicator replication from intranet' }
      - { user: '${repl}'    ,db: postgres    ,addr: intra     ,auth: pwd   ,title: 'replicator postgres db from intranet' }
      - { user: '${monitor}' ,db: all         ,addr: localhost ,auth: pwd   ,title: 'monitor from localhost with password' }
      - { user: '${monitor}' ,db: all         ,addr: infra     ,auth: pwd   ,title: 'monitor from infra host with password' }
      - { user: '${admin}'   ,db: all         ,addr: infra     ,auth: ssl   ,title: 'admin @ infra nodes with pwd & ssl' }
      - { user: '${admin}'   ,db: all         ,addr: world     ,auth: ssl   ,title: 'admin @ everywhere with ssl & pwd' }
      - { user: dbuser_mssql ,db: mssql       ,addr: intra     ,auth: md5   ,title: 'allow mssql dbsu intranet access' } # <--- 为 mssql 用户使用 md5 认证方法
      - { user: '+dbrole_readonly',db: all    ,addr: localhost ,auth: pwd   ,title: 'pgbouncer read/write via local socket' }
      - { user: '+dbrole_readonly',db: all    ,addr: intra     ,auth: pwd   ,title: 'read/write biz user via password' }
      - { user: '+dbrole_offline' ,db: all    ,addr: intra     ,auth: pwd   ,title: 'allow etl offline tasks from intranet' }
    pg_default_services: # 将 primary 和 replica 服务路由到 mssql 端口 1433
      - { name: primary ,port: 5433 ,dest: 1433  ,check: /primary   ,selector: "[]" }
      - { name: replica ,port: 5434 ,dest: 1433  ,check: /read-only ,selector: "[]" , backup: "[? pg_role == `primary` || pg_role == `offline` ]" }
      - { name: default ,port: 5436 ,dest: postgres ,check: /primary   ,selector: "[]" }
      - { name: offline ,port: 5438 ,dest: postgres ,check: /replica   ,selector: "[? pg_role == `offline` || pg_offline_query ]" , backup: "[? pg_role == `replica` && !pg_offline_query]" }

您可以在 pg_databasespg_users 部分定义业务数据库和用户:

#----------------------------------#
# pgsql (singleton on current node)
#----------------------------------#
# 这是一个在当前节点上安装了 postgis 和 timescaledb 的单节点 postgres 集群示例,包含一个业务数据库和两个业务用户
pg-meta:
  hosts:
    10.10.10.10: { pg_seq: 1, pg_role: primary } # <---- 具有读写能力的主实例
  vars:
    pg_cluster: pg-test
    pg_users:                           # 创建 MSSQL 超级用户
      - {name: dbuser_mssql ,password: DBUser.MSSQL ,superuser: true, pgbouncer: true ,roles: [dbrole_admin], comment: superuser & owner for babelfish  }
    pg_primary_db: mssql                # 使用 `mssql` 作为主 sql server 数据库
    pg_databases:
      - name: mssql
        baseline: mssql.sql             # 初始化 babelfish 数据库和用户
        extensions:
          - { name: uuid-ossp          }
          - { name: babelfishpg_common }
          - { name: babelfishpg_tsql   }
          - { name: babelfishpg_tds    }
          - { name: babelfishpg_money  }
          - { name: pg_hint_plan       }
          - { name: system_stats       }
          - { name: tds_fdw            }
        owner: dbuser_mssql
        parameters: { 'babelfishpg_tsql.migration_mode' : 'multi-db' }
        comment: babelfish cluster, a MSSQL compatible pg cluster

客户端访问

您可以使用任何兼容 SQL Server 的客户端工具来访问此数据库集群。

Microsoft 提供 sqlcmd 作为官方命令行工具。

此外,他们还有一个 go 版本的 cli 工具:go-sqlcmd

安装 go-sqlcmd

curl -LO https://github.com/microsoft/go-sqlcmd/releases/download/v1.4.0/sqlcmd-v1.4.0-linux-amd64.tar.bz2
tar xjvf sqlcmd-v1.4.0-linux-amd64.tar.bz2
sudo mv sqlcmd* /usr/bin/

开始使用 go-sqlcmd

$ sqlcmd -S 10.10.10.10,1433 -U dbuser_mssql -P DBUser.MSSQL
1> select @@version
2> go
version
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Babelfish for PostgreSQL with SQL Server Compatibility - 12.0.2000.8
Oct 22 2023 17:48:32
Copyright (c) Amazon Web Services
PostgreSQL 15.4 (EL 1:15.4.wiltondb3.3_2-2.el8) on x86_64-redhat-linux-gnu (Babelfish 3.3.0)

(1 row affected)

您可以将服务流量路由到 MSSQL 1433 端口而不是 5433/5434:

# 将所有成员上的 5433 路由到主节点上的 1433
sqlcmd -S 10.10.10.11,5433 -U dbuser_mssql -P DBUser.MSSQL

# 将所有成员上的 5434 路由到副本上的 1433
sqlcmd -S 10.10.10.11,5434 -U dbuser_mssql -P DBUser.MSSQL

安装

如果您有互联网访问权限,可以将 WiltonDB 仓库添加到节点并直接作为节点包安装:

node_repo_modules: local,node,pgsql,mssql
node_packages: [ wiltondb ]

使用以下命令安装 wiltondb:

./node.yml -t node_repo,node_pkg

在同一个节点上安装原版 PostgreSQL 和 WiltonDB 是可以的,但一次只能运行其中一个,不建议在生产环境中这样做。


扩展

PGSQL 模块的大多数扩展(非 SQL 类)不能直接在 MSSQL 模块的 WiltonDB 内核上使用,需要重新编译。

WiltonDB 目前附带以下扩展插件:

名称 版本 注释
dblink 1.2 从数据库内连接到其他 PostgreSQL 数据库
adminpack 2.1 PostgreSQL 的管理功能
dict_int 1.0 整数的文本搜索字典模板
intagg 1.1 整数聚合器和枚举器(已过时)
dict_xsyn 1.0 扩展同义词处理的文本搜索字典模板
amcheck 1.3 验证关系完整性的函数
autoinc 1.0 自动递增字段的函数
bloom 1.0 bloom 访问方法 - 基于签名文件的索引
fuzzystrmatch 1.1 确定字符串之间的相似性和距离
intarray 1.5 1-D 整数数组的函数、操作符和索引支持
btree_gin 1.3 在 GIN 中索引常见数据类型的支持
btree_gist 1.7 在 GiST 中索引常见数据类型的支持
hstore 1.8 存储(键,值)对集合的数据类型
hstore_plperl 1.0 hstore 和 plperl 之间的转换
isn 1.2 国际产品编号标准的数据类型
hstore_plperlu 1.0 hstore 和 plperlu 之间的转换
jsonb_plperl 1.0 jsonb 和 plperl 之间的转换
citext 1.6 不区分大小写字符串的数据类型
jsonb_plperlu 1.0 jsonb 和 plperlu 之间的转换
jsonb_plpython3u 1.0 jsonb 和 plpython3u 之间的转换
cube 1.5 多维立方体的数据类型
hstore_plpython3u 1.0 hstore 和 plpython3u 之间的转换
earthdistance 1.1 计算地球表面的大圆距离
lo 1.1 大对象维护
file_fdw 1.0 平面文件访问的外部数据包装器
insert_username 1.0 跟踪谁更改了表的函数
ltree 1.2 分层树状结构的数据类型
ltree_plpython3u 1.0 ltree 和 plpython3u 之间的转换
pg_walinspect 1.0 检查 PostgreSQL 写前日志内容的函数
moddatetime 1.0 跟踪最后修改时间的函数
old_snapshot 1.0 支持 old_snapshot_threshold 的实用程序
pgcrypto 1.3 加密函数
pgrowlocks 1.2 显示行级锁定信息
pageinspect 1.11 在低级别检查数据库页面的内容
pg_surgery 1.0 对损坏关系进行手术的扩展
seg 1.4 表示线段或浮点区间的数据类型
pgstattuple 1.5 显示元组级统计信息
pg_buffercache 1.3 检查共享缓冲区缓存
pg_freespacemap 1.2 检查空闲空间映射(FSM)
postgres_fdw 1.1 远程 PostgreSQL 服务器的外部数据包装器
pg_prewarm 1.2 预热关系数据
tcn 1.0 触发的更改通知
pg_trgm 1.6 基于三元组的文本相似度测量和索引搜索
xml2 1.1 XPath 查询和 XSLT
refint 1.0 实现引用完整性的函数(已过时)
pg_visibility 1.2 检查可见性映射(VM)和页面级可见性信息
pg_stat_statements 1.10 跟踪所有已执行 SQL 语句的规划和执行统计信息
sslinfo 1.2 SSL 证书信息
tablefunc 1.0 操作整个表的函数,包括交叉表
tsm_system_rows 1.0 接受行数作为限制的 TABLESAMPLE 方法
tsm_system_time 1.0 接受毫秒时间作为限制的 TABLESAMPLE 方法
unaccent 1.1 去除重音符号的文本搜索字典
uuid-ossp 1.1 生成通用唯一标识符(UUID)
plpgsql 1.0 PL/pgSQL 过程语言
babelfishpg_money 1.1.0 babelfishpg_money
system_stats 2.0 PostgreSQL 的 EnterpriseDB 系统统计信息
tds_fdw 2.0.3 查询 TDS 数据库(Sybase 或 Microsoft SQL Server)的外部数据包装器
babelfishpg_common 3.3.3 Transact SQL 数据类型支持
babelfishpg_tds 1.0.0 TDS 协议扩展
pg_hint_plan 1.5.1
babelfishpg_tsql 3.3.1 Transact SQL 兼容性

4 - IvorySQL

具有 Oracle(语法)兼容性的 PostgreSQL 分支

IvorySQL 是一个开源的"Oracle 兼容"PostgreSQL 内核,由 HighGo 开发,采用 Apache 2.0 许可证。

这里的 Oracle 兼容性是指在 PL/SQL、语法、内置函数、数据类型、系统视图、MERGE 和 GUC 参数级别的兼容性。它不是像 BabelfishopenHaloFerretDB 那样的线协议兼容性, 不能使用原始客户端驱动程序。用户仍需要使用 PostgreSQL 客户端工具访问 IvorySQL,但可以使用 Oracle 兼容的语法。

目前,IvorySQL 的最新版本 5.0 与 PostgreSQL 的最新次要版本 18.0 保持兼容,并为主流 Linux 发行版提供二进制 RPM/DEB 包。 Pigsty 提供了在 PG RDS 中用 IvorySQL 内核替换原生 PostgreSQL 的选项,支持所有 Pigsty 支持的 Linux 系统。


快速开始

使用标准流程以 ivory 配置模板 安装 Pigsty:

curl -fsSL https://repo.pigsty.io/get | bash -s v3.7.0; cd ~/pigsty;
./configure -c ivory     # 使用 IvorySQL 配置模板
./install.yml            # 运行安装剧本

对于生产部署,您应该编辑自动生成的 pigsty.yml 配置文件,在执行 ./install.yml 进行部署之前修改密码等参数。

最新的 IvorySQL 5.0 等价于 PostgreSQL 18.0。任何与 PostgreSQL 线协议兼容的客户端工具都可以访问 IvorySQL 集群。

默认情况下,您可以使用 PostgreSQL 客户端通过替代的 1521 端口访问,该端口默认启用 Oracle 兼容模式。


配置说明

要在 Pigsty 中使用 IvorySQL 内核,请修改以下四个配置参数:

就这么简单——只需在配置文件的全局变量中添加这四行,Pigsty 就会用 IvorySQL 替换原生 PostgreSQL 内核:

pg_mode: ivory                           # IvorySQL 兼容模式,使用 IvorySQL 二进制文件
pg_packages: [ ivorysql, pgsql-common ]  # 安装 ivorysql,替换 pgsql-main 内核
pg_libs: 'liboracle_parser, pg_stat_statements, auto_explain'  # 加载 Oracle 兼容性扩展
repo_extra_packages: [ ivorysql ]        # 下载 ivorysql 包

IvorySQL 还提供了一系列新的 GUC 参数,可以在 pg_parameters 中指定。


扩展

PGSQL 模块的大多数扩展(非 SQL 类)不能直接在 IvorySQL 内核上使用。 如果您需要使用它们,您需要为新内核从源代码重新编译和安装。


注意事项

  • IvorySQL 软件包位于 pigsty-infra 仓库中,而不在 pigsty-pgsqlpigsty-ivory 仓库中。
  • Pigsty 不为使用 IvorySQL 内核承担任何保证,任何问题或请求应联系制造商。

5 - Percona

支持 TDE 的 Percona Postgres 发行版

Percona Postgres 是一个带有 pg_tde(透明数据加密)扩展的补丁 Postgres 内核。

它与 PostgreSQL 18.1 兼容,在所有 Pigsty 支持的平台上都可用。


快速开始

使用 pgtde 配置模板 安装 Pigsty。

curl -fsSL https://repo.pigsty.io/get | bash -s v3.7.0; cd ~/pigsty;
./configure -c pgtde     # 使用 percona postgres 内核
./install.yml            # 使用 pigsty 设置一切

配置

需要调整以下参数来部署 Percona 集群:

pg-meta:
  hosts:
    10.10.10.10: { pg_seq: 1, pg_role: primary }
  vars:
    pg_cluster: pg-meta
    pg_users:
      - { name: dbuser_meta ,password: DBUser.Meta   ,pgbouncer: true ,roles: [dbrole_admin   ] ,comment: pigsty admin user }
      - { name: dbuser_view ,password: DBUser.Viewer ,pgbouncer: true ,roles: [dbrole_readonly] ,comment: read-only viewer  }
    pg_databases:
      - name: meta
        baseline: cmdb.sql
        comment: pigsty tde database
        schemas: [pigsty]
        extensions: [ vector, postgis, pg_tde ,pgaudit, { name: pg_stat_monitor, schema: monitor } ]
    pg_hba_rules:
      - { user: dbuser_view , db: all ,addr: infra ,auth: pwd ,title: 'allow grafana dashboard access cmdb from infra nodes' }
    node_crontab: [ '00 01 * * * postgres /pg/bin/pg-backup full' ] # 每天凌晨 1 点进行全量备份

    # Percona PostgreSQL TDE 临时设置
    pg_packages: [ percona-main, pgsql-common ]  # 安装 percona postgres 包
    pg_libs: 'pg_tde, pgaudit, pg_stat_statements, pg_stat_monitor, auto_explain'

扩展

Percona 提供了 80 个可用的扩展,包括 pg_tde, pgvector, postgis, pgaudit, set_user, pg_stat_monitor 等实用三方扩展。

name version comment
hstore_plperlu 1.0 transform between hstore and plperlu
jsonb_plperl 1.0 transform between jsonb and plperl
intagg 1.1 integer aggregator and enumerator (obsolete)
pltcl 1.0 PL/Tcl procedural language
isn 1.3 data types for international product numbering standards
pgstattuple 1.5 show tuple-level statistics
postgis_topology-3 3.5.4 PostGIS topology spatial types and functions
postgis_raster 3.5.4 PostGIS raster types and functions
tsm_system_rows 1.0 TABLESAMPLE method which accepts number of rows as a limit
lo 1.2 Large Object maintenance
hstore_plperl 1.0 transform between hstore and plperl
ltree 1.3 data type for hierarchical tree-like structures
postgis_raster-3 3.5.4 PostGIS raster types and functions
postgis_topology 3.5.4 PostGIS topology spatial types and functions
pgrowlocks 1.2 show row-level locking information
address_standardizer_data_us-3 3.5.4 Address Standardizer US dataset example
uuid-ossp 1.1 generate universally unique identifiers (UUIDs)
postgis-3 3.5.4 PostGIS geometry and geography spatial types and functions
hstore_plpython3u 1.0 transform between hstore and plpython3u
postgis 3.5.4 PostGIS geometry and geography spatial types and functions
set_user 4.2.0 similar to SET ROLE but with added logging
postgis_tiger_geocoder-3 3.5.4 PostGIS tiger geocoder and reverse geocoder
jsonb_plperlu 1.0 transform between jsonb and plperlu
pg_surgery 1.0 extension to perform surgery on a damaged relation
xml2 1.2 XPath querying and XSLT
pg_stat_monitor 2.3 The pg_stat_monitor is a PostgreSQL Query Performance Monitoring tool, based on PostgreSQL contrib module pg_stat_statements. pg_stat_monitor provides aggregated statistics, client information, plan details including plan, and histogram information.
pg_tde 2.1 pg_tde access method
plpgsql 1.0 PL/pgSQL procedural language
address_standardizer-3 3.5.4 Used to parse an address into constituent elements. Generally used to support geocoding address normalization step.
tablefunc 1.0 functions that manipulate whole tables, including crosstab
hstore 1.8 data type for storing sets of (key, value) pairs
vector 0.8.1 vector data type and ivfflat and hnsw access methods
postgis_tiger_geocoder 3.5.4 PostGIS tiger geocoder and reverse geocoder
dblink 1.2 connect to other PostgreSQL databases from within a database
pltclu 1.0 PL/TclU untrusted procedural language
pg_trgm 1.6 text similarity measurement and index searching based on trigrams
sslinfo 1.2 information about SSL certificates
pg_stat_statements 1.12 track planning and execution statistics of all SQL statements executed
bool_plperlu 1.0 transform between bool and plperlu
cube 1.5 data type for multidimensional cubes
ltree_plpython3u 1.0 transform between ltree and plpython3u
amcheck 1.5 functions for verifying relation integrity
postgis_sfcgal 3.5.4 PostGIS SFCGAL functions
plpython3u 1.0 PL/Python3U untrusted procedural language
tsm_system_time 1.0 TABLESAMPLE method which accepts time in milliseconds as a limit
intarray 1.5 functions, operators, and index support for 1-D arrays of integers
btree_gist 1.8 support for indexing common datatypes in GiST
plperlu 1.0 PL/PerlU untrusted procedural language
fuzzystrmatch 1.2 determine similarities and distance between strings
bool_plperl 1.0 transform between bool and plperl
btree_gin 1.3 support for indexing common datatypes in GIN
pg_prewarm 1.2 prewarm relation data
pg_repack 1.5.3 Reorganize tables in PostgreSQL databases with minimal locks
citext 1.8 data type for case-insensitive character strings
pgcrypto 1.4 cryptographic functions
moddatetime 1.0 functions for tracking last modification time
plperl 1.0 PL/Perl procedural language
seg 1.4 data type for representing line segments or floating-point intervals
earthdistance 1.2 calculate great-circle distances on the surface of the Earth
unaccent 1.1 text search dictionary that removes accents
postgres_fdw 1.2 foreign-data wrapper for remote PostgreSQL servers
pg_logicalinspect 1.0 functions to inspect logical decoding components
tcn 1.0 Triggered change notifications
bloom 1.0 bloom access method - signature file based index
dict_int 1.0 text search dictionary template for integers
autoinc 1.0 functions for autoincrementing fields
address_standardizer_data_us 3.5.4 Address Standardizer US dataset example
postgis_sfcgal-3 3.5.4 PostGIS SFCGAL functions
jsonb_plpython3u 1.0 transform between jsonb and plpython3u
file_fdw 1.0 foreign-data wrapper for flat file access
pgaudit 18.0 provides auditing functionality
dict_xsyn 1.0 text search dictionary template for extended synonym processing
pg_walinspect 1.1 functions to inspect contents of PostgreSQL Write-Ahead Log
pg_buffercache 1.6 examine the shared buffer cache
refint 1.0 functions for implementing referential integrity (obsolete)
pg_freespacemap 1.3 examine the free space map (FSM)
insert_username 1.0 functions for tracking who changed a table
address_standardizer 3.5.4 Used to parse an address into constituent elements. Generally used to support geocoding address normalization step.
pg_visibility 1.2 examine the visibility map (VM) and page-level visibility info
pageinspect 1.13 inspect the contents of database pages at a low level

6 - PolarDB

PolarDB for PostgreSQL,带有 aurora 风格的 RAC

PolarDB 是一个由阿里云开发并开源的 aurora RAC 风格"云原生"数据库系统。

当前仓库中的最新版本 v15.15.5.0 与 PostgreSQL 15 兼容,在所有 Pigsty 支持的操作系统上都可用。


快速开始

使用 polar 配置模板 安装 Pigsty。

curl -fsSL https://repo.pigsty.io/get | bash -s v3.7.0; cd ~/pigsty;
./configure -c polar     # 使用 polar(PolarDB)模板
./install.yml            # 运行部署剧本

配置

需要调整以下参数来部署 PolarDB 集群:

pg-meta:
  hosts:
    10.10.10.10: { pg_seq: 1, pg_role: primary }
  vars:
    pg_cluster: pg-meta
    pg_users:
      - {name: dbuser_meta ,password: DBUser.Meta   ,pgbouncer: true ,roles: [dbrole_admin]    ,comment: pigsty admin user }
      - {name: dbuser_view ,password: DBUser.Viewer ,pgbouncer: true ,roles: [dbrole_readonly] ,comment: read-only viewer for meta database }
    pg_databases:
      - {name: meta ,baseline: cmdb.sql ,comment: pigsty meta database ,schemas: [pigsty]}
    pg_hba_rules:
      - {user: dbuser_view , db: all ,addr: infra ,auth: pwd ,title: 'allow grafana dashboard access cmdb from infra nodes'}
    node_crontab: [ '00 01 * * * postgres /pg/bin/pg-backup full' ] # 每天凌晨 1 点进行全量备份

    # PolarDB 临时设置
    pg_version: 15                            # PolarDB PG 基于 PG 15
    pg_mode: polar                            # PolarDB PG 兼容模式
    pg_packages: [ polardb, pgsql-common ]    # 用 PolarDB 内核替换 PG 内核
    pg_exporter_exclude_database: 'template0,template1,postgres,polardb_admin'
    pg_default_roles:                         # PolarDB 要求 replicator 为超级用户
      - { name: dbrole_readonly  ,login: false ,comment: role for global read-only access     }
      - { name: dbrole_offline   ,login: false ,comment: role for restricted read-only access }
      - { name: dbrole_readwrite ,login: false ,roles: [dbrole_readonly] ,comment: role for global read-write access }
      - { name: dbrole_admin     ,login: false ,roles: [pg_monitor, dbrole_readwrite] ,comment: role for object creation }
      - { name: postgres     ,superuser: true  ,comment: system superuser }
      - { name: replicator   ,superuser: true  ,replication: true ,roles: [pg_monitor, dbrole_readonly] ,comment: system replicator } # <- 复制需要超级用户权限
      - { name: dbuser_dba   ,superuser: true  ,roles: [dbrole_admin]  ,pgbouncer: true ,pool_mode: session, pool_connlimit: 16 ,comment: pgsql admin user }
      - { name: dbuser_monitor ,roles: [pg_monitor] ,pgbouncer: true ,parameters: {log_min_duration_statement: 1000 } ,pool_mode: session ,pool_connlimit: 8 ,comment: pgsql monitor user }

PolarDB for PostgreSQL 本质上等价于 PostgreSQL 15,任何与 PostgreSQL 线协议兼容的客户端工具都可以访问 PolarDB 集群。

扩展

PGSQL 模块的大多数扩展(非纯 SQL)不能直接在 PolarDB 内核上使用。如果您需要使用它们,您需要为新内核从源代码重新编译和安装。

这是 PolarDB 内核提供的扩展列表:

name Version comment
adminpack 2.1 administrative functions for PostgreSQL
amcheck 1.3 functions for verifying relation integrity
autoinc 1.0 functions for autoincrementing fields
bloom 1.0 bloom access method - signature file based index
bool_plperl 1.0 transform between bool and plperl
bool_plperlu 1.0 transform between bool and plperlu
btree_gin 1.3 support for indexing common datatypes in GIN
btree_gist 1.7 support for indexing common datatypes in GiST
citext 1.6 data type for case-insensitive character strings
cube 1.5 data type for multidimensional cubes
dblink 1.2 connect to other PostgreSQL databases from within a database
dict_int 1.0 text search dictionary template for integers
dict_xsyn 1.0 text search dictionary template for extended synonym processing
earthdistance 1.1 calculate great-circle distances on the surface of the Earth
file_fdw 1.0 foreign-data wrapper for flat file access
fuzzystrmatch 1.1 determine similarities and distance between strings
hll 2.18 type for storing hyperloglog data
hstore 1.8 data type for storing sets of (key, value) pairs
hstore_plperl 1.0 transform between hstore and plperl
hstore_plperlu 1.0 transform between hstore and plperlu
hstore_plpython3u 1.0 transform between hstore and plpython3u
hypopg 1.3.1 Hypothetical indexes for PostgreSQL
insert_username 1.0 functions for tracking who changed a table
intagg 1.1 integer aggregator and enumerator (obsolete)
intarray 1.5 functions, operators, and index support for 1-D arrays of integers
isn 1.2 data types for international product numbering standards
jsonb_plperl 1.0 transform between jsonb and plperl
jsonb_plperlu 1.0 transform between jsonb and plperlu
jsonb_plpython3u 1.0 transform between jsonb and plpython3u
lo 1.1 Large Object maintenance
log_fdw 1.4 foreign-data wrapper for Postgres log file access
ltree 1.2 data type for hierarchical tree-like structures
ltree_plpython3u 1.0 transform between ltree and plpython3u
moddatetime 1.0 functions for tracking last modification time
old_snapshot 1.0 utilities in support of old_snapshot_threshold
pageinspect 1.11 inspect the contents of database pages at a low level
pase 0.0.1 ant ai similarity search
pg_bigm 1.2 text similarity measurement and index searching based on bigrams
pg_buffercache 1.4 examine the shared buffer cache
pg_freespacemap 1.2 examine the free space map (FSM)
pg_jieba 1.1.0 a parser for full-text search of Chinese
pg_prewarm 1.2 prewarm relation data
pg_repack 1.5.1-1 Reorganize tables in PostgreSQL databases with minimal locks
pg_stat_statements 1.10 track planning and execution statistics of all SQL statements executed
pg_surgery 1.0 extension to perform surgery on a damaged relation
pg_trgm 1.6 text similarity measurement and index searching based on trigrams
pg_visibility 1.2 examine the visibility map (VM) and page-level visibility info
pg_walinspect 1.0 functions to inspect contents of PostgreSQL Write-Ahead Log
pgcrypto 1.3 cryptographic functions
pgrowlocks 1.2 show row-level locking information
pgstattuple 1.5 show tuple-level statistics
plperl 1.0 PL/Perl procedural language
plperlu 1.0 PL/PerlU untrusted procedural language
plpgsql 1.0 PL/pgSQL procedural language
plpython3u 1.0 PL/Python3U untrusted procedural language
pltcl 1.0 PL/Tcl procedural language
pltclu 1.0 PL/TclU untrusted procedural language
polar_audit 1.0 provides auditing functionality
polar_feature_utils 1.0 PolarDB feature utilization
polar_io_stat 1.0 polar io stat in multi dimension
polar_login_history 1.0 record user login information
polar_masking 1.0.0 provides data masking for polardb
polar_monitor 1.0 monitor functions for PolarDB
polar_monitor_preload 1.0 examine the polardb information
polar_parameter_manager 1.1 Extension to select parameters for manger.
polar_password_policy 1.0 create password policies and check user passwords based on the policies
polar_proxy_utils 1.0 Extension to provide operations about proxy.
polar_resource_manager 1.0 a background process that forcibly frees user session process memory
polar_smgrperf 1.0 smgr perf test extension
polar_sql_mapping 1.0 Record error sqls and mapping them to correct one
polar_stat_env 1.0 env stat functions for PolarDB
polar_vfs 1.0 polar virtual file system for different storage
polar_worker 1.0 polar_worker
postgres_fdw 1.1 foreign-data wrapper for remote PostgreSQL servers
refint 1.0 functions for implementing referential integrity (obsolete)
roaringbitmap 0.5 support for Roaring Bitmaps
seg 1.4 data type for representing line segments or floating-point intervals
sslinfo 1.2 information about SSL certificates
tablefunc 1.0 functions that manipulate whole tables, including crosstab
tcn 1.0 Triggered change notifications
tsm_system_rows 1.0 TABLESAMPLE method which accepts number of rows as a limit
tsm_system_time 1.0 TABLESAMPLE method which accepts time in milliseconds as a limit
unaccent 1.1 text search dictionary that removes accents
uuid-ossp 1.1 generate universally unique identifiers (UUIDs)
vector 0.6.2 vector data type and ivfflat and hnsw access methods
xml2 1.1 XPath querying and XSLT

PolarDB for Oracle

还有 PolarDB 的第二个分支,即 PolarDB for Oracle,它不是开源的。

Pigsty Pro 支持将 PolarDB for Oracle 作为 RDS 运行。

7 - OrioleDB

PostgreSQL 的下一代 OLTP 引擎

OrioleDB 是一个 PostgreSQL 存储引擎扩展,声称能够 提供 4 倍 OLTP 性能,没有 xid 环绕和表膨胀问题,并具有"云原生"(数据存储在 s3)能力。

OrioleDB 的最新版本基于 补丁版 PostgreSQL 17.0 和一个额外的扩展

您可以使用 pigsty 将 OrioleDB 作为 RDS 运行,它与 PG 17 兼容,在所有支持的 Linux 平台上都可用。 最新版本为 beta12 ,基于 PG 17_11 补丁。


快速开始

按照 Pigsty 标准安装 流程,使用 oriole 配置模板。

curl -fsSL https://repo.pigsty.io/get | bash -s v3.7.0; cd ~/pigsty;
./configure -c oriole    # 使用 OrioleDB 配置模板
./install.yml            # 使用 OrioleDB 安装 Pigsty

对于生产部署,请确保在运行 install 剧本之前修改 pigsty.yml 配置中的密码参数。


配置

pg-meta:
  hosts:
    10.10.10.10: { pg_seq: 1, pg_role: primary }
  vars:
    pg_cluster: pg-meta
    pg_users:
      - {name: dbuser_meta ,password: DBUser.Meta   ,pgbouncer: true ,roles: [dbrole_admin]    ,comment: pigsty admin user }
      - {name: dbuser_view ,password: DBUser.Viewer ,pgbouncer: true ,roles: [dbrole_readonly] ,comment: read-only viewer for meta database }
    pg_databases:
      - {name: meta ,baseline: cmdb.sql ,comment: pigsty meta database ,schemas: [pigsty], extensions: [orioledb]}
    pg_hba_rules:
      - {user: dbuser_view , db: all ,addr: infra ,auth: pwd ,title: 'allow grafana dashboard access cmdb from infra nodes'}
    node_crontab: [ '00 01 * * * postgres /pg/bin/pg-backup full' ] # 每天凌晨 1 点进行全量备份

    # OrioleDB 临时设置
    pg_mode: oriole                                         # oriole 兼容模式
    pg_packages: [ orioledb, pgsql-common ]                 # 安装 OrioleDB 内核
    pg_libs: 'orioledb, pg_stat_statements, auto_explain'   # 加载 OrioleDB 扩展

使用

要使用 OrioleDB,您需要安装 orioledb_17oriolepg_17 包(目前仅提供 RPM 版本)。

使用 pgbench 初始化类似 TPC-B 的表,包含 100 个仓库:

pgbench -is 100 meta
pgbench -nv -P1 -c10 -S -T1000 meta
pgbench -nv -P1 -c50 -S -T1000 meta
pgbench -nv -P1 -c10    -T1000 meta
pgbench -nv -P1 -c50    -T1000 meta

接下来,您可以使用 orioledb 存储引擎重建这些表并观察性能差异:

-- 创建 OrioleDB 表
CREATE TABLE pgbench_accounts_o (LIKE pgbench_accounts INCLUDING ALL) USING orioledb;
CREATE TABLE pgbench_branches_o (LIKE pgbench_branches INCLUDING ALL) USING orioledb;
CREATE TABLE pgbench_history_o (LIKE pgbench_history INCLUDING ALL) USING orioledb;
CREATE TABLE pgbench_tellers_o (LIKE pgbench_tellers INCLUDING ALL) USING orioledb;

-- 从常规表复制数据到 OrioleDB 表
INSERT INTO pgbench_accounts_o SELECT * FROM pgbench_accounts;
INSERT INTO pgbench_branches_o SELECT * FROM pgbench_branches;
INSERT INTO pgbench_history_o SELECT  * FROM pgbench_history;
INSERT INTO pgbench_tellers_o SELECT * FROM pgbench_tellers;

-- 删除原始表并重命名 OrioleDB 表
DROP TABLE pgbench_accounts, pgbench_branches, pgbench_history, pgbench_tellers;
ALTER TABLE pgbench_accounts_o RENAME TO pgbench_accounts;
ALTER TABLE pgbench_branches_o RENAME TO pgbench_branches;
ALTER TABLE pgbench_history_o RENAME TO pgbench_history;
ALTER TABLE pgbench_tellers_o RENAME TO pgbench_tellers;

8 - OpenHalo

MySQL 兼容的 Postgres 14 分支

OpenHalo 是一个开源的 PostgreSQL 内核,提供 MySQL 线协议兼容性。

OpenHalo 基于 PostgreSQL 14.10 内核版本,提供与 MySQL 5.7.32-log / 8.0 版本的线协议兼容性。

Pigsty 在所有支持的 Linux 平台上为 OpenHalo 提供部署支持。


快速开始

使用 Pigsty 的 标准安装流程mysql 配置模板。

curl -fsSL https://repo.pigsty.io/get | bash -s v3.7.0; cd ~/pigsty;
./configure -c mysql    # 使用 MySQL(openHalo)配置模板
./install.yml           # 安装,生产部署请先在 pigsty.yml 中修改密码

对于生产部署,请确保在运行安装剧本之前修改 pigsty.yml 配置文件中的密码参数。


配置

pg-meta:
  hosts:
    10.10.10.10: { pg_seq: 1, pg_role: primary }
  vars:
    pg_cluster: pg-meta
    pg_users:
      - {name: dbuser_meta ,password: DBUser.Meta   ,pgbouncer: true ,roles: [dbrole_admin]    ,comment: pigsty admin user }
      - {name: dbuser_view ,password: DBUser.Viewer ,pgbouncer: true ,roles: [dbrole_readonly] ,comment: read-only viewer for meta database }
    pg_databases:
      - {name: postgres, extensions: [aux_mysql]} # mysql 兼容数据库
      - {name: meta ,baseline: cmdb.sql ,comment: pigsty meta database ,schemas: [pigsty]}
    pg_hba_rules:
      - {user: dbuser_view , db: all ,addr: infra ,auth: pwd ,title: 'allow grafana dashboard access cmdb from infra nodes'}
    node_crontab: [ '00 01 * * * postgres /pg/bin/pg-backup full' ] # 每天凌晨 1 点进行全量备份

    # OpenHalo 临时设置
    pg_mode: mysql                    # HaloDB 的 MySQL 兼容模式
    pg_version: 14                    # 当前 HaloDB 兼容 PG 主版本 14
    pg_packages: [ openhalodb, pgsql-common ]  # 安装 openhalodb 而不是 postgresql 内核

使用

访问 MySQL 时,实际连接使用的是 postgres 数据库。请注意,MySQL 中的"数据库"概念实际上对应于 PostgreSQL 中的"Schema"。因此,use mysql 实际上使用的是 postgres 数据库内的 mysql Schema。

用于 MySQL 的用户名和密码与 PostgreSQL 中的相同。您可以使用标准的 PostgreSQL 方法管理用户和权限。

客户端访问

OpenHalo 提供 MySQL 线协议兼容性,默认监听端口 3306,允许 MySQL 客户端和驱动程序直接连接。

Pigsty 的 conf/mysql 配置默认安装 mysql 客户端工具。

您可以使用以下命令访问 MySQL:

mysql -h 127.0.0.1 -u dbuser_dba

目前,OpenHalo 官方确保 Navicat 可以正常访问此 MySQL 端口,但 Intellij IDEA 的 DataGrip 访问会导致错误。


修改

Pigsty 安装的 OpenHalo 内核基于 HaloTech-Co-Ltd/openHalo 内核进行了少量修改:

  • 将默认数据库名称从 halo0root 改回 postgres
  • 从默认版本号中删除 1.0. 前缀,恢复为 14.10
  • 修改默认配置文件以启用 MySQL 兼容性并默认监听端口 3306

请注意,Pigsty 不为使用 OpenHalo 内核提供任何保证。使用此内核时遇到的任何问题或需求应与原始供应商联系。

9 - Cloudberry

Cloudberry 和 Greenplum,MPP 数据仓库

您可以部署和监控 Cloudberry 集群,这是 Greenplum 的一个分支。

要定义 Greenplum 集群,您需要指定以下参数:

POC

我们正在等待 Apache Cloudberry 2.0 的官方发布,因此现在请勿在生产环境中使用


安装

要安装 cloudberry,您必须启用 gpsql 仓库模块:

./node.yml -t node_install  -e '{"node_repo_modules":"node,pgsql,gpsql","node_packages":["cloudberrydb"]}'

配置

设置 pg_mode = gpsql 和额外的标识参数 pg_shardgp_role

#================================================================#
#                        GPSQL 集群                              #
#================================================================#

#----------------------------------#
# 集群:mx-mdw (gp master)
#----------------------------------#
mx-mdw:
  hosts:
    10.10.10.10: { pg_seq: 1, pg_role: primary , nodename: mx-mdw-1 }
  vars:
    gp_role: master          # 此集群用作 greenplum master
    pg_shard: mx             # pgsql 分片名称和 gpsql 部署名称
    pg_cluster: mx-mdw       # 此 master 集群名称为 mx-mdw
    pg_databases:
      - { name: matrixmgr , extensions: [ { name: matrixdbts } ] }
      - { name: meta }
    pg_users:
      - { name: meta , password: DBUser.Meta , pgbouncer: true }
      - { name: dbuser_monitor , password: DBUser.Monitor , roles: [ dbrole_readonly ], superuser: true }

    pgbouncer_enabled: true                # 为 greenplum master 启用 pgbouncer
    pgbouncer_exporter_enabled: false      # 为 greenplum master 启用 pgbouncer_exporter
    pg_exporter_params: 'host=127.0.0.1&sslmode=disable'  # 使用 127.0.0.1 作为本地监控主机

#----------------------------------#
# 集群:mx-sdw (gp master)
#----------------------------------#
mx-sdw:
  hosts:
    10.10.10.11:
      nodename: mx-sdw-1        # greenplum 段节点
      pg_instances:             # greenplum 段实例
        6000: { pg_cluster: mx-seg1, pg_seq: 1, pg_role: primary , pg_exporter_port: 9633 }
        6001: { pg_cluster: mx-seg2, pg_seq: 2, pg_role: replica , pg_exporter_port: 9634 }
    10.10.10.12:
      nodename: mx-sdw-2
      pg_instances:
        6000: { pg_cluster: mx-seg2, pg_seq: 1, pg_role: primary , pg_exporter_port: 9633  }
        6001: { pg_cluster: mx-seg3, pg_seq: 2, pg_role: replica , pg_exporter_port: 9634  }
    10.10.10.13:
      nodename: mx-sdw-3
      pg_instances:
        6000: { pg_cluster: mx-seg3, pg_seq: 1, pg_role: primary , pg_exporter_port: 9633 }
        6001: { pg_cluster: mx-seg1, pg_seq: 2, pg_role: replica , pg_exporter_port: 9634 }
  vars:
    gp_role: segment               # 这些是 gp 段的节点
    pg_shard: mx                   # pgsql 分片名称和 gpsql 部署名称
    pg_cluster: mx-sdw             # 这些段集群名称为 mx-sdw
    pg_preflight_skip: true        # 跳过预检查(因为 pg_seq 和 pg_role 和 pg_cluster 不存在)
    pg_exporter_config: pg_exporter_basic.yml                             # 使用基本配置以避免段服务器崩溃
    pg_exporter_params: 'options=-c%20gp_role%3Dutility&sslmode=disable'  # 使用 gp_role = utility 连接到段

10 - Supabase

在您的 Postgres 上自托管 BaaS —— Supabase

最新的自托管教程请参阅:Supabase

Supabase 很好,拥有属于你自己的 supabase 则好上加好。 Pigsty 可以帮助您在自己的服务器上(物理机/虚拟机/云服务器),一键自建企业级 supabase —— 更多扩展,更好性能,更深入的控制,更合算的成本。

Pigsty 是 Supabase 官网文档上列举的三种自建部署之一:Self-hosting: Third-Party Guides


简短版本

准备 Linux,执行 Pigsty 标准安装 流程,选择 supabase 配置模板,依次执行:

curl -fsSL https://repo.pigsty.io/get | bash -s v3.7.0; cd ~/pigsty
./configure -c supabase    # 使用 supabase 配置(请在 pigsty.yml 中更改凭据)
vi pigsty.yml              # 编辑域名、密码、密钥...
./install.yml              # 安装 pigsty
./docker.yml               # 安装 docker compose 组件
./app.yml                  # 使用 docker 启动 supabase 无状态部分(可能较慢)

安装完毕后,使用浏览器访问 8000 端口造访 Supa Studio,用户名 supabase,密码 pigsty


目录


Supabase是什么?

Supabase 是一个 BaaS (Backend as Service),开源的 Firebase,是 AI Agent 时代最火爆的数据库 + 后端解决方案。 Supabase 对 PostgreSQL 进行了封装,并提供了身份认证,消息传递,边缘函数,对象存储,并基于 PG 数据库模式自动生成 REST API 与 GraphQL API。

Supabase 旨在为开发者提供一条龙式的后端解决方案,减少开发和维护后端基础设施的复杂性。 它能让开发者告别绝大部分后端开发的工作,只需要懂数据库设计与前端即可快速出活! 开发者只要用 Vibe Coding 糊个前端与数据库模式设计,就可以快速完成一个完整的应用。

目前,Supabase 是 PostgreSQL 开源生态 中人气最高的开源项目,在 GitHub 上已有 八万 Star。 Supabase 还为小微创业者提供了“慷慨”的免费云服务额度 —— 免费的 500 MB 空间,对于存个用户表,浏览数之类的东西绰绰有余。


为什么要自建?

既然 Supabase 云服务这么香,为什么要自建呢?

最直观的原因是是我们在《云数据库是智商税吗?》中提到过的:当你的数据/计算规模超出云计算适用光谱(Supabase:4C/8G/500MB免费存储),成本很容易出现爆炸式增长。 而且在当下,足够可靠的 本地企业级 NVMe SSD 在性价比上与 云端存储 有着三到四个数量级的优势,而自建能更好地利用这一点。

另一个重要的原因是 功能, Supabase 云服务的功能受限 —— 很多强力PG扩展因为多租户安全挑战与许可证的原因无法以云服务的形式。 故而尽管 扩展是 PostgreSQL 的核心特色,在 Supabase 云服务上也依然只有 64 个扩展可用。 而通过 Pigsty 自建的 Supabase 则提供了多达 437 个开箱即用的 PG 扩展。

此外,自主可控与规避供应商锁定也是自建的重要原因 —— 尽管 Supabase 虽然旨在提供一个无供应商锁定的 Google Firebase 开源替代,但实际上自建高标准企业级的 Supabase 门槛并不低。 Supabase 内置了一系列由他们自己开发维护的 PG 扩展插件,并计划将原生的 PostgreSQL 内核替换为收购的 OrioleDB,而这些内核与扩展在 PGDG 官方仓库中并没有提供。

这实际上是某种隐性的供应商锁定,阻止了用户使用除了 supabase/postgres Docker 镜像之外的方式自建,Pigsty 则提供开源,透明,通用的方案解决这个问题。 我们将所有 Supabase 自研与用到的 10 个缺失的扩展打成开箱即用的 RPM/DEB 包,确保它们在所有 主流Linux操作系统发行版 上都可用:

扩展 说明
pg_graphql 提供PG内的GraphQL支持 (RUST),Rust扩展,由PIGSTY提供
pg_jsonschema 提供JSON Schema校验能力,Rust扩展,由PIGSTY提供
wrappers Supabase提供的外部数据源包装器捆绑包,,Rust扩展,由PIGSTY提供
index_advisor 查询索引建议器,SQL扩展,由PIGSTY提供
pg_net 用 SQL 进行异步非阻塞HTTP/HTTPS 请求的扩展 (supabase),C扩展,由PIGSTY提供
vault 在 Vault 中存储加密凭证的扩展 (supabase),C扩展,由PIGSTY提供
pgjwt JSON Web Token API 的PG实现 (supabase),SQL扩展,由PIGSTY提供
pgsodium 表数据加密存储 TDE,扩展,由PIGSTY提供
supautils 用于在云环境中确保数据库集群的安全,C扩展,由PIGSTY提供
pg_plan_filter 使用执行计划代价过滤阻止特定查询语句,C扩展,由PIGSTY提供

同时,我们在 Supabase 自建部署中默认 安装绝大多数扩展,您可以参考可用扩展列表按需 启用

同时,Pigsty 还会负责好底层 高可用 PostgreSQL 数据库集群,高可用 MinIO 对象存储集群的自动搭建,甚至是 Docker 容器底座的部署与 Nginx 反向代理,域名配置HTTPS证书签发。 您可以使用 Docker Compose 拉起任意数量的无状态 Supabase 容器集群,并将状态存储在外部 Pigsty 自托管数据库服务中。

在这一自建部署架构中,您获得了使用不同内核的自由(PG 15-18,OrioleDB),加装 437 个扩展的自由,扩容与伸缩 Supabase / Postgres / MinIO 的自由, 免于数据库运维杂务的自由,以及免于供应商锁定,本地运行到地老天荒的自由。 而相比于使用云服务需要付出的代价,不过是准备服务器和多敲几行命令而已。


单节点自建快速上手

让我们先从单节点 Supabase 部署开始,我们会在后面进一步介绍多节点高可用部署的方法。

准备 一台全新 Linux 服务器,使用 Pigsty 提供的 supabase 配置模板执行 标准安装, 然后额外运行 docker.ymlapp.yml 拉起无状态部分的 Supabase 容器即可(默认端口 8000/8433)。

curl -fsSL https://repo.pigsty.io/get | bash -s v3.7.0; cd ~/pigsty
./configure -c supabase    # 使用 supabase 配置(请在 pigsty.yml 中更改凭据)
vi pigsty.yml              # 编辑域名、密码、密钥...
./install.yml              # 安装 pigsty
./docker.yml               # 安装 docker compose 组件
./app.yml                  # 使用 docker 启动 supabase 无状态部分

在部署 Supabase 前请根据实际情况修改自动生成的 pigsty.yml 配置文件中的参数(域名与密码) 如果只是本地开发测试,可以先跳过,我们将在后面介绍如何通过修改配置文件来进一步定制。

asciicast

如果配置无误,大约十分钟后,就可以在本地网络通过 http://<your_ip_address>:8000 访问到 Supabase Studio 图形管理界面了。 默认的用户名与密码分别是: supabasepigsty

中国大陆地区 DockerHub 被墙

在中国大陆地区,Pigsty 默认使用 1Panel 与 1ms 提供的 DockerHub 镜像站点下载 Supabase 相关镜像,可能会较慢。 你也可以自行配置 代理镜像站cd /opt/supabase; docker compose pull 手动拉取镜像。 我们亦提供包含完整离线安装方案的 Supabase 自建专家咨询服务

使用 Supabase 的对象存储需要HTTPS/域名

如果你需要使用的对象存储功能,那么需要通过域名与 HTTPS 访问 Supabase,否则会出现报错。

生产部署请务必修改密码!

对于严肃的生产部署,请 务必 修改所有默认密码!


自建关键技术决策

以下是一些自建 Supabase 会涉及到的关键技术决策,供您参考:

使用默认的单节点部署 Supabase 无法享受到 PostgreSQL / MinIO 的高可用能力。 尽管如此,单节点部署相比官方纯 Docker Compose 方案依然要有显著优势: 例如开箱即用的监控系统,自由安装扩展的能力,各个组件的扩缩容能力,以及提供兜底数据库时间点恢复能力等。

如果您只有一台服务器,或者选择在云服务器上自建,Pigsty 建议您使用外部的 S3 替代本地的 MinIO 作为对象存储,存放 PostgreSQL 的备份,并承载 Supabase Storage 服务。 这样的部署在故障时可以在单机部署条件下,提供一个兜底级别的 RTO (小时级恢复时长)/ RPO (MB级数据损失)容灾水平。

在严肃的生产部署中,Pigsty 建议使用至少3~4个节点的部署策略,确保 MinIO 与 PostgreSQL 都使用满足企业级高可用要求的多节点部署。 在这种情况下,您需要相应准备更多节点与磁盘,并相应调整 pigsty.yml 配置清单中的集群配置,以及 supabase 集群配置中的接入信息,使用高可用接入点访问服务。

Supabase 的部分功能需要发送邮件,所以要用到 SMTP 服务。除非单纯用于内网,否则对于严肃的生产部署,建议使用 SMTP 云服务。自建的邮件服务器发送的邮件容易被标记为垃圾邮件导致拒收。

如果您的服务直接向公网暴露,我们强烈建议您使用真正的域名与 HTTPS 证书,并通过 Nginx 门户 访问。

接下来,我们会依次讨论一些进阶主题。如何在单节点部署的基础上,进一步提升 Supabase 的安全性、可用性与性能。


进阶主题:安全加固

Pigsty基础组件

对于严肃的生产部署,我们强烈建议您修改 Pigsty 基础组件的密码。因为这些默认值是公开且众所周知的,不改密码上生产无异于裸奔:

以上密码为 Pigsty 组件模块的密码,强烈建议在安装部署前就设置完毕。

Supabase密钥

除了 Pigsty 组件的密码,你还需要 修改 Supabase 的密钥,包括

这里请您务必参照 Supabase教程:保护你的服务 里的说明:

  • 生成一个长度超过 40 个字符的 JWT_SECRET,并使用教程中的工具签发 ANON_KEYSERVICE_ROLE_KEY 两个 JWT。
  • 使用教程中提供的工具,根据 JWT_SECRET 以及过期时间等属性,生成一个 ANON_KEY JWT,这是匿名用户的身份凭据。
  • 使用教程中提供的工具,根据 JWT_SECRET 以及过期时间等属性,生成一个 SERVICE_ROLE_KEY,这是权限更高服务角色的身份凭据。
  • 指定一个32个字符以上的随机字符串密钥 PG_META_CRYPTO_KEY,用于加密 Studio UI 与 meta 服务的交互
  • 如果您使用的 PostgreSQL 业务用户使用了不同于默认值的密码,请相应修改 `POSTGRES_PASSWORD`` 的值
  • 如果您的对象存储使用了不同于默认值的密码,请相应修改 S3_ACCESS_KEY``](https://github.com/pgsty/pigsty/blob/v3.7.0/conf/supabase.yml#L154) 与 [S3_SECRET_KEY`` 的值

Supabase 部分的凭据修改后,您可以重启 Docker Compose 容器以应用新的配置:

./app.yml -t app_config,app_launch
cd /opt/supabase; make up

进阶主题:域名接入

如果你在本机或局域网内使用 Supabase,那么可以选择 IP:Port 直连 Kong 对外暴露的 HTTP 8000 端口访问 Supabase。

你可以使用一个内网静态解析的域名,但对于严肃的生产部署,我们建议您使用真域名 + HTTPS 来访问 Supabase。 在这种情况下,您的服务器应当有一个公网 IP 地址,你应当拥有一个域名,使用云/DNS/CDN 供应商提供的 DNS 解析服务,将其指向安装节点的公网 IP(可选默认下位替代:本地 /etc/hosts 静态解析)。

比较简单的做法是,直接批量替换占位域名(supa.pigsty)为你的实际域名,假设为 supa.pigsty.cc

sed -ie 's/supa.pigsty.cc/supa.pigsty/g/' ~/pigsty/pigsty.yml

如果你没有事先配置好,那么重载 Nginx 和 Supabase 的配置生效即可:

make nginx      # 重载 nginx 配置
make cert       # 申请 certbot 免费 HTTPS 证书
./app.yml       # 重载 Supabase 配置

修改后的配置应当类似下面的片段:

all:
  vars:
    infra_portal:
      supa :
        domain: supa.pigsty.cc        # 替换为你的域名!
        endpoint: "10.10.10.10:8000"
        websocket: true
        certbot: supa.pigsty.cc       # 证书名称,通常与域名一致即可

  children:
    supabase:
      vars:
          supabase:                                       # the definition of supabase app
            conf:                                         # override /opt/supabase/.env
              SITE_URL: https://supa.pigsty                # <------- Change This to your external domain name
              API_EXTERNAL_URL: https://supa.pigsty        # <------- Otherwise the storage api may not work!
              SUPABASE_PUBLIC_URL: https://supa.pigsty     # <------- DO NOT FORGET TO PUT IT IN infra_portal!

完整的域名/HTTPS 配置可以参考 证书管理 教程,您也可以使用 Pigsty 自带的本地静态解析与自签发 HTTPS 证书作为下位替代。

asciicast


进阶主题:外部对象存储

您可以使用 S3 或 S3 兼容的服务,来作为 PGSQL 备份与 Supabase 使用的对象存储。这里我们使用一个 阿里云 OSS 对象存储作为例子。

Pigsty 提供了一个 terraform/spec/aliyun-meta-s3.tf 模板, 可以用于在阿里云上拉起一台服务器,以及一个 OSS 存储桶。

首先,我们修改 all.children.supa.vars.apps.[supabase].conf 中 S3 相关的配置,将其指向阿里云 OSS 存储桶:

# if using s3/minio as file storage
S3_BUCKET: data                       # 替换为 S3 兼容服务的连接信息
S3_ENDPOINT: https://sss.pigsty:9000  # 替换为 S3 兼容服务的连接信息
S3_ACCESS_KEY: s3user_data            # 替换为 S3 兼容服务的连接信息
S3_SECRET_KEY: S3User.Data            # 替换为 S3 兼容服务的连接信息
S3_FORCE_PATH_STYLE: true             # 替换为 S3 兼容服务的连接信息
S3_REGION: stub                       # 替换为 S3 兼容服务的连接信息
S3_PROTOCOL: https                    # 替换为 S3 兼容服务的连接信息

同样使用以下命令重载 Supabase 配置:

./app.yml -t app_config,app_launch

您同样可以使用 S3 作为 PostgreSQL 的备份仓库,在 all.vars.pgbackrest_repo 新增一个 aliyun 备份仓库的定义:

all:
  vars:
    pgbackrest_method: aliyun          # pgbackrest 备份方法:local,minio,[其他用户定义的仓库...],本例中将备份存储到 MinIO 上
    pgbackrest_repo:                   # pgbackrest 备份仓库: https://pgbackrest.org/configuration.html#section-repository
      aliyun:                          # 定义一个新的备份仓库 aliyun
        type: s3                       # 阿里云 oss 是 s3-兼容的对象存储
        s3_endpoint: oss-cn-beijing-internal.aliyuncs.com
        s3_region: oss-cn-beijing
        s3_bucket: pigsty-oss
        s3_key: xxxxxxxxxxxxxx
        s3_key_secret: xxxxxxxx
        s3_uri_style: host
        path: /pgbackrest
        bundle: y                         # bundle small files into a single file
        bundle_limit: 20MiB               # Limit for file bundles, 20MiB for object storage
        bundle_size: 128MiB               # Target size for file bundles, 128MiB for object storage
        cipher_type: aes-256-cbc          # enable AES encryption for remote backup repo
        cipher_pass: pgBackRest.MyPass    # 设置一个加密密码,pgBackRest 备份仓库的加密密码
        retention_full_type: time         # retention full backup by time on minio repo
        retention_full: 14                # keep full backup for the last 14 days

然后在 all.vars.pgbackrest_mehod 中指定使用 aliyun 备份仓库,重置 pgBackrest 备份:

./pgsql.yml -t pgbackrest

Pigsty 会将备份仓库切换到外部对象存储上,更多备份配置可以参考 PostgreSQL 备份 文档。


进阶主题:使用SMTP

你可以使用 SMTP 来发送邮件,修改 supabase 应用配置,添加 SMTP 信息:

all:
  children:
    supabase:        # supa group
      vars:          # supa group vars
        apps:        # supa group app list
          supabase:  # the supabase app
            conf:    # the supabase app conf entries
              SMTP_HOST: smtpdm.aliyun.com:80
              SMTP_PORT: 80
              SMTP_USER: [email protected]
              SMTP_PASS: your_email_user_password
              SMTP_SENDER_NAME: MySupabase
              SMTP_ADMIN_EMAIL: [email protected]
              ENABLE_ANONYMOUS_USERS: false

不要忘了使用 app.yml 来重载配置


进阶主题:真·高可用

经过这些配置,您拥有了一个带公网域名,HTTPS 证书,SMTP,PITR 备份,监控,IaC,以及 400+ 扩展的企业级 Supabase (基础单机版)。 高可用的配置请参考 Pigsty 其他部份的文档,如果您懒得阅读学习,我们提供手把手扶上马的 Supabase 自建专家咨询服务 —— ¥2000 元免去折腾与下载的烦恼。

单节点的 RTO / RPO 依赖外部对象存储服务提供兜底,如果您的这个节点挂了,外部 S3 存储中保留了备份,您可以在新的节点上重新部署 Supabase,然后从备份中恢复。 这样的部署在故障时可以提供一个最低标准的 RTO (小时级恢复时长)/ RPO (MB级数据损失)兜底容灾水平 兜底。

如果想要达到 RTO < 30s ,切换零数据丢失,那么需要使用多节点进行高可用部署,这涉及到:

  • ETCD: DCS 需要使用三个节点或以上,才能容忍一个节点的故障。
  • PGSQL: PGSQL 同步提交不丢数据模式,建议使用至少三个节点。
  • INFRA:监控基础设施故障影响稍小,建议生产环境使用双副本
  • Supabase 无状态容器本身也可以是多节点的副本,可以实现高可用。

在这种情况下,您还需要修改 PostgreSQL 与 MinIO 的接入点,使用 DNS / L2 VIP / HAProxy 等 高可用接入点 关于这些部分,您只需参考 Pigsty 中各个模块的文档进行配置部署即可。 建议您参考 conf/ha/trio.ymlconf/ha/safe.yml 中的配置,将集群规模升级到三节点或以上。

11 - FerretDB

MongoDB 线协议兼容的 PostgreSQL 方案

FerretDB 是开源的 MongoDB 线协议兼容中间件,可将 PostgreSQL 作为 MongoDB 的直接替代后端。依赖 MongoDB 线协议的应用可以通过它无缝使用 PostgreSQL,在两个数据库生态之间建立桥梁。

启用 FerretDB 需要使用 FerretDB 修订的 documentdb 扩展;Pigsty 软件仓库也提供该扩展。此冻结版本中的最新组合为 FerretDB 2.7 与 DocumentDB 0.107.0。


快速上手

按照 Pigsty 的标准安装流程,使用 mongo 配置模板:

./configure -c mongo    # 使用 FerretDB / DocumentDB 配置模板
./install.yml           # 安装;生产部署前请先修改 pigsty.yml 中的密码

生产部署时,务必在运行安装剧本前修改 pigsty.yml 中的密码参数。


配置

pg-meta:
  hosts:
    10.10.10.10: { pg_seq: 1, pg_role: primary }
  vars:
    pg_cluster: pg-meta
    pg_users:
      - { name: mongod      ,password: DBUser.Mongo  ,pgbouncer: true ,roles: [dbrole_admin   ] ,comment: ferretdb super user ,superuser: true }
      - { name: dbuser_meta ,password: DBUser.Meta   ,pgbouncer: true ,roles: [dbrole_admin   ] ,comment: pigsty admin user }
      - { name: dbuser_view ,password: DBUser.Viewer ,pgbouncer: true ,roles: [dbrole_readonly] ,comment: read-only viewer  }
    pg_databases:
      - {name: meta, owner: mongod ,baseline: cmdb.sql ,comment: pigsty meta database ,schemas: [pigsty] ,extensions: [ documentdb, postgis, vector, pg_cron, rum ]}
    pg_hba_rules:
      - { user: dbuser_view , db: all ,addr: infra ,auth: pwd ,title: 'allow grafana dashboard access cmdb from infra nodes' }
      - { user: mongod      , db: all ,addr: world ,auth: pwd ,title: 'mongodb password access from everywhere' }
    node_crontab: [ '00 01 * * * postgres /pg/bin/pg-backup full' ]

    # DocumentDB 设置
    pg_extensions: [ documentdb, citus, postgis, pgvector, pg_cron, rum ]
    pg_libs: 'pg_documentdb, pg_documentdb_core, pg_cron, pg_stat_statements, auto_explain'
    pg_parameters: { cron.database_name: meta }

使用

完整说明请参阅 FERRET 模块文档。

安装客户端工具

可以使用 MongoDB 命令行工具 MongoSH 访问 FerretDB。

先用 pig 添加 MongoDB 软件仓库,再通过 yumapt 安装 mongosh

pig repo add mongo -u
yum install mongodb-mongosh
apt install mongodb-mongosh

连接 FerretDB

任何语言的 MongoDB 驱动都可以使用 MongoDB 连接串访问 FerretDB。以下为 mongosh 示例:

$ mongosh
Current Mongosh Log ID: 67ba8c1fe551f042bf51e943
Connecting to:          mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.4.0
Using MongoDB:          7.0.77
Using Mongosh:          2.4.0

For mongosh info see: https://www.mongodb.com/docs/mongodb-shell/

test>

认证

可以使用不同用户登录,细节参阅 FerretDB:认证

mongosh 'mongodb://dbuser_meta:[email protected]:27017/meta'      # 业务管理员
mongosh 'mongodb://dbuser_view:[email protected]:27017/meta'    # 只读用户

使用示例

连接 FerretDB 后,可以像使用 MongoDB 集群一样执行命令:

$ mongosh 'mongodb://dbuser_meta:[email protected]:27017/meta'

MongoDB 命令会转换为 SQL,并在底层 PostgreSQL 中执行:

use test                            // CREATE SCHEMA test;
db.dropDatabase();                  // DROP SCHEMA test;
db.createCollection('posts');       // CREATE TABLE posts(_data JSONB,...)
db.posts.insertOne({                // INSERT INTO posts VALUES(...);
    title: 'Post One',body: 'Body of post one',category: 'News',tags: ['news', 'events'],
    user: {name: 'John Doe',status: 'author'},date: Date()}
);
db.posts.find().limit(2).pretty();  // SELECT * FROM posts LIMIT 2;
db.posts.createIndex({ title: 1 })  // CREATE INDEX ON posts(_data->>'title');

如果不熟悉 MongoDB,可以参考同样适用于 FerretDB 的 MongoDB Shell CRUD 教程

下面的 mongosh 脚本可用于生成简单的示例负载:

cat > benchmark.js <<'EOF'
const coll = "testColl";
const numDocs = 1000;

for (let i = 0; i < numDocs; i++) {
  db.getCollection(coll).insertOne({ num: i, name: "MongoDB Benchmark Test" });
}
for (let i = 0; i < numDocs; i++) {
  db.getCollection(coll).find({ num: i });
}
for (let i = 0; i < numDocs; i++) {
  db.getCollection(coll).updateOne({ num: i }, { $set: { name: "Updated" } });
}
for (let i = 0; i < numDocs; i++) {
  db.getCollection(coll).deleteOne({ num: i });
}
EOF

mongosh 'mongodb://dbuser_meta:[email protected]:27017' benchmark.js

FerretDB 的支持命令列表已知差异说明了兼容边界;对基本使用场景而言,这些差异通常影响不大。