ORA-00600 오류 원인과 해결 방법 완벽 가이드

ORA-00600
2026년 05월 21일 | Oracle DBA 가이드

📌 이 글에서 다루는 내용

ORA-00600 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.

# ORA-00600 완전 정복: Oracle 내부 오류 실무 대응 가이드


ORA-00600란?

ORA-00600은 Oracle 데이터베이스 엔진 내부에서 예상치 못한 상황이 발생했을 때 Oracle 커널이 던지는 내부 오류(Internal Error Code)입니다. 일반적인 SQL 문법 오류나 권한 오류와 달리, 이 에러는 Oracle 소프트웨어 자체의 버그, 메모리 손상, 데이터 블록 오염 등 시스템 수준의 문제를 나타내기 때문에 단순한 재시도로 해결되지 않는 경우가 많습니다. 에러 메시지에는 반드시 대괄호 [] 안에 내부 인자값(argument)이 함께 출력되며, 이 인자값이 문제의 유형을 특정하는 핵심 단서가 됩니다.


주요 발생 원인

  • Oracle 소프트웨어 버그 (Bug)

Oracle 특정 버전 또는 패치 레벨에서 알려진 버그로 인해 내부 코드 경로에서 예외가 발생할 수 있습니다. 예를 들어 특정 SQL 실행 계획, 옵티마이저 기능, 또는 PL/SQL 처리 중 버그가 트리거되면 ORA-00600이 발생합니다. Oracle MOS(My Oracle Support)에는 수천 건의 ORA-00600 관련 버그 문서가 등록되어 있으며, 첫 번째 인자값([argument1])을 기준으로 검색하면 대부분 관련 패치를 찾을 수 있습니다.

  • 데이터 블록 손상 (Block Corruption)

디스크 I/O 오류, 스토리지 펌웨어 버그, 잘못된 백업/복구 작업 등으로 인해 데이터 블록이 손상되면 Oracle이 해당 블록을 읽는 과정에서 내부 검증 로직이 실패하여 ORA-00600이 발생합니다. 이 경우 V$DATABASE_BLOCK_CORRUPTION 뷰에 손상된 블록 정보가 기록되며, 알림 로그(alert log)에도 관련 스택 트레이스가 남습니다.

  • 메모리 손상 (Memory Corruption) 또는 부족

SGA(System Global Area) 또는 PGA(Program Global Area) 메모리 영역이 잘못된 포인터 접근이나 메모리 덮어쓰기로 인해 손상되면 Oracle 내부 코드가 예기치 않은 데이터를 만나게 됩니다. 특히 대용량 쿼리나 병렬 처리 중 PGA가 과도하게 사용될 때 이 문제가 나타날 수 있으며, OS 레벨에서 메모리 오류(ECC 오류 등)가 동반되는 경우도 있습니다.

  • 잘못된 데이터 딕셔너리(Data Dictionary) 상태

SYS 스키마의 딕셔너리 테이블이 직접 수정되거나, 불완전한 DDL 작업, 또는 비정상적인 데이터베이스 종료로 인해 딕셔너리 정보가 불일치 상태가 되면 Oracle이 객체 정보를 파싱하는 과정에서 내부 오류가 발생합니다. 이 경우 특정 테이블이나 인덱스에 접근할 때만 재현되는 패턴을 보이는 경우가 많습니다.

  • Oracle 실행 파일 손상 또는 잘못된 설치

OS 패치 적용 이후 Oracle 바이너리와의 라이브러리 불일치, 불완전한 Oracle 패치 적용, 또는 파일시스템 오류로 인한 실행 파일 손상이 원인이 될 수 있습니다. 이 경우 특정 기능이나 패키지를 호출할 때 일관되게 ORA-00600이 발생하며, Oracle Home 재설치 또는 패치 롤백으로 해결되는 경우가 있습니다.


해결 방법

1단계: 에러 인자값 및 트레이스 파일 확인

ORA-00600이 발생하면 가장 먼저 alert logtrace 파일을 확인해야 합니다.

-- alert log 위치 확인
SELECT VALUE FROM V$DIAG_INFO WHERE NAME = 'Diag Trace';

-- ADR(Automatic Diagnostic Repository) 기반 최근 인시던트 확인
SELECT INCIDENT_ID, CREATE_TIME, INCIDENT_STATUS, PROBLEM_KEY
FROM V$DIAG_INCIDENT
ORDER BY CREATE_TIME DESC
FETCH FIRST 10 ROWS ONLY;

-- 관련 에러 메시지 확인
SELECT MESSAGE_TEXT, TIME_STAMP
FROM V$DIAG_ALERT_EXT
WHERE MESSAGE_TEXT LIKE '%ORA-00600%'
ORDER BY TIME_STAMP DESC;

2단계: 데이터 블록 손상 확인 및 복구

-- 블록 손상 여부 확인
SELECT FILE#, BLOCK#, BLOCKS, CORRUPTION_TYPE
FROM V$DATABASE_BLOCK_CORRUPTION;

-- DBVERIFY를 활용한 특정 데이터파일 검증 (OS 명령)
-- dbv FILE=/oradata/ORCL/users01.dbf BLOCKSIZE=8192 LOGFILE=/tmp/dbv_result.log

-- RMAN을 이용한 블록 복구
-- RMAN> RECOVER DATAFILE 4 BLOCK 1234;
-- RMAN> BLOCKRECOVER DATAFILE 4 BLOCK 1234 FROM BACKUPSET;

-- 손상된 블록이 포함된 세그먼트 찾기
SELECT OWNER, SEGMENT_NAME, SEGMENT_TYPE, FILE_ID, BLOCK_ID, BLOCKS
FROM DBA_EXTENTS
WHERE FILE_ID = 4  -- 위 쿼리의 FILE# 값
  AND BLOCK_ID <= 1234  -- 위 쿼리의 BLOCK# 값
  AND BLOCK_ID + BLOCKS - 1 >= 1234;

3단계: 딕셔너리 정합성 검증

-- 딕셔너리 검증 (SYSDBA 권한 필요)
-- DBMS_UTILITY를 이용한 컴파일 오류 확인
SELECT OBJECT_NAME, OBJECT_TYPE, STATUS
FROM DBA_OBJECTS
WHERE STATUS = 'INVALID'
ORDER BY OBJECT_TYPE, OBJECT_NAME;

-- 무효화된 객체 재컴파일
BEGIN
    DBMS_UTILITY.COMPILE_SCHEMA(
        schema    => 'SCOTT',
        compile_all => FALSE  -- INVALID 객체만 컴파일
    );
END;
/

-- 전체 딕셔너리 무결성 검사 (운영 중 실행 주의)
ANALYZE TABLE SYS.OBJ$ VALIDATE STRUCTURE CASCADE;

-- 특정 테이블 통계 및 구조 검증
ANALYZE TABLE HR.EMPLOYEES VALIDATE STRUCTURE;

4단계: 특정 SQL에서만 발생하는 경우 – 옵티마이저 우회

-- 문제가 되는 SQL의 실행계획 확인
EXPLAIN PLAN FOR
SELECT /*+ NO_MERGE NO_PUSH_PRED */
    e.employee_id, e.first_name, d.department_name
FROM hr.employees e
JOIN hr.departments d ON e.department_id = d.department_id
WHERE e.salary > 5000;

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

-- 특정 힌트로 우회 (버그로 인한 실행계획 문제 시)
SELECT /*+ FULL(e) NO_PARALLEL(e) */
    e.employee_id, e.first_name, d.department_name
FROM hr.employees e
JOIN hr.departments d ON e.department_id = d.department_id
WHERE e.salary > 5000;

-- 세션 레벨에서 옵티마이저 기능 임시 비활성화
ALTER SESSION SET "_optimizer_mjc_enabled" = FALSE;
ALTER SESSION SET OPTIMIZER_FEATURES_ENABLE = '11.2.0.3';

-- 특정 SQL_ID에 대해 SQL Plan Baseline 고정 (근본 해결책이 아닌 임시방편)
DECLARE
    l_plans NUMBER;
BEGIN
    l_plans := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(
        sql_id => 'abc123xyz789'
    );
    DBMS_OUTPUT.PUT_LINE('Loaded plans: ' || l_plans);
END;
/

5단계: MOS 검색 및 패치 적용

ORA-00600의 첫 번째 인자값을 기준으로 Oracle MOS(support.oracle.com)에서 검색합니다.

-- 현재 Oracle 버전 및 패치 정보 확인
SELECT * FROM V$VERSION;

-- 적용된 패치 목록 확인 (12c 이상)
SELECT PATCH_ID, PATCH_UID, DESCRIPTION, ACTION, ACTION_TIME
FROM DBA_REGISTRY_SQLPATCH
ORDER BY ACTION_TIME DESC;

-- 데이터베이스 컴포넌트 상태 확인
SELECT COMP_NAME, VERSION, STATUS
FROM DBA_REGISTRY
ORDER BY COMP_NAME;

예방 방법

1. 정기적인 데이터베이스 헬스체크 및 백업 검증

RMAN을 활용한 주기적인 블록 검증을 자동화하여 블록 손상을 조기에 발견해야 합니다. 단순 백업에 그치지 않고, 백업 유효성 검증(VALIDATE CHECK LOGICAL)까지 스케줄링하는 것이 중요합니다.

📚 Oracle 에러 코드 시리즈

ORA 에러를 번호 순서대로 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

⚠ 본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.

댓글 남기기