通過控制程式碼恢復Linux下誤刪除的資料庫資料檔案

wuweilong發表於2015-08-26

環境介紹:

OS:Redhat EnterPrise 5.4
DB:Oracle EnterPrise Database 11gR2(11.2.3.0)


       在資料庫正常執行時,運維人員在無意中將部分資料檔案刪除了,此時資料庫管理員並不知道,且資料庫執行正常,並沒有立即丟擲錯誤和告警;但是開發人員在對某張表進行更新的時候,正好這張表在被刪除的資料檔案中,報出ORA-01110和ORA-27041錯誤。隨即資料庫管理人員來看現象,發現有一個檔案已經從系統層面刪除了,並且資料庫資料庫沒有進行重啟操作,所以在沒有進行更新的時候業務並沒有造成影響。

非常幸運的是,在資料檔案刪除的情況下,資料庫沒有重啟,使得這次的恢復變的較為簡單,基於這次的恢復,我在我得實驗裝置上進行了重演,記錄了完整的資料檔案刪除和恢復的完整步驟,如下:


一、準備測試環境,建立新的表空間及資料檔案:

  1. SQL> create tablespace woo datafile
  2.   2 '/u01/app/oracle/oradata/PROD1/woo01.dbf'
  3.   3 size 20m autoextend on;

  4. Tablespace created.

  5. SQL> select name from v$dbfile;

  6. NAME
  7. --------------------------------------------------------------------------------
  8. /u01/app/oracle/oradata/PROD1/users01.dbf
  9. /u01/app/oracle/oradata/PROD1/undotbs01.dbf
  10. /u01/app/oracle/oradata/PROD1/sysaux01.dbf
  11. /u01/app/oracle/oradata/PROD1/system01.dbf
  12. /u01/app/oracle/oradata/PROD1/example01.dbf
  13. /u01/app/oracle/oradata/PROD1/tools.dbf
  14. /u01/app/oracle/oradata/PROD1/test.dbf
  15. /u01/app/oracle/oradata/PROD1/woo01.dbf

  16. 8 rows selected.

二、模擬故障,在系統級別刪除資料檔案:

  1. SQL> !rm -rf /u01/app/oracle/oradata/PROD1/woo01.dbf

三、檢查資料庫狀態,並且建立測試資料

  1. SQL> !tail -100f /u01/app/oracle/diag/rdbms/prod1/PROD1/trace/alert*

  2. Wed Aug 26 14:31:01 2015
  3. create tablespace woo datafile
  4. '/u01/app/oracle/oradata/PROD1/woo01.dbf'
  5. size 20m autoextend on
  6. Completed: create tablespace woo datafile
  7. '/u01/app/oracle/oradata/PROD1/woo01.dbf'
  8. size 20m autoextend on

  9. #在這裡我們可以看到資料檔案在系統層面被刪除之後資料庫並沒產生告警。


  10. SQL> create table test tablespace woo as select * from dba_users;
  11. create table test tablespace woo as select * from dba_users
  12.                                                   *
  13. ERROR at line 1:
  14. ORA-01116: error in opening database file 8
  15. ORA-01110: data file 8: '/u01/app/oracle/oradata/PROD1/woo01.dbf'
  16. ORA-27041: unable to open file
  17. Linux Error: 2: No such file or directory
  18. Additional information: 3


  19. #而使在我們需要往這個刪除的檔案中寫入資料的時候才發現資料檔案被刪除了。

  20. SQL> !tail -50 /u01/app/oracle/diag/rdbms/prod1/PROD1/trace/alert*

  21. Wed Aug 26 14:34:33 2015
  22. Errors in file /u01/app/oracle/diag/rdbms/prod1/PROD1/trace/PROD1_smon_9564.trc:
  23. ORA-01116: error in opening database file 8
  24. ORA-01110: data file 8: '/u01/app/oracle/oradata/PROD1/woo01.dbf'
  25. ORA-27041: unable to open file
  26. Linux Error: 2: No such file or directory
  27. Additional information: 3
  28. Wed Aug 26 14:34:33 2015
  29. Checker run found 1 new persistent data failures
  30. Wed Aug 26 14:39:44 2015
  31. Errors in file /u01/app/oracle/diag/rdbms/prod1/PROD1/trace/PROD1_m000_14015.trc:
  32. ORA-01116: error in opening database file 8
  33. ORA-01110: data file 8: '/u01/app/oracle/oradata/PROD1/woo01.dbf'
  34. ORA-27041: unable to open file
  35. Linux Error: 2: No such file or directory
  36. Additional information: 3


  37. SQL> select instance_name,status from v$instance;

  38. INSTANCE_NAME STATUS
  39. ---------------- ------------
  40.         PROD1 OPEN                                     #即便資料庫已經知道了資料庫檔案丟失,因為不是系統表空間的資料檔案,所以資料庫的執行並沒有收到影響。

四、查詢資料檔案

        因為資料庫並沒有停止執行,這個時候我們可以通過dbwr寫資料檔案程式來找到程式控制程式碼號,進入該控制程式碼號就可以找到該程式鎖定的相關資料檔案了。


  1. SQL> !ps -ef|grep dbw|grep -v grep
  2. oracle 9554 1 0 07:16 ? 00:00:01 ora_dbw0_PROD1

  3. #我們可以看到程式的ID為9554,通過程式ID查詢到程式下鎖定的所有檔案
  4. SQL> !ls -rtl /proc/9554/fd

  5. [oracle@edbjr2p1 trace]$ ls -rtl /proc//9554/fd
  6. total 0
  7. lr-x------ 1 oracle oinstall 64 Aug 26 14:37 0 -> /dev/null
  8. lr-x------ 1 oracle oinstall 64 Aug 26 14:37 9 -> /dev/null
  9. lr-x------ 1 oracle oinstall 64 Aug 26 14:37 8 -> /u01/app/oracle/product/11.2.0/dbhome_1/bin/oracle
  10. lr-x------ 1 oracle oinstall 64 Aug 26 14:37 7 -> /dev/null
  11. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 6 -> /u01/app/oracle/product/11.2.0/dbhome_1/hpatch/orapatchPROD1.cfg
  12. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 5 -> /u01/app/oracle/product/11.2.0/dbhome_1/dbs/hc_PROD1.dat
  13. lr-x------ 1 oracle oinstall 64 Aug 26 14:37 4 -> /dev/null
  14. lr-x------ 1 oracle oinstall 64 Aug 26 14:37 3 -> /dev/null
  15. l-wx------ 1 oracle oinstall 64 Aug 26 14:37 2 -> /dev/null
  16. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 19 -> /u01/app/oracle/product/11.2.0/dbhome_1/hpatch/orapatchPROD1.cfg
  17. lr-x------ 1 oracle oinstall 64 Aug 26 14:37 18 -> /proc/9554/fd
  18. lr-x------ 1 oracle oinstall 64 Aug 26 14:37 17 -> /u01/app/oracle/product/11.2.0/dbhome_1/rdbms/mesg/oraus.msb
  19. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 16 -> /u01/app/oracle/product/11.2.0/dbhome_1/dbs/hc_PROD1.dat
  20. lr-x------ 1 oracle oinstall 64 Aug 26 14:37 15 -> /u01/app/oracle/product/11.2.0/dbhome_1/bin/oracle
  21. lr-x------ 1 oracle oinstall 64 Aug 26 14:37 14 -> /dev/zero
  22. lr-x------ 1 oracle oinstall 64 Aug 26 14:37 13 -> /dev/zero
  23. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 12 -> /u01/app/oracle/product/11.2.0/dbhome_1/hpatch/orapatchPROD1.cfg
  24. lr-x------ 1 oracle oinstall 64 Aug 26 14:37 11 -> /dev/null
  25. lr-x------ 1 oracle oinstall 64 Aug 26 14:37 10 -> /dev/null
  26. l-wx------ 1 oracle oinstall 64 Aug 26 14:37 1 -> /dev/null
  27. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 268 -> /u01/app/oracle/oradata/PROD1/woo01.dbf (deleted) //我們找到了這個檔案,處於deleted
  28. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 267 -> /u01/app/oracle/oradata/PROD1/temp2.dbf
  29. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 266 -> /u01/app/oracle/oradata/PROD1/temp1.dbf
  30. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 265 -> /u01/app/oracle/oradata/PROD1/temp01.dbf
  31. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 264 -> /u01/app/oracle/oradata/PROD1/test.dbf
  32. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 263 -> /u01/app/oracle/oradata/PROD1/tools.dbf
  33. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 262 -> /u01/app/oracle/oradata/PROD1/example01.dbf
  34. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 261 -> /u01/app/oracle/oradata/PROD1/users01.dbf
  35. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 260 -> /u01/app/oracle/oradata/PROD1/undotbs01.dbf
  36. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 259 -> /u01/app/oracle/oradata/PROD1/sysaux01.dbf
  37. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 258 -> /u01/app/oracle/oradata/PROD1/system01.dbf
  38. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 257 -> /u01/app/oracle/oradata/PROD1/control02.ctl
  39. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 256 -> /u01/app/oracle/oradata/PROD1/control01.ctl
  40. lr-x------ 1 oracle oinstall 64 Aug 26 14:37 24 -> /u01/app/oracle/product/11.2.0/dbhome_1/rdbms/mesg/oraus.msb
  41. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 23 -> /u01/app/oracle/product/11.2.0/dbhome_1/dbs/lkPROD1
  42. lrwx------ 1 oracle oinstall 64 Aug 26 14:37 22 -> /u01/app/oracle/product/11.2.0/dbhome_1/dbs/hc_PROD1.dat
  43. lr-x------ 1 oracle oinstall 64 Aug 26 14:37 21 -> /u01/app/oracle/product/11.2.0/dbhome_1/bin/oracle
  44. lr-x------ 1 oracle oinstall 64 Aug 26 14:37 20 -> /dev/zero
  45. lrwx------ 1 oracle oinstall 64 Aug 26 15:09 25 -> socket:[173283]

