En este instructivo, crearás una base de datos de demostración y ejecutarás la carga de trabajo de una aplicación. Luego, configurarás los procesos de archivado y de copia de seguridad. A continuación, aprenderás a verificar los procesos de copia de seguridad, archivado y recuperación. Por último, aprenderás a recuperar la base de datos en un momento específico.
Este instructivo está dirigido a administradores de bases de datos, operadores de sistemas, profesionales de DevOps y arquitectura de nube interesados en la configuración de una estrategia de copia de seguridad y recuperación para bases de datos de PostgreSQL.
En este instructivo, se supone que estás familiarizado con los contenedores de Docker y que te sientes cómodo con Compute Engine, los comandos de Linux y los motores de las bases de datos de PostgreSQL.
Objetivos
- Configurar un proceso de copia de seguridad y archivado
- Realizar una PITR
- Supervisar la copia de seguridad
- Verificar una recuperación
Costos
En este documento, usarás los siguientes componentes facturables de Google Cloud:
Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios.
Cuando finalices las tareas que se describen en este documento, puedes borrar los recursos que creaste para evitar que continúe la facturación. Para obtener más información, consulta Cómo realizar una limpieza.
Antes de comenzar
- 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.
Conceptos
Antes de comenzar con el instructivo, revisa los siguientes conceptos de PostgreSQL:
- Archivado continuo. Es el proceso en el que la base de datos guarda transacciones secuenciales en un archivo de forma continua.
- Registro de escritura por adelantado (WAL). Los cambios en los archivos de datos se registran en el WAL antes de realizarse en el archivo.
- Registro WAL. Cada transacción que se aplica a la base de datos recibe el formato de registro WAL y se almacena como tal.
- Archivos de segmentos. Los archivos de segmentos tienen nombres que aumentan de forma monótona y contienen tantos registros WAL como sea posible. El tamaño del archivo se puede configurar y tiene un valor predeterminado de 16 MiB. Si esperas transacciones de un recuento o un tamaño voluminosos, puedes elegir un tamaño mayor para reducir la cantidad total de archivos de segmentos generados y disminuir la carga de la administración de archivos.
Para obtener más información, consulta La confiabilidad y el registro de escritura por adelantado.
En el siguiente diagrama, se muestra cómo los WAL se conservan en dos etapas.
En el diagrama anterior, la primera etapa de los WAL persistentes consiste en que el motor de la base de datos registre transacciones de escritura en el búfer de WAL de forma simultánea a la escritura en una tabla. Cuando se confirma la transacción, el búfer de WAL se escribe en el disco (se borran sus datos) durante la segunda etapa y se agrega al archivo de segmentos WAL.
Elige una PITR
Una PITR es apropiada para las siguientes situaciones:
- Minimizar el objetivo de punto de recuperación (RPO). El RPO es el tiempo máximo de pérdida de datos que se tolera sin que tenga un impacto significativo en los procesos empresariales. Si se guardan todas las transacciones en los WAL entre las instantáneas de copia de seguridad, se disminuye de forma drástica la cantidad de datos perdidos, ya que se cuenta con las transacciones desde la última copia de seguridad completa para su aplicación a la base de datos.
- Minimizar el objetivo de tiempo de recuperación (RTO). El RTO es la cantidad de tiempo necesaria para recuperar una base de datos si se produce un evento destructivo. Después de configurar las copias de seguridad de objetos binarios y el archivado de registros, el tiempo necesario para recuperar la base de datos puede ser mínimo.
- Solucionar un error de corrupción de datos o una falla administrativa. Si la versión de un código causa daños catastróficos en los datos o si se comete un error irrecuperable durante el mantenimiento de rutina, puedes realizar una recuperación a un momento anterior a ese.
En algunas arquitecturas de aplicaciones, como una arquitectura de microservicios, puede que haya bases de datos paralelas que requieran recuperaciones independientes. Por ejemplo, puede que una aplicación de venta minorista tenga datos de clientes en una base de datos y detalles de pedidos de venta minorista junto con información del inventario en otras bases de datos. Según el estado general de los datos, es posible que debas recuperar una, dos o todas las bases de datos en paralelo.
Una PITR no es apropiada para las siguientes situaciones:
- El RPO es amplio. Si tu política de recuperación ante desastres puede tolerar la pérdida de cualquier transacción recibida después de la instantánea más reciente, puedes evitar los pasos adicionales y enfocarte en reducir el tiempo de recuperación de los datos.
- Se necesita una recuperación completa de la base de datos. Si tu meta es recuperar hasta la transacción más reciente, el objetivo de recuperación es la marca de tiempo de la última transacción conservada. Esta situación es un caso específico de PITR, pero la meta se conoce de forma semántica como una recuperación completa.
Consideraciones de rendimiento
El proceso de archivado agrega una carga adicional de E/S en el servidor de la base de datos. La carga adicional depende de las características de tu carga de trabajo, ya que es proporcional al volumen de transacciones de escritura, actualización y eliminación.
Si deseas reducir el impacto de E/S que podría generar la actividad de archivado de WAL en tu base de datos principal, puedes realizar los archivados de WAL periódicos mediante el uso de una réplica de solo lectura.
Esta configuración aísla la base de datos principal de las actividades de E/S por lotes relacionadas con la transferencia de los archivos WAL. Las transacciones que se dirigen a la réplica de solo lectura se transmiten en un flujo constante desde la base de datos principal, lo que exige un impacto mucho menor en la capacidad de procesamiento de estado estable.
Además, si la topología de la base de datos de producción ya incluye una réplica de solo lectura, esta configuración no agrega ninguna carga adicional de administración, precios, ni de ningún otro tipo.
Arquitectura de referencia
En el siguiente diagrama, se ilustra la arquitectura que implementas en este instructivo.
En este instructivo, crearás una infraestructura de nube para observar una PITR que usa los siguientes componentes:
- Un servidor de bases de datos de PostgreSQL que se ejecuta en Compute Engine
- Cloud Storage para el almacenamiento de instantáneas y registros de transacciones
En el siguiente diagrama, se muestran los dos contenedores de Docker que se inician en la máquina virtual (VM) de la base de datos de PostgreSQL. Como en una separación de intereses, el servidor de la base de datos se ejecuta en uno de los contenedores y el archivador de WAL se ejecuta en el otro.
En este diagrama, se muestra cómo se asignan los volúmenes de Docker en cada contenedor a los puntos de activación del Persistent Disk en la VM host.
Configura variables de entorno
Los comandos y las secuencias de comandos que se usan en este instructivo se basan en variables de entorno de shell.
En Cloud Shell, configura las variables de entorno de tu proyecto, el nombre de la instancia y la base de datos de PostgreSQL de demostración.
export PROJECT_ID=your-gcp-project export PG_INSTANCE_NAME=instance-pg-pitr export POSTGRES_PASSWORD=PasswordIsThis export POSTGRES_PITR_DEMO_DBNAME=pitr_demo
Reemplaza los siguientes elementos:
your-gcp-project
: Es el nombre del proyecto que creaste para este instructivo.PasswordIsThis
: Es una contraseña segura para la base de datos de PostgreSQL.
Configura la variable de entorno de la zona de Google Cloud . Reemplaza
choose-an-appropriate-zone
por una zona de .export ZONE=choose-an-appropriate-zone export REGION=${ZONE%-[a-z]}
Configura la variable de entorno de la subred de la nube privada virtual (VPC) predeterminada de la región de tu zona:
export SUBNETWORK_URI=$(gcloud compute networks subnets \ describe default --format=json --region=$REGION | \ jq --raw-output '.ipCidrRange')
Configura la variable de entorno del bucket de Cloud Storage. Reemplaza
archive-bucket
por un nombre único para el bucket de Cloud Storage en el que se guardan los WAL.export ARCHIVE_BUCKET=archive-bucket
Crea un bucket de Cloud Storage
Crea un bucket de Cloud Storage para guardar los archivos WAL desde la base de datos de PostgreSQL:
gcloud storage buckets create gs://${ARCHIVE_BUCKET}
Permite el acceso a instancias de direcciones IP privadas
En cuanto a las instancias que se usan en este instructivo, como en muchos casos prácticos de producción, no es necesario que las instancias de VM obtengan direcciones IP públicas. Sin embargo, necesitas acceso para conectarte mediante una shell segura y las instancias requieren acceso a la Internet pública a fin de extraer las imágenes de contenedor de ejemplo. Debes configurar una puerta de enlace de traducción de direcciones de red (NAT) y un Identity-Aware Proxy (IAP) para la redirección de TCP.
Crea una puerta de enlace NAT
Debido a que las instancias de VM que creas no tienen direcciones IP públicas, debes crear una puerta de enlace NAT para que las instancias puedan extraer imágenes de contenedores de Docker Hub.
En Cloud Shell, crea un Cloud Router:
export CLOUD_ROUTER_NAME=${PROJECT_ID}-nat-router gloud compute routers create $CLOUD_ROUTER_NAME \ --network=default --region=$REGION
Crea la puerta de enlace 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
Configura IAP para la redirección de TCP
IAP controla el acceso a tus aplicaciones y VMs en la nube que se ejecutan en Google Cloud. IAP verifica la identidad del usuario y el contexto de la solicitud para determinar si el usuario puede acceder a una VM.
En Cloud Shell, permite el tráfico desde el bloque de red de redirección de TCP hacia las instancias de tu proyecto:
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
Para conectarte mediante un túnel de reenvío de TCP, agrega una vinculación de políticas de Identity and Access Management (IAM). Reemplaza
your-email-address
por la dirección de correo electrónico que usas para acceder a la consola de 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
Crea la infraestructura de la base de datos de PostgreSQL
En Cloud Shell, clona el repositorio de origen que contiene las secuencias de comandos de configuración y cambia el contexto de la shell al repositorio local:
git clone https://github.com/GoogleCloudPlatform/gcs-postgresql-recovery-tutorial cd gcs-postgresql-recovery-tutorial
Para crear y configurar la instancia de VM de la base de datos, ejecuta la siguiente secuencia de comandos:
cd bin ./create_postgres_instance.sh
En el caso de este instructivo, la secuencia de comandos inicia una instancia de VM en la zona elegida con el sistema operativo optimizado para contenedores y dos discos persistentes nuevos conectados. En este caso, puedes ignorar el mensaje de advertencia que muestra la API acerca del rendimiento bajo de E/S debido a que las secuencias de comandos crean discos persistentes pequeños.
Revisa la configuración de cloud-init
Cloud-init es un paquete de distribución múltiple que inicializa una instancia en la nube.
Revisa la siguiente muestra de código de cloud-init:
En este instructivo, se usa cloud-init para realizar las siguientes acciones:
- Crear dos dispositivos de almacenamiento en bloque de Persistent Disk
- Crear los sistemas de archivos en ambos dispositivos: uno para los datos y otro para los registros de archivos
- Activar los dispositivos en puntos de activación lógicos en la instancia de VM, que se comparten con los contenedores de Docker
- Crear y, luego, iniciar un servicio
systemd
(postgres.service
), que inicia un contenedor de Docker de PostgreSQL que contiene los siguientes elementos:- Los discos persistentes activados como volúmenes
- El puerto de PostgreSQL (
5432
) publicado en el host de VM
- Crear un archivo
/var/tmp/docker-entrypoint-initdb.d/init-pitr-demo-db.sql
para crear un conjunto simple de tablas en un esquema y una base de datos de demostración - Crear e iniciar un segundo servicio
systemd
(wal_archive.service
) que ejecute un contenedor de Docker de Google Cloud CLI con los discos WAL activados como un volumen. Este servicio crea una copia de seguridad de los archivos WAL almacenados en Cloud Storage - Crear, habilitar y, luego, iniciar un temporizador
systemd
(wal_archive.timer
) que ejecute elwal_archive.service
de forma periódica - Garantizar que el puerto de PostgreSQL (
5432
) esté abierto para la subred de VPC, de forma que el generador de transacciones pueda alcanzar el puerto de la base de datos
Modifica la configuración de la instancia de la base de datos
El servidor de la base de datos se encuentra en ejecución, pero debes configurar el acceso a la red y comenzar el proceso de archivado de WAL.
Conéctate a la instancia de VM de la base de datos
En la consola de Google Cloud , ve a la página Instancias de VM.
Para abrir la shell de una terminal, junto a la instancia
instance-pg-pitr
que creaste, haz clic en SSH.En la shell de la terminal, verifica que se haya iniciado el contenedor de Docker:
docker ps
El resultado es similar a este:
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
Si el contenedor aún no se encuentra en ejecución, espera un momento y, luego, usa el mismo comando para volver a realizar la verificación.
Permite conexiones de red entrantes en la base de datos
En la shell de la terminal de la instancia
instance-pg-pitr
, abre el archivo de configuración de autenticación basado en el host de PostgreSQL para editarlo:sudoedit /mnt/disks/data/pgdata/pg_hba.conf
Para quitar el acceso predeterminado de todas las direcciones IP a la base de datos, comenta la siguiente línea desde el final del archivo mediante el agregado de
#
al comienzo de la línea. La línea del archivo es similar a la siguiente:#host all all all md5
Para permitir conexiones protegidas por contraseñas desde hosts en el bloque CIDR
10.0.0.0/8
, agrega la siguiente línea al final del archivo:host all all 10.0.0.0/8 md5
Esta entrada habilita la conectividad desde la subred de VPC en la que se creará el generador de transacciones más adelante.
Guarda y, luego, cierra el archivo.
Configura el archivado de WAL
En la shell de la terminal de la instancia
instance-pg-pitr
, edita el archivopostgresql.conf
:sudoedit /mnt/disks/data/pgdata/postgresql.conf
Reemplaza las líneas comentadas existentes
archive_mode
,archive_command
yarchive_timeout
por las siguientes: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
Cuando reemplaces las líneas en el archivo modificado, será similar al siguiente fragmento de código:
Guarda y, luego, cierra el archivo.
Aplica y verifica los cambios de configuración
En la shell de la terminal de la instancia
instance-pg-pitr
, reinicia el contenedor para aplicar los cambios:sudo systemctl restart postgres
Verifica los archivos de segmentos WAL:
sudo ls -l /mnt/disks/wal/pg_wal
El resultado es similar a este:
total 16388 -rw------- 1 postgres 70 16777216 Sep 5 23:07 000000010000000000000001 drwx------ 2 postgres 70 4096 Sep 5 23:05 archive_status
Comprueba la conectividad de red a la base de datos:
export LOCAL_IP=127.0.0.1 docker exec postgres-db psql -w --host=$LOCAL_IP \ --command='SELECT 1'
El resultado es similar a este:
?column? ---------- 1 (1 row)
Cierra la conexión SSH a la instancia.
Inicia el generador de transacciones para propagar la base de datos
Mediante los siguientes pasos, se inicia un programa de Go que genera transacciones para este instructivo. El programa se ejecuta dentro de un contenedor en una instancia de VM.
La imagen para el contenedor ya se encuentra compilada y alojada en un proyecto con un Container Registry público.
En Cloud Shell, cambia al directorio del generador de transacciones:
cd ~/gcs-postgresql-recovery-tutorial/bin
Configura las variables de entorno:
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')
Para ejecutar el generador de transacciones, inicia la instancia:
./run_trans_gen_instance.sh
Ignora el mensaje de advertencia acerca del rendimiento bajo de E/S.
Espera unos minutos y comprueba que las transacciones lleguen a la base de datos de 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;'"
El resultado contiene un recuento mayor que 0 cuando el generador de transacciones agrega registros a la base de datos:
count ------- 413 (1 row)
Configura el programa de copia de seguridad de instantáneas de objetos binarios
Puedes crear una copia de seguridad de los discos persistentes en función de un programa y conservarlos durante un tiempo definido en la política de recursos.
Crea el programa de instantáneas
En Cloud Shell, configura las variables de entorno:
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
Reemplaza zone-of-your-instance por la zona deGoogle Cloud en la que iniciaste la VM de la base de datos antes.
Crea el programa de instantáneas:
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
Conecta el programa de instantáneas a los discos
Cuando ejecutaste la secuencia de comandos para crear una instancia, se crearon los datos y los volúmenes de WAL como dos discos persistentes independientes. Para crear instantáneas de discos persistentes en función de un programa definido, debes asociar una política de recursos a cada disco persistente. En este caso, deseas que las instantáneas de los discos se produzcan de forma simultánea, por lo que debes usar la misma política para ambos discos persistentes conectados a la VM de Compute Engine.
En Cloud Shell, configura las variables de entorno:
export SNAPSHOT_SCHEDULE_NAME=pgdata-disk-schedule export PG_INSTANCE_NAME=instance-pg-pitr export ZONE=zone-of-your-instance
Conecta la política de programación al disco de datos persistentes:
gcloud beta compute disks add-resource-policies ${PG_INSTANCE_NAME}-data \ --resource-policies $SNAPSHOT_SCHEDULE_NAME \ --zone $ZONE
Conecta la política de programación al disco de WAL persistente:
gcloud beta compute disks add-resource-policies ${PG_INSTANCE_NAME}-wal \ --resource-policies $SNAPSHOT_SCHEDULE_NAME \ --zone $ZONE
Ejecuta una instantánea de forma manual
Las instantáneas programadas se producen dentro de la ventana de programación, por lo que es poco probable que se haya tomado una de forma inmediata cuando creaste el programa (opcional). Si no quieres esperar a que se produzca la instantánea programada, puedes ejecutar la instantánea inicial de forma manual.
En Cloud Shell, configura las variables de entorno:
export ZONE=zone-of-your-instance export PG_INSTANCE_NAME=instance-pg-pitr export REGION=${ZONE%-[a-z]}
Crea una instantánea de los dos discos persistentes de instancias de 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
Visualiza las instantáneas que creaste:
gcloud compute snapshots list
El resultado es similar a este:
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
Realiza una PITR
A menudo, se realiza una PITR para recuperar los datos que se perdieron debido a un error operativo o programático.
En esta sección del instructivo, realizarás una actualización de la base de datos para simular una pérdida catastrófica de datos. Luego, simularás una respuesta en estado de pánico antes de iniciar una recuperación hasta el momento antes de que se emitiera el comando erróneo.
Asegúrate de que se pueda realizar una PITR
Antes de realizar una PITR, debes esperar el tiempo suficiente para que se ejecuten los siguientes elementos:
- Las copias de seguridad de objetos binarios (instantáneas de discos)
- El archivado de WAL
Para este instructivo, archive_timeout
se estableció de forma atípica en 120 segundos con el fin de forzar la rotación frecuente de los archivos WAL. Además, debes esperar hasta que se realice al menos una instantánea programada del disco o debes tomar una instantánea del disco de forma manual.
Comprueba que se haya tomado al menos una instantánea:
En la consola de Google Cloud , ve a la página Instantáneas.
Verifica que haya al menos dos instantáneas: una para el volumen de datos y otra para el volumen de WAL, por ejemplo,
instance-pg-pitr--us-central1-a-20190805023535-i3hpw7kn
.
Verifica que los archivos de segmentos estén archivados en Cloud Storage:
En la consola de Google Cloud , ve a la página Navegador de Cloud Storage.
Haz clic en
archive-bucket
.
Daña los datos
Para simular una pérdida catastrófica de datos, abre una shell de línea de comandos en la base de datos de PostgreSQL y daña los datos en la tabla que propaga el generador de transacciones.
En la consola de Google Cloud , ve a la página Instancias de VM.
En la instancia
instance-pg-pitr
, haz clic en SSH.En la terminal de SSH, ejecuta el frontend basado en la terminal de PostgreSQL en el contenedor de Docker:
docker exec -it postgres-db psql --dbname=pitr_demo
Para modificar una fila en la tabla de clientes, envía una declaración DML de SQL con un error de ortografía intencional en la shell de PostgreSQL:
UPDATE pitr_db_schema.customer SET name = 'New Name for customer id=1'; WHERE id = 1;
El resultado es similar a este:
UPDATE 999 pitr_demo=# WHERE id = 1; ERROR: syntax error at or near "WHERE" LINE 1: WHERE id = 1; ^
El error se generó debido a que se insertó un punto y coma adicional antes de la cláusula
WHERE
. Se actualizaron todas las filas de la base de datos. Ahora puedes realizar una PITR para recuperar las filas que se modificaron mediante la declaración incorrecta.
Determina el tiempo deseado para la recuperación
El primer paso en una PITR es determinar el tiempo deseado para la recuperación. Este tiempo se determina mediante el examen de los datos para identificar un punto que se encuentre un poco antes del evento que dañó los datos.
En el shell de la terminal de la instancia
instance-pg-pitr
, obtén la marca de tiempo máxima de las filas dañadas:SELECT MAX(create_timestamp)::timestamptz FROM pitr_db_schema.customer WHERE name = 'New Name for customer id=1';
El resultado es similar a este:
max . ------------------------------- 2019-08-05 18:14:58.226511+00 (1 row)
En una base de datos de producción, la consulta para determinar el tiempo deseado de recuperación es más compleja, en especial en los casos en que la tabla afectada es grande y la columna indicativa no se encuentra indexada.
Copia el resultado. Debes usar el valor que muestra esta consulta en el siguiente paso.
Recupera la base de datos
En el caso de este instructivo, una secuencia de comandos de recuperación automatiza la PITR. Te recomendamos que tengas un proceso automatizado para recuperar la base de datos y que lo pruebes de forma periódica.
En Cloud Shell, cambia el directorio de trabajo actual a la ubicación de la secuencia de comandos de recuperación:
cd ~/gcs-postgresql-recovery-tutorial/bin
Configura las variables de entorno que se requieren para la secuencia de comandos. Reemplaza
YYYY-MM-DD HH:MM:SS.999999+00
por el resultado de la consulta que copiaste antes.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
Ejecuta la secuencia de comandos de recuperación:
./recover_to_point_in_time.sh
Comprende la secuencia de comandos de recuperación
En esta sección, se proporcionan algunos detalles sobre los parámetros de entrada y los pasos que realiza la secuencia de comandos.
La secuencia de comandos requiere que se configuren las siguientes variables de entorno:
PIT_RECOVERY_TARGET
: Es el tiempo deseado de recuperación.PROJECT_ID
: Es el proyecto en el que se encuentra la instanciaPG_INSTANCE_NAME
.ZONE
: Es la zona en la que se encuentra la instanciaPG_INSTANCE_NAME
.PG_INSTANCE_NAME
: Es la instancia en la que se ejecuta la instancia de PostgreSQL de producción.RECOVER_BUCKET
: Es el bucket de Cloud Storage en el que se archivan los archivos de segmentos WAL.POSTGRES_PASSWORD
: Es la contraseña que se usa para el usuario de la base de datos de PostgreSQL.
La secuencia de comandos realiza los siguientes pasos:
- Determina las instantáneas más recientes del disco en función de la fecha y hora deseadas para la recuperación.
Crea un archivo
cloud-init.yaml
que se proporciona a una VM de almacenamiento optimizada para contenedores que ejecuta la base de datos de PITR. El archivocloud-init.yaml
crea archivos de configuración y ejecuta varios comandos del sistema para establecer el siguiente entorno:- Un contenedor
gcsfuse
que activa el bucket de almacenamiento del archivo de segmentos WAL como un volumen que, luego, se expone al host con una activación de vinculación de Docker Un contenedor
postgres-db
en el que el motor de la base de datos ejecuta los siguientes elementos:- El sistema de archivos host en el que los discos persistentes se conectan como volúmenes
- El sistema de archivos host en el que el bucket de Cloud Storage se conecta como un volumen
Un archivo de recuperación
recovery.conf
en el directorio de datos de PostgreSQL que contiene la siguiente información:- La fecha deseada
- El comando
restore
: es un comando de copia con parámetros que la base de datos usa para copiar archivos de segmentos WAL desde el sistema de archivos de archivado, según sea necesario.%f
es el archivo de segmentos y%p
es la ruta de acceso que usa la base de datos para procesar archivos durante la recuperación
La configuración de
archive_
se comenta desde el archivo de configuraciónpostgresql.conf
para evitar que se dañe el directorio de archivos WAL
- Un contenedor
Inicia la instancia de PITR que contiene la siguiente información:
- Un nombre creado mediante la combinación de la variable de entorno
$PG_INSTANCE_NAME
y los valores alfanuméricos de la variable de entorno$PIT_RECOVERY_TARGET
- Los discos persistentes creados a partir de las instantáneas del disco identificadas de forma previa
- Un nombre creado mediante la combinación de la variable de entorno
El siguiente es un archivo recovery.conf
de ejemplo:
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
Valida la recuperación
En la consola de Google Cloud , ve a la página Instancias de VM.
En la instancia
instance-pg-pitr-YYYYMMDDHHMMSS
, haz clic en SSH.En las terminales SSH, ejecuta el frontend basado en la terminal de PostgreSQL en el contenedor de Docker:
docker exec -it postgres-db psql --dbname=pitr_demo
Si recibes el siguiente error, espera un momento para que se inicie el contenedor de PostgreSQL y vuelve a ejecutar el comando:
Error: No such container: postgres-db
Verifica los datos en la tabla de clientes:
SELECT * FROM pitr_db_schema.customer WHERE id > (SELECT MAX(id)-10 FROM pitr_db_schema.customer);
El resultado es similar a este:
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
En el nombre, se muestra el valor que creó el generador de transacciones. La última fila tiene una marca de tiempo anterior al tiempo deseado de recuperación (el que proporcionaste en la secuencia de comandos de recuperación en una variable de entorno). En función de la cantidad de registros que necesites recuperar, es posible que tengas que esperar unos minutos para que se actualicen todas las filas.
Limpia
La manera más fácil de eliminar la facturación es borrar el proyecto de Google Cloud que creaste para el instructivo. Como alternativa, puedes borrar los recursos individuales.
Borra el proyecto
- 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.
¿Qué sigue?
- Obtén más información sobre el sistema operativo optimizado para contenedores.
- Obtén más información sobre cloud-init.
- Obtén más información sobre Cloud Storage Fuse.
- Explora arquitecturas de referencia, diagramas y prácticas recomendadas sobre Google Cloud. Consulta nuestro Cloud Architecture Center. .