Proxmox ZFS “pool is not healthy”: qué hacer antes de que empeore

¿Te fue útil?

Tu nodo Proxmox va bien, las VM funcionan y de repente lo ves: “pool is not healthy”. Ese mensaje nunca aparece temprano. Es ZFS aclarando la garganta con educación antes de empezar a gritar.

Si lo tratas como una advertencia cosmética, tarde o temprano te encontrarás con un corte que hace que las invitaciones del calendario parezcan ataques personales. Si lo tratas como un incidente controlado, normalmente mantendrás todo operativo —y con frecuencia arreglarás la causa raíz antes de que los datos estén en riesgo.

Qué significa realmente “pool is not healthy” en Proxmox

Proxmox no está haciendo una forense profunda de ZFS cuando muestra “pool is not healthy”. Normalmente está mostrando la propia evaluación de salud de ZFS: el estado del pool no es ONLINE y limpio, o ZFS ha registrado errores que no pudo corregir por completo.

Los estados comunes detrás de la advertencia:

  • DEGRADED: Uno o más vdevs falta o están con fallo, pero aún existe redundancia. Estás funcionando con la rueda de repuesto.
  • FAULTED: El pool (o un vdev) ha perdido redundancia y/o acceso. Las lecturas/escrituras pueden fallar.
  • UNAVAIL: Faltan dispositivos, las rutas están mal, o el pool no puede ser accedido.
  • SUSPENDED: ZFS suspendió I/O por fallos repetidos. Es ZFS diciendo “no te ayudaré a empeorar esto”.

Separado del estado, ZFS también rastrea contadores de error:

  • READ errors: el dispositivo no pudo leer bloques. Podría ser medio físico, cable, controlador o enrutamiento de la ruta.
  • WRITE errors: las escrituras fallaron. A menudo indica problemas del dispositivo/controlador.
  • CKSUM (checksum) errors: los datos leídos del disco no coincidieron con su checksum; la redundancia pudo haberlo reparado. Esto es engañoso porque el disco puede “funcionar” mientras devuelve silenciosamente datos erróneos.

El punto operativo clave: “pool is not healthy” no es un único problema. Es una etiqueta de categoría. Tu trabajo es clasificarlo rápidamente: ¿es una falla de dispositivo, un problema de path/cableado/controlador, un problema lógico/de configuración, o corrupción real de datos?

Idea parafraseada de Werner Vogels (CTO de Amazon): Todo falla, todo el tiempo; diseña y opera como si eso fuera siempre cierto.

Una cosa más: los clústeres Proxmox complican las emociones. Cuando el almacenamiento en un nodo se pone raro, la gente empieza a culpar al quorum, corosync, la red o el clima. No lo hagas. Empieza con la evidencia que da ZFS.

Broma #1: Un pool ZFS “saludable” es como un niño pequeño silencioso: no te jactas, simplemente disfrutas del silencio mientras dura.

Guía de diagnóstico rápido (primero/segundo/tercero)

Esta es la rutina de “orientarse en cinco minutos”. El objetivo no es una solución completa. Es identificar el modo de fallo y decidir si puedes seguir en línea, necesitas mantenimiento o debes dejar de tocar cosas.

Primero: clasifica el estado del pool y el tipo de error

  • Ejecuta zpool status -xv. Quieres: el state, qué dispositivo está implicado, si los errores son READ/WRITE/CKSUM, y el texto exacto del mensaje.
  • Si el pool está SUSPENDED o muestra errores permanentes en archivos, trátalo como incidente de alta severidad. Deja de “optimizar”, empieza a preservar evidencia y hacer backups.

Segundo: determina si es problema de disco o de path

  • Revisa SMART rápidamente: smartctl -a (o el log SMART de NVMe). Busca sectores reasignados, sectores pendientes, errores CRC, errores de media.
  • Consulta los logs del kernel en busca de resets de enlace, errores de I/O, errores de transporte: journalctl -k.
  • Si ves tormentas de CRC o resets de enlace, sospecha de cables/backplane/HBA antes de condenar el disco.

Tercero: decide la siguiente acción según redundancia y riesgo

  • Si existe redundancia (mirror/RAIDZ) y solo un dispositivo está afectado: planifica un reemplazo/resilver controlado.
  • Si la redundancia está comprometida (vdev de un solo disco, RAIDZ con múltiples fallos, varios mirrors degradados): prioriza la evacuación de datos y minimizar escrituras.
  • Si es un escenario de rendimiento + errores (scrub/resilver lento, timeouts): revisa el queueing del HBA, la negociación de velocidad SATA y la contención de carga antes de forzar más I/O.

Hechos interesantes y un poco de historia (porque cambia decisiones)

