CDC Tables
Purpose#
The CDC Tables page mirrors individual source tables into a destination database and keeps them current. Its subtitle says what the surface does: "Mirror source tables into a destination database via timestamp polling or MySQL binlog."
One CDC table is one mirrored source table: a source connector, a fully qualified source name, a destination, a strategy, and a schedule. Rows arrive in the destination with their change metadata attached, so you can see what changed and when, not just the latest state.
Before you begin#
- Read —
viewerand above can list CDC tables and open one. - Create, sync, pause, re-snapshot, delete, and check drift — all
require the
editorglobal role or above. - A source connector registered under Data Connectors, tested and passing.
- A destination connector that is Postgres or MySQL. Those are the only destinations the v1 runner supports.
- Source-side prerequisites for your chosen strategy — replication slots, binary logging, or SQL Server capture instances. See CDC strategies.
Create a CDC table#
The wizard walks five sections.
1. Source#
Pick the source connector, then the source FQN.
The FQN picker is free-text first: it tries to list what the source actually has, but typing a name yourself is always accepted. Its states are searching, no matches, and error — and even the error state stays usable, reading "Couldn't load results" over "The source couldn't be reached. You can still type the name."
That matters when the source is behind a slow link or the browsing account lacks catalogue rights: you can still create the mirror.
2. Destination#
Pick the destination connector. Only Postgres and MySQL connectors appear. If you have registered none, the section reads "No Postgres or MySQL connector registered yet…" — register one first.
3. Strategy#
Choose how changes are detected. This is the decision that constrains everything else; read the matrix below before choosing.
4. Sync#
Set the batch size and the schedule. Schedule presets are: Manual only, 1 min, 5 min, 15 min, 30 min, 1 hour, 6 hours, 24 hours.
5. Mirror table#
A DDL preview shows exactly what will be created: every source column, the source primary key, plus four platform columns.
| Mirror column | What it carries |
|---|---|
_abrq_op |
The change operation the row represents |
_abrq_ingested_at |
When Abrq DIP wrote the row |
_abrq_source_ts |
The change timestamp as the source reported it |
_abrq_batch_id |
The batch that delivered the row, for reconciliation |
Read the preview before you confirm. It is the last cheap moment to notice a missing primary key or an unexpected column type.
Strategy and engine must match#
The runner enforces a strategy/engine matrix. Only these combinations run:
| Strategy | Source engines that work |
|---|---|
timestamp |
postgres, mysql |
log_mysql |
mysql |
log_pg |
postgres |
log_mssql |
sqlserver |
Warning. The picker currently offers wider combinations than the runner accepts —
timestampagainst MariaDB, SQL Server, SingleStore, or Snowflake, andlog_mysqlagainst MariaDB, among others. Those selections save without complaint and then fail at the first sync with:strategy '<STRATEGY>' does not support engine '<ENGINE>'Check your combination against the table above before creating the CDC table; the form will not check it for you.
Strategy fields#
| Field | Required | Validation | Effect |
|---|---|---|---|
Timestamp column (timestamp) |
yes | A source column, default updated_at |
The column polled for changes; rows with a newer value are picked up |
Soft-delete column (timestamp) |
no | A source column | Lets deletes be detected when the source marks rather than removes rows |
MySQL replica server_id (log_mysql) |
yes | Integer, default 21001, unique across every replica reading that server |
Identifies this reader to the MySQL primary |
Replication slot name (log_pg) |
no | Leave blank to auto-derive | The Postgres replication slot the reader consumes |
Capture instance (log_mssql) |
yes | Default <SCHEMA>_<TABLE> |
The SQL Server capture instance the reader polls |
Two prerequisites that bite in practice:
timestampcannot detect hard deletes. Polling a column only ever sees rows that still exist. If the source deletes rows outright, use a log-based strategy or configure a soft-delete column.log_mssqlneeds capture enabled first. Runsys.sp_cdc_enable_dband thensys.sp_cdc_enable_tableon the source before creating the CDC table, or the capture instance will not exist.
Run and manage a mirror#
| Action | What it does |
|---|---|
| Snapshot | Takes the initial full copy of the source table into the mirror |
| Sync | Runs one incremental pass now, outside the schedule |
| Pause / Resume | Stops future scheduled runs, and restarts them |
| Re-snapshot | Drops the mirror, clears the checkpoint, and takes a fresh full snapshot |
| Preview | Shows the top 100 rows currently in the mirror |
| History | Past runs with their outcomes |
| Drift | Checks the source schema against the mirror |
Note. Pause does not cancel an in-flight sync. The runner finishes the batch it is working on and then stops. If you paused to protect a source under load, expect one more batch to complete.
Re-snapshot is destructive. It drops the mirror table and clears the checkpoint, so everything already delivered is rebuilt from the source. The confirmation asks you to type the source FQN — the friction is the point. Use it after resolving schema drift manually, or when the mirror and source have diverged beyond repair.
The detail page#
/cdc/:id gives you the operational view:
- Status — State, Last run, Interval, Next run.
- Recent runs — per-run counts as
+Iinserted,~Uupdated,−Ddeleted, plus a flagged-rows column for rows that needed attention. - A live log tail streamed over SSE, so a running sync can be watched without reloading.
Schema drift#
When the source table's shape changes, the mirror cannot silently follow.
Destructive drift always blocks, under every policy. Removed columns and changed types are never auto-applied:
destructive source schema change (removed ['col']; type-changed ['amount']) — never auto-applied; resolve the mirror manually, then resume
Additive drift depends on the configured policy. Under
block_and_alert an added source column also stops the mirror:
source added columns [...] and on_schema_drift=block_and_alert — enable auto_add/rescue or evolve the mirror manually, then resume
Both messages tell you the same thing: change the mirror deliberately, then resume. Options and trade-offs per policy are in Schema drift policies.
Failure modes#
| What you see | What it means | What to do |
|---|---|---|
strategy '<STRATEGY>' does not support engine '<ENGINE>' at first sync |
The strategy/engine pair is outside the enforced matrix, even though the form accepted it | Change strategy or source engine to a supported pair, then re-create the CDC table |
HTTP 409 — destination data connector uses unsupported engine 'snowflake' — v1 runner supports 'postgres' and 'mysql' destinations |
The destination is not Postgres or MySQL | Register a Postgres or MySQL destination connector and point the mirror at it |
HTTP 422 — source_fqn must be 'db.schema.table' or 'schema.table', got '...' |
The FQN is malformed — usually a stray space or a missing part | Re-enter the name in db.schema.table or schema.table form |
destructive source schema change (removed [...]; type-changed [...]) — never auto-applied; resolve the mirror manually, then resume |
Columns were dropped or retyped at the source | Evolve the mirror by hand, or re-snapshot, then resume |
source added columns [...] and on_schema_drift=block_and_alert — enable auto_add/rescue or evolve the mirror manually, then resume |
Additive drift under a blocking policy | Enable auto_add/rescue, or add the columns to the mirror yourself, then resume |
Couldn't load results in the FQN picker |
The source could not be browsed — slow link, or the account lacks catalogue rights | Type the FQN directly; the field accepts free text |
| "No Postgres or MySQL connector registered yet…" in Destination | No supported destination exists | Register one under Data Connectors |
| Sync keeps missing deleted rows | timestamp strategy cannot see hard deletes |
Configure a soft-delete column, or move to a log-based strategy |
| A pause did not stop the running sync | Expected — pause stops scheduling, not the current batch | Wait for the batch to finish; the mirror stays consistent |