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:

Propiedad Significado
used Espacio consumido por el dataset + sus snapshots
available Espacio libre que el dataset puede usar
referenced Espacio del dataset activo (excluye snapshots)
compressratio Ratio 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

Flag Efecto
-c Comprime el stream
-i Incremental entre dos snapshots
-I Incremental incluyendo snapshots intermedios
-R Replica dataset recursivamente
-s Guarda estado de reanudación en el receptor
-v Salida 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ística ZFS Btrfs LVM + ext4 XFS
Copy-on-write No No
RAID integrado Sí (RAIDZ) Sí (limitado) Vía LVM No
Snapshots nativos Vía LVM No
Replicación send/receive Sí (nativo) No No
Checksums / auto-reparación Sí (limitado) No No
Compresión Sí (lz4, zstd) No No
Caché ARC/L2ARC No No No
Madurez en producción (Linux) Alta (OpenZFS) Media Muy alta Muy 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 Datos recordsize recomendado Razón
PostgreSQL 8K o 16K Coincide con página de 8K
MySQL InnoDB 16K Coincide con página InnoDB
MySQL MyISAM 128K Favorece escaneos secuenciales
MongoDB 16K Página WiredTiger por defecto
SQLite 4K Coincide 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