Database-migratie laten uitvoeren: van Oracle, MSSQL of MySQL naar Postgres of cloud

Een database-migratie is zelden een puur technische oefening. Het raakt licentiekosten, applicatie-architectuur, downtime-vensters, datakwaliteit en — als het misgaat — directe omzet. Wij begeleiden migratieprojecten van legacy Oracle, Microsoft SQL Server, MySQL of MongoDB naar Postgres, AWS Aurora, Cloud SQL of Azure Database, met change data capture en parallel-write strategieen die downtime tot minuten of zelfs nul beperken.

Oracle naar Postgres MSSQL naar Postgres MySQL naar Postgres Cloud-migratie CDC met Debezium AWS DMS Zero-downtime cutover
Bespreek uw migratie-case Bekijk migratiepaden
LEGACY POSTGRES CDC

Database-migratie zonder downtime: wat het verschil maakt tussen succesvol en pijnlijk

De meeste mislukte database-migraties stranden niet op het kopieren van rijen. Ze stranden op vergeten stored procedures, op sequence-IDs die hergebruikt worden, op encoding-verschillen tussen WIN1252 en UTF8, of op een cutover-venster dat niet past bij de business. Een goede migratie kijkt eerst naar het hele plaatje — applicatie, schema, data, integraties, monitoring — en kiest pas dan een strategie.

Wij beginnen elk migratieproject met een nuchtere inventarisatie. Welk volume praten we over: 50 GB OLTP of 12 TB historie? Hoeveel reads en writes per seconde tijdens piek? Welke applicaties spreken direct met de database, en welke via een API? Hoeveel stored procedures, triggers, views en jobs draaien op de bron? Welk downtime-venster accepteert de business — een nacht, een uur, of nul? Pas met die antwoorden kiezen we tussen big-bang dump-restore, parallel-write of een full change data capture (CDC) flow.

Wat dan vaak boven water komt: de echte complexiteit zit niet in de tabellen, maar in de aangrenzende systemen. Een Oracle-database die al twintig jaar draait heeft PL/SQL-packages, materialized views en database links naar andere instances. Een legacy MSSQL heeft Linked Servers, SSIS-pakketten en tientallen SQL Agent-jobs. Die meeneembare complexiteit bepaalt vaak meer over het succes dan de Postgres-doelkant zelf.

Typische redenen om weg te gaan van een legacy database

Database-migraties beginnen zelden vanuit nieuwsgierigheid. Er is bijna altijd een concrete trigger — een licentiefactuur, een cloud-strategie of een schaalprobleem dat niet meer met meer hardware op te lossen is.

💰

Licentie-inflatie Oracle en MSSQL

Oracle Enterprise Edition, partitioning, RAC en Data Guard tellen snel op tot zes- of zevencijferige jaarbedragen. Microsoft SQL Server Enterprise per core volgt dezelfde curve. Een overstap naar Postgres of een managed cloud-variant haalt die kostenpost weg en geeft budget voor nieuwe features. pg_partman en pgvector dekken steeds meer use cases die historisch alleen op Oracle werkten.

🔓

Vendor-lock-in doorbreken

PL/SQL-pakketten, T-SQL stored procedures en proprietary types maken het lastig om weg te bewegen. Wij herschrijven business logic naar de applicatielaag of naar plpgsql, zodat u in de toekomst opnieuw kunt kiezen — voor een andere cloud, een ander database-product of een nieuwe runtime — zonder elk schema opnieuw te moeten ontwerpen.

☁️

Cloud-native deployment

On-premise Oracle of MSSQL op een fysieke server schaalt niet mee met containerized applicaties op Kubernetes. Een migratie naar AWS Aurora PostgreSQL, Google Cloud SQL of Azure Database for PostgreSQL geeft automatische backups, point-in-time recovery, leesreplica's en geografische redundantie zonder eigen DBA-werk.

📐

Schema-modernisatie

