martes, 15 de julio de 2014

Crear Backup Automatico con Postgres en Windows

Actualizado [15-04-2016]

A continucación voy a explicar como pude hacer un backup en Postgres y ademas decirle a windows que lo haga periodicamente(via Programador de Tareas).


Primero que todo decir que lo siguiente es la recopilación y lectura de muchos post en español e ingles, igualmente me apoye en la documentación de Postgres 9.5. Algunos métodos no me funcionaron, otros a medias hasta que un poquito de uno y un poco de otro dio resultado acertado. Los ejercicios que haré a continuación se han ejecutado en Windows 7 64 y 32 bits(sirviendo como servidores para PyMes), Windows Server 2008 R2, Windows 10 en modo desarrollo y CentOs 5 y 6.


Comencemos:


Lo primero que hay que tener en cuenta es que para hacer backups en Postgres se utiliza la utilidad pg_dump. Esta utilidad tiene muchas configuraciones para realizar el backup correcpondiente de una base de datos. La siguiente instruccion es la que utilizaremos para realizar el backup, ya que es la que por medio de pg_admin III me ha servido en su totalidad sin generar mas que errores evidentes pero que no tienen nada que ver con los datos o estructura de la base de datos.


pg_dump -i -h <server> -p <puerto> -U <usuario> -F c -b -v -f <nombre_fichero> <bd> 


Tambien hay otra forma que me ha servido y es mas purista en cuanto a la documentacion de Postgres. Las dos me han servido en los sistemas operativos mencionados anteriormente.


pg_dump -h host/server -p puerto -U usuario base > nombre_fichero


Como podemos ver en la instruccion, el signo mayor que(>) nos sirve para decirle donde vamos a guardar el backup.


Para utilizar esta intruccion como debe ser, el directorio bin/ de Postgres tiene que estar en las variables de entorno de entorno de Windows, sino lo hiciéramos, se podría incluir la dirección completa de la ubicación, pero en sistemas de 64 bits molesta bastante debido a los espacios del nombre de las carpetas. Por lo tanto agregaremos al path de Windows, el directorio de postgres.


Para agregar el directorio vamos al siguiente link.


Como ya podemos utilizar pg_dump en el sistema via cmd. Entonces ahora vamos a crear un archivo con extension .bat que se ejecutara y creara nuestro backup. Abrimos nuestro editor preferido e ingresaremos el siguiente codigo.


Forma 1:



  1. @echo off
  2. for /f "tokens=1-3 delims=/ " %%i in ("%date%") do (
  3. set day=%%i
  4. set month=%%j
  5. set year=%%k
  6. )
  7.  
  8. set datestr=%day%_%month%_%year%
  9. echo datestr is %datestr%
  10. set BACKUP_FILE=G:/mibase_%datestr%.backup
  11. SET PGPASSWORD=14785
  12. echo on
  13. pg_dump -i -h host -p puerto -U usuario -F c -b -v -f %BACKUP_FILE% base
  14. SET PGPASSWORD=

Forma 2:
  1. @echo off
  2. for /f "tokens=1-3 delims=/ " %%i in ("%date%") do (
  3. set day=%%i
  4. set month=%%j
  5. set year=%%k
  6. )
  7. set datestr=%day%_%month%_%year%
  8. echo datestr is %datestr%
  9. set BACKUP_FILE=G:/mibase_%datestr%.backup
  10. SET PGPASSWORD=14785
  11. echo on
  12. pg_dump -h host -p puerto -U usuario -F c base > %BACKUP_FILE%
  13. SET PGPASSWORD=

El código anterior es código Batch, si alguien tiene una mejor manera de decirlo, lo agradeceré enormemente. A continuación explico el código.


Línea 1: Cancelamos el echo para que no haya volcado de datos.

