PostgreSQL es mi DeLorean: Viajando en el Tiempo con Point-in-Time Recovery (PITR)

PostgreSQL es mi DeLorean: Viajando en el Tiempo con Point-in-Time Recovery (PITR)

TL;DR
¿La has liado parda borrando datos en producción? No pasa nada, McFly. Con Point-in-Time Recovery (PITR) de PostgreSQL puedes volver al segundo exacto antes del desastre. Te explico qué es esta brujería, por qué es tu mejor seguro de vida contra los "ups, la cagué", y cómo montarte tu propio condensador de flujo con backups base y archivado de WALs. No se necesitan 1.21 gigavatios, pero casi.

Vale, sinceridad ante todo. ¿Quién no ha sentido ese sudor frío, ese microinfarto que te recorre el cuerpo justo después de ejecutar un UPDATE o un DELETE en producción y darte cuenta de que se te ha olvidado el WHERE? Es un rito de iniciación. En ese momento, en ese instante en el que el universo se congela, solo deseas dos cosas: que nadie se dé cuenta y tener un DeLorean para volver 30 segundos atrás y darte un capón a ti mismo.

Pues bien, aunque conseguir un deportivo que viaja en el tiempo está complicado (y el plutonio ni te cuento), en el mundo de PostgreSQL tenemos algo que se le parece peligrosamente: la Recuperación a un Momento Concreto, o como nos gusta llamarlo a los frikis, Point-in-Time Recovery (PITR).

Y no, no es el típico "restauro el backup de anoche y que Dios reparta suerte". PITR es una máquina del tiempo de precisión quirúrgica. Te permite decirle a tu base de datos: "Eh, mira, son las 10:41 AM. Pues quiero que vuelvas a ser exactamente como eras a las 10:37:15 AM, justo antes de que mi cerebro hiciese cortocircuito". Y la tía va y lo hace. Es la diferencia entre un despido y una anécdota divertida para contar en la cena de empresa.

¿Por qué necesitas esto en tu vida, pero ya?

Si piensas que con el backup nocturno vas sobrado, es que vives al límite, y no en el buen sentido. En un entorno de producción, los datos son sagrados. PITR es tu póliza de seguro contra el apocalipsis digital. Es la red de seguridad para cuando:

  • El factor humano ataca: El clásico "borré la tabla de usuarios" o "actualicé todos los precios a 1€". Errores tontos que nos pasan a todos. Con PITR, la catástrofe se convierte en un susto de cinco minutos.
  • Tus datos se corrompen: A veces, las cosas se rompen solas. Una actualización de software que sale mal, un bug escondido o una tormenta solar (bueno, vale, esto último es menos probable) pueden dejar tus datos hechos un Cristo. PITR te deja volver a un estado sano y conocido.
  • El servidor se convierte en una tostadora: Si el hardware decide inmolarse, PITR es una pieza clave de tu plan de recuperación ante desastres. Te permite levantar un nuevo servidor y perder, como mucho, los datos de los últimos segundos, no de las últimas 24 horas.

En resumen, no tener PITR es como ir por la vida sin copias de seguridad de tus fotos: todo va bien hasta que un día, simplemente, deja de ir bien. Y entonces vienen los lloros.

Los ingredientes del viaje: WAL y Backups Base

Para que esta magia funcione, PostgreSQL se apoya en dos colegas que trabajan juntos mejor que Marty y el Doc Brown:

  1. La copia de seguridad base (Base Backup): Esto es tu punto de partida. Imagina que congelas el tiempo y sacas una foto perfecta y consistente de toda tu base de datos en un instante concreto. Para esto, se suele usar la herramienta pg_basebackup. Esta es tu "versión estable" de la realidad, tu "1985" al que siempre puedes regresar.
  2. Los registros de escritura anticipada (Write-Ahead Logs o WALs): ¡Aquí está el condensador de flujo, amigos! Los ficheros WAL son el diario personal de tu base de datos. Son una lista obsesiva y detallada de CADA maldito cambio que ocurre. ¿Un INSERT? Apuntado. ¿Un UPDATE? Registrado. ¿Un DELETE? Lo anota todo. Normalmente, Postgres los va borrando, pero con PITR los "archivamos" en un lugar seguro, creando una cronología perfecta de todo lo que ha pasado desde la última "foto".

La mecánica es de una simpleza aplastante: coges tu foto (el backup base), la pones en el proyector y luego le dices a PostgreSQL: "ahora, reproduce a cámara rápida todo lo que ha pasado (los WALs) hasta este momento exacto". Y ¡boom!, has vuelto al futuro que querías.

