移行 への 道のり
- 社内で初めてのAWS商用利用サービス
- 単一 availability zone
- ほぼメンテされなくなっている自社HA構成
→ なんとかしたい
-
from : PostgreSQL 9.3 on EC2
-
to : Amazon RDS for PostgreSQL (9.4) Multi-AZ!
これを達成するために、いくつもの闇を垣間見ることになりました。
Amazon DMS の 闇
1. ソースDB PostgreSQL 9.4 or later
-
ソース側にレプリケーションスロットの設定が必要
- (つまり、そのあたりの機能を使っている)ということでここを回避するのは難しい
-
私たちは、事前にアップグレードメンテをやりました(することができました)
upgradeも時間を短縮したい!
pg_upgrade -k
- ハードリンクで移行をすることによって、アップデートにかかる時間は大幅に短縮
- 旧バージョンの
PGDATA
領域にあるgarbageはVACUUM
でも回収されない部分がでてきてしまう- ストレージ領域の余剰に注意
2. 謎のエラー終了(テーブル単位)
どうしてもエラー終了になってしまうテーブルが存在した。
→ マニュアルをみても、ログを見ても理由が不明で解消しきらない
→ 「がんばってしまう」のか、これらがあるとタスク完了までの時間も延びる
DMSタスクで「除外」に設定して、テーブルダンプで対応
→ データベース全体からみれば小さい話なので、がんばりすぎないで割り切る。
Amazon RDS for PostgreSQL の 闇との 合わせ技
3. superuser の 闇
Amazon RDS for PostgreSQL では superuser は使えません
(正直な話、superuserさえ使えていれば特に問題にならない話が多いです)
4. pg_dumpall は 使えない
当たり前ですが特権的なデータベースオブジェクトを含むpg_dumpallは、superuserがつかえないのでまともに使えません。
pg_dump は -x
-O
オプションをつける
データベースオブジェクトのオーナー毎に DMS タスクを作ればいけるかも?
5. large object の 闇
ラージオブジェクトはDMSの移行サポート外
- 某サービスでは、このlarge object をかなり重要なデータに使っている。
- pg_largeobjectテーブルは superuser でないと直接扱えない
- どうするか……
-O -x
オプションでテーブルダンプする ← 結論
6. timestamp型の闇
timestamp with time zone
型のカラムの値が、9時間ずれている!
-
2018/09/18 18:00+09
→2018/09/18 09:00+09
のようなズレ- 一見すると不可解。
timestamp with time zone
はDMSのサポート対象外
- ドキュメントには確かに書いてある(マジかよ)
- 困ってサポートに泣きついた
- 「パラメータグループで、RDSのタイムゾーンをUTCにして、移行が完了したらRDSのタイムゾーンをAsia/Tokyoにするという方法で回避できないか」
- → 無事回避
(言われてみれば、一旦UTCにしてデータを転送したあと、時刻表記をずらさずにタイムゾーン情報だけ後付けしているみたいなズレ)
#金の弾丸強い
7. テーブル継承の闇
テーブル継承をつかった同一ノード内で水平分割をしているテーブルがある
- 親テーブルに対するSELECT文の発行で、子テーブルを走査して結果を返してくれる
- 移行元では子テーブルにだけあるデータが、子テーブルのデータのみならず親テーブルのデータとしても抽出される
- データが二重に移行されてしまう
- 親テーブルはデータ移行対象から除外する必要がある。
8. スキーマと所有権の闇
ベーシックスキーマコピーの闇
- 元テーブルの定義をきちんと読んでくれるわけではなく、入っているデータを見ている
- character varying (制限なし) は 既存カラムの最大長に合わせて最大文字列長が設定される。
- DMSはあくまで「データをコピーするためのマネージドサービス」と割り切って使う
pg_dumpにオプションを付ける
pg_dump -d <database_name> -s -o -O -x
-
-s
でスキーマのみダンプ -
-O
で 所有権情報を出力しない -
-x
で アクセス権情報を出力しない。 -
-o
はoid情報の出力で、large objectを使っているので念のため。
所有権 の闇
superuserに頼った運用をしていると、以下の様な闇を踏むかもしれません。
Materialized Viewの闇
Materialized ViewのREFRESHはMVの所有者でないと実施できません。
テーブル継承の闇 パート2
子テーブルが増えるタイミングのトリガーは、テーブルの所有者でないと実施できません。
9. 制約の闇
外部キー制約、つけていますか?
- (SQLアンチパターン第4章:キーレスエントリも読もう!)
制約がついていると移行が難しい。
- FKやCHECK制約などはつけていない、シンプルなCREATE TABLE文だけを先にRDSインスタンスに適用
- DMSによるデータ移行を済ませた後に制約をつけたりインデックスを追加したり
10. sequenceの闇
-
シーケンスがどこまで進んでいるかはDMSによる移行対象になりません。
-
困ったときのQiita記事(ありがとうございます!)
落とし穴
- どこのカラムとも関連付けせずにアプリケーションから使っているシーケンスの存在
- そんなものに限ってテストしづらい外部連携機能で使っていたりする。
- つらい
終わりに
それでもAmazon DMSは便利でした。
いまではRDSで幸せに運用しています。