7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Db2のHADR構成構築メモ

Last updated at Posted at 2018-10-28

前回Db2のネイティブ暗号化の構築覚書に続いて、暗号化したDBをHADR(High Availability Disaster Recovery)構成にするところまでの覚書。
HADRはいわゆるRDBMSのレプリケーション機能で、OracleならData Guard、MySQLならそのまんまレプリケーション(名前ないのかな?)、HiRDBならData Replicatorに相当する機能。

完成後はこのような構成になる。PRIMARYのDB01はDb2ネイティブ暗号化による暗号化済み。
スクリーンショット 2018-10-28 14.39.57.png

項目 PRIMARY STANDBY
ホスト名 db1 db2
インスタンス名 dbinst dbinst
DB名 DB01 DB01
HADRポート1 db2_hadr(55555/tcp) db2_hadr(55555/tcp)

PRIMARY、STANDBYのホスト名はそれぞれ"db1"と"db2"で、それぞれインスタンス名(インスタンスユーザ名)は"dbinst"。
HADR構成の要件としては、インスタンス名は必ずしも同じでなくてよいものの、DB名は同じでなければならない。
物理パスは同じでなくても動作するが、初期構築時にPRIMARYからSTANDBYへDBをリストアするので、同じ方が簡単(物理パスが異なるとリストアが面倒になる)。つまり一旦、同じ構成のDBがSTANDBY側にもできて、そこからSTANDBY側固有の設定をすることになる。
また、ログはアーカイブモードが必須(循環ログはNG)。
同様に、プライマリで暗号化している場合は、同じ暗号化キー(DBの暗号化鍵を暗号化するマスターキーを含むキーストア)をスタンバイにも登録する必要がある。

前提環境

項目
OS RHEL7.3
Db2 v11.1.3.3
DB PATH /db/db01/database
Storage /db/db01/tbsp1,/db/db01/tbsp2
Log /db/db01/log1
Mirror Log /db/db01/log2
Log ArchMeth1 DISK:/db/db01/logarch

※VMware Fusion上の仮想マシンとして構築

DB作成

DBディレクトリ作成(PRIMARY/STANDBYそれぞれ)

mkdir /db/db01
cd /db/db01; pwd
mkdir database tbsp1 tbsp2 log1 log2 logarch

DB作成(PRIMARYのみ)

db2 "CREATE DB DB01 
AUTOMATIC STORAGE YES
ON /db/db01/tbsp1,/db/db01/tbsp2
DBPATH ON /db/db01/database
USING CODESET UTF-8 TERRITORY JP
COLLATE USING IDENTITY
PAGESIZE 4 K
ENCRYPT CIPHER AES KEY LENGTH 256 MASTER KEY LABEL MasterKey"

DB設定更新(PRIMARYのみ)

db2 "UPDATE DB CFG FOR DB01 USING NEWLOGPATH /db/db01/log1"
db2 "UPDATE DB CFG FOR DB01 USING MIRRORLOGPATH /db/db01/log2"
db2 "UPDATE DB CFG FOR DB01 USING LOGARCHMETH1 DISK:/db/db01/logarch"
db2 "UPDATE DB CFG FOR DB01 USING LOGINDEXBUILD ON"

HADR構成

PRIMARYでバックアップ取得

NFSでPRIMARY、STANDBYからアクセス可能な領域に出力。NFSが使えなければSCPなりHULFTなりでSTANDBYへ転送。

db2 "BACKUP DB DB01 TO /nfs/db01"

STANDBYにリストア

db2 "RESTORE DB DB01 FROM /nfs/db01 ENCRYPT"

暗号化しているのでENCRYPTオプション必須。
ただし、先にSTANDBYでもCREATE DATABASEをENCRYPTつきで実行済みならENCRYPT不要(つけるとエラー)。BACKUP DBのバックアップデータはデフォルト暗号化されない点には一応注意。

PRIMARY・STANDBYでHADRポート番号追加

echo "db2_hadr    55555/tcp" >>/etc/services

ローカルHADR設定(PRIMARY)

db2 "UPDATE DB CFG FOR DB01 USING
    HADR_LOCAL_HOST   db1
    HADR_LOCAL_SVC    db2_hadr
    HADR_SYNCMODE     ASYNC
"

ローカルHADR設定(STANDBY)

db2 "UPDATE DB CFG FOR DB01 USING
    HADR_LOCAL_HOST   db2
    HADR_LOCAL_SVC    db2_hadr
    HADR_SYNCMODE     ASYNC
"

リモートHADR設定(PRIMARY)

db2 "UPDATE DB CFG FOR DB01 USING
    HADR_REMOTE_HOST db2
    HADR_REMOTE_SVC  db2_hadr
    HADR_REMOTE_INST dbinst
"

リモートHADR設定(STANDBY)

