Oracle Data Guard における複数 Observer 構成の検証

# はじめに
## Observer とは
Oracle Data Guard を用いると Oracle Database をリアルタイムに複製することが可能になり高可用性を担保できます。

Oracle Data Guard にはプライマリとなるDBが異常停止した際に、自動的にスタンバイとなるDBをプライマリに昇格させる`ファスト・スタート・フェイルオーバー`(以下FSFO、[参考](https://docs.oracle.com/cd/F19136_01/dgbkr/using-data-guard-broker-to-manage-switchovers-failovers.html#GUID-995CED84-BEA1-4675-9C68-B37CB996924F))という処理があります。

このFSFOを実施するために必要なプライマリ・スタンバイ以外でDBの正常性を確認しているコンポーネントが Observer となります。

## 本記事で確認すること
Oracle Database 12c までは1つの Oracle Data Guard 構成に登録できる Observer は1台まででした。

この場合 Observer サーバそのもので障害が発生した際、OSレベルでHA構成を組んでいないとFSFOができなくなります。

Oracle Database 19c からは1つの Oracle Data Guard 構成に登録できる Observer が3台までとなり、単純に Observer プロセスを起動するサーバを複数用意すればよくなりまりました([参考](https://docs.oracle.com/cd/F19136_01/dgbkr/using-data-guard-broker-to-manage-switchovers-failovers.html#GUID-11EF3897-8FCA-4A54-B63B-E8C1668AE21B))。

そこで、本記事では構築方法と動作確認を行いたいと思います

# 本記事の要約
- Oracle Database 19c からは1つの Oracle Data Guard 構成に対して、Observer を3つまで登録できるようになった
- Observer は Master/Backup に分かれていて Master の障害時は30秒程度で切り替わった
- 監視については、単一障害は exporter を用いた監視、全障害は EMCC を利用した監視をしている
- この構成で DB の Switchover や FSFO が問題なく実施されることも確認済み

# 構築方法
## 1. Oracle Client インストール
- 以下のサイトなどから19c以上の Oracle Client をダウンロードしておきます
  - https://edelivery.oracle.com/osdc/faces/Home.jspx
- その上で以下の方法でインストールしましょう

```bash
sudo su - <oracle_user>
## 適宜UNIX_GROUP_NAME、INVENTORY_LOCATION、ORACLE_HOMEを埋めてください
cat << 'EOF' > $HOME/client.rsp
###############################################################################
## Copyright(c) Oracle Corporation 1998,2019. All rights reserved.           ##
##                                                                           ##
## Specify values for the variables listed below to customize                ##
## your installation.                                                        ##
##                                                                           ##
## Each variable is associated with a comment. The comment                   ##
## can help to populate the variables with the appropriate                   ##
## values.                                                                   ##
##                                                                           ##
###############################################################################
 
 
#-------------------------------------------------------------------------------
# Do not change the following system generated value.
#-------------------------------------------------------------------------------
oracle.install.responseFileVersion=/oracle/install/rspfmt_clientinstall_response_schema_v19.0.0
 
#-------------------------------------------------------------------------------
# Unix group to be set for the inventory directory.
#-------------------------------------------------------------------------------
UNIX_GROUP_NAME=
#-------------------------------------------------------------------------------
# Inventory location.
#-------------------------------------------------------------------------------
INVENTORY_LOCATION=
#-------------------------------------------------------------------------------
# Complete path of the Oracle Home
#-------------------------------------------------------------------------------
ORACLE_HOME=
#-------------------------------------------------------------------------------
# Complete path of the Oracle Base.
#-------------------------------------------------------------------------------
ORACLE_BASE=/home/ora19/app/ora19
#------------------------------------------------------------------------------
#Name       : INSTALL_TYPE
#Datatype   : String
#Description: Installation type of the component.
#
#             The following choices are available. The value should contain
#             only one of these choices.
#               - Administrator
#               - Runtime
#               - InstantClient
#               - Custom
#
#Example    : INSTALL_TYPE = Administrator
#------------------------------------------------------------------------------
oracle.install.client.installType=Administrator
 
#-------------------------------------------------------------------------------
# Name       : oracle.install.client.customComponents
# Datatype   : StringList
#
# This property is considered only if INSTALL_TYPE is set to "Custom"
#
# Description: List of Client Components you would like to install
#
#   The following choices are available. You may specify any
#   combination of these choices.  The components you choose should
#   be specified in the form "internal-component-name:version"
#   Below is a list of components you may specify to install.
#
# oracle.sqlj:19.0.0.0.0 -- "Oracle SQLJ"
# oracle.rdbms.util:19.0.0.0.0 -- "Oracle Database Utilities"
# oracle.javavm.client:19.0.0.0.0 -- "Oracle Java Client"
# oracle.sqlplus:19.0.0.0.0 -- "SQL*Plus"
# oracle.dbjava.jdbc:19.0.0.0.0 -- "Oracle JDBC/THIN Interfaces"
# oracle.ldap.client:19.0.0.0.0 -- "Oracle Internet Directory Client"
# oracle.rdbms.oci:19.0.0.0.0 -- "Oracle Call Interface (OCI)"
# oracle.precomp:19.0.0.0.0 -- "Oracle Programmer"
# oracle.xdk:19.0.0.0.0 -- "Oracle XML Development Kit"
# oracle.network.aso:19.0.0.0.0 -- "Oracle Advanced Security"
# oracle.oraolap.mgmt:19.0.0.0.0 -- "OLAP Analytic Workspace Manager and Worksheet"
# oracle.network.client:19.0.0.0.0 -- "Oracle Net"
# oracle.network.cman:19.0.0.0.0 -- "Oracle Connection Manager"
# oracle.network.listener:19.0.0.0.0 -- "Oracle Net Listener"
# oracle.ordim.client:19.0.0.0.0 -- "Oracle Multimedia Client Option"
# oracle.odbc:19.0.0.0.0 -- "Oracle ODBC Driver"
# oracle.has.client:19.0.0.0.0 -- "Oracle Clusterware High Availability API"
# oracle.dbdev:19.0.0.0.0 -- "Oracle SQL Developer"
# oracle.rdbms.scheduler:19.0.0.0.0 -- "Oracle Scheduler Agent"
#
# Example    : oracle.install.client.customComponents="oracle.precomp:19.0.0.0.0","oracle.oraolap.mgmt:19.0.0.0.0","oracle.rdbms.scheduler:19.0.0.0.0"
#-------------------------------------------------------------------------------
oracle.install.client.customComponents=
 
#-------------------------------------------------------------------------------
# Host name to be used for by the Oracle Scheduler Agent.
# This needs to be entered in case oracle.rdbms.scheduler is selected in the
# list of custom components during custom install
#
# Example    : oracle.install.client.schedulerAgentHostName = acme.domain.com
#------------------------------------------------------------------------------
oracle.install.client.schedulerAgentHostName=
 
#------------------------------------------------------------------------------
# Port number to be used for by the Oracle Scheduler Agent.
# This needs to be entered in case oracle.rdbms.scheduler is selected in the
# list of custom components during custom install
#
# Example: oracle.install.client.schedulerAgentPortNumber = 1500
#------------------------------------------------------------------------------
oracle.install.client.schedulerAgentPortNumber=
EOF

## インストール実行
unzip V982064-01.zip
cd client
./runInstaller -silent -ignoreSysPrereqs -responseFile $HOME/client.rsp -ignorePrereqFailure -showProgress

## ↑が「java.library.pathシステム変数が欠落しているか無効です」で失敗したら以下でインストールしてから再実行してください
sudo yum install libnsl

## root script実行
exit
sudo su -
<root script>
exit

## 確認
which dgmgrl
dgmgrl
```

## 2. Observer登録
- あとは Observer サーバにログインし、登録したいDBに dgmgrl で接続して`START OBSERVER`を実行すれば登録完了です
- Observer 名を指定する必要があるので注意してください(指定しないとホスト名になります)
  - https://docs.oracle.com/cd/F19136_01/dgbkr/oracle-data-guard-broker-commands.html#GUID-8AADB389-6E31-46D6-AB1C-4FBB8EB6C411

```bash
sudo su - <oracle_user>

## 接続
dgmgrl
connect <user>/<password>@<connection_string>

## 起動
show observer
start observer <observer_name>
show observer

### 出力例 ###
DGMGRL> show observer
 
Configuration - <broker名>
 
  Primary:            <primary>
  Active Target:      <standby>
 
Observer "<observer1>"(19.3.0.0.0) - Master
 
  Host Name:                    <observer1>
  Last Ping to Primary:         0 seconds ago
  Last Ping to Target:          1 second ago
 
Observer "<observer2>"(19.3.0.0.0) - Backup
 
  Host Name:                    <observer2>
  Last Ping to Primary:         1 second ago
  Last Ping to Target:          2 seconds ago
 
Observer "<observer3>"(19.3.0.0.0) - Backup
 
  Host Name:                    <observer3>
  Last Ping to Primary:         1 second ago
  Last Ping to Target:          3 seconds ago
#############
```

# 動作確認
以下の観点で動作確認します。
- Observer の Master/Backup 切り替え検証
  - Observer の計画的な切り替え
  - Observer の障害による切り替え

## Observer の Master/Backup 切り替え検証 - Observer の計画的な切り替え
- Observer のMaster/Backup の切り替えは`SET MASTEROBSERVER TO <observer_name>`でできます
  - https://docs.oracle.com/cd/F19136_01/dgbkr/oracle-data-guard-broker-commands.html#GUID-99AD3268-4D63-4329-A703-5C71E31DCBD6

```bash
## 事前確認
DGMGRL> show observer
 
Configuration - <broker名>
 
  Primary:            <primary>
  Active Target:      <standby>
 
Observer "<observer1>"(19.3.0.0.0) - Master
 
  Host Name:                    <observer1>
  Last Ping to Primary:         0 seconds ago
  Last Ping to Target:          3 second ago
 
Observer "<observer2>"(19.3.0.0.0) - Backup
 
  Host Name:                    <observer2>
  Last Ping to Primary:         1 second ago
  Last Ping to Target:          1 seconds ago
 
Observer "<observer3>"(19.3.0.0.0) - Backup
 
  Host Name:                    <observer3>
  Last Ping to Primary:         1 second ago
  Last Ping to Target:          3 seconds ago

## 切り替え
DGMGRL> SET MASTEROBSERVER TO <observer2>
Succeeded.

## 事後確認
DGMGRL> show observer
 
Configuration - <broker名>
 
  Primary:            <primary>
  Active Target:      <standby>
 
Observer "<observer2>"(19.3.0.0.0) - Master
 
  Host Name:                    <observer2>
  Last Ping to Primary:         1 seconds ago
  Last Ping to Target:          3 second ago
 
Observer "<observer1>"(19.3.0.0.0) - Backup
 
  Host Name:                    <observer1>
  Last Ping to Primary:         1 second ago
  Last Ping to Target:          1 seconds ago
 
Observer "<observer3>"(19.3.0.0.0) - Backup
 
  Host Name:                    <observer3>
  Last Ping to Primary:         0 second ago
  Last Ping to Target:          3 seconds ago
```

## Observer の Master/Backup 切り替え検証 - Observer の障害による切り替え
- Observer プロセスを停止して、自動で Master が切り替わることを確認します
- 30秒程度 Master Observer から DB へのアクセスができていない場合、勝手に切り替わるようです

```bash
## 事前確認
DGMGRL> show observer
 
Configuration - <broker名>
 
  Primary:            <primary>
  Active Target:      <standby>
 
Observer "<observer2>"(19.3.0.0.0) - Master
 
  Host Name:                    <observer2>
  Last Ping to Primary:         1 seconds ago
  Last Ping to Target:          3 second ago
 
Observer "<observer1>"(19.3.0.0.0) - Backup
 
  Host Name:                    <observer1>
  Last Ping to Primary:         1 second ago
  Last Ping to Target:          1 seconds ago
 
Observer "<observer3>"(19.3.0.0.0) - Backup
 
  Host Name:                    <observer3>
  Last Ping to Primary:         0 second ago
  Last Ping to Target:          3 seconds ago

## observerプロセス停止
### systemdで管理していたのでsystemctlで止めてますが、OS止めてもkillしてもいいと思います。
sudo systemctl stop <observer_service>

## 事後確認
DGMGRL> show observer
 
Configuration - <broker名>
 
  Primary:            <primary>
  Active Target:      <standby>
 
Observer "<observer1>"(19.3.0.0.0) - Master
 
  Host Name:                    <observer1>
  Last Ping to Primary:         0 seconds ago
  Last Ping to Target:          3 second ago
 
Observer "<observer2>"(19.3.0.0.0) - Backup
 
  Host Name:                    <observer2>
  Last Ping to Primary:         35 second ago
  Last Ping to Target:          4 seconds ago
 
Observer "<observer3>"(19.3.0.0.0) - Backup
 
  Host Name:                    <observer3>
  Last Ping to Primary:         1 second ago
  Last Ping to Target:          1 seconds ago
```

# まとめ
この記事では以下の内容を紹介しました。
- Oracle Database 19c からは1つの Oracle Data Guard 構成に対して、Observer を3つまで登録できるようになった
- Observer は Master/Backup に分かれていて Master の障害時は30秒程度で切り替わった
- この構成で DB の Switchover や FSFO が問題なく実施されることも確認済み

また FSFO を行うには Oracle Data Guardの設定に条件があります、それについては[このマニュアル](https://docs.oracle.com/cd/F19136_01/dgbkr/using-data-guard-broker-to-manage-switchovers-failovers.html#GUID-995CED84-BEA1-4675-9C68-B37CB996924F)を参考に設定してください。

# 参考にしたリンク
- スイッチオーバー操作とフェイルオーバー操作
  - https://docs.oracle.com/cd/F19136_01/dgbkr/using-data-guard-broker-to-manage-switchovers-failovers.html
- Oracle Data Guardコマンドライン・インタフェース・リファレンス
  - https://docs.oracle.com/cd/F19136_01/dgbkr/oracle-data-guard-broker-commands.html
- クライアント用 Wallet を作成する（Oracle Database 19c / mkstore)
  - https://qiita.com/plusultra/items/a155aefd4420104a733f