Generación y almacenamiento automático de backups con PHP y MySQL

backups

En los últimos meses, con el objetivo de mejorar mi productividad, estoy dedicando tiempo a automatizar las tareas frecuentes y tediosas que me ocupaban parte de mi día a día. Hoy comparto cómo genero y almaceno de forma automática y muy simple los backups de bases de datos MySQL con PHP.

Hay varias formas diferentes de generar y almacenar respaldos de bases de datos de forma periódica, pero yo me he decantado por la que a mi juicio es la forma más sencilla y cómoda. Esta implementación es válida para MySQL y servidores UNIX, aunque se podría adaptar a otros motores de bases de datos o sistemas operativos sin demasiada dificultad.

Generar el fichero de backup

Para empezar, necesitamos programar un script en PHP que obtenga un backup de la base de datos que queremos respaldar y lo almacene en el servidor:

Vamos a utilizar el comando mysqldump para generar un archivo SQL con las sentencias para la creación de las tablas de la base de datos y todas las inserciones necesarias para recuperar el estado actual de la base de datos. Al comando mysqldump le especificamos con parámetros los datos de acceso a nuestra base de datos ($host, $username, $password, $dbName) y comprimimos el fichero resultante utilizando gzip.

Por último necesitamos establecer el nombre y la ruta donde vamos a almacenar el fichero resultante. Por motivos de seguridad es conveniente que almacenemos los backups en una ruta no accesible a través de ninguna url, si bien no es imprescindible dado que como veremos un poco más adelante eliminaremos el fichero al finalizar este proceso porque lo almacenaremos fuera de nuestro servidor.

En cuanto al nombre del fichero, sigo la convención de utilizar el nombre del proyecto web al que aplica la base de datos concatenado con la fecha de generación del respaldo en formato año-mes-día, que favorece la ordenación cronológica, y extensión .sql.gz.

Envío de los backups por correo electrónico

Una vez que tenemos generado el fichero de respaldo, la mejor manera de almacenarlo de forma ordenada es enviarlo por email a una cuenta de correo utilizada únicamente para este fin. Yo en concreto utilizo una cuenta normal y corriente de Gmail a la que envío todos los backups de los proyectos web que administro. Utilizo Gmail para este fin porque te proporciona 15GB de almacenamiento gratuito y además es más seguro que almacenar los backups en tu propio servidor, ya que las probabilidades de que tu cuenta de Gmail sufra un ataque o pierda los datos son muy inferiores a las de hacer lo mismo en tu servidor (salvo que seas un gurú de la seguridad, claro).

Para simplificar el acceso a los backups de un proyecto, os recomiendo crear una etiqueta para cada proyecto web y a través de un filtro de correo electrónico etiquetar automáticamente los backups con su proyecto web correspondiente.

Puedes enviar el backup adjunto por email con este sencillo código:

Una vez enviado el email, eliminamos del servidor el fichero para evitar exponer la información de la base de datos. Además, se puede crear un fichero de log para trazar el estado de los backups que se han generado, aunque no es estrictamente necesario.

Automatización del proceso

Cuando hayamos verificado que se genera y envía por correo electrónico correctamente el backup de nuestra base de datos, lo siguiente que tenemos que hacer es automatizar el proceso con un cron job. Accedemos por SSH a nuestro servidor y tras ejecutar crontab -e añadimos al listado de tareas lo siguiente:

Tendríais que sustituir path-to-script por la ruta completa donde se encuentra alojado el script PHP que hemos creado anteriormente y configurar la periodicidad de ejecución a vuestro gusto (en mi caso ejecuto los backups diariamente a las 3:30 de la mañana). Si en vuestro servidor no disponéis de PHP 5.5 instalado, podéis adaptar el comando a la versión de PHP que utilicéis en vuestro servidor.

