Copias de seguridad incrementales de PostgreSQL con pgbackrest: un curso para un joven luchador del desarrollador

Descargo de responsabilidad

Soy desarrollador. Escribo código e interactúo con la base de datos solo como usuario. De ninguna manera pretendo ser administrador de sistemas y mucho menos dba. Pero…

Sucedió que necesitaba organizar una copia de seguridad de la base de datos PostgreSQL. Sin nubes: simplemente use SSH y asegúrese de que todo funcione sin pedir dinero. ¿Qué hacemos en tales casos? Así es, insertamos pgdump en cron, hacemos una copia de seguridad de todo en el archivo todos los días y, si estamos completamente perdidos, enviamos este archivo a algún lugar lejano.

Esta vez el problema fue que, según los planes, la base de datos debía crecer aproximadamente +- 100 MB por día. Por supuesto, después de un par de semanas, el deseo de hacer una copia de seguridad de todo con pgdump desaparecerá. Aquí es donde las copias de seguridad incrementales vienen al rescate.

¿Interesante? Bienvenido al gato.

La copia de seguridad incremental es un tipo de copia de seguridad en la que no se copian todos los archivos de origen, sino solo los nuevos y los modificados desde la creación de la copia anterior.

Como cualquier desarrollador que no estaba ABSOLUTAMENTE dispuesto (en ese momento) a comprender las complejidades de Postgres, quería encontrar el botón verde. Bueno, ya sabes, como en AWS, DigitalOcean: presionaste un botón, obtuviste replicación, presionaste el segundo, configuraste copias de seguridad, el tercero, retrocediste todo un par de horas. No encontré un botón ni una hermosa herramienta GUI. Si conoces uno (gratuito o barato), escríbelo en los comentarios.

Después de buscar en Google encontré dos herramientas. pgbarman и respaldo. Simplemente no tuve éxito con el primero (la documentación es muy escasa, intenté resolverlo todo según manuales antiguos), pero con el segundo la documentación resultó estar a la altura, pero no sin fallas. Para simplificar el trabajo de quienes se enfrentan a una tarea similar, se escribió este artículo.

Después de leer este artículo, aprenderá cómo realizar copias de seguridad incrementales, guardarlas en un servidor remoto (repositorio con copias de seguridad) y restaurarlas en caso de pérdida de datos u otros problemas en el servidor principal.

Formación

Para reproducir el manual necesitarás dos VPS. El primero será el almacenamiento (el repositorio en el que se almacenarán las copias de seguridad), y el segundo, de hecho, el propio servidor con postgres (en mi caso, la versión 11 de postgres).

Se supone que en el servidor con postgres tiene root, usuario sudo, usuario postgres y el propio postgres está instalado (el usuario postgres se crea automáticamente al instalar postgresql), y en el servidor del repositorio hay usuario root y sudo (en el manual se utilizará el nombre de usuario pgbackrest).

Para que tengas menos problemas a la hora de reproducir las instrucciones, las escribo en cursiva dónde, con qué usuario y con qué derechos ejecuté el comando mientras escribo y reviso el artículo.

Instalación del respaldo

Repositorio (usuario pgbackrest):

1. Descargue el archivo desde pgbackrest y transfiera 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. Instale las dependencias necesarias para el montaje:

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

3. Montaje del respaldo:

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

4. Copie el archivo ejecutable en el directorio /usr/bin:

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

5. Pgbackrest requiere perl. Instalar:

sudo apt-get install perl

6. Cree directorios para registros, otorgue ciertos derechos:

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. Verifique:

pgbackrest version

Servidor Postgres (usuario sudo o root):

El proceso de instalación de pgbackrest en un servidor con postgres es similar al proceso de instalación en el repositorio (sí, pgbackrest debe estar instalado en ambos servidores), pero en el sexto párrafo el segundo y último manda:

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

reemplazar con:

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

Configurar 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 utilizando el archivo clave.

Repositorio (usuario pgbackrest):

Cree 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! Ejecutamos los comandos anteriores sin sudo.

Servidor Postgres (usuario sudo o root):

Cree 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):

Copie 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@<postgres_server_ip> cat /var/lib/postgresql/.ssh/id_rsa.pub) | 
       sudo -u pgbackrest tee -a /home/pgbackrest/.ssh/authorized_keys

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

Servidor Postgres (usuario sudo):

Copie 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@<repository_server_ip> cat /home/pgbackrest/.ssh/id_rsa.pub) | 
       sudo -u postgres tee -a /var/lib/postgresql/.ssh/authorized_keys

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

Comprobamos:

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

sudo -u pgbackrest ssh postgres@<postgres_server_ip>

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

sudo -u postgres ssh pgbackrest@<repository_server_ip>

Nos aseguramos de que obtendremos acceso sin problemas.

Configurar un servidor postgres

Servidor Postgres (usuario sudo o root):

1. Permitamos llamar al servidor postgres desde IP externas. Para hacer esto, edite el archivo. postgresql.conf (ubicado en la carpeta /etc/postgresql/11/main), agregando la línea:

