Die Datenbank-Saga:
Eine epische Migration mit AWS DMS
Wie ein Unternehmen seine Oracle-Datenbank mithilfe von AWS DMS nach PostgreSQL migrierte – ein Abenteuerbericht voller Learnings, Stolperfallen und heldenhafter Optimierungen.
Kapitel 1: Der Ruf zum Abenteuer
In den tiefen Kammern eines mächtigen Unternehmens gab es eine riesige Schatzkammer. Dort lebte ein Orakel (Fußnote: Oracle Database Enterprise Edition), das über Jahre hinweg Wissen gesammelt hatte – doch seine Zeit lief langsam ab. Der unerbittliche Drache Lizenzuskostus hatte sich in der Schatzkammer breitgemacht und hielt das Königreich der IT in Atem. Es musste ein Weg gefunden werden, die unermesslichen Datenschätze zu retten.
So erreichte uns der Ruf zum Abenteuer. Drei mutige IT-Helden wurden auserwählt, sich der Herausforderung zu stellen: Die Schätze sollten in eine neue Schatzkammer transportiert werden. Dort würden sie von einem großen Elefanten (Fußnote: PostgreSQL) bewacht werden.
Doch die Aufgabe war gefährlich. Der Drache schläft immer nur 1,5 Tage, kein einziger Datenschatz durfte verloren gehen, und ein Rückweg für Notfälle musste stets bereitstehen.
So beginnt jede große Heldengeschichte – mit einem Risiko, mit Angst und Zweifeln, aber auch mit der Aussicht auf Ruhm und Erkenntnis. Der erste naive Plan war schnell geschmiedet. Wie jeder Held jedoch wissen muss: Nichts ist so einfach, wie es scheint …
Der Kunde betreibt eine seiner wichtigen Businessanwendungen inkl. zugehöriger Datenbank in der AWS-Cloud. Aufgrund der hohen Lizenzkosten sollte die damals genutzte Oracle- durch eine PostgreSQL-Datenbank ersetzt werden. Die Anwendung wird montags bis freitags genutzt, weshalb die Datenmigration an einem Wochenende stattfinden musste. Es musste zwei Wochen lang möglich sein, auf die Oracle-Datenbank zurückzuwechseln.
Kapitel 2: Die Helden rüsten sich
Einer der Helden hatte von einem magischen Artefakt namens AWS DMS gehört, das es erlaubt, Schätze aus einer Datenbank ganz einfach in eine neue zu transportieren.
AWS DMS [1] ist ein Service für Datenbankmigrationen innerhalb der AWS-Cloud. Man definiert Replikations-Tasks, um die Daten aus den Tabellen zwischen den Datenbanken zu übertragen. Diese werden auf einer Replikations-Instanz ausgeführt. Damit die Tasks auf die Datenbanken zugreifen können, müssen zusätzlich Endpunkte konfiguriert werden [2].

Die Helden bauten das Artefakt auf und warteten gespannt, dass es seine Magie wirkte. Doch nach drei Tagen mussten sie einsehen, dass es zu lange dauerte. Der König hatte ihnen gesagt, dass sie nur 1,5 Tage Zeit hätten. Sie wälzten also einen dicken Folianten mit den Geheimnissen des Artefakts und lernten, den Transport zu beschleunigen. Mit diesen Maßnahmen konnte die Migrationsdauer auf ein Drittel reduziert werden.
Der erste Versuch die gesamte Datenbank in einem Durchgang zu migrieren dauerte zu lange. Um die Migration zu beschleunigen haben wir die Tabellen der Größe nach in mehrere Tasks aufgeteilt, die wir mit einer stärkeren Replikations-Instanz parallel ausgeführt haben. Damit die Oracle-Datenbank den höheren Durchsatz effizient verarbeiten konnte haben wir temporär eine größere Instanz gewählt, Constraints deaktiviert und Indices erst nach der Migration aufgebaut.
Kapitel 3: Die Helden müssen Rätsel lösen
Nachdem es den Helden gelungen war, die Schätze das erste Mal in einem Probelauf zu transportieren, stellten sie fest, dass etwas nicht stimmte. Zuerst sah alles gut aus, aber als sie genauer hinschauten, stellten die Helden fest, dass sich einige der Datenschätze beim Transport verändert hatten. Und noch schlimmer: Ein Teil der Schätze fehlte sogar. Die Helden seufzten laut und begannen, den Weg abzulaufen, um herauszufinden, warum sich die Daten verändert hatten und wo welche verloren gegangen waren.
1. Duplicate Key Violations
Beim Speichern traten plötzlich Konflikte auf – Ursache war, dass AWS DMS keine Sequences überträgt. Mit einem SQL-Skript, das den höchsten Schlüsselwert je Tabelle ermittelt, konnten wir die Sequences aktualisieren.
2. Boolean-Mapping-Fehler
Tabellen mit Boolean-Spalten wurden nicht korrekt übertragen. In den Logs erschien: „Error: ‚true‘ is not a valid boolean“!
AWS DMS mappt Datentypen als erstes auf einen internen Typ und anschließend auf den passenden Typ für die Zieldatenbank. Der Orcale Typ number(1,0) wird auf BOOLEAN gemappt. Standardmäßig wird BOOLEAN zu varchar(5) transfomiert. In der Zieldatenbank haben wir die Spalte aber mit boolean definiert, was zu dem Fehler führte. Durch eine Konfiguration an dem Endpunkt konnte das Mapping korrigiert werden.
3. Nicht migrierte Tabelle ohne Fehlermeldung
Eine Tabelle wurde komplett ignoriert – ohne Hinweis in den AWS DMS Logs. Sie unterschied sich auf den ersten Blick nicht von den anderen Tabellen.
Auf den zweiten Blick fiel auf das eine der Spalten einen sehr sperrigen Namen hatte (VALUE_ADDED_TAX….). Es stellte sich raus, dass Spaltennamen, die länger als 38 Zeichen sind, werden von AWS DMS ignoriert – vermutlich ein Überbleibsel aus Zeiten, in denen Oracle diese Länge beschränkte.
Die Helden konnten alle Probleme identifizieren und beheben.
Kapitel 4: Die Helden planen für den Notfall
Nach mühevoller Suche fanden die Helden alle Stolpersteine, die auf dem Weg zu Problemen geführt hatten, und konnten sie wegräumen. Der Weg war frei, um den Schatz umzuziehen.
Doch der König bangte: Was, wenn die neue Schatzkammer nicht so gut wäre, wie ihm versprochen wurde? Was würde dann aus all seinen Schätzen werden? Ein Notfallplan wurde geschmiedet!
Neben der einmaligen Replikation („Full Load“) unterstützt AWS DMS auch eine fortlaufende Replikation („Change Data Capture“), die auf Transaktionslogs basiert. Änderungen werden dabei nicht direkt aus der Datenbank, sondern aus den Logs ausgelesen und auf die Zieldatenbank übertragen – vorausgesetzt, die Logs stehen lange genug zur Verfügung.
Wir planten, PostgreSQL und Oracle für zwei Wochen synchron zu halten, um im Fall eines Rollbacks zurückwechseln zu können.

Beim Testen traten Probleme bei der Rückreplikation auf. Besonders auffällig: ein Fehler bei der Verarbeitung von Datumswerten. Während PostgreSQL das Format „YYYY-MM-DD“ nutzt, war in Oracle standardmäßig „MM/DD/YYYY“ hinterlegt. Diese Abweichung führte zu einem ORA-01843-Fehler. Da AWS DMS diesen Parameter beim Verbindungsaufbau nicht überschreibt, setzten wir gezielt einen LOGON-Trigger ein, um das Format nur für den DMS-User korrekt zu setzen. Auch bei CLOB-Werten kam es zu unerwartetem Verhalten. Obwohl TEXT-Werte von PostgreSQL beim Rückschreiben als CLOB erwartet wurden, blieben die Felder leer. AWS DMS unterstützt kein direktes Mapping in diese Richtung. Unsere Lösung: manuelle Migration der betroffenen Spalten.

