Portal en español sobre PostgreSQL

Usando PITR - Point in Time Recovery

servidor

PITR - Point in Time Recovery es un tipo de backup avanzado utilizado en sistemas PostgreSQL que trabajan con datos importantes los cuales no pueden perderse en caso de fallo.

Este artículo es un poco avanzado, largo y no muy interesante para pequeños sistemas sin grandes requerimientos de seguridad en lo concerniente a la perdida de datos por problemas de hardware. Necesitais conocimientos de administración de sistemas Linux/Unix y como trabajar con LVM (Linux Volume Manager) para administrar vuestros discos y particiones.

La teoria es fácil de entender, pero la práctica y la administración de este tipo de copias de seguridad es complicado y engorroso si queremos estar seguros de la calidad y utilidad de las mismas. PostgreSQL nos proporciona la infraestructura necesaria para poder realizar backups del tipo PITR, pero somos nosotros los que debemos de crear todo lo necesario para ponerla en uso.

Introducción

PITR no es otra cosa que el almacenamiento y copia continua de todas las transacciones producidas por PostgreSQL desde el ultimo backup realizado a nivel de sistema de fichero. Esta copias de seguridad se podran usar en caso de un fallo grave de hardware con perdida de la zona de datos, ó de necesidad de restaurar nuestra base de datos en un determinado momento del pasado.

PITR funciona de la siguiente manera cuando está activado:

  • PostgreSQL almacena todos los ficheros WAL (Write Ahead Log - información sobre las transacciones realizadas) generados por el sistema. Este almacenamiento es continuo y no parará una vez activado
  • Cada cierto tiempo debemos de realizar la denominada copia de seguridad base. Esta copia de seguridad se realiza a nivel del sistema de ficheros, sin apagar PostgreSQL y sin procuparnos de lo inconsistente que sea por ello.
  • Una vez terminada la copia de seguridad base habrá que borrar todos ficheros WAL antiguos que no se necesiten.
  • En caso de catástrofe, podremos utilizar nuestra copia de seguridad inconsistente, copia de seguridad base, más todos los ficheros WAL archivados desde el termino de esta copia hasta el momento del fallo, para restaurar nuestra base de datos a un estado consistente y sin perdida de datos.
  • De la misma manera se puede devolver a la base de datos al estado en que se encontraba en un determinado momento, de ahi que se llame "recuperacion a un punto del tiempo"

Implementando PITR en nuestro sistema

A continuación vamos a ver como se puede administrar todo esto, las reglas a seguir y lo que necesitamos hacer para poder empezar a utilizar PITR en nuestro sistema:

  • Todos los datos se basan en la versión 8.3.x de PostgreSQL
  • Las particiones de datos/WAL y las de backup tienen que encontrarse en discos diferentes. Esto es importantisimo. Los sistemas donde se utiliza PITR, suelen estar conectados a cabinetes externos de discos totalmente independientes unos de otros, con redundancia de componentes a diferentes niveles y RAID. El mínimo absoluto que se necesita para garantizar los datos si utilizais un servidor con discos internos es que los datos/WALs y los backups esten en dos discos independientes.
  • Vamos a utilizar la funcionalidad LVM-snapshot proveida por Linux Volume Manager para crear las copia de seguridad base y minimizar la inconsistencia de esta copia. Esto suele ayudar bastante en sistemas con bases de datos grandes y actualizadas constantemente.

    El grupo de volúmenes (VG) utilizado para albergar el volumen lógico (LV) utilizado para la partición de datos, debe de tener espacio libre suficiente para poder realizar un LVM-snapshot del LV de datos. Cuanto espacio extra libre se necesitará, dependerá de lo mucho que cambien vuestros datos en el LV mientras que el LVM-snapshot esta activo. Con un 25% de espacio libre en el VG deberiais de tener más que suficiente. El informe mandado al final por pitr_basebackup.sh incluye información sobre cuanto espacio se ha utilizado, el atributo con esta informacion es Allocated to snapshot

  • archive_wal.sh se va a utilizar por PostgreSQL para archivar continuamente todos los ficheros WAL generados.
  • archive_last_wal.sh se va a ejecutar via cron para archivar el último fichero WAL en uso residente en el directorio pg_xlog y que todavia no se ha archivado por PostgreSQL
  • pitr_basebackup.sh se va a ejecutar via cron para crear una copia de seguridad de la partición de datos a nivel de sistema de ficheros, y para borrar todos los ficheros WAL archivados que ya no se necesitan

