ZFS zfs list -o space: La vista que explica ‘¿A dónde se fue?’

¿Te fue útil?

Todo operador de ZFS se encuentra tarde o temprano con el mismo fantasma: el pool que está “de repente” lleno. Revisas el dataset obvio, revisas el directorio evidente, incluso ejecutas un rápido du y te sientes brevemente tranquilo—hasta que ZFS insiste con calma en que el pool se está quedando sin espacio de todos modos. Eso no es ZFS siendo gracioso. Es ZFS diciéndote que estás mirando la capa equivocada.

zfs list -o space es la capa. Es la vista “libro de contabilidad de espacio” que reconcilia datasets, snapshots, reservations, refreservations y los tipos de consumo invisibles que hacen que los turnos de on-call sean picantes. En producción, es la diferencia entre adivinar y saber—y entre borrar lo incorrecto y arreglar la causa real.

Qué muestra realmente zfs list -o space

La mayoría de las discusiones “¿a dónde fue mi espacio?” con ZFS ocurren porque mezclamos dos perspectivas válidas pero distintas:

  • Perspectiva del sistema de archivos (lo que reporta du): cuenta los datos de archivos vivos accesibles desde un punto de montaje, normalmente ignorando snapshots, frecuentemente omitiendo metadatos y con frecuencia engañando por omisión cuando hay compresión, archivos dispersos o clones involucrados.
  • Perspectiva del asignador del pool (lo que ZFS debe gestionar): cuenta bloques realmente asignados, más el espacio efectivamente retenido por snapshots, más el espacio reservado por promesas que hiciste a otros datasets (reservations/refreservations), además de la sobrecarga.

zfs list -o space es un mapa curado de esa segunda perspectiva. Descompone “USED” en cubos significativos: datos, snapshots, datasets hijos, reservations, refreservation y metadatos. Si solo has visto zfs list con las columnas por defecto, te faltan los recibos.

Una nota operativa: el atajo space no es magia; es un conjunto de columnas nombrado. En muchos sistemas, se expande en algo como:

  • name, avail, used, usedbysnapshots, usedbydataset, usedbychildren, usedbyrefreservation, usedbyreservation

Dependiendo de la implementación y la versión de ZFS, también puedes ver usedbyrefquota o necesitar pedir otras propiedades explícitamente. El principio se mantiene: deja de tratar USED como un solo número.

Datos interesantes y contexto histórico

Porque ayuda saber qué tipo de bestia estás manejando:

  1. ZFS nació en Sun Microsystems a principios de los 2000 como un sistema de archivos combinado con un gestor de volúmenes, por eso puede hacer cosas como snapshots a nivel de bloque sin una capa LVM separada.
  2. El diseño original de ZFS impulsó checksum de extremo a extremo y copy-on-write como características de primera clase, por eso “eliminar un archivo” no significa necesariamente “liberar espacio ahora” si los snapshots todavía referencian los bloques.
  3. Los datasets de ZFS son baratos y están pensados para ser numerosos; el diseño asume que dividirás el almacenamiento por aplicación/tenant y gestionarás el comportamiento por dataset mediante propiedades.
  4. La contabilidad de espacio en ZFS distingue intencionalmente “referenciado” de “usado”; los clones y snapshots hacen que la “propiedad” no sea obvia, así que ZFS la rastrea.
  5. Las reservations y refreservations existen porque el almacenamiento “mejor esfuerzo” no es aceptable en muchas cargas empresariales; son promesas respaldadas por el comportamiento del asignador, no por buenas intenciones.
  6. Los zvols (dispositivos de bloque respaldados por ZFS) se introdujeron para servir imágenes de VM y consumidores estilo iSCSI/FC; complican la intuición de espacio porque las herramientas de sistema de archivos no ven dentro de ellos.
  7. La compresión se añadió temprano y se volvió ampliamente usada porque es una de las pocas optimizaciones de rendimiento que también puede reducir la amplificación de escritura y mejorar la eficiencia de la caché—cuando los datos comprimen.
  8. La deduplicación es famosa por ser a la vez brillante y financieramente ruinoso cuando se activa sin criterio; muchos operadores tienen una historia de “probamos dedup una vez” y ahora la tratan como una pistola cargada.

Las columnas de espacio, desmitificadas

Comienza con el modelo mental: “¿quién está reteniendo los bloques?”

En ZFS, los bloques se comparten. Un snapshot no es una copia; es un marcador. Cuando modificas un bloque después de que existe un snapshot, ZFS escribe el nuevo bloque en otro lugar (copy-on-write), y el snapshot sigue apuntando al antiguo. Entonces el snapshot “retiene” los bloques antiguos vivos. Por eso eliminar archivos no siempre devuelve espacio: eliminaste la referencia viva, pero el snapshot aún referencia los datos.

zfs list -o space responde: ¿cuánto del USED de este dataset se mantiene por cada razón?

Interpretación columna por columna (los sospechosos habituales)

USED

El espacio total consumido por el dataset y todo lo “debajo” de él, según el contexto. Para un dataset, USED típicamente incluye sus propios datos y metadatos, snapshots (en el sentido de espacio único atribuible), y los hijos, además de impactos por reservations/refreservations. Esto es lo que ve el asignador. Esto es lo que hace que los pools se llenen.

AVAIL

Espacio disponible para ese dataset, teniendo en cuenta el espacio libre del pool y cuotas/reservas (y a veces reglas especiales como el “slop space”). AVAIL es el número que experimenta tu aplicación al escribir.

USEDBYDATASET

Espacio usado por el sistema de archivos vivo del dataset (y metadatos) excluyendo snapshots y excluyendo hijos. Si esto es grande, tus datos vivos son grandes. Si esto es pequeño pero USED es enorme, el fantasma está en otro lado.

USEDBYSNAPSHOTS

Espacio retenido debido a snapshots. No es “el tamaño de los snapshots” en un sentido humano; es el espacio único que no puede liberarse porque los snapshots lo referencian. Alto USEDBYSNAPSHOTS a menudo significa “tuvimos churn en un dataset con snapshots habilitados.” Piensa en bases de datos, imágenes de VM, caches de artefactos CI o cualquier cosa que reescriba archivos grandes en su lugar.

USEDBYCHILDREN

Espacio usado por datasets y volúmenes descendientes. Un padre puede parecer “lleno” cuando en realidad solo actúa como contenedor. Este es el número que te salva de culpar al dataset equivocado.

USEDBYRESERVATION

Espacio consumido debido a una reservation en el dataset (o en algunas implementaciones, debido a una reserva que impacta la contabilidad). Una reservation es una garantía: este dataset podrá escribir esa cantidad incluso si el pool se aprieta.

USEDBYREFRESERVATION

Espacio consumido por refreservation. A diferencia de reservation, refreservation típicamente se aplica al dataset mismo (no a sus hijos) y es común con zvols que soportan VMs. Puede ser el “impuesto invisible” que hace que un pool parezca lleno mientras los datos reales no lo están.

Chiste #1 (porque nos lo hemos ganado): Las reservations son como invitaciones a reuniones—una vez que las aceptas, bloquean tu calendario aunque nadie se presente.

Propiedades relacionadas que a menudo completan el panorama

zfs list -o space es la lente más rápida, pero a menudo querrás propiedades adyacentes para responder el “por qué”:

  • referenced: cuánto espacio referencia el estado vivo de este dataset (sin contar snapshots). Genial para “¿qué tan grande es realmente?”
  • logicalused / logicalreferenced: cuánto datos existirían sin compresión (y a veces antes de copias/dedup). Útil para detectar ganancias/pérdidas por compresión.
  • compressratio: pista rápida sobre si la compresión está ayudando.
  • written: cuánto dato se ha escrito desde el último snapshot (o la creación del dataset). Útil para análisis de churn.
  • volsize / volblocksize: para comportamiento de zvols.
  • copies, dedup: los interruptores de “¿estamos multiplicando bloques?”.

Guion de diagnóstico rápido

Esta es la versión “son las 03:17, el pool está al 92% y el pager está cantando”. El objetivo no es ser elegante; es evitar empeorar la situación.

1) Confirma la verdad a nivel de pool

Primera pregunta: ¿es realmente un problema de espacio o es un problema de fragmentación/asignación/metadatos que se presenta como espacio?

cr0x@server:~$ zpool list
NAME   SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank  10.9T  9.80T  1.10T        -         -    43%    89%  1.00x  ONLINE  -

Interpretación: CAP cerca del 90% es territorio de riesgo para muchos pools, especialmente si FRAG es alto y la carga de trabajo tiene escrituras aleatorias intensas. Si CAP es bajo pero AVAIL en datasets es bajo, probablemente estés lidiando con cuotas/reservas.

2) Encuentra a los mayores culpables según la contabilidad del asignador

cr0x@server:~$ zfs list -o space -S used -r tank
NAME              AVAIL   USED  USEDSNAP  USEDDS  USEDCHILD  USEDREFRESERV  USEDRESERV
tank              1.10T  9.80T     3.20T    900G      5.70T            0B          0B
tank/vm           1.10T  6.10T     2.60T    400G      3.10T         80.0G          0B
tank/home         1.10T  2.90T     400G     2.30T     200G            0B          0B
tank/backup       1.10T  800G     200G      580G       20G            0B          0B

Interpretación: Ahora tienes un mapa: el pool está lleno principalmente porque tank/vm está lleno; dentro de eso, los snapshots dominan (USEDSNAP) y también hay una huella de refreservation.

3) Decide qué palanca es segura: snapshots, reservations o datos reales

En orden de menos riesgoso a más riesgoso:

  1. Podar snapshots según la política de retención conocida (especialmente los automatizados). Esto típicamente tiene el mayor retorno con el menor radio de daños.
  2. Reducir/eliminar refreservations solo si entiendes al consumidor (VM/zvol) y puedes aceptar el riesgo de overcommit.
  3. Eliminar/mover datos vivos solo si estás seguro de que los snapshots no son los verdaderos retenedores y no estás rompiendo una expectativa de la carga de trabajo.

4) Valida con una vista adicional de contabilidad antes de actuar

cr0x@server:~$ zfs get -o name,property,value -H used,referenced,logicalused,logicalreferenced,compressratio tank/vm
tank/vm	used	6.10T
tank/vm	referenced	410G
tank/vm	logicalused	7.90T
tank/vm	logicalreferenced	520G
tank/vm	compressratio	1.92x

Interpretación: Los datos vivos referenciados son solo ~410G; el resto son snapshots/hijos/reservas. Si empiezas a borrar archivos vivos de VM, no recuperarás mucho. Los snapshots son la palanca.

Tareas prácticas (comandos + interpretación)

Estos son los movimientos del día a día que convierten -o space de trivia en dinero ahorrado y fallos evitados. Todos los ejemplos asumen el pool tank; ajusta según corresponda.

Tarea 1: Mostrar la descomposición de espacio para un árbol de datasets

cr0x@server:~$ zfs list -o space -r tank
NAME        AVAIL   USED  USEDSNAP  USEDDS  USEDCHILD  USEDREFRESERV  USEDRESERV
tank        1.10T  9.80T     3.20T    900G      5.70T            0B          0B
tank/vm     1.10T  6.10T     2.60T    400G      3.10T         80.0G          0B
tank/home   1.10T  2.90T     400G     2.30T     200G            0B          0B

Interpretación: Usa esto para responder “¿son snapshots, hijos o el dataset mismo?” sin adivinar.

Tarea 2: Ordenar por espacio retenido por snapshots para encontrar puntos calientes de churn

cr0x@server:~$ zfs list -o name,usedbysnapshots,usedbydataset,usedbychildren -S usedbysnapshots -r tank
NAME        USEDSNAP  USEDDS  USEDCHILD
tank/vm       2.60T    400G     3.10T
tank/home      400G   2.30T      200G
tank/backup     200G    580G       20G

Interpretación: La poda de snapshots debe comenzar con tank/vm. Esto también es una pista para revisar la frecuencia de snapshots en datasets con churn alto.

Tarea 3: Listar snapshots y su huella “used” (incremental)

cr0x@server:~$ zfs list -t snapshot -o name,used,referenced -S used -r tank/vm | head
NAME                              USED  REFERENCED
tank/vm@auto-2025-12-24-2300       48G        410G
tank/vm@auto-2025-12-24-2200       41G        409G
tank/vm@auto-2025-12-24-2100       39G        409G
tank/vm@weekly-2025-w51            22G        405G

Interpretación: El USED del snapshot es el espacio adicional consumido comparado con el estado del snapshot anterior. Números grandes significan reescritura intensa entre snapshots.

Tarea 4: Ver rápidamente el churn de snapshots desde el último snapshot usando written

cr0x@server:~$ zfs get -o name,property,value -H written tank/vm
tank/vm	written	312G

Interpretación: Si written es enorme y los snapshots son frecuentes, el crecimiento por snapshots será grande. Bases de datos e imágenes de VM son ofensores clásicos.

Tarea 5: Identificar minas de refreservation (común con almacenamiento de VM respaldado por zvol)

