pg_durable:Microsoft 开源数据库内持久执行

概述

  • pg_durable 被视为 2026 年更广泛趋势的一部分,即“Postgres 作为队列/编排器”,与其他基于 PG 的作业/队列系统并列。
  • 讨论分成两派:一派对“把计算带到数据旁边”感到兴奋,另一派则强烈偏好将编排和业务逻辑放在应用代码中。

数据库内持久执行 vs 外部编排器

  • 支持者认为:如果 Postgres 是主要的有状态组件,把工作流保留在数据库内可以简化技术栈,避免额外基础设施(例如 Temporal、Airflow),降低延迟/往返次数,并且让数据库快照同时捕获数据和工作流状态。
  • 批评者认为:对于跨系统工作流,外部编排器和 DAG 调度器(Airflow、类似 Temporal 的系统)更合适;它们能让控制流保留在熟悉的语言和工具链中。

提到的用例与收益

  • 长时间运行/可恢复的工作流、ETL/AI 管道、具有 exactly-once 语义和检查点回放的类 cron 作业。
  • 能够在包含工作流的情况下恢复“某个时间点”的状态,这对与数据库状态紧密耦合的 ETL 和 AI 管道很有用。
  • 当 HTTP 调用和处理主要以数据为中心,并且已经以数据库为目标时,这种方式尤其有帮助。

担忧与批评

  • “闻起来像存储过程”:担心业务逻辑隐藏、可观测性差、扩展压力集中在数据库上、IO 和外部 API 集成有限。
  • 开发体验问题:SQL/DSL 语法别扭、调试困难、与主流语言和 CI/CD 流程相比工具不足。
  • 担心给本来就难以扩展的数据库再加上长时间运行的作业。

工具、版本管理与测试

  • 多条评论询问如何对持久函数进行版本管理、测试、调试和发布。
  • 有人认为所有数据库对象(函数、触发器)本来就应该纳入源代码管理和迁移;也有人说大多数团队并没有成熟的数据库工作流,因此把逻辑放在代码里更安全。

pg_durable 的行为方式(来自讨论串)

  • 工作流通过 df.start(...) 定义并启动,返回一个实例 ID。
  • df.wait_for_signal 只针对单个实例,并且在该实例内是“exactly once”;重复调用 df.start 会创建新的实例。
  • 超时和错误处理会以工作流状态和失败实例的形式暴露出来,但详细的错误语义对读者来说仍然有些不清楚。

元讨论:Postgres、扩展与 Rust

  • 关于 Postgres 是否足够可扩展的旁支讨论(许多人提到其丰富的扩展生态),以及是否应当用 Rust 重写并采用更模块化架构的呼声。
  • 有人认为数据库内编排是“内部平台效应”;也有人认为这只是对成熟、可扩展系统的一种务实复用。