Índice del diarioDockup / nota de campo
Note / database-backups-you-have-restored

Un backup que nunca has restaurado no es un backup

Los backups de bases de datos que no se han probado fallan de formas predecibles: dumps vacíos, roles ausentes, flags incorrectos o ninguna clave de cifrado. Aprende a verificar una restauración para asegurarte de que el archivo que conservas funciona.

El peor momento para descubrir que un backup no funciona es cuando lo necesitas. Y, sin embargo, ese es exactamente el patrón más habitual: backups configurados una vez, un tick verde en un dashboard durante dieciocho meses y, después, una restauración que produce una base de datos vacía.

Probar la restauración de un backup de base de datos no es una best practice en el sentido en que la mayoría de las best practices son opcionales. Un backup es una afirmación y, hasta que no hayas restaurado uno, es una afirmación no verificada.

Así es como fallan y esto es lo que debe comprobar realmente una verificación.

Las cuatro formas en que un backup puede ser inútil sin que nadie lo note

1. Está vacío y nadie lo ha comprobado

Un pg_dump que falla a mitad del proceso puede seguir generando un archivo. Un dump ejecutado sobre el nombre de base de datos equivocado produce un archivo válido, correcto y vacío. Ambos parecen indicar que todo ha ido bien para cualquier sistema que solo compruebe que la salida no sea cero o que exista un archivo.

La comprobación más barata del mundo: mira el tamaño y compáralo con el de ayer. Un backup de 400 bytes cuando el de ayer tenía 40 MB te lo ha dicho todo. Un backup que lleva seis meses ocupando 400 bytes te lo ha estado diciendo desde el principio.

2. Contiene datos, pero no todo lo que los rodea

Un pg_dump de una sola base de datos no incluye roles ni otras bases de datos. Restáuralo en un servidor nuevo y las tablas llegarán, pero cada GRANT hará referencia a un rol que no existe. Tu app se conectará y obtendrá un error de permisos en todo.

Con las extensiones ocurre lo mismo. Si tu schema depende de pgcrypto o uuid-ossp y el destino no las tiene, la restauración fallará a mitad del proceso y te dejará con algunas tablas.

3. Los flags no eran los adecuados para la restauración que necesitas

pg_dump produce resultados distintos según el formato, y el error suele descubrirse bajo presión:

  • Plain SQL se restaura con psql y es legible para humanos. No se puede restaurar de forma selectiva y es lento para bases de datos grandes.
  • Custom format (-Fc) se restaura con pg_restore, admite paralelismo y restauraciones selectivas, y es lo que necesitas para cualquier base de datos de cierto tamaño.

Hacer el backup en formato plain porque así lo hacía el tutorial y descubrir durante un incidente que no puedes restaurar una sola tabla es una forma de pasar un mal día muy concreta y evitable.

4. No puedes descifrarlo

Si los backups están cifrados —y deberían estarlo—, la clave forma parte del backup. Una clave que solo existe en la máquina que se ha perdido o únicamente en una variable de entorno del servicio que está caído es una clave que no tendrás cuando la necesites.

Cómo es una verificación real

La prueba no consiste en «¿existe el archivo?». Consiste en restaurarlo en otro sitio y hacerle una pregunta.

# 1. Restore into a scratch database, not the live one
createdb verify_$(date +%Y%m%d)
pg_restore -d verify_$(date +%Y%m%d) --no-owner --no-privileges latest.dump

# 2. Ask it something only real data can answer
psql -d verify_$(date +%Y%m%d) -c "
  select
    (select count(*) from users)            as users,
    (select count(*) from orders)           as orders,
    (select max(created_at) from orders)    as newest_order;
"

# 3. Drop it
dropdb verify_$(date +%Y%m%d)

El paso 2 es el objetivo de todo esto. Que una restauración termine sin errores no te dice nada sobre si los datos están ahí. Los recuentos de filas y una comprobación de actualidad sí.

Hay tres aspectos que merece la pena validar:

  • Los recuentos de filas están en el orden de magnitud correcto. No tienen que ser exactos —los datos cambian—, pero una tabla que tenía 200.000 filas y ahora tiene 12 indica un fallo.
  • El registro más reciente es reciente. Si el pedido más reciente de tu backup «nocturno» es de marzo, tu backup job se detuvo en marzo.
  • La app puede conectarse de verdad. Apunta una instancia de staging a la base de datos restaurada y carga una página.

Hazlo con una frecuencia programada, no cuando te acuerdes

La frecuencia realista es mensual y automatizada, con el resultado en algún lugar donde vayas a verlo. Un recordatorio en el calendario para «probar los backups» es un recordatorio que pospondrás.

Lo que hace que esto funcione es hacer que el fallo sea evidente: si la query de verificación devuelve menos filas que un umbral, debería avisar a alguien del mismo modo que lo haría un error de producción. Un sistema de backups que falla en silencio no se distingue de no tener ningún sistema de backups, al menos hasta que llega el momento de necesitarlo.

Cómo gestiona esto Dockup

Tres decisiones, cada una orientada a uno de los fallos concretos anteriores.

Los backups se guardan en otro sitio. Un backup en el mismo disco que la base de datos no es un backup: es una copia que muere con el disco. Dockup transmite los backups de bases de datos directamente a object storage a medida que se generan, por lo que el archivo nunca depende del host que lo creó.

Están cifrados y la clave no está en la máquina. Los backups se cifran con AES-256-GCM mientras se transmiten. Lo importante para la recuperación es que la clave la gestiona la plataforma, en lugar de estar en el entorno del servicio del que se está haciendo el backup.

Un backup que no ha producido nada no se registra como backup. Esto aborda directamente el fallo de los archivos vacíos: si el dump termina con un código distinto de cero o produce cero bytes, la subida se elimina y el backup se registra como fallido. No acabas con una lista de entradas verdes en la que una de ellas es un archivo de 400 bytes.

dockup db backup my-project/main-db --json     # take one now
dockup db backups my-project/main-db --json    # list them with sizes

Los tamaños de ese listado son la comprobación de salud más barata que tienes. Observa su evolución.

La pregunta incómoda

Si tu base de datos de producción quedara destruida en los próximos diez minutos, ¿cuánto tardarías en recuperarla y cuántos datos perderías?

Si no puedes responder a ambas preguntas, no tienes una estrategia de backups: tienes archivos de backup. La diferencia está por completo en si alguien ha hecho alguna vez la restauración.

Preguntas frecuentes

¿Con qué frecuencia debería probar una restauración? Una vez al mes es una frecuencia predeterminada razonable, automatizada en lugar de manual. Lo importante es que el fallo sea evidente, no que la frecuencia sea especialmente alta.

¿Por qué la restauración terminó correctamente, pero no produjo datos? Normalmente, el dump se hizo sobre la base de datos equivocada o falló a mitad del proceso mientras seguía escribiendo el archivo. Compara los tamaños de los backups a lo largo del tiempo: un dump vacío resulta evidente en la evolución del tamaño e invisible en una columna de estado.

¿Deberían estar cifrados los backups? Sí, y la clave debe estar en un lugar que sobreviva a la pérdida de la máquina. Un backup cifrado cuya clave estaba en el servidor perdido no se puede recuperar.

¿Es un snapshot lo mismo que un backup? No. Un snapshot de volumen captura el disco, incluido el estado en el que se encontraba la base de datos en ese instante. Un dump lógico es consistente por construcción. La mayoría de los equipos quieren ambos, porque protegen frente a fallos diferentes.