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


 生產上肯定是容易腦袋發熱,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 ;

進行恢復。

 在執行的時候,查看登陸用戶有沒有權限:

select  count(*) from sys.user$; select  count(*) from sys.tab$;  --如果查看不了這些視圖,說明用戶權限不夠,建議用sys,system或者具有dba權限用戶彩操作。

 

 我是用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;

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM