一個特殊的ORA-00600: internal error code, arguments: [6302], [20], [], [], [], [], [], []

zhang41082發表於2019-02-18
系統出現ORA-00600錯誤,看看了TRACE檔案,發現是一個插入的SQL語句導致的,看看這個SQL沒有任何異常,而且第一次碰見這樣的問題,這種問題基本只有METALINK能夠解決,到METALINK上搜尋了一把,發現有三個相關的BUG。第一個說:corrupt index creating functional index from existing local index;第二個說:when creating index on table containing a NULL REF column;第三個說:ALTER TABLE MOVE corrupts an IOT (OERI:6302 or silent corruption)。三個都是DDL操作出現的問題,都跟我們的情況不一致,導致問題的這個SQL相關的表不是分割槽表,也不是IOT表,上面只有三個普通的索引,而且導致問題的不是建立索引,而是一個簡單的INSERT語句。但根據METALINK的相關BUG,覺得這個問題應該還是跟索引有關的,後來的結果也證明了這個猜測。[@more@]

仔細看看天書一樣的TRACE檔案,沒什麼大的發現,只是有一點跟之前見過的TRACE不一樣,開頭就有這樣兩行:
key1 (20): 7a 68 61 6e 67 34 31 30 38 32 32 40 31 36 33 2e 63 6f 6d 00
key2 (19): 7a 68 61 6e 67 34 31 30 38 32 32 40 31 36 33 2e 63 6f 6d
那麼既然是索引相關的問題,而且TRACE檔案中也有一個KEY的關鍵字,那麼上面這串數字應該就是索引的鍵值了,這個表上一共三個索引,一個是順序號,一個是EMAIL,另一個也是一串數字,那麼先把這串數字解出來吧(因為涉及到客戶資訊,所以上面的數字使用了偶自己的資訊代替),其實上面的數字就是ASCII值,那麼ORACLE中有函式可以用的,select UTL_RAW.CAST_TO_varchar2(replace('7a 68 61 6e 67 34 31 30 38 32 32 40 31 36 33 2e 63 6f 6d',' ','')) from dual,返回結果是一個EMAIL(返回的EMAIL使用偶自己的替代了),那麼就很明確的知道了是這個表上的EMAIL的一個索引的問題。上面的函式其實就是把空格去掉,然後轉換成VARCHAR2,得到的就是ASCII字元轉換過來的實際資訊了。

看看這個表的索引也很正常,而且也有新的資料新來,並且新的資料EMAIL欄位也是有值的,那就說明這個索引還在不停的更新中,索引是沒問題的。仔細看看上面的兩串數字,發現KEY1最後多了一個00,這就是這個問題的關鍵所在了。因為這個EMAIL是客戶透過WEB提交過來的,WEB中可能對這個欄位的校驗不嚴格導致這個特殊的控制字元被傳入到了資料庫中,而這個值更新到索引中的時候,就會報這個錯。為了驗證這個錯誤,可以反過來做一下,把UTL_RAW.CAST_TO_varchar2(replace('7a 68 61 6e 67 34 31 30 38 32 32 40 31 36 33 2e 63 6f 6d 00',' ',''))更新到任何一行的EMAIL欄位上,立馬錯誤重現。找到了根本,解決就比較簡單了,不過這個ASCII碼為00的特殊字元,客戶是怎麼弄進來的呢?

另外補充一點UTL_RAW的用法,這個包還有一個CAST_TO_RAW的函式,可以把字串轉化成RAW,這個特性可以應用在DBLINK中。
具體說就是如果資料庫之間的字符集不一致,可能導致透過DBLINK拉過來的中文出現亂碼,那麼可以在遠端建一個VIEW,把所有中文透過CAST_TO_RAW把字串轉換成RAW,然後資料拉過來後,再透過CAST_TO_VARCHAR2再還原出來,這樣就可以解決亂碼問題了。

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

相關文章