Oracle Database Global Data Services構築 その4

# サービス作成
下記用途の二つのサービスを作成します。
| サービス名 | 用途 | 
|:-|:-|
| ro_svc  | 参照専用処理を想定したサービス  |
| rw_svc  | 更新および参照処理を想定したサービス  |

### ro_svcサービスの動作仕様
* 通常時はスタンバイデータベースにのみ接続する。
* スタンバイデータベースが使用不可の場合は、プライマリデータベースに接続する。

add serviceコマンドを使用して、ro_svcサービスを作成します。
* -serviceパラメータに、サービス名を指定します。
* -preferredパラメータに、優先データベースを指定します。
* -availableパラメータに、使用可能データベースを指定します。使用可能データベースとは、優先データベースが使用できない場合に使用されるデータベースの事です。
```
GDSCTL> add service -service ro_svc -preferred stokyo -available ptokyo
操作は正常に完了しました
```
RACデータベースのインスタンスに対するサービスの動作をmodify serviceコマンドにて設定します。
* -serviceパラメータに、サービス名を指定します。
* -databaseパラメータに、データベース名を指定します。
* -add_instancesに続く、-preferredパラメータに、優先インスタンスを設定します。
```
GDSCTL> modify service -service ro_svc -database ptokyo -add_instances -preferred ptokyo1, ptokyo2
操作は正常に完了しました
GDSCTL> modify service -service ro_svc -database stokyo -add_instances -preferred stokyo1, stokyo2
操作は正常に完了しました
```
### rw_svcサービスの動作仕様
* プライマリデータベースにのみ接続する。
* スイッチオーバ後も新プライマリデータベースにのみ接続する。

add serviceコマンドを使用して、ro_svcサービスを作成します。
* -serviceパラメータに、サービス名を指定します。
* -preferredパラメータに、優先データベースを指定します。
* -roleパラメータに、データベースロールを指定します。データベースが指定したロールの状態のときにサービスが起動します。
```
GDSCTL> add service -service rw_svc -preferred ptokyo,stokyo -role PRIMARY
操作は正常に完了しました
```
RACデータベースのインスタンスに対するサービスの動作をmodify serviceコマンドにて設定します。
* -serviceパラメータに、サービス名を指定します。
* -databaseパラメータに、データベース名を指定します。
* -add_instancesに続く、-preferredパラメータに、優先インスタンスを設定します。
```
GDSCTL> modify service -service rw_svc -database ptokyo -add_instances -preferred ptokyo1, ptokyo2
操作は正常に完了しました
GDSCTL> modify service -service rw_svc -database stokyo -add_instances -preferred stokyo1, stokyo2
操作は正常に完了しました
```
# サービスの起動
start serviceコマンドを使用して、サービスを起動します。
* -serviceパラメータに、起動対象のサービス名を指定します。
```
GDSCTL> start service -service ro_svc
操作は正常に完了しました
GDSCTL> start service -service rw_svc
操作は正常に完了しました
```
servicesコマンドを使用して、サービスの起動状態を確認します。ro_svcはスタンバイデータベースの両インスタンスにて起動していることがわかります。また、rw_svcはプライマリデータベースの両インスタンスで起動していることがわかります。
```
GDSCTL> services
サービス"ro_svc.dbpoolora.oradbcloud"に2のインスタンスがあります。アフィニティ: ANYWHERE
   インスタンス"dbpoolora%11"、名前: "stokyo1"、DB: "stokyo"、リージョン:  "tokyo2"、ステータス: ready。
   インスタンス"dbpoolora%12"、名前: "stokyo2"、DB: "stokyo"、リージョン:  "tokyo2"、ステータス: ready。
サービス"rw_svc.dbpoolora.oradbcloud"に2のインスタンスがあります。アフィニティ: ANYWHERE
   インスタンス"dbpoolora%1"、名前: "ptokyo1"、DB: "ptokyo"、リージョン:  "tokyo1"、ステータス: ready。
   インスタンス"dbpoolora%2"、名前: "ptokyo2"、DB: "ptokyo"、リージョン:  "tokyo1"、ステータス: ready。
```
# データベースクライアント
データベースクライアントのsqlplusを使用して、クライアント環境のtnsnames.oraを編集します。
* hostに指定するホスト名は、データベースサーバではなく、GSMが稼働するホストとなります。
* service_nameは、GDSのサービス名を指定します。

```
cat $ORACLE_HOME/network/admin/tnsnames.ora
ro_svc = 
  (DESCRIPTION=
    (ADDRESS=
      (PROTOCOL=TCP)(host=gsm01)(port=1531)
    )
    (CONNECT_DATA=(SERVICE_NAME=ro_svc.dbpoolora.oradbcloud))
  )

rw_svc =
  (DESCRIPTION=
    (ADDRESS=
      (PROTOCOL=TCP)(host=gsm01)(port=1531)
    )
    (CONNECT_DATA=(SERVICE_NAME=rw_svc.dbpoolora.oradbcloud))
  )
```
データベースクライアントのsqlplusを起動し、データベース接続を1秒間隔で行うスクリプトを用意しました。
```
PASSWORD=****
SVC_NAME=****
while true; do
    sqlplus -s system/${PASSWORD}@${SVC_NAME} <<EOF
SET TAB OFF
SELECT TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss') AS timestamp,
       (SELECT instance_name FROM v\$instance) AS instance_name,
       database_role
  FROM v\$database;
EOF
    sleep 1
done
```
スクリプトを実行すると下記のように、タイムスタンプ、接続先インスタンス名、接続先データベースのロールを出力します。
```
TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 16:37:57 stokyo1          PHYSICAL STANDBY

TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 16:37:59 stokyo2          PHYSICAL STANDBY

```
# 参照専用処理を想定したサービスの動作確認
ro_svcサービスの動作確認を行います。
* 通常時は、Active Data Guardのスタンバイデータベースにのみ接続する。
* スタンバイデータベースが使用不可の場合は、プライマリデータベースに接続する。
* スタンバイデータベースが復旧後は、スタンバイデータベースにのみ接続する。

### 通常時
通常時のクライアントの接続ログを下記に示します。想定通りスタンバイデータベースにのみ接続されています。なお、インスタンスには優先度を設定していないため、stokyo1あるいはstokyo2に接続する動作となります。
```
TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 16:37:57 stokyo1          PHYSICAL STANDBY

TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 16:37:59 stokyo2          PHYSICAL STANDBY

TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 16:38:01 stokyo1          PHYSICAL STANDBY

TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 16:38:03 stokyo2          PHYSICAL STANDBY
```
### スタンバイデータベース使用不可
スタンバイデータベースのstokyo1インスタンスを異常終了させるため、pmonをkillします。
```
[oracle@db21 ~]$ pgrep -a ora_pmon
9174 ora_pmon_stokyo1
[oracle@db21 ~]$ kill -9 9174
[oracle@db21 ~]$ date
2023年  5月  5日 金曜日 16:38:22 JST
```
クライアントは、スタンバイデータベースのstokyo2にのみ接続されるようになりました。
```
TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 16:38:20 stokyo2          PHYSICAL STANDBY

TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 16:38:22 stokyo2          PHYSICAL STANDBY

TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 16:38:24 stokyo2          PHYSICAL STANDBY

TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 16:38:26 stokyo2          PHYSICAL STANDBY
```
さらにスタンバイデータベースのstokyo2インスタンスを異常終了させるため、pmonをkillします。
```
[oracle@db22 ~]$ pgrep -a ora_pmon
11745 ora_pmon_stokyo2
[oracle@db22 ~]$ kill -9 11745
```
スタンバイデータベースが完全に使用できなくなったため、プライマリデータベースptokyoに接続され始めました。
```
TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 16:41:48 ptokyo2          PRIMARY

TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 16:41:50 ptokyo1          PRIMARY

TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 16:41:52 ptokyo2          PRIMARY

TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 16:41:54 ptokyo1          PRIMARY
```
スタンバイデータベースを起動した後のクライアントの接続状況を下記に示します。想定通り、スタンバイデータベースの両インスタンスに接続されるようになりました。
```
TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 17:09:01 stokyo1          PHYSICAL STANDBY

TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 17:09:03 stokyo2          PHYSICAL STANDBY

TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 17:09:05 stokyo1          PHYSICAL STANDBY
```
# 更新および参照処理を想定したサービスの動作確認
rw_svcサービスの動作確認を行います。
* プライマリデータベースにのみ接続する。
* スイッチオーバ後も新プライマリデータベースにのみ接続する。

### 通常時
通常時のクライアントの接続ログを下記に示します。想定通りプライマリデータベースにのみ接続されています。
```
TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 17:14:12 ptokyo1          PRIMARY

TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 17:14:14 ptokyo2          PRIMARY

TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 17:14:16 ptokyo1          PRIMARY

TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 17:14:18 ptokyo2          PRIMARY
```
### プライマリデータベース使用不可
プライマリデータベースのptokyo1インスタンスを異常終了させるため、pmonをkillします。
```
[oracle@db11 ~]$ pgrep -a ora_pmon
9264 ora_pmon_ptokyo1
[oracle@db11 ~]$ kill -9 9264; date
2023年  5月  5日 金曜日 17:20:22 JST
```
クライアントは、プライマリデータベースのptokyo2にのみ接続されるようになりました。
```
TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 17:20:25 ptokyo2          PRIMARY

TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 17:20:26 ptokyo2          PRIMARY

TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 17:20:28 ptokyo2          PRIMARY
```
さらに、プライマリデータベースのptokyo2インスタンスを強制停止します。
```
[oracle@db12 ~]$ pgrep -a ora_pmon
12149 ora_pmon_ptokyo2
[oracle@db12 ~]$ kill -9 12149; date
2023年  5月  5日 金曜日 17:21:28 JST
```
データベースロールが、PRIMARYロールのデータベースが存在しないため、想定通り、接続エラーとなりました。
```
ERROR:
ORA-12514: TNS:
リスナーは接続記述子でリクエストされたサービスを現在認識していません
```
### Data Guardスイッチオーバ
プライマリデータベースptokyoを起動後、スタンバイデータベースのstokyoへスイッチオーバします。
```
[oracle@db21 ~]$ dgmgrl / as sysdg
DGMGRL for Linux: Release 19.0.0.0.0 - Production on 金 5月 5 17:30:04 2023
Version 19.16.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

DGMGRLへようこそ。詳細は"help"と入力してください。
"stokyo"に接続しました
SYSDGとして接続しました。
DGMGRL> validate database stokyo

  データベース・ロール:        フィジカル・スタンバイ・データベース
  プライマリ・データベース:  ptokyo

  スイッチオーバー可能:  はい
  フェイルオーバー可能:  はい (プライマリ実行中)

  フラッシュバック・データベースのステータス:
    ptokyo:  オフ
    stokyo:  オフ

  クラスタウェアにより管理される:
    ptokyo:  YES
    stokyo:  YES

DGMGRL> switchover to stokyo
現在スイッチオーバーを実行しています。お待ちください...
新しいプライマリ・データベース"stokyo"がオープン中です...
Oracle Clusterwareはデータベース"ptokyo"を再起動しています...
ORA-01017: invalid username/password; logon denied

        インスタンス"ptokyo1" (データベース"ptokyo")を停止します
        インスタンス"ptokyo1" (データベース"ptokyo")を起動します

DGMGRL> show configuration

構成 - dg_config

  保護モード: MaxPerformance
  メンバー:
  stokyo - プライマリ・データベース
    ptokyo - フィジカル・スタンバイ・データベース

ファスト・スタート・フェイルオーバー:  Disabled

構成ステータス:
SUCCESS   (ステータスは5秒前に更新されました)
```
クライアント側の接続状況を下記に示します。スイッチオーバが完了するまでは、接続エラーが発生し続けて、スイッチオーバ後は新プライマリデータベースであるstokyoに接続される事が確認できました。
```
ORA-12514: TNS:
リスナーは接続記述子でリクエストされたサービスを現在認識していません

TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 17:33:37 stokyo1          PRIMARY


TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 17:33:39 stokyo2          PRIMARY


TIMESTAMP           INSTANCE_NAME    DATABASE_ROLE
------------------- ---------------- ----------------
2023-05-05 17:33:41 stokyo2          PRIMARY
```

数回にまたがって紹介しましたが、GDS構築は以上で完結となります。気になるトピックを思いついたら追加していきたいと思います。