全部博文(126)
分类:
2007-06-28 16:42:48
当我们的oracle发生了不能恢复的损坏时,oracle还提供一个DUL的工具,用来从datafile中抽取数据。
这个实验是在没有丢失system表空间,以及oracle能正常运行的环境下进行的。
搭建测试环境:
1. 创建tablespace:
CREATE TABLESPACE dul
DATAFILE 'D:\database\oracle\oradata\ora817\dul.dbf' SIZE
extent management local uniform size 40K;
2.在用户dlinger下创建table和数据:
create table test_p (id varchar2(10),name varchar2(20)) tablespace dul
PARTITION BY RANGE(id)
(PARTITION id1 VALUES LESS THAN ('ab'),
PARTITION id2 VALUES LESS THAN ('bc')
);
insert into test_p values('aa','dlinger');
insert into test_p values('bb','dlinger');
create table test tablespace dul as select * from dba_objects where rownum<5000;
使用DUL工具:
在d:创建dul目录,将dul工具解压在这个目录下。
1.创建init.dul和control.dul文件
根据win2000下,oracle8i版本
Init.dul:
osd_big_endian_flag=false
osd_dba_file_bits=10
osd_c_struct_alignment=32
osd_file_leader_size=1
osd_word_size = 32
control_file = D:\Dul\control.dul
db_block_size=8192
export_mode=true
compatible=8
file = dump
control.dul
SQL>connect internal
SQL>spool control.dul
SQL> select ts#, rfile#, name from v$datafile;
SQL>spool off
修改输出的结果为如下格式:
0 1 D:\DATABASE\ORACLE\ORADATA\ORA817\SYSTEM01.DBF
1 2 D:\DATABASE\ORACLE\ORADATA\ORA817\RBS01.DBF
2 3 D:\DATABASE\ORACLE\ORADATA\ORA817\USERS01.DBF
17 4 D:\DATABASE\ORACLE\ORADATA\ORA817\IMP.DBF
4 5 D:\DATABASE\ORACLE\ORADATA\ORA817\TOOLS01.DBF
5 6 D:\DATABASE\ORACLE\ORADATA\ORA817\INDX01.DBF
6 7 D:\DATABASE\ORACLE\ORADATA\ORA817\DR01.DBF
7 8 D:\DATABASE\ORACLE\ORADATA\ORA817\NNC_DATA01.ORA
8 9 D:\DATABASE\ORACLE\ORADATA\ORA817\NNC_DATA02.ORA
9 10 D:\DATABASE\ORACLE\ORADATA\ORA817\NNC_DATA03.ORA
10 11 D:\DATABASE\ORACLE\ORADATA\ORA817\NNC_INDEX01.ORA
11 12 D:\DATABASE\ORACLE\ORADATA\ORA817\NNC_INDEX02.ORA
12 13 D:\DATABASE\ORACLE\ORADATA\ORA817\NNC_INDEX03.ORA
13 14 D:\DATABASE\ORACLE\ORADATA\ORA817\OEM_REPOSITORY.ORA
14 15 D:\DATABASE\ORACLE\ORADATA\ORA817\TEST.ORA
18 16 D:\DATABASE\ORACLE\ORADATA\ORA817\EXP.DBF
19 17 D:\DATABASE\ORACLE\ORADATA\ORA817\DUL.DBF
2.使用DUL工具
Unload the object information:
D:\dul>dul.exe dictv8.ddl Data UnLoader with 64-bit io functions Copyright (c) 1994/2001 Bernard van Duijnen All rights reserved. Parameter altered Parameter altered Parameter altered Parameter altered . unloading table OBJ$ 25647 rows unloaded . unloading table TAB$ 595 rows unloaded . unloading table . unloading table USER$ 44 rows unloaded exit and restart DUL to load the first four dictionary tables in the cache OPTIONALLY for partitioned tables, indexes or lobs or for MIGRATED use bootstrap procedure for full bootstrap start with the following commands: scan database; bootstrap; (and follow the instructions) |
接下来就可以开始导出数据了:
DUL提供了四种导出数据的模式:unload database; unload user; unload table; unload extent ,这里,我们使用unload user来导出上面创建的两个测试table。
D:\dul>dul Data UnLoader with 64-bit io functions Copyright (c) 1994/2001 Bernard van Duijnen All rights reserved. DUL: Warning: Recreating file "dul.log" Loaded 44 entries from USER.dat DUL: Warning: Increased the size of DC_OBJECTS from 25000 to 50000 entries Loaded 25647 entries from OBJ.dat Loaded 595 entries from TAB.dat Loaded 20493 entries from COL.dat DUL> unload user dlinger; About to unload DLINGER's tables ... . unloading table TEST 4999 rows unloaded DUL: Error: No partitions found for partitioned table TEST_P . unloading table TEST_P . table TEST_P total 0 rows unloaded |
我们发现,表test成功地导出来了,但是对于分区表test_p,没有导出数据。
在d:\dul目录下多出了两个dmp文件dump001和dump002
我们先把dump001 imp到用户dling下
C:\Documents and Settings\duanl>imp userid=dling/dling full=y file='d:\dul\dump 001.dmp' ; Import: Release (c) Copyright 2000 Oracle Corporation. All rights reserved. 连接到: Oracle8i With the Partitioning option JServer Release 经由常规路径导出由EXPORT:V 警告: 此对象由 Bernard's DUL 导出, 而不是当前用户 . 正在将Bernard's DUL的对象导入到 DLING . . 正在导入表 "TEST" 4999行被导入 成功终止导入,但出现警告。 |
查看数据:
C:\Documents and Settings\duanl>sqlplus dling/dling SQL*Plus: Release (c) Copyright 2000 Oracle Corporation. All rights reserved. 连接到: Oracle8i With the Partitioning option JServer Release SQL> select count(*) from test; COUNT(*) ---------- 4999 |
然后单独来处理分区表test_p,这里我们需要在DUL下使用scan tables的命令,
在这之前,必须要先scan database。
DUL> scan database; tablespace 0, data file 1: 33791 blocks scanned tablespace 1, data file 2: 38399 blocks scanned tablespace 2, data file 3: 13823 blocks scanned tablespace 17, data file 4: 1279 blocks scanned tablespace 4, data file 5: 1535 blocks scanned tablespace 5, data file 6: 7423 blocks scanned tablespace 6, data file 7: 11263 blocks scanned tablespace 7, data file 8: 6399 blocks scanned tablespace 8, data file 9: 2559 blocks scanned tablespace 9, data file 10: 2559 blocks scanned tablespace 10, data file 11: 1279 blocks scanned tablespace 11, data file 12: 1279 blocks scanned tablespace 12, data file 13: 1279 blocks scanned tablespace 13, data file 14: 3840 blocks scanned tablespace 14, data file 15: 12799 blocks scanned tablespace 18, data file 16: 1279 blocks scanned tablespace 19, data file 17: 1279 blocks scanned D:\dul1> D:\dul1>dul > scan.out& scan tables; |
这里我们将scan tables的结果输出到scan.out的文件中,阅读这个文件,我们发现了如下和表test_p相关的信息:
Analyzing segment: data object id=26918 segment header at ( file=17 block=84) heap organized table DUL: Warning: Column 1: type based on optimistic NICE voting no count IntSz NULL >75% 100% Any Nice Any Nice Any Nice 1 1 2 0% 100% 100% 100% 0% 0% 0% 0% 0% 2 1 7 0% 100% 100% 0% 0% 0% 0% 0% 0% "aa" "dlinger" UNLOAD TABLE OBJNO26918 ( COL001 CHAR(2), COL002 CHAR(7) ) STORAGE( DATAOBJNO 26918 ); Analyzing segment: data object id=26919 segment header at ( file=17 block=89) heap organized table DUL: Warning: Column 1: type based on optimistic NICE voting no count IntSz NULL >75% 100% Any Nice Any Nice Any Nice 1 1 2 0% 100% 100% 100% 0% 0% 0% 0% 0% 2 1 7 0% 100% 100% 0% 0% 0% 0% 0% 0% "bb" "dlinger" UNLOAD TABLE OBJNO26919 ( COL001 CHAR(2), COL002 CHAR(7) ) STORAGE( DATAOBJNO 26919 ); |
我们将这样两个命令copy出来:
UNLOAD TABLE OBJNO26918 ( COL001 CHAR(2), COL002 CHAR(7) )
STORAGE( DATAOBJNO 26918 );
UNLOAD TABLE OBJNO26919 ( COL001 CHAR(2), COL002 CHAR(7) )
STORAGE( DATAOBJNO 26919 );
然后用test_p的column定义语句来替换相关的内容:
UNLOAD TABLE OBJNO26918 ( id varchar2(10),name varchar2(20) )
STORAGE( DATAOBJNO 26918 );
UNLOAD TABLE OBJNO26919 ( id varchar2(10),name varchar2(20) )
STORAGE( DATAOBJNO 26919 );
在DUL中,对于每一个分区,将其看做一个独立的table来处理。使用这样的命令来导出分区表的数据:
DUL> UNLOAD TABLE OBJNO26918 ( id varchar2(10),name varchar2(20) ) DUL 2> STORAGE( DATAOBJNO 26918 ); . unloading table OBJNO26918 1 row unloaded DUL> UNLOAD TABLE OBJNO26919 ( id varchar2(10),name varchar2(20) ) DUL 2> STORAGE( DATAOBJNO 26919 ); . unloading table OBJNO26919 1 row unloaded DUL> quit; |
我们把这次dump出来的文件imp到用户dling下:
我们发现,dling用户下增加了两个table:
SQL> connect dling/dling;
SQL> select table_name from user_tables;
TABLE_NAME
------------------------------
OBJNO26918
OBJNO26919
TEST
然后我们用test_p的脚本重新创建table,将OBJNO26918和OBJNO26919的数据导入table test_p,再drop OBJNO26919和OBJNO26918就可以了:
SQL> create table test_p (id varchar2(10),name varchar2(20)) tablespace dul 2 PARTITION BY RANGE(id) 3 (PARTITION id1 VALUES LESS THAN ('ab'), 4 PARTITION id2 VALUES LESS THAN ('bc') ); Table created SQL> insert into test_p select * from OBJNO26918; 1 row inserted SQL> insert into test_p select * from OBJNO26919; 1 row inserted SQL> commit; Commit complete |