oracle truncate table recover(oracle 如何拯救誤操作truncate的表)

翰墨文海發表於2020-11-03

 生產上肯定是容易腦袋發熱,truncate一張表,立馬的心跳加速,眼神也不迷糊了,搞錯了,完了……

那麼,truncate表後,能不能進行恢復?

truncate操作是比較危險的操作,不記錄redo,也不能通過閃回查詢來找回資料,但是只要段所佔用的塊沒有全部被重新佔用的情況下,我們還是可以通過一些特殊的辦法來找回truncate掉的資料,因為當Truncate命令發起之後,Oracle實際上並沒有在刪除底層資料塊上的資料,而是要等到重用的時候才會把這一部分資料回收,於是這給了我們一個能夠恢復資料庫的機會。

所以當truncate 表後,需要立馬的進行恢復,當尤其是生產上表空間不太夠的情況,或者是業務比較繁忙的情況,不一定能夠完全恢復truncate表的資料,所以時間就是金錢,理論上也不太可能把業務資料的表空間設定成read only狀態,所以,儘快進行恢復操作;

 

1.ORACLE官方上是dul能夠進行資料抽取

DUL Data Unloader 的縮寫,是一個荷蘭的Oracle 工程師開發的,他的名字為Bernard Van DuijnenDUL 是一個開發的小程式,編譯後整個程式只有一個檔案,大小也不過幾百 KB,它工作時不需 Oracle RDBMS 以及任何的Oracle 的程式、元件,它可以直接從一個壞了資料庫的資料檔案中讀取資料,生成IMP SQL*Loader 可以識別的檔案。

DUL 不是一個商用化的產品,Oracle 不賣、不提供也不支援它的使用。DUL 只有在Oracle 的內部網站才可以下載到,因此也只有Oracle Supporter 才能下載到有這個工具 

 

2.FY_Recover_Data.zip 儲存過程恢復

  如果我們已經有一套後設資料及資料塊,然後將被TRUNCATE的使用者資料塊的內容取代其使用者資料塊的內容,是否可以“騙”過Oracle,讓它讀出這些資料呢?

回顧一下表掃描的過程,這個方法應該是可行的。我們只要想辦法構造出一個結構相同、且具有完整後設資料資訊和格式化了的使用者資料塊的傀儡表物件,然後將被TRUNCATE的使用者資料塊找出,再將其資料內容部分嫁接到傀儡物件的使用者資料塊,使Oracle以外這是傀儡物件的資料,就能讓Oracle掃描並讀出資料內容。其原理用圖示描述如下:

 

 

下載地址:

 

http://www.hellodba.com/Download/FY_Recover_Data.zip

 

3.gDUL(這個後面再做測試)

  • 完整支援多種格式匯出,包括expdp,exp,text格式。目前市面上的類dul工具只有gDUL支援expdp格式。

  • 支援ASM檔案系統,並內建asmcmd命令。

  • 支援絕大多數列型別,支援常見的NUMBER,CHAR, VARCHAR2, DATE,LOB, LONG等型別。

  • 支援主流硬體平臺(HP-UX,AIX, Solaris, Linux, Windows),各個平臺僅需單一的可執行檔案,方便分發。

  • 重點是——永久免費使用,無需額外費用,不開源。

gdul完全就是破解了dul,兩者想差不大,底層原理都一樣,下載地址:https://pan.baidu.com/s/1c1yrbkW#list/path=%2F

4.其他收費的資料抽取的工具就多了,比如odl,PRM-DUL,AUL/mydul

 

FY_Recover_Data.pck恢復truncate的表

 

可以參考案例:

http://www.hellodba.com/reader.php?ID=190&lang=CN

 環境:oracle 19c

linux 7.6

恢復要求:FY_Recover_Data.pck支援windows和linux truncate表操作,

1.oracle有完整後設資料資訊,系統表空間不能有問題。

2.執行的時候需要有dba許可權的使用者執行(最好是sys使用者,如果發現包狀態異常,那就是許可權過小,不能訪問一些檢視和系統表

3.大寫(作者沒有整合大小寫,恢復的時候,輸入的物件名和使用者都是要大寫)

4.linux測試完恢復(tmp下有表空間的資料檔案,如果不用的話,建議刪除fy_rec_Data,fy_rst_data)表空間,不然伺服器重啟,資料庫起不起來(臨時檔案被清理了)

 

create table TEST_OBJ as select * from dba_objects;

insert into  TEST_OBJ  select * from dba_objects;

 insert into  TEST_OBJ  select * from dba_objects;

 insert into  TEST_OBJ  select * from TEST_OBJ ;

commit;

 

 

 

 

檢視這個包:

tow表示需要恢復的表的所有者(本次測試為SYS),ttb為表的名稱,fbks表示恢復表中要填寫的塊號(可選也可不填),後面臨時表空間,和離線檔案都預設為空;

truncate table TEST_OBJ ;

進行恢復。

 

 我是用plsql develop

 開啟FY_Recover_Data包,執行裡面的儲存過程recover_truncated_table;

plsql 命令列執行:exec fy_recover_data.recover_truncated_table('SYS','TEST_OBJ');

 記住了,一定要是大寫,表名和使用者名稱.


14:01:05: Use existing Directory Name: FY_DATA_DIR
14:01:05: Recover Table: SYS.TEST_OBJ$
14:01:05: Restore Table: SYS.TEST_OBJ$$
14:01:09: Copy file of Recover Tablespace: FY_REC_DATA_COPY.DAT
14:01:09: begin to recover table SYS.TEST_OBJ
14:01:09: Use existing Directory Name: TMP_HF_DIR
14:01:09: Recovering data in datafile /u01/app/oracle/oradata/TEST19C/datafile/o1_mf_system_hnz0bpfm_.dbf
14:01:09: Use existing Directory Name: TMP_HF_DIR
14:04:07: 15550 truncated data blocks found. 
14:04:07: 919872 records recovered in backup table SYS.TEST_OBJ$$
14:04:07: Total: 15550 truncated data blocks found. 
14:04:07: Total: 919872 records recovered in backup table SYS.TEST_OBJ$$
14:04:07: Recovery completed.
14:04:07: Data has been recovered to SYS.TEST_OBJ$$

 恢復出來了,如果被truncate表資料量很大,恢復時間比較久。

 

 insert into TEST_OBJ select * from SYS.TEST_OBJ$$;

commit;

 

 

 

tmp下有表空間的資料檔案,如果用完了的話,建議刪除fy_rec_Data,fy_rst_data表空間。


drop tablespace fy_rec_data including contents and datafiles;

drop tablespace fy_rst_data including contents and datafiles;

下次需要恢復的時候建兩個表空間就好了。

 

相關文章