Una de las primeras obligaciones, si no la más importante, del administrador de un servidor de bases de datos, es mantener copias de seguridad funcionales y actualizadas de todas y cada una de ellas.
Nunca se sabe cuando algo puede ir mal: un disco duro, una memoria, caidas del sistema por algún problema de software o por el ataque de algún elemento mal intencionado…
En ese momento es cuando podremos resolver el problema de dos maneras, en unos pocos minutos restaurando la copia de seguridad ó backup del dÃa anterior, o bien pasarnos varias horas mirando de restaurar copias antiguas o en el peor de los casos perdiendo totalmente el contenido de la base de datos.
En el artÃculo de hoy me gustarÃa hablar concretamente del gestor de bases de datos MySQL. En su instalación base viene acompañado de una herramienta de backup muy potente: mysqldump.
La herramienta permite hacer copias de seguridad de las tablas de una base de datos, de varias bases de datos o bien de todas ellas a la vez. Genera todas las instrucciones en lenguaje SQL necesarias para restaurar la base de datos al momento de la cópia, y las imprime en canal stdout (la pantalla); con lo que si las redirigimos a un fichero podremos guardarlo.
mysqldump --databases mibasededatos > backup_mibasededatos.sql
El único inconveniente lo encontramos si queremos guardar cada base de datos en un fichero separado de las demás. La opción –all-databases, o bien –databases db1 db2 … dbn imprimirán todo el código a la vez en stdout, sin distinción.
Es por ello que he desarrollado el siguiente script bash, el cual, ejecuta una instrucción en MySQL “SHOW DATABASES;” que nos imprime los nombres de todas las bases de datos en una lista, sobre la cual podremos realizar un bucle e ir ejecutando para cada una de ellas, una instrucción mysqldump.
#!/bin/bash
# Ruta en la que se guarda el log de la operacion de backup.
logfile="/path/to/mysql.log"
# Ruta en la que guardar los backups
backup_dir="/path/to/saved/mysql"
# Usuario
username="<nombre_usuario>"
password="<password_de_acceso>"
# Creamos un nuevo log del proceso de backup
rm -rf $logfile
touch $logfile
# Mediante esta instruccion, generamos un nombre de fichero con el dia y la hora del proceso de backup.
timeslot=`date +%Y%m%d_%H%M`
cd $backup_dir
# Iteramos a traves de la lista de bases de datos a la que el usuario tiene acceso.
for BBDD in $( mysql -u $username --password=$password -h localhost -Bse 'show databases' ); do
echo "Creando copia de seguridad de $BBDD"
# Volcamos la base de datos en un fichero temporal
mysqldump --user=$username --password=$password $BBDD > datos.sql
# Y lo comprimimos en un tar.bz2 para ocupar lo mnimo. Util en bases de datos grandes.
tar cvjf mysql-$BBDD-$timeslot.tar.bz2 *.sql
# El nombre del fichero resultante contiene el nombre de la base de datos y la fecha de la copia.
# De esta manera, cuando sea necesaria su restauracion sera mas sencillo de localizar.
echo "Backup completo en la base de datos: $BBDD (mysql-$BBDD-$timeslot.tar.bz2)" >> $logfile
# Borramos el fichero temporal
rm datos.sql
done
#-------------------------------------------------
#
# Finalmente podemos enviar un email con el log de acciones para tener controlado el proceso de copia
#
cat $logfile|mail -s "Proceso Backup $HOSTNAME = MySQL" <direccion_email_de_control>
- Download this code: backupalldatabases.sh
Y ya lo tenemos. Solamente quedará generar una tarea en el cron del sistema para que se ejecute de manera automática diariamente o cada X horas. A partir de aquà deberemos ir revisando que los backups se hacen de manera correcta y guardarlos ficheros en CD para almacenarlos fuera del servidor.
En un próximo artÃculo mostraré como subir, automáticamente y en el mismo proceso de backup, a un servidor FTP los ficheros de backup para maximizar la seguridad en caso de fallos.
Muy interesante el script, utilizaba uno más simple para mis copias dee seguridad pero me gusta más el tuyo asà que lo he incorporado en mi trabajo.
Gracias y un saludo
De nada, espero que te sea de mucha utilidad!
Pero para eso necesitas tener acceso a uan shell, ¿no?. Muchos servidores web te permiten usar trabajos Cron pero sólo ejecutar scripts en PHP.
Si, seria lo mas sencillo. Si no es el caso podrÃas probar si el servidor te da acceso a las funciones “exec” o “shell_exec”. Asà podrÃas ejecutar comandos en el servidor.
Hola porfavor lo mas pronto !
nmecesito entender :
shell
cron
shell_exc
lo q pasa es q me han pedido hacer un backup de una bd en mysql y luego restaurarla cada 7 horas ..por favor ayudeneme..porq nose mucho mysql
Dorisita, las funciones shell o shell_exec se utilizan desde scripts php (lenguage de programacion web). En principio para hacer backups y luego restaurarlos no serian necesarios.
El cron es relativamente sencillo de comprender. Basicamente le dices cada cuanto tiempo quieres que ejecute una tarea. En el wiki del Cron http://es.wikipedia.org/wiki/Cron_(unix) veras claro como se utiliza.
En cuanto a lo de hacer backups, con el script que pongo aqui seria sencillo. Y para restaurar cada siete horas, tendrias que crear un script que descomprimiera el tar.bz2 y luego lo ejecutara mediante una instruccion:
mysql basededatos < fichero_descomprimido
A ver si asà te oriento un poco mas.
hola, todo funciona ok, lo q no se puede es enviar a mi mail
el log :
script.sh: 45: mail: not found
que hay q configurar para q funcione, o q es lo que puede estar mal.
GRACIAS.
Por el error, lo que sucede es que no tienes instalado el programa “mail” en tu distribucion linux. Si la instalas ya te funcionarà todo correctamente.
En Ubuntu/Debian, por ejemplo, se instalaria mediante la instrucción de consola
sudo apt-get install mail
En otras distribuciones funcionará de manera similar. Consulta tu gestor de paquetes para ver de que manera se puede hacer.
Un saludo,
tengo el siguiente error
jjjj@dddddd:~$ sudo ./crondb.sh
“Creando copia de seguridad de mysqlâ€
tar: +%Y%m%d_%H%M.tar.bz2: No se puede stat: No existe el fichero o el directori o
datos.sql
tar: Salida con error demorada desde errores anteriores
“Creando copia de seguridad de Verâ€
mysqldump: Got error: 1049: Unknown database ‘Ver’ when selecting the database
tar: +%Y%m%d_%H%M.tar.bz2: No se puede stat: No existe el fichero o el directori o
datos.sql
tar: Salida con error demorada desde errores anteriores
“Creando copia de seguridad de 14.12â€
mysqldump: Got error: 1102: Incorrect database name ‘14.12′ when selecting the d atabase
tar: +%Y%m%d_%H%M.tar.bz2: No se puede stat: No existe el fichero o el directori o
datos.sql
me parece que la linea 18 no la tienes bien.
timeslot=`date +%Y%m%d_%H%M`
¿Has puesto las comillas tipo acento abierto (`) al principio y al final no?
De esta manera el script interpreta que ha de asignar el contenido de la ejecución de “date”.
Muchisimas gracias señor
De nada, a mandar!
Buenas!!
Muchas, però que muchas gracias por tu script!
Me parecÃa ofensivo usar tu script como muchos otros estaran haciendo, sin comentarte nada por aquÃ… asà que aquà me tienes, con un post de lo más simple.
Gracias por tu trabajo!!!!
Muchas gracias Roc!
De verdad que se agradece!
Hola,
he observado que en la última lÃnea del fichero sql, que me genera mysqldump,aparece “Dump completed on “.
Pues bien, la hora que me aparece es exactamente la anterior a la de ejecución del mysqldump.
En el crontab tengo automatizado el mysqldump para que se ejecute a las 12:00 h., y en el fichero SQL que genera, en la última lÃnea aparece que se ejecuta a las 11:00h.
“Dump completed on 11:00:08
¿Alguna sugerencia?
Gracias
Lo que comentas tiene pinta de ser que el servidor tenga configurado mal el reloj. Concretamente el desvio horario, lo de UTC+1, +2, etc.
Lo puedes revisar eso?
Hola David,
no creo que sea lo que indicas.
En mi servidor, con sistema operativo solaris, además de mysql tengo BBDD Oracle.
No hay ningún problema con la hora en las otras aplicaciones. Incluso ejecutando los siguientes comandos en mysql todo parece OK:
mysql> select now();
+———————+
| now() |
+———————+
| 2009-02-02 11:03:16 |
+———————+
1 row in set (0.00 sec)
mysql> system date
Mon Feb 2 11:03:21 CET 2009
Pero con “mysqldump” se genera el fichero sql, apareciendo en la última lÃnea “Dump completed fecha hora” siendo la hora inferior en un entero a la actual.
Saludos
Y si ejecutas “date” desde la consola del servidor, no del mysql, que aparece?
David, perdona por el retraso en contestar, pero he estado muy liado con el trabajo.
Te detallo las distintas salidas de la fecha con y sin mysql:
mysql> select now();
+———————+
| now() |
+———————+
| 2009-02-05 09:02:14 |
+———————+
1 row in set (0.00 sec)
mysql> system date
Thu Feb 5 09:02:21 CET 2009
mysql>
mysql>
mysql> exit
Bye
cursosbd#mysql> exit
root@cursosbd # date
Thu Feb 5 09:02:27 CET 2009
Si lanzo el mysqldump al final del fichero sql generado me aparece las 08:02:35 ¿¿¿???
¿Alguna sugerencia?
Gracias
Disculpa como podria usar tu script en Windows. Entiendo que tendria que guardarlo como .bat pero al momento de ejecutarlo solo arroja un archivo vacio en el path que le indico.
Saludos y gracias por compartir tu info.
Muchas gracias por compartir el script, me está siendo muy muy útil. Sin embargo me gustaría hacer una pregunta que quizás revele mi ignorancia
¿No es peligroso tener el script en el sistema? Si un intruso le echara un vistazo al crontab podría leerlo y ver el nombre de usuario y contraseña para acceder a la base de datos, no? :S
Gracias de nuevo!
Kanakis, si le pones permisos para que cualquiera pueda leerlos, es peligroso.
Si lo pones en /root/script.sh, con permisos 700, no tendrias problemas.