No se nota un problema de ashift cuando un pool es nuevo. Todo está vacío, los benchmarks parecen correctos y la vida va bien.
Luego el pool se llena, la latencia aumenta, los scrubs tardan una eternidad y de repente tu arreglo de SSD “rápido” rinde como si estuviera devolviendo resultados desde un sótano.
La parte fea: no puedes “arreglar” un ashift incorrecto en el lugar. La detección es el trabajo. Tomar la decisión es el trabajo.
Esta guía trata sobre cómo revisar pools existentes, demostrar si tienes un desajuste y elegir la salida menos dolorosa.
Qué es realmente ashift (y qué no es)
ashift es la unidad de asignación en disco de ZFS, expresada como potencia de dos.
Si ashift=12, ZFS asigna en 212 bytes: 4096 bytes (4K).
Si ashift=9, son 512 bytes.
Eso no es lo mismo que los tamaños de sector “lógico” y “físico” reportados por el disco, pero está relacionado.
ZFS escogerá un ashift en el momento de crear el vdev según lo que crea que es el tamaño mínimo de sector del dispositivo.
Una vez establecido, es efectivamente permanente para ese vdev. Puedes reemplazar discos, expandir, resilverizar—ashift se mantiene.
Aquí tienes la traducción operacional:
- Ashift demasiado pequeño (por ejemplo, 512B en sectores físicos de 4K) causa read-modify-write, amplificación de escritura, picos de latencia y scrubs/resilvers que parecen malditos.
- Ashift demasiado grande (por ejemplo, 8K o 16K en dispositivos de 4K) desperdicia algo de espacio y puede aumentar la sobrecarga para bloques muy pequeños, pero normalmente no genera el mismo perfil de “todo está en llamas”.
Lo que ashift no es:
- No es lo mismo que
recordsizeovolblocksize. Esos son tamaños lógicos de nivel superior usados por filesystems y zvols. - No es un parámetro que puedas “ajustar más tarde” sin reconstruir. Si un artículo te dice lo contrario, te está vendiendo esperanza.
Una cosa más: ashift es por vdev, no por pool en sentido estricto. Los pools contienen vdevs. Los vdevs contienen discos.
La mayoría de los pools se crean con un ashift consistente en todos los vdevs, pero existen pools con ashift mixtos—a menudo durante expansiones o cuando alguien añadió “solo un vdev más” de otra época.
Hechos interesantes y breve historia
Los problemas de almacenamiento se repiten porque los fabricantes cambian las reglas mientras mantienen los nombres de marketing. Algunos hechos ayudan a enmarcar por qué existe ashift:
- Los sectores de 512 bytes fueron la larga norma. Décadas de software asumieron bloques de 512B. ZFS nació en ese mundo.
- “Advanced Format” (sectores físicos de 4K) se volvió común a principios de los 2010. Muchos discos presentaban 512B lógicos por compatibilidad mientras escribían físicamente en 4K.
- Algunos dispositivos mienten. Puentes USB-SATA, ciertos controladores RAID y algunos discos virtuales históricamente han reportado 512B aun cuando el backend es 4K.
- ZFS fijó
ashiftal crear el vdev porque el formato en disco importa. ZFS se preocupa por consistencia y verificabilidad; cambiar la granularidad de asignación después sería una migración de formato, no una “tuneada”. - Las primeras herramientas de OpenZFS no siempre dejaban el ashift obvio. Podías crear un pool y solo descubrir el desajuste cuando el rendimiento se desplomaba a escala.
- Los bloques de borrado de SSD y las páginas NAND son mucho mayores que 4K. Incluso con ashift correcto, las capas internas de flash pueden crear amplificación de escritura—un ashift errado lo empeora.
- Existe 4Kn (sectores lógicos nativos de 4K). Algunos discos empresariales reportan 4096 lógicos y físicos. Suelen comportarse mejor, sobre todo porque son más difíciles de detectar mal.
- Algunos hipervisores “normalizan” tamaños de bloque. Tu guest podría ver 512B mientras el datastore usa 4K o más. ZFS dentro del guest tomará decisiones basadas en el tamaño visible para el guest.
Por qué duele un desajuste de ashift (modos de fallo)
El desajuste clásico es ashift=9 en discos con sectores físicos de 4K. ZFS escribe bloques alineados a 512B, pero la unidad solo puede actualizar fragmentos de 4K.
Entonces una “escritura pequeña” se convierte en:
- Leer el sector físico de 4K que contiene la región de 512B.
- Modificar la porción de 512B en memoria.
- Escribir de vuelta el sector completo de 4K.
Ese ciclo read-modify-write infla la latencia y convierte tus IOPS en una broma práctica.
Formas comunes en que aparece en producción:
- El tiempo de scrub/resilver explota porque el sistema hace más operaciones IO por cantidad lógica de datos.
- Las cargas de escritura aleatoria sufren (bases de datos, imágenes de VM, trabajos de archivos pequeños, compilaciones con muchas metadata).
- El uso de CPU puede subir porque la ruta IO hace más trabajo, las interacciones con compresión/dedup se vuelven más ruidosas y la latencia aumenta el cambio de contexto.
- La amplificación de escritura afecta la resistencia de los SSD—no siempre de forma catastrófica, pero lo suficiente como para convertir “cómodo dentro de la garantía” en “vamos a cambiar discos más de lo planeado”.
“Pero mi pool parece estar bien.” Claro. Un desajuste puede estar enmascarado por:
- Escrituras mayormente secuenciales
- Muchas aciertos en ARC
- Utilización del pool muy baja
- Cargas dominadas por bloques grandes (medios grandes, backups)
Luego agregas VMs, habilitas escrituras sync, llegas al 70% de ocupación o empiezas muchas actualizaciones de metadata. El desajuste deja de ser teórico.
Una cita operacional (idea parafraseada): El mantra de fiabilidad de Gene Kranz—“failures are not an option”—se traduce bien: planea como si el desajuste fuera real hasta que pruebes que no lo es.
Broma #1: Si el almacenamiento pudiera hablar, diría “no estoy lento, solo me estoy expresando”. Luego le haría timeout a tu base de datos.
Guion de diagnóstico rápido
Quieres el camino más corto desde “esto se siente lento” hasta “esto es ashift, o no lo es”. Aquí está el orden que ahorra más tiempo.
Primero: confirma ashift en cada vdev de nivel superior
- Si ashift es correcto y consistente, deja de culparlo y sigue adelante.
- Si ashift es demasiado pequeño (9 en hardware 4K), considérelo sospechoso nº1.
- Si ashift está mezclado entre vdevs, espera rendimiento desigual y latencias largas impredecibles.
Segundo: confirma lo que el OS cree que son los discos (lógico/físico)
- Revisa tamaños de sector con
lsblkyblockdev. - Atento a dispositivos “512/4096”. Ahí nacen los errores de ashift.
- No confíes en puentes USB o HBAs RAID que virtualizan sectores sin avisar.
Tercero: busca firmas obvias de rendimiento
zpool iostat -vpara escrituras pequeñas y alta latencia a nivel vdeviostat -xparaawaitalto y bajo throughput pese a alta utilizaciónzpool status -vpara errores o progreso lento de resilver/scrub (no es prueba, pero sí un olfato)
Cuarto: valida el comportamiento de alineación con una prueba de escritura controlada
- Usa un dataset de prueba o un host de ensayo si puedes.
- Ejecuta una prueba de escritura aleatoria de bloques pequeños y observa latencia/IOPS. Un pool con ashift desajustado a menudo “cae en picado” con cargas de 4K aprox.
Quinto: decide tu camino
- Ashift correcto: céntrate en
recordsize, ajustes sync, SLOG, vdevs especiales, fragmentación y llenado del pool. - Ashift incorrecto: deja de tunear en torno a ello. Planea migración o reconstrucción.
Tareas prácticas: comandos, salidas, decisiones
Abajo hay comprobaciones reales que puedes ejecutar hoy. Cada tarea tiene: el comando, qué significa la salida y la decisión que debes tomar.
Úsalas como una lista de verificación, no como adivinación.
Task 1: Listar pools y confirmar que miras el correcto
cr0x@server:~$ zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 21.8T 17.2T 4.60T - - 32% 78% 1.00x ONLINE -
Significado: Tienes un pool, tank, 78% lleno y moderadamente fragmentado. La ocupación y la fragmentación pueden agravar problemas de ashift.
Decisión: Si el pool está >80% lleno, trata cualquier problema de rendimiento como multifactorial. Aún así verifica ashift, pero no te detengas ahí.
Task 2: Obtener el layout de vdevs (lo necesitas para comprobaciones por vdev)
cr0x@server:~$ zpool status -P tank
pool: tank
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
/dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3C ONLINE 0 0 0
/dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3D ONLINE 0 0 0
/dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3E ONLINE 0 0 0
/dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3F ONLINE 0 0 0
/dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3G ONLINE 0 0 0
/dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3H ONLINE 0 0 0
errors: No known data errors
Significado: Un vdev RAIDZ2 con seis discos.
Decisión: Comprobarás ashift para este vdev y confirmarás que todos los dispositivos subyacentes tienen características de sector coincidentes.
Task 3: Comprobar ashift via zdb (el método más directo y menos optimista)
cr0x@server:~$ sudo zdb -C tank | sed -n '/vdev_tree/,/features_for_read/p'
vdev_tree:
type: 'root'
id: 0
guid: 12345678901234567890
children[0]:
type: 'raidz'
id: 0
guid: 11111111111111111111
nparity: 2
ashift: 12
children[0]:
type: 'disk'
id: 0
guid: 22222222222222222222
path: '/dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3C'
children[1]:
type: 'disk'
id: 1
guid: 33333333333333333333
path: '/dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3D'
Significado: ashift: 12 significa asignaciones de 4K. Eso suele ser correcto para HDD/SSD modernos.
Decisión: Si ves ashift: 9 en algún vdev construido sobre discos físicos 4K, márcalo para planificar migración.
Task 4: Detectar ashift mixto entre vdevs (las expansiones son donde sucede)
cr0x@server:~$ sudo zdb -C tank | grep -E 'children\[[0-9]+\]:|ashift'
children[0]:
ashift: 12
children[1]:
ashift: 9
Significado: Tienes al menos dos vdevs de nivel superior con diferentes valores de ashift. Eso es un impuesto en rendimiento y predictibilidad.
Decisión: Trata el ashift más pequeño como el probable causante. Planea retirar ese vdev (vía migración) o reconstruir el pool.
Task 5: Comprobar qué reporta el OS sobre tamaños lógico/físico
cr0x@server:~$ lsblk -d -o NAME,MODEL,SIZE,ROTA,LOG-SEC,PHY-SEC /dev/sd[a-f]
NAME MODEL SIZE ROTA LOG-SEC PHY-SEC
sda ST12000NM0008 10.9T 1 512 4096
sdb ST12000NM0008 10.9T 1 512 4096
sdc ST12000NM0008 10.9T 1 512 4096
sdd ST12000NM0008 10.9T 1 512 4096
sde ST12000NM0008 10.9T 1 512 4096
sdf ST12000NM0008 10.9T 1 512 4096
Significado: Estos son discos 512e: 512 lógico, 4096 físico. Si tu vdev ashift es 9, estás desalineado para IO físico.
Decisión: Con 512e, por defecto usa ashift=12 para nuevos vdevs. Para vdevs existentes con ashift=9, planifica una migración en lugar de “tunearlo”.
Task 6: Confirmar tamaños de sector con blockdev (ayuda a detectar reportes extraños)
cr0x@server:~$ sudo blockdev --getss /dev/sda
512
cr0x@server:~$ sudo blockdev --getpbsz /dev/sda
4096
Significado: El kernel ve sector lógico 512B, físico 4096B. Consistente con la vista de lsblk.
Decisión: Si las herramientas discrepan (p. ej., 512/512 pero sabes que es 4K), trata la capa de dispositivo como poco fiable y asume que necesitas ashift=12 como mínimo.
Task 7: Comprobar comportamiento IO del pool durante carga real
cr0x@server:~$ zpool iostat -v tank 1 5
capacity operations bandwidth
pool alloc free read write read write
-------------------------- ----- ----- ----- ----- ----- -----
tank 17.2T 4.60T 210 980 54.3M 22.1M
raidz2-0 17.2T 4.60T 210 980 54.3M 22.1M
ata-ST12000NM...B3C - - 35 165 9.10M 3.80M
ata-ST12000NM...B3D - - 35 165 9.05M 3.75M
ata-ST12000NM...B3E - - 35 165 9.07M 3.78M
ata-ST12000NM...B3F - - 35 165 9.02M 3.76M
ata-ST12000NM...B3G - - 35 160 9.03M 3.70M
ata-ST12000NM...B3H - - 35 160 9.06M 3.72M
-------------------------- ----- ----- ----- ----- ----- -----
Significado: Estadísticas balanceadas por disco sugieren que el vdev se comporta normalmente. Esto no prueba corrección de ashift, pero descarta un disco lento obvio.
Decisión: Si las escrituras por disco son altas mientras el ancho de banda es bajo, sospecha escrituras pequeñas y amplificación—desajuste de ashift es un candidato, junto a cargas sync y fragmentación.
Task 8: Correlacionar con latencia a nivel de dispositivo usando iostat
cr0x@server:~$ iostat -x 1 3
Linux 6.6.0 (server) 12/26/2025 _x86_64_ (32 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
6.12 0.00 3.41 8.55 0.00 81.92
Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %util await r_await w_await
sda 35.0 160.0 9320.0 3860.0 0.0 2.0 92.0 27.4 9.2 31.1
sdb 35.0 160.0 9300.0 3840.0 0.0 1.0 91.5 26.9 9.0 30.6
Significado: Alta utilización y await elevado en escrituras puede ser normal bajo carga para RAIDZ en HDD, pero si ves await extremo con throughput mínimo, algo falla.
Decisión: Si empujas escrituras pequeñas y ves await alto, verifica ashift y también la ruta de escrituras sync (SLOG), propiedades de datasets y patrones de carga.
Task 9: Validar expectativas de volblocksize/recordsize (no las confundas con ashift)
cr0x@server:~$ zfs get -o name,property,value,source recordsize,compression tank
NAME PROPERTY VALUE SOURCE
tank recordsize 128K default
tank compression lz4 local
Significado: recordsize es 128K. Es típico para filesystems de propósito general. No cambia ashift, pero afecta patrones de IO.
Decisión: Si tu pool aloja VMs/bases de datos, puedes ajustar recordsize/volblocksize. Pero si ashift es incorrecto, ajustar esto es maquillaje en una grúa.
Task 10: Comprobar tamaño de bloque de zvol (común en stacks de virtualización)
cr0x@server:~$ zfs get -o name,property,value,source volblocksize tank/vmdata
NAME PROPERTY VALUE SOURCE
tank/vmdata volblocksize 8K local
Significado: zvol usa bloques de 8K. Si ashift es 9 en dispositivos físicos 4K, 8K puede seguir estando desalineado de formas sutiles durante escrituras parciales.
Decisión: Mantén volblocksize alineado a la carga (a menudo 8K–16K para VMs/DBs), pero prioriza corregir el desajuste de ashift primero si existe.
Task 11: Comprobar 4Kn vs 512e vs “dispositivos misterio” usando IDs de udev
cr0x@server:~$ for d in /dev/disk/by-id/ata-ST12000NM0008-*; do echo "== $d =="; udevadm info --query=property --name="$d" | grep -E 'ID_MODEL=|ID_SERIAL=|ID_BUS='; done
== /dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3C ==
ID_BUS=ata
ID_MODEL=ST12000NM0008-1JH101
ID_SERIAL=ST12000NM0008-1JH101_ZA1A2B3C
Significado: Los discos son dispositivos ATA directos, no están detrás de USB. Bien: menos mentiras sobre sectores.
Decisión: Si ves USB o capas de transporte inusuales para pools de producción, asume que el reporte de sectores es sospechoso y sé conservador (ashift=12 o 13 para nuevos pools).
Task 12: Confirmar que ZFS usa rutas nativas y no nombres de dispositivo obsoletos
cr0x@server:~$ zpool status -P tank | grep /dev/sd
Significado: No hay rutas /dev/sdX en la salida de configuración (bueno). Usar rutas by-id reduce errores operativos durante reemplazos de disco.
Decisión: Si tu pool usa /dev/sdX, corrígelo en la próxima ventana de mantenimiento (export/import con by-id) antes de hacer algo riesgoso como migraciones.
Task 13: Comprobar ashift por hoja (útil cuando el output de vdev_tree es largo)
cr0x@server:~$ sudo zdb -l /dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3C | grep -i ashift
ashift: 12
Significado: La etiqueta de dispositivo leaf indica ashift 12 para el vdev al que pertenece. Es una comprobación rápida si no quieres todo el volcado de configuración.
Decisión: Si la etiqueta muestra ashift: 9 y el sector físico del dispositivo es 4096, has confirmado un desajuste. Empieza a planificar la reconstrucción/migración.
Task 14: Medir una firma de escritura sync de bloques pequeños (no adivines)
cr0x@server:~$ sudo zfs create -o sync=always -o recordsize=16K tank/ashift-test
cr0x@server:~$ dd if=/dev/zero of=/tank/ashift-test/blob bs=4K count=250000 oflag=dsync status=progress
1024000000 bytes (1.0 GB, 954 MiB) copied, 54 s, 19.0 MB/s
cr0x@server:~$ sync
Significado: Esta prueba tosca fuerza comportamiento sync. Bloques de 4K más sync pueden exponer problemas de alineación y latencia rápidamente.
Decisión: Si el throughput se desploma y la latencia sube cuando tu hardware debería rendir mejor, investiga desajuste de ashift y también la historia SLOG/PLP. No “optimices” hasta saber qué cuello de botella tienes.
Tres microhistorias corporativas (qué falló, qué nos salvó)
Microhistoria 1: El incidente causado por una suposición errónea
Un equipo heredó una plataforma de VM respaldada por ZFS que había sido “estable durante años”. También se había construido en una época en la que la mitad de los discos en la cadena de suministro eran 512e,
y la mitad de las herramientas seguían tratando el tamaño de sector como trivia.
El on-call empezó a recibir alertas: latencia de IO de VM en picos, profundidad de colas de almacenamiento en aumento y timeouts periódicos de aplicaciones.
La primera suposición del equipo—una suposición extremadamente corporativa—fue que “la nueva carga es más ruidosa”, porque había llegado una nueva plataforma de microservicios.
Controlaron a los tenants, tocaron algunos knobs del scheduler de IO y movieron unas VMs. Los síntomas se movieron, pero el problema no.
Luego corrió un scrub. Llegó a horario laboral, como siempre, y se volvió más lento cada mes. Esta vez desencadenó una cascada:
la latencia subió, los timeouts aumentaron, empezaron tormentas de reintentos y el sistema de monitorización los llamó más fuerte.
La causa raíz real fue dolorosamente aburrida: un vdev de nivel superior tenía ashift=9 desde la creación original del pool,
mientras que los discos debajo eran físicos de 4K. “Había funcionado” cuando el pool estaba mayormente vacío y la carga mayormente secuencial.
Años después, se convirtió en un impuesto sobre cada escritura aleatoria y actualización de metadata.
La solución no fue ingeniosa. Fue cara: construir un pool nuevo con ashift=12, migrar datasets, rotar tenants y dar de baja los vdevs viejos.
La lección quedó porque dolió: no asumas que tus predecesores eligieron el ashift correcto, aunque el sistema sea viejo y “esté bien”.
Microhistoria 2: La optimización que salió mal
Otra organización decidió “estandarizar el rendimiento” creando pools nuevos con un ashift mayor porque “bloques más grandes son más rápidos”.
Alguien escogió ashift=13 (8K) para todo, incluidos volúmenes de bases de datos de IO pequeño y cargas CI con mucha metadata.
Al principio se veía bien. Las escrituras secuenciales grandes iban sanas y las gráficas de espacio no parecían horribles.
Luego notaron que algunas cargas intensivas en zvol se volvieron raras: las actualizaciones pequeñas producían más churn backend de lo esperado, los snapshots crecían más rápido de lo anticipado,
y el equipo empezó a quejarse del “overhead de ZFS”.
Lo que salió mal no fue que ashift=13 sea siempre erróneo. Fue que lo aplicaron universalmente sin emparejarlo con el dispositivo y la carga.
En SSDs con sectores 4K, la asignación de 8K aumentó la amplificación interna para ciertos patrones y desperdició espacio para bloques pequeños y metadata.
También empeoraron trade-offs de compresión/dedup en casos extremos forzando un tamaño de asignación mínimo mayor.
El plan de recuperación fue otra vez poco glamuroso: mantener ashift=13 solo donde tenía sentido (algunos arreglos y casos especiales),
y volver a ashift=12 como valor por defecto. Documentaron la decisión y requirieron justificación para desviaciones.
La “estandarización de rendimiento” se volvió una práctica estándar: no elegir ashift por sensaciones.
Broma #2: Nada dice “optimización empresarial” como empeorar las cosas de forma estandarizada.
Microhistoria 3: La práctica aburrida pero correcta que salvó el día
Un entorno regulado usaba ZFS para archivos de logs y backups de VM. Nada emocionante. El equipo tenía una lista de cambios que incluía:
registrar tamaños de sector de dispositivos, anotar el ashift previsto y almacenar la salida de zdb -C en el momento de crear el pool.
Era tan aburrido que los ingenieros se quejaban—en voz baja, como profesionales.
Años después, una renovación de almacenamiento introdujo nuevo firmware de HBA y una remesa de discos nueva. Se planificó una expansión del pool:
añadir otro vdev RAIDZ. Durante las comprobaciones previas, el ingeniero comparó el reporte de sectores de los discos nuevos contra los antiguos.
La nueva ruta (a través de otro enclosure) reportó 512 lógico y 512 físico, a pesar de que el modelo de disco era conocido por ser físico 4K.
Porque el equipo tenía los artefactos aburridos de builds previos, detectaron la inconsistencia antes de añadir el vdev.
Movieron los discos a otro slot de enclosure, obtuvieron reporte correcto 512/4096 y procedieron con ashift=12.
No hubo pool con ashift mixto, ni precipicio de rendimiento latente, ni scrubs “misteriosos”.
La victoria no fue solo evitar un error; fue evitar un error a cámara lenta que habría surgido meses después, cuando nadie recordara el cambio.
La documentación no los hizo más rápidos. Los hizo menos sorprendidos. Ese es el punto.
Errores comunes: síntomas → causa raíz → solución
Esta sección es deliberadamente específica. “Revisa tu hardware” no es una solución; es postergación con mejor postura.
1) Los scrubs son dolorosamente lentos, pero los discos parecen saludables
- Síntomas: El progreso del scrub avanza a paso de tortuga;
zpool statusno muestra errores; IO parece ocupado pero el throughput decepciona. - Causa raíz:
ashift=9en discos físicos 4K causando IO extra (visible especialmente en metadata y bloques pequeños). - Solución: Confirma con
zdb -C. Si está desajustado, planifica migración/reconstrucción del pool conashift=12. No intentes “tunear” la velocidad del scrub alrededor de un ashift erróneo.
2) Las escrituras aleatorias son terribles; lo secuencial parece bien
- Síntomas: Las cargas de VM se quejan; la latencia de fsync en bases de datos es alta; las escrituras de backup se ven ok.
- Causa raíz: Escrituras pequeñas desalineadas; a menudo desajuste de ashift, a veces cargas sync sin SLOG apropiado, y a veces ambos.
- Solución: Verifica ashift y tamaños de sector primero. Si ashift es correcto, evalúa ajustes sync y SLOG (y protección contra pérdida de energía si usas SSD).
3) Un vdev “se siente más lento” después de una expansión
- Síntomas: Tras añadir un vdev, la distribución de latencias empeora; el rendimiento se vuelve inconsistente en tiempo y cargas.
- Causa raíz: Ashift mixto entre vdevs o un vdev nuevo detrás de una capa de dispositivo que reporta tamaños de sector distintos.
- Solución: Revisa
zdb -Cpara cada vdev de nivel superior. Si hay mezcla, considera migrar datasets calientes fuera del vdev lento o reconstruir.
4) Reemplazaste discos y esperabas que ashift cambiara
- Síntomas: “Cambiamos a discos 4Kn; ¿por qué zdb aún muestra ashift=9?”
- Causa raíz: Ashift se fija al crear el vdev y no cambia con los reemplazos/resilvering.
- Solución: Reconstruir/migrar a un nuevo vdev/pool creado con el ashift deseado.
5) Los benchmarks no reproducen el dolor en producción
- Síntomas: fio en un pool vacío se ve bien; las cargas reales tartamudean cuando el pool está ocupado.
- Causa raíz: El benchmark no coincide en tamaño IO, semántica sync, concurrencia o llenado del pool; el desajuste de ashift amplifica especialmente IO pequeño aleatorio bajo contención.
- Solución: Benchmark con escrituras aleatorias de 4K/8K, ajustes sync realistas y múltiples jobs. Confirma ashift antes de fiarte de cualquier narrativa de benchmark.
6) Enclosures USB/JBOD producen comportamiento de rendimiento “aleatorio”
- Síntomas: Los tamaños de sector aparecen inconsistentes; la selección de ashift difiere entre discos idénticos; el rendimiento cambia tras replug/reboot.
- Causa raíz: El firmware del bridge miente o cambia las características reportadas; ZFS fija ashift según lo que vio en la creación.
- Solución: Evita puentes USB para pools ZFS serios. Si debes usarlos, fuerza ashift en la creación via
zpool create -o ashift=12y valida conzdb -Cde inmediato.
Listas de verificación / plan paso a paso
Checklist A: “¿Tengo un desajuste de ashift ahora mismo?”
- Identifica el pool y los vdevs:
zpool status -P. - Vuelca la configuración y busca ashift:
sudo zdb -C poolname. - Registra ashift por vdev de nivel superior (mirror/raidz/draid/especial).
- Comprueba tamaños de sector de cada disco leaf:
lsblk -d -o NAME,LOG-SEC,PHY-SEC. - Si cualquier vdev tiene
ashiftmenor que el tamaño de sector físico, tienes un desajuste que importa. - Si ashift está mezclado, tienes un desajuste que te pasará factura de formas desiguales.
Checklist B: “¿Es ashift realmente el cuello de botella?”
- Confirma el tamaño de IO y el comportamiento sync de la carga (VMs y bases de datos suelen significar aleatorio pequeño + patrones algo sync).
- Durante la carga, ejecuta
zpool iostat -v 1yiostat -x 1lado a lado. - Busca ops/s altos con bajo ancho de banda y alta latencia—firma clásica de amplificación por IO pequeño.
- Si ashift es correcto, verifica:
- ocupación/fragmentación del pool (
zpool listFRAG/CAP) - propiedades de datasets (sync, recordsize, volblocksize)
- presión de metadata en vdevs especiales (si se usan)
- diseño de SLOG (si cargas sync dominan)
- ocupación/fragmentación del pool (
Checklist C: “Plan de migración/reconstrucción cuando ashift está mal”
- Deja de discutir con la física. Decide reconstruir/migrar en lugar de tunear alrededor del problema.
- Proporciona almacenamiento nuevo (pool nuevo o vdevs nuevos) con
-o ashift=12explícito (o un valor mayor justificado). - Verifica el ashift nuevo inmediatamente con
sudo zdb -Cy regístralo. - Replica datasets:
zfs snapshotzfs send | zfs receive- o usa tu herramienta de replicación existente
- Corta el servicio a los workloads gradualmente; mide latencia y velocidad de scrub.
- Retira el pool/vdev antiguo solo después de que hayas:
- validado restauraciones
- validado scrub en el pool nuevo
- validado rendimiento bajo carga pico aproximada
Preguntas frecuentes
1) ¿Puedo cambiar ashift en un vdev o pool existente?
No en el lugar. Ashift está horneado en cómo se asignaron bloques en disco. La solución práctica es crear un vdev/pool nuevo con el ashift correcto y migrar los datos.
2) ¿Dónde veo confiablemente ashift de un pool existente?
Usa sudo zdb -C poolname y busca ashift: N bajo cada vdev de nivel superior en vdev_tree.
zpool get no te dirá ashift de forma fiable porque no es una propiedad del pool de la misma manera.
3) Si mis discos son 512e (512 lógico / 4096 físico), ¿qué ashift debería elegir?
Usualmente ashift=12. Eso alinea las asignaciones de ZFS a fronteras de 4K y evita read-modify-write en el disco.
4) ¿Es ashift=13 “mejor” que ashift=12?
No automáticamente. Puede tener sentido para algunos arreglos y características de flash, pero también aumenta el tamaño mínimo de asignación.
Usa 12 por defecto salvo que tengas una razón específica y hayas probado la carga.
5) Reemplacé todos los discos por 4Kn. ¿Por qué no se actualizó ashift?
Porque ashift se determina cuando se crea el vdev, no cuando se reemplazan discos. Los reemplazos heredan el ashift existente del vdev.
6) Si ashift está mal, ¿por qué ZFS no lo detectó?
ZFS usa las características reportadas por el dispositivo en el momento de creación. Si la capa de dispositivo reportó 512B (aunque fuera falso), ZFS lo creyó.
ZFS es escéptico con la corrupción, no con la honestidad del proveedor.
7) ¿Cuáles son las comprobaciones de tamaño de sector más fiables en Linux?
lsblk -o LOG-SEC,PHY-SEC y blockdev --getss/--getpbsz. Si esas herramientas discrepan o parecen sospechosas detrás de bridges/controladores, toma eso como advertencia.
8) ¿Pueden convivir vdevs con ashift mixto en un mismo pool?
Sí. Suele ocurrir después de expansiones o al añadir vdevs de hardware distinto. Puede funcionar, pero complica rendimiento y predictibilidad.
9) ¿Recordsize/volblocksize “arregla” un desajuste de ashift?
No. Influyen en patrones de IO y pueden reducir el dolor en algunos casos, pero no pueden cambiar la granularidad de asignación en disco de vdevs existentes.
10) ¿Cuál es la respuesta operativa más segura una vez confirmo ashift=9 en discos físicos 4K?
Planifica migración/reconstrucción. Mantén el pool estable, evita “tuneos heroicos” y programa un movimiento controlado a un pool creado correctamente.
Conclusión: próximos pasos que puedes tomar
Detectar desajustes de ashift no es un ejercicio académico. Es la diferencia entre “este pool es viejo pero está bien” y “este pool está robando silenciosamente nuestro presupuesto de latencia”.
Si sospechas un desajuste, no lo discutas—mídelo.
Pasos prácticos:
- Ejecuta
sudo zdb -Cy registra ashift por vdev. - Confirma tamaños de sector de disco con
lsblkyblockdev. - Si encuentras
ashift=9en dispositivos físicos 4K, deja de tunear y empieza a planear reconstrucción/migración. - Si ashift es correcto, sigue adelante rápidamente: revisa comportamiento sync, ocupación del pool, fragmentación y tamaños IO de la carga.
- Añade una práctica aburrida al futuro: captura la salida de
zdb -Cal crear el pool y guárdala con los registros de cambio.