跳转到主要内容

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

返回本页常规视图.

Pigsty v3.7.0 文档

冻结于 Pigsty v3.7.0 的历史文档。
说明

在本冻结点,Pigsty v4 仍属于未来预告;本归档记录的是稳定版 v3.7.0。

Postgres In Great STYle —— Postgres Infra Graphic Service Toolbox, Yours —— 你的图形化 PG 基建服务工具箱!

简介

Pigsty (/ˈpɪɡ staɪ/) 是一个开箱即用的开源 PostgreSQL 发行版, 也是一个本地优先的 RDS 替代方案

价值
    为什么使用 Pigsty?Pigsty 的 8 条核心价值主张
特性
    核心特性、亮点和技术细节
参考
    架构、用例、对比和其他参考资料
关于
    许可证、发布、社区、新闻、作者、服务等...

Pigsty 汇聚了 PostgreSQL 和数据库世界的所有超能力,提供构建数据基础设施所需的一切。

一切皆用 Postgres!像专家一样自建!


安装

快速开始准备 一台具有 SSH 访问权限节点,新安装 Linux 系统, 使用具有免密 sshsudo 权限的 用户 运行:

install
curl -fsSL https://repo.pigsty.io/get | bash -s v3.7.0; cd ~/pigsty;  # 下载安装 Pigsty
./configure    # 生成配置文件
./install.yml  # 执行安装部署

下载配置安装。Pigsty 会在几分钟内 完成安装!您可以稍后 添加更多节点 与数据库集群。

接下来,您可以探索 用户界面,访问 5432 端口上的 Postgres 服务,以及 3000 端口上的 Grafana 监控大盘(用户名/密码:admin / pigsty)。

安装
    在 Linux 服务器上安装 Pigsty
准备
    为正式部署准备环境
配置
    使用配置清单自定义数据库集群
管理
    使用 Ansible 剧本管理您的环境

你可以将多种风味的 PostgreSQL 内核封装为 RDS: Citus, WiltonDB, IvorySQL, OpenHalo, Percona, OrioleDB, PolarDB, 以及 Supabase


模块

Pigsty 由多个 模块 组成。其中,PGSQL / INFRA / NODE / ETCDPINE 组合) 是自主托管 Postgres RDS 服务的 必需 模块。

PGSQL
    具有高可用、PITR、IaC、ACL、监控和 437 扩展的 HA PG 集群
INFRA
    Nginx、软件仓库、DNS、NTP、Prometheus 和 Grafana 可观测性技术栈
NODE
    将节点注册到所需状态并监控,以及 VIP、HAProxy
ETCD
    可靠的分布式共识存储(DCS),为 PGSQL 高可用提供支持

Pigsty 还提供了一些 完全可选 的 “福利” 模块,它们与 PostgreSQL 配合良好,并能为您的数据基础设施带来额外价值。

MINIO
    S3 兼容的对象存储,可选的备份存储
REDIS
    高性能内存缓存,可选的数据结构服务器
DOCKER
    容器运行时,可选,用于运行无状态应用和工具
FERRET
    将你的 PostgreSQL 封装为一套 MongoDB!

常见问题

Pigsty 是什么,不是什么?
    Pigsty 是一个 PostgreSQL 数据库发行版,本地优先的开源 RDS 云数据库解决方案。Pigsty 不是数据库(DBMS),而是管理数据库的工具,解决方案,与最佳实践。属于 RDS/DBA 赛道。类比:数据库是车,那么 DBA 是司机,RDS 是出租车服务,Pigsty 则是自动驾驶软件。
Pigsty 解决什么问题?
    用好数据库的能力极为稀缺:要么高薪聘请数据库专家自建(雇司机),或从云厂商以天价租赁 RDS(打车),但现在你有新的选项:Pigsty(自动驾驶)。Pigsty 帮用户用好数据库:让用户在没有 DBA 的情况下,以不到 RDS 1/10 的成本,自建质量效率更优的本地云数据库服务!
Pigsty 为什么能帮您用好数据库?
    Pigsty 沉淀了顶尖专家在最复杂,最大规模的甲方 PostgreSQL 场景中打磨得到的经验与最佳实践,产品化为可复制的软件:一次性解决扩展安装,高可用,链接池,监控,备份恢复,参数优化,IaC 批量管理,一键安装,自动化运维等诸多问题。提前规避诸多陷阱,避免重复踩坑。
Pigsty 为何比 RDS 好用?
    Pigsty 提供远超 RDS 的特性集与基础设施支持,包括 400+ 扩展插件与 8+ 内核支持,提供独一无二的监控系统,与久经复杂场景打磨考验的架构最佳实践,简单易用。且用探探,苹果,阿里等顶级甲方场景打磨而成,用激情与热爱持续浇灌,深度与成熟度绝非 RDS 大锅饭可比。
Pigsty 为何比 RDS 省钱?
    Pigsty 允许您使用 10 ¥/核·月的纯硬件资源,运行 400¥-1400¥/核·月的 RDS 云数据库,并省去 DBA 的工资。通常,成规模的 Pigsty 部署总拥有成本(TCO)能比 RDS 低 90% 以上。Pigsty 能够同时降低软件许可/服务/人力的开销,自建无需加人,让您将成本花在刀刃上。
Pigsty 对研发有什么帮助?
    Pigsty 整合了 PG 生态最全的扩展(400+),提供了 All in PG 解决方案:单一组件替代 Redis, Kafka, MySQL, ES, 向量数据库, OLAP / 大数据分析等专用组件。极大提高研发效能与敏捷性的同时降低复杂度成本,而且研发能在 Pigsty 的加持下实现自助管理,自主 DevOps,无需 DBA
Pigsty 对运维有什么帮助?
    Pigsty 故障自愈的高可用架构确保硬件故障无需当场处理,让运维与 DBA 睡个好觉;监控助力问题分析与性能优化;IaC 赋能超大规模集群自动化管理。运维在 Pigsty 加持下能兼职 DBA ,而 DBA 则可以跳过系统建设阶段,节省大量工时并专注于高价值工作,或喝茶看报,学习PG。
Pigsty 的作者是谁?
    Pigsty 主体由冯若航一人开发,这是一位专注于 PostgreSQL 领域 10 年的开源贡献者,数据库专家与布道师,曾任职于阿里,探探,苹果,全栈专家。现为一人公司创始人,提供专业咨询服务。同时他也是技术 KOL,微信数据库个人公众号榜首 《非法加冯》 的主理人,全网粉丝六万+
Pigsty 的生态位与影响力如何?
    Pigsty 是 OSSRANK PG 生态开源榜单中国人主导项目的第一名,同时也是 PostgreSQL 生态最活跃的开源项目之一,目前在扩展分发与监控系统上占据碾压性优势。Pigsty 目前是云厂商 RDS 的挑战者,目前已经广泛应用于军工,政企,医疗,互联网,金融,制造业等各个行业。
Pigsty 适合什么规模的客户?
    Pigsty 源于超大规模 PostgreSQL 自动化管理的需求,但已针对易用性进行深度优化,缺乏专业 DBA 能力的个人开发者与中小型企业也可以轻松上手使用。最大规模部署为 25K vCPU,450万QPS,六年+,最小规模部署可完整运行于 1c1g 虚拟机上作为 Demo / Devbox 使用
Pigsty 提供哪些能力?
    Pigsty 专注于整合 PostgreSQL 生态,提供 PostgreSQL 的最佳实践,但同时也支持一系列与 PostgreSQL 配合良好的开源软件。例如 Etcd, Redis, MinIO, DuckDB, Prometheus, FerretDB, Babelfish, IvorySQL, PolarDB, OrioleDB, OpenHalo, Supabase, Greenplum, Dify, Odoo,...
Pigsty 适用于哪些场景
    运行大规模 PostgreSQL 集群用于业务;自建 RDS,对象存储,缓存,数仓,Supabase, …;自建 Odoo,Dify,Wiki,GitLab 等企业级应用;运行监控基础设施,监控现有数据库与主机;同时组合使用多种PG扩展插件;大屏开发与交互式数据应用 Demo,数据可视化,Web 建站
Pigsty 开源免费吗?
    Pigsty 是 100% 的开源软件 + 自由软件,使用 AGPLv3 许可证开源。在遵循开源许可证的前提下,您可以将其免费地,自由的用于各种商业目的。我们珍视软件自由,对于非 DBaaS / OEM 用例,我们执行更为宽松的等效 Apache 2.0 许可证。请参阅许可证以获取更多详细信息。
Pigsty 提供商业支持吗?
    Pigsty 软件本身开源免费,并提供丰俭由人的商业订阅,为 Pigsty & PostgreSQL 提供质保。订阅提供更宽广的 OS/PG/芯片架构支持范围,以及专家咨询与支持。Pigsty 商业订阅交付业界顶尖的管理/技术经验/解决方案,帮助您节省宝贵的时间,替您扛雷,并为疑难杂症兜底。
Pigsty 支持国产信创吗?
    Pigsty 软件本身不属于数据库,不受信创名录限制,且已有多个部队用例。但 Pigsty 开源版不提供任何形式的信创支持,商业版订阅提供与阿里云合作的国产信创解决方案,支持使用具有信创资质的 PolarDB-O (需单独采购)作为 RDS 内核,能够运行于信创操作系统/芯片环境。
Pigsty 可以作为多租户 DBaaS 出售或换 Logo 贴牌吗?
    您可以在遵循 AGPLv3 许可证 —— 开源全部衍生工作的前提下将其用于此目的。我们保留对公有云/数据库厂商违反 AGPLv3 许可证进行追责的权利。如果您不希望开源衍生作品,建议您选购 Pigsty 企业版订阅计划,那里提供对此用例的清晰授权以及对 AGPLv3 开源义务的豁免。

1 - 安装

Pigsty 入门指南

快速开始

快速开始准备 一台具有 SSH访问权限节点,新安装 Linux系统, 使用具有免密 sshsudo 权限的用户运行:

步骤 1

使用以下命令[**下载**](/zh/docs/prepare/software#pigsty) pigsty:

```bash
curl -fsSL https://repo.pigsty.io/get | bash -s v3.7.0; cd ~/pigsty;
```

步骤 2

执行 [`configure`](/zh/docs/config/configure) 生成 [配置清单](/zh/docs/config/inventory)。(<span class="text-red-500 font-black">务必修改</span> 生成的 [`pigsty.yml`](/zh/docs/config/inventory) 中的密码)

```bash
./configure
```

步骤 3

一键 [**安装部署**](/zh/docs/install/start) 所有组件:

```bash
./install.yml
```

Pigsty 安装完成!请探索 用户界面,访问 5432 端口上的 Postgres 服务,或 3000 端口上的 Grafana 监控大盘(admin / pigsty)。


下一步做什么?


安装

单机安装
    在当前 Linux 节点上,执行标准的完整在线安装流程
高可用安装
    在多个节点上安装,以实现真正的企业级高可用部署
离线安装
    在没有互联网连接的情况下,从本地离线包引导安装
精简安装
    仅安装高可用 Postgres 集群所必须的组件,不装监控

准备工作

准备
    准备节点、网络、存储、用户、ssh、sudo、ansible 等
Linux 操作系统
    检查兼容的 Linux 发行版和可用性矩阵
Vagrant
    使用 vagrant / virtualbox 置备本地 Linux 虚拟机
Terraform
    在云供应商上使用 terraform 置备云 Linux 服务器

参考

界面
    访问和管理 Pigsty 提供的数据库端点与图形用户界面
配置
    使用声明式的配置文件描述你需要的基础设施与集群
剧本
    了解可用的 Ansible 剧本和其使用方法
安全
    生产环境的安全加固和最佳实践

1.1 - 快速上手

如何在您的 Linux 主机上安装 pigsty?

本文是 Pigsty 单节点安装指南,多节点安装 介绍了在生产环境进行真正高可用部署的方法。


简化版本

准备 一台具有 SSH权限节点 并安装 兼容的Linux发行版, 使用带免密 sshsudo 权限的用户:

步骤 1

    [**下载**](#download) pigsty,它会自动安装至 `~/pigsty` 目录,并尝试安装 [`ansible`](/zh/docs/admin/ansible):

    ```bash
    curl -fsSL https://repo.pigsty.io/get | bash -s v3.7.0; cd ~/pigsty;
    ```

步骤 2

    使用 [`configure`](/docs/config/configure) 生成配置文件,或直接根据您的需求调整 [`pigsty.yml`](/zh/docs/config/inventory):

    ```bash
    ./configure   # 可以使用 -c [conf] 指定具体的配置模板
    ```

步骤 3

    使用 `install.yml` 剧本,一键 [**安装部署**](#install) 所有组件:

    ```bash
    ./install.yml
    ```

示例:在 RockyLinux 9 上的单机安装:

asciicast


准备

安装 Pigsty 涉及一些 准备工作 ,以下是简略检查清单:

项目 要求 项目 要求
节点 至少 1C1G,推荐 2C2G 规格 至少1个节点,2个为半高可用,3个以上真高可用
磁盘 /data,主挂载点,ext4/xfs 网络 静态 IPv4 地址,单节点可使用 127.0.0.1
VIP L2 VIP,可选 域名 本地/公网域名,可选
内核 Linux 发行版 el8/9/10,d12/13, u22/u24 x x86_64 / aarch64
Locale C.UTF-8C 防火墙 端口:80 / 443 / 22 / 5432
用户 避免使用 rootpostgres Sudo nopass sudo 权限
SSH 通过公钥 nopass 可达性 ssh <ip|alias> sudo ls 无错误

下载

推荐)您可以使用以下命令获取并解压最新稳定版本的 pigsty 源码:

curl -fsSL https://repo.pigsty.io/get | bash -s v3.7.0; cd ~/pigsty
curl -fsSL https://repo.pigsty.cc/get | bash -s v3.7.0; cd ~/pigsty   # 中国镜像
curl -fsSL https://repo.pigsty.io/get | bash -s v3.7.0; cd ~/pigsty

您也可以通过 gitpig 或直接从 GitHub 下载源码离线软件包 压缩包的方式安装。


配置

configure 脚本将根据您的环境和输入生成具有良好默认值的 pigsty.yml 配置文件 配置清单。 这是 可选的,您可以如 教程 所示直接编辑 pigsty.yml

有许多 配置模板 供您参考,以下是一些快速示例:

./configure                  # 使用默认模板,安装默认的 PG 18,带有必要扩展
./configure -v 17            # 使用 PG 17 的版本,而非默认的 PG18
./configure -c rich          # 创建本地软件仓库,下载所有扩展,安装主要扩展
./configure -c slim          # 最小安装模板,与 ./slim.yml 剧本一起使用
./configure -c app/supa      # 使用 app/supa 自托管 supabase 配置模板
./configure -c ivory         # 使用 ivorysql 内核而非原生 PG
./configure -i 10.11.12.13   # 显式指定主 IP 地址
./configure -r china         # 使用中国镜像而非默认仓库
./configure -c full -s       # 使用 4 节点沙箱配置模板,不进行 IP 替换和探测

让我们不带任何参数执行 configure,如果发现多个 IP 地址,它可能会要求您输入主 IP 地址。

[vagrant@node-2 pigsty]$ ./configure
configure pigsty v3.7.0 begin
[ OK ] region  = default
[ OK ] kernel  = Linux
[ OK ] machine = x86_64
[ OK ] package = rpm,dnf
[ OK ] vendor  = rocky (Rocky Linux)
[ OK ] version = 9 (9.6)
[ OK ] sudo = vagrant ok
[ OK ] ssh = [email protected] ok
[WARN] Multiple IP address candidates found:
    (1) 192.168.121.24	inet 192.168.121.24/24 brd 192.168.121.255 scope global dynamic noprefixroute eth0
    (2) 10.10.10.12	    inet 10.10.10.12/24 brd 10.10.10.255 scope global noprefixroute eth1
[ IN ] INPUT primary_ip address (of current meta node, e.g 10.10.10.10):
=> 10.10.10.12    # <------- 在这里输入你的首要 IPv4 地址!
[ OK ] primary_ip = 10.10.10.12 (from input)
[ OK ] admin = [email protected] ok
[ OK ] mode = meta (el9)
[ OK ] locale  = C.UTF-8
[ OK ] configure pigsty done
proceed with ./install.yml

该脚本将把 IP 占位符 10.10.10.10 替换为当前节点的主 IPv4 地址。 在 手动 配置 pigsty 时请注意这一点。检查生成的 pigsty.yml 以继续。

嘿!别忘了这些密码!

修改默认密码!

安装 前,任何正式部署中请务必 修改默认密码

然后修改默认 密码 并进行必要的调整,最终的 pigsty.yml 可能如下所示:

~/pigsty/pigsty.yml
all:

  #==============================================================#
  # Clusters, Nodes, and Modules
  #==============================================================#
  children:

    #----------------------------------------------#
    # PGSQL : https://doc.pgsty.com/pgsql
    #----------------------------------------------#
    # this is an example single-node postgres cluster with pgvector installed, with one biz database & two biz users
    pg-meta:
      hosts:
        10.10.10.10: { pg_seq: 1, pg_role: primary } # <---- primary instance with read-write capability
        #x.xx.xx.xx: { pg_seq: 2, pg_role: replica } # <---- read only replica for read-only online traffic
        #x.xx.xx.xy: { pg_seq: 3, pg_role: offline } # <---- offline instance of ETL & interactive queries
      vars:
        pg_cluster: pg-meta

        # install, load, create pg extensions: https://doc.pgsty.com/pgsql/extension
        pg_extensions: [ postgis, pgvector ]

        # define business users/roles : https://doc.pgsty.com/pgsql/user
        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  }

        # define business databases : https://doc.pgsty.com/pgsql/db
        pg_databases:
          - name: meta
            baseline: cmdb.sql
            comment: "pigsty meta database"
            schemas: [pigsty]
            # define extensions in database : https://doc.pgsty.com/pgsql/extension/create
            extensions: [ postgis, vector ]

        # define HBA rules : https://doc.pgsty.com/pgsql/hba
        pg_hba_rules:
          - { user: dbuser_view , db: all ,addr: infra ,auth: pwd ,title: 'allow grafana dashboard access cmdb from infra nodes' }

        # define backup policies: https://doc.pgsty.com/pgsql/backup
        node_crontab: [ '00 01 * * * postgres /pg/bin/pg-backup full' ] # make a full backup every day 1am

        # define (OPTIONAL) L2 VIP that bind to primary
        #pg_vip_enabled: true
        #pg_vip_address: 10.10.10.2/24
        #pg_vip_interface: eth1


    #----------------------------------------------#
    # INFRA : https://doc.pgsty.com/infra
    #----------------------------------------------#
    infra:
      hosts:
        10.10.10.10: { infra_seq: 1 }
      vars:
        repo_enabled: false   # disable in 1-node mode :  https://doc.pgsty.com/admin/repo
        #repo_extra_packages: [ pg18-main ,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]

    #----------------------------------------------#
    # ETCD : https://doc.pgsty.com/etcd
    #----------------------------------------------#
    etcd:
      hosts:
        10.10.10.10: { etcd_seq: 1 }
      vars:
        etcd_cluster: etcd
        etcd_safeguard: false             # prevent purging running etcd instance?

    #----------------------------------------------#
    # MINIO : https://doc.pgsty.com/minio
    #----------------------------------------------#
    #minio:
    #  hosts:
    #    10.10.10.10: { minio_seq: 1 }
    #  vars:
    #    minio_cluster: minio
    #    minio_users:                      # list of minio user to be created
    #      - { access_key: pgbackrest  ,secret_key: S3User.Backup ,policy: pgsql }
    #      - { access_key: s3user_meta ,secret_key: S3User.Meta   ,policy: meta  }
    #      - { access_key: s3user_data ,secret_key: S3User.Data   ,policy: data  }

    #----------------------------------------------#
    # DOCKER : https://doc.pgsty.com/docker
    # APP    : https://doc.pgsty.com/app
    #----------------------------------------------#
    # launch example pgadmin app with: ./app.yml (http://10.10.10.10:8885 [email protected] / pigsty)
    app:
      hosts: { 10.10.10.10: {} }
      vars:
        docker_enabled: true                # enabled docker with ./docker.yml
        docker_registry_mirrors: ["https://docker.1panel.live","https://docker.1ms.run","https://docker.xuanyuan.me","https://registry-1.docker.io"]
        app: pgadmin                        # specify the default app name to be installed (in the apps)
        apps:                               # define all applications, appname: definition
          pgadmin:                          # pgadmin app definition (app/pgadmin -> /opt/pgadmin)
            conf:                           # override /opt/pgadmin/.env
              PGADMIN_DEFAULT_EMAIL: [email protected]
              PGADMIN_DEFAULT_PASSWORD: pigsty


  #==============================================================#
  # Global Parameters
  #==============================================================#
  vars:

    #----------------------------------------------#
    # INFRA : https://doc.pgsty.com/infra
    #----------------------------------------------#
    version: v3.7.0                   # pigsty version string
    admin_ip: 10.10.10.10             # admin node ip address
    region: china                     # upstream mirror region: default|china|europe
    proxy_env:                        # global proxy env when downloading packages
      no_proxy: "localhost,127.0.0.1,10.0.0.0/8,192.168.0.0/16,*.pigsty,*.aliyun.com,mirrors.*,*.myqcloud.com,*.tsinghua.edu.cn"
      # http_proxy:  # set your proxy here: e.g http://user:[email protected]
      # https_proxy: # set your proxy here: e.g http://user:[email protected]
      # all_proxy:   # set your proxy here: e.g http://user:[email protected]
    infra_portal:                     # domain names and upstream servers
      home         : { domain: h.pigsty }
      grafana      : { domain: g.pigsty ,endpoint: "${admin_ip}:3000" , websocket: true }
      prometheus   : { domain: p.pigsty ,endpoint: "${admin_ip}:9058" }
      alertmanager : { domain: a.pigsty ,endpoint: "${admin_ip}:9059" }
      blackbox     : { endpoint: "${admin_ip}:9115" }
      loki         : { endpoint: "${admin_ip}:3100" }
      pgadmin      : { domain: adm.pigsty ,endpoint: "${admin_ip}:8885" }
      #minio       : { domain: m.pigsty ,endpoint: "${admin_ip}:9001" ,scheme: https ,websocket: true }

    #----------------------------------------------#
    # PASSWORD : https://doc.pgsty.com/config/security
    #----------------------------------------------#
    grafana_admin_password: pigsty               # <-------- CHANGE ME!
    pg_admin_password: DBUser.DBA                # <-------- CHANGE ME!
    pg_monitor_password: DBUser.Monitor          # <-------- CHANGE ME!
    pg_replication_password: DBUser.Replicator   # <-------- CHANGE ME!
    patroni_password: Patroni.API                # <-------- CHANGE ME!
    haproxy_admin_password: pigsty               # <-------- CHANGE ME!
    minio_secret_key: minioadmin                 # <-------- CHANGE ME!

    #----------------------------------------------#
    # NODE : https://doc.pgsty.com/node/param
    #----------------------------------------------#
    nodename_overwrite: false             # do not overwrite node hostname on single node mode
    node_tune: tiny                       # node tuning specs: oltp,olap,tiny,crit
    node_etc_hosts: [ '10.10.10.10 h.pigsty a.pigsty p.pigsty g.pigsty sss.pigsty' ]
    node_repo_modules: 'node,infra,pgsql' # add these repos directly to the singleton node
    #node_repo_modules: local             # use this if you want to build & user local repo
    node_repo_remove: true                # remove existing node repo for node managed by pigsty
    #node_packages: [openssh-server]      # packages to be installed current nodes with the latest version

    #----------------------------------------------#
    # PGSQL : https://doc.pgsty.com/pgsql/param
    #----------------------------------------------#
    pg_version: 18                      # default postgres version
    pg_locale: C.UTF-8                  # overwrite default C local
    pg_lc_collate: C.UTF-8              # overwrite default C lc_collate
    pg_lc_ctype: C.UTF-8                # overwrite default C lc_ctype

    pg_conf: tiny.yml                   # pgsql tuning specs: {oltp,olap,tiny,crit}.yml
    pg_safeguard: false                 # prevent purging running postgres instance?
    pg_packages: [ pgsql-main, pgsql-common ]                 # pg kernel and common utils
    #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]
如果想要更多扩展怎么办?

只需在 pigsty.yml 中取消注释以下参数,使其看起来像这样:

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]

您可以用配置文件做更多神奇的事情,查看 配置 了解详情。


安装

Pigsty 中的一切都由 配置清单 所定义,也就是 上面 生成的 pigsty.yml 配置。

运行 install.yml 剧本 会实施这个部署计划。

~/pigsty
./install.yml

输出尾部如果带有 pgsql init donePLAY RECAP 等字样,说明安装已经完成!

......

TASK [pgsql : pgsql init done] *************************************************
ok: [10.10.10.11] => {
    "msg": "postgres://10.10.10.11/postgres | meta  | dbuser_meta dbuser_view "
}
......

TASK [pg_monitor : load grafana datasource meta] *******************************
changed: [10.10.10.11]

PLAY RECAP *********************************************************************
10.10.10.11                : ok=302  changed=232  unreachable=0    failed=0    skipped=65   rescued=0    ignored=1
localhost                  : ok=6    changed=3    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

上游仓库(如 Linux / PGDG 仓库)可能会因为更新而进入崩溃状态并导致安装失败(有过多次先例)! 您可以选择等待上游仓库修复后安装,或者使用预制的 离线软件包 来解决这个问题。

不要在已经部署好的环境中重新运行 install.yml!

重新运行整个 install.yml 剧本将会覆盖式创建所有组件,有可能导致数据丢失和服务中断!

如果您熟悉 ansible 并清楚的知道自己在做什么,请谨慎使用。

安装完成后,您可以探索 用户界面,纳管 更多节点 并部署更多高可用数据库集群。


更多

您可以使用 pigsty 部署和监控 更多集群:向 配置清单 添加定义并运行:

bin/node-add pg-test    # 初始化集群 pg-test 的 3 个节点
bin/pgsql-add pg-test   # 初始化高可用 PGSQL 集群 pg-test
bin/redis-add redis-ms  # 初始化 redis 集群 redis-ms

记住,大多数模块都需要先安装 NODE 模块。查看可用的 模块 了解详情

PGSQLINFRANODEETCDMINIOREDISFERRETDOCKER……

1.2 - 用户界面

探索仪表盘并访问数据库服务

安装完成后,您在当前节点上将安装有四个核心模块: PGSQLINFRANODEETCD

ID NODE PGSQL INFRA ETCD
1 node-1 pg-meta-1 infra-1 etcd-1

您可以直接通过以下 端口 直接访问 WebUI 服务(不推荐用于生产环境)。 或使用本地/公共 域名 通过 Nginx 门户 访问它们。

请注意,SSL 证书 需要与域名一起使用。

组件 端口 域名 备注 公共演示
Nginx 80/443 h.pigsty 门户、仓库、HAProxy 管理 home.pigsty.io
Grafana 3000 g.pigsty Grafana 仪表盘 g.pgsty.com
Prometheus 9058 p.pigsty Prometheus Web UI p.pigsty.io
AlertManager 9059 a.pigsty 告警管理 a.pigsty.io

您可以通过以下数据库用户和相应的 PGURL 访问默认端口 5432 上的默认 PostgreSQL 数据库(meta):

psql postgres://dbuser_dba:[email protected]:5432/meta
psql postgres://dbuser_meta:[email protected]:5432/meta
psql postgres://dbuser_view:[email protected]:5432/meta

PostgreSQL

个人用户开发测试使用时,可以直接使用默认超级用户和 IP:端口来访问 PostgreSQL:

DBSU

默认超级用户

默认数据库超级用户是 dbuser_dba,默认密码为 DBUser.DBA,如果修改过请使用您自己的密码。

用户名 dbuser_dba pg_admin_username
密码 DBUser.DBA pg_admin_password

CLI

内置的 psql CLI 已经为管理员用户(安装 Pigsty 使用的用户)配置了 .pgpass.pg_service.conf

p   # 别名:操作系统管理员用户 @ 当前节点
psql postgres://dbuser_dba:[email protected]/postgres  # 替换为您的 IP 和密码

GUI

您可以使用您喜欢的 GUI 工具来访问数据库,Pigsty 也提供了一些 GUI 工具的内置模板。

名称 描述 Pigsty 支持
PgAdmin 官方 PostgreSQL 管理工具 内置 Docker 模板,OSS
Supabase Studio 精美的第三方 PostgreSQL 管理 UI 内置 Docker 模板,OSS
PgWeb 轻量级基于 Web 的 PostgreSQL 客户端 内置 Docker 模板,OSS
Bytebase 具有良好 GUI 的模式迁移工具 内置 Docker 模板,OSS
DataGrip / IntelliJ 具有强大功能的专业数据库 IDE 商业 / 社区版
Navicat 流行的商业数据库管理工具 商业版
DBeaver 开源通用数据库 GUI OSS

默认设置

您可以定义业务 数据库用户配置模板 中有一些预定义的示例供您参考。

例如,默认的 meta 配置模板预定义了一个 meta 数据库:

  • 带有 Pigsty CMDB 模式(可选)
  • 预装来 timescaledb, postgis, citus, pgvector 四个业务扩展
  • 它定义了 dbuser_meta 作为具有 DDL 权限的业务管理员用户,和一个 dbuser_view 作为只读查看者用户。
pg-meta:
  hosts:
    10.10.10.10: { pg_seq: 1, pg_role: primary } # <---- 这个集群中只有一个实例,主库
  vars:
    pg_cluster: pg-meta                 # 必选参数,集群名

    pg_databases:                       # 数据库列表
      - name: meta
        baseline: cmdb.sql
        comment: "pigsty meta database"
        schemas: [pigsty]
        extensions: [ postgis, timescaledb, vector ]   # 安装了三个扩展

    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_hba_rules:                       # example hba rules
      - {user: dbuser_view , db: all ,addr: infra ,auth: pwd ,title: 'allow grafana dashboard access cmdb from infra nodes'}

这意味着您也可以使用这两个用户访问 meta 数据库:

psql postgres://dbuser_meta:[email protected]:5432/meta
psql postgres://dbuser_view:[email protected]:5432/meta

生产环境

要在生产环境中使用高可用 PostgreSQL 集群,您需要阅读以下文档来继续:

在这种情况下,您的流量在到达数据库之前会通过 haproxy 进行分发,并由 pgbouncer 池化。


Grafana

Grafana 是监控和可观测性平台,提供可视化面板能力,默认监听 3000 端口:

  • http://10.10.10.10:3000(替换为您的 IP)
通过域名访问

Pigsty 为 Web 组件提供了 静态本地域名,您可以通过 Nginx 访问 http://g.pigsty 来使用 Grafana 建议使用域名,因为您可以通过域名经由 Nginx 暴露所有服务,并为它们使用 SSL 证书。

Grafana 用户名和密码

默认凭据:admin:pigsty。如果您已更改默认凭据,请使用您自己的。

用户名 admin grafana_admin_username
密码 pigsty grafana_admin_password

您可以查看我们的公共演示站点来看看它是什么样子: https://g.pgsty.com

pigsty-home.jpg
本地域名的自签名 SSL 证书

Pigsty 默认会自动为本地静态域名 颁发自签名 SSL 证书,但您必须在浏览器中 信任自签名 CA 才不会弹窗报错。

使用真实域名和证书

Pigsty 支持使用 真实域名真正的免费 SSL 证书

只需替换 infra_portal 中的 domain 条目为你的真实域名,并使用 make cert 命令即可免费申请真实证书

1.3 - 多节点部署

如何在多个节点上安装 Pigsty,实现生产级别高可用?

你可以参考 配置教程 ,将一个单机 Pigsty 节点逐步扩展为多节点高可用部署。 但是完成这些工作最简单的办法,始终是在部署前就预先规划一切,并且一次性完成整个环境的置备。


单节点部署

我们已经在 快速上手 一节中演示了单节点安装的流程 —— 最简单的部署方式。

ID IP 地址 NODE PGSQL INFRA ETCD
1 10.10.10.10 meta pg-meta-1 infra-1 etcd-1

单节点没有高可用性,也没有冗余,如果您确实要将其用于生产环境,请为 PG 配置外部 MinIO / S3 / NFS… 作为远程备份仓库,这样能提供最低数据完整性灾难恢复能力。

Pigsty 有很多单节点 配置模板 供您参考。 你可以使用 Vagrant 默认的 meta.rb 来在本地置备此环境所需的虚拟机。 或者使用 Terraform 默认的 meta.tf 来在阿里云上置备此环境。


双节点部署

半高可用设置

双节点设置可实现一主一从的数据库物理复制和半高可用功能:

ID IP 地址 NODE PGSQL INFRA ETCD
1 10.10.10.10 meta pg-meta-1 infra-1 etcd-1
2 10.10.10.11 node-1 pg-meta-2

虽然比单节点设置更加健壮,但双节点架构的高可用性有限制:

  • 如果 node-2 故障,自动故障转移正常工作 - node-1 会自动被提升
  • 如果 node-1 故障,无法进行自动故障切换 - 需要手动提升 node-2

也就是说,这种"半高可用"设置只能从 特定的节点故障 中自动恢复,只允许坏其中一台特定的节点2。

您可以使用 dual.yml 配置模板,并使用 Vagrant dual.rb 来置备此环境所需的虚拟机。


三节点部署

真正的高可用

一个能够从任意单节点故障中自动恢复的真正高可用设置:

ID IP 地址 NODE PGSQL INFRA ETCD
1 10.10.10.10 node-1 pg-meta-1 infra-1 etcd-1
2 10.10.10.11 node-2 pg-meta-2 infra-2 etcd-2
3 10.10.10.12 node-3 pg-meta-3 infra-3 etcd-3

您可以使用 trio.yml 配置模板,并使用 Vagrant trio.rb 来置备此环境所需的虚拟机。


四节点沙箱

这是 Pigsty 中使用的 沙箱演示 环境,具有一个基础设施节点和三个额外的数据节点:

ID IP 地址 NODE PGSQL INFRA ETCD MINIO
1 10.10.10.10 meta pg-meta-1 infra-1 etcd-1 minio-1
2 10.10.10.11 node-1 pg-test-1
3 10.10.10.12 node-2 pg-test-1
4 10.10.10.13 node-3 pg-test-1

您可以使用 full.yml 配置模板,并使用 Vagrant full.rbTerraform full.tf 来置备此环境。


五节点构建

这个 pro.yml 是一个五节点构建环境,包含支持的 Linux 发行版

ID IP 地址 NODE PGSQL INFRA ETCD
1 10.10.10.8 el8 el8-1 infra-1
2 10.10.10.9 el9 el9-1 infra-2 etcd-2
3 10.10.10.12 u12 u12-1 infra-3
4 10.10.10.22 u22 u22-1 infra-4
5 10.10.10.24 u24 u24-1 infra-5

您可以使用 Vagrant pro.rbTerraform pro.tf 来置备此环境。


三十六节点仿真

一个包含 36 个节点的生产仿真环境(simu.yml),涵盖了所有 Pigsty 组件

IP 地址 规格 NODE PGSQL INFRA ETCD MINIO REDIS
10.10.10.10 8C32G meta1 pg-meta-1 infra-1
10.10.10.11 8C32G meta2 pg-meta-2 infra-2
10.10.10.12 2C4G pg12 pg-v12-1
10.10.10.13 2C4G pg13 pg-v13-1
10.10.10.14 2C4G pg14 pg-v14-1
10.10.10.15 2C4G pg15 pg-v15-1
10.10.10.16 2C4G pg16 pg-v16-1
10.10.10.17 2C4G pg17 pg-v17-1
10.10.10.18 2C4G proxy1
10.10.10.19 2C4G proxy2
10.10.10.21 2C4G minio1 etcd-1 minio-1 redis-meta-1
10.10.10.22 2C4G minio2 etcd-2 minio-2 redis-meta-2
10.10.10.23 2C4G minio3 etcd-3 minio-3 redis-meta-3
10.10.10.24 2C4G minio4 etcd-4 minio-4 redis-meta-4
10.10.10.25 2C4G minio5 etcd-5 minio-5 redis-meta-5
10.10.10.40 1C2G node40 pg-pitr-1
10.10.10.41 1C2G node41 pg-test-1 redis-test-1
10.10.10.42 1C2G node42 pg-test-2 redis-test-2
10.10.10.43 1C2G node43 pg-test-3 redis-test-3
10.10.10.44 1C2G node44 pg-test-4 redis-test-4
10.10.10.45 1C2G node45 pg-src-1 redis-src-1
10.10.10.46 1C2G node46 pg-src-2 redis-src-2
10.10.10.47 1C2G node47 pg-src-3 redis-src-3
10.10.10.48 1C2G node48 pg-dst-1 redis-dst-1
10.10.10.49 1C2G node49 pg-dst-2 redis-dst-2
10.10.10.50 1C2G node50 pg-citus0-1
10.10.10.51 1C2G node51 pg-citus0-2
10.10.10.52 1C2G node52 pg-citus1-1
10.10.10.53 1C2G node53 pg-citus1-2
10.10.10.54 1C2G node54 pg-citus2-1
10.10.10.55 1C2G node55 pg-citus2-2
10.10.10.56 1C2G node56 pg-citus3-1
10.10.10.57 1C2G node57 pg-citus3-2
10.10.10.58 1C2G node58 pg-citus4-1
10.10.10.59 1C2G node59 pg-citus4-2
10.10.10.88 4C8G test

您可以使用 Vagrant simu.rb 来置备此环境。 您可以在真实服务器(72C / 256G)上运行整个仿真,使用 Vagrant 的 libvirt 作为虚拟机提供程序。

  • 2 个基础设施节点,相互监控
  • 2 个专用代理节点运行 HAProxy
  • 5 节点 ETCD 集群可容忍 2 个节点故障,以及 5 节点 Redis Sentinel 集群
  • 5 节点 MinIO 集群,每个节点有 4 个磁盘
  • 10 个 PostgreSQL 集群:pg13 - pg15pg-srcpg-dstpg-pitrpg-test
  • 10 节点 Citus 集群有 5 个分片
  • Redis 独立集群 redis-srcredis-dst,以及原生集群 redis-test

1.4 - 离线安装

如何在没有互联网访问的情况下安装 pigsty?

Pigsty 默认从互联网上游 安装 所需软件包,但有些环境与互联网隔离。 为了解决这个问题,Pigsty 支持使用 离线软件包 进行离线安装。

步骤 1

    下载 pigsty 离线软件包,将其放到 `/tmp/pkg.tgz`

步骤 2

    下载 pigsty 源码包,解压(假设解压到 `~/pigsty`)

步骤 3

    `cd ~/pigsty; ./bootstrap`,它将解压软件包并使用本地仓库

步骤 4

    `vi ~/pigsty.yml`,覆盖 [`node_repo_modules`](/zh/docs/node/param#node_repo_modules) 设为 `local` 以使用本地仓库

步骤 5

    照常运行 `./install.yml`。它将从本地仓库安装所有内容。

什么是离线软件包?

离线软件包打包了所有需要的 RPM/DEB 软件包及其依赖; 它本质上是在正常 安装 后采取的本地 APT / YUM 仓库的快照压缩包。

您可以从 GitHub 发布页面 找到这些软件包,例如:

d6e9d6fa73620460ceb373a0c2f41ebe  pigsty-v3.7.0.tgz
987529769d85a3a01776caefefa93ecb  pigsty-pkg-v3.7.0.d12.aarch64.tgz
2d8272493784ae35abeac84568950623  pigsty-pkg-v3.7.0.d12.x86_64.tgz
090cc2531dcc25db3302f35cb3076dfa  pigsty-pkg-v3.7.0.d13.x86_64.tgz
ddc54a9c4a585da323c60736b8560f55  pigsty-pkg-v3.7.0.el10.aarch64.tgz
d376e75c490e8f326ea0f0fbb4a8fd9b  pigsty-pkg-v3.7.0.el10.x86_64.tgz
8c2deeba1e1d09ef3d46d77a99494e71  pigsty-pkg-v3.7.0.el8.aarch64.tgz
9795e059bd884b9d1b2208011abe43cd  pigsty-pkg-v3.7.0.el8.x86_64.tgz
08b860155d6764ae817ed25f2fcf9e5b  pigsty-pkg-v3.7.0.el9.aarch64.tgz
1ac430768e488a449d350ce245975baa  pigsty-pkg-v3.7.0.el9.x86_64.tgz
e033aaf23690755848db255904ab3bcd  pigsty-pkg-v3.7.0.u22.aarch64.tgz
cc022ea89181d89d271a9aaabca04165  pigsty-pkg-v3.7.0.u22.x86_64.tgz
0e978598796db3ce96caebd76c76e960  pigsty-pkg-v3.7.0.u24.aarch64.tgz
48223898ace8812cc4ea79cf3178476a  pigsty-pkg-v3.7.0.u24.x86_64.tgz

我们通常为以下 Linux 发行版 发布离线软件包,使用最新的操作系统次要版本。

EL Distribution Code Arch OS Code Package
RockyLinux 9.6 EL9 x86_64 el9.x86_64 pigsty-pkg-v3.7.0.el9.x86_64.tgz
Ubuntu 24.04.2 U24 x86_64 u24.x86_64 pigsty-pkg-v3.7.0.u24.x86_64.tgz
Debian 12.11 D12 x86_64 d12.x86_64 pigsty-pkg-v3.7.0.d12.x86_64.tgz
RockyLinux 9.6 EL9 x86_64 el9.aarch64 pigsty-pkg-v3.7.0.el9.aarch64.tgz
Ubuntu 24.04.2 U24 x86_64 u24.aarch64 pigsty-pkg-v3.7.0.u24.aarch64.tgz
Debian 12.11 D12 x86_64 d12.aarch64 pigsty-pkg-v3.7.0.d12.aarch64.tgz

https://github.com/pgsty/pigsty/releases/download/v3.7.0/pigsty-pkg-v3.7.0.el9.x86_64.tgz

离线软件包是为特定的 Linux 操作系统小版本制作的

在较低的操作系统小版本上使用更高小版本的离线软件包,大概率可以使用,但也有失败的可能


使用离线软件包?

将离线软件包放置于 /tmp/pkg.tgz 路径下,进入 ~/pigsty 目录执行 ./bootstrap,即可解包使用离线安装包。 Pigsty 会将其解压至 /www/pigsty,然后配置系统仓库列表启用此仓库,并从中安装 ansible

自从 Pigsty v3.6 版本起,大部份配置模板都默认不再构建本地软件仓库,而是直接从互联网上游安装软件包。 少部分配置模板如 richfull 依然保留了旧版本的行为 —— 先构建本地仓库再使用。

如果您想要在自己的配置中使用已经解包配置好的离线软件包,请修改以下配置:

  • repo_enabled:将此参数打开,设置为 true,则会构建本地软件源(在大部份配置中被显式关闭)
  • node_repo_modules:将此参数设置为 local,则环境中所有节点都从本地软件仓库安装
    • 在大部份模板中,此参数现在被显式配置为:node,infra,pgsql,即直接从这些上游软件仓库安装。
    • 将其设置为 local,则会使用本地软件仓库安装所有软件包,速度最快,没有其他仓库的变数干扰。
    • 如果你想同时使用本地软件仓库和上游软件仓库,可以将其设置为 local,node,infra,pgsql

优缺点

如果您使用的是上述列表中给出的操作系统(精确匹配的小版本),那么建议使用离线软件包。 Pigsty 为这些系统提供了开箱即用的预制离线软件包,在 GitHub 上提供免费下载。

使用离线软件包的优点
  • 官方离线软件包经过测试。
  • 在与互联网隔离的环境中交付的最简单方法。
  • 通过一次性预下载所有软件包来加速安装过程。
  • 快照确保可以正常工作,无需担心上游依赖项的变动导致依赖错漏。
使用离线软件包的缺点
  • 如果操作系统次要版本不匹配,操作系统的 rpm/deb 软件包可能会出现问题
  • 可能不包含最新的更新和操作系统安全补丁。

如果你使用的操作系统版本不在上述列表中,你可以考虑自制离线安装包,我们也提供针对更多操作系统大小版本的离线安装包预制服务(¥200)


引导程序

bootstrap 脚本将自动检测 /tmp/pkg.tgz 并默认将其解压到 /www/pigsty。 它还将设置操作系统软件包管理器的仓库文件,并安装 ansible 和其他工具。

我的仓库文件在哪里?

引导程序默认会 清除 现有仓库,以确保只安装所需的仓库。

您可以在 /etc/yum.repos.d/backup (EL) 或 /etc/apt/backup (Debian / Ubuntu) 中找到它们

如果您想保留现有仓库

您可以使用 -k|--keep 参数来保持现有仓库文件不变:

./bootstrap -k # 或 --keep

制作离线软件包

如果您选择的操作系统不在默认列表中, 您可以使用内置的 cache.yml 剧本制作自己的离线软件包。

步骤 1

    找到一台运行完全相同操作系统版本,且可以访问互联网的节点

步骤 2

    运行标准 [在线安装](/zh/docs/install) (建议使用 `rich` 配置模板:`configure -c rich`)

步骤 3

    `cd ~/pigsty; ./cache.yml`:制作并获取离线软件包到 `~/pigsty/dist/${version}/`

步骤 4

    将离线软件包复制到没有互联网访问的环境中(ftp、scp、usb 等),通过 `bootstrap` 解包使用
v3.6 的行为变化

自从 Pigsty v3.6 开始,大部份配置模板都直接从互联网上游安装软件包,而不是先下载到管理节点本地构建软件仓库,再从中安装。 你可以通过调整参数来恢复此前的默认行为,如果你需要构建自己的离线软件包,这很有用:

  • repo_enabled:将此参数打开,则会构建本地软件源(在大部份配置中被显式关闭)
  • node_repo_modules:将此参数设置为 local,则环境中所有节点都从本地软件仓库安装

部分配置模板,例如 richfull 依然直接保留旧版本的行为 —— 先构建本地仓库再使用,故无需调整。

我们提供付费服务,提供经过测试的预制 Linux 主版本.次版本制作离线软件包。(¥200)


混合方法

有一种混合方法可以使用离线软件包作为基础,并在线补足不匹配的增量软件包,这种办法可以融合离线安装与在线安装的优点。

例如,假设您使用的是 RockyLinux 9.5,但官方离线软件包是为 RockyLinux 9.6 制作的。 您可以使用 el9 离线软件包,(虽然是针对 9.6 制作的) 然后在执行正式安装前,执行 make repo-build 重新下载 9.5 对应的缺失软件包, Pigsty 将从上游仓库重新下载所需的增量。

1.5 - 精简安装

使用最少依赖安装 PostgreSQL

如果您只想要高可用 PostgreSQL 本身,而不需要监控、基础设施等功能,请考虑精简安装。

没有 INFRA 模块,没有监控,没有 本地仓库,只有 ETCDPGSQL 以及部分 NODE 功能


概述

使用精简安装,您需要:

步骤 1

  使用 `slim.yml` 配置模板(`configure -c slim`)

步骤 2

  运行 `slim.yml` 剧本而不是 `install.yml`
curl https://repo.pigsty.cc/get | bash -s v3.7.0
./configure -c slim
./install.yml

精简安装只安装这些核心组件:

组件 必需性 描述
patroni 必需 引导高可用 PostgreSQL 集群
etcd 必需 Patroni 的元数据库依赖(DCS)
pgbouncer 可选 PostgreSQL 连接池
vip-manager 可选 L2 VIP 绑定到 PostgreSQL 集群主节点
haproxy 可选 自动路由 服务
chronyd 可选 与 NTP 服务器的时间同步
tuned 可选 节点调优模板和内核参数管理

您可以关闭可选组件,只有两个必需组件是 patronietcd

软件包直接从互联网上游仓库安装,离线安装 在此处不适用。


配置

精简安装的配置文件示例:conf/slim.yml

all:
  children:
    infra: { hosts: { 10.10.10.10: { infra_seq: 1 }} ,vars: { repo_enabled: false }}
    etcd:  { hosts: { 10.10.10.10: { etcd_seq: 1  }} ,vars: { etcd_cluster: etcd  }}

    #----------------------------------------------#
    # PostgreSQL Cluster
    #----------------------------------------------#
    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' ] # make a full backup every 1am

  vars:
    #----------------------------------------------#
    # INFRA : https://doc.pgsty.com/infra/param
    #----------------------------------------------#
    version: v3.7.0                   # pigsty version string
    admin_ip: 10.10.10.10             # admin node ip address
    region: default                   # upstream mirror region: default,china,europe
    infra_portal:                     # domain names and upstream servers
      home         : { domain: h.pigsty }
      grafana      : { domain: g.pigsty ,endpoint: "${admin_ip}:3000" , websocket: true }
      prometheus   : { domain: p.pigsty ,endpoint: "${admin_ip}:9058" }
      alertmanager : { domain: a.pigsty ,endpoint: "${admin_ip}:9059" }
      blackbox     : { endpoint: "${admin_ip}:9115" }
      loki         : { endpoint: "${admin_ip}:3100" }

    #----------------------------------------------#
    # NODE : https://doc.pgsty.com/node/param
    #----------------------------------------------#
    nodename_overwrite: false           # do not overwrite node hostname on single node mode
    node_repo_modules: node,infra,pgsql # add these repos directly to the singleton node
    node_tune: oltp                     # node tuning specs: oltp,olap,tiny,crit

    #----------------------------------------------#
    # PGSQL : https://doc.pgsty.com/pgsql/param
    #----------------------------------------------#
    pg_version: 17                      # Default PostgreSQL Major Version is 17
    pg_conf: oltp.yml                   # pgsql tuning specs: {oltp,olap,tiny,crit}.yml
    pg_packages: [ pgsql-main, pgsql-common ]   # pg kernel and common utils
    #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]

    #----------------------------------------------#
    # SLIM: http://localhost:3000/docs/install/minimal
    #----------------------------------------------#
    nginx_enabled: false              # nginx not exists
    dns_enabled: false                # dnsmasq not exists
    prometheus_enabled: false         # prometheus not exists
    grafana_enabled: false            # grafana not exists
    pg_exporter_enabled: false        # disable pg_exporter
    pgbouncer_exporter_enabled: false # disable pgbouncer_exporter
    pgbackrest_exporter_enabled: false # disable pgbackrest_exporter
    pg_vip_enabled: false             # disable pg_vip

安装

使用 slim.yml 剧本而不是 install.yml 剧本:

./slim.yml
不要使用 install.yml 进行精简安装

这个 slim.yml 剧本是专门用来在精简安装场景中取代默认 install.yml 剧本的。

1.6 - 视频演示

安装过程的视频教程

请参见 Asciinema 终端录像: Vonng


标准安装

Pigsty v3.6.0, RockyLinux 9.6, x86_64, 标准安装, Link

这会使用默认的 meta 单节点配置模板,从互联网直接安装所有所需软件包。

curl -fsSL https://repo.pigsty.io/get | bash -s v3.6.0; cd ~/pigsty;
./configure
./install.yml

asciicast


完整安装

Pigsty v3.6.0, Ubuntu 24.04.2, x86_64, 完整安装

完整安装使用 rich 模板,在标准安装的基础上,有以下区别于改动:

  • 尽可能安装(但不都启用)所有 PostgreSQL 扩展插件
  • 构建本地软件仓库,先下载到本地仓库,再让所有节点都从本地软件仓库进行安装
  • 1 node minio used as central backup repo
  • cluster stub for 3-node pg-test / ferret / redis
  • stub for nginx, certs, and website self-hosting config
  • detailed comments for database / user / service
./configure -c rich     # use the conf/rich.yml template
./install.yml
curl -fsSL https://repo.pigsty.io/get | bash -s v3.6.0; cd ~/pigsty;
./configure -i rich
vi pigsty.yml   # edit password
./install.yml
make tu tssh
asciinema rec
ssh meta
ls /www/pigsty
cat ~/pigsty/pigsty.yml | grep node_repo_modules
sudo su - postgres
pg list
pb info
pg-backup incr
pb list
psql
SELECT * FROM pg_available_extensions;

Slim Install

Pigsty v3.6.0, Debian 12.11, aarch64, Slim Installation, Link

Postgres HA Cluster with essential modules, (with ETCD, without INFRA).

asciinema rec
ssh meta
curl -fsSL https://repo.pigsty.io/get | bash -s v3.6.0; cd ~/pigsty;
./configure -i slim
./slim.yml
sudo su - postgres
psql

Offline Install

Pigsty v3.6.0, RockyLinux 9.6, aarch64, Slim Installation

# download this offline package and put it to /tmp/pkg.tgz, we just skip downloading here
# curl https://github.com/pgsty/pigsty/releases/download/v3.6.0/pigsty-pkg-v3.6.0.el9.x86_64.tgz -o /tmp/pkg.tgz
scp ~/pigsty/dist/v3.6.0/pigsty-v3.6.0.tgz meta:~/pigsty.tgz

# download source package and extract it to ~/pigsty, we just skip downloading here
# curl https://github.com/pgsty/pigsty/releases/download/v3.6.0/pigsty-v3.6.0.tgz -o ~/pigsty.tgz; tar xzf ~/pigsty.tgz -C ~/
scp ~/pigsty/dist/v3.6.0/pigsty-pkg-v3.6.0.el9.aarch64.tgz meta:/tmp/pkg.tgz

ssh meta
tar -xf pigsty.yml  # extract pigsty source tarball
cd pigsty           # enter pigsty home dir
./bootstrap         # now bootstrap pigsty from local repo
./configure         # generate pigsty.yml
vi pigsty.yml       # use local repo rather than install from the internet upstream repo
#node_repo_modules: local

./install.yml

Supabase

Pigsty v3.6.0, Ubuntu 24.04, x86_64, Install Supabase

curl -fsSL https://repo.pigsty.io/get | bash -s v3.6.0; cd ~/pigsty;
./configure -c supabase
./install.yml
./docker.yml   # install docker & docker-compose
./app.yml      # launch supabase docker app with docker compose
vi pigsty.yml


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


cd /opt/supabase
docker ps

sudo su - postgres
pg list
pb info
pg-backup incr
pb info

psql
\dn
\l
\du
table pg_available_extensions;

\c supabase
\dn
\du

# Now let's setup your domain name and HTTPS certificates
ssh meta            # the temp cloud server for the supabase demo
dig supa.pigsty.cc  # let's use this as example, use your domain name instead, and resolve it to your server IP
cd ~/pigsty/
grep supa.pigsty pigsty.yml -a2 -b2
sed -ie 's/supa.pigsty/supa.pigsty.cc/g' pigsty.yml  # rename old supa.pigsty domain placeholder to your domain name
sed -ie 's/supa.pigsty.cc/supa.pigsty/g' pigsty.yml  # rename old supa.pigsty domain placeholder to your domain name
grep supa.pigsty pigsty.yml -a2 -b2
curl -i https://supa.pigsty.cc

2 - 准备

为严肃的部署准备资源
硬件
    节点、规格、磁盘、网络、VIP、域名...
Linux 操作系统
    支持的 Linux 操作系统发行版列表
软件
    区域设置、防火墙、Ansible、Pigsty...
管理员
    用户、Sudo、SSH、可访问性...

您可以利用 IaC 工具如 TerraformVagrant 来帮助您准备环境并完成繁重的工作。

Ansible
    Ansible 101,pigsty 用户的基础知识
沙盒
    用于学习和测试的四节点沙盒
Vagrant
    使用 vagrant 置备本地虚拟机
Terraform
    使用 terraform 置备云服务器

这里有一个检查清单,帮助您为生产环境中的严肃 Pigsty 部署准备环境。

项目 要求 项目 要求
节点 至少 1C1G,推荐 2C2G,无上限 规格 至少 1 个节点,2 个用于半高可用,3+ 个用于真正的高可用
磁盘 /data,主挂载点,ext4xfs 网络 静态内网,IPv4 地址,最好有互联网访问
VIP 为 VIP 保留一个 L2 IP (可选 域名 使用本地 / 公共域名(可选
内核 Linux,MacOS 可用作管理控制器 发行版 EL (8/9)、Debian (12)、Ubuntu (22/24)、x86_64 / aarch64
区域设置 C.UTF-8C 防火墙 端口:80 / 443 / 22 / 5432
用户 避免使用 rootpostgres Sudo nopass sudo 权限
SSH 通过公钥 nopass 可访问 ssh <ip|alias> sudo ls 有效

2.1 - 硬件置备

节点、规格、磁盘、网络、VIP、域名…

节点

Pigsty 目前运行在具有 Linux 内核和 x86_64 / aarch64 架构的节点上。

节点” 指的是 SSH 可访问 且提供裸 Linux 操作系统环境的资源。 它可以是物理机、虚拟机或配备 systemdsudosshd 的类似操作系统的容器。

部署 pigsty 至少需要 1 个节点, 您可以准备更多并在 一次性 中设置所有内容,或稍后添加它们。 最小节点规格要求是 1C1G,建议至少使用 2C2G。 越高越好,没有上限。参数将根据可用资源自动调优。

生产部署使用多个节点

功能性 HA 设置至少需要 3 个节点才能工作,或使用 2 个节点进行半 HA 设置


规格

您需要多少个节点?这取决于您的资源和需求。

单节点设置

最简单的设置,所有内容都在单个节点上运行,安装四个基本模块:

ID NODE PGSQL INFRA ETCD
1 node-1 pg-meta-1 infra-1 etcd-1

如果为备份/PITR 配置了外部 S3/MinIO,此设置可用于生产。

双节点设置

双节点设置启用数据库复制和半 HA 功能:

ID NODE PGSQL INFRA ETCD
1 node-1 pg-meta-1 (主节点) infra-1 etcd-1
2 node-2 pg-meta-2 (副本)

虽然比单节点设置更强大,但 HA 有限制:

  • 如果 node-1 故障,无自动故障转移 - 需要手动提升 node-2
  • 如果 node-2 故障,自动故障转移有效 - node-1 自动提升

这种"半 HA"设置只能从特定节点故障中自动恢复。

三节点设置

真正的 HA 设置,可以从任何单个节点故障中自动恢复:

ID NODE PGSQL INFRA ETCD
1 node-1 pg-meta-1 infra-1 etcd-1
2 node-2 pg-meta-2 infra-2 etcd-2
3 node-3 pg-meta-3 infra-3 etcd-3
四节点设置

Pigsty 沙盒 使用的标准演示环境:

ID NODE PGSQL INFRA ETCD
1 node-1 pg-meta-1 infra-1 etcd-1
2 node-2 pg-test-1 etcd-2
3 node-3 pg-test-2 etcd-3
4 node-4 pg-test-3

磁盘

Pigsty 将使用 /data 作为默认数据目录,如果您有专用的主数据磁盘,建议将其挂载到那里, 并为额外的磁盘驱动器使用 /data1/data2/dataN

将磁盘挂载到别处?

如果您将其挂载到别处,您必须相应地更改以下参数:

名称 描述 默认值
node_data 节点主数据目录 /data
pg_fs_main postgres 主数据目录 /data
pg_fs_backup postgres 备份数据目录 /data/backups
etcd_data etcd 数据目录 /data/etcd
prometheus_data prometheus 数据目录 /data/prometheus
loki_data loki 数据目录 /data/loki
minio_data minio 数据目录 /data/minio
redis_fs_main redis 数据目录 /data/redis

我们建议使用 ext4xfs 作为数据磁盘的文件系统。它们对 PostgreSQL 有最佳性能。

虽然 ext4 有更多的数据恢复工具,但 xfs 对小文件更高效。 如果您运行 MinIO,建议使用 xfs,否则,建议使用 ext4 作为默认选项。

Pigsty 的工作假设是 /data 目录属于 root:root,权限为 755。 管理员可以分配一级目录的所有权和权限。每个应用在其子目录中运行时将使用专用用户。


网络

Pigsty 需要静态网络才能工作,您应该为每个节点明确分配一个固定的 IPv4 地址。

没有固定 IP?

在单节点安装中,如果没有固定 IP 地址,可以使用 127.0.0.1 作为变通方法。

IP 地址将用作节点的唯一标识符,它应该是绑定到用于内部网络通信的主网络接口的主 IP 地址。

永远不要使用公共 IP 作为标识符

使用公共 IP 地址作为节点标识符可能导致安全和连接问题。

L2 VIP 需要 L2 网络

要使用可选的节点 VIP 和 PG VIP 功能,请确保所有节点位于同一 L2 网络内

执行标准(在线)安装 时需要互联网访问。 但 pigsty 可以通过离线软件包进行 离线安装, 在这种情况下不需要互联网访问。


VIP

Pigsty 支持 NODE 集群(keepalived)和 PGSQL 集群(vip-manager)的可选 L2 VIP。

要使用 L2 VIP 功能,您必须为它们明确分配一个 L2 VIP。 在您自己的硬件上运行时这不是大问题, 但在公有云环境中工作时可能成为问题。


域名

Pigsty 为以下具有 WebUI 的服务使用本地静态域名。 您可以为这些服务分配自定义域名,或使用真实域名。 只需在 infra_portal 中更改它们。

域名 名称 端口 组件 描述
h.pigsty home 80/443 Nginx 默认服务器,本地仓库
g.pigsty grafana 3000 Grafana 监控和可视化
p.pigsty prometheus 9058 Prometheus 时间序列数据库
a.pigsty alertmanager 9059 AlertManager 告警聚合和路由

域名是可选的,要使用它们,用户有责任将以下记录添加到您的 /etc/hosts 文件(本地静态解析), 或将它们添加到您的 DNS 服务器/公共 DNS 供应商。

10.10.10.10 h.pigsty g.pigsty p.pigsty a.pigsty

2.2 - Linux 系统

与 Pigsty 兼容的 Linux 操作系统发行版列表

Pigsty 推荐使用以下操作系统:RockyLinux 9.6, Ubuntu 24.04.2,与 Debian 12.11。

发行版 架构 系统代码 PG18 PG17 PG16 PG15 PG14 PG13
RHEL9 / Rocky9 / Alma9 x86_64 el9.x86_64
RHEL9 / Rocky9 / Alma9 aarch64 el9.aarch64
Ubuntu 24.04 (noble) x86_64 u24.x86_64
Ubuntu 24.04 (noble) aarch64 u24.aarch64
Debian 12 (bookworm) x86_64 d12.x86_64
Debian 12 (bookworm) aarch64 d12.aarch64
推荐使用 EL 9.6
推荐使用 Debian 12.11
推荐使用 Ubuntu 24.04.2

EL

Pigsty 支持 EL 8/9/10 兼容系统(RHEL / Rocky / Alma / Anolis / CentOS …… ),推荐使用 RockyLinux 9.6。

EL 发行版 架构 系统代码 PG18 PG17 PG16 PG15 PG14 PG13
RHEL10 / Rocky10 / Alma10 x86_64 el10.x86_64
RHEL10 / Rocky10 / Alma10 aarch64 el10.aarch64
RHEL9 / Rocky9 / Alma9 x86_64 el9.x86_64
RHEL9 / Rocky9 / Alma9 aarch64 el9.aarch64
RHEL8 / Rocky8 / Alma8 x86_64 el8.x86_64
RHEL8 / Rocky8 / Alma8 aarch64 el8.aarch64
RHEL7 / CentOS7 x86_64 el7.x86_64
RHEL7 / CentOS7 aarch64 -
推荐使用 RockyLinux 9.6

RockyLinux 9.6 提供了完整的扩展插件支持,是 Pigsty 首要支持并推荐使用的 EL 系统版本。

EL 7 EOL

EL 7 支持已经不再维护,如果您需要在过时系统上运行,考虑我们的专业服务。


Ubuntu

Pigsty v3.7 支持 Ubuntu 24.04 / 22.04,建议使用 24.04.2。

Ubuntu 发行版 架构 系统代码 PG18 PG17 PG16 PG15 PG14 PG13
Ubuntu 24.04 (noble) x86_64 u24.x86_64
Ubuntu 24.04 (noble) aarch64 u24.aarch64
Ubuntu 22.04 (jammy) x86_64 u22.x86_64
Ubuntu 22.04 (jammy) aarch64 u22.aarch64
推荐使用 Ubuntu 24.04.2 LTS

Ubuntu 24.04 提供了完整的扩展插件支持,是 Pigsty 首要支持并推荐使用的 Linux 系统版本。


Debian

Pigsty 可运行于 Debian 13 / 12 / 11 上,建议使用 12.11。

Debian 发行版 架构 系统代码 PG18 PG17 PG16 PG15 PG14 PG13
Debian 13 (trixie) x86_64 d13.x86_64
Debian 13 (trixie) aarch64 d13.aarch64
Debian 12 (bookworm) x86_64 d12.x86_64
Debian 12 (bookworm) aarch64 d12.aarch64
Debian 11 (bullseye) x86_64 d11.x86_64
Debian 11 (bullseye) aarch64 -
推荐使用 Debian 12.11

Debian 12 带有完整的扩展支持,是 Pigsty 首要支持并推荐使用的 Linux 系统版本。

Debian 11 支持

Debian 11 支持已经不再维护,如果您需要在过时系统上运行,考虑我们的专业服务。

2.3 - 软件置备

区域设置、防火墙、Ansible、Pigsty…

Linux

Pigsty 运行在 Linux 操作系统上,它支持 14 种主流 Linux 发行版:兼容操作系统列表

我们推荐使用 RockyLinux 9.6Debian 12.11Ubuntu 24.04.5 作为默认操作系统选项。

在 macOS 上运行 pigsty?

您可以在 macOS 上安装 pigsty,并使用 ansible 从本地笔记本电脑发起控制。(用作管理节点) 但数据库/基础设施/节点/etcd 服务仍在 Linux 节点上运行。

我们强烈建议使用全新安装的操作系统环境,并将 en_US 设置为主要语言。

如何启用 en_US 区域设置?

在使用其他主要语言时确保 en_US 区域设置可用:

localedef -i en_US -f UTF-8 en_US.UTF-8
localectl set-locale LANG=en_US.UTF-8

Pigsty 使用容器,主要组件针对特定发行版主版本打包。

在所有节点上使用相同的操作系统版本

请在单个部署中的所有节点上使用相同的操作系统主版本和次版本。


文件系统

Pigsty 建议使用 ext4xfs 文件系统,两者在 PostgreSQL 用例上都有最好的性能表现。 如果您清楚知道自己在做什么,也可以考虑使用 zfs 这样的文件系统,但切勿使用 nfs 等网络文件系统运行数据库服务。

如果您需要使用到 MinIO,建议使用 xfs 文件系统,这是 MinIO 唯一推荐使用到文件系统。 它在大量小文件的场景中有更好的性能表现,但工具生态(例如数据恢复)略逊于 ext4

如果您只是运行标准 PostgreSQL 服务,我们建议您默认使用 Linux ext4 文件系统。


防火墙

您的安全策略和防火墙设置应该允许访问所需的端口。

要访问 WebUI 服务,您必须允许 HTTP(80)/ HTTPS(443)访问。

要访问 PostgreSQL 数据库服务,您必须允许 postgres 的 5432 端口。

您可以通过其他端口访问 postgres 服务
  • 5432: PostgreSQL 数据库
  • 6432: Pgbouncer 连接池
  • 5433: PG 主要服务
  • 5434: PG 副本服务
  • 5436: PG 默认服务
  • 5438: PG 离线服务

如果您通过其他端口访问 postgres 服务,请相应地允许它们

在典型的公有云 VPS 设置中,端口 22/80/443/5432 通常是开放的。

谨慎公开数据库端口

直接向互联网暴露数据库服务端口是非常危险的。 如果您需要这样做,请考虑咨询 安全最佳实践 并谨慎进行。

在典型的生产设置中,端口 22/80/443 从 LAN / 跳板机向 DBA/OPS 开放。 其他端口从内网访问。您必须确保它们在内部开放:使用的端口


Ansible

Pigsty 使用 Ansible 从管理节点发起对所有被管理节点的控制。

您不需要关心细节,ansible 在 Bootstrap 阶段安装。

手动安装 Ansible
sudo apt install -y ansible python3-jmespath
sudo dnf install -y ansible python3-jmespath
sudo dnf install -y ansible python3.12-jmespath
sudo yum install -y ansible python-jmespath
brew install ansible
pip3 install jmespath

Ansible 只在管理节点上需要,您可以在 macOS 上运行 ansible 将您的笔记本电脑用作管理节点。


Pigsty

推荐)您可以使用以下方式获取并提取最新稳定版本的 pigsty 源代码:

curl -fsSL https://repo.pigsty.io/get | bash -s v3.7.0; cd ~/pigsty
curl -fsSL https://repo.pigsty.cc/get | bash -s v3.7.0; cd ~/pigsty   # 中国镜像

要安装特定版本,将版本字符串作为第一个参数传递:

curl -fsSL https://repo.pigsty.io/get | bash -s v3.7.0; cd ~/pigsty
curl -fsSL https://repo.pigsty.cc/get | bash -s v3.7.0; cd ~/pigsty # 中国镜像

您也可以使用 gitGitHub 克隆 Pigsty 源代码仓库:

克隆最新版本
git clone https://github.com/pgsty/pigsty.git; cd ~/pigsty; git checkout v3.7.0
使用前检出特定版本

默认的 main 分支可能处于不稳定的开发状态,使用前请 git checkout v3.7.0

$ curl -fssL https://repo.pigsty.cc/get | bash -s v3.7.0
[v3.7.0] ===========================================
$ curl -fsSL https://repo.pigsty.cc/get | bash -s v3.7.0
[Docs] https://doc.pgsty.com
[Demo] https://g.pgsty.com
[Repo] https://github.com/pgsty/pigsty
[Download] ===========================================
[ OK ] version = v3.7.0 (from arg)
curl -fSL https://repo.pigsty.cc/src/pigsty-v3.7.0.tgz -o /tmp/pigsty-v3.7.0.tgz
[WARN] tarball = /tmp/pigsty-v3.7.0.tgz exists, size = 1472486, use it
[ OK ] md5sums = df64ac0c2b5aab39dd29698a640daf2e  /tmp/pigsty-v3.7.0.tgz
[Install] ===========================================
[ OK ] install = /home/vagrant/pigsty, from /tmp/pigsty-v3.7.0.tgz
[Bootstrap] ===========================================
[ OK ] ansible = ready
[ OK ] bootstrap = skip
you can run ./bootstrap to extrac offline package and install ansible
[TodoList] ===========================================
cd /home/vagrant/pigsty
./configure      # [可选] 预检和配置生成
./install.yml    # 部署配置描述的所有内容

您也可以从 GitHub Release Page 手动下载 pigsty 源代码(pigsty-<version>.tar.gz):

wget https://repo.pigsty.io/src/pigsty-v3.7.0.tgz
wget https://pigsty.cc/pgsty/pigsty/releases/download/v3.7.0/pigsty-v3.7.0.tgz
wget https://github.com/pgsty/pigsty/releases/download/v3.7.0/pigsty-v3.7.0.tgz

如果您的环境没有互联网访问,请考虑与源代码压缩包一起下载离线软件包并将其上传到您的节点。

详情请查看 离线安装

2.4 - 管理用户

用户、区域设置、Sudo、SSH、可访问性…

用户

Pigsty 需要一个在所有被管理节点上具有免密 sshsudo 权限的操作系统用户


命名约定

通常我们会选择 dbaadmin 这样的名称, 但避免使用 rootpostgres

避免使用 root 用户

虽然可能,但出于安全原因,不建议使用 root 作为管理员用户。

不要使用 postgres dbsu 作为管理员用户

DBSU(默认为 postgres不应该用作管理员用户。 这会导致意外的安全问题。

如果您使用不同的 dbsu 用户,也避免将其用作管理员用户。


提供密码

如果您可以接受每个 sshsudo 命令的密码提示,则免密要求是可选的。

使用密码提示运行 playbook

您可以在运行 playbook 时使用 -k|--ask-pass 来提示输入 ssh 密码。

并使用 -K|--ask-become-pass 来提示输入 sudo 密码。

./install.yml -k -K

创建管理员用户

在服务器置备阶段,用户/供应商有责任创建并交付这样的管理员用户。 但如果您没有这样的管理员用户,或者该用户受到限制,您可以使用 pigsty 本身创建一个:

使用 pigsty 创建管理员用户

假设您在节点上有 root 或现有的管理员用户,您可以使用 pigsty 本身创建管理员用户。

./node.yml -k -K -t node_admin -e ansible_user=[existing_admin_user]

它将利用现有的管理员创建新的管理员用户。 它将创建由以下参数描述的专用 dba(uid=88)用户, 并正确配置 sudo / ssh。

名称 描述 默认值
node_admin_enabled 启用节点管理员用户 true
node_admin_uid 节点管理员用户的 uid 88
node_admin_username 节点管理员用户名 dba

Sudo 权限

所有 管理员用户 都应该在所有被管理节点上具有免密 sudo 权限。

如果您想从头开始配置具有免密 sudo 权限的管理员用户:

允许免密 sudo

要手动允许用户执行免密 sudo 命令:

为您的管理员用户创建 sudoers 文件(假设是 vagrant,请替换为您选择的名称):

echo '%vagrant ALL=(ALL) NOPASSWD: ALL' | sudo tee /etc/sudoers.d/vagrant

假设您的管理员用户名选择是 dba,那么 /etc/sudoers.d/dba 内容应该是

%dba ALL=(ALL) NOPASSWD: ALL

Ansible 依赖 sudo 在被管理节点上以 root 权限执行命令。 因此,在 sudo 不可用的环境中(比如在精简容器内),您可能需要先安装 sudo


SSH

您的当前用户应该能够以相应的管理员用户身份免密 SSH 访问所有被管理节点。

您的当前用户可以是管理员用户本身,但不是必需的,只要您能以管理员用户身份 SSH。

SSH 配置是 Linux 101,但我们会在此处介绍基础知识,以防您不熟悉:


生成 SSH 密钥

如果您没有 SSH 密钥对,请生成一个

生成 SSH 密钥
ssh-keygen -t rsa -b 2048 -N '' -f ~/.ssh/id_rsa -q

如果您没有密钥对,Pigsty 会在 bootstrap 阶段为您完成此操作。


复制 SSH 密钥

您需要将生成的公钥分发到远程(和本地)服务器,并将其放入 所有节点上管理员用户的 ~/.ssh/authorized_keys 文件中。 可以使用 ssh-copy-id 工具。

将您的 ssh 密钥分发到其他节点

将公钥复制到所有被管理节点,使用 ssh-copy-id 或手动添加到 ~/.ssh/authorized_keys

ssh-copy-id <ip>                        # 交互式密码输入

您可以使用 sshpass 工具直接传递密码而不提示,但这很危险:

sshpass -p <password> ssh-copy-id <ip>  # 非交互式(谨慎使用)

使用别名

当无法直接 SSH 访问时(由于跳板机、其他端口、凭据等…),考虑:

使用 SSH 别名

~/.ssh/config 中配置 SSH 别名,并在那里放置别名的自定义参数。

Host meta
    HostName 10.10.10.10
    User dba                      # <--- 远程上不同的用户
    IdentityFile /etc/dba/id_rsa  # <--- 不是普通密钥
    Port 24                       # <--- 不是众所周知的端口

并在清单中引用别名,使用 ansible_host 指定真实的 SSH 别名。

nodes:
  hosts:          # 如果节点 `10.10.10.10` 需要 SSH 别名 `meta`
    10.10.10.10: { ansible_host: meta }  # <---- 通过 `ssh meta` 访问

SSH 参数可以直接在 ansible 中使用,详情请查看 Ansible Inventory Guide


检查可访问性

您应该能够从管理节点通过当前用户免密 ssh 访问所有被管理节点。 远程用户(管理员用户)应该有权限运行免密 sudo 命令。

验证免密 ssh sudo 是否工作

在管理节点上对所有被管理节点运行此命令:

ssh <ip|alias> 'sudo ls'

如果没有密码提示或错误,免密 ssh/sudo 按预期工作。

2.5 - 沙箱环境

用于学习和测试的 4 节点环境

Pigsty 有一个沙盒,这是一个具有固定 IP 地址和其他标识符的 4 节点部署。

我们将使用它作为学习和测试目的的标准演示环境。

pigsty-sandbox.jpg

描述

沙盒由具有固定 IP 地址和身份的 4 个节点组成:

ID IP 地址 NODE PGSQL INFRA ETCD MINIO
1 10.10.10.10 meta pg-meta-1 infra-1 etcd-1 minio-1
2 10.10.10.11 node-1 pg-test-1
3 10.10.10.12 node-2 pg-test-1
4 10.10.10.13 node-3 pg-test-1

meta 节点上有一个主要的单例 PostgreSQL 集群:pg-meta, 它可以独立使用,还有一个可选的 L2 VIP 10.10.10.2 和集群 DNS pg-meta 绑定到它。

10.10.10.10 meta pg-meta-1
10.10.10.2  pg-meta

沙盒中还有三个额外的节点,组成一个 3 实例的 PostgreSQL HA 集群 pg-test。 有一个可选的 L2 VIP 10.10.10.3 和集群 DNS pg-test 绑定到集群领导者。

10.10.10.11 node-1 pg-test-1
10.10.10.12 node-2 pg-test-2
10.10.10.13 node-3 pg-test-3
10.10.10.3  pg-test

meta 节点上还有一个 1 节点的 etcd 集群和 1 节点的 minio 集群。

10.10.10.10 minio-1
10.10.10.10 etcd-1

实现

您可以使用 Vagrant 创建本地沙盒,或使用 Terraform 创建云沙盒。

要使用本地 vagrant 模板:

make full9     # 使用 RockyLinux 9 创建 4 节点沙盒
make full12     # 使用 Debian 12 创建 4 节点沙盒
make full24     # 使用 Ubuntu 24.04 创建 4 节点沙盒

要使用云 terraform 模板,请使用 spec/aliyun-full.tf 作为示例, 阿里云 4 节点沙盒模板适用于所有发行版和 amd/arm。

make tu     # terraform up
make td     # terraform destroy
make tssh   # 将 ssh 别名写入 ~/.ssh/pigsty_config

2.6 - Vagrant

使用 vagrant 置备本地虚拟机

Pigsty 需要 Linux 环境,您可以使用 Vagrant 轻松创建本地 linux 虚拟机。

您还需要一个虚拟机提供商,(比如笔记本电脑的 VirtualBox 和服务器的 libvirt)


入门

您可以在 macOS 上使用 homebrew 安装 vagrant、virtualbox、ansible:

在 macos 上安装
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install vagrant virtualbox ansible

您已准备就绪!使用 make 快捷方式创建虚拟机:

~/pigsty
make meta       # 1 节点开发箱,用于快速启动、开发、测试和实验
make full       # 4 节点沙盒,用于 HA 测试和功能演示
make simu       # 36 节点模拟箱,用于生产环境模拟
...
make meta9      # 使用 bento/rockylinux-9 镜像创建单例元节点
make full22     # 使用 generic/ubuntu2204 镜像创建 4 节点沙盒
make simu12     # 使用 generic/debian12 镜像创建 36 节点模拟环境

配置

您必须在启动前在 Vagrantfile 中定义虚拟机。 默认的 Vagrantfile 定义了一个 el9(bento/rockylinux-9)1 节点虚拟机,使用本地 virtualbox VM 提供商。

我们在 vagrant/spec 文件夹中有一系列预定义的 VM 规格

模板 节点 规格 注释 别名
meta.rb 1 节点 2c4g x 1 单节点元数据 开发箱
dual.rb 2 节点 1c2g x 2 双节点
trio.rb 3 节点 1c2G x 3 三节点
full.rb 4 节点 2c4g + 1c2g x 3 全功能 4 节点 沙盒
simu.rb 36 节点 杂项 生产环境模拟 模拟箱
oss.rb 3 节点 1c2g x 3 3 节点 OSS 构建环境
pro.rb 5 节点 1c2g x 5 5 节点 PRO 构建环境

每个规格文件包含一个描述 VM 节点的 Specs 变量。例如,full.rb 包含:

# full: pigsty 全功能 4 节点沙盒,用于 HA 测试、教程和实践

Specs = [
  { "name" => "meta"   , "ip" => "10.10.10.10" ,  "cpu" => "2" ,  "mem" => "4096" ,  "image" => "bento/rockylinux-9"  },
  { "name" => "node-1" , "ip" => "10.10.10.11" ,  "cpu" => "1" ,  "mem" => "2048" ,  "image" => "bento/rockylinux-9"  },
  { "name" => "node-2" , "ip" => "10.10.10.12" ,  "cpu" => "1" ,  "mem" => "2048" ,  "image" => "bento/rockylinux-9"  },
  { "name" => "node-3" , "ip" => "10.10.10.13" ,  "cpu" => "1" ,  "mem" => "2048" ,  "image" => "bento/rockylinux-9"  },
]

您可以使用规格与 config 脚本,它将根据规格和环境变量(资源、镜像、vm 提供商等…)渲染 Vagrantfile

cd ~/pigsty
vagrant/config [spec] [image] [scale] [provider]

vagrant/config meta                # 使用 1 节点规格,默认 el8 镜像
vagrant/config dual el9            # 使用 2 节点规格,使用 el9 镜像
vagrant/config trio d12 2          # 使用 3 节点规格,使用 debian12 镜像,双倍 cpu/mem 资源
vagrant/config full u22 4          # 使用 4 节点规格,使用 ubuntu22 镜像,使用 4x cpu/mem 资源
vagrant/config simu u24 1 libvirt  # 使用 36 节点规格,使用 ubuntu24 镜像,使用 libvirt 作为提供商而不是 virtualbox

您可以使用环境变量 VM_SCALE 扩展资源单位,默认值为 1

例如,VM_SCALE=2 vagrant/config meta 将使 meta 规格的 cpu / mem 资源翻倍

Specs = [
  { "name" => "meta" , "ip" => "10.10.10.10", "cpu" => "8" , "mem" => "16384" , "image" => "bento/rockylinux-9" },
]

快捷方式

配置后,您可以使用 vagrant up 命令创建虚拟机。

Pigsty 模板将使用您的 ~/.ssh/id_rsa[.pub] 作为 vagrant 置备的默认 ssh 密钥。 在开始之前确保您有有效的 ssh 密钥对,您可以通过以下方式生成一个:ssh-keygen -t rsa -b 2048

有一些包装 vagrant 命令的快捷方式,您可以使用它们来管理虚拟机。

~/pigsty/vagrant
make         # = make start
make new     # 销毁现有 vm 并创建新的
make ssh     # 将 VM ssh 配置写入 ~/.ssh/     (必需)
make dns     # 将 VM DNS 记录写入 /etc/hosts (可选)
make start   # 启动 VM 并写入 ssh 配置    (up + ssh)
make up      # 使用 vagrant up 启动 VM
make halt    # 关闭 VM (down,dw)
make clean   # 销毁 VM (clean/del/destroy)
make status  # 显示 VM 状态 (st)
make pause   # 暂停 VM (suspend,pause)
make resume  # 恢复 VM (resume)
make nuke    # 使用 virsh 销毁所有 vm 和卷(如果使用 libvirt)

版本

Pigsty 目前使用以下 vagrant 盒子进行测试:

x86_64
$ vagrant box list

el8 :  bento/rockylinux-8     (libvirt, 202502.21.0, (amd64))
el9 :  bento/rockylinux-9     (libvirt, 202502.21.0, (amd64))

d11 :  generic/debian11       (libvirt, 4.3.12, (amd64))
d12 :  generic/debian12       (libvirt, 4.3.12, (amd64))

u20 :  generic/ubuntu2004     (libvirt, 4.3.12, (amd64))
u22 :  generic/ubuntu2204     (libvirt, 4.3.12, (amd64))
u24 :  bento/ubuntu-24.04     (libvirt, 20250316.0.0, (amd64))

它们并非都有 arm64 架构支持,所以在使用 Apple Silicon MacOS 时要注意。

aarch64
bento/rockylinux-9 (virtualbox, 202502.21.0, (arm64))
bento/ubuntu-24.04 (virtualbox, 202502.21.0, (arm64))

您可以在 https://app.vagrantup.com/bento/boxes 上找到支持的 Box 镜像


注意事项

Virtualbox 网络配置

当使用较旧版本的 virtualbox 作为 vagrant 提供商时,需要额外设置才能使用默认的 10.x.x.x CIDR 作为仅主机网络:将其添加到 /etc/vbox/networks.conf

echo "10.0.0.0/8" | sudo tee -a /etc/vbox/networks.conf

2.7 - Terraform

使用 terraform 置备云虚拟机

Terraform 是一个流行的 IaC 工具。您可以使用一个命令在公有云上创建虚拟机。

阿里云和 AWS 模板用作示例提供商。您可以将 terraform.tf 作为示例。


入门

您可以在 macOS 上使用 homebrew 安装 terraform

安装 homebrew 和 terraform
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install terraform

然后初始化 terraform 云提供商,调整 terraform.tf 配置文件并应用它:

cd ~/pigsty/terraform
terraform init
terraform apply #-auto-approve

打印公共 IP 地址:

terraform output | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'

AWS 设置

您必须设置 aws 配置和凭据才能使用 AWS 提供商。

# ~/.aws

# ~/.aws/config
[default]
region = cn-northwest-1

# ~/.aws/credentials
[default]
aws_access_key_id = <YOUR_AWS_ACCESS_KEY>
aws_secret_access_key =  <AWS_ACCESS_SECRET>

# ~/.aws/pigsty-key
# ~/.aws/pigsty-key.pub

有一个 AWS(Amazon Web Services)的贡献示例,但它没有得到积极维护。


阿里云设置

您可以将您的阿里云凭据添加到环境文件中,例如 ~/.bash_profile

export ALICLOUD_ACCESS_KEY="<your_access_key>"
export ALICLOUD_SECRET_KEY="<your_secret_key>"
export ALICLOUD_REGION="cn-beijing"

示例配置文件:

  • spec/aliyun-meta.tf : 阿里云 1 元节点模板,适用于所有发行版和 amd/arm(默认)
  • spec/aliyun-full.tf : 阿里云 4 节点沙盒模板,适用于所有发行版和 amd/arm。
  • spec/aliyun-oss.tf : 阿里云 5 节点构建模板,适用于所有发行版和 amd/arm。

以下是阿里云中使用的示例 ECS 公共操作系统镜像

发行版 镜像前缀 镜像前缀
CentOS 7.9 centos_7_9_x64 rockylinux_8_10_arm6
Rocky 8.10 rockylinux_8_10_x64 rockylinux_9_6_arm64
Rocky 9.6 rockylinux_9_5_x64
Debian 11.11 debian_11_11_x64
Debian 12.11 debian_12_11_x64 debian_12_11_arm64
Ubuntu 20.04 ubuntu_20_04_x64
Ubuntu 22.04 ubuntu_22_04_x64 ubuntu_22_04_arm64
Ubuntu 24.04 ubuntu_24_04_x64 ubuntu_24_04_arm64
Anolis 8.8 anolisos_8_9_x64

腾讯云设置

有一个腾讯云的贡献示例,但它没有得到积极维护。

3 - 配置

使用配置描述您的环境

Pigsty 将基础设施和数据库视为代码。 您可以使用声明式配置 清单 描述一切。 通常是 YAML 格式的 Ansible 清单pigsty.yml。 但 CMDB 也可以用作动态清单。

configure 过程将根据您的环境和输入生成配置。 但这是 可选的:您始终可以直接编辑 pigsty.yml 文件,如 教程 所示。 并且有大量的 模板 供您参考。

清单
    Pigsty 的主配置文件,描述您的整个部署
配置
    根据您的输入和环境生成配置文件
教程
    根据业务需求规划您的部署
模板
    可用的配置模板和示例
安全
    生产部署的安全考虑和最佳实践
CMDB
    使用 PostgreSQL 作为 CMDB 而不是本地 YAML 配置文件

PGSQL
    具有 HA、PITR、IaC、ACL、监控、连接池的 PostgreSQL 集群
INFRA
    用于可观测性的 Nginx、仓库、DNS、NTP、Prometheus 和 Grafana 技术栈
NODE
    将节点注册到期望状态并监控它,以及 VIP、HAProxy
ETCD
    可靠的分布式共识存储 (DCS),为 PGSQL HA 提供支持
MINIO
    兼容 S3 的对象存储,可选备份存储
REDIS
    高性能内存缓存,可选数据结构服务器

3.1 - 清单

Pigsty 的主配置文件

每个 pigsty 部署都有一个对应的配置 清单。 它可以存储在 YAML 格式的本地配置文件中,或从 CMDB 或任何 ansible 兼容格式动态生成。 Pigsty 默认使用一个单一的 YAML 配置文件,即 pigsty.yml位于 pigsty 主目录中。

configure 脚本将根据您的环境和输入生成具有良好默认值的 pigsty.yml 文件脚手架, 但它是 可选的:您始终可以直接编辑 pigsty.yml 文件,如教程所示。


结构

清单由两部分组成:全局变量 和多个 。您可以在 all.children 中定义新集群。 并使用全局变量描述基础设施:all.vars。它可能看起来像这样:

all:                  # 顶级对象:all
  vars: {...}         # 全局参数
  children:           # 组定义
    infra:            # 组定义:'infra'
      hosts: {...}        # 组成员:'infra'
      vars:  {...}        # 组参数:'infra'
    etcd:    {...}    # 组定义:'etcd'
    pg-meta: {...}    # 组定义:'pg-meta'
    pg-test: {...}    # 组定义:'pg-test'
    redis-test: {...} # 组定义:'redis-test'
    # ...

conf/ 下有大量示例,在 configure 期间也可以用作模板。


集群

每个 ansible 组可能代表一个集群,可以是节点集群、PostgreSQL 集群、Redis 集群、Etcd 集群或 Minio 集群等…

集群定义由两部分组成:hostsvars。 您可以在 <cls>.hosts 中定义集群成员,并在 <cls>.vars 中使用参数描述集群。 这是一个 3 节点 HA PG 集群的示例:

all:
  children:    # 所有组
    pg-test:   # 组名
      hosts:   # 组主机(集群成员)
        10.10.10.11: { pg_seq: 1, pg_role: primary } # 主机 1
        10.10.10.12: { pg_seq: 2, pg_role: replica } # 主机 2
        10.10.10.13: { pg_seq: 3, pg_role: offline } # 主机 3
      vars:    # 组变量(集群参数)
        pg_cluster: pg-test

集群级别的 vars 将覆盖全局变量,主机级别的 vars 将覆盖集群变量和全局变量。


参数

参数是定义部署中所有实体的键值对。 键是字符串名称,值可以是五种类型之一:布尔值、字符串、数字、数组或对象。

参数可以在不同级别设置,具有以下优先级:

级别 位置 描述 优先级
CLI 参数 命令行 通过 -e CLI 参数 最高 (5)
主机变量 <group>.hosts.<host> 特定于单个主机的参数 高 (4)
组变量 <group>.vars 组/集群中主机共享的参数 中等 (3)
全局变量 all.vars 所有主机共享的参数 低 (2)
默认值 <roles>/default/main.yml 角色实现默认值 最低 (1)

以下是关于参数优先级的一些示例:

  • 使用 Playbook CLI 参数 -e pg_version=16 覆盖 PostgreSQL 主版本
  • 使用主机变量上的实例级别参数 pg_role 覆盖 pg 实例角色
  • 使用组变量上的集群级别参数 pg_cluster 覆盖 pg 集群名称。
  • 使用全局变量上的全局参数 node_ntp_servers 指定全局 NTP 服务器
  • 如果没有设置 pg_version,pigsty 将使用角色实现的默认值(默认为 18

除了强制性的 身份参数 外,每个参数都有一个适当的默认值;它们用作标识符,必须明确设置。 例如上述片段中的 pg_clusterpg_rolepg_seq

可用参数根据模块而异:


参考

Pigsty 有 290+ 个参数,查看模块参数了解详细信息。

模块 部分 描述 数量
INFRA META Pigsty 元数据 4
INFRA CA 自签名 CA 3
INFRA INFRA_ID 基础设施门户和身份 2
INFRA REPO 本地软件仓库 9
INFRA INFRA_PACKAGE 基础设施包 2
INFRA NGINX Nginx Web 服务器 7
INFRA DNS DNSMASQ 名称服务器 3
INFRA PROMETHEUS Prometheus 堆栈 18
INFRA GRAFANA Grafana 堆栈 6
INFRA LOKI Loki 日志服务 4
NODE NODE_ID 节点身份参数 5
NODE NODE_DNS 节点域名和解析器 6
NODE NODE_PACKAGE 节点仓库和包 5
NODE NODE_TUNE 节点调优和内核功能 10
NODE NODE_ADMIN 管理员用户和凭据 7
NODE NODE_TIME 节点时区、NTP、Crontabs 5
NODE NODE_VIP 节点 Keepalived L2 VIP 8
NODE HAPROXY HAProxy 负载均衡器 10
NODE NODE_EXPORTER 节点监控代理 3
NODE PROMTAIL Promtail 日志代理 4
DOCKER DOCKER Docker 守护进程 4
ETCD ETCD ETCD DCS 集群 10
MINIO MINIO MINIO S3 对象存储 15
REDIS REDIS Redis 键值 NoSQL 缓存 20
PGSQL PG_ID PG 身份参数 11
PGSQL PG_BUSINESS PG 业务对象定义 12
PGSQL PG_INSTALL 安装 PG 包和扩展 10
PGSQL PG_BOOTSTRAP 使用 Patroni 初始化 HA PG 集群 35
PGSQL PG_PROVISION 创建数据库内对象 9
PGSQL PG_BACKUP 使用 pgBackRest 设置备份仓库 5
PGSQL PG_ACCESS 暴露服务、绑定 VIP、DNS 16
PGSQL PG_MONITOR 收集 Postgres 的指标和日志 18
PGSQL PG_EXPORTER 移除 Postgres 集群 4

3.2 - 配置

如何配置 pigsty 清单文件?

configure 脚本将根据您的环境和输入生成具有良好默认值的 pigsty.yml 配置文件清单。 它是 可选的,您可以直接编辑 pigsty.yml,如教程所示。


用法

除非指定了 -n|--non-interactive,否则 configure 脚本是一个交互式向导。

~/pigsty/configure
./configure
    [-c|--conf <confname>   # [meta|dual|trio|full|app/supa|...]
    [-i|--ip <ip>]          # 主 IP 地址(使用 -s 跳过)
    [-v|--version <pgver>   # [18|17|16|15|14|13]
    [-r|--region <region>   # [default|china|europe]
    [-o|--output <file>]    # 输出配置文件(默认为 pigsty.yml)
    [-s|--skip]             # 跳过 IP 地址探测
    [-x|--proxy]            # 从环境变量写入代理环境
    [-n|--non-interactive]  # 非交互模式
    [-p|--port <port>]      # 指定 SSH 端口(仅在设置时使用)
选项 描述
-c|--conf 根据此参数从配置模板生成配置
-i|--ip 用给定 IP 替换 IP 地址占位符 10.10.10.10
-v|--version 指定 PostgreSQL 主版本号(13|14|15|16|17|18
-r|--region 根据 region 设置上游仓库镜像(default|china|europe
-o|--output 将生成的配置清单写入指定文件(默认为 pigsty.yml
-x|--proxy 将当前代理环境写入配置 proxy_env
-s|--skip 跳过交互式向导并使用默认/参数值
-n|--non-interactive 非交互模式
-p|--port 指定 SSH 端口(仅在设置时使用)

示例

./configure                # 如果只有一个 IP 地址,否则会要求您输入
./configure -i 10.11.12.13 # 明确告诉主 IP 地址
./configure -c rich -v 16  # 使用 conf/rich.yml 作为模板,使用 PG 16 和所有扩展
./configure -c app/supa    # 使用 app/supa 模板,运行自托管 supabase
./configure -c mssql       # 使用 babelfish 模板,运行 MSSQL 兼容的 PG 内核分支
./configure -c full -s     # 使用 4 节点沙箱配置模板,不进行 IP 替换和探测
./configure -r china       # 使用中国镜像而不是默认仓库

configure 输出示例:

./configure
[vagrant@node-1 pigsty]$ ./configure
configure pigsty v3.7.0 begin
[ OK ] region = china
[ OK ] kernel  = Linux
[ OK ] machine = x86_64
[ OK ] package = rpm,dnf
[ OK ] vendor  = rocky (Rocky Linux)
[ OK ] version = 9 (9.6)
[ OK ] sudo = vagrant ok
[ OK ] ssh = [email protected] ok
[WARN] Multiple IP address candidates found:
    (1) 192.168.121.193	    inet 192.168.121.193/24 brd 192.168.121.255 scope global dynamic noprefixroute eth0
    (2) 10.10.10.11	    inet 10.10.10.11/24 brd 10.10.10.255 scope global noprefixroute eth1
[ IN ] INPUT primary_ip address (of current meta node, e.g 10.10.10.10):
=> 10.10.10.11
[ OK ] primary_ip = 10.10.10.11 (from input)
[ OK ] admin = [email protected] ok
[ OK ] mode = meta (el9)
[ OK ] locale  = C.UTF-8
[ OK ] configure pigsty done
proceed with ./install.yml

行为

配置模板

如果指定了 -c|--conf <template>,它将从指定的模板生成配置文件。例如 metaapp/supa 等… 如果没有给出配置模板,它将使用默认的单节点配置模板 meta

IP 地址

如果指定了 -i|--ip <ipaddr>,它将用给定的 IP 地址替换配置模板中的占位符 10.10.10.10。 否则,如果当前节点只有一个 IP 地址,将使用该地址。如果有多个 IP 地址,它会要求您手动输入当前节点的主 IP 地址。

PostgreSQL 版本

如果指定了 -v|--version,它将使用指定的 PostgreSQL 主版本号,范围从 1318。 如果没有指定版本,它会保持 pg_version 不变,通常默认回退到 18

区域

如果指定了 -r|--region,它将直接使用指定的区域。在无法访问 Google 服务的地方将使用 china 镜像。

代理环境

如果指定了 -x|--proxy,它将把当前代理环境变量写入配置 proxy_env。 在安装期间将被重用。包括:HTTP_PROXYHTTPS_PROXYALL_PROXYNO_PROXY

跳过模式

如果指定了 -s|--skip,它将跳过 IP 地址替换和 ssh sudo 权限检查

非交互模式

如果指定了 -n|--non-interactive,此脚本不会询问您任何事情,但您必须使用 -i|--ip <ipaddr> 明确指定主 IP 地址。

SSH 端口

如果指定了 -p|--port,它将使用指定的 SSH 端口而不是默认的 22。 当您的本地 SSH 端口不是 22 时使用。

低端硬件优化

如果当前节点 CPU 核心数 ≤ 4,它将对 pg_confnode_tune 使用 tiny 模式以优化低端硬件。

区域设置

Pigsty 将使用 C.UTF-8 作为默认区域设置,如果:

  • PostgreSQL 主版本 ≥ 17,具有内置本地提供程序(默认)
  • 或者,您的系统支持 C.utf8 / C.utf-8 区域设置(locale -a

否则,默认将使用本地 C

3.3 - 教程

从零开始打造复杂配置

您可以手动从零开始编写 pigsty 配置文件,而不是使用 configure 生成配置。

这里是一个教程,帮助您从零开始构建复杂的配置文件清单


最小配置

这是一个最小的工作配置示例,您必须告诉 pigsty 管理节点和基础设施节点的 IP。

~/pigsty/pigsty.yml
all:
  children: {infra: {hosts: {10.10.10.10: { infra_seq: 1 }}}}
  vars: { admin_ip: 10.10.10.10 }

这将在 10.10.10.10(更改为您的 IP 地址)上安装 INFRANODE 模块。

~/pigsty
./install.yml

您将拥有一个完整的可观测性堆栈和节点监控。但数据库服务尚未运行。


PGSQL & ETCD

要提供 PostgreSQL 服务,您必须定义其他组并安装 PGSQLETCD 模块。

~/pigsty/pigsty.yml
all:
  children:
    infra:   { hosts: { 10.10.10.10: { infra_seq: 1 } } }
    etcd:    { hosts: { 10.10.10.10: { etcd_seq: 1 } }, vars: { etcd_cluster: etcd } }
    pg-meta: { hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }, vars: { pg_cluster: pg-meta } }
  vars:
    admin_ip: 10.10.10.10

我们在这里添加了两个新组:etcdpg-meta,它们定义了一个 1 节点 ETCD 集群和一个 1 节点 PGSQL 集群。 使用 ./install.yml 重新创建所有内容,或使用这些命令进行增量步骤:

~/pigsty
./etcd.yml  -l etcd      # 在 etcd 组上安装 etcd 模块
./pgsql.yml -l pg-meta   # 在 pg-meta 组上安装 pgsql 模块

PGSQL 模块依赖 ETCD 进行 HA 共识,因此请确保首先安装 ETCD 模块。


数据库和用户

现在我们要自定义我们的 postgres 数据库集群,包括用户、数据库和备份:

~/pigsty/pigsty.yml
all:
  children:
    infra:   { hosts: { 10.10.10.10: { infra_seq: 1 } } }
    etcd:    { hosts: { 10.10.10.10: { etcd_seq: 1 } }, vars: { etcd_cluster: etcd } }
    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: admin user}
        pg_databases:
          - { name: meta ,baseline: cmdb.sql ,comment: pigsty meta database ,schemas: [pigsty] ,extensions: [vector]}
        node_crontab:
          - '00 01 * * * postgres /pg/bin/pg-backup full'
  vars:
    admin_ip: 10.10.10.10

我们在 pg-meta 集群级别定义一些额外的详细信息:

  • pg_users:定义一个新用户 dbuser_meta,密码为 DBUser.Meta
  • pg_databases:定义一个新数据库 meta,包含 pigsty CMDB 模式和 vector 扩展
  • node_crontab:定义在每天凌晨 1 点进行完整备份的 crontab

我们不使用 ./install.yml 重新创建所有内容,而是增量地进行更改:

~/pigsty
bin/pgsql-user pg-meta dbuser_meta      # 在 pg-meta 上创建用户 dbuser_meta
bin/pgsql-db   pg-meta meta             # 在 pg-meta 上创建数据库 meta
./node.yml -l pg-meta -t node_crontab   # 在 pg-meta 上将备份任务添加到 crontab

PG 版本和扩展

您可以安装不同的 PostgreSQL 主版本,以及 437 相应的扩展。

让我们安装 PostgreSQL 16(而不是默认的 18),包含 timescaledbpostgispgvector 扩展。

~/pigsty/pigsty.yml
all:
  children:
    infra:   { hosts: { 10.10.10.10: { infra_seq: 1 } } }
    etcd:    { hosts: { 10.10.10.10: { etcd_seq: 1 } }, vars: { etcd_cluster: etcd } }
    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
        pg_databases:
          - name: meta
            baseline: cmdb.sql
            comment: pigsty meta database
            schemas: [pigsty]
            extensions: [ vector, postgis, timescaledb ]           # <--- 创建扩展
        pg_libs: 'timescaledb, pg_stat_statements, auto_explain'   # <--- 加载扩展
        node_crontab:
          - '00 01 * * * postgres /pg/bin/pg-backup full'
  vars:
    admin_ip: 10.10.10.10
    region: default # 使用本地镜像以获得更快的下载速度   # <--- default|china|europe
    repo_extra_packages: [ timescaledb, postgis, pgvector, pgsql ] # <--- 下载扩展
    pg_extensions:       [ timescaledb, postgis, pgvector ]        # <--- 安装扩展
    pg_version: 16   # PG 17 是默认的最新主版本   # <--- 使用 PG 16 版本
  • repo_extra_packages:下载 timescaledbpostgis 扩展。
  • pg_libs:预加载 timescaledbpg_stat_statementsauto_explain 扩展。

让我们重新下载缺失的包(PG 16 内核和扩展),删除旧集群,并重新创建它:

make repo                   # 重新下载包
./pgsql-rm.yml -l pg-meta   # 删除旧的 pg-meta 集群(因为它是 PG18)
./pgsql.yml    -l pg-meta   # 使用 PG16 和扩展重新创建 pg-meta 集群

更多节点

我们可以向此部署添加 3 个更多节点。

bin/node-add pg-test

或者逐个添加它们:

bin/node-add 10.10.10.11
bin/node-add 10.10.10.12
bin/node-add 10.10.10.13

PGSQL HA

现在我们要添加一个新的数据库集群 pg-test,具有 3 节点 HA 设置:

~/pigsty/pigsty.yml
all:
  children:
    infra:   { hosts: { 10.10.10.10: { infra_seq: 1 } } }
    etcd:    { hosts: { 10.10.10.10: { etcd_seq: 1 } }, vars: { etcd_cluster: etcd } }
    pg-meta: { hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }, vars: { pg_cluster: pg-meta } }
    pg-test:
      hosts:
        10.10.10.11: { pg_seq: 1, pg_role: primary }
        10.10.10.12: { pg_seq: 2, pg_role: replica  }
        10.10.10.13: { pg_seq: 3, pg_role: replica  }
      vars: { pg_cluster: pg-test }
  vars:
    admin_ip: 10.10.10.10

Pigsty 的工作假设是每个节点上只有一个 postgres 实例。 不支持在单个节点上运行多个 postgres 实例。


Redis 启动

Pigsty 有可选的 Redis 支持,用作 PostgreSQL 前面的缓存。

bin/redis-add redis-ms
bin/redis-add redis-meta
bin/redis-add redis-test

Redis HA 设置需要集群模式或哨兵基础设施,请查看 Redis 配置了解详情。


MinIO 启动

Pigsty 有可选的 MinIO 支持,用作 PostgreSQL 的备份存储。

./minio.yml -l minio

严肃的生产 MinIO 部署通常需要至少 4 个节点,每个节点有 4 个磁盘(4N/16D)


Docker 启动

infra 组上安装 docker:

./docker.yml -l infra

运行 PgAdmin

查看 App: Pgadmin 了解如何使用 Pigsty 运行 pgAdmin 的详细信息。简短版本:

./docker.yml -l infra
./app.yml    -l infra -e app=pgadmin

自托管 Supabase

查看 App: Supabase 了解如何使用 Pigsty 运行 Supabase 的详细信息。简短版本:

./configure -c app/supa
./install.yml
./docker.yml
./app.yml

3.4 - 模板

Pigsty 的配置模板

这个目录 conf 包含 pigsty 配置模板,将在 configure 过程中使用。

配置模板可以使用 ./configure -c <conf> 指定,其中 conf 是到 conf 目录的相对路径(有或没有 .yml 后缀)。 例如 ~/pigsty/conf/rich.yml 可以指定为 rich

./configure                     # 默认使用 meta.yml 配置模板
./configure -c meta             # 明确使用 meta.yml 1 节点模板
./configure -c rich             # 使用包含所有扩展和 minio 的 1 节点模板
./configure -c slim             # 使用最小的 1 节点模板
./configure -c supabase         # 使用 Supabase 自建模板
./configure -c app/dify         # 使用 dify 1 节点模板

如果没有给出 -c|--conf,默认会自动选择单节点 meta 配置模板。


基本模板

这里是单节点模板,提供不同的功能和配置。

模板 节点 描述
meta.yml 1 默认 1 节点配置,pgsql、infra、node、etcd,最小扩展
rich.yml 1 meta + minio + 所有扩展
slim.yml 1 meta - infra - node 监控,最小安装
fat.yml 1 下载PG13-18 所有包,安装全部扩展

异种内核

使用异种 Postgres 内核分支:

模板 节点 描述
mssql.yml 1 WiltonDB 和 Babelfish,具有 MSSQL 协议兼容性
polar.yml 1 PolarDB for PostgreSQL,具有 Aurora RAC 特性
ivory.yml 1 IvorySQL 集群,具有 Oracle 兼容性
mysql.yml 1 Halo 集群,具有 MySQL 协议兼容性
mongo.yml 1 FerretDB 和 DocumentDB,具有 Mongo 协议兼容性
oriole.yml 1 OrioleDB 集群,具有 OLTP 增强

多节点

模板 节点 描述
dual.yml 2 半高可用部署
trio.yml 3 标准高可用部署
full.yml 4 沙箱部署
safe.yml 4 带延迟副本的安全增强
simu.yml 36 生产模拟

应用程序

模板 描述
app/supa.yml 启动 1 节点 supabase
app/odoo.yml 启动 odoo ERP 系统
app/dify.yml 启动 dify AI 工作流系统
app/electric.yml 启动 electric 同步引擎应用

演示模板

模板 描述
demo/el.yml EL 8/9 系统的包含所有默认参数的配置文件
demo/debian.yml debian/ubuntu 系统的包含所有默认参数的配置文件
demo/remote.yml 监控远程 pgsql 集群或 RDS PG 的示例配置
demo/redis.yml redis 集群的示例配置
demo/minio.yml 3 节点 minio 集群的示例配置
demo/demo.yml pigsty 公共演示 的配置文件
citus.yml Citus 集群示例:1 个协调器和 3 个数据节点(4 节点)

构建模板

模板 描述
build/oss.yml EL 8、9、Debian 12 和 Ubuntu 22.04/24.04 OSS 的构建配置
build/pro.yml EL 7-9、Ubuntu、Debian pro 版本的构建配置

3.5 - 安全

安全考虑和最佳实践

Pigsty 已经提供了一个默认安全的数据库身份验证访问控制模型。

只要您遵循以下安全最佳实践,它对大多数常见场景来说都足够强大。


机密性

文件

保护您的 pigsty 配置文件
  • pigsty.yml 包含非常敏感的信息,如密码
  • 限制只有管理员/DBA 用户才能访问管理员/基础设施节点
  • 如果您使用 GitOps 管理 pigsty 配置,请限制对仓库的访问
保护您的 CA 私钥
  • 默认生成在 ~/pigsty/files/pki/ca/ca.key
  • 在安全的地方备份它,不要丢弃它!
  • 还要考虑保护各种证书的其他私钥

密码

不要使用默认密码

在严肃的部署中,始终更改这些默认密码

更改 MinIO 凭据和 pgbackrest 引用

如果您使用 MinIO 作为备份存储,还要更改这些凭据:

使用 passwordcheck 扩展强制使用强密码
  • $lib/passwordcheck 添加到 pg_libs 以强制执行密码策略。
  • 更强版本:passwordcheck_cracklib
使用加密算法加密远程备份
  • 检查 pgbackrest_repo 定义 repo_cipher_type
  • 默认为 cipher_type: aes-256-cbc
为 PostgreSQL 使用高级密码加密方法
  • 使用 pg_pwd_enc 默认 scram-sha-256 而不是传统的 md5
  • 默认行为是 scram-sha-256md5 已被弃用
为业务用户密码添加过期日期

为了合规目的,您可以为每个用户设置过期日期。

- { name: dbuser_meta , password: Pleas3-ChangeThisPwd ,expire_in: 7300 ,pgbouncer: true ,roles: [ dbrole_admin ]    ,comment: pigsty admin user }
- { name: dbuser_view , password: Make.3ure-Compl1ance  ,expire_in: 7300 ,pgbouncer: true ,roles: [ dbrole_readonly ] ,comment: read-only viewer for meta database }
- { name: postgres     ,superuser: true  ,expire_in: 7300                        ,comment: system superuser }
- { name: replicator ,replication: true  ,expire_in: 7300 ,roles: [pg_monitor, dbrole_readonly]   ,comment: system replicator }
- { name: dbuser_dba   ,superuser: true  ,expire_in: 7300 ,roles: [dbrole_admin]  ,pgbouncer: true ,pool_mode: session, pool_connlimit: 16 , comment: pgsql admin user }
- { name: dbuser_monitor ,roles: [pg_monitor] ,expire_in: 7300 ,pgbouncer: true ,parameters: {log_min_duration_statement: 1000 } ,pool_mode: session ,pool_connlimit: 8 ,comment: pgsql monitor user }

不要忘记使用 pgsql-user.yml playbook 定期刷新这些过期日期

不要将密码打印到日志
SET log_statement TO 'none';
ALTER USER "{{ user.name }}" PASSWORD '{{ user.password }}';
SET log_statement TO DEFAULT;

IP 地址

为 postgres/pgbouncer/patroni 绑定特定 IP 地址
  • 默认的 pg_listen 地址是 0.0.0.0,即所有 IPv4 地址。
  • 考虑使用 pg_listen: '${ip},${vip},${lo}' 绑定到特定地址以获得更好的安全性。
不要将任何端口暴露到互联网;除了 80/443,基础设施门户
  • Grafana/Prometheus 默认绑定到所有 IP 地址以便于使用。
  • 您可以修改它们的绑定配置,使其监听 localhost/内网 IP 并通过 Nginx 暴露。
  • Redis 服务器默认绑定到所有 IP 地址以便于使用。您可以更改 redis_bind_address 以监听内网 IP。
  • 您也可以通过安全组或防火墙规则来实现。
使用 HBA 限制 postgres 客户端访问
  • 有一个安全增强配置模板:safe.yml
限制从基础设施/管理节点访问 patroni 管理

网络流量

使用 SSL 和域名访问 Nginx
使用 SSL 保护 Patroni REST API
  • patroni_ssl_enabled 默认禁用
  • 因为它会影响健康检查和 API 调用。
  • 注意这是一个全局选项,您必须在部署前决定。
使用 SSL 保护 Pgbouncer 客户端流量

完整性

一致性

为 PostgreSQL 使用一致性优先模式
  • 使用 crit.yml 模板为 pg_conf 将牺牲一些可用性以获得最佳一致性。
使用节点关键调整模板以获得更好的一致性
  • node_tune 设置为 crit 以减少脏页比率。

  • 启用数据校验和以检测静默数据损坏。

  • pg_checksum 在 v3.7.0 中默认启用

  • 这可以稍后启用,但需要完整的集群扫描/停止。

审计

启用连接日志进行审计
  • 在 pg 集群引导后启用 log_connectionslog_disconnections
  • 审计传入会话;这在 crit.yml 中默认启用。

误操作

不要重新运行 install.yml playbook

再次运行 install.yml 将销毁(覆盖)整个部署!

谨慎重新运行 pgsql.yml

在 v3.5 之前,它默认会覆盖现有的 PostgreSQL。

使用 pg_safeguard 避免误操作


可用性

冗余

为严肃的生产部署使用足够的节点
  • 您需要至少三个节点(容忍一个节点故障)才能实现生产级高可用性。
  • 如果您只有两个节点,您可以容忍特定备用节点的故障。
  • 如果您有一个节点,请使用外部 S3/MinIO 进行冷备份和 wal 归档存储。
在严肃的生产部署中使用多个基础设施节点
  • 在严肃的生产部署中使用多个基础设施节点(例如,1~3)
  • 通常,2 ~ 3 对于大型生产部署来说是足够的。
使用足够的 etcd 成员并使用奇数
  • 使用足够的 etcd 成员并使用奇数(1,3,5,7)。
  • 查看 ETCD 配置 了解详情。

容错

为 PostgreSQL 在可用性和一致性之间进行权衡
  • pg_rpo可用性和一致性之间的权衡
  • pg_rto故障概率和影响之间的权衡

访问

使用 VIP、DNS、HAProxy 而不是固定 IP
  • 不要通过固定 IP 地址直接访问数据库;使用 VIP、DNS、HAProxy 或它们的组合。
  • Haproxy 将在故障转移/切换时为客户端处理流量控制。

3.6 - CMDB

使用 PostgreSQL 作为配置清单

Pigsty 允许您使用 数据库(CMDB) 作为动态配置源,而不是静态配置文件。 您可以使用内置的 PostgreSQL 作为配置清单进行配置管理。

使用 Postgres CMDB,配置被组织在结构化关系表中,可以使用 SQL 轻松查询和操作。 这允许与其他系统和工具更容易地集成。


工作原理

Ansible 允许您使用动态清单脚本来即时生成清单配置。

其想法是在 ansible.cfg 中用动态 shell 脚本 inventory.sh 替换静态 pigsty.yml

~/pigsty/ansible.cfg
---
inventory = pigsty.yml
+++
inventory = inventory.sh

inventory.sh 的内容非常简单,它将查询 PostgreSQL CMDB 并检索配置。

~/pigsty/inventory.sh
psql ${METADB_URL} -AXtwc 'SELECT text FROM pigsty.inventory;'
CMDB 实用脚本

CMDB 模式

CMDB 基线模式随 pigsty 一起提供:files/cmdb.sql 大多数默认配置模板都将其用作示例基线。这意味着默认情况下可以使用它。

all:
  children:
    pg-meta:
      hosts:
        10.10.10.10: { pg_seq: 1, pg_role: primary }
      vars:
        pg_cluster: pg-meta
        pg_databases:
          - name: meta
            baseline: cmdb.sql  # <--- 使用它作为数据库模式基线

加载配置数据

CMDB 默认为空,使用 bin/inventory_load 脚本将配置文件加载到 CMDB 中。

不带参数运行 bin/inventory_load 将加载默认的 pigsty.yml 到默认 CMDB 中。

usage: inventory_load [-h] [-p PATH] [-d CMDB_URL]

load config arguments

optional arguments:
  -h, --help            show this help message and exit
  -p PATH, --path PATH  config path, ${PIGSTY_HOME}/pigsty.yml by default
  -d DATA, --data DATA  postgres cmdb pgurl, ${METADB_URL} by default

使用 -p 指定配置文件路径,使用 -d 指定 CMDB URL。

bin/inventory_load
bin/inventory_load -p conf/demo.yml
bin/inventory_load -p conf/ha/full.yml -d postgresql://dbuser_meta:[email protected]:5432/meta

切换清单

您可以通过以下方式切换到动态 CMDB 清单:

bin/inventory_cmdb

这实际上将 ansible.cfg 中的 inventory 参数更改为使用 inventory.sh 脚本。

4 - 管理

管理您的部署
Ansible
    使用 ansible 运行管理命令
剧本
    Pigsty 中的内置剧本
仪表板
    grafana 仪表板介绍
监控
    prometheus 和 alertmanager 介绍

Nginx 门户
    WebUI 服务的 Nginx 门户
本地仓库
    管理本地 APT / YUM 仓库
域名
    使用本地 / 公共域名
CA 和证书
    使用自签名或真实 HTTPS 证书

PGSQL
    具有 HA、PITR、IaC、ACL、监控、连接池的 PostgreSQL 集群
INFRA
    用于可观测性的 Nginx、本地仓库、DNS、NTP、可观测性技术栈
NODE
    将节点注册到期望状态并监控它,以及 VIP、HAProxy
ETCD
    可靠的分布式共识存储 (DCS),为 PGSQL HA 提供支持
MINIO
    兼容 S3 的对象存储,可选备份存储
REDIS
    高性能内存缓存,可选数据结构服务器

4.1 - Ansible

开始学习基本的 ansible 概念

Pigsty 使用 Ansible 实现管理控制器,这是一个开源自动化工具,用于以基础设施即代码(IaC)的方式管理大规模基础设施。 被运维人员广泛使用。


安装

Pigsty 将在引导期间尽力安装 ansible 及其依赖项。 但您始终可以手动安装它,它在大多数操作系统的官方仓库中都可用,如果使用 Pigsty,则可以用以下命令安装。

安装 Ansible

Playbooks 还需要一个弱依赖:jmespath python 包。

cd ~/pigsty; ./bootstrap
sudo apt install -y ansible python3-jmespath
sudo dnf install -y ansible python-jmespath
sudo dnf install -y ansible python3.12-jmespath
sudo yum install -y ansible python-jmespath
brew install ansible
pip3 install jmespath

请注意,目前 EL10 EPEL 仓库尚未提供完整的 Ansible 包,Pigsty PGSQL EL10 仓库中补充了这个包。

macOS

Ansible 在 macOS 上也可用。您可以使用 Homebrew 在 Mac 上安装 Ansible。 并将其用作管理节点来管理远程云服务器。 如果您在云 VPS 上部署单节点 pigsty,这很方便。但不建议在生产环境中使用。


基础知识

了解 Ansible 知识有助于使用,但 并非必须。您只需要知道如何运行 Ansible 剧本 即可。 剧本(Playbook)是包含要执行的一系列任务的可执行 YAML 文件。

运行 ./node.yml playbook 本质上是执行 ansible-playbook node.yml 命令。剧本顶部的 hashbang 使其可直接执行。 您可以使用一些参数来精细控制剧本的执行:

~/pigsty
./node.yml                         # 在所有主机上运行 node 剧本
./pgsql.yml -l pg-test             # 在 pg-test 集群上运行 pgsql 剧本
./infra.yml -t repo                # 运行 infra.yml 的子任务 repo
./pgsql-rm.yml -e pg_rm_pkg=false  # 删除 pgsql,但保留包

以下 4 个参数 需要您注意,以便有效使用 ansible:

目的 参数 描述
对象 -l|--limit <pattern> 限制在特定组/主机/模式上的执行目标
任务 -t|--tags <tags> 只运行具有特定标签的任务
参数 -e|--extra-vars <vars> 额外的命令行参数
配置 -i|--inventory <path> 使用特定的清单文件

限制主机

playbook 的执行目标可以通过 -l|--limit <selector> 限制。 当尝试在特定主机/节点或组/集群上运行 playbooks 时,这很方便。 以下是主机限制的一些示例:

./pgsql.yml                              # 在所有主机上运行(危险!)
./pgsql.yml -l pg-test                   # 在 pg-test 集群上运行
./pgsql.yml -l 10.10.10.10               # 在单个主机 10.10.10.10 上运行
./pgsql.yml -l pg-*                      # 在匹配 glob 模式 `pg-*` 的主机/组上运行
./pgsql.yml -l '10.10.10.11,&pg-test'    # 在 pg-test 组的 10.10.10.11 上运行
./pgsql-rm.yml -l 'pg-test,!10.10.10.11' # 在 pg-test 上运行,除了 10.10.10.11
./pgsql.yml -l pg-test                   # 对 pg-test 集群中的主机执行 pgsql playbook

查看 ansible 文档中的所有详细信息:Patterns: targeting hosts and groups

在没有主机限制的情况下运行 playbook 可能很危险!

缺少这个值可能很危险,因为大多数 playbooks 将在 all 主机上执行。请谨慎使用


限制任务

执行任务可以通过 -t|--tags <tags> 控制。 如果指定,将执行具有给定标签的任务,而不是整个 playbook。 以下是一些任务限制示例:

./infra.yml -t repo          # 创建仓库
./node.yml  -t node_pkg      # 安装节点包
./pgsql.yml -t pg_install    # 安装 pg 包和扩展
./etcd.yml  -t etcd_purge    # 销毁 etcd 集群
./minio.yml -t minio_alias   # 写入 minio cli 配置

要运行多个任务,指定多个标签并用逗号分隔:-t tag1,tag2

./node.yml  -t node_repo,node_pkg   # 添加仓库,然后安装包
./pgsql.yml -t pg_hba,pg_reload     # 配置,然后重新加载 pg hba 规则

额外变量

您可以使用 cli 参数在运行时覆盖配置参数,它具有最高优先级

额外的命令行参数可以通过 -e|--extra-vars KEY=VALUE 传递,可以多次使用:

# 使用另一个管理员用户创建管理员
./node.yml -e ansible_user=admin -k -K -t node_admin

# 初始化一个特定的 redis 实例:10.10.10.11:6379
./redis.yml -l 10.10.10.10 -e redis_port=6379 -t redis

# 删除 postgres,但保留包和数据
./pgsql-rm.yml -e pg_rm_pkg=false -e pg_rm_data=false

对于复杂参数,可以使用 JSON 字符串:

# 添加仓库并安装包
./node.yml -t node_install -e '{"node_repo_modules":"infra","node_packages":["duckdb"]}'

指定清单

默认配置文件是 pigsty 主目录中的 pigsty.yml

您可以使用 -i <path> 参数指定不同的清单文件路径。

./pgsql.yml -i conf/rich.yml            # 根据 rich 配置初始化一个下载了所有扩展的单节点
./pgsql.yml -i conf/ha/full.yml            # 根据 full 配置初始化一个 4 节点集群
./pgsql.yml -i conf/app/supa.yml        # 根据 supa.yml 配置初始化一个 1 节点 Supabase 部署
更改默认清单文件

要永久更改默认配置文件,请更改 ansible.cfg 中的 inventory 参数。

4.2 - 剧本

使用 ansible 运行 playbooks,Pigsty 中的剧本列表与说明

Pigsty 使用幂等的 Ansible playbooks 实现管理控制器。 Playbooks 需要您的 PATH 中有 ansible-playbook 可执行文件。您必须安装 ansible 才能运行 playbooks。

这里是 Pigsty 中的内置 playbooks,您也可以添加自己的。

模块 Playbook 功能
INFRA install.yml 在当前节点上一键安装 Pigsty
INFRA infra.yml 在基础设施节点上初始化 pigsty 基础设施
INFRA infra-rm.yml 从基础设施节点移除基础设施组件
INFRA cache.yml 从目标节点制作离线安装包
INFRA cert.yml 使用 pigsty 自签名 CA 颁发证书(例如用于 pg 客户端)
NODE node.yml 为 pigsty 初始化节点,将节点调整到所需状态
NODE node-rm.yml 从 pigsty 移除节点
PGSQL pgsql.yml 初始化 HA PostgreSQL 集群,或添加新副本
PGSQL pgsql-rm.yml 移除 PostgreSQL 集群,或移除副本
PGSQL pgsql-db.yml 向现有 PostgreSQL 集群添加新业务数据库
PGSQL pgsql-user.yml 向现有 PostgreSQL 集群添加新业务用户
PGSQL pgsql-pitr.yml 在现有 PostgreSQL 集群上执行时间点恢复
PGSQL pgsql-monitor.yml 使用本地导出器监控远程 postgres 实例
PGSQL pgsql-migration.yml 为现有 PostgreSQL 生成迁移手册和脚本
PGSQL slim.yml 安装最小组件的 Pigsty
REDIS redis.yml 初始化 redis 集群/节点/实例
REDIS redis-rm.yml 移除 redis 集群/节点/实例
ETCD etcd.yml 初始化 etcd 集群,或扩容新成员
ETCD etcd-rm.yml 移除 etcd 集群与数据,或移除现有成员缩容
MINIO minio.yml 初始化 minio 集群(pgbackrest 仓库可选)
MINIO minio.yml 移除 minio 集群与数据
DOCKER docker.yml 在节点上安装 docker
DOCKER app.yml 使用 docker compose 安装应用程序
FERRET mongo.yml 在节点上安装 Mongo/FerretDB

部署

特殊的 playbook install.yml 将使用临时 playbooks 部署所有内容:

Playbook 命令 分组 infra [nodes] etcd minio [pgsql]
infra.yml ./infra.yml -l infra
node.yml ./node.yml
etcd.yml ./etcd.yml -l etcd
minio.yml ./minio.yml -l minio
pgsql.yml ./pgsql.yml

4.3 - Nginx 入口

配置基础设施门户和 nginx 设置

Pigsty 在基础设施节点上安装 Nginx 作为 Web 服务代理,默认使用端口 80/443。 全局参数 infra_portal 配置 Nginx 代理规则和上游服务。


Nginx 服务器配置通过 infra_portal 参数指定。用户声明要通过 Nginx 代理的所有域名,以及相应的上游服务器端点或本地目录路径。

基本示例

infra_portal:  # 域名和上游服务器
  home         : { domain: h.pigsty }
  grafana      : { domain: g.pigsty, endpoint: "${admin_ip}:3000", websocket: true }
  prometheus   : { domain: p.pigsty, endpoint: "${admin_ip}:9058" }
  alertmanager : { domain: a.pigsty, endpoint: "${admin_ip}:9059" }
  blackbox     : { endpoint: "${admin_ip}:9115" }
  loki         : { endpoint: "${admin_ip}:3100" }

复杂示例

infra_portal:
  home         : { domain: home.pigsty.cc }
  grafana      : { domain: g.pgsty.com, endpoint: "${admin_ip}:3000", websocket: true }
  cc           : { domain: pigsty.cc, path: "/www/pigsty.cc" }
  en           : { domain: pigsty.io, path: "/www/pigsty.io" }
  prometheus   : { domain: p.pigsty.cc, endpoint: "${admin_ip}:9058" }
  alertmanager : { domain: a.pigsty.cc, endpoint: "${admin_ip}:9059" }
  minio        : { domain: s3.pigsty.cc, endpoint: "${admin_ip}:9001", websocket: true }
  jupyter      : { domain: lab.pigsty.cc, endpoint: "${admin_ip}:8888", websocket: true }
  repo         : { domain: repo.pigsty.cc, path: "/www/repo", index: true }
  wiki         : { domain: wiki.pigsty.cc, endpoint: "${admin_ip}:9002" }
  noco         : { domain: noco.pigsty.cc, endpoint: "${admin_ip}:8080" }
  supa         : { domain: supa.pigsty.cc, endpoint: "${admin_ip}:3001" }
  dify         : { domain: dify.pigsty.cc, endpoint: "${admin_ip}:8001" }
  pg1          : { domain: pg1.pigsty.cc, endpoint: "10.10.10.11:5432", scheme: tcp }
  pg2          : { domain: pg2.pigsty.cc, endpoint: "10.10.10.12:5432", scheme: tcp }
  pg3          : { domain: pg3.pigsty.cc, endpoint: "10.10.10.13:5432", scheme: tcp }

Playbook 配置

可以使用 Ansible playbook 重新配置 Nginx:

./infra.yml -t nginx           # 完全重新配置 Nginx
./infra.yml -t nginx_config    # 重新生成 Nginx 配置文件
./infra.yml -t nginx_launch    # 重启 Nginx 服务
./infra.yml -t nginx_cert      # 重新生成 SSL 证书

服务器

infra_portal 中的每个服务器记录支持以下配置选项:

核心参数

  • domain - 可选的代理域名
  • endpoint - 上游服务地址(IP:PORT 或套接字路径)
  • path - 静态内容的本地 Web 服务器根目录
  • scheme - 协议规范(http/https/tcp/udp)

SSL/TLS 参数

  • certbot - 启用 Let’s Encrypt 证书管理
  • cert - 自定义 SSL 证书文件路径
  • key - 自定义 SSL 私钥文件路径

高级参数

  • conf - 自定义 Nginx 配置模板
  • domains - 服务的附加域名
  • index - 为静态内容启用目录列表
  • log - 自定义日志文件配置
  • websocket - 为实时应用启用 WebSocket 支持

参数使用示例

# 带目录列表的静态文件服务
repo: { domain: repo.pigsty.cc, path: "/www/repo", index: true }

# 启用 WebSocket 的服务
grafana: { domain: g.pigsty.cc, endpoint: "${admin_ip}:3000", websocket: true }

# 自定义 SSL 证书
secure_app: {
  domain: secure.pigsty.cc,
  endpoint: "${admin_ip}:8443",
  cert: "/etc/ssl/certs/custom.crt",
  key: "/etc/ssl/private/custom.key"
}

# Let's Encrypt 管理的证书
public_api: { domain: api.pigsty.cc, endpoint: "${admin_ip}:8080", certbot: true }

# TCP 流代理
pg_primary: { domain: pg.pigsty.cc, endpoint: "10.10.10.11:5432", scheme: tcp }

使用域名

DNS 解析方法

  1. 公共互联网域名 通过 DNS 提供商
  2. 内部网络 DNS 服务器
  3. 本地 /etc/hosts 文件修改

对于本地开发和测试,请在您的 /etc/hosts 文件中添加条目:

# 添加到 /etc/hosts
<your_public_ip_address> h.pigsty g.pigsty p.pigsty a.pigsty

<your_public_ip_address> 替换为您的实际管理节点 IP 地址。

HTTPS 配置

通过 nginx_sslmode 参数配置 HTTPS 访问,支持以下选项:

  • disabled - 仅 HTTP,无 SSL
  • self-signed - 使用自签名证书(默认)
  • provided - 使用提供的证书
  • letsencrypt - 使用 Let’s Encrypt 证书

证书管理

./infra.yml -t nginx_cert      # 重新生成 SSL 证书

HTTPS 访问方法

对于自签名证书,您可以:

  • 在浏览器中信任自签名 CA
  • 使用浏览器安全绕过选项(在 Chrome 中输入 thisisunsafe
  • 为生产环境配置适当的 CA 签名证书

服务访问示例

使用默认配置,服务可通过以下方式访问:

  • 主页http://h.pigstyhttps://h.pigsty
  • Grafana 仪表板http://g.pigstyhttps://g.pigsty
  • Prometheus 指标http://p.pigstyhttps://p.pigsty
  • Alertmanagerhttp://a.pigstyhttps://a.pigsty

最佳实践

  1. 使用域名 访问服务,而不是直接使用 IP:PORT
  2. 配置 DNS 解析 或适当更新本地 hosts 文件
  3. 为需要的服务启用 WebSocket 支持(如 Grafana、Jupyter)
  4. 在生产环境中使用 HTTPS 并配置适当的证书
  5. 合理组织服务 使用有意义的子域名命名
  6. 监控 Let’s Encrypt 证书过期时间
  7. 通过 Nginx 集中管理 Web 服务代理 以获得更好的管理体验
  8. 使用静态文件服务 用于文档和仓库浏览

4.4 - 本地软件源

配置本地 APT / YUM 软件仓库

快速开始

如果您想向本地仓库添加一些包,请将它们添加到:

然后运行 make repo 快捷方式来更新本地仓库和节点仓库缓存:

make repo
./infra.yml -t repo_build
./node.yml -t node_repo

使用别名

您可以使用别名来指定一组包,查看 roles/node_id/vars/<os>.<arch>.yml 了解可用的别名:

EL

node-bootstrap: "ansible python3 python3-pip python3-virtualenv python3-requests python3-jmespath python3-cryptography dnf-utils modulemd-tools createrepo_c sshpass"
infra-package:  "nginx dnsmasq etcd haproxy vip-manager node_exporter keepalived_exporter pg_exporter pgbackrest_exporter redis_exporter redis minio mcli pig"
infra-addons:   "grafana grafana-plugins loki logcli promtail prometheus alertmanager pushgateway blackbox_exporter nginx_exporter pev2 certbot python3-certbot-nginx"
extra-modules:  "docker-ce docker-compose-plugin ferretdb2 duckdb restic juicefs vray grafana-infinity-ds"
node-package1:  "lz4 unzip bzip2 zlib yum pv jq git ncdu make patch bash lsof wget uuid tuned nvme-cli numactl grubby sysstat iotop htop rsync tcpdump perf flamegraph chkconfig"
node-package2:  "netcat socat ftp lrzsz net-tools ipvsadm bind-utils telnet audit ca-certificates readline vim-minimal keepalived chrony openssl openssh-server openssh-clients"
pgsql-utility:  "patroni patroni-etcd pgbouncer pgbackrest pgbadger pg_activity pg_timetable pgFormatter pg_filedump pgxnclient timescaledb-tools timescaledb-event-streamer pgcopydb pgloader"

postgresql:     "postgresql$v*"
pgsql:          "postgresql$v postgresql$v-server postgresql$v-libs postgresql$v-contrib postgresql$v-plperl postgresql$v-plpython3 postgresql$v-pltcl postgresql$v-llvmjit"
pgsql-mini:     "postgresql$v postgresql$v-server postgresql$v-libs postgresql$v-contrib"
pgsql-core:     "postgresql$v postgresql$v-server postgresql$v-libs postgresql$v-contrib postgresql$v-plperl postgresql$v-plpython3 postgresql$v-pltcl postgresql$v-llvmjit"
pgsql-full:     "postgresql$v postgresql$v-server postgresql$v-libs postgresql$v-contrib postgresql$v-plperl postgresql$v-plpython3 postgresql$v-pltcl postgresql$v-llvmjit postgresql$v-test postgresql$v-devel"
pgsql-main:     "postgresql$v postgresql$v-server postgresql$v-libs postgresql$v-contrib postgresql$v-plperl postgresql$v-plpython3 postgresql$v-pltcl postgresql$v-llvmjit pg_repack_$v* wal2json_$v* pgvector_$v*"
pgsql-client:   "postgresql$v"
pgsql-server:   "postgresql$v-server postgresql$v-libs postgresql$v-contrib"
pgsql-devel:    "postgresql$v-devel"
pgsql-basic:    "pg_repack_$v* wal2json_$v* pgvector_$v*"
# ......

Debian

node-bootstrap: "ansible python3 python3-pip python3-venv python3-jmespath dpkg-dev sshpass tnftp linux-perf"
infra-package:  "nginx dnsmasq etcd haproxy vip-manager node-exporter keepalived-exporter pg-exporter pgbackrest-exporter redis-exporter redis minio mcli pig"
infra-addons:   "grafana grafana-plugins loki logcli promtail prometheus alertmanager pushgateway blackbox-exporter nginx-exporter pev2 certbot python3-certbot-nginx"
extra-modules:  "docker-ce docker-compose-plugin ferretdb2 duckdb restic juicefs vray grafana-infinity-ds"
node-package1:  "lz4 unzip bzip2 zlib1g pv jq git ncdu make patch bash lsof wget uuid tuned nvme-cli numactl sysstat iotop htop rsync tcpdump acl chrony"
node-package2:  "netcat-openbsd socat lrzsz net-tools ipvsadm dnsutils telnet ca-certificates libreadline-dev vim-tiny keepalived openssl openssh-server openssh-client"
pgsql-utility:  "patroni pgbouncer pgbackrest pgbadger pg-activity pg-timetable pgformatter postgresql-filedump pgxnclient timescaledb-tools timescaledb-event-streamer pgcopydb pgloader"

postgresql:     "postgresql-$v postgresql-client-$v postgresql-plpython3-$v postgresql-plperl-$v postgresql-pltcl-$v postgresql-server-dev-$v"
pgsql:          "postgresql-$v postgresql-client-$v postgresql-plpython3-$v postgresql-plperl-$v postgresql-pltcl-$v"
pgsql-mini:     "postgresql-$v postgresql-client-$v"
pgsql-core:     "postgresql-$v postgresql-client-$v postgresql-plpython3-$v postgresql-plperl-$v postgresql-pltcl-$v"
pgsql-full:     "postgresql-$v postgresql-client-$v postgresql-plpython3-$v postgresql-plperl-$v postgresql-pltcl-$v postgresql-server-dev-$v"
pgsql-main:     "postgresql-$v postgresql-client-$v postgresql-plpython3-$v postgresql-plperl-$v postgresql-pltcl-$v postgresql-$v-repack postgresql-$v-wal2json postgresql-$v-pgvector"
pgsql-client:   "postgresql-client-$v"
pgsql-server:   "postgresql-$v"
pgsql-devel:    "postgresql-server-dev-$v"
pgsql-basic:    "postgresql-$v-repack postgresql-$v-wal2json postgresql-$v-pgvector"
# ......
发行版 x86_64 aarch64
Debian 11 d11.x86_64.yml -
Debian 12 d12.x86_64.yml d12.aarch64.yml
Debian 13 d13.x86_64.yml d13.aarch64.yml
Ubuntu 22.04 u22.x86_64.yml u22.aarch64.yml
Ubuntu 24.04 u24.x86_64.yml u24.aarch64.yml

参考

使用以下 Playbook 任务来管理基础设施节点上的本地软件包仓库(YUM/APT):

./infra.yml -t repo              # 从互联网或离线包创建本地仓库

./infra.yml -t repo_dir          # 创建本地仓库目录
./infra.yml -t repo_check        # 检查本地仓库是否存在
./infra.yml -t repo_prepare      # 如果可用则使用现有的本地仓库
./infra.yml -t repo_build        # 如果不存在则从上游构建本地仓库
./infra.yml     -t repo_upstream     # 添加上游 repo/list 文件
./infra.yml     -t repo_remove       # 如果 repo_remove=true 则移除现有仓库文件
./infra.yml     -t repo_add          # 添加上游仓库文件到 /etc/yum.repos.d(或 apt)
./infra.yml     -t repo_url_pkg      # 下载 repo_url_packages 中定义的软件包
./infra.yml     -t repo_cache        # 使用 yum makecache / apt update 创建元数据缓存
./infra.yml     -t repo_boot_pkg     # 安装引导软件包(createrepo_c、yum-utils 等)
./infra.yml     -t repo_pkg          # 从上游下载软件包及依赖项
./infra.yml     -t repo_create       # 使用 createrepo_c / dpkg-dev 创建本地仓库
./infra.yml     -t repo_use          # 添加新仓库到 /etc/yum.repos.d | apt sources
./infra.yml -t repo_nginx        # 如果未运行则启动 nginx 作为文件服务器

常用命令:

./infra.yml     -t repo_upstream     # 添加 repo_upstream 中定义的上游仓库
./infra.yml     -t repo_pkg          # 下载软件包及其依赖项
./infra.yml     -t repo_create       # 创建/更新本地 yum/apt 仓库

4.5 - DNS 域名

为 Web 服务设置域名

安装 Pigsty 后,用户可以通过 IP + 端口访问大多数基础设施组件的 Web 界面。

假设您的节点内部 IP 是 10.10.10.10,那么默认情况下:

虽然 IP + 端口对于开发/测试环境来说工作得很好(嘿,我们有时都很懒!),但对于更严肃的部署,我强烈建议通过域名访问这些服务。

使用域名有许多优势,不需要额外费用,只需要一个简单的配置行。

让我们深入了解这些主题:


TL;DR

将此静态解析记录添加到您的 /etc/hosts(Linux/MacOS)或 C:\Windows\System32\drivers\etc\hosts(Windows):

sudo tee -a /etc/hosts <<EOF
10.10.10.10 h.pigsty g.pigsty p.pigsty a.pigsty
EOF

将占位符 IP 10.10.10.10 替换为您的 Pigsty 节点的 IP(公共/私有,只要可达即可)。

如果您在 infra_portal 中修改了默认域名,请用您的自定义域名替换它们。


为什么使用域名?

Pigsty 强烈建议使用域名而不是直接 IP+端口访问,原因如下:

  • 域名更容易记住(除非您是机器人 🤖)
  • 更灵活 — 指向不同的 IP 而无需更改配置
  • 将所有服务整合在 Nginx 后面,以获得更好的管理、审计和减少攻击面
  • 启用 HTTPS 加密以防止流量窃听
  • 在中国,对未注册域名的 HTTP 访问会被 ISP 劫持,但 HTTPS 不会
  • 通过 Nginx 代理访问绑定到 127.0.0.1 或内部 Docker 网络的服务

Pigsty 默认使用内部静态域名 — 只需在本地添加 DNS 记录,无需注册真实域名

对于面向互联网的部署,考虑使用带有免费 HTTPS 证书的真实域名。


DNS 工作原理

如果您不熟悉 HTTP/DNS 协议,这里是关于 Nginx 如何在单个端口(80 + HTTPS 443)上为多个域名提供服务的快速入门:

DNS 协议

HTTP 协议

  • HTTP 请求(HTTP/1.1+)包含带有请求域名的 Host 标头
  • 这个 Host 标头是关键的 — HTTP/1.1 规范要求客户端包含它
  • Nginx 使用 Host 标头匹配并将请求路由到不同的站点
  • 因此,一个端口可以根据 Host 值提供不同的内容

Pigsty 默认域名

Pigsty 默认配置这四个内部域名

域名 名称 端口 组件 描述
h.pigsty home 80/443 Nginx 默认服务器,本地仓库
g.pigsty grafana 3000 Grafana 监控和可视化
p.pigsty prometheus 9058 Prometheus 时间序列数据库
a.pigsty alertmanager 9059 AlertManager 警报聚合和路由

由于这些域名不使用 TLD,您需要本地静态内部动态解析。

不用担心 — 只需要一行配置! 🚀


本地静态解析

假设 Pigsty 的内部 IP 是 10.10.10.10,将此添加到您的客户端机器的 hosts 文件:

# Pigsty 核心组件和默认域名
10.10.10.10 h.pigsty g.pigsty p.pigsty a.pigsty

添加解析

客户端机器是您浏览 Pigsty 服务的地方 — 您的笔记本电脑、台式机、VM 等。

对于 Linux / macOS:sudo nano /etc/hosts 对于 Windows:以管理员身份运行记事本,编辑 C:\Windows\System32\drivers\etc\hosts

添加记录后,您可以通过这些域名访问 Pigsty Web 服务。

自定义域名

不喜欢默认域名?在安装前在 infra_portal 中修改它们:

infra_portal:
  home         : { domain: h.pigsty.xxx }
  grafana      : { domain: g.pigsty.xxx ,endpoint: "${admin_ip}:3000" ,websocket: true }
  prometheus   : { domain: p.pigsty.xxx ,endpoint: "${admin_ip}:9058" }
  alertmanager : { domain: a.pigsty.xxx ,endpoint: "${admin_ip}:9059" }
  blackbox     : { endpoint: "${admin_ip}:9115" }
  loki         : { endpoint: "${admin_ip}:3100" }

然后相应地更新您的 hosts 文件:

10.10.10.10 h.pigsty.xxx g.pigsty.xxx p.pigsty.xxx a.pigsty.xxx

使用您喜欢的任何域名 — 真实的或虚构的 - 只要它通过本地内部公共 DNS 解析到 Pigsty 的 IP。

附加记录

运行其他 Pigsty 扩展?也添加这些记录:

# Pigsty 扩展工具和默认域名
10.10.10.10 adm.pigsty   # pgAdmin GUI
10.10.10.10 ddl.pigsty   # Bytebase DDL 管理
10.10.10.10 cli.pigsty   # pig CLI 保留
10.10.10.10 api.pigsty   # Pigsty API 保留
10.10.10.10 lab.pigsty   # JupyterLab 保留
10.10.10.10 git.pigsty   # Gitea 保留
10.10.10.10 wiki.pigsty  # Wiki.js 保留
10.10.10.10 noco.pigsty  # NocoDB 保留
10.10.10.10 supa.pigsty  # Supabase 保留
10.10.10.10 dify.pigsty  # Dify 保留
10.10.10.10 odoo.pigsty  # Odoo 保留
10.10.10.10 mm.pigsty    # MinIO 保留

公共 IP 解析

对于云部署,解析到您的公共 IP,而不是内部 IP。

如果您的服务器有互联网访问,它通常有两个网卡 - 一个用于互联网(公共 IP),一个用于内部网络(私有 IP)。

示例:如果您的云服务器的公共 IP 是 1.2.3.4,VPC IP 是 10.10.10.10

# 对于云部署,解析到公共 IP!只需更改 IP 部分:
1.2.3.4 h.pigsty g.pigsty p.pigsty a.pigsty

内部动态解析

希望您的办公室同事通过域名访问 Pigsty?使用内部动态解析

最简单的方法:请您的网络管理员将 DNS 记录添加到您的内部 DNS 服务器。

使用内部 DNS

如果您的内部 DNS 服务器是 192.168.1.1,在 Linux/MacOS 上编辑 /etc/resolv.conf

nameserver 192.168.1.1

在 Windows 上:网络设置 → 网络适配器 → TCP/IPv4 属性 → DNS 配置

测试内部 DNS 解析:

dig h.pigsty @192.168.1.1

使用 Pigsty 的 DNS

Pigsty 基础设施模块 包括 DNS 服务器(端口 53)。

⚠️ 中国部署警告:公共服务器通常不能运行 DNS 服务(端口 53)!


本地 HTTPS 访问

对 Pigsty 的 HTTP 访问显示"不安全" - 它是明文的,容易受到 MITM 攻击。

默认情况下,Pigsty 使用本地自签名 CA 为所有 Nginx 虚拟主机颁发证书。

HTTPS 访问显示"证书错误" - 这些是自签名证书,不是来自受信任的 CA。

您的选择:

  • 忽略它,使用 HTTP 或 IP+端口(反正是内部的,对吧?😅)
  • 使用 HTTPS,点击"高级 → 仍然继续"
  • Chrome 用户:在警告时输入 thisisunsafe(魔法词!)
  • 通过将 Pigsty 的 CA 添加到您的浏览器/操作系统来信任自签名证书
  • 为 Pigsty 使用真实的 CA 证书
  • 使用带有适当 HTTPS 证书的真实域名

对于需要 HTTPS 但不想持续警告的内部访问,信任 Pigsty 的自签名 CA

对于生产环境,我们建议使用公共域名通过 certbot 获取免费的 HTTPS 证书。


信任自签名 CA

Pigsty 在初始化期间在管理节点源目录(~/pigsty)中生成自签名 CA。

要使用 HTTPS,请将 Pigsty 的 CA 证书分发到客户端信任存储(或使用真实的 CA — 昂贵!)。

Pigsty 管理的 Linux 节点自动信任 CA。对于其他 Linux 系统:

  • 信任 CA 证书
  • EL
  • Debian / Ubuntu
rm -rf /etc/pki/ca-trust/source/anchors/ca.crt
ln -s /etc/pki/ca.crt /etc/pki/ca-trust/source/anchors/ca.crt
/bin/update-ca-trust

MacOS:双击 ca.crt,添加到钥匙串,搜索 pigsty-ca,打开并"信任"根证书。

Windows:将 ca.crt 添加到"受信任的根证书颁发机构"。

信任 Pigsty 的 CA 后,不再有"不受信任的证书"警告! 🎉


公共域名解析

使用 DNS 提供商,如 Cloudflare、Godaddy、阿里云或腾讯云 DNSPod。

需要购买域名 - 基本域名费用约为每年 10 美元。

通过提供商的控制台/API 添加 DNS 记录,将域名指向 Pigsty 的公共 IP

示例:使用域名 pigsty.xxx,添加通配符 * A 记录或单独的 A 记录:

  • h.pigsty.xxx → 1.2.3.4
  • a.pigsty.xxx → 1.2.3.4
  • p.pigsty.xxx → 1.2.3.4
  • g.pigsty.xxx → 1.2.3.4

Pigsty 包括Certbot 支持以获取免费的 HTTPS 证书(每 3 个月续订一次)。


进一步阅读

有关更高级的配置,请查看 Pigsty 文档中的 DNS、Nginx 和 HTTPS 证书管理。

4.6 - SSL 证书

配置真实和自签名 HTTPS 证书

Pigsty 在基础设施节点上预装了 Certbot,使您能够为 Nginx 服务器和公共域名获取免费的 Let’s Encrypt HTTPS 证书。


前提条件

在获取 Let’s Encrypt 证书之前,请确保您拥有:

  • 一个公共域名
  • 指向您服务器公共 IP 的 DNS 记录
  • 正确配置了您的域名的 Nginx

步骤 1:确定哪些域名需要证书

首先,通过在您的 infra_portal 中配置域名来确定哪些上游服务需要公共证书:

infra_portal:
  home         : { domain: h.pigsty.cc }
  grafana      : { domain: g.pigsty.cc, endpoint: "${admin_ip}:3000", websocket: true }
  prometheus   : { domain: p.pigsty.cc, endpoint: "${admin_ip}:9058" }
  alertmanager : { domain: a.pigsty.cc, endpoint: "${admin_ip}:9059" }
  minio        : { domain: m.pigsty.cc, endpoint: "${admin_ip}:9001", scheme: https, websocket: true }
  web          : { domain: pigsty.cc, path: "/www/web.cc" }
  repo         : { domain: repo.pigsty.cc, path: "/www/repo" }

步骤 2:将域名指向您的服务器

配置 DNS A 记录,将所有域名指向您服务器的公共 IP 地址:

# DNS 配置示例
47.83.172.23 pigsty.cc
47.83.172.23 h.pigsty.cc
47.83.172.23 g.pigsty.cc
47.83.172.23 p.pigsty.cc
47.83.172.23 a.pigsty.cc
47.83.172.23 m.pigsty.cc
47.83.172.23 repo.pigsty.cc

验证您的域名是否正确指向您的服务器:

# 测试域名解析
nslookup pigsty.cc
dig g.pigsty.cc

步骤 3:使用 Certbot 请求证书

使用 Certbot 为您的域名请求 Let’s Encrypt 证书:

交互式方法(首次)

certbot --nginx -d pigsty.cc -d repo.pigsty.cc -d g.pigsty.cc -d p.pigsty.cc -d a.pigsty.cc

在首次运行期间,您将被提示:

  • 提供用于 Let’s Encrypt 账户注册的电子邮件地址
  • 同意服务条款
  • 选择是否与电子前哨基金会分享您的电子邮件

非交互式方法

对于自动化部署,使用非交互式模式:

certbot --nginx --agree-tos --email [email protected] -n -d your-domain.com

多个域名的示例:

certbot --nginx --agree-tos --email [email protected] -n \
  -d pigsty.cc \
  -d g.pigsty.cc \
  -d p.pigsty.cc \
  -d a.pigsty.cc \
  -d repo.pigsty.cc

步骤 4:更新 Nginx 配置

成功获取证书后,通过添加 certbot: true 参数来更新您的 infra_portal 配置以使用它们:

infra_portal:
  grafana: { domain: g.pigsty.cc, endpoint: "${admin_ip}:3000", websocket: true, certbot: true }
  prometheus: { domain: p.pigsty.cc, endpoint: "${admin_ip}:9058", certbot: true }
  alertmanager: { domain: a.pigsty.cc, endpoint: "${admin_ip}:9059", certbot: true }
  web: { domain: pigsty.cc, path: "/www/web.cc", certbot: true }
  repo: { domain: repo.pigsty.cc, path: "/www/repo", certbot: true }

然后重新生成 Nginx 配置并重启服务:

./infra.yml -t nginx_config,nginx_launch

步骤 5:配置证书续期

Let’s Encrypt 证书每 90 天过期一次。设置自动续期以确保持续的 HTTPS 覆盖:

测试续期(试运行)

在设置自动续期之前,测试流程:

certbot renew --dry-run

手动续期

手动续期所有证书:

certbot renew

续期特定证书:

certbot renew --cert-name your-domain.com

自动续期

设置每月自动续期的 cron 作业:

# 添加到 crontab
crontab -e

# 添加这一行在每月第一天凌晨 2 点进行续期
0 2 1 * * certbot renew --quiet

或者,如果可用,使用 systemd 定时器:

# 启用 certbot 定时器
systemctl enable certbot.timer
systemctl start certbot.timer

证书管理命令

以下是管理证书的有用 Certbot 命令:

# 列出所有证书
certbot certificates

# 查看证书详细信息
certbot certificates --cert-name your-domain.com

# 续期特定证书
certbot renew --cert-name your-domain.com

# 删除证书
certbot delete --cert-name your-domain.com

# 扩展证书以包含新域名
certbot --nginx -d existing-domain.com -d new-domain.com

# 撤销证书
certbot revoke --cert-path /etc/letsencrypt/live/your-domain.com/cert.pem

故障排除

常见问题

  1. 域名不可访问:确保 DNS 记录正确配置并已传播
  2. 端口 80 被阻塞:Let’s Encrypt 需要端口 80 进行域名验证
  3. 速率限制:Let’s Encrypt 有速率限制;避免快速请求太多证书
  4. 防火墙问题:确保防火墙中端口 80 和 443 是开放的

验证命令

# 检查证书过期时间
openssl x509 -in /etc/letsencrypt/live/your-domain.com/cert.pem -text -noout | grep "Not After"

# 测试 SSL 配置
openssl s_client -connect your-domain.com:443 -servername your-domain.com

# 检查 Nginx 配置
nginx -t

# 重新加载 Nginx
nginx -s reload

最佳实践

  1. 在适当时使用通配符证书用于多个子域名
  2. 使用自动化警报监控证书过期
  3. 定期使用试运行测试续期流程
  4. 保留证书文件的备份
  5. 在生产部署前使用暂存环境进行测试
  6. 为证书过期日期设置监控
  7. 为团队参考记录您的域名配置

安全考虑

  • 保护私钥:确保证书私钥具有受限权限
  • 使用强 SSL 配置:使用现代 SSL 设置配置 Nginx
  • 启用 HTTP 到 HTTPS 重定向:强制安全连接
  • 实施 HSTS:添加 HTTP 严格传输安全标头
  • 定期安全审计:使用 SSL Labs 等工具测试您的 SSL 配置

5 - 关于

关于 pigsty 本身的信息和服务

Pigsty (/ˈpɪɡ staɪ/) 是一个开箱即用的开源 PostgreSQL 发行版, 也是一个本地优先的 RDS 替代方案

作者
    Pigsty 由 冯若航 (@Vonng) 与社区创建
许可证
    Pigsty 在 AGPLv3 许可证下开源,有一些豁免
社区
    加入我们的用户群和论坛,从社区获得支持
服务
    从专家获得专业支持,企业用例的专业支持和订阅计划

发布
    Pigsty 的发布说明和更改日志
事件
    最新事件、会议、聚会、办公时间等
路线图
    Pigsty 的新功能、改进和未来计划
问题
    安全漏洞、错误缺陷、修复公告

5.1 - 作者

The one who created Pigsty

关于作者

我是冯若航,别名 @Vonng,Pigsty 的作者。 Pigsty 的绝大部分的代码由我 一人开发,个别特性由 社区贡献

软件领域依然存在个人英雄主义,独一无二的个体才能够创造出独一无二的作品来 —— 我希望 Pigsty 能够成为这样的作品。 如果您对我感兴趣,这里是我的个人主页:https://vonng.com/

墨天轮风云人物访谈录 —— 冯若航

90后,辞职创业,说要卷死云数据库


历史起源

Pigsty 项目始于 2018 ~ 2019 年,起源于 探探。 探探是一个互联网交友 App —— 中国的 Tinder,现已被陌陌收购。 探探这家公司是一个北欧 Style 的创业公司,有着一个瑞典工程师初创团队。

探探在技术上极有品味,使用 PostgreSQL 与 Go 作为核心技术栈。 探探整个系统架构参照了 Instagram ,一切围绕 PostgreSQL 数据库设计。 直到几百万日活,几百万 TPS,几百 TB 数据的量级下,数据组件 只用了 PostgreSQL。 几乎所有的业务逻辑都使用 PG 存储过程实现 —— 甚至包括 100ms 的推荐算法!

探探这种深度使用 PostgreSQL 特性的非典型研发模式,对工程师与DBA的水平提出了极高的要求。 而 Pigsty ,就是我们用这种真实世界的大规模,高标准数据库集群场景打磨出的开源项目 —— 沉淀着我们作为顶尖 PostgreSQL 专家的经验与最佳实践。


发展过程

在最开始,Pigsty 并没有现在这样的愿景、目标与版图。而是旨在提供一个供我们自己使用的 PostgreSQL 监控系统。 我们调研了市面上所有的方案,开源的、商业的、云的,datadog, pgwatch,…… ,没有一个能满足我们对于可观测性的需求。 因此我们决定亲自动手,基于 Grafana 与 Prometheus 自己动手打造一个,这就是 Pigsty 的前身与雏形。 Pigsty 作为监控系统的效果相当惊艳,帮助我们解决了无数管理问题。

随后,研发人员希望在本地的开发机上也有这样的监控系统,于是我们使用 Ansible 编写了置备剧本,将这套系统从一次性建设任务转变为了可重复使用,可复制的软件。 新的功能允许用户使用 Vagrant 和 Terraform,用 Infra as Code 的方式快速拉起本地 DevBox 开发机,或生产环境服务器,并自动完成 PostgreSQL 与监控系统的部署。

接下来,我们重新设计了生产环境的 PostgreSQL 架构,引入了 Patroni 与 pgBackRest 解决了数据库的 高可用时间点恢复 问题。 开发了基于逻辑复制的不停机 迁移 方案,通过蓝绿部署将生产环境两百套数据库集群滚动升级至最新大版本。并将这些能力引入 Pigsty 中。

Pigsty 是我们做给自己使用的软件,我们自己作为甲方用户,非常清楚自己需要什么,也不会在自己的需求上偷懒。 “Eat dog food”最大的好处就是,我们自己既是开发者也更是用户 —— 因此非常了解自己需要什么,也不会在自己的需求上偷懒。

我们解决了一个又一个的问题,并将解决方案沉淀到 Pigsty 里。Pigsty 的定位,也从一个监控系统,逐渐发展成为一个开箱即用的 PostgreSQL 数据库发行版。 因此在这一阶段,我们决定将 Pigsty 对外开源,并开始了一系列的技术分享与宣传,也开始有各行各业的外部用户使用起 Pigsty 并提出反馈意见。


全职创业

在 2022 年,Pigsty 项目获得了由陆奇博士发起的奇绩创坛的种子轮投资,我得以全职出来做这件事情。

作为一个开源项目,Pigsty 的发展相当不赖,在全职创业这两年里,Pigsty 在 Github 上的 Star 数从的 几百翻了几番到了 3700;上了 HN 头条推荐,增长开始滚起雪球; 在 OSSRank 开源榜单 中,Pigsty 在 PostgreSQL 生态项目中排名第 22 名,在中国人主导的项目里是最靠前的。

从前 Pigsty 只能跑在 CentOS 7 上,现今已经基本覆盖了所有主流 Linux 发行版 (EL, Debian, Ubuntu)。支持的 PG 大版本覆盖 12 - 18,维护,收录整合了PG生态中的 437 扩展插件。 其中,我本人维护了这里超过一半的扩展插件,并提供开箱即用的 RPM/DEB 包,算上 Pigsty 本身,“基于开源,回馈开源”,算是为 PG 生态做一些贡献。

Pigsty 的定位,也在不断发展的过程中,从一个 PostgreSQL 数据库发行版,进一步扩展到了 开源云数据库替代。它真正对标的是云厂商的整个云数据库品牌。


公有云的反叛者

AWS、Azure、GCP、Aliyun 等公有云厂商为初创企业提供了许多便利,但它们是闭源的,并迫使用户以高额费用租赁基础资源。

我们认为,优秀的数据库服务,应该和优秀的数据库内核一样,普及到每一个用户手中,而不是必须花费高昂的代价去向赛博领主租赁。

云计算的敏捷与弹性都很好,但它应该是自由、开源、普惠、本地优先的 —— 我们认为云计算宇宙中需要一个代表开源价值观的解决方案,在不牺牲云带来好处的前提下,将基础设施的控制权交还给用户。

因此,我们也在引领着一场 下云的运动与战役,作为公有云的反叛者,来重塑这个行业的价值观。


我们的愿景

我希望,未来的世界人人都有自由使用优秀服务的事实权利,而不是只能被圈养在几个赛博领主公有云巨头厂商的地盘上当赛博佃户甚至赛博农奴。

这正是 Pigsty要做的事 —— 一个更好的,开源免费的RDS替代。让用户能够在任何地方(包括云服务器)上,一键拉起有比云RDS更好的数据库服务。

Pigsty 是是对 PostgreSQL 的彻底补完,更是对云数据库的辛辣嘲讽。它本意是“猪圈”,但更是 Postgres In Great STYle 的缩写,即“全盛状态下的 PostgreSQL”。

Pigsty 本身是一款完全开源免费的软件,我们纯粹靠提供 咨询与服务 来维持运营 建设良好的系统也许跑个几年都不会遇到需要 ”兜底“ 的问题,但数据库的问题一但出现就不是小问题。 很多时候,专家的经验更是能够一言化腐朽为神奇,而我们为有需求的客户提供这样的服务 —— 我们认为这是一种更加公正、合理、可持续的模式。

5.2 - 开源协议

开源许可证,法律声明,以及 SBOM 清单

摘要

Pigsty 使用 AGPLv3 开源协议,这是一种强制性的 Copyleft 许可证。

如果您通过网络分发、托管或创建 Pigsty 软件的 衍生作品, GNU AGPLv3 许可证要求您也按照相同的 GNU AGPL v3 许可证分发组合作品的完整、相应的源代码。 无论您是否修改了 Pigsty ,此要求都适用。

本协议授权您:

  • 商用
  • 修改
  • 分发
  • 专利授权
  • 私人使用

本协议不提供:

  • 商标使用权
  • 责任与担保

本协议的条件:

  • 包含本许可证并显著声明
  • 不得修改其开源状态
  • 公开源代码
  • 通过网络使用属于分发的一种
  • 使用同样的协议开源

提示:本产品自动化安装了第三方组件(Grafana, MinIO,可选),这些组件遵循 AGPLv3 许可,用户在通过网络分发这些组件的修改版时需遵循相应义务。


豁免条款

Pigsty 采用了 AGPLv3 许可证,但对于普通终端用户(即:公有云厂商,数据库厂商除外的用户),执行等效 Apache 2.0 许可证。

普通终端用户可以将 AGPLv3 用于商业目的,提供服务,二次开发,而无需担心许可证问题。 即使普通终端用户对 Pigsty 进行二次开发,并违反了 AGPL 协议没有开源衍生作品, 只要用途在合理范围内,我们不会对此进行追索,并豁免用户的相关开源义务。 在 订阅支持 中,我们可以提供关于责任豁免的书面承诺。

我们支持并欢迎遵循 AGPLv3 协议的 PostgreSQL 服务提供商 基于 Pigsty 交付, 并提供自己的付费咨询与支持服务,并将二次开发成果回馈上游社区主干。 请注意,PIGSTY® 是注册商标,在提供服务与咨询时,您应当尊重 PIGSTY 的知识产权,包括但不限于商标权与著作权。 我们提供 OEM 合作方案,详情请参考 商业支持


为何使用AGPLv3

AGPLv3 的精神实质是确保 “软件自由”:AGPLv3 不影响普通用户的使用:因为使用并不是一种 “发布”,您无需操心使用 Pigsty 的业务代码是否需要开源。 当您将 Pigsty 或 Pigsty 的修改作为软件/服务的全部或一部分对外“发布”时,您才需要考虑到 AGPLv3 的约束。以下是 GNU 官方对 GPL 相关问题的解答:

GNU 许可证常见问题


BOM清单

本项目所依赖或相关的核心开源软件及其开源协议。437 个 PostgreSQL 扩展插件的许可证请参考 PG扩展列表

模块 软件名称 许可证 必要性,用途与说明 必要性
PGSQL PostgreSQL PostgreSQL License PostgreSQL 内核 必选
PGSQL patroni MIT License 提供 PostgreSQL 高可用能力 必选
ETCD etcd Apache License 2.0 提供高可用共识与分布式配置存储 必选
INFRA Ansible GPLv3 管控工具,执行剧本,发起管控命令 必选
INFRA Nginx BSD-2 暴露Web系统界面,提供本地软件源 必选
PGSQL pgbackrest MIT License 提供 PITR 备份/恢复管理能力 建议
PGSQL pgbouncer ISC License 提供 PostgreSQL 连接池化能力 建议
PGSQL vip-manager BSD 2-Clause License 提供自动将 L2 VIP 绑定到 PG 集群主库的能力 建议
PGSQL pg_exporter Apache License 2.0 提供监控 PostgreSQL 与 PgBouncer 的能力 建议
NODE node_exporter Apache License 2.0 提供主机节点监控能力 建议
NODE haproxy HAPROXY’s License (GPLv2) 提供负载均衡,对外暴露服务的能力 建议
INFRA Grafana AGPLv3 提供数据库可视化平台 建议
INFRA Prometheus Stack Apache License 2.0 提供监控时序数据库存储,指标采集与监控告警 建议
INFRA Loki AGPLv3 提供集中式日志收集存储查询平台 建议
INFRA DNSMASQ GPLv2 / GPLv3 提供DNS解析服务,提供集群名查询能力 建议
MINIO MinIO AGPLv3 提供S3兼容的对象存储服务 可选
NODE keepalived MIT License 提供绑定在节点集群上的 VIP 可选
REDIS Redis Redis License (BSD-3) 搭配PG使用的缓存服务,锁死版本 7.2.6 可选
REDIS Redis Exporter MIT License 提供 Redis 监控能力 可选
MONGO FerretDB Apache License 2.0 提供基于PG的MongoDB兼容能力 可选
DOCKER docker-ce Apache License 2.0 提供容器管理能力 可选
CLOUD SealOS Apache License 2.0 提供快速部署,复制,打包K8S集群的能力 可选
DUCKDB DuckDB MIT 提供简单易用的高性能分析能力 可选
External Vagrant Business Source License 1.1 拉起本地测试环境虚拟机 按需
External Terraform Business Source License 1.1 一键申请云资源用于部署 按需
External Virtualbox GPLv2 虚拟机管理软件 按需

必要性等级说明:

  • 必选:提供 Pigsty 关键性核心能力,不提供关闭停用选项
  • 建议:Pigsty 默认启用的组件,可以通过配置选项停用
  • 可选:Pigsty 默认会下载但不启用的组件,可通过配置启用
  • 按需:按需使用的工具,可按需配置下载并启用

协议原文

                    GNU AFFERO GENERAL PUBLIC LICENSE
                       Version 3, 19 November 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.

  A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate.  Many developers of free software are heartened and
encouraged by the resulting cooperation.  However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.

  The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community.  It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server.  Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.

  An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals.  This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU Affero General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Remote Network Interaction; Use with the GNU General Public License.

  Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software.  This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time.  Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    Copyright (C) 2018-2025  Ruohang Feng, Author of Pigsty

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source.  For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code.  There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.

5.3 - 社区

开源社区和用户群组

Pigsty 社区已经提供免费的微信/Discord/Telegram 问答答疑时间,我们也很乐意为我们的支持者提供更多免费的增值服务。


GitHub 总部

如果您觉得 Pigsty 有用,请考虑在 GitHub 上给我们一个 star。 欢迎提交 Issues、PRs 和讨论。

仓库
    Pigsty 的源代码仓库
组织
    GitHub 上的 `pgsty` 组织是 Pigsty 的官方主页。
问题
    创建新问题和报告错误,提交功能请求
讨论
    提问,分享想法,从社区获得帮助

社区

我们有 7 个活跃的微信用户群,约有 2700+ 用户,加入我们的讨论!

讨论
    Pigsty 的 GitHub 讨论论坛
微信
    搜索 `pigsty-cc` 并加入用户群组。
Telegram
    Pigsty 的 Telegram 群组:gV9zfZraNPM3YjFh
Discord
    Pigsty 的 Discord 服务器:j5pG8qfKxU

您也可以通过邮件联系我:[email protected]


寻求帮助

您可以向社区寻求帮助,提供足够信息和上下文的问题更容易得到帮助。

也可以考虑使用我们的 ChatGPT QA 代理专业服务

寻求帮助

发生了什么? (必需)

Pigsty 版本和操作系统版本 (必需)

$ grep version  pigsty.yml

$ cat /etc/os-release

如果您使用云提供商,请告诉我们您使用的是哪个云提供商以及什么操作系统镜像。

如果您在安装裸机操作系统后自定义和修改了环境,或者在 WAN 中有特定的安全规则和防火墙配置,请在故障排除时也告诉我们。

Pigsty 配置文件 (必需)

不要忘记删除敏感信息,如密码等…

cat ~/pigsty/pigsty.yml

您期望发生什么?

请描述您期望发生什么。

如何重现它?

请尽可能详细地告诉我们如何重现该问题。

监控截图

如果您正在使用 pigsty 监控系统,您可以在此处粘贴相关截图。

错误日志

请复制并粘贴任何相关的日志输出。不要粘贴类似"无法启动 xxx 服务"的内容

  • Syslog:/var/log/messages(RHEL)或 /var/log/syslog(Debian)
  • Postgres:/pg/log/postgres/*
  • Patroni:/pg/log/patroni/*
  • Pgbouncer:/pg/log/pgbouncer/*
  • Pgbackrest:/pg/log/pgbackrest/*
journalctl -u patroni
journalctl -u <service name>

您是否尝试过问题和 FAQ?

我们还需要知道什么?

您提供的信息和上下文越多,我们就越有可能帮助您解决问题。

5.4 - 新闻

Pigsty 相关事件与新闻,与最新活动预告

最近新闻


2025-11-29

第八届中国 PG 生态大会:Pigsty 荣获 “PostgreSQL 万磁王奖”

Ruohang Feng

主题演讲:打造立足中国,面向世界的 PG 数据库发行版

闪电演讲:为什么 PostgreSQL 是 AI 时代数据库之王?

闪电演讲:身陷囹圄:PostgreSQL 安装与交付最佳实践

第八届中国PG生态大会 中国杭州


2025-05-16

扩展分发:让你的作品对世界可见

Ruohang Feng

Giving a lightning talk here at #PGConfdev is Ruohang Feng, founder at Pigsty, presenting on “Extension Delivery: Make your PG Ext accessible to users” —— PGConf.Dev X

Wechat Column: Lighting Talks Recap

Lighting Talks, PGConf.Dev 2025, Montreal, Canada


2025-05-12

The Missing Package Manager and Extension Repo for PostgreSQL Ecosystem

PGEXT.DAY

Youtube: https://www.youtube.com/live/cucQOOAahNY (Start @ 4:50:20)

2025-05-12: PGEXT.DAY, PGCon.Dev 2025, Montreal


Before


会议与演讲

日期 类型 活动 主题
2025-05-16 技术大会 PGCon.Dev 2025 全球PG开发者大会 闪电演讲:Extension Delivery - Make your PGEXT accessible to users
2025-05-12 技术大会 PGCon.Dev 2025 全球PG开发者大会扩展峰会 PG 生态缺失的包管理器与扩展仓库 - pig
2025-04-19 实战工坊 PostgreSQL 数据库技术峰会 使用Pigsty拉起PG生态好伙伴 Dify,Odoo,Supabase
2025-04-11 直播主持 开源中国-数智漫谈 全网爆火的 MCP 到底是炒作还是神器
2025-01-15 直播演讲 开源项目老牌与新秀 第四期 PostgreSQL 扩展吞噬数据库世界?PG包管理器 pig 与 RDS 自建发行版 Pigsty
2025-01-09 颁奖活动 开源中国 2024 年度突出贡献专家 开源中国 2024 年度突出贡献专家
2025-01-06 圆桌论坛 中国 PostgreSQL 数据库生态大会 PostgreSQL 正在通过扩展吞噬数据库世界
2024-11-23 播客节目 播客·科技乱炖 从Linux基金会聊起,为什么这些年都热衷于“卡脖子”?
2024-08-21 媒体专访 Blue Tech Wave: Interview with Feng Ruohang, author of Pigsty Simplifying PostgreSQL management and advancing the Chinese open-source community
2024-08-15 技术大会 GOTC 全球开源技术峰会 PostgreSQL AI/ML/RAG 扩展生态与最佳实践
2024-07-12 主题演讲 第十三届PG中国技术大会 数据库世界的未来:Extensions, Service, and Postgres
2024-05-31 技术大会 PGCon.Dev 2024 全球PG开发者大会 Unconference Built-in Prometheus Metrics Exporter
2024-05-28 主题研讨 PGCon.Dev 2024 全球PG开发者大会扩展峰会 Extension in Core & Binary Packing
2024-05-29 主题奥伦 第十三届PG中国技术大会 数据库世界的未来:Extensions, Service, and Postgres
2024-05-10 直播对谈 明说三人行:云计算泥石流系列第三期 公有云是杀猪盘吗?
2024-04-17 直播对谈 明说三人行:云计算泥石流系列第二期 云数据库是智商税吗?
2024-04-16 圆桌论坛 Cloudflare Immerse 深圳 赛博菩萨圆桌论坛
2024-04-12 技术大会 2024 数据技术嘉年华 Pigsty:解决 PostgreSQL 运维难题
2024-03-31 直播对谈 明说三人行:云计算泥石流系列第一期 老罗卖云咱下云?
2024-01-24 直播主持 开源中国:开源漫谈第九期 DBA 会被云淘汰吗?
2023-12-20 直播辩论 开源中国:开源漫谈第七期 上云 or 下云,割韭菜还是降本增效?
2023-11-24 技术大会 机器之心:大模型时代的向量数据库 圆桌讨论:大模型时代向量数据库新未来
2023-09-08 人物专访 墨天轮风云人物访谈 冯若航:不想当段子手的技术狂,不是一位好的开源创始人
2023-08-16 技术大会 DTCC 2023 DBA之夜:PostgreSQL vs MySQL的开源协议问题
2023-08-09 直播辩论 开源漫谈第一期 MySQL vs PostgreSQL,谁是世界第一?
2023-07-01 技术大会 SACC 2023 专题研讨会8:FinOps实践:云成本管理与优化
2023-05-12 线下活动 PostgreSQL中国社区 温州站线下沙龙 PG With DB4AI: 向量数据库 PGVECTOR & AI4DB: 数据库自动驾驶 Pigsty
2023-04-08 技术大会 数据库嘉年华 2023 更好的开源RDS替代:Pigsty
2023-04-01 技术大会 PostgreSQL中国社区 西安站线下沙龙 PG高可用与容灾最佳实践
2023-03-23 公开直播 Bytebase x Pigsty 管理 PostgreSQL 的最佳实践: Bytebase x Pigsty
2023-03-04 技术大会 PostgreSQL中国技术大会 炮打 RDS,Pigsty v2.0 发布
2023-02-01 技术大会 DTCC 2022 开源 RDS 替代:开箱即用、自动驾驶的数据库发行版 Pigsty
2022-07-21 直播辩论 云吞噬开源,那开源有机会反击吗? 云吞噬开源,那开源有机会反击吗?
2022-07-04 人物专访 专题采访:创造者说 90 后,辞职创业,说要卷死云数据库
2022-06-28 公开直播 贝斯的圆桌趴 |DBA 福音 - SQL 审核最佳实践
2022-06-12 公开路演 奇绩创坛 S22 路演日 好用省钱的数据库发行版 Pigsty
2022-06-05 视频直播 PG中文社区直播分享 Pigstyv1.5快速上手新特性介绍与生产集群搭建
2021-08-01 技术大会 GOTC 全球开源技术峰会 2021 ⽼树发新芽 —— 开箱即⽤的开源PostgreSQL发⾏版 Pigsty

排名

Star History: pgsty/pigsty

OSSRank: PostgreSQL Ecosystem

PS: Pigsty 目前是中国在 PostgreSQL 生态开源项目(内核,扩展,发行版)中 GitHub Star 数最高的项目。

项目 Star 简介
pigsty 4.3K 开箱即用的PG发行版
PolarDB PG 3.1K 阿里云 PolarDB 开源内核
pgvector.rs 2.1K Rust 编写的PG向量扩展
VectorChord 1.4K 下一代 Rust PG 向量扩展
TBase 1.4K 腾讯云 PG 内核
Cloudberry 1.1K Hashdata 的开源 Greenplum 2.0
IvorySQL 960 瀚高主导的 Oracle 兼容内核
openGauss 751 华为主导的早期 PG 分叉
openHalo 626 易景开源的 MySQL 兼容 PG 内核
zhparser 798 使用 scws 的PG中文分词扩展
duckdb_fdw 393 李红艳开源的 DuckDB 包装器
pg_jieba 392 使用结巴分词的 PG 中文分词扩展
VectorChord-bm25 314 PG 原生的 BM25 排序索引算法
pg_roaringbitmap 263 PG 中的 RoaringBitmap 位图

5.5 - 漏洞

安全漏洞,Bug 缺陷,修复公告

PIGSTY-20231201

PIGSTY-20231201

**问题名称**: ETCD 写满导致 PGSQL 高可用失效

问题等级关键错误,请立即安排修复

影响范围: Pigsty v2.0.0 - v2.5.1 ,于 Pigsty v2.6.0 修复

问题描述

etcd 默认设置了一个 2GB 的数据库容量上限,如果您的 etcd 数据库容量超过了这个限制,etcd 将会拒绝写入请求。这可能导致依赖 etcd 的 PostgreSQL 高可用机制无法正常工作。 与此同时,etcd 的 数据模型 使得每一次写入都会产生一个新的版本,因此如果您的 etcd 集群频繁写入,即使只有极个别的 Key, etcd 数据库的大小也可能会不断增长,并在达到容量上限时出现故障。

解决方案

将 Pigsty 更新至 v2.6.0 以上的版本,或者更新 roles/etcd 部分的代码后,重新执行 ./etcd.yml 强制重置 etcd 集群实现修复。 关键配置更新: roles/etcd/templates/etcd.conf


5.6 - 路线

未来特性规划和功能雷达

Pigsty 遵循结构化的开发路线图,定期发布和持续改进。本页概述了我们的发布时间表、即将推出的功能和长期计划。


发布公告

Pigsty v3.7.0 已发布

Pigsty v3.7.0 已发布!


发布计划

Pigsty 使用格式为 <主版本>.<次版本>.<补丁>语义版本控制

  • 主要更新:每年发布一次,包含重要的新功能和改进
  • 次要更新:每年发布 4~6 次,通常与 PostgreSQL 发布保持一致
  • 补丁更新:根据需要进行错误修复和小改进
版本命名约定
  • 稳定发布v3.1.0v3.2.0
  • Alpha 版本v3.1.0-a1v3.1.0-a2(早期开发)
  • Beta 版本v3.1.0-b1v3.1.0-b2(功能完整,测试中)
  • 候选发布v3.1.0-rc1(生产就绪,最终测试)
发布建议
  • 始终使用标记的发布版本而不是 GitHub 主分支
  • 在生产部署中使用特定版本的发布
  • 在升级生产环境之前在开发环境中测试新版本

功能雷达

以下特性已经完成,或列入后续版本的规划与评估:

  • PostgreSQL 18 支持
  • Supabase 自托管教程
  • Dify 自托管教程
  • Odoo 自托管教程
  • EL 10 支持
  • 自托管 PostHog
  • MySQL 数据库部署监控
  • 使用 vector 替换 Promtail
  • 使用 victorialogs 替换 Loki
  • 使用 victoriametrics 替换 Prometheus
  • 改进日志输出目标管理
  • 使用 SealOS 部署和监控高可用 Kubernetes 集群

6 - 价值主张

Pigsty 的八条核心价值主张

Pigsty 提出以下八条核心价值主张,这八大价值协同工作,提供了一个从开发到企业生产环境的全面数据库平台。 Pigsty 将 PostgreSQL 从简单的数据库转变为组织真正拥有和控制的强大、可观测、可维护的数据基础设施。


可扩展的 Postgres
    无限可能的绽放
可靠的基础设施
    坚如磐石且安全
可观测的图形
    清晰与洞察
可扩展的服务
    弹性性能
可维护的工具箱
    简单可操作
可组合的模块
    灵活的乐高积木
可控的 FOSS
    主权自托管
经济实惠的解决方案
    性价比卓越的 RDS

🧩 可扩展的 Postgres

“滋养万物,协同繁荣,铸就无限可能!”

数据分析
    大数据挑战者
人工智能
    RAG应用标配
地理空间
    GIS事实标准
时间序列
    玩转时序时态
全文检索
    内置搜索引擎
存储过程
    语言任君选择
外表封装
    打通数据孤岛
特色扩展
    数据库即平台

🛡️ 可靠的基础设施

“巍峨高峰,基石坚固,屹立于任何巅峰!”

极致可用
    HA PostgreSQL
故障自愈
    自适应服务接入
删库兜底
    预置时间点恢复
自给自足
    没有外部依赖
访问控制
    模型开箱即用
坚如磐石
    机密性保障
精益求精
    完整性校验
实战检验
    可用性标杆

📊 可观测的图形

“天行健,洞察一切,感知细节以掌控全局!”

开箱即用
    自带监控基础设施
数据驱动
    为数智化转型奠基
极致体验
    PG监控版本答案
通用监控
    不仅是PG与RDS
自动告警
    告别DBA人肉盯盘
性能优化
    慢查询瓶颈轻松查
日志分析
    快速定位故障根因
大屏报表
    低代码可视化开发

⚡ 可扩展的服务

“如水而流,柔韧坚韧,汇聚溪流以适应无尽变化!”

性能澎湃
    新硬件红利尽享
读写分离
    读请求无限扩容
链接池化
    高并发手到擒来
负载均衡
    控制台流量管控
水平扩展
    分布式原地改造
存储扩容
    外部表透明压缩
批量管理
    大规模集群部署
弹性伸缩
    云计算他山之石

🔧 可维护的工具箱

“如火燎原,照亮四方,熊熊燃烧永不息!”

言出法随
    基础设施即代码
简单易用
    几分钟快速上手
裸机运行
    无需容器与K8S
离线安装
    稳定顺畅的交付
体系配套
    开发规约与SOP
无需停服
    在线迁移与变配
按需配置
    丰富的定制参数
沙箱环境
    一键置备服务机

🎯 可组合的模块

“疾如风,化繁为简,乘风破浪自如!”

自由拼装
    模块化乐高设计
软件模板
    企业级应用一键建
核心模块
    功能完备PG RDS
扩展模块
    拓展能力边界
内核模块
    可替换数据库引擎
数仓模块
    强大数据分析能力
试点模块
    前沿边界的探索
风味模块
    Postgres玩出花

🎛️ 可控的 FOSS

“厚德载物,海纳百川——坚守初心,仰望星空!”

自由软件
    民主化自建能力
本地优先
    运营到地老天荒
多云部署
    再无供应商锁定
扩展自由
    海量扩展随心装
掌控数据
    真正自主掌控
二次开发
    撸起袖子自己上
信创合规
    国产化顺势而为
专业服务
    顶级专家来兜底

💰 经济实惠的解决方案

“雷霆万钧,破而后立,成本可控,价值永升!”

开源免费
    用好PostgreSQL
财务降本
    逃离RDS杀猪盘
人力增效
    人人都能是DBA
简化架构
    无需云原生全家桶
赋能下云
    解决自建关键卡点
社区支持
    交流讨论共建
咨询服务
    会者不难按需付费
订阅服务
    明码标价物有所值

这八大价值协同工作,提供了一个从开发到企业生产环境的全面数据库平台。Pigsty 将 PostgreSQL 从简单的数据库转变为组织真正拥有和控制的强大、可观测、可维护的数据基础设施。

6.1 - 可扩展性

百花齐放的 PostgreSQL

多模态,超融合,一条SQL顶应用千言万语,四百插件助PG征战天下!

数据分析
    大数据挑战者
人工智能
    向量数据库基线
地理空间
    GIS事实标准
时间序列
    玩转时序时态
全文检索
    内置搜索引擎
存储过程
    语言任君选择
外表封装
    打通数据孤岛
特色扩展
    数据库即平台

数据分析:大数据挑战者

一流的分析性能,DuckDB 集成,并行查询,分布式计算

PostgreSQL 在数据分析领域表现出色,拥有强大的 SQL 功能和众多分析扩展:

  • DuckDB 集成:在 PostgreSQL 中直接使用 DuckDB 进行 OLAP 查询
  • 并行查询:自动并行化复杂查询以提升性能
  • 分布式计算:通过 Citus 实现横向扩展
  • 列式存储:支持列式数据格式以优化分析工作负载

人工智能:向量数据库基线

AI 和数据库融合,向量存储,SQL 中的机器学习

PostgreSQL 原生支持向量数据类型和 AI 工作负载:

  • 向量扩展:pgvector 提供高效的向量相似性搜索
  • 嵌入存储:原生支持高维向量数据存储
  • 机器学习:MADlib 提供 SQL 中的机器学习算法
  • AI 集成:与主流 AI 框架无缝集成

地理空间:GIS事实标准

全面的地理空间处理,路由,索引

PostGIS 是地理信息系统的黄金标准:

  • PostGIS:最成熟的开源地理空间数据库扩展
  • 空间索引:高效的 GiST 和 SP-GiST 索引
  • 路径规划:pgRouting 提供路径规划和网络分析
  • 坐标转换:支持数千种空间参考系统

时间序列:玩转时序时态

基于时间的数据处理,时态表,调度

PostgreSQL 为时间序列数据提供强大支持:

  • TimescaleDB:时间序列数据库扩展
  • 时态表:SQL 标准的时态数据功能
  • 分区表:按时间自动分区以优化性能
  • 压缩存储:时间序列数据的高效压缩

多语言词典,混合搜索功能

PostgreSQL 内置强大的全文搜索功能:

  • 多语言支持:内置多种语言的词典和分词器
  • 模糊搜索:支持相似性搜索和拼写纠错
  • 排序算法:tf-idf 和其他相关性排序
  • 搜索高亮:查询结果的文本高亮显示

存储过程:语言任君选择

20+ 编程语言支持数据库开发

PostgreSQL 支持多种编程语言编写存储过程:

  • PL/pgSQL:PostgreSQL 原生过程语言
  • Python:通过 PL/Python 支持 Python 编程
  • JavaScript:PL/V8 提供 JavaScript 支持
  • 其他语言:支持 Perl、Tcl、R、Java 等多种语言

外表封装:打通数据孤岛

统一 SQL 访问异构数据源

Foreign Data Wrapper (FDW) 允许访问外部数据:

  • 多数据源:连接 MySQL、Oracle、MongoDB 等
  • 文件系统:直接查询 CSV、JSON、Parquet 文件
  • API 集成:通过 HTTP FDW 访问 REST API
  • 统一查询:在单个 SQL 中查询多个数据源

从 HTTP 请求到 Web 应用开发的多样化扩展

PostgreSQL 生态系统提供丰富的功能扩展:

  • HTTP 客户端:在数据库中直接发送 HTTP 请求
  • 消息队列:pg_mq 提供消息队列功能
  • 作业调度:pg_cron 实现定时任务调度
  • Web 服务:PostgREST 将数据库表自动转换为 REST API

6.2 - 可依赖性

安全可靠的基础设施

稳如泰山,坚若磐石,在极端场景下也能保持安全可靠的运行

极致可用
    HA PostgreSQL
故障自愈
    自适应服务接入
删库兜底
    预置时间点恢复
自给自足
    没有外部依赖
访问控制
    模型开箱即用
坚如磐石
    机密性保障
精益求精
    完整性校验
实战检验
    可用性标杆

极致可用:HA PostgreSQL

通过 PostgreSQL 物理复制实现业界领先的高可用性
针对特定场景的可调 RTO 和 RPO 指标

Pigsty 实现了业界领先的高可用架构:

  • 自动故障转移:基于 Patroni 的自动主从切换
  • 零数据丢失:同步复制确保数据安全
  • 快速恢复:RTO < 30秒,RPO = 0 的高可用承诺
  • 多层冗余:从硬件到软件的全栈高可用设计

故障自愈:自适应服务接入

透明的主从拓扑
故障转移期间的自动流量重定向
与行业 HA 最佳实践集成

智能的服务发现和流量管理:

  • 服务发现:HAProxy + Consul 的动态服务发现
  • 健康检查:多层次健康检查确保服务可用性
  • 流量切换:故障时自动切换到备用节点
  • 透明访问:应用无需感知底层拓扑变化

删库兜底:预置时间点恢复

默认备份和 WAL 归档
支持本地和远程冷备份策略
一键备份和恢复

完整的数据保护解决方案:

  • 连续归档:WAL 日志实时归档保护
  • 定期备份:自动化的基础备份调度
  • PITR 恢复:可恢复到任意时间点
  • 多存储后端:支持本地、S3、MinIO 等存储

自给自足:没有外部依赖

完整的 PostgreSQL RDS 基础设施闭环
本地软件源确保运营自主性

完全自包含的部署方案:

  • 本地软件源:内置完整的软件包仓库
  • 离线部署:无需互联网连接即可完成部署
  • 版本锁定:确保软件版本一致性和稳定性
  • 安全隔离:无外部依赖降低安全风险

访问控制:模型开箱即用

预定义角色:只读、读写、管理员、分析
遵循最小权限原则
同步连接池凭据

企业级的访问控制机制:

  • 角色模板:预定义的数据库角色模板
  • 权限分离:按业务需求划分访问权限
  • 连接池集成:与 PGBouncer 无缝集成
  • 审计日志:完整的用户操作审计记录

坚如磐石:机密性保障

自签名 CA,端到端 SSL 加密
密码保护的备份
严格的访问间隔控制

全方位的数据安全保护:

  • 传输加密:SSL/TLS 加密所有网络通信
  • 存储加密:支持数据文件透明加密
  • 证书管理:自动化的 SSL 证书管理
  • 网络隔离:基于 IP 白名单的访问控制

精益求精:完整性校验

数据校验和防护
多副本和延迟副本保护
审计插件日志记录

多层次的数据完整性保障:

  • 数据校验:页面级别的数据校验和
  • 复制校验:主从数据一致性校验
  • 备份校验:备份文件完整性检查
  • 审计追踪:完整的数据变更审计日志

实战检验:可用性标杆

在大型组织中得到验证
滚动升级,最少停机时间
关键组件中的冗余

经过生产环境验证的稳定性:

  • 生产验证:在大规模生产环境中验证
  • 滚动升级:零停机的在线升级能力
  • 故障演练:定期的灾难恢复演练
  • 性能基准:持续的性能监控和优化

6.3 - 可观测性

洞若观火的图形界面

大局在胸,细微在握,为数字化管理与智能化运维提供坚实的支撑

开箱即用
    自带监控基础设施
数据驱动
    为数智化转型奠基
极致体验
    PG监控版本答案
通用监控
    不仅是PG与RDS
自动告警
    告别DBA人肉盯盘
性能优化
    慢查询瓶颈轻松查
日志分析
    快速定位故障根因
大屏报表
    低代码可视化开发

开箱即用:自带监控基础设施

提供即用的 Prometheus & Grafana 可观测技术栈
自动对象发现,企业级监控无需额外配置

Pigsty 内置完整的可观测性基础设施:

  • Prometheus 技术栈:完整的指标收集、存储和查询
  • Grafana 仪表板:200+ 预配置的专业仪表板
  • 自动发现:无需配置的服务和目标自动发现
  • 企业级功能:告警、通知、用户管理开箱即用

数据驱动:为数智化转型奠基

将数千个指标处理成精心设计的仪表板
从宏观到微观的全方位系统状态可见性

完整的数据驱动管理体系:

  • 全栈监控:从硬件到应用的完整监控栈
  • 指标体系:数千个精心设计的监控指标
  • 数据血缘:清晰的数据流向和依赖关系
  • 决策支持:基于数据的运维决策支持

极致体验:PG监控版本答案

五级联动:全局/集群/实例/数据库/对象
精细的历史指标,深入到单个数据库对象

业界领先的 PostgreSQL 监控体验:

  • 五级钻取:从全局视图深入到对象级别
  • 实时监控:毫秒级的实时数据更新
  • 历史分析:长期历史数据的趋势分析
  • 对象级监控:表、索引级别的细粒度监控

通用监控:不仅是PG与RDS

可以监控云 RDS、PostgreSQL 兼容服务
支持监控主机、数据库、应用程序、负载均衡器

广泛的监控能力覆盖:

  • 多数据库:支持各种 PostgreSQL 变体和 RDS
  • 混合环境:云端和本地环境统一监控
  • 基础设施:服务器、网络、存储全面监控
  • 应用监控:应用层面的性能和业务指标

自动告警:告别DBA人肉盯盘

经过验证的预配置告警规则集
56 个预设告警覆盖所有 Pigsty 模块

智能化的告警体系:

  • 预设规则:基于最佳实践的告警规则
  • 分级告警:根据严重程度分级处理
  • 多渠道通知:邮件、短信、钉钉、微信通知
  • 告警抑制:智能的告警合并和抑制机制

性能优化:慢查询瓶颈轻松查

识别资源消耗的慢查询
集成 pg_stat_statements 和 auto_explain 进行查询分析

深度的性能分析能力:

  • 慢查询分析:自动识别和分析慢查询
  • 执行计划:查询执行计划的可视化分析
  • 资源消耗:CPU、内存、IO 等资源使用分析
  • 优化建议:基于分析结果的优化建议

日志分析:快速定位故障根因

使用 Loki 和 Promtail 统一日志收集
像搜索引擎一样轻松检索和过滤日志

强大的日志分析系统:

  • 统一收集:所有组件日志的统一收集
  • 实时搜索:ElasticSearch 级别的日志搜索
  • 关联分析:日志与指标的关联分析
  • 故障溯源:快速的问题根因定位

大屏报表:低代码可视化开发

使用 PostgreSQL、Grafana、Echarts 的低代码可视化
交互式数据应用原型开发

灵活的可视化开发平台:

  • 低代码开发:拖拽式的仪表板开发
  • 丰富组件:多样化的可视化组件库
  • 交互式设计:支持复杂的交互式分析
  • 快速原型:快速的数据应用原型开发

6.4 - 可伸缩性

性能澎湃的弹性服务

水行万变,张弛自如,滔天流量洪峰涌于眼前而丝毫不怵

性能澎湃
    新硬件红利尽享
读写分离
    读请求无限扩容
链接池化
    高并发手到擒来
负载均衡
    控制台流量管控
水平扩展
    分布式原地改造
存储扩容
    外部表透明压缩
批量管理
    大规模集群部署
弹性伸缩
    云计算他山之石

性能澎湃:新硬件红利尽享

PostgreSQL 的"令人惊叹的可伸缩性"
可以处理大规模事务处理

充分发挥现代硬件的极致性能:

  • 单机极限:200万行/秒查询速率
  • 写入性能:100万行/秒写入速率
  • 表容量:单表支持 32TB 容量
  • 硬件优化:针对 NVMe SSD 和多核 CPU 优化

读写分离:读请求无限扩容

支持无限制的只读副本级联
支持只读和离线服务路由
可以实现"一主三十从"

灵活的读写分离架构:

  • 级联复制:支持多级复制拓扑
  • 读负载分发:智能的读请求负载均衡
  • 离线查询:专用的分析查询副本
  • 异步复制:低延迟的异步数据同步

链接池化:高并发手到擒来

内置 PGBouncer
将数千个并发连接转换为最少的活动连接
自动配置同步

高效的连接管理机制:

  • 连接复用:大幅降低数据库连接开销
  • 并发控制:支持数千并发连接
  • 智能路由:基于负载的连接路由
  • 配置同步:连接池配置自动同步

负载均衡:控制台流量管控

HAProxy Web 控制台实时流量管理
支持滚动连接排空
实现无缝在线迁移

专业的流量管理能力:

  • 实时控制:Web 界面的实时流量控制
  • 滚动迁移:零停机的服务迁移
  • 健康检查:智能的后端健康检测
  • 流量分配:精细的流量权重控制

水平扩展:分布式原地改造

Citus 扩展用于分布式 PostgreSQL
支持多租户、多写入场景
在线分片重平衡

强大的分布式扩展能力:

  • 分布式查询:跨节点的并行查询处理
  • 自动分片:数据的自动分片和分布
  • 在线扩容:无停机的集群扩容
  • 多租户支持:原生的多租户数据隔离

存储扩容:外部表透明压缩

透明压缩(10:1 比率)
外部表和对象存储集成
支持冷热数据分离

灵活的存储扩展方案:

  • 数据压缩:高达 10:1 的压缩比率
  • 分层存储:热数据本地,冷数据对象存储
  • 透明访问:应用无感知的数据访问
  • 成本优化:基于数据访问模式的成本优化

批量管理:大规模集群部署

为极端规模而设计
基于 Ansible 的大规模操作
最大部署:25,000 vCPU,3000+ 实例

企业级的大规模管理能力:

  • 批量操作:支持数千节点的批量管理
  • 自动化运维:基于 Ansible 的自动化操作
  • 模板化部署:标准化的部署模板
  • 监控覆盖:大规模集群的统一监控

弹性伸缩:云计算他山之石

云服务器部署支持
灵活的多云策略
基线购买,峰时租赁模型

云原生的弹性扩缩能力:

  • 多云支持:AWS、阿里云、腾讯云等多云部署
  • 弹性计算:基于负载的自动扩缩容
  • 混合云架构:本地与云端的混合部署
  • 成本优化:按需使用的成本控制模型

6.5 - 可维护性

简明易用的工具实践

人生苦短,关爱运维,以最小的复杂度代价最大化可操作性与可演化性

言出法随
    基础设施即代码
简单易用
    几分钟快速上手
裸机运行
    无需容器与K8S
离线安装
    稳定顺畅的交付
体系配套
    开发规约与SOP
无需停服
    在线迁移与变配
按需配置
    丰富的定制参数
沙箱环境
    一键置备服务机

言出法随:基础设施即代码

Pigsty 采用声明式 API,让数据库部署和运维如写代码般灵活。支持 GitOps、批量管理和 PostgreSQL CMDB

Infrastructure as Code 的最佳实践:

  • 声明式配置:YAML 配置文件描述期望状态
  • GitOps 工作流:通过 Git 管理配置变更
  • 批量管理:一套配置管理数千个实例
  • 版本控制:配置的版本化管理和回滚

简单易用:几分钟快速上手

一键下载安装,几分钟部署上线,一行命令搞定所有步骤。提供各种场景的开箱即用配置模板

极致的用户体验设计:

  • 一键安装:单条命令完成全部安装
  • 智能配置:自动检测环境并生成配置
  • 场景模板:针对不同场景的预设模板
  • 文档完善:详细的操作指南和最佳实践

裸机运行:无需容器与K8S

运行于 Linux 裸系统上,避免 Docker 和 Kubernetes 的额外复杂度
支持主流 Linux 发行版和架构

简单可靠的部署方式:

  • 原生部署:直接运行在 Linux 系统上
  • 多发行版支持:RHEL、Ubuntu、Debian 等
  • 多架构支持:x86_64、ARM64 架构
  • 资源高效:无容器开销的资源利用

离线安装:稳定顺畅的交付

提供离线安装包,可在无网络环境中一键完成自举安装
确保软件版本一致性,避免依赖问题

企业级的交付保障:

  • 离线包:完整的离线安装包
  • 版本锁定:确保软件版本一致性
  • 依赖完整:包含所有必需依赖
  • 快速部署:无需网络的快速部署

体系配套:开发规约与SOP

将顶级 DBA 经验提炼为统一的开发运维指南

完整的运维体系建设:

  • 标准规范:统一的开发和运维规范
  • 操作手册:详细的 SOP 操作手册
  • 最佳实践:经过验证的最佳实践集合
  • 培训体系:完整的技能培训体系

无需停服:在线迁移与变配

依托基于逻辑复制的蓝绿部署方案,实现不停机在线迁移
支持滚动维护和精细的流量管理

零停机的运维能力:

  • 蓝绿部署:基于逻辑复制的零停机迁移
  • 滚动升级:服务的渐进式升级
  • 在线扩容:无停机的容量扩展
  • 流量控制:精细的流量管理和切换

按需配置:丰富的定制参数

近 300+ 可配置参数,默认值即可满足绝大多数场景
支持多层级配置,丰富的文档说明

灵活的配置管理系统:

  • 参数丰富:300+ 可调节的配置参数
  • 默认优化:开箱即用的优化默认值
  • 分层配置:全局、集群、实例多层配置
  • 文档详尽:每个参数都有详细说明

沙箱环境:一键置备服务机

自带沙箱环境,可在单台笔记本上完整体验

快速的环境置备能力:

  • 沙箱模式:单机完整功能演示
  • 快速体验:5分钟快速体验完整功能
  • 开发环境:本地开发测试环境
  • 云主机集成:与云平台无缝集成

6.6 - 可组合性

灵活搭配的积木组件

灵活拼装,化繁为简,用模块化的积木组合出千变万化的服务

自由拼装
    模块化乐高设计
软件模板
    企业级应用一键建
核心模块
    功能完备PG RDS
扩展模块
    拓展能力边界
内核模块
    可替换数据库引擎
数仓模块
    强大数据分析能力
试点模块
    前沿边界的探索
风味模块
    Postgres玩出花

自由拼装:模块化乐高设计

模块化设计,像乐高积木一样自由组合组件
声明式配置,用于定制基础设施和数据库环境

  • 开箱即用的高可用集群(PGSQL + ETCD)
  • 无限存储的集中备份(MINIO + PGSQL)
  • 独立数据库监控(INFRA + NODE)
  • 网站托管和数据可视化(INFRA + PGSQL)

软件模板:企业级应用一键建

可选的 Docker 模块,带有 Compose 模板
可销毁的无状态容器,状态持久化在外部 HA PGSQL 中

  • 企业应用:GitLab、Odoo、Dify
  • 高级数据库:Supabase、Neon、EdgeDB
  • 数据库管理工具:PGAdmin、Bytebase、PGWEB

核心模块:功能完备PG RDS

4 个核心模块协同工作,构建完整的 PostgreSQL RDS
可扩展、灵活的组合,无额外依赖

  • PGSQL:具有 HA、PITR、IaC、监控、437 扩展的 PG 集群
  • INFRA:Nginx、本地仓库、Prometheus 和 Grafana 堆栈、DNS、NTP
  • NODE:节点管理、仓库、包、VIP、日志、NTP
  • ETCD:PG 高可用的分布式配置存储

扩展模块:拓展能力边界

与 PostgreSQL 配合出色的组件
完全可选,按需安装

  • MINIO:S3 兼容对象存储,可选的 PG 备份仓库
  • REDIS:各种模式下的高性能字典服务器
  • FERRET:PostgreSQL 的 MongoDB 协议兼容性

内核模块:可替换数据库引擎

普通 PostgreSQL 内核的可选替换
提供不同的数据库兼容性

  • Babelfish:来自 AWS 的 Microsoft SQL Server 协议兼容 PG
  • IvorySQL:来自海高的 Oracle 兼容 PostgreSQL 17 内核
  • OpenHalo:由 HaloTech 开发的 MySQL 协议兼容 PG 内核
  • OrioleDB:无 xid 环绕和表膨胀的新存储引擎

数仓模块:强大数据分析能力

DuckDB 集成展示
Greenplum 衍生版本的安装和监控支持

  • CITUS:PostgreSQL 的原生分布式 HTAP 扩展
  • DUCKDB:带有 5 个 PG 扩展的嵌入式 OLAP 内核
  • GREENPLUM:具有 EL 监控的 MPP 数据仓库(PG 12)
  • CLOUDBERRY:来自原 GPSQL 团队的 PG 14 兼容版本

试点模块:前沿边界的探索

与 PostgreSQL 无关
实验性能力探索

  • KUBE:使用 SealOS 的 Kubernetes 设置,部署支持
  • KAFKA:由 KRaft 驱动的消息队列
  • MYSQL:单节点 MySQL 8.0 支持
  • VICTORIA:指标和日志的基础设施替代方案

风味模块:Postgres玩出花

原生 PostgreSQL 上的多样化包装器和功能
探索后端即服务、无服务器和数据库内 Web 开发

  • SUPA:Firebase 开源替代方案
  • NEON:具有数据库分支的无服务器 PostgreSQL
  • EDGE:具有强大查询语言的 PostgreSQL
  • OMNI:针对特定用例扩展的 PostgreSQL

6.7 - 可控制性

自主可控的开源软件

脚踏实地,仰望星空,用开源软件的信仰捍卫真正的软件自由

自由软件
    民主化自建能力
本地优先
    运营到地老天荒
多云部署
    再无供应商锁定
扩展自由
    海量扩展随心装
掌控数据
    真正自主掌控
二次开发
    撸起袖子自己上
信创合规
    国产化顺势而为
专业服务
    顶级专家来兜底

自由软件:民主化自建能力

100% 基于开源组件
继承 AGPLv3 自由精神
“普及自建顶级数据库服务的能力”

真正的软件自由:

  • 开源基因:100% 基于开源软件构建
  • 自由许可:AGPLv3 保障软件自由
  • 无专利风险:避免专有软件的法律风险
  • 社区驱动:开放透明的开发模式

本地优先:运营到地老天荒

可以离线和独立运行
本地软件仓库与版本快照
“离线断网也能独立运转至地老天荒”

完全自主的运行能力:

  • 离线运行:无需依赖外部网络服务
  • 版本锁定:本地软件仓库确保版本一致
  • 自给自足:完整的软件依赖闭环
  • 持续运营:长期稳定的独立运行

多云部署:再无供应商锁定

数据库 PaaS 自建
拒绝供应商锁定
使用 Terraform 进行跨云资源置备

真正的多云自由:

  • 跨云部署:支持所有主流云平台
  • 统一管理:跨云环境的统一管理
  • 自由迁移:云平台间的自由迁移
  • 议价权力:拥有真正的选择权

扩展自由:海量扩展随心装

提供 437 PostgreSQL 扩展
支持 RPM/DEB 软件包
“不再忍受云厂商安全策略/开源协议的桎梏”

丰富的扩展生态:

  • 扩展完整:437 PostgreSQL 扩展
  • 安装简便:标准软件包管理
  • 无限制使用:无云厂商策略限制
  • 持续更新:扩展的持续维护和更新

掌控数据:真正自主掌控

合理的资源定价
数据库超级用户权限
绕过 RDS 支持官僚主义

完全的数据主权:

  • 数据所有权:完全的数据控制权
  • 超级用户权限:不受限制的数据库访问
  • 透明定价:清晰的资源成本
  • 无中间商:直接的技术支持

二次开发:撸起袖子自己上

AGPLv3 许可证允许修改
对不同用户类型灵活
支持 DBaaS 和 OEM 用例

灵活的开发自由:

  • 代码修改权:完全的源码修改权利
  • 商业友好:支持各种商业用例
  • 定制开发:深度的产品定制能力
  • 技术独立:摆脱技术依赖

信创合规:国产化顺势而为

PostgreSQL 扩展项目排名第一
支持 PolarDB v2.0 内核
符合国产操作系统/芯片架构

完整的信创支持:

  • 国产适配:支持国产操作系统和芯片
  • 合规认证:满足信创合规要求
  • 本土化:完整的本土化支持
  • 安全可控:自主可控的技术栈

专业服务:顶级专家来兜底

顶级 PostgreSQL 专家支持
经济的订阅模式
提供保修和广泛支持

专业的技术保障:

  • 专家团队:顶级 PostgreSQL 专家
  • 及时响应:快速的技术支持响应
  • 深度服务:从咨询到实施的全程支持
  • 质量保证:专业的服务质量保证

6.8 - 可承担性

降本增效的自建方案

雷震天地,破而后立,以极致的性价比掀翻公有云数据库的饭桌!

开源免费
    用好PostgreSQL
财务降本
    逃离RDS杀猪盘
人力增效
    人人都能是DBA
简化架构
    无需云原生全家桶
赋能下云
    解决自建关键卡点
社区支持
    交流讨论共建
咨询服务
    会者不难按需付费
订阅服务
    明码标价物有所值

开源免费:用好PostgreSQL

开源不等于免费,但用好了肯定更省钱
解决云数据库和DBA成本问题

开源不等于免费,有效使用可能代价昂贵。不同 PostgreSQL 托管解决方案及其成本比较:

  • Oracle 许可证 + 支持费用:约 $3,878 / 年·vCPU
  • AWS RDS PG 费用:约 $1,920 ~ $2,640 / 年·vCPU
  • Pigsty 开源版本免费,硬件成本约 $27/年·vCPU

财务降本:逃离RDS杀猪盘

相比云数据库服务节省 50% ~ 95%+ 的费用
从云数据库到本地自建成本大幅下降

云数据库杀猪盘的真相:

  • RDS 成本可达 $2,000-$2,600/年·vCPU
  • 在云 EC2 上自托管,保持弹性并节省 RDS 成本
  • 在 IDC 自托管:深度利用 Gen5 SSD 等尖端硬件

人力增效:人人都是DBA

沉淀顶级DBA经验
初级研发与运维可发挥中高级DBA效果

经济实惠的人力成本,将开发人员和运维人员转变为 DBA:

  • 封装来自真实世界故障的精英 DBA 专业知识
  • 初级开发和运维人员通过合适的工具可以表现为中高级 DBA
  • 无需数据库专家即可构建企业级 RDS 服务

简化架构:无需云原生全家桶

使用熟悉的 Ansible
获得云原生好处,避免复杂度

简单性很重要,无需使用容器和 kubernetes:

  • 云原生优势,无复杂性
  • 无需 K8s 和数据库的稀有专家
  • 通常只需要担心:空间满了就加磁盘

赋能下云:解决自建关键卡点

摆脱供应商锁定
获得真正的选择权和议价权

传统公有云服务正在迅速失去其价值主张:

  • 不再依赖云服务 - 拥有您的基础设施
  • 具有自建能力的客户拥有真正的选择
  • 数据库对云迁出至关重要,Pigsty 提供 FOSS RDS 替代方案

社区支持:交流讨论,生态共建

活跃的用户社区
免费公益答疑

活跃的用户社区,提供免费的公共问答支持:

  • 在 GitHub Issue 中提问,报告错误和缺陷
  • 加入微信、Telegram 和 Discord 群组
  • 每月办公时间收集反馈并回答问题

咨询服务:会者不难,按需付费

快速面诊
专业咨询和支持

按需提供专业咨询服务:

  • 快速咨询:“一杯咖啡或一点运气”
  • 专业咨询:$400 / 案例,约一小时
  • 支持人日:$4K / 天,完整工作日

订阅服务:明码标价,物有所值

多个版本选择
从免费到企业级,满足不同需求

透明的订阅定价,价值主张明确:

  • 标准版:基本支持和更新
  • 专业版:增强功能和优先支持
  • 企业版:完整功能访问,专门支持

7 - 关键特性

关键特性和亮点
条目
      href="/zh/docs/intro/distro">
    将 PostgreSQL 用于一切! \
    用组装的超能力构建数据基础设施!
面向运维的 RDS 解决方案
    像专家一样自托管 PostgreSQL! \
    无需专业知识即可运营生产级服务

Postgres 扩展
    开箱即用地获得 **437** PG 扩展的超能力
高可用性
    自愈架构和无忧服务访问
内核替换
    在 PGSQL 之上模拟 MySQL、Mongo、Oracle、SQL Server
灾难恢复
    自动配置备份和简化的 PITR
基础设施即代码
    用代码 / 数据描述和实现一切
内置监控
    使用 Grafana 和 Prometheus 技术栈的预配置仪表板
自托管 Supabase
    将 Postgres 转变为全功能的后端即服务
应用模板
    使用 HA PG 强化软件:Gitlab、Odoo、Dify 等

7.1 - PG 扩展

获得 437 个开箱即用的扩展

Pigsty 允许您通过三个组件来利用 PostgreSQL 扩展生态系统的协同超能力:

  • 目录:查找您需要的扩展,包含无与伦比的 437 个扩展
  • 仓库:为 10 个主流 Linux 操作系统获取预制的 RPM/DEB 包
  • 包管理器:使用单个命令安装一切 - pig

另外查看我们的博客文章:PostgreSQL is eating the Database World

ecosystem


扩展

TIME GIS RAG FTS OLAP FEAT LANG TYPE
UTIL FUNC ADMIN STAT SEC FDW SIM ETL

类别 数量 描述
TIME 11 TimescaleDB、版本控制与时态表、Crontab、异步与后台作业调度器
GIS 20 地理空间数据类型、操作符和索引、六边形索引、OGR 数据 FDW、GeoIP 与 MobilityDB
RAG 10 具有 IVFFLAT、HNSW、DiskANN 索引的向量数据库、SQL 接口中的 AI 和 ML、相似性函数
FTS 20 ElasticSearch 替代品,具有 BM25、2-gram/3-gram 模糊搜索、Zhparser 与 Hunspell 分词词典
OLAP 13 DuckDB 与 FDW 和 PG Lakehouse 集成、从文件/S3 访问 Parquet、使用 Citus/Partman/PlProxy 分片
FEAT 56 AGE 的 OpenCypher、GraphQL、JsonSchema、Hints 与 Hypo Index、HLL、Rum、IVM、ChemRDKit 和消息队列
LANG 31 开发、测试、打包和交付用各种 PL/语言编写的存储过程:Java、Js、Lua、R、Sh、PRQL
TYPE 37 专用新数据类型如:prefix、sember、uint、SIUnit、RoaringBitmap、Rational、Sphere、Hash、RRule
UTIL 31 实用工具如发送 HTTP 请求、执行 gzip/zstd 压缩、发送邮件、正则表达式、ICU、编码、文档、加密
FUNC 43 函数如 ID 生成器、聚合、草图、向量函数、数学函数和摘要函数
ADMIN 36 膨胀控制、脏读、缓冲区检查、DDL 生成、校验和验证、权限、优先级、目录的实用工具
STAT 34 可观测性目录、监控指标和视图、统计、查询计划、等待采样、慢日志
SEC 26 审计日志、强制密码、保持机密、TDE、SM 算法、登录钩子、日志错误、扩展白名单
FDW 22 FDW 开发的包装器和 Multicorn、访问其他 DBMS:MySQL、Mongo、SQLite、MSSQL、Oracle、HDFS、DB2
SIM 16 协议模拟和异构 DBMS 兼容性:Oracle、MSSQL、DB2、MySQL、Memcached 和 Babelfish
ETL 17 逻辑复制、解码、protobuf/JSON/Mongo 格式的 CDC、复制和加载及比较 Postgres 数据库

仓库

Pigsty 有一个仓库,在 10 个主流 Linux 发行版 上提供 200+ 个额外的 PostgreSQL 扩展。 它被设计为与官方 PostgreSQL 全球开发组(PGDG)仓库一起工作。

您可以使用 pig CLI 工具启用 pigsty infra 和 pgsql 仓库,或手动将它们添加到您的系统:

curl https://repo.pigsty.io/pig | bash      # 下载并安装 pig CLI 工具
pig repo add all -u                         # 添加 linux、pgdg、pigsty 仓库并更新缓存
# 将 Pigsty 的 GPG 公钥添加到您的系统密钥链以验证包签名
curl -fsSL https://repo.pigsty.io/key | sudo gpg --dearmor -o /etc/apt/keyrings/pigsty.gpg

# 获取 Debian 发行版代号(distro_codename=jammy、focal、bullseye、bookworm),并将相应的上游仓库地址写入 APT List 文件
distro_codename=$(lsb_release -cs)
sudo tee /etc/apt/sources.list.d/pigsty-io.list > /dev/null <<EOF
deb [signed-by=/etc/apt/keyrings/pigsty.gpg] https://repo.pigsty.io/apt/infra generic main
deb [signed-by=/etc/apt/keyrings/pigsty.gpg] https://repo.pigsty.io/apt/pgsql/${distro_codename} ${distro_codename} main
EOF

# 刷新 APT 仓库缓存
sudo apt update
# 将 Pigsty 的 GPG 公钥添加到您的系统密钥链以验证包签名
curl -fsSL https://repo.pigsty.io/key | sudo tee /etc/pki/rpm-gpg/RPM-GPG-KEY-pigsty >/dev/null

# 将 Pigsty 仓库定义文件添加到 /etc/yum.repos.d/ 目录,包括两个仓库
sudo tee /etc/yum.repos.d/pigsty-io.repo > /dev/null <<-'EOF'
[pigsty-infra]
name=Pigsty Infra for $basearch
baseurl=https://repo.pigsty.io/yum/infra/$basearch
skip_if_unavailable = 1
enabled = 1
priority = 1
gpgcheck = 1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-pigsty
module_hotfixes=1

[pigsty-pgsql]
name=Pigsty PGSQL For el$releasever.$basearch
baseurl=https://repo.pigsty.io/yum/pgsql/el$releasever.$basearch
skip_if_unavailable = 1
enabled = 1
priority = 1
gpgcheck = 1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-pigsty
module_hotfixes=1
EOF

# 刷新 YUM/DNF 仓库缓存
sudo yum makecache;

所有 RPM / DEB 包都使用 Pigsty 仓库中的 GPG 密钥 指纹(B9BD8B20)签名。


包管理器

“Postgres 安装天才,PostgreSQL 生态系统缺失的扩展包管理器”

在几秒钟内 开始使用 PIG:

curl -fsSL https://repo.pigsty.io/pig | bash
curl -fsSL https://repo.pigsty.cc/pig | bash

然后就可以使用了,假设您想安装 pg_duckdb 扩展:

$ pig repo add pigsty pgdg -u  # 添加 pgdg 和 pigsty 仓库,然后更新仓库缓存
$ pig ext install pg18         # 使用原生 PGDG 包安装 PostgreSQL 18 内核
$ pig ext install pg_duckdb    # 安装 pg_duckdb 扩展(用于当前的 pg18)

7.2 - PG 内核分支

模拟其他数据库管理系统,用特殊分支替换普通 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 线缆协议兼容的内核


选择合适的内核

说明

灵活内核:为您的特定用例选择合适的内核 - 无论您需要 MSSQL 兼容性、Oracle 功能还是水平扩展能力。

内核 关键特性 描述
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)

说明

SQL Server 兼容

说明

Beta

使用 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)

说明

Oracle 兼容

说明

社区版

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

关键特性

  • Oracle 语法支持:支持 Oracle SQL 语法和 PL/SQL
  • 数据类型兼容:Oracle 数据类型映射和行为
  • 包支持:Oracle 风格的包和过程
  • 内置函数:Oracle 兼容的内置函数库
  • 迁移友好:简化从 Oracle 的迁移过程

使用场景

  • Oracle 到 PostgreSQL 的数据库迁移
  • 降低 Oracle 许可成本
  • 遗留 Oracle 应用程序现代化
  • 需要 Oracle 功能的新项目

OpenHalo(MySQL)

说明

MySQL 兼容

说明

实验性

OpenHalo 提供 MySQL 协议兼容性,允许 MySQL 应用程序和工具连接到 PostgreSQL。

关键特性

  • MySQL 协议:与 MySQL 客户端和驱动程序兼容
  • SQL 方言:支持 MySQL 特定的 SQL 语法
  • 函数映射:MySQL 函数到 PostgreSQL 等效项的映射
  • 连接器支持:与现有 MySQL 工具和连接器工作

OrioleDB(云原生)

说明

云原生存储

说明

开发中

OrioleDB 是一个云原生存储引擎,为现代云环境优化,提供无膨胀存储和 S3 集成。

关键特性

  • 无膨胀存储:消除 PostgreSQL 传统的膨胀问题
  • 云存储集成:原生 S3 存储支持
  • OLTP 优化:为事务性工作负载优化
  • 现代架构:为云原生环境设计

PolarDB PG(共享存储)

说明

共享存储

说明

企业版

PolarDB for PostgreSQL 提供类似 Aurora 的共享存储架构,具有中国国产化特性。

关键特性

  • 共享存储:计算与存储分离架构
  • 读写分离:多个只读实例共享存储
  • 快速扩容:快速添加只读实例
  • 国产化:符合中国信创要求

Supabase(BaaS)

说明

后端即服务

说明

开源

Supabase 将 PostgreSQL 转换为完整的后端即服务平台,提供 Firebase 的开源替代方案。

关键特性

  • 实时数据库:实时订阅和同步
  • 认证服务:内置用户认证系统
  • 存储服务:文件存储和 CDN
  • 边缘函数:无服务器函数支持
  • 仪表板:Web 管理界面

Greenplum(数据仓库)

说明

MPP 架构

说明

企业版

Greenplum 是基于 PostgreSQL 的大规模并行处理数据仓库,专为分析性工作负载设计。

关键特性

  • MPP 架构:大规模并行处理
  • 列式存储:优化分析查询性能
  • 分布式计算:跨节点并行查询执行
  • ETL 工具:内置数据加载和转换工具
  • 企业功能:备份、恢复和高可用性

通过选择合适的 PostgreSQL 内核分支,您可以在保持 PostgreSQL 生态系统优势的同时获得特定的功能和兼容性。每个内核都为不同的使用场景和迁移需求提供了解决方案。

7.3 - 可观测性基础设施

具有 3000+ 指标、30+ 仪表板和企业级监控的现代可观测性堆栈

Pigsty 提供 无与伦比的可观测性,具有基于行业最佳实践构建的现代监控堆栈。 自动监控每个组件,具有 3000+ 指标30+ 仪表板

说明

完整洞察:从高级集群健康到单个表统计的所有内容进行监控。完整洞察您基础设施的过去、现在和未来。

架构概述

Pigsty 的可观测性基础设施在一个连贯的、生产就绪的堆栈中利用经过实战考验的开源组件:

Grafana 可视化引擎

具有高级交互式可视化的仪表板

Prometheus 指标数据库

具有强大查询语言的时间序列存储

Loki 日志平台

具有基于标签索引的集中式日志记录

AlertManager

告警聚合、管理和升级

服务架构

graph TB
    subgraph "Observability Stack"
        Grafana[Grafana :3000]
        Prometheus[Prometheus :9058]
        Loki[Loki :3100]
        AlertManager[AlertManager :9059]
        Pushgateway[Pushgateway :9091]
        Blackbox[Blackbox :9115]
    end

    subgraph "Data Sources"
        PG[(PostgreSQL)]
        Node[Node Metrics]
        Redis[(Redis)]
        MinIO[(MinIO)]
    end

    subgraph "Exporters"
        PGExp[pg_exporter]
        NodeExp[node_exporter]
        RedisExp[redis_exporter]
        MinIOExp[minio_exporter]
    end

    PG --> PGExp
    Node --> NodeExp
    Redis --> RedisExp
    MinIO --> MinIOExp

    PGExp --> Prometheus
    NodeExp --> Prometheus
    RedisExp --> Prometheus
    MinIOExp --> Prometheus

    Prometheus --> Grafana
    Prometheus --> AlertManager
    Loki --> Grafana

监控仪表板

多层级仪表板层次结构

Pigsty 提供按逻辑下钻层次结构组织的 26+ PostgreSQL 仪表板

# 全局概览仪表板
dashboards:
  - Home: 全局集群概览和关键指标
  - INFRA: 基础设施服务状态
  - NODES: 节点级资源利用率
  - Alert: 活跃告警和通知状态

目的:整个环境的高级运营可见性 受众:运营团队、管理仪表板

# 集群焦点仪表板
dashboards:
  - PGSQL Cluster: 集群健康和复制状态
  - PGSQL Service: 服务端点和负载均衡
  - PGSQL Activity: 连接池和查询活动
  - PGSQL Replication: 流复制指标

目的:集群范围的 PostgreSQL 性能和健康 受众:数据库管理员、SRE 团队

# 实例特定仪表板
dashboards:
  - PGSQL Instance: 详细的 PostgreSQL 服务器指标
  - PGSQL Persist: WAL、检查点和持久化
  - PGSQL Proxy: Pgbouncer 连接池指标
  - PGSQL Session: 活跃会话和锁分析

目的:深入了解单个 PostgreSQL 实例 受众:数据库开发人员、性能工程师

# 数据库和对象级仪表板
dashboards:
  - PGSQL Database: 数据库特定性能指标
  - PGSQL Table: 表统计和访问模式
  - PGSQL Query: 查询性能和优化
  - PGSQL Slow: 慢查询分析和调优

目的:应用级数据库性能分析 受众:应用程序开发人员、数据库分析师

仪表板功能

下钻导航

无缝探索 从概览到详细信息,具有上下文链接

时间范围控制

灵活的时间窗口 从实时到数月的历史分析

多维过滤

动态过滤 按集群、实例、数据库或自定义标签

告警集成

可视化告警关联 与指标和告警详情的直接链接


Grafana 部署

增强的 Grafana 堆栈

Pigsty 使用强大的插件和数据源扩展 Grafana,用于高级分析:

# 基本 Grafana 插件
grafana_plugins:
  - grafana-piechart-panel        # 饼图可视化
  - grafana-polystat-panel        # 多值状态面板
  - grafana-worldmap-panel        # 地理可视化
  - grafana-clock-panel           # 时间显示小部件

目的:监控仪表板的基本可视化功能

# 高级可视化插件
grafana_plugins:
  - echarts-panel                 # Apache ECharts 集成
  - volkovlabs-echarts-panel      # 增强的 ECharts 支持
  - volkovlabs-form-panel         # 交互式表单
  - volkovlabs-variable-panel     # 动态变量

目的:用于复杂数据分析的丰富交互式可视化

# 扩展数据源支持
grafana_datasources:
  - infinity-datasource           # REST API 和文件数据源
  - redis-datasource              # Redis 数据源
  - clickhouse-datasource         # ClickHouse 集成
  - postgres-datasource           # 增强的 PostgreSQL 支持

目的:连接到传统指标之外的多样化数据源

# Pigsty 特定定制
custom_features:
  - pigsty-theme                  # 自定义品牌和颜色
  - dashboard-provisioning       # 自动化仪表板部署
  - alert-templates               # 预配置告警规则
  - data-link-automation          # 上下文感知导航

目的:为 PostgreSQL 环境优化的定制用户体验

配置和定制

# 高级 Grafana 配置
grafana_config:
  # 认证
  auth.anonymous.enabled: true
  auth.anonymous.org_role: Viewer
  auth.disable_login_form: false

  # 安全性
  security.allow_embedding: true
  security.cookie_secure: true
  security.cookie_samesite: strict

  # 性能
  database.max_open_conn: 300
  database.max_idle_conn: 300
  database.conn_max_lifetime: 14400

  # 告警
  alerting.enabled: true
  alerting.execute_alerts: true
  unified_alerting.enabled: true

  # 自定义面板
  panels.enable_alpha: true
  feature_toggles.enable: ngalert,live,publicDashboards

Prometheus 堆栈

完整的监控生态系统

Pigsty 部署完整的 Prometheus 生态系统以实现全面的可观测性:

步骤 1

Prometheus 服务器

核心指标数据库 具有高级查询和存储功能

# Prometheus 配置亮点
prometheus_config:
  global:
    scrape_interval: 15s          # 默认抓取频率
    evaluation_interval: 15s      # 规则评估频率
    external_labels:
      cluster: '{{ pg_cluster }}'

  rule_files:
    - "/etc/prometheus/rules/*.yml"

  scrape_configs:
    - job_name: 'node'            # 节点级指标
    - job_name: 'postgres'        # PostgreSQL 指标
    - job_name: 'redis'           # Redis 指标
    - job_name: 'pushgateway'     # 批处理作业指标

步骤 2

AlertManager

智能告警路由 具有抑制、分组和升级功能

# AlertManager 路由配置
alertmanager_routes:
  - match:
      severity: critical
    receiver: pagerduty-critical
    group_wait: 30s
    group_interval: 5m
    repeat_interval: 4h

  - match:
      severity: warning
    receiver: slack-warnings
    group_wait: 1m
    group_interval: 10m
    repeat_interval: 24h

步骤 3

Pushgateway

批处理作业指标收集 用于短暂工作负载和 cron 作业

# 示例:备份作业指标
echo "backup_duration_seconds $(date +%s)" | curl --data-binary @- \
  http://pushgateway:9091/metrics/job/pg-backup/instance/pg-test

步骤 4

Blackbox Exporter

网络连接监控 具有 HTTP、TCP 和 ICMP 探测

# Blackbox 探测配置
blackbox_probes:
  http_2xx:
    prober: http
    timeout: 5s
    http:
      valid_status_codes: [200]

  tcp_connect:
    prober: tcp
    timeout: 5s

预配置告警规则

# PostgreSQL 告警规则示例
alert_rules:
  - alert: PostgreSQLDown
    expr: pg_up == 0
    for: 5m
    labels:
      severity: critical
    annotations:
      summary: "PostgreSQL 实例 {{ $labels.instance }} 已宕机"

  - alert: PostgreSQLHighConnections
    expr: pg_stat_database_numbackends / pg_settings_max_connections > 0.8
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "{{ $labels.instance }} 上连接使用率过高"

  - alert: PostgreSQLReplicationLag
    expr: pg_replication_lag_seconds > 300
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "{{ $labels.instance }} 上复制延迟 > 5 分钟"

pg_exporter:高级 PostgreSQL 监控

自定义指标引擎

Pigsty 的 pg_exporter 是一个高度可定制的 PostgreSQL 指标收集器,支持 所有 PostgreSQL 版本,具有细粒度指标控制:

# pg_exporter 关键功能
features:
  - auto_discovery: true          # 自动数据库发现
  - custom_queries: true          # 用户定义指标查询
  - version_aware: true           # PostgreSQL 版本检测
  - rds_compatible: true          # 云数据库支持
  - label_customization: true     # 灵活的指标标签
  - connection_pooling: true      # 高效连接重用

优势:灵活、轻量级且高度可配置

# PostgreSQL 版本支持矩阵
supported_versions:
  - postgresql_9_6: legacy_metrics_set
  - postgresql_10: enhanced_metrics_set
  - postgresql_11: advanced_metrics_set
  - postgresql_12: modern_metrics_set
  - postgresql_13: extended_metrics_set
  - postgresql_14: latest_metrics_set
  - postgresql_15: cutting_edge_metrics_set
  - postgresql_16: next_gen_metrics_set

好处:异构 PostgreSQL 环境的单一 exporter

# 自定义指标定义示例
custom_queries:
  pg_custom_business_metrics:
    query: |
      SELECT
        schemaname,
        tablename,
        n_tup_ins as inserts_total,
        n_tup_upd as updates_total,
        n_tup_del as deletes_total
      FROM pg_stat_user_tables
    metrics:
      - inserts_total:
          usage: COUNTER
          description: "插入总数"
      - updates_total:
          usage: COUNTER
          description: "更新总数"
# RDS 监控配置
rds_monitoring:
  connection_string: "postgres://monitor:[email protected]:5432/postgres"
  metrics_subset: rds_safe        # 仅 RDS 兼容指标
  auto_discovery: false           # 手动数据库规范
  query_timeout: 30s              # 保守超时

  # RDS 特定指标
  included_databases: [production, staging]
  excluded_schemas: [information_schema, pg_catalog]

主机与基础设施监控

Pigsty v3.7 在受管节点上安装 node_exporter。启用相应模块后,会将 Node、 HAProxy、Keepalived、Nginx、Etcd、MinIO、Redis、PostgreSQL、PgBouncer 与 pgBackRest 目标注册到 Prometheus。端口和开关以 v3.7 标签中的角色默认值及 各模块参数页为准。

外部数据库监控

pgsql-monitor.yml 可注册现有 PostgreSQL 或云 RDS。请提供仅具有必要 pg_monitor 权限的监控连接串;Pigsty 只注册 pg_exporter 与 Grafana 数据源, 不会置备或修改被监控数据库。

./pgsql-monitor.yml -e pg_exporters='{"rds":{"pg_exporter_url":"postgres://dbuser_monitor:[email protected]:5432/postgres"}}'

数据分析与可视化平台

Grafana 既可查询 Prometheus 指标,也可查询 PostgreSQL 数据。内置仪表板通过 变量和 URL 链接实现下钻与上卷;ECharts 等随包提供的插件也可展示应用或 业务数据。

低代码应用开发

Grafana 面板可结合 PostgreSQL 查询构建内部运维视图。这属于可视化能力, 并不是独立的 Pigsty 部署模块或应用 API。

可复用基础设施

infra.yml 可以独立于 PGSQL 部署 INFRA。Nginx、DNSMasq、Prometheus、 AlertManager、Grafana 与 Loki 等服务均由已记录的 *_enabled 参数控制, 因而可以复用既有基础设施或与其共存。

最佳实践

  • 控制指标基数,并根据可用磁盘设置保留周期。
  • 备份 Grafana 配置,定期验证告警通知渠道。
  • 监控端点暴露到可信网络之外时,应配置访问控制与 HTTPS。
  • 监控监控系统本身,并定期检查存储增长。

限制与注意事项

v3.7 的 Prometheus 与 Loki 默认是单节点服务。高指标基数、长保留周期和复杂 仪表板需要额外容量规划。外部长周期存储和高可用监控架构属于人工集成, 不是 v3.7 内置模块。

7.4 - 高可用性

具有自动故障转移和自愈能力的企业级高可用性

Pigsty 使用 Patroni 为 PostgreSQL 实现高可用性,确保自动故障转移。

pigsty-ha
说明

主节点故障 RTO ≈ 30s,RPO < 1MB,副本故障 RTO≈0(重置当前连接)


概述

Pigsty 的 PostgreSQL 集群具有由 PatroniEtcdHAProxy 支持的内置高可用性。

当您在 PostgreSQL 集群中有两个或更多实例时,您就能够从硬件故障中自愈,无需任何进一步配置——只要集群中的任何实例存活,集群就能提供服务。客户端只需连接到集群中的任何节点即可获得完整服务,无需担心复制拓扑变化。

默认情况下,主节点故障的恢复时间目标(RTO)约为 30s ~ 60s,数据恢复点目标(RPO)< 1MB;对于备用节点故障,RPO = 0,RTO ≈ 0(瞬时)。在一致性优先模式下,保证故障转移期间零数据丢失:RPO = 0。这些指标可以根据您的实际硬件条件和可靠性要求 按需配置

Pigsty 集成了 HAProxy 负载均衡器进行自动流量切换,为客户端提供多种访问方法,如 DNS/VIP/LVS。除了偶发的中断外,故障转移和切换对业务端几乎不可感知,这意味着应用程序不需要修改连接字符串或重启。

关键指标

RTO ~ 30s
主节点故障
RPO < 1MB
异步模式 RPO
RTO ~ 0s
副本故障
RPO = 0
同步模式

高可用性解决的问题

高可用性解决关键的运营挑战:

数据安全

提升可用性:RPO ≈ 0,RTO < 30s,增强数据保护

滚动维护

无缝维护:最小化维护窗口,运营便利

硬件故障

自愈能力:无需人工干预即可从硬件故障中自动恢复

负载分布

读扩展:在备用实例间分布只读查询

具体优势

  • 增强数据安全性:将数据安全 CIA 的可用性方面提升到新高度
  • 滚动维护能力:实现最小停机时间的无缝维护
  • 硬件故障恢复:无需人工干预即可从硬件故障中自愈
  • 负载共享:只读请求可以分布在备用实例间

高可用性的成本

实施 HA 会引入某些权衡和要求:

说明

基础设施要求:HA 需要至少 3 个节点 和额外的基础设施依赖。

资源要求

  • 最小集群规模:至少 3 个节点以实现适当的共识
  • 额外基础设施:需要共识存储(Etcd)和负载均衡器
  • 资源开销:额外的 CPU、内存和网络资源
  • 运营复杂性:增加的监控和管理要求

限制

说明

高可用性 无法防止

  • 人为错误和操作失误
  • 导致数据损坏的软件缺陷
  • 逻辑数据删除或损坏

对于这些场景,需要额外的恢复策略:

  • 延迟集群 防护逻辑损坏
  • 时间点恢复 进行细粒度数据恢复
  • 定期备份 用于灾难恢复场景

架构

Pigsty 的 HA 架构利用多组件设计消除单点故障:

Patroni

集群管理:编排 PostgreSQL 进程并处理自动故障转移

Etcd

共识存储:提供分布式配置和领导者选举

HAProxy

负载均衡器:路由流量并提供服务发现

VIP Manager

虚拟 IP:用于无缝连接的可选第二层 VIP 绑定

组件角色

集群编排器

  • 管理 PostgreSQL 服务器进程
  • 处理自动故障转移和切换
  • 监控集群健康和拓扑
  • 配置流复制
  • 提供集群管理 REST API
# Patroni 配置示例
patron:
  name: pg-test-1
  scope: pg-test
  bootstrap:
    dcs:
      ttl: 30
      loop_wait: 10
      retry_timeout: 30

分布式配置存储

  • 存储集群配置和状态
  • 提供领导者选举机制
  • 确保所有节点的一致视图
  • 优雅处理网络分区
  • 维护集群成员信息
# Etcd 集群配置
etcd_cluster: etcd
etcd_safeguard: false

流量路由器和负载均衡器

  • 将读/写流量路由到适当的节点
  • 为数据库实例提供健康检查
  • 提供多个服务端点
  • 处理连接池和负载分布
  • 支持 SSL 终止和连接限制
# HAProxy 服务端点
primary:5433    # 主节点读写流量
replica:5434    # 副本只读流量
default:5436    # 故障转移感知连接
offline:5438    # 专用离线查询

虚拟 IP 管理

  • 管理第二层虚拟 IP 地址
  • 提供无缝客户端连接
  • 在故障转移期间处理 VIP 迁移
  • 支持多个 VIP 接口
  • 用于简化客户端访问的可选组件
# VIP 配置
vip_enabled: true
vip_address: 10.10.10.99/24
vip_interface: eth0

实现

Pigsty 的 HA 实现遵循 PostgreSQL 集群的成熟模式:

复制架构

步骤 1

流复制

PostgreSQL 使用内置流复制在主节点和备用节点之间进行数据同步。

步骤 2

基于共识的领导

Patroni 使用 Etcd 进行分布式共识来选举集群领导者并管理拓扑变化。

步骤 3

自动故障转移

当主节点失败时,Patroni 自动提升最新的备用节点成为新的主节点。

步骤 4

流量重路由

HAProxy 检测拓扑变化并自动将流量路由到新的主实例。

故障场景

主节点故障处理过程

  1. 检测:Patroni 检测主节点故障(15-30 秒)
  2. 领导者选举:Etcd 协调新领导者选择
  3. 提升:最新的备用节点被提升为主节点
  4. 重新配置:剩余的备用节点重新配置到新主节点
  5. 流量切换:HAProxy 将流量重定向到新主节点
说明

写服务中断:故障转移过程中 15-30 秒

备用节点故障处理过程

  1. 检测:立即检测到备用节点故障
  2. 流量重路由:HAProxy 从池中移除故障节点
  3. 服务连续性:只读查询在剩余备用节点上继续
  4. 自动恢复:节点恢复时自动重新加入集群
说明

最小影响:只读查询仅经历短暂中断

网络分区处理

  1. 防止脑裂:Etcd 共识防止多个主节点
  2. 仲裁要求:需要大多数节点进行操作
  3. 优雅降级:少数分区中的只读模式
  4. 自动恢复:分区愈合时恢复正常操作
说明

仲裁依赖:需要大多数共识节点保持运行


权衡

Pigsty 提供可配置参数来平衡恢复速度和数据一致性:

恢复时间目标(RTO)

pg_rto 参数控制故障转移时间和敏感性:

# RTO 配置
pg_rto: 30  # 默认:30 秒

较低的 RTO 值:

  • ✅ 更快的故障转移响应
  • ✅ 减少服务中断
  • ❌ 更高的误报风险
  • ❌ 可能导致不必要的故障转移

较高的 RTO 值:

  • ✅ 更稳定,较少误报
  • ✅ 对网络故障有更好的容忍度
  • ❌ 更长的服务中断
  • ❌ 对真实故障的延迟响应

恢复点目标(RPO)

pg_rpo 参数限制故障转移期间的潜在数据丢失:

# RPO 配置
pg_rpo: 1048576  # 默认:1MB

较低的 RPO 值:

  • ✅ 更好的数据一致性
  • ✅ 最小的数据丢失风险
  • ❌ 可能延迟故障转移
  • ❌ 可能影响可用性

较高的 RPO 值:

  • ✅ 更快的故障转移过程
  • ✅ 更好的可用性
  • ❌ 更多数据丢失的可能性
  • ❌ 一致性权衡

配置示例

# 零数据丢失配置
synchronous_mode: true
synchronous_mode_strict: true
pg_rpo: 0
pg_rto: 60
synchronous_standby_names: 'ANY 1 (*)'

使用场景:金融系统、关键交易数据

# 快速故障转移配置
synchronous_mode: false
pg_rpo: 16777216  # 16MB
pg_rto: 15
max_replication_slots: 16

使用场景:高流量应用、读重型工作负载

# 默认平衡配置
synchronous_mode: false
pg_rpo: 1048576   # 1MB
pg_rto: 30
max_replication_slots: 8

使用场景:大多数生产环境

网络质量影响

网络条件显著影响 HA 行为:

  • 高质量网络:可以安全使用较低的 RTO 值
  • 不稳定网络:需要较高的 RTO 以防止误报
  • WAN 部署:需要仔细调整超时参数
  • 本地网络:可以优化更快的故障转移

监控和可观测性

Pigsty 为 HA 集群健康提供全面监控:

关键指标

集群状态

监控集群拓扑、领导者状态和成员健康

复制延迟

跟踪所有副本的复制延迟和同步状态

故障转移事件

记录并分析故障转移事件及其影响

性能

监控查询性能和连接健康

仪表板集成

Pigsty 包含用于 HA 监控的预构建 Grafana 仪表板:

  • 集群概览:实时集群拓扑和健康
  • 复制监控:延迟指标和同步状态
  • 故障转移分析:历史故障转移事件和时间
  • 性能指标:正常和故障转移场景下的查询性能

最佳实践

部署建议

说明

反亲和性:在不同的物理主机、机架或可用区部署集群节点。

  • 硬件多样性:使用不同的硬件配置以避免常见故障模式
  • 网络冗余:确保集群节点间有多条网络路径
  • 存储考虑:使用本地存储获得最佳性能,特定用例使用共享存储
  • 监控设置:在投产前实施全面监控

运营指南

  • 定期测试:在非生产环境中执行受控的故障转移测试
  • 容量规划:为故障转移场景适当调整集群节点大小
  • 备份策略:维护独立于 HA 设置的定期备份
  • 文档:保持紧急程序运行手册的更新

常见陷阱

说明

避免这些常见错误:

  • 节点间网络带宽不足
  • 复制延迟监控不充分
  • 不定期测试故障转移程序
  • 防火墙配置不正确

总结

Pigsty 的高可用性解决方案提供:

  • 自动故障转移,RTO 不到一分钟
  • 可配置一致性,具有 RPO 控制
  • 自愈能力,用于硬件故障
  • 负载均衡,用于读扩展
  • 最小运营开销,具有自动化管理

Patroni、Etcd 和 HAProxy 的组合创建了一个强大的、生产就绪的 HA 解决方案,自动处理大多数故障场景,同时提供基于特定要求调整行为的灵活性。


高可用性不仅仅是技术——它是构建您的业务可以依赖的弹性系统。

7.5 - 灾难恢复

经过实战考验的备份策略和自动配置的时间点恢复

时间点恢复(PITR)允许将 PostgreSQL 集群回滚到过去的任何特定时刻,防止软件缺陷或人为错误导致的数据丢失。Pigsty 使用 pgBackRest 进行 PITR,具有可配置的备份策略,使用本地文件系统或 MinIO 等对象存储。

PITR Architecture
说明

数据库的时间旅行:将您的集群回滚到任何时间点,防止高可用性无法解决的软件缺陷、人为错误和数据损坏场景。

概述

Pigsty 提供 企业级时间点恢复,具有零配置设置、自动备份和灵活的恢复选项。基于 pgBackRest 构建,支持 MinIO/S3,防护数据损坏、人为错误和逻辑灾难。

降低 RPO
通过连续 WAL 归档最小化恢复点目标
数据完整性
增强数据完整性保护,防止损坏
灾难恢复
通过灵活的恢复选项改进灾难恢复能力

PITR 工作原理

PITR 需要两个关键组件协同工作以实现时间点恢复:

基础备份 [#base-backups]

使用 pgBackRest 创建数据库集群快照,支持多种备份类型:

- **完整备份**:完整的数据库集群快照
- **增量备份**:仅自上次备份以来的变更
- **差异备份**:自上次完整备份以来的变更
- **计划备份**:通过 Crontab 配置的定期备份

WAL 归档 [#wal-archiving]

连续归档预写日志(WAL)段文件:

- **连续归档**:实时 WAL 文件保存
- **自动管理**:WAL 文件和清理自动处理
- **可选功能**:如果不需要 PITR 可以禁用

实现

Pigsty 提供两种默认备份策略,具有灵活的配置选项:

本地文件系统策略 [#local-filesystem-strategy]

- **频率**:每日完整备份
- **存储**:本地文件系统存储
- **使用场景**:单节点或本地开发环境

MinIO/S3 策略 [#minio-s3-strategy]

- **频率**:每周完整备份,每日增量备份
- **存储**:对象存储(MinIO、S3)
- **使用场景**:具有分布式存储的生产环境

配置选项

备份配置非常灵活,可以指定选项:

  • 仓库类型:本地、S3 或其他支持的后端
  • 保留策略:保留备份的时间长度
  • 加密:安全备份存储
  • 存储位置:多个备份目标

恢复选项

说明

恢复操作应谨慎执行,因为它们将替换当前的数据库状态。

恢复命令允许恢复到各种时间点:

步骤 1

### 最新 WAL 归档 [#latest-wal-archive]
恢复到 WAL 归档中可用的最近点:
```bash
pg-pitr
```

步骤 2

### 特定时间戳 [#specific-timestamp]
恢复到确切的时间点:
```bash
pg-pitr --time="2022-12-30 14:44:44+08"
```

步骤 3

### 命名恢复点 [#named-restore-point]
恢复到之前创建的命名点:
```bash
pg-pitr --name="my-restore-point"
```

步骤 4

### 特定 LSN 或事务 ID [#specific-lsn-or-transaction-id]
恢复到特定的日志序列号或事务:
```bash
pg-pitr --lsn="0/1234567"
pg-pitr --xid="12345"
```
说明

虽然 PITR 对数据恢复很强大,但理想情况下应该与高可用性解决方案结合使用,以全面保护数据免受逻辑和物理故障的影响。

7.6 - 基础设施即代码

通过 YAML 驱动配置的声明式基础设施和数据库管理

Pigsty 提供 声明式 接口:在 配置 文件中描述一切,Pigsty 使用幂等的 playbooks 将其操作到期望的状态。它的工作原理类似于 Kubernetes CRD 和 Operator,但适用于任何节点上的数据库和基础设施:裸机或虚拟机。

说明

基础设施即代码,数据库即代码:声明式 API 和幂等 Playbooks,GitOPS 工作得如魅力般。


声明模块

您可以在单个节点上声明模块:

# infra cluster for proxy, monitor, alert, etc...
infra: { hosts: { 10.10.10.10: { infra_seq: 1 } } }

# minio cluster, s3 compatible object storage
minio: { hosts: { 10.10.10.10: { minio_seq: 1 } }, vars: { minio_cluster: minio } }

# etcd cluster for ha postgres DCS
etcd: { hosts: { 10.10.10.10: { etcd_seq: 1 } }, vars: { etcd_cluster: etcd } }

# postgres example cluster: pg-meta
pg-meta: { hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }, vars: { pg_cluster: pg-meta } }

并使用 playbooks 应用:

./infra.yml -l infra    # 在节点 10.10.10.10 上初始化 infra 模块
./etcd.yml  -l etcd     # 在节点 10.10.10.10 上初始化 etcd 模块
./minio.yml -l minio    # 在节点 10.10.10.10 上初始化 minio 模块
./pgsql.yml -l pg-meta  # 在节点 10.10.10.10 上初始化 pgsql 模块

声明集群

要创建具有流复制的三节点 HA postgres 集群:

pg-test:
  hosts:
    10.10.10.11: { pg_seq: 1, pg_role: primary }
    10.10.10.12: { pg_seq: 2, pg_role: replica }
    10.10.10.13: { pg_seq: 3, pg_role: replica }
  vars:
    pg_cluster: pg-test

并使用以下命令应用:

./pgsql.yml -l pg-test  # 初始化 pg-test 集群

声明集群内部

您可以深度定制数据库集群:

pg-meta:
  hosts:
    10.10.10.10: { pg_seq: 1, pg_role: primary }
  vars:
    pg_cluster: pg-meta
    pg_databases:
      - name: meta
        baseline: cmdb.sql
        comment: pigsty meta database
        schemas: [pigsty]
        extensions:
          - { name: adminpack, schema: pg_catalog }
          - { name: postgis, schema: public }
          - { name: timescaledb, schema: public }
    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: pigsty read-only user }
    pg_services:
      - { name: primary, port: 5433, dest: default }
      - { name: replica, port: 5434, dest: default, selector: "[]" }
      - { name: default, port: 5436, dest: postgres }
      - { name: offline, port: 5438, dest: postgres, selector: "[]" }
    pg_hba_rules:
      - { user: dbuser_view, db: all, addr: infra, auth: pwd, title: 'allow view user from infra nodes' }
    pgb_hba_rules:
      - { user: dbuser_view, db: all, addr: infra, auth: pwd, title: 'allow view user from infra nodes' }

声明访问控制

定义高级访问控制规则:

pg_hba_rules:
  - { 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: '${ip}/32', auth: pwd, title: 'replicator replication from ${ip}' }
  - { user: '${repl}', db: postgres, addr: '${ip}/32', auth: pwd, title: 'replicator postgres db from ${ip}' }
  - { user: '${monitor}', db: all, addr: '${ip}/32', auth: pwd, title: 'monitor from ${ip}' }
  - { user: '${monitor}', db: all, addr: infra, auth: pwd, title: 'monitor from infra nodes' }
  - { user: '${admin}', db: all, addr: infra, auth: ssl, title: 'admin @ infra nodes with pwd & ssl' }
  - { user: '+dbrole_readonly', db: all, addr: '${vip}/32', auth: ssl, title: 'allow readonly role from ${vip} with ssl' }
  - { user: '+dbrole_offline', db: all, addr: '${vip}/32', auth: ssl, title: 'allow offline role from ${vip} with ssl' }
  - { user: dbuser_meta, db: meta, addr: '10.0.0.0/8', auth: ssl, title: 'allow meta user from 10.0.0.0/8 with ssl' }

Citus 分布式集群

声明一个水平分布的 Citus 集群:

pg-citus0: # coordinator
  hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
  vars:
    pg_cluster: pg-citus0
    pg_mode: citus
    pg_shard: pg-citus
    pg_primary_db: meta
    pg_users: [ { name: dbuser_meta, password: DBUser.Meta, pgbouncer: true, roles: [ dbrole_admin ] } ]
    pg_databases: [ { name: meta, extensions: [ { name: citus }, { name: postgis }, { name: timescaledb } ] } ]
    pg_hba_rules:
      - { user: 'all', db: all, addr: '10.10.10.0/24', auth: trust }
pg-citus1: # worker1
  hosts: { 10.10.10.11: { pg_seq: 1, pg_role: primary } }
  vars: { pg_cluster: pg-citus1, pg_mode: citus, pg_shard: pg-citus }
pg-citus2: # worker2
  hosts: { 10.10.10.12: { pg_seq: 1, pg_role: primary } }
  vars: { pg_cluster: pg-citus2, pg_mode: citus, pg_shard: pg-citus }
pg-citus3: # worker3
  hosts: { 10.10.10.13: { pg_seq: 1, pg_role: primary } }
  vars: { pg_cluster: pg-citus3, pg_mode: citus, pg_shard: pg-citus }

Redis 集群

声明不同类型的 Redis 集群:

redis-ms: # redis classic primary-replica
  hosts: { 10.10.10.10: { redis_node: 1 , redis_instances: { 6379: { }, 6380: { replica_of: '10.10.10.10 6379' } } } }
  vars: { redis_cluster: redis-ms ,redis_password: 'redis.ms' }
redis-sentinel: # redis sentinel x3
  hosts:
    10.10.10.10: { redis_node: 1, redis_instances: { 26379: { sentinel_monitor: redis-src } } }
    10.10.10.11: { redis_node: 2, redis_instances: { 26379: { sentinel_monitor: redis-src } } }
    10.10.10.12: { redis_node: 3, redis_instances: { 26379: { sentinel_monitor: redis-src } } }
  vars: { redis_cluster: redis-sentinel, redis_password: 'redis.sentinel' }
redis-cluster: # native redis cluster: 3m x 3s
  hosts:
    10.10.10.10: { redis_node: 1 ,redis_instances: { 6379: { }, 6380: { } } }
    10.10.10.11: { redis_node: 2 ,redis_instances: { 6379: { }, 6380: { } } }
    10.10.10.12: { redis_node: 3 ,redis_instances: { 6379: { }, 6380: { } } }
  vars: { redis_cluster: redis-cluster, redis_password: 'redis.cluster', redis_mode: cluster, redis_max_memory: 64MB }

Etcd 集群

声明一个 3 节点 etcd 共识集群:

etcd:
  hosts:
    10.10.10.10: { etcd_seq: 1 }
    10.10.10.11: { etcd_seq: 2 }
    10.10.10.12: { etcd_seq: 3 }
  vars:
    etcd_cluster: etcd
    etcd_safeguard: false

MinIO 集群

声明一个 3 节点 MinIO 对象存储集群:

minio:
  hosts:
    10.10.10.10: { minio_seq: 1 }
    10.10.10.11: { minio_seq: 2 }
    10.10.10.12: { minio_seq: 3 }
  vars:
    minio_cluster: minio
    minio_data: '/data/minio'
    minio_domain: sss.pigsty
    minio_buckets: [ { name: pgsql }, { name: infra }, { name: redis } ]
    minio_users:
      - { access_key: dba, secret_key: S3User.DBA, policy: consoleAdmin }
      - { access_key: pgbackrest, secret_key: S3User.Backup, policy: readwrite }

Pigsty 使您能够声明式地描述整个基础设施并通过代码管理它,为您的数据库和基础设施操作提供一致性、可重复性和可扩展性。

7.7 - 无容器

Pigsty 在原生 Linux 上运行,无需容器和 kubernetes

Pigsty 运行在裸 Linux 上,我们支持主流 Linux 发行版,如 EL / Debian / Ubuntu,以及兼容的 Linux 发行版,如 Rocky Linux、AlmaLinux 等……

我们这样做是有目的的。为每个主版本 x PG 版本 x 操作系统架构编译和打包所有 postgres 相关包和数百个扩展到 RPM/DEB 是困难的……

但我相信这是正确的做法。所以我们不走 Docker、Podman 或 Kubernetes 这样的捷径。

7.8 - 应用模板

使用模板设置企业软件,supabase、odoo、dify、gitlab……
Supabase
    自托管 Supabase
Odoo
    运行 Odoo 开源 ERP
Dify
    运行 Dify AI 工作流
pgAdmin
    运行官方管理 GUI 工具

7.9 - Supabase

将 Postgres 转换为功能齐全的后端即服务

自托管 Supabase

7.10 - 本地优先

无需互联网安装,包含所有依赖项

8 - 参考

架构、用例、比较等…

Pigsty (/ˈpɪɡ staɪ/) 是一个电池级、FOSS PostgreSQL 发行版 作为本地优先的 RDS 替代方案

PostgreSQL 企业版
    轻松创建自愈的高可用 PG 集群,预配置时间点恢复、ACL、CA、SSL...
基础设施即代码
    用代码声明您的整个基础设施,并从裸机操作系统设置 PG 需要的一切:LB、Nginx、NTP、DNS、本地仓库等...
令人惊叹的可观测性
    基于现代 Prometheus 和 Grafana 可观测性技术栈的无与伦比的监控最佳实践,开箱即用
扩展和分支
    <span class="text-red-800 font-bold">437</span> PGSQL 扩展电池级内置!还有分支:Babelfish、Oriole、IvorySQL、OpenHalo、PolarDB、Supabase...

Pigsty 提供了自托管企业级 PostgreSQL 服务所需的一切,即使没有专业知识也能做到。

只需将 PostgreSQL 用于 一切,并像专家一样自托管 PostgreSQL!

想要了解更多?

阅读我们深入的 什么是 Pigsty 介绍。

8.1 - PG 发行版

为一切使用 PostgreSQL!用 postgres 超能力构建数据基础设施

PostgreSQL 正在吞噬数据库世界, 它正在成为数据库世界的 Linux 内核。

但是发行版在哪里?


什么是发行版?

如今,人们使用 Ubuntu、Debian 和 RHEL 等操作系统发行版,而不是直接使用原始的 Linux 内核。 您需要大量组件来构建实用的操作系统,例如 systemd、cron、NTP、DNS、日志记录等,以使原始 Linux 内核可用。

Linux 内核大小为几 MB,但完整的操作系统 DVD 可以轻松占用 10+ GB,包括所有必要的部分和软件包。 这就是 PostgreSQL 发行版的全部内容——为您提供构建生产级数据库服务所需的一切。


为什么我们需要发行版?

我们有两个东西来打造强大的 PostgreSQL 发行版:扩展服务

扩展

PostgreSQL 生态系统中有 1000+ 个扩展。 但其中只有 100 个可以通过"官方" PGDG 存储库访问。

因此,我们将最受欢迎和最有用的扩展打包到预制的 RPM/DEB 包中,支持 10 个 Linux 发行版和 5 个 PG 主版本。 现在有无与伦比的 422 个扩展 开箱即用,我们将在未来继续添加更多扩展。

更重要的是,我们甚至支持 8 种 PostgreSQL 内核版本(扩展、分支、包装器等),包括:

内核 关键特性 描述
Citus 水平扩展 原生分布式 PostgreSQL
WiltonDB SQL Server 迁移 SQL Server 协议兼容性
IvorySQL Oracle 迁移 Oracle 语法和 PL/SQL 兼容
OpenHalo MySQL 迁移 MySQL 协议兼容性
FerretDB MongoDB 迁移 MongoDB 协议兼容性
OrioleDB OLTP 优化 Zheap、无膨胀、S3 存储
PolarDB PG Aurora 风格 RAC RAC、中国国产合规
Supabase 后端即服务 基于 PostgreSQL 的 BaaS,Firebase 替代品
Greenplum 分析/数据仓库 大规模并行处理数据仓库

服务

您可以像 systemctl start postgresql 这样轻松地开始使用原始 PostgreSQL 内核,但这远不是生产级服务。 这就是人们为 AWS RDS 等托管 PostgreSQL 服务支付每 vCPU·月 160 美元的主要原因。

但是,如果您可以用几个命令在自己的服务器上构建企业级 PostgreSQL 服务,而且不需要许可费用,会怎么样? Pigsty 使您能够做到这一点。它为您提供具有 PITR、监控和告警、连接池等功能的 HA PostgreSQL 集群

8.2 - RDS 替代

像专家一样自托管 PostgreSQL!在没有专业知识的情况下运行生产级服务

什么是 RDS?

您可以像 systemctl start postgresql 这样轻松地开始使用原始 PostgreSQL 内核,但这远不是生产级服务。 这就是人们为 AWS RDS 等托管 PostgreSQL 服务支付每 vCPU·月 160 美元的主要原因,甚至为传统的"企业"数据库服务支付更多费用。

构建和管理生产级 PostgreSQL 服务的专业知识既稀少又昂贵。

如果……

但是,如果您可以用几个命令在自己的服务器上构建企业级 PostgreSQL 服务,而且不需要许可费用,会怎么样? Pigsty 使您能够做到这一点。它为您提供具有 PITR、监控和告警、连接池等功能的 HA PostgreSQL 集群

这一切都从几个命令开始,您可以自己构建生产级 PostgreSQL 服务, 无需昂贵的许可证或专业知识。

8.3 - 整体架构

Pigsty 的模块化、声明式 PostgreSQL 基础设施设计

模块化架构和声明式接口!

  • Pigsty 部署通过配置清单描述,并使用 ansible playbooks 实现。
  • Pigsty 在 Linux 通用节点上工作,即裸机或虚拟机。
  • Pigsty 使用模块化设计,可以自由组合以适应不同场景。
  • 配置控制在哪里如何使用参数安装模块
  • Playbooks 将以幂等方式将节点调整到所需状态。

模块

Pigsty 使用模块化设计,有六个默认模块:PGSQLINFRANODEETCDREDISMINIO

  • PGSQL:由 Patroni、Pgbouncer、HAproxy、PgBackrest 等驱动的自主 HA Postgres 集群…
  • INFRA:本地 yum/apt 仓库、Prometheus、Grafana、Loki、AlertManager、PushGateway、Blackbox Exporter…
  • NODE:将节点调整到所需状态,名称、时区、NTP、ssh、sudo、haproxy、docker、promtail、keepalived
  • ETCD:分布式键值存储将用作高可用 Postgres 集群的 DCS。
  • REDIS:独立主副本、哨兵、集群模式的 Redis 服务器与 Redis exporter。
  • MINIO:S3 兼容的简单对象存储服务器,可用作 Postgres 的可选备份中心。

您可以以声明式方式自由组合它们。如果您想要主机监控,INFRANODE 就足够了。额外的 ETCDPGSQL 用于 HA PG 集群。在多个节点上部署它们将形成 HA 集群。您可以重用 pigsty 基础设施并开发您的模块,考虑可选的 REDISMINIO 作为示例。

pigsty-sandbox.jpg


单例元数据

Pigsty 默认将安装在单个节点(裸机/虚拟机)上。install.yml playbook 将在当前节点上安装 INFRAETCDPGSQL 和可选的 MINIO 模块,这将为您提供功能齐全的可观测性基础设施(Prometheus、Grafana、Loki、AlertManager、PushGateway、BlackboxExporter 等……)和一个开箱即用的 PostgreSQL 单例实例(名为 meta)。

此节点现在具有自监控系统、可视化工具集和具有自动配置 PITR 的 Postgres 数据库。您可以将此节点用于开发环境、测试、运行演示以及进行数据可视化和分析。或者,进一步向其添加更多节点!

pigsty-arch.jpg


监控

安装的 单例元数据 可用作管理节点监控中心,将更多节点和数据库服务器纳入其监控和控制范围。

如果您想安装 Prometheus / Grafana 可观测性堆栈,Pigsty 为您提供最佳实践!它具有适用于 节点PostgreSQL 的细粒度仪表板,无论这些节点或 PostgreSQL 服务器是否由 Pigsty 管理,您都可以通过简单的配置立即获得生产级监控和告警。

pigsty-dashboard.jpg


HA PG 集群

使用 Pigsty,您可以随心所欲地拥有自己的本地生产级 HA PostgreSQL RDS。

要创建这样的 HA PostgreSQL 集群,您所要做的就是描述它并运行 playbook:

pg-test:
  hosts:
    10.10.10.11: { pg_seq: 1, pg_role: primary }
    10.10.10.12: { pg_seq: 2, pg_role: replica }
    10.10.10.13: { pg_seq: 3, pg_role: replica }
  vars: { pg_cluster: pg-test }
$ bin/pgsql-add pg-test

这将为您提供以下集群,监控、副本、备份全部设置完成。

pigsty-ha.png

硬件故障由基于 patronietcdhaproxy 的自愈 HA 架构覆盖,在主节点故障的情况下将在 30 秒内执行自动故障转移。借助由 haproxy 支持的自愈流量控制,在切换或副本故障的情况下,客户端甚至可能根本不会注意到有故障。

软件故障、人为错误和数据中心故障由 pgbackrest 和可选的 MinIO 集群覆盖。这使您能够执行时间点恢复到任何时间(只要您的存储能够支持)


数据库即代码

Pigsty 遵循 IaC 和 GitOPS 哲学:Pigsty 部署由声明式 配置清单 描述,并通过幂等 playbooks 实现。

用户以声明式方式使用 参数 描述所需状态,playbooks 以幂等方式将目标节点调整为该状态。这就像 Kubernetes CRD 和 Operator,但适用于裸机和虚拟机。

pigsty-iac.jpg

以默认配置片段为例,它描述了一个安装了 INFRANODEETCDPGSQL 模块的节点 10.10.10.10

# infra cluster for proxy, monitor, alert, etc...
infra: { hosts: { 10.10.10.10: { infra_seq: 1 } } }

# minio cluster, s3 compatible object storage
minio: { hosts: { 10.10.10.10: { minio_seq: 1 } }, vars: { minio_cluster: minio } }

# etcd cluster for ha postgres DCS
etcd: { hosts: { 10.10.10.10: { etcd_seq: 1 } }, vars: { etcd_cluster: etcd } }

# postgres example cluster: pg-meta
pg-meta: { hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary }, vars: { pg_cluster: pg-meta } }

要实现它,请使用以下 playbooks:

./infra.yml -l infra    # init infra module on group 'infra'
./etcd.yml  -l etcd     # init etcd module on group 'etcd'
./minio.yml -l minio    # init minio module on group 'minio'
./pgsql.yml -l pg-meta  # init pgsql module on group 'pgsql'

执行常规管理任务将很简单。例如,如果您希望向现有的 HA PostgreSQL 集群添加新副本/数据库/用户,您只需在配置中添加一个主机并在其上运行该 playbook,例如:

pg-test:
  hosts:
    10.10.10.11: { pg_seq: 1, pg_role: primary }
    10.10.10.12: { pg_seq: 2, pg_role: replica }
    10.10.10.13: { pg_seq: 3, pg_role: replica } # <-- add new instance
  vars: { pg_cluster: pg-test }
$ bin/pgsql-add  pg-test 10.10.10.13

您甚至可以使用这种方法管理许多 PostgreSQL 实体:用户/角色、数据库、服务、HBA 规则、扩展、模式等……

查看 PGSQL 配置 了解详情。

8.4 - 技术对比

与市面类似产品的对比

与云厂商 RDS 对比

Pigsty 是使用 AGPLv3 开源的本地优先 RDS 替代,可以部署在您自己的物理机/虚拟机上,也可以部署在云服务器上。

因此,我们选择了全球份额第一的亚马逊云 AWS RDS for PostgreSQL,以及中国市场份额第一的阿里云 RDS for PostgreSQL 作为参照对象。

阿里云 RDS 与 AWS RDS 均为闭源云数据库服务,通过租赁模式,仅在公有云上对外提供,以下对比基于最新的 PostgreSQL 16 主干版本进行,对比截止日期为 2024 年 2 月份。


功能特性

指标 Pigsty Aliyun RDS AWS RDS
大版本支持 12 - 17 12 - 17 12 - 17
只读从库 支持任意数量只读从库 备实例不对用户开放 备实例不对用户开放
读写分离 支持端口区分读写流量 独立收费组件 独立收费组件
快慢分离 支持离线 ETL 实例 未见相关特性 未见相关特性
异地灾备 支持备份集群 支持多可用区部署 支持多可用区部署
延迟从库 支持延迟实例 未见相关特性 未见相关特性
负载均衡 HAProxy / LVS 独立收费组件 独立收费组件
连接池 Pgbouncer 独立收费组件:RDS 独立收费组件:RDS Proxy
高可用 Patroni / etcd 需高可用版提供支持 需高可用版提供支持
时间点恢复 pgBackRest / MinIO 提供备份支持 提供备份支持
指标监控 Prometheus / Exporter 免费基础版/收费进阶版 免费基础版/收费进阶版
日志采集 Loki / Promtail 基础支持 基础支持
可视化系统 Grafana / Echarts 提供基本监控 提供基本监控
告警聚合通知 AlterManager 基础支持 基础支持

重要扩展

这里列出了一些重要扩展,对比基于最新的 PostgreSQL 16 主干版本进行,截止至 2024-02-28

扩展名称 Pigsty RDS / PGDG 官方仓库 阿里云 RDS AWS RDS
加装扩展 自由加装 不允许 不允许
地理空间 PostGIS 3.5.1 PostGIS 3.3.4 / Ganos 6.1 PostGIS 3.4.1
雷达点云 PG PointCloud 1.2.5 Ganos PointCloud 6.1
向量嵌入 PGVector 0.8.1 / Svector 0.5.6 pase 0.0.1 PGVector 0.6
机器学习 PostgresML 2.10.0
时序扩展 TimescaleDB 2.20.2
水平分布式 Citus 13.1
数据分析 Hydra 1.1.1
全文检索 pg_bm25 0.5.6
图数据库 Apache AGE 1.5.0
GraphQL PG GraphQL 1.5.0
OLAP pg_analytics 0.5.6
消息队列 pgq 3.5.0
DuckDB duckdb_fdw 1.1
模糊分词 zhparser 1.1 / pg_bigm 1.2 parser 1.0 / pg_jieba pg_bigm 1.2
CDC抽取 wal2json 2.5.3 wal2json 2.5
膨胀治理 pg_repack 1.5.0 pg_repack 1.4.8 pg_repack 1.5.0

性能对比

指标 Pigsty Aliyun RDS AWS RDS
最佳性能 PGTPC on NVME SSD 评测 sysbench oltp_rw RDS PG 性能白皮书 sysbench oltp 场景 每核 QPS 4000 ~ 8000
存储规格:最高档容量 32TB / NVME SSD 32 TB / ESSD PL3 64 TB / io2 EBS Block Express
存储规格:最高档IOPS 4K随机读:最大3M,随机写 2000~350K 4K随机读:最大 1M 16K随机IOPS: 256K
存储规格:最高档延迟 4K随机读:75µs,随机写 15µs 4K随机读:200µs 500µs / 推断为16K随机IO
存储规格:最高档可靠性 UBER < 1e-18,折合18个9 MTBF: 200万小时 5DWPD,持续三年 可靠性 9个9, 合 UBER 1e-9 存储与数据可靠性 持久性:99.999%,5个9 (0.001% 年故障率) io2 说明
存储规格:最高档成本 31.5 ¥/TB·月 ( 5年质保均摊 / 3.2T / 企业级 / MLC ) 3200¥/TB·月 (原价 6400¥,包月4000¥) 3年预付整体打5折才有此价格 1900 ¥/TB·月 使用最大规格 65536GB / 256K IOPS 最大优惠

可观测性

Pigsty 提供了近 3000 类监控指标,提供了 50+ 监控面板,覆盖了数据库监控、主机监控、连接池监控、负载均衡监控等方方面面,为用户提供无与伦比的可观测性体验。

dashboard

Pigsty 提供了 638 与 PostgreSQL 有关的监控指标,而 AWS RDS 只有 99 个,阿里云 RDS 更是只有个位数指标:

此外,也有一些项目提供了监控 PostgreSQL 的能力,但都相对比较简单初级:


可维护性

指标 Pigsty Aliyun RDS AWS RDS
系统易用性 简单 简单 简单
配置管理 配置文件 / CMDB 基于 Ansible Inventory 可使用 Terraform 可使用 Terraform
变更方式 幂等剧本 基于 Ansible Playbook 控制台点击操作 控制台点击操作
参数调优 自动根据节点适配 四种预置模板 OLTP, OLAP, TINY, CRIT
Infra as Code 原生支持 可使用 Terraform 可使用 Terraform
可定制参数点 总计 280+ 个
服务与支持 提供商业订阅支持兜底 提供售后工单支持 提供售后工单支持
无互联网部署 可离线安装部署 N/A N/A
数据库迁移 提供从现有v10+ PG实例基于逻辑复制不停机迁移至Pigsty托管实例的剧本 提供上云辅助迁移 Aliyun RDS 数据同步

成本

经验上看,软硬件资源的部分 RDS 单位成本是自建的 5 ~ 15 倍,租售比通常在一个月。详情请参考 成本分析

要素 指标 Pigsty Aliyun RDS AWS RDS
成本 软件授权/服务费用 免费,硬件约 20 - 40 ¥/核·月 200 ~ 400 ¥/核·月 400 ~ 1300 ¥/核·月
服务支持费用 服务约 100 ¥/ 核·月 包含在 RDS 成本中

其他本地数据库管控软件

一些提供管理 PostgreSQL 能力的软件与供应商


其他 Kubernetes Operator

Pigsty 拒绝在生产环境中使用 Kubernetes 管理数据库,因此与这些方案在生态位上存在差异。

  • PGO
  • StackGres
  • CloudNativePG
  • TemboOperator
  • PostgresOperator
  • PerconaOperator
  • Kubegres
  • KubeDB
  • KubeBlocks

更多信息请参阅:


PostgreSQL 发行版生态

8.5 - 模块

Pigsty 中可用的模块

核心模块

Pigsty 由多个模块组成。PINE 技术栈:PGSQL / INFRA / NODE / ETCD 对于自托管 Postgres RDS 服务是 必需的

PGSQL
    具有 PITR、IaC、ACL、监控和 437 扩展的 HA PG 集群
INFRA
    用于可观测性的 Nginx、仓库、DNS、NTP、Prometheus 和 Grafana 堆栈
NODE
    将节点注册到所需状态并监控它,以及 VIP、HAProxy
ETCD
    可靠的分布式共识存储(DCS),为 PGSQL HA 提供支持

额外模块

Pigsty 还有一些 可选的 “奖励” 模块,它们与 PostgreSQL 配合良好,为您的数据基础设施带来额外价值。

MINIO
    S3 兼容的对象存储,可选的备份存储
REDIS
    高性能内存缓存,可选的数据结构服务器
DOCKER
    容器运行时,可选用于运行无状态应用程序和工具
FERRET
    在 PostgreSQL 上兼容 MongoDB 协议,可选中间件

内核模块

Pigsty 允许使用 8 种特殊的 PostgreSQL 内核 分支,作为可选的就地替换:

Citus

原生分布式扩展

Babelfish

SQL Server 协议兼容

IvorySQL

Oracle 语法和 PL/SQL 兼容

OpenHalo

MySQL 协议兼容性

OrioleDB

OLTP 优化的云原生存储引擎

PolarDB PG

类似 Aurora 的共享存储,符合中国合规要求

Supabase

后端即服务,自托管 Firebase

Greenplum

大规模并行处理数据仓库

8.6 - FAQ

常见问题

9 - 版本

Pigsty 历史版本发行注记
版本 发布日期 摘要 发布页面
v3.7.0 2025-12-02 PG18 成为默认版本,437 个扩展,EL10 与 Debian13 的完整支持, PGEXT.CLOUD v3.7.0
v3.6.1 2025-08-15 例行 PG 小版本更新,PGDG 中国区域镜像,EL9,D13 存根 v3.6.1
v3.6.0 2025-07-30 pgactive,MinIO / ETCD 改进,安装简化,配置梳理 v3.6.0
v3.5.0 2025-06-16 PG18 beta,421 扩展,监控升级,代码重构 v3.5.0
v3.4.1 2025-04-05 OpenHalo & OrioleDB,MySQL兼容,pgAdmin改进 v3.4.1
v3.4.0 2025-03-30 备份改进,自动证书,AGE,Ivory 全平台,本地化,架构与参数改进 v3.4.0
v3.3.0 2025-02-24 404 扩展,扩展目录,App 剧本,Nginx 定制,DocumentDB 支持 v3.3.0
v3.2.2 2025-01-23 390扩展,Omnigres支持,Mooncake,Citus13与PG17支持 v3.2.2
v3.2.1 2025-01-12 350扩展,Ivory4,Citus强化,Odoo模板 v3.2.1
v3.2.0 2024-12-24 扩展管理 CLI ,Grafana 强化,ARM64 扩展补完 v3.2.0
v3.1.0 2024-11-24 PG 17 升默认大版本,配置简化,Ubuntu24与ARM 支持,Supabase,MinIO 改进 v3.1.0
v3.0.4 2024-10-30 PG 17 扩展,OLAP 全家桶,pg_duckdb v3.0.4
v3.0.3 2024-09-27 PostgreSQL 17,Etcd 运维优化,IvorySQL 3.4,PostGIS 3.5 v3.0.3
v3.0.2 2024-09-07 精简安装模式,PolarDB 15支持,监控视图更新 v3.0.2
v3.0.1 2024-08-31 例行问题修复,Patroni 4支持,Oracle兼容性改进 v3.0.1
v3.0.0 2024-08-25 333个扩展插件,可插拔内核,MSSQL,Oracle,PolarDB 兼容性 v3.0.0
v2.7.0 2024-05-20 扩展大爆炸,新增20+强力扩展插件,与多款Docker应用 v2.7.0
v2.6.0 2024-02-28 PG 16 作为默认大版本,引入 ParadeDB 与 DuckDB 等扩展 v2.6.0
v2.5.1 2023-12-01 例行小版本更新,PG16重要扩展支持 v2.5.1
v2.5.0 2023-09-24 Ubuntu/Debian支持:bullseye, bookworm, jammy, focal v2.5.0
v2.4.1 2023-09-24 Supabase/PostgresML支持与各种新扩展:graphql, jwt, pg_net, vault v2.4.1
v2.4.0 2023-09-14 PG16,监控RDS,服务咨询支持,新扩展:中文分词全文检索/图/HTTP/嵌入等 v2.4.0
v2.3.1 2023-09-01 带HNSW的PGVector,PG 16 RC1, 文档翻新,中文文档,例行问题修复 v2.3.1
v2.3.0 2023-08-20 主机VIP, ferretdb, nocodb, MySQL存根, CVE修复 v2.3.0
v2.2.0 2023-08-04 仪表盘 & 置备重做,UOS 兼容性 v2.2.0
v2.1.0 2023-06-10 支持 PostgreSQL 12 ~ 16beta v2.1.0
v2.0.2 2023-03-31 新增 pgvector 支持,修复 MinIO CVE v2.0.2
v2.0.1 2023-03-21 v2 错误修复,安全增强,升级 Grafana 版本 v2.0.1
v2.0.0 2023-02-28 架构大升级,兼容性、安全性、可维护性显著增强 v2.0.0
v1.5.1 2022-06-18 Grafana 安全性修复 v1.5.1
v1.5.0 2022-05-31 Docker 应用程序支持 v1.5.0
v1.4.1 2022-04-20 错误修复 & 英文文档完整翻译 v1.4.1
v1.4.0 2022-03-31 MatrixDB 支持,分离 INFRA/NODES/PGSQL/REDIS模块 v1.4.0
v1.3.0 2021-11-30 PGCAT 重整 & PGSQL 增强 & Redis Beta支持 v1.3.0
v1.2.0 2021-11-03 默认 PGSQL 版本升级至 14 v1.2.0
v1.1.0 2021-10-12 主页, JupyterLab, PGWEB, Pev2 & pgbadger v1.1.0
v1.0.0 2021-07-26 v1 正式版, 监控系统重整 v1.0.0
v0.9.0 2021-04-04 Pigsty 图形界面, 命令行界面, 日志集成 v0.9.0
v0.8.0 2021-03-28 服务置备,定制对外暴露的数据库服务 v0.8.0
v0.7.0 2021-03-01 仅监控部署,监控现有 PostgreSQL 实例 v0.7.0
v0.6.0 2021-02-19 架构增强,将PG与Consul解耦 v0.6.0
v0.5.0 2021-01-07 支持在配置中定义业务数据库/用户 v0.5.0
v0.4.0 2020-12-14 支持 PostgreSQL 13,添加官方文档 v0.4.0
v0.3.0 2020-10-22 虚拟机置备方案正式定稿 v0.3.0
v0.2.0 2020-07-10 PG监控系统第六版正式发布 v0.2.0
v0.1.0 2020-06-20 在生产仿真测试环境中验证通过 v0.1.0
v0.0.5 2020-08-19 离线安装模式:无需互联网访问即可交付 v0.0.5
v0.0.4 2020-07-27 将 Ansible 剧本重构为 Role v0.0.4
v0.0.3 2020-06-22 接口设计改进 v0.0.3
v0.0.2 2020-04-30 首次提交 v0.0.2
v0.0.1 2019-05-15 概念原型 v0.0.1

9.1 - Pigsty 发布

Pigsty 的历史版本发布说明

Pigsty v3.7.0

亮点特性

  • PostgreSQL 18 深度支持,成为默认 PG 大版本,扩展已就位!
  • 新增 EL10 / Debian 13 操作系统支持,总数达 14 个!
  • 新增 PostgresQL 扩展数量,总数达到 437 个!
  • 支持了 Ansible 2.19 破坏性重构以后的版本!
  • Supabase,PolarDB, IvorySQL, Percona 内核更新至最新版本!
  • 优化了 PG 默认参数的设置逻辑,更充分利用资源。

版本更新

  • PostgreSQL 18.1, 17.7, 16.11, 15.15, 14.20, 13.23
  • Patroni 4.1.0
  • Pgbouncer 1.25.0
  • pg_exporter 1.0.3
  • pgbackrest 2.57.0
  • Supabase 2025-11
  • PolarDB 15.15.5.0
  • FerretDB 2.7.0
  • DuckDB 1.4.2
  • Etcd 3.6.6
  • pig 0.7.4

更多软件版本更新信息,请参考:

API变化

  • 为并行执行的相关参数设置了更合理的优化策略,详见 调参说明
  • richfull 模板中,不再默认安装 citus 扩展,因为 citus 尚未支持 PG 18
  • PG 参数模板中,新增 duckdb 系列扩展存根。
  • min_wal_size, max_wal_size, max_slot_wal_keep_size 设置 200,2000,3000 GB 的封顶上限值。
  • temp_file_limit 设置 200 GB 的封顶上限,OLAP 设置为 2 TB。
  • 适当增大连接池默认链接数量
  • 新增 prometheus_port 参数,且默认值为 9058,避开与 EL10 RHEL Web Console 端口的冲突。
  • 修改 alertmanager_port 参数的默认值为 9059,避开与 Kafka SSL 端口的潜在冲突。
  • 新增 pg_pkgpg_pre 子任务,在安装 PG 包前移除 el9+ 上导致 LLVM 冲突的 bpftool, python3-perf
  • 在 Debian / Ubuntu 的默认仓库定义中新增 llvm 仓库模块
  • 修复了 infra-rm.yml 移除软件包的逻辑

兼容性修复

  • 修复了 Ubuntu/Debian 信任 CA 时 Warning 返回码错误的问题。
  • 修复了 Ansible 2.19 引入的大量兼容性问题,确保在新老版本上正常运行。
  • 为 seq 类变量添加了 int 类型转换,确保兼容
  • 将大量 with_items 修改为 loop 语法,确保兼容
  • 为密钥交换变量添加一层列表嵌套,避免在新版本下针对字符串进行字符迭代。
  • 将 range 用例显式转换为 list 后使用
  • 修改了 name,port 等标记保留的变量命名
  • play_hosts 修改为 ansible_play_hosts
  • 为部分字符串类型添加了 string 强制类型转换,避免运行时错误。
  • EL10 逻辑适配:
  • 修复了 EL10 缺少 ansible-collection-community-crypto 无法生成密钥的问题
  • 修复了 EL10 缺少 ansible 逻辑包的问题
  • 移除 modulemd_tools flamegraph timescaledb-tool
  • 使用 java-21-openjdk 替代 java-17-openjdk
  • aarch64 YUM 仓库名称问题
  • Debian 13 逻辑适配
  • 使用 bind9-dnsutils 替代 dnsutils
  • Ubuntu 24 修复
  • 临时移除了上游依赖崩溃的 tcpdump 包

校验和

e00d0c2ac45e9eff1cc77927f9cd09df  pigsty-v3.7.0.tgz
987529769d85a3a01776caefefa93ecb  pigsty-pkg-v3.7.0.d12.aarch64.tgz
2d8272493784ae35abeac84568950623  pigsty-pkg-v3.7.0.d12.x86_64.tgz
090cc2531dcc25db3302f35cb3076dfa  pigsty-pkg-v3.7.0.d13.x86_64.tgz
ddc54a9c4a585da323c60736b8560f55  pigsty-pkg-v3.7.0.el10.aarch64.tgz
d376e75c490e8f326ea0f0fbb4a8fd9b  pigsty-pkg-v3.7.0.el10.x86_64.tgz
8c2deeba1e1d09ef3d46d77a99494e71  pigsty-pkg-v3.7.0.el8.aarch64.tgz
9795e059bd884b9d1b2208011abe43cd  pigsty-pkg-v3.7.0.el8.x86_64.tgz
08b860155d6764ae817ed25f2fcf9e5b  pigsty-pkg-v3.7.0.el9.aarch64.tgz
1ac430768e488a449d350ce245975baa  pigsty-pkg-v3.7.0.el9.x86_64.tgz
e033aaf23690755848db255904ab3bcd  pigsty-pkg-v3.7.0.u22.aarch64.tgz
cc022ea89181d89d271a9aaabca04165  pigsty-pkg-v3.7.0.u22.x86_64.tgz
0e978598796db3ce96caebd76c76e960  pigsty-pkg-v3.7.0.u24.aarch64.tgz
48223898ace8812cc4ea79cf3178476a  pigsty-pkg-v3.7.0.u24.x86_64.tgz

v3.6.1

curl https://repo.pigsty.cc/get | bash -s v3.6.1

亮点特性

  • PostgreSQL 17.6, 16.10, 15.14, 14.19, 13.22, 以及 18 Beta 3 支持
  • 在中国大陆地区使用 Pigsty 提供的 PGDG APT/YUM 镜像解决更新断供问题。
  • 新的网站首页: https://pgsty.com
  • 增加了 el10, debian 13 的实现存根,以及 el10 的 Terraform 镜像

基础设施软件包更新

  • Grafana 12.1.0
  • pg_exporter 1.0.2
  • pig 0.6.1
  • vector 0.49.0
  • redis_exporter 1.75.0
  • mongo_exporter 0.47.0
  • victoriametrics 1.123.0
  • victorialogs: 1.28.0
  • grafana-victoriametrics-ds 0.18.3
  • grafana-victorialogs-ds 0.19.3
  • grafana-infinity-ds 3.4.1
  • etcd 3.6.4
  • ferretdb 2.5.0
  • tigerbeetle 0.16.54
  • genai-toolbox 0.12.0

数据库软件包更新

  • pg_search 0.17.3

API变更

  • node_kernel_modules 默认值中移除 br_filter 内核模块。
  • 在添加 PGDG YUM 源时使用操作大版本号,不再使用小版本号。

校验和

045977aff647acbfa77f0df32d863739  pigsty-pkg-v3.6.1.d12.aarch64.tgz
636b15c2d87830f2353680732e1af9d2  pigsty-pkg-v3.6.1.d12.x86_64.tgz
700a9f6d0db9c686d371bf1c05b54221  pigsty-pkg-v3.6.1.el8.aarch64.tgz
2aff03f911dd7be363ba38a392b71a16  pigsty-pkg-v3.6.1.el8.x86_64.tgz
ce07261b02b02b36a307dab83e460437  pigsty-pkg-v3.6.1.el9.aarch64.tgz
d598d62a47bbba2e811059a53fe3b2b5  pigsty-pkg-v3.6.1.el9.x86_64.tgz
13fd68752e59f5fd2a9217e5bcad0acd  pigsty-pkg-v3.6.1.u22.aarch64.tgz
c25ccfb98840c01eb7a6e18803de55bb  pigsty-pkg-v3.6.1.u22.x86_64.tgz
0d71e58feebe5299df75610607bf428c  pigsty-pkg-v3.6.1.u24.aarch64.tgz
4fbbab1f8465166f494110c5ec448937  pigsty-pkg-v3.6.1.u24.x86_64.tgz
083d8680fa48e9fec3c3fcf481d25d2f  pigsty-v3.6.1.tgz

v3.6.0

curl https://repo.pigsty.cc/get | bash -s v3.6.0

亮点特性

  • 全新文档站: https://doc.pgsty.com
  • 新增 pgsql-pitr 剧本与备份/恢复教程,改善 PITR 体验,
  • 新增内核支持:Percona PG TDE (PG17)
  • 优化 Supabase 自建体验,更新至最新版本,并解决了一系列官方模板的问题
  • 简化安装步骤,默认使用在线安装,更加高效简单,bootstrap 过程(安装ansible)嵌入安装脚本中

设计改进

  • 改善了 Etcd 模块的实现,新增独立的 etcd-rm.yml 剧本与扩缩容 SOP 脚本。
  • 改善了 MinIO 模块的实现,支持 HTTP 模式,创建不同属性的三个桶供开箱即用
  • 重新调整梳理了所有配置模板,使用更为便利
  • 针对中国大陆使用速度更快的 Docker Registry 镜像站
  • 优化了 tuned 操作系统参数模板,针对现代硬件与 NVMe 磁盘优化
  • 新增扩展 pgactive 用于多主复制与亚秒级故障切换
  • 调整 pg_fs_main / pg_fs_backup 默认值,简化文件目录结构设计

问题修复

  • 修复了 pgbouncer 配置文件的错误 by @housei-zzy
  • 修复了 OrioleDB 在 Debian 平台上的问题
  • 修复了 tuned shm 配置参数的问题
  • 离线软件包直接使用 PGDG 源,避免使用断开同步的镜像站点
  • 修复了 IvorySQL libxcrypt 依赖的问题
  • 替换了破损与缓慢的 EPEL 软件仓库站点
  • 修复了 haproxy_enabled 标记位的功能

基础设施软件包更新

新增 Victoria Metrics / Victoria Logs 相关包

  • genai-toolbox 0.9.0 (new)
  • victoriametrics 1.120.0 -> 1.121.0 (重构)
  • vmutils 1.121.0 (重命名 victoria-metrics-utils)
  • grafana-victoriametrics-ds 0.15.1 -> 0.17.0
  • victorialogs 1.24.0 -> 1.25.1 (重构)
  • vslogcli 1.24.0 -> 1.25.1
  • vlagent 1.25.1 (新增)
  • grafana-victorialogs-ds 0.16.3 -> 0.18.1
  • prometheus 3.4.1 -> 3.5.0
  • grafana 12.0.0 -> 12.0.2
  • vector 0.47.0 -> 0.48.0
  • grafana-infinity-ds 3.2.1 -> 3.3.0
  • keepalived_exporter 1.7.0
  • blackbox_exporter 0.26.0 -> 0.27.0
  • redis_exporter 1.72.1 -> 1.77.0
  • rclone 1.69.3 -> 1.70.3

数据库软件包更新

  • PostgreSQL 18 Beta2 更新
  • pg_exporter 1.0.1,更新至最新依赖并提供 Docker 镜像
  • pig 0.6.0,更新了最新扩展与仓库列表,带有 pig install 子命令
  • vip-manager 3.0.0 -> 4.0.0
  • ferretdb 2.2.0 -> 2.3.1
  • dblab 0.32.0 -> 0.33.0
  • duckdb 1.3.1 -> 1.3.2
  • etcd 3.6.1 -> 3.6.3
  • ferretdb 2.2.0 -> 2.4.0
  • juicefs 1.2.3 -> 1.3.0
  • tigerbeetle 0.16.41 -> 0.16.50
  • pev2 1.15.0 -> 1.16.0

PG扩展包更新

  • OrioleDB 1.5 beta12
  • OriolePG 17.11
  • plv8 3.2.3 -> 3.2.4
  • postgresql_anonymizer 2.1.1 -> 2.3.0
  • pgvectorscale 0.7.1 -> 0.8.0
  • wrappers 0.5.0 -> 0.5.3
  • supautils 2.9.1 -> 2.10.0
  • citus 13.0.3 -> 13.1.0
  • timescaledb 2.20.0 -> 2.21.1
  • vchord 0.3.0 -> 0.4.3
  • pgactive 2.1.5 (new)
  • documentdb 0.103.0 -> 0.105.0
  • pg_search 0.17.0

API变更

  • pg_fs_backup:重命名为 pg_fs_backup,默认值为 /data/backups
  • pg_rm_bkup:重命名为 pg_rm_backup,默认值为 true
  • pg_fs_main:现在默认值调整为 /data/postgres
  • nginx_cert_validity:新增参数,用于控制 Nginx 自签名证书的有效期,默认为 397d
  • minio_buckets:默认值调整为创建名为 pgsqlmetadata 的三个桶。
  • minio_users:移除 dba 用户,新增 s3user_metas3user_data 用户,分别对应 metadata 桶。
  • minio_https:新增参数,允许配置 MinIO 使用 HTTP 模式。
  • minio_provision:新增参数,允许跳过 MinIO 置备阶段(跳过桶和用户的创建)。
  • minio_safeguard:新增参数,启用后会在执行 minio-rm.yml 时中止操作。
  • minio_rm_data:新增参数,控制在执行 minio-rm.yml 时是否删除 minio 数据目录。
  • minio_rm_pkg:新增参数,控制在执行 minio-rm.yml 时是否卸载 minio 软件包。
  • etcd_learner:新增参数,允许 etcd 以学习者身份初始化。
  • etcd_rm_data:新增参数,控制在执行 etcd-rm.yml 时是否删除 etcd 数据目录。
  • etcd_rm_pkg:新增参数,控制在执行 etcd-rm.yml 时是否卸载 etcd 软件包。

校验和

df64ac0c2b5aab39dd29698a640daf2e  pigsty-v3.6.0.tgz
cea861e2b4ec7ff5318e1b3c30b470cb  pigsty-pkg-v3.6.0.d12.aarch64.tgz
2f253af87e19550057c0e7fca876d37c  pigsty-pkg-v3.6.0.d12.x86_64.tgz
0158145b9bbf0e4a120b8bfa8b44f857  pigsty-pkg-v3.6.0.el8.aarch64.tgz
07330d687d04d26e7d569c8755426c5a  pigsty-pkg-v3.6.0.el8.x86_64.tgz
311df5a342b39e3288ebb8d14d81e0d1  pigsty-pkg-v3.6.0.el9.aarch64.tgz
92aad54cc1822b06d3e04a870ae14e29  pigsty-pkg-v3.6.0.el9.x86_64.tgz
c4fadf1645c8bbe3e83d5a01497fa9ca  pigsty-pkg-v3.6.0.u22.aarch64.tgz
5477ed6be96f156a43acd740df8a9b9b  pigsty-pkg-v3.6.0.u22.x86_64.tgz
196169afc1be02f93fcc599d42d005ca  pigsty-pkg-v3.6.0.u24.aarch64.tgz
dbe5c1e8a242a62fe6f6e1f6e6b6c281  pigsty-pkg-v3.6.0.u24.x86_64.tgz

v3.5.0

亮点特性

  • 支持 PG 18 (Beta),扩展更新,总数达到 421 个
  • OrioleDB 与 OpenHalo 内核在全平台上可用
  • 可使用 pig do 子命令代替 bin 脚本
  • Supabase 自建加强,解决若干遗留问题,例如复制延迟与密钥分发
  • 代码重构与架构优化,优化了 Postgres 与 Pgbouncer 默认参数
  • 更新了 Grafana 12, pg_exporter 1.0 与相关插件,翻修面板
curl https://repo.pigsty.cc/get | bash -s v3.5.0
  • 支持 PostgreSQL 18
  • 通过 pg_exporter 1.0.0 支持 PG18 监控指标
  • 通过 pig 0.4.1 支持 PG18 安装 Alias。
  • 提供 pg18 配置模板
  • 重构 pgsql 模块
  • PGSQL 重构,将 PG 监控抽离为单独的 pg_monitor 角色,移除 clean 逻辑
  • 去除冗余重复的任务,合并同类项,精简配置。移除 dir/utils 任务块
  • 所有扩展默认安装至 extensions 模式中(与 supabase 安全实践保持一致)
  • 重命名模板文件,移除所有 .j2 后缀
  • 为所有模板中的 monitor 函数添加 SET 命令清空 search_path,遵循 Supabase 安全最佳实践。
  • 调整 pgbouncer 默认参数,增大默认链接池大小,设置链接池清理查询。
  • 新增参数 pgbouncer_ignore_param ,允许配置 pgbouncer 忽略的参数列表
  • 新增任务 pg_key 用于生成 pgsodium 所需的服务端密钥
  • 针对 PG 17 默认启用 sync_replication_slots
  • 重新调整了子任务标签,使其更符合配置小节的拆分逻辑
  • 重构 pg_remove 模块
  • 重命名参数:pg_rm_data, pg_rm_bkup, pg_rm_pkg 用于控制删除的内容
  • 重新调整角色代码结构,使用更清楚的标签进行划分
  • 新增 pg_monitor 模块
  • pgbouncer_exporter 现在不再和 pg_exporter 共享配置文件
  • 新增了 TimescaleDB, Citus,pg_wait_event 的监控指标。
  • 使用 pg_exporter 1.0.0 ,更新了 PG16/17/18 相关监控指标。
  • 使用更为紧凑,全新设计的指标收集器配置文件。
  • Supabase 加强 (感谢来自 @lawso017 的贡献!)
  • 将 Supabase 容器镜像与数据库模式更新至最新版本
  • 现在默认支持 pgsodium 服务端密钥加载
  • 通过 supa-kick 定时任务解决 logflare 无法及时更新复制进度的问题
  • 为 monitor 模式中的函数添加 set search_path 子句以遵循安全最佳实践
  • CLI 新增 pig do 命令,允许通过命令行工具替代 bin/ 中的 Shell 脚本
  • 监控系统更新
  • 更新 Grafana 大版本至 12.0.0,更新相关插件/数据源软件包
  • 更新 Postgres 数据源 uid 命名方式(以适应新的 uid 长度限制与字符限制)
  • 新增了 Static Datasource
  • 更新了现有 Dashboard,修复若干遗留问题

基础设施软件包更新

  • pig 0.4.2
  • duckdb 1.3.0
  • etcd 3.6.0
  • vector 0.47.0
  • minio 20250422221226
  • mcli 20250416181326
  • pev 1.5.0
  • rclone 1.69.3
  • mtail 3.0.8 (new)

可观测性软件包更新

  • grafana 12.0.0
  • grafana-victorialogs-ds 0.16.3
  • grafana-victoriametrics-ds 0.15.1
  • grafana-infinity-ds 3.2.1
  • grafana_plugins 12.0.0
  • prometheus 3.4.0
  • pushgateway 1.11.1
  • nginx_exporter 1.4.2
  • pg_exporter 1.0.0
  • pgbackrest_exporter 0.20.0
  • redis_exporter 1.72.1
  • keepalived_exporter 1.6.2
  • victoriametrics 1.117.1
  • victoria_logs 1.22.2

数据库软件包更新

  • PostgreSQL 17.5, 16.9, 15.13, 14.18, 13.21
  • PostgreSQL 18beta1 支持
  • pgbouncer 1.24.1
  • pgbackrest 2.55
  • pgbadger 13.1

Postgres 扩展包更新

  • spat 0.1.0a4 新扩展
  • pgsentinel 1.1.0 新扩展
  • pgdd 0.6.0 (pgrx 0.14.1) 新扩展
  • convert 0.0.4 (pgrx 0.14.1) 新扩展
  • pg_tokenizer.rs 0.1.0 (pgrx 0.13.1)
  • pg_render 0.1.2 (pgrx 0.12.8)
  • pgx_ulid 0.2.0 (pgrx 0.12.7)
  • pg_idkit 0.3.0 (pgrx 0.14.1)
  • pg_ivm 1.11.0
  • orioledb 1.4.0 beta11 新增 debian/ubuntu 支持
  • openhalo 14.10 新增 debian/ubuntu 支持
  • omnigres 20250507 (在 d12/u22 编译最新版本失败)
  • citus 12.0.3
  • timescaledb 2.20.0 (移除 PG14 支持)
  • supautils 2.9.2
  • pg_envvar 1.0.1
  • pgcollection 1.0.0
  • aggs_for_vecs 1.4.0
  • pg_tracing 0.1.3
  • pgmq 1.5.1
  • tzf-pg 0.2.0 (pgrx 0.14.1)
  • pg_search 0.15.18 (pgrx 0.14.1)
  • anon 2.1.1 (pgrx 0.14.1)
  • pg_parquet 0.4.0 (0.14.1)
  • pg_cardano 1.0.5 (pgrx 0.12) -> 0.14.1
  • pglite_fusion 0.0.5 (pgrx 0.12.8) -> 14.1
  • vchord_bm25 0.2.1 (pgrx 0.13.1)
  • vchord 0.3.0 (pgrx 0.13.1)
  • pg_vectorize 0.22.1 (pgrx 0.13.1)
  • wrappers 0.4.6 (pgrx 0.12.9)
  • timescaledb-toolkit 1.21.0 (pgrx 0.12.9)
  • pgvectorscale 0.7.1 (pgrx 0.12.9)
  • pg_session_jwt 0.3.1 (pgrx 0.12.6) -> 0.12.9
  • pg_timetable 5.13.0
  • ferretdb 2.2.0
  • documentdb 0.103.0 (新增 aarch64 支持)
  • pgml 2.10.0 (pgrx 0.12.9)
  • sqlite_fdw 2.5.0 (fix pg17 deb)
  • tzf 0.2.2 0.14.1 (rename src)
  • pg_vectorize 0.22.2 (pgrx 0.13.1)
  • wrappers 0.5.0 (pgrx 0.12.9)

校验和

ab91bc05c54b88c455bf66533c1d8d43  pigsty-v3.6.0.tgz
4c9fabc2d1f0ed733145af2b6aff2f48 pigsty-pkg-v3.5.0.d12.x86_64.tgz
796d47de12673b2eb9882e527c3b6ba0 pigsty-pkg-v3.5.0.el8.x86_64.tgz
a53ef2cede1363f11e9faaaa43718fdc pigsty-pkg-v3.5.0.el9.x86_64.tgz
36da28f97a845fdc0b7bbde2d3812a67 pigsty-pkg-v3.5.0.u22.x86_64.tgz
8551b3e04b38af382163e6857778437d pigsty-pkg-v3.5.0.u24.x86_64.tgz

v3.4.1

GitHub 发布页面:v3.4.1

  • 在 EL 系统上增加了对 MySQL 协议兼容 PostgreSQL 内核的支持:openHalo
  • 在 EL 系统上增加了对 OLTP 增强 PostgreSQL 内核的支持:orioledb
  • 优化了 pgAdmin 9.2 应用模板,具有自动服务器列表更新和 pgpass 密码填充功能
  • 将 PG 默认最大连接数增加到 250、500、1000
  • 从 EL8 中删除了有依赖错误的 mysql_fdw 扩展

基础设施更新

  • pig 0.3.4
  • etcd 3.5.21
  • restic 0.18.0
  • ferretdb 2.1.0
  • tigerbeetle 0.16.34
  • pg_exporter 0.8.1
  • node_exporter 1.9.1
  • grafana 11.6.0
  • zfs_exporter 3.8.1
  • mongodb_exporter 0.44.0
  • victoriametrics 1.114.0
  • minio 20250403145628
  • mcli 20250403170756

扩展更新

  • 将 pg_search 升级到 0.15.13
  • 将 citus 升级到 13.0.3
  • 将 timescaledb 升级到 2.19.1
  • 将 pgcollection RPM 升级到 1.0.0
  • 将 pg_vectorize RPM 升级到 0.22.1
  • 将 pglite_fusion RPM 升级到 0.0.4
  • 将 aggs_for_vecs RPM 升级到 1.4.0
  • 将 pg_tracing RPM 升级到 0.1.3
  • 将 pgmq RPM 升级到 1.5.1

校验和

471c82e5f050510bd3cc04d61f098560  pigsty-v3.4.1.tgz
4ce17cc1b549cf8bd22686646b1c33d2  pigsty-pkg-v3.4.1.d12.aarch64.tgz
c80391c6f93c9f4cad8079698e910972  pigsty-pkg-v3.4.1.d12.x86_64.tgz
811bf89d1087512a4f8801242ca8bed5  pigsty-pkg-v3.4.1.el9.x86_64.tgzz
9fe2e6482b14a3e60863eeae64a78945  pigsty-pkg-v3.4.1.u22.x86_64.tgz

v3.4.0

GitHub 发布页面:v3.4.0

介绍博客:Pigsty v3.4 MySQL 兼容性和全面增强

新功能

  • 增加了新的 pgBackRest 备份监控指标和仪表板
  • 增强了 Nginx 服务器配置选项,支持自动 Certbot 签发
  • 现在优先使用 PostgreSQL 内置的 C/C.UTF-8 区域设置
  • IvorySQL 4.4 现在在所有平台上完全支持(RPM/DEB 在 x86/ARM 上)
  • 增加了新的软件包:Juicefs、Restic、TimescaleDB EventStreamer
  • Apache AGE 图数据库扩展现在在 EL 上完全支持 PostgreSQL 13–17
  • 改进了 app.yml playbook:无需额外配置即可启动标准 Docker 应用
  • 升级 Supabase、Dify 和 Odoo 应用模板到最新版本
  • 增加 electric 应用模板,本地优先的 PostgreSQL 同步引擎

基础设施包

  • +restic 0.17.3
  • +juicefs 1.2.3
  • +timescaledb-event-streamer 0.12.0
  • Prometheus 3.2.1
  • AlertManager 0.28.1
  • blackbox_exporter 0.26.0
  • node_exporter 1.9.0
  • mysqld_exporter 0.17.2
  • kafka_exporter 1.9.0
  • redis_exporter 1.69.0
  • pgbackrest_exporter 0.19.0-2
  • DuckDB 1.2.1
  • etcd 3.5.20
  • FerretDB 2.0.0
  • tigerbeetle 0.16.31
  • vector 0.45.0
  • VictoriaMetrics 1.113.0
  • VictoriaLogs 1.17.0
  • rclone 1.69.1
  • pev2 1.14.0
  • grafana-victorialogs-ds 0.16.0
  • grafana-victoriametrics-ds 0.14.0
  • grafana-infinity-ds 3.0.0

PostgreSQL 相关

  • Patroni 4.0.5
  • PolarDB 15.12.3.0-e1e6d85b
  • IvorySQL 4.4
  • pgbackrest 2.54.2
  • pev2 1.14
  • WiltonDB 13.17

PostgreSQL 扩展

  • pgspider_ext 1.3.0(新扩展)
  • apache age 13–17 el rpm (1.5.0)
  • timescaledb 2.18.2 → 2.19.0
  • citus 13.0.1 → 13.0.2
  • documentdb 1.101-0 → 1.102-0
  • pg_analytics 0.3.4 → 0.3.7
  • pg_search 0.15.2 → 0.15.8
  • pg_ivm 1.9 → 1.10
  • emaj 4.4.0 → 4.6.0
  • pgsql_tweaks 0.10.0 → 0.11.0
  • pgvectorscale 0.4.0 → 0.6.0 (pgrx 0.12.5)
  • pg_session_jwt 0.1.2 → 0.2.0 (pgrx 0.12.6)
  • wrappers 0.4.4 → 0.4.5 (pgrx 0.12.9)
  • pg_parquet 0.2.0 → 0.3.1 (pgrx 0.13.1)
  • vchord 0.2.1 → 0.2.2 (pgrx 0.13.1)
  • pg_tle 1.2.0 → 1.5.0
  • supautils 2.5.0 → 2.6.0
  • sslutils 1.3 → 1.4
  • pg_profile 4.7 → 4.8
  • pg_snakeoil 1.3 → 1.4
  • pg_jsonschema 0.3.2 → 0.3.3
  • pg_incremental 1.1.1 → 1.2.0
  • pg_stat_monitor 2.1.0 → 2.1.1
  • ddl_historization 0.7 → 0.0.7(错误修复)
  • pg_sqlog 3.1.7 → 1.6(错误修复)
  • pg_random 删除开发后缀(错误修复)
  • asn1oid 1.5 → 1.6
  • table_log 0.6.1 → 0.6.4

接口变更

  • 增加了新的 Docker 参数:docker_datadocker_storage_driver#521@waitingsong 提供)
  • 增加了新的基础设施参数:alertmanager_port,让您指定 AlertManager 端口
  • 增加了新的基础设施参数:certbot_sign,在 nginx 初始化期间申请证书?(默认为 false)
  • 增加了新的基础设施参数:certbot_email,指定通过 Certbot 请求证书时使用的邮箱
  • 增加了新的基础设施参数:certbot_options,指定 Certbot 的额外参数
  • 更新 IvorySQL,从 IvorySQL 4.4 开始将其默认二进制文件放在 /usr/ivory-4
  • pg_lc_ctype 和其他区域相关参数的默认值从 en_US.UTF-8 更改为 C
  • 对于 PostgreSQL 17,如果使用 UTF8 编码与 CC.UTF-8 区域,PostgreSQL 的内置本地化规则现在优先
  • configure 自动检测 PG 版本和环境是否都支持 C.utf8,并相应调整区域相关选项
  • 将默认 IvorySQL 二进制路径设置为 /usr/ivory-4
  • 更新 pg_packages 的默认值为 pgsql-main patroni pgbouncer pgbackrest pg_exporter pgbadger vip-manager
  • 更新 repo_packages 的默认值为 [node-bootstrap, infra-package, infra-addons, node-package1, node-package2, pgsql-utility, extra-modules]
  • /etc/profile.d/node.sh 中删除 LANGLC_ALL 环境变量设置
  • 现在使用 bento/rockylinux-8bento/rockylinux-9 作为 EL 的 Vagrant box 镜像
  • 增加了新别名 extra_modules,包含额外的可选模块
  • 更新 PostgreSQL 别名:postgresqlpgsql-mainpgsql-corepgsql-full
  • GitLab 仓库现在包含在可用模块中
  • Docker 模块已合并到基础设施模块中
  • node.yml playbook 现在包含 node_pip 任务,在每个节点上配置 pip 镜像
  • pgsql.yml playbook 现在包含 pgbackrest_exporter 任务,用于收集备份指标
  • Makefile 现在允许使用 META/PKG 环境变量
  • 增加 /pg/spool 目录作为 pgBackRest 的临时存储
  • 默认禁用 pgBackRest 的 link-all 选项
  • 默认为 MinIO 仓库启用块级增量备份

错误修复

  • 修复 pg-backup 中的退出状态码(#532@waitingsong 提供)
  • pg-tune-hugepage 中,限制 PostgreSQL 仅使用大页面(#527@waitingsong 提供)
  • 修复 pg-role 任务中的逻辑错误
  • 纠正大页面配置参数的类型转换
  • 修复 slim 模板中 node_repo_modules 的默认值问题

校验和

768bea3bfc5d492f4c033cb019a81d3a  pigsty-v3.4.0.tgz
7c3d47ef488a9c7961ca6579dc9543d6  pigsty-pkg-v3.4.0.d12.aarch64.tgz
b5d76aefb1e1caa7890b3a37f6a14ea5  pigsty-pkg-v3.4.0.d12.x86_64.tgz
42dacf2f544ca9a02148aeea91f3153a  pigsty-pkg-v3.4.0.el8.aarch64.tgz
d0a694f6cd6a7f2111b0971a60c49ad0  pigsty-pkg-v3.4.0.el8.x86_64.tgz
7caa82254c1b0750e89f78a54bf065f8  pigsty-pkg-v3.4.0.el9.aarch64.tgz
8f817e5fad708b20ee217eb2e12b99cb  pigsty-pkg-v3.4.0.el9.x86_64.tgz
8b2fcaa6ef6fd8d2726f6eafbb488aaf  pigsty-pkg-v3.4.0.u22.aarch64.tgz
83291db7871557566ab6524beb792636  pigsty-pkg-v3.4.0.u22.x86_64.tgz
c927238f0343cde82a4a9ab230ecd2ac  pigsty-pkg-v3.4.0.u24.aarch64.tgz
14cbcb90693ed5de8116648a1f2c3e34  pigsty-pkg-v3.4.0.u24.x86_64.tgz

v3.3.0

  • 可用扩展总数增加到 404
  • PostgreSQL 二月小版本更新:17.4、16.8、15.12、14.17、13.20
  • 新功能:app.yml 脚本,用于自动安装 Odoo、Supabase、Dify 等应用。
  • 新功能:在 infra_portal 中进一步自定义 Nginx 配置。
  • 新功能:增加 Certbot 支持,快速申请免费 HTTPS 证书。
  • 新功能:pg_default_extensions 现在支持纯文本扩展列表。
  • 新功能:默认仓库现在包含 mongo、redis、groonga、haproxy 等。
  • 新参数:node_aliases,为节点添加命令别名。
  • 修复:解决 Bootstrap 脚本中的默认 EPEL 仓库地址问题。
  • 改进:为 Debian Security 仓库添加阿里云镜像。
  • 改进:IvorySQL 内核的 pgBackRest 备份支持。
  • 改进:PolarDB 的 ARM64 和 Debian/Ubuntu 支持。
  • pg_exporter 0.8.0 现在支持 pgbouncer 1.24 中的新指标。
  • 新功能:gitdockersystemctl 等常用命令的自动补全 #506 #507@waitingsong 提供。
  • 改进:优化 pgbouncer 配置模板中的 ignore_startup_parameters #488@waitingsong 提供。
  • 新主页设计:Pigsty 的网站现在拥有全新的外观。
  • 扩展目录:RPM/DEB 二进制包的详细信息和下载链接。
  • 扩展构建:pig CLI 现在自动设置 PostgreSQL 扩展构建环境。

更多版本信息请参考 GitHub 发布页面


v2.7.0

2024-05-16:扩展大爆发,新的 docker 应用

https://github.com/pgsty/pigsty/releases/tag/v2.7.0


v2.6.0

2024-02-29:PG 16 作为默认版本,ParadeDB 和 DuckDB

https://github.com/pgsty/pigsty/releases/tag/v2.6.0


v2.5.1

2023-12-01:常规更新,pg16 主要扩展

https://github.com/pgsty/pigsty/releases/tag/v2.5.1


v2.5.0

2023-10-24:Ubuntu/Debian 支持:bullseye、bookworm、jammy、focal

https://github.com/pgsty/pigsty/releases/tag/v2.5.0


v2.4.1

2023-09-24:Supabase/PostgresML 支持,graphql、jwt、pg_net、vault

https://github.com/pgsty/pigsty/releases/tag/v2.4.1


v2.4.0

2023-09-14:PG16、RDS 监控、新扩展

https://github.com/pgsty/pigsty/releases/tag/v2.4.0


v2.3.1

2023-09-01:带 HNSW 的 PGVector、PG16 RC1、中文文档、错误修复

https://github.com/pgsty/pigsty/releases/tag/v2.3.1


v2.3.0

2023-08-20:PGSQL/REDIS 更新、NODE VIP、Mongo/FerretDB、MYSQL 存根

https://github.com/pgsty/pigsty/releases/tag/v2.3.0


v2.2.0

2023-08-04:仪表板和置备大修,UOS 兼容性

https://github.com/pgsty/pigsty/releases/tag/v2.2.0


v2.1.0

2023-06-10:PostgreSQL 12 ~ 16beta 支持

https://github.com/pgsty/pigsty/releases/tag/v2.1.0


v2.0.2

2023-03-31:添加 pgvector 支持并修复 MinIO CVE

https://github.com/pgsty/pigsty/releases/tag/v2.0.2


v2.0.1

2023-03-21:v2 错误修复,安全增强和升级 grafana 版本

https://github.com/pgsty/pigsty/releases/tag/v2.0.1


v2.0.0

2023-02-28:兼容性安全性可维护性增强

https://github.com/pgsty/pigsty/releases/tag/v2.0.0


v1.5.1

2022-06-18:Grafana 安全热修复

https://github.com/pgsty/pigsty/releases/tag/v1.5.1


v1.5.0

2022-05-31:Docker 应用

https://github.com/pgsty/pigsty/releases/tag/v1.5.0


v1.4.1

2022-04-20:错误修复和英文文档的完整翻译。

https://github.com/pgsty/pigsty/releases/tag/v1.4.1


v1.4.0

2022-03-31:MatrixDB 支持,分离的 INFRA、NODES、PGSQL、REDIS

https://github.com/pgsty/pigsty/releases/tag/v1.4.0


v1.3.0

2021-11-30:PGCAT 大修和 PGSQL 增强以及 Redis 支持测试版

https://github.com/pgsty/pigsty/releases/tag/v1.3.0


v1.2.0

2021-11-03:将默认 Postgres 升级到 14,监控现有 pg

https://github.com/pgsty/pigsty/releases/tag/v1.2.0


v1.1.0

2021-10-12:主页、JupyterLab、PGWEB、Pev2 和 Pgbadger

https://github.com/pgsty/pigsty/releases/tag/v1.1.0


v1.0.0

2021-07-26:v1 GA,监控系统大修

https://github.com/pgsty/pigsty/releases/tag/v1.0.0


v0.9.0

2021-04-04:Pigsty GUI、CLI、日志集成

https://github.com/pgsty/pigsty/releases/tag/v0.9.0


v0.8.0

2021-03-28:服务置备

https://github.com/pgsty/pigsty/releases/tag/v0.8.0


v0.7.0

2021-03-01:仅监控部署

https://github.com/pgsty/pigsty/releases/tag/v0.7.0


v0.6.0

2021-02-19:架构增强

https://github.com/pgsty/pigsty/releases/tag/v0.6.0


v0.5.0

2021-01-07:数据库定制模板

https://github.com/pgsty/pigsty/releases/tag/v0.5.0


v0.4.0

2020-12-14:PostgreSQL 13 支持,官方文档

https://github.com/pgsty/pigsty/releases/tag/v0.4.0


v0.3.0

2020-10-22:置备解决方案 GA

https://github.com/pgsty/pigsty/releases/tag/v0.3.0


v0.2.0

2020-07-10:PGSQL 监控 v6 GA

https://github.com/pgsty/pigsty/commit/385e33a62a19817e8ba19997260e6b77d99fe2ba


v0.1.0

2020-06-20:在测试环境中验证

https://github.com/pgsty/pigsty/commit/1cf2ea5ee91db071de00ec805032928ff582453b


v0.0.5

2020-08-19:离线安装模式

https://github.com/pgsty/pigsty/commit/0fe9e829b298fe5e56307de3f78c95071de28245


v0.0.4

2020-07-27:将 playbooks 重构为 ansible 角色

https://github.com/pgsty/pigsty/commit/90b44259818d2c71e37df5250fe8ed1078a883d0


v0.0.3

2020-06-22:界面增强

https://github.com/pgsty/pigsty/commit/4c5c68ccd57bc32a9e9c98aa3f264aa19f45c7ee


v0.0.2

2020-04-30:首次提交

https://github.com/pgsty/pigsty/commit/dd646775624ddb33aef7884f4f030682bdc371f8


v0.0.1

2019-05-15:概念验证

https://github.com/Vonng/pg/commit/fa2ade31f8e81093eeba9d966c20120054f0646b


9.2 - 最新版本

Pigsty 最新的稳定版本 v3.7.0

Pigsty v3.7.0

亮点特性

  • PostgreSQL 18 深度支持,成为默认 PG 大版本,扩展已就位!
  • 新增 EL10 / Debian 13 操作系统支持,总数达 14 个!
  • 新增 PostgresQL 扩展数量,总数达到 437 个!
  • 支持了 Ansible 2.19 破坏性重构以后的版本!
  • Supabase,PolarDB, IvorySQL, Percona 内核更新至最新版本!
  • 优化了 PG 默认参数的设置逻辑,更充分利用资源。

版本更新

  • PostgreSQL 18.1, 17.7, 16.11, 15.15, 14.20, 13.23
  • Patroni 4.1.0
  • Pgbouncer 1.25.0
  • pg_exporter 1.0.3
  • pgbackrest 2.57.0
  • Supabase 2025-11
  • PolarDB 15.15.5.0
  • FerretDB 2.7.0
  • DuckDB 1.4.2
  • Etcd 3.6.6
  • pig 0.7.4

更多软件版本更新信息,请参考:

API变化

  • 为并行执行的相关参数设置了更合理的优化策略,详见 调参说明
  • richfull 模板中,不再默认安装 citus 扩展,因为 citus 尚未支持 PG 18
  • PG 参数模板中,新增 duckdb 系列扩展存根。
  • min_wal_size, max_wal_size, max_slot_wal_keep_size 设置 200,2000,3000 GB 的封顶上限值。
  • temp_file_limit 设置 200 GB 的封顶上限,OLAP 设置为 2 TB。
  • 适当增大连接池默认链接数量
  • 新增 prometheus_port 参数,且默认值为 9058,避开与 EL10 RHEL Web Console 端口的冲突。
  • 修改 alertmanager_port 参数的默认值为 9059,避开与 Kafka SSL 端口的潜在冲突。
  • 新增 pg_pkgpg_pre 子任务,在安装 PG 包前移除 el9+ 上导致 LLVM 冲突的 bpftool, python3-perf
  • 在 Debian / Ubuntu 的默认仓库定义中新增 llvm 仓库模块
  • 修复了 infra-rm.yml 移除软件包的逻辑

兼容性修复

  • 修复了 Ubuntu/Debian 信任 CA 时 Warning 返回码错误的问题。
  • 修复了 Ansible 2.19 引入的大量兼容性问题,确保在新老版本上正常运行。
    • 为 seq 类变量添加了 int 类型转换,确保兼容
    • 将大量 with_items 修改为 loop 语法,确保兼容
    • 为密钥交换变量添加一层列表嵌套,避免在新版本下针对字符串进行字符迭代。
    • 将 range 用例显式转换为 list 后使用
    • 修改了 name,port 等标记保留的变量命名
    • play_hosts 修改为 ansible_play_hosts
    • 为部分字符串类型添加了 string 强制类型转换,避免运行时错误。
  • EL10 逻辑适配:
    • 修复了 EL10 缺少 ansible-collection-community-crypto 无法生成密钥的问题
    • 修复了 EL10 缺少 ansible 逻辑包的问题
    • 移除 modulemd_tools flamegraph timescaledb-tool
    • 使用 java-21-openjdk 替代 java-17-openjdk
    • aarch64 YUM 仓库名称问题
  • Debian 13 逻辑适配
    • 使用 bind9-dnsutils 替代 dnsutils
  • Ubuntu 24 修复
    • 临时移除了上游依赖崩溃的 tcpdump 包

校验和

e00d0c2ac45e9eff1cc77927f9cd09df  pigsty-v3.7.0.tgz
987529769d85a3a01776caefefa93ecb  pigsty-pkg-v3.7.0.d12.aarch64.tgz
2d8272493784ae35abeac84568950623  pigsty-pkg-v3.7.0.d12.x86_64.tgz
090cc2531dcc25db3302f35cb3076dfa  pigsty-pkg-v3.7.0.d13.x86_64.tgz
ddc54a9c4a585da323c60736b8560f55  pigsty-pkg-v3.7.0.el10.aarch64.tgz
d376e75c490e8f326ea0f0fbb4a8fd9b  pigsty-pkg-v3.7.0.el10.x86_64.tgz
8c2deeba1e1d09ef3d46d77a99494e71  pigsty-pkg-v3.7.0.el8.aarch64.tgz
9795e059bd884b9d1b2208011abe43cd  pigsty-pkg-v3.7.0.el8.x86_64.tgz
08b860155d6764ae817ed25f2fcf9e5b  pigsty-pkg-v3.7.0.el9.aarch64.tgz
1ac430768e488a449d350ce245975baa  pigsty-pkg-v3.7.0.el9.x86_64.tgz
e033aaf23690755848db255904ab3bcd  pigsty-pkg-v3.7.0.u22.aarch64.tgz
cc022ea89181d89d271a9aaabca04165  pigsty-pkg-v3.7.0.u22.x86_64.tgz
0e978598796db3ce96caebd76c76e960  pigsty-pkg-v3.7.0.u24.aarch64.tgz
48223898ace8812cc4ea79cf3178476a  pigsty-pkg-v3.7.0.u24.x86_64.tgz

9.3 - 测试版本

Pigsty 最新可用的 Beta 版本

你可以通过以下方式获取 Pigsty 的最新 Beta 版本:

curl -fsSL https://repo.pigsty.io/beta | bash; cd ~/pigsty   # 全球的默认仓库
curl -fsSL https://repo.pigsty.cc/beta | bash; cd ~/pigsty   # 中国的镜像站点

不过目前并没有可用的 Pigsty beta 版本,因为 最新的稳定版本v3.7.0 刚刚发布。

9.4 - PIG 发布

pig 包管理器发布说明

pig 是一个开源的 PostgreSQL(和扩展)包管理器,支持 主流 Linux 发行版。

在 (amd64 / arm64) 上使用原生 apt/yum/dnf 安装 PostgreSQL 13~18 以及 437 个扩展

最新稳定版本是 v0.7.4, 查看 GitHub 仓库pig 文档 了解更多详情。

版本 日期 摘要 GitHub
v0.7.4 2025-12-01 更新 ivory/pgtde 内核与 pgdg extras 仓库 v0.7.4
v0.7.3 2025-11-24 修复 el10 & debian13 仓库配置 v0.7.3
v0.7.2 2025-11-20 437 个扩展,修复 pig build 的一些问题 v0.7.2
v0.7.1 2025-11-10 新网站,改进容器内的使用体验 v0.7.1
v0.7.0 2025-11-05 强化 build 能力,大批量包更新 v0.7.0
v0.6.2 2025-10-03 正式提供 PG 18 支持 v0.6.2
v0.6.1 2025-08-14 CI/CD, el10 存根, PGDG 中国镜像 v0.6.1
v0.6.0 2025-07-17 423 个扩展,percona pg_tde,mcp 工具箱 v0.6.0
v0.5.0 2025-06-30 422 个扩展,新的扩展目录 v0.5.0
v0.4.2 2025-05-27 421 个扩展,halo 和 oriole deb v0.4.2
v0.4.1 2025-05-07 414 个扩展,pg18 别名支持 v0.4.1
v0.4.0 2025-05-01 do 和 pt 子命令,halo 和 orioledb v0.4.0
v0.3.4 2025-04-05 常规更新 v0.3.4
v0.3.3 2025-03-25 别名、仓库、依赖 v0.3.3
v0.3.2 2025-03-21 新扩展 v0.3.2
v0.3.1 2025-03-19 轻微错误修复 v0.3.1
v0.3.0 2025-02-24 新主页和扩展目录 v0.3.0
v0.2.2 2025-02-22 404 个扩展 v0.2.2
v0.2.0 2025-02-14 400 个扩展 v0.2.0
v0.1.4 2025-02-12 常规错误修复 v0.1.4
v0.1.3 2025-01-23 390 个扩展 v0.1.3
v0.1.2 2025-01-12 anon 扩展和其他 350 个扩展 v0.1.2
v0.1.1 2025-01-09 更新扩展列表 v0.1.1
v0.1.0 2024-12-29 repo、ext、sty 和自更新 v0.1.0
v0.0.1 2024-12-23 创世发布 v0.0.1

v0.7.4

  • 更新扩展版本与元数据:pg_searchpgmqpg_stat_monitor
  • 更新 PGDG 仓库 URL 变化,extras 仓库现在位于 yum 仓库顶层
  • 将 ivorysql 更新至 5.0 版本,与 PG 18 兼容
  • 将 Percona Postgres TDE 内核更新至 18.1

Checksums

5769b0051f04dcda22dd92b30b8effc8ddfa40097308bded76ce2b38d012ce57  pig-0.7.4-1.aarch64.rpm
d15c829fa2e3ce8dcd1adc063c107607b8e70f2cf747646aaa2fa257cdbf979c  pig-0.7.4-1.x86_64.rpm
bb4c90e253a3d470e50316e633a41e90ed2d4a5c5a1fd3a8dbb68ee87d831d47  pig-v0.7.4.darwin-amd64.tar.gz
faaf7ac7b08390f5048c081bb7a78100714387e35dc890e26d9746fc1caef415  pig-v0.7.4.darwin-arm64.tar.gz
037cacddd0dc1283f13dd2c9bace87ad7f2c74ffc245e629f1420be94bbf93df  pig-v0.7.4.linux-amd64.tar.gz
2ce819b2c3686cfb9f86790fdf61acd30bf7798bd6cd3c4f589df22e273dc867  pig-v0.7.4.linux-arm64.tar.gz
97f62d62f1cca61ce6d335efed88e3855d94ea2cd4ed941f2755fbac73931fcd  pig_0.7.4-1_amd64.deb
d2b80af89ed42601716f6b41eda3f8bee16db34023527df9deef8a43aa25a498  pig_0.7.4-1_arm64.deb

v0.7.3

  • 新增 pig repo reload 命令,更新仓库元数据
  • 修复 EL PGDG sysupdate aarch64 仓库问题。
  • 修复 EL10.aarch64 PGDG 仓库重命名问题。
  • 订正了若干扩展版本
  • 更新 Pigsty 版本至 3.7.0

校验和

786d72f6b685d6d6abf5f255f0a7de9204988a05630a26a53bfc7631823c0c6f  pig-0.7.3-1.aarch64.rpm
da59e24ef79d1164e348bacc43e3222e8e2778ec0e103e7ffc0c6df064758e8f  pig-0.7.3-1.x86_64.rpm
73062a979749095e89abc07dd583d34d4f57908bb4ee935cf7640f129ca6a2cb  pig-v0.7.3.darwin-amd64.tar.gz
ca5f5576f6d0d9be1d10cad769821be9daa62220b2fb56b94d6e4c0cede6da61  pig-v0.7.3.darwin-arm64.tar.gz
d193b4b87cf9a6e4775b1b07709802d30f0233ccb1b728843a09decb545168d3  pig-v0.7.3.linux-amd64.tar.gz
e7f612df0e8e4d9fac6df3765862b9e491bb50aad651856abf7a6935986e6f99  pig-v0.7.3.linux-arm64.tar.gz
3d5306ce95dcf704dd498b05325d942637564b13115f1e5a5bb9ef6781df1ba6  pig_0.7.3-1_amd64.deb
32e695ba2d49a741d8cd92008f8f2dec29f10754d35b732035f48517b382c30d  pig_0.7.3-1_arm64.deb

v0.7.2

  • 批量更新扩展,数量达到 437 个

  • 新增 PGDG EL10 Sysupdate 仓库

  • 新增 LLVM APT 仓库

  • 在 pig build 命令中使用可选的本地 extension.csv 扩展定义问题。

  • 更新的扩展: vchord pg_later pgvectorscale pglite_fusion pgx_ulid pg_search citus timescaledb pg_profile pg_stat_monitor documentdb

  • 新增的扩展:pglinter pg_typeid pg_enigma pg_retry pg_biscuit pg_weighted_statistics

校验和

f303c391fc28bc74832712e0aa58319abe0ebcae4f6c07fdf9a9e542b735d2ec  pig-0.7.2-1.aarch64.rpm
c096a61a4e3a49b1238659664bbe2cd7f29954c43fb6bb8e8e9fb271f95a612e  pig-0.7.2-1.x86_64.rpm
5e037c891dff23b46856485108d6f64bede5216dfbd4f38a481f0d0672ee910b  pig-v0.7.2.darwin-amd64.tar.gz
736b4b47999c543c3c886781f4d8dddbf4276f363c35c7bf50094b6f18d14600  pig-v0.7.2.darwin-arm64.tar.gz
20b13f059efed29dd76f6927b3e8d7b597c0c8d734f9e22ba3d0a2af6dbcd3bf  pig-v0.7.2.linux-amd64.tar.gz
9548b530c05f2ffdc8d73b8f890718d47b74a51eb62852a99c08b1b52e47f014  pig-v0.7.2.linux-arm64.tar.gz
b6faad9f92b926546a10f590274f2cb2afff21b9cea878094cfc5caf09e67d2c  pig_0.7.2-1_amd64.deb
452f73f1fa035e5417ab49fc51d797925550179ffcc023e8f03d80144309212a  pig_0.7.2-1_arm64.deb

v0.7.1

  • 全新的网站: https://pgext.cloud
  • 修复了不必要的 sudo 使用问题,现在可以方便的在容器中使用
  • 允许 pig ext link 命令使用形如 pg17 pg18 的参数形式
  • 新增环境变量 PIG_NO_SUDO,强制不使用 sudo 执行命令
  • RPM 变更日志: 为几乎所有扩展新增 PG 18 支持
  • DEB 变更日志: 为几乎所有扩展新增 PG 18 支持
  • Infra 变更日志: 例行更新至最新版本

校验和

a696c9ec784e2fc248e5f3d87cc8aae4116e890f78c5997957d30593f2c85ca6  pig-0.7.1-1.aarch64.rpm
f669538a99cd1dc592d3005b949628fcceb9e78114fc78862d7726b340ee194d  pig-0.7.1-1.x86_64.rpm
e42bdaaf93b720c5b76b32b57362320e4b447109740c76089aefe030b7c8b836  pig-v0.7.1.darwin-amd64.tar.gz
b4c240aadad34e785666ee0a755d9b7455724f790c2d088a1dd7c37ad3b2a457  pig-v0.7.1.darwin-arm64.tar.gz
ffc687add0ca71ac90cba5749c8a7a6075cf7618cba85584072831cf3eb182f7  pig-v0.7.1.linux-amd64.tar.gz
7b0d1f158150d0a40c525692f02b6bce9f5b4ac523a4e59278d702c334e222e1  pig-v0.7.1.linux-arm64.tar.gz
43e91a3bea273d7cacb2d7a58c0a5745501dbd06348b5cb3af971171fae70268  pig_0.7.1-1_amd64.deb
fc2a34aeb46e07cb0ae93611de47d6622c3bd46fe4c415ce4c9091840e0e08a2  pig_0.7.1-1_arm64.deb

v0.7.0

  • 提供针对 Debian 13 和 EL 10 发行版的支持
  • 大批量扩展更新至最新版本,带有 PostgreSQL 18 支持。
  • 几乎所有 Rust 扩展现已通过 pgrx 0.16.1 支持 PG 18
  • pig build 命令彻底重做
    • pig build pkg <pkg> 现在会一条龙完成扩展的下载,依赖安装,构建
    • pig build pgrx 命令现在从 pig build rust 中分离
    • pig build pgrx [-v pgrx_version] 现在可以直接使用现有的 PG 安装
    • pig build dep 现在会处理 EL 和 Debian 系统下的扩展依赖
    • pig build ext 命令现在有了更为紧凑和美观的输出,可在 EL 下不依赖 build 脚本直接构建 RPM
    • pig build spec 现在支持直接从Pigsty仓库下载 spec 文件包
    • pig build repo / pig repo add / pig repo set 现在默认使用 node,pgsql,infra 仓库模块,取代原本的 node,pgdg,pigsty
  • 大量优化了错误日志记录。
  • 基于 hugo 与 hextra 全新目录网站

校验和

ad60f9abcde954769e46eb23de61965e  pig_0.7.0-1_amd64.deb
aa15d7088d561528e38b2778fe8f7cf9  pig_0.7.0-1_arm64.deb
05549fe01008e04f8d5a59d4f2a5f0b8  pig-0.7.0-1.aarch64.rpm
0cc9e46c7c72d43c127a6ad115873b67  pig-0.7.0-1.x86_64.rpm
ddacfb052f3f3e5567a02e92fdb31cdd  pig-v0.7.0.darwin-amd64.tar.gz
17d25b565308d3d35513e4b0d824946b  pig-v0.7.0.darwin-arm64.tar.gz
ee7e055ceff638039956765fb747f80b  pig-v0.7.0.linux-amd64.tar.gz
284e674807b87447d4b33691fd7a420d  pig-v0.7.0.linux-arm64.tar.gz

v0.6.2

  • 使用 PG 18 官方正式仓库取代原本的 Testing Beta 仓库 instead of testing repo
  • 在接收 Pigsty 版本字符串的时候,自动添加 v 前缀
  • 改进了网络检查与下载的逻辑

校验和

01f5b7dc20644226c762dbb229768347  pig_0.6.2-1_amd64.deb
ce4f00256adc12cbea91467b7f2241cd  pig_0.6.2-1_arm64.deb
cefc36ae8f348aede533b30836fba720  pig-0.6.2-1.aarch64.rpm
d04a287c6eb92b11ecbf99542c2db602  pig-0.6.2-1.x86_64.rpm
e637ca86a7f38866c67686b060223d9a  pig-v0.6.2.darwin-amd64.tar.gz
79749bc69c683586bd8d761bdf6af98e  pig-v0.6.2.darwin-arm64.tar.gz
ad4f02993c7d7d8eec142f0224551bb4  pig-v0.6.2.linux-amd64.tar.gz
9793affa4a0cb60e9753e65b7cba3dca  pig-v0.6.2.linux-arm64.tar.gz

v0.6.1

  • 新增 el10 与 debian 13 trixie 的支持存根
  • 专门的新文档网站: https://pgext.cloud/pig
  • 使用 go 1.25 重新构建,新增 CI/CD 管道
  • 在中国大陆使用 PIGSTY PGDG 镜像
  • 移除空的 pgdg-el10fix 仓库
  • 使用 Pigsty WiltonDB 镜像
  • 修复 EL 10 专用的 EPEL 仓库
  • pig version 输出构建环境信息

v0.6.0

  • 新扩展目录:https://ext.pgsty.com
  • 新子命令:pig install 简化 pig ext install
  • 添加新内核支持:带 pg_tde 的 percona
  • 添加新包:Google GenAI MCP 数据库工具箱
  • 添加新仓库:percona 仓库和 clickhouse 仓库
  • 将扩展摘要信息链接更改为 https://ext.pgsty.com
  • 修复 orioledb 在 Debian/Ubuntu 系统上的问题
  • 修复 EL 发行版上的 epel 仓库
  • 将 golang 升级到 1.24.5
  • 将 pigsty 升级到 v3.6.0

校验和

1804766d235b9267701a08f95903bc3b  pig_0.6.0-1_amd64.deb
35f4efa35c1eaecdd12aa680d29eadcb  pig_0.6.0-1_arm64.deb
b523b54d9f2d7dcc5999bcc6bd046b1d  pig-0.6.0-1.aarch64.rpm
9434d9dca7fd9725ea574c5fae1a7f52  pig-0.6.0-1.x86_64.rpm
f635c12d9ad46a779aa7174552977d11  pig-v0.6.0.linux-amd64.tar.gz
165af4e63ec0031d303fe8b6c35c5732  pig-v0.6.0.linux-arm64.tar.gz

v0.5.0

  • 将扩展列表更新至 422 个
  • 新扩展:来自 AWS 的 pgactive
  • 将 timescaledb 升级到 2.20.3
  • 将 citus 升级到 13.1.0
  • 将 vchord 升级到 0.4.3
  • 修复错误:pgvectorscale debian/ubuntu pg17 失败
  • 将 kubernetes 仓库升级到 1.33
  • 将默认 pigsty 版本升级到 3.5.0

校验和

9ec6f3caf3edbe867caab5de0e0ccb33  pig_0.5.0-1_amd64.deb
4fbb0a42cd8a88bce50b3c9d85745d77  pig_0.5.0-1_arm64.deb
9cf8208396b068cab438f72c90d39efe  pig-0.5.0-1.aarch64.rpm
d9a8d78c30f45e098b29c3d16471aa8d  pig-0.5.0-1.x86_64.rpm
761df804ff7b83965c41492700717674  pig-v0.5.0.linux-amd64.tar.gz
5d1830069d98030728f08835f883ea39  pig-v0.5.0.linux-arm64.tar.gz

发布:https://github.com/pgsty/pig/releases/tag/v0.5.0


v0.4.2

  • 将扩展列表更新至 421 个
  • 为 Debian / Ubuntu 添加 openhalo/orioledb 支持
  • pgdd 0.6.0 (pgrx 0.14.1)
  • convert 0.0.4 (pgrx 0.14.1)
  • pg_idkit 0.3.0 (pgrx 0.14.1)
  • pg_tokenizer.rs 0.1.0 (pgrx 0.13.1)
  • pg_render 0.1.2 (pgrx 0.12.8)
  • pgx_ulid 0.2.0 (pgrx 0.12.7)
  • pg_ivm 1.11.0 适用于 debian/ubuntu
  • orioledb 1.4.0 beta11
  • 重新添加 el7 仓库

校验和

bbf83fa3e3ec9a4dca82eeed921ae90a  pig_0.4.2-1_amd64.deb
e45753335faf80a70d4f2ef1d3100d72  pig_0.4.2-1_arm64.deb
966d60bbc2025ba9cc53393011605f9f  pig-0.4.2-1.aarch64.rpm
1f31f54da144f10039fa026b7b6e75ad  pig-0.4.2-1.x86_64.rpm
1eec26c4e69b40921e209bcaa4fe257a  pig-v0.4.2.linux-amd64.tar.gz
768d43441917a3625c462ce9f2b9d4ef  pig-v0.4.2.linux-arm64.tar.gz

发布:https://github.com/pgsty/pig/releases/tag/v0.4.2


v0.4.1

  • 将扩展列表更新至 414 个
  • pig ext scan 映射中添加 citus_wal2jsoncitus_pgoutput
  • 添加 PG 18 beta 仓库
  • 添加 PG 18 包别名

扩展包更新

  • omnigres 20250507
  • citus 12.0.3
  • timescaledb 2.19.3
  • supautils 2.9.1
  • pg_envvar 1.0.1
  • pgcollection 1.0.0
  • aggs_for_vecs 1.4.0
  • pg_tracing 0.1.3
  • pgmq 1.5.1
  • tzf-pg 0.2.0 (pgrx 0.14.1)
  • pg_search 0.15.18 (pgrx 0.14.1)
  • anon 2.1.1 (pgrx 0.14.1)
  • pg_parquet 0.4.0 (0.14.1)
  • pg_cardano 1.0.5 (pgrx 0.12) -> 0.14.1
  • pglite_fusion 0.0.5 (pgrx 0.12.8) -> 14.1
  • vchord_bm25 0.2.1 (pgrx 0.13.1)
  • vchord 0.3.0 (pgrx 0.13.1)
  • pg_vectorize 0.22.1 (pgrx 0.13.1)
  • wrappers 0.4.6 (pgrx 0.12.9)
  • timescaledb-toolkit 1.21.0 (0.12.9)
  • pgvectorscale 0.7.1 (pgrx 0.12.9)
  • pg_session_jwt 0.3.1 (pgrx 0.12.6) -> 0.12.9

校验和

e2c1037c20f97c6f5930876ee82b6392  pig_0.4.1-1_amd64.deb
8197b6b5b95d1d1ae95e0a0e50355ecb  pig_0.4.1-1_arm64.deb
9d3a261d31c92fc73fe5bbfcd5b8e8ba  pig-0.4.1-1.aarch64.rpm
ffcec2a2ae965d14b9d3d80278fd340c  pig-0.4.1-1.x86_64.rpm
01d3128e782f35a20f0c81480cbe9025  pig-v0.4.1.linux-amd64.tar.gz
b2655628df326a1d0ed13f3dd8762c65  pig-v0.4.1.linux-arm64.tar.gz

发布:https://github.com/pgsty/pig/releases/tag/v0.4.1


v0.4.0

  • 更新扩展列表,可用扩展达到 407
  • 添加 pig do 子命令用于执行 Pigsty playbook 任务
  • 添加 pig pt 子命令用于包装 Patroni 命令行工具
  • 添加扩展别名:openhaloorioledb
  • 添加 gitlab-ce / gitlab-ee 仓库区分
  • 使用最新 Go 1.24.2 构建并升级依赖项版本
  • 修复特定条件下 pig ext status 的 panic 问题
  • 修复 pig ext scan 无法匹配多个扩展的问题

扩展包更新

  • 将 pg_search 更新到 0.15.13
  • 将 citus 更新到 13.0.3
  • 将 timescaledb 更新到 2.19.1
  • 将 pgcollection RPM 更新到 1.0.0
  • 将 pg_vectorize RPM 更新到 0.22.1
  • 将 pglite_fusion RPM 更新到 0.0.4
  • 将 aggs_for_vecs RPM 更新到 1.4.0
  • 将 pg_tracing RPM 更新到 0.1.3
  • 将 pgmq RPM 更新到 1.5.1

校验和

bbc0adf94b342ac450c7999ea1c5ab76  pig_0.4.0-1_amd64.deb
7445b819624e7498b496edb12a36f426  pig_0.4.0-1_arm64.deb
835ce929afac0fb1f249f55571fbed97  pig-0.4.0-1.aarch64.rpm
25ba5a846095e17d2bfa2f15fe4e4b44  pig-0.4.0-1.x86_64.rpm
1568b163ffa23cb921ee439452ca4de9  pig-v0.4.0.linux-amd64.tar.gz
9f2ab3f5d1e29807a9642dfbe1dc9b0e  pig-v0.4.0.linux-arm64.tar.gz

发布:https://github.com/pgsty/pig/releases/tag/v0.4.0


v0.3.4

curl https://repo.pigsty.io/pig | bash -s 0.3.4
  • 常规扩展元数据更新
  • 使用阿里云 epel 镜像代替损坏的清华大学 tuna 镜像
  • 升级 pigsty 版本字符串
  • 在仓库列表中添加 gitlab 仓库

校验和

5c0bba04d955bbe6a29d24d31aa17c6b  pig-0.3.4-1.aarch64.rpm
42636b9fc64d7882391d856d36d715e7  pig-0.3.4-1.x86_64.rpm
1a6296421d642000ad75a5a41bc9ab96  pig-v0.3.4.linux-amd64.tar.gz
f7ea5ba8abaa89e866811e5b2508e82f  pig-v0.3.4.linux-arm64.tar.gz
2dd63cdb5965f78a48da462a0453001d  pig_0.3.4-1_amd64.deb
094b9e028e81c46d71ee315d8a223ada  pig_0.3.4-1_arm64.deb

发布:https://github.com/pgsty/pig/releases/tag/v0.3.4


v0.3.3

  • 添加 pig build dep 命令安装扩展构建依赖项
  • 更新默认仓库列表
  • mssql 模块(wiltondb/babelfish)使用 pigsty.io 镜像
  • 将 docker 模块合并到 infra
  • 从 el7 目标中移除 pg16/17
  • 允许在 el7 中安装扩展
  • 更新包别名
  • pgsqlpgsql-mainpgsql-corepgsql-minipgsql-full
  • ivorysql 现在映射到 ivorysql4
  • timescaledb-utils
  • pgbackrest_exporter
  • 移除 pgsql-simple
  • 拉取 #13 将 github.com/golang-jwt/jwt/v5 从 5.2.1 升级到 5.2.2
  • 将 polardb 升级到 15.12.3.0-e1e6d85b
  • pig repo set 现在会自动更新元缓存
  • 清理嵌入的 pigsty tarball

更改内容

新贡献者

完整变更日志:https://github.com/pgsty/pig/compare/v0.3.2…v0.3.3

发布:https://github.com/pgsty/pig/releases/tag/v0.3.3

校验和

4e10567077e5d8cefd94d1c7aeb9478b  pig-0.3.3-1.aarch64.rpm
cc8a423abeb0f5316b427097993b9c6e  pig-0.3.3-1.x86_64.rpm
835d4f63b4ee0b36e2322a4ffef6527a  pig-v0.3.3.linux-amd64.tar.gz
c43e082c661e75d91f1c726e60911ea3  pig-v0.3.3.linux-arm64.tar.gz
938db83c5ca065419b8185adb285ed5a  pig_0.3.3-1_amd64.deb
75af6731adc4d31aa3458d70fc7f4e42  pig_0.3.3-1_arm64.deb

发布:https://github.com/pgsty/pig/releases/tag/v0.3.3


v0.3.2

增强功能

  • 新扩展
  • 使用 upx 减少二进制大小
  • 移除嵌入的 pigsty 以减少二进制大小
  • 允许指定 -y 强制重新安装 rust 在 pig build rust
  • 允许指定 -v 指定要安装的 pgrx 版本

新扩展

405 个 PG 扩展列表:

  • apache age 13 - 17 el rpm (1.5.0)
  • pgspider_ext 1.3.0 (新扩展)
  • timescaledb 2.18.2 -> 2.19.0
  • citus 13.0.1 -> 13.0.2
  • documentdb 1.101-0 -> 1.102-0
  • pg_analytics: 0.3.4 -> 0.3.7
  • pg_search: 0.15.2 -> 0.15.8
  • pg_ivm 1.9 -> 1.10
  • emaj 4.4.0 -> 4.6.0
  • pgsql_tweaks 0.10.0 -> 0.11.0
  • pgvectorscale 0.4.0 -> 0.6.0 (pgrx 0.12.5)
  • pg_session_jwt 0.1.2 -> 0.2.0 (pgrx 0.12.6)
  • wrappers 0.4.4 -> 0.4.5 (pgrx 0.12.9)
  • pg_parquet 0.2.0 -> 0.3.1 (pgrx 0.13.1)
  • vchord 0.2.1 -> 0.2.2 (pgrx 0.13.1)
  • pg_tle 1.2.0 -> 1.5.0
  • supautils 2.5.0 -> 2.6.0
  • sslutils 1.3 -> 1.4
  • pg_profile 4.7 -> 4.8
  • pg_snakeoil 1.3 -> 1.4
  • pg_jsonschema 0.3.2 -> 0.3.3
  • pg_incremental: 1.1.1 -> 1.2.0
  • pg_stat_monitor 2.1.0 -> 2.1.1
  • 修复 ddl_historization 版本 0.7 -> 0.0.7
  • 修复 pg_sqlog 3.1.7 -> 1.6
  • 修复 pg_random 移除 dev 后缀
  • asn1oid 1.5 -> 1.6
  • table_log 0.6.1 -> 0.6.4

校验和

f773aedf4a76d031f411cb38bc623134  pig-0.3.2-1.aarch64.rpm
fa9084877deb57d4882b7d9531ea0369  pig-0.3.2-1.x86_64.rpm
7f9a03c9dd23cba094191a8044fa0263  pig-v0.3.2.linux-amd64.tar.gz
adda8986efc048565834cda1ef206a20  pig-v0.3.2.linux-arm64.tar.gz
5b27cefdc716629db8f1fbc534f58691  pig_0.3.2-1_amd64.deb
936e85bda5818da4c20b758ebd65e618  pig_0.3.2-1_arm64.deb

发布:https://github.com/pgsty/pig/releases/tag/v0.3.2


v0.3.1

常规错误修复

  • 修复仓库格式字符串
  • 修复扩展信息链接
  • 更新 pg_mooncake 元数据

校验和

9251aa18e663f1ecf239adcba3a798b9  pig-0.3.1-1.aarch64.rpm
3b91e7faa78c5f0283d27ffe632dda46  pig-0.3.1-1.x86_64.rpm
87c75dfd114252230c53ee8c5d60dac4  pig-v0.3.1.linux-amd64.tar.gz
82832ae767e226627087b97a87982daf  pig-v0.3.1.linux-arm64.tar.gz
4d99f9c03915accf413b6374b75f1bdb  pig_0.3.1-1_amd64.deb
e38e8a21ed73a37d4588053f8c900f7c  pig_0.3.1-1_arm64.deb

发布:https://github.com/pgsty/pig/releases/tag/v0.3.1


v0.3.0

pig 项目现在有了新的 主页,以及 PostgreSQL 扩展 目录

curl https://repo.pigsty.io/pig | bash    # cloudflare
curl https://repo.pigsty.cc/pig | bash    # 中国 cdn

您可以使用简单的命令安装 PostgreSQL 内核以及 404 个扩展。此外, pig v0.3 也嵌入并随最新的 Pigsty v3.3.0 一起发布。

新功能

pig build 子命令具有设置扩展构建环境的 能力

pig build repo     # 初始化构建仓库 (=repo set -ru)
pig build tool     # 初始化构建工具集
pig build rust     # 初始化 rustc 和 pgrx (0.12.9)
pig build spec     # 初始化 rpm/deb spec 仓库
pig build get      # 获取扩展源码 tarball
pig build ext      # 构建扩展
## 下载大型 tarball
pig build get std          # 下载 std 小型 tarball
pig build get all          # 下载所有源码 tarball
pig build get pg_mooncake
pig build get pg_duckdb
pig build get omnigres
pig build get plv8
pig build get citus

pig build ext citus
pig build ext timescaledb

以及其他工具,如构建代理:

pig build proxy                  # 安装 v2ray 代理
pig build proxy [user@host:port] # 初始化并设置代理

pig 0.3.0 随 Pigsty 3.3.0 一起发布

新扩展

pgext.cloud 目录正在迁移到 https://pgext.cloud/list,包含更多信息!

ecosystem

校验和

9cc3848ab13c41a0415f1fea6294ad2d  pig-0.3.0-1.aarch64.rpm
ee99a6c1ff17975ed184f009a4b1aac5  pig-0.3.0-1.x86_64.rpm
b06f6b5aeaa83a9d76c9b563b2516e1c  pig-v0.3.0.linux-amd64.tar.gz
d783732413e4f32074adeab2d5d092c3  pig-v0.3.0.linux-arm64.tar.gz
7c942b8dbd78458d5371c1abca2571c6  pig_0.3.0-1_amd64.deb
c0a411cf53cb58706ca81b49b4fc840e  pig_0.3.0-1_arm64.deb

发布:https://github.com/pgsty/pig/releases/tag/v0.3.0


v0.2.2

Pig v0.2.2 中提供 404 个扩展

curl https://repo.pigsty.io/pig | bash -s v0.2.2
  • documentdb 0.101-0
  • pgcollection (新) 0.9.1
  • pg_bzip (新) 1.0.0
  • pg_net 0.14.0 (部分发行版)
  • pg_curl 2.4.2
  • vault 0.3.1 (SQL -> C)
  • table_version 1.10.3 -> 1.11.0
  • pg_duration 1.0.2
  • timescaledb 2.18.2
  • pg_analytics 0.3.4
  • pg_search 0.15.2
  • pg_graphql 1.5.11
  • vchord 0.1.1 -> 0.2.1 ((+13))
  • vchord_bm25 0.1.0 -> 0.1.1
  • pg_mooncake 0.1.1 -> 0.1.2
  • pg_duckdb 0.2.0 -> 0.3.1
  • pgddl 0.29
  • pgsql_tweaks 0.11.0

发布:https://github.com/pgsty/pig/releases/tag/v0.2.2


v0.2.0

使用以下命令安装最新的 pig 版本:

curl -fsSL https://repo.pigsty.io/pig | bash

新扩展

更新扩展版本

  • citus 13.0.0 -> 13.0.1
  • pg_mooncake 0.1.0 -> 0.1.1
  • timescaledb 2.17.2 -> 2.18.1
  • supautils 2.5.0 -> 2.6.0
  • VectorChord 0.1.0 -> 0.2.0
  • pg_bulkload 3.1.22 (+pg17)
  • pg_store_plan 1.8 (+pg17)
  • pg_search 0.14 -> 0.15.1
  • pg_analytics 0.3.0 -> 0.3.2
  • pgroonga 3.2.5 -> 4.0.0
  • zhparser 2.2 -> 2.3
  • pg_vectorize 0.20.0 -> 0.21.1

发布:https://github.com/pgsty/pig/releases/tag/v0.2.0


v0.1.4

使用以下命令安装最新的 pig 版本:

curl -fsSL https://repo.pigsty.io/pig | bash

新扩展

更新扩展版本

  • citus 13.0.0 -> 13.0.1
  • pg_mooncake 0.1.0 -> 0.1.1
  • timescaledb 2.17.2 -> 2.18.1
  • supautils 2.5.0 -> 2.6.0
  • VectorChord 0.1.0 -> 0.2.0
  • pg_bulkload 3.1.22 (+pg17)
  • pg_store_plan 1.8 (+pg17)
  • pg_search 0.14 -> 0.15.1
  • pg_analytics 0.3.0 -> 0.3.2
  • pgroonga 3.2.5 -> 4.0.0
  • zhparser 2.2 -> 2.3
  • pg_vectorize 0.20.0 -> 0.21.1

校验和

6da06705be1c179941327c836d455d35  pig-0.1.4-1.aarch64.rpm
9fa5712e3cfe56e0dcf22a11320b01b1  pig-0.1.4-1.x86_64.rpm
af506dc37f955a7a2e31ff11e227450c  pig-v0.1.4.linux-amd64.tar.gz
1e6eb3dc1ad26f49b07afabdd9142d4e  pig-v0.1.4.linux-arm64.tar.gz
83ae89b58bff003da5c3022eeac1786e  pig_0.1.4_amd64.deb
d6778e628d82bddf3fae1e058e1e05e4  pig_0.1.4_arm64.deb

发布:https://github.com/pgsty/pig/releases/tag/v0.1.4


v0.1.3

v0.1.3,常规更新,现在可用 390 个扩展!

curl https://repo.pigsty.io/pig | bash
curl https://repo.pigsty.cc/pig | bash

校验和

c79b74f676b03482859f5519b279b657  pig-0.1.3-1.aarch64.rpm
1d00a7cd5855a65e4db964075a5e49f6  pig-0.1.3-1.x86_64.rpm
6cd8507b130fca093247278e36d9478b  pig-v0.1.3.linux-amd64.tar.gz
5eee92908701b0d456ec3c15bc817c0b  pig-v0.1.3.linux-arm64.tar.gz
cb376ef2c3512ad35ff43132942c0052  pig_0.1.3_amd64.deb
2b545abc617670a96c2edd13878e0227  pig_0.1.3_arm64.deb

发布:https://github.com/pgsty/pig/releases/tag/v0.1.3


v0.1.2

351 个 PostgreSQL 扩展,包括强大的 postgresql-anonymizer 2.0

现在您可以使用以下方式安装 pig:

curl -fsSL https://repo.pigsty.io/pig | bash
curl -fsSL https://repo.pigsty.cc/pig | bash

添加新扩展

  • 添加 pg_anon 2.0.0
  • 添加 omnisketch 1.0.2
  • 添加 ddsketch 1.0.1
  • 添加 pg_duration 1.0.1
  • 添加 ddl_historization 0.0.7
  • 添加 data_historization 1.1.0
  • 添加 schedoc 0.0.1
  • 添加 floatfile 1.3.1
  • 添加 pg_upless 0.0.3
  • 添加 pg_task 1.0.0
  • 添加 pg_readme 0.7.0
  • 添加 vasco 0.1.0
  • 添加 pg_xxhash 0.0.1

更新扩展

  • lower_quantile 1.0.3
  • quantile 1.1.8
  • sequential_uuids 1.0.3
  • pgmq 1.5.0 (subdir)
  • floatvec 1.1.1
  • pg_parquet 0.2.0
  • wrappers 0.4.4
  • pg_later 0.3.0
  • 修复 topn for deb.arm64
  • 在 debian 上添加 age 17
  • powa + pg17, 5.0.1
  • h3 + pg17
  • ogr_fdw + pg17
  • age + pg17 1.5 在 debian
  • pgtap + pg17 1.3.3
  • repmgr
  • topn + pg17
  • pg_partman 5.2.4
  • credcheck 3.0
  • ogr_fdw 1.1.5
  • ddlx 0.29
  • postgis 3.5.1
  • tdigest 1.4.3
  • pg_repack 1.5.2

发布:https://github.com/pgsty/pig/releases/tag/v0.1.2


v0.1.0

pig CLI v0.1 发布,具有以下新功能:

安装脚本

curl -fsSL https://repo.pigsty.io/pig | bash     # cloudflare,默认
curl -fsSL https://repo.pigsty.cc/pig | bash     # 中国大陆镜像

扩展管理

您可以使用 import 子命令下载扩展及其依赖项,使用 link 激活不同的 postgres 主版本,并使用 build 子命令准备构建环境

pig ext list    [query]      # 列出和搜索扩展
pig ext info    [ext...]     # 获取特定扩展的信息
pig ext status  [-v]         # 显示已安装的扩展和 pg 状态
pig ext add     [ext...]     # 为当前 pg 版本安装扩展
pig ext rm      [ext...]     # 为当前 pg 版本移除扩展
pig ext update  [ext...]     # 将扩展更新到最新版本
pig ext import  [ext...]     # 将扩展下载到本地仓库
pig ext link    [ext...]     # 将 postgres 安装链接到路径
pig ext build   [ext...]     # 为扩展设置构建环境

仓库管理

您现在可以创建本地仓库并从中创建 tarball(离线包),将其复制到某处(例如,没有互联网访问),并从该离线包创建仓库:

pig repo list                    # 可用仓库列表              (info)
pig repo info   [repo|module...] # 显示仓库信息               (info)
pig repo status                  # 显示当前仓库状态           (info)
pig repo add    [repo|module...] # 添加仓库和模块             (root)
pig repo rm     [repo|module...] # 移除仓库和模块             (root)
pig repo update                  # 更新仓库包缓存             (root)
pig repo create                  # 在当前系统上创建仓库       (root)
pig repo boot                    # 从离线包启动仓库           (root)
pig repo cache                   # 将仓库缓存为离线包         (root)

Pigsty 管理

pig 也可以用作 Pigsty 的 CLI 工具——电池级免费 PostgreSQL RDS

pig sty init     # 将嵌入的 pigsty 安装到 ~/pigsty
pig sty boot     # 安装 ansible 和其他预依赖项
pig sty conf     # 自动生成 pigsty.yml 配置文件
pig sty install  # 运行 install.yml playbook

自更新

要将 pig 本身更新到最新版本,您可以使用以下命令:

pig update

信息

现在 pig info 提供有关您的 OS 和 PG 环境的更多详细信息:

$ pig info

# [Configuration] ================================
Pig Version      : 0.1.0
Pig Config       : /home/vagrant/.pig/config.yml
Log Level        : info
Log Path         : stderr

# [OS Environment] ===============================
OS Distro Code   : el9
OS Architecture  : amd64
OS Package Type  : rpm
OS Vendor ID     : rocky
OS Version       : 9
OS Version Full  : 9.3
OS Version Code  : el9

# [PG Environment] ===============================
Installed:
* PostgreSQL 17.2  74  Extensions

Active:
PG Version      :  PostgreSQL 17.2
Config Path     :  /usr/pgsql-17/bin/pg_config
Binary Path     :  /usr/pgsql-17/bin
Library Path    :  /usr/pgsql-17/lib
Extension Path  :  /usr/pgsql-17/share/extension

# [Pigsty Environment] ===========================
Inventory Path   : /home/vagrant/pigsty/pigsty.yml
Pigsty Home      : /home/vagrant/pigsty
Embedded Version : 3.2.0

# [Network Conditions] ===========================
pigsty.cc  ping ok: 141 ms
pigsty.io  ping ok: 930 ms
google.com request error
Internet Access   :  true
Pigsty Repo       :  pigsty.io
Inferred Region   :  china
Latest Pigsty Ver :  v3.2.0

享受 PostgreSQL!

更改内容

新贡献者

完整变更日志:https://github.com/pgsty/pig/compare/v0.0.1…v0.1.0

校验和

46165beec97ab9ff1314f80af953bd59  pig-0.1.0-1.aarch64.rpm
1320a6f9bfbd79948515657d6becbf37  pig-0.1.0-1.x86_64.rpm
bd078a5dc0c41454fcbbe0d8693d5fa0  pig-v0.1.0.linux-amd64.tar.gz
8a15e52f96735b78afa7da42843f1504  pig-v0.1.0.linux-arm64.tar.gz
4d25597cff8425c7e52a2b411344aa4a  pig_0.1.0_amd64.deb
d5f0874601bc1bbd0dd40b5c9982ea9f  pig_0.1.0_arm64.deb

发布:https://github.com/pgsty/pig/releases/tag/v0.1.0


v0.0.1

入门

首先安装 pig 包,您也可以通过命令安装:

curl -fsSL https://repo.pigsty.io/pig | bash     # cloudflare,默认
curl -fsSL https://repo.pigsty.cc/pig | bash     # 中国大陆镜像

然后就可以使用了,假设您想安装 pg_duckdb 扩展:

$ pig repo add pigsty pgdg -u  # 添加 pgdg 和 pigsty 仓库,更新缓存
$ pig ext install pg17         # 使用 PGDG 原生包安装 PostgreSQL 17 内核
$ pig ext install pg_duckdb    # 安装 pg_duckdb 扩展(用于当前 pg17)

就是这样!全部设置好了!您可以使用 pig ext status 子命令检查:

$ pig ext status               # 显示已安装的扩展和 pg 状态
                               # 要打印内置 contrib 扩展,使用 -c|--contrib 标志
Installed PG Vers :  17 (active)
Active PostgreSQL :  PostgreSQL 17.2
PostgreSQL        :  PostgreSQL 17.2
Binary Path       :  /usr/pgsql-17/bin
Library Path      :  /usr/pgsql-17/lib
Extension Path    :  /usr/pgsql-17/share/extension
Extension Stat    :  1 Installed (PIGSTY 1, PGDG 0) + 67 CONTRIB = 68 Total

Name       Version  Cate  Flags   License  Repo    Package        Description
----       -------  ----  ------  -------  ------  ------------   ---------------------
pg_duckdb  0.2.0    OLAP  -dsl--  MIT      PIGSTY  pg_duckdb_17*  DuckDB Embedded in Postgres

(1 Rows) (Flags: b = HasBin, d = HasDDL, s = HasSolib, l = NeedLoad, t = Trusted, r = Relocatable, x = Unknown)

查看高级用法详情和 列出 340 个可用扩展

安装

pig 工具是一个独立的 go 二进制文件,没有依赖项。您可以直接下载二进制文件或使用以下命令添加仓库并通过包管理器安装(推荐)。

对于 Ubuntu 22.04 / 24.04 和 Debian 12 或任何兼容平台:

sudo tee /etc/apt/sources.list.d/pigsty.list > /dev/null <<EOF
deb [trusted=yes] https://repo.pigsty.io/apt/infra generic main
EOF
sudo apt update; sudo apt install -y pig

对于 EL 8/9 和兼容平台:

sudo tee /etc/yum.repos.d/pigsty.repo > /dev/null <<-'EOF'
[pigsty-infra]
name=Pigsty Infra for $basearch
baseurl=https://repo.pigsty.io/yum/infra/$basearch
enabled = 1
gpgcheck = 0
module_hotfixes=1
EOF
sudo yum makecache; sudo yum install -y pig

对于中国大陆用户:考虑将 repo.pigsty.io 替换为 repo.pigsty.cc

兼容性

pig 运行在:RHEL 8/9、Ubuntu 22.04/24.04 和 Debian 12,支持 amd64/arm64 架构

代码 发行版 x86_64 aarch64
el9 RHEL 9 / Rocky9 / Alma9 / … PG 17 - 13 PG 17 - 13
el8 RHEL 8 / Rocky8 / Alma8 / … PG 17 - 13 PG 17 - 13
u24 Ubuntu 24.04 (noble) PG 17 - 13 PG 17 - 13
u22 Ubuntu 22.04 (jammy) PG 17 - 13 PG 17 - 13
d12 Debian 12 (bookworm) PG 17 - 13 PG 17 - 13

以下是上述发行版的一些坏情况和限制:

  • citusaarch64 和 ubuntu 24.04 上不可用
  • pljavael8 上缺失
  • jdbc_fdwel8.aarch64el9.aarch64 上缺失
  • plluael8.aarch64 上对 pg 13,14,15 缺失
  • topnel8.aarch64el9.aarch64 上对 pg13 缺失,以及所有 deb.aarch64
  • pg_partmantimeseriesu24 上对 pg13 缺失
  • wiltondbd12 上缺失

发布:https://github.com/pgsty/pig/releases/tag/v0.0.1

9.5 - PG Exporter

pg_exporter 指标收集器发布说明

Prometheus 提供的高级 PostgreSQLpgBouncer 指标 exporter

PG Exporter 通过声明式配置动态规划可定制收集器为您的 PostgreSQL 带来终极监控体验。 它提供 600+ 指标和每个实例约 3K 时间序列,涵盖 PostgreSQL 可观测性所需的一切。 查看 GitHub 仓库 了解更多详情。

pg_exporter 的最新稳定版本是 v1.0.3

版本 日期 摘要 GitHub
v1.0.3 2025-11-20 Go 1.25.4 例行更新,修复不支持的 libpq 环境变量 v1.0.3
v1.0.2 2025-08-14 CI/CD 构建管道,使用 Go
1.25, https://exp.pgsty.com
v1.0.2
v1.0.1 2025-07-17 DockerHub 镜像,Go 1.24.5,禁用 pg_tsdb_hypertable v1.0.1
v1.0.0 2025-05-06 PostgreSQL 18 支持,新的 WAL/checkpointer/I/O 指标 v1.0.0
v0.9.0 2025-04-26 TimescaleDB、Citus、pg_wait_sampling 收集器 v0.9.0
v0.8.1 2025-03-29 依赖项更新,docker 镜像标签 v0.8.1
v0.8.0 2025-02-14 PgBouncer 1.24 支持,Go 1.24,日志重构 v0.8.0
v0.7.1 2024-12-29 常规更新,配置作为 Reader 支持 v0.7.1
v0.7.0 2024-08-09 PostgreSQL 17 支持,谓词查询功能 v0.7.0
v0.6.0 2023-10-18 PostgreSQL 16 支持,ARM64 包,安全修复 v0.6.0
v0.5.0 2022-05-13 RPM/DEB 构建,列缩放,指标增强 v0.5.0
v0.4.1 2022-03-08 收集器更新,connect-timeout 参数 v0.4.1
v0.4.0 2021-05-28 PostgreSQL 14 支持,自动发现功能 v0.4.0
v0.3.2 2021-02-01 Shadow DSN 修复,文档更新 v0.3.2
v0.3.1 2020-12-04 旧版 PostgreSQL 版本的配置修复 v0.3.1
v0.3.0 2020-10-29 PostgreSQL 13 支持,REST API,虚拟服务器 v0.3.0
v0.2.0 2020-03-21 YUM 包,配置重载支持 v0.2.0
v0.1.2 2020-02-20 动态配置重载,批量模式 v0.1.2
v0.1.1 2020-01-10 启动挂起错误修复 v0.1.1
v0.1.0 2020-01-08 初始稳定版本 v0.1.0
v0.0.4 2019-12-20 生产测试版本 v0.0.4
v0.0.3 2019-12-13 生产环境测试 v0.0.3
v0.0.2 2019-12-09 早期测试版本 v0.0.2
v0.0.1 2019-12-09 带有 PgBouncer 模式的初始版本 v0.0.1

v1.0.3

  • 使用 Go 1.25.4 与最新依赖构建
  • 修复 #80:与 libpq 环境变量冲突
  • @kadaffyauto-discovery 默认值修正为 true

校验和

https://github.com/pgsty/pg_exporter/releases/download/v1.0.3/checksums.txt

v1.0.2

  • 使用 Go 1.25 构建,更新依赖至最新版本。
  • 新网站首页:https://exp.pgsty.com
  • 使用 goreleaser 自动化构建,集成 GitHub Actions CI/CD
  • 添加 windows amd64 构建目标
  • 添加 linux ppc64le 构建目标

校验和

https://github.com/pgsty/pg_exporter/releases/download/v1.0.2/checksums.txt

683bf97f22173f2f2ec319a88e136939c2958a1f5ced4f4aa09a1357fc1c44c5  pg-exporter_1.0.2-1_amd64.deb
f62d479a92be2d03211c162b8419f968cea87ceef5b1f25f2bcd390e0b72ccb5  pg-exporter_1.0.2-1_arm64.deb
e1bbfc5a4c1b93e6f92bc7adcb4364583ab763e76e156aa5c979d6d1040f4c7a  pg-exporter_1.0.2-1_ppc64le.deb
f51d5b45448e6bbec3467d1d1dc049b1e16976f723af713c4262541ac55a039c  pg_exporter-1.0.2-1.aarch64.rpm
18380011543674e4c48b2410266b41165974d780cbc8918fc562152ba623939e  pg_exporter-1.0.2-1.ppc64le.rpm
198372d894b9598c166a0e91ca36d3c9271cb65298415f63dbffcf6da611f2bb  pg_exporter-1.0.2-1.x86_64.rpm
cbe7e07df6d180507c830cdab4cf86d40ccd62774723946307b5331d4270477d  pg_exporter-1.0.2.darwin-amd64.tar.gz
20c4a35fa244287766c1d1a19cd2e393b3fa451a96a81e5635401e69bef04b97  pg_exporter-1.0.2.darwin-arm64.tar.gz
d742111185f6a89fff34bfd304b851c8eb7a8e38444f0220786e11ed1934eff1  pg_exporter-1.0.2.linux-amd64.tar.gz
0b1f4c97c1089c4767d92eb22419b8f29c9f46fb90ddfd1e8514cc42dc41054f  pg_exporter-1.0.2.linux-arm64.tar.gz
895083fd2c7fc5409cc1a2dbaaef1e47ac7aa6a3fd5db2359012922d90bcdcc3  pg_exporter-1.0.2.linux-ppc64le.tar.gz
5f751228e7120604af9a482fb70197489fa633c38a0f2b6a3489393fbc6a10aa  pg_exporter-1.0.2.windows-amd64.tar.gz

1.0.1

  • 添加 dockerhub 镜像:pgsty/pg_exporter
  • 将 go 依赖项升级到最新版本,使用 go 1.24.5 构建
  • 默认禁用 pg_tsdb_hypertable 收集器,因为 timescaledb 目录已更改。

校验和

d5e2d6a656eef0ae1b29cd49695f9773  pg_exporter-1.0.1-1.aarch64.rpm
cb01bb78d7b216a235363e9342803cb3  pg_exporter-1.0.1-1.x86_64.rpm
67093a756b04845f69ad333b6d458e81  pg_exporter-v1.0.1.darwin-amd64.tar.gz
2d3fdc10045d1cf494b9c1ee7f94f127  pg_exporter-v1.0.1.darwin-arm64.tar.gz
e242314461becfa99c3978ae72838ab0  pg_exporter-v1.0.1.linux-amd64.tar.gz
63de91da9ef711a53718bc60b89c82a6  pg_exporter-v1.0.1.linux-arm64.tar.gz
718f6afc004089f12c1ca6553f9b9ba5  pg-exporter_1.0.1_amd64.deb
57da7a8005cdf91ba8c1fb348e0d7367  pg-exporter_1.0.1_arm64.deb

https://github.com/pgsty/pg_exporter/releases/tag/v1.0.1


1.0.0

添加 PostgreSQL 18 指标支持

  • 新收集器分支 pg_wal_18
  • 移除 writesyncwrite_timesync_time 指标
  • 移动到 pg_stat_io
  • 新收集器分支 pg_checkpointer_18
  • 新指标 num_done
  • 新指标 slru_written
  • 新收集器分支 pg_db_18
  • 新指标 parallel_workers_to_launch
  • 新指标 parallel_workers_launched
  • 新收集器分支 pg_table_18
  • table_parallel_workers_to_launch
  • table_parallel_workers_launched
  • 新收集器分支 pg_io_18
  • 关于 WAL 统计的新系列
  • 新指标 read_bytes
  • 新指标 write_bytes
  • 新指标 extend_bytes
  • 由于固定值移除 op_bytes
  • 新收集器分支 pg_vacuuming_18
  • 新指标 delay_time
8637bc1a05b93eedfbfd3816cca468dd  pg_exporter-1.0.0-1.aarch64.rpm
a28c4c0dcdd3bf412268a2dbff79f5b9  pg_exporter-1.0.0-1.x86_64.rpm
229129209b8e6bc356c28043c7c22359  pg_exporter-v1.0.0.darwin-amd64.tar.gz
d941c2c28301269e62a8853c93facf12  pg_exporter-v1.0.0.darwin-arm64.tar.gz
5bbb94db46cacca4075d4c341c54db37  pg_exporter-v1.0.0.linux-amd64.tar.gz
da9ad428a50546a507a542d808f1c0fa  pg_exporter-v1.0.0.linux-arm64.tar.gz
0fa2395d9d7a43ab87e5c87e5b06ffcc  pg-exporter_1.0.0_amd64.deb
fed56f8a37e30cc59e85f03c81fce3f5  pg-exporter_1.0.0_arm64.deb

https://github.com/pgsty/pg_exporter/releases/tag/v1.0.0


0.9.0

默认收集器

  • timescaledb hypertable 新增指标收集器
  • citus 分布节点新增指标收集器
  • pg_wait_sampling 等待事件配置文件新增指标收集器
  • pg_slot 全面改进:添加 16/17 pg_replication_slot 指标
  • 允许 pg_slot 收集器在副本上运行(自 16/17)
  • 重构 pg_wait 收集器以聚合所有进程
  • 限制 pg_clustering、pg_indexing、pg_vacuuming 在主节点上运行
  • 将所有 reset_time 标记为 GAUGE 而不是 COUNTER
  • 修复 pg_recovery_prefetch_skip_fpw 类型从 GAUGECOUNTER
  • 修复 pg_recv.state 类型从 LABELGAUGE
  • 以紧凑模式格式化收集器
  • 新的默认指标 pg_exporter_build_info / pgbouncer_exporter_build_info
  • pg_meta 收集器添加 server_encoding
  • pg_setting 收集器添加 12 个新设置指标
  • wal_block_size
  • segment_size
  • wal_segment_size
  • wal_level
  • wal_log_hints
  • work_mem
  • hugepage_count
  • hugepage_status
  • max_wal_size
  • min_wal_size
  • max_slot_wal_keep_size

Exporter 代码库

  • 使用最小 pg 版本后缀规范化收集器分支名称
  • 向二进制包添加许可证文件
  • pgsty/pg_exporter 仓库移动到 pgsty/pg_exporter
  • 重构 server.go 以减少 CompatiblePostgresPrecheck 复杂性
  • 使用额外的数字前缀重命名指标收集器以更好地排序
  • 将依赖项升级到最新版本
  • 在所有非致命收集器之前执行致命收集器,并快速失败

https://github.com/pgsty/pg_exporter/releases/tag/v0.9.0


0.8.1

https://github.com/pgsty/pg_exporter/releases/tag/v0.8.1


0.8.0

  • 添加 PgBouncer 1.24 新指标支持(stat、pool、database)
  • 修复:如果日志目录设置不当,310-pg_size.yml 失败 #64@Süleyman Vurucu 提供
  • 使用最新的 Go 1.24 构建并升级所有依赖项
  • 使用标准 log/slog 而不是 go-kit 重构日志记录
  • 完整变更日志:https://github.com/pgsty/pg_exporter/compare/v0.7.1…v0.8.0

https://github.com/pgsty/pg_exporter/releases/tag/v0.8.0


0.7.1

使用 dependabot 进行常规更新

  • 功能:支持将配置指定为 Reader,由 @ringerc#62 中提供
  • 将 golang.org/x/crypto 从 0.21.0 升级到 0.31.0,由 @dependabot#63 中提供
  • 修复一些拼写错误
  • 完整变更日志:https://github.com/pgsty/pg_exporter/compare/v0.7.0…v0.7.1

https://github.com/pgsty/pg_exporter/releases/tag/v0.7.1


0.7.0

为最新的 go 版本重构代码库。

https://github.com/pgsty/pg_exporter/releases/tag/v0.7.0


0.6.0

https://github.com/pgsty/pg_exporter/releases/tag/v0.6.0


0.5.0

Exporter 增强

  • 使用 nfpm 构建 rpm 和 deb
  • 添加 column.default,当指标值为 NULL 时替换
  • 添加 column.scale,当指标值为 float/int 时乘以缩放因子(例如 µs 到秒)
  • 修复 /stat 端点输出
  • 添加 docker 容器 pgsty/pg_exporter

指标收集器

  • 将 bgwriter 和 pg_wal 时间单位缩放为秒
  • 移除 pg_class 收集器并将其移动到 pg_table 和 pg_inex
  • 向 pg_table 添加 pg_class 指标
  • 向 pg_index 添加 pg_class 指标
  • 默认启用 pg_table_size
  • 将 pg_query pg_db pg_bgwriter pg_ssl pgbouncer_stat 时间指标缩放为秒

https://github.com/pgsty/pg_exporter/releases/tag/v0.5.0


0.4.1

  • 更新默认收集器
    • 在对象监控中省略 citus 和 timescaledb 模式
    • 避免重复的 pg_statio 元组
    • 支持 pgbouncer v1.16
    • 错误修复:pg_repl 收集器在 pg 12 上重叠
  • 新参数:-T connect-timeout PG_EXPORTER_CONNECT_TIMEOUT 这在监控远程 Postgres 实例时很有用。
  • 现在在 rpm 包中 pg_exporter.yaml 重命名为 pg_exporter.yml

https://github.com/pgsty/pg_exporter/releases/tag/v0.4.1


0.4.0

  • 添加 PG 14 支持
  • 默认指标配置全面改进。(但您仍然可以使用旧配置)
  • 添加 auto-discoveryinclude-databaseexclude-database 选项
  • 添加多数据库监控实现(使用 auto-discovery = on

https://github.com/pgsty/pg_exporter/releases/tag/v0.4.0


0.3.2

  • 修复 shadow DSN 边界情况
  • 修复拼写错误和文档

https://github.com/pgsty/pg_exporter/releases/tag/v0.3.2


0.3.1

修复默认配置问题(特别是对于低于 13 的版本)

  • 设置 primary_conninfo 直到 PG13 才存在
  • pg_func 收集器添加 funcid 标签以避免函数名重复标签
  • 将版本字符串修复为 pg_exporter

https://github.com/pgsty/pg_exporter/releases/tag/v0.3.1


0.3.0

https://github.com/pgsty/pg_exporter/releases/tag/v0.3.0

  • 更改默认配置,支持 PostgreSQL 13 新指标(pg_slrupg_shmempg_query13pg_backup 等…)
  • 添加一系列新的 REST API 用于健康/恢复状态检查
  • 添加一个虚拟服务器,提供假的 pg_up 0 指标,在 PgExporter 初始化之前提供服务。
  • 如果未给出 sslmode,则向 URL 添加 sslmode=disable
  • 修复拼写错误和错误

0.2.0

  • 添加 yum 包和 linux 服务定义
  • 向查询配置添加 ‘skip’ 标志
  • 修复 pgbouncer_up 指标
  • 添加配置重载支持

https://github.com/pgsty/pg_exporter/releases/tag/v0.2.0


0.1.2

  • 修复 pgbouncer_up 指标
  • 添加动态配置重载
  • 移除 ‘shard’ 相关逻辑
  • 向默认设置添加 ‘bulky’ 模式

https://github.com/pgsty/pg_exporter/releases/tag/v0.1.2


0.1.1

修复 pg_exporter 在启动期间如果任何查询失败会挂起的错误。

https://github.com/pgsty/pg_exporter/releases/tag/v0.1.1


0.1.0

它工作,看起来不错。

https://github.com/pgsty/pg_exporter/releases/tag/v0.1.0


0.0.4

在真实的生产环境中测试了约 2 周,有 200+ 个节点。看起来不错!

https://github.com/pgsty/pg_exporter/releases/tag/v0.0.4


0.0.3

v0.0.3 发布,在生产环境中测试

此版本已在生产环境中测试。

这个项目仍在快速发展中,我想说如果您想在生产中使用它,请谨慎尝试。

https://github.com/pgsty/pg_exporter/releases/tag/v0.0.3


0.0.2

现在可以尝试了

https://github.com/pgsty/pg_exporter/releases/tag/v0.0.2


0.0.1

添加 pgbouncer 模式

https://github.com/pgsty/pg_exporter/releases/tag/v0.0.1

9.6 - RPM 发布

PostgreSQL 和扩展 RPM 包变更日志和发布说明

查看 pgsty/rpm 仓库的构建规范和 pigsty-pgsql 的使用方法

pig
curl https://repo.pigsty.io/pig | bash      # 下载并安装 pig CLI 工具
pig repo add all pigsty -u                  # 添加 pigsty-pgsql 仓库并更新缓存
yum
# 将 Pigsty 的 GPG 公钥添加到您的系统密钥链以验证包签名
curl -fsSL https://repo.pigsty.io/key | sudo tee /etc/pki/rpm-gpg/RPM-GPG-KEY-pigsty >/dev/null

# 将 Pigsty 仓库定义文件添加到 /etc/yum.repos.d/ 目录,包括两个仓库
sudo tee /etc/yum.repos.d/pigsty-pgsql.repo > /dev/null <<-'EOF'
[pigsty-pgsql]
name=Pigsty PGSQL For el$releasever.$basearch
baseurl=https://repo.pigsty.io/yum/pgsql/el$releasever.$basearch
skip_if_unavailable = 1
enabled = 1
priority = 1
gpgcheck = 1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-pigsty
module_hotfixes=1
EOF

# 刷新 YUM/DNF 仓库缓存
sudo yum makecache;

2025-11-20

名称 旧版本 新版本 备注
vchord 0.5.3 1.0.0
pg_later 0.3.1 0.4.0
pgvectorscale 0.8.0 0.9.0 -pg13, +pg18
pglite_fusion 0.0.5 0.0.6
pgx_ulid 0.2.1 0.2.2
pg_search 0.19.5 0.19.7 resume PIGSTY building
citus 13.2.0 13.2.0 official tag
timescaledb 2.23.0 2.23.1
pg_profile 4.10 4.11
pglinter 1.0.0 new
pg_typeid 0.3.0 head with pg18 support
pg_enigma 0.4.0 vonng patched pgrx version
pg_retry 1.0.0 new, pg17-18
pg_biscuit 1.0 new, pg16-18
pg_weighted_statistics 1.0.0 new, pg13-18
pg_stat_monitor 2.2.0 2.3.0 fix PGDG pg18 missing
documentdb 0.106 0.107 ferretdb fork
PolarDB 15.15 15.15.5.0-38948055

2025-11-10

为几乎所有扩展添加 PostgreSQL 18 支持

名称 旧版本 新版本 备注
omni_csv - 0.1.1 new
omni_datasets - 0.1.0 new
omni_shmem - 0.1.0 new
pg_csv - 1.0.1 new
pg_dbms_errlog - 2.2 new
pg_rrule - 0.2.0 new
plxslt - 0.20140221 new
anon 2.3.0 2.4.1 +pg18
collection 1.0.0 1.1.0 +pg18
credcheck 3.0 4.2 +pg18
emaj 4.7.0 4.7.1 +pg18
explain_ui 0.0.1 0.0.2 +pg18
firebird_fdw 1.4.0 1.4.1 +pg18
logerrors 2.1.3 2.1.5 +pg18
multicorn 3.0 3.2 +pg18
omni 0.2.9 0.2.14 +pg18
omni_email 0 0.1.0 +pg18
omni_httpc 0.1.5 0.1.10 +pg18
omni_httpd 0.4.6 0.4.11 +pg18
omni_id 0.4.2 0.4.3 +pg18
omni_kube 0.1.1 0.4.2 +pg18
omni_ledger 0.1.2 0.1.3 +pg18
omni_sql 0.5.1 0.5.3 +pg18
omni_sqlite 0.1.2 0.2.2 +pg18
omni_types 0.3.4 0.3.6 +pg18
omni_vfs 0.2.1 0.2.2 +pg18
omni_worker 0.1.0 0.2.1 +pg18
periods 1.2.2 1.2.3 +pg18
pg_bestmatch 0.0.1 0.0.2 +pg18
pg_cardano 1.0.5 1.1.1 +pg18
pg_checksums 1.1 1.3 +pg18
pg_duckdb 0.3.1 1.1.0 +pg18
pg_failover_slots 1.1.0 1.2.0 +pg18
pg_graphql 1.5.11 1.5.12 +pg18
pg_idkit 0.3.1 0.4.0 +pg18
pg_later 0.3.0 0.3.1 +pg18
pg_mooncake 0.1.2 0.2.0 +pg18
pg_net 0.9.2 0.20.0 +pg18
pg_parquet 0.4.3 0.5.1 +pg18
pg_render 0.1.2 0.1.3 +pg18
pg_session_jwt 0.3.1 0.3.3 +pg18
pg_smtp_client 0.2.0 0.2.1 +pg18
pg_sphere 1.5.1 1.5.2 +pg18
pg_statement_rollback 1.4 1.5 +pg18
pg_store_plans 1.8 1.9 +pg18
pg_tle 1.5.1 1.5.2 +pg18
pg_tokenizer 0.1.0 0.1.1 +pg18
pg_uuidv7 1.6.0 1.7.0 +pg18
pgactive 2.1.6 2.1.7 +pg18
pglogical 2.4.5 2.4.6 +pg18
pglogical_origin 2.4.5 2.4.6 +pg18
pgmq 1.5.1 1.7.0 +pg18
pgsmcrypto 0.1.0 0.1.1 +pg18
pgx_ulid 0.2.0 0.2.1 +pg18
pldbgapi 1.8 1.9 +pg18
pljava 1.6.8 1.6.10 +pg18
plprql 1.0.0 18.0.0 +pg18
roaringbitmap 0.5.4 0.5.5 +pg18
semver 0.32.1 0.40.0 +pg18
supautils 2.10.0 3.0.2 +pg18
tds_fdw 2.0.4 2.0.5 +pg18
timescaledb 2.22.0 2.23.0 +pg18
timescaledb_toolkit 1.21.0 1.22.0 +pg18
timeseries 0.1.6 0.1.7 +pg18
tzf 0.2.2 0.2.3 +pg18
vchord 0.5.1 0.5.3 +pg18
vchord_bm25 0.2.1 0.2.2 +pg18
vectorize 0.22.2 0.25.0 +pg18
wrappers 0.5.4 0.5.6 +pg18
gzip 1.0.1 1.0.0 +pg18
hypopg 1.4.1 1.4.2 +pg18
mobilitydb 1.2.0 1.3.0 +pg18
mongo_fdw 5.5.1 5.5.3 +pg18
orafce 4.14.4 4.14.6 +pg18
pg_hint_plan 1.7.1 1.8.0 +pg18
pg_ivm 1.11 1.13 +pg18
pg_partman 5.2.4 5.3.1 +pg18
pg_search 0.18.1 0.19.2 +pg18
pg_show_plans 2.1.6 2.1.7 +pg18
pgpcre 1 0.20190509 +pg18
pgroonga 4.0.0 4.0.4 +pg18
pgroonga_database 4.0.0 4.0.4 +pg18
plpgsql_check 2.8.2 2.8.3 +pg18
uint 1.20231206 1.20250815 +pg18
uint128 1.1.0 1.1.1 +pg18
omni_* 20250525 20251108 +pg18
acl 1.0.4 +pg18
aggs_for_arrays 1.3.3 +pg18
aggs_for_vecs 1.4.0 +pg18
arraymath 1.1 +pg18
asn1oid 1.6 +pg18
aws_s3 0.0.1 +pg18
base36 1.0.0 +pg18
base62 0.0.1 +pg18
bzip 1.0.0 +pg18
chkpass 1.0 +pg18
convert 0.0.4 +pg18
count_distinct 3.0.2 +pg18
country 0.0.3 +pg18
cryptint 1.0.0 +pg18
currency 0.0.3 +pg18
data_historization 1.1.0 +pg18
db_migrator 1.0.0 +pg18
dbt2 0.61.7 +pg18
ddl_historization 0.0.7 +pg18
ddsketch 1.0.1 +pg18
decoder_raw 1.0 +pg18
decoderbufs 3.2.0 +pg18
emailaddr 0 +pg18
envvar 1.0.1 +pg18
faker 0.5.3 +pg18
financial 1.0.1 +pg18
fio 1.0 +pg18
first_last_agg 0.1.4 +pg18
floatfile 1.3.1 +pg18
floatvec 1.1.1 +pg18
geoip 0.3.0 +pg18
hashlib 1.1 +pg18
hashtypes 0.1.5 +pg18
hll 2.18 +pg18
hunspell_* 1.0 +pg18
imgsmlr 1.0 +pg18
index_advisor 0.2.0 +pg18
kafka_fdw 0.0.3 +pg18
login_hook 1.7 +pg18
oracle_fdw 2.8.0 +pg18
pg_auth_mon 3.0 +pg18
pg_background 1.3 +pg18
pg_bigm 1.2 +pg18
pg_cron 1.6.7 +pg18
pg_profile 4.10 +pg18
pg_stat_kcache 2.3.0 +pg18
pgdd 0.6.0 +pg18
pgjwt 0.2.0 +pg18
pgnodemx 1.7 +pg18
pgsodium 3.1.9 +pg18
pgtap 1.3.3 +pg18
plprofiler 4.2.5 +pg18
plproxy 2.11.0 +pg18
plr 8.4.8 +pg18
plv8 3.2.4 +pg18
pointcloud 1.2.5 +pg18
powa 5.0.1 +pg18
prefix 1.2.10 +pg18
q3c 2.0.1 +pg18
redis_fdw 1.0 +pg18
session_variable 3.4 +pg18
set_user 4.1.0 +pg18
system_stats 3.2 +pg18
temporal_tables 1.2.2 +pg18
topn 2.7.0 +pg18
unit 7.10 +pg18
zhparser 2.3 +pg18
zstd 1.1.2 +pg18

2025-09-04

名称 旧版本 新版本 备注
timesacledb 2.21.1 2.22.0
citus 13.1.0 13.2.0
documentdb 0.105.0 0.106.0 work with ferretdb 2.5
ddlx 0.29 0.30 + pg18
icu_ext 1.9.0 1.10.0 + pg18
asn1oid 1.5 1.6 + pg18
uint128 1.0.0 1.1.0 + pg18
toastinfo 1.5 1.6 + pg18
vchord 0.4.3 0.5.1 pgrx 0.16.0
pg_idkit 0.3.0 0.3.1 pgrx 0.15.0
pg_search 0.17.3 0.18.0 pgrx 0.15.0
pg_parquet 0.4.0 0.4.3 pgrx 0.16.0
wrappers 0.5.3 0.5.4 pgrx 0.14.3
pg_rewrite - 2.0.0 + Debian/Ubuntu (PGDG)
pg_tracing - 0.1.3-2 + pg 14/18
pg_curl 2.4 2.4.5 new version epoch
pg_rewrite - 2.0.0 Import from PGDG
pg_tracing - 1.3.0 + pg14 / pg18
pgactive 2.1.5 2.1.6 + pg18
sentinel 1.1 1.2 1.2
pg_tle 1.5.1-1 1.5.1-2 + pg18
redis_fdw + pg18
pgextwlist 1.17 1.19 + pg18
wal2json 1.6 + pg18
pgvector 0.8.1 + pg18

2025-07-24

名称 旧版本 新版本 备注
OrioleDB beta11 1.4 beta12 1.5 与 oriolepg 17.11 配合
OriolePG 17.9 17.11 与 orioledb 1.5 beta12 配合
documentdb 0.104.0 0.105.0 与 ferretdb 2.4 配合
timescaledb 2.20.0 2.21.1
supautils 2.9.2 2.10.0 .so 位置变更
plv8 3.2.3 3.2.4
postgresql_anonymizer 3.1.1 2.3.0 (pgrx 0.14.3)
wrappers 0.5.0 0.5.3 (pgrx 0.14.3) pgrx 版本变更
pgvectorscale 0.7.1 0.8.0 (pgrx 0.12.9)
pg_search 0.15.8 0.17.0 (download) 修复 el icu 依赖问题

2025-06-24

名称 旧版本 新版本 备注
citus 13.0.3 13.1.0
timescaledb 2.20.0 2.21.0
vchord 0.3.0 0.4.3
pgactive - 2.1.5 需要 pgfeutils
documentdb 0.103.0 0.104.0 添加 arm 支持

2025-05-26

名称 旧版本 新版本 备注
pgdd 0.5.0 0.6.0
convert - 0.0.4
pg_idkit 0.2.0 0.3.0
pg_tokenizer.rs - 0.1.0
pg_render - 0.1.2
pgx_ulid - 0.2.0
orioledb 1.4.0b10 1.4.0b11

2025-05-22

名称 旧版本 新版本 备注
openhalodb - 14.10
spat - 0.1.0a4
pgsentinel - 1.1.0
timescaledb - 2.20.0
sqlite_fdw - 2.5.0
documentdb - 0.103.0
tzf - 0.2.2
pg_vectorize - 0.22.2
wrappers - 0.5.0

2025-05-07

名称 旧版本 新版本 备注
omnigres - 20250507
citus - 12.0.3
timescaledb - 2.19.3
supautils - 2.9.1
pg_envvar - 1.0.1
pgcollection - 1.0.0
aggs_for_vecs - 1.4.0
pg_tracing - 0.1.3
pgmq - 1.5.1
tzf-pg - 0.2.0
pg_search - 0.15.18
anon - 2.1.1
pg_parquet - 0.4.0
pg_cardano - 1.0.5
pglite_fusion - 0.0.5
vchord_bm25 - 0.2.1
vchord - 0.3.0
timescaledb-toolkit - 1.21.0
pgvectorscale - 0.7.1
pg_session_jwt - 0.3.1

2025-03-20

名称 旧版本 新版本 备注
timescaledb - 2.19.0
citus - 13.0.2
documentdb - 1.102
pg_analytics - 0.3.7
pg_search - 0.15.8
emaj - 4.6.0
pgsql_tweaks - 0.11.0
pgvectorscale - 0.6.0
pg_session_jwt - 0.2.0
wrappers - 0.4.5
pg_parquet - 0.3.1
vchord - 0.2.2
pg_tle 1.2.0 1.5.0
supautils 2.5.0 2.6.0
sslutils 1.3 1.4
pg_profile 4.7 4.8
pg_jsonschema 0.3.2 0.3.3
pg_incremental 1.1.1 1.2.0
ddl_historization 0.7 0.0.7
pg_sqlog 3.1.7 1.6
pg_random - -
pg_stat_monitor 2.1.0 2.1.1
pg_profile 4.7 4.8

2024-10-16

名称 旧版本 新版本 备注
pg_timeseries - 0.1.6
pgmq - 1.4.4
pg_protobuf - 16 17
pg_uuidv7 - 1.6
pg_readonly - latest
pgddl - 0.28
pg_safeupdate - latest
pg_stat_monitor - 2.1
pg_profile - 4.7
system_stats - 3.2
pg_auth_mon - 3.0
login_hook - 1.6
logerrors - 2.1.3
pg-orphaned - latest
pgnodemx - 1.7
sslutils - 1.4 (+16,17)

9.7 - DEB 发布

PostgreSQL 和扩展 DEB 包变更日志和发布说明

查看 pgsty/deb 仓库的构建规范和 pigsty-pgsql 的使用方法

pig
curl https://repo.pigsty.io/pig | bash      # 下载并安装 pig CLI 工具
pig repo add all pigsty -u                  # 添加 pigsty-pgsql 仓库并更新缓存
apt
# 将 Pigsty 的 GPG 公钥添加到您的系统密钥链以验证包签名
curl -fsSL https://repo.pigsty.io/key | sudo gpg --dearmor -o /etc/apt/keyrings/pigsty.gpg

# 获取 Debian 发行版代号(distro_codename=jammy、focal、bullseye、bookworm),并将相应的上游仓库地址写入 APT List 文件
distro_codename=$(lsb_release -cs)
sudo tee /etc/apt/sources.list.d/pigsty-io.list > /dev/null <<EOF
deb [signed-by=/etc/apt/keyrings/pigsty.gpg] https://repo.pigsty.io/apt/pgsql/${distro_codename} ${distro_codename} main
EOF

# 刷新 APT 仓库缓存
sudo apt update

2025-11-20

名称 旧版本 新版本 备注
vchord 0.5.3 1.0.0
pg_later 0.3.1 0.4.0
pgvectorscale 0.8.0 0.9.0 -pg13, +pg18
pglite_fusion 0.0.5 0.0.6
pgx_ulid 0.2.1 0.2.2
pg_search 0.19.5 0.19.7 resume PIGSTY building
citus 13.2.0 13.2.0 official tag
timescaledb 2.23.0 2.23.1
pg_profile 4.10 4.11
pglinter 1.0.0 new
pg_typeid 0.3.0 head with pg18 support
pg_enigma 0.4.0 vonng patched pgrx version
pg_retry 1.0.0 new, pg17-18
pg_biscuit 1.0 new, pg16-18
pg_weighted_statistics 1.0.0 new, pg13-18
documentdb 0.106 0.107 ferretdb fork
PolarDB 15.15 15.15.5.0-38948055

2025-11-10

为几乎所有扩展添加 PostgreSQL 18 支持

名称 旧版本 新版本 备注
omni_csv - 0.1.1 new
omni_datasets - 0.1.0 new
omni_shmem - 0.1.0 new
pg_csv - 1.0.1 new
pljs - 1.0.3 new
plxslt - 0.20140221 new
credcheck 3.0 4.2 +pg18
dbt2 0.45.0 0.61.7 +pg18
h3 4.1.3 4.2.3 +pg18
h3_postgis 4.1.3 4.2.3 +pg18
mongo_fdw 1.1 5.5.3 +pg18
multicorn 3.0 3.2 +pg18
orafce 4.14.4 4.14.6 +pg18
pg_hint_plan 1.7.0 1.8.0 +pg18
pg_search 0.18.1 0.19.2 +pg18
pg_show_plans 2.1.6 2.1.7 +pg18
pgactive 2.1.6 2.1.7 +pg18
pgpcre 1 0.20190509 +pg18
plpgsql_check 2.8.2 2.8.3 +pg18
roaringbitmap 0.5.4 0.5.5 +pg18
uint 1.20231206 1.20250815 +pg18
uint128 1.1.0 1.1.1 +pg18
anon 2.3.0 2.4.1 +pg18
collection 1.0.0 1.1.0 +pg18
emaj 4.7.0 4.7.1 +pg18
explain_ui 0.0.1 0.0.2 +pg18
firebird_fdw 1.4.0 1.4.1 +pg18
login_hook 1.6 1.7 +pg18
logerrors 2.1.3 2.1.5 +pg18
mobilitydb 1.2.0 1.3.0 +pg18
omni 0.2.9 0.2.14 +pg18
omni_httpc 0.1.5 0.1.10 +pg18
omni_httpd 0.4.6 0.4.11 +pg18
omni_kube 0.1.1 0.4.2 +pg18
omni_sql 0.5.1 0.5.3 +pg18
omni_sqlite 0.1.2 0.2.2 +pg18
omni_worker 0.1.0 0.2.1 +pg18
pg_cardano 1.0.5 1.1.1 +pg18
pg_checksums 1.2 1.3 +pg18
pg_cron 1.6.5 1.6.7 +pg18
pg_duckdb 0.3.1 1.1.0 +pg18
pg_failover_slots 1.1.0 1.2.0 +pg18
pg_graphql 1.5.11 1.5.12 +pg18
pg_idkit 0.3.1 0.4.0 +pg18
pg_mooncake 0.1.2 0.2.0 +pg18
pg_net 0.9.2 0.20.0 +pg18
pg_parquet 0.4.3 0.5.1 +pg18
pg_partman 5.2.4 5.3.0 +pg18
pg_session_jwt 0.3.1 0.3.3 +pg18
pg_sphere 1.5.1 1.5.2 +pg18
pg_stat_monitor 2.2.0 2.3.0 +pg18
pg_statement_rollback 1.4 1.5 +pg18
pg_store_plans 1.8 1.9 +pg18
pg_task 1.0.0 2.1.12 +pg18
pg_tle 1.5.1 1.5.2 +pg18
pg_uuidv7 1.6.0 1.7.0 +pg18
pglogical 2.4.5 2.4.6 +pg18
pgmq 1.5.1 1.7.0 +pg18
pgroonga 4.0.0 4.0.4 +pg18
pgsql_tweaks 0.11.3 1.0.2 +pg18
pldbgapi 1.8 1.9 +pg18
plprql 1.0.0 18.0.0 +pg18
supautils 2.10.0 3.0.2 +pg18
timescaledb 2.22.0 2.23.0 +pg18
timescaledb_toolkit 1.21.0 1.22.0 +pg18
vchord 0.5.1 0.5.3 +pg18
vectorize 0.22.2 0.25.0 +pg18
wrappers 0.5.4 0.5.6 +pg18
acl 1.0.4 - +pg18
aggs_for_arrays 1.3.3 - +pg18
aggs_for_vecs 1.4.0 - +pg18
base36 1.0.0 - +pg18
hashlib 1.1 - +pg18
hll 2.18 - +pg18
imgsmlr 1.0 - +pg18
index_advisor 0.2.0 - +pg18
kafka_fdw 0.0.3 - +pg18
pg_auth_mon 3.0 - +pg18
pg_background 1.3 - +pg18
pg_bigm 1.2 - +pg18
pg_profile 4.10 - +pg18
pg_stat_kcache 2.3.0 - +pg18
pgdd 0.6.0 - +pg18
pgjwt 0.2.0 - +pg18
pgmp 1.0.5 - +pg18
plprofiler 4.2.5 - +pg18
plv8 3.2.4 - +pg18
redis_fdw 1.0 - +pg18
repmgr 5.5.0 - +pg18
system_stats 3.2 - +pg18
topn 2.7.0 - +pg18
zhparser 2.3 - +pg18

2025-09-06

名称 旧版本 新版本 备注
timesacledb 2.21.1 2.22.0
citus 13.1.0 13.2.0
documentdb 0.105.0 0.106.0 work with ferretdb 2.5
ddlx 0.29 0.30 + pg18
uint128 1.0.0 1.1.0 + pg18
vchord 0.4.3 0.5.1 pgrx 0.16.0
pg_idkit 0.3.0 0.3.1 pgrx 0.15.0
pg_search 0.17.3 0.18.0 pgrx 0.15.0
pg_parquet 0.4.0 0.4.3 pgrx 0.16.0
wrappers 0.5.3 0.5.4 pgrx 0.14.3
pg_rewrite - 2.0.0 + Debian/Ubuntu
pg_tracing - 0.1.3-2 + pg 14/18
pg_curl 2.4 2.4.5
pg_ivm 1.11 1.12 + pg18
pg_rewrite - 2.0.0 new extension
pg_tracing - 1.3.0 + pg14 / pg18
pgactive 2.1.5 2.1.6 + pg18
pgsentinel 1.1 1.2 1.2
pg_tle 1.5.1-1 1.5.1-2 + pg18
redis_fdw + pg18
emaj 4.6 4.7
table_version 1.11.0 1.11.1

2025-07-24

名称 旧版本 新版本 备注
OrioleDB beta11 1.4 beta12 1.5 与 oriolepg 17.11 配合
OriolePG 17.9 17.11 与 orioledb 1.5 beta12 配合
documentdb 0.104.0 0.105.0 与 ferretdb 2.4 配合
timescaledb 2.20.0 2.21.1
supautils 2.9.2 2.10.0 .so 位置变更
plv8 3.2.3 3.2.4
postgresql_anonymizer 3.1.1 2.3.0 (pgrx 0.14.3)
wrappers 0.5.0 0.5.3 (pgrx 0.14.3) pgrx 版本变更
pgvectorscale 0.7.1 0.8.0 (pgrx 0.12.9)
pg_search 0.15.8 0.17.0 (download) 修复 el icu 依赖问题
pg_profile 4.8.0 4.10.0

2025-07-04

名称 旧版本 新版本 备注
orioledb 1.4 beta11 重新构建
pgvectorscale 0.7.1 0.7.1 重新构建修复错误
pg_stat_monitor 2.1.1 2.2.0
pgsql-tweaks 0.11.1 0.11.3
pg_tle 1.5.0 1.5.1
pg_curl 2.4 2.4.5

2025-06-24

名称 旧版本 新版本 备注
citus 13.0.3 13.1.0
timescaledb 2.20.0 2.21.0
vchord 0.3.0 0.4.3
pgactive - 2.1.5 需要 pgfeutils
documentdb 0.103.0 0.104.0 添加 arm 支持

2025-05-26

名称 旧版本 新版本 备注
pgdd 0.5.0 0.6.0
convert - 0.0.4
pg_idkit 0.2.0 0.3.0
pg_tokenizer.rs - 0.1.0
pg_render - 0.1.2
pgx_ulid - 0.2.0
pg_ivm 1.10.0 1.11.0
orioledb 1.4.0b10 1.4.0b11

2025-05-22

名称 旧版本 新版本 备注
openhanded - 14.10
spat - 0.1.0a4
pgsentinel - 1.1.0
timescaledb - 2.20.0
sqlite_fdw - 2.5.0
documentdb - 0.103.0
tzf - 0.2.2
pg_vectorize - 0.22.2
wrappers - 0.5.0

2025-05-07

名称 旧版本 新版本 备注
omnigres - 20250507
citus - 12.0.3
timescaledb - 2.19.3
supautils - 2.9.1
pg_envvar - 1.0.1
pgcollection - 1.0.0
aggs_for_vecs - 1.4.0
pg_tracing - 0.1.3
pgmq - 1.5.1
tzf-pg - 0.2.0
pg_search - 0.15.18
anon - 2.1.1
pg_parquet - 0.4.0
pg_cardano - 1.0.5
pglite_fusion - 0.0.5
vchord_bm25 - 0.2.1
vchord - 0.3.0
timescaledb-toolkit - 1.21.0
pgvectorscale - 0.7.1
pg_session_jwt - 0.3.1

2025-03-20

名称 旧版本 新版本 备注
timescaledb - 2.19.0
citus - 13.0.2
documentdb - 1.102
pg_analytics - 0.3.7
pg_search - 0.15.8
pg_ivm - 1.10
emaj - 4.6.0
pgsql_tweaks - 0.11.0
pgvectorscale - 0.6.0
pg_session_jwt - 0.2.0
wrappers - 0.4.5
pg_parquet - 0.3.1
vchord - 0.2.2
pg_tle 1.2.0 1.5.0
supautils 2.5.0 2.6.0
sslutils 1.3 1.4
pg_profile 4.7 4.8
pg_jsonschema 0.3.2 0.3.3
pg_incremental 1.1.1 1.2.0
ddl_historization 0.7 0.0.7
pg_sqlog 3.1.7 1.6
pg_random - -
pg_stat_monitor 2.1.0 2.1.1
pg_profile 4.7 4.8

2024-10-16

名称 旧版本 新版本 备注
pg_ivm - 1.9
pg_timeseries - 0.1.6
pgmq - 1.4.4
pg_protobuf - 16 17
pg_uuidv7 - 1.6
pg_readonly - latest
pgddl - 0.28
pg_safeupdate - latest
pg_stat_monitor - 2.1
pg_profile - 4.7
system_stats - 3.2
pg_auth_mon - 3.0
login_hook - 1.6
logerrors - 2.1.3
pg-orphaned - latest
pgnodemx - 1.7
sslutils - 1.4 (+16,17)

9.8 - INFRA 发布

pigsty-infra 仓库变更日志和可观测性包发布说明

查看 pgsty/infra-pkg 仓库的构建规范和 pigsty-infra 的使用方法

pig
curl https://repo.pigsty.io/pig | bash      # 下载并安装 pig CLI 工具
pig repo add infra -u                       # 添加 pigsty-pgsql 仓库并更新缓存

2025-11-23

名称 旧版本 新版本 备注
pgschema - 1.4.2 new
pgflo - 0.0.15 new
vector 0.51.0 0.51.1 bugfix release
sealos 5.0.1 5.1.1
etcd 3.6.5 3.6.6
duckdb 1.4.1 1.4.2
pg_exporter 1.0.2 1.0.3
pig 0.7.1 0.7.2
grafana 12.1.0 12.3.0
pg_timetable 6.1.0 6.2.0
genai-toolbox 0.16.0 0.21.0
timescaledb-tools 0.18.0 0.18.1 move to infra
timescaledb-event-streamer 0.12.0 0.20.0
tigerbeetle 0.16.60 0.16.65
victoria-metrics 1.129.1 1.130.0
victorialogs 1.37.2 1.38.0
grafana-victorialogs-ds 0.21.4 0.22.1
grafana-victoriametrics-ds 0.19.6 0.19.7
grafana-plugins 12.0.0 12.3.0

2025-11-11

名称 旧版本 新版本 备注
grafana 12.1.0 12.2.1 下载地址发生变化
prometheus 3.6.0 3.7.3
pushgateway 1.11.1 1.11.2
alertmanager 0.28.1 0.29.0
nginx_exporter 1.5.0 1.5.1
node_exporter 1.9.1 1.10.2
pgbackrest_exporter 0.20.0 0.21.0
redis_exporter 1.77.0 1.80.0
duckdb 1.4.0 1.4.1
dblab 0.33.0 0.34.2
pg_timetable 5.13.0 6.1.0
vector 0.50.0 0.51.0
rclone 1.71.1 1.71.2
victoria-metrics 1.126.0 1.129.1
victoria-logs 1.35.0 1.37.2
grafana-victorialogs-ds 0.21.0 0.21.4
grafana-victoriametrics-ds 0.19.4 0.19.6
grafana-infinity-ds 3.5.0 3.6.0
genai-toolbox 0.16.0 0.18.0
pev2 1.16.0 1.17.0
pig 0.6.2 0.7.1

2025-10-18

名称 旧版本 新版本 备注
prometheus 3.5.0 3.6.0
nginx_exporter 1.4.2 1.5.0
mysqld_exporter 0.17.2 0.18.0
redis_exporter 1.75.0 1.77.0
mongodb_exporter 0.47.0 0.47.1
victoria-metrics 1.121.0 1.126.0
vicotira-logs 1.25.1 1.35.0
duckdb 1.3.2 1.4.0
etcd 3.6.4 3.6.5
restic 0.18.0 0.18.1
tigerbeetle 0.16.54 0.16.60
grafana-victorialogs-ds 0.19.3 0.21.0
grafana-victoriametrics-ds 0.18.3 0.19.4
grafana-infinity-ds 3.3.0 3.5.0
genai-toolbox 0.9.0 0.16.0
grafana 12.1.0 12.2.0
vector 0.49.0 0.50.0
rclone 1.70.3 1.71.1
minio 20250723155402 20250907161309
mcli 20250721052808 20250813083541

2025-08-15

名称 旧版本 新版本 备注
grafana 12.0.0 12.1.0
pg_exporter 1.0.1 1.0.2
pig 0.6.0 0.6.1
vector 0.48.0 0.49.0
redis_exporter 1.74.0 1.75.0
mongo_exporter 0.46.0 0.47.0
victoriametrics 1.121.0 1.123.0
victorialogs: 1.25.0 1.28.0
grafana-victoriametrics-ds 0.17.0 0.18.3
grafana-victorialogs-ds 0.18.3 0.19.3
grafana-infinity-ds 3.3.0 3.4.1
etcd 3.6.1 3.6.4
ferretdb 2.3.1 2.5.0
tigerbeetle 0.16.50 0.16.54
genai-toolbox 0.9.0 0.12.0

2025-07-24

名称 旧版本 新版本 备注
FerretDB - 2.4.0 与 documentdb 1.105 配合
etcd - 3.6.3
minio - 20250723155402
mcli - 20250721052808
ivorysql - 4.5-0ffca11-20250709 修复 libxcrypt 依赖问题

2025-07-16

名称 旧版本 新版本 备注
genai-toolbox 0.8.0 0.9.0 各种 DBMS 的 MCP 工具箱
victoriametrics 1.120.0 1.121.0 拆分为各种包
victorialogs 1.24.0 1.25.0 拆分为各种包
prometheus 3.4.2 3.5.0
duckdb 1.3.1 1.3.2
etcd 3.6.1 3.6.2
tigerbeetle 0.16.48 0.16.50
grafana-victoriametrics-ds 0.16.0 0.17.0
rclone 1.69.3 1.70.3
pig 0.5.0 0.6.0
pev2 1.15.0 1.16.0
pg_exporter 1.0.0 1.0.1

2025-07-04

名称 旧版本 新版本 备注
prometheus 3.4.1 3.4.2 -
grafana 12.0.1 12.0.2 -
vector 0.47.0 0.48.0 -
rclone 1.69.0 1.70.2 -
vip-manager 3.0.0 4.0.0 -
blackbox_exporter 0.26.0 0.27.0 -
redis_exporter 1.72.1 1.74.0 -
duckdb 1.3.0 1.3.1 -
etcd 3.6.0 3.6.1 -
ferretdb 2.2.0 2.3.1 -
dblab 0.32.0 0.33.0 -
tigerbettle 0.16.41 0.16.48 -
grafana-victorialogs-ds 0.16.3 0.18.1 -
grafana-victoriametrics-ds 0.15.1 0.16.0 -
grafana-inifinity-ds 3.2.1 3.3.0 -
victorialogs 1.22.2 1.24.0 -
victoriametrics 1.117.1 1.120.0 -

2025-06-01

名称 旧版本 新版本 备注
grafana - 12.0.1 -
prometheus - 3.4.1 -
keepalived_exporter - 1.7.0 -
redis_exporter - 1.73.0 -
victoriametrics - 1.118.0 -
victorialogs - 1.23.1 -
tigerbeetle - 0.16.42 -
grafana-victorialogs-ds - 0.17.0 -
grafana-infinity-ds - 3.2.2 -

2025-05-22

名称 旧版本 新版本 备注
dblab - 0.32.0 -
prometheus - 3.4.0 -
duckdb - 1.3.0 -
etcd - 3.6.0 -
pg_exporter - 1.0.0 -
ferretdb - 2.2.0 -
rclone - 1.69.3 -
minio - 20250422221226 最后一个带管理 GUI 的版本
mcli - 20250416181326 -
nginx_exporter - 1.4.2 -
keepalived_exporter - 1.6.2 -
pgbackrest_exporter - 0.20.0 -
redis_exporter - 1.27.1 -
victoriametrics - 1.117.1 -
victorialogs - 1.22.2 -
pg_timetable - 5.13.0 -
tigerbeetle - 0.16.41 -
pev2 - 1.15.0 -
grafana - 12.0.0 -
grafana-victorialogs-ds - 0.16.3 -
grafana-victoriametrics-ds - 0.15.1 -
grafana-infinity-ds - 3.2.1 -
grafana_plugins - 12.0.0 -

2025-04-23

名称 旧版本 新版本 备注
mtail - 3.0.8
pig - 0.4.0 -
pg_exporter - 0.9.0 -
prometheus - 3.3.0 -
pushgateway - 1.11.1 -
keepalived_exporter - 1.6.0 -
redis_exporter - 1.70.0 -
victoriametrics - 1.115.0 -
victoria_logs - 1.20.0 -
duckdb - 1.2.2 -
pg_timetable - 5.12.0 -
vector - 0.46.1 -
minio - 20250422221226 -
mcli - 20250416181326 -

2025-04-05

名称 旧版本 新版本 备注
pig - 0.3.4 -
etcd - 3.5.21 -
restic - 0.18.0 -
ferretdb - 2.1.0 -
tigerbeetle - 0.16.34 -
pg_exporter - 0.8.1 -
node_exporter - 1.9.1 -
grafana - 11.6.0 -
zfs_exporter - 3.8.1 -
mongodb_exporter - 0.44.0 -
victoriametrics - 1.114.0 -
minio - 20250403145628 -
mcli - 20250403170756 -

2025-03-23

名称 旧版本 新版本 备注
etcd - 3.5.20 -
pgbackrest_exporter - 0.19.0 重新构建
victorialogs - 1.17.0 -
vslogcli - 1.17.0 -

2025-03-17

名称 旧版本 新版本 备注
kafka - 4.0.0 -
Prometheus - 3.2.1 -
AlertManager - 0.28.1 -
blackbox_exporter - 0.26.0 -
node_exporter - 1.9.0 -
mysqld_exporter - 0.17.2 -
kafka_exporter - 1.9.0 -
redis_exporter - 1.69.0 -
DuckDB - 1.2.1 -
etcd - 3.5.19 -
FerretDB - 2.0.0 -
tigerbeetle - 0.16.31 -
vector - 0.45.0 -
VictoriaMetrics - 1.114.0 -
VictoriaLogs - 1.16.0 -
rclone - 1.69.1 -
pev2 - 1.14.0 -
grafana-victorialogs-ds - 0.16.0 -
grafana-victoriametrics-ds - 0.14.0 -
grafana-infinity-ds - 3.0.0 -
timescaledb-event-streamer - 0.12.0
restic - 0.17.3
juicefs - 1.2.3

2025-02-12

名称 旧版本 新版本 备注
pushgateway 1.10.0 1.11.0 -
alertmanager 0.27.0 0.28.0 -
nginx_exporter 1.4.0 1.4.1 -
pgbackrest_exporter 0.18.0 0.19.0 -
redis_exporter 1.66.0 1.67.0 -
mongodb_exporter 0.43.0 0.43.1 -
VictoriaMetrics 1.107.0 1.111.0 -
VictoriaLogs v1.3.2 1.9.1 -
DuckDB 1.1.3 1.2.0 -
Etcd 3.5.17 3.5.18 -
pg_timetable 5.10.0 5.11.0 -
FerretDB 1.24.0 2.0.0 -
tigerbeetle 0.16.13 0.16.27 -
grafana 11.4.0 11.5.1 -
vector 0.43.1 0.44.0 -
minio 20241218131544 20250207232109 -
mcli 20241121172154 20250208191421 -
rclone 1.68.2 1.69.0 -

2024-11-19

名称 旧版本 新版本 备注
Prometheus 2.54.0 3.0.0 -
VictoriaMetrics 1.102.1 1.106.1 -
VictoriaLogs v0.28.0 1.0.0 -
MySQL Exporter 0.15.1 0.16.0 -
Redis Exporter 1.62.0 1.66.0 -
MongoDB Exporter 0.41.2 0.42.0 -
Keepalived Exporter 1.3.3 1.4.0 -
DuckDB 1.1.2 1.1.3 -
etcd 3.5.16 3.5.17 -
tigerbeetle 16.8 0.16.13 -
grafana - 11.3.0 -
vector - 0.42.0 -

10 - 服务

专家咨询和订阅计划

Pigsty 旨在聚集PG生态的合力,帮助用户用好世界上最流行,最先进的开源数据库 —— PostgreSQLPigsty 完全开源免费,并遵循开源软件惯例,不提供任何质保,用户自行承担使用风险

我们深知专业支持对于企业客户的重要性,因此,Pigsty 提供付费订阅服务,提供质量保证与服务承诺, 提供更广泛的支持范围与顶级专家的咨询与协助。

按需专家咨询

按需专家服务,3000 元/主题,约一小时,聊透相关主题,例如:

  • 根据您的需求与环境,提供架构设计建议与 Pigsty 配置文件
  • 自托管 Supabase、odoo、dify、gitlab 等的指导
  • 关于数据库、云、可观测性以及相关主题的咨询
  • 调查故障原因,优化慢查询(紧急故障故障响应不适用)
  • 制作或提供支持范围内的离线安装包

按需专家咨询服务 不提供 响应时间承诺。 如果您需要长期、可靠的 SLA 承诺支持,请参考 订阅计划

长期订阅计划
  • 在关键场景中运行数据库,需要严格 SLA 保障兜底。
  • 希望对 Pigsty 与 PostgreSQL 相关疑难杂症提供兜底。
  • 希望获取关于 PostgreSQL / Pigsty 生产环境最佳实践的指导。
  • 希望有专家帮助解读监控图表,分析定位性能瓶颈与故障根因,给出意见。
  • 希望根据现有资源与业务需求,规划满足安全/容灾/合规要求的数据库架构。
  • 需要将其他数据库迁移至 PostgreSQL 数据库,或对历史遗留实例迁移与改造。
  • 建设基于Prometheus / Grafana 技术栈的可观测性体系,数据大盘,可视化应用。
  • 希望支持国产信创操作系统/国产信创 ARM 芯片架构,提供中文/本地化界面支持。
  • 下云并寻求 RDS for PostgreSQL 的开源替代 —— 云中立,无供应商锁定的解决方案。
  • 希望获取关于 Redis / ETCD / MinIO,以及 TimescaleDB / Citus 等扩展的专业支持。
  • 希望规避 AGPL v3 协议对衍生作品强制使用同协议开源的的限制,进行二次开发与 OEM 贴牌。
  • 希望将 Pigsty 作为 SaaS / PaaS / DBaaS 对外销售,或基于此发行版提供技术服务/咨询/云服务。

如果您需要更多信息,请 通过邮件联系作者 冯若航([email protected])。


订阅

Pigsty 提供 3 种订阅计划:标准版专业版企业版,供您按需选择:

项目 / 计划 OSS 标准版 专业版 企业版
许可证 AGPLv3 商业 商业 商业
节点限制 无限制 ≤ 5 ≤ 15 ≤ 45, 最多无限制
保证 无保证 +Pigsty +内核 +扩展
Pigsty 错误修复 最新次要版本 最新主要版本 全部 全部
PG 支持 17 17,16 17,16,15,14,13 回到 9.x+
PG 扩展 +调试符号 +所有版本 +定制构建
操作系统支持 EL9, D12, U22 +ARM64 +EL8, U24 +EL7,D11,U20 定制
架构支持 x86_64 x86_64, ARM64 x86_64, ARM64 x86_64, ARM64
离线包 el9,d12,u22@x64 +ARM64 +操作系统次要版本 定制
核心模块
异种内核 x86, 在线 +ARM64 +离线安装 +扩展支持
额外模块 +ARM64 +专业模块 +试点模块
高级 CLI
DBA 小时 一次性设置 最多 5 小时/月 最多 10 小时/月
专家支持 可用 1 人·天/年 2 人·天/年
支持等级 标准 专业 企业
支持 SLA 5x8, 当日 5x8, < 4 小时 7x24, < 30 分钟
价格 免费 10,000 美元/年 30,000 美元/年 60,000 美元/年

节点数量定义为在 Pigsty 部署的配置清单 中的独立 IP 地址总数,即 Pigsty 管理的节点总数。


Pigsty OSS

AGPLv3 许可证下免费,无保证

Pigsty 建立在开源基础上,也回馈开源社区。它是对 PostgreSQL 社区和所有用户的礼物——您可以在不付费的情况下获得 Pigsty 的完整核心功能。当然,与典型的开源软件一样,Pigsty 开源版本不提供任何保证服务,也不对其使用产生的任何后果承担责任。如果您需要保证,请考虑我们的订阅服务。

Pigsty 开源版本在 AGPLv3 许可证下发布,这是一个 copyleft、严格的开源许可证。 如果您是普通最终用户(即公有云供应商或数据库供应商以外的用户),我们不会对您对 Pigsty 的二次开发追究任何行动。 在实践中,对于大多数最终用户,它实际上是在更宽松的 Apache 2.0 许可证下许可的。

如果您发现 Pigsty 的任何缺陷,我们强烈鼓励您在 GitHub 上提交 Issue 来帮助我们改进。如果您有任何问题,可以在社区中寻求帮助。

对于开源版本,我们为三个精确定位的操作系统发行版——EL 9.5、Debian 12.10、Ubuntu 22.04.5——提供 PostgreSQL 17 的预构建标准离线包,都是最新的次要版本(作为开源支持的一种形式,也为 Debian 12 提供 aarch64 离线包)。

通过使用 Pigsty 开源版本,入门级开发人员和 DevOps 工程师可以访问专业 DBA 70%+ 的能力。即使没有专门的数据库专家,您也可以轻松建立高可用、高性能、易于维护、安全可靠的 PostgreSQL 数据库集群。如果在云中自托管,您可以立即节省 EC2/ESSD 和 RDS 服务之间的价格差异,实现高达 90+% 的显著成本降低。

代码 发行版主要版本 次要版本 x86_64 aarch64 PG17 PG16 PG15 PG14 PG13
EL9 RHEL 9 / Rocky9 / Alma9 9.5 el9.x86_64 el9.aarch64
D12 Debian 12 (bookworm) 12.10 d12.x86_64 d12.aarch64
U22 Ubuntu 22.04 (jammy) 22.04.5 u22.x86_64 u22.aarch64

● = 主要支持; ○ = 不可用; ◐ = 可用,DIY 无支持


Pigsty 标准版

中小企业、初创公司和自由职业者的经济选择

Pigsty 标准版订阅为中小企业提供了负担得起的安全网——我们为 Pigsty 软件本身提供保证和支持覆盖。标准版订阅使用专门的商业许可证,提供书面合同承诺,免除 Pigsty 的 AGPLv3 衍生作品开源义务。

我们为标准版订阅客户提供一次性架构咨询服务。根据您的环境和可用资源,我们将提出合适的数据库架构设计。无论您想使用 PostgreSQL 构建业务系统还是自托管 Odoo、Dify、Supabase、Gitlab 或其他应用程序,我们都可以提供全面支持,包括离线安装和网络解决方案。

Pigsty 标准版订阅包括基本的专家工单和问答服务。我们承诺在工作时间内回应您的问题。对于需要额外支持的更复杂问题,我们的专家支持(人·天)服务也可以购买。我们的 PostgreSQL 专业知识可以帮助您避免许多陷阱,为您节省时间、精力和成本。

对于主流开源 Linux 发行版(EL9、Debian 12、Ubuntu 22.04)的最新稳定次要版本,Pigsty 标准版订阅提供 x86_64aarch64 的离线软件安装包。这些包包括 PostgreSQL 17 内核和所有可用扩展,经过测试以确保快速、稳定、高效的安装,版本一致,独立于网络环境和上游仓库变化。

Pigsty 标准版的起始价格为 8,000 美元/年,大致相当于 AWS HA RDS PG 4 个 vCPU 的年费或月薪 600 美元 的实习生的工资。

代码 发行版主要版本 次要版本 x86_64 aarch64 PG17 PG16 PG15 PG14 PG13
EL9 RHEL 9 / Rocky9 / Alma9 9.5 el9.x86_64 el9.aarch64
D12 Debian 12 (bookworm) 12.10 d12.x86_64 d12.aarch64
U22 Ubuntu 22.04 (jammy) 22.04.5 u22.x86_64 u22.aarch64

Pigsty 专业版

典型企业用户的合适选择

Pigsty 专业版订阅在标准版产品的基础上提供更高级的咨询服务。专业版订阅包括复杂问题分析和性能瓶颈优化,确保您在关键时刻能够获得顶级 DBA 专业知识。

我们为专业版订阅客户提供全面的架构咨询。根据您的业务需求和资源可用性,我们制定最佳的数据库架构设计并确保其成功实施。我们还协助进行高可用性测试和 PITR 练习,并提供关于 Pigsty 监控系统、配置方法和管理命令的培训。

Pigsty 专业版订阅提供增强的支持。我们每年提供一个专家人·天,以及每月不超过五小时的 DBA 咨询和问答。我们还提供更快的 SLA 响应时间:对于常规问题,我们保证在工作日工作时间(5x8)内四小时内响应。

Pigsty 专业版订阅支持更广泛的操作系统,在支持的发行版列表中添加了 EL 8 和 Ubuntu 24.04,并为所有这些版本提供 aarch64 支持。如果您没有使用最新的次要版本,我们可以为您指定的次要版本定制离线软件包。此外,离线包包括所有 Pigsty 功能模块,如 PG 分支内核(IvorySQL、PolarDB、Babelfish)和所有 Pro/Beta 模块。

Pigsty 专业版提供对三个最新 PostgreSQL 主要发行版(17、16、15)的支持,并为 PostgreSQL 主要版本升级以及 Pigsty 升级提供专家指导。

Pigsty 专业版的起始价格为 24,000 美元/年,大致相当于 AWS HA RDS PG 11 个 vCPU 的年费,或月薪 2,000 美元 的初级 DevOps 工程师的年薪。

代码 发行版主要版本 次要版本 x86_64 aarch64 PG17 PG16 PG15 PG14 PG13
EL9 RHEL 9 / Rocky9 / Alma9 9.5 el9.x86_64 el9.aarch64
D12 Debian 12 (bookworm) 12.10 d12.x86_64 d12.aarch64
U22 Ubuntu 22.04 (jammy) 22.04.5 u22.x86_64 u22.aarch64
U24 Ubuntu 24.04 (noble) 24.04.5 u24.x86_64 u24.aarch64
EL8 RHEL 8 / Rocky8 / Alma8 8.10 el8.x86_64 el8.aarch64

Pigsty 企业版

专为关键任务场景设计

Pigsty 企业版专为需要严格 SLA 的中大型企业或关键任务场景而设计。通过企业版订阅,我们提供最高级别的支持来满足您的所有数据库需求。

在企业版订阅下,我们帮助您设计和实施最佳的数据库架构解决方案。除了数据库演练、压力测试和性能评估外,我们还提供管理系统的咨询和培训,帮助您建立符合各种安全和合规要求的全面数据库管理框架。

Pigsty 企业版每年包括两个专家人·天,以及每月最多 10 小时的 DBA 咨询和问答。对于常规问题,我们保证 7x24 在 30 分钟内响应,并始终优先处理您的请求。

Pigsty 企业版订阅提供最广泛的操作系统支持,添加了 EL7、Debian 11 和 Ubuntu 20.04,包括 EOL 发行版。 我们还可以定制支持 Euler、Anolis、UOS、Kylin、TencentOS、AliOS、OpenCloudOS 和其他 Linux 发行版。

Pigsty 企业版订阅涵盖其活跃生命周期内的所有 PostgreSQL 主要发行版(13–17),确保不同主要版本之间的平滑就地升级。使用包含的人·天,您可以通过零停机、蓝绿部署过程将 PostgreSQL 集群迁移到最新主要版本。

Pigsty 企业版允许在指定规模下将 Pigsty 用作 DBaaS,允许您构建和销售云数据库服务。它还允许 OEM 使用——您可以在约定范围内使用自己的徽标、商标和品牌分发 Pigsty。

Pigsty 企业版的起始价格为 60,000 美元/年,相当于 AWS RDS for PostgreSQL 的 27 个 vCPU,或月薪 5,000 美元 的开发人员。

代码 发行版主要版本 次要版本 x86_64 aarch64 PG17 PG16 PG15 PG14 PG13
EL9 RHEL 9 / Rocky9 / Alma9 9.5 el9.x86_64 el9.aarch64
D12 Debian 12 (bookworm) 12.10 d12.x86_64 d12.aarch64
U22 Ubuntu 22.04 (jammy) 22.04.5 u22.x86_64 u22.aarch64
U24 Ubuntu 24.04 (noble) 24.04.5 u24.x86_64 u24.aarch64
EL8 RHEL 8 … / Anolis8 8.10 el8.x86_64 el8.aarch64
EL7 RHEL 7 … / UOS / Euler 7.9 el7.x86_64 el7.aarch64
D11 Debian 11 (bullseye) 11.11 d11.x86_64 d11.aarch64
U20 Ubuntu 20.04 (focal) 20.04.6 u20.x86_64 u20.aarch64

定价

Pigsty 订阅是年度的,从约定日期开始。到期前付款意味着自动续订。连续订阅享受折扣:第二年 5% 折扣,后续年份 10% 折扣,三年承诺 15% 折扣。

订阅到期后,不续订将导致更新、技术支持和咨询停止,但之前安装的专业版软件仍可使用。不续订间隙在重新订阅时不需要补缴,但忠诚度折扣会重置。

Pigsty 的定价提供卓越的价值——以与雇用全职专家或使用云数据库服务相比较的成本,提供对顶级 DBA 专业知识和数据库管理实践的即时访问。作为参考,类似企业数据库服务的市场价格包括:

企业数据库服务的公平市场价格通常在每 vCPU 1K - 4K 美元/年 的范围内。

Pigsty 的定价提供无与伦比的成本效率,特别是在高端服务器上。

11 - PostgreSQL

世界上最先进的开源关系型数据库!

概念

了解 Pigsty 中的 PostgreSQL 集群架构,重要实体与核心概念。

架构
    PostgreSQL 集群架构与核心概念
服务
    通过负载均衡、代理、连接池提供可靠服务接入
数据库
    定义、创建、管理业务数据库
用户
    定义、创建、管理业务用户与角色
认证
    使用 HBA 规则进行认证与访问控制
权限
    开箱即用的默认角色与权限模型

管理

内核
    使用不同风味的 PostgreSQL 内核分支
扩展
    利用 437 个 PostgreSQL 扩展协同带来的超能力
配置
    定义不同类型的 PostgreSQL 实例和集群
参数
    使用 120 个参数来深度定制 PostgreSQL 集群
管理
    管理 PostgreSQL 集群、实例、用户、数据库
剧本
    使用 Ansible 剧本进行控制原语操作
备份恢复
    备份与时间点恢复 (PITR)
迁移
    零停机蓝绿部署迁移
监控
    监控现有的 PostgreSQL 或 RDS 实例
仪表板
    使用 Grafana 仪表板可视化信息

11.1 - 架构

PostgreSQL 集群架构和概念

实体关系

Pigsty 的 PGSQL 模块中有四种核心实体类型:

  • 集群:一个自治的 PostgreSQL 业务单元,其他实体的顶层命名空间
  • 服务:集群能力的抽象,流量路由,通过不同的节点端口暴露服务
  • 实例:一个 PostgreSQL 服务器,由单个节点上的一组运行进程和文件组成
  • 节点:硬件资源的抽象,可以是裸机、虚拟机或 k8s pod

架构

以下是在 配置清单 中描述的 PostgreSQL 集群 pg-test

pg-test:
  hosts:
    10.10.10.11: { pg_seq: 1, pg_role: primary }
    10.10.10.12: { pg_seq: 2, pg_role: replica }
    10.10.10.13: { pg_seq: 3, pg_role: replica }
  vars:
    pg_cluster: pg-test

它定义了一个如上所示的 高可用 PostgreSQL 集群,该集群中的相关实体包括:

  • 1 个 PostgreSQL 集群:pg-test
  • 2 个实例角色:primaryreplica
  • 3 个 PostgreSQL 实例:pg-test-1pg-test-2pg-test-3
  • 3 个节点:10.10.10.1110.10.10.1210.10.10.13
  • 4 个 PostgreSQL 服务,默认自动生成:

高可用

PostgreSQL 集群由 Patroni 管理, 这是一个经过实战验证的 PostgreSQL 高可用解决方案。 它将在多个节点上设置 PostgreSQL 复制,并在主节点宕机时执行自动故障转移。

备份由 pgBackRest 处理,这是一个强大的 PostgreSQL 备份工具, 支持增量备份/恢复、压缩、加密,备份到本地磁盘或 S3 / MinIO。

pgbouncer 是一个轻量级连接池,可以在高并发情况下提高性能。 它与 Postgres 服务器 1:1 部署,默认被主库/从库服务使用。

服务HAProxy 暴露,这是一个高性能的 TCP/HTTP 负载均衡器,它是 NODE 模块的一部分。 4 个 默认服务幂等的方式在所有集群节点上自动暴露。

应用程序可以访问任何 haproxy 来访问 Postgres 集群,流量将根据 patroni 健康检查端点路由到正确的实例。 因此故障转移对应用程序是透明的。

patroni 需要您的部署中有一个正常工作的 ETCD,pgbackrest 可以使用可选的 MinIO 作为集中备份存储; 监控导出器将收集指标和日志到 Infra 模块。


组件

PGSQL 节点 由以下组件组成(部分可以禁用):

组件 端口 描述
postgres 5432 由 Patroni 管理的 PostgreSQL 服务器进程
pgbouncer 6432 Pgbouncer 连接池
pgbackrest - 备份和时间点恢复工具
patroni 8008 Patroni 高可用组件,管理 postgres
primary @ haproxy 5433 主库连接池:读写服务
replica @ haproxy 5434 从库连接池:只读服务
default @ haproxy 5436 主库直连服务
offline @ haproxy 5438 离线直连:离线读取服务
pg_exporter 9630 PostgreSQL 监控指标导出器
pgbouncer_exporter 9631 pgbouncer 监控指标导出器
pgbackrest_exporter 9854 pgbackrest 监控指标导出器
vip-manager - 绑定 VIP 到主库

交互

同时,基础设施节点 由以下与 PGSQL 交互的组件组成:

组件 端口 域名 描述
nginx 80 h.pigsty Web 服务门户(YUM/APT 仓库)
alertmanager 9059 a.pigsty 告警聚合和分发
prometheus 9058 p.pigsty 监控时间序列数据库
grafana 3000 g.pigsty 可视化平台
lok 3100 - 日志收集服务器
pushgateway 9091 - 收集一次性作业指标
blackbox_exporter 9115 - 黑盒探测
dnsmasq 53 - DNS 服务器
chronyd 123 - NTP 时间服务器
ansible - - 运行剧本
  • 集群 DNS 由基础设施节点上的 DNSMASQ 解析
  • 集群 VIP 由 vip-manager 管理,绑定到集群主库
    • vip-manager 将直接从 etcd 集群获取由 patroni 写入的集群领导者信息
  • 集群服务由节点上的 Haproxy 暴露,服务通过节点端口(543x)区分
    • Haproxy 端口 9101:监控指标、统计信息和管理页面
    • Haproxy 端口 5433:路由到主库 pgbouncer 的默认服务:primary
    • Haproxy 端口 5434:路由到从库 pgbouncer 的默认服务:replica
    • Haproxy 端口 5436:路由到主库 postgres 的默认服务:default
    • Haproxy 端口 5438:路由到离线 postgres 的默认服务:offline
    • HAProxy 将根据 patroni 提供的健康检查信息路由流量
  • Pgbouncer 是监听端口 6432 的连接池
    • 通过本地 unix socket 与 Postgres 服务器 1:1 部署
    • 生产流量(主库/从库)默认通过 pgbouncer
    • 通过将 pg_default_service_dest 设置为 postgres 来绕过 primary/replica 服务的 pgbouncer
    • 默认/离线服务将始终绕过 pgbouncer 并直接连接到目标 Postgres
  • Postgres 在端口 5432 提供关系数据库服务
    • 在多个节点上安装 PGSQL 模块将自动基于复制形成高可用集群
    • PostgreSQL 默认由 patroni 监督
  • Patroni 将默认在端口 8008 监督 PostgreSQL 服务器
    • Patroni 将 postgres 服务器作为子进程生成
    • Patroni 使用 etcd 作为 DCS:配置存储、故障检测和领导者选举
    • Patroni 将通过健康检查提供 Postgres 信息,由 HAProxy 使用
    • Patroni 指标将被基础设施节点上的 prometheus 抓取
  • PG Exporter 将在端口 9630 暴露 postgres 指标
  • Pgbouncer Exporter 将在端口 9631 暴露 pgbouncer 指标
    • Pgbouncer 的指标将被基础设施节点上的 prometheus 抓取
  • pgBackRest 默认在本地仓库上工作(pgbackrest_method
    • 如果使用 local(默认)作为备份仓库,主库的 pg_fs_backup 用作本地备份仓库
    • 如果使用 minio,pgBackRest 将在专用 MinIO 集群上创建仓库
  • Postgres 相关日志(postgres、pgbouncer、patroni、pgbackrest)由 promtail 在端口 9080 暴露
    • Promtail 将日志发送到基础设施节点上的 Loki

完整实体关系图

一个 Pigsty 部署对应一个 配置清单 文件和一个 基础设施。 一个 Pigsty 部署中可能有多个数据库集群。

一个集群/实例可能有多个数据库,数据库包含表和其他对象(查询、索引、函数、序列…)。

11.2 - 配置

描述和配置 PostgreSQL 集群

您可以定义不同类型的实例和集群。

  • 身份参数:用于描述 PostgreSQL 集群的参数
  • 命名规范:用于描述 PostgreSQL 集群的参数
  • 主库:定义单实例集群
  • 从库:定义具有一个主库和一个从库的基本高可用集群
  • 离线库:为 OLAP/ETL/交互查询定义专用实例
  • 同步从库:启用同步提交以确保无数据丢失
  • 法定人数提交:使用法定人数同步提交获得更高的一致性级别
  • 备用集群:克隆现有集群并跟随它
  • 延迟集群:克隆现有集群用于紧急数据恢复
  • Citus 集群:定义 Citus 分布式数据库集群

身份参数

描述 PostgreSQL 集群需要 4必需参数:

名称 类型 级别 描述
inventory_hostname ip 实例 PG 节点 IPv4 地址
pg_cluster string 集群 PG 数据库集群名称
pg_seq number 实例 PG 数据库实例 ID
pg_role enum 实例 PG 数据库实例角色
  • pg_cluster:集群名称,在集群级别配置
  • pg_role:在实例级别配置,标识实例的角色
    • primary 角色将此实例标记为集群领导者(初始时)
    • replica 是默认角色,将此实例标记为普通只读从库
    • offline 将此实例标记为服务于 offline 服务的特殊只读从库
  • pg_seq:用于在集群内标识实例,一个非负整数
    • 从 0 或 1 开始,按顺序递增分配,一旦分配就不要更改
    • {{ pg_cluster }}-{{ pg_seq }} 用于唯一标识实例,即 pg_instance
    • {{ pg_cluster }}-{{ pg_role }} 用于标识集群内的服务,即 pg_service
  • pg_shardpg_group 用于水平分片集群,仅适用于 citus 和 greenplum

这些身份将在整个系统中使用,例如,指标可能如下所示:

pg_up{cls="pg-test", ins="pg-test-1", ip="10.10.10.11", job="pgsql"}
pg_up{cls="pg-test", ins="pg-test-2", ip="10.10.10.12", job="pgsql"}
pg_up{cls="pg-test", ins="pg-test-3", ip="10.10.10.13", job="pgsql"}

分片集群

您可以使用可选的 pg_shardpg_group 参数来标识水平分片集群:

名称 类型 级别 描述
pg_shard string C 集群的 PG 数据库分片名称
pg_group number C 集群的 PG 数据库分片索引

例如,使用 citus、greenplum 或手动分片进行水平分片:

pg-citus:
  hosts:
    10.10.10.10: { pg_group: 0, pg_cluster: pg-citus0 ,pg_seq: 1, pg_role: primary }
    10.10.10.11: { pg_group: 0, pg_cluster: pg-citus0 ,pg_seq: 2, pg_role: replica }
    10.10.10.12: { pg_group: 1, pg_cluster: pg-citus1 ,pg_seq: 1, pg_role: primary }
    10.10.10.13: { pg_group: 2, pg_cluster: pg-citus2 ,pg_seq: 1, pg_role: primary }
  vars:
    pg_mode: citus          # PostgreSQL 集群模式:citus
    pg_shard: pg-citus      # citus 分片名称:pg-citus

命名规范

  • 集群名称应为有效的域名,匹配 [a-zA-Z0-9-]+,且 ≤ 40 字符
  • 服务名称以集群名称为前缀,以单个单词为后缀,用 - 连接
  • 实例名称以集群名称为前缀,以整数为后缀,用 - 连接
  • 节点由其主要 IPv4 地址标识,主机名用作次要标识符
实体 命名示例
集群 pg-metapg-test
服务 pg-meta-primarypg-test-replicapg-test-offlinepg-test-standbypg-meta-default
实例 pg-meta-1pg-test-1pg-test-2pg-test-3
节点 10.10.10.1010.10.10.1110.10.10.1210.10.10.13

版本策略

Pigsty 遵循 PostgreSQL 版本策略 并"官方"支持以下主要版本。

主版本 小版本 注释 扩展 RPM 扩展 DEB
18 18.1 最新稳定版本(推荐 392 390
17 17.7 次要稳定版本(推荐 418 413
16 16.11 2023-09-14 首次发布 420 412
15 15.15 2022-10-13 首次发布 422 414
14 14.20 2021-09-30 首次发布 410 402
13 13.23 2020-09-24 首次发布,即将结束支持 382 371

Pigsty 支持 PG 13 - 18。较低的主版本(12-)“可能"有效,但不保证。 对于遗留 PG 版本支持,请考虑我们的 专业服务

要使用不同的主版本,请配置 pg_version 变量。 可以使用 -v <ver> 选项全局 配置。 只要它们在本地/上游仓库中可用,就不需要进一步更改。

pg-v13:
  hosts: { 10.10.10.13: { pg_seq: 1 ,pg_role: primary } }
  vars:
    pg_cluster: pg-v13
    pg_version: 13

pg-v14:
  hosts: { 10.10.10.14: { pg_seq: 1 ,pg_role: primary } }
  vars:
    pg_cluster: pg-v14
    pg_version: 14

pg-v15:
  hosts: { 10.10.10.15: { pg_seq: 1 ,pg_role: primary } }
  vars:
    pg_cluster: pg-v15
    pg_version: 15

pg-v16:
  hosts: { 10.10.10.16: { pg_seq: 1 ,pg_role: primary } }
  vars:
    pg_cluster: pg-v16
    pg_version: 16

pg-v17:
  hosts: { 10.10.10.17: { pg_seq: 1 ,pg_role: primary } }
  vars:
    pg_cluster: pg-v17
    pg_version: 17

主库

让我们从最简单的情况开始,单例元数据库:

pg-test:
  hosts:
    10.10.10.11: { pg_seq: 1, pg_role: primary }
  vars:
    pg_cluster: pg-test

使用以下命令在 10.10.10.11 节点上创建主数据库实例。

bin/pgsql-add pg-test

从库

要添加物理从库,您可以将新实例分配给 pg-test,并将 pg_role 设置为 replica

pg-test:
  hosts:
    10.10.10.11: { pg_seq: 1, pg_role: primary }
    10.10.10.12: { pg_seq: 2, pg_role: replica }  # <--- 新添加的
  vars:
    pg_cluster: pg-test

您可以 创建 整个集群或 添加 从库到现有集群:

bin/pgsql-add pg-test               # 一次性初始化整个集群
bin/pgsql-add pg-test 10.10.10.12   # 向现有集群添加从库

离线库

离线实例是专用从库,用于服务慢查询、ETL、OLAP 流量和交互查询等。

要添加离线实例,分配一个新实例并将 pg_role 设置为 offline

pg-test:
  hosts:
    10.10.10.11: { pg_seq: 1, pg_role: primary }
    10.10.10.12: { pg_seq: 2, pg_role: replica }
    10.10.10.13: { pg_seq: 3, pg_role: offline } # <--- 新添加的
  vars:
    pg_cluster: pg-test

离线实例的工作方式类似于普通从库实例,但它在 pg-test-replica 服务中用作备份服务器。也就是说,只有当所有 replica 实例都宕机时,离线和主实例才会提供服务。

您可以使用 pg_default_hba_rulespg_hba_rules 对离线实例进行临时访问控制。它将应用于离线实例和任何带有 pg_offline_query 标志的实例。


同步从库

Pigsty 默认使用异步流复制,可能有小的复制延迟(10KB / 10ms)。当主库失效时可能出现小的数据丢失窗口(可通过 pg_rpo 控制),但对于大多数场景这是可以接受的。

但在一些关键场景(例如金融交易)中,数据丢失是完全不可接受的,或者需要读写一致性。在这种情况下,您可以启用同步提交来确保这一点。

要启用同步从库模式,您可以在 pg_conf 中简单使用 crit.yml 模板:

pg-test:
  hosts:
    10.10.10.11: { pg_seq: 1, pg_role: primary }
    10.10.10.12: { pg_seq: 2, pg_role: replica }
    10.10.10.13: { pg_seq: 3, pg_role: replica }
  vars:
    pg_cluster: pg-test
    pg_conf: crit.yml   # <--- 使用 crit 模板

要在现有集群上启用同步从库,配置 集群并启用 synchronous_mode

$ pg edit-config pg-test    # 在管理节点上使用管理员用户运行
+++
-synchronous_mode: false    # <--- 旧值
+synchronous_mode: true     # <--- 新值
 synchronous_mode_strict: false

Apply these changes? [y/N]: y

如果 synchronous_mode: truesynchronous_standby_names 参数将由 patroni 管理。它将从所有可用从库中选择一个同步从库,并将其名称写入主库的配置文件。


法定人数提交

当启用 同步从库 时,PostgreSQL 将选择一个从库作为备用实例,所有其他从库作为候选。主库将等待备用实例刷新到磁盘后再确认提交,备用实例将始终拥有最新数据而没有任何延迟。

但是,您可以通过法定人数提交实现更高/更低的一致性级别(与可用性权衡)。

例如,要让所有 2 个从库确认提交:

synchronous_mode: true          # 确保启用同步模式
synchronous_node_count: 2       # 至少需要 2 个节点确认提交

如果您有更多从库并希望有更多同步从库,请相应增加 synchronous_node_count。注意在您 添加移除 从库时相应调整 synchronous_node_count

postgres synchronous_standby_names 参数将由 patroni 管理:

synchronous_standby_names = '2 ("pg-test-3","pg-test-2")'

经典的法定人数提交是使用大多数从库来确认提交。

synchronous_mode: quorum        # 使用法定人数提交
postgresql:
  parameters:                   # 更改 PostgreSQL 参数 `synchronous_standby_names`,使用 `ANY n ()` 记号
    synchronous_standby_names: 'ANY 1 (*)'  # 您可以指定备用名称列表,或使用 `*` 匹配所有

备用集群

您可以克隆现有集群并创建 备用集群,用于迁移、水平拆分、多可用区部署或灾难恢复。

备用集群的定义与任何其他普通集群相同,除了在主实例上定义了 pg_upstream

例如,您有一个 pg-test 集群,要创建备用集群 pg-test2,配置清单可能如下所示:

# pg-test 是原始集群
pg-test:
  hosts:
    10.10.10.11: { pg_seq: 1, pg_role: primary }
  vars: { pg_cluster: pg-test }

# pg-test2 是 pg-test 的备用集群
pg-test2:
  hosts:
    10.10.10.12: { pg_seq: 1, pg_role: primary , pg_upstream: 10.10.10.11 } # <--- 在这里定义 pg_upstream
    10.10.10.13: { pg_seq: 2, pg_role: replica }
  vars: { pg_cluster: pg-test2 }

pg-test2-1pg-test2 的主库将是 pg-test 的从库,并在 pg-test2 中充当备用领导者

只需确保在备份集群的主库上配置了 pg_upstream 参数,以自动从原始上游拉取备份。

bin/pgsql-add pg-test     # 创建原始集群
bin/pgsql-add pg-test2    # 创建备份集群

延迟集群

延迟集群是一种特殊类型的备用集群,用于尽快恢复"意外删除"的数据。

例如,如果您希望有一个集群 pg-testdelay,其数据与 1 天前的 pg-test 集群相同:

# pg-test 是原始集群
pg-test:
  hosts:
    10.10.10.11: { pg_seq: 1, pg_role: primary }
  vars: { pg_cluster: pg-test }

# pg-testdelay 是 pg-test 的延迟集群
pg-testdelay:
  hosts:
    10.10.10.12: { pg_seq: 1, pg_role: primary , pg_upstream: 10.10.10.11, pg_delay: 1d }
    10.10.10.13: { pg_seq: 2, pg_role: replica }
  vars: { pg_cluster: pg-test2 }

您也可以在现有 备用集群配置 复制延迟。

$ pg edit-config pg-testdelay
 standby_cluster:
   create_replica_methods:
   - basebackup
   host: 10.10.10.11
   port: 5432
+  recovery_min_apply_delay: 1h    # <--- 在这里添加延迟

Apply these changes? [y/N]: y

当某些元组和表被意外删除时,您可以将此延迟集群推进到适当的时间点并从中选择数据。

它需要更多资源,但比 PITR 更快且影响更小。


Citus 集群

Pigsty 有原生 citus 支持。请查看 conf/citus.yml 示例。

要定义 citus 集群,您必须指定以下参数:

此外,需要允许从本地和其他数据节点进行 ssl 访问的额外 hba 规则。可能如下所示:

all:
  children:
    pg-citus0: # citus 数据节点 0
      hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
      vars: { pg_cluster: pg-citus0 , pg_group: 0 }
    pg-citus1: # citus 数据节点 1
      hosts: { 10.10.10.11: { pg_seq: 1, pg_role: primary } }
      vars: { pg_cluster: pg-citus1 , pg_group: 1 }
    pg-citus2: # citus 数据节点 2
      hosts: { 10.10.10.12: { pg_seq: 1, pg_role: primary } }
      vars: { pg_cluster: pg-citus2 , pg_group: 2 }
    pg-citus3: # citus 数据节点 3,带有额外从库
      hosts:
        10.10.10.13: { pg_seq: 1, pg_role: primary }
        10.10.10.14: { pg_seq: 2, pg_role: replica }
      vars: { pg_cluster: pg-citus3 , pg_group: 3 }
  vars:                               # 所有 citus 集群的全局参数
    pg_mode: citus                    # PostgreSQL 集群模式:citus
    pg_shard: pg-citus                # citus 分片名称:pg-citus
    patroni_citus_db: meta            # citus 分布式数据库名称
    pg_dbsu_password: DBUser.Postgres # 所有 citus 集群的数据库超级用户密码访问
    pg_users: [ { name: dbuser_meta ,password: DBUser.Meta ,pgbouncer: true ,roles: [ dbrole_admin ] } ]
    pg_databases: [ { name: meta ,extensions: [ { name: citus }, { name: postgis }, { name: timescaledb } ] } ]
    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'  }

您可以在协调器节点上创建分布式表和引用表。自 citus 11.2 以来,任何数据节点都可以用作协调器节点。

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$$);

11.3 - 参数

使用 121 个参数定制 PostgreSQL 集群

PGSQL 模块有 121 个参数。

章节 数量 描述
PG_ID 11 计算和检查 Postgres 身份 - 用于识别 PGSQL 实体(如实例和服务)的参数
PG_BUSINESS 12 Postgres 业务对象定义 - 业务用户、数据库、服务和身份验证的配置
PG_INSTALL 10 安装 PGSQL 包和扩展 - 数据库用户设置、版本选择和包安装的设置
PG_BOOTSTRAP 35 使用 Patroni 初始化 HA Postgres 集群 - 包括数据目录、网络和高可用性设置的全面集群初始化
PG_PROVISION 9 创建用户、数据库和数据库内对象 - 引导后的数据库对象置备和默认配置
PG_BACKUP 6 使用 pgbackrest 设置备份仓库 - 使用 pgbackrest 的备份和恢复配置
PG_ACCESS 16 暴露 pg 服务,绑定 VIP 和注册 DNS - 服务暴露、负载均衡、VIP 管理和 DNS 注册
PG_MONITOR 18 为 PGSQL 实例添加监控 - 使用各种导出器进行指标收集的监控设置
PG_REMOVE:删除 Postgres 集群
名称 类型 级别 注释
pg_safeguard bool G/C/A 启用时中止删除,默认为 false
pg_rm_data bool G/C/A 删除 PostgreSQL 数据,默认为 true
pg_rm_backup bool G/C/A 删除主实例的 pgBackRest 备份,默认为 true
pg_rm_pkg bool G/C/A 卸载 PostgreSQL 软件包,默认为 true

PG_ID

以下是一些常用的参数,用于标识 PGSQL 实体:实例、服务等…


pg_mode

参数名称: pg_mode, 类型: enum, 层次:C

pgsql 集群模式,默认为 pgsql,即标准 PostgreSQL 集群。

  • pgsql: 标准 PostgreSQL 集群,默认值。
  • citus: 使用 citus 扩展的水平分片集群。
  • mssql: Babelfish MSSQL 线缆协议兼容内核。
  • ivory: IvorySQL Oracle 兼容内核。
  • polar: PolarDB for PostgreSQL 内核。
  • oracle: PolarDB for Oracle 内核。
  • gpsql: Greenplum / Cloudberry

如果 pg_mode 设置为 citusgpsql,则需要 pg_shardpg_group 用于水平分片集群。


pg_cluster

参数名称: pg_cluster, 类型: string, 层次:C

PostgreSQL 集群名称,必选的身份标识参数,没有默认值

集群名将用作资源的命名空间。

集群命名需要遵循特定的命名模式:[a-z][a-z0-9-]*,即,只使用数字与小写字母,且不以数字开头,以符合标识上的不同约束的要求。


pg_seq

参数名称: pg_seq, 类型: int, 层次:I

PostgreSQL 实例序列号,必选的身份标识参数,无默认值。

此实例的序号,在其集群内是唯一分配的,通常使用自然数,从0或1开始分配,通常不会回收重用。


pg_role

参数名称: pg_role, 类型: enum, 层次:I

pgsql 角色,必需,可以是 primary,replica,offline

PostgreSQL 实例的角色,可以是:primaryreplicastandbyoffline

  • primary: 主库,集群中有且仅有一个。
  • replica: 用于承载在线只读流量的副本,可能会有轻微复制延迟(10ms~100ms, 100KB)。
  • standby: 始终与主库同步的特殊副本,没有复制延迟和数据丢失。(目前与 replica 相同)
  • offline: 用于承接离线只读流量的离线副本,如统计分析/ETL/个人查询等。

身份参数,必需参数,实例级参数。


pg_instances

参数名称: pg_instances, 类型: dict, 层次:I

使用 {port:ins_vars} 的形式在一台主机上定义多个 PostgreSQL 实例。

此参数是为在单个节点上的多实例部署保留的参数,Pigsty 尚未实现此功能,并强烈建议独占节点部署。


pg_upstream

参数名称: pg_upstream, 类型: ip, 层次:I

备份集群或级联从库的上游实例 IP 地址。

在集群的 primary 实例上设置 pg_upstream ,表示此集群是一个备份集群,该实例将作为 standby leader,从上游集群接收并应用更改。

对非 primary 实例设置 pg_upstream 参数将指定一个具体实例作为物理复制的上游,如果与主实例 ip 地址不同,此实例将成为 级联副本 。确保上游 IP 地址是同一集群中的另一个实例是用户的责任。


pg_shard

参数名称: pg_shard, 类型: string, 层次:C

PostgreSQL 水平分片名称,对于分片集群来说(例如 citus 集群),这是的必选标识参数。

当多个标准的 PostgreSQL 集群一起以水平分片方式为同一业务提供服务时,Pigsty 将此组集群标记为 水平分片集群

pg_shard 是分片组名称。它通常是 pg_cluster 的前缀。

例如,如果我们有一个分片组 pg-citus,并且其中有4个集群,它们的标识参数将是:

cls pg_shard: pg-citus
cls pg_group = 0:   pg-citus0
cls pg_group = 1:   pg-citus1
cls pg_group = 2:   pg-citus2
cls pg_group = 3:   pg-citus3

pg_group

参数名称: pg_group, 类型: int, 层次:C

PostgreSQL 水平分片集群的分片索引号,对于分片集群来说(例如 citus 集群),这是的必选标识参数。

此参数与 pg_shard 配对使用,通常可以使用非负整数作为索引号。


gp_role

参数名称: gp_role, 类型: enum, 层次:C

PostgreSQL 集群的 Greenplum/Matrixdb 角色,可以是 mastersegment

  • master: 标记 postgres 集群为 greenplum 主实例(协调节点),这是默认值。
  • segment 标记 postgres 集群为 greenplum 段集群(数据节点)。

此参数仅用于 Greenplum/MatrixDB 数据库 (pg_modegpsql),对于普通的 PostgreSQL 集群没有意义。


pg_exporters

参数名称: pg_exporters, 类型: dict, 层次:C

额外用于监控远程 PostgreSQL 实例的 Exporter 定义,默认值:{}

如果您希望监控远程 PostgreSQL 实例,请在监控系统所在节点(Infra节点)集群上的 pg_exporters 参数中定义它们,并使用 pgsql-monitor.yml 剧本来完成部署。

pg_exporters: # list all remote instances here, alloc a unique unused local port as k
    20001: { pg_cluster: pg-foo, pg_seq: 1, pg_host: 10.10.10.10 }
    20004: { pg_cluster: pg-foo, pg_seq: 2, pg_host: 10.10.10.11 }
    20002: { pg_cluster: pg-bar, pg_seq: 1, pg_host: 10.10.10.12 }
    20003: { pg_cluster: pg-bar, pg_seq: 1, pg_host: 10.10.10.13 }

pg_offline_query

参数名称: pg_offline_query, 类型: bool, 层次:I

设置为 true 以在此实例上启用离线查询,默认为 false

当某个 PostgreSQL 实例启用此参数时, 属于 dbrole_offline 分组的用户可以直接连接到该 PostgreSQL 实例上执行离线查询(慢查询,交互式查询,ETL/分析类查询)。

带有此标记的实例在效果上类似于为实例设置 pg_role = offline ,唯一的区别在于 offline 实例默认不会承载 replica 服务的请求,是作为专用的离线/分析从库实例而存在的。

如果您没有富余的实例可以专门用于此目的,则可以挑选一台普通的从库,在实例层次启用此参数,以便在需要时承载离线查询。


PG_BUSINESS

定制集群模板:用户,数据库,服务,权限规则。

用户需重点关注此部分参数,因为这里是业务声明自己所需数据库对象的地方。

默认的数据库用户及其凭据,强烈建议在生产环境中修改这些用户的密码。

# postgres business object definition, overwrite in group vars
pg_users: []                      # postgres business users
pg_databases: []                  # postgres business databases
pg_services: []                   # postgres business services
pg_hba_rules: []                  # business hba rules for postgres
pgb_hba_rules: []                 # business hba rules for pgbouncer
# global credentials, overwrite in global vars
pg_dbsu_password: ''              # dbsu password, empty string means no dbsu password by default
pg_replication_username: replicator
pg_replication_password: DBUser.Replicator
pg_admin_username: dbuser_dba
pg_admin_password: DBUser.DBA
pg_monitor_username: dbuser_monitor
pg_monitor_password: DBUser.Monitor

pg_users

参数名称: pg_users, 类型: user[], 层次:C

PostgreSQL 业务用户列表,需要在 PG 集群层面进行定义。默认值为:[] 空列表。

每一个数组元素都是一个 用户/角色 定义,例如:

- name: dbuser_meta               # 必需,`name` 是用户定义的唯一必选字段
  password: DBUser.Meta           # 可选,密码,可以是 scram-sha-256 哈希字符串或明文
  login: true                     # 可选,默认情况下可以登录
  superuser: false                # 可选,默认为 false,是超级用户吗?
  createdb: false                 # 可选,默认为 false,可以创建数据库吗?
  createrole: false               # 可选,默认为 false,可以创建角色吗?
  inherit: true                   # 可选,默认情况下,此角色可以使用继承的权限吗?
  replication: false              # 可选,默认为 false,此角色可以进行复制吗?
  bypassrls: false                # 可选,默认为 false,此角色可以绕过行级安全吗?
  pgbouncer: true                 # 可选,默认为 false,将此用户添加到 pgbouncer 用户列表吗?(使用连接池的生产用户应该显式定义为 true)
  connlimit: -1                   # 可选,用户连接限制,默认 -1 禁用限制
  expire_in: 3650                 # 可选,此角色过期时间:从创建时 + n天计算(优先级比 expire_at 更高)
  expire_at: '2030-12-31'         # 可选,此角色过期的时间点,使用 YYYY-MM-DD 格式的字符串指定一个特定日期(优先级没 expire_in 高)
  comment: pigsty admin user      # 可选,此用户/角色的说明与备注字符串
  roles: [dbrole_admin]           # 可选,默认角色为:dbrole_{admin,readonly,readwrite,offline}
  parameters: {}                  # 可选,使用 `ALTER ROLE SET` 针对这个角色,配置角色级的数据库参数
  pool_mode: transaction          # 可选,默认为 transaction 的 pgbouncer 池模式,用户级别
  pool_connlimit: -1              # 可选,用户级别的最大数据库连接数,默认 -1 禁用限制
  search_path: public             # 可选,根据 postgresql 文档的键值配置参数(例如:使用 pigsty 作为默认 search_path)

pg_databases

参数名称: pg_databases, 类型: database[], 层次:C

PostgreSQL 业务数据库列表,需要在 PG 集群层面进行定义。默认值为:[] 空列表。

每一个数组元素都是一个 业务数据库 定义,例如:

- name: meta                      # 必选,`name` 是数据库定义的唯一必选字段
  baseline: cmdb.sql              # 可选,数据库 sql 的基线定义文件路径(ansible 搜索路径中的相对路径,如 files/)
  pgbouncer: true                 # 可选,是否将此数据库添加到 pgbouncer 数据库列表?默认为 true
  schemas: [pigsty]               # 可选,要创建的附加模式,由模式名称字符串组成的数组
  extensions:                     # 可选,要安装的附加扩展: 扩展对象的数组
    - { name: postgis , schema: public }  # 可以指定将扩展安装到某个模式中,也可以不指定(不指定则安装到 search_path 首位模式中)
    - { name: timescaledb }               # 例如有的扩展会创建并使用固定的模式,就不需要指定模式。
    - vector                              # 你也可以直接使用字符串指定扩展名称
  comment: pigsty meta database   # 可选,数据库的说明与备注信息
  owner: postgres                 # 可选,数据库所有者,默认为 postgres
  template: template1             # 可选,要使用的模板,默认为 template1,目标必须是一个模板数据库
  encoding: UTF8                  # 可选,数据库编码,默认为 UTF8(必须与模板数据库相同)
  locale: C                       # 可选,数据库地区设置,默认为 C(必须与模板数据库相同)
  lc_collate: C                   # 可选,数据库 collate 排序规则,默认为 C(必须与模板数据库相同),没有理由不建议更改。
  lc_ctype: C                     # 可选,数据库 ctype 字符集,默认为 C(必须与模板数据库相同)
  tablespace: pg_default          # 可选,默认表空间,默认为 'pg_default'
  allowconn: true                 # 可选,是否允许连接,默认为 true。显式设置 false 将完全禁止连接到此数据库
  revokeconn: false               # 可选,撤销公共连接权限。默认为 false,设置为 true 时,属主和管理员之外用户的 CONNECT 权限会被回收
  register_datasource: true       # 可选,是否将此数据库注册到 grafana 数据源?默认为 true,显式设置为 false 会跳过注册
  connlimit: -1                   # 可选,数据库连接限制,默认为 -1 ,不限制,设置为正整数则会限制连接数。
  pool_auth_user: dbuser_meta     # 可选,连接到此 pgbouncer 数据库的所有连接都将使用此用户进行验证(启用 pgbouncer_auth_query 才有用)
  pool_mode: transaction          # 可选,数据库级别的 pgbouncer 池化模式,默认为 transaction
  pool_size: 64                   # 可选,数据库级别的 pgbouncer 默认池子大小,默认为 64
  pool_size_reserve: 32           # 可选,数据库级别的 pgbouncer 池子保留空间,默认为 32,当默认池子不够用时,最多再申请这么多条突发连接。
  pool_size_min: 0                # 可选,数据库级别的 pgbouncer 池的最小大小,默认为 0
  pool_max_db_conn: 100           # 可选,数据库级别的最大数据库连接数,默认为 100

在每个数据库定义对象中,只有 name 是必选字段,其他的字段都是可选项。


pg_services

参数名称: pg_services, 类型: service[], 层次:C

PostgreSQL 服务列表,需要在 PG 集群层面进行定义。默认值为:[] ,空列表。

用于在数据库集群层面定义额外的服务,数组中的每一个对象定义了一个服务,一个完整的服务定义样例如下:

- name: standby                   # 必选,服务名称,最终的 svc 名称会使用 `pg_cluster` 作为前缀,例如:pg-meta-standby
  port: 5435                      # 必选,暴露的服务端口(作为 kubernetes 服务节点端口模式)
  ip: "*"                         # 可选,服务绑定的 IP 地址,默认情况下为所有 IP 地址
  selector: "[]"                  # 必选,服务成员选择器,使用 JMESPath 来筛选配置清单
  backup: "[? pg_role == `primary`]"  # 可选,服务成员选择器(备份),也就是当默认选择器选中的实例都宕机后,服务才会由这里选中的实例成员来承载
  dest: default                   # 可选,目标端口,default|postgres|pgbouncer|<port_number>,默认为 'default',Default的意思就是使用 pg_default_service_dest 的取值来最终决定
  check: /sync                    # 可选,健康检查 URL 路径,默认为 /,这里使用 Patroni API:/sync ,只有同步备库和主库才会返回 200 健康状态码
  maxconn: 5000                   # 可选,允许的前端连接最大数,默认为5000
  balance: roundrobin             # 可选,haproxy 负载均衡算法(默认为 roundrobin,其他选项:leastconn)
  options: 'inter 3s fastinter 1s downinter 5s rise 3 fall 3 on-marked-down shutdown-sessions slowstart 30s maxconn 3000 maxqueue 128 weight 100'

请注意,本参数用于在集群层面添加额外的服务。如果您想在全局定义所有 PostgreSQL 数据库都要提供的服务,可以使用 pg_default_services 参数。


pg_hba_rules

参数名称: pg_hba_rules, 类型: hba[], 层次:C

数据库集群/实例的客户端IP黑白名单规则。默认为:[] 空列表。

对象数组,每一个对象都代表一条规则, hba 规则对象的定义形式如下:

- title: allow intranet password access
  role: common
  rules:
    - host   all  all  10.0.0.0/8      md5
    - host   all  all  172.16.0.0/12   md5
    - host   all  all  192.168.0.0/16  md5
  • title: 规则的标题名称,会被渲染为 HBA 文件中的注释。
  • rules:规则数组,每个元素是一条标准的 HBA 规则字符串。
  • role :规则的应用范围,哪些实例角色会启用这条规则?
  • common:对于所有实例生效
  • primary, replica,offline: 只针对特定的角色 pg_role 实例生效。
  • 特例:role: 'offline' 的规则除了会应用在 pg_role : offline 的实例上,对于带有 pg_offline_query 标记的实例也生效。

除了上面这种原生 HBA 规则定义形式,Pigsty 还提供了另外一种更为简便的别名形式:

- addr: 'intra'    # world|intra|infra|admin|local|localhost|cluster|<cidr>
  auth: 'pwd'      # trust|pwd|ssl|cert|deny|<official auth method>
  user: 'all'      # all|${dbsu}|${repl}|${admin}|${monitor}|<user>|<group>
  db: 'all'        # all|replication|....
  rules: []        # raw hba string precedence over above all
  title: allow intranet password access

pg_default_hba_rules 与本参数基本类似,但它是用于定义全局的 HBA 规则,而本参数通常用于定制某个集群/实例的 HBA 规则。


pgb_hba_rules

参数名称: pgb_hba_rules, 类型: hba[], 层次:C

Pgbouncer 业务HBA规则,默认值为: [], 空数组。

此参数与 pg_hba_rules 基本类似,都是 hba 规则对象的数组,区别在于本参数是为 Pgbouncer 准备的。

pgb_default_hba_rules 与本参数基本类似,但它是用于定义全局连接池 HBA 规则,而本参数通常用于定制某个连接池集群/实例的 HBA 规则。


pg_replication_username

参数名称: pg_replication_username, 类型: username, 层次:G

PostgreSQL 物理复制用户名,默认使用 replicator,不建议修改此参数。


pg_replication_password

参数名称: pg_replication_password, 类型: password, 层次:G

PostgreSQL 物理复制用户密码,默认值为:DBUser.Replicator

警告:请在生产环境中修改此密码!


pg_admin_username

参数名称: pg_admin_username, 类型: username, 层次:G

PostgreSQL / Pgbouncer 管理员名称,默认为:dbuser_dba

这是全局使用的数据库管理员,具有数据库的 Superuser 权限与连接池的流量管理权限,请务必控制使用范围。


pg_admin_password

参数名称: pg_admin_password, 类型: password, 层次:G

PostgreSQL / Pgbouncer 管理员密码,默认为: DBUser.DBA

警告:请在生产环境中修改此密码!


pg_monitor_username

参数名称: pg_monitor_username, 类型: username, 层次:G

PostgreSQL/Pgbouncer 监控用户名,默认为:dbuser_monitor

这是一个用于监控的数据库/连接池用户,不建议修改此用户名。

但如果您的现有数据库使用了不同的监控用户,可以在指定监控目标时使用此参数传入使用的监控用户名。


pg_monitor_password

参数名称: pg_monitor_password, 类型: password, 层次:G

PostgreSQL/Pgbouncer 监控用户使用的密码,默认为:DBUser.Monitor

请尽可能不要在密码中使用 @:/ 这些容易与 URL 分隔符混淆的字符,减少不必要的麻烦。

警告:请在生产环境中修改此密码!


pg_dbsu_password

参数名称: pg_dbsu_password, 类型: password, 层次:G/C

PostgreSQL pg_dbsu 超级用户密码,默认是空字符串,即不为其设置密码。

我们不建议为 dbsu 配置密码登陆,这会增大攻击面。例外情况是:pg_mode = citus,这时候需要为每个分片集群的 dbsu 配置密码,以便在分片集群内部进行连接。


PG_INSTALL

本节负责安装 PostgreSQL 及其扩展。如果您希望安装不同大版本与扩展插件,修改 pg_versionpg_extensions 即可,不过请注意,并不是所有扩展都在所有大版本可用。

pg_dbsu: postgres                 # os 数据库超级用户名称,默认为 postgres,最好不要更改
pg_dbsu_uid: 26                   # os 数据库超级用户 uid 和 gid,默认为 26,适用于默认的 postgres 用户和组
pg_dbsu_sudo: limit               # 数据库超级用户 sudo 权限,可选 none,limit,all,nopass。默认为 limit
pg_dbsu_home: /var/lib/pgsql      # postgresql 主目录,默认为 `/var/lib/pgsql`
pg_dbsu_ssh_exchange: true        # 是否在相同的 pgsql 集群中交换 postgres 数据库超级用户的 ssh 密钥
pg_version: 18                    # 要安装的 postgres 主版本,默认为 18
pg_bin_dir: /usr/pgsql/bin        # postgres 二进制目录,默认为 `/usr/pgsql/bin`
pg_log_dir: /pg/log/postgres      # postgres 日志目录,默认为 `/pg/log/postgres`
pg_packages:                      # 待安装的软件包列表,可以使用别名
  - pgsql-main pgsql-common
pg_extensions: []                 # 待安装的扩展列表,可以使用别名

pg_dbsu

参数名称: pg_dbsu, 类型: username, 层次:C

PostgreSQL 使用的操作系统 dbsu 用户名, 默认为 postgres,改这个用户名是不太明智的。

不过在特定情况下,您可能会使用到不同于 postgres 的用户名,例如在安装配置 Greenplum / MatrixDB 时,需要使用 gpadmin / mxadmin 作为相应的操作系统超级用户。


pg_dbsu_uid

参数名称: pg_dbsu_uid, 类型: int, 层次:C

操作系统数据库超级用户的 uid 和 gid,26 是 PGDG RPM 默认的 postgres 用户 UID/GID。

对于 Debian/Ubuntu 系统,没有默认值,且 26 号用户经常被占用。因此Pigsty 在检测到安装环境为 Debian 系,且 uid 为 26 时,会自动使用替换的 pg_dbsu_uid = 543


pg_dbsu_sudo

参数名称: pg_dbsu_sudo, 类型: enum, 层次:C

数据库超级用户的 sudo 权限,可以是 nonelimitallnopass。默认为 limit

  • none: 无 Sudo 权限
  • limit: 有限的 sudo 权限,用于执行与数据库相关的组件的 systemctl 命令(默认选项)。
  • all: 完全的 sudo 权限,需要密码。
  • nopass: 不需要密码的完全 sudo 权限(不推荐)。
  • 默认值为 limit,只允许执行 sudo systemctl <start|stop|reload> <postgres|patroni|pgbouncer|...>

可以使用 sudo 管理的服务列表:

  • patroni
  • pgbouncer
  • postgres
  • pg_exporter
  • pgbackrest
  • pgbouncer_exporter
  • pgbackrest_exporter
  • vip-manager
  • haproxy (仅限reload)

pg_dbsu_home

参数名称: pg_dbsu_home, 类型: path, 层次:C

postgresql 主目录,默认为 /var/lib/pgsql,与官方的 pgdg RPM 保持一致。


pg_dbsu_ssh_exchange

参数名称: pg_dbsu_ssh_exchange, 类型: bool, 层次:C

是否在交换操作系统 dbsu 用户的 ssh 密钥?

默认值为 true,意味着数据库超级用户可以互相 ssh 访问。

对于严格限制 ssh 访问的场景,您可以将其设置为 false

请注意,SSH 密钥交换发生在同时执行剧本的实例之间,如果您针对一个 PostgreSQL 集群运行 pgsql 角色,密钥交换将发生在这个集群中的所有实例之间。 如果您针对所有 PostgreSQL 集群运行 pgsql 角色,密钥交换将发生在 所有 实例之间,对于大规模集群,O(n2) 复杂度交换可能导致严重的组合爆炸。 如果任何参与交换的实例没有 pg_dbsu 用户,与该实例相关的密钥交换将失败,但不影响其他实例的密钥交换。


pg_version

参数名称: pg_version, 类型: enum, 层次:C

要安装的 postgres 主版本,默认为 18

请注意,PostgreSQL 的物理流复制不能跨主要版本,因此最好不要在实例级别上配置此项。

您可以使用 pg_packagespg_extensions 中的参数来为特定的 PG 大版本安装不同的软件包与扩展。


pg_bin_dir

参数名称: pg_bin_dir, 类型: path, 层次:C

PostgreSQL 二进制程序目录,默认为 /usr/pgsql/bin

默认值是在安装过程中手动创建的软链接,指向安装的特定的 Postgres 版本目录。

例如 /usr/pgsql -> /usr/pgsql-17。在 Ubuntu/Debian 上则指向 /usr/lib/postgresql/15/bin

更多详细信息,请查看 PGSQL 文件结构


pg_log_dir

参数名称: pg_log_dir, 类型: path, 层次:C

PostgreSQL 日志目录,默认为:/pg/log/postgresPromtail 会使用此变量收集 PostgreSQL 日志。

请注意,如果日志目录 pg_log_dir 以数据库目录 pg_data 作为前缀,则不会显式创建(数据库目录初始化时自动创建)。


pg_packages

参数名称: pg_packages, 类型: string[], 层次:C

要安装的 PostgreSQL 软件包(rpm/deb),这是一个由软件包名组成的数组,每个元素都是逗号或空格分割的 PG 软件包名或别名(Alias)。

默认值为:[ pgsql-main pgsql-common ]

这里的默认值是两个别名,分通过 别名翻译 为当前 PG 大版本对应的主要 RPM/DEB 包名,以及 PG 版本无关的通用组件(例如 Patroni,PgBackrest 等)

从 Pigsty v3 开始,您可以在本参数中使用roles/node_id/vars 中系统对应配置指定的别名列表。

使用包别名的好处是,您无需操心 PostgreSQL 相关软件包在不同系统平台上的包名,架构,以及大版本号,从而屏蔽了不同 OS 之间的区别:

定义在这里的软件包会首先经过 package_map 的翻译,然后经过 PG 大版本号的替换,最后安装实际的 RPM/DEB 包。

您也可以直接指定最终安装的 RPM/DEB 包名称,包名中的 ${pg_version}$v 版本号占位符将被替换为具体的大版本号 pg_version


pg_extensions

参数名称: pg_extensions, 类型: string[], 层次:G/C

要安装的 PostgreSQL 扩展包(rpm/deb),这是一个由扩展包名组成的数组,每个元素都是逗号或空格分割的 PG 扩展包名。

本参数在形式上与 pg_packages 一致,但是通常用于指定需要安装的扩展插件,而且在这里指定的软件包会升级到可用的最新版本。

pg_extensions: []

完整可用的扩展列表,已经在 Pigsty 默认生成的配置文件中给出,用户按需使用即可。

完整列表请参考:roles/node_id/vars 与 Pigsty 扩展目录


PG_BOOTSTRAP

使用 Patroni 引导拉起 PostgreSQL 集群,并设置 1:1 对应的 Pgbouncer 连接池。

它还会使用 PG_PROVISION 中定义的默认角色、用户、权限、模式、扩展来初始化数据库集群

pg_data: /pg/data                 # postgres 数据目录,默认值为 `/pg/data`
pg_fs_main: /data/postgres        # postgres 主数据盘挂载点/路径,默认值为 `/data/postgres`
pg_fs_bkup: /data/backups         # postgres 备份数据盘挂载点/路径,默认值为 `/data/backups`
pg_storage_type: SSD              # postgres 主数据盘存储介质类型,默认值为 `SSD`
pg_dummy_filesize: 64MiB          # 紧急情况下占位符文件 `/pg/dummy` 的大小,默认值为 `64MiB`
pg_listen: '0.0.0.0'              # postgres/pgbouncer 监听地址,默认值为 `0.0.0.0`
pg_port: 5432                     # postgres 监听端口,默认值为 `5432`
pg_localhost: /var/run/postgresql # postgres 本地连接的 Unix 套接字目录,默认值为 `/var/run/postgresql`
patroni_enabled: true             # 如果禁用,在初始化期间将不会创建 postgres 集群
patroni_mode: default             # patroni 工作模式:default,pause,remove
pg_namespace: /pg                 # etcd 中的顶级键命名空间,由 patroni 和 vip 使用
patroni_port: 8008                # patroni 监听端口,默认为 8008
patroni_log_dir: /pg/log/patroni  # patroni 日志目录,默认为 `/pg/log/patroni`
patroni_ssl_enabled: false        # 是否使用 SSL 保护 patroni RestAPI 通信?
patroni_watchdog_mode: off        # patroni 看门狗模式:automatic,required,off。默认为 off
patroni_username: postgres        # patroni restapi 用户名,默认为 `postgres`
patroni_password: Patroni.API     # patroni restapi 密码,默认为 `Patroni.API`
pg_primary_db: postgres           # 主数据库名称,用于 citus 等,默认为 postgres
pg_parameters: {}                 # postgresql.auto.conf 中的额外参数
pg_files: []                      # 要复制到 postgres 数据目录的额外文件(例如许可证)
pg_conf: oltp.yml                 # 配置模板:oltp,olap,crit,tiny。默认为 `oltp.yml`
pg_max_conn: auto                 # postgres 最大连接数,`auto` 将使用推荐值
pg_shared_buffer_ratio: 0.25      # postgres 共享缓冲区比例,默认为 0.25,范围 0.1~0.4
pg_rto: 30                        # 恢复时间目标(秒),默认为 `30s`
pg_rpo: 1048576                   # 恢复点目标(字节),默认最多 `1MiB`
pg_libs: 'pg_stat_statements, auto_explain'  # 预加载库,默认为 `pg_stat_statements,auto_explain`
pg_delay: 0                       # 备用集群领导者的复制应用延迟
pg_checksum: true                 # 为 postgres 集群启用数据校验和?
pg_pwd_enc: scram-sha-256         # 密码加密算法:md5,scram-sha-256
pg_encoding: UTF8                 # 数据库集群编码,默认为 `UTF8`
pg_locale: C                      # 数据库集群区域设置,默认为 `C`
pg_lc_collate: C                  # 数据库集群排序规则,默认为 `C`
pg_lc_ctype: C                    # 数据库字符类型,默认为 `C`
#pgsodium_key: ""                 # pgsodium key, 64 hex digits, default to sha256(pg_cluster)
#pgsodium_getkey_script: ""       # pgsodium getkey script path, pgsodium_getkey by default

pg_data

参数名称: pg_data, 类型: path, 层次:C

Postgres 数据目录,默认为 /pg/data

这是一个指向底层实际数据目录的符号链接,在多处被使用,请不要修改它。参阅 PGSQL文件结构 获取详细信息。


pg_fs_main

参数名称: pg_fs_main, 类型: path, 层次:C

PostgreSQL 主数据盘的挂载点/文件系统路径,默认为/data/postgres

默认值:/data/postgres,它将被用作 PostgreSQL 主数据目录。

建议使用 NVME SSD 作为 PostgreSQL 主数据存储,Pigsty默认为SSD存储进行了优化,但是也支持HDD。

您可以更改pg_storage_typeHDD以针对HDD存储进行优化。


pg_fs_bkup

参数名称: pg_fs_bkup, 类型: path, 层次:C

PostgreSQL 备份数据盘的挂载点/文件系统路径,默认为/data/backup

如果您使用的是默认的 pgbackrest_method = local,建议为备份存储使用一个单独的磁盘。

备份磁盘应足够大,以容纳所有的备份,至少足以容纳3个基础备份+2天的WAL归档。 通常容量不是什么大问题,因为您可以使用便宜且大的机械硬盘作为备份盘。

建议为备份存储使用一个单独的磁盘,否则 Pigsty 将回退到主数据磁盘,并占用主数据盘的容量与IO。


pg_storage_type

参数名称: pg_storage_type, 类型: enum, 层次:C

PostgreSQL 数据存储介质的类型:SSDHDD,默认为SSD

默认值:SSD,它会影响一些调优参数,如 random_page_costeffective_io_concurrency


pg_dummy_filesize

参数名称: pg_dummy_filesize, 类型: size, 层次:C

/pg/dummy的大小,默认值为64MiB,用于紧急使用的64MB磁盘空间。

当磁盘已满时,删除占位符文件可以为紧急使用释放一些空间,建议生产使用至少8GiB


pg_listen

参数名称: pg_listen, 类型: ip, 层次:C

PostgreSQL / Pgbouncer 的监听地址,默认为0.0.0.0(所有ipv4地址)。

您可以在此变量中使用占位符,例如:'${ip},${lo}''${ip},${vip},${lo}'

  • ${ip}:转换为 inventory_hostname,它是配置清单中定义的首要内网IP地址。
  • ${vip}:如果启用了pg_vip_enabled,将使用pg_vip_address的主机部分。
  • ${lo}:将替换为127.0.0.1

对于高安全性要求的生产环境,建议限制监听的IP地址。


pg_port

参数名称: pg_port, 类型: port, 层次:C

PostgreSQL 服务器监听的端口,默认为 5432


pg_localhost

参数名称: pg_localhost, 类型: path, 层次:C

本地主机连接 PostgreSQL 使用的 Unix套接字目录,默认值为/var/run/postgresql

PostgreSQL 和 Pgbouncer 本地连接的Unix套接字目录,pg_exporter 和 patroni 都会优先使用 Unix 套接字访问 PostgreSQL。


pg_namespace

参数名称: pg_namespace, 类型: path, 层次:C

etcd 中使用的顶级命名空间,由 patroni 和 vip-manager 使用,默认值是:/pg,不建议更改。


patroni_enabled

参数名称: patroni_enabled, 类型: bool, 层次:C

是否启用 Patroni ?默认值为:true

如果禁用,则在初始化期间不会创建Postgres集群。Pigsty将跳过拉起 patroni的任务,当试图向现有的postgres实例添加一些组件时,可以使用此参数。


patroni_mode

参数名称: patroni_mode, 类型: enum, 层次:C

Patroni 工作模式:defaultpauseremove。默认值:default

  • default:正常使用 Patroni 引导 PostgreSQL 集群
  • pause:与default相似,但在引导后进入维护模式
  • remove:使用Patroni初始化集群,然后删除Patroni并使用原始 PostgreSQL。

patroni_port

参数名称: patroni_port, 类型: port, 层次:C

patroni监听端口,默认为8008,不建议更改。

Patroni API服务器在此端口上监听健康检查和API请求。


patroni_log_dir

参数名称: patroni_log_dir, 类型: path, 层次:C

patroni日志目录,默认为/pg/log/patroni,由promtail收集。


patroni_ssl_enabled

参数名称: patroni_ssl_enabled, 类型: bool, 层次:G

使用SSL保护patroni RestAPI通信吗?默认值为false

此参数是一个全局标志,只能在部署之前预先设置。因为如果为 patroni 启用了SSL,您将必须使用 HTTPS 而不是 HTTP 执行健康检查、获取指标,调用API。


patroni_watchdog_mode

参数名称: patroni_watchdog_mode, 类型: string, 层次:C

patroni看门狗模式:automaticrequiredoff,默认值为 off

在主库故障的情况下,Patroni 可以使用看门狗 来强制关机旧主库节点以避免脑裂。

  • off:不使用看门狗。完全不进行 Fencing (默认行为)
  • automatic:如果内核启用了softdog模块并且看门狗属于dbsu,则启用 watchdog
  • required:强制启用 watchdog,如果softdog不可用则拒绝启动 Patroni/PostgreSQL。

默认值为off,您不应该在 Infra节点 启用看门狗,数据一致性优先于可用性的关键系统,特别是与钱有关的业务集群可以考虑打开此选项。

请注意,如果您的所有访问流量都使用 HAproxy 健康检查服务接入,正常是不存在脑裂风险的。


patroni_username

参数名称: patroni_username, 类型: username, 层次:C

Patroni REST API 用户名,默认为postgres,与patroni_password 配对使用。

Patroni的危险 REST API (比如重启集群)由额外的用户名/密码保护,查看配置集群Patroni RESTAPI以获取详细信息。


patroni_password

参数名称: patroni_password, 类型: password, 层次:C

Patroni REST API 密码,默认为Patroni.API

警告:务必生产环境中修改此参数!


pg_primary_db

参数名称: pg_primary_db, 类型: string, 层次:C

指定集群中的主数据库名称,用于 citus 等业务数据库,默认为 postgres

例如,在使用 Patroni 管理高可用的 Citus 集群时,您必须选择一个 “主数据库”。

此外,在这里指定的数据库名称,将在 PGSQL 模块安装完成后,显示在打印的连接串中。


pg_parameters

参数名称: pg_parameters, 类型: dict, 层次:G/C/I

可用于指定并管理 postgresql.auto.conf 中的配置参数。

当集群所有实例完成初始化后,pg_param 任务将会把本字典中的 key / value 键值对依次覆盖写入 /pg/data/postgresql.auto.conf 中。

注意:请不要手工修改该配置文件,或通过 ALTER SYSTEM 修改集群配置参数,修改会在下一次配置同步时被覆盖。

该变量的优先级大于 Patroni / DCS 中的集群配置(即优先级高于集群配置,由 Patroni edit-config 编辑的配置),因此通常可以在实例级别覆盖集群默认参数。

当您的集群成员有着不同的规格(不推荐的行为!)时,您可以通过本参数对每个实例的配置进行精细化管理。

pg-test:
  hosts:
    10.10.10.11: { pg_seq: 1, pg_role: primary , pg_parameters: { shared_buffers: '5GB' } }
    10.10.10.12: { pg_seq: 2, pg_role: replica , pg_parameters: { shared_buffers: '4GB' } }
    10.10.10.13: { pg_seq: 3, pg_role: replica , pg_parameters: { shared_buffers: '3GB' } }

请注意,一些 重要的集群参数(对主从库参数值有要求)是 Patroni 直接通过命令行参数管理的,具有最高优先级,无法通过此方式覆盖,对于这些参数,您必须使用 Patroni edit-config 进行管理与配置。

在主从上必须保持一致的 PostgreSQL 参数(不一致会导致从库无法启动!):

  • wal_level
  • max_connections
  • max_locks_per_transaction
  • max_worker_processes
  • max_prepared_transactions
  • track_commit_timestamp

在主从上最好保持一致的参数(考虑到主从切换的可能性):

  • listen_addresses
  • port
  • cluster_name
  • hot_standby
  • wal_log_hints
  • max_wal_senders
  • max_replication_slots
  • wal_keep_segments
  • wal_keep_size

您可以设置不存在的参数(例如来自扩展的 GUC,从而配置 ALTER SYSTEM 无法修改的“尚未存在”的参数),但将现有配置修改为非法值可能会导致 PostgreSQL 无法启动,请谨慎配置!


pg_files

参数名称: pg_files, 类型: path[], 层次:C

用于指定需要拷贝至PGDATA目录的文件列表,默认为空数组:[]

在本参数中指定的文件将会被拷贝至 {{ pg_data }} 目录下,这主要用于下发特殊商业版本 PostgreSQL 内核要求的 License 文件。

目前仅有 PolarDB (Oracle兼容)内核需要许可证文件,例如,您可以将 license.lic 文件放置在 files/ 目录下,并在 pg_files 中指定:

pg_files: [ license.lic ]

pg_conf

参数名称: pg_conf, 类型: enum, 层次:C

配置模板:{oltp,olap,crit,tiny}.yml,默认为oltp.yml

  • tiny.yml:为小节点、虚拟机、小型演示优化(1-8核,1-16GB)
  • oltp.yml:为OLTP工作负载和延迟敏感应用优化(4C8GB+)(默认模板)
  • olap.yml:为OLAP工作负载和吞吐量优化(4C8G+)
  • crit.yml:为数据一致性和关键应用优化(4C8G+)

默认值:oltp.yml,但是配置程序将在当前节点为小节点时将此值设置为 tiny.yml

您可以拥有自己的模板,只需将其放在templates/<mode>.yml下,并将此值设置为模板名称即可使用。


pg_max_conn

参数名称: pg_max_conn, 类型: int, 层次:C

PostgreSQL 服务器最大连接数。你可以选择一个介于 50 到 5000 之间的值,或使用 auto 选择推荐值。

默认值为 auto,会根据 pg_confpg_default_service_dest 来设定最大连接数。

  • tiny: 250
  • olap: 500
  • crit: 500 (pgbouncer) / 1000 (postgres)
  • oltp: 500 (pgbouncer) / 1000 (postgres)

不建议将此值设定为超过 5000,否则你还需要手动增加 haproxy 服务的连接限制。

Pgbouncer 的事务池可以缓解过多的 OLTP 连接问题,因此默认情况下不建议设置很大的连接数。

对于 OLAP 场景, pg_default_service_dest 修改为 postgres 可以绕过连接池。


pg_shared_buffer_ratio

参数名称: pg_shared_buffer_ratio, 类型: float, 层次:C

Postgres 共享缓冲区内存比例,默认为 0.25,正常范围在 0.1~0.4 之间。

默认值:0.25,意味着节点内存的 25% 将被用作 PostgreSQL 的分片缓冲区。如果您想为 PostgreSQL 启用大页,那么此参数值应当适当小于 node_hugepage_ratio

将此值设定为大于 0.4(40%)通常不是好主意,但在极端情况下可能有用。

注意,共享缓冲区只是 PostgreSQL 中共享内存的一部分,要计算总共享内存,使用 show shared_memory_size_in_huge_pages;


pg_rto

参数名称: pg_rto, 类型: int, 层次:C

以秒为单位的恢复时间目标(RTO)。这将用于计算 Patroni 的 TTL 值,默认为 30 秒。

如果主实例在这么长时间内失踪,将触发新的领导者选举,此值并非越低越好,它涉及到利弊权衡:

减小这个值可以减少集群故障转移期间的不可用时间(无法写入), 但会使集群对短期网络抖动更加敏感,从而增加误报触发故障转移的几率。

您需要根据网络状况和业务约束来配置这个值,在故障几率和故障影响之间做出权衡, 默认值是 30s,它将影响以下的 Patroni 参数:

# 获取领导者租约的 TTL(以秒为单位)。将其视为启动自动故障转移过程之前的时间长度。默认值:30
ttl: {{ pg_rto }}

# 循环将休眠的秒数。默认值:10,这是 patroni 检查循环间隔
loop_wait: {{ (pg_rto / 3)|round(0, 'ceil')|int }}

# DCS 和 PostgreSQL 操作重试的超时时间(以秒为单位)。比这短的 DCS 或网络问题不会导致 Patroni 降级领导。默认值:10
retry_timeout: {{ (pg_rto / 3)|round(0, 'ceil')|int }}

# 主实例在触发故障转移之前允许从故障中恢复的时间(以秒为单位),最大 RTO:2 倍循环等待 + primary_start_timeout
primary_start_timeout: {{ (pg_rto / 3)|round(0, 'ceil')|int }}

pg_rpo

参数名称: pg_rpo, 类型: int, 层次:C

以字节为单位的恢复点目标(RPO),默认值:1048576

默认为 1MiB,这意味着在故障转移期间最多可以容忍 1MiB 的数据丢失。

当主节点宕机并且所有副本都滞后时,你必须做出一个艰难的选择,在可用性和一致性之间进行权衡

  • 提升一个从库成为新的主库,并尽快将系统恢复服务,但要付出可接受的数据丢失代价(例如,少于 1MB)。
  • 等待主库重新上线(可能永远不会),或人工干预以避免任何数据丢失。

你可以使用 crit.yml conf 模板来确保在故障转移期间没有数据丢失,但这会牺牲一些性能。


pg_libs

参数名称: pg_libs, 类型: string, 层次:C

预加载的动态共享库,默认为 pg_stat_statements,auto_explain,这是两个 PostgreSQL 自带的扩展,强烈建议启用。

对于现有集群,您可以直接配置集群shared_preload_libraries 参数并应用生效。

如果您想使用 TimescaleDB 或 Citus 扩展,您需要将 timescaledbcitus 添加到此列表中。timescaledbcitus 应当放在这个列表的最前面,例如:

citus,timescaledb,pg_stat_statements,auto_explain

其他需要动态加载的扩展也可以添加到这个列表中,例如 pg_cronpgml 等,通常 citustimescaledb 有着最高的优先级,应该添加到列表的最前面。


pg_delay

参数名称: pg_delay, 类型: interval, 层次:I

延迟备库复制延迟,默认值:0

如果此值被设置为一个正值,备用集群主库在应用 WAL 变更之前将被延迟这个时间。设置为 1h 意味着该集群中的数据将始终滞后原集群一个小时。

查看 延迟备用集群 以获取详细信息。


pg_checksum

参数名称: pg_checksum, 类型: bool, 层次:C

为 PostgreSQL 集群启用数据校验和吗?v3.7.0 默认值是 true

这个参数只能在 PGSQL 部署之前设置(但你可以稍后手动启用它)。

如果使用 pg_conf crit.yml 模板,无论此参数如何,都会始终启用数据校验和,以确保数据完整性。


pg_pwd_enc

参数名称: pg_pwd_enc, 类型: enum, 层次:C

密码加密算法:md5scram-sha-256,默认值:scram-sha-256

前者已经不再安全,如果你与旧客户端有兼容性问题,你可以将其设置为 md5


pg_encoding

参数名称: pg_encoding, 类型: enum, 层次:C

数据库集群编码,默认为 UTF8

除非你非常清楚自己在做什么,否则不建议使用其他非 UTF8 的编码。


pg_locale

参数名称: pg_locale, 类型: enum, 层次:C

PostgreSQL 使用的本地化规则集,默认为 C。会在数据库初始化时作为参数传递给 initdb 命令。

configure 检测到当前 PG 版本大于等于 17,或者当前系统明确支持 C.utf8 时,会自动配置此参数为 C.UTF-8

当 PostgreSQL 版本大于等于 17 时, CC.UTF-8 配置将使用 PostgreSQL 内部自带的 Locale Providier。

除非你非常清楚自己在做什么,否则强烈建议您使用默认的 CC.UTF-8 配置。

通常应当与 pg_lc_collatepg_lc_ctype 配置保持一致。


pg_lc_collate

参数名称: pg_lc_collate, 类型: enum, 层次:C

PostgreSQL 使用的本地化排序规则集,默认为 C,一旦确定,无法在集群层面修改。

configure 检测到当前 PG 版本大于等于 17,或者当前系统明确支持 C.utf8 时,会自动配置此参数为 C.UTF-8

配置规则与 pg_locale 一致,但针对排序规则。


pg_lc_ctype

参数名称: pg_lc_ctype, 类型: enum, 层次:C

PostgreSQL 使用的本地化字符集定义 CTYPE,默认为 C,一旦确定,无法在集群层面修改。

configure 检测到当前 PG 版本大于等于 17,或者当前系统明确支持 C.utf8 时,会自动配置此参数为 C.UTF-8

配置规则与 pg_locale 一致,但针对字符类型。


pgsodium_key

参数名称: pgsodium_key, 类型: string, 层次:C

默认值未定义,将使用 pg_cluster 的 SHA256 哈希值作为密钥。

你可以提供自定义的 pgsodium 密钥,应该是 64 位十六进制数字字符串。

密钥将被写入 /pg/conf/pgsodium.key


pgsodium_getkey_script

参数名称: pgsodium_getkey_script, 类型: path, 层次:C

默认值为 pgsodium_getkey,它将 roles/pgsql/templates/pgsodium_getkey 渲染到 /pg/bin/pgsodium_getkey

默认的 getkey 脚本只是从 /pg/conf/pgsodium.key 读取 pgsodium_key 并返回它。 如果你的密钥由外部系统(如 KMS、IAM 等)管理,你可以实现自己的 getkey 脚本从那里获取密钥:示例


PG_PROVISION

如果说 PG_BOOTSTRAP 是创建一个新的集群,那么 PG_PROVISION 就是在集群中创建默认的对象,包括:

pg_provision: true                # provision postgres cluster after bootstrap
pg_init: pg-init                  # provision init script for cluster template, `pg-init` by default
pg_default_roles:                 # default roles and users in postgres cluster
  - { 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 ,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, dbrole_readonly] ,pgbouncer: true ,parameters: {log_min_duration_statement: 1000 } ,pool_mode: session ,pool_connlimit: 8 ,comment: pgsql monitor user }
pg_default_privileges:            # 管理员用户创建时的默认权限
  - GRANT USAGE      ON SCHEMAS   TO dbrole_readonly
  - GRANT SELECT     ON TABLES    TO dbrole_readonly
  - GRANT SELECT     ON SEQUENCES TO dbrole_readonly
  - GRANT EXECUTE    ON FUNCTIONS TO dbrole_readonly
  - GRANT USAGE      ON SCHEMAS   TO dbrole_offline
  - GRANT SELECT     ON TABLES    TO dbrole_offline
  - GRANT SELECT     ON SEQUENCES TO dbrole_offline
  - GRANT EXECUTE    ON FUNCTIONS TO dbrole_offline
  - GRANT INSERT     ON TABLES    TO dbrole_readwrite
  - GRANT UPDATE     ON TABLES    TO dbrole_readwrite
  - GRANT DELETE     ON TABLES    TO dbrole_readwrite
  - GRANT USAGE      ON SEQUENCES TO dbrole_readwrite
  - GRANT UPDATE     ON SEQUENCES TO dbrole_readwrite
  - GRANT TRUNCATE   ON TABLES    TO dbrole_admin
  - GRANT REFERENCES ON TABLES    TO dbrole_admin
  - GRANT TRIGGER    ON TABLES    TO dbrole_admin
  - GRANT CREATE     ON SCHEMAS   TO dbrole_admin
pg_default_schemas: [ monitor ]   # 默认模式
pg_default_extensions:            # 默认扩展
  - { name: pg_stat_statements ,schema: monitor }
  - { name: pgstattuple        ,schema: monitor }
  - { name: pg_buffercache     ,schema: monitor }
  - { name: pageinspect        ,schema: monitor }
  - { name: pg_prewarm         ,schema: monitor }
  - { name: pg_visibility      ,schema: monitor }
  - { name: pg_freespacemap    ,schema: monitor }
  - { name: postgres_fdw       ,schema: public  }
  - { name: file_fdw           ,schema: public  }
  - { name: btree_gist         ,schema: public  }
  - { name: btree_gin          ,schema: public  }
  - { name: pg_trgm            ,schema: public  }
  - { name: intagg             ,schema: public  }
  - { name: intarray           ,schema: public  }
  - { name: pg_repack }
pg_reload: true                   # HBA变化后是否重载配置?
pg_default_hba_rules:             # postgres 默认 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: '+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'}
pgb_default_hba_rules:            # pgbouncer 默认 HBA 规则集
  - {user: '${dbsu}'    ,db: pgbouncer   ,addr: local     ,auth: peer  ,title: 'dbsu local admin access with os ident'}
  - {user: 'all'        ,db: all         ,addr: localhost ,auth: pwd   ,title: 'allow all user local access with pwd' }
  - {user: '${monitor}' ,db: pgbouncer   ,addr: intra     ,auth: pwd   ,title: 'monitor access via intranet with pwd' }
  - {user: '${monitor}' ,db: all         ,addr: world     ,auth: deny  ,title: 'reject all other monitor access addr' }
  - {user: '${admin}'   ,db: all         ,addr: intra     ,auth: pwd   ,title: 'admin access via intranet with pwd'   }
  - {user: '${admin}'   ,db: all         ,addr: world     ,auth: deny  ,title: 'reject all other admin access addr'   }
  - {user: 'all'        ,db: all         ,addr: intra     ,auth: pwd   ,title: 'allow all user intra access with pwd' }

pg_provision

参数名称: pg_provision, 类型: bool, 层次:C

在集群拉起后,完整本节定义的 PostgreSQL 集群置备工作。默认值为true

如果禁用,不会置备 PostgreSQL 集群。对于一些特殊的 “PostgreSQL” 集群,比如 Greenplum,可以关闭此选项跳过置备阶段。


pg_init

参数名称: pg_init, 类型: string, 层次:G/C

用于初始化数据库模板的Shell脚本位置,默认为 pg-init,该脚本会被拷贝至/pg/bin/pg-init后执行。

该脚本位于 roles/pgsql/templates/pg-init

你可以在该脚本中添加自己的逻辑,或者提供一个新的脚本放置在 templates/ 目录下,并将 pg_init 设置为新的脚本名称。使用自定义脚本时请保留现有的初始化逻辑。


pg_default_roles

参数名称: pg_default_roles, 类型: role[], 层次:G/C

Postgres 集群中的默认角色和用户。

Pigsty有一个内置的角色系统,请查看PGSQL访问控制:角色系统了解详情。

pg_default_roles:                 # default roles and users in postgres cluster
  - { 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 ,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, dbrole_readonly] ,pgbouncer: true ,parameters: {log_min_duration_statement: 1000 } ,pool_mode: session ,pool_connlimit: 8 ,comment: pgsql monitor user }

pg_default_privileges

参数名称: pg_default_privileges, 类型: string[], 层次:G/C

每个数据库中的默认权限(DEFAULT PRIVILEGE)设置:

pg_default_privileges:            # 管理员用户创建时的默认权限
  - GRANT USAGE      ON SCHEMAS   TO dbrole_readonly
  - GRANT SELECT     ON TABLES    TO dbrole_readonly
  - GRANT SELECT     ON SEQUENCES TO dbrole_readonly
  - GRANT EXECUTE    ON FUNCTIONS TO dbrole_readonly
  - GRANT USAGE      ON SCHEMAS   TO dbrole_offline
  - GRANT SELECT     ON TABLES    TO dbrole_offline
  - GRANT SELECT     ON SEQUENCES TO dbrole_offline
  - GRANT EXECUTE    ON FUNCTIONS TO dbrole_offline
  - GRANT INSERT     ON TABLES    TO dbrole_readwrite
  - GRANT UPDATE     ON TABLES    TO dbrole_readwrite
  - GRANT DELETE     ON TABLES    TO dbrole_readwrite
  - GRANT USAGE      ON SEQUENCES TO dbrole_readwrite
  - GRANT UPDATE     ON SEQUENCES TO dbrole_readwrite
  - GRANT TRUNCATE   ON TABLES    TO dbrole_admin
  - GRANT REFERENCES ON TABLES    TO dbrole_admin
  - GRANT TRIGGER    ON TABLES    TO dbrole_admin
  - GRANT CREATE     ON SCHEMAS   TO dbrole_admin

Pigsty 基于默认角色系统提供了相应的默认权限设置,请查看PGSQL访问控制:权限了解详情。


pg_default_schemas

参数名称: pg_default_schemas, 类型: string[], 层次:G/C

要创建的默认模式,默认值为:[ monitor ],这将在所有数据库上创建一个monitor模式,用于放置各种监控扩展、表、视图、函数。


pg_default_extensions

参数名称: pg_default_extensions, 类型: extension[], 层次:G/C

要在所有数据库中默认创建启用的扩展列表,默认值:

pg_default_extensions: # default extensions to be created
  - { name: pg_stat_statements ,schema: monitor }
  - { name: pgstattuple        ,schema: monitor }
  - { name: pg_buffercache     ,schema: monitor }
  - { name: pageinspect        ,schema: monitor }
  - { name: pg_prewarm         ,schema: monitor }
  - { name: pg_visibility      ,schema: monitor }
  - { name: pg_freespacemap    ,schema: monitor }
  - { name: postgres_fdw       ,schema: public  }
  - { name: file_fdw           ,schema: public  }
  - { name: btree_gist         ,schema: public  }
  - { name: btree_gin          ,schema: public  }
  - { name: pg_trgm            ,schema: public  }
  - { name: intagg             ,schema: public  }
  - { name: intarray           ,schema: public  }
  - { name: pg_repack }

唯一的三方扩展是 pg_repack,这对于数据库维护很重要,所有其他扩展都是内置的 PostgreSQL Contrib 扩展插件。

监控相关的扩展默认安装在 monitor 模式中,该模式由pg_default_schemas创建。


pg_reload

参数名称: pg_reload, 类型: bool, 层次:A

在hba更改后重新加载 PostgreSQL,默认值为true

当您想在应用HBA更改之前进行检查时,将其设置为false以禁用自动重新加载配置。


pg_default_hba_rules

参数名称: pg_default_hba_rules, 类型: hba[], 层次:G/C

PostgreSQL 基于主机的认证规则,全局默认规则定义。默认值为:

pg_default_hba_rules:             # postgres default host-based authentication rules
  - {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: '+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'}

默认值为常见场景提供了足够的安全级别,请查看PGSQL身份验证了解详情。

本参数为 HBA规则对象组成的数组,在形式上与 pg_hba_rules 完全一致。 建议在全局配置统一的 pg_default_hba_rules,针对特定集群使用 pg_hba_rules 进行额外定制。两个参数中的规则都会依次应用,后者优先级更高。


pgb_default_hba_rules

参数名称: pgb_default_hba_rules, 类型: hba[], 层次:G/C

Pgbouncer 默认的基于主机的认证规则,数组或 hba 规则对象。

默认值提供了一套对于常见场景足够的安全级别,查看 PGSQL Authentication 了解详情。

pgb_default_hba_rules:            # pgbouncer default host-based authentication rules
  - {user: '${dbsu}'    ,db: pgbouncer   ,addr: local     ,auth: peer  ,title: 'dbsu local admin access with os ident'}
  - {user: 'all'        ,db: all         ,addr: localhost ,auth: pwd   ,title: 'allow all user local access with pwd' }
  - {user: '${monitor}' ,db: pgbouncer   ,addr: intra     ,auth: pwd   ,title: 'monitor access via intranet with pwd' }
  - {user: '${monitor}' ,db: all         ,addr: world     ,auth: deny  ,title: 'reject all other monitor access addr' }
  - {user: '${admin}'   ,db: all         ,addr: intra     ,auth: pwd   ,title: 'admin access via intranet with pwd'   }
  - {user: '${admin}'   ,db: all         ,addr: world     ,auth: deny  ,title: 'reject all other admin access addr'   }
  - {user: 'all'        ,db: all         ,addr: intra     ,auth: pwd   ,title: 'allow all user intra access with pwd' }

默认的Pgbouncer HBA规则很简单:

  1. 允许从本地使用密码登陆
  2. 允许从内网网断使用密码登陆

用户可以按照自己的需求进行定制。

本参数在形式上与 pgb_hba_rules 完全一致,建议在全局配置统一的 pgb_default_hba_rules,针对特定集群使用 pgb_hba_rules 进行额外定制。两个参数中的规则都会依次应用,后者优先级更高。


PG_BACKUP

本节定义了用于 pgBackRest 的变量,它被用于 PGSQL 时间点恢复 PITR 。

查看 PGSQL 备份 & PITR 以获取详细信息。

pgbackrest_enabled: true          # 在 pgsql 主机上启用 pgBackRest 吗?
pgbackrest_clean: true            # 初始化时删除 pg 备份数据?
pgbackrest_log_dir: /pg/log/pgbackrest # pgbackrest 日志目录,默认为 `/pg/log/pgbackrest`
pgbackrest_method: local          # pgbackrest 仓库方法:local, minio, [用户定义...]
pgbackrest_repo:                  # pgbackrest 仓库:https://pgbackrest.org/configuration.html#section-repository
  local:                          # 默认使用本地 posix 文件系统的 pgbackrest 仓库
    path: /pg/backup              # 本地备份目录,默认为 `/pg/backup`
    retention_full_type: count    # 按计数保留完整备份
    retention_full: 2             # 使用本地文件系统仓库时,最多保留 3 个完整备份,至少保留 2 个
  minio:                          # pgbackrest 的可选 minio 仓库
    type: s3                      # minio 是与 s3 兼容的,所以使用 s3
    s3_endpoint: sss.pigsty       # minio 端点域名,默认为 `sss.pigsty`
    s3_region: us-east-1          # minio 区域,默认为 us-east-1,对 minio 无效
    s3_bucket: pgsql              # minio 桶名称,默认为 `pgsql`
    s3_key: pgbackrest            # pgbackrest 的 minio 用户访问密钥
    s3_key_secret: S3User.Backup  # pgbackrest 的 minio 用户秘密密钥
    s3_uri_style: path            # 对 minio 使用路径风格的 uri,而不是主机风格
    path: /pgbackrest             # minio 备份路径,默认为 `/pgbackrest`
    storage_port: 9000            # minio 端口,默认为 9000
    storage_ca_file: /etc/pki/ca.crt  # minio ca 文件路径,默认为 `/etc/pki/ca.crt`
    block: y                      # 启用块增量备份
    bundle: y                     # 将小文件捆绑在一起
    bundle_limit: 20MiB           # 文件捆绑限制,20MiB 用于对象存储
    bundle_size: 128MiB           # 文件捆绑目标大小,128MiB 用于对象存储
    cipher_type: aes-256-cbc      # 为远程备份仓库启用 AES 加密
    cipher_pass: pgBackRest       # AES 加密密码,默认为 'pgBackRest'
    retention_full_type: time     # 在 minio 仓库上按时间保留完整备份
    retention_full: 14            # 保留过去 14 天的完整备份

pgbackrest_enabled

参数名称: pgbackrest_enabled, 类型: bool, 层次:C

是否在 PGSQL 节点上启用 pgBackRest?默认值为: true

在使用本地文件系统备份仓库(local)时,只有集群主库才会真正启用 pgbackrest。其他实例只会初始化一个空仓库。


pgbackrest_clean

参数名称: pgbackrest_clean, 类型: bool, 层次:C

初始化时删除 PostgreSQL 备份数据吗?默认值为 true


pgbackrest_log_dir

参数名称: pgbackrest_log_dir, 类型: path, 层次:C

pgBackRest 日志目录,默认为 /pg/log/pgbackrestpromtail 日志代理会引用此参数收集日志。


pgbackrest_method

参数名称: pgbackrest_method, 类型: enum, 层次:C

pgBackRest 仓库方法:默认可选项为:localminio 或其他用户定义的方法,默认为 local

此参数用于确定用于 pgBackRest 的仓库,所有可用的仓库方法都在 pgbackrest_repo 中定义。

Pigsty 默认使用 local 备份仓库,这将在主实例的 /pg/backup 目录上创建一个备份仓库。底层存储路径由 pg_fs_bkup 指定。


pgbackrest_init_backup

name: pgbackrest_init_backup, type: bool, level: C

Take a full backup after pgBackRest is initialized? default value is true.

An initial pgbackrest backup is created after repo init if:

  • pgbackrest_init_backup is true (and pgbackrest_enabled is true of course)
  • The /etc/pgbackrest/initial.done marker file doesn’t exist (will be created after the initial backup is done).

If you don’t want to take an initial full backup at all, just set this parameter tofalse.


pgbackrest_repo

参数名称: pgbackrest_repo, 类型: dict, 层次:G/C

pgBackRest 仓库文档:https://pgbackrest.org/configuration.html#section-repository

默认值包括两种仓库方法:localminio,定义如下:

pgbackrest_repo:                  # pgbackrest 仓库:https://pgbackrest.org/configuration.html#section-repository
  local:                          # 默认使用本地 posix 文件系统的 pgbackrest 仓库
    path: /pg/backup              # 本地备份目录,默认为 `/pg/backup`
    retention_full_type: count    # 按计数保留完整备份
    retention_full: 2             # 使用本地文件系统仓库时,最多保留 3 个完整备份,至少保留 2 个
  minio:                          # pgbackrest 的可选 minio 仓库
    type: s3                      # minio 是与 s3 兼容的,所以使用 s3
    s3_endpoint: sss.pigsty       # minio 端点域名,默认为 `sss.pigsty`
    s3_region: us-east-1          # minio 区域,默认为 us-east-1,对 minio 无效
    s3_bucket: pgsql              # minio 桶名称,默认为 `pgsql`
    s3_key: pgbackrest            # pgbackrest 的 minio 用户访问密钥
    s3_key_secret: S3User.Backup  # pgbackrest 的 minio 用户秘密密钥
    s3_uri_style: path            # 对 minio 使用路径风格的 uri,而不是主机风格
    path: /pgbackrest             # minio 备份路径,默认为 `/pgbackrest`
    storage_port: 9000            # minio 端口,默认为 9000
    storage_ca_file: /etc/pki/ca.crt  # minio ca 文件路径,默认为 `/etc/pki/ca.crt`
    block: y                      # 启用块增量备份
    bundle: y                     # 将小文件捆绑在一起
    bundle_limit: 20MiB           # 文件捆绑限制,20MiB 用于对象存储
    bundle_size: 128MiB           # 文件捆绑目标大小,128MiB 用于对象存储
    cipher_type: aes-256-cbc      # 为远程备份仓库启用 AES 加密
    cipher_pass: pgBackRest       # AES 加密密码,默认为 'pgBackRest'
    retention_full_type: time     # 在 minio 仓库上按时间保留完整备份
    retention_full: 14            # 保留过去 14 天的完整备份

您可以定义新的备份仓库,例如使用 AWS S3,GCP 或其他云供应商的 S3 兼容存储服务。

在备份仓库定义参数中,你可以使用 ${pg_cluster} 变量来引用集群名称,例如作为备份路径或加密密钥的一部分。 但如果你有跨集群 PITR 的需求,则应该保持备份仓库路径与加密密钥相同。


PG_ACCESS

本节介绍如何将PostgreSQL服务暴露给外部世界,包括:

  • 使用haproxy在不同的端口上暴露不同的PostgreSQL服务
  • 使用vip-manager将可选的L2 VIP绑定到主实例
  • 在基础设施节点上使用dnsmasq注册集群/实例DNS记录
pgbouncer_enabled: true           # if disabled, pgbouncer will not be launched on pgsql host
pgbouncer_port: 6432              # pgbouncer listen port, 6432 by default
pgbouncer_log_dir: /pg/log/pgbouncer  # pgbouncer log dir, `/pg/log/pgbouncer` by default
pgbouncer_auth_query: false       # query postgres to retrieve unlisted business users?
pgbouncer_poolmode: transaction   # pooling mode: transaction,session,statement, transaction by default
pgbouncer_sslmode: disable        # pgbouncer client ssl mode, disable by default

pg_weight: 100          #INSTANCE # relative load balance weight in service, 100 by default, 0-255
pg_default_service_dest: pgbouncer # default service destination if svc.dest='default'
pg_default_services:              # postgres default service definitions
  - { name: primary ,port: 5433 ,dest: default  ,check: /primary   ,selector: "[]" }
  - { name: replica ,port: 5434 ,dest: default  ,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_vip_enabled: false             # 为pgsql主要实例启用l2 vip吗? 默认为false
pg_vip_address: 127.0.0.1/24      # `<ipv4>/<mask>`格式的vip地址,如果启用vip则需要
pg_vip_interface: eth0            # vip网络接口监听,默认为eth0
pg_dns_suffix: ''                 # pgsql dns后缀,默认为空
pg_dns_target: auto               # auto、primary、vip、none或特定的ip

pgbouncer_enabled

name: pgbouncer_enabled, type: bool, level: C

default value is true, if disabled, pgbouncer will not be launched on pgsql host


pgbouncer_port

name: pgbouncer_port, type: port, level: C

pgbouncer listen port, 6432 by default


pgbouncer_log_dir

name: pgbouncer_log_dir, type: path, level: C

pgbouncer log dir, /pg/log/pgbouncer by default, referenced by promtail the logging agent.


pgbouncer_auth_query

name: pgbouncer_auth_query, type: bool, level: C

query postgres to retrieve unlisted business users? default value is false

If enabled, pgbouncer user will be authenticated against postgres databases with SELECT username, password FROM monitor.pgbouncer_auth($1), otherwise, only the users with pgbouncer: true will be allowed to connect to pgbouncer.


pgbouncer_poolmode

name: pgbouncer_poolmode, type: enum, level: C

Pgbouncer pooling mode: transaction, session, statement, transaction by default

  • session: Session-level pooling with the best compatibility.
  • transaction: Transaction-level pooling with better performance (lots of small conns), could break some session level features such as notify/listen, etc…
  • statements: Statement-level pooling which is used for simple read-only queries.

If your application has some compatibility issues with pgbouncer, you can try to change this value to session instead.


pgbouncer_sslmode

name: pgbouncer_sslmode, type: enum, level: C

pgbouncer client ssl mode, disable by default

default values: disable, beware that this may have a huge performance impact on your pgbouncer.

  • disable: Plain TCP. If a client requests TLS, it’s ignored. Default.
  • allow: If a client requests TLS, it is used. If not, plain TCP is used. If the client presents a client certificate, it is not validated.
  • prefer: Same as allow.
  • require: Client must use TLS. If not, the client connection is rejected. If the client presents a client certificate, it is not validated.
  • verify-ca: Client must use TLS with valid client certificate.
  • verify-full: Same as verify-ca.

pgbouncer_ignore_param

name: pgbouncer_ignore_param, type: string[], level: G/C

default values: [ extra_float_digits, application_name, TimeZone, DateStyle, IntervalStyle, search_path ]

This will be used as value of ignore_startup_parameters in pgbouncer.


pg_weight

参数名称: pg_weight, 类型: int, 层次:G

服务中的相对负载均衡权重,默认为100,范围0-255。

默认值: 100。您必须在实例变量中定义它,并重载服务以生效。


pg_service_provider

参数名称: pg_service_provider, 类型: string, 层次:G/C

专用的haproxy节点组名,或默认为本地节点的空字符串。

如果指定,PostgreSQL服务将注册到专用的haproxy节点组,而不是当下的 PGSQL 集群节点。

请记住为每个服务在专用的 haproxy 节点上分配唯一的端口!

例如,如果我们在3节点的 pg-test 集群上定义以下参数:

pg_service_provider: infra       # use load balancer on group `infra`
pg_default_services:             # alloc port 10001 and 10002 for pg-test primary/replica service
  - { name: primary ,port: 10001 ,dest: postgres  ,check: /primary   ,selector: "[]" }
  - { name: replica ,port: 10002 ,dest: postgres  ,check: /read-only ,selector: "[]" , backup: "[? pg_role == `primary` || pg_role == `offline` ]" }

pg_default_service_dest

参数名称: pg_default_service_dest, 类型: enum, 层次:G/C

当定义一个服务时,如果 svc.dest='default',此参数将用作默认值。

默认值: pgbouncer,意味着 5433 读写服务和 5434 只读服务将默认将流量路由到 pgbouncer。

如果您不想使用 pgbouncer,将其设置为 postgres。流量将直接路由到 postgres。


pg_default_services

参数名称: pg_default_services, 类型: service[], 层次:G/C

postgres默认服务定义

默认值是四个默认服务定义,如PGSQL Service所述

pg_default_services:               # postgres default service definitions
  - { name: primary ,port: 5433 ,dest: default  ,check: /primary   ,selector: "[]" }
  - { name: replica ,port: 5434 ,dest: default  ,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_vip_enabled

参数名称: pg_vip_enabled, 类型: bool, 层次:C

为 PGSQL 集群启用 L2 VIP吗?默认值是false,表示不创建 L2 VIP。

启用 L2 VIP 后,会有一个 VIP 绑定在集群主实例节点上,由 vip-manager 管理,根据 etcd 中的数据进行判断。

L2 VIP只能在相同的L2网络中使用,这可能会对您的网络拓扑产生额外的限制。


pg_vip_address

参数名称: pg_vip_address, 类型: cidr4, 层次:C

如果启用vip,则需要<ipv4>/<mask>格式的vip地址。

默认值: 127.0.0.1/24。这个值由两部分组成:ipv4mask,用/分隔。


pg_vip_interface

参数名称: pg_vip_interface, 类型: string, 层次:C/I

vip network interface to listen, eth0 by default.

L2 VIP 监听的网卡接口,默认为 eth0

它应该是您节点的首要网卡名,即您在配置清单中使用的IP地址。

如果您的节点有多块名称不同的网卡,您可以在实例变量上进行覆盖:

pg-test:
    hosts:
        10.10.10.11: {pg_seq: 1, pg_role: replica ,pg_vip_interface: eth0 }
        10.10.10.12: {pg_seq: 2, pg_role: primary ,pg_vip_interface: eth1 }
        10.10.10.13: {pg_seq: 3, pg_role: replica ,pg_vip_interface: eth2 }
    vars:
      pg_vip_enabled: true          # 为这个集群启用L2 VIP,默认绑定到主实例
      pg_vip_address: 10.10.10.3/24 # L2网络CIDR: 10.10.10.0/24, vip地址: 10.10.10.3
      # pg_vip_interface: eth1      # 如果您的节点有统一的接口,您可以在这里定义它

pg_dns_suffix

参数名称: pg_dns_suffix, 类型: string, 层次:C

PostgreSQL DNS 名称后缀,默认为空字符串。

在默认情况下,PostgreQL 集群名会作为 DNS 域名注册到 Infra 节点的 dnsmasq 中对外提供解析。

您可以通过本参数指定一个域名后缀,这样会使用 {{ pg_cluster }}{{ pg_dns_suffix }} 作为集群 DNS 名称。

例如,如果您将 pg_dns_suffix 设置为 .db.vip.company.tld,那么 pg-test 的集群 DNS 名称将是 pg-test.db.vip.company.tld


pg_dns_target

参数名称: pg_dns_target, 类型: enum, 层次:C

可以是:autoprimaryvipnone或一个特定的IP地址,它将是集群DNS记录的解析目标IP地址。

默认值: auto,如果pg_vip_enabled,将绑定到pg_vip_address,否则会回退到集群主实例的 IP 地址。

  • vip:绑定到pg_vip_address
  • primary:解析为集群主实例IP地址
  • auto:如果 pg_vip_enabled,解析为 pg_vip_address,或回退到集群主实例ip地址。
  • none:不绑定到任何ip地址
  • <ipv4>:绑定到指定的IP地址

PG_EXPORTER

PG Exporter 用于监控 PostgreSQL 数据库与 Pgbouncer 连接池的状态。

pg_exporter_enabled: true              # 在 pgsql 主机上启用 pg_exporter 吗?
pg_exporter_config: pg_exporter.yml    # pg_exporter 配置文件名
pg_exporter_cache_ttls: '1,10,60,300'  # pg_exporter 收集器 ttl 阶段(秒),默认为 '1,10,60,300'
pg_exporter_port: 9630                 # pg_exporter 监听端口,默认为 9630
pg_exporter_params: 'sslmode=disable'  # pg_exporter dsn 的额外 url 参数
pg_exporter_url: ''                    # 如果指定,将覆盖自动生成的 pg dsn
pg_exporter_auto_discovery: true       # 启用自动数据库发现?默认启用
pg_exporter_exclude_database: 'template0,template1,postgres' # 在自动发现过程中不会被监控的数据库的 csv 列表
pg_exporter_include_database: ''       # 在自动发现过程中将被监控的数据库的 csv 列表
pg_exporter_connect_timeout: 200       # pg_exporter 连接超时(毫秒),默认为 200
pg_exporter_options: ''                # 覆盖 pg_exporter 的额外选项
pgbouncer_exporter_enabled: true       # 在 pgsql 主机上启用 pgbouncer_exporter 吗?
pgbouncer_exporter_port: 9631          # pgbouncer_exporter 监听端口,默认为 9631
pgbouncer_exporter_url: ''             # 如果指定,将覆盖自动生成的 pgbouncer dsn
pgbouncer_exporter_options: ''         # 覆盖 pgbouncer_exporter 的额外选项
pgbackrest_exporter_enabled: true      # 在 pgsql 主机上启用 pgbackrest_exporter 吗?
pgbackrest_exporter_port: 9854         # pgbackrest_exporter 监听端口,默认为 9854
pgbackrest_exporter_options: ''        # 覆盖 pgbackrest_exporter 的额外选项

pg_exporter_enabled

参数名称: pg_exporter_enabled, 类型: bool, 层次:C

是否在 PGSQL 节点上启用 pg_exporter?默认值为:true

PG Exporter 用于监控 PostgreSQL 数据库实例,如果不想安装 pg_exporter 可以设置为 false


pg_exporter_config

参数名称: pg_exporter_config, 类型: string, 层次:C

pg_exporter 配置文件名,PG Exporter 和 PGBouncer Exporter 都会使用这个配置文件。默认值:pg_exporter.yml

如果你想使用自定义配置文件,你可以在这里定义它。你的自定义配置文件应当放置于 files/<name>.yml

例如,当您希望监控一个远程的 PolarDB 数据库实例时,可以使用样例配置:files/polar_exporter.yml


pg_exporter_cache_ttls

参数名称: pg_exporter_cache_ttls, 类型: string, 层次:C

pg_exporter 收集器 TTL 阶梯(秒),默认为 1,10,60,300

默认值:1,10,60,300,它将为不同的度量收集器使用不同的TTL值: 1s, 10s, 60s, 300s。

PG Exporter 内置了缓存机制,避免多个 Prometheus 重复抓取对数据库产生不当影响,所有指标收集器按 TTL 分为四类:

ttl_fast: "{{ pg_exporter_cache_ttls.split(',')[0]|int }}"         # critical queries
ttl_norm: "{{ pg_exporter_cache_ttls.split(',')[1]|int }}"         # common queries
ttl_slow: "{{ pg_exporter_cache_ttls.split(',')[2]|int }}"         # slow queries (e.g table size)
ttl_slowest: "{{ pg_exporter_cache_ttls.split(',')[3]|int }}"      # ver slow queries (e.g bloat)

例如,在默认配置下,存活类指标默认最多缓存 1s,大部分普通指标会缓存 10s(应当与 prometheus_scrape_interval 相同)。 少量变化缓慢的查询会有 60s 的TTL,极个别大开销监控查询会有 300s 的TTL。


pg_exporter_port

参数名称: pg_exporter_port, 类型: port, 层次:C

pg_exporter 监听端口号,默认值为:9631


pg_exporter_params

参数名称: pg_exporter_params, 类型: string, 层次:C

pg_exporter 所使用 DSN 中额外的 URL PATH 参数。

默认值:sslmode=disable,它将禁用用于监控连接的 SSL(因为默认使用本地 unix 套接字)。


pg_exporter_url

参数名称: pg_exporter_url, 类型: pgurl, 层次:C

如果指定了本参数,将会覆盖自动生成的 PostgreSQL DSN,使用指定的 DSN 连接 PostgreSQL 。默认值为空字符串。

如果没有指定此参数,PG Exporter 默认会使用以下的连接串访问 PostgreSQL :

postgres://{{ pg_monitor_username }}:{{ pg_monitor_password }}@{{ pg_host }}:{{ pg_port }}/postgres{% if pg_exporter_params != '' %}?{{ pg_exporter_params }}{% endif %}

当您想监控一个远程的 PostgreSQL 实例时,或者需要使用不同的监控用户/密码,配置选项时,可以使用这个参数。


pg_exporter_auto_discovery

参数名称: pg_exporter_auto_discovery, 类型: bool, 层次:C

启用自动数据库发现吗? 默认启用:true

PG Exporter 默认会连接到 DSN 中指定的数据库 (默认为管理数据库 postgres) 收集全局指标,如果您希望收集所有业务数据库的指标,可以开启此选项。 PG Exporter 会自动发现目标 PostgreSQL 实例中的所有数据库,并在这些数据库中收集 库级监控指标


pg_exporter_exclude_database

参数名称: pg_exporter_exclude_database, 类型: string, 层次:C

如果启用了数据库自动发现(默认启用),在这个参数指定的列表中的数据库将不会被监控。 默认值为: template0,template1,postgres,即管理数据库 postgres 与模板数据库会被排除在自动监控的数据库之外。

作为例外,DSN 中指定的数据库不受此参数影响,例如,PG Exporter 如果连接的是 postgres 数据库,那么即使 postgres 在此列表中,也会被监控。


pg_exporter_include_database

参数名称: pg_exporter_include_database, 类型: string, 层次:C

如果启用了数据库自动发现(默认启用),在这个参数指定的列表中的数据库才会被监控。默认值为空字符串,即不启用此功能。

参数的形式是由逗号分隔的数据库名称列表,例如:db1,db2,db3

此参数相对于 pg_exporter_exclude_database 有更高的优先级,相当于白名单模式。如果您只希望监控特定的数据库,可以使用此参数。


pg_exporter_connect_timeout

参数名称: pg_exporter_connect_timeout, 类型: int, 层次:C

pg_exporter 连接超时(毫秒),默认为 200 (单位毫秒)

当 PG Exporter 尝试连接到 PostgreSQL 数据库时,最多会等待多长时间?超过这个时间,PG Exporter 将会放弃连接并报错。

默认值 200毫秒 对于绝大多数场景(例如:同可用区监控)都是足够的,但是如果您监控的远程 PostgreSQL 位于另一个大洲,您可能需要增加此值以避免连接超时。


pg_exporter_options

参数名称: pg_exporter_options, 类型: arg, 层次:C

传给 PG Exporter 的命令行参数,默认值为:"" 空字符串。

当使用空字符串时,会使用默认的命令参数:

{% if pg_exporter_port != '' %}
PG_EXPORTER_OPTS='--web.listen-address=:{{ pg_exporter_port }} {{ pg_exporter_options }}'
{% else %}
PG_EXPORTER_OPTS='--web.listen-address=:{{ pg_exporter_port }} --log.level=info'
{% endif %}

注意,请不要在本参数中覆盖 pg_exporter_port 的端口配置。


pgbouncer_exporter_enabled

参数名称: pgbouncer_exporter_enabled, 类型: bool, 层次:C

在 PGSQL 节点上,是否启用 pgbouncer_exporter ?默认值为:true


pgbouncer_exporter_port

参数名称: pgbouncer_exporter_port, 类型: port, 层次:C

pgbouncer_exporter 监听端口号,默认值为:9631


pgbouncer_exporter_url

参数名称: pgbouncer_exporter_url, 类型: pgurl, 层次:C

如果指定了本参数,将会覆盖自动生成的 pgbouncer DSN,使用指定的 DSN 连接 pgbouncer。默认值为空字符串。

如果没有指定此参数,Pgbouncer Exporter 默认会使用以下的连接串访问 Pgbouncer:

postgres://{{ pg_monitor_username }}:{{ pg_monitor_password }}@:{{ pgbouncer_port }}/pgbouncer?host={{ pg_localhost }}&sslmode=disable

当您想监控一个远程的 Pgbouncer 实例时,或者需要使用不同的监控用户/密码,配置选项时,可以使用这个参数。


pgbouncer_exporter_options

参数名称: pgbouncer_exporter_options, 类型: arg, 层次:C

传给 Pgbouncer Exporter 的命令行参数,默认值为:"" 空字符串。

当使用空字符串时,会使用默认的命令参数:

{% if pgbouncer_exporter_options != '' %}
PG_EXPORTER_OPTS='--web.listen-address=:{{ pgbouncer_exporter_port }} {{ pgbouncer_exporter_options }}'
{% else %}
PG_EXPORTER_OPTS='--web.listen-address=:{{ pgbouncer_exporter_port }} --log.level=info'
{% endif %}

注意,请不要在本参数中覆盖 pgbouncer_exporter_port 的端口配置。


pgbackrest_exporter_enabled

参数名称: pgbackrest_exporter_enabled, 类型: bool, 层次:C

在 PGSQL 节点上,是否启用 pgbackrest_exporter ?默认值为:true

如果 pgbackrest_enabledfalse,则本参数因短路无效。


pgbackrest_exporter_port

参数名称: pgbackrest_exporter_port, 类型: port, 层次:C

pgbackrest_exporter 监听端口号,默认值为:9854


pgbackrest_exporter_options

参数名称: pgbackrest_exporter_options, 类型: arg, 层次:C

传给 Pgbouncer Exporter 的命令行参数,默认值为:"" 空字符串。


PG_REMOVE

这些参数控制 pgsql-rm.yml,并与 v3.7.0 的 roles/pg_remove/defaults/main.yml 保持一致。

pg_safeguard: false               # 显式启用时中止删除
pg_rm_data: true                  # 删除 PostgreSQL 数据
pg_rm_backup: true                # 删除主实例的 pgBackRest 备份
pg_rm_pkg: true                   # 卸载 PostgreSQL 软件包

pg_safeguard

参数名称:pg_safeguard,类型:bool,层级:G/C/A

设为 true 时,pgsql-rm.yml 会在修改集群前中止。v3.7.0 默认值为 false


pg_rm_data

参数名称:pg_rm_data,类型:bool,层级:G/C/A

删除 PostgreSQL 数据,默认值为 true;设为 false 可保留数据目录。


pg_rm_backup

参数名称:pg_rm_backup,类型:bool,层级:G/C/A

删除主实例时一并删除 pgBackRest 备份仓库,默认值为 true;设为 false 可保留备份。


pg_rm_pkg

参数名称:pg_rm_pkg,类型:bool,层级:G/C/A

删除时卸载 PostgreSQL 与扩展软件包。v3.7.0 角色默认值为 true;设为 false 可保留已安装的软件包。

11.4 - 管理

数据库管理任务标准操作指南(SOP)

如何使用 Pigsty 维护现有的 PostgreSQL 集群?

以下是常见 PostgreSQL 管理任务的标准操作程序:


快捷命令

PGSQL 剧本和快捷命令:

bin/pgsql-add   <cls>                   # 创建 PostgreSQL 集群 <cls>
bin/pgsql-user  <cls> <username>        # 在集群 <cls> 上创建用户 <username>
bin/pgsql-db    <cls> <dbname>          # 在集群 <cls> 上创建数据库 <dbname>
bin/pgsql-svc   <cls> [...ip]           # 重载集群 <cls> 的 PostgreSQL 服务
bin/pgsql-hba   <cls> [...ip]           # 重载集群 <cls> 的 postgres/pgbouncer HBA 规则
bin/pgsql-add   <cls> [...ip]           # 为集群 <cls> 添加从库
bin/pgsql-rm    <cls> [...ip]           # 从集群 <cls> 移除从库
bin/pgsql-rm    <cls>                   # 移除 PostgreSQL 集群 <cls>

Patroni 管理命令和快捷方式:

pg list        <cls>                    # 打印集群信息
pg edit-config <cls>                    # 编辑集群配置
pg reload      <cls> [ins]              # 重载集群配置
pg restart     <cls> [ins]              # 重启 PostgreSQL 集群
pg reinit      <cls> [ins]              # 重新初始化集群成员
pg pause       <cls>                    # 进入维护模式(无自动故障转移)
pg resume      <cls>                    # 退出维护模式
pg switchover  <cls>                    # 在集群 <cls> 上执行主从切换
pg failover    <cls>                    # 在集群 <cls> 上执行故障转移

pgBackRest 备份与恢复命令和快捷方式:

pb info                                 # 打印 pgbackrest 仓库信息
pg-backup                               # 进行备份,增量备份,或在必要时进行完整备份
pg-backup full                          # 进行完整备份
pg-backup diff                          # 进行差异备份
pg-backup incr                          # 进行增量备份
pg-pitr -i                              # 恢复到最新备份完成的时间(不常用)
pg-pitr --time="2022-12-30 14:44:44+08" # 恢复到特定时间点(在删除数据库、删除表的情况下)
pg-pitr --name="my-restore-point"       # 恢复到由 pg_create_restore_point 创建的命名恢复点
pg-pitr --lsn="0/7C82CB8" -X            # 恢复到 LSN 之前
pg-pitr --xid="1234567" -X -P           # 恢复到特定事务 ID 之前,然后提升
pg-pitr --backup=latest                 # 恢复到最新备份集
pg-pitr --backup=20221108-105325        # 恢复到特定备份集,可通过 pgbackrest info 检查

Systemd 组件快速参考:

systemctl stop patroni                  # start stop restart reload
systemctl stop pgbouncer                # start stop restart reload
systemctl stop pg_exporter              # start stop restart reload
systemctl stop pgbouncer_exporter       # start stop restart reload
systemctl stop node_exporter            # start stop restart
systemctl stop haproxy                  # start stop restart reload
systemctl stop vip-manager              # start stop restart reload
systemctl stop postgres                 # 仅当 patroni_mode == 'remove' 时

创建集群

要创建新的 Postgres 集群,首先在配置清单中定义它,然后使用以下命令初始化:

bin/node-add <cls>                # 为集群 <cls> 初始化节点           # ./node.yml  -l <cls>
bin/pgsql-add <cls>               # 初始化集群 <cls> 的 PostgreSQL 实例  # ./pgsql.yml -l <cls>

注意,请先执行 bin/node-add,然后执行 bin/pgsql-add,PGSQL 只能在受管节点上工作。


创建用户

要在现有 Postgres 集群上创建新的业务用户,将用户定义添加到 all.children.<cls>.pg_users,然后按如下方式创建用户:

bin/pgsql-user <cls> <username>   # ./pgsql-user.yml -l <cls> -e username=<username>

创建数据库

要在现有 Postgres 集群上创建新的数据库用户,将数据库定义添加到 all.children.<cls>.pg_databases,然后按如下方式创建数据库:

bin/pgsql-db <cls> <dbname>       # ./pgsql-db.yml -l <cls> -e dbname=<dbname>

注意:如果数据库指定了拥有者,该用户应该已经存在,否则您需要先 创建用户


重载服务

服务是由 HAProxy 服务的暴露访问点。

此任务用于集群成员发生变化时,例如 添加/移除 从库、主从切换/故障转移或暴露新服务或更新现有服务的配置(例如负载均衡权重)。

要在整个代理集群或特定实例上创建新服务或重载现有服务:

bin/pgsql-svc <cls>               # pgsql.yml -l <cls> -t pg_service -e pg_reload=true
bin/pgsql-svc <cls> [ip...]       # pgsql.yml -l ip... -t pg_service -e pg_reload=true

重载 HBA 规则

此任务用于您的 Postgres/Pgbouncer HBA 规则发生变化时,您可能需要重载 HBA 以应用更改。

如果您有任何特定于角色的 HBA 规则,您可能也需要在主从切换/故障转移后重载 HBA。

要在整个集群或特定实例上重载 postgres 和 pgbouncer HBA 规则:

bin/pgsql-hba <cls>               # pgsql.yml -l <cls> -t pg_hba,pg_reload,pgbouncer_hba,pgbouncer_reload -e pg_reload=true
bin/pgsql-hba <cls> [ip...]       # pgsql.yml -l ip... -t pg_hba,pg_reload,pgbouncer_hba,pgbouncer_reload -e pg_reload=true

配置集群

要更改现有 Postgres 集群的配置,您必须在使用管理员用户的管理节点上发起控制命令:

pg edit-config <cls>              # 使用 patronictl 交互式配置集群

更改 patroni 参数和 postgresql.parameters,使用向导保存并应用更改。


添加从库

要向现有 Postgres 集群添加新的从库,您必须将其定义添加到配置清单:all.children.<cls>.hosts,然后:

bin/node-add <ip>                 # 为新从库初始化节点 <ip>
bin/pgsql-add <cls> <ip>          # 在 <ip> 上为集群 <cls> 初始化 PostgreSQL 实例

这将把节点 <ip> 添加到 pigsty 并将其初始化为集群 <cls> 的从库。

集群服务将被 重载 以采纳新成员。


移除从库

要从现有 PostgreSQL 集群中移除从库:

bin/pgsql-rm <cls> <ip...>        # ./pgsql-rm.yml -l <ip>

这将从集群 <cls> 中移除实例 <ip>。集群服务将被 重载 以从负载均衡器中踢出被移除的实例。


移除集群

要移除整个 Postgres 集群,只需运行:

bin/pgsql-rm <cls>                # ./pgsql-rm.yml -l <cls>

主从切换

您可以使用 patroni 命令执行 PostgreSQL 集群主从切换。

pg switchover <cls>   # 交互模式,您可以使用以下选项跳过
pg switchover --leader pg-test-1 --candidate=pg-test-2 --scheduled=now --force pg-test

备份集群

要使用 pgBackRest 创建备份,以本地数据库超级用户身份运行:

pg-backup                         # 进行 PostgreSQL 基础备份
pg-backup full                    # 进行完整备份
pg-backup diff                    # 进行差异备份
pg-backup incr                    # 进行增量备份
pb info                           # 检查备份信息

详情请查看 备份PITR


恢复集群

要将集群恢复到之前的时间点(PITR),以本地数据库超级用户身份运行:

pg-pitr -i                              # 恢复到最新备份完成的时间(不常用)
pg-pitr --time="2022-12-30 14:44:44+08" # 恢复到特定时间点(在删除数据库、删除表的情况下)
pg-pitr --name="my-restore-point"       # 恢复到由 pg_create_restore_point 创建的命名恢复点
pg-pitr --lsn="0/7C82CB8" -X            # 恢复到 LSN 之前
pg-pitr --xid="1234567" -X -P           # 恢复到特定事务 ID 之前,然后提升
pg-pitr --backup=latest                 # 恢复到最新备份集
pg-pitr --backup=20221108-105325        # 恢复到特定备份集,可通过 pgbackrest info 检查

然后按照指导向导操作,详情请查看备份和 PITR


添加软件包

要添加更新版本的 RPM 软件包,您必须将它们添加到 repo_packagesrepo_url_packages

然后使用 ./infra.yml -t repo_build 子任务在基础设施节点上重建仓库,然后您可以使用 ansible 模块 package 安装这些软件包:

ansible pg-test -b -m package -a "name=pg_cron_15,topn_15,pg_stat_monitor_15*"  # 安装一些软件包

安装扩展

如果您想在 PostgreSQL 集群上安装扩展,将它们添加到 pg_extensions 并确保它们被安装:

./pgsql.yml -t pg_ext     # 安装扩展

一些扩展需要在 shared_preload_libraries 中加载,您可以将它们添加到 pg_libs,或 配置 现有集群。

最后,在集群主实例上执行 CREATE EXTENSION <extname>; 来安装它。

详情请查看 PGSQL 扩展:安装


小版本升级

要执行小版本的服务器版本升级/降级,您必须首先将软件包 添加 到 yum/apt 仓库。

然后从所有从库执行滚动升级/降级,然后切换集群以升级主库。

ansible <cls> -b -a "yum upgrade/downgrade -y <pkg>"    # 升级/降级软件包
pg restart --force <cls>                                # 重启集群

大版本升级

实现大版本升级的最简单方法是使用新版本创建新集群,然后使用逻辑复制和蓝绿部署进行 迁移

您也可以执行就地大版本升级,但不建议这样做,特别是当安装了某些扩展时。但这是可能的。

假设您想将 PostgreSQL 14 升级到 15,您必须将软件包 添加 到 yum/apt 仓库,并保证扩展也具有完全相同的版本。

./pgsql.yml -t pg_pkg -e pg_version=15                         # 为 PostgreSQL 15 安装软件包
sudo su - postgres; mkdir -p /data/postgres/pg-meta-15/data/   # 为 15 准备目录
pg_upgrade -b /usr/pgsql-14/bin/ -B /usr/pgsql-15/bin/ -d /data/postgres/pg-meta-14/data/ -D /data/postgres/pg-meta-15/data/ -v -c # 预检
pg_upgrade -b /usr/pgsql-14/bin/ -B /usr/pgsql-15/bin/ -d /data/postgres/pg-meta-14/data/ -D /data/postgres/pg-meta-15/data/ --link -j8 -v -c
rm -rf /usr/pgsql; ln -s /usr/pgsql-15 /usr/pgsql;             # 修复二进制链接
mv /data/postgres/pg-meta-14 /data/postgres/pg-meta-15         # 重命名数据目录
rm -rf /pg; ln -s /data/postgres/pg-meta-15 /pg                # 修复数据目录链接

11.4.1 - 参数优化

调整 postgres 参数

Pigsty 默认提供了四套场景化参数模板,可以通过 pg_conf 参数指定并使用。

  • tiny.yml:为小节点、虚拟机、小型演示优化(1-8核,1-16GB)
  • oltp.yml:为OLTP工作负载和延迟敏感应用优化(4C8GB+)(默认模板)
  • olap.yml:为OLAP工作负载和吞吐量优化(4C8G+)
  • crit.yml:为数据一致性和关键应用优化(4C8G+)

Pigsty 会针对这四种默认场景,采取不同的参数优化策略,如下所示:


内存参数调整

Pigsty 默认会检测系统的内存大小,并以此为依据设定最大连接数量与内存相关参数。

默认情况下,Pigsty 使用 25% 的内存作为 PostgreSQL 共享缓冲区,剩余的 75% 作为操作系统缓存。

默认情况下,如果用户没有设置一个 pg_max_conn 最大连接数,Pigsty 会根据以下规则使用默认值:

  • oltp: 500 (pgbouncer) / 1000 (postgres)
  • crit: 500 (pgbouncer) / 1000 (postgres)
  • tiny: 300
  • olap: 300

其中对于 OLTP 与 CRIT 模版来说,如果服务没有指向 pgbouncer 连接池,而是直接连接 postgres 数据库,最大连接会翻倍至 1000 条。

决定最大连接数后,work_mem 会根据共享内存数量 / 最大连接数计算得到,并限定在 64MB ~ 1GB 的范围内。

{% if pg_max_conn != 'auto' and pg_max_conn|int >= 20 %}{% set pg_max_connections = pg_max_conn|int %}{% else %}{% if pg_default_service_dest|default('postgres') == 'pgbouncer' %}{% set pg_max_connections = 500 %}{% else %}{% set pg_max_connections = 1000 %}{% endif %}{% endif %}
{% set pg_max_prepared_transactions = pg_max_connections if 'citus' in pg_libs else 0 %}
{% set pg_max_locks_per_transaction = (2 * pg_max_connections)|int if 'citus' in pg_libs or 'timescaledb' in pg_libs else pg_max_connections %}
{% set pg_shared_buffers = (node_mem_mb|int * pg_shared_buffer_ratio|float) | round(0, 'ceil') | int %}
{% set pg_maintenance_mem = (pg_shared_buffers|int * 0.25)|round(0, 'ceil')|int %}
{% set pg_effective_cache_size = node_mem_mb|int - pg_shared_buffers|int  %}
{% set pg_workmem =  ([ ([ (pg_shared_buffers / pg_max_connections)|round(0,'floor')|int , 64 ])|max|int , 1024])|min|int %}

CPU参数调整

在 PostgreSQL 中,有 4 个与并行查询相关的重要参数,Pigsty 会自动根据当前系统的 CPU 核数进行参数优化。 在所有策略中,总并行进程数量(总预算)通常设置为 CPU 核数 + 8,且保底为 16 个,从而为逻辑复制与扩展预留足够的后台 worker 数量,OLAP 和 TINY 模板根据场景略有不同。

OLTP 设置逻辑 范围限制
max_worker_processes max(100% CPU + 8, 16) 核数 + 4,保底 12,
max_parallel_workers max(ceil(50% CPU), 2) 1/2 CPU 上取整,最少两个
max_parallel_maintenance_workers max(ceil(33% CPU), 2) 1/3 CPU 上取整,最少两个
max_parallel_workers_per_gather min(max(ceil(20% CPU), 2),8) 1/5 CPU 下取整,最少两个,最多 8 个
OLAP 设置逻辑 范围限制
max_worker_processes max(100% CPU + 12, 20) 核数 + 12,保底 20,
max_parallel_workers max(ceil(80% CPU, 2)) 4/5 CPU 上取整,最少两个
max_parallel_maintenance_workers max(ceil(33% CPU), 2) 1/3 CPU 上取整,最少两个
max_parallel_workers_per_gather max(floor(50% CPU), 2) 1/2 CPU 上取整,最少两个
CRIT 设置逻辑 范围限制
max_worker_processes max(100% CPU + 8, 16) 核数 + 8,保底 16,
max_parallel_workers max(ceil(50% CPU), 2) 1/2 CPU 上取整,最少两个
max_parallel_maintenance_workers max(ceil(33% CPU), 2) 1/3 CPU 上取整,最少两个
max_parallel_workers_per_gather 0, 按需启用
TINY 设置逻辑 范围限制
max_worker_processes max(100% CPU + 4, 12) 核数 + 4,保底 12,
max_parallel_workers max(ceil(50% CPU) 1) 50% CPU 下取整,最少1个
max_parallel_maintenance_workers max(ceil(33% CPU), 1) 33% CPU 下取整,最少1个
max_parallel_workers_per_gather 0, 按需启用

请注意,CRIT 和 TINY 模板直接通过设置 max_parallel_workers_per_gather = 0 关闭了并行查询。 用户可以按需在需要时设置此参数以启用并行查询。

OLTP 和 CRIT 模板都额外设置了以下参数,将并行查询的 Cost x 2,以降低使用并行查询的倾向。

parallel_setup_cost: 2000           # double from 100 to increase parallel cost
parallel_tuple_cost: 0.2            # double from 0.1 to increase parallel cost
min_parallel_table_scan_size: 16MB  # double from 8MB to increase parallel cost
min_parallel_index_scan_size: 1024  # double from 512 to increase parallel cost

请注意 max_worker_processes 参数的调整必须在重启后才能生效。此外,当从库的本参数配置值高于主库时,从库将无法启动。 此参数必须通过 patroni 配置管理进行调整,该参数由 Patroni 管理,用于确保主从配置一致,避免在故障切换时新从库无法启动。


存储空间参数

Pigsty 默认检测 /data/postgres 主数据目录所在磁盘的总空间,并以此作为依据指定下列参数:

min_wal_size: {{ ([pg_size_twentieth, 200])|min }}GB                  # 1/20 disk size, max 200GB
max_wal_size: {{ ([pg_size_twentieth * 4, 2000])|min }}GB             # 2/10 disk size, max 2000GB
max_slot_wal_keep_size: {{ ([pg_size_twentieth * 6, 3000])|min }}GB   # 3/10 disk size, max 3000GB
temp_file_limit: {{ ([pg_size_twentieth, 200])|min }}GB               # 1/20 of disk size, max 200GB
  • temp_file_limit 默认为磁盘空间的 5%,封顶不超过 200GB。
  • min_wal_size 默认为磁盘空间的 5%,封顶不超过 200GB。
  • max_wal_size 默认为磁盘空间的 20%,封顶不超过 2TB。
  • max_slot_wal_keep_size 默认为磁盘空间的 30%,封顶不超过 3TB。

作为特例, OLAP 模板允许 20% 的 temp_file_limit ,封顶不超过 2TB

11.4.2 - 维护保养

常见系统维护任务

要确保 Pigsty 与 PostgreSQL 集群健康稳定运行,需要进行一些例行维护保养工作。


定期查阅监控

Pigsty 提供了开箱即用的监控平台,我们建议您每天浏览一次监控大盘,关注系统状态。 极端情况下,我们建议您每周至少查阅一次监控,关注出现的告警事件,这样可以提前规避绝大多数故障与问题。

这里列举了 Pigsty 中预先定义的 告警规则 列表。


故障切换善后

Pigsty 的高可用架构允许 PostgreSQL 集群自动进行主从切换,这意味着运维与 DBA 无需即时介入与响应。 然而用户仍然需要在合适的时机(例如第二天工作日)进行以下善后工作,包括:

  • 调查并确认故障出现的原因,避免再次出现
  • 视情况恢复集群原本的主从拓扑,或者修改配置清单以匹配新的主从状态。
  • 通过 bin/pgsql-svc 刷新负载均衡器配置,更新服务的路由状态
  • 通过 bin/pgsql-hba 刷新集群的 HBA 规则,避免主从特定的规则漂移
  • 如果有必要,使用 bin/pgsql-rm 移除故障服务器,并通过 bin/pgsql-add 扩容一台新从库

表膨胀治理

长时间运行的 PostgreSQL 会出现 “表膨胀” / “索引膨胀” 现象, 导致系统性能劣化。

定期使用 pg_repack 对表与索引进行在线重建,有助于维护 PostgreSQL 的良好性能表现。 Pigsty 已经默认在所有数据库中安装并启用了此扩展,因此您可以直接使用。

您可以通过 Pigsty 的 PGCAT Database - Table Bloat 面板, 确认数据库中的表膨胀情况与索引膨胀情况。并选择膨胀率较高(膨胀率高于 50% 的较大表)的表与索引,使用 pg_repack 进行在线重整:

pg_repack dbname -t schema.table

重整期间不会影响正常读写,但重整完毕之后的 切换瞬间 需要获取表上的 AccessExclusive 锁阻塞一切访问。 因此对于高吞吐量业务,建议在业务低峰期或者维护窗口进行。更多细节,请参考:关系膨胀的治理


VACUUM FREEZE

冻结过期事务ID(VACUUM FREEZE)是PostgreSQL重要的维护任务,用于防止事务ID (XID) 用尽导致停机。 尽管 PostgreSQL 已经提供了自动垃圾回收(AutoVacuum)机制,然而对于高标准的生产环境, 我们依然建议结合自动和手动两种方式,定期执行全库级别的 VACUUM FREEZE ,以确保 XID 安全。

11.4.3 - 故障排查

常见故障与分析排查思路

本文档列举了 PostgreSQL 和 Pigsty 中可能出现的故障,以及定位,处理,分析问题的 SOP。


磁盘空间写满

磁盘空间写满是最常见的故障类型。

现象

当数据库所在磁盘空间耗尽时,PostgreSQL 将无法正常工作,可能出现以下现象:数据库日志反复报错“no space left on device”(磁盘空间不足), 新数据无法写入,甚至 PostgreSQL 可能触发 PANIC 强制关闭。

Pigsty 带有 NodeFsSpaceFull 告警规则,当文件系统可用空间不足 10% 时触发告警。 使用监控系统 NODE Instance 面板查阅 FS 指标面板定位问题。

诊断

您也可以登录数据库节点,使用 df -h 查看各挂载盘符使用率,确定哪个分区被写满。 对于数据库节点,重点检查以下目录及其大小,以判断是哪个类别的文件占满了空间:

  • 数据目录/pg/data/base):存放表和索引的数据文件,大量写入与临时文件需要关注
  • WAL目录(如 pg/data/pg_wal):存放 PG WAL,WAL 堆积/复制槽保留是常见的磁盘写满原因。
  • 数据库日志目录(如 pg/log):如果 PG 日志未及时轮转写大量报错写入,也可能占用大量空间。
  • 本地备份目录(如 data/backups):使用 pgBackRest 等在本机保存备份时,也有可能撑满磁盘。

如果问题出在 Pigsty 管理节点或监控节点,还需考虑:

  • 监控数据:Prometheus 的时序指标和 Loki 日志存储都会占用磁盘,可检查保留策略。
  • 对象存储数据:Pigsty 集成的 MinIO 对象存储可能会被用于 PG 备份保存。

明确占用空间最大的目录后,可进一步使用 du -sh <目录> 深入查找特定大型文件或子目录。

处理

磁盘写满属于紧急问题,需立即采取措施释放空间并保证数据库继续运行。 当数据盘并未与系统盘区分时,写满磁盘可能导致 Shell 命令无法执行。这种情况下,可以删除 /pg/dummy 占位文件,释放少量应急空间以便 shell 命令恢复正常。 如果数据库由于 pg_wal 写满已经宕机,清理空间后需要重启数据库服务并仔细检查数据完整性。


事务号回卷

PostgreSQL 循环使用 32 位事务ID (XID),耗尽时会出现“事务号回卷”故障(XID Wraparound)。

现象

第一阶段的典型征兆是 PGSQL Persist - Age Usage 面板年龄饱和度进入警告区域。 数据库日志开始出现:WARNING: database "postgres" must be vacuumed within xxxxxxxx transactions 字样的信息。

若问题持续恶化,PostgreSQL 会进入保护模式:当剩余事务ID不到约100万时数据库切换为只读模式;达到上限约21亿(2^31)时则拒绝任何新事务并迫使服务器停机以避免数据错误。

诊断

PostgreSQL 与 Pigsty 默认启用自动垃圾回收(AutoVacuum),因此此类故障出现通常有更深层次的根因。 常见的原因包括:超长事务(SAGE),Autovacuum 配置失当,复制槽阻塞,资源不足,存储引擎/扩展BUG,磁盘坏快。

首先定位年龄最大的数据库,然后可通过 Pigsty PGCAT Database - Tables 面板来确认表的年龄分布。 同时查阅数据库错误日志,通常可以找到定位根因的线索。

处理

  1. 立即冻结老事务:如果数据库尚未进入只读保护状态,立刻对受影响的库执行一次手动 VACUUM FREEZE。可以从老化最严重的表开始逐个冻结,而不是整库一起做,以加快效果。使用超级用户连接数据库,针对识别出的 relfrozenxid 最大的表运行 VACUUM FREEZE 表名;,优先冻结那些XID年龄最大的表元组。这样可以迅速回收大量事务ID空间。
  2. 单用户模式救援:如果数据库已经拒绝写入或宕机保护,此时需要启动数据库到单用户模式执行冻结操作。在单用户模式下运行 VACUUM FREEZE database_name; 对整个数据库进行冻结清理。完成后再以多用户模式重启数据库。这样做可以解除回卷锁定,让数据库重新可写。需要注意在单用户模式下操作要非常谨慎,并确保有足够的事务ID余量完成冻结。
  3. 备用节点接管:在某些复杂场景(例如遭遇硬件问题导致 vacuum 无法完成),可考虑提升集群中的只读备节点为主,以获取一个相对干净的环境来处理冻结。例如主库因坏块导致无法 vacuum,此时可以手动Failover提升备库为新的主库,再对其进行紧急 vacuum freeze。确保新主库已冻结老事务后,再将负载切回来。

连接耗尽

PostgreSQL 有一个最大连接数配置 (max_connections),当客户端连接数超过此上限时,新的连接请求将被拒绝。典型现象是在应用端看到数据库无法连接,并报出类似 FATAL: remaining connection slots are reserved for non-replication superuser connectionstoo many clients already 的错误。 这表示普通连接数已用完,仅剩下保留给超管或复制的槽位

诊断

连接耗尽通常由客户端大量并发请求引起。您可以通过 PGCAT Instance / PGCAT Database / PGCAT Locks 直接查阅数据库当前的活跃会话。 并判断是什么样的查询填满了系统,并进行进一步的处理。特别需要关注是否存在大量 Idle in Transaction 状态的连接以及长时间运行的事务(以及慢查询)。

处理

杀查询:对于已经耗尽导致业务受阻的情况,通常立即使用 pg_terminate_backend(pid) 进行紧急降压。 对于使用连接池的情况,则可以调整连接池大小参数,并执行 reload 重载的方式减少数据库层面的连接数量。

您也可以修改 max_connections 参数为更大的值,但本参数需要重启数据库后才能生效。


etcd 配额写满

etcd 配额写满将导致 PG 高可用控制面失效,无法进行配置变更。

诊断

Pigsty 在实现高可用时使用 etcd 作为分布式配置存储(DCS),etcd 自身有一个存储配额(默认约为2GB)。 当 etcd 存储用量达到配额上限时,etcd 将拒绝写入操作,报错 “etcdserver: mvcc: database space exceeded”。在这种情况下,Patroni 无法向 etcd 写入心跳或更新配置,从而导致集群管理功能失效。

解决

在 Pigsty v2.0.0 - v2.5.1 之间的版本默认受此问题影响。Pigsty v2.6.0 为部署的 etcd 新增了自动压实的配置项,如果您仅将其用于 PG 高可用租约,则常规用例下不会再有此问题。


有缺陷的存储引擎

目前,TimescaleDB 的试验性存储引擎 Hypercore 被证实存在缺陷,已经出现 VACUUM 无法回收出现 XID 回卷故障的案例。 请使用该功能的用户及时迁移至 PostgreSQL 原生表或者 TimescaleDB 默认引擎

详细介绍:《PG新存储引擎故障案例

11.4.4 - 误删处理

处理误删数据,误删表,误删数据库

误删数据

如果是小批量 DELETE 误操作,可以考虑使用 pg_surgery 或者 pg_dirtyread 扩展进行原地手术恢复。

-- 立即关闭此表上的 Auto Vacuum 并中止 Auto Vacuum 本表的 worker 进程
ALTER TABLE public.some_table SET (autovacuum_enabled = off, toast.autovacuum_enabled = off);

CREATE EXTENSION pg_dirtyread;
SELECT * FROM pg_dirtyread('tablename') AS t(col1 type1, col2 type2, ...);

如果被删除的数据已经被 VACUUM 回收,那么使用通用的误删处理流程。

误删对象

当出现 DROP/DELETE 类误操作,通常按照以下流程决定恢复方案。

  1. 确认此数据是否可以通过业务系统或其他数据系统找回,如果可以,直接从业务侧修复。
  2. 确认是否有延迟从库,如果有,推进延迟从库至误删时间点,查询出来恢复。
  3. 如果数据已经确认删除,确认备份信息,恢复范围是否覆盖误删时间点,如果覆盖,开始 PITR
  4. 确认是整集群原地 PITR 回滚,还是新开服务器重放,还是用从库来重放,并执行恢复策略

误删集群

如果出现整个数据库集群通过 Pigsty 管理命令被误删的情况,例如错误的执行 pgsql-rm.yml 剧本或 bin/pgsql-rm 命令。 除非您指定了 pg_rm_backup 参数为 false,否则备份会与数据库集群一起被删除。

说明

警告:在这种情况,您的数据将无法找回!请务必三思而后行!

建议:对于生产环境,您可以在配置清单中全局配置此参数为 false,在移除集群时保留备份。

11.5 - 剧本

Pigsty 提供的 Ansible 剧本

如何使用 Ansible playbook 管理 PostgreSQL 集群

Pigsty 有一系列 PostgreSQL playbook:


安全防护

如果您担心意外删除 PostgreSQL 集群,可以启用安全防护功能。

pg_safeguard 参数设置为 true 将阻止 pgsql-rm.yml 运行。

在 Pigsty v3.5 之前,pgsql.yml 可能会误删数据库,请谨慎使用!

Pigsty v3.5 从 pgsql.yml 中删除了 pg 清除逻辑, 所以现在删除 PostgreSQL 的唯一方法是运行 pgsql-rm.yml


pgsql.yml

pgsql.yml 用于初始化 HA PostgreSQL 集群或添加新副本。

asciicast

此 playbook 包含以下子任务

pg_install              : # 安装 postgres 包和扩展
  - pg_dbsu             : # 为 postgres dbsu 设置操作系统用户 sudo
    - pg_dbsu_create    : # 交换 dbsu ssh 密钥
    - pg_dbsu_sudo      : # 交换 dbsu ssh 密钥
    - pg_ssh            : # 交换 dbsu ssh 密钥
  - pg_pkg              : # 安装 postgres 包
    - pg_ext            : # 安装 postgres 扩展包
  - pg_link             : # 将 pgsql 版本 bin 链接到 /usr/pgsql
  - pg_path             : # 将 pgsql bin 添加到系统路径
  - pg_dir              : # 创建 postgres 目录并设置 fhs
  - pg_bin              : # 同步 /pg/bin 脚本
  - pg_alias            : # 写入 pgsql/psql 别名
  - pg_dummy            : # 创建虚拟占位符文件
pg_bootstrap            : # 引导 postgres 集群
  - pg_config           : # 生成 postgres 配置
    - pg_conf           : # 生成 patroni 配置
    - pg_key            : # 生成 pgsodium 密钥
  - pg_cert             : # 为 postgres 颁发证书
    - pg_cert_private   : # 检查 pg 私钥是否存在
    - pg_cert_issue     : # 签署 pg 服务器证书
    - pg_cert_copy      : # 将密钥和证书复制到 pg 节点
  - pg_launch           : # 启动 patroni 主实例和副本(patroni)
    - pg_watchdog       : # 为 postgres 授予看门狗权限
    - pg_primary        : # 启动 patroni/postgres 主实例
    - pg_init           : # 使用角色/模板初始化 pg 集群
    - pg_pass           : # 将 .pgpass 文件写入 pg 主目录
    - pg_replica        : # 启动 patroni/postgres 副本
    - pg_hba            : # 生成 pg HBA 规则
    - patroni_reload    : # 重新加载 patroni 配置
    - pg_patroni        : # 如有必要暂停或删除 patroni
pg_provision            : # 置备 postgres 业务用户和数据库
 - pg_user              : # 置备 postgres 业务用户
    - pg_user_config    : # 渲染创建用户 sql
    - pg_user_create    : # 在 postgres 上创建用户
 - pg_db                : # 置备 postgres 业务数据库
    - pg_db_config      : # 渲染创建数据库 sql
    - pg_db_create      : # 在 postgres 上创建数据库
pg_backup               : # 初始化 postgres PITR 备份
  - pgbackrest          : # 为备份设置 pgbackrest
    - pgbackrest_config : # 生成 pgbackrest 配置
    - pgbackrest_init   : # 初始化 pgbackrest 仓库
    - pgbackrest_backup : # 引导后进行初始备份
pg_access               : # 初始化 postgres 服务访问、池、dns、vip、svc
 - pgbouncer            : # 部署 pgbouncer sidecar 与 postgres
   - pgbouncer_dir      : # 创建 pgbouncer 目录
   - pgbouncer_config   : # 生成 pgbouncer 配置
     -  pgbouncer_hba   : # 生成 pgbouncer hba 配置
     -  pgbouncer_user  : # 生成 pgbouncer 用户列表
   -  pgbouncer_launch  : # 启动 pgbouncer 池化服务
   -  pgbouncer_reload  : # 重新加载 pgbouncer 配置
 - pg_vip               : # 使用 vip-manager 将 vip 绑定到 pgsql 主实例
   - pg_vip_config      : # 生成 vip-manager 配置
   - pg_vip_launch      : # 启动 vip-manager 以绑定 vip
 - pg_dns               : # 将 dns 名称注册到基础设施 dnsmasq
   - pg_dns_ins         : # 注册 pg 实例名称
   - pg_dns_cls         : # 注册 pg 集群名称
 - pg_service           : # 使用 haproxy 暴露 pgsql 服务
   - pg_service_config  : # 生成 pg 服务的本地 haproxy 配置
   - pg_service_reload  : # 使用 haproxy 暴露 postgres 服务
pg_monitor              : # 设置 pgsql 监控并注册到基础设施
  - pg_exporter         : # 配置和启动 pg_exporter
  - pgbouncer_exporter  : # 配置和启动 pgbouncer_exporter
  - pgbackrest_exporter : # 配置和启动 pgbackrest_exporter
  - register_prometheus : # 将 pg 注册为 prometheus 监控目标
  - register_grafana    : # 将 pg 数据库注册为 grafana 数据源

使用此 playbook 的管理任务

先初始化主实例再初始化副本
  • 副本初始化后,您可能需要运行重新加载 HBA 规则追加副本
  • 包装脚本 pgsql-add 会执行此操作,详情请查看 SOP:添加实例
  • 如果您在整个集群上运行此操作,则无需担心此问题。
在备用集群之前初始化上游集群
  • 如果您正在初始化备用集群,您应该确保上游集群已经初始化。

pgsql-rm.yml

playbook pgsql-rm.yml 可以删除 PostgreSQL 集群,或从集群中删除特定副本。

asciicast

此 playbook 包含以下子任务

pg_monitor               : # 删除 prometheus、grafana、nginx 中的注册
  - prometheus           : # 从 prometheus 中删除监控目标
  - grafana              : # 从 grafana 中删除数据源
  - pg_exporter          : # 删除 pg_exporter(postgres 监控)
  - pgbouncer_exporter   : # 删除 pgbouncer_exporter(pgbouncer 监控)
  - pgbackrest_exporter  : # 删除 pgbackrest_exporter(pgbackrest 监控)
pg_access                : # 删除 pg 服务访问
  - dns                  : # 删除 pg dns 记录
  - vip                  : # 删除 vip-manager
  - pg_service           : # 从 haproxy 删除 pg 服务
  - pgbouncer            : # 删除 pgbouncer 连接中间件
postgres                 : # 删除 postgres 实例
  - pg_replica           : # 删除所有副本
  - pg_primary           : # 删除主实例
  - pg_meta              : # 从 dcs 删除元数据
pg_backup                : # 删除备份仓库(使用 `pg_rm_backup=false` 禁用)
pg_data                  : # 删除 postgres 数据(使用 `pg_rm_data=false` 禁用)
pg_pkg                   : # 卸载 pg 包(使用 `pg_rm_pkg=false` 禁用)
 - pg_ext                : # 单独卸载 postgres 扩展

一些参数可以影响此 playbook 的行为:

# 删除 pgsql 集群 `pg-test`
./pgsql-rm.yml                          # 删除所有 postgres 集群(非常危险)
./pgsql-rm.yml -l pg-test               # 删除集群 `pg-test`
./pgsql-rm.yml -e pg_safeguard=false    # 强制禁用安全防护,强制运行此 playbook
./pgsql-rm.yml -e pg_rm_data=false        # 保留数据目录,不要删除它(保留数据)
./pgsql-rm.yml -e pg_rm_backup=false      # 默认不清除 postgres 数据(保留备份仓库)
./pgsql-rm.yml -e pg_rm_pkg=false     # 默认不卸载 postgres 包(保留包)

使用此 playbook 的管理任务

关于此 playbook 的一些注意事项

当仍有副本时,不要直接在单个集群主实例上运行此 playbook
  • 否则,其余副本将触发自动故障转移。
  • 如果您在删除主实例之前删除所有副本,就不会有问题。
  • 如果您在整个集群上运行此操作,则无需担心此问题。
从集群中删除副本后重新加载服务
  • 它是一个死服务器,所以不会影响集群服务。
  • 但您应该及时重新加载服务以确保环境与配置清单之间的一致性。
  • 删除副本时,它仍然在 haproxy 负载均衡器的配置文件中。

pgsql-db.yml

剧本 pgsql-db.yml 可以向现有 PostgreSQL 集群添加新业务数据库。

查看管理 SOP:创建数据库


pgsql-user.yml

剧本 pgsql-user.yml 可以向现有 PostgreSQL 集群添加新业务用户。

查看管理 SOP:创建用户


pgsql-pitr.yml

剧本 pgsql-pitr.yml 可以在现有 PostgreSQL 集群上执行 时间点恢复 (PITR)。

查看管理 SOP: 备份恢复


pgsql-pitr.yml

剧本 pgsql-pitr.yml 可以向现有 PostgreSQL 集群添加新业务用户。

查看管理 SOP:时间点恢复


pgsql-monitor.yml

剧本 pgsql-monitor.yml 可以将现有/远程 postgres / RDS 实例纳入监控。

查看管理 SOP:监控 Postgres


pgsql-migration.yml

剧本 pgsql-migration.yml 可以为现有 PostgreSQL 集群生成迁移手册和脚本。

查看管理 SOP:数据库迁移

11.6 - 监控

监控现有 PostgreSQL 或 RDS

概述

Pigsty 使用现代可观测性栈进行 PostgreSQL 监控:

  • Grafana 用于指标可视化和 PostgreSQL 数据源。
  • Prometheus 用于 PostgreSQL / Pgbouncer / Patroni / HAProxy / Node 指标
  • Loki 用于 PostgreSQL / Pgbouncer / Patroni / pgBackRest 日志
  • 开箱即用的 PostgreSQL 和其他一切的仪表板

指标

PostgreSQL 的指标由收集器文件定义:pg_exporter.yml。Prometheus 记录规则和告警评估将进一步处理它:files/prometheus/rules/pgsql.yml

有三个身份标签:clsinsip,它们将附加到所有指标和日志。节点和 haproxy 将尝试重用相同的身份以提供一致的指标和日志。

{ cls: pg-meta, ins: pg-meta-1, ip: 10.10.10.10 }
{ cls: pg-meta, ins: pg-test-1, ip: 10.10.10.11 }
{ cls: pg-meta, ins: pg-test-2, ip: 10.10.10.12 }
{ cls: pg-meta, ins: pg-test-3, ip: 10.10.10.13 }

日志

PostgreSQL 相关日志默认由 promtail 收集并发送到基础设施节点上的 Loki。

目标

Prometheus 监控目标在 /etc/prometheus/targets/pgsql/ 下的静态文件中定义。每个实例都有一个对应的文件。以 pg-meta-1 为例:

# pg-meta-1 [primary] @ 10.10.10.10
- labels: { cls: pg-meta, ins: pg-meta-1, ip: 10.10.10.10 }
  targets:
    - 10.10.10.10:9630    # <--- PostgreSQL 指标的 pg_exporter
    - 10.10.10.10:9631    # <--- Pgbouncer 指标的 pg_exporter
    - 10.10.10.10:8008    # <--- patroni 指标

当全局标志 patroni_ssl_enabled 设置时,patroni 目标将作为 /etc/prometheus/targets/patroni/<ins>.yml 管理,因为它需要不同的抓取端点(https)。

当集群被 bin/pgsql-rmpgsql-rm.yml 删除时,Prometheus 监控目标将被删除。您可以使用 playbook 子任务,或手动删除它们:

bin/pgmon-rm <ins>      # 从所有基础设施节点删除 prometheus 目标

远程 RDS 目标作为 /etc/prometheus/targets/pgrds/<cls>.yml 管理。它将由 pgsql-monitor.yml playbook 或 bin/pgmon-add 脚本创建。


监控模式

在 Pigsty 中有三种监控 PostgreSQL 实例的方式:

项目 \ 级别 L1 L2 L3
名称 远程数据库服务 现有部署 完全托管部署
简称 RDS MANAGED FULL
场景 仅连接字符串 URL 可 SSH sudo 由 Pigsty 创建的实例
PGCAT 功能 ✅ 完全可用 ✅ 完全可用 ✅ 完全可用
PGSQL 功能 ✅ 仅 PG 指标 ✅ PG 和节点指标 ✅ 完全支持
连接池指标 ❌ 不可用 ⚠️ 可选 ✅ 预配置
负载均衡器指标 ❌ 不可用 ⚠️ 可选 ✅ 预配置
PGLOG 功能 ❌ 不可用 ⚠️ 可选 ⚠️ 可选
PG Exporter ⚠️ 在基础设施节点上 ✅ 在数据库节点上 ✅ 在数据库节点上
Node Exporter ❌ 未部署 ✅ 在数据库节点上 ✅ 在数据库节点上
对数据库节点的入侵 ✅ 非入侵 ⚠️ 安装导出器 ⚠️ 完全由 Pigsty 管理
实例已存在 ✅ 是 ✅ 是 ⚠️ 由 Pigsty 创建
监控用户和视图 ⚠️ 手动设置 ⚠️ 手动设置 ✅ 自动配置
部署使用 Playbook bin/pgmon-add <cls> pgsql.ym/node.yml 的子任务 pgsql.yml
所需权限 来自基础设施节点的可连接 PGURL 数据库节点 SSH 和 sudo 权限 数据库节点 SSH 和 sudo 权限
功能概述 PGCAT + PGRDS 大部分功能 完整功能

监控现有集群

假设目标数据库节点可以由 Pigsty 管理(可通过 SSH 访问且 sudo 可用)。在这种情况下,您可以使用 pgsql.yml playbook 中的 pg_exporter 任务,以与标准部署相同的方式在目标节点上部署监控组件 PG Exporter。

您还可以使用同一 playbook 的 pgbouncerpgbouncer_exporter 任务在现有实例节点上部署连接池及其监控。此外,您可以使用 node.yml playbook 的 node_exporterhaproxypromtail 任务部署主机监控、负载均衡和日志收集组件,实现与原生 Pigsty 集群相似的用户体验。

现有集群的定义方法与 Pigsty 管理的普通集群非常相似。有选择地运行 pgsql.yml playbook 中的某些任务,而不是运行整个 playbook。

./node.yml  -l <cls> -t node_repo,node_pkg           # 在主机节点上为基础设施节点添加 YUM 源并安装包。
./node.yml  -l <cls> -t node_exporter,node_register  # 配置主机监控并添加到 Prometheus。
./node.yml  -l <cls> -t promtail                     # 配置主机日志收集并发送到 Loki。
./pgsql.yml -l <cls> -t pg_exporter,pg_register      # 配置 PostgreSQL 监控并注册到 Prometheus/Grafana。

由于目标数据库集群已经存在,您必须在目标数据库集群上手动设置监控用户、架构和扩展


监控 RDS

如果您只能通过 PGURL(数据库连接字符串)访问目标数据库,您可以参考这里的说明进行配置。在此模式下,Pigsty 在基础设施节点上部署相应的 PG Exporter 以从远程数据库获取指标,如下所示:

------ infra ------
|                 |
|   prometheus    |            v---- pg-foo-1 ----v
|       ^         |  metrics   |         ^        |
|   pg_exporter <-|------------|----  postgres    |
|   (port: 20001) |            | 10.10.10.10:5432 |
|       ^         |            ^------------------^
|       ^         |                      ^
|       ^         |            v---- pg-foo-2 ----v
|       ^         |  metrics   |         ^        |
|   pg_exporter <-|------------|----  postgres    |
|   (port: 20002) |            | 10.10.10.11:5433 |
-------------------            ^------------------^

监控系统将不再有主机/池化器/负载均衡器指标。但 PostgreSQL 指标和目录信息仍然可用。Pigsty 为此有两个专用仪表板:PGRDS 集群PGRDS 实例。概览和数据库级别仪表板被重用。由于 Pigsty 无法管理您的 RDS,您必须提前在目标数据库上设置监控

下面,我们使用沙箱环境作为示例:现在我们假设 pg-meta 集群是要监控的 RDS 实例 pg-foo-1pg-test 集群是要监控的 RDS 集群 pg-bar

  1. 在目标上创建监控架构、用户和权限。详情请参考监控设置

  2. 在配置列表中声明集群。例如,假设我们想要监控"远程" pg-metapg-test 集群:

infra:            # 基础设施集群,用于代理、监控、告警等。
  hosts: { 10.10.10.10: { infra_seq: 1 } }
  vars:           # 在 'infra' 组上为远程 postgres RDS 安装 pg_exporter
    pg_exporters: # 在这里列出所有远程实例,为每个分配一个唯一的未使用本地端口
      20001: { pg_cluster: pg-foo, pg_seq: 1, pg_host: 10.10.10.10 , pg_databases: [{ name: meta }] } # 将 meta 数据库注册为 Grafana 数据源

      20002: { pg_cluster: pg-bar, pg_seq: 1, pg_host: 10.10.10.11 , pg_port: 5432 } # 几种不同的连接字符串拼接方法
      20003: { pg_cluster: pg-bar, pg_seq: 2, pg_host: 10.10.10.12 , pg_exporter_url: 'postgres://dbuser_monitor:[email protected]:5432/postgres?sslmode=disable'}
      20004: { pg_cluster: pg-bar, pg_seq: 3, pg_host: 10.10.10.13 , pg_monitor_username: dbuser_monitor, pg_monitor_password: DBUser.Monitor }

pg_databases 字段中列出的数据库将在 Grafana 中注册为 PostgreSQL 数据源,为 PGCAT 监控面板提供数据支持。如果您不想使用 PGCAT 并在 Grafana 中注册数据库,请将 pg_databases 设置为空数组或留空。

pigsty-monitor.jpg
  1. 执行命令添加监控:bin/pgmon-add <clsname>
bin/pgmon-add pg-foo  # 将 pg-foo 集群纳入监控
bin/pgmon-add pg-bar  # 将 pg-bar 集群纳入监控
  1. 要从监控中删除远程集群,使用 bin/pgmon-rm <clsname>
bin/pgmon-rm pg-foo  # 从 Pigsty 监控中删除 pg-foo
bin/pgmon-rm pg-bar  # 从 Pigsty 监控中删除 pg-bar

您可以使用更多参数来覆盖默认的 pg_exporter 选项。这里有一个使用 Pigsty 监控阿里云 RDS 和 PolarDB 的示例:


监控设置

当您想要监控现有实例时,无论是 RDS 还是自建的 PostgreSQL 实例,您都需要在目标数据库上进行一些配置,以便 Pigsty 可以访问它们。

要将外部现有的 PostgreSQL 实例纳入监控,您需要一个可以访问该实例/集群的连接字符串。任何可访问的连接字符串(业务用户、超级用户)都可以使用,但我们建议使用专用的监控用户以避免权限泄露。

  • 监控用户:默认使用的用户名是 dbuser_monitor。此用户属于 pg_monitor 组,或确保它具有必要的视图权限。
  • 监控 HBA:默认密码是 DBUser.Monitor。您需要确保 HBA 策略允许监控用户从基础设施节点访问数据库。
  • 监控架构:可选但建议为监控视图和扩展创建专用架构 monitor
  • 监控扩展:强烈建议启用内置扩展 pg_stat_statements
  • 监控视图:监控视图是可选的,但可以提供额外的指标。推荐使用。

监控用户

在目标数据库集群上创建一个监控用户。例如,Pigsty 中默认使用 dbuser_monitor

CREATE USER dbuser_monitor;                                       -- 创建监控用户
COMMENT ON ROLE dbuser_monitor IS 'system monitor user';          -- 为监控用户添加注释
GRANT pg_monitor TO dbuser_monitor;                               -- 将系统角色 pg_monitor 授予监控用户

ALTER USER dbuser_monitor PASSWORD 'DBUser.Monitor';              -- 为监控用户设置密码
ALTER USER dbuser_monitor SET log_min_duration_statement = 1000;  -- 设置此值以避免日志洪泛
ALTER USER dbuser_monitor SET search_path = monitor,public;       -- 设置此值以避免 pg_stat_statements 扩展不工作

这里的监控用户应该与 Pigsty 配置清单中的 pg_monitor_usernamepg_monitor_password 一致。


监控 HBA

您还需要配置 pg_hba.conf 以允许监控用户从基础设施/管理节点访问。

# 允许本地角色监控使用密码
local   all  dbuser_monitor                    md5
host    all  dbuser_monitor  127.0.0.1/32      md5
host    all  dbuser_monitor  <admin_ip>/32     md5
host    all  dbuser_monitor  <infra_ip>/32     md5

如果您的 RDS 不支持原始 HBA 格式,请将管理/基础设施节点 IP 添加到白名单。


监控架构

监控架构是可选的,但我们强烈推荐创建一个。

CREATE SCHEMA IF NOT EXISTS monitor;               -- 创建专用监控架构
GRANT USAGE ON SCHEMA monitor TO dbuser_monitor;   -- 允许监控用户使用此架构

监控扩展

监控扩展是可选的,但我们强烈推荐启用 pg_stat_statements 扩展。

请注意,此扩展必须列在 shared_preload_libraries 中才能生效,更改此参数需要重启数据库。

CREATE EXTENSION IF NOT EXISTS "pg_stat_statements" WITH SCHEMA "monitor";

您应该在管理数据库中创建此扩展:postgres。如果您的 RDS 不授予数据库 postgresCREATE 权限,您可以在默认的 public 架构中创建该扩展:

CREATE EXTENSION IF NOT EXISTS "pg_stat_statements";
ALTER USER dbuser_monitor SET search_path = monitor,public;

只要您的监控用户可以在没有架构限定的情况下访问 pg_stat_statements 视图,就应该没问题。


监控视图

建议在所有需要监控的数据库中创建监控视图。

监控架构和视图定义

----------------------------------------------------------------------
-- 表膨胀估算:monitor.pg_table_bloat
----------------------------------------------------------------------
DROP VIEW IF EXISTS monitor.pg_table_bloat CASCADE;
CREATE OR REPLACE VIEW monitor.pg_table_bloat AS
SELECT CURRENT_CATALOG AS datname, nspname, relname , tblid , bs * tblpages AS size,
       CASE WHEN tblpages - est_tblpages_ff > 0 THEN (tblpages - est_tblpages_ff)/tblpages::FLOAT ELSE 0 END AS ratio
FROM (
         SELECT ceil( reltuples / ( (bs-page_hdr)*fillfactor/(tpl_size*100) ) ) + ceil( toasttuples / 4 ) AS est_tblpages_ff,
                tblpages, fillfactor, bs, tblid, nspname, relname, is_na
         FROM (
                  SELECT
                      ( 4 + tpl_hdr_size + tpl_data_size + (2 * ma)
                          - CASE WHEN tpl_hdr_size % ma = 0 THEN ma ELSE tpl_hdr_size % ma END
                          - CASE WHEN ceil(tpl_data_size)::INT % ma = 0 THEN ma ELSE ceil(tpl_data_size)::INT % ma END
                          ) AS tpl_size, (heappages + toastpages) AS tblpages, heappages,
                      toastpages, reltuples, toasttuples, bs, page_hdr, tblid, nspname, relname, fillfactor, is_na
                  FROM (
                           SELECT
                               tbl.oid AS tblid, ns.nspname , tbl.relname, tbl.reltuples,
                               tbl.relpages AS heappages, coalesce(toast.relpages, 0) AS toastpages,
                               coalesce(toast.reltuples, 0) AS toasttuples,
                               coalesce(substring(array_to_string(tbl.reloptions, ' ') FROM 'fillfactor=([0-9]+)')::smallint, 100) AS fillfactor,
                               current_setting('block_size')::numeric AS bs,
                               CASE WHEN version()~'mingw32' OR version()~'64-bit|x86_64|ppc64|ia64|amd64' THEN 8 ELSE 4 END AS ma,
                               24 AS page_hdr,
                               23 + CASE WHEN MAX(coalesce(s.null_frac,0)) > 0 THEN ( 7 + count(s.attname) ) / 8 ELSE 0::int END
                                   + CASE WHEN bool_or(att.attname = 'oid' and att.attnum < 0) THEN 4 ELSE 0 END AS tpl_hdr_size,
                               sum( (1-coalesce(s.null_frac, 0)) * coalesce(s.avg_width, 0) ) AS tpl_data_size,
                               bool_or(att.atttypid = 'pg_catalog.name'::regtype)
                                   OR sum(CASE WHEN att.attnum > 0 THEN 1 ELSE 0 END) <> count(s.attname) AS is_na
                           FROM pg_attribute AS att
                                    JOIN pg_class AS tbl ON att.attrelid = tbl.oid
                                    JOIN pg_namespace AS ns ON ns.oid = tbl.relnamespace
                                    LEFT JOIN pg_stats AS s ON s.schemaname=ns.nspname AND s.tablename = tbl.relname AND s.inherited=false AND s.attname=att.attname
                                    LEFT JOIN pg_class AS toast ON tbl.reltoastrelid = toast.oid
                           WHERE NOT att.attisdropped AND tbl.relkind = 'r' AND nspname NOT IN ('pg_catalog','information_schema')
                           GROUP BY 1,2,3,4,5,6,7,8,9,10
                       ) AS s
              ) AS s2
     ) AS s3
WHERE NOT is_na;
COMMENT ON VIEW monitor.pg_table_bloat IS 'postgres table bloat estimate';

GRANT SELECT ON monitor.pg_table_bloat TO pg_monitor;

----------------------------------------------------------------------
-- 索引膨胀估算:monitor.pg_index_bloat
----------------------------------------------------------------------
DROP VIEW IF EXISTS monitor.pg_index_bloat CASCADE;
CREATE OR REPLACE VIEW monitor.pg_index_bloat AS
SELECT CURRENT_CATALOG AS datname, nspname, idxname AS relname, tblid, idxid, relpages::BIGINT * bs AS size,
       COALESCE((relpages - ( reltuples * (6 + ma - (CASE WHEN index_tuple_hdr % ma = 0 THEN ma ELSE index_tuple_hdr % ma END)
                                               + nulldatawidth + ma - (CASE WHEN nulldatawidth % ma = 0 THEN ma ELSE nulldatawidth % ma END))
                                  / (bs - pagehdr)::FLOAT  + 1 )), 0) / relpages::FLOAT AS ratio
FROM (
         SELECT nspname,idxname,indrelid AS tblid,indexrelid AS idxid,
                reltuples,relpages,
                current_setting('block_size')::INTEGER                                                               AS bs,
                (CASE WHEN version() ~ 'mingw32' OR version() ~ '64-bit|x86_64|ppc64|ia64|amd64' THEN 8 ELSE 4 END)  AS ma,
                24                                                                                                   AS pagehdr,
                (CASE WHEN max(COALESCE(pg_stats.null_frac, 0)) = 0 THEN 2 ELSE 6 END)                               AS index_tuple_hdr,
                sum((1.0 - COALESCE(pg_stats.null_frac, 0.0)) *
                    COALESCE(pg_stats.avg_width, 1024))::INTEGER                                                     AS nulldatawidth
         FROM pg_attribute
                  JOIN (
             SELECT pg_namespace.nspname,
                    ic.relname                                                   AS idxname,
                    ic.reltuples,
                    ic.relpages,
                    pg_index.indrelid,
                    pg_index.indexrelid,
                    tc.relname                                                   AS tablename,
                    regexp_split_to_table(pg_index.indkey::TEXT, ' ') :: INTEGER AS attnum,
                    pg_index.indexrelid                                          AS index_oid
             FROM pg_index
                      JOIN pg_class ic ON pg_index.indexrelid = ic.oid
                      JOIN pg_class tc ON pg_index.indrelid = tc.oid
                      JOIN pg_namespace ON pg_namespace.oid = ic.relnamespace
                      JOIN pg_am ON ic.relam = pg_am.oid
             WHERE pg_am.amname = 'btree' AND ic.relpages > 0 AND nspname NOT IN ('pg_catalog', 'information_schema')
         ) ind_atts ON pg_attribute.attrelid = ind_atts.indexrelid AND pg_attribute.attnum = ind_atts.attnum
                  JOIN pg_stats ON pg_stats.schemaname = ind_atts.nspname
             AND ((pg_stats.tablename = ind_atts.tablename AND pg_stats.attname = pg_get_indexdef(pg_attribute.attrelid, pg_attribute.attnum, TRUE))
                 OR (pg_stats.tablename = ind_atts.idxname AND pg_stats.attname = pg_attribute.attname))
         WHERE pg_attribute.attnum > 0
         GROUP BY 1, 2, 3, 4, 5, 6
     ) est;
COMMENT ON VIEW monitor.pg_index_bloat IS 'postgres index bloat estimate (btree-only)';

GRANT SELECT ON monitor.pg_index_bloat TO pg_monitor;

----------------------------------------------------------------------
-- 关系膨胀:monitor.pg_bloat
----------------------------------------------------------------------
DROP VIEW IF EXISTS monitor.pg_bloat CASCADE;
CREATE OR REPLACE VIEW monitor.pg_bloat AS
SELECT coalesce(ib.datname, tb.datname)                                                   AS datname,
       coalesce(ib.nspname, tb.nspname)                                                   AS nspname,
       coalesce(ib.tblid, tb.tblid)                                                       AS tblid,
       coalesce(tb.nspname || '.' || tb.relname, ib.nspname || '.' || ib.tblid::RegClass) AS tblname,
       tb.size                                                                            AS tbl_size,
       CASE WHEN tb.ratio < 0 THEN 0 ELSE round(tb.ratio::NUMERIC, 6) END                 AS tbl_ratio,
       (tb.size * (CASE WHEN tb.ratio < 0 THEN 0 ELSE tb.ratio::NUMERIC END)) ::BIGINT    AS tbl_wasted,
       ib.idxid,
       ib.nspname || '.' || ib.relname                                                    AS idxname,
       ib.size                                                                            AS idx_size,
       CASE WHEN ib.ratio < 0 THEN 0 ELSE round(ib.ratio::NUMERIC, 5) END                 AS idx_ratio,
       (ib.size * (CASE WHEN ib.ratio < 0 THEN 0 ELSE ib.ratio::NUMERIC END)) ::BIGINT    AS idx_wasted
FROM monitor.pg_index_bloat ib
         FULL OUTER JOIN monitor.pg_table_bloat tb ON ib.tblid = tb.tblid;

COMMENT ON VIEW monitor.pg_bloat IS 'postgres relation bloat detail';
GRANT SELECT ON monitor.pg_bloat TO pg_monitor;

----------------------------------------------------------------------
-- monitor.pg_index_bloat_human
----------------------------------------------------------------------
DROP VIEW IF EXISTS monitor.pg_index_bloat_human CASCADE;
CREATE OR REPLACE VIEW monitor.pg_index_bloat_human AS
SELECT idxname                            AS name,
       tblname,
       idx_wasted                         AS wasted,
       pg_size_pretty(idx_size)           AS idx_size,
       round(100 * idx_ratio::NUMERIC, 2) AS idx_ratio,
       pg_size_pretty(idx_wasted)         AS idx_wasted,
       pg_size_pretty(tbl_size)           AS tbl_size,
       round(100 * tbl_ratio::NUMERIC, 2) AS tbl_ratio,
       pg_size_pretty(tbl_wasted)         AS tbl_wasted
FROM monitor.pg_bloat
WHERE idxname IS NOT NULL;
COMMENT ON VIEW monitor.pg_index_bloat_human IS 'postgres index bloat info in human-readable format';
GRANT SELECT ON monitor.pg_index_bloat_human TO pg_monitor;


----------------------------------------------------------------------
-- monitor.pg_table_bloat_human
----------------------------------------------------------------------
DROP VIEW IF EXISTS monitor.pg_table_bloat_human CASCADE;
CREATE OR REPLACE VIEW monitor.pg_table_bloat_human AS
SELECT tblname                                          AS name,
       idx_wasted + tbl_wasted                          AS wasted,
       pg_size_pretty(idx_wasted + tbl_wasted)          AS all_wasted,
       pg_size_pretty(tbl_wasted)                       AS tbl_wasted,
       pg_size_pretty(tbl_size)                         AS tbl_size,
       tbl_ratio,
       pg_size_pretty(idx_wasted)                       AS idx_wasted,
       pg_size_pretty(idx_size)                         AS idx_size,
       round(idx_wasted::NUMERIC * 100.0 / idx_size, 2) AS idx_ratio
FROM (SELECT datname,
             nspname,
             tblname,
             coalesce(max(tbl_wasted), 0)                         AS tbl_wasted,
             coalesce(max(tbl_size), 1)                           AS tbl_size,
             round(100 * coalesce(max(tbl_ratio), 0)::NUMERIC, 2) AS tbl_ratio,
             coalesce(sum(idx_wasted), 0)                         AS idx_wasted,
             coalesce(sum(idx_size), 1)                           AS idx_size
      FROM monitor.pg_bloat
      WHERE tblname IS NOT NULL
      GROUP BY 1, 2, 3
     ) d;
COMMENT ON VIEW monitor.pg_table_bloat_human IS 'postgres table bloat info in human-readable format';
GRANT SELECT ON monitor.pg_table_bloat_human TO pg_monitor;


----------------------------------------------------------------------
-- 活动概览:monitor.pg_session
----------------------------------------------------------------------
DROP VIEW IF EXISTS monitor.pg_session CASCADE;
CREATE OR REPLACE VIEW monitor.pg_session AS
SELECT coalesce(datname, 'all') AS datname, numbackends, active, idle, ixact, max_duration, max_tx_duration, max_conn_duration
FROM (
         SELECT datname,
                count(*)                                         AS numbackends,
                count(*) FILTER ( WHERE state = 'active' )       AS active,
                count(*) FILTER ( WHERE state = 'idle' )         AS idle,
                count(*) FILTER ( WHERE state = 'idle in transaction'
                    OR state = 'idle in transaction (aborted)' ) AS ixact,
                max(extract(epoch from now() - state_change))
                FILTER ( WHERE state = 'active' )                AS max_duration,
                max(extract(epoch from now() - xact_start))      AS max_tx_duration,
                max(extract(epoch from now() - backend_start))   AS max_conn_duration
         FROM pg_stat_activity
         WHERE backend_type = 'client backend'
           AND pid <> pg_backend_pid()
         GROUP BY ROLLUP (1)
         ORDER BY 1 NULLS FIRST
     ) t;
COMMENT ON VIEW monitor.pg_session IS 'postgres activity group by session';
GRANT SELECT ON monitor.pg_session TO pg_monitor;


----------------------------------------------------------------------
-- 顺序扫描:monitor.pg_seq_scan
----------------------------------------------------------------------
DROP VIEW IF EXISTS monitor.pg_seq_scan CASCADE;
CREATE OR REPLACE VIEW monitor.pg_seq_scan AS
SELECT schemaname                                                        AS nspname,
       relname,
       seq_scan,
       seq_tup_read,
       seq_tup_read / seq_scan                                           AS seq_tup_avg,
       idx_scan,
       n_live_tup + n_dead_tup                                           AS tuples,
       round(n_live_tup * 100.0::NUMERIC / (n_live_tup + n_dead_tup), 2) AS live_ratio
FROM pg_stat_user_tables
WHERE seq_scan > 0
  and (n_live_tup + n_dead_tup) > 0
ORDER BY seq_scan DESC;
COMMENT ON VIEW monitor.pg_seq_scan IS 'table that have seq scan';
GRANT SELECT ON monitor.pg_seq_scan TO pg_monitor;

11.7 - 答疑

常见问题解答

因 postgres 存在而中止

当您在运行 PostgreSQL 的节点上运行 pgsql.yml 时会发生这种情况。 如果有正在运行的 PostgreSQL 实例,您可以使用 pgsql-rm.yml 剧本显式移除它:

./pgsql-rm.yml -l <cls_to_remove>    # 移除集群 'cls_to_remove'

因启用 pg_safeguard 而中止

禁用 pg_safeguard 以移除 PostgreSQL 实例。

如果启用了 pg_safeguard,您无法使用 bin/pgsql-rmpgsql-rm.yml 剧本移除正在运行的 PostgreSQL 实例。

要禁用 pg_safeguard,您可以在配置清单中将 pg_safeguard 设置为 false,或将 -e pg_safeguard=false 作为命令行参数传递给剧本:

./pgsql-rm.yml -e pg_safeguard=false -l <cls_to_remove>    # 强制覆盖 pg_safeguard

等待 postgres/patroni 主库失败

这个错误有几个可能的原因,您需要 检查 系统日志来确定实际原因。

这通常发生在集群配置错误,或者之前的主库被不当移除时(例如,DCS 中有相同集群名称的垃圾元数据)。

您必须检查 /pg/log/* 以找到原因。

要从 etcd 删除垃圾元数据,您可以使用 etcdctl del --prefix /pg/<cls>,操作时请谨慎!

  • 1:配置错误。识别不正确的参数,修改它们并应用更改。
  • 2:部署中已存在同名的另一个集群
  • 3:节点上的之前集群,或同名的之前集群未正确移除。
  • 要移除过时的集群元数据,您可以使用 etcdctl del --prefix /pg/<cls> 手动删除残留数据。
  • 4:与您的 PostgreSQL 或节点相关的 RPM 包未成功安装。
  • 5:您的 Watchdog 内核模块未正确启用或加载,但是必需的。
  • 6:指定的语言环境或字符类型 pg_lc_collatepg_lc_ctype 在操作系统中不存在

请随时提交问题或寻求社区帮助。


等待 postgres/patroni 从库失败

立即失败:通常,这是由于配置错误、网络问题、DCS 元数据损坏等导致的,您必须检查 /pg/log 以找出实际原因。

一段时间后失败:这可能是由于源实例数据损坏。查看 PGSQL 常见问题:数据损坏时如何创建从库?

超时:如果 wait for postgres replica 任务需要 30 分钟或更长时间并因超时而失败,这对于大型集群(例如 1TB+,可能需要数小时才能创建从库)是常见的。在这种情况下,底层创建从库过程仍在进行。您可以使用 pg list <cls> 检查集群状态,等待从库追上主库。然后继续以下任务:

./pgsql.yml -t pg_hba,pg_param,pg_backup,pgbouncer,pg_vip,pg_dns,pg_service,pg_exporter,pg_register -l <problematic_replica>

安装 PostgreSQL 13 - 17

要安装 PostgreSQL 13 ~ 17,您必须在配置清单中将 pg_version 设置为 1314151617。(通常在集群级别设置)

pg_version: 16                    # 在此模板中安装 PostgreSQL 16

如何为 PostgreSQL 启用大页面?

使用 node_hugepage_countnode_hugepage_ratio/pg/bin/pg-tune-hugepage

如果您计划启用大页面,请考虑使用 node_hugepage_countnode_hugepage_ratio 并使用 ./node.yml -t node_tune 应用。

在 PostgreSQL 启动之前分配足够的大页面是好的做法,然后使用 pg_tune_hugepage 稍后缩减它们。

如果您的 PostgreSQL 已经在运行,您可以使用 /pg/bin/pg-tune-hugepage 即时启用大页面。请注意,这仅适用于 PostgreSQL 15+

sync; echo 3 > /proc/sys/vm/drop_caches   # 丢弃系统缓存(准备承受性能影响)
sudo /pg/bin/pg-tune-hugepage             # 将 nr_hugepages 写入 /etc/sysctl.d/hugepage.conf
pg restart <cls>                          # 重启 PostgreSQL 以使用大页面

如何在故障转移期间保证零数据丢失?

使用 crit.yml 模板,或设置 pg_rpo0,或使用同步模式 配置集群

考虑使用 同步从库法定人数提交 来保证故障转移期间 0 数据丢失。


如何从磁盘满的情况中恢复?

rm -rf /pg/dummy 将释放一些紧急空间。

pg_dummy_filesize 默认设置为 64MB。考虑在生产环境中将其增加到 8GB 或更大。

它将被放置在与 PGSQL 主数据磁盘相同的磁盘上的 /pg/dummy 中。您可以删除该文件以释放一些紧急空间。至少您可以在该节点上运行一些 shell 脚本。


数据损坏时如何创建从库?

在坏实例上禁用 clonefrom 并重新加载 patroni 配置。

Pigsty 在所有实例的 patroni 配置上设置 cloneform: true 标签,这标记实例可用于克隆从库。

如果此实例有损坏的数据文件,您可以设置 clonefrom: false 以避免从有问题的实例拉取数据。具体操作如下:

$ vi /pg/bin/patroni.yml

tags:
  nofailover: false
  clonefrom: true      # ----------> 改为 false
  noloadbalance: false
  nosync: false
  version:  '15'
  spec: '4C.8G.50G'
  conf: 'oltp.yml'

$ systemctl reload patroni

数据损坏时如何创建从库?

在坏实例上禁用 clonefrom 并重新加载 patroni 配置。

Pigsty 在所有实例的 patroni 配置上设置 cloneform: true 标签,这标记实例可用于克隆从库。

如果此实例有损坏的数据文件,您可以设置 clonefrom: false 以避免从有问题的实例拉取数据。具体操作如下:

$ vi /pg/bin/patroni.yml

tags:
  nofailover: false
  clonefrom: true      # ----------> 改为 false
  noloadbalance: false
  nosync: false
  version:  '15'
  spec: '4C.8G.50G'
  conf: 'oltp.yml'

$ systemctl reload patroni

监控导出器的性能影响

影响不大,每 10 ~ 15 秒 200ms,不会影响数据库性能。

Pigsty 中 prometheus 的默认抓取间隔为 10 秒,确保导出器可以在该时间段内完成抓取。


如何监控现有的 PostgreSQL 实例?

详情请查看 PGSQL 监控


如何从 prometheus 中移除监控目标?

./pgsql-rm.yml -t prometheus -l <cls>     # 移除集群 'cls' 的 prometheus 目标

或者

bin/pgmon-rm <ins>     # 移除 PostgreSQL 实例 'ins' 的 prometheus 目标的快捷方式

11.8 - 用户

在此上下文中,用户是指通过 SQL CREATE USER / ROLE 创建的逻辑对象

您可以使用 Pigsty 以 IaC 方式管理 PostgreSQL 用户和角色。


定义用户

您可以使用以下参数定义角色/用户,它们都是由用户对象组成的数组:

  • pg_users:在集群级别定义业务用户和角色(集群定义
  • pg_default_roles:定义系统范围的角色和全局用户(全局默认值

前者定义整个环境中共享的全局角色和用户,后者定义特定于单个集群的业务角色和用户。 以下是一些用户定义的示例:

pg-meta:
  hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
  vars:
    pg_cluster: pg-meta
    pg_databases:
      - {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 }
      - {name: dbuser_grafana  ,password: DBUser.Grafana  ,pgbouncer: true ,roles: [dbrole_admin]    ,comment: admin user for grafana database    }
      - {name: dbuser_bytebase ,password: DBUser.Bytebase ,pgbouncer: true ,roles: [dbrole_admin]    ,comment: admin user for bytebase database   }
      - {name: dbuser_kong     ,password: DBUser.Kong     ,pgbouncer: true ,roles: [dbrole_admin]    ,comment: admin user for kong api gateway    }
      - {name: dbuser_gitea    ,password: DBUser.Gitea    ,pgbouncer: true ,roles: [dbrole_admin]    ,comment: admin user for gitea service       }
      - {name: dbuser_wiki     ,password: DBUser.Wiki     ,pgbouncer: true ,roles: [dbrole_admin]    ,comment: admin user for wiki.js service     }
      - {name: dbuser_noco     ,password: DBUser.Noco     ,pgbouncer: true ,roles: [dbrole_admin]    ,comment: admin user for nocodb service      }

用户属性

您可以使用更多属性自定义用户,完整示例如下:

- name: dbuser_meta           # 必需,`name` 是用户定义的唯一必填字段
  password: DBUser.Meta       # 可选,密码,可以是 scram-sha-256 哈希字符串或明文
  login: true                 # 可选,可以登录,默认为 true(新业务角色应该为 false)
  superuser: false            # 可选,是超级用户吗?默认为 false
  createdb: false             # 可选,可以创建数据库吗?默认为 false
  createrole: false           # 可选,可以创建角色吗?默认为 false
  inherit: true               # 可选,此角色可以使用继承的权限吗?默认为 true
  replication: false          # 可选,此角色可以进行复制吗?默认为 false
  bypassrls: false            # 可选,此角色可以绕过行级安全吗?默认为 false
  pgbouncer: true             # 可选,将此用户添加到 pgbouncer 用户列表?默认为 false(生产用户应明确设置为 true)
  connlimit: -1               # 可选,用户连接限制,默认 -1 禁用限制
  expire_in: 3650             # 可选,现在 + n 天后此角色过期(覆盖 expire_at)
  expire_at: '2030-12-31'     # 可选,YYYY-MM-DD '时间戳',此角色过期时间(被 expire_in 覆盖)
  comment: pigsty admin user  # 可选,此用户/角色的注释字符串
  roles: [dbrole_admin]       # 可选,所属角色。默认角色有:dbrole_{admin,readonly,readwrite,offline}
  parameters: {}              # 可选,使用 `ALTER ROLE SET` 的角色级别参数
  pool_mode: transaction      # 可选,用户级别的 pgbouncer 池模式,默认为 transaction
  pool_connlimit: -1          # 可选,用户级别的最大数据库连接数,默认 -1 禁用限制
  search_path: public         # 键值配置参数,根据 postgresql 文档(例如:使用 pigsty 作为默认 search_path)
  • 唯一必需的字段是 name,它应该是 PostgreSQL 中有效且唯一的用户名。
  • 角色不需要 password,但对于可登录用户可能是必需的。
  • password 可以是明文或 scram-sha-256 / md5 哈希字符串。
  • 用户/角色定义顺序很重要,pg_default_roles 在前,pg_users 在后,按顺序排列。
  • 确保角色/组定义在其成员之前。
  • 角色属性loginsuperusercreatedbcreateroleinheritreplicationbypassrls
  • pgbouncer 默认禁用。明确设置为 true 以在 pgbouncer 中启用它。

ACL 系统

Pigsty 具有电池包含的 ACL 系统,可以通过将角色分配给用户来轻松使用:

  • dbrole_readonly:全局只读访问角色
  • dbrole_readwrite:全局读写访问角色
  • dbrole_admin:对象创建角色
  • dbrole_offline:受限只读访问角色(离线实例)

如果您希望重新设计您的 ACL 系统,请检查以下参数和 SQL 模板。


创建用户

pg_default_rolespg_users 中定义的用户和角色将在模块安装期间逐一自动创建。 它只在集群领导者,即主实例上运行。

要在现有集群上创建用户, 将新用户/角色定义添加到 all.children.<cls>.pg_users,并使用 bin/pgsql-user 工具或 pgsql-user.yml playbook 创建数据库:

bin/pgsql-user <cls>   <dbname>         # bin 工具脚本
bin/pgsql-user pg-meta dbuser_meta      # 示例:在 pg-meta 集群中创建 dbuser_meta 用户
./pgsql-user.yml -l <cls>   -e username=<dbname> # 实际 playbook
./pgsql-user.yml -l pg-meta -e username=meta     # 示例:在 pg-meta 集群中创建 dbuser_meta 用户

创建用户是幂等操作,意味着可以多次安全运行。

使用 Pigsty 创建用户/角色

Pigsty 将管理 pgbouncer 用户列表,因此请使用 Pigsty playbook/工具创建业务数据库。 查看创建用户 SOP 了解详细信息。 如果您不使用 pgbouncer 或能够自己维护它,您可以以任何您喜欢的方式创建用户。

在创建数据库之前创建所有者用户

在 PostgreSQL 中,用户属于数据库集群,而不是特定数据库。

如果您的用户是任何数据库的所有者,请确保在创建数据库之前创建用户。


修改用户

修改 PostgreSQL 用户属性与创建用户相同。 通过修改配置清单调整您的用户定义,然后重新运行创建用户

有两个例外:nameroles,需要手动干预:

Pigsty 不直接支持重命名用户

用户名用作用户的标识,因此如果您真的想这样做,请使用标准 SQL:

ALTER USER "old_name" RENAME TO "new_name";
Pigsty 不会撤销成员资格

请注意,修改用户不会删除用户,而是使用 ALTER USER 命令修改用户属性。 它也不会撤销用户权限和组成员资格,并使用 GRANT 命令授予新角色。

查看 PostgreSQL 文档了解更多关于 ALTER USER 的详细信息。


删除用户

出于安全原因,Pigsty 不会自动删除用户,即使您从配置中删除用户定义,Pigsty 也不会删除现有用户。

您需要使用 SQL 命令 DROP USER 手动删除用户:

DROP USER "<username>";

如果您要删除的角色是一个组(有其他用户属于它),您需要首先从组中删除其他用户,然后再删除组:

REVOKE "<rolename>" FROM "<other_user>";

如果您要删除的用户拥有数据库对象,您需要首先将这些对象的所有权更改为另一个用户,然后再删除用户:

REASSIGN OWNED BY "<username>" TO "<another_user>";

查看 PostgreSQL 文档了解更多关于 DROP USERREASSIGN OWNEDREVOKE 的详细信息。


Pgbouncer 用户

Pigsty 帮助管理 pgbouncer 用户列表中的用户,并使其与 postgres 保持同步。 它需要在用户定义中明确设置 pgbouncer: true 标志以注册到 pgbouncer 用户列表中。

系统管理员用户(pg_admin_username)和监控用户(pg_monitor_username) 将始终添加到 pgbouncer 用户列表中用于管理和监控。

配置文件

Pgbouncer 连接池中的用户列在 /etc/pgbouncer/userlist.txt 中,示例:

/etc/pgbouncer/userlist.txt
"postgres" ""
"dbuser_wiki" "SCRAM-SHA-256$4096:+77dyhrPeFDT/TptHs7/7Q==$KeatuohpKIYzHPCt/tqBu85vI11o9mar/by0hHYM2W8=:X9gig4JtjoS8Y/o1vQsIX/gY1Fns8ynTXkbWOjUfbRQ="
"dbuser_view" "SCRAM-SHA-256$4096:DFoZHU/DXsHL8MJ8regdEw==$gx9sUGgpVpdSM4o6A2R9PKAUkAsRPLhLoBDLBUYtKS0=:MujSgKe6rxcIUMv4GnyXJmV0YNbf39uFRZv724+X1FE="
"dbuser_monitor" "SCRAM-SHA-256$4096:fwU97ZMO/KR0ScHO5+UuBg==$CrNsmGrx1DkIGrtrD1Wjexb/aygzqQdirTO1oBZROPY=:L8+dJ+fqlMQh7y4PmVR/gbAOvYWOr+KINjeMZ8LlFww="
"dbuser_meta" "SCRAM-SHA-256$4096:leB2RQPcw1OIiRnPnOMUEg==$eyC+NIMKeoTxshJu314+BmbMFpCcspzI3UFZ1RYfNyU=:fJgXcykVPvOfro2MWNkl5q38oz21nSl1dTtM65uYR1Q="
"dbuser_kong" "SCRAM-SHA-256$4096:bK8sLXIieMwFDz67/0dqXQ==$P/tCRgyKx9MC9LH3ErnKsnlOqgNd/nn2RyvThyiK6e4=:CDM8QZNHBdPf97ztusgnE7olaKDNHBN0WeAbP/nzu5A="
"dbuser_grafana" "SCRAM-SHA-256$4096:HjLdGaGmeIAGdWyn2gDt/Q==$jgoyOB8ugoce+Wqjr0EwFf8NaIEMtiTuQTg1iEJs9BM=:ed4HUFqLyB4YpRr+y25FBT7KnlFDnan6JPVT9imxzA4="
"dbuser_gitea" "SCRAM-SHA-256$4096:l1DBGCc4dtircZ8O8Fbzkw==$tpmGwgLuWPDog8IEKdsaDGtiPAxD16z09slvu+rHE74=:pYuFOSDuWSofpD9OZhG7oWvyAR0PQjJBffgHZLpLHds="
"dbuser_dba" "SCRAM-SHA-256$4096:zH8niABU7xmtblVUo2QFew==$Zj7/pq+ICZx7fDcXikiN7GLqkKFA+X5NsvAX6CMshF0=:pqevR2WpizjRecPIQjMZOm+Ap+x0kgPL2Iv5zHZs0+g="
"dbuser_bytebase" "SCRAM-SHA-256$4096:OMoTM9Zf8QcCCMD0svK5gg==$kMchqbf4iLK1U67pVOfGrERa/fY818AwqfBPhsTShNQ=:6HqWteN+AadrUnrgC0byr5A72noqnPugItQjOLFw0Wk="

用户级别参数在单独的文件中维护:/etc/pgbouncer/useropts.txt,示例:

/etc/pgbouncer/useropts.txt
dbuser_dba                  = pool_mode=session max_user_connections=16
dbuser_monitor              = pool_mode=session max_user_connections=8

当您创建用户时,userlist.txtuseropts.txt 将自动刷新 并通过 systemctl reload pgbouncer 生效,通常不会影响现有连接。

重新加载

要重新加载 pgbouncer 配置,您可以使用 ansible playbook 或 systemctl 命令

./pgsql.yml -t pgbouncer_reload
systemctl reload pgbouncer

管理

Pgbouncer 与 PostgreSQL 使用相同的 dbsu 运行,默认为 postgres 操作系统用户。 您可以使用 pgb 别名通过 dbsu 访问 pgbouncer 管理功能。

postgres
sudo su - postgres
pgb   # 使用管理员用户登录到 pgbouncer 命令行界面

删除 Pgbouncer 用户

如果所有数据库用户都由 Pigsty 管理,您可以重新生成 pgbouncer 用户列表(在配置清单的列表中不包含已删除的用户)并重新加载它:

./pgsql.yml -t pgbouncer_user,pgbouncer_reload -e pg_reload=true

要手动从 pgbouncer 池中删除用户,只需从 /etc/pgbouncer/userlist.txt 中删除相应的行并重新加载 pgbouncer:

systemctl reload pgbouncer

动态用户认证

请注意,pgbouncer_auth_query 参数允许您使用动态查询完成连接池用户认证,这是当您不想在连接池中管理用户时的一种折衷方案。

11.9 - 数据库

在此上下文中,数据库是指由 SQL CREATE DATABASE 创建的对象。

一个 PostgreSQL 服务器可以同时服务多个数据库。您可以使用 Pigsty 来管理它们。


定义数据库

业务数据库由 pg_databases 定义,这是一个集群级参数。

例如,默认的 meta 数据库在 pg-meta 集群中定义:

pg-meta:
  hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
  vars:
    pg_cluster: pg-meta
    pg_databases:
      - { name: meta ,baseline: cmdb.sql ,comment: pigsty meta database ,schemas: [pigsty] ,extensions: [{name: postgis, schema: public}, {name: timescaledb}]}
      - { name: grafana  ,owner: dbuser_grafana  ,revokeconn: true ,comment: grafana primary database }
      - { name: bytebase ,owner: dbuser_bytebase ,revokeconn: true ,comment: bytebase primary database }
      - { name: kong     ,owner: dbuser_kong     ,revokeconn: true ,comment: kong the api gateway database }
      - { name: gitea    ,owner: dbuser_gitea    ,revokeconn: true ,comment: gitea meta database }
      - { name: wiki     ,owner: dbuser_wiki     ,revokeconn: true ,comment: wiki meta database }
      - { name: noco     ,owner: dbuser_noco     ,revokeconn: true ,comment: nocodb database }

每个数据库定义是一个包含以下字段的字典:

- name: meta                      # 必需,`name` 是数据库定义的唯一必需字段
  baseline: cmdb.sql              # 可选,数据库 SQL 基线路径(ansible 搜索路径中的相对路径,例如 files/)
  pgbouncer: true                 # 可选,将此数据库添加到 pgbouncer 数据库列表?默认为 true
  schemas: [pigsty]               # 可选,要创建的额外模式,模式名称数组
  extensions:                     # 可选,要安装的额外扩展:`{name[,schema]}` 数组
    - { name: postgis , schema: public }
    - { name: timescaledb }
  comment: pigsty meta database   # 可选,此数据库的注释字符串
  owner: postgres                 # 可选,数据库拥有者,默认为 postgres
  template: template1             # 可选,使用哪个模板,默认为 template1
  encoding: UTF8                  # 可选,数据库编码,默认为 UTF8(必须与模板数据库相同)
  locale: C                       # 可选,数据库区域设置,默认为 C(必须与模板数据库相同)
  lc_collate: C                   # 可选,数据库排序规则,默认为 C(必须与模板数据库相同)
  lc_ctype: C                     # 可选,数据库字符分类,默认为 C(必须与模板数据库相同)
  tablespace: pg_default          # 可选,默认表空间,默认为 'pg_default'
  allowconn: true                 # 可选,允许连接,默认为 true。false 将完全禁用连接
  revokeconn: false               # 可选,撤销公共连接权限。默认为 false(将连接权限留给拥有者并授予授权选项)
  register_datasource: true       # 可选,将此数据库注册到 grafana 数据源?默认为 true
  connlimit: -1                   # 可选,数据库连接限制,默认 -1 禁用限制
  pool_auth_user: dbuser_meta     # 可选,所有到此 pgbouncer 数据库的连接都将由此用户认证
  pool_mode: transaction          # 可选,数据库级别的 pgbouncer 池模式,默认为 transaction
  pool_size: 64                   # 可选,数据库级别的 pgbouncer 池大小,默认为 64
  pool_size_reserve: 32           # 可选,数据库级别的 pgbouncer 池保留大小,默认为 32
  pool_size_min: 0                # 可选,数据库级别的 pgbouncer 池最小大小,默认为 0
  pool_max_db_conn: 100           # 可选,数据库级别的最大数据库连接数,默认为 100

唯一必需的字段是 name,它应该是 PostgreSQL 中有效且唯一的数据库名称。

新创建的数据库默认从 template1 数据库分叉。该模板在集群引导期间由 PG_PROVISION 自定义。

有关数据库级权限的详细信息,请查看 ACL:数据库权限


创建数据库

pg_databases定义 的数据库将在模块安装期间自动创建。 如果您希望在现有集群上 创建数据库,可以使用 bin/pgsql-db 工具。

将新的数据库定义添加到 all.children.<cls>.pg_databases,然后使用以下命令创建该数据库:

bin/pgsql-db <cls> <dbname>    # bin 工具脚本
bin/pgsql-db pg-meta meta      # 示例:在 pg-meta 集群中创建 meta 数据库
./pgsql-db.yml -l <cls> -e dbname=<dbname>    # 实际的剧本
./pgsql-db.yml -l pg-meta -e dbname=meta      # 示例:在 pg-meta 集群中创建 meta 数据库

此剧本通常是幂等的,可以重新运行以刷新数据库定义。 但如果您有复杂的 baseline 模式(如删除操作),则不应在现有数据库上重新运行此剧本。

使用 pigsty 创建 postgres 数据库

Pigsty 将管理 pgbouncer 数据库列表,因此请使用 Pigsty 剧本/工具创建业务数据库。 详情请查看 创建数据库 标准操作程序。 如果您不使用 pgbouncer 或能够自己维护它,可以使用任何方式创建数据库。

创建数据库前先创建拥有者

如果您的数据库有非默认的 owner(默认为数据库超级用户 postgres),请确保拥有者用户在创建数据库之前已存在。 简而言之,始终在创建数据库之前 创建 用户


Pgbouncer 数据库

Pgbouncer 默认启用并充当连接池中间件。

Pigsty 默认将 pg_databases 中的所有数据库添加到 pgbouncer 数据库列表。 您可以通过在数据库 定义 中设置 pgbouncer: false 来禁用特定数据库的 pgbouncer 代理。

使用 Pigsty 工具和剧本 创建数据库 时,Pgbouncer 数据库列表将被更新。 数据库在 /etc/pgbouncer/database.txt 中列出,带有额外的数据库级参数:

/etc/pgbouncer/database.txt
meta     = host=/var/run/postgresql mode=session
grafana  = host=/var/run/postgresql mode=transaction
bytebase = host=/var/run/postgresql auth_user=dbuser_meta
kong     = host=/var/run/postgresql pool_size=32 reserve_pool=64
gitea    = host=/var/run/postgresql min_pool_size=10
wiki     = host=/var/run/postgresql
noco     = host=/var/run/postgresql
mongo    = host=/var/run/postgresql

当您 创建数据库 时,Pgbouncer 数据库列表定义文件将被刷新并通过在线配置重载生效,不会影响现有连接。

要访问 pgbouncer 管理功能,您可以以数据库超级用户(postgres)身份使用 pgb 别名。 查看 pgbouncer 使用方法 了解可用命令:

postgres
sudo su - postgres  # 切换到 postgres 数据库超级用户
pgb                 # 访问 pgbouncer 管理虚拟数据库

/etc/profile.d/pg-alias.sh 中定义了一个工具函数,允许您快速将 pgbouncer 数据库流量重新路由到新主机,可用于零停机时间迁移。

/etc/profile.d/pg-alias.sh
# 将 pgbouncer 流量路由到另一个集群成员
function pgb-route(){
  local ip=${1-'\/var\/run\/postgresql'}
  sed -ie "s/host=[^[:space:]]\+/host=${ip}/g" /etc/pgbouncer/pgbouncer.ini
  cat /etc/pgbouncer/pgbouncer.ini
}

11.10 - 服务

通过负载均衡、代理、连接池提供可靠的服务访问

服务实现

在 Pigsty 中,服务通过节点上的 haproxy 实现,通过主机节点上的不同端口来区分。

每个节点都启用了 Haproxy 来暴露服务。从数据库角度来看,集群中的节点可能是主节点或副本节点,但从服务角度来看,所有节点都是相同的。这意味着即使您访问副本节点,只要使用正确的服务端口,您仍然可以使用主节点的读写服务。这种设计封装了复杂性:只要您能访问 PostgreSQL 集群上的任何实例,就可以完全访问所有服务。

这种设计类似于 Kubernetes 中的 NodePort 服务。同样,在 Pigsty 中,每个服务都包含这两个核心元素:

  1. 通过 NodePort 暴露的访问端点(端口号,从哪里访问?)
  2. 通过选择器选择的目标实例(实例列表,谁来处理?)

Pigsty 服务交付的边界止于集群的 HAProxy。用户可以通过各种方式访问这些负载均衡器。请参考访问服务

所有服务都通过配置文件声明。例如,默认的 PostgreSQL 服务由 pg_default_services 参数定义:

- { name: primary ,port: 5433 ,dest: default  ,check: /primary   ,selector: "[]" }
- { name: replica ,port: 5434 ,dest: default  ,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_services 中定义新服务。pg_default_servicespg_services 都是服务定义的数组。


定义服务

默认服务在 pg_default_services 中定义。

您可以在全局或集群级别使用 pg_services 定义额外的 PostgreSQL 服务。

这两个参数都是服务对象的数组。每个服务定义将被渲染为 /etc/haproxy/<svcname>.cfg 中的 haproxy 配置,查看 service.cfg 了解详细信息。

这里是一个额外服务定义的示例:standby

- name: standby                   # 必需,服务名称,实际服务名称将以 `pg_cluster` 为前缀,例如:pg-meta-standby
  port: 5435                      # 必需,服务暴露端口(作为 kubernetes 服务节点端口模式工作)
  ip: "*"                         # 可选,服务绑定 IP 地址,默认为所有 IP 的 `*`
  selector: "[]"                  # 必需,服务成员选择器,使用 JMESPath 过滤清单
  dest: default                   # 可选,目标端口,default|postgres|pgbouncer|<port_number>,默认为 'default'
  check: /sync                    # 可选,健康检查 URL 路径,默认为 /
  backup: "[? pg_role == `primary`]"  # 备份服务器选择器
  maxconn: 3000                   # 可选,最大允许前端连接数
  balance: roundrobin             # 可选,haproxy 负载均衡算法(默认为 roundrobin,其他:leastconn)
  options: 'inter 3s fastinter 1s downinter 5s rise 3 fall 3 on-marked-down shutdown-sessions slowstart 30s maxconn 3000 maxqueue 128 weight 100'

它将被转换为 haproxy 配置文件 /etc/haproxy/pg-test-standby.conf

#---------------------------------------------------------------------
# service: pg-test-standby @ 10.10.10.11:5435
#---------------------------------------------------------------------
# service instances 10.10.10.11, 10.10.10.13, 10.10.10.12
# service backups   10.10.10.11
listen pg-test-standby
    bind *:5435
    mode tcp
    maxconn 5000
    balance roundrobin
    option httpchk
    option http-keep-alive
    http-check send meth OPTIONS uri /sync  # <--- 对主节点和同步备节点为真
    http-check expect status 200
    default-server inter 3s fastinter 1s downinter 5s rise 3 fall 3 on-marked-down shutdown-sessions slowstart 30s maxconn 3000 maxqueue 128 weight 100
    # servers
    server pg-test-1 10.10.10.11:6432 check port 8008 weight 100 backup   # 主节点用作备份服务器
    server pg-test-3 10.10.10.13:6432 check port 8008 weight 100
    server pg-test-2 10.10.10.12:6432 check port 8008 weight 100

重新加载服务

当集群成员发生变化时,如添加/移除副本、切换/故障转移或调整相对权重,您必须重新加载服务以使更改生效。

bin/pgsql-svc <cls> [ip...]         # 为负载均衡集群或负载均衡实例重新加载服务
# ./pgsql.yml -t pg_service         # 重新加载服务的实际 ansible 任务

覆盖服务

您可以通过几种方式覆盖默认服务配置:

绕过 Pgbouncer

在定义服务时,如果 svc.dest='default',将使用参数 pg_default_service_dest 作为默认值。默认使用 pgbouncer,您可以改用 postgres,这样默认的主节点和副本服务将绕过 pgbouncer 并直接将流量路由到 postgres

如果您完全不需要连接池,可以将 pg_default_service_dest 更改为 postgres,并移除 defaultoffline 服务。

如果您不需要用于在线流量的只读副本,也可以从 pg_default_services 中移除 replica

pg_default_services:
  - { name: primary ,port: 5433 ,dest: default  ,check: /primary   ,selector: "[]" }
  - { name: replica ,port: 5434 ,dest: default  ,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]"}

委托服务

Pigsty 在节点上使用 haproxy 暴露 PostgreSQL 服务。集群中的所有 haproxy 实例都配置了相同的服务定义。

然而,您可以将 pg 服务委托给特定的节点组(例如,专用的 haproxy 负载均衡集群)而不是集群成员。

要做到这一点,您需要使用 pg_default_services 覆盖默认服务定义,并将 pg_service_provider 设置为代理组名称。

例如,这个配置将在 haproxy 节点组 proxy 上使用端口 10013 暴露 pg 集群主服务。

pg_service_provider: proxy       # 使用组 `proxy` 上的负载均衡器和端口 10013
pg_default_services:  [{ name: primary ,port: 10013 ,dest: postgres  ,check: /primary   ,selector: "[]" }]

用户有责任确保每个委托服务端口在代理集群中是唯一的

分离读写,将流量路由到正确的位置,并实现对 PostgreSQL 集群的稳定可靠访问。

服务是一个抽象,用于封装底层集群的细节,特别是在集群故障转移/切换期间。


个人用户

对于个人用户,服务是没有意义的。您可以使用原始 IP 地址或任何您喜欢的方法访问数据库。

psql postgres://dbuser_dba:[email protected]/meta     # dbsu 直接连接
psql postgres://dbuser_meta:[email protected]/meta   # 默认业务管理员用户
psql postgres://dbuser_view:DBUser.View@pg-meta/meta       # 默认只读用户

服务概述

在现实世界的生产环境中,我们利用基于复制的 PostgreSQL 数据库集群。在集群内,只有一个实例是可以接受写入的领导者(主节点)。其他实例(副本)持续从领导者获取 WAL 以保持同步。此外,副本可以处理只读查询,并在读取密集、写入较少的场景中为主节点分担负载。因此,区分写入和只读请求是一种常见做法。

此外,我们通过连接池中间件(Pgbouncer)为高频、短期连接池化请求,以减少连接和后端进程创建的开销。而且,对于 ETL 和变更执行等场景,我们需要绕过连接池并直接访问数据库服务器。此外,高可用性集群可能在故障期间发生故障转移,导致集群领导权发生变化。因此,读写请求应该自动重新路由到新的领导者。

这些不同的需求(读写分离、池化与直接连接以及客户端请求故障转移)导致了服务概念的抽象。

通常,数据库集群必须提供这个基本服务:

  • 读写服务(主节点):可以读取和写入数据库。

对于生产数据库集群,至少应该提供这两个服务:

  • 读写服务(主节点):写入数据:只由主节点承载。
  • 只读服务(副本):读取数据:可以由副本承载,但如果没有可用的副本,则回退到主节点。

此外,可能还有其他服务,例如:

  • 直接访问服务(默认):允许(管理员)用户绕过连接池并直接访问数据库。
  • 离线副本服务(离线):专用副本,不处理在线读取流量,用于 ETL 和分析查询。
  • 同步副本服务(备用):无复制延迟的只读服务,由同步备用/主节点处理读取查询。
  • 延迟副本服务(延迟):从一定时间前的同一集群访问较旧的数据,由延迟副本处理。

默认服务

Pigsty 将为每个 PostgreSQL 集群启用四个默认服务:

服务 端口 描述
primary 5433 pgbouncer 读写,连接到主节点 5432 或 6432
replica 5434 pgbouncer 只读,连接到副本 5432/6432
default 5436 管理员或直接访问主节点
offline 5438 OLAP、ETL、个人用户、交互式查询

以默认的 pg-meta 集群为例,您可以通过以下方式访问这些服务:

psql postgres://dbuser_meta:DBUser.Meta@pg-meta:5433/meta   # pg-meta-primary : 通过主节点 pgbouncer(6432) 进行生产读写
psql postgres://dbuser_meta:DBUser.Meta@pg-meta:5434/meta   # pg-meta-replica : 通过副本 pgbouncer(6432) 进行生产只读
psql postgres://dbuser_dba:DBUser.DBA@pg-meta:5436/meta     # pg-meta-default : 通过主节点 postgres(5432) 直接连接主节点
psql postgres://dbuser_stats:DBUser.Stats@pg-meta:5438/meta # pg-meta-offline : 通过离线 postgres(5432) 直接连接离线

pigsty-ha.png

这里 pg-meta 域名指向集群的 L2 VIP,进而指向主实例上的 haproxy 负载均衡器。 它负责将流量路由到不同的实例,查看访问服务了解详细信息。


主服务

主服务可能是生产使用中最关键的服务。

它将根据 pg_default_service_dest 将流量路由到主实例:

  • pgbouncer:将流量路由到主节点 pgbouncer 端口(6432),这是默认行为
  • postgres:如果您不想使用 pgbouncer,直接将流量路由到主节点 postgres 端口(5432)
- { name: primary ,port: 5433 ,dest: default  ,check: /primary   ,selector: "[]" }

这意味着所有集群成员都将包含在主服务中(selector: "[]"),但通过健康检查(check: /primary)的唯一实例将被用作主实例。Patroni 将保证任何时候只有一个实例是主节点,因此主服务将始终将流量路由到主实例。

listen pg-test-primary
    bind *:5433
    mode tcp
    maxconn 5000
    balance roundrobin
    option httpchk
    option http-keep-alive
    http-check send meth OPTIONS uri /primary
    http-check expect status 200
    default-server inter 3s fastinter 1s downinter 5s rise 3 fall 3 on-marked-down shutdown-sessions slowstart 30s maxconn 3000 maxqueue 128 weight 100
    # servers
    server pg-test-1 10.10.10.11:6432 check port 8008 weight 100
    server pg-test-3 10.10.10.13:6432 check port 8008 weight 100
    server pg-test-2 10.10.10.12:6432 check port 8008 weight 100

副本服务

副本服务用于生产只读流量。

在现实场景中,只读查询可能比读写查询多得多。您可能有许多副本。

副本服务将根据 pg_default_service_dest 将流量路由到 Pgbouncer 或 postgres,就像主服务一样。

- { name: replica ,port: 5434 ,dest: default  ,check: /read-only ,selector: "[]" , backup: "[? pg_role == `primary` || pg_role == `offline` ]" }

replica 服务流量将尽量使用 pg_role = replica 的普通 pg 实例,以尽可能减轻 primary 实例的负载。它将尽量不使用 pg_role = offline 的实例,以尽可能避免混合 OLAP 和 OLTP 查询。

所有集群成员将包含在副本服务中(selector: "[]"),当它通过只读健康检查(check: /read-only)时。primaryoffline 实例用作备份服务器,在所有 replica 实例都宕机的情况下接管。

listen pg-test-replica
    bind *:5434
    mode tcp
    maxconn 5000
    balance roundrobin
    option httpchk
    option http-keep-alive
    http-check send meth OPTIONS uri /read-only
    http-check expect status 200
    default-server inter 3s fastinter 1s downinter 5s rise 3 fall 3 on-marked-down shutdown-sessions slowstart 30s maxconn 3000 maxqueue 128 weight 100
    # servers
    server pg-test-1 10.10.10.11:6432 check port 8008 weight 100 backup
    server pg-test-3 10.10.10.13:6432 check port 8008 weight 100
    server pg-test-2 10.10.10.12:6432 check port 8008 weight 100

默认服务

默认服务将默认路由到主节点 postgres(5432)。

它非常类似于主服务,除了它将始终绕过 pgbouncer,无论 pg_default_service_dest 如何。这对于管理连接、ETL 写入、CDC 变更数据捕获等非常有用…

- { name: primary ,port: 5433 ,dest: default  ,check: /primary   ,selector: "[]" }
listen pg-test-default
    bind *:5436
    mode tcp
    maxconn 5000
    balance roundrobin
    option httpchk
    option http-keep-alive
    http-check send meth OPTIONS uri /primary
    http-check expect status 200
    default-server inter 3s fastinter 1s downinter 5s rise 3 fall 3 on-marked-down shutdown-sessions slowstart 30s maxconn 3000 maxqueue 128 weight 100
    # servers
    server pg-test-1 10.10.10.11:5432 check port 8008 weight 100
    server pg-test-3 10.10.10.13:5432 check port 8008 weight 100
    server pg-test-2 10.10.10.12:5432 check port 8008 weight 100

离线服务

离线服务将直接将流量路由到专用的 postgres 实例。

这可能是 pg_role = offline 实例,或者是标记了 pg_offline_query 的实例。

如果找不到这样的实例,它将回退到任何副本实例。底线是:它永远不会将流量路由到主实例。

- { name: offline ,port: 5438 ,dest: postgres ,check: /replica   ,selector: "[? pg_role == `offline` || pg_offline_query ]" , backup: "[? pg_role == `replica` && !pg_offline_query]"}
listen pg-test-offline
    bind *:5438
    mode tcp
    maxconn 5000
    balance roundrobin
    option httpchk
    option http-keep-alive
    http-check send meth OPTIONS uri /replica
    http-check expect status 200
    default-server inter 3s fastinter 1s downinter 5s rise 3 fall 3 on-marked-down shutdown-sessions slowstart 30s maxconn 3000 maxqueue 128 weight 100
    # servers
    server pg-test-3 10.10.10.13:5432 check port 8008 weight 100
    server pg-test-2 10.10.10.12:5432 check port 8008 weight 100 backup

访问服务

Pigsty 使用 haproxy 暴露服务。默认情况下,所有节点都启用了 haproxy。

默认情况下,haproxy 负载均衡器在同一个 pg 集群中是幂等的,您可以通过任何/所有方式使用它们。

典型的方法是通过集群域名访问,它解析为集群 L2 VIP,或以轮询方式解析为所有实例 IP 地址。

服务可以通过不同的方式实现。您甚至可以实现自己的访问方法,如 L4 LVS、F5 等,而不是 haproxy。

pigsty-access.jpg

您可以使用主机和端口的不同组合,它们以不同的方式提供 PostgreSQL 服务。

主机

类型 示例 描述
集群域名 pg-test 通过集群域名(由基础设施节点上的 dnsmasq 解析)
集群 VIP 地址 10.10.10.3 通过由 vip-manager 管理的 L2 VIP 地址,绑定到主节点
实例主机名 pg-test-1 通过任何实例主机名访问(由基础设施节点上的 dnsmasq 解析)
实例 IP 地址 10.10.10.11 访问任何实例 IP 地址

端口

Pigsty 使用不同的端口来区分 pg 服务:

端口 服务 类型 描述
5432 postgres 数据库 直接访问 postgres 服务器
6432 pgbouncer 中间件 在访问 postgres 之前通过连接池中间件
5433 primary 服务 访问主节点 pgbouncer(或 postgres)
5434 replica 服务 访问副本 pgbouncer(或 postgres)
5436 default 服务 访问主节点 postgres
5438 offline 服务 访问离线 postgres

组合

# 通过集群域名访问
postgres://test@pg-test:5432/test # DNS -> L2 VIP -> 主节点直接连接
postgres://test@pg-test:6432/test # DNS -> L2 VIP -> 主节点连接池 -> 主节点
postgres://test@pg-test:5433/test # DNS -> L2 VIP -> HAProxy -> 主节点连接池 -> 主节点
postgres://test@pg-test:5434/test # DNS -> L2 VIP -> HAProxy -> 副本连接池 -> 副本
postgres://dbuser_dba@pg-test:5436/test # DNS -> L2 VIP -> HAProxy -> 主节点直接连接(管理员)
postgres://dbuser_stats@pg-test:5438/test # DNS -> L2 VIP -> HAProxy -> 离线直接连接(ETL/个人查询)

# 通过集群 VIP 直接访问
postgres://[email protected]:5432/test # L2 VIP -> 主节点直接访问
postgres://[email protected]:6432/test # L2 VIP -> 主节点连接池 -> 主节点
postgres://[email protected]:5433/test # L2 VIP -> HAProxy -> 主节点连接池 -> 主节点
postgres://[email protected]:5434/test # L2 VIP -> HAProxy -> 副本连接池 -> 副本
postgres://[email protected]:5436/test # L2 VIP -> HAProxy -> 主节点直接连接(管理员)
postgres://[email protected]::5438/test # L2 VIP -> HAProxy -> 离线直接连接(ETL/个人查询)

# 直接指定任何集群实例名称
postgres://test@pg-test-1:5432/test # DNS -> 数据库实例直接连接(单例访问)
postgres://test@pg-test-1:6432/test # DNS -> 连接池 -> 数据库
postgres://test@pg-test-1:5433/test # DNS -> HAProxy -> 连接池 -> 数据库读写
postgres://test@pg-test-1:5434/test # DNS -> HAProxy -> 连接池 -> 数据库只读
postgres://dbuser_dba@pg-test-1:5436/test # DNS -> HAProxy -> 数据库直接连接
postgres://dbuser_stats@pg-test-1:5438/test # DNS -> HAProxy -> 数据库离线读写

# 直接指定任何集群实例 IP 访问
postgres://[email protected]:5432/test # 数据库实例直接连接(直接指定实例,无自动流量分发)
postgres://[email protected]:6432/test # 连接池 -> 数据库
postgres://[email protected]:5433/test # HAProxy -> 连接池 -> 数据库读写
postgres://[email protected]:5434/test # HAProxy -> 连接池 -> 数据库只读
postgres://[email protected]:5436/test # HAProxy -> 数据库直接连接
postgres://[email protected]:5438/test # HAProxy -> 数据库离线读写

# 智能客户端自动读写分离(连接池)
postgres://[email protected]:6432,10.10.10.12:6432,10.10.10.13:6432/test?target_session_attrs=primary
postgres://[email protected]:6432,10.10.10.12:6432,10.10.10.13:6432/test?target_session_attrs=prefer-standby

11.11 - 认证

Pigsty 中基于主机的身份验证

PostgreSQL 有各种 身份验证 方法。您可以使用所有这些方法,而 Pigsty 的开箱即用 ACL 系统专注于 HBA、密码和 SSL 身份验证。


客户端身份验证

要连接到 PostgreSQL 数据库,用户必须经过身份验证(默认使用密码)。

您可以在连接字符串中提供密码(不安全)或使用 PGPASSWORD 环境变量或 .pgpass 文件。查看 psql 文档和 PostgreSQL 连接字符串 获取更多详细信息。

psql 'host=<host> port=<port> dbname=<dbname> user=<username> password=<password>'
psql postgres://<username>:<password>@<host>:<port>/<dbname>
PGPASSWORD=<password>; psql -U <username> -h <host> -p <port> -d <dbname>

meta 数据库的默认连接字符串:

psql 'host=10.10.10.10 port=5432 dbname=meta user=dbuser_dba password=DBUser.DBA'
psql postgres://dbuser_dba:[email protected]:5432/meta
PGPASSWORD=DBUser.DBA; psql -U dbuser_dba -h 10.10.10.10 -p 5432 -d meta

要使用 SSL 证书连接,您可以使用 PGSSLCERTPGSSLKEY 环境变量或 sslkeysslcert 参数。

psql 'postgres://dbuser_dba:[email protected]:5432/meta?sslkey=/path/to/dbuser_dba.key&sslcert=/path/to/dbuser_dba.crt'

客户端证书(CN = 用户名)可以使用本地 CA 和 cert.yml 颁发。


定义 HBA

Pigsty 中有四个 HBA 规则参数:

它们是 HBA 规则对象的数组,每个 HBA 规则是以下形式之一:

1. 原始形式

- title: allow intranet password access
  role: common
  rules:
    - host   all  all  10.0.0.0/8      md5
    - host   all  all  172.16.0.0/12   md5
    - host   all  all  192.168.0.0/16  md5

在这种形式中,title 将被渲染为注释行,然后是 rules 作为 HBA 字符串逐一显示。

当实例的 pg_rolerole 相同时,HBA 规则被安装。

带有 role: common 的 HBA 规则将在所有实例上安装。

带有 role: offline 的 HBA 规则将在 pg_role = offlinepg_offline_query = true 的实例上安装。

2. 别名形式

别名形式,用 addrauthuserdb 字段替换 rules

- addr: 'intra'    # world|intra|infra|admin|local|localhost|cluster|<cidr>
  auth: 'pwd'      # trust|pwd|ssl|cert|deny|<official auth method>
  user: 'all'      # all|${dbsu}|${repl}|${admin}|${monitor}|<user>|<group>
  db: 'all'        # all|replication|....
  rules: []        # 原始 HBA 字符串优先于以上所有
  title: allow intranet password access
  • addr:哪里

    • world:所有 IP 地址
    • intra:所有内网 CIDR:'10.0.0.0/8'、'172.16.0.0/12'、'192.168.0.0/16'
    • infra:基础设施节点的 IP 地址
    • adminadmin_ip 地址
    • local:本地 unix 套接字
    • localhost:本地 unix 套接字 + tcp 127.0.0.1/32
    • cluster:PostgreSQL 集群成员的所有 IP 地址
    • <cidr>:任何标准 CIDR 块或 IP 地址
  • auth:如何

    • deny:拒绝访问
    • trust:信任身份验证
    • pwd:根据 pg_pwd_enc 使用 md5scram-sha-256 密码认证
    • sha/scram-sha-256:强制 scram-sha-256 密码身份验证
    • md5md5 密码身份验证
    • ssl:在 pwd 认证基础上强制主机 SSL
    • ssl-md5:在 md5 密码认证基础上强制主机 SSL
    • ssl-sha:在 scram-sha-256 密码认证基础上强制主机 SSL
    • os/ident:使用 ident 操作系统用户身份验证
    • peer:使用 peer 身份验证
    • cert:使用基于证书的客户端身份验证
  • user:谁

  • db:哪个

    • all:所有数据库
    • replication:复制数据库
    • 临时数据库名称

3. 在哪里定义

通常,全局 HBA 在 all.vars 中定义。如果您想修改全局默认 HBA 规则,可以从 full.yml 模板复制到 all.vars 进行修改。

集群特定的 HBA 规则在数据库的集群级配置中定义:

以下是集群 HBA 规则定义的一些示例。

pg-meta:
  hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
  vars:
    pg_cluster: pg-meta
    pg_hba_rules:
      - { user: dbuser_view ,db: all    ,addr: infra        ,auth: pwd  ,title: 'allow grafana dashboard access cmdb from infra nodes'}
      - { user: all         ,db: all    ,addr: 100.0.0.0/8  ,auth: pwd  ,title: 'all user access all db from kubernetes cluster' }
      - { user: '${admin}'  ,db: world  ,addr: 0.0.0.0/0    ,auth: cert ,title: 'all admin world access with client cert'        }

重载 HBA

要重载 postgres/pgbouncer HBA 规则:

bin/pgsql-hba <cls>                 # 重载集群 `<cls>` 的 HBA 规则
bin/pgsql-hba <cls> ip1 ip2...      # 重载特定实例的 HBA 规则

底层命令是:

./pgsql.yml -l <cls> -e pg_reload=true -t pg_hba,pg_reload
./pgsql.yml -l <cls> -e pg_reload=true -t pgbouncer_hba,pgbouncer_reload

默认 HBA

Pigsty 有一套默认的 HBA 规则,对大多数情况来说都相当安全。

这些规则以别名形式自解释。

pg_default_hba_rules:             # PostgreSQL 默认基于主机的身份验证规则
  - {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: '+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'}
pgb_default_hba_rules:            # pgbouncer 默认基于主机的身份验证规则
  - {user: '${dbsu}'    ,db: pgbouncer   ,addr: local     ,auth: peer  ,title: 'dbsu local admin access with os ident'}
  - {user: 'all'        ,db: all         ,addr: localhost ,auth: pwd   ,title: 'allow all user local access with pwd' }
  - {user: '${monitor}' ,db: pgbouncer   ,addr: intra     ,auth: pwd   ,title: 'monitor access via intranet with pwd' }
  - {user: '${monitor}' ,db: all         ,addr: world     ,auth: deny  ,title: 'reject all other monitor access addr' }
  - {user: '${admin}'   ,db: all         ,addr: intra     ,auth: pwd   ,title: 'admin access via intranet with pwd'   }
  - {user: '${admin}'   ,db: all         ,addr: world     ,auth: deny  ,title: 'reject all other admin access addr'   }
  - {user: 'all'        ,db: all         ,addr: intra     ,auth: pwd   ,title: 'allow all user intra access with pwd' }

安全增强

对于那些关键情况,我们有一个 safe.yml 模板,以下 HBA 规则集作为参考:

pg_default_hba_rules:             # PostgreSQL 默认基于主机的认证规则
  - {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: ssl   ,title: 'replicator replication from localhost'}
  - {user: '${repl}'    ,db: replication ,addr: intra     ,auth: ssl   ,title: 'replicator replication from intranet' }
  - {user: '${repl}'    ,db: postgres    ,addr: intra     ,auth: ssl   ,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: ssl   ,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: cert  ,title: 'admin @ everywhere with ssl & cert'   }
  - {user: '+dbrole_readonly',db: all    ,addr: localhost ,auth: ssl   ,title: 'pgbouncer read/write via local socket'}
  - {user: '+dbrole_readonly',db: all    ,addr: intra     ,auth: ssl   ,title: 'read/write biz user via password'     }
  - {user: '+dbrole_offline' ,db: all    ,addr: intra     ,auth: ssl   ,title: 'allow etl offline tasks from intranet'}
pgb_default_hba_rules:            # pgbouncer 基于主机的身份验证规则
  - {user: '${dbsu}'    ,db: pgbouncer   ,addr: local     ,auth: peer  ,title: 'dbsu local admin access with os ident'}
  - {user: 'all'        ,db: all         ,addr: localhost ,auth: pwd   ,title: 'allow all user local access with pwd' }
  - {user: '${monitor}' ,db: pgbouncer   ,addr: intra     ,auth: ssl   ,title: 'monitor access via intranet with pwd' }
  - {user: '${monitor}' ,db: all         ,addr: world     ,auth: deny  ,title: 'reject all other monitor access addr' }
  - {user: '${admin}'   ,db: all         ,addr: intra     ,auth: ssl   ,title: 'admin access via intranet with pwd'   }
  - {user: '${admin}'   ,db: all         ,addr: world     ,auth: deny  ,title: 'reject all other admin access addr'   }
  - {user: 'all'        ,db: all         ,addr: intra     ,auth: ssl   ,title: 'allow all user intra access with pwd' }

11.12 - 权限

使用默认角色和权限进行数据库访问控制

Pigsty 具有一套默认的角色系统,包含四个 默认角色 和四个 默认用户

默认用户 用户描述 默认角色 角色描述
postgres 系统超级用户 dbrole_readonly 全局只读权限角色
replicator 系统复制用户 dbrole_readwrite 全局读写权限角色
dbuser_dba PostgreSQL 管理员用户 dbrole_admin 对象创建权限角色
dbuser_monitor PostgreSQL 监控用户 dbrole_offline 受限只读权限角色

概览

角色名称 属性 所属角色 描述
dbrole_readonly NOLOGIN 全局只读权限角色
dbrole_readwrite NOLOGIN dbrole_readonly 全局读写权限角色
dbrole_admin NOLOGIN pg_monitor,dbrole_readwrite 对象创建权限角色
dbrole_offline NOLOGIN 受限只读权限角色
postgres SUPERUSER 系统超级用户
replicator REPLICATION pg_monitor,dbrole_readonly 系统复制用户
dbuser_dba SUPERUSER dbrole_admin PostgreSQL 管理员用户
dbuser_monitor pg_monitor PostgreSQL 监控用户
pg_default_roles:                 # PostgreSQL 集群中的默认角色和用户
  - { 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 ,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 }

默认角色

Pigsty 中有四个默认角色:

  • 只读角色(dbrole_readonly):全局只读权限访问角色
  • 读写角色(dbrole_readwrite):全局读写权限访问角色,继承 dbrole_readonly
  • 管理员角色(dbrole_admin):DDL 命令权限角色,继承 dbrole_readwrite
  • 离线角色(dbrole_offline):受限只读权限访问角色(离线 实例)

默认角色在 pg_default_roles 中定义,不建议修改默认角色。

- { name: dbrole_readonly  , login: false , comment: role for global read-only access  }                            # 生产只读角色
- { name: dbrole_offline ,   login: false , comment: role for restricted read-only access (offline instance) }      # 受限只读角色
- { 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 } # 生产 DDL 变更角色

默认用户

Pigsty 中也有四个默认用户。

  • 超级用户(postgres),集群的拥有者和创建者,与操作系统数据库超级用户相同
  • 复制用户(replicator),用于主从复制的系统用户
  • 监控用户(dbuser_monitor),用于监控数据库和连接池指标的用户
  • 管理员用户(dbuser_dba),执行日常操作和数据库变更的管理员用户

默认用户的用户名/密码由专用参数定义(除了数据库超级用户密码):

!> 请记住在生产部署中更改这些密码!

pg_dbsu: postgres                             # 数据库的操作系统用户
pg_replication_username: replicator           # 系统复制用户
pg_replication_password: DBUser.Replicator    # 系统复制用户密码
pg_monitor_username: dbuser_monitor           # 系统监控用户
pg_monitor_password: DBUser.Monitor           # 系统监控用户密码
pg_admin_username: dbuser_dba                 # 系统管理员用户
pg_admin_password: DBUser.DBA                 # 系统管理员用户密码

要定义额外选项,请在 pg_default_roles 中指定:

- { name: postgres     ,superuser: true                                          ,comment: system superuser }
- { name: replicator ,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, dbrole_readonly] ,pgbouncer: true ,parameters: {log_min_duration_statement: 1000 } ,pool_mode: session ,pool_connlimit: 8 ,comment: pgsql monitor user }

权限管理

Pigsty 具有一套开箱即用的权限模型,与 默认角色 配合使用。

  • 所有用户都可以访问所有 Schema
  • 只读用户可以从所有表读取数据(SELECT、EXECUTE)
  • 读写用户可以向所有表写入数据并运行 DML(INSERT、UPDATE、DELETE)
  • 管理员用户可以创建对象并运行 DDL(CREATE、USAGE、TRUNCATE、REFERENCES、TRIGGER)
  • 离线用户是在离线实例上具有受限访问权限的只读用户(pg_role = 'offline'pg_offline_query = true
  • 由管理员用户创建的对象将具有正确的权限
  • 默认权限安装在所有数据库上,包括模板数据库
  • 数据库连接权限由数据库 定义 覆盖
  • 默认情况下,数据库和 public schema 的 CREATE 权限从 PUBLIC 撤销

对象权限

默认对象权限在 pg_default_privileges 中定义。

- GRANT USAGE      ON SCHEMAS   TO dbrole_readonly
- GRANT SELECT     ON TABLES    TO dbrole_readonly
- GRANT SELECT     ON SEQUENCES TO dbrole_readonly
- GRANT EXECUTE    ON FUNCTIONS TO dbrole_readonly
- GRANT USAGE      ON SCHEMAS   TO dbrole_offline
- GRANT SELECT     ON TABLES    TO dbrole_offline
- GRANT SELECT     ON SEQUENCES TO dbrole_offline
- GRANT EXECUTE    ON FUNCTIONS TO dbrole_offline
- GRANT INSERT     ON TABLES    TO dbrole_readwrite
- GRANT UPDATE     ON TABLES    TO dbrole_readwrite
- GRANT DELETE     ON TABLES    TO dbrole_readwrite
- GRANT USAGE      ON SEQUENCES TO dbrole_readwrite
- GRANT UPDATE     ON SEQUENCES TO dbrole_readwrite
- GRANT TRUNCATE   ON TABLES    TO dbrole_admin
- GRANT REFERENCES ON TABLES    TO dbrole_admin
- GRANT TRIGGER    ON TABLES    TO dbrole_admin
- GRANT CREATE     ON SCHEMAS   TO dbrole_admin

当新创建的对象由管理员用户创建时,它们将具有相应的权限。

\ddp+ 命令的输出可能如下所示:

类型 访问权限
function =X
dbrole_readonly=X
dbrole_offline=X
dbrole_admin=X
schema dbrole_readonly=U
dbrole_offline=U
dbrole_admin=UC
sequence dbrole_readonly=r
dbrole_offline=r
dbrole_readwrite=wU
dbrole_admin=rwU
table dbrole_readonly=r
dbrole_offline=r
dbrole_readwrite=awd
dbrole_admin=arwdDxt

默认权限

ALTER DEFAULT PRIVILEGES 允许您设置将应用于未来创建的对象的权限。它不会影响分配给已存在对象的权限,也不会影响由非管理员用户创建的对象。

Pigsty 将使用以下默认权限:

{% for priv in pg_default_privileges %}
ALTER DEFAULT PRIVILEGES FOR ROLE {{ pg_dbsu }} {{ priv }};
{% endfor %}

{% for priv in pg_default_privileges %}
ALTER DEFAULT PRIVILEGES FOR ROLE {{ pg_admin_username }} {{ priv }};
{% endfor %}

-- 对于额外的业务管理员,他们可以使用 SET ROLE 切换到 dbrole_admin
{% for priv in pg_default_privileges %}
ALTER DEFAULT PRIVILEGES FOR ROLE "dbrole_admin" {{ priv }};
{% endfor %}

这些权限将在 pg-init-template.sql 中与管理员用户的 ALTER DEFAULT PRIVILEGES 语句一起渲染。

这些 SQL 命令将在集群引导期间在 postgrestemplate1 上执行,新创建的数据库将默认从 template1 继承它们。

也就是说,要维护正确的对象权限,您必须使用管理员用户运行 DDL,这些用户可以是:

  1. {{ pg_dbsu }},默认为 postgres
  2. {{ pg_admin_username }},默认为 dbuser_dba
  3. 被授予 dbrole_admin 权限的业务管理员用户

明智的做法是使用 postgres 作为全局对象拥有者来执行 DDL 变更。 如果您希望使用业务管理员用户创建对象,您必须在运行该 DDL 之前使用 SET ROLE dbrole_admin 来维护正确的权限。

您也可以使用 ALTER DEFAULT PRIVILEGE FOR ROLE <some_biz_admin> XXX 来为业务管理员用户授予默认权限。


数据库权限

数据库权限由 数据库定义 覆盖。

有 3 个数据库级别的权限:CONNECTCREATETEMP,以及一个特殊的"权限":OWNERSHIP

- name: meta         # 必需,`name` 是数据库定义的唯一必需字段
  owner: postgres    # 可选,指定数据库拥有者,默认为 {{ pg_dbsu }}
  allowconn: true    # 可选,允许连接,默认为 true。false 将完全禁用连接
  revokeconn: false  # 可选,撤销公共连接权限。默认为 false。(将连接权限留给拥有者并授予授权选项)
  • 如果 owner 存在,它将用作数据库拥有者,而不是默认的 {{ pg_dbsu }}
  • 如果 revokeconnfalse,所有用户都具有数据库的 CONNECT 权限,这是默认行为
  • 如果 revokeconn 明确设置为 true
  • 数据库的 CONNECT 权限将从 PUBLIC 撤销
  • CONNECT 权限将授予 {{ pg_replication_username }}{{ pg_monitor_username }}{{ pg_admin_username }}
  • CONNECT 权限将授予数据库拥有者并带有 GRANT OPTION

revokeconn 标志可用于数据库访问隔离,您可以为每个数据库创建不同的业务用户作为拥有者,并为所有数据库设置 revokeconn 选项。


创建权限

出于安全考虑,Pigsty 默认从 PUBLIC 撤销数据库上的 CREATE 权限。这也是 PostgreSQL 15 以来的默认行为。

数据库拥有者具有根据需要调整这些权限的完全能力。

11.13 - 面板

查看可视化信息

PostgreSQL 集群的 Grafana 监控面板:演示图库

pigsty-dashboard.jpg

共有 26 个关于 PostgreSQL 的默认 Grafana 监控面板,分为 4 个层级,并按数据源分为 PGSQLPGCATPGLOG

概览

  • pgsql-overview:PGSQL 模块的主要监控面板
  • pgsql-alert:全局 PGSQL 关键指标和告警事件
  • pgsql-shard:水平分片 PGSQL 集群概览,例如 citus / gpsql 集群

集群

  • pgsql-cluster:PGSQL 集群的主要监控面板
  • pgrds-cluster:RDS 的 PGSQL 集群监控面板,仅关注所有 postgres 指标
  • pgsql-activity:关注 PGSQL 集群的会话/负载/QPS/TPS/锁
  • pgsql-replication:关注 PGSQL 集群复制、槽位和发布/订阅
  • pgsql-service:关注 PGSQL 集群服务、代理、路由和负载均衡器
  • pgsql-databases:关注数据库 CRUD、慢查询和跨所有实例的表统计
  • pgsql-patroni:关注集群高可用代理 patroni 状态
  • pgsql-pitr:关注 PITR 过程中集群状态的上下文

实例

  • pgsql-instance:单个 PGSQL 实例的主要监控面板
  • pgrds-instance:RDS 的 PGSQL 实例监控面板,仅关注所有 postgres 指标
  • pgcat-instance:直接从数据库目录获取的实例信息
  • pgsql-persist:关于持久化的指标:WAL、XID、检查点、归档、IO
  • pgsql-proxy:关于服务提供商 haproxy 的指标
  • pgsql-queries:单个实例中所有查询的概览
  • pgsql-session:单个实例中关于会话和活动/空闲时间的指标
  • pgsql-xacts:关于事务、锁、查询等的指标
  • pgsql-exporter:Postgres 和 Pgbouncer 导出器自监控指标

数据库

  • pgsql-database:单个 PGSQL 数据库的主要监控面板
  • pgcat-database:直接从数据库目录获取的数据库信息
  • pgsql-tables:单个数据库内的表/索引访问指标
  • pgsql-table:单个表的详细信息(QPS/RT/索引/顺序扫描…)
  • pgcat-table:直接从数据库目录获取的单个表的详细信息(统计/膨胀/…)
  • pgsql-query:单个查询的详细信息(QPS/RT)
  • pgcat-query:直接从数据库目录获取的单个查询的详细信息(SQL/统计)

概览

PGSQL 概览:PGSQL 模块的主要监控面板

PGSQL 告警:全局 PGSQL 关键指标和告警事件

PGSQL 分片:水平分片 PGSQL 集群概览,例如 CITUS / GPSQL 集群


集群

PGSQL 集群:PGSQL 集群的主要监控面板

PGRDS 集群:RDS 的 PGSQL 集群监控面板,仅关注所有 postgres 指标

PGSQL 服务:关注 PGSQL 集群服务、代理、路由和负载均衡器

PGSQL 活动:关注 PGSQL 集群的会话/负载/QPS/TPS/锁

PGSQL 复制:关注 PGSQL 集群复制、槽位和发布/订阅

PGSQL 数据库集:关注数据库 CRUD、慢查询和跨所有实例的表统计

PGSQL Patroni:关注集群高可用代理 patroni 状态

PGSQL PITR:关注 PITR 过程中集群状态的上下文


实例

PGSQL 实例:单个 PGSQL 实例的主要监控面板

PGRDS 实例:RDS 的 PGSQL 实例监控面板,仅关注所有 postgres 指标

PGSQL 代理:关于服务提供商 haproxy 的指标

PGSQL Pgbouncer:关于单个 pgbouncer 连接池实例的指标

PGSQL 持久化:关于持久化的指标:WAL、XID、检查点、归档、IO

PGSQL 事务:关于事务、锁、查询等的指标

PGSQL 会话:单个实例中关于会话和活动/空闲时间的指标

PGSQL 导出器:Postgres 和 Pgbouncer 导出器自监控指标


数据库

PGSQL 数据库:单个 PGSQL 数据库的主要监控面板

PGSQL 表:单个数据库内的表/索引访问指标

PGSQL 表详情:单个表的详细信息(QPS/RT/索引/顺序扫描…)

PGSQL 查询:单个查询的详细信息(QPS/RT)


PGCAT

PGCAT 实例:直接从数据库目录获取的实例信息

PGCAT 数据库:直接从数据库目录获取的数据库信息

PGCAT 模式:直接从数据库目录获取的单个模式的详细信息

PGCAT 表详情:直接从数据库目录获取的单个表的详细信息

PGCAT 查询:直接从数据库目录获取的单类查询的详细信息

PGCAT 锁:直接从数据库目录获取的活动锁和活动的详细信息


PGLOG

PGLOG 概览:Pigsty 元数据库中 CSV 日志样本的概览

PGLOG 详情:Pigsty 元数据库中 CSV 日志样本的单个会话详情

11.14 - 迁移

零宕机蓝绿部署

Pigsty 有一个内置的 playbook pgsql-migration.yml 来执行基于逻辑复制的在线数据库迁移。

通过适当的自动化,宕机时间可以最小化到几秒钟。但请注意,逻辑复制需要 PostgreSQL 10+ 才能工作。 您仍然可以使用这里的工具,并使用 pg_dump | psql 代替逻辑复制。


定义迁移任务

您必须创建一个迁移任务定义文件来使用此 playbook。

查看 files/migration/pg-meta.yml 作为示例。

它将尝试将 pg-meta.meta 迁移到 pg-test.test

pg-meta-1	10.10.10.10  --> pg-test-1	10.10.10.11 (10.10.10.12,10.10.10.13)

您必须告诉 Pigsty 源集群和目标集群在哪里。要迁移的数据库以及主 IP 地址。

您应该在两端都有超级用户权限才能继续

您可以使用 src_pg 覆盖到源集群的超级用户连接,使用 sub_conn 覆盖逻辑复制连接字符串,否则将使用 Pigsty 默认的管理员和复制器凭据。

---
#-----------------------------------------------------------------
# PG_MIGRATION
#-----------------------------------------------------------------
context_dir: ~/migration           # 迁移手册和脚本
#-----------------------------------------------------------------
# SRC 集群(旧集群)
#-----------------------------------------------------------------
src_cls: pg-meta      # 源集群名称         <必填>
src_db: meta          # 源数据库名称        <必填>
src_ip: 10.10.10.10   # 源集群主 IP        <必填>
#src_pg: ''            # 如果定义,使用此作为源 dbsu pgurl 而不是:
#                      # postgres://{{ pg_admin_username }}@{{ src_ip }}/{{ src_db }}
#                      # 例如 'postgres://dbuser_dba:[email protected]:5432/meta'
#sub_conn: ''          # 如果定义,使用此作为订阅 connstr 而不是:
#                      # host={{ src_ip }} dbname={{ src_db }} user={{ pg_replication_username }}'
#                      # 例如 'host=10.10.10.10 dbname=meta user=replicator password=DBUser.Replicator'
#-----------------------------------------------------------------
# DST 集群(新集群)
#-----------------------------------------------------------------
dst_cls: pg-test      # 目标集群名称         <必填>
dst_db: test          # 目标数据库名称        <必填>
dst_ip: 10.10.10.11   # 目标集群主 IP        <必填>
#dst_pg: ''            # 如果定义,使用此作为目标 dbsu pgurl 而不是:
#                      # postgres://{{ pg_admin_username }}@{{ dst_ip }}/{{ dst_db }}
#                      # 例如 'postgres://dbuser_dba:[email protected]:5432/test'
#-----------------------------------------------------------------
# PGSQL
#-----------------------------------------------------------------
pg_dbsu: postgres
pg_replication_username: replicator
pg_replication_password: DBUser.Replicator
pg_admin_username: dbuser_dba
pg_admin_password: DBUser.DBA
pg_monitor_username: dbuser_monitor
pg_monitor_password: DBUser.Monitor
#-----------------------------------------------------------------
...

生成计划

该 playbook 不会将源迁移到目标,但它会生成您需要执行此操作的所有内容。

执行后,您将在默认的 ~/migration/pg-meta.meta 下找到迁移上下文目录

按照 README.md 并逐一执行这些脚本,您就能完成此操作!

# 此脚本将使用环境变量设置迁移上下文
. ~/migration/pg-meta.meta/activate

# 这些脚本用于检查源集群状态
# 并帮助在 Pigsty 中生成新的集群定义
./check-user     # 检查源用户
./check-db       # 检查源数据库
./check-hba      # 检查源 hba 规则
./check-repl     # 检查源副本标识
./check-misc     # 检查源特殊对象

# 这些脚本用于在现有源集群和 Pigsty 管理的目标集群之间
# 构建逻辑复制
# 架构、数据将实时同步,除了序列
./copy-schema    # 将架构复制到目标
./create-pub     # 在源上创建发布
./create-sub     # 在目标上创建订阅
./copy-progress  # 打印逻辑复制进度
./copy-diff      # 通过计数表快速比较源和目标差异

# 这些脚本将在在线迁移中运行,它们将
# 停止源集群,复制序列号(逻辑复制不会同步)
# 您必须根据您的访问方法重新路由您的应用流量(dns,vip,haproxy,pgbouncer 等...)
# 然后执行清理以删除订阅和发布
./copy-seq [n]   # 同步序列号,如果给定 n,将应用额外的偏移
#./disable-src   # 限制源集群仅对管理节点和新集群的访问(您的实现)
#./re-routing    # 将应用程序流量从源路由到目标!            (您的实现)
./drop-sub       # 迁移后在目标上删除订阅
./drop-pub       # 迁移后在源上删除发布

注意事项

您可以使用 ./copy-seq 1000 在同步序列后将所有序列提前一个数字(例如 1000)。这可能会防止新集群中潜在的串行主键冲突。

您必须实现自己的 ./re-routing 脚本来将应用程序流量从源路由到目标。因为我们不知道您的流量是如何路由的(例如 dns、VIP、haproxy 或 pgbouncer)。当然,您总是可以手动完成…

您必须实现自己的 ./disable-src 脚本来限制源集群。您可以通过更改 HBA 规则并重新加载(推荐)来做到这一点,或者只是关闭 postgres、pgbouncer 或 haproxy…

11.15 - 备份

备份和时间点恢复

Pigsty 使用 pgBackRest 管理 PostgreSQL 备份,它可能是生态系统中最强大的开源备份工具。 具有增量/并行备份和恢复、加密、MinIO / S3 支持以及许多其他功能。 Pigsty 默认为每个 PGSQL 集群预配置了它。

策略
    备份脚本、调度、pgbackrest、仓库和管理
管理
    备份策略、磁盘规划、恢复窗口权衡
恢复
    使用 playbook 恢复到特定时间点
示例
    沙箱示例:手动执行恢复
无质保承诺

Pigsty 尽力提供可靠的 PITR 解决方案,但我们不对 PITR 操作导致的数据丢失承担任何责任,请自行承担风险使用。 如需专业支持,请考虑我们的 专业服务


快速开始

步骤 1

    [备份策略](/zh/docs/pgsql/backup/mechanism):使用 Crontab 调度基础备份

步骤 2

    [WAL 归档](/zh/docs/pgsql/backup/policy):持续记录写入活动

步骤 3

    [恢复和还原](/zh/docs/pgsql/backup/restore):从备份和 WAL 归档中恢复
每天凌晨 1 点全量备份
node_crontab: [ '00 01 * * * postgres /pg/bin/pg-backup full' ]
恢复到时间点
./pgsql-pitr.yml -e '{"pg_pitr": { "time": "2025-07-13 10:00:00+00" }}'

11.15.1 - 备份机制

备份脚本、调度、仓库和基础设施

备份可以通过内置 脚本 调用,使用节点 crontab 调度, 由 pgbackrest 管理,并存储在备份仓库中, 仓库可以是本地磁盘文件系统或 MinIO / S3,具有不同的 保留 策略。


备份脚本

您可以使用 pg_dbsu 用户(默认为 postgres)通过 pgbackrest 命令创建备份:

pgbackrest --stanza=pg-meta --type=full backup   # 为集群 pg-meta 创建全量备份
$ pgbackrest --stanza=pg-meta --type=full backup
2025-07-15 01:36:57.007 P00   INFO: backup command begin 2.54.2: --annotation=pg_cluster=pg-meta --compress-type=lz4 --delta --exec-id=88380-4b22e767 --expire-auto --log-level-console=info --log-level-file=info --log-path=/pg/log/pgbackrest --pg1-path=/pg/data --pg1-port=5432 --repo1-block --repo1-bundle --repo1-bundle-limit=20MiB --repo1-bundle-size=128MiB --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/pgbackrest --repo1-retention-full=14 --repo1-retention-full-type=time --repo1-s3-bucket=pgsql --repo1-s3-endpoint=sss.pigsty --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --repo1-s3-uri-style=path --repo1-storage-ca-file=/etc/pki/ca.crt --repo1-storage-port=9000 --repo1-type=s3 --stanza=pg-meta --start-fast --type=full
2025-07-15 01:36:57.030 P00   INFO: execute non-exclusive backup start: backup begins after the requested immediate checkpoint completes
2025-07-15 01:36:57.105 P00   INFO: backup start archive = 000000010000000000000006, lsn = 0/6000028
2025-07-15 01:36:57.105 P00   INFO: check archive for prior segment 000000010000000000000005
2025-07-15 01:36:58.403 P00   INFO: execute non-exclusive backup stop and wait for all WAL segments to archive
2025-07-15 01:36:58.421 P00   INFO: backup stop archive = 000000010000000000000006, lsn = 0/6000120
2025-07-15 01:36:58.424 P00   INFO: check archive for segment(s) 000000010000000000000006:000000010000000000000006
2025-07-15 01:36:58.540 P00   INFO: new backup label = 20250715-013657F
2025-07-15 01:36:58.588 P00   INFO: full backup size = 44.5MB, file total = 1437
2025-07-15 01:36:58.589 P00   INFO: backup command end: completed successfully (1584ms)
2025-07-15 01:36:58.589 P00   INFO: expire command begin 2.54.2: --exec-id=88380-4b22e767 --log-level-console=info --log-level-file=info --log-path=/pg/log/pgbackrest --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/pgbackrest --repo1-retention-full=14 --repo1-retention-full-type=time --repo1-s3-bucket=pgsql --repo1-s3-endpoint=sss.pigsty --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --repo1-s3-uri-style=path --repo1-storage-ca-file=/etc/pki/ca.crt --repo1-storage-port=9000 --repo1-type=s3 --stanza=pg-meta
2025-07-15 01:36:58.593 P00   INFO: repo1: time-based archive retention not met - archive logs will not be expired
2025-07-15 01:36:58.593 P00   INFO: expire command end: completed successfully (4ms)
$ pgbackrest --stanza=pg-meta --type=diff backup
2025-07-15 01:37:24.952 P00   INFO: backup command begin 2.54.2: --annotation=pg_cluster=pg-meta --compress-type=lz4 --delta --exec-id=88431-1b8ca3e0 --expire-auto --log-level-console=info --log-level-file=info --log-path=/pg/log/pgbackrest --pg1-path=/pg/data --pg1-port=5432 --repo1-block --repo1-bundle --repo1-bundle-limit=20MiB --repo1-bundle-size=128MiB --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/pgbackrest --repo1-retention-full=14 --repo1-retention-full-type=time --repo1-s3-bucket=pgsql --repo1-s3-endpoint=sss.pigsty --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --repo1-s3-uri-style=path --repo1-storage-ca-file=/etc/pki/ca.crt --repo1-storage-port=9000 --repo1-type=s3 --stanza=pg-meta --start-fast --type=diff
2025-07-15 01:37:24.985 P00   INFO: last backup label = 20250715-013657F, version = 2.54.2
2025-07-15 01:37:24.985 P00   INFO: execute non-exclusive backup start: backup begins after the requested immediate checkpoint completes
2025-07-15 01:37:25.045 P00   INFO: backup start archive = 000000010000000000000008, lsn = 0/8000028
2025-07-15 01:37:25.045 P00   INFO: check archive for prior segment 000000010000000000000007
2025-07-15 01:37:26.204 P00   INFO: execute non-exclusive backup stop and wait for all WAL segments to archive
2025-07-15 01:37:26.220 P00   INFO: backup stop archive = 000000010000000000000008, lsn = 0/8000158
2025-07-15 01:37:26.223 P00   INFO: check archive for segment(s) 000000010000000000000008:000000010000000000000008
2025-07-15 01:37:26.337 P00   INFO: new backup label = 20250715-013657F_20250715-013724D
2025-07-15 01:37:26.381 P00   INFO: diff backup size = 424.3KB, file total = 1437
2025-07-15 01:37:26.381 P00   INFO: backup command end: completed successfully (1431ms)
2025-07-15 01:37:26.381 P00   INFO: expire command begin 2.54.2: --exec-id=88431-1b8ca3e0 --log-level-console=info --log-level-file=info --log-path=/pg/log/pgbackrest --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/pgbackrest --repo1-retention-full=14 --repo1-retention-full-type=time --repo1-s3-bucket=pgsql --repo1-s3-endpoint=sss.pigsty --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --repo1-s3-uri-style=path --repo1-storage-ca-file=/etc/pki/ca.crt --repo1-storage-port=9000 --repo1-type=s3 --stanza=pg-meta
2025-07-15 01:37:26.386 P00   INFO: repo1: time-based archive retention not met - archive logs will not be expired
2025-07-15 01:37:26.386 P00   INFO: expire command end: completed successfully (5ms)
$ pgbackrest --stanza=pg-meta --type=incr backup
2025-07-15 01:37:30.305 P00   INFO: backup command begin 2.54.2: --annotation=pg_cluster=pg-meta --compress-type=lz4 --delta --exec-id=88449-eba235f7 --expire-auto --log-level-console=info --log-level-file=info --log-path=/pg/log/pgbackrest --pg1-path=/pg/data --pg1-port=5432 --repo1-block --repo1-bundle --repo1-bundle-limit=20MiB --repo1-bundle-size=128MiB --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/pgbackrest --repo1-retention-full=14 --repo1-retention-full-type=time --repo1-s3-bucket=pgsql --repo1-s3-endpoint=sss.pigsty --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --repo1-s3-uri-style=path --repo1-storage-ca-file=/etc/pki/ca.crt --repo1-storage-port=9000 --repo1-type=s3 --stanza=pg-meta --start-fast --type=incr
2025-07-15 01:37:30.337 P00   INFO: last backup label = 20250715-013657F_20250715-013724D, version = 2.54.2
2025-07-15 01:37:30.337 P00   INFO: execute non-exclusive backup start: backup begins after the requested immediate checkpoint completes
2025-07-15 01:37:30.383 P00   INFO: backup start archive = 000000010000000000000009, lsn = 0/9000028
2025-07-15 01:37:30.383 P00   INFO: check archive for segment 000000010000000000000009
2025-07-15 01:37:31.191 P00   INFO: execute non-exclusive backup stop and wait for all WAL segments to archive
2025-07-15 01:37:31.230 P00   INFO: backup stop archive = 00000001000000000000000A, lsn = 0/A000050
2025-07-15 01:37:31.232 P00   INFO: check archive for segment(s) 000000010000000000000009:00000001000000000000000A
2025-07-15 01:37:31.356 P00   INFO: new backup label = 20250715-013657F_20250715-013730I
2025-07-15 01:37:31.403 P00   INFO: incr backup size = 8.3KB, file total = 1437
2025-07-15 01:37:31.403 P00   INFO: backup command end: completed successfully (1099ms)
2025-07-15 01:37:31.403 P00   INFO: expire command begin 2.54.2: --exec-id=88449-eba235f7 --log-level-console=info --log-level-file=info --log-path=/pg/log/pgbackrest --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/pgbackrest --repo1-retention-full=14 --repo1-retention-full-type=time --repo1-s3-bucket=pgsql --repo1-s3-endpoint=sss.pigsty --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --repo1-s3-uri-style=path --repo1-storage-ca-file=/etc/pki/ca.crt --repo1-storage-port=9000 --repo1-type=s3 --stanza=pg-meta
2025-07-15 01:37:31.409 P00   INFO: repo1: time-based archive retention not met - archive logs will not be expired
2025-07-15 01:37:31.409 P00   INFO: expire command end: completed successfully (6ms)
$ pgbackrest --stanza=pg-meta info
stanza: pg-meta
    status: ok
    cipher: aes-256-cbc

    db (current)
        wal archive min/max (17): 000000010000000000000001/00000001000000000000000A

        full backup: 20250715-013441F
            timestamp start/stop: 2025-07-15 01:34:41+00 / 2025-07-15 01:34:43+00
            wal start/stop: 000000010000000000000004 / 000000010000000000000004
            database size: 43.9MB, database backup size: 43.9MB
            repo1: backup size: 8.3MB

        full backup: 20250715-013657F
            timestamp start/stop: 2025-07-15 01:36:57+00 / 2025-07-15 01:36:58+00
            wal start/stop: 000000010000000000000006 / 000000010000000000000006
            database size: 44.5MB, database backup size: 44.5MB
            repo1: backup size: 8.7MB

        diff backup: 20250715-013657F_20250715-013724D
            timestamp start/stop: 2025-07-15 01:37:24+00 / 2025-07-15 01:37:26+00
            wal start/stop: 000000010000000000000008 / 000000010000000000000008
            database size: 44.5MB, database backup size: 424.3KB
            repo1: backup size: 94KB
            backup reference total: 1 full

        incr backup: 20250715-013657F_20250715-013730I
            timestamp start/stop: 2025-07-15 01:37:30+00 / 2025-07-15 01:37:31+00
            wal start/stop: 000000010000000000000009 / 00000001000000000000000A
            database size: 44.5MB, database backup size: 8.3KB
            repo1: backup size: 504B
            backup reference total: 1 full, 1 diff

这里的 stanza 是数据库集群名称:pg_cluster,对于默认设置是 pg-meta

Pigsty 有一个别名 pb 和包装脚本 pg-backup,它们将当前集群名称填充为 stanza:

alias
function pb() {
    local stanza=$(grep -o '\[[^][]*]' /etc/pgbackrest/pgbackrest.conf | head -n1 | sed 's/.*\[\([^]]*\)].*/\1/')
    pgbackrest --stanza=$stanza $@
}
pb ...    # pgbackrest --stanza=pg-meta ...
pb info   # pgbackrest --stanza=pg-meta info
pb backup # pgbackrest --stanza=pg-meta backup
script
pg-backup full   # 进行全量备份         = pgbackrest --stanza=pg-meta --type=full backup
pg-backup incr   # 进行增量备份  = pgbackrest --stanza=pg-meta --type=incr backup
pg-backup diff   # 进行差异备份 = pgbackrest --stanza=pg-meta --type=diff backup

定时调度

Pigsty 利用 Linux 的 crontab 来调度备份。您可以使用它定义您的备份策略。

例如,大多数单节点配置模板将为备份设置以下 node_crontab

每日凌晨1点全量备份
node_crontab: [ '00 01 * * * postgres /pg/bin/pg-backup full' ]

您可以使用 crontab 和 pg-backup 脚本设计更复杂的备份策略,例如:

周一全量备份,工作日增量备份
node_crontab:  # 周一凌晨 1 点进行全量备份,工作日进行增量备份
  - '00 01 * * 1 postgres /pg/bin/pg-backup full'
  - '00 01 * * 2,3,4,5,6,7 postgres /pg/bin/pg-backup'

要应用 crontab 更改,使用 node.yml 在所有节点上更新 crontab。

应用 crontab
./node.yml -t node_crontab -l pg-meta    # 将 crontab 更改应用到 pg-meta 组

pgbackrest

以下是 Pigsty 对 pgbackrest 的设置详情:

文件系统层次结构

  • 二进制文件:/usr/bin/pgbackrest,来自 PGDG 的 pgbackrest 包,在组别名 pgsql-common 中。
  • 配置:/etc/pgbackrest,主配置是 /etc/pgbackrest/pgbackrest.conf
  • 日志:/pg/log/pgbackrest/*,由 pgbackrest_log_dir 控制
  • 临时文件:/pg/spool 用作 pgbackrest 的临时缓冲目录
  • 数据:如果选择默认的 local 文件系统备份仓库,则使用 /pg/backup

此外,在 PITR 恢复 过程中, Pigsty 将创建一个临时的 /pg/conf/pitr.conf pgbackrest 配置文件。 并将 PostgreSQL 恢复日志写入 /pg/tmp/recovery.log 文件。

监控

有一个 pgbackrest_exporter 服务运行在(pgbackrest_exporter_port9854)上以导出 pgbackrest 指标。 您可以通过 pgbackrest_exporter_options 自定义它,并通过将 pgbackrest_exporter_enabled 设置为 false 来禁用它。

初始备份

当创建 PostgreSQL 集群时,Pigsty 会自动创建初始备份。 这是一个小备份,因为新集群几乎是空的。 它会留下一个标记文件 /etc/pgbackrest/initial.done 以避免再次创建初始备份。 如果您不想要它,请将 pgbackrest_init_backup 设置为 false


管理

启用备份

如果您的数据库集群是在 pgbackrest_enable 设置为 true 的情况下创建的,备份将自动启用。

如果是在 false 值下创建的,您可以使用以下命令启用 pgbackrest 组件:

./pgsql.yml -t pg_backup    # 运行 pgbackrest 子任务

移除备份

Pigsty 在移除主实例(pg_role = primary)时会移除 pgbackrest 备份 stanza。

./pgsql-rm.yml
./pgsql-rm.yml -e pg_rm_backup=false   # 保持备份完整
./pgsql-rm.yml -t pg_backup            # 仅移除备份

使用 pg_backup 子任务仅移除备份,并使用 pg_rm_backup 参数保留备份。

如果您的备份仓库被锁定(例如,S3 / MinIO 有锁定选项),此操作将失败。

备份移除

移除备份可能导致永久数据丢失,这是一个危险操作,请极其谨慎地执行。

列出备份

此命令将列出 pgbackrest 仓库中的所有备份(由所有集群共享)

pgbackrest info

手动备份

Pigsty 有一个内置脚本 /pg/bin/pg-backup,它封装了 pgbackrest 备份命令。

pg-backup        # 进行增量备份
pg-backup full   # 进行全量备份
pg-backup incr   # 进行增量备份
pg-backup diff   # 进行差异备份

基础备份

Pigsty 有一个替代备份脚本 /pg/bin/pg-basebackup,它不依赖 pgbackrest,并为您提供数据库集群的物理副本。 默认备份目录是 /pg/backup

NAME
  pg-basebackup  -- make base backup from PostgreSQL instance

SYNOPSIS
  pg-basebackup -sdfeukr
  pg-basebackup --src postgres:/// --dst . --file backup.tar.lz4

DESCRIPTION
-s, --src, --url     Backup source URL, optional, "postgres:///" by default, if password is required, it should be given in url, ENV or .pgpass
-d, --dst, --dir     Where to put backup files, "/pg/backup" by default
-f, --file           Overwrite default backup filename, "backup_${tag}_${date}.tar.lz4"
-r, --remove         .lz4 Files mtime before n minutes ago will be removed, default is 1200 (20hour)
-t, --tag            Backup file tag, if not set, target cluster_name or local ip address will be used. Also used as part of DEFAULT filename
-k, --key            Encryption key when --encrypt is specified, default key is ${tag}
-u, --upload         Upload backup files to cloud storage, (need your own implementation)
-e, --encryption     Encrypt with RC4 using OpenSSL, if not key is specified, tag is used as key
-h, --help           Print this message
postgres@pg-meta-1:~$ pg-basebackup
[2025-07-13 06:16:05][INFO] ================================================================
[2025-07-13 06:16:05][INFO] [INIT] pg-basebackup begin, checking parameters
[2025-07-13 06:16:05][DEBUG] [INIT] #====== BINARY
[2025-07-13 06:16:05][DEBUG] [INIT] pg_basebackup     :   /usr/pgsql/bin/pg_basebackup
[2025-07-13 06:16:05][DEBUG] [INIT] openssl           :   /usr/bin/openssl
[2025-07-13 06:16:05][DEBUG] [INIT] #====== PARAMETER
[2025-07-13 06:16:05][DEBUG] [INIT] filename  (-f)    :   backup_pg-meta_20250713.tar.lz4
[2025-07-13 06:16:05][DEBUG] [INIT] src       (-s)    :   postgres:///
[2025-07-13 06:16:05][DEBUG] [INIT] dst       (-d)    :   /pg/backup
[2025-07-13 06:16:05][DEBUG] [INIT] tag       (-t)    :   pg-meta
[2025-07-13 06:16:05][DEBUG] [INIT] key       (-k)    :   pg-meta
[2025-07-13 06:16:05][DEBUG] [INIT] encrypt   (-e)    :   false
[2025-07-13 06:16:05][DEBUG] [INIT] upload    (-u)    :   false
[2025-07-13 06:16:05][DEBUG] [INIT] remove    (-r)    :   -mmin +1200
[2025-07-13 06:16:05][INFO] [LOCK] acquire lock @ /tmp/backup.lock
[2025-07-13 06:16:05][INFO] [LOCK] lock acquired success on /tmp/backup.lock, pid=107417
[2025-07-13 06:16:05][INFO] [BKUP] backup begin, from postgres:/// to /pg/backup/backup_pg-meta_20250713.tar.lz4
[2025-07-13 06:16:05][INFO] [BKUP] backup in normal mode
pg_basebackup: initiating base backup, waiting for checkpoint to complete

pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/7000028 on timeline 1
pg_basebackup: write-ahead log end point: 0/7000FD8
pg_basebackup: syncing data to disk ...
pg_basebackup: base backup completed
[2025-07-13 06:16:06][INFO] [BKUP] backup complete!
[2025-07-13 06:16:06][INFO] [RMBK] remove local obsolete backup: 1200
[2025-07-13 06:16:06][INFO] [BKUP] find obsolete backups: find /pg/backup/ -maxdepth 1 -type f -mmin +1200 -name 'backup*.lz4'
[2025-07-13 06:16:06][WARN] [BKUP] remove obsolete backups:
[2025-07-13 06:16:06][INFO] [RMBK] remove old backup complete
[2025-07-13 06:16:06][INFO] [LOCK] release lock @ /tmp/backup.lock
[2025-07-13 06:16:06][INFO] [DONE] backup procedure complete!
[2025-07-13 06:16:06][INFO] ================================================================

备份使用 lz4 压缩,您可以使用以下命令解压缩和提取 tarball:

mkdir -p /tmp/data   # 将备份提取到此目录
cat /pg/backup/backup_pg-meta_20250713.tar.lz4 | unlz4 -d -c | tar -xC /tmp/data

逻辑备份

您也可以使用 pg_dump 命令执行逻辑备份。

逻辑备份不能用于 PITR(时间点恢复), 但它们对于在不同主版本之间迁移数据或实现灵活的数据导出逻辑很有用。

从仓库引导

现在假设您有一个现有集群 pg-meta,并且想要分叉它作为 pg-meta2

您需要创建新的 pg-meta2 集群分叉,然后在其上运行 pitr

11.15.2 - 备份仓库

PostgreSQL 的备份存储仓库

您可以通过指定 pgbackrest_repo 参数来配置存储备份的位置。 您可以在那里定义多个仓库,Pigsty 将根据 pgbackrest_method 的值选择它。

默认仓库

默认情况下,Pigsty 有两个默认备份仓库定义:localminio 备份仓库。

  • local默认,使用本地 /pg/backup 目录(软链接指向 pg_fs_backup/data/backups
  • minio:使用 SNSD 1 节点 MinIO 集群(由 pigsty 支持,但默认未启用)
pgbackrest_method: local          # 选择备份仓库方法,`local` 或 `minio` 或任何其他用户定义的仓库
pgbackrest_repo:                  # pgbackrest 仓库:https://pgbackrest.org/configuration.html#section-repository
  local:                          # 使用本地 posix fs 的默认 pgbackrest 仓库
    path: /pg/backup              # 本地备份目录,默认为 `/pg/backup`
    retention_full_type: count    # 按数量保留全量备份
    retention_full: 2             # 使用本地 fs 仓库时保留 2 个,最多 3 个全量备份
  minio:                          # pgbackrest 的可选 minio 仓库
    type: s3                      # minio 兼容 s3,所以使用 s3
    s3_endpoint: sss.pigsty       # minio 端点域名,默认为 `sss.pigsty`
    s3_region: us-east-1          # minio 区域,默认 us-east-1,对 minio 无用
    s3_bucket: pgsql              # minio 存储桶名称,默认为 `pgsql`
    s3_key: pgbackrest            # pgbackrest 的 minio 用户访问密钥
    s3_key_secret: S3User.Backup  # pgbackrest 的 minio 用户密钥
    s3_uri_style: path            # 对 minio 使用路径样式 uri 而不是主机样式
    path: /pgbackrest             # minio 备份路径,默认为 `/pgbackrest`
    storage_port: 9000            # minio 端口,默认为 9000
    storage_ca_file: /etc/pki/ca.crt  # minio ca 文件路径,默认为 `/etc/pki/ca.crt`
    block: y                      # 启用块增量备份
    bundle: y                     # 将小文件打包成单个文件
    bundle_limit: 20MiB           # 文件包限制,对象存储为 20MiB
    bundle_size: 128MiB           # 文件包目标大小,对象存储为 128MiB
    cipher_type: aes-256-cbc      # 为远程备份仓库启用 AES 加密
    cipher_pass: pgBackRest       # AES 加密密码,默认为 'pgBackRest'
    retention_full_type: time     # 在 minio 仓库上按时间保留全量备份
    retention_full: 14            # 保留最后 14 天的全量备份

保留策略

如果您每天备份而不删除它们,备份仓库将越来越大并占满您的磁盘空间。 您需要定义保留策略以仅保留有限数量的备份。

默认备份策略在 pgbackrest_repo 参数中定义,根据需要更改它们。

  • local:保留最后 2 个全量备份,备份期间最多 3 个
  • minio:保留最后 14 天内的所有全量备份

空间规划

对象存储提供几乎无限的存储容量,因此您无需担心磁盘空间。 您可以通过混合全量和差异备份策略优化空间使用。

对于本地磁盘备份仓库,pigsty 建议使用保留最后 2 个全量备份的保留策略, 这意味着在磁盘上保留两个最新的全量备份(在运行新备份时可能存在第三个副本)。

这为您提供至少最后 24 小时的保证恢复窗口。详情请查看备份策略


仓库替代方案

您也可以使用其他服务作为备份仓库,详情请查看 pgbackrest 文档


仓库版本控制

您甚至可以指定仓库目标时间以获取对象存储的快照。

您可以通过在 minio_buckets 中添加 versioning 标志来启用 MinIO 版本控制:

minio_buckets:
  - { name: pgsql ,versioning: true }
  - { name: meta  ,versioning: true }
  - { name: data }

仓库锁定

一些对象存储服务(S3、MinIO 等)支持锁定,可以防止备份被删除,即使是 DBA 本人。

您可以通过在 minio_buckets 中添加 lock 标志来启用 MinIO 锁定功能:

minio_buckets:
  - { name: pgsql , lock: true }
  - { name: meta ,versioning: true  }
  - { name: data }

使用对象存储

对象存储服务提供几乎无限的存储容量,并为您的系统提供远程灾难容错。 如果您没有对象存储,Pigsty 有内置的 MinIO 支持。

MinIO

您可以通过取消注释以下设置来启用 minio 备份仓库。 请注意,pgbackrest 只接受 HTTPS / 域名,因此您必须使用域名和 HTTPS 端点运行 MinIO。

all:
  vars:
    pgbackrest_method: minio      # 使用 minio 作为默认备份仓库
  children:                       # 定义一个单节点 minio SNSD 集群
    minio: { hosts: { 10.10.10.10: { minio_seq: 1 }} ,vars: { minio_cluster: minio }}

S3

如果您只有一个节点,有意义的备份策略可能是使用云供应商的对象存储服务,如 AWS S3、阿里云 OSS 或 Google Cloud 等… 要实现这一点,您可以定义一个新的仓库:

pgbackrest_method: s3             # 使用 'pgbackrest_repo.s3' 作为备份仓库
pgbackrest_repo:                  # pgbackrest 仓库:https://pgbackrest.org/configuration.html#section-repository

  s3:                             # 阿里云 oss(s3 兼容)对象存储服务
    type: s3                      # oss 兼容 s3
    s3_endpoint: oss-cn-beijing-internal.aliyuncs.com
    s3_region: oss-cn-beijing
    s3_bucket: <your_bucket_name>
    s3_key: <your_access_key>
    s3_key_secret: <your_secret_key>
    s3_uri_style: host
    path: /pgbackrest
    bundle: y                     # 将小文件打包成单个文件
    bundle_limit: 20MiB           # 文件包限制,对象存储为 20MiB
    bundle_size: 128MiB           # 文件包目标大小,对象存储为 128MiB
    cipher_type: aes-256-cbc      # 为远程备份仓库启用 AES 加密
    cipher_pass: pgBackRest       # AES 加密密码,默认为 'pgBackRest'
    retention_full_type: time     # 在 minio 仓库上按时间保留全量备份
    retention_full: 14            # 保留最后 14 天的全量备份

  local:                          # 使用本地 posix fs 的默认 pgbackrest 仓库
    path: /pg/backup              # 本地备份目录,默认为 `/pg/backup`
    retention_full_type: count    # 按数量保留全量备份
    retention_full: 2             # 使用本地 fs 仓库时保留 2 个,最多 3 个全量备份

管理备份

启用备份

如果您的数据库集群是在 pgbackrest_enable 设置为 true 的情况下创建的,备份将自动启用。

如果是在 false 值下创建的,您可以使用以下命令启用 pgbackrest 组件:

./pgsql.yml -t pg_backup    # 运行 pgbackrest 子任务

移除备份

Pigsty 在移除主实例(pg_role = primary)时会移除 pgbackrest 备份 stanza。

./pgsql-rm.yml
./pgsql-rm.yml -e pg_rm_backup=false   # 保持备份完整
./pgsql-rm.yml -t pg_backup            # 仅移除备份

使用 pg_backup 子任务仅移除备份,并使用 pg_rm_backup 参数保留备份。

如果您的备份仓库被锁定(例如,S3 / MinIO 有锁定选项),此操作将失败。

备份移除

移除备份可能导致永久数据丢失,这是一个危险操作,请极其谨慎地执行。

列出备份

此命令将列出 pgbackrest 仓库中的所有备份(由所有集群共享)

pgbackrest info

手动备份

Pigsty 有一个内置脚本 /pg/bin/pg-backup,它封装了 pgbackrest 备份命令。

pg-backup        # 进行增量备份
pg-backup full   # 进行全量备份
pg-backup incr   # 进行增量备份
pg-backup diff   # 进行差异备份

基础备份

Pigsty 有一个替代备份脚本 /pg/bin/pg-basebackup,它不依赖 pgbackrest,并为您提供数据库集群的物理副本。 默认备份目录是 /pg/backup

NAME
  pg-basebackup  -- make base backup from PostgreSQL instance

SYNOPSIS
  pg-basebackup -sdfeukr
  pg-basebackup --src postgres:/// --dst . --file backup.tar.lz4

DESCRIPTION
-s, --src, --url     Backup source URL, optional, "postgres:///" by default, if password is required, it should be given in url, ENV or .pgpass
-d, --dst, --dir     Where to put backup files, "/pg/backup" by default
-f, --file           Overwrite default backup filename, "backup_${tag}_${date}.tar.lz4"
-r, --remove         .lz4 Files mtime before n minutes ago will be removed, default is 1200 (20hour)
-t, --tag            Backup file tag, if not set, target cluster_name or local ip address will be used. Also used as part of DEFAULT filename
-k, --key            Encryption key when --encrypt is specified, default key is ${tag}
-u, --upload         Upload backup files to cloud storage, (need your own implementation)
-e, --encryption     Encrypt with RC4 using OpenSSL, if not key is specified, tag is used as key
-h, --help           Print this message
postgres@pg-meta-1:~$ pg-basebackup
[2025-07-13 06:16:05][INFO] ================================================================
[2025-07-13 06:16:05][INFO] [INIT] pg-basebackup begin, checking parameters
[2025-07-13 06:16:05][DEBUG] [INIT] #====== BINARY
[2025-07-13 06:16:05][DEBUG] [INIT] pg_basebackup     :   /usr/pgsql/bin/pg_basebackup
[2025-07-13 06:16:05][DEBUG] [INIT] openssl           :   /usr/bin/openssl
[2025-07-13 06:16:05][DEBUG] [INIT] #====== PARAMETER
[2025-07-13 06:16:05][DEBUG] [INIT] filename  (-f)    :   backup_pg-meta_20250713.tar.lz4
[2025-07-13 06:16:05][DEBUG] [INIT] src       (-s)    :   postgres:///
[2025-07-13 06:16:05][DEBUG] [INIT] dst       (-d)    :   /pg/backup
[2025-07-13 06:16:05][DEBUG] [INIT] tag       (-t)    :   pg-meta
[2025-07-13 06:16:05][DEBUG] [INIT] key       (-k)    :   pg-meta
[2025-07-13 06:16:05][DEBUG] [INIT] encrypt   (-e)    :   false
[2025-07-13 06:16:05][DEBUG] [INIT] upload    (-u)    :   false
[2025-07-13 06:16:05][DEBUG] [INIT] remove    (-r)    :   -mmin +1200
[2025-07-13 06:16:05][INFO] [LOCK] acquire lock @ /tmp/backup.lock
[2025-07-13 06:16:05][INFO] [LOCK] lock acquired success on /tmp/backup.lock, pid=107417
[2025-07-13 06:16:05][INFO] [BKUP] backup begin, from postgres:/// to /pg/backup/backup_pg-meta_20250713.tar.lz4
[2025-07-13 06:16:05][INFO] [BKUP] backup in normal mode
pg_basebackup: initiating base backup, waiting for checkpoint to complete

pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/7000028 on timeline 1
pg_basebackup: write-ahead log end point: 0/7000FD8
pg_basebackup: syncing data to disk ...
pg_basebackup: base backup completed
[2025-07-13 06:16:06][INFO] [BKUP] backup complete!
[2025-07-13 06:16:06][INFO] [RMBK] remove local obsolete backup: 1200
[2025-07-13 06:16:06][INFO] [BKUP] find obsolete backups: find /pg/backup/ -maxdepth 1 -type f -mmin +1200 -name 'backup*.lz4'
[2025-07-13 06:16:06][WARN] [BKUP] remove obsolete backups:
[2025-07-13 06:16:06][INFO] [RMBK] remove old backup complete
[2025-07-13 06:16:06][INFO] [LOCK] release lock @ /tmp/backup.lock
[2025-07-13 06:16:06][INFO] [DONE] backup procedure complete!
[2025-07-13 06:16:06][INFO] ================================================================

备份使用 lz4 压缩,您可以使用以下命令解压缩和提取 tarball:

mkdir -p /tmp/data   # 将备份提取到此目录
cat /pg/backup/backup_pg-meta_20250713.tar.lz4 | unlz4 -d -c | tar -xC /tmp/data

逻辑备份

您也可以使用 pg_dump 命令执行逻辑备份。

逻辑备份不能用于 PITR(时间点恢复), 但它们对于在不同主版本之间迁移数据或实现灵活的数据导出逻辑很有用。

从仓库引导

现在假设您有一个现有集群 pg-meta,并且想要分叉它作为 pg-meta2

您需要创建新的 pg-meta2 集群分叉,然后在其上运行 pitr

11.15.3 - 备份策略

根据您的需求设计备份策略。
  • 何时:备份策略
  • 何地:备份仓库
  • 如何:备份方法

何时备份

第一个问题是何时备份您的数据库——在备份频率和恢复时间之间做权衡。 由于您需要回放 WAL 日志到从上次备份以来的恢复目标, 备份越频繁,需要回放的 WAL 日志就越少,恢复就越快。

每日全量备份

对于生产数据库,建议从最简单的每日全量备份策略开始。 这是 Pigsty 中的默认备份策略,通过 crontab 实现。

每日凌晨1点全量备份
node_crontab: [ '00 01 * * * postgres /pg/bin/pg-backup full' ]
pgbackrest_method: local          # 选择备份仓库方法,`local` 或 `minio` 或任何其他用户定义的仓库
pgbackrest_repo:                  # pgbackrest 仓库:https://pgbackrest.org/configuration.html#section-repository
  local:                          # 使用本地 POSIX 文件系统的默认 pgbackrest 仓库
    path: /pg/backup              # 本地备份目录,默认为 `/pg/backup`
    retention_full_type: count    # 按数量保留全量备份
    retention_full: 2             # 保留 2 个,使用本地文件系统仓库时最多 3 个全量备份

当使用默认的 local 文件系统备份仓库时,它提供 24~48 小时的恢复窗口。

假设您的数据库大小为 100GB,每天写入 10GB,您的备份大小将是:

它将消耗数据库大小的 2 ~ 3 倍,加上 2 天的 WAL。 因此在实践中,您可能需要准备至少数据库大小 3 ~ 5 倍 的备份磁盘 来使用默认备份策略。

全量 + 增量备份

您可以通过更改这些参数来优化备份空间使用。

如果您使用 MinIO / S3 作为集中式备份仓库,您可以使用比磁盘限制更多的空间。 那么考虑使用 2 周保留策略的全量 + 增量备份:

node_crontab:  # 周一凌晨 1 点进行全量备份,工作日进行增量备份
  - '00 01 * * 1 postgres /pg/bin/pg-backup full'
  - '00 01 * * 2,3,4,5,6,7 postgres /pg/bin/pg-backup'
pgbackrest_method: minio
pgbackrest_repo:                  # pgbackrest 仓库:https://pgbackrest.org/configuration.html#section-repository
  minio:                          # pgbackrest 的可选 minio 仓库
    type: s3                      # minio 兼容 s3,所以使用 s3
    s3_endpoint: sss.pigsty       # minio 端点域名,默认为 `sss.pigsty`
    s3_region: us-east-1          # minio 区域,默认为 us-east-1,对 minio 无用
    s3_bucket: pgsql              # minio 存储桶名称,默认为 `pgsql`
    s3_key: pgbackrest            # pgbackrest 的 minio 用户访问密钥
    s3_key_secret: S3User.Backup  # pgbackrest 的 minio 用户秘密密钥
    s3_uri_style: path            # 对 minio 使用路径样式 URI 而不是主机样式
    path: /pgbackrest             # minio 备份路径,默认为 `/pgbackrest`
    storage_port: 9000            # minio 端口,默认为 9000
    storage_ca_file: /etc/pki/ca.crt  # minio ca 文件路径,默认为 `/etc/pki/ca.crt`
    block: y                      # 启用块增量备份
    bundle: y                     # 将小文件打包成单个文件
    bundle_limit: 20MiB           # 文件包的限制,对象存储为 20MiB
    bundle_size: 128MiB           # 文件包的目标大小,对象存储为 128MiB
    cipher_type: aes-256-cbc      # 为远程备份仓库启用 AES 加密
    cipher_pass: pgBackRest       # AES 加密密码,默认为 'pgBackRest'
    retention_full_type: time     # 在 minio 仓库上按时间保留全量备份
    retention_full: 14            # 保留最近 14 天的全量备份

当使用内置的 minio 文件系统备份仓库时,它提供有保证的 1 周 PITR 窗口。

假设您的数据库大小为 100GB,每天写入 10GB,您的备份大小将如下所示:


备份位置

默认情况下,Pigsty 有两个默认备份仓库定义:localminio 备份仓库。

  • local默认,使用本地 /pg/backup 目录(软链接指向 pg_fs_backup/data/backups
  • minio:使用 SNSD 1 节点 MinIO 集群(由 Pigsty 支持,但默认未启用)
pgbackrest_method: local          # 选择备份仓库方法,`local` 或 `minio` 或任何其他用户定义的仓库
pgbackrest_repo:                  # pgbackrest 仓库:https://pgbackrest.org/configuration.html#section-repository
  local:                          # 使用本地 POSIX 文件系统的默认 pgbackrest 仓库
    path: /pg/backup              # 本地备份目录,默认为 `/pg/backup`
    retention_full_type: count    # 按数量保留全量备份
    retention_full: 2             # 保留 2 个,使用本地文件系统仓库时最多 3 个全量备份
  minio:                          # pgbackrest 的可选 minio 仓库
    type: s3                      # minio 兼容 s3,所以使用 s3
    s3_endpoint: sss.pigsty       # minio 端点域名,默认为 `sss.pigsty`
    s3_region: us-east-1          # minio 区域,默认为 us-east-1,对 minio 无用
    s3_bucket: pgsql              # minio 存储桶名称,默认为 `pgsql`
    s3_key: pgbackrest            # pgbackrest 的 minio 用户访问密钥
    s3_key_secret: S3User.Backup  # pgbackrest 的 minio 用户秘密密钥
    s3_uri_style: path            # 对 minio 使用路径样式 URI 而不是主机样式
    path: /pgbackrest             # minio 备份路径,默认为 `/pgbackrest`
    storage_port: 9000            # minio 端口,默认为 9000
    storage_ca_file: /etc/pki/ca.crt  # minio ca 文件路径,默认为 `/etc/pki/ca.crt`
    block: y                      # 启用块增量备份
    bundle: y                     # 将小文件打包成单个文件
    bundle_limit: 20MiB           # 文件包的限制,对象存储为 20MiB
    bundle_size: 128MiB           # 文件包的目标大小,对象存储为 128MiB
    cipher_type: aes-256-cbc      # 为远程备份仓库启用 AES 加密
    cipher_pass: pgBackRest       # AES 加密密码,默认为 'pgBackRest'
    retention_full_type: time     # 在 minio 仓库上按时间保留全量备份
    retention_full: 14            # 保留最近 14 天的全量备份

11.15.4 - 备份管理

管理备份仓库和备份

启用备份

如果您的数据库集群是在 pgbackrest_enable 设置为 true 的情况下创建的,备份将自动启用。

如果是在 false 值下创建的,您可以使用以下命令启用 pgbackrest 组件:

./pgsql.yml -t pg_backup    # 运行 pgbackrest 子任务

移除备份

Pigsty 在移除主实例(pg_role = primary)时会移除 pgbackrest 备份 stanza。

./pgsql-rm.yml
./pgsql-rm.yml -e pg_rm_backup=false   # 保持备份完整
./pgsql-rm.yml -t pg_backup            # 仅移除备份

使用 pg_backup 子任务仅移除备份,并使用 pg_rm_backup 参数保留备份。

如果您的备份仓库被锁定(例如,S3 / MinIO 有锁定选项),此操作将失败。

备份移除

移除备份可能导致永久数据丢失,这是一个危险操作,请极其谨慎地执行。


列出备份

此命令将列出 pgbackrest 仓库中的所有备份(由所有集群共享)

pgbackrest info

手动备份

Pigsty 有一个内置脚本 /pg/bin/pg-backup,它封装了 pgbackrest 备份命令。

pg-backup        # 进行增量备份
pg-backup full   # 进行全量备份
pg-backup incr   # 进行增量备份
pg-backup diff   # 进行差异备份

基础备份

Pigsty 有一个替代备份脚本 /pg/bin/pg-basebackup,它不依赖 pgbackrest,并为您提供数据库集群的物理副本。 默认备份目录是 /pg/backup

NAME
  pg-basebackup  -- make base backup from PostgreSQL instance

SYNOPSIS
  pg-basebackup -sdfeukr
  pg-basebackup --src postgres:/// --dst . --file backup.tar.lz4

DESCRIPTION
-s, --src, --url     Backup source URL, optional, "postgres:///" by default, if password is required, it should be given in url, ENV or .pgpass
-d, --dst, --dir     Where to put backup files, "/pg/backup" by default
-f, --file           Overwrite default backup filename, "backup_${tag}_${date}.tar.lz4"
-r, --remove         .lz4 Files mtime before n minutes ago will be removed, default is 1200 (20hour)
-t, --tag            Backup file tag, if not set, target cluster_name or local ip address will be used. Also used as part of DEFAULT filename
-k, --key            Encryption key when --encrypt is specified, default key is ${tag}
-u, --upload         Upload backup files to cloud storage, (need your own implementation)
-e, --encryption     Encrypt with RC4 using OpenSSL, if not key is specified, tag is used as key
-h, --help           Print this message
postgres@pg-meta-1:~$ pg-basebackup
[2025-07-13 06:16:05][INFO] ================================================================
[2025-07-13 06:16:05][INFO] [INIT] pg-basebackup begin, checking parameters
[2025-07-13 06:16:05][DEBUG] [INIT] #====== BINARY
[2025-07-13 06:16:05][DEBUG] [INIT] pg_basebackup     :   /usr/pgsql/bin/pg_basebackup
[2025-07-13 06:16:05][DEBUG] [INIT] openssl           :   /usr/bin/openssl
[2025-07-13 06:16:05][DEBUG] [INIT] #====== PARAMETER
[2025-07-13 06:16:05][DEBUG] [INIT] filename  (-f)    :   backup_pg-meta_20250713.tar.lz4
[2025-07-13 06:16:05][DEBUG] [INIT] src       (-s)    :   postgres:///
[2025-07-13 06:16:05][DEBUG] [INIT] dst       (-d)    :   /pg/backup
[2025-07-13 06:16:05][DEBUG] [INIT] tag       (-t)    :   pg-meta
[2025-07-13 06:16:05][DEBUG] [INIT] key       (-k)    :   pg-meta
[2025-07-13 06:16:05][DEBUG] [INIT] encrypt   (-e)    :   false
[2025-07-13 06:16:05][DEBUG] [INIT] upload    (-u)    :   false
[2025-07-13 06:16:05][DEBUG] [INIT] remove    (-r)    :   -mmin +1200
[2025-07-13 06:16:05][INFO] [LOCK] acquire lock @ /tmp/backup.lock
[2025-07-13 06:16:05][INFO] [LOCK] lock acquired success on /tmp/backup.lock, pid=107417
[2025-07-13 06:16:05][INFO] [BKUP] backup begin, from postgres:/// to /pg/backup/backup_pg-meta_20250713.tar.lz4
[2025-07-13 06:16:05][INFO] [BKUP] backup in normal mode
pg_basebackup: initiating base backup, waiting for checkpoint to complete

pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/7000028 on timeline 1
pg_basebackup: write-ahead log end point: 0/7000FD8
pg_basebackup: syncing data to disk ...
pg_basebackup: base backup completed
[2025-07-13 06:16:06][INFO] [BKUP] backup complete!
[2025-07-13 06:16:06][INFO] [RMBK] remove local obsolete backup: 1200
[2025-07-13 06:16:06][INFO] [BKUP] find obsolete backups: find /pg/backup/ -maxdepth 1 -type f -mmin +1200 -name 'backup*.lz4'
[2025-07-13 06:16:06][WARN] [BKUP] remove obsolete backups:
[2025-07-13 06:16:06][INFO] [RMBK] remove old backup complete
[2025-07-13 06:16:06][INFO] [LOCK] release lock @ /tmp/backup.lock
[2025-07-13 06:16:06][INFO] [DONE] backup procedure complete!
[2025-07-13 06:16:06][INFO] ================================================================

备份使用 lz4 压缩,您可以使用以下命令解压缩和提取 tarball:

mkdir -p /tmp/data   # 将备份提取到此目录
cat /pg/backup/backup_pg-meta_20250713.tar.lz4 | unlz4 -d -c | tar -xC /tmp/data

逻辑备份

您也可以使用 pg_dump 命令执行逻辑备份。

逻辑备份不能用于 PITR(时间点恢复),但它们对于在不同主版本之间迁移数据或实现灵活的数据导出逻辑很有用。


从备份仓库中恢复

现在假设您有一个现有集群 pg-meta,并且想要分叉它作为 pg-meta2

您需要创建新的 pg-meta2 集群分叉,然后在其上运行 pitr任务,来实现从备份仓库中恢复的效果。

11.15.5 - 时间点恢复

从备份恢复 PostgreSQL

您可以使用预配置的 pgbackrest 在 Pigsty 中执行时间点恢复(PITR)。

  • 手动方式:使用 pg-pitr 提示脚本进行 PITR,手动操作,更灵活但更复杂。
  • 剧本方式:使用 pgsql-pitr.yml 剧本进行 PITR,自动化,但灵活性较低且更容易出错。

如果您对配置非常熟悉,可以使用全自动剧本, 否则,考虑逐步手动操作


快速开始

如果您想将 pg-meta 集群回滚到之前的时间点,添加 pg_pitr

pg-meta:
  hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
  vars:
    pg_cluster: pg-meta2
    pg_pitr: { time: '2025-07-13 10:00:00+00' }  # 从最新备份恢复

然后运行 pgsql-pitr.yml 剧本,它将把 pg-meta 集群回滚到指定的时间点。

./pgsql-pitr.yml -l pg-meta

恢复 PITR

恢复的集群上的 archive_mode 将被禁用,以防止不必要的 WAL 写入。 如果恢复的数据库状态正常,您可以启用 archive_mode 并进行全量备份。

postgres @ pg-meta $
psql -c 'ALTER SYSTEM RESET archive_mode; SELECT pg_reload_conf();'
pg-backup full    # 进行新的全量备份

恢复目标

您可以在 pg_pitr 中指定不同类型的恢复目标,但它们是互斥的:

  • time:恢复到哪个时间点?
  • name:恢复到命名的恢复点(由 pg_create_restore_point 创建)
  • xid:恢复到特定的事务 ID(TXID/XID)
  • lsn:恢复到特定的 LSN(日志序列号)点

如果指定了上述任何参数,恢复 type 将相应设置, 否则将设置为 latest(WAL 归档流的末尾)。 特殊的 immediate 类型可用于指示 pgbackrest 通过在第一个一致点停止来最小化恢复时间。

目标类型

pg_pitr: { }  # 恢复到最新状态(wal 归档流结束)
pg_pitr: { time: "2025-07-13 10:00:00+00" }
pg_pitr: { lsn: "0/4001C80" }
pg_pitr: { xid: "250000" }
pg_pitr: { name: "some_restore_point" }
pg_pitr: { type: "immediate" }

按时间

最常用的目标是时间点;您可以指定要恢复到的时间点:

恢复到时间点
./pgsql-pitr.yml -e '{"pg_pitr": { "time": "2025-07-13 10:00:00+00" }}'

时间应该是有效的 PostgreSQL TIMESTAMP,建议使用 YYYY-MM-DD HH:MM:SS+TZ

按名称

您可以使用 pg_create_restore_point 创建命名的恢复点:

SELECT pg_create_restore_point('shit_incoming');

并在 PITR 中使用该命名恢复点:

./pgsql-pitr.yml -e '{"pg_pitr": { "name": "shit_incoming" }}'

按 XID

如果您有一个意外删除某些数据的事务,最好的恢复方法是将数据库恢复到该事务之前的状态。

恢复到事务之前
./pgsql-pitr.yml -e '{"pg_pitr": { "xid": "250000", exclusive: true }}'

您可以从监控仪表板找到确切的事务 ID,或从 CSVLOG 的 TXID 中找到它。

包含 vs 排除

目标参数默认是"包含"的,这意味着恢复将包含目标点。 exclusive 标志将排除那个确切的目标,比如 xid 24999 将是最后一个被重放的事务

这仅适用于 timexidlsn 恢复目标,详情请查看 recovery_target_inclusive

按 LSN

PostgreSQL 使用 LSN(日志序列号)来标识 WAL 记录的位置。 您可以在任何地方找到它,比如 Pigsty 仪表板的 PG LSN 面板。

恢复到 LSN
./pgsql-pitr.yml -e '{"pg_pitr": { "lsn": "0/4001C80", timeline: "1" }}'

要恢复到 WAL 流中的确切点,您还可以指定 timeline 参数(默认为 latest


恢复来源

  • cluster:恢复哪个集群?默认使用当前的 pg_cluster,您可以在同一个 pgbackrest 仓库中使用任何其他集群
  • repo:覆盖备份仓库,使用与 pgbackrest_repo 相同的格式
  • set:默认使用 latest 备份集,但您可以指定特定的 pgbackrest 备份标签

Pigsty 将从 pgbackrest 备份仓库恢复,如果您使用集中式备份仓库(如 MinIO/S3), 您可以指定另一个"stanza"(另一个集群的备份目录)来恢复。

pg-meta2:
  hosts: { 10.10.10.11: { pg_seq: 1, pg_role: primary } }
  vars:
    pg_cluster: pg-meta2
    pg_pitr: { cluster: pg-meta }  # 从 pg-meta 集群备份恢复

上述配置将标记 PITR 过程使用 pg-meta stanza。 您也可以通过 CLI 参数传递 pg_pitr 参数:

使用 pg-meta 备份恢复 pg-meta2
./pgsql-pitr.yml -l pg-meta2 -e '{"pg_pitr": { "cluster": "pg-meta" }}'

从另一个集群进行 pitr 时,您也可以使用这些目标:

./pgsql-pitr.yml -l pg-meta2 -e '{"pg_pitr": { "cluster": "pg-meta", "time": "2025-07-14 08:00:00+00" }}'

分步执行

这种方法是半自动的,您将参与 PITR 过程以做出关键决策。

例如,此配置将把 pg-meta 集群本身恢复到指定的时间点

pg-meta:
  hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
  vars:
    pg_cluster: pg-meta2
    pg_pitr: { time: '2025-07-13 10:00:00+00' }  # 从最新备份恢复

让我们逐步执行:

./pgsql-pitr.yml -l pg-meta -t down     # 暂停 patroni HA
./pgsql-pitr.yml -l pg-meta -t pitr     # 运行 pitr 过程
./pgsql-pitr.yml -l pg-meta -t up       # 生成 pgbackrest 配置和恢复脚本
# down                 : # 停止 ha 并关闭 patroni 和 postgres
#   - pause            : # 暂停 patroni 自动故障转移
#   - stop             : # 停止 patroni 和 postgres 服务
#     - stop_patroni   : # 停止 patroni 服务
#     - stop_postgres  : # 停止 postgres 服务
# pitr                 : # 执行 PITR 过程
#   - config           : # 生成 pgbackrest 配置和恢复脚本
#   - restore          : # 运行 pgbackrest 恢复命令
#   - recovery         : # 启动 postgres 并完成恢复
#   - verify           : # 验证恢复的集群控制数据
# up:                  : # 启动 postgres / patroni 并恢复 ha
#   - etcd             : # 在启动前清理 etcd 元数据
#   - start            : # 启动 patroni 和 postgres 服务
#     - start_postgres : # 启动 postgres 服务
#     - start_patroni  : # 启动 patroni 服务
#   - resume           : # 恢复 patroni 自动故障转移

PITR 定义

pg_pitr 参数中有更多可用选项,以下是一些可用的参考项:

pg_pitr:                          # 定义 PITR 任务
    cluster: "some_pg_cls_name"   # 源集群名称
    type: latest                  # 恢复目标类型:time、xid、name、lsn、immediate、latest
    time: "2025-01-01 10:00:00+00" # 恢复目标:时间,与 xid、name、lsn 互斥
    name: "some_restore_point"    # 恢复目标:命名恢复点,与 time、xid、lsn 互斥
    xid:  "100000"                # 恢复目标:事务 ID,与 time、name、lsn 互斥
    lsn:  "0/3000000"             # 恢复目标:日志序列号,与 time、name、xid 互斥
    timeline: latest              # 目标时间线,可以是整数,默认为 latest
    exclusive: false              # 排除目标点,默认为 false?
    action: pause                 # 恢复后操作:pause、promote、shutdown
    archive: false                # 保留归档设置?默认为 false
    db_exclude: [ template0, template1 ]
    db_include: []
    link_map:
      pg_wal: '/data/wal'
      pg_xact: '/data/pg_xact'
    process: 4                    # 并行恢复进程
    repo: {}                      # 要恢复的仓库
    data: /pg/data                # 恢复数据的位置
    port: 5432                    # 恢复实例的监听端口

11.15.6 - 示例

在沙盒环境中根据提示脚本手动执行 PITR

您可以使用 pgsql-pitr 剧本执行 PITR,但在某些情况下,您可能希望手动执行 PITR。 我们将使用带有 MinIO 备份仓库的 4 节点沙盒环境 集群来演示该过程。


初始化沙盒

使用 vagrantterraform 准备 4 节点沙盒环境,然后:

curl https://repo.pigsty.io/get | bash -s v3.7.0; cd ~/pigsty/
./configure -c full
./install

现在在管理节点上以管理员用户(或 dbsu)身份操作以继续。

pigsty-sandbox.jpg

检查备份

要检查备份状态,您需要切换到 postgres 用户并使用 pb 命令:

sudo su - postgres    # 切换到 dbsu:postgres 用户
pb info               # 打印 pgbackrest 备份信息

pbpgbackrest 的别名,会自动从 pgbackrest 配置中获取 stanza 名称。

/etc/profile.d/pg-alias.sh
function pb() {
    local stanza=$(grep -o '\[[^][]*]' /etc/pgbackrest/pgbackrest.conf | head -n1 | sed 's/.*\[\([^]]*\)].*/\1/')
    pgbackrest --stanza=$stanza $@
}

您可以看到初始备份信息,这是在以下时间创建的全量备份:

root@pg-meta-1:~# pb info
stanza: pg-meta
    status: ok
    cipher: aes-256-cbc

    db (current)
        wal archive min/max (17): 000000010000000000000001/000000010000000000000007

        full backup: 20250713-022731F
            timestamp start/stop: 2025-07-13 02:27:31+00 / 2025-07-13 02:27:33+00
            wal start/stop: 000000010000000000000004 / 000000010000000000000004
            database size: 44MB, database backup size: 44MB
            repo1: backup size: 8.4MB

备份完成于 2025-07-13 02:27:33+00,这是您可以恢复到的最早时间。 由于 WAL 归档处于活动状态,您可以恢复到备份后直到 WAL 结束(现在)的任何时间点。


生成心跳

您可以生成一些心跳来模拟工作负载。/pg-bin/pg-heartbeat 就是为此目的, 它将每秒向 monitor.heartbeat 表写入一个心跳时间戳。

make rh     # 运行心跳:ssh 10.10.10.10 'sudo -iu postgres /pg/bin/pg-heartbeat'
ssh 10.10.10.10 'sudo -iu postgres /pg/bin/pg-heartbeat'
   cls   |              ts               |    lsn     |  lsn_int  | txid | status  |       now       |  elapse
---------+-------------------------------+------------+-----------+------+---------+-----------------+----------
 pg-meta | 2025-07-13 03:01:20.318234+00 | 0/115BF5C0 | 291239360 | 4812 | leading | 03:01:20.318234 | 00:00:00

您甚至可以为集群添加更多工作负载,让我们使用 pgbench 生成一些随机写入:

make ri     # 初始化 pgbench
make rw     # 运行 pgbench 读写工作负载
pgbench -is10 postgres://dbuser_meta:[email protected]:5433/meta
while true; do pgbench -nv -P1 -c4 --rate=64 -T10 postgres://dbuser_meta:[email protected]:5433/meta; done
while true; do pgbench -nv -P1 -c4 --rate=64 -T10 postgres://dbuser_meta:[email protected]:5433/meta; done
pgbench (17.5 (Homebrew), server 17.4 (Ubuntu 17.4-1.pgdg24.04+2))
progress: 1.0 s, 60.9 tps, lat 7.295 ms stddev 4.219, 0 failed, lag 1.818 ms
progress: 2.0 s, 69.1 tps, lat 6.296 ms stddev 1.983, 0 failed, lag 1.397 ms
...

手动 PITR

现在让我们选择一个恢复的时间点,比如说 2025-07-13 03:03:03+00,这是初始备份(和心跳)之后的时间点。 要执行手动 PITR,请使用 pg-pitr 工具:

$ pg-pitr -t "2025-07-13 03:03:00+00"

它将为您生成执行恢复的说明,通常需要四个步骤:

Perform time PITR on pg-meta
[1. Stop PostgreSQL] ===========================================
   1.1 暂停 Patroni(如果有任何副本)
       $ pg pause <cls>  # 暂停 patroni 自动故障转移
   1.2 关闭 Patroni
       $ pt-stop         # sudo systemctl stop patroni
   1.3 关闭 Postgres
       $ pg-stop         # pg_ctl -D /pg/data stop -m fast

[2. Perform PITR] ===========================================
   2.1 恢复备份
       $ pgbackrest --stanza=pg-meta --type=time --target='2025-07-13 03:03:00+00' restore
   2.2 启动 PG 以重放 WAL
       $ pg-start        # pg_ctl -D /pg/data start
   2.3 验证并提升
     - 如果数据库内容正确,提升它以完成恢复,否则转到 2.1
       $ pg-promote      # pg_ctl -D /pg/data promote

[3. Restore Primary] ===========================================
   3.1 启用归档模式(需要重启)
       $ psql -c 'ALTER SYSTEM SET archive_mode = on;'
   3.1 重启 Postgres 以应用更改
       $ pg-restart      # pg_ctl -D /pg/data restart
   3.3 重启 Patroni
       $ pt-restart      # sudo systemctl restart patroni

[4. Restore Cluster] ===========================================
   4.1 重新初始化所有**副本**(如果有)
       - 4.1.1 选项 1:使用相同的 pgbackrest 命令恢复副本(需要中央备份仓库)
           $ pgbackrest --stanza=pg-meta --type=time --target='2025-07-13 03:03:00+00' restore
       - 4.1.2 选项 2:清除副本数据目录并重启 patroni(可能需要很长时间恢复)
           $ rm -rf /pg/data/*; pt-restart
       - 4.1.3 选项 3:使用 patroni 重新初始化,如果主 lsn < 副本 lsn 可能会失败
           $ pg reinit pg-meta
   4.2 恢复 Patroni
       $ pg resume pg-meta
   4.3 全量备份(可选)
       $ pg-backup full      # 建议在 PITR 后进行新的全量备份

单节点示例

让我们以简单的单节点 pg-meta 集群为例开始,这比较简单。

关闭数据库

pt-stop         # sudo systemctl stop patroni,关闭 patroni(和 postgres)
$ pg_stop        # pg_ctl -D /pg/data stop -m fast,关闭 postgres

pg_ctl: PID file "/pg/data/postmaster.pid" does not exist
Is server running?

$ pg-ps           # 打印与 postgres 相关的进程

 UID         PID   PPID  C STIME TTY      STAT   TIME CMD
postgres  31048      1  0 02:27 ?        Ssl    0:19 /usr/sbin/pgbouncer /etc/pgbouncer/pgbouncer.ini
postgres  32026      1  0 02:28 ?        Ssl    0:03 /usr/bin/pg_exporter --web.listen-address=:9630 --log.level=info
postgres  32252      1  0 02:28 ?        Ssl    0:00 /usr/bin/pg_exporter --web.listen-address=:9631 --log.level=info
postgres  32460      1  0 02:28 ?        Ssl    0:00 /usr/bin/pgbackrest_exporter --log.level=info
postgres  35480  35479  0 03:00 pts/2    S      0:00 -bash
postgres  35510  35480  0 03:01 pts/2    S+     0:00 /bin/bash /pg/bin/pg-heartbeat
postgres  37183  37182  0 03:07 pts/4    S      0:00 -bash
postgres  38627  35510  0 03:14 pts/2    S+     0:00 sleep 1

确保本地 postgres 没有运行,然后执行手册中给出的恢复命令:

恢复备份

pgbackrest --stanza=pg-meta --type=time --target='2025-07-13 03:03:00+00' restore
postgres@pg-meta-1:~$ pgbackrest --stanza=pg-meta --type=time --target='2025-07-13 03:03:00+00' restore
2025-07-13 03:17:07.443 P00   INFO: restore command begin 2.54.2: --archive-mode=off --delta --exec-id=38997-5c07abb3 --log-level-console=info --log-level-file=info --log-path=/pg/log/pgbackrest --pg1-path=/pg/data --process-max=2 --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/pgbackrest --repo1-s3-bucket=pgsql --repo1-s3-endpoint=sss.pigsty --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --repo1-s3-uri-style=path --repo1-storage-ca-file=/etc/pki/ca.crt --repo1-storage-port=9000 --repo1-type=s3 --spool-path=/pg/spool --stanza=pg-meta --target="2025-07-13 03:03:00+00" --type=time
2025-07-13 03:17:07.470 P00   INFO: repo1: restore backup set 20250713-022731F, recovery will start at 2025-07-13 02:27:31
2025-07-13 03:17:07.471 P00   INFO: remove invalid files/links/paths from '/pg/data'
2025-07-13 03:17:08.523 P00   INFO: write updated /pg/data/postgresql.auto.conf
2025-07-13 03:17:08.526 P00   INFO: restore global/pg_control (performed last to ensure aborted restores cannot be started)
2025-07-13 03:17:08.527 P00   INFO: restore size = 44MB, file total = 1436
2025-07-13 03:17:08.527 P00   INFO: restore command end: completed successfully (1087ms)

验证数据

我们不希望 patroni HA 在确保数据正确之前接管,所以我们手动启动 postgres:

pg-start
waiting for server to start....2025-07-13 03:19:33.133 UTC [39294] LOG:  redirecting log output to logging collector process
2025-07-13 03:19:33.133 UTC [39294] HINT:  Future log output will appear in directory "/pg/log/postgres".
 done
server started

现在您可以检查数据,看看它是否在您想要的时间点。 您可以通过检查业务表中的一些最新时间戳来验证它,或者在这种情况下,通过心跳表进行检查。

postgres@pg-meta-1:~$ psql -c 'table monitor.heartbeat'
   id    |              ts               |    lsn    | txid
---------+-------------------------------+-----------+------
 pg-meta | 2025-07-13 03:02:59.214104+00 | 302005504 | 4912

时间戳正好在我们指定的时间点之前!(2025-07-13 03:03:00+00)。 如果这不是您想要的时间点,您可以使用不同的时间点重复恢复。 由于恢复是以增量和并行方式执行的,所以很快。 重试直到获得正确的时间点是可以的。

提升为主节点

恢复的 postgres 集群处于 recovery 模式,因此在您将其提升为主节点之前,它将拒绝任何写入操作。 这些恢复参数由 pgBackRest 在配置文件中生成。

/pg/data/postgresql.auto.conf
postgres@pg-meta-1:~$ cat /pg/data/postgresql.auto.conf
# Do not edit this file or use ALTER SYSTEM manually!
# It is managed by Pigsty & Ansible automatically!

# Recovery settings generated by pgBackRest restore on 2025-07-13 03:17:08
archive_mode = 'off'
restore_command = 'pgbackrest --stanza=pg-meta archive-get %f "%p"'
recovery_target_time = '2025-07-13 03:03:00+00'

如果数据正确,您可以将其提升为主节点,将其标记为新的领导者并准备接受写入。

pg-promote
waiting for server to promote.... done
server promoted
psql -c 'SELECT pg_is_in_recovery()'   # 'f' 表示它已提升为主节点
 pg_is_in_recovery
-------------------
 f
(1 row)
新时间线和脑裂

一旦提升,数据库集群将进入新的时间线(主节点纪元)。 如果有任何写入流量,它将被写入新的时间线。

恢复集群

最后,不仅数据需要恢复,集群状态也需要恢复,例如:

  • patroni 接管
  • 归档模式
  • 备份集
  • 副本

Patroni 接管

您的 postgres 直接启动,要恢复 HA 接管;您必须启动 patroni 服务:

pt-start   # sudo systemctl start patroni
pg resume pg-meta      # 恢复 patroni 自动故障转移(如果您之前暂停了它)

归档模式

archive_mode 在恢复期间被 pgbackrest 禁用。 如果您希望新主节点的写入被归档到备份仓库中,您还需要启用 archive_mode 配置。

psql -c 'show archive_mode'

 archive_mode
--------------
 off
psql -c 'ALTER SYSTEM RESET archive_mode;'
psql -c 'SELECT pg_reload_conf();'
psql -c 'show archive_mode'
# 您也可以直接编辑 postgresql.auto.conf 并使用 pg_ctl 重新加载
sed -i '/archive_mode/d' /pg/data/postgresql.auto.conf
pg_ctl -D /pg/data reload

备份集

在 PITR 后进行新的全量备份通常是一个好主意,但这是可选的。

副本

如果您的 postgres 集群有副本,您需要在每个副本上也执行 PITR。 或者,简单的方法是清除副本数据目录并重启 patroni,这将从主节点重新初始化副本。 我们将在下一个多节点集群示例中介绍这种情况。

11.16 - 内核

您可以在 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 处理
说明

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

11.16.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

详情请参考 扩展目录

11.16.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'  }

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

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

11.16.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 兼容性

11.16.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 内核承担任何保证,任何问题或请求应联系制造商。

11.16.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

11.16.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 运行。

11.16.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;

11.16.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 内核提供任何保证。使用此内核时遇到的任何问题或需求应与原始供应商联系。

11.16.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 连接到段

11.16.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.16.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 的支持命令列表已知差异说明了兼容边界;对基本使用场景而言,这些差异通常影响不大。

11.17 - 扩展

利用 PostgreSQL 扩展的协同超能力

Pigsty 允许您通过三样东西来利用 Postgres 扩展生态系统的协同超能力:目录、仓库和 pig。

扩展目录
    完整的 <span class="text-lg font-black text-emerald-500">437</span> 可用 PostgreSQL 扩展列表
软件仓库
    提供 PostgreSQL 扩展的 APT/YUM 仓库
包管理器
    PostgreSQL 和扩展缺失的包管理器
快速开始
    如何获取、安装、配置、管理这些扩展?

v3.7.0 扩展目录共收录 437 个 PostgreSQL 扩展,且 PostgreSQL 18 是默认版本。

下表是归档中保留的 PG13–17 兼容性快照,并未记录最终 PG18 分项统计;PG18 请以 v3.7.0 软件包别名和发布说明为准。

发行版 全部 PGDG PIGSTY CONTRIB 其他 缺失 PG17 PG16 PG15 PG14 PG13
EL 417 119 227 71 0 6 399 407 410 394 368
Debian 410 103 236 71 0 13 397 400 403 391 363

ecosystem

时间 地理 向量 搜索 分析 特性 语言 类型 工具 函数 管理 统计 安全 外部 兼容 数据

MIT ISC PostgreSQL BSD-0 BSD-2 BSD-3 Artistic Apache-2.0 MPL-2.0 GPL-2.0 GPL-3.0 LGPL-2.1 LGPL-3.0 AGPL-3.0 Timescale


使用方法

    使用包别名下载和安装扩展
下载
    从 PGDG / Pigsty 仓库下载扩展
安装
    安装 Postgres 扩展包
配置
    配置扩展并设置预加载
下载
    从 PGDG / Pigsty 仓库下载扩展
安装
    安装 Postgres 扩展包
配置
    配置扩展并设置预加载
创建
    在数据库中创建 Postgres 扩展
更新
    升级 Postgres 扩展
移除
    卸载 Postgres 扩展

索引

类别 扩展
时间 emaj periods pg_background pg_cron pg_later pg_task table_version temporal_tables timescaledb timescaledb_toolkit timeseries
地理 address_standardizer address_standardizer_data_us earthdistance geoip h3 h3_postgis mobilitydb ogr_fdw pg_geohash pg_polyline pgrouting pointcloud pointcloud_postgis postgis postgis_raster postgis_sfcgal postgis_tiger_geocoder postgis_topology q3c tzf
向量 pg4ml pg_similarity pg_summarize pg_tiktoken pgml smlar vchord vector vectorize vectorscale
搜索 fuzzystrmatch hunspell_cs_cz hunspell_de_de hunspell_en_us hunspell_fr hunspell_ne_np hunspell_nl_nl hunspell_nn_no hunspell_pt_pt hunspell_ru_ru hunspell_ru_ru_aot pg_bestmatch pg_bigm pg_search pg_tokenizer pg_trgm pgroonga pgroonga_database vchord_bm25 zhparser
分析 citus citus_columnar columnar duckdb_fdw pg_analytics pg_duckdb pg_fkpart pg_mooncake pg_parquet pg_partman pg_strom plproxy tablefunc
特性 age bloom hll hypopg imgsmlr index_advisor jsquery omni omni_auth omni_aws omni_cloudevents omni_containers omni_credentials omni_email omni_http omni_httpc omni_httpd omni_id omni_json omni_kube omni_ledger omni_manifest omni_mimetypes omni_os omni_polyfill omni_python omni_regex omni_rest omni_schema omni_seq omni_service omni_session omni_sql omni_sqlite omni_test omni_txn omni_types omni_var omni_vfs omni_vfs_types_v1 omni_web omni_worker omni_xml omni_yaml orioledb pg_cardano pg_graphql pg_hint_plan pg_incremental pg_ivm pg_jsonschema pgmq pgq plan_filter rdkit rum
语言 bool_plperl bool_plperlu dbt2 faker hstore_pllua hstore_plluau hstore_plperl hstore_plperlu hstore_plpython3u jsonb_plperl jsonb_plperlu jsonb_plpython3u ltree_plpython3u pg_tle pgtap pldbgapi pljava pllua plluau plperl plperlu plpgsql plpgsql_check plprofiler plprql plpython3u plr plsh pltcl pltclu plv8
类型 acl asn1oid chkpass citext collection country cube currency debversion emailaddr hashtypes hstore ip4r isn l10n_table_dependent_extension ltree md5hash numeral pg_duration pg_rational pg_rrule pg_sphere pg_xenophile pgfaceting pglite_fusion pgmp pgpdf prefix roaringbitmap seg semver timestamp9 uint uint128 unit uri xml2
工具 bzip cryptint data_historization ddl_historization envvar floatfile gzip hashlib http icu_ext pg_curl pg_extra_time pg_html5_email_address pg_net pg_protobuf pg_readme pg_readme_test_extension pg_render pg_smtp_client pgjq pgjwt pgpcre pgqr pgsql_tweaks pguecc schedoc shacrypt sparql url_encode xxhash zstd
函数 aggs_for_arrays aggs_for_vecs arraymath autoinc base36 base62 btree_gin btree_gist convert count_distinct ddsketch dict_int dict_xsyn extra_window_functions financial first_last_agg floatvec insert_username intagg intarray lower_quantile moddatetime omnisketch permuteseq pg_base58 pg_hashids pg_idkit pg_math pg_uuidv7 pgx_ulid quantile random refint sequential_uuids tcn tdigest topn tsm_system_rows tsm_system_time unaccent uuid-ossp vasco xicor
管理 adminpack amcheck basebackup_to_shell basic_archive ddlx fio lo old_snapshot pg_catcheck pg_cheat_funcs pg_checksums pg_cooldown pg_crash pg_dirtyread pg_drop_events pg_orphaned pg_permissions pg_prewarm pg_readonly pg_repack pg_savior pg_squeeze pg_surgery pg_upless pgagent pgautofailover pgcozy pgdd pgfincore pgpool_adm pgpool_recovery pgpool_regclass pre_prepare prioritize safeupdate table_log
统计 auto_explain bgw_replstatus explain_ui meta pageinspect pagevis pg_buffercache pg_freespacemap pg_logicalinspect pg_overexplain pg_proctab pg_profile pg_qualstats pg_relusage pg_show_plans pg_sqlog pg_stat_kcache pg_stat_monitor pg_stat_statements pg_store_plans pg_tracing pg_track_settings pg_visibility pg_wait_sampling pg_walinspect pgmeminfo pgnodemx pgrowlocks pgsentinel pgstattuple powa sslinfo system_stats toastinfo
安全 anon auth_delay credcheck logerrors login_hook noset passwordcheck passwordcheck_cracklib pg_auditor pg_auth_mon pg_jobmon pg_session_jwt pg_snakeoil pg_tde pgaudit pgauditlogtofile pgcrypto pgcryptokey pgextwlist pgsmcrypto pgsodium sepgsql set_user sslutils supabase_vault supautils
外部 aws_s3 db2_fdw dblink file_fdw firebird_fdw hdfs_fdw jdbc_fdw kafka_fdw log_fdw mongo_fdw multicorn mysql_fdw odbc_fdw oracle_fdw pgbouncer_fdw pgspider_ext postgres_fdw redis redis_fdw sqlite_fdw tds_fdw wrappers
兼容 babelfishpg_common babelfishpg_money babelfishpg_tds babelfishpg_tsql documentdb documentdb_core documentdb_distributed orafce pg_dbms_job pg_dbms_lock pg_dbms_metadata pg_statement_rollback pgmemcache pgtt session_variable spat
数据 db_migrator decoder_raw decoderbufs mimeo pg_bulkload pg_fact_loader pg_failover_slots pgactive pgl_ddl_deploy pglogical pglogical_origin pglogical_ticker pgoutput repmgr test_decoding wal2json wal2mongo

11.17.1 - 快速开始

安装、加载、创建、更新 PostgreSQL 扩展

Pigsty 为 14 个主流 Linux 发行版提供了无与伦比的 437 扩展。


概述

交付扩展需要 4 个步骤:下载安装配置创建

步骤 1

    [**下载**](#download-extension):要下载哪些扩展包

    ```yaml tab="config" title="定义要下载的扩展"
    repo_extra_packages: [ postgis, timescaledb, vector ]
    ```
    ```bash tab="apply" title="下载包"
    make repo
    ```

步骤 2

    [**安装**](#install-extension):要安装哪些扩展

    ```yaml tab="config"
    pg_extensions: [ postgis, pgvector, timescaledb ]
    ```
    ```bash tab="apply"
    ./pgsql.yml -t pg_ext     # 安装扩展
    ```

步骤 3

    [**加载**](#load-extension):要预加载哪些扩展

    ```yaml tab="config"
    pg_libs: 'timescaledb, pg_stat_statements, auto_explain'  # 将扩展添加到预加载库(并非所有扩展都需要此操作)
    ```
    ```bash tab="apply" title="编辑现有集群配置并重新加载"
    pg edit-config --force -p shared_preload_libraries='timescaledb, pg_stat_statements, auto_explain'
    ```

步骤 4

    [**创建**](#create-extension):在[数据库](/zh/docs/pgsql/db)中创建扩展

    ```yaml tab="config"
    pg_databases:
    - { name: meta ,extensions: [ postgis, timescaledb, vector ] }
    ```
    ```sql tab="apply" title="在现有数据库中创建扩展"
    CREATE EXTENSION postgis CASCADE;
    ```

快速开始

您可以在配置清单中描述扩展,Pigsty 将为您下载、安装、配置和启用扩展。 此示例使 postgispgvectortimescaledb 开箱即用:

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, vector ]} # 创建(在数据库中)
        pg_extensions: [ postgis, pgvector ]                        # 安装(在集群中)
  vars:
    repo_extra_packages: [ postgis, timescaledb, vector ]           # 下载(全局)

当您初始化此 PG 集群时,这些扩展将在 pg-meta 集群中为您提供。

这里是一个更复杂的示例:启动 Postgres 并带有自托管 supabase 所需的扩展:

all:
  children:
    pg-meta:
      hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
      vars:
        pg_cluster: pg-meta
        pg_databases:
          - name: postgres
            baseline: supabase.sql
            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 } # 生成通用唯一标识符 (UUIDs)
              - { name: pgsodium        }               # PostgreSQL 的现代密码学
              - { name: supabase_vault  }               # Supabase Vault 扩展
              - { name: pg_graphql      }               # GraphQL 支持
              - { name: pg_jsonschema   }               # JSON 模式验证
              - { name: wrappers        }               # 外部数据包装器集合
              - { name: http            }               # 数据库内网页检索
              - { name: pg_cron         }               # PostgreSQL 的作业调度器
              - { name: timescaledb     }               # 时间序列数据支持
              - { name: pg_tle          }               # PostgreSQL 的可信语言扩展
              - { name: vector          }               # 向量相似性搜索
              - { name: pgmq            }               # 轻量级消息队列
        # supabase 加载所需扩展
        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
  vars:
    pg_version: 17
    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 17 的所有可用扩展,并加载和启用了所需的扩展。

11.17.2 - 软件包

扩展包和别名

管理扩展和包并不简单,这里有两个常见的扩展示例:

实体 示例 pgvector 示例 postgis
扩展 vector postgis, postgis_topology, postgis_raster,…
pgvector postgis
操作系统包 pgvector_17 postgresql-16-postgis-3
RPM/DEB pgvector_17_0.8.0-1PGDG.rhel8.x86_64.rpm postgresql-17-postgis-3_3.5.2+dfsg-1.pgdg22.04+1_amd64.deb

要以最小的努力安装正确的 RPM / DEB,我们需要使用抽象层:包别名。 因此您可以通过指定"标准化"名称(如 pgvectorpostgis)来安装这些扩展。 无需了解 PG 和操作系统版本、架构、扩展版本以及任何其他详细信息。

包别名 pkg 用于扩展下载和安装,但在数据库中 CREATE EXTENSION 时您必须使用扩展名称 ext(如 meta 数据库中的 vector)。 请注意,某些扩展需要显式预加载,如上述示例中的 timescaledb

此外,所有扩展都被分类为 16 个主要类别,我们也为整个扩展类别提供别名 这样您就可以批量下载和安装它们,例如:

将 17 替换为 16,15,14,13,...
repo_extra_packages: [ pg17-main ,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]

除了 olap 类别外,所有扩展都可以同时安装,在 olap 类别中,citushydra 冲突,pg_duckdbpg_mooncake 冲突。 所以您可以下载所有扩展,但要一次安装一个。

11.17.3 - 下载

下载 PostgreSQL 扩展

在 Pigsty 中,下载和安装扩展是两个独立的步骤。在 INFRA 模块安装期间,Pigsty 将所有必需的软件下载到本地机器上,并为整个部署创建本地 YUM/APT 仓库。

这种方法加速了安装过程,消除了冗余下载,移除了数据库节点访问互联网的需求,减少了网络流量,提高了交付可靠性,并确保了环境中版本的一致性——这些都是生产部署的最佳实践。

对于开发环境,直接从互联网仓库安装扩展也是可以接受的


快速开始

repo_packagesrepo_extra_packages 中定义的包会在 Pigsty 安装期间自动下载到您的本地仓库。

对于 PostgreSQL 相关的包(内核和扩展),通常将它们放在 repo_extra_packages 中,而让 repo_packages 保持其特定于操作系统的全局默认值。

repo_extra_packages 的默认值是 [pgsql-main],这是一个别名,代表当前活跃主版本的核心 PostgreSQL 和关键扩展。

repo_extra_packages: [ pgsql-main ]  # 当前 pg 主版本 18 的主要包(内核 + 3 个扩展)

要添加特定扩展,只需将 Pigsty 扩展包名称(pkg添加到此参数中。Pigsty 会自动为您的活跃 PG 版本和当前操作系统发行版下载适当的包。

repo_extra_packages: [ pgsql-main, documentdb, citus, postgis, pgvector, pg_cron, rum ]

要下载当前 PG 版本的所有可用扩展,添加所有 16 个扩展类别别名(如 rich 配置模板中所示):

repo_extra_packages: [ pgsql-main ,pgsql-time ,pgsql-gis ,pgsql-rag ,pgsql-fts ,pgsql-olap ,pgsql-feat ,pgsql-lang ,pgsql-type ,pgsql-util ,pgsql-func ,pgsql-admin ,pgsql-stat ,pgsql-sec ,pgsql-fdw ,pgsql-sim ,pgsql-etl]

或者,使用特定版本的别名来下载多个 PostgreSQL 版本的扩展:

repo_extra_packages: [
    pg18-core,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,
    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,
    pg16-core,pg16-time,pg16-gis,pg16-rag,pg16-fts,pg16-olap,pg16-feat,pg16-lang,pg16-type,pg16-util,pg16-func,pg16-admin,pg16-stat,pg16-sec,pg16-fdw,pg16-sim,pg16-etl,
    pg15-core,pg15-time,pg15-gis,pg15-rag,pg15-fts,pg15-olap,pg15-feat,pg15-lang,pg15-type,pg15-util,pg15-func,pg15-admin,pg15-stat,pg15-sec,pg15-fdw,pg15-sim,pg15-etl,
    pg14-core,pg14-time,pg14-gis,pg14-rag,pg14-fts,pg14-olap,pg14-feat,pg14-lang,pg14-type,pg14-util,pg14-func,pg14-admin,pg14-stat,pg14-sec,pg14-fdw,pg14-sim,pg14-etl,
    pg13-core,pg13-time,pg13-gis,pg13-rag,pg13-fts,pg13-olap,pg13-feat,pg13-lang,pg13-type,pg13-util,pg13-func,pg13-admin,pg13-stat,pg13-sec,pg13-fdw,pg13-sim,pg13-etl,
]

要向本地仓库添加新扩展,修改上述参数并运行:

./infra.yml -t repo_build   # 重新下载并重建本地仓库

要在您环境中的所有其他节点上刷新仓库元数据,运行:

./node.yml  -t node_repo    # [可选] apt update / yum makecache

别名映射

PostgreSQL 拥有丰富的开源生态系统,在不同系统和架构中有众多包。

Pigsty 提供了一个抽象层,将 PostgreSQL 包分类为"别名",隐藏了系统、架构和 PG 版本之间的差异。

快速开始部分,我们使用了 pgsql-mainpgsql-core 等别名。这些别名根据您的系统和架构转换为特定的包名称。对于 EL 系统,pgsql-main 扩展为 postgresql$v* 内核包以及 pgvector_$v*pg_repack_$v*wal2json_$v* 扩展包。

pgsql-main:   "postgresql$v* pg_repack_$v* wal2json_$v* pgvector_$v*"

$v 占位符被 pg_version 值(默认:18)替换以指向正确的版本。* 通配符扩展以包括所有包变体(例如 server、libs、contrib、devel)。Pigsty 自动处理这些细节。

可用包和别名的完整列表在 roles/node_id/vars/<os_package>.yml 中。以下是在所有支持的系统中可用的常用别名:

postgresql:   "postgresql$v*"
pgsql-main:   "postgresql$v* pg_repack_$v* wal2json_$v* pgvector_$v*"
pgsql-core:   "postgresql$v postgresql$v-server postgresql$v-libs postgresql$v-contrib postgresql$v-plperl postgresql$v-plpython3 postgresql$v-pltcl postgresql$v-test postgresql$v-devel postgresql$v-llvmjit"
pgsql-simple: "postgresql$v postgresql$v-server postgresql$v-libs postgresql$v-contrib postgresql$v-plperl postgresql$v-plpython3 postgresql$v-pltcl"
pgsql-client: "postgresql$v"
pgsql-server: "postgresql$v-server postgresql$v-libs postgresql$v-contrib"
pgsql-devel:  "postgresql$v-devel"
pgsql-basic:  "pg_repack_$v* wal2json_$v* pgvector_$v*"

pgsql-time:   "timescaledb-tsl_$v* timescaledb-toolkit_$v pg_timeseries_$v periods_$v* temporal_tables_$v* e-maj_$v table_version_$v pg_cron_$v* pg_task_$v* pg_later_$v pg_background_$v*"
pgsql-gis:    "postgis35_$v* pgrouting_$v* pointcloud_$v* h3-pg_$v* q3c_$v* ogr_fdw_$v* geoip_$v pg_polyline_$v pg_geohash_$v*"
pgsql-rag:    "pgvector_$v* vchord_$v pgvectorscale_$v pg_vectorize_$v pg_similarity_$v* smlar_$v* pg_summarize_$v pg_tiktoken_$v pg4ml_$v"
pgsql-fts:    "pg_search_$v pgroonga_$v* pg_bigm_$v* zhparser_$v* pg_bestmatch_$v vchord_bm25_$v hunspell_cs_cz_$v hunspell_de_de_$v hunspell_en_us_$v hunspell_fr_$v hunspell_ne_np_$v hunspell_nl_nl_$v hunspell_nn_no_$v hunspell_ru_ru_$v hunspell_ru_ru_aot_$v"
pgsql-olap:   "citus_$v* pg_analytics_$v pg_duckdb_$v* pg_mooncake_$v* duckdb_fdw_$v* pg_parquet_$v pg_fkpart_$v pg_partman_$v* plproxy_$v*" #hydra_$v* #pg_strom_$v*
pgsql-feat:   "hll_$v* rum_$v pg_graphql_$v pg_jsonschema_$v jsquery_$v* pg_hint_plan_$v* hypopg_$v* index_advisor_$v pg_plan_filter_$v* imgsmlr_$v* pg_ivm_$v* pg_incremental_$v* pgmq_$v pgq_$v* pg_cardano_$v omnigres_$v" #apache-age_$v*
pgsql-lang:   "pg_tle_$v* plv8_$v* pllua_$v* pldebugger_$v* plpgsql_check_$v* plprofiler_$v* plsh_$v* pljava_$v*" #plprql_$v #plr_$v* #pgtap_$v* #postgresql_faker_$v* #dbt2-pgsql-extensions*
pgsql-type:   "prefix_$v* semver_$v* postgresql-unit_$v* pgpdf_$v* pglite_fusion_$v md5hash_$v* asn1oid_$v* pg_roaringbitmap_$v* pgfaceting_$v pgsphere_$v* pg_country_$v* pg_xenophile_$v pg_currency_$v* pgcollection_$v* pgmp_$v* numeral_$v* pg_rational_$v* pguint_$v* pg_uint128_$v* hashtypes_$v* ip4r_$v* pg_duration_$v* pg_uri_$v* pg_emailaddr_$v* acl_$v* timestamp9_$v* chkpass_$v*"
pgsql-util:   "pgsql_gzip_$v* pg_bzip_$v* pg_zstd_$v* pgsql_http_$v* pg_net_$v* pg_curl_$v* pgjq_$v* pgjwt_$v pg_smtp_client_$v pg_html5_email_address_$v url_encode_$v* pgsql_tweaks_$v pg_extra_time_$v pgpcre_$v icu_ext_$v* pgqr_$v* pg_protobuf_$v pg_envvar_$v* floatfile_$v* pg_readme_$v ddl_historization_$v data_historization_$v pg_schedoc_$v pg_hashlib_$v pg_xxhash_$v* postgres_shacrypt_$v* cryptint_$v* pg_ecdsa_$v* pgsparql_$v"
pgsql-func:   "pg_idkit_$v pg_uuidv7_$v* permuteseq_$v* pg_hashids_$v* sequential_uuids_$v topn_$v* quantile_$v* lower_quantile_$v* count_distinct_$v* omnisketch_$v* ddsketch_$v* vasco_$v* pgxicor_$v* tdigest_$v* first_last_agg_$v extra_window_functions_$v* floatvec_$v* aggs_for_vecs_$v* aggs_for_arrays_$v* pg_arraymath_$v* pg_math_$v* pg_random_$v* pg_base36_$v* pg_base62_$v* pg_base58_$v pg_financial_$v*"
pgsql-admin:  "pg_repack_$v* pg_squeeze_$v* pg_dirtyread_$v* pgfincore_$v* pg_cooldown_$v* ddlx_$v pg_prioritize_$v* pg_readonly_$v* pg_upless_$v pg_permissions_$v pg_catcheck_$v* preprepare_$v* pgcozy_$v pg_orphaned_$v* pg_crash_$v* pg_cheat_funcs_$v* pg_fio_$v pg_savior_$v* safeupdate_$v* pg_drop_events_$v table_log_$v" #pg_checksums_$v* #pg_auto_failover_$v* #pgagent_$v* #pgpool-II-pgsql-extensions
pgsql-stat:   "pg_profile_$v* pg_tracing_$v* pg_show_plans_$v* pg_stat_kcache_$v* pg_stat_monitor_$v* pg_qualstats_$v* pg_store_plans_$v* pg_track_settings_$v pg_wait_sampling_$v* system_stats_$v* pg_meta_$v pgnodemx_$v pg_sqlog_$v bgw_replstatus_$v* pgmeminfo_$v* toastinfo_$v* pg_explain_ui_$v pg_relusage_$v pagevis_$v powa_$v*"
pgsql-sec:    "passwordcheck_cracklib_$v* supautils_$v* pgsodium_$v* vault_$v* pg_session_jwt_$v pg_anon_$v pgsmcrypto_$v pgaudit_$v* pgauditlogtofile_$v* pg_auth_mon_$v* credcheck_$v* pgcryptokey_$v pg_jobmon_$v logerrors_$v* login_hook_$v* set_user_$v* pg_snakeoil_$v* pgextwlist_$v* pg_auditor_$v sslutils_$v* noset_$v*" #pg_tde_$v*
pgsql-fdw:    "wrappers_$v multicorn2_$v* odbc_fdw_$v* mysql_fdw_$v* tds_fdw_$v* sqlite_fdw_$v* pgbouncer_fdw_$v redis_fdw_$v* pg_redis_pubsub_$v* hdfs_fdw_$v* firebird_fdw_$v aws_s3_$v log_fdw_$v*" #jdbc_fdw_$v* #oracle_fdw_$v* #db2_fdw_$v* #mongo_fdw_$v* #kafka_fdw_$v
pgsql-sim:    "documentdb_$v* orafce_$v pgtt_$v* session_variable_$v* pg_statement_rollback_$v* pg_dbms_metadata_$v pg_dbms_lock_$v pgmemcache_$v*" #pg_dbms_job_$v #wiltondb
pgsql-etl:    "pglogical_$v* pglogical_ticker_$v* pgl_ddl_deploy_$v* pg_failover_slots_$v* db_migrator_$v wal2json_$v* postgres-decoderbufs_$v* decoder_raw_$v* mimeo_$v pg_fact_loader_$v* pg_bulkload_$v*" #wal2mongo_$v* #repmgr_$v*

使用这些别名时,$v 占位符会被来自 pg_version(默认:18)的 PostgreSQL 主版本号替换。

要为不同的 PostgreSQL 版本下载包,可以:

  • 更改 pg_version 参数,或
  • 通过将 pgsql- 前缀替换为 pg18-pg17-pg16- 等来使用特定版本的别名。

并非所有扩展在所有系统上都可用。某些扩展在别名中被注释掉,因为它们:

  • 在特定系统上不可用
  • 具有大量依赖项(如 pl/R
  • 依赖于商业软件(如 oracle_fdw
  • 在最新的 PG 18 中不可用但在早期版本中可用

如果需要,您仍然可以手动添加这些扩展。

11.17.4 - 安装

安装 PostgreSQL 扩展

Pigsty 依托标准的操作系统包管理器(yum/apt)来安装 PostgreSQL 扩展。


快速开始

在安装扩展时,Pigsty 使用与下载部分相同的别名映射

为集群 pg-meta 安装在 pg_extensions 参数中明确指定的所有扩展:

all:
  children:
    pg-meta:
      hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
      vars:
        pg_cluster: pg-meta
        pg_extensions: # 要在此集群上安装的扩展
          - timescaledb timescaledb_toolkit pg_timeseries periods temporal_tables emaj table_version pg_cron pg_task pg_later pg_background
          - postgis pgrouting pointcloud pg_h3 q3c ogr_fdw geoip pg_polyline pg_geohash #mobilitydb
          - pgvector vchord pgvectorscale pg_vectorize pg_similarity smlar pg_summarize pg_tiktoken pg4ml #pgml
          - pg_search pgroonga pg_bigm zhparser pg_bestmatch vchord_bm25 hunspell
          - citus hydra pg_analytics pg_duckdb pg_mooncake duckdb_fdw pg_parquet pg_fkpart pg_partman plproxy #pg_strom
          - age hll rum pg_graphql pg_jsonschema jsquery pg_hint_plan hypopg index_advisor pg_plan_filter imgsmlr pg_ivm pg_incremental pgmq pgq pg_cardano omnigres #rdkit
          - pg_tle plv8 pllua plprql pldebugger plpgsql_check plprofiler plsh pljava #plr #pgtap #faker #dbt2
          - pg_prefix pg_semver pgunit pgpdf pglite_fusion md5hash asn1oid roaringbitmap pgfaceting pgsphere pg_country pg_xenophile pg_currency pg_collection pgmp numeral pg_rational pguint pg_uint128 hashtypes ip4r pg_uri pgemailaddr pg_acl timestamp9 chkpass #pg_duration #debversion #pg_rrule
          - pg_gzip pg_bzip pg_zstd pg_http pg_net pg_curl pgjq pgjwt pg_smtp_client pg_html5_email_address url_encode pgsql_tweaks pg_extra_time pgpcre icu_ext pgqr pg_protobuf envvar floatfile pg_readme ddl_historization data_historization pg_schedoc pg_hashlib pg_xxhash shacrypt cryptint pg_ecdsa pgsparql
          - pg_idkit pg_uuidv7 permuteseq pg_hashids sequential_uuids topn quantile lower_quantile count_distinct omnisketch ddsketch vasco pgxicor tdigest first_last_agg extra_window_functions floatvec aggs_for_vecs aggs_for_arrays pg_arraymath pg_math pg_random pg_base36 pg_base62 pg_base58 pg_financial
          - pg_repack pg_squeeze pg_dirtyread pgfincore pg_cooldown pg_ddlx pg_prioritize pg_checksums pg_readonly pg_upless pg_permissions pgautofailover pg_catcheck preprepare pgcozy pg_orphaned pg_crash pg_cheat_funcs pg_fio pg_savior safeupdate pg_drop_events table_log #pgagent #pgpool
          - pg_profile pg_tracing pg_show_plans pg_stat_kcache pg_stat_monitor pg_qualstats pg_store_plans pg_track_settings pg_wait_sampling system_stats pg_meta pgnodemx pg_sqlog bgw_replstatus pgmeminfo toastinfo pg_explain_ui pg_relusage pagevis powa
          - passwordcheck supautils pgsodium pg_vault pg_session_jwt pg_anon pg_tde pgsmcrypto pgaudit pgauditlogtofile pg_auth_mon credcheck pgcryptokey pg_jobmon logerrors login_hook set_user pg_snakeoil pgextwlist pg_auditor sslutils pg_noset
          - wrappers multicorn odbc_fdw jdbc_fdw mysql_fdw tds_fdw sqlite_fdw pgbouncer_fdw mongo_fdw redis_fdw pg_redis_pubsub kafka_fdw hdfs_fdw firebird_fdw aws_s3 log_fdw #oracle_fdw #db2_fdw
          - documentdb orafce pgtt session_variable pg_statement_rollback pg_dbms_metadata pg_dbms_lock pgmemcache #pg_dbms_job #wiltondb
          - pglogical pglogical_ticker pgl_ddl_deploy pg_failover_slots db_migrator wal2json wal2mongo decoderbufs decoder_raw mimeo pg_fact_loader pg_bulkload #repmgr

或者通过类别别名全局安装所有扩展:

all:
  vars:
    pg_version: 18   # v3.7 的默认版本,因此 pgsql-main 等同于 pg18-main
    pg_extensions: [ pgsql-main ,pgsql-time ,pgsql-gis ,pgsql-rag ,pgsql-fts ,pgsql-olap ,pgsql-feat ,pgsql-lang ,pgsql-type ,pgsql-util ,pgsql-func ,pgsql-admin ,pgsql-stat ,pgsql-sec ,pgsql-fdw ,pgsql-sim ,pgsql-etl]

您也可以在这些别名中明确指定 PG 主版本:

all:
  vars:

    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]

同时安装所有扩展是可行的(除了在 olap 类别中的两个冲突)但不推荐。只需在 pg_extensions 参数中明确指定您需要的扩展。


配置

在 PGSQL 集群初始化期间,Pigsty 将自动安装在 pg_packagespg_extensions 中指定的包(和别名)。

这两个参数都可以用来安装 PostgreSQL 相关的包。通常,pg_packages 用于全局指定应在环境中所有 PostgreSQL 集群上安装的包:如 PostgreSQL 内核、高可用代理(如 Patroni)、连接池(pgBouncer)、监控(pgExporter)等。

默认情况下,Pigsty 还在这里指定了 3 个重要扩展:pgvectorpg_repackwal2json,分别用于向量搜索、膨胀管理和 CDC 变更提取。

同时,pg_extensions 通常用于为特定集群指定扩展。默认值是一个空列表,表示默认不会安装其他扩展。

pg_packages:                      # 要安装的 pg 包,可以使用别名,状态=present
  - postgresql
  - wal2json pg_repack pgvector
  - patroni pgbouncer pgbackrest pg_exporter pgbadger vip-manager
pg_extensions: []                 # 要安装的 pg 扩展,可以使用别名,状态=latest

一个重要的区别:通过 pg_packages 安装的包只确保存在,而通过 pg_extensions 安装的包会自动升级到最新可用版本。

当使用本地软件仓库时,这个区别并不重要。但是,当使用上游互联网仓库时,请仔细考虑这一点,并将您不希望自动升级的扩展移至 pg_packages


安装

pg_extensions(和 pg_packages)中预定义的扩展将在集群置备期间安装。

要在已置备的 PostgreSQL 集群上安装新扩展:

首先,将扩展添加到 pg_extensions,然后执行 playbook 子任务:

./pgsql.yml -t pg_extension  # 安装在 pg_extensions 中指定的扩展

注意,在 pg_extension 任务中指定的扩展插件默认将升级到您当前环境中的最新可用版本。


仓库

要安装扩展,您需要确保满足以下条件之一:

  • 本地仓库:您已配置使用 Pigsty 的本地仓库,并且扩展已经下载到本地仓库。
  • 在线仓库:您已在目标节点上直接配置了上游互联网仓库,并且这些节点上有互联网访问。

对于生产环境,我们建议使用 Pigsty 的本地软件仓库来统一管理和安装扩展:首先将扩展下载到本地仓库,然后从那里安装它们。 这确保了您环境中扩展版本的一致性,并防止数据库节点直接访问互联网。从本地仓库安装时您无需做任何事情,只需确保它们已下载到本地仓库。

对于开发环境,您可以选择直接使用上游互联网仓库以便于操作。使用以下命令在目标集群上添加互联网仓库并直接安装扩展:

./node.yml  -l <cls> -t node_repo -e node_repo_modules=local,node,pgsql    # 在目标节点上启用互联网仓库
./pgsql.yml -l <cls> -t pg_extension                                        # 使用本地+互联网上游仓库安装扩展

包别名

在安装扩展时,用户可以使用扩展别名来指定扩展。

别名将被转换为当前活跃的 PG 主版本和操作系统环境。

并通过别名转换机制转换为相应的 RPM/DEB 包名称。


注意事项

  • 有两个已知冲突:
  • pgaudit 在 el 系统的 pg 15- 版本中有不同的命名模式:pg16+ = pgaudit,pg15=pgaudit17,pg14=pgaudit16,pg13=pgaudit15,pg12=pgaudit14
  • postgis 在 el 包名中有自己的版本:默认为 postgis35,遗留 el7 为 postgis33

11.17.5 - 配置

预加载扩展并配置扩展参数

虽然大多数用 SQL 编写的 PostgreSQL 扩展可以使用 CREATE EXTENSION 直接启用,但一些使用特殊 postgres 钩子的扩展在使用前需要额外的步骤来预加载它们。


预加载

大多数扩展都有一个或多个对应的动态库(.so.dylib.dll),其中一些在使用前需要预加载。 尝试在没有正确预加载的情况下 CREATE 这些扩展将导致错误。 错误配置的预加载库可能导致数据库重启/启动失败。

一些扩展可以在没有预加载的情况下部分工作,这意味着扩展功能的一部分可以直接使用,其余功能在预加载后可用。

要预加载扩展,将其添加到 shared_preload_libraries 并重启数据库服务器。 扩展目录 提供了需要动态预加载的扩展的完整列表。


配置

要在新 postgres 集群上配置预加载,可以使用 pg_libs 参数。 它将在 postgres 集群引导期间填充到 shared_preload_libraries 参数中。

示例:设置 Supabase 扩展预加载

此示例展示如何使用 pg_libs 参数指定预加载的扩展。

all:
  children:
pg-meta:
  hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
  vars:
    pg_cluster: pg-meta
    pg_libs: 'timescaledb, plpgsql, plpgsql_check, pg_cron, pg_net, pg_stat_statements, auto_explain, pg_tle, plan_filter'

shared_preload_libraries 是一个以逗号分隔的扩展列表。

请注意,这仅在集群创建之前有效。之后, 您必须配置集群来更改现有集群上的 shared_preload_libraries 参数。(使用 patronictlALTER SYSTEM 等…)

将 timescaledb 添加到 shared_preload_libraries
pg edit-config pg-meta --force -p shared_preload_libraries='timescaledb, pg_stat_statements, auto_explain'
pg restart pg-meta    # 重启以应用更改

如果您想手动配置预加载,您可以自己更改 postgresql.conf


默认值

pg_libs 的默认值是 pg_stat_statements, auto_explain, 它默认预加载这两个 Contrib 扩展,这两个扩展提供基本的可观测性:


注意事项

预加载库是逐个加载的,因此 shared_preload_libraries 中扩展的顺序很重要, 以下是一些需要遵循的已知规则:

  • 对于 STAT 扩展,在 pg_stat_statements 之后添加它们以确保使用相同的 query_id。
  • timescaledbcitus 应该放在 shared_preload_libraries开头
  • 如果您同时使用 citustimescaledb,请将 citus 放在 timescaledb 之前。
  • 对于 documentdb,使用 pg_documentdbpg_documentdb_core 作为库名称。
  • pg_search 在 PostgreSQL 17 及更高版本中不需要预加载,但早期版本需要。

参数

一些扩展有可配置的参数,您可以在不同的地方管理它们。

有关详细信息,请查阅每个扩展的官方文档。

11.17.6 - 创建

创建和启用 PostgreSQL 扩展

快速开始

您可以使用 CREATE EXTENSION 语句启用(创建)扩展:

CREATE EXTENSION vector; -- 无需显式加载
CREATE EXTENSION timescaledb; -- 需要显式加载

扩展需要首先安装,一些扩展还需要在使用前进行预加载

一些扩展依赖于其他扩展。 在这种情况下,您可以先安装依赖项 或使用 CASCADE 子句一次安装所有依赖项。

CREATE EXTENSION documentdb CASCADE; -- 创建 documentdb 扩展及其所有依赖项

您也可以使用 Pigsty 配置扩展,它会自动为您创建扩展。


配置

扩展(数据库逻辑对象)在逻辑上是 PostgreSQL 数据库 的一部分。 在 Pigsty 中,您可以使用 pg_databases 参数指定在数据库中创建哪些扩展。

pg_databases:
  - { name: meta ,extensions: [ vector, postgis, timescaledb ] }

但您可以使用 object 格式显式指定扩展详细信息,比如在特定模式中创建它们。 或安装特定版本。这里是一个完整的示例(自托管 supabase):

pg_databases:
  - name: postgres
    baseline: supabase.sql
    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 } # postgres 的 json web token API
      - { name: uuid-ossp ,schema: extensions } # 生成通用唯一标识符 (UUID)
      - { name: pgsodium        }               # pgsodium 是 Postgres 的现代密码学库
      - { name: supabase_vault  }               # Supabase Vault 扩展
      - { name: pg_graphql      }               # pg_graphql:GraphQL 支持
      - { name: pg_jsonschema   }               # pg_jsonschema:验证 json schema
      - { name: wrappers        }               # wrappers:FDW 集合
      - { 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 的轻量级消息队列

定义扩展

extensions 字段是要在数据库中创建的扩展(名称或对象)列表。 它将在 dbsu 的 search_path 中的第一个模式下创建(通常是 public 模式)。

这里,数据库对象中的 extensions 是一个列表,其中每个元素可以是:

  • 表示扩展名称的简单字符串,如 vector
  • 或者,可以使用包含以下字段的字典:
    • name:扩展名称,必需,注意它可能与扩展包名称不同。
    • schema:安装扩展的模式,可选,默认为当前 dbsu search_path 中的第一个模式,通常是默认的 public
    • version:指定扩展版本,可选,默认为最新版本,很少使用。

如果数据库尚不存在,这里定义的扩展将在通过 Pigsty 创建集群创建数据库时自动创建。

重新创建具有非平凡基线模式的数据库可能很危险(如果您在那里放置一些 DROP) 因此,对于现有集群/数据库,建议使用您自己的模式迁移工具来管理扩展。(pgadmin、psql、bytebase、flyway、sqlitch…) 但将它们列在配置清单中用于记录保存目的是有帮助的。(这样如果您想分叉这个集群,它包含这些扩展)


默认扩展

Pigsty 默认创建一些内置扩展和一个特殊的 pg_repack

这些扩展由 pg_default_extensions 定义,默认在 template1 数据库和 postgres 数据库中创建。 新创建的数据库将从 template1 继承这些扩展,因此您无需再次创建它们。

pg_default_extensions:
  - { name: pg_stat_statements ,schema: monitor }
  - { name: pgstattuple        ,schema: monitor }
  - { name: pg_buffercache     ,schema: monitor }
  - { name: pageinspect        ,schema: monitor }
  - { name: pg_prewarm         ,schema: monitor }
  - { name: pg_visibility      ,schema: monitor }
  - { name: pg_freespacemap    ,schema: monitor }
  - { name: postgres_fdw       ,schema: public  }
  - { name: file_fdw           ,schema: public  }
  - { name: btree_gist         ,schema: public  }
  - { name: btree_gin          ,schema: public  }
  - { name: pg_trgm            ,schema: public  }
  - { name: intagg             ,schema: public  }
  - { name: intarray           ,schema: public  }
  - { name: pg_repack } # <-- 默认创建的唯一第三方扩展

pg_default_schemas 定义的一个额外默认模式 monitor 也默认创建。 它用于包含监控相关的扩展、表、函数和视图。

在 Pigsty 中默认可用的有三个第三方扩展:

扩展 作用 位置
pg_repack 在线膨胀控制工具 pg_default_extensions
wal2json JSON 格式的变更数据捕获 无 DDL 扩展,安装意味着可用
vector 向量数据类型和索引 pg_databases 中作为示例

pg_repack 扩展是在线维护膨胀表的重要工具。

vector 是用于 RAG 的非常流行的扩展, 它默认安装(在 pgsql-main 别名中)并在大多数配置模板的占位符 meta 数据库中创建。

wal2json 是用于变更数据捕获(CDC)的另一个重要扩展。它默认安装,但它是一个无 DDL 的扩展, 因此您无需显式 CREATE 它。


无 DDL 扩展

无 DDL 扩展不需要 CREATE EXTENSION 命令即可工作

PostgreSQL 扩展通常由三部分组成:必需的控制文件、可选的 SQL 文件和可选的库。 如果扩展没有 SQL 文件,则不需要 CREATE EXTENSION 命令。

组件 描述 必需
控制文件 关键元数据,名称、依赖项、模式、版本… 必需
SQL 文件 SQL DDL 语句、类型、函数等… 可选
库文件 二进制共享库(.so.dylib.dll 可选

由于 SQL / LIB 文件是可选的,有四种可能的扩展类型组合:

LOAD / DDL 需要 CREATE EXTENSION 不需要 CREATE EXTENSION
需要 LOAD 使用钩子的扩展 无头扩展
不需要 LOAD 不使用钩子的扩展 逻辑解码输出插件

11.17.7 - 更新

如何将 PostgreSQL 扩展更新到新版本

要更新现有扩展,您需要首先使用操作系统的包管理器更新 RPM/DEB 包, 然后在 PostgreSQL 中使用 ALTER EXTENSION ... UPDATE 将扩展更改为新版本。

您可以使用以下命令升级扩展包

pig ext update extname...
yum upgrade extname...
apt upgrade extname...
./pgsql.yml -t pg_ext   # -l cls

pg_extensions 中列出的所有扩展将在 pgsql.yml playbook 执行期间升级。


升级扩展

pg_extensions 中列出的扩展(包别名)将通过 pgsql.ymlpg_ext 子任务升级:

~/pigsty
./pgsql.yml -t pg_ext

此 playbook 将自动安装您当前环境中可用的最新版本的扩展 RPM/DEB 包。 (从构建的本地仓库或直接通过互联网)。 您也可以直接使用 Linux 系统的 yum/apt upgrade 命令升级扩展,但您需要指定完整的包名称:

yum upgrade extname...
apt upgrade extname...

Pigsty 的 pig CLI 也可以帮助您完成此操作,无需指定完整包名称的负担:

pig ext update ext|pkg

更改扩展

执行 ALTER EXTENSION ... UPDATE SQL 命令将扩展更新到新版本:

ALTER EXTENSION name UPDATE [ TO new_version ]

如果省略 TO new_version 子句,扩展将更新到可用的最新版本。

11.17.8 - 移除

如何移除 PostgreSQL 扩展

移除扩展

要卸载扩展,您通常需要运行 DROP EXTENSION SQL 语句:

DROP EXTENSION "<extname>";

如果其他扩展或数据库对象依赖于此扩展,您需要先移除这些依赖项才能卸载扩展。 或者使用 CASCADE 选项一次性移除所有依赖:

DROP EXTENSION "<extname>" CASCADE;
Warning

CASCADE 选项将删除所有依赖于此扩展的对象,
包括数据库对象、函数、视图等。请谨慎使用!

某些扩展没有 DDL,这些扩展不需要 DROP EXTENSION 语句来卸载。 相反,您可以简单地从 shared_preload_libraries(如果已配置)中移除扩展并卸载包。 请参考无 DDL 扩展部分了解更多详细信息。


移除加载

如果您使用的扩展需要动态加载(修改 shared_preload_libraries 参数),您需要首先重新配置 shared_preload_libraries 参数。

shared_preload_libraries 中移除扩展名称,并重启数据库集群以使更改生效。

对于需要动态加载的扩展,请参考需要加载的扩展列表。


卸载包

在从集群中的所有数据库中移除扩展(逻辑对象)后,您可以安全地卸载扩展的软件包。Ansible 命令可以帮助您方便地执行此操作:

ansible <cls> -m package -a "name=<extname> state=absent"

您也可以使用 pig,或直接使用 apt/yum 命令来卸载。

如果您不知道扩展包名称,可以参考扩展列表或查看在 roles/node_id/vars 中定义的扩展包名称映射。

12 - 基础设施

门户和可观测性技术栈
架构
    架构、核心概念、身份管理
配置
    配置基础设施模块,并使用多个基础设施节点。
参数
    使用 57+ 参数自定义基础设施组件
管理
    管理本地仓库、nginx 门户、域名、证书等
剧本
    可在此模块中使用的 Ansible 剧本
监控
    仪表板、指标、记录和告警规则。
常见问题
    关于基础设施模块的常见问题

12.1 - 架构

INFRA 模块中的架构与实体

标准 Pigsty 部署包含 INFRA 模块,默认提供以下服务:

这些组件为生产级 PostgreSQL 服务提供必要的基础设施。

组件 端口 域名 说明
nginx 80 h.pigsty Web 服务入口与 YUM/APT 仓库
alertmanager 9059 a.pigsty 告警聚合与投递
prometheus 9058 p.pigsty 监控时序数据库
grafana 3000 g.pigsty 可视化平台
loki 3100 - 日志收集服务器
pushgateway 9091 - 收集一次性任务指标
blackbox_exporter 9115 - ICMP、TCP、HTTP 探测
dnsmasq 53 - 可选 DNS 服务器
chronyd 123 - 可选 NTP 时间服务器
不使用 INFRA 也能部署高可用 PostgreSQL

如果不需要这些组件,可使用最小化安装,在不安装 INFRA 模块的情况下部署高可用 PostgreSQL。

  • Nginx:本地仓库 Web 服务器及其他 Web UI 的反向代理
  • Grafana:指标、仪表板和数据分析的可视化平台
  • Loki:通过 Grafana 查询的集中日志系统
  • Prometheus:采集、保存指标并计算告警的时序数据库
  • AlertManager:聚合、静默并投递告警
  • PushGateway:接收一次性任务与批处理任务指标
  • BlackboxExporter:探测节点 IP 与 VIP 的可达性
  • DNSMASQ:解析 Pigsty 内部域名
  • Chronyd:保持节点时间同步

INFRA 并非高可用 PostgreSQL 的硬依赖,例如最小化安装 就会省略它。但它提供生产集群通常需要的支撑服务,因此大多数部署都建议保留。

如果已有 Nginx、本地仓库、监控、DNS 或 NTP 基础设施,可以禁用对应组件, 并通过 INFRA 配置 接入既有系统。


Nginx

Nginx 是 Pigsty 所有 Web UI 的入口,默认监听 HTTP 80 与 HTTPS 443。 它代理 Grafana、Prometheus、AlertManager、HAProxy 控制台等 Web UI,同时提供 本地 YUM/APT 仓库等静态资源。

Nginx 根据 infra_portal 生成配置:

infra_portal:
  home         : { domain: h.pigsty }
  grafana      : { domain: g.pigsty ,endpoint: "${admin_ip}:3000" ,websocket: true }
  prometheus   : { domain: p.pigsty ,endpoint: "${admin_ip}:9058" }
  alertmanager : { domain: a.pigsty ,endpoint: "${admin_ip}:9059" }
  blackbox     : { endpoint: "${admin_ip}:9115" }
  loki         : { endpoint: "${admin_ip}:3100" }
  #minio        : { domain: sss.pigsty ,endpoint: "${admin_ip}:9001" ,scheme: https ,websocket: true }

其他服务会引用这些 endpoint:日志发送至 Loki,Grafana 数据源注册到 Grafana, 告警则投递给 AlertManager。Nginx 也可作为本地文件服务器或通用反向代理,并可 使用自签名证书或真实 HTTPS 证书。


本地软件仓库

安装时,Pigsty 可在 INFRA 节点创建本地软件仓库,以加速后续安装。仓库位于 /www/pigsty,由 Nginx 通过 http://h.pigsty/pigsty 提供服务。

离线软件包就是预先构建好的仓库目录压缩包。如果 /www/pigsty 存在并带有 /www/pigsty/repo_complete 标记,Pigsty 会跳过上游 下载,适用于离线环境。

仓库定义文件为 /www/pigsty.repo,可通过以下命令获取:

curl -L http://h.pigsty/pigsty.repo -o /etc/yum.repos.d/pigsty.repo

也可以不经过 Nginx,直接使用文件仓库:

[pigsty-local]
name=Pigsty local $releasever - $basearch
baseurl=file:///www/pigsty/
enabled=1
gpgcheck=0

仓库参数参阅:INFRA - REPO


Prometheus

Prometheus 是 Pigsty v3.7 的监控时序数据库,监听 9058,可通过 IP:9058http://p.pigsty 访问。它负责:

  • 通过带身份标签的本地静态文件发现服务;
  • 拉取、预处理并保存指标;
  • 计算告警规则并将告警发送给 AlertManager。

AlertManager

AlertManager 监听 9059IP:9059http://a.pigsty),负责接收、聚合、 静默和路由 Prometheus 告警。发送邮件等通知需要额外配置。

Prometheus、AlertManager、PushGateway 与 BlackboxExporter 参数参阅: INFRA - PROMETHEUS


Grafana

Grafana 监听 3000IP:3000http://g.pigsty)。Pigsty 的监控以仪表板和 URL 导航为核心,可在全局、集群、实例、数据库和对象之间快速下钻或上卷。

Pigsty 还预装 ECharts 等可视化插件,因此 Grafana 也可用于低代码数据应用。 Loki 在 3100 端口保存日志,节点上的 Promtail 将日志发送到 Loki。

参数参阅:INFRA - GRAFANAINFRA - Loki


Ansible

Ansible 会在引导时安装到 管理节点。INFRA 节点上的 Ansible 通常不会被 使用,但当管理节点不可用时可作为备用控制入口。


DNSMASQ

DNSMASQ 为 Pigsty 内部域名提供解析,其他模块会将域名记录注册到 INFRA 的 DNSMASQ。记录保存在所有 INFRA 节点的 /etc/hosts.d/

参数参阅:INFRA - DNS。Pigsty 内部仍主要使用 /etc/hosts 静态记录,因此 DNSMASQ 只是便利功能。


Chronyd

Chronyd 用于保持所有节点时间同步。参数参阅: NODE - NTP。如果已有 NTP 服务,可以不启用它。

12.2 - 配置

配置基础设施节点、nginx、仓库、dns、ntp、监控系统

INFRA 模块主要提供监控基础设施,对于 PostgreSQL 服务是 可选的

除非您在其他地方手动配置了对 INFRA 节点的 DNS/NTP 服务依赖,否则 INFRA 模块的故障通常不会影响 PostgreSQL 数据库集群的正常运行。

在大多数情况下,单个 INFRA 节点足以满足典型场景。对于有更高要求的生产环境,我们建议使用 2-3 个 INFRA 节点以实现高可用性。

为了提高资源利用率,PostgreSQL 高可用性通常依赖于 ETCD 模块,该模块可以与 INFRA 模块共享节点。

使用超过 3 个 INFRA 节点提供的好处有限,但您可以使用更多 ETCD 节点(例如 5 个)来增强 DCS 服务的可用性和可靠性。


示例

要在节点上安装 INFRA 模块,首先将节点 IP 添加到 清单 中的 infra 组,并为它们分配一个 Infra 实例编号 infra_seq

默认情况下,单个 INFRA 节点配置可以满足大多数要求。所有配置模板都包含默认的 infra 组定义:

all:
  children:
    infra: { hosts: { 10.10.10.10: { infra_seq: 1 } }}

配置 期间,infra 组中的 10.10.10.10 IP 占位符将被替换为 当前节点的主 IP 地址,这意味着 INFRA 模块将安装在当前节点上。

然后使用 infra.yml playbook 在节点上初始化 INFRA 模块。

更多节点

要配置两个 INFRA 节点,请将新 IP 添加到 infra.hosts

all:
  children:
    infra:
      hosts:
        10.10.10.10: { infra_seq: 1 }
        10.10.10.11: { infra_seq: 2 }

要配置三个 INFRA 节点并使用自定义集群/节点参数:

all:
  children:
    infra:
      hosts:
        10.10.10.10: { infra_seq: 1 }
        10.10.10.11: { infra_seq: 2, repo_enabled: false }
        10.10.10.12: { infra_seq: 3, repo_enabled: false }
      vars:
        grafana_clean: false
        prometheus_clean: false
        loki_clean: false

高可用性

Infra 模块中的大多数组件是"无状态/共享状态"的。对于这些组件,高可用性主要需要解决负载均衡问题。

Infra 组件负载均衡可以通过两种方法实现:Keepalived L2 VIP 或 HAProxy 四层负载均衡。

如果您的网络环境支持二层连接,您可以使用 Keepalived L2 VIP 实现高可用性:

infra:
  hosts:
    10.10.10.10: { infra_seq: 1 }
    10.10.10.11: { infra_seq: 2 }
    10.10.10.12: { infra_seq: 3 }
  vars:
    vip_enabled: true
    vip_vrid: 128
    vip_address: 10.10.10.8
    vip_interface: eth1

    infra_portal:
      home         : { domain: h.pigsty }
      grafana      : { domain: g.pigsty ,endpoint: "10.10.10.8:3000" , websocket: true }
      prometheus   : { domain: p.pigsty ,endpoint: "10.10.10.8:9058" }
      alertmanager : { domain: a.pigsty ,endpoint: "10.10.10.8:9059" }
      blackbox     : { endpoint: "10.10.10.8:9115" }
      loki         : { endpoint: "10.10.10.8:3100" }

除了配置像 vip_address 这样的 VIP 相关参数外,您还需要在 infra_portal 中修改 Infra 服务的端点。

12.3 - 参数

使用选项进行自定义

Pigsty 基础设施组件的参数:本地 YUM 仓库、Nginx、DNSMasq、Prometheus、Grafana、Loki、AlertManager、PushGateway、Blackbox Exporter 等。

本模块共有 9 个部分,57 个参数。

  • META:基础设施元数据
  • CA:自签名 CA
  • INFRA_ID:门户和身份
  • REPO:本地 YUM/APT 仓库
  • INFRA_PACKAGE:要安装的包
  • NGINX:Nginx Web 服务器
  • DNS:DNSMasq 域名服务器
  • PROMETHEUS:Prometheus、AlertManager、PushGateway 和 Blackbox Exporter
  • GRAFANA:Grafana,可视化平台
  • LOKI:Loki,日志服务器

参数

名称 部分 类型 级别 注释
version META string G pigsty 版本字符串
admin_ip META ip G 管理员节点 IP 地址
region META enum G 上游镜像区域:default、china、europe
proxy_env META dict G 下载包时的全局代理环境
ca_create CA bool G CA 缺失时创建,默认为 true
ca_cn CA string G CA 通用名称,固定为 pigsty-ca
cert_validity CA interval G 证书有效期,默认 20 年
infra_seq INFRA_ID int I 基础设施节点身份,必需
infra_portal INFRA_ID dict G 通过门户暴露的基础设施服务
repo_enabled REPO bool G/I 在此基础设施节点上创建 yum 仓库?
repo_home REPO path G 仓库主目录,默认 /www
repo_name REPO string G 仓库名称,默认为 pigsty
repo_endpoint REPO url G 通过域名或 IP:端口访问此仓库的接入点
repo_remove REPO bool G/A 移除现有上游仓库
repo_modules REPO string G/A 在 repo_upstream 中安装哪些仓库模块
repo_upstream REPO upstream[] G 从哪里下载上游包
repo_packages REPO string[] G 包含哪些包
repo_extra_packages REPO string[] G/C/I 要包含的额外包
repo_url_packages REPO string[] G 来自 URL 的额外包
infra_packages INFRA_PACKAGE string[] G 要在基础设施节点上安装的包
infra_packages_pip INFRA_PACKAGE string G 为基础设施节点安装的 pip 包
nginx_enabled NGINX bool G/I 在此基础设施节点上启用 nginx?
nginx_exporter_enabled NGINX bool G/I 在此基础设施节点上启用 nginx_exporter?
nginx_sslmode NGINX enum G nginx SSL 模式?disable、enable、enforce
nginx_cert_validity NGINX duration G nginx 自签名证书有效期,默认 397 天
nginx_home NGINX path G nginx 内容目录,默认 /www
nginx_port NGINX port G nginx 监听端口,默认 80
nginx_ssl_port NGINX port G nginx SSL 监听端口,默认 443
nginx_navbar NGINX index[] G nginx 索引页导航链接
certbot_sign NGINX bool G/A 设置期间使用 certbot 签名 nginx 证书?
certbot_email NGINX string G/A certbot 邮箱地址,用于免费 SSL
certbot_options NGINX string G/A certbot 额外选项
dns_enabled DNS bool G/I 在此基础设施节点上设置 dnsmasq?
dns_port DNS port G DNS 服务器监听端口,默认 53
dns_records DNS string[] G 由 dnsmasq 解析的动态 DNS 记录
prometheus_enabled PROMETHEUS bool G/I 在此基础设施节点上启用 prometheus?
prometheus_port PROMETHEUS port G prometheus 监听端口号,默认为 9058
prometheus_clean PROMETHEUS bool G/A 初始化期间清理 prometheus 数据?
prometheus_data PROMETHEUS path G prometheus 数据目录,默认 /data/prometheus
prometheus_sd_dir PROMETHEUS path G prometheus 文件服务发现目录
prometheus_sd_interval PROMETHEUS interval G prometheus 目标刷新间隔,默认 5 秒
prometheus_scrape_interval PROMETHEUS interval G prometheus 抓取和评估间隔,默认 10 秒
prometheus_scrape_timeout PROMETHEUS interval G prometheus 全局抓取超时,默认 8 秒
prometheus_options PROMETHEUS arg G prometheus 额外服务器选项
pushgateway_enabled PROMETHEUS bool G/I 在此基础设施节点上设置 pushgateway?
pushgateway_options PROMETHEUS arg G pushgateway 额外服务器选项
blackbox_enabled PROMETHEUS bool G/I 在此基础设施节点上设置 blackbox_exporter?
blackbox_options PROMETHEUS arg G blackbox_exporter 额外服务器选项
alertmanager_enabled PROMETHEUS bool G/I 在此基础设施节点上设置 alertmanager?
alertmanager_port PROMETHEUS port G alertmanager 监听端口,默认 9059
alertmanager_options PROMETHEUS arg G alertmanager 额外服务器选项
exporter_metrics_path PROMETHEUS path G exporter 指标路径,默认 /metrics
exporter_install PROMETHEUS enum G 如何安装 exporter?none、yum、binary
exporter_repo_url PROMETHEUS url G 如果通过 yum 安装 exporter 的仓库文件 URL
grafana_enabled GRAFANA bool G/I 在此基础设施节点上启用 grafana?
grafana_clean GRAFANA bool G/A 初始化期间清理 grafana 数据?
grafana_admin_username GRAFANA username G grafana 管理员用户名,默认 admin
grafana_admin_password GRAFANA password G grafana 管理员密码,默认 pigsty
loki_enabled LOKI bool G/I 在此基础设施节点上启用 loki?
loki_clean LOKI bool G/A 是否移除现有 loki 数据?
loki_data LOKI path G loki 数据目录,默认 /data/loki
loki_retention LOKI interval G loki 日志保留期,默认 15 天

META

本部分包含当前 Pigsty 部署的元数据,如版本字符串、管理员节点 IP 地址、仓库镜像 region 和下载包时的 HTTP(S) 代理。

version: v3.7.0                   # Pigsty 版本字符串
admin_ip: 10.10.10.10             # 管理员节点 IP 地址
region: default                   # 上游镜像区域:default、china、europe
proxy_env:                        # 下载包时的全局代理环境
  no_proxy: "localhost,127.0.0.1,10.0.0.0/8,192.168.0.0/16,*.pigsty,*.aliyun.com,mirrors.*,*.myqcloud.com,*.tsinghua.edu.cn"
  # http_proxy:  # 在此设置您的代理:例如 http://user:[email protected]
  # https_proxy: # 在此设置您的代理:例如 http://user:[email protected]
  # all_proxy:   # 在此设置您的代理:例如 http://user:[email protected]

version

类型:string,级别:G

pigsty 版本字符串

默认值:v3.7.0

它将用于 pigsty 内省和内容渲染。


admin_ip

类型:ip,级别:G

管理员节点 IP 地址

默认值:10.10.10.10

具有此 IP 地址的节点将被视为管理员节点,通常指向安装 Pigsty 的第一个节点。

默认值 10.10.10.10 是一个占位符,将在 配置 过程中被替换

此参数被许多其他参数引用,例如:

确切的字符串 ${admin_ip} 将被替换为上述参数的实际 admin_ip


region

类型:enum,级别:G

上游镜像区域:default、china、europe

默认值:default

如果设置了除 default 以外的区域,并且在 repo_upstream.[repo].baseurl 中有相应的条目,它将被使用而不是 default

例如,如果使用 china,pigsty 将使用在 repo_upstream 中指定的中国镜像(如果适用)。


proxy_env

类型:dict,级别:G

下载包时的全局代理环境

默认值:

proxy_env: # 下载包时的全局代理环境
  http_proxy: 'http://username:[email protected]'
  https_proxy: 'http://username:[email protected]'
  all_proxy: 'http://username:[email protected]'
  no_proxy: "localhost,127.0.0.1,10.0.0.0/8,192.168.0.0/16,*.pigsty,*.aliyun.com,mirrors.aliyuncs.com,mirrors.tuna.tsinghua.edu.cn,mirrors.zju.edu.cn"

在受限制的生产环境中或当您的互联网访问被阻止时(例如中国大陆),使用 HTTP 代理非常重要。

请注意,如果使用 Docker 模块,代理服务器配置也将写入 Docker 守护程序配置文件。

请注意,如果在 ./configure 期间指定了 -x 参数,当前环境中的代理配置信息将自动填入生成的 pigsty.yaml 文件。


CA

Pigsty 使用自签名 CA;高级安全功能依赖它。

ca_create: true                   # CA 缺失时创建;否则要求用户提供密钥与证书
ca_cn: pigsty-ca                  # CA 通用名称,固定为 pigsty-ca
cert_validity: 7300d              # 证书有效期,默认 20 年

ca_create

类型:bool,级别:G

默认值为 trueca 角色仅在 files/pki/ca/ca.keyfiles/pki/ca/ca.crt 缺失时创建 CA,已有 CA 始终复用。若要使用自行 提供的密钥与证书,可设为 false;此时密钥缺失会立即中止。


ca_cn

类型:string,级别:G

CA 通用名称,不建议修改,默认值为 pigsty-ca

可使用 openssl x509 -text -in /etc/pki/ca.crt 检查。


cert_validity

类型:interval,级别:G

证书有效期,默认值为 7300d(20 年)。


INFRA_ID

基础设施身份和门户定义。

#infra_seq: 1                     # 基础设施节点身份,明确必需
infra_portal:                     # 通过门户暴露的基础设施服务
  home         : { domain: h.pigsty }
  grafana      : { domain: g.pigsty ,endpoint: "${admin_ip}:3000" ,websocket: true }
  prometheus   : { domain: p.pigsty ,endpoint: "${admin_ip}:9058" }
  alertmanager : { domain: a.pigsty ,endpoint: "${admin_ip}:9059" }
  blackbox     : { endpoint: "${admin_ip}:9115" }
  loki         : { endpoint: "${admin_ip}:3100" }

infra_seq

类型:int,级别:I

基础设施节点身份,必需,没有默认值,您必须明确分配它。


infra_portal

类型:dict,级别:G

通过门户暴露的基础设施服务。

默认值将通过相应的域名通过 nginx 暴露首页、grafana、prometheus、alertmanager。

infra_portal:                     # 通过门户暴露的基础设施服务
  home         : { domain: h.pigsty }
  grafana      : { domain: g.pigsty ,endpoint: "${admin_ip}:3000" ,websocket: true }
  prometheus   : { domain: p.pigsty ,endpoint: "${admin_ip}:9058" }
  alertmanager : { domain: a.pigsty ,endpoint: "${admin_ip}:9059" }
  blackbox     : { endpoint: "${admin_ip}:9115" }
  loki         : { endpoint: "${admin_ip}:3100" }

每个记录由键和值字典组成,其中 name 是键,表示组件名称,值是可以配置以下参数的对象:

每个记录由键和值字典组成,其中 name 是键,表示组件名称,值是可以配置以下参数的对象:

每个记录由键和值字典组成,其中 name 是键,表示组件名称,值是可以配置以下参数的对象:

  • name必需,指定 Nginx 服务器的名称
    • 默认记录:home、grafana、prometheus、alertmanager、blackbox、loki 是固定名称,请不要修改它们。
    • 用作 Nginx 配置文件名的一部分,对应配置文件:/etc/nginx/conf.d/<name>.conf
    • 没有域字段的 Nginx 服务器不会生成配置文件,但将用作引用。
  • domain可选,当服务需要通过 Nginx 对外暴露时,它是一个必需字段,指定使用的域名
    • 在 Pigsty 自签名 Nginx HTTPS 证书中,域名将添加到 Nginx SSL 证书的 SAN 字段
    • Pigsty 网页交叉引用将使用此处的默认域名
  • endpoint:通常用作 path 的替代,指定上游服务器地址。设置 endpoint 表示这是一个反向代理服务器
    • 在配置中,${admin_ip} 可以用作占位符,并将在部署期间动态替换为 admin_ip
    • 默认反向代理服务器使用 endpoint.conf 作为配置模板
    • 反向代理服务器还可以配置 websocket 和 schema 参数
  • path:通常用作 endpoint 的替代,指定本地文件服务器路径。设置 path 意味着这是一个本地 Web 服务器
    • 本地 Web 服务器使用 path.conf 作为配置模板
    • 本地 Web 服务器还可以配置 index 参数,是否启用文件索引页
  • certbot:Certbot 证书名称,如果配置,将使用 Certbot 申请证书
    • 如果多个服务器指定相同的 certbot,Pigsty 将合并证书申请,最终证书名称将是此 certbot 的名称
  • cert:证书文件路径,如果配置,将覆盖默认证书路径
  • key:证书密钥文件路径,如果配置,将覆盖默认证书密钥路径
  • websocket:是否启用 WebSocket 支持
    • 只有反向代理服务器可以配置此参数,如果启用它将允许上游使用 WebSocket 连接
  • schema:上游服务器使用的协议,如果配置,将覆盖默认协议
    • 默认是 http,如果配置为 https 将强制 HTTPS 连接到上游服务器
  • index:是否启用文件索引页
    • 只有本地 Web 服务器可以配置此参数,如果启用它将启用 autoindex 配置以自动为目录生成索引页
  • log:Nginx 日志文件路径
    • 如果指定,访问日志将写入此文件,否则将根据服务器类型使用默认日志文件
    • 反向代理服务器使用 /var/log/nginx/<name>.log 作为默认日志文件路径
    • 本地 Web 服务器使用默认访问日志
  • conf:Nginx 配置文件路径
  • config:Nginx 配置代码块
    • 直接注入到 Nginx Server 配置块的配置文本
  • enforce_https:将 HTTP 重定向到 HTTPS
    • 全局配置可以通过 nginx_sslmode: enforce 指定
    • 此配置不影响默认主页服务器,它将始终同时监听端口 80 和 443 以确保兼容性。

REPO

本部分是关于本地软件仓库的。Pigsty 在初始化基础设施节点时将创建一个本地软件仓库(APT/YUM)。

在初始化过程中,Pigsty 将从互联网上游仓库(由 repo_upstream 指定)下载所有包及其依赖项(由 repo_packages 指定)到 {{ nginx_home }} / {{ repo_name }}(默认为 /www/pigsty),所有依赖软件的总大小约为 1GB。

创建本地仓库时,如果目录已经存在并且目录中有名为 repo_complete 的标记文件,Pigsty 将跳过软件下载阶段。

如果某些包的下载速度太慢,您可以通过使用 proxy_env 配置条目设置下载代理或直接下载预打包的 离线包 来完成初始下载,这本质上是在同一操作系统上构建的本地软件源。

repo_enabled: true                # 在此基础设施节点上创建 yum 仓库?
repo_home: /www                   # 仓库主目录,默认 `/www`
repo_name: pigsty                 # 仓库名称,默认为 pigsty
repo_endpoint: http://${admin_ip}:80 # 通过域名或 IP:端口访问此仓库的接入点
repo_remove: true                 # 移除现有上游仓库
repo_modules: infra,node,pgsql    # 在仓库引导期间安装上游仓库
#repo_upstream: []                # 从哪里下载
#repo_packages: []                # 下载哪些包
#repo_extra_packages: []          # 下载额外包
repo_url_packages: []             # 来自 URL 的额外包

repo_enabled

类型:bool,级别:G/I

在此基础设施节点上创建 YUM 仓库?默认值:true

如果您有多个基础设施节点,您可以在其他备用节点上禁用 YUM 仓库以减少互联网流量。


repo_home

类型:path,级别:G

仓库主目录,默认 /www


repo_name

类型:string,级别:G

仓库名称,默认为 pigsty,不建议更改此值


repo_endpoint

类型:url,级别:G

通过域名或 IP:端口访问此仓库的接入点,默认值:http://${admin_ip}:80

如果您更改了 nginx_portnginx_ssl_port,或使用与管理员节点不同的基础设施节点,请相应调整此参数。

${admin_ip} 将在运行时被替换为实际的 admin_ip


repo_remove

类型:bool,级别:G/A

移除现有上游仓库,默认值:true

如果您想保留现有上游仓库,请将此值设置为 false


repo_modules

类型:string,级别:G/A

在 repo_upstream 中安装哪些仓库模块,默认值:infra,node,pgsql

这是一个逗号分隔的值字符串,用于过滤 repo_upstream 中具有相应 module 字段的条目。

对于 Ubuntu/Debian 用户,您可以将 redis 添加到列表中:infra,node,pgsql,redis


repo_upstream

类型:upstream[],级别:G

此参数定义 Pigsty 的上游软件仓库。它没有默认值;您可以明确指定它,或者如果您想使用默认值则留空。

留空时,Pigsty 将根据您的操作系统使用在 roles/node_id/vars 中定义的 repo_upstream_default 的默认值。

对于 EL(8、9、10)系统,默认值为:

- { name: pigsty-local   ,description: 'Pigsty Local'       ,module: local   ,releases: [7,8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'http://${admin_ip}/pigsty'  }} # 内网节点使用
- { name: pigsty-infra   ,description: 'Pigsty INFRA'       ,module: infra   ,releases: [7,8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://repo.pigsty.io/yum/infra/$basearch' ,china: 'https://repo.pigsty.cc/yum/infra/$basearch' }}
- { name: pigsty-pgsql   ,description: 'Pigsty PGSQL'       ,module: pgsql   ,releases: [7,8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://repo.pigsty.io/yum/pgsql/el$releasever.$basearch' ,china: 'https://repo.pigsty.cc/yum/pgsql/el$releasever.$basearch' }}
- { name: nginx          ,description: 'Nginx Repo'         ,module: infra   ,releases: [7,8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://nginx.org/packages/rhel/$releasever/$basearch/' }}
- { name: docker-ce      ,description: 'Docker CE'          ,module: infra   ,releases: [7,8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://download.docker.com/linux/centos/$releasever/$basearch/stable'        ,china: 'https://mirrors.aliyun.com/docker-ce/linux/centos/$releasever/$basearch/stable' ,europe: 'https://mirrors.xtom.de/docker-ce/linux/centos/$releasever/$basearch/stable' }}
- { name: baseos         ,description: 'EL 8+ BaseOS'       ,module: node    ,releases: [  8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://dl.rockylinux.org/pub/rocky/$releasever/BaseOS/$basearch/os/'         ,china: 'https://mirrors.aliyun.com/rockylinux/$releasever/BaseOS/$basearch/os/'         ,europe: 'https://mirrors.xtom.de/rocky/$releasever/BaseOS/$basearch/os/'     }}
- { name: appstream      ,description: 'EL 8+ AppStream'    ,module: node    ,releases: [  8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://dl.rockylinux.org/pub/rocky/$releasever/AppStream/$basearch/os/'      ,china: 'https://mirrors.aliyun.com/rockylinux/$releasever/AppStream/$basearch/os/'      ,europe: 'https://mirrors.xtom.de/rocky/$releasever/AppStream/$basearch/os/'  }}
- { name: extras         ,description: 'EL 8+ Extras'       ,module: node    ,releases: [  8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://dl.rockylinux.org/pub/rocky/$releasever/extras/$basearch/os/'         ,china: 'https://mirrors.aliyun.com/rockylinux/$releasever/extras/$basearch/os/'         ,europe: 'https://mirrors.xtom.de/rocky/$releasever/extras/$basearch/os/'     }}
- { name: powertools     ,description: 'EL 8 PowerTools'    ,module: node    ,releases: [  8  ] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://dl.rockylinux.org/pub/rocky/$releasever/PowerTools/$basearch/os/'     ,china: 'https://mirrors.aliyun.com/rockylinux/$releasever/PowerTools/$basearch/os/'     ,europe: 'https://mirrors.xtom.de/rocky/$releasever/PowerTools/$basearch/os/' }}
- { name: crb            ,description: 'EL 9 CRB'           ,module: node    ,releases: [    9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://dl.rockylinux.org/pub/rocky/$releasever/CRB/$basearch/os/'            ,china: 'https://mirrors.aliyun.com/rockylinux/$releasever/CRB/$basearch/os/'            ,europe: 'https://mirrors.xtom.de/rocky/$releasever/CRB/$basearch/os/'        }}
- { name: epel           ,description: 'EL 8+ EPEL'         ,module: node    ,releases: [  8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'http://download.fedoraproject.org/pub/epel/$releasever/Everything/$basearch/' ,china: 'https://mirrors.tuna.tsinghua.edu.cn/epel/$releasever/Everything/$basearch/'    ,europe: 'https://mirrors.xtom.de/epel/$releasever/Everything/$basearch/'     }}
- { name: pgdg-common    ,description: 'PostgreSQL Common'  ,module: pgsql   ,releases: [7,8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://download.postgresql.org/pub/repos/yum/common/redhat/rhel-$releasever-$basearch' ,china: 'https://mirrors.tuna.tsinghua.edu.cn/postgresql/repos/yum/common/redhat/rhel-$releasever-$basearch' , europe: 'https://mirrors.xtom.de/postgresql/repos/yum/common/redhat/rhel-$releasever-$basearch' }}
- { name: pgdg-el8fix    ,description: 'PostgreSQL EL8FIX'  ,module: pgsql   ,releases: [  8  ] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://download.postgresql.org/pub/repos/yum/common/pgdg-centos8-sysupdates/redhat/rhel-8-x86_64/' ,china: 'https://mirrors.tuna.tsinghua.edu.cn/postgresql/repos/yum/common/pgdg-centos8-sysupdates/redhat/rhel-8-x86_64/' , europe: 'https://mirrors.xtom.de/postgresql/repos/yum/common/pgdg-centos8-sysupdates/redhat/rhel-8-x86_64/' } }
- { name: pgdg-el9fix    ,description: 'PostgreSQL EL9FIX'  ,module: pgsql   ,releases: [    9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://download.postgresql.org/pub/repos/yum/common/pgdg-rocky9-sysupdates/redhat/rhel-9-x86_64/'  ,china: 'https://mirrors.tuna.tsinghua.edu.cn/postgresql/repos/yum/common/pgdg-rocky9-sysupdates/redhat/rhel-9-x86_64/' , europe: 'https://mirrors.xtom.de/postgresql/repos/yum/common/pgdg-rocky9-sysupdates/redhat/rhel-9-x86_64/' }}
- { name: pgdg13         ,description: 'PostgreSQL 13'      ,module: pgsql   ,releases: [7,8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://download.postgresql.org/pub/repos/yum/13/redhat/rhel-$releasever-$basearch' ,china: 'https://mirrors.tuna.tsinghua.edu.cn/postgresql/repos/yum/13/redhat/rhel-$releasever-$basearch' ,europe: 'https://mirrors.xtom.de/postgresql/repos/yum/13/redhat/rhel-$releasever-$basearch' }}
- { name: pgdg14         ,description: 'PostgreSQL 14'      ,module: pgsql   ,releases: [7,8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://download.postgresql.org/pub/repos/yum/14/redhat/rhel-$releasever-$basearch' ,china: 'https://mirrors.tuna.tsinghua.edu.cn/postgresql/repos/yum/14/redhat/rhel-$releasever-$basearch' ,europe: 'https://mirrors.xtom.de/postgresql/repos/yum/14/redhat/rhel-$releasever-$basearch' }}
- { name: pgdg15         ,description: 'PostgreSQL 15'      ,module: pgsql   ,releases: [7,8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://download.postgresql.org/pub/repos/yum/15/redhat/rhel-$releasever-$basearch' ,china: 'https://mirrors.tuna.tsinghua.edu.cn/postgresql/repos/yum/15/redhat/rhel-$releasever-$basearch' ,europe: 'https://mirrors.xtom.de/postgresql/repos/yum/15/redhat/rhel-$releasever-$basearch' }}
- { name: pgdg16         ,description: 'PostgreSQL 16'      ,module: pgsql   ,releases: [  8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://download.postgresql.org/pub/repos/yum/16/redhat/rhel-$releasever-$basearch' ,china: 'https://mirrors.tuna.tsinghua.edu.cn/postgresql/repos/yum/16/redhat/rhel-$releasever-$basearch' ,europe: 'https://mirrors.xtom.de/postgresql/repos/yum/16/redhat/rhel-$releasever-$basearch' }}
- { name: pgdg17         ,description: 'PostgreSQL 17'      ,module: pgsql   ,releases: [  8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://download.postgresql.org/pub/repos/yum/17/redhat/rhel-$releasever-$basearch' ,china: 'https://mirrors.tuna.tsinghua.edu.cn/postgresql/repos/yum/17/redhat/rhel-$releasever-$basearch' ,europe: 'https://mirrors.xtom.de/postgresql/repos/yum/17/redhat/rhel-$releasever-$basearch' }}
- { name: pgdg-extras    ,description: 'PostgreSQL Extra'   ,module: extra   ,releases: [7,8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://download.postgresql.org/pub/repos/yum/common/pgdg-rhel$releasever-extras/redhat/rhel-$releasever-$basearch' ,china: 'https://mirrors.tuna.tsinghua.edu.cn/postgresql/repos/yum/common/pgdg-rhel$releasever-extras/redhat/rhel-$releasever-$basearch' , europe: 'https://mirrors.xtom.de/postgresql/repos/yum/common/pgdg-rhel$releasever-extras/redhat/rhel-$releasever-$basearch' }}
- { name: pgdg13-nonfree ,description: 'PostgreSQL 13+'     ,module: extra   ,releases: [7,8,9] ,arch: [x86_64         ] ,baseurl: { default: 'https://download.postgresql.org/pub/repos/yum/non-free/13/redhat/rhel-$releasever-$basearch' ,china: 'https://mirrors.tuna.tsinghua.edu.cn/postgresql/repos/yum/non-free/13/redhat/rhel-$releasever-$basearch' ,europe: 'https://mirrors.xtom.de/postgresql/repos/yum/non-free/13/redhat/rhel-$releasever-$basearch' }}
- { name: pgdg14-nonfree ,description: 'PostgreSQL 14+'     ,module: extra   ,releases: [7,8,9] ,arch: [x86_64         ] ,baseurl: { default: 'https://download.postgresql.org/pub/repos/yum/non-free/14/redhat/rhel-$releasever-$basearch' ,china: 'https://mirrors.tuna.tsinghua.edu.cn/postgresql/repos/yum/non-free/14/redhat/rhel-$releasever-$basearch' ,europe: 'https://mirrors.xtom.de/postgresql/repos/yum/non-free/14/redhat/rhel-$releasever-$basearch' }}
- { name: pgdg15-nonfree ,description: 'PostgreSQL 15+'     ,module: extra   ,releases: [7,8,9] ,arch: [x86_64         ] ,baseurl: { default: 'https://download.postgresql.org/pub/repos/yum/non-free/15/redhat/rhel-$releasever-$basearch' ,china: 'https://mirrors.tuna.tsinghua.edu.cn/postgresql/repos/yum/non-free/15/redhat/rhel-$releasever-$basearch' ,europe: 'https://mirrors.xtom.de/postgresql/repos/yum/non-free/15/redhat/rhel-$releasever-$basearch' }}
- { name: pgdg16-nonfree ,description: 'PostgreSQL 16+'     ,module: extra   ,releases: [  8,9] ,arch: [x86_64         ] ,baseurl: { default: 'https://download.postgresql.org/pub/repos/yum/non-free/16/redhat/rhel-$releasever-$basearch' ,china: 'https://mirrors.tuna.tsinghua.edu.cn/postgresql/repos/yum/non-free/16/redhat/rhel-$releasever-$basearch' ,europe: 'https://mirrors.xtom.de/postgresql/repos/yum/non-free/16/redhat/rhel-$releasever-$basearch' }}
- { name: pgdg17-nonfree ,description: 'PostgreSQL 17+'     ,module: extra   ,releases: [  8,9] ,arch: [x86_64         ] ,baseurl: { default: 'https://download.postgresql.org/pub/repos/yum/non-free/17/redhat/rhel-$releasever-$basearch' ,china: 'https://mirrors.tuna.tsinghua.edu.cn/postgresql/repos/yum/non-free/17/redhat/rhel-$releasever-$basearch' ,europe: 'https://mirrors.xtom.de/postgresql/repos/yum/non-free/17/redhat/rhel-$releasever-$basearch' }}
- { name: timescaledb    ,description: 'TimescaleDB'        ,module: extra   ,releases: [7,8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://packagecloud.io/timescale/timescaledb/el/$releasever/$basearch'  }}
- { name: wiltondb       ,description: 'WiltonDB'           ,module: mssql   ,releases: [7,8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://repo.pigsty.io/yum/mssql/el$releasever.$basearch', china: 'https://repo.pigsty.cc/yum/mssql/el$releasever.$basearch' , origin: 'https://download.copr.fedorainfracloud.org/results/wiltondb/wiltondb/epel-$releasever-$basearch/' }}
- { name: ivorysql       ,description: 'IvorySQL'           ,module: ivory   ,releases: [7,8,9] ,arch: [x86_64         ] ,baseurl: { default: 'https://repo.pigsty.io/yum/ivory/el$releasever.$basearch', china: 'https://repo.pigsty.cc/yum/ivory/el$releasever.$basearch' }}
- { name: groonga        ,description: 'Groonga'            ,module: groonga ,releases: [  8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://packages.groonga.org/almalinux/$releasever/$basearch/' }}
- { name: mysql          ,description: 'MySQL'              ,module: mysql   ,releases: [7,8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://repo.mysql.com/yum/mysql-8.0-community/el/$releasever/$basearch/', china: 'https://mirrors.tuna.tsinghua.edu.cn/mysql/yum/mysql-8.0-community-el7-$basearch/'}}
- { name: mongo          ,description: 'MongoDB'            ,module: mongo   ,releases: [7,8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/8.0/$basearch/' , 'https://mirrors.aliyun.com/mongodb/yum/redhat/$releasever/mongodb-org/8.0/$basearch/' }}
- { name: redis          ,description: 'Redis'              ,module: redis   ,releases: [7    ] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://rpmfind.net/linux/remi/enterprise/$releasever/remi/$basearch/' }}
- { name: redis          ,description: 'Redis'              ,module: redis   ,releases: [  8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://rpmfind.net/linux/remi/enterprise/$releasever/redis72/$basearch/' }}
- { name: grafana        ,description: 'Grafana'            ,module: grafana ,releases: [7,8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://rpm.grafana.com' }}
- { name: kubernetes     ,description: 'Kubernetes'         ,module: kube    ,releases: [7,8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://pkgs.k8s.io/core:/stable:/v1.31/rpm/', china: 'https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.31/rpm/' }}
- { name: gitlab         ,description: 'Gitlab'             ,module: gitlab  ,releases: [  8,9] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://packages.gitlab.com/gitlab/gitlab-ee/el/$releasever/$basearch' }}

对于 Debian(11,12,13)或 Ubuntu(22.04, 24.04)系统,默认值为:

- { name: pigsty-local   ,description: 'Pigsty Local'       ,module: local   ,releases: [11,12,13,20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'http://${admin_ip}/pigsty ./' }}
- { name: pigsty-pgsql   ,description: 'Pigsty PgSQL'       ,module: pgsql   ,releases: [11,12,13,20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://repo.pigsty.io/apt/pgsql/${distro_codename} ${distro_codename} main', china: 'https://repo.pigsty.cc/apt/pgsql/${distro_codename} ${distro_codename} main' }}
- { name: pigsty-infra   ,description: 'Pigsty Infra'       ,module: infra   ,releases: [11,12,13,20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://repo.pigsty.io/apt/infra/ generic main' ,china: 'https://repo.pigsty.cc/apt/infra/ generic main' }}
- { name: nginx          ,description: 'Nginx'              ,module: infra   ,releases: [11,12,13,20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'http://nginx.org/packages/${distro_name} ${distro_codename} nginx' }}
- { name: docker-ce      ,description: 'Docker'             ,module: infra   ,releases: [11,12,13,20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://download.docker.com/linux/${distro_name} ${distro_codename} stable'                               ,china: 'https://mirrors.aliyun.com/docker-ce/linux/${distro_name} ${distro_codename} stable' }}
- { name: base           ,description: 'Debian Basic'       ,module: node    ,releases: [11,12,13         ] ,arch: [x86_64, aarch64] ,baseurl: { default: 'http://deb.debian.org/debian/ ${distro_codename} main non-free-firmware'                                  ,china: 'https://mirrors.aliyun.com/debian/ ${distro_codename} main restricted universe multiverse' }}
- { name: updates        ,description: 'Debian Updates'     ,module: node    ,releases: [11,12,13         ] ,arch: [x86_64, aarch64] ,baseurl: { default: 'http://deb.debian.org/debian/ ${distro_codename}-updates main non-free-firmware'                          ,china: 'https://mirrors.aliyun.com/debian/ ${distro_codename}-updates main restricted universe multiverse' }}
- { name: security       ,description: 'Debian Security'    ,module: node    ,releases: [11,12,13         ] ,arch: [x86_64, aarch64] ,baseurl: { default: 'http://security.debian.org/debian-security ${distro_codename}-security main non-free-firmware'            ,china: 'https://mirrors.aliyun.com/debian-security/ ${distro_codename}-security main non-free-firmware' }}
- { name: base           ,description: 'Ubuntu Basic'       ,module: node    ,releases: [         20,22,24] ,arch: [x86_64         ] ,baseurl: { default: 'https://mirrors.edge.kernel.org/ubuntu/ ${distro_codename}           main universe multiverse restricted' ,china: 'https://mirrors.aliyun.com/ubuntu/ ${distro_codename}           main restricted universe multiverse' }}
- { name: updates        ,description: 'Ubuntu Updates'     ,module: node    ,releases: [         20,22,24] ,arch: [x86_64         ] ,baseurl: { default: 'https://mirrors.edge.kernel.org/ubuntu/ ${distro_codename}-backports main restricted universe multiverse' ,china: 'https://mirrors.aliyun.com/ubuntu/ ${distro_codename}-updates   main restricted universe multiverse' }}
- { name: backports      ,description: 'Ubuntu Backports'   ,module: node    ,releases: [         20,22,24] ,arch: [x86_64         ] ,baseurl: { default: 'https://mirrors.edge.kernel.org/ubuntu/ ${distro_codename}-security  main restricted universe multiverse' ,china: 'https://mirrors.aliyun.com/ubuntu/ ${distro_codename}-backports main restricted universe multiverse' }}
- { name: security       ,description: 'Ubuntu Security'    ,module: node    ,releases: [         20,22,24] ,arch: [x86_64         ] ,baseurl: { default: 'https://mirrors.edge.kernel.org/ubuntu/ ${distro_codename}-updates   main restricted universe multiverse' ,china: 'https://mirrors.aliyun.com/ubuntu/ ${distro_codename}-security  main restricted universe multiverse' }}
- { name: base           ,description: 'Ubuntu Basic'       ,module: node    ,releases: [         20,22,24] ,arch: [        aarch64] ,baseurl: { default: 'http://ports.ubuntu.com/ubuntu-ports/ ${distro_codename}             main universe multiverse restricted' ,china: 'https://mirrors.aliyun.com/ubuntu-ports/ ${distro_codename}           main restricted universe multiverse' }}
- { name: updates        ,description: 'Ubuntu Updates'     ,module: node    ,releases: [         20,22,24] ,arch: [        aarch64] ,baseurl: { default: 'http://ports.ubuntu.com/ubuntu-ports/ ${distro_codename}-backports   main restricted universe multiverse' ,china: 'https://mirrors.aliyun.com/ubuntu-ports/ ${distro_codename}-updates   main restricted universe multiverse' }}
- { name: backports      ,description: 'Ubuntu Backports'   ,module: node    ,releases: [         20,22,24] ,arch: [        aarch64] ,baseurl: { default: 'http://ports.ubuntu.com/ubuntu-ports/ ${distro_codename}-security    main restricted universe multiverse' ,china: 'https://mirrors.aliyun.com/ubuntu-ports/ ${distro_codename}-backports main restricted universe multiverse' }}
- { name: security       ,description: 'Ubuntu Security'    ,module: node    ,releases: [         20,22,24] ,arch: [        aarch64] ,baseurl: { default: 'http://ports.ubuntu.com/ubuntu-ports/ ${distro_codename}-updates     main restricted universe multiverse' ,china: 'https://mirrors.aliyun.com/ubuntu-ports/ ${distro_codename}-security  main restricted universe multiverse' }}
- { name: pgdg           ,description: 'PGDG'               ,module: pgsql   ,releases: [11,12,13,   22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'http://apt.postgresql.org/pub/repos/apt/ ${distro_codename}-pgdg main' ,china: 'https://repo.pigsty.cc/apt/pgdg/ ${distro_codename}-pgdg main' }}
- { name: pgdg-beta      ,description: 'PGDG Beta'          ,module: beta    ,releases: [11,12,13,   22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'http://apt.postgresql.org/pub/repos/apt/ ${distro_codename}-pgdg-testing main 19' ,china: 'https://mirrors.aliyun.com/postgresql/repos/apt/ ${distro_codename}-pgdg-testing main 19' }}
- { name: timescaledb    ,description: 'TimescaleDB'        ,module: extra   ,releases: [11,12,13,20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://packagecloud.io/timescale/timescaledb/${distro_name}/ ${distro_codename} main' }}
- { name: citus          ,description: 'Citus'              ,module: extra   ,releases: [11,12,   20,22   ] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://packagecloud.io/citusdata/community/${distro_name}/ ${distro_codename} main' } }
- { name: percona        ,description: 'Percona TDE'        ,module: percona ,releases: [11,12,   20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://repo.pigsty.io/apt/percona ${distro_codename} main' ,china: 'https://repo.pigsty.cc/apt/percona ${distro_codename} main' ,origin: 'http://repo.percona.com/ppg-17.6/apt ${distro_codename} main' }}
- { name: wiltondb       ,description: 'WiltonDB'           ,module: mssql   ,releases: [         20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://repo.pigsty.io/apt/mssql/ ${distro_codename} main', china: 'https://repo.pigsty.cc/apt/mssql/ ${distro_codename} main'   ,origin: 'https://ppa.launchpadcontent.net/wiltondb/wiltondb/ubuntu/ ${distro_codename} main'  }}
- { name: groonga        ,description: 'Groonga Debian'     ,module: groonga ,releases: [11,12,13         ] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://packages.groonga.org/debian/ ${distro_codename} main' }}
- { name: groonga        ,description: 'Groonga Ubuntu'     ,module: groonga ,releases: [         20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://ppa.launchpadcontent.net/groonga/ppa/ubuntu/ ${distro_codename} main' }}
- { name: mysql          ,description: 'MySQL'              ,module: mysql   ,releases: [11,12,   20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://repo.mysql.com/apt/${distro_name} ${distro_codename} mysql-8.0 mysql-tools', china: 'https://mirrors.tuna.tsinghua.edu.cn/mysql/apt/${distro_name} ${distro_codename} mysql-8.0 mysql-tools' }}
- { name: mongo          ,description: 'MongoDB'            ,module: mongo   ,releases: [11,12,   20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://repo.mongodb.org/apt/${distro_name} ${distro_codename}/mongodb-org/8.0 multiverse', china: 'https://mirrors.aliyun.com/mongodb/apt/${distro_name} ${distro_codename}/mongodb-org/8.0 multiverse' }}
- { name: redis          ,description: 'Redis'              ,module: redis   ,releases: [11,12,   20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://packages.redis.io/deb ${distro_codename} main' }}
- { name: llvm           ,description: 'LLVM'               ,module: llvm    ,releases: [11,12,13,20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'http://apt.llvm.org/${distro_codename}/ llvm-toolchain-${distro_codename} main' ,china: 'https://mirrors.tuna.tsinghua.edu.cn/llvm-apt/${distro_codename}/ llvm-toolchain-${distro_codename} main' }}
- { name: haproxyd       ,description: 'Haproxy Debian'     ,module: haproxy ,releases: [11,12            ] ,arch: [x86_64, aarch64] ,baseurl: { default: 'http://haproxy.debian.net/ ${distro_codename}-backports-3.1 main' }}
- { name: haproxyu       ,description: 'Haproxy Ubuntu'     ,module: haproxy ,releases: [         20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://ppa.launchpadcontent.net/vbernat/haproxy-3.1/ubuntu/ ${distro_codename} main' }}
- { name: grafana        ,description: 'Grafana'            ,module: grafana ,releases: [11,12,13,20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://apt.grafana.com stable main' ,china: 'https://mirrors.aliyun.com/grafana/apt/ stable main' }}
- { name: kubernetes     ,description: 'Kubernetes'         ,module: kube    ,releases: [11,12,13,20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://pkgs.k8s.io/core:/stable:/v1.33/deb/ /', china: 'https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.33/deb/ /' }}
- { name: gitlab-ee      ,description: 'Gitlab EE'          ,module: gitlab  ,releases: [11,12,13,20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://packages.gitlab.com/gitlab/gitlab-ee/${distro_name}/ ${distro_codename} main' }}
- { name: gitlab-ce      ,description: 'Gitlab CE'          ,module: gitlab  ,releases: [11,12,13,20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://packages.gitlab.com/gitlab/gitlab-ce/${distro_name}/ ${distro_codename} main' }}
- { name: clickhouse     ,description: 'ClickHouse'         ,module: click   ,releases: [11,12,13,20,22,24] ,arch: [x86_64, aarch64] ,baseurl: { default: 'https://packages.clickhouse.com/deb/ stable main', china: 'https://mirrors.aliyun.com/clickhouse/deb/ stable main' }}

repo_packages

类型:string[],级别:G

此参数是一个字符串数组,每个字符串是用空格分隔的软件包列表,指定要包含和下载哪些包。

此参数没有默认值,您可以明确指定它,或者如果您想使用默认值则留空。

留空时,Pigsty 将根据您的操作系统使用在 roles/node_id/vars 中定义的 repo_packages_default 的默认值。

[ node-bootstrap, infra-package, infra-addons, node-package1, node-package2, pgsql-utility, extra-modules ]

repo_packages 中的每个元素将根据上述文件中定义的 package_map 翻译为特定操作系统发行版版本的包名称列表。

例如,在 EL 系统上,它将被翻译为:

node-bootstrap:          "ansible python3 python3-pip python3-virtualenv python3-requests python3-jmespath python3-cryptography dnf-utils modulemd-tools createrepo_c sshpass"
infra-package:           "nginx dnsmasq etcd haproxy vip-manager node_exporter keepalived_exporter pg_exporter pgbackrest_exporter redis_exporter redis minio mcli pig"
infra-addons:            "grafana grafana-plugins loki logcli promtail prometheus alertmanager pushgateway blackbox_exporter nginx_exporter pev2 certbot python3-certbot-nginx"
extra-modules:           "docker-ce docker-compose-plugin ferretdb2 duckdb restic juicefs vray grafana-infinity-ds"
node-package1:           "lz4 unzip bzip2 zlib yum pv jq git ncdu make patch bash lsof wget uuid tuned nvme-cli numactl grubby sysstat iotop htop rsync tcpdump perf flamegraph chkconfig"
node-package2:           "netcat socat ftp lrzsz net-tools ipvsadm bind-utils telnet audit ca-certificates readline vim-minimal keepalived chrony openssl openssh-server openssh-clients"
pgsql-utility:           "patroni patroni-etcd pgbouncer pgbackrest pgbadger pg_activity pg_timetable pgFormatter pg_filedump pgxnclient timescaledb-tools timescaledb-event-streamer pgcopydb"

在 Debian/Ubuntu 系统上,它将被翻译为:

node-bootstrap:          "ansible python3 python3-pip python3-venv python3-jmespath dpkg-dev sshpass ftp linux-tools-generic"
infra-package:           "nginx dnsmasq etcd haproxy vip-manager node-exporter keepalived-exporter pg-exporter pgbackrest-exporter redis-exporter redis minio mcli pig"
infra-addons:            "grafana grafana-plugins loki logcli promtail prometheus alertmanager pushgateway blackbox-exporter nginx-exporter pev2 certbot python3-certbot-nginx"
extra-modules:           "docker-ce docker-compose-plugin ferretdb2 duckdb restic juicefs vray grafana-infinity-ds"
node-package1:           "lz4 unzip bzip2 zlib1g pv jq git ncdu make patch bash lsof wget uuid tuned nvme-cli numactl sysstat iotop htop rsync tcpdump acl chrony"
node-package2:           "netcat-openbsd socat lrzsz net-tools ipvsadm dnsutils telnet ca-certificates libreadline-dev vim-tiny keepalived openssl openssh-server openssh-client"
pgsql-utility:           "patroni pgbouncer pgbackrest pgbadger pg-activity pg-timetable pgformatter postgresql-filedump pgxnclient timescaledb-tools timescaledb-event-streamer pgcopydb pgloader"

按照惯例,repo_packages 通常包括与 PostgreSQL 主版本无关的软件包(如 Infra、Node 和 PGDG Common),而与 PostgreSQL 主版本相关的软件包(内核、扩展)通常在 repo_extra_packages 中指定,以便于在 PG 主版本之间切换。


repo_extra_packages

类型:string[],级别:G/C/I

此参数与 repo_packages 相同,但用于需要下载的额外软件包(通常是 PostgreSQL 版本特定的包)。

默认值是空列表。您可以在集群和实例级别覆盖它以指定需要下载的额外软件包。

如果未明确定义此参数,Pigsty 将从 roles/node_id/vars 中定义的 repo_extra_packages_default 加载默认值,即:

[ pgsql-main ]

repo_packages 中的每个元素将根据上述文件中定义的 package_map 翻译为特定操作系统发行版版本的包名称列表。

例如,在 EL 系统上,它将被翻译为:

postgresql$v postgresql$v-server postgresql$v-libs postgresql$v-contrib postgresql$v-plperl postgresql$v-plpython3 postgresql$v-pltcl postgresql$v-llvmjit pg_repack_$v* wal2json_$v* pgvector_$v*

在 Debian/Ubuntu 系统上,它将被翻译为:

postgresql-$v postgresql-client-$v postgresql-plpython3-$v postgresql-plperl-$v postgresql-pltcl-$v postgresql-$v-repack postgresql-$v-wal2json postgresql-$v-pgvector

这里 $v 将被实际的 PostgreSQL 主版本号 pg_version 替换,所以您可以在这里添加任何 PG 版本相关的包,Pigsty 将为您下载它们。


repo_url_packages

类型:object[] | string[],级别:G

来自 URL 的额外包,默认值:[]

您可以在此参数中使用对象列表或字符串列表,在后一种情况下,Pigsty 将使用 URL 基名作为文件名。

请注意,如果 region 设置为 chinapigsty.io 将自动替换为 pigsty.cc


INFRA_PACKAGE

这些包仅安装在基础设施节点上,包括常见的 rpm/deb/pip 包。


infra_packages

类型:string[],级别:G

此参数是一个字符串数组,每个字符串是用空格分隔的通用软件包列表,指定要在 INFRA 节点上安装哪些包。

此参数没有默认值;您可以明确指定它,或者如果您想使用默认值则留空。

留空时,Pigsty 将根据您的操作系统使用在 roles/node_id/vars 中定义的 repo_packages_default 的默认值。

对于 EL(7/8/9)系统,默认值为:

infra_packages:                   # 要在基础设施节点上安装的包
  - grafana,loki,logcli,promtail,prometheus,alertmanager,pushgateway,grafana-plugins,restic,certbot,python3-certbot-nginx
  - node_exporter,blackbox_exporter,nginx_exporter,pg_exporter,pev2,nginx,dnsmasq,ansible,etcd,python3-requests,redis,mcli

对于 Debian(11,12)或 Ubuntu(22.04, 22.04)系统,默认值为:

infra_packages:                   # 要在基础设施节点上安装的包
  - grafana,grafana-plugins,loki,logcli,promtail,prometheus,alertmanager,pushgateway,restic,certbot,python3-certbot-nginx
  - node-exporter,blackbox-exporter,nginx-exporter,pg-exporter,pev2,nginx,dnsmasq,ansible,etcd,python3-requests,redis,mcli

infra_packages_pip

类型:string,级别:G

为基础设施节点安装的 pip 包,默认值为空字符串


NGINX

Pigsty 通过 Nginx 暴露所有 Web 服务:主页、Grafana、Prometheus、AlertManager 等,以及其他可选工具如 PGWeb、Jupyter Lab、pgAdmin、Bytebase,以及其他静态资源和报告如 pevschemaspypgbadger

此 Nginx 还用作本地 YUM/APT 仓库。

nginx_enabled: true               # 在此基础设施节点上启用 nginx?
nginx_exporter_enabled: true      # 在此基础设施节点上启用 nginx_exporter?
nginx_sslmode: enable             # nginx SSL 模式?disable、enable、enforce
nginx_cert_validity: 397d         # nginx 自签名证书有效期,默认 397 天
nginx_home: /www                  # nginx 内容目录,默认 `/www`
nginx_port: 80                    # nginx 监听端口,默认 80
nginx_ssl_port: 443               # nginx SSL 监听端口,默认 443
nginx_navbar:                     # nginx 索引页导航链接
  - { name: CA Cert ,url: '/ca.crt'   ,desc: 'pigsty self-signed ca.crt'   }
  - { name: Package ,url: '/pigsty'   ,desc: 'local yum repo packages'     }
  - { name: PG Logs ,url: '/logs'     ,desc: 'postgres raw csv logs'       }
  - { name: Reports ,url: '/report'   ,desc: 'pgbadger summary report'     }
  - { name: Explain ,url: '/pigsty/pev.html' ,desc: 'postgres explain visualizer' }
certbot_sign: false               # 设置期间使用 certbot 签名 nginx 证书?
certbot_email: [email protected]     # certbot 邮箱地址,用于免费 SSL
certbot_optionss: ''               # certbot 额外选项

nginx_enabled

类型:bool,级别:G/I

在此基础设施节点上启用 nginx?默认值:true


nginx_exporter_enabled

类型:bool,级别:G/I

在此基础设施节点上启用 nginx_exporter?默认值:true

将此设置为 false 也将禁用 /nginx 健康检查存根:如果您的 Nginx 不支持 /nginx 存根,您可以将此值设置为 false 以禁用它。


nginx_sslmode

类型:enum,级别:G

nginx SSL 模式?可以是:disableenableenforce,默认值:enable

  • disable:监听 nginx_port 并仅提供纯 HTTP
  • enable:也监听 nginx_ssl_port 并提供 HTTPS
  • enforce:所有链接将默认呈现为 https://
    • 也为 nginx infra_portal 中的所有非默认服务器将 80 端口重定向到 443 端口

nginx_cert_validity

类型:duration,级别:G

nginx 自签名证书有效期,默认 397d

不建议使用更长的有效期,因为最新的浏览器要求网站证书最多有效期为 397 天,所以这是默认值。


nginx_home

类型:path,级别:G

nginx Web 服务器静态内容目录,默认 /www

包含静态资源和仓库资源的 Nginx 根目录。明智的做法是将此值设置为与 repo_home 相同,以便自动提供本地仓库内容。


nginx_port

类型:port,级别:G

提供 HTTP 请求的 Nginx 监听端口,默认 80

如果您的默认 80 端口被占用或不可用,您可以考虑使用另一个端口,并相应地更改 repo_endpointrepo_upstreamlocal 条目)。


nginx_ssl_port

类型:port,级别:G

nginx SSL 监听端口,默认 443


nginx_navbar

类型:index[],级别:G

nginx 索引页导航链接

默认值:

nginx_navbar:                     # nginx 索引页导航链接
  - { name: CA Cert ,url: '/ca.crt'   ,desc: 'pigsty self-signed ca.crt'   }
  - { name: Package ,url: '/pigsty'   ,desc: 'local yum repo packages'     }
  - { name: PG Logs ,url: '/logs'     ,desc: 'postgres raw csv logs'       }
  - { name: Reports ,url: '/report'   ,desc: 'pgbadger summary report'     }
  - { name: Explain ,url: '/pigsty/pev.html' ,desc: 'postgres explain visualizer' }

每个记录都呈现为 Pigsty 主页应用下拉菜单的导航链接,这些应用都是可选的,默认挂载在 http://h.pigsty/ 下的 Pigsty 默认服务器上。

url 参数指定应用的 URL PATH,例外情况是如果 URL 中存在 ${grafana} 字符串,它将自动替换为在 infra_portal 中定义的 Grafana 域名。


certbot_sign

类型:bool,级别:G/A

设置期间使用 certbot 签名 nginx 证书?默认值:false

当设置为 true 时,Pigsty 将在执行 infra.ymlinstall.yml playbook(nginx 角色)期间使用 certbot 自动从 Let’s Encrypt 申请免费 SSL 证书。

infra_portal 定义的域中,如果定义了 certbot 参数,Pigsty 将使用 certbot 为 domain 域申请证书,证书名称将是 certbot 参数的值。如果多个服务器/域指定相同的 certbot 参数,Pigsty 将合并并为这些域申请证书,并使用 certbot 参数的值作为证书名称。

启用此选项需要:

  • 当前节点可以通过公共域名访问,并且 DNS 解析已正确指向当前节点的公共 IP
  • 当前节点可以访问 Let’s Encrypt API 接口

此选项默认禁用,您可以在安装后手动执行 make cert 命令来手动执行它,它实际上调用渲染的 /etc/nginx/sign-cert 脚本,使用 certbot 更新或申请证书。


certbot_email

类型:string,级别:G/A

用于接收证书到期提醒邮件的邮箱地址,默认值:[email protected]

certbot_sign 设置为 true 时,建议提供此参数。Let’s Encrypt 将在证书即将到期时向此邮箱发送提醒邮件。


certbot_options

类型:string,级别:G/A

传递给 certbot 的额外配置参数,默认值:空字符串。

您可以通过此参数向 certbot 传递额外的命令行选项,例如 --dry-run,然后 certbot 将不会实际申请证书,而是预览和测试。


DNS

Pigsty 将在基础设施节点上启动默认的 DNSMASQ 服务器来处理 DNS 查询。如 h.pigsty a.pigsty p.pigsty g.pigsty 和可选 MinIO 服务的 sss.pigsty

所有记录将添加到基础设施节点的 /etc/hosts.d/*

您必须在您的 /etc/resolv 中添加 nameserver {{ admin_ip }} 来使用此 DNS 服务器,node_dns_servers 将完成这个技巧。

dns_enabled: true                 # 在此基础设施节点上设置 dnsmasq?
dns_port: 53                      # DNS 服务器监听端口,默认 53
dns_records:                      # 由 dnsmasq 解析的动态 DNS 记录
  - "${admin_ip} h.pigsty a.pigsty p.pigsty g.pigsty"
  - "${admin_ip} api.pigsty adm.pigsty cli.pigsty ddl.pigsty lab.pigsty git.pigsty sss.pigsty wiki.pigsty"

dns_enabled

类型:bool,级别:G/I

在此基础设施节点上设置 dnsmasq?默认值:true

如果您不想使用默认 DNS 服务器,您可以将此值设置为 false 以禁用它。并使用 node_default_etc_hostsnode_etc_hosts 代替。


dns_port

类型:port,级别:G

DNS 服务器监听端口,默认 53


dns_records

类型:string[],级别:G

由 dnsmasq 解析的动态 DNS 记录,一些辅助域名将默认写入基础设施节点上的 /etc/hosts.d/default

dns_records:                      # 由 dnsmasq 解析的动态 DNS 记录
  - "${admin_ip} h.pigsty a.pigsty p.pigsty g.pigsty"
  - "${admin_ip} api.pigsty adm.pigsty cli.pigsty ddl.pigsty lab.pigsty git.pigsty sss.pigsty wiki.pigsty"

PROMETHEUS

Prometheus 用作指标抓取、存储和分析的时间序列数据库。

prometheus_enabled: true          # 在此基础设施节点上启用 prometheus?
prometheus_clean: true            # 初始化期间清理 prometheus 数据?
prometheus_data: /data/prometheus # prometheus 数据目录,默认 `/data/prometheus`
prometheus_sd_dir: /etc/prometheus/targets # prometheus 文件服务发现目录
prometheus_sd_interval: 5s        # prometheus 目标刷新间隔,默认 5 秒
prometheus_scrape_interval: 10s   # prometheus 抓取和评估间隔,默认 10 秒
prometheus_scrape_timeout: 8s     # prometheus 全局抓取超时,默认 8 秒
prometheus_options: '--storage.tsdb.retention.time=15d' # prometheus 额外服务器选项
pushgateway_enabled: true         # 在此基础设施节点上设置 pushgateway?
pushgateway_options: '--persistence.interval=1m' # pushgateway 额外服务器选项
blackbox_enabled: true            # 在此基础设施节点上设置 blackbox_exporter?
blackbox_options: ''              # blackbox_exporter 额外服务器选项
alertmanager_enabled: true        # 在此基础设施节点上设置 alertmanager?
alertmanager_port: 9059           # alertmanager 监听端口,默认 9059
alertmanager_options: ''          # alertmanager 额外服务器选项
exporter_metrics_path: /metrics   # exporter 指标路径,默认 `/metrics`
exporter_install: none            # 如何安装 exporter?none、yum、binary
exporter_repo_url: ''             # 如果通过 yum 安装 exporter 的仓库文件 URL

prometheus_enabled

类型:bool,级别:G/I

在此基础设施节点上启用 prometheus?

默认值:true,如果关闭,这个基础设施上将不会部署 Prometheus。


prometheus_port

类型:port,级别:G

Prometheus 监听的端口号,默认值为 9058

从 3.7 版开始,从此前的默认值 9090 修改为新值,原因是 EL10 在此端口上启动了一个默认 Web 服务。


prometheus_clean

类型:bool,级别:G/A

初始化期间清理 prometheus 数据?默认值:true


prometheus_data

类型:path,级别:G

prometheus 数据目录,默认 /data/prometheus


prometheus_sd_dir

类型:path,级别:G,默认值:/etc/prometheus/targets

prometheus 静态文件服务发现目标目录,prometheus 将从此目录中找到动态监控目标。


prometheus_sd_interval

类型:interval,级别:G,默认值:5s

Prometheus 将默认每 5 秒检查 prometheus_sd_interval 目录以找到新的监控目标。


prometheus_scrape_interval

类型:interval,级别:G

prometheus 抓取和评估间隔,默认 10s


prometheus_scrape_timeout

类型:interval,级别:G

prometheus 全局抓取超时,默认 8s

不要将此设置为大于 prometheus_scrape_interval


prometheus_options

类型:arg,级别:G

prometheus 额外服务器选项

默认值:--storage.tsdb.retention.time=15d

prometheus 服务器的额外 cli 参数,默认值将设置 15 天数据保留以限制磁盘使用。


pushgateway_enabled

类型:bool,级别:G/I

在此基础设施节点上设置 pushgateway?默认值:true


pushgateway_options

类型:arg,级别:G

pushgateway 额外服务器选项,默认值:--persistence.interval=1m


blackbox_enabled

类型:bool,级别:G/I

在此基础设施节点上设置 blackbox_exporter?默认值:true


blackbox_options

类型:arg,级别:G

blackbox_exporter 额外服务器选项,默认值为空字符串


alertmanager_enabled

类型:bool,级别:G/I

在此基础设施节点上设置 alertmanager?默认值:true


alertmanager_port

类型:port,级别:G

AlertManager 的监听端口,默认值为 9059

默认值自 Pigsty v3.7 起修改为 9059,因为 Kafka 的默认端口之一也使用 9093


alertmanager_options

类型:arg,级别:G

alertmanager 额外服务器选项,默认值为空字符串


exporter_metrics_path

类型:path,级别:G

exporter 指标路径,默认 /metrics


exporter_install

类型:enum,级别:G

过时)如何安装 exporter?none、yum、binary

默认值:none

指定如何安装 Exporter:

  • none:不安装,(默认情况下,Exporter 已经由 node_pkg 任务预先安装)
  • yum:使用 yum 安装(如果启用 yum 安装,在部署 Exporter 之前运行 yum 安装 node_exporterpg_exporter
  • binary:使用复制二进制文件安装(直接从本地文件目录复制 node_exporterpg_exporter 二进制文件,不推荐)

使用 yum 安装时,如果指定了 exporter_repo_url(非空),安装将首先将该 URL 下的 REPO 文件安装到 /etc/yum.repos.d。此功能允许您直接安装 Exporter 而无需初始化节点基础设施。不建议常规用户使用 binary 安装。此模式通常用于紧急故障排除和临时问题修复。

<meta>:<pigsty>/files/node_exporter ->  <target>:/usr/bin/node_exporter
<meta>:<pigsty>/files/pg_exporter   ->  <target>:/usr/bin/pg_exporter

exporter_repo_url

类型:url,级别:G

过时)如果通过 yum 安装 exporter 的仓库文件 URL

默认值为空字符串

默认为空;当 exporter_installyum 时,此参数指定的仓库将添加到节点源列表。


GRAFANA

Grafana 是 Pigsty 监控系统的可视化平台。

它也可以用作低代码数据可视化环境

grafana_enabled: true             # 在此基础设施节点上启用 grafana?
grafana_clean: true               # 初始化期间清理 grafana 数据?
grafana_admin_username: admin     # grafana 管理员用户名,默认 `admin`
grafana_admin_password: pigsty    # grafana 管理员密码,默认 `pigsty`
loki_enabled: true                # 在此基础设施节点上启用 loki?
loki_clean: false                 # 是否移除现有 loki 数据?
loki_data: /data/loki             # loki 数据目录,默认 `/data/loki`
loki_retention: 15d               # loki 日志保留期,默认 15 天

grafana_enabled

类型:bool,级别:G/I

在此基础设施节点上启用 grafana?默认值:true


grafana_clean

类型:bool,级别:G/A

初始化期间清理 grafana 数据?默认值:true


grafana_admin_username

类型:username,级别:G

grafana 管理员用户名,默认 admin


grafana_admin_password

类型:password,级别:G

grafana 管理员密码,默认 pigsty

默认值:pigsty

警告:在部署到生产环境之前,请将其更改为强密码


LOKI


loki_enabled

类型:bool,级别:G/I

在此基础设施节点上启用 loki?默认值:true


loki_clean

类型:bool,级别:G/A

是否移除现有 loki 数据?默认值:false


loki_data

类型:path,级别:G

loki 数据目录,默认值:/data/loki


loki_retention

类型:interval,级别:G

loki 日志保留期,默认 15d

12.4 - 管理

管理基础设施组件、本地仓库、nginx 门户和域名

这里是与 INFRA 模块相关的一些管理任务

Nginx 门户
    WebUI 服务的 Nginx 门户
本地仓库
    管理本地 APT / YUM 仓库
域名
    使用本地/公共域名
CA 与证书
    使用自签名或真实的 HTTPS 证书

安装 INFRA

使用 infra.yml playbook 在基础设施节点上安装 INFRA 模块:

./infra.yml     # 在 infra 组上安装 INFRA 模块

移除 INFRA

使用 infra-rm.yml playbook 从基础设施节点卸载 INFRA 模块:

./infra-rm.yml  # 从 infra 组卸载 INFRA 模块

扩展 INFRA

要扩展现有的 INFRA 部署,首先通过添加新节点 IP 并分配唯一的 infra_seq 数字来修改 infra 组:

all:
  children:
    infra:
      hosts:
        10.10.10.10: { infra_seq: 1 } # 现有节点 #1
        10.10.10.11: { infra_seq: 2 } # 新节点 #2(新鲜血液!)

然后使用 infra.yml playbook 在新节点上安装 INFRA:

./infra.yml -l 10.10.10.11    # 在新节点上安装 INFRA

本地仓库

使用这些 playbook 任务在基础设施节点上管理本地软件包仓库(YUM/APT):

./infra.yml -t repo              # 从互联网或离线软件包创建本地仓库

./infra.yml -t repo_dir          # 创建本地仓库目录
./infra.yml -t repo_check        # 检查本地仓库是否存在
./infra.yml -t repo_prepare      # 如果可用,使用现有的本地仓库
./infra.yml -t repo_build        # 如果不存在,从上游构建本地仓库
./infra.yml     -t repo_upstream     # 添加上游仓库/列表文件
./infra.yml     -t repo_remove       # 如果 repo_remove=true,移除现有仓库文件
./infra.yml     -t repo_add          # 向 /etc/yum.repos.d(或 apt)添加上游仓库文件
./infra.yml     -t repo_url_pkg      # 下载在 repo_url_packages 中定义的软件包
./infra.yml     -t repo_cache        # 使用 yum makecache / apt update 创建元数据缓存
./infra.yml     -t repo_boot_pkg     # 安装引导软件包(createrepo_c、yum-utils 等)
./infra.yml     -t repo_pkg          # 从上游下载软件包和依赖项
./infra.yml     -t repo_create       # 使用 createrepo_c / dpkg-dev 创建本地仓库
./infra.yml     -t repo_use          # 向 /etc/yum.repos.d | apt 源添加新仓库
./infra.yml -t repo_nginx        # 如果未运行,启动 nginx 作为文件服务器

常用命令:

./infra.yml     -t repo_upstream     # 添加在 repo_upstream 中定义的上游仓库
./infra.yml     -t repo_pkg          # 下载软件包及其依赖项
./infra.yml     -t repo_create       # 创建/更新本地 YUM/APT 仓库

管理 Nginx

./infra.yml -t nginx                       # 重置 Nginx 组件
./infra.yml -t nginx_index                 # 重新渲染 Nginx 主页
./infra.yml -t nginx_config,nginx_reload   # 重新渲染配置并公开新的上游服务

如果用户在 infra_portalcertbot 字段中指定证书名称,您可以使用 certbot 获取免费的 HTTPS 证书:

# 使用 certbot 为真实域名获取免费的 HTTPS 证书
./infra.yml -t nginx_certbot,nginx_reload -e certbot_sign=true

管理基础设施组件

使用这些 playbook 任务在基础设施节点上管理基础设施组件

./infra.yml -t infra           # 配置基础设施
./infra.yml -t infra_env       # 配置环境变量:env_dir、env_pg、env_pgadmin、env_var
./infra.yml -t infra_pkg       # 安装必需的软件包:infra_pkg_yum、infra_pkg_pip
./infra.yml -t infra_user      # 设置基础设施操作系统用户组
./infra.yml -t infra_cert      # 为基础设施组件颁发证书
./infra.yml -t dns             # 配置 DNSMasq:dns_config、dns_record、dns_launch
./infra.yml -t nginx           # 配置 Nginx:nginx_config、nginx_cert、nginx_static、nginx_launch、nginx_exporter
./infra.yml -t prometheus      # 配置 Prometheus:prometheus_clean、prometheus_dir、prometheus_config、prometheus_launch、prometheus_reload
./infra.yml -t alertmanager    # 配置 AlertManager:alertmanager_config、alertmanager_launch
./infra.yml -t pushgateway     # 配置 PushGateway:pushgateway_config、pushgateway_launch
./infra.yml -t blackbox        # 配置 Blackbox Exporter:blackbox_launch
./infra.yml -t grafana         # 配置 Grafana:grafana_clean、grafana_config、grafana_plugin、grafana_launch、grafana_provision
./infra.yml -t loki            # 配置 Loki:loki_clean、loki_dir、loki_config、loki_launch
./infra.yml -t infra_register  # 向 prometheus 注册基础设施组件

其他有用的任务

./infra.yml -t nginx_index                        # 重新渲染 Nginx 主页
./infra.yml -t nginx_config,nginx_reload          # 重新渲染配置并公开新的上游服务
./infra.yml -t prometheus_conf,prometheus_reload   # 重新生成 Prometheus 配置并重新加载
./infra.yml -t prometheus_rule,prometheus_reload   # 重新复制规则和告警,然后重新加载
./infra.yml -t grafana_plugin                     # 下载 Grafana 插件(可能需要 VPN)

12.5 - 剧本

使用剧本部署与移除可观测性基础设施

有三个与 INFRA 模块相关的 playbook:

  • infra.yml:在基础设施节点上初始化 Pigsty 基础设施
  • infra-rm.yml:从基础设施节点移除基础设施组件
  • install.yml:在当前节点上执行 Pigsty 的完整一次性安装

infra.yml

INFRA 模块 playbook infra.yml 在配置文件的 infra 组中定义的 Infra 节点 上初始化基础设施模块。

此 playbook 执行以下任务:

  • 在 Infra 节点上配置目录和环境变量
  • 下载并创建本地软件仓库以加速后续安装(如果使用离线包或本地仓库已存在则跳过)
  • 将当前 Infra 节点纳入由 Pigsty 管理的 普通节点
  • 部署基础设施组件,包括 Prometheus、Grafana、Loki、Alertmanager、PushGateway、Blackbox Exporter 等

此 playbook 默认在 infra 组上执行:

  • Pigsty 在配置文件中名为 infra 的组上安装 INFRA 模块
  • 配置 期间,Pigsty 将当前安装节点标记为 Infra 节点,并将配置模板中的占位符 IP 地址 10.10.10.10 替换为 当前节点的主 IP 地址
  • 此节点可以发起管理任务并托管基础设施组件,同时像任何常规被管理节点一样工作

Playbook 注意事项:

  • 这是一个幂等的 playbook - 重复执行将覆盖 Infra 节点上的基础设施组件

    • 除非 prometheus_clean 设置为 false,否则 Prometheus 时间序列指标将丢失
    • 除非 loki_clean 设置为 false,否则 Loki 日志数据将丢失
    • 除非 grafana_clean 设置为 false,否则 Grafana 仪表板和配置更改将丢失
  • 当本地软件仓库 /www/pigsty/repo_complete 存在时,此 playbook 跳过从互联网下载软件

    • 完整执行大约需要 1 ~ 3 分钟,取决于机器配置和网络条件
    • 直接从原始上游源下载软件(不使用离线包)可能需要 5-10 分钟,取决于您的网络连接

演示

asciicast

可用任务

以下是 infra.yml playbook 中可用任务的列表:

#--------------------------------------------------------------#
# Tasks
#--------------------------------------------------------------#
# ca            : create self-signed CA in localhost files/pki
#   - ca_dir        : create CA directory
#   - ca_private    : generate CA private key: files/pki/ca/ca.key
#   - ca_cert       : sign CA certificate: files/pki/ca/ca.crt
#
# id            : generate node identity
#
# repo          : bootstrap a local YUM repository from internet or offline packages
#   - repo_dir      : create repository directory
#   - repo_check    : check repository exists
#   - repo_prepare  : use existing repository if exists
#   - repo_build    : build repository from upstream if not exists
#     - repo_upstream    : handle upstream repository files in /etc/yum.repos.d
#       - repo_remove    : remove existing repository file if repo_remove == true
#       - repo_add       : add upstream repository files to /etc/yum.repos.d
#     - repo_url_pkg     : download packages from internet defined by repo_url_packages
#     - repo_cache       : make upstream YUM cache with yum makecache
#     - repo_boot_pkg    : install bootstrap packages such as createrepo_c, yum-utils, etc.
#     - repo_pkg         : download packages & dependencies from upstream repository
#     - repo_create      : create a local YUM repository with createrepo_c & modifyrepo_c
#     - repo_use         : add newly built repository into /etc/yum.repos.d
#   - repo_nginx    : launch nginx for repository if no nginx is serving
#
# node/haproxy/docker/monitor : set up infra node as a common node (check node.yml)
#   - node_name, node_hosts, node_resolv, node_firewall, node_ca, node_repo, node_pkg
#   - node_feature, node_kernel, node_tune, node_sysctl, node_profile, node_ulimit
#   - node_data, node_admin, node_timezone, node_ntp, node_crontab, node_vip
#   - haproxy_install, haproxy_config, haproxy_launch, haproxy_reload
#   - docker_install, docker_admin, docker_config, docker_launch, docker_image
#   - haproxy_register, node_exporter, node_register, promtail
#
# infra         : set up infra components
#   - infra_env      : env_dir, env_pg, env_pgadmin, env_var
#   - infra_pkg      : infra_pkg_yum, infra_pkg_pip
#   - infra_user     : set up infra OS user group
#   - infra_cert     : issue certificate for infra components
#   - dns            : dns_config, dns_record, dns_launch
#   - nginx          : nginx_config, nginx_cert, nginx_static, nginx_launch, nginx_certbot, nginx_reload, nginx_exporter
#   - prometheus     : prometheus_clean, prometheus_dir, prometheus_config, prometheus_launch, prometheus_reload
#   - alertmanager   : alertmanager_config, alertmanager_launch
#   - pushgateway    : pushgateway_config, pushgateway_launch
#   - blackbox       : blackbox_config, blackbox_launch
#   - grafana        : grafana_clean, grafana_config, grafana_launch, grafana_provision
#   - loki           : loki clean, loki_dir, loki_config, loki_launch
#   - infra_register : register infra components to prometheus
#--------------------------------------------------------------#

infra-rm.yml

INFRA 模块 playbook infra-rm.yml 从配置文件的 infra 组中定义的 Infra 节点 移除 Pigsty 基础设施。

常见子任务包括:

./infra-rm.yml               # 移除 INFRA 模块
./infra-rm.yml -t service    # 停止 INFRA 上的基础设施服务
./infra-rm.yml -t data       # 移除 INFRA 上保留的数据
./infra-rm.yml -t package    # 卸载 INFRA 上安装的包

install.yml

INFRA 模块 playbook install.yml所有节点上执行 Pigsty 的完整一次性安装。

此 playbook 在 Playbook:一次性部署 中有更详细的描述。

12.6 - 监控

infra 模块的仪表板和告警规则

仪表板


告警规则

Pigsty 为 INFRA 模块提供以下两个告警规则:

  • InfraDown:基础设施组件宕机
  • AgentDown:监控代理宕机

您可以在 files/prometheus/rules/infra.yml 中修改或添加新的基础设施告警规则。

################################################################
#                Infrastructure Alert Rules                    #
################################################################
- name: infra-alert
  rules:

    #==============================================================#
    #                       Infra Aliveness                        #
    #==============================================================#
    # infra components (prometheus,grafana) down for 1m triggers a P1 alert
    - alert: InfraDown
      expr: infra_up < 1
      for: 1m
      labels: { level: 0, severity: CRIT, category: infra }
      annotations:
        summary: "CRIT InfraDown {{ $labels.type }}@{{ $labels.instance }}"
        description: |
          infra_up[type={{ $labels.type }}, instance={{ $labels.instance }}] = {{ $value  | printf "%.2f" }} < 1

    #==============================================================#
    #                       Agent Aliveness                        #
    #==============================================================#

    # agent aliveness are determined directly by exporter aliveness
    # including: node_exporter, pg_exporter, pgbouncer_exporter, haproxy_exporter

12.7 - FAQ

常见问题解答

INFRA 包含哪些组件

  • Ansible 用于自动化、部署和管理;
  • Nginx 用于公开任何 WebUI 服务并提供 YUM/APT 仓库;
  • 自签名 CA 用于 SSL/TLS 证书;
  • Prometheus 用于监控指标
  • Grafana 用于监控/可视化
  • Loki 用于日志收集
  • AlertManager 用于告警聚合
  • Chronyd 用于管理节点上的 NTP 时间同步。
  • DNSMasq 用于 DNS 注册和解析。
  • ETCD 作为 PostgreSQL HA 的 DCS(专用模块);
  • 元节点上的 PostgreSQL 作为 CMDB(可选);
  • Docker 用于无状态应用程序和工具(可选)。

如何恢复 Prometheus 目标

如果您意外删除了 Prometheus 目标目录,您可以使用以下方式再次向 Prometheus 注册监控目标:

./infra.yml -t register_prometheus  # 在基础设施节点上向 prometheus 注册所有基础设施目标
./node.yml  -t register_prometheus  # 在基础设施节点上向 prometheus 注册所有节点目标
./etcd.yml  -t register_prometheus  # 在基础设施节点上向 prometheus 注册所有 etcd 目标
./minio.yml -t register_prometheus  # 在基础设施节点上向 prometheus 注册所有 minio 目标
./pgsql.yml -t register_prometheus  # 在基础设施节点上向 prometheus 注册所有 pgsql 目标

如何恢复 Grafana 数据源

pg_databases 中的 PGSQL 数据库默认注册为 Grafana 数据源。

如果您意外删除了 Grafana 中注册的 postgres 数据源,您可以使用以下方式再次注册它们:

./pgsql.yml -t register_grafana  # 将所有 pgsql 数据库(在 pg_databases 中)注册为 grafana 数据源

如何恢复 HAProxy 管理页面代理

haproxy 管理页面由默认服务器下的 Nginx 代理。

如果您意外删除了 /etc/nginx/conf.d/haproxy 中注册的 haproxy 代理设置,您可以使用以下方式再次恢复它们:

./node.yml -t register_nginx     # 在基础设施节点上向 nginx 注册所有 haproxy 管理页面代理设置

如何恢复 DNS 注册

PGSQL 集群/实例域名默认注册到基础设施节点上的 /etc/hosts.d/<name>

您可以使用以下命令恢复它们:

./pgsql.yml -t pg_dns   # 在基础设施节点上向 dnsmasq 注册 pg DNS 名称

如何公开新的 Nginx 上游服务

如果您希望通过 Nginx 门户公开新的 WebUI 服务,您可以将服务定义添加到 infra_portal 参数。

并重新运行 ./infra.yml -t nginx_config,nginx_launch 来更新和应用 Nginx 配置。

如果您希望使用 HTTPS 访问,您必须删除 files/pki/csr/pigsty.csrfiles/pki/nginx/pigsty.{key,crt} 以强制重新生成 Nginx SSL/TLS 证书以包含新上游的域名。


如何通过 Nginx 公开 Web 服务?

虽然您可以通过 IP:Port 直接访问服务,但我们仍然建议通过使用域名并通过 Nginx 门户统一访问各种基于 Web 的服务来整合访问点。这种方法有助于集中访问、减少暴露的端口数量,并促进访问控制和审计。

如果您希望通过 Nginx 门户公开新的 WebUI 服务,您可以将服务定义添加到 infra_portal 参数。例如,这是公共演示站点使用的配置,它公开了几个额外的 Web 服务:

infra_portal:
  home         : { domain: home.pigsty.io }
  grafana      : { domain: g.pgsty.com ,endpoint: "${admin_ip}:3000" ,websocket: true }
  prometheus   : { domain: p.pigsty.io ,endpoint: "${admin_ip}:9058" }
  alertmanager : { domain: a.pigsty.io ,endpoint: "${admin_ip}:9059" }
  blackbox     : { endpoint: "${admin_ip}:9115" }
  loki         : { endpoint: "${admin_ip}:3100" }
  # 额外的 Web 门户
  minio        : { domain: sss.pigsty  ,endpoint: "${admin_ip}:9001" ,scheme: https ,websocket: true }
  postgrest    : { domain: api.pigsty.io  ,endpoint: "127.0.0.1:8884"   }
  pgadmin      : { domain: adm.pigsty.io  ,endpoint: "127.0.0.1:8885"   }
  pgweb        : { domain: cli.pigsty.io  ,endpoint: "127.0.0.1:8886"   }
  bytebase     : { domain: ddl.pigsty.io  ,endpoint: "127.0.0.1:8887"   }
  gitea        : { domain: git.pigsty.io  ,endpoint: "127.0.0.1:8889"   }
  wiki         : { domain: wiki.pigsty.io ,endpoint: "127.0.0.1:9002"   }
  noco         : { domain: noco.pigsty.io ,endpoint: "127.0.0.1:9003"   }
  supa         : { domain: supa.pigsty.io ,endpoint: "127.0.0.1:8000", websocket: true }

完成 Nginx 上游服务定义后,使用以下命令向 Nginx 注册新服务。

./infra.yml -t nginx_config           # 重新生成 Nginx 配置
./infra.yml -t nginx_launch           # 更新和应用 nginx 配置

# 您可以使用 ansible 重新加载 nginx
ansible infra -b -a 'nginx -s reload'  # 使用 ansible 重新加载 nginx

如果您希望通过 HTTPS 访问,您必须删除 files/pki/csr/pigsty.csrfiles/pki/nginx/pigsty.{key,crt} 以强制重新生成 Nginx SSL/TLS 证书以包含新的上游域名。如果您更愿意使用权威组织颁发的 SSL 证书而不是 Pigsty 自签名 CA 颁发的证书,您可以将其放在 /etc/nginx/conf.d/cert/ 目录中并修改相应的配置:/etc/nginx/conf.d/<name>.conf


如何手动添加上游仓库文件

Pigsty 有一个内置的包装脚本 bin/repo-add,它将调用 Ansible playbook node.yml 来向相应的节点添加仓库文件。

bin/repo-add <selector> [modules]
bin/repo-add 10.10.10.10           # 为节点 10.10.10.10 添加节点仓库
bin/repo-add infra   node,infra    # 为组 infra 添加节点和基础设施仓库
bin/repo-add infra   node,local    # 添加节点仓库和本地 pigsty 仓库
bin/repo-add pg-test node,pgsql    # 为组 pg-test 添加节点和 pgsql 仓库

13 - 节点

将 Linux 机器主机注册到期望状态

要部署 模块,您必须通过在 Linux 服务器上安装 NODE 模块将它们注册到 pigsty 中。

架构
    架构、核心概念、身份管理
配置
    配置节点身份
参数
    使用 64 个参数自定义节点组件
管理
    设置 VIP,管理监控节点目标
剧本
    可在节点模块中使用的 Ansible 剧本
监控
    仪表板、指标、记录和告警规则。
常见问题
    关于节点模块的常见问题

13.1 - 架构

节点类型、架构与核心概念

“节点”是可通过 SSH 访问、 并提供裸 Linux 环境的资源。它可以是物理机、虚拟机,也可以是带有 systemdsudosshd 的类操作系统容器。

Pigsty 中有三类节点;在单节点部署中,它们是同一台机器。

节点类型 说明
管理节点 安装 Pigsty 并发出管理命令的节点
基础设施节点 安装 INFRA 模块的节点
普通节点 所有由 Pigsty 管理的节点,包括管理与基础设施节点

示例

下面的四节点沙箱包含四个普通节点,其中 10.10.10.10 同时是基础设施节点和管理节点。

all:
  children:
    infra:   { hosts: { 10.10.10.10: { infra_seq: 1 } } }  # <--- 标记为基础设施节点
    etcd:    { hosts: { 10.10.10.10: { etcd_seq: 1 } }, vars: { etcd_cluster: etcd } }
    pg-meta: { hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }, vars: { pg_cluster: pg-meta } }
    pg-test:
      hosts:
        10.10.10.11: { pg_seq: 1, pg_role: primary }
        10.10.10.12: { pg_seq: 2, pg_role: replica }
        10.10.10.13: { pg_seq: 3, pg_role: replica }
      vars: { pg_cluster: pg-test }
  vars:
    admin_ip: 10.10.10.10    # <--- 标记管理节点

普通节点

普通节点默认启用以下组件:

组件 端口 说明 默认状态
node_exporter 9100 节点监控指标导出器 启用
haproxy 9101 HAProxy 管理与指标端口 启用
promtail 9080 日志采集代理 启用

以下组件为可选项,可通过参数启用:

组件 端口 说明 默认状态
docker 9323 容器服务及指标端口 禁用
keepalived - 管理节点集群二层 VIP 禁用
keepalived_exporter 9650 监控 Keepalived 状态 禁用

管理节点

管理节点是最先安装 Pigsty、并发出全部控制命令的节点。 每套 Pigsty 部署只有一个管理节点,由 admin_ip 指定;配置时会将其设置为管理节点的主 IP。

保护管理节点访问

管理节点需要通过免密 sshsudo 管理其他节点。未经授权的访问风险 很高,请妥善保护管理节点。

管理节点是最先安装 Pigsty 的节点

管理节点用于向其他节点发出命令,通常与第一个 INFRA 节点重合。

本地笔记本也可作为管理节点

可以在本地笔记本或 Mac 上准备 Pigsty 与 Ansible,并从本机发出管理命令。


基础设施节点

一套部署可以有一个或多个 INFRA 节点;生产环境建议至少两个。配置清单中的 infra 分组指定这些节点,并在其上安装 INFRA 模块。

组件 端口 域名 说明
nginx 80 h.pigsty Web 服务入口与 YUM/APT 仓库
alertmanager 9059 a.pigsty 告警聚合与投递
prometheus 9058 p.pigsty 监控时序数据库
grafana 3000 g.pigsty 可视化平台
loki 3100 - 日志收集服务器
pushgateway 9091 - 一次性任务指标入口
blackbox_exporter 9115 - 黑盒探测
dnsmasq 53 - DNS 服务
chronyd 123 - NTP 服务
ansible - - 执行 Playbook

PGSQL 节点

安装 PGSQL 模块的节点称为 PGSQL 节点。节点与 PostgreSQL 实例按 1:1 部署;node_id_from_pg 可让 节点复用 PostgreSQL 实例身份。

组件 端口 说明 状态
postgres 5432 由 Patroni 管理的 PostgreSQL 服务 启用
pgbouncer 6432 连接池 启用
patroni 8008 PostgreSQL 高可用组件 启用
primary @ haproxy 5433 主库连接池,读写服务 启用
replica @ haproxy 5434 从库连接池,只读服务 启用
default @ haproxy 5436 主库直连服务 启用
offline @ haproxy 5438 离线实例直连服务 启用
pg_exporter 9630 PostgreSQL 指标导出器 启用
pgbouncer_exporter 9631 PgBouncer 指标导出器 启用
pgbackrest_exporter 9854 pgBackRest 指标导出器 启用
vip-manager - 将 VIP 绑定到主库 禁用

13.2 - 配置

节点身份、DNS、VIP、数据目录和 haproxy 服务

您不需要显式定义节点集群和节点实例。 它通常由其他数据库 模块 的集群定义暗示。 如果您定义了一个 PGSQL 集群,它会隐式定义一个节点集群。

但在某些情况下,您可能希望使用显式命名的节点集群/实例。 例如运行专用用途的节点组(例如,haproxy 组、节点缓冲池等)


身份参数

Pigsty 使用节点的主要 IPv4 地址(inventory_hostname)作为其身份。

名称 类型 级别 必要性 注释
inventory_hostname ip - 必需 节点 IP
nodename string I 可选 节点名称
node_cluster string C 可选 节点集群名称

nodenamenode_cluster 可以用作监控目的的可选次要身份。

节点集群示例
node-test:
  hosts:
    10.10.10.11: { nodename: node-test-1 }
    10.10.10.12: { nodename: node-test-2 }
    10.10.10.13: { nodename: node-test-3 }
  vars:
    node_cluster: node-test

当您只想监控这些节点而不是在其上运行数据库时,这会很有用。


借用身份

因为 Pigsty 在 NODE 和 PG 实例之间使用 1:1 映射(每个节点只有一个 PG 实例), 节点的身份可以从相应的 PG 实例借用:

名称 标签 级别 借用身份 注释
nodename ins I {{ pg_cluster }}-{{ pg_seq }} PG 实例名称
node_cluster cls C {{ pg_cluster }} PG 集群名称

这是默认行为,在监控系统中让 PG 和 NODE 具有相同的 cls / ins 身份标签很方便。 这可以通过将 node_id_from_pg 参数覆盖为 false 来禁用。

如果没有定义相应的 PG 实例,也没有明确定义 nodenamenode_cluster, 节点将被标记为 clsnodesins 为当前主机名。


SSH 连接

inventory_hostnameAnsible 用于通过 SSH 连接到节点。

如果您的节点无法通过 ssh <inventory_hostname> 简单访问,可以使用 ssh 别名 和更多 ansible 连接参数(甚至不同的 IP)。 但 inventory_hostname 仍然是节点的核心身份。

ssh 参数示例
node-test:
  hosts:
    10.10.10.11: { nodename: node-test-1 , ansible_host: node-1 }
    10.10.10.12: { nodename: node-test-2 , ansible_host: 192.168.0.1 , ansible_port: 2222 , ansible_user: root }
  vars:
    node_cluster: node-test

13.3 - 参数

65 个参数用于定制节点

NODE 模块有 10 个部分,65 个参数。


参数

名称 部分 类型 级别 注释
nodename NODE_ID string I 节点实例身份,如果缺失则使用主机名,可选
node_cluster NODE_ID string C 节点集群身份,如果缺失则使用 ’nodes’,可选
nodename_overwrite NODE_ID bool C 使用 nodename 覆盖节点的主机名?
nodename_exchange NODE_ID bool C 在 play 主机间交换节点名?
node_id_from_pg NODE_ID bool C 如果适用,使用 postgres 身份作为节点身份?
node_write_etc_hosts NODE_DNS bool G/C/I 修改目标节点上的 /etc/hosts
node_default_etc_hosts NODE_DNS string[] G /etc/hosts 中的静态 DNS 记录
node_etc_hosts NODE_DNS string[] C /etc/hosts 中的额外静态 DNS 记录
node_dns_method NODE_DNS enum C 如何处理 DNS 服务器:add、none、overwrite
node_dns_servers NODE_DNS string[] C /etc/resolv.conf 中的动态名称服务器
node_dns_options NODE_DNS string[] C /etc/resolv.conf 中的 DNS 解析选项
node_repo_modules NODE_PACKAGE string C 节点上要添加的上游仓库,默认为本地
node_repo_remove NODE_PACKAGE bool C 移除节点上现有的仓库?
node_packages NODE_PACKAGE string[] C 当前节点要安装的包
node_default_packages NODE_PACKAGE string[] G 所有节点上要安装的默认包
node_disable_firewall NODE_TUNE bool C 禁用节点防火墙?默认为 true
node_disable_selinux NODE_TUNE bool C 禁用节点 selinux?默认为 true
node_disable_numa NODE_TUNE bool C 禁用节点 numa,需要重启
node_disable_swap NODE_TUNE bool C 禁用节点交换分区,谨慎使用
node_static_network NODE_TUNE bool C 重启后保留 DNS 解析器设置
node_disk_prefetch NODE_TUNE bool C 在 HDD 上设置磁盘预取以提高性能
node_kernel_modules NODE_TUNE string[] C 此节点上要启用的内核模块
node_hugepage_count NODE_TUNE int C 2MB 大页数量,优先于比率
node_hugepage_ratio NODE_TUNE float C 节点内存大页比率,默认 0 禁用
node_overcommit_ratio NODE_TUNE float C 节点内存过量使用比率,默认 0 禁用
node_tune NODE_TUNE enum C 节点调优配置文件:none、oltp、olap、crit、tiny
node_sysctl_params NODE_TUNE dict C 除调优外的 k:v 格式 sysctl 参数
node_data NODE_ADMIN path C 节点主数据目录,默认为 /data
node_admin_enabled NODE_ADMIN bool C 在目标节点上创建管理员用户?
node_admin_uid NODE_ADMIN int C 节点管理员用户的 uid 和 gid
node_admin_username NODE_ADMIN username C 节点管理员用户名,默认为 dba
node_admin_ssh_exchange NODE_ADMIN bool C 在节点集群间交换管理员 SSH 密钥
node_admin_pk_current NODE_ADMIN bool C 将当前用户的 SSH 公钥添加到管理员 authorized_keys
node_admin_pk_list NODE_ADMIN string[] C 要添加到管理员用户的 SSH 公钥
node_aliases NODE_ADMIN dict C 要添加的额外 shell 别名,k:v 字典
node_timezone NODE_TIME string C 设置节点时区,空字符串跳过
node_ntp_enabled NODE_TIME bool C 启用 chronyd 时间同步服务?
node_ntp_servers NODE_TIME string[] C /etc/chrony.conf 中的 NTP 服务器
node_crontab_overwrite NODE_TIME bool C 覆盖还是追加到 /etc/crontab
node_crontab NODE_TIME string[] C /etc/crontab 中的 crontab 条目
vip_enabled NODE_VIP bool C 在此节点集群上启用 VIP?
vip_address NODE_VIP ip C IPv4 格式的节点 VIP 地址,如果启用 VIP 则必需
vip_vrid NODE_VIP int C 必需,整数,1-254,在同一 VLAN 中应唯一
vip_role NODE_VIP enum I 可选,master/backup,默认为 backup,用作初始角色
vip_preempt NODE_VIP bool C/I 可选,true/false,默认为 false,启用 VIP 抢占
vip_interface NODE_VIP string C/I 节点 VIP 监听的网络接口,默认为 eth0
vip_dns_suffix NODE_VIP string C 节点 VIP DNS 名称后缀,默认为空字符串
vip_exporter_port NODE_VIP port C keepalived 导出器监听端口,默认为 9650
haproxy_enabled HAPROXY bool C 在此节点上启用 haproxy?
haproxy_clean HAPROXY bool G/C/A 清理所有现有的 haproxy 配置?
haproxy_reload HAPROXY bool A 配置后重新加载 haproxy?
haproxy_auth_enabled HAPROXY bool G 为 haproxy 管理页面启用身份验证
haproxy_admin_username HAPROXY username G haproxy 管理员用户名,默认为 admin
haproxy_admin_password HAPROXY password G haproxy 管理员密码,默认为 pigsty
haproxy_exporter_port HAPROXY port C haproxy 管理/导出器端口,默认为 9101
haproxy_client_timeout HAPROXY interval C 客户端连接超时,默认为 24h
haproxy_server_timeout HAPROXY interval C 服务器端连接超时,默认为 24h
haproxy_services HAPROXY service[] C 要在节点上公开的 haproxy 服务列表
node_exporter_enabled NODE_EXPORTER bool C 在此节点上设置 node_exporter?
node_exporter_port NODE_EXPORTER port C node exporter 监听端口,默认为 9100
node_exporter_options NODE_EXPORTER arg C node_exporter 的额外服务器选项
promtail_enabled PROMTAIL bool C 启用 promtail 日志收集器?
promtail_clean PROMTAIL bool G/A 初始化期间清除现有的 promtail 状态文件?
promtail_port PROMTAIL port C promtail 监听端口,默认为 9080
promtail_positions PROMTAIL path C promtail 位置状态文件路径

NODE

Node 模块将目标节点调优到所需状态,并将它们集成到 Pigsty 监控系统中。


NODE_ID

每个节点都有身份参数,这些参数通过 <cluster>.hosts<cluster>.vars 中的参数配置。详情请查看 NODE Identity


nodename

名称:nodename,类型:string,级别:I

节点实例身份,如果缺失则使用主机名,可选

无默认值,Null 或空字符串表示 nodename 将设置为节点的当前主机名。

如果 node_id_from_pgtrue(默认)且 nodename 未明确定义,nodename 将首先尝试使用 ${pg_cluster}-${pg_seq},如果此节点上未定义 PGSQL,则回退到默认的 HOSTNAME

如果 nodename_overwritetrue,节点名称也将用作 HOSTNAME。


node_cluster

名称:node_cluster,类型:string,级别:C

节点集群身份,如果缺失则使用 ’nodes’,可选

默认值:nodes

如果 node_id_from_pgtrue(默认)且 node_cluster 未明确定义,node_cluster 将首先尝试使用 ${pg_cluster},如果此节点上未定义 PGSQL,则回退到默认的 HOSTNAME


nodename_overwrite

名称:nodename_overwrite,类型:bool,级别:C

使用 nodename 覆盖节点的主机名?

默认值为 true,非空节点名 nodename 将覆盖当前节点的主机名。

nodename 参数未定义或为空字符串,但 node_id_from_pgtrue 时,节点名称将尝试使用 {{ pg_cluster }}-{{ pg_seq }},借用 1:1 PostgreSQL 实例的实例名身份。

如果 nodename 未定义、为空或空字符串且 node_id_from_pgfalse,则不对主机名进行任何更改。


nodename_exchange

名称:nodename_exchange,类型:bool,级别:C

在 play 主机间交换节点名?

默认值为 false

启用此参数时,在执行 node.yml playbook 的同一组节点之间交换节点名称,写入 /etc/hosts


node_id_from_pg

名称:node_id_from_pg,类型:bool,级别:C

如果适用,使用 postgres 身份作为节点身份?

默认值为 true

如果适用,借用 PostgreSQL 集群和实例身份。

如果 postgres 和节点之间存在 1:1 关系,使用相同的身份很有用。


NODE_DNS

Pigsty 为节点配置静态 DNS 记录和动态 DNS 解析器。

如果您已经有 DNS 服务器,请将 node_dns_method 设置为 none 以禁用动态 DNS 设置。

node_write_etc_hosts: true        # 修改目标节点上的 `/etc/hosts`?
node_default_etc_hosts:           # `/etc/hosts` 中的静态 DNS 记录
  - "${admin_ip} h.pigsty a.pigsty p.pigsty g.pigsty"
node_etc_hosts: []                # `/etc/hosts` 中的额外静态 DNS 记录
node_dns_method: add              # 如何处理 DNS 服务器:add、none、overwrite
node_dns_servers: ['${admin_ip}'] # `/etc/resolv.conf` 中的动态名称服务器
node_dns_options:                 # `/etc/resolv.conf` 中的 DNS 解析选项
  - options single-request-reopen timeout:1

node_write_etc_hosts

名称:node_write_etc_hosts,类型:bool,级别:G|C|I

修改目标节点上的 /etc/hosts

例如,docker VM 默认无法修改 /etc/hosts,因此您可以将此值设置为 false 以禁用修改。


node_default_etc_hosts

名称:node_default_etc_hosts,类型:string[],级别:G

/etc/hosts 中的静态 DNS 记录

默认值:

["${admin_ip} h.pigsty a.pigsty p.pigsty g.pigsty"]

node_default_etc_hosts 是一个数组。每个元素都是格式为 <ip> <name> 的 DNS 记录。

它用于全局静态 DNS 记录。您可以为每个集群使用 node_etc_hosts 来设置临时记录。

确保在 DNS 名称服务器启动之前,将类似 10.10.10.10 h.pigsty a.pigsty p.pigsty g.pigsty 的 DNS 记录写入 /etc/hosts,以确保可以使用域名访问本地 yum 仓库。


node_etc_hosts

名称:node_etc_hosts,类型:string[],级别:C

/etc/hosts 中的额外静态 DNS 记录

默认值:[]

node_default_etc_hosts 相同,但是额外添加的。


node_dns_method

名称:node_dns_method,类型:enum,级别:C

如何处理 DNS 服务器:add、none、overwrite

默认值:add

  • add:将 node_dns_servers 中的记录追加到 /etc/resolv.conf 并保留现有的 DNS 服务器。(默认)
  • overwrite:用 node_dns_servers 中的记录覆盖 /etc/resolv.conf
  • none:如果在生产环境中提供了 DNS 服务器,可以跳过 DNS 服务器配置。

node_dns_servers

名称:node_dns_servers,类型:string[],级别:C

/etc/resolv.conf 中的动态名称服务器

默认值:["${admin_ip}"],管理节点上的默认名称服务器将作为第一个名称服务器添加到 /etc/resolv.conf


node_dns_options

名称:node_dns_options,类型:string[],级别:C

/etc/resolv.conf 中的 DNS 解析选项,默认值:

- options single-request-reopen timeout:1

NODE_PACKAGE

本节讨论要安装的上游 yum 仓库和软件包。

node_repo_modules: local          # 要在节点上添加的上游仓库,默认为本地
node_repo_remove: true            # 移除节点上现有的仓库?
node_packages: [openssh-server]   # 要安装最新版本的当前节点软件包
#node_default_packages: []        # 要在基础设施节点上安装的默认软件包,(默认值从 node_id/vars 加载)

node_repo_modules

名称:node_repo_modules,类型:string,级别:C/A

要在节点上添加的上游仓库,默认值:local

此参数指定要添加到节点的上游仓库。它用于过滤 repo_upstream 条目,只有具有相同 module 值的条目才会添加到节点的软件源。这类似于 repo_modules 参数。


node_repo_remove

名称:node_repo_remove,类型:bool,级别:C/A

移除节点上现有的仓库?

默认值为 true,因此 Pigsty 将在添加上游仓库之前将 /etc/yum.repos.d 中的现有仓库文件移动到备份目录:/etc/yum.repos.d/backup。在 Debian/Ubuntu 上,Pigsty 将备份并移动 /etc/apt/sources.list(.d)/etc/apt/backup


node_packages

名称:node_packages,类型:string[],级别:C

要在当前节点上安装的软件包,默认值:[openssh-server]

每个元素都是逗号分隔的软件包名称列表,除了 node_default_packages 之外,还将在当前节点上安装。

此参数中指定的软件包将升级到最新版本,默认值为 [openssh-server],默认升级 sshd 以避免 SSH CVE。

此参数通常用于安装对当前节点/集群而言是临时的额外软件包。


node_default_packages

名称:node_default_packages,类型:string[],级别:G

要在所有节点上安装的默认软件包,未定义默认值。

此参数是字符串数组,每个字符串都是逗号分隔的软件包名称列表,默认情况下将在所有节点上安装。

此参数没有默认值,您可以明确指定它,或者如果要使用默认值则将其留空。

当将其留空时,Pigsty 将根据您的操作系统使用 roles/node_id/vars 中定义的 node_packages_default 的默认值。

对于 EL 系统,默认值为:

- lz4,unzip,bzip2,pv,jq,git,ncdu,make,patch,bash,lsof,wget,uuid,tuned,nvme-cli,numactl,sysstat,iotop,htop,rsync,tcpdump
- python3,python3-pip,socat,lrzsz,net-tools,ipvsadm,telnet,ca-certificates,openssl,keepalived,etcd,haproxy,chrony
- zlib,yum,audit,bind-utils,readline,vim-minimal,node_exporter,grubby,openssh-server,openssh-clients

对于 debian / ubuntu 节点,明确使用此默认值:

- lz4,unzip,bzip2,pv,jq,git,ncdu,make,patch,bash,lsof,wget,uuid,tuned,nvme-cli,numactl,sysstat,iotop,htop,rsync,tcpdump
- python3,python3-pip,socat,lrzsz,net-tools,ipvsadm,telnet,ca-certificates,openssl,keepalived,etcd,haproxy,chrony
- zlib1g,acl,dnsutils,libreadline-dev,vim-tiny,node-exporter,openssh-server,openssh-client

NODE_TUNE

在节点上配置调优模板、功能、内核模块、sysctl 参数。

node_disable_firewall: true       # 禁用节点防火墙?默认为 true
node_disable_selinux: true        # 禁用节点 selinux?默认为 true
node_disable_numa: false          # 禁用节点 numa,需要重启
node_disable_swap: false          # 禁用节点交换分区,谨慎使用
node_static_network: true         # 重启后保留 DNS 解析器设置
node_disk_prefetch: false         # 在 HDD 上设置磁盘预取以提高性能
node_kernel_modules: [ softdog, ip_vs, ip_vs_rr, ip_vs_wrr, ip_vs_sh ]
node_hugepage_count: 0            # 2MB 大页数量,优先于比率
node_hugepage_ratio: 0            # 节点内存大页比率,0 禁用它(默认)
node_overcommit_ratio: 0          # 节点内存过量使用比率,0 禁用它(默认)
node_tune: oltp                   # 节点调优配置文件:none、oltp、olap、crit、tiny
node_sysctl_params: { }           # 除调优外的 k:v 格式 sysctl 参数

node_disable_firewall

名称:node_disable_firewall,类型:bool,级别:C

禁用节点防火墙?默认为 true

默认值为 true


node_disable_selinux

名称:node_disable_selinux,类型:bool,级别:C

禁用节点 selinux?默认为 true

默认值为 true


node_disable_numa

名称:node_disable_numa,类型:bool,级别:C

禁用节点 numa,需要重启

默认值为 false

布尔标志,默认不关闭。请注意,关闭 NUMA 需要重启机器才能生效!

如果您不知道如何设置 CPU 亲和性,建议关闭 NUMA。


node_disable_swap

名称:node_disable_swap,类型:bool,级别:C

禁用节点交换分区,谨慎使用

默认值为 false

不建议关闭 SWAP。但是,当您的节点用于 Kubernetes 部署时,应该禁用 SWAP。

如果有足够的内存并且数据库独占部署,可能会略微提高性能。


node_static_network

名称:node_static_network,类型:bool,级别:C

重启后保留 DNS 解析器设置,默认值为 true

启用静态网络意味着机器重启不会因 NIC 更改而覆盖您的 DNS Resolv 配置。建议在生产环境中启用。


node_disk_prefetch

名称:node_disk_prefetch,类型:bool,级别:C

在 HDD 上设置磁盘预取以提高性能

默认值为 false,使用 HDD 时考虑启用此功能。


node_kernel_modules

名称:node_kernel_modules,类型:string[],级别:C

要在此节点上启用的内核模块

默认值:

node_kernel_modules: [ softdog, ip_vs, ip_vs_rr, ip_vs_wrr, ip_vs_sh ]

由内核模块名称组成的数组,声明需要在节点上安装的内核模块。


node_hugepage_count

名称:node_hugepage_count,类型:int,级别:C

2MB 大页数量,优先于比率,默认为 0

优先于 node_hugepage_ratio。如果给出非零值,将写入 /etc/sysctl.d/hugepage.conf

如果 node_hugepage_countnode_hugepage_ratio 都为 0(默认),大页将完全禁用。

负值不起作用,高于节点内存 90% 的数字将上限到节点内存的 90%。

如果不为零,它应该略大于 pg_shared_buffer_ratio


node_hugepage_ratio

名称:node_hugepage_ratio,类型:float,级别:C

节点内存大页比率,0 禁用它(默认),有效范围:0 ~ 0.40

默认值:0,将设置 vm.nr_hugepages=0 并且根本不使用 HugePage。

此内存的百分比将分配为 HugePage,并为 PostgreSQL 保留。

如果不为零,它应该等于或略大于 pg_shared_buffer_ratio

例如,如果您为 postgres 共享缓冲区使用默认的 25% 内存,您可以将此值设置为 0.27 ~ 0.30,浪费的大页可以稍后使用 /pg/bin/pg-tune-hugepage 回收。


node_overcommit_ratio

名称:node_overcommit_ratio,类型:int,级别:C

节点内存过量使用比率,0 禁用它(默认)。这是一个从 0 到 100+ 的整数。

默认值:0,将设置 vm.overcommit_memory=0,否则将使用 vm.overcommit_memory=2,此值将用作 vm.overcommit_ratio

建议在专用 pgsql 节点上设置使用 vm.overcommit_ratio。例如 50 ~ 100。


node_tune

名称:node_tune,类型:enum,级别:C

节点调优配置文件:none、oltp、olap、crit、tiny

默认值:oltp

  • tiny:微型虚拟机(1 ~ 3 核,1 ~ 8 GB 内存)
  • oltp:优化延迟的常规 OLTP 模板
  • olap:优化吞吐量的常规 OLAP 模板
  • crit:核心金融业务模板,优化脏页数量

通常,数据库调优模板 pg_conf 应该与节点调优模板配对:node_tune


node_sysctl_params

名称:node_sysctl_params,类型:dict,级别:C

除调优外的 k:v 格式 sysctl 参数

默认值:{}

字典 K-V 结构,Key 是内核 sysctl 参数名称,Value 是参数值。

您也可以使用调优配置文件定义 sysctl 参数。


NODE_ADMIN

本节讨论管理员用户及其凭据。

node_data: /data                  # 节点主数据目录,默认为 `/data`
node_admin_enabled: true          # 在目标节点上创建管理员用户?
node_admin_uid: 88                # 节点管理员用户的 uid 和 gid
node_admin_username: dba          # 节点管理员用户名,默认为 `dba`
node_admin_ssh_exchange: true     # 在节点集群间交换管理员 SSH 密钥
node_admin_pk_current: true       # 将当前用户的 SSH 公钥添加到管理员 authorized_keys
node_admin_pk_list: []            # 要添加到管理员用户的 SSH 公钥

node_data

名称:node_data,类型:path,级别:C

节点主数据目录,默认为 /data

默认值:/data

如果指定,此路径将用作主数据磁盘挂载点。如果路径不存在,将创建目录并抛出警告。

数据目录由 root 拥有,模式为 0777


node_admin_enabled

名称:node_admin_enabled,类型:bool,级别:C

在目标节点上创建管理员用户?

默认值为 true

在每个节点上创建管理员用户(免密 sudo 和 ssh),默认创建名为 dba (uid=88) 的管理员用户,可以从元节点通过 SSH 免密访问环境中的其他节点并执行 sudo。


node_admin_uid

名称:node_admin_uid,类型:int,级别:C

节点管理员用户的 uid 和 gid

默认值:88


node_admin_username

名称:node_admin_username,类型:username,级别:C

节点管理员用户名,默认为 dba

默认值:dba


node_admin_ssh_exchange

名称:node_admin_ssh_exchange,类型:bool,级别:C

在节点集群间交换管理员 SSH 密钥

默认值为 true

启用时,Pigsty 将在 playbook 执行期间在成员之间交换 SSH 公钥,允许管理员 node_admin_username 从不同节点相互访问。


node_admin_pk_current

名称:node_admin_pk_current,类型:bool,级别:C

将当前用户的 SSH 公钥添加到管理员 authorized_keys

默认值为 true

启用时,在当前节点上,当前用户的 SSH 公钥(~/.ssh/id_rsa.pub)被复制到目标节点管理员用户的 authorized_keys

在生产环境中部署时,请务必注意此参数,它将当前执行命令的用户的默认公钥安装到所有机器的管理员用户。


node_admin_pk_list

名称:node_admin_pk_list,类型:string[],级别:C

要添加到管理员用户的 SSH 公钥

默认值:[]

数组的每个元素都是一个字符串,包含写入管理员用户 ~/.ssh/authorized_keys 的密钥,具有相应私钥的用户可以作为管理员用户登录。

在生产环境中部署时,请务必注意此参数,并且只将受信任的密钥添加到此列表。


node_aliases

名称:node_aliases,类型:dict,级别:C/I

要添加到管理员用户 shell 配置文件的额外别名

默认值:{}

您可以向其添加额外的 shell 别名,pigsty 将这些别名添加到目标节点上的 /etc/profile.d/node.alias.sh 文件:

node_aliases:
  g:   git
  d:   docker

这将生成:

alias g="git"
alias d="docker"

NODE_TIME

node_timezone: ''                 # 设置节点时区,空字符串跳过
node_ntp_enabled: true            # 启用 chronyd 时间同步服务?
node_ntp_servers:                 # `/etc/chrony.conf` 中的 NTP 服务器
  - pool pool.ntp.org iburst
node_crontab_overwrite: true      # 覆盖还是追加到 `/etc/crontab`?
node_crontab: [ ]                 # `/etc/crontab` 中的 crontab 条目

node_timezone

名称:node_timezone,类型:string,级别:C

设置节点时区,空字符串跳过

默认值为空字符串,不会更改默认时区(通常为 UTC)


node_ntp_enabled

名称:node_ntp_enabled,类型:bool,级别:C

启用 chronyd 时间同步服务?

默认值为 true,因此 Pigsty 将使用 node_ntp_servers 覆盖节点的 /etc/chrony.conf

如果您已经配置了 NTP 服务器,只需设置为 false 即可保持不变。


node_ntp_servers

名称:node_ntp_servers,类型:string[],级别:C

/etc/chrony.conf 中的 NTP 服务器,默认值:["pool pool.ntp.org iburst"]

只有当 node_ntp_enabled 为 true 时才生效。

您可以使用 ${admin_ip} 与管理节点上的 NTP 服务器同步时间,而不是公共 NTP 服务器。

node_ntp_servers: [ 'pool ${admin_ip} iburst' ]

node_crontab_overwrite

名称:node_crontab_overwrite,类型:bool,级别:C

覆盖还是追加到 /etc/crontab

默认值为 true,pigsty 将以覆盖模式渲染 node_crontab 中的记录,而不是追加到其中。


node_crontab

名称:node_crontab,类型:string[],级别:C

/etc/crontab 中的 crontab 条目

默认值:[]


NODE_VIP

您可以在一个节点集群之间绑定可选的 L2 VIP,默认情况下是禁用的。

L2 VIP 只能在同一 L2 LAN 中使用,这可能会对您的网络拓扑产生额外限制。

如果启用,您必须为每个节点集群手动分配 vip_addressvip_vrid

用户有责任确保地址 / vrid 在同一 LAN 中是唯一的

vip_enabled: false                # 在此节点集群上启用 VIP?
# vip_address:         [IDENTITY] # IPv4 格式的节点 VIP 地址,如果启用 VIP 则必需
# vip_vrid:            [IDENTITY] # 必需,整数,1-254,在同一 VLAN 中应唯一
vip_role: backup                  # 可选,`master/backup`,默认为 backup,用作初始角色
vip_preempt: false                # 可选,`true/false`,默认为 false,启用 VIP 抢占
vip_interface: eth0               # 节点 VIP 监听的网络接口,默认为 `eth0`
vip_dns_suffix: ''                # 节点 VIP DNS 名称后缀,默认为空字符串
vip_exporter_port: 9650           # keepalived 导出器监听端口,默认为 9650

vip_enabled

名称:vip_enabled,类型:bool,级别:C

在此节点集群上启用 VIP?默认值为 false,表示不为此节点集群创建 L2 VIP。

L2 VIP 只能在同一 L2 LAN 中使用,这可能会对您的网络拓扑产生额外限制。


vip_address

名称:vip_address,类型:ip,级别:C

IPv4 格式的节点 VIP 地址,如果节点 vip_enabled必需

无默认值。此参数必须明确分配并在您的 LAN 中唯一。


vip_vrid

名称:vip_vrid,类型:int,级别:C

整数,1-254,在同一 VLAN 中应唯一,如果节点 vip_enabled必需

无默认值。此参数必须明确分配并在您的 LAN 中唯一。


vip_role

名称:vip_role,类型:enum,级别:I

节点 VIP 角色,可以是 masterbackup,将用作初始 keepalived 状态。


vip_preempt

名称:vip_preempt,类型:bool,级别:C/I

可选,true/false,默认为 false,启用 VIP 抢占

默认值为 false,表示当备份具有比活跃主服务器更高的优先级时不会发生抢占。


vip_interface

名称:vip_interface,类型:string,级别:C/I

节点 VIP 监听的网络接口,默认为 eth0

它应该是节点的相同主要内网接口,即您在清单文件中使用的 IP 地址。

如果您的节点有不同的接口,您可以在实例变量上覆盖它。


vip_dns_suffix

名称:vip_dns_suffix,类型:string,级别:C/I

节点 VIP DNS 名称后缀,默认为空字符串。它将用作节点 VIP 的 DNS 名称。


vip_exporter_port

名称:vip_exporter_port,类型:port,级别:C/I

keepalived 导出器监听端口,默认为 9650。


HAPROXY

默认情况下,HAProxy 安装在每个节点上,以 NodePort 方式公开服务。

它由 PGSQL Service 使用。

haproxy_enabled: true             # 在此节点上启用 haproxy?
haproxy_clean: false              # 清理所有现有的 haproxy 配置?
haproxy_reload: true              # 配置后重新加载 haproxy?
haproxy_auth_enabled: true        # 为 haproxy 管理页面启用身份验证
haproxy_admin_username: admin     # haproxy 管理员用户名,默认为 `admin`
haproxy_admin_password: pigsty    # haproxy 管理员密码,默认为 `pigsty`
haproxy_exporter_port: 9101       # haproxy 管理/导出器端口,默认为 9101
haproxy_client_timeout: 24h       # 客户端连接超时,默认为 24h
haproxy_server_timeout: 24h       # 服务器端连接超时,默认为 24h
haproxy_services: []              # 要在节点上公开的 haproxy 服务列表

haproxy_enabled

名称:haproxy_enabled,类型:bool,级别:C

在此节点上启用 haproxy?

默认值为 true


haproxy_clean

名称:haproxy_clean,类型:bool,级别:G/C/A

清理所有现有的 haproxy 配置?

默认值为 false


haproxy_reload

名称:haproxy_reload,类型:bool,级别:A

配置后重新加载 haproxy?

默认值为 true,它将在配置更改后重新加载 haproxy。

如果您希望在应用之前检查,您可以使用 cli 参数关闭此功能并检查它。


haproxy_auth_enabled

名称:haproxy_auth_enabled,类型:bool,级别:G

为 haproxy 管理页面启用身份验证

默认值为 true,这将需要管理页面的 http 基本身份验证。

不建议禁用它,因为您的流量控制将被暴露。


haproxy_admin_username

名称:haproxy_admin_username,类型:username,级别:G

haproxy 管理员用户名,默认为 admin


haproxy_admin_password

名称:haproxy_admin_password,类型:password,级别:G

haproxy 管理员密码,默认为 pigsty

请在您的生产环境中更改它!


haproxy_exporter_port

名称:haproxy_exporter_port,类型:port,级别:C

haproxy 管理/导出器端口,默认为 9101


haproxy_client_timeout

名称:haproxy_client_timeout,类型:interval,级别:C

客户端连接超时,默认为 24h


haproxy_server_timeout

名称:haproxy_server_timeout,类型:interval,级别:C

服务器端连接超时,默认为 24h


haproxy_services

名称:haproxy_services,类型:service[],级别:C

要在节点上公开的 haproxy 服务列表,默认值:[]

每个元素都是一个服务定义,这是一个临时 haproxy 服务示例:

haproxy_services:                   # haproxy 服务列表

  # 公开 pg-test 只读副本
  - name: pg-test-ro                # [必需] 服务名称,唯一
    port: 5440                      # [必需] 服务端口,唯一
    ip: "*"                         # [可选] 服务监听地址,默认为 "*"
    protocol: tcp                   # [可选] 服务协议,默认为 'tcp'
    balance: leastconn              # [可选] 负载均衡算法,默认为 roundrobin(或 leastconn)
    maxconn: 20000                  # [可选] 最大允许前端连接,默认为 20000
    default: 'inter 3s fastinter 1s downinter 5s rise 3 fall 3 on-marked-down shutdown-sessions slowstart 30s maxconn 3000 maxqueue 128 weight 100'
    options:
      - option httpchk
      - option http-keep-alive
      - http-check send meth OPTIONS uri /read-only
      - http-check expect status 200
    servers:
      - { name: pg-test-1 ,ip: 10.10.10.11 , port: 5432 , options: check port 8008 , backup: true }
      - { name: pg-test-2 ,ip: 10.10.10.12 , port: 5432 , options: check port 8008 }
      - { name: pg-test-3 ,ip: 10.10.10.13 , port: 5432 , options: check port 8008 }

它将渲染到 /etc/haproxy/<service.name>.cfg 并在重新加载后生效。


NODE_EXPORTER

node_exporter_enabled: true       # 在此节点上设置 node_exporter?
node_exporter_port: 9100          # node exporter 监听端口,默认为 9100
node_exporter_options: '--no-collector.softnet --no-collector.nvme --collector.tcpstat --collector.processes'

node_exporter_enabled

名称:node_exporter_enabled,类型:bool,级别:C

在此节点上设置 node_exporter?默认值为 true


node_exporter_port

名称:node_exporter_port,类型:port,级别:C

node exporter 监听端口,默认为 9100


node_exporter_options

名称:node_exporter_options,类型:arg,级别:C

node_exporter 的额外服务器选项,默认值:--no-collector.softnet --no-collector.nvme --collector.tcpstat --collector.processes

默认情况下,Pigsty 启用 tcpstatprocesses 收集器并禁用 nvmesoftnet 指标收集器。


PROMTAIL

Promtail 将从其他模块收集日志,并将它们发送到 LOKI

  • INFRA:基础设施日志,仅在基础设施节点上收集。
    • nginx-access/var/log/nginx/access.log
    • nginx-error/var/log/nginx/error.log
    • grafana/var/log/grafana/grafana.log
  • NODES:主机节点日志,在所有节点上收集。
    • syslog/var/log/messages
    • dmesg/var/log/dmesg
    • cron/var/log/cron
  • PGSQL:PostgreSQL 日志,当节点使用 pg_cluster 定义时收集。
    • postgres/pg/log/postgres/*
    • patroni/pg/log/patroni.log
    • pgbouncer/pg/log/pgbouncer/pgbouncer.log
    • pgbackrest/pg/log/pgbackrest/*.log
  • REDIS:Redis 日志,当节点使用 redis_cluster 定义时收集。
    • redis/var/log/redis/*.log

日志目录可根据 pg_log_dirpatroni_log_dirpgbouncer_log_dirpgbackrest_log_dir 自定义

promtail_enabled: true            # 启用 promtail 日志收集器?
promtail_clean: false             # 初始化期间清除现有的 promtail 状态文件?
promtail_port: 9080               # promtail 监听端口,默认为 9080
promtail_positions: /var/log/positions.yaml # promtail 位置状态文件路径

promtail_enabled

名称:promtail_enabled,类型:bool,级别:C

启用 promtail 日志收集器?

默认值为 true


promtail_clean

名称:promtail_clean,类型:bool,级别:G/A

初始化期间清除现有的 promtail 状态文件?

默认值为 false,如果您选择清理,Pigsty 将删除由 promtail_positions 定义的现有状态文件,这意味着 Promtail 将重新收集当前节点上的所有日志并再次将它们发送到 Loki。


promtail_port

名称:promtail_port,类型:port,级别:C

promtail 监听端口,默认为 9080

默认值:9080


promtail_positions

名称:promtail_positions,类型:path,级别:C

promtail 位置状态文件路径

默认值:/var/log/positions.yaml

Promtail 记录所有日志的消费偏移量,定期写入由 promtail_positions 指定的文件。

13.4 - 管理

节点管理标准操作程序

节点管理 SOP,添加和移除节点,设置管理员,绑定 VIP 和其他杂项

以下是 NODE 模块的一些常见管理任务。


添加节点

要将节点添加到 Pigsty,您需要对该节点具有免密 ssh/sudo 访问权限

# ./node.yml -l <cls|ip|group>        # 底层 playbook
# bin/node-add <selector|ip...>       # 将集群/节点添加到 pigsty
bin/node-add node-test                # 初始化节点集群 'node-test'
bin/node-add 10.10.10.10              # 初始化节点 '10.10.10.10'

移除节点

要从 Pigsty 中移除节点,您可以使用以下命令:

# ./node-rm.yml -l <cls|ip|group>    # 底层 playbook
# bin/node-rm <selector|ip...>       # 从 pigsty 中移除节点:
bin/node-rm node-test                # 移除节点集群 'node-test'
bin/node-rm 10.10.10.10              # 移除节点 '10.10.10.10'

创建管理员

如果当前用户对节点没有免密 ssh/sudo 访问权限,您可以使用其他管理员用户来引导节点:

node.yml -t node_admin -k -K -e ansible_user=<another admin>   # 为另一个管理员输入 ssh/sudo 密码

绑定 VIP

您可以使用 vip_enabled 在节点集群上绑定可选的 L2 VIP。

proxy:
  hosts:
    10.10.10.29: { nodename: proxy-1 }
    10.10.10.30: { nodename: proxy-2 } # , vip_role: master }
  vars:
    node_cluster: proxy
    vip_enabled: true
    vip_vrid: 128
    vip_address: 10.10.10.99
    vip_interface: eth1
./node.yml -l proxy -t node_vip     # 首次启用
./node.yml -l proxy -t vip_refresh  # 刷新 VIP 配置(例如指定主节点)

其他任务

# Play
./node.yml -t node                            # 初始化节点本身(不包括 haproxy 监控)
./node.yml -t haproxy                         # 在节点上设置 haproxy 以暴露服务
./node.yml -t monitor                         # 设置 node_exporter 和 promtail 用于指标和日志
./node.yml -t node_vip                        # 为节点集群 L2 VIP 启用 keepalived
./node.yml -t vip_config,vip_reload           # 刷新 L2 VIP 配置
./node.yml -t haproxy_config,haproxy_reload   # 刷新节点集群上的 haproxy 服务定义
./node.yml -t register_prometheus             # 将节点注册到 Prometheus
./node.yml -t register_nginx                  # 将 haproxy 管理页面 URL 注册到基础设施节点上的 Nginx

# Task
./node.yml -t node-id        # 生成节点身份
./node.yml -t node_name      # 设置主机名
./node.yml -t node_hosts     # 设置 /etc/hosts 记录
./node.yml -t node_resolv    # 设置 DNS 解析器
./node.yml -t node_firewall  # 设置防火墙和 selinux
./node.yml -t node_ca        # 添加和信任 CA 证书
./node.yml -t node_repo      # 添加上游仓库
./node.yml -t node_pkg       # 安装 yum 包
./node.yml -t node_feature   # 设置 numa、grub、静态网络
./node.yml -t node_kernel    # 启用内核模块
./node.yml -t node_tune      # 设置调优配置文件
./node.yml -t node_sysctl    # 设置额外的 sysctl 参数
./node.yml -t node_profile   # 写入 /etc/profile.d/node.sh
./node.yml -t node_ulimit    # 设置资源限制
./node.yml -t node_data      # 设置主数据目录
./node.yml -t node_admin     # 设置管理员用户和 SSH 密钥
./node.yml -t node_timezone  # 设置时区
./node.yml -t node_ntp       # 设置 NTP 服务器/客户端
./node.yml -t node_crontab   # 添加/覆写 crontab 任务
./node.yml -t node_vip       # 为节点集群设置可选的 L2 VRRP VIP

节点调优

Pigsty 为不同的工作负载预定义了四个调优配置文件:

配置文件 描述 场景
TINY 针对小型虚拟机运行优化 规格 < 4c8g
OLTP 针对延迟优化 默认,事务处理
OLAP 针对吞吐量优化 分析性工作负载
CRIT 针对可靠性优化 金融、关键业务

您也可以在节点上使用 tuned-adm 命令管理调优配置文件:

tuned-adm list             # 列出可用配置文件
tuned-adm active           # 显示当前配置文件
tuned-adm profile          # 列出活动配置文件
tuned-adm profile <name>   # 切换到配置文件 <name>
tuned-adm verify           # 列出活动配置文件
cat /var/log/tuned/tuned.log  # 显示调优日志

内核模块

您可以在 node.yml 中使用 node_kernel_modules 管理内核模块。

要手动管理内核模块,您可以在节点上使用以下命令:

lsmod                   # 列出已加载的内核模块
modprobe <module>       # 加载内核模块 <module>

13.5 - 剧本

使用 Ansible playbooks 自动化节点生命周期管理

Pigsty 提供两个用于节点管理的 playbooks:

剧本 目的 用法 范围
node.yml 将节点添加到 pigsty ./node.yml -l <target> 单个节点或集群
node-rm.yml 从 pigsty 中移除节点 ./node-rm.yml -l <target> 单个节点或集群

node.yml

node.yml playbook 将裸机计算资源转换为 Pigsty 基础设施中完全配置、监控和服务就绪的节点。这个全面的自动化处理从基本操作系统配置到高级监控设置的所有内容。

node-id       : generate node identity
node_name     : setup hostname
node_hosts    : setup /etc/hosts records
node_resolv   : setup dns resolver
node_firewall : setup firewall & selinux
node_ca       : add & trust ca certificate
node_repo     : add upstream repo
node_pkg      : install yum packages
node_feature  : setup numa, grub, static network
node_kernel   : enable kernel modules
node_tune     : setup tuned profile
node_sysctl   : setup additional sysctl parameters
node_profile  : write /etc/profile.d/node.sh
node_ulimit   : setup resource limits
node_data     : setup main data dir
node_admin    : setup admin user and ssh key
node_timezone : setup timezone
node_ntp      : setup ntp server/clients
node_crontab  : add/overwrite crontab tasks
node_vip      : setup optional l2 vrrp vip for node cluster
  - vip_install
  - vip_config
  - vip_launch
  - vip_reload
haproxy       : setup haproxy on node to expose services
  - haproxy_install
  - haproxy_config
  - haproxy_launch
  - haproxy_reload
monitor       : setup node_exporter & promtail for metrics & logs
  - haproxy_register
  - vip_dns
  - node_exporter
    - node_exporter_config
    - node_exporter_launch
  - vip_exporter
    - vip_exporter_config
    - vip_exporter_launch
  - node_register
  - promtail
    - promtail_clean
    - promtail_config
    - promtail_install
    - promtail_launch

asciicast


node-rm.yml

node-rm.yml playbook 执行从 Pigsty 基础设施中干净、全面地移除节点。此自动化确保所有服务、配置和监控集成都正确注销和清理,防止孤立资源并保持系统卫生。

register       : remove register from prometheus & nginx
  - prometheus : remove registered prometheus monitor target
  - nginx      : remove nginx proxy record for haproxy admin
vip            : remove node keepalived if enabled
haproxy        : remove haproxy load balancer
node_exporter  : remove monitoring exporter
vip_exporter   : remove keepalived_exporter if enabled
promtail       : remove loki log agent
profile        : remove /etc/profile.d/node.sh

13.6 - 监控

使用节点和 Linux 操作系统指标进行主机监控

仪表板

NODE 模块有 6 个仪表板。

NODE Overview:所有节点概览

NODE Cluster:特定节点集群的详细信息

NODE Instance:单个节点实例的详细信息

NODE Alert:所有节点集群/实例的关键指标概览

NODE VIP:节点集群上 L2 VIP 的详细信息

NODE Haproxy:haproxy 负载均衡器的详细信息


告警规则

以下是节点模块的默认告警规则:

################################################################
#                         Node Alert                           #
################################################################
- name: node-alert
  rules:

    #==============================================================#
    #                          Aliveness                           #
    #==============================================================#
    # node exporter is dead indicate node is down
    - alert: NodeDown
      expr: node_up < 1
      for: 1m
      labels: { level: 0, severity: CRIT, category: node }
      annotations:
        summary: "CRIT NodeDown {{ $labels.ins }}@{{ $labels.instance }}"
        description: |
          node_up[ins={{ $labels.ins }}, instance={{ $labels.instance }}] = {{ $value }} < 1
          http://g.pigsty/d/node-instance?var-ins={{ $labels.ins }}

    # haproxy the load balancer
    - alert: HaproxyDown
      expr: haproxy_up < 1
      for: 1m
      labels: { level: 0, severity: CRIT, category: node }
      annotations:
        summary: "CRIT HaproxyDown {{ $labels.ins }}@{{ $labels.instance }}"
        description: |
          haproxy_up[ins={{ $labels.ins }}, instance={{ $labels.instance }}] = {{ $value }} < 1
          http://g.pigsty/d/node-haproxy?var-ins={{ $labels.ins }}

    # promtail the logging agent
    - alert: PromtailDown
      expr: promtail_up < 1
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: "WARN PromtailDown {{ $labels.ins }}@{{ $labels.instance }}"
        description: |
          promtail_up[ins={{ $labels.ins }}, instance={{ $labels.instance }}] = {{ $value }} < 1
          http://g.pigsty/d/node-instance?var-ins={{ $labels.ins }}

    # docker the container engine
    - alert: DockerDown
      expr: docker_up < 1
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: "WARN DockerDown {{ $labels.ins }}@{{ $labels.instance }}"
        description: |
          docker_up[ins={{ $labels.ins }}, instance={{ $labels.instance }}] = {{ $value }} < 1
          http://g.pigsty/d/node-instance?var-ins={{ $labels.ins }}

    # keepalived daemon
    - alert: KeepalivedDown
      expr: keepalived_up < 1
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: "WARN KeepalivedDown {{ $labels.ins }}@{{ $labels.instance }}"
        description: |
          keepalived_up[ins={{ $labels.ins }}, instance={{ $labels.instance }}] = {{ $value }} < 1
          http://g.pigsty/d/node-instance?var-ins={{ $labels.ins }}



    #==============================================================#
    #                          Node : CPU                          #
    #==============================================================#
    # cpu usage high : 1m avg cpu usage > 70% for 3m
    - alert: NodeCpuHigh
      expr: node:ins:cpu_usage_1m > 0.70
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: 'WARN NodeCpuHigh {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.2f" }}'
        description: |
          node:ins:cpu_usage[ins={{ $labels.ins }}] = {{ $value  | printf "%.2f" }} > 70%

    # OPTIONAL: one core high
    # OPTIONAL: throttled
    # OPTIONAL: frequency
    # OPTIONAL: steal

    #==============================================================#
    #                       Node : Schedule                        #
    #==============================================================#
    # node load high : 1m avg standard load > 100% for 3m
    - alert: NodeLoadHigh
      expr: node:ins:stdload1 > 1
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: 'WARN NodeLoadHigh {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.2f" }}'
        description: |
          node:ins:stdload1[ins={{ $labels.ins }}] = {{ $value  | printf "%.2f" }} > 100%


    #==============================================================#
    #                        Node : Memory                         #
    #==============================================================#
    # available memory < 10%
    - alert: NodeOutOfMem
      expr: node:ins:mem_avail < 0.10
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: 'WARN NodeOutOfMem {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.2f" }}'
        description: |
          node:ins:mem_avail[ins={{ $labels.ins }}] = {{ $value  | printf "%.2f" }} < 10%

    # commit ratio > 90%
    #- alert: NodeMemCommitRatioHigh
    #  expr: node:ins:mem_commit_ratio > 0.90
    #  for: 1m
    #  labels: { level: 1, severity: WARN, category: node }
    #  annotations:
    #    summary: 'WARN NodeMemCommitRatioHigh {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.2f" }}'
    #    description: |
    #      node:ins:mem_commit_ratio[ins={{ $labels.ins }}] = {{ $value  | printf "%.2f" }} > 90%

    # OPTIONAL: EDAC Errors

    #==============================================================#
    #                        Node : Swap                           #
    #==============================================================#
    # swap usage > 1%
    - alert: NodeMemSwapped
      expr: node:ins:swap_usage > 0.01
      for: 5m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: 'WARN NodeMemSwapped {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.2f" }}'
        description: |
          node:ins:swap_usage[ins={{ $labels.ins }}] = {{ $value  | printf "%.2f" }} > 1%

    #==============================================================#
    #                     Node : File System                       #
    #==============================================================#

    # filesystem usage > 90%
    - alert: NodeFsSpaceFull
      expr: node:fs:space_usage > 0.90
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: 'WARN NodeFsSpaceFull {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.2f" }}'
        description: |
          node:fs:space_usage[ins={{ $labels.ins }}] = {{ $value  | printf "%.2f" }} > 90%

    # inode usage > 90%
    - alert: NodeFsFilesFull
      expr: node:fs:inode_usage > 0.90
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: 'WARN NodeFsFilesFull {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.2f" }}'
        description: |
          node:fs:inode_usage[ins={{ $labels.ins }}] = {{ $value  | printf "%.2f" }} > 90%

    # file descriptor usage > 90%
    - alert: NodeFdFull
      expr: node:ins:fd_usage > 0.90
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: 'WARN NodeFdFull {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.2f" }}'
        description: |
          node:ins:fd_usage[ins={{ $labels.ins }}] = {{ $value  | printf "%.2f" }} > 90%

    # OPTIONAL: space predict 1d
    # OPTIONAL: filesystem read-only
    # OPTIONAL: fast release on disk space

    #==============================================================#
    #                          Node : Disk                         #
    #==============================================================#
    # read latency > 32ms (typical on pci-e ssd: 100µs)
    - alert: NodeDiskSlow
      expr: node:dev:disk_read_rt_1m{device="dfa"} > 0.032 or node:dev:disk_write_rt_1m{device="dfa"} > 0.032
      for: 1m
      labels: { level: 2, severity: INFO, category: node }
      annotations:
        summary: 'INFO NodeReadSlow {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.6f" }}'
        description: |
          node:dev:disk_read_rt_1m[ins={{ $labels.ins }}] = {{ $value  | printf "%.6f" }} > 32ms

    # OPTIONAL: raid card failure
    # OPTIONAL: read/write traffic high
    # OPTIONAL: read/write latency high

    #==============================================================#
    #                        Node : Network                        #
    #==============================================================#
    # OPTIONAL: unusual network traffic
    # OPTIONAL: interface saturation high

    #==============================================================#
    #                        Node : Protocol                       #
    #==============================================================#

    # rate(node:ins:tcp_error[1m]) > 1
    - alert: NodeTcpErrHigh
      expr: rate(node:ins:tcp_error[1m]) > 1
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: 'WARN NodeTcpErrHigh {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.2f" }}'
        description: |
          rate(node:ins:tcp_error{ins={{ $labels.ins }}}[1m]) = {{ $value  | printf "%.2f" }} > 1

    # node:ins:tcp_retrans_ratio1m > 1e-4
    - alert: NodeTcpRetransHigh
      expr: node:ins:tcp_retrans_ratio1m > 1e-2
      for: 1m
      labels: { level: 2, severity: INFO, category: node }
      annotations:
        summary: 'INFO NodeTcpRetransHigh {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.6f" }}'
        description: |
          node:ins:tcp_retrans_ratio1m[ins={{ $labels.ins }}] = {{ $value  | printf "%.6f" }} > 1%

    # OPTIONAL: tcp conn high
    # OPTIONAL: udp traffic high
    # OPTIONAL: conn track

    #==============================================================#
    #                          Node : Time                         #
    #==============================================================#

    - alert: NodeTimeDrift
      expr: node_timex_sync_status != 1
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: 'WARN NodeTimeDrift {{ $labels.ins }}@{{ $labels.instance }}'
        description: |
          node_timex_status[ins={{ $labels.ins }}]) = {{ $value | printf "%.6f" }} != 0 or
          node_timex_sync_status[ins={{ $labels.ins }}]) = {{ $value | printf "%.6f" }} != 1


    # time drift > 64ms
    # - alert: NodeTimeDrift
    #   expr: node:ins:time_drift > 0.064
    #   for: 1m
    #   labels: { level: 1, severity: WARN, category: node }
    #   annotations:
    #     summary: 'WARN NodeTimeDrift {{ $labels.ins }}@{{ $labels.instance }}'
    #     description: |
    #       abs(node_timex_offset_seconds)[ins={{ $labels.ins }}]) = {{ $value | printf "%.6f" }} > 64ms

13.7 - FAQ

常见问题解答

如何配置 NTP 服务?

如果未配置 NTP,请使用公共 NTP 服务或与管理节点同步时间。

如果您的节点已经配置了 NTP,您可以通过将 node_ntp_enabled 设置为 false 来保持不变。

否则,如果您有互联网访问权限,您可以使用公共 NTP 服务,如 pool.ntp.org

如果您没有互联网访问权限,至少您可以使用以下方式与管理节点同步时间:

node_ntp_servers:                 # /etc/chrony.conf 中的 NTP 服务器
  - pool cn.pool.ntp.org iburst
  - pool ${admin_ip} iburst       # 假设非管理节点没有互联网访问权限

如何强制在节点上同步时间?

使用 chronyc 同步时间。您必须首先配置 NTP 服务。

ansible all -b -a 'chronyc -a makestep'     # 同步时间

您可以将 all 替换为任何组或主机 IP 地址来限制执行范围。


远程节点无法通过 SSH 命令访问。

如果目标机器隐藏在 SSH 跳板机后面,或者进行了一些自定义以至于无法使用 ssh ip 直接访问,请考虑使用 Ansible 连接参数。可以使用 ansible_portansible_host 指定 SSH 别名的额外 SSH 端口。

pg-test:
  vars: { pg_cluster: pg-test }
  hosts:
    10.10.10.11: {pg_seq: 1, pg_role: primary, ansible_host: node-1 }
    10.10.10.12: {pg_seq: 2, pg_role: replica, ansible_port: 22223, ansible_user: admin }
    10.10.10.13: {pg_seq: 3, pg_role: offline, ansible_port: 22224 }

远程节点 SSH 和 SUDO 需要密码

在执行部署和更改时,使用的管理员用户必须对所有节点具有 sshsudo 权限。不需要免密。

您可以在执行 playbook 时通过 -k|-K 参数传入 ssh 和 sudo 密码,甚至可以通过 -eansible_host=<another_user> 使用另一个用户运行 playbook。但是,Pigsty 强烈建议为管理员用户配置 SSH 免密登录和免密 sudo


使用现有管理员用户创建管理员用户。

这将使用该节点上的现有管理员用户创建由 node_admin_username 指定的管理员用户。

./node.yml -k -K -e ansible_user=<another_admin> -t node_admin

使用 HAProxy 公开节点服务

您可以在 node.yml 中使用 haproxy_services 公开服务。

这是使用它公开 MinIO 服务的示例:公开 MinIO 服务


为什么我的节点 /etc/yum.repos.d/* 被清除了?

Pigsty 将尝试在基础设施节点上的本地 yum 仓库中包含所有依赖项。此仓库文件将根据 node_repo_modules 添加。现有的仓库文件将根据 node_repo_remove 的默认值默认删除。这将防止节点使用互联网仓库或一些愚蠢的问题。

如果您想在节点初始化期间保留现有的仓库文件,只需将 node_repo_remove 设置为 false

如果您想在基础设施节点本地仓库引导期间保留现有的仓库文件,只需将 repo_remove 设置为 false


为什么我的 shell 提示符改变了,如何恢复?

pigsty 提示符在 /etc/profile.d/node.sh 中使用环境变量 PS1 定义。

要恢复您现有的提示符,只需删除该文件并重新登录。


腾讯 OpenCloudOS 兼容性问题

OpenCloudOS 没有 softdog 模块,在全局变量上覆盖 node_kernel_modules

node_kernel_modules: [ ip_vs, ip_vs_rr, ip_vs_wrr, ip_vs_sh ]

14 - ETCD

分布式元数据存储

ETCD 是一个分布式、可靠的键值存储,用于分布式系统的最关键数据。 etcd 被用作 patroni 的 DCS(分布式配置存储),为 PostgreSQL 高可用代理提供配置管理和领导者选举功能。

简而言之,PGSQL 依赖于全局的 ETCD 模块,而 ETCD 依赖于 NODE 模块才能正常工作(使用节点 CA)。

配置
    定义不同规模的 etcd 集群
参数
    使用 10 个参数自定义 etcd 组件
管理
    添加/删除 etcd 成员,刷新端点...
剧本
    可在 etcd 模块中使用的 Ansible 剧本
监控
    仪表板、指标、记录和告警规则
常见问题
    关于 etcd 模块的常见问题

14.1 - 配置

描述您想要的集群

在部署之前,您必须在配置清单中定义 etcd 集群。

通常您可以选择一个 etcd 集群:

  • 单节点,无高可用性,仅具有 etcd 功能,适用于开发、测试和演示目的。
  • 三节点,基本高可用性,容忍一个节点故障,适用于中等生产环境。
  • 五节点,更好的高可用性,容忍两个节点故障,适用于大型生产环境。

使用偶数个 etcd 节点是没有意义的,超过五个节点也不常见。


单节点

在清单中定义组 etcd,它将创建一个单例 etcd 实例。

# etcd cluster for ha postgres
etcd: { hosts: { 10.10.10.10: { etcd_seq: 1 } }, vars: { etcd_cluster: etcd } }

这一行几乎存在于所有单节点配置模板中,其中占位符 IP 地址 10.10.10.10 将被替换为当前管理节点 IP。

唯一必要的参数是 etcd_seqetcd_cluster,它们唯一地标识集群和每个实例。


三节点

三节点 etcd 集群非常常见,容忍一个节点故障,适用于大多数情况。

triosafe 配置模板使用三节点 etcd 集群,如下所示:

etcd: # dcs service for postgres/patroni ha consensus
  hosts:  # 1 node for testing, 3 or 5 for production
    10.10.10.10: { etcd_seq: 1 }  # etcd_seq required
    10.10.10.11: { etcd_seq: 2 }  # assign from 1 ~ n
    10.10.10.12: { etcd_seq: 3 }  # use odd numbers
  vars: # cluster level parameter override roles/etcd
    etcd_cluster: etcd  # mark etcd cluster name etcd
    etcd_safeguard: false # safeguard against purging

五节点

五节点 etcd 集群可以容忍两个节点故障,适用于大型生产环境。

prod 模板中有一个五节点 etcd 集群示例:

etcd:
  hosts:
    10.10.10.21 : { etcd_seq: 1 }
    10.10.10.22 : { etcd_seq: 2 }
    10.10.10.23 : { etcd_seq: 3 }
    10.10.10.24 : { etcd_seq: 4 }
    10.10.10.25 : { etcd_seq: 5 }
  vars: { etcd_cluster: etcd    }

您可以使用更多节点,但建议使用 3 或 5 个节点。

Note

为集群大小使用奇数,如 1、3、5、7、…


Etcd 使用

这些是当前使用 Etcd 的服务:

  • patroni:使用 etcd 作为 PostgreSQL HA 的共识后端
  • vip-manager:从 Etcd 读取领导者信息,在 PostgreSQL 集群上绑定可选的 L2 VIP

在对 etcd 集群成员进行任何永久更改后,您必须重新加载 etcd 配置。

例如,更新 patroni 对 etcd 端点的引用:

./pgsql.yml -t pg_conf                                  # re-gen patroni config
./pgsql.yml -t patroni_reload -e patroni_reload=true    # reload patroni config

例如,更新 vip-manager 对 etcd 端点的引用(如果您使用 PGSQL L2 VIP):

./pgsql.yml -t pg_vip # reload vip-manager config

14.2 - 参数

使用 12 个参数自定义 etcd

ETCD 模块共有 12 个参数。

ETCD: 9 个参数:

参数 类型 级别 说明
etcd_seq int I etcd 实例标识符,必需
etcd_cluster string C etcd 集群和组名,默认为 etcd
etcd_learner bool I 防止清除运行中的 etcd 实例?
etcd_data path C etcd 数据目录,默认为 /data/etcd
etcd_port port C etcd 客户端端口,默认为 2379
etcd_peer_port port C etcd 对等端口,默认为 2380
etcd_init enum C etcd 初始集群状态,new 或 existing
etcd_election_timeout int C etcd 选举超时,默认为 1000ms
etcd_heartbeat_interval int C etcd 心跳间隔,默认为 100ms

ETCD_REMOVE: 3 个 参数:

参数 类型 级别 说明
etcd_safeguard bool G/C/A 防止清除运行中的 etcd 实例?
etcd_rm_data bool G/C/A 移除期间删除 etcd 数据?(默认:true)
etcd_rm_pkg bool G/C/A 移除期间卸载 etcd 包?(默认:false)

默认值

默认参数在 roles/etcd/defaults/main.yml 中定义

额外的移除参数在 roles/etcd_remove/defaults/main.yml 中定义

#-----------------------------------------------------------------
# ETCD
#-----------------------------------------------------------------
#etcd_seq: 1                      # etcd instance identifier, explicitly required
etcd_cluster: etcd                # etcd cluster & group name, etcd by default
etcd_data: /data/etcd             # etcd data directory, /data/etcd by default
etcd_learner: false               # etcd instance run as learner? false by default
etcd_port: 2379                   # etcd client port, 2379 by default
etcd_peer_port: 2380              # etcd peer port, 2380 by default
etcd_init: new                    # etcd initial cluster state, new or existing
etcd_election_timeout: 1000       # etcd election timeout, 1000ms by default
etcd_heartbeat_interval: 100      # etcd heartbeat interval, 100ms by default

ETCD_REMOVE 参数

#-----------------------------------------------------------------
# ETCD_REMOVE
#-----------------------------------------------------------------
etcd_safeguard: false             # prevent accidental removal?
etcd_rm_data: true                # remove etcd data during removal?
etcd_rm_pkg: false                # uninstall etcd packages during removal?

etcd_seq

名称:etcd_seq,类型:int,级别:I

etcd 实例标识符,必需

没有默认值,您必须明确指定它。这里是一个 3 节点 etcd 集群示例:

etcd: # dcs service for postgres/patroni ha consensus
  hosts:  # 1 node for testing, 3 or 5 for production
    10.10.10.10: { etcd_seq: 1 }  # etcd_seq required
    10.10.10.11: { etcd_seq: 2 }  # assign from 1 ~ n
    10.10.10.12: { etcd_seq: 3 }  # use odd numbers
  vars: # cluster level parameter override roles/etcd
    etcd_cluster: etcd  # mark etcd cluster name etcd
    etcd_safeguard: false # safeguard against purging

etcd_cluster

名称:etcd_cluster,类型:string,级别:C

etcd 集群和组名,默认为 etcd

默认值:etcd,这是一个固定的组名,当您想要部署一些额外的 etcd 集群时很有用


etcd_learner

名称:etcd_learner,类型:bool,级别:I

将 etcd 实例初始化为学习者?默认值为 false

当设置为 true 时,etcd 实例将被初始化为学习者,因此它无法在 etcd 集群中投票。 您可以稍后使用 etcdctl member promote 命令将其提升为完整成员。


etcd_data

名称:etcd_data,类型:path,级别:C

etcd 数据目录,默认为 /data/etcd


etcd_port

名称:etcd_port,类型:port,级别:C

etcd 客户端端口,默认为 2379


etcd_peer_port

名称:etcd_peer_port,类型:port,级别:C

etcd 对等端口,默认为 2380


etcd_init

名称:etcd_init,类型:enum,级别:C

etcd 初始集群状态,newexisting

默认值:new,将创建一个独立的新 etcd 集群。

existing 在尝试向现有 etcd 集群追加新成员时使用。


etcd_election_timeout

名称:etcd_election_timeout,类型:int,级别:C

etcd 选举超时,默认为 1000(毫秒)


etcd_heartbeat_interval

名称:etcd_heartbeat_interval,类型:int,级别:C

etcd 心跳间隔,默认为 100(毫秒)


ETCD_REMOVE

这一节包含 etcd_remove 角色中定义的参数, 一些供 etcd-rm.yml 剧本使用的行为控制标记。


etcd_safeguard

名称:etcd_safeguard,类型:bool,级别:G/C/A

防止清除 etcd 实例?默认值为 false

如果启用,运行中的 etcd 实例将不会被 etcd-rm.yml playbook 清除。


etcd_rm_data

名称:etcd_rm_data,类型:bool,级别:G/C/A

移除期间删除 etcd 数据?默认值为 true

启用时,etcd-rm.yml playbook 将在集群或成员移除期间删除 etcd 数据目录和配置文件。


etcd_rm_pkg

名称:etcd_rm_pkg,类型:bool,级别:G/C/A

移除期间卸载 etcd 包?默认值为 false

启用时,etcd-rm.yml playbook 将在集群或成员移除期间卸载 etcd 包。

14.3 - 管理预案

etcd 集群管理 SOP:创建、销毁、扩缩容与更新配置。

以下是一些常见的 etcd 管理任务 SOP(预案):

  • 创建集群:如何初始化 etcd 集群?
  • 销毁集群:如何销毁 etcd 集群?
  • 环境变量:如何配置 etcd 客户端,以访问 etcd 服务器集群?
  • 重载配置:如何更新客户端使用的 etcd 服务器成员列表?
  • 添加成员:如何向现有 etcd 集群添加新成员?
  • 移除成员:如何从 etcd 集群移除老成员?
  • 便捷脚本:使用 bin/etcd-addbin/etcd-rm 简化操作

更多问题请参考 FAQ:ETCD


创建集群

要创建一个集群,首先需要在 配置清单 中定义 etcd 集群:

etcd:
  hosts:
    10.10.10.10: { etcd_seq: 1 }
    10.10.10.11: { etcd_seq: 2 }
    10.10.10.12: { etcd_seq: 3 }
  vars: { etcd_cluster: etcd }

执行 etcd.yml 剧本即可。

./etcd.yml  # 初始化 etcd 集群
架构变化:Pigsty v3.6+

自 Pigsty v3.6 起,etcd.yml 剧本专注于集群安装和成员添加,不再包含移除功能。所有移除操作请使用独立的 etcd-rm.yml 剧本。

对于已初始化的生产环境 etcd 集群,可以打开防误删保护 etcd_safeguard,避免误删现有的 etcd 实例。


销毁集群

要销毁一个 etcd 集群,请使用独立的 etcd-rm.yml 剧本。执行此命令前请务必三思!

./etcd-rm.yml                         # 移除整个 etcd 集群
./etcd-rm.yml -e etcd_safeguard=false # 强制覆盖防误删保险

或使用便捷脚本:

bin/etcd-rm                           # 移除整个 etcd 集群

移除剧本会尊重 etcd_safeguard 防误删保险的配置。如果该参数设置为 true,剧本将中止执行以防止误删。

注意

在移除 etcd 集群之前,请确保没有 PostgreSQL 集群正在使用该 etcd 作为 DCS 服务。否则会导致 PostgreSQL 高可用功能失效。


环境变量

Pigsty 默认使用 etcd v3 API(v3.6+ 已移除 v2 API 支持)。Pigsty 会在 etcd 节点上自动配置环境变量脚本 /etc/profile.d/etcdctl.sh,登录后会自动加载。

以下是 etcd 客户端配置环境变量的示例:

alias e="etcdctl"
alias em="etcdctl member"
export ETCDCTL_ENDPOINTS=https://10.10.10.10:2379
export ETCDCTL_CACERT=/etc/etcd/ca.crt
export ETCDCTL_CERT=/etc/etcd/server.crt
export ETCDCTL_KEY=/etc/etcd/server.key
export ETCDCTL_USER="root:$(cat /etc/etcd/etcd.pass)"

配置好客户端环境变量后,你可以使用以下命令进行 etcd CRUD 操作:

e put a 10 ; e get a; e del a   # 基本 KV 操作
e member list                    # 列出集群成员
e endpoint health                # 检查端点健康状态
e endpoint status                # 查看端点状态

Pigsty v4.0 默认启用 etcd 的 RBAC(基于角色的访问控制)认证机制。在集群初始化时,etcd_auth 任务会自动创建 root 用户并启用认证。

root 用户密码etcd_root_password 参数指定,默认值为 Etcd.Root。密码存储在 /etc/etcd/etcd.pass 文件中,权限为 0640(root 所有,etcd 组可读)。

在生产环境中,强烈建议修改默认密码

etcd:
  hosts:
    10.10.10.10: { etcd_seq: 1 }
    10.10.10.11: { etcd_seq: 2 }
    10.10.10.12: { etcd_seq: 3 }
  vars:
    etcd_cluster: etcd
    etcd_root_password: 'YourSecurePassword'  # 修改默认密码

客户端认证方式

# 方式一:使用环境变量(推荐,已自动配置在 /etc/profile.d/etcdctl.sh)
export ETCDCTL_USER="root:$(cat /etc/etcd/etcd.pass)"

# 方式二:在命令行中指定
etcdctl --user root:YourSecurePassword member list

Patroni 与 etcd 认证

PostgreSQL 高可用组件 Patroni 通过 pg_etcd_password 参数配置连接 etcd 的密码。如果该参数为空,Patroni 会使用集群名称作为密码(不推荐)。建议在生产环境中为每个 PG 集群配置独立的 etcd 密码。


重载配置

如果 etcd 集群的成员发生变化(添加或移除成员),我们需要刷新对 etcd 服务端点的引用。目前 Pigsty 中有以下几处 etcd 引用需要更新:

配置位置 配置文件 更新方式
etcd 成员配置 /etc/etcd/etcd.conf ./etcd.yml -t etcd_conf
etcdctl 环境变量 /etc/profile.d/etcdctl.sh ./etcd.yml -t etcd_config
Patroni DCS 配置 /pg/bin/patroni.yml ./pgsql.yml -t pg_conf
VIP-Manager 配置 /etc/default/vip-manager ./pgsql.yml -t pg_vip_config

刷新 etcd 成员配置文件

./etcd.yml -t etcd_conf                           # 刷新 /etc/etcd/etcd.conf
ansible etcd -f 1 -b -a 'systemctl restart etcd'  # 可选:逐一重启 etcd 实例

刷新 etcdctl 客户端环境变量

./etcd.yml -t etcd_config                         # 刷新 /etc/profile.d/etcdctl.sh

更新 Patroni DCS 端点配置

./pgsql.yml -t pg_conf                            # 重新生成 patroni 配置
ansible all -f 1 -b -a 'systemctl reload patroni' # 重新加载 patroni 配置

更新 VIP-Manager 端点配置(仅当使用 PGSQL L2 VIP 时需要):

./pgsql.yml -t pg_vip_config                           # 重新生成 vip-manager 配置
ansible all -f 1 -b -a 'systemctl restart vip-manager' # 重启 vip-manager
提示

使用 bin/etcd-addbin/etcd-rm 便捷脚本时,脚本会在操作完成后提示您需要执行的配置刷新命令。


添加成员

ETCD 参考: 添加成员

推荐方式:使用便捷脚本

使用 bin/etcd-add 脚本是向现有 etcd 集群添加新成员的推荐方式

# 首先在配置清单中添加新成员定义,然后执行:
bin/etcd-add <ip>              # 添加单个新成员
bin/etcd-add <ip1> <ip2> ...   # 添加多个新成员

脚本会自动完成以下操作:

  • 验证 IP 地址有效性
  • 执行 etcd.yml 剧本(自动设置 etcd_init=existing
  • 提供安全警告和倒计时
  • 操作完成后提示配置刷新命令

手动方式:分步操作

向现有的 etcd 集群添加新成员需要以下步骤:

  1. 更新配置清单:将新实例添加到 etcd
  2. 通知集群:执行 etcdctl member add 命令(可选,剧本会自动执行)
  3. 初始化新成员:使用 etcd_init=existing 参数运行剧本
  4. 提升成员:将学习者提升为正式成员(可选,使用 etcd_learner=true 时需要)
  5. 重载配置:更新所有客户端的 etcd 端点引用
# 配置清单更新后,初始化新成员
./etcd.yml -l <new_ins_ip> -e etcd_init=existing

# 如果使用 learner 模式,需要手动提升
etcdctl member promote <new_ins_server_id>
重要

添加新成员时必须使用 etcd_init=existing 参数,否则新实例会尝试创建新集群而非加入现有集群。

详细步骤:向etcd集群添加成员

下面是具体操作的详细细节,让我们从一个单实例 etcd 集群开始:

etcd:
  hosts:
    10.10.10.10: { etcd_seq: 1 } # <--- 集群中原本存在的唯一实例
    10.10.10.11: { etcd_seq: 2 } # <--- 将此新成员定义添加到清单中
  vars: { etcd_cluster: etcd }

使用便捷脚本添加新成员(推荐):

$ bin/etcd-add 10.10.10.11

或者手动操作。首先使用 etcdctl member add 向现有 etcd 集群宣告新的学习者实例 etcd-2 即将到来:

$ etcdctl member add etcd-2 --learner=true --peer-urls=https://10.10.10.11:2380
Member 33631ba6ced84cf8 added to cluster 6646fbcf5debc68f

ETCD_NAME="etcd-2"
ETCD_INITIAL_CLUSTER="etcd-2=https://10.10.10.11:2380,etcd-1=https://10.10.10.10:2380"
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://10.10.10.11:2380"
ETCD_INITIAL_CLUSTER_STATE="existing"

使用 etcdctl member list(或 em list)检查成员列表,我们可以看到一个 unstarted 新成员:

33631ba6ced84cf8, unstarted, , https://10.10.10.11:2380, , true       # 这里有一个未启动的新成员
429ee12c7fbab5c1, started, etcd-1, https://10.10.10.10:2380, https://10.10.10.10:2379, false

接下来使用 etcd.yml 剧本初始化新的 etcd 实例 etcd-2,完成后,我们可以看到新成员已经启动:

$ ./etcd.yml -l 10.10.10.11 -e etcd_init=existing    # 一定要添加 existing 参数
...
33631ba6ced84cf8, started, etcd-2, https://10.10.10.11:2380, https://10.10.10.11:2379, true
429ee12c7fbab5c1, started, etcd-1, https://10.10.10.10:2380, https://10.10.10.10:2379, false

新成员初始化完成并稳定运行后,可以将新成员从学习者提升为追随者:

$ etcdctl member promote 33631ba6ced84cf8   # 将学习者提升为追随者
Member 33631ba6ced84cf8 promoted in cluster 6646fbcf5debc68f

$ em list                # 再次检查,新成员已提升为正式成员
33631ba6ced84cf8, started, etcd-2, https://10.10.10.11:2380, https://10.10.10.11:2379, false
429ee12c7fbab5c1, started, etcd-1, https://10.10.10.10:2380, https://10.10.10.10:2379, false

新成员添加完成,请不要忘记 重载配置 ,让所有客户端也知道新成员的存在。

重复以上步骤,可以添加更多成员。记住,生产环境中至少要使用 3 个成员。


移除成员

推荐方式:使用便捷脚本

使用 bin/etcd-rm 脚本是从 etcd 集群移除成员的推荐方式

bin/etcd-rm <ip>              # 移除指定成员
bin/etcd-rm <ip1> <ip2> ...   # 移除多个成员
bin/etcd-rm                   # 移除整个 etcd 集群

脚本会自动完成以下操作:

  • 从集群中优雅地移除成员
  • 停止并禁用 etcd 服务
  • 清理数据和配置文件
  • 从监控系统中注销

手动方式:分步操作

要从 etcd 集群中删除一个成员实例,通常需要以下步骤:

  1. 从配置清单中移除:注释或删除该实例,并 重载配置
  2. 从集群中踢除:使用 etcdctl member remove 命令
  3. 清理实例:使用 etcd-rm.yml 剧本清理实例
# 使用专用移除剧本(推荐)
./etcd-rm.yml -l <ip>

# 或者手动操作
etcdctl member remove <server_id>      # 从集群中踢除
./etcd-rm.yml -l <ip>                  # 清理实例
详细步骤:从etcd集群移除成员

让我们以一个 3 节点的 etcd 集群为例,从中移除 3 号实例。

方法一:使用便捷脚本(推荐)

$ bin/etcd-rm 10.10.10.12

脚本会自动完成所有操作,包括从集群中移除成员、停止服务、清理数据。

方法二:手动操作

首先,为了刷新配置,您需要 注释 待删除的成员,然后 重载配置,让所有客户端都不要再使用此实例。

etcd:
  hosts:
    10.10.10.10: { etcd_seq: 1 }
    10.10.10.11: { etcd_seq: 2 }
    # 10.10.10.12: { etcd_seq: 3 }   # <---- 注释掉这个成员
  vars: { etcd_cluster: etcd }

然后,使用移除剧本:

$ ./etcd-rm.yml -l 10.10.10.12

剧本会自动执行以下操作:

  1. 获取成员列表并找到对应的成员 ID
  2. 执行 etcdctl member remove 从集群中踢除
  3. 停止 etcd 服务
  4. 清理数据和配置文件

如果需要手动操作,可以这样做:

$ etcdctl member list
429ee12c7fbab5c1, started, etcd-1, https://10.10.10.10:2380, https://10.10.10.10:2379, false
33631ba6ced84cf8, started, etcd-2, https://10.10.10.11:2380, https://10.10.10.11:2379, false
93fcf23b220473fb, started, etcd-3, https://10.10.10.12:2380, https://10.10.10.12:2379, false  # <--- 移除这个

$ etcdctl member remove 93fcf23b220473fb  # 从集群中踢除
Member 93fcf23b220473fb removed from cluster 6646fbcf5debc68f

执行完毕后,您可以将其从配置清单中永久删除,移除成员至此完成。

重复以上步骤,可以移除更多成员,与添加成员配合使用,可以对 etcd 集群进行滚动升级搬迁。


便捷脚本

Pigsty v3.6+ 提供了便捷脚本简化 etcd 集群的扩容和缩容操作:

bin/etcd-add

向现有 etcd 集群添加新成员:

bin/etcd-add <ip>              # 添加单个新成员
bin/etcd-add <ip1> <ip2> ...   # 添加多个新成员

脚本功能:

  • 验证 IP 地址是否在配置清单中定义
  • 自动设置 etcd_init=existing 参数
  • 执行 etcd.yml 剧本完成成员添加
  • 操作完成后提示配置刷新命令

bin/etcd-rm

从 etcd 集群移除成员或整个集群:

bin/etcd-rm <ip>              # 移除指定成员
bin/etcd-rm <ip1> <ip2> ...   # 移除多个成员
bin/etcd-rm                   # 移除整个 etcd 集群

脚本功能:

  • 提供安全警告和确认倒计时
  • 自动执行 etcd-rm.yml 剧本
  • 优雅地从集群中移除成员
  • 清理数据和配置文件

14.4 - 剧本

使用剧本创建,销毁,扩容,缩容 Etcd 集群

有一个内置的 playbook:etcd.yml 用于 etcd 集群安装。


etcd.yml

创建新的 etcd 集群,运行以下 playbook:

./etcd.yml    # 在组 'etcd' 上安装 etcd 集群
bin/etcd-add    # 创建整个 etcd 集群

以下是可用的子任务:

  • etcd_assert:生成 etcd 身份
  • etcd_install:安装 etcd rpm 包
  • etcd_dir:创建 etcd 数据和配置目录
  • etcd_config:生成 etcd 配置
    • etcd_conf:生成 etcd 主配置
    • etcd_cert:生成 etcd ssl 证书
  • etcd_launch:启动 etcd 服务
  • etcd_register:向 prometheus 注册 etcd

如果您想向现有 etcd 集群追加新成员, 您必须将其添加到配置清单中,并使用 etcd_init = existing 对新成员运行 playbook:

./etcd.yml -l <new_instance> -e etcd_init=existing
bin/etcd-add <ip> # 向现有 etcd 集群追加新成员

通常重新运行 playbook 是可以的,它会更新 etcd 集群配置并重启 etcd 实例。

Pigsty v3.6+ 的变化

从 Pigsty v3.6+ 开始,etcd.yml playbook 不再具有集群移除功能。请使用专用的 etcd-rm.yml playbook 和 etcd_remove 角色进行 etcd 集群移除操作。


etcd-rm.yml

移除 etcd 集群,运行以下 playbook:

./etcd-rm.yml    # 移除 etcd 集群

以下是可用的子任务:

  • etcd_safeguard:检查安全防护并在启用时中止
  • prometheus:从 prometheus 移除 etcd 目标注册
  • etcd_leave:在清除前尝试优雅地离开 etcd 集群
  • etcd_stop:使用 systemd 停止并禁用 etcd 服务
  • etcd_data:移除 etcd 数据(使用 etcd_rm_data=false 禁用)
  • etcd_pkg:卸载 etcd 包(使用 etcd_rm_pkg=true 启用)

要从现有 etcd 集群中移除成员,您可以运行 playbook

./etcd-rm.yml -l <ip>
bin/etcd-rm <ip1> <ip2> ...    # 从 etcd 集群移除特定成员
bin/etcd-rm                    # 移除整个 etcd 集群

移除 playbook 使用新的 etcd_remove 角色,具有可配置参数:

14.5 - 监控

etcd 模块的仪表板和告警规则

仪表板

ETCD 模块提供一个监控仪表板:Etcd Overview。

ETCD Overview:ETCD 集群概览

该仪表板提供有关 ETCD 状态的关键信息,其中最值得注意的是 ETCD Aliveness,它显示 ETCD 集群的整体服务状态。

红色条带表示实例不可用的时期,而下方的蓝灰色条带显示整个集群不可用的时期。


告警规则

Pigsty 为 INFRA 模块提供以下两个告警规则:

告警规则 描述 严重程度
EtcdServerDown Etcd 节点宕机,关键告警 Critical
EtcdNoLeader Etcd 集群没有领导者,关键告警 Critical
EtcdQuotaFull Etcd 配额使用率超过 90%,警告 Warning
EtcdNetworkPeerRTSlow Etcd 网络延迟慢,提醒 Notice
EtcdWalFsyncSlow Etcd 磁盘 fsync 慢,提醒 Notice

您可以在 files/prometheus/rules/etcd.yml 中修改或添加新的 etcd 告警规则。

#==============================================================#
#                         Aliveness                            #
#==============================================================#
# etcd server instance down
- alert: EtcdServerDown
  expr: etcd_up < 1
  for: 1m
  labels: { level: 0, severity: CRIT, category: etcd }
  annotations:
    summary: "CRIT EtcdServerDown {{ $labels.ins }}@{{ $labels.instance }}"
    description: |
      etcd_up[ins={{ $labels.ins }}, instance={{ $labels.instance }}] = {{ $value }} < 1
      http://g.pigsty/d/etcd-overview

#==============================================================#
#                         Error                                #
#==============================================================#
# Etcd no Leader triggers a P0 alert immediately
# if dcs_failsafe mode is not enabled, this may lead to global outage
- alert: EtcdNoLeader
  expr: min(etcd_server_has_leader) by (cls) < 1
  for: 15s
  labels: { level: 0, severity: CRIT, category: etcd }
  annotations:
    summary: "CRIT EtcdNoLeader: {{ $labels.cls }} {{ $value }}"
    description: |
      etcd_server_has_leader[cls={{ $labels.cls }}] = {{ $value }} < 1
      http://g.pigsty/d/etcd-overview?from=now-5m&to=now&var-cls={{$labels.cls}}

#==============================================================#
#                        Saturation                            #
#==============================================================#
- alert: EtcdQuotaFull
  expr: etcd:cls:quota_usage > 0.90
  for: 1m
  labels: { level: 1, severity: WARN, category: etcd }
  annotations:
    summary: "WARN EtcdQuotaFull: {{ $labels.cls }}"
    description: |
      etcd:cls:quota_usage[cls={{ $labels.cls }}] = {{ $value | printf "%.3f" }} > 90%

#==============================================================#
#                         Latency                              #
#==============================================================#
# etcd network peer rt p95 > 200ms for 1m
- alert: EtcdNetworkPeerRTSlow
  expr: etcd:ins:network_peer_rt_p95_5m > 0.200
  for: 1m
  labels: { level: 2, severity: INFO, category: etcd }
  annotations:
    summary: "INFO EtcdNetworkPeerRTSlow: {{ $labels.cls }} {{ $labels.ins }}"
    description: |
      etcd:ins:network_peer_rt_p95_5m[cls={{ $labels.cls }}, ins={{ $labels.ins }}] = {{ $value }} > 200ms
      http://g.pigsty/d/etcd-instance?from=now-10m&to=now&var-cls={{ $labels.cls }}

# Etcd wal fsync rt p95 > 50ms
- alert: EtcdWalFsyncSlow
  expr: etcd:ins:wal_fsync_rt_p95_5m > 0.050
  for: 1m
  labels: { level: 2, severity: INFO, category: etcd }
  annotations:
    summary: "INFO EtcdWalFsyncSlow: {{ $labels.cls }} {{ $labels.ins }}"
    description: |
      etcd:ins:wal_fsync_rt_p95_5m[cls={{ $labels.cls }}, ins={{ $labels.ins }}] = {{ $value }} > 50ms
      http://g.pigsty/d/etcd-instance?from=now-10m&to=now&var-cls={{ $labels.cls }}

14.6 - 常见问题

Pigsty etcd 模块常见问题答疑

etcd集群起什么作用?

etcd 是一个分布式的、可靠的键-值存储,用于存放系统中最为关键的数据,Pigsty 使用 etcd 作为 Patroni 的 DCS(分布式配置存储)服务,用于存储 PostgreSQL 集群的高可用状态信息。

Patroni 将通过 etcd,实现集群故障检测、自动故障转移、主从切换,集群配置管理等功能。

etcd 对于 PostgreSQL 集群的高可用至关重要,而 etcd 本身的可用性与容灾,是通过使用多个分布式的节点来保证的。


etcd集群使用多大规模合适?

如果超过集群成员数一半(包括正好一半)的 etcd 实例不可用,那么 etcd 集群将进入不可用状态,拒绝对外提供服务。

例如:使用 3 节点的 etcd 集群允许最多一个节点宕机,而其他两个节点仍然可以正常工作;而使用 5 节点的 etcd 集群则可以容忍 2 节点失效。

请注意,etcd 集群中的 学习者(Learner)实例不计入成员数,因此在 3 节点 etcd 集群中,如果有一个学习者实例,那么实际上成员数量为 2,不能容忍任一节点失效。

在生产环境中,我们建议使用奇数个 etcd 实例,对于生产环境,建议使用 3 节点或 5 节点的 etcd 集群部署以确保足够的可靠性。


etcd集群不可用会有什么影响?

如果 etcd 集群不可用,那么会影响 PostgreSQL 的管控平面,但不会影响数据平面 —— 现有的 PostgreSQL 集群将继续运行,但通过 Patroni 进行的管理操作将无法执行。

etcd 故障期间,PostgreSQL 高可用将无法实现自动故障转移,您也无法使用 patronictl 对 PostgreSQL 集群发起管理操作,例如修改配置,执行手动故障转移等。 通过 Ansible 发起的管理命令不受 etcd 故障影响:例如创建数据库,创建用户,刷新 HBA 与 Service 配置等,etcd 故障期间,您依然可以直接操作 PostgreSQL 集群来实现这些功能。

请注意,以上描述的行为仅适用于较新版本的 Patroni (>=3.0,对应 Pigsty >= 2.0)。如果您使用的是较老版本的 Patroni (<3.0,对应 Pigsty 版本为 1.x),则 etcd / consul 故障会引发极为严重的全局性影响: 所有 PostgreSQL 集群将发生降级:主库将降级为从库,拒绝写请求,etcd 故障将放大为全局性 PostgreSQL 故障。在 Patroni 3.0 引入 DCS Failsafe 功能后,这种情况得到了显著改善。


etcd集群中存储着什么数据?

在 Pigsty 中,etcd 仅用于 PostgreSQL 高可用,并不会用于存储任何其他配置或状态数据。

而 PG 高可用组件 Patroni 会自动生成并管理 etcd 中的数据,当这些数据在 etcd 中丢失时,Patroni 会自动重建。

因此默认情况下,Pigsty 中的 etcd 可以视作 “无状态服务”,可以进行销毁与重建,这为维护工作带来了极大的便利。

如果您将 etcd 用于其他目的,例如作为 Kubernetes 的元数据存储,或自行存储其他数据,那么您需要自行备份 etcd 数据,并在 etcd 集群恢复后进行数据恢复。


如何从etcd故障中恢复?

因为 Pigsty 中的 etcd 只用于 PostgreSQL 高可用,本质上是可销毁、可重建的 “无状态服务”,因此在出现故障时,您可以通过 “重启” / “重置” 来进行快速止血。

重启 etcd 集群,您可以使用以下 Ansible 命令:

./etcd.yml -t etcd_launch

重置 etcd 集群,您可以直接执行以下剧本,实现覆盖抹除式重装:

./etcd.yml

如果您自行使用 etcd 存储了其他数据,那么通常需要备份 etcd 数据,并在 etcd 集群恢复后进行数据恢复。


维护etcd有什么注意事项?

简单的版本是:不要写爆 etcd 就好

Pigsty v2.6+ 默认启用了 etcd 自动压实(Auto Compact)和 16GB 的后端存储配额,通常无需担心写满 etcd 的问题。

etcd 的数据模型 使得每一次写入都会产生一个新的版本。 因此如果您的 etcd 集群频繁写入,即使只有极个别的 Key,etcd 数据库的大小也可能会不断增长。 当达到容量上限时,etcd 将会拒绝写入请求,这可能导致依赖 etcd 的 PostgreSQL 高可用机制无法正常工作。

Pigsty 默认的 etcd 配置已包含以下优化:

auto-compaction-mode: periodic      # 周期性自动压缩
auto-compaction-retention: "24h"    # 保留 24 小时历史
quota-backend-bytes: 17179869184    # 16 GiB 配额

更多维护细节请阅读 etcd 官方文档维护指南

提示

对于 Pigsty v2.6 之前的版本,请参照下面的说明手动启用 etcd 自动垃圾回收。


如何启动etcd自动垃圾回收?

如果您使用的早先版本的 Pigsty (v2.0 - v2.5),我们强烈建议您通过以下步骤,在生产环境中启用 etcd 的自动压实功能,从而避免 etcd 容量配额写满导致的 etcd 不可用故障。

在 Pigsty 源码目录中,编辑 etcd 配置文件模板:roles/etcd/templates/etcd.conf,添加以下三条配置项:

auto-compaction-mode: periodic
auto-compaction-retention: "24h"
quota-backend-bytes: 17179869184

然后将所有相关 PostgreSQL 集群设置为 维护模式 后,重新使用 ./etcd.yml 覆盖部署 etcd 集群即可。

该配置会将 etcd 默认的容量配额从 2 GiB 提高到 16 GiB,并确保只保留最近一天的写入历史版本,从而避免了 etcd 数据库大小的无限增长。


etcd中的PostgreSQL高可用数据存储在哪里?

默认情况下,Patroni 使用 pg_namespace 指定的前缀(默认为 /pg)作为所有元数据键的前缀,随后是 PostgreSQL 集群名称。 例如,名为 pg-meta 的 PG 集群,其元数据键将存储在 /pg/pg-meta 下。

etcdctl get /pg/pg-meta --prefix

其中的数据样本如下所示:

/pg/pg-meta/config
{"ttl":30,"loop_wait":10,"retry_timeout":10,"primary_start_timeout":10,"maximum_lag_on_failover":1048576,"maximum_lag_on_syncnode":-1,"primary_stop_timeout":30,"synchronous_mode":false,"synchronous_mode_strict":false,"failsafe_mode":true,"pg_version":16,"pg_cluster":"pg-meta","pg_shard":"pg-meta","pg_group":0,"postgresql":{"use_slots":true,"use_pg_rewind":true,"remove_data_directory_on_rewind_failure":true,"parameters":{"max_connections":100,"superuser_reserved_connections":10,"max_locks_per_transaction":200,"max_prepared_transactions":0,"track_commit_timestamp":"on","wal_level":"logical","wal_log_hints":"on","max_worker_processes":16,"max_wal_senders":50,"max_replication_slots":50,"password_encryption":"scram-sha-256","ssl":"on","ssl_cert_file":"/pg/cert/server.crt","ssl_key_file":"/pg/cert/server.key","ssl_ca_file":"/pg/cert/ca.crt","shared_buffers":"7969MB","maintenance_work_mem":"1993MB","work_mem":"79MB","max_parallel_workers":8,"max_parallel_maintenance_workers":2,"max_parallel_workers_per_gather":0,"hash_mem_multiplier":8.0,"huge_pages":"try","temp_file_limit":"7GB","vacuum_cost_delay":"20ms","vacuum_cost_limit":2000,"bgwriter_delay":"10ms","bgwriter_lru_maxpages":800,"bgwriter_lru_multiplier":5.0,"min_wal_size":"7GB","max_wal_size":"28GB","max_slot_wal_keep_size":"42GB","wal_buffers":"16MB","wal_writer_delay":"20ms","wal_writer_flush_after":"1MB","commit_delay":20,"commit_siblings":10,"checkpoint_timeout":"15min","checkpoint_completion_target":0.8,"archive_mode":"on","archive_timeout":300,"archive_command":"pgbackrest --stanza=pg-meta archive-push %p","max_standby_archive_delay":"10min","max_standby_streaming_delay":"3min","wal_receiver_status_interval":"1s","hot_standby_feedback":"on","wal_receiver_timeout":"60s","max_logical_replication_workers":8,"max_sync_workers_per_subscription":6,"random_page_cost":1.1,"effective_io_concurrency":1000,"effective_cache_size":"23907MB","default_statistics_target":200,"log_destination":"csvlog","logging_collector":"on","log_directory":"/pg/log/postgres","log_filename":"postgresql-%Y-%m-%d.log","log_checkpoints":"on","log_lock_waits":"on","log_replication_commands":"on","log_statement":"ddl","log_min_duration_statement":100,"track_io_timing":"on","track_functions":"all","track_activity_query_size":8192,"log_autovacuum_min_duration":"1s","autovacuum_max_workers":2,"autovacuum_naptime":"1min","autovacuum_vacuum_cost_delay":-1,"autovacuum_vacuum_cost_limit":-1,"autovacuum_freeze_max_age":1000000000,"deadlock_timeout":"50ms","idle_in_transaction_session_timeout":"10min","shared_preload_libraries":"timescaledb, pg_stat_statements, auto_explain","auto_explain.log_min_duration":"1s","auto_explain.log_analyze":"on","auto_explain.log_verbose":"on","auto_explain.log_timing":"on","auto_explain.log_nested_statements":true,"pg_stat_statements.max":5000,"pg_stat_statements.track":"all","pg_stat_statements.track_utility":"off","pg_stat_statements.track_planning":"off","timescaledb.telemetry_level":"off","timescaledb.max_background_workers":8,"citus.node_conninfo":"sslm
ode=prefer"}}}
/pg/pg-meta/failsafe
{"pg-meta-2":"http://10.10.10.11:8008/patroni","pg-meta-1":"http://10.10.10.10:8008/patroni"}
/pg/pg-meta/initialize
7418384210787662172
/pg/pg-meta/leader
pg-meta-1
/pg/pg-meta/members/pg-meta-1
{"conn_url":"postgres://10.10.10.10:5432/postgres","api_url":"http://10.10.10.10:8008/patroni","state":"running","role":"primary","version":"4.0.1","tags":{"clonefrom":true,"version":"16","spec":"8C.32G.125G","conf":"tiny.yml"},"xlog_location":184549376,"timeline":1}
/pg/pg-meta/members/pg-meta-2
{"conn_url":"postgres://10.10.10.11:5432/postgres","api_url":"http://10.10.10.11:8008/patroni","state":"running","role":"replica","version":"4.0.1","tags":{"clonefrom":true,"version":"16","spec":"8C.32G.125G","conf":"tiny.yml"},"xlog_location":184549376,"replication_state":"streaming","timeline":1}
/pg/pg-meta/status
{"optime":184549376,"slots":{"pg_meta_2":184549376,"pg_meta_1":184549376},"retain_slots":["pg_meta_1","pg_meta_2"]}

如何使用一个外部的已经存在的 etcd 集群?

配置清单中硬编码了所使用 etcd 的分组名为 etcd,这个分组里的成员将被用作 PGSQL 的 DCS 服务器。您可以使用 etcd.yml 对它们进行初始化,或直接假设它是一个已存在的外部 etcd 集群。

要使用现有的外部 etcd 集群,只要像往常一样定义它们即可,您可以跳过 etcd.yml 剧本的执行,因为集群已经存在,不需要部署。

但用户必须确保 现有 etcd 集群证书是由 Pigsty 使用的相同 CA 签名颁发的。否则客户端无法使用 Pigsty 自签名 CA 颁发的证书来访问外部的 etcd 集群。


如何向现有etcd集群添加新的成员?

详细过程,请参考向 etcd 集群添加成员

推荐方式:使用便捷脚本

# 首先在配置清单中添加新成员定义,然后执行:
bin/etcd-add <ip>      # 添加单个新成员
bin/etcd-add <ip1>     # 添加多个新成员

手动方式:

etcdctl member add <etcd-?> --learner=true --peer-urls=https://<new_ins_ip>:2380 # 宣告新成员加入
./etcd.yml -l <new_ins_ip> -e etcd_init=existing                                 # 初始化新成员
etcdctl member promote <new_ins_server_id>                                       # 提升为正式成员

请注意,我们建议一次只添加一个新成员。


如何从现有etcd集群中移除成员?

详细过程,请参考从 etcd 集群中移除成员

推荐方式:使用便捷脚本

bin/etcd-rm <ip>              # 移除指定成员
bin/etcd-rm                   # 移除整个 etcd 集群

手动方式:

./etcd-rm.yml -l <ins_ip>                    # 使用专用移除剧本
etcdctl member remove <etcd_server_id>       # 从集群中踢出成员
./etcd-rm.yml -l <ins_ip>                    # 清理实例

15 - MinIO

开源对象存储服务

Min.IO:兼容 S3 的开源多云对象存储服务,设计为可扩展、安全且便捷。 它具有原生的多节点多驱动器 HA 支持,可以存储文档、图片、视频和备份。它是 Pigsty 中的一个 可选模块

您可以使用 MinIO 作为可选的 PostgreSQL 备份 存储仓库,除了默认的本地 posix FS 仓库之外。如果使用 MinIO 仓库, MINIO 模块应该在任何 PGSQL 模块之前安装。MinIO 需要受信任的 CA 才能工作,所以您必须在 NODE 之后安装它。


配置
    配置 minio 模块,并使用多个 minio 节点。
参数
    使用 22 个参数自定义 minio 组件
管理
    创建、移除、扩展、收缩、升级 minio 集群
剧本
    可在此模块中使用的 Ansible 剧本
监控
    仪表板、指标、记录和告警规则。
使用
    如何使用 mcli 和配置备份仓库

15.1 - 使用

MinIO 与 mcli 使用入门,如何访问 MinIO 服务?

MinIO 集群 配置 并通过 剧本 部署完成后,您可以按照以下说明开始使用和访问 MinIO 集群。


部署集群

使用 Pigsty 部署单节点 MinIO 实例非常简单。

minio: { hosts: { 10.10.10.10: { minio_seq: 1 } }, vars: { minio_cluster: minio } }

配置清单 中定义它,然后运行剧本:

./minio.yml -l minio

install.yml 剧本将自动创建清单中定义的 MinIO 集群,因此如果您选择默认的一次性安装,无需手动运行 minio.yml 剧本。

如果您计划部署生产级大规模多节点 MinIO 集群,我们 强烈 建议您在开始之前阅读 Pigsty MinIO 配置文档 和 MinIO 官方文档


访问集群

您必须通过 HTTPS 访问 MinIO,因此请确保默认的 minio 服务域名(sss.pigsty)指向正确的位置:

  1. 您可以在 node_etc_hosts 中添加静态解析记录或手动修改 /etc/hosts 文件
  2. 如果您正在使用 DNS 服务,可以在内部 DNS 服务器上添加记录
  3. 如果您正在使用基础设施节点上的 DNSMASQ,可以在 dns_records 中添加记录

建议使用第一种方法:静态 DNS 解析记录,以避免 MinIO 在生产环境中对 DNS 的额外依赖。

您必须将 MinIO 服务域名指向 MinIO 服务器节点的 IP 地址和服务端口,或负载均衡器的 IP 地址和服务端口。Pigsty 将使用默认域名 sss.pigsty 和默认端口 9000

例如,如果您使用 haproxy 来暴露 MinIO 服务 像这样,端口可能是 9002


添加别名

要使用 mcli 客户端访问 MinIO 服务器集群,您需要首先配置服务器别名:

mcli alias ls  # 列出 minio 别名(默认是 sss)
mcli alias set sss https://sss.pigsty:9000 minioadmin minioadmin              # root 用户
mcli alias set sss https://sss.pigsty:9002 minioadmin minioadmin              # root 用户,在负载均衡器端口 9002 上

mcli alias set pgbackrest https://sss.pigsty:9000 pgbackrest S3User.Backup    # 使用其他用户

在管理节点的管理用户上有一个预配置的名为 sss 的 MinIO 别名,您可以直接使用它。

关于 MinIO 客户端工具 mcli 的完整功能,请参考文档:MinIO Client


管理用户

您可以使用 mcli 在 MinIO 中管理业务用户,例如,您可以使用命令行创建两个默认业务用户:

mcli admin user list sss     # 列出所有用户
set +o history               # 隐藏 shell 历史
mcli admin user add sss dba S3User.DBA
mcli admin user add sss pgbackrest S3User.Backup
set -o history

管理桶

您可以使用 mcli 管理桶:

mcli ls sss/                         # 列出 'sss' 上的所有桶
mcli mb --ignore-existing sss/hello  # 创建名为 'hello' 的桶
mcli rb --force sss/hello            # 删除 'hello' 桶

管理对象

您可以使用 cli 执行对象 CRUD 操作,例如:

mcli cp /www/pigsty/* sss/infra/     # 将本地仓库内容上传到 infra 桶
mcli cp sss/infra/plugins.tgz /tmp/  # 从 minio 下载文件到本地
mcli ls sss/infra                    # 列出 infra 桶中的所有文件
mcli rm sss/infra/plugins.tgz        # 删除 infra 桶中的文件
mcli cat sss/infra/repo_complete     # 输出文件内容

详细信息请查看 教程:对象管理


使用 rclone

Pigsty 仓库中提供了 rclone,这是一个方便的云对象存储客户端,您可以使用它来访问 MinIO 服务。

yum install rclone; # el 兼容
dnf install rclone; # debian/ubuntu

mkdir -p ~/.config/rclone/;
tee ~/.config/rclone/rclone.conf > /dev/null <<EOF
[sss]
type = s3
access_key_id = minioadmin
secret_access_key = minioadmin
endpoint = sss.pigsty:9000
EOF

rclone ls sss:/

备份仓库

在 Pigsty 中,MinIO 默认用作 pgBackRest 的备份仓库。当您将 pgbackrest_method 修改为 minio 时,PGSQL 模块将自动将备份仓库切换到 MinIO。

pgbackrest_method: local          # pgbackrest 仓库方法:local,minio,[用户定义...]
pgbackrest_repo:                  # pgbackrest 仓库:https://pgbackrest.org/configuration.html#section-repository
  local:                          # 使用本地 posix fs 的默认 pgbackrest 仓库
    path: /pg/backup              # 本地备份目录,默认为 `/pg/backup`
    retention_full_type: count    # 按数量保留完整备份
    retention_full: 2             # 使用本地 fs 仓库时保留 2 个,最多 3 个完整备份
  minio:                          # pgbackrest 可选的 minio 仓库
    type: s3                      # minio 兼容 s3,因此使用 s3
    s3_endpoint: sss.pigsty       # minio 端点域名,默认为 `sss.pigsty`
    s3_region: us-east-1          # minio 区域,默认为 us-east-1,对 minio 无用
    s3_bucket: pgsql              # minio 桶名,默认为 `pgsql`
    s3_key: pgbackrest            # pgbackrest 的 minio 用户访问密钥
    s3_key_secret: S3User.Backup  # pgbackrest 的 minio 用户密钥
    s3_uri_style: path            # 对 minio 使用路径样式 uri 而不是主机样式
    path: /pgbackrest             # minio 备份路径,默认为 `/pgbackrest`
    storage_port: 9000            # minio 端口,默认为 9000
    storage_ca_file: /pg/cert/ca.crt  # minio ca 文件路径,默认为 `/pg/cert/ca.crt`
    bundle: y                     # 将小文件打包成单个文件
    cipher_type: aes-256-cbc      # 为远程备份仓库启用 AES 加密
    cipher_pass: pgBackRest       # AES 加密密码,默认为 'pgBackRest'
    retention_full_type: time     # 在 minio 仓库上按时间保留完整备份
    retention_full: 14            # 保留最近 14 天的完整备份

请注意,如果您通过负载均衡器使用 MinIO,您应该在此处使用相应的域名和端口号。

15.2 - 集群配置

根据需求场景选择合适的 MinIO 部署类型,并对外提供可靠的接入。

在部署 MinIO 之前,你需要在 配置清单 中定义一个 MinIO 集群,MinIO 有三种经典部署模式:

  • 单机单盘:SNSD:单机单盘模式,可以使用任意目录作为数据盘,仅作为开发、测试、演示使用。
  • 单机多盘:SNMD:折中模式,在单台服务器上使用多块磁盘 (>=2),仅当资源极为有限时使用。
  • 多机多盘:MNMD:多机多盘模式,标准生产环境部署,具有最好的可靠性,但需要多台服务器。

通常我们建议使用 SNSD 与 MNMD 这两种模式,前者用于开发测试,后者用于生产部署,SNMD 仅在资源有限(只有一台服务器)的情况下使用。

此外,还可以使用 多池部署 来实现现有 MinIO 集群的扩容,或者直接部署 多套集群

使用多节点 MinIO 集群时,访问任意节点都可以获取服务,因此最佳实践是在 MinIO 集群前使用负载均衡与高可用服务接入机制


核心参数

MinIO 部署中,MINIO_VOLUMES 是一个核心配置参数,用于指定 MinIO 的部署模式。 Pigsty 提供了一些便捷的参数用于自动根据配置清单,生成 MINIO_VOLUMES 与其他配置参数的值,但您也可以直接指定它们。

  • 单机单盘: MINIO_VOLUMES 指向本机上的一个普通目录,默认由 minio_data 指定,默认位置为 /data/minio
  • 单机多盘: MINIO_VOLUMES 指向本机上的序列挂载点,同样是由 minio_data 指定,但需要用特殊语法显式覆盖指定真实挂载点,例如 /data{1...4}
  • 多机多盘: MINIO_VOLUMES 指向多台服务器上的序列挂载点,由以下两部分自动组合生成:
    • 首先要使用 minio_data 指定集群每个成员的磁盘挂载点序列 /data{1...4}
    • 还需要使用 minio_node 指定节点的命名模式 ${minio_cluster}-${minio_seq}.pigsty
  • 多池部署: 您需要显式指定 minio_volumes 参数来分配每个存储池的节点,从而实现集群扩容

单机单盘

SNSD 模式,部署参考教程:MinIO 单机单盘部署

在 Pigsty 中,定义一个单例 MinIO 实例非常简单:

# 1 节点 1 驱动器(默认)
minio: { hosts: { 10.10.10.10: { minio_seq: 1 } }, vars: { minio_cluster: minio } }

单机模式下,唯一必要的参数是 minio_seqminio_cluster,它们会唯一标识每一个 MinIO 实例。

单节点单磁盘模式仅用于开发目的,因此您可以使用一个普通的目录作为数据目录,该目录由参数 minio_data 默认为 /data/minio

在您使用 MinIO 时,强烈建议您通过静态解析的域名记录访问 MinIO,例如,假设 minio_domain 设置的内部服务域名使用了默认的 sss.pigsty, 那么您可以在所有节点上添加一个静态解析,便于其他节点访问此服务。

node_etc_hosts: ["10.10.10.10 sss.pigsty"] # domain name to access minio from all nodes (required)
SNSD 仅适用于开发测试

单节点单盘模式应当仅用于开发、测试、演示目的,因为它无法容忍任何硬件故障,也无法带来多磁盘的性能改善。生产环境请使用 多机多盘 模式。


单机多盘

SNMD 模式,部署参考教程:MinIO 单机多盘部署

要在单节点上使用多块磁盘,所需的操作与 单机单盘 基本一致,但用户需要以 {{ prefix }}{x...y} 的特定格式指定 minio_data,该格式定义了序列磁盘挂载点。

minio:
  hosts: { 10.10.10.10: { minio_seq: 1 } }
  vars:
    minio_cluster: minio         # minio 集群名称,默认为 minio
    minio_data: '/data{1...4}'   # minio 数据目录,使用 {x...y} 记号来指定多块磁盘
请使用真实磁盘挂载点

请注意,SNMD 模式不支持使用普通目录作为数据目录。如果您使用 SNMD 模式拉起 MinIO,但数据目录不是有效的磁盘挂载点,MinIO 将拒绝启动。请确保使用 XFS 格式化的真实磁盘。

例如 Vagrant MinIO 沙箱 定义了一个带有4块磁盘的单节点 MinIO 集群:/data1/data2/data3/data4。启动 MinIO 之前,你需要正确地挂载它们(请务必使用 xfs 格式化磁盘):

mkfs.xfs /dev/vdb; mkdir /data1; mount -t xfs /dev/sdb /data1;   # 挂载第1块盘……
mkfs.xfs /dev/vdc; mkdir /data2; mount -t xfs /dev/sdb /data2;   # 挂载第2块盘……
mkfs.xfs /dev/vdd; mkdir /data3; mount -t xfs /dev/sdb /data3;   # 挂载第3块盘……
mkfs.xfs /dev/vde; mkdir /data4; mount -t xfs /dev/sdb /data4;   # 挂载第4块盘……

挂载磁盘属于服务器置备的部分,超出 Pigsty 的处理范畴。挂载的磁盘应该同时写入 /etc/fstab 以便在服务器重启后可以自动挂载。

/dev/vdb /data1 xfs defaults,noatime,nodiratime 0 0
/dev/vdc /data2 xfs defaults,noatime,nodiratime 0 0
/dev/vdd /data3 xfs defaults,noatime,nodiratime 0 0
/dev/vde /data4 xfs defaults,noatime,nodiratime 0 0

SNMD 模式可以利用单机上的多块磁盘,提供更高的性能和容量,并且容忍部分磁盘故障。 但单节点模式无法容忍整个节点的故障,而且您无法在运行时添加新的节点,因此如果没有特殊原因,我们不建议在生产环境中使用 SNMD 模式。


多机多盘

MNMD 模式,部署参考教程:MinIO 多机多盘部署

除了需要 单机多盘 模式中的 minio_data 指定磁盘驱动器,使用MinIO 多节点部署需要使用一个额外的 minio_node 参数。

例如,以下配置定义了一个 MinIO 集群,其中有四个节点,每个节点有四块磁盘:

minio:
  hosts:
    10.10.10.10: { minio_seq: 1 }  # 实际节点名: minio-1.pigsty
    10.10.10.11: { minio_seq: 2 }  # 实际节点名: minio-2.pigsty
    10.10.10.12: { minio_seq: 3 }  # 实际节点名: minio-3.pigsty
    10.10.10.13: { minio_seq: 4 }  # 实际节点名: minio-4.pigsty
  vars:
    minio_cluster: minio
    minio_data: '/data{1...4}'                         # 每个节点使用四块磁盘
    minio_node: '${minio_cluster}-${minio_seq}.pigsty' # minio 节点名称规则

minio_node 参数指定了 MinIO 节点名称的模式,用于生成每个节点的唯一名称。 默认情况下,节点名称是 ${minio_cluster}-${minio_seq}.pigsty,其中 ${minio_cluster} 是集群名称,${minio_seq} 是节点序号。 MinIO 实例的名称非常重要,会自动写入到 MinIO 节点的 /etc/hosts 中进行静态解析。MinIO 依靠这些名称来识别并访问集群中的其他节点。

在这种情况下,MINIO_VOLUMES 将被设置为 https://minio-{1...4}.pigsty/data{1...4} ,以标识四个节点上的四块盘。 您可以直接在 MinIO 集群中指定 minio_volumes 参数,来覆盖自动根据规则生成的值。 但通常不需要这样做,因为 Pigsty 会自动根据配置清单生成它。


多池部署

MinIO 的架构允许通过添加新的存储池来扩容。在 Pigsty 中,您可以通过显式指定 minio_volumes 参数来分配每个存储池的节点,从而实现集群扩容。

例如,假设您已经创建了 多机多盘 样例中定义的 MinIO 集群,现在您想要添加一个新的存储池,同样由四个节点构成。

那么,你需要直接覆盖指定 minio_volumes 参数:

minio:
  hosts:
    10.10.10.10: { minio_seq: 1 }
    10.10.10.11: { minio_seq: 2 }
    10.10.10.12: { minio_seq: 3 }
    10.10.10.13: { minio_seq: 4 }

    10.10.10.14: { minio_seq: 5 }
    10.10.10.15: { minio_seq: 6 }
    10.10.10.16: { minio_seq: 7 }
    10.10.10.17: { minio_seq: 8 }
  vars:
    minio_cluster: minio
    minio_data: "/data{1...4}"
    minio_node: '${minio_cluster}-${minio_seq}.pigsty' # minio 节点名称规则
    minio_volumes: 'https://minio-{1...4}.pigsty:9000/data{1...4} https://minio-{5...8}.pigsty:9000/data{1...4}'

在这里,空格分割的两个参数分别代表两个存储池,每个存储池有四个节点,每个节点有四块磁盘。更多关于存储池的信息请参考 管理预案:MinIO集群扩容


多套集群

您可以将新的 MinIO 节点部署为一个全新的 MinIO 集群,使用不同的集群名称定义一个新的分组即可,以下配置声明了两个独立的 MinIO 集群:

minio1:
  hosts:
    10.10.10.10: { minio_seq: 1 }
    10.10.10.11: { minio_seq: 2 }
    10.10.10.12: { minio_seq: 3 }
    10.10.10.13: { minio_seq: 4 }
  vars:
    minio_cluster: minio2
    minio_data: "/data{1...4}"

minio2:
  hosts:
    10.10.10.14: { minio_seq: 5 }
    10.10.10.15: { minio_seq: 6 }
    10.10.10.16: { minio_seq: 7 }
    10.10.10.17: { minio_seq: 8 }
  vars:
    minio_cluster: minio2
    minio_data: "/data{1...4}"
    minio_alias: sss2
    minio_domain: sss2.pigsty
    minio_endpoint: sss2.pigsty:9000

请注意,Pigsty 默认一套部署中只有一个 MinIO 集群,如果您需要部署多个 MinIO 集群,那么一些带有默认值的参数需要显式设置,无法省略,否则会出现命名冲突,如上所示。


服务接入

MinIO 默认使用 9000 端口提供服务。多节点 MinIO 集群可以通过访问 任意一个节点 来访问其服务。

服务接入属于 NODE 模块的功能范畴,这里仅做基本介绍。

多节点 MinIO 集群的高可用接入可以使用 L2 VIP 或 HAProxy 实现。例如,您可以选择使用 keepalived 在 MinIO 集群上绑定一个 L2 VIP, 或者使用由 NODE 模块的提供的 haproxy 组件,通过负载均衡器对外暴露 MinIO 服务。

# minio cluster with 4 nodes and 4 drivers per node
minio:
  hosts:
    10.10.10.10: { minio_seq: 1 , nodename: minio-1 }
    10.10.10.11: { minio_seq: 2 , nodename: minio-2 }
    10.10.10.12: { minio_seq: 3 , nodename: minio-3 }
    10.10.10.13: { minio_seq: 4 , nodename: minio-4 }
  vars:
    minio_cluster: minio
    minio_data: '/data{1...4}'
    minio_buckets: [ { name: pgsql }, { name: infra }, { name: redis } ]
    minio_users:
      - { access_key: dba , secret_key: S3User.DBA, policy: consoleAdmin }
      - { access_key: pgbackrest , secret_key: S3User.SomeNewPassWord , policy: readwrite }

    # bind a node l2 vip (10.10.10.9) to minio cluster (optional)
    node_cluster: minio
    vip_enabled: true
    vip_vrid: 128
    vip_address: 10.10.10.9
    vip_interface: eth1

    # expose minio service with haproxy on all nodes
    haproxy_services:
      - name: minio                    # [REQUIRED] service name, unique
        port: 9002                     # [REQUIRED] service port, unique
        balance: leastconn             # [OPTIONAL] load balancer algorithm
        options:                       # [OPTIONAL] minio health check
          - option httpchk
          - option http-keep-alive
          - http-check send meth OPTIONS uri /minio/health/live
          - http-check expect status 200
        servers:
          - { name: minio-1 ,ip: 10.10.10.10 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
          - { name: minio-2 ,ip: 10.10.10.11 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
          - { name: minio-3 ,ip: 10.10.10.12 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
          - { name: minio-4 ,ip: 10.10.10.13 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }

例如,上面的配置块为 MinIO 集群的所有节点上启用了 HAProxy ,在 9002 端口上暴露 MinIO 服务,同时为集群绑定了一个二层 VIP。 当使用时,用户应当将 sss.pigsty 域名解析指向 VIP 地址 10.10.10.9,并使用 9002 端口访问 MinIO 服务。这样当任意一个节点发生故障时,VIP 会自动切换到另一个节点,保证服务的高可用性。

在这种情况下,您通常还需要在全局修改域名解析的目的地,以及 minio_endpoint 参数,修改写入管理节点 MinIO Alias 对应的端点地址:

minio_endpoint: https://sss.pigsty:9002   # 覆盖默认值: https://sss.pigsty:9000
node_etc_hosts: ["10.10.10.9 sss.pigsty"] # 其他节点将使用 sss.pigsty 域名来访问 MinIO

专用负载均衡

Pigsty 允许用户使用专用的负载均衡服务器组,而不是集群本身来运行 VIP 与 HAProxy。例如 prod 模板中就使用了这种方式。

proxy:
  hosts:
    10.10.10.18 : { nodename: proxy1 ,node_cluster: proxy ,vip_interface: eth1 ,vip_role: master }
    10.10.10.19 : { nodename: proxy2 ,node_cluster: proxy ,vip_interface: eth1 ,vip_role: backup }
  vars:
    vip_enabled: true
    vip_address: 10.10.10.20
    vip_vrid: 20

    haproxy_services:      # expose minio service : sss.pigsty:9000
      - name: minio        # [REQUIRED] service name, unique
        port: 9000         # [REQUIRED] service port, unique
        balance: leastconn # Use leastconn algorithm and minio health check
        options: [ "option httpchk", "option http-keep-alive", "http-check send meth OPTIONS uri /minio/health/live", "http-check expect status 200" ]
        servers:           # reload service with ./node.yml -t haproxy_config,haproxy_reload
          - { name: minio-1 ,ip: 10.10.10.21 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
          - { name: minio-2 ,ip: 10.10.10.22 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
          - { name: minio-3 ,ip: 10.10.10.23 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
          - { name: minio-4 ,ip: 10.10.10.24 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
          - { name: minio-5 ,ip: 10.10.10.25 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }

在这种情况下,您通常还需要在全局修改 MinIO 域名的解析,将 sss.pigsty 指向负载均衡器的地址,并修改 minio_endpoint 参数,修改写入管理节点 MinIO Alias 对应的端点地址:

minio_endpoint: https://sss.pigsty:9002    # overwrite the defaults: https://sss.pigsty:9000
node_etc_hosts: ["10.10.10.20 sss.pigsty"] # domain name to access minio from all nodes (required)

访问服务

如果您想要访问上面通过 HAProxy 暴露的 MinIO,以 PGSQL 备份配置为例,可以修改 pgbackrest_repo 中的配置,添加新的备份仓库定义:

# 这是新添加的 HA MinIO Repo 定义,使用此配置代替之前的单机 MinIO 配置
minio_ha:
  type: s3
  s3_endpoint: minio-1.pigsty   # s3_endpoint 可以是任何一个负载均衡器:10.10.10.1{0,1,2},或指向任意 3 个节点的域名
  s3_region: us-east-1          # 你可以使用外部域名:sss.pigsty,该域名指向任一成员(`minio_domain`)
  s3_bucket: pgsql              # 你可使用实例名和节点名:minio-1.pigsty minio-1.pigsty minio-1.pigsty minio-1 minio-2 minio-3
  s3_key: pgbackrest            # 最好为 MinIO 的 pgbackrest 用户使用专门的密码
  s3_key_secret: S3User.SomeNewPassWord
  s3_uri_style: path
  path: /pgbackrest
  storage_port: 9002            # 使用负载均衡器的端口 9002 代替默认的 9000(直接访问)
  storage_ca_file: /etc/pki/ca.crt
  bundle: y
  cipher_type: aes-256-cbc      # 在您的生产环境中最好使用新的加密密码,这里可以使用集群名作为密码的一部分。
  cipher_pass: pgBackRest.With.Some.Extra.PassWord.And.Salt.${pg_cluster}
  retention_full_type: time
  retention_full: 14

暴露管控

MinIO 默认通过 9001 端口(由 minio_admin_port 参数指定)提供Web管控界面。

将后台管理界面暴露给外部可能存在安全隐患。如果你希望这样做,请将 MinIO 添加到 infra_portal 并刷新 Nginx 配置。

# ./infra.yml -t nginx
infra_portal:
  home         : { domain: h.pigsty }
  grafana      : { domain: g.pigsty ,endpoint: "${admin_ip}:3000" , websocket: true }
  prometheus   : { domain: p.pigsty ,endpoint: "${admin_ip}:9090" }
  alertmanager : { domain: a.pigsty ,endpoint: "${admin_ip}:9093" }
  blackbox     : { endpoint: "${admin_ip}:9115" }
  loki         : { endpoint: "${admin_ip}:3100" }

  # MinIO 管理页面需要 HTTPS / Websocket 才能工作
  minio        : { domain: m.pigsty     ,endpoint: "10.10.10.10:9001" ,scheme: https ,websocket: true }
  minio10      : { domain: m10.pigsty   ,endpoint: "10.10.10.10:9001" ,scheme: https ,websocket: true }
  minio11      : { domain: m11.pigsty   ,endpoint: "10.10.10.11:9001" ,scheme: https ,websocket: true }
  minio12      : { domain: m12.pigsty   ,endpoint: "10.10.10.12:9001" ,scheme: https ,websocket: true }
  minio13      : { domain: m13.pigsty   ,endpoint: "10.10.10.13:9001" ,scheme: https ,websocket: true }

请注意,MinIO 管控页面需要使用 HTTPS,请 不要 在生产环境中暴露未加密的 MinIO 管控页面。

这意味着,您通常需要在您的 DNS 服务器,或者本机 /etc/hosts 中添加 m.pigsty 的解析记录,以便访问 MinIO 管控页面。

与此同时,如果您使用的是 Pigsty 自签名的 CA 而不是一个正规的公共 CA ,通常您还需要手工信任该 CA 或证书,才能跳过浏览器中的 “不安全” 提示信息。

15.3 - 参数

自定义 MinIO 参数

MinIO 是一个兼容 S3 的对象存储服务。它被用作 PostgreSQL 的可选中央备份存储仓库。

您也可以将其用于其他目的,例如存储大文件、文档、图片和视频。


参数

MinIO 模块记录 21 项设置:16 个 MINIO 参数、2 个可覆盖的派生值,以及 3 个 MINIO_REMOVE 参数。

参数 类型 层级 注释
minio_seq int I minio 实例标识符,必需
minio_cluster string C minio 集群名称,默认为 minio
minio_user username C minio 操作系统用户,默认为 minio
minio_https bool G 为 minio 使用 https,默认为 true
minio_node string C minio 节点名称模式
minio_data path C minio 数据目录,使用 {x...y} 指定多个驱动器
minio_volumes string C minio 核心参数,指定节点和磁盘,默认自动生成
minio_domain string G minio 外部域名,默认为 sss.pigsty
minio_port port C minio 服务端口,默认为 9000
minio_admin_port port C minio 控制台端口,默认为 9001
minio_access_key username C root 访问密钥,默认为 minioadmin
minio_secret_key password C root 密钥,默认为 minioadmin
minio_extra_vars string C minio 服务器的额外环境变量
minio_provision bool G/C 运行 minio 置备任务?
minio_alias string G 本地 minio 部署的别名
minio_endpoint string C 上述 minio 别名对应的 host:port
minio_buckets bucket[] C 要创建的 minio 桶列表
minio_users user[] C 要创建的 minio 用户列表
参数 类型 层级 注释
minio_safeguard bool G/C/A 防止意外移除?(默认:false)
minio_rm_data bool G/C/A 移除期间删除 minio 数据?(默认:true)
minio_rm_pkg bool G/C/A 移除期间卸载 minio 包?(默认:false)

minio_volumesminio_endpoint 是自动生成的参数,但您可以显式覆盖这两个参数。


默认值

MINIO 共有 18 项设置(含 2 个派生值),定义于 roles/minio/defaults/main.yml

#-----------------------------------------------------------------
# MINIO
#-----------------------------------------------------------------
#minio_seq: 1                     # minio 实例标识符,必需
minio_cluster: minio              # minio 集群标识符,必需
minio_user: minio                 # minio 操作系统用户,默认为 `minio`
minio_https: true                 # 为 minio 使用 https,默认为 true
minio_node: '${minio_cluster}-${minio_seq}.pigsty' # minio 节点名称模式
minio_data: '/data/minio'         # minio 数据目录,使用 {x...y} 指定多个驱动器
#minio_volumes:                   # minio 数据卷,如果指定则覆盖默认值
minio_domain: sss.pigsty          # minio 外部域名,默认为 `sss.pigsty`
minio_port: 9000                  # minio 服务端口,默认为 9000
minio_admin_port: 9001            # minio 控制台端口,默认为 9001
minio_access_key: minioadmin      # root 访问密钥,默认为 `minioadmin`
minio_secret_key: minioadmin      # root 密钥,默认为 `minioadmin`
minio_extra_vars: ''              # 额外环境变量
minio_provision: true             # 运行 minio 置备任务?
minio_alias: sss                  # 本地 minio 部署的别名
#minio_endpoint: https://sss.pigsty:9000 # 如果未指定,由默认值覆盖
minio_buckets:                    # 要创建的 minio 桶列表
  - { name: pgsql }
  - { name: meta ,versioning: true }
  - { name: data }
minio_users:                      # 要创建的 minio 用户列表
  - { access_key: pgbackrest  ,secret_key: S3User.Backup ,policy: pgsql }
  - { access_key: s3user_meta ,secret_key: S3User.Meta   ,policy: meta  }
  - { access_key: s3user_data ,secret_key: S3User.Data   ,policy: data  }

MINIO_REMOVE 共有 3 个参数,定义于 roles/minio_remove/defaults/main.yml 中:

#-----------------------------------------------------------------
# MINIO_REMOVE
#-----------------------------------------------------------------
minio_safeguard: false            # 防止意外移除?
minio_rm_data: true               # 移除期间删除 minio 数据?
minio_rm_pkg: false               # 移除期间卸载 minio 包?

minio_seq

名称:minio_seq,类型:int,层级:I

minio 实例标识符,必需的身份参数。没有默认值,您必须手动分配它


minio_cluster

名称:minio_cluster,类型:string,层级:C

minio 集群名称,默认为 minio。这在部署多个 MinIO 集群时很有用


minio_user

名称:minio_user,类型:username,层级:C

minio 操作系统用户名,默认为 minio


minio_https

名称:minio_https,类型:bool,层级:G

为 MinIO 服务使用 HTTPS 还是 HTTP,默认为 true,表示使用 HTTPS。

请注意,pgbackrest 需要 MinIO HTTPS 才能正常工作,但如果您不将 minio 用于此目的,并且不想为 MinIO 使用 HTTPS,您可以将其设置为 false


minio_node

名称:minio_node,类型:string,层级:C

minio 节点名称模式,这用于 多节点 部署

默认值:${minio_cluster}-${minio_seq}.pigsty


minio_data

名称:minio_data,类型:path,层级:C

minio 数据目录

默认值:/data/minio,这是 单节点 部署的通用目录。

对于 多驱动器 部署,您可以使用 {x...y} 概念来指定多个驱动器。


minio_volumes

名称:minio_volumes,类型:string,层级:C

MinIO 的唯一核心参数,如果未指定,将按以下规则自动生成:

minio_volumes: "{% if minio_cluster_size|int > 1 %}https://{{ minio_node|replace('${minio_cluster}', minio_cluster)|replace('${minio_seq}',minio_seq_range) }}:{{ minio_port|default(9000) }}{% endif %}{{ minio_data }}"
  • SNSDSNMD 部署的情况下,minio_volumes 直接使用 minio_data 的值
  • MNMD 部署的情况下,minio_volumes 使用 minio_nodeminio_portminio_data 的值来生成此参数:
  • 在多个存储池的情况下,您必须覆盖 minio_volumes 来显式指定多个节点池。

用户有责任确保 minio_volumes 中使用的参数与 minio_nodeminio_portminio_data 一致。


minio_domain

名称:minio_domain,类型:string,层级:G

minio 服务域名,默认为 sss.pigsty

客户端可以通过此域名访问 minio S3 服务。此名称将注册到本地 DNSMASQ 并包含在 SSL 证书中。


minio_port

名称:minio_port,类型:port,层级:C

minio 服务端口,默认为 9000


minio_admin_port

名称:minio_admin_port,类型:port,层级:C

minio 控制台端口,默认为 9001


minio_access_key

名称:minio_access_key,类型:username,层级:C

root 访问密钥,默认为 minioadmin


minio_secret_key

名称:minio_secret_key,类型:password,层级:C

root 密钥,默认为 minioadmin

默认值:minioadmin

更改密码!

在您的部署中更改此密码非常重要!


minio_extra_vars

名称:minio_extra_vars,类型:string,层级:C

minio 服务器的额外环境变量。查看 Minio Server 获取完整列表。

默认值为空字符串,您可以使用多行字符串传递多个环境变量。


minio_alias

名称:minio_alias,类型:string,层级:G

本地 MinIO 集群的 MinIO 别名

默认值:sss,将写入基础设施节点/管理用户的客户端别名配置文件。


minio_endpoint

名称:minio_endpoint,类型:string,层级:C

上述 MinIO 别名对应的 host:port。此参数默认未定义。

如果未定义,将被以下默认值覆盖:

mcli alias set {{ minio_alias }} {% if minio_endpoint is defined and minio_endpoint != '' %}{{ minio_endpoint }}{% else %}https://{{ minio_domain }}:{{ minio_port }}{% endif %} {{ minio_access_key }} {{ minio_secret_key }}

此别名和端点将添加到管理节点上的管理用户。


minio_buckets

名称:minio_buckets,类型:bucket[],层级:C

默认要创建的 minio 桶列表:

minio_buckets:                    # 要创建的 minio 桶列表
  - { name: pgsql }
  - { name: meta ,versioning: true }
  - { name: data }

默认创建三个桶,具有不同的策略。

pgsql 桶默认用于 PostgreSQL 备份。而 metadata 是用于其他目的的开放桶。 例如,supabase 模板可能使用 data 桶来存储业务数据。

如果您有需要版本控制的重要元数据,可以开箱即用地使用 meta 桶。

每个桶都有相应的策略,名称与桶名相同。例如,pgsql 策略对 pgsql 桶有所有权限,等等。

您还可以在桶定义中添加 lock 标志,这将启用对象锁定功能,以防止意外删除桶中的对象。


minio_users

名称:minio_users,类型:user[],层级:C

要创建的 minio 用户列表,默认值:

minio_users:                      # 要创建的 minio 用户列表
  - { access_key: pgbackrest  ,secret_key: S3User.Backup ,policy: pgsql }
  - { access_key: s3user_meta ,secret_key: S3User.Meta   ,policy: meta  }
  - { access_key: s3user_data ,secret_key: S3User.Data   ,policy: data  }

为 PostgreSQL DBA 和 pgBackREST 创建默认用户。

更改密码!

请在严肃的生产部署中更改这些密码。


minio_safeguard

名称:minio_safeguard,类型:bool,层级:G/C/A

防止意外移除?默认值为 false

如果启用,minio-rm.yml 剧本将中止并拒绝移除 MinIO 集群,提供防止意外删除的保护。


minio_rm_data

名称:minio_rm_data,类型:bool,层级:G/C/A

移除期间删除 minio 数据?默认值为 true

启用时,minio-rm.yml 剧本将在集群移除期间删除 MinIO 数据目录和配置文件。


minio_rm_pkg

名称:minio_rm_pkg,类型:bool,层级:G/C/A

移除期间卸载 minio 包?默认值为 false

启用时,minio-rm.yml 剧本将在集群移除期间卸载 MinIO 包。默认禁用此功能,以保留 MinIO 安装以供将来可能使用。

15.4 - 管理

创建、移除、扩展、收缩、升级 minio 集群

以下是 MinIO 的一些管理标准操作程序:

查看 MINIO: FAQ 了解更多问题。


创建集群

要创建 MinIO 集群,首先在 清单 中定义 minio 集群:

minio: { hosts: { 10.10.10.10: { minio_seq: 1 } }, vars: { minio_cluster: minio } }

minio_cluster 参数将此集群标记为 MinIO 集群,minio_seq 是 MinIO 节点的序列号,用于生成 MinIO 节点名称如 minio-1minio-2 等。

此代码片段定义了一个单节点 MinIO 集群,使用以下命令创建 MinIO 集群:

./minio.yml -l minio  # 在 minio 组上初始化 MinIO 模块

移除集群

要销毁现有的 MinIO 集群,使用专用的 minio-rm.yml 剧本:

./minio-rm.yml -l minio                                  # 移除 MinIO 集群

您也可以使用参数自定义移除过程:

./minio-rm.yml -l minio -e minio_rm_pkg=true            # 同时移除包
./minio-rm.yml -l minio -e minio_rm_data=false          # 保留数据目录
./minio-rm.yml -l minio -e minio_safeguard=true         # 启用安全防护(将中止)

传统方法(已弃用):

架构变更:Pigsty v3.6+

自 Pigsty v3.6+ 起,MinIO 集群移除已移至使用 minio_remove 角色的专用 minio-rm.yml 剧本。移除过程中会自动清理 prometheus 监控目标。


扩展集群

您无法在节点/磁盘级别扩展 MinIO,但可以在存储池(多个节点)级别扩展。

假设您有一个 4 节点的 MinIO 集群,想通过添加另一个四节点存储池来将容量翻倍。

minio:
  hosts:
    10.10.10.10: { minio_seq: 1 , nodename: minio-1 }
    10.10.10.11: { minio_seq: 2 , nodename: minio-2 }
    10.10.10.12: { minio_seq: 3 , nodename: minio-3 }
    10.10.10.13: { minio_seq: 4 , nodename: minio-4 }
  vars:
    minio_cluster: minio
    minio_data: '/data{1...4}'
    minio_buckets: [ { name: pgsql }, { name: infra }, { name: redis } ]
    minio_users:
      - { access_key: dba , secret_key: S3User.DBA, policy: consoleAdmin }
      - { access_key: pgbackrest , secret_key: S3User.SomeNewPassWord , policy: readwrite }

    # 绑定节点 l2 vip (10.10.10.9) 到 minio 集群(可选)
    node_cluster: minio
    vip_enabled: true
    vip_vrid: 128
    vip_address: 10.10.10.9
    vip_interface: eth1

    # 在所有节点上使用 haproxy 暴露 minio 服务
    haproxy_services:
      - name: minio                    # [必需] 服务名称,唯一
        port: 9002                     # [必需] 服务端口,唯一
        balance: leastconn             # [可选] 负载均衡算法
        options:                       # [可选] minio 健康检查
          - option httpchk
          - option http-keep-alive
          - http-check send meth OPTIONS uri /docs/minio/health/live
          - http-check expect status 200
        servers:
          - { name: minio-1 ,ip: 10.10.10.10 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
          - { name: minio-2 ,ip: 10.10.10.11 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
          - { name: minio-3 ,ip: 10.10.10.12 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
          - { name: minio-4 ,ip: 10.10.10.13 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }

步骤 1,在组中添加 4 个节点定义,分配序列号 5 到 8。 关键步骤是修改 minio_volumes 参数,将新的 4 个节点分配到新的 存储池

minio:
  hosts:
    10.10.10.10: { minio_seq: 1 , nodename: minio-1 }
    10.10.10.11: { minio_seq: 2 , nodename: minio-2 }
    10.10.10.12: { minio_seq: 3 , nodename: minio-3 }
    10.10.10.13: { minio_seq: 4 , nodename: minio-4 }
    # 新节点
    10.10.10.14: { minio_seq: 5 , nodename: minio-5 }
    10.10.10.15: { minio_seq: 6 , nodename: minio-6 }
    10.10.10.16: { minio_seq: 7 , nodename: minio-7 }
    10.10.10.17: { minio_seq: 8 , nodename: minio-8 }

  vars:
    minio_cluster: minio
    minio_data: '/data{1...4}'
    minio_volumes: 'https://minio-{1...4}.pigsty:9000/data{1...4} https://minio-{5...8}.pigsty:9000/data{1...4}'  # 新增的集群配置
    # 其他参数

步骤 2,将这些节点添加到 Pigsty:

./node.yml -l 10.10.10.14,10.10.10.15,10.10.10.16,10.10.10.17

步骤 3,使用 minio_install 子任务在新节点上置备 MinIO(用户、目录、包等):

./minio.yml -l 10.10.10.14,10.10.10.15,10.10.10.16,10.10.10.17 -t minio_install

步骤 4:使用 minio_config 子任务在 整个集群 上重新配置整个 MinIO 集群

./minio.yml -l minio -t minio_config

也就是说,现有 4 个节点的 MINIO_VOLUMES 配置也会被更新

步骤 5:同时重启整个 MinIO 集群(注意,不要滚动重启!):

./minio.yml -l minio -t minio_launch -f 10   # 并行度为 10

步骤 6:这是 可选的,如果您使用负载均衡器,请确保负载均衡器配置已更新。

例如,将新的四个节点添加到负载均衡器配置:

# 在所有节点上使用 haproxy 暴露 minio 服务
haproxy_services:
  - name: minio                    # [必需] 服务名称,唯一
    port: 9002                     # [必需] 服务端口,唯一
    balance: leastconn             # [可选] 负载均衡算法
    options:                       # [可选] minio 健康检查
      - option httpchk
      - option http-keep-alive
      - http-check send meth OPTIONS uri /docs/minio/health/live
      - http-check expect status 200
    servers:
      - { name: minio-1 ,ip: 10.10.10.10 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
      - { name: minio-2 ,ip: 10.10.10.11 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
      - { name: minio-3 ,ip: 10.10.10.12 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
      - { name: minio-4 ,ip: 10.10.10.13 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }

      - { name: minio-5 ,ip: 10.10.10.14 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
      - { name: minio-6 ,ip: 10.10.10.15 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
      - { name: minio-7 ,ip: 10.10.10.16 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
      - { name: minio-8 ,ip: 10.10.10.17 ,port: 9000 ,options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }

然后运行 node.yml 剧本的 haproxy 子任务来更新负载均衡器配置:

./node.yml -l minio -t haproxy_config,haproxy_reload   # 重新配置并重新加载 haproxy 服务定义

如果节点 L2 VIP 也用于确保可靠的负载均衡器访问,您还需要将新节点(如果有)添加到现有的 NODE VIP 组:

./node.yml -l minio -t node_vip  # 重新加载节点 l2 vip 配置

收缩集群

MinIO 无法在节点/磁盘级别缩减,但您可以在存储池(多个节点)级别退役——添加新存储池,排空旧存储池,迁移到新存储池,然后退役旧存储池。


升级集群

首先,将新版本的 MinIO 软件包下载到 INFRA 节点的本地软件仓库:

然后重建软件仓库:

./infra.yml -t repo_create

您可以使用 Ansible package 模块升级所有 MinIO 软件包:

ansible minio -m package -b -a 'name=minio state=latest'  # 升级 MinIO 服务器
ansible minio -m package -b -a 'name=mcli state=latest'   # 升级 mcli 客户端

最后,通知 MinIO 集群使用 mc 命令行工具重启:

mc admin service restart sss

节点故障恢复

# 1. 移除故障节点
bin/node-rm <your_old_node_ip>

# 2. 用相同名称替换故障节点(如果 IP 发生变化,修改清单)
bin/node-add <your_new_node_ip>

# 3. 在新节点上置备 MinIO
./minio.yml -l <your_new_node_ip>

# 4. 指示 MinIO 执行修复操作
mc admin heal

磁盘故障恢复

# 1. 卸载故障磁盘
umount /dev/<your_disk_device>

# 2. 更换新驱动器,使用 xfs 格式化
mkfs.xfs /dev/sdb -L DRIVE1

# 3. 不要忘记为自动挂载设置 fstab
vi /etc/fstab
# LABEL=DRIVE1     /mnt/drive1    xfs     defaults,noatime  0       2

# 4. 重新挂载新磁盘
mount -a

# 5. 指示 MinIO 执行修复操作
mc admin heal

15.5 - 剧本

控制原语

您必须在运行剧本之前在 配置清单配置 minio 集群。


剧本

有两个内置的 MinIO 集群管理剧本:

minio.yml

minio.yml

  • minio-id : 生成 minio 身份
  • minio_install : 安装 minio/mcli
    • minio_os_user : 创建操作系统用户 minio
    • minio_pkg : 安装 minio/mcli 包
    • minio_dir : 创建 minio 目录
  • minio_config : 生成 minio 配置
    • minio_conf : minio 主配置
    • minio_cert : minio ssl 证书
    • minio_dns : 写入 minio dns 记录
  • minio_launch : 启动 minio 服务
  • minio_register : 将 minio 注册到 prometheus
  • minio_provision : 创建 minio 别名/桶/用户
    • minio_alias : 创建 minio 客户端别名
    • minio_bucket : 创建 minio 桶
    • minio_user : 创建 minio 业务用户
架构变更:Pigsty v3.6+

自 Pigsty v3.6+ 起,minio.yml 剧本和 minio 角色专注于集群安装。所有移除操作已移至专用的 minio-rm.yml 剧本,使用 minio_remove 角色。

您应该在 Pigsty 管理的节点上安装 MINIO 模块(即,首先安装 NODE)。

受信任的 ca 文件:/etc/pki/ca.crt 应该已经存在于所有节点上。它在 role: ca 中生成,并在 role: node 中默认加载和信任。


minio-rm.yml

移除 MinIO 集群,运行以下剧本:

./minio-rm.yml    # 移除 MinIO 集群

以下是可用的子任务:

  • minio_id : 为移除操作生成 minio 身份
  • prometheus : 从 prometheus 移除 minio 目标注册
  • minio_stop : 使用 systemd 停止并禁用 minio 服务
  • minio_data : 移除 minio 数据(使用 minio_rm_data=false 禁用)
  • minio_pkg : 卸载 minio 包(使用 minio_rm_pkg=true 启用)

移除剧本使用新的 minio_remove 角色,带有可配置参数:


命令

MINIO 剧本备忘单和常用命令

./minio.yml -l <cls>                      # 在组 <cls> 上初始化 MINIO 模块
./minio-rm.yml -l minio                   # 使用专用移除剧本移除 MinIO 集群
./minio.yml -l minio -t minio_install     # 安装 MinIO,设置目录,不进行配置和启动
./minio.yml -l minio -t minio_config      # 生成 MinIO 配置和证书
./minio.yml -l minio -t minio_launch      # 重启 MinIO 集群

15.6 - 监控

监控 MinIO 集群

仪表板

MINIO 模块提供一个仪表板。

MinIO Overview:单个 MinIO 集群的概览


告警规则

为 MinIO 预定义了 3 个告警规则,定义在 files/prometheus/rules/minio.yml 中:

  • MinioServerDown
  • MinioNodeOffline
  • MinioDiskOffline
#==============================================================#
#                         Aliveness                            #
#==============================================================#
# MinIO server instance down
- alert: MinioServerDown
  expr: minio_up < 1
  for: 1m
  labels: { level: 0, severity: CRIT, category: minio }
  annotations:
    summary: "CRIT MinioServerDown {{ $labels.ins }}@{{ $labels.instance }}"
    description: |
      minio_up[ins={{ $labels.ins }}, instance={{ $labels.instance }}] = {{ $value }} < 1
      http://g.pigsty/d/minio-overview

#==============================================================#
#                         Error                                #
#==============================================================#
# MinIO node offline triggers a p1 alert
- alert: MinioNodeOffline
  expr: avg_over_time(minio_cluster_nodes_offline_total{job="minio"}[5m]) > 0
  for: 3m
  labels: { level: 1, severity: WARN, category: minio }
  annotations:
    summary: "WARN MinioNodeOffline: {{ $labels.cls }} {{ $value }}"
    description: |
      minio_cluster_nodes_offline_total[cls={{ $labels.cls }}] = {{ $value }} > 0
      http://g.pigsty/d/minio-overview?from=now-5m&to=now&var-cls={{$labels.cls}}

# MinIO disk offline triggers a p1 alert
- alert: MinioDiskOffline
  expr: avg_over_time(minio_cluster_disk_offline_total{job="minio"}[5m]) > 0
  for: 3m
  labels: { level: 1, severity: WARN, category: minio }
  annotations:
    summary: "WARN MinioDiskOffline: {{ $labels.cls }} {{ $value }}"
    description: |
      minio_cluster_disk_offline_total[cls={{ $labels.cls }}] = {{ $value }} > 0
      http://g.pigsty/d/minio-overview?from=now-5m&to=now&var-cls={{$labels.cls}}

15.7 - FAQ

常见问题解答

无法启动多节点/多驱动器 MinIO 集群。

多驱动器多节点 模式下,如果数据目录不是有效的挂载点,MinIO 将拒绝启动。

为 MinIO 数据目录使用挂载的磁盘而不是普通目录。您只能在 单节点单驱动器 模式下使用普通目录。


如何部署多节点多驱动器 MinIO 集群?

查看 创建多节点多驱动器 MinIO 集群


如何向现有 MinIO 集群添加成员?

您最好在部署前规划 MinIO 集群…因为这需要全局重启

查看这个:扩展 MinIO 部署


如何为 PGSQL 使用 HA MinIO 部署?

使用可选的负载均衡器和不同端口访问 HA MinIO 集群。

这是一个示例:访问 MinIO 服务

16 - Redis

开源内存数据结构存储
配置
    配置 PostgreSQL 集群
参数
    使用 21 个参数自定义 redis 组件
管理
    创建、移除、扩展 redis 集群
剧本
    可在此模块中使用的 Ansible 剧本
监控
    仪表板、指标、记录和告警规则。
常见问题
    关于 redis 模块的常见问题

16.1 - 配置

描述您想要的 redis 集群

Redis 的实体模型与 PostgreSQL 几乎相同, 也包括集群实例的概念。这里的集群不是指原生 Redis 集群模式。

REDIS 模块与 PGSQL 模块的核心区别是 Redis 使用单节点多实例部署而不是 1:1 部署: 通常在一个物理/虚拟机节点上部署多个 Redis 实例以充分利用多核 CPU。 因此,配置管理 Redis 实例的方式与 PGSQL 略有不同。

在 Pigsty 管理的 Redis 中,节点完全从属于集群,这意味着目前 不允许在一个节点上部署两个不同集群的 Redis 实例。 但是,这不影响在一个节点上部署多个独立的 Redis 主副本实例。


Redis 身份

Redis 身份参数 是定义 Redis 集群时的必需参数。

名称 属性 描述 示例
redis_cluster 必需,集群级别 集群名称 redis-test
redis_node 必需,节点级别 节点序列号 1,2
redis_instances 必需,节点级别 实例定义 { 6001 : {} ,6002 : {}}

Redis 模式

Pigsty 中有三种可用的 redis_mode

  • standalone:以独立(主从)模式设置 Redis
  • cluster:将此 Redis 集群设置为 Redis 原生集群
  • sentinel:将 Redis 设置为独立 Redis HA 的哨兵

以下是三个示例:

  • 1 节点,一个主节点和一个从节点的 Redis 独立集群:redis-ms
  • 1 节点,3 实例的 Redis 哨兵集群:redis-sentinel
  • 2 节点,6 实例的 Redis 集群:redis-cluster
redis-ms: # redis classic primary & replica
  hosts: { 10.10.10.10: { redis_node: 1 , redis_instances: { 6379: { }, 6380: { replica_of: '10.10.10.10 6379' } } } }
  vars: { redis_cluster: redis-ms ,redis_password: 'redis.ms' ,redis_max_memory: 64MB }

redis-meta: # redis sentinel x 3
  hosts: { 10.10.10.11: { redis_node: 1 , redis_instances: { 26379: { } ,26380: { } ,26381: { } } } }
  vars:
    redis_cluster: redis-meta
    redis_password: 'redis.meta'
    redis_mode: sentinel
    redis_max_memory: 16MB
    redis_sentinel_monitor: # primary list for redis sentinel, use cls as name, primary ip:port
      - { name: redis-ms, host: 10.10.10.10, port: 6379 ,password: redis.ms, quorum: 2 }

redis-test: # redis native cluster: 3m x 3s
  hosts:
    10.10.10.12: { redis_node: 1 ,redis_instances: { 6379: { } ,6380: { } ,6381: { } } }
    10.10.10.13: { redis_node: 2 ,redis_instances: { 6379: { } ,6380: { } ,6381: { } } }
  vars: { redis_cluster: redis-test ,redis_password: 'redis.test' ,redis_mode: cluster, redis_max_memory: 32MB }

限制

  • 一个 Redis 节点只能属于一个 Redis 集群,这意味着您不能同时将一个节点分配给两个不同的 Redis 集群。
  • 在每个 Redis 节点上,您需要为 Redis 实例分配唯一的端口号以避免端口冲突。
  • 通常,同一个 Redis 集群将使用相同的密码,但 Redis 节点上的多个 Redis 实例不能设置不同的密码(因为 redis_exporter 只允许一个密码)。
  • Redis 集群具有内置 HA,而独立 HA 需要在哨兵中手动配置,因为我们不确定您是否有可用的哨兵。 幸运的是,配置独立 Redis HA 很简单:使用哨兵配置 HA

16.2 - 参数

使用 21 个参数定制 redis

redis 模块中有 21 个参数。

参数 类型 级别 注释
redis_cluster string C redis 集群名称,必需的身份参数
redis_instances dict I 此 redis 节点上的 redis 实例定义
redis_node int I redis 节点序列号,必需的节点整数 ID
redis_fs_main path C redis 主数据挂载点,默认为 /data
redis_exporter_enabled bool C 在 redis 节点上安装 redis exporter?
redis_exporter_port port C redis exporter 监听端口,默认为 9121
redis_exporter_options string C/I redis exporter 的 cli 参数和额外选项
redis_safeguard bool G/C/A 防止清除正在运行的 redis 实例?
redis_clean bool G/C/A 初始化期间清除现有的 redis?
redis_rmdata bool G/C/A 清除 redis 服务器时移除 redis 数据?
redis_mode enum C redis 模式:standalone、cluster、sentinel
redis_conf string C redis 配置模板路径,除 sentinel 外
redis_bind_address ip C redis 绑定地址,空字符串将使用主机 IP
redis_max_memory size C/I 每个 redis 实例使用的最大内存
redis_mem_policy enum C redis 内存逐出策略
redis_password password C redis 密码,空字符串将禁用密码
redis_rdb_save string[] C redis rdb 保存指令,使用空列表禁用
redis_aof_enabled bool C 启用 redis 追加文件?
redis_rename_commands dict C 重命名 redis 危险命令
redis_cluster_replicas int C redis 集群中一个主节点的副本数量
redis_sentinel_monitor master[] C sentinel 主节点列表,仅限 sentinel 集群

默认值

默认参数在 roles/redis/defaults/main.yml 中定义

#redis_cluster:        <CLUSTER> # redis 集群名称,必需的身份参数
#redis_node: 1            <NODE> # redis 节点序列号,必需的节点整数 ID
#redis_instances: {}      <NODE> # 此 redis 节点上的 redis 实例定义
redis_fs_main: /data              # redis 主数据挂载点,默认为 `/data`
redis_exporter_enabled: true      # 在 redis 节点上安装 redis exporter?
redis_exporter_port: 9121         # redis exporter 监听端口,默认为 9121
redis_exporter_options: ''        # redis exporter 的 cli 参数和额外选项
redis_safeguard: false            # 防止清除正在运行的 redis 实例?
redis_clean: true                 # 初始化期间清除现有的 redis?
redis_rmdata: true                # 清除 redis 服务器时移除 redis 数据?
redis_mode: standalone            # redis 模式:standalone、cluster、sentinel
redis_conf: redis.conf            # redis 配置模板路径,除 sentinel 外
redis_bind_address: '0.0.0.0'     # redis 绑定地址,空字符串将使用主机 IP
redis_max_memory: 1GB             # 每个 redis 实例使用的最大内存
redis_mem_policy: allkeys-lru     # redis 内存逐出策略
redis_password: ''                # redis 密码,空字符串将禁用密码
redis_rdb_save: ['1200 1']        # redis rdb 保存指令,使用空列表禁用
redis_aof_enabled: false          # 启用 redis 追加文件?
redis_rename_commands: {}         # 重命名 redis 危险命令
redis_cluster_replicas: 1         # redis 集群中一个主节点的副本数量
redis_sentinel_monitor: []        # sentinel 主节点列表,仅在 sentinel 集群上工作

redis_cluster

名称:redis_cluster,类型:string,级别:C

redis 集群名称,必需的身份参数。

无默认值,您必须明确定义它。

符合正则表达式 [a-z][a-z0-9-]*,建议使用与组名相同的名称并以 redis- 开头


redis_node

名称:redis_node,类型:int,级别:I

redis 节点序列号,在 redis 集群中需要唯一的整数

您必须为每个 redis 节点明确定义节点 ID。整数从 0 或 1 开始。


redis_instances

名称:redis_instances,类型:dict,级别:I

此 redis 节点上的 redis 实例定义

无默认值,您必须使用此参数在每个 redis 节点上明确定义 redis 实例。

这是一个原生 redis 集群定义的示例

redis-test: # redis 原生集群:3m x 3s
  hosts:
    10.10.10.12: { redis_node: 1 ,redis_instances: { 6379: { } ,6380: { } ,6381: { } } }
    10.10.10.13: { redis_node: 2 ,redis_instances: { 6379: { } ,6380: { } ,6381: { } } }
  vars: { redis_cluster: redis-test ,redis_password: 'redis.test' ,redis_mode: cluster, redis_max_memory: 32MB }

端口号在节点中应该是唯一的,value 中的 replica_of 应该是同一 redis 集群的实例成员。

redis_instances:
    6379: {}
    6380: { replica_of: '10.10.10.13 6379' }
    6381: { replica_of: '10.10.10.13 6379' }

redis_fs_main

名称:redis_fs_main,类型:path,级别:C

redis 主数据挂载点,默认为 /data

默认值:/data,并且 /data/redis 将用作 redis 数据目录。


redis_exporter_enabled

名称:redis_exporter_enabled,类型:bool,级别:C

在 redis 节点上安装 redis exporter?

默认值为 true,这将在此 redis_node 上启动一个 redis_exporter


redis_exporter_port

名称:redis_exporter_port,类型:port,级别:C

redis exporter 监听端口,默认为 9121

默认值:9121


redis_exporter_options

名称:redis_exporter_options,类型:string,级别:C/I

redis exporter 的 cli 参数和额外选项,将添加到 /etc/default/redis_exporter

默认值为空字符串


redis_safeguard

名称:redis_safeguard,类型:bool,级别:G/C/A

防止清除正在运行的 redis 实例?

默认值为 false,如果设置为 true,且 redis 实例正在运行,初始化/移除 playbook 将立即中止。


redis_clean

名称:redis_clean,类型:bool,级别:G/C/A

初始化期间清除现有的 redis?

默认值为 true,这将在 redis 初始化或移除期间移除 redis 服务器。


redis_rmdata

名称:redis_rmdata,类型:bool,级别:G/C/A

清除 redis 服务器时移除 redis 数据?

默认值为 true,这将与 redis 实例一起移除 redis rdb / aof。


redis_mode

名称:redis_mode,类型:enum,级别:C

redis 模式:standalone、cluster、sentinel

默认值:standalone

  • standalone:将 redis 设置为独立(主从)模式
  • cluster:将此 redis 集群设置为 redis 原生集群
  • sentinel:为独立 redis HA 设置 redis 为 sentinel

redis_conf

名称:redis_conf,类型:string,级别:C

redis 配置模板路径,除 sentinel 外

默认值:redis.conf,这是 roles/redis/templates/redis.conf 中的模板文件。

如果您想使用自己的 redis 配置模板,可以将其放在 templates/ 目录中并将此参数设置为模板文件名。

请注意,redis sentinel 使用不同的模板文件,即 roles/redis/templates/redis-sentinel.conf


redis_bind_address

名称:redis_bind_address,类型:ip,级别:C

redis 绑定地址,空字符串将使用清单主机名

默认值:0.0.0.0,这将绑定到此主机上的所有可用 IPv4 地址

请在生产环境中仅绑定到内网 IP,即将此值设置为 ''


redis_max_memory

名称:redis_max_memory,类型:size,级别:C/I

每个 redis 实例使用的最大内存,默认值:1GB


redis_mem_policy

名称:redis_mem_policy,类型:enum,级别:C

redis 内存逐出策略

默认值:allkeys-lru,查看 redis 逐出策略 获取更多详情

  • noeviction:达到内存限制时不保存新值。当数据库使用复制时,这适用于主数据库
  • allkeys-lru:保留最近使用的键;移除最少使用的(LRU)键
  • allkeys-lfu:保留经常使用的键;移除最少经常使用的(LFU)键
  • volatile-lru:移除过期字段设置为 true 的最少使用键。
  • volatile-lfu:移除过期字段设置为 true 的最少经常使用键。
  • allkeys-random:随机移除键以为添加的新数据腾出空间。
  • volatile-random:随机移除过期字段设置为 true 的键。
  • volatile-ttl:移除过期字段设置为 true 且剩余生存时间(TTL)值最短的键。

redis_password

名称:redis_password,类型:password,级别:C/N

redis 密码,空字符串将禁用密码,这是默认行为

请注意,由于 redis_exporter 的实现限制,每个节点只能设置一个 redis_password。这通常不是问题,因为 pigsty 不允许在同一节点上部署两个不同的 redis 集群。

请在生产环境中使用强密码


redis_rdb_save

名称:redis_rdb_save,类型:string[],级别:C

redis rdb 保存指令,使用空列表禁用,查看 redis 持久化 获取详情。

默认值为 ["1200 1"]:如果至少 1 个键发生变化,每 20 分钟将数据集转储到磁盘:


redis_aof_enabled

名称:redis_aof_enabled,类型:bool,级别:C

启用 redis 追加文件?默认值为 false


redis_rename_commands

名称:redis_rename_commands,类型:dict,级别:C

重命名 redis 危险命令,这是一个 k:v old: new 的字典

默认值:{},您可以通过设置此值来隐藏像 FLUSHDBFLUSHALL 这样的危险命令,这是一个示例:

{
  "keys": "op_keys",
  "flushdb": "op_flushdb",
  "flushall": "op_flushall",
  "config": "op_config"
}

redis_cluster_replicas

名称:redis_cluster_replicas,类型:int,级别:C

redis 集群中一个主节点/主要节点的副本数量,默认值:1


redis_sentinel_monitor

名称:redis_sentinel_monitor,类型:master[],级别:C

只有当 redis_mode 设置为 sentinel 时才能使用。

此 sentinel 集群要监控的 redis 主节点列表。每个主节点定义为具有 namehostportpasswordquorum 键的字典。

redis_sentinel_monitor:  # redis sentinel 的主节点列表,使用 cls 作为名称,主节点 ip:port
  - { name: redis-src, host: 10.10.10.45, port: 6379 ,password: redis.src, quorum: 1 }
  - { name: redis-dst, host: 10.10.10.48, port: 6379 ,password: redis.dst, quorum: 1 }

namehost 是必需的,portpasswordquorum 是可选的,quorum 用于为此主节点设置法定人数,通常大于 sentinel 实例的一半。

16.3 - 管理

运行管理任务

这里是 Redis 的一些常见管理任务。更多详情请查看 FAQ: Redis


初始化 Redis

初始化集群/节点/实例

# 在组 <cluster> 上初始化所有 redis 实例
./redis.yml -l <cluster>      # 初始化 redis 集群

# 初始化 redis 节点
./redis.yml -l 10.10.10.10    # 初始化 redis 节点

# 初始化一个特定的 redis 实例 10.10.10.11:6379
./redis.yml -l 10.10.10.11 -e redis_port=6379 -t redis

您也可以使用包装脚本:

bin/redis-add redis-ms          # 创建 redis 集群 'redis-ms'
bin/redis-add 10.10.10.10       # 创建 redis 节点 '10.10.10.10'
bin/redis-add 10.10.10.10 6379  # 创建 redis 实例 '10.10.10.10:6379'

移除 Redis

移除集群/节点/实例

# 移除集群 `redis-test`
redis-rm.yml -l redis-test

# 移除集群 `redis-test`,并卸载软件包
redis-rm.yml -l redis-test -e redis_uninstall=true

# 移除 redis 节点 10.10.10.13 上的所有实例
redis-rm.yml -l 10.10.10.13

# 移除一个特定的实例 10.10.10.13:6379
redis-rm.yml -l 10.10.10.13 -e redis_port=6379

您也可以使用包装脚本:

bin/redis-rm redis-ms          # 移除 redis 集群 'redis-ms'
bin/redis-rm 10.10.10.10       # 移除 redis 节点 '10.10.10.10'
bin/redis-rm 10.10.10.10 6379  # 移除 redis 实例 '10.10.10.10:6379'

重新加载 Redis

您可以部分运行 redis.yml 任务来重新配置 redis。

./redis.yml -l <cluster> -t redis_config,redis_launch

请注意,redis 无法在线重新加载;您必须重启 redis 才能使配置生效。


使用 Redis CLI

使用 redis-cli 访问 redis 实例:

$ redis-cli -h 10.10.10.10 -p 6379 # <--- 使用主机和端口连接
10.10.10.10:6379> auth redis.ms    # <--- 使用密码验证
OK
10.10.10.10:6379> set a 10         # <--- 设置一个键
OK
10.10.10.10:6379> get a            # <--- 获取一个键
"10"

Redis 还有一个 redis-benchmark,可用于基准测试和在 redis 服务器上生成负载:

redis-benchmark -h 10.10.10.13 -p 6379

复制 Redis

https://redis.io/commands/replicaof/

# 将 redis 实例提升为主节点
> REPLICAOF NO ONE
"OK"

# 使 redis 实例成为另一个实例的副本
> REPLICAOF 127.0.0.1 6799
"OK"

使用 Sentinel 的高可用

您必须使用您的 redis sentinel 手动为 redis 独立主从集群启用 HA。

以 4 节点沙盒为例,redis sentinel 集群 redis-meta 用于管理 redis-ms 独立集群。

# 对于每个 sentinel,使用以下方式将 redis 主节点添加到 sentinel:
$ redis-cli -h 10.10.10.11 -p 26379 -a redis.meta
10.10.10.11:26379> SENTINEL MONITOR redis-ms 10.10.10.10 6379 1
10.10.10.11:26379> SENTINEL SET redis-ms auth-pass redis.ms      # 如果启用了身份验证,必须配置密码

如果您希望从 sentinel 中移除 redis 主节点,请使用 SENTINEL REMOVE <name>

您可以使用 redis_sentinel_monitor 在 sentinel 集群上配置多个 redis 主节点。

redis_sentinel_monitor: # redis sentinel 的主节点列表,使用 cls 作为名称,主节点 ip:port
  - { name: redis-src, host: 10.10.10.45, port: 6379 ,password: redis.src, quorum: 1 }
  - { name: redis-dst, host: 10.10.10.48, port: 6379 ,password: redis.dst, quorum: 1 }

并使用以下方式刷新 sentinel 集群上的主节点列表:

./redis.yml -l redis-meta -t redis-ha   # 如果您的 sentinel 集群有不同的名称,请替换 redis-meta

16.4 - 剧本

控制原语

redis 有两个剧本:

redis.yml

剧本 redis.yml 将初始化 redis 集群/节点/实例:

redis_node        : init redis node
  - redis_install : install redis & redis_exporter
  - redis_user    : create os user redis
  - redis_dir     : create redis redis fhs
redis_exporter    : config and launch redis_exporter
  - redis_exporter_config  : generate redis_exporter config
  - redis_exporter_launch  : launch redis_exporter
redis_instance    : config and launch redis cluster/node/instance
  - redis_check   : check redis instance existence
  - redis_clean   : purge existing redis instance
  - redis_config  : generate redis instance config
  - redis_launch  : launch redis instance
redis_register    : register redis to prometheus
redis_ha          : setup redis sentinel
redis_join        : join redis cluster

redis-rm.yml

剧本 redis-rm.yml 将移除 redis 集群/节点/实例:

- register       : remove monitor target from prometheus
- redis_exporter : stop and disable redis_exporter
- redis          : stop and disable redis cluster/node/instance
- redis_data     : remove redis data (rdb, aof)
- redis_pkg      : uninstall redis & redis_exporter packages

16.5 - 监控

Redis 监控仪表板和告警规则

仪表板

REDIS 模块有三个仪表板。

Redis 概览

Redis Overview:所有 Redis 实例的概览

Redis 集群

Redis Cluster:单个 redis 集群的概览

Redis 实例

Redis Instance:单个 redis 实例的概览


告警规则

Redis 有 6 个预定义的告警规则,定义在 files/prometheus/rules/redis.yml 中。

名称 描述 级别
RedisDown Redis 服务器宕机 Critical
RedisRejectConn Redis 实例拒绝连接 Critical
RedisRTHigh Redis 实例响应时间过高 Warning
RedisCPUHigh Redis 实例 CPU 使用率过高 Warning
RedisMemHigh Redis 实例内存使用率过高 Warning
RedisQPSHigh Redis 实例 QPS 过高 Warning
#==============================================================#
#                         Error                                #
#==============================================================#
# redis down triggers a P0 alert
- alert: RedisDown
  expr: redis_up < 1
  for: 1m
  labels: { level: 0, severity: CRIT, category: redis }
  annotations:
    summary: "CRIT RedisDown: {{ $labels.ins }} {{ $labels.instance }} {{ $value }}"
    description: |
      redis_up[ins={{ $labels.ins }}, instance={{ $labels.instance }}] = {{ $value }} == 0
      http://g.pigsty/d/redis-instance?from=now-5m&to=now&var-ins={{$labels.ins}}

# redis reject connection in last 5m
- alert: RedisRejectConn
  expr: redis:ins:conn_reject > 0
  labels: { level: 0, severity: CRIT, category: redis }
  annotations:
    summary: "CRIT RedisRejectConn: {{ $labels.ins }} {{ $labels.instance }} {{ $value }}"
    description: |
      redis:ins:conn_reject[cls={{ $labels.cls }}, ins={{ $labels.ins }}][5m] = {{ $value }} > 0
      http://g.pigsty/d/redis-instance?from=now-10m&to=now&viewPanel=88&fullscreen&var-ins={{ $labels.ins }}



#==============================================================#
#                         Latency                              #
#==============================================================#
# redis avg query response time > 160 µs
- alert: RedisRTHigh
  expr: redis:ins:rt > 0.00016
  for: 1m
  labels: { level: 1, severity: WARN, category: redis }
  annotations:
    summary: "WARN RedisRTHigh: {{ $labels.cls }} {{ $labels.ins }}"
    description: |
      pg:ins:query_rt[cls={{ $labels.cls }}, ins={{ $labels.ins }}] = {{ $value }} > 160µs
      http://g.pigsty/d/redis-instance?from=now-10m&to=now&viewPanel=97&fullscreen&var-ins={{ $labels.ins }}



#==============================================================#
#                        Saturation                            #
#==============================================================#
# redis cpu usage more than 70% for 1m
- alert: RedisCPUHigh
  expr: redis:ins:cpu_usage > 0.70
  for: 1m
  labels: { level: 1, severity: WARN, category: redis }
  annotations:
    summary: "WARN RedisCPUHigh: {{ $labels.cls }} {{ $labels.ins }}"
    description: |
      redis:ins:cpu_all[cls={{ $labels.cls }}, ins={{ $labels.ins }}] = {{ $value }} > 60%
      http://g.pigsty/d/redis-instance?from=now-10m&to=now&viewPanel=43&fullscreen&var-ins={{ $labels.ins }}

# redis mem usage more than 70% for 1m
- alert: RedisMemHigh
  expr: redis:ins:mem_usage > 0.70
  for: 1m
  labels: { level: 1, severity: WARN, category: redis }
  annotations:
    summary: "WARN RedisMemHigh: {{ $labels.cls }} {{ $labels.ins }}"
    description: |
      redis:ins:mem_usage[cls={{ $labels.cls }}, ins={{ $labels.ins }}] = {{ $value }} > 80%
      http://g.pigsty/d/redis-instance?from=now-10m&to=now&viewPanel=7&fullscreen&var-ins={{ $labels.ins }}

#==============================================================#
#                         Traffic                              #
#==============================================================#
# redis qps more than 32000 for 5m
- alert: RedisQPSHigh
  expr: redis:ins:qps > 32000
  for: 5m
  labels: { level: 2, severity: INFO, category: redis }
  annotations:
    summary: "INFO RedisQPSHigh: {{ $labels.cls }} {{ $labels.ins }}"
    description: |
      redis:ins:qps[cls={{ $labels.cls }}, ins={{ $labels.ins }}] = {{ $value }} > 16000
      http://g.pigsty/d/redis-instance?from=now-10m&to=now&viewPanel=96&fullscreen&var-ins={{ $labels.ins }}

16.6 - FAQ

常见问题

由于现有 redis 实例而中止

使用 redis_clean = trueredis_safeguard = false 强制清理 redis 数据

当您运行 redis.yml 初始化已经运行的 redis 实例,并且 redis_clean 设置为 false 时会发生这种情况。

如果 redis_clean 设置为 true(且 redis_safeguard 也设置为 false),redis.yml playbook 将删除现有的 redis 实例并将其重新初始化为新实例,这使得 redis.yml playbook 完全幂等。


由于启用 redis_safeguard 而中止

当使用 redis_safeguard 设置为 true 移除 redis 实例时会发生这种情况。

您可以禁用 redis_safeguard 来移除 Redis 实例。这就是 redis_safeguard 的作用。


如何在此节点上添加一个新的 redis 实例?

使用 bin/redis-add <ip> <port> 在节点上部署新的 redis 实例。


如何从节点移除单个 redis 实例?

bin/redis-rm <ip> <port> 从节点移除单个 redis 实例

17 - FERRET

Ferret,基于 postgres 的 mongo

MongoDB 已经失去了其开源吸引力,不再适合许多用例。 相比之下,PostgreSQL 提供强大的原生 JSON 支持,作为文档数据库的性能超越了 MongoDB。

因此,FerretDB 在 postgres 之上提供了与 mongo 线协议兼容的层,使 MongoDB 用户能够平滑迁移到 PostgreSQL 的优越平台。 FERRET 是 Pigsty 中的一个 可选 模块。 自 v2.0 以来,它需要 documentdb 扩展才能工作。

Pigsty 已经打包了这个扩展,并提供了一个 mongo.yml 模板,帮助您轻松部署 FerretDB 集群。

配置
    配置 ferret 模块,并使用多个 ferret 节点。
参数
    使用 9 个参数自定义 ferret 组件
管理
    创建、移除、扩展、收缩、升级 ferret 集群
剧本
    可在此模块中使用的 Ansible 剧本
监控
    仪表板、指标、记录和告警规则。
使用
    如何使用 mcli 和配置备份仓库

17.1 - 使用方法

安装客户端工具,连接并使用 FerretDB

本文档介绍如何安装 MongoDB 客户端工具并连接到 FerretDB。


安装客户端工具

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

使用 pig 命令添加 MongoDB 仓库,然后使用 yumapt 安装 mongosh

pig repo add mongo -u   # 添加 MongoDB 官方仓库
yum install mongodb-mongosh   # RHEL/CentOS/Rocky/Alma
apt install mongodb-mongosh   # Debian/Ubuntu

安装完成后,您可以使用 mongosh 命令连接到 FerretDB。


连接到 FerretDB

您可以使用任何语言的 MongoDB 驱动程序通过 MongoDB 连接字符串访问 FerretDB。以下是使用 mongosh CLI 工具的示例:

$ 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 的身份验证完全基于 PostgreSQL。由于 Pigsty 管理的 PostgreSQL 集群默认使用 scram-sha-256 认证方式,您必须在连接字符串中指定 PLAIN 认证机制:

mongosh 'mongodb://dbuser_meta:[email protected]:27017?authMechanism=PLAIN'

连接字符串格式:

mongodb://<username>:<password>@<host>:<port>/<database>?authMechanism=PLAIN

使用不同的用户

您可以使用任何已在 PostgreSQL 中创建的用户连接到 FerretDB:

# 使用 dbuser_dba 用户
mongosh 'mongodb://dbuser_dba:[email protected]:27017?authMechanism=PLAIN'

# 使用 mongod 超级用户
mongosh 'mongodb://mongod:[email protected]:27017?authMechanism=PLAIN'

# 连接到特定数据库
mongosh 'mongodb://test:[email protected]:27017/test?authMechanism=PLAIN'

基本操作

连接到 FerretDB 后,您可以像使用 MongoDB 一样进行操作。以下是一些基本操作示例:

数据库操作

// 切换/创建数据库
use mydb

// 显示所有数据库
show dbs

// 删除当前数据库
db.dropDatabase()

集合操作

// 创建集合
db.createCollection('users')

// 显示所有集合
show collections

// 删除集合
db.users.drop()

文档操作

// 插入单个文档
db.users.insertOne({
    name: 'Alice',
    age: 30,
    email: '[email protected]'
})

// 插入多个文档
db.users.insertMany([
    { name: 'Bob', age: 25 },
    { name: 'Charlie', age: 35 }
])

// 查询文档
db.users.find()
db.users.find({ age: { $gt: 25 } })
db.users.findOne({ name: 'Alice' })

// 更新文档
db.users.updateOne(
    { name: 'Alice' },
    { $set: { age: 31 } }
)

// 删除文档
db.users.deleteOne({ name: 'Bob' })
db.users.deleteMany({ age: { $lt: 30 } })

索引操作

// 创建索引
db.users.createIndex({ name: 1 })
db.users.createIndex({ age: -1 })

// 查看索引
db.users.getIndexes()

// 删除索引
db.users.dropIndex('name_1')

与 MongoDB 的差异

FerretDB 实现了 MongoDB 的线协议,但底层使用 PostgreSQL 存储数据。这意味着:

  • MongoDB 命令会被翻译为 SQL 语句执行
  • 大多数基本操作与 MongoDB 兼容
  • 某些高级功能可能有差异或不支持

您可以查阅以下资源了解详细信息:


程序语言驱动

除了 mongosh 命令行工具,您还可以使用各种编程语言的 MongoDB 驱动程序连接到 FerretDB:

Python

from pymongo import MongoClient

client = MongoClient('mongodb://dbuser_meta:[email protected]:27017/?authMechanism=PLAIN')
db = client.test
collection = db.users
collection.insert_one({'name': 'Alice', 'age': 30})

Node.js

const { MongoClient } = require('mongodb');

const uri = 'mongodb://dbuser_meta:[email protected]:27017/?authMechanism=PLAIN';
const client = new MongoClient(uri);

async function run() {
    await client.connect();
    const db = client.db('test');
    const collection = db.collection('users');
    await collection.insertOne({ name: 'Alice', age: 30 });
}

Go

import (
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

uri := "mongodb://dbuser_meta:[email protected]:27017/?authMechanism=PLAIN"
client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri))

关键点:所有驱动程序都需要在连接字符串中指定 authMechanism=PLAIN 参数。

17.2 - 配置

描述您想要的 ferret 集群

FerretDB 集群

在部署 Mongo (FerretDB) 集群之前,您需要使用相关 参数 在清单中定义它。

以下示例使用默认的单节点 pg-meta 集群的 meta 数据库作为 FerretDB 的底层存储:

all:
  children:

    #----------------------------------#
    # ferretdb for mongodb on postgresql
    #----------------------------------#
    # ./mongo.yml -l ferret
    ferret:
      hosts:
        10.10.10.10: { mongo_seq: 1 }
      vars:
        mongo_cluster: ferret
        mongo_pgurl: 'postgres://mongod:[email protected]:5432/meta'

这里,mongo_clustermongo_seq 是基本的身份参数。对于 FerretDB,还需要 mongo_pgurl 来指定底层 PG 位置。

请注意,mongo_pgurl 参数需要一个 PostgreSQL 超级用户。在此示例中,为 FerretDB 定义了一个专用的 mongod 超级用户。

请注意,FerretDB 的 身份验证 完全基于 PostgreSQL。您可以使用 FerretDB 或 PostgreSQL 创建其他常规用户。


PostgreSQL 集群

FerretDB 2.0+ 需要一个扩展:DocumentDB,它依赖于几个其他扩展。以下是为 FerretDB 创建 PostgreSQL 集群的模板:

all:
  children:

    #----------------------------------#
    # pgsql (singleton on current node)
    #----------------------------------#
    # postgres cluster: pg-meta
    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 ] ,superuser: true ,comment: ferretdb super user }
          - { 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, 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' }
        pg_extensions:
          - documentdb, citus, postgis, pgvector, pg_cron, rum
        pg_parameters:
          cron.database_name: meta
        pg_libs: 'pg_documentdb, pg_documentdb_core, pg_cron, pg_stat_statements, auto_explain'  # 将 timescaledb 添加到 shared_preload_libraries

高可用性

您可以使用 服务 连接到高可用的 PostgreSQL 集群,并部署多个 FerretDB 实例副本,并为 FerretDB 层高可用性绑定 L2 VIP。

ferret:
  hosts:
    10.10.10.45: { mongo_seq: 1 }
    10.10.10.46: { mongo_seq: 2 }
    10.10.10.47: { mongo_seq: 3 }
  vars:
    mongo_cluster: ferret
    mongo_pgurl: 'postgres://mongod:[email protected]:5436/test'
    vip_enabled: true
    vip_vrid: 128
    vip_address: 10.10.10.99
    vip_interface: eth1

17.3 - 参数

使用 9 个参数自定义 FerretDB

FERRET 模块中有 9 个参数。

参数 类型 层级 注释
mongo_seq int I mongo 实例标识符,必需
mongo_cluster string C mongo 集群名称,默认为 MONGO
mongo_pgurl pgurl C/I ferretdb 的底层 postgres URL
mongo_ssl_enabled bool C mongo/ferretdb ssl 启用,默认为 false
mongo_listen ip C mongo 监听地址,为空时监听所有地址
mongo_port port C mongo 服务端口,默认为 27017
mongo_ssl_port port C mongo tls 监听端口,默认为 27018
mongo_exporter_port port C mongo exporter 端口,默认为 9216
mongo_extra_vars string C MONGO 服务器的额外环境变量

默认值

默认参数定义在 roles/ferret/defaults/main.yml

# mongo_cluster:        #CLUSTER  # mongo 集群名称,必需的身份参数
# mongo_seq: 0          #INSTANCE # mongo 实例序列号,必需的身份参数
# mongo_pgurl: 'postgres:///'     # mongo/ferretdb 底层 postgresql url,必需
mongo_ssl_enabled: false          # mongo/ferretdb ssl 启用,默认为 false
mongo_listen: ''                  # mongo/ferretdb 监听地址,'' 表示所有地址
mongo_port: 27017                 # mongo/ferretdb 监听端口,默认为 27017
mongo_ssl_port: 27018             # mongo/ferretdb tls 监听端口,默认为 27018
mongo_exporter_port: 9216         # mongo/ferretdb exporter 端口,默认为 9216
mongo_extra_vars: ''              # mongo/ferretdb 的额外环境变量

mongo_cluster

名称:mongo_cluster,类型:string,层级:C

mongo 集群名称,必需的身份参数。

默认值为 MONGO,但您应该为生产使用显式定义它。

符合正则表达式 [a-z][a-z0-9-]*,建议使用描述性名称并以 mongo- 开头


mongo_seq

名称:mongo_seq,类型:int,层级:I

mongo 实例序列号,mongo 集群中需要唯一整数

您必须为每个 mongo 实例显式定义序列号。整数从 0 或 1 开始。


mongo_pgurl

名称:mongo_pgurl,类型:pgurl,层级:C/I

ferretdb 连接的底层 postgres URL。

没有默认值,您必须显式定义它。这是 FerretDB 将用作其后端存储的 PostgreSQL 数据库 URL。

格式:postgres://username:password@host:port/database


mongo_ssl_enabled

名称:mongo_ssl_enabled,类型:bool,层级:C

mongo/ferretdb ssl 启用标志。

默认值为 false。设置为 true 以启用 mongo 连接的 SSL/TLS 加密。


mongo_listen

名称:mongo_listen,类型:ip,层级:C

mongo 绑定的监听地址。

默认值为空字符串 '',这意味着监听所有可用地址。您可以指定特定的 IP 地址进行绑定。


mongo_port

名称:mongo_port,类型:port,层级:C

mongo 客户端连接的服务端口。

默认值为 27017,这是标准的 MongoDB 端口。如果您需要避免端口冲突,请更改此端口。


mongo_ssl_port

名称:mongo_ssl_port,类型:port,层级:C

mongo 加密连接的 tls 监听端口。

默认值为 27018。当为安全连接启用 SSL/TLS 时,使用此端口。


mongo_exporter_port

名称:mongo_exporter_port,类型:port,层级:C

mongo 指标收集的 exporter 端口。

默认值为 9216。此端口由监控 exporter 使用,向 Prometheus 暴露指标。


mongo_extra_vars

名称:mongo_extra_vars,类型:string,层级:C

MONGO 服务器的额外环境变量。

默认值为空字符串 ''。您可以指定将传递给 FerretDB 进程的额外环境变量。

17.4 - 管理

运行管理任务

创建 FerretDB 集群

清单定义 FerretDB 集群后,您可以使用以下命令安装它:

./mongo.yml -l ferret   # 在 ferret 组上安装 MongoDB/FerretDB

由于 FerretDB 使用 PostgreSQL 作为其底层存储,多次运行此剧本通常是安全的。


移除 FerretDB 集群

要移除 Mongo/FerretDB 集群,请使用 mongo_purge 参数运行 mongo.yml 剧本的 mongo_purge 子任务:

./mongo.yml -e mongo_purge=true -t mongo_purge

17.5 - 剧本

使用剧本安装 ferretdb

有一个内置的剧本 mongo.yml 用于在节点上安装 FerretDB。


mongo.yml

mongo.yml:在目标主机上安装 MongoDB/FerretDB。

此剧本包含以下子任务:

  • mongo_check :检查 mongo 身份
  • mongo_dbsu :创建操作系统用户 mongod
  • mongo_install :安装 mongo/ferretdb rpm
  • mongo_purge :清除 mongo/ferretdb
  • mongo_config:配置 mongo/ferretdb
  • mongo_cert :签发 mongo/ferretdb ssl 证书
  • mongo_launch :启动 mongo/ferretdb 服务
  • mongo_register :将 mongo/ferretdb 注册到 prometheus

17.6 - 监控

FerretDB 监控仪表板和告警

FERRET 模块目前有一个仪表板。

Mongo Overview

Mongo Overview:Mongo/FerretDB 集群概览

18 - Docker

Docker,开源容器服务

Docker 是 Pigsty 中的一个 可选模块,默认已下载但未安装。 您必须在使用前显式 启用 它。

配置
    配置 docker 注册中心、代理、镜像等...
参数
    使用 8 个参数自定义 docker 组件
管理
    管理 docker 镜像、容器等...
剧本
    可在 docker 模块中使用的 Ansible 剧本
监控
    仪表板、指标、记录和告警规则。
常见问题
    关于 docker 模块的常见问题

18.1 - 配置

配置您的 docker 设置

Pigsty 包含内置的 Docker 支持,允许您快速部署容器化应用程序。


快速开始

要在节点上安装 docker,请将 docker_enabled 参数设置为 true

all:
  vars:

    infra:
      hosts:
        10.10.10.10: { infra_seq: 1, nodename: infra-1 }
        10.10.10.11: { infra_seq: 2, nodename: infra-2 }
      vars:
        docker_enabled: true  # 在此组上安装 Docker

然后运行 docker.yml playbook(在目标主机/组上):

~/pigsty
./docker.yml -l infra

Docker 将安装在该 infra 组上。


镜像站

您可以使用 docker_registry_mirrors 指定 docker 注册表镜像:

all:
  vars:
    docker_registry_mirrors: ["https://docker.1ms.run"]

以下是一些示例注册表镜像:

  • 阿里云:["https://registry.cn-hangzhou.aliyuncs.com"]
  • 腾讯云:["https://ccr.ccs.tencentyun.com"]
  • DaoCloud:["https://docker.m.daocloud.io"]
  • 1Ms:["https://docker.1ms.run"]

您可以将多个注册表镜像指定为数组,记住用 " 引用 URL。


代理

如果指定了 proxy_env 参数,Docker 将使用它。

您可以在全局参数 all.vars 或专用组(如 infra)中定义它:

all:
  vars:
    proxy_env:
      no_proxy: "localhost,127.0.0.1,10.0.0.0/8,192.168.0.0/16,*.pigsty,*.aliyun.com,mirrors.*"
      http_proxy: 'http://127.0.0.1:12345'
      https_proxy: 'http://127.0.0.1:12345'
      all_proxy: 'http://127.0.0.1:12345'

它将在 docker_config 任务期间呈现到 /etc/docker/daemon.json

{
  "proxies": {
    "http-proxy": "127.0.0.1:12345",
    "https-proxy": "127.0.0.1:12345",
    "no-proxy": "localhost,127.0.0.1,10.0.0.0/8,192.168.0.0/16,*.pigsty,*.aliyun.com,mirrors.*,*.tsinghua.edu.cn"
  }
}

这在由于各种原因阻止直接网络访问时很有用。


镜像

您可以使用 docker_imagedocker_image_cache 置备 docker 镜像:

infra:
  hosts:
    10.10.10.10: { infra_seq: 1 }
  vars:
    docker_enabled: true
    docker_image:
      - redis:latest
    docker_image_cache: "/tmp/docker/*.tgz"

docker_image 中定义的镜像将在 docker_image 任务期间逐个拉取。 匹配 docker_image_cache glob 列表的带有 .tgz 后缀的本地 docker 镜像缓存将使用 docker load 加载到 docker 中


加速

您可以在各个云供应商上使用加速器:

  • 阿里云 ACR:https://cr.console.aliyun.com/cn-shanghai/instances/mirrors

18.2 - 参数

使用 8 个参数自定义 docker

Docker 模块有 8 个参数:

名称 类型 层级 注释
docker_enabled bool G/C/I 在此节点上启用 docker?
docker_data path G/C/I Docker 数据目录,默认为 /var/lib/docker
docker_storage_driver enum G/C/I Docker 存储驱动程序,默认为 overlay2
docker_cgroups_driver enum G/C/I docker cgroup fs 驱动程序:cgroupfs,systemd
docker_registry_mirrors string[] G/C/I docker 注册中心镜像列表
docker_exporter_port port G Docker 指标导出器端口,默认为 9323
docker_image path[] G/C/I 要拉取的 docker 镜像,默认为 []
docker_image_cache path G/C/I docker 镜像缓存压缩包通配符,默认为 /tmp/docker

默认值

Docker 的默认参数定义在 roles/docker/defaults/main.yml

docker_enabled: false             # 在此节点上启用 docker?
docker_data: /var/lib/docker      # docker 数据目录,默认为 /var/lib/docker
docker_storage_driver: overlay2   # docker 存储驱动程序,可以是 zfs, btrfs
docker_cgroups_driver: systemd    # docker cgroup fs 驱动程序:cgroupfs,systemd
docker_registry_mirrors: []       # docker 注册中心镜像列表
docker_exporter_port: 9323        # docker 指标导出器端口,默认为 9323
docker_image: []                  # 引导后要拉取的 docker 镜像
docker_image_cache: /tmp/docker/*.tgz # docker 镜像缓存通配符模式

docker_enabled

名称:docker_enabled,类型:bool,层级:G/C/I

在此节点上启用 docker?默认值为 false


docker_data

名称:docker_data,类型:path,层级:C

Docker 数据目录,默认为 /var/lib/docker


docker_storage_driver

名称:docker_storage_driver,类型:enum,层级:C

Docker 存储驱动程序,默认为 overlay2

请参考:https://docs.docker.com/engine/storage/drivers/select-storage-driver/

  • overlay2
  • fuse-overlayfs
  • brtfs
  • zfs
  • vfs

docker_cgroups_driver

名称:docker_cgroups_driver,类型:enum,层级:G/C/I

docker cgroup fs 驱动程序,可以是 cgroupfssystemd,默认值:systemd


docker_registry_mirrors

名称:docker_registry_mirrors,类型:string[],层级:G/C/I

docker 注册中心镜像列表,默认值:[],示例:

以下是使用各云厂商内网镜像的一些示例:

["https://docker.m.daocloud.io"]                # 国内 DaoCloud 镜像站点
["https://docker.1ms.run"]                      # 国内毫秒镜像站点
["https://mirror.ccs.tencentyun.com"]           # 腾讯云内网镜像站点
["https://registry.cn-hangzhou.aliyuncs.com"]   # 阿里云内网镜像站点,需要登录

考虑使用 Cloudflare Worker Docker Proxy

如果拉取速度太慢,您也可以考虑:docker login quay.io 使用其他注册中心。


docker_exporter_port

名称:docker_exporter_port,类型:port,层级:G

Docker 指标导出器端口,默认为 9323


docker_image

名称:docker_image,类型:string[],层级:G/C/I

要拉取的 docker 镜像,默认为 []

这里列出的镜像将在 docker 置备期间被拉取。


docker_image_cache

名称:docker_image_cache,类型:path,层级:G/C/I

docker 镜像缓存压缩包通配符列表,默认为 "/tmp/docker/*.tgz"

匹配此通配符列表的带有 .tgz 后缀的本地 docker 镜像缓存将逐一加载到 docker 中:

cat *.tgz | gzip -d -c - | docker load

18.3 - 管理

Docker 管理任务

安装

要在节点上安装和启用 docker,请 配置 docker_enabled 参数为 true

all:
  vars:

    infra:
      hosts:
        10.10.10.10: { infra_seq: 1, nodename: infra-1 }
        10.10.10.11: { infra_seq: 2, nodename: infra-2 }
      vars:
        docker_enabled: true  # 在此组上安装 Docker

然后运行 docker.yml 剧本(在目标主机/组上):

./docker.yml -l infra

Docker 将安装在该 infra 组上。

infra 是占位符

我们在这里使用 infra 组作为示例,您可以在其他地方定义它,只要它适用于预期的主机。


仓库

Docker 仓库是 infra 仓库模块的一部分,将在 仓库 构建期间自动添加。

- name: docker-ce
  description: 'Docker CE'
  module: infra
  releases: [7,8,9]
  arch: [x86_64, aarch64]
  baseurl:
    default: 'https://download.docker.com/linux/centos/$releasever/$basearch/stable'
    europe:  'https://mirrors.xtom.de/docker-ce/linux/centos/$releasever/$basearch/stable'
    china:   'https://mirrors.aliyun.com/docker-ce/linux/centos/$releasever/$basearch/stable'
- name: docker-ce
  description: 'Docker CE'
  module: infra
  releases: [11,12,20,22,24]
  arch: [x86_64, aarch64]
  baseurl:
    default: 'https://download.docker.com/linux/${distro_name} ${distro_codename} stable'
    china: 'https://mirrors.aliyun.com/docker-ce/linux/${distro_name} ${distro_codename} stable'

您可以使用以下命令将此仓库添加到您的节点:

./node.yml -t node_repo -e node_repo_modules=infra -l infra

升级

要升级 Docker 守护进程,使用 ansible 命令,添加 docker 仓库,然后:

~/pigsty
ansible infra -m package -b -a 'name=docker-ce state=latest'

它将把 docker-ce 包升级到您配置的仓库中可用的最新版本。


移除

要移除 Docker 守护进程,使用 ansible 命令运行:

~/pigsty
ansible infra -m package -b -a 'name=docker-ce state=absent'

它将使用您的操作系统包管理器移除 docker-ce 包。


应用程序

Pigsty 提供基于 Docker Compose 的即用型 软件模板,用于部署与 Pigsty 管理的数据库集群无缝集成的外部应用程序。

18.4 - 剧本

使用剧本设置 docker

DOCKER 模块只有一个剧本:docker.yml 用于在目标节点上安装 docker 守护进程和 docker compose。


docker.yml

原始剧本:docker.yml

在任何主机上运行此剧本将在启用 docker_enabled: true 标志的目标节点上安装 docker-cedocker-compose-plugin

以下是 docker.yml 剧本中可用的子任务:

  • docker_install:在节点上安装 Docker 和 Docker Compose 包。
  • docker_admin:将指定用户添加到 Docker 管理员用户组。
  • docker_config:生成 Docker 守护进程服务配置文件。
  • docker_launch:启动 Docker 守护进程服务。
  • docker_register:将 Docker 守护进程注册为 Prometheus 监控目标。
  • docker_image:如果存在的话,尝试从 /tmp/docker/*.tgz 加载预打包的 Docker 镜像。

Docker 模块不提供专用的 Docker 卸载剧本。如果您需要卸载 Docker,您可以手动停止 Docker 服务然后卸载它:

systemctl stop docker                        # 停止 Docker 守护进程服务
yum remove docker-ce docker-compose-plugin   # 在 EL 系统上卸载 Docker
apt remove docker-ce docker-compose-plugin   # 在 Debian 系统上卸载 Docker

18.5 - 监控

docker 监控和仪表板

如果节点的 docker_enabled = true,Pigsty 将把 docker 守护进程添加到监控目标中

但是 docker 模块没有默认的仪表板和告警规则,您可以向 prometheus 和 grafana 添加自己的规则。

18.6 - FAQ

常见问题解答

谁可以运行 Docker 命令?

默认情况下,Pigsty 将在远程主机上运行剧本的 管理用户(即 SSH 登录用户)和由 node_admin_username 参数定义的用户都添加到操作系统组 docker 中。 该组中的任何账户都可以通过 docker CLI 管理 Docker。

需要为另一个用户授予 Docker 访问权限?只需将该操作系统用户添加到 docker 组:

sudo usermod -aG docker <username>

通过代理工作

在安装期间,如果设置了 proxy_env 参数,Pigsty 会将指定的 HTTP 代理设置写入 /etc/docker/daemon.json

然后 Docker 将通过此代理路由所有来自上游注册中心的镜像拉取。

提示: 使用 -x 标志运行 configure 剧本会自动捕获当前 shell 的代理变量并将它们注入到 proxy_env 中。


使用镜像注册中心

在中国大陆,您可能会遇到 GFW 限制。可以使用诸如 quay.io 等镜像:

docker login quay.io   # 输入您的凭据登录

更新(2024年6月): 中国所有以前可访问的 Docker 镜像现在都已被阻止。请通过代理拉取镜像。


将 Docker 添加到监控

安装 Docker 模块后,您可以通过运行 docker_register(别名 register_prometheus)任务将 Docker 注册为特定节点的 Prometheus 目标:

./docker.yml -l <your-node-selector> -t register_prometheus

软件模板

Pigsty 提供了一系列 软件模板,这些模板使用 Docker Compose 启动流行的技术栈——开箱即用。

只需确保首先安装了 Docker 模块。

19 - APP

使用 pigsty 和 docker compose 运行自托管应用程序模板
Supabase
    自托管 Supabase
Odoo
    运行 Odoo 开源 ERP
Dify
    运行 Dify AI 工作流
pgAdmin
    运行官方管理 GUI 工具

19.1 - 剧本

运行 docker compose 应用程序

Pigsty 内置支持 Docker 和一系列使用 PostgreSQL 作为主存储的软件。

您可以使用 docker compose 运行无状态应用程序,并将数据存储在外部高可用的 PostgreSQL(Redis/MinIO/…)集群中。

有一个专用的剧本 app.yml 可以帮助您轻松运行 docker compose 应用程序

19.2 - pgAdmin

启动 PostgreSQL 官方 GUI 管理工具

pgAdmin 是最受欢迎且功能丰富的 PostgreSQL 开源管理和开发平台, PostgreSQL 是世界上最先进的开源数据库。


快速开始

Pigsty 内置(但可选)支持 pgAdmin,它使用 Docker Compose 启动 pgadmin:

./docker.yml
./app.yml -e app=pgadmin

pgadmin 的默认端口是 8885,您可以通过 IP:端口访问它:http://10.10.10.10:8885

默认凭据在 .env 中定义,用户名:[email protected],密码:pigsty


自定义

/opt/pgadmin/.env 中自定义 pgadmin 配置并使用 docker compose 管理它。

您还可以自定义 apps 参数并使用以下方式覆盖默认 .env 配置:

all:
  children:

    infra:
      hosts:
        10.10.10.10: { infra_seq: 1 }
      vars:
        docker_enabled: true
        app: pgadmin  # 指定要安装的应用程序名称(pgadmin)(在 apps 中)
        apps:         # 定义所有应用程序
          supabase:   # pgadmin 应用程序的定义
            conf:     # 覆盖 /opt/supabase/.env

              PGADMIN_DEFAULT_EMAIL: [email protected]
              PGADMIN_DEFAULT_PASSWORD: yourPassword

              PGADMIN_LISTEN_ADDRESS: 0.0.0.0
              PGADMIN_PORT: 8885
              PGADMIN_SERVER_JSON_FILE: /pgadmin4/servers.json
              PGADMIN_REPLACE_SERVERS_ON_STARTUP: true

要启动应用程序,运行:

./app.yml -l infra

域名和证书

要通过 nginx(而不是直接访问端口 8885)访问 pgadmin,请使用以下方式配置 基础设施门户

pigsty.yml
all:
  vars:
    infra_portal:
      home         : { domain: h.pigsty }
      grafana      : { domain: g.pigsty ,endpoint: "${admin_ip}:3000" , websocket: true }
      prometheus   : { domain: p.pigsty ,endpoint: "${admin_ip}:9058" }
      alertmanager : { domain: a.pigsty ,endpoint: "${admin_ip}:9059" }
      blackbox     : { endpoint: "${admin_ip}:9115" }
      loki         : { endpoint: "${admin_ip}:3100" }

      # 在此处添加 pgadmin 上游服务器定义
      pgadmin      : { domain: adm.pigsty  ,endpoint: "127.0.0.1:8885" }

然后运行 make nginx 更新 nginx 配置,并在 /etc/hosts本地 / 公共 DNS 服务器中配置 本地静态 DNS 记录 <your_ip_address> adm.pigsty

Pigsty 将自动为 infra_portal 中列出的域名签发自签名 SSL 证书。 如果您想使用真实域名,请定义 cerbot 条目并运行 make cert,查看 SSL 证书 了解详情。

all:
  vars:        # 确保您的域名(adm.pigsty.cc)解析到您的公网 IP
    certbot_sign: true   # 使用 certbot 签发真实 HTTPS 证书(需要互联网访问!)
    infra_portal:
      pgadmin : { domain: adm.pigsty.cc  ,endpoint: "127.0.0.1:8885", certbot: adm.pigsty.cc }

19.3 - Supabase

使用 Pigsty 自托管企业级 supabase,带有监控,高可用,PITR,IaC 以及 400+ PG扩展。

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 中的配置,将集群规模升级到三节点或以上。

19.4 - Odoo

自托管 Odoo,开源 ERP

Odoo 是一个开源企业资源规划 (ERP) 软件 它提供一整套业务应用程序,包括 CRM、销售、采购、库存、生产、会计, 和其他管理功能。Odoo 是一个典型的 Web 应用程序,使用 PostgreSQL 作为底层数据库。

您的所有业务,都在一个平台上,简单、高效且实惠


快速开始

curl -fsSL https://repo.pigsty.io/get | bash -s v3.7.0; cd ~/pigsty
./bootstrap                # 安装 ansible
./configure -c app/odoo    # 使用 odoo 配置(请在 pigsty.yml 中更改凭据)
./install.yml              # 安装 pigsty
./docker.yml               # 安装 docker compose
./app.yml                  # 使用 docker 启动 odoo 无状态部分

默认的用户名和密码都是 admin


配置模板

conf/app/odoo.yml 定义了一个模板配置文件 定义单个 Odoo 实例所需的资源。

all:
  children:

    # odoo 应用程序(默认用户名和密码:admin/admin)
    odoo:
      hosts: { 10.10.10.10: {} }
      vars:
        app: odoo   # 指定要安装的应用程序名称(在 apps 中)
        apps:       # 定义所有应用程序
          odoo:     # 应用程序名称应该有对应的 ~/app/odoo 文件夹
            file:   # 要创建的可选目录
              - { path: /data/odoo         ,state: directory, owner: 100, group: 101 }
              - { path: /data/odoo/webdata ,state: directory, owner: 100, group: 101 }
              - { path: /data/odoo/addons  ,state: directory, owner: 100, group: 101 }
            conf:   # 覆盖 /opt/<app>/.env 配置文件
              PG_HOST: 10.10.10.10            # postgres 主机
              PG_PORT: 5432                   # postgres 端口
              PG_USERNAME: odoo               # postgres 用户
              PG_PASSWORD: DBUser.Odoo        # postgres 密码
              ODOO_PORT: 8069                 # odoo 应用程序端口
              ODOO_DATA: /data/odoo/webdata   # odoo webdata
              ODOO_ADDONS: /data/odoo/addons  # odoo 插件
              ODOO_DBNAME: odoo               # odoo 数据库名称
              ODOO_VERSION: 19.0              # odoo 镜像版本

    # odoo 数据库
    pg-odoo:
      hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
      vars:
        pg_cluster: pg-odoo
        pg_users:
          - { name: odoo    ,password: DBUser.Odoo ,pgbouncer: true ,roles: [ dbrole_admin ] ,createdb: true ,comment: admin user for odoo service }
          - { name: odoo_ro ,password: DBUser.Odoo ,pgbouncer: true ,roles: [ dbrole_readonly ]  ,comment: read only user for odoo service  }
          - { name: odoo_rw ,password: DBUser.Odoo ,pgbouncer: true ,roles: [ dbrole_readwrite ] ,comment: read write user for odoo service }
        pg_databases:
          - { name: odoo ,owner: odoo ,revokeconn: true ,comment: odoo main database  }
        pg_hba_rules:
          - { user: all ,db: all ,addr: 172.17.0.0/16  ,auth: pwd ,title: 'allow access from local docker network' }
          - { user: dbuser_view , db: all ,addr: infra ,auth: pwd ,title: 'allow grafana dashboard access cmdb from infra nodes' }

    infra: { hosts: { 10.10.10.10: { infra_seq: 1 } } }
    etcd:  { hosts: { 10.10.10.10: { etcd_seq: 1 } }, vars: { etcd_cluster: etcd } }
    #minio: { hosts: { 10.10.10.10: { minio_seq: 1 } }, vars: { minio_cluster: minio } }

  vars:                               # 全局变量
    version: v3.7.0                   # pigsty 版本字符串
    admin_ip: 10.10.10.10             # 管理节点 ip 地址
    region: default                   # 上游镜像区域:default|china|europe
    node_tune: oltp                   # 节点调优规格:oltp,olap,tiny,crit
    pg_conf: oltp.yml                 # pgsql 调优规格:{oltp,olap,tiny,crit}.yml

    docker_enabled: true              # 在应用程序组上启用 docker
    #docker_registry_mirrors: ["https://docker.m.daocloud.io"] # 在中国大陆使用道云镜像
    proxy_env:                        # 下载包和拉取 docker 镜像时的全局代理环境
      no_proxy: "localhost,127.0.0.1,10.0.0.0/8,192.168.0.0/16,*.pigsty,*.aliyun.com,mirrors.*,*.tsinghua.edu.cn"
      #http_proxy:  127.0.0.1:12345 # 在此处添加代理环境以下载包或拉取镜像
      #https_proxy: 127.0.0.1:12345 # 通常代理格式为 http://user:[email protected]
      #all_proxy:   127.0.0.1:12345

    infra_portal: # 域名和上游服务器
      home         : { domain: h.pigsty }
      grafana      : { domain: g.pigsty ,endpoint: "${admin_ip}:3000" , websocket: true }
      prometheus   : { domain: p.pigsty ,endpoint: "${admin_ip}:9058" }
      alertmanager : { domain: a.pigsty ,endpoint: "${admin_ip}:9059" }
      blackbox     : { endpoint: "${admin_ip}:9115" }
      loki         : { endpoint: "${admin_ip}:3100" }
      minio        : { domain: m.pigsty    ,endpoint: "${admin_ip}:9001" ,scheme: https ,websocket: true }
      odoo         : { domain: odoo.pigsty, endpoint: "127.0.0.1:8069"   ,websocket: true }  #cert: /path/to/crt ,key: /path/to/key
      # 在这里设置您自己的域名 ^^^,或使用默认域名,或 ip + 8069 端口直接访问
      # certbot --nginx --agree-tos --email [email protected] -n -d odoo.your.domain    # 替换为您的邮箱和 odoo 域名

    #----------------------------------#
    # 凭据:更改这些密码
    #----------------------------------#
    #grafana_admin_username: admin
    grafana_admin_password: pigsty
    #pg_admin_username: dbuser_dba
    pg_admin_password: DBUser.DBA
    #pg_monitor_username: dbuser_monitor
    pg_monitor_password: DBUser.Monitor
    #pg_replication_username: replicator
    pg_replication_password: DBUser.Replicator
    #patroni_username: postgres
    patroni_password: Patroni.API
    #haproxy_admin_username: admin
    haproxy_admin_password: pigsty

    repo_modules: infra,node,pgsql,docker
    repo_packages: [ node-bootstrap, infra-package, infra-addons, node-package1, node-package2, pgsql-utility, docker ]
    repo_extra_packages: [ pg18-main ]
    pg_version: 18

基础

检查 .env 文件中的可配置环境变量:

# https://hub.docker.com/_/odoo#
PG_HOST=10.10.10.10
PG_PORT=5432
PG_USER=dbuser_odoo
PG_PASS=DBUser.Odoo
ODOO_PORT=8069

然后使用以下命令启动 odoo:

make up  # docker compose up

访问 http://ddl.pigsty 或 http://10.10.10.10:8887

Makefile

make up         # 在最小模式下使用 docker compose 启动 odoo
make run        # 使用 docker 启动 odoo,本地数据目录和外部 PostgreSQL
make view       # 打印 odoo 访问点
make log        # tail -f odoo 日志
make info       # 使用 jq 检查 odoo
make stop       # 停止 odoo 容器
make clean      # 移除 odoo 容器
make pull       # 拉取最新的 odoo 镜像
make rmi        # 移除 odoo 镜像
make save       # 保存 odoo 镜像到 /tmp/docker/odoo.tgz
make load       # 从 /tmp/docker/odoo.tgz 加载 odoo 镜像

使用外部 PostgreSQL

您可以为 Odoo 使用外部 PostgreSQL。Odoo 将在设置期间创建自己的数据库,因此您不需要这样做

pg_users: [ { name: dbuser_odoo ,password: DBUser.Odoo ,pgbouncer: true ,roles: [ dbrole_admin ]    ,comment: admin user for odoo database } ]
pg_databases: [ { name: odoo ,owner: dbuser_odoo ,revokeconn: true ,comment: odoo primary database } ]

并使用以下命令创建业务用户和数据库:

bin/pgsql-user  pg-meta  dbuser_odoo
#bin/pgsql-db    pg-meta  odoo     # odoo 将在设置期间创建数据库

检查连接性:

psql postgres://dbuser_odoo:[email protected]:5432/odoo

暴露 Odoo 服务

通过 nginx 门户 暴露 odoo Web 服务:

    infra_portal:                     # 域名和上游服务器
      home         : { domain: h.pigsty }
      grafana      : { domain: g.pigsty    ,endpoint: "${admin_ip}:3000" , websocket: true }
      prometheus   : { domain: p.pigsty    ,endpoint: "${admin_ip}:9058" }
      alertmanager : { domain: a.pigsty    ,endpoint: "${admin_ip}:9059" }
      blackbox     : { endpoint: "${admin_ip}:9115" }
      loki         : { endpoint: "${admin_ip}:3100" }
      odoo         : { domain: odoo.pigsty, endpoint: "127.0.0.1:8069", websocket: true }  # <------ 添加这一行
./infra.yml -t nginx   # 设置 nginx 基础设施门户

Odoo 插件

社区中有很多 Odoo 模块可用,您可以通过下载并将它们放在 addons 文件夹中来安装它们。

volumes:
  - ./addons:/mnt/extra-addons

您可以将 ./addons 目录挂载到容器中的 /mnt/extra-addons,然后下载并解压到 addons 文件夹,

要启用插件模块,首先进入 开发者模式

设置 -> 通用设置 -> 开发者工具 -> 激活开发者模式

然后转到 > 应用程序 -> 更新应用程序列表,然后您可以找到额外的插件并从面板安装。

常用的 免费 插件:会计套件


演示

查看公共演示:http://odoo.pigsty.io,用户名:[email protected],密码:pigsty

如果您想通过 SSL 访问 odoo,您必须在浏览器中信任 files/pki/ca/ca.crt(或在 chrome 中使用肮脏的黑客 thisisunsafe

反馈

19.5 - Dify

使用剧本设置 docker

Dify 是一个生成式 AI 应用创新引擎和开源 LLM 应用开发平台。它提供从 Agent 构建到 AI 工作流编排、RAG 检索和模型管理的能力,帮助用户轻松构建和运营生成式 AI 原生应用程序。

Pigsty 提供对自托管 Dify 的支持,允许您使用单个命令部署 Dify,同时将关键状态存储在外部管理的 PostgreSQL 中。您可以在同一个 PostgreSQL 实例中使用 pgvector 作为向量数据库,进一步简化部署。

Pigsty v3.7.0 内置 Dify v1.8.1 应用模板。


快速开始

在运行 兼容操作系统 的全新 Linux x86 / ARM 服务器上执行:

curl -fsSL https://repo.pigsty.cc/get | bash -s v3.7.0; cd ~/pigsty
./bootstrap                # 安装 Pigsty 依赖
./configure -c app/dify    # 使用 Dify 配置模板
vi pigsty.yml              # 编辑密码、域名、密钥等

./install.yml              # 安装 Pigsty
./docker.yml               # 安装 Docker 和 Compose
./app.yml                  # 安装 Dify

Dify 默认监听端口 5001。您可以通过浏览器访问 http://<ip>:5001 并设置您的初始用户凭据来登录。

Dify 启动后,您可以安装各种扩展、配置系统模型并开始使用它!


为什么要自托管

自托管 Dify 有很多原因,但主要动机是数据安全。Dify 提供的 DockerCompose 模板使用基本的默认数据库镜像,缺乏企业级功能,如高可用性、灾难恢复、监控、IaC 和 PITR 能力。

Pigsty 为 Dify 优雅地解决了这些问题,基于配置文件使用单个命令部署所有组件,并使用镜像解决中国地区访问挑战。这使得 Dify 部署和交付变得非常顺畅。它一次性处理 PostgreSQL 主数据库、PGVector 向量数据库、MinIO 对象存储、Redis、Prometheus 监控、Grafana 可视化、Nginx 反向代理和免费 HTTPS 证书。

Pigsty 确保所有 Dify 状态都存储在外部管理的服务中,包括 PostgreSQL 中的元数据和文件系统中的其他数据。通过 Docker Compose 启动的 Dify 实例成为可以随时销毁和重建的无状态应用程序,大大简化了运维。


安装

让我们从单节点 Dify 部署开始。我们稍后将介绍生产高可用部署方法。

首先,使用 Pigsty 的 标准安装过程 安装 Dify 所需的 PostgreSQL 实例:

curl -fsSL https://repo.pigsty.cc/get | bash -s v3.7.0; cd ~/pigsty
./bootstrap               # 准备 Pigsty 依赖
./configure -c app/supa   # 使用 Supabase 应用程序模板
vi pigsty.yml             # 编辑配置文件,修改域名和密码
./install.yml             # 安装 Pigsty 和各种数据库

当您使用 ./configure -c app/dify 命令时,Pigsty 会根据 conf/app/dify.yml 模板和您当前的环境自动生成配置文件。 您应该根据实际需要在生成的 pigsty.yml 配置文件中修改密码、域名和其他相关参数,然后使用 ./install.yml 执行标准安装过程。

接下来,运行 docker.yml 安装 Docker 和 Docker Compose,然后使用 app.yml 完成 Dify 部署:

./docker.yml              # 安装 Docker 和 Docker Compose
./app.yml                 # 使用 Docker 部署 Dify 无状态组件

您可以在本地网络上通过 http://<your_ip_address>:5001 访问 Dify Web 管理界面。

首次登录时会提示设置默认用户名、邮箱和密码。

您也可以使用本地解析的占位符域名 dify.pigsty,或按照下面的配置使用带有 HTTPS 证书的真实域名。


配置

当您使用 ./configure -c app/dify 命令进行配置时,Pigsty 会根据 conf/app/dify.yml 模板和您当前的环境自动生成配置文件。以下是默认配置的详细说明:

all:
  children:

    # dify 应用程序
    dify:
      hosts: { 10.10.10.10: {} }
      vars:
        app: dify   # 指定要安装的应用程序名称(在 apps 中)
        apps:       # 定义所有应用程序
          dify:     # 应用程序名称,应该有对应的 ~/pigsty/app/dify 文件夹
            file:   # 要创建的数据目录
              - { path: /data/dify ,state: directory ,mode: 0755 }
            conf:   # 覆盖 /opt/dify/.env 配置文件

              # 更改域名、镜像、代理、密钥
              NGINX_SERVER_NAME: dify.pigsty
              # 用于签名和加密的密钥,使用 `openssl rand -base64 42` 生成(更改密码!)
              SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
              # 默认使用端口 5001 暴露 DIFY nginx 服务
              DIFY_PORT: 5001
              # dify 文件存储位置?默认是 ./volume,我们将使用上面创建的另一个卷
              DIFY_DATA: /data/dify

              # 代理和镜像设置
              #PIP_MIRROR_URL: https://pypi.tuna.tsinghua.edu.cn/simple
              #SANDBOX_HTTP_PROXY: http://10.10.10.10:12345
              #SANDBOX_HTTPS_PROXY: http://10.10.10.10:12345

              # 数据库凭据
              DB_USERNAME: dify
              DB_PASSWORD: difyai123456
              DB_HOST: 10.10.10.10
              DB_PORT: 5432
              DB_DATABASE: dify
              VECTOR_STORE: pgvector
              PGVECTOR_HOST: 10.10.10.10
              PGVECTOR_PORT: 5432
              PGVECTOR_USER: dify
              PGVECTOR_PASSWORD: difyai123456
              PGVECTOR_DATABASE: dify
              PGVECTOR_MIN_CONNECTION: 2
              PGVECTOR_MAX_CONNECTION: 10

    pg-meta:
      hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
      vars:
        pg_cluster: pg-meta
        pg_users:
          - { name: dify ,password: difyai123456 ,pgbouncer: true ,roles: [ dbrole_admin ] ,superuser: true ,comment: dify superuser }
        pg_databases:
          - { name: dify ,owner: dify ,revokeconn: true ,comment: dify main database  }
        pg_hba_rules:
          - { user: dify ,db: all ,addr: 172.17.0.0/16  ,auth: pwd ,title: 'allow dify access from local docker network' }
        node_crontab: [ '00 01 * * * postgres /pg/bin/pg-backup full' ] # 每天凌晨 1 点进行完整备份

    infra: { hosts: { 10.10.10.10: { infra_seq: 1 } } }
    etcd:  { hosts: { 10.10.10.10: { etcd_seq: 1 } }, vars: { etcd_cluster: etcd } }
    #minio: { hosts: { 10.10.10.10: { minio_seq: 1 } }, vars: { minio_cluster: minio } }

  vars:                               # 全局变量
    version: v3.7.0                   # pigsty 版本字符串
    admin_ip: 10.10.10.10             # 管理节点 ip 地址
    region: default                   # 上游镜像区域:default|china|europe
    node_tune: oltp                   # 节点调优规格:oltp,olap,tiny,crit
    pg_conf: oltp.yml                 # pgsql 调优规格:{oltp,olap,tiny,crit}.yml

    docker_enabled: true              # 在应用程序组上启用 docker
    #docker_registry_mirrors: ["https://docker.1ms.run"] # 在中国大陆使用镜像

    proxy_env:                        # 下载包和拉取 docker 镜像时的全局代理环境
      no_proxy: "localhost,127.0.0.1,10.0.0.0/8,192.168.0.0/16,*.pigsty,*.aliyun.com,mirrors.*,*.tsinghua.edu.cn"
      #http_proxy:  127.0.0.1:12345 # 在此处添加代理环境以下载包或拉取镜像
      #https_proxy: 127.0.0.1:12345 # 通常代理格式为 http://user:[email protected]
      #all_proxy:   127.0.0.1:12345

    infra_portal: # 域名和上游服务器
      home         : { domain: h.pigsty }
      grafana      : { domain: g.pigsty ,endpoint: "${admin_ip}:3000" , websocket: true }
      prometheus   : { domain: p.pigsty ,endpoint: "${admin_ip}:9058" }
      alertmanager : { domain: a.pigsty ,endpoint: "${admin_ip}:9059" }
      blackbox     : { endpoint: "${admin_ip}:9115" }
      loki         : { endpoint: "${admin_ip}:3100" }
      #minio        : { domain: m.pigsty    ,endpoint: "${admin_ip}:9001" ,scheme: https ,websocket: true }
      dify:                            # dify 的 nginx 服务器配置
        domain: dify.pigsty            # 替换为您自己的域名!
        endpoint: "10.10.10.10:5001"   # dify 服务端点:IP:PORT
        websocket: true                # 添加 websocket 支持
        certbot: dify.pigsty           # certbot 证书名称,使用 `make cert` 申请

    #----------------------------------#
    # 凭据:更改这些密码
    #----------------------------------#
    #grafana_admin_username: admin
    grafana_admin_password: pigsty
    #pg_admin_username: dbuser_dba
    pg_admin_password: DBUser.DBA
    #pg_monitor_username: dbuser_monitor
    pg_monitor_password: DBUser.Monitor
    #pg_replication_username: replicator
    pg_replication_password: DBUser.Replicator
    #patroni_username: postgres
    patroni_password: Patroni.API
    #haproxy_admin_username: admin
    haproxy_admin_password: pigsty
    #minio_access_key: minioadmin
    minio_secret_key: minioadmin      # minio root 密钥,默认为 `minioadmin`

    repo_extra_packages: [ pg17-main ]
    pg_version: 17

检查清单

以下是您需要关注的配置项检查清单:

  • 硬件/软件:准备所需的机器资源:Linux x86_64/arm64 服务器,主流 Linux 操作系统 的全新安装
  • 网络/权限:SSH 免密登录访问权限,用户具有 免密 sudo 权限
  • 确保机器在内网中有静态 IPv4 网络地址且可访问互联网
  • 如果通过公网访问,确保您有可用的域名指向当前节点的 公网 IP 地址
  • 确保使用 app/dify 配置模板并根据需要修改参数
    • configure -c app/dify,并输入节点的内网主 IP 地址,或通过 -i <primary_ip> 命令行参数指定
  • 您是否修改了所有密码相关的配置参数?【可选】
  • 您是否修改了 PostgreSQL 集群业务用户密码和使用这些密码的应用程序配置?
    • 默认用户名 dify 和密码 difyai123456 是 Pigsty 为 Dify 生成的,请根据实际情况修改
    • 在 Dify 的配置块中,请相应修改 DB_USERNAMEDB_PASSWORDPGVECTOR_USERPGVECTOR_PASSWORD 等参数
  • 您是否修改了 Dify 的默认加密密钥?
    • 您可以使用 openssl rand -base64 42 随机生成密码字符串并填入 SECRET_KEY 参数
  • 您是否修改了 Dify 使用的域名?
    • 将占位符域名 dify.pigsty 替换为您的实际域名,例如 dify.pigsty.cc
    • 您可以使用 sed -ie 's/dify.pigsty/dify.pigsty.cc/g' pigsty.yml 修改 Dify 的域名

域名和 SSL

如果您想使用带有 HTTPS 证书的真实域名,需要在 pigsty.yml 配置文件中修改:

  • infra_portal 参数的 dify 域名
  • 最好指定一个邮箱地址 certbot_email 用于接收证书过期通知
  • 配置 Dify 的 NGINX_SERVER_NAME 参数来指定您的实际域名
all:
  children:                            # 集群定义
    dify:                              # Dify 组
      vars:                            # Dify 组变量
        apps:                          # 应用程序配置
          dify:                        # Dify 应用程序定义
            conf:                      # Dify 应用程序配置
              NGINX_SERVER_NAME: dify.pigsty

  vars:                                # 全局参数
    #certbot_sign: true                # 使用 Certbot 申请免费 HTTPS 证书
    certbot_email: [email protected]      # 证书申请邮箱,用于过期通知,可选
    infra_portal:                      # 配置 Nginx 服务器
      dify:                            # Dify 服务器定义
        domain: dify.pigsty            # 请在此处替换为您自己的域名!
        endpoint: "10.10.10.10:5001"   # 请在此处指定 Dify 的 IP 和端口(默认自动配置)
        websocket: true                # Dify 需要启用 websocket
        certbot: dify.pigsty           # 指定 Certbot 证书名称

使用以下命令申请 Nginx 证书:

# 申请证书,也可以手动执行 /etc/nginx/sign-cert 脚本
make cert

# 上述 Makefile 快捷命令实际执行以下剧本任务:
./infra.yml -t nginx_certbot,nginx_reload -e certbot_sign=true

执行 app.yml 剧本重新部署 Dify 服务以使 NGINX_SERVER_NAME 配置生效。

./app.yml

文件备份

您可以使用 restic 备份 Dify 的文件存储(默认位于 /data/dify 目录),使用以下命令进行备份:

export RESTIC_REPOSITORY=/data/backups/dify   # 指定 dify 备份目录
export RESTIC_PASSWORD=some-strong-password   # 指定备份加密密码
mkdir -p ${RESTIC_REPOSITORY}                 # 创建 dify 备份目录
restic init

创建 Restic 备份仓库后,您可以使用以下命令备份 Dify:

export RESTIC_REPOSITORY=/data/backups/dify   # 指定 dify 备份目录
export RESTIC_PASSWORD=some-strong-password   # 指定备份加密密码

restic backup /data/dify                      # 将 /dify 数据目录备份到仓库
restic snapshots                              # 查看备份快照列表
restic restore -t /data/dify 0b11f778         # 将快照 xxxxxx 恢复到 /data/dify
restic check                                  # 定期检查仓库完整性

另一种更可靠的方法是使用 JuiceFS 将 MinIO 对象存储挂载到 /data/dify 目录,这样您就可以使用 MinIO/S3 存储文件状态。

如果您想将所有数据存储在 PostgreSQL 中,请考虑"使用 JuiceFS 将文件系统数据存储在 PostgreSQL 中"

例如,您可以创建另一个 dify_fs 数据库并将其用作 JuiceFS 的元数据存储:

METAURL=postgres://dify:difyai123456@:5432/dify_fs
OPTIONS=(
  --storage postgres
  --bucket :5432/dify_fs
  --access-key dify
  --secret-key difyai123456
  ${METAURL}
  jfs
)
juicefs format "${OPTIONS[@]}"         # 创建 PG 文件系统
juicefs mount ${METAURL} /data/dify -d # 后台挂载到 /data/dify 目录
juicefs bench /data/dify               # 测试性能
juicefs umount /data/dify              # 停止挂载

参考

Dify 自托管常见问题