mingwei 2015-08-22
“想当然”是一种思维定式,也是一种思维惯性。当我们经常处理一类问题,自认为信心满满的时候,就会形成思维定式和惯性。思维定式和惯性可以帮助我们快速定位问题,解决问题,但是也会形成“一叶遮目”。
相同的技术,不同的场景出现问题是千差万别。特别是在第三方不确定人员的参与下,这种问题出现就更加复杂多变。我们能做到的仅是不断积累经验,提高自身阅历经验,永远本着一颗“本心”去面对我们自己的技术生涯。
DMP文件是目前Oracle数据逻辑备份、传输和还原的最常见的方法。无论是开发人员倾向的Exp/Imp工具,还是DBA越来越接受的Data Pump,都是以.dmp作为文件载体。处理导入导出dmp文件过程中的出现各种问题,已经被大家挖掘差不多了。所以,一般水平的DBA,都可以聊几条常见错误。
笔者一个同事在处理从第三方公司发送Dmp文件时候,处理时遇到问题。联系笔者帮忙解决,在纠结一段时间之后,问题被意想不到的定位和解决。记录下问题,权作为需要朋友不时之需。
1、问题说明
同事在做一个项目,从下属各公司收集数据Dmp文件进行后续处理整合。由于前期沟通有一些问题,所以并没有规定上交文件是用Exp/Imp提交还是DataPump,更不要说版本之类的信息了。所以,同事能做的只有逐步实验进行测试导入。每个文件都意味着一次实验。
在处理过程中,一个公司提交的两个dmp文件问题显现出来。无论是Imp还是Impdp,都不能顺利处理。笔者索要了问题文件,进行初步检查和处理。
文件自身并不是很大,只有几K,这对于Oracle DMP文件来讲是比较奇怪的。因为无论如何,Oracle在保存数据表元数据的时候,都会保存一定的信息文件。那么小的dmp文件是比较少见的。事后想,这就是重要的问题线索。
转移到Windows平台上,调用imp和impdp命令处理文件。
C:\Users\Administrator>impdp \"/ as sysdba\" dumpfile=i_aaa_statistical.dmp
Import: Release 11.2.0.4.0 - Production on Thu Aug 13 17:03:24 2015
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit
Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
ORA-39001: invalid argument value
ORA-39000: bad dump file specification
ORA-31619: invalid dump file "C:\app\Administrator/admin/sicsdb/dpdump/i_aaa_statistical.dmp"
C:\app\Administrator\admin\sicsdb\dpdump>imp \"/ as sysdba\" file=i_aaa_statistical.dmp
Import: Release 11.2.0.4.0 - Production on Thu Aug 13 17:07:46 2015
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit
Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
IMP-00037: Character set marker unknown
IMP-00000: Import terminated unsuccessfully
调用Impdp命令,报错信息是文件格式不正确。在Oracle官方经验集合中,一般是传输过程(特别是FTP传输)中,text/binary格式数据设置错误导致文件损坏。这种错误在之前笔者也遇到过,除了找原系统管理员重新传输外没有其他办法。
调用Imp命令,报错信息也是同样迷惑。Oracle认为字符集标记错误,无法进行解析。在之前的Blog中,我们了解到dmp文件文件头中包括字符集信息。
两个工具的错误信息,同样是迷惑。Impdp的信息表示文件已经损坏,没有修复的可能。而Imp起码还有一个入手点。笔者打算死马当活马医,起码看看文件头内容。
[oracle@localhost dpdump]$ cat i_aaa_statistical.dmp | od -x |head -1|awk '{print $2 $3}'|cut -c 3-6
ef70
SQL> select nls_charset_name(to_number('ef70','xxxx')) from dual;
NLS_CHARSET_NAME(TO_NUMBER('EF
----------------------------------------
的确是文件头错误。那么,笔者想起来Linux下的file命令,可以查看到文件的一些基础信息。想起码看看损坏文件的类型是什么样子。
[oracle@localhost dpdump]$ file i_aaa_statistical.dmp
i_aaa_statistical.dmp: UTF-8 Unicode (with BOM) Java program text, with CRLF line terminators
UTF-8格式文件。根据笔者之前的经验,作为一个dmp文件,起码是一个二进制文件吧。从file命令结果看,这显然是一个与Java程序相关的文本文件,还包括换行符号。
为了确定出一个Dmp文件究竟是什么样子,笔者分别对Exp和Expdp生成的dmp文件进行解析。
--Expdp文件
[oracle@localhost dpdump]$ file INT_TEST_150317.dmp
INT_TEST_150317.dmp: DBase 3 data file (1728057941 records)
--Exp文件
[oracle@localhost dpdump]$ file scott.dmp
scott.dmp: DBase 3 data file (1380929624 records)
从结果看,起码与Database相关的文件类型。但是问题dmp文件无论如何也不能算是一个二进制文件。
于是乎,笔者壮着胆子,用文本编辑器打开了文件。结果一切真相大白。
prompt PL/SQL Developer import file
prompt Created on 2015年7月01日 by xxxxxx
set feedback off
set define off
prompt Creating I_aaa_stat...
create table I_aaa_stat
(
(篇幅原因,有省略…..)
)
tablespace My_TBS
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
next 1M
minextents 1
maxextents unlimited
)
nologging;
prompt Disabling triggers for I_aaa_stat...
alter table I_aaa_stat disable all triggers;
insert into I_aaa_stat (companyname, plancode, polyr, count)
从文件中,可以看出下属公司是利用PL/SQL Developer的某项功能将数据导出,阴差阳错的将文本文件保存成dmp文件拓展名。
3、结论
后续的处理似乎不需要再过多的解释。这个案例按说虽然蹊跷,但是还算简单。留给笔者最大的感受是:我们如何看待经验?经验是我们日常工作、学习中积累的宝贵财富,也是我们在专业逐步深入的水位线。
但是同时,经验也会形成定式。让我们惯性的去做、去说、去想。当我们的经验不能应对新的问题,求知求变是必不可少的心态和过程。