Cuando trabajas como DBA debes realizar, como hemos mencionado en otras entradas, muchas tareas. Algunas, más básicas como crear usuarios, ampliar un tablespace u obtener alguna configuración específica de la BBDD. Otras, sin embargo, serán más elaboradas y tediosas, como instalar un entorno desde cero, hacer algún upgrade o configurar los backups.
Dentro de esta última tarea, claro está, vamos a tener muchas subtareas relacionadas. Porque no solo habrá que configurarlos, si no que deberemos comprobar que se realicen de forma correcta, que no haya problemas en las planificaciones y, además, hacer pruebas de restores ante posibles crisis.
Y en esa casuística, arrancamos esta entrada: restaurar PostgreSQL desde una copia física, es decir, desde un backup guardado o generado a disco, del propio directorio de datos o, lo que es lo mismo, del pg_data
. Es importante que entiendas que esta entrada NO TRATA de restaurar un backup generado con herramientas nativas de PostgreSQL como pg_dumpall
o pg_dump
.
Permitidme explicar brevemente el escenario: tenemos nuestra base de datos Postgres dentro de un pod de OpenShift y debemos comprobar que, a partir del último backup que tengamos, somos capaces de restaurar la BBDD y que quede funcionando sin ningún tipo de problema.
Al tratarse de un entorno productivo (independientemente de si es producción, preproducción o desarrollo), no podemos hacer dichas pruebas sobre el pod o el servidor en cuestión. Por ello, vamos a realizar la tarea en otro servidor.
No voy a entrar a desarrollar un caso específico como que es una base de datos de producción y que debemos restaurar no solo el último full backup, si no además, todos los WAL
(Write Ahead Logs) para dejar el estado lo más cercano a la antesala de la crisis. En este caso, solo voy a aplicar el último full backup del directorio de datos generado. Dejaremos la otra casuística para otra ocasión.
Bien, vamos a ello.
Como he dicho antes, esta prueba la realicé sobre un servidor dedicado a pruebas de restores. Así que el primer punto es comprobar que disponemos de la misma versión de PostgreSQL que en origen. En este caso, es la 13.7. Si no, como paso adicional, deberás instalar binarios de dicha versión.
Ahora, comprobamos que tenemos en el servidor de restores el comprimido de full backup de origen y un FS con espacio suficiente para restaurarlo, con una ruta de directorio definida.
postgres@restoreserv:/home/postgres$ cd /restores
postgres@restoreserv:/restores$ ls -ltr
-rw-r--r-- 1 postgres postgres 34383996 Jan 17 17:23 pgdata_postgresDW.tar.gz
postgres@restoreserv:/restores$ mkdir postgreDW
Perfecto. Ahora, descomprimimos el directorio del pg_data
de origen en esta ruta creada.
postgres@restoreserv:/restores$ tar -xvf pgdata_postgresDW.tar.gz -C ./postgreDW/
El siguiente punto va a ser definir un fichero de variables de entorno para cargarlo y poder trabajar directamente. La otra opción, si vas a hacer esta tarea en la misma sesión SSH sin ningún corte, es exportar dichas variables manualmente. Yo prefiero dejarlas en un fichero en el directorio home del usuario postgres.
postgres@restoreserv:/restores$ cd /home/postgres
postgres@restoreserv:/home/postgres$ vi pg_env.sh
Dentro de este fichero, pondremos las siguientes variables.
export PATH=/bin:$PATH:/usr/pgsql-13/bin
export PGDATA=/restores/postgreDW
export PGDATABASE=postgres
export PGUSER=postgres
export PGPORT=5432
export PGLOCALEDIR=/share/locale
export MANPATH=$MANPATH:/share/man
Recuerda que deberás adaptar estas variables a tu entorno. Quizás, tu tengas los binarios de Postgres en otra ruta (puedes ubicarlos con un find
) o vayas a levantar la instancia por otro puerto. Yo he puesto el puerto por defecto para esta prueba.
Ahora, debemos editar el fichero de configuración de PostgreSQL, llamado postgresql.conf
para adaptar las opciones necesarias. Si quieres, haz una copia por si las moscas.
postgres@restoreserv:/home/postgres$ cd /restores/postgreDW
postgres@restoreserv:/restores/postgreDW$ cp postgresql.conf postgresql.conf_old
postgres@restoreserv:/restores/postgreDW$ vi postgresql.conf
Yo en mi caso, he cambiado el puerto de la instancia y he comentado la línea correspondiente a un include
de OpenShift, además de deshabilitar el parámetro archive_command
, ya que no quiero que los WAL
generados los mueva a la ubicación de origen (más que nada, porque dicha ubicación en esta máquina no existe y porque no voy a generar WAL
al no hacer ninguna transacción en la BBDD).
Dicho esto, los cambios quedan tal que así:
#port = 5450
port = 5432
...
#include '/var/lib/pgsql/openshift-custom-postgresql.conf'
...
#archive_command = 'cp %p /opt/PostgresqlWalDW/archive/%f'
Recuerda también editar, por si acaso, el fichero pg_hba.conf
y deshabilitar todas las entradas correspondientes a las comunicaciones en origen.
Y por último, solo nos falta arrancar la instancia manualmente como root.
root@restoreserv:/# /usr/pgsql-13/bin/postmaster -D /restores/postgreDW
Este comando es muy sencillo: indicamos la ruta del binario postmaster
, ubicado en la carpeta de binarios de tu versión de PostgreSQL y la ruta donde está el pg_data
de la instancia que queremos levantar.
¡Listo! Si ahora lanzamos el comando psql
deberemos entrar en la herramienta de la consola de comandos y visualizar la versión. Además, podemos ver las BBDD que hay corriendo en la instancia que hemos levantado o el propio tamaño de alguna BBDD.
Recuerda volver a cargar las variables de entorno que definimos antes en el fichero pg_env.sh
ya que hemos salido de la sesión para levantar la instancia como root
.
postgres@restoreserv:/home/postgres$ . ./pg_env.sh
postgres@restoreserv:/home/postgres$ psql
psql (13.7)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+---------------+----------+------------+------------+-----------------------
PostgreDW | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)
Fin. Ya hemos podido restaurar PostgreSQL desde una copia física del pg_data
original. Esto quiere decir que nuestras políticas de backup se ejecutan correctamente y que, en caso de desastre, podremos tener una BBDD idéntica en pocos comandos.
¿Qué te ha parecido esta entrada? Espero tus reacciones en la caja de comentarios más abajo. Y si quieres ayudarme a que esta web se conozca más, no olvides compartir esta entrada con los botones sociales que tienes justo abajo.
Hasta la próxima, ¡un saludo!