cr0x@server:~$ zfs list -o name,type,usedbyrefreservation,refreservation,volsize -r tank/vm
NAME              TYPE   USEDREFRESERV  REFRESERVATION  VOLSIZE
tank/vm           filesystem       80.0G             none        -
tank/vm/zvol0     volume          200G              200G      500G
tank/vm/zvol1     volume          300G              300G      300G

Interpretación: USEDREFRESERV te dice cuánto espacio se está apartando. Si el pool está ajustado, estos bloques “retenidos” pueden ser la diferencia entre estabilidad y outage.

Tarea 6: Encontrar datasets donde las cuotas hacen que AVAIL parezca menor que el libre del pool

cr0x@server:~$ zfs get -o name,property,value -H quota,refquota,reservation,refreservation tank/home tank/vm
tank/home	quota	2.5T
tank/home	refquota	none
tank/home	reservation	none
tank/home	refreservation	none
tank/vm	quota	none
tank/vm	refquota	none
tank/vm	reservation	none
tank/vm	refreservation	none

Interpretación: Una cuota puede hacer que un dataset reporte AVAIL bajo incluso cuando el pool tiene espacio libre. Esto es un asunto de política, no del pool.

Tarea 7: Comparar la vista del sistema de archivos vivo vs la vista del asignador ZFS (y detectar la discrepancia)

cr0x@server:~$ df -h /tank/vm
Filesystem      Size  Used Avail Use% Mounted on
tank/vm          11T  410G   11T   4% /tank/vm

cr0x@server:~$ zfs list -o name,used,referenced,usedbysnapshots tank/vm
NAME     USED  REFERENCED  USEDSNAP
tank/vm  6.10T       410G    2.60T

Interpretación: df reporta lo que es accesible en el dataset vivo. ZFS reporta lo que el asignador del pool debe mantener. Cuando difieren masivamente, normalmente hay snapshots/clones/reservas involucradas.

Tarea 8: Detectar clones que retienen espacio (la sorpresa de “eliminé la imagen base”)

cr0x@server:~$ zfs list -o name,origin,used,referenced -r tank/vm
NAME                 ORIGIN                          USED  REFERENCED
tank/vm/base         -                               60G        60G
tank/vm/base@golden   -                               0B        60G
tank/vm/clone01       tank/vm/base@golden            80G        75G
tank/vm/clone02       tank/vm/base@golden            95G        88G

Interpretación: Los clones dependen de su snapshot origen. Elimina el snapshot origen a ciegas y te quedarás bloqueado—o peor, planificarás capacidad incorrectamente porque el origen aún no puede desaparecer.

Tarea 9: Comprobar la efectividad de la compresión cuando lógico y físico divergen

cr0x@server:~$ zfs get -o name,property,value -H logicalused,used,compressratio compression tank/home
tank/home	logicalused	3.40T
tank/home	used	2.90T
tank/home	compressratio	1.17x
tank/home	compression	lz4

Interpretación: La compresión está ayudando un poco, no mucho. Si logicalused es mucho mayor que used, tienes ganancias reales; si está cerca, no cuentes con la compresión para la planificación de capacidad.

Tarea 10: Encontrar datasets con metadatos inesperadamente altos (indirectamente)

cr0x@server:~$ zfs list -o name,used,referenced,recordsize,special_small_blocks -r tank | head -n 10
NAME       USED  REFERENCED  RECORDSIZE  SPECIAL_SMALL_BLOCKS
tank       9.80T      900G     128K      0
tank/home  2.90T     2.30T     128K      0
tank/vm    6.10T      410G     128K      0

Interpretación: ZFS no expone “metadatos usados” como una propiedad simple en la salida de zfs list, pero discrepancias entre referenced y used, más el tipo de carga (millones de archivos pequeños) y el ajuste de vdevs especiales pueden sugerirlo fuertemente. Si sospechas metadatos, confirma a nivel de pool con otras herramientas y considera estrategias de vdev especiales con cuidado.

Tarea 11: Usar zfs list -p para unidades no humanas y scriptables

cr0x@server:~$ zfs list -o space -p -r tank/vm | head -n 3
NAME	AVAIL	USED	USEDSNAP	USEDDS	USEDCHILD	USEDREFRESERV	USEDRESERV
tank/vm	1209462790553	6713214521344	2858730235904	429496729600	3420000000000	85899345920	0
tank/vm/zvol0	1209462790553	650000000000	0	650000000000	0	214748364800	0

