案例:部门有一个数据库因为机器无故重启,无法启动,初步判断是系统表空间出问题了。尝试过各种不同手段,均无法修复。后来发现上面只有一个用户的数据,遂想到直接通过AUL工具从数据文件中抽取出整个库。
准备工作:从官网上下载AUL,我用的版本是aul5 http://www.anysql.net/
开始:
aul是收费的,不过单个文件在512M之内的是免费的。我看了一下我的文件,虽然表空间有2G多,但实际数据只有30M左右,所以完全在免费的范围之内。
首先把下载的aul包直接解压,新建一个文本文件,我们配置成recovery.cfg,命名无所谓,主要是里面的内容:
1 0 D:\oracle\oradata\bak\SYSTEM01.DBF
1 0 D:\oracle\oradata\bak\USSD.ORA
1 0 D:\oracle\oradata\bak\USSD.ORA
每行一个数据文件 FILE# RFILE# FILENAME.
FILE#, RFILE#不要求很准确,AUL能帮助我们搞定的;FILENAME一定要准确
SYSTEM01.DBF就是损坏的文件,里面存放着数据库的用户等信息
USSD.ORA就是我们要提取的用户数据信息
运行aul,先贴个设置参数的注释
//oracle 数据块的大小, 可以从参数文件及 show parameter block_size 查看
SET BLOCK_SIZE {2048 | 4096 | 8192 | 16384 | 32768}
//oracle 数据文件所处平台字节设置, windows 下设置 LITTLE
SET BYTE_ORDER {BIG | LITTLE}
//设置恢复的数据文件中列间隔付,采用默认即可
SET FIELD_TAG field_tag
//设置恢复的数据文件中行结束符,采用默认即可
SET RECORD_TAG record_tag
//恢复的数据文件是文本方式的还是DMP格式的
SET OUTPUT_STYLE {TXT | DMP}
//设置字符集,需要和oracle数据库保持一致,中文下为852
SET CHARSET charsetid
//设置字符集,需要和oracle数据库保持一致,中文下为852
SET NLSCHARSET charsetid
//是否进行块检验,建议0 最大限度的恢复数据
SET BLOCK_CHECK {0 | 1}
//CLOB的字节顺序10g以前需要和机器一致windows(LITTLE),10g以后BIG
SET CLOB_EDIAN {BIG | LITTLE}
//LOB中的编码 如果存储中文则需要设置 1 GBK
SET LOB_CONVERT {0:NONE | 1:GBK | 2:UTF8}
//LOB中数据存储位置采用默认0 即可
SET LOB_STORAGE {0:INLINE | 1:FILE | 2:NONE}
首先设置几个参数:
AUL> set charset 852
Current CHARSET is : 0x0354
AUL> set nlscharset 852
Current NLSCHARSET is : 0x0354
AUL> set lob_convert 1
Current LOB_CONVERT is : 1-GBK
AUL> set lob_storage 1
Current LOB_STORAGE is : 1-FILE
Current CHARSET is : 0x0354
AUL> set nlscharset 852
Current NLSCHARSET is : 0x0354
AUL> set lob_convert 1
Current LOB_CONVERT is : 1-GBK
AUL> set lob_storage 1
Current LOB_STORAGE is : 1-FILE
前面两项852表示是GBK编码
特别是最后两项,lob_convert 1 表示clob或者blob里面的中文用gbk表示,这个要看数据库自身的编码来选择,不然lob字段会出现乱码
lob_storage 1 表示用文件来存储lob信息,否则它会写到后续步骤的txt文件里面去,本人这个案例中就没法把clob字段正常导入到库中去了
然后在命令窗口使用命令 open recovery.cfg
AUL> open recovery.cfg
* ts# fno rfn ver bsize blocks filename
- ---- ---- ---- --- ----- ---------- -----------------------------------
Y 0 1 1 02 8192 51200 D:\oracle\oradata\bak\SYSTEM01.DBF
Y 13 12 12 02 8192 65536 D:\oracle\oradata\bak\USSD.ORA
* ts# fno rfn ver bsize blocks filename
- ---- ---- ---- --- ----- ---------- -----------------------------------
Y 0 1 1 02 8192 51200 D:\oracle\oradata\bak\SYSTEM01.DBF
Y 13 12 12 02 8192 65536 D:\oracle\oradata\bak\USSD.ORA
出现上述显示,特别是第一行的Y,表示能够正常读取,N就是有问题了
接下来就是生成所需要的恢复脚本了
AUL> UNLOAD TABLE USER$;
2013-10-09 16:29:57
2013-10-09 16:29:57
AUL> UNLOAD TABLE OBJ$;
2013-10-09 16:30:11
2013-10-09 16:30:11
AUL> UNLOAD TABLE TAB$;
2013-10-09 16:30:21
2013-10-09 16:30:21
AUL> UNLOAD TABLE COL$;
2013-10-09 16:30:33
2013-10-09 16:30:33
2013-10-09 16:29:57
2013-10-09 16:29:57
AUL> UNLOAD TABLE OBJ$;
2013-10-09 16:30:11
2013-10-09 16:30:11
AUL> UNLOAD TABLE TAB$;
2013-10-09 16:30:21
2013-10-09 16:30:21
AUL> UNLOAD TABLE COL$;
2013-10-09 16:30:33
2013-10-09 16:30:33
以上命令会生成基本的用户结构信息
接下来 ussd是数据库用户名
AUL> list table ussd
UNLOAD TABLE ussd.AA TO AA.txt;
UNLOAD TABLE ussd.BB TO BB.txt;
UNLOAD TABLE ussd.CC TO CC.txt;
UNLOAD TABLE ussd.DD TO DD.txt;
UNLOAD TABLE ussd.EE TO EE.txt;
新建一个文本,命名为recovery.txt 把上述显示出来的复制到里面去
然后在命令窗口执行:
AUL> @recovery.txt
等候执行完,看aul里面的文件,是不是多了很多呢。接下来我们就要离开aul了,使用sqlload导入到新建的数据库中去
其中 _sqlldr.ctl结尾的是sqlload的控制文件,_syntax.sql结尾的是建表语句,其他的就是数据文件了,注意出现很多文件夹的那些是clob或者blob的数据文件。
先把表创建好,然后打开cmd窗口,进入到aul目录下,然后敲入命令:
D:\aul>sqlldr ussd/ussd@test control=d:\aul\AA_sqlldr.ctl
这样数据就会导入了,比较不方便的是要一个表一个表建,要是很多表的话就很麻烦了
这样整个数据恢复过程就完成了,aul工具还是很好的,d.c.b.a 确实厉害。