Binary Logs
Los binary logs (binlogs) son el mecanismo que MySQL usa para registrar todos los cambios realizados en la base de datos. Cada sentencia que modifica datos o la estructura de las tablas queda registrada en estos archivos. Los binlogs cumplen dos funciones fundamentales: permiten la replicación entre servidores MySQL y hacen posible la recuperación point-in-time después de restaurar un backup.
Verificar el estado del binlog
Para comprobar si los binary logs están habilitados en tu servidor:
SHOW VARIABLES LIKE 'log_bin';| Variable_name | Value |
|---|---|
| log_bin | ON |
Si el valor es OFF, necesitas activarlos en el archivo de configuración:
# /etc/mysql/my.cnf
[mysqld]
log_bin = /var/log/mysql/mysql-bin
server_id = 1A partir de MySQL 8.0, el binlog está habilitado por defecto. En versiones anteriores necesitas activarlo explícitamente. Después de modificar la configuración, reinicia el servidor:
sudo systemctl restart mysqlFormatos del binlog
MySQL soporta tres formatos de binary log, controlados por la variable binlog_format:
SHOW VARIABLES LIKE 'binlog_format';| Variable_name | Value |
|---|---|
| binlog_format | ROW |
El formato ROW registra los cambios a nivel de fila. En lugar de almacenar la sentencia SQL, almacena el estado anterior y posterior de cada fila afectada. Es el formato más seguro para replicación porque el resultado es determinista independientemente del contexto de ejecución. Es el formato por defecto en MySQL 8.0 y posteriores.
El formato STATEMENT registra la sentencia SQL tal como fue ejecutada. Ocupa menos espacio pero puede causar inconsistencias en replicación si la sentencia usa funciones no deterministas como UUID(), RAND() o NOW().
El formato MIXED es un híbrido que usa STATEMENT por defecto pero cambia automáticamente a ROW cuando detecta sentencias potencialmente no seguras para replicación. Ofrece un equilibrio entre eficiencia de almacenamiento y seguridad.
-- Verificar el formato actual
SELECT @@binlog_format;
-- Cambiar el formato para la sesión actual
SET SESSION binlog_format = 'ROW';Listar los binary logs
Para ver los archivos de binlog disponibles en el servidor:
SHOW BINARY LOGS;| Log_name | File_size | Encrypted |
|---|---|---|
| mysql-bin.000001 | 1073741824 | No |
| mysql-bin.000002 | 1073741824 | No |
| mysql-bin.000003 | 536870912 | No |
| mysql-bin.000004 | 98304 | No |
Cada archivo tiene un número secuencial. Cuando un archivo alcanza el tamaño máximo configurado (max_binlog_size, por defecto 1 GB), MySQL crea un nuevo archivo e incrementa el número. También se crea un nuevo archivo al reiniciar el servidor o al ejecutar FLUSH LOGS.
Para ver cuál es el binlog activo actualmente:
SHOW MASTER STATUS;| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
|---|---|---|---|
| mysql-bin.000004 | 98304 |
Ver el contenido con mysqlbinlog
La herramienta mysqlbinlog convierte los archivos binarios en sentencias SQL legibles:
# Ver todo el contenido de un binlog
mysqlbinlog /var/log/mysql/mysql-bin.000004
# Ver eventos en un rango de tiempo
mysqlbinlog --start-datetime="2026-02-14 10:00:00" \
--stop-datetime="2026-02-14 11:00:00" \
/var/log/mysql/mysql-bin.000004
# Ver eventos entre posiciones específicas
mysqlbinlog --start-position=4567 \
--stop-position=8901 \
/var/log/mysql/mysql-bin.000004Para binlogs en formato ROW, las sentencias se muestran codificadas por defecto. Usa --verbose para ver las filas decodificadas:
mysqlbinlog --verbose /var/log/mysql/mysql-bin.000004La salida muestra comentarios indicando los valores de cada columna:
### UPDATE `tienda_mysql`.`productos`
### WHERE
### @1=1
### @2='iPhone 15 Pro'
### @3=1299.99
### SET
### @1=1
### @2='iPhone 15 Pro'
### @3=1349.99Eventos del binlog
Puedes ver los eventos almacenados en un binlog directamente desde SQL:
SHOW BINLOG EVENTS IN 'mysql-bin.000004' LIMIT 10;| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
|---|---|---|---|---|---|
| mysql-bin.000004 | 4 | Format_desc | 1 | 126 | Server ver: 8.4.0 |
| mysql-bin.000004 | 126 | Previous_gtids | 1 | 157 | |
| mysql-bin.000004 | 157 | Anonymous_Gtid | 1 | 236 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000004 | 236 | Query | 1 | 345 | BEGIN |
| mysql-bin.000004 | 345 | Table_map | 1 | 412 | table_id: 108 (tienda_mysql.productos) |
Configuración del tamaño y retención
Controlar el tamaño y la retención de los binlogs es esencial para evitar llenar el disco:
-- Verificar configuración actual
SHOW VARIABLES LIKE 'max_binlog_size';
SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';| Variable_name | Value |
|---|---|
| max_binlog_size | 1073741824 |
| binlog_expire_logs_seconds | 2592000 |
El valor max_binlog_size (1 GB por defecto) determina cuándo MySQL rota al siguiente archivo. El valor binlog_expire_logs_seconds (30 días por defecto) controla cuánto tiempo se conservan los archivos antiguos.
# Configurar retención a 7 días
# /etc/mysql/my.cnf
[mysqld]
binlog_expire_logs_seconds = 604800
max_binlog_size = 512MPurgar binlogs manualmente
Puedes eliminar binlogs antiguos manualmente:
-- Eliminar todos los binlogs anteriores a un archivo específico
PURGE BINARY LOGS TO 'mysql-bin.000003';
-- Eliminar todos los binlogs anteriores a una fecha
PURGE BINARY LOGS BEFORE '2026-02-07 00:00:00';Antes de purgar, asegúrate de que ningún esclavo de replicación necesita esos binlogs y de que tienes un backup que cubre el período correspondiente. Purgar binlogs necesarios para replicación romperá la replicación.
-- Verificar qué binlog están leyendo los esclavos
SHOW SLAVE HOSTS;Rotar el binlog actual
Para cerrar el binlog actual y empezar uno nuevo:
FLUSH BINARY LOGS;Esto es útil antes de hacer un backup, ya que garantiza que los eventos más recientes se escriban en un archivo completo.
Monitorear el espacio del binlog
Los binlogs pueden consumir una cantidad significativa de espacio en disco. Monitorea regularmente:
# Espacio total usado por binlogs
du -sh /var/log/mysql/mysql-bin.*-- Espacio por archivo desde SQL
SHOW BINARY LOGS;Si los binlogs están consumiendo demasiado espacio, revisa la configuración de retención y el volumen de escrituras en tu servidor.
Desactivar el binlog para una sesión
En situaciones específicas, como restaurar un backup o ejecutar operaciones de mantenimiento que no quieres replicar, puedes desactivar temporalmente el binlog para la sesión actual:
SET sql_log_bin = 0;
-- Operaciones que no se registrarán en el binlog
LOAD DATA INFILE '/tmp/datos_masivos.csv' INTO TABLE productos ...;
SET sql_log_bin = 1;Esta variable solo afecta a la sesión actual y requiere el privilegio SYSTEM_VARIABLES_ADMIN o SUPER.
Binlog y rendimiento
Los binary logs añaden un overhead de escritura porque cada cambio se escribe tanto en las tablas InnoDB como en el binlog. En servidores con muchas escrituras, este overhead puede ser significativo. La variable sync_binlog controla cuándo se sincroniza el binlog con el disco:
SHOW VARIABLES LIKE 'sync_binlog';| Variable_name | Value |
|---|---|
| sync_binlog | 1 |
Un valor de 1 significa que el binlog se sincroniza con cada transacción, lo que es lo más seguro pero lo más lento. Un valor mayor o 0 reduce el overhead pero aumenta el riesgo de perder eventos en caso de un fallo.
Los binary logs son la columna vertebral de la replicación y la recuperación en MySQL. Entender cómo funcionan te da el control necesario para configurar estrategias de alta disponibilidad y recuperación ante desastres. En el siguiente artículo veremos los slow query logs, que te ayudan a identificar las consultas que necesitan optimización.
Escrito por Eduardo Lázaro
