Change Data Capture Grundlagen: Datenaenderungen zuverlaessig erfassen
AI generated
SELECT
JOIN
SQL · Data Engineering · CDC · Replikation
Change Data Capture Grundlagen
Datenaenderungen erfassen, ohne Polling zu betreiben

Change Data Capture erfasst jede Aenderung an Datenzeilen nahezu in Echtzeit, statt sie in periodischen Abfragen zu suchen. Log-basiertes CDC liest direkt aus dem Transaktionslog der Datenbank und liefert Aenderungen zuverlaessig an nachgelagerte Systeme, ohne die Quelldatenbank mit zusaetzlicher Last zu belasten.

18 Min. Lesezeit Log-basiertes CDC · Trigger · Outbox-Pattern PostgreSQL · MySQL · Debezium

1. Was Change Data Capture wirklich loest

Change Data Capture (kurz CDC) beschreibt eine Gruppe von Techniken, um jede Aenderung an Zeilen einer Datenbank, also INSERT, UPDATE und DELETE, zuverlaessig zu erfassen und an nachgelagerte Systeme weiterzureichen. Ohne CDC muessen nachgelagerte Systeme entweder periodisch die gesamte Quelltabelle abfragen (Polling) oder Anwendungscode explizit Events versenden, wenn eine Aenderung passiert. Beide Ansaetze haben Schwachstellen: Polling verpasst schnelle Aenderungsfolgen, und Anwendungscode vergisst leicht einzelne Codepfade, in denen eine Aenderung ohne Event-Versand geschieht.

Change Data Capture loest dieses Problem an der Quelle: Aenderungen werden dort erfasst, wo sie garantiert vollstaendig sichtbar sind, entweder im Transaktionslog der Datenbank oder ueber Trigger, die bei jeder Schreiboperation feuern. Die folgenden Abschnitte zeigen, warum Log-basiertes CDC die robusteste Variante ist, wie Trigger-CDC als Alternative funktioniert und wie das Outbox-Pattern Konsistenzprobleme zwischen Datenbank-Schreiboperation und Event-Versand loest.

2. Warum Polling an seine Grenzen stoesst

Der naheliegendste Ansatz, Aenderungen zu erfassen, ist ein periodisches Polling: alle paar Sekunden eine Abfrage gegen die Quelltabelle, gefiltert auf einen updated_at-Zeitstempel. Das funktioniert fuer viele Faelle, hat aber zwei strukturelle Schwaechen. Erstens erkennt ein reiner Zeitstempel-Filter keine geloeschten Zeilen, weil eine geloeschte Zeile schlicht nicht mehr existiert und in der Abfrage nicht mehr auftaucht. Zweitens verpasst Polling Zwischenzustaende: Wird eine Zeile innerhalb eines Polling-Intervalls zweimal geaendert, sieht das nachgelagerte System nur den letzten Zustand, nicht die Zwischenaenderung.

Fuer viele Reporting-Anwendungsfaelle ist das akzeptabel, fuer Audit-Trails, Echtzeit-Synchronisation oder Event-getriebene Architekturen jedoch nicht. Change Data Capture loest genau dieses Problem, indem es jede einzelne Aenderung erfasst, in der Reihenfolge, in der sie tatsaechlich passiert ist, inklusive geloeschter Zeilen und Zwischenzustaenden. Der Umstieg von Polling auf CDC ist meist der Punkt, an dem Datenpipelines von Batch-artig zu ereignisgetrieben wechseln.

3. Log-basiertes CDC: Transaktionslog als Quelle

Log-basiertes Change Data Capture liest direkt aus dem Write-Ahead-Log (PostgreSQL) beziehungsweise dem Binary Log (MySQL) der Datenbank. Jede Datenbank schreibt ohnehin jede Aenderung in dieses Log, bevor sie auf die eigentlichen Datenseiten angewendet wird, um Crash-Recovery zu ermoeglichen. CDC-Tools wie Debezium klinken sich als logischer Replikations-Client an dieses Log an und lesen Aenderungen, ohne zusaetzliche Leselast auf den Tabellen selbst zu erzeugen.

Dieser Ansatz ist der performanteste, weil er die Quelldatenbank praktisch nicht zusaetzlich belastet: Das Log wird ohnehin geschrieben, CDC liest es lediglich mit. In PostgreSQL richtet man dafuer einen logischen Replikations-Slot ein, der garantiert, dass keine Log-Eintraege geloescht werden, bevor sie vom CDC-Konsumenten gelesen wurden. Das Change Data Capture per Log erfasst automatisch auch DELETE-Operationen und die exakte Reihenfolge aller Aenderungen, was bei Trigger- oder Polling-basierten Ansaetzen zusaetzlichen Aufwand erfordert.


