1. 程式人生 > >第四章:手工不完全恢復

第四章:手工不完全恢復

一般是資料庫啟動不起來的,所以是在mount下進行

4.1 不完全恢復的特點:     

      1)讓整個database 回到過去某個時間點,不能避免資料丟失。

      2)想跳過壞日誌而繼續恢復所有其他工作是不可能的,前滾沒有這個功能(考點)。

      3)必須以sysdba身份連線進行不完全恢復,普通使用者或sysoper都不行(考點)。

      4)語句只有recover databaseuntil 這種形式,表示整個資料庫回到某個時間點或SCN,而until是指恢復在指定時間點停止,而非到那個指定時間點(考點)。

4.2 不完全恢復(Incompleterecover) 適用環境:

       1)在過去的某個時間點重要的資料被破壞。

       2)在做完全恢復時,丟失了歸檔日誌或當前onlineredo log(考點)

       3)當誤刪除了表空間時(需要舊的控制檔案備份)

       4)丟失了所有的控制檔案,使用備份的控制檔案恢復時  (條件滿足時可以完全恢復)     

4.3 不完全恢復的基本型別:

      1)基於時間點 (until time):   使整個資料庫恢復到過去的一個時間點前  

      2)基於scn (until change):   使整個資料庫恢復到過去的某個SCN前

      2)基於cancel (untilcancel):   使整個資料庫恢復到歸檔日誌或當前日誌的斷點前

      3)基於誤刪除表空間(使用備份的舊控制檔案controlfile): 使整個資料庫恢復到誤刪除表空間前

4.4 傳統的不完全恢復的操作步驟:(效率低) 現在不大用了,但是這種方法最萬能。

      1)先通過logmnr 找到誤操作的時間點

      2)對現在的database做新全備(所有的資料檔案和當前控制檔案,資料庫要先正常的關閉,然後cp)

      3)還原該時間點前所有的datafile (將所有舊的dbf備份cp過來,recoverdatabase until change scn)

      4)以當前控制檔案進入mount狀態,對database做recover,前滾,恢復到誤操作時間點

      5)開啟資料庫(alter databaseopen resetlogs),將恢復出來的table做邏輯備份(exp),將表匯出來

      6)再正常關閉資料庫,然後再將新剛才的全備還原

      7)將匯出的表匯入database(imp)

其實我們現在用的比較多的是,先看一下閃回資料庫是否打開了,如果打開了,那麼就閃回。如果是在rman下做的備份,那麼我們可以就這個表空間做一個不完全恢復,且不用停機(將表空間做一個TSPITP)。

4.5   logminer 工具的使用 日誌挖掘

     對redo log 進行挖掘,找出在某個時間點所作的DDL 或DML 誤操作(包括:時間點、scn 、sql語句)

4.6 不完全恢復範例:

範例1:

恢復過去某個時間點誤操作的table

4.6.1 基於時間點的不完全恢復

在這個狀態下先在OS下做一個數據檔案和控制檔案的冷備。如果前面有備份了,就不要做下面的了。

SQL> shutdown immediate

