ITPub博客

首页 > 数据库 > Oracle > Oracle误truncate操作恢复(一)

Oracle误truncate操作恢复(一)

原创 Oracle 作者:龙山游龙 时间:2025-03-05 17:22:56 0 删除 编辑

1 、 truncate 原理介绍

Oracle数据库truncate table时只产生非常少的redo和undo,就实现了清空表数据并降低表HWM的功能。 有兴趣的同学 可以通过10046以及redo dump去分析truncate的整个操作过程 。你会 看到,Oracle truncate table的实质是在不修改数据块的情况下,通过修改segment header的data_object_id,hwm,extent map,aux map等信息来实现清空表的目的 , 其中还涉及数据字典基表以及L1、L2位图块的修改,truncate操作存储数据的数据块没有产生任何redo和undo,但是segment header,位图块,数据字典基表还是会产生redo和undo。

2 、使用备份恢复

( 1)利用逻辑备份恢复;如无特殊需求,只恢复误操作的业务表即可;缺点:恢复出来的数据固定在备份的时间点。有部分数据会丢失。

示例:

nohup impdp \'\/ as sysdba\' directory= datad ir dumpfile=full_db.dmp logfile=impdb.log tables= U1 . TABLE1 , U2 . TABLE2  &

( 2)利用物理备份与归档前滚的方式,恢复到误操作的前几分钟或几秒钟。此需要精确误操作的时间节点,且数据库较大的情况,恢复时间较长 。

示例:

RMAN>   restore controlfile from '/u01/backup/ctl_0gnpvd65_1_1.ctl';                                           

RMAN>   restore database;    

RMAN>   recover database until time '2020-06-22   13:15:24' using backup controlfile;

RMAN>   alter database open resetlogs;

3 、使用闪回恢复

( 1)有物理备库,且备库端开启了全库级别的闪回,保障故障时间在闪回范围内,且有之后的归档日志。

示例:

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

RMAN> flashback database to time = "TO_DATA('2024-10-22 12:34:00','yyyy-mm-dd hh24:mi:ss')";

4 、使用 FY_Recover_Data 恢复

当尝试使用该存储过程包恢复数据,其前提是表数据块未被覆盖。原理:如果我们已经有一套元数据及数据块,然后将被 TRUNCATE的用户数据块的内容取代其用户数据块的内容,是否可以“骗”过Oracle,让它读出这些数据呢?

回顾一下表扫描的过程,这个方法应该是可行的。我们只要想办法构造出一个结构相同、且具有完整元数据信息和格式化了的用户数据块的傀儡表对象,然后将被 TRUNCATE的用户数据块找出,再将其数据内容部分嫁接到傀儡对象的用户数据块,使Oracle以外这是傀儡对象的数据,就能让Oracle扫描并读出数据内容。其原理用图示描述如下:

FY_Recover_Data对于表恢复的支持性如下:

压缩表 

支持 

索引组织表

支持

分区表 

支持  

行链接/行迁移

不支持

标准SQL类型

支持

BLOB/CLOB

支持Store in Row

离线恢复

支持

操作系统平台

全部 

数据库版本

9i以上

 

创建测试数据:

SQL> conn mary/mary

Connected.

SQL> create table mary.test_obj as select * from dba_objects;

Table created.

SQL> select count(*) from mary.test_obj;

  COUNT(*)

----------

     86295

 

误操作模拟:

SQL> truncate table mary.test_obj;

Table truncated.

SQL> select count(*) from mary.test_obj;

  COUNT(*)

----------

         0

SQL> select file_id from dba_extents where segment_name='TEST_OBJ';

   FILE_ID

----------

         4

注:保障新数据已经停止写入,老的数据块没有被覆盖。

 

FY_Recover_Data 包安装:

SQL> @/home/oracle/FY_Recover_Data.pck

 

执行存储过程恢复数据:

EXEC FY_RECOVER_DATA.recover_truncated_table(' 用户 ', ' 表名 ', 数据文件编号 , ' 备份路径 ', ' 数据文件路径 ');

 

使用 FY_Recover_Data 包恢复数据:

SQL> exec fy_recover_data.recover_truncated_table('MARY','TEST_OBJ');

SQL> select count(*) from mary.test_obj$$;

  COUNT(*)

----------

     86295

SQL> insert into mary.test_obj select * from mary.test_obj$$;

86295 rows created.

SQL> commit;

Commit complete.

 

残存清理:

SQL> drop tablespace FY_REC_DATA INCLUDING CONTENTS and datafiles;

Tablespace dropped.

SQL> drop tablespace FY_RST_DATA INCLUDING CONTENTS and datafiles;

Tablespace dropped.

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/30310891/viewspace-3074897/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
传统商业、开源和国产据库领域十从业经验,TB级高并发数据库的管理经验。对于数据库内部原理、体系结构,数据页/块结构原理有着深刻认识;对于数据库新特性、分布式高可用架构和性能调优有着丰富的的实战经验。擅长故障诊断以及数据库异常打开及数据灾难挽救。

注册时间:2015-06-28

  • 博文量
    178
  • 访问量
    334654