Interpretación: Usa esto cuando estés construyendo alertas o informes. Las unidades legibles para humanos son para humanos; la automatización quiere enteros.

Tarea 12: Verificar qué se liberaría al eliminar un snapshot (pensamiento de dry-run)

cr0x@server:~$ zfs list -t snapshot -o name,used -S used -r tank/vm | head -n 5
NAME                              USED
tank/vm@auto-2025-12-24-2300       48G
tank/vm@auto-2025-12-24-2200       41G
tank/vm@auto-2025-12-24-2100       39G
tank/vm@weekly-2025-w51            22G

Interpretación: Si eliminas tank/vm@auto-2025-12-24-2300, el límite superior del recupero inmediato es aproximadamente 48G—a menudo menos si los bloques se comparten con clones u otros snapshots. Este orden aún te dice qué podar primero.

Tarea 13: Mostrar qué consume un padre: dataset vs hijos

cr0x@server:~$ zfs list -o name,usedbydataset,usedbychildren,usedbysnapshots -r tank | grep -E 'tank$|tank/vm$|tank/home$'
tank       900G      5.70T     3.20T
tank/vm    400G      3.10T     2.60T
tank/home  2.30T      200G      400G

Interpretación: Excelente para “¿qué subárbol es el problema?” y para evitar el error clásico de eliminar desde el padre cuando el hijo es el que consume.

Tarea 14: Confirmar que las reservations son la razón por la que AVAIL es bajo

cr0x@server:~$ zfs get -o name,property,value -H reservation,refreservation tank/vm/zvol1
tank/vm/zvol1	reservation	none
tank/vm/zvol1	refreservation	300G

cr0x@server:~$ zfs list -o name,avail,usedbyrefreservation -r tank/vm | grep zvol1
tank/vm/zvol1  1209462790553  322122547200

Interpretación: Si el pool está ajustado, refreservation es espacio “gastado” desde el punto de vista del asignador. Si lo quitas, estás cambiando el contrato con esa VM o consumidor de bloque.

Chiste #2: La contabilidad del espacio es como presupuestar—todo está bien hasta que categorizas tus gastos.

Tres mini-historias del mundo corporativo

1) Incidente causado por una suposición incorrecta: “Borramos los datos, así que el espacio debe estar libre”

El ticket llegó como una alerta de capacidad rutinaria: pool al 88%, en ascenso. El responsable del servicio juró que no había cambiado nada grande. El sysadmin hizo la primera pasada habitual: du -sh en el punto de montaje, vio un par de cientos de gigabytes, se encogió de hombros y asumió que la alerta era ruido. No lo era.

Dos horas más tarde, las escrituras empezaron a fallar de forma no obvia. Las aplicaciones no se quedaban sin disco dentro del sistema de archivos (según df), pero ZFS empezó a devolver ENOSPC durante picos. Ese es el tipo de fallo que hace que la gente desconfíe del almacenamiento—y no están equivocados.

La causa raíz: churn intenso en un dataset de imágenes de VM más snapshots agresivos. Un sistema CI estaba generando artefactos grandes, copiándolos en discos de VM, luego descartándolos y repitiendo. El dataset vivo se mantenía pequeño porque la pipeline se limpiaba a sí misma. Pero los snapshots retenían las versiones anteriores de esos bloques como un museo que se niega a desinventariar nada.

zfs list -o space lo dejó en evidencia en segundos: USEDBYSNAPSHOTS empequeñecía todo lo demás. La solución no fue “borrar más archivos”, fue “podar snapshots para reflejar la realidad” y “dejar de snapshotear datos con churn alto a una cadencia pensada para bases de datos”. Ajustaron la retención, movieron cargas efímeras a un dataset con política de snapshots diferente, y la alerta desapareció permanentemente.

La lección quedó: las herramientas de sistema de archivos te dicen lo visible; ZFS te dice lo asignado. Si solo escuchas a una, tomarás la decisión equivocada bajo presión.

2) Optimización que salió mal: “Aumentemos la frecuencia de snapshots para mejor RPO”

Un equipo quería puntos de recuperación más ajustados para una flota de servicios respaldados por VM. Aumentaron la frecuencia de snapshots de horaria a cada cinco minutos y mantuvieron la misma ventana de retención. En papel, sonaba como una ganancia gratis: los snapshots son “baratos”, ¿no?