Un sistema de almacenamiento ideal para nuestro sistema podria tener esta configuración:

Dependiendo de la complejidad y redundancia de nuestro sistema este esquema puede variar. El más simple de todos solo tendria dos discos, uno para datos/WAL y otro para backup/logs, no tendria RAID y solamente un VG con un LV para la particion de datos y espacio libre para el snapshot.

Scripts de administración de PITR

Para administrar PITR vamos a utilizar 3 scripts en BASH, pitr_basebackup.sh, archive_wal.sh y archive_last_wal.sh. Los podeis grabar en un directoria que este definido en vuestro PATH, por ejemplo /usr/local/bin

Estos 3 scripts han estado en uso en la Universidad de Oslo durante varios años realizando sus trabajo sin problemas. Para que os hagais una idea, durante el último año ejecutamos pitr_basebackup.sh aproximádamente unas 3.650 veces, archive_last_wal.sh unas 5.256.000 y archive_wal.sh unas 500.000 veces. Muchas de las comprobaciones que hacen son para asegurarse que todo funciona sin problemas y para mandar informes despues de haber descubierto problemas y fallos durante situaciones no planeadas (discos llenos, etc).

Al final de este artículo teneis los tres scripts a modo de ejemplos para que veais como están implementados. Si quereis utilizarlos vais a tener que modificar algunas de las variables para adaptarlos a vuestro sistema. Las versiones de estos scripts que nosotros tenemos en uso som más completas ya que están integradas en nuestro sistema de administración y entre otras cosas graban el estatus de las ejecuciones en una base de datos interna.

A continuación teneis una descripción de las tareas que estos scripts realizan:

archive_wal.sh

  • Comprobar que la partición para archivar ficheros WAL existe
  • Comprobar que la partición donde se generan ficheros WAL existe
  • Comprobar que el fichero WAL que se intenta archivar no está ya archivado
  • Archivar el fichero WAL definido en la partición para archivar ficheros WAL

archive_last_wal.sh

  • Borrar los archivos WAL obsoletos grabados en la partición para archivar el último fichero WAL en uso, residente en el directorio pg_xlog
  • Archivar el último fichero WAL en uso residente en el directorio pg_xlog y que todavia no se ha archivado

pitr_basebackup.sh

  • Comprobar que la partición para archivar el fichero con copia de seguridad base existe
  • Estimar el espacio necesario para crear copia de seguridad base y parar el script para evitar problemas si estimamos que la partición se va a llenar durante le ejecución de este script.
  • Comprobar que no se esta generando una copia de seguridad base
  • Registrar el comienzo de la copia de seguridad base con pg_start_backup()
  • Crear un LVM-snapshot de la partición de datos
  • Montar el volumen que contien el LVM-snapshot
  • Crear un fichero tar de todo el contenido en el volumen LVM-snapshot
  • Desmontar el volumen que contien el LVM-snapshot
  • Destruir el contenido del LVM-snapshot
  • Registrar el final de la copia de seguridad base con pg_stop_backup()
  • Archivar el último fichero WAL en uso residente en el directorio pg_xlog y que todavia no se ha archivado
  • Borrar los archivos WAL obsoletos
  • Borrar los ficheros con copia de seguridad base obsoletos
  • Generar informe de la ejecución

Usando los scripts de administración de PITR

archive_last_wal.sh se ejecutará cada minuto por el usuario 'postgres' desde cron. Para ello teneis que actualizar el fichero cron del usuario postgres con esta linea:

*  *  *  *  *   /usr/local/bin/archive_last_wal.sh -S hostname

archive_wal.sh se ejecutará automaticamente por postgreSQL cuando lo necesite. Para que esto ocurra tendreis que activar PITR en el fichero postgresql.conf definiendo estas dos lineas:

archive_mode = on           
archive_command = '/usr/local/bin/archive_wal.sh -P %p -F %f -S hostname'

