百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 优雅编程 > 正文

使用imp导入文件竟出现IMP-00009问题,该如何处理?

sinye56 2024-10-07 14:38 9 浏览 0 评论

原文:https://www.enmotech.com/web/detail/1/788/1.html (复制链接,打开浏览器即可查看)

导读:本文来自读者“小豹子加油(网名)”的投稿,主要讲述使用imp导入文件出现IMP-00009问题的处理过程。

一、概述


最近在测试环境的一个Oracle数据库上面,使用exp将表导出没有问题,而将导出的文件使用imp导入时却出现了如下错误。


IMP-00009: abnormal end of export fileImport terminated successfully with warnings.

经过反复实验,终于找出问题出现的原因,是由以下几点共同造成的:

a. 数据库中参数deferred_segment_creation设置的是默认值true,即创建表的时候不立即分配段,等有行的时候才会分配段。

b. 导出的表中有分区表,而恰好该分区表存在分区没有行的情况,即有的分区没有分配段。

c. 导出时使用了direct=true。

解决办法直接看(三、解决办法)

二、问题复现


1. 准备工作

在测试库中准备两个用户,tom(导出的用户),jerry(导入的用户),分别给予其最大的权限。


SQL> create user tom identified by tom;SQL> grant dba to tom;SQL> create user jerry identified by jerry;SQL> grant dba to jerry;

2. 检查数据库中参数deferred_segment_creation


SQL> show parameter deferredNAME TYPE VALUE------------------------------------ ----------- ------------------------------deferred_segment_creation boolean TRUE

可以看到该参数是true,默认值。

3. 创建测试表


SQL> create table tom.t_normal as select * from scott.emp; // 创建一张普通表,并且有行SQL> create table tom.t_norows as select * from scott.emp where 1=0; // 创建一张空表SQL> create table tom.t_par(id number, name varchar2(10))partition by list(id)(partition p01 values(1),partition p02 values(default)); // 创建一张分区表,两个分区SQL> insert into tom.t_par values(1, 'aa'); // 往分区p01插入一条数据SQL> commit;

至此,tom用户下有三张表,t_normal是普通表,t_norows是一张普通的空表,t_par是分区表。

通过下面的sql查到tom用户下只有两个segment,空表和分区表中无数据的分区都没有创建段。


SQL> select owner,segment_name,partition_name,segment_type from dba_segments where owner='TOM';OWNER SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE---------- -------------------- ------------------------------ ------------------TOM T_NORMAL TABLETOM T_PAR P01 TABLE PARTITION

4. 使用tom对表进行导出

exp tom/tom file=tom.dmp log=tom_exp.log direct=true

导出日志如下(省略部分无关内容):


. . exporting table T_NORMAL 14 rows exported. . exporting table T_NOROWS 0 rows exported. . exporting table T_PAR. . exporting partition P01 1 rows exported. . exporting partition P02 0 rows exportedExport terminated successfully without warnings.

5. 使用jerry对文件进行导入

mp jerry/jerry file=tom.dmp log=jerry_imp.log fromuser=tom touser=jerry

导入日志如下(省略部分无关内容):


. . importing table "T_NORMAL" 14 rows imported. . importing table "T_NOROWS" 0 rows imported. . importing partition "T_PAR":"P01" 1 rows imported. . importing partition "T_PAR":"P02"IMP-00009: abnormal end of export fileImport terminated successfully with warnings.

生产上面出现的错误在这里就得到复现了。而且是在导入"T_PAR":"P02"出现的错误,这个正好印证了前面的观点。

三、解决办法


解决办法有以下两种(任一即可):

a. 使用exp导出的时候不要加direct=true

b. 设置数据库的参数deferred_segment_creation为false(注意:这个参数只影响新建的分区表,老的分区表导出再导入仍然会报错!)

四、有时间、有兴趣的读者可以接着做实验


可能大家会问,你怎么知道是分区表的问题,又怎么知道是direct=true的问题,又怎么知道是参数deferred_segment_creation的问题?接下来我一一验证。

1. 清空jerry的表,导出tom用户下表t_normal,t_norows,再导入到jerry用户中


SQL> drop user jerry cascade; // 通过重建jerry用户来清空jerry的表SQL> create user jerry identified by jerry;SQL> grant dba to jerry;exp tom/tom file=tom.dmp log=tom_exp.log direct=true tables=t_normal,t_norows

导出日志:


