Decode360's Blog

          業(yè)精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
            302 隨筆 :: 26 文章 :: 82 評論 :: 0 Trackbacks
          損壞回滾數(shù)據(jù)文件的恢復(fù)方法
          ?
          ?

          回滾段表空間中的一個數(shù)據(jù)文件丟失或者損壞導(dǎo)致數(shù)據(jù)庫無法識別它,在啟動數(shù)據(jù)庫的時候會出現(xiàn)ORA-1157, ORA-1110的錯誤,或者操作系統(tǒng)級別的錯誤,例如ORA-7360。
          在關(guān)閉數(shù)據(jù)庫的時候(normal或者immediate)會出現(xiàn)ORA-1116, ORA-1110的錯誤,或者操作系統(tǒng)級別的錯誤,例如ORA-7368。
          感謝coolyl的辛勤工作,關(guān)于回滾段的大部分內(nèi)容都是摘自他在itpub的文章。
          ?

          1.損壞數(shù)據(jù)文件,但數(shù)據(jù)庫處于Open狀態(tài)
          ?
          如果你發(fā)現(xiàn)有回滾段的數(shù)據(jù)文件丟失或者損壞了,而此時的數(shù)據(jù)庫是處于打開的狀態(tài)下并且在運行,就千萬不要關(guān)閉數(shù)據(jù)庫了,因為在大多數(shù)的情況下打開的時候比關(guān)閉的時候好解決問題一些。
          一般也是存在有兩種情況:
          Aoffline丟失或損壞的數(shù)據(jù)文件,然后從一個備份中恢復(fù),執(zhí)行介質(zhì)恢復(fù)以保持一致性。但是這種情況要求數(shù)據(jù)庫是歸檔方式下才可以采用的。
          B、offline那個存在丟失或損壞的數(shù)據(jù)文件所在的整個回滾段表空間,然后刪除整個回滾段表空間并重建,但是你必須要殺掉那些在回滾段中已經(jīng)激活的用戶進程才可以offline的。

          通常第一種情況就比較簡單實現(xiàn),但是更多的用戶事務(wù)將會出錯并且回滾。

          A的具體步驟:

          1、offline丟失或損壞的數(shù)據(jù)文件

          SQL> ALTER DATABASE DATAFILE '<full_path_file_name>' OFFLINE;

          2、從一個有效的備份中恢復(fù)

          3、執(zhí)行以下查詢

          SELECT V1.GROUP#, MEMBER, SEQUENCE#?
          ? FROM V$LOG V1, V$LOGFILE V2?
          ?WHERE V1.GROUP# = V2.GROUP#;

          這個將列出你的所有redolog文件以及它們所代表的sequence numbers

          4、恢復(fù)數(shù)據(jù)文件

          SQL> RECOVER DATAFILE '<full_path_file_name>';

          5、確信你應(yīng)用了所有的redolog文件,直至出現(xiàn)提示信息Media recovery complete”

          6、online那個數(shù)據(jù)文件

          SQL> ALTER DATABASE DATAFILE '<full_path_file_name>' ONLINE;

          ?
          B的具體步驟:
          1、offline存在丟失或損壞的數(shù)據(jù)文件的回滾段表空間中的所有回滾段
          SQL> ALTER ROLLBACK SEGMENT?'<rollback_segment>' OFFLINE;
          2、檢測當然回滾段的狀態(tài)

          SELECT SEGMENT_NAME, STATUS FROM DBA_ROLLBACK_SEGS?
          ?WHERE TABLESPACE_NAME = '<TABLESPACE_NAME>';

          3、刪除所有offline的回滾段

          SQL> DROP ROLLBACK SEGMENT <rollback_segment>;

          4、處理那些online狀態(tài)的回滾段

          重新執(zhí)行第二步的查詢
          SELECT SEGMENT_NAME, STATUS FROM DBA_ROLLBACK_SEGS?
          ?WHERE TABLESPACE_NAME = '<TABLESPACE_NAME>';

          如果你已經(jīng)執(zhí)行過offline操作的回滾段狀態(tài)仍然是online,則說明這個回滾段內(nèi)有活動的事務(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;

          如果沒有返回結(jié)果,則證明存在丟失或損壞的數(shù)據(jù)文件的回滾段表空間中的所有回滾段都已經(jīng)被offline了,然后重新執(zhí)行第2步,第3步。
          ?
          如果查詢有結(jié)果返回,則狀態(tài)應(yīng)該是“PENDING OFFLINE”,接著查看ACTIVE_TX列,如果值為0,則表明此回滾段中已經(jīng)沒有未處理的事務(wù)了,很快就會被offline的,然后等它offline后重新執(zhí)行2,3步后跳至第6步;如果值大于0,則繼續(xù)到第五步。

          5、強制那些包含活動事務(wù)的回滾段offline

          活動的事務(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ù),如果不能做到的話,那就只能強制性的殺掉進程了。

          ALTER SYSTEM KILL SESSION '<SID>, <SERIAL#>';
          殺掉進程后再過一段時間后回滾段會自動清除那些事務(wù),然后就可以回到第二步繼續(xù)查詢了。

          6、刪除回滾段

          SQL> DROP TABLESPACE <tablespace_name> INCLUDING CONTENTS;

          7、重建回滾段并online它們
          ?

          說明:
          1、數(shù)據(jù)庫如果是open狀態(tài),就可以直接在open狀態(tài)下解決問題,沒有必要停下數(shù)據(jù)庫,增加down機時間
          2、不管上上面那種恢復(fù)方法都是正常性的恢復(fù),不會引起數(shù)據(jù)的不一致或錯誤。
          ?
          ?
          2.數(shù)據(jù)庫關(guān)閉,但是數(shù)據(jù)文件中沒有活動事務(wù)

          這種情況下最簡單的方法就是offline drop掉這個壞了的或者丟失的數(shù)據(jù)文件,然后以restricted模式打開數(shù)據(jù)庫然后刪除并且重建包含損壞文件的回滾段表空間。
          具體步驟如下:
          1、確定數(shù)據(jù)庫是正常的關(guān)閉的。方法是可以去查看alert文件,到最后看是否有如下信息:

          alter database dismount
          Completed: alter database dismount

          如果有的話,就證明數(shù)據(jù)庫是正常關(guān)閉的,否則就不能用這個方法去恢復(fù)。
          2、修改init參數(shù)文件,移去ROLLBACK_SEGMENTS中包含的損壞數(shù)據(jù)文件的回滾段表空間的回滾段
          ?
          如果你不能確定哪些回滾段是壞的,簡單的方法是你可以注釋掉整個ROLLBACK_SEGMENTS

          3、以restricted模式去mount數(shù)據(jù)庫

          SQL> STARTUP RESTRICT MOUNT;

          4、offline drop掉那個壞的數(shù)據(jù)文件

          SQL> ALTER DATABASE DATAFILE '<full_path_file_name>' OFFLINE DROP;

          5、打開數(shù)據(jù)庫

          SQL> ALTER DATABASE OPEN;

          如果你看到如下信息“Statement processed”,則跳到第7步,如果你看到ORA-604, ORA-376, and ORA-1110的錯誤信息,繼續(xù)第6步。

          6、正常的關(guān)閉數(shù)據(jù)庫,然后在init文件中注釋掉ROLLBACK_SEGMENTS,并加入隱含參數(shù)

          _corrupted_rollback_segments = ( <rollback1>,...., <rollbackN> )

          然后以restricted模式打開數(shù)據(jù)庫

          SQL> STARTUP RESTRICT

          7、刪除掉那個包含損壞文件的回滾段表空間

          DROP TABLESPACE <tablespace_name> INCLUDING CONTENTS;

          8、重建回滾段表空間,記得創(chuàng)建后要把回滾段都online

          9、重新使數(shù)據(jù)庫對所有用戶可用

          SQL> ALTER SYSTEM DISABLE RESTRICTED SESSION;

          10、然后正常關(guān)閉數(shù)據(jù)庫,修改init文件
          ?
          如果開始只是注釋掉了ROLLBACK_SEGMENTS的,就去掉注釋即可,如果加了隱含參數(shù)的,注釋掉它,并在ROLLBACK_SEGMENTS加入所有的回滾段。
          11、正常啟動數(shù)據(jù)庫

          SQL> Startup;
          ?

          說明:

          1、這種方法的前提條件是數(shù)據(jù)庫是正常關(guān)閉(不是abort)可用
          2、這種方法是正常方法,不會引起數(shù)據(jù)錯誤
          ?

          3.數(shù)據(jù)庫關(guān)閉,數(shù)據(jù)文件中有活動事務(wù),沒有可用備份

          一般造成這種原因的情況是采用了shutdown abort或其它原因異常關(guān)機(如斷電)導(dǎo)致的

          1、開啟一個事務(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的一個數(shù)據(jù)文件

          C:>del D:\oracle\oradata\dodo\UNDOTBS01.DBF

          4、修改INIT<sid>.ora

          rollback_segments=(system)
          添加_corrupted_rollback_segments=(rbs0,rbs1,rbs2……)

          5、SQL>Startup mount

          6、Drop掉表空間
          ?
          SQL>alter database datafile?'D:\oracle\oradata\dodo\UNDOTBS01.DBF' offline drop;
          Database altered.

          7、SQL>recover database;

          8、SQL>alter database open;
          Database altered.

          9、SQL>select * from v$rollname;

          ?????? USN NAME
          ---------- ------------------------------
          ???????? 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、Drop segment
          ?
          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
          ?
          ?
          說明:

          1、這種辦法是萬不得以的時候使用的方法,如果有備份,都建議從備份上進行恢復(fù)
          2、這種方法恢復(fù)的數(shù)據(jù)庫,可能會引起數(shù)據(jù)庫的數(shù)據(jù)錯誤
          3、恢復(fù)成功以后,建議exp/imp數(shù)據(jù),并重新分析檢查數(shù)據(jù)庫
          ?

          4.數(shù)據(jù)庫關(guān)閉,數(shù)據(jù)文件中有活動事務(wù),從備份恢復(fù)

          1、從一個有效的備份中恢復(fù)損壞的數(shù)據(jù)文件

          2、mount數(shù)據(jù)庫

          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# ;

          這個將列出redlog文件所代表的sequence和first change numbers

          5、如果數(shù)據(jù)庫是非歸檔情況下,執(zhí)行以下查詢:

          SELECT FILE#, CHANGE# FROM V$RECOVER_FILE;
          如果CHANGE#大于最小的redolog文件的FIRST_CHANGE#,則數(shù)據(jù)文件可以被恢復(fù),記得在應(yīng)用日志的時候要把所有redolog文件全部應(yīng)用一遍。
          如果CHANGE#小于最小的redolog文件的FIRST_CHANGE#,則數(shù)據(jù)文件就不可以被恢復(fù)了,這時候你要從一個有效的全備份中去恢復(fù)數(shù)據(jù)庫了,如果沒有全備份的話,那你就只能把數(shù)據(jù)庫強制打開到一個不一致的狀態(tài)去exp出數(shù)據(jù),然后重新建庫導(dǎo)入數(shù)據(jù),因為這種方式的恢復(fù)oracle是不推薦用戶自己做的,所以這里我就不詳細說明了。
          6、恢復(fù)數(shù)據(jù)文件

          RECOVER DATAFILE '<full_path_file_name>'?;

          7、確信你應(yīng)用了所有的redolog文件,直至出現(xiàn)提示信息“Media recovery complete”

          8、打開數(shù)據(jù)庫
          ?

          說明:

          1、這種方法要求在歸檔有備份的方式下進行,而且是建議方式
          2、這種方法不會導(dǎo)致數(shù)據(jù)庫的錯誤




          -The End-

          posted on 2008-12-20 23:31 decode360-3 閱讀(201) 評論(0)  編輯  收藏 所屬分類: DBA
          主站蜘蛛池模板: 来安县| 丹东市| 潜山县| 且末县| 资中县| 阿克陶县| 兴安盟| 新宾| 鄱阳县| 五河县| 弥渡县| 东港市| 霍山县| 龙里县| 平和县| 丰都县| 建平县| 新蔡县| 浏阳市| 伽师县| 托里县| 淮阳县| 双桥区| 来宾市| 紫阳县| 资阳市| 旺苍县| 永德县| 连南| 当雄县| 汾阳市| 墨玉县| 佛坪县| 娄底市| 应城市| 蚌埠市| 新乡市| 新竹市| 德州市| 仙居县| 云龙县|