본문 바로가기
Cloud 개발

Oracle ORA-65114 완벽 해결 가이드 (ATP 무료 버전)

by 굿대디~ 2025. 10. 12.
반응형

Oracle ATP 무료 버전에서 ORA-65114 에러 발생 시 해결 방법. 
데이터 삭제 후에도 공간이 반환되지 않는 이유와 SHRINK, MOVE를 활용한 실전 해결 가이드로, 휴지통 관리부터 테이블 재구성까지 단계별 설명해 드립니다.

문제 상황

Oracle Cloud ATP 무료 버전(20GB 제한)을 사용하던 중 갑자기 이런 에러가 발생했습니다.

ORA-65114: space usage in container is too high

분명 13GB만 사용 중인데 왜 이런 에러가 발생할까요? 더 황당한 것은 6GB 테이블에서 데이터를 대량 삭제했는데도 에러가 계속 발생한다는 점입니다.

핵심 원인: Oracle의 공간 관리 방식

Oracle은 데이터를 삭제해도 할당된 공간을 자동으로 반환하지 않습니다.

삭제 전: ████████████████████████ (6GB 사용)
삭제 후: ████░░░░░░░░░░░░░░░░░░░░ (6GB 여전히 점유!)

데이터는 사라졌지만, 테이블이 차지하고 있는 세그먼트 공간은 그대로입니다. 이것이 바로 문제의 원인입니다.


해결 방법 (난이도 순)

1단계: 휴지통 비우기 (가장 먼저!)

Oracle은 삭제된 테이블을 휴지통에 보관합니다. 이것부터 비워야 합니다.

-- 휴지통 내용 확인
SELECT object_name, original_name, 
       ROUND(space * 8/1024, 2) AS space_mb
FROM user_recyclebin
ORDER BY space DESC;

-- 휴지통 완전히 비우기
PURGE RECYCLEBIN;

이것만으로도 수 GB의 공간을 확보할 수 있습니다!


2단계: 실제 공간 사용량 확인

어떤 객체가 공간을 많이 차지하는지 확인합니다.

-- 테이블별 공간 사용량
SELECT 
    segment_name,
    segment_type,
    ROUND(bytes/1024/1024/1024, 2) AS size_gb
FROM user_segments
WHERE segment_type IN ('TABLE', 'INDEX')
ORDER BY bytes DESC;

-- LOB 세그먼트 확인 (CLOB, BLOB)
SELECT 
    segment_name,
    ROUND(bytes/1024/1024/1024, 2) AS size_gb
FROM user_segments
WHERE segment_type LIKE 'LOB%'
ORDER BY bytes DESC;

3단계: 테이블 공간 축소 - SHRINK

가장 안전한 방법입니다. 인덱스 재생성이 필요 없고, 서비스 중단도 최소화됩니다.

-- ROW MOVEMENT 활성화
ALTER TABLE your_large_table ENABLE ROW MOVEMENT;

-- 테이블과 인덱스 공간 축소
ALTER TABLE your_large_table SHRINK SPACE CASCADE;

-- (선택) ROW MOVEMENT 비활성화
ALTER TABLE your_large_table DISABLE ROW MOVEMENT;

장점:

  • 인덱스 재생성 불필요
  • 서비스 영향 최소
  • 안전하고 확실한 공간 반환

단점:

  • 실행 시간이 다소 오래 걸림
  • 일부 테이블 타입에서는 지원 안 됨

4단계: 테이블 재구성 - MOVE

SHRINK가 안 되는 경우 사용합니다. 테이블을 물리적으로 재구성하여 공간을 압축합니다.

MOVE의 동작 원리

[삭제 후 - 6GB 점유]
┌─────────────────────────────────────┐
│ ████░░░░░░░░░░██░░░░████░░░░░░░░░░░│
└─────────────────────────────────────┘

[MOVE 후 - 2GB로 축소]
┌─────────────┐
│ ████████████│
└─────────────┘

실행 방법

-- 1. 테이블 MOVE 실행
ALTER TABLE your_large_table MOVE ONLINE;

-- 2. 인덱스 재생성 (필수!)
-- MOVE 후 모든 인덱스가 UNUSABLE 상태가 됨
SELECT index_name, status 
FROM user_indexes 
WHERE table_name = 'YOUR_LARGE_TABLE';

