使用控制程式碼實現特定場景的無備份恢復
使用rman備份或者做一個完整的系統級備份也是很重要的,如果在特定的場景下,沒有備份,如果還能恢復,那就太幸運了。
當資料庫中的某個資料檔案誤刪的時候,如果資料庫還沒有重啟的時候,還是能夠做一些工作的。因為檔案對應的控制程式碼還沒有釋放。我們可以從裡面找到一個映象的備份實現我們的資料恢復。一定注意這種恢復不一定是完全的資料恢復,如果在資料檔案刪除的瞬間,有開啟的事務,那麼這些事務也是提交過的。
在刪除之前,我們先來看看測試環境的資料檔案情況。
SQL> select tablespace_name,file_name from dba_data_files;
TABLESPACE_NAME FILE_NAME
------------------------------ --------------------------------------------------
SYSTEM /u03/ora11g/oradata/TEST01/system01.dbf
SYSAUX /u03/ora11g/oradata/TEST01/sysaux01.dbf
UNDOTBS /u03/ora11g/oradata/TEST01/undotbs01.dbf
TEST_DATA1 /u02/ora11g/testdata1.dbf
POOL_DATA /u03/ora11g/oradata/TEST01/pool_data03.dbf
POOL_DATA /u03/ora11g/oradata/TEST01/pool_data01.dbf
POOL_DATA /u03/ora11g/oradata/TEST01/pool_data02.dbf
POOL_DATA /u03/ora11g/oradata/TEST01/pool_data04.dbf
POOL_DATA /u03/ora11g/oradata/TEST01/pool_data05.dbf
POOL_DATA /u01/ora11g/pool_data06.dbf
POOL_DATA /u01/ora11g/pool_data07.dbf
11 rows selected.
我們建立一個新的表空間和資料檔案,
SQL> create tablespace test_delete datafile '/u01/ora11g/test_delete.dbf' size 10M;
Tablespace created.
SQL> create user test_delete identified by test_delete default tablespace test_delete quota unlimited on test_delete;
User created.
然後建立一個使用者,在裡面新增一些資料。
grant connect,resource to test_delete;
conn test_delete/test_delete
create table test as select *from all_objects;
create index test_ind on test(object_id);
create table test1 as select *from test where rownum<100;
update test1 set object_name='a' ;
注意最後的一條update語句,我們還沒有做commit操作,所以此時資料還可能沒有寫入資料檔案,從事務的角度來說,這個update還沒有完成。
我們來看看是否能夠恢復所有的資料,包括未提交的事務資料。
在刪除之前,簡單來一個檢查。
SQL> select count(*)from test;
COUNT(*)
----------
5660
SQL> select count(*)from test1 where object_name='a';
COUNT(*)
----------
99
開始手動刪除資料檔案
[ora11g@rac1 fd]$ rm /u01/ora11g/test_delete.dbf
刪除之後嘗試做一個create操作,竟然成功了。
SQL> create table test3 as select *from test1;
Table created.
繼續嘗試一個Update,終於報錯了,得到了期望之中的Ora錯誤。
update test set object_id=1
*
ERROR at line 1:
ORA-01116: error in opening database file 12
ORA-01110: data file 12: '/u01/ora11g/test_delete.dbf'
ORA-27041: unable to open file
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3
這個時候開始考慮使用控制程式碼來檢視對應的資料檔案,
首先使用ps得到dbw對應的程式號。
[ora11g@rac1 proc]$ ps -ef|grep ora_dbw
ora11g 938 1 0 Nov20 ? 00:00:07 ora_dbw0_TEST01
ora11g 7819 5794 0 06:04 pts/0 00:00:00 grep ora_dbw
然後在/proc/938/fd裡面檢視
[ora11g@rac1 proc]$ ll /proc/938/fd
total 0
lr-x------ 1 ora11g dba 64 Nov 21 05:36 0 -> /dev/null
l-wx------ 1 ora11g dba 64 Nov 21 05:36 1 -> /dev/null
lr-x------ 1 ora11g dba 64 Nov 21 05:36 10 -> /dev/zero
lr-x------ 1 ora11g dba 64 Nov 21 05:36 11 -> /dev/zero
lrwx------ 1 ora11g dba 64 Nov 21 05:36 12 -> /u03/ora11g/product/11.2.0/dbhome_1/dbs/hc_TEST01.dat
lr-x------ 1 ora11g dba 64 Nov 21 05:36 13 -> /u03/ora11g/product/11.2.0/dbhome_1/rdbms/mesg/oraus.msb
lr-x------ 1 ora11g dba 64 Nov 21 05:36 14 -> /proc/938/fd
lr-x------ 1 ora11g dba 64 Nov 21 05:36 15 -> /dev/zero
lrwx------ 1 ora11g dba 64 Nov 21 05:36 16 -> /u03/ora11g/product/11.2.0/dbhome_1/dbs/hc_TEST01.dat
lrwx------ 1 ora11g dba 64 Nov 21 05:36 17 -> /u03/ora11g/product/11.2.0/dbhome_1/dbs/lkTEST01
lr-x------ 1 ora11g dba 64 Nov 21 05:36 18 -> /u03/ora11g/product/11.2.0/dbhome_1/rdbms/mesg/oraus.msb
lrwx------ 1 ora11g dba 64 Nov 21 06:05 19 -> socket:[1434598]
l-wx------ 1 ora11g dba 64 Nov 21 05:36 2 -> /dev/null
lrwx------ 1 ora11g dba 64 Nov 21 05:36 256 -> /u03/ora11g/oradata/TEST01/control01.ctl
lrwx------ 1 ora11g dba 64 Nov 21 05:36 257 -> /u03/ora11g/oradata/TEST01/control02.ctl
lrwx------ 1 ora11g dba 64 Nov 21 05:36 258 -> /u03/ora11g/oradata/TEST01/system01.dbf
lrwx------ 1 ora11g dba 64 Nov 21 05:36 259 -> /u03/ora11g/oradata/TEST01/sysaux01.dbf
lrwx------ 1 ora11g dba 64 Nov 21 05:36 260 -> /u03/ora11g/oradata/TEST01/undotbs01.dbf
lrwx------ 1 ora11g dba 64 Nov 21 05:36 261 -> /u02/ora11g/testdata1.dbf
lrwx------ 1 ora11g dba 64 Nov 21 05:36 262 -> /u03/ora11g/oradata/TEST01/pool_data03.dbf
lrwx------ 1 ora11g dba 64 Nov 21 05:36 263 -> /u03/ora11g/oradata/TEST01/pool_data01.dbf
lrwx------ 1 ora11g dba 64 Nov 21 05:36 264 -> /u03/ora11g/oradata/TEST01/pool_data02.dbf
lrwx------ 1 ora11g dba 64 Nov 21 05:36 265 -> /u03/ora11g/oradata/TEST01/pool_data04.dbf
lrwx------ 1 ora11g dba 64 Nov 21 05:36 266 -> /u03/ora11g/oradata/TEST01/pool_data05.dbf
lrwx------ 1 ora11g dba 64 Nov 21 05:36 267 -> /u01/ora11g/pool_data06.dbf
lrwx------ 1 ora11g dba 64 Nov 21 05:36 268 -> /u01/ora11g/pool_data07.dbf
lrwx------ 1 ora11g dba 64 Nov 21 05:36 269 -> /u03/ora11g/oradata/TEST01/temp01.dbf
lrwx------ 1 ora11g dba 64 Nov 21 05:55 270 -> /u01/ora11g/test_delete.dbf (deleted)
lr-x------ 1 ora11g dba 64 Nov 21 05:36 3 -> /dev/null
lr-x------ 1 ora11g dba 64 Nov 21 05:36 4 -> /dev/null
lr-x------ 1 ora11g dba 64 Nov 21 05:36 5 -> /dev/null
lr-x------ 1 ora11g dba 64 Nov 21 05:36 6 -> /dev/null
lrwx------ 1 ora11g dba 64 Nov 21 05:36 7 -> /u03/ora11g/product/11.2.0/dbhome_1/dbs/hc_TEST01.dat
lr-x------ 1 ora11g dba 64 Nov 21 05:36 8 -> /dev/null
lr-x------ 1 ora11g dba 64 Nov 21 05:36 9 -> /dev/null
可以看到控制程式碼的資訊,刪除的資料檔案狀態已經在/proc/xx/fd裡面有所體現了。
這個時候我們手動複製資料檔案到目標目錄。
[ora11g@rac1 fd]$ cp 270 /u01/ora11g/test_delete.dbf
[ora11g@rac1 fd]$
複製完成之後,使用測試使用者來做一些簡單的驗證。發現建立一個新表的操作順利完成了。
SQL> conn test_delete/test_delete
Connected.
SQL> create table test4 as select *from cat;
Table created.
來看看在資料檔案恢復之前的情況。
SQL> select count(*)from test; --資料沒有問題,條數和預期一致。
COUNT(*)
----------
5660
SQL> select count(*)from test1 where object_name='a'; --這個部分,事務已經做了提交。可以說明變更的資料已經寫入了資料檔案。期望應該是0條。
COUNT(*)
----------
99
然後我們來嘗試做資料檔案的恢復。
SQL> conn / as sysdba
Connected.
SQL> alter database datafile '/u01/ora11g/test_delete.dbf' offline;
Database altered.
SQL> recover datafile '/u01/ora11g/test_delete.dbf';
Media recovery complete.
SQL> alter database datafile '/u01/ora11g/test_delete.dbf' online;
Database altered.
來看看資料檔案恢復之後的情況
SQL> select count(*)from test; --資料沒有問題,條數和預期一致。
COUNT(*)
----------
5660
SQL> select count(*)from test1 where object_name='a'; --這個部分,事務已經做了提交。可以說明變更的資料已經寫入了資料檔案。期望應該是0條。
COUNT(*)
----------
99
重新啟動資料庫來看看能否正常啟停。資料的變化情況。
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.
Total System Global Area 313159680 bytes
Fixed Size 2227944 bytes
Variable Size 255852824 bytes
Database Buffers 50331648 bytes
Redo Buffers 4747264 bytes
Database mounted.
Database opened.
SQL> conn test_delete
Enter password:
Connected.
SQL> select count(*)from test; --資料沒有問題,條數和預期一致。
COUNT(*)
----------
5660
SQL> select count(*)from test1 where object_name='a'; --這個部分,事務已經做了提交。可以說明變更的資料已經寫入了資料檔案。期望應該是0條。
COUNT(*)
----------
99
所以透過上面的例子也能夠說明備份重於一切,而且這種恢復還是需要運氣的,不過某正程度來說,有總比沒有好。而且這種恢復也是需要運氣,如果資料庫一開始停掉的話,也無能為力了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8494287/viewspace-1346955/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 無備份恢復各種場景的處理
- 備份與恢復--利用備份的控制檔案恢復
- 備份與恢復系列 十一 控制檔案的備份與恢復
- 資料檔案丟失 無備份 無重啟 通過控制程式碼恢復
- 資料檔案丟失,無備份,無重啟,通過控制程式碼恢復
- 使用舊的控制檔案備份來恢復控制檔案
- 使用備份的控制檔案恢復資料庫資料庫
- RMAN備份恢復之控制檔案的恢復(三)
- RMAN備份恢復之控制檔案的恢復(二)
- RMAN備份恢復之控制檔案的恢復(一)
- 利用備份的控制檔案恢復
- 控制檔案的備份和恢復
- 【備份與恢復】控制檔案的恢復(不完全恢復)
- 【備份恢復】利用 備份控制檔案到指定目錄下的控制檔案 恢復控制檔案
- Oracle備份與恢復【丟失控制檔案的恢復】Oracle
- 【備份恢復】無備份線上恢復非關鍵資料檔案
- java中實現MYSQL的備份和恢復JavaMySql
- 使用RMAN實現異機備份恢復(WIN平臺)
- 【備份恢復】Oracle 資料備份與恢復微實踐Oracle
- 非歸檔無備份下控制檔案丟失的恢復
- 無備份恢復(歸檔模式)模式
- 系統表空間檔案丟失無備份用控制程式碼的辦法恢復
- 【備份恢復】所有控制檔案丟失後 利用trace中的控制檔案備份執行恢復
- 【備份與恢復】恢復受損的複用控制檔案
- 【備份恢復】 控制檔案多路徑
- 備份與恢復--重建控制檔案
- 備份恢復原理的實踐
- 【備份恢復】noarchive模式下使用增量備份恢復資料庫Hive模式資料庫
- innobackupex備份恢復實戰
- 【備份恢復】從備份恢復資料庫資料庫
- 【管理篇備份恢復】備份恢復基礎
- Oracle 11g RAMN恢復-控制檔案的備份和恢復Oracle
- 備份恢復實驗(1)丟失部分控制檔案
- Oracle備份恢復之熱備份恢復及異機恢復Oracle
- Percona XtraBackup 實現全備&增量備份與恢復
- rman備份丟失控制檔案恢復
- 【管理篇備份恢復】rman恢復測試(二) 控制檔案恢復(三)
- 【管理篇備份恢復】rman恢復測試(二) 控制檔案恢復(二)