Actualización de OpenZFS: la lista de verificación que evita fallos

¿Te fue útil?

Las actualizaciones de OpenZFS normalmente no fallan porque el código sea malo. Fallan porque los humanos son optimistas, las ventanas de cambio son cortas y la compatibilidad es sutil. La rotura no suele ser dramática; es del tipo silencioso: replicación que se detiene dos días después, un pool de arranque que no se puede importar tras una actualización del kernel, o una feature flag que habilitaste “porque estaba ahí” y que deja tu pool inservible en hosts más antiguos.

Si gestionas almacenamiento en producción, no “actualizas ZFS”. Actualizas un ecosistema: módulos del kernel, herramientas de userland, soporte del bootloader, feature flags, propiedades de datasets, monitorización y todos los scripts que asumen el comportamiento del año pasado. Esta es la lista de verificación que evita que ese ecosistema te cause problemas.

Qué se rompe realmente durante las actualizaciones de OpenZFS

La mayoría de las guías de “actualizar ZFS” se centran en el comando llamado zpool upgrade. Eso es como centrarse en el cinturón del avión mientras se ignoran los motores. Las roturas en el mundo real se agrupan en unas pocas categorías:

1) Actualizaste userland, pero no el módulo del kernel (o viceversa)

En Linux, OpenZFS suele ser un módulo del kernel distribuido vía DKMS o paquetes kABI-tracking. Si tu kernel se actualiza y el módulo no se compila o carga, no tienes ZFS. Si las herramientas de userland son más nuevas que el módulo, obtienes advertencias, comportamientos extraños o funciones ausentes. En FreeBSD, ZFS suele estar integrado, pero aún puedes generar desajustes de versión entre entornos de arranque o jails.

2) Las feature flags hacen que los pools sean “más nuevos” que algunos hosts

OpenZFS usa feature flags en los pools. Una vez habilitadas, algunas flags están “activas” y no se pueden desactivar. La implicación práctica: habilitar una flag puede bloquear permanentemente la importación del pool en implementaciones OpenZFS más antiguas. Eso se vuelve problemático cuando el “host más antiguo” resulta ser tu sitio de DR.

3) El pool de arranque y el soporte del bootloader son un universo aparte

Root-on-ZFS es maravilloso hasta que descubres que tu bootloader entiende solo un subconjunto de características de OpenZFS. El pool puede estar perfectamente sano, pero tu sistema no arranca porque el bootloader no puede leer las estructuras en disco creadas por funciones más nuevas. Si vas a actualizar un pool de arranque, tu plan de reversión debe ser infalible.

4) La compatibilidad de replicación es un contrato operativo

zfs send/zfs receive es tu canal de datos. Si habilitas features o cambias propiedades que alteran la compatibilidad del stream, tu replicación puede fallar, omitir silenciosamente lo que esperas o forzarte a resembrados completos. “Sigue haciendo snapshots” no es lo mismo que “sigue replicando”.

5) Las regresiones de rendimiento suelen ser desajustes en la configuración

Las actualizaciones pueden cambiar valores por defecto, comportamiento del ARC, patrones de prefetch o cómo ciertas cargas interactúan con compresión, recordsize y vdevs especiales. El código puede estar bien; puede que tu carga revele que la sintonía anterior era una ilusión. Necesitas una línea base de rendimiento pre/post, o pasarás una semana discutiendo con gráficos.

Una idea parafraseada de Gene Kim, que hizo carrera traduciendo el dolor operativo a un lenguaje que los ejecutivos entienden: la fiabilidad viene de cambios rápidos y seguros con bucles de retroalimentación. Ese es el núcleo de esta lista de verificación: hacer el cambio seguro, observable y reversible.

