溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

IMP-00009:異常結(jié)束導(dǎo)出文件解決方案

發(fā)布時間:2020-08-07 21:33:36 來源:ITPUB博客 閱讀:223 作者:云和恩墨 欄目:數(shù)據(jù)庫


原文: https://www.enmotech.com/web/detail/1/788/1.html  


導(dǎo)讀:本文來自讀者“小豹子加油(網(wǎng)名)”的投稿,主要講述使用imp導(dǎo)入文件出現(xiàn)IMP-00009問題的處理過程。



一、概述




最近在測試環(huán)境的一個Oracle數(shù)據(jù)庫上面,使用exp將表導(dǎo)出沒有問題,而將導(dǎo)出的文件使用imp導(dǎo)入時卻出現(xiàn)了如下錯誤。


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


經(jīng)過反復(fù)實驗,終于找出問題出現(xiàn)的原因,是由以下幾點共同造成的:


a. 數(shù)據(jù)庫中參數(shù)deferred_segment_creation設(shè)置的是默認(rèn)值true,即創(chuàng)建表的時候不立即分配段,等有行的時候才會分配段。
b. 導(dǎo)出的表中有分區(qū)表,而恰好該分區(qū)表存在分區(qū)沒有行的情況,即有的分區(qū)沒有分配段。
c. 導(dǎo)出時使用了direct=true。


解決辦法直接看(三、解決辦法)



二、問題復(fù)現(xiàn)




1. 準(zhǔn)備工作

在測試庫中準(zhǔn)備兩個用戶,tom(導(dǎo)出的用戶),jerry(導(dǎo)入的用戶),分別給予其最大的權(quán)限。


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. 檢查數(shù)據(jù)庫中參數(shù)deferred_segment_creation


SQL> show parameter deferred
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
deferred_segment_creation            boolean     TRUE


可以看到該參數(shù)是true,默認(rèn)值。


3. 創(chuàng)建測試表


SQL> create table tom.t_normal as select * from scott.emp;  // 創(chuàng)建一張普通表,并且有行
SQL> create table tom.t_norows as select * from scott.emp where 1=0;  // 創(chuàng)建一張空表
SQL> create table tom.t_par(id number, name varchar2(10))
partition by list(id)
(partition p01 values(1),
partition p02 values(default));  // 創(chuàng)建一張分區(qū)表,兩個分區(qū)
SQL> insert into tom.t_par values(1, 'aa');  // 往分區(qū)p01插入一條數(shù)據(jù)
SQL> commit;


至此,tom用戶下有三張表,t_normal是普通表,t_norows是一張普通的空表,t_par是分區(qū)表。


通過下面的sql查到tom用戶下只有兩個segment,空表和分區(qū)表中無數(shù)據(jù)的分區(qū)都沒有創(chuàng)建段。


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                                            TABLE
TOM        T_PAR                P01                            TABLE PARTITION


4. 使用tom對表進(jìn)行導(dǎo)出


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


導(dǎo)出日志如下(省略部分無關(guān)內(nèi)容):


. . 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 exported
Export terminated successfully without warnings.


5. 使用jerry對文件進(jìn)行導(dǎo)入


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


導(dǎo)入日志如下(省略部分無關(guān)內(nèi)容):


. . 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 file
Import terminated successfully with warnings.


生產(chǎn)上面出現(xiàn)的錯誤在這里就得到復(fù)現(xiàn)了。而且是在導(dǎo)入"T_PAR":"P02"出現(xiàn)的錯誤,這個正好印證了前面的觀點。



三、解決辦法




解決辦法有以下兩種(任一即可):
a. 使用exp導(dǎo)出的時候不要加direct=true
b. 設(shè)置數(shù)據(jù)庫的參數(shù)deferred_segment_creation為false(注意:這個參數(shù)只影響新建的分區(qū)表,老的分區(qū)表導(dǎo)出再導(dǎo)入仍然會報錯!)



四、有時間、有興趣的讀者可以接著做實驗



可能大家會問,你怎么知道是分區(qū)表的問題,又怎么知道是direct=true的問題,又怎么知道是參數(shù)deferred_segment_creation的問題?接下來我一一驗證。


1. 清空jerry的表,導(dǎo)出tom用戶下表t_normal,t_norows,再導(dǎo)入到j(luò)erry用戶中


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


導(dǎo)出日志:


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


導(dǎo)入日志:


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


可以看到對這兩張表導(dǎo)入是沒有問題的


2. 清空jerry的表,導(dǎo)出tom用戶下表t_par,再導(dǎo)入到j(luò)erry用戶中


清空jerry的表的操作請看上面的步驟


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


導(dǎo)出日志:


. . exporting table                          T_PAR
. . exporting partition                            P01          1 rows exported
. . exporting partition                            P02          0 rows exported
Export terminated successfully without warnings.

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


導(dǎo)入日志:


. 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 file
Import terminated successfully with warnings.


可以看到問題就出在對這張分區(qū)表的導(dǎo)入上面了


3. 清空jerry的表,重新導(dǎo)出tom用戶下表t_par,再導(dǎo)入到j(luò)erry用戶中(這次導(dǎo)出不加參數(shù)direct=true)


清空jerry的表的操作請看上面的步驟

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


導(dǎo)出日志:


. . exporting table                          T_PAR
. . exporting partition                            P01          1 rows exported
. . exporting partition                            P02          0 rows exported
Export terminated successfully without warnings.

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


導(dǎo)入日志:


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


可以看到這次導(dǎo)入沒有任何問題,也就是說不加direct=true直接可以解決問題,但是如果我非要加這個參數(shù)呢,或者說這個命令寫死到程序中了,沒辦法改怎么辦?處理辦法看下面第6條。