pitr_basebackup.sh se tiene que ejecutar tambien por el usuario 'postgres' desde cron. Dependiendo de lo grande que sea vuestra instalación PostgreSQL y lo mucho que los datos cambien en la misma, tendreis que ejecutar este script más ó menos a menudo. Si dejais pasar mucho tiempo entre cada ejecución y teneis una instalación que genere muchos ficheros WAL, tardareis mucho en restaurar el sistema si teneis que hacer esto alguna vez.

Yo suelo ejecutarlo una vez al dia por la noche. Podeis por ejemplo actualizar el fichero cron del usuario postgres con esta linea:

01  03  *  *  *  /usr/local/bin/pitr_basebackup.sh -S hostname -c t 

Como veis, todos estos scripts se ejecutan por el usuario postgres. Por ello tendreis que actualizar el fichero /etc/sudoers con la siguiente linea:

postgres  ALL = NOPASSWD: /usr/sbin/lvcreate, /usr/sbin/lvremove, 
/usr/sbin/lvdisplay, /usr/sbin/vgdisplay, /bin/mount, /bin/umount

El usuario postgres tiene que poder conectarse al cluster PostgreSQL via sockets y sin clave. Más información sobre como configurar la cuanta de administrador postgres, se puede encontrar en el artículo Asegurando la cuenta de administrador "postgres".

Restaurar datos

Si tuvieramos que restaurar los datos de nuestro cluster PostgreSQL a partir de las copias de seguridad realizadas por estos scripts tendriamos que realizar las siguientes operaciones:

  • Si existe algún fichero en $PG_DATA_PARTITION, borrarlo.
  • Si existe algún fichero en $PG_ARCH_PARTITION, borrarlo.
  • Descomprimir en $PG_DATA_PARTITION la copia de seguridad base (fichero tar) grabado en $PG_BACKUP_PITR_DATA
  • Asegurarse que $PG_DATA_PARTITION y $PG_ARCH_PARTITION y sus contenidos tienen al usuario postgres como dueño
  • Copiar a $PG_BACKUP_PITR_WAL el fichero WAL grabado en $PG_BACKUP_PITR_LAST
  • Cambiar el nombre del directorio $PG_BACKUP_PITR_WAL a ${PG_BACKUP_PITR_WAL]_restore
  • Crear un directorio con el nombre $PG_BACKUP_PITR_WAL
  • Asegurarse que todos los ficheros WAL en ${PG_BACKUP_PITR_WAL]_restore tienen permisos de escritura para el usuario postgres
  • Borrar los ficheros postmaster.pid y postmaster.opts en $PG_DATA_PARTITION
  • Crear en $PG_DATA_PARTITION un fichero llamado recovery.conf con esta linea:
    restore_command = 'cp ${PG_BACKUP_PITR_WAL]_restore/%f %p'
    
  • Cambiar archive_mode a 'off' y listen_addresses a '' en el archivo postgresql.conf
  • Arrancar PostgreSQL
  • Esperar a que termine el proceso de restauración. Podeis comprobar cuando ha terminado cuando estas dos lineas aparezcan en el fichero log de PostgreSQL:
    LOG: archive recovery complete
    LOG: database system is ready
    
  • Cambiar archive_mode a 'on' y listen_addresses a su valor original
  • Apagar y arrancar PostgreSQL
Los valores de las variables en esta lista están definidas en los tres scripts.

Más información

Scripts

Aqui teneis los tres scripts de los que hablamos en este artículo liberados bajo la licencia GPLv3. Tendreis que actualizar las variables definidas al principio de los mismos para adaptarlas a vuestros sistemas. Es importante que tengais la configuración LVM de vuestro sistema correctamente configurada para que estos scripts funcionen.
AdjuntoTamaño
pitr_basebackup_sh.37.92 KB
archive_wal_sh.14.28 KB
archive_last_wal_sh.9.01 KB

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de webmaster

Nueva version

Estamos preparando una nueva version de estos scripts que usa un fichero global de configuración para evitar configuración redundante.

Sugerencias

