CDC
Subscribe to Postgres Change Data Capture streams from db.cdc.postgres sources. List configured sources, open a stream, and receive row-level change events over a channel.
Loading
local cdc = require("cdc")
list_sources
List all configured CDC sources:
local sources, err = cdc.list_sources()
for _, s in ipairs(sources) do
print(s.name, s.slot, s.streaming)
end
Each source is a table: name, slot, publication, tables, streaming, failover, temporary, snapshot. See CDC sources.
Returns: table, error
source
Get a single source by name (its entry ID):
local info, err = cdc.source("app:pg_cdc")
if info == nil then
-- no such source
end
Returns: table, error (source info, or nil if not found)
stream
Open a change stream on a source. Returns a cdc.Stream whose channel delivers change events:
local stream, err = cdc.stream("app:pg_cdc", {
tables = { "public.users", "public.orders" },
ops = { "insert", "update" },
buffer = 128,
})
| Parameter | Type | Description |
|---|---|---|
name |
string | Source name (entry ID) |
opts.tables |
[]string | Filter to these tables (omit for all configured tables) |
opts.ops |
[]string | Filter to these operations: insert, update, delete, truncate |
opts.buffer |
int | Channel buffer size (1-65536) |
Returns: Stream, error
Stream Methods
channel
Return the channel that receives change events. The first call subscribes to the source (yields); subsequent calls return the same channel. :receive() blocks until the next change arrives, or returns nil when the stream ends:
local stream = cdc.stream("app:pg_cdc")
local ch = stream:channel()
while true do
local change = ch:receive()
if change == nil then break end -- stream closed
if change.op == "insert" then
handle_new_user(change.table, change.after)
elseif change.op == "update" then
handle_update(change.table, change.before, change.after)
elseif change.op == "delete" then
handle_delete(change.table, change.before)
end
end
receive is an alias for channel.
close
Stop the subscription and release the stream. Idempotent; also auto-closed at task scope. release is an alias for close.
stream:close()
Change Event
Each message received on the channel is a change table:
| Field | Description |
|---|---|
op |
Operation: insert, update, delete, truncate, or r (snapshot read) |
schema |
Table schema |
table |
Table name |
relation |
schema.table |
before |
Row state before the change (update, delete; absent for insert) |
after |
Row state after the change (insert, update, r; absent for delete) |
source |
Source name |
lsn |
Log sequence number of the change |
commit_lsn |
LSN of the committing transaction (when applicable) |
xid |
Transaction ID (when applicable) |
before and after are row maps keyed by column name.
Errors
| Condition | Kind |
|---|---|
| No context / no process PID | errors.INTERNAL |
| Source name required | errors.INVALID |
| Invalid buffer size | errors.INVALID |
| Source not found | errors.INTERNAL |
See Error Handling for working with errors.
See Also
- Change Data Capture -
db.cdc.postgressource configuration - Channel - Channel semantics
- Database - SQL database services