close

>>08/30 發生一件發生弔詭事情...有客戶反應要對某個表格做index 會發生ORA-08103

其實不難發現看字眼就覺得是....表格已經刪除了或者...跟錯user帳號...但是這件事情並不是這樣

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

####特別處理

 CREATE INDEX Jiade.jiade_tem_idex ON Jiade.jiade_tem 
(SEQNO, WO_CODE) TABLESPACE JIADE_DATA; 
CREATE INDEX TMSNAF.PRDRPTIT_INDEX_SW ON TMSNAF.PRODUCTION_DAILY_REPORT_ITEM 
* 
ERROR at line 1: 
ORA-08103: object no longer exists

<<以為是表格不存在....但是...

 

SQL> desc Jiade.jiade_tem
Name Null? Type 
----------------------------------------- -------- ---------------------------- 
REPORT_ITEM_ID NOT NULL VARCHAR2(32) 
REPORT_ID VARCHAR2(32) 
REPORT_CODE VARCHAR2(20) 
REPORT_SEQNO NUMBER 
WO_CODE VARCHAR2(20) 
SEQNO NUMBER 
OP_TYPE_CODE VARCHAR2(20) 
SUB_OP_TYPE_CODE VARCHAR2(20) 
DUTY_OP_TYPE_CODE VARCHAR2(20) 
QUESTION_CODE VARCHAR2(20) 
ACT_QTY NUMBER 
QTY NUMBER 
UNIT VARCHAR2(32) 

.

.

.

表結構是正常的.....表示表格內有一個壞塊造成原因

   >>在創建索引時候ORACLE會對表格每個塊去掃描,當掃描到有問題塊時候就會跳出並出錯ora-08103...

  >>所以這邊有嘗試使用SELECT COUNT(1)方式也是一樣結果 --COUNT也是全部掃描

 >>這邊有嘗試過很多方是來做但是都不行

      >>匯入匯出

      >>對表格做複製 CREATE TABLE XXX AS SELECT * FROM JIADE.JIADE_ITEM;

 

---------------------------------以下以原廠文件來解決也不行------------------------------------------------------------

以Oracle給的文檔來處理 ( Doc ID 8103.1 ) 

我運行以下結果 都不行解決我的問題,以下紅色為語句
>>analyze table JIADE.JIADE_ITEM validate structure cascade online; 
If this returns ORA-8103 
Flush the buffer cache. 
It might be a corruption only in the SGA memory (Buffer cache): 
>>alter session set events 'immediate trace name flush_cache level 1'; 
In a RAC system, flushing the buffer cache may be needed in the additional rac instances. 
If the error persists, continue with the next steps: 
Flush the shared pool. 
In some cases the problem can be caused by a cursor invalidation problem for which flushing the shared_pool can be a workaround: 
>>alter system flush shared_pool; 

 

>>>以下是Oracle透過跳開壞塊來insert into 到新表,但是也不行

SQL> create table REPORT_ITEM08 
as 
select * 
from PRODUCTION_DAILY_REPORT_ITEM 
where 1=2; 2 3 4 5 

Table created. 

SQL> create table bad_rows (row_id rowid, oracle_error_code number); 

set serveroutput on 
Table created. 

SQL> SQL> 
SQL> DECLARE 
2 TYPE RowIDTab IS TABLE OF ROWID INDEX BY BINARY_INTEGER; 
3 
4 CURSOR c1 IS select rowid 
5 from PRODUCTION_DAILY_REPORT_ITEM tab1 
6 order by rowid; 
7 
8 r RowIDTab; 
9 rows NATURAL := 20000; 
10 bad_rows number := 0 ; 
11 errors number; 
12 error_code number; 
13 myrowid rowid; 
14 BEGIN 
15 OPEN c1; 
16 LOOP 
17 FETCH c1 BULK COLLECT INTO r LIMIT rows; 
18 EXIT WHEN r.count=0; 
19 BEGIN 
20 FORALL i IN r.FIRST..r.LAST SAVE EXCEPTIONS 
21 insert into REPORT_ITEM08 
22 select /*+ ROWID(A) */ A.* 
23 from PRODUCTION_DAILY_REPORT_ITEM A where rowid = r(i); 
24 EXCEPTION 
25 when OTHERS then 
26 BEGIN 
27 errors := SQL%BULK_EXCEPTIONS.COUNT; 
FOR err1 IN 1..errors LOOP 
28 29 error_code := SQL%BULK_EXCEPTIONS(err1).ERROR_CODE; 
30 if error_code in (1410, 8103, 1578) then 
31 myrowid := r(SQL%BULK_EXCEPTIONS(err1).ERROR_INDEX); 
32 bad_rows := bad_rows + 1; 
33 insert into bad_rows values(myrowid, error_code); 
34 else 
35 raise; 
36 end if; 
37 END LOOP; 
38 END; 
39 END; 
40 commit; 
41 END LOOP; 
42 commit; 
43 CLOSE c1; 
44 dbms_output.put_line('Total Bad Rows: '||bad_rows); 
45 END; 
46 / 
DECLARE 
* 
ERROR at line 1: 
ORA-08103: object no longer exists 
ORA-06512: at line 17 

>>文件寫道透過跳過壞塊也不行

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

透過Oracle文章來用根本不行......我表上也沒索引可以使用...只能使用後續方式來解決

後續透過追蹤發現 有壞塊出現

