MSSQL → Oracle 마이그레이션: 체크리스트와 실전 검증 전략
MSSQL(SQL Server)에서 Oracle로의 마이그레이션은 단순 데이터 이동(Copy & Paste)이 아니라 이기종(Heterogeneous) 전환입니다.
엔진 아키텍처, 데이터 타입, 문자열/NULL 처리, 트랜잭션/락(동시성 모델) 등 근본 차이 때문에, “툴로 옮기면 끝”으로 접근하면 조용한 데이터 오류(silent error) 와 운영 장애가 뒤늦게 터질 가능성이 큽니다.
이 글은 엔터프라이즈 환경에서 다음 3가지 전환 시나리오를 모두 커버합니다.
- 무중단(Zero Downtime): CDC 기반 실시간 동기화 후 컷오버
- 저다운타임(Low Downtime): Bulk + Delta(변경분) 방식
- 중단 전환(Full Downtime / Big Bang): 서비스 중단 후 일괄 이관·검증·오픈
그리고 각 시나리오별로:
- 사전 Assessment 체크리스트
- 선택 기준(언제 어떤 전략을 쓰는지)
- 실행 Runbook(실무 절차)
- 정합성 검증(Verification) 쿼리/방법론
까지 한 번에 정리합니다.

0) 가장 먼저 결정해야 할 것: “전환 방식(컷오버 모드)” 3종
전환 방식은 멋있어 보여서가 아니라, 허용 다운타임, 변경량, 데이터 규모, 운영 리스크로 결정합니다.

전환 전략 A: CDC 기반 무중단(Zero Downtime)
- 대상: 24×7 무중단 필수(금융/커머스/핵심 결제)
- 핵심: Initial Load 후, 로그 기반 변경분을 실시간으로 Oracle에 반영 → Lag=0이면 연결만 스위칭
- 장점: 다운타임 최소(컷오버 순간의 커넥션 전환 수준)
- 단점: 설계/운영 난이도 높음(모니터링/재처리/DDL 관리 포함)
전환 전략 B: 저다운타임(Low Downtime) — Bulk + Delta
- 대상: 주말 새벽 등 4~6시간 점검 윈도우가 확보되는 경우
- 핵심: D-7에 전체 Bulk 이관 → D-Day에 변경분(Delta)만 적용 → 검증 후 스위칭
- 장점: CDC 대비 단순, 운영 난이도 낮음
- 단점: Delta 추출/적용 기준(UpdatedAt 등) 설계가 필수
전환 전략 C: 중단 전환(Full Downtime / Big Bang)
- 대상: 내부 업무 시스템/비핵심 서비스/데이터 규모가 작거나 변경량이 낮은 시스템, 또는 운영 리스크를 단순화하고 싶은 경우
- 핵심: 서비스 중단(쓰기 중지 포함) → 최종 스냅샷/덤프 → 이관 → 전수 검증 → 오픈
- 장점: 가장 단순하며 “동기화 복잡도”가 거의 없음
- 단점: 다운타임이 길어질 수 있고, 검증/롤백이 시간에 직접 영향을 줌
1) 마이그레이션 시작 전: 핵심 체크리스트 (Assessment)
이 단계가 성공의 80%를 좌우합니다. “두 DB의 다름”을 문서로 고정하지 않으면, 이관 후 운영에서 반드시 사고가 납니다.
1.1 데이터 타입 매핑(Data Type Mapping) — 자동 변환 툴을 그대로 믿지 말 것
자동화 도구는 참고용이고, 최종 매핑은 반드시 수동 검증 매핑표로 확정해야 합니다.

