Backups

Cuestiones sobre backups, tips con rsync, etc.

Rsync sobre sistemas remotos

Introducción

rsync es una aplicación que ofrece un sistema de transmisión de ficheros, de forma incremental que permite la generación de sistemas de backups muy efectivos. Uno de los mejores ejemplos es Time Machine de Apple, que no es sino una interface visual de rsync

Sin embargo muchos sitios expresan o ponen a disposición de los usuarios ejemplos que usados en un escenario diferente del usado en un entorno personal o corporativo, son fuente de problemas.

Como norma general se usa el parámetro -a o --archive el cual es el equivalente a -rlptgoD lo cual supone que los parámetros de usuario y grupo, y los permisos de lectura, escritura y ejecución intentarán ser clonados, cosa que no funcionará e incluso creará problemas silenciosos en un entorno en el que los usuarios y grupos no son los mismos en origen que en destino.

Parámetros de rsync para usar en sistemas remotos no coincidentes

El escenario es el de realizar un backup de un sistema completo (disco principal) en un usuario remoto (no root)

# rsync --devices --specials --hard-links --one-file-system --recursive --links --times --no-perms --no-group --no-owner --itemize-changes  / remote_user@remote.host:/remote/path

Parámetros con rsync-time-backup

Dado que es un programa basado en rsync con sus propias normas para anular su configuración debemos usar otro camino con --rsync-set-flags

--rsync-set-flags "-D --numeric-ids --links --hard-links -rlt --no-perms --no-group --no-owner --itemize-changes"

Parámetros

Deberás ajustar los parámetros a tu escenario, pero te explico los que he usado aquí.

Corto Normal Descripción
-D El mismo que --devices -aspecials
-l --links copia los enlaces simbólicos como enlaces simbólicos
-H --hard-links preserva los enlaces duros
-x --one-file-system No copiará los dispositivos montados. Si tu sistemas tiene particiones como /var /usr y quieres copiar algo de aqui, esta opción NO debería estar aquí
-r --recursive Copiara recursivamente
-t --times Necesario sobre todo si no usamos -a, ya que será parte de la marca para saber si el fichero debe o no ser transferido o actualizado
--no-perms No copiara los permisos originales. De esta forma no nos encontraremos con problemas de eliminación, uso, debidos a cuestiones de propietario /permisos. Como contrapartida, nos obliga a a tener un sistema de metadatos, que sí guarde esta información.
--no-group Para evitar el uso del grupo del propietario del fichero
--no-owner Para evitar actualizar el propietario del fichero

Aviso

Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de Castris

Si necesitas soporte profesional puedes contratar con Castris soporte profesional.

rsync-time-backup: include y exclude

Introducción

rsync-time-backup es una buena herramienta con la salvedad de que no tiene limite por fechas de los backlups continuos basados en rsync. Es un clon de Time Machine de Mac.

Es un fork mantenido por Castrsi, con algunas mejoras.

Si trabajamos con sistemas completos hay muchos directorios y ficheros que debemos excluir e incluir.

Actualziacion 17/09/2025

Include and Exclude

Si trabajamos con sistemas remotos, deberías leer Rsync sobre sistemas remotos o tendrás problemas con los permisos y el pruning en las rotaciones de backups expirados.

Ejemplo que a mi me funciona, y que deja el orden correcto para evitar problemas.

Cualquier cambio, deberías probar si funciona.

