Oracle 19c에서 ALTER INDEX … REBUILD ONLINE을 실행하면 재구성 도중의 DML은 계속 허용되지만, 작업 시작과 종료 시점에는 기반 테이블에 공유 테이블 잠금(TM 모드 4)을 요청하므로 커밋되지 않은 긴 트랜잭션이 있으면 재구성 세션이 대기할 수 있습니다. 그래서 작업 전에 장시간 트랜잭션을 정리하고, 중단된 온라인 재구성은 DBMS_REPAIR.ONLINE_INDEX_CLEAN으로 정리한 뒤 인덱스 상태를 확인하는 순서가 안전합니다.
- ONLINE 재구성은 시작과 종료 구간에서 TM 모드 4 잠금을 요청하므로, 커밋되지 않은 긴 트랜잭션이 남아 있으면 재구성이 대기하고 저널 세그먼트와 공간이 계속 점유될 수 있습니다.
- ONLINE을 쓰지 않은 일반 REBUILD는 필요한 잠금을 얻지 못하면 ORA-00054로 즉시 실패할 수 있어, 오류 코드가 원인 구분의 단서가 됩니다.
- 중단된 온라인 재구성은 ORA-08104를 남길 수 있고, Oracle 19c에서는 DBMS_REPAIR.ONLINE_INDEX_CLEAN으로 정리한 뒤 DBA_INDEXES.STATUS를 확인하는 편이 좋습니다.
- PostgreSQL의 REINDEX CONCURRENTLY는 트랜잭션 블록 안에서 실행할 수 없고, 실패하면 인덱스가 INVALID로 남을 수 있어 별도의 정리 계획이 필요합니다.
ONLINE 재구성도 잠금을 완전히 없애지 않는 이유
Oracle 19c에서 ALTER INDEX … REBUILD ONLINE을 실행해도 잠금이 완전히 사라지는 것은 아닙니다. 온라인 재구성은 작업 시작과 종료 시점에 기반 테이블에 공유 테이블 잠금(TM 모드 4)을 요청하고, 새 인덱스를 만드는 동안에는 로우 셰어(TM 모드 2) 수준의 잠금만 유지합니다. 모드 2는 일반 DML이 잡는 잠금과 호환되므로 재구성 도중에도 INSERT, UPDATE, DELETE는 계속 진행됩니다. 다만 재구성을 시작하기 전에 커밋되지 않은 긴 트랜잭션이 테이블을 잡고 있으면 재구성 세션은 그 트랜잭션이 끝날 때까지 기다립니다. 11g 이후 버전에서는 이 대기 때문에 뒤따르는 새 DML까지 함께 멈추지는 않지만, 재구성이 끝나지 않아 변경분을 담는 SYS_JOURNAL 임시 세그먼트와 공간이 계속 유지된다는 점은 운영에서 부담이 됩니다. Oracle은 재구성 대상 인덱스의 온라인 빌드 여부를 내부 상태로 관리하므로, 중단이 발생하면 그 상태를 먼저 해소해야 다음 작업이 진행됩니다.
대기와 장시간 작업을 구분하는 관찰 기준
운영에서 마주치는 증상은 크게 두 가지로 나뉩니다. 하나는 enq: TX – row lock contention이나 TM 잠금 대기로 세션이 밀리는 경우이고, 다른 하나는 재구성 세션이 좀처럼 끝나지 않는 경우입니다. 전자는 대개 특정 로우를 수정한 트랜잭션이 커밋되지 않아 생기며, 재구성 세션이 그 뒤에서 기다리는 구조일 수 있습니다. 이때는 어떤 세션이 무엇을 기다리는지부터 확인해 보세요. V$SESSION의 EVENT와 BLOCKING_SESSION, V$LOCK의 TM과 TX 항목, DBA_BLOCKERS를 함께 보면 대기 사슬이 읽기·쓰기 트랜잭션인지 DDL인지 구분됩니다. 재구성이 정상적으로 진행 중이라면 V$SESSION_LONGOPS에서 관련 인덱스 작업의 진행률을 확인해, 단순한 장시간 작업인지 잠금 대기인지 판단할 수 있습니다. ONLINE을 쓰지 않은 일반 REBUILD라면 잠금을 얻지 못하고 ORA-00054로 바로 실패하므로, 오류 코드 자체가 원인 구분의 단서가 됩니다.

실행 전에 확인할 사전 조건과 방식 선택
실행 전에는 세 가지를 먼저 확인해 두시길 권합니다. 첫째, 기반 테이블에 커밋되지 않은 장시간 트랜잭션이 남아 있는지입니다. 재구성이 잠금을 요청하는 시점에 그 트랜잭션이 버티고 있으면 작업이 시작하지 못하고 그대로 대기할 수 있습니다. 둘째, 공간입니다. 온라인 재구성은 기존 인덱스, 새 인덱스, 변경분을 담는 저널 세그먼트가 동시에 존재하므로 테이블스페이스와 임시 공간 여유를 평소보다 넉넉하게 잡아 두는 편이 좋습니다. 셋째, DDL 동시성과 실행 계획입니다. 재구성 중에는 같은 인덱스에 대한 DROP 같은 DDL이 대기하고, 인덱스가 잠시 UNUSABLE 상태가 되면 그 인덱스를 쓰던 쿼리의 계획이 바뀌어 느려질 수 있습니다. 유지보수 창이 확보되고 쓰기 중단이 허용된다면 ONLINE 없이 수행하는 재구성이 더 단순하고 빠를 수 있습니다. 파티션 인덱스라면 파티션 단위로 나누어 재구성하는 방식이 잠금 노출 시간과 공간 사용을 줄이는 데 도움이 됩니다.
중단된 재구성의 복구와 사후 검증
재구성이 중간에 끊기면 인덱스는 내부적으로 온라인 빌드 중 상태로 남을 수 있습니다. 이때 같은 인덱스에 다시 REBUILD나 DROP을 시도하면 ORA-08104가 발생하며, 원인은 남아 있는 저널 세그먼트와 내부 플래그입니다. Oracle 19c에서는 DBMS_REPAIR.ONLINE_INDEX_CLEAN 프로시저에 object_id와 wait_for_lock을 넘겨 이 상태를 정리할 수 있고, object_id에는 오류 메시지에 표시된 값을 그대로 사용합니다. 정리 후에는 DBA_INDEXES에서 STATUS가 VALID인지, DBA_SEGMENTS에 이전 저널 세그먼트가 남아 있지 않은지 확인하고, 필요하면 통계를 다시 수집해 실행 계획을 점검합니다. PostgreSQL에서는 REINDEX CONCURRENTLY를 트랜잭션 블록 안에서 실행할 수 없고, 실패하면 인덱스가 INVALID 상태로 남을 수 있으며 이런 인덱스는 조회에 사용되지 않습니다. 재구성 전후 점검 항목과 복구 절차를 평소에 문서로 정리해 두면 실제 장애 때 판단이 훨씬 빨라집니다.
출처
- Oracle Database SQL Language Reference, ALTER INDEX Oracle · 2026-09-29
- Oracle Database PL/SQL Packages and Types Reference, DBMS_REPAIR (ONLINE_INDEX_CLEAN) Oracle · 2026-09-29
- Amazon RDS for Oracle User Guide, Cleaning up interrupted online index builds Amazon Web Services · 2026-09-29
- PostgreSQL Documentation, REINDEX PostgreSQL Global Development Group · 2026-09-29