CDC strategies
The enforced matrix#
A CDC table pairs a strategy with a source engine. Only four combinations exist:
| Strategy | Supported source engine |
|---|---|
timestamp |
postgres, mysql |
log_pg |
postgres |
log_mysql |
mysql |
log_mssql |
sqlserver |
Nothing else works. mariadb, cockroachdb, singlestore, snowflake and
every non-relational engine have no change-capture path at all.
Warning. The strategy picker in the UI offers wider combinations than the platform supports, and an unsupported pairing saves without complaint. It fails on the first sync, with:
strategy '<name>' does not support engine '<engine>'. Check the pairing against the table above before you register a CDC table.
CDC mirrors can only be written to postgres or mysql destinations —
see Connectors.
timestamp#
Detection. A polling strategy. Each sync selects rows whose configured timestamp column is greater than the stored watermark, then advances the watermark to the highest value it read. It needs no database-level configuration, no elevated grants, and no restart — which is why it is the strategy to reach for when you cannot change the source server.
Delete detection. timestamp cannot detect hard deletes. A row removed
with DELETE simply stops appearing in the source and remains in the mirror
forever. If the application soft-deletes, configure the soft-delete column and
the strategy will treat a flagged row as a delete. If it hard-deletes, use a
log-based strategy or accept that the mirror is insert/update-only.
Tuning. The timestamp column, an optional soft-delete column, the poll
interval, and the batch size. Choose a column the source updates on every
write — a created_at column silently misses updates.
Prerequisites. SELECT on the source table, and an indexed timestamp
column. Without an index every poll is a full scan.
log_pg (PostgreSQL logical decoding)#
Detection. Reads PostgreSQL's write-ahead log through logical decoding, so inserts, updates and deletes are all observed as they were committed — no polling window, no dependence on an application-maintained column.
Delete detection. Yes, natively. Hard deletes are captured.
Tuning. Poll interval and batch size govern how often the slot is drained
and how much is taken per drain. The replication slot is named
abrq_<datasource>_<schema>_<table> and the bundled test_decoding output
plugin is used, so no third-party plugin has to be installed on the server.
Source prerequisites.
wal_level = logicalinpostgresql.conf. This requires a server restart — it cannot be changed with a reload.- A role with the
REPLICATIONattribute, plusSELECTon the captured table. - Enough
max_replication_slotsheadroom for one slot per CDC table.
ALTER SYSTEM SET wal_level = 'logical';
-- restart the server, then:
SHOW wal_level;
CREATE ROLE <ABRQ_CDC_USER> WITH LOGIN REPLICATION PASSWORD '<PASSWORD>';
GRANT SELECT ON <SCHEMA>.<TABLE> TO <ABRQ_CDC_USER>;
Warning. A replication slot that is never drained holds WAL on the source server indefinitely and will eventually exhaust its disk. If you retire a CDC table, delete it in Abrq DIP so the slot is released — or drop the slot manually.
log_mysql (binary log)#
Detection. Reads the MySQL binary log as a replica would, so every committed insert, update and delete is captured in commit order.
Delete detection. Yes, natively.
Tuning. Poll interval, batch size, and the replication server_id the
platform presents to the source. The default is 21001; it must be unique
across everything reading that server's binary log, including real replicas and
any second Abrq DIP instance.
Source prerequisites.
log_bin = ON.binlog_format = ROW. Statement or mixed format does not carry row images.binlog_row_metadata = FULL. MySQL 8.0.14 and later default toMINIMAL, which omits the column names the platform needs to map rows.- Grants:
REPLICATION CLIENTandREPLICATION SLAVE, plusSELECTon the captured table. - A
server_idnot used by any other replica.
SHOW VARIABLES WHERE Variable_name IN
('log_bin', 'binlog_format', 'binlog_row_metadata', 'binlog_row_image');
GRANT REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO '<ABRQ_CDC_USER>'@'%';
GRANT SELECT ON <DATABASE>.<TABLE> TO '<ABRQ_CDC_USER>'@'%';
Binary-log retention on the source must exceed the longest expected outage of the CDC worker. If the log segment holding the last read position is purged, the table has to be re-seeded.
log_mssql (SQL Server CDC)#
Detection. Reads SQL Server's own CDC shadow tables through the
cdc.fn_cdc_get_all_changes_* functions. SQL Server captures the changes; Abrq
DIP consumes them.
Delete detection. Yes, natively.
Tuning. Poll interval and batch size. The retention of the shadow tables is controlled by SQL Server's CDC cleanup job, not by Abrq DIP.
Source prerequisites.
- SQL Server Agent must be running — the capture and cleanup jobs depend on it.
- Enable CDC once per database:
EXEC sys.sp_cdc_enable_db;
- Enable CDC per captured table:
EXEC sys.sp_cdc_enable_table
@source_schema = N'<SCHEMA>',
@source_name = N'<TABLE>',
@role_name = NULL;
- Grants for the Abrq DIP login:
SELECTon the shadow tablecdc.<schema>_<table>_CT, andEXECUTEon the matchingcdc.fn_cdc_get_all_changes_*function.
Note. The connection test probes MySQL binary-log settings, but it cannot verify PostgreSQL
wal_leveland it cannot verify that SQL Server CDC has been enabled on the database or the table. Check those yourself with the statements above before the first sync — otherwise the first run is where you find out.
Choosing a strategy#
| If… | Use |
|---|---|
| You cannot restart or reconfigure the source server | timestamp |
| Hard deletes must reach the mirror | a log-based strategy |
| The source has no reliable per-write timestamp column | a log-based strategy |
| The source is SQL Server | log_mssql — it is the only option |
| The source is MariaDB, CockroachDB, SingleStore or Snowflake | No CDC exists; use scheduled ETL instead |
Schema drift on a CDC mirror is governed separately, and destructive drift always blocks — see Schema drift policies.