대표적인 사고 구간 위주로 정리하면:
| 구분 | MSSQL (Source) | Oracle (Target) | ⚠️ 주의 및 변환 전략 |
|---|---|---|---|
| 대용량 문자열 | VARCHAR(MAX), TEXT | CLOB | Oracle VARCHAR2는 길이 제한이 있음. MAX 계열은 원칙적으로 CLOB |
| 유니코드 문자열 | NVARCHAR, NVARCHAR(MAX) | NVARCHAR2, NCLOB 또는 UTF-8 기반 CLOB | 문자셋(NLS) 정책에 따라 결정. 한글/이모지/특수문자 리허설 필수 |
| 날짜/시간 | DATETIME, DATETIME2 | DATE 또는 TIMESTAMP(p) | Oracle DATE는 “초”까지만 저장. ms 보존 필요 시 TIMESTAMP 강제 |
| 자동 증가 | IDENTITY | IDENTITY(12c+) 또는 SEQUENCE | 시퀀스 초기값/캐시/갭 정책 포함해 설계 |
| UUID | UNIQUEIDENTIFIER | RAW(16) 또는 CHAR(36) | 저장/인덱스 효율과 가독성 트레이드오프 |
| 바이너리/이미지 | VARBINARY(MAX), IMAGE | BLOB | LOB는 별도 트랙(Pre-load)로 분리하는 것이 일반적으로 안전 |
1.1.1 문자열/NULL 처리(가장 치명적인 함정)
- SQL Server:
NULL과''(빈 문자열)은 구분됨 - Oracle: 일반적으로
''을 NULL로 취급하는 동작이 존재
즉, SQL Server에서 의미 있게 쓰이던 ''이 Oracle에서 NULL로 들어가면:
- NOT NULL 컬럼에서 제약 위반
- 의미 값 소실(정합성 훼손)
- 비교/조인 결과 변화
실무 대응 정책(권장)
- 빈 문자열이 “의미 값”이면 표준 치환값(예:
<EMPTY>또는 공백 1칸 등)을 정의하고 이관 시 변환 - 의미 값이 아니면, 소스에서 빈 문자열을 NULL로 정규화하고 타깃 제약/디폴트를 재설계
1.2 SQL 문법/함수 차이(T‑SQL vs Oracle SQL/PLSQL)
문법 치환 자체보다 “결과 동치성(semantic equivalence)”이 핵심입니다.
- TOP N:
TOP (N)→FETCH FIRST N ROWS ONLY(12c+) 또는ROWNUM - 함수:
ISNULL()→NVL(),LEN()→LENGTH(),GETDATE()→SYSDATE/SYSTIMESTAMP - 페이징: 정렬 안정성이 없으면 결과가 달라질 수 있음(ORDER BY 필수)
- Collation/NLS: 대소문자/정렬/비교 규칙이 바뀌면 결과가 달라질 수 있음
1.3 객체/운영 기능 체크리스트(“데이터만”으로 끝나지 않는다)
- 제약조건/인덱스 적용 시점(초기 비활성화 → 적재 후 활성화 전략)
- 뷰/MV, 트리거, 프로시저/함수(T‑SQL → PL/SQL 전환 범위)
- 잡/스케줄러(SQL Agent → Oracle Scheduler 등)
- 권한/역할/스키마 구조(Owner, Synonym, 권한 재설계)
- 암호화/마스킹/감사로그(규제/보안 요구 반영)
2) 다운타임 최소화/중단 전환 전략: 선택 기준과 실행 개요
2.1 전략 선택 기준(실무 관점)
아래 질문에 답하면 대부분 방향이 정해집니다.
1) 허용 다운타임이 0에 가깝다 → A(무중단 CDC)
2) 다운타임 4~6시간 확보 가능, UpdatedAt/CDC 기준이 있다 → B(저다운타임 Bulk+Delta)
3) 다운타임이 길어도 괜찮고 “단순·확실”이 우선이다 → C(중단 전환 Big Bang)
추가로, 다음 항목이 강하게 영향을 줍니다.
- 데이터 규모(TB급 이상이면 “LOB/대형테이블 분리” 고려)
- 변경량(피크 시간대 TPS/변경률)
- 운영 리스크(동기화 실패 시 복구 난이도)
- 조직 역량(툴/모니터링/리허설 경험)
3) 공통 Runbook: 마이그레이션 표준 프로세스(모든 전략에 적용)
전환 방식이 달라도, 큰 흐름은 같습니다.
1) Schema 변환/생성(DDL)
2) Initial Load(대량 적재)
3) (전략별) Sync(CDC 또는 Delta 또는 없음)
4) 정합성 검증(Verification)
5) 컷오버(Cut-over)
6) 안정화/모니터링
7) 롤백 대비(소스 Read-only 유지/스냅샷 보관)

4) 전략별 상세 실행 Runbook
4.1 전략 A: 무중단(CDC) Runbook

