Copias de seguridad incrementales de postgresql con pgbackrest — curso introductorio del desarrollador

Descargo de responsabilidad

Soy desarrollador. Escribo código y solo interactúo con la base de datos como usuario. En ningún caso pretendo ocupar el puesto de administrador del sistema y, mucho menos, de DBA. Pero...

Resulta que necesitaba organizar copias de seguridad de la base de datos de PostgreSQL. Sin nubes: utiliza SSH y haz que todo funcione sin que te pida dinero. ¿Qué hacemos en estos casos? Correcto, metemos pg_dump en cron, hacemos un backup diario en un archivo y, si llegamos al extremo, enviamos ese archivo a algún lugar lejano.

En esta ocasión, la dificultad fue que, según los planes, la base de datos debía crecer aproximadamente unos 100 MB al día. Por supuesto, después de un par de semanas, la necesidad de hacer todo con pg_dump desaparece. Aquí es donde entran en juego las copias de seguridad incrementales.

¿Interesado? Bienvenido al siguiente apartado.

Una copia de seguridad incremental es un tipo de copia donde no se copian todos los archivos de la fuente, sino solo los nuevos y modificados desde la creación de la copia anterior.

Como cualquier desarrollador, total y absolutamente reacio (en ese momento) a entender las complejidades de Postgres, quería encontrar el botón verde. Ya sabes, como en AWS, DigitalOcean: pulsas un botón y obtienes replicación, pulsas el segundo y configuras backups, el tercero y restauras todo a unas horas atrás. No encontré ni botones ni una herramienta gráfica atractiva. Si conoces alguna (gratuita o económica), por favor coméntalo.

Al buscar encontré dos herramientas pgbarman y pgbackrest. Con la primera no tuve suerte (documentación muy escasa, intenté configurarlo con antiguos manuales), pero la documentación de la segunda estaba a la altura, aunque no sin defectos. Para simplificar el trabajo de quienes se enfrenten a una tarea similar, se escribió este artículo.

Al finalizar la lectura de este artículo, aprenderás a realizar copias de seguridad incrementales, guardarlas en un servidor remoto (repositorio de copias de seguridad) y restaurarlas en caso de pérdida de datos u otros problemas en el servidor principal.

Preparación

Para seguir el manual necesitarás dos VPS. El primero será el almacenamiento (repositorio en el que estarán las copias de seguridad), y el segundo será, en sí, el servidor con PostgreSQL (en mi caso, la versión 11 de PostgreSQL).

Se asume que en el servidor con Postgres tienes un usuario root, un usuario sudo, un usuario postgres y que postgres está instalado (el usuario postgres se crea automáticamente al instalar PostgreSQL), y que en el servidor del repositorio hay un usuario root y un usuario sudo (en el manual se usará el nombre de usuario pgbackrest).

Para que tengas menos problemas al reproducir las instrucciones, escribiré en cursiva dónde, con qué usuario y con qué permisos ejecuté el comando durante la escritura y verificación del artículo.

Instalación de pgbackrest

Repositorio (usuario pgbackrest):

1. Descargamos el archivo comprimido de pgbackrest y trasladamos su contenido a la carpeta /build:

sudo mkdir /build
sudo wget -q -O - 
       https://github.com/pgbackrest/pgbackrest/archive/release/2.18.tar.gz | 
       sudo tar zx -C /build

2. Instalamos las dependencias necesarias para la compilación:

sudo apt-get update
sudo apt-get install build-essential libssl-dev libxml2-dev libperl-dev zlib1g-dev 
       libpq-dev

3. Compilamos pgbackrest:

cd /build/pgbackrest-release-2.18/src && sudo ./configure
sudo make -s -C /build/pgbackrest-release-2.18/src

4. Copiamos el archivo ejecutable al directorio /usr/bin:

sudo cp /build/pgbackrest-release-2.18/src/pgbackrest /usr/bin
sudo chmod 755 /usr/bin/pgbackrest

5. Pgbackrest requiere Perl. Instalamos:

sudo apt-get install perl

6. Creamos directorios para los logs y les damos permisos específicos:

sudo mkdir -p -m 770 /var/log/pgbackrest
sudo chown pgbackrest:pgbackrest /var/log/pgbackrest
sudo mkdir -p /etc/pgbackrest
sudo mkdir -p /etc/pgbackrest/conf.d
sudo touch /etc/pgbackrest/pgbackrest.conf
sudo chmod 640 /etc/pgbackrest/pgbackrest.conf
sudo chown pgbackrest:pgbackrest /etc/pgbackrest/pgbackrest.conf

7. Verificamos:

pgbackrest version

Servidor Postgres (usuario sudo o root):

El proceso de instalación de pgbackrest en el servidor con Postgres es similar al proceso de instalación en el repositorio (sí, pgbackrest debe estar en ambos servidores), pero en el punto 6 reemplazamos el segundo y último comando:

sudo chown pgbackrest:pgbackrest /var/log/pgbackrest
sudo chown pgbackrest:pgbackrest /etc/pgbackrest/pgbackrest.conf

por:

sudo chown postgres:postgres /var/log/pgbackrest
sudo chown postgres:postgres /etc/pgbackrest/pgbackrest.conf

Configuración de la interacción entre servidores a través de SSH sin contraseña

Para que pgbackrest funcione correctamente, es necesario configurar la interacción entre el servidor postgres y el repositorio a través de un archivo clave.

Repositorio (usuario pgbackrest):

Creamos un par de claves:

mkdir -m 750 /home/pgbackrest/.ssh
ssh-keygen -f /home/pgbackrest/.ssh/id_rsa 
       -t rsa -b 4096 -N ""

¡Atención! Los comandos mencionados anteriormente se ejecutan sin sudo.

Servidor Postgres (usuario sudo o root):

Creamos un par de claves:

sudo -u postgres mkdir -m 750 -p /var/lib/postgresql/.ssh
sudo -u postgres ssh-keygen -f /var/lib/postgresql/.ssh/id_rsa 
       -t rsa -b 4096 -N ""

Repositorio (usuario sudo):

Copiamos la clave pública del servidor postgres al servidor del repositorio:

(echo -n 'no-agent-forwarding,no-X11-forwarding,no-port-forwarding,' && 
       echo -n 'command="/usr/bin/pgbackrest ${SSH_ORIGINAL_COMMAND#* }" ' && 
       sudo ssh root@ cat /var/lib/postgresql/.ssh/id_rsa.pub) | 
       sudo -u pgbackrest tee -a /home/pgbackrest/.ssh/authorized_keys

En este paso se pedirá la contraseña del usuario root. ¡Debes ingresar la contraseña del usuario root del servidor postgres!

Servidor Postgres (usuario sudo):

Copiamos la clave pública del repositorio al servidor con postgres:

(echo -n 'no-agent-forwarding,no-X11-forwarding,no-port-forwarding,' && 
       echo -n 'command="/usr/bin/pgbackrest ${SSH_ORIGINAL_COMMAND#* }" ' && 
       sudo ssh root@ cat /home/pgbackrest/.ssh/id_rsa.pub) | 
       sudo -u postgres tee -a /var/lib/postgresql/.ssh/authorized_keys

En este paso se pedirá la contraseña del usuario root. ¡Debes ingresar la contraseña del usuario root del repositorio!

Verificando:

Repositorio (usuario root, para la pureza del experimento):

sudo -u pgbackrest ssh postgres@

Servidor Postgres (usuario root, para la pureza del experimento):

sudo -u postgres ssh pgbackrest@

Verificamos que tenemos acceso sin problemas.

Configuración del servidor postgres

Servidor Postgres (usuario sudo o root):

1. Permitiremos el acceso al servidor postgres desde IPs externas. Para ello, editaremos el archivo postgresql.conf (se encuentra en la carpeta /etc/postgresql/11/main), añadiendo la línea:

listen_addresses = '*'

Si ya existe esa línea, descoméntala o establece el valor del parámetro como ‘*’.

En el archivo pg_hba.conf (también se encuentra en la carpeta /etc/postgresql/11/main) añadimos las siguientes líneas:

hostssl  all  all  0.0.0.0/0  md5
host  all  all  0.0.0.0/0  md5

donde:

hostssl/host - nos conectamos a través de SSL (o no)
all - permitimos la conexión a todas las bases de datos
all - nombre del usuario al que permitimos la conexión (a todos)
0.0.0.0/0 - máscara de red desde la cual se puede conectar
md5 - método de cifrado de contraseñas

