新建的表空間(或資料檔案)丟失以及控制檔案丟失,有新建表空間(或資料檔案)前的控制文

hanson發表於2019-04-14

事情源於
http://www.itpub.net/showthread.php?s=&threadid=594452&perpage=10&pagenumber=1
同時結合很早的一個問題:
http://www.itpub.net/showthread.php?s=&threadid=326938&perpage=10&pagenumber=1

自己總結了一下。試驗過程如下:
1、首先備份控制檔案。
2、建立一個新的表空間。
3、在該表空間上建立一個表,並插入測試資料。
4、關閉資料庫。這一步是關鍵。分為兩種情況:正常關閉、非正常關閉。
5、OS上刪除控制檔案、新加入的資料檔案。
6、啟動以後,不完全恢復到表空間建立的時間。這個時間可以在alert.log裡找到。試驗證明,第四步,如果正常關閉則不能成功,如果非正常關閉,可以成功。


介紹一下不完全恢復的背景。不完全恢復能夠成功的前提是所有的資料檔案頭部的SCN都保持一致才能算是成功。只要有一個資料檔案頭的SCN與其他資料檔案頭的SCN不一致,就不能開啟資料庫。不完全恢復包括until time、until cancel、until scn。

這三種方式的本質都是向前應用一大堆redo entry,直到達到某一確定SCN時為止,不再應用該SCN以後的所有redo entry。這三種方法無非提供了三種方式,讓你能夠找到該確定的SCN而已。
對於until time來說,就是你指定的時間點以前的最大的SCN。
對於until cancel來說,就是你指定cancel的時候,已經應用了的日誌所含有的最大的SCN。
對於until scn來說,就是你指定的SCN。

ok,來做測試。
1、
SQL> alter database backup controlfile to 'C:oracleoradatacontrol01.ctl';

資料庫已更改。

2、
SQL> create tablespace test datafile 'C:oracleoradataora10test.dbf' size 2M extent management local;

表空間已建立。

3、
SQL> create table test(n number) tablespace test;

表已建立。

SQL> insert into test values(1);

已建立 1 行。

SQL> commit;

提交完成。

4、非正常關閉資料庫,注意這一步非常重要。
SQL> shutdown abort;
ORACLE 例程已經關閉。

5、刪除控制檔案、test資料檔案。然後將第一步備份的控制檔案恢復上去。

6、
SQL> connect / as sysdba
已連線到空閒例程。
SQL> startup
ORACLE 例程已經啟動。

Total System Global Area 135338868 bytes
Fixed Size 453492 bytes
Variable Size 109051904 bytes
Database Buffers 25165824 bytes
Redo Buffers 667648 bytes
資料庫裝載完畢。
ORA-01589: 要開啟資料庫則必須使用 RESETLOGS 或 NORESETLOGS 選項

SQL> set linesize 500
SQL> select name,creation_change#,checkpoint_change#,last_change#,online_change# from v$datafile;

NAME CREATION_CHANGE# CHECKPOINT_CHANGE# LAST_CHANGE# ONLINE_CHANGE#
---------------------------------------- ---------------- ------------------ ------------ --------------
C:ORACLEORADATAORA10SYSTEM01.DBF 6 230918 230744
C:ORACLEORADATAORA10DRSYS01.DBF 5688 230918 230744
C:ORACLEORADATAORA10EXAMPLE01.DBF 5705 230918 230744
C:ORACLEORADATAORA10INDX01.DBF 5723 230918 230744
C:ORACLEORADATAORA10TOOLS01.DBF 5741 230918 230744
C:ORACLEORADATAORA10USERS01.DBF 5761 230918 230744
C:ORACLEORADATAORA10XDB01.DBF 5779 230918 230744
C:ORACLEORADATAORA10UNDONEW01.DBF 230433 230918 230744

已選擇8行。

SQL> recover database using backup controlfile until time '2006-07-21 13:31:11';
ORA-00279: 更改 230918 (在 07/21/2006 13:29:50 生成) 對於執行緒 1 是必需的
ORA-00289: 建議: C:ORACLEORADATAORA10ARCHIVEARC00001.001
ORA-00280: 更改 230918 對於執行緒 1 是按序列 # 1 進行的


指定日誌: {=suggested | filename | AUTO | CANCEL}
C:oracleoradataora10redo01.log
ORA-00339: 歸檔日誌未包含任何重做
ORA-00334: 歸檔日誌: 'C:ORACLEORADATAORA10REDO01.LOG'


ORA-01547: 警告: RECOVER 成功但 OPEN RESETLOGS 將出現如下錯誤
ORA-01194: 檔案1需要更多的恢復來保持一致性
ORA-01110: 資料檔案 1: 'C:ORACLEORADATAORA10SYSTEM01.DBF'


SQL> recover database using backup controlfile until time '2006-07-21 13:31:11';
ORA-00279: 更改 230918 (在 07/21/2006 13:29:50 生成) 對於執行緒 1 是必需的
ORA-00289: 建議: C:ORACLEORADATAORA10ARCHIVEARC00001.001
ORA-00280: 更改 230918 對於執行緒 1 是按序列 # 1 進行的


指定日誌: {=suggested | filename | AUTO | CANCEL}
C:oracleoradataora10redo02.log
ORA-00283: 恢復會話因錯誤而取消
ORA-01244: 未命名的資料檔案由介質恢復新增至控制檔案
ORA-01110: 資料檔案 2: 'C:ORACLEORADATAORA10TEST.DBF'


ORA-01112: 未啟動介質恢復

ok,從這裡可以看到,原來備份的控制檔案裡是沒有記錄有關test.dbf資料檔案記錄的。因為該檔案是在備份控制檔案以後建立的。然後,通過應用日誌redo02.log,裡面記錄了建立test.dbf的命令。但是因為控制檔案不知道現在該檔案叫什麼名字了,所以將其命名為一個很怪的名字:UNNAMED00002。注意,這個時候,資料檔案並沒有實際恢復回來。因為控制檔案裡沒有記錄test.dbf這個資料檔案,所以也就沒有執行建立表空間和資料檔案的redo entry,而是直接彈出錯誤。

SQL> select name,creation_change#,checkpoint_change#,last_change#,online_change# from v$datafile;

NAME CREATION_CHANGE# CHECKPOINT_CHANGE# LAST_CHANGE# ONLINE_CHANGE#
---------------------------------------- ---------------- ------------------ ------------ --------------
C:ORACLEORADATAORA10SYSTEM01.DBF 6 231078 230744
C:ORACLEORA92DATABASEUNNAMED00002 231076 231076 0
C:ORACLEORADATAORA10DRSYS01.DBF 5688 231078 230744
C:ORACLEORADATAORA10EXAMPLE01.DBF 5705 231078 230744
C:ORACLEORADATAORA10INDX01.DBF 5723 231078 230744
C:ORACLEORADATAORA10TOOLS01.DBF 5741 231078 230744
C:ORACLEORADATAORA10USERS01.DBF 5761 231078 230744
C:ORACLEORADATAORA10XDB01.DBF 5779 231078 230744
C:ORACLEORADATAORA10UNDONEW01.DBF 230433 231078 230744

已選擇9行。

沒問題,可以通過命令把這個名字改回來,並同時建立該資料檔案。
SQL> alter database create datafile 'C:ORACLEORA92DATABASEUNNAMED00002' as 'C:ORACLEORADATAORA10test.dbf';

資料庫已更改。

SQL> select name,creation_change#,checkpoint_change#,last_change#,online_change# from v$datafile;

NAME CREATION_CHANGE# CHECKPOINT_CHANGE# LAST_CHANGE# ONLINE_CHANGE#
---------------------------------------- ---------------- ------------------ ------------ --------------
C:ORACLEORADATAORA10SYSTEM01.DBF 6 231078 230744
C:ORACLEORA92DATABASETEST.DBF 231076 231076 0
C:ORACLEORADATAORA10DRSYS01.DBF 5688 231078 230744
C:ORACLEORADATAORA10EXAMPLE01.DBF 5705 231078 230744
C:ORACLEORADATAORA10INDX01.DBF 5723 231078 230744
C:ORACLEORADATAORA10TOOLS01.DBF 5741 231078 230744
C:ORACLEORADATAORA10USERS01.DBF 5761 231078 230744
C:ORACLEORADATAORA10XDB01.DBF 5779 231078 230744
C:ORACLEORADATAORA10UNDONEW01.DBF 230433 231078 230744

已選擇9行。

再次應用日誌,將test表恢復回來。
SQL> recover database using backup controlfile until time '2006-07-21 13:31:11';
ORA-00279: 更改 231076 (在 07/21/2006 13:30:33 生成) 對於執行緒 1 是必需的
ORA-00289: 建議: C:ORACLEORADATAORA10ARCHIVEARC00001.001
ORA-00280: 更改 231076 對於執行緒 1 是按序列 # 1 進行的


指定日誌: {=suggested | filename | AUTO | CANCEL}
C:oracleoradataora10redo02.log
已應用的日誌。
完成介質恢復。

SQL> alter database open resetlogs;

資料庫已更改。

SQL> select * from test;

N
----------
1

SQL>

如果在第四步正常關閉資料庫的話,則由於正常關閉資料庫將提高資料檔案頭的SCN,這樣導致在恢復到指定的時間點時,只有被恢復的test.dbf的檔案頭SCN增加上去了,而其他資料檔案由於沒有應用到redo entry,導致比test.dbf的scn要低,所以這時是不能開啟資料庫的。必須把這個時間點推遲到正常關閉資料庫的那個時間點才能夠應用足夠的redo entry。
這也就解釋了以前的一個問題:
http://www.itpub.net/showthread.php?s=&threadid=326938&perpage=10&pagenumber=11

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9842/viewspace-156320/,如需轉載,請註明出處,否則將追究法律責任。

相關文章