検証10g新機能 その5

<検証10g新機能 その5 ~Data Pump編~>
ペンネーム:ベロ

前回のData Pumpによるロード処理では約2倍とスピードアップはしたが、もう
一つパッとしない結果となった。

前回の処理時間の結果は以下の通り。

=============================================================================

処理内容                                        時間(分)     ファイルサイズ
----------------------------------------------- ---------- ------------------
1.従来の Export によるデータのアンロード              47             19.86GB
2.従来の Export によるダイレクト・アンロード          32             18.69GB
3.Data Pumpによるアンロード                           29             19.87GB
4.従来の Import によるデータのロード                  63
5.Data Pumpによるロード                               26

=============================================================================

前回のロード処理では、同一ディスク上のReadとWriteの競合の発生がパフォ
ーマンスの弊害となっていた。
今回は、データファイルのあるディスクとダンプファイルを作成するディスク
を物理的に別にして検証を行っている。

Data Pumpのアーキテクチャーのキーはダイレクトパス及びパラレル処理にある。
ロード処理において、ダイレクト書込みをパラレル処理で多重化することで、
ディスク性能を最大限引き出すことがパフォーマンスアップのポイントとなる。

前回のディスク構成

  データファイル:ディスク4本のRAID0構成
  ダンプファイル:上記と同じディスク

今回のディスク構成

  データファイル:ディスク4本のRAID0構成
  ダンプファイル:上記とは別の単体ディスク
=============================================================================

処理内容                                        時間(分)     ファイルサイズ
----------------------------------------------- ---------- ------------------
1.従来の Export によるダイレクト・アンロード          16             18.69GB
2.Data Pumpによるアンロード                           12             19.87GB
3.従来の Import によるデータのロード                  56
4.Data Pumpによるロード                               10 

=============================================================================

従来のImportによるロード処理は56分と大きなスピードアップはないが、Data
Pumpによるロード処理は大きくスピードアップした。ロード処理は約5.5倍の
スピードアップとなった。

また、余談ですが、ダイレクトパスでの書込みといえば、SQL*Loaderでのダイ
レクトモードを想像するが、動きは同じなのであろうか?

SQL*Loaderの場合は、ハイウォーターマーク(HWM)以降に直接書込みを行っ
たあと、HWMを引き上げる仕様である。これによって、データファイル内のフ
リースペースを探し、無ければコアレスすると言った余分なオーバーヘッドが
回避できる。

ということで、Data Pumpを使用しHWMの動きを見てみたいと思います。

1.サンプルテーブルの作成

   SQL> create table hign_water_mark (id number, text varchar2(128))
    2 > tablespace test;

