今天,我们很高兴地宣布 PostgreSQL 14 在 Azure 的超大规模 (Citus) 选项上的通用可用性 (GA)。 据我们所知,这是主要云提供商第一次在正式发布后的一天宣布在其平台上发布新的 Postgres 主要版本的 GA。
从今天开始,您可以在许多超大规模 (Citus) 区域部署 Postgres 14。 在接下来的几个月中,我们将在更多 Azure 区域推出 Postgres 14,并在 Azure Database for PostgreSQL 中使用我们新的灵活服务器选项发布它。
随着新功能的推出,此公告可帮助我们将最新的 Postgres 带给 Azure 客户。 此外,它表明了我们对开源 PostgreSQL 及其生态系统的承诺。 我们选择扩展 Postgres 并分享我们的贡献,而不是在云上创建和管理专有分支。

在这篇博文中,您将首先了解 Postgres 14 中我们最喜欢的一些特性。这些特性包括连接扩展、更快的 VACUUM 以及对崩溃恢复时间的改进。
然后,我们将描述使 Postgres 扩展与新的主要 Postgres 版本兼容所涉及的工作,包括我们的分布式数据库 Citus 以及其他扩展,例如 HyperLogLog (HLL)、pg_cron 和 TopN。最后,您将了解打包、测试和部署如何在超大规模 (Citus) 上工作。最后一部分将所有内容联系在一起,使我们能够在 Azure 上快速发布新版本。
- PostgreSQL 14 中最喜欢的新特性
- 使 Citus 和其他扩展与 PostgreSQL 14 兼容
- 超大规模(Citus)——发布新的 PostgreSQL 版本
PostgreSQL 14 中最喜欢的新特性
PostgreSQL 的每个主要版本都带来了新功能。本次发布也不例外。 PostgreSQL 14 在性能、数据类型、数据库管理、复制和安全性方面带来了新的改进。您可以在此处阅读功能亮点和完整的发行说明。
对于我们微软来说,迄今为止最令人兴奋的改进是在更好的连接扩展方面的工作。通过这些更改,Postgres 14 为需要大量数据库连接的应用程序带来了显着改进。 Postgres 连接模型为每个连接使用一个进程。这种模型有好处,但也会在高连接数时引入开销。在此版本中,扩展活动和空闲连接的效果明显更好。
我们分析了 Postgres 中的连接扩展瓶颈,并将快照可扩展性确定为主要瓶颈。 (Postgres 使用快照来识别在创建快照时哪些事务正在运行。这允许语句决定由其他事务创建的哪些行应该可见,哪些不可见。)在确定了这个瓶颈之后,我们的团队提交了一系列更改提高 Postgres 中的快照可扩展性。这些变化反过来显着改善了连接扩展特性,特别是当其中许多连接处于空闲状态时。
您可以在此处阅读有关与快照可扩展性和相关补丁相关的 3 个特定瓶颈的更多信息,以克服它们。我们使用只读 pgbench 基准测试在 Azure F72s v2 上测试了这些更改,并看到了以下好处。其他人也研究了这些变化并报告了他们的发现。

图 1:基准测试结果(只读 pgbench),显示快照可扩展性改进的效果
除了连接扩展之外,我们对其他两项有助于我们改善您的 Postgres 体验的贡献感到兴奋。首先,我们一直听说碰撞恢复时间和 VACUUM 速度是潜在的改进领域。在 Postgres 14 中,我们对受 CPU 约束的某些工作负载进行了更改,将崩溃恢复速度提高了 2.4 倍,将 VACUUM 时间提高了 25%。所有这些改进都来自 400 行代码。
其次,Postgres 在崩溃恢复开始时打开并 fsyncs 它拥有的每个文件。使用 recovery_init_sync_method 设置,Postgres 可以要求 Linux 在恢复开始之前同步数据和 WAL 目录中的所有文件。这允许在具有许多数据库文件的系统上进行更快的崩溃恢复。
使 Citus 和其他扩展与 PostgreSQL 14 兼容
PostgreSQL 的定义特征之一是它的可扩展性。通过编写 Postgres 扩展,开发人员可以添加新的数据库功能,而无需从原始项目分叉。
PostgreSQL 扩展由两部分组成:一组 SQL 对象(例如元数据表、函数、类型)和加载到 PostgreSQL 中的共享库。 PostgreSQL 中的所有数据库模块都是可扩展的,除了解析器。这主要是因为解析器代码是在构建时生成的,而扩展基础设施在运行时加载共享库。保持解析器不可扩展还强制扩展之间的句法互操作性。
在 Microsoft,我们开发和维护了几个开源扩展,包括 Citus、pg_cron、HLL (HyperLogLog) 和 TopN。在这些扩展中,Citus 是最复杂的一个。它扩展了 PostgreSQL 以包括一个分片层、一个分布式查询计划器和执行器、分布式事务和弹性横向扩展逻辑。为了提供这些功能,Citus 以 3 种方式广泛利用 Postgres API。
- 公开记录的扩展 API:使用这些 API,开发人员可以编写新的数据类型、运算符、函数、索引、后台工作者等。大多数扩展只使用这些 API。例如,Citus 客户通过调用 SELECT create_distributed_table(‘table_name’, ‘distribution_column’); 创建一个分布式表。为了启用此逻辑,Citus 使用用户定义的 API。
- 代码内扩展挂钩:挂钩是记录在代码中的全局函数指针。通过这些钩子,开发人员可以扩展规划器、执行器、表访问方法、事务逻辑等。例如,在解析任何不通过常规规划器的命令后调用实用程序挂钩。 Citus 使用这个钩子在分布式表上运行 DDL 和 COPY 命令。
- 代码内公共函数:扩展还可以通过包含相关的头文件来使用 Postgres 中的公共函数。这些函数为 Citus 等分布式数据库提供了巨大的优势。 Citus 可以只依赖 Postgres,而不是实现新功能。例如,Postgres 生成一个查询树来保存 SQL 语句的内部表示。 Citus 然后使用 Postgres 函数来复制、遍历或操作部分查询树结构。
对于每个新的 PostgreSQL 版本,上述任何集成点都可能发生重大更改。使扩展与 Postgres 版本兼容的过程是合并对这些集成点的更改。例如,在 PostgreSQL 14 中,实用程序挂钩的签名更改为包含一个新参数。因此,我们必须合并此更改,如下所示。您还可以在此拉取请求中阅读 Postgres 14 集成的完整更改集。

图 2:显示 Citus 中示例更改的代码差异,以支持 Postgres 14 中的 API 更改
多年来,我们开发了一种使扩展与新 PostgreSQL 版本兼容的流程。对于 Citus,这个过程可以概括为三个高级步骤。
- 我们解决了扩展源代码中的重大更改。在这一步之后,可以针对新的 PostgreSQL 版本编译源代码。
- 我们回顾了新的 PostgreSQL 特性。这涉及查看 PostgreSQL 的发行说明。对于与扩展相关的每个更改(例如新功能),如果需要,请在扩展的源代码中解决它。
- 我们通过我们的测试管道运行这些更改并修复失败的测试。
这第三步通常花费最多的时间,涉及以下内容:
- 持续集成 (CI):这些测试为我们提供了 95% 的代码覆盖率,并行运行大约需要 5 分钟。它们包括四大类:(a) PostgreSQL 测试套件,(b) 验证基本和复杂 SQL 输出的回归测试,© 强调并发会话行为的隔离测试,以及 (d) 执行失败的失败测试(对于例如,网络故障)。这些测试针对不同版本的 Postgres 和 Citus 运行。
- 性能、规模和内存测试:这些公开可用的测试以各种规模运行标准基准。我们还运行 Valgrind 作为我们的动态分析工具来检测任何内存管理错误。如果在这些自动化测试期间出现任何问题,我们会修复它们。由于这些测试需要很长时间才能运行,因此我们每周运行一次。
- 发布测试:包括为 Postgres/Citus 运行升级测试;针对外部工具进行测试的集成测试;静态分析工具;并通过 SQLancer/SQLsmith 等工具进行模糊测试以查找逻辑错误。这里的大多数测试都是自动化的,但需要开发人员解释测试结果。此步骤最多需要一周时间才能完成。
一旦我们创建了新的扩展包,Hyperscale (Citus) 就可以开始使用它们。
超大规模(Citus)——发布新的 PostgreSQL 版本
通过对 PostgreSQL 的深入了解并对其进行扩展,我们可以尽早为您提供新版本。通过利用超大规模 (Citus) 中的两个最佳实践,我们可以在主要版本发布后的一天内使 PostgreSQL 14 在 Azure 上普遍可用。
第一个最佳实践是超大规模(Citus)的控制平面和数据平面之间的职责分离。在我们的架构中,控制平面负责管理 Postgres/Citus 数据库的业务逻辑。此逻辑包括定期运行状况检查、高可用性和故障转移、备份和恢复、只读副本、定期维护操作等。数据平面单独负责运行数据库。因此,数据平面几乎不包含除了库存 PostgreSQL 及其扩展之外的任何其他内容。

图 3:显示控制平面和数据平面的超大规模 (Citus) 架构图。数据平面运行现有的 PostgreSQL、扩展和一些实用工具(例如,用于备份/恢复)。这允许在发布新的 Postgres 和扩展版本时快速迭代
控制平面和数据平面之间的这种分离使我们能够轻松地将新的 PostgreSQL 版本安装到数据平面节点。剩下的工作是确保新的 PostgreSQL 版本与控制平面的业务逻辑保持兼容。由于两个原因,此步骤通常很简单。首先,控制平面被设计为使用公共 PostgreSQL 公共接口——而 PostgreSQL 开发社区通常会注意避免向后不兼容的更改。其次,Postgres 的开发是公开进行的,因此我们可以尽早为任何重大变化做好准备。
在我们进行更改以支持新的 PostgreSQL 版本之后,超大规模 (Citus) 的第二个最佳实践开始发挥作用:测试。我们的第一道防线是单元测试(模拟测试)。我们使用单元测试来获得有关我们更改的快速反馈,并且我们经常运行它们。我们的单元测试在大约 2 分钟内运行,并为我们提供了 100% 的控制平面代码覆盖率。所有针对 Hyperscale (Citus) 的新拉取请求都需要运行单元测试并保持 100% 的覆盖率。
在单元测试中,许多调用都是模拟的。这可以实现快速反馈,但不能提供良好的端到端视图。我们测试管道的第二步是端到端 (E2E) 测试。这些测试涵盖了常见场景,例如配置、高可用性和故障转移、通过分片重新平衡器向外扩展等。通过这些测试,我们可以测试每个组件与其他组件的交互。
在代码审查、单元测试和 E2E 测试之后,推出新的主要 PostgreSQL 版本的下一步是部署。为此,我们需要刻录两个机器映像。第一个图像,用于控制平面的图像,包括我们需要进行的所有托管服务更改以适应新的 PostgreSQL 版本。第二个图像,用于数据平面的图像,包含库存 PostgreSQL/Citus 二进制文件和一些帮助脚本。使用这些映像,我们可以开始将新的有效负载部署到所有 Azure 区域。
Azure 区域部署涉及第三系列测试。在部署期间,我们根据安全部署实践遵循特定规则和部署顺序。根据这些实践,新的有效负载首先进入暂存环境,然后进入 Azure 早期更新访问计划 (EUAP) 区域,最后进入剩余的生产区域。在每个新区域中,更改都会等待一定的烘焙期。在每个区域的烘烤期间,我们的自动化测试会运行某些场景以进行验证。这些综合生成的测试包括 Citus 配置、升级、纵向扩展/横向扩展、时间点恢复、故障转移等。如果其中任何一个场景失败,我们会停止部署以进行调查并在需要时回滚。

图 4:Azure 安全部署实践。 新的变化会经历各个阶段,在每个阶段都会监控健康指标以触发自动操作和警报
幸运的是,我们的团队还自动化了部署过程。 在为及时发布新的 PG 版本而构建流程进行了所有艰苦的工作之后,我们的团队所要做的就是单击一个按钮——部署就被触发了。 我们所有的工作都得到了回报,并且在 Postgres 14 首次发布后的一天内,您就可以在 Azure 上使用它。
如果您想在云上横向扩展 Postgres 14,您可以访问 Azure 门户并立即启动一个新的超大规模 (Citus) 集群。 如果您已经在 Postgres 12 或 13 上运行集群,您现在也可以对集群进行主要版本升级!

图 5:创建超大规模 (Citus) 服务器组时 Azure 门户配置流程的屏幕截图,突出显示 PostgreSQL 版本 14 现在可用。
欢迎来到 Postgres 14
总之,我们很高兴在 Postgres 14 正式发布后的一天内宣布 Azure 上的 Postgres 14 全面上市 (GA)。 该公告是我们对开源的承诺、我们决定扩展 Postgres 而不是分叉它的结果,以及我们为改进我们的自动化测试基础架构以实现更可靠的软件所做的努力的积累。
与每个产品一样,我们还有很多需要改进的地方。 所以,请试试我们,让我们知道您的想法。
Postgres、PostgreSQL 和 Slonik 徽标是加拿大 PostgreSQL 社区协会的商标或注册商标,并经其许可使用。
原文标题:How We Shipped PostgreSQL 14 on Azure Within One Day of its Release
原文作者:Ozgun Erdogan
原文地址:https://techcommunity.microsoft.com/t5/azure-database-for-postgresql/how-we-shipped-postgresql-14-on-azure-within-one-day-of-its/ba-p/2801300




