1. Introducción
En este codelab, crearás una copia de seguridad de un clúster de alta disponibilidad (HA) en un almacén de objetos compatible con S3 para AlloyDB Omni con el organizador de RPM.
En este codelab, se usa el clúster del codelab Implementa un clúster de alta disponibilidad de AlloyDB Omni en VMs de GCE con el organizador de RPM para crear un clúster de HA en máquinas virtuales (VM) de Compute Engine. En este codelab, agregarás un servidor de almacenamiento de objetos compatible con S3 en una de las VMs. Usas el servidor de almacenamiento de objetos para el clúster de HA para hacer copias de seguridad de los datos y restablecer el clúster desde el servidor.

Requisitos previos
- Un proyecto de Google Cloud con facturación habilitada.
- Los roles de IAM que se enumeran en el codelab de HA
- Conocimientos básicos de los comandos de Linux y SQL
Qué aprenderás
- Cómo instalar y ejecutar un servidor de almacén de objetos compatible con S3 para copias de seguridad
- Cómo crear un plan de copias de seguridad que escriba copias de seguridad en un almacenamiento compatible con S3
- Cómo crear una copia de seguridad a pedido
- Cómo restablecer un clúster a partir de una copia de seguridad y a un momento determinado
Requisitos
- Son las URLs de los repositorios de software de AlloyDB Omni y de la colección de Ansible del organizador. Para recibir las URLs, completa el formulario de registro de AlloyDB Omni. Para obtener más información, consulta la descripción general de AlloyDB Omni con RPM. Usarás las URLs en el codelab de HA.
- Un clúster de HA de AlloyDB Omni del codelab Implementa un clúster de alta disponibilidad de AlloyDB Omni en VMs de GCE con el organizador de RPM
- Una terminal con acceso a Google Cloud y a Cloud Shell
2. Configuración y requisitos
- En este paso, crearás un clúster de HA con el codelab Implementa un clúster de alta disponibilidad de AlloyDB Omni en VMs de GCE con el organizador de RPM. Completa los siguientes pasos. Si ya tienes un clúster del codelab, continúa con el siguiente paso.
- Nota: No ejecutes el paso "Limpiar recursos" en esta etapa. Realizarás ese paso al final de este codelab.
- Regresa a este codelab
3. Conéctate al clúster y agrega datos de muestra
En este paso, cargarás la configuración del clúster en la VM de control. Luego, te conectarás al clúster y agregarás una tabla con datos de muestra.
- Si no estás conectado a la VM de control, conéctate a ella desde Cloud Shell:
Las variablesgcloud compute ssh "$CLUSTER-control" --zone="$ZONE" --project="$PROJECT"CLUSTER,ZONEyPROJECTprovienen del paso Prepara las VMs para la implementación del codelab Implementa un clúster de alta disponibilidad de AlloyDB Omni en VMs de GCE con el organizador de RPM. Si Cloud Shell no tiene estas variables, vuelve a configurarlas. - En la VM de control, cambia a tu directorio principal y carga las variables de entorno. Luego, agrega el nombre del clúster y el usuario de SSH al archivo de entorno:
Verifica que el resultado muestrecd ~ 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_USERyVIRTUAL_IP. Nota: Si te vuelves a conectar a la VM de control más adelante, ejecutacd ~ysource ~/.codelab.envantes de continuar. - Agrega la configuración de conexión al archivo de entorno. Cuando el comando
readsolicite la contraseña, ingresa la del usuariopostgres. Establece esta contraseña en el paso Bootstrap AlloyDB Omni Cluster del codelab Deploy AlloyDB Omni high availability cluster on GCE VMs using RPM Orchestrator.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)=' - Crea una tabla y agrega 1,000 filas:
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 - Cuenta las filas:
Verifica que el resultado muestrepsql -c "SELECT pg_catalog.count(*) FROM public.orders;"1000.
4. Instala y ejecuta el almacén de objetos compatible con S3
En este paso, escribirás un playbook de Ansible que instalará un servidor de MinIO en la VM de control. El playbook también crea el bucket y el usuario para las copias de seguridad, y se asegura de que las VMs de la base de datos puedan conectarse a MinIO. Ejecuta todos los comandos de este paso en la VM de control.
- En la VM de control, agrega la configuración de almacenamiento al archivo de entorno. Los comandos
opensslgeneran contraseñas aleatorias. Asegúrate de que el resultado muestre el nombre y la dirección IP interna de la VM de control, por ejemplo,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. Las VMs de la base de datos usan este nombre de host y dirección IP para conectarse a MinIO. El servidor de metadatos de la VM proporciona la dirección IP. Para obtener más información, consulta la documentación de metadatos de VM.Los valoresMINIO_URLyMC_URLson las URLs de descarga del servidor de MinIO y del cliente de MinIO (mc). - Instala la colección de
community.cryptoAnsible requerida en la VM de control:ansible-galaxy collection install community.crypto - Crea la guía
s3_server.yaml: La variablecat > 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_DOMAINpermite que MinIO acepte solicitudes de estilo de host virtual. El organizador de RPM usa el usuarioalloydb-backuppara escribir las copias de seguridad. La políticareadwritees una política integrada de MinIO. - Ejecuta la guía:
Verifica que el resultado deansible-playbook s3_server.yaml -i deployment_spec.yamlPLAY RECAPmuestrefailed=0paralocalhosty para cada VM de la base de datos. - Verifica que el bucket exista:
Verifica que el resultado muestre el bucketmc --insecure ls s3repoalloydb-backups/.
5. Crear un plan de creación de copias de seguridad
Un plan de copias de seguridad contiene la ubicación de almacenamiento, la programación y el período de retención de las copias de seguridad de un clúster. En este paso, crearás un plan de copias de seguridad para el bucket de MinIO.
- En la VM de control, crea el playbook de copia de seguridad y el playbook de estado. Usas la guía de copias de seguridad para los recursos
Secret,BackupPlanyBackup. Usas la guía de estado para mostrar el estado de un recurso.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 - Crea un recurso
Secretpara las credenciales de S3. Luego, aplica el recurso: Los nombres de las claves en la secciónS3_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.yamldatadeben seraccess-key-idyaccess-key. Debes aplicar el recursoSecretantes de aplicar el recursoBackupPlan. - Crea el recurso
BackupPlany, luego, aplícalo: El valor decat > 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.yamlkeyes la ruta de acceso para las copias de seguridad en el bucket. Esta ruta debe comenzar con una barra (/). El campocaBundlecontiene el certificado de la AC con codificación PEM que valida el certificado del servidor de almacenamiento de S3. - Verifica que el plan de copias de seguridad esté listo:
Verifica que el campoansible-playbook status.yaml -i deployment_spec.yaml \ -e resource_type=BackupPlan -e resource_name=s3-backup-planphasemuestreReady. Si la fase no esReady, espera un minuto y vuelve a ejecutar el comando. - Cuando se crea un plan de copia de seguridad, el orquestador de RPM inicia automáticamente una copia de seguridad completa inicial. Verifica que se complete esta copia de seguridad inicial antes de crear una copia de seguridad a pedido:
Verifica que la fase inicial de la copia de seguridad se complete correctamente.ansible-playbook status.yaml -i deployment_spec.yaml \ -e resource_type=Backup
6. Crea una copia de seguridad según demanda
En este paso, crearás una copia de seguridad a pedido del clúster.
- En la VM de control, crea el recurso
Backup. Luego, aplica el recurso: El campocat > 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.yamlbackupPlanRefes el nombre del plan de copias de seguridad. El campodbclusterRefes el nombre del clúster. - Verifica que se haya completado la copia de seguridad:
Verifica que el campoansible-playbook status.yaml -i deployment_spec.yaml \ -e resource_type=Backup -e resource_name=s3-backup-1phasemuestreSucceeded. Si la fase no esSucceeded, espera un minuto y vuelve a ejecutar el comando. - Verifica que los archivos de copia de seguridad estén en el bucket:
Verifica que el resultado muestre una carpetamc --insecure tree "s3repo/$S3_BUCKET"backupque contenga una carpetadb.
7. Restablece el clúster a partir de una copia de seguridad
El organizador de RPM restablece un clúster en su lugar. En este paso, borrarás una tabla y la restablecerás desde la copia de seguridad. Luego, puedes restablecer el clúster a un momento determinado de forma opcional.
Precaución: Una operación de restablecimiento reemplaza todos los datos del clúster de la base de datos.
Restablecer copia de seguridad
- En la VM de control, borra la tabla
orders. Luego, cuenta las filas: Verifica que el segundo comando falle con un error. El mensaje de error muestra que la relación no existe. Por ejemplo, "ERROR: table "orders" does not exist"psql -c "DROP TABLE public.orders;" psql -c "SELECT pg_catalog.count(*) FROM public.orders;" - Crea la guía de restablecimiento:
cat > restore.yaml <<EOF - name: Restore AlloyDB Omni cluster hosts: localhost roles: - role: google.alloydbomni_orchestrator.restore EOF - Crea un recurso
Restorepara la copia de seguridad des3-backup-1. Luego, aplica el recurso: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 - Verifica que la operación de restablecimiento se haya completado:
Verifica que el campoansible-playbook status.yaml -i deployment_spec.yaml \ -e resource_type=Restore -e resource_name=s3-restore-1phasemuestreProvisionSucceeded. Si la fase no esProvisionSucceeded, espera un minuto y vuelve a ejecutar el comando. - Cuenta las filas de la tabla restaurada:
Verifica que el resultado muestrepsql -c "SELECT pg_catalog.count(*) FROM public.orders;"1000.
(Opcional) Restablece a un momento determinado
El restablecimiento a un momento determinado usa una copia de seguridad y el registro de escritura anticipada (WAL) archivado. Puedes restablecer el clúster a cualquier momento dentro del período de recuperación del plan de copia de seguridad.
Reglas para la hora objetivo
Debes seguir todas las reglas para elegir el valor y el formato de la hora objetivo:
- Usa el formato RFC 3339 en UTC:
YYYY-MM-DDThh:mm:ssZ. Por ejemplo,2026-06-19T14:30:00Zes el 19 de junio de 2026 a las 14:30:00 UTC. La letraTsepara la fecha y la hora. La letraZmuestra la hora UTC. - Usa una fecha y hora del pasado.
- Usa una hora posterior al valor
begindel camporecoveryWindowdel CRDBackupPlan.
Para mostrar la hora actual en formato RFC 3339, ejecuta este comando:
date -u +%Y-%m-%dT%H:%M:%SZ
Para cambiar una hora local a este formato, agrega el desplazamiento de UTC de la hora local al comando date. Por ejemplo, el siguiente comando cambia 16:30:00 en 19 June 2026 a las UTC+02:00:
date -u -d "2026-06-19 16:30:00 +0200" +%Y-%m-%dT%H:%M:%SZ
El comando devuelve 2026-06-19T14:30:00Z.
Cómo restablecer a un momento grabado
En este procedimiento, agregarás filas a la tabla y registrarás un tiempo. Cuando registras un momento, marcas el instante exacto en el que la base de datos está completamente intacta (con exactamente 1,500 filas).Luego, borras filas y restableces el clúster al momento registrado.
- Agrega 500 filas a la tabla:
psql <<'SQL' INSERT INTO public.orders (id, item) SELECT g, 'item-' || g FROM pg_catalog.generate_series(1001, 1500) AS g; SQL - Registra el tiempo. En este momento, la tabla tiene 1,500 filas.
Verifica que el resultado muestre una hora en el formatosleep 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, por ejemplo,2026-10-05T11:16:02Z. - Borra filas de la tabla para simular una eliminación accidental de datos. Luego, inicia un nuevo archivo del WAL:
Verifica que la búsquedapsql -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();"countmuestre1000. La funciónpg_switch_walhace que el servidor inicie un nuevo archivo del WAL. Luego, el servidor puede archivar el archivo WAL que contiene tus cambios. - Verifica que la ventana de recuperación del plan de copias de seguridad contenga la hora registrada:
Verifica que el valor detest -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_TIMEsea posterior al valor debegindel camporecoveryWindow. - Crea un recurso
Restorepara el tiempo registrado. Luego, aplica el recurso: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 - Verifica que la operación de restablecimiento se haya completado:
Verifica que el campoansible-playbook status.yaml -i deployment_spec.yaml \ -e resource_type=Restore -e resource_name=s3-restore-pitrphasemuestreProvisionSucceeded. Si la fase no esProvisionSucceeded, espera un minuto y vuelve a ejecutar el comando. - Cuenta las filas:
Verifica que el resultado muestrepsql -c "SELECT pg_catalog.count(*) FROM public.orders;"1500.
8. Limpieza
Para evitar que se apliquen cargos a tu cuenta de Google Cloud, borra los recursos de este codelab y del codelab Deploy AlloyDB Omni high availability cluster on GCE VMs using RPM Orchestrator. Primero, borra los recursos de copia de seguridad y, luego, borra el clúster y el entorno de procesamiento.
- En la VM de control, crea el playbook de eliminación:
cat > delete.yaml <<EOF - name: Delete AlloyDB Omni resources hosts: localhost roles: - role: google.alloydbomni_orchestrator.delete EOF - Enumera las copias de seguridad:
Verifica que el resultado muestre la copia de seguridad deansible-playbook status.yaml -i deployment_spec.yaml -e resource_type=Backups3-backup-1. - Borra la copia de seguridad de
s3-backup-1:ansible-playbook delete.yaml -i deployment_spec.yaml \ -e resource_type=Backup -e resource_name=s3-backup-1 - Borra el plan de copias de seguridad:
ansible-playbook delete.yaml -i deployment_spec.yaml \ -e resource_type=BackupPlan -e resource_name=s3-backup-plan - Borra el clúster y el entorno de procesamiento con el paso Clean up Resources del codelab Deploy AlloyDB Omni high availability cluster on GCE VMs using RPM Orchestrator. El servidor de MinIO y las copias de seguridad que contiene se encuentran en la VM de control. Cuando borras el entorno de procesamiento, borras tanto el servidor como las copias de seguridad.
9. Felicitaciones
Felicitaciones. Realizaste una copia de seguridad de un clúster de alta disponibilidad (HA) en un almacenamiento de objetos compatible con S3 para AlloyDB Omni con el organizador de RPM. Luego, restableciste el clúster a partir de las copias de seguridad.
Temas abordados
- Cómo instalar y ejecutar MinIO como almacén de objetos compatible con S3.
- Cómo crear un plan de copias de seguridad y una copia de seguridad a pedido
- Cómo restablecer un clúster a partir de una copia de seguridad y a un momento determinado
Para obtener más información, consulta las siguientes páginas: