Skip to content

Latest commit

 

History

History
52 lines (39 loc) · 6.16 KB

File metadata and controls

52 lines (39 loc) · 6.16 KB

🐛 트러블슈팅 및 디버깅 여정 (Troubleshooting & Debugging)

대용량 E-Commerce 데이터를 파이썬으로 자동 생성하여 오라클 데이터베이스에 초고속으로 적재(SQL*Loader)하는 시스템을 구축하면서 마주쳤던 6가지 핵심 오류와 그 해결 과정을 상세히 기록합니다.


1. Out of Memory (OOM) 문제 방지: 파이썬 제너레이터 도입

  • 상황: 수십만 건의 데이터를 메모리에 배열(List) 형태로 들고 있다가 한 번에 SQL 구문으로 출력(03_seed_data.sql)하려다 보니 파이썬 프로세스에서 메모리 초과(OOM)가 발생할 위험이 컸습니다.
  • 해결: 파이썬의 yield 키워드를 사용한 제너레이터(Generator) 패턴csv.DictWriter를 결합하여 데이터를 한 줄씩(Streaming) 즉시 파일로 써내려가는 방식으로 아키텍처를 전면 개편했습니다. 그 결과 메모리 사용량을 O(1) 수준으로 극적으로 낮출 수 있었습니다.

2. 성능 한계: INSERT 구문에서 SQL*Loader로의 전환

  • 상황: 생성된 25만 건 이상의 .sql 스크립트를 SQL*Plus로 한 줄씩 INSERT 하려니 수 시간이 소요될 정도로 적재 속도가 너무 느렸습니다.
  • 해결: 오라클에서 대용량 데이터를 적재할 때 사용하는 SQL*Loader (sqlldr) 툴을 활용하기로 결정했습니다. 파이썬 스크립트가 순수 데이터인 .csv 파일과 제어 파일인 .ctl을 자동 생성하도록 OracleExporter를 개편하였고, 적재 속도를 단 몇 초 단위로 단축했습니다.

3. ORA-01918 (User Does Not Exist): 멀티테넌트(PDB) 접속 이슈

  • 에러 메시지: ORA-01918: user 'ECOMMERCE' does not exist
  • 상황: 오라클 23ai Free 버전을 도커 컨테이너로 띄우고 sqlplus로 접속하여 설치 스크립트(install.sql, uninstall.sql)를 실행했으나, 스키마 유저를 찾을 수 없거나 생성할 수 없는 문제가 발생했습니다.
  • 원인: 최신 오라클 데이터베이스는 멀티테넌트(CDB/PDB) 아키텍처를 따릅니다. 기본 접속 시 CDB$ROOT 컨테이너에 접속되는데, 이 루트 영역에서는 일반 서비스 유저(ECOMMERCE)를 관리할 수 없습니다.
  • 해결: 모든 DDL 스크립트(install.sql, uninstall.sql) 최상단에 ALTER SESSION SET CONTAINER = FREEPDB1; 구문을 삽입하여, 플러거블 데이터베이스(PDB)로 세션이 이동한 뒤 유저 관리와 테이블 생성을 수행하도록 수정했습니다.

4. ORA-SQL*Loader-522 (File Permission Denied): 도커 소유권 문제

  • 에러 메시지: SQL*Loader-522: lfiopn failed for file (data/categories.log)
  • 상황: 파이썬으로 로컬(Mac/Windows)에서 생성한 결과물(output/) 폴더를 docker cp 명령어를 이용해 오라클 도커 컨테이너 내부로 복사한 뒤, load_data.sh를 실행했으나 위 오류가 발생하며 적재가 실패했습니다.
  • 원인: docker cp를 통해 호스트에서 도커 내부로 복사된 파일들은 소유자가 root로 지정됩니다. 하지만 SQL*Loader는 oracle 계정 권한으로 실행되므로, root 소유의 폴더에 로그 파일(.log)이나 배드 파일(.bad)을 작성할 권한이 없어서 발생한 에러입니다.
  • 해결: docker cp 후 반드시 도커 내부의 파일 소유권을 oracle:oinstall로 변경해주는 절차를 필수화했습니다.
    docker exec -u 0 oracle26ai chown -R oracle:oinstall /home/oracle/all_schema

5. ORA-01722 (Invalid Number): CRLF 줄바꿈 오류

  • 에러 메시지: ORA-01722: unable to convert string value containing 'D' to a number
  • 상황: 윈도우 환경이나 특정 파이썬 설정에서 CSV 파일을 생성하면, 숫자가 들어가야 할 마지막 컬럼에서 지속적으로 문자열 변환 에러가 발생했습니다.
  • 원인: 파이썬 내장 csv 모듈은 기본적으로 윈도우 스타일의 줄바꿈인 \r\n(캐리지 리턴 + 라인 피드)을 사용합니다. 리눅스 환경의 도커 안에서 SQL*Loader가 이를 파싱할 때, 보이지 않는 \r 문자가 마지막 숫자 컬럼에 포함되어 "숫자가 아닌 문자가 섞였다"고 판단한 것입니다.
  • 해결: 파이썬 OracleExportercsv.DictWriter 인스턴스 생성 시 lineterminator='\n' 옵션을 명시적으로 지정하여, 모든 운영체제에서 리눅스 호환 LF 포맷으로 파일이 생성되도록 원천 봉쇄했습니다.

6. ORA-01841 (Date Parsing) 및 스키마 컬럼 순서 미스매치

  • 상황: 마지막 14개 분석/참여 테이블 데이터를 생성한 후 CARTS, REVIEWS, POINT_TRANSACTIONS 등의 테이블에서 0건이 적재되거나 이상한 에러가 발생했습니다.
  • 원인 1 (컬럼 순서 불일치): 파이썬 Faker 제너레이터가 yield 하는 딕셔너리(Dictionary)의 키 순서와 오라클 테이블의 실제 컬럼 정의(schema_definition.py) 순서가 달랐습니다. csv.DictWriter는 딕셔너리의 키 순서대로 CSV를 생성하지만, SQL*Loader(.ctl)는 오라클 테이블 컬럼 순서대로 데이터를 읽어 들이려다 보니, 문자열("ACTIVE")을 날짜 컬럼(CREATED_AT)에 넣으려다 ORA-01841 에러가 났습니다.
  • 원인 2 (데이터 내 줄바꿈 포함): REVIEWSCOMPLAINTS 테이블에 Faker.text()로 본문을 넣었는데, 본문 안에 개행 문자(\n)가 포함되어 있었습니다. 기본 SQL*Loader 설정에서는 개행 문자를 새로운 레코드(행)의 시작으로 간주하기 때문에 큰따옴표로 감싸여 있어도 파싱이 깨졌습니다.
  • 해결:
    1. massive_generator.py의 모든 제너레이터 딕셔너리 반환 순서를 schema_definition.py의 컬럼 선언 순서와 단 1개의 오차도 없이 100% 동일하게 일치시켰습니다. (예: point_transactionstx_type 등 변수명도 정확히 일치시킴).
    2. Faker.text().replace('\n', ' ') 를 사용하여 텍스트 데이터 내부의 줄바꿈을 모두 공백으로 치환하여 SQL*Loader가 헷갈리지 않게 방어 로직을 추가했습니다.