실무 기준으로 반드시 다음에 결정해야 할 것들(우선순위 순)
1️⃣ 실행 모델 결정 (가장 먼저)
이 앱은 “동기 요청 앱”인가, “Job 기반 앱”인가?
정답
👉 B. Job 기반 비동기 모델
동기 요청 앱은 구조적으로 성립하지 않는다.
이유
- Ora2Pg는 수 초 ~ 수 시간
- HTTP 타임아웃과 구조적으로 충돌 (HTTP 요청/응답 모델: 수 초 ~ 수십 초. 브라우저/프록시 타임아웃 존재)
- 로그/중단/재시작/다운로드 관리 필요 (중단 / 실패 / 재시작 가능성 있음)
- (도중에 끊기면 작업불가, 로그확인불가, 중간취소불가, 대용량에서 서버 다운)
📌 이걸 먼저 정하지 않으면
API, DB, UI 전부 다시 설계해야 한다.
2️⃣ Job 기반 앱에서 “스레드 vs 프로세스”는 어떻게 결정하나?
2-1️⃣ 결론 먼저
👉 이 앱에서는 “프로세스 기반 Job”이 정답이다.
스레드는 의도적으로 탈락시켜야 한다.
2-2️⃣ 스레드 Job을 쓰면 왜 안 되나?
❌ 스레드 방식의 본질적 문제
① 메모리 격리 ❌
- 스레드는 같은 프로세스 메모리 공유
- Oracle 접속 정보가 완전히 분리되지 않음
- 실수 한 번이면 전역 노출
② 장애 전파 ❌
- Ora2Pg 실행 중 세그폴트
- Oracle Client 라이브러리 크래시
- → 프로세스 전체 종료
③ 자원 제어 불가 ❌
- CPU / 메모리 제한 어려움
- 한 Job 폭주 → 전체 서버 영향
④ 보안 측면 ❌
- “Job 단위 수명”을 OS가 보장하지 않음
- 개발자 실수에 취약
👉 스레드는 웹 요청 처리에는 좋지만,
외부 도구 실행에는 부적합이다.
2-3️⃣ 프로세스 Job의 장점 (이 앱에 딱 맞음)
✅ 프로세스 기반 Job이 주는 것
① 완전한 격리
- 메모리 분리
- 환경변수 분리
- 작업 디렉터리 분리
② 보안 자동 강화
- 프로세스 종료 = 메모리 해제
- 접속 정보 자연 소멸
③ 장애 국소화
- Job 하나 죽어도
- Backend 서버는 살아 있음
④ 자원 제어 가능
- Docker면 CPU / Memory 제한 가능
- 로컬 subprocess도 제한 설정 가능
3️⃣ Job 기반 + 프로세스 기반 구조를 한 줄로 정의하면
이 앱은
“요청 → Job 생성 → 별도 프로세스 실행 → 상태 조회 → 결과 다운로드”
구조의 시스템 도구다.
웹앱처럼 보여도, 본질은 배치/툴이다.
4️⃣ 최종 구조를 정확히 그리면 이렇다
[React UI]
|
| POST /jobs
v
[Backend (Orchestrator)]
|
| Job 생성 (DB or 메모리)
|
| fork / subprocess / docker run
v
[Job Process]
|
| Oracle 조회
| Ora2Pg 실행
|
v
[Artifacts]
(CSV / SQL / ZIP)
- Backend는 절대 무거운 일을 안 한다
- Job 프로세스가 모든 무거운 일을 한다
2️⃣ 상태 모델 정의 (RUNNING 말고 뭐가 있나?)
“마이그레이션 하나”의 **생애주기(state machine)**를 정해야 한다.
최소 상태 모델 (추천)
CREATED
→ RUNNING
→ DONE
→ FAILED
→ CANCELED
선택 옵션:
- VALIDATING (접속 정보 검증)
- PACKAGING (ZIP 생성 중)
📌 상태 정의가 안 되면:
- 프론트 UX 혼란
- 장애 시 복구 불가
- 로그 해석 불가
3️⃣ 보안 모델 (지금 안 정하면 나중에 무조건 사고 남)
Oracle 접속 정보는 어떻게 다룰 것인가?
반드시 결정해야 할 질문들:
- DB 비밀번호를 서버에 저장하는가?
- Job 종료 후 삭제하는가?
- 로그에 접속 정보가 남지 않는가?
- 멀티 유저를 허용하는가?
실무 권장 기준
- ✔ Job 단위 메모리/임시파일 사용
- ✔ 실행 종료 후 즉시 삭제
- ❌ DB 비밀번호 영구 저장 금지
📌 이건 “기능”이 아니라 제품 신뢰성 문제다.
4️⃣ 실행 환경 추상화 (Docker vs Local)
이미 얘기했지만 지금 코드 설계에 바로 반영해야 한다.
반드시 결정할 것
Ora2Pg 실행은
- Docker로 할 수도 있고
- 로컬 바이너리로 할 수도 있다
그래서:
실행 방식은 코드에서 몰라야 한다
즉시 필요한 결정
- Runner 인터페이스
- DockerRunner / LocalRunner 분리
- 설정파일 생성 로직 공통화
📌 이걸 지금 안 하면
“나중에 실행 파일로” 절대 못 간다.
5️⃣ 결과물 스펙 (다운로드 버튼 누르면 뭐가 나오나?)
파일 다운로드 버튼의 정확한 계약(Contract)
정해야 할 것:
- 단일 CSV인가?
- 객체별 파일인가?
- ZIP으로 묶는가?
- 파일명 규칙은?
예시 (권장)
job-20240101-001.zip
├─ schema.sql
├─ data/
│ ├─ EMP.csv
│ └─ DEPT.csv
└─ summary.txt
나중에 바꾸면 프론트/백엔드 다 깨진다.
6️⃣ “어디까지 자동화하고, 어디부터 수동인가?”
아주 중요한 판단이다.
정해야 할 질문:
- 트리거/프로시저 자동 변환 결과를
- 바로 포함할 것인가?
- 참고용으로만 줄 것인가?
- 실패한 객체는 전체 실패인가?
- 일부 성공 허용인가?
실무 정답 패턴
- TABLE / DATA → 자동
- VIEW → 대부분 자동
- TRIGGER / PROCEDURE → 참고용 출력
📌 이 기준이 없으면
사용자가 결과를 “믿어도 되는지” 알 수 없다.
7️⃣ 최소 제품 범위(MVP) 컷라인
마지막으로 이걸 정해야 한다.
1차 버전에서 할 것
- Oracle 객체 조회
- TABLE + DATA CSV 생성
- Job 상태 조회
- 파일 다운로드
의도적으로 안 할 것
- 실시간 진행률 %
- PostgreSQL 직접 적재
- 자동 롤백
- 프로시저 실행 검증
📌 이걸 정하지 않으면
프로젝트는 끝없이 커진다.
지금 단계 요약
지금까지:
- ✔ 아키텍처 합의
- ✔ 유즈케이스 합의
다음 단계는 “설계 결정 고정”이다.
우선순위 TOP 5
- Job 기반 비동기 모델
- 상태(State) 정의
- 보안 정책
- 실행 환경 추상화
- 결과물 포맷 계약
다음으로 가장 자연스럽고 생산적인 흐름은
👉 “Job 기반 API 스펙을 먼저 확정”
또는
👉 “백엔드 내부 도메인 모델(Job / Runner / Artifact) 설계”
여기부터는 진짜로 코드로 내려갈 준비 단계다.
'실험실 > db이행' 카테고리의 다른 글
| 이슈 업무범위 ddl까지 vs data 이행까지 (0) | 2026.01.15 |
|---|---|
| 이슈 (1) | 2026.01.15 |
| 핵심 유즈케이스 (0) | 2026.01.14 |
| 언어선택의 기준 (1) | 2026.01.14 |
| ORACLE -> PostgreSQL (0) | 2026.01.12 |
댓글