Oracel Data Pumpのアーキテクチャから理解する「PARALLELパラメータとワーカー・プロセスの関係」

## はじめに
Oracle Data Pumpは、Oracle Databaseのオンプレミスからクラウドへの移行やバージョンアップの際によく使用される手法の１つです。
今回は、PARALLELパラメータとワーカー・プロセスの関係について、Oracle Data Pumoのアーキテクチャについて触れながらご紹介していきます。

また、本記事の内容は、

**第8回 Oracle DBaseCamp**
**【Oracle Data Pumpによるエクスポートとインポート】**

に登壇した際の内容になります。

詳細についてご覧になりたい方は、以下の録画や資料を参考にしてみてください。
* 録画

https://youtu.be/ysJdrpuwkNY

*資料

https://speakerdeck.com/oracle4engineer/oracle-dbasecamp-8

## Oracle Data Pumpのコンポーネント
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/0c75d394-af5d-470e-bc32-abb987b19e0e.png)
まず、ユーザーからエクスポート・インポートコマンドが実行された際のOracle Data Pump内部のコンポーネントの関係を見ていきます。
Oracle Data Pumpのクライアントの**expdp**と**impdp**は、それぞれエクスポート・ユーティリティとインポート・ユーティリティと呼ばれ、内部的にデータ・ポンプAPIである**DBMS_DATAPUMP**を実行します。
DBMS_DATAPUMPは、PL/SQLパッケージで、エクスポートおよびインポートを実行するために、コマンドラインで入力されたパラメータを解釈し実行します。
また、メタデータを移動する場合は、PL/SQLパッケージの**DBMS_METADATA**で提供される機能が使用されます。
**External table API**と**Direct path API**については、データポンプでデータを移動する場合に内部的に利用されます。

## Oracle Data Pumpのアーキテクチャ
続いて、Oracle Data Pumpのアーキテクチャについて紹介していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/2cd0df8d-9688-d9a2-2a4a-ff4144288138.png)
実行ユーザーがexpdpおよびimpdpを実行すると、**制御プロセス**が作成されます。この制御プロセスというのは、**制御表**を使用してOracle Data Pumoで実行するジョブ全体を制御しています。
次に、処理の実行を行う**ワーカー・プロセス**が作成されます。制御プロセスは、このワーカープロセスに対して実行するジョブのタスクを渡したり、ワーカー・プロセスが実行中のタスクなどを把握しながら、全体のジョブを制御していきます。
このプロセス間の通信は、Oracle Databaseの機能である**Advanced Queuing**を通して行われ、ワーカー・プロセスはこのキューを通して制御プロセスからジョブのタスクを受け取って、ダンプ・ファイルにデータの書き込みを行います。
また、制御プロセスも制御表に含まれるジョブの情報をタンプ・ファイブに書き込んでいきます。

## PARALLELパラメータとワーカー・プロセスの関係
### ■ PARALLELパラメータとは
PARALLELパラメータを使用することで、複数のダンプ・ファイルに対して同時にデータの書き込みを行うことが可能になるため、エクスポートとインポートの処理速度を上げることができます。

### ■ PARALLELパラメータとワーカー・プロセスの関係
パラレル値の指定した数に応じてワーカープロセスが作成されます。

**【PARALLEL=1(デフォルト)を指定した場合】**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/4bae8ac0-0c47-244c-861e-b879cf13567b.png)
この例では<INS>**パラレル値がデフォルトの1**</INS>ですので、制御プロセスが1つワーカープロセスが1つといった構成となっております。

**【PARALLEL=4を指定した場合】**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/67700755-2a1b-d458-f06d-d36171d6d7c5.png)
この場合は、ワーカー・プロセスが4つ作成されます。
しかし、ワーカー・プロセスがダンプ・ファイルに書き込むとき、<INS>**1つのファイルを独占するような形で書き込む**</INS>ため、他のワーカープロセスは、全てアイドル状態になってしまい、せっかくプロセスが起動したにも関わらず仕事をしていないことになってしまいます。

では、それをどうやって調整するかというと、**DUMPFILEパラメーター**を工夫することになります。
これは作成されるダンプ・ファイルの名前を指定するためのパラメーターですが、この名前の中に<INS>**%Uや%Lなどの置換変数であるワイルドカードを使用することで、複数のファイルに書き込むように指定することができます。**</INS>

**【PARALLEL=4、DUMPFILEパラメータで%Lを指定】**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/2e3f8c48-05ef-429a-d8b6-03d4c9402170.png)
こ場合、PARALLEL値が4で2以上なので、DUMPFILEパラメーターでワイルドカードを指定することで、ワーカー・プロセスが一度に複数のファイルに書き込むことができるようになります。
これにより作成したワーカー・プロセスが活躍できるようになります。

しかし、それでもワーカー・プロセスがアイドル状態になってしまう場合があります。


**【%Lを指定したにも関わらず、ワーカー・プロセスがアイドル状態になる場合】**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/6c370b1f-8e0d-f87f-ea56-9d8ccfe507a8.png)
大規模なテーブルなどではワーカー・プロセスがパラレル実行プロセスを使用するように判断する場合があります。
その場合、ワーカー・プロセスはクエリー・コーディネーターとして振る舞います。
このような場合、<INS>**Oracle Data Pumpの処理全体としてCPUを使いすぎないように、特定のワーカー・プロセスをアイドル状態にします。**</INS>
このようにしてOracle Data Pumpを実行しているサーバーのCPU負荷を一定に保つように考慮されています。

## おわりに
今回は、PARALLELパラメータとワーカー・プロセスの関係について、Oracel Data Pumpのアーキテクチャから理解していきました。

Oracle Data Pumpについて、更に詳しく知りたい方は以下の記事もご参考にしてみてください。

:::note info
* [Oracle Data Pumpによるエクスポートとインポートの基礎](https://qiita.com/yunagash/items/15625a0b6010ee83de1a)
* [Oracle Data Pumpの機能紹介 ～Enterprise Editionおよびオプションで利用できる機能～](https://qiita.com/yunagash/items/57cb29729bfdad52da2d)
* [Oracle Data Pumpのベスト・プラクティスと代表的なパラメータ](https://qiita.com/yunagash/items/aa41b3a2d916761807dc)
* [Oracle Data Pumpによる移行方法（クラウドリフト時の移行ケースと注意点）](https://qiita.com/yunagash/items/f2c037b1062753821c89)
* [Oracle Data Pumpのエクスポート時のジョブの中断、再開、強制終了の方法](https://qiita.com/yunagash/items/e06eb0fd4b1824bd09e0)
:::