五、將該檔案控制程式碼拷貝到原檔案位置:

  1. SQL> !cp /proc//9554/fd/268 /u01/app/oracle/oradata/PROD1/woo01.dbf

六、對拷貝回來的檔案執行常規的資料恢復操作,實際上也就是更新下資料檔案頭部的scn號:

  1. SQL> col name format a50
  2. SQL> select file#,status,name from v$datafile;

  3.      FILE# STATUS NAME
  4. ---------- ------- --------------------------------------------------
  5.          1 SYSTEM /u01/app/oracle/oradata/PROD1/system01.dbf
  6.          2 ONLINE /u01/app/oracle/oradata/PROD1/sysaux01.dbf
  7.          3 ONLINE /u01/app/oracle/oradata/PROD1/undotbs01.dbf
  8.          4 ONLINE /u01/app/oracle/oradata/PROD1/users01.dbf
  9.          5 ONLINE /u01/app/oracle/oradata/PROD1/example01.dbf
  10.          6 ONLINE /u01/app/oracle/oradata/PROD1/tools.dbf
  11.          7 ONLINE /u01/app/oracle/oradata/PROD1/test.dbf
  12.          8 ONLINE /u01/app/oracle/oradata/PROD1/woo01.dbf     #我們可以看到這個時候該資料檔案是ONLINE狀態

  13. 8 rows selected.


  14. #由於這是一套線上庫,且有其它業務,不可隨意停機,所以這個時候將需要恢復的資料檔案offline,就可以直接線上執行恢復了。

  15. SQL> alter database datafile 8 offline;

  16. Database altered.

  17. SQL> select file#,status,name from v$datafile;

  18.      FILE# STATUS NAME
  19. ---------- ------- --------------------------------------------------
  20.          1 SYSTEM /u01/app/oracle/oradata/PROD1/system01.dbf
  21.          2 ONLINE /u01/app/oracle/oradata/PROD1/sysaux01.dbf
  22.          3 ONLINE /u01/app/oracle/oradata/PROD1/undotbs01.dbf
  23.          4 ONLINE /u01/app/oracle/oradata/PROD1/users01.dbf
  24.          5 ONLINE /u01/app/oracle/oradata/PROD1/example01.dbf
  25.          6 ONLINE /u01/app/oracle/oradata/PROD1/tools.dbf
  26.          7 ONLINE /u01/app/oracle/oradata/PROD1/test.dbf
  27.          8 RECOVER /u01/app/oracle/oradata/PROD1/woo01.dbf #在對資料檔案進行操作,觸發了該檔案,發現檔案頭部的scn不一致,提示需要進行恢復。’

  28. 8 rows selected.

  29. #執行線上恢復並且online該資料檔案。

  30. SQL> recover datafile 8;
  31. Media recovery complete.
  32. SQL> alter database datafile 8 online;

  33. Database altered.

七、驗證資料檔案恢復後是否可以正常使用

  1. SQL> select file#,status,name from v$datafile;

  2.      FILE# STATUS NAME
  3. ---------- ------- --------------------------------------------------
  4.          1 SYSTEM /u01/app/oracle/oradata/PROD1/system01.dbf
  5.          2 ONLINE /u01/app/oracle/oradata/PROD1/sysaux01.dbf
  6.          3 ONLINE /u01/app/oracle/oradata/PROD1/undotbs01.dbf
  7.          4 ONLINE /u01/app/oracle/oradata/PROD1/users01.dbf
  8.          5 ONLINE /u01/app/oracle/oradata/PROD1/example01.dbf
  9.          6 ONLINE /u01/app/oracle/oradata/PROD1/tools.dbf
  10.          7 ONLINE /u01/app/oracle/oradata/PROD1/test.dbf
  11.          8 ONLINE /u01/app/oracle/oradata/PROD1/woo01.dbf

  12. 8 rows selected.

  13. SQL> create table test tablespace woo as select * from dba_users;

  14. Table created.

八、至此完成該資料檔案的恢復



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

相關文章