db2 "UPDATE DB CFG FOR DB01 USING
    HADR_REMOTE_HOST db1
    HADR_REMOTE_SVC  db2_hadr
    HADR_REMOTE_INST dbinst
"

スタンバイでHADR開始

db2 "START HADR ON DB DB01 AS STANDBY"
db2pd -hadr -db DB01

プライマリでHADR開始

db2 "START HADR ON DB DB01 AS PRIMARY"
db2pd -hadr -db DB01

状態確認

db2pd -hadr -db DB01
抜粋
                            HADR_ROLE = STANDBY
                           HADR_STATE = PEER
                  HADR_CONNECT_STATUS = CONNECTED

以下を確認する。

  • HADR_ROLEがそれぞれPRIMARY、STANDBYになっていること
  • HADR_STATEがPEERになっていること
  • HADR_CONNECT_STATUSがCONNECTEDになっていること

同期確認

PRIMARYでテーブル作成

db2 "CONNECT TO DB01"
db2 "CREATE TABLE Hogetbl(hoge INTEGER PRIMARY KEY NOT NULL, geho VARCHAR(16))"
db2 "INSERT INTO Hogetbl VALUES (1,'hogehoge')"

STANDBYで確認

STANDBYをPRIMARYに昇格(PRIMARYはSTANDBYへ降格)

db2 "TAKEOVER HADR ON DB DB01"
db2pd -hadr -db DB01

通常、STANDBYであるうちはCONNECTできないが、レジストリ変数(DB2_HADR_ROS)を設定することでアクセス可能

SELECTしてみる

db2 "CONNECT TO DB01"
db2 "SELECT * FROM Hogetbl"

無事に旧PRIMARYのデータが引継がれた。

元に戻す

PRIMARYで実行
db2 "TAKEOVER HADR ON DB DB01"
db2pd -hadr -db DB01

起動と停止

停止

停止するときは、PRIMARYからSTANDBYの順。

PRIMARY
db2 "DEACTIVATE DB DB01"
db2stop
STANDBY
db2 "DEACTIVATE DB DB01"
db2stop

起動

起動は逆にSTANDBYからPRIMARYの順。

STANDBY
db2start
db2 "ACTIVATE DB DB01"
PRIMARY
db2start
db2 "ACTIVATE DB DB01"

HADR構成の破棄(PRIMARY、STANDBYそれぞれ実施)

db2 "DEACTIVATE DB DB01"
db2 "STOP HADR ON DB DB01"

これをやるとHADR環境は作り直しが必要になる可能性がある(トランザクションがPRIMARY側で大量に発生して、PRIMARY/STANDBY間の整合性が取れなくなるなど)。
なにも更新がなければ再度START HADR ON DB DB01 AS PRIMARY/STANDBYで再開始可能。

いろいろ実験

バックアップとリストア

バックアップはPRIMARY側で実行する(STANDBYでは取得不可)。オフライン・オンラインいずれも可能。

リストアして障害発生直前までロールフォワード

db2 "DEACTIVATE DB DB01"
db2 "BACKUP DB DB01 TO /db/db01/backup"

ここでDBを更新してみる。

db2 "ACTIVATE DB DB01"
db2 "CONNECT TO DB01"
db2 "INSERT INTO Hogetbl VALUES(2, 'gehogeho')"
db2 "TERMINATE"

ここで障害が発生したと想定し、リストア&ロールフォワードしてから、HADRのPRIMARYとして再始動する。

db2 "DEACTIVATE DB DB01"
db2 "RESTORE DB DB01 FROM /db/db01/backup TAKEN AT 20181028114425"
db2 "ROLLFORWARD DB DB01 TO END OF LOGS AND STOP"
db2 "ACTIVATE DB DB01"
db2 "CONNECT TO DB01"
db2 "SELECT * FROM Hogetbl"
db2 "START HADR ON DB DB01 AS PRIMARY"
db2 "db2pd -hadr -db DB01"

しばらくHADR_STATE = REMOTE_CATCHUP_PENDINGになっていたがPEERに戻った。

壊してみるその1(中途半端にリストア)

ログから最後までロールフォワードせず、バックアップ時点までしかもどさなかった(戻らなかった)場合。
まずは先ほどと同様にバックアップ取得。

db2 "DEACTIVATE DB DB01"
db2 "BACKUP DB DB01 TO /db/db01/backup"

DBを更新する。

db2 "ACTIVATE DB DB01"
db2 "CONNECT TO DB01"
db2 "INSERT INTO Hogetbl VALUES(3, 'hogehogehoge')"
db2 "TERMINATE"

障害発生!リストアする。