Esto no es trivia. Explican por qué ZFS se comporta como lo hace —y por qué algunos instintos “clásicos de RAID” son activamente perjudiciales.

  1. ZFS nació en Sun Microsystems a mediados de los 2000, diseñado para acabar con la división “sistema de ficheros más gestor de volúmenes”. Por eso habla de pools y vdevs en lugar de particiones como destino inevitable.
  2. Copy-on-write (CoW) significa que ZFS nunca sobrescribe bloques en vivo en el lugar. Genial para consistencia; también significa que “simplemente ejecutar fsck” no es aplicable. El modelo de reparación es diferente.
  3. Cada bloque tiene checksum, incluida la metadata. Por eso los errores de checksum importan: ZFS está detectando mentiras en la pila de almacenamiento.
  4. Scrub no es una característica de rendimiento. Es una auditoría de integridad. Hazla porque quieres dormir tranquilo, no porque los dashboards luzcan mejor.
  5. “RAIDZ no es RAID” es más que pedantería. Los controladores RAID a menudo ocultan la identidad del disco y detalles de error; ZFS quiere visibilidad directa. Los HBAs en modo IT son populares por una razón.
  6. El estado de salud del pool es conservador. ZFS seguirá quejándose de errores incluso si fueron corregidos, hasta que los borres. Es a propósito: el sistema quiere que los humanos reconozcan el riesgo.
  7. Los sectores 4K lo cambiaron todo. La elección de ashift (alineación de sectores) es básicamente irreversible por vdev y puede destruir silenciosamente el rendimiento si es incorrecta.
  8. Resilver cambió con el tiempo. Las mejoras de “resilver secuencial” en versiones recientes de OpenZFS hicieron que las reconstrucciones fuesen menos castigadoras, pero aún así cargan fuertemente los vdev(s) afectados.
  9. Proxmox hizo ZFS popular en clústeres pequeños. Buen resultado, pero también significa que la gente ejecuta producción con hábitos de laboratorio en almacenamiento.

Reglas de triage: qué haces inmediatamente (y qué no)

Haz esto inmediatamente

  • Captura el estado actual: zpool status, zfs list, logs relevantes. Cuando las cosas empeoren, querrás un antes/después.
  • Detén la actividad no esencial: pospone migraciones, suspende backups masivos, evita explosiones de snapshots. Quieres menos escrituras durante un periodo inestable.
  • Verifica que tienes un backup reciente que restaure, no solo “un trabajo de backup que corrió”. Si la redundancia está comprometida, los backups se vuelven tu único adulto en la sala.

Evita estas tentaciones

  • No “borres” errores para que la alerta desaparezca antes de entenderlos. Borrar es reconocimiento, no una solución.
  • No ejecutes un scrub mientras hay fallos activos (timeouts, resets, pool suspended). Scrub aumenta lecturas; los dispositivos fallando suelen morir más rápido bajo presión.
  • No pongas offline el disco equivocado. Identifica por IDs persistentes, no por “/dev/sdX probablemente…”. “Probablemente” es como creas una segunda falla.
  • No mezcles heroicidades con incertidumbre. Si estás adivinando, cambia a import solo lectura (cuando aplique) y evacúa datos.

Broma #2: Si eliges discos por el orden /dev/sdX, básicamente estás haciendo ingeniería de almacenamiento con una Ouija.

Tareas prácticas con comandos: leer salidas, tomar decisiones

Abajo hay tareas prácticas que puedes ejecutar en un host Proxmox. Cada una incluye: comando, qué significa una salida típica y qué decisión impulsa. Ejecútalas como root o con privilegios adecuados.

Task 1: Confirmar la salud del pool e identificar al culpable

cr0x@server:~$ zpool status -xv
  pool: rpool
 state: DEGRADED
status: One or more devices could not be opened.  Sufficient replicas exist for
        the pool to continue functioning in a degraded state.
action: Attach the missing device and online it using 'zpool online'.
   see: message ID: ZFS-8000-2Q
config:

        NAME                         STATE     READ WRITE CKSUM
        rpool                        DEGRADED     0     0     0
          mirror-0                   DEGRADED     0     0     0
            ata-SAMSUNG_SSD_870...   ONLINE       0     0     0
            ata-SAMSUNG_SSD_870...   UNAVAIL      0     0     0  cannot open

errors: No known data errors

Qué significa: El pool está degradado porque un miembro del mirror no está disponible. Aún no hay errores de datos.

Decisión: Trátalo como urgente pero controlado. Identifica si es fallo de disco o fallo de path. Planifica restaurar la redundancia lo antes posible.

Task 2: Comprobar si Proxmox piensa que algo anda mal a nivel de clúster

cr0x@server:~$ pvecm status
Cluster information
-------------------
Name:             prodcluster
Config Version:   18
Transport:        knet
Secure auth:      on

Quorum information
------------------
Date:             Fri Dec 26 11:02:18 2025
Quorum provider:  corosync_votequorum
Nodes:            3
Node ID:          0x00000001
Ring ID:          1.2a
Quorate:          Yes

Qué significa: El quorum del clúster está bien. Esto es un incidente de almacenamiento, no un drama de split-brain.

Decisión: Mantén el enfoque en ZFS/hardware del nodo. No cambies ajustes de clúster como “arreglo”.

Task 3: Mapear nombres de dispositivo ZFS a rutas de hardware reales (deja de adivinar)

cr0x@server:~$ zpool status -P
  pool: rpool
 state: DEGRADED
config:

        NAME                                                STATE     READ WRITE CKSUM
        rpool                                               DEGRADED     0     0     0
          mirror-0                                          DEGRADED     0     0     0
            /dev/disk/by-id/ata-SAMSUNG_SSD_870_EVO_S5...   ONLINE       0     0     0
            /dev/disk/by-id/ata-SAMSUNG_SSD_870_EVO_S6...   UNAVAIL      0     0     0  cannot open

Qué significa: ZFS ya está usando rutas estables by-id (bien). Si ves /dev/sdX aquí, arréglalo después del incidente.

Decisión: Usa estos IDs para localizar el disco físico en el chasis, la ranura HBA o el mapeo de bahías del backplane.

Task 4: Revisar mensajes recientes del kernel por errores de I/O, resets de enlace y timeouts

cr0x@server:~$ journalctl -k -n 80 --no-pager
Dec 26 10:58:41 server kernel: ata7.00: exception Emask 0x10 SAct 0x0 SErr 0x4050002 action 0x6 frozen
Dec 26 10:58:41 server kernel: ata7.00: irq_stat 0x08000000, interface fatal error
Dec 26 10:58:41 server kernel: ata7: SError: { CommWake DevExch }
Dec 26 10:58:42 server kernel: ata7: hard resetting link
Dec 26 10:58:47 server kernel: ata7: link is slow to respond, please be patient (ready=0)
Dec 26 10:58:52 server kernel: ata7: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
Dec 26 10:58:52 server kernel: sd 6:0:0:0: [sdf] tag#7 FAILED Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
Dec 26 10:58:52 server kernel: blk_update_request: I/O error, dev sdf, sector 14680064 op 0x0:(READ)

Qué significa: Errores fatales de interfaz y resets. Huele a problemas de cableado/backplane/HBA, no necesariamente a “el disco está muerto”. También observa que el enlace se negoció a 3.0 Gbps; podría indicar problemas de calidad de señal.

Decisión: Antes de reemplazar el disco, resitúa/reemplaza cable, mueve la bahía, verifica firmware del HBA y comprueba estabilidad de alimentación. Si los errores continúan, entonces reemplaza el disco.

Task 5: Extraer datos SMART para discos SATA/SAS e interpretar los campos correctos

cr0x@server:~$ smartctl -a /dev/sdf
SMART Attributes Data Structure revision number: 16
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  5 Reallocated_Sector_Ct   0x0033   100   100   010    Pre-fail  Always       -       0
197 Current_Pending_Sector  0x0012   100   100   000    Old_age   Always       -       0
198 Offline_Uncorrectable   0x0010   100   100   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x003e   200   199   000    Old_age   Always       -       37

Qué significa: No hay sectores reasignados/pendientes, pero existen errores CRC. Los errores CRC suelen ser ruido de cableado/backplane, no fallo del plato.

Decisión: Arregla la ruta (cable/backplane/HBA). Luego borra contadores a nivel ZFS (no SMART) y observa. Si CRC sigue subiendo, sigue investigando.

Task 6: Extraer salud NVMe (herramientas diferentes, pistas diferentes)

cr0x@server:~$ nvme smart-log /dev/nvme0
Smart Log for NVME device:nvme0 namespace-id:ffffffff
critical_warning                    : 0x00
temperature                         : 44 C
available_spare                     : 100%
available_spare_threshold           : 10%
percentage_used                     : 6%
media_errors                        : 0
num_err_log_entries                 : 0

Qué significa: NVMe parece sano. Si ZFS reporta errores de checksum en un mirror NVMe y SMART está limpio, sospecha de problemas PCIe, firmware o corrupción de RAM en lugar de desgaste NAND.

Decisión: Correlaciona con journalctl -k para errores PCIe AER; considera actualizaciones de firmware y pruebas de memoria si los checksums persisten.

Task 7: Verificar eventos del pool y líneas de tiempo (ZFS te dice lo que notó)

cr0x@server:~$ zpool events -v | tail -n 25
Dec 26 10:58:52 sysevent.fs.zfs.vdev_fault
  pool: rpool
  vdev: /dev/disk/by-id/ata-SAMSUNG_SSD_870_EVO_S6...
  errno: 5
  description: Vdev I/O failure, zio pool=rpool vdev=/dev/disk/by-id/ata-SAMSUNG...
Dec 26 10:59:10 sysevent.fs.zfs.statechange
  pool: rpool
  old-state: ONLINE
  new-state: DEGRADED

Qué significa: Tienes una marca temporal clara. Eso es oro para correlacionar con mantenimiento, eventos de energía, actualizaciones de kernel o alguien que “solo reseteó un cable rápido”.

Decisión: Usa la línea temporal para validar o descartar hipótesis. Si empezó justo después de un reboot o cambio de firmware, sospecha configuración/compatibilidad.

Task 8: Comprobar el estado del scrub y si es seguro ejecutar uno ahora

cr0x@server:~$ zpool status
  pool: rpool
 state: DEGRADED
status: One or more devices could not be opened...
scan: scrub repaired 0B in 00:18:44 with 0 errors on Sun Dec 22 03:20:12 2025
config:
  ...

Qué significa: El último scrub terminó recientemente sin errores. Eso sugiere que la integridad estaba bien hasta que el vdev quedó missing/unavailable.

Decisión: Arregla el dispositivo missing y resilver; no inicies un scrub hasta restaurar la redundancia (a menos que estés diagnosticando errores de checksum y el pool sea estable).

Task 9: Borrar solo después de haber arreglado la causa (y saber qué estás reconociendo)

cr0x@server:~$ zpool clear rpool
cr0x@server:~$ zpool status -xv
all pools are healthy

Qué significa: Se borraron los contadores de error de ZFS y el pool volvió a healthy.

Decisión: Haz esto sólo tras la remediación. Si borras demasiado pronto, pierdes señal y dificultas probar problemas recurrentes.

Task 10: Encontrar y validar el disco físico que vas a tocar

cr0x@server:~$ ls -l /dev/disk/by-id/ata-SAMSUNG_SSD_870_EVO_S6*
lrwxrwxrwx 1 root root  9 Dec 26 10:40 /dev/disk/by-id/ata-SAMSUNG_SSD_870_EVO_S6... -> ../../sdf
cr0x@server:~$ udevadm info --query=all --name=/dev/sdf | egrep 'ID_SERIAL=|ID_PATH=|DEVNAME='
DEVNAME=/dev/sdf
ID_SERIAL=SAMSUNG_SSD_870_EVO_S6...
ID_PATH=pci-0000:3b:00.0-ata-7

Qué significa: Tienes un serial estable y una ruta de bus. Así evitas arrancar el disco equivocado.

Decisión: Empareja el serial con la etiqueta del chasis o el mapeo HBA. Si no puedes emparejar con confianza, detente y crea el mapeo primero.

Task 11: Poner offline un dispositivo fallando (cuando realmente lo quieres) y reemplazarlo

cr0x@server:~$ zpool offline rpool /dev/disk/by-id/ata-SAMSUNG_SSD_870_EVO_S6...
cr0x@server:~$ zpool status -P
  pool: rpool
 state: DEGRADED
config:

        NAME                                                STATE     READ WRITE CKSUM
        rpool                                               DEGRADED     0     0     0
          mirror-0                                          DEGRADED     0     0     0
            /dev/disk/by-id/ata-SAMSUNG_SSD_870_EVO_S5...   ONLINE       0     0     0
            /dev/disk/by-id/ata-SAMSUNG_SSD_870_EVO_S6...   OFFLINE      0     0     0

Qué significa: Has dejado intencionadamente el dispositivo en offline. ZFS dejará de intentar usarlo, lo cual puede reducir el spam de errores y la latencia.

Decisión: Reemplaza el disco y luego añade el nuevo miembro. No pongas offline discos “para ver qué pasa” en RAIDZ — los mirrors son indulgentes; RAIDZ no tanto.

Task 12: Adjuntar/reemplazar y vigilar el progreso del resilver

cr0x@server:~$ zpool replace rpool /dev/disk/by-id/ata-SAMSUNG_SSD_870_EVO_S6... /dev/disk/by-id/ata-SAMSUNG_SSD_870_EVO_S7...
cr0x@server:~$ zpool status
  pool: rpool
 state: DEGRADED
scan: resilver in progress since Fri Dec 26 11:15:04 2025
        3.12G scanned at 410M/s, 1.02G issued at 134M/s, 92.3G total
        1.02G resilvered, 1.10% done, 0:11:20 to go
config:

        NAME                                                STATE     READ WRITE CKSUM
        rpool                                               DEGRADED     0     0     0
          mirror-0                                          DEGRADED     0     0     0
            /dev/disk/by-id/ata-SAMSUNG_SSD_870_EVO_S5...   ONLINE       0     0     0
            /dev/disk/by-id/ata-SAMSUNG_SSD_870_EVO_S7...   ONLINE       0     0     0  (resilvering)

errors: No known data errors

Qué significa: El resilver está en marcha y las estimaciones parecen razonables. “Scanned” vs “issued” indica cuán rápido ZFS puede leer vs escribir/verificar.

Decisión: Mantén la carga moderada. Si ves timeouts, tasas colapsando o resets repetidos en logs, pausa y arregla la estabilidad del path del hardware.

Task 13: Si el resilver es dolorosamente lento, revisa la presión de I/O y latencia

cr0x@server:~$ iostat -x 2 5
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.33    0.00    5.21   41.08    0.00   41.38

Device            r/s     w/s   r_await   w_await  aqu-sz  %util
sde              58.2   120.4     8.12    42.77   12.40   98.7
sdf               2.1    90.3     1.90   210.55   19.10   99.9

Qué significa: Un dispositivo está saturado con enorme latencia de escritura. Durante resilver, un disco o path débil arrastra todo hacia abajo.

Decisión: Reduce la carga competitiva (backups, replicación), revisa configuraciones de caché de escritura, verifica que el disco de reemplazo no sea SMR disfrazado en pools HDD, y confirma que no hay cuello de botella en el controlador.

Task 14: Comprobar si ves señales de corrupción relacionadas con memoria

cr0x@server:~$ dmesg | egrep -i 'edac|mce|ecc|machine check' | tail -n 20
[  912.220112] EDAC MC0: 1 CE memory scrubbing error on CPU_SrcID#0_Ha#0_Chan#1_DIMM#0
[  912.220119] mce: [Hardware Error]: Corrected error, no action required.

Qué significa: Errores ECC corregidos siguen siendo una señal. Si aparecen errores de checksum en múltiples discos o vdevs, RAM/CPU/PCIe se convierten en sospechas creíbles.

Decisión: Si los patrones de error están “en todas partes”, no juegues al whack-a-mole con discos. Estabiliza la plataforma: pruebas de memoria, resitúa DIMMs, actualiza firmware, revisa alimentación.

Task 15: Encontrar “errores permanentes” y decidir si necesitas recuperación a nivel de archivo

cr0x@server:~$ zpool status -v
  pool: tank
 state: ONLINE
status: One or more devices has experienced an error resulting in data corruption.
action: Restore the file in question if possible.
  see: message ID: ZFS-8000-8A
config:
        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          raidz1-0  ONLINE       0     0     0
            sdb     ONLINE       0     0     0
            sdc     ONLINE       0     0     0
            sdd     ONLINE       0     0     0

errors: Permanent errors have been detected in the following files:

        tank/vmdata:vm-104-disk-0

Qué significa: El pool está ONLINE, pero un archivo está corrupto y no puede ser reparado por redundancia. En términos de Proxmox, eso podría ser un disco de VM.

Decisión: Restaura desde backup o réplica. Para un disco de VM, considera restaurar la imagen de disco de la VM o migrar el servicio a un snapshot conocido bueno si lo tienes.

Task 16: Validar elecciones de ashift y recordsize (problemas de rendimiento que parecen “salud”)

cr0x@server:~$ zdb -C rpool | egrep 'ashift|vdev_tree' -n | head -n 20
55:    vdev_tree:
61:        ashift: 12
cr0x@server:~$ zfs get recordsize,compression,atime tank/vmdata
NAME        PROPERTY     VALUE  SOURCE
tank/vmdata recordsize   128K   local
tank/vmdata compression  zstd   local
tank/vmdata atime        off    local

Qué significa: ashift: 12 (4K) generalmente es sensato. Las opciones de dataset muestran un dataset de VM con compresión y atime off.

Decisión: Si ashift es 9 en discos 4K modernos, espera problemas. No puedes “arreglar” ashift en sitio; reconstruyes vdevs. La afinación de recordsize es específica de la carga; no la cambies durante un incidente a menos que sepas exactamente por qué.

Tres micro-historias corporativas desde el terreno

Mini-historia 1: El outage causado por una suposición equivocada

Tenían un clúster Proxmox ordenado: tres nodos, cada uno con SSDs mirrored de arranque y un RAIDZ2 separado para almacenamiento de VM. La alerta decía “pool is not healthy” en el pool de VM de un nodo. El ingeniero on-call hizo lo que muchos hacemos a las 2 a.m.: buscó en la memoria la última vez que ocurrió.

La última vez fue un SSD muerto. Así que asumieron que era un disco muerto otra vez. Vieron un dispositivo en UNAVAIL y lo pusieron offline de inmediato. Fueron al rack y reemplazaron la unidad en la bahía que creían que correspondía a /dev/sdf. El pool siguió degradado. Los errores persistieron. Luego otro dispositivo empezó a alternar. Ahora el pool no solo estaba degradado, se estaba volviendo inestable.

La causa raíz fue mundana: el HBA se había movido a otra ranura PCIe durante un mantenimiento previo, y el mapeo bahía→dispositivo que mantenían en un doc compartido ya no era correcto. El “disco muerto” estaba bien; era la bahía equivocada. Sacaron un disco sano de RAIDZ2, convirtiendo “un dispositivo faltante” en “ahora estamos realmente en peligro”.

Se recuperaron, pero solo porque el pool era RAIDZ2 y tenía un margen de error más amplio que el que merecía su proceso. La postmortem no fue sobre ZFS. Fue sobre disciplina de identificación: siempre usa /dev/disk/by-id, siempre valida números de serie y nunca asumas que los nombres de dispositivo del SO son estables.

Mini-historia 2: La optimización que salió mal

Otra compañía quería más rendimiento para VM. Alguien leyó que deshabilitar escrituras síncronas puede aumentar throughput, y puso sync=disabled en un dataset usado por una VM de base de datos. Se veía genial en benchmarks. Las gráficas de latencia se volvieron motivo de orgullo.

Meses después, el almacenamiento empezó a mostrar errores de checksum. Un scrub encontró un puñado de reparaciones y luego algunos errores permanentes en un disco de VM. La reacción inmediata fue culpar a “discos malos” y reemplazaron dos discos en dos nodos. Los errores siguieron apareciendo y ahora todos estaban nerviosos porque los reemplazos no “lo arreglaron”.

La historia real: tenían un problema de firmware del controlador que ocasionalmente reconocía escrituras antes de que fueran durables. Con la semántica síncrona debilitada, la tolerancia del sistema a reconocimientos extraños desapareció. El modo de fallo se convirtió en “la aplicación cree que el dato está comprometido, hay un parpadeo de energía y ahora ZFS ve una realidad inconsistente”. ZFS hizo su trabajo quejándose, pero no pudo deshacer una transacción de base de datos que la VM ya creía segura.

Revirtieron la propiedad del dataset a sync=standard, añadieron un SLOG adecuado en hardware con protección ante pérdida de energía y actualizaron el firmware del controlador. El rendimiento bajó un poco. Los incidentes bajaron mucho. La lección no fue “nunca optimizar”. Fue “optimiza solo después de entender qué contrato de seguridad estás reescribiendo”.

Mini-historia 3: La práctica aburrida que salvó el día

Esta es menos glamorosa y más instructiva. Una organización mediana tenía un entorno Proxmox con mirrors ZFS para almacenamiento de VM. Nada sofisticado. Pero tenían dos hábitos aburridos: scrubs mensuales con alertas y pruebas trimestrales de restauración para un conjunto pequeño de VMs críticas.

Un lunes apareció “pool is not healthy” con unos pocos errores de checksum en un solo disco. SMART estaba bien. Los logs del kernel mostraban resets de enlace intermitentes. En lugar de reemplazar el disco inmediatamente, programaron una ventana de mantenimiento, movieron VMs fuera del nodo y reemplazaron un cable SAS sospechoso y un expander de backplane que tenía un puerto conocido por fallar.

Borraron los contadores de error de ZFS solo después de la reparación de hardware. Los errores no regresaron. El pool se mantuvo estable. No hubo reemplazos de emergencia, no hubo swaps de discos aleatorios, no hubo scrubs de pánico.

Y aquí está la parte que importa: como ya tenían resultados de scrub y ejercicios de restauración, la dirección no discutió la ventana de mantenimiento. Tenían un historial que traducía riesgo técnico en confianza operativa. La práctica aburrida no fue solo “buena higiene”. Fue apalancamiento organizacional.

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

1) Síntoma: “CKSUM errors increasing” pero SMART parece limpio

Causa raíz: A menudo un cable defectuoso, backplane marginal, puerto HBA inestable o problemas PCIe/AER. Los checksums detectan datos malos en cualquier parte de la cadena.

Solución: Correlaciona con journalctl -k por resets; resitúa/reemplaza cables, mueve el disco a otra bahía/puerto, actualiza firmware del HBA. Luego ejecuta scrub una vez estable para validar integridad.

2) Síntoma: Pool DEGRADED después de reboot, dispositivo UNAVAIL

Causa raíz: Cambio en enumeración de dispositivos, falta de enlaces by-id en initramfs, o timing del BIOS/HBA causando disponibilidad tardía del dispositivo.

Solución: Asegura que los pools usen rutas /dev/disk/by-id; verifica actualizaciones de initramfs; revisa ajustes BIOS/HBA y orden de arranque; evita mezclar arranque por USB con complejidad ZFS en producción.

3) Síntoma: Scrub “repaired bytes” repetidamente cada scrub

Causa raíz: Fuente de corrupción persistente: RAM inestable, problemas de controlador o un disco que devuelve lecturas inconsistentes.

Solución: No celebres “lo reparó”. Eso es la advertencia. Ejecuta diagnósticos de memoria, revisa logs ECC, verifica firmware e aísla moviendo miembros del vdev a otros puertos.

4) Síntoma: Resilver extremadamente lento y el host se siente congelado

Causa raíz: Resilver compite con I/O de VM; disco de reemplazo más lento que otros; unidades SMR en carga de escritura aleatoria; cuellos de botella en la cola del controlador.

Solución: Limita cargas (pausa backups, migra VMs calientes), confirma la clase de disco (evita SMR en pools de VM), considera programar resilver en horarios de baja actividad.

5) Síntoma: Pool SUSPENDED

Causa raíz: ZFS se rindió con I/O por fallos repetidos. A menudo un controlador/backplane fallando fuerte, o múltiples discos caídos.

Solución: Detén escrituras. Captura logs. Revisa la capa física y la alimentación. Considera import read-only y evacuación de datos. Reemplaza componentes fallidos antes de intentar un import normal.

6) Síntoma: Proxmox UI advierte, pero zpool status -x dice healthy

Causa raíz: Estado en caché obsoleto, retardo del monitoreo o el pool se recuperó recientemente pero la alerta no se borró.

Solución: Revisa de nuevo con zpool status -xv, borra alertas resueltas en tu monitoreo y verifica que no haya contadores de error no-cero.

7) Síntoma: “Permanent errors in vm-XXX-disk-Y”

Causa raíz: La redundancia no pudo reconstruir un bloque. Podría ser fallos múltiples, corrupción silenciosa o datos escritos durante un periodo defectuoso.

Solución: Restaura desde backup/replicación. Si tienes snapshots, intenta clonar y ejecutar checks en el guest. No asumas que “ZFS lo arreglará” cuando dice explícitamente que no puede.

8) Síntoma: Flapping frecuente OFFLINE/ONLINE de dispositivos

Causa raíz: Conexión suelta, alimentación marginal, sobrecalentamiento, problemas de expander o gestión agresiva de energía de enlace.

Solución: Arregla la capa física, mejora la refrigeración, revisa rieles PSU, desactiva funciones de ahorro de energía problemáticas para rutas de almacenamiento y monitoriza recurrencia de errores.

Listas de verificación / plan paso a paso

Checklist A: “Acabo de ver la alerta” (primeros 15 minutos)

  1. Ejecuta zpool status -xv. Regístralo (pega en ticket/notas).
  2. Ejecuta zpool status -P para confirmar rutas by-id y obtener el identificador exacto del dispositivo.
  3. Revisa journalctl -k alrededor de la hora del primer error; busca resets/timeouts/AER.
  4. Extrae salud SMART/NVMe del dispositivo implicado.
  5. Decide: fallo de disco vs fallo de path vs sospecha sistémica (RAM/controlador).
  6. Reduce churn: pausa jobs pesados de backup/replicación; evita migraciones grandes.
  7. Verifica la capacidad de restauración de backups para las VMs más críticas en ese pool.

Checklist B: Reemplazo controlado de disco (mirror o RAIDZ, sistema estable)

  1. Identifica el disco por /dev/disk/by-id y número de serie.
  2. Si está fallando pero aún presente, zpool offline intencionalmente.
  3. Reemplaza hardware (disco, cable, bahía o puerto HBA según la evidencia).
  4. Usa zpool replace con rutas by-id.
  5. Monitoriza zpool status hasta que el resilver termine.
  6. Tras completar, considera un scrub (si fue tema de checksum) en ventana tranquila.
  7. Solo entonces, zpool clear si es necesario, y vigila recurrencia.

Checklist C: Cuando la redundancia está comprometida (estás al límite)

  1. Detén escrituras no esenciales. Si es posible, apaga con gracia VMs no críticas.
  2. Captura evidencia: zpool status -xv, zpool events -v, logs del kernel.
  3. Prioriza evacuación: backups, replicación o exportar discos de VM a otro destino.
  4. Si el import es inestable, considera import read-only cuando aplique y copia lo que puedas.
  5. Reemplaza primero el componente más obviamente fallado (a menudo path/controlador/energía).
  6. Después de que vuelva la estabilidad, reconstruye redundancia; luego ejecuta un scrub para validar.

Checklist D: Después del incidente (evitar la secuela)

  1. Programa scrubs regulares con alertas (mensual es común; ajusta según capacidad y carga).
  2. Monitorea SMART y tasas de resets de enlace; alerta por tendencias, no solo por umbrales.
  3. Documenta el mapeo bahía→serie y mantenlo actualizado tras cambios de hardware.
  4. Estandariza HBAs y versiones de firmware entre nodos.
  5. Prueba restauraciones trimestralmente para VMs representativas.

FAQ

1) ¿“pool is not healthy” significa que ya estoy perdiendo datos?

No necesariamente. DEGRADED suele significar que la redundancia está reducida pero los datos siguen intáctos. “Permanent errors” es la frase que debería hacerte asumir que algún dato está corrupto.

2) ¿Debo ejecutar un scrub inmediatamente?

Sólo si el pool es estable y estás diagnosticando integridad. Si los dispositivos están cayendo, hay timeouts o el pool está suspended, un scrub puede empujar hardware fallando al colapso.

3) ¿Qué es peor: READ errors o CKSUM errors?

READ errors indican que el dispositivo no puede leer. CKSUM errors indican que el dispositivo (o el path) devolvió datos incorrectos. Los CKSUM a menudo apuntan a cables/controlador/RAM y pueden ser más insidiosos.

4) ¿Puedo simplemente limpiar los errores para que Proxmox deje de quejarse?

Puedes, pero es una mala idea antes de arreglar la causa. Borrar quita el rastro de evidencia. Borra tras la remediación para detectar recurrencias con claridad.

5) ¿Cómo sé que estoy reemplazando el disco correcto?

Usa zpool status -P y /dev/disk/by-id. Confirma con udevadm info y el número de serie del disco. Si no puedes emparejar serial→bahía, pausa y crea el mapeo.

6) ¿Por qué el pool quedó DEGRADED tras un reboot aunque los discos estén “bien”?

Causas comunes son cambios en el pathing, inicialización lenta de dispositivos o nodes by-id faltantes en initramfs. Arregla usando IDs persistentes y revisando comportamiento de boot/initramfs.

7) Resilver está tardando una eternidad—¿puedo acelerarlo?

La forma más rápida de “acelerarlo” es eliminar I/O competitivo: pausa backups, evita migraciones, reduce carga de escritura de VMs. Si el dispositivo de reemplazo es más lento o el path inestable, no hay ajuste que supere arreglar hardware.

8) ¿Es obligatoria la memoria ECC para ZFS en Proxmox?

¿Obligatoria? No. ¿Muy recomendada en producción? Sí —especialmente si ejecutas VMs importantes. Sin ECC, apuestas a que los errores de memoria no coincidirán con I/O intenso y scrubs.

9) ¿Qué pasa si zpool status muestra “errors: No known data errors” pero el pool no está healthy?

Usualmente significa que la redundancia está reducida o falta un dispositivo, pero ZFS no ha identificado bloques irrecuperables. Aún necesitas restaurar redundancia rápidamente.

10) ¿Debería usar RAID por hardware con ZFS en Proxmox?

En general: evítalo. ZFS quiere control directo de dispositivos y visibilidad. Usa un HBA (modo IT) a menos que tengas una excepción muy específica y bien entendida.

Próximos pasos para evitar reincidencias

Cuando Proxmox indica que un pool ZFS no está saludable, trátalo como una alarma de humo, no como un adorno de tablero. El mejor resultado es aburrido: identifica el componente fallando, restaura redundancia, valida integridad y ajusta hábitos operativos para que la próxima alerta sea accionable en lugar de misteriosa.

Pasos prácticos que puedes hacer esta semana:

  • Configura un cronograma recurrente de scrubs y alerta por errores o ralentizaciones de scrub.
  • Implementa disciplina de identidad de discos: /dev/disk/by-id en todas partes y mantiene un mapa bahía→serie.
  • Establece una línea base de salud SMART/NVMe y patrones de errores del kernel para detectar “nuevos raros” rápidamente.
  • Ejecuta una prueba de restauración desde backup para una VM crítica. No porque esperes fallos—porque esperas la realidad.

Si no haces nada más: no borres la alerta hasta que puedas explicarla. ZFS te está dando la oportunidad de arreglar el problema mientras aún tienes opciones. Aprovecha la pista.

← Anterior
Correo: Buzón lleno — prevenirlo y recuperarlo sin problemas
Siguiente →
Debian 13: tormentas de writeback en disco — ajustar vm.dirty sin riesgo de pérdida de datos (caso #45)

Deja un comentario