. . exporting table T_NORMAL 14 rows exported. . exporting table T_NOROWS 0 rows exportedExport terminated successfully without warnings.imp jerry/jerry file=tom.dmp log=jerry_imp.log fromuser=tom touser=jerry

导入日志:


. . importing table "T_NORMAL" 14 rows imported. . importing table "T_NOROWS" 0 rows importedImport terminated successfully without warnings.

可以看到对这两张表导入是没有问题的

2. 清空jerry的表,导出tom用户下表t_par,再导入到jerry用户中

清空jerry的表的操作请看上面的步骤


exp tom/tom file=tom.dmp log=tom_exp.log direct=true tables=t_par

导出日志:


. . exporting table T_PAR. . exporting partition P01 1 rows exported. . exporting partition P02 0 rows exportedExport terminated successfully without warnings.imp jerry/jerry file=tom.dmp log=jerry_imp.log fromuser=tom touser=jerry

导入日志:


. importing TOM's objects into JERRY. . importing partition "T_PAR":"P01" 1 rows imported. . importing partition "T_PAR":"P02"IMP-00009: abnormal end of export fileImport terminated successfully with warnings.

可以看到问题就出在对这张分区表的导入上面了

3. 清空jerry的表,重新导出tom用户下表t_par,再导入到jerry用户中(这次导出不加参数direct=true)

清空jerry的表的操作请看上面的步骤

exp tom/tom file=tom.dmp log=tom_exp.log tables=t_par

导出日志:


. . exporting table T_PAR. . exporting partition P01 1 rows exported. . exporting partition P02 0 rows exportedExport terminated successfully without warnings.imp jerry/jerry file=tom.dmp log=jerry_imp.log fromuser=tom touser=jerry

导入日志:


. importing TOM's objects into JERRY. . importing partition "T_PAR":"P01" 1 rows imported. . importing partition "T_PAR":"P02" 0 rows importedImport terminated successfully without warnings.

可以看到这次导入没有任何问题,也就是说不加direct=true直接可以解决问题,但是如果我非要加这个参数呢,或者说这个命令写死到程序中了,没办法改怎么办?处理办法看下面第6条。

4. 清空jerry的表,在tom.t_par的p02分区中插入一条数据,重新导出tom用户下表t_par,再导入到jerry用户中(这次导出依然加参数direct=true)

清空jerry的表的操作请看上面的步骤


SQL> insert into tom.t_par values(2, 'bb'); // 往分区p02插入一条数据SQL> commit;

通过下面的sql查到t_par两个分区都有段了

SQL> select owner,segment_name,partition_name,segment_type from dba_segments where owner='TOM';OWNER SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE---------- -------------------- ------------------------------ ------------------TOM T_PAR P01 TABLE PARTITIONTOM T_PAR P02 TABLE PARTITIONTOM T_NORMAL TABLEexp tom/tom file=tom.dmp log=tom_exp.log direct=true tables=t_par

导出日志:


. . exporting table T_PAR. . exporting partition P01 1 rows exported. . exporting partition P02 1 rows exportedExport terminated successfully without warnings.imp jerry/jerry file=tom.dmp log=jerry_imp.log fromuser=tom touser=jerry

导入日志:


. importing TOM's objects into JERRY. . importing partition "T_PAR":"P01" 1 rows imported. . importing partition "T_PAR":"P02" 1 rows importedImport terminated successfully without warnings.

可以看到分区表中所有分区都有数据的话,导入就没有任何问题

5. 验证deferred_segment_creation参数对其的影响

清空jerry的表的操作请看上面的步骤

修改数据库中参数deferred_segment_creation为false


SQL> alter system set deferred_segment_creation=false;

重建tom用户的t_par表,让其一个分区有数据,另外一个分区无数据


SQL> drop table tom.t_par;SQL> create table tom.t_par(id number, name varchar2(10))partition by list(id)(partition p01 values(1),partition p02 values(default)); // 创建一张分区表,两个分区SQL> insert into tom.t_par values(1, 'aa'); // 往分区p01插入一条数据SQL> commit;

通过下面的sql查到t_par两个分区都有段了,即使p02分区里面没有数据


SQL> select owner,segment_name,partition_name,segment_type from dba_segments where owner='TOM';OWNER SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE---------- -------------------- ------------------------------ ------------------TOM T_PAR P01 TABLE PARTITIONTOM T_PAR P02 TABLE PARTITIONTOM T_NORMAL TABLEexp tom/tom file=tom.dmp log=tom_exp.log direct=true tables=t_par

