如何在无备份情况下恢复Oracle中被截断的表

2025-11-05 11:02:19

1、假设被truncate掉的表名字叫做torderdetail_his

SQL> desc ParnassusData.TORDERDETAIL_HIS

 Name                    Null?    Type

 ----------------------- -------- --------------

SEQ_ID                NOT NULL   NUMBER(10)

 SI_STATUS                        NUMBER(38)

 D_CREATEDATE                     CHAR(20)

 D_UPDATEDATE                     CHAR(20)

 B_ISDELETE                       CHAR(1)

 N_SHOPID                         NUMBER(10)

 N_ORDERID                        NUMBER(10)

 C_ORDERCODE                      CHAR(20)

 N_MEMBERID                       NUMBER(10)

 N_SKUID                          NUMBER(10)

 C_PROMOTION                      NVARCHAR2(5)

 N_AMOUNT                         NUMBER(7,2)

 N_UNITPRICE                      NUMBER(7,2)

 N_UNITSELLINGPRICE               NUMBER(7,2)

 N_QTY                            NUMBER(7,2)

 N_QTYFREE                        NUMBER(7,2)

 N_POINTSGET                      NUMBER(7,2)

 N_OPERATOR                       NUMBER(10)

 C_TIMESTAMP                      VARCHAR2(20)

 H_SEQID                          NUMBER(10)

 N_RETQTY                         NUMBER(7,2)

 N_QTYPOS                         NUMBER(7,2)

原本共有 984359条数据

select count(*) from TORDERDETAIL_HIS;

  COUNT(*)

----------

    984359

现在由于被工作人员误操作truncate了该表,所以直接查询会显示0条记录

select count(*) from TORDERDETAIL_HIS;

  COUNT(*)

----------

    0

2、启动PRM,在Windows平台上是  点击prm.bat 脚本, 在Linux/Unix平台上执行prm.sh ,启动后会显示PRM图形化主界面。并选择 Tools =>  Recovery Wizard

如何在无备份情况下恢复Oracle中被截断的表

3、点击Next

如何在无备份情况下恢复Oracle中被截断的表

4、如果该数据库采用了ASM存储则选择 Dictonary Mode(ASM),否则若使用文件系统或裸设备存放数据文件则选择Dictonary Mode

如何在无备份情况下恢复Oracle中被截断的表

5、我们要选择几个参数 : 包括Endian 字节序和DB NAME

由于ORACLE数据文件在不同的操作系统平台上采用了不同的Endian字节序格式,字节序和平台对应列表如下:

Solaris[tm] OE (32-bit) Big

Solaris[tm] OE (64-bit) Big

Microsoft Windows IA (32-bit) Little

Linux IA (32-bit) Little

AIX-Based Systems (64-bit) Big

HP-UX (64-bit) Big

HP Tru64 UNIX Little

HP-UX IA (64-bit) Big

Linux IA (64-bit) Little

HP Open VMS Little

Microsoft Windows IA (64-bit)  Little

IBM zSeries Based Linux Big

Linux x86 64-bit Little

Apple Mac OS Big

Microsoft Windows x86 64-bit Little

Solaris Operating System (x86) Little

IBM Power Based Linux Big

HP IA Open VMS Little

Solaris Operating System (x86-64) Little

Apple Mac OS (x86-64) Little

 

例如在传统Unix  AIX-Based Systems (64-bit) 、HP-UX (64-bit) 上使用的是Big Endian大端字节序,则这里要选为Big Endian。

如何在无备份情况下恢复Oracle中被截断的表

6、如果你使用Windows或者Linux那么一般就使用默认的Little Endian。

注意事项: 如果你的数据文件是在AIX(即Big Endian的)上生成的,你为了方便而将这些数据文件拷贝到Windows服务器上并使用PRM来恢复数据,那么你仍应当选择其原生的Big Endian格式。

如何在无备份情况下恢复Oracle中被截断的表

7、这里由于我们的数据文件是在Linux x86上所以我们选择Endian为Little,并输入Database name数据库名字(注意这里输入的数据库名仅仅是一个别名,它不代表这个数据库真实的DBNAME,PRM的LICENSE检测机制使用的是真实的DBNAME,而非此处输入的Database Name),并点击Next。

如何在无备份情况下恢复Oracle中被截断的表

8、本步骤需要将被truncate掉的表对应的表空间Tablespace下的数据文件和system表空间的数据文件选出来。

点击Choose Files, 一般我们推荐 如果数据库不大,那么将该库所有的数据文件都选择进来; 如果你的数据库很大,且你了解你的数据表位于哪些数据文件上,则你可以仅仅选择SYSTEM表空间的数据文件(必须!)以及数据所在的数据文件。

注意Choose界面支持Ctrl + A 和Shift等键盘操作:

如何在无备份情况下恢复Oracle中被截断的表

9、之后需要为指定的数据文件指定其Block Size即ORACLE数据块的大小,这里根据实际情况修改即可, 例如你的DB_BLOCK_SIZE是8K,但是部分表空间指定16K作为数据块大小的,仅仅需要为那些不是8k的数据文件修改BLOCK_SIZE即可。

 

这里的OFFSET 参数主要是为了那些采用裸设备存放数据文件的场景,例如在AIX上基于普通VG的LV作为数据文件,则存在4k的OFFSET,需要在此处指定。

如果你恰巧正在使用裸设备数据文件,而又不知道OFFSET到底是多少? 则可以使用$ORACLE_HOME/bin下自带的dbfsize工具查看,如下面的例子高亮部分显示该裸设备具有4K的OFFSET

$dbfsize /dev/lv_control_01

Database file: /dev/lv_control_01

Database file type: raw device without 4K starting offset

Database file size: 334 16384 byte blocks     

 

由于此场景中所有数据文件均为8K的BLOCK SIZE,且基于文件系统所以均没有OFFSET,点击Load

如何在无备份情况下恢复Oracle中被截断的表

10、Load阶段PRM会从SYSTEM表空间中读取ORACLE数据字典信息,并在自带的Derby中自建一个数据字典,这让PRM有能力操作ORACLE数据库中的各种数据。

如何在无备份情况下恢复Oracle中被截断的表

11、Load完成后会在后台输出数据库 字符集和国家字符集等信息:

如何在无备份情况下恢复Oracle中被截断的表

12、Load完成后 PRM界面左侧出现按照数据库用户分组的树形图

点开USERS,可以看到多个用户名,例如用户需要恢复PARNASSUSDATA SCHEMA下的一张表,则点开PARNASSUSDATA,并双击表名:

如何在无备份情况下恢复Oracle中被截断的表

13、由于该TORDERDETAIL_HIS表之前已经被TRUNCATED掉了,所以双击没有显示有数据,此时在表上右键选择Unload truncated data:

如何在无备份情况下恢复Oracle中被截断的表

14、PRM将尝试扫描该表所在表空间并将已经truncated掉的数据抽取出来。

如下图所示从已经被TRUNCATE过的TORDERDETAIL_HIS表中抽取出完整的984359条记录,并存放在提示指定的路径下。

这里还自动生成了将文本数据导入到数据库中使用的SQLLDR 控制文件。

$ cd /home/oracle/prm/prmdata/parnassus_dbinfo_PARNASSUSDATA/

$ ls -l ParnassusData*

-rw-r--r-- 1 oracle oinstall       495 Jan 18 08:31 ParnassusData.torderdetail_his.ctl

-rw-r--r-- 1 oracle oinstall 191164826 Jan 18 08:32 ParnassusData.torderdetail_his.dat.truncated

$ cat ParnassusData.torderdetail_his.ctl

LOAD DATA

INFILE  'ParnassusData.torderdetail_his.dat.truncated'

APPEND

INTO TABLE ParnassusData.torderdetail_his

FIELDS TERMINATED BY ' '

OPTIONALLY ENCLOSED BY '"'

TRAILING NULLCOLS (

"SEQ_ID" ,

"SI_STATUS" ,

"D_CREATEDATE" ,

"D_UPDATEDATE" ,

"B_ISDELETE" ,

"N_SHOPID" ,

"N_ORDERID" ,

"C_ORDERCODE" ,

"N_MEMBERID" ,

"N_SKUID" ,

"C_PROMOTION" ,

"N_AMOUNT" ,

"N_UNITPRICE" ,

"N_UNITSELLINGPRICE" ,

"N_QTY" ,

"N_QTYFREE" ,

"N_POINTSGET" ,

"N_OPERATOR" ,

"C_TIMESTAMP" ,

"H_SEQID" ,

"N_RETQTY" ,

"N_QTYPOS"

)

如何在无备份情况下恢复Oracle中被截断的表

如何在无备份情况下恢复Oracle中被截断的表

15、将数据导入到源表中(注意 ParnassusData强烈建议你修改该SQLLDR控制文件中导入的表名字为一个临时表,这样不会覆盖原环境),且不要使用被truncate掉的表所在的表空间作为存放新数据的表空间。

$ sqlldr control=ParnassusData.torderdetail_his.ctl direct=y

Username:/ as sysdba

//以上使用sqlldr导入了恢复的数据

 

//可以通过minus来对比恢复出来的数据:

select * from ParnassusData.torderdetail_his minus select * from parnassus.torderdetail_his;

no rows selected

测试TRUNCATE用例表与源数据表对比,发现记录完全一致。

说明PRM完整、丝毫不差地恢复了被TRUNCATE表上的记录。

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