事象
regionsテーブルを参照するパッケージとファンクションがそれぞれ存在します。
CREATE OR PACKAGE P_EXAMPLE AS
ASIA CONSTANT regions.region_name%type := 'Asia';
END P_EXAMPLE;
CREATE OR FUNCTION F_EXAMPLE RETURN regions.region_id%type AS
ret regions.region_id%type;
BEGIN
SELECT region_id into ret FROM regions WHERE region_name = P_EXAMPLE.ASIA;
RETURN ret;
END;
このパッケージとファンクションはそれぞれコンパイルOKの状態です。
SELECT OBJECT_NAME, OBJECT_TYPE, STATUS
FROM USER_OBJECTS
WHERE OBJECT_NAME LIKE '%EXAMPLE'
OBJECT_NAME | OBJECT_TYPE | STATUS |
---|---|---|
F_EXAMPLE | FUNCTION | VALID |
P_EXAMPLE | PACKAGE | VALID |
この状態で、regionsテーブルに対し、impdpを実施します。
impdp dump_user/passw0rd@localhost:1521/xepdb1 \
directory=DUMP_DIRECTORY \
LOGFILE=impdp.log \
dumpfile=HR.dmp \
content=all \
table_exists_action=replace \
tables=HR.regions
すると、impdpは成功しますが、regionsテーブルを参照するパッケージとファンクションのステータスがINVALIDになってしまいました。
SELECT OBJECT_NAME, OBJECT_TYPE, STATUS
FROM USER_OBJECTS
WHERE OBJECT_NAME LIKE '%EXAMPLE'
OBJECT_NAME | OBJECT_TYPE | STATUS |
---|---|---|
F_EXAMPLE | FUNCTION | INVALID |
P_EXAMPLE | PACKAGE | INVALID |
考察
今回はimpdpのtable_exists_actionオプションにreplaceを指定した結果、内部的にregionsテーブルのdropが行われ、関連するパッケージやファンクションのステータスがINVALIDになったものと思われます。
もっとも、impdpは内部的な仕様が公開されていないこともあり、table_exists_actionオプションにreplaceを指定しても、INVALIDにならない環境もあるでしょう。table_exists_actionオプションに別の値を指定したからといって、絶対にこの問題が起こらないかといわれると、それも断言できません。
Oracle Databaseでは、ステータスがINVALIDのパッケージやファンクションにアクセスすると、再コンパイルしますが、状況によっては再コンパイルが走らない、再コンパイルに失敗してINVALIDのままになるといったことも考えられます。現にわたしはそのような状況におちいったことがあります。
とりあえず、パッケージやファンクションを多用する環境においてimpdpを実施する場合は、そのあたりも考慮して、運用設計する必要があると思います。
※ Oracle Databaseはちょっとしたパラメータの差異やデータ量の違いによって、挙動を大きく変えることがあるため、問題の調査にてこずりがちです。Oracle社や第三者保守のサポート窓口に問い合わせようにも、何をどこまで情報をまとめればよいのかに困ることもしばしばあります (保守期限が切れているなんてことも…)
環境情報
- Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production