Tratándose de sistemas linux, esta bastante correcto, pero tratando de sistemas como freebsd o solaris, basta con definir 2 raidz en mirrors (zfs) o 2 raidz2(doble paridad), y tienes asegurada la integridad de los datos, igual con freebsd con unas cuantas clases de geom se puede conseguir lo mismo, por lo que teniendo un mirror de un raidz y ademas siempre tener una copia diaria de la db en otro disco tienes solucionado el problema. Ademas de que no hace falta que postgresql registre en disco datos adicionales. siempre tendra la ultima db consistente, a pesar de fallo de hardware o algún error de usuario.

Imagen de webmaster

RAID y PITR

El uso de PITR es independiente de los mecanismos de seguridad y redundantes que tengas instalados a nivel del sistema de almacenamiento.

Los ejemplos que pones de diversos tipos de raid en otros sistemas operativos no anulan la necesidad de archivar las transacciones a nivel de base de datos (oracle y otras bases de datos funcionan igual).

Si no tienes activado el archivo continuo de transacciones (PITR) perderas todos los datos desde el momento del ultimo backup (consistente, por supuesto) hasta el momento en que un fallo grave de hardware con perdida de datos te oblige a restaurar tu base de datos desde una copia de seguridad.

PITR puede activarse/usarse independientemente de si usas o no un sistema raid (no importa el tipo o el sistema operativo)

RAID y PITR

Si bueno, tienes la razón, lo que quise decir es que, freebsd/solaris integran sistemas que prevén esos fallos graves de hardware, por lo que es un plus, nunca quise decir que no hace falta PITR, siento la confusión.

Re: Problemas en la generacion de los backups en WAL

Buenas tardes,
Hoy realice las correcciones en el parametro archive_command y en algunos detalles en el archivo pitr_basebackup.sh con respecto a la ubicacion de algunos programas tales como el mkdir, rm, etc, ademas que renombre los VG y LVM y se ejecuto todo de manera perfecta, a continuacion coloco la salida del log:

[10-06-2010 14:24:01] [OK] Partition /pitr/PITR_data checked
[10-06-2010 14:24:01] [OK] Partition /pitr/PITR_data available disk space checked / 4512416 / 1145590 / 3366826 / 19300
[10-06-2010 14:24:01] [OK] Backup label file checked
[10-06-2010 14:24:01] [OK] Backup process started
[10-06-2010 14:24:01] [OK] PITR_BASEBACKUP_FILE:/pitr/PITR_data/PITRBASE-vg_pitr_v8.4.4_2010-06-10_142401_bckid00000020.tar.gz
[10-06-2010 14:24:01] [OK] Free space under data VG: 108MB
Logical volume "PITR_snapshot" created
[10-06-2010 14:24:01] [OK] Snapshot PITR_snapshot created
[10-06-2010 14:24:01] [OK] LVM Snapshot mounted under /pitr/PITR_snapshot
PITR_data/
PITR_data/PITRBASE-vg_pitr_v8.4.4_2010-06-10_141801_bckid00000020.tar.gz
PITR_last_wal/
PITR_last_wal/000000010000000000000062
PITR_snapshot/
PITR_wal/
PITR_wal/00000001000000000000005E
PITR_wal/000000010000000000000059
PITR_wal/000000010000000000000063.00000020.backup
PITR_wal/000000010000000000000060
PITR_wal/000000010000000000000062
PITR_wal/000000010000000000000063
PITR_wal/00000001000000000000005F.00000020.backup
PITR_wal/000000010000000000000062.00000020.backup
PITR_wal/00000001000000000000005D.00000020.backup
PITR_wal/000000010000000000000061.00000020.backup
PITR_wal/00000001000000000000005C
PITR_wal/00000001000000000000005D
PITR_wal/00000001000000000000005F
PITR_wal/00000001000000000000005B
PITR_wal/00000001000000000000005C.00000020.backup
PITR_wal/000000010000000000000061
PITR_wal/00000001000000000000005B.00000020.backup
PITR_wal/000000010000000000000059.00000020.backup
PITR_wal/00000001000000000000005E.00000020.backup
PITR_wal/00000001000000000000005A
[10-06-2010 14:24:21] [OK] /pitr/PITR_data/PITRBASE-vg_pitr_v8.4.4_2010-06-10_142401_bckid00000020.tar.gz file created
[10-06-2010 14:24:22] [OK] Snapshot partition /pitr/PITR_snapshot umounted
[10-06-2010 14:24:22] [OK] Snapshot final information saved
Logical volume "PITR_snapshot" successfully removed
[10-06-2010 14:24:22] [OK] Snapshot LV /dev/vg_pitr/PITR_snapshot removed
[10-06-2010 14:24:22] [OK] Last WAL file copied from /postgres/8.4/main/pg_xlog/000000010000000000000064 to /pitr/PITR_last_wal
0/64000080
[10-06-2010 14:24:23] [OK] Backup process stopped