Datos históricos e información útil

  • ZFS popularizó el checksum de extremo a extremo para datos y metadatos, lo que cambia cómo piensas sobre la “corrupción silenciosa” respecto a pilas RAID tradicionales.
  • Las feature flags de OpenZFS reemplazaron los antiguos números de versión de pool para que las implementaciones pudieran evolucionar sin una única línea de versión lineal.
  • Copy-on-write es la razón por la que los snapshots son baratos, pero también significa que los patrones de fragmentación del espacio libre pueden sorprenderte tras un churn intenso.
  • El “ARC” no es solo caché; es una caché adaptable con comportamiento de expulsión que puede dominar las conversaciones sobre presión de memoria en cargas mixtas.
  • L2ARC no es un caché de lectura de la forma en que la gente lo imagina; es una caché de segundo nivel con costes de calentamiento y sobrecarga de metadatos que puede perjudicar si está mal dimensionada o en un soporte frágil.
  • Los vdevs especiales (para metadatos y bloques pequeños) pueden ser transformadores, pero también introducen “dispositivos pequeños, críticos y rápidos” que pueden tirar abajo todo el pool si no son redundantes.
  • Los streams de zfs send evolucionaron para soportar propiedades, bloques grandes, datos embebidos y receives reanudables; no todos los receivers entienden todos los sabores de stream.
  • Root-on-ZFS ganó adopción mainstream en varios sistemas operativos porque los boot environments más los snapshots hacen reversibles las actualizaciones—cuando respetas las limitaciones del bootloader.

Preflight: decide qué significa “actualizar” en tu entorno

Antes de tocar paquetes, responde tres preguntas. Si no puedes responderlas, no estás actualizando; estás jugando a los dados en una sala de servidores.

Define el alcance de la actualización

  • ¿Solo userland? Herramientas como zfs, zpool, zed (daemon de eventos).
  • ¿Módulo del kernel? En Linux: versión del módulo ZFS, SPL, estado de compilación DKMS, initramfs.
  • ¿Feature flags del pool? Si ejecutarás zpool upgrade o dejarás los pools como están.
  • ¿Cambios de propiedades en datasets? Algunos equipos “actualizan” activando compresión en todos lados. Eso no es una actualización. Es una migración del comportamiento I/O.

Inventaria la superficie de compatibilidad

Enumera cada sistema que pueda importar este pool o recibir streams de replicación:

  • Hosts primarios
  • Hosts de DR
  • Destinos de backup
  • Estaciones de trabajo forenses/recuperación (sí, alguien intentará importar un pool en un portátil)
  • Capacidades del bootloader si es un pool de arranque

Comprométete con una estrategia de reversión

Solo hay dos estrategias de reversión maduras:

  1. Rollback de entorno de arranque (sistemas ZFS, root-on-ZFS): snapshot/clone del dataset raíz y mantener un boot environment conocido y funcional seleccionable en el arranque.
  2. Rollback fuera de banda (ZFS no raíz): mantener paquetes antiguos disponibles, mantener el kernel antiguo disponible y nunca habilitar características irreversibles hasta estar seguro.

Broma #1: ZFS es como una cocina profesional—todo está etiquetado, checksummed y organizado, y aun así un interno puede incendiar el lugar.

Tareas prácticas: comandos, salidas y decisiones (12+)

Estas son tareas de producción. Cada una incluye un comando, una salida de ejemplo, qué significa y qué decides después. Ejecútalas antes y después de la actualización. Guarda las salidas en tu ticket de cambio. El yo del futuro te lo agradecerá, y el yo del futuro normalmente es quien sostiene el pager.

Task 1: Confirma qué ZFS estás ejecutando realmente

cr0x@server:~$ zfs --version
zfs-2.2.2-1
zfs-kmod-2.2.2-1

Qué significa: Se muestran versiones de userland y módulo del kernel (varía según la distro). Si ves solo userland, comprueba el módulo por separado.

Decisión: Si las versiones no coinciden tras la actualización, detente y arregla la paridad de paquete/módulo antes de tocar los pools.

Task 2: Verifica que el módulo del kernel esté cargado (Linux)

cr0x@server:~$ lsmod | grep -E '^zfs '
zfs                  8843264  6

Qué significa: El módulo ZFS está cargado; el último número es “usuarios”.

Decisión: Si no está cargado, revisa los logs de compilación de DKMS, initramfs y si la actualización del kernel rompió la compilación del módulo.

Task 3: Comprueba la salud del pool y los contadores de errores antes de cambiar nada

cr0x@server:~$ zpool status -x
all pools are healthy

Qué significa: No hay fallos conocidos. Si obtienes otra cosa, tienes trabajo que hacer antes de actualizar.

Decisión: Si hay errores de checksum, resilvering o vdevs degradados: pospon la actualización. Repara el pool primero y luego actualiza.

