La alerta llega a las 09:12: “DEGRADED pool.” Cambias el disco, ejecutas zpool replace y esperas un par de horas de actividad.
Entonces zpool status te muestra “resilvering… 3%” y una ETA que parece un fin de semana largo.
El tiempo de resilver no es una falta moral. Es física, profundidad de cola, geometría de vdev y la incómoda realidad de que las cargas de producción no se detienen porque tú lo prefieras.
La clave es saber qué palancas son seguras, cuáles son rituales y cuáles intercambian velocidad hoy por pérdida de datos mañana.
Qué hace realmente el resilver (y por qué parece más lento de lo «esperado»)
En ZFS, un “resilver” es la reconstrucción tras reemplazar un dispositivo o cuando vuelve a estar en línea. ZFS recorre los metadatos del pool para descubrir qué bloques están realmente en uso,
luego regenera las copias/paridad faltantes y las escribe en el dispositivo nuevo (o retornado).
Esa parte de “recorrer los metadatos” es por qué el resilver a menudo no es una simple copia lineal de “bytes usados”. Es una cadena de dependencias:
ZFS debe leer metadatos para saber dónde están los bloques de datos, luego leer esos bloques y escribir los bloques reconstruidos, mientras además mantiene la consistencia con escrituras en curso.
Si tu pool está fragmentado, lleno de metadatos o bajo carga, el resilver se convierte en un festival de búsquedas y colas.
Además, el resilver no es solo una gran lectura y escritura en streaming. Es “encontrar todos los bloques referenciados y reparar el lado que falta”, lo que en RAIDZ significa leer suficientes
columnas para reconstruir la paridad, y en mirrors significa copiar los bloques del otro lado. Los mirrors pueden ser rápidos si pueden leer secuencialmente. RAIDZ muchas veces no.
Otra realidad operativa: ZFS intenta comportarse de forma responsable. Por defecto no apartará tu carga de servicio para hacer el trabajo sin miramientos.
El resilver compite por I/O con todo lo demás, y ZFS deja intencionalmente margen—a menos que le indiques lo contrario.
Por qué un resilver tarda días: los cuellos de botella reales
1) I/O aleatorio y fragmentación: tus «bytes usados» no son contiguos
Si tu pool ha estado funcionando años con cargas mixtas—imágenes de VM, bases de datos, archivos pequeños, eliminaciones, snapshots—los bloques se dispersan.
ZFS debe seguir punteros de metadatos, lo que se convierte en muchas lecturas pequeñas. A los HDDs no les gusta eso. Incluso los SSD pueden sufrir si saturas con desajustes de profundidad de cola
o sufres amplificación de escritura.
La mentira que nos contamos es: “Hay solo 12 TB usados; debería resilver en 12 TB / rendimiento del disco.” Eso asume lecturas y escrituras secuenciales, bajo overhead de metadatos
y sin contención. En realidad, el throughput efectivo del resilver a menudo está limitado por IOPS, no por MB/s.
2) Geometría del vdev: RAIDZ lee más de lo que piensas
En un mirror, para reconstruir un lado faltante normalmente puedes leer el disco sano y escribir el nuevo. En RAIDZ, para reconstruir un disco faltante,
ZFS lee las columnas restantes de cada stripe. Eso implica más I/O por byte reconstruido, y se dispersa entre más spindles.
El resilver en RAIDZ puede ser especialmente castigador en vdevs anchos con discos grandes. El pool está degradado, así que la redundancia se reduce, y el rendimiento cae justo cuando más lo necesitas.
Si tienes mala suerte, también estarás sirviendo lecturas de producción con menos columnas disponibles. Es como reconstruir un puente mientras aún es hora pico.
3) “Se están asignando mientras se hace el resilver”: los bloques se mueven bajo tus pies
ZFS es copy-on-write. Las escrituras nuevas van a nuevas ubicaciones; los bloques antiguos siguen referenciados hasta que se liberen. Durante un resilver, las escrituras activas pueden cambiar lo que necesita copiarse:
actualizaciones de metadatos, bloques indirectos, nuevos punteros de bloque. ZFS maneja esto, pero significa que la operación es menos de “pasada única” de lo que la gente asume.
4) Uso del pool: por encima de ~80% la cosa se pone fea rápido
Los pools llenos se fragmentan más, asignan en fragmentos más pequeños y obligan a ZFS a trabajar más para encontrar espacio. El resilver se vuelve más aleatorio y el overhead aumenta.
Si además tienes muchas snapshots, el espacio liberado no está realmente libre hasta que las snapshots expiren, así que “df dice 20% libre” puede ser ficción.
5) Recordsize, volblocksize y cargas con bloques pequeños
El resilver debe lidiar con los tamaños de bloque tal como están en disco. Un zvol de VM con volblocksize de 8K o un dataset de base de datos con recordsize de 16K
resulta en muchos más bloques a recorrer que un dataset lleno de registros de 1M.
Más bloques significa más metadatos, más checksums, más operaciones de I/O y menos probabilidad de patrones secuenciales agradables. No lo notas en el día a día
hasta que necesitas reconstruir.
6) Compresión y dedup: geniales hasta que reconstruyes
La compresión suele ayudar al resilver porque hay menos bytes que leer y escribir—si la CPU no es el cuello de botella.
La deduplicación es lo opuesto: añade búsquedas de metadatos y a menudo hace todo más aleatorio.
Si activaste dedup porque una vez viste una diapositiva sobre “eficiencia de almacenamiento”, te has impuesto una tasa de resilver. Se complica bajo presión.
7) Checksumming, cifrado y cuellos de botella de CPU
ZFS verifica checksums al leer. Si usas cifrado nativo, también descifra. En CPUs antiguas o máquinas ocupadas, el resilver puede volverse limitado por CPU,
especialmente cuando el patrón de I/O son muchos bloques pequeños (más operaciones de checksum por byte).
8) “Prioridad del resilver” es un intercambio, no un almuerzo gratis
A menudo puedes acelerar el resilver permitiéndole consumir más I/O. Eso acelera la recuperación pero puede aplastar la latencia para tus aplicaciones.
La aceleración segura es la que mantiene tus SLOs intactos.
9) Discos de reemplazo lentos o incompatibles
Si el disco nuevo es SMR, tiene recolección de basura interna agresiva, está conectado a través de un HBA débil o simplemente es más lento que el anterior,
el tiempo de resilver puede explotar. “Misma capacidad” no es “mismo comportamiento.”
Broma #1: Resilver es el equivalente al repintar la casa mientras sigues viviendo en ella—todo es técnicamente posible, simplemente no es agradable.
Hechos e historia interesantes (porque el pasado explica el dolor)
- ZFS se inició en Sun Microsystems a mediados de los 2000 como respuesta a sistemas de archivos que trataban “gestor de volúmenes” y “sistema de archivos” como problemas separados.
- Copy-on-write fue una apuesta deliberada: hizo que los snapshots fueran baratos y la consistencia fuerte, pero también complicó los patrones de asignación con el tiempo.
- Resilver no es scrub: scrub valida todo el pool; resilver reconstruye la redundancia tras la pérdida de un dispositivo. Comparten rutas de código pero tienen intenciones distintas.
- Existe espacio de «slop» por una razón: ZFS reserva algo de espacio no asignable para evitar fragmentación catastrófica y fallos de asignación en pools casi llenos.
- Históricamente la expansión de RAIDZ fue limitada (crecer un vdev RAIDZ añadiendo discos), lo que llevó a muchos a crear vdevs anchos desde el inicio—genial el día uno, tenso en el día 900.
- Los discos SMR cambiaron el juego: pueden parecer bien en benchmarks y luego hundirse bajo escrituras aleatorias sostenidas como el tráfico de resilver.
- OpenZFS se convirtió en el centro de gravedad tras Sun, con múltiples plataformas (illumos, FreeBSD, Linux) llevando la antorcha y divergiendo en tunables.
- Mejoras para resilver secuencial aparecieron con el tiempo para acelerar ciertos patrones, pero no pueden deshacer la fragmentación ni arreglar el “pool al 92%” como elección de vida.
Guía de diagnóstico rápido: encuentra el cuello de botella en 10 minutos
Cuando el resilver está lento, no adivines. Toma tres medidas: qué ZFS piensa que está haciendo, qué están haciendo los discos y qué hacen la CPU y la memoria.
Luego decide si acelerar el resilver o reducir la carga de producción—o ambas cosas.
Primero: confirma que la reconstrucción es real y mira su forma
- Revisa
zpool statuspara tasa de escaneo, errores y si es resilver o scrub. - Confirma qué vdev está afectado y si eres RAIDZ o mirror.
- Mira el progreso tipo “resilvered X in Y”; si avanza apenas, probablemente estás limitado por IOPS o bloqueado por errores/reintentos.
Segundo: identifica el recurso limitante (IOPS, ancho de banda, CPU o contención)
- Disco ocupado pero bajo throughput: I/O aleatorio / colas / SMR / reintentos.
- CPU alta en hilos del kernel/ZFS: checksum/cifrado/trabajo intensivo en metadatos.
- Picos de latencia en apps: resilver compitiendo con I/O de producción; ajusta prioridades o planifica reducción de carga.
Tercero: decide la intervención segura
- Si la producción está tranquila, aumenta la agresividad del resilver ligeramente y vigila la latencia.
- Si la producción sufre, baja el impacto del resilver y acepta una reconstrucción más larga—a menos que el riesgo dicte otra cosa.
- Si un dispositivo está reportando errores, deja de “tunear” y empieza el triage de hardware primero.
Tareas prácticas: comandos, salidas y decisiones (12+)
Estas son las comprobaciones que realmente ejecuto. Cada una incluye lo que significa la salida y la decisión que tomas a partir de ella.
Los comandos se muestran como si estuvieras en una máquina Linux con OpenZFS; adapta rutas si estás en illumos/FreeBSD.
Task 1: Confirmar estado del escaneo, velocidad y si estás resilvering o scrubbing
cr0x@server:~$ zpool status -v tank
pool: tank
state: DEGRADED
status: One or more devices is being resilvered.
action: Wait for the resilver to complete.
scan: resilver in progress since Mon Dec 23 09:12:11 2025
1.87T scanned at 58.3M/s, 612G issued at 19.1M/s, 22.4T total
102G resilvered, 2.91% done, 5 days 03:18:22 to go
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
raidz2-0 DEGRADED 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
sdg ONLINE 0 0 0
sdh ONLINE 0 0 0
sdi ONLINE 0 0 0
sdj ONLINE 0 0 0
sdk ONLINE 0 0 0
sdl ONLINE 0 0 0
sdm ONLINE 0 0 0
sdn ONLINE 0 0 0
sdo ONLINE 0 0 0
sdp ONLINE 0 0 0
sdq ONLINE 0 0 0
sdr ONLINE 0 0 0
sds ONLINE 0 0 0
sdt ONLINE 0 0 0
sdu ONLINE 0 0 0
sdv ONLINE 0 0 0
sdx ONLINE 0 0 0
sdy ONLINE 0 0 0
sdz ONLINE 0 0 0
sdaa ONLINE 0 0 0
sdab ONLINE 0 0 0
sdac ONLINE 0 0 0
sdad ONLINE 0 0 0
sdae ONLINE 0 0 0
sdaf ONLINE 0 0 0
sdag ONLINE 0 0 0
sdah ONLINE 0 0 0
sdai ONLINE 0 0 0
sdaj ONLINE 0 0 0
sdak ONLINE 0 0 0
sdal ONLINE 0 0 0
sdam ONLINE 0 0 0
sdan ONLINE 0 0 0
sdao ONLINE 0 0 0
sdap ONLINE 0 0 0
sdaq ONLINE 0 0 0
sdar ONLINE 0 0 0
sdas ONLINE 0 0 0
sdat ONLINE 0 0 0
sdau ONLINE 0 0 0
sdav ONLINE 0 0 0
sdaw ONLINE 0 0 0
sdax ONLINE 0 0 0
sday ONLINE 0 0 0
sdaz ONLINE 0 0 0
sdba ONLINE 0 0 0
sdbb ONLINE 0 0 0
sdbc ONLINE 0 0 0
sdbd ONLINE 0 0 0
sdbe ONLINE 0 0 0
sdbf ONLINE 0 0 0
sdbg ONLINE 0 0 0
sdbh ONLINE 0 0 0
sdbi ONLINE 0 0 0
sdbj ONLINE 0 0 0
sdbk ONLINE 0 0 0
sdbl ONLINE 0 0 0
sdbm ONLINE 0 0 0
sdbn ONLINE 0 0 0
sdbo ONLINE 0 0 0
sdbp ONLINE 0 0 0
sdbq ONLINE 0 0 0
sdbr ONLINE 0 0 0
sdbs ONLINE 0 0 0
sdbt ONLINE 0 0 0
sdbu ONLINE 0 0 0
sdbv ONLINE 0 0 0
sdbw ONLINE 0 0 0
sdbx ONLINE 0 0 0
sdby ONLINE 0 0 0
sdbz ONLINE 0 0 0
sdcA ONLINE 0 0 0
sdcB ONLINE 0 0 0
sdcC ONLINE 0 0 0
sdcD ONLINE 0 0 0
sdcE ONLINE 0 0 0
sdcF ONLINE 0 0 0
sdcG ONLINE 0 0 0
sdcH ONLINE 0 0 0
sdcI ONLINE 0 0 0
sdcJ ONLINE 0 0 0
sdcK ONLINE 0 0 0
sdcL ONLINE 0 0 0
sdcM ONLINE 0 0 0
sdcN ONLINE 0 0 0
sdcO ONLINE 0 0 0
sdcP ONLINE 0 0 0
sdcQ ONLINE 0 0 0
sdcR ONLINE 0 0 0
sdcS ONLINE 0 0 0
sdcT ONLINE 0 0 0
sdcU ONLINE 0 0 0
sdcV ONLINE 0 0 0
sdcW ONLINE 0 0 0
sdcX ONLINE 0 0 0
sdcY ONLINE 0 0 0
sdcZ ONLINE 0 0 0
sdd0 ONLINE 0 0 0
errors: No known data errors
Qué significa: “scanned” vs “issued” te dice recorrido de metadatos frente a I/O real de reconstrucción.
Si “issued” es mucho menor que “scanned”, estás pasando tiempo recorriendo metadatos y/o siendo limitado por IOPS.
Decisión: Si la ETA son días y tu pool es grande, no entres en pánico todavía. Pasa a las comprobaciones de cuello de botella abajo antes de tocar tunables.
Task 2: Revisar salud del pool y tendencias de errores (no ajustes alrededor de hardware moribundo)
cr0x@server:~$ zpool status -x
pool 'tank' is degraded
Qué significa: El pool no está sano; el resilver es esperado. Si ves errores adicionales (READ/WRITE/CKSUM), eso es más urgente.
Decisión: Si los errores aumentan durante el resilver, deja de hacer “trabajo de rendimiento” y comienza el “triage de hardware.”
Task 3: Confirmar qué disco es el nuevo y si negociado correctamente (velocidad de enlace, tamaño)
cr0x@server:~$ lsblk -o NAME,SIZE,MODEL,SERIAL,ROTA,TYPE /dev/sdx
NAME SIZE MODEL SERIAL ROTA TYPE
sdx 14.6T ST16000NM000J ZR12ABCDEF 1 disk
Qué significa: Quieres que el reemplazo coincida en capacidad esperada y sea un modelo CMR empresarial, no un disco SMR de sobremesa sorpresa.
Decisión: Si el modelo/serial parece incorrecto, detén y valida la adquisición. La «solución» más barata es devolver el disco equivocado antes de que te haga perder la semana.
Task 4: Detectar comportamiento SMR o estancamientos profundos de escritura con iostat
cr0x@server:~$ iostat -x 2 5 /dev/sdx
Linux 6.6.0 (server) 12/25/2025 _x86_64_ (32 CPU)
Device r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sdx 12.0 180.0 1.1 9.4 116.0 27.8 145.2 8.1 154.8 2.9 56.8
sdx 11.5 190.5 1.0 2.2 36.2 64.1 336.7 9.2 356.8 2.7 52.4
Qué significa: El aumento de await con wMB/s colapsando es comportamiento clásico de “el disco se está bloqueando”.
No siempre es SMR, pero a menudo es “el firmware del disco está reorganizando escrituras” o tienes un problema de transporte/HBA.
Decisión: Si el dispositivo de reemplazo tiene await patológico, muévelo a otra bahía/cable/puerto HBA o cambia el modelo del disco.
Task 5: Ver si el resilver está limitado por IOPS a través del vdev
cr0x@server:~$ iostat -x 2 3
Device r/s w/s rMB/s wMB/s avgqu-sz await %util
sda 85.0 22.0 5.1 1.2 9.2 86.4 92.0
sdb 82.0 25.0 4.9 1.4 8.7 84.9 90.1
sdc 83.0 23.0 5.0 1.3 9.1 85.7 91.5
Qué significa: %util alta con MB/s bajos significa que no estás haciendo streaming; estás buscando. Por eso la matemática “disco de 14TB a 250MB/s” falla.
Decisión: No subas a tope los knobs de “resilver speed” esperando milagros. Necesitas reducir la presión de I/O aleatorio (pausar cargas pesadas, reducir churn de snapshots),
o aceptar la línea temporal.
Task 6: Revisar presión de ARC y si la máquina está thrashing
cr0x@server:~$ arcstat 2 5
time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
09:23:01 914 202 22 46 23 156 77 0 0 96G 112G
09:23:03 901 229 25 51 22 178 78 0 0 96G 112G
09:23:05 938 301 32 90 29 211 70 0 0 96G 112G
Qué significa: El aumento de misses durante el resilver puede indicar que los metadatos no caben bien, o que la combinación de producción + resilver supera la utilidad de la caché.
Decisión: Si el ARC está constreñido y hay swapping, detente: la presión de memoria destruirá el resilver y todo lo demás. Añade RAM o reduce la carga.
Task 7: Confirmar que no estás intercambiando (swap) (el swap convierte la reconstrucción en un desastre en cámara lenta)
cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
3 0 0 82432 12644 9812448 0 0 4920 1280 4200 6100 18 12 58 12 0
2 0 0 80120 12644 9812016 0 0 5100 1320 4302 6230 17 11 57 15 0
Qué significa: si/so deberían ser cero. Si estás haciendo swap, los recorridos de metadatos de ZFS y el trabajo de checksums se arrastrarán.
Decisión: Si hay swapping, reduce el cap de ARC, detén procesos que consumen memoria o mueve cargas. No “simplemente dejes que termine.”
Task 8: Comprobar si hay un scrub concurrente (y detenerlo si no es crítico por política)
cr0x@server:~$ zpool status tank | sed -n '1,20p'
pool: tank
state: DEGRADED
scan: scrub in progress since Mon Dec 23 08:55:02 2025
3.11T scanned at 72.5M/s, 901G issued at 21.0M/s, 22.4T total
0B repaired, 4.03% done, 2 days 22:10:05 to go
Qué significa: Un scrub compitiendo con un resilver suele ser autoboicot, salvo que tengas una razón concreta.
Decisión: Si el pool ya está degradado y estás intentando restaurar redundancia, prioriza el resilver y pausa el scrub.
cr0x@server:~$ sudo zpool scrub -s tank
scrub stopped
Task 9: Verificar autotrim y supuestos de ashift (aquí se esconden cliff de rendimiento)
cr0x@server:~$ zdb -C tank | egrep -i 'ashift|autotrim'
ashift: 12
autotrim: off
Qué significa: ashift define la alineación de sectores. Un ashift incorrecto puede mermar permanentemente el rendimiento de escritura.
autotrim importa sobre todo para pools de SSD.
Decisión: No puedes cambiar ashift en sitio. Si está mal, planifica una migración. No finjas que un tunable arreglará la geometría.
Task 10: Comprobar propiedades a nivel de dataset que amplifican el trabajo de resilver
cr0x@server:~$ zfs get -o name,property,value -s local recordsize,compression,dedup,atime tank/vmstore
NAME PROPERTY VALUE
tank/vmstore recordsize 128K
tank/vmstore compression lz4
tank/vmstore dedup off
tank/vmstore atime off
Qué significa: Recordsize pequeño, dedup=on y atime=on (para datasets ocupados) pueden aumentar el churn de metadatos y el trabajo de reconstrucción.
Decisión: No cambies esto a mitad de un resilver como “truco de velocidad”. Úsalo como entrada para diseño futuro y para acotar qué cargas debes limitar.
Task 11: Identificar si vdev especial o dispositivos de metadatos son el cuello de botella
cr0x@server:~$ zpool status tank | sed -n '1,120p'
pool: tank
state: DEGRADED
scan: resilver in progress since Mon Dec 23 09:12:11 2025
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
raidz2-0 DEGRADED 0 0 0
sda ONLINE 0 0 0
...
special
mirror-1 ONLINE 0 0 0
nvme0n1 ONLINE 0 0 0
nvme1n1 ONLINE 0 0 0
Qué significa: Si tienes un vdev especial (metadatos/bloques pequeños), su rendimiento puede dominar la velocidad de resilver porque el resilver es muy dependiente de metadatos.
Decisión: Vigila la latencia y salud de NVMe; un vdev de datos “bien” aún puede resilver lentamente si los dispositivos de metadatos están saturados o degradados.
Task 12: Buscar errores de I/O y reintentos en logs del kernel (asesino silencioso)
cr0x@server:~$ sudo dmesg -T | egrep -i 'ata[0-9]|scsi|reset|I/O error|blk_update_request' | tail -n 12
[Tue Dec 23 10:02:14 2025] sd 3:0:8:0: [sdx] tag#83 I/O error, dev sdx, sector 1883742336 op 0x1:(WRITE) flags 0x0 phys_seg 16 prio class 0
[Tue Dec 23 10:02:15 2025] ata9: hard resetting link
[Tue Dec 23 10:02:20 2025] ata9: SATA link up 1.5 Gbps (SStatus 113 SControl 310)
Qué significa: Reset de enlaces y negociación de enlace degradada (1.5 Gbps) estirarán el resilver hasta tiempos geológicos.
Decisión: Arregla el cableado/backplane/HBA. No ajustes ZFS para compensar un transporte inestable.
Task 13: Ver si ZFS está limitando el resilver por tunables (y ajustar con cuidado)
cr0x@server:~$ sudo sysctl -a 2>/dev/null | egrep 'zfs_vdev_resilver|zfs_resilver|scan_idle'
debug.zfs_scan_idle=50
debug.zfs_vdev_resilver_max_active=2
debug.zfs_vdev_resilver_min_active=1
Qué significa: Estos knobs influyen en cuán agresivamente ZFS emite I/O para resilver y cuánto se detiene para favorecer producción.
Los nombres varían por plataforma/distribución; no copies valores de blogs sin pensar.
Decisión: Si tienes margen de I/O y latencia aceptable, aumenta max_active modestamente. Si la latencia ya es mala, no lo hagas.
Task 14: Verificar que el pool no esté peligrosamente lleno (los pools llenos se reconstruyen lentamente y fallan creativamente)
cr0x@server:~$ zfs list -o name,used,avail,refer,mountpoint -p tank | head
NAME USED AVAIL REFER MOUNTPOINT
tank 19854735163392 2533274798080 1048576 /tank
Qué significa: Aproximadamente 19.8 TB usados, 2.5 TB disponibles. En un pool de ~22 TB, eso roza la zona de peligro.
Decisión: Si estás por encima de ~80–85% y el resilver es lento, prioriza liberar espacio (borrar snapshots antiguos, mover datos fríos) antes de tunear por velocidad.
Formas seguras de acelerar el resilver (qué funciona, qué no)
El objetivo no es “hacer el resilver rápido.” El objetivo es “restaurar redundancia rápidamente sin destrozar la producción o corromper datos.”
No son lo mismo. Siempre puedes hacer las cosas rápido haciendo lo incorrecto.
1) Reducir I/O competidor (la medida poco sexy con mayor apalancamiento)
Si el resilver está limitado por IOPS, la jugada ganadora es dejar de generar I/O aleatorio. Normalmente eso significa:
- Pausar jobs por lotes: backups, reindexados de logs, analítica, grandes rsyncs.
- Limitar o migrar inquilinos ruidosos (los clusters de VM son famosos por esto).
- Aplazar la poda de snapshots que provoque muchas liberaciones/reescrituras (depende de implementación y carga).
Esto suele ser políticamente difícil. No debería serlo. Un pool degradado es un evento de riesgo. Trátalo como tal.
2) Aumentar la agresividad del resilver—con cuidado y con plan de reversión
Tunables de ZFS que controlan la concurrencia de scan/resilver pueden aumentar el throughput. También pueden incrementar la latencia y provocar timeouts en apps sensibles.
Ajusta en pequeños pasos, mide y revierte si el dolor supera la ganancia.
cr0x@server:~$ sudo sysctl -w debug.zfs_scan_idle=0
debug.zfs_scan_idle = 0
Qué significa: Menos tiempo idle significa que el trabajo de scan cede menos a I/O normal. El resilver obtiene más turnos.
Decisión: Usa esto solo cuando toleres mayor latencia y monitoriza los SLOs de las aplicaciones inmediatamente. Si la latencia sube, vuelve a ponerlo.
cr0x@server:~$ sudo sysctl -w debug.zfs_vdev_resilver_max_active=4
debug.zfs_vdev_resilver_max_active = 4
Qué significa: Más operaciones I/O concurrentes por vdev. Bueno para sistemas infrautilizados, malo para spindles ya saturados.
Decisión: Si los discos muestran baja %util y baja profundidad de cola, esto puede ayudar. Si ya están al máximo, principalmente aumentará latencia.
3) Poner el reemplazo en la mejor ruta (HBA, firmware, cableado)
La verdad aburrida: la velocidad de resilver a menudo está limitada por un enlace que se comporta mal. Un solo disco a 1.5 Gbps SATA, o un puerto HBA que hace flapping,
puede arrastrar un resilver RAIDZ porque la reconstrucción de paridad espera a los más lentos.
Arregla la capa física. Luego afina.
4) Preferir mirrors cuando el tiempo de rebuild importa más que la capacidad
Si diseñas sistemas donde el tiempo de rebuild tras una falla es un riesgo central, los mirrors son tus aliados. Resilverean copiando bloques asignados del lado sano.
En muchas implementaciones reales, los mirrors también ofrecen rendimiento más predecible bajo fallas parciales.
RAIDZ está bien—a veces es excelente—pero no finjas que es “lo mismo pero más barato.” Durante el resilver es otra bestia.
5) Mantener los pools menos llenos (tu yo futuro te lo agradecerá)
La forma más fácil de acelerar el resilver es evitar la fragmentación patológica. El predictor más fiable de fragmentación en ZFS es:
qué tan cerca del máximo mantienes el pool.
Establece cuotas. Hazlas cumplir. Ten un plan de capacidad. “Lo limpiaremos después” es cómo obtienes resilvers de 5 días y reuniones a las 2 a.m.
6) Usar tamaños de bloque sensatos para la carga (antes del incidente, no durante)
Para almacenes de VM, elige volblocksize con intención. Para datasets, selecciona recordsize alineado con la carga. Esto no es microoptimizar benchmarks;
es reducir metadatos y conteo de bloques para que el trabajo de reconstrucción escale de forma sensata.
7) No “optimices” desactivando checksums ni confiando en magia
Los checksums no son cinturones de seguridad opcionales. El resilver es exactamente cuando quieres integridad extremo a extremo.
ZFS no te ofrece un camino soportado y sensato para “saltar la verificación por velocidad”, y eso es una característica, no una limitación.
Broma #2: Girar knobs durante un resilver sin medir es como añadir más café para arreglar una impresora rota—satisfactorio emocionalmente, irrelevante técnicamente.
Una cita para mantener en tu puente de incidentes
“La esperanza no es una estrategia.” — idea parafraseada comúnmente citada en ingeniería y operaciones
La versión operativa: mide primero, cambia una cosa, mide de nuevo. Cualquier otra cosa es cosplay de rendimiento.
Tres microhistorias corporativas desde el frente
Microhistoria 1: El incidente provocado por una suposición errónea
Una empresa SaaS mediana ejecutaba un cluster de VM respaldado por ZFS sobre un vdev RAIDZ2 ancho. Había funcionado “bien” durante años. Un disco falló un martes.
El on-call lo cambió rápido y lanzó el replace. Todo el mundo se relajó.
La suposición: “El resilver solo copia datos usados, así que será más rápido que una reconstrucción completa.” El pool tenía alrededor del 60% usado.
Hicieron la clásica cuenta en una servilleta usando throughput secuencial y decidieron que el resilver terminaría esa noche.
La noche pasó y el progreso se estancó en un dígito porcentual. La latencia de las VMs de clientes subió intermitentemente y el hypervisor empezó a registrar timeouts de I/O de invitados.
El equipo reaccionó añadiendo más carga—específicamente, migrando VMs para “balancear”. Esa migración generó lecturas y escrituras aleatorias. Echó gasolina al fuego.
El problema real: el pool era viejo, con muchas snapshots y muy fragmentado. El resilver estaba limitado por IOPS, no por ancho de banda. Cada mitigación de “mover rápido” empeoró el patrón de I/O.
Tras 36 horas, un segundo disco arrojó errores. Ya no era un rebuild lento; era un incidente de riesgo de datos.
Se recuperaron, pero la lección quedó: el tiempo de resilver no es función solo de “TB usados”. Es función de historial de asignación, forma de la carga y contención.
Sus acciones de postmortem fueron simples e incómodas: imponer margen de capacidad, limitar cantidad de snapshots y dejar de diseñar vdevs anchos para clusters de VM sensibles a latencia.
Microhistoria 2: La optimización que salió mal
Otra organización decidió que los resilvers tardaban demasiado. Alguien encontró tunables online y configuró concurrencia de scan/resilver agresivamente en toda la flota.
Parecía genial en un entorno de staging tranquilo: las reconstrucciones fueron más rápidas. Todos celebraron. El cambio se desplegó.
Entonces en producción hubo una falla real. Un disco se cayó durante horas punta. El resilver se aceleró como un motor a reacción: mucha I/O concurrente, mínimo idling.
La velocidad de rebuild mejoró, claro. Mientras tanto, la latencia de la base de datos pasó de “bien” a “por qué todo está haciendo timeout”.
Lo peor no fue la latencia. Fueron los reintentos. Las apps empezaron a reintentar peticiones fallidas, lo que aumentó la carga, lo que aumentó I/O, lo que aumentó la latencia.
El sistema entró en una espiral familiar: cuanto más luchaba, más se esforzaba.
El equipo revirtió los tunables durante el incidente. El rebuild se ralentizó, pero la plataforma se estabilizó.
Conclusión del postmortem: “resilver más rápido” no es un valor por defecto global. Es un interruptor en modo incidente, ligado a horas de negocio y SLOs, con monitorización y reversión explícita.
Microhistoria 3: La práctica aburrida pero correcta que salvó el día
Una empresa de servicios financieros (sí, del tipo que ama el control de cambios) ejecutaba vdevs mirror para datasets críticos y RAIDZ para capas frías.
También aplicaban una política simple: los pools se mantienen bajo un umbral de llenado definido, y la retención de snapshots se limita con poda regular.
Un disco falló durante el cierre trimestral. Por supuesto que pasó. El on-call lo reemplazó y comenzó el resilver. No tocaron tunables al principio.
En su lugar, ejecutaron el runbook: pausar jobs por lotes no esenciales, verificar que no haya scrub concurrente, chequear velocidad de enlace, revisar dmesg por resets y vigilar dashboards de latencia.
El resilver terminó en una ventana predecible. Sin drama. Sin segunda falla. Sin ajustes heroicos.
La parte favorita del equipo fue lo poco que tuvieron que explicar a gestión—porque no pasó nada visible para el cliente.
El trabajo “aburrido” se hizo meses antes: margen de capacidad, diseño sensato de vdev y disciplina operativa.
Esa es la historia de fiabilidad que nadie cuenta en conferencias porque no cabe en una camiseta. Aun así, es la que quieres.
Errores comunes: síntoma → causa raíz → arreglo
1) Síntoma: La tasa de resilver empieza decente y luego colapsa
Causa raíz: Estancamiento interno de escritura del disco de reemplazo (a menudo SMR o GC de firmware), o renegociación de enlace, o el pool alcanzó regiones más fragmentadas.
Arreglo: Revisa iostat -x por aumento de await y colapso de MB/s; revisa dmesg por resets/velocidad de enlace. Cambia puerto/cable/HBA o reemplaza el modelo del disco.
2) Síntoma: “Scanned” crece rápido, “issued” es tiny
Causa raíz: Recorrido intensivo en metadatos con poca reconstrucción real, a menudo por fragmentación y muchas snapshots; a veces por ajustes de throttling.
Arreglo: Reduce churn de metadatos competidor (pausa snapshotting, actividad intensa del filesystem). Considera bajar temporalmente scan_idle si el presupuesto de latencia lo permite.
3) Síntoma: Apps hacen timeout durante el resilver aunque el throughput no sea alto
Causa raíz: Pico de latencia cola larga por contención de I/O aleatorio; unas pocas colas saturadas mientras el throughput medio parece modesto.
Arreglo: Vigila await, profundidad de cola y latencia p99 a nivel app. Reduce carga o aumenta el idle del resilver para dar prioridad a producción.
4) Síntoma: Resilver nunca termina; el progreso avanza a paso de tortuga y luego “reinicia”
Causa raíz: Dispositivo hace flapping, desconexiones transitorias o errores repetidos que fuerzan reintentos; a veces backplane marginal.
Arreglo: Revisa contadores de error en zpool status; inspecciona dmesg. Arregla hardware. Ningún tunable compensa un cable que te odia.
5) Síntoma: CPU al máximo durante el resilver en un “sistema I/O”
Causa raíz: Trabajo de checksums/cifrado en muchos bloques pequeños, más overhead de metadatos. Puede amplificarse por dedup.
Arreglo: Confirma con top/vmstat y estadísticas ARC; reduce churn de bloques pequeños (pausa migraciones de VM) y planifica upgrades de CPU para pools cifrados.
6) Síntoma: Resilver lento solo en un pool, no en otros del mismo hardware
Causa raíz: Llenado del pool, fragmentación, elección de tamaños de bloque de dataset, recuento de snapshots o diferencias en ancho de vdev.
Arreglo: Compara uso con zfs list, recuento de snapshots y propiedades de datasets. El hardware no está “lento”; tu historial de asignación lo está.
7) Síntoma: La velocidad de reconstrucción mejoró tras “tunear”, luego el pool se pone raro
Causa raíz: Cambios persistentes en sysctl/tunables aplicados globalmente sin guardarraíles; mayor presión de I/O causa timeouts y fallas secundarias.
Arreglo: Haz que los tunables sean con ámbito de incidente y con reversión explícita. Captura valores baseline y revierte tras la salud del pool.
Listas de verificación / plan paso a paso
Paso a paso: cuando un disco falla y comienza el resilver
- Confirmar estado:
zpool status. Asegura que es un resilver, no un scrub, e identifica el vdev afectado. - Detener mantenimiento competidor: Si hay un scrub en ejecución, deténlo salvo que la política lo requiera ahora mismo.
- Sanidad del hardware: Confirma modelo del disco de reemplazo (CMR vs SMR), velocidad de enlace y ausencia de resets en
dmesg. - Medir contención:
iostat -xy dashboards de latencia de apps. Decide si tienes margen para presionar más el resilver. - Revisar presión de memoria:
vmstaty estadísticas ARC. Asegura que no hay swapping. - Decidir prioridad: Si el riesgo es alto (segundo disco inestable, datos críticos), prioriza resilver. Si son horas de negocio, prioriza SLOs.
- Aplicar tunables con cuidado (opcional): Aumenta la agresividad del resilver en incrementos pequeños, monitorizando p95/p99.
- Comunicar: Fija expectativas. “Degradado hasta X” es una declaración de riesgo de negocio, no una curiosidad técnica.
- Tras la finalización: Verifica que el pool esté sano y luego revierte los tunables temporales. Programa un scrub después de restaurar redundancia.
Lista: aceleraciones seguras que puedes justificar en un postmortem
- Pausar I/O por lotes no esenciales y trabajos con heavy snapshot.
- Detener scrubs concurrentes mientras corre un resilver (a menos que cumplimiento lo exija).
- Arreglar problemas de transporte (resets, negociaciones SATA degradadas) antes de tunear.
- Aumentar concurrencia de resilver modestamente solo cuando los discos tienen margen y la latencia de apps está estable.
- Reducir temporalmente el idle del scan solo durante una ventana de incidente controlada.
- Preferir mirrors para capas donde el riesgo de rebuild domina la eficiencia de capacidad.
- Mantener margen de capacidad como política, no sugerencia.
Lista: cosas que no deberías hacer durante un resilver
- No habilites dedup “para ahorrar espacio” a mitad del incidente.
- No inicies grandes migraciones, reequilibrios o reescrituras masivas a menos que intentes conscientemente intercambiar tiempo de resilver por un riesgo mayor.
- No sigas subiendo tunables cuando la latencia ya es mala; solo estás haciendo que la falla sea más ruidosa.
- No ignores logs del kernel. Si ves resets o errores de I/O, estás en terreno de hardware ahora.
Preguntas frecuentes
1) ¿Se supone que el resilver debe ser más rápido que un scrub?
A menudo sí—porque el resilver solo toca bloques asignados que necesitan reconstrucción. Pero la fragmentación y el recorrido de metadatos pueden borrar esa ventaja.
Si el pool es viejo y con I/O aleatorio intenso, el resilver puede sentirse como un scrub con pasos extra.
2) ¿Por qué “scanned” no coincide con “resilvered”?
“Scanned” refleja cuánto ha recorrido el proceso de scan los punteros de bloque y metadatos del pool.
“Resilvered” es la data reconstruida y escrita al reemplazo. Mucho scanning con poco resilvered suele significar trabajo intensivo en metadatos o límites por throttling/IOPS.
3) ¿El resilver de ZFS copia solo el espacio usado?
ZFS intenta resilver solo bloques asignados (referenciados), no todo el dispositivo crudo. Por eso el espacio libre no siempre cuesta tiempo.
Pero “bloques asignados” aún pueden estar dispersos en millones de pequeñas extenciones, lo que hace la operación lenta.
4) ¿Puedo pausar y reanudar un resilver?
Dependiendo de la plataforma y versión, puede que puedas detener un scan y luego reanudar, pero el comportamiento varía y puede reiniciar porciones de trabajo.
Operativamente: trata “pausa” como “retraso con riesgo”, no como un checkpoint limpio.
5) ¿Debo ejecutar un scrub inmediatamente después de reemplazar un disco?
Normalmente: resilver primero, scrub después. Mientras está degradado, quieres restaurar la redundancia lo más rápido posible.
Tras completar el resilver y restaurar la salud del pool, un scrub es un buen paso para validar integridad—planéalo en baja carga.
6) ¿Cuál es la forma más segura de acortar el tiempo de resilver?
Reducir I/O competidor y mantener pools menos llenos. Los tunables ayudan en los márgenes; carga y fragmentación determinan la línea base.
La aceleración “más segura” es quitar presión del pool para que el resilver use IOPS sin dañar producción.
7) ¿Los mirrors siempre son mejores que RAIDZ para resilver?
No siempre, pero los mirrors típicamente resilverean de forma más predecible y con menos amplificación por lectura de paridad.
RAIDZ puede ser eficiente y fiable, pero el comportamiento de rebuild bajo fallo es más complejo, especialmente en vdevs anchos y pools ocupados.
8) ¿Por qué reemplazar un disco por un modelo “mismo tamaño” hizo el resilver más lento?
Igual capacidad no es igual rendimiento. Puede que hayas introducido comportamiento SMR, tasas sostenidas de escritura peores, firmware que rinde mal bajo escrituras aleatorias, o un enlace negociado a menor velocidad.
Verifica el modelo y revisa errores de transporte.
9) ¿La compresión hace el resilver más rápido o más lento?
Usualmente más rápido en sistemas limitados por I/O porque se mueven menos bytes. Puede ser más lento si la CPU se convierte en cuello de botella, especialmente con cifrado y bloques pequeños.
Mide CPU durante el resilver; no supongas.
10) Si el resilver es lento, ¿están mis datos en riesgo?
Un pool degradado tiene redundancia reducida, así que el riesgo es mayor hasta que termine el resilver. Un resilver lento extiende la ventana de exposición.
Por eso la reacción correcta no es solo “esperar”; es “reducir carga, arreglar problemas de hardware y restaurar redundancia rápidamente.”
Próximos pasos que puedes hacer hoy
Si estás en medio de un resilver dolorosamente lento, haz esto en orden:
- Ejecuta
zpool statusy confirma que no estás accidentalmente haciendo scrub mientras estás degradado. - Revisa
dmesgpor resets de enlace y errores de I/O; arregla problemas físicos antes de tocar los knobs de ZFS. - Usa
iostat -xpara decidir si estás limitado por IOPS o por ancho de banda. - Reduce I/O competidor: pausa backups, migraciones, jobs por lotes y cualquier churn intenso de snapshots.
- Si el presupuesto de latencia lo permite, ajusta modestamente la agresividad del resilver y monitoriza p95/p99; revierte después de que el pool esté sano.
Si actualmente no estás degradado, mejor aún. Usa esa calma para comprar velocidad futura: mantén margen, evita SMR sorpresa, elige geometría de vdev intencionadamente
y trata el tiempo de resilver como una restricción de diseño de primera clase—no como una reflexión que descubres cuando el disco muere.