← 返回信息流
AI 资讯Hacker News·1 小时前

微软开源 pg_durable:实现数据库内持久化执行

原标题:pg_durable: Microsoft open sources in-database durable execution

速览

微软近日开源了 pg_durable 项目,旨在为数据库应用提供持久化执行能力。该技术允许开发者在数据库内部可靠地运行长时间任务,无需依赖外部编排系统。此举有助于简化分布式事务处理,提升应用的容错性和开发效率。

AI 深度解读

pg_durable:微软将持久化执行引入 PostgreSQL

背景

在数据工程和 AI 管道开发中,团队通常需要在 PostgreSQL 中管理状态,同时依赖外部组件(如 cron 任务、工作进程、消息队列和状态表)来确保后台任务的可靠性。这种“拼凑”式的架构不仅增加了运维复杂度,还引入了脆弱性。例如,长事务会持有锁并导致 WAL(Write-Ahead Log)增长,使得批量作业在大规模下变得不稳定;而并行工作在应用层处理则容易引发部分失败和状态漂移。此外,一旦数据库崩溃或重启,之前已成功的部分工作往往需要重新运行,导致人工清理和不确定性的重放。

为了解决这一痛点,微软开源了 pg_durable。该项目旨在将“持久化执行”(Durable Execution)这一行业标准模式直接带入 PostgreSQL 内部,无需额外的服务基础设施。其核心理念是“将计算靠近数据”,让工作流逻辑以 SQL 原生方式定义,并由数据库本身负责状态的检查点保存与恢复。

核心内容

pg_durable 是一个 PostgreSQL 扩展,它允许用户定义由 SQL 步骤组成的有向无环图(DAG)工作流。PostgreSQL 在执行这些步骤时会进行持久化检查点。如果数据库崩溃、重启或某个步骤失败,执行将从最后一个持久化检查点恢复,而非从头开始。

适用场景与目标用户

  • 后端与数据工程师:希望工作流与其操作的数据紧邻,避免跨系统维护状态。
  • DBA 与 SRE:需要自动化运行手册(Runbooks),确保流程在重启后存活且可在 SQL 中审计。
  • 数据/AI 管道团队:需要针对每一行、每个文档或每个批次实现持久化执行。

典型用例

  • 向量嵌入管道:分块数据 -> 调用嵌入 API -> 使用 pgvector 进行 upsert。
  • 数据摄入管道:暂存、去重、转换并发布大批量数据。
  • 计划维护:检测膨胀 -> 通知 -> 等待审批 -> 执行下一步。
  • 扇出聚合:并行运行独立查询,然后连接结果。
  • 外部 API 工作流:从 SQL 内部执行丰富化、分类和 Webhook 风格调用。

与传统方案的对比

  • 替代 pg_cron + 状态表:无需手动管理重试计数器、状态列和轮询工作进程。
  • 替代外部编排器:无需引入 Airflow、Temporal、Step Functions 或 Argo 等重型外部服务。
  • 替代队列+Worker+状态表:消除了协调重试和部分完成所需的复杂队列和状态表。
  • 替代 plpgsql 过程:解决了长事务或崩溃导致必须重头开始的问题。

技术实现与工作流定义

工作流定义以 SQL 形式呈现,使用组合操作符(如 ~>|=>)。

  1. 定义:使用组合操作符定义步骤。
  2. 启动:通过 df.start() 启动工作流并返回实例 ID。
  3. 执行:运行时在每个步骤之间进行持久化检查点。
  4. 监控:在运行期间或完成后,通过查询 PostgreSQL 表(如 df.instances)获取状态和结果。

代码示例:

SELECT df.start(
    'SELECT id FROM documents WHERE processed = false LIMIT 100' |=> 'batch'
    ~> 'UPDATE documents SET processed = true WHERE id = ANY($batch)'
);

限制与边界

pg_durable 故意采用 SQL 形状的设计。以下场景不适合使用:

  • 需要亚毫秒级同步请求处理。
  • 无法安装扩展或运行后台工作进程的环境。
  • 工作流主要位于 PostgreSQL 外部且跨越多个异构系统。
  • 需要任意应用逻辑(非 HTTP SDK、非 SQL 映射的控制流)。

对于需要任意代码的步骤,建议将其封装为 SQL 函数,或通过 df.http() 暴露为 HTTP 端点,或将该部分逻辑交给通用编排器处理。

安装与配置

  • 支持版本:PostgreSQL 17 和 18(amd64)。
  • 构建依赖:Rust (nightly), cargo-pgrx 0.16.1。
  • 安装方式
    1. 从 GitHub Release 获取 Debian 包(如 pg-durable-postgresql-17_x.x.x-1_amd64.deb)。
    2. 将扩展库、控制文件和 SQL 升级文件安装到 PostgreSQL 目录。
    3. postgresql.conf 中将 pg_durable 添加到 shared_preload_libraries
    4. 重启 PostgreSQL。
    5. 在目标数据库中执行 CREATE EXTENSION pg_durable;

权限与安全

  • CREATE EXTENSION 不会向 PUBLIC 授予任何权限。
  • 管理员必须显式授予应用角色权限,使用 df.grant_usage('role')
  • 行级安全(RLS):确保每个用户只能查看和管理自己的持久化函数实例和节点。
  • 后台工作进程角色pg_durable.worker_role(默认为 azuresu)必须是超级用户,以绕过 RLS 管理所有用户的实例。
  • 升级注意:升级扩展后,需重新运行 df.grant_usage 以确保新函数的访问权限生效。

关键要点

  • 零基础设施:作为 PostgreSQL 扩展运行,无需 Redis、Temporal 或其他外部服务。
  • SQL 原生:使用组合操作符在 SQL 中定义函数,逻辑清晰且可审计。
  • 数据库感知:提供调度、条件和并行执行的一等公民原语。
  • 持久化:函数状态持久化到 PostgreSQL,能够承受崩溃、重启和故障转移。
  • 状态内聚:重试状态、进度跟踪和检查点机制内置于数据库,消除了定制的应用代码。
  • 运维简化:通过标准的 PostgreSQL 表(如 df.instances)提供操作可见性,沿用现有的认证和备份模型。
  • 开发体验:支持通过 VS Code Dev Container 或本地 pg-start.sh 脚本快速搭建开发环境。

意义与影响

pg_durable 的开源标志着数据库即服务(DBaaS)理念在功能层面的进一步延伸。它将原本分散在应用层、消息队列和外部编排器中的状态管理和容错逻辑,收拢回数据库内核。

  1. 简化架构:对于已经重度依赖 PostgreSQL 的团队,pg_durable 消除了维护复杂微服务架构(Cron + Worker + Queue + Status Table)的负担,降低了系统耦合度。
  2. 提升可靠性:通过将检查点机制下沉到数据库引擎,确保了在基础设施故障下的数据一致性和任务连续性,避免了“部分成功”导致的脏数据或重复处理。
  3. 推动 AI/数据管道标准化:随着 RAG 和向量数据库的普及,数据处理管道日益复杂。pg_durable 为在数据库内部构建可靠的 ETL 和 AI 预处理流水线提供了原生支持,特别契合 pgvector 等扩展生态。
  4. 性能与成本优化:减少了数据在应用层和数据库层之间的网络往返,以及跨系统协调的开销。对于中小规模团队,这意味更低的运维成本和更少的组件故障点。

总体而言,pg_durable 是微软“将计算靠近数据”战略的具体落地,它为 PostgreSQL 用户提供了一种更现代、更健壮的方式来处理长运行和容错型任务,填补了传统 SQL 过程语言与现代分布式编排系统之间的空白。

查看原文 →github.com