Hacer un backup mysql con CRON en Linux

Es siempre bueno realizar un backup de nuestras bases de datos en caso de algún fallo, perdida o error humano (que es lo que más suele ocurrir). Como ya muchos saben Linux posee una herramienta llamada CRON el cual permite ejecutar tareas repetitivas periodicamente.

En este tutorial les mostraré como hacer un pequeño script que permite realizar un backup de la base de datos que tengamos en mysql.

Estoy suponiendo que tienes instalado y configurado un servidor mysql funcionando en tu computadora o en un servidor remoto y que tienes los privilegios necesarios para accesar a la base de datos y ejecutar scripts en tu computadora o en el servidor remoto. Aclarado esto podemos seguir con el tutorial.

Script de Backup Mysql

Primero vamos a crear una carpeta para guardar el backup que vamos a generar, esta carpeta la puedes crear donde quieras, yo personalmente la creé en mi directorio raíz pero lo puedes crear donde quieras:

mkdir /respaldosql

En nuestro editor de texto favorito escribimos el script que hará el backup de la bases de datos que tengamos en nuestro servidor de MySQL:

 #!/bin/sh
 mysqldump -uroot -ppwd --opt db1.sql > /respaldosql/db1.sql
 mysqldump -uroot -ppwd --opt db2.sql > /respaldosql/db2.sql
 cd /home/usuario/respaldosql/
 tar -zcvf respaldosql_$(date +%d%m%y).tgz *.sql
 find -name '*.tgz' -type f -mtime +2 -exec rm -f {} ;

Guarda este script con el nombre mysqlrespaldo.sh (o el nombre que más te parezca) en donde quieras, yo tengo una carpeta llamada scripts en mi directorio home, es a gusto de cada quien.

Vamos a analizar el script línea por línea: la primera línea #!/bin/sh simplemente le indica al bash que es un script ejecutable y donde va a buscar el bash que va a utilizar para ejecutar este script en este caso /bin/sh.

La segunda línea es la que hace todo el trabajo, mysqldump es un comando que “vuelca” o copia todos los datos que estén dentro de la base de datos que le indiquemos en la línea de comandos, las opciones son las siguientes:

  • -u es para indicar el usuario en este caso es root pero puede ser cualquier otro usuario que tenga privilegios sobre la base de datos
  • -p es para indicarle el password aquí tienes que colocar el password del usuario que estás utilizando para conectarte en la base de datos.
  • –opt db1 aquí indicamos cual es base de datos que queremos que copie en este caso db1
  • el operador > redirecciona la salida del comando hacia un archivo llamado db1.sql en una carpeta llamada respaldosql.

La línea que sigue hace exactamente lo mismo que la primera pero con otra base de datos llamada db2, puedes agregar tantas base de datos como quieras a este script.

Después cambiamos al directorio de respaldo donde acabamos de crear los archivos db1.sql y db2.sql con cd /respaldosql/ y comprimimos todos los archivos en uno solo con su respectiva fecha con el comando date, esto es para tener un respaldo anterior y saber cuando lo hicimos, es útil en caso de que por alguna razón queramos un respaldo viejo.

La última línea es opcional, lo que hace es buscar todos los archivos comprimidos que tengan más de 2 días y los elimina, esto es para evitar que se nos acumulen archivos antiguos, puedes cambiar con que frecuencia quieres borrar estos archivos puedes utilizar man find para mayor información.

Muy bien ahora tenemos nuestro script listo lo primero es hacerlo ejecutable:

En Ubuntu:

 sudo chmod 700 mysqlrespaldo.sh

En cualquier otra distribución tenemos que tener privilegios de administrador o root:

 chmod 700 mysqlrespaldo.sh

Añadiendo el Script a CRON

Como ya mencioné anteriormente CRON es una herramienta que posee Linux para ejecutar programas o scripts en forma repetitiva. Para modificar la tabla de cron ejecutamos el siguiente comando en nuestro shell:

 crontab -e

Se abrirá el crontab en nuestro editor de texto por defecto (en Ubuntu casi siempre se abre en el nano) aquí agregamos la siguiente línea y guardamos nuestro archivo:

 0 1 * * * /home/usuario/scripts/mysqlrespaldo.sh

