このチュートリアルでは、デモ用のデータベースを作成し、アプリケーション ワークロードを実行します。次に、アーカイブ プロセスとバックアップ プロセスを構成します。その後、バックアップ、アーカイブ、復元のプロセスを確認する方法について説明します。最後に、データベースを特定の時点まで復元する方法について説明します。
このチュートリアルは、PostgreSQL データベースのバックアップと復元の戦略に関心があるデータベース管理者、システム オペレータ、DevOps 専門家、クラウド アーキテクトを対象としています。
このチュートリアルでは、読者が Docker コンテナに精通しており、Linux コマンド、PostgreSQL データベース エンジン、Compute Engine を使い慣れていることを前提としています。
目標
- バックアップとアーカイブのプロセスを設定する。
- PITR を実行する。
- バックアップをモニタリングします。
- 復元を確認します。
費用
このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。
始める前に
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine and Cloud Storage APIs.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine and Cloud Storage APIs.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
コンセプト
チュートリアルを開始する前に、PostgreSQL の次のコンセプトを確認してください。
- 継続的なアーカイブ。データベースが継続的に順次トランザクションをファイルに保存することを指します。
- ログ先行書き込み(WAL)。データファイルへの変更は、ファイルに適用される前に WAL に記録されます。
- WAL レコード。データベースに適用される各トランザクションは、WAL レコードとしてフォーマットされて、保存されます。
- セグメント ファイル。セグメント ファイルのファイル名は単調に増加し、可能な限り多くの WAL レコードが含まれます。ファイルサイズは構成可能で、デフォルトは 16 MiB です。大きなサイズまたは多数のトランザクションが予想される場合は、生成されるセグメント ファイルの合計数を減らし、ファイル管理の負担を軽減するために、このファイルサイズを大きくできます。
詳細については、信頼性とログ先行書き込みをご覧ください。
次の図は、WAL が 2 つのステージでどのように保持されるかを示しています。
上の図では、永続的な WAL の最初のステージは、テーブルへの書き込みと同時に、WAL バッファ内の書き込みトランザクションを記録するデータベース エンジンで構成されています。トランザクションが commit されると、2 番目のステージで WAL バッファがディスクに書き込まれ(フラッシュされ)、WAL セグメント ファイルに追加されます。
PITR を選択する
PITR は、次のような場合に適しています。
- リカバリ ポイント目標(RPO)を最小限に抑える。 RPO とは、許容されるデータ損失の最大時間です。この時間を超えるとビジネス プロセスに重大な影響がおよびます。バックアップ スナップショット間ですべてのトランザクションを WAL に保存すると、最後の完全バックアップ以降のトランザクションがデータベースに適用されるため、失われるデータの量が大幅に減少します。
- リカバリ時間目標(RTO)を最小限に抑える。RTO は、破壊的なイベントが発生した場合にデータベースを復元するために必要な時間です。バイナリ バックアップとログアーカイブを設定すると、データベースの復元に必要な時間を最小限に抑えることができます。
- データ破損のバグや管理上の誤りを修正する。 コードのリリースによって壊滅的なデータの破損が発生した場合や、定期メンテナンス中に回復不能なミスをした場合、その前の状態に復元できます。
マイクロサービス アーキテクチャなどの一部のアプリケーション アーキテクチャには、独立した復元が必要な並列データベースが存在する場合があります。たとえば、小売アプリケーションで顧客データが 1 つのデータベースに格納され、小売注文の詳細と在庫情報が他のデータベースに格納されている場合などです。データの全体的な状態に応じて、1 つ、2 つ、またはすべてのデータベースを並行して復元する必要があります。
以下の状況では、PITR は適切でありません。
- RPO が大きい。障害復旧ポリシーにより、最近のスナップショットの後に受信したトランザクションの損失を許容できる場合は、追加の手順を行わずに、データの復元時間を短縮することに集中できます。
- データベースを完全に復元する必要がある。直近のトランザクションに復元することが目標である場合、復元のターゲットは最後に保存されたトランザクションのタイムスタンプになります。このシナリオは PITR の特殊なケースですが、意味的にこの目標は「完全復旧」と呼ばれます。
パフォーマンスに関する注意事項
アーカイブ プロセスにより、データベース サーバーに追加の I/O 負荷がかかります。追加の負荷は、トランザクションの書き込み、更新、削除の量に比例するため、ワークロードの特性によって異なります。
WAL アーカイブのアクティビティによってプライマリ データベースに及ぼされる I/O の影響を減らすには、読み取り専用レプリカを使用して定期的に WAL アーカイブを実行します。
この構成により、WAL ファイルの転送に関連するバッチ指向の I/O アクティビティからプライマリ データベースが分離されます。読み取り専用レプリカを宛先とするトランザクションは、プライマリ データベースから一定のストリームで送信されるため、安定したスループットに対する影響ははるかに小さくなります。
さらに、本番環境のデータベース トポロジにすでに読み取り専用のレプリカが含まれている場合、この構成によって管理や価格などの負担が増えることはありません。
リファレンス アーキテクチャ
次の図は、このチュートリアルで実装するアーキテクチャを示しています。
このチュートリアルでは、クラウド インフラストラクチャを作成して、次のコンポーネントを使用する PITR を確認します。
- Compute Engine で実行される PostgreSQL データベース サーバー。
- スナップショットとトランザクション ログを保存するための Cloud Storage。
次の図は、PostgreSQL データベース仮想マシン(VM)で起動される 2 つの Docker コンテナを示しています。関心の分離として、データベース サーバーはコンテナの 1 つで実行され、WAL アーカイバは別のコンテナで実行されます。
この図は、各コンテナの Docker ボリュームが、ホスト VM の永続ディスク マウント ポイントにどのようにマッピングされるかを示しています。
環境変数を設定する
このチュートリアルで使用するスクリプトとコマンドは、シェル環境変数に依存します。
Cloud Shell で、プロジェクト、インスタンス名、デモ用の PostgreSQL データベースの環境変数を設定します。
export PROJECT_ID=your-gcp-project export PG_INSTANCE_NAME=instance-pg-pitr export POSTGRES_PASSWORD=PasswordIsThis export POSTGRES_PITR_DEMO_DBNAME=pitr_demo
次のように置き換えます。
your-gcp-project
: このチュートリアル用に作成したプロジェクトの名前。PasswordIsThis
: PostgreSQL データベースの安全なパスワード。
Google Cloud ゾーンの環境変数を設定します。
choose-an-appropriate-zone
を Google Cloud ゾーンに置き換えます。export ZONE=choose-an-appropriate-zone export REGION=${ZONE%-[a-z]}
ゾーンのリージョンのデフォルトの Virtual Private Cloud(VPC)サブネットの環境変数を設定します。
export SUBNETWORK_URI=$(gcloud compute networks subnets \ describe default --format=json --region=$REGION | \ jq --raw-output '.ipCidrRange')
Cloud Storage バケットの環境変数を設定します。
archive-bucket
は、WAL が保存されている Cloud Storage バケットの一意の名前に置き換えます。export ARCHIVE_BUCKET=archive-bucket
Cloud Storage バケットの作成
Cloud Storage バケットを作成して、PostgreSQL データベースから WAL ファイルをアーカイブします。
gcloud storage buckets create gs://${ARCHIVE_BUCKET}
プライベート IP アドレスのインスタンスにアクセスできるようにする
このチュートリアルで使用するインスタンスの場合、多くの本番環境のユースケースと同様に、VM インスタンスでパブリック IP アドレスを取得する必要はありません。ただし、インスタンスはパブリック インターネットにアクセスしてサンプル コンテナ イメージを pull する必要があり、セキュアシェルを使用して接続するための権限が必要です。ネットワーク アドレス変換(NAT)ゲートウェイを構成し、TCP 転送用の Identity-Aware Proxy(IAP)を構成します。
NAT ゲートウェイを作成する
作成する VM インスタンスにはパブリック IP アドレスがないため、インスタンスが Docker Hub からコンテナ イメージを pull できるように NAT ゲートウェイを作成します。
Cloud Shell で、Cloud Router を作成します。
export CLOUD_ROUTER_NAME=${PROJECT_ID}-nat-router gloud compute routers create $CLOUD_ROUTER_NAME \ --network=default --region=$REGION
NAT ゲートウェイを作成します。
gcloud compute routers nats create ${PROJECT_ID}-nat-gateway \ --region=$REGION \ --router=$CLOUD_ROUTER_NAME \ --auto-allocate-nat-external-ips \ --nat-all-subnet-ip-ranges
TCP 転送用に IAP を構成する
IAP は、Google Cloud で実行されているクラウド アプリケーションと VM へのアクセスを制御します。IAP は、リクエストのユーザー ID とコンテキストを確認して、ユーザーが VM にアクセスできるかどうかを判断します。
Cloud Shell で、TCP 転送ネットブロックからプロジェクト内のインスタンスへのトラフィックを許可します。
export IAP_FORWARDING_CIDR=35.235.240.0/20 gcloud compute --project=$PROJECT_ID firewall-rules create \ cloud-iap-tcp-forwarding --direction=INGRESS \ --priority=1000 --network=default \ --action=ALLOW --rules=all \ --source-ranges=$IAP_FORWARDING_CIDR
TCP 転送トンネルを使用して接続するには、Identity and Access Management(IAM)ポリシー バインディングを追加します。
your-email-address
は、Google Cloud コンソールへのログインに使用するメールアドレスに置き換えます。export GRANT_EMAIL_ADDRESS=your-email-address gcloud projects add-iam-policy-binding $PROJECT_ID \ --member=user:$GRANT_EMAIL_ADDRESS \ --role=roles/iap.tunnelResourceAccessor
PostgreSQL データベース インフラストラクチャを作成する
Cloud Shell で、構成スクリプトを含むソース リポジトリのクローンを作成し、シェル コンテキストをローカル リポジトリに変更します。
git clone https://github.com/GoogleCloudPlatform/gcs-postgresql-recovery-tutorial cd gcs-postgresql-recovery-tutorial
データベース VM インスタンスを作成して構成するには、次のスクリプトを実行します。
cd bin ./create_postgres_instance.sh
このチュートリアルのスクリプトでは、コンテナ用に最適化されたオペレーティング システムと 2 つの新たに追加された永続ディスクを使用して、選択したゾーンで VM インスタンスを起動します。この場合、スクリプトによって小さな永続ディスクが作成されるため、API から返される I/O パフォーマンスの低下に関する警告メッセージは無視してかまいません。
cloud-init 構成を確認する
cloud-init は、クラウド インスタンスを初期化するマルチ配布パッケージです。
次の cloud-init コードサンプルを確認します。
このチュートリアルでは、cloud-init を使用して次のことを行います。
- 2 つの永続ディスク ブロック ストレージ デバイスを作成します。
- 2 つのデバイスにファイル システムを作成します。1 つはデータ用で、もう 1 つはアーカイブログ用です。
- Docker コンテナと共有されている VM インスタンスの論理マウント ポイントにデバイスをマウントします。
systemd
サービス(postgres.service
)を作成して開始します。これにより、次とともに、PostgreSQL Docker コンテナが開始します。- ボリュームとしてマウントされた永続ディスク。
- VM ホストに公開されている PostgreSQL ポート(
5432
)。
/var/tmp/docker-entrypoint-initdb.d/init-pitr-demo-db.sql
ファイルを作成して、デモ用のデータベースとスキーマに簡単なテーブルセットを作成します。- WAL ディスクをボリュームとしてマウントして、Google Cloud CLI の Docker コンテナを実行する 2 つ目の
systemd
サービス(wal_archive.service
)を作成して起動します。このサービスにより、アーカイブされた WAL ファイルが Cloud Storage にバックアップされます。 wal_archive.service
を定期的に実行するsystemd
タイマー(wal_archive.timer
)を作成して有効にし、開始します。- トランザクション生成ツールがデータベース ポートに到達できるように、VPC サブネットの PostgreSQL ポート(
5432
)が開いていることを確認します。
データベース インスタンス構成を変更する
データベース サーバーは稼働していますが、ネットワーク アクセスを構成し、WAL アーカイブ プロセスを開始する必要があります。
データベース VM インスタンスに接続する
Google Cloud コンソールで [VM インスタンス] ページに移動します。
ターミナル シェルを開くには、作成した
instance-pg-pitr
インスタンスの横にある [SSH] をクリックします。ターミナル シェルで、Docker コンテナが起動したことを確認します。
docker ps
出力は次のようになります。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8bb65d8c1197 postgres:11-alpine "docker-entrypoint.s…" About a minute ago Up About a minute postgres-db
コンテナがまだ実行されていない場合は、しばらく待ってから、同じコマンドを使用してもう一度確認します。
データベースへの受信ネットワーク接続を許可する
instance-pg-pitr
インスタンスのターミナル シェルで、PostgreSQL ホストベースの認証構成ファイルを開いて編集します。sudoedit /mnt/disks/data/pgdata/pg_hba.conf
データベースへのデフォルトのすべての IP アドレス アクセスを削除するには、行の先頭に
#
を追加してファイルの末尾から次の行をコメントアウトします。ファイル内の行は次のようになります。#host all all all md5
10.0.0.0/8
CIDR ブロックでホストからのパスワードで保護された接続を許可するには、次の行をファイルの末尾に追加します。host all all 10.0.0.0/8 md5
このエントリにより、後でトランザクション生成ツールが作成される VPC サブネットからの接続が有効になります。
ファイルを保存して閉じます。
WAL アーカイブを構成する
instance-pg-pitr
インスタンスのターミナル シェルで、postgresql.conf
ファイルを編集します。sudoedit /mnt/disks/data/pgdata/postgresql.conf
コメントアウトされた既存の
archive_mode
、archive_command
、archive_timeout
行を次のように置き換えます。archive_mode=on archive_command = '( ARCHIVE_PATH=/var/lib/postgresql/wal/pg_wal_archive; test ! -f $ARCHIVE_PATH/%f && cp %p $ARCHIVE_PATH/%f.cp && mv $ARCHIVE_PATH/%f.cp $ARCHIVE_PATH/%f ) ' archive_timeout = 120
変更したファイルの行を置き換えると、次のコード スニペットのようになります。
ファイルを保存して閉じます。
構成の変更を適用して確認する
instance-pg-pitr
インスタンスのターミナル シェルで、コンテナを再起動して変更を適用します。sudo systemctl restart postgres
WAL セグメント ファイルを確認します。
sudo ls -l /mnt/disks/wal/pg_wal
出力は次のようになります。
total 16388 -rw------- 1 postgres 70 16777216 Sep 5 23:07 000000010000000000000001 drwx------ 2 postgres 70 4096 Sep 5 23:05 archive_status
データベースへのネットワーク接続を確認します。
export LOCAL_IP=127.0.0.1 docker exec postgres-db psql -w --host=$LOCAL_IP \ --command='SELECT 1'
出力は次のようになります。
?column? ---------- 1 (1 row)
インスタンスに対する SSH 接続を閉じます。
トランザクション生成ツールを起動してデータベースにデータを入力する
次の手順では、このチュートリアルのトランザクションを生成する Go プログラムを起動します。このプログラムは VM インスタンス上のコンテナ内で実行されます。
コンテナのイメージは、一般公開されている Container Registry を使用してすでにビルドされ、プロジェクトでホストされています。
Cloud Shell で、トランザクション生成ツールのディレクトリに移動します。
cd ~/gcs-postgresql-recovery-tutorial/bin
環境変数を設定します。
export TRANS_GEN_INSTANCE_NAME=instance-trans-gen export POSTGRES_HOST_IP=$(gcloud compute instances describe \ --format=json --zone=${ZONE} ${PG_INSTANCE_NAME} | \ jq --raw-output '.networkInterfaces[0].networkIP')
トランザクション生成ツールを実行するには、インスタンスを起動します。
./run_trans_gen_instance.sh
I/O パフォーマンスの低下に関する警告メッセージは無視してください。
しばらく待ってから、トランザクションが PostgreSQL データベースに到達していることを確認します。
gcloud compute ssh $PG_INSTANCE_NAME \ --tunnel-through-iap \ --zone=$ZONE \ --command="docker exec postgres-db psql \ --dbname=$POSTGRES_PITR_DEMO_DBNAME \ --command='SELECT COUNT(*) FROM pitr_db_schema.customer;'"
トランザクション生成ツールによってデータベースにレコードが追加されると、出力には 0 よりも大きい数値が含まれます。
count ------- 413 (1 row)
バイナリ スナップショットのバックアップ スケジュールを構成する
スケジュールに従って永続ディスクをバックアップし、リソース ポリシーで定義された期間保持できます。
スナップショット スケジュールを作成する
Cloud Shell で、環境変数を設定します。
export ZONE=zone-of-your-instance export SNAPSHOT_SCHEDULE_NAME=pg-disk-schedule export REGION=${ZONE%-[a-z]} export SNAPSHOT_WINDOW_START=$(TZ=":GMT" date "+%H:00") export SNAPSHOT_RETENTION_DAYS=2 export SNAPSHOT_FREQUENCY_HOURS=1
zone-of-your-instance は、以前にデータベース VM を起動した Google Cloud ゾーンに置き換えます。
スナップショット スケジュールを作成します。
gcloud compute resource-policies create snapshot-schedule \ $SNAPSHOT_SCHEDULE_NAME \ --region=$REGION \ --max-retention-days=$SNAPSHOT_RETENTION_DAYS \ --on-source-disk-delete=apply-retention-policy \ --hourly-schedule=$SNAPSHOT_FREQUENCY_HOURS \ --start-time=$SNAPSHOT_WINDOW_START \ --storage-location=$REGION
スナップショット スケジュールをディスクに接続する
インスタンスを作成するスクリプトを実行したときに、2 つの独立した永続ディスクとしてデータと WAL ボリュームが作成されました。定義されたスケジュールに従って永続ディスクのスナップショットを作成するには、各永続ディスクにリソース ポリシーを関連付けます。この場合、ディスク スナップショットを同時に実行する必要があるため、Compute Engine VM に接続された両方の永続ディスクに同じポリシーを使用します。
Cloud Shell で、環境変数を設定します。
export SNAPSHOT_SCHEDULE_NAME=pgdata-disk-schedule export PG_INSTANCE_NAME=instance-pg-pitr export ZONE=zone-of-your-instance
永続データディスクにスケジュール ポリシーを接続します。
gcloud beta compute disks add-resource-policies ${PG_INSTANCE_NAME}-data \ --resource-policies $SNAPSHOT_SCHEDULE_NAME \ --zone $ZONE
永続 WAL ディスクにスケジュール ポリシーを接続します。
gcloud beta compute disks add-resource-policies ${PG_INSTANCE_NAME}-wal \ --resource-policies $SNAPSHOT_SCHEDULE_NAME \ --zone $ZONE
スナップショットを手動で実行する
(省略可)スケジュールされたスナップショットはスケジュール設定された期間内で実行されるため、スケジュールを作成したときにスナップショットがすぐに作成されることはほどんどありません。そこで、スケジュールされたスナップショットを待たずに、最初のスナップショットを手動で実行する手順を以下に示します。
Cloud Shell で、環境変数を設定します。
export ZONE=zone-of-your-instance export PG_INSTANCE_NAME=instance-pg-pitr export REGION=${ZONE%-[a-z]}
2 つの PostgreSQL インスタンス永続ディスクのスナップショットを作成します。
gcloud compute disks snapshot \ ${PG_INSTANCE_NAME}-data ${PG_INSTANCE_NAME}-wal \ --snapshot-names=${PG_INSTANCE_NAME}-data-`date+%s`,${PG_INSTANCE_NAME}-wal-`date +%s` \ --zone=$ZONE --storage-location=$REGION
作成したスナップショットを表示します。
gcloud compute snapshots list
出力は次のようになります。
NAME DISK_SIZE_GB SRC_DISK STATUS instance-pg-pitr-data-1578339767 200 us-central1-f/disks/instance-pg-pitr-data READY instance-pg-pitr-wal-1578339767 100 us-central1-f/disks/instance-pg-pitr-wal READY
PITR を実行する
多くの場合、PITR は運用上またはプログラム上の誤った手順によって失われたデータを復元するために実行されます。
チュートリアルのこのセクションでは、データベースの更新を実行して、データの壊滅的な損失をシミュレートします。次に、パニック状態のレスポンスをシミュレートした後、誤ったコマンドが発行されたときよりも前の時点への復旧を開始します。
PITR を使用できるようにする
PITR を実行する前に、次を実行するための十分な時間を確保しておく必要があります。
- バイナリのバックアップ(ディスク スナップショット)
- WAL のアーカイブ
このチュートリアルでは、頻繁に WAL ファイルをローテーションするために、標準的ではない 120 秒という低い値に archive_timeout
を設定しました。少なくとも 1 つのスケジュールされたディスク スナップショットが実行されるまで待つか、手動でディスクのスナップショットを作成する必要があります。
少なくとも 1 つのスナップショットが作成されたことを確認します。
Google Cloud コンソールで、[スナップショット] ページに移動します。
少なくとも 2 つのスナップショットがあることを確認します。1 つはデータ ボリューム用で、もう 1 つは WAL ボリューム用です(例:
instance-pg-pitr--us-central1-a-20190805023535-i3hpw7kn
)。
セグメント ファイルが Cloud Storage にアーカイブされていることを確認します。
Google Cloud コンソールで、Cloud Storage ブラウザページに移動します。
[
archive-bucket
] をクリックします。
データを破損する
壊滅的なデータ損失をシミュレートするには、PostgreSQL データベースに対してコマンドライン シェルを開き、トランザクション生成ツールによって入力されたテーブルのデータを破損させます。
Google Cloud コンソールで [VM インスタンス] ページに移動します。
instance-pg-pitr
インスタンスの [SSH] をクリックします。SSH ターミナルで、Docker コンテナの PostgreSQL ターミナルベースのフロントエンドを実行します。
docker exec -it postgres-db psql --dbname=pitr_demo
顧客テーブルの行を変更するには、PostgreSQL シェルで意図的な誤字を含む SQL DML ステートメントを送信します。
UPDATE pitr_db_schema.customer SET name = 'New Name for customer id=1'; WHERE id = 1;
出力は次のようになります。
UPDATE 999 pitr_demo=# WHERE id = 1; ERROR: syntax error at or near "WHERE" LINE 1: WHERE id = 1; ^
WHERE
句の前に余分なセミコロンが挿入されたため、エラーが発生しました。データベース内のすべての行が更新されました。これで、PITR を実行して、誤ったステートメントによって変更された行を復元できます。
復元の目標時間を決定する
PITR の最初のステップは、復元の目標時間を決定することです。この時間は、データを調べて、データ破損イベントの少し前の時点を特定することで決まります。
instance-pg-pitr
インスタンスのターミナル シェルで、破損した行の最大タイムスタンプを取得します。SELECT MAX(create_timestamp)::timestamptz FROM pitr_db_schema.customer WHERE name = 'New Name for customer id=1';
出力は次のようになります。
max . ------------------------------- 2019-08-05 18:14:58.226511+00 (1 row)
本番環境のデータベースでは、特に影響を受けるテーブルが大きく、指標列がインデックスに登録されていない場合、復元ターゲットを決定するクエリは複雑になります。
結果をコピーします。このクエリで返された値を次のステップで使用します。
データベースを復元する
このチュートリアルでは、復元スクリプトによって PITR が自動化されます。データベースを復元する自動プロセスを用意し、このプロセスを定期的にテストすることをおすすめします。
Cloud Shell で、現在の作業ディレクトリを復元スクリプトの場所に変更します。
cd ~/gcs-postgresql-recovery-tutorial/bin
スクリプトに必要な環境変数を設定します。
YYYY-MM-DD HH:MM:SS.999999+00
は、以前にコピーしたクエリ出力に置き換えます。export PROJECT_ID=$(gcloud config get-value project) export PG_INSTANCE_NAME=instance-pg-pitr export POSTGRES_PASSWORD=PasswordIsThis export PG_INSTANCE_NAME=instance-pg-pitr export RECOVER_BUCKET=archive-bucket export PIT_RECOVERY_TARGET="YYYY-MM-DD HH:MM:SS.999999+00" export ZONE=zone-of-your-instance
復元スクリプトを実行します。
./recover_to_point_in_time.sh
復元スクリプトを理解する
このセクションでは、入力パラメータとスクリプトで実行される手順について詳しく説明します。
このスクリプトでは、次の環境変数を設定する必要があります。
PIT_RECOVERY_TARGET
: 復元のターゲット時間。PROJECT_ID
:PG_INSTANCE_NAME
インスタンスが配置されているプロジェクト。ZONE
:PG_INSTANCE_NAME
インスタンスが配置されているゾーン。PG_INSTANCE_NAME
: 本番環境の PostgreSQL インスタンスが実行されているインスタンス。RECOVER_BUCKET
: WAL セグメント ファイルがアーカイブされる Cloud Storage バケット。POSTGRES_PASSWORD
: PostgreSQL データベース ユーザーに使用するパスワード。
スクリプトによって、次の手順が実行されます。
- 復元ターゲットの日時に基づいて、最新のディスク スナップショットを判別します。
cloud-init.yaml
ファイルを作成します。このファイルは、PITR データベースを実行するコンテナ用に最適化されたストレージ VM に提供されます。cloud-init.yaml
ファイルは構成ファイルを作成し、いくつかのシステム コマンドを実行して次の環境を確立します。- WAL セグメント ファイルのアーカイブ バケットをボリュームとしてマウントする
gcsfuse
コンテナ。これは、Docker バインド マウントでホストに公開されます。 データベース エンジンが次を実行する
postgres-db
コンテナ。- 永続ディスクがボリュームとして接続されているホスト ファイル システム。
- Cloud Storage バケットがボリュームとして接続されているホスト ファイル システム。
PostgreSQL データ ディレクトリにある
recovery.conf
リカバリ ファイル。次の情報が含まれています。- ターゲットの日付。
restore
コマンド。データベースが必要に応じてアーカイブ ファイル システムから WAL セグメント ファイルをコピーするために使用するパラメータ化されたコピーコマンド。%f
はセグメント ファイルであり、%p
はデータベースが復元中にファイルを処理するために使用するパスです。
archive_
の設定は、WAL アーカイブ ディレクトリが破損しないように、postgresql.conf
設定ファイルからコメントアウトされます。
- WAL セグメント ファイルのアーカイブ バケットをボリュームとしてマウントする
次の情報を使用して、PITR インスタンスを起動します。
$PG_INSTANCE_NAME
環境変数と、$PIT_RECOVERY_TARGET
環境変数の英数字の値を組み合わせて作成された名前。- 以前に識別されたディスク スナップショットから作成された永続ディスク。
recovery.conf
ファイルの例を次に示します。
restore_command = '(test -d /var/lib/postgresql/wal/pg_wal_recover && cp /var/lib/postgresql/wal/pg_wal_recover/%f %p ) '
recovery_target_time='YYYY-MM-DD HH:MM:SS UTC'
recovery_target_inclusive=true
復元を検証する
Google Cloud コンソールで [VM インスタンス] ページに移動します。
instance-pg-pitr-YYYYMMDDHHMMSS
インスタンスの [SSH] をクリックします。SSH ターミナルで、Docker コンテナの PostgreSQL ターミナルベースのフロントエンドを実行します。
docker exec -it postgres-db psql --dbname=pitr_demo
次のエラーが発生した場合は、PostgreSQL コンテナが起動するまで待ち、コマンドを再実行します。
Error: No such container: postgres-db
顧客テーブルのデータを確認します。
SELECT * FROM pitr_db_schema.customer WHERE id > (SELECT MAX(id)-10 FROM pitr_db_schema.customer);
出力は次のようになります。
id | name | create_timestamp ------+---------------------------+---------------------------- 711 | customer_name_from_golang | 2019-12-06 18:03:51.229444 712 | customer_name_from_golang | 2019-12-06 18:03:52.531755 713 | customer_name_from_golang | 2019-12-06 18:03:53.555441 714 | customer_name_from_golang | 2019-12-06 18:03:54.581872 715 | customer_name_from_golang | 2019-12-06 18:03:55.607459 716 | customer_name_from_golang | 2019-12-06 18:03:56.633362 717 | customer_name_from_golang | 2019-12-06 18:03:57.658523 718 | customer_name_from_golang | 2019-12-06 18:03:58.685469 719 | customer_name_from_golang | 2019-12-06 18:03:59.706939
名前は、トランザクション生成ツールによって作成された値を示します。最後の行のタイムスタンプは、復元ターゲット(環境変数で復元スクリプトに指定したもの)よりも前に設定されています。復元するレコードの数によっては、すべての行が更新されるまでしばらく待つ必要があります。
クリーンアップ
課金を停止する最も簡単な方法は、チュートリアル用に作成した Google Cloud プロジェクトを削除することです。また、リソースを個別に削除することもできます。
プロジェクトを削除する
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
次のステップ
- コンテナ用に最適化されたオペレーティング システムの詳細を確認する。
- cloud-init の詳細を確認する。
- Cloud Storage Fuse の詳細を確認する。
- Google Cloud に関するリファレンス アーキテクチャ、図、ベスト プラクティスを確認する。Cloud アーキテクチャ センターを確認する。