Task 4: Obtén el estado completo, no el resumen tranquilizador

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: ONLINE
status: One or more devices has experienced an unrecoverable error.
action: Determine if the device needs to be replaced, and clear the errors
  scan: scrub repaired 0B in 00:12:33 with 0 errors on Thu Dec 19 03:12:01 2025
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          raidz1-0  ONLINE       0     0     0
            sda     ONLINE       0     0     2  (repairable)
            sdb     ONLINE       0     0     0
            sdc     ONLINE       0     0     0

errors: Permanent errors have been detected in the following files:
/tank/vmstore/vm-104-disk-0

Qué significa: “Healthy” todavía puede ocultar errores reparados pero reales. Los errores permanentes listan los ficheros afectados.

Decisión: Investiga y remedia errores permanentes (restaurar desde réplica/backup) antes de la actualización. También evalúa el disco sda para reemplazo.

Task 5: Confirma que tienes scrubs recientes y que no gritan

cr0x@server:~$ zpool get -H scrub tank
tank	scrub	scrub repaired 0B in 00:12:33 with 0 errors on Thu Dec 19 03:12:01 2025	-

Qué significa: Resultado y timestamp del último scrub.

Decisión: Si los scrubs son antiguos o muestran errores, haz un scrub antes de actualizar. Quieres datos validados antes de cambiar la pila.

Task 6: Captura las feature flags actualmente habilitadas y activas

cr0x@server:~$ zpool get -H -o name,property,value all tank | grep -E '^tank	feature@'
tank	feature@async_destroy	enabled
tank	feature@empty_bpobj	active
tank	feature@spacemap_histogram	enabled
tank	feature@extensible_dataset	enabled

Qué significa: enabled indica que el pool puede usarla; active indica que está en uso en disco.

Decisión: Si ves features que no reconoces como soportadas por hosts de DR/backup, no ejecutes zpool upgrade todavía. Construye primero una matriz de compatibilidad.

Task 7: Ve qué upgrades están disponibles (y no los apliques a ciegas)

cr0x@server:~$ zpool upgrade
This system supports ZFS pool feature flags.

The following pools are formatted with legacy version numbers and can be upgraded:
  tank

The following feature flags are supported:
  spacemap_histogram
  enabled_txg
  hole_birth
  extensible_dataset
  ...

Qué significa: Muestra las features soportadas y si pools usan versiones legacy.

Decisión: Actualizar el formato del pool es una decisión explícita de compatibilidad. Si existe alguna posibilidad de importar en sistemas antiguos, retrasa la actualización del pool hasta que todos los sistemas estén actualizados y probados.

Task 8: Revisa propiedades de datasets que afectan rendimiento y replicación

cr0x@server:~$ zfs get -r -o name,property,value -s local,received compression,recordsize,atime,xattr,acltype,encryption,keylocation tank
NAME                PROPERTY     VALUE
tank                compression  zstd
tank                recordsize   128K
tank                atime        off
tank/vmstore        recordsize   16K
tank/vmstore        compression  lz4
tank/backup         atime        on

Qué significa: Propiedades locales y recibidas que determinan el layout en disco, patrones I/O y comportamiento.

Decisión: Congela los cambios de propiedades durante la ventana de actualización. Si quieres “arreglar propiedades”, hazlo en un cambio separado con su propia estrategia de reversión.

Task 9: Valida la postura de snapshots/replicación antes de actualizar

cr0x@server:~$ zfs list -t snapshot -o name,creation -S creation | head
NAME                          CREATION
tank/vmstore@autosnap_2025-12-26_0000  Fri Dec 26 00:00 2025
tank/home@autosnap_2025-12-26_0000     Fri Dec 26 00:00 2025
tank@autosnap_2025-12-26_0000          Fri Dec 26 00:00 2025

Qué significa: Hay snapshots y son recientes.

Decisión: Si los snapshots no están al día, arregla la automatización antes de actualizar. Sin snapshots no hay rollback rápido ante errores de datos.

Task 10: Comprueba la compatibilidad del stream de replicación en la práctica (dry run con resumable receive)

cr0x@server:~$ zfs send -nP tank/vmstore@autosnap_2025-12-26_0000 | head
size	1234567896

Qué significa: -nP estima el tamaño del send sin enviarlo. Si esto falla, tienes un problema en el lado del envío.

