Tu respaldo no es real hasta que lo hayas restaurado. Y tu replicación ZFS no es real hasta que sobrevive a lo aburrido: enlaces inestables, pools llenos, instantáneas desordenadas y esa persona que “solo renombró el dataset rápido”.
ZFS hace que la ingeniería de respaldos parezca injustamente fácil—hasta que deja de serlo. El objetivo de esta guía es mantenerlo en el carril “fácil”: hábitos claros de instantáneas, patrones sensatos de envío/recepción y un playbook de resolución cuando aparece la realidad.
El modelo mental: las instantáneas son tiempo, el envío/recepción es transporte
Los respaldos ZFS son dos mecanismos unidos:
- Instantáneas capturan el estado del dataset en un momento dado. Son baratas (inicialmente), rápidas y consistentes.
- Envío/recepción serializa las diferencias de instantáneas y las mueve a otro lugar, para que puedas perder un servidor y seguir con tu trabajo.
Todo lo demás—retención, nombres, replicación incremental, tokens de reanudación, cifrado, límites de ancho de banda—existe para hacer que esos dos mecanismos se comporten bajo estrés.
Las instantáneas no son copias. Son referencias.
Una instantánea ZFS es una vista de solo lectura de bloques. Al crear una instantánea de un dataset, ZFS no duplica los datos. Bloquea los bloques que forman esa vista puntual. A medida que el sistema de archivos en vivo cambia, se asignan bloques nuevos y los bloques antiguos se mantienen mientras alguna instantánea los referencie.
Esto significa:
- Crear instantáneas es rápido.
- Mantener muchas instantáneas puede ser caro si tu carga de trabajo churnea datos (imágenes de VM, bases de datos, artefactos de CI).
- Eliminar instantáneas puede ser lento si referencian una gran cantidad de bloques únicos.
Envío/recepción es determinista—tus políticas no lo son
zfs send produce un stream que representa el contenido de la instantánea (completo) o las diferencias (incremental). zfs receive aplica ese stream a un dataset objetivo.
La replicación funciona cuando ambos lados están de acuerdo en la línea de instantáneas. Falla cuando rompes la línea al eliminar la instantánea equivocada, renombrar datasets a la ligera, o mezclar conjuntos de instantáneas “manuales” y “automatizados” sin reglas.
Una verdad seca: la mayoría de los incidentes de respaldo con ZFS son bugs de política, no bugs de ZFS.
Broma #1 (corta, relevante): Las instantáneas ZFS son como viajar en el tiempo—fáciles de crear, caras de explicar cuando guardaste 9,000 de ellas.
El nombrado de instantáneas no es estética; es tu plano de control
Decide desde temprano un esquema de nombres que codifique:
- quién la creó (sistema vs humano),
- propósito (horaria/diaria/semanal, pre-upgrade, pre-deploy),
- tiempo (UTC, siempre).
Si no lo codificas, la retención y la replicación se convertirán en un juego de adivinanzas. Los juegos de adivinanzas son divertidos hasta que llegan los auditores.
Enfoque con opinión: separa “instantáneas de respaldo” de “instantáneas operativas”
Las instantáneas operativas (pre-upgrade, antes de una migración riesgosa) son maravillosas. Pero mezclarlas en tu cadena de replicación sin reglas eventualmente romperá el envío incremental. Usa prefijos distintos.
Ejemplos de prefijos para instantáneas:
bk-hh/bk-dd/bk-wwpara niveles de respaldo programadosops-para instantáneas de flujos de trabajo humanos/automatizados
La regla fundamental: nunca dejes el objetivo de respaldo “caliente”
Si tu pool de respaldo está al 85–95% de uso, vives de prestado. El rendimiento y comportamiento de ZFS se degradan cuando el espacio libre disminuye, y la eliminación se vuelve trabajo. Obtendrás sends lentos, receives lentos, eliminaciones de instantáneas lentas y eventualmente huecos de replicación que te obligarán a envíos completos.
Mantén los pools de respaldo por debajo de ~70–80% de uso en estado estable. Sí, finanzas preguntará por qué “desperdiciaste” discos. Explica que compras predictibilidad, no bytes brutos.
Una cita (idea parafraseada)
“La esperanza no es una estrategia.” — idea parafraseada atribuida a líderes de operaciones y ingeniería de confiabilidad
Los sistemas de instantáneas y replicación son donde la esperanza va a morir. Bien. Construye sistemas que no la necesiten.
Datos interesantes y breve historia útil en el trabajo
- ZFS surgió de Sun Microsystems como un diseño de “sistema de archivos más gestor de volúmenes”, no como una herramienta RAID acoplada. Por eso las instantáneas y la replicación se sienten nativas.
- Copy-on-write no lo inventó ZFS, pero ZFS popularizó un modelo de extremo a extremo donde el sistema de archivos, checksums y el pool cooperan en vez de pelear.
- ZFS suma checksum a cada bloque y verifica en lectura; por eso ZFS encaja tan bien en respaldos. La corrupción silenciosa es el enemigo que no te avisa.
- RAID-Z existe porque los controladores RAID tradicionales mienten (a veces accidentalmente) sobre el orden de escrituras y cachés. ZFS buscó un modelo nativo en software.
- Los streams de zfs send son portables entre muchas plataformas que implementan OpenZFS, por eso es común replicar entre Linux y sistemas derivados de illumos.
- receive resumible (“resume tokens”) se agregó porque las replicaciones grandes mueren en redes reales. Esta es una de las evoluciones más prácticas en operaciones ZFS.
- Las instantáneas no congelan el tiempo para las aplicaciones salvo que coordines escrituras. ZFS te da instantáneas crash-consistent por defecto; application-consistent requiere pasos adicionales.
- Dedup existe, pero rara vez es tu amiga en objetivos de respaldo a menos que sepas exactamente lo que haces. Consume mucha RAM y tiene puntas afiladas.
- La compresión suele ser una ventaja para respaldos: menos bytes por la red, menos bytes en disco, a menudo más rápido por menos IO. Es una de las pocas características de “come y ten tu pastel”.
Diseña un sistema de respaldos ZFS que sobreviva a los humanos
Elige una topología de replicación con intención
Caerás en una de estas:
- Uno a uno: el host de producción replica a un host de respaldo. Simple, común, bueno.
- Muchos a uno: múltiples hosts de producción replican a una caja central de respaldo. Excelente para operaciones; vigila el nombrado de datasets, cuotas y planificación de capacidad del pool.
- Fan-out: replica a un objetivo local y luego a un objetivo fuera de sitio. Así obtienes restauraciones rápidas y recuperación ante desastres.
Recomendación opinada: haz muchos-a-uno solo si tienes estándares de nombrado fuertes y cuotas. De lo contrario, un equipo llenará el pool y todos aprenderán qué significa “los respaldos están caídos”.
Decide qué replicar: datasets, no pools
Replica datasets (y sus hijos) con propiedades consistentes. Si replicás todo un pool, heredas cada error de propiedad y cada experimento. Los datasets son tu control del radio de explosión.
Usa instantáneas recursivas, pero no seas descuidado
La mayoría de los servicios viven en un árbol: pool/app, pool/app/db, pool/app/logs. Si quieres un punto en el tiempo consistente en ese árbol, haces snapshot recursivo con un nombre común. ZFS provee zfs snapshot -r y las herramientas de replicación se basan en esto.
Haz de la retención una política, no un efecto secundario
La retención es donde mueren los sistemas de respaldo. Crearás instantáneas indefinidamente, la replicación funcionará maravillosamente y luego te quedarás sin espacio y comenzarás a borrar cosas en el orden equivocado mientras la producción arde.
Elige una retención por niveles que coincida con la realidad del negocio:
- Horaria por 24–72 horas (recuperación rápida de “ups”)
- Diaria por 14–35 días (la mayoría de incidentes que “acabamos de notar”)
- Semanal por 8–12 semanas (problemas de detección lenta)
- Mensual por 6–18 meses (necesidades de cumplimiento)
Luego implementa con automatización que etiquete instantáneas y borre por etiqueta/prefijo. No borres instantáneas por “más antiguas primero” sin entender holds, clones y dependencias de replicación.
Mantén los datasets de respaldo en solo lectura (en el lado de respaldo)
En el objetivo, configura los datasets replicados como de solo lectura para evitar “soluciones rápidas” que rompan permanentemente la línea de instantáneas.
Configura:
readonly=on- opcionalmente
canmount=offpara datasets de respaldo puro
Cifrado: decide cifrar en reposo, en tránsito, o ambos
SSH proporciona cifrado en tránsito. El cifrado nativo de ZFS proporciona cifrado en reposo. Tu modelo de amenazas decide.
- Si envías a un tercero o a medios removibles: el cifrado nativo importa.
- Si está dentro de tu propio DC asegurado: SSH puede ser “suficiente”, pero los auditores pueden discrepar.
Una advertencia práctica: los datasets cifrados complican la replicación si no planificas la carga de claves y la herencia de propiedades. Prueba las restauraciones. Siempre.
Prefiere la replicación incremental, pero planifica envíos completos
Los incrementales son eficientes y rápidos. También dependen de un historial compartido de instantáneas. Si ese historial se rompe, o bien:
- recreas una instantánea base común (a veces posible), o
- haces un envío completo (a veces doloroso).
Planifica envíos completos ocasionales asegurando que toleras el ancho de banda y el impacto en almacenamiento, o manteniendo instantáneas base más largas para tener más opciones.
Tareas prácticas (comandos + salidas + decisiones)
Estas son las tareas que realmente ejecuto al construir o depurar replicación de respaldos ZFS. Cada una incluye un comando, salida típica y qué decisión tomar a partir de ello.
Task 1: Identify pools and basic health
cr0x@server:~$ zpool status
pool: tank
state: ONLINE
scan: scrub repaired 0B in 02:11:18 with 0 errors on Sun Dec 22 03:10:42 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz1-0 ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
sdc ONLINE 0 0 0
errors: No known data errors
Qué significa: El pool está online, sin errores de IO, scrub reciente limpio.
Decisión: Si ves DEGRADED, errores de checksum o scrubs fallando, arregla la salud del almacenamiento antes de afinar la replicación. La replicación no puede adelantarse a discos defectuosos.
Task 2: Check pool capacity (the silent killer)
cr0x@server:~$ zfs list -o name,used,avail,refer,mountpoint -t filesystem tank
NAME USED AVAIL REFER MOUNTPOINT
tank 6.12T 1.45T 192K /tank
Qué significa: Solo 1.45T disponible. Dependiendo del tamaño del pool, puede ser apretado.
Decisión: Si el pool supera ~80% de uso, empieza a planificar cambios de retención o expansión de capacidad. Espera que las eliminaciones de instantáneas y los receives se ralenticen.
Task 3: Inspect datasets and snapshot counts (spot runaway retention)
cr0x@server:~$ zfs list -t all -r tank/prod -o name,used,refer,creation | head
NAME USED REFER CREATION
tank/prod 820G 96K Sun Dec 1 10:02 2025
tank/prod@bk-dd-2025-12-01 2.1G 96K Sun Dec 1 23:00 2025
tank/prod@bk-dd-2025-12-02 2.4G 96K Mon Dec 2 23:00 2025
tank/prod@bk-dd-2025-12-03 1.9G 96K Tue Dec 3 23:00 2025
Qué significa: Ves instantáneas y su impacto de espacio (USED). USED es el espacio único para la instantánea frente al dataset en vivo.
Decisión: Si USED de las instantáneas es grande y crece, tu carga churnea datos. Ajusta retención o separa datasets de alto churn (como imágenes de VM) en árboles separados.
Task 4: Create consistent recursive snapshots with one name
cr0x@server:~$ zfs snapshot -r tank/prod@bk-hh-2025-12-25T0200Z
Qué significa: Cada dataset hijo bajo tank/prod obtiene una instantánea con el mismo nombre exacto, habilitando replicación consistente.
Decisión: Si no puedes snapshotar recursivamente porque tu árbol es un desastre, eso es un problema estructural. Arregla el layout de datasets; no “solo snapshota lo que importa” y esperes.
Task 5: Verify snapshot existence across the tree
cr0x@server:~$ zfs list -t snapshot -r tank/prod -o name | grep bk-hh-2025-12-25T0200Z | head
tank/prod@bk-hh-2025-12-25T0200Z
tank/prod/db@bk-hh-2025-12-25T0200Z
tank/prod/web@bk-hh-2025-12-25T0200Z
tank/prod/logs@bk-hh-2025-12-25T0200Z
Qué significa: La instantánea está presente donde esperas.
Decisión: Si algún hijo falta la instantánea, la replicación con -R no se comportará como esperas. Arregla la automatización de creación de instantáneas.
Task 6: Do a first full replication (with properties) to initialize backup
cr0x@server:~$ zfs send -R tank/prod@bk-dd-2025-12-25 | ssh backup1 'zfs receive -u backup/prod'
Qué significa: -R incluye datasets descendientes y propiedades; -u evita montar en el receive.
Decisión: Usa -u para objetivos de respaldo, y luego monta explícitamente solo al restaurar. Si el receive falla, verifica existencia de datasets, espacio en pool y permisos primero.
Task 7: Incremental replication between two snapshots
cr0x@server:~$ zfs send -R -i tank/prod@bk-dd-2025-12-24 tank/prod@bk-dd-2025-12-25 | ssh backup1 'zfs receive -u backup/prod'
Qué significa: Envía solo cambios desde la instantánea del 24 hasta la del 25.
Decisión: Si esto falla con “incremental source does not exist”, tu línea de instantáneas divergió. No lo tapes—identifica qué se borró/renombró y por qué.
Task 8: Use “replication streams” with forced rollback (carefully)
cr0x@server:~$ zfs send -R -i tank/prod@bk-dd-2025-12-24 tank/prod@bk-dd-2025-12-25 | ssh backup1 'zfs receive -u -F backup/prod'
Qué significa: -F fuerza al receptor a revertir al snapshot más reciente que coincida con el stream entrante, descartando cambios locales más nuevos.
Decisión: Usa -F solo en objetivos de respaldo si aplicas readonly=on y entiendes que descartas modificaciones locales (que no deberías tener).
Task 9: Check and set read-only on replicated datasets
cr0x@server:~$ ssh backup1 'zfs get -H -o name,property,value readonly backup/prod'
backup/prod readonly off
Qué significa: El dataset objetivo es escribible. Eso invita a problemas.
Decisión: Enciéndelo:
cr0x@server:~$ ssh backup1 'zfs set readonly=on backup/prod'
Task 10: Diagnose “why is my send slow” (CPU vs disk vs network)
cr0x@server:~$ zfs send -nPv tank/prod@bk-dd-2025-12-25
full send of tank/prod@bk-dd-2025-12-25 estimated size is 812G
size 812G
Qué significa: Dry run (-n) con progreso/verbose te da una estimación. Si vas a empujar 800G por un enlace 1Gb, será una tarde larga.
Decisión: Si el tamaño estimado es grande inesperadamente, revisa si perdiste la instantánea incremental base o si estás enviando un dataset con churn masivo.
Task 11: Monitor receive progress and detect stalls
cr0x@server:~$ ssh backup1 'zpool iostat -v tank 5 2'
capacity operations bandwidth
pool alloc free read write read write
-------------------------- ----- ----- ----- ----- ----- -----
tank 6.12T 1.45T 12 205 8.1M 112M
raidz1-0 6.12T 1.45T 12 205 8.1M 112M
sda - - 4 68 2.7M 38.0M
sdb - - 3 69 2.4M 37.1M
sdc - - 5 68 3.0M 36.9M
-------------------------- ----- ----- ----- ----- ----- -----
Qué significa: El receive escribe ~112MB/s al pool. Eso es sano para muchos arreglos de HDD.
Decisión: Si las escrituras bajan a casi cero pero el send sigue en ejecución, revisa la red, la retropresión de SSH y si el pool está casi lleno o muy fragmentado.
Task 12: Handle an interrupted receive using resume tokens
cr0x@server:~$ ssh backup1 'zfs get -H -o name,property,value receive_resume_token backup/prod'
backup/prod receive_resume_token 1-fd1b6a8c9d-118-789c...
Qué significa: El receive fue interrumpido y dejó un token de reanudación.
Decisión: Reanúdalo en lugar de empezar de nuevo:
cr0x@server:~$ zfs send -t 1-fd1b6a8c9d-118-789c... | ssh backup1 'zfs receive -u backup/prod'
Task 13: Confirm snapshot lineage on source and target (avoid broken incrementals)
cr0x@server:~$ zfs list -t snapshot -o name -s creation -r tank/prod | tail -5
tank/prod@bk-dd-2025-12-21
tank/prod@bk-dd-2025-12-22
tank/prod@bk-dd-2025-12-23
tank/prod@bk-dd-2025-12-24
tank/prod@bk-dd-2025-12-25
cr0x@server:~$ ssh backup1 'zfs list -t snapshot -o name -s creation -r backup/prod | tail -5'
backup/prod@bk-dd-2025-12-21
backup/prod@bk-dd-2025-12-22
backup/prod@bk-dd-2025-12-23
backup/prod@bk-dd-2025-12-24
backup/prod@bk-dd-2025-12-25
Qué significa: El objetivo tiene las mismas instantáneas. Los incrementales deberían funcionar.
Decisión: Si el objetivo falta una instantánea intermedia, detente y arregla esa cadena. No sigas “incrementando” y esperando; te pintarás en una esquina.
Task 14: Check dataset properties that affect backups (compression, recordsize, atime)
cr0x@server:~$ zfs get -o name,property,value -s local,default compression,recordsize,atime tank/prod
NAME PROPERTY VALUE
tank/prod compression zstd
tank/prod recordsize 128K
tank/prod atime off
Qué significa: Valores razonables por defecto para muchas cargas servidor: compresión activada, atime desactivado.
Decisión: Si la compresión está apagada, considera activarla antes de escalar la replicación. Si recordsize está desajustado para la carga (ej., 1M para bases de datos), puedes amplificar churn y deltas de respaldo.
Task 15: Validate you can restore (mount a received snapshot read-only)
cr0x@server:~$ ssh backup1 'zfs clone backup/prod@bk-dd-2025-12-25 backup/restore-test && zfs set readonly=on backup/restore-test && zfs mount backup/restore-test && ls -la /backup/restore-test | head'
total 12
drwxr-xr-x 3 root root 3 Dec 25 02:10 .
drwxr-xr-x 5 root root 5 Dec 25 02:10 ..
drwx------ 12 root root 12 Dec 25 02:00 data
Qué significa: Puedes acceder al contenido restaurado. Clonar es rápido porque es CoW.
Decisión: Si las pruebas de restauración fallan, tus respaldos son decorativos. Arregla los procedimientos de restauración y controles de acceso ahora, no durante un incidente.
Task 16: Find large snapshot space consumers (what’s keeping space pinned)
cr0x@server:~$ zfs list -t snapshot -o name,used -s used -r tank/prod | tail -5
tank/prod@bk-dd-2025-11-29 48.2G
tank/prod@bk-dd-2025-11-30 51.7G
tank/prod@bk-dd-2025-12-01 55.3G
tank/prod@bk-dd-2025-12-02 62.9G
tank/prod@bk-dd-2025-12-03 73.4G
Qué significa: Algunos días fijan mucho más dato único. Eso suele correlacionar con eventos de carga (reindex, actualización de plantilla VM, rotación de logs que salió mal).
Decisión: Si un dataset específico es siempre el culpable, aíslalo y ponle una retención distinta. Una talla no le queda bien a nadie.
Tres microhistorias corporativas desde el campo
1) Incidente causado por una suposición errónea: “Las instantáneas son prácticamente gratis, ¿no?”
En una empresa mediana, un equipo ejecutaba ZFS en un host de almacenamiento que soportaba discos de VM. Estaban orgullosos de sus instantáneas: instantáneas horarias durante dos semanas, diarias por tres meses. Nadie preguntó cuánto churneaban los datos; simplemente asumieron que CoW es magia.
La carga era principalmente VMs Windows con ciclos de parches frecuentes, más un sistema CI que reconstruía imágenes a menudo. El churn fue violento. Las instantáneas no copiaban datos, pero fijaban bloques antiguos a una tasa que hacía que el pool pareciera comerse a sí mismo.
El primer síntoma fue sutil: la replicación comenzó a tardar más. Luego la eliminación de instantáneas empezó a tardar horas. Después un receive falló porque el pool objetivo no tenía suficiente espacio contiguo para asignaciones de metadata. El pool de producción llegó a un nivel de llenado donde la latencia se volvió una característica.
Intentaron arreglar borrando instantáneas agresivamente—las más antiguas primero—durante horario laboral. Eso empeoró el IO porque la eliminación de instantáneas es trabajo real. De pronto, las VMs estaban lentas, el help desk tenía sentimientos, y el equipo de almacenamiento estaba en una llamada con cinco gerentes preguntando si “podemos reiniciar el SAN”.
La solución no fue ingeniosa. Reducieron la frecuencia de instantáneas para discos VM, separaron datasets de alto churn (artefactos CI) en su propio árbol con retención corta, y aplicaron objetivos de espacio libre en los pools. También programaron borrados de instantáneas en ventanas off-peak y monitorearon USED de snapshots. La suposición cambió: las instantáneas son baratas de crear, no de mantener.
2) Optimización que salió mal: “Activemos dedup en el objetivo de respaldo”
Otra organización tenía un gran servidor de respaldo y muchos datasets similares. Alguien se emocionó con dedup. En teoría, dedup en el objetivo podría reducir dramáticamente el consumo porque “tantos archivos son iguales entre servidores”.
Activaron dedup=on en los datasets de respaldo justo antes de incorporar una nueva flota. La replicación siguió “funcionando” y los gráficos iniciales de almacenamiento se vieron bien. Todos sonrieron. Finanzas también sonrió, y ahí sabes que es peligroso.
En semanas, el sistema de respaldo se volvió impredecible. Los receives fueron espigados. La latencia explotaba durante ingest masivo. A veces las eliminaciones de instantáneas se arrastraban. La tabla de dedup quería RAM, luego más RAM, luego empezó a usar disco de formas que empeoraron todo. Habían construido un sistema donde el camino lento se volvió el camino normal.
El contragolpe fue operacional: las restauraciones fueron más lentas y menos fiables, lo que derrotó el propósito de tener respaldos. Terminaron migrando datasets entrantes a árboles sin dedup, planificando una evacuación cuidadosa de datasets dedupeados y estableciendo SLOs estrictos de rendimiento para restauraciones. Lección aprendida: dedup no es almuerzo gratis; es una hipoteca.
3) Práctica aburrida pero correcta que salvó el día: “Ensayos mensuales de restauración”
Una empresa regulada hizo algo casi ofensivamente poco sexy: una vez al mes, realizaban un ensayo de restauración. No un ejercicio de mesas. Una restauración real a un entorno scratch. Validaban contenidos del filesystem, permisos y un puñado de comprobaciones a nivel de aplicación.
Era burocrático. Consumía tiempo. Los ingenieros pusieron los ojos en blanco. Pero el equipo lo automatizó lo suficiente para que no fuera un proyecto héroe. Clonaban una instantánea recibida, la montaban read-only, ejecutaban comprobaciones y luego destruían el clone.
Un mes, el ensayo falló. Los datos se restauraron, pero la comprobación a nivel de app reportó inconsistencia. Resultó que las instantáneas de la base de datos eran crash-consistent pero no application-consistent. No estaban coordinando con el modo backup de la BD. Nadie lo notó porque “las instantáneas ZFS son consistentes”. Consistentes, sí. Application-consistent, no.
Como fue un ensayo, se abrió un ticket, no un incidente. Actualizaron su proceso: usar mecanismos nativos de BD (o fsfreeze/modo backup) antes de tomar instantáneas. Cuando luego tuvieron una corrupción real en producción, la restauración funcionó bien. La práctica aburrida pagó por sí misma en un día, que es un gran ROI si te gusta dormir.
Broma #2 (corta, relevante): Los ensayos de respaldo son como usar hilo dental—molestos hasta que los saltas y pagas en sangre.
Playbook de diagnóstico rápido: encuentra el cuello de botella
Cuando la replicación es lenta o falla, quieres señal rápido. No una excavación arqueológica de tres horas por logs.
Primero: ¿es un problema de salud/capacidad del pool?
- Pool origen: ¿
zpool statuslimpio? ¿Errores de checksum? ¿Historial de scrub sano? - Pool destino: ¿suficiente espacio libre? ¿No está casi lleno? ¿Algún resilver en curso?
Si un pool está degradado o lleno, deja de culpar a la red. El almacenamiento siempre cobra su deuda.
Segundo: ¿el stream de envío tiene el tamaño que crees?
- Ejecuta
zfs send -nPv ...para estimar el tamaño del stream. - Si el incremental es enorme, probablemente perdiste la instantánea base incremental o tu carga churneó fuerte.
Tercero: ¿el cuello de botella es red, CPU o disco?
- Red: ¿estás saturando el enlace? ¿Hay retransmisiones? (Usa tus herramientas de red habituales; en muchos sistemas puedes inspeccionar errores de interfaz y throughput.)
- Disco:
zpool iostat -v 5muestra ancho de banda y ops en tiempo real. - CPU: la compresión/cifrado puede limitar CPU. Si el send comprime mucho o los cifrados SSH son costosos, lo verás.
Cuarto: ¿estás atascado en eliminación de instantáneas u holds?
- La eliminación de instantáneas puede bloquear la recuperación de espacio y hacer que receives fallen.
- Los holds pueden prevenir la eliminación y romper silenciosamente la retención.
Quinto: ¿dejó un receive interrumpido un resume token?
- Revisa
receive_resume_tokenen el dataset objetivo. - Reanuda con
zfs send -ten lugar de re-enviar.
El diagnóstico rápido consiste en eliminar categorías. No afines la compresión cuando el pool está al 97% de uso. No agregues discos cuando la instantánea base fue borrada.
Errores comunes: síntomas → causa raíz → solución
1) El envío incremental falla: “incremental source … does not exist”
Síntomas: Tu script funcionó ayer. Hoy falla durante zfs send -i.
Causa raíz: La instantánea “from” fue borrada en origen o destino, o la línea del dataset divergió (cambios locales en el destino, o recibir en una ruta de dataset diferente).
Solución: Compara listas de instantáneas en ambos lados; restablece una instantánea base común. Si no puedes, realiza un envío completo (planifica downtime/impacto), luego ajusta reglas de retención para preservar instantáneas base hasta que se repliquen.
2) Los receives de repente se ralentizan
Síntomas: El throughput de replicación cae; zfs receive apenas escribe; la latencia de IO sube.
Causa raíz: Pool objetivo demasiado lleno, alta fragmentación, resilver/scrub en curso, o presión de tabla de dedup. A veces también tamaños de record muy pequeños causando churn de metadatos.
Solución: Revisa uso del pool y escaneos en curso. Detén la hemorragia: libera espacio, añade capacidad o reduce la tasa de ingest. Si activaste dedup, reconsidera y planifica una migración.
3) “cannot receive: destination has snapshots” / “destination is busy”
Síntomas: El receive se queja de instantáneas existentes o instantáneas desajustadas en el objetivo.
Causa raíz: Alguien creó o eliminó instantáneas en el objetivo, o estás recibiendo en la ruta de dataset equivocada.
Solución: Aplica readonly=on y restringe quién puede administrar el pool de respaldo. Usa zfs receive -F solo si estás seguro de poder revertir el estado del objetivo de forma segura.
4) Borras instantáneas, pero el espacio no vuelve
Síntomas: Destruyes instantáneas viejas, pero zfs list muestra poco espacio liberado.
Causa raíz: Los datos están referenciados por clones, holds u otras instantáneas; también puede ser que el dataset en vivo sea el consumidor principal de espacio.
Solución: Busca clones y holds. Elimina holds si es apropiado. Identifica clones y promuévelos o destrúyelos después de validar que no se necesitan.
5) El dataset de respaldo contiene propiedades o comportamiento de montaje “inesperados”
Síntomas: Datasets recibidos se montan automáticamente, o propiedades como compression no coinciden con lo esperado.
Causa raíz: Usar zfs send/receive con flags de replicación e herencia de propiedades sin una política en el lado destino.
Solución: Recibe con -u y establece políticas destino explícitas: readonly=on, canmount=off, puntos de montaje controlados. Decide si preservar u sobrescribir propiedades.
6) La replicación cifrada falla o produce restauraciones inútiles
Síntomas: El receive finaliza, pero el dataset no monta; claves indisponibles; las restauraciones están bloqueadas.
Causa raíz: La gestión de claves no fue diseñada. La replicación movió datasets cifrados sin asegurar procedimientos de carga de claves en el entorno de restauración.
Solución: Documenta y prueba la carga de claves. Asegura que tu runbook de restauración incluya recuperación y verificación de claves. Ejecuta ensayos de restauración que incluyan cifrado.
7) “Se replicó, pero la restauración de la aplicación está rota”
Síntomas: Los archivos están; la aplicación reporta corrupción/inconsistencia.
Causa raíz: Se usaron instantáneas crash-consistent para apps que requieren instantáneas coordinadas (bases de datos, algunos sistemas de correo, etc.).
Solución: Usa hooks a nivel de aplicación: modo backup de BD, fsfreeze donde aplique, o replica respaldos lógicos dentro de datasets ZFS.
Listas de verificación / plan paso a paso
Paso a paso: configurar replicación limpia desde cero
- Crea el layout de datasets origen para que “lo que restauras” sea un árbol de datasets, no directorios aleatorios.
- Elige nombrado de instantáneas (UTC, prefijo por nivel) y escríbelo. Los humanos seguirán el camino que traces.
- Activa propiedades sensatas en origen:
compression=zstdpara la mayoría de cargas;atime=off. - Toma una instantánea recursiva inicial con un nombre base que conservarás un tiempo.
- Inicializa la replicación con un
zfs send -Rcompleto al objetivo de respaldo conzfs receive -u. - Bloquea el objetivo de respaldo: establece
readonly=on, consideracanmount=off, restringe acceso administrativo. - Automatiza la replicación incremental usando el mismo esquema de nombres y snapshots “from/to” explícitos.
- Implementa retención por niveles; borra instantáneas por prefijo y antigüedad.
- Añade monitoreo: capacidad de pool, lag de replicación (última instantánea replicada), estado de scrub y fallos de receive.
- Ejecuta ensayos de restauración mensuales (al menos): clonar, montar, validar, destruir.
Checklist: antes de activar características “inteligentes”
- Dedup: ¿tienes presupuesto de RAM y probaste ingest y restauración en peor caso?
- Cifrado nativo: ¿tienes gestión de claves y procedimientos de restauración probados?
- Ajustes de recordsize grandes: ¿entiendes cómo impactan churn y tamaño incremental?
- Cambios de compresión: ¿benchmarkeaste la capacidad de CPU y verificaste la velocidad de replicación?
- Múltiples objetivos de replicación: ¿tienes convenciones de nombres y aplicación de cuotas?
Checklist: restaurando bajo presión
- Identifica el dataset y la instantánea. No adivines; revisa la lista de instantáneas.
- Clona la instantánea a un dataset de restauración (rápido, riesgo mínimo).
- Monta primero en modo solo lectura; valida contenido y propiedad.
- Para aplicaciones: ejecuta los pasos específicos de recuperación/validación de la app.
- Solo entonces copia datos de vuelta o promueve/renombra según sea necesario.
- Documenta qué instantánea se usó y por qué. Tu yo futuro preguntará.
Preguntas frecuentes
1) ¿Las instantáneas ZFS son “respaldos”?
No. Las instantáneas en el mismo pool protegen contra borrados accidentales y despliegues malos. No protegen contra pérdida del pool, incendio, robo o errores administrativos. Replica a otro lugar.
2) ¿Debería snapshotear cada hora en todas partes?
Sólo si la carga y la retención lo justifican. Los datasets de alto churn te castigarán. Empieza con horarias para ventanas cortas y diarias para más largo, luego ajusta según crecimiento de snapshot USED.
3) ¿Cuál es la diferencia entre instantáneas crash-consistent y application-consistent?
Crash-consistent es como desconectar la energía: el sistema de archivos está consistente, pero las apps pueden necesitar recuperación. Application-consistent significa que la app cooperó (flush, freeze, modo backup), así las restauraciones son más limpias.
4) ¿Cuándo debo usar zfs receive -F?
En un objetivo de respaldo que deba ser réplica exacta, y solo cuando estés cómodo revirtiendo el objetivo para que coincida con el stream entrante. Si tu objetivo es escribible o se usa para otros fines, -F es un pie-cazador.
5) ¿Por qué a veces eliminar instantáneas tarda tanto?
Porque ZFS debe liberar bloques referenciados y actualizar metadata. Si la instantánea referencia muchos bloques únicos (alto churn) o el pool está bajo presión, la eliminación puede ser lenta. Programa borrados off-peak y evita pools calientes.
6) ¿Puedo replicar datasets cifrados de forma segura?
Sí, pero “de forma segura” incluye gestión de claves y ensayos de restauración. Si las claves no están disponibles en un incidente, tus respaldos son pisapapeles cifrados.
7) ¿La replicación reemplaza al software de backup tradicional?
A veces. La replicación es excelente para restauraciones rápidas y DR del estado del filesystem. Pero puede que aún necesites herramientas separadas para archivos a largo plazo, restauraciones cross-platform y respaldos conscientes de la aplicación. No fuerces una herramienta a ser toda tu estrategia.
8) ¿Cómo evito cadenas incrementales rotas?
Usa nombres de instantánea consistentes, no borres manualmente instantáneas base de replicación hasta confirmar que se replicaron, mantiene datasets de destino en solo lectura y monitorea la “última instantánea replicada” por dataset.
9) ¿Debería replicar todo el pool con -R?
Replica el árbol de datasets que realmente necesitas restaurar. La replicación de todo el pool tiende a convertirse en un vertedero incontrolado con propiedades y experimentos que no querías preservar.
10) ¿Cuál es la forma más segura de probar restauraciones sin afectar producción?
En el host de respaldo, clona una instantánea recibida a un dataset temporal, móntalo read-only, valida y luego destruye el clone. Los clones son baratos y reversibles.
Conclusión: próximos pasos que realmente importan
Si quieres “sin lágrimas”, deja de perseguir lo ingenioso y empieza a imponer la corrección aburrida:
- Estandariza el nombrado de instantáneas (prefijo + timestamp UTC) y separa instantáneas de respaldo de las operativas.
- Inicializa la replicación limpiamente con un
zfs send -Rcompleto, luego envíos incrementales solo cuando verifiques la línea de instantáneas. - Bloquea el objetivo de respaldo:
readonly=on, recibe con-u, restringe acceso administrativo. - Monitorea la capacidad de los pools y mantenlos por debajo de la zona de peligro; no operes el almacenamiento de respaldo caliente.
- Programa ensayos de restauración y trata fallos como bugs de producto, no fracasos personales.
ZFS te da primitivas poderosas. Tu trabajo es mantenerlas apuntando en la dirección correcta—lejos de tu pie y hacia una restauración que funcione a la primera.