TL;DR — Resumen Rápido

Snapshots ZFS protegen datos Linux con copy-on-write sin costo. Aprende a crear, revertir, clonar y replicar datasets con zfs send/receive y sanoid.

Los snapshots ZFS son una de las herramientas de protección de datos más potentes disponibles en Linux. A diferencia de los enfoques tradicionales de backup que copian datasets completos, los snapshots ZFS aprovechan la semántica de copy-on-write (COW) para capturar el estado exacto de un sistema de archivos en un momento dado — de forma instantánea y sin costo inicial de espacio. Esta guía cubre desde los fundamentos de ZFS hasta pipelines de snapshots automatizados con sanoid y syncoid.

Requisitos Previos

  • Ubuntu 22.04/24.04 LTS (o cualquier distro con OpenZFS 2.1+)
  • Uno o más dispositivos de bloque para pruebas (discos reales o archivos loopback)
  • Acceso con sudo
  • Familiaridad básica con nombres de dispositivos Linux (/dev/sd*, /dev/vd*)

Conceptos Fundamentales de ZFS

Copy-on-Write (COW): ZFS nunca sobreescribe datos activos en el mismo lugar. Cuando se modifica un bloque, ZFS escribe la nueva versión en una ubicación libre y actualiza atómicamente el puntero. El bloque antiguo permanece intacto — esto es lo que aprovechan los snapshots.

Pools y Datasets: Un pool (zpool) es el contenedor de almacenamiento de nivel superior formado por uno o más vdevs (dispositivos virtuales: espejos, franjas RAIDZ). Un dataset (zfs create) es un sistema de archivos montable dentro de un pool.

Checksums: Cada bloque lleva un checksum de 256 bits. En la lectura, ZFS verifica el checksum y puede auto-repararse desde una copia redundante si el bloque primario está corrupto, eliminando la corrupción silenciosa de datos.


Instalación de ZFS en Ubuntu

sudo apt update
sudo apt install zfsutils-linux -y
zfs --version

Creación de Pools

# Espejo (equivalente a RAID-1)
sudo zpool create tank mirror /dev/sdb /dev/sdc

# RAIDZ1 — 1 disco de paridad, tolera 1 fallo
sudo zpool create tank raidz /dev/sdb /dev/sdc /dev/sdd

# RAIDZ2 — 2 discos de paridad, tolera 2 fallos (recomendado para >=6 discos)
sudo zpool create tank raidz2 /dev/sd{b,c,d,e,f,g}
zpool status tank
zpool list

Gestión de Datasets

# Dataset con compresión LZ4
zfs create -o compression=lz4 tank/data

# Punto de montaje explícito
zfs set mountpoint=/srv/data tank/data

# Compresión zstd para mejor ratio
zfs set compression=zstd tank/data

# Ajuste de recordsize para bases de datos
zfs set recordsize=16K tank/postgres    # PostgreSQL
zfs set recordsize=128K tank/mysql      # MySQL InnoDB

# Cuotas y reservaciones
zfs set quota=500G tank/data
zfs set reservation=100G tank/data

Propiedades clave de monitoreo:

PropiedadSignificado
usedEspacio consumido por el dataset + sus snapshots
availableEspacio libre que el dataset puede usar
referencedEspacio del dataset activo (excluye snapshots)
compressratioRatio de compresión logrado (ej. 2.14x)

Fundamentos de Snapshots

Crear Snapshots

# Snapshot único
zfs snapshot tank/data@2026-03-22

# Snapshot recursivo
zfs snapshot -r tank@2026-03-22

# Con timestamp del shell
zfs snapshot tank/data@$(date +%Y-%m-%dT%H%M)

Listar Snapshots

zfs list -t snapshot
zfs list -t snapshot -o name,used,referenced,creation

Revertir (Rollback)

zfs rollback tank/data@2026-03-22

# Si existen snapshots más recientes
zfs rollback -r tank/data@2026-03-21

Acceder al Contenido de un Snapshot sin Revertir

ls /srv/data/.zfs/snapshot/
# Restaurar un archivo individual
cp /srv/data/.zfs/snapshot/2026-03-22/importante.sql /srv/data/restaurado.sql

Eliminar Snapshots

zfs destroy tank/data@2026-03-20
# Rango de snapshots
zfs destroy tank/data@2026-03-01%2026-03-15

Clones: Snapshots Escribibles

Un clon es un dataset escribible derivado de un snapshot, ideal para entornos de staging.

# Crear un clon
zfs clone tank/data@2026-03-22 tank/data-staging