En la práctica, la carga reescribía archivos grandes constantemente. Las imágenes de VM hacen eso: logs dentro de invitados, páginas de base de datos, actualizaciones de paquetes, archivos temporales. Copy-on-write significó que cada snapshot congelaba un conjunto de punteros a bloques, así que la siguiente reescritura tuvo que asignar nuevos bloques. Multiplica eso por doce snapshots por hora y de repente el asignador del pool hacía cardio todo el día.

Luego vino el efecto de segundo orden: la replicación. Los incrementales se hicieron más grandes y frecuentes. La red y el I/O del lado receptor subieron. Los trabajos de destrucción de snapshots se hicieron más lentos porque había más snapshots y más contabilidad de bloques que desenredar. La gente notó “ZFS está lento” y empezó a proponer cambios drásticos, incluyendo desactivar checksums en otros sistemas y comprar discos de emergencia. Espiral clásica de diagnóstico erróneo.

Retrocedieron, pero no volviendo a lo horario. Dividieron datasets: datos críticos de bajo churn recibieron snapshots frecuentes; scratch y caches de VM con churn alto recibieron menos. También repensaron la retención: muchos snapshots cada cinco minutos por unas horas, menos horarios para un día, luego diarios. El pool se estabilizó sin perder el RPO real requerido.

La lección operativa: la frecuencia de snapshots no es una virtud moral. Es una función de coste. zfs list -o space es cómo ves la factura.

3) Una práctica aburrida pero correcta que salvó el día: “Siempre reserva margen y mide por ZFS, no por sensaciones”

En un entorno—grande, multi-tenant, muchos equipos internos—los incidentes de almacenamiento eran raros. No porque el hardware fuera mágico, sino porque el equipo de almacenamiento era terco con reglas aburridas.

Primero: se negaban a operar pools “calientes”. Las alertas de capacidad disparaban en umbrales que a los equipos de aplicación les parecían conservadores. La presión era predecible: “Pagamos los discos; ¿por qué no usarlos?” El equipo de almacenamiento respondió con la realidad operativa: el comportamiento del asignador empeora, el estrés en resilver durante reconstrucciones sube, y las eliminaciones de emergencia son donde nacen los errores. Querían margen, no drama.

Segundo: construyeron dashboards desde zfs list -o space -p, no desde du o números reportados por aplicaciones. Los dashboards desglosaban USEDBYSNAPSHOTS y USEDBYREFRESERVATION explícitamente, así que el “crecimiento misterioso” se convertía en “desajuste de retención de snapshots” o “creep de refreservation” en lugar de un juego de culpas.

Tercero: hicieron la política de snapshots explícita por clase de dataset y la revisaron trimestralmente. Nada sofisticado—suficiente para atrapar accidentes como “dataset de cache CI heredó política de snapshots para bases de datos”.

Cuando un equipo de app desplegó accidentalmente una tormenta de logs que reescribió una enorme disco de VM repetidamente, el pool empezó a subir. Los dashboards mostraron que los snapshots eran los retenedores en minutos. Podaron de forma segura, ajustaron la política para ese dataset y siguieron con su trabajo. Sin llamadas generales, sin compra de almacenamiento de emergencia, sin folclore de “ZFS está embrujado”. Aburrido, correcto, efectivo.

Errores comunes, síntomas, soluciones

Error 1: Confiar en du para explicar la asignación del pool

Síntoma: du muestra uso pequeño; el pool está casi lleno; eliminar archivos no ayuda.

Por qué ocurre: Snapshots, clones, zvols, compresión y metadatos no se representan como crees en una caminata de directorio.

Solución: Usa la contabilidad de ZFS primero.

cr0x@server:~$ zfs list -o space -S used -r tank

Error 2: Eliminar el dataset equivocado porque miraste el USED del padre

Síntoma: Borras desde el punto de montaje de tank, no cambia nada, o rompes algo no relacionado.

Por qué ocurre: El USED del padre incluye a los hijos vía USEDBYCHILDREN.

Solución: Compara USEDDS vs USEDCHILD antes de actuar.

cr0x@server:~$ zfs list -o name,usedbydataset,usedbychildren,usedbysnapshots -r tank

Error 3: Asumir que el “tamaño” de un snapshot equivale al “used” del snapshot

Síntoma: Los snapshots se ven pequeños individualmente, pero USEDBYSNAPSHOTS es enorme.

Por qué ocurre: Muchos incrementales pequeños se suman; además, la retención larga + churn acumula bloques.

