18.1 Oracle → PostgreSQL (ora2pg)
Oracle에서 PostgreSQL로 마이그레이션은 라이선스 비용·자유도·클라우드 친화 때문에 흔히 추진됩니다. 가장 표준적인 도구는 ora2pg(Perl 기반, GPL 오픈소스). ora2pg의 동작과 단계별 마이그레이션 절차를 정리합니다.
마이그레이션 전 평가
flowchart TD
A["스키마 평가"]
B["PL/SQL 평가"]
C["데이터량·전송 시간"]
D["application 코드 변경 평가"]
E["테스트·검증 계획"]
F["cutover 절차"]
A --> B --> C --> D --> E --> F
classDef step fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
class A,B,C,D,E,F step
ora2pg가 evaluation report 자동 생성합니다.
ora2pg 설치
sudo dnf install -y perl-DBI perl-DBD-Oracle perl-DBD-Pg
# Oracle Instant Client 별도 설치 필요
# CPAN 또는 GitHub release
sudo cpan install Ora2Pg
# 또는
git clone https://github.com/darold/ora2pg.git
cd ora2pg && perl Makefile.PL && make && sudo make install설정 — ora2pg.conf
# Oracle 연결
ORACLE_DSN dbi:Oracle:host=oracle.example.com;sid=ORCL
ORACLE_USER scott
ORACLE_PWD tiger
# PostgreSQL 출력 (또는 직접 연결)
PG_DSN dbi:Pg:dbname=app_main;host=pg.example.com
PG_USER pgadmin
PG_PWD secret
# 출력
OUTPUT output.sql
TYPE TABLE # TABLE / DATA / TRIGGER / FUNCTION / 등
# 옵션
EXPORT_SCHEMA 1
SCHEMA APPSCHEMA
PG_SCHEMA public
# 데이터 일괄 처리
DATA_LIMIT 10000
BLOB_LIMIT 500
PARALLEL_TABLES 4단계별 실행
ora2pg는 type별로 여러 번 실행:
# 1. 평가 report
ora2pg -c ora2pg.conf -t SHOW_REPORT --estimate_cost > report.txt
# 2. 스키마 (DDL)
ora2pg -c ora2pg.conf -t TABLE -o tables.sql
ora2pg -c ora2pg.conf -t SEQUENCE -o sequences.sql
ora2pg -c ora2pg.conf -t INDEX -o indexes.sql
ora2pg -c ora2pg.conf -t VIEW -o views.sql
ora2pg -c ora2pg.conf -t TRIGGER -o triggers.sql
ora2pg -c ora2pg.conf -t FUNCTION -o functions.sql
ora2pg -c ora2pg.conf -t PROCEDURE -o procedures.sql
# 3. 데이터 (가장 오래)
ora2pg -c ora2pg.conf -t COPY # PG로 직접 적용
# 또는
ora2pg -c ora2pg.conf -t COPY -o data.sql평가 report
-------------------------------------------------------------------------------
Oracle Database Content Report -- ORA2PG_VERSION 25.0
-------------------------------------------------------------------------------
Object Number Invalid Estimated cost Comments
-------------------------------------------------------------------------------
TABLE 127 0 0
INDEX 341 0 0
TRIGGER 23 0 50 Note: 자동 변환 가능
PROCEDURE 89 0 800 Note: 일부 수동 변경 필요
FUNCTION 156 0 1200 Note: PL/SQL 패키지 의존
SEQUENCE 64 0 0
PACKAGE 34 0 950 Note: PostgreSQL은 package 미지원
SYNONYM 12 0 30
...
-------------------------------------------------------------------------------
Total 3030 3030 단위 / man-daycost가 man-day 단위 — 평가가 1000이면 약 5인 month.
자동 변환되는 것
| Oracle | PostgreSQL |
|---|---|
NUMBER(p) | numeric(p) |
VARCHAR2(n) | varchar(n) |
CLOB | text |
BLOB | bytea |
DATE | timestamp |
TIMESTAMP WITH TIME ZONE | timestamptz |
sequence MYSEQ.NEXTVAL | nextval('myseq') |
SYSDATE | now() |
| ` | |
DECODE(...) | CASE ... END |
NVL(a, b) | COALESCE(a, b) |
ROWNUM | LIMIT (또는 window function) |
CONNECT BY (계층 쿼리) | WITH RECURSIVE |
ora2pg가 대부분 자동 변환합니다. 일부 PL/SQL은 수동 검토합니다.
자동 변환 어려운 것
| Oracle | PostgreSQL 대응 |
|---|---|
| PACKAGE | 없음 — schema·function 묶음으로 |
| TYPE BODY | composite type + function |
| DBMS_* | 일부 — pg-equivalent 또는 application 로직 |
| 외부 procedure | extension 또는 외부 service |
| Global temporary table | CREATE TEMP TABLE (세션 스코프 동일) |
| AUTONOMOUS_TRANSACTION | dblink 또는 PG의 BEGIN ... COMMIT 외부 |
| MERGE | PG 15+ MERGE 지원, 그 전엔 ON CONFLICT |
| MATERIALIZED VIEW LOG | logical replication 또는 trigger |
EDB Postgres Advanced Server (EPAS)
상용 배포본 — Oracle PL/SQL을 대부분 그대로 실행합니다. 마이그레이션 부담 ↓, 라이선스 비용 ↑.
| 측면 | PG + ora2pg | EDB EPAS |
|---|---|---|
| 비용 | 무료 | EDB 라이선스 |
| 호환 | 코드 재작성 필요 | Oracle PL/SQL 호환 |
| 미래 | 표준 PG 길 | EDB 의존 |
데이터 마이그레이션 — 무중단 전환
대용량은 full dump가 시간 너무 큽니다. 무중단 패턴:
1. 스키마 PG로 (ora2pg 자동)
2. 초기 데이터 COPY (대부분 시간 소요)
3. Oracle → PG의 CDC 시작 (Debezium·Striim·자체 trigger 기반)
4. application의 read를 점진 PG로
5. write도 PG로 cut-over
6. Oracle decommission대규모(TB 단위)에서는 3rd party 도구 추천 — Striim·Qlik Replicate·AWS DMS.
AWS DMS (Database Migration Service)
AWS의 매니지드 마이그레이션 도구입니다. Oracle·SQL Server·MySQL → PostgreSQL.
source endpoint (Oracle)
target endpoint (RDS PostgreSQL)
replication instance
task: full load + ongoing replication (CDC)대용량 마이그레이션의 표준 옵션.
application 변경
| 영역 | 변경 |
|---|---|
| 드라이버 | ojdbc → pgJDBC |
| connection string | 다름 |
| Quoted identifier | Oracle은 모든 대문자, PG는 소문자 — 케이스 주의 |
| empty string vs NULL | Oracle은 동일, PG는 다름 — 검증 필요 |
| 시퀀스 호출 | SELECT myseq.NEXTVAL FROM dual → SELECT nextval('myseq') |
| outer join | (+) 대신 LEFT JOIN |
| hint | /*+ INDEX(...) */ 동작 안 함 — pg_hint_plan |
검증 — row count + checksum
-- Oracle
SELECT count(*), sum(amount) FROM orders;
-- PostgreSQL — 같은 결과여야
SELECT count(*), sum(amount) FROM orders;각 테이블에 대해 row count, sum, hash 비교합니다. 자동화합니다.
cutover 절차
- 애플리케이션 트래픽 일시 정지 (수 분)
- 마지막 변경 데이터 동기화
- 검증 쿼리 실행
- application connection을 PG로 전환
- read·write 정상 확인
- Oracle은 read-only로 두고 일정 기간 관찰
- Oracle decommission
정리
- ora2pg = Oracle → PG 마이그레이션의 표준 도구
- 평가 report로 작업량 미리 산정 (man-day)
- 스키마·시퀀스·trigger·function 대부분 자동 변환
- PACKAGE·DBMS_*·복잡 PL/SQL은 수동 검토
- 대용량 데이터는 CDC 기반 무중단 마이그레이션
- application 변경: 드라이버·시퀀스·quoting·outer join 등
다음 절(18.2)에서는 MySQL → PostgreSQL의 패턴을 봅니다.