운영과 비용
적재 오류 트러블슈팅 (COPY, Snowpipe, 파일 형식, 권한)
COPY INTO 와 Snowpipe 적재가 실패하거나 조용히 건너뛸 때 보는 순서와, 열 수 불일치, 날짜와 숫자 형식, 인코딩, 이미 적재된 파일, 스토리지 통합 권한, 이벤트 알림 누락, 반정형 데이터 크기 같은 사례를 증상, 원인, 해결 순서로 정리합니다.
트러블슈팅COPY INTOSnowpipe적재 오류파일 형식스토리지 통합VALIDATE2026-10 기준, 약 9분
먼저 볼 것
적재 문제는 크게 세 가지입니다. 파일을 못 읽음(권한, 경로), 파일을 읽었지만 행이 거부됨(형식), 파일이 아예 처리 대상이 아님(이미 적재됨, 알림 누락). 어느 쪽인지 먼저 가릅니다.
-- 최근 적재 기록 (COPY 와 Snowpipe 모두, 14일)
SELECT file_name, status, row_count, row_parsed, first_error_message,
first_error_line_number, first_error_column_name, last_load_time
FROM TABLE(INFORMATION_SCHEMA.COPY_HISTORY(
TABLE_NAME => 'RAW.EVENTS',
START_TIME => DATEADD(hour, -24, CURRENT_TIMESTAMP())))
ORDER BY last_load_time DESC;
-- 적재 전에 오류만 미리 보기
COPY INTO raw.events FROM @raw.s3_events
FILE_FORMAT = (FORMAT_NAME = 'raw.csv_fmt')
VALIDATION_MODE = RETURN_ERRORS;
-- 방금 실행한 COPY 의 거부 행
SELECT * FROM TABLE(VALIDATE(raw.events, JOB_ID => '_last'));기본 문법과 옵션은 COPY INTO, 자동 적재는 Snowpipe 문서에 있습니다.
사례 1. 열 수가 맞지 않습니다
- 증상: "Number of columns in file (12) does not match that of the corresponding table (11)" 오류가 납니다.
- 원인: 원본 시스템이 열을 추가했거나, 값 안의 구분자(쉼표)가 따옴표로 감싸지지 않았습니다.
- 해결: 따옴표 문제라면 파일 형식에
FIELD_OPTIONALLY_ENCLOSED_BY = '"'를 넣습니다. 열이 늘어난 것이라면 테이블에 열을 추가하거나ERROR_ON_COLUMN_COUNT_MISMATCH = FALSE를 검토합니다. 열 이름으로 맞추려면 헤더를 읽는PARSE_HEADER = TRUE와MATCH_BY_COLUMN_NAME을 씁니다.
사례 2. 날짜, 숫자 형식 오류
- 증상: "Date '2026/10/01' is not recognized" 또는 "Numeric value '1,234' is not recognized" 가 납니다.
- 원인: 파일의 날짜, 숫자 표기가 Snowflake 기본 형식과 다릅니다.
- 해결: 파일 형식에
DATE_FORMAT = 'YYYY/MM/DD',TIMESTAMP_FORMAT을 지정합니다. 천 단위 쉼표 같은 표기는 COPY 의 변환 쿼리에서TO_NUMBER($3, '9,999,999')처럼 처리하거나, 문자열로 받은 뒤 변환합니다.
사례 3. 한글이 깨지거나 인코딩 오류가 납니다
- 증상: "Invalid UTF8 detected in string" 오류가 나거나 적재된 한글이 깨집니다.
- 원인: 파일이 UTF-8 이 아니라 CP949(EUC-KR) 입니다. 국내 레거시 시스템 내보내기에서 흔합니다.
- 해결: CSV 파일 형식에 원본 인코딩을 지정합니다. EUC-KR 은
ENCODING = 'EUCKR', 확장 완성형(CP949 계열)은ENCODING = 'WINDOWS949'입니다. 깨진 바이트를 대체 문자로 바꾸고 계속하려면REPLACE_INVALID_CHARACTERS = TRUE를 씁니다.
사례 4. COPY 가 성공했는데 0 행입니다
- 증상: COPY 결과가 "Copy executed with 0 files processed" 이고 데이터가 들어오지 않습니다.
- 원인: 같은 파일을 64일 안에 이미 적재해 적재 메타데이터가 건너뛰었습니다. 또는
PATTERN이 파일 이름과 맞지 않습니다. - 해결:
COPY_HISTORY에서 그 파일이 이미LOADED인지 봅니다. 정말 다시 넣어야 한다면FORCE = TRUE를 쓰되 중복을 주의합니다. 패턴은LIST @stage PATTERN = '...'로 먼저 확인합니다.
주의
FORCE = TRUE와PURGE = FALSE조합을 정기 작업에 넣으면 같은 파일이 매번 다시 들어갑니다. 재적재는 한 번만 수동으로 실행합니다.
사례 5. 스토리지 통합 권한 오류
- 증상: "Failed to access remote file: access denied" 또는 "Insufficient privileges to operate on integration" 이 납니다.
- 원인: 클라우드 쪽 IAM 역할(또는 Azure 동의, GCS 서비스 계정 권한)이 버킷 경로를 허용하지 않거나, 신뢰 정책의 외부 ID 가 바뀌었거나, Snowflake 역할에 통합
USAGE가 없습니다. - 해결:
DESC INTEGRATION s3_int; -- STORAGE_AWS_IAM_USER_ARN, STORAGE_AWS_EXTERNAL_ID 확인
GRANT USAGE ON INTEGRATION s3_int TO ROLE loader;AWS IAM 역할의 신뢰 정책에 위 사용자 ARN 과 외부 ID 가 그대로 들어 있는지, 권한 정책에 s3:GetObject, s3:ListBucket 이 해당 경로로 있는지 확인합니다. 통합을 CREATE OR REPLACE 로 다시 만들면 외부 ID 가 바뀌니 신뢰 정책도 갱신해야 합니다.
사례 6. Snowpipe 가 새 파일을 못 봅니다
- 증상: 버킷에 파일이 쌓이는데
AUTO_INGEST파이프가 적재하지 않습니다. - 원인: 버킷 이벤트 알림이 파이프의 알림 채널(SQS 등)로 오지 않거나, 이벤트 필터 경로가 파이프 경로와 다르거나, 파이프가 일시 중지 상태입니다.
- 해결:
SELECT SYSTEM$PIPE_STATUS('raw.events_pipe'); -- executionState, pendingFileCount, lastReceivedMessageTimestamp
SHOW PIPES LIKE 'EVENTS_PIPE'; -- notification_channel
ALTER PIPE raw.events_pipe REFRESH; -- 최근 7일 안의 누락 파일 다시 큐에 넣기lastReceivedMessageTimestamp 가 오래되었다면 알림 설정 문제입니다. 같은 버킷 접두사에 이벤트 알림을 둘 이상 걸 수 없는 제약 때문에 기존 알림과 충돌하는 경우도 흔합니다.
사례 7. 반정형 데이터가 너무 큽니다
- 증상: JSON 적재에서 "Max LOB size exceeded" 류의 오류가 납니다.
- 원인: 파일 전체가 하나의 큰 JSON 배열이라 한 행으로 읽히거나, 한 문서가 VARIANT 크기 한도를 넘었습니다.
- 해결: 파일 형식에
STRIP_OUTER_ARRAY = TRUE를 지정해 배열 요소를 행으로 나눕니다. 그래도 크면 원본에서 문서를 쪼개거나 큰 필드는 따로 저장합니다. 한도는 공식 문서의 데이터 형식 표를 확인합니다. 반정형 데이터 문서를 참고합니다.
사례 8. Parquet 적재 후 값이 NULL 입니다
- 증상: Parquet 파일을 적재했는데 일부 열이 모두 NULL 입니다.
- 원인:
MATCH_BY_COLUMN_NAME을 쓸 때 열 이름 대소문자가 맞지 않거나, 변환 쿼리에서$1:column경로 이름을 틀렸습니다. - 해결:
MATCH_BY_COLUMN_NAME = CASE_INSENSITIVE를 쓰고,INFER_SCHEMA로 파일의 실제 열 이름과 형식을 확인합니다.
SELECT * FROM TABLE(INFER_SCHEMA(
LOCATION => '@raw.s3_events/2026/10/',
FILE_FORMAT => 'raw.parquet_fmt'));
오류 처리 옵션 고르기
| ON_ERROR | 동작 | 맞는 곳 |
|---|---|---|
| ABORT_STATEMENT (COPY 기본) | 하나라도 오류면 전체 중단 | 정확성이 중요한 배치 |
| CONTINUE | 오류 행만 건너뜀 | 일부 손실을 허용하는 로그 |
| SKIP_FILE (Snowpipe 기본) | 오류가 있는 파일 통째로 건너뜀 | 파일 단위 재처리 |
| SKIP_FILE_ | 오류가 n 개 또는 n% 넘으면 파일 건너뜀 | 약간의 오류 허용 |
건너뛴 행과 파일은 반드시 따로 기록하고 알림을 겁니다. 조용히 사라진 데이터가 가장 찾기 어렵습니다.