Solución: Ordena snapshots por USED y poda según la política de retención, no por estética del nombre.

cr0x@server:~$ zfs list -t snapshot -o name,used -S used -r tank/dataset

Error 4: Olvidar las refreservations en zvols

Síntoma: El pool parece inexplicablemente ajustado; eliminar datos no libera tanto como esperabas; los datasets de almacenamiento de VM muestran alto USEDREFRESERV.

Por qué ocurre: refreservation preasigna espacio “garantizado” y aparece como consumido en la contabilidad del asignador.

Solución: Audita las refreservations y decide si realmente necesitas garantías o puedes tolerar overcommit.

cr0x@server:~$ zfs list -o name,usedbyrefreservation,refreservation -r tank/vm

Error 5: Confundir quota con espacio libre del pool

Síntoma: La aplicación dice “sin espacio”, pero zpool list muestra bastante libre; AVAIL del dataset es pequeño.

Por qué ocurre: Las cuotas limitan el crecimiento del dataset independientemente del espacio libre del pool.

Solución: Revisa quota/refquota y ajusta intencionalmente.

cr0x@server:~$ zfs get -o name,property,value -H quota,refquota tank/app

Error 6: Tratar “eliminar snapshots” como siempre seguro

Síntoma: La destrucción de snapshot falla o queda bloqueada; el espacio no se reclamó como esperabas.

Por qué ocurre: Los clones dependen de snapshots origen; los bloques compartidos entre snapshots pueden reducir la posibilidad de reclaim.

Solución: Comprueba clones vía origin y planifica la promoción de clones o cambios en el ciclo de vida.

cr0x@server:~$ zfs list -o name,origin -r tank | grep -v '^-'

Listas de verificación / plan paso a paso

Plan paso a paso: “El pool se está llenando más rápido de lo esperado”

  1. Confirma el estado del pool y la tendencia de capacidad.
    cr0x@server:~$ zpool list
    cr0x@server:~$ zpool status

    Interpretación: Asegúrate de no confundir un problema de capacidad con un problema de vdev degradado/rendimiento de resilver.

  2. Encuentra los datasets principales por USED y luego por espacio retenido por snapshots.
    cr0x@server:~$ zfs list -o space -S used -r tank | head -n 30
    cr0x@server:~$ zfs list -o name,usedbysnapshots,usedbydataset,usedbychildren -S usedbysnapshots -r tank | head -n 30

    Interpretación: Identifica si el crecimiento es datos vivos, snapshots, hijos o reservations.

  3. Si los snapshots dominan, localiza la política de snapshots y el churn.
    cr0x@server:~$ zfs list -t snapshot -o name,used -S used -r tank/offender | head
    cr0x@server:~$ zfs get -o name,property,value -H written tank/offender

    Interpretación: Gran written + muchos snapshots = presión de espacio previsible.

  4. Si refreservation domina, inventaría zvols y contratos.
    cr0x@server:~$ zfs list -o name,type,usedbyrefreservation,refreservation,volsize -r tank/offender

    Interpretación: Decide si las garantías son necesarias o si puedes reducir el espacio retenido de forma segura.

  5. Si los hijos dominan, profundiza recursivamente y evita borrar al nivel equivocado.
    cr0x@server:~$ zfs list -o space -S used -r tank/offender

    Interpretación: Encuentra el subárbol real; no “limpies” rutas al azar.

  6. Después de cualquier cambio, vuelve a comprobar la descomposición del espacio y el CAP del pool.
    cr0x@server:~$ zfs list -o space tank/offender
    cr0x@server:~$ zpool list

    Interpretación: Asegúrate de que la palanca que moviste realmente cambió los números que esperabas.

Lista de verificación: antes de eliminar snapshots en producción

  1. Confirma el dataset y la política de nombrado/retención del snapshot (evita eliminar el último punto de restauración válido).
  2. Comprueba clones que dependan de esos snapshots (relaciones origin).
  3. Prefiere eliminar snapshots más antiguos primero para mejorar la predictibilidad del reclaim (a menos que la política diga otra cosa).
  4. Mide el recupero esperado usando el orden por USED de snapshots (sabiendo que es un límite superior).

Lista de verificación: antes de cambiar reservation/refreservation

  1. Identifica al consumidor (host VM, objetivo iSCSI, requisito de la app).
  2. Confirma si la garantía es requerida para la corrección o solo por comodidad.
  3. Ajusta en pasos pequeños durante periodos estables; vigila CAP del pool y el comportamiento de la carga.

