Configuración de Copias de Seguridad Incrementales de MySQL con Percona XtraBackup

Construye y restaura copias de seguridad incrementales de MySQL con Percona XtraBackup, incluyendo copias completas, encadenamiento de LSN, pasos de preparación y copia de retorno.

Configuración de Copias de Seguridad Incrementales de MySQL con Percona XtraBackup

Percona XtraBackup (PXB) puede realizar copias de seguridad en caliente de servidores compatibles con MySQL que utilicen InnoDB. Las copias completas son sencillas, pero las bases de datos grandes a menudo necesitan copias de seguridad incrementales para no copiar las mismas páginas cada noche.

Esta guía cubre los comandos para una copia de seguridad base completa, copias incrementales encadenadas y la secuencia de restauración que aplica cada incremental en orden.

Entendiendo el Mecanismo Incremental de Percona XtraBackup

PXB se basa en el funcionamiento interno del motor de almacenamiento InnoDB, específicamente rastreando cambios usando el Número de Secuencia de Registro (LSN). Cada página de InnoDB está etiquetada con un LSN. Cuando PXB realiza una copia de seguridad incremental, registra solo aquellas páginas cuyo LSN es mayor que el LSN registrado en el momento de la copia de seguridad anterior.

Fundamentalmente, las copias de seguridad incrementales requieren una copia de seguridad base completa para establecer el punto de partida. Todas las copias de seguridad incrementales posteriores se encadenan, haciendo referencia a la copia de seguridad inmediatamente anterior (que puede ser la copia base u otra incremental).

Archivos y Conceptos Clave

  • LSN (Número de Secuencia de Registro): El marcador utilizado para determinar dónde comienzan y terminan los cambios.
  • xtrabackup_checkpoints: Un archivo creado durante cada copia de seguridad que contiene to_lsn (el LSN alcanzado al final de la copia) y, para copias incrementales, from_lsn (el LSN de inicio).
  • --incremental-basedir: La bandera esencial utilizada durante las ejecuciones incrementales, que apunta a PXB al directorio de la copia de seguridad anterior (que determina el LSN de inicio).

Paso 1: Realizando la Copia de Seguridad Base Completa

Antes de tomar cualquier instantánea incremental, se debe crear una copia de seguridad base completa y consistente. Esto establece la base para toda la cadena de copias de seguridad.

Comience definiendo un directorio claro para la copia completa:

# Define el directorio base para la copia completa
BASE_DIR="/data/backups/2023-10-01_FULL"

# Crea el directorio
mkdir -p $BASE_DIR

# Ejecuta la copia completa
xtrabackup --backup \
  --target-dir=$BASE_DIR \
  --user=root --password=secret_password \
  --datadir=/var/lib/mysql

# Verifica el LSN de la copia completa
cat $BASE_DIR/xtrabackup_checkpoints | grep 'to_lsn'

Nota: El target-dir debe estar vacío o no existir al iniciar el proceso de copia. Los privilegios requeridos varían según la versión de MySQL y XtraBackup, por lo que se recomienda crear un usuario de copia de seguridad dedicado siguiendo la guía de privilegios actual de Percona en lugar de reutilizar root.

Paso 2: Tomando la Primera Copia de Seguridad Incremental

Para realizar la primera copia incremental, debemos hacer referencia al directorio de la copia base completa usando la bandera --incremental-basedir. PXB leerá el to_lsn de la copia base y solo copiará las páginas que hayan cambiado desde ese punto.

# Define el directorio para la primera copia incremental
INCREMENTAL_1_DIR="/data/backups/2023-10-02_INC1"

# Ejecuta la copia incremental, haciendo referencia a la base completa
xtrabackup --backup \
  --target-dir=$INCREMENTAL_1_DIR \
  --incremental-basedir=/data/backups/2023-10-01_FULL \
  --user=root --password=secret_password

Paso 3: Encadenando Copias de Seguridad Incrementales Posteriores

Para cualquier copia incremental posterior (INC2, INC3, etc.), el --incremental-basedir debe apuntar al directorio de la copia incremental inmediatamente anterior.

Si queremos crear INC2 basada en los cambios desde INC1:

# Define el directorio para la segunda copia incremental
INCREMENTAL_2_DIR="/data/backups/2023-10-03_INC2"

# Ejecuta la copia incremental, haciendo referencia a la incremental anterior (INC1)
xtrabackup --backup \
  --target-dir=$INCREMENTAL_2_DIR \
  --incremental-basedir=/data/backups/2023-10-02_INC1 \
  --user=root --password=secret_password

Este encadenamiento continúa mientras se mantenga la secuencia. Si algún eslabón de la cadena se rompe (es decir, un directorio falta), el proceso de restauración fallará.

Restauración: Aplicando Cambios Incrementales

Restaurar un conjunto de copias incrementales es un proceso de múltiples pasos que implica aplicar los cambios secuencialmente a la copia base. A diferencia de una copia completa, las copias incrementales no se pueden copiar directamente al directorio de datos.

Fase de Restauración 1: Preparando la Copia Base