Tabellen die in 2003 ontworpen zijn voor een VARCHAR2(4000) wereld passen vaak niet meer bij REST-API's en eventgedreven architecturen. Een migratie is het natuurlijke moment om JSONB in te zetten waar dat passend is, surrogate keys toe te voegen, foreign keys te repareren en partitioning naar tijds- of tenant-as in te richten.

Performance op moderne workloads

Postgres met JIT, parallel query, logical replication en moderne indextypes (BRIN, GIN, GiST) presteert op veel OLTP- en analytische workloads beter dan een legacy MySQL 5.7 of een ondergespecificeerde Oracle Standard. Vooral analytische queries op tijdseries en geometrie (PostGIS) zijn typisch waar de winst zit.

🧩

Consolidatie van datasilos

Drie MySQL-databases, twee MSSQL-instances en een MongoDB-cluster die allemaal hetzelfde klantenobject opslaan — wij zien het regelmatig. Een migratietraject wordt dan een consolidatie-project: gegevens samenbrengen in een Postgres-platform met JSONB waar flexibiliteit nodig is, en relationele integriteit waar dat moet.

Zes migratiepaden die wij regelmatig uitvoeren

Niet elke migratie is een 1-op-1 portering. Soms is consolideren slimmer, soms is een hybride bestemming logisch. Dit zijn de paden die in onze projecten het vaakst voorbijkomen.

PadTypische triggerToolchain
Oracle → PostgreSQL Licentiekosten, vendor-lock, modernisering van PL/SQL ora2pg, AWS DMS, custom plpgsql-rewrite
MSSQL → PostgreSQL Per-core licenties, Linux-only deployment, cloud-strategie AWS DMS, pgloader, T-SQL → plpgsql conversie
MySQL → PostgreSQL Behoefte aan transactionele integriteit, JSONB, betere indextypes pgloader, Debezium MySQL connector, logical replication
Oracle → AWS Aurora / Cloud SQL Volledige cloud-migratie, managed service, multi-AZ HA AWS Schema Conversion Tool + DMS, GoldenGate voor zero-downtime
MongoDB consolidatie naar Postgres + JSONB Schema-drift, gebrek aan joins, analytics-pijn Custom ETL, Debezium MongoDB connector, dual-write transitie
NoSQL ↔ SQL of cross-platform Bewuste polyglot-strategie, splitsen van OLTP en OLAP Striim, Kafka Connect, change-data-capture pipelines

Schema-translatie: waar het in de praktijk vastloopt

Een migratietool kan tabellen kopieren. Wat een tool niet voor u doet, is beslissen wat er met datatypes, sequences, views en stored procedures moet gebeuren. Dat is handwerk, en het is precies waar onafhankelijke databases-migraties op vastlopen.

Datatypes mappen, niet kopieren

Oracle's NUMBER zonder precisie wordt vaak verkeerd vertaald naar NUMERIC in Postgres terwijl BIGINT bedoeld was. VARCHAR2 versus TEXT heeft impact op opslag en indices. DATE in Oracle bevat tijdcomponenten — in Postgres heet dat TIMESTAMP. MSSQL's DATETIME2, UNIQUEIDENTIFIER en HIERARCHYID hebben elk een gerichte aanpak nodig.

Sequences en identity-kolommen

Oracle SEQUENCES met NEXTVAL gedragen zich anders dan Postgres-sequences. MSSQL IDENTITY en MySQL AUTO_INCREMENT mappen op Postgres' GENERATED BY DEFAULT AS IDENTITY of klassieke sequences. Wij hernoemen, herstellen de huidige last_value en zorgen dat applicaties geen gat in de IDs creeren tijdens cutover.

Views en materialized views

Oracle-views met CONNECT BY, hierarchische queries en analytische functies vertalen niet 1-op-1. Wij herschrijven naar Postgres' recursieve WITH-clauses en window-functions. Materialized views krijgen een refresh-strategie — incrementeel waar mogelijk via logical replication of een door de applicatie aangestuurde refresh.