# Primero incluir lo que quieres mantener
+ /home/***
+ /usr/local/directadmin/***
+ /var/www/***

# Luego excluir directorios del sistema
- /bin/***
- /boot/***
- /cdrom/***
- /dev/***
- /lib/***
- /lib32/***
- /lib64/***
- /libx32/***
- /media/***
- /mnt/***
- /opt/***
- /proc/***
- /run/***
- /sbin/***
- /sbin.usr-is-merged/***
- /snap/***
- /srv/***
- /swap.img
- /sys/***
- /tmp/***
- /usr/***
- /var/***

# Excluir patrones específicos
- *.git*
- */cache/*
- */usr/*

Una respuesta que ta ayudará a entender el RsyncTutorial que propone el desarrollador, algo lioso.

Aviso

Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de Castris

Si necesitas soporte profesional puedes contratar con Castris soporte profesional.

Diagnóstico y resolución de fallos en snapshots LVM durante backups en Proxmox

Contexto del problema

Síntomas iniciales

Durante la ejecución de backups automatizados en Proxmox 7.2.14, se producían fallos intermitentes al procesar el disco secundario (disco-1) de la VM 473, lo que causaba error en el tamaño de la copia.

Processing backup of disk 473-0
Transferring: kvm-473-0.2025-10-27-05-41-56.gz
25442648064 bytes (25 GB, 24 GiB) copied, 129 s, 197 MB/s
dd: error reading '/dev/lvm/snap-473-0': Input/output error
3051+1 records in
3051+1 records out
25594953728 bytes (26 GB, 24 GiB) copied, 130.739 s, 196 MB/s

Características del sistema

Proceso de análisis

Fase 1: Verificación de espacio en VG

Descartado rápidamente. El Volume Group tenía espacio abundante:

pvs -o +pv_name,vg_name,pv_size,pv_free
PV             VG   Fmt  Attr PSize  PFree
/dev/nvme1n1p1 lvm  lvm2 a--  <1.75t  757.49g

Conclusión: 757GB libres, suficiente para snapshots.

Fase 2: Revisión de logs del sistema

dmesg -T | grep -i "error\|fail\|i/o" | tail -50

Hallazgos:

[Mon Oct 27 05:38:02 2025] Buffer I/O error on dev dm-54, logical block 5923136, async page read
[Mon Oct 27 05:38:02 2025] Buffer I/O error on dev dm-54, logical block 5923136, async page read
[Mon Oct 27 05:38:02 2025] Buffer I/O error on dev dm-54, logical block 5923136, async page read
[Mon Oct 27 05:44:05 2025] Buffer I/O error on dev dm-51, logical block 6248768, async page read

Sospecha inicial: Problema de hardware en disco NVMe.

Fase 3: Verificación de salud del disco NVMe

smartctl -a /dev/nvme1n1p1

Resultado crítico:

SMART overall-health self-assessment test result: PASSED
Media and Data Integrity Errors:    0
Error Information Log Entries:      0
Available Spare:                    100%
Percentage Used:                    8%

Conclusión: El disco NVMe está perfectamente sano. No es problema de hardware.

Fase 4: Análisis de device mapper

Intentamos localizar los dispositivos dm-54 y dm-51 reportados en dmesg:

dmsetup ls --tree | grep -E "dm-5[14]"
ls -la /dev/dm-54 /dev/dm-51
# cannot access '/dev/dm-54': No such file or directory
# cannot access '/dev/dm-51': No such file or directory

Interpretación: Los snapshots temporales ya fueron destruidos tras el backup (comportamiento normal). Los errores ocurrieron durante la existencia efímera del snapshot.

Hipótesis evaluadas

Hipótesis 1: Sectores defectuosos en disco físico

Hipótesis 2: Bug del kernel 5.15 con snapshots bajo carga

Hipótesis 3: Snapshot COW lleno durante backup

Diagnóstico definitivo

Herramienta de diagnóstico utilizada

Durante la ejecución del backup, se monitorizó en tiempo real el estado de los snapshots:

watch -n1 'lvs -a | grep snap'

Output revelador:

Every 1.0s: lvs -a | grep snap                                                                                 
  snap-473-0    lvm  swi-aos---   1.00g      vm-473-disk-0 7.61
  snap-473-1    lvm  swi-I-s---   1.00g      vm-473-disk-1 100.00
  snap-999-0    vg   swi-a-s---   3.00g      vm-999-disk-0 9.09

Interpretación de los flags LVM

Campo Valor Significado
snap-473-0 swi-aos--- Snapshot activo, OK (7.61% uso)
snap-473-1 swi-I-s--- Snapshot INVÁLIDO (letra I mayúscula)
snap-473-1 100.00 COW al 100% - completamente lleno

Conclusión definitiva:

El snapshot del disco-1 alcanzó el 100% de su espacio Copy-On-Write (1GB), provocando:

  1. Marcado del snapshot como inválido por LVM
  2. Cualquier lectura posterior genera "Buffer I/O error"
  3. Fallo del proceso de backup

Causa raíz

¿Por qué el disco-1 y no el disco-0?

snap-473-0: 7.61% usado  → VM escribe poco en este disco durante backup
snap-473-1: 100% usado   → VM escribe intensivamente en este disco

El disco-1 contiene elementos con alta tasa de escritura:

El problema del tamaño de snapshot

Configuración problemática:

# Snapshot de 1GB para disco de 35GB = ~3% del tamaño del disco
lvcreate -L1G -s -n snap-473-1 /dev/lvm/vm-473-disk-1

Durante el backup (que puede tardar 2-3 minutos con 35GB):

Solución implementada

Ajuste del tamaño de snapshot en scripts de backup

Al ser un proceso solapado de hosts snapshots con creación aleatoria de marca de tiempo, y de mysqldump en el KVM, el cual por tamaños era causa del rpoblema (> 6G) no procede el aumento tan significativo de porcentaje de snapshot

Dado que hay incidentes similares, y ya habia alguna modifciaciones al script de backups de mysql, mysqldump_remote_utility.sh se procede a realizar una mejora en el script, para poder realizar los backup al vuelo, (directamente mysqldump + compresión sobre la conexión).

Consultar README_mysqldump_remote.md

Datos relevantes para otros cálculos

Cálculo del tamaño óptimo de snapshot

Tamaño disco Actividad VM Snapshot recomendado
35GB Baja (logs, configs) 10% = 3.5GB
35GB Media (servicios web) 20% = 7GB
35GB Alta (BD, swap activo) 30% = 10GB
100GB+ Alta 20-30GB (límite práctico)

Verificación del tamaño durante backup

Añadir monitorización al script de backup:

#!/bin/bash
# En paralelo durante el backup
watch -n5 "lvs -a | grep snap-473 | awk '{print \$1, \$6}'"

# O con alertas:
while true; do
    USAGE=$(lvs --noheadings -o snap_percent snap-473-1 2>/dev/null | xargs)
    if (( $(echo "$USAGE > 80" | bc -l) )); then
        echo "WARNING: Snapshot at ${USAGE}%"
    fi
    sleep 5
done

Comandos útiles para diagnóstico

Monitorización en tiempo real

# Ver estado de snapshots activos
watch -n1 'lvs -a | grep snap'

# Ver uso específico con más detalle
lvs -a -o +chunksize,snap_percent | grep snap

# Logs en tiempo real
dmesg -wT | grep -i "error\|snapshot"

Post-mortem tras fallo

# Revisar logs del kernel
dmesg -T | grep -i "error\|fail\|i/o" | tail -50

# Estado de los VG
vgs -o +lv_metadata_size,metadata_percent

# Snapshots huérfanos o colgados
lvs -a | grep snap

# Salud del storage
smartctl -a /dev/nvmeXnY

Lecciones aprendidas

  1. Los errores de I/O en dm-XX no siempre son hardware: Primero verificar el estado de snapshots LVM.

  2. El tamaño de snapshot no es porcentaje fijo: Depende de la tasa de escritura durante el backup, no del tamaño del disco.

  3. Herramienta clave: watch -n1 'lvs -a | grep snap' permite ver en tiempo real el llenado del COW.

  4. Pattern recognition: "Primera copia OK, segunda FAIL" → indica recurso que se agota (no hardware defectuoso).

  5. Flag 'I' en lvs: Snapshot inválido por COW lleno. Crítico para diagnóstico rápido.

Prevención futura

Script de validación pre-backup

#!/bin/bash
# validate_snapshot_size.sh

VM_ID=$1
DISK_NUM=$2
DISK_LV="/dev/lvm/vm-${VM_ID}-disk-${DISK_NUM}"

# Obtener tamaño del disco
DISK_SIZE_G=$(lvs --noheadings -o lv_size --units g "$DISK_LV" | tr -d 'g' | xargs)

# Calcular snapshot recomendado (30%)
RECOMMENDED_G=$(echo "$DISK_SIZE_G * 0.3 / 1" | bc)

# Obtener espacio libre en VG
VG_NAME=$(lvs --noheadings -o vg_name "$DISK_LV" | xargs)
FREE_G=$(vgs --noheadings -o vg_free --units g "$VG_NAME" | tr -d 'g' | xargs)

echo "Disco: $DISK_LV"
echo "Tamaño: ${DISK_SIZE_G}G"
echo "Snapshot recomendado: ${RECOMMENDED_G}G"
echo "Espacio libre en VG: ${FREE_G}G"

if (( $(echo "$FREE_G < $RECOMMENDED_G" | bc -l) )); then
    echo "ERROR: Espacio insuficiente en VG"
    exit 1
fi

echo "OK: Suficiente espacio disponible"

Monitorización automatizada

#!/bin/bash
# monitor_snapshots.sh
# Ejecutar en paralelo durante backups

THRESHOLD=85  # Alertar al 85% de uso

while true; do
    lvs -a --noheadings -o lv_name,snap_percent 2>/dev/null | grep snap | while read name percent; do
        if [ -n "$percent" ]; then
            percent_int=$(echo "$percent" | cut -d'.' -f1)
            if [ "$percent_int" -ge "$THRESHOLD" ]; then
                logger -t backup-monitor "WARNING: Snapshot $name at ${percent}%"
                # Opcional: enviar alerta email/telegram
            fi
        fi
    done
    sleep 10
done

Referencias


Fecha de resolución: 27 de octubre de 2025
Sistema: Proxmox VE 7.2.14
Causa raíz: Snapshot COW undersized para tasa de escritura de la VM
Solución: Mejora script cliente KVM para mysqldump en solución on-fly

Aviso

Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de Castris

Si necesitas soporte profesional puedes contratar con Castris soporte profesional.