サンプルデータの作成

   SQL> begin
    2 >     for i in 10000 loop
    3 >         insert into high_water_mark values (i,'test text : '||i');
    4 >         if (mod(i,1000)=0) then
    5 >             commit;
    6 >         end if;
    7 >     end loop;
    8 >     commit;
    9 > end;
    10> /

2.現在のHWMを確認

   SQL> var total_blocks                number
   SQL> var total_bytes                 number
   SQL> var unused_blocks               number
   SQL> var unused_bytes                number
   SQL> var last_used_extent_file_id    number
   SQL> var last_used_extent_block_id   number
   SQL> var last_used_block             number
   SQL> 
   SQL> exec dbms_space.unused_space('TPC','HIGH_WATER_MARK','TABLE'
    2 >                             ,:total_blocks
    3 >                             ,:total_bytes
    4 >                             ,:unused_blocks
    5 >                             ,:unused_bytes
    6 >                             ,:last_used_extent_file_id
    7 >                             ,:last_used_extent_block_id
    8 >                             ,:last_used_block);

上記SQLでHWMはTOTAL_BLOCKは、896ブロックとなっている。

3.Delete処理
ここで、HWMを下げずにデータを削除。

4.通常のロード処理

5.現在のHWMを確認
2.のSQLで確認すると、HWMは896ブロックとなっており変化はない。

6.Delete処理

7.Data Pumpによるロード処理

8.現在のHWMを確認
2.のSQLで確認すると、HWMは1536ブロックとなり、HWMが上昇している。

つまり、Data Pumpによるロード処理はどんどんHWMを引き上げることになる。
HWMが引き上がることで、全件検索時のパフォーマンスが劣化することが考え
られる。TABLE_EXISTS_ACTIONパラメータをAPPENDにし、既存データに追記す
る形でのロード処理の場合、特に注意が必要になってくると思われます。

================================================================================

さらに、SQL*Loaderのダイレクトパスでデータをロードした場合ロード処理前
にトリガーを無効にし、正常にローディング完了後に有効に戻される。Data
Pumpによるロード処理ではトリガーは正常に機能するのであろうか?

まず、WAREHOUSEテーブルへのINSERT後、WARE_TMPテーブルへのUPDATEを行う
トリガーを作成してみる。

SQL> create table ware_tmp (id number default 0);

表が作成されました。

SQL> create trigger ware_test_trg after insert
  2  on warehouse for each row
  3  begin
  4     update ware_tmp set id=id+1;
  5  end;
  6  /

トリガーが作成されました。

SQL> insert into ware_tmp values (0);

1行が作成されました。

SQL> commit;

コミットが完了しました。

ここで、Data Pumpによるロード処理を行ってみる。

-------------------------------------------------------------------------------
Import: Release 10.1.0.2.0 - Production on 日曜日, 13 6月, 2004 20:11

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

接続先: Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - Production
With the Partitioning, OLAP and Data Mining options
マスター表"TPC"."SYS_IMPORT_TABLE_01"は正常にロード/アンロードされました
"TPC"."SYS_IMPORT_TABLE_01"を起動しています: 
tpc/******** directory=pump_dir2 dumpfile=exp_pump_obj.dmp tables=warehouse
content=data_only logfile=imp_pump_obj.log parallel=2 table_exists_action=append
オブジェクト型TABLE_EXPORT/TABLE/TBL_TABLE_DATA/TABLE/TABLE_DATAの処理中です

. . "TPC"."WAREHOUSE"            7.898 KB       5行がインポートされました

ジョブ"TPC"."SYS_IMPORT_TABLE_01"が20:11で正常に完了しました
-------------------------------------------------------------------------------

ここで、正常にトリガーが動作したのか確認してみると、

SQL> select * from ware_tmp;

        ID
----------
         5

つまり、SQL*Loaderとは違い、ダイレクトであってもトリガーは正常に動作す
るという事でした。

================================================================================

同様に、SQL*Loaderのダイレクトロード処理では、Primary Key制約のある表
に対し、Primary Keyに重複のあるデータを挿入した場合、重複データが挿入
され、Indexがunusable になります。

この場合もData Pumpのダイレクトロード処理ではどのような動きをするのだ
ろうか?

まず、WAREHOUSEテーブルにPrimary Key制約を付けてみる。

SQL> alter table warehouse add constraint ware_pk primary key(w_id);

表が変更されました。

ここで、Data Pumpによるダイレクトロード処理を行ってみる。

Import: Release 10.1.0.2.0 - Production on 日曜日, 13 6月, 2004 20:04

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

-------------------------------------------------------------------------------
接続先: Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - Production
With the Partitioning, OLAP and Data Mining options
マスター表"TPC"."SYS_IMPORT_TABLE_01"は正常にロード/アンロードされました
"TPC"."SYS_IMPORT_TABLE_01"を起動しています: 
tpc/******** directory=pump_dir2 dumpfile=exp_pump_obj.dmp tables=warehouse 
content=data_only logfile=imp_pump_obj.log parallel=2 table_exists_action=append
オブジェクト型TABLE_EXPORT/TABLE/TBL_TABLE_DATA/TABLE/TABLE_DATAの処理中です
ORA-31693: 表データ・オブジェクト"TPC"."WAREHOUSE"は、ロード/アンロードに失敗し、
           エラーのためスキップされます:
ORA-00001: 一意制約(TPC.WARE_PK)に反しています
ジョブ"TPC"."SYS_IMPORT_TABLE_01"が完了しましたが、1エラーが20:04で発生しています
-------------------------------------------------------------------------------

きっちり、Primary Key制約は有効になっていました。

来週からは、Data Guardの検証を予定しています。ご期待あれ。

自転車のカギをなくしてしまいました。。。茅ヶ崎より