在生产中,极有可能遇到不小心truncate表的情况,truncate表后不会产生日志记录和回滚段空间的使用,不能用闪回恢复。尤其是在没有任何备份的情况下所以恢复起来相当麻烦,虽然在有备份的情况下是可以用rman恢复,但是在生产业务库中,一般是不能轻易停库的,而且为了一张表而关库也会对其它正常的数据产生影响 ,所以这在时间上和空间上都是不可取的。那有没有在不影响数据业务正常运行的情况下去快速恢复表呢,答案是确定的。
truncate原理:
TRUNCATE不会逐个清除用户数据块上的数据,而仅仅重置数据字典和元数据块上的元数据(如存储段头和扩展段图)。也就是说,此时,其基本数据并未被破坏,而是被系统回收、等待被重新分配————因此,要恢复被TRUNCATE的数据,需要及时备份其所在的数据文件。
方法:用存储过程包Fy_Recover_Data 它是利用Oracle表扫描机制、数据嫁接机制恢复TRUNCATE或者损坏数据的工具包,这个包是由行内有影响力的DBA大师黄炜先生通过PLSQL编写的,再这里再次感谢他的无私技术分享。Fy_Recover_Data去本文附近中下载
下面通过oracle数据库中scott用户自带的emp表做测试:
步骤1:先把Fy_Recover_Data包拷贝到oracle相关目录下
步骤2:在scott用户下创建test_emp表:
SQL> conn scott/tiger;
Connected.
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
BONUS TABLE
DEPT TABLE
EMP TABLE
SALGRADE TABLE
SQL> select count(*) from emp;
COUNT(*)
----------
14
SQL> create table test_emp as select * from emp;
Table created.
SQL> select count(*) from test_emp;
COUNT(*)
----------
14
步骤3:用truncate删除test_emp表:
SQL> truncate table test_emp;
Table truncated.
SQL> select count(*) from 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
步骤5:恢复
1)在sys用户下执行存储过程
SQL> @/home/oracle/FY_Recover_Data.SQL
Package created.
Package body created.
2)查看test_emp表在数据文件中的目录
SQL> select file_name from dba_data_files f, dba_tables t where t.owner='SCOTT' and t.table_name='TEST_EMP' and t.tablespace_name = f.tablespace_name;
FILE_NAME
--------------------------------------------------------------------------------
/u03/oracle/oradata/WUTONG/datafile/o1_mf_users_cx3xt940_.dbf
3)通过脚本恢复,可以用sqlplus命令行或者plsql developer执行
declare
tgtowner varchar2(30);
tgttable varchar2(30);
datapath varchar2(4000);
datadir varchar2(30);
rects varchar2(30);
recfile varchar2(30);
rstts varchar2(30);
rstfile varchar2(30);
blksz number;
rectab varchar2(30);
rsttab varchar2(30);
copyfile varchar2(30);
begin
tgtowner := 'SCOTT'; --table owner
tgttable := 'TEST_EMP'; --table name
datapath := '/u03/oracle/oradata/WUTONG/datafile/'; --必须和test.t1表所在的数据文件的目录相同
datadir := 'FY_DATA_DIR'; --oracle中目录的名字,可以修改
Fy_Recover_data.prepare_files(tgtowner, tgttable, datapath, datadir, rects, recfile, rstts, rstfile, blksz);
Fy_Recover_data.fill_blocks(tgtowner, tgttable, datadir, rects, recfile, rstts, 8, tgtowner, tgtowner, rectab, rsttab, copyfile);
Fy_Recover_data.recover_table(tgtowner, tgttable, tgtowner, rectab, tgtowner, rsttab, datadir, datadir, recfile,datadir, copyfile, blksz);
end;
exec Fy_Recover_data.recover_truncated_table('SCOTT','EMP',1,null,null);
以上SQL脚本产生2个表空间(2个数据文件),还有1个copy文件。
4)切换到scott用户下查看会发现多了些不一样以test_emp的表,这时找到相关有数据的表,把数据插入原表test_emp
SQL> conn scott/tiger
Connected.
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
BONUS TABLE
DEPT TABLE
EMP TABLE
SALGRADE TABLE
TEST_EMP TABLE
TEST_EMP$ TABLE
TEST_EMP$$ TABLE
7 rows selected.
SQL> insert into test_emp select * from TEST_EMP$$;
14 rows created.
SQL> commit;
Commit complete.
SQL> select count(*) from test_emp;
COUNT(*)
----------
14
当你看到这一步的时候,说明truncate的表已经完全恢复了,恭喜你数据恢复成功!紧张的压力随之而释放,脸上露出灿烂的笑容和自豪感(做DBA很辛苦,数据库能保持正常运行,DBA在幕后做了大量的工作,有时是不会不被公司其他人理解的。。。。。)
步骤6:恢复数据后,把恢复时产生的2个表空间删除,再删除对应数据文件
SQL> conn / as sysdba
Connected.
SQL> select name from v$datafile;
NAME
--------------------------------------------------------------------------------
/u03/oracle/oradata/WUTONG/datafile/o1_mf_system_cx3xt90z_.dbf
/u03/oracle/oradata/WUTONG/datafile/o1_mf_sysaux_cx3xt930_.dbf
/u03/oracle/oradata/WUTONG/datafile/o1_mf_undotbs1_cx3xt93b_.dbf
/u03/oracle/oradata/WUTONG/datafile/o1_mf_users_cx3xt940_.dbf
/u03/oracle/oradata/WUTONG/datafile/o1_mf_wutong_cx415lcj_.dbf
/u03/oracle/oradata/WUTONG/datafile/FY_REC_DATA.DAT
/u03/oracle/oradata/WUTONG/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/WUTONG/datafile/o1_mf_system_cx3xt90z_.dbf
/u03/oracle/oradata/WUTONG/datafile/o1_mf_sysaux_cx3xt930_.dbf
/u03/oracle/oradata/WUTONG/datafile/o1_mf_undotbs1_cx3xt93b_.dbf
/u03/oracle/oradata/WUTONG/datafile/o1_mf_users_cx3xt940_.dbf
/u03/oracle/oradata/WUTONG/datafile/o1_mf_wutong_cx415lcj_.dbf
然后去操作系统下把对应的数据文件删除即可