How to recover data with DUL after table dropped

首先系统情况如下:
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

错误时刻都可能发生,为了数据的安全,为了自己工作饭碗的安全,还是做好备份吧。

Can We Delete $ORCLE_HOME/.patch_storage

问:$ORCLE_HOME/.patch_storage占据了7-8G的空间,能否删除?

答:该目录不能直接删除,但是可以通过opatch命令做一定的清理。

该目录的作用可以参看Metalink Note: 403218.1

该目录中保存着每次Patch涉及到的文件的备份还有local inventory的备份,如果我们要做patch rollback就需要存储在这个目录中的信息,下面几种情况都必须要做Patch Rollback。
1. 某些之前的Patch跟现在需要的Patch冲突,则必须先Rollback之前的Patch。
2. 最新的CPU (Critical Patch Update) Patch总是包含前一版本的Patch内容,因此每次打CPU Patch都会自动做一次前一版本Patch的Rollback。

如何通过opatch命令清理该目录可以参看Metalink Note: 550522.1

在新版的OPatch中,新增了util命令,通过该命令可以清理.patch_storage目录。

具体的命令为:opatch util cleanup

帮助信息:opatch util cleanup -help

$ opatch util cleanup -help
Invoking OPatch 10.2.0.3.4

Oracle Interim Patch Installer version 10.2.0.3.4
Copyright (c) 2007, Oracle Corporation. All rights reserved.

UTIL session

DESCRIPTION
This utility cleans up 'restore.sh,make.txt' files and 'rac,scratch,backup'
directories of the.patch_storage directory of Oracle Home.If -ps option is used,
then, it cleans the above specified areas only for that patch, else for all
patches under ORACLE_HOME/.patch_storage. You will be still able to
rollback patches after this cleanup.

SYNTAX
opatch util cleanup [-invPtrLoc  ]
[-jre  ] [-oh  ]
[-silent] [-force] [-report]
[-ps , this will
be located under ORACLE_HOME/.patch_storage/]

示例:

$ opatch util cleanup
Invoking OPatch 10.2.0.3.4

Oracle Interim Patch Installer version 10.2.0.3.4
Copyright (c) 2007, Oracle Corporation. All rights reserved.

UTIL session

Oracle Home : /home/oracle/10.2.0.3
Central Inventory : /home/oracle/oraInventory
from : /etc/oraInst.loc
OPatch version : 10.2.0.3.4
OUI version : 10.2.0.3.0
OUI location : /home/oracle/10.2.0.3/oui
Log file location : /home/oracle/10.2.0.3/cfgtoollogs/opatch/opatch2008-02-12_10-33-40AM.log

Invoking utility "cleanup"
OPatch will clean up 'restore.sh,make.txt' files and 'rac,scratch,backup' directories.
You will be still able to rollback patches after this cleanup.
Do you want to proceed? [y|n]
y
User Responded with: Y
Size of directory "/home/oracle/10.2.0.3/.patch_storage" before cleanup is 438057972 bytes.
Size of directory "/home/oracle/10.2.0.3/.patch_storage" after cleanup is 198415929 bytes.

UtilSession: Backup area for restore has been cleaned up. For a complete list of files/directories
deleted, Please refer log file.

OPatch succeeded. 
$ 

如果在执行了上述命令之后,还觉得.patch_storage占用了过大的空间,那么可以更进一步的做手工清理。
执行’opatch lsinventory’命令,查看输出,然后手动删除.patch_storage目录中所有不在输出列表中的子目录。

Free Hosting!

Update@2010-1-8
Freehosting计划已经停止新域名申请。

Freehosting计划是为了鼓励大家分享自己的生活学习工作体验,而不是为了提供免费的文件中转站,因此将在近期内做一次入住域名清理,符合以下条件的域名都将被删除。
1. 超过半年没有文章更新。
2. 没有安装wordpress或者其它类似于此的文章发布系统。

对于在Freehosting中的所有Wordpress程序都已经在后台设置了自动更新,在每次Wordpress官方版本更新后会自动更新,目前最新版本是2.9.1,在大多数情况下,自动版本更新不会有任何问题。

请大家对自己发表的文章多做备份,因为这是Free的,因此不会有太多的技术保证,我个人也不承担任何风险,万一由于种种原因导致参加Freehosting计划的站点出现故障,请大家自求多福。 🙂

Update@2009-5-12
已经收到不少份申请,目前我还没有人数限制的考虑,计划总人数如果可以到20个左右,再去考虑是否持续这个计划。
目前已经进入工作状态,因此非周末的晚上恐怕时间较少,所有的申请都会在周末开始做。

请申请者务必先注册一个域名,然后告诉我你喜欢用的或者习惯用的用户名,这个用户名将用于通过ssh登陆远程DH服务器。

关于注册域名,千万别以为我在给万网或者其它什么别的域名服务商拉客户,只是觉得如果你注册了自己的域名花了钱,那么大概可以更督促自己在这份免费的空间里多写一些文章吧。

Free Hosting!
自己一直在用Dreamhost提供的虚拟主机服务,价格在我个人可以接受的范围内,提供了超大的磁盘空间(目前425G)和带宽(目前8.39T)。

Your Account Provides:
425.02 GB Disk (Grows 2 GB / week)
Used: 5 GB (1.1% – Overage 0.01/MB)
8.39 TB BW per Cycle (Grows 40 GB / week)
Used this Cycle: 15.8 GB (0.2% – Overage:
0.10/GB)

这么多的磁盘空间和带宽流量一个人远远用不完,既然租金都已经交了又何苦浪费这些资源呢?
因此决定免费提供主机空间给需要的朋友使用。

1. 如果你是一个愿意记录自己的经验,分享自己的知识的人
2. 如果你已经有一个多人公用的网志空间(比如搜狐,新浪,QQ空间,ITPUB BLOG等),但是你仍然想要一个自己的个性域名
3. 如果你保证自己不会提供大量的上传下载软件服务
4. 如果你熟悉用Wordpress发布网志或者有愿望学习如何使用Wordpress(我可以保证这不会比你在Office里面打字困难多少)

那么你可以给我留言或者给我邮件,我会在自己的Dreamhost主机空间中给你划出一块,让你免费使用。

我可以提供的是:
1. 一个可以使用ssh或者ftp上传文件的主机帐号,最大使用50G磁盘空间,最大使用的磁盘空间根据总人数平均配给(总空间300G),不限带宽
2. 可以帮你免费安装最新的Wordpress
3. 提供给你几乎不限量的MySQL数据库空间

需要你做的:
1. 注册一个属于自己的域名,现在在万网注册.cn域名,第一年只需要35元
2. 联系我,我会全程support你如何将这个域名指向到我划给你的这个空间中

在这个空间里面所有文章或者其他内容所有权都是属于你的。但是这个免费Hosting计划的解释权属于我。

我可以保证的是我不会无缘无故终止服务,即使终止我也不会像“千橡猫扑强迫七龙记玩家将剩余金钱转入千橡运营的另外一款游戏中”这样无耻,会有充足的时间让你转移所有需要转移的数据。当前费用已经交到2010年11月28日。