5.3損壞回滾數(shù)據(jù)文件的恢復(fù)方法
回滾段表空間中的一個(gè)數(shù)據(jù)文件丟失或者損壞導(dǎo)致數(shù)據(jù)庫(kù)無(wú)法識(shí)別它,在啟動(dòng)數(shù)據(jù)庫(kù)的時(shí)候會(huì)出現(xiàn)ORA-1157, ORA-1110的錯(cuò)誤,或者操作系統(tǒng)級(jí)別的錯(cuò)誤,例如ORA-7360。在關(guān)閉數(shù)據(jù)庫(kù)的時(shí)候(normal或者immediate)會(huì)出現(xiàn)ORA-1116, ORA-1110的錯(cuò)誤,或者操作系統(tǒng)級(jí)別的錯(cuò)誤,例如ORA-7368。
感謝Coolyl的辛勤工作,關(guān)于回滾段的大部分內(nèi)容都是摘自他在itpub的文章。
5.3.1損壞數(shù)據(jù)文件,但數(shù)據(jù)庫(kù)處于Open狀態(tài)
如果你發(fā)現(xiàn)有回滾段的數(shù)據(jù)文件丟失或者損壞了,而此時(shí)的數(shù)據(jù)庫(kù)是處于打開(kāi)的狀態(tài)下并且在運(yùn)行,就千萬(wàn)不要關(guān)閉數(shù)據(jù)庫(kù)了,因?yàn)樵诖蠖鄶?shù)的情況下打開(kāi)的時(shí)候比關(guān)閉的時(shí)候好解決問(wèn)題一些。
一般也是存在有兩種情況:
A、是offline丟失或損壞的數(shù)據(jù)文件,然后從一個(gè)備份中恢復(fù),執(zhí)行介質(zhì)恢復(fù)以保持一致性。但是這種情況要求數(shù)據(jù)庫(kù)是歸檔方式下才可以采用的。
B、是offline那個(gè)存在丟失或損壞的數(shù)據(jù)文件所在的整個(gè)回滾段表空間,然后刪除整個(gè)回滾段表空間并重建,但是你必須要?dú)⒌裟切┰诨貪L段中已經(jīng)激活的用戶進(jìn)程才可以offline的。
通常第一種情況就比較簡(jiǎn)單實(shí)現(xiàn),但是更多的用戶事務(wù)將會(huì)出錯(cuò)并且回滾。
A的具體步驟:
1、 offline丟失或損壞的數(shù)據(jù)文件
ALTER DATABASE DATAFILE '<full_path_file_name>' OFFLINE;
2、 從一個(gè)有效的備份中恢復(fù)。
3、 執(zhí)行以下查詢:
SELECT V1.GROUP#, MEMBER, SEQUENCE#
FROM V$LOG V1, V$LOGFILE V2
WHERE V1.GROUP# = V2.GROUP# ;
這個(gè)將列出你的所有redolog文件以及它們所代表的sequence numbers。
4、 恢復(fù)數(shù)據(jù)文件。
RECOVER DATAFILE '<full_path_file_name>'
5、 確信你應(yīng)用了所有的redolog文件,直至出現(xiàn)提示信息"Media recovery complete"。
6、 online那個(gè)數(shù)據(jù)文件。
ALTER DATABASE DATAFILE '<full_path_file_name>' ONLINE;
B的具體步驟:
1、 offline存在丟失或損壞的數(shù)據(jù)文件的回滾段表空間中的所有回滾段。
ALTER ROLLBACK SEGMENT <rollback_segment> OFFLINE;
2、 檢測(cè)當(dāng)然回滾段的狀態(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)的回滾段。
重新執(zhí)行第二步的查詢
如果你已經(jīng)執(zhí)行過(guò)offline操作的回滾段狀態(tài)仍然是online,則說(shuō)明這個(gè)回滾段內(nèi)有活動(dòng)的事務(wù)。你要接著查詢
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)有返回結(jié)果,則證明存在丟失或損壞的數(shù)據(jù)文件的回滾段表空間中的所有回滾段都已經(jīng)被offline了,然后重新執(zhí)行第二步,第三步。如果查詢有結(jié)果返回,則狀態(tài)應(yīng)該是"PENDING OFFLINE".接著查看ACTIVE_TX列,如果值為0,則表明此回滾段中已經(jīng)沒(méi)有未處理的事務(wù)了,很快就會(huì)被offline的,然后等它offline后重新執(zhí)行2,3步后跳至第六步。如果值大于0,則繼續(xù)到第五步。
5、 強(qiáng)制那些包含活動(dòng)事務(wù)的回滾段offline。
活動(dòng)的事務(wù)應(yīng)該被提交或者回滾,執(zhí)行下面的查詢看看哪些用戶占用了回滾段:
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ù),如果不能做到的話,那就只能強(qiáng)制性的殺掉進(jìn)程了。
ALTER SYSTEM KILL SESSION '<SID>, <SERIAL#>';
殺掉進(jìn)程后再過(guò)一段時(shí)間后回滾段會(huì)自動(dòng)清除那些事務(wù),然后就可以回到第二步繼續(xù)查詢了。
6、 刪除回滾段。
DROP TABLESPACE <tablespace_name> INCLUDING CONTENTS;
7、 重建回滾段并online它們。
說(shuō)明:
1、數(shù)據(jù)庫(kù)如果是open狀態(tài),就可以直接在open狀態(tài)下解決問(wèn)題,沒(méi)有必要停下數(shù)據(jù)庫(kù),增加down機(jī)時(shí)間;
2、不管上上面那種恢復(fù)方法都是正常性的恢復(fù),不會(huì)引起數(shù)據(jù)的不一致或錯(cuò)誤。
5.3.2數(shù)據(jù)庫(kù)關(guān)閉,但是數(shù)據(jù)文件中沒(méi)有活動(dòng)事務(wù)
這種情況下最簡(jiǎn)單的方法就是offline drop掉這個(gè)壞了的或者丟失的數(shù)據(jù)文件,然后以restricted模式打開(kāi)數(shù)據(jù)庫(kù)然后刪除并且重建包含損壞文件的回滾段表空間。
具體步驟如下:
1、 確定數(shù)據(jù)庫(kù)是正常的關(guān)閉的。方法是可以去查看alert文件,到最后看是否有如下信息:
"alter database dismount
Completed: alter database dismount"
如果有的話,就證明數(shù)據(jù)庫(kù)是正常關(guān)閉的,否則就不能用這個(gè)方法去恢復(fù)。
2、 修改init參數(shù)文件,移去ROLLBACK_SEGMENTS中包含的損壞數(shù)據(jù)文件的回滾段表空間的回滾段,如果你不能確定哪些回滾段是壞的,簡(jiǎn)單的方法是你可以注釋掉整個(gè)ROLLBACK_SEGMENTS。
3、 以restricted模式去mount數(shù)據(jù)庫(kù)。
STARTUP RESTRICT MOUNT
4、 offline drop掉那個(gè)壞的數(shù)據(jù)文件
ALTER DATABASE DATAFILE '<full_path_file_name>' OFFLINE DROP;
5、 打開(kāi)數(shù)據(jù)庫(kù)
ALTER DATABASE OPEN
如果你看到如下信息"Statement processed",則跳到第7步,如果你看到ORA-604, ORA-376, and ORA-1110的錯(cuò)誤信息,繼續(xù)第6步。
6、 正常的關(guān)閉數(shù)據(jù)庫(kù),然后在init文件中注釋掉ROLLBACK_SEGMENTS,并加入隱含參數(shù)
_corrupted_rollback_segments = ( <rollback1>,...., <rollbackN> )
然后以restricted模式打開(kāi)數(shù)據(jù)庫(kù)
STARTUP RESTRICT
7、 刪除掉那個(gè)包含損壞文件的回滾段表空間。
DROP TABLESPACE <tablespace_name> INCLUDING CONTENTS;
8、 重建回滾段表空間,記得創(chuàng)建后要把回滾段都online。
9、 重新使數(shù)據(jù)庫(kù)對(duì)所有用戶可用。
ALTER SYSTEM DISABLE RESTRICTED SESSION;
10、然后正常關(guān)閉數(shù)據(jù)庫(kù),修改init文件,如果開(kāi)始只是注釋掉了ROLLBACK_SEGMENTS的,就去掉注釋即可,如果加了隱含參數(shù)的,注釋掉它,并在ROLLBACK_SEGMENTS加入所有的回滾段。
11、正常啟動(dòng)數(shù)據(jù)庫(kù):
Startup
說(shuō)明:
1、這種方法的前提條件是數(shù)據(jù)庫(kù)是正常關(guān)閉(不是abort)可用;
2、這種方法是正常方法,不會(huì)引起數(shù)據(jù)錯(cuò)誤。
5.3.3數(shù)據(jù)庫(kù)關(guān)閉,數(shù)據(jù)文件中有活動(dòng)事務(wù),沒(méi)有可用備份。
一般造成這種原因的情況是采用了shutdown abort或其它原因異常關(guān)機(jī)(如斷電)導(dǎo)致的。
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è)數(shù)據(jù)文件
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;
數(shù)據(jù)庫(kù)已更改。
7、SQL>recover database;
完成介質(zhì)恢復(fù)。
8、SQL>alter database open ;
數(shù)據(jù)庫(kù)已更改。
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)機(jī)。
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)行恢復(fù);
2、這種方法恢復(fù)的數(shù)據(jù)庫(kù),可能會(huì)引起數(shù)據(jù)庫(kù)的數(shù)據(jù)錯(cuò)誤;
3、恢復(fù)成功以后,建議exp/imp數(shù)據(jù),并重新分析檢查數(shù)據(jù)庫(kù)。
5.3.4數(shù)據(jù)庫(kù)關(guān)閉,數(shù)據(jù)文件中有活動(dòng)事務(wù),從備份恢復(fù)
1、從一個(gè)有效的備份中恢復(fù)損壞的數(shù)據(jù)文件。
2、mount數(shù)據(jù)庫(kù)。
3、執(zhí)行以下查詢:
SELECT FILE#, NAME, STATUS FROM V$DATAFILE;
如果發(fā)現(xiàn)要恢復(fù)的文件是offline狀態(tài)的話,要先online它:
ALTER DATABASE DATAFILE '<full_path_file_name>' ONLINE;
4、執(zhí)行以下查詢
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、如果數(shù)據(jù)庫(kù)是非歸檔情況下,執(zhí)行以下查詢:
SELECT FILE#, CHANGE# FROM V$RECOVER_FILE;
如果CHANGE#大于最小的redolog文件的FIRST_CHANGE#,則數(shù)據(jù)文件可以被恢復(fù),記得在應(yīng)用日志的時(shí)候要把所有redolog文件全部應(yīng)用一遍。
如果CHANGE#小于最小的redolog文件的FIRST_CHANGE#,則數(shù)據(jù)文件就不可以被恢復(fù)了,這時(shí)候你要從一個(gè)有效的全備份中去恢復(fù)數(shù)據(jù)庫(kù)了,如果沒(méi)有全備份的話,那你就只能把數(shù)據(jù)庫(kù)強(qiáng)制打開(kāi)到一個(gè)不一致的狀態(tài)去exp出數(shù)據(jù),然后重新建庫(kù)導(dǎo)入數(shù)據(jù),因?yàn)檫@種方式的恢復(fù)Oracle是不推薦用戶自己做的,所以這里我就不詳細(xì)說(shuō)明了。
6、恢復(fù)數(shù)據(jù)文件:
RECOVER DATAFILE '<full_path_file_name>'
7、確信你應(yīng)用了所有的redolog文件,直至出現(xiàn)提示信息"Media recovery complete"。
8、打開(kāi)數(shù)據(jù)庫(kù)。
說(shuō)明:
1、這種方法要求在歸檔有備份的方式下進(jìn)行,而且是建議方式;
2、這種方法不會(huì)導(dǎo)致數(shù)據(jù)庫(kù)的錯(cuò)誤。
5.4損壞臨時(shí)數(shù)據(jù)文件的恢復(fù)方法
臨時(shí)數(shù)據(jù)文件的恢復(fù)是比較簡(jiǎn)單的,因?yàn)榕R時(shí)文件中不涉及到其它的有用的數(shù)據(jù),所以可以刪除后重建。
1、關(guān)閉數(shù)據(jù)庫(kù):
SQL>shutdown immediate
2、刪除臨時(shí)數(shù)據(jù)文件,模擬媒體失??;
3、啟動(dòng)數(shù)據(jù)庫(kù),檢測(cè)到文件錯(cuò)誤;
聯(lián)系客服