Reemplazar un disco en ZFS es una de esas tareas que parece rutinaria—hasta que deja de serlo. El pool pasa a DEGRADED, las alertas empiezan a sonar, tu cola de tickets se llena de “¿sigue siendo seguro?”, y alguien inevitablemente sugiere reiniciar “para limpiar todo.” Así es como conviertes un único disco malo en un incidente de varios días con una buena dosis de arrepentimiento.
Este es el flujo que uso en producción cuando quiero resultados previsibles: identificar el disco correcto por el número de serie, validar el reemplazo, elegir el verbo ZFS adecuado (replace/attach/detach/online), monitorizar el resilver como si te importara, y cerrar limpiamente para que el pool quede realmente sano—no “verde hasta el próximo scrub”.
Qué significa “seguro” al reemplazar discos en ZFS
En ZFS, “seguro” no es una sensación. Es una secuencia de verificaciones que evita tres fallos clásicos:
- Reemplazar el disco equivocado (el error de operador número 1). Así es como conviertes la redundancia en una moneda al aire.
- Usar la ruta de dispositivo equivocada (hola, la ruleta /dev/sdX), lo que provoca que el pool “se sane” en otro disco físico distinto al que crees.
- Declarar la victoria demasiado pronto: el resilver termina, pero no arreglaste el problema de transporte/controladora subyacente, así que el siguiente disco “falla” por simpatía.
La verdad operativa: ZFS es muy bueno con la integridad de datos y muy honesto sobre lo que sabe. Pero ZFS no puede protegerte de números de bahía confusos, expanders SAS defectuosos, backplanes mal cableados, o un disco de reemplazo que venga DOA. Tu flujo de trabajo debe cubrir esa brecha.
Usa el verbo ZFS correcto o sufre las consecuencias
“Reemplazo” de disco en ZFS puede significar cosas distintas:
zpool replace: reemplaza una hoja específica por otra. Es la vía habitual para discos fallidos.zpool attach: añade un disco a un vdev de un solo disco para convertirlo en mirror, o añade otro disco a un mirror existente (raro; ten cuidado). No es un reemplazo.zpool detach: elimina un disco de un vdev mirror (nunca de RAIDZ). Se usa tras migraciones basadas en attach o para reducir mirrors.zpool offline/online: sacar un disco de servicio temporalmente. Útil cuando quieres controlar el momento.
Uno más: zpool clear no es una solución. Limpia contadores de error. Puede ser apropiado después de corregir un problema de cableado y querer confirmar estabilidad. No es apropiado como ritual para que las alertas desaparezcan.
Idea parafraseada de Gene Kim: el verdadero trabajo de la fiabilidad es hacer que el camino normal sea el camino seguro. Eso aplica a swaps de discos tanto como a despliegues.
Broma corta #1: Si tu plan depende de “recordaré cuál es el disco”, felicitaciones—has inventado almacenamiento no persistente para humanos.
Hechos interesantes y breve historia (para que dejes de pelearte con el sistema)
- ZFS fue creado para detectar corrupción silenciosa de datos. Los checksums se almacenan separados de los datos, así que un disco no puede “corregirse a sí mismo”.
- El resilver ha cambiado con el tiempo: OpenZFS moderno soporta resilver secuencial, que suele ser más amable con pools fragmentados y más rápido en discos giratorios.
- Los scrubs preceden muchas ideas “cloud-native”. Un scrub de ZFS es básicamente verificación continua a escala, mucho antes de que “escaneo de integridad” fuera moda.
- RAIDZ no es RAID5. Objetivos similares, implementación muy distinta: ZFS tiene checksums end-to-end y un modelo transaccional que evita el clásico write hole.
ashiftes para siempre. Una vez que un vdev se crea con un ashift (exponente del tamaño de sector), no lo cambias sin reconstruir el vdev.- Las guerras por los nombres de dispositivo son antiguas. Los administradores han sido quemados por nombres inestables desde antes de que SATA fuera cool; existen IDs persistentes porque los humanos siguen perdiendo esa pelea.
- El “autoexpand” de ZFS existe porque las actualizaciones son normales. Pero no es magia. Tiene reglas y tiempos, y no arregla tamaños de vdev desajustados.
- ZFS puede usar un log de intención separado (SLOG) para acelerar escrituras síncronas, pero no ayuda a la velocidad de resilver y puede complicar el manejo de fallos.
- SMART no es la verdad, es testimonio. Los discos pueden morir sin aviso; otros chillan durante meses y siguen funcionando. ZFS usa checksums y redundancia para vivir en la realidad.
Preflight: qué comprobar antes de tocar hardware
El reemplazo de un disco es una coreografía entre ZFS, el SO, el controlador/HBA, el chasis/backplane y la persona que sostiene la bandeja. El objetivo es reducir la incertidumbre antes de tirar de nada.
Reglas que sigo en producción
- No sacar discos sin confirmar el número de serie. Los números de bahía mienten. Las etiquetas cambian. Los humanos leen mal. Los números de serie no se preocupan.
- Hacer un scrub o al menos evaluar el estado del último scrub primero. Si el pool ya tiene errores de checksum, el resilver no es un paseo de celebración—es una prueba de estrés.
- No resilveer durante una ventana sensible a rendimiento a menos que controles deliberadamente el ritmo y aceptes el radio de impacto.
- Preferir identificadores persistentes de dispositivo (rutas by-id) para operaciones de replace y para la configuración del vdev a largo plazo.
- Validar el disco de reemplazo: tamaño de sector, capacidad, tipo de transporte y “¿es siquiera el disco correcto?”.
Tareas prácticas: comandos, qué significa la salida y qué decisión tomar
Las siguientes tareas son deliberadamente repetitivas. Ese es el punto. Los swaps de discos fallan cuando la gente improvisa.
Task 1: Confirmar la salud del pool e identificar el vdev problemático
cr0x@server:~$ sudo zpool status -v tank
pool: tank
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: Replace the device using 'zpool replace'.
scan: scrub repaired 0B in 03:12:44 with 0 errors on Tue Dec 24 01:12:18 2025
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
raidz2-0 DEGRADED 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0A123 ONLINE 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0A124 ONLINE 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0A125 UNAVAIL 0 0 0 cannot open
ata-WDC_WD80EFAX-68LHPN0_VKJ0A126 ONLINE 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0A127 ONLINE 0 0 0
errors: No known data errors
Significado: ZFS no puede abrir una hoja; la redundancia mantiene el pool en línea. El historial de scrub está limpio. Bien.
Decisión: Reemplazar ...VKJ0A125. No tocar otros discos. Si varios están inestables, pausa e investiga el cableado/backplane antes de cambiar más hardware.
Task 2: Obtener el árbol vdev completo con nombres persistentes (y ver si ya los usas)
cr0x@server:~$ sudo zpool status -P tank
pool: tank
state: DEGRADED
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
raidz2-0 DEGRADED 0 0 0
/dev/disk/by-id/ata-WDC_WD80EFAX-68LHPN0_VKJ0A123 ONLINE 0 0 0
/dev/disk/by-id/ata-WDC_WD80EFAX-68LHPN0_VKJ0A124 ONLINE 0 0 0
/dev/disk/by-id/ata-WDC_WD80EFAX-68LHPN0_VKJ0A125 UNAVAIL 0 0 0
/dev/disk/by-id/ata-WDC_WD80EFAX-68LHPN0_VKJ0A126 ONLINE 0 0 0
/dev/disk/by-id/ata-WDC_WD80EFAX-68LHPN0_VKJ0A127 ONLINE 0 0 0
Significado: La configuración del pool usa rutas by-id estables. Esto es lo que quieres.
Decisión: Continuar usando /dev/disk/by-id/... para el reemplazo. Si ves /dev/sdX, corrígelo durante/después del reemplazo (detalles más adelante).
Task 3: Confirmar que el SO ve el disco fallido (o que realmente desapareció)
cr0x@server:~$ ls -l /dev/disk/by-id/ | grep VKJ0A125 || true
Significado: Si la ruta falta, el disco no se está enumerando—puede ser disco muerto, bahía muerta o problema de enlace.
Decisión: Si falta, revisa los registros del controlador y el enlace físico antes de asumir que solo el disco es el problema.
Task 4: Extraer errores recientes del kernel/almacenamiento (ver controlador/backplane)
cr0x@server:~$ sudo dmesg -T | egrep -i "ata|sas|scsi|reset|link|I/O error|blk_update_request" | tail -n 25
[Wed Dec 24 09:42:11 2025] ata9.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 frozen
[Wed Dec 24 09:42:11 2025] ata9.00: failed command: READ FPDMA QUEUED
[Wed Dec 24 09:42:11 2025] blk_update_request: I/O error, dev sdi, sector 123456789
[Wed Dec 24 09:42:12 2025] ata9: hard resetting link
[Wed Dec 24 09:42:13 2025] ata9: link is slow to respond, please be patient
[Wed Dec 24 09:42:18 2025] ata9: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[Wed Dec 24 09:42:19 2025] sd 9:0:0:0: [sdi] tag#2 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
Significado: Reseteos de enlace y errores I/O. Podría ser el disco. Podría ser la bahía/cable.
Decisión: Si varios discos en el mismo puerto muestran reseteos, detente e investiga el HBA/backplane. Si está aislado a un disco, el reemplazo es razonable.
Task 5: Mapear el dispositivo by-id a una bahía física (herramientas del chasis)
En chasis SAS, a menudo tienes sg_ses / sesutil / herramientas del vendedor. En Linux con HBAs comunes, empieza con lsblk y udevadm.
cr0x@server:~$ lsblk -o NAME,SIZE,SERIAL,MODEL,HCTL,PATH | egrep "sdi|VKJ0A125|NAME"
NAME SIZE SERIAL MODEL HCTL PATH
sdi 7.3T VKJ0A125 WDC WD80EFAX 9:0:0:0 /dev/pci0000:3b/0000:3b:00.0/ata9/host8/target8:0:0/8:0:0:0/block/sdi
Significado: Tienes el serial y el HCTL/ruta. Esa es tu pista para la bahía correcta.
Decisión: Usa este mapeo con la documentación del chasis o la gestión del enclosure para identificar la bahía exacta antes de extraer nada.
Task 6: Confirmar que el disco de reemplazo es sano (tamaño, sector, transporte)
cr0x@server:~$ sudo smartctl -a /dev/sdj | egrep "Model|Serial|User Capacity|Sector Size|Rotation Rate|SMART overall|SATA Version"
Device Model: WDC WD80EFAX-68LHPN0
Serial Number: VKJ0B555
User Capacity: 8,001,563,222,016 bytes [8.00 TB]
Sector Size: 512 bytes logical, 4096 bytes physical
Rotation Rate: 5400 rpm
SMART overall-health self-assessment test result: PASSED
SATA Version is: SATA 3.3, 6.0 Gb/s
Significado: La capacidad coincide, sectores físicos 4Kn, SMART pasa. Buena base.
Decisión: Si el reemplazo es más pequeño (incluso ligeramente), detente. ZFS no puede reemplazar un disco por otro más pequeño en el mismo vdev. Si las características de sector difieren, procede pero espera consecuencias de rendimiento/ashift (cubierto más adelante).
Task 7: Comprobar la realidad de ashift del pool (porque pasan sorpresas)
cr0x@server:~$ sudo zdb -C tank | egrep "ashift|vdev_tree|path" | head -n 30
vdev_tree:
type: 'raidz'
id: 0
ashift: 12
children[0]:
path: '/dev/disk/by-id/ata-WDC_WD80EFAX-68LHPN0_VKJ0A123'
children[1]:
path: '/dev/disk/by-id/ata-WDC_WD80EFAX-68LHPN0_VKJ0A124'
Significado: ashift: 12 (4K). Esto suele ser correcto para discos modernos.
Decisión: Si ves ashift: 9 en discos 4K, no lo “arregles” reemplazando un disco. Planea reconstruir/migrar el vdev cuando puedas permitirlo.
Task 8: Poner el disco fallido offline (retirada controlada)
cr0x@server:~$ sudo zpool offline tank ata-WDC_WD80EFAX-68LHPN0_VKJ0A125
Significado: ZFS deja de usar ese disco y espera que esté ausente. Esto reduce el caos cuando extraes la unidad.
Decisión: Poner offline antes de la retirada física salvo que el disco ya haya desaparecido. Si el pool ya está perdiendo el disco, hacer offline puede no importar.
Task 9: Confirmar que el disco está offline (no otro disco)
cr0x@server:~$ sudo zpool status tank | sed -n '1,35p'
pool: tank
state: DEGRADED
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
raidz2-0 DEGRADED 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0A123 ONLINE 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0A124 ONLINE 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0A125 OFFLINE 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0A126 ONLINE 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0A127 ONLINE 0 0 0
Significado: La hoja correcta está offline. Si ves otro disco offline, detente inmediatamente y deshaz el último comando.
Decisión: Proceder al intercambio físico.
Task 10: Después de insertar el disco nuevo, encontrar su ruta by-id estable
cr0x@server:~$ ls -l /dev/disk/by-id/ | egrep "VKJ0B555|WDC_WD80EFAX" | tail -n 5
lrwxrwxrwx 1 root root 9 Dec 24 10:11 ata-WDC_WD80EFAX-68LHPN0_VKJ0B555 -> ../../sdj
lrwxrwxrwx 1 root root 10 Dec 24 10:11 ata-WDC_WD80EFAX-68LHPN0_VKJ0B555-part1 -> ../../sdj1
Significado: El SO ve el disco nuevo como sdj, pero usarás la ruta by-id.
Decisión: Usar /dev/disk/by-id/ata-...VKJ0B555 para zpool replace.
Task 11: Borrar etiquetas antiguas en el disco de reemplazo (evitar fantasmas)
cr0x@server:~$ sudo zpool labelclear -f /dev/disk/by-id/ata-WDC_WD80EFAX-68LHPN0_VKJ0B555
Significado: Limpia etiquetas ZFS que podrían confundir el reemplazo (común con discos reutilizados).
Decisión: Si falla porque el disco está ocupado, detente y comprueba que no hayas elegido por error un disco ya en uso.
Task 12: Reemplazar el disco offline por el disco nuevo
cr0x@server:~$ sudo zpool replace tank ata-WDC_WD80EFAX-68LHPN0_VKJ0A125 /dev/disk/by-id/ata-WDC_WD80EFAX-68LHPN0_VKJ0B555
Significado: ZFS comienza el resilvering hacia el disco nuevo. La identidad del disco viejo ahora se asocia al dispositivo físico nuevo.
Decisión: Empezar a monitorizar el resilver inmediatamente. Si el pool no empieza a resilverar, comprueba ruta errónea, nombre de hoja equivocado, o que el disco realmente no esté presente.
Task 13: Monitorizar el progreso del resilver (y aprender cómo se ve “bien”)
cr0x@server:~$ watch -n 10 sudo zpool status tank
Every 10.0s: sudo zpool status tank
pool: tank
state: DEGRADED
status: One or more devices is currently being resilvered.
scan: resilver in progress since Wed Dec 24 10:14:02 2025
1.82T scanned at 920M/s, 612G issued at 308M/s, 1.82T total
102G resilvered, 32.83% done, 03:44:10 to go
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
raidz2-0 DEGRADED 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0A123 ONLINE 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0A124 ONLINE 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0B555 ONLINE 0 0 0 (resilvering)
ata-WDC_WD80EFAX-68LHPN0_VKJ0A126 ONLINE 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0A127 ONLINE 0 0 0
Significado: Obtienes scanned, issued, rendimiento actual, ETA, y la hoja marcada como “(resilvering)”.
Decisión: Si el rendimiento colapsa o la ETA crece sin control, salta a la Guía rápida de diagnóstico. No esperes horas para “ver si se arregla solo”.
Task 14: Comprobar si aumentan errores de lectura/escritura/checksum durante el resilver
cr0x@server:~$ sudo zpool status -v tank | sed -n '1,60p'
pool: tank
state: DEGRADED
scan: resilver in progress since Wed Dec 24 10:14:02 2025
2.34T scanned, 1.01T issued, 180G resilvered, 54.11% done
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
raidz2-0 DEGRADED 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0A123 ONLINE 0 0 2
ata-WDC_WD80EFAX-68LHPN0_VKJ0A124 ONLINE 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0B555 ONLINE 0 0 0 (resilvering)
ata-WDC_WD80EFAX-68LHPN0_VKJ0A126 ONLINE 0 1 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0A127 ONLINE 0 0 0
errors: No known data errors
Significado: Los errores aumentan en otros discos, no solo en el reemplazado. Eso huele a un problema compartido (cable, expander, HBA, alimentación).
Decisión: Pausar cambios operativos. Considerar limitar cargas de trabajo, revisar errores de transporte y quizá poner offline un segundo disco solo si la redundancia lo permite y tienes un plan.
Task 15: Cuando el resilver termine, verificar que el pool esté realmente sano
cr0x@server:~$ sudo zpool status tank
pool: tank
state: ONLINE
scan: resilvered 1.09T in 04:18:51 with 0 errors on Wed Dec 24 14:32:53 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0A123 ONLINE 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0A124 ONLINE 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0B555 ONLINE 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0A126 ONLINE 0 0 0
ata-WDC_WD80EFAX-68LHPN0_VKJ0A127 ONLINE 0 0 0
errors: No known data errors
Significado: El pool está ONLINE, el resilver completó y no se registraron errores.
Decisión: Programa un scrub pronto si el pool tuvo alguna inestabilidad. Un scrub tras un resilver es el movimiento de “confiar pero verificar”.
Task 16: Confirmar la política de TRIM/autotrim (SSDs y algunos casos SMR)
cr0x@server:~$ sudo zpool get autotrim tank
NAME PROPERTY VALUE SOURCE
tank autotrim off local
Significado: Autotrim está off. En pools de SSD eso puede afectar rendimiento/reescritura de espacio; en pools HDD suele ser irrelevante.
Decisión: Para pools basados en SSD, considera activarlo tras verificar firmware/comportamiento del controlador. No toques configuraciones en medio de un resilver a menos que disfrutes depurar tu propia curiosidad.
Paso a paso: reemplazar un disco en un mirror (la versión menos dramática)
Los mirrors son indulgentes. También son donde la gente se descuida porque “es solo un mirror.” Los mirrors fallan cuando reemplazas el lado equivocado y descubres que has estado funcionando con una sola pata durante meses.
Flujo de reemplazo en mirror
- Identificar la hoja fallida vía
zpool status -P. Capturar la ruta by-id y el serial. - Confirmar mapeo físico (LEDs de bahía si están disponibles; si no, mapeo serial → bahía).
- Poner offline la hoja fallida si aún está presente:
zpool offline pool oldleaf. - Reemplazar el disco físicamente. Esperar a que el SO lo enumere.
- Labelclear el disco nuevo si pudo haber sido usado antes.
- Reemplazar:
zpool replace pool oldleaf newdisk. - Monitorizar resilver. Los mirrors suelen resilverar rápido, pero vigila errores en el disco “bueno”.
- Cerrar con un scrub programado pronto si ese mirror es importante.
Cuándo usar attach para mirrors
Usas zpool attach cuando conviertes un vdev de un solo disco en un mirror, o cuando quieres intencionadamente un mirror triple temporalmente. Durante reemplazos, replace es el por defecto porque preserva la topología e intención del vdev.
Paso a paso: reemplazar un disco en RAIDZ (donde la paciencia es una virtud)
Los resilvers en RAIDZ son más pesados. Leen desde muchos discos y reconstruyen datos en el nuevo. Esa carga puede sacar a la luz discos marginales, cables marginales y suposiciones marginales.
Flujo de reemplazo en RAIDZ
- Confirmar margen de redundancia. RAIDZ1 con un disco fallido vive al límite. RAIDZ2 te da margen de maniobra, no permiso para ser descuidado.
- Comprobar historial de scrub y errores actuales. Si ya tienes errores de checksum, trata esto en modo incidente.
- Estabilizar la plataforma. Si ves reseteos o timeouts en múltiples discos, arregla el transporte primero.
- Poner offline el disco objetivo (si está presente) para no competir con el SO durante el hot-swap.
- Reemplazar usando la ruta by-id persistente, no
/dev/sdX. - Monitorizar resilver y métricas del sistema. El resilver puede saturar I/O y afectar aplicaciones. Eso es normal. La pregunta es: ¿progresa de forma consistente?
- Después de completar, verificar que no aparezcan nuevos errores. Si los errores aumentaron, no “limpies” y olvides—investiga, porque el próximo scrub te lo recordará.
Broma corta #2: El resilvering de RAIDZ es como ver secar la pintura, salvo que la pintura ocasionalmente puede prenderse fuego.
Paso a paso: ampliar capacidad con discos más grandes (sin engañarte)
Las ampliaciones de capacidad son donde la gente accidentalmente ejecuta “almacenamiento de realidad mixta”: el pool informa un tamaño, el chasis contiene otro, y todos discuten con matemáticas. El enfoque seguro es aburrido: reemplaza un disco a la vez, espera el resilver, repite, y luego expande.
La secuencia aburrida y correcta
- Reemplaza un disco por otro más grande usando
zpool replace. - Espera a que el resilver termine.
- Repite para cada disco en el vdev.
- Activa autoexpand si quieres que ZFS crezca los vdevs cuando sea posible.
- Expande el pool (a menudo es automático tras el último reemplazo; a veces requiere online/expand manual según la plataforma).
Task 17: Comprobar la configuración autoexpand y habilitar si procede
cr0x@server:~$ sudo zpool get autoexpand tank
NAME PROPERTY VALUE SOURCE
tank autoexpand off default
Significado: Autoexpand está actualmente off.
Decisión: Si estás actualizando discos intencionadamente y quieres que ZFS crezca los vdevs automáticamente cuando todas las hojas sean más grandes, actívalo. Si no estás en una actualización planificada, déjalo como está.
cr0x@server:~$ sudo zpool set autoexpand=on tank
Task 18: Confirmar tamaño del pool y asignación por vdev tras las actualizaciones
cr0x@server:~$ sudo zpool list -v tank
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 29.1T 18.4T 10.7T - - 22% 63% 1.00x ONLINE -
raidz2-0 29.1T 18.4T 10.7T - - 22% 63% - ONLINE -
Significado: El tamaño del pool y de los vdevs ahora refleja la capacidad ampliada.
Decisión: Si el tamaño no cambió tras reemplazar todos los discos, probablemente necesites hacer online/expand de los dispositivos, o la partición de la plataforma dejó espacio sin usar.
Task 19: Poner online y expandir una hoja (cuando sea necesario)
cr0x@server:~$ sudo zpool online -e tank /dev/disk/by-id/ata-WDC_WD80EFAX-68LHPN0_VKJ0B555
Significado: El -e intenta expandir el dispositivo para usar el espacio disponible.
Decisión: Usa esto si reemplazaste por un disco más grande y ZFS no ha detectado el tamaño. Si el disco está particionado y la partición no se expandió, debes arreglar el particionamiento primero (fuera del alcance de este artículo, pero el punto es: ZFS no puede usar espacio que no ve).
Guía rápida de diagnóstico (encuentra el cuello de botella antes de culpar a ZFS)
Cuando el resilver es lento, se queda o hace que la máquina se sienta como si avanzara en jarabe, no adivines. Hacer triage en un orden estricto. El objetivo es decidir: ¿es un resilver lento normal, conflicto de carga, un disco hermano fallando, o un problema de transporte/controladora?
Primero: confirmar que ZFS realmente progresa
- Comprobar la línea scan de
zpool status: ¿aumenta “issued” con el tiempo? ¿aumenta “resilvered”? - Decisión: Si el progreso es constante, mayormente tienes un tema de ajuste/planificación. Si el progreso se detiene, tienes un fallo.
cr0x@server:~$ sudo zpool status tank | sed -n '1,20p'
pool: tank
state: DEGRADED
scan: resilver in progress since Wed Dec 24 10:14:02 2025
2.61T scanned at 410M/s, 1.22T issued at 190M/s, 230G resilvered, 61.44% done, 02:31:20 to go
Segundo: buscar dolor en el transporte (timeouts, reseteos, reintentos)
Los problemas de transporte imitan fallos de disco y arruinan los resilvers.
cr0x@server:~$ sudo dmesg -T | egrep -i "reset|timeout|link|frozen|SAS|phy|I/O error" | tail -n 40
[Wed Dec 24 11:02:41 2025] ata10: hard resetting link
[Wed Dec 24 11:02:46 2025] ata10: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[Wed Dec 24 11:03:10 2025] blk_update_request: I/O error, dev sdh, sector 987654321
Decisión: Si los reseteos se correlacionan con caídas de rendimiento y afectan a múltiples discos, sospecha de cable/backplane/HBA. Arregla eso primero. Reemplazar “otro disco” no ayudará.
Tercero: medir saturación y colas a nivel de dispositivo
cr0x@server:~$ iostat -x 5 3
Linux 6.8.0 (server) 12/24/2025 _x86_64_ (32 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
12.10 0.00 6.20 18.50 0.00 63.20
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s w_await aqu-sz %util
sdg 98.0 101024.0 0.0 0.00 22.10 1030.9 12.0 1408.0 11.20 2.18 99.0
sdh 96.0 98624.0 0.0 0.00 21.80 1027.3 10.0 1280.0 10.90 2.10 98.5
sdj 30.0 9216.0 0.0 0.00 15.50 307.2 80.0 81920.0 35.10 3.90 99.3
Significado: Utilización cercana al 100% y altos tiempos await. Eso puede ser normal durante un resilver en HDDs, pero vigila si un disco destaca mucho.
Decisión: Si un disco tiene mucho mayor await o errores, es el siguiente candidato a fallo—o está en un puerto malo.
Cuarto: comprobar latencia y presión de cola a nivel ZFS
cr0x@server:~$ sudo zpool iostat -v tank 5 3
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 18.4T 10.7T 420 210 180M 92.0M
raidz2-0 18.4T 10.7T 420 210 180M 92.0M
sda - - 90 45 38.0M 20.0M
sdb - - 85 40 36.0M 18.5M
sdj - - 60 95 22.0M 38.0M
sdd - - 92 15 40.0M 6.0M
sde - - 93 15 44.0M 9.0M
---------- ----- ----- ----- ----- ----- -----
Decisión: Si el disco nuevo es el hotspot de escritura (común), eso es esperado. Si el ancho de banda de lectura de un disco viejo colapsa, investiga ese disco y su enlace.
Quinto: decidir si limitar cargas o posponer
Si esto es una caja de producción compartida, resilver más lecturas random intensas es un impuesto de rendimiento. A veces la respuesta correcta es: limitar o mover cargas. ZFS no negocia con tu tráfico pico.
Errores comunes: síntomas → causa raíz → solución
1) Síntoma: el pool sigue DEGRADED después del reemplazo
Causa raíz: Reemplazaste la hoja equivocada, usaste la ruta de dispositivo equivocada, o el disco nuevo no se adjuntó al vdev correcto.
Solución: Revisa zpool status -P. Confirma que la hoja reemplazada ahora apunta a la ruta by-id nueva. Si ves viejo y nuevo, puede que hayas usado attach en lugar de replace. Corrige la topología intencionalmente.
2) Síntoma: el resilver “avanza” pero nunca termina (la ETA no para de crecer)
Causa raíz: Errores de lectura o reseteos de enlace en discos supervivientes, o el disco nuevo cae intermitentemente.
Solución: Revisa dmesg por reseteos/timeouts. Revisa contadores de error en zpool status. Si los errores están en varios discos por una misma ruta, arregla el transporte.
3) Síntoma: cannot replace ... with ... o “device is too small”
Causa raíz: El disco de reemplazo es ligeramente más pequeño (común entre modelos/vendedores) o la partición es más pequeña de lo esperado.
Solución: Usa un disco con capacidad igual o mayor. Si está particionado, asegura que la partición de reemplazo coincida o supere la original.
4) Síntoma: el disco nuevo aparece ONLINE pero acumula errores de escritura inmediatamente
Causa raíz: Disco nuevo defectuoso, enlace SATA/SAS malo, o problema en la bahía del backplane.
Solución: Mueve el disco a otra bahía si es posible para aislar bahía vs disco. Ejecuta tests SMART extendidos si hay tiempo. Trata reseteos repetidos como problemas de plataforma, no de ZFS.
5) Síntoma: después de “ampliar con discos más grandes”, el tamaño del pool no aumenta
Causa raíz: No todos los discos del vdev se actualizaron, autoexpand está off, las hojas no se expandieron, o las particiones no se redimensionaron.
Solución: Verifica el tamaño de cada hoja, activa autoexpand si procede y usa zpool online -e donde sea soportado. Confirma tamaños de partición.
6) Síntoma: el scrub encuentra nuevos errores de checksum justo después del reemplazo
Causa raíz: Tenías corrupción latente o un disco/cable marginal que solo se mostró bajo lecturas intensas.
Solución: Identifica qué vdev/disco muestra errores. Si los errores están en un disco, reemplázalo. Si están dispersos, investiga el controlador/backplane. No “limpies” y sigas adelante.
7) Síntoma: reemplazaste un disco y ahora el pool no importa
Causa raíz: Se removieron/pusieron offline múltiples discos, se extrajo el disco equivocado, o cruzaste el límite de redundancia (especialmente RAIDZ1). A veces también es una controladora que presenta IDs distintos tras un reboot.
Solución: Para. Preserva evidencia. Usa zpool import para inspeccionar pools importables y su estado. Evita flags forzados a menos que entiendas los transaction groups y qué estás sobreescribiendo.
Task 20: Inspeccionar pools importables cuando las cosas parecen mal
cr0x@server:~$ sudo zpool import
pool: tank
id: 1234567890123456789
state: DEGRADED
status: One or more devices are missing from the system.
action: The pool can be imported despite missing or damaged devices. The fault tolerance of the pool may be compromised.
config:
tank DEGRADED
raidz2-0 DEGRADED
ata-WDC...VKJ0A123 ONLINE
ata-WDC...VKJ0A124 ONLINE
ata-WDC...VKJ0B555 ONLINE
ata-WDC...VKJ0A126 ONLINE
ata-WDC...VKJ0A127 UNAVAIL
Significado: ZFS ve el pool y probablemente puede importarlo, pero falta un dispositivo.
Decisión: No fuerces nada hasta saber qué dispositivo físico falta y por qué.
Tres mini-historias corporativas desde las trincheras
Incidente causado por una suposición errónea: “La bahía 12 es la bahía 12 en todas partes”
Una empresa mediana tenía un par de servidores de almacenamiento en dos racks, mismo modelo de chasis, mismo número de bahías, pools espejados para varios servicios. Saltó una alerta de disco: zpool status mostraba un serial específico faltante. El ingeniero on-call hizo lo “normal”: pidió a facilities que sacaran la “Bahía 12” porque las etiquetas del chasis decían Bahía 12.
Resultó que un chasis había sido reparado meses antes. Durante el servicio, el cableado del backplane se había reorientado para acomodar un mapeo de puerto HBA distinto. Las etiquetas del chasis seguían pareciendo correctas; el mapeo detrás de ellas había cambiado. “Bahía 12” en la UI no era Bahía 12 en el metal.
Sacaron un disco sano. El pool pasó de DEGRADED a “tienes un problema”. Afortunadamente era RAIDZ2, así que el servicio siguió arriba, pero el plan de resilver se volvió más feo. Reinsertaron el disco equivocado rápidamente—aun así ZFS registró una ráfaga de errores por la extracción repentina bajo carga.
El postmortem fue corto y doloroso: la causa raíz no era ZFS. Era un flujo humano que confiaba en el número de bahía sin confirmar el serial. La solución fue aburrida: requerir verificación por serial antes de la extracción, y mantener un documento vivo de mapeo por chasis (puerto HBA → expander → bahía).
La lección mayor: en producción, “hardware idéntico” es un mito. Los sistemas derivan. La gente olvida. Las etiquetas sobreviven más que las verdades.
Optimización que salió mal: “Aceleremos el resilver subiendo la concurrencia”
Otro equipo tenía un gran pool RAIDZ en HDDs con cargas mixtas: lecturas analíticas durante el día, escrituras de backup por la noche. Querían resilvers más rápidos para reducir ventanas de riesgo. Alguien encontró tunables que prometían más throughput aumentando la paralelización y “haciendo que el sistema use más los discos.”
Cambiaron unos parámetros durante horario laboral—porque el pool ya estaba degradado y “necesitamos esto ya.” La tasa de resilver subió… brevemente. Luego la latencia de las aplicaciones se disparó. La máquina empezó a loguear timeouts. No solo en el disco reemplazado; en varios discos.
El verdadero cuello de botella no era “ZFS que no intenta lo suficiente.” Era la ruta HBA/expander y una profundidad de cola que se volvió patológica con los nuevos ajustes. Con más concurrencia, el sistema convirtió latencias transitorias en timeouts de comando, que ZFS interpretó como errores de dispositivo. El pool pasó ciclos reintentando y recuperando, en lugar de copiar datos.
Revirtieron los tunables y en cambio limitaron la carga moviendo jobs por lotes fuera del host durante el resilver. El resilver tardó más que el pico óptimo, pero terminó de forma fiable y el pool no acumuló nuevos errores.
Regla de optimización: si no sabes cuál es el cuello de botella, tu “tuning” es solo una nueva forma de equivocarte, más rápido.
Práctica aburrida pero correcta que salvó el día: IDs persistentes y manos lentas
Una firma de servicios financieros operaba mirrors ZFS para bases de datos de baja latencia y RAIDZ2 para backups. Sus runbooks eran estrictos: cada extracción de disco requería el nombre de hoja ZFS, la ruta by-id, el número de serie, y una segunda persona para verificar el serial físico en la etiqueta. Sin excepciones, incluso a las 3 a.m.
Una noche, un disco empezó a lanzar errores. El on-call siguió el procedimiento, puso offline la hoja exacta, y el técnico reemplazó el disco correcto. Empezó el resilver. Luego, a mitad de camino, otro disco en el mismo backplane empezó a mostrar reseteos de enlace.
Aquí es donde la práctica aburrida pagó: como estaban vigilando los contadores de error y dmesg durante el resilver, reconocieron un problema de ruta compartida temprano. Pausaron cargas no esenciales y resituaron el cable del backplane en una ventana controlada. Los errores pararon. El resilver completó limpio.
El análisis posterior mostró que el segundo disco estaba bien. Era el cable. Si hubieran “optimizado” cambiando discos rápidamente para perseguir alertas, podrían haber sacado un disco sano y cruzado la línea de redundancia. En cambio, trataron al sistema como un sistema: discos, enlaces y humanos.
Operar de forma fiable es en gran parte negarse a tener prisa justo en los momentos en que te sientes apurado.
Listas de verificación / plan paso a paso
Checklist A: Reemplazo estándar de disco fallido (cualquier topología)
- Ejecutar
zpool status -P; copiar el identificador exacto de la hoja y la ruta by-id. - Confirmar historial de scrub y errores actuales. Si existen errores de checksum, tratar como riesgo elevado.
- Comprobar logs del sistema (
dmesg) por reseteos/timeouts que afecten a varios discos. - Mapear serial → bahía física; confirmar con herramientas/etiquetas del chasis.
- Poner offline el disco objetivo (si está presente) con
zpool offline. - Reemplazar el disco físico; confirmar el serial nuevo en el SO.
- Limpiar etiquetas en el disco nuevo:
zpool labelclear -f. - Ejecutar
zpool replaceusando rutas by-id. - Monitorizar resilver con
zpool status,zpool iostaty métricas del SO. - Al completar, confirmar que el pool está ONLINE y los contadores de error estables.
- Programar un scrub si este incidente implicó reseteos, errores de checksum o múltiples discos con problemas.
- Cerrar el ciclo: registrar serial antiguo, serial nuevo, fecha y cambios de mapeo de bahía.
Checklist B: Plan de contención si pudiste haber sacado el disco equivocado
- Deja de sacar discos. Vuelve a insertar el disco removido si es posible.
- Ejecuta
zpool status -Py toma una captura de la salida para notas del incidente. - Comprobar margen de redundancia: RAIDZ1 con dos discos faltantes no es lugar para experimentos.
- Usar identificación por serial para reconciliar lo que falta vs lo que se removió físicamente.
- Si el pool aún es importable, no exportes/importes repetidamente “a ver si ayuda.” Estabiliza primero.
- Sólo tras estabilizar el sistema, procede con un reemplazo verificado a la vez.
Checklist C: Ampliación de capacidad (discos más grandes)
- Confirmar layout actual de vdev y ashift (para no actualizar hacia errores anteriores).
- Asegurar que los discos de reemplazo son realmente más grandes (no “marketing más grande”).
- Reemplazar exactamente un disco por vdev a la vez, esperando el resilver cada vez.
- Tras reemplazar todas las hojas en un vdev, verificar la expansión (
zpool list -v). - Usar
zpool online -edonde sea necesario y seguro. - Ejecutar un scrub tras el reemplazo final y la expansión.
Task 21: Línea base de rendimiento y latencia antes/después del reemplazo (para detectar regresiones)
cr0x@server:~$ sudo zpool iostat -v tank 1 5
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 18.4T 10.7T 110 65 42.0M 18.0M
raidz2-0 18.4T 10.7T 110 65 42.0M 18.0M
sda - - 22 13 8.5M 3.0M
sdb - - 20 12 7.9M 2.8M
sdj - - 26 15 9.8M 4.0M
sdd - - 21 12 8.1M 4.1M
sde - - 21 13 7.7M 4.1M
---------- ----- ----- ----- ----- ----- -----
Significado: Establece un perfil básico. Si un disco se vuelve lento tras el reemplazo, aquí lo verás.
Decisión: Si el disco nuevo rinde mucho peor que sus pares, sospecha de quirks SMR, comportamiento firmware o enlace/puerto malo.
Task 22: Ejecutar un scrub posterior al reemplazo (verificación planificada)
cr0x@server:~$ sudo zpool scrub tank
Significado: Inicia una comprobación completa de integridad. En pools grandes puede tardar horas.
Decisión: Programarlo en una ventana más tranquila si la carga es sensible a latencia; monitorizar por errores e impacto en rendimiento.
Task 23: Comprobar resultados del scrub y tomar la decisión de “firmar”
cr0x@server:~$ sudo zpool status tank | sed -n '1,15p'
pool: tank
state: ONLINE
scan: scrub repaired 0B in 06:41:08 with 0 errors on Thu Dec 25 02:01:33 2025
Significado: El scrub no encontró ni reparó nada, con cero errores. Esto es lo más cercano al cierre definitivo.
Decisión: Cerrar el incidente/cambio. Si se encontraron errores, seguir investigando; algo sigue mal.
Preguntas frecuentes (FAQ)
1) ¿Siempre debo poner offline un disco antes de extraerlo?
Sí, cuando el disco aún está presente y controlas el momento. Ponerlo offline reduce errores I/O sorpresa y convierte la extracción en un cambio intencional. Si el disco ya desapareció, poner offline no ayudará, pero tampoco lo arreglará mágicamente.
2) ¿Cuál es la diferencia entre “resilver” y “scrub”?
Resilver reconstruye datos en un dispositivo de reemplazo para restaurar la redundancia. Scrub verifica los checksums de todo el pool y repara usando la redundancia cuando es posible. Resilver es recuperación dirigida; scrub es auditoría de todo el pool.
3) ¿Puedo reemplazar múltiples discos fallidos a la vez?
Puedes, pero normalmente no deberías. De uno en uno mantienes el sistema en un estado conocido y evitas cruzar límites de redundancia por accidente. La excepción es cuando tienes spares preadjuntados en algunos diseños, o cuando una falla del backplane obliga múltiples cambios—ahí operas en modo incidente con aceptación explícita del riesgo.
4) ¿Debo usar rutas /dev/sdX en zpool replace?
No. Usa /dev/disk/by-id/... (o el equivalente estable en tu SO). /dev/sdX es un detalle de implementación que cambia entre reboots, rescans y a veces solo porque el kernel quiso.
5) Mi disco nuevo es “el mismo modelo” pero ligeramente más pequeño. ¿Por qué?
Porque los proveedores revisan firmware, usan diferentes platos o reservan distintas cantidades de espacio. ZFS es estricto: el reemplazo debe ser igual o mayor. Mantén algunos repuestos “conocidos buenos y suficientemente grandes” en lugar de confiar en la capacidad de marketing.
6) ¿Por qué la velocidad de resilver difiere tanto de una copia simple disco a disco?
ZFS no copia bloques crudos desde una sola fuente. Reconstruye desde redundancia, lee a través de miembros del vdev, valida checksums y compite con cargas activas. Además, pools fragmentados tienden a resilverar más lento porque metadata y bloques están dispersos.
7) Tras el reemplazo, ¿puedo simplemente ejecutar zpool clear para resetear errores?
Puedes limpiar después de haber arreglado la causa subyacente y querer vigilar recurrencias. No uses clear como sustituto de la investigación. Los contadores de error son evidencia, y la evidencia es útil.
8) ¿Necesito particionar discos para ZFS?
Depende de tus convenciones de plataforma y requisitos de arranque. Muchas instalaciones Linux usan discos enteros; otras usan particiones por alineamiento o herramientas. Operativamente, la consistencia importa más que la ideología: no mezcles enfoques a la ligera y asegura que los reemplazos coincidan con el esquema existente.
9) ¿Qué hay de los hot spares—debería usarlos?
Los hot spares pueden reducir el tiempo hasta el resilver, lo cual reduce riesgo. Pero también pueden ocultar problemas de higiene operativa (aún debes reemplazar físicamente el disco fallido) y pueden consumirse por modos de fallo equivocados (como un expander defectuoso que cause múltiples “fallos”). Úsalos, pero no dejes que reemplacen monitoreo y disciplina.
10) ¿Es aceptable RAIDZ1 si reemplazo discos rápidamente?
A veces, para datos de bajo valor y pools pequeños. En producción, RAIDZ1 más discos grandes más cargas reales es una decisión de riesgo, no un truco técnico. El reemplazo de discos es exactamente cuando descubres cuánto te arrepientes de esa decisión.
Cierre: pasos prácticos siguientes
Si quieres menos incidentes de reemplazo de discos ZFS—y menos mañanas de “¿por qué sigue enojado el pool?”—haz del flujo seguro tu predeterminado:
- Estandariza en nombres de dispositivo persistentes en la configuración del pool y en los runbooks.
- Requerir confirmación por serial antes de cualquier extracción física. Verificación por dos personas si los datos importan.
- Poner offline intencionalmente, reemplazar con
zpool replace, y monitorizar el resilver como si fuera una migración en vivo—porque básicamente lo es. - Cuando el resilver sea lento, diagnostica transporte y discos hermanos primero. ZFS suele estar reportando síntomas, no alucinando problemas.
- Termina con un scrub cuando el incidente tuvo cualquier olor a inestabilidad. Es la pista de auditoría que tu yo futuro agradecerá.
Haz esto consistentemente y los reemplazos de discos serán lo que deben ser: mantenimiento, no teatro.