Línea 2-6: Creamos un ciclo for /f para asignar en las variables day, month y year la fecha actual vía %date%
Línea 8-9: Creamos una variable datestr en la cual asignaremos la fecha en formato dd_mm_aaaa y estará lista para usarla después
Línea 10: creamos la variable BACKUP_FILE y en esta ingresaremos el lugar (ruta) donde guardaremos nuestro backup. Como pueden ver yo estoy guardando el backup en la raíz de D: con el nombre mibase, guion bajo y %datestr% que es la fecha, por último la extensión .backup.
Línea 11: Set sirve en Batch para mostrar, asignar o eliminar variables de entorno mientras esté abierto la sesión cmd que lo llamo, es decir mientras termina nuestro backup, por lo tanto en esta línea estamos asignando a PGPASSWORD la contraseña del usuario de postres que va a hacer el backup. 
Línea 12: le decimos al echo que puede comenzar desde aquí el volcado de datos, vía instrucción siguiente.
Línea 13: Ejecuta la utilidad pg_dump, los parámetros que deben cambiar son 5432(en caso de que hayan configurado un puerto diferente a postres), usuario(es el usuario que tiene como contraseña la línea 11) y base (nombre de la pase de datos en postres que vamos a hacer el backup). Hay que tener en cuenta que la opcion -F c, significa el formato que utilizara pg_dump para el documento de salida. La c es custom y comprime los datos por defecto. Si le quitamos esto, el documento nos saldra en formato texto plano, es decir SQL puro.
Línea 14: Reasignamos la contraseña del usuario que creo el backup, por seguridad.

Guardamos este script en un lugar que se pueda recordar facilmente y si queremos podemos ejecutarlo via cmd de la siguiente manera para que puedan ver que realmente ya hace el backup.


Ingresamos a cmd y buscamos el archivo. Mi archivo lo guarde en raiz de C, entocnes lo llamo asi:


C:/archivo.bat


De inmediato el archivo se ejecutara y al final nos devolvera a la consola para una nueva intruccion, para verficar que si tenemos bien el script, vamos a la carpeta o ruta donde guardamos el backup y veremos como creo el archivo, en mi caso, D:/mibase_15-07-2014.backup


Con esto ya podemos crear nuestros backups de nuestra base de datos. Para hacerlo automaticamente, es decir que el PC lo haga en una hora determinada cada dia, mensual, semanal debemos de agregar una tarea al programador de tareas de windows y ejecutar este archivo. Para ver este manual da click aqui.

El archivo .backup significa un archivo comprimido diferente a los .sql. Los .sql son archivos planos puros que suelen pesar mucho mas que los comprimidos.


Conclusiones:


Las dos instrucciones funcionan correctamente, lo unico que se cambio es practicamente que el signo mayor que(>) tiene la funcion similar de la opcion -f. 


Como les dije en un momento, esto esta probado, esta en funcionamiento. Si tienen problemas comenten, sino tienen problemas, tambien comenten. Si hay un error en el manual, comenten.

