首先系统情况如下:
1. Oracle版本是9.2.0.8,操作系统是IBM AIX
2. 数据文件存储在裸设备上
3. 被删除的表是分区表
4. 数据库非归档,没有任何备份
5. 在误drop table以后,立刻将包含该表的表空间offline了,并且保留了当时的current online redo文件
6. 保留了之前建表时的create脚本
恢复过程如下:
1. DUL使用的init.dul内容:
osd_big_endian_flag=true
osd_dba_file_bits=10
osd_c_struct_alignment=32
osd_file_leader_size=1
osd_word_size=32
control_file=/tmp/control.dul
db_block_size=8192
compatible=9
2. DUL使用的control.dul文件内容
58 58 /somepath/rawdevice1 4096 blocks 4095873
58 110 /somepath/rawdevice2 4096 blocks 639873
58 126 /somepath/rawdevice3 4096 blocks 255873
第1位是TS#,第2位是RFILE#,第3位是数据文件全路径,第4位是在AIX系统中裸设备需要跳过的字节,第5位是数据文件的真实block数(从v$datafile中以size/db_block_size获得)。
第4,5两位在数据文件为裸设备的情况下才需要,否则在scan database时扫描到裸设备结尾的时候,将可能报错。
3. 通过logminer得到被drop掉的表分区的data object id(因为被drop了,因此无法从system数据字典中获得)。如何使用Logminer不在本文范围内。
比如最后看到SQL_REDO字段的结果是类似于这样的输出:
delete from "SYS"."OBJ$" where "OBJ#" = '25514' and "DATAOBJ#" = '25514' ......
那么就可以知道data object id = 25514
4. 登录DUL
DUL> scan database;
DUL> unload table table_name partition(p_name)
(col_name1 VARCHAR2(6),col_name2 VARCHAR2(17),col_name3 VARCHAR2(3).....)
storage (dataobjno 25514);
这里的table_name和p_name其实都可以随便写,甚至不写partition也可以,最主要的是dataobjno必须正确,就可以unload出表数据。当然还必须有表结构,否则会报告无法在OBJ$中找到相应表。
如果此处没有事先保留的create table脚本,而且也不知道表中有哪些字段,那么工作量就大了。
基本步骤如下:
DUL> alter session set use_scanned_extent_map = true;
DUL> scan database;
DUL> scan tables;
然后在dul.log中查找上面的data object id,找到的话,将会是类似于下面的输出:
UNLOAD TABLE OBJNO25514 ( COL001 VARCHAR2(6), COL002 VARCHAR2(17), COL003 VARCHAR2(3)
, COL004 VARCHAR2(26), COL005 VARCHAR2(30), COL006 NUMBER, COL007 NUMBER
, COL008 VARCHAR2(1), COL009 NUMBER, COL010 VARCHAR2(38) )
STORAGE( DATAOBJNO 25514 );
同时为了保险起见,在scan tables的过程中,DUL在log中还显示了该表的前5行记录内容,可以比对一下看看是否确实是被误删除的表。
之后,就是根据对于业务的了解,重新构建表结构了,其实对于只是删除了一张表而言,工作量还可以接受,但是如果是删除了整个USER …
5. 之后就是用sqlldr重新加载数据的事情了,不再赘述。
DUL格言是:Life without DUL
错误时刻都可能发生,为了数据的安全,为了自己工作饭碗的安全,还是做好备份吧。
刚用MyLOG+AUL恢复了一个这样的案例。
@anysql
把MyLOG和AUL开源吧 >:) >:)
被误删除的表是创建在ASSM的表空间上面吗?
alter session set use_scanned_extent_map = true;的作用是什么?
用 DUL和AUL 的过程都很痛苦
kamus,你的头像怎么加进去的?
@overmars
在本例中不是ASSM
作用是在没有数据字典的时候,告诉DUL用每个block自己头部的object id作为unload table的基础。
那尝试用一下老熊的ODU吧,呵呵
@boypoo
参看这篇文章:
https://www.dbform.com/html/2006/76.html
刚看了一下ODU, 命令语法和AUL差不多啊.
@anysql
都是一样的unload数据方法,自然命令语法都差不多吧。
我看了一下耿永辉的gDUL,语法也差不多。
你们几个干脆一起做这个产品吧,何苦各自为营,劳动力浪费啊。
除了直接访问ASM没搞定外,其他的都一个人搞定了,所以没想open source.
open source也不是为了解决自己一个人搞不定的技术难题。其实。。。open source是一种生活方式,呵呵。