Preguntas frecuentes

1) ¿Por qué df muestra mucho espacio pero ZFS dice que el pool está casi lleno?

df reporta el espacio visible por el sistema de archivos dentro de un dataset, generalmente ignorando bloques retenidos por snapshots y a veces otras realidades del asignador. La plenitud del pool de ZFS trata sobre bloques asignados. Si los snapshots son grandes o hay reservations en juego, estos números divergen drásticamente.

2) ¿Cuál es la diferencia entre USED y REFERENCED?

REFERENCED es cuánto espacio apunta el estado vivo del dataset. USED es lo que ve el asignador y puede incluir espacio retenido por snapshots, hijos e impactos de reservas según el contexto. Cuando los snapshots son pesados, USED puede eclipsar REFERENCED.

3) ¿USEDBYSNAPSHOTS equivale a la suma de los valores USED de snapshots?

No siempre, porque el compartimiento y los límites de contabilidad pueden complicar sumas ingenuas—especialmente con clones y bloques compartidos. Trata el USED de snapshot como “crecimiento incremental por snapshot”, y trata USEDBYSNAPSHOTS como “espacio retenido por snapshots” a nivel de dataset.

4) Eliminé un montón de snapshots, pero el espacio no volvió de inmediato. ¿Por qué?

Razones comunes: los bloques todavía son referenciados por otros snapshots, clones o estados de dataset; la liberación asíncrona puede tardar; o la presión es en realidad por reservations/refreservations. Revisa de nuevo zfs list -o space y busca clones vía origin.

5) ¿Son las reservations y refreservations “uso real”?

Son reales desde el punto de vista del asignador porque reducen lo que otros datasets pueden usar de forma segura. Pueden no corresponder a datos vivos, pero afectan absolutamente si las escrituras tendrán éxito bajo presión.

6) ¿Por qué los datasets de VM suelen tener mucho uso por snapshots?

Los discos de VM churn: pequeñas escrituras a través de grandes discos virtuales reescriben bloques constantemente. Con snapshots, los bloques antiguos permanecen referenciados, por lo que el churn se traduce en crecimiento de espacio. La frecuencia y la retención de snapshots importan más para datasets de VM que para cargas mayormente append.

7) ¿Cómo encuentro rápido al único mayor “tragón de espacio”?

Empieza con:

cr0x@server:~$ zfs list -o space -S used -r tank | head -n 30

Luego decide si el tragón es snapshots, hijos, dataset o reservations leyendo las columnas de descomposición.

8) ¿Cuándo debería usar la salida con -p?

Siempre que planees parsear resultados en scripts, dashboards o alertas. Las unidades legibles para humanos son ambiguas y sensibles a la configuración regional; los enteros son estables.

9) ¿Puedo “arreglar” problemas de espacio desactivando snapshots?

Deshabilitar snapshots futuros no liberará los bloques retenidos por snapshots existentes. Debes eliminar snapshots (con seguridad) para reclamar espacio. Además, desactivar snapshots puede ser una decisión de gobernanza—asegúrate de no cambiar capacidad por un riesgo de recuperación inaceptable.

10) ¿Qué pasa si USEDBYDATASET es enorme pero la aplicación insiste en que limpió?

Entonces puedes estar lidiando con datos no visibles en el punto de montaje (zvols), overlays de montaje ocultos, o limpieza que ocurrió dentro de un invitado (VM) mientras el host ve un gran archivo de disco virtual que no se redujo. Valida qué contiene realmente el dataset y si es un volumen o un sistema de archivos.

Conclusión

zfs list -o space es la vista de “verdad de capacidad” más útil en las operaciones diarias de ZFS porque responde la única pregunta que importa durante un incidente: ¿qué está reteniendo los bloques? Una vez que puedes separar el espacio retenido por snapshots de los datos vivos y de las promesas de reserva, el misterio desaparece—y tus opciones de remediación se vuelven claras, seguras y rápidas.

Si operas ZFS en producción, haz de esta vista un hábito: estandarízala, alerta sobre ella y enséñala. El pool no está embrujado. Está contabilizado.

← Anterior
Permisos de bind mount de Docker en Windows: la configuración menos dolorosa
Siguiente →
Elección del planificador IO de ZFS: mq-deadline vs none para HDD, SSD y NVMe

Deja un comentario