sql >> Base de Datos >  >> RDS >> PostgreSQL

Pruebas automatizadas de copias de seguridad de PostgreSQL

Tener copias de seguridad periódicas de su base de datos PostgreSQL por sí sola no es suficiente para la recuperación ante desastres:debe asegurarse de que los archivos de copia de seguridad estén accesibles y en buen estado cuando sea necesario para un procedimiento de restauración. Siga leyendo para ver algunos ejemplos de cómo configurar pruebas automatizadas de copias de seguridad de PostgreSQL.

Copias de seguridad realizadas con pg_basebackup

El pg_basebackup Las copias de seguridad contienen el directorio de datos completo para un clúster de base de datos. Este directorio generalmente se empaqueta en un tarball, a veces con un tarball adicional para los archivos WAL que se crearon desde el inicio de la copia de seguridad.

Para probar tal pg_basebackup tarball, primero descomprima el tarball en un directorio vacío. Si hay un tarball de archivo WAL separado, descomprímalo en el pg_wal directorio dentro del nuevo directorio:

$ mkdir backup-test
$ cd backup-test
$ tar --no-same-owner xvf /path/to/base.tar.gz
$ mkdir -p pg_wal
$ cd pg_wal
$ tar --no-same-owner xvf /path/to/pg_wal.tar.gz

Ahora puede iniciar un proceso de servidor PostgreSQL para este directorio:

$ pg_ctl -D path/to/backup-test start

(Nota:pg_ctl es una herramienta de línea de comandos incluida en la distribución estándar de Postgres. Está disponible en todos los lugares donde se encuentra Postgres, similar a las otras herramientas incluidas como psql y pg_dump .Aprenda más sobre pg_ctl aquí.)

Si ya hay un servidor PostgreSQL instalado/ejecutándose en esta máquina, probablemente querrá comenzar en un puerto que no sea el 5432 predeterminado:

$ pg_ctl -D path/to/backup-test -o "-p 6000 -k /tmp" start

Si todo tuvo éxito hasta ahora, querrá verificar si los datos dentro de su base de datos restaurada están sanos. Si tiene secuencias de comandos de prueba automatizadas para ejecutar en su base de datos, ahora sería un buen momento para iniciar al menos un pequeño conjunto de esas pruebas en esta base de datos restaurada. Si no, puede hackear algunas comprobaciones rápidas usando psql:

$ psql -p 6000 -d mydb -o /dev/null -c "select * from users limit 1"

El comando anterior realiza una consulta simple en una tabla que debería existir. El código de salida de psql debería decirle si la consulta fue exitosa o no. Por supuesto, puede ejecutar consultas más complejas, o ejecutar un archivo .sql, o incluso un script de prueba separado que se conectará a esta base de datos y ejecutará pruebas.

Cuando haya terminado con la prueba, puede detener el proceso del servidor de Postgres con:

$ pg_ctl -D path/to/backup-test stop

Y limpie todo el directorio del clúster de la base de datos extraído:

$ rm -rf path/to/backup-test

Así es como se ve cuando está todo junto:

#!/bin/bash

# exit immediately if any step fails 
set -eo pipefail

# fetch the latest backup
# TODO: copy out base.tar.gz and pg_wal.tar.gz of latest backup

# create a directory to work in
BACKUP_DIR=/tmp/backup-test
rm -rf $BACKUP_DIR
mkdir $BACKUP_DIR

# unpack the backup archives
tar -C $BACKUP_DIR --no-same-owner xvf /path/to/base.tar.gz
mkdir -p $BACKUP_DIR/pg_wal
tar -C $BACKUP_DIR/pg_wal --no-same-owner xvf /path/to/pg_wal.tar.gz

# start a new Postgres server for the cluster on port 6000
pg_ctl -D $BACKUP_DIR -o "-p 6000 -k /tmp" start

# perform a simple test
psql -p 6000 -d mydb -o /dev/null -c "select * from users limit 1"

# shutdown the server
pg_ctl -D $BACKUP_DIR stop

# cleanup the files
rm -rf $BACKUP_DIR /path/to/base.tar.gz /path/to/pg_wal.tar.gz

Copias de seguridad hechas usando pg_dump

El pg_dump La herramienta (docs) también se puede usar para crear copias de seguridad; esto es más flexible ya que puede seleccionar opcionalmente la base de datos/esquema/tablas que desea respaldar, a diferencia de pg_basebackup que es un proceso de todo o nada.

Con pg_dump , puede generar un solo .sql script o un binario .pgdmp archivo que contiene todos los datos (y opcionalmente también las sentencias DDL para crear las tablas/índices, etc.). Para restaurar dicho archivo, debe conectarse a un servidor de base de datos en vivo y ejecutar los comandos SQL dentro del archivo .sql/.pgdmp. Si bien puede usar el psql regular para ejecutar el archivo .sql, deberá usar pg_restore comando (docs) para ejecutar el archivo .pgdmp.

Para probar dichas copias de seguridad, primero buscamos el archivo y luego creamos un nuevo clúster de base de datos vacío:

