Email: service@parnassusdata.com 7 x 24 online support!

使用PRM恢复Oracle数据库中误truncate截断的表数据

使用PRM恢复Oracle数据库中误truncate截断的表数据

 

恢复场景1 误Truncate表的常规恢复

 

D公司的业务维护人员由于误将产品数据库当做测试环境库导致错误地TRUNCATE了一张表上的所有数据,DBA尝试恢复但是发觉最近的备份不可用,导致无法从备份中恢复出该数据表上的记录。 此时DBA决定采用PRM来恢复已经被TRUNCATE掉的数据。

 

由于该环境中 所有数据库文件均是可用且健康的,用户仅需要 字典模式下加载SYSTEM表空间的数据文件以及被TRUNCATED表的数据文件即可,例如:

 

 

 

create table ParnassusData.torderdetail_his1 tablespace users as

select * from parnassusdata.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)

 

 

select count(*) from ParnassusData.TORDERDETAIL_HIS;

 

  COUNT(*)

----------

    984359

 

select bytes/1024/1024 from dba_segments where segment_name='TORDERDETAIL_HIS' and owner='PARNASSUSDATA';

 

BYTES/1024/1024

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

      189.71875

 

 

 

SQL> truncate table ParnassusData.TORDERDETAIL_HIS;

 

Table truncated.

 

SQL> select count(*) from ParnassusData.TORDERDETAIL_HIS;

 

  COUNT(*)

----------

         0

 

 

启动PRM ,并选择 Tools =>  Recovery Wizard

 

 

 

点击Next

 

 

 

在此TRUNCATE场景中并未采用ASM存储,所以仅需要选择 《Dictionary Mode》字典模式即可:

 

 

下一步骤 我们要选择几个参数 : 包括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:

 

 

 

 

否则例如常见的Linux x86-64 、Windows都保持为默认的Little Endian:

 

 

 

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

 

 

 

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

 

 

 

点击Next

 

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

 

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

 

 

 

 

 

 

之后需要为指定的数据文件指定其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

 

 

 

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

 

 

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

 

 

 

 

注意PRM是支持 多语言和ORACLE数据库的多字符集的, 但是前提是实施PRM数据恢复的操作系统要求已经安装了对应的语言包; 例如在Windows操作系统上没有安装中文语言包,但是由于ORACLE数据库字符集是独立于操作系统语言的,即ORACLE数据库的字符集可以为ZHS16GBK字符集,但是操作系统并不支持中文,此场景中不在本服务器上部署的ORACLE客户端并不受影响,可以正确显示数据库中的中文数据。

 

但是使用PRM则要求实施PRM数据恢复的操作系统已经安装了对应的语言包,例如用户要恢复ZHS16GBK的中文字符集数据库,则需要操作系统上已经安装了中文语言包才可以。

 

类似的 在Linux上需要安装fonts-chinese 中文字体包。

 

 

 

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

 

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

 

 

 

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

 

 

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"

)

 

 

将数据导入到源表中(注意 ParnassusData强烈建议你修改该SQLLDR控制文件中导入的表名字为一个临时表,这样不会覆盖原环境)。

 

 

$ 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表上的记录。

 

 

恢复场景2 误Truncate表的DataBridge数据搭桥恢复

 

恢复场景1中我们采用了常规unload+sqlldr的恢复方式; 但实际上ParnassusData原厂更推荐您使用我们精心设计的DataBridge数据搭桥模式。

 

为什么要引入数据搭桥模式呢?

 

•       普通的unload+sqlldr恢复方式意味着要保存一份源数据,一份抽取数据,和一份目标数据,即在恢复过程中可能需要扩容2倍于原来的存储空间,这对于甚至无法腾出备份空间的企业来说十分困难

•       数据搭桥与普通unload+sqlldr模式的最大区别在于,数据搭桥直接从源库中抽取数据并传送到目标数据库中,无需在文件系统上保留一份抽取数据

•       通过数据搭桥传送到目标数据库中的数据本身就是结构化的,可以立即使用SQL语句来验证其完整性和一致性

•       如果数据搭桥的目标数据库库位于异机上,那么源数据库上仅仅做读取操作,读写IO将分布于2台服务器上,PRM恢复的速度将更快

•       如果用户所需要恢复的是Truncate数据的话,那么可以马上搭桥回到源库中,恢复仅仅是鼠标点几下的工作

 

使用数据搭桥模式也十分简便,通常规模式一样,在左侧树形图中点中你需要的表,右键选择DataBridge选项:

 

 

 

首次使用数据搭桥模式时需要先创建目标数据库连接信息,这就和我们在SQLDEVELOPER中创建一个Connection是类似的工作,包括目标数据库的Host、端口、Service_Name以及用户登录信息;注意这里填选的用户信息,将会是稍后数据搭桥使用的目标数据库的User用户,即从源库这里抽取出来的表会传输到目标数据库中此处所指定的用户名下。

 

 

如上述建立了一个G10R25的连接,用户为maclean,对应的oracle Easy Connection连接串为 192.168.1.191:1521/G10R25。

 

 

完成上述数据库连接信息填写后可以点击Test按钮来测试该连接配置是否正确可用,如果返回 “ Connect to db server successfully “则说明连接可用,点击Save按钮保存即可。

 

 

 

Save后进入DataBridge主界面,首先在DB Connection下拉框中选择刚刚加入的Connection G10R25:

 

 

 

此处如果所需用的数据库连接并未在DB connection下拉框中出现,则需要点击DB connection旁的”…”按钮添加DB Connection:

 

 

正确选择DB Connection后可以Tablespace的下拉框将变得可用,选中合适的表空间:

 

 

用户可以选择是否要将从源库传输到目标库的表的表名做映射修改,例如我们在源库中Truncate掉了一张表,现在通过DataBridge将数据恢复回源库中,但是不想使用原来的表名字,如原来的表名为torderdetail_his,现在希望将恢复的数据以别的表名存放,则可以选中“if need to remap table”并填入合适的目标表名,如下图所示:

 

 

 

注意: 1)对于目标库中已经存在对应表名的情况,PRM不会重建表而是会在现有表的基础上插入所需恢复的数据,由于表已经建立了所以指定的表空间将无效  2)对于目标数据库中还不存在对应表名的情况,PRM会尝试在指定表空间上建表并插入恢复数据

 

 

此场景中由于我们是恢复Truncate掉的数据,所以需要选中“if data truncated”选项,否则PRM将以常规模式抽取数据,将无法抽取到已经被Truncate掉的数据。

 

Truncate数据的大致机理是,ORACLE会在数据字典和Segment Header中更新表的Data Object ID,而实际数据部分的块则不会做修改。由于数据字典与段头的DATA_OBJECT_ID与后续的数据块中的并不一致,所以ORACLE服务进程在读取全表数据时不会读取到已经被TRUNCATE但是实际仍未被覆盖的数据。

 

PRM通过自动扫描被TRUNCATE掉数据段头Segment Header后续的数据块智能判断TRUNCATE前数据段的DATA_OBJECT_ID,并根据字典中的表字段定义和自动获得的原始DATA_OBJECT_ID来抽取数据。

 

 

此处还存在一个”if to specify data object id”输入框,该输入框可以让用户指定要恢复的数据的Data Object ID。一般情况下不需要指定任何值,除非你发现恢复Truncate数据不成功时,建议在ParnassusData原厂工程师的帮助下指定该值。

 

 

如上正确完成DataBridge配置后即可证实开始数据搭桥,只需要点击DataBridge按钮即可:

 

 

数据搭桥完成后会显示成功传输的数据行数,以及耗时。