导出日志:


. . exporting table T_PAR. . exporting partition P01 1 rows exported. . exporting partition P02 0 rows exportedExport terminated successfully without warnings.imp jerry/jerry file=tom.dmp log=jerry_imp.log fromuser=tom touser=jerry

导入日志:


. importing TOM's objects into JERRY. . importing partition "T_PAR":"P01" 1 rows imported. . importing partition "T_PAR":"P02" 0 rows importedImport terminated successfully without warnings.

可以看到将参数deferred_segment_creation修改为false导入也正常,但是这只适用于新建的分区表,对于已经存在的分区表,依然会导入失败。处理办法看下面第6条。

6. 接下来回答上面第3和5步中的问题

如果想用exp,imp进行导出导入,导出的时候又必须加direct=true,而且导出的表中包含分区表,并且该分区表中存在分区没有段的情况。那怎么办?

光是将参数deferred_segment_creation修改为false不够,因为这只影响新建的表,要想对老的表也生效,可以采取下面的办法。

6.1. 将参数deferred_segment_creation修改为false

SQL> alter system set deferred_segment_creation=false;

6.2. 使用exp对分区表进行导出(只有那些分区表中存在分区没有分配段的才需要导出),注意不要加direct=true

exp tom/tom file=tom.dmp log=tom_exp.log tables=t_par

6.3. 删除该分区表

SQL> drop table tom.t_par;

6.4. 使用imp对其进行导入

imp tom/tom file=tom.dmp log=tom_imp.log full=y

导入日志


. importing TOM's objects into TOM. . importing partition "T_PAR":"P01" 1 rows imported. . importing partition "T_PAR":"P02" 0 rows importedImport terminated successfully without warnings.

导入后查看段的情况


SQL> select owner,segment_name,partition_name,segment_type from dba_segments where owner='TOM';OWNER SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE---------- -------------------- ------------------------------ ------------------TOM T_PAR P02 TABLE PARTITIONTOM T_PAR P01 TABLE PARTITION

可以看到现在即使P02分区中没有行,也分配了段。这是由于我先前已经将参数deferred_segment_creation设置成了false,并且删除了表,imp在执行过程中,会先创建表然后插入数据,在创建表时,每个分区都会分配段。也就是说只需要解决老的分区表中段没有分配的情况,后面就不会碰到IMP-00009。

五、总结


只有在分区表中存在分区没有分配段,而且在导出时使用了direct=true参数,这两种情况在一起才会造成我这个IMP-00009这个错误。对于其它的普通表,不管有没有分配段,是否使用direct=true都不会造成这个错误。

我在分析IMP-00009这个问题的时候,首先日志纪录只有一行,就写"IMP-00009: abnormal end of export file",第一时间去查导出的日志,"Export terminated successfully without warnings.",导出的日志没有显示任何异常。这就把我整懵逼了。然后我开始求助于万能的互联网,查了一圈下来,没有找到任何解决方案,其实不是大牛不解答,而是问问题的人提供的信息太少了,你就提供个错误日志,比方说我这次碰到的问题,假设你只给个错误日志,大牛打死也复现不出来问题,那就谈不上去解决问题了。而往往当我们把整个问题都描述清楚了,问题大概率就迎刃而解了。

文章中涉及到的相关信息备注:

deferred_segment_creation:延迟段创建,上面已经通过实验介绍的很清楚了。

direct=true:导出数据时不经过buffer cache,这个参数是个天坑,bug极多,导出时尽量不要用。

出处:https://www.cnblogs.com/ddzj01/

想了解更多关于数据库、云技术的内容吗?

快来关注“数据和云”公众号、“云和恩墨”官方网站,我们期待与大家一同学习和进步!

(扫描上方二维码,关注“数据和云”公众号,即可查看更多科技文章)

相关推荐

6个接私活的网站,你有技术就有钱

如果觉得有帮助,还请大家帮忙多多转发,点个关注作者:发哥链接:GitHubDaily本篇文章会向大家推荐国内外几个接外包比较靠谱的平台,主旨是贵精不贵多。因此,像「猪x戒」这种会让程序员自贬身价,扰乱...

Java开源可商用的CMS建站系统_java建站源码

