在數(shù)據(jù)庫運(yùn)維中,相信大家都遇到過truncate表后,又需要找回?cái)?shù)據(jù)的情況。但技術(shù)上因truncate表后不會(huì)產(chǎn)生日志記錄和未生成回滾段,因此不能使用常規(guī)在線方式恢復(fù),當(dāng)然也不能用閃回恢復(fù)。
常用的補(bǔ)救方法有:
1、有備份的情況下可以用rman恢復(fù),但是在生產(chǎn)業(yè)務(wù)庫中,一般不能輕易停庫,而且為了一張表而關(guān)庫也會(huì)對其它正常的業(yè)務(wù)產(chǎn)生影響 ,所以這在時(shí)間上和空間上都是不可取的。
2、檢查誤刪除的表或分區(qū)是否有dmp備份,如有可以從dmp恢復(fù);
那么無備份、無歸檔的情況下TRUNCATE掉的對象,是否還有更加迅捷的方法來恢復(fù)數(shù)據(jù)呢?筆者有位資深DBA朋友通過PLSQL編寫的一個(gè)存儲(chǔ)過程包Fy_Recover_Data,可以在不影響數(shù)據(jù)業(yè)務(wù)正常運(yùn)行的情況下去快速恢復(fù)表。它是利用Oracle表掃描機(jī)制、數(shù)據(jù)嫁接機(jī)制恢復(fù)TRUNCATE或者損壞數(shù)據(jù)的工具包。
Fy_Recover_Data包的工作原理是:構(gòu)造出一個(gè)結(jié)構(gòu)相同、且具有完整元數(shù)據(jù)信息和格式化了的用戶數(shù)據(jù)塊的傀儡表對象,然后將被TRUNCATE的用戶數(shù)據(jù)塊找出,再將其數(shù)據(jù)內(nèi)容部分嫁接到傀儡對象的用戶數(shù)據(jù)塊,使Oracle以為這是傀儡對象的數(shù)據(jù),Oracle就可掃描并讀出數(shù)據(jù)內(nèi)容。
其原理用圖示描述如下:
(Fy_Recover_Data包的工作原理)
以下是Fy_Recover_Data包的詳細(xì)使用操作過程:
(1) 先把Fy_Recover_Data包拷貝到數(shù)據(jù)庫主機(jī)相關(guān)目錄下(oracle用戶)
[oracle@dbaedu1 shsnc]$ ls -lrt -rw-r--r-- 1 oracle oinstall 12888 Apr 7 00:42 FY_Recover_Data.zip [oracle@dbaedu1 shsnc]$ |
(2) 在dbauser用戶下創(chuàng)建test_emp表
SYS@PROD> conn dbauser/####### Connected. DBAUSER@PROD> create table dbauser.test_emp as select * from dba_objects; Table created. DBAUSER@PROD> select count(*) from dbauser.test_emp; COUNT(*) ---------- 86975 |
(3) 用truncate刪除test_emp表
SQL> truncate table dbauser.test_emp; Table truncated. SQL> select count(*) from dbauser.test_emp; COUNT(*) ---------- 0 |
(4) 在linux中的oracle用戶下解壓FY_Recover_Data.zip包
$ unzip FY_Recover_Data.zip Archive: FY_Recover_Data.zip inflating: FY_Recover_Data.SQL [oracle@dbaedu1 shsnc]$ ls -lrt -rw-r--r-- 1 oracle oinstall 79775 Apr 7 00:41 FY_Recover_Data.pck [oracle@dbaedu1 shsnc]$ |
(5) 在sys用戶下執(zhí)行存儲(chǔ)過程
SQL> @/home/oracle/shsnc/FY_Recover_Data.SQL Package created. Package body created. |
(6) 查看test_emp表在數(shù)據(jù)文件中的目錄
select file_name from dba_data_files f, dba_tables t where t.owner=DBAUSER and t.table_name=TEST_EMP and t.tablespace_name = f.tablespace_name; FILE_NAME -------------------------------------------------------------------- /u01/app/oracle/oradata/PROD/users01.dbf |
(7) 通過腳本恢復(fù),可以用sqlplus命令行或者plsqldeveloper執(zhí)行
exec fy_recover_data.recover_truncated_table(DBAUSER,TEST_EMP); |
(8) 切換到DBAUSER用戶下查看會(huì)發(fā)現(xiàn)多了些不一樣以test_emp的表,這時(shí)找到相關(guān)有數(shù)據(jù)的表,把數(shù)據(jù)插入原表test_emp
DBAUSER@PROD> select count(*) from dbauser.test_emp$$; COUNT(*) ---------- 86975 SQL> insert into test_emp select * from TEST_EMP$$; 86975 rows created. SQL> commit; Commit complete. SQL> select count(*) from test_emp; COUNT(*) ---------- 86975 |
(9) 恢復(fù)數(shù)據(jù)后,把恢復(fù)時(shí)產(chǎn)生的2個(gè)表空間刪除,再刪除對應(yīng)數(shù)據(jù)文件
SQL> conn / as sysdba Connected. SQL> select name from v$datafile; NAME -------------------------------------------------------------------------------- /u03/oracle/oradata/datafile/o1_mf_system_xr5ht70z_.dbf /u03/oracle/oradata/datafile/o1_mf_sysaux_xr5ht730_.dbf /u03/oracle/oradata/datafile/o1_mf_undotbs1_xr5ht73b_.dbf /u03/oracle/oradata/datafile/o1_mf_users_xr5ht740_.dbf /u03/oracle/oradata/datafile/o1_mf_biboss_cx415lcj_.dbf /u03/oracle/oradata/datafile/FY_REC_DATA.DAT /u03/oracle/oradata/datafile/FY_RST_DATA.DAT 7 rows selected. SQL>drop tablespace FY_REC_DATA INCLUDING CONTENTS; Tablespace dropped. SQL>drop tablespace FY_RST_DATA INCLUDING CONTENTS; Tablespace dropped. SQL> select name from v$datafile; NAME -------------------------------------------------------------------------------- /u03/oracle/oradata/datafile/o1_mf_system_xr5ht70z_.dbf /u03/oracle/oradata/datafile/o1_mf_sysaux_xr5ht730_.dbf /u03/oracle/oradata/datafile/o1_mf_undotbs1_xr5ht73b_.dbf /u03/oracle/oradata/datafile/o1_mf_users_xr5ht740_.dbf /u03/oracle/oradata/datafile/o1_mf_biboss_cx415lcj_.dbf |
(10)然后去操作系統(tǒng)下把對應(yīng)的數(shù)據(jù)文件刪除即可。
對于使用工具fy_recover_data進(jìn)行數(shù)據(jù)恢復(fù),需要確保:
①truncate之后,需要保證沒有新的數(shù)據(jù)進(jìn)入表中,否則無法還原;
②存放該表的數(shù)據(jù)文件塊不能被覆蓋,否則無法完整還原數(shù)據(jù)。
在發(fā)生故障后,可以迅速使用:
SQL> altertablespace users read only;
SQL> altertablespace users read write;
來關(guān)閉/開啟表空間的寫功能,這樣可以保證數(shù)據(jù)文件不會(huì)被覆寫。
當(dāng)然,最后希望大家永遠(yuǎn)不要用到今天分享的這個(gè)package。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/130144.html
摘要:數(shù)據(jù)庫管理系統(tǒng)的全稱是,簡稱。命令的語法表名數(shù)據(jù)庫約束約束是表上強(qiáng)制執(zhí)行的數(shù)據(jù)校驗(yàn)規(guī)則,約束主要用于保證數(shù)據(jù)庫里數(shù)據(jù)的完整性。 SQL語句是對所有關(guān)系數(shù)據(jù)庫都通用的命令語法,而JDBC API只是執(zhí)行SQL語句的工具,JDBC允許對不同的平臺(tái)、不同的數(shù)據(jù)庫采用相同的編程接口來執(zhí)行SQL語句 關(guān)系數(shù)據(jù)庫基本概念和MySQL基本命令 數(shù)據(jù)庫僅僅是存放用戶數(shù)據(jù)的地方。當(dāng)用戶訪問、操作數(shù)據(jù)庫中...
摘要:數(shù)據(jù)庫管理系統(tǒng)的全稱是,簡稱。命令的語法表名數(shù)據(jù)庫約束約束是表上強(qiáng)制執(zhí)行的數(shù)據(jù)校驗(yàn)規(guī)則,約束主要用于保證數(shù)據(jù)庫里數(shù)據(jù)的完整性。 SQL語句是對所有關(guān)系數(shù)據(jù)庫都通用的命令語法,而JDBC API只是執(zhí)行SQL語句的工具,JDBC允許對不同的平臺(tái)、不同的數(shù)據(jù)庫采用相同的編程接口來執(zhí)行SQL語句 關(guān)系數(shù)據(jù)庫基本概念和MySQL基本命令 數(shù)據(jù)庫僅僅是存放用戶數(shù)據(jù)的地方。當(dāng)用戶訪問、操作數(shù)據(jù)庫中...
閱讀 1356·2023-01-11 13:20
閱讀 1707·2023-01-11 13:20
閱讀 1215·2023-01-11 13:20
閱讀 1906·2023-01-11 13:20
閱讀 4165·2023-01-11 13:20
閱讀 2757·2023-01-11 13:20
閱讀 1402·2023-01-11 13:20
閱讀 3671·2023-01-11 13:20