alter session set max_dump_file_size=unlimited; 
alter session set db_file_multiblock_read_count=1; 
alter session set events 'immediate trace name trace_buffer_on level 1048576'; 
alter session set events '10200 trace name context forever, level 1'; 
alter session set events '8103 trace name errorstack level 3'; 
alter session set events '10236 trace name context forever, level 1'; 
alter session set tracefile_identifier='ORA8103'; 

run the query that produces the error ORA-8103 

alter session set events 'immediate trace name trace_buffer_off'; 
exit 

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

查看文件 紅圈處...發現 file=6 block=2207571  出現unknow情況

ktrget2(): started for block <0x0007 : 0x01a1af53> objd: 0x000258a1 <<<<<< 
env [0xfffffd7ffc7f96cc]: (scn: 0x0adb.9ad85beb xid: 0x0000.000.00000000 uba: 0x00000000.0000.00 statement num=0 parent xid: 0x0000.000.00000000 st-scn: 0x0000.00000000 hi-scn: 0x0000.00000000 ma-scn: 0x0adb.922f406e flg: 0x00000660) 
ktrexf(): returning 9 on: d06be90 cr-scn: 0xffff.ffffffff xid: 0x0000.000.00000000 uba: 0x00000000.0000.00 cl-scn: 0xffff.ffffffff sfl: 0 
KTRVAC: path typ=58, rdba=1a1af53 
KTRGET: pobj=0, dsobj=153761, dsd=1a1af53, sd=182ea20 

Dump of buffer cache at level 10 for tsn=7 rdba=27373395 
BH (0x12bfa2438) file#: 6 rdba: 0x01a1af53 (6/2207571) class: 1 ba: 0x12b5ee000 
set: 10 pool: 3 bsz: 8192 bsi: 0 sflg: 1 pwc: 0,19 
dbwrid: 0 obj: 153761 objn: 153761 tsn: 7 afn: 6 hint: f 
hash: [0x36517a0c0,0x36517a0c0] lru: [0xdbf8a0d0,0x141f3a440] 
lru-flags: hot_buffer 
ckptq: [NULL] fileq: [NULL] objq: [0x35fa11588,0x14fee7be8] objaq: [0x35fa11578,0x14fee7bf8] 
use: [NULL] wait: [NULL] fast-cr-pins: 1 
st: XCURRENT md: NULL fpin: 'ktswh72: ktsbget' tch: 196 
flags: 
LRBA: [0x0.0.0] LSCN: [0x0.0] HSCN: [0xffff.ffffffff] HSUB: [65535] 
buffer tsn: 7 rdba: 0x01a1af53 (6/2207571) 
scn: 0x0ada.6a5cf51e seq: 0x01 flg: 0x04 tail: 0xf51e3a01 
frmt: 0x02 chkval: 0x524e type: 0x3a=unknown <<<<<<< type: 0x3a=unknown 
Hex dump of block: st=0, typ_found=0 
Dump of memory from 0x000000012B5EE000 to 0x000000012B5F0000 
12B5EE000 0000A23A 01A1AF53 6A5CF51E 04010ADA [:...S.....\j....] 
12B5EE010 0000524E 00000000 00000000 00000000 [NR..............] 
12B5EE020 00000000 00000000 00000000 00000000 [................] 

 

---------------只能透過以下方式來將問題解決

>> 1.sqlplus user/passwd 
>> create table maob_error_info (A varchar2(4000)); 
>> create table JIADE.JIADE_ITEM_bak tablespace JIADE_DATA as select * from JIADE.JIADE_ITEM where 1=2;   >>建構表欄位


     2.run following script to extract normal data and insert backup table. 


DECLARE 
MY_ROWID ROWID; 
vs_error varchar2(200); 
vn_block_id number; 
cursor cur1 is select relative_fno,block_id, blocks from 
dba_extents where segment_name='JIADE_ITEM' and owner='JIADE' ;  
c_row cur1%rowtype; 

begin 
open cur1; 
loop 
fetch cur1 into c_row; 
exit when cur1%notfound; 

for j in 0 .. c_row.blocks-1 loop 
vn_block_id:=c_row.block_id+j; 

FOR i in 0..500 loop 
begin 

my_rowid := DBMS_ROWID.ROWID_CREATE(1, <issue table data_object_id>, c_row.relative_fno, vn_block_id, i); <<<<select data_object_id from dba_objects where object_name='<your issue table>'; 
--dbms_lock.sleep(10); 
insert into JIADE.JIADE_ITEM_bak select * from JIADE.JIADE_ITEM where rowid=my_rowid; 

commit; 
exception 
when others then 
vs_error:=substr(sqlerrm,1,30); 
insert into maob_error_info values(my_rowid||'Error info:'||vs_error||' FILE_NO='||c_row.relative_fno||' BLOCKID='||vn_block_id ||' rownum='||i); 

end; 
end loop; --FOR i in 0..1000 loop 
end loop; 
commit; 
end loop; 
end; 
/ 

3.rename issue table to other name. 
alter table JIADE.JIADE_ITEM RENAME TO JIADE_ERR

4.rename backup table to issue table name. 
ALTER TABLE JIADE.JIADE_ITEM_BAK RENAME TO JIADE.JIADE_ITEM

5.rebuild indexes. 

 

 

------以上解決問題.....但是一定會有數據毀損要有心理準備。

如果喜歡或有協助您解決 別忘了留言給點意見喔!!

 

 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 jiade_Chen 的頭像
    jiade_Chen

    assistant engineer

    jiade_Chen 發表在 痞客邦 留言(0) 人氣()