ORA-08103物件不再存在問題分析
在資料庫進行CTAS 操作查詢表 ooo .A_D_BRXXX_XXX_XXX 時報出了ORA-08103 錯誤,
SQL> create table A_D_BRXXX_XXX_XXX_1125 as select * from .A_D_BRXXX_XXX_XXX; ORA-08103: object no longer exists |
關於ORA-08103 的解釋:
Error: ORA 8103
|
Description ORA-8103 is reporting that a SQL statement found a block that no longer belongs to the object referenced in the statement. Cause
ORA-8103 is caused by an invalid block type. The block header has an invalid block type or the block type inside the block is not expected; e.g. a data block (Type=6) was expected but the actual block information is not a data block (Type!=6).
|
從以上的關於的ORA-08103 可以知道 ORA-08103 出現的場景是當一個語句執行時發現某個塊不屬於某個物件。
導致的原因有二:
1. 導致ORA-08103 的原因是存在不可用的塊型別。即所描述的塊型別和實際記錄塊型別不一致。
2. 另一個原因是當某個語句執行時其data_object_id 被改變導致,這種是由於 DDL 引起。
而可以確認的是在執行CTAS 操作時,資料庫中並不存在其他的會話在進行 DDL 操作。因此,可以懷疑導致的問題的原因是第一種。
10046 跟蹤:
以下對CTAS 的過程進行 10046 追蹤,以確認錯誤在哪一步出現:
以下部分 10046 日誌擷取: CLOSE #4574899200:c=3,e=4,dep=1,type=0,tim=47159071133647 ===================== PARSING IN CURSOR #4574893000 len=83 dep=0 uid=0 oct=1 lid=0 tim=47159071134928 hv=506090881 ad='7000000a7827840' sqlid='2918v7hg2npc1' create table OOO .A_D_BRXXX_XXX_XXX_1126 as select * from OOO .A_D_BRXXX_XXX_XXX <<<< 執行的 CTAS 語句 END OF STMT PARSE #4574893000:c=2530,e=4075,p=0,cr=10,cu=0,mis=1,r=0,dep=0,og=1,plh=2393565612,tim=47159071134928 BINDS #4574047816: 。。。。。 <<<< 省略 。。。。。 DDE Action 'DB_STRUCTURE_INTEGRITY_CHECK' was flood controlled ----- END DDE Action: 'DB_STRUCTURE_INTEGRITY_CHECK' (FLOOD CONTROLLED, 1 csec) ----- Executing ASYNC actions ----- END DDE Actions Dump (total 0 csec) ----- ===================== PARSING IN CURSOR #4574654208 len=67 dep=1 uid=0 oct=3 lid=0 tim=47159074207269 hv=785625969 ad='7000000a789fd58' sqlid='at1ygf4rd7cvj' select file#, block#, blocks from seg$ where type# = 3 and ts# = :1 <<<< 透過 seg$ 查詢 type#=3 的檔案和塊號, type#=3 是 TEMPORARY ,這裡指的是臨時段 END OF STMT PARSE #4574654208:c=53,e=88,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,plh=1764637915,tim=47159074207269 BINDS #4574654208: Bind#0 oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00 oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0 kxsbbbfp=110af7520 bln=22 avl=02 flg=05 value=6 <<<< 繫結變數 ts# 的值,這裡是 6,6 號表空間正是 OOO 使用者所在的表空間 EXEC #4574654208:c=63,e=102,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,plh=1764637915,tim=47159074207506 FETCH #4574654208:c=1793,e=2805,p=0,cr=312,cu=0,mis=0,r=1,dep=1,og=4,plh=1764637915,tim=47159074212837 FETCH #4574654208:c=25453,e=53743,p=0,cr=4792,cu=0,mis=0,r=1,dep=1,og=4,plh=1764637915,tim=47159074266671 WAIT #4574893000: nam='db file sequential read' ela= 28 file#=678 block#=116881 blocks=1 obj#=-1 tim=47159074266832 <<<< 最後一個讀取的塊是 678 號檔案的 116881 號塊 EXEC #4574893000:c=1236647,e=3132010,p=8505,cr=81566,cu=13568,mis=0,r=0,dep=0,og=1,plh=2393565612,tim=47159074266999 <<<< 執行 ERROR #4574893000: err=8103 tim=47159074267016 <<< 丟擲了 8103 的錯誤 STAT #4574893000 id=1 cnt=0 pid=0 pos=1 obj=0 op='LOAD AS SELECT (cr=0 pr=0 pw=0 time=37 us)' STAT #4574893000 id=2 cnt=376158 pid=1 pos=1 obj=0 op='PARTITION RANGE ALL PARTITION: 1 1945 (cr=9786 pr=8504 pw=0 time=387949 us cost=22628 size=453306100 card=2887300)' STAT #4574893000 id=3 cnt=376158 pid=2 pos=1 obj=4312763 op='TABLE ACCESS FULL A_D_BRXXX_XXX_XXX PARTITION: 1 1945 (cr=9786 pr=8504 pw=0 time=274483 us cost=22628 size=453306100 card=2887300)' STAT #4574654208 id=1 cnt=2 pid=0 pos=1 obj=14 op='TABLE ACCESS FULL SEG$ (cr=5104 pr=0 pw=0 time=2790 us cost=989 size=20 card=1)' CLOSE # 4574654208:c=26,e=42,dep=1,type=0,tim=47159074267249 <<<< 報錯之後結束執行 WAIT #4574893000: nam='log file sync' ela= 60983 buffer#=4081 sync scn=2662421508 p3=0 obj#=4314004 tim=47159074331972 WAIT #4574893000: nam='SQL*Net break/reset to client' ela= 11 driver id=1650815232 break?=1 p3=0 obj#=4314004 tim=47159074336018 WAIT #4574893000: nam='SQL*Net break/reset to client' ela= 10448 driver id=1650815232 break?=0 p3=0 obj#=4314004 tim=47159074346509 WAIT #4574893000: nam='SQL*Net message to client' ela= 4 driver id=1650815232 #bytes=1 p3=0 obj#=4314004 tim=47159074346570 |
從以上的10046 追蹤日誌基本可以檢視出報出 ora-08103 的過程,在此之前需先了解 CTAS 的過程。
CTAS 的過程解析:
在ORACLE 中 CTAS 的時候,建立的表的 BLOCK 首先被標誌為 TEMP , 等表全部建立完了再改為 其他型別,例如table 。 這樣當CTAS 出現問題的時候,不需要回退,只需要以後回收臨時段就可以了。
而這個過程中,所有物件的記錄便在基表seg$ 中,其中 type#=3 是臨時塊, type#=5 是 table 型別。在個正常的 CTAS 過程是在新建表時將新建表所要存放的塊先以型別是 3 插入到 seg$ 中(如果 seg$ 中已存在 type#=3 的便可繼續複用),之後完成了再 update 型別成 5 ,並且當一個 CTAS 語句正常結束時是不會有 type#=3 的塊存在的。如果是異常的 CTAS ,便透過 smon 來進行清理回收臨時段。
而在以上報錯的過程中,是先透過以下語句查詢seg$ 中 ts#=6,type#=3 的塊:
( select file#, block#, blocks from seg$ where type# = 3 and ts# = :1 ) ,而之後找到的塊是678 號檔案的 116881 號塊,這說明這個塊已經被記錄來用作臨時塊,但在讀取這個塊的卻報出了 ORA-08103 錯誤。由此,可以初步斷定,本次 ORA-08103 錯誤與 678 號檔案的 116881 號塊有關。
實際上, 在當時透過檔案號及塊號查詢出了該塊上的物件是一個已存在的普通表 ,即是說seg$ 中記錄 678 號檔案的 116881 號塊的型別是臨時塊,與實際情況不一致,因此導致了 ORA-08103 錯誤。這正符合以上的原因一。以下透過實驗可以重現該過程。
1.2 ORA-08103 錯誤模擬重現實驗
1. 建立一個測試表空間。
create tablespace cwdtest datafile '+DATA' size 1G autoextend on;
TABLESPACE_NAME SUM_MB FREE_MB USE_PRECENT ------------------------------ ---------- ---------- ----------- CWDTEST 1024 1023 .1 |
2. 查詢當前資料庫 seg$ 中 type#=3 的塊,正常情況下沒有,在 CTAS 的過程中才會出現。
3. 透過 10046 捕捉正常 CTAS 過程中的 insert into seg$ 語句,並將某個空塊手工以 type#=3 插入到 seg$ 中。(這裡主要模擬的是某些塊被定義為 seg$ 臨時塊後沒有及時更改);
SQL> insert into seg$ (file#,block#,type#,ts#,blocks,extents,minexts,maxexts,extsize,extpct,user#,iniexts,lists,groups,cachehint,hwmincr, spare1, scanhint, bitmapranges) values (86,2291642,3,53,8,1,1,2147483645,128,0,46,8,0,0,0,118552,DECODE(4194561,0,NULL,4194561),0,2147483645);
1 row created.
SQL> commit;
Commit complete.
SQL> select file#, block#, blocks from SYS.seg$ where type# = 3;
FILE# BLOCK# BLOCKS ---------- ---------- ---------- 86 2291642 8 |
4.
實際上該塊上目前還沒有資料:
5. 於是手工往這個表空上建立物件,並往表上擴充套件分割槽:
SQL> create table s (n number,c varchar2(4000)) nologging tablespace cwdtest;
Table created. SQL> BEGIN 2 FOR I IN 1 .. 100000000 LOOP EXECUTE IMMEDIATE 'alter table s allocate extent(size 1048576 datafile ''+DATA/cspadg/datafile/cwdtest.409.961946541'')'; END LOOP; END; 3 4 5 6 7 / |
6.
實際上在擴充套件分割槽的過程中已經報出了
ORA-08103
,此時這個塊已經被佔用。
7. 此時進行 CTAS 時也同樣報出了 ORA-08103 錯誤:
8 .實際上,此時將 seg$ 記錄的不一致的塊給刪除了,該問題就解決了。
透過以上實驗,可以確定,在CTAS 的過程中 oracle 根據 seg$ 表中 type#=3 的塊來左右臨時塊以建立新的物件,但當其實際中該塊被使用了的時候,此時便會報出了 ORA-08103 的錯誤。
1.3 總結
透過從以上分析,資料庫出現的ORA-08103 的問題是因為資料庫中 seg$ 記錄了臨時塊,其與實際塊的使用情況不一致,導致在該 OOO 使用者表空間進行 CTAS 操作時需要用到該塊做為臨時塊是便報出了 ORA-08103 錯誤。 S eg$ 記錄資訊出現異常可能是由於多次異常 CTAS 造成 seg$ 表中關於臨時塊的記錄未被及時更新而存留在 seg$ 表中導致。
建議處理方式如下:
1. 資料檔案使用非自動擴充套件方式並預先分配空間,已使在尋找臨時塊時發現不可用可繼續往下尋找而不報錯。
2. 更新seg$ 存留的異常記錄,刪除或更新型別與實際相同。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29863023/viewspace-2662449/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- go path 存在的問題Go
- 虛擬化存在的問題
- 問題:兩個物件值相同(x.equals(y) == true),但是可能存在hashCode不同嗎?物件
- 物件存在位置物件
- 是否存在JSON物件JSON物件
- IDC發展存在哪些問題?
- 遊戲是否存在價值問題?遊戲
- Redis儲存物件問題Redis物件
- 有關 socialiteproviders 存在的幾個問題IDE
- 密碼找回功能可能存在的問題密碼
- ClientAbortException 問題分析clientException
- 遊戲伺服器存在的主要問題遊戲伺服器
- Oracle 調優確定存在問題的SQLOracleSQL
- 解決godoc命令不存在的問題Go
- 最新vue-cli 2.9.1的webpack存在問題VueWeb
- 平臺化設計產品存在的問題
- 密碼找回功能可能存在的問題(補充)密碼
- 人工智慧存在的問題是什麼(三)人工智慧
- redis使用中存在的問題及如何避免(二)Redis
- redis使用中存在的問題及如何避免(一)Redis
- Spring框架問題分析Spring框架
- JVM 問題分析思路JVM
- HDFS Decommission問題分析
- Rabbimtmq unack問題分析MQ
- vue 克隆物件時遇到的問題Vue物件
- springboot @RequestBody bean 物件 為空問題Spring BootBean物件
- 02.Java物件導向問題Java物件
- vue 陣列和物件渲染問題Vue陣列物件
- 問答題:物件導向的思想物件
- javascript的物件問題及總結JavaScript物件
- 單例模式中可能存在的一些問題(執行緒安全問題)單例模式執行緒
- [20181122]模擬ORA-08103錯誤.txt
- JDK動態代理物件與被代理物件地址值問題JDK物件
- 關於物件繼承的問題——利用空物件做中介物件繼承
- 我們常常意識不到問題的存在,直到有人解決了這些問題
- 產品設計中,DFMEA存在的問題有哪些?
- 跨鏈橋的存在解決了什麼問題?
- 開放世界遊戲仍然存在的10個問題遊戲