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

ORA-14086
2026년 09월 22일 | DBMS Error 가이드

이 글에서 다루는 내용

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

ORA-14086 a partitioned index may not be rebuilt as a whole 는?

ORA-14086 에러는 파티션된 인덱스(Partitioned Index)를 전체 단위로 재구성(REBUILD)하려고 시도할 때 발생하는 오류입니다. Oracle은 파티션 인덱스의 특성상 전체를 한 번에 REBUILD하는 것을 허용하지 않으며, 반드시 각 파티션 또는 서브파티션 단위로 개별 재구성을 수행해야 합니다. 이 에러는 주로 대용량 파티션 테이블의 인덱스를 유지보수하는 작업 중에 자주 마주치게 되며, 파티션 인덱스의 동작 방식을 정확히 이해하지 못한 상태에서 작업할 때 나타납니다.


주요 발생 원인

  • 파티션 인덱스에 대해 REBUILD 명령을 전체 단위로 실행한 경우

파티션 인덱스에 대해 ALTER INDEX ... REBUILD 명령을 파티션 지정 없이 실행하면 이 에러가 발생합니다. Oracle의 파티션 인덱스는 내부적으로 각 파티션마다 독립적인 세그먼트를 가지고 있기 때문에, 전체를 하나의 단위로 처리하는 것이 구조적으로 불가능합니다. DBA가 일반 인덱스와 동일한 방식으로 REBUILD를 시도하면 반드시 이 오류를 마주치게 됩니다.

  • 스크립트 자동화 과정에서 인덱스 유형 구분 없이 일괄 REBUILD 수행

인덱스 유지보수 자동화 스크립트에서 모든 인덱스를 동일한 방식으로 처리하다 보면, 파티션 인덱스와 비파티션 인덱스를 구분하지 않아 이 에러가 발생할 수 있습니다. 특히 DBA_INDEXES 뷰를 조회해 인덱스 목록을 가져오는 스크립트에서 PARTITIONED 컬럼을 필터링하지 않으면 문제가 생깁니다. 이런 경우에는 스크립트가 특정 인덱스에서 실패하고 전체 유지보수 작업이 중단될 수 있습니다.

  • UNUSABLE 상태의 파티션 인덱스 복구 시 잘못된 명령 사용

테이블 파티션 작업(SPLIT, MERGE, EXCHANGE 등) 이후 인덱스가 UNUSABLE 상태가 되었을 때, 빠르게 복구하려는 시도에서 잘못된 명령을 사용하면 ORA-14086이 발생합니다. UNUSABLE 인덱스를 복구할 때도 파티션 단위의 REBUILD가 필요하다는 사실을 인지하지 못하면 동일한 오류가 반복됩니다. 특히 여러 파티션이 동시에 UNUSABLE 상태가 되었을 때 일괄 처리하려는 욕심이 이 실수를 유발합니다.


해결 방법

해결책 1: 파티션별 개별 REBUILD 수행

파티션 인덱스는 반드시 파티션 이름을 명시하여 개별적으로 REBUILD해야 합니다.

-- 잘못된 방법 (ORA-14086 발생)
ALTER INDEX HR.EMP_IDX REBUILD;

-- 올바른 방법: 파티션 단위로 REBUILD
ALTER INDEX HR.EMP_IDX REBUILD PARTITION p2023_q1;
ALTER INDEX HR.EMP_IDX REBUILD PARTITION p2023_q2;
ALTER INDEX HR.EMP_IDX REBUILD PARTITION p2023_q3;
ALTER INDEX HR.EMP_IDX REBUILD PARTITION p2023_q4;

해결책 2: UNUSABLE 상태의 파티션 인덱스 일괄 복구 스크립트

아래 스크립트를 사용하면 UNUSABLE 상태인 파티션 인덱스를 자동으로 탐색하여 파티션 단위로 REBUILD할 수 있습니다.

-- UNUSABLE 상태의 파티션 인덱스 파티션 확인
SELECT ip.index_owner,
       ip.index_name,
       ip.partition_name,
       ip.status
FROM   dba_ind_partitions ip
WHERE  ip.status = 'UNUSABLE'
ORDER BY ip.index_owner, ip.index_name;

-- 동적 SQL을 이용한 자동 REBUILD 스크립트
BEGIN
    FOR r IN (
        SELECT index_owner,
               index_name,
               partition_name
        FROM   dba_ind_partitions
        WHERE  status = 'UNUSABLE'
    ) LOOP
        BEGIN
            EXECUTE IMMEDIATE
                'ALTER INDEX ' || r.index_owner || '.' || r.index_name ||
                ' REBUILD PARTITION ' || r.partition_name ||
                ' ONLINE PARALLEL 4';
            DBMS_OUTPUT.PUT_LINE('REBUILT: ' || r.index_owner || '.' ||
                                 r.index_name || ' PARTITION ' || r.partition_name);
        EXCEPTION
            WHEN OTHERS THEN
                DBMS_OUTPUT.PUT_LINE('ERROR on ' || r.index_name ||
                                     '.' || r.partition_name || ': ' || SQLERRM);
        END;
    END LOOP;
