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

时间:2024-10-14 00:27:53

1、假设被truncate掉的表名字叫做torderdetail_hisSQL> desc Par荏鱿胫协nassusData.TORDERDETAIL_HISName 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数据文件在不同的操作系统平台上采用了不同的Endia荏鱿胫协n字节序格式,字节序和平台对应列表如下:Solaris[tm] OE (32-bit) BigSolaris[tm] OE (64-bit) BigMicrosoft Windows IA (32-bit) LittleLinux IA (32-bit) LittleAIX-Based Systems (64-bit) BigHP-UX (64-bit) BigHP Tru64 UNIX LittleHP-UX IA (64-bit) BigLinux IA (64-bit) LittleHP Open VMS LittleMicrosoft Windows IA (64-bit) LittleIBM zSeries Based Linux BigLinux x86 64-bit LittleApple Mac OS BigMicrosoft Windows x86 64-bit LittleSolaris Operating System (x86) LittleIBM Power Based Linux BigHP IA Open VMS LittleSolaris Operating System (x86-64) LittleApple 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即OR钽吟篑瑜ACLE数据块的大小,这里根据实际情况修改即可, 例如你的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_01Database file: /dev/lv_control_01Database file type: raw device without 4K starting offsetDatabase 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.ctlLOAD DATAINFILE 'ParnassusData.torderdetail_his.dat.truncated'APPENDINTO TABLE ParnassusData.torderdetail_hisFIELDS 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=yUsername:/ as sysdba//以上使用sqlldr导入了恢复的数据//可以通过minus来对比恢复出来的数据:select * from ParnassusData.torderdetail_his minus select * from parnassus.torderdetail_his;no rows selected测试TRUNCATE用例表与源数据表对比,发现记录完全一致。说明PRM完整、丝毫不差地恢复了被TRUNCATE表上的记录。

© 手抄报圈