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

ORA-01466
2026년 07월 17일 | DBMS Error 가이드

이 글에서 다루는 내용

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

ORA-01466 unable to read data – table definition has changed 는?

ORA-01466 에러는 Oracle의 Flashback Query 또는 AS OF 쿼리를 사용할 때, 조회 대상 테이블의 정의(DDL)가 지정한 과거 시점 이후에 변경된 경우 발생하는 에러입니다. 즉, 사용자가 특정 SCN(System Change Number) 또는 타임스탬프를 기준으로 과거 데이터를 읽으려 할 때, 그 시점과 현재 사이에 해당 테이블에 DDL 변경이 있었다면 Oracle은 해당 데이터를 일관성 있게 읽을 수 없다고 판단하여 이 에러를 던집니다. 주로 SELECT ... AS OF TIMESTAMP 또는 SELECT ... AS OF SCN 구문과 함께 나타나며, 운영 환경에서 테이블 구조 변경이 잦은 경우 특히 자주 마주치게 됩니다.


주요 발생 원인

1. Flashback Query 대상 테이블에 DDL 변경이 발생한 경우

가장 흔한 원인으로, AS OF TIMESTAMP 또는 AS OF SCN으로 과거 시점을 지정해 데이터를 조회하는 도중, 그 시점 이후에 해당 테이블에 컬럼 추가, 삭제, 타입 변경 등의 DDL이 실행된 경우입니다. Oracle은 Undo 데이터를 기반으로 과거 이미지를 재구성하는데, 테이블 정의 자체가 달라지면 과거 데이터 블록의 해석이 불가능해져 에러가 발생합니다. 예를 들어 어제 오전에 컬럼을 삭제했고 오늘 어제 오후 시점의 데이터를 Flashback으로 조회하려 하면 이 에러가 발생합니다.

2. Row Movement가 비활성화된 상태에서 Flashback Table 시도

Flashback Table 기능을 사용하려면 해당 테이블에 ROW MOVEMENT가 활성화되어 있어야 합니다. 이 옵션이 비활성화된 상태에서 테이블을 과거 시점으로 복원하려 하면 ORA-01466과 함께 관련 에러가 동반되기도 합니다. 또한, 파티션 테이블에서 파티션 관련 DDL(파티션 추가, 삭제, 분할 등)이 수행된 뒤 해당 시점 이전 데이터를 Flashback으로 읽으려 할 때도 동일한 문제가 나타납니다.

3. DBMS_FLASHBACK 또는 Flashback Data Archive 사용 중 테이블 재생성

DBMS_FLASHBACK.ENABLE_AT_TIME 또는 Flashback Data Archive(FDA)를 활용하는 애플리케이션에서, 특정 세션이 과거 시점으로 고정된 상태에서 다른 세션이나 배치 작업이 해당 테이블을 TRUNCATE, DROP 후 재생성(CREATE)하거나 ALTER TABLE로 구조를 변경한 경우에도 발생합니다. 특히 야간 배치에서 테이블을 재생성하는 패턴이 있는 시스템에서 Flashback 기능을 함께 사용하면 이 에러가 빈번하게 발생할 수 있습니다.


해결 방법

원인 1 해결: Flashback Query 시점 재조정

DDL이 발생한 시점 이후의 타임스탬프 또는 SCN으로 쿼리 시점을 조정하거나, DDL이 발생하기 이전의 데이터가 필요하다면 Flashback이 불가능하므로 다른 복구 방법(RMAN, Data Pump 등)을 검토해야 합니다.

-- 현재 SCN 확인
SELECT CURRENT_SCN FROM V$DATABASE;

-- 최근 DDL이 발생한 시점 이후 SCN으로 조회
SELECT *
FROM employees AS OF SCN 9999999
WHERE department_id = 10;

-- 타임스탬프 방식으로 조회 (DDL 이후 시점으로 조정)
SELECT *
FROM employees AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '30' MINUTE)
WHERE department_id = 10;

-- DDL 변경 이력 확인 (DBA_OBJECTS, LAST_DDL_TIME 활용)
SELECT object_name, last_ddl_time, object_type
FROM dba_objects
WHERE object_name = 'EMPLOYEES'
  AND owner = 'HR';

원인 2 해결: ROW MOVEMENT 활성화 후 Flashback Table 재시도

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

-- Flashback Table 수행 (특정 시점으로 테이블 복원)
FLASHBACK TABLE employees
TO TIMESTAMP (SYSTIMESTAMP - INTERVAL '1' HOUR);

-- 또는 SCN 기준으로 복원
FLASHBACK TABLE employees TO SCN 9999999;

-- 작업 완료 후 ROW MOVEMENT 다시 비활성화 (선택사항)
ALTER TABLE employees DISABLE ROW MOVEMENT;

-- 파티션 테이블의 경우 파티션별 DDL 이력 확인
SELECT table_name, partition_name, last_analyzed
FROM dba_tab_partitions
WHERE table_name = 'EMPLOYEES'
ORDER BY partition_position;

