Oracle使用控制代碼實現特定情境的無備份恢複

來源:互聯網
上載者:User

Oracle使用控制代碼實現特定情境的無備份恢複

在dba的工作中,備份是一切工作的基礎。如果沒有備份,本來很簡單的恢複工作也會難上加難,如果業務資料要求很高,造成資料的丟失或者損壞,就是重大事故了。使用rman備份或者做一個完整的系統級備份也是很重要的,如果在特定的情境下,沒有備份,如果還能恢複,那就太幸運了。

當資料庫中的某個資料檔案誤刪的時候,如果資料庫還沒有重啟的時候,還是能夠做一些工作的。因為檔案對應的控制代碼還沒有釋放。我們可以從裡面找到一個鏡像的備份實現我們的資料恢複。一定注意這種恢複不一定是完全的資料恢複,如果在資料檔案刪除的瞬間,有開啟的事務,那麼這些事務也是提交過的。

--------------------------------------推薦閱讀 --------------------------------------

RMAN 配置歸檔日誌刪除策略

Oracle基礎教程之通過RMAN複製資料庫

RMAN備份策略制定參考內容

RMAN備份學習筆記

OracleDatabase Backup加密 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

所以通過上面的例子也能夠說明備份重於一切,而且這種恢複還是需要運氣的,不過某正程度來說,有總比沒有好。而且這種恢複也是需要運氣,如果資料庫一開始停掉的話,也無能為力了。

 

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.