Guardamos nuestro archivo y ya está listo para ejecutarse diariamente, vamos a explicar un poco como funciona (recuerda colocar en /home/usuario/scripts la ruta donde guardaste tu script).

El archivo de crontab tiene la siguiente estructura de izquierda a derecha:

  • Minutos (rango de 0-59)
  • Horas (0-23)
  • Día del mes (1-31)
  • Mes (1-12)
  • Día de la semana (0-6 siendo 0=Domingo)
  • Path completo al script o programa que queramos ejecutar

Cualquier campo con * quiere decir que se corre a cualquier posible valor de ese campo. Así que en nuestro caso el script correrá todos los días a la 1:00 de la madrugada.

Bueno eso fue todo espero que les sirva, como siempre cualquier duda o comentario son bienvenidos.

Saludos

Olivers

61 comentarios

  1. Olivers:
    Perfectamente explicado, felicidades. Por favor sigue compartiendo.
    Mi Script quedó algo así:
    #!/bin/sh
    mysql -u Usuario -pPassword -e ‘FLUSH TABLES WITH READ LOCK;’ Base_de_datos # Esto Permite asegurar primero la base de datos
    mysqldump -u Usuario -pPassword Base_de_datos | gzip -9 > /home/usuario/Respaldos/Base_de_datos_`date '+%d-%m-%Y_%T'`.sql.gz # Aqui se genera el volcado y se comprime con gzip
    mysqldump -u Usuario -pPassword Base_de_datos > /home/usuario/Respaldos/Base_de_datos_`date '+%d-%m-%Y_%T'`.sql # por políticas se respalda normalmente
    mysql -u Usuario -pPassword -e ‘UNLOCK TABLES;’ Base_de_datos # se quitan los seguros a las tablas que respaldamos
    find -name '*.gz' -type f -mtime +15 -exec rm -f {} ; # y aqui buscamos los archivos gz y borramos los que tengan más de 15 días.
    find -name '*.sql' -type f -mtime +15 -exec rm -f {} ;# y aqui buscamos los archivos sql y borramos los que tengan más de 15 días.

  2. Hola, muy interesante el tutorial, yo hice el scrip de la copia de seguridad del wordpress, necesito que me llegue un correo por consola y que contenga la copia de seguridad.
    Por otro lado que también, me copie todos los ficheros, imagenes, etc. Si me puedes ayudar.
    Tengo instalado el posfix.
    Muchas gracias.

  3. Hola, muy interesante el tema en desarrollo amigos, estoy iniciando en el mejor sistema operativo GNU/LINUX, les queria pedir ayuda sobre este tema, necesito crear un scritp o bash de linux por que deseo que cuando el sistema inicie los servicios como mysql, apache esten detenidos y cuando se necesiten usar iniciarlos a traves de un script, la distribucion de linux es Debian 6, que involucre todos el detalle para su ejecucion gracias.

  4. Muchas gracias por el aporte!

    me ha servido de mucho para poder automatizar el respaldo de la base de datos de una librería asociativa.
    Le he tenido que hacer algun cambio porque no me iba bien, por ejemplo el nombre de la base de datos no me lo admitía con el .sql, tenía que ponerlo sin la extensión.
    también en la ruta del respaldo le he puesto la ruta completa porque no estab seguro de que me lo fuera a hacer bien.

    Saludos!

  5. no me funciona de medice cat el fichero o directorio no existe
    realice los siguientes pasos

    $1=/home /juan … donde se guadaran los respaldos
    $2 lo reeplace por 30

    cree el archivo directorios dentro de este las rutas de lo que quiero copiar
    este archivo lo cree dentro de $1

    *la extencion del archivo no importa o si

    help

  6. hola, todo esta muy bien, ahora quisiera saber como hago un backup de todas las maquinas de la red. en el servidor.. y con que servicio en el servidor lo haria,
    ej, smb, apache, etc.. dependiendo k OS tengan los ordenadores. bueno gracias, y pa’lante..

  7. mperalbo, tienes que revisar los siguientes puntos:

    1. Que el archivo sea ejecutable
    2. Que tengas permisos de escritura en el directorio donde estás intentando guardar los archivos.

    Que pasa cuando ejecutas el script desde el terminal.

    Cualquier duda vuelve a escribir

    Saludos
    Olivers

  8. Hola Olivers

    He tratado de hacer el cron en mi servidor web, para la base de datos mysql, pero no me funciona todavia miro en la carpeta que le di que se guardara en el script y nada no guarda nada, no se q hacer.
    este es mi sh:
    #!/bin/sh
    mysqldump -u root -p prue2oo8 –opt dotproject.sql > /respaldosql/dotproject.sql
    cd /root/respaldosql/
    tar -zcvf respaldosql_$(date +%d%m%y).tgz *.sql

    mi cron:
    # Scrip para el backup diario de dotproject
    45 9 * * * /root/respaldosql/mysqlrespaldo.sh

    Gracias

  9. Hola Olivers, perdona que te moleste otra vez pero los archivos comprimidos no me los está borrando, quizá sea por el cambio que hice al añadir la hora. ¿Puedes decirme si tengo que hacer algún cambio en la última línea para solucionarlo?

  10. Mil gracias Olivers, con %T me daba un error
    (tar: respaldossql_18110817:00:03.tgz: Cannot open: Input/output error
    tar: Error is not recoverable: exiting now)
    pero lo he cambiado a:
    tar -zcvf respaldossql_$(date +%d%m%y%H%M).tgz *.sql
    y va perfecto.
    Esto va a ser una tranquilidad para mí. ¡Gracias!

  11. Hola Eva, muchas gracias por tu comentario. Para agregarle la hora solo tienes que modificiar la línea que dice:

    tar -zcvf respaldosql_$(date +%d%m%y).tgz *.sql

    Y colocarle:

    tar -zcvf respaldosql_$(date +%d%m%y%T).tgz *.sql

    Con %T le agregas la hora en formato de %H:%M:%S es decir por ejemplo 08:10:25 si quieres otros tipos de formatos puedes ejecutar man date y revisa la parte de formatos.

    Espero que te sirva, cualquier otra duda estoy a la orden.

    Saludos
    Olivers

  12. BitGenix, de verdad te recomiendo que hagas un backup de la base de datos en Windows lo puedes hacer desde el cmd con:

    mysqldump –opt -u nombredeusuario -p basededatos tabla1 > archivodebackup.txt

    También lo podrías hacer con phpmyadmin

    Y despues subes ese backup a Linux, es muy rapido de esta forma

    Saludos
    Olivers

  13. Hola: Mi base de datos esta en MySQL (36Mb) y pense que solo con copiarla en /opt/lampp/var/mysql podia trabajarla en Ubuntu, pero no fue asi. He estado trabajando con este problema desde hace algunos dias pero no consigo la razon por la cual lampp no pueda ver mi base de datos. He trabajado con los persmisos de usuarios dejandolos igual que el folder de “test” y “mysql” pero nada. El formato del archivo es diferente en windows que en linux? Hay que registrar las bases de datos en algun lugar antes de colocarlas en su lugar? Que tipo de problema podria encontrar si lo hago de esta forma? perdida de datos? de interpretacion de campos y/o valores? Gracias…

  14. Hola BitGenix, que tipo de base de datos tienes MySQL?, en teoria si podrias mover la carpeta pero yo te aconsejo que hagas un backup de tu base de datos de windows y luego la importes en Linux es una forma mucho más fácil y práctica de hacerlo, además así te evitas problemas

    Saludos
    Olivers

  15. Hola: Como puedo hacer para que Ubuntu me reconozca mi folder de mi base de datos copiada desde windows? Quisiera saber si esto es posible o si el formato en la base de datos de winxp es diferente a los archivos en ubuntu y tengo que hacerlo a traves de backup. No es suficiente copiando solo el folder? Les agradecere respuestas.

  16. Hola mira nos han mandado a hacer un backup con la red nfs y tcp ip, que cuando el usuario haga un backup vaya al administrador con el nombre y la fecha y tambien con el contrab. mas o menos tengo una idea pero ….como se puede hacer un script para elegir si o no por ejemplo ¿quieres hacer una copia de esta carpeta s/n? y cuando marcas una de las 2 haga una cosa o otra

    gracias bss

  17. Hola piny, cron no es un servidor es un “servicio” que tienen todas las distribuciones de linux para hacer tareas regulares.

    Lo que muestro aqui es como utilizar CRON para que haga respaldos regulares de una base de datos en MySQL

    Cualquier otra duda pregunta

    Saludos
    Olivers

  18. Hola Hector,

    Pues cron al principio puede parecer dificil pero realmente no lo es. Hay muchas formas de aprender pero la mejor es con las paginas de manual. Puedes hacer un:

    man crontab

    Y ahi verás como se utiliza y cuales son las opciones.

    Más adelante publicaré un tutorial más detallado de cron pero por ahora con man y google podrás encontrar la información que necesitas.

    Disculpa la tardanza de la respuesta

    Y estamos a la orden para cualquier cosa

    Saludos
    Olivers

  19. Hola anrey, hay muchas formas de hacer lo que estas pensando podrías hacerlo con un script hecho en perl. Busca en Google como manejar una base de datos con perl y ejecutas el script que hagas con cron.

    Es algo largo para explicarlo por aquí quizas en un futuro tutorial.

    Si quieres puedes ir haciendo preguntas más concretas si te encuentras con problemas para ayudarte.

    Saludos
    Olivers

  20. hola muy buenas yo necesito hacer una backup de la bd q se encuentra en mi pag web diariamente y que la misma se carge automaticamente en la bd localizada en mi pc local como prodria hacerlo con cron podrian ayudarme gracias

  21. Hola, me sirvió mucho la parte “$(date +%d%m%y)”, pues es justo lo que yo andaba buscando. Lo que yo hice fue usar este script:

    #!/bin/bash
    # Este script genera un backup del directorio de trabajo /home/jaime/work
    cp -r /home/jaime/work /home/jaime/work/backup_$(date +%H%M%S) # Este script trabajará de la mano con el crontab. Lo que se le programó al crontab (digitando “crontab -e” desde la consola) es la siguiente línea: “*/5 * * * * /home/jaime/work/10”. Eso significa que cada 5 minutos se estará ejecutando este script, de manera que cada 5 minutos se estará haciendo un backup de /home/jaime/work, será ubicado ahí mismo en /home/jaime/work y tendrá por nombre backup_$(date +%H%M%S), donde “$(date +%H%M%S)” almacena la hora, minutos y segundos del momento en que se realizó el backup. Por ejemplo, si se realizó a las 2 de la madrugada con 35 minutos y 1 segundo, el directorio tendrá por nombre “backup_023501” y la ruta completa será: “/home/jaime/work/backup_023501”. Suponiendo que en vez de concatenar horas, minutos y segundos, se quisiera concatenar el día, mes y año junto con el nombre del archivo, en vez de “$(date +%H%M%S)” tendría que utilizarse “$(date +%d%m%y)”.

    Luego con un cron llamo al script:

    GNU nano 2.0.2 Fichero: /tmp/crontab.eMdHMp/crontab Modificado

    # m h dom mon dow command
    */5 * * * * /home/jaime/work/10 # Este cron estará llamando al script /home/jaime/work/10 cada 5
    minutos, y es el script el que contiene el código para que se generen backups o copias de respaldo correctamente.

    Me funciona todo perfectamente y ya puedo hacer backups de mi información. Muchas gracias por haber publicado esto: “$(date +%d%m%y)”. Era justo lo que yo necesitaba y me mucho tiempo buscándolo y finalmente lo encontré en este sitio. Saludes desde El Salvador, hasta pronto.

  22. Hola oliver,
    por favor quisiera q me ayudes, tengo una instruccion select en my sql, y quiero q se ejecute todos lo dias a cierta hora, como hago esto? quiero que el resultado de la instraccion se guarde en un archivo.txt.
    agradeceria mucho tu ayuda, cualquier ayuda por favor enviamela a mi correo,

    gracias 🙂

  23. Hola Marcos la base de datos es guadada en /var/lib/mysql, sin embargo te aconsejo que mejor exportes la base de datos de donde la tengas y luego la importes con mysql o con phpmyadmin es una forma más límpia y correcta de hacerla. Además copiarla directamente te puede dar luego problemas.

    Saludos
    Olivers