En algún momento, todo equipo de almacenamiento se enfrenta al mismo villano: el vdev “temporal”. Llegó durante una crisis, solucionó un problema de capacidad y ahora vive en tu pool como un compañero de piso malo que no paga la renta. Quieres quitarlo. ZFS, famoso por su conservadurismo, dice: quizá.
La eliminación de vdev es real, útil y aún está llena de riesgos. En producción, la diferencia entre “funciona bien” y “me arruinó el fin de semana” es planificar según las reglas de ZFS, no según tus esperanzas.
El modelo mental: qué significa realmente “eliminar”
Los pools ZFS se construyen a partir de vdevs (dispositivos virtuales). Un vdev es la unidad atómica de redundancia y asignación. ZFS distribuye los datos en stripe entre vdevs, no entre discos individuales. Esa frase debería cambiar la forma en que piensas sobre la eliminación.
Cuando ejecutas zpool remove, no estás “desenchufando un disco”. Estás iniciando una evacuación: ZFS reescribe cada bloque asignado que reside en el vdev objetivo hacia otros vdevs del pool. Solo después de que eso tenga éxito, el vdev puede separarse de la configuración del pool. Durante la evacuación, el vdev debe ser legible; el resto del pool debe contar con suficiente espacio libre para absorber los datos.
Eso también significa que la eliminación no es instantánea. Es un trabajo de movimiento de datos a nivel de pool con efectos reales: más I/O, más presión de fragmentación, picos de latencia y muchas preguntas del tipo “¿por qué mi pool está ocupado a las 2 a. m.?”.
Una matización crucial más: la eliminación de vdev no es una característica general para “encoger el pool”. Es una capacidad muy específica con restricciones, y ZFS se negará a hacerlo en muchas topologías. Si solo te llevas una cosa: diseña tu pool como si pudieras querer cambiarlo más adelante, porque ZFS no te salvará mágicamente de un arrepentimiento arquitectónico.
Términos que necesitas, en lenguaje operativo
- Top-level vdev: Un vdev directamente bajo el pool (por ejemplo, un vdev mirror, un vdev raidz o un vdev de un solo disco). La mayoría de las discusiones sobre eliminación tratan top-level vdevs.
- Leaf device: Un disco o partición dentro de un vdev. En un mirror, puedes eliminar/reemplazar hojas; eso no es “eliminación de vdev”, es “reemplazo/desconexión de dispositivo”.
- Special vdev: Un dispositivo de la clase de asignación para metadata (y opcionalmente bloques pequeños). Potente. También fácil de convertir en un punto único de falla si te pones demasiado ingenioso.
- SLOG (log vdev): Registro de intención separado para escrituras síncronas. Se puede quitar, pero las consecuencias dependen de la carga de trabajo y de la configuración de sync.
- L2ARC (cache vdev): Caché de lectura. Siempre removible; es una pista de rendimiento, no almacenamiento primario.
- Evacuación: El movimiento de datos que realiza ZFS para sacar datos del vdev eliminado. Ese es el trabajo.
Qué puedes eliminar (y qué no)
Generalmente puedes eliminar: dispositivos de caché (L2ARC)
Los dispositivos L2ARC pueden añadirse y quitarse sin afectar la corrección de los datos. El peor escenario es una regresión de rendimiento mientras la caché se vuelve a calentar. Si tu pool está sano, quitar un L2ARC es básicamente aburrido.
Generalmente puedes eliminar: dispositivos de log (SLOG)
Quitar un dispositivo de log está permitido. ZFS volverá a usar el pool principal para el ZIL. El pool sigue siendo consistente. El riesgo es la latencia y el rendimiento de las escrituras síncronas, no la pérdida de datos. Si quitas SLOG bajo alta carga síncrona, tus aplicaciones te lo notarán de inmediato, generalmente mediante timeouts.
Puedes eliminar: top-level vdevs en algunas configuraciones (el gran caso)
La eliminación de top-level vdevs es lo que a la gente le importa cuando dice “encoger un pool”. Existe, pero está condicionada por la implementación y el soporte de versión. En la práctica:
- Eliminar un top-level mirror completo es comúnmente soportado (cuando la característica existe en tu plataforma y pool).
- Eliminar un top-level vdev de disco único suele estar soportado (de nuevo: depende de la característica/plataforma).
- Eliminar un top-level vdev raidz típicamente no está soportado en muchas implementaciones; incluso si algunas plataformas evolucionan, trátalo como “supón que no” a menos que hayas verificado explícitamente en tu implementación exacta de ZFS y las banderas de característica.
Puedes eliminar: dispositivos de un vdev mirror (pero eso no es “eliminación de vdev”)
Si tienes un vdev mirror con dos discos, puedes desacoplar uno y seguir operando con el disco restante (ahora un vdev de disco único). Esa es una operación sobre la hoja. Reduce redundancia. No evacua bloques hacia otros vdevs. A menudo es lo que la gente necesita cuando dice “quitar un disco”.
Special vdevs: removibles en teoría, peligrosos en la práctica
Los special vdevs (clase de asignación) son donde la producción se encuentra con la soberbia. Si un special vdev contiene metadata (y la mayoría lo hace), perderlo puede dejar el pool inservible. Quitar un special vdev puede estar soportado en tu stack, pero deberías tratarlo como un proyecto de migración, no como un comando casual. Si tu special vdev está en mirror y sano, puedes planear su eliminación; si está degradado, estás en territorio de emergencia.
Chiste #1: Un special vdev es como un clúster de Kubernetes “temporal”: todos juran que es solo para pruebas hasta que se vuelve crítico un viernes por la noche.
Límites estrictos que debes respetar
1) No puedes eliminar lo que ZFS no puede evacuar
La evacuación requiere espacio libre en los vdevs restantes. No “un poco” de espacio libre. Suficiente para reescribir los bloques asignados más overhead, y además mantener el funcionamiento del asignador del pool. Si tu pool está al 85–90% lleno, la eliminación es una mala idea. Al 95% es autolesión.
2) La eliminación está condicionada por características e implementación
No existe un único ZFS. Está OpenZFS, y luego integraciones de sistemas operativos y distribuciones de vendors con distintas versiones, banderas de características y backports de correcciones. El propio pool también tiene flags de característica: si el pool no tiene la característica correcta activada, no vas a eliminar nada.
3) No puedes “eliminar parcialmente” un raidz top-level para reducir su anchura
La gente pregunta: “¿Puedo quitar un disco de mi vdev raidz y mantener raidz?” No. Puedes reemplazar discos por otros más grandes y expandir (con el soporte de la característica correcta), pero reducir el ancho de un raidz quitando una hoja no es el diseño de ZFS. Si quieres encoger con flexibilidad, construye con mirrors, acepta la sobrecarga de capacidad y duerme tranquilo por la noche.
4) No puedes quitar el último top-level vdev
Un pool necesita al menos un top-level vdev. Si quieres “eliminar todo”, no estás encogiendo: estás migrando.
5) La eliminación estresa el pool y compite con cargas de producción
La evacuación es un trabajo de reescritura. Afectará discos, ARC, metadata y posiblemente tu fragmentación. Si lo haces durante la carga pico, espera que la latencia suba y que las aplicaciones sufran retardos “misteriosos”. Si debes hacerlo online, regolalo y monitoriza sin descanso.
6) La eliminación no es lo mismo que un resilver, y los controles son distintos
El resilver reconstruye hacia un dispositivo de reemplazo. La evacuación es redistribución a través del pool. Verás síntomas distintos: no solo “velocidad de scan”, sino comportamiento del asignador, contención de metaslabs y colas de I/O generales.
7) Puedes eliminar el vdev y aun así no recuperar el espacio que esperabas
La contabilidad de ZFS puede sorprenderte. Snapshots, reservations, refreservations, ajustes de bloques pequeños en special y copias afectan “¿por qué sigue lleno?” Tras la eliminación, el tamaño total del pool disminuye—a veces drásticamente—por lo que cualquier margen que creías tener puede evaporarse. Planifica la capacidad post-eliminación, no solo “¿puedo eliminarlo?”.
Una cita operativa para llevar en el bolsillo
John Allspaw (idea parafraseada): “La confiabilidad viene de cómo se comportan los sistemas bajo estrés, no de cómo se comportan cuando todo va bien”.
Datos interesantes y breve historia (porque esta función no cayó del cielo)
- ZFS se construyó alrededor de “los vdevs son para siempre”. Los diseños iniciales de ZFS asumían que solo crecerías pools, no que los encogerías.
- La eliminación de top-level vdev llegó tarde en comparación con los básicos de mirrors/raidz; es un reconocimiento de que los operadores reales hacen cosas desordenadas durante incidentes.
- Las “clases de asignación” (special vdevs) cambiaron el riesgo operativo: mover metadata a dispositivos rápidos puede ser brillante, pero convierte a esos dispositivos en existenciales.
- El ZIL siempre existe incluso sin un dispositivo SLOG; SLOG solo reubica el log a almacenamiento más rápido y de menor latencia.
- El contenido de L2ARC es descartable por diseño; fue creado como una caché que puedes perder sin lágrimas.
- Los flags de característica del pool son una puerta de un solo sentido: habilitar características nuevas puede impedir importar en sistemas antiguos. La capacidad de eliminación a menudo depende de esos flags.
- Los scrubs de ZFS preceden a la era “cloud native” de la mayoría como una rutina para detectar corrupción silenciosa con checksums end-to-end.
- Las metaslabs y los mapas de espacio importan más durante la evacuación: el asignador se vuelve el cuello de botella mucho antes de que pegues al CPU.
- La fragmentación no es solo un problema de rendimiento: puede convertir la evacuación en un trabajo largo y entrecortado con picos de latencia desagradables.
Guía rápida de diagnóstico (encuentra el cuello de botella antes de adivinar)
Este es el flujo de “tengo 15 minutos antes de la próxima reunión y el pool se está derritiendo”. No seas creativo. Sé sistemático.
Primero: ¿Es el pool elegible para eliminación de vdev?
- Comprueba los flags de característica y la versión/implementación de ZFS.
- Confirma que el objetivo sea una clase removible (no un raidz top-level en un stack que no lo soporta).
Segundo: ¿Tienes suficiente espacio para evacuar?
- Mira el espacio libre del pool y la fragmentación.
- Mira snapshots y reservas que impedirán liberar espacio.
- Decide si necesitas borrar/mover datos o añadir capacidad temporal primero.
Tercero: ¿Está el pool lo bastante sano como para sobrevivir la operación?
- ¿Hay vdevs degradados? Arréglalos primero.
- ¿Hay resilver/scrub en curso? Decide si esperar.
- Comprueba SMART de los dispositivos que podrían morir durante la evacuación.
Cuarto: Si la eliminación es lenta, ¿en qué está esperando?
- ¿Saturación de IOPS en disco? Observa
iostaty la latencia por vdev. - ¿Disco único lento? Busca un dispositivo con tiempos await enormes.
- ¿Contención del asignador / fragmentación? Espera progreso desigual y mucho I/O de metadata.
- ¿Recordsize/bloques pequeños? Las cargas con bloques pequeños pueden hacer que la evacuación parezca que el pegamento se está secando.
Tareas prácticas: comandos, salidas y la decisión que tomas
A continuación hay movimientos operativos reales. Cada uno es “haz algo, interpreta la salida, decide el siguiente paso”. Así es como evitas que el almacenamiento se convierta en arte performativo.
Task 1: Identifica con qué tratas (topología del pool)
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
scan: scrub repaired 0B in 02:11:43 with 0 errors on Wed Dec 18 03:11:12 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-WDC_WD80EFAX-1 ONLINE 0 0 0
ata-WDC_WD80EFAX-2 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
ata-WDC_WD80EFAX-3 ONLINE 0 0 0
ata-WDC_WD80EFAX-4 ONLINE 0 0 0
logs
nvme-SAMSUNG_MZVLB256 ONLINE 0 0 0
cache
nvme-INTEL_SSDPEKNW512 ONLINE 0 0 0
errors: No known data errors
Qué significa: Dos top-level vdevs mirror, además de un dispositivo de log y uno de caché. Los mirrors son la topología top-level más amigable para eliminación.
Decisión: Si el objetivo es reducir capacidad, el candidato es mirror-1 (top-level). Si el objetivo es simplificar, puedes quitar SLOG o L2ARC con riesgo mínimo.
Task 2: Verifica flags de característica del pool (puerta de elegibilidad)
cr0x@server:~$ zpool get -H feature@device_removal tank
tank feature@device_removal active -
Qué significa: El pool tiene la bandera device_removal activa.
Decisión: Procede con la planificación. Si está disabled o -, probablemente no podrás eliminar top-level vdevs en este pool sin actualizar/importar con features (lo cual es otra ventana de cambios).
Task 3: Comprueba qué tan lleno está el pool (¿puedes evacuar?)
cr0x@server:~$ zfs list -o name,used,avail,refer,mountpoint -r tank
NAME USED AVAIL REFER MOUNTPOINT
tank 41.2T 6.3T 96K /tank
tank/home 11.1T 6.3T 10.9T /tank/home
tank/vm 28.7T 6.3T 28.7T /tank/vm
tank/backups 1.4T 6.3T 1.4T /tank/backups
Qué significa: Solo 6.3T disponibles. Si el vdev que quieres eliminar tiene más de eso asignado, la evacuación no podrá completarse.
Decisión: Antes de eliminar un top-level vdev, estima cuántos datos hay en él. Si no estás seguro, asume “aproximadamente proporcional” y exige margen cómodo de espacio libre. Si no puedes crear ese margen, no inicies la eliminación.
Task 4: Comprueba la capacidad y la fragmentación del pool (predictor de dolor de evacuación)
cr0x@server:~$ zpool list -o name,size,alloc,free,frag,health tank
NAME SIZE ALLOC FREE FRAG HEALTH
tank 47.5T 41.2T 6.3T 58% ONLINE
Qué significa: 58% de fragmentación no es “aceptable”. Es “esto llevará más tiempo del que quieres e interferirá con el rendimiento”.
Decisión: Si debes eliminar ahora, planifica limitación y una ventana más amplia. Si puedes esperar, considera mover datos fríos fuera y de vuelta (u otras estrategias de desfragmentación) antes de intentar la eliminación.
Task 5: Identifica si los snapshots están atrapando espacio
cr0x@server:~$ zfs list -t snapshot -o name,used,refer -S used | head
NAME USED REFER
tank/vm@hourly-2025-12-25-0900 1.2T 28.7T
tank/vm@hourly-2025-12-25-0800 1.1T 28.7T
tank/home@daily-2025-12-24 640G 10.9T
tank/vm@hourly-2025-12-25-0700 610G 28.7T
Qué significa: Los snapshots consumen espacio significativo. Eliminar datasets puede no liberar espacio si los snapshots referencian bloques antiguos.
Decisión: Si necesitas margen para evacuar, reduce la retención de snapshots o replica snapshots fuera del pool y luego destrúyelos localmente—con cuidado y con alineación con los interesados.
Task 6: Comprueba las reservas de dataset que bloquean la evacuación
cr0x@server:~$ zfs get -H -o name,property,value -r reservation,refreservation tank | egrep -v '\t(none|0)\t' | head
tank/vm reservation 5T
tank/home refreservation 1T
Qué significa: Las reservas reservan espacio que otras operaciones no pueden usar, incluyendo el margen necesario para evacuación.
Decisión: Reduce o elimina temporalmente reservas (con aprobación de los responsables de las aplicaciones) para crear espacio libre real. Vuélvelas a poner después.
Task 7: Confirma la salud antes de comenzar a mover el mundo
cr0x@server:~$ zpool status tank
pool: tank
state: ONLINE
scan: scrub repaired 0B in 02:11:43 with 0 errors on Wed Dec 18 03:11:12 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-WDC_WD80EFAX-1 ONLINE 0 0 0
ata-WDC_WD80EFAX-2 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
ata-WDC_WD80EFAX-3 ONLINE 0 0 0
ata-WDC_WD80EFAX-4 ONLINE 0 0 0
logs
nvme-SAMSUNG_MZVLB256 ONLINE 0 0 0
cache
nvme-INTEL_SSDPEKNW512 ONLINE 0 0 0
Qué significa: Online, sin errores, scrub reciente exitoso. Esto es lo que parece “elegible para trabajo riesgoso”.
Decisión: Si ves DEGRADED, FAULTED o errores de checksum en aumento, arréglalo primero. Eliminar bajo degradación es apostar con apuestas más altas.
Task 8: Eliminar un dispositivo L2ARC (seguro, reversible en espíritu)
cr0x@server:~$ sudo zpool remove tank nvme-INTEL_SSDPEKNW512
Qué significa: El dispositivo de caché se desacopla del pool. Normalmente no hay una salida dramática.
Decisión: Monitoriza latencia de lectura y la tasa de aciertos de caché (si la sigues). Si el rendimiento cae, vuelve a añadirlo o reemplázalo por un dispositivo mejor. La integridad de los datos no está en riesgo.
Task 9: Eliminar un dispositivo SLOG (espera cambios en latencia de escrituras síncronas)
cr0x@server:~$ sudo zpool remove tank nvme-SAMSUNG_MZVLB256
Qué significa: ZFS volverá a usar el pool principal para el registro de intenciones. Tus aplicaciones pueden notarlo.
Decisión: Si tu entorno depende de escrituras síncronas (bases de datos, NFS con sync), programa este cambio o ajusta expectativas temporalmente. Si ves timeouts en apps, vuelve a añadir SLOG rápidamente.
Task 10: Inicia la eliminación de un top-level vdev (comienza la evacuación)
cr0x@server:~$ sudo zpool remove tank mirror-1
Qué significa: El pool comienza a evacuar datos desde mirror-1 hacia los vdevs top-level restantes.
Decisión: Comienza inmediatamente a monitorizar el progreso y el rendimiento. También: notifica a las personas. Esto no es una operación silenciosa.
Task 11: Monitoriza el progreso de la eliminación vía zpool status
cr0x@server:~$ zpool status tank
pool: tank
state: ONLINE
remove: Removal of vdev 1 copied 8.31T of 17.2T at 612M/s, 03:48:29 remaining
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-WDC_WD80EFAX-1 ONLINE 0 0 0
ata-WDC_WD80EFAX-2 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0 (removing)
ata-WDC_WD80EFAX-3 ONLINE 0 0 0
ata-WDC_WD80EFAX-4 ONLINE 0 0 0
errors: No known data errors
Qué significa: ZFS informa bytes copiados, tasa y tiempo estimado restante. Las tasas variarán muchísimo; no adores la ETA.
Decisión: Si la tasa colapsa y la latencia se dispara, regula o pausa la carga. Si aparecen errores, detente y reevalúa la salud del hardware.
Task 12: Observa la latencia por dispositivo mientras corre la eliminación (encuentra la rueda lenta)
cr0x@server:~$ iostat -x 5
Linux 6.6.0 (server) 12/25/2025 _x86_64_ (32 CPU)
Device r/s w/s rkB/s wkB/s await svctm %util
sda 92.1 48.3 9840 5120 6.4 1.1 15.2
sdb 89.7 47.9 9600 4980 6.7 1.0 14.8
sdc 31.2 88.4 3200 10120 38.9 1.2 98.5
sdd 29.8 90.1 3100 10320 41.3 1.2 99.1
Qué significa: sdc y sdd están saturados con await alto; probablemente son el vdev que se está eliminando o los vdevs destino bajo presión.
Decisión: Si solo un dispositivo está lento, sospecha de un disco fallando o un problema de ruta. Si ambos dispositivos destino están al máximo, simplemente estás haciendo demasiado I/O—regula la eliminación reduciendo la carga competitiva.
Task 13: Comprueba el comportamiento de TRIM/discard en pools basados en SSD (acantilado de rendimiento oculto)
cr0x@server:~$ zpool get -H autotrim tank
tank autotrim on -
Qué significa: Autotrim está activado. Durante reescrituras intensas, trim puede añadir overhead dependiendo del firmware del dispositivo.
Decisión: Si ves amplificación de escritura o picos de latencia raros en SSDs durante la evacuación, prueba con autotrim=off en una ventana de mantenimiento. No cambies esto a la ligera sin entender el comportamiento de los SSD en tu flota.
Task 14: Encuentra “¿por qué no libera espacio?” con uso lógico vs físico
cr0x@server:~$ zfs get -H -o name,property,value -r used,usedbysnapshots,usedbydataset,usedbyrefreservation tank/vm
tank/vm used 28.7T
tank/vm usedbysnapshots 6.4T
tank/vm usedbydataset 22.3T
tank/vm usedbyrefreservation 0B
Qué significa: Una porción grande son snapshots. Borrar archivos dentro de tank/vm no reclamará el espacio referenciado por snapshots.
Decisión: Ajusta la política de snapshots o replica y poda. Si intentas hacer espacio para la eliminación, los snapshots suelen ser el verdadero bloqueador.
Task 15: Confirma que el vdev eliminado desapareció (verificación del estado final)
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-WDC_WD80EFAX-1 ONLINE 0 0 0
ata-WDC_WD80EFAX-2 ONLINE 0 0 0
errors: No known data errors
Qué significa: mirror-1 desapareció. El tamaño del pool reflejará la reducción.
Decisión: Ahora puedes reutilizar los discos, reemplazarlos o construir un nuevo vdev en otro sitio. También: vuelve a comprobar las alarmas de capacidad. Tus umbrales deben cambiar porque el pool es más pequeño.
Task 16: Valida el tamaño y el margen del pool después del cambio (no supongas)
cr0x@server:~$ zpool list -o name,size,alloc,free,frag,health tank
NAME SIZE ALLOC FREE FRAG HEALTH
tank 23.7T 21.1T 2.6T 64% ONLINE
Qué significa: El pool ahora es mucho más pequeño; el espacio libre también se redujo. La fragmentación aumentó (común tras grandes movimientos).
Decisión: Si el espacio libre ahora es escaso, mueve cargas de trabajo, añade nueva capacidad de vdev o ajusta la retención. No celebres la eliminación y luego olvides que estás cerca del límite.
Tres microhistorias corporativas desde el terreno
Incidente: la suposición equivocada (“podemos eliminar un vdev raidz, ¿no?”)
Una empresa SaaS mediana tenía un pool ZFS que respaldaba una flota de hosts VM. Empezó como raidz2 porque el equipo quería eficiencia de capacidad y tolerancia a fallos. Con el tiempo añadieron otro vdev raidz2 durante un periodo de crecimiento. Luego el crecimiento se frenó, los presupuestos de hardware se apretaron y alguien propuso “quitar el vdev nuevo” para reutilizar esos discos en otro clúster.
El plan parecía inofensivo: iniciar la eliminación un viernes por la noche, dejarla correr todo el fin de semana y presentarse el lunes con un pool más pequeño. El operador había usado zpool remove antes—en dispositivos de caché. Asumieron que la misma flexibilidad aplicaba a cualquier vdev. ZFS no estuvo de acuerdo.
El comando falló con un error directo indicando que el tipo de vdev no era removible en su entorno. El problema mayor no fue la falla; fue lo que ocurrió después. Para “forzarlo”, el equipo intentó una secuencia de soluciones desesperadas: desacoplar dispositivos, poner discos offline e intentar reemplazos parciales. Así convirtieron un vdev raidz sano en uno degradado, a mitad de un cambio, mientras corría producción.
Se recuperaron, pero costó toda la noche: volver a poner online dispositivos, resilvering y cancelar el plan de “shrink” por completo. El postmortem fue simple: el error original fue tratar la eliminación de vdev como una herramienta general para encoger pools. No lo es. Si quieres la opción de encoger, eliges una topología que lo soporte y aceptas el coste.
Optimización que salió mal: añadir un special vdev “temporal” para acelerar metadata
Un equipo de ingeniería de servicios financieros tenía un pool ZFS que servía un gran árbol de archivos con millones de archivos pequeños. Las operaciones de metadata eran lentas, los recorridos de directorios eran penosos y todas las revisiones de incidentes decían lo mismo: “deberíamos añadir SSDs”. Lo hicieron. Añadieron un special vdev en un par de NVMes para alojar metadata y bloques pequeños. El rendimiento mejoró de inmediato.
Entonces se volvieron ambiciosos. Para maximizar capacidad, configuraron el special vdev de una forma técnicamente redundante pero operativamente frágil: las actualizaciones de firmware y el mantenimiento los manejaba otro equipo, y el equipo de almacenamiento no recibía notificaciones sobre peculiaridades de NVMe. Predeciblemente, un NVMe empezó a lanzar errores bajo carga sostenida y a veces desaparecía y reaparecía en el bus PCIe.
Nada se corrompió al instante. Eso es lo que lo hace peligroso. El pool empezó a registrar errores de checksum intermitentes ligados a lecturas de metadata. Los usuarios vieron errores I/O “aleatorios”. La primera reacción del equipo fue quitar el special vdev y volver al mundo anterior. Pero la eliminación requiere una vía sana para leer bloques y reescribirlos en otro sitio. Su “optimización” se había vuelto una dependencia.
La solución final fue poco espectacular: reemplazar el NVMe inestable, resilverar el mirror del special, scrubs hasta limpiar y luego planear una migración/eliminación controlada con margen suficiente. La lección no fue “nunca uses special vdevs”. Fue: si añades un special vdev, trátalo como una capa de almacenamiento de primera clase con gestión de ciclo de vida, monitorización y control de cambios. Si no, es una mejora de rendimiento que te facturará después.
Práctica aburrida pero correcta que salvó el día: margen de capacidad y migración por etapas
Un equipo de plataforma interna empresarial usaba ZFS para directorios home NFS y artefactos de build. Tenían una regla que molestaba a todos: el pool debía mantenerse por debajo del 75% asignado, y la retención de snapshots debía justificarse con necesidades reales de recuperación. Los ingenieros se quejaban porque parecía capacidad desperdiciada.
Un trimestre necesitaron descomisionar un chasis de discos antiguos. El pool se había expandido con los años con múltiples top-level vdevs mirror (no raidz), específicamente porque valoraban la flexibilidad operativa. Planearon la eliminación de vdevs mirror que estaban en el chasis antiguo.
Porque el pool tenía margen, la evacuación pudo ejecutarse sin que el asignador entrara en pánico. Porque los snapshots estaban controlados, pudieron liberar espacio si fue necesario. Porque practicaban scrubs y reemplazaban discos cuestionables temprano, no descubrieron fallos de hardware a mitad de un trabajo de reescritura de varios días.
Las eliminaciones aún llevaron tiempo y el pool trabajó más caliente de lo habitual, pero se mantuvo predecible. El desmantelamiento ocurrió según lo previsto y nadie fuera del on-call de almacenamiento lo notó. Ese es el punto de las prácticas aburridas: no crean historias emocionantes, y por eso las sigues haciendo.
Chiste #2: “Solo quita el vdev” es la versión de almacenamiento de “simplemente reinícialo”—ocasionalmente correcto, usualmente sin la parte donde explicas qué se rompe después.
Errores comunes: síntomas → causa raíz → solución
1) Síntoma: zpool remove se niega con “operation not supported”
Causa raíz: Los flags de característica del pool no incluyen device removal, o tu implementación/versión de ZFS no soporta eliminación para ese tipo de vdev.
Solución: Verifica flags de característica, versión de ZFS y tipo de vdev. Si es raidz, asume que necesitas migración en lugar de eliminación. No intentes trucos creativos de detach/offline.
2) Síntoma: la eliminación comienza, luego el progreso se reduce a casi cero
Causa raíz: El pool está demasiado lleno o fragmentado; el asignador y la selección de metaslabs se vuelven costosos, y las escrituras compiten con el I/O de producción.
Solución: Crea margen (borra/replica datos, reduce snapshots), programa el trabajo en una ventana tranquila y reduce la carga competitiva. Si no puedes, no ejecutes la eliminación online en pico.
3) Síntoma: el pool está ONLINE pero las apps ven picos de latencia y timeouts durante la eliminación
Causa raíz: La evacuación satura discos y destruye la latencia para cargas síncronas o con metadata intensiva.
Solución: Añade capacidad temporal para reducir la presión de movimiento, mueve cargas calientes, o regula en la capa de aplicación (limitar velocidad de backups, pausar reconstrucciones, escalonar trabajos por lotes). Monitoriza a nivel de SLO de la aplicación, no solo métricas de almacenamiento.
4) Síntoma: “Liberamos 5TB pero zpool list free no cambió mucho”
Causa raíz: Los snapshots todavía referencian bloques; el espacio se eliminó lógicamente pero se retiene físicamente.
Solución: Identifica grandes consumidores de snapshots con zfs list -t snapshot y usedbysnapshots. Ajusta retención, replica y luego destruye snapshots intencionalmente.
5) Síntoma: después de quitar SLOG, la base de datos se hunde
Causa raíz: Las escrituras síncronas ahora aterrizan en el pool principal; la latencia aumentó drásticamente.
Solución: Vuelve a añadir SLOG en dispositivos de baja latencia y con protección ante pérdida de energía. Si no puedes, evalúa si la app realmente necesita sync o si por accidente estabas forzando sync via configuración de mount/export.
6) Síntoma: quitar special vdev parece imposible sin riesgo
Causa raíz: El special vdev contiene metadata/bloques pequeños críticos, y no tienes un layout objetivo seguro ni margen para migrar.
Solución: Trátalo como una migración: añade un nuevo special vdev (mirrored), migra, scrub, y luego elimina el antiguo. Si tu plataforma no soporta eliminación, planifica una migración del pool.
7) Síntoma: el pool encogió pero el espacio libre ahora es peligrosamente bajo
Causa raíz: Planeaste la viabilidad de la evacuación, no el margen operativo post-eliminación.
Solución: Recalcula objetivos de capacidad tras la eliminación. Actualiza umbrales de alerta. Añade capacidad antes de que te veas forzado a hacerlo durante un fallo.
8) Síntoma: un disco muestra await loco durante la eliminación
Causa raíz: Disco fallando, cable/HBA defectuoso, o un dispositivo con comportamiento shingled/peculiaridades de firmware bajo escrituras sostenidas.
Solución: Valida hardware. Reemplaza el dispositivo sospechoso antes de continuar una evacuación larga. Si muere a mitad de la operación, podrías perder la capacidad de leer bloques para la evacuación.
Listas de comprobación / plan paso a paso (cómo hacerlo sin improvisar a las 3 a. m.)
Checklist pre-vuelo: decide si la eliminación es la herramienta correcta
- Declara el objetivo: encoger capacidad, descomisionar hardware, quitar una capa de rendimiento o revertir una expansión temporal.
- Identifica el objetivo: cache/log/special/top-level data vdev.
- Verifica soporte: flags de característica e implementación/versión de ZFS para ese objetivo.
- Confirma salud del pool: sin vdevs degradados, sin errores de checksum sin resolver.
- Confirma margen: espacio libre más margen operacional; ajusta snapshots/reservas.
- Planifica impacto en la carga: programa, regula y comunica.
Plan de ejecución: eliminación de top-level vdev (vdev de datos)
- Toma una instantánea de configuración para tu tranquilidad: captura
zpool status,zpool list,zfs listy la configuración de reservas. - Ejecuta un scrub antes de la eliminación si no lo has hecho recientemente. Quieres descubrir errores de lectura latentes ahora, no a mitad de la evacuación.
- Reduce o pausa trabajos batch no críticos: backups, grandes restauraciones y cargas tipo compactación.
- Inicia la eliminación:
zpool remove pool target. - Monitoriza progreso y latencia:
zpool statusyiostat -x. - Si el impacto en rendimiento es inaceptable: reduce primero la carga competitiva. No detengas en pánico a menos que tengas un plan de rollback explícito.
- Cuando termine, verifica topología y capacidad. Actualiza umbrales de monitorización y pronósticos de capacidad.
Plan de ejecución: eliminar SLOG o L2ARC (vdevs auxiliares)
- Mide latencia base de la app y latencia de almacenamiento.
- Elimina el dispositivo con
zpool remove. - Observa cargas de escritura síncronas (bases de datos, NFS) por la eliminación de SLOG; espera poco en la eliminación de L2ARC aparte del recalentamiento de la caché.
- Decide si reemplazar por un dispositivo mejor o quedarte sin él.
Pensamiento de rollback (porque no siempre obtienes lo que quieres)
- Si la eliminación no está soportada: tu rollback es “dejar de intentarlo” y planear una migración a un pool nuevo con la topología adecuada.
- Si la eliminación está soportada pero es demasiado disruptiva: el rollback es operativo—pausar cargas competitivas, añadir capacidad temporal o reprogramar. No puedes “desescribir” la evacuación ya completada.
- Si el hardware comienza a fallar durante la eliminación: trátalo como un incidente. El vdev eliminado debe permanecer legible para terminar la evacuación con seguridad.
Preguntas frecuentes
¿Puedo encoger un pool ZFS como encoges un volumen LVM?
Usualmente no. ZFS fue diseñado para crecer pools. La eliminación de vdev es una característica específica de evacuación, no una herramienta general para encoger, y está limitada por tipo de vdev y soporte de plataforma.
¿Quitar un disco de un mirror es lo mismo que eliminar un vdev?
No. Desacoplar un disco hoja de un mirror cambia la redundancia dentro del vdev. Eliminar un top-level vdev desencadena evacuación de bloques asignados hacia otros top-level vdevs.
¿Puedo eliminar un vdev raidz de un pool?
En muchas implementaciones del mundo real: efectivamente no. Trata los vdevs raidz top-level como permanentes. Si necesitas flexibilidad para encoger, diseña con mirrors o planea la migración del pool.
¿Cuánto tarda la eliminación de vdev?
Depende de los datos asignados en el vdev objetivo, la fragmentación del pool, la velocidad de los dispositivos y la carga competitiva. Espera “horas a días”, no “minutos”, para vdevs de múltiples terabytes.
¿Qué pasa si un disco en el vdev que se elimina falla a mitad de la evacuación?
Si el vdev queda ilegible, la evacuación puede fallar y puedes perder la capacidad de completar la eliminación con seguridad. Los mirrors te dan más resiliencia; los vdevs de disco único son implacables. No inicies eliminación sobre hardware cuestionable.
¿Quitar SLOG arriesga pérdida de datos?
No en el sentido de corromper datos comprometidos. ZFS mantiene la consistencia. El riesgo es el rendimiento: la latencia de escrituras síncronas puede aumentar drásticamente, causando timeouts en aplicaciones.
¿Quitar L2ARC arriesga pérdida de datos?
No. L2ARC es una caché. Quitarla hace que pierdas datos en caché y que la tasa de aciertos se reconstruya con el tiempo.
¿Puedo quitar un special vdev de forma segura?
A veces, pero no es “seguro” en el sentido casual. Los special vdevs contienen metadata; debes asegurar redundancia, salud, margen y soporte en tu plataforma. Trátalo como una migración con scrubs y verificación.
¿Por qué el espacio libre es tan crítico para la eliminación?
Porque la evacuación reescribe bloques asignados en otro sitio. Si los vdevs restantes no pueden aceptar los datos, ZFS no puede completar el movimiento. Además, los pools muy llenos se comportan mal: la asignación se ralentiza y el rendimiento se desploma.
¿Debo preferir mirrors sobre raidz si quiero eliminar vdevs más adelante?
Sí, si la flexibilidad operativa importa más que la eficiencia de capacidad. Los mirrors cuestan más en espacio usable, pero te ofrecen expansiones, reemplazos y (cuando están soportados) eliminaciones más simples.
Conclusión: próximos pasos prácticos
Si quieres quitar algo de un pool ZFS, empieza por clasificarlo. Los dispositivos de caché y log suelen ser victorias fáciles. Los vdevs de datos top-level son posibles solo cuando tu pool y plataforma lo soportan explícitamente, y aun así es una migración controlada de datos bajo carga.
Próximos pasos que rinden inmediato retorno:
- Realiza las comprobaciones de elegibilidad ahora (flags de característica, topología) antes de necesitar la opción durante un incidente.
- Haz cumplir el margen. Si tu pool vive por encima del ~80% asignado todo el tiempo, estás eligiendo vivir en modo crisis.
- Diseña para el cambio: si anticipas encoger, prefiere top-level vdevs en espejo y evita layouts “temporales” que no puedas deshacer.
- Practica las disciplinas aburridas: scrubs, monitorización SMART, higiene de snapshots y reservas que puedas justificar ante un compañero escéptico.
ZFS hará lo correcto cuando respetes sus reglas. Cuando no lo hagas, seguirá haciendo lo correcto—negándose. Eso es una característica. Trátala como tal.