一、報錯
有個朋友遇到一個存儲過程,開發反饋執行有問題,需要排查,后續檢查發現這個JOB調用執行存儲過程報對象不存在??? 需要對這個問題進行分析一波 ORA-8103 "Object No Longer Exists"
二、相關資料
問題很簡單對象不存在? 真的不存在嗎? 對象檢查還是存在的!那什么情況會出現對象不存在的問題??? 參考鏈接 Solution: 'ORA-8103: Object no longer exists' When Insert Into External Table after Truncate With Storage Performed (Doc ID 422083.1) OERR: ORA-8103 "Object No Longer Exists" Master Note / Troubleshooting, Diagnostic and Solution (Doc ID 8103.1) 膜拜下面兩位大神的博客 http://blog.itpub.net/29863023/viewspace-2662449/ https://www.askmaclean.com/archives/ora-8103.html 如果執行 flush buffer cache之后再次analyze validate structure不再報ORA-8103錯誤則說明: 可能是完全正常的現象,之前的ORA-8103正是也因為對象正在被DROP/TRUNCATE而導致SELECT報ORA-8103。一般來說Call Stack會顯示進程正嘗試訪問該段的segment header。
更多信息可以參考BUG 7441661 也可能該問題僅僅發生在buffer cache層,而沒有發生在DISK上。通過flush buffer_cache若能解決,則一般是這種情況,往往是Buffer Cache管理的BUG 。 ORA-8103 is also caused by an unexpected data_object_id where it is concurrently changing for the involved object while the affected SQL statement
is executed. Expected behavior. Tables are being dropped/truncated while a SQL statement for those tables is still in execution. In the case of an index, it might be caused by
an index rebuild. In other words the object has been deleted by another session since the operation began. Look if dba_objects.data_object_id is changing for the affected object while queries are being executed. data_object_id is changed by DDL statements like: truncate table alter index .. rebuild alter table .. move alter table .. exchange partition alter table .. split partition etc. For a truncate look for column TRUNCATED in DBA_TAB_MODIFICATIONS. Note that it indicates whether the table has been truncated since the last
analyze. See documentation. In 11g+ parameter enable_ddl_logging can be set to TRUE to print DDL statements in the alert log or in 12c in the log/ddl sub-directory of the
ADR home (example <diagostic_dest>/rdbms/<sid>/<dbname>/log/ddl_$ORACLE_SID.log) and identify what DDL's are run that may potentially cause
this error. The init.ora parameter ENABLE_DDL_LOGGING is licensed as part of Oracle Database Lifecycle Management Pack for Oracle Database
when set to TRUE. For more information check the "Database Licensing Information User Manual" section "Oracle Database Editions".
三、相關可能性太多!
觀察JOB調用執行的存儲過程,存在truncate,與文檔中的 --session 1 select object --session 2 truncate --session 1 返回ORA報錯對象不存在 模擬! SQL> select sum(bytes)/1024/1024/1024 from user_segments where segment_name='RANGE_PART_TAB'; SUM(BYTES)/1024/1024/1024 ------------------------- 2.93066406 SQL> set timing on SQL> set autotrace on SQL> select count(*) from RANGE_PART_TAB; SQL> truncate table scott.RANGE_PART_TAB; * ERROR at line 1: ORA-08103: object no longer exists SQL> select object_id,DATA_OBJECT_ID from dba_objects where owner='SCOTT' AND OBJECT_NAME='TT'; SQL> CREATE TABLE TT(ID INT); SQL> select object_id,DATA_OBJECT_ID from dba_objects where owner='SCOTT' AND OBJECT_NAME='TT'; OBJECT_ID DATA_OBJECT_ID ---------- -------------- 89382 89382 SQL> TRUNCATE TABLE TT; SQL> select object_id,DATA_OBJECT_ID from dba_objects where owner='SCOTT' AND OBJECT_NAME='TT'; OBJECT_ID DATA_OBJECT_ID ---------- -------------- 89382 89382 SQL> INSERT INTO TT VALUES(1); SQL> COMMIT; SQL> TRUNCATE TABLE TT; OBJECT_ID DATA_OBJECT_ID ---------- -------------- 89382 89383 SQL> INSERT INTO TT VALUES(1); SQL> COMMIT; SQL> TRUNCATE TABLE TT reuse storage; OBJECT_ID DATA_OBJECT_ID ---------- -------------- 89382 89384
將情況反饋給開發,開發可以從幾個方面調整
1.truncate與select 代碼錯開;
2.如果select truncate的對象報錯,ORA-8103 再次查詢,而非結束存儲過程異常退出;
下一次再次執行可以加上 sleep 5s 再次查詢一次,truncate一個對象2~3s就完成了。或者sleep更久