ORA-00600: 內部錯誤程式碼, 引數: [kdsgrp1] 解決案例
一日, 客戶的資料庫中表空間SYSAUX的AWR相關表出現了一個壞塊。通過truncate表(資料不重要),從備份中restore資料檔案,做完恢復之後壞塊修復。
資料庫OPEN之後,客戶業務出現錯誤。檢查告警日誌,出現了:
Errors in file /u01/app/Oracle/diag/rdbms/test/test/trace/test_ora_51465.trc (incident=279339):
ORA-00600: 內部錯誤程式碼, 引數: [kdsgrp1], [], [], [], [], [], [], [], [], [], [], []
Incident details in: /u01/app/oracle/diag/rdbms/test/test/incident/incdir_279339/test_ora_51465_i279339.trc
從trace中看出,某個SQL引發了這個錯誤。這個錯誤主要指對應索引ROWID,在資料表中找不到記錄,這表明出現了資料一致性問題。從trace檔案中獲得了引發錯誤的SQL,執行之,如下:
繼續看trace檔案, 可以定位到如下記錄
*** 2019-03-30 22:00:06.323
*** SESSION ID:(1802.759) 2019-03-30 22:00:06.323
*** CLIENT ID:() 2019-03-30 22:00:06.323
*** SERVICE NAME:(ysnc) 2019-03-30 22:00:06.323
*** MODULE NAME:(sqlservr.exe) 2019-03-30 22:00:06.323
*** ACTION NAME:() 2019-03-30 22:00:06.323
* kdsgrp1-1: *************************************************
row 0x030b33a7.0 continuation at
0x030b33a7.0 file# 12 block# 734119 slot 0 not found
KDSTABN_GET: 0 ..... ntab: 0
curSlot: 0 ..... nrows: 0
kdsgrp - dump CR block dba=0x030b33a7
Block header dump: 0x030b33a7
Object id on Block? Y
seg/obj: 0x29761 csc: 0x00.53475f8c itc: 2 flg: E typ: 1 - DATA
brn: 0 bdba: 0x30b3300 ver: 0x01 opc: 0
inc: 0 exflg: 0
從中,得到了資料檔案號12, 以及資料塊編號, 734119, 可以使用SQL定位出錯的物件
select owner,segment_name,segment_type from dba_extents where file_id= 12 and block_id<= 734119 and (block_id+blocks)>= 734119 ;
查詢到了物件之後,開始嘗試重建物件的索引。
重建時,出現了錯誤ORA-00600 13004。
只得通過drop索引,然後再create的辦法建立。
索引重建完成後,此SQL再次執行,沒有發生錯誤。
另外,此客戶的資料庫後來又發生了ORA-08103 Object no longer exists
查詢表時,已經發生錯誤,這裡就不可避免發生了資料丟失。
從MOS上查到了如下指令碼搶救資料:
REM Create a new table based on the table that is producing errors with no rows:
create table <使用者>.(表名>_20180331
as
select *
from <使用者>.(表名>
where 1=2;
REM Create the table to keep track of ROWIDs pointing to affected rows:
create table <使用者>.bad_rows (row_id rowid, oracle_error_code number);
set serveroutput on
DECLARE
TYPE RowIDTab IS TABLE OF ROWID INDEX BY BINARY_INTEGER;
CURSOR c1 IS select /*+ index_ffs(tab1 <索引名稱>) parallel(tab1) */ rowid
from <使用者>.(表名> tab1
where pk_flow is NOT NULL
order by rowid;
r RowIDTab;
rows NATURAL := 20000;
bad_rows number := 0 ;
errors number;
error_code number;
myrowid rowid;
BEGIN
OPEN c1;
LOOP
FETCH c1 BULK COLLECT INTO r LIMIT rows;
EXIT WHEN r.count=0;
BEGIN
FORALL i IN r.FIRST..r.LAST SAVE EXCEPTIONS
insert into <使用者>.(表名>_20180331
select /*+ ROWID(A) */ a.*
from <使用者>.(表名> A where rowid = r(i);
EXCEPTION
when OTHERS then
BEGIN
errors := SQL%BULK_EXCEPTIONS.COUNT;
FOR err1 IN 1..errors LOOP
error_code := SQL%BULK_EXCEPTIONS(err1).ERROR_CODE;
if error_code in (1410, 8103, 1578) then
myrowid := r(SQL%BULK_EXCEPTIONS(err1).ERROR_INDEX);
bad_rows := bad_rows + 1;
insert into <使用者>.bad_rows values(myrowid, error_code);
else
raise;
end if;
END LOOP;
END;
END;
commit;
END LOOP;
commit;
CLOSE c1;
dbms_output.put_line('Total Bad Rows: '||bad_rows);
END;
萬幸的是, 40多萬條資料最終只丟失了6條,收到影響的單據有兩個。業務通過補單據的方式挽回了資料。
Linux公社的RSS地址 : https://www.linuxidc.com/rssFeed.aspx
本文永久更新連結地址: https://www.linuxidc.com/Linux/2019-04/157970.htm