-- 3. 인덱스 하나씩 REBUILD
ALTER INDEX index_name_1 REBUILD ONLINE;
ALTER INDEX index_name_2 REBUILD ONLINE;

인덱스 일괄 재생성 스크립트

BEGIN
    FOR idx IN (
        SELECT index_name 
        FROM user_indexes 
        WHERE table_name = 'YOUR_LARGE_TABLE'
    ) LOOP
        EXECUTE IMMEDIATE 
            'ALTER INDEX ' || idx.index_name || ' REBUILD ONLINE';
    END LOOP;
END;
/

SHRINK vs MOVE 비교표

항목 SHRINK SPACE MOVE
인덱스 재생성 ✅ 불필요 ❌ 필수
ROW MOVEMENT ❌ 필요 ✅ 불필요
서비스 영향 ⭐ 최소 ⚠️ 잠금 발생 (ONLINE 옵션 제외)
실행 속도 🐢 느림 🐇 빠름
추천 상황 일반적인 경우 SHRINK가 안 되는 경우

ATP 무료 버전 실전 가이드

권장 순서

-- Step 1: 휴지통 비우기
PURGE RECYCLEBIN;

-- Step 2: 공간 사용량 확인
SELECT segment_name, ROUND(bytes/1024/1024/1024, 2) AS gb
FROM user_segments
ORDER BY bytes DESC;

-- Step 3: 대용량 테이블 SHRINK
ALTER TABLE your_table ENABLE ROW MOVEMENT;
ALTER TABLE your_table SHRINK SPACE CASCADE;

-- Step 4: (SHRINK 실패 시) MOVE
ALTER TABLE your_table MOVE ONLINE;
-- 이후 인덱스 REBUILD 필수!

LOB 컬럼이 있는 경우

CLOB, BLOB 등의 LOB 컬럼은 별도 세그먼트로 저장되므로 추가 작업이 필요합니다.

-- LOB 포함 MOVE
ALTER TABLE your_table MOVE 
    LOB (lob_column_name) STORE AS (TABLESPACE data);

주의사항 및 팁

⚠️ 작업 전 체크리스트

  1. 백업 확인: 중요한 작업이므로 백업 필수
  2. 작업 시간: 테이블 크기에 비례 (6GB → 10~30분 소요 가능)
  3. 임시 공간: MOVE 시 원본 + 새 테이블 공간 필요 (일시적으로 2배 공간 필요)
  4. 인덱스: MOVE 후 반드시 인덱스 재생성

💡 Pro Tips

-- 압축 적용하여 공간 더 절약
ALTER TABLE your_table MOVE COMPRESS;

-- 작업 전후 크기 비교
SELECT 
    table_name,
    ROUND(num_rows * avg_row_len / 1024 / 1024, 2) AS estimated_mb
FROM user_tables
WHERE table_name = 'YOUR_TABLE';

예방 방법

정기적인 공간 관리

-- 월 1회 실행 권장
PURGE RECYCLEBIN;

-- 분기 1회 대용량 테이블 SHRINK
ALTER TABLE large_table_1 SHRINK SPACE CASCADE;
ALTER TABLE large_table_2 SHRINK SPACE CASCADE;

모니터링 쿼리

-- 전체 DB 사용량
SELECT 
    ROUND(SUM(bytes)/1024/1024/1024, 2) AS total_gb
FROM user_segments;

-- 상위 10개 대용량 객체
SELECT segment_name, segment_type,
       ROUND(bytes/1024/1024, 2) AS mb
FROM user_segments
ORDER BY bytes DESC
FETCH FIRST 10 ROWS ONLY;

마치며

Oracle ATP 무료 버전의 20GB 제한은 생각보다 빡빡합니다. 하지만 위의 방법들을 적절히 활용하면 충분히 효율적으로 사용할 수 있습니다.

핵심은 정기적인 공간 관리입니다. 휴지통을 비우고, 대용량 테이블을 주기적으로 SHRINK하는 습관을 들이면 ORA-65114 에러를 예방할 수 있습니다.

도움이 되셨다면 댓글로 알려주세요! 😊


관련 글

  • Oracle ATP 무료 버전 활용 가이드
  • Oracle 테이블스페이스 관리 완벽 가이드
  • ORA-01653 에러 해결 방법
반응형