一次異常的ORA-01555故障解決

ORA-01555是一個很經典很常見的錯誤.產生的原因是你的查詢sql在構造CR的時候,發現undo中的CR塊被覆蓋了,就會產生ORA-01555.

一般的解決思路:

1.優化sql

2.加大undo表空間

3.加大undo_retention,加大undo的保留時間

但是我這次遇到的確不是上面的情況.

首先現象是,一個簡單的查詢,報錯ORA-01555,快照過舊:

 

Select * From 住院費用記錄 t Where t.病人id=1023738;

這個sql語句非常簡單,病人ID上面也有索引,但是一執行就會報錯ORA-01555.查詢alert日誌,如下:

Fri Oct 11 11:34:28 2019
ORA-01555 caused by SQL statement below (SQL ID: gmwgdkyndx34j, Query Duration=0 sec, SCN: 0x0001.95ad6c0e):
Select * From 住院費用記錄 Where 病人id = 1023733
Fri Oct 11 11:34:31 2019
ORA-00060: Deadlock detected. More info in file D:\APP\ADMINISTRATOR\diag\rdbms\orcl\orcl\trace\orcl_ora_9744.trc.
ORA-01555 caused by SQL statement below (SQL ID: gmwgdkyndx34j, Query Duration=0 sec, SCN: 0x0001.95ad6c99):
Select * From 住院費用記錄 Where 病人id = 1023733
Fri Oct 11 11:34:46 2019

這裏的執行時間爲0 sec.這裏明顯感覺不是因爲構造CR塊的時候undo被覆蓋導致的.懷疑可能是bug.於是搜索MOS,發現一篇文件正好一致:

IF: ORA-1555 Reported with Query Duration = 0 , or a Few Seconds (文檔 ID 1950577.1)

APPLIES TO:Oracle Database Cloud Service - Version N/A and later


Oracle Database - Standard Edition - Version 11.2.0.1 to 11.2.0.1 [Release 11.2]
Oracle Database Cloud Schema Service - Version N/A and later
Oracle Database Exadata Cloud Machine - Version N/A and later
Oracle Cloud Infrastructure - Database Service - Version N/A and later
Information in this document applies to any platform.

SYMPTOMS

a) An incorrect ORA-01555 error is reported with Query Duration=0

e.g

Error message in the alert Log / console will look similar to this:

Wed Jan 4 11:11:56 2014
ORA-01555 caused by SQL statement below (SQL ID: 1dnh4ypr7734w, Query Duration=0 sec, SCN: 0x0000.00be7c41):

OR


b) ORA-1555 with (extermely) small query duration reported in the error message. Eg:

ORA-01555 caused by SQL statement below (Query Duration=9 sec, SCN: 0x0001.8be5c8d1):

 

CAUSE

ORA-1555 with Query Duration 0 or a few seconds  is mainly caused by indexes/table mismatch  Or primary key index corruption.

Similar error is reported for flashback queries or queries involving dblinks.

 

這裏提到了,原因是索引/表不一致,或者主鍵索引壞塊.

結合現實環境,上面的sql語句走病人ID這個索引,於是嘗試做一個全表掃描的查詢,看是否報錯:

 

Select /*+ FULL(t) */ * From 住院費用記錄 t Where t.病人id=1023738;

發現正常.說明表是正常的,但是當通過索引訪問數據的時候出現報錯,那麼定位應該是這個索引有邏輯壞塊.

那麼解決辦法就很簡單了,只要重建索引就可以了.由於這個表很大,使用了在線併發重建索引:

alter index XXX rebuild online parallel 8;

別忘了關閉索引的併發度:

alter index XXX noparallel;

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章