4. 清空jerry的表,在tom.t_par的p02分區(qū)中插入一條數(shù)據(jù),重新導(dǎo)出tom用戶下表t_par,再導(dǎo)入到j(luò)erry用戶中(這次導(dǎo)出依然加參數(shù)direct=true)


清空jerry的表的操作請看上面的步驟

SQL> insert into tom.t_par values(2, 'bb');  // 往分區(qū)p02插入一條數(shù)據(jù)
SQL> commit;



通過下面的sql查到t_par兩個分區(qū)都有段了

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 PARTITION
TOM        T_PAR                P02                            TABLE PARTITION
TOM        T_NORMAL                                            TABLE
exp tom/tom file=tom.dmp log=tom_exp.log direct=true tables=t_par

導(dǎo)出日志:

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



導(dǎo)入日志:


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


可以看到分區(qū)表中所有分區(qū)都有數(shù)據(jù)的話,導(dǎo)入就沒有任何問題


5. 驗證deferred_segment_creation參數(shù)對其的影響


清空jerry的表的操作請看上面的步驟


修改數(shù)據(jù)庫中參數(shù)deferred_segment_creation為false


SQL> alter system set deferred_segment_creation=false;


重建tom用戶的t_par表,讓其一個分區(qū)有數(shù)據(jù),另外一個分區(qū)無數(shù)據(jù)


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));  // 創(chuàng)建一張分區(qū)表,兩個分區(qū)
SQL> insert into tom.t_par values(1, 'aa');  // 往分區(qū)p01插入一條數(shù)據(jù)
SQL> commit;


通過下面的sql查到t_par兩個分區(qū)都有段了,即使p02分區(qū)里面沒有數(shù)據(jù)


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 PARTITION
TOM        T_PAR                P02                            TABLE PARTITION
TOM        T_NORMAL                                            TABLE
exp tom/tom file=tom.dmp log=tom_exp.log direct=true tables=t_par

 

導(dǎo)出日志:

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

導(dǎo)入日志:


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


可以看到將參數(shù)deferred_segment_creation修改為false導(dǎo)入也正常,但是這只適用于新建的分區(qū)表,對于已經(jīng)存在的分區(qū)表,依然會導(dǎo)入失敗。處理辦法看下面第6條。


6. 接下來回答上面第3和5步中的問題


如果想用exp,imp進(jìn)行導(dǎo)出導(dǎo)入,導(dǎo)出的時候又必須加direct=true,而且導(dǎo)出的表中包含分區(qū)表,并且該分區(qū)表中存在分區(qū)沒有段的情況。那怎么辦?


光是將參數(shù)deferred_segment_creation修改為false不夠,因為這只影響新建的表,要想對老的表也生效,可以采取下面的辦法。


6.1. 將參數(shù)deferred_segment_creation修改為false
SQL> alter system set deferred_segment_creation=false;


6.2. 使用exp對分區(qū)表進(jìn)行導(dǎo)出(只有那些分區(qū)表中存在分區(qū)沒有分配段的才需要導(dǎo)出),注意不要加direct=true

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


6.3. 刪除該分區(qū)表

SQL> drop table tom.t_par;


6.4. 使用imp對其進(jìn)行導(dǎo)入

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


導(dǎo)入日志


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


導(dǎo)入后查看段的情況


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 PARTITION
TOM        T_PAR                P01                            TABLE PARTITION


可以看到現(xiàn)在即使P02分區(qū)中沒有行,也分配了段。這是由于我先前已經(jīng)將參數(shù)deferred_segment_creation設(shè)置成了false,并且刪除了表,imp在執(zhí)行過程中,會先創(chuàng)建表然后插入數(shù)據(jù),在創(chuàng)建表時,每個分區(qū)都會分配段。也就是說只需要解決老的分區(qū)表中段沒有分配的情況,后面就不會碰到IMP-00009。



五、總結(jié)




只有在分區(qū)表中存在分區(qū)沒有分配段,而且在導(dǎo)出時使用了direct=true參數(shù),這兩種情況在一起才會造成我這個IMP-00009這個錯誤。對于其它的普通表,不管有沒有分配段,是否使用direct=true都不會造成這個錯誤。


我在分析IMP-00009這個問題的時候,首先日志紀(jì)錄只有一行,就寫"IMP-00009: abnormal end of export file",第一時間去查導(dǎo)出的日志,"Export terminated successfully without warnings.",導(dǎo)出的日志沒有顯示任何異常。這就把我整懵逼了。然后我開始求助于萬能的互聯(lián)網(wǎng),查了一圈下來,沒有找到任何解決方案,其實不是大牛不解答,而是問問題的人提供的信息太少了,你就提供個錯誤日志,比方說我這次碰到的問題,假設(shè)你只給個錯誤日志,大牛打死也復(fù)現(xiàn)不出來問題,那就談不上去解決問題了。而往往當(dāng)我們把整個問題都描述清楚了,問題大概率就迎刃而解了。


文章中涉及到的相關(guān)信息備注:


deferred_segment_creation:延遲段創(chuàng)建,上面已經(jīng)通過實驗介紹的很清楚了。
direct=true:導(dǎo)出數(shù)據(jù)時不經(jīng)過buffer cache,這個參數(shù)是個天坑,bug極多,導(dǎo)出時盡量不要用。


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


想了解更多關(guān)于數(shù)據(jù)庫、云技術(shù)的內(nèi)容嗎?

快來關(guān)注“數(shù)據(jù)和云”公眾號、“云和恩墨”官方網(wǎng)站,我們期待與大家一同學(xué)習(xí)和進(jìn)步!

IMP-00009:異常結(jié)束導(dǎo)出文件解決方案


(掃描上方二維碼,關(guān)注“數(shù)據(jù)和云”公眾號,即可查看更多科技文章)


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI