Oracle Database Global Data Servicesの紹介

# Oracle Database Global Data Servicesとは
　負荷分散や、可用性を確保する目的で、Oracle Active Data Guardや、Oracle GoldenGateを使用したレプリケーション環境を採用しているシステムの課題の一つとして、データベースクライアントのワークロードの管理があります。
　例えば、Oracle RACのデータベースサービスは、RACデータベースの複数インスタンスのワークロードを管理可能ですが、Data GuardやGoldenGate環境のような複数データベースにまたがるシステムのワークロードには対応していないため、異なるデータベースに接続先を切り替えたい場合は、クライアント側のデータベース接続情報(例tnsnames.ora)を修正するなど、システム運用で工夫して対応するケースが多いのではないでしょうか。
　Oracle Database Global Data Services(以降GDS)は、Oracle RACのデータベースサービスを拡張し、複数のデータベースにまたがるデータベースサービスを構成する機能を提供しています。上記のような煩わしい運用課題を解消するためのソリューションになる可能性を秘めていると考えます。GDSのユースケースをいくつか挙げます。
* Oracle Active Data Guardのスイッチオーバやフェイルオーバにより、データベースロールが変わった場合に、クライアントは自動的に新プライマリデータベース、あるいは新スタンバイデータベースに接続できます。
* Oracle Active Data GuardのREDO適用ラグが閾値を超過した場合、クライアントはスタンバイデータベースではなく、プライマリデータベースに接続できます。
* Oracle GoldenGateのアクティブ・アクティブ環境において、通常運用時はクライアントは地理的に近いデータベースに接続し、計画停止時やトラブル時は、異なるデータベースに接続できます。

より詳細を知りたい方は下記ドキュメントをご覧いただければと存じます。
* [Global Data Services概要および管理ガイド](https://docs.oracle.com/cd/F19136_01/gsmug/index.html)
* [Oracle Global Data Services（Oracle GDS）のMAAベスト・プラクティス](https://www.oracle.com/technetwork/jp/database/availability/maa-globaldataservices-3413211-ja.pdf)

GDSの動作確認を行いました。以降で紹介いたします。なお、導入設定手順は別記事にて紹介予定です。

# 動作確認概要
Oracle Active Data Guard環境にて下記の動作確認を行いました。
### 参照専用処理を想定したサービスの動作確認
* 通常時はスタンバイデータベースにのみ接続する。
* スタンバイデータベースが使用不可の場合は、プライマリデータベースに接続する。
### 更新および参照処理を想定したサービスの動作確認
* プライマリデータベースにのみ接続する。
* スイッチオーバ後も新プライマリデータベースにのみ接続する。

# 動作確認環境
### データベース環境
2ノードのRACデータベースを2セット用意しました。また各RACデータベースは、Oracle Active Data Guardによるレプリケーションを構成しました。
|ホスト名| scanホスト名:ポート | DBユニーク名 | DBインスタンス名 | データベースロール |
|:-|:-|:-|:-|:-|
|db11|db1-scan:1521 |ptokyo   |ptokyo1   |PRIMARY   |
|db12|db1-scan:1521 |ptokyo   |ptokyo2   |PRIMARY   |
|db21|db2-scan:1521 |stokyo   |stokyo1   |PHYSICAL STANDBY   |
|db22|db2-scan:1521 |stokyo   |stokyo2   |PHYSICAL STANDBY   |

### GDS環境
本記事のGDS環境は、1ノードで構成しました。前述のMAAベストプラクティスガイドやマニュアルにも記載がありますが、本番環境ではGDSが単一障害点とならないよう、GDSの各コンポーネント(Global Service Manager、GDSカタログデータベース)を冗長化する必要があります。

### データベースクライアント
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

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

上記実現のため、サービス作成の際に下記を設定しました。
* 優先データベース: stokyo(スタンバイデータベース)
* 使用可能データベース: ptokyo(プライマリデータベース)

### 通常時
通常時のクライアントの接続ログを下記に示します。想定通りスタンバイデータベースにのみ接続されています。なお、インスタンスには優先度を設定していないため、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
```
# 更新および参照処理を想定したサービスの動作確認
* プライマリデータベースにのみ接続する。
* スイッチオーバ後も新プライマリデータベースにのみ接続する。

上記実現のため、サービス作成の際に下記を設定しました。
* 優先データベース: ptokyo,stokyo
* データベースロール: PRIMARY

### 通常時
通常時のクライアントの接続ログを下記に示します。想定通りプライマリデータベースにのみ接続されています。
```
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
```
# まとめ
OCIやAWSなどのクラウド環境へのシフトが加速するに伴い、複数のデータセンタを使用するケースが増えていくと予想できます。ワークロード管理のソリューションとして、GDSが解になるかもしれません。