원인 3 해결: DBMS_FLASHBACK 세션 초기화 및 재설정

-- 현재 Flashback 세션 비활성화
EXEC DBMS_FLASHBACK.DISABLE;

-- Undo 보존 시간 및 Flashback 가능 범위 확인
SELECT name, value
FROM v$parameter
WHERE name IN ('undo_retention', 'db_flashback_retention_target');

-- Flashback Data Archive 사용 시 아카이브 이력 조회
SELECT flashback_archive_name, retention_in_days, status
FROM dba_flashback_archive;

-- 테이블이 FDA에 등록되어 있는지 확인
SELECT owner, table_name, flashback_archive_name
FROM dba_flashback_archive_tables
WHERE table_name = 'EMPLOYEES';

-- FDA 비등록 후 재등록 (테이블 재생성 상황 대응)
ALTER TABLE employees NO FLASHBACK ARCHIVE;
ALTER TABLE employees FLASHBACK ARCHIVE fda_1year;

일반적인 진단 쿼리

-- Undo 세그먼트 상태 및 보존 시간 확인
SELECT usn, status, xacts, rssize/1024/1024 AS rssize_mb
FROM v$rollstat rs
JOIN v$rollname rn ON rs.usn = rn.usn
ORDER BY rssize_mb DESC;

-- Flashback 가능한 가장 오래된 SCN 확인
SELECT oldest_flashback_scn,
       oldest_flashback_time
FROM v$flashback_database_log;

-- 특정 시간 기준 SCN 변환
SELECT timestamp_to_scn(
         TO_TIMESTAMP('2024-01-15 09:00:00', 'YYYY-MM-DD HH24:MI:SS')
       ) AS target_scn
FROM dual;

예방 방법

1. DDL 변경 전 Flashback 의존 작업 중단 및 공지 프로세스 수립

운영 환경에서 테이블에 DDL을 수행하기 전에는 반드시 해당 테이블에 Flashback Query, Flashback Table, 또는 FDA를 사용하는 애플리케이션이나 배치가 있는지 사전에 확인하는 프로세스를 수립해야 합니다. DDL 작업 일정은 모든 관련 팀에 공지하고, 변경 이후에는 Flashback 기준 시점을 DDL 이후로 재설정하도록 가이드를 제공해야 합니다. 또한 DBA_OBJECTS.LAST_DDL_TIME을 모니터링하는 스크립트를 작업 스케줄러(DBMS_SCHEDULER)로 등록하여 무단 DDL 변경을 자동으로 감지하는 체계를 갖추는 것이 중요합니다.

-- DDL 변경 모니터링을 위한 DDL 트리거 예시
CREATE OR REPLACE TRIGGER monitor_ddl_changes
AFTER DDL ON DATABASE
BEGIN
  INSERT INTO ddl_audit_log (
    ddl_type, object_type, object_name,
    object_owner, ddl_time
  ) VALUES (
    ora_sysevent, ora_dict_obj_type,
    ora_dict_obj_name, ora_dict_obj_owner,
    SYSTIMESTAMP
  );
END;
/

2. UNDO_RETENTION 및 Flashback Data Archive 정책 정기 검토

UNDO_RETENTION 파라미터와 GUARANTEE UNDO RETENTION 설정을 비즈니스 요구사항에 맞게 관리하고, Flashback이 반드시 필요한 중요 테이블은 Flashback Data Archive(FDA)에 등록하여 장기 이력을 보장해야 합니다. FDA를 사용하면 일반 Undo 기반 Flashback과 달리 테이블 구조 변경 이력까지 추적하므로, 단순 DDL 변경으로 인한 ORA-01466 발생 가능성을 근본적으로 낮출 수 있습니다. 정기적으로(월 1회 이상) V$FLASHBACK_DATABASE_LOG, DBA_FLASHBACK_ARCHIVE 뷰를 점검하여 Flashback 가용 범위가 SLA를 충족하는지 확인하는 루틴을 운영 프로세스에 포함시키는 것을 강력히 권장합니다.


관련 에러

  • ORA-01555 (Snapshot too old): Undo 데이터가 이미 덮어써져 과거 이미지를 재구성할 수 없을 때 발생하며, ORA-01466과 함께 Flashback 관련 트러블슈팅에서 자주 동반됩니다.
  • ORA-08185 (Flashback not supported for user SYS): SYS 스키마 객체에 Flashback Query를 시도할 때 발생합니다.
  • ORA-01031 (Insufficient privileges): Flashback 관련 권한(FLASHBACK ANY TABLE, FLASHBACK OBJECT)이 없을 때 발생합니다.
  • ORA-38729 (Not enough flashback database log data): Flashback Database 수행 시 지정한 시점까지의 Flashback 로그가 부족할 때 발생합니다.

DBMS 에러 코드 시리즈

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

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

댓글 남기기