$ rm -rf path/to/backup-test
$ pg_ctl -D path/to/backup-test initdb

e inicie un servidor PostgreSQL en él, escuchando en el puerto 6000 como antes:

$ pg_ctl -D path/to/backup-test -o "-p 6000 -k /tmp" start

Es posible generar pg_dump archivos que son totalmente autónomos, pero también es posible generarlos para que no lo sean tanto. Por lo tanto, dependiendo de cómo se generó el volcado, es posible que se requieran algunos pasos de configuración:

  • crear una base de datos
  • crear tablas, índices, etc.
  • otorgar privilegios

Una vez hecho esto, puede usar psql o pg_restore para devolver los datos a la vida:

# for .sql files
$ psql -p 6000 -h /tmp -v ON_ERROR_STOP=1 -1 -b -f path/to/dump.sql 

# for .pgdmp files
$ pg_restore -p 6000 -h /tmp -d mydb -C -1 -f path/to/dump.pgdmp

Como antes, en este punto, se pueden realizar pruebas para garantizar la cordura de los datos restaurados.

Así es como se ve, todo junto:

#!/bin/bash

# exit immediately if any step fails 
set -eo pipefail

# fetch the latest dump
# TODO: copy out the dump.sql or dump.pgdmp of latest backup

# create an empty database cluster
BACKUP_DIR=/tmp/backup-test
rm -rf $BACKUP_DIR
pg_ctl -D $BACKUP_DIR initdb

# start a new Postgres server for the cluster on port 6000
pg_ctl -D $BACKUP_DIR -o "-p 6000 -k /tmp" start

# TODO: perform any specific setup steps here

# restore the file, .sql:
psql -p 6000 -h /tmp -v ON_ERROR_STOP=1 -1 -b -f path/to/dump.sql 
# or .pgdmp:
pg_restore -p 6000 -h /tmp -d mydb -C -1 -f path/to/dump.pgdmp

# perform a simple test
psql -p 6000 -d mydb -o /dev/null -c "select * from users limit 1"

# shutdown the server
pg_ctl -D $BACKUP_DIR stop

# cleanup the files
rm -rf $BACKUP_DIR /path/to/dump.*

Cuidado con los desencadenantes

Al restaurar un pg_dump copia de seguridad, los datos se insertan en las tablas, como cuando lo hace una aplicación. Si tiene disparadores que se conectan a servicios externos para notificar las inserciones de filas, sería mejor deshabilitarlos durante el procedimiento de restauración.

Al invocar pg_dump para emitir archivos sql, puede usar la opción --disable-triggers decirle a pg_dump para generar un script para deshabilitar los disparadores durante la inserción.

Al invocar pg_restore en una base de datos que ya tiene disparadores, puede usar --disable-triggers en pg_restore para lograr el mismo efecto.

Pruebas PITR

La recuperación de un punto en el tiempo (PITR) en Postgres se basa en una copia de seguridad completa realizada con pg_basebackup , y una secuencia de archivos WAL desde ese punto hasta el momento en el que desea recuperar. Por lo tanto, la prueba de PITR implica probar la copia de seguridad completa, así como los archivos WAL posteriores.

Para las pruebas de copia de seguridad automatizadas, no tenemos un objetivo de recuperación específico. Se deben probar todos los archivos WAL archivados desde la última copia de seguridad en adelante hasta la más reciente. La forma más fácil de probar esto es seguir los mismos pasos que para pg_basebackup método de prueba, con solo un paso adicional. Después de desempaquetar la última copia de seguridad, obtenga todos los archivos WAL relevantes y disponibles y colóquelos en pg_wal antes de iniciar el servidor de Postgres. Específicamente:

#!/bin/bash

# exit immediately if any step fails 
set -eo pipefail

# fetch the latest backup
# TODO: copy out base.tar.gz and pg_wal.tar.gz of latest backup

# create a directory to work in
BACKUP_DIR=/tmp/backup-test
rm -rf $BACKUP_DIR
mkdir $BACKUP_DIR

# unpack the backup archives
tar -C $BACKUP_DIR --no-same-owner xvf /path/to/base.tar.gz
mkdir -p $BACKUP_DIR/pg_wal
tar -C $BACKUP_DIR/pg_wal --no-same-owner xvf /path/to/pg_wal.tar.gz

# --> this is the new extra step <--
# TODO: fetch all WAL files from the WAL archive since the last
# backup, and place them in $BACKUP_DIR/pg_wal

# start a new Postgres server for the cluster on port 6000
pg_ctl -D $BACKUP_DIR -o "-p 6000 -k /tmp" start

# perform a simple test
psql -p 6000 -d mydb -o /dev/null -c "select * from users limit 1"

# shutdown the server
pg_ctl -D $BACKUP_DIR stop

# cleanup the files
rm -rf $BACKUP_DIR /path/to/base.tar.gz /path/to/pg_wal.tar.gz

Esto debería verificar si tanto la última copia de seguridad como los archivos WAL subsiguientes son buenos, de modo que puedan usarse para PITR cuando sea necesario.