# Migration von Oracle zu PostgreSQL ohne Ausfallzeiten: Eine technische Analyse
Die Migration von Oracle zu PostgreSQL ohne Unterbrechung des Dienstes ist eine anspruchsvolle, aber machbare Aufgabe. In diesem Artikel zerlegen wir eine schrittweise Migrationsstrategie basierend auf einem realen Projekt mit Spring Boot-Mikroservices, bei dem null Auswirkungen auf die Nutzer eine zentrale Anforderung waren. Die Nutzung von CDC über Debezium ermöglichte die Echtzeit-Datensynchronisation, vermied Ausfallzeiten und minimierte Risiken.
Vorbereitung: Analyse der Struktur und Daten
Die erste Phase umfasst eine gründliche Überprüfung der aktuellen Datenbank. Es gilt, das Datenvolumen, die Verteilung der Feldtypen, das Vorhandensein veralteter Datensätze und oracle-spezifische Konstrukte ohne direkte Entsprechungen in PostgreSQL zu verstehen. Das Bereinigen irrelevanter Daten verringert das Migrationsvolumen und beschleunigt den Prozess.
Ein zentraler Aspekt ist die Zuordnung der Datentypen. Beispiele:
NUMBER(1,0)→BOOLEANVARCHAR2→TEXToderVARCHARDATE→TIMESTAMP WITHOUT TIME ZONECLOB→TEXT
Zur Analyse haben wir diese SQL-Abfrage verwendet:
select distinct DATA_TYPE
from ALL_TAB_COLUMNS
where owner = 'schemat'
order by DATA_TYPE
Basierend auf den Ergebnissen haben wir eine Zuordnungstabelle für Datentypen erstellt, die die Grundlage für alle weiteren Transformationen bildete. Ebenso wichtig ist die Berücksichtigung der Unterschiede bei der Behandlung von NULL und leeren Strings: In Oracle wird ein leerer String als NULL behandelt, in PostgreSQL jedoch nicht. Dies erfordert Anpassungen in der Geschäftslogik und den Abfragen.
Schema-Anpassung und Liquibase
Ein simpler Austausch des Datenbanktreibers führt zu Fehlern. Migrationsskripte müssen für PostgreSQL angepasst werden. Dazu:
- DDL- und DML-Operationen werden über Liquibase-Kontexte getrennt – DML wird vorübergehend deaktiviert.
- Skripte werden iterativ getestet: Nach jeder Änderung wird das Changelog ausgeführt, gefolgt von Bereinigung und Rauchtests.
- Voraussetzungen werden auf Korrektheit geprüft, und die Schema-Konsistenz mit Oracle wird gewährleistet.
Besondere Aufmerksamkeit gilt den Sequenzen. Sind diese nicht synchronisiert, können neue IDs mit historischen Daten kollidieren. Die Lösung:
- Beim Anwendungsstart wird der aktuelle Sequenzwert in PostgreSQL geprüft.
- Ist er niedriger als in Oracle, wird er mit Puffer nach vorne verschoben.
- Die Logik ist idempotent: Wiederholte Ausführungen verursachen keine Fehler.
Zusammenfassend wurde das Ziel-Schema für PostgreSQL in einem einzigen Pull Request zusammengestellt und war bereit für die Datenbefüllung.
Anpassungen im Anwendungs-Code
Nach dem erfolgreichen Start der Anwendung gegen eine leere PostgreSQL tauchen Java-seitige Codefehler auf. Wichtigste Änderungen:
- Ersetzen der
@Lob-Annotation durch@Column(columnDefinition = "text"). - Behandlung von NULL in nativen SQL-Abfragen, insbesondere in
IN (...)-Konstrukten. - Wechsel von numerischen Flags (0/1) zu
boolean. - Anpassung der String-Vergleichslogik unter Berücksichtigung der Oracle/PostgreSQL-Unterschiede.
- Umschreibung nativer Abfragen für den PostgreSQL-Dialekt.
Tests wurden auf Unit-Test- und Integrationsebene durchgeführt. Besonderer Fokus auf Randfälle: Leere Strings, NULL-Werte, große Textfelder.
Implementierung von CDC über Debezium und Kafka Connect
Wir haben den klassischen Stack gewählt: Debezium + Kafka Connect. Architektur:
- Source-Connector (Debezium Oracle) liest das Redo-Log und erzeugt CDC-Events.
- Events werden an Kafka gesendet (ein Topic pro Tabelle).
- Sink-Connector (JDBC Sink) wendet Änderungen in gleicher Reihenfolge auf PostgreSQL an.
Einrichtungsphasen:
- Initial Snapshot — vollständige Datenkopie zum Startzeitpunkt.
- Streaming Changes — kontinuierliche Replikation von INSERT/UPDATE/DELETE aus dem Redo-Log.
- Order Preservation — Garantie der Änderungsreihenfolge über LogMiner.
Verwendete Images:
quay.io/debezium/kafka:3.0quay.io/debezium/zookeeper:3.0quay.io/debezium/connect:3.0provectuslabs/kafka-ui:0.7.2(für Monitoring)
Die Einrichtung erfolgt über REST-API mit curl. Die Debezium-UI war während der Migration instabil, daher wurden Konfigurationen manuell im JSON-Format übermittelt.
Beispiel Source-Connector-Konfiguration:
{
"name": "oracle-connector",
"config": {
"connector.class": "io.debezium.connector.oracle.OracleConnector",
"database.hostname": "oracle-host",
"database.port": "1521",
"database.user": "user",
"database.password": "password",
"database.dbname": "ORCLCDB",
"database.server.name": "server1",
"table.include.list": "schema.table1,schema.table2",
"database.history.kafka.bootstrap.servers": "kafka:9092",
"database.history.kafka.topic": "schema-changes"
}
}
Beispiel Sink-Connector-Konfiguration:
{
"name": "postgres-sink",
"config": {
"connector.class": "io.confluent.connect.jdbc.JdbcSinkConnector",
"connection.url": "jdbc:postgresql://postgres:5432/db",
"connection.user": "user",
"connection.password": "password",
"topics": "server1.schema.table1,server1.schema.table2",
"auto.create": "false",
"auto.evolve": "false",
"insert.mode": "upsert",
"pk.mode": "record_key",
"pk.fields": "id"
}
}
Einige Tabellen (z. B. mit Komposit-Schlüsseln) erfordern separate Konfigurationen. Jeder Connector wird isoliert getestet.
Abschließender Wechsel und Qualitätskontrolle
Nach Abschluss des Initial Snapshots und Stabilisierung des Streamings:
- Testinstanzen der Services werden mit PostgreSQL verbunden gestartet.
- End-to-End-Tests werden durchgeführt: API, UI, Hintergrundprozesse.
- Lasttests auf produktionsähnlichen Daten.
- Zum Zeitpunkt minimaler Last wird DNS oder Ingress-Routen auf die neuen Instanzen umgeleitet.
- Logs, Metriken und Alarme werden 24–48 Stunden überwacht.
Rollback ist nur bis zum Umschaltpunkt möglich. Danach läuft das System ausschließlich auf PostgreSQL. Oracle-Backups werden für Notfall-Datenerholung aufbewahrt.
Wichtige Erkenntnisse
- Keine Einheitslösung — jedes Projekt erfordert individuelle Anpassungen.
- CDC ohne Double Writes — ein akzeptabler Kompromiss mit wenigen Sekunden Verzögerung.
- Sequenz-Synchronisation — essenziell, um ID-Konflikte zu vermeiden.
- Tests in jeder Phase — der Schlüssel zu einer stabilen Migration.
- Debezium + Kafka Connect — ein flexibler und zuverlässiger Stack für Online-Migrationen.
Die Migration dauerte inklusive Vorbereitung 18 Stunden, aber die tatsächliche Nutzer-Ausfallzeit betrug 0 Sekunden. Das Projekt läuft seit über einem Jahr erfolgreich auf PostgreSQL ohne Rückschläge.
— Editorial Team
Noch keine Kommentare.