>_ DevTrendszh

语言

首页

语言

板块

前端 后端 移动端 DevOps AI / ML 游戏开发 区块链 嵌入式 安全
Rust

如何让 PostgreSQL 在重启后继续完成后台任务

想象这样一个场景:你正在编写一个复杂的数据处理工作流。你需要获取记录、将其发送到外部 API、更新数据库中的状态,然后启动报告生成。如果数据库"崩溃"或服务器在工作流执行中途重启,标准的 PL/pgSQL 过程将直接中止。结果是"悬空"数据和令人头疼的问题:你如何确定一切停在了哪个阶段,又如何安全地重新启动?

通常我们通过变通方案来解决这个问题。我们设置 1、创建带有任务队列的表、用 Python 或 Go 编写不断轮询数据库的工作进程。在最糟糕的情况下,我们会引入像 Temporal 或 Airflow 这样的重量级工具。但微软的工程师们认为所有这些都是不必要的复杂性,于是发布了 pg_durable 扩展。

为什么开发者需要这个

该项目的核心思想是赋予 PostgreSQL 执行长时间运行的、能够抵御故障的函数的能力。用作者的话说,这被称为"持久执行"(Durable Execution)。

pg_durable logo

如果你的工作流是通过 pg_durable 定义的,数据库会在每个步骤后保存其状态。如果服务器在执行重查询或 API 调用时重启,扩展将从最后一个成功的检查点恢复任务。你不再需要将 cron 任务、工作进程和状态表粘合在一起。

底层原理

该项目使用 pgrx 用 Rust 编写。从架构上讲,它不仅仅是一个包装器,而是一个位于数据库内部的完整执行环境。它由几个层次组成:

  1. SQL DSL:用于描述任务图的一组运算符。
  2. Background Worker:Postgres 内部管理执行的后台进程。
  3. Duroxide:一个编排引擎(同样是微软的开发),负责确定性重放和检查点。

有趣的是,作者选择了"SQL 原生"的方法。你可以直接在控制台或迁移中描述逻辑,使用 2 或 3 这样的特殊运算符。

Workflow graph example

主要功能

以下三个特性真正简化了你的生活。

无需外部服务的容错能力

你不需要 Redis 做队列,也不需要单独的 Temporal 实例。一切都位于 4 和 5 表中。数据和控制在同一个事务环境中。这消除了经典的分布式系统问题——任务存在于队列中,但数据库中的更改尚未提交。

并行执行和合并

使用运算符,你可以轻松地将任务执行"分叉"成多个并行流,然后等待它们完成。README 中有一个清晰的示例:同时统计用户、订单和收入,然后将所有内容合并到一个报告步骤中。

与外部系统集成

扩展有一个 6 函数。这意味着你可以直接从长时间运行的进程中调用外部微服务或神经网络 API。如果 API 返回 500 错误,pg_durable 可以等待并重试,而不会阻塞整个数据库的运行。

代码示例

以下是在 SQL 中直接创建简单任务的样子:

0

这段代码将创建一个保证会执行的 Workflow 实例。如果 UPDATE 失败,系统将准确知道它正在尝试处理哪条 7 数据。

适用场景

我看到了几个 pg_durable 可以为你节省大量时间的场景。

首先是AI 管道。如果你需要通过嵌入模型运行数千行数据并保存到 8,这是理想的工具。文本分块、OpenAI API 调用和数据库 upsert 被打包成一个可靠的管道。

其次是大规模数据处理(ETL)。你可以将工作分解成带有检查点的小步骤,而不是编写在 WAL 用尽时会崩溃的大型 PL/pgSQL 过程。

第三是管理自动化。例如,检查表膨胀、发送通知并等待批准——所有这些都可以描述为 Durable Function。

细节和限制

该项目处于预览状态。这意味着现在投入生产还为时过早,但它非常适合内部工具。

重要的限制:你需要 PostgreSQL 17 或 18。如果你使用的是旧版本,则需要升级。另一个问题是安全性。默认情况下,9 中所有函数的设置都需要超级用户权限,尽管开发人员为常规角色提供了通过 10 的权限系统。

系统针对 SQL 进行了优化。如果你需要用 Python 或 Node.js 处理带有复杂循环的复杂业务逻辑,最好直接从应用程序代码中使用 Duroxide 引擎。pg_durable 专门用于将计算保持在尽可能接近数据的位置。

微软正在积极投资 Postgres(还记得 Citus 收购吗),pg_durable 是将数据库转变为完整应用平台的又一步。如果你厌倦了后台任务在最不方便的时刻"掉线",或者厌倦了为简单管道配置外部编排器,一定要看看这个仓库。要开始使用,简单的 Docker 容器或 Codespaces 就足够了,仓库的 Development 选项卡中已经配置好了。

相关项目