Decisión: Si la estimación falla después de actualizar, probablemente tocaste una incompatibilidad de feature/property o un cambio en el stream de send. Investiga antes de la próxima replicación programada.

Task 11: Confirma que puedes realmente importar el pool en el host actualizado (y por qué podría no hacerlo)

cr0x@server:~$ zpool import
   pool: tank
     id: 1234567890123456789
  state: ONLINE
 action: The pool can be imported using its name or numeric identifier.
 config:

        tank        ONLINE
          raidz1-0  ONLINE
            sda     ONLINE
            sdb     ONLINE
            sdc     ONLINE

Qué significa: Pool importable descubierto. En un sistema real no ejecutarías esto en el host activo a menos que estés en recuperación; es ideal en un standby o entorno de rescate.

Decisión: Si zpool import muestra “unsupported features”, has probado una ruptura de compatibilidad. No actualices las feature del pool hasta que cada importador esté listo.

Task 12: Valida las restricciones del pool de arranque (entornos root-on-ZFS)

cr0x@server:~$ zpool list -o name,size,alloc,free,ashift,health
NAME   SIZE  ALLOC   FREE  ASHIFT  HEALTH
bpool  1.8G   612M  1.2G      12  ONLINE
rpool  1.8T   1.1T  724G      12  ONLINE

Qué significa: Probablemente tengas un bpool (boot pool) separado con features conservadoras, más rpool para el filesystem raíz.

Decisión: Trata bpool como “almacenamiento compatible con el bootloader”. Sé extremadamente conservador al actualizar o habilitar features en él.

Task 13: Confirma que ZED está en ejecución y reportará problemas

cr0x@server:~$ systemctl status zfs-zed.service --no-pager
● zfs-zed.service - ZFS Event Daemon (zed)
     Loaded: loaded (/lib/systemd/system/zfs-zed.service; enabled)
     Active: active (running) since Thu 2025-12-26 00:10:11 UTC; 2h 3min ago

Qué significa: El demonio de eventos ZFS está activo. Sin él, puedes perder eventos de fallo de disco y alertas de scrub.

Decisión: Si ZED no está corriendo, arréglalo antes de la actualización. La visibilidad es parte de la seguridad.

Task 14: Revisa el comportamiento del ARC antes/después (sanity rápida, no tuning por moda)

cr0x@server:~$ arcstat 1 3
    time  read  miss  miss%  dmis  dm%  pmis  pm%  mmis  mm%  size     c
00:00:01   912    34      3     9   1%    21   2%     4   0%  28.1G  31.9G
00:00:02   877    29      3     8   1%    17   2%     4   0%  28.1G  31.9G
00:00:03   940    35      3     9   1%    22   2%     4   0%  28.1G  31.9G

Qué significa: Tasa de misses y tamaño del ARC. Un pico de miss tras la actualización puede indicar cambio en prefetch o presión de memoria.

Decisión: Si miss% sube y la latencia aumenta, empieza por revisar carga y presión de memoria antes de cambiar tunables.

Task 15: Confirma que la actualización no cambió el comportamiento de montaje o la visibilidad de datasets

cr0x@server:~$ zfs mount | head
tank                          /tank
tank/home                     /tank/home
tank/vmstore                  /tank/vmstore

Qué significa: Datasets montados y sus mountpoints.

Decisión: Si datasets esperados no están montados tras reinicio/actualización, revisa canmount, mountpoint y si systemd cambió el orden de montaje.

Task 16: Post-actualización: asegúrate de que el pool siga limpio y el log de eventos no oculte drama

cr0x@server:~$ zpool events -v | tail -n 12
TIME                           CLASS
Dec 26 02:11:03.123456 2025    sysevent.fs.zfs.config_sync
    pool: tank
    vdev: /dev/sdb

Dec 26 02:11:04.654321 2025    sysevent.fs.zfs.history_event
    history: zpool scrub tank

Qué significa: Eventos recientes de ZFS. Útiles después de actualizaciones para ver si desaparecieron dispositivos, cambió multipath o hubo sync de configuración.

Decisión: Si ves eventos repetidos de remoción/agregado de dispositivos, detente e investiga cableado, HBAs, configuración de multipath o cambios de nombres por udev antes de confiar en el pool.

Listas de verificación / plan paso a paso (la que puedes ejecutar a las 2 AM)

Este plan asume que estás actualizando OpenZFS en un host de producción. Ajústalo a tu plataforma, pero no te saltes la lógica. ZFS castiga la improvisación.

Fase 0: Planificación de compatibilidad (haz esto antes de la ventana de cambio)

  1. Escribe todos los importadores. Cada host que pueda importar el pool, incluido DR, backup y medios de rescate.
  2. Escribe todos los receptores de replicación. Cada destino que reciba streams de zfs send.
  3. Determina la versión más antigua de OpenZFS en ese conjunto. Esa versión es tu piso de compatibilidad.
  4. Decide si ejecutarás zpool upgrade. Respuesta por defecto en un entorno mixto: no. Actualiza el código primero, las features después.
  5. Para pools de arranque: identifica las limitaciones del bootloader. Si no puedes decir qué puede leer tu bootloader, trata las actualizaciones del boot pool como prohibidas hasta probarlas a fondo.
  6. Construye un plan de reversión que no dependa de la esperanza. Kernel antiguo disponible, paquetes antiguos disponibles, entorno de arranque si root-on-ZFS y un “cómo obtener una shell” documentado (IPMI/iLO/consola).

Fase 1: Comprobaciones previas (justo antes del cambio)

  1. Confirma versiones de ZFS (zfs --version).
  2. Confirma módulo cargado (lsmod | grep zfs en Linux).
  3. Confirma salud del pool (zpool status -x, luego zpool status -v).
  4. Confirma recencia del scrub (zpool get scrub).
  5. Captura feature flags (zpool get feature@* o salida filtrada).
  6. Captura propiedades clave de datasets (zfs get -r para compression/recordsize/atime/encryption).
  7. Confirma que existen snapshots y que la replicación corrió limpia (tu tooling + zfs list -t snapshot).
  8. Confirma margen de espacio libre. Quieres slack operativo para resilvers y crecimiento de metadatos.

Fase 2: Ejecución de la actualización (código primero, features después)

  1. Actualiza paquetes. Anota las versiones antes/después.
  2. Reconstruye initramfs si procede. En Linux, ZFS en initramfs importa para pools de arranque.
  3. Reinicia durante la ventana. Si no reinicias, no estás probando la parte más difícil.
  4. Post-boot valida módulo + import del pool + montajes. Verifica zfs mount, servicios y I/O de aplicaciones.
  5. No ejecutes zpool upgrade el primer día. Observa la estabilidad primero.

Fase 3: Verificación post-actualización (inmediatamente y otra vez 24 horas después)

  1. Revisa estado del pool y errores.
  2. Revisa ZED y pipeline de alertas.
  3. Ejecuta un scrub (si la ventana lo permite) o programa uno pronto.
  4. Dispara una replicación y verifica el lado receptor.
  5. Compara líneas base de rendimiento: latencia, IOPS, uso CPU, tasas de miss del ARC.
  6. Revisa zpool events -v por churn de dispositivos.

Fase 4: Actualización de feature flags (solo cuando la flota esté lista)

Cuando—y solo cuando—cada importador y receptor tenga una versión compatible de OpenZFS, y hayas probado rutas de reversión, entonces puedes considerar habilitar nuevas features del pool.

  1. Revisa features soportadas (zpool upgrade).
  2. Habilita features deliberadamente, en conjuntos pequeños, con un registro de cambio.
  3. Verifica que la replicación siga funcionando después.
  4. Actualiza tu documentación de “piso de compatibilidad”. La versión mínima de tu flota acaba de moverse.

Broma #2: Lo único más permanente que una feature flag es la memoria de la persona que la habilitó cinco minutos antes de irse de vacaciones.

Manual de diagnóstico rápido

Tras una actualización de OpenZFS, normalmente recibirás una de tres señales de dolor: no arranca/importa, está lento o la replicación falla. Este playbook está ordenado para encontrar el cuello de botella rápido, no filosóficamente.

Primero: ¿puede el sistema ver el pool y los dispositivos?

  • Comprueba módulo cargado: lsmod | grep zfs (Linux) o valida que el kernel tenga ZFS y que userland coincida.
  • Comprueba que los nombres de dispositivo sean estables: busca discos faltantes, WWNs cambiados, problemas de multipath.
  • Comprueba la importabilidad: zpool import (en un entorno de rescate o standby).
  • Comprueba el estado del pool: zpool status -v para vdevs degradados y errores de checksum.

Segundo: ¿es un problema de compatibilidad/feature flags?

  • Si el pool no se importa y ves “unsupported feature(s)”, detente. No es un problema de tuning.
  • Compara zpool get feature@* entre hosts que funcionan y los que fallan.
  • Para fallos de arranque: sospecha del soporte del bootloader, no de que “ZFS esté roto”.

Tercero: ¿es una regresión de rendimiento o un problema de la ruta I/O?

  • Comprueba latencia en el pool: zpool iostat -v 1 10 (no mostrado arriba, pero deberías ejecutarlo).
  • Comprueba misses del ARC y presión de memoria: arcstat, y estadísticas de memoria del SO.
  • Comprueba uso de CPU en hilos del kernel: CPU system alta puede indicar sobrecarga por checksum/compresión o un patrón patológico de carga.
  • Comprueba drift de recordsize/compresión: las actualizaciones no cambian bloques existentes, pero pueden exponer que tus propiedades “universales” eran mentiras.

Cuarto: ¿es replicación/herramientas?

  • Ejecuta un zfs send -nP manual y revisa errores.
  • Confirma que el receptor puede aceptar el stream (versión/soporte de features).
  • Revisa si tus herramientas de replicación parsean salidas que cambiaron sutilmente.

Errores comunes: síntoma → causa raíz → solución

1) Síntoma: el pool no se importa tras la actualización; el mensaje menciona unsupported features

Causa raíz: Se habilitaron features en el pool desde otro host (o ejecutaste zpool upgrade) y ahora intentas importar en una implementación OpenZFS más antigua.

Solución: Actualiza el entorno importador a una versión OpenZFS compatible. Si esto es DR y no puedes, tu única vía es restaurar desde replicación/backup que apunte a un pool compatible. No puedes “deshabilitar” la mayoría de las features activas.

2) Síntoma: el sistema arranca a initramfs o shell de emergencia; pool raíz no encontrado

Causa raíz: Módulo ZFS no incluido/compilado para el nuevo kernel, initramfs sin ZFS o el módulo falló al cargar.

Solución: Arranca con un kernel antiguo desde el bootloader (mantén uno), recompila DKMS/módulo, reconstruye initramfs y reinicia. Valida la paridad con zfs --version después.

3) Síntoma: el bootloader no puede leer el boot pool, pero el pool se importa bien desde medio de rescate

Causa raíz: Features del boot pool no soportadas por el bootloader. Actualizaste/cambiaste algo en bpool o usaste un ashift/sett de features incompatible para el cargador.

Solución: Restaura el boot pool desde un snapshot/boot environment conocido si está disponible. Si no, reinstala el bootloader con un diseño de boot pool compatible (a menudo: mantener el boot pool conservador y separado).

4) Síntoma: la replicación empieza a fallar tras la actualización con errores de stream

Causa raíz: El sender ahora produce streams usando features que el receptor no puede aceptar, o tu script de replicación asume comportamiento/flags antiguos de zfs send.

Solución: Actualiza primero el receptor (o mantén el sender compatible), y ajusta la herramienta de replicación para usar flags compatibles. Verifica con zfs send -nP y un dataset de prueba pequeño.

5) Síntoma: caída de rendimiento; picos de CPU; aumenta I/O wait

Causa raíz: A menudo no es “ZFS se volvió más lento”, sino un cambio en el kernel, scheduler I/O, implementación de compresión o comportamiento de reclaim que interactúa con el ARC.

Solución: Compara líneas base pre/post. Revisa arcstat miss rates, zpool iostat latencias y si tu carga cambió. Solo entonces considera ajustes dirigidos. No dispares zfs_arc_max por corazonadas.

6) Síntoma: datasets no montados tras reinicio; servicios fallan por rutas faltantes

Causa raíz: Propiedades de dataset como canmount, mountpoint o el orden de systemd cambiaron; a veces una propiedad recibida anula expectativas locales.

Solución: Inspecciona propiedades con zfs get, corrige la fuente prevista (local vs received) y asegúrate de que las dependencias de servicio esperen a los mounts de ZFS.