Esto lo estoy haciendo en un ambiente de prueba para luego pasarlo a mi ambiente de produccion

Muchas gracias por todo y espero las nuevas versiones de los scripts.
Saludos desde Venezuela

Dudas sobre el pitr

Buenas Tardes, ya tengo ejecutando las pruebas de los scripts una vez solventados los inconvenientes que tuve, ahora se guardan archivos en mis directorios PITR_wal, PITR_last_wal y PITR_data, mi pregunta es sobre este ultimo el PITR_data,en el cual se genera un archivo con la extension .tar.gz, pero cuando lo abro veo que tiene los siguientes directorios: PITR_data, PITR_wal y PITR_last_wal nuevamente, no se si es que asi se tiene q generar o es que se esta generando mal, por que en los otros 2 directorios tengo archivos wal tal como dice el foro, pero en este del data imaginaba que tenia que respaldarse el pg_data de mi cluster o no se siestoy equivocado, es por esto que me gustaria aclarar esta duda.
Aqui coloco unas variables como las tengo en el archivo pitr_basebackup.sh
PG_DATA_PARTITION="/postgres/8.4/main"
PG_ARCH_PARTITION="/postgres/8.4/main/pg_xlog"
PG_LOGS_PARTITION="/logs/8.4"
PG_BACKUP_PARTITION="/pitr" ## Aqui cree el LVM y es alli donde tengo los directorios PITR_

Gracias de antemano.

APLICACIÓN

No existe una aplicación administrativa que realice el reprocesamiento del archivo??? Sin tener que trabajar con comandos manuales?

saludos
:P

pregunta de novato

Comentario irrelevante con PITR. Trasladado a los foros: http://www.postgresql-es.org/node/323

Re: ficheros wal

  • Si, los ficheros WAL guardan informacion sobre todos los cambios/transacciones que se han realizado en la base de datos.
  • Los cambios en un fichero WAL siempre se graban primero en el disco con 'fsync'. Una vez que estamos seguros que estos cambios del WAL estan grabados correctamente, se grabaran los cambios en la base de datos
  • Si, los ficheros WAL tienen un tamaño predeterminado y se reciclan para que el numero de WALs tampoco crezca indefinidamente.
  • Los WAL garantizan que ante una caida se puedan arreglar automaticamente posible inconsistencias en la base de datos

Problemas en la generacion de los backups en WAL