-- PostgreSQL: create a logical replication slot for CDC
SELECT pg_create_logical_replication_slot(
  'cdc_orders_slot',
  'pgoutput'
);

-- Publication defines which tables are captured
CREATE PUBLICATION cdc_orders_publication
FOR TABLE orders, order_items;

-- Inspect the current replication lag of a slot
SELECT slot_name, active, confirmed_flush_lsn,
       pg_current_wal_lsn() - confirmed_flush_lsn AS lag_bytes
FROM pg_replication_slots
WHERE slot_name = 'cdc_orders_slot';

4. Trigger-basiertes CDC: Aenderungen selbst protokollieren

Nicht jede Datenbank oder jedes Betriebs-Setup erlaubt Zugriff auf das Transaktionslog, etwa in stark eingeschraenkten Cloud-Datenbank-Instanzen. In diesen Faellen ist Trigger-basiertes Change Data Capture die Alternative: Ein Trigger auf INSERT, UPDATE und DELETE schreibt bei jeder Aenderung eine Zeile in eine separate Aenderungsprotokoll-Tabelle. Nachgelagerte Systeme lesen dann aus dieser Protokoll-Tabelle statt aus dem Log.

Der Nachteil dieses Change Data Capture-Ansatzes ist der zusaetzliche Schreib-Overhead: Jede Schreiboperation auf der Quelltabelle loest zusaetzlich eine Schreiboperation auf der Protokoll-Tabelle aus, innerhalb derselben Transaktion. Bei sehr hohem Schreibdurchsatz kann das spuerbar werden. Der Vorteil ist die Unabhaengigkeit von Datenbank-internen Replikationsmechanismen und die einfache Portierbarkeit zwischen verschiedenen Datenbank-Engines, da Trigger und Protokoll-Tabelle reines SQL sind.


-- Trigger-based CDC: log every change to a dedicated audit table
CREATE TABLE orders_changelog (
  changelog_id BIGSERIAL PRIMARY KEY,
  order_id INT NOT NULL,
  operation CHAR(1) NOT NULL, -- I, U, D
  changed_at TIMESTAMP NOT NULL DEFAULT NOW(),
  old_data JSONB,
  new_data JSONB
);

CREATE OR REPLACE FUNCTION log_order_change() RETURNS TRIGGER AS $$
BEGIN
  IF TG_OP = 'DELETE' THEN
    INSERT INTO orders_changelog (order_id, operation, old_data)
    VALUES (OLD.order_id, 'D', to_jsonb(OLD));
    RETURN OLD;
  ELSE
    INSERT INTO orders_changelog (order_id, operation, old_data, new_data)
    VALUES (NEW.order_id, LEFT(TG_OP, 1), to_jsonb(OLD), to_jsonb(NEW));
    RETURN NEW;
  END IF;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER orders_cdc_trigger
AFTER INSERT OR UPDATE OR DELETE ON orders
FOR EACH ROW EXECUTE FUNCTION log_order_change();

5. Das Outbox-Pattern fuer konsistente Events

Ein haeufiges Problem beim Versenden von Events nach einer Datenbank-Aenderung: Die Anwendung schreibt die Aenderung in die Datenbank und versendet danach separat ein Event an eine Message Queue. Schlaegt der Event-Versand fehl, obwohl die Datenbank-Transaktion erfolgreich war, entsteht eine Inkonsistenz, das sogenannte Dual-Write-Problem. Das Outbox-Pattern, eine spezielle Form von Change Data Capture, loest dieses Problem.

Beim Outbox-Pattern schreibt die Anwendung das zu versendende Event in dieselbe Transaktion wie die eigentliche Datenaenderung, in eine separate Outbox-Tabelle. Ein CDC-Prozess liest anschliessend aus dieser Outbox-Tabelle und versendet die Events zuverlaessig an die Message Queue, unabhaengig vom urspruenglichen Transaktionskontext. Weil Datenaenderung und Outbox-Eintrag in derselben Transaktion committen, ist das Dual-Write-Problem strukturell ausgeschlossen.


-- Outbox pattern: write the business change and the event
-- to be published within the same transaction
BEGIN;

UPDATE orders SET status = 'shipped' WHERE order_id = 1001;

INSERT INTO outbox_events (aggregate_type, aggregate_id, event_type, payload, created_at)
VALUES (
  'order',
  1001,
  'OrderShipped',
  '{"order_id": 1001, "status": "shipped"}'::jsonb,
  NOW()
);

COMMIT;

