Respaldo Continuo y Warm/Hot Standby
Las versiones más recientes de PostgreSql soportan varios modos de archivamiento (respaldo continuo) y servidores en espera (standby con recupero continuo)
Resumen de Modos de Operación:
- Continuous Archiving(online backup): archivamiento continuo (respaldos de los segmentos de WAL)
- Point-In-Time Recovery (PITR): recuperación en el tiempo (disaster recovery)
- Warm-standby: archivamiento + recuperación continua (high availability)
- Hot-standby: archivamiento + recuperación continua + consultas de solo lectura
Entorno
Para evitar errores, es conveniente definir las variables de entorno con directorios, binarios y configuraciones a utilizar:
export PGDATA=~/pg/data90 export PGBIN=~/pg/bin export PGPORT=5485 export PGDATABASE=correo export PGPORTNEW=5486
Configurar archivamiento
Para habilitar archivamiento en postgresql.conf, modificar las opciones de configuración:
wal_level = hot_standby # o archive archive_mode = on archive_command = 'cp -i %p ../archive/%f </dev/null' # Unix -i previene sobrescritura #archive_command = 'copy "%p" "C:\\server\\archivedir\\%f"' # Windows archive_timeout = 60 # forzar archivar cada 1 minuto
Según el modo, establecer wal_level a archive (solo recuperación continua) o hot_standby para que se guarden en los segmentos la información necesaria.
El archive_command debe copiar los segmentos a un directorio accesible por el servidor.
Iniciar archivamiento
Para comenzar a archivar, crear un directorio para los segmentos y reiniciar el servidor para que tome el cambio de configuración:
mkdir archive $PGBIN/pg_ctl -D $PGDATA restart
Asegurarse que se llene archivo
Verificar que comience a archivar, sino el directorio pg_xlog se llenará indefinidamente.
Se puede forzar la escritura de un segmento con pg_switch_xlog():
$PGBIN/psql -c "select pg_switch_xlog()"
Si el archivamiento funciona, un ls archive debería mostrar los segmentos copiados:
000000010000000000000004 000000010000000000000005
Iniciar respaldo
Una vez comenzado el modo de archivamiento, se debe indicar al servidor que se realizará un respaldo base que sea consistente mediante la función pg_start_backup().
El primer parámetro de la función es la etiqueta para marcar el backup. Este proceso puede demorar por checkpoint i/o, sino usar 2do param en true.
$PGBIN/psql postgres -c "SELECT pg_start_backup('respaldo');"
La salida esperada sería el punto de inicio del backup (se puede ignorar el resultado):
pg_start_backup ----------------- 0/5000020 (1 fila)
Copiar físicamente archivos respaldo base
Luego de indicar al servidor que comienza el backup, se debe realizar la copia de los archivos físicamente, por ej. con las siguientes órdenes:
mkdir respaldo chmod 700 respaldo cd $PGDATA ; cp -rvdpaf !(pg_xlog) ../respaldo; cd ..
También podría usarse tar, rsync o similar.
Detener respaldo consistente
Terminada la copia física de los archivos, se debe indicar que finaliza el backup con pg_stop_backup():
$PGBIN/psql postgres -c "select pg_stop_backup(), current_timestamp"
cuya salida será:
NOTICE: pg_stop_backup completado, todos los segmentos de WAL requeridos han sido archivados pg_stop_backup | now ----------------+------------------------------- 0/9000044 | 2010-12-28 01:42:12.138907-03 (1 fila)
Configurar recovery (en respaldo)
Cuando se desee recuperar el servidor de respaldo, se debe crear un archivo recovery.conf que indica al motor como realizar el proceso:
cat << eof > respaldo/recovery.conf restore_command = 'cp ../archive/%f %p' standby_mode = 'on' # recuperación continua, comentar si se des eof
Para detener la recuperación en un momento específico (PITR), utilizar las siguientes opciones de configuración en recovery.conf:
#recovery_target_time = '' # e.g. '2004-07-14 22:39:00 EST' #recovery_target_xid = '' #recovery_target_inclusive = 'true' #recovery_target_timeline = 'latest'
Si la recuperación se realiza en el mismo equipo, cambiar en respaldo/postgresql.conf la configuración general y desactivar el archivamiento:
port = 5486 # (para esta prueba, deshabilitar accesos si corresponde) hot_standby = on # habilitar consultas de solo lectura archive_mode = off
Recuperar
Una vez configurado el servidor de respaldo, para iniciar el proceso de recuperación iniciar el motor (previa limpieza del directorio de datos):
rm respaldo/postmaster.pid # borrar pid del principal rm respaldo/pg_xlog -Rv mkdir respaldo/pg_xlog # recrear directorio WAL bin/pg_ctl -D respaldo start
La salida esperada (en modo de recuperación normal) sería:
servidor iniciándose reingart@eepc:~/pg$ LOG: el sistema de bases de datos fue interrumpido; última vez en funcionamiento en 2010-12-28 01:40:47 ART LOG: creando el directorio WAL faltante «pg_xlog/archive_status» LOG: comenzando proceso de recuperación LOG: se ha restaurado el archivo «000000010000000000000005» desde el área de archivado LOG: redo comienza en 0/5000070 LOG: se ha restaurado el archivo «000000010000000000000006» desde el área de archivado LOG: se ha restaurado el archivo «000000010000000000000007» desde el área de archivado LOG: se ha restaurado el archivo «000000010000000000000008» desde el área de archivado LOG: se ha restaurado el archivo «000000010000000000000009» desde el área de archivado LOG: el estado de recuperación consistente fue alcanzado en 0/A000000 LOG: se ha restaurado el archivo «00000001000000000000000A» desde el área de archivado LOG: se ha restaurado el archivo «00000001000000000000000B» desde el área de archivado LOG: se ha restaurado el archivo «00000001000000000000000C» desde el área de archivado LOG: se ha restaurado el archivo «00000001000000000000000D» desde el área de archivado cp: no se puede efectuar «stat» sobre «../archive/00000001000000000000000E»: No existe el archivo o directorio LOG: no se pudo abrir «pg_xlog/00000001000000000000000E» (archivo de registro 0, segmento 14): No existe el archivo o directorio LOG: redo listo en 0/D3F4834 LOG: última transacción completada al tiempo de registro 2010-12-28 01:52:06.098197-03 LOG: se ha restaurado el archivo «00000001000000000000000D» desde el área de archivado cp: no se puede efectuar «stat» sobre «../archive/00000002.history»: No existe el archivo o directorio LOG: seleccionado nuevo ID de timeline: 2 cp: no se puede efectuar «stat» sobre «../archive/00000001.history»: No existe el archivo o directorio LOG: recuperación completa
Los errores de `cp' generalmente son inofensivos y señalan donde termina la recuperación (hasta que segmento de WAL se ha copiado y recuperado).
En modo de recuperación continua, la salida varía:
LOG: el sistema de bases de datos fue apagado durante la recuperación en 2010-12-28 03:57:43 ART LOG: entrando al modo standby LOG: se ha restaurado el archivo «00000001000000000000002F» desde el área de archivado LOG: redo comienza en 0/2F000020 LOG: el estado de recuperación consistente fue alcanzado en 0/30000000 LOG: el sistema de bases de datos está listo para aceptar conexiones de sólo lectura cp: no se puede efectuar «stat» sobre «../archive/000000010000000000000030»: No existe el archivo o directorio cp: no se puede efectuar «stat» sobre «../archive/000000010000000000000030»: No existe el archivo o directorio
Inspeccionar respaldo actualizaciones
Para probar la recuperación continua, en el servidor principal se puede correr pgbench para generar datos de prueba, forzar el transpaso de segmento de wal y verificar en el respaldo:
$PGBIN/psql -c "select count(*) from pgbench_history" $PGBIN/pgbench -t 1000 -p 5485 correo $PGBIN/psql -c "select count(*) from pgbench_history" $PGBIN/psql -c "select pg_switch_xlog()" $PGBIN/psql -p $PGPORTNEW -c "select count(*) from pgbench_history"
La salida debería indicar los registros modificados:
count ------- 1000 (1 fila)
Consejos ("TIPs")
Al utilizar recuperación continua:
- Usar REINDEX indices hash (no pasan por la WAL)
- No modificar templates al tomar el backup base
- Nuevos tablespaces -> rehacer backup base
- Comprimir segmentos WAL con pg_lesslog
Bibliografía
Para mayor información dirigirse a:
- Documentación Oficial
- PostgreSQL 9 Administration Cookbook, Simon Riggs - Hannu Krosing, Packt Publishing, 2010