2. Haremos las configuraciones necesarias en postgresql.conf (se encuentra en la carpeta /etc/postgresql/11/main) para el funcionamiento de pgbackrest:

archive_command = 'pgbackrest --stanza=main archive-push %p' # Donde main es el nombre del clúster. Al instalar postgres se crea automáticamente el clúster main.
archive_mode = on
max_wal_senders = 3
wal_level = replica

3. Haremos las configuraciones necesarias en el archivo de configuración de pgbackrest (/etc/pgbackrest/pgbackrest.conf):

[main]
pg1-path=/var/lib/postgresql/11/main

[global]
log-level-file=detail
repo1-host=

4. Reiniciamos postgresql:

sudo service postgresql restart

Configuración del servidor repositorio

Repositorio (usuario pgbackrest):

Haremos las configuraciones necesarias en el archivo de configuración pgbackrest
(/etc/pgbackrest/pgbackrest.conf):

[main]
pg1-host=
pg1-path=/var/lib/postgresql/11/main

[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2 # Este parámetro indica cuánto tiempo almacenar copias de seguridad completas. Es decir, si tienes dos copias de seguridad completas y creas una tercera, las dos primeras se eliminarán junto con los incrementos.
start-fast=y # Comienza la copia de seguridad de inmediato, puedes leer sobre este parámetro aquí https://postgrespro.ru/docs/postgrespro/9.5/continuous-archiving

Creación de almacenamiento

Repositorio (usuario pgbackrest):

Creamos un nuevo almacenamiento para el clúster main:

sudo mkdir -m 770 /var/lib/pgbackrest
sudo chown -R pgbackrest /var/lib/pgbackrest/
sudo -u pgbackrest pgbackrest --stanza=main stanza-create

Verificación

Servidor Postgres (usuario sudo o root):

Verificamos en el servidor de postgres:

sudo -u postgres pgbackrest --stanza=main --log-level-console=info check

Repositorio (usuario pgbackrest):

Verificamos en el servidor de repositorio:

sudo -u pgbackrest pgbackrest --stanza=main --log-level-console=info check

Asegurémonos de que en la salida veamos la línea «check command end: completed successfully».

¿Cansado? Pasemos a lo más interesante.

Hacemos una copia de seguridad

Repositorio (usuario pgbackrest):

1. Realizamos la copia de seguridad:

sudo -u pgbackrest pgbackrest --stanza=main backup

2. Asegurémonos de que se ha creado la copia de seguridad:

ls /var/lib/pgbackrest/backup/main/

Pgbackrest creará la primera copia de seguridad completa. Si lo deseas, puedes volver a ejecutar el comando de copia de seguridad y asegurarte de que el sistema creará una copia de seguridad incremental.

Si deseas volver a realizar una copia de seguridad completa, debes especificar un flag adicional:

sudo -u pgbackrest pgbackrest --stanza=main --type=full backup

Si deseas una salida detallada en la consola, también debes especificar:

sudo -u pgbackrest pgbackrest --stanza=main --type=full --log-level-console=info backup

Restauramos la copia de seguridad

Servidor Postgres (usuario sudo o root):

1. Detenemos el clúster en funcionamiento:

sudo pg_ctlcluster 11 main stop

2. Restauramos desde la copia de seguridad:

sudo -u postgres pgbackrest --stanza=main --delta restore

3. Iniciamos el clúster:

sudo pg_ctlcluster 11 main start

Después de restaurar la copia de seguridad, debemos realizar una copia de seguridad nuevamente:

Repositorio (usuario pgbackrest):

sudo pgbackrest --stanza=main backup

Eso es todo. Para concluir, quiero recordar que no intento pretender ser un DBA senior y que, en cuanto tenga la oportunidad, usaré la nube. Actualmente, estoy comenzando a estudiar varios temas como copias de seguridad, replicaciones, monitoreo, etc., y estoy escribiendo pequeños informes sobre los resultados, para hacer una pequeña contribución a la comunidad y dejarme pequeñas chuletas.

En los próximos artículos intentaré hablar sobre características adicionales: restauración de datos en un clúster limpio, cifrado de copias de seguridad y publicación en S3, copias de seguridad a través de rsync.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster