【引言】
近日,因实际工作需要,笔者对Exp/Expdp导出的DMP文件进行了初步研究,现记录如下,一防遗忘,二来或可供DBA同行们参阅与指正。
Oracle从10g以来,在原有Exp数据导出工具之外,新增加了Expdp(Oracle称其为DataPump数据泵)工具,效率号称提升了好几个数量级。或许是为了便于DBA的了解,这两个工具导出的文件名后缀默认都是DMP。这样一来,无形中造成了不必要的误解与麻烦:
一是“粗心”的DBA误以为这两个DMP文件格式兼容(Oracle或许在某个Concept中有专门介绍);
二是这两个“美猴王”单从外观上看实在有点“傻傻分不清楚”,除非用Hex编辑器打开它;
三是作为DMP文件核心信息的、Oracle数据库“最复杂而犯晕”的数据库字符集信息的记录方式很让人挠头。
下面是本人的浅见,错误之处,恳请各位不吝赐教!
一. Exp导出格式的DMP文件
该格式的DMP文件在文件头区记录了两个重要信息:一是数据库版本、一是数据库字符集;数据库版本格式为Vxx.xx.xx,下图为08.01.07即Oracle8.1.7版,数据库字符集为该文件的第2、3字节(注意:偏移从0位起算,第2、3字节即是00000000h的1、2号位),本例为0001,即US7ASCII,03 54即为CHS16GBK,修改此2字节可手工修改Exp导出文件的字符集。需要特别提醒注意的是:修改DMP文件推荐使用WinHEX、UltraEdit等编辑工具,确保在HEX(16进制,下同)修改模式下进行,误修改可能会导致文件永久损坏!!!

此外,Exp工具的导出日志文件中详细记录了数据库字符集信息,如需查询字符集,只需查看该日志即可。以下是Exp工具的LOG日志文件格式示例:

可见,数据库版本、数据库字符集、国家字符集已经在日志中有记录了。
二. Expdp格式的DMP文件
该工具导出的DMP文件在文件头区记录的信息更多,有平台版本,见下图标记1,为IBMPC/WINNT64-9.1.0,有数据库实例名,下图标记2,为oracle980zd,数据库字符集,下图标记3,为CHS16GBK,数据库版本,下图标记4,格式为xx.xx.xx.xx.xx,本例为11.02.00. 04.00,即为版本11.2.0.4.0。
打算手工修改Expdp导出的DMP文件字符集的朋友们要当心,笔者不能冒猜是否强制修改120、130h段就可以达到目的!!!在没有实验证实的情况下,不建议强制修改此DMP文件的数据库字符集,强烈建议按照导出时的字符集导入目标库,再对目标库的字符集进行修改,这是最安全、保险的操作。
作为一名DBA,建议Oracle在将DMP导入目标库时由用户选择是否做字符集转换。显然,这得有一个前提,那就是目标数据库字符集必须是源DMP文件字符集的超集!而且,用户必须同意Oracle对源库的表定义进行目标库字符集适配的调整权限,如果目标库字符集不兼容源DMP数据库字符集,导入的数据自然会变成乱码。
此外,该文件的头区信息与Exp的DMP格式有明显的不同。首先,该文件的2、3字节不表示字符集了,01 91已不是字符集内码了,修改此代码肯定会造成文件损坏;其次,此文件的40、50h偏移段与Exp导出的DMP格式完全不同,Exp的恒为20,即空白,Expdp的为“SYS_EXPORT”等字样。笔者以为,此段或可成为两种格式的判断依据。

同样地,下面是Expdp工具的LOG日志文件格式示例,数据库字符集信息居然被Oracle省去了,好在DMP文件头记录的信息已经足够多了。

三. 小结
最后,经过上述一番简略分析,我们可以得出以下几个要点:
-
Exp工具导出的DMP文件格式与Expdp导出的文件格式十分地不同,其最大的不同在文件头的40-50h区段;
-
Exp格式文件头记录的信息相对简略,数据库字符集以明文记录在Log日志文件中以及文件头的2、3字节,以代码方式表示;
-
Expdp格式记录的信息更更多,也更详细,其数据库字符集只记录在DMP文件头的120-130h区段,以明文方式记录;
-
修改DMP文件的数据库字符集是危险操作,必须首先分清楚DMP文件的生成工具再考虑修改策略,低版本的Exp格式尚可修改,Expdp格式的不建议修改;
-
Oracle出品的Exp/Expdp两种工具导出的两种DMP文件格式,客观来说,在一定程度上的确增加了用户的辨识度和复杂度。
笔者2022-10-12于北京
EM:Iyft_hws150@sina.com
【 后 记 】
针对Exp/Expdp工具版本与数据库版本的几种情形,笔者作了如下四类简单实验,结果表明:Exp工具导出的DMP格式文件中似乎没有记录数据库的版本号,而Expdp工具导出的DMP格式文件中似乎没有记录导出工具的版本号。
以下是实验结果,错误之处恳请读者批评指正。
(甲) Exp工具与数据库不同版本
低版本Exp工具导出高版本数据库的DMP格式:笔者使用10.2.0.1版本的Exp工具导出11.2.0.4版数据库时,LOG日志没有变化,DMP头文件区记录的是Exp工具的版本号,这和之前的判断是不相符的,之前误以为是数据库的版本号。如下图:

(乙) Exp工具与数据库同版本
再接再厉,我们测试一下相同版本的Exp导出数据库的情形。可以看到:头文件区记录了Exp工具的版本号,而在20h区第4个字节起,出现了变化:Exp10.2.0.1记录值为2048.0.32.0,而Exp11.2.0.4的值为2048.0.64.0,这个值的含义有待于从Oracle相关的资料中获得支持。也就是说,Exp导出的DMP文件中似乎没有记录数据库版本号!!!
当然,Exp工具的LOG日志中已经记录了数据库版本号、字符集与国家字符集。

(丙) Expdp工具与数据库不同版本
低版本Expdp导出高版本数据库的情形(实验环境:Expdp10.2.0.1,数据库11.2.0.4)。下图为DMP文件与LOG日志文件,LOG日志中记录了Expdp工具的版本和数据库版本,而DMP文件只在1d0、1e0区记录了服务版本号。也就是说,Expdp格式的DMP文件似乎没有记录导出工具的版本号,而只在LOG日志中记录了工具与数据库版本号!!!


(丁) Expdp工具与数据库相同版本
同版本Expdp导出同版本数据库时,DMP头文件区和低版本导出时的格式完全相同,不同之处仅仅在于LOG日志文件中记录了Expdp的版本号和数据库的版本号,如下图所示。

最后,关于高版本的Exp工具导出低版本的数据库和高版本的Expdp工具导出低版本的数据库这两种“开倒车”的行为,Oracle官方是严格禁止的,如果读者有兴趣,可以自己模拟一下。
在模拟过程中,如下兼容参数或许能派上用场:Exp工具不支持版本兼容参数,Expdp工具支持VERSION参数,即要导出的对象的版本,其有效关键字为: (COMPATIBLE), LATEST 或任何有效的数据库版本。
Good luck!
2022-10-14补