Stored procedures: applicatielaag of plpgsql

Honderden PL/SQL-packages 1-op-1 naar plpgsql porteren is technisch mogelijk via ora2pg, maar zelden de beste keuze. Wij analyseren wat business-logic is (verplaatsbaar naar de applicatie of een service-laag) en wat puur datalogica is (blijft in de database als plpgsql). Dat verhoogt testbaarheid en maakt toekomstige migraties trivialer.

Migratiestrategieen: van big-bang tot zero-downtime CDC

De gekozen strategie hangt af van het downtime-venster, het datavolume, de transactiedichtheid en de tolerantie voor risico. Vier strategieen die wij in projecten toepassen.

Big-bang dump & restore

Snelste route voor kleine databases (tot enkele tientallen GB) of niet-kritische systemen. Bron stilzetten, pg_dump of expdp, restoren op de doelkant, applicaties omschakelen. Downtime: enkele uren tot een nacht. Geschikt voor staging-databases, interne tools en historie-archieven die zelden geraadpleegd worden.

Parallel-write en dual-read

De applicatie schrijft tijdelijk naar zowel oude als nieuwe database. Eerst lezen we van oud, valideren we tegen nieuw, en schakelen pas om als de checksums consistent zijn. Past bij applicaties waar we de data-access layer kunnen aanpassen en waar enkele weken parallelle infrastructuur acceptabel is.

Change Data Capture (CDC) met Debezium

Debezium leest het transactielog (Oracle redo logs, MySQL binlog, MSSQL CDC, Postgres WAL) en streamt elke wijziging via Apache Kafka naar de doelkant. Initial load via pg_dump of bulk-load, daarna realtime sync. Cutover-downtime daalt naar minuten. Geschikt voor 24x7 transactionele systemen.

AWS DMS, GoldenGate of Striim

Voor cloud-migraties zonder eigen Kafka-cluster zetten we AWS Database Migration Service in. Voor Oracle-bron met strikte zero-downtime eisen werkt Oracle GoldenGate. Voor cross-platform en heterogene flows is Striim een sterke optie. Tool-keuze hangt af van bron, bestemming, datavolume en hoe lang de bron en doel naast elkaar moeten draaien.

Toolchain die wij inzetten

Geen migratie zonder gereedschap. De keuze hangt af van bron, bestemming en de strategie hierboven. Wij hebben praktijkervaring met onderstaande tools en kiezen pragmatisch — niet op basis van wat het laatste blogartikel aanraadt.

Voor schema en data: ora2pg voor Oracle-naar-Postgres schemaconversie inclusief PL/SQL-rewrite, pgloader voor snelle MySQL-/MSSQL-naar-Postgres bulk-load, AWS Schema Conversion Tool voor automatische assessment van AWS-doel-databases, pg_dump en pg_restore voor Postgres-naar-Postgres met logical replication als follow-up.

Voor change data capture: Debezium connectoren voor Oracle (via LogMiner of XStream), MySQL (binlog), MSSQL (CDC) en MongoDB, gekoppeld aan Apache Kafka. AWS DMS voor managed CDC zonder zelf-gehoste broker. Oracle GoldenGate waar de licentie al aanwezig is en zero-downtime kritiek is.

Voor schema-versionering: Liquibase of Flyway om DDL-changes deterministisch en reproduceerbaar uit te rollen, ook tijdens parallel-write fases. Schema-diff tools zoals migra of Liquibase' diff-functie om afwijkingen tussen bron en doel zichtbaar te maken.

PostgreSQL 15+ ora2pg pgloader AWS DMS Debezium Apache Kafka Liquibase Flyway pg_partman pgvector PostGIS JSONB logical replication COPY GoldenGate Striim

Testen en valideren: niet alleen rij-tellen

