Qレプリケーション・チュートリアル ASNCLP版（４）～Qレプリケーションの定義～

これは、**Qレプリケーション・チュートリアル ASNCLP版**の4番目の記事です。
←[前の記事(3)][Qrep_nonGUI.3] | [次の記事(5)][Qrep_nonGUI.5]→
[(1)][Qrep_nonGUI.1] | [(2)][Qrep_nonGUI.2] | [(3)][Qrep_nonGUI.3] | [(4)][Qrep_nonGUI.4] | [(5)][Qrep_nonGUI.5]


# :four_leaf_clover: <font color="MediumAquaMarine">モジュール.2</font> :four_leaf_clover:<br>　Q レプリケーションのセットアップ - つづき
**参照元:** [モジュール 2: Q レプリケーションのセットアップ- IBM Documentation][QrepTut_Module.2]

前のステップで、コントロール表の作成と、データベース・ログの保持方法を変更しました。
次からいよいよレプリケーションの定義に入ります。

## :shamrock: <font color="MediumAquaMarine">レッスン 2.3</font> :shamrock: <br>　レプリケーション・キュー・マップの作成
**参照元:** [レッスン 2.3: レプリケーション・キュー・マップの作成 - IBM Documentation][Lesson2.3]

このレッスンでは、**レプリケーション・キュー・マップ**を作成します。
キュー・マップはリモート送信キュー、受信キュー、リモート管理キューの組み合わせで構成されるレプリケーション・データや管理情報の通り道のようなものになります。
この後のレッスンで各表ごとにレプリケーションの定義(Qサブスクリプション)を作成しますが、Qサブスクリプションは必ずいずれかのキュー・マップに関連づけられるので、先にこのキュー・マップを作成しておく必要があります。
![QMAP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528658/efbe54de-fa61-8487-26c7-58fbc2bbfcf3.png)


**１．キュー・マップ作成用のASNCLPスクリプト・ファイルの作成**

:::note
**キュー・マップ作成用のASNCLPコマンド**
　**CREATE REPLQMAP**

キュー・マップの名前：SAMPLE_ASN_TO_TARGETDB_ASN
送信キューの名前：SENDQ
受信キューの名前：RECVQ
    管理キューの名前：**RMT_ADMINQ**　　:point_left: <font color="DarkOrange">注意</font>

![QMAP構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528658/24684fad-2277-2a21-3541-c03c5c4de65b.png)
:::

:::note warn
ここで間違い易いのが**管理キューの名前**です。
**キュー・マップの定義では、Ｑアプライ側で使用するリモート管理キューの名前を指定**します。**Ｑキャプチャー側の管理キュー（ローカル・キュー）ではないので、注意**してください。
チュートリアルでは、どちらの名前もADMINQとなっていて少し分かりにくいので、ここではあえてＱアプライ側で使用するリモート管理キューの名前をRMT_ADMINQとしました。
:::

:::note warn
CREATE REPLQMAPで指定する**キューの順序**にも注意が必要です。
感覚的には送信キューから記載したくなりますが、
　ADMINQ "admnqname"
　RECVQ "recvqname"
　SENDQ "sendqname"
の順序で書かないとエラーになりますので、ここも注意してください。
:::

では、```cre.QREP_QMAP.clpin.txt```ファイルを作成して、以下の内容を記載してください。
前半のQキャプチャー、Qアプライのスキーマ名を記載するところまでは、制御表を作成したスクリプトの書き方と同じですが、出力されるSQLファイルやログ・ファイルの名前はキュー・マップ作成用と分かるように変更しています。
また制御表作成時は、キュー・マネージャーの指定が必要でしたが、キュー・マップ作成時はキュー・マネージャーの情報は不要です。（書いてあってもエラーにはなりません。）


```cre.QREP_QMAP.clpin.txt
### Qレプリケーション用のASNCLPセッションであることを宣言
ASNCLP SESSION SET TO Q REPLICATION;

### 生成されたSQL文を保管するファイル
 SET OUTPUT CAPTURE SCRIPT "cre.QCAP_QMAP.sql.txt";
 SET OUTPUT TARGET SCRIPT "cre.QAPP_QMAP.sql.txt";

### ASNCLPコマンドの実行ログファイル
 SET LOG "cre.QREP_QMAP.clpin.log.txt";

### SQLファイルの出力のみ（SQLファイルの内容は自分で実行する）
 SET RUN SCRIPT LATER ;

### 即時実行
# SET RUN SCRIPT NOW STOP ON SQL ERROR ON;

### ソースおよびターゲット データベースの指定
### パスワード・ファイルを利用して、接続ユーザー情報とパスワード情報を読みこませる場合
 SET PWDFILE "asnpwd.aut";
 SET SERVER CAPTURE TO DB SAMPLE ;
 SET SERVER TARGET TO DB TARGETDB ;

### Qキャプチャー、Qアプライのスキーマ名（ASNはデフォルト、任意の名前を指定可能）
 SET CAPTURE SCHEMA SOURCE ASN;
 SET APPLY SCHEMA ASN;

### キュー・マップの作成
 CREATE REPLQMAP SAMPLE_ASN_TO_TARGETDB_ASN
 USING 
  ADMINQ "RMT_ADMINQ"
  RECVQ  "RECVQ"
  SENDQ  "SENDQ"
 ;
```

**２．キュー・マップの作成**
作成したASNCLPスクリプト・ファイル```cre.QREP_QMAP.clpin.txt```を実行します。
SET RUN SCRIPTの指定は、**最初はLATER、エラーがなければNOWで再実行**してください。

```
asnclp -f cre.QREP_QMAP.clpin.txt
```

<details><summary>2.キュー・マップの作成ASNCLPコマンド SET RUN SCRIPT NOWでの実行例</summary>

```
====
CMD: ### Qレプリケーション用のASNCLPセッションであることを宣言
====
====
CMD: ASNCLP SESSION SET TO Q REPLICATION;
====
(中略)
====
CMD: ### キュー・マップの作成
====
====
CMD: CREATE REPLQMAP SAMPLE_ASN_TO_TARGETDB_ASN
====
====
CMD: USING
====
====
CMD: ADMINQ "RMT_ADMINQ"
====
====
CMD: RECVQ  "RECVQ"
====
====
CMD: SENDQ  "SENDQ" ;
====

ASN1956I  ASNCLP : アクション "CREATE REPLICATION QUEUE MAP" の SQL スクリプト・ファイルを生成しています。
ASN1955I  ASNCLP : 次のファイルを使用しています。キャプチャー SQL スクリプトとして "cre.QCAP_QMAP.sql.txt"、コントロール SQL スクリプトとして "replctl.sql"、ターゲット SQL スクリプトとして "cre.QAPP_QMAP.sql.txt"、およびログ・ファイルとして "cre.QREP_QMAP.clpin.log.txt"。
--- ASNCLP Version 11.5 Build date 2022-09-22 21:41:24

<ClpInfo2Log:: Preparing to run script.>
<ClpInfo2Log:: Now running SQL...>
ASN1514I  レプリケーション・アクションは、"2023年xx月xx日 (x曜日) 15時32分46秒 JST" に、"1" 個の成功、"0" 個のエラー、および "0" 個の警告を伴って終了しました。

<ClpInfo2Log:: The SQL command completed successfully.>

ASN1953I  ASNCLP :  コマンドが完了しました。
```
</details>

キュー・マップの情報は、Qキャプチャー側の制御表の**ASN.IBMQREP_SENDQUEUES**とQアプライ側の制御表**ASN.IBMQREP_RECVQUEUES**に入りますので、興味があればSELECTして内容を確認してみてください。

次は、**Qサブスクリプション**を作成します。

## :shamrock: <font color="MediumAquaMarine">レッスン 2.4</font> :shamrock: <br>　Q サブスクリプションの作成
**参照元:** [レッスン 2.4: Q サブスクリプションの作成 - IBM Documentation][Lesson2.4]

**Qサブスクリプション**とは、ソース表からターゲット表のレプリケーションの仕方を定義するものです。
レプリケーション対象の表ごとに Q サブスクリプションは作成します。 
このチュートリアルでのレッスンでは、SAMPLE データベース内の EMPLOYEE 表を TARGETDB データベースの EMPLOYEE という名前のコピー表にレプリケーションするように定義しています。
![Qsub.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528658/27e56dd3-5428-1ffc-76fc-9a3862206777.png)

先述したように、１つのQ サブスクリプションはいずれか１つのキュー・マップに属するようにします。
Q サブスクリプションとキュー・マップは1対1でも良いですが、一般的なのは、１つのキュー・マップに複数のQサブスクシプションを含める構成です。
![Qsub_Qmap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528658/d5a5b515-094e-838d-0b67-58275792e3ea.png)
では、SAMPLE データベース内の EMPLOYEE 表を TARGETDB データベースの EMPLOYEE 表にレプリケーションするQサブスクシプションを定義するASNCLPコマンドを作成します。

**１．Qサブスクリプション作成用のASNCLPスクリプト・ファイルの作成**

:::note
**Qサブスクリプション作成用のASNCLPコマンド**
　**CREATE QSUB**
参考：[CREATE QSUB コマンド (単一方向レプリケーション) - IBM Documentation](https://www.ibm.com/docs/ja/idr/11.4.0?topic=replication-create-qsub-command-unidirectional)

キュー・マップの名前：SAMPLE_ASN_TO_TARGETDB_ASN
Qサブスクリプションの名前：EMPLOYEE0001
ソース表の名前：DB2ADMIN.EMPLOYEE
ターゲット表の名前：DB2ADMIN.EMPLOYEE
:::

```cre.QREP_QSUB.clpin.txt```ファイルを作成して、以下の内容を記載してください。
前半のQキャプチャー、Qアプライのスキーマ名を記載するところまでは、制御表やQマップを作成したスクリプトの書き方と同じですが、出力されるSQLファイルやログ・ファイルの名前はQサブスクリプション作成用と分かるように変更しています。
お使いのユーザーIDがdb2admin以外の場合は、**DB2ADMIN**.EMPLOYEEのスキーマ名を適宜変更してください。

```cre.QREP_QSUB.clpin.txt
### Qレプリケーション用のASNCLPセッションであることを宣言
ASNCLP SESSION SET TO Q REPLICATION;

### 生成されたSQL文を保管するファイル
 SET OUTPUT CAPTURE SCRIPT "cre.QCAP_QSUB.sql.txt";
 SET OUTPUT TARGET SCRIPT "cre.QAPP_QSUB.sql.txt";

### ASNCLPコマンドの実行ログファイル
 SET LOG "cre.QREP_QSUB.clpin.log.txt";

### SQLファイルの出力のみ（SQLファイルの内容は自分で実行する）
 SET RUN SCRIPT LATER ;

### 即時実行
# SET RUN SCRIPT NOW STOP ON SQL ERROR ON;

### ソースおよびターゲット データベースの指定
### パスワード・ファイルを利用して、接続ユーザー情報とパスワード情報を読みこませる場合
 SET PWDFILE "asnpwd.aut";
 SET SERVER CAPTURE TO DB SAMPLE ;
 SET SERVER TARGET TO DB TARGETDB ;

### Qキャプチャー、Qアプライのスキーマ名（ASNはデフォルト、任意の名前を指定可能）
 SET CAPTURE SCHEMA SOURCE ASN;
 SET APPLY SCHEMA ASN;

### Qサブスクリプションの作成
CREATE QSUB
USING REPLQMAP SAMPLE_ASN_TO_TARGETDB_ASN
( 
SUBNAME EMPLOYEE0001
 DB2ADMIN.EMPLOYEE
OPTIONS 
TARGET NAME "DB2ADMIN"."EMPLOYEE"
) ;
```

:::note
**キュー・マップの指定**
レプリケーション・センターを使用した場合、キュー・マップ名は定義済みのものがあれば自動的に名前が入りますが、CREATE QSUBコマンドでは**キュー・マップ名は必ず指定**しなければなりません。
:::

:::note
**Qサプスクリプション名**
CREATE QSUBコマンドでは、Qサブスクリプション名を指定しないと、<strong>"SUB-<ソース表名>"</strong>になりますが、任意の名前を付けることができますので**管理しやすい名前を明示指定する**ことをお勧めします。
レプリケーション・センターでは、Qサブスクリプションの名前は表名から自動的に生成され、チュートリアルでは EMPLOYEE0001 となっていますが、この**自動生成された名前は、GUI上では変更できません**。

ここではチュートリアルと同じ EMPLOYEE0001 をQサブスクリプション名を指定しています。
:::

:::note
ターゲット表名と表スペース
ターゲット表は、チュートリアルに従い新規に作成するようにしています。
ターゲット表名は省略すると、ソース表と同じスキーマで<strong>“TG+<ソース表名>”</strong>となりますが、ターゲット表もソース表と同じ名前になるようにここでは明示指定しています。

一般的にはターゲット表も事前に作成していることが多いと思います。
その場合には、以下のようにTARGET NAMEの前にEXISTを指定します。
```
EXIST
TARGET NAME ・・・
```
ターゲット表を作成する表スペースは、レプリケーション・センターでは「新規の表スペース」とすると、自動的にCREATE TABLESPACEステートメントを生成してくれますが、ASNCLPでは既存の表スペース名を指定する必要があるため、ここでは表スペース名は指定せず、デフォルトの表スペースに作成されるようにしています。
その他様々なオプションが指定できますが、今回は明示指定はせずデフォルト設定を利用するようにします。
:::

**２．Qサブスクリプションの作成**
作成したASNCLPスクリプト・ファイル```cre.QREP_QSUB.clpin.txt```を実行します。
SET RUN SCRIPTの指定は、**最初はLATER、エラーがなければNOWで再実行**してください。

```
asnclp -f cre.QREP_QSUB.clpin.txt
```

<details><summary>2.Qサブスクリプションの作成ASNCLPコマンド SET RUN SCRIPT NOWでの実行例</summary>

```
====
CMD: ### Qレプリケーション用のASNCLPセッションであることを宣言
====
====
CMD: ASNCLP SESSION SET TO Q REPLICATION;
====
(中略)
====
CMD: ### Qサブスクリプションの作成
====
====
CMD: CREATE QSUB
====
====
CMD: USING REPLQMAP SAMPLE_ASN_TO_TARGETDB_ASN
====
====
CMD: (
====
====
CMD: SUBNAME EMPLOYEE0001
====
====
CMD: DB2ADMIN.EMPLOYEE
====
====
CMD: OPTIONS
====
====
CMD: TARGET NAME "DB2ADMIN"."EMPLOYEE"
====
====
CMD: ) ;
====

ASN1956I  ASNCLP : アクション "CREATE Q SUBSCRIPTION" の SQL スクリプト・ファイルを生成しています。
ASN1955I  ASNCLP : 次のファイルを使用しています。キャプチャー SQL スクリプトとして "cre.QCAP_QSUB.sql.txt"、コントロール SQL スクリプトとして "replctl.sql"、ターゲット SQL スクリプトとして "cre.QAPP_QSUB.sql.txt"、およびログ・ファイルとして "cre.QREP_QSUB.clpin.log.txt"。

--- ASNCLP Version 11.5 Build date 2022-09-22 21:41:24

<ClpInfo2Log:: Now running SQL...>
ASN1514I  レプリケーション・アクションは、"2023年xx月xx日 (x曜日) 15時59分49秒 JST" に、"1" 個の成功、"0" 個のエラー、および "0" 個の警告を伴って終了しました。

<ClpInfo2Log:: Now running SQL...>
ASN1514I  レプリケーション・アクションは、"2023年xx月xx日 (x曜日) 15時59分49秒 JST" に、"0" 個の成功、"0" 個のエラー、および "0" 個の警告を伴って終了しました。

<ClpInfo2Log:: The SQL command completed successfully.>

ASN1953I  ASNCLP :  コマンドが完了しました。
```
</details>

:::note
参考
レプリケーションのソース表として登録する場合、表の属性としてData Capture Changesが必要です。
これはレプリケーションに必要な情報を拡張してDb2のログに書くようにする設定です。
今回ソース表にしたEMPLOYEE表は、作成時にはData Capture Changesはついていませんでしたが、CREATE QSUBを行った際に、この属性がついていないソース表の場合は、ASNCLPが自動的に以下のSQL文を生成して実行してくれています。
興味のある方は、ASNCLPがQキャプチャー側用に生成した```cre.QCAP_QSUB.sql.txt```の内容を確認してみてください。
※ASNCLPが生成するSQLファイルは追記モードです。上書きではありません。そのため新しい情報はファイルの最後の方から確認してください。
```
ALTER TABLE DB2ADMIN.EMPLOYEE
 DATA CAPTURE CHANGES;
```
:bulb:このALTERは表の属性を変更するため、Db2のカタログを更新します。
実際に本番で使用されている表の場合には、その表に対する更新がない、あるいは少ない時間帯に実行することをお勧めします。
:::

:::note
今回のシナリオでは、ASNCLPを実行することによって生成されたSQL文も実行する方法を使っていますが、SET SCRIPT LATER でSQL文(ファイル）だけを生成し、そのSQL文をあとで個別に実行して制御表に登録することもできます。
実際の開発時には、そのような方法を取られる事が多いです。
:::

これで、準備は整いました。ではレプリケーションを開始してみましょう。

**次のステップ　:four_leaf_clover: モジュール 3 :four_leaf_clover:  Q レプリケーションの開始**
→　[**Qレプリケーション・チュートリアル ASNCLP版（５)**][Qrep_nonGUI.5] 


[Qrep_nonGUI.1]: https://qiita.com/Seven_Marine/private/a2e93561e6b8629725ee
[Qrep_nonGUI.2]: https://qiita.com/Seven_Marine/private/31bb30f28d6ed362c785
[Qrep_nonGUI.3]: https://qiita.com/Seven_Marine/private/d86657f0c88e20129515
[Qrep_nonGUI.4]: https://qiita.com/Seven_Marine/private/95c2ffc913b5fdffc642
[Qrep_nonGUI.5]: https://qiita.com/Seven_Marine/private/de33924e47864a24bf97

[QrepTutrial]: https://www.ibm.com/docs/ja/idr/11.4.0?topic=tutorials-q-replication-tutorial
[QrepTut_Intro]: https://www.ibm.com/docs/ja/idr/11.4.0?topic=tutorial-introduction-q-replication
[QrepTut_Module.1]: https://www.ibm.com/docs/ja/idr/11.4.0?topic=tutorial-module-1-setting-up-mq
[QrepTut_Module.2]: https://www.ibm.com/docs/ja/idr/11.4.0?topic=tutorial-module-2-setting-up-q-replication
[QrepTut_Module.3]: https://www.ibm.com/docs/ja/idr/11.4.0?topic=tutorial-module-3-starting-q-replicationting

[Lesson2.1]: https://www.ibm.com/docs/ja/idr/11.4.0?topic=replication-lesson-21-creating-source-target-control-tables
[Lesson2.2]: https://www.ibm.com/docs/ja/idr/11.4.0?topic=replication-lesson-22-enabling-source-database
[Lesson2.3]: https://www.ibm.com/docs/ja/idr/11.4.0?topic=replication-lesson-23-creating-queue-map
[Lesson2.4]: https://www.ibm.com/docs/ja/idr/11.4.0?topic=replication-lesson-24-creating-q-subscription

[asnclp_Qrep]: https://www.ibm.com/docs/ja/idr/11.4.0?topic=program-asnclp-commands-q-replication
[asnclp_qiita]: https://qiita.com/namazu-841/items/3f8a017afca9521447ee