識別和修復無效物件

llnnmc發表於2017-05-03

一、無效物件的識別和編譯

 

1、識別無效物件

 

col object_name for a30

select object_name, object_type from dba_objects where owner = 'CMES' and status='INVALID';

 

2、編譯單個無效物件

 

語法:alter 物件型別 物件名稱 compile;

 

如重新編譯某個儲存過程,編譯不能透過時,可用SQL*Plus命令show errors檢視原因,但是檢視不支援show errors

alter procedure cmes.m085i_chk_lot compile;

 

警告: 更改的過程帶有編譯錯誤。

 

show errors;

 

PROCEDURE CMES.M085I_CHK_LOT 出現錯誤:

 

LINE/COL ERROR

-------- -----------------------------------------------------------------

27/7     PLS-00103: 出現符號 "="在需要下列之一時:

         := . ( @ % ;

         符號 ":=在 "=" 繼續之前已插入。

 

可以使用檢視dba_dependencies檢視物件間的依賴關係,便於分析編譯錯誤的原因,如:

col owner for a10

col name for a20

col referenced_owner for a20

col referenced_name for a20

col referenced_link_name for a20

select * from dba_dependencies where owner = 'CMES' and name='FS_GET_CHANNEL' and referenced_owner != 'SYS';

 

OWNER      NAME                 TYPE               REFERENCED_OWNER     REFERENCED_NAME      REFERENCED_TYPE    REFERENCED_LINK_NAME DEPENDENCY_TYPE

---------- -------------------- ------------------ -------------------- -------------------- ------------------ -------------------- ---------------

CMES       FS_GET_CHANNEL       PROCEDURE          CMES                 FS_CHANNEL_T         TABLE                                   HARD

CMES       FS_GET_CHANNEL       PROCEDURE          CMES                 FS_CHK_CONDITION     PROCEDURE                               HARD

CMES       FS_GET_CHANNEL       PROCEDURE          CMES                 FS_CONDITION_T       TABLE                                   HARD

CMES       FS_GET_CHANNEL       PROCEDURE          CMES                 C_SILO_T             TABLE                                   HARD

CMES       FS_GET_CHANNEL       PROCEDURE          RMES                 R_BOLT_RECORD_T      TABLE                                   HARD

CMES       FS_GET_CHANNEL       PROCEDURE          RMES                 R_WIP_BOL_T          TABLE                                   HARD

CMES       FS_GET_CHANNEL       PROCEDURE          CMES                 C_BOLT_T             TABLE                                   HARD

 

3、透過Oracle自帶的指令碼可以編譯全部無效物件

 

用系統自帶的指令碼可以執行對全部無效物件的編譯,注意該指令碼必須以SYSDBA身份執行:

@?\rdbms\admin\utlrp

 

4、透過構建SQL編譯無效物件

 

批次編譯無效物件的一種方法就是利用以下SQL查詢批次生成編譯語句,然後提取執行。該方法的好處是可以比較靈活的選擇物件來執行,並且無需以SYSDBA身份登入:

select 'alter procedure ' || object_name || ' compile;' from dba_objects where owner = 'CMES' and status='INVALID';

 

5、透過以下儲存過程編譯無效物件

 

如果提取utlrp的指令碼,可以重新組織成一個用於編譯所有無效物件的儲存過程

create or replace procedure recompile as

 

  -- 編譯無效物件

 

  type tab_char is table of varchar2(32767) index by binary_integer;

  commands     tab_char;

  table_exists number;

 

begin

  utl_recomp.recomp_parallel(0);

 

  select count(*)

    into table_exists

    from dba_objects

   where owner = 'SYS'

     and object_name = 'UTLIRP_ENABLED_FUNC_INDEXES'

     and object_type = 'TABLE';

 

  if (table_exists > 0) then

    execute immediate q'+

         select 'alter index "' || u.name || '"."' || o.name || '" enable'

            from utlirp_enabled_func_indexes e, ind$ i, obj$ o, user$ u

            where e.obj# = i.obj# and i.obj# = o.obj# and o.owner# = u.user#

              and bitand(i.flags, 1024) != 0+' bulk

                      collect

      into commands;

 

    if (commands.count() > 0) then

      for i in 1 .. commands.count() loop

        execute immediate commands(i);

      end loop;

    end if;

 

    execute immediate 'drop table utlirp_enabled_func_indexes';

  end if;

 

  dbms_registry_sys.validate_components;

end;

 

二、不可用索引及其修復

 

如果某個儲存過程物件變為無效,DBA可以不執行任何操作,首次訪問該物件時,Oracle會嘗試進行重新編譯。但如果索引變得不可用,則必須顯示的修復它。

 

10g以前的版本中,如果會話試圖使用不可用的索引,那麼會立即返回一條錯誤訊息,同時語句執行失敗。但10g開始更改了這種方式,如果索引不可用,那麼語句會重走不需要該索引的執行計劃,執行總會成功,雖然效能可能會顯著下降。

 

有一個例項引數控制該行為:skip_unusable_indexes,預設為true,表示即便索引不可用,也可以執行語句。這是一個動態引數,如想實現舊版本中不可用索引導致返回錯誤訊息的功能,則可將其修改為false

 

即便skip_unusable_indexestrue,對於透過索引實施約束的情況是一個例外,如主鍵約束,需要建立索引,如果主鍵上的索引變得不可用,那麼會對DML命令鎖定表,此時無法進行DML操作。

 

1、查詢不可用索引

 

select table_name, index_name, index_type, tablespace_name, uniqueness from dba_indexes where owner = 'CMES' and status = 'UNUSABLE';

 

2、修復不可用索引

 

如果rowid指標不再正確,則索引將標記為不可用。為了修復不可用索引,可以使用以下命令重建索引:

alter index 索引名 rebuild [tablespace 表空間名] [online] [nologging];

 

tablespace:預設索引在當前表空間內重建,也可以指定重建在其它表空間上。

online:預設重建索引過程會對DML命令鎖定表,若使用該引數則不會影響DML的操作。

nologging:指示Oracle不為索引重建操作生成重做,這樣重建速度將加快,但也意味著應當對包含指定索引的表空間進行備份。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28974745/viewspace-2138333/,如需轉載,請註明出處,否則將追究法律責任。

相關文章