Een migratie waar de rij-tellingen kloppen, kan nog steeds business-logic stuk maken. Wij hanteren drie validatielagen die parallel draaien — niet pas op de cutover-avond.

Row-count en checksum-validatie

Per tabel vergelijken we COUNT(*) en aggregate-checksums (md5 of xxhash over relevante kolommen). Geautomatiseerd en herhaalbaar, zodat we de validatie meerdere keren kunnen draaien tijdens parallel-write zonder handwerk. Afwijkingen leveren een tabel-naam plus een rijenrange — niet alleen "de migratie klopt niet".

ETL versus ELT-flows controleren

Veel migraties zijn feitelijk ETL-projecten: extract uit bron, transform onderweg, load in doel. Voor JSONB-consolidatie of schema-redesigns is ELT (rauw laden, transformeren in de doel-database) vaak handiger. Wij valideren dat de transformaties idempotent zijn en dat herhaalde runs geen duplicaten of afwijkingen produceren.

Business-logic equivalence-tests

De zwaarste test: kritieke applicatie-queries laten draaien tegen oude en nieuwe database, en de resultaten 1-op-1 vergelijken. Voor financiele rapportages, factuur-totalen en compliance-queries is dit niet onderhandelbaar. Wij bouwen test-suites met pytest of vergelijkbaar, gekoppeld aan een staging-omgeving, zodat regressies vroeg in het traject zichtbaar worden.

Cutover-planning: het uur waarop u iets doms niet wilt doen

Cutover is het moment waarop applicaties van bron naar doel switchen. Hoe goed de migratie ook is voorbereid, dit blijft het meest gespannen uur van het traject. Wij leveren altijd een gedetailleerd cutover-runbook op, getoetst in dry-runs, met expliciete go/no-go criteria en een teruggetest rollback-plan.

Een typisch runbook bevat: bevestiging dat CDC-lag onder 5 seconden zit, freeze van schema-changes 24 uur voor cutover, applicatie-gezondheidscontroles op zowel oude als nieuwe omgeving, een DNS-/connection-string switch met TTL die past bij het downtime-venster, een smoke-test suite die binnen 10 minuten draait, en go/no-go beslismomenten met de business. Falen we de smoke test, dan rollen we terug — geen heroiek.

Onze aanpak in vier fasen

Geen maandenlang vooronderzoek zonder concreet resultaat. Elke fase eindigt met iets aantoonbaars — een assessment, een POC, een dry-run, een productie-cutover.

Assessment

Inventarisatie van bron-schema, datavolume, transactiedichtheid, integraties, downtime-venster en compliance-eisen. Resultaat: migratiepad, toolchain-keuze en risicokaart.

Schema-conversie en POC

Schema-vertaling, sequence-mapping, view-rewrite. Eerste end-to-end run op een staging-doel met representatieve data. Validatie via row-count en checksums.

CDC en parallel-run

CDC-pipeline (Debezium of DMS) opgezet, initial load gedraaid, replication-lag gemonitord. Applicatie schrijft optioneel parallel. Equivalence-tests draaien dagelijks.

Cutover en optimalisatie

Cutover volgens runbook, smoke-tests, monitoring scherpgesteld. Daarna: indextuning, VACUUM-strategie, autovacuum-instellingen en eventuele pg_partman-partitionering.

Veelgestelde vragen over database-migratie

