Email: service@parnassusdata.com 7 x 24 online support!
ORACLE DUL用户与配置指南 V10.2.4.27
如果自己搞不定可以找诗檀软件专业ORACLE数据库修复团队成员帮您恢复!
诗檀软件专业数据库修复团队
服务热线 : 13764045638 QQ号:47079569 邮箱:service@parnassusdata.com
1. DUL的原理和功能列表
1.1 独立的C语言程序
DUL是一个独立的C程序,它直接从数据文件的表中检索行。 Oracle的RDBMS软件完全不被使用。DUL进行脏读,它假定每个事务已经提交。它也不检查是否需要完成介质恢复。
1.2 最后的还原手段
DUL旨在检索无法用其他方法检索的数据。它不是EXP,SQL *Load等的替代选择,而是最后的方案。不用于正常的生产环境。
在使用DUL之前,你必须知道RDBMS有许多隐藏的功能可以强制打开坏数据库。隐藏参数和事件可以用于跳过前滚,禁用回滚,禁用特定SMON行为,推进数据库scn等等。
1.3 数据库损坏-数据块好的
数据库可以被破坏,但单独的数据块必须是100%正确。在所有导出进行检查时,确保块没有损坏并属于正确的数据段。如果扫描时遇到损坏的块,一个错误信息被打印在加载程序(loader)文件和标准输出。将继续导出下一行或下一个块。
1.4 簇/表/索引中的行
DUL只会导出索引/表/簇中数据。它不会转储触发器和存储过程,也不会创建表或视图的SQL脚本。(但描述它们的数据字典表可以被导出)。该数据将被导出为适合SQL * Loader或IMP的格式。同时,SQL * Loader的匹配控制文件也会生成。
DUL可以导出索引和索引组织表。索引的导出能用来确定表应该有多少行或标识缺失的行。
1.5 跨平台导出
支持跨平台导出。数据库可以从与DUL-主机不同的操作系统被复制。 (迄今所涉及的数据库/系统:Sequent/ptx, Vax Vms, Alpha Vms, MVS, HP9000/8xx, IBM AIX, SCO Unix, Alpha OSF/1, Intel Windows NT)。
在“init.dul”中的配置参数必须进行修改,以匹配原始平台和O / S,而非导出执行的平台。
1.6 支持ORACLE的所有产品特性
支持数据库的所有概念:行链接,行迁移,哈希/索引 簇,longs,raws,rowid,日期,数字,multiple free list groups,段的高水位,NULLS,trailing NULL columns,区的无限扩展,Oracle8的新数据块布局,表分区。
后来增加的有lobs,压缩索引,9iR2压缩表。可变数组(varray)和抽象数据类型ADTs(用户定义的对象)在SQL * Loader模式下被部分支持。
ASM是完全支持的,文件可以从ASM磁盘组中提取。不需要mount ASM实例,直接访问磁盘。支持非默认的ASM分配单元大小。
数据可以用unexp命令从export 的dump文件里恢复。
1.7 支持的数据库版本
DUL能用于Oracle 6以上版本。 DUL已通过从6.0.26到10.2的所有版本。即使旧版数据块头布局(6.0.27.2之前)也支持。
1.8 多字节支持
DUL本质上是一个单一字节的应用程序。它的命令解析器无法解析多字节字符,但导出任何多字节的数据库是可以的。对于所有可能情况都有解决方法。
DUL可转换为UTF8。这是为了存储在UTF16的 NCLOBS。
1.9 限制
1.9.1 MLSLABELS
oracle信任的多层安全标记不支持。
1.9.2 (LONG) RAW
DUL可以导出(long)raws。目前在SQL * Loader中用合适的格式来保存所有的long raws。所以long raws和blobs可以被两种模式下导出。
1.9.3 ORACLE8 OBJECT OPTION AND LOBS
尚不支持嵌套表,如果需要请告知我来添加。支持varray和ADT,以及储存为核心lob的。 在SQL * Loader模式和EXP模式下都支持CLOBS,NCLOBS。 BLOBS在EXP模式下好处理,但在SQL * Loader模式下产生的十六进制格式当前未能正确加载。
1.10 可移植性
通过ANSI-C编译器,DUL可以移植到任何操作系统。 DUL已经被移植到许多UNIX系统上,VMS和WindowsNT。目前,所有构建都使用gcc和Linux的交叉编译环境完成。
1.11 数据库内部
了解Oracle RDBMS内部是成功地使用DUL的必要前提。例如数据服务器内部(DSI)文档和教程提供一个良好的基础。甚至还有专门的DUL模块。
2. 设置和使用DUL
2.1 配置文件
DUL有两个配置文件。 “init.dul”包含所有的配置参数。 (缓存大小,块头布局的详细内容,oracle数据块大小,输出文件格式)。
在控制文件“control.dul”中,指定数据库的数据文件名和asm磁盘。
2.2 可用的数据字典
如果组成SYSTEM表空间的数据文件可用,那Oracle数据字典就可用。Oracle分配给这些文件的数字和你给定的名称(不需要是Oracle知道的原始名称),必须列入“control.dul”文件。您还需要包括文件数和其他表空间的文件名,这些表空间是最终想要导出表及其数据。不包含这些文件不会影响数据字典导出步骤,但会影响之后的表导出。
当USER$, OBJ$, TAB$ and COL$能被导出时,使用DUL
步骤如下:
1. 在目标数据库配置DUL。这表示要创建一个正确的init.dul和control.dul。 SYSTEM表空间的数据文件数量和名称必须与你要导出表和数据的表空间的所有数据文件一并包含在control.dul文件中。对于Oracle8及以上版本,表空间数和相关文件数必须在每个数据文件中指定。
2. 使用”BOOTSTRAP”命令来准备导出。在引导过程中会发现一个兼容的段,找到bootstrap$表导出。不再需要旧的“dul dictv7.ddl”。
3. 导出数据文件被包含在“control.dul”文件中的表。使用以下命令之一:
“UNLOAD TABLE [ owner>.]table ;这将导出表定义和表的数据。
“UNLOAD USER user name ; 这为指定的用户导出所有表和数据。
“UNLOAD DATABASE ;这导出所有可用的数据库表。 (除了SYS用户)
2.3 没有可用的数据字典
如果SYSTEM表空间的数据文件不可用,那么虽然可以unload 导出数据,但USER,TABLE和COLUM名称是未知的。识别表会是艰巨的任务。但它可以(并已经)被完成。你需要深入了解你的应用程序和应用程序表。列类型可以由DUL猜测,但表和列名丢失了。来自同一数据库但旧了几周的任何SYSTEM表空间可以有很大的帮助!DUL使用的多数信息不改变。 (只有dataobj#是在truncate或索引重建过程中会有改变)
2.3.1 没有system表空间下使用DUL
步骤如下:
1. 在目标数据库配置DUL。这表示创建一个正确的init.dul和control.dul。在这种情况下,control.dul文件需要将被导出的表和数据的数量和数据文件名,但它并不需要SYSTEM表空间信息。
2. SCAN DATABASE; :扫描数据库,创建区和段的分布图
3. SCAN TABLES; or SCAN EXTENTS; :收集行统计信息
4. 从步骤3的输出中识别丢失的表。
5. 导出识别出的表。
2.3.2 自动搜索
为了便于寻找丢失的表:在seen_tab.dat和seen_col.dat扫描的统计信息可以被加载到一个全新的数据库。如果你要重建表(但愿创建表的脚本仍可用),那么通过两个SQL * Plus脚本(fill.sql和getlost.sql),“丢失”表的结构信息可以匹配到“可见”表被扫描的信息。
2.3.3 提示和陷阱
1. 名称与DUL不是很相关的,仅与必须加载数据的人相关。但是,如果你不知道被导出的数据来自哪个表,它就没有任何价值。
2. 猜测的列可能是错误的。即使算法是保守的,但在不确定时决定为UNKNOWN。
3. 尾部是NULL的列不存储在数据库中。因此,如果最后一列只包含空值,那扫描将无法找到。 (在导出显示NULL列尾部被正确处理时)。
4. 当一个表被删除,该描述仅从数据字典中被移除。除非数据块被重新用于新的段,否则不会被重写。所以扫描软件可以看到被删除的表。
5. 没有行的表会被忽视。
6. 较新的对象ID比旧对象更高。如果表被重建,或者如果有同一表的测试和生产版本,对象的id可用于决定。
3. 导出语句概述
DUL使用类似SQL的命令界面。有导出区,表,用户或整个数据库的DDL语句。所需的数据字典信息可以在DDL语句中指定或取自先前导出的数据字典。以下三个语句将导出DEPT表。如果数据字典和区段地图可用,最常见的形式是:
UNLOAD TABLE scott.dept;
所有相关信息也可以在语句中指定:
REM Columns with type in the correct order
REM The segment header loaction in the storage clause UNLOAD TABLE dept( deptno NUMBER, dname CHAR, loc CHAR)
STORAGE( EXTENTS ( FILE 1 BLOCK 1205 ));
Oracle version 6:
REM version 6 data blocks have segment header location in each block ALTER SESSION SET USE_SCANNED_EXTENT_MAP = TRUE;
UNLOAD TABLE dept( deptno NUMBER, dname CHAR, loc CHAR) STORAGE( EXTENTS ( FILE 1 BLOCK 1205 ));
Oracle7:
REM Oracle7 data blocks have object id in each block ALTER SESSION SET USE_SCANNED_EXTENT_MAP = TRUE;
UNLOAD TABLE dept( deptno NUMBER, dname CHAR, loc CHAR) STORAGE( OBJNO 1501 );
4. 输出格式
只有完好无损的行会被写入输出文件。各行都是会被缓存的。buffer的大小可以通过init.dul的参数BUFFER来更改。高BUFFER参数不等同于较快的速度,它应该大到足以容纳一个完整的行。不完整或损坏的行不会被写出。 init.dul参数FILE_SIZE_IN_MB可用于将输出(在适当的边界)分割成多个文件,每个文件可以单独加载。
有三种不同的输出格式
◾导出模式
◾SQL * Loader模式:流数据文件
◾SQL * Loader模式:固定的物理记录数据文件
4.1导出模式
生成的文件与由EXP生成的导出文件完全不同!该文件是IMP能加载的最小格式。每个表中将生成单独的IMP可加载文件。它是单一的表转储文件。它包含一个header,一个insert table语句和表数据。表grant,存储过程,或触发器将不被包括在内。一个最小的建表语句被包含在内(无存储子句,只有列名和没有精度的类型)。在生成的header中文件中的字符集指示是V6类型。它被设置为表示基于ASCII的字符集。
要启用导出模式, 将init.dul参数EXPORT_MODE设置为TRUE。
由于生成的转储文件不包含字符集信息,设置NLS_LANG以匹配原始数据库。在导出模式才不会进行字符集转换。
4.2 SQL*LOADER模式
数据在此模式要么完全不能转换,要么全部被转换为UTF8,前提是设置了LDR_OUTPUT_IN_UTF8。在混合字符集环境中此设置是必需的,因为一个数据文件的内容必须有一个单独的字符集。
在加载数据时,你可能需要设置NLS_LANG以匹配原始数据库,从而防止不必要的字符集转换。
在两种SQL * Loader输出格式中,列将被空格分隔并被双引号括起来。数据中的任何双引号将增加一倍。SQL * Loader会识别这点并只加载一个。使用init.dul参数LDR_ENCLOSE_CHAR,你能将包围列的字符从双引号更改为任何想要的字符。
有两种类型的物理记录模式:
流模式
在流模式下没什么特别的,每条记录后会有换行符打印出来。这是紧凑模式,可用于数据不包含换行符的情况。要启用数据流模式,在init.dul中设置LDR_PHYS_REC_SIZE = 0
固定的物理记录
如果数据可包含换行符,这个模式是必不可少的。一个逻辑记录和一个完整的行可以由多个物理记录组成。默认的记录长度为81,这很适合VT220的屏幕。物理记录大小可用init.dul里的LDR_PHYS_REC_SIZE指定。
4.3 输出文件名
生成的文件名是:owner name_table name.ext。IMP可加载文件的扩展名为“.dmp”。“.dat”和“.ctl”被用于SQL * Loader数据文件和控制文件。为了防止变量替换和其他不好的影响,奇怪的字符被剥离。(只有字母数字和’_’被允许)。
如果设置了FILE参数,生成的名称将是FILEnnn.ext。如果文件系统不支持足够长的文件名,可以用这个方法处理。
5. 一些DUL内部构件
5.1 要求信息
要从数据库块中导出表数据必须了解以下信息:
1.列/簇信息:列的数量和类型。CHAR或VARCHAR列的最大长度。这个信息可以由unload语句提供,或者从先前导出的USER $,OBJ $,TAB $和COL $中获得。
2.段/区的信息:当导出表时,在数据段头块的extent表被用于定位所有数据块。这个数据段头块(文件号和块号)的位置来自数据字典或可在unload语句中指定。如果该段头不正确/不可用,那必须用另一种方法。 DUL能通过扫描整个数据库创建自己的段区地图。 (以DUL与扫描数据库语句单独运行。)
5.2 二进制头文件
在块头的C-Structs不被直接复制,它们通过特殊方法检索。结构成员的所有偏移量都被编入DUL。这种方法使跨平台导出实现。(在HP导出MVS创建的数据文件)除了字节顺序,至今只有四个布局类型被发现。
1.VAX VMS和Netware:在结构成员之间无对齐填充。
2.韩国Ticom Unix机器:结构成员的16位对齐。
3.MS / DOS :16位对齐和16位字长。
4.世界上其他(包括Alpha VMS):结构成员对成员大小对齐。
5.3 机器依赖
(数据库)机器依赖用以下参数配置:
◾大/小端字节顺序
◾在DBA(块地址)FILE#的低部分的位数量
◾在一个C-Struct中的成员对齐
◾oracle文件头块之前的块或字节数
◾在段头结构中使用的字节大小
5.4 导出数据字典
如果数据字典的文件存在且未破坏,DUL可以导出数据库的数据字典。对于要使用的数据字典,内部表必须首先导出至外部文件(USER $,OBJ $,TAB $和COL $)。bootstrap命令将找到并导出所需的表。
6. DDL(DUL描述语言)规范
[ ALTER SESSION ] SET init.dul parameter = value ;
Most parameters can be changed on the fly.
BOOTSTRAP [LOCATE | GENERATE | COMPLETE
| UNLOAD Bootstrap$ segment header block address ];
Bootstraps the data dictionary. Default is COMPLETE.
LOCATE finds and unloads the bootstrap$ table.
GENERATE builds a ddl file based on inforation in the cache.
COMPLETE is in fact LOCATE, followed by GENERATE (two times)
COMMIT;
Writes the changed block to the data file.
CREATE BLOCK INDEX index_name ON device ;
块索引包含在损坏的文件系统中找到的有效Oracle块的地址。用于合并多个磁盘映像或从损坏的文件系统导出。只有在极端的文件系统损坏情况下有用。
DESCRIBE owner_name . table_name ;
DUMP [ TABLESPACE tablespace_no ]
[ FILE file_no ]
[ BLOCK block_no ]
[ LEVEL level_no ] ;
Not a complete blockdump, mainly used for debugging. The block address is remembered.
EXTRACT asm file name to output file name ;
Copies any ASM file from a disk group to the file system.
(there was a problem with online redologs this needs more testing)
MERGE block_index INTO [ segment ];
合并命令使用索引文件中的信息来定位文件数和对象id的组合的可能数据块,每个候选块与在数据文件中的当前块进行比较。如果当前块是坏的,或有一个更旧的scn,候选块将被写入数据文件。这只有在极端的文件系统损坏情况下有用。
REM any_text_you_like_till_End_Of_Line : comment
REM NOT allowed inside ddl statements. ( To avoid a two layer lexical scan). ROLLBACK; # Cancels the UPDATE statements.
SHOW DBA dba ; # dba -> file_no block_no calculator
| DBA rfile_no block_no ; # file_no block_no -> dba calculator
| SIZES ; # show some size of important structs
| PARAMETER; # shows the values of all parameters
| LOBINFO; # lob indexes found with SCAN DATABASE
| DATAFILES; # summary of configured datafiles
| ASM DISKS; # summary of configured asm disks
| ASM FILES; # summary of configured datafiles on asm
| ASM FILE cid # extent information for asm file
UNEXP [TABLE] [ owner . ] table name
( column list ) [ DIRECT ]
DUMP FILE dump file name
FROM begin offset [ UNTIL end offset ]
[ MINIMUM minimal number of columns COLUMNS ] ;
To unload data from a corrupted exp dump file. No special setup or configuration is required, just the compatible parameter.
The start offset should be where a row actually begins.
UNPUMP
To unload data from a corrupted expdp (datapump) dump file.
This is still work in progress, the basic commands work but rather complex to use. Contact me if this is needed.
unload DATABASE;
UNLOAD USER user_name;
UNLOAD [TABLE] [ schema_name . ] table_name
[ PARTITION( partition_name ) ]
[ SUBPARTITION( sub_partition_name ) ] [ ( column_definitions ) ]
[ cluster_clause ]
[ storage_clause ] ;
UNLOAD EXTENT table_name
[ ( column_definitions ) ]
[ TABLESPACE tablespace_no ]
FILE extent_start_file_number BLOCK extent_start_block_number
BLOCKS extent_size_in oracle_blocks ;
UNLOAD LOB SEGMENT FOR [ schema_name . ] table_name [ ( column name ) ] ;
UNLOAD LOB SEGMENT STORAGE ( SEGOBJNO data obj#) ;
UPDATE [ block_address ] SET UB1|UB2|UB4 @ offset_in_block = new_value ;
UPDATE [ block_address ] SET block element name = new_value ;
Now and then we can repair something.
Patches the current block and dumps it. You can issue multiple UPDATE commands.
Block is not written yet, use COMMIT to write.
storage_clause ::=
STORAGE ( storage_specification [ more_storage_specs ] )
storage_specification ::=
OBJNO object_id_number
| TABNO cluster_table_number
| SEGOBJNO cluster/data_object_number /* v7/v8 style data block id */
| FILE data_segment_header_file_number /* v6 style data block id */ BLOCK data_segment_header_block_number )
| any_normal_storage_specification_but_silently_ignored
SCAN DATABSE;
扫描所有数据文件的所有块。产生两个或三个文件:
1.SEG.dat 找到的段头(索引/簇/表)信息:(对象ID,文件号和块号)。
2.EXT.dat连续的表/簇的数据块的信息。 (对象ID(V7),段头的文件和块号(V6),文件号和第一个块的块号,块号,表号)
3.SCANNEDLOBPAGE.dat每个lob数据块的信息,这个文件可能很大(可选的,仅在init.dul:SCAN_DATABASE_SCANS_LOB_SEGMENTS= TRUE)。同时,需要的内存大小可能会产生问题。目的有两个:1:在导出表时可能解决损坏的lob索引。 2:导出lob段(已删除的lob或无lob索引或父表的lob段)。SCANNEDLOBPAGE.dat字段的含义:(segobj#,lobid,fat_page_no,version( wrap, base),ts#,file#,block#)
SCAN DUMP FILE dump file name
[ FROM begin offset ]
[ UNTIL end offset ];
Scans an export dump file to produce to provide the
create/insert statements and the offsets in the dump file.
SCAN LOB SEGMENT storage clause ;
SCAN LOB SEGMENT FOR table name [. column name] ;
Scans the lob segment to produce LOBPAGE.dat information,
but then for this segment only. Probably quicker and smaller.
For partitioned objects use scan database.
SCAN TABLES;
Uses SEG.dat and EXT.dat as input.
Scans all tables in all data segments (a header block and at least one matching extent with at least 1 table).
SCAN EXTENTS;
Uses SEG.dat and EXT.dat as input.
All extents for which no corresponding segment header has been found. (Only useful if a tablespace is not complete, or a segment header
is corrupt).
EXIT QUIT and EOF all cause DUL to terminate.
7. DDL(DUL描述语言)概述
UNLOAD EXTENT和UNLOAD TABLE规则:
7.1 extent map
UNLOAD TABLE要求一个extent map。在99.99%的情况下,段头中的extent map是可用的。在罕见的0.01%的情况下,段头丢失。可以用扫描数据库命令创建一个extent map。仅当参数USE_SCANNED_EXTENT_MAP被设为TRUE时,自生成的extent map才在导出时被使用。
7.2 列定义
列定义必须指定列存储在段中的顺序,由col$.segcol#指定。这不需要与在CREATE TABLE语句中指定的列顺序相同。簇表列被移到前面,long移到后面。使用ALTER TABLE命令添加到表的列总是最后保存。
7.3 导出单个区
UNLOAD EXTENT可用于导出一个或多个相邻块。要导出的区段必须用STROEAGE子句指定:要指定单个区段,使用:STORAGE(EXTENTS(FILE fno BLOCK bno BLOCKS #blocks))(FILE和BLOCK指定第一个块,BLOCKS 是指区的大小)
7.4 DUL具体列类型
有两个额外的DUL特定数据类型:
1.IGNORE:该列将被跳过,就好像它不存在。
2.UNKNOWN:每列会有一个启发式猜测。
在SQL * Loader模式还有更多DUL特定的数据类型:
1.HEXRAW:列是十六进制转储。
2.LOBINFO:显示LOB定位的一些信息。
3.BINARY NUMBER:在LOB索引中使用的字。
7.5 识别USER$,OBJ$, TAB$和COL$表
DUL使用与RDBMS相同的bootstrap程序。即它使用系统数据文件头的root dba来定位bootstrap$ 表。由于版本不同,root dba可能是包含bootstrap$地址的兼容段位置,或较新版本中是bootstrap$表本身的地址。bootstrap$表被导出,它的内容是分析以查找一开始的四张表(USER $,OBJ $, TAB$和COL$)。其他表都是基于前面四张表的信息导出的。
7.6 SCAN 命令概述
SCAN TABLES和SCAN EXTENTS扫描相同的信息,并生成类似的输出。所有行的所有列都被检查。每一列收集以下统计数据:
◾行在数据块中多久显示一次。
◾最大的内部列长度。
◾列是NULL的情况有多久。
◾列由至少75%可打印的ASCII组成的情况有多久。
◾列由100%可打印的ASCII组成的情况有多久。
◾列是一个有效的Oracle数字的情况有多久。
◾列是一个不错的数字的情况有多久。 (没有多少以零开头或结尾 )
◾列是一个有效的日期的情况有多久。
◾列是一个可能有效的rowid的情况有多久。
这些统计被组合并有一种列类型被提出。使用该建议,五行被导出显示结果。这些统计数据转储到两个文件(seen_tab.dat和seen_col.dat)。有SQL * Loader和SQL * Plus脚本可以自动完成识别过程的一部分。 (目前称为getlost选项)。
7.7 describe命令
这是一个描述命令。它会显示表的字典信息,在DUL的字典缓存中可用
8. DUL启动顺序
在启动过程中,DUL经过以下步骤:
◾参数文件“dul”被处理。
◾DUL控制文件(默认“control.dul”)被扫描。
◾尝试加载USER$,OBJ$,TAB $和COL $的转储文件,如果有则放到DUL的数据字典缓存中。
◾尝试加载seg.dat和col.dat。
◾接受DDL语句或运行指定为第一个参数的DDL脚本。
9. init.dul中可以指定的DUL 参数
ALLOW_TRAILER_MISMATCH
BOOLEAN
强烈不推荐使用,会产生更少的行。只有在你完全理解它的意思及为什么想使用时才能使用。跳过正确块的检查。在这个测试中失败的块可能是坏的。但这样省去了修补一些块的麻烦。
ALLOW_DBA_MISMATCH
BOOLEAN
强烈不推荐使用,会产生更少的行。只有在你完全理解它的意思及为什么想使用时才能使用。跳过正确块trailer的检查。在这个测试中失败的块是损坏的碎片。但这样省去了修补一些块的麻烦。
ALLOW_OTHER_OBJNO
BOOLEAN
如果你的字典比你的数据文件更旧,那数据对象ID对于被truncate的表有所不同。当这个参数设为true,它会发出警告,但使用来自段头的值。所有其他块都被全面检查。这只用于特例。
ASCII2EBCDIC
BOOLEAN
(var)char字段必须从 EBCDIC 转译为 ASCII。(针对在ASCII主机上导出MVS数据库)
BUFFER
NUMBER (字节)
在导出和SQL * Loader模式中使用的行输出缓冲区(buffer)的大小。它在各行被首先存储到该缓冲区中。只有没有错误的完整行才会被写入到输出文件。
COMPATIBLE
NUMBER
数据库版本,有效值为 6,7,8,9,10,11。必须指定参数。
CONTROL_FILE
TEXT
DUL 控制文件名(默认:“ control.dul”)。
DB_BLOCK_SIZE
NUMBER
Oracle块大小(最大32K)
CONTROL_FILE TEXT
DC_COLUMNS
NUMBER
DC_OBJECTS
NUMBER
DC_TABLES
NUMBER
DC_USERS
NUMBER
dul 字典缓存大小。如果其中一个过低,高速缓存将被自动调整大小。
EXPORT_MODE
BOOLEAN
使用export 导出模式或 SQL*Loader 模式。
FILE
TEXT
(转储或数据)文件名生成的基础。对类似8.3 DOS的文件系统使用。
FILE_SIZE_IN_MB
NUMBER (M)
最大转储文件大小。转储文件被分割成多个部分。每个文件都有一个完整的头,并能被单独加载。
LDR_ENCLOSE_CHAR
TEXT
包围住SQL* Loader模式中导出文件名的字符。
LDR_PHYS_REC_SIZE
NUMBER
生成的loader数据文件的物理记录大小。
LDR_PHYS_REC_SIZE = 0没有固定的记录,每个记录以一个换行符结束。
LDR_PHYS_REC_SIZE > 2: 固定的记录大小。
MAX_OPEN_FILES
在操作系统级别同时保持开放的数据文件最大数量。
OSD_BIG_ENDIAN_FLAG
字节顺序。Big Endian一开始也被称为MSB。 DUL根据在运行的机器设置默认值。要了解这个被称为Big Endian的原因,阅读Gullivers Travels。
OSD_DBA_FILE_BITS
以位表示的DBA中文件编号大小。更精确的说是文件号的低序部分的大小。
OSD_FILE_LEADER_SIZE
在数据文件头部添加的字节数/块数
OSD_C_STRUCT_ALIGNMENT
C 结构成员对齐(0,16或23)。默认的32对于大多数端口是正确的。
OSD_WORD_SIZE
一个字的大小,总是32,除了MS/DOS(16)
PARSE_HEX_ESCAPES
Boolean 默认 FALSE
在解析时,在字符串使用\\xhh十六进制转义序列。如果设置为true,则奇怪的字符可以使用转义序列来指定。该功能也用于指定多字节字符。
USE_SCANNED_EXTENT_MAP
BOOLEAN
导出表时,在ext.dat使用扫描好的extent map。一般算法在段头使用extent map。只有当一些段头丢失或不正确时,该参数才有用。
WARN_RECREATE_FILES
BOOLEAN (TRUE)
如果现有的文件被覆盖,设置为FALSE以取消警告信息。
WRITABLE_DATAFILES
BOOLEAN (FALSE)
使用DUL一般只会读取数据库文件。然而,UPDATE和 SCAN RAW DEVICE也将写出。参数能防止有意外损坏。
SAMPLE init.dul :
# sample init.dul configuration parameters
# these must be big enough for the database in question
# the cache must hold all entries from the dollar tables. dc_columns = 200000
dc_tables = 10000
dc_objects = 10000
dc_users = 40
# OS specific parameters osd_big_endian_flag = false osd_dba_file_bits = 10
osd_c_struct_alignment = 32
osd_file_leader_size = 1
# database parameters db_block_size = 8k
# loader format definitions LDR_ENCLOSE_CHAR = " LDR_PHYS_REC_SIZE = 81
10. 配置端口相关的参数
收集已知的参数
osd_big_endian_flag
big endian 或 little endian(字节顺序):HP,SUN和大型机通常big endian:OSD_BIG_ENDIAN_FLAG = TRUE。
DEC和Intel平台是little endian :OSD_BIG_ENDIAN_FLAG = FALSE。默认值对DUL正在运行的平台是正确的。
这点没有标准的技巧,以下在UNIX系统上可能有效:
echo dul | od -x
If the output is like:
0000000 6475 6c0a
0000004
You are on a big endian machine (OSD_BIG_ENDIAN_FLAG=TRUE).
If you see:
0000000 7564 0a6c
0000004
This is a little endian machine (OSD_BIG_ENDIAN_FLAG=FALSE).
osd_dba_file_bits
在DBA用于文件号的低位部分的位数量,执行下面的查询:
SQL> select dump(chartorowid('0.0.1')) from dual;
Typ=69 Len=6: 8,0,0,0,0,0 -> osd_dba_file_bits = 5 (SCO)
Typ=69 Len=6: 4,0,0,0,0,0 -> osd_dba_file_bits = 6 (Sequent , HP)
Typ=69 Len=6: 1,0,0,0,0,0 -> osd_dba_file_bits = 8 (NCR,AIX)
Typ=69 Len=6: 0,16,0,0,0,0 -> osd_dba_file_bits = 12 (MVS)
Typ=69 Len=10: 0,0,0,0,0,64,0,0,0,0 osd_dba_file_bits = 10 (Oracle8)
OSD_C_STRUCT_ALIGNMENT
在数据文件头的结构布局。
0:在C-结构(VAX/ VMS只)成员之间没有填充
16:一些韩国ticom机和MS/ DOS
32:结构成员按成员大小排列。 (所有其他包括ALPHA / VMS)
执行下面的查询:
SELECT * FROM v$type_size
WHERE type IN ( 'KCBH', 'KTNO', 'KCBH', 'KTBBH', 'KTBIT', 'KDBH'
, 'KTECT', 'KTETB', 'KTSHC') ;
一般osd_c_struct_alignment = 32 且输出如下:
K KTNO TABLE NUMBER IN CLUSTER 1
KCB KCBH BLOCK COMMON HEADER 20
KTB KTBIT TRANSACTION VARIABLE HEADER 24
KTB KTBBH TRANSACTION FIXED HEADER 48
KDB KDBH DATA HEADER 14
KTE KTECT EXTENT CONTROL 44
KTE KTETB EXTENT TABLE 8
KTS KTSHC SEGMENT HEADER 8
8 rows selected.
仅对于VAX/ VMS和Netware,会出现 osd_c_struct_alignment=0和如下输出::
COMPONEN TYPE DESCRIPTION SIZE
-------- -------- -------------------------------- ----------
K KTNO TABLE NUMBER IN CLUSTER 1
KCB KCBH BLOCK COMMON HEADER 20
KTB KTBIT TRANSACTION VARIABLE HEADER 23
KTB KTBBH TRANSACTION FIXED HEADER 42
KDB KDBH DATA HEADER 14
KTE KTECT EXTENT CONTROL 39
KTE KTETB EXTENT TABLE 8
KTS KTSHC SEGMENT HEADER 7
8 rows selected.
如果有其他的不同的列表,可能是黑客攻击并可能对DUL有重大变化。
osd_file_leader_size
在Oracle文件头前的块/字节数。 Unix数据文件有一个额外的前面的块(文件大小,块数)大的值(>100)被看作是一个字节偏移,小的数被看作Oracle块号。
Unix : osd_file_leader_size = 1
Vms : osd_file_leader_size = 0
Desktop : osd_file_leader_size = 1 (or 512 for old personal oracle)
Others : Unknown ( Use Andre Bakker's famous PATCH utility to find out)
Oracle7 的文件头的开始格式是0X0B010000.
你可以在control.dul中可选的第三个字段添加一个额外的字节偏移(如AIX或DEC UNIX裸设备上的数据文件)
11. 控制文件语法规范
控制文件(默认名称“control.dul”)用于指定ASM磁盘,块索引和数据文件名。control的格式已被扩展。
目前在DUL控制文件中有三种类型的定义。在单独的行中的每个条目。 ASM磁盘必须先于ASM文件。
control_file_line ::= asm_disk_spec | file_piece_spec | block_index_spec
如果compatible是10或更高,你也可以指定ASM磁盘。它对于指定设备名称通常足够。所有属性都是由头部检查自动检索。当头部检查是不可能时才需要完整的语法,用于有损坏的header的磁盘。语法是:
DISK device name [ disk group options ]
disk group option ::= GROUP disk group name
| DISK_NO disk number in group
| F1B1 File1 Block1 location
块索引是在损坏的文件系统上访问Oracle块的一种方式。通常,损坏的文件系统没有被全部删除,它不是空的。由于oracle块的特定布局,可能将数据块的位置信息存储在块索引上。参见 create block index命令。block_index_name是一个普通的标识符,它用于构建一个唯一的文件名。
BLOCK INDEX block_index_name
每个条目可以包含一个数据文件的一部分。最小单位是一个数据块。这样的话,对于DUL来说太大的数据文件可分割成多个部分,其中每个部分小于2GB。
一般指定的文件名就足够了。即使对于单个块。如果compatible为10或更高,文件号和表空间号将从文件头读取。
如果指定的细节与文件头不同,DUL会给出一个警告,但使用你的定义。这是为了能在文件损坏的头块导出文件。对于调试,可以转储文件头。
可选的额外段肉偏移是一个额外的字节偏移,它将被添加到该数据文件的所有lseek() 操作。这样就可以跳过一些AIX裸设备额外的4K块,或在Tru64d上裸设备额外的64K块。
file_piece_spec ::=
[ [ tablespace_no ] relative_file_number]data_file_name
[ optional extra leader offset ]
[ startblock block_no ]
[ endblock block_no ]
例子
# AIX version 7 example with one file on raw device
1 /usr/oracle/dbs/system.dbf
8 /dev/rdsk/data.dbf 4096
# Oracle8 example with a datafile split in multiple parts, each part smaller than 2GB
0 1 /fs1/oradata/PMS/system.dbf
1 2 /tmp/huge_file_part1 startblock 1 endblock 1000000
1 2 /tmp/huge_file_part2 startblock 1000001 endblock 2000000
1 2 /mnt3/huge_file_part3 startblock 2000001 endblock 2550000
# ASM disks for two disk groups disk /media/maxtor/asm/dgn1 disk /media/maxtor/asm/dgn2 disk /media/maxtor/asm/dgn3 disk /media/maxtor/asm/dgn4 disk /media/maxtor/asm/dgodd
# system datafile in the first asm disk group
+DGN/db102/datafile/system.257.621616979
# users datafile in a different disk group
+DGODD/db102/datafile/users.257.621616683
# a so called big file tablespace, use 1024 for the file#
8 1024 /home/oracle/v102/dbs/bigfilets
# Or let DUL find out itself from the header
/home/oracle/v102/dbs/bigfilets
# one tablespace with a different block size
/home/oracle/v102/dbs/ts16k.dbf block_size 16k
# or let DUL find out by header inspection
/home/oracle/v102/dbs/ts16k.dbf
12. 导出例子
12.1 DUL用数据字典
1、创建合适的“init.dul”文件
2、创建“control.dul”文件
连接到数据库,并把数据库启动到mount状态,执行下面查询,把查询结果编辑到”control.dul”文件里
sqlplus /nolog
connect / as sysdba startup mount
set trimspool on pagesize 0 linesize 256 feedback off
column name format a200
spool control.dul
select ts#, rfile#, name from v$datafile; exit
edit the result
For Oracle8 a different query must be used: select ts#, rfile#, name from v$datafile;
3、启动DUL并执行bootstrap
$ dul
Data UnLoader 10.2.1.16 - Oracle Internal Only - on Thu Jun 28 11:37:24 2007 with 64-bit io functions
Copyright (c) 1994 2007 Bernard van Duijnen All rights reserved. Strictly Oracle Internal use Only
DUL> bootstrap;
Probing file = 1, block = 377
. unloading table BOOTSTRAP$ 57 rows unloaded DUL: Warning: Dictionary cache DC_BOOTSTRAP is empty
Reading BOOTSTRAP.dat 57 entries loaded Parsing Bootstrap$ contents
DUL: Warning: Recreating file "dict.ddl" Generating dict.ddl for version 10
OBJ$: segobjno 18, file 1
TAB$: segobjno 2, tabno 1, file 1
COL$: segobjno 2, tabno 5, file 1
USER$: segobjno 10, tabno 1, file 1
Running generated file "@dict.ddl" to unload the dictionary tables
. unloading table OBJ$ 52275 rows unloaded
. unloading table TAB$ 1943 rows unloaded
. unloading table COL$ 59310 rows unloaded
. unloading table USER$ 70 rows unloaded Reading USER.dat 70 entries loaded
Reading OBJ.dat
52275 entries loaded and sorted 52275 entries Reading TAB.dat 1943 entries loaded
Reading COL.dat 59310 entries loaded and sorted 59310 entries Reading BOOTSTRAP.dat 57 entries loaded
...
Some more messages for all the other TABLES
...
Database character set is WE8ISO8859P1 Database national character set is AL16UTF16
DUL> unload user SCOTT;
About to unload SCOTT's tables ...
. unloading table EMP 14 rows unloaded
12.2 DUL不用数据字典
1、创建合适的“init.dul”文件
2、创建“control.dul”文件
3、扫描数据库的段头和区
$ dul
UnLoader: Version 2.0.0.0 - Very Restricted on Tue May 16 11:10:16 1995
Copyright (c) 1994/95 Oracle Corporation, The Netherlands. All rights reserved.
DUL> scan database;
data file 1 20480 blocks scanned
data file 4 7680 blocks scanned
data file 5 512 blocks scanned
DUL>quit
4、重启DUL,扫描找到的表获得列的统计信息,这将生成大量的输出:
echo scan tables \; | dul > scan.out&
[ many lines here]
Object id 1601 table number 0
UNLOAD TABLE T1601_0 ( C1 NUMBER, C2 UNKNOWN, C3 UNKNOWN, C4 NUMBER, C5 DATE
, C6 NUMBER, C7 NUMBER, C8 NUMBER )
STORAGE ( TABNO 0 EXTENTS( FILE 1 BLOCK 10530));
Colno Seen MaxIntSz Null% C75% C100 Num% NiNu% Dat% Rid%
1 14 3 0% 0% 0% 100% 100% 0% 0%
2 14 6 0% 100% 100% 100% 14% 0% 21%
3 14 9 0% 100% 100% 100% 14% 0% 0%
4 14 3 7% 0% 0% 100% 100% 0% 0%
5 14 7 0% 0% 0% 0% 0% 100% 0%
6 14 3 0% 0% 0% 100% 100% 0% 0%
7 14 2 71% 0% 0% 100% 100% 0% 0%
8 14 2 0% 0% 0% 100% 100% 0% 0%
"7369" "SMITH" "CLERK" "7902" "17-DEC-1980 AD 00:00:00" "800" "" "20"
"7499" "-0.000025253223" "SALESMAN" "7698" "20-FEB-1981 AD 00:00:00" "1600" "30+0" "30"
"7521" "WARD" "SALESMAN" "7698" "22-FEB-1981 AD 00:00:00" "1250" "500" "30"
"7566" "JONES" "MANAGER" "7839" "02-APR-1981 AD 00:00:00" "2975" "" "20"
"7654" "MARTIN" "SALESMAN" "7698" "28-SEP-1981 AD 00:00:00" "1250" "1400" "30"
[ many more lines here ]
这看着眼熟,用上面的信息和你对EMP表的了解构建:
UNLOAD TABLE emp ( empno number, ename char, job char, mgr number, hiredate date, sal number, comm number deptno number)
STORAGE ( TABNO 0 EXTENTS( FILE 1 BLOCK 10530));
5、用这个语句导出emp表
$ dul
UnLoader: Version 2.0.0.0 - Very Restricted on Tue May 16 11:46:33 1995 Copyright (c) 1994/95 Oracle Corporation, The Netherlands. All rights reserved. Loaded 350 segments
Loaded 204 extents Extent map sorted
DUL> UNLOAD TABLE emp ( empno number, ename char, job char, mgr number, hiredate date, sal number, comm number deptno number) STORAGE ( TABNO 0 EXTENTS( FILE 1 BLOCK 10530));
. unloading table EMP 14 rows unloaded
DUL>quit
12.3 init.dul里错误的参数设置
错误的osd_dba_file_bits size
这会产生类似如下的输出。通常这不应该发生,因为你应该创建一个演示数据库,并通过DUL记录的(HTML页)查询进行检查。
在DBA的失配是只在文件号(括号内第一号)的部分。第二个数字,块号,是正确的。
Data UnLoader: Release 3.2.0.1 - Internal Use Only - on Wed Sep 3 10:40:33 1997 Copyright (c) 1994/95 Oracle Corporation, The Netherlands. All rights reserved. Session altered.
Session altered. Session altered. Session altered. Session altered.
DUL: Warning: Block[1][2] DBA in block mismatch [4][2] DUL: Warning: Bad cache layer header file#=1, block#=2
DUL: Warning: Block[1][3] DBA in block mismatch [4][3] DUL: Warning: Bad cache layer header file#=1, block#=3
...........and etc..........
错误的osd_file_leader_size
这可能会造成类似如下的输出,但还有许多其他可能。在这里,我们block off号是固定的。文件号是正确的。块号的差是恒定的:
Data UnLoader: Release 3.2.0.1 - Internal Use Only - on Wed Sep 3 10:44:23 1997 Copyright (c) 1994/95 Oracle Corporation, The Netherlands. All rights reserved. Session altered.
Session altered. Session altered. Session altered. Session altered.
DUL: Warning: Block[1][2] DBA in block mismatch [1][3] DUL: Warning: Bad cache layer header file#=1, block#=2
DUL: Warning: Block[1][3] DBA in block mismatch [1][4] DUL: Warning: Bad cache layer header file#=1, block#=3
...........and etc..........
错误的 osd_c_struct_alignment
这可能会产生如下的错误的输出:
Data UnLoader: Release 3.2.0.1 - Internal Use Only - on Wed Sep 3 10:46:10 1997 Copyright (c) 1994/95 Oracle Corporation, The Netherlands. All rights reserved. Session altered.
Session altered. Session altered. Session altered. Session altered.
. unloading table OBJ$
DUL: Warning: file# 0 is out of range
DUL: Warning: Cannot read data block file#=0, block# = 262145 OS error 2: No such file or directory
DUL: Warning: file# 0 is out of range
DUL: Warning: Cannot read data block file#=0, block# = 262146 OS error 2: No such file or directory
...........and etc..........
错误的db_block_size
当DB_BLOCK_SIZE设置过小时会生成以下输出。正确值是4096,而设置为2048。通常情况下,此参数值应取自Oracle实例的init.ora文件中。
Data UnLoader: Release 3.2.0.1 - Internal Use Only - on Thu Sep 4 12:38:25 1997 Copyright (c) 1994/95 Oracle Corporation, The Netherlands. All rights reserved. Session altered.
Session altered. Session altered. Session altered. Session altered.
DUL: Warning: Block[1][2] DBA in block mismatch [513][1159680] DUL: Warning: File=1, block 2: illegal block version 2
DUL: Warning: Block[1][2] Illegal block type[0]
DUL: Warning: Bad cache layer header file#=1, block#=2
DUL: Warning: Block[1][4] DBA in block mismatch [1][2] DUL: Warning: File[1]Block[4]INCSEQ mismatch[90268!=0] DUL: Warning: Bad cache layer header file#=1, block#=4
DUL: Warning: Block[1][6] DBA in block mismatch [1][3]
DUL: Warning: File[1]Block[6]INCSEQ mismatch[139591710!=86360346] DUL: Warning: Bad cache layer header file#=1, block#=6
...........and etc..........
QUOTE MISSING
如果收到以下错误,这是由于数据字典表“USER$,OBJ$, TAB$和COL$”没有被正确生成。要解决这个错误,简单地删除所有dictv6.ddl或dictv7.ddl创建.dat和.ctl文件并重启。
Data UnLoader: Release 3.2.0.1 - Internal Use Only - on Wed Sep 3 10:49:30 1997
Copyright (c) 1994/95 Oracle Corporation, The Netherlands. All rights reserved.
DUL: Error: Quote missing
13. 从损坏的EXP转储文件拯救数据 - UNEXP教程
如果你不了解EXP转储文件的结构任何东西,这就比较困难。以下是一个快速解释。除了文件头,转储文件有识别各个部分的标记。在每个表部分会有SQL语句。最有趣的部分是建表语句,接下来是插入到表语句。插入语句后直接跟绑定信息,(列数,以及每列的类型和绑定长度和其他一些信息)。接下来是实际的列。每列之前是两个字节长度,后跟实际列数据。可能较长的列有几个技巧。列数据的结尾以特殊的长度标记OXFFFF标志。行的开头没有标记。损坏后的重新同步是试错。损坏一般不能立即检测到。该格式与直接导出略有不同,所以你必须要对直接导出使用直接选项。指定的偏移量是一个行的开头。一般来说第一个直接在绑定数组之后,但为最佳的灵活性,你可以从行数据的任何地方开始。
第一步是扫描转储文件来找到偏移量和SQL语句。每个输出行从项目被找到的偏移位置开始。
DUL> scan dump file expdat.dmp;
0: CSET: 1 (US7ASCII) # Character set info from the header 3: SEAL EXPORT:V10.02.01 # the Seal - the exp version tag
20: DBA SYSTEM # exp done as SYSTEM
8461: CONNECT SCOTT # section for user SCOTT 8475: TABLE "EMP"
# complete create table staement 8487: CREATE TABLE "EMP" ("EMPNO" NUMBER(4, 0), "ENAME" VARCHAR2(10),
"JOB" VARCHAR2(9), "MGR" NUMBER(4, 0), "HIREDATE" DATE, "SAL" NUMBER(7, 2), "COMM" NUMBER(7, 2), "DEPTNO" NUMBER(2, 0)) PCTFREE 10 PCTUSED 40
INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 FREELISTS 1
FREELIST GROUPS 1 BUFFER_POOL DEFAULT) TABLESPACE "USERS" LOGGING NOCOMPRESS
# Insert statement
8829: INSERT INTO "EMP" ("EMPNO", "ENAME", "JOB", "MGR", "HIREDATE",
"SAL", "COMM", "DEPTNO") VALUES (:1, :2, :3, :4, :5, :6, :7, :8)
# BIND information
8957: BIND information for 8 columns
col[ 1] type 2 max length 22
col[ 2] type 1 max length 10 cset 31 (WE8ISO8859P1) form 1
col[ 3] type 1 max length 9 cset 31 (WE8ISO8859P1) form 1
col[ 4] type 2 max length 22
col[ 5] type 12 max length 7
col[ 6] type 2 max length 22
col[ 7] type 2 max length 22
col[ 8] type 2 max length 22
Conventional export # Conventional means NOT DIRECT 9003: start of table data # Here begins the first row
现在从建表语句和direct/conventional信息和列数据的头部信息创建unexp语句:
UNEXP TABLE "EMP" ("EMPNO" NUMBER(4, 0), "ENAME" VARCHAR2(10),
"JOB" VARCHAR2(9), "MGR" NUMBER(4, 0), "HIREDATE" DATE, "SAL" NUMBER(7, 2), "COMM" NUMBER(7, 2), "DEPTNO" NUMBER(2, 0))
dump file expdat.dmp from 9003;
Unloaded 14 rows, end of table marker at 9670 # so we have our famous 14 rows
这将创建普通SQL * Loader文件和匹配的控制文件。在输出文件中一个额外的列被添加,这是与行的状态有关。 AP表示行是部分的,(缺失一些列)R指重新同步,这是一个再同步之后的第一行。 O表示重叠,之前的一行有错误,但新行与另一行部分重叠。