v3.4:MySQL兼容与整体改进

经过一个月的密集开发,Pigsty v3.4 正式发布了!这次发布带来了一款新PG内核的支持,并进行了相当显著的架构优化,解决了一些客户与用户非常关心的问题:

  • 支持使用 MySQL 兼容的 openHalo 内核

  • 将一套集群的物理备份,PITR恢复到另一套集群

  • pgBackRest 备份组件的监控指标与面板

  • 想要自建应用,但 Certbot 申请证书太麻烦

  • 本地化排序规则与字符集的最佳实践

  • Oracle 兼容的 IvorySQL 现已全平台可用

  • 图数据库扩展 AGE 现已全平台可用

  • GitHub 发布页面:v3.4.0

  • GitHub 发布页面:v3.4.1

接下来,我们展开来聊一聊 Pigsty v3.4 引入的一些关键变化。


MySQL 兼容

在 Pigsty v3.4.1 中,我们引入了对 openHalo 的支持,这个内核在 PostgreSQL 14.10 的基础上,提供了 MySQL 线缆协议的兼容性。

这意味着 MySQL 用户可以在不改代码的情况下,从 MySQL 丝滑迁移到 PostgreSQL,你可以同时用 PG 和 MySQL 客户端连接到同一个数据库。

目前 Pigsty 提供了 openHalo 的 RPM 包,并且允许用户在安装时选择使用 openHalo 作为 PostgreSQL 内核,打造一个完整的 RDS 服务。

./configure -c mysql   # 使用 MySQL 兼容的 openHalo 配置模板

自动申请证书

最近,有不少用户是因为要自建 DifyOdooSupabase 而使用 Pigsty 的。 有人反馈说,证书申请的步骤看上去有点繁琐,还要 自己调用 certbot,有没有办法把这个东西给自动化掉?

于是在这个版本里,Pigsty 对 Nginx 的配置进行了加强,现在如果用户在某个 Nginx Server 上定义了 certbot 字段, 用户就可以使用 make cert 命令一键完成证书的申请与应用,不需要任何其他二次配置与命令了。

因此,在 Dify,Odoo,Supabase 这些应用自建模板中,都使用了这个新的功能, 当你完成安装后,make cert 就会自动更新或新申请所需的证书,如果你连这行命令都懒得敲,那么事先配置好 certbot_sign = true 就会直接安装过程中自动申请证书了。

除此之外,v3.4 中 Nginx 的可配置项目也更加丰富了,例如,你可以使用 confignginx 中注入配置,可以使用 enforce 来强制重定向 HTTPS。 如果你要自建一个网站,完全可以在绝大多数场景下做到根本不碰任何传统的 Nginx 配置,实现灵活的定制。

下面是 Pigsty 中文网站使用的配置样例,使用这个配置文件,我可以在几分钟内在世界的任何角落自建一个 Pigsty 文档/软件仓库站点。

    infra_portal:                     # domain names and upstream servers
      home         : { domain: home.pigsty.cc                                                 ,certbot: pigsty.demo }
      grafana      : { domain: demo.pigsty.cc ,endpoint: "${admin_ip}:3000", websocket: true  ,certbot: pigsty.demo }
      prometheus   : { domain: p.pigsty.cc    ,endpoint: "${admin_ip}:9090"                   ,certbot: pigsty.demo }
      alertmanager : { domain: a.pigsty.cc    ,endpoint: "${admin_ip}:9093"                   ,certbot: pigsty.demo }
      blackbox     : { endpoint: "${admin_ip}:9115"                                                               }
      loki         : { endpoint: "${admin_ip}:3100"                                                               }
      postgrest    : { domain: api.pigsty.cc  ,endpoint: "127.0.0.1:8884"                                         }
      pgadmin      : { domain: adm.pigsty.cc  ,endpoint: "127.0.0.1:8885"                                         }
      pgweb        : { domain: cli.pigsty.cc  ,endpoint: "127.0.0.1:8886"                                         }
      bytebase     : { domain: ddl.pigsty.cc  ,endpoint: "127.0.0.1:8887"                                         }
      jupyter      : { domain: lab.pigsty.cc  ,endpoint: "127.0.0.1:8888"   ,websocket: true                      }
      gitea        : { domain: git.pigsty.cc  ,endpoint: "127.0.0.1:8889"                     ,certbot: pigsty.cc }
      wiki         : { domain: wiki.pigsty.cc ,endpoint: "127.0.0.1:9002"                     ,certbot: pigsty.cc }
      noco         : { domain: noco.pigsty.cc ,endpoint: "127.0.0.1:9003"                     ,certbot: pigsty.cc }
      supa         : { domain: supa.pigsty.cc ,endpoint: "10.2.82.163:8000" ,websocket: true  ,certbot: pigsty.cc }
      dify         : { domain: dify.pigsty.cc ,endpoint: "10.2.82.163:8001" ,websocket: true  ,certbot: pigsty.cc }
      odoo         : { domain: odoo.pigsty.cc ,endpoint: "127.0.0.1:8069"   ,websocket: true  ,certbot: pigsty.cc }
      mm           : { domain: mm.pigsty.cc   ,endpoint: "10.2.82.163:8065" ,websocket: true                      }
      web.io:
        domain: en.pigsty.cc
        path: "/www/web.io"
        certbot: pigsty.doc
        enforce_https: true
        config: |
          # rewrite /zh/ to /
              location /zh/ {
                  rewrite ^/zh/(.*)$ /$1 permanent;
              }          
      web.cc:
        domain: pigsty.cc
        path: "/www/web.cc"
        domains: [ zh.pigsty.cc ]
        certbot: pigsty.doc
        config: |
          # rewrite /zh/ to /
              location /zh/ {
                  rewrite ^/zh/(.*)$ /$1 permanent;
              }          
      repo:
        domain: pro.pigsty.cc
        path: "/www/repo"
        index: true
        certbot: pigsty.doc

