Copia de Seguridad · 10 min read · Dec 10, 2025
Copia de seguridad incremental de MySQL - Copia de seguridad y recuperación en el tiempo de bases de datos InnoDB y MyIsam
Hacer copias de seguridad incrementales es un requisito importante para grandes bases de datos de producción. Sin una copia de seguridad incremental segura, no puedes decirte a ti mismo que tienes una base de datos de producción confiable. Porque debes tener suficientes datos para poder recuperar tu base de datos en casos de emergencia. Después de buscar en Internet, no pude encontrar ninguna herramienta que pudiera hacer una copia de seguridad incremental completa para MyISAM e InnoDB en un entorno mixto donde las aplicaciones utilizan ambos motores de base de datos simultáneamente (quizás no soy un buscador experto en Google e Internet). Así que decidí escribir esta, pero para evitar perder tiempo y beneficiarme de otras soluciones de código abierto, preferí agregar esta función al script -automysqlbackup- que es el mejor script para copias de seguridad completas en simplicidad y uso generalizado.
Mecanismo
Utilizamos la función Post- y Pre de automysqlbackup para hacer una copia de seguridad incremental. Antes de comenzar una copia de seguridad completa, mysql-backup-pre ejecuta una consulta para bloquear toda la base de datos durante el proceso de copia de seguridad porque debemos congelar el binlog para evitar cualquier cambio mientras se está ejecutando la copia de seguridad. El nombre y la posición del binlog no pueden cambiar durante la copia de seguridad. La posición del log binario es muy crucial en el posterior proceso de copia de seguridad incremental y se utilizará como punto de partida para comenzar la siguiente copia de seguridad incremental. Después de finalizar la copia de seguridad completa, mysql-backup-post elimina el bloqueo de la base de datos.
Consulta de bloqueo: FLUSH TABLES WITH READ LOCK; SELECT SLEEP(86400)
Encontrar consultas de bloqueo: mysql -u[usuario] -p[contraseña] -e “show processlist” | grep “SELECT SLEEP(86400)” | awk ‘{print $1}’
Requisitos
- privilegios de root para instalar el paquete y actualizar mysql.conf
- paquete mysql-community-client
- instalación de automysqlbackup y mysql-incremental
Instalación
Instala el paquete mysql-community-client para tu distribución.
Nota: después de la instalación de MySQL, debes tener el comando ‘mysqlshow’.
Instala automysqlbackup:
descarga el paquete de https://sourceforge.net/projects/automysqlbackup/tar -xzf [RutaDondeGuardasteElArchivoTar] -C /tmp/cd /tmp/./install.shDurante la instalación de automysqlbackup, se te preguntará sobre la ruta de automysqlbackup.conf y su binario, puedes dejar los valores predeterminados sin ningún cambio.
rm /etc/automysqlbackup/myserver.confInstala el mysql-incremental: Descarga el paquete de https://sourceforge.net/projects/mysqlincrementalbackup/
cd /tmp
wget http://downloads.sourceforge.net/project/mysqlincrementalbackup/mysql-incremental.tar.gz
tar xfz mysql-incremental.tar.gzcp mysql-incremental /etc/automysqlbackup/chmod 755 /etc/automysqlbackup/mysql-incrementalcp mysql-backup-post /etc/automysqlbackup/chmod 755 /etc/automysqlbackup/mysql-backup-postcp mysql-backup-pre /etc/automysqlbackup/chmod 755 /etc/automysqlbackup/mysql-backup-preActualiza el automysqlbackup.conf:
Encuentra los siguientes parámetros, descoméntalos y cámbialos:
CONFIG_mysql_dump_username='Nombre de usuario de Mysql. Debe tener privilegios para obtener el bloqueo'
CONFIG_mysql_dump_password='Contraseña'
CONFIG_backup_dir='El directorio de copia de seguridad donde deseas almacenar la copia de seguridad completa e incremental'
CONFIG_db_names=('nombreBaseDeDatos1' 'nombreBaseDeDatos2' )
CONFIG_db_month_names=('nombreBaseDeDatos1' 'nombreBaseDeDatos2' )
CONFIG_mysql_dump_master_data=2
CONFIG_prebackup="/etc/automysqlbackup/mysql-backup-pre"
CONFIG_postbackup="/etc/automysqlbackup/mysql-backup-post"Actualiza my.cnf:
Edita el archivo de configuración de MySQL:
nano /etc/mysql/my.cnf1- Formato de BinLog
Debido a algunas limitaciones en el formato STATEMENT, mi recomendación es establecer el formato basado en ROW. Para más información, consulta la sección ‘solución de problemas’ en este cómo hacerlo. Puedes verificar el tipo de formato de log binario ejecutando la consulta “ select @@binlog_format; “. Para modificar el formato logbin, debes agregar binlog_format = ROW a mysql.conf o my.cnf.
2- binlog_do_db
Debes especificar las bases de datos en las que pretendes tener los cambios relacionados en el log binario. Ten en cuenta que si no especificas ninguna base de datos, cualquier cambio en cualquier base de datos se registrará en el log binario. En este caso, si eliges el formato STATEMENT, podrías tener algunos problemas al restaurar desde la copia de seguridad incremental y los archivos binlog. Puedes agregar bases de datos a esta opción:
binlog_do_db = NOMBREBASEDEDATOS1
binlog_do_db = NOMBREBASEDEDATOS23- expire_logs_days
Para tener archivos de log binario durante más tiempo, puedes aumentar este parámetro a un valor más alto. Mi recomendación es 60 días. Así que debes agregar o cambiarlo a “ expire_logs_days = 60 “.
4- log-bin
El directorio donde se almacenarán los logs binarios. En versiones antiguas de MySQL, mysql-incremental podría no ser capaz de encontrar la ruta correcta. Así que si obtienes un error sobre esto después de ejecutar mysql-incremental, debes actualizar el script mysql-incremental y establecer la ruta del log binario.
5- log_slave_updates
Si estás configurando la copia de seguridad mysql-incremental en un servidor esclavo, debes habilitar esta opción. Normalmente, un esclavo no registra actualizaciones en su propio log binario como si las hubiera recibido de un servidor maestro. Esta opción le dice al esclavo que registre las actualizaciones realizadas por sus hilos SQL en su propio log binario. http://dev.mysql.com/doc/refman/5.1/en/replication-options-slave.html#option_mysqld_log-slave-updates
Ejecutar automysqlbackup
Ejecuta automysqlbackup manualmente para tener al menos una copia de seguridad completa de tus bases de datos especificadas.
automysqlbackupDespués de ejecutar el comando con éxito, verifica el archivo /[DirectorioDeCopiaDeSeguridadEnAutomysqlbackup]/status/backup_info para la nueva información añadida sobre la copia de seguridad diaria. Para detalles de errores, verifica /var/log/Backup_Post_Pre_log. El archivo de copia de seguridad se almacenará en el directorio /[DirectorioDeCopiaDeSeguridadEnAutomysqlbackup]/daily/[NombreDeLaBaseDeDatos]/.
Ejecutar mysql-incremental
Ejecuta mysql-incremental manualmente ahora para tener al menos una copia de seguridad por hora.
mysql-incrementalEn caso de un error, los detalles se registran en el archivo “ /var/log/Backup_Incremental_Log “. Los archivos de copia de seguridad incrementales se almacenarán en el directorio /[DirectorioDeCopiaDeSeguridadEnAutomysqlbackup]/IncrementalBackup/.
Editar el crontab de root
Puedes programar mysql-incremental para más de una hora. Puedes encontrar el tiempo total de la copia de seguridad completa en backup_status y luego, basado en ese valor, establecer un horario preciso. Por supuesto, la copia de seguridad incremental de mysql tiene un mecanismo para encontrar cualquier copia de seguridad completa en ejecución antes de comenzar, así que no hay preocupación por conflictos entre la copia de seguridad incremental y la completa.
crontab -e5 00 * * * root /usr/local/bin/automysqlbackup
25 * * * * root /etc/automysqlbackup/mysql-incrementalRestaurar base de datos
Para restaurar hasta un momento específico (recuperación en el tiempo), primero debes restaurar una copia de seguridad diaria completa y luego restaurar secuencialmente los archivos de copia de seguridad incrementales relacionados. Para aclarar más, aquí están los pasos para recuperar la base de datos testDB. En un escenario de muestra, pretendemos recuperar nuestros datos hasta el 2015-5-01 a las 2 AM. hemos establecido /backup como nuestro directorio principal de copias de seguridad y testDB como nuestra base de datos objetivo:
1- mysql -u root -p NombreDeLaBaseDeDatos < /backup/daily/testDB/daily_NombreDeLaBaseDeDatos_2015-05-16_00h05m_Sábado.sql.gz
2- mysql -u root -p NombreDeLaBaseDeDatos < /backup/IncrementalBackup/2015-5-01_Incremental/testDB/testDB_IncrementalBackup_2015-5-01_00h25m.1
3- mysql -u root -p NombreDeLaBaseDeDatos < /backup/IncrementalBackup/2015-5-01_Incremental/testDB/testDB_IncrementalBackup_2015-5-01_01h25m.2
4- mysql -u root -p NombreDeLaBaseDeDatos < /backup/IncrementalBackup/2015-5-01_Incremental/testDB/testDB_IncrementalBackup_2015-5-01_02h25m.3Notas importantes y solución de problemas
MySQL admite diferentes formatos para el log binario. Algunas versiones de Mysql utilizan ‘basado en declaraciones’ como formato de binlog, que este tipo de binlog tiene algunas limitaciones a las que debemos prestar mucha atención cuando pretendemos usarlo en el procedimiento de copia de seguridad incremental. Cuando mysql está configurado en formato basado en declaraciones, no puede filtrar correctamente según las bases de datos. Si estableces ‘USE o \u’ para cambiar de base de datos y luego actualizas otra base de datos que no está incluida en binlog-do-db, la declaración se registrará en el archivo binlog, lo cual no es un estado deseable y expondrá algunos problemas al restaurar según una base de datos específica y también si cambias a otra base de datos que no está incluida en binlog-do-db y actualizas una base de datos que está incluida en binlog-do-db, la declaración no se registrará en el archivo binlog. Nuestro propósito al agregar bases de datos a binlog-do-db es filtrar según la base de datos, pero no funciona como se esperaba. Si USE o \u no se ejecuta antes de ejecutar consultas, mysqlbinlog no puede extraer ‘consultas de actualización’ relacionadas con una base de datos. Explicaremos más este problema con los siguientes escenarios:
bases de datos:
- binlog
- persona (tabla)
- binlog2
- persona (tabla)
binlog-do-db=binlog2 (se supone que solo se registran los cambios de esta base de datos en el archivo binlog)
--------Escenario 1---------
\u binlog2
insert into persona (datos) values ('17') ---> registrado en binlog *estado deseado*
insert into binlog.persona (datos) values ('25'); ---> registrado en binlog (la base de datos objetivo es 'binlog' ) *estado no deseado*
--------Escenario 2---------
\u binlog
insert into persona (datos) values ('17') ---> no se registra en binlog *estado deseado*
insert into binlog2.persona (datos) values ('25'); ---> no se registra en binlog (la base de datos objetivo es 'binlog2' ) *estado no deseado* porque la base de datos binlog2 está siendo cambiada, así que queremos tener este cambio, pero no se registrará en el archivo logbin
--------Escenario 3---------
sí solo te conectas a la base de datos sin ninguna declaración USE o \u, todas las actualizaciones en cualquier base de datos se registrarán, pero mysqlbinlog no podrá filtrar según una base de datos específica, así que ese no es un estado deseable para nuestro propósito en la copia de seguridad incremental. Usar USE o \u antes de ejecutar consultas de actualización es muy importante. Porque mysqlbinlog encuentra consultas de actualización basadas en la declaración USE en el archivo binlog.Solución alternativa para el problema mencionado
Definiendo usuarios en bases de datos de tal manera que cada usuario solo tenga acceso a una base de datos para actualizar (usuario de aplicación) y cuando se conecta a la base de datos, debe especificarse el nombre de la base de datos. Por supuesto, la mayoría de las aplicaciones tienen un archivo de configuración en el que se establecen las credenciales y el nombre de la base de datos, así que en ese caso no tendrás acceso cruzado a las bases de datos y no habrá preocupación por usar “\USE o \u”.
Si utilizas el formato de binlog basado en filas, todos los problemas mencionados desaparecerán. En otras palabras, el formato basado en filas es un método mucho más adecuado para el binlog. https://dev.mysql.com/doc/refman/5.1/en/replication-options-binary-log.html
Archivos de registro
Intenté registrar todo en un archivo de registro para que puedas encontrar suficiente información en los registros:
/var/log/Backup_Post_Pre_log
/var/log/Backup_Incremental_Log
/[DirectorioDeCopiaDeSeguridadEspecificadoEnAutomysqlbackup.conf]/status/backup_info
El archivo “ backup_info “ contiene la información detallada sobre la copia de seguridad y cuándo se finalizó la copia de seguridad (Los tiempos están en formato de tiempo Unix). Contiene el nombre del binlog y la posición del punto de tiempo en el que comenzó la copia de seguridad, el tipo de copia de seguridad, el número de copias de seguridad desde la última copia de seguridad completa y la duración de la copia de seguridad.
Ejemplo de backup_info:
1431043501,mysql-bin.000026,120,Diaria,2015-05-08,0,24
1431044701,mysql-bin.000026,120,Por Hora,2015-05-08,1,1Aquí hay una descripción de los diferentes valores:
1º) 1431043501 : indica el momento en que se ha finalizado la copia de seguridad. Puedes ejecutar el comando date --date @1431043501 en el servidor donde se realizó la copia de seguridad para verlo en un formato legible por humanos.
2º) Mysql-bin.000026 : indica el nombre del log binario hasta el cual se ha realizado la copia de seguridad.
3º) 120 : indica la posición del binlog hasta la cual se ha realizado la copia de seguridad en el log binario.
4º) Diaria/Por Hora: indica el tipo de copia de seguridad. Diaria significa la copia de seguridad completa realizada por el script automysqlbackup y Por Hora es realizada por el script mysql-incremental.
5º) 2015-05-08: La fecha en que se realizó la copia de seguridad. Esta fecha se utilizará para crear el directorio para la copia de seguridad incremental y también como base para restaurar copias de seguridad por hora. En el procedimiento de restauración, primero se restaura una copia de seguridad completa y luego se restauran secuencialmente otras copias de seguridad incrementales.
6º) 0 : indica el número de copias de seguridad desde la última copia de seguridad completa. 0 significa que la copia de seguridad es completa y otros significan por hora. Este número es muy importante en el procedimiento de restauración.
7º) 24: La duración de la copia de seguridad en segundos.Informe de errores
Puedes informar errores o dar tus sugerencias y comentarios en https://sourceforge.net/projects/mysqlincrementalbackup.
Recibe nuevas publicaciones en tu bandeja de entrada.
No spam. Cancela la suscripción en cualquier momento.