從新編譯Invalid Oracle schema objects

在Oracle上進行一些操做例如:upgrades,patches和DDL操做會致使某些schema objects的失效。Oracle是提供了在須要調用時自動從新編譯的功能,可是有時這會比較耗時(可能會引起某些鎖),特別是針對一些有複雜依賴關係的對象。另外在某些特定的環境中,它的這種自動從新編譯的機制是不會被觸發的,例如我在DG上查詢某張視圖。這樣一來,就有必要主動對invalid objects進行檢查與重編譯。
查找Invalid objects
COLUMN owner format a15
COLUMN object_name FORMAT A30
SELECT owner,
       object_type,
       object_name,
       status
FROM   dba_objects
WHERE  status = 'INVALID'
ORDER BY owner, object_type, object_name;


有數種方法來處理這些失效的對象。
The Manual Approach
若是失效對象較少並且發生的頻率也比較小,可使用手工處理,處理語句以下:
ALTER PACKAGE my_package COMPILE;
ALTER PACKAGE my_package COMPILE BODY;
ALTER PROCEDURE my_procedure COMPILE;
ALTER FUNCTION my_function COMPILE;
ALTER TRIGGER my_trigger COMPILE;
ALTER VIEW my_view COMPILE;

可使用以下簡單的語句生成上述格式的查詢語句(不包含全部對象類型):
select
'alter '||object_type||' '||'"'||owner||'"'||'.'||object_name||' compile;' from dba_objects 
where status='INVALID'
order by object_type;

除了使用"ALTER"命令之外,還可使用"DBMS_DDL"來操做,不過有一些限制,其被操做的對象只能是PL/SQL對象,因此不能使用它來對視圖對象操做。
EXEC DBMS_DDL.alter_compile('PACKAGE', 'MY_SCHEMA', 'MY_PACKAGE');
EXEC DBMS_DDL.alter_compile('PACKAGE BODY', 'MY_SCHEMA', 'MY_PACKAGE');
EXEC DBMS_DDL.alter_compile('PROCEDURE', 'MY_SCHEMA', 'MY_PROCEDURE');
EXEC DBMS_DDL.alter_compile('FUNCTION', 'MY_SCHEMA', 'MY_FUNCTION');
EXEC DBMS_DDL.alter_compile('TRIGGER', 'MY_SCHEMA', 'MY_TRIGGER');

Custom Script
面對較多的失效對象而又須要很快的完成從新編譯的任務,編寫腳原本完成確定會比上述的方法要好的多。例如使用以下的腳原本查找、重編譯packages與package bodies.
SET SERVEROUTPUT ON SIZE 1000000
BEGIN
  FOR cur_rec IN (SELECT owner,
                         object_name,
                         object_type,
                         DECODE(object_type, 'PACKAGE', 1,
                                             'PACKAGE BODY', 2, 2) AS recompile_order
                  FROM   dba_objects
                  WHERE  object_type IN ('PACKAGE', 'PACKAGE BODY')
                  AND    status != 'VALID'
                  ORDER BY 4)
  LOOP
    BEGIN
      IF cur_rec.object_type = 'PACKAGE' THEN
        EXECUTE IMMEDIATE 'ALTER ' || cur_rec.object_type || 
            ' "' || cur_rec.owner || '"."' || cur_rec.object_name || '" COMPILE';
      ElSE
        EXECUTE IMMEDIATE 'ALTER PACKAGE "' || cur_rec.owner || 
            '"."' || cur_rec.object_name || '" COMPILE BODY';
      END IF;
    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.put_line(cur_rec.object_type || ' : ' || cur_rec.owner || 
                             ' : ' || cur_rec.object_name);
    END;
  END LOOP;
END;
/

此腳本在執行過程當中可能會存在對某些對象進行屢次編譯的狀況,因此選擇使用Oracle提供的現成的方法可能更好一些。

DBMS_UTILITY.compile_schema
compile_schema包含在DBMS_UTILITY包中,用來編譯被指定schema中全部的procedures,functions,packages,triggers.例如:
EXEC DBMS_UTILITY.compile_schema(schema => 'SCOTT');

UTL_RECOMP
UTL_RECOMP包內含了兩個用來處理invalid objects的procedure,"RECOMP_SERIAL"使用串行方式,"RECOMP_PARALLEL"以並行方式處理:
PROCEDURE RECOMP_SERIAL(
   schema   IN   VARCHAR2    DEFAULT NULL,
   flags    IN   PLS_INTEGER DEFAULT 0);

PROCEDURE RECOMP_PARALLEL(
   threads  IN   PLS_INTEGER DEFAULT NULL,
   schema   IN   VARCHAR2    DEFAULT NULL,
   flags    IN   PLS_INTEGER DEFAULT 0);

參數說明:
schema-指定須要進行從新編譯的schema.若是爲null則DB中全部無效的對象均被重編譯。
thread-此參數對於並行處理有效,若是爲null則會使用"job_queue_processes"參數值,一般threads的值最好和CPU的數量相匹配。
flag-用來內部診斷與測試。
使用舉例:
-- Schema level.
EXEC UTL_RECOMP.recomp_serial('SCOTT');
EXEC UTL_RECOMP.recomp_parallel(4, 'SCOTT');

-- Database level.
EXEC UTL_RECOMP.recomp_serial();
EXEC UTL_RECOMP.recomp_parallel(4);

-- Using job_queue_processes value.
EXEC UTL_RECOMP.recomp_parallel();
EXEC UTL_RECOMP.recomp_parallel(NULL, 'SCOTT');

使用這個包的一些限制:
(1).並行執行使用的是job隊列.當運行並行編譯的時候全部job都會標記爲disble直到編譯完成.
(2).包必須在sqlplus中以sys用戶或者有sysdba權限的用戶運行.
(3).UTL_RECOMP依賴於DBMS_STANDARD,DBMS_JOB,DBMS_RANDOM.
(4).若是在運行這個包的時候執行DDL語句可能會致使死鎖.

utlrp.sql and utlprp.sql
這兩個SQL腳本用來處理DB中全部的invalid objects.它們一般在DB升級或者patches之後運行。它們的存放位置在$ORACLE_HOME/rdbms/admin。其實utlrp.sql只是簡單調用了utlprp.sql,它在調用utlprp.sql時會傳遞給它一個參數,默認爲0,這個參數其實用來指定並行值。
此參數值定義:
0 - 基於CPU_COUNT參數設置並行值.
1 - 以串行方式編譯對象,一次編譯一個.
N - 以N個線程數並行進行編譯.
兩個腳本須要以sys用戶或者有sysdba權限的用戶執行。

------------------------------------------------------------------------------------------------------------------------------------------
參考來源:
http://www.oracle-base.com/articles/misc/recompiling-invalid-schema-objects.php
http://bbs.chinaunix.net/thread-3643482-1-1.html
http://topic.csdn.net/u/20110111/10/7b9a9e0c-5708-4146-b210-4f0d1e2f0fcd.html?53458
http://blog.csdn.net/a9529lty/article/details/6004334
http://dbataj.blogspot.tw/2007/08/how-to-compile-invalid-objects.html
http://www.51testing.com/?uid-16403-action-viewspace-itemid-98161
相關文章
相關標籤/搜索