本地化排序

许多程序员对于 Locale/Collation 规则都不太了解,但它确实是一个相当重要的东西。 使用不当的 Collation 配置不仅可能带来几倍的性能损失,还可能导致数据不一致,甚至是数据丢失。 是的没有错,索引与排序规则紧密相关,Collation 不是什么无关紧要的配置。

关于这个主题,我强烈推荐感兴趣的朋友阅读 在 PG中的本地化排序规则 一文, 以及 PGCon.Dev 2024 Jeremy Schneider 的 PPT 分享: Collations from A to Z, Putting words in order without losing your mind or your data

作为一个摘要概括,最佳实践就是始终使用 CC.UTF-8 作为 Locale 排序规则。 其中,C 有最好的兼容性 —— 所有系统上都可以用,但它却少 Unicode 对于字符集的知识 —— 除了 ASCII 之外的字符,大小写之类的功能就失灵了! C.UTF-8C 的基础上实现了 Unicode 语义,更符合用户直觉,然而并非所有系统都默认支持它。 好在,PostgreSQL 17 的一个新特性是内置了对这两种 Collation 的支持,而不再依赖操作系统的 libc。

因此 Pigsty v3.4 也及时跟进并反映了这种最佳实践。 首先,所有 Locale 相关参数现在的默认值都统一使用 C(这里主要是 pg_lc_ctypes 发生变化,从 en_US.UTF-8 变为 C),这确保了你在任何系统里都能跑起来! 然后,在自动配置过程中,如果检测到 PG 版本 >= 17 或者操作系统明确支持 C.utf8 (反例:默认Debian,EL7,MacOS),就会将 Locale 配置为 C.UTF-8 获得更好的 Unicode 语义。

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

除非你的数据库密集地工作在某种特定语言排序场景,否则这样的默认值就是最佳实践。 你可以使用 PostgreSQL 提供的 COLLATION 语法方便的在查询/索引/列上指定与配置具体的其他排序规则,PG + ICU 总共支持 841 种排序规则,能满足用户对于排序最诡异的癖好了。


时间点恢复改进

时间点恢复是关系型数据库的核心功能,在以前,Pigsty 通过 pg-pitr 辅助用户执行半自动的 PITR。

而在在 Pigsty v3.4 中,对 PITR 的支持进行了显著的改进。例如,你现在可以很方便的从集中式备份仓库中选择任何一个备份进行恢复。

你可以使用更加 Ansible 原生的方式来实现这一点。 当你在 PG 集群上定义 pg_pitr 参数时, Pigsty 会自动生成用于恢复的 /pg/bin/pg-restore 命令,以及 /pg/conf/pitr.conf 配置文件

pg_pitr:
  cluster: pg-test              # 指定要恢复的集群名称
  type:   'default'             # default, immediate, time, lsn, xid, name, backup
  path:   '/pg/data'            # restore to which path? /pg/data by default
  time:   '2022-01-01T00:00:00' # if type = time
  lsn:    '0/1000000'           # if type = lsn
  xid:    '123456'              # if type = xid
  name:   'restore_point'       # if type = name
  backup: '20221108-105325F'    # if type = set
  action: 'promote'             # promote, pause, shutdown
  exclusive: false              # Stop just BEFORE the recovery target (xid,time,lsn) is reached?
  db_exclude: []                # Restore excluding the specified databases
  db_include: []                # Restore only specified databases
  link_map: {}                  # Restore with tablespace link map
  process: max                  # Number of parallel processes to use for restore (default to CPU count)

在执行 pg-restore 命令时,Pigsty 会自动暂停 Patroni 集群,关闭 PG,开始原地进行增量 PITR,恢复到指定位点的时候再拉起 PG。 这里比较好的一个改进是,如果你使用集中式备份仓库,你可以用别的集群备份来覆盖当前集群。

另外对于备份的监控,v3.4 引入了一个新的组件:pgbackrest_exporter,用于收集备份监控指标。同时,在 PGSQL PITR 监控面板上也会显示出当前的备份状态。 虽然在以前用户也可以通过 PGCAT Instance 直接查询 PGBackRest 的备份状态,但那里只有当前状态,没有历史记录,而这次的改进毫无疑问对于分析备份的状态非常有帮助。


扩展插件更新

在过去的几个版本中, Pigsty 主要关注 PostgreSQL 扩展生态,在持续一年的扩张中,我已经收录了 PG 生态中几乎所有能打的扩展 —— 数量高达 404 个。

不过,扩展突飞猛进摊大饼的阶段已经基本结束了因此,在最近的版本中,我将关注点重新放回到 Pigsty 的架构与基础设,在扩展上以巩固为主。

所以 v3.4 中只加入了一个新扩展 pgspider_ext,利用各种 FDW 实现多数据源查询。不过,Pigsty 维护的扩展中,有 28 个更新到了最新的版本。 此外,我们仔细梳理了一遍现有的扩展,修复了几个扩展的版本与 Bug。

其中最值得一题的是图数据库扩展 Apache AGE,该项目的开发者似乎被裁了,导致基本进入了无维护状态。作为发行版作者,我也只能尽自己最大的努力去为它 “续命” 了。 所以这次,我根据 Debian 上的 Patch,重新编译了 AGE 1.5.0 的 13 - 17 的扩展,终于补上了缺少很多 EL RPM 的遗憾。


异构风味的内核

在 Pigsty v3.4 中,更新了对 PolarDBIvorySQL,以及 Babelfish 最新版本的支持。

可喜可贺的是,继 PolarDB 之后,IvorySQL 第二个成为了在 Pigsty 支持的十大 Linux 发行版上可用的 PostgreSQL 内核,现在唯一的瑕疵就是 WiltonDB 不支持 Debian 了。

在这次更新中,我们与 IvorySQL 团队合作,改善了 Pigsty 与 IvorySQL 的集成与整合,除了扩展插件外,IvorySQL 4.4 的体验基本与 PostgreSQL 17.4 一致。

使用 IvorySQL (Oracle兼容模式)只需要修改以下四个参数即可简单实现:

pg_mode: ivory                                                 # 使用 IvorySQL 兼容模式
pg_packages: [ ivorysql, pgsql-common ]                        # 安装 IvorySQL 软件包
pg_libs: 'liboracle_parser, pg_stat_statements, auto_explain'  # 加载 Oracle 兼容扩展
repo_extra_packages: [ ivorysql ]                              # 下载 IvorySQL 软件包

当然这里我还要顺带批评下 PolarDB,打包 DEB 也不认真,打出来的 Debian 包 libicu 版本依赖写错了,根本装不上,让人感觉根本没测试过。 但好在他们的响应速度还是挺快的,本来我自己都魔改DEB包修完了,结果他们在我反馈这个问题之后很快就重新发布的 新的修复版本

与此同时,我们还将 Supabase 的模板更新到了最新版本,将分布式扩展 Citus 更新到了 13.0.2。 在接下来的版本中,我会关注专注 OLTP 性能的 OrioleDB 以及提供 MySQL 协议兼容性的 OpenHalo 内核。


基础设施强化

在 v3.4 中,我们更新了许多了 Infra 软件包的版本,新增了几个组件:

  • JuiceFS:将 S3/MinIO 挂载为本地文件系统
  • Restic:类似 pgBackRest,但是用于备份文件
  • TimescaleDB EventStreamer:用于抽取 TimescaleDB 超表的数据变更流

本来我计划在这个版本推出 JuiceFS 的 Beta 模块,不过时间有点赶,这个功能就留到下个版本了。

不过,在 Pigsty v3.4 中,上面这几个组件都会默认下载了,所以如果你想要使用,直接安装就行。

另外一个改变是,以下软件包现在额外添加到 Pigsty 默认的下载列表:

extra-modules: "docker-ce docker-compose-plugin ferretdb2 duckdb restic juicefs vray grafana-infinity-ds"

主要是我确实发现 Docker 用的人还是太多了,除了跑软件,主要是用来跑 pgAdmin,我想既然这样,干脆还是让 Docker 成为默认下载的一部分吧,不纠结那 100MB 了。


v3.5 特性展望

v3.5 的特性规划已经开始了,目前计划了以下几个功能:

pig 命令行一直说要把 Pigsty Playbook 精细管理给做进去,现在正好是时机了,我希望下个版本,用户可以告别直接执行 Anislbe Playbook,用一个 Go 命令行就能搞定一切。

然后是配置向导与 MCP Server。有不少用户反馈说 Pigsty 的配置文件有些复杂,能不能做一个 Vibe Config Wizard 之类的东西。 我想了想这个技术上不算太难,把文档当上下文喂进去,问几个问题,像 Cursor 一样现场改配置就行了。 当然,我还是希望能像原来 configure 脚本一样自动根据环境做一些判断,那么也许就需要一个 MCP server 来收集一些环境信息并修改配置了。

第三点也是拖了好久的特性,Docker 镜像。我准备在下个版本中做一个 Debian 12 x86/ARM 的 Pigsty Docker 版,有了 ARM 版,Mac笔记本本地就可以快速试用起来。

最后是两个新的 PG 内核,OrioleDB 和 openHalo,前者昨天刚发布了 Beta10,后者昨天刚开源,都是代码一丢啥也不管,还需要我自己打 DEB/RPM 包。 但我觉得这两个内核的特色应该有不少人喜欢:前者是 PG + 极致 OLTP 性能 + 无膨胀,后者是 PG + MySQL 线缆协议兼容。 不出意外的话,下个版本就能在 Pigsty 中看到这两个 PG 新内核了。

好的,以上就是 Pigsty v3.4 的新特性介绍,祝大家使用愉快~


v3.4.0 发布注记

新特性

  • 新增 pgbackrest 备份监控指标与面板
  • 丰富了 Nginx 服务器的配置项,支持自动化 Certbot 证书申请
  • 优先使用 PostgreSQL 自带的 C, C.UTF-8 本地化规则集
  • IvorySQL 4.4 全平台支持(RPM/DEB x x86/ARM)
  • 新增可用软件包:Juicefs, Restic, TimescaleDB EventStreamer
  • 图数据库扩展 Apache AGE 现提供 EL 上 PG 13-17 的完整支持
  • 优化 app.yml 剧本的使用体验,现在可以免配置拉起普通 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
  • WiltonDB 13.17

PostgreSQL扩展包

  • pgspider_ext 1.3.0 (new extension)
  • 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
  • fix ddl_historization ver 0.7 -> 0.0.7
  • fix pg_sqlog 3.1.7 -> 1.6
  • fix pg_random remove dev suffix
  • asn1oid 1.5 -> 1.6
  • table_log 0.6.1 -> 0.6.4

接口变更

  • 新增 Docker 参数:docker_data, 以及 docker_storage_driver by #521 by [@waitingsong]https://github.com/waitingsong)
  • 新增 Infra 参数: alertmanager_port,可指定 AlertManager 端口
  • 新增 Infra 参数:certbot_sign:是否在 Nginx 初始化时自动申请 Certbot 证书?默认为否
  • 新增 Infra 参数:certbot_email:使用 Certbot 申请证书时使用的 email
  • 新增 Infra 参数:certbot_options:使用 Certbot 申请证书时使用的额外参数
  • 从 IvorySQL 4.4 版本起调整了 IvorySQL 的默认二进制路径:/usr/ivory-4
  • pg_lc_ctype 与其他 Locale 相关参数默认值由 en_US.UTF-8 修改为 C
  • 对于 PG 17 ,如果使用 UTF8 编码和 C/C.UTF-8 Locale,则优先使用PG自带的本地化规则。
  • configure 现在会根据 PG 版本与环境是否支持 C.utf8,自动配置 locale 相关选项
  • 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-8, bento/rockylinux-9 作为 EL 的 Vagrant box 镜像
  • 新增 Alias:extra_modules ,包含额外的可选模块:
  • 调整 PGSQL Alias: postgresql, pgsql-main, pgsql-core, pgsql-full
  • 仓库:Gitlab 仓库现已加入可用模块列表
  • 仓库:Docker 模块现已合并入 Infra 模块中
  • node.yml 剧本新增了 node_pip 任务,将 pip 镜像站写入节点 pip 配置
  • pgsql.yml 剧本新增了 pgbackrest_exporter 任务,收集备份监控指标
  • 允许在 Makefile 中使用 META/PKG 环境变量
  • 新增了 /pg/spool 目录用于 pgBackrest 临时文件存储
  • pgBackRest 的 link-all 选项默认关闭
  • 对于 MinIO 备份仓库,现在默认启用块增量备份模式`

缺陷修复

  • 修复 pg-backup 返回状态码:#532 by [@waitingsong]https://github.com/waitingsong)
  • pg-tune-hugepage 中设置只允许 PG 使用大页 #527 by [@waitingsong]https://github.com/waitingsong)
  • 修复 pg-role 中的问题逻辑
  • 修复 hugepage 配置参数类型转换问题
  • 修复 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
最后修改 2025-04-04: add openhalo (053a5b8)