Step A-1. Initial Load
- SQL Server에서 기준 시점 데이터 Bulk 적재
- 적재 성능을 위해 제약/인덱스 적용 시점은 정책에 따라 조정(대개 적재 후 활성화)
Step A-2. CDC 시작
- 로그 기반 변경분(Insert/Update/Delete)을 Oracle에 실시간 반영
- 반드시 운영 항목을 같이 준비
- Lag 지표(분/초 단위)
- 에러 큐(재처리)
- 충돌 정책(업서트/PK 충돌/순서 역전)
Step A-3. 컷오버
- Lag=0 확인
- 애플리케이션 연결을 Oracle로 전환(커넥션 스트링/서비스 디스커버리)
- 일정 시간 안정화 후, 소스는 Read-only 유지(롤백 대비)
주의사항
- 컷오버 직전 DDL 변경은 거의 금지(DDL 동기화가 위험)
- PK/UK 품질이 CDC 안정성에 직접 영향
4.2 전략 B: 저다운타임(Bulk + Delta) Runbook

Step B-1. D-7 Bulk
- 전체 데이터 1차 이관(대량 적재)
- 이 시점부터는 “변경분 추출 기준”을 확정하고 변경 추적 준비
Step B-2. D-Day Delta
- 1차 이관 이후 변경된 데이터(Delta)만 추출하여 Oracle에 반영
- 핵심 조건:
UpdatedAt같은 변경 기준 컬럼이 존재해야 함- 해당 컬럼 인덱싱(대용량에서 Delta 추출이 병목이 되지 않도록)
Step B-3. 검증 + 컷오버
- 최소 검증 세트(5장)를 통과하면 전환
- 실패 시: Delta 재적용/재검증 또는 점검 윈도우 내 롤백 결정
4.3 전략 C: 중단 전환(Full Downtime / Big Bang) Runbook
중단 전환은 “서비스 중단 시간이 길어질 수 있음”이 단점이지만, 반대로 동기화 복잡도가 없어서 가장 단순하고 확실한 방식이 될 수 있습니다.

Step C-1. 사전 준비(중단시간 단축이 핵심)
- 사전 리허설(Mock Migration)로 “이관 소요시간”과 “검증 소요시간”을 측정
- 대형 테이블/LOB는 가능하면 사전 적재(Pre-load)로 분리(정책 허용 시)
- 스키마/인덱스/제약 적용 순서 최적화(적재 후 Enable 전략)
Step C-2. D-Day 중단(Freeze)
- 애플리케이션 점검 모드 전환(쓰기/주문/결제 등 업무 중단)
- 배치/잡 중지
- SQL Server에서 최종 스냅샷(덤프/백업) 확보
- 이 스냅샷이 곧 “롤백의 생명줄”입니다.
Step C-3. 이관(Export/Import)
- BCP 등으로 파일 Export
- SQL*Loader 등으로 Oracle에 고속 적재
- 적재 완료 후 제약/인덱스 활성화(정책에 따라 순서 조정)
Step C-4. 정합성 검증(최소 세트 + 핵심 테이블 심화)
- 5장 검증을 통과하면 오픈 가능 상태
Step C-5. 오픈
- 애플리케이션 연결을 Oracle로 전환
- 오류율/응답시간/배치 수행 등 안정화 모니터링
중단 전환에서 자주 터지는 포인트
- “검증 시간이 생각보다 길어서” 다운타임이 늘어나는 문제
- “인덱스/제약 활성화 시간이 과다”하여 오픈이 늦는 문제
- LOB 이관 병목(전략적으로 분리하지 않으면 시간이 폭발)
5) 데이터 정합성 검증(Verification) — 최소 3단계 + 운영형 확증
“에러가 없었다”는 검증이 아닙니다.
대용량 이관은 조용한 오류(silent error) 가 더 치명적입니다.