END;
/

해결책 3: 자동화 스크립트에서 파티션 인덱스 구분 처리

인덱스 유지보수 스크립트를 작성할 때는 반드시 파티션 인덱스 여부를 먼저 확인해야 합니다.

-- 파티션 인덱스와 비파티션 인덱스를 구분하여 처리
BEGIN
    -- 비파티션 인덱스 REBUILD
    FOR r IN (
        SELECT owner, index_name
        FROM   dba_indexes
        WHERE  partitioned = 'NO'
          AND  status      = 'UNUSABLE'
          AND  owner NOT IN ('SYS','SYSTEM')
    ) LOOP
        EXECUTE IMMEDIATE
            'ALTER INDEX ' || r.owner || '.' || r.index_name || ' REBUILD ONLINE';
        DBMS_OUTPUT.PUT_LINE('Non-Partitioned REBUILT: ' || r.index_name);
    END LOOP;

    -- 파티션 인덱스 REBUILD (파티션 단위)
    FOR r IN (
        SELECT ip.index_owner,
               ip.index_name,
               ip.partition_name
        FROM   dba_ind_partitions ip
               JOIN dba_indexes i
                 ON ip.index_owner = i.owner
                AND ip.index_name  = i.index_name
        WHERE  ip.status = 'UNUSABLE'
          AND  i.owner NOT IN ('SYS','SYSTEM')
    ) LOOP
        EXECUTE IMMEDIATE
            'ALTER INDEX ' || r.index_owner || '.' || r.index_name ||
            ' REBUILD PARTITION ' || r.partition_name || ' ONLINE';
        DBMS_OUTPUT.PUT_LINE('Partitioned REBUILT: ' || r.index_name ||
                             '(' || r.partition_name || ')');
    END LOOP;
END;
/

해결책 4: 서브파티션 인덱스 REBUILD

복합 파티션(Composite Partitioning) 인덱스의 경우 서브파티션 단위로도 REBUILD가 가능합니다.

-- 서브파티션 인덱스 REBUILD
ALTER INDEX HR.EMP_IDX REBUILD SUBPARTITION p2023_q1_sub1;

-- UNUSABLE 서브파티션 인덱스 일괄 복구
BEGIN
    FOR r IN (
        SELECT index_owner,
               index_name,
               subpartition_name
        FROM   dba_ind_subpartitions
        WHERE  status = 'UNUSABLE'
    ) LOOP
        EXECUTE IMMEDIATE
            'ALTER INDEX ' || r.index_owner || '.' || r.index_name ||
            ' REBUILD SUBPARTITION ' || r.subpartition_name;
        DBMS_OUTPUT.PUT_LINE('Subpartition REBUILT: ' || r.subpartition_name);
    END LOOP;
END;
/

예방 방법

  • 인덱스 유지보수 스크립트에 파티션 유형 체크 로직 내장

모든 인덱스 유지보수 스크립트를 작성할 때는 DBA_INDEXES.PARTITIONED 컬럼을 반드시 조회하여 파티션 인덱스와 비파티션 인덱스를 구분하는 분기 처리를 포함해야 합니다. 이를 통해 자동화된 배치 작업 중 ORA-14086 에러로 인한 작업 중단을 원천 차단할 수 있으며, 유지보수 작업의 신뢰성을 높일 수 있습니다. 가능하다면 Oracle의 DBMS_STATS 패키지와 연계하여 통계 수집과 인덱스 관리를 통합적으로 수행하는 것을 권장합니다.

  • 파티션 DDL 작업 후 인덱스 상태 모니터링 자동화

SPLIT PARTITION, MERGE PARTITION, EXCHANGE PARTITION 등의 DDL 작업 이후에는 관련 인덱스의 상태가 UNUSABLE로 변경될 수 있으므로, 작업 직후 인덱스 상태를 자동으로 점검하는 모니터링 스크립트를 운영 절차에 포함시켜야 합니다. DBA_IND_PARTITIONSDBA_IND_SUBPARTITIONS 뷰를 주기적으로 조회하는 모니터링 잡(Job)을 DBMS_SCHEDULER를 통해 등록하면 인덱스 상태 이상을 조기에 감지할 수 있습니다.


관련 에러

  • ORA-14048: 파티션 유지보수 작업에서 허용되지 않는 조합을 사용했을 때 발생하며, ORA-14086과 유사한 맥락에서 파티션 인덱스 조작 시 주로 함께 나타납니다.
  • ORA-01502: 인덱스 또는 인덱스 파티션이 UNUSABLE 상태일 때 해당 인덱스를 사용하는 DML 또는 SELECT 문이 실패하면서 발생하는 에러로, ORA-14086으로 인해 REBUILD가 실패한 직후 연쇄적으로 발생할 수 있습니다.
  • ORA-14074: 로컬 인덱스의 파티션에 대한 잘못된 조작을 시도할 때 발생하며, 글로벌 파티션 인덱스와 로컬 파티션 인덱스의 차이를 이해하지 못한 경우 ORA-14086과 함께 자주 경험하게 됩니다.

DBMS 에러 코드 시리즈

주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

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

댓글 남기기