Monday, January 08, 2007

[Oracle Data Pump] ダンプ・ファイルを途中で削除した場合、ジョブが残存する

[概要]
Oracle Data Pump Export/Importのジョブを停止中(STATE: NOT RUNNING)に、OSコマンド
などにより手動でダンプ・ファイルを削除すると、ジョブへの接続が行なえなくなり、結
果としてジョブが残存します。
このような現象が発生する原因と対処方法について下記に説明します。


[対象リリース]
Oracle Database 10g Release1 (10.1.0)


[対象プラットフォーム]
すべてのプラットフォーム


[詳細]
(a) 具体例
本現象が発生する具体例を以下に示します。

1. Data Pump Exportを実行し、対話方式インタラクティブ・モードに切り替えて、stop_job
コマンドを実行します。

% expdp scott/tiger directory=test_dir dumpfile=scott.dmp nologfile=y job_name=scott_job

Export: Release 10.1.0.4.0 - 64bit Production on 金曜日, 08 7月, 2005 15:16

Copyright (c) 2003, Oracle. All rights reserved.

接続先: Oracle Database 10g Enterprise Edition Release 10.1.0.4.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP and Data Mining Scoring Engine options
FLASHBACKでは、データベース整合性が自動的に維持されます。
"SCOTT"."SCOTT_JOB"を起動しています: scott/******** directory=test_dir dumpfile=scott.dmp nolo
gfile=y job_name=scott_job
BLOCKSメソッドを使用して見積り中です...
^C
Export> stop_job
このジョブを停止しますか([y]/n): yes

2. dba_datapump_jobs ビューを確認して、1. で停止したジョブの状態が 'NOT RUNNING' にな
  ることを確認します。

SQL> select * from dba_datapump_jobs where JOB_NAME='SCOTT_JOB';

OWNER_NAME JOB_NAME OPERATION
------------------------ ------------------------------ ------------------------
JOB_MODE STATE DEGREE ATTACHED_SESSIONS
------------------------ ------------------------------ ---------- -----------------
SCOTT SCOTT_JOB EXPORT

SCHEMA NOT RUNNING 0 0


3. 出力されたダンプファイルの存在を確認し、これを削除します。

% ls -l /home/pires/ora10104/work/scott.dmp
-rw-r----- 1 ora10104 dba 4096 7月 8日 15:16 /home/pires/ora10104/work/scott.dmp

% rm scott.dmp
rm: scott.dmp を消去しますか (yes/no)? y


4. attach パラメータを使用して、上記で停止したジョブに再度アタッチします。すると、下記の
  ようなエラーが発生し、アタッチに失敗します。

% expdp scott/tiger attach=scott_job

Export: Release 10.1.0.4.0 - 64bit Production on 金曜日, 08 7月, 2005 15:20

Copyright (c) 2003, Oracle. All rights reserved.

接続先: Oracle Database 10g Enterprise Edition Release 10.1.0.4.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP and Data Mining Scoring Engine options
ORA-39002: 操作が無効です
ORA-39000: ダンプ・ファイル指定が無効です
ORA-31640: ダンプ・ファイル"/home/pires/ora10104/work/scott.dmp"を読取りのためにオープンできません
ORA-27037: ファイル・ステータスを取得できません。
SVR4 Error: 2: No such file or directory
Additional information: 3

5. dba_datapump_jobs ビューを確認すると、該当のジョブ(ジョブ名がSCOTT_JOB)が
  残存していることが分かります。

SQL> select * from dba_datapump_jobs where JOB_NAME='SCOTT_JOB';

OWNER_NAME JOB_NAME OPERATION
------------------------ ------------------------------ ------------------------
JOB_MODE STATE DEGREE ATTACHED_SESSIONS
------------------------ ------------------------------ ---------- -----------------
SCOTT SCOTT_JOB EXPORT

SCHEMA NOT RUNNING 0 0


(b) 発生原因
Oracle Data Pump ではジョブを実行する際に、ユーザのスキーマにジョブに関する様々な情報を
格納する 'マスター表' という表が作成されます。これは Data Pump の機能の中心的役割を果た
すものです。
このマスター表には、expdp もしくは impdp を実行するオブジェクトやジョブの実行パラメータ
および各プロセスの状態、ダンプファイルの作成状況などの情報を格納しています。

マスター表は、expdp を実行中に作成され、expdp の最終段階でダンプファイルに書き込まれます。
これとは逆に、impdp 実行時にはその最初の段階で'マスター表をロードするようになっています。
対象のジョブにアタッチする際にも、ジョブの情報を取得するために、ファイルセットにアクセス
して情報を取得しようとします。ジョブのステータスが 'NOT RUNNING' (停止中)であっても、
その途中でマスターテーブルの情報を包含したダンプファイルを削除してしまうことで、ジョブに
関する情報を取得することができないため、このようにエラーを返し、さらに dba_datapump_jobs
ビューにエントリが残ってしまうという状況が発生します。
本現象の影響は、dba_datapump_jobs ビューにエントリが残るのみとなります。


(c) 対処方法
下記のいずれかの方法を実施することにより、dba_datapump_jobs ビューからジョブのエントリを
削除することができます。

- ジョブを起動したユーザを削除する
- マスター表を削除する

マスター表の削除についてさらに詳しく説明します。
上記の具体例で示したように、ビューにエントリが残るのは、データベース上にマスターテーブル
が不正な形で残ってしまっているためとなります。正常に処理が終了した場合にはこのようにエン
トリが残ることはありません。
マスター表は、実行したジョブ名と同じ名前で、そのジョブを開始したユーザのスキーマ内に作成
されます。これを手動で削除することによりビューに不正に残存してしまったエントリを削除する
ことができます。
なお、これを手動で削除することは問題となるオペレーションではありません。
下記にエントリを削除する方法を紹介します。

1. dba_tables/user_tables などのビューから Data Pump のジョブを起動・開始したユーザの所有
する表を確認します。マスター表は実行ジョブ名と同じ名称となります。
  今回の例では、マスター表の名前は 'SCOTT_JOB' です。

SQL> connect scott/tiger
接続されました。
SQL> select table_name from user_tables;

TABLE_NAME
------------------------------
SCOTT_JOB
SALGRADE
BONUS
EMP
DEPT

5行が選択されました。

2. マスター表を削除します。

SQL> drop table SCOTT_JOB purge;

表が削除されました。

3. dba_tables/user_tables ビューおよび dba_datapump_jobs ビューを参照し、該当エントリが削除
  されていることが確認できます。

SQL> select table_name from user_tables where table_name='SCOTT_JOB';

レコードが選択されませんでした。

SQL> select * from dba_datapump_jobs where job_name='SCOTT_JOB';

レコードが選択されませんでした。


[参照情報]
『Oracle Database ユーティリティ 10g リリース1(10.1)』


[更新履歴]
2005/07/08 10.1.0.4での検証結果をもとに全面的に修正し公開区分を「サポート契約あり」に変更
2004/03/18 本文書を公開(社内のみ)

No comments: