Familiaridad con pg_probackup. La segunda parte

imagen



Seguimos familiarizándonos con la herramienta pg_probackup .



En la primera parte, instalamos pg_probackup, creamos y configuramos una instancia, tomamos dos copias de seguridad: completa e incremental en modo DELTA, y aprendimos cómo ver y cambiar la configuración de la instancia. Obtuvimos una lista de copias de seguridad, escribimos un script (bkp_base.sh) que realiza una copia de seguridad del clúster y envía los resultados de la última operación de copia de seguridad al sistema de monitoreo. Hoy abordaremos tareas no menos interesantes.



Problema 2



Dado: Tenemos dos servidores, en el primero tenemos nuestra base de datos (nombre de host srv_db1, usuario postgres), y en el segundo almacenaremos copias de seguridad (nombre de host srv_bkp, usuario backup_user). Pero además de las copias de seguridad en el mismo servidor, almacenaremos copias de los registros de pregrabación para poder restaurar a un punto arbitrario en el tiempo (recuperación a un punto en el tiempo) dentro de los últimos 3 días.



Solución:



Para poder restaurar al punto seleccionado en el tiempo (punto de restauración), debemos tener una copia de seguridad realizada antes del punto de restauración, así como todos los archivos WAL desde el momento en que comenzó la copia de seguridad hasta el punto de restauración.



Ya tenemos copias de seguridad, queda configurar el archivo WAL en srv_bkp.

Conéctese a srv_db1 usando el usuario de postgres y ejecute los siguientes comandos:



ssh-keygen -t rsa
ssh-copy-id backup_user@srv_bkp


Modifiquemos el archivo ~ / .ssh / autorized_keys a srv_bkp:



command="pg_probackup-12 agent" ssh-rsa AAAA....


De vuelta a srv_db1, debe habilitar el modo de archivo (archive_mode) y configurar el parámetro archive_command. Contiene un comando para realizar una copia de seguridad del segmento WAL completo.



psql -c 'show archive_mode'


si se apaga, cambia a encendido



psql -c 'alter system set archive_mode = on'


Para que se aplique el cambio, debe reiniciar PostgreSQL, pero por ahora pospondremos esta acción y configuraremos un parámetro más.



Si el flujo de archivos WAL es lo suficientemente grande, es posible que el servidor de respaldo pronto se quede sin espacio, por lo que podemos insertar la opción --compress en la línea archive_command, luego los archivos de registro se comprimirán antes de enviarse a srv_bkp. Y no tendremos que preocuparnos por el hecho de que estos archivos deberán descomprimirse por separado durante la recuperación: pg_probackup puede funcionar con archivos comprimidos.



alter system set archive_command = 'pg_probackup-12 archive-push -B /home/backup_user/backup_db --instance=db1 --wal-file-path=%p --wal-file-name=%f --remote-host=srv_bkp --remote-user=backup_user --compress';


Ahora puedes reiniciar.



Lo que hicimos en la primera tarea se llama copia de seguridad sin conexión. Se llama así porque dicha copia contiene todos los archivos WAL necesarios para restaurarla. En la tarea actual, estamos pasando de copias fuera de línea a copias de archivo, dichas copias no contienen los registros necesarios dentro de ellas, pero esto no importa, porque vamos a guardar todos los archivos WAL que necesitamos en un archivo. Al restaurar desde copias de seguridad, los archivos WAL se copiarán del archivo.



Dado que en la situación en cuestión estamos pasando de copias de seguridad fuera de línea (realizadas en modo de flujo) a archivadas (en modo de archivo), puede surgir una situación en la que hagamos una copia cuando el modo de archivo aún no estaba habilitado, después de lo cual algunos de los segmentos WAL ya han aparecido. remoto. Esto significa que la primera copia de seguridad después de cambiar al modo de archivo no se puede realizar en el modo PAGE, porque el segmento de WAL en el archivo entre el pasado y la copia actual puede no estar completo.



Hagamos esto usando el script creado en la primera tarea:



./bkp_base.sh DELTA


Luego crearemos nuestra primera copia de seguridad en modo PAGE



./bkp_base.sh PAGE


Permítame recordarle que hay tres modos incrementales disponibles: PAGE, DELTA y PTRACK. Se diferencian entre sí en las formas de obtener la información necesaria sobre las páginas modificadas:



  • DELTA ,
  • PAGEWAL , ,
  • PTRACK — - Block Change Tracking Oracle — , . ( ..). , .


Ahora pensemos, la copia de seguridad, para poder recuperarla, necesita los archivos WAL creados durante la creación de la copia de seguridad. Aquellos. si hacemos una copia de seguridad incremental durante 30 minutos y durante estos 30 minutos se crearon 10 GB de WAL, entonces solo se necesitan estos 10 GB para que podamos recuperarnos consistentemente. Todos los demás archivos WAL son necesarios solo con el fin de recuperarlos en un punto en el tiempo seleccionado (recuperación en un momento determinado).



La tarea indicó que queremos poder recuperarnos en cualquier momento durante los últimos 3 días. Es decir, todos los WAL para este período deben guardarse, además, es necesario guardar todos los WAL que se necesitan para restaurar desde copias de seguridad anteriores, ¡pero no necesitamos almacenar todos los demás archivos WAL!



Y, si podemos usar el comando find para eliminar los WAL obsoletos, agregando mtime y -exec rm {}, entonces determinar qué segmento de WAL se necesita para restaurar consistentemente una copia de seguridad en particular no es una tarea fácil. Es bueno que los desarrolladores hayan pensado en esto y hayan agregado el parámetro --wal-depth, con el que puede configurar la profundidad de almacenamiento de WAL, calculada en las copias de seguridad.



Se puede describir esquemáticamente de la siguiente manera:







Tenga en cuenta que ahora está en algún lugar a la mitad del sábado, lo que significa que podemos eliminar todos los archivos WAL que no son necesarios para restaurar copias de seguridad de más de tres días (color marrón en el gráfico). Los WAL que aún se necesitan están resaltados en amarillo. Aquí puede surgir una pregunta lógica, pero después de todo, ya es la mitad del sábado, lo que significa que algunos de los registros matutinos creados el miércoles ya no son necesarios y se pueden eliminar. Sí, así es, y puedes configurar el borrado del exceso de WAL al menos cada minuto, pero en nuestro artículo borraremos los logs junto con la creación de las copias de seguridad, por lo que a pesar de que ya no entran en la política de retención, se borrarán al crear la siguiente copia de seguridad. ...



Cambie la configuración de la instancia db1: agregue la vida útil de los archivos WAL



pg_probackup set-config --instance db1 --wal-depth=3


Comprobemos que se han aplicado los ajustes:



pg_probackup show-config --instance=db1 | grep wal-depth


Agregue el indicador --delete-wal al comando de respaldo en el script bkp_base.sh , y también elimine la clave --stream, porque estamos pasando de respaldos fuera de línea a respaldos archivados



pg_probackup backup --instance=db1 -j 2 --progress -b $1 --compress --delete-expired --delete-wal


Por el momento, hemos configurado la creación de copias de seguridad de archivos en un servidor separado. Además, los archivos de registro se agregan aquí, lo que nos brinda la oportunidad de usar la recuperación no solo para una copia de seguridad específica, sino también para realizar una recuperación en un momento determinado: recuperación en un momento específico.



Dado que ahora tenemos un archivo de archivos WAL, podemos usar el modo PAGE para crear copias de seguridad incrementales, permítame recordarle que en este modo, los cambios relativos a la copia de seguridad anterior no se calculan por archivos de datos, sino por WAL acumulados desde la copia de seguridad anterior.



PD ¡Solo con fines educativos! Creemos una tabla en la base de datos del servidor srv_db1:



psql -c 'create table timing(time_now timestamp with time zone)'


Luego escribiremos la siguiente línea en crontab:



* * * * * psql -c 'insert into timing(select now())'


Cada minuto, se registrará información sobre la hora actual en la base de datos, esta información nos será útil cuando restauremos a un punto en el tiempo.



Problema 3



Dado:



Tenemos dos servidores, en el primero tenemos nuestra base de datos (nombre de host srv_db1, usuario postgres), en el segundo almacena copias de seguridad archivadas y archivos WAL (nombre de host srv_bkp, usuario backup_user). En nuestro entorno aparece otro servidor srv_db2 (usuario postgres), en el que tendremos que desplegar una réplica de nuestro clúster y reconfigurar pg_probackup para que tome copias de seguridad de la réplica.



Decisión:



Internet está lleno de descripciones de cómo crear réplicas en PostgreSQL, todo lo que necesita hacer es impulsar "crear una réplica en PostgreSQL" en el motor de búsqueda - ¡elija, no quiero! Hay documentación, artículos e incluso videos tutoriales. Y todos estos métodos son buenos, pero no suelen tener en cuenta que ya tenemos copias de seguridad. Queremos crear una réplica utilizando una copia de seguridad, por lo que eliminamos la carga de lectura del maestro. Es decir, nuestro servidor de producción no se dará cuenta de que en algún lugar junto a él se está creando una réplica (esto, por supuesto, con reservas; aquí será necesario crear la ranura de réplica y establecer los derechos de acceso, pero mientras creamos una réplica, no hay carga adicional en el maestro. no será).



Configuramos el acceso por claves entre los servidores srv_bkp y srv_db2, instalamos PostgreSQL y pg_probackup en srv_db2 (hicimos todo menos la instalación de PostgreSQL durante la primera tarea, pero si tiene alguna pregunta sobre la instalación del DBMS, eche un vistazo aquí ).



Ir a srv_db2



