Mastodon管理者のためのWAL-Gバックアップ
WAL-Gのススメ
Mastodonサーバ管理者(鯖缶)のみなさん、オブジェクトストレージ、使ってますか?
使っているなら、PostgreSQLのバックアップ、オブジェクトストレージにとるという手がありますよ。
ざっくり言うと、
- PostgreSQLの設定に
archive_mode=on
とarchive_command='wal-g wal-push'
を追加し、自動で差分バックアップをとる - cronで、毎日
wal-g backup-push
で自動でフルバックアップをとる - cronで、毎週
wal-g delete retain 7
で7回分だけ残して自動で残りを削除する
という感じです。簡単でしょ?
なお、WAL-Gはgoで書かれていて、バイナリ1個配置すれば動きます。
保管場所がオブジェクトストレージなので、
- 安価で、容量の心配不要
- 復元が簡単
- 任意の時点に復元可能
- 全自動
- (暗号化)
- (サーバの引っ越しが簡単)
というような利点があります。
便利そうでしょ? やってみる?
設定手順
とりあえずUbuntu、wasabi、PostgreSQL11で説明します。
オブジェクトストレージに保存場所を作る
- wasabi(S3やS3互換ストレージ)で、バックアップ保存用のバケットを作る
たとえば、i.ll.be.back
というバケットをつくります。
- APIアクセスできるようにしたユーザーに読み書きできる権限を与える
こういうポリシーを作って(i-ll-be-back-fullaccess
とか)
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::i.ll.be.back" }, { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:DeleteObject" ], "Resource": "arn:aws:s3:::i.ll.be.back/*" } ] }
Mastodonで使っているユーザーのPermissionsにこのポリシーを与えます。
バックアップオペレーターを作ってもいいと思います。
新規につくる場合、APIアクセスできるようにして、KEY_IDとACCESS_KEYをわかるようにしておいて下さい。
WAL-Gをとってきて配置する
- WAL-G is an archival restoration tool for Postgres.を見にいって、最新リリースのページから最新版のバイナリをもらってくる
/usr/local/bin
にでもおいておく
wget -O - https://github.com/wal-g/wal-g/releases/download/v0.2.9/wal-g.linux-amd64.tar.gz|tar xvzf - sudo mv wal-g /usr/local/bin
設定を環境変数に保存してまとめて呼び出せるようにenvdirを入れておく
- daemontoolsに入ってるので入れる
sudo apt install daemontools
環境変数を設定する
- ディレクトリを作って、変数名のファイルを作って中身を書き込む
sudo mkdir -p /etc/wal-g.d/env sudoedit /etc/wal-g.d/env/AWS_ACCESS_KEY_ID sudoedit /etc/wal-g.d/env/AWS_SECRET_ACCESS_KEY echo "https://s3.us-west-1.wasabisys.com" | sudo tee /etc/wal-g.d/env/AWS_ENDPOINT echo "s3://i.ll.be.back/" | sudo tee /etc/wal-g.d/env/WALG_S3_PREFIX echo "/var/run/postgresql" | sudo tee /etc/wal-g.d/env/PGHOST echo "5432" | sudo tee /etc/wal-g.d/env/PGPORT echo "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/go/bin" | sudo tee /etc/wal-g.d/env/PATH
wasabiのリージョンにあわせたENDPOINTと、バックアップ用のエンドポイントにあわせてs3://バケット名/
のように設定すること。
- バックアップのリストを表示する
backup-list
で No backups found になることを確認する。
sudo -u postgres envdir /etc/wal-g.d/env wal-g backup-list
postgres.confに設定する
データディレクトリのpostgresql.conf
を変更する。
データディレクトリはpg_lscluster
して確認。ついでにログの場所も確認しとく。
なお、私はconf.d/archive.conf
に書いて、postgresql.confでinclude_dir = 'conf.d'
のコメントはずして有効にし、個別に読み込ませるのが好き。
archive_mode = on archive_command = '/usr/bin/envdir /etc/wal-g.d/env /usr/local/bin/wal-g wal-push %p' archive_timeout = 60 wal_level = replica
archive_timeout
で60秒に一度はWALをアーカイブするようにしている。
すでにレプリケーションを設定していれば、wal_level
の設定は不要。
バックアップする
とりあえず差分から
さっき設定したpostgresqlをrestartして、動いているかどうか、ログを監視する。
sudo pg_ctlcluster 11 main restart
sudo tail -f /var/log/postgresql/postgresql-11-main.log
次にフルバックアップ
sudo -iu postgres envdir /etc/wal-g.d/env wal-g backup-push /var/lib/postgresql/11/main
cronで定期実行を仕込む
毎日フルバックアップ、毎週7つだけ残して古いのを削除、という設定。このへんは任意に。
sudo crontab -u postgres -e
@daily /usr/bin/envdir /etc/wal-g.d/env /usr/local/bin/wal-g backup-push /var/lib/postgresql/11/main @weekly /usr/bin/envdir /etc/wal-g.d/env /usr/local/bin/wal-g delete retain 7 --confirm
リストアする
リストアしても副作用はないので、バックアップをとりはじめたら、とりあえず一回やってみることをお薦めする。
どこか別のUbuntu環境に復元してみる。
いざという時の復旧手順そのものなので、ちゃんと記録しておいたり、準備しておいたりした方がいいよ。
envdirとか環境変数とかWAL-Gとか準備する
さっきと手順は同じ。
wget -O - https://github.com/wal-g/wal-g/releases/download/v0.2.9/wal-g.linux-amd64.tar.gz|tar xvzf - sudo mv wal-g /usr/local/bin sudo apt install daemontools sudo mkdir -p /etc/wal-g.d/env sudoedit /etc/wal-g.d/env/AWS_ACCESS_KEY_ID sudoedit /etc/wal-g.d/env/AWS_SECRET_ACCESS_KEY echo "https://s3.us-west-1.wasabisys.com" | sudo tee /etc/wal-g.d/env/AWS_ENDPOINT echo "s3://i.ll.be.back/" | sudo tee /etc/wal-g.d/env/WALG_S3_PREFIX echo "/var/run/postgresql" | sudo tee /etc/wal-g.d/env/PGHOST echo "5432" | sudo tee /etc/wal-g.d/env/PGPORT echo "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/go/bin" | sudo tee /etc/wal-g.d/env/PATH
復元先のクラスタを作って、データディレクトリを空にしとく
sudo pg_createcluster 11 test sudo sh -c "rm -rf /var/lib/postgres/11/test/*"
最新のフルバックアップを復元
sudo -u postgres envdir /etc/wal-g.d/env wal-g backup-fetch /var/lib/postgresql/11/test/ LATEST
最新の差分を復元
データディレクトリにrecovery.confを作成して
cat <<_EOS_ | sudo -u postgres tee /var/lib/postgresql/11/test/recovery.conf restore_command = '/usr/bin/envdir /etc/wal-g.d/env /usr/local/bin/wal-g wal-fetch "%f" "%p"' _EOS_
で、動かす。
sudo pg_ctlcluster 11 test start
必要な差分を適用し、recovery.confがrecovery.doneにリネームされて、書き込み可能な状態になる(リストア完了)
任意の時点に復元する
フルバックアップのリストを表示して、last_modifiedから対象のバックアップのnameをピックアップ
sudo -u postgres envdir /etc/wal-g.d/env wal-g backup-list
LATESTの代わりにnameを指定
sudo -u postgres envdir /etc/wal-g.d/env wal-g backup-fetch /var/lib/postgresql/11/test/ base_000000020000000000000042
recovery.confに日時を指定
cat <<_EOS_ | sudo -u postgres tee /var/lib/postgresql/11/test/recovery.conf restore_command = '/usr/bin/envdir /etc/wal-g.d/env /usr/local/bin/wal-g wal-fetch "%f" "%p"' recovery_target_time = '2019-03-04 17:20:00' _EOS_
という流れです。
サーバ引っ越しの際は?
下準備
- 引っ越し先にフルバックアップをbackup-fetchする
- recovery.confを作成(wal-fetch)
- /etc/postgresql/11/main の設定ファイル類を持ってくる
- postgresql.conf の設定内容を、新旧比較して反映する
このとき、元サーバであらかじめconf.d/
に設定を分離していれば、postgresql.confそのものをいじらずに済む - pg_hba.conf は接続セキュリティ設定なので、IPアドレスなどの変更を含めて反映し、よく見直しておく
- (その他のファイルも、使っていたものがあれば反映する)
本番
- 元のデータベースを停止
- 引っ越し先のデータベースを開始
という流れになります。
本番前に、一度testクラスタを作って練習しておきましょう。
練習が済んだら、pg_dropcluster 11 test --stop
などでバッサリ削除します。
暗号化は?
説明が長くなるので割愛します :-)
wal-gのgithubを見て、環境変数で、WALG_S3_SSE
とかWALG_S3_SSE_KMS_ID
とか、WALG_PGP_KEY
やWALG_PGP_KEY_PATH
などを指定してください。仕組みがわかっていれば簡単です。
参考資料
- WAL-G github
- WAL-Eの場合(1) WAL-E で PostgreSQL の Backup / Restore
- WAL-Eの場合(2) Herokuが開発したWAL-Eを使って、AWSでPostgreSQLのバックアップを取る