Java研发的CMS内容管理系统具有许多优势和特点,包括以下几个方面:跨平台性:Java是一种跨平台的编程语言,可以在不同的操作系统上运行,包括Windows、Linux、Mac等。这意味着Java...

SEO新手建站必看"干货"优质空间和功能选择技巧!

一.空间的分类服务器:远程的高级大型计算机。vps:虚拟服务器。虚拟空间:也称虚拟主机云主机:是在一组集群主机上虚拟出多个类似独立主机的部分,集群中每个主机上都有云主机的一个镜像,从而大大提高了虚拟主...

千字长文教你使用 宝塔面板 快速搭建网站

本文将教大家使用宝塔面板快速搭建网站,云服务器购买以及域名注册部分请自行上网搜索了解,亦可留言联系小编进行咨询。如果是和下方一样本地搭建演示的话,则不需要付费购买域名和主机。宝塔面板的是...

BlueHost香港虚拟主机建站的5个优点

应该是从2006年左右开始,如果我们建站选择国内的主机需要备案手续,而且比较繁琐,且根据各地的不同政策还需要到接入点拍照登记个人信息等,一来比较繁琐,二来我们担心万一网站可能存在的信息问题导致不必要的...

10款好用的Linux服务器网站管理面板推荐

如今在建站时,很多人都会使用管理面板来辅助建站,因为相对于手动安装软件,面板更加简单而且高效,即使新手也能很快学会搭建网站,在本文中我们来推荐几款好用的网站管理面板宝塔面板宝塔面板是一款简单好用的网站...

小白拥有一台云服务器到底能干些什么?成就感爆棚的简单方案!

?云服务器是什么?云服务器(比如阿里云、腾讯云等)是提供给用户的一种虚拟服务器资源,你可以把它看作一台“rent的电脑”,只需要支付少量费用就可以拥有一个功能强大的网络设备。对于小白来说,拥有一...

苹果CMS,苹果CMS采集插件,苹果CMS快速建站(图文教程)

苹果CMS,有着强大的管理功能,管理后台界面大方、操作简单、功能齐全、模块众多、双端管理。苹果CMS加上丰富的系统标签,系统内置了丰富的cms标签并支持thinkphp框架标签完美融合,可以调取系统内...

新手搭建网站、小程序、APP等系统,如何选择服务器?

今天和小蔡和大家说说,新手搭建网站,如何选择服务器?废话不多说,直接来干货。服务器是存放网站源代码的容器,也是运行网站程序的工具,所以是不可或缺的。新手刚接触搭建网站,若不知道怎么去选择一台适合自己...

在海外VPS服务器(Hostinger)上配置宝塔面板的操作步骤

不得不说,宝塔面板是真的好用啊~用上就放不下了,一些海外的免费开源的服务器集成面板(比如CloudPanel)我也用了,不喜欢,真的不如宝塔面板方便耐用。今天聊一下在海外服务器(也包括国内服务器,没有...

干货盘点:每个wordpress站长都推荐完成的60个任务清单

构建和运营wordpress网站包含了很多重要任务,遗漏哪一方面都可能造成或大或小的不良后果,因此我们特别整理了这个任务清单,为你查漏补缺,希望能对您现在运营或者即将开始构建的wordpress网站有...

为什么站长喜欢选择BlueHost主机建站

BlueHost正式成立于2003年,从事主机(虚拟主机)业务至今已经将近十余年,无论从口碑还是用户的评价,我们基本很少看到关于Bluehost主机产品和商家负面的评论信息。从2014年开始,Blue...

自助建站时代来临 半小时成建站达人

“H5”意为第五代HTML,即第五代网页编写语言。自从1991年第一代HTML开始研发以来,网页编写、网站建设一直都属于高端技术行业,网站建设人员都是一些专业型人才,这也意味着网站的建设和维护都需要不...

现代化、开源的 Linux 服务器运维管理面板

1Panel是一个现代化、开源的Linux服务器运维管理面板。1Panel的功能和优势包括:快速建站:深度集成Wordpress和Halo,域名绑定、SSL证书配置等一键搞定;高效管理...

[1Panel]开源,现代化,新一代的 Linux 服务器运维管理面板

测评介绍本期测评试用一下1Panel这款面板。1Panel是国内飞致云旗下开源产品。整个界面简洁清爽,后端使用GO开发,前端使用VUE的Element-Plus作为UI框架,整个面板的管理都是基于do...

取消回复欢迎 发表评论: