oracle ODU抽取数据

ODU可以直接从数据文件的数据字典中读取数据,可用于以下灾难恢复的场景(这些场景的前提是保证对象所在物理位置没被覆盖):

(1)drop表purge没进回收站

(2)truncate表恢复

(3)delete表恢复(如果undo已经被覆盖、闪回查询无法恢复的情形)

(4)数据库无法open,恢复数据文件中的各对象(但需要保证数据字典完整,如obj$等基表)

(5)表中存在坏块

(6)sys或system包无法使用,使用@?/rdbms/admin/catalog.sql @?/rdbms/admin/catproc.sql @?/rdbms/admin/utlrp.sql 无法恢复

ODU只可以恢复表定义或表数据,其他如括索引、主外键约束、触发器、存储过程、dblink等需要手动创建

1、安装ODU

(1)解压安装包

mv odu_308_linux_x86.tar.tar odu_308_linux_x86.tar.gz

tar -xvf odu_308_linux_x86.tar.gz

得到config.txt(定义数据库的属性,如字符集、字节序、timezone、导出的数据格式(text还是dmp,分别可以用sqlldr和imp导入)等)

control.txt(定义数据文件的位置、文件号、所在表空间号等)

(2)编辑config.txt

byte_order little

block_size  8192

db_timezone -7

client_timezone 8

data_path   data

charset_name UTF8

ncharset_name AL16UTF16

output_format text

delimiter |

lob_storage infile

clob_byte_order little

unload_deleted no

(3)编辑control.txt

set lines 400 pages 9999

col filename for a50

select d.TS#  ts,d.FILE#      fno, d.FILE#      fno, d.NAME       filename,   d.BLOCK_SIZE block_size from v$datafile d order by ts;

cat control.txt

#ts #fno #rfno     filename                                          block_size

0          1          1 /oradata/dr_cc/system01.dbf                              8192

1          2          2 /oradata/dr_cc/sysaux01.dbf                              8192

2          3          3 /oradata/dr_cc/undotbs01.dbf                             8192

4          4          4 /oradata/dr_cc/users01.dbf                               8192

4          5          5 /oradata/dr_cc/users02.dbf                               8192

6          6          6 /oradata/dr_cc/test01.dbf                                8192

6         10         10 /oradata/dr_cc/temp05.dbf                                8192

6          9          9 /oradata/dr_cc/test04.dbf                                8192

8          7          7 /oradata/dr_cc/test02.dbf                                8192

9          8          8 /oradata/dr_cc/audit_data01.dbf                          8192

11         11         11 /oradata/dr_cc/test123.dbf                               8192

12         12         12 /oradata/dr_cc/testcc.dbf                                8192

13         13         13 /dgdata/tab_cc.dbf                                       8192

14         14         14 /dgdata/idx_cc.dbf                                       8192

ODU 并不是从文件号为 1 的数据文件中得到 bootstrap$地址进而得到数据字典,而是从 ODU 控制文件的第一行指定的文件中得到 bootstrap$地址,所以需要将 SYSTEM表空间中的第 1 个数据文件放置于 control.txt 中的第 1 行。否则会得到如下的错误:can not get bootstrap$ address from SYSTEM tablespace

(3)asmdisk.txt配置

如果是asm存储,需要将ASM 磁盘组的所有 ASM 磁盘的设备文件路径及名称添加到asmdisk.txt

0 /dev/mapper/asm-data111

0 /dev/mapper/asm-data121

0 /dev/mapper/asm-data131

2、使用ODU

(1)config.txt和control.txt加载

在config.txt和control.txt所在目录执行 ./odu,会自动加载这两个文件

如果对config.txt修改,需要重新load config config.txt

执行了 load config 命令之后,建议执行一次 open 命令,因为部分参数会影响到 open 命令执行时 Oracle 数据文件的自动识别

(2)获取数据字典

unload dict

(3)恢复truncate表数据

表被 Truncate 之后,表的数据实际上并没有被删除,只是高水位线被缩回到了段头,空间被回收,同时 data object id 增加。使用此命令格式恢复 Truncate 表的数据,关键是需要知道Truncate 之前的 data object id,

如果表之前没有被 Truncate 或 Move 过,其之前的 data object id 应该与 object id 相同,

否则需要通过闪回查询或日志挖掘(logminer)来获取 Truncate之前的 data object id

SQL> select count(*) from test.test_t;

 COUNT(*)

----------

     5000

SQL> truncate table test.test_t;

Table truncated.

SQL> select count(*) from test.test_t;

 COUNT(*)

----------

        0

1. 得到表所在表空间号和文件号

select a.TS#,b.TABLESPACE_NAME,b.FILE_ID,b.RELATIVE_FNO  from  v$tablespace a,dba_extents b where a.name=b.TABLESPACE_NAME and owner='TEST' and SEGMENT_NAME='TEST_T';

或者直接在odu中desc test.test_t,可以得到表空间和数据文件号

2. offline表空间并手动做检查点

alter tablespace test offline;

对于繁忙的库,为了防止数据段被重写,最好将表所在表空间先offline

alter system checkpoint;

手动做检查点,让 ODU 能够读到最新的数据字典数据

3. 重新加载数据字典

因为表是新建的,需要重新 unload dict

4. 扫描数据文件

scan extent tablespace 6 datafile 6 parallel 2;

5. 恢复数据

unload table test.test_t object auto

5000条数据成功导出到data下的txt文件中,自动生成sql(表定义)、txt(数据)、ctl(sqlldr控制文件)

如果上述命令无法恢复,可以dump数据文件的块,得到表原本的data_object_id恢复

unload table test.test_t object data_object_id(truncate表会保留object_id,更新data_object_id,可以利用logmnr得到data_object_id:128158

6. online表空间

alter tablespace test online;

7. sqlldr导入数据

sqlldr test/test control=TEST_TEST_T.ctl

(4)恢复drop purge的表

1. offline表空间并手动做检查点

alter tablespace test offline;

对于繁忙的库,为了防止数据段被重写,最好将表所在表空间先offline

alter system checkpoint;

手动做检查点,让 ODU 能够读到最新的数据字典数据

2. logminor得到data_object_id

查询当前redo

set lines 400 pages 9999

col MEMBER for a50

select v1.status, v1.group#, member from v$log v1, v$logfile v2 where v1.group# = v2.group#;

将redolog加入logmnr

exec dbms_logmnr.ADD_LOGFILE('/oradata/dr_cc/redo02.log');

开始挖掘日志,注意要加上dict_from_online_catalog选项,否则无法得到delete from obj$语句

exec sys.dbms_logmnr.start_logmnr(options=>sys.dbms_logmnr.dict_from_online_catalog);

找到drop此表相关的语句

select to_char(timestamp,'yyyy-mm-dd HH24:mi:ss'),sql_redo from v$logmnr_contents where operation='DDL' and lower(sql_redo) like '%test_drop%';

 select to_char(timestamp,'yyyy-mm-dd HH24:mi:ss'),sql_redo from v$logmnr_contents where to_char(timestamp,'yyyy-mm-dd hh24:mi:ss')='2021-03-17 21:57:58' and lower(sql_redo) like 'delete%sys%obj$%'  ;

所以test_drop的data_object_id为128170

3. 重新加载数据字典

因为表是新建的,需要重新 unload dict

4. 扫描全部数据文件

如果不知道原表在哪个表空间,可以扫描全部数据文件

scan extent parallel 2

或者scan extent tablespace 6 parallel 2

5. 恢复表

由于我们不知道表的列名和类型,需要用sample抽样来自动判断数据的类型

unload  object 128170 sample

会生成data/sample.txt(数据类型)和ODU_0000128170.txt(表数据)

利用COMMAND:来恢复表结构

此时会生成ctl、sql、txt文件,但ODU_0000128170.sql文件的表名和列名都不是实际名字,可以手动修改为原来的表名(如果知道原来的建表语句,可以直接sqlldr数据即可,无需用生成的sql建表)

如果使用sqlldr的ctl的话,需要修改下ctl'中指定的表名

6. online表空间

(5)恢复一个有坏块的表

如果一个表有坏块,查询的时候会报错,导致整个表无法访问,我们可以通过odu抽取好的部分数据,恢复表

1. bbed构造坏块

alter system flush buffer_cache;

select * from test_partition2;

2. 停掉数据库

因为此坏块属于system数据文件,system表空间无法offline,只能将库停掉恢复

shutdown immediate

3. 加载数据字典

unload dict

desc sys.test_partition2

4. 加载此表数据

unload table sys.test_partition2

可以看出odu会跳过坏块,只加载好的数据(原来有10001条)

5. 恢复表

原表是分区表,但是恢复的sql却是普通表,所以我们不用恢复出的sql建表,而是直接truncate原表,然后再sqlldr加载

启动数据库

truncate table sys.test_partition2;

sys的表只能用

sqlldr "'/ as sysdba'" control=SYS_TEST_PARTITION2.ctl

(6)恢复用户(若系统表空间被损坏,但obj$可用,但库无法使用)

drop user test cascade;

1. offline表空间,非必须,可以将监听停掉,防止新的写入

2. 加载数据字典

unload dict

3. 得到所有用户

list user

4. 得到要恢复用户test的所有表

list table test

5. 恢复用户

unload user test

生成的dmp文件的格式为‘用户_表名.dmp’

只能恢复表和数据,不能恢复index、procedure、sequence等

6. imp恢复表和数据

imp "'/ as sysdba'" file=TEST_TEST_PARTITION.dmp      fromuser=test touser=test1

imp "'/ as sysdba'" file=TEST_TEST_PK.dmp             fromuser=test touser=test1

imp "'/ as sysdba'" file=TEST_TEST2.dmp               fromuser=test touser=test1

imp "'/ as sysdba'" file=TEST_TEST1.dmp               fromuser=test touser=test1

imp "'/ as sysdba'" file=TEST_TEST_RECYCLEBIN.dmp     fromuser=test touser=test1

如果恢复到新建的库,需要新建表空间、用户(密码最好设置为原来的值),赋权等

如果表多的话,可以参考以下脚本:

ls * >> all.txt

cat /data01/dmp/all.txt | while read datafile

do

user=`echo $datafile |cut -d "_" -f1`

pass=`echo ${user,,}`

imp $user/$pass file=${datafile} FULL=y

done

7. online表空间或开启监听

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值