Oracle CDC — Quickstart & Runbook
Confirm prerequisites, collect health signals, register a connector, verify changes, and roll back safely.
Prerequisites (DB)
- ARCHIVELOG mode recommended.
- Supplemental logging enabled (DB-level minimal; table-level for key columns or ALL for keyless tables).
- Redo/archive retention window ≥ snapshot + catch-up time.
- Stable primary keys (or table log groups capturing merge keys).
- ARCHIVELOG mode keeps redo history available so CDC readers can recover. Supplemental logging ensures redo contains key columns to reconstruct before/after images, which is critical when applying updates downstream.
-- archivelog and redo
SELECT log_mode FROM v$database;
SELECT sequence#, archived, status
FROM v$log
ORDER BY first_time DESC FETCH FIRST 5 ROWS ONLY;
-- supplemental logging
SELECT supplemental_log_data_min, supplemental_log_data_all FROM v$database;
SELECT owner, table_name, log_group_name, always, log_group_type
FROM dba_log_groups ORDER BY owner, table_name;
DB Setup (examples)
-- table-level log group for keyless merge
ALTER TABLE APP.CUSTOMER ADD LOG GROUP lg_customer_pk (ID) ALWAYS;
-- throttle snapshot scope to avoid redo storms (choose limited tables)
-- and plan off-hours if tables are huge
Connector Notes
- Prefer narrow includes/filters to reduce LogMiner workload.
- Measure redo switch rate before and after snapshot.
- Have a plan for LOBs (exclude or route separately if large).
{
"name": "oracle-cdc",
"config": {
"connector.class": "io.debezium.connector.oracle.OracleConnector",
"database.hostname": "oracle",
"database.port": "1521",
"database.user": "CDC",
"database.password": "CDC",
"database.dbname": "ORCLCDB",
"database.pdb.name": "ORCLPDB1",
"topic.prefix": "server1",
"schema.include.list": "APP",
"table.include.list": "APP.CUSTOMER",
"tombstones.on.delete": "false",
"include.schema.changes": "false",
"snapshot.mode": "initial",
"errors.tolerance": "all",
"errors.deadletterqueue.topic.name": "dlq.oracle"
}
}
Verify
-- generate a change
UPDATE APP.CUSTOMER SET EMAIL = EMAIL || '.X' WHERE ROWNUM = 1;
-- redo activity sample
SELECT TO_CHAR(first_time, 'YYYY-MM-DD HH24:MI') AS t, COUNT(*) AS switches
FROM v$log_history
WHERE first_time > SYSDATE - 1/24
GROUP BY TO_CHAR(first_time, 'YYYY-MM-DD HH24:MI');
kafka-console-consumer --bootstrap-server localhost:9092 \
--topic server1.APP.CUSTOMER --from-beginning --max-messages 5
Acceptance (target/sink)
- No duplicate PKs after connector restart.
- Latest-wins per key by commit timestamp/SCN.
- DLQ empty or only expected test errors.
SELECT COUNT(*) AS rows, COUNT(DISTINCT ID) AS distinct_keys
FROM TARGET_CUSTOMERS;
Safe Rollback
Pause the connector and retain archived logs until downstream systems are consistent. If schema or log-group changes are needed, plan a clean re-snapshot of affected tables.