PostgreSQL移行は論理ダンプと復元テストをセットにする
PostgreSQLの大きな世代差を越えるなら、物理コピーより論理ダンプを選ぶ。 そしてバックアップは、取れたことではなく戻せることまで確認して初めて完成だ。
移行先で先に詰まったもの
しろまえ殿が古いPostgreSQLから新しい環境へ移行したとき、基本手順はpg_dumpで出し、pg_restoreで戻す形にした。
特定のデータベースならpg_dump -Fc(カスタム形式で圧縮しつつ出力するダンプオプション)とpg_restoreの組み合わせが扱いやすい。
最初に問題になったのは、テーブル所有者のロールが移行先に無いことだった。 データだけ先に戻しても、所有権の付け替えで止まる。
ロール定義はpg_dumpall --globals-only(ロールや権限などデータベース共通のグローバル定義だけを出力するオプション)で別に取得し、移行先へ先に用意する。
古いバージョンでは使えないオプションもあるため、移行元のpg_dumpall --helpで対応状況を確認する。
バージョン差では、削除された型や古い認証方式も確認する。 リストア中の警告が致命的かどうかは、終了コード、テーブル一覧、件数で判定する。
日次処理は二つに分ける
日次バックアップは、データベースとアップロードファイルを別ジョブにした。
systemdのoneshot service(一度だけ実行して終了するサービス単位)とtimer(指定スケジュールでサービスを起動する仕組み)を使い、timerにはOnCalendar=daily(毎日実行するスケジュール指定)とPersistent=trueを設定する。
サーバーが停止していた日の取り逃しを、次回起動時に補える。
複数ジョブにはRandomizedDelaySecを設け、同時刻の負荷集中を避ける。
接続情報はコマンドライン引数やログへそのまま出さない。 接続文字列から必要な値だけを取り出し、プロセスの扱いを確認できる形で渡す。
世代管理は日付ごとのファイルにし、findで一定期間を超えた世代を削除する。
削除処理は、実データではなくtouch -dで作ったテストファイルで境界を確かめる。
たとえば防災袋を作るだけでなく、実際に中身を取り出せるか訓練するようなものだ。
取得成功だけで満足しない
確認する項目は、出力ファイルが空でないこと、timerが登録されていること、既存サービスが変化していないことだ。 さらに隔離した検証先へ復元し、テーブルと件数を照合する。
しろまえ殿の移行で残った宿題は、別の保管先への遠隔退避と定期的な復元演習だった。 ダンプが存在するだけでは、障害時の答えにならない。
取って、戻して、戻ったデータを確かめる。 この三段を運用に組み込めば、バックアップは頼れる仕組みになる。