Nahtlose Datensynchronisation über Datenbanken hinweg mit PostgreSQL Logical Replication
Olivia Novak
Dev Intern · Leapcell

Einleitung
In der heutigen datengetriebenen Welt umfassen Anwendungen oft mehrere Datenbanken, was effiziente Mechanismen zur Gewährleistung der Datenkonsistenz und zur Bereitstellung nahezu Echtzeit-Updates erfordert. Ob zum Aufbau von Data Warehouses, zur Ermöglichung der Kommunikation zwischen Microservices oder zur Gewährleistung hoher Verfügbarkeit durch Read Replicas – die Herausforderung der Synchronisation von Daten über unterschiedliche Systeme hinweg ist allgegenwärtig. Herkömmliche Methoden wie Batch-Jobs oder kundenspezifische CDC auf Anwendungsebene führen oft zu Komplexität, Latenz und betrieblichem Mehraufwand. Hier erweist sich die Logical Replication von PostgreSQL als eine leistungsstarke und elegante Lösung. Sie bietet eine native, robuste und hochgradig konfigurierbare Möglichkeit, Änderungen zu erfassen und anzuwenden, und vereinfacht damit die Architektur für die verteilte Datenverwaltung erheblich. Dieser Artikel wird die Feinheiten der Logical Replication von PostgreSQL untersuchen und aufzeigen, wie sie für nahtlose datenbankübergreifende Datensynchronisation und effizientes Change Data Capture (CDC) genutzt werden kann.
Understanding Logical Replication
Um die Fähigkeiten der Logical Replication von PostgreSQL vollständig zu verstehen, ist es wichtig, zunächst einige Kernkonzepte zu begreifen:
- Logical Replication: Eine Methode zur Replikation von Datenobjekten und ihren Änderungen, basierend auf ihrer logischen Darstellung (INSERT-, UPDATE-, DELETE-Anweisungen), anstatt auf ihren physischen Speicherblöcken. Dies ermöglicht die Replikation zwischen verschiedenen Hauptversionen von PostgreSQL oder sogar zu Nicht-PostgreSQL-Systemen unter Verwendung benutzerdefinierter Decoder.
- Physical Replication: Die traditionelle Methode zur Replikation des gesamten Datenbankclusters, einschließlich der Betriebssystemdateien, auf Blockebene. Dies wird hauptsächlich für Disaster-Recovery- und schreibgeschützte Replikationsszenarien verwendet, bei denen die Replikation eine exakte Kopie des Primärsystems ist.
- Write-Ahead Log (WAL): Der Kernmechanismus von PostgreSQL zur Gewährleistung von Datenintegrität und Haltbarkeit. Jede Änderung an der Datenbank wird zuerst in das WAL geschrieben, bevor sie auf die tatsächlichen Datendateien angewendet wird. Die Logical Replication extrahiert Datenänderungen direkt aus dem WAL.
- Publication: Eine Menge von Tabellen (und optional allen Tabellen in einem Schema oder allen Tabellen in der Datenbank), die für die Replikation auf der Publisher-Datenbank markiert sind. Publisher definieren, welche Daten gesendet werden sollen.
- Subscription: Eine Verbindung zu einer Publication auf einer Subscriber-Datenbank. Subscriber empfangen und wenden die Änderungen von der Publication an.
- Logical Decoding: Der Prozess der Übersetzung des binären WAL-Formats in ein logisches Format (z. B. SQL-Anweisungen, JSON, Avro), das leicht verstanden und für die Replikation verarbeitet werden kann.
Der Mechanismus der Logical Replication
PostgreSQL Logical Replication funktioniert, indem Änderungen aus dem WAL des Publishers erfasst und an den Subscriber übertragen werden. Dieser Prozess kann in mehrere Schritte unterteilt werden:
- WAL-Generierung: Jede DML-Operation (INSERT, UPDATE, DELETE) auf der Publisher-Datenbank generiert entsprechende Einträge im WAL.
- Logical Decoding: Ein Logical Decoding-Plugin (wie
pgoutput
, das Standard für die integrierte Logical Replication ist) liest diese WAL-Einträge und übersetzt sie in einen logischen Änderungsstrom. - Publication: Der Publisher erstellt eine Publication, die angibt, welche Tabellen oder Schemata repliziert werden sollen. Dies fungiert als Filter für den logischen Änderungsstrom.
- Subscription: Der Subscriber erstellt eine Subscription, die auf eine bestimmte Publication auf dem Publisher verweist.
- Datentransfer: Der Subscriber stellt eine Verbindung zum Publisher her. Der Publisher sendet dann einen Snapshot der initialen Daten für die abonnierten Tabellen an den Subscriber. Nach der anfänglichen Synchronisation streamt er kontinuierlich die logischen Änderungen (INSERTs, UPDATEs, DELETEs) an den Subscriber.
- Anwendung: Der Subscriber empfängt diese logischen Änderungen und wendet sie auf seine lokalen Tabellen an, wodurch die Daten effektiv synchronisiert werden.
Implementierung und Beispiel
Lassen Sie uns ein praktisches Beispiel für die Einrichtung der Logical Replication zwischen zwei PostgreSQL-Instanzen durchgehen.
Voraussetzungen:
Sie benötigen zwei PostgreSQL-Instanzen (z. B. pg1
und pg2
). Stellen Sie sicher, dass sie über das Netzwerk kommunizieren können. Für dieses Beispiel gehen wir davon aus, dass pg1
der Publisher und pg2
der Subscriber ist.
Schritt 1: PostgreSQL auf dem Publisher (pg1
) konfigurieren
Bearbeiten Sie postgresql.conf
auf pg1
und setzen Sie die folgenden Parameter:
# /path/to/pg1/data/postgresql.conf wal_level = logical max_replication_slots = 10 # Nach Bedarf anpassen max_wal_senders = 10 # Nach Bedarf anpassen
Starten Sie die pg1
-Instanz neu, damit die Änderungen wirksam werden.
Öffnen Sie als Nächstes pg_hba.conf
auf pg1
, um Verbindungen vom Subscriber zuzulassen. Fügen Sie eine Zeile ähnlich dieser hinzu (ersetzen Sie subscriber_ip
durch die tatsächliche IP-Adresse oder den Bereich):
# /path/to/pg1/data/pg_hba.conf
host replication all subscriber_ip/32 md5
Starten Sie pg1
erneut, wenn Sie pg_hba.conf
geändert haben.
Schritt 2: Eine Publication auf dem Publisher (pg1
) erstellen
Verbinden Sie sich mit pg1
als Superuser oder als Benutzer mit der Berechtigung REPLICATION
.
-- Verbinden Sie sich mit pg1 psql -h localhost -p 5432 -U postgres -- Eine Datenbank und eine Tabelle für die Demonstration erstellen CREATE DATABASE publisher_db; \c publisher_db; CREATE TABLE products ( product_id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, price DECIMAL(10, 2) NOT NULL, last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Eine Publication für die 'products'-Tabelle erstellen CREATE PUBLICATION my_publication FOR TABLE products; -- Optional, um alle Tabellen in der aktuellen Datenbank zu replizieren: -- CREATE PUBLICATION my_all_tables_publication FOR ALL TABLES;
Schritt 3: Die Subscriber-Datenbank (pg2
) vorbereiten
Verbinden Sie sich mit pg2
als Superuser.
-- Verbinden Sie sich mit pg2 psql -h localhost -p 5433 -U postgres -- Eine Datenbank und eine Tabelle mit demselben Schema wie auf dem Publisher erstellen -- Es ist wichtig, dass das Schema der Subscriber-Tabelle kompatibel ist (mindestens dieselbe Primärschlüssel- und Spaltennamen/-typen haben) CREATE DATABASE subscriber_db; \c subscriber_db; CREATE TABLE products ( product_id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, price DECIMAL(10, 2) NOT NULL, last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
Schritt 4: Eine Subscription auf dem Subscriber (pg2
) erstellen
Erstellen Sie die Subscription von subscriber_db
auf pg2
aus:
-- Verbinden Sie sich mit subscriber_db auf pg2 psql -h localhost -p 5433 -U postgres -d subscriber_db CREATE SUBSCRIPTION my_subscription CONNECTION 'host=localhost port=5432 user=postgres dbname=publisher_db password=your_pg1_password' PUBLICATION my_publication;
Ersetzen Sie localhost
und 5432
durch den tatsächlichen Host und Port Ihrer pg1
-Instanz sowie your_pg1_password
durch das Passwort für den postgres
-Benutzer auf pg1
.
Schritt 5: Die Replikation testen
Nun fügen wir einige Daten in den Publisher ein und beobachten sie auf dem Subscriber.
Auf pg1
(in publisher_db
):
INSERT INTO products (name, price) VALUES ('Laptop', 1200.00); INSERT INTO products (name, price) VALUES ('Mouse', 25.50); UPDATE products SET price = 1150.00 WHERE name = 'Laptop'; DELETE FROM products WHERE name = 'Mouse';
Auf pg2
(in subscriber_db
):
SELECT * FROM products;
Sie sollten den Eintrag Laptop
mit dem aktualisierten Preis sehen und der Eintrag Mouse
sollte nicht mehr vorhanden sein, was eine erfolgreiche Replikation belegt.
Anwendungsfälle
Logical Replication ist unglaublich vielseitig und kann in zahlreichen Szenarien angewendet werden:
- Change Data Capture (CDC): Durch die Überwachung des logischen Replikationsstroms können externe Anwendungen in Echtzeit auf Datenbankänderungen reagieren. Dies ist grundlegend für ereignisgesteuerte Architekturen, Auditing oder Stream-Verarbeitung.
- Datenbankübergreifende Datensynchronisation: Konsistente Daten zwischen verschiedenen Datenbanken für Microservices, Data Marts oder geografisch verteilte Anwendungen aufrechterhalten.
- Data Warehousing und ETL: Änderungen inkrementell in Data Warehouses einspeisen, wodurch die Notwendigkeit von Massen-Datenladevorgängen reduziert wird.
- Zero-Downtime-Upgrades: Daten von einer älteren PostgreSQL-Version auf eine neuere replizieren, um die Ausfallzeit bei Hauptversions-Upgrades zu minimieren.
- Multi-Master (Active-Active) Replikation (mit Vorsicht): Obwohl komplex und normalerweise zusätzliche Konfliktlösungslogik auf Anwendungsebene erfordert, kann die Logical Replication das Rückgrat für benutzerdefinierte Multi-Master-Setups bilden.
- Selektive Replikation: Nur bestimmte Tabellen oder Schemata replizieren, was eine feinere Kontrolle über die zu synchronisierenden Daten ermöglicht, was mit physischer Replikation nicht möglich ist.
- Datenaustausch mit externen Systemen: Mit benutzerdefinierten Logical Decoding-Plugins können Daten in Nicht-PostgreSQL-Datenbanken oder Message Queues repliziert werden, was als universeller Datenänderungsstrom fungiert.
Fazit
PostgreSQL Logical Replication bietet eine robuste, effiziente und native Lösung für kritische Datenbankoperationen wie die datenbankübergreifende Datensynchronisation und Change Data Capture. Durch die Nutzung des WAL und eines Publikations-/Subskriptionsmodells bietet sie eine feingliedrige Kontrolle über den Datenfluss und ermöglicht hochgradig resiliente und verteilte Datenarchitekturen. Ihre Vielseitigkeit macht sie zu einem unverzichtbaren Werkzeug für moderne Anwendungsentwicklung und Datenmanagement und befähigt Entwickler, skalierbare Systeme mit konsistenten Daten in ihrem gesamten Ökosystem zu erstellen.