# Punto de montaje
zfs set mountpoint=/srv/staging tank/data-staging

# Promover el clon a independiente
zfs promote tank/data-staging

Send/Receive: Replicación ZFS

Envío Completo Inicial

# Copia local
zfs send tank/data@2026-03-22 | zfs receive backup/data

# Por SSH con compresión
zfs send -c tank/data@2026-03-22 | ssh backup-host zfs receive backup/data

Envíos Incrementales

# -i = incremento único
zfs send -ci tank/data@2026-03-21 tank/data@2026-03-22 | \
  ssh backup-host zfs receive -F backup/data

# -I = incluye snapshots intermedios
zfs send -cI tank/data@2026-03-20 tank/data@2026-03-22 | \
  ssh backup-host zfs receive -F backup/data

Reanudar Transferencias Interrumpidas

# Obtener token de reanudación
zfs get receive_resume_token backup/data

# Reanudar el envío
zfs send -t <token> | ssh backup-host zfs receive -s backup/data

Referencia de Flags de Replicación

FlagEfecto
-cComprime el stream
-iIncremental entre dos snapshots
-IIncremental incluyendo snapshots intermedios
-RReplica dataset recursivamente
-sGuarda estado de reanudación en el receptor
-vSalida detallada

Snapshots Automatizados con Sanoid

Instalar Sanoid

sudo apt install sanoid -y

Configurar Políticas

# /etc/sanoid/sanoid.conf
[tank/data]
  use_template = production
  recursive = yes

[template_production]
  hourly = 24
  daily = 30
  monthly = 3
  autosnap = yes
  autoprune = yes

Habilitar el Timer de Systemd

sudo systemctl enable --now sanoid.timer

# Prueba manual
sudo sanoid --take-snapshots --verbose
sudo sanoid --prune-snapshots --verbose

Syncoid para Replicación

syncoid tank/data backup-host:backup/data
syncoid --recursive tank backup-host:backup

Scrubbing y Auto-reparación

# Iniciar scrub
sudo zpool scrub tank

# Verificar estado
zpool status tank | grep -A5 scrub

# Programar scrubs mensuales
echo "0 2 1 * * root /sbin/zpool scrub tank" | sudo tee /etc/cron.d/zfs-scrub

ZFS vs. Alternativas

CaracterísticaZFSBtrfsLVM + ext4XFS
Copy-on-writeNoNo
RAID integradoSí (RAIDZ)Sí (limitado)Vía LVMNo
Snapshots nativosVía LVMNo
Replicación send/receiveSí (nativo)NoNo
Checksums / auto-reparaciónSí (limitado)NoNo
CompresiónSí (lz4, zstd)NoNo
Caché ARC/L2ARCNoNoNo
Madurez en producción (Linux)Alta (OpenZFS)MediaMuy altaMuy alta

Patrones de Producción

Boot Environments

# Crear entorno de arranque antes de actualizar
sudo zfs snapshot -r rpool/ROOT/ubuntu@before-upgrade

Docker sobre ZFS

echo '{"storage-driver": "zfs"}' | sudo tee /etc/docker/daemon.json
sudo systemctl restart docker
zfs set recordsize=128K tank/docker

Recordsize para Bases de Datos

Base de Datosrecordsize recomendadoRazón
PostgreSQL8K o 16KCoincide con página de 8K
MySQL InnoDB16KCoincide con página InnoDB
MySQL MyISAM128KFavorece escaneos secuenciales
MongoDB16KPágina WiredTiger por defecto
SQLite4KCoincide con página por defecto

Casos Especiales y Advertencias

  • Nunca importes el mismo pool en dos hosts simultáneamente: causa split-brain y corrupción.
  • snapshot hold vs. destroy: Usa zfs hold para anclar un snapshot durante un send activo.
  • Deduplicación raramente vale la pena: Requiere ~5 GB de RAM por TB de datos únicos.
  • Swap en ZFS: Evita usar un zvol ZFS como swap — pueden ocurrir deadlocks bajo presión extrema de memoria.

Resumen

  • Los snapshots ZFS son copias instantáneas y eficientes en espacio basadas en copy-on-write.
  • Usa zfs snapshot para snaps manuales y sanoid para gestión automatizada por políticas.
  • zfs send | zfs receive replica datasets eficientemente — solo los bloques cambiados viajan por la red.
  • El scrubbing mensual detecta corrupción silenciosa antes de que se propague.
  • Los snapshots en el mismo pool no sustituyen los backups fuera del pool — siempre replica a un host separado.

Artículos Relacionados