ssh-keygen -t rsa
ssh-copy-id backup_user@srv_bkp


Ir a srv_bkp



ssh-copy-id postgres@srv_db2


Activemos nuestro paranoico interno y editemos ~ / .ssh / autorized_keys - insert



command="pg_probackup-12 agent"


antes de nuevas llaves.



Usar archivos WAL es mucho más lento que restaurar a partir de una copia de seguridad, así que creemos otra copia de seguridad incremental: conéctese al servidor srv_bkp usando backup_user y ejecute el comando:



pg_probackup backup --instance=db1 -j 2 --progress -b PAGE --compress


¿Por qué no usamos el script que creamos? El hecho es que anteriormente agregamos la opción --delete-wal al script, es decir, después de crear esta copia de seguridad, no podríamos restaurar a un punto en el tiempo que era hace tres días. Pero si dejamos esta copia de seguridad, la siguiente copia de seguridad realizada mediante la ejecución de nuestro script seguirá saliendo de WAL solo durante los últimos dos días, es decir, después de que nos recuperemos de esta copia de seguridad, tiene sentido eliminarla.



Hacemos recuperación:



time pg_probackup restore --instance=db1 -D /var/lib/pgsql/12/data -j 2 --restore-as-replica --progress --remote-proto=ssh --remote-host=srv_db2 --archive-host=srv_bkp --archive-user=backup_user --log-level-console=log --log-level-file=verbose --log-filename=restore_rep.log


El directorio / var / lib / pgsql / 12 / data debe estar vacío, además, en el servidor srv_db1, debe realizar cambios en pg_hba.conf - permitir el acceso desde el servidor srv_db2 usando el protocolo de replicación.



host    replication     all             srv_db2                 md5


Volvemos a leer la configuración:



psql -c 'select pg_reload_conf()'


Comprobación de errores tipográficos:



psql -c 'select * from pg_hba_file_rules'


creamos un archivo ~ / .pgpass en srv_db2, en el que especificamos los permisos de conexión en srv_db1 pero esta vez con la base de replicación e iniciamos PostgreSQL.



srv_db1:5432:replication:backup:Strong_PWD


Y cambiemos sus derechos a 600:



chmod 600 ~/.pgpass


Iniciamos el clúster en srv_db2.



Comprobemos que todo funciona bien. Usaremos las siguientes posibilidades para esto.



Miramos en el archivo de registro de réplica, en algún lugar cerca del final, debería aparecer la siguiente línea:



Database system is ready to accept read only connections


psql -c 'select pg_is_in_recovery()' 


debería devolver t



Ahora creemos una placa t1 en el asistente:



srv_db1: psql -c 'create table t1()'


Comprobemos si apareció en la réplica.



srv_db2: psql -c '\d'


La placa está en su lugar, entonces la replicación está funcionando. Quitamos la placa del maestro.



srv_db1: psql -c 'drop table t1'


Por supuesto, en una base de datos real, ahora sería necesario crear una ranura de replicación en el maestro y configurar la réplica para que vaya al maestro a través de esta ranura, pero el tema de nuestro artículo no son las réplicas, sino las copias de seguridad, así que continuaremos.



Entonces, la réplica nos funciona, si es necesario, podemos cambiar a la réplica, pero hagámonos una pregunta: ¿podemos hacerlo mejor?

Por supuesto que puede. ¿Por qué necesitamos realizar copias de seguridad del maestro cuando podemos eliminar la carga de lectura del maestro y transferirla a una réplica?



¡PRECAUCIÓN! EL MONITOREO DE FALTA DE RÉPLICA DEBE SER MONITOREADO, DE LO CONTRARIO PUEDE DARSE DE QUE USTED NO SABERÁ QUE LA RÉPLICA SE HA RETRASADO Y CONTINUARÁ HACIENDO COPIA DE SEGURIDAD DEL RETRASO DE RÉPLICA.



¡Vamos a hacer eso!



Realizamos cambios en la configuración del clúster en los servidores srv_db1 y srv_db2:



alter system set archive_timeout=180;
select pg_reload_conf();


Vaya a srv_bkp y cambie el valor del parámetro de host remoto:



pg_probackup set-config --instance db1 --remote-host=srv_db2


Hacemos cambios a .pgpass en el servidor srv_bkp - agregue las cadenas de conexión al servidor srv_db2:



srv_db2:5432:replication:backup:Strong_PWD
srv_db2:5432:backupdb:backup:Strong_PWD


E intentemos hacer otra copia de seguridad.



srv_bkp: ./bkp_base.sh PAGE


Vemos que la copia de seguridad ha funcionado.



¡El problema esta resuelto!



La siguiente parte estará dedicada a la restauración desde copias de seguridad: consideraremos varias opciones de recuperación, aprenderemos cómo restaurar a una copia de seguridad específica, a un punto en el tiempo, nos familiarizaremos con las restauraciones parciales e incrementales.



All Articles