实时订阅工作原理:Postgres CDC 与事件模型


文档摘要

实时订阅工作原理:Postgres CDC 与事件模型 理解 Realtime 的关键,在于理解它「如何知道数据变了」。本节讲清背后的核心技术——PostgreSQL 的逻辑复制(CDC),以及与之相关的事件模型。 轮询 vs 推送:为什么要 CDC 先回顾两种获取最新数据的方式: 轮询(Polling):客户端每隔 N 秒主动查询一次「有没有新数据」。简单但低效——大部分查询是空查,且真正的变更存在最多 N 秒延迟。 推送(Push):数据一变,服务端立刻通知客户端。高效且真正实时,但需要一种「感知数据变化」的机制。

实时订阅工作原理:Postgres CDC 与事件模型

理解 Realtime 的关键,在于理解它「如何知道数据变了」。本节讲清背后的核心技术——PostgreSQL 的逻辑复制(CDC),以及与之相关的事件模型。

轮询 vs 推送:为什么要 CDC

先回顾两种获取最新数据的方式:

  • 轮询(Polling):客户端每隔 N 秒主动查询一次「有没有新数据」。简单但低效——大部分查询是空查,且真正的变更存在最多 N 秒延迟。
  • 推送(Push):数据一变,服务端立刻通知客户端。高效且真正实时,但需要一种「感知数据变化」的机制。

Realtime 选择推送模式,而它感知变化的依据,就是 PostgreSQL 自带的逻辑复制(Logical Replication),也叫 CDC(Change Data Capture,变更数据捕获)

什么是逻辑复制(CDC)

PostgreSQL 内置强大的复制能力:它会把数据库中发生的每一次数据变更(插入、更新、删除),按照时间顺序记录成一条条「变更日志」。这套机制原本用于数据库的主从复制,但 Supabase 巧妙地把它用于实时推送:

  1. 数据库发生变更(无论来自哪个客户端或函数)。
  2. PostgreSQL 通过逻辑复制把变更事件输出。
  3. Supabase 的 Realtime 服务接收这些事件。
  4. Realtime 服务把事件分发给订阅了对应数据的客户端。

关键在于:变更的源头不重要。无论是用户 A 的操作、用户 B 的操作,还是某个边缘函数的批量更新,只要数据变了,所有订阅者都会被通知。这种「变更中心化感知、订阅端各自响应」的模式,是实时应用的核心。

三种变更事件

逻辑复制会输出三类事件,对应数据库的三种写操作:

  • INSERT 事件:新行被插入,事件携带新行的内容。
  • UPDATE 事件:某行被修改,事件携带新行内容(通常也含旧值或主键)。
  • DELETE 事件:某行被删除,事件携带被删行的标识(通常是主键)。

客户端订阅时,可以指明关心哪些类型的事件,从而只接收自己关心的变更。

订阅的本质:过滤器 + 回调

一次订阅,本质上是「告诉 Realtime 服务:当某张表、某些类型的变更发生时,调用我的回调函数」。订阅可以带有过滤条件,例如:

  • 只关心某张表(如 orders)。
  • 只关心某种事件(如 INSERT)。
  • 只关心满足某条件的行(如 user_id 是某用户)。

Realtime 服务收到变更事件后,按各订阅者的过滤条件分发——只有匹配的订阅者才收到。这让不同客户端可以各取所需,互不干扰。

RLS 对订阅范围的约束

一个重要的安全特性:Realtime 的订阅同样受 RLS 约束。客户端只能订阅到「按 RLS 规则它有权看到」的行变更。

例如,订单表启用了「用户只能看自己订单」的 RLS 策略,那么用户 A 订阅 orders 时,只会收到属于 A 的订单变更,用户 B 的订单变更不会推给 A。这保证了实时能力不会成为安全漏洞——推送的内容与查询的内容遵循同一套权限规则。

因此,要让某张表支持安全的实时订阅,前提是该表已启用 RLS 并开启了实时能力(Realtime 需在表级别显式启用)。

Realtime 的三种能力

除了「数据库变更订阅」,Supabase Realtime 还提供另外两种能力,本章后续会展开:

  • 广播(Broadcast):客户端之间低延迟地互相发送消息,不经过数据库持久化。适合聊天、实时光标等。
  • 在线状态(Presence):跟踪「谁在线」,并同步参与者的临时状态。适合协作编辑中的在线成员展示。

这三种能力共享同一套连接与认证机制,可在同一个客户端上同时使用。

小结

Realtime 基于 PostgreSQL 的逻辑复制(CDC)感知数据变更,把插入、更新、删除事件推送给订阅者;订阅可带过滤条件,且受 RLS 约束保证安全。理解了这条「变更感知 → 安全分发」的主线,下一节我们进入实操,学习如何订阅具体的数据库变更。


发布者: 作者: 灏天文库 转发
评论区 (0)
U