[Oracle] Invaild Object 발생원인 및 재컴파일 방법
데이터베이스 주간 점검항목으로 선정한 invalid object는 다양한 상황에 의해 발생할 수 있습니다. 이와 같은 invalid object는 데이터베이스에서 사용할 수 없는 상태를 의미하며, 보통 다음과 같은 이유로 인해 발생합니다.
- 의존성 문제: 객체가 의존하고 있는 다른 객체가 변경되거나 삭제된 경우. 예를 들어, 테이블이 변경되면 이를 참조하는 뷰나 프로시저가 invalid 상태가 될 수 있습니다.
- 사례: 테이블 employees를 참조하는 뷰 employee_view가 있을 때, employees 테이블의 구조가 변경되면 employee_view는 invalid 상태가 됩니다. 이는 테이블의 변경이 뷰의 정의와 일치하지 않기 때문입니다.
- 컴파일 에러: PL/SQL 코드에 문법적 오류나 논리적 오류가 있는 경우. 이로 인해 프로시저, 함수, 패키지 등이 컴파일되지 않고 invalid 상태로 남게 됩니다.
- 사례: 프로시저 calculate_bonus를 작성 중에 문법 오류가 포함된 경우, 이 프로시저는 컴파일되지 않고 invalid 상태가 됩니다.
- 권한 문제: 객체를 참조하는 사용자에게 필요한 권한이 없어진 경우. 예를 들어, 사용자에게 특정 테이블에 대한 SELECT 권한이 제거되면 이를 참조하는 뷰나 프로시저는 invalid 상태가 될 수 있습니다.
- 사례: 프로시저 update_salary가 테이블 salaries를 업데이트하는데, 사용자에게 salaries 테이블에 대한 UPDATE 권한이 제거되면 update_salary 프로시저는 invalid 상태가 됩니다.
- 데이터베이스 구조 변경: 테이블, 인덱스, 시퀀스 등과 같은 데이터베이스 객체의 구조가 변경된 경우.
- 사례: 인덱스 emp_idx가 삭제되면, 이 인덱스를 사용하는 뷰나 프로시저는 invalid 상태가 될 수 있습니다.
- 시스템 오류: 데이터베이스 서버의 문제나 네트워크 문제로 인해 객체가 손상될 경우.
- 사례: 데이터베이스 서버 크래시 후 복구 과정에서 일부 객체가 손상되어 invalid 상태가 될 수 있습니다.
invalid object는 주로 객체 간의 의존성 문제, 권한 문제, 구조 변경 또는 시스템 오류로 인해 발생하며, 이를 해결하기 위해 원인을 파악하고 적절히 재컴파일하거나 수정해야 합니다. 그러나 invalid object를 반드시 재컴파일할 필요가 없는 경우도 몇 가지 있습니다. 이러한 상황에서는 데이터베이스가 객체를 자동으로 다시 컴파일하거나 사용자가 직접 개입하지 않아도 되는 이유를 포함합니다. 주요 이유는 다음과 같습니다.
- 자동 재컴파일: Oracle Database는 객체가 처음 호출될 때 자동으로 다시 컴파일하는 기능을 제공합니다. 즉, invalid 상태의 객체가 호출되면 데이터베이스가 해당 객체를 자동으로 컴파일하여 사용할 수 있게 합니다. 이는 Oracle의 자동 의존성 관리 시스템 덕분에 가능합니다.
- 사례: 프로시저가 invalid 상태일 때, 사용자가 이를 호출하면 Oracle이 자동으로 해당 프로시저를 컴파일합니다. 이로 인해 사용자는 직접 재컴파일 명령을 실행하지 않아도 됩니다.
- 비사용 객체: invalid 상태의 객체가 현재 사용되지 않는 경우, 즉시 재컴파일할 필요가 없습니다. 이러한 객체는 필요할 때까지 invalid 상태로 남아 있을 수 있습니다.
- 사례: 과거에 사용되었으나 현재 사용되지 않는 보고서 생성 프로시저가 invalid 상태인 경우, 이 프로시저가 다시 필요해질 때까지 재컴파일할 필요가 없습니다.
- 의도적인 변경 대기: 일부 객체는 향후 변경이나 업데이트를 위해 의도적으로 invalid 상태로 유지될 수 있습니다. 개발 중이거나 테스트 중인 객체는 나중에 한꺼번에 재컴파일할 수 있습니다.
- 사례: 대규모 시스템 업데이트 중, 여러 관련 객체가 변경될 예정이라면, 전체 작업이 완료된 후 모든 객체를 한꺼번에 재컴파일하는 것이 효율적일 수 있습니다.
- 의존성 해결: 일부 객체는 특정 의존성이 해결될 때까지 재컴파일할 필요가 없습니다. 예를 들어, 아직 배포되지 않은 라이브러리나 패키지에 의존하는 객체는 의존성이 준비될 때까지 invalid 상태로 남아 있을 수 있습니다.
- 사례: 새로운 버전의 패키지가 배포될 때까지 기다리는 중인 프로시저나 함수는 패키지가 준비된 후에 한꺼번에 재컴파일할 수 있습니다.
이러한 이유들로 인해, 모든 invalid 객체를 즉시 재컴파일할 필요가 없을 수 있습니다. 다만, 시스템의 안정성과 성능을 보장하기 위해 주기적으로 invalid 객체를 점검하고 필요한 경우 재컴파일하는 것이 좋습니다.
- 수동으로 재컴파일하는 방법
$ vi recompile.sh#!/bin/bash sqlplus -s '/as sysdba' <<EOF > recompile.sql 2>&1 SET HEADING OFF; SET FEEDBACK OFF; SET PAGESIZE 0; SET LINESIZE 1000; SELECT 'ALTER ' || OBJECT_TYPE || ' ' || OWNER || '.' || OBJECT_NAME || DECODE(OBJECT_TYPE, 'PACKAGE BODY', ' COMPILE BODY;', ' COMPILE;') FROM DBA_OBJECTS WHERE STATUS = 'INVALID' AND object_type IN ('VIEW', 'SYNONYM', 'PROCEDURE', 'FUNCTION', 'PACKAGE BODY', 'PACKAGE', 'TRIGGER'); EXIT; EOF$ chmod 744 ./recompile.sh$ ./recompile.sh$ sqlplus '/as sysdba'SQL> @recompile.sql
- Oracle에서 제공하는 유틸리티를 사용해서 자동으로 재컴파일하는 방법
– 만약 utlrp.sql로 수행이 안될 경우에는 여러 번 수행하면 재컴파일됩니다.$ sqlplus '/as sysdba'SQL> @$ORACLE_HOME/rdbms/admin/utlrp.sqlPL/SQL procedure successfully completed.