Sin embargo, si tienes una base de datos relativamente grande, seguro que te habrás encontrado con tablas de varios cientos de miles e incluso millones de registros de las que no necesitas hacer respaldos tan a menudo como de aquella información realmente importante. Y es que no todas las tablas de tu base de datos son igual de importantes ni necesitan ser respaldadas con la misma frecuencia. No es lo mismo una tabla donde almacenas los datos de tus productos o de los pagos, que una tabla donde almacenas información relativamente estática, como puede ser un listado de localidades o de códigos postales. Con una pequeña variación sobre el proceso inicial, podemos conseguir que nuestro proceso automático de backups pase por alto las tablas que no nos interesen.

Evitar algunas tablas al hacer un backup de tu base de datos MySQL

Por suerte, hay una solución muy sencilla para evitarnos tener que hacer un dump de toda una base de datos completa, y por lo tanto ahorrar tamaño de archivo (y tiempo de procesamiento) al generar el fichero de backup, y es utilizar la opción –ignore-table que proporciona el comando mysqldump:

Basta con que repitas en la secuencia de opciones del comando mysqldump tantas veces como tablas quieras pasar por alto la opción –ignore-table=BaseDeDatos.Tabla.

Hacer backups solo de algunas tablas de tu base de datos MySQL

Dependiendo del tamaño y la complejidad de tu base de datos, puede que ninguna de las dos opciones que he planteado hasta ahora (hacer un respaldo de todas las tablas, o bien hacer un respaldo de todas las tablas excluyendo algunas de ellas) sea la más adecuada para ti. Existe una tercera opción que consiste en dividir el proceso de backups en procesos más pequeños que hagan backups solo de un conjunto de tablas indicadas de forma explícita.

Esto es especialmente útil si tienes una base de datos muy grande, ya que el tamaño de los adjuntos que se puede enviar por correo electrónico es limitado. Por lo tanto, si tu fichero comprimido ocupa muchos megas, y además crece cada mes, puede que llegue un momento en el que tus backups no se envíen por correo electrónico. Para ello, una buena solución es descomponer el proceso de backup en otros más pequeños, de forma que en lugar de generar un email con el backup de toda la base de datos diariamente (o con la frecuencia que hayas establecido), generes tantos procesos como necesites.

También es una buena solución si dispones de una base de datos compleja con tablas mucho más importantes y que cambian con más frecuencia que otras. Volviendo al ejemplo de antes, no tiene sentido que hagas respaldo de una tabla que contiene un listado de ciudades estático de forma diaria, pero a lo mejor la tabla donde almacenas tus leads o tus compras o cualquier otra información crítica necesites que se respalde cada hora.

Donde $tables es un array que contiene en cada entrada el nombre de una tabla de la base de datos.

De este modo puedes fácilmente crear por ejemplo un proceso que respalde cada hora tus tablas con información sobre pagos y demás temas críticos, otra que almacene de forma diaria las tablas que se actualizan diariamente, y un proceso que semanalmente haga un backup de aquellas tablas que son estáticas y no suelen registrar cambios ni contienen información crítica.

Revisa de forma periódica tus backups

Que el proceso sea automático no implica que necesariamente te debas olvidar de ello. Yo tengo creada una alarma semanal para revisar la bandeja de entrada de mi cuenta de correo electrónico para backups, con el propósito de comprobar que todos los proyectos siguen generando sus backups de forma correcta y para eliminar los más antiguos. En mi caso, algunas de las bases de datos son muy grandes y los 15GB de espacio de almacenamiento que proporciona Gmail se me acabarían muy rápido si no elimino las copias de seguridad más antiguas (y que ya no necesito).

 

Este post fue publicado originalmente el 14 de junio de 2015, y desde entonces ha sido actualizado en varias ocasiones.

Uso de cookies

Este sitio web, como todos, utiliza cookies. Si continúas navegando por la web estás dando tu consentimiento para la aceptación de la política de cookies de este sitio web. ACEPTAR

Aviso de cookies