通常のLOADはIMPORT(INSERTの繰返し)と違ってログ出力が最低限になるので、ログシッピングを前提としているHADR環境での使用には注意がいる。具体的にはリカバリ(ROLLFORWARD)用のイメージ出力をしつつ、かつそのイメージファイルにSTANDBY側からPRIMARYと同じパスでアクセスできる必要がある。
- Db2 v11.1
- OS: RHEL 7.3
- DB名: HADRDB
- PRIMARYホスト: db1
- STANDBYホスト: db2
NFS環境
もともと密結合にならざるを得ないHADR環境ではあるが、LOADする場合はさらに密。今回はNASサーバが別にいて各DBサーバからマウントして使用できる、という構成にする。
nas:/export/disk1 /nfs nfs defaults,soft,noauto 0 0
このNASサーバはそれほど可用性が高くないので、マウントオプションにsoft,noautoを付与しておく。/nfs/loadディレクトリ下にイメージを出力することにする。PRIMARYとSTANDBY側から同じパスでマウントする。
投入データ作成
# 投入データ作成
for i in $(seq 1 100000); do
echo "${i},hogehoge${i}" >> hogetbl.csv
done
NONRECOVERABLEなLOADの実験
# データ初期化
db2 "TRUNCATE TABLE Hogetbl IMMEDIATE"
# オフラインバックアップ
db2 "TERMINATE"
db2 "DEACTIVATE DB HADRDB"
db2 "BACKUP DB HADRDB TO /nfs"
# LOAD実行
db2 "ACTIVATE DB HADRDB"
db2 "CONNECT TO HADRDB"
db2 "LOAD FROM hogetbl.csv OF DEL INSERT INTO Hogetbl COPY NO"
# HADR確認
db2pd -hadr -db hadrdb # peer
HADR_FLAGS = STANDBY_TABLESPACE_ERROR SSL_PROTOCOL
FLAGSのところにSTANDBY_TABLESPACE_ERRORと出力されている。
また、STANDBYの"instance.nfy"ログに以下のようなメッセージが記録される。
ADM5571W The "DATA" object with ID "4" in table space "2" for table "TBSPACEID=2.TABLEID=4" is being marked as unavailable.
STANDBY側に計画切替えして確認する。
db2 "TAKEOVER HADR ON DB HADRDB"
db2 "CONNECT TO HADRDB"
db2 "SELECT COUNT(*) FROM Hogetbl"
SQL1477N For table "DBINST.HOGETBL" an object "4" in table space "2" cannot
be accessed. SQLSTATE=55019
出力されたメッセージを元に、わかりきってはいるが対象のテーブルを調べる。
db2 "SELECT TABNAME FROM SYSCAT.TABLES WHERE TABLEID='4' AND TBSPACEID='2'"
HOGETBLが無効になったとわかる。
と、このようにNONRECOVERABLEなLOADをHADR環境で実行すると、STANDBY側でTAKEOVERしても当該表へはアクセスできなくなる。PRIMARYでどのような更新があったとしてもスキップされる。
LOAD元ファイル(今回の例ではhogetbl.csv)がSTANDBY側にも転送されて、TAKEOVER時にDROP TABLE/CREATE TABLE/LOADするという運用になっているならそれはそれでOKではある。とにかく、STANDBY側でこれを復旧するには、一度対象のテーブルをDROPしてCREATEしなおすか、バックアップからリストアする必要がある。
今回は0件状態のバックアップからリストアして復旧。
db2 "TERMINATE"
db2 "DEACTIVATE DB HADRDB"
db2 "RESTORE DB HADRDB FROM /nfs"
db2 "START HADR ON DB HADRDB AS ${HADR_ROLE}" # STANDBY|PRIMARYの順
db2pd -hadr -db hadrdb # peer
COPY YESでのLOADとロールフォワードの実験
# バックアップ取得
db2 "BACKUP DB HADRDB ONLINE TO /nfs"
# COPY YESでログ出力しつつLOAD
mkdir /nfs/load
db2 "LOAD FROM /nfs/hogetbl.csv OF DEL INSERT INTO Hogetbl COPY YES TO /nfs/load"
# HADR状態確認
db2pd -hadr -db hadrdb # peer
# /nfs/loadを確認
ls -l /nfs/load
HADRDB.4.dbinst.DBPART000.20181115215259.001 HADRDB.4.dbinst.DBPART000.20181115215326.001
ここで障害が発生した想定でバックアップからリストアする。
db2 "TERMINATE"
db2 "DEACTIVATE DB HADRDB"
db2 "RESTORE DB HADRDB FROM /nfs TAKEN AT 20181115215120" # さっきとったオンラインバックアップ
db2 "ROLLFORWARD DB HADRDB TO END OF LOGS" # 戻せるところまでロールフォワード
db2 "ROLLFORWARD DB HADRDB STOP" # ペンディング解除
db2 "START HADR ON DB HADRDB AS PRIMARY" # HADR復帰
db2pd -hadr -db hadrdb # peer
db2 "CONNECT TO HADRDB"
db2 "SELECT COUNT(*) FROM Hogetbl" # 10万件
LOADしたデータもロールフォワードでき、かつHADRもPEERになった(STANDBYでTAKEOVERして更新したりしていない、つまりPRIMARYがROLLFORWARDすることでSTANDBYとデータ整合が取れた)。
では、このログはいつまで必要か、といえば当然次にバックアップを取るまで、ということになる。とはいっても自動で削除してくれるわけではないので、自分で削除する。