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

ORA-12012
2026년 09월 04일 | DBMS Error 가이드

이 글에서 다루는 내용

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

ORA-12012 error on auto execute of job 는?

ORA-12012는 Oracle DBMS_SCHEDULER 또는 DBMS_JOB 패키지에 의해 자동으로 실행되는 Job이 실행 도중 오류가 발생했을 때 나타나는 에러입니다. 이 에러는 Job 자체의 오류라기보다는 Job 실행 엔진이 해당 Job을 자동 수행하는 과정에서 내부적으로 발생한 예외 상황을 알려주는 Wrapper 에러로, alert.log나 trace 파일에 함께 기록됩니다. 실무에서는 이 에러 단독으로는 원인을 파악하기 어렵고, 반드시 함께 발생하는 ORA-06512, ORA-01555 등의 하위 에러 메시지를 함께 분석해야 근본 원인을 파악할 수 있습니다.


주요 발생 원인

1. Job이 참조하는 프로시저 또는 객체의 유효성 문제 (INVALID 상태)

Job이 실행하도록 등록된 PL/SQL 프로시저, 패키지, 혹은 함수가 컴파일 오류 등으로 INVALID 상태에 놓여 있는 경우 Job 실행 시 ORA-12012가 발생합니다. 특히 DDL 변경(테이블 컬럼 추가/삭제, 타입 변경 등) 이후 관련 프로시저가 자동 무효화(Invalidation)될 때 이 문제가 빈번하게 발생합니다. DBA는 정기적으로 INVALID 객체 현황을 점검하고, 배포 후 반드시 재컴파일 절차를 수행해야 합니다.

2. Job 실행 계정의 권한 부족 또는 세션 자원 한계 초과

Job이 실행되는 스키마 계정이 참조하는 테이블, 뷰, 시퀀스 등에 대한 접근 권한이 부여되지 않았거나, 세션 레벨의 자원(UNDO 공간, PGA 메모리, 열린 커서 수 등)이 한계를 초과하는 경우 에러가 발생합니다. Role을 통해 부여된 권한은 Definer 권한으로 실행되는 프로시저에서는 효력이 없기 때문에, 직접 권한(Direct Grant)으로 부여되어 있지 않으면 Job 실행 중 ORA-01031(insufficient privileges)과 함께 ORA-12012가 연쇄적으로 발생하기도 합니다. 자원 한계의 경우는 PROFILE 설정 및 undo_retention 파라미터를 함께 점검해야 합니다.

3. Job 내부 로직의 예외 처리 미흡 및 데이터 오류

Job이 실행하는 로직 내부에서 NULL 값 처리, 0으로 나누기, 예외 미처리(Unhandled Exception) 등으로 인해 비정상 종료되는 경우입니다. DBMS_JOB은 실패 횟수(FAILURES)를 누적하여 16회 이상 실패 시 BROKEN 상태로 전환되며, 이 경우 더 이상 자동 실행이 되지 않습니다. 프로시저 내부에 적절한 EXCEPTION 블록을 작성하고, 실패 이력을 모니터링하는 것이 중요합니다.


해결 방법

원인 1 해결: INVALID 객체 재컴파일

먼저 INVALID 상태의 객체를 조회하고 재컴파일합니다.

-- INVALID 객체 전체 조회
SELECT owner, object_name, object_type, status, last_ddl_time
FROM dba_objects
WHERE status = 'INVALID'
ORDER BY owner, object_type, object_name;

-- 특정 스키마의 INVALID 프로시저 재컴파일
ALTER PROCEDURE scott.my_job_proc COMPILE;

-- 패키지 재컴파일 (헤더 + 바디 순서 유지)
ALTER PACKAGE scott.my_job_pkg COMPILE;
ALTER PACKAGE BODY scott.my_job_pkg COMPILE BODY;

-- 전체 INVALID 객체 일괄 재컴파일 (SYS 실행)
EXEC DBMS_UTILITY.COMPILE_SCHEMA(schema => 'SCOTT', compile_all => FALSE);

-- 또는 utlrp.sql 스크립트 사용 (DBA 권한 필요)
-- @?/rdbms/admin/utlrp.sql

원인 2 해결: 권한 확인 및 직접 부여

-- Job 실행 계정의 권한 확인
SELECT grantee, owner, table_name, privilege, grantable
FROM dba_tab_privs
WHERE grantee = 'SCOTT';

-- Role이 아닌 직접 권한 부여 (Definer 권한 프로시저에서 유효)
GRANT SELECT, INSERT, UPDATE, DELETE ON hr.employees TO scott;
GRANT EXECUTE ON sys.dbms_lock TO scott;

-- DBMS_JOB BROKEN 상태 확인
SELECT job, log_user, what, broken, failures, last_date, next_date
FROM dba_jobs
WHERE broken = 'Y';

