1. はじめに
この Codelab では、RPM オーケストレーターを使用して、AlloyDB Omni の高可用性(HA)クラスタを S3 互換のオブジェクト ストレージにバックアップします。
この Codelab では、Codelab RPM オーケストレーターを使用して GCE VM に AlloyDB Omni 高可用性クラスタをデプロイするのクラスタを使用して、Compute Engine 仮想マシン(VM)に HA クラスタを作成します。この Codelab では、VM の 1 つに S3 互換のオブジェクト ストレージ サーバーを追加します。オブジェクト ストレージ サーバーを HA クラスタに使用して、データをバックアップし、サーバーからクラスタを復元します。

前提条件
- 課金を有効にした Google Cloud プロジェクト
- HA の Codelab に記載されている IAM ロール。
- Linux コマンドと SQL の基本的な知識があること。
学習内容
- バックアップ用の S3 互換オブジェクト ストレージ サーバーをインストールして実行する方法。
- バックアップを S3 互換ストレージに書き込むバックアップ プランを作成する方法。
- オンデマンド バックアップを作成する方法。
- バックアップから特定の時点にクラスタを復元する方法。
必要なもの
- AlloyDB Omni ソフトウェア リポジトリとオーケストレーター Ansible コレクションの URL。URL を受け取るには、AlloyDB Omni 登録フォームに記入してください。詳細については、RPM を使用する AlloyDB Omni の概要をご覧ください。これらの URL は、HA Codelab で使用します。
- RPM オーケストレーターを使用して GCE VM に AlloyDB Omni 高可用性クラスタをデプロイする Codelab の AlloyDB Omni HA クラスタ。
- Google Cloud と Cloud Shell にアクセスできるターミナル。
2. 設定と要件
- このステップでは、Codelab の RPM オーケストレーターを使用して GCE VM に AlloyDB Omni 高可用性クラスタをデプロイするを使用して HA クラスタを作成します。次の手順を行います。Codelab のクラスタがすでにある場合は、次のステップに進みます。
- 注: この段階では、「リソースをクリーンアップする」の手順は実行しないでください。この手順は、この Codelab の最後で行います。
- この Codelab に戻る
3. クラスタに接続してサンプルデータを追加する
この手順では、クラスタ設定を制御 VM に読み込みます。次に、クラスタに接続して、サンプルデータを含むテーブルを追加します。
- 制御 VM に接続していない場合は、Cloud Shell から接続します。
gcloud compute ssh "$CLUSTER-control" --zone="$ZONE" --project="$PROJECT"CLUSTER、ZONE、PROJECTの各変数は、RPM オーケストレーターを使用して GCE VM に AlloyDB Omni 高可用性クラスタをデプロイする Codelab のデプロイ用に VM を準備するの手順で取得します。Cloud Shell にこれらの変数がない場合は、再度設定します。 - 制御 VM で、ホーム ディレクトリに移動して環境変数を読み込みます。次に、クラスタ名と SSH ユーザーを環境ファイルに追加します。
出力にcd ~ source /tmp/cluster.conf cat >> ~/.codelab.env <<EOF export CLUSTER="$cluster" export SSH_USER="$service_account" EOF source ~/.codelab.env env | grep -E '^(CLUSTER|SSH_USER|VIRTUAL_IP)='CLUSTER、SSH_USER、VIRTUAL_IPが表示されていることを確認します。注: 後で制御 VM に再度接続する場合は、続行する前にcd ~とsource ~/.codelab.envを実行します。 - 環境ファイルに接続設定を追加します。
readコマンドでパスワードを求められたら、postgresユーザーのパスワードを入力します。このパスワードは、RPM オーケストレーターを使用して GCE VM に AlloyDB Omni 高可用性クラスタをデプロイする Codelab の AlloyDB Omni クラスタをブートストラップするの手順で設定します。cat >> ~/.codelab.env <<'EOF' export PATH="/usr/pgsql-18/bin:$PATH" export PGHOST="$VIRTUAL_IP" export PGUSER="postgres" EOF read -rsp "Password of the postgres user: " PGPASSWORD; echo printf 'export PGPASSWORD=%q\n' "$PGPASSWORD" >> ~/.codelab.env source ~/.codelab.env env | grep -E '^(PGHOST|PGUSER|PGPASSWORD)=' - テーブルを作成して 1,000 行を追加します。
psql <<'SQL' CREATE TABLE public.orders ( id integer PRIMARY KEY, item text NOT NULL, created_at timestamptz NOT NULL DEFAULT pg_catalog.now() ); INSERT INTO public.orders (id, item) SELECT g, 'item-' || g FROM pg_catalog.generate_series(1, 1000) AS g; SQL - 行数をカウントします。
出力がpsql -c "SELECT pg_catalog.count(*) FROM public.orders;"1000を返すことを確認します。
4. S3 互換のオブジェクト ストレージをインストールして実行する
この手順では、制御 VM に MinIO サーバーをインストールする Ansible Playbook を作成します。このプレイブックでは、バックアップ用のバケットとユーザーも作成し、データベース VM が MinIO に接続できることを確認します。この手順のコマンドはすべて、コントロール VM で実行します。
- 制御 VM で、ストレージ設定を環境ファイルに追加します。
opensslコマンドはランダムなパスワードを作成します。 出力に、コントロール VM の名前と内部 IP アドレス(例:MD=http://metadata.google.internal/computeMetadata/v1/instance S3_IP=$(curl -s -H "Metadata-Flavor: Google" "$MD/network-interfaces/0/ip") cat >> ~/.codelab.env <<EOF export S3_IP="$S3_IP" export S3_HOST="$CLUSTER-control" export S3_BUCKET="alloydb-backups" export S3_REGION="us-east-1" export MINIO_ROOT_USER="s3admin" export MINIO_ROOT_PASSWORD="$(openssl rand -hex 16)" export S3_ACCESS_KEY_ID="alloydb-backup" export S3_SECRET_ACCESS_KEY="$(openssl rand -hex 16)" export MINIO_URL="https://github.com/minio/minio/releases/download/RELEASE.2024-05-10T01-41-38Z/minio.linux-amd64.RELEASE.2024-05-10T01-41-38Z" export MC_URL="https://github.com/minio/mc/releases/download/RELEASE.2024-05-09T17-04-24Z/mc.linux-amd64.RELEASE.2024-05-09T17-04-24Z" EOF source ~/.codelab.env echo "$S3_HOST $S3_IP"my-cluster-control 10.1.0.2)が表示されていることを確認します。データベース VM は、このホスト名と IP アドレスを使用して MinIO に接続します。VM のメタデータ サーバーが IP アドレスを付与します。詳細については、VM メタデータのドキュメントをご覧ください。MINIO_URLとMC_URLの値は、MinIO サーバーと MinIO クライアント(mc)のダウンロード URL です。 - 必要な
community.cryptoAnsible コレクションを制御 VM にインストールします。ansible-galaxy collection install community.crypto s3_server.yamlハンドブックを作成します。cat > s3_server.yaml <<EOF - name: Install and run MinIO on the control VM hosts: localhost connection: local become: true gather_facts: false tasks: - name: Create MinIO directories ansible.builtin.file: path: "{{ item }}" state: directory mode: "0755" loop: - /var/lib/minio/data - /var/lib/minio/certs - name: Download MinIO server and client ansible.builtin.get_url: url: "{{ item.url }}" dest: "{{ item.dest }}" mode: "0755" loop: - url: "$MINIO_URL" dest: /usr/local/bin/minio - url: "$MC_URL" dest: /usr/local/bin/mc - name: Generate MinIO TLS private key community.crypto.openssl_privatekey: path: /var/lib/minio/certs/private.key size: 2048 mode: "0600" - name: Generate MinIO certificate signing request community.crypto.openssl_csr_pipe: privatekey_path: /var/lib/minio/certs/private.key common_name: "$S3_HOST" subject_alt_name: - "DNS:$S3_HOST" - "DNS:$S3_BUCKET.$S3_HOST" - "DNS:localhost" - "IP:127.0.0.1" - "IP:$S3_IP" register: minio_csr - name: Generate self-signed MinIO TLS certificate community.crypto.x509_certificate: path: /var/lib/minio/certs/public.crt csr_content: "{{ minio_csr.csr }}" privatekey_path: /var/lib/minio/certs/private.key provider: selfsigned selfsigned_not_after: "+365d" mode: "0644" - name: Create MinIO systemd service unit ansible.builtin.copy: dest: /etc/systemd/system/minio.service mode: "0600" content: | [Unit] Description=MinIO Object Storage After=network.target [Service] Environment="MINIO_ROOT_USER=$MINIO_ROOT_USER" Environment="MINIO_ROOT_PASSWORD=$MINIO_ROOT_PASSWORD" Environment="MINIO_DOMAIN=$S3_HOST" ExecStart=/usr/local/bin/minio server /var/lib/minio/data --certs-dir /var/lib/minio/certs Restart=on-failure [Install] WantedBy=multi-user.target - name: Start and enable MinIO service ansible.builtin.systemd_service: name: minio daemon_reload: true state: started enabled: true - name: Add storage host names to /etc/hosts on the control VM ansible.builtin.lineinfile: path: /etc/hosts line: "$S3_IP $S3_HOST $S3_BUCKET.$S3_HOST" state: present - name: Wait for MinIO health endpoint ansible.builtin.uri: url: "https://$S3_HOST:9000/minio/health/live" ca_path: /var/lib/minio/certs/public.crt status_code: 200 register: minio_health until: minio_health.status == 200 retries: 6 delay: 5 - name: Create backup bucket and user in MinIO ansible.builtin.command: argv: "{{ item }}" loop: - - /usr/local/bin/mc - --insecure - alias - set - s3repo - "https://$S3_HOST:9000" - "$MINIO_ROOT_USER" - "$MINIO_ROOT_PASSWORD" - - /usr/local/bin/mc - --insecure - mb - --ignore-existing - "s3repo/$S3_BUCKET" - - /usr/local/bin/mc - --insecure - admin - user - add - s3repo - "$S3_ACCESS_KEY_ID" - "$S3_SECRET_ACCESS_KEY" - - /usr/local/bin/mc - --insecure - admin - policy - attach - s3repo - readwrite - --user - "$S3_ACCESS_KEY_ID" become: false no_log: true - name: Configure database VMs for MinIO hosts: primary_instance_nodes become: true gather_facts: false vars: ansible_user: $SSH_USER ansible_ssh_private_key_file: $HOME/ssh-key-cluster-sa tasks: - name: Set SELinux to permissive mode ansible.builtin.command: cmd: setenforce 0 - name: Add storage host names to /etc/hosts ansible.builtin.lineinfile: path: /etc/hosts line: "$S3_IP $S3_HOST $S3_BUCKET.$S3_HOST" state: present - name: Verify storage host resolution ansible.builtin.getent: database: hosts key: "$S3_BUCKET.$S3_HOST" - name: Verify connection to MinIO ansible.builtin.uri: url: "https://$S3_HOST:9000/minio/health/live" validate_certs: false status_code: 200 EOFMINIO_DOMAIN変数を使用すると、MinIO は仮想ホスト型のリクエストを受け入れることができます。RPM オーケストレーターは、alloydb-backupユーザーを使用してバックアップを書き込みます。readwriteポリシーは、MinIO の組み込みポリシーです。- ハンドブックを実行します。
ansible-playbook s3_server.yaml -i deployment_spec.yamlPLAY RECAP出力に、localhostと各データベース VM のfailed=0が表示されていることを確認します。 - バケットが存在することを確認します。
出力にmc --insecure ls s3repoalloydb-backups/バケットが表示されていることを確認します。
5. バックアップ プランを作成する
バックアップ プランには、クラスタのバックアップの保存場所、スケジュール、保持期間が含まれます。この手順では、MinIO バケットのバックアップ プランを作成します。
- 制御 VM で、バックアップ ハンドブックとステータス ハンドブックを作成します。
Secret、BackupPlan、Backupリソースにはバックアップ ハンドブックを使用します。ステータス ハンドブックを使用して、リソースのステータスを表示します。cat > backup.yaml <<EOF - name: Manage AlloyDB Omni backups hosts: localhost roles: - role: google.alloydbomni_orchestrator.backup EOF cat > status.yaml <<EOF - name: Get resource status hosts: localhost roles: - role: google.alloydbomni_orchestrator.status EOF - S3 認証情報用の
Secretリソースを作成します。リソースを適用します。S3_KEY_ID_B64=$(printf '%s' "$S3_ACCESS_KEY_ID" | base64 -w 0) S3_KEY_B64=$(printf '%s' "$S3_SECRET_ACCESS_KEY" | base64 -w 0) cat > s3_secret.yaml <<EOF Secret: metadata: name: s3-backup-secret spec: type: Opaque data: access-key-id: "$S3_KEY_ID_B64" access-key: "$S3_KEY_B64" EOF ansible-playbook backup.yaml -i deployment_spec.yaml \ -e resource_spec=s3_secret.yamldataセクションのキー名はaccess-key-idとaccess-keyにする必要があります。BackupPlanリソースを適用する前に、Secretリソースを適用する必要があります。 BackupPlanリソースを作成して適用します。cat > backup_plan.yaml <<EOF BackupPlan: metadata: name: s3-backup-plan spec: dbclusterRef: $CLUSTER backupLocation: type: S3 s3Options: bucket: $S3_BUCKET key: /backups endpoint: https://$S3_HOST:9000 region: $S3_REGION secretRef: name: s3-backup-secret caBundle: - | $(sed 's/^/ /' /var/lib/minio/certs/public.crt) EOF ansible-playbook backup.yaml -i deployment_spec.yaml \ -e resource_spec=backup_plan.yamlkey値は、バケット内のバックアップのパスです。このパスはスラッシュ(/)で始まる必要があります。caBundleフィールドには、S3 ストレージ サーバーの証明書を検証する PEM エンコードされた CA 証明書が含まれています。- バックアップ プランの準備ができていることを確認します。
ansible-playbook status.yaml -i deployment_spec.yaml \ -e resource_type=BackupPlan -e resource_name=s3-backup-planphaseフィールドにReadyが表示されていることを確認します。フェーズがReadyでない場合は、1 分待ってからコマンドを再度実行します。 - バックアップ プランが作成されると、RPM オーケストレーターが最初のフル バックアップを自動的に開始します。オンデマンド バックアップを作成する前に、この初期バックアップが完了していることを確認します。
初期バックアップ フェーズが成功したことを確認します。ansible-playbook status.yaml -i deployment_spec.yaml \ -e resource_type=Backup
6. オンデマンド バックアップを作成する
このステップでは、クラスタのオンデマンド バックアップを作成します。
- コントロール VM で、
Backupリソースを作成します。リソースを適用します。cat > create_backup.yaml <<EOF Backup: metadata: name: s3-backup-1 spec: backupPlanRef: s3-backup-plan dbclusterRef: $CLUSTER EOF ansible-playbook backup.yaml -i deployment_spec.yaml \ -e resource_spec=create_backup.yamlbackupPlanRefフィールドは、バックアップ プランの名前です。dbclusterRefフィールドはクラスタの名前です。 - バックアップが完了したことを確認します。
ansible-playbook status.yaml -i deployment_spec.yaml \ -e resource_type=Backup -e resource_name=s3-backup-1phaseフィールドにSucceededが表示されていることを確認します。フェーズがSucceededでない場合は、1 分待ってからコマンドを再度実行します。 - バックアップ ファイルがバケットにあることを確認します。
出力にmc --insecure tree "s3repo/$S3_BUCKET"dbフォルダを含むbackupフォルダが表示されていることを確認します。
7. バックアップからクラスタを復元する
RPM オーケストレーターは、クラスタをインプレースで復元します。このステップでは、テーブルを削除してバックアップから復元します。必要に応じて、クラスタを特定の時点に復元できます。
注意: 復元オペレーションは、データベース クラスタ内のすべてのデータを上書きします。
バックアップから復元する
- 制御 VM で、
ordersテーブルを削除します。次に、行数をカウントします。 2 番目のコマンドがエラーで失敗することを確認します。エラー メッセージは、リレーションが存在しないことを示しています。例: 「ERROR: table "orders" does not exist」psql -c "DROP TABLE public.orders;" psql -c "SELECT pg_catalog.count(*) FROM public.orders;" - 復元ハンドブックを作成します。
cat > restore.yaml <<EOF - name: Restore AlloyDB Omni cluster hosts: localhost roles: - role: google.alloydbomni_orchestrator.restore EOF s3-backup-1バックアップのRestoreリソースを作成します。リソースを適用します。cat > restore_backup.yaml <<EOF Restore: metadata: name: s3-restore-1 spec: sourceDBCluster: $CLUSTER backup: s3-backup-1 EOF ansible-playbook restore.yaml -i deployment_spec.yaml \ -e resource_spec=restore_backup.yaml- 復元オペレーションが完了していることを確認します。
ansible-playbook status.yaml -i deployment_spec.yaml \ -e resource_type=Restore -e resource_name=s3-restore-1phaseフィールドにProvisionSucceededが表示されていることを確認します。フェーズがProvisionSucceededでない場合は、1 分待ってからコマンドを再度実行します。 - 復元されたテーブルの行数をカウントします。
出力にpsql -c "SELECT pg_catalog.count(*) FROM public.orders;"1000が表示されていることを確認します。
(省略可)特定の時点に復元する
ポイントインタイム復元では、バックアップとアーカイブされた write-ahead log(WAL)を使用します。クラスタは、バックアップ プランの復元ウィンドウ内の任意の時点に復元できます。
目標時間のルール
目標時間の値と形式を選択するには、次のすべてのルールに従う必要があります。
- UTC で RFC 3339 形式を使用します(
YYYY-MM-DDThh:mm:ssZ)。たとえば、2026-06-19T14:30:00Zは 2026 年 6 月 19 日の 14:30:00 UTC です。日付と時刻は文字Tで区切ります。文字Zは UTC を示します。 - 過去の時刻を使用します。
BackupPlanCRD のrecoveryWindowフィールドのbegin値より後の時間を使用します。
現在の時刻を RFC 3339 形式で表示するには、次のコマンドを実行します。
date -u +%Y-%m-%dT%H:%M:%SZ
ローカル時間をこの形式に変更するには、ローカル時間の UTC オフセットを date コマンドに追加します。たとえば、次のコマンドは UTC+02:00 の 19 June 2026 で 16:30:00 を変更します。
date -u -d "2026-06-19 16:30:00 +0200" +%Y-%m-%dT%H:%M:%SZ
このコマンドは 2026-06-19T14:30:00Z を返します。
記録された時間に復元する
この手順では、テーブルに行を追加して時間を記録します。時間を記録すると、データベースが完全に無傷(1,500 行)の瞬間のブックマークが作成されます。次に、行を削除し、クラスタを記録した時間に復元します。
- テーブルに 500 行を追加します。
psql <<'SQL' INSERT INTO public.orders (id, item) SELECT g, 'item-' || g FROM pg_catalog.generate_series(1001, 1500) AS g; SQL - 時間を記録します。この時点でのテーブルの行数は 1,500 です。
出力にsleep 5 PITR_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ) echo "export PITR_TIME=$PITR_TIME" >> ~/.codelab.env echo "$PITR_TIME" sleep 5YYYY-MM-DDThh:mm:ssZ形式(例:2026-10-05T11:16:02Z)で時刻が表示されていることを確認します。 - テーブルから行を削除して、誤ってデータを削除した状態をシミュレートします。次に、新しい WAL ファイルを開始します。
psql -c "DELETE FROM public.orders WHERE id > 1000;" psql -c "SELECT pg_catalog.count(*) FROM public.orders;" psql -c "SELECT pg_catalog.pg_switch_wal();"countクエリに1000が表示されていることを確認します。pg_switch_wal関数は、サーバーに新しい WAL ファイルを開始させます。その後、サーバーは変更を含む WAL ファイルをアーカイブできます。 - バックアップ プランの復元ウィンドウに記録された時間が含まれていることを確認します。
test -n "$PITR_TIME" || { echo "PITR_TIME is not set. Run step 2 again."; exit 1; } echo "$PITR_TIME" ansible-playbook status.yaml -i deployment_spec.yaml \ -e resource_type=BackupPlan -e resource_name=s3-backup-planPITR_TIMEの値がrecoveryWindowフィールドのbeginの値の後にあることを確認します。 - 記録された時間の
Restoreリソースを作成します。リソースを適用します。cat > restore_pitr.yaml <<EOF Restore: metadata: name: s3-restore-pitr spec: sourceDBCluster: $CLUSTER pointInTime: "$PITR_TIME" EOF ansible-playbook restore.yaml -i deployment_spec.yaml \ -e resource_spec=restore_pitr.yaml - 復元オペレーションが完了していることを確認します。
ansible-playbook status.yaml -i deployment_spec.yaml \ -e resource_type=Restore -e resource_name=s3-restore-pitrphaseフィールドにProvisionSucceededが表示されていることを確認します。フェーズがProvisionSucceededでない場合は、1 分待ってからコマンドを再度実行します。 - 行数をカウントします。
出力にpsql -c "SELECT pg_catalog.count(*) FROM public.orders;"1500が表示されていることを確認します。
8. クリーンアップ
Google Cloud アカウントに課金されないようにするには、この Codelab のリソースと RPM Orchestrator を使用して GCE VM に AlloyDB Omni 高可用性クラスタをデプロイする Codelab のリソースを削除します。まずバックアップ リソースを削除してから、クラスタとコンピューティング環境を削除します。
- 制御 VM で、削除プレイブックを作成します。
cat > delete.yaml <<EOF - name: Delete AlloyDB Omni resources hosts: localhost roles: - role: google.alloydbomni_orchestrator.delete EOF - バックアップを一覧表示します。
出力にansible-playbook status.yaml -i deployment_spec.yaml -e resource_type=Backups3-backup-1バックアップが表示されていることを確認します。 s3-backup-1バックアップを削除します。ansible-playbook delete.yaml -i deployment_spec.yaml \ -e resource_type=Backup -e resource_name=s3-backup-1- バックアップ プランを削除します。
ansible-playbook delete.yaml -i deployment_spec.yaml \ -e resource_type=BackupPlan -e resource_name=s3-backup-plan - RPM オーケストレーターを使用して GCE VM に AlloyDB Omni 高可用性クラスタをデプロイする Codelab のリソースをクリーンアップするの手順に沿って、クラスタとコンピューティング環境を削除します。MinIO サーバーとそのバックアップは、制御 VM にあります。コンピューティング環境を削除すると、サーバーとバックアップの両方が削除されます。
9. 完了
これで操作は完了です。RPM オーケストレーターを使用して、AlloyDB Omni の高可用性(HA)クラスタを S3 互換のオブジェクト ストレージにバックアップしました。その後、バックアップからクラスタを復元しました。
学習した内容
- MinIO を S3 互換のオブジェクト ストレージとしてインストールして実行する方法。
- バックアップ プランとオンデマンド バックアップを作成する方法。
- バックアップから特定の時点にクラスタを復元する方法。
詳しくは次のページをご覧ください。