Dazu exportierten wir die Daten als CSV, nummerierten sie durch, importierten sie in eine temporäre Tabelle und aktualisierten die Zielspalten gezielt anhand der Indizes.
Kapitel 5: Die Helden schreiten zur Tat
Nun war es endlich so weit: Der Transport der Schätze konnte beginnen. Alles verlief ohne Schwierigkeiten, sodass keiner der Schätze beschädigt wurde. Viele Kutschen fuhren an dem Tag zwischen den Datenbanken, um die Schätze zu transportieren, und auch in der Nacht wurde fleißig weitergearbeitet. Als der nächste Tag anbrach, stellten die Helden erschöpft fest, dass es ihnen nicht gelungen war, den Schatz vollständig in die neue Schatzkammer zu transportieren. Langsam dämmerte die Erkenntnis, dass nicht mehr genug Zeit blieb, bevor der Drache wieder erwachen würde. Sie mussten den Transport stoppen und ihren Plan überarbeiten. Dabei kamen einige magische Tricks zum Einsatz, mit denen es im zweiten Anlauf gelang, alle Schätze deutlich schneller zu transportieren.
Da eine vollständige Migration nicht an einem Wochenende möglich war, entschieden wir uns für eine zweistufige Vorgehensweise:
Zuerst migrierten wir alle Daten bis zu einem festgelegten Stichtag, danach das Delta der neu hinzugekommenen Daten.
Die Oracle-Datenbank wurde an einem Wochenende geklont, während die Anwendung gestoppt war. Anschließend konnten wir alle bis zum Stichtag vorhandenen Daten in die neue PostgreSQL-Datenbank übertragen. Neue Daten, die nach dem Stichtag eingingen, wurden weiterhin in Oracle und den Transaktionslogs gespeichert.
Diese Logs bildeten die Grundlage für eine fortlaufende Replikation. Nach wenigen Tagen war das Delta ebenfalls übertragen und die Systeme synchron. Die Anwendung konnte nun auf PostgreSQL umgestellt werden. Zur Sicherheit hielten wir die Synchronisierung via Rückreplikation noch zwei Wochen aufrecht, bevor Oracle endgültig abgeschaltet wurde.

Kapitel 6: Das Abenteuer endet
Die alte Datenbank wurde abgeschaltet. Der Drache gebannt. Die Helden ruhen sich aus – bis zum nächsten Abenteuer.
Über den Autor
Stefan Becker ist Senior Software Architect bei BettercallPaul in München. Seit über 9 Jahren bringt er seine Expertise in komplexe Softwareprojekte ein – vor allem im Automotive Umfeld. Als technischer Lead und DevOps-Experte begleitet er Kunden entlang der gesamten Entwicklungsstrecke: von Architektur und Implementierung bis hin zum Betrieb und zur kontinuierlichen Weiterentwicklung. Stefan denkt ganzheitlich, findet pragmatische Lösungen und bringt Teams mit Weitblick und Verlässlichkeit voran. Seine Werkzeuge: Java, Kubernetes, PostgreSQL, Cloud-Infrastrukturen und eine gute Portion Teamgeist.
Quellen:
[1] https://aws.amazon.com/dms/
[2] https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Introduction.HighLevelView.html
[3] https://docs.aws.amazon.com/dms/latest/userguide/CHAP_BestPractices.html#CHAP_BestPractices.Performance
[4] https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Target.PostgreSQL.html#CHAP_Target.PostgreSQL.Limitations
[5] https://repost.aws/questions/QUBfs3Gsi7Tb-s_VSCbRQd8A/aws-dms-38-character-limit
[6] https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Tasks.CustomizingTasks.TableMapping.SelectionTransformation.Transformations.html