7) Síntoma: los comandos “zfs” funcionan pero operaciones de pool fallan raro; logs muestran desajuste de versión

Causa raíz: Desajuste entre userland y módulo del kernel tras una actualización parcial.

Solución: Alinea versiones. En Linux, eso significa asegurar que el módulo ZFS esté compilado para el kernel en ejecución y que los paquetes userland coincidan con la misma línea de release.

Tres micro-historias del mundo corporativo (anonimizadas, dolorosamente plausibles)

Micro-historia #1: El incidente causado por una suposición errónea

Una empresa mediana operaba un par de servidores de almacenamiento: primario y DR. El primario se actualizaba trimestralmente. El DR era “estable” como el pan viejo. La suposición era simple: la replicación ZFS son solo snapshots por la red, así que mientras existan datasets, la compatibilidad se arreglará sola.

Durante una actualización rutinaria, un ingeniero ejecutó zpool upgrade porque el comando parecía el siguiente paso lógico. El pool siguió online, nada se cayó y el ticket se cerró pronto. En los días siguientes, los trabajos de replicación empezaron a fallar, pero solo en algunos datasets. Los fallos eran lo bastante intermitentes como para ignorarlos y lo bastante ruidosos como para molestar a todos.

Luego ocurrió un incidente real en el primario: un HBA empezó a lanzar resets bajo carga. Fallaron al conmutar a DR y descubrieron que el pool no se importaba. “Unsupported features” al importar. El DR corría una versión antigua de OpenZFS que no entendía unas feature flags ahora activas. El pool no estaba dañado. Simplemente era demasiado moderno para el entorno que más lo necesitaba.

La recuperación fue aburrida y costosa: reconstruir DR con una pila más nueva y luego restaurar datos desde la replicación que aún funcionaba. La verdadera caída no fue por ZFS; fue por la suposición de que las feature flags son opcionales y reversibles. No lo son.

Micro-historia #2: La optimización que salió mal

Otra organización tenía un clúster de virtualización respaldado por ZFS. Tras actualizar OpenZFS, un ingeniero decidió “aprovechar la nueva versión” cambiando compresión de lz4 a zstd en todo el dataset de VM. La lógica era simple: mejor compresión = menos I/O = mejor rendimiento. Buena teoría en un mundo donde la CPU es gratis y la latencia es imaginaria.

En la práctica, el clúster tenía una carga mixta: escrituras aleatorias pequeñas, operaciones de metadata explosivas y tormentas de backup ocasionales. Tras el cambio, la latencia empeoró en horas punta. La CPU subió. El on-call empezó a ver timeouts de VM que antes nunca aparecían. Las gráficas de disco parecían normales, lo que hacía el incidente más divertido: todos culpaban a la red.

La raíz no fue que zstd sea mala. Fue que cambiaron una propiedad que define la carga en la misma ventana que la actualización de OpenZFS, sin comparativas de línea base. Los niveles de compresión y la sobrecarga de CPU importan. Además, los bloques existentes no se recomprimen, así que el comportamiento fue inconsistente entre VMs según la antigüedad de los datos. Ideal para confusión.

La solución fue revertir compresión en el dataset caliente a lz4, mantener zstd para datos fríos y separar “actualizar la pila de almacenamiento” de “cambiar el comportamiento de almacenamiento”. La actualización no fue la villana; fue el empacado de cambios.

Micro-historia #3: La práctica aburrida pero correcta que salvó el día

Una compañía del sector financiero utilizaba root-on-ZFS por todas partes. Tenían una política que hacía rodar los ojos a los ingenieros: cada actualización de host requería un boot environment fresco, además de un reinicio post-actualización dentro de la ventana. Sin excepciones. La política existía porque alguien, años antes, se cansó del “reboot más tarde” que equivalía a “lo descubriremos durante el outage”.

Durante una actualización de OpenZFS, un host volvió con servicios ZFS fallando al montar un dataset. La causa fue mundana: combinación de orden de servicios y una propiedad de montaje heredada inesperadamente. El host estaba técnicamente arriba, pero las aplicaciones estaban muertas. El ingeniero on-call no intentó arreglos creativos en un sistema roto bajo presión.

Seleccionaron el boot environment previo en el bootloader, volvieron al stack antiguo y restauraron el servicio. Luego, en horario diurno, reprodujeron el problema en staging, arreglaron el orden de montaje y reintentaron la actualización. El downtime fue mínimo porque la reversión no era teórica: era parte de la memoria muscular.

Este tipo de práctica parece lenta hasta que resulta ser más rápida que todas las alternativas.

Preguntas frecuentes (FAQ)

1) ¿Debo ejecutar zpool upgrade inmediatamente después de actualizar OpenZFS?

No, no por defecto. Actualiza la pila de software primero, valida estabilidad y replicación, luego actualiza las features del pool cuando todos los importadores/receptores estén listos.

2) ¿Cuál es la diferencia entre actualizar OpenZFS y actualizar un pool?

Actualizar OpenZFS cambia el código que lee/escribe tu pool. Actualizar un pool cambia feature flags en disco. Esto último puede ser irreversible y afecta la compatibilidad entre hosts.

3) ¿Puedo degradar OpenZFS si algo sale mal?

Normalmente puedes degradar el software si no habilitaste nuevas feature flags y tu distro soporta rollback de paquetes. Si habilitaste features que están activas, las implementaciones antiguas pueden ya no poder importar el pool.

4) ¿Por qué mi pool dice “healthy” pero aún tengo errores permanentes?

zpool status -x es un resumen. Pueden existir errores permanentes aun cuando el pool esté online. Revisa siempre zpool status -v antes de actualizar.

5) ¿Necesito hacer un scrub antes de actualizar?

Si no has hecho un scrub recientemente, sí. Un scrub valida la integridad de los datos en todo el pool. Quieres datos conocidos buenos antes de cambiar módulos del kernel y código de almacenamiento.

6) ¿Alguna precaución especial con datasets encriptados?

Asegura que la gestión de claves funcione tras reinicios: confirma keylocation, prueba procedimientos de desbloqueo y valida que el arranque temprano pueda acceder a las claves si el dataset raíz está encriptado.

7) Mi objetivo de replicación es más antiguo. ¿Puedo actualizar el sender?

A menudo sí, si evitas habilitar features incompatibles y mantienes los streams de replicación compatibles. Pero debes probar: ejecuta zfs send -nP y valida un receive en el objetivo más antiguo.

8) ¿Por qué la gente separa boot pool (bpool) de root pool (rpool)?

Los bootloaders suelen soportar menos features de ZFS que el SO. Un boot pool conservador reduce la probabilidad de que una actualización de features deje el sistema sin arrancar.

9) Si el rendimiento cambió tras actualizar, ¿cuál es la primera métrica en la que confiar?

La latencia a nivel de pool y vdev, además de las tasas de miss del ARC bajo la misma carga. Las gráficas de throughput pueden ocultar regresiones en tail-latency que rompen aplicaciones.

10) ¿L2ARC es buena idea después de actualizar?

Sólo si puedes demostrar que ayuda. L2ARC añade complejidad y puede robar memoria para metadatos. Mide antes y después; no lo trates como un rito de iniciación.

Conclusión: próximos pasos que realmente debes tomar

Aquí tienes el camino práctico que evita la mayor parte del dolor al actualizar OpenZFS:

  1. Inventaria importadores y receptores. La compatibilidad es una propiedad de flota, no de un host.
  2. Actualiza el código primero, reinicia, valida. Si no vas a reiniciar, estás posponiendo la prueba real para un peor momento.
  3. Retrasa zpool upgrade hasta que todo el ecosistema esté listo. Trata las feature flags como migraciones de esquema: planificadas, revisadas y cronometradas.
  4. Captura evidencia. Guarda salidas pre/post de versiones, estado del pool, feature flags, propiedades y pruebas de replicación.
  5. Ejecuta una prueba controlada de replicación. Si no puedes demostrar que send/receive sigue funcionando, no tienes DR: tienes una historia.

Actualizar OpenZFS puede ser aburrido. Ese es el objetivo. La lista de verificación no es ceremonia; es cómo evitas que el turno de on-call se convierta en un evento de desarrollo profesional.

← Anterior
HBM explicado: por qué la memoria se volvió vertical
Siguiente →
Knight Capital: el fallo de trading que quemó cientos de millones en minutos

Deja un comentario