Desde hace una semana estoy tratando de poner en marcha los scripts que se indican en este foro para ver si implmento este tipo de PITR en mi empresa, para eso estoy usando como sistema operativo Debian Lenny y Postgres 8.4, lo cierto es que he estado haciendo algunas adaptaciones en vista que me generaban ciertos errores, una vez corregidos estos detalles estoy observando que al ejecutarse el archivo pitr_basebackup.sh el comando de backup no termina en vista que en el archivo de log muestra: [07-06-2010 14:41:31] [OK] /logs/PITR_data/PITRBASE-srvdatabase_v8.4.4_2010-06-07_144101_bckid00000020.tar.gz file created
[07-06-2010 14:41:31] [OK] Snapshot partition /logs/PITR_snapshot umounted
[07-06-2010 14:41:32] [OK] Snapshot final information saved
Logical volume "PITR_snapshot" successfully removed
[07-06-2010 14:41:32] [OK] Snapshot LV /dev/srvdatabase_data/PITR_snapshot removed
/bin/cp: omitting directory `/postgres/8.4/main/pg_xlog/archive_status/'
[07-06-2010 14:41:32] [WARNING] Could not copy last WAL
WARNING: pg_stop_backup todavía espera que el archivo se complete (han pasado 60 segundos)
WARNING: pg_stop_backup todavía espera que el archivo se complete (han pasado 120 segundos)
WARNING: pg_stop_backup todavía espera que el archivo se complete (han pasado 240 segundos)
Por lo que estoy notando que se queda esperando que culmine el archivo de respaldo, ademas al ejecutar en el servidor el comando: ps ax | grep postgres muestra lo siguiente:
7933 ? S 0:01 /usr/lib/postgresql/8.4/bin/postgres -D /postgres/8.4/main -c config_file=/etc/postgresql/8.4/main/postgresql.conf
7934 ? Ss 0:00 postgres: logger process
7937 ? Ss 0:01 postgres: writer process
7938 ? Ss 0:00 postgres: wal writer process
7939 ? Ss 0:01 postgres: autovacuum launcher process
7940 ? Ss 0:00 postgres: archiver process failed on 00000001000000000000003F
7942 ? Ss 0:00 postgres: stats collector process
8286 ? S 0:00 /usr/lib/postgresql/8.4/bin/psql --quiet -U postgres -h localhost -c SELECT pg_stop_backup(); -P tuples_only -P format=unaligned
8290 ? Ss 0:00 postgres: postgres postgres ::1(45466) SELECT
16111 pts/0 R<+ 0:00 grep postgres
Ademas en el log que genera postgres me muestra lo siguiente:
/opt/pitr_basebackup.sh: illegal option -- P

ERROR: No service_hostname has been defined

Script: /opt/pitr_basebackup.sh
Version: 2.3

Description: This script is used to create a base backup of PGDATA
that can be used by PITR to restore the database.

Usage:
pitr_basebackup.sh [-v][-h][-S service_hostname]

-h Help
-v Version
-S Hostname running postgreSQL (*)

(*) - Must be defined

Example: pitr_basebackup.sh -S dbpg-example -j 6 -c t -e f

Database: -Usuario: -Host: -Proceso: 7940 -Duracion: 2010-06-07 15:00:18 VET -SQL: LOG: la orden de archivado fall? con c?digo de retorno 65
Database: -Usuario: -Host: -Proceso: 7940 -Duracion: 2010-06-07 15:00:18 VET -SQL: DETALLE: La orden fallida era: <>
/opt/pitr_basebackup.sh: illegal option -- P

ERROR: No service_hostname has been defined

Esto lo muestra muchas veces, ademas de las siguientes lineas
Database: -Usuario: -Host: -Proceso: 7940 -Duracion: 2010-06-07 15:45:20 VET -SQL: LOG: la orden de archivado fall? con c?digo de retorno 65
Database: -Usuario: -Host: -Proceso: 7940 -Duracion: 2010-06-07 15:45:20 VET -SQL: DETALLE: La orden fallida era: <>
Database: -Usuario: -Host: -Proceso: 7940 -Duracion: 2010-06-07 15:45:20 VET -SQL: WARNING: el archivo de transacci?n <<00000001000000000000003F>> no pudo ser archivado: demasiadas fallas
Database: postgres -Usuario: postgres -Host: ::1(45466) -Proceso: 8290 -Duracion: 2010-06-07 15:45:32 VET -SQL: SELECT WARNING: pg_stop_backup todavía espera que el archivo s complete (han pasado 3840 segundos)

En el cron hago los llamados a los scripts de la siguiente manera:

* * * * * /opt/archive_last_wal.sh -S srvdatabase
41 14 * * * /opt/pitr_basebackup.sh -S srvdatabase -c t

Lo que no se es por que no termina de generar el backup y ademas el por que genera los errores que me muestra el log de postgres; po rlo que les agradeceria en lo que me puedan ayudar.

Enviar nuevo comentario

  • Las direcciones de las páginas web y las de correo se convierten en enlaces automáticamente.
  • Etiquetas HTML permitidas: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd><h2><pre>
  • Saltos automáticos de líneas y de párrafos.

Más información sobre opciones de formato

Image CAPTCHA
Enter the characters shown in the image.