[[email protected] ~] $cp /u01/oradata/timran11g/*.dbf  /u01/back1 

[[email protected] ~] $cp /u01/oradata/timran11g/*.ctl  /u01/back1 

SQL> startup

1)環境:scott使用者在test表空間下有個t1表

SQL>conn scott/scott

SQL>create table t1(id int) tablespace test;

SQL>insert into t1 values(1);

SQL>insert into t1 values(2);

SQL>insert into t1 values(3);

SQL>commit;

SQL>select * from t1;

        ID

----------

         1

         2

         3

2)誤刪除了t1表,並purge了。

SQL>drop table t1 purge;

SQL>select * from v$log;

    GROUP#   THREAD#  SEQUENCE#      BYTES   MEMBERS ARCHIVED STATUS          FIRST_CHANGE# FIRST_TIME

-------------------- ---------- ---------- ---------- -------- ----------------------------- -----------

         1          1        131  52428800          1 YES      INACTIVE               1875893 2012-6-13 1

         2          1        132  52428800          1 YES      INACTIVE               1896385 2012-6-13 1

         3          1       133   52428800          1 NO       CURRENT                1916973 2012-7-18 1 

SQL>alter system switch logfile;

SQL>/

SQL>/

SQL>select name from v$archived_log;

NAME

--------------------------------------------------------------------------------

...

/u01/disk1/timran/arch_1_782662700_129.log

/u01/disk1/timran/arch_1_782662700_130.log

/u01/disk1/timran/arch_1_782662700_131.log

/u01/disk1/timran/arch_1_782662700_132.log

/u01/disk1/timran/arch_1_782662700_133.log //drop table t1 purge這個動作的日誌條目記錄在此歸檔日誌裡了。

/u01/disk1/timran/arch_1_782662700_134.log

/u01/disk1/timran/arch_1_782662700_135.log

116 rowsselected

3)通過logmr 找出誤操作的ddl命令的timestamp 或 san    --DDL日誌挖掘

SQL>show parameter utl

NAME                                 TYPE        VALUE

----------------------------------------------- ------------------------------

create_stored_outlines               string

utl_file_dir                         string      /home/oracle/logmnr

如果utl_file_dir沒有值,那麼我們可以手動新增值,這樣將來日誌挖掘的內容就會放在這個目錄裡。

$ mkdir /home/oracle/logmnr

這個初始化引數不是一個動態引數,只能記到spfile

SQL> alter system setutl_file_dir='/home/oracle/logmnr' scope=spfile;

然後需要重啟一下資料庫

SQL> startup force

--下面這句是固定的

SQL>execute dbms_logmnr_d.build('dict.ora','/home/oracle/logmnr',dbms_logmnr_d.store_in_flat_file); 

--往裡面新增日誌,歸檔日誌,當前日誌都可以新增。第一個日誌要是.new,後面就是.addfile

--下面這個也是固定的

SQL>executedbms_logmnr.start_logmnr(dictfilename=>'/home/oracle/logmnr/dict.ora',options=>dbms_logmnr.ddl_dict_tracking);

--檢視分析結果

SQL>select username,scn,to_char(timestamp,'yyyy-mm-dd hh24:mi:ss'),sql_redo fromv$logmnr_contents WHERE lower(sql_redo) like 'droptable%';

USERNAME                  SCNTO_CHAR(TIMESTAMP,'YYYY-MM-DDH SQL_REDO

---------------------------------------- -----------------------------------------------------------------------------

SCOTT                1917250    2012-07-18 16:44:55      drop table test purge;

SCOTT                1917267    2012-07-18 16:45:01      droptable student purge;

SCOTT                1918000    2012-08-0117:28:29      drop table t1 purge;

--釋放記憶體

SQL>execute dbms_logmnr.end_logmnr;

4) 關閉資料庫,刪除所有dbf,準備做不完全恢復

SQL>shutdown immediate 或者shutdown abort

刪之前確保都已經做了備份了。

[[email protected]~]$ cd /u01/oradata/timran11g

[[email protected]~]$ rm *.dbf

5)還原所有備份的資料檔案

[[email protected]~]$ cp /u01/back1/*.dbf ./

6)根據log miner提供的資訊,做基於時間點的不完全恢復

17:31:43SQL> startup

ORACLEinstance started.

TotalSystem Global Area  285212672 bytes

FixedSize                  1218968 bytes

VariableSize              75499112 bytes

DatabaseBuffers          201326592 bytes

RedoBuffers                7168000 bytes

Databasemounted.

ORA-01113:file 1 needs media recovery

ORA-01110:data file 1: '/u01/oradata/timran11g/system01.dbf'

這是因為我們用的舊的資料檔案頭scn,與現在的控制檔案scn不一樣。

17:33:07SQL> recover database until time '2012-08-01 17:28:29';

ORA-00279:change 1917581 generated at 07/18/2012 16:46:34 needed for thread 1

ORA-00289:suggestion : /u01/disk1/timran/arch_1_782662700_133.log

ORA-00280:change 1917581 for thread 1 is in sequence #133

這是因為我們前滾到這一點,需要使用歸檔日誌,所以它建議你使用哪個歸檔日誌。對於歸檔日誌,我們可以使用auto;對於當前線上日誌,可能就得指定一個filename了。

17:33:17Specify log: {<RET>=suggested | filename | AUTO | CANCEL}

auto

Logapplied.

Mediarecovery complete.

7)resetlogs方式開啟資料庫

SQL>alter database open resetlogs;

8)驗證

SQL>select * from scott.t1;

        ID

----------

         1

         2

         3

9)看看在resetlogs後,日誌sequence重置了。

SQL>select * from v$log;

    GROUP#   THREAD#  SEQUENCE#      BYTES   MEMBERS ARCHIVED STATUS          FIRST_CHANGE# FIRST_TIME

-------------------- ---------- ---------- ---------- -------- ----------------------------- -----------

         1          1          0  52428800          1 YES      UNUSED                       0 

         2          1          0  52428800          1 YES      UNUSED                       0 

         3          1          1  52428800          1 NO       CURRENT                1918000 2012-8-1 17

4.6.2 基於SCN的不完全恢復(略)

在手工基於scn的不完全恢復的命令子句是change關鍵字,與基於時間的不完全恢復類似,其命令格式只要將recover命令換成下面即可:

SQL>recover database until change 1918000;  

這裡不多贅述了。                                                                                   

4.6.3 基於cancel的不完全恢復

在這個狀態下先在OS下做一個數據檔案和控制檔案的冷備。如果前面有備份了,就不要做下面的了。

SQL> shutdown immediate

[[email protected] ~] $cp /u01/oradata/timran11g/*.dbf  /u01/back1 

[[email protected] ~] $cp /u01/oradata/timran11g/*.ctl  /u01/back1 

SQL> startup

範例2:在做完全恢復時,丟失了部分歸檔日誌

1)模擬環境

SQL>select * from t1;

        ID

----------

         1

         2

         3

SQL>select * from v$log;

    GROUP#   THREAD#  SEQUENCE#      BYTES   MEMBERS ARCHIVED STATUS           FIRST_CHANGE#FIRST_TIME

-------------------- ---------- ---------- ---------- -------- ------------- ---------------------

    1         1          0   52428800          1 YES      UNUSED                 0

    2         1          0   52428800          1 YES      UNUSED                0

    3         1          1   52428800          1 NO       CURRENT       1918000 2012-8-1 17

SQL>insert into t1 values (111);

SQL>commit;

SQL>alter system switch logfile;

SQL>/

SQL>/

SQL>select * from v$log;

    GROUP#   THREAD#  SEQUENCE#      BYTES   MEMBERS ARCHIVED STATUS           FIRST_CHANGE# FIRST_TIME

-------------------- ---------- ---------- ---------- -------- -------------- --------------------

     1         1          2   52428800         1 YES      INACTIVE         1918829 2012-8-1 17

  2          1          3  52428800          1 YES     ACTIVE           1918831 2012-8-1 17

  3          1          4  52428800          1 NO      CURRENT        1918838 2012-8-1 17

SQL>insert into t1 values (444);

SQL>commit;

SQL>alter system switch logfile;

SQL>/

SQL>/

SQL>select * from v$log;

    GROUP#   THREAD#  SEQUENCE#      BYTES   MEMBERS ARCHIVED STATUS           FIRST_CHANGE# FIRST_TIME

-------------------- ---------- ---------- ---------- -------- -------------- --------------------

   1         1          5   52428800          1 YES     INACTIVE          1918829 2012-8-1 17

2          1          6  52428800          1 YES     ACTIVE            1918831 2012-8-1 17

   3         1          7   52428800         1 NO       CURRENT        1918838 2012-8-1 17

SQL>insert into t1 values (777);

SQL>commit;

SQL>select * from t1;

        ID

----------

         1

         2

         3 

       111          //這個動作的日誌條目記錄在sequence 1裡

       444          //這個動作的日誌條目記錄在sequence 4裡

       777          //這個動作的日誌條目記錄在sequence 7裡

2)模擬資料檔案介質損壞,並需要恢復的歸檔日誌有斷點

SQL>shutdown abort

[[email protected]~]$ cd /u01/oradata/timran11g

[[email protected]~]$ rm user01.dbf        假設users 表空間的datafile損壞

3)再模擬某歸檔日誌損壞

[[email protected]~]$ cd /u01/disk1/timran

[[email protected]~]$ ll

總計359672

-rw-r-----1 oracle oinstall     1024 08-01 16:52arch_1_782662700_139.log

-rw-r-----1 oracle oinstall 46894080 08-01 17:07 arch_1_782662700_140.log

-rw-r-----1 oracle oinstall   608768 08-01 17:48arch_1_790191207_1.log

-rw-r-----1 oracle oinstall     1024 08-01 17:48arch_1_790191207_2.log

-rw-r-----1 oracle oinstall     6144 08-01 17:48arch_1_790191207_3.log

-rw-r-----1 oracle oinstall    49664 08-01 17:49arch_1_790191207_4.log

-rw-r-----1 oracle oinstall     1024 08-01 17:49arch_1_790191207_5.log

-rw-r-----1 oracle oinstall    11264 08-01 17:49arch_1_790191207_6.log

-rw-r-----1 oracle oinstall     1536 08-01 17:49arch_1_790191207_7.log

[[email protected]~]$ mv arch_1_790191207_4.log arch_1_790191207_4.delete

[[email protected]~]$ ll

-rw-r-----1 oracle oinstall     1024 08-01 16:52arch_1_782662700_139.log

-rw-r-----1 oracle oinstall 46894080 08-01 17:07 arch_1_782662700_140.log

-rw-r-----1 oracle oinstall   608768 08-01 17:48arch_1_790191207_1.log

-rw-r-----1 oracle oinstall     1024 08-01 17:48arch_1_790191207_2.log

-rw-r-----1 oracle oinstall     6144 08-01 17:48arch_1_790191207_3.log

-rw-r-----1 oracle oinstall    49664 08-01 17:49arch_1_790191207_4.delete //日誌不連續了,假設在sequence 4斷掉了

-rw-r-----1 oracle oinstall     1024 08-01 17:49arch_1_790191207_5.log

-rw-r-----1 oracle oinstall    11264 08-01 17:49arch_1_790191207_6.log

-rw-r-----1 oracle oinstall     1536 08-01 17:49arch_1_790191207_7.log

4)嘗試對某資料檔案的完全恢復

SQL>startup

ORACLEinstance started.

TotalSystem Global Area  285212672 bytes

FixedSize                  1218968 bytes

VariableSize              75499112 bytes

DatabaseBuffers          201326592 bytes

RedoBuffers                7168000 bytes

Databasemounted.

ORA-01157:cannot identify/lock data file 4 - see DBWR trace file

ORA-01110:data file 4: '/u01/oradata/timran11g/users01.dbf'

SQL>select file#,error from v$recover_file;                                                                                   

     FILE# ERROR

---------------------------------------------------------------------------

         4 FILE NOT FOUND

[[email protected]~]$cp /u01/back1/users01.dbf /u01/oradata/timran11g/users01.dbf //還原單個數據檔案,企圖基於datafile的完全恢復

06:09:07SQL> recover datafile 4;

有如下報錯:

......

......

ORA-00308:cannot open archived log '/u01/disk1/timran/arch_1_790191207_4.log'

ORA-27037:unable to obtain file status

LinuxError: 2: No such file or directory

Additionalinformation: 3

//完全恢復失敗,因為缺少歸檔日誌:(/u01/disk1/timran/arch_1_790191207_4.log),只能做基於cancel的不完全恢復。

5)使用備份還原所有的datafile

[[email protected]~]$ cd /u01/oradata/timran11g

[[email protected]~]$ rm *.dbf

[[email protected]~]$ cp /u01/back1/*.dbf ./

6)進行基於cancel的不完全恢復

SQL>recover database until cancel;

ORA-00279:change 1918785 generated at 08/01/2012 17:48:41 needed for thread 1

ORA-00289:suggestion : /u01/disk1/timran/arch_1_790191207_4.log

ORA-00280:change 1918785 for thread 1 is in sequence #4

17:56:15Specify log: {<RET>=suggested | filename | AUTO | CANCEL}

auto

ORA-00308:cannot open archived log '/u01/disk1/timran/arch_1_790191207_4.log'

ORA-27037:unable to obtain file status

LinuxError: 2: No such file or directory

Additionalinformation: 3

ORA-00308:cannot open archived log '/u01/disk1/timran/arch_1_790191207_4.log'

ORA-27037:unable to obtain file status

LinuxError: 2: No such file or directory

Additionalinformation: 3

//選auto不好使,再來一遍選cancel.

17:56:21SQL> recover database until cancel;

ORA-00279:change 1918785 generated at 08/01/2012 17:48:41 needed for thread 1

ORA-00289:suggestion : /u01/disk1/timran/arch_1_790191207_4.log

ORA-00280:change 1918785 for thread 1 is in sequence #4

17:56:23Specify log: {<RET>=suggested | filename | AUTO | CANCEL}

cancel

Mediarecovery cancelled.

//選擇cancel ,在丟失的歸檔日誌前終止recover

7)resetlogs開啟資料庫

SQL>alter database open resetlogs;

8)驗證

SQL>select * from scott.t1;

        ID

----------

         1

         2

         3

       111

4.6.4 基於backupcontrolfile 的恢復(有一定的複雜性)

不完全恢復中的複雜性是恢復資料檔案的時候使用備份的舊的控制檔案。

1)為什麼會使用備份的控制檔案? 實際工作中主要有兩種情況:

第一種:當前控制檔案全部損壞,而資料檔案備份,控制檔案備份及當前日誌處於不同SCN版本,它們之間又增加過表空間(資料檔案)。

第二種:當前控制檔案沒有損壞,但想要恢復被刪除的表空間。

2)使用備份的控制檔案恢復資料庫的語法:

//符合條件時,實現完全恢復。走完歸檔日誌,再走當前日誌(使用filename來指定當前日誌路徑和檔名)。(控制檔案中沒有記錄當前日誌,只記錄歸檔日誌)

recover database using backupcontrolfile; 

//不完全恢復,開啟資料庫是,需要alter database open resetlogs;

recover database until[time|change] using backup controlfile;

注意:[time|change]是可選的,就是說如果條件滿足,仍然可以做到完全恢復。

然後會有如下選項:

Specifylog: {<RET>=suggested | filename | AUTO | CANCEL}

此語法的出現是由於控制檔案和當前日誌中不一致,當前日誌的scn總是最新的,而控制檔案可能是老的或尚未更新的(shutdwon abort過)。

AUTO:  自動使用archivelog前滾恢復,但一般不包括前滾currentlog;

filename:  輸入當前日誌檔案的路徑和檔名,是指currentlog的恢復

CANCEL:  退出。

考點:

1)在控制檔案丟失後進行恢復將會出現停機時間,因此不能聯機執行控制檔案的恢復。

2)使用backup controlfile子句的不完全恢復資料庫之後,一律要使用alter database open resetlogs開啟資料庫。

當我們沒restlogs就會換一個朝代(incarnation),就是RESETLOGS_ID會不一樣。

範例1:(屬於第一種情況)

第一種:當前控制檔案全部損壞,而資料檔案備份,控制檔案備份及當前日誌處於不同SCN版本,它們之間又增加過表空間(資料檔案)。

環境:當前控制檔案損壞,資料檔案損壞,有全備但之後增加了表空間,並備份了配套的控制檔案。

模式:所有資料檔案備份(老)------(新建表空間abcd)-----備份控制檔案(次新)------日誌檔案(新)

分析:新建表空間資料檔案損壞, 全備裡沒有該資料檔案的備份及控制檔案描述,當前控制檔案又丟失,只能用備份的控制檔案恢復。

在這個狀態下先在OS下做一個數據檔案和控制檔案的冷備。如果前面有備份了,就不要做下面的了。

SQL> shutdown immediate

[[email protected] ~] $cp /u01/oradata/timran11g/*.dbf  /u01/back1 

[[email protected] ~] $cp /u01/oradata/timran11g/*.ctl  /u01/back1 

SQL> startup

1)環境:

SQL>select * from v$tablespace;

       TS# NAME                           INC BIG FLA ENC

---------------------------------------- --- --- --- ---

         0 SYSTEM                         YES NO  YES

         1 SYSAUX                         YES NO  YES

         4 USERS                          YES NO  YES

         6 EXAMPLE                        YES NO  YES

         8 TEST                           YES NO  YES

         2 UNDOTBS1                       YES NO  YES

         3 TEMP                           NO  NO  YES

SQL>select * from v$log;

    GROUP#   THREAD#  SEQUENCE#      BYTES   MEMBERS ARC STATUS          FIRST_CHANGE# FIRST_TIME

-------------------- ---------- ---------- ---------- --- ---------------- --------------------------------

         1          1          7  52428800          1 NO  CURRENT                6676574 2013-01-17 13:55:19

         2          1          5  52428800          1 YES INACTIVE               6676549 2013-01-17 13:54:14

         3          1          6  52428800          1 YES INACTIVE               6676562 2013-01-17 13:54:48

SQL>create tablespace abcd datafile '/u01/oradata/timran11g/abcd01.dbf' size 5m;

SQL>create table scott.a1 (name char(10)) tablespace abcd;

SQL>insert into scott.a1 values('a');

SQL>commit;

SQL>select * from scott.a1;

NAME

----------

a

SQL>alter system switch logfile;

這是因為,不切換的話,它是在當前日誌裡,而控制檔案只存歸檔日誌。

2)備份控制檔案

--19:17:55

SQL>alter database backup controlfile to '/u01/oradata/timran11g/con.bak1';

SQL>insert into scott.a1 values('b');

SQL>commit;

3) 模擬abcd01.dbf損壞

[[email protected]~]$rm /u01/oradata/timran11g/abcd01.dbf  //資料庫open狀態,刪除abcd01.dbf資料檔案

SQL>alter system flush buffer_cache;     //dbbuffer 清空 

SQL>conn / as sysdba       //換個session檢視 a1表物理讀失敗

已連線。

SQL>select * from scott.a1;

select *from scott.a1

                    *

第 1 行出現錯誤:

ORA-00376:此時無法讀取檔案 3

ORA-01110:資料檔案 3: '/u01/oradata/timran11g/abcd01.dbf'

4)關閉資料庫

SQL>shutdown abort;

5)恢復所有資料檔案備份,準備做不完全恢復

[[email protected]]$ cd /u01/oradata/timran11g

[[email protected]]$ rm *.ctl

[[email protected]]$ rm *.dbf

[[email protected]]$ cp /u01/back1/*.dbf ./

[[email protected]]$ cp con.bak1 control01.ctl

[[email protected]]$ cp con.bak1 control02.ctl

[[email protected]]$ cp con.bak1 control03.ctl

SQL>startup

ORACLE 例程已經啟動。

TotalSystem Global Area  422670336 bytes

FixedSize                  1300352 bytes

VariableSize             331352192 bytes

DatabaseBuffers           83886080 bytes

RedoBuffers                6131712 bytes

資料庫裝載完畢。現在沒有open,是在mount狀態。

ORA-01589:要開啟資料庫則必須使用 RESETLOGS 或 NORESETLOGS 選項

這是因為目前日誌的scn比控制檔案和資料檔案都新,這裡不去管它。

SQL>col name for a50;

SQL>select file#,checkpoint_change#,name from v$datafile;

     FILE# CHECKPOINT_CHANGE# NAME

---------------------------- --------------------------------------------------

         1            6676574/u01/oradata/timran11g/system01.dbf

         2            6676574/u01/oradata/timran11g/sysaux01.dbf

         3            6676601/u01/oradata/timran11g/abcd01.dbf

         4            6676574 /u01/oradata/timran11g/user01.dbf

         5            6676574/u01/oradata/timran11g/example01.dbf

         6            6676574/u01/oradata/timran11g/test01.dbf

         7            6676574/u01/oradata/timran11g/undotbs01.dbf

SQL>select file#,checkpoint_change#  fromv$datafile_header;

     FILE# CHECKPOINT_CHANGE#

----------------------------

         1            6676343

         2            6676343

         3                  0

         4            6676343

         5            6676343

         6            6676343

         7            6676343

SQL> 

可以看出:1)file3 在控制檔案裡記錄是abcd01.dbf,而與之對應的資料檔案3是不存在的,2)備份的資料備份的scn比控制檔案scn的還老。

6)使用備份控制檔案恢復

SQL>recover database using backup controlfile;

ORA-00283:恢復會話因錯誤而取消

ORA-01110:資料檔案 3: '/u01/oradata/timran11g/abcd01.dbf'

ORA-01157:無法標識/鎖定資料檔案 3 - 請參閱 DBWR 跟蹤檔案

ORA-01110:資料檔案 3: '/u01/oradata/timran11g/abcd01.dbf'

//此錯是因為老備份裡沒有abcd表空間,但只要控制檔案裡記錄了abcd就好辦,方法是建一個datafile的空檔案,而其中內容可由日誌檔案recover(前滾)時填補出來。

SQL>alter database create datafile '/u01/oradata/timran11g/abcd01.dbf';

---再次使用備份控制檔案恢復

SQL>recover database using backup controlfile;

ORA-00279:change 1917582 generated at 07/18/2012 17:46:34 needed for thread 1

ORA-00289:suggestion : /u01/disk1/timran/arch_1_804846835_6.log

ORA-00280:change 1917582 for thread 1 is in sequence #133

指定日誌:{<RET>=suggested | filename | AUTO | CANCEL}

//注意:對於這個例子來說,一定要看清提示:如果提示的arch_1_804846837_6.log不是歸檔的日誌。如果是歸檔日誌,則輸入auto;如果是當前日誌,則輸入filename的目錄和檔名。否則open時會失敗。

ORA-00308:無法開啟歸檔日誌 '/u01/disk1/timran/arch_1_804846837_9.log'

ORA-27037:無法獲得檔案狀態

LinuxError: 2: No such file or directory

Additionalinformation: 3

//archive日誌前滾結束了,但當前日誌裡還有資訊需要恢復

SQL>recover database using backup controlfile;   //再次做恢復

指定日誌:{<RET>=suggested | filename | AUTO | CANCEL}

/u01/oradata/timran11g/redo03.log

//把蛇頭(當前日誌)給它,這裡有3個redo log,挨個試試。

已應用的日誌。

完成介質恢復。

7)resetlogs開啟資料庫

這裡其實已經做了一個完全恢復了,但是它是一種不完全恢復的結構,所以開啟還得加resetlogs(不完全恢復的結構,恢復了完全資料)

SQL>alter database open resetlogs;

8)驗證

SQL>select * from scott.a1;

NAME

----------------------------------------

a

b

範例2:(屬於第一種情況)(略)

第一種:當前控制檔案全部損壞,而資料檔案備份,控制檔案備份及當前日誌處於不同SCN版本,它們之間又增加過表空間(資料檔案)。

在這個狀態下先在OS下做一個數據檔案和控制檔案的冷備。如果前面有備份了,就不要做下面的了。

SQL> shutdown immediate

[[email protected] ~] $cp /u01/oradata/timran11g/*.dbf  /u01/back1 

[[email protected] ~] $cp /u01/oradata/timran11g/*.ctl  /u01/back1 

SQL> startup

環境:當前控制檔案損壞,新建表空間在備份控制檔案之後

模式:全備(老)-----備份控制檔案(次新)-----新建表空間timran------日誌檔案(新)

分析:整個恢復過程中datafile結構有了變化,變化發生在備份控制檔案之後,新增了表空間timran,控制檔案備份裡沒有此表空間記錄,但日誌裡有。

1)環境

SQL>drop tablespace abcd including contents and datafiles;

SQL>alter database backup controlfile to '/u01/oradata/timran11g/con.bak2';

SQL>create tablespace timran datafile '/u01/oradata/timran11g/timran01.dbf' size5m; 

SQL>create table scott.r1 (id int) tablespace timran ;

SQL>insert into scott.r1 values(1);

SQL>commit;

SQL>select * from v$tablespace;

       TS# NAME                                               INCBIG FLA ENC

------------------------------------------------------------ --- --- --- ---

         0 SYSTEM                                            YES NO  YES

         1 SYSAUX                                             YES NO  YES

        14 TIMRAN                                            YES NO  YES

         4 USERS                                             YES NO  YES

         6 EXAMPLE                                            YESNO  YES

         8 TEST                                              YES NO  YES

         3 TEMP                                              NO  NO  YES

         2 UNDOTBS1                                           YESNO  YES

SQL>select * from scott.r1;

        ID

----------

         1

SQL>  select * from v$log;

    GROUP#   THREAD#  SEQUENCE#      BYTES   MEMBERS ARC STATUS          FIRST_CHANGE# FIRST_TIME

-------------------- ---------- ---------- ---------- --- ---------------- --------------------------------

         1          1          1  52428800          1 NO  CURRENT                6677119 2013-01-17 14:08:18

         2          1          0  52428800          1 YES UNUSED                       0

         3          1          0  52428800          1 YES UNUSED                       0

2)模擬新建資料檔案損壞

[[email protected]]rm timran01.dbf

SQL>altersystem flush buffer_cache;

SQL>conn/ as sysdba

SQL>select* from scott.r1;

第 1 行出現錯誤:

ORA-01116:開啟資料庫檔案 3 時出錯

ORA-01110:資料檔案 3: '/u01/oradata/timran11g/timran01.dbf'

ORA-27041:無法開啟檔案

LinuxError: 2: No such file or directory

Additionalinformation: 3

3) 關閉資料庫

SQL>shutdownabort

4)還原所有資料檔案,以老控制檔案替換當前控制檔案

[[email protected]]$ cd /u01/oradata/timran11g

[[email protected]]$ rm *.ctl

[[email protected]]$ rm *.dbf

[[email protected]]$ cp /u01/back1/*.dbf ./

[[email protected]]$ cp con.bak2 control01.ctl

[[email protected]]$ cp con.bak2 control02.ctl

[[email protected]]$ cp con.bak2 control03.ctl

5)啟動資料庫

SQL>startup

ORACLE 例程已經啟動。

......

資料庫裝載完畢。

ORA-01589:要開啟資料庫則必須使用 RESETLOGS 或 NORESETLOGS 選項

SQL>select file#,checkpoint_change#,name from v$datafile;

     FILE# CHECKPOINT_CHANGE# NAME

---------------------------- --------------------------------------------------

         1            6677122 /u01/oradata/timran11g/system01.dbf

         2            6677122/u01/oradata/timran11g/sysaux01.dbf

         4            6677122/u01/oradata/timran11g/user01.dbf

         5            6677122/u01/oradata/timran11g/example01.dbf

         6            6677122 /u01/oradata/timran11g/test01.dbf

         7            6677122/u01/oradata/timran11g/undotbs01.dbf

SQL>select file#,checkpoint_change# from v$datafile_header;

     FILE# CHECKPOINT_CHANGE#

----------------------------

         1            6676343

         2            6676343

         4            6676343

         5            6676343

         6            6676343

         7            6676343

6)使用備份控制檔案恢復資料庫

ORA-00279:更改 6676343 (在 01/16/2013 14:11:39 生成) 對於執行緒 1 是必需的

ORA-00289:建議: /u01/disk1/timran/arch_1_804846837_4.log

ORA-00280:更改 6676343 (用於執行緒 1) 在序列 #4 中

指定日誌:{<RET>=suggested | filename | AUTO | CANCEL}

auto

......

//注意:對於這個例子來說,一定要看清提示:如果提示的arch_1_804846837_6.log不是歸檔的日誌。如果是歸檔日誌,則輸入auto;如果是當前日誌,則輸入filename的目錄和檔名。否則open時會失敗。

ORA-00308:無法開啟歸檔日誌 '/u01/disk1/timran/arch_1_804847837_9.log'

ORA-27037:無法獲得檔案狀態

LinuxError: 2: No such file or directory

Additionalinformation: 3

經檢視arch_1_804946837_9.log是當前日誌,所以就是輸入filename了

SQL>recover database using backup controlfile;

指定日誌:{<RET>=suggested | filename | AUTO | CANCEL}

/u01/oradata/timran11g/redo01.log

......

ORA-00283:恢復會話因錯誤而取消

ORA-01244:未命名的資料檔案由介質恢復新增至控制檔案

ORA-01110:資料檔案 3: '/u01/oradata/timran11g/timran01.dbf'

ORA-01112:未啟動介質恢復

SQL>select file#,checkpoint_change#,name from v$datafile;

     FILE# CHECKPOINT_CHANGE# NAME

---------------------------- --------------------------------------------------

         1            6678002/u01/oradata/timran11g/system01.dbf

         2            6678002/u01/oradata/timran11g/sysaux01.dbf

         3            6677999/u01/oracle/dbs/UNNAMED00003  //注意這個問題,老控制檔案不知道之後的timran01.dbf

         4            6678002 /u01/oradata/timran11g/user01.dbf

         5            6678002/u01/oradata/timran11g/example01.dbf

         6            6678002/u01/oradata/timran11g/test01.dbf

         7            6678002/u01/oradata/timran11g/undotbs01.dbf

SQL>select file#,checkpoint_change# from v$datafile_header;

     FILE# CHECKPOINT_CHANGE#

----------------------------

         1            6678002

         2            6678002

         3                  0

         4            6678002

         5            6678002

         6            6678002

         7            6678002

7)重新命名資料檔案

SQL>alter database create datafile '/u01/oracle/dbs/UNNAMED00003' as'/u01/oradata/timran11g/timran01.dbf';

//上面的命令一石二鳥,自動完成了兩個動作1)加了一個數據檔案timran01.dbf,2)重新命名控制檔案UNNAMED00003為timran01.dbf

SQL>select file#,checkpoint_change#,name from v$datafile;

     FILE# CHECKPOINT_CHANGE# NAME

---------------------------- --------------------------------------------------

         1            6678002/u01/oradata/timran11g/system01.dbf

         2            6678002/u01/oradata/timran11g/sysaux01.dbf

         3            6677999/u01/oradata/timran11g/timran01.dbf

         4            6678002/u01/oradata/timran11g/user01.dbf

         5            6678002 /u01/oradata/timran11g/example01.dbf

         6            6678002/u01/oradata/timran11g/test01.dbf

         7            6678002/u01/oradata/timran11g/undotbs01.dbf

SQL>recover database using backup controlfile;

ORA-00279:更改 6677999 (在 01/17/2013 14:20:50 生成) 對於執行緒 1 是必需的

ORA-00289:建議: /u01/disk1/timran/arch_1_804953298_1.log

ORA-00280:更改 6677999 (用於執行緒 1) 在序列 #1 中

指定日誌:{<RET>=suggested | filename | AUTO | CANCEL}

/u01/oradata/timran11g/redo01.log

已應用的日誌。

完成介質恢復。

8)resetlogs開啟資料庫

SQL>alter database open resetlogs;

9)驗證

SQL>select * from scott.r1;

        ID

----------

         1

         2

         3

範例3 恢復被刪除的表空間(屬於第二種情況)(略)

第二種:當前控制檔案沒有損壞,但想要恢復被刪除的表空間。

在這個狀態下先在OS下做一個數據檔案和控制檔案的冷備。如果前面有備份了,就不要做下面的了。

SQL> shutdown immediate

[[email protected] ~] $cp /u01/oradata/timran11g/*.dbf  /u01/back1 

[[email protected] ~] $cp /u01/oradata/timran11g/*.ctl  /u01/back1 

SQL> startup

環境:使用者使用正常操作命令刪除了表空間及其資料檔案,但之後又希望恢復刪除的表空間。全備裡有這個表空間的資料檔案。

模式:全備(老)------控制檔案備份(次新)-----刪除表空間------所需日誌(新)

分析:當用戶使用droptablesapce xxx including contents and datafiles 這條DDL語句後,資料庫的結構發生了變更,涉及了三個地方。

a)控制檔案

b)該表空間下的資料檔案

c)系統表空間(資料字典)

特別提醒的是:當前的控制檔案裡已經沒有該表空間的資訊了,所以不能使用當前的控制檔案做恢復。恢復這個表空間要滿足三個條件:

a)要有該表空間的資料檔案備份

b)使用不完全恢復(基於時間點或scn)

c)使用備份的控制檔案,而這個控制檔案是刪除該表空間前的控制檔案,不是當前的控制檔案。這個非常重要,該控制檔案中的內容記錄了你需要恢復資料庫結構,重要的這個控制檔案必須包括有你要恢復的那個表空間的資訊。

1)背景:

SQL>select * from v$tablespace;

       TS# NAME                           INC BIG FLA ENC

---------------------------------------- --- --- --- ---

         0 SYSTEM                         YES NO  YES

         1 SYSAUX                         YES NO  YES

         5 UNDOTBS2                       YES NO  YES

         4 USERS                          YES NO  YES

         6 EXAMPLE                        YES NO YES

         8 TEST                           YES NO  YES

         3 TEMP                           NO  NO  YES

SQL>create table scott.t1(id int) tablespace test;

SQL>insert into scott.t1 values(1);

SQL>commit;

SQL>alter system switch logfile;

SQL>/

SQL>/

2)記錄下當前scn  (實際情況下,我們通過4.6.1的方法,使用logmnr進行日誌挖掘,發現時間點或者scn)

SQL>select current_scn from v$database;

CURRENT_SCN

-----------

    7222848

3)備份控制檔案

SQL>alter database backup controlfile to '/u01/oradata/timran11g/con.bak'

4)刪除表空間及資料檔案

SQL>drop tablespace test including contents and datafiles;

SQL>shutdown abort

5)刪除所有資料檔案和當前控制檔案,還原所有資料檔案及備份的控制檔案

[[email protected]]$ rm *.dbf

[[email protected]]$ rm *.ctl

[[email protected]]$ cp /u01/back1/*.dbf ./

[[email protected]]$ cp con.bak control01.ctl

[[email protected]]$ cp con.bak control02.ctl

[[email protected]]$ cp con.bak control03.ctl

6)啟動資料庫後,要做基於時間點(或SCN)的不完全恢復

SQL>startup

...

資料庫裝載完畢。

ORA-01589:要開啟資料庫則必須使用 RESETLOGS 或 NORESETLOGS 選

SQL>recover database until change 7222848 using backup controlfile;

ORA-00279:更改 6678999 (在 01/17/2013 17:20:50 生成) 對於執行緒 1 是必需的

ORA-00289:建議: /u01/disk1/timran/arch_1_804953398_1.log

ORA-00280:更改 6678999 (用於執行緒 1) 在序列 #1 中

指定日誌:{<RET>=suggested | filename | AUTO | CANCEL}

auto

//注意:對於這個例子來說,一定要看清提示:如果提示的arch_1_804846837_6.log不是歸檔的日誌。如果是歸檔日誌,則輸入auto;如果是當前日誌,則輸入filename的目錄和檔名。否則open時會失敗。

ORA-00308:無法開啟歸檔日誌 '/u01/disk1/timran/arch_1_804946837_9.log'

ORA-27037:無法獲得檔案狀態

LinuxError: 2: No such file or directory

Additionalinformation: 3

經檢視arch_1_804946837_9.log是當前日誌,所以就是輸入filename了

SQL>recover database until change 7222848 using backup controlfile;

ORA-00279:更改 6677999 (在 01/17/2013 14:20:50 生成) 對於執行緒 1 是必需的

ORA-00289:建議: /u01/disk1/timran/arch_1_804953298_1.log

ORA-00280:更改 6677999 (用於執行緒 1) 在序列 #1 中

指定日誌:{<RET>=suggested | filename | AUTO | CANCEL}

/u01/oradata/timran11g/redo01.log

已應用的日誌。

完成介質恢復。

7)以不完全恢復方式開啟資料庫

SQL>alter database open resetlogs;

8)驗證

SQL>select * from scott.t1;

        ID

----------

         1