Primero, la copia base debe ser preparada. Esto se hace típicamente en un área de preparación temporal para garantizar la seguridad de los datos.

Al preparar la copia base, PXB realiza dos acciones esenciales:

  1. Aplica las transacciones confirmadas (el registro de rehacer).
  2. Revierte las transacciones no confirmadas.

Usamos la bandera --prepare, pero críticamente, añadimos la bandera --apply-log-only. Esto evita que PXB revierta transacciones no confirmadas, lo cual es necesario porque los registros incrementales posteriores necesitan esos fragmentos de transacción para completar la restauración.

# Define el directorio de preparación
RESTORE_TARGET="/data/restore_staging"

# Copia los archivos de la copia base completa al área de preparación
rsync -avr /data/backups/2023-10-01_FULL/ $RESTORE_TARGET

# Prepara la copia base, manteniéndola lista para incrementos
xtrabackup --prepare --target-dir=$RESTORE_TARGET --apply-log-only

# Busca confirmación: 'completed OK!'

Fase de Restauración 2: Aplicando Copias Incrementales Secuencialmente

A continuación, aplica cada copia incremental en el orden cronológico exacto en que fueron tomadas. Cada comando debe hacer referencia al directorio de preparación (la copia base que se está modificando actualmente) y usar la bandera --incremental-dir apuntando a la instantánea incremental específica.

# Aplica Incremental 1
xtrabackup --prepare --target-dir=$RESTORE_TARGET \
  --incremental-dir=/data/backups/2023-10-02_INC1 \
  --apply-log-only

# Aplica Incremental 2
xtrabackup --prepare --target-dir=$RESTORE_TARGET \
  --incremental-dir=/data/backups/2023-10-03_INC2 \
  --apply-log-only

# ... continúa para todos los incrementos requeridos ...

Fase de Restauración 3: Finalizando la Preparación

Una vez que se ha aplicado la última instantánea incremental deseada, ejecuta el paso de preparación final sin la bandera --apply-log-only. Esto permite que PXB realice la limpieza final, revirtiendo cualquier transacción que aún no estuviera confirmada en toda la secuencia de copias, resultando en un estado consistente.

# Finaliza la preparación (sin --apply-log-only)
xtrabackup --prepare --target-dir=$RESTORE_TARGET

# IMPORTANTE: Busca la confirmación final que indica 'xtrabackup: Recovery completed OK!'

Fase de Restauración 4: Copiando los Datos de Vuelta a MySQL

Después de una preparación exitosa, los datos en el directorio de preparación ($RESTORE_TARGET) son consistentes y están listos para ser usados por el servidor MySQL.

  1. Detén el servicio de MySQL.
  2. Asegúrate de que el directorio de datos de MySQL esté vacío o respaldado (opcional: usa la opción --move-back si está permitido, pero --copy-back es más seguro para la recuperación).
  3. Usa xtrabackup --copy-back para mover los archivos.
  4. Corrige los permisos.
  5. Reinicia MySQL.
# Detén el servicio de MySQL
sudo systemctl stop mysql

# Copia los archivos preparados de vuelta al directorio de datos de MySQL
xtrabackup --copy-back --target-dir=$RESTORE_TARGET

# Asegura la propiedad adecuada de los archivos
sudo chown -R mysql:mysql /var/lib/mysql

# Inicia MySQL
sudo systemctl start mysql

Mejores Prácticas para la Gestión de Copias Incrementales

Automatización y Scripting

Las estrategias de copias incrementales son más efectivas cuando están completamente automatizadas. Los scripts deben gestionar el encadenamiento de LSN automáticamente, identificando dinámicamente el directorio de copia más reciente para usar con la bandera --incremental-basedir.

Política de Retención

Las cadenas incrementales pueden volverse muy largas, haciendo la restauración lenta y frágil. Periódicamente, renueva la cadena tomando una nueva copia completa. Algunos equipos también mantienen copias completas semanales y mensuales bajo un modelo de retención Abuelo-Padre-Hijo.

Compresión y Limitación

Para servidores muy ocupados, considera usar la opción --throttle durante la fase de copia para limitar las operaciones de E/S. Usa --compress para reducir el tamaño de la copia, lo cual es muy beneficioso para los conjuntos de datos más pequeños generados por las copias incrementales.

# Ejemplo con compresión y limitación
xtrabackup --backup \
  --target-dir=$INCREMENTAL_3_DIR \
  --incremental-basedir=$INCREMENTAL_2_DIR \
  --compress \
  --throttle=100

Verificación y Monitoreo

Siempre prueba tus procedimientos de restauración regularmente. Una copia de seguridad que no se puede restaurar es inútil. Monitorea el espacio en disco consumido por tu cadena incremental, especialmente antes de iniciar una nueva copia base completa.

Conclusión

XtraBackup incremental funciona solo cuando la cadena está intacta: copia completa, primera incremental basada en la copia completa, luego cada incremental posterior basada en la copia anterior. Durante la restauración, prepara la base con --apply-log-only, aplica cada incremental en orden, ejecuta una preparación final sin --apply-log-only, y solo entonces copia los datos preparados de vuelta a MySQL.