-- BROKEN 상태 Job 복구
BEGIN
  DBMS_JOB.BROKEN(job => 101, broken => FALSE, next_date => SYSDATE);
  COMMIT;
END;
/

-- DBMS_SCHEDULER Job 상태 확인
SELECT job_name, state, enabled, run_count, failure_count, last_run_duration
FROM dba_scheduler_jobs
WHERE state IN ('DISABLED', 'BROKEN');

-- SCHEDULER Job 활성화
BEGIN
  DBMS_SCHEDULER.ENABLE(name => 'SCOTT.MY_SCHEDULER_JOB');
END;
/

원인 3 해결: 내부 로직 예외 처리 강화

-- Job 실행 이력 및 에러 로그 조회 (DBMS_SCHEDULER)
SELECT log_date, job_name, status, error#, additional_info
FROM dba_scheduler_job_run_details
WHERE job_name = 'MY_SCHEDULER_JOB'
ORDER BY log_date DESC
FETCH FIRST 20 ROWS ONLY;

-- DBMS_JOB 실패 이력 확인
SELECT job, failures, broken, last_date, last_sec, what
FROM dba_jobs
WHERE failures > 0;

-- 예외 처리가 강화된 프로시저 예시
CREATE OR REPLACE PROCEDURE scott.my_job_proc AS
  v_error_msg VARCHAR2(4000);
BEGIN
  -- 비즈니스 로직
  INSERT INTO scott.job_result_table (run_date, status)
  VALUES (SYSDATE, 'START');
  
  -- ... 실제 작업 수행 ...
  
  UPDATE scott.job_result_table
  SET status = 'SUCCESS'
  WHERE run_date = TRUNC(SYSDATE);
  
  COMMIT;
EXCEPTION
  WHEN OTHERS THEN
    v_error_msg := SQLERRM || CHR(10) || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;
    -- 에러 로그 테이블에 기록
    INSERT INTO scott.job_error_log (log_date, proc_name, error_msg)
    VALUES (SYSDATE, 'MY_JOB_PROC', v_error_msg);
    COMMIT;
    -- 에러를 재발생시키지 않으면 Job은 성공으로 처리됨
    -- 필요에 따라 RAISE; 추가
END my_job_proc;
/

예방 방법

1. Job 실행 이력 모니터링 자동화

DBA_SCHEDULER_JOB_RUN_DETAILS 또는 DBA_JOBS 뷰를 정기적으로 조회하는 모니터링 스크립트를 작성하고, 실패 횟수가 임계값(예: 3회)을 초과하는 경우 DBA에게 이메일 또는 알림을 발송하는 체계를 구축하세요. Oracle Enterprise Manager(OEM)의 Job Activity 모니터링 기능을 활용하거나, 별도의 모니터링 Job을 통해 실패한 Job 목록을 매일 점검하는 것이 Best Practice입니다.

-- 최근 24시간 내 실패한 Scheduler Job 조회 (모니터링 쿼리)
SELECT job_name, log_date, status, error#, additional_info
FROM dba_scheduler_job_run_details
WHERE status = 'FAILED'
  AND log_date >= SYSDATE - 1
ORDER BY log_date DESC;

2. 배포 전후 INVALID 객체 점검 절차 표준화

운영 환경에 DDL 변경 또는 신규 객체 배포 시, 반드시 INVALID 객체 점검 및 재컴파일 절차를 Change Management 프로세스에 포함시키세요. 배포 스크립트 마지막에 항상 DBMS_UTILITY.COMPILE_SCHEMA 또는 utlrp.sql 실행을 포함하고, 배포 완료 후 INVALID 객체 수가 0인지 확인하는 검증 단계를 의무화하는 것이 재발 방지에 효과적입니다.


관련 에러

  • ORA-06512: PL/SQL 스택 추적 에러로, ORA-12012와 함께 alert.log에 기록되며 실제 오류 발생 위치(라인 번호)를 알려줍니다.
  • ORA-01031: 권한 부족(insufficient privileges) 에러로, Job 실행 스키마에 직접 권한이 없을 때 ORA-12012와 함께 발생합니다.
  • ORA-04068: 패키지 상태 무효화 에러로, 패키지가 재컴파일된 이후 기존 세션의 패키지 상태가 초기화될 때 발생하며 Job 실행 중 ORA-12012를 유발할 수 있습니다.
  • ORA-01555: Snapshot Too Old 에러로, 장시간 실행되는 Job에서 UNDO 공간 부족으로 발생하며 ORA-12012의 하위 에러로 자주 나타납니다.
  • ORA-12011: ORA-12012와 유사한 에러로, execution of N jobs failed 메시지와 함께 여러 Job이 동시에 실패했음을 나타냅니다.
DBMS 에러 코드 시리즈

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

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

댓글 남기기