db2 "DEACTIVATE DB DB01"
db2 "RESTORE DB DB01 FROM /db/db01/backup TAKEN AT 20181028115805"
db2 "ROLLFORWARD DB DB01 TO END OF BACKUP AND STOP"
db2 "ACTIVATE DB DB01"
db2 "CONNECT TO DB01"
db2 "SELECT * FROM Hogetbl"

当然、3個目のレコードはない。ここでHADRを再開しようとすると、、、

db2 "START HADR ON DB DB01"
SQL1768N  Unable to start HADR. Reason code = "7".

db2 "? SQL1768N"で調べると、Reason code 7はSTANDBYとの通信タイムアウト。DB構成パラメタ上もSTANDARDになっている。

出力抜粋
db2 "GET DB CFG FOR DB01" | grep -i hadr
 HADR database role                                      = STANDARD

STANDBY側を調査する。

db2pd -hadr -db DB01
Database DB01 not activated on database member 0 or this database name cannot be found in the local database directory.

HADRが落ちているのでdb2diagで調べると。

出力抜粋
db2diag -l Severe
MESSAGE : ZRC=0x8610000D=-2045771763=SQLP_BADLOG "Log File cannot be used"
          DIA8414C Logging can not continue due to an error.
SQL1034C  The database was damaged, so all applications processing 
          the database were stopped.

あたりまえだが、PRIMARYとSTANDBYとでログの状態が変わったので、これ以上HADRはできないということで、STANDBY側のHADRが異常終了した。
これを修復するには再度PRIMARYでバックアップを取得し、これをSTANDBYへリストアするしかない(HADR初期構成)。
Directoryサーバのレプリケーションではオンライン初期化ができるのに、、、

復旧

PRIMARY側
db2 "BACKUP DB DB01 TO /nfs/db01"
STANDY側
db2 "STOP HADR ON DB DB01"
db2 "DROP DB DB01"                            # すでに存在するDBをドロップ
db2 "RESTORE DB DB01 FROM /nfs/db01 ENCRYPT"  # 最新バックアップからリストア
# HADR関連パラメタ変更
db2 "UPDATE DB CFG FOR DB01 USING
  HADR_LOCAL_HOST db2
  HADR_LOCAL_SVC db2_hadr
  HADR_REMOTE_HOST db1
  HADR_REMOTE_SVC db2_hadr
"
db2 "START HADR ON DB DB01 AS STANDBY"
PRIMARY側
db2 "START HADR ON DB DB01 AS PRIMARY"
db2pd -hadr -db DB01

といわけで超面倒。ログの不整合が起きると大変なので気をつけましょう。

壊してみるその2(STANDBYが計画停止)

STANDBYが計画停止している間にPRIMARYのログが全部切り替わってしまった状況を想定(PRIMARYのアーカイブログを使ってSTANDBYをPEERまで持っていってくれるかどうかの検証)。

STANDBY側計画停止
db2 "DEACTIVATE DB DB01"
db2stop
PRIMARY側(データ更新しながらログをアーカイブへ逃がす)
# 現在のアクティブログを確認
db2 "GET DB CFG FOR DB01" | grep "First active"
# ついでにログ設定も確認
db2 "GET DB CFG FOR DB01" | grep -e "LOGPRIMARY" -e "LOGSECOND"

# 更新とログアーカイブの繰り返し
for i in $(seq 5 50); do
db2 "CONNECT TO DB01"
db2 "INSERT INTO Hogetbl VALUES(${i}, 'hogehoge')"
db2 "TERMINATE"
db2 "ARCHIVE LOG FOR DB DB01"
done

# ログとHADR状況確認
find /db/db01/log1/NODE0000 -name "*.LOG"

db2pd -hadr -db DB01 | grep _LOG_FILE
            PRIMARY_LOG_FILE,PAGE,POS = S0000160.LOG, 0, 741864654
            STANDBY_LOG_FILE,PAGE,POS = S0000110.LOG, 2, 533182206
     STANDBY_REPLAY_LOG_FILE,PAGE,POS = S0000110.LOG, 2, 533182206

この時点でのログの状態は以下の通りだった。

項目 状況
PRIMARYのFirst active log S0000160.LOG
PRIMARYのアクティブログ保持状況 S0000159.LOG〜S0000171.LOG(LOGPRIMARY=13)
STANDBYのFirst active log相当 S0000110.LOG

つまり、STANDBY側はPRIMARYのアクティブログからは追いつけない状況になっている。

STANDBY側復旧
db2start
db2 "ACTIVATE DB DB01"
db2pd -hadr -db DB01

"HADR_STATE"は"REMOTE_CATCHUP"からしばらくして"PEER"になった。
このことから、PRIMARYのアーカイブログも使って、STANDBY側のDBに追いつきをかけてくれると想定される。

  1. マニュアルには「個別の」ポートが必要と記載があるが、同じポート番号が不可とは明記されていない。

7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?