Hoe lang duurt een typische Oracle-naar-Postgres migratie?
Van eerste assessment tot productie-cutover varieert het van zes weken voor een compacte applicatie tot zes tot twaalf maanden voor een Oracle-database van enkele TB met honderden PL/SQL-packages, materialized views en kritische integraties. Het pad is bijna altijd: assessment, POC, schema-conversie, parallel-run en cutover. Wij doen geen big-bang over een nacht voor een productiedatabase tenzij volume en complexiteit dat echt toelaten.
Wat is het verschil tussen ETL en ELT bij een migratie?
ETL transformeert data tijdens transport — de migratietool herstructureert tabellen, splitst kolommen of voegt referenties toe voordat het in de doel-database landt. ELT laadt eerst rauw en transformeert binnen de doel-database, vaak met SQL of plpgsql. ELT is efficienter bij grote volumes en wanneer u JSONB als transitiestaat gebruikt. ETL past beter bij sterke schema-redesigns of wanneer de doel-database geen ruimte heeft voor stagingtabellen.
Waarvoor gebruikt u Debezium versus AWS DMS?
Debezium is open source, draait op uw eigen Kafka-cluster en geeft maximale controle — handig in zelf-gehoste of multi-cloud scenario's. AWS DMS is een managed service zonder Kafka-overhead, ideaal als de bestemming AWS Aurora of RDS is en u geen eigen streaming-platform wilt onderhouden. Voor Oracle-bronnen met zware load is Oracle GoldenGate vaak de meest stabiele keuze, mits de licentie al beschikbaar is.
Migreren jullie ook naar MongoDB of NoSQL als doel?
Ja, maar wij adviseren in de meeste gevallen om relationele data niet zonder bewuste reden naar een document-store te verplaatsen. Vaak werkt Postgres met JSONB beter — u krijgt schema-flexibiliteit waar dat nodig is en SQL-joins waar dat handig is. Voor specifieke use cases (write-heavy logs, eventual-consistent caches, geo-replicated key-value stores) is een NoSQL-bestemming wel passend.
Hoe gaat u om met stored procedures die niet 1-op-1 vertalen?
Eerst inventariseren we welke procedures echt business-logic bevatten en welke puur dataconsistentie afdwingen. Business-logic verhuist bij voorkeur naar de applicatielaag of een service-laag — daar is het testbaar en versie-beheerd in dezelfde repository als de rest van de code. Pure datalogica (constraints, triggers voor audit-tables) blijft in de database als plpgsql. Voor complexe analytische functies herschrijven we naar Postgres' window-functions of materialized views.
Kan downtime echt nul zijn?
In de meeste praktijksituaties haalt u met CDC plus parallel-write een cutover-downtime van enkele seconden tot enkele minuten — de tijd die nodig is om de connection-string van de applicatie te switchen en de laatste replication-lag op te halen. Echte zero-downtime (geen enkele dropped connection, geen enkel mislukt request) vergt extra investeringen in feature-flag gestuurde data-access en zorgvuldige routering. We adviseren vaak een venster van twee tot tien minuten op een rustig moment — meestal volstaat dat ruim.
Wat doet u met character encoding-verschillen?
Een veelgemaakte valkuil. Oracle-databases draaien vaak op WE8MSWIN1252 of AL32UTF8, MSSQL gebruikt SQL_Latin1_General_CP1_CI_AS als default, MySQL was lange tijd latin1 en is vaak migrated naar utf8mb4. Postgres draait standaard op UTF8. Wij detecteren mojibake (foute dubbele encoding), normaliseren naar UTF8 en valideren met steekproeven op tekstvelden waar accenten en speciale tekens voorkomen.
Hoe voorkomt u dat sequence-IDs gaten of duplicaten krijgen?
Tijdens parallel-write leveren beide databases hun eigen IDs op. Wij lossen dit op met een sequence-rename-strategie: de oude sequence loopt door, de nieuwe sequence krijgt een offset (bijvoorbeeld oude max + 1.000.000), en op cutover-moment alignen we de waarden zonder applicatieverwarring. Voor UUID-gebaseerde primaire sleutels is dit triviaal. Voor numerieke IDENTITY-kolommen vergt het zorgvuldige boekhouding tijdens dry-runs.

Database-migratie laten uitvoeren?

Plan een vrijblijvend gesprek. Wij beoordelen uw migratiepad, downtime-eisen en risicoprofiel — en leveren een concreet voorstel met fasering, toolchain en cutover-strategie.

Plan een migratie-assessment

Edit Content