2026년 09월 02일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-06556 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-06556 the pipe is empty, cannot fulfill the unpack_message request 는?
ORA-06556 에러는 Oracle의 DBMS_PIPE 패키지를 사용할 때, 파이프(pipe)에서 메시지를 읽으려 했으나 파이프가 비어 있는 상태일 때 발생하는 에러입니다. 주로 DBMS_PIPE.UNPACK_MESSAGE 프로시저를 호출했을 때, 사전에 DBMS_PIPE.RECEIVE_MESSAGE로 수신한 메시지가 없거나 파이프 버퍼가 비어 있는 경우에 발생합니다. 이 에러는 프로세스 간 통신(IPC, Inter-Process Communication)을 구현하는 PL/SQL 코드에서 자주 마주치게 되며, 파이프 통신의 순서나 타이밍 제어가 잘못된 경우 실무에서 빈번하게 나타납니다.
주요 발생 원인
1. RECEIVE_MESSAGE 없이 UNPACK_MESSAGE 직접 호출
DBMS_PIPE.UNPACK_MESSAGE는 반드시 DBMS_PIPE.RECEIVE_MESSAGE가 성공적으로 메시지를 수신한 이후에 호출해야 합니다. RECEIVE_MESSAGE의 반환값을 확인하지 않고 바로 UNPACK_MESSAGE를 호출하면, 파이프 버퍼에 아무것도 없는 상태에서 언패킹을 시도하게 됩니다. 이는 가장 흔한 실수로, 반환 코드 확인 로직이 누락된 레거시 코드에서 특히 자주 발생합니다.
2. RECEIVE_MESSAGE 타임아웃 후 반환값 미검증
DBMS_PIPE.RECEIVE_MESSAGE 함수는 성공 시 0, 타임아웃 시 1, 기타 오류 시 3을 반환합니다. 타임아웃(반환값 1)이 발생한 경우에도 반환값을 검사하지 않고 UNPACK_MESSAGE를 호출하면 ORA-06556이 발생합니다. 멀티 세션 환경에서 송신 측이 늦게 메시지를 보내거나, 네트워크 지연이 발생할 경우 이런 타임아웃 상황이 빈번하게 나타날 수 있습니다.
3. 파이프에 PACK_MESSAGE 없이 빈 메시지 전송 또는 파이프 초기화 문제
DBMS_PIPE.SEND_MESSAGE를 호출하기 전에 DBMS_PIPE.PACK_MESSAGE로 데이터를 패킹하지 않았거나, 파이프가 DBMS_PIPE.PURGE로 초기화된 이후 수신 측에서 이를 인지하지 못하고 메시지를 읽으려 할 때도 이 에러가 발생합니다. 또한 파이프 이름(pipe name)을 송·수신 양쪽에서 다르게 지정한 경우에도 수신 측 파이프가 비어 있어 동일한 에러가 발생할 수 있습니다.
해결 방법
원인 1 해결: RECEIVE_MESSAGE 반환값 검증 후 UNPACK_MESSAGE 호출
아래와 같이 RECEIVE_MESSAGE의 반환값을 반드시 확인한 후 UNPACK_MESSAGE를 호출하는 패턴을 사용해야 합니다.
DECLARE
v_pipe_name VARCHAR2(30) := 'MY_PIPE';
v_status INTEGER;
v_message VARCHAR2(4000);
BEGIN
-- RECEIVE_MESSAGE 호출 (타임아웃 10초 설정)
v_status := DBMS_PIPE.RECEIVE_MESSAGE(
pipename => v_pipe_name,
timeout => 10
);
-- 반환값 검증: 0이어야만 UNPACK_MESSAGE 호출
IF v_status = 0 THEN
DBMS_PIPE.UNPACK_MESSAGE(v_message);
DBMS_OUTPUT.PUT_LINE('수신된 메시지: ' || v_message);
ELSIF v_status = 1 THEN
DBMS_OUTPUT.PUT_LINE('타임아웃 발생: 파이프에 메시지가 없습니다.');
ELSE
DBMS_OUTPUT.PUT_LINE('오류 발생, 상태 코드: ' || v_status);
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('예외 발생: ' || SQLERRM);
END;
/
원인 2 해결: 재시도(Retry) 로직 구현으로 타임아웃 대응
타임아웃 상황에서 일정 횟수 재시도하는 로직을 구현하면 안정성을 높일 수 있습니다.
DECLARE
v_pipe_name VARCHAR2(30) := 'MY_PIPE';
v_status INTEGER;
v_message VARCHAR2(4000);
v_retry INTEGER := 0;
v_max_retry INTEGER := 3;
BEGIN
LOOP
v_status := DBMS_PIPE.RECEIVE_MESSAGE(
pipename => v_pipe_name,
timeout => 5
);
IF v_status = 0 THEN
-- 메시지 수신 성공
DBMS_PIPE.UNPACK_MESSAGE(v_message);
DBMS_OUTPUT.PUT_LINE('메시지 수신 성공: ' || v_message);
EXIT;
ELSIF v_status = 1 THEN
v_retry := v_retry + 1;
DBMS_OUTPUT.PUT_LINE('재시도 중... (' || v_retry || '/' || v_max_retry || ')');
IF v_retry >= v_max_retry THEN
DBMS_OUTPUT.PUT_LINE('최대 재시도 초과. 종료합니다.');
EXIT;
END IF;
ELSE
DBMS_OUTPUT.PUT_LINE('수신 오류 발생. 상태 코드: ' || v_status);
EXIT;
END IF;
END LOOP;
END;
/
원인 3 해결: 송신 측 PACK_MESSAGE 확인 및 파이프 이름 일치 검증
송신 측에서 반드시 PACK_MESSAGE로 데이터를 패킹한 뒤 SEND_MESSAGE를 호출하는지 확인하고, 파이프 이름이 양측에서 동일한지 검증합니다.
-- [송신 측 예시]
DECLARE
v_pipe_name VARCHAR2(30) := 'MY_PIPE'; -- 수신 측과 동일한 이름 사용
v_status INTEGER;
BEGIN
-- 반드시 PACK_MESSAGE로 데이터를 먼저 패킹
DBMS_PIPE.PACK_MESSAGE('안녕하세요, 파이프 테스트 메시지입니다.');
v_status := DBMS_PIPE.SEND_MESSAGE(
pipename => v_pipe_name,
timeout => 10
);
IF v_status = 0 THEN
DBMS_OUTPUT.PUT_LINE('메시지 전송 성공');
ELSE
DBMS_OUTPUT.PUT_LINE('메시지 전송 실패, 상태 코드: ' || v_status);
END IF;
END;
/
-- [파이프 상태 확인 쿼리 - DBA 권한 필요]
SELECT NAME, ITEMS, SIZE_Used, SIZE_Limit
FROM V$DB_PIPES
WHERE NAME = 'MY_PIPE';
-- [파이프 초기화가 필요한 경우]
BEGIN
DBMS_PIPE.PURGE('MY_PIPE');
DBMS_OUTPUT.PUT_LINE('파이프 초기화 완료');
END;
/
예방 방법
1. 표준화된 파이프 통신 래퍼(Wrapper) 프로시저 구현
프로젝트 내에서 DBMS_PIPE를 직접 호출하는 대신, 반환값 검증 및 예외 처리 로직이 내장된 공통 래퍼 프로시저를 만들어 전 팀이 공유하도록 합니다. 이렇게 하면 반환값 미검증으로 인한 실수를 원천적으로 방지할 수 있습니다. 래퍼 프로시저에는 타임아웃 값, 최대 재시도 횟수, 로깅 기능을 표준으로 포함시켜 유지보수성을 높이는 것이 Best Practice입니다.
2. 운영 모니터링 및 파이프 상태 주기적 점검
V$DB_PIPES 동적 뷰를 활용하여 파이프의 현재 상태(메시지 수, 사용 크기 등)를 주기적으로 모니터링하는 스크립트를 운영 환경에 배치합니다. 파이프 버퍼가 꽉 차거나 장기간 메시지가 쌓이는 현상이 발생하면 알람이 울리도록 설정하여 선제적으로 대응합니다. 파이프 기반 통신 로직에는 반드시 타임아웃과 최대 재시도 횟수를 설정하여 무한 대기 상태가 발생하지 않도록 해야 합니다.
관련 에러
- ORA-06557:
RECEIVE_MESSAGE가 호출되지 않은 상태에서 발생하는 파이프 관련 에러로, ORA-06556과 함께 파이프 통신 오류의 대표적인 쌍을 이룹니다. - ORA-23322: 파이프 접근 권한이 없는 사용자가 파이프에 접근할 때 발생하며, 파이프 통신 구현 시 권한 설정을 잘못한 경우에 나타납니다.
- ORA-06558: 파이프 버퍼가 가득 찬 상태에서
PACK_MESSAGE를 추가로 호출할 때 발생하며, 대용량 메시지 전송 시 주의해야 합니다. - ORA-06559:
PACK_MESSAGE또는UNPACK_MESSAGE에서 데이터 타입이 일치하지 않을 때 발생하는 에러로, 송·수신 측의 데이터 타입 순서를 반드시 맞춰야 합니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.