5.1 1단계: Row Count(전수) 검증
- 모든 테이블에 대해 건수 일치 확인
- 대용량이면:
- 파티션별/날짜 범위별 COUNT로 분해
- 핵심 테이블은 반드시 전수 COUNT 수행
SQL Server(테이블별 Row Count 빠른 방식)
SELECT
s.name AS schema_name,
t.name AS table_name,
SUM(p.row_count) AS row_count
FROM sys.tables t
JOIN sys.schemas s
ON t.schema_id = s.schema_id
JOIN sys.dm_db_partition_stats p
ON t.object_id = p.object_id
AND p.index_id IN (0,1)
GROUP BY s.name, t.name
ORDER BY row_count DESC;
Oracle(전수 Count)
SELECT COUNT(*) AS row_count
FROM TARGET_SCHEMA.TARGET_TABLE;
5.2 2단계: 집계/해시 검증(중요 테이블)
건수는 맞아도 내용이 깨질 수 있습니다(인코딩, 정밀도, 스케일, 기본값/트리거 등).
집계(금액/수량 등)
SELECT
COUNT(*) AS cnt,
SUM(AMOUNT) AS sum_amount,
MIN(AMOUNT) AS min_amount,
MAX(AMOUNT) AS max_amount
FROM ORDER_TABLE
WHERE ORDER_DATE >= DATE '2024-01-01';
샘플링(키 범위)
SELECT ORDER_ID, CUSTOMER_NAME, ORDER_DATE, AMOUNT
FROM ORDER_TABLE
WHERE ORDER_ID BETWEEN 1000 AND 1010
ORDER BY ORDER_ID;
구간 해시(이상 탐지용)
SELECT
STANDARD_HASH(
LISTAGG(
ORDER_ID || '|' ||
NVL(CUSTOMER_NAME,'<NULL>') || '|' ||
TO_CHAR(ORDER_DATE,'YYYYMMDDHH24MISS'),
'#'
) WITHIN GROUP (ORDER BY ORDER_ID),
'SHA256'
) AS chunk_hash
FROM ORDER_TABLE
WHERE ORDER_ID BETWEEN 100000 AND 100999;
대형 구간에서는 LISTAGG 한계를 피하기 위해 범위를 더 잘게 나누거나, ETL 단계에서 row-hash를 만들어 비교하는 방식도 실무적으로 많이 씁니다.
5.3 3단계: 특수문자/인코딩/NULL(빈 문자열) 검증
깨진 문자 탐지(예: ‘?’)
SELECT *
FROM USER_INFO
WHERE NAME LIKE '%?%';
제어문자/비정상 문자 탐지
SELECT *
FROM USER_INFO
WHERE REGEXP_LIKE(NAME, '[[:cntrl:]]');
NULL 비율 점검(도메인상 허용 여부 확인)
SELECT
COUNT(*) AS total_cnt,
SUM(CASE WHEN NAME IS NULL THEN 1 ELSE 0 END) AS null_cnt
FROM USER_INFO;
5.4 운영형 추가 검증(권장)
- FK 무결성(Enable 시 실패 여부)
- Sequence/Identity 정합성(
MAX(PK)vsNEXTVAL) - LOB 검증(길이/해시/샘플 다운로드)
- 성능 리그레션(핵심 API/리포트 쿼리 리플레이)
6) 전환 후 잠재 리스크(운영에서 “의외로” 문제되는 것들)
6.1 동시성/락 모델 차이
Oracle은 MVCC 기반이라 Reader/Writer 경합 패턴이 SQL Server와 다르게 나타납니다.
이관 후 애플리케이션에서:
- 락/데드락 패턴 변화
- 트랜잭션 설계(낙관/비관) 재검토 필요
같은 이슈가 발생할 수 있습니다.
6.2 대소문자/식별자 정책
Oracle 식별자 처리(대문자 저장, quoted identifier 사용 시 case-sensitive 등)와
ORM/쿼리 표기 정책을 통일하지 않으면 “운영에서 갑자기 쿼리 실패”가 나올 수 있습니다.
6.3 날짜 정밀도/타임존
정밀도(ms) 손실, UTC/로컬 혼재는 로그/감사/정산에서 치명적입니다.
요구 정밀도와 표준 타임존 정책을 먼저 고정하세요.
마치며
마이그레이션은 “DB 교체”가 아니라 운영 체계 전환입니다.
특히 중단 전환(Full Downtime) 은 단순해 보이지만, 실제로는 “검증/인덱스/LOB”에서 다운타임이 길어질 수 있으니, 사전 리허설로 시간을 계량화하고 Runbook을 고정하는 것이 핵심입니다.
이 글의 체크리스트와 검증 쿼리를 프로젝트 상황(데이터 규모, 변경량, 허용 다운타임, 규제)에 맞게 커스터마이징하여 반복 리허설(Mock Migration) 에 적용해 보시길 권장합니다.
