一个长任务跑到一半,Postgres 重启了。已经处理完的 batch 算不算数?失败的外部 API 调用怎么补?状态表、重试计数、队列 worker、cron 脚本,到底谁说了算?

Microsoft 开源的 pg_durable,就盯着这个缝隙下手:既然很多团队的状态已经在 Postgres 里,那就把长任务的编排、checkpoint、崩溃后续跑,也放进 Postgres。

这不是成熟企业级产品。项目状态是 Preview。真正该看的,也不是“数据库又多了一个扩展”,而是它把编排器、队列和状态表收回数据库后,到底少了多少胶水,又给主库加了多少责任。

pg_durable 解决的是长任务续跑,不是普通 SQL

pg_durable 是一个 PostgreSQL 扩展。安装后,可以用 SQL DSL 定义工作流图,再用 df.start(...) 启动。

它的核心动作是 checkpoint。步骤之间的状态会持久化。数据库崩溃、重启,或者某个步骤失败后,任务可以从上一个 checkpoint 附近继续,而不是把整条长链路推倒重来。

它对标的不是 SELECTINSERT 这种普通 SQL。

它对标的是工程里常见的几套拼装:

现有做法pg_durable 想收掉的部分现实代价
pg_cron + jobs 表调度、状态、进度追踪逻辑散在表和脚本里
队列 + worker后台执行、失败恢复多一套服务和部署面
Airflow / Temporal / Step Functions贴着 Postgres 的轻量编排外部编排与库内状态容易割裂
plpgsql 过程避免一次长事务扛到底可恢复性和可观察性有限

它瞄准的场景也很具体:embedding / AI 数据管道、批量 ingest、维护 runbook、并行聚合、外部 API 调用。

比如文档分块,调用 embedding API,再写回 pgvector。或者把一批数据 stage、去重、转换、发布。输入在库里,输出也在库里,中间状态还在库里。

这时 pg_durable 的吸引力就出来了:不再为了一个贴着 Postgres 的任务,硬拉一套外部编排系统。

但安装门槛不能轻描淡写。当前包面向 PostgreSQL 17 / 18,需要配置 shared_preload_libraries,重启 PostgreSQL,创建扩展,还要处理后台 worker 和权限。

对 PostgreSQL DBA / SRE 来说,这意味着它不是“开发随手装个插件”。它会进入变更窗口、权限审查、扩展升级、worker 监控和故障预案。能不能用,先看你们有没有资格和能力动这台库。

真正的价值:状态在库里时,少一层系统

我比较买账的一点是:pg_durable 没有假装发明工作流。它承认了一个老事实——很多后台任务的状态、输入、输出、审计,本来就在 Postgres。

这时外面再套队列、worker、编排器,常常不是架构优雅,而是胶水增殖。

数据在库里。状态在 jobs 表里。执行在 worker 里。重试策略在代码里。监控再另起一套。

最后最难回答的问题反而最朴素:这件事做到哪一步了?

pg_durable 的价值就在这里。把计算贴近数据,把工作流状态放回同一套备份、权限、查询和审计体系里。

这对两类人影响最直接。

角色可能怎么做先别急着做什么
后端 / 数据工程师用它替代自制 jobs 表、轮询 worker、简单 runbook 编排不要把复杂跨系统业务流硬塞进 SQL DSL
PostgreSQL DBA / SRE评估 worker、WAL、锁、权限、扩展升级和主库负载不要让 Preview 扩展直接接管关键生产链路

对后端和数据工程师,它像是少写一堆重复胶水。尤其是 AI 数据管道这类任务:读库、调外部 API、写回库、记录进度。过去常见做法是 jobs 表加 worker,再手写重试和幂等。

pg_durable 至少给了一个更贴近数据库的选择。

对 DBA 和 SRE,它不是省事,而是换一种麻烦。外部 worker 少了,数据库内部职责多了。后台 worker 怎么跑,失败怎么观测,权限怎么收,主库压力怎么隔离,都要提前算。

有点像早期铁路公司自己修电报线。不是因为电报新潮,而是调度必须贴着轨道。工作流也一样:任务主要围着 Postgres 转,编排离数据越远,事故边界越多。

这个类比不完全一样。今天的软件系统比铁路调度更松散,也更容易跨云、跨 SaaS、跨消息系统。但重复的是同一种权力结构:谁掌握状态,谁就掌握恢复和追责。

边界更关键:Preview、SQL-shaped、主库负载

pg_durable 的边界要说硬一点。

它不适合单条 SQL。一个 INSERT ... SELECT 能解决的事,不该拆成工作流。

它也不适合低延迟同步请求。durable background execution 不是毫秒级在线接口。

更重要的是,它不适合复杂异构系统里的大业务流。如果任务主要在 SaaS、消息总线、对象存储、外部 SDK、应用内存状态之间跑,Temporal、Airflow 或云编排器仍然更合适。

pg_durable 的形状是 SQL-shaped。能映射成 SQL steps、分支、循环、HTTP 调用,它才舒服。映射不进去,就不要硬拧。

还有一个目前看不清、但最该观察的变量:失败语义。

Preview 阶段,不能只看“能 checkpoint”。更要看这些问题:

  • 重试策略能不能精细配置;
  • 外部 API 调用如何避免重复副作用;
  • worker 崩溃后状态如何恢复;
  • 权限、RLS、worker role 能不能在多用户环境里讲清楚;
  • checkpoint、队列状态和日志会给 WAL、锁、连接带来多大压力。

这些不是文档边角料。它们决定 pg_durable 是可控工具,还是一颗装进主库的隐形炸点。

“天下熙熙,皆为利来。”架构也一样。少一个服务,是利;数据库多背一层职责,是价。

所以我愿意给一个正面但克制的判断:pg_durable 值得后端、数据工程师和 PostgreSQL DBA / SRE 关注,尤其适合“状态已经在 Postgres,任务也围着 Postgres 转”的团队。

但它不该被吹成 Temporal 杀手,也不该被简单骂成数据库滥用。

接下来最该观察的不是口号,而是三件事:Preview 到稳定版的节奏,失败和重试语义是否足够清楚,生产环境里对主库负载和权限边界的处理是否可靠。

用对地方,它切掉胶水。用错地方,它会把主库改造成半个应用服务器。

那就不是减法了。只是把复杂度换了个房间。