# Migrace z Oracle na PostgreSQL bez výpadku: technický rozbor
Přechod z Oracle na PostgreSQL bez zastavení služby je složitý, ale proveditelný úkol. V tomto materiálu rozebereme krok za krokem strategii migrace založenou na reálném projektu s mikroslužbami na Spring Boot, kde klíčovým požadavkem bylo nulové ovlivnění uživatelů. Použití CDC přes Debezium umožnilo synchronizovat data v reálném čase, vyhnout se výpadkům a minimalizovat rizika.
Příprava: analýza struktury a dat
První etapa – důkladný audit stávající databáze. Je třeba pochopit objem dat, rozložení typů polí, přítomnost zastaralých záznamů a specifických konstrukcí Oracle, které nemají přímé analogy v PostgreSQL. Vyčištění neaktualních dat snižuje objem migrace a urychluje proces.
Klíčový moment – shoda typů dat. Například:
NUMBER(1,0)→BOOLEANVARCHAR2→TEXTneboVARCHARDATE→TIMESTAMP WITHOUT TIME ZONECLOB→TEXT
Pro analýzu byl použit SQL dotaz:
select distinct DATA_TYPE
from ALL_TAB_COLUMNS
where owner = 'schemat'
order by DATA_TYPE
Na základě výsledků byla sestavena tabulka shody typů, která sloužila jako základ všech následných transformací. Důležité je také zohlednit rozdíly v zpracování NULL a prázdných řetězců: v Oracle je prázdný řetězec interpretován jako NULL, v PostgreSQL ne. To vyžaduje úpravu business logiky a dotazů.
Adaptace schématu a Liquibase
Jednoduchá výměna ovladače DB vede k chybám. Migrační skripty musí být přizpůsobeny pro PostgreSQL. K tomu:
- DDL a DML operace jsou odděleny přes kontexty Liquibase – DML je dočasně vypnuto.
- Skripty se iterativně testují: po každé úpravě proběhne changelog, vyčištění a smoke testování.
- Kontroluje se správnost preconditions a konzistence schématu s Oracle.
Zvláštní pozornost věnována sekvencím. Pokud se nesynchronizují, nové ID mohou kolidovat s historickými daty. Řešení:
- Při startu aplikace se kontroluje aktuální hodnota sekvence v PostgreSQL.
- Pokud je menší než v Oracle – provede se posun s rezervou.
- Logika je idempotentní: opakované spuštění nezpůsobí selhání.
Výsledkem bylo sestavení cílového schématu PostgreSQL v jednom pull requestu, připraveného na naplnění daty.
Úprava kódu aplikace
Po úspěšném spuštění aplikace na prázdné PostgreSQL se odhalí chyby na úrovni Java kódu. Hlavní změny:
- Výměna anotace
@Lobza@Column(columnDefinition = "text"). - Zpracování NULL v nativních SQL dotazech, zejména v konstrukcích
IN (...). - Přechod z číselných příznaků (0/1) na
boolean. - Úprava logiky porovnávání řetězců s ohledem na rozdíly Oracle/PostgreSQL.
- Přepsání nativních dotazů s ohledem na dialekt PostgreSQL.
Testování probíhalo na úrovni unit testů a integračních scénářů. Zvláštní pozornost věnována hraničním případům: prázdné řetězce, NULL hodnoty, velká textová pole.
Implementace CDC přes Debezium a Kafka Connect
Vybrán klasický stack: Debezium + Kafka Connect. Architektura:
- Source konektor (Debezium Oracle) čte redo log a generuje CDC události.
- Události se posílají do Kafka (jeden topic na tabulku).
- Sink konektor (JDBC Sink) aplikuje změny do PostgreSQL ve stejném pořadí.
Etapy nastavení:
- Initial Snapshot – kompletní kopírování dat v okamžiku startu.
- Streaming Changes – kontinuální replikace INSERT/UPDATE/DELETE z redo logu.
- Order Preservation – záruka zachování pořadí změn díky LogMiner.
Použité image:
quay.io/debezium/kafka:3.0quay.io/debezium/zookeeper:3.0quay.io/debezium/connect:3.0provectuslabs/kafka-ui:0.7.2(pro monitorování)
Nastavení probíhá přes REST API pomocí curl. UI od Debezium bylo v době migrace nestabilní, proto se konfigurace posílají ručně ve formátu JSON.
Příklad konfigurace source konektoru:
{
"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"
}
}
Příklad konfigurace sink konektoru:
{
"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"
}
}
Některé tabulky (např. s kompozitními klíči) vyžadují samostatnou konfiguraci. Testování každého konektoru probíhá izolováně.
Finální přechod a kontrola kvality
Po dokončení initial snapshot a stabilizaci streamingu:
- Spustí se testovací instance služeb připojené k PostgreSQL.
- Proveďe se end-to-end testování: API, UI, pozadí procesy.
- Bude provedeno zatížové testování na produkčních datech.
- V okamžiku minimální zátěže – přepnutí DNS nebo ingress tras na nové instance.
- Monitorování logů, metrik a alertů po dobu 24–48 hodin.
Rollback je plánován pouze do okamžiku přepnutí. Poté systém běží výhradně na PostgreSQL. Zálohy Oracle se uchovávají pro případ nouzového obnovení dat.
Co je důležité
- Žádné univerzální řešení – každý projekt vyžaduje individuální přizpůsobení.
- CDC bez dvojitého zápisu – přijatelný kompromis při tolerovatelném zpoždění několika sekund.
- Synchronizace sekvencí – nezbytná k prevenci kolizí ID.
- Testování na každé etapě – klíč k stabilní migraci.
- Debezium + Kafka Connect – flexibilní a spolehlivý stack pro online migrace.
Migrace trvala 18 hodin včetně přípravy, ale skutečný výpadek pro uživatele činil 0 sekund. Projekt úspěšně běží na PostgreSQL již více než rok bez regrese.
— Editorial Team
Zatím žádné komentáře.