Oracle的数据恢复处理,有各种方法工具支持,在这方面,我算是一个新手,也是处于不断的学习中。
业界有一些著名的恢复软件,简单罗列一下,
1. Oracle DUL
是Oracle公司内部的数据库恢复工具,由在荷兰的Oracle Support,Bernard van Duijnen开发,需要注意的是,DUL不是Oracle的一个产品,不是一个受Oracle支持的产品。DUL被严格限制为Oracle Support售后支持部门内部使用,其使用在国外需要经过Oracle公司的内部审批,首先你必须购买了Oracle的标准服务PS才可能用到DUL,否则甚至没有资格使用DUL。之所以被严格控制的一个原因是其采用了部分Oracle源代码,所以必须被严格控制。
DUL可以从已经损坏严重的数据库中抽取数据, DUL可以直接扫描Oracle Datafile数据文件,并识别表头块segment header,访问Extent盘区信息,并从中读取实际行数据。后续DUL能生成SQLLDR形式的导入文件,或者EXP格式的DMP文件。如果SYSTEM表空间数据文件还在,那么DUL读取Oracle数据字典。否则DUL采取采用的形式实际读取行,并根据内部算法判断字段类型,字段长度。DUL直接从Oracle Datafile抽取数据,而无需Oracle数据库实例。 DUL兼容ORACLE 6,7,8和9以及10g,11g,12c。
DUL User’s and Configuration Guide V10.2.4.27:
http://www.askmaclean.com/wp-content/uploads/2014/01/DUL-Users-and-Configuration-Guide-V10.2.4.27.pdf
2. Oracle ODU
Oracle Database Unloader,是类似于Oracle DUL的一款恢复软件,他的作者是两位ACED,老熊和dbsnake。ODU用于直接从Oracle数据库的数据文件中获取表数据。在各种原因造成的数据库不能打开时,可用于抢救数据,最大限度地减少数据丢失。ODU软件同样不需要运行Oracle软件,直接读取数据文件解析数据。支持的Oracle数据库版本包括7,8i,9i,10g,11g,12c。其他支持和介绍,可以参考:http://www.oracleodu.com/cn/。
3. PRM-DUL
作者是诗檀软件,Maclean Liu。为了解决ORA-00600、数据库打不开、ASM Diskgroup无法Mount、SELECT报错、硬盘/存储/文件系统故障引起的数据库问题、丢失数据文件。相关介绍,可以参考http://www.parnassusdata.com/oracle-recovery-landing/index.html。
4. AUL(MyDUL)
作者是楼方鑫(d.b.c.a),AUL可以脱离Oracle软件从Oracle数据文件中直接读取数据。如果无法正常启动Oracle数据,并且没有有效备份可供恢复时,例如, 丢失SYSTEM表空间,表被意外删除或Truncate,或数据文件有严重坏块。可以选择AUL(Feature Overview)作为最后的恢复手段,同Oracle提供的恢复服务相比,成本相对较低廉。但目前应该未有更新了。
5. mydul
总体来看,(2)和(3)可以正常使用,但均未收费版本,免费版本有限制,(1)是Oracle内部人员使用,(4)已经不再更新,(5)通用性弱一些。
最近正巧,有一个存在corrupt block的数据文件,尝试使用ODU恢复,趁机学习一下。一些参考资料:
ODU用户手册下载:
http://www.oracleodu.com/soft/ODUUserGuide_cn.pdf
ODU官方链接:
http://www.oracleodu.com/cn/
老熊博客中关于ODU的文章:
http://www.laoxiong.net/category/odu
不同平台版本,可以下载,
http://www.oracleodu.com/cn/download
要运行odu需要一些配置文件,包括如下两个,
1. config.txt配置文件,如下红色字体,为更改了默认的配置,其他配置项采用默认参数,
byte_order little
block_size 8192
block_buffers 1024
db_timezone -7
client_timezone 8
asmfile_extract_path /asmfile
data_path /DATA/oracle/odu
lob_path /odu/data/lob
charset_name US7ASII
ncharset_name AL16UTF16
output_format text
lob_storage infile
clob_byte_order big
trace_level 1
delimiter |
unload_deleted no
file_header_offset 0
is_tru64 no
record_row_addr no
convert_clob_charset yes
use_scanned_lob yes
trim_scanned_blob yes
lob_switch_dir_rows 20000
db_block_checksum yes
db_block_checking yes
rdba_file_bits 10
compatible 11
这两个参数含义,
DATA_PATH
DATA_PATH指定恢复的数据所存储的目录,如果需要恢复的数量量非常大,可以用这个参数值指定一个与ODU软件所在目录不同的路径。注意这个参数指定的目录必须是已经存在的,ODU不会自动创建这个目录。
可以使用相对路径,也可以使用绝对路径。默认值为"data",表示恢复的数据缺省保存在ODU软件所在目录的data子目录中。
在数据恢复时,应该首先估算需要的存储空间用于存储恢复的数据。建议将DATA_PATH设置为单独的容量足够大的文件系统。
COMPATIBLE
用于指定数据库的版本。默认值为10,即10g。这个参数的有效值为Oracle的主版本号,从7至12。
2. control.txt配置文件,为需要进行恢复的数据文件,包括文件编号、表空间号、文件路径、数据块量,等一系列信息,
#ts fno rfno filename block_size is_big_file header_offset blocks
0 1 1 /DATA/oracle/oradata/DATA/system01.dbf
9 12 12 /DATA/oracle/oradata/DATA/data01.dbf
其中#ts、fno这些信息,可以使用如下SQL,得到control.txt需要的数据文件配置,
SQL> SELECT name, file#, ts#, rfile# FROM v$datafile;
/DATA/oracle/oradata/DATA/system01.dbf 1 0 1
/DATA/oracle/oradata/DATA/sysaux01.dbf 2 1 2
/DATA/oracle/oradata/DATA/undotbs01.dbf 3 2 3
/DATA/oracle/oradata/DATA/users01.dbf 4 4 4
...
/DATA/oracle/oradata/DATA/data01.dbf 12 9 12
...
值得注意的是,ODU并不是从文件号为1的数据文件中得到bootstrap$地址进而得到数据字典,而是从ODU控制文件的第一行指定的文件中得到bootstrap$地址。所以,需要将SYSTEM表空间中的第1个数据文件放置于control.txt中的第1行,如下所示,第二行的data01.dbf为需要恢复的文件,
#ts fno rfno filename block_size is_big_file header_offset blocks
0 1 1 /DATA/oracle/oradata/DATA/system01.dbf
9 12 12 /DATA/oracle/oradata/DATA/data01.dbf
如果第一行不是system01.dbf,就会得到如下的错误:
can not get bootstrap$ address from SYSTEM tablespace
执行odu指令,进入操作控制台,可以看出,初始化加载了config.txt,以及control.txt配置文件,
./odu
Oracle Data Unloader trial version 4.1.3
Copyright (c) 2008,2009,2010,2011 XiongJun. All rights reserved.
Web: http://www.oracleodu.com
Email: magic007cn@gmail.com
loading default config.......
byte_order little
block_size 8192
block_buffers 1024
error at line 3.
db_timezone -7
Invalid db timezone:-7
client_timezone 8
Invalid client timezone:8
asmfile_extract_path /asmfile
data_path /DATA/oracle/odu
lob_path /odu/data/lob
charset_name US7ASII
charset name 'US7ASII' not found,will use default charset ZHS16GBK
ncharset_name AL16UTF16
output_format text
lob_storage infile
clob_byte_order big
trace_level 1
delimiter |
unload_deleted no
file_header_offset 0
is_tru64 no
record_row_addr no
convert_clob_charset yes
use_scanned_lob yes
trim_scanned_blob yes
lob_switch_dir_rows 20000
db_block_checksum yes
db_block_checking yes
rdba_file_bits 10
compatible 11
load config file 'config.txt' successful
loading default asm disk file ......
grp# dsk# bsize ausize disksize diskname groupname path
---- ---- ----- ------ -------- --------------- --------------- --------------------------------------------
load asm disk file 'asmdisk.txt' successful
loading default control file ......
ts# fn rfn bsize blocks bf offset filename
---- ---- ---- ----- -------- -- ------ --------------------------------------------
0 1 1 8192 896000 N 0 /DATA/oracle/oradata/DATA/system01.dbf
9 12 12 8192 3840000 N 0 /DATA/oracle/oradata/DATA/data01.dbf
load control file 'control.txt' successful
loading dictionary data......done
loading scanned data......done
使用load config可以重新加载config.txt配置,
ODU> load config
byte_order little
block_size 8192
block_buffers 1024
error at line 3.
db_timezone -7
Invalid db timezone:-7
client_timezone 8
Invalid client timezone:8
asmfile_extract_path /asmfile
data_path /DATA/oracle/odu
lob_path /odu/data/lob
charset_name US7ASII
charset name 'US7ASII' not found,will use default charset ZHS16GBK
ncharset_name AL16UTF16
output_format text
lob_storage infile
clob_byte_order big
trace_level 1
delimiter |
unload_deleted no
file_header_offset 0
is_tru64 no
record_row_addr no
convert_clob_charset yes
use_scanned_lob yes
trim_scanned_blob yes
lob_switch_dir_rows 20000
db_block_checksum yes
db_block_checking yes
rdba_file_bits 10
compatible 11
load config file 'config.txt' successful
执行unload dict加载数据字典信息,
如果忘了指令,随意输入,会有提示信息,
ODU> unload
unload dict [block
unload table [object truncate] [partition
]
unload table [object scanned] [partition
]
unload table object [tablespace ]
unload table datafile block [blocks ] [partition
]
unload object [tablespace ] [cluster ] column
type: VARCHAR2 VARCHAR CHAR NUMBER SKIP LONG RAW
DATE LONG_RAW TIMESTAMP TIMESTAMP_TZ TIMESTAMP_LTZ
BINARY_FLOAT BINARY_DOUBLE NVARCHAR2 NCHAR
CLOB NCLOB BLOB
unload object [tablespace ] [cluster ] sample
unload object all [tablespace ] sample
unload user
执行scan extent,扫描数据文件区,/DATA/oracle/oradata/DATA/data01.dbf文件容量30G,执行scan extent约为20分钟,
ODU> scan extent
scan extent start: 2017-12-26 01:20:15
scanning extent...
scanning extent finished.
scan extent completed: 2017-12-26 01:40:20
执行unload table恢复表数据,此处我需要恢复分区表,某一个分区数据,需要注意,如果表名、分区名称是小写,会报错找不着,
ODU> unload table user.tbl object scanned partition tbl_2016q1
Using scanned extent.
partition 'tbl_2016q1' does not exist.
表名、分区名称,改为大写,提示恢复了114225行的数据,
ODU> unload table USER.TBL object scanned partition TBL_2016Q1
Using scanned extent.
Unloading table: TBL,partition: TBL_2016Q1 object ID: 117775
Unloading segment,storage(Obj#=117784 DataObj#=117784 TS#=9 File#=14 Block#=761986 Cluster=0)
114225 rows unloaded
数据恢复完成,odu路径内容如下,
这些后缀odu的文件,就是恢复出来的一些配置,例如user.odu,显示了数据库用户和角色,
0,SYS
1,PUBLIC
2,CONNECT
3,RESOURCE
4,DBA
5,SYSTEM
6,SELECT_CATALOG_ROLE
7,EXECUTE_CATALOG_ROLE
8,DELETE_CATALOG_ROLE
9,OUTLN
10,EXP_FULL_DATABASE
...
config.txt中的data_path(/DATA/oracle/odu)定义路径,存储了三个文件,这就是恢复出来的数据,
-rw-r--r-- 1 ora11g dba 985 Dec 22 10:35 USER_TBL.sql
-rw-r--r-- 1 ora11g dba 970 Dec 22 10:35 USER_TBL.ctl
-rw-r--r-- 1 ora11g dba 12M Dec 22 10:36 USER_TBL.txt
其中,
USER_TBL.sql:列出表结构定义。
USER_TBL.ctl:sqlldr控制文件。
USER_TBL.txt:sqlldr数据文件。
可以使用USER_TBL.sql创建表结构,使用USER_TBL.ctl和USER_TBL.txt,用sqlldr工具进行导入,就完成了恢复。
tbl_2016q1分区包含20万数据,但实际只恢复了11万数据,咨询告知,试用版一个block只会恢复1条数据,可以理解,毕竟是一款个人软件,需要保护版权,支持原创,
试用版仅用于测试、学习和验证,只能恢复SYSTEM表空间下的数据,对于其他表空间的数据,仅恢复少量的数据以验证数据可恢复。而正式版在获取LICENSE后能够恢复所有能够恢复的数据。
ODU的使用上还是比较简单,操作并不复杂,帮助信息丰富,足以快速掌握,朋友们有兴趣,可以下载试用。
领取专属 10元无门槛券
私享最新 技术干货