對於資料庫管理員來說,文件的管理是非常重要的,因此對於文件的刪除作業一定要萬分小心,在windows下面刪除是會報文件在使用無法刪除,而linux下如果profile文件沒有配置rm刪除確認,那么直接下rm命令就會刪除,這樣的風險很大,因此最好是能在profile中設定rm刪除的確認(alias rm='rm -i';alias mv='mv -i';)
但是,怎么做也可能出現萬一,那么萬一出現了無刪除數據文件怎么辦?那么我們分幾種文件來討論:(下面的文章全部以Linux為基礎)
1. 臨時文件(temp01.dbf等):誤刪除后對系統沒有影響,可以直接alter tablespace來drop掉,然後新增幾個臨時文件就OK;
2. 回滾表空間文件(undotbs01.dbf等):如果裡面不包含需要recover的段,則可以直接drop掉,新建就OK。如包含了需要recover的段,則需要在參數文件中增加隱含參數來開啟數據庫,并刪除舊的回滾段并重建(在後面會詳細講到);
3. 普通數據文件(user01.dbf,log_data01.dbf等):可直接拷貝standby的相應文件,并正常關閉數據庫,開啟時做datafile recover(需保證歸檔文件連續),如果沒有備份,則只能drop掉文件,承受這數據的損失;
4. 關鍵系統文件(system01.dbf等):因system表空間中包含了整個數據庫最核心的東西,如系統包、數據字典等等。如果該文件被刪除,則數據庫關閉后100%無法啟動。因此需要從備份庫拷貝相應的文件及歸檔文件,并重啟數據庫在mount模式下做recover;如沒有備份或者歸檔文件不連續,且原system文件的磁盤又被其他文件複寫,那么整個數據庫就基本沒有辦法挽救。
其他文件的誤刪除還是有很多辦法解決,而且基本不會導致系統無法開啟,因此下面我主要就linux下system01.dbf文件被誤刪來進行一個解決過程的總結:
當誤刪除動作發生后,不能緊張,關閉監聽并通知管理員關閉AP系統,且避免system01.dbf文件所在磁盤有文件創建,以免覆蓋system01文件所在位置,那樣將無法恢復。在確保以上事情沒出現時,進行下面操作:
1. 執行ps –ef |grep SID,找到DBWR進程的pid號
2. 根據查找到的PID號,到對應的/proc/PID/fd目錄中,使用ls –alh查看
找到對應的system01文件,如有誤刪除則會在文件后加(deleted)標記
1. 到此就發現了system01文件的編號,那么要找到就要使用cat /proc/PID/fd/19 > /u01/system01.dbf,這裡要尤其注意,不要將cat出來的system01文件放在原system01同磁盤上,如原來的在raid1上,則cat出來的要放在raid5上
2. 拷貝cat出來的文件到原路徑中
3. 關閉資料庫,一般使用shutdown immediate是無法關閉的,需要使用shutdown abort來關閉
4. 開啟資料庫,使用startup mount命令將資料庫開啟到mount狀態,然後recover datafile 1(1代表的是system01在oracle中的文件編號);等recover成功完成直接open就恢復完成。
5. 如果刪除了較長時間,那么在第六步,可能在recover的時候會出現redo 不一致的錯誤時,則需要看recover到哪個歸檔的時候出現了這個錯誤。然後關閉數據庫,重新copy 恢復出來的system01文件覆蓋剛剛recover出錯的,再startup mount開啟到mount狀態,使用recover database until time '2004-04-22 10:05:00'(時間可設定在recover出錯之前)進行不完全恢復,然後使用alter database open resetlogs;來強行重置文件頭及數據庫,如開啟沒有問題則恢復完成,建議立即進行全庫導出或者建立standby。
6. 在第七步中,如過open resetlogs出錯,則需要加入隱含參數_allow_resetlogs_ corruption=true來強行開啟資料庫。因關閉資料庫的時候使用的是shutdown abort,那么有可能存在回滾段需要recover的情況,這個時候有可能會報回滾段錯誤,那么就需要刪除原undo空間,重新創建一個undo,步驟為:
1) 設置*.undo_management='MANUAL'
2) 指定回滾空間為system,*.undo_tablespace=’system’
3) 設置隱含參數_corrupted_rollback_segments=(_SYSSMU1$,_SYSSMU2$, _SYSSMU3$,_SYSSMU4$,_SYSSMU5$,_SYSSMU6$,_SYSSMU7$,_SYSSMU8$,_SYSSMU9$,_SYSSMU10$,_SYSSMU11$) 及_offline_rollback_ segments=true
4) 開啟資料庫,然後drop tablespace xxx including contents and datafiles;并新建undotbs2的undo空間
5) 去掉隱含參數,并修改undo_management為auto,undo_tablespace為undotbs2,開啟數據庫ok。
7. 如果還遇到數據庫smon進程在清理表空間臨時段出錯,并在報錯100次后自動關閉數據庫,則需要加入event='10061 trace name context forever, level 10'事件來屏蔽smon進程對表空間臨時段的清理,然後開啟數據庫就不會報錯,但是表空間中的臨時段的清理工作將會停止,使用Select * from dba_segments where segment_type='TEMPORARY'能查到有哪些表空間臨時段沒有清理,会发现这样类似AA.BBBBB的临时段,这是Oracle在创建数据(或索引)段过程中生成的临时段,由于创建过程因某种原因(用户中断或空间不够大)失败而造成的。段名中的AA为数据文件的file_id,BBBBB为数据块的block_id。可用以下方法清除(只要这个段没有被锁住):
alter session set events 'immediate trace name DROP_SEGMENTS level TS#+1'
其中 TS# = TS$.TS#
如果想清除所有表空间的临时段,则
TS# = 2147483647
然後關閉數據庫,屏蔽添加的event,正常開啟就ok。如不使用清理,也可將改block上的表move到別的表空間,然後直接屏蔽event,重啟數據庫。
8. 最後屏蔽所有添加的隱含參數,到此,文件誤刪除的恢復就完成了。
最後,建議立即建立standby,并測試激活standby是否可用且正常,有可能的話也立即進行全庫導出。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/110321/viewspace-607673/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/110321/viewspace-607673/