2026년 10월 07일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-29284 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-29284 file read error 는?
ORA-29284는 Oracle이 외부 파일을 읽는 과정에서 발생하는 파일 읽기 오류입니다. 주로 UTL_FILE 패키지, 외부 테이블(External Table), BFILE, 또는 Data Pump 작업 중에 특정 파일에 접근하거나 내용을 읽을 때 시스템이 파일을 정상적으로 읽지 못할 경우 발생합니다. 파일이 존재하더라도 파일 손상, 권한 문제, 잘못된 파일 핸들 등 다양한 원인으로 인해 이 에러가 발생할 수 있습니다.
주요 발생 원인
1. 파일 권한(Permission) 문제
Oracle 데이터베이스 프로세스(oracle 유저)가 해당 파일에 대한 읽기 권한을 가지고 있지 않을 경우 ORA-29284가 발생합니다. 운영체제 수준에서 파일 소유자나 권한이 Oracle 프로세스 계정과 맞지 않으면, Oracle은 파일을 열 수 있더라도 읽기 단계에서 실패하게 됩니다. 특히 FTP나 SFTP로 파일을 전송한 직후 권한이 600(소유자만 읽기/쓰기)으로 설정된 경우가 빈번한 사례입니다.
2. 파일 손상(File Corruption) 또는 불완전한 파일
파일이 완전히 전송되지 않았거나, 도중에 쓰기 작업이 중단되어 파일이 손상된 경우 읽기 오류가 발생합니다. 특히 네트워크를 통해 전송된 대용량 파일이나, 다른 프로세스가 쓰기 중인 파일을 Oracle이 동시에 읽으려 할 때 이 문제가 나타납니다. 파일의 내용이 예상한 형식과 다르거나 중간에 깨진 바이트가 있으면 UTL_FILE.GET_LINE 또는 외부 테이블 접근 시 에러가 발생합니다.
3. 잘못된 디렉토리 오브젝트 또는 파일 핸들 사용
Oracle DIRECTORY 오브젝트가 실제 OS 디렉토리 경로와 일치하지 않거나, 이미 닫힌 파일 핸들을 다시 사용하려 할 때 ORA-29284가 발생합니다. UTL_FILE.FOPEN 이후 파일 핸들을 제대로 관리하지 않아 FCLOSE 이후에도 읽기를 시도하는 코드 로직 오류가 대표적인 예입니다. DIRECTORY 오브젝트 생성 시 경로 뒤에 슬래시(/)를 잘못 붙이거나 오타가 있으면 내부적으로 파일 경로가 달라져 읽기 실패로 이어집니다.
해결 방법
원인 1: 파일 권한 문제 해결
OS 수준에서 oracle 유저가 파일을 읽을 수 있도록 권한을 변경합니다.
# OS 명령어로 파일 권한 확인 및 수정
ls -la /data/oracle/input/data_file.txt
chmod 644 /data/oracle/input/data_file.txt
chown oracle:oinstall /data/oracle/input/data_file.txt
Oracle DIRECTORY 오브젝트의 권한을 확인하고 필요한 사용자에게 READ 권한을 부여합니다.
-- DIRECTORY 오브젝트 확인
SELECT directory_name, directory_path
FROM dba_directories
WHERE directory_name = 'DATA_DIR';
-- 사용자에게 READ 권한 부여
GRANT READ ON DIRECTORY DATA_DIR TO hr_user;
-- 권한 확인
SELECT grantee, privilege, directory_name
FROM dba_tab_privs
WHERE table_name = 'DATA_DIR';
원인 2: 파일 손상 또는 불완전한 파일 해결
파일이 완전히 전송되었는지 확인하고, 파일 무결성을 검증하는 절차를 추가합니다.
-- UTL_FILE을 이용한 파일 존재 및 읽기 테스트
DECLARE
v_file UTL_FILE.FILE_TYPE;
v_line VARCHAR2(4000);
v_count NUMBER := 0;
BEGIN
-- 파일 열기 (읽기 모드, 최대 라인 길이 4000)
v_file := UTL_FILE.FOPEN('DATA_DIR', 'data_file.txt', 'R', 4000);
-- 파일 내용 읽기 루프
BEGIN
LOOP
UTL_FILE.GET_LINE(v_file, v_line);
v_count := v_count + 1;
-- 첫 5줄만 출력하여 파일 상태 확인
IF v_count <= 5 THEN
DBMS_OUTPUT.PUT_LINE('Line ' || v_count || ': ' || v_line);
END IF;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('총 읽은 라인 수: ' || v_count);
END;
-- 파일 정상 종료
UTL_FILE.FCLOSE(v_file);
EXCEPTION
WHEN UTL_FILE.READ_ERROR THEN
-- ORA-29284에 해당하는 예외 처리
DBMS_OUTPUT.PUT_LINE('파일 읽기 오류 발생: 파일이 손상되었거나 불완전합니다.');
IF UTL_FILE.IS_OPEN(v_file) THEN
UTL_FILE.FCLOSE(v_file);
END IF;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('예기치 않은 오류: ' || SQLERRM);
IF UTL_FILE.IS_OPEN(v_file) THEN
UTL_FILE.FCLOSE(v_file);
END IF;
END;
/
원인 3: 디렉토리 오브젝트 및 파일 핸들 문제 해결
DIRECTORY 오브젝트를 올바르게 생성하고, 파일 핸들을 안전하게 관리합니다.
-- 기존 DIRECTORY 오브젝트 삭제 후 재생성 (경로 끝에 슬래시 없이)
DROP DIRECTORY DATA_DIR;
CREATE OR REPLACE DIRECTORY DATA_DIR AS '/data/oracle/input';
-- DIRECTORY 오브젝트 정보 확인
SELECT directory_name, directory_path
FROM dba_directories
WHERE directory_name = 'DATA_DIR';
-- 안전한 파일 읽기 프로시저 예제 (핸들 관리 포함)
CREATE OR REPLACE PROCEDURE safe_file_reader (
p_dir_name IN VARCHAR2,
p_file_name IN VARCHAR2
) AS
v_file UTL_FILE.FILE_TYPE;
v_line VARCHAR2(32767);
BEGIN
-- 파일이 이미 열려있는지 확인 후 열기
v_file := UTL_FILE.FOPEN(p_dir_name, p_file_name, 'R', 32767);
LOOP
BEGIN
UTL_FILE.GET_LINE(v_file, v_line);
DBMS_OUTPUT.PUT_LINE(v_line);
EXCEPTION
WHEN NO_DATA_FOUND THEN
EXIT; -- 파일 끝에 도달하면 루프 종료
END;
END LOOP;
-- 반드시 파일 닫기
UTL_FILE.FCLOSE(v_file);
EXCEPTION
WHEN UTL_FILE.INVALID_PATH THEN
DBMS_OUTPUT.PUT_LINE('잘못된 디렉토리 경로입니다: ' || p_dir_name);
RAISE;
WHEN UTL_FILE.READ_ERROR THEN
DBMS_OUTPUT.PUT_LINE('파일 읽기 오류: ' || p_file_name);
IF UTL_FILE.IS_OPEN(v_file) THEN
UTL_FILE.FCLOSE(v_file);
END IF;
RAISE;
WHEN OTHERS THEN
IF UTL_FILE.IS_OPEN(v_file) THEN
UTL_FILE.FCLOSE(v_file);
END IF;
RAISE;
END safe_file_reader;
/
외부 테이블(External Table) 사용 시 디렉토리 설정 확인:
-- 외부 테이블 정의 확인
SELECT table_name, access_parameters
FROM dba_external_tables
WHERE table_name = 'EXT_EMPLOYEE_DATA';
-- 외부 테이블 재정의 예시 (올바른 DIRECTORY 지정)
CREATE TABLE ext_employee_data (
emp_id NUMBER,
emp_name VARCHAR2(100),
salary NUMBER
)
ORGANIZATION EXTERNAL (
TYPE ORACLE_LOADER
DEFAULT DIRECTORY DATA_DIR
ACCESS PARAMETERS (
RECORDS DELIMITED BY NEWLINE
FIELDS TERMINATED BY ','
MISSING FIELD VALUES ARE NULL
)
LOCATION ('employees.csv')
)
REJECT LIMIT UNLIMITED;
-- 외부 테이블 접근 테스트
SELECT COUNT(*) FROM ext_employee_data;
예방 방법
1. 파일 입수 후 자동 권한 설정 및 유효성 검증 스크립트 운영
파일을 서버에 적재한 후 Oracle 프로세스가 읽기 전에 OS 권한을 자동으로 조정하는 쉘 스크립트를 cron job으로 설정하여 관리합니다. 또한 파일 크기, 체크섬(md5sum), 마지막 수정 시간 등을 검증하는 사전 점검 절차를 Oracle 작업 전에 반드시 삽입하여 불완전한 파일로 인한 런타임 오류를 사전에 차단해야 합니다.
-- 파일 속성 확인을 위한 UTL_FILE.FGETATTR 활용
DECLARE
v_fexists BOOLEAN;
v_file_len NUMBER;
v_block_size BINARY_INTEGER;
BEGIN
UTL_FILE.FGETATTR(
location => 'DATA_DIR',
filename => 'employees.csv',
fexists => v_fexists,
file_length => v_file_len,
block_size => v_block_size
);
IF v_fexists THEN
DBMS_OUTPUT.PUT_LINE('파일 존재 여부: YES');
DBMS_OUTPUT.PUT_LINE('파일 크기: ' || v_file_len || ' bytes');
DBMS_OUTPUT.PUT_LINE('블록 크기: ' || v_block_size);
-- 최소 파일 크기 검증 (0바이트 파일 방지)
IF v_file_len = 0 THEN
RAISE_APPLICATION_ERROR(-20001, '파일이 비어 있습니다. 처리를 중단합니다.');
END IF;
ELSE
RAISE_APPLICATION_ERROR(-20002, '파일을 찾을 수 없습니다.');
END IF;
END;
/
2. 표준화된 예외 처리 템플릿 및 로깅 체계 구축
UTL_FILE을 사용하는 모든 PL/SQL 코드에 표준 예외 처리 블록(UTL_FILE.READ_ERROR, UTL_FILE.INVALID_PATH, UTL_FILE.INVALID_FILEHANDLE 등)을 반드시 포함하고, 오류 발생 시 로그 테이블에 기록하는 체계를 마련합니다. 파일 작업 완료 후에는 항상 UTL_FILE.FCLOSE_ALL을 호출하거나 IS_OPEN 체크를 통해 열린 핸들이 남지 않도록 관리하여 핸들 누수로 인한 후속 오류를 방지합니다.
관련 에러
- ORA-29280: 잘못된 디렉토리 경로 (DIRECTORY 오브젝트 경로가 OS와 불일치할 때)
- ORA-29281: 잘못된 파일 작업 (읽기 모드로 열린 파일에 쓰기 시도 등 모드 불일치)
- ORA-29282: 잘못된 파일 핸들 (이미 닫힌 핸들 또는 초기화되지 않은 핸들 사용)
- ORA-29283: 잘못된 파일 작업 (파일 존재하지 않거나 접근 불가)
- ORA-29285: 파일 쓰기 오류 (ORA-29284의 쓰기 버전에 해당)
- ORA-29286: 파일 닫기 오류 (파일 닫기 과정에서 발생하는 오류)
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.