Manos a la obra: Configurando tu propia máquina del tiempo

Venga, vamos al lío. Configurar esto no requiere 1.21 gigavatios, pero sí tocar un par de líneas en tu postgresql.conf con cariño.

Paso 1: Dile a Postgres que no sea un ansias y guarde los WALs

Por defecto, Postgres es muy de "usar y tirar" con los WALs. Vamos a cambiarle esa mentalidad.

Abre tu postgresql.conf:

# Primero, el nivel de 'chismorreo' del WAL. Necesitamos que sea hablador.
wal_level = replica

# ¡Great Scott! ¡Activamos el modo archivo! Esto es clave.
archive_mode = on

# Ahora le decimos QUÉ hacer con cada fichero WAL que llene.
# El comando más simple es copiarlo a otra carpeta.
# '%p' es el path del fichero y '%f' es el nombre. No lo toques.
archive_command = 'cp %p /var/lib/postgresql/wal_archive/%f' 

Ojo, ese cp es un ejemplo de andar por casa. En un entorno serio, seguramente usarías un scp para mandarlo a otro servidor o un script que lo comprima y lo suba a S3, R2 o donde te dé la gana. Lo importante es que ese comando funcione y devuelva un 0 si todo ha ido bien.

Paso 2: Saca la primera foto (Backup Base)

Con el archivado funcionando, es hora de crear nuestro punto de partida.

# Conéctate a tu servidor y lanza esto.
# -D es el directorio donde guardarás el backup. El resto es autoexplicativo.
pg_basebackup -h localhost -D /var/lib/postgresql/backup/base -U postgres -p 5432 -v -P

Esto te creará una copia limpita de tu base de datos, lista para la acción.

Paso 3: ¡Acelera a 88 mph! La recuperación

Ha pasado. La has liado. Mantén la calma.

  1. PARA LA MÁQUINA: sudo systemctl stop postgresql. Detén el estropicio.
  2. Limpia y restaura: Bórralo todo (rm -rf /var/lib/postgresql/14/main/*). Sí, sin miedo. Ahora, copia los ficheros de tu backup base a ese directorio.
  3. Prepara el viaje en el tiempo: En el directorio de datos que acabas de restaurar, crea un fichero vacío llamado recovery.signal. Esto le dice a Postgres que al arrancar, tiene que entrar en modo "voy a arreglar un marrón".
  4. Añade la configuración de recuperación a tu postgresql.conf:
# El comando inverso al de archivar. ¿De dónde tiene que pillar los WALs?
restore_command = 'cp /var/lib/postgresql/wal_archive/%f %p'

# ¡El momento clave! ¿A qué puto instante quieres volver?
# Formato: 'AAAA-MM-DD HH:MI:SS'
recovery_target_time = '2025-08-27 10:37:15'
  1. Arranca de nuevo: sudo systemctl start postgresql. Verás en los logs cómo empieza a "reproducir la cinta" de los WALs. Se detendrá justo en el momento que le has dicho. Cuando termine, borrará el recovery.signal y tu base de datos estará viva, sana y exactamente como estaba antes del desastre.

¿Y si soy un vago y uso Cloud?

Pues estás de suerte. Si usas servicios como Amazon RDS, Google Cloud SQL o Azure Database for PostgreSQL, todo este tinglado te lo dan prácticamente hecho. Ellos se encargan de los backups y del archivado de WALs de forma automática. Activar PITR suele ser tan fácil como hacer clic en un botón y decidir cuántos días de "historial" quieres guardar. La restauración normalmente te crea una base de datos nueva, clonada al punto que tú elijas, para que no la líes aún más sobreescribiendo la de producción.

Conclusión: No se necesitan carreteras

PITR es una de esas funcionalidades que, hasta que no la necesitas, no valoras lo suficiente. Pero cuando te salva el culo, le pones un altar. Es la máxima tranquilidad para cualquier persona que gestione una base de datos en producción.

Así que deja de rezarle a cualquier proveedor cloud y empieza a confiar en el poder del self-hosting bien hecho. No esperes a que un Biff Tannen cualquiera te tire un DROP DATABASE. Monta tu PITR. Tu "yo" del futuro, ese que acaba de evitar un marrón de proporciones épicas, te lo agradecerá eternamente.

Como siempre, espero que os haya molado el post. Nos vemos en la red <3.