查看: 38834|回复: 0

[Oracle数据库] oracle从dbf文件中恢复数据(通过AUL工具实现)

发表于 2013-10-14 20:49:30
游戏辅助AD


适用的情况
数据库彻底崩溃,只剩下tablespace对应的dbf文件。当然,如果有SYSTEM01.DBF文件的话,恢复起来会更方便。

准备工作


下载AUL5(内含程序及官方指南),当然,你也可以从AUL的官网下载最新版本
找到system01.dbf以及目标用户的dbf文件,比如我的都在E:appAdministratororadataorcl目录下。
为了阐述方便,我们假设目标用户为gz,其tablespace为gz_sp,对应的dbf文件为gz_sp.dbf

SYSTEM01.DBF文件尚在的情况

简单地科普一下,用户gz的若干表,分为两块内容,一是表结构(字段名、字段类型、表名、约束等等),全部保存在SYSTEM01.DBF文件中,而gz_sp.dbf文件中只保存赤裸裸的数据。因此,如果SYSTEM01.DBF尚在,恢复起来是非常方便的,完全是傻瓜式操作,步骤如下:


   建立配置文件
  • 在aul5b_trial.exe所在目录下,建立一个文本文档,填入如下格式的内容,数字无所谓,关键是后面的路径。最后,文件命名为auldemo.cfg。
  • 运行aul5b_trial.exe,输入以下命令。从而载入DBF文件,并读取用户、表结构等信息。
    1. open auldemo.cfg;
    2. UNLOAD TABLE USER$;
    3. UNLOAD TABLE OBJ$;
    4. UNLOAD TABLE TAB$;
    5. UNLOAD TABLE COL$;
    复制代码
  • 生成并执行恢复脚本。输入
    [list table 用户名]命令后,将会输出恢复各个表所需要的脚本。
    1. AUL> LIST TABLE gz
    2. --以下内容为控制台输出的结果
    3. UNLOAD TABLE gz.DEPT TO DEPT.txt;
    4. UNLOAD TABLE gz.EMP TO EMP.txt;
    5. UNLOAD TABLE gz.BONUS TO BONUS.txt;
    复制代码
    此时,你可以直接在AUL的命令行窗口中输入所需恢复表对应的脚本,也可以将多个脚本复制下来,粘贴到一个文本文档中,以便批量执行。假如,我们把上面输出的四行脚本都保存在cmds.txt文件中,批量执行的方法如下:
    1. AUL> @cmds.txt--本质上,等价于若干句 AUL>  UNLOAD TABLE gz.BONUS TO BONUS.txt;
    复制代码
  • 数据恢复。对于每一张待恢复的表,都会生成3个文件,形如BONUS.txt,BONUS_syntax.sql,BONUS_sqlldr.ctl,txt文本中存放了纯数据,sql文本中存放的是建表语句,ctl文件用于最终将数据导入数据库。打开cmd窗口,借助于Oracle 自带的sqlldr 工具,执行如下命令即可:其中gz为用户名,123456为密码,最后为aul生成的ctl文件。
    1. C:>sqlldr gz/123456 control=BONUS_sqlldr.ctl
    复制代码

SYSTEM01.DBF文件丢失的情况
这种情况相对而言就比较悲剧了,没有system01.dbf,无法获取详细、精确的表结构,就只能根据从gz_sp.dbf解析出来的数据来猜测了。虽然比较麻烦,但只要掌握一些技巧,还是可以很快找到数据的。步骤如下:


  • 根据纯数据获取表信息。与上一段落的方法类似,建立auldemo.cfg文件,只不过其中少一行system01.dbf的信息。open命令后,再执行scan命令,解析(猜测)表结构
    1. AUL> open auldemo.cfg
    2. AUL> scan table to scan_table.log
    复制代码
  • 从scan_table.log文件中,寻找恢复命令。大体上,对于每一个表,都会生成下述格式的内容,"cmd:"后面的为恢复脚本。其中,最有价值的是COLUMN后面的一串内容,它是AUL根据数据的形式猜测的字段类型,通过这个,我们大体上可以排查出我们想要恢复的那张表。
    1. Column Count=6CMD:UNLOAD OBJECT 9980 CLUSTER 0 COLUMN  VARCHAR NUMBER NUMBER VARCHAR DATE NUMBER
    复制代码
    针对上述情况,我们大体可以猜出这是一张6列内容的表,并且表结构大体上类似于 VARCHAR NUMBER NUMBER VARCHAR DATE NUMBER,当然,这不是绝对的,比如binary_float可能就无法被正确解析出来,所以仅供参考。根据字段数量及其类型,找出想要恢复的表对应的脚本后,逐一执行。
    1. UNLOAD OBJECT 9980 CLUSTER 0 COLUMN  VARCHAR NUMBER NUMBER VARCHAR DATE NUMBER to tableName.txt
    复制代码
    tableName.txt中,每行一条表记录,用|隔开,形式如下:
    1. aaa|3333|333|aaaaaaaa|2013-02-17 11:24:03|3
    2. bbb|4444|44|bbbbbbb|2013-02-17 11:24:03|4
    复制代码
    当然,这些字段的类型可能会猜错,导致部分内容是乱码,此时,手动修改UNLOAD命令后面的一串字段类型即可。然后,手写ctl文件并执行,方法参考上一段落的步骤4。虽然很麻烦,但是,宝贵的数据总归能大部分都找回来了。
其他注意事项AUL并非完全的免费软件,免费版的每个文件只能读取最前面的512MB 内容。具体请参考“准备工作”中附件里的官方手册。
最后,笔者对于oracle数据库也只是会简单地应用,理解并不深入,阐述中谬误在所难免,欢迎指出。



回复

使用道具 举报