5.3損壞回滾數據文件的恢復方法
回滾段表空間中的一個(gè)數據文件丟失或者損壞導致數據庫無(wú)法識別它,在啟動(dòng)數據庫的時(shí)候會(huì )出現ORA-1157, ORA-1110的錯誤,或者操作系統級別的錯誤,例如ORA-7360。在關(guān)閉數據庫的時(shí)候(normal或者immediate)會(huì )出現ORA-1116, ORA-1110的錯誤,或者操作系統級別的錯誤,例如ORA-7368。
感謝Coolyl的辛勤工作,關(guān)于回滾段的大部分內容都是摘自他在itpub的文章。
5.3.1損壞數據文件,但數據庫處于Open狀態(tài)
如果你發(fā)現有回滾段的數據文件丟失或者損壞了,而此時(shí)的數據庫是處于打開(kāi)的狀態(tài)下并且在運行,就千萬(wàn)不要關(guān)閉數據庫了,因為在大多數的情況下打開(kāi)的時(shí)候比關(guān)閉的時(shí)候好解決問(wèn)題一些。
一般也是存在有兩種情況:
A、是offline丟失或損壞的數據文件,然后從一個(gè)備份中恢復,執行介質(zhì)恢復以保持一致性。但是這種情況要求數據庫是歸檔方式下才可以采用的。
B、是offline那個(gè)存在丟失或損壞的數據文件所在的整個(gè)回滾段表空間,然后刪除整個(gè)回滾段表空間并重建,但是你必須要殺掉那些在回滾段中已經(jīng)激活的用戶(hù)進(jìn)程才可以offline的。
通常第一種情況就比較簡(jiǎn)單實(shí)現,但是更多的用戶(hù)事務(wù)將會(huì )出錯并且回滾。
A的具體步驟:
1、 offline丟失或損壞的數據文件
ALTER DATABASE DATAFILE '<full_path_file_name>' OFFLINE;
2、 從一個(gè)有效的備份中恢復。
3、 執行以下查詢(xún):
SELECT V1.GROUP#, MEMBER, SEQUENCE#
FROM V$LOG V1, V$LOGFILE V2
WHERE V1.GROUP# = V2.GROUP# ;
這個(gè)將列出你的所有redolog文件以及它們所代表的sequence numbers。
4、 恢復數據文件。
RECOVER DATAFILE '<full_path_file_name>'
5、 確信你應用了所有的redolog文件,直至出現提示信息"Media recovery complete"。
6、 online那個(gè)數據文件。
ALTER DATABASE DATAFILE '<full_path_file_name>' ONLINE;
B的具體步驟:
1、 offline存在丟失或損壞的數據文件的回滾段表空間中的所有回滾段。
ALTER ROLLBACK SEGMENT <rollback_segment> OFFLINE;
2、 檢測當然回滾段的狀態(tài)。
SELECT SEGMENT_NAME, STATUS FROM DBA_ROLLBACK_SEGS
WHERE TABLESPACE_NAME = '<TABLESPACE_NAME>';
3、 刪除所有offline的回滾段
DROP ROLLBACK SEGMENT <rollback_segment>;
4、 處理那些online狀態(tài)的回滾段。
重新執行第二步的查詢(xún)
如果你已經(jīng)執行過(guò)offline操作的回滾段狀態(tài)仍然是online,則說(shuō)明這個(gè)回滾段內有活動(dòng)的事務(wù)。你要接著(zhù)查詢(xún)
SELECT SEGMENT_NAME, XACTS ACTIVE_TX, V.STATUS
FROM V$ROLLSTAT V, DBA_ROLLBACK_SEGS
WHERE TABLESPACE_NAME = '<TABLESPACE_NAME>' AND SEGMENT_ID = USN;
如果沒(méi)有返回結果,則證明存在丟失或損壞的數據文件的回滾段表空間中的所有回滾段都已經(jīng)被offline了,然后重新執行第二步,第三步。如果查詢(xún)有結果返回,則狀態(tài)應該是"PENDING OFFLINE".接著(zhù)查看ACTIVE_TX列,如果值為0,則表明此回滾段中已經(jīng)沒(méi)有未處理的事務(wù)了,很快就會(huì )被offline的,然后等它offline后重新執行2,3步后跳至第六步。如果值大于0,則繼續到第五步。
5、 強制那些包含活動(dòng)事務(wù)的回滾段offline。
活動(dòng)的事務(wù)應該被提交或者回滾,執行下面的查詢(xún)看看哪些用戶(hù)占用了回滾段:
SELECT S.SID, S.SERIAL#, S.USERNAME, R.NAME "ROLLBACK"
FROM V$SESSION S, V$TRANSACTION T, V$ROLLNAME R
WHERE R.NAME IN ('<PENDING_ROLLBACK_1>', ... ,
'<PENDING_ROLLBACK_N>')
AND S.TADDR = T.ADDR AND T.XIDUSN = R.USN;
最好能直接聯(lián)系到那些user讓他們自己去回滾或者提交事務(wù),如果不能做到的話(huà),那就只能強制性的殺掉進(jìn)程了。
ALTER SYSTEM KILL SESSION '<SID>, <SERIAL#>';
殺掉進(jìn)程后再過(guò)一段時(shí)間后回滾段會(huì )自動(dòng)清除那些事務(wù),然后就可以回到第二步繼續查詢(xún)了。
6、 刪除回滾段。
DROP TABLESPACE <tablespace_name> INCLUDING CONTENTS;
7、 重建回滾段并online它們。
說(shuō)明:
1、數據庫如果是open狀態(tài),就可以直接在open狀態(tài)下解決問(wèn)題,沒(méi)有必要停下數據庫,增加down機時(shí)間;
2、不管上上面那種恢復方法都是正常性的恢復,不會(huì )引起數據的不一致或錯誤。
5.3.2數據庫關(guān)閉,但是數據文件中沒(méi)有活動(dòng)事務(wù)
這種情況下最簡(jiǎn)單的方法就是offline drop掉這個(gè)壞了的或者丟失的數據文件,然后以restricted模式打開(kāi)數據庫然后刪除并且重建包含損壞文件的回滾段表空間。
具體步驟如下:
1、 確定數據庫是正常的關(guān)閉的。方法是可以去查看alert文件,到最后看是否有如下信息:
"alter database dismount
Completed: alter database dismount"
如果有的話(huà),就證明數據庫是正常關(guān)閉的,否則就不能用這個(gè)方法去恢復。
2、 修改init參數文件,移去ROLLBACK_SEGMENTS中包含的損壞數據文件的回滾段表空間的回滾段,如果你不能確定哪些回滾段是壞的,簡(jiǎn)單的方法是你可以注釋掉整個(gè)ROLLBACK_SEGMENTS。
3、 以restricted模式去mount數據庫。
STARTUP RESTRICT MOUNT
4、 offline drop掉那個(gè)壞的數據文件
ALTER DATABASE DATAFILE '<full_path_file_name>' OFFLINE DROP;
5、 打開(kāi)數據庫
ALTER DATABASE OPEN
如果你看到如下信息"Statement processed",則跳到第7步,如果你看到ORA-604, ORA-376, and ORA-1110的錯誤信息,繼續第6步。
6、 正常的關(guān)閉數據庫,然后在init文件中注釋掉ROLLBACK_SEGMENTS,并加入隱含參數
_corrupted_rollback_segments = ( <rollback1>,...., <rollbackN> )
然后以restricted模式打開(kāi)數據庫
STARTUP RESTRICT
7、 刪除掉那個(gè)包含損壞文件的回滾段表空間。
DROP TABLESPACE <tablespace_name> INCLUDING CONTENTS;
8、 重建回滾段表空間,記得創(chuàng )建后要把回滾段都online。
9、 重新使數據庫對所有用戶(hù)可用。
ALTER SYSTEM DISABLE RESTRICTED SESSION;
10、然后正常關(guān)閉數據庫,修改init文件,如果開(kāi)始只是注釋掉了ROLLBACK_SEGMENTS的,就去掉注釋即可,如果加了隱含參數的,注釋掉它,并在ROLLBACK_SEGMENTS加入所有的回滾段。
11、正常啟動(dòng)數據庫:
Startup
說(shuō)明:
1、這種方法的前提條件是數據庫是正常關(guān)閉(不是abort)可用;
2、這種方法是正常方法,不會(huì )引起數據錯誤。
5.3.3數據庫關(guān)閉,數據文件中有活動(dòng)事務(wù),沒(méi)有可用備份。
一般造成這種原因的情況是采用了shutdown abort或其它原因異常關(guān)機(如斷電)導致的。
1、開(kāi)啟一個(gè)事務(wù)
SQL> set transaction use rollback segment rbs0;
Transaction set.
SQL> insert into test (a) values (1);
1 row created.
2、異常關(guān)閉
SQL> shutdown abort;
Oracle instance shut down.
3、刪除rbs的一個(gè)數據文件
C:>delD:\Oracle\oradata\chen\rbs01.
4、修改INIT<sid>.ora :
rollback_segments=(system)
添加_corrupted_rollback_segments=(rbs0,rbs1,rbs2……)
5、SQL>Startup mount
6、SQL>alter database datafile 'd:\Oracle\oradata\t8i\rbs01.dbf' offline drop;
數據庫已更改。
7、SQL>recover database;
完成介質(zhì)恢復。
8、SQL>alter database open ;
數據庫已更改。
9、SQL>select * from v$rollname;
USNNAME
---- -------
0 SYSTEM
10、SQL>select segment_name,tablespace_name,status
FROM dba_rollback_segs;
SEGMENT_NAME TABLESPACE_NAME STATUS
----------- ------ ------------------------------------
SYSTEM SYSTEM ONLINE
RBS0 RBS NEEDS RECOVERY
RBS1 RBS NEEDS RECOVERY
RBS2 RBS NEEDS RECOVERY
11、SQL>drop rollback segment rbs0;
重算段已丟棄。
SQL>drop rollback segment rbs1;
重算段已丟棄。
SQL>drop rollback segment rbs2;
重算段已丟棄。
12、SQL>select segment_name,tablespace_name,status
FROM dba_rollback_segs;
SEGMENT_NAME TABLESPACE_NAME STATUS
-------------------------------------
SYSTEM SYSTEM ONLINE
13、SQL>drop tablespace rbs including contents;
表空間已丟棄。
14、重建新的回滾表空間及回滾段,并聯(lián)機。
15、SQL>shutdown abort
16、再修改INIT<sid>.ora:
rollback_segments=(rbs0,rbs1,rbs2)
將_corrupted_rollback_segments=(rbs0,rbs1,rbs2)去掉。
17、SQL>startup
說(shuō)明:
1、這種辦法是萬(wàn)不得以的時(shí)候使用的方法,如果有備份,都建議從備份上進(jìn)行恢復;
2、這種方法恢復的數據庫,可能會(huì )引起數據庫的數據錯誤;
3、恢復成功以后,建議exp/imp數據,并重新分析檢查數據庫。
5.3.4數據庫關(guān)閉,數據文件中有活動(dòng)事務(wù),從備份恢復
1、從一個(gè)有效的備份中恢復損壞的數據文件。
2、mount數據庫。
3、執行以下查詢(xún):
SELECT FILE#, NAME, STATUS FROM V$DATAFILE;
如果發(fā)現要恢復的文件是offline狀態(tài)的話(huà),要先online它:
ALTER DATABASE DATAFILE '<full_path_file_name>' ONLINE;
4、執行以下查詢(xún)
SELECT V1.GROUP#, MEMBER, SEQUENCE#, FIRST_CHANGE#
FROM V$LOG V1, V$LOGFILE V2
WHERE V1.GROUP# = V2.GROUP# ;
這個(gè)將列出redlog文件所代表的sequence和first change numbers。
5、如果數據庫是非歸檔情況下,執行以下查詢(xún):
SELECT FILE#, CHANGE# FROM V$RECOVER_FILE;
如果CHANGE#大于最小的redolog文件的FIRST_CHANGE#,則數據文件可以被恢復,記得在應用日志的時(shí)候要把所有redolog文件全部應用一遍。
如果CHANGE#小于最小的redolog文件的FIRST_CHANGE#,則數據文件就不可以被恢復了,這時(shí)候你要從一個(gè)有效的全備份中去恢復數據庫了,如果沒(méi)有全備份的話(huà),那你就只能把數據庫強制打開(kāi)到一個(gè)不一致的狀態(tài)去exp出數據,然后重新建庫導入數據,因為這種方式的恢復Oracle是不推薦用戶(hù)自己做的,所以這里我就不詳細說(shuō)明了。
6、恢復數據文件:
RECOVER DATAFILE '<full_path_file_name>'
7、確信你應用了所有的redolog文件,直至出現提示信息"Media recovery complete"。
8、打開(kāi)數據庫。
說(shuō)明:
1、這種方法要求在歸檔有備份的方式下進(jìn)行,而且是建議方式;
2、這種方法不會(huì )導致數據庫的錯誤。
5.4損壞臨時(shí)數據文件的恢復方法
臨時(shí)數據文件的恢復是比較簡(jiǎn)單的,因為臨時(shí)文件中不涉及到其它的有用的數據,所以可以刪除后重建。
1、關(guān)閉數據庫:
SQL>shutdown immediate
2、刪除臨時(shí)數據文件,模擬媒體失??;
3、啟動(dòng)數據庫,檢測到文件錯誤;
聯(lián)系客服