40 comentarios :

  1. Lo probé ayer, funciono a la perfección. Muchas gracias

    ResponderBorrar
  2. ayudenme no funciona
    @echo off
    for /f "tokens=1-3 delims=/ " %%i in ("%date%") do (
    set day=%%i
    set month=%%j
    set year=%%k
    )

    set datestr=%day%_%month%_%year%
    echo datestr is %datestr%
    set BACKUP_FILE=C:/mibase_%datestr%.backup
    SET PGPASSWORD=sistemas2015
    echo on
    pg_dump -i -h localhost -p 5432 -U postgres -F c -b -v -f %BACKUP_FILE% Disa
    SET PGPASSWORD=sistemas2015

    ResponderBorrar
    Respuestas
    1. ¿Que error sale?, ¿No genera el archivo?. Tenga en cuenta que tiene que hacer los pasos de variables globales.

      Borrar
  3. me ha funcionado, gracias por compartir! ¿te puedo hacer un par de consultas más? ¿se podría hacer un script para copiar el servidor "entero"? lo que haría 'Backup server' en pgAdmin
    y ¿alguna manera de gestionar, ir eliminando los backups según van creándose los nuevos? muchas gracias de nuevo!

    ResponderBorrar
    Respuestas
    1. Buen dia Guillermo,

      Sobre la primera pregunta: investiga sobre pg_dumpall.

      Sobre la segunda: El ejemplo de aqui es para hacer un backup autoincremental. Si solo quieres hacer un backup, digamos diario, sin guardar los de los dias anteriores, modifica el script para quitarle la fecha, que es lo que hace que cada cierto tiempo se cree un archivo. Al quitarle la fecha, postgres sobreescribira el documento, por la version mas actualizada. Esta es la solucion mas simple.

      Espero haberte ayudado.

      Borrar
  4. Bueno tardes, estiamado tengo un server postgres que me realiza backup, me gustaria saber los procedimiento de restaurar un bd

    ResponderBorrar
    Respuestas
    1. Buenas Tardes Marcos,

      Para subir cualquier archivo .sql desde terminal es con la siguiente instrucción:

      psql -U postgres -d base_de_datos -f archivo.sql

      Para hacerlo sobre un archivo .backup que es el generado en el post. Es con la instruccion pg_restore y se utiliza asi:

      pg_restore -i -h localhost -p 5432 -U postgres -d base_de_datos -v archivo.backup

      En los dos casos, se pedira la contraseña despues de ejecutar la linea en el terminal.

      Si tienes preguntas sobre que es -v, siginifica verbose y sirve para ver en pantalla lo que se esta subiendo o restaurando.

      La -i es para ignorar la version.

      Espero haberte ayudado Marcos.

      Borrar
  5. Buenas tardes, Gracias por tu aporrte..
    Estimado actualmente estoy administrando servidor postgres y Servidor Barman, me gustaria su explicacion como restaurar una BD, lo cual el respaldo es
    nombrerespaldo20151006T110425.zip y dentro del zip cotiene walls y base, me gustaria un documento que me diga como restaurarla independiente de la version de postgressql y barman Saludos y muchas gracias

    ResponderBorrar
  6. Pues Marcos, en la documentacion oficial de Barman esta toda la informacion necesaria para restaurar y crear backups.

    http://docs.pgbarman.org/release/1.5.0/#restoring-a-whole-server

    ResponderBorrar
  7. Hola amigos, no funciona para el posgres version 9.5, que sintacys se varia para que pueda funcionar.....

    ResponderBorrar
  8. Excelente artículo, me funciono perfecto, llevaba tiempo buscando la mejor forma de hacerlo. Muchas gracias.

    ResponderBorrar
  9. Deseo Instalar y configurar la ultima version de Barman,
    Mi pregunta si se puede configurar y que trabaje muy bien con la version 8.4 postgres para los respaldo, si existen alguna configuracion que agregar favor apoyarme..

    Saludos y muchas gracias

    ResponderBorrar
  10. Hola Amigo, y si quiero ejecutar un script con una función ya creada cómo sería el archivo bat?

    ResponderBorrar
    Respuestas
    1. Hola Renzo, gracias por el comentario.

      ¿Podrías ser mas claro sobre la función?. Es una función de PL-pgSQL o una función hecha en un lenguaje de programación.

      Entre mas información comparta, mas fácil podremos ayudar.

      Borrar
    2. Si necesitas ejecutar un script hecho en php, entonces mira esto:

      http://rincondedesarrollo.blogspot.com.co/2014/10/creacion-de-cron-jobs-desde-cpanel-y.html

      Borrar
    3. Para Windows es exactamente igual, solo tienen que tener en cuenta que PHP se ejecute desde consola y el resto lo hace el programador de tareas.

      Borrar
  11. Logro generar el backup pero esta vacío

    ResponderBorrar
  12. Buenos días amigo y si quiero que mi backup me guarde en formato Directory, como lo debo declarar?

    ResponderBorrar
    Respuestas
    1. Hola, ¿como estas?.

      Para los formatos, tienes que cambiar el parametro de -F en la instruccion pg_dump. Para que guarde en formato directory es por medio de -F d .

      Espero haber ayudado. Quedo atento y gracias por leer el blog.

      La documentacion oficial esta aqui:
      https://www.postgresql.org/docs/current/static/app-pgdump.html

      Borrar
  13. hola me gustaría hacer un backup pero por tablas alguien me podría ayudar ...

    ResponderBorrar
  14. hola me gustaría hacer un backup pero por tablas alguien me podría ayudar ...

    ResponderBorrar
    Respuestas
    1. Hola, ¿como estas?.

      Para dar una respuesta rápida. Añade -t [tabla] a la linea que ejecuta pg_dump. Esto seria para una sola tabla. Si quieres un grupo de tablas, seria añadir -t [tabla] segun las tablas que se deseen.

      La otra forma es por medio de patrones según los nombres de las tablas. Si usas prefijos entonces: -t [patrón]* o -t t_* como ejemplo.

      Ten en cuenta que esto lleva ciertos riesgos ya que postgres solo hara el backup de las tablas que encuentre con el parámetro -t y no de sus relaciones.

      Esta es la documentación oficial: https://www.postgresql.org/docs/current/static/app-pgdump.html Puedes revisarla para que no hayan dudas.

      Espero haberte ayudado. Quedo atento.

      Borrar
  15. RESPALDAR UNA TABLA DE UNA BASE DE DATOS AUTOMATICAMENTE

    set mes=%date:~3,2%
    set dia=%date:~0,2%
    set hora=%time:~0,2%
    set minuto=%time:~3,2%
    SET PGPASSWORD=postgres
    echo on
    "C:/Program Files/PostgreSQL/9.1/bin\pg_dump.exe" --host localhost --port 5432 -U "postgres" --format plain --column-inserts --verbose --file "C:/respaldopp/bk_datos_juventud%dia%%mes%%hora%%minuto%.sql" --table "public.datos_juventud" "db_pp"
    "C:/Program Files/PostgreSQL/9.1/bin\pg_dump.exe" --host localhost --port 5432 -U "postgres" --format plain --column-inserts --verbose --file "C:/respaldopp/bk_datos_participante%dia%%mes%%hora%%minuto%.sql" --table "public.datos_participante" "db_pp"
    SET PGPASSWORD=

    ResponderBorrar
  16. Hermano, buen aporte lo he probado tal cual lo explica y me ha funcionado bien, te agradezco, una pregunta extra si en vez de un backup quisiera que postgre ejecutará una función, crees o considera que puede hacerlo con este método?

    ResponderBorrar
  17. Amigo probé tu script, me genera el backup pero me lo genera vacio. Si puedes ayudarme estaria agradecido

    ResponderBorrar
    Respuestas
    1. Este es mi Script

      @echo off
      for /f "tokens=1-3 delims=/ " %%i in ("%date%") do (
      set day=%%i
      set month=%%j
      set year=%%k
      )
      set datestr=%day%_%month%_%year%
      echo datestr is %datestr%
      set BACKUP_FILE=D:/respaldos/reporte_%datestr%.backup
      SET PGPASSWORD=123456
      echo on
      pg_dump -i -h localhost -p 5432 -U postgres -F c bddata > %BACKUP_FILE%
      SET PGPASSWORD=123456

      Borrar
  18. Este comentario ha sido eliminado por el autor.

    ResponderBorrar
  19. Este comentario ha sido eliminado por el autor.

    ResponderBorrar
  20. NO FUNCIONA TU SCRIPT, PARA LOS QUE LES PASO LO MISMO QUE AMI LES DEJO UN SCRIPT QUE SI FUNCIONA.
    REEMPLAZAR LO QUE ESTA ENTRE CORCHETES Y NO SE OLVIDEN QUE pg_dump DEBE ESTAR EN LAS VARIABLES DE ENTORNO DE WINDOWS
    @echo off
    for /f "tokens=1-4 delims=/ " %%i in ("%date%") do (
    set dow=%%i
    set month=%%j
    set day=%%k
    set year=%%l
    )
    set datestr=%month%_%day%_%year%
    echo datestr is %datestr%

    set BACKUP_FILE=[NameOfTheFile]_%datestr%.backup
    echo backup file name is %BACKUP_FILE%
    SET PGPASSWORD=[PassWord]
    echo on
    pg_dump -i -h [HostName] -p 5432 -U [UserName] -F c -b -v -f %BACKUP_FILE% [DATABASENAME]

    ResponderBorrar
  21. Hola, Como puedo restaurar una base de datos automaticamente sobre una que ya esta en uso, el proceso que deseo automatizar es que, el operador ejecute un batch que genere el backup, lo lleve a su notbook y alli tenga otro batch que restaure sobre la base de datos actual.

    ResponderBorrar
  22. Hola a todos, muchas gracias por este aporte, funciona de maravilla, tengo una consulta adicional. Estoy haciendo un backup cada 5 minutos por tiempo indefinido, hay alguna manera de que el backup pueda revisar el tamaño del archivo y si no hay modificacion en el tamaño no haga el backup y que una vez el tamaño de la base de datos crezca o disminuya se vuelva a generar el backup. Esto podria ser posible?

    ResponderBorrar
  23. Amigo me crea el archivo pero vacio sin nada

    ResponderBorrar
  24. Hola, ya lo he checado y solo me mandara error en la -i solo la quite y listo, ahora bien si le quisiera yo agregar, hora, minuto y segundo del día amigos! agradecería su ayuda

    ResponderBorrar
  25. Hola buenas noches,como se sabe a que directorio(carpeta esta guardando este backup x favor?

    ResponderBorrar
  26. Este comentario ha sido eliminado por el autor.

    ResponderBorrar