listen_addresses = '*'

Si dicha línea ya existe, elimine el comentario o establezca el valor del parámetro en '*'.

En archivo pg_hba.conf (también ubicado en la carpeta /etc/postgresql/11/principal) agregue 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 - подключаемся через SSL (или нет)
all - разрешаем подключение ко всем базам
all - имя пользователя, которому разрешаем подключение (всем)
0.0.0.0/0 - маска сети с которой можно подключаться
md5 - способ шифрования пароля

2. Hagamos los ajustes necesarios en postgresql.conf (está en la carpeta /etc/postgresql/11/principal) para que pgbackrest funcione:

archive_command = 'pgbackrest --stanza=main archive-push %p' # Где main - название кластера. При установке postgres автоматически создает кластер main.
archive_mode = on
max_wal_senders = 3
wal_level = replica

3. Realicemos los ajustes necesarios 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=<repository_server_ip>

4. Vuelva a cargar postgresql:

sudo service postgresql restart

Configurar un servidor de repositorio

Repositorio (usuario de pgbackrest):

Hagamos los ajustes necesarios en el archivo de configuración. respaldo
(/etc/pgbackrest/pgbackrest.conf):

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

[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2 # Параметр, указывающий сколько хранить полных бэкапов. Т.е. если у вас есть два полных бэкапа и вы создаете третий, то самый старый бэкап будет удален. Можно произносить как "хранить не более двух бэкапов" - по аналогии с ротациями логов. Спасибо @Aytuar за исправление ошибки.
start-fast=y # Начинает резервное копирование немедленно, прочитать про этот параметр можно тут https://postgrespro.ru/docs/postgrespro/9.5/continuous-archiving

Creando un repositorio

Repositorio (usuario de pgbackrest):

Crear un nuevo almacenamiento para el clúster principal:

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

Проверка

Servidor Postgres (usuario sudo o root):

Comprobamos en el servidor postgres:

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

Repositorio (usuario de pgbackrest):

Verificamos en el servidor del repositorio:

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

Nos aseguramos de que en el resultado veamos la línea "comprobar fin del comando: completado con éxito".

¿Cansado? Pasemos a la parte más interesante.

Hacer una copia de seguridad

Repositorio (usuario de pgbackrest):

1. Realice una copia de seguridad:

sudo -u pgbackrest pgbackrest --stanza=main backup

2. Asegúrese de que se haya creado una copia de seguridad:

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

Pgbackrest creará la primera copia de seguridad completa. Si lo desea, puede ejecutar el comando de copia de seguridad nuevamente y asegurarse de que el sistema cree una copia de seguridad incremental.

Si desea volver a realizar una copia de seguridad completa, especifique una marca adicional:

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

Si desea una salida de consola detallada, especifique también:

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

Restaurar una copia de seguridad

Servidor Postgres (usuario sudo o root):

1. Detenga el clúster en ejecución:

sudo pg_ctlcluster 11 main stop

2. Restaurar desde una copia de seguridad:

sudo -u postgres pgbackrest --stanza=main --log-level-console=info --delta --recovery-option=recovery_target=immediate restore

Para restaurar la base de datos al estado de la última copia de seguridad COMPLETA, use el comando sin especificar recovery_target:

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

¡Importante! Después de la recuperación, puede suceder que la base de datos se atasque en el modo de recuperación (habrá errores como ERROR: no se puede ejecutar DROP DATABASE en una transacción de solo lectura). Para ser honesto, todavía no he entendido con qué está relacionado esto. La solución es la siguiente (deberá esperar un poco después de ejecutar el comando):

sudo -u postgres psql -c "select pg_wal_replay_resume()"

De hecho, es posible restaurar una copia de seguridad específica por su nombre. aqui estoy solo Proporcionaré un enlace a la descripción de esta característica en la documentación.. Los desarrolladores recomiendan utilizar esta opción con precaución y explican por qué. Puedo agregar por mi parte que lo usé. Si realmente lo necesita, asegúrese de que después de la recuperación la base de datos salga del modo de recuperación (seleccione pg_is_in_recovery() debería mostrar “f”) y, por si acaso, haga una copia de seguridad completa después de la recuperación.

3. Inicie el clúster:

sudo pg_ctlcluster 11 main start

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

Repositorio (usuario de pgbackrest):

sudo pgbackrest --stanza=main backup

Eso es todo. En conclusión, me gustaría recordarles que de ninguna manera intento pretender ser un dba senior y utilizaré las nubes en la menor oportunidad. Actualmente, yo mismo estoy empezando a estudiar diversos temas como respaldo, replicación, monitoreo, etc. y escribo pequeños informes sobre los resultados para hacer una pequeña contribución a la comunidad y dejarme pequeñas hojas de trucos para mí.

En los siguientes artículos intentaré hablar sobre funciones adicionales: recuperación de datos en un clúster limpio, cifrado de copias de seguridad y publicación en S3, copias de seguridad mediante rsync.

Fuente: habr.com

Añadir un comentario