UNDO表空間損壞的處理

charsi發表於2012-06-15

一個半生產的Oracle資料庫.資料庫版本Oracle9.2.0.8
資料庫為非歸檔模式執行.

因為要處理的資料量較大,所以在週五臨下班前,在後臺執行了兩個個大資料量的insert插入指令碼。
結果週一來的時候,發現那個指令碼還沒有執行完成.

於是kill作業系統程式,kill Oracle session.然後從v$session中看到session的狀態變為KILLED之後,又在作業系統層面上kill資料庫的使用者程式.
然後看到資料庫的UNDO一直沒有釋放,就想直接重啟資料庫得了.使用shudown immediate等了很久沒停下來,這時候資料庫已經處於HANG的狀態,於是直接shudown abort。
後來的結果證明這種處理方式簡單粗暴,結果是引發了更大麻煩.

再啟動資料庫之後,UNDO仍然沒有釋放.
select sid,seq#,event from v$sesion_wait;
看到的部分內容如下:
19 7820 db file sequential read
28 7531 db file sequential read
27 7920 db file sequential read
20 7705 db file sequential read
23 10569 db file sequential read
24 7433 db file sequential read
25 7577 db file sequential read
12 1624 wait for stopper event to be increased SMON session
21 1626 wait for a undo record P001 session

也就是說,這時候是由於一個大的事務回滾,回滾量較大,達到一個閾值,SMON就會使用併發程式來處理。這時候查詢v$px_session也可以看到SMON產生了6個併發程式在處理。
在網上找了一個方法,修改fast_start_parallel_rollback引數由預設值LOW改為false,即不使用併發處理回滾.

這時候使用shutdown immediate停止資料庫都特別慢,所以我都使用shutdown abort的方式.
alter system set fast_start_parallel_rollback = false;
重啟資料庫.

但是問題還是解決不了.這時候smon的等待事件變成了db file sequential read
而UNDO表空間的空間一直不能得到釋放.
在alert日誌中出現了下面的資訊:

SMON: mark undo segment 1 as available
SMON: about to recover undo segment 2
SMON: mark undo segment 2 as available
SMON: about to recover undo segment 1
SMON: mark undo segment 1 as available
SMON: about to recover undo segment 2
SMON: mark undo segment 2 as available
SMON: about to recover undo segment 1
SMON: mark undo segment 1 as available
SMON: about to recover undo segment 2
SMON: mark undo segment 2 as available
SMON: about to recover undo segment 1
SMON: mark undo segment 1 as available
SMON: about to recover undo segment 2
SMON: mark undo segment 2 as available
SMON: about to recover undo segment 1
SMON: mark undo segment 1 as available
SMON: about to recover undo segment 2

檢視dba_rollback_segs檢視,也看到有有幾個回滾段的狀態為PARTLY AVAILABLE
從這些資訊來看,說明回滾段中的內容已經有部分被損壞了。
原因在於資料庫是處於非歸檔模式,而在回滾事務的過程中執行了好幾次的shutdown abort操作。

沒辦法,只能刪除現有的UNDO表空間然後重建UNDO表空間.
create undo tablespace UNDO1 datafile '/xxxx/yyyy/zzz/undo01.dbf' size 10240M reuse autoextend off;
alter system set undo_tablespace=UNDO1;
alter tablespace UNDO offline;


這時候問題來了。
當我將UNDO表空間offline之後,原來做的大事務操作insert的表就有問題了。當我全表掃描的時候,它會提示找不到資料檔案(offline的那個表空間的資料檔案).
這個應該也好理解,因為回滾段中需要回滾的資料正好是那個表中的資料。
解決這個問題,只能將UNDO表空間online之後,重組那幾個表。

確認資料庫中所有的表都沒有問題之後,刪除UNDO表空間.
出現的錯誤是
SQL> drop tablespace UNDO ;
drop tablespace UNDO
*
ERROR at line 1:
ORA-01548: active rollback segment '_SYSSMU1$' found, terminate dropping
tablespace

這種情況下,只能使用下面的方法刪除UNDO表空間:
1.建立pfile
create pfile="/xxxx/yyyy/initSID.ora" from spfile;
2.修改pfile,增加_corrupted_rollback_segments引數
_corrupted_rollback_segments=(_SYSSMU1$,_SYSSMU2$)
這裡面的_SYSSMU1$,_SYSSMU2$是我從dba_rollback_segs中看到狀態為PARTLY AVAILABLE的段名
3.使用這個引數啟動資料庫
startup pfile="/xxxx/yyyy/initSID.ora"
4.刪除UNDO表空間
drop tablespace UNDO including contents and datafiles;
5.重啟資料庫。
這次使用原來的spfile啟動即可。

這樣,這次出現的問題終於得到了解決。

通過這次事件,告訴我們:
1.資料庫使用非歸檔模式確實是不安全的;
2.處理問題一定得慎用簡單粗暴的方式
3.處理問題的時候一定要非常清楚這一步操作的用處和用途。切忌病急亂投醫,否則問題可能越來越麻煩。

最後慶幸一下,幸虧這個資料庫不是很重要。

[@more@]

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

相關文章