-- CDC reads from outbox_events and publishes to the message queue,
-- then marks the row as processed
UPDATE outbox_events SET processed_at = NOW()
WHERE event_id = 4821 AND processed_at IS NULL;

6. Schema-Evolution und CDC-Vertraege

Ein oft unterschaetztes Problem bei Change Data Capture: Aendert sich das Schema der Quelltabelle, etwa durch eine neue Spalte oder eine geaenderte Datentyp-Definition, muessen alle CDC-Konsumenten diese Aenderung vertragen. Ein CDC-Consumer, der ein festes Schema erwartet, bricht bei einer Schema-Migration ab, wenn diese nicht mit einem Schema-Registry-Mechanismus abgesichert ist.

Bewaehrte Praxis ist ein explizites CDC-Schema-Contract: neue Spalten werden nur additiv eingefuehrt, bestehende Spalten werden nicht umbenannt oder geloescht, sondern als deprecated markiert und spaeter entfernt. Werkzeuge wie Debezium unterstuetzen Schema-Registries, die Konsumenten ueber Aenderungen informieren, bevor sie produktiv werden, und so verhindern, dass ein CDC-Konsument unerwartet ausfaellt.


-- Additive schema change: safe for existing CDC consumers
ALTER TABLE orders ADD COLUMN loyalty_points INT DEFAULT 0;

-- Deprecating a column instead of dropping it immediately
COMMENT ON COLUMN orders.legacy_status IS
  'Deprecated since 2026-07-30, use status_code instead. Remove after Q4.';

-- Consumers can check for column presence before relying on it
SELECT column_name
FROM information_schema.columns
WHERE table_name = 'orders' AND column_name = 'loyalty_points';

7. Konsistenzgarantien: At-Least-Once vs. Exactly-Once

Change Data Capture liefert in den meisten realen Implementierungen At-Least-Once-Semantik: Ein Event wird garantiert mindestens einmal zugestellt, kann aber bei einem Fehler und anschliessendem Retry auch mehrfach ankommen. Exactly-Once-Semantik, bei der ein Event garantiert genau einmal ankommt, ist technisch deutlich aufwendiger und erfordert idempotente Konsumenten oder transaktionale Zusicherungen ueber Systemgrenzen hinweg.

In der Praxis loest man dieses Problem, indem man Konsumenten idempotent gestaltet, statt Exactly-Once auf Infrastrukturebene zu erzwingen. Jedes CDC-Event traegt eine eindeutige ID, der Konsument prueft vor der Verarbeitung, ob diese ID bereits verarbeitet wurde. Diese Kombination aus At-Least-Once-Zustellung und idempotenter Verarbeitung erreicht effektiv dasselbe Ergebnis wie Exactly-Once, ohne dessen Infrastruktur-Komplexitaet.

8. CDC im Betrieb: Monitoring und Fehlerbehandlung

Ein produktiver Change Data Capture-Prozess braucht Monitoring fuer den Replikations-Lag, also die Verzoegerung zwischen einer Datenbank-Aenderung und ihrer Ankunft beim Konsumenten. Waechst dieser Lag unkontrolliert, deutet das meist auf einen ueberlasteten Konsumenten oder ein Problem im CDC-Tool hin, das dringend behoben werden muss, bevor der Replikations-Slot so weit anwaechst, dass er die Quelldatenbank belastet.

Ein haeufiges Betriebsproblem: Ein logischer Replikations-Slot in PostgreSQL, dessen Konsument gestoppt wurde, verhindert das Loeschen alter Write-Ahead-Log-Segmente. Das fuellt kontinuierlich Festplattenspeicher, bis die Datenbank selbst in Schwierigkeiten geraet. Alerting auf die Slot-Groesse ist deshalb ein Pflicht-Bestandteil jedes Change Data Capture-Setups, nicht nur ein Nice-to-have.


-- Monitor replication slot size to catch a stuck consumer early
SELECT
  slot_name,
  active,
  pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal
FROM pg_replication_slots
ORDER BY pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) DESC;

-- Alert threshold example: flag slots retaining more than 5 GB of WAL
SELECT slot_name
FROM pg_replication_slots
WHERE pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) > 5 * 1024 * 1024 * 1024;

9. CDC-Ansaetze im Vergleich

Die drei zentralen Ansaetze fuer Change Data Capture unterscheiden sich deutlich in Aufwand, Performance-Auswirkung und Genauigkeit.

Ansatz Last auf Quelle Erfasst DELETEs Komplexitaet
Polling Mittel bis hoch Nein Niedrig
Trigger-basiert Gering, aber pro Schreibvorgang Ja Mittel
Log-basiert Minimal Ja Hoch (Infrastruktur)
Outbox-Pattern Gering, pro Event N/A (explizite Events) Mittel

Log-basiertes Change Data Capture ist der Goldstandard fuer Performance und Vollstaendigkeit, erfordert aber Infrastruktur wie Debezium und Kafka Connect. Trigger-basiertes CDC eignet sich, wenn kein Zugriff auf Replikations-Mechanismen besteht. Das Outbox-Pattern ist die richtige Wahl, wenn nicht beliebige Tabellenaenderungen, sondern gezielt definierte Business-Events zwischen Services ausgetauscht werden sollen.

Mironsoft

Data Engineering, CDC-Pipelines und Event-getriebene Architekturen

Datenaenderungen zuverlaessig und in Echtzeit erfassen?

Wir richten Log-basiertes CDC mit Debezium, Trigger-basierte Alternativen oder das Outbox-Pattern ein und stellen Konsistenz zwischen Quellsystem und Konsumenten sicher.

CDC-Setup

Replikations-Slots, Debezium-Konnektoren und Publikationen konfigurieren

Outbox-Pattern

Dual-Write-Probleme durch transaktionale Outbox-Tabellen eliminieren

Monitoring

Replikations-Lag und Slot-Groesse ueberwachen, bevor Probleme entstehen

10. Zusammenfassung

Change Data Capture ersetzt periodisches Polling durch eine zuverlaessige Erfassung jeder einzelnen Datenaenderung, inklusive geloeschter Zeilen und Zwischenzustaenden. Log-basiertes CDC liest direkt aus dem Transaktionslog und erzeugt dabei minimale zusaetzliche Last auf der Quelldatenbank. Trigger-basiertes CDC ist die Alternative, wenn kein Zugriff auf Replikations-Mechanismen besteht. Das Outbox-Pattern loest zusaetzlich das Dual-Write-Problem zwischen Datenbank-Transaktion und Event-Versand.

Wer Change Data Capture produktiv einsetzt, muss Replikations-Lag und Slot-Groesse aktiv ueberwachen und Konsumenten idempotent gestalten, um mit At-Least-Once-Zustellung sicher umzugehen. Diese Kombination aus richtigem CDC-Ansatz, Schema-Vertraegen und Monitoring macht Event-getriebene Architekturen robust genug fuer den produktiven Dauerbetrieb.

Change Data Capture Grundlagen — Das Wichtigste auf einen Blick

Log-basiertes CDC

Liest aus Write-Ahead-Log oder Binary Log, minimale Zusatzlast, erfasst DELETEs automatisch.

Trigger-basiertes CDC

Protokoll-Tabelle per Trigger befuellt, reines SQL, aber zusaetzlicher Schreib-Overhead.

Outbox-Pattern

Event und Datenaenderung in derselben Transaktion, eliminiert das Dual-Write-Problem.

Betrieb

Replikations-Lag und Slot-Groesse ueberwachen, Konsumenten idempotent gestalten.

11. FAQ: Change Data Capture Grundlagen

1Was ist Change Data Capture?
Erfassung jeder Datenbank-Aenderung nahezu in Echtzeit, statt sie ueber periodische Abfragen zu suchen.
2Warum reicht Polling nicht?
Polling erkennt keine geloeschten Zeilen und verpasst schnelle Aenderungsfolgen innerhalb eines Intervalls.
3Was ist Log-basiertes CDC?
Liest direkt aus dem Transaktionslog, minimale Zusatzlast auf der Quelldatenbank.
4Wann Trigger-basiertes CDC?
Ohne Zugriff auf Replikations-Mechanismen, mit dem Nachteil zusaetzlichen Schreib-Overheads.
5Was ist das Dual-Write-Problem?
Inkonsistenz, wenn Datenbank-Schreibvorgang und Event-Versand als getrennte Operationen ausgefuehrt werden.
6Wie loest Outbox das Dual-Write-Problem?
Event und Datenaenderung landen in derselben Transaktion, ein CDC-Prozess versendet danach separat.
7Was ist At-Least-Once-Semantik?
Event wird garantiert mindestens einmal zugestellt, kann aber mehrfach ankommen, Konsumenten muessen idempotent sein.
8Was passiert bei einem ungelesenen Replikations-Slot?
Write-Ahead-Log-Segmente koennen nicht geloescht werden, Festplattenspeicher fuellt sich kontinuierlich.
9Erfasst CDC Schema-Aenderungen?
Separat ueber Schema-Registries behandeln, neue Spalten additiv einfuehren, nichts abrupt entfernen.
10Welches Werkzeug fuer Log-basiertes CDC?
Debezium ist das verbreitetste Werkzeug, meist zusammen mit Kafka Connect eingesetzt.