Suele empezar igual: la latencia sube, los paneles se vuelven amarillos y entonces tu servicio “rápido” se convierte en una pieza de museo. Las sesiones SSH se congelan a mitad de comando. Una base de datos deja de responder. La CPU está aburrida, la RAM está bien, la red parece normal —y sin embargo la máquina se siente como si estuviera atrapada en cemento húmedo.
En Ubuntu 24.04, la versión más exasperante de esto es un “congelamiento” del disco bajo carga: no una falla limpia, no un crash evidente, sino una parada a nivel de todo el sistema porque la E/S de almacenamiento no se completa y los timeouts son demasiado lentos (o inexistentes en las capas que importan). La solución raramente es “comprar un disco más rápido.” Normalmente es “hacer que el sistema falle rápido, aislar el daño y evitar que un dispositivo trabado tenga secuestrado todo el host”.
Qué es realmente un “congelamiento” de disco (y por qué tu host se queda congelado)
Cuando la gente dice “el disco se colgó”, a menudo se refiere a una de tres cosas:
- Un dispositivo o ruta deja de completar E/S. El kernel espera, reintenta y espera más. Las aplicaciones quedan bloqueadas en sueño no interrumpible (
Dstate). Si suficientes hilos críticos se bloquean, el host parece congelado. - La E/S se completa, pero tan lentamente que resulta indistinguible de un bloqueo. Las profundidades de cola explotan, la latencia pasa de milisegundos a minutos, y todo lo que necesita almacenamiento queda efectivamente caído.
- Una capa de la pila de almacenamiento serializa el manejo de errores. Una ruta muerta retiene un bloqueo, una cola se atasca, un controlador entra en un bucle de reinicio y el resto del sistema se pone en cola detrás de ello.
Linux suele ser bueno evitando panic en problemas de almacenamiento. Eso es excelente para la integridad de datos. Pero puede ser terrible para la disponibilidad cuando el sistema está configurado para esperar “como por siempre” por un dispositivo que nunca volverá. Muchos entornos preferirían fallar un montaje, activar un health check o expulsar un nodo antes que dejar que un miembro de la flota se quede atascado.
Hay una razón por la que esto duele tanto: la E/S de disco es una dependencia para casi todo. Registro, estado, archivos temporales, gestores de paquetes, cachés DNS, colas de métricas, capas de contenedor —el problema de almacenamiento no solo rompe la base de datos. Rompe tu capacidad de observar la ruptura.
Una idea parafraseada a menudo atribuida a Werner Vogels (ingeniería de fiabilidad): Todo falla, así que diseña para la falla en lugar de fingir que no ocurrirá.
Los timeouts de almacenamiento son exactamente eso: decidir cómo fallas.
Dos verdades incómodas:
- Ningún ajuste de timeout único “arregla” los congelamientos. Necesitas timeouts coherentes entre capas para que la recuperación ocurra dentro de un presupuesto predecible.
- Timeouts demasiado agresivos pueden causar sus propios incidentes —especialmente en arreglos ocupados, volúmenes cloud sobrecargados o tejidos multipath inestables.
Broma #1: El almacenamiento nunca “se cae”, solo entra en una profunda meditación sobre la impermanencia de los paquetes.
Guion de diagnóstico rápido: primeras / segundas / terceras comprobaciones
Este es el “tengo 5 minutos antes de que alguien declare un incidente” rutina. El objetivo no es la causa raíz perfecta. El objetivo es identificar la capa que está atascada y decidir si conmutar, cercar o reiniciar.
Primero: confirma que es almacenamiento e identifica el dispositivo afectado
- Revisa los logs del kernel en busca de timeouts/reinicios. Si ves timeouts SCSI, reinicios de controlador NVMe o “blocked for more than … seconds”, estás en el artículo correcto.
- Lista tareas bloqueadas y acumulaciones en estado D. Si muchos hilos están en
D, casi siempre es espera de E/S en un dispositivo o en el journal/log del sistema de archivos. - Mapea montajes → dispositivos. Si
/varo un montaje de base de datos está en el dispositivo problemático, el host entero se sentirá peor que si fuera solo un montaje de datos fríos.
Segundo: determina si es dispositivo, ruta o carga de trabajo
- ¿A nivel de dispositivo? Registros SMART/NVMe, errores de medio, reinicios de enlace, reinicios de controlador.
- ¿A nivel de ruta? Caídas de sesión iSCSI, flaps de enlace FC, grupos de ruta de multipath fallando, mensajes de “no path”.
- ¿A nivel de carga? Un proceso haciendo escrituras sync masivas, atascos del journal del sistema de archivos, congestión de writeback, saturación de profundidad de cola.
Tercero: elige la mitigación menos mala
- Si una ruta está muerta y hay multipath configurado: ajusta la comprobación de rutas y los timeouts de failover para que el failover ocurra rápidamente.
- Si un dispositivo está trabado: planifica su remoción/cercado. En un host de disco único, eso suele ser reiniciar. En una pila redundante (RAID, multipath, FS cluster), normalmente puedes aislarlo.
- Si es saturación de carga: reduce concurrencia, ajusta profundidad de cola/scheduler o arregla la carga (buffering, batching, I/O asíncrono).
Hechos interesantes y contexto histórico
- Linux solía usar por defecto el planificador CFQ para equidad en discos giratorios; los kernels modernos prefieren
mq-deadlineononedebido al I/O de bloque multi-cola. - Los timeouts SCSI vienen de una era de dispositivos lentos donde esperar 30–60 segundos no era extravagante; en los servicios de hoy, eso es una eternidad.
- Las advertencias de “hung task” existen porque el sueño no interrumpible es una característica, no un bug. El kernel deliberadamente no siempre puede matar una tarea que espera E/S de forma segura.
- Multipath se diseñó para rutas defectuosas, no para pensamiento defectuoso. Puede ocultar fallos transitorios maravillosamente —hasta que los timeouts no coinciden y se atrasa más de lo que tolera tu SLA.
- NVMe cambió el modelo de fallas. Es lo bastante rápido como para que la antigua lógica de “reintentar un rato” pueda volverse catastrófica bajo presión de colas.
- La congestión de writeback es algo viejo (la VM y la capa de bloque la han discutido durante décadas), pero todavía muerde cuando las proporciones de dirty y el journaling se encuentran.
- EXT4 y XFS priorizan la integridad. Un journal/log atascado puede hacer que un montaje entero parezca muerto incluso si el resto del dispositivo “está bien”.
- El almacenamiento en la nube introdujo nuevas patologías de latencia. Throttling, vecinos ruidosos y mantenimiento en el backend pueden parecer “congelamientos aleatorios” desde el invitado.
La mecánica: timeouts por capa (bloque, SCSI, NVMe, multipath, sistemas de archivos)
Para evitar bloqueos completos, necesitas entender quién espera a quién. La pila de almacenamiento es una cadena de promesas:
- La aplicación promete que puede bloquearse en E/S.
- El sistema de archivos promete orden y recuperación (journal/log).
- La capa de bloque promete encolar y despachar E/S.
- El driver del dispositivo promete hablar con el hardware y recuperarse de errores.
- El transporte (SATA/SAS/NVMe/FC/iSCSI) promete entrega—o al menos un error.
Cuando un disco “se cuelga”, lo peor es cuando los errores no se devuelven rápidamente. En su lugar, el kernel reintenta durante mucho tiempo, el sistema de archivos espera I/O crítico y los hilos de la aplicación se acumulan. Muchos subsistemas están correctos al esperar. Tu trabajo es decidir cuánto debe durar ese “correcto”.
Timeouts de la capa de bloque (request timeouts)
La capa de bloque de Linux tiene el concepto de timeout por solicitud. Para muchos dispositivos se expone como:
/sys/block/<dev>/device/timeout(común para SCSI)/sys/class/block/<dev>/queue/parámetros (profundidad de cola, scheduler, etc.)
Si las solicitudes no se completan dentro de ese timeout, el kernel intenta abortar/resetear. Si eso ayuda depende del driver y del hardware. Si el driver sigue reiniciando para siempre, obtienes lo peor de ambos mundos: nada progresa y no hay falla limpia.
SCSI: timeouts de comandos y manejo de errores
SCSI tiene timeouts de comando explícitos (históricamente 30 segundos es común). En un disco SAS local, eso puede estar bien. En un SAN con multipath y caches grandes, puede ser demasiado corto (falsos timeouts). En una ruta inestable, puede ser demasiado largo (retrasando el failover).
El manejo de errores SCSI también puede bloquear. Si el dispositivo está en un estado malo, puedes ver intentos repetidos de reset en dmesg. La clave es alinear los timeouts SCSI con la recuperación de multipath y del transporte para que una capa se responsabilice por fallar o fallar rápido —no todas peleándose entre sí.
NVMe: timeouts de controlador y bucles de reinicio
NVMe suele ser “o vuela o está en llamas.” Cuando falla, a menudo falla por reinicio de controlador. Verás mensajes sobre timeouts y reinicios. La perilla clave es el timeout central de NVMe y el comportamiento ante pérdida de controlador (según kernel/driver). Algunos ajustes son parámetros del módulo; otros son sysfs por dispositivo.
En la práctica: si un dispositivo NVMe se traba intermitentemente, acortar timeouts puede ayudarte a recuperarte más rápido—o puede causar reinicios repetidos bajo alta carga si el dispositivo solo está lento. No ajustes esto a ciegas; mide la distribución de latencias.
Multipath: donde la “alta disponibilidad” se vuelve “alta ansiedad”
Device-mapper multipath puede salvarte o estancarte. El modo de falla más grande es el desajuste de timeouts:
- El timeout de comando SCSI es largo.
- El comprobador de rutas de multipath es lento para declarar una ruta muerta.
- El comportamiento de encolado está configurado en “queue forever” cuando no existe ruta.
Ese último es el asesino: el sistema sigue encolando E/S indefinidamente, tus apps se bloquean y el host parece muerto mientras espera educadamente por una ruta que no está devolviendo nada. En muchos entornos, quieres que el encolado pare tras un tiempo acotado para que los servicios puedan fallar y los orquestadores reprogramen.
Sistemas de archivos: los atascos de journal/log parecen colgadas de dispositivo
EXT4 usa un journal; XFS usa un log. Si las escrituras de metadatos críticas no pueden completarse, el sistema de archivos puede bloquear a los llamadores. Incluso si el dispositivo de bloque subyacente está solo “parcialmente” mal, el montaje puede sentirse totalmente atascado porque las operaciones de metadatos se serializan.
Además: los patrones de fsync() pueden hacer que tu almacenamiento parezca colgado. Un solo proceso realizando escrituras síncronas en bucle cerrado puede dominar la latencia para todos. Si alguna vez has oído “¿por qué la caja está congelada?” y la respuesta fue “alguien activó el logging síncrono en todas partes”, bienvenido al club.
Broma #2: El disco no está lento—solo está poniendo a prueba tu paciencia.
Tareas prácticas: 12+ comandos, cómo leer la salida, qué decisión tomar
Estos son comandos prácticos y seguros para producción. Úsalos para identificar el cuello de botella y para validar si el ajuste de timeouts está funcionando. Cada tarea incluye: comando, salida de ejemplo, qué significa y qué decisión tomar.
Task 1: Check for kernel I/O timeout signatures
cr0x@server:~$ sudo dmesg -T | egrep -i 'timed out|timeout|reset|I/O error|blk_update_request|hung task|blocked for more than' | tail -n 40
[Mon Dec 30 10:11:02 2025] sd 2:0:0:0: timing out command, waited 30s
[Mon Dec 30 10:11:02 2025] blk_update_request: I/O error, dev sdb, sector 12345678 op 0x1:(WRITE) flags 0x0 phys_seg 8 prio class 0
[Mon Dec 30 10:11:05 2025] scsi host2: sas: attempt task abort!
[Mon Dec 30 10:11:22 2025] INFO: task postgres:2211 blocked for more than 120 seconds.
Significado: Tienes distress real a nivel de dispositivo/driver, no solo “la BD está lenta.” La presencia de timing out command e intentos de abort/reset implica que el kernel está intentando recuperarse.
Decisión: Identifica qué dispositivo (sdb aquí), relaciónalo con un montaje/carga y decide si estás ante una falla de medio (reemplazar) o de ruta/transporte (failover/ajustar multipath).
Task 2: Identify D-state pileups quickly
cr0x@server:~$ ps -eo state,pid,comm,wchan:32 --sort=state | head -n 20
S 1 systemd ep_poll
D 2211 postgres io_schedule
D 2450 postgres xfs_log_force_lsn
D 3102 rsyslogd blk_mq_get_tag
R 4021 ps -
Significado: Múltiples procesos en estado D, esperando en funciones del kernel relacionadas con I/O. xfs_log_force_lsn es una clara señal de presión/atasco del log de XFS.
Decisión: Pivota hacia verificaciones del sistema de archivos y del dispositivo subyacente. Si los procesos bloqueados son daemons críticos (journald, rsyslog, base de datos), el host se sentirá “congelado”.
Task 3: See real-time I/O latency and queue depth with iostat
cr0x@server:~$ iostat -x 1 5
Linux 6.8.0-xx-generic (server) 12/30/2025 _x86_64_ (16 CPU)
Device r/s w/s rkB/s wkB/s await svctm %util
sda 5.0 12.0 120.0 900.0 2.1 0.3 3.0
sdb 200.0 80.0 25600.0 6400.0 1800.0 1.2 100.0
dm-2 195.0 75.0 25000.0 6000.0 1850.0 1.1 100.0
Significado: await en rango de segundos con %util al máximo significa que el dispositivo está saturado o atascado. El dispositivo dm coincide con el comportamiento del disco subyacente, sugiriendo que el cuello de botella está por debajo del sistema de archivos.
Decisión: Si el dispositivo está realmente saturado, reduce concurrencia o arregla la carga. Si está “atascado”, busca timeouts/reinicios y considera el failover/remoción.
Task 4: Map mounts to devices (find what you’re about to break)
cr0x@server:~$ lsblk -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
sda
├─sda1 ext4 1.0 2b4a... 120G 20% /
└─sda2 swap 1 9f31...
sdb
└─mpatha LVM2_member 3JkQ...
├─vg0-data xfs 8d1c... 80G 85% /var/lib/postgresql
└─vg0-log xfs 7a2b... 10G 40% /var/log
Significado: El disco problemático sdb soporta volúmenes LVM que contienen datos y logs de PostgreSQL. Eso explica el dolor a nivel de todo el sistema.
Decisión: Si el problema está en el SAN/ruta, importa ajustar multipath. Si es fallo de disco local, planifica el reemplazo. En cualquier caso, prioriza la seguridad de datos y la recuperación del servicio.
Task 5: Confirm whether you’re on multipath and inspect its behavior
cr0x@server:~$ sudo multipath -ll
mpatha (3600508b400105e210000900000490000) dm-2 LIO-ORG ,TCMU device
size=200G features='1 queue_if_no_path' hwhandler='0' wp=rw
|-+- policy='service-time 0' prio=50 status=active
| `- 2:0:0:0 sdb 8:16 active ready running
`-+- policy='service-time 0' prio=10 status=enabled
`- 3:0:0:0 sdc 8:32 active ready running
Significado: Estás encolando I/O si no existe ruta (queue_if_no_path). Si ambas rutas flaquean o desaparecen, la E/S puede estancarse indefinidamente.
Decisión: Decide si “encolar para siempre” coincide con tus objetivos de disponibilidad. Muchos clusters prefieren un encolado acotado y luego fallar.
Task 6: Check SCSI per-device timeout
cr0x@server:~$ cat /sys/block/sdb/device/timeout
30
Significado: Los comandos SCSI expiran tras 30 segundos (valor por defecto común). Eso es por comando, y el comportamiento de reintentos/reset puede extender drásticamente el tiempo total de bloqueo.
Decisión: Si necesitas un failover más rápido (multipath), puedes reducir esto—con cuidado. Si tienes un SAN lento que ocasionalmente se atasca, puede que necesites aumentarlo, pero entonces asegúrate de que otras capas no encolen para siempre.
Task 7: Inspect queue settings and scheduler (performance vs latency)
cr0x@server:~$ cat /sys/block/sdb/queue/scheduler
[mq-deadline] kyber bfq none
Significado: mq-deadline está activo. Eso suele ser un buen valor por defecto para dispositivos de bloque que se benefician de latencia acotada. Para NVMe, none también es común.
Decisión: No cambies el scheduler en medio de un incidente. Pero si estás en bfq en un dispositivo de servidor con alta concurrencia, considera cambiarlo tras pruebas.
Task 8: Check if requests are timing out at the block layer
cr0x@server:~$ sudo journalctl -k -b | egrep -i 'blk_update_request|Buffer I/O error|reset|timed out' | tail -n 30
Dec 30 10:11:02 server kernel: blk_update_request: I/O error, dev sdb, sector 12345678 op 0x1:(WRITE) flags 0x0 phys_seg 8 prio class 0
Dec 30 10:11:05 server kernel: sd 2:0:0:0: timing out command, waited 30s
Dec 30 10:11:06 server kernel: scsi host2: sas: attempt task abort!
Significado: Confirma que el kernel emite errores e incluye el dispositivo y el tipo de operación (READ/WRITE).
Decisión: Si las escrituras están fallando, los sistemas de archivos pueden remontarse como solo lectura o bloquearse; planifica el failover del servicio. Si las lecturas fallan en una configuración redundante, evalúa si está aislado a una ruta.
Task 9: Find which process is pounding the disk
cr0x@server:~$ sudo iotop -oPa
Total DISK READ: 25.00 M/s | Total DISK WRITE: 8.00 M/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
2211 be/4 postgres 18.00 M/s 4.00 M/s 0.00 % 98.00 % postgres: checkpointer
2305 be/4 postgres 6.00 M/s 2.50 M/s 0.00 % 65.00 % postgres: walwriter
Significado: La base de datos es la principal consumidora de I/O y está pasando mucho tiempo esperando E/S (IO% alto).
Decisión: Si el dispositivo está enfermo, matar el proceso no ayudará; solo moverá la espera a otro sitio. Si es sobrecarga, ajusta el checkpointing/WAL de la BD y la concurrencia del almacenamiento.
Task 10: Check NVMe error log and controller resets (if NVMe)
cr0x@server:~$ sudo nvme list
Node SN Model Namespace Usage Format FW Rev
/dev/nvme0n1 S4G8... ACME NVMe 3.2TB 1 1.20 TB / 3.20 TB 512 B + 0 B 1.2.3
cr0x@server:~$ sudo nvme smart-log /dev/nvme0
critical_warning : 0x00
temperature : 44 C
available_spare : 100%
percentage_used : 3%
media_errors : 0
num_err_log_entries : 12
cr0x@server:~$ sudo nvme error-log /dev/nvme0 | head -n 10
Entry[0]
error_count : 12
sqid : 3
cmdid : 0x0042
status_field : 0x4004
parm_err_loc : 0x0000
Significado: Existen errores (num_err_log_entries). No todos los errores NVMe son fatales, pero se correlacionan fuertemente con tormentas de reinicio y picos de latencia.
Decisión: Si los contadores de error suben durante el congelamiento, trátalo como problema de dispositivo/firmware/controlador y considera reemplazo o actualización de firmware en tu ventana de mantenimiento.
Task 11: Confirm multipathd timing and path checker events
cr0x@server:~$ sudo journalctl -u multipathd -b | tail -n 40
Dec 30 10:10:51 server multipathd[812]: sdb: tur checker reports path is down
Dec 30 10:10:55 server multipathd[812]: mpatha: remaining active paths: 1
Dec 30 10:11:15 server multipathd[812]: sdb: reinstated
Significado: Las rutas están fluctando. Si el failover/reincorporación tarda demasiado, el host se estanca mientras multipath decide cuál es la realidad.
Decisión: Ajusta los intervalos de comprobación de multipath y la política de reintento cuando no hay ruta para alinearlos con la tolerancia de pausas de tu servicio.
Task 12: Inspect filesystem health signals (XFS example)
cr0x@server:~$ sudo dmesg -T | egrep -i 'xfs|ext4|journal|metadata' | tail -n 30
[Mon Dec 30 10:11:01 2025] XFS (dm-2): log I/O error -5
[Mon Dec 30 10:11:01 2025] XFS (dm-2): metadata I/O error: block 0x12a3f error 5
Significado: El sistema de archivos está viendo errores de I/O. Esto ya no es “quizá está lento.” Está fallando.
Decisión: Detén las escrituras si es posible (failover del servicio), captura logs y planifica reparación/recuperación. No sigas golpeando un dispositivo de log que falla.
Task 13: Check writeback pressure (dirty ratios) that can mimic hangs
cr0x@server:~$ sysctl vm.dirty_background_ratio vm.dirty_ratio vm.dirty_expire_centisecs vm.dirty_writeback_centisecs
vm.dirty_background_ratio = 10
vm.dirty_ratio = 20
vm.dirty_expire_centisecs = 3000
vm.dirty_writeback_centisecs = 500
Significado: Estos son valores por defecto razonables. En cargas de ingestión muy rápidas hacia discos más lentos, los límites de dirty pueden alcanzarse y causar que hilos de usuario se bloqueen en writeback —otra apariencia de “congelamiento”.
Decisión: Si ves atascos sin errores de dispositivo y con muchas páginas dirty, ajusta esto con cuidado y arregla el buffering de la carga de trabajo.
Task 14: Measure latency distribution quickly with fio (safe mode)
cr0x@server:~$ sudo fio --name=latcheck --filename=/var/lib/postgresql/.fio-testfile --size=256M --rw=randread --bs=4k --iodepth=16 --numjobs=1 --direct=1 --time_based --runtime=20 --group_reporting
latcheck: (groupid=0, jobs=1): err= 0: pid=5123: Mon Dec 30 10:20:01 2025
read: IOPS=18.2k, BW=71.2MiB/s (74.7MB/s)(1.39GiB/20001msec)
lat (usec): min=70, max=540000, avg=880, stdev=12000
Significado: Latencia máxima de 540ms (o peor) durante lecturas aleatorias sugiere latencias finales severas. Si el máximo está en segundos/minutos, estás en territorio de congelamiento.
Decisión: Usa esto para validar mejoras tras ajustes. Si la cola de latencia sigue siendo enorme, los timeouts pueden estar ocultando un problema de dispositivo/ruta más profundo.
Ajustes de timeout que previenen bloqueos completos (qué ajustar y cómo)
Seamos francos: el ajuste más seguro para “nunca bloquearse” es “no hacer E/S nunca”. Como no podemos hacer eso, el objetivo real es:
- Detectar la falla lo suficientemente rápido como para conmutar (si es redundante) o marcar el nodo como malo (si no lo es).
- Evitar el encolado indefinido que convierte un disco/ruta mala en un bloqueo a nivel de host.
- Mantener los timeouts consistentes para que una capa no espere 5 minutos mientras otra espera 10 segundos.
1) Multipath: dejar de encolar para siempre (dolor acotado)
Si usas multipath, tu mayor palanca de disponibilidad es si la E/S se encola cuando no hay una ruta operativa.
Por qué “queue_if_no_path” es peligroso: Es fantástico para parpadeos cortos de ruta. Es catastrófico cuando una capa de red está caída, un target desaparece o hay un fallo de autenticación. Tus procesos se bloquean esperando E/S que se está encolando en el vacío.
Guía para producción:
- Para clusters con failover a nivel de nodo (Kubernetes, Pacemaker, etc.), prefiere el encolado acotado para que el nodo falle y el servicio se relocalice.
- Para sistemas de host único y no redundantes donde esperar es preferible a fallar (raro), el encolado puede ser aceptable—pero estás eligiendo conscientemente que el host se bloquee.
Ejemplo conceptual de configuración multipath (no es un enlace, solo los ajustes):
no_path_retry: cuántos reintentos cuando no hay rutas; puede ser numérico ofail.dev_loss_tmoy ajustes de transporte: cuánto tiempo el kernel mantiene un dispositivo tras perder conectividad (común en iSCSI/FC).fast_io_fail_tmo: qué tan rápido fallar I/O cuando las rutas están fallando (depende de FC/iSCSI).polling_interval: con qué frecuencia multipath verifica rutas.
En Ubuntu 24.04, multipath suele configurarse vía /etc/multipath.conf. Quieres alinear:
- Tiempo de detección de ruta (checker + polling) con
- Cuánto pueden esperar las apps (timeouts de servicio, timeouts de DB) y
- Cuánto reintenta el kernel comandos SCSI antes de declarar un dispositivo muerto.
Regla práctica: si tu orquestador matará/reemplazará un nodo en 60 segundos, no configures el almacenamiento para que se estanque 10 minutos “por si acaso.” Solo tendrás un outage en cámara lenta.
2) Timeout de dispositivo SCSI: ajústalo con cuidado (y nunca solo)
Los timeouts SCSI son por comando. El sistema puede reintentar y resetear varias veces. Reducir el timeout puede acelerar el failover, pero también puede causar resets innecesarios bajo carga transitoria.
Cuándo bajar el timeout SCSI ayuda:
- En telas multipath donde una ruta está muerta y quieres failover rápido.
- En hosts donde “congelarse por minutos” es peor que “error de I/O rápido”.
- En entornos donde el backend de almacenamiento es fiable y un timeout realmente indica fallo.
Cuándo es arriesgado reducirlo:
- SAN ocupados que ocasionalmente se atascan durante decenas de segundos por mantenimiento.
- Cargas con I/O muy grandes en medios lentos donde operaciones largas son esperadas.
- Controladores con conocido comportamiento de recuperación lento (algunos HBA RAID).
En la práctica, afinas los timeouts SCSI junto con el comportamiento de no_path de multipath y los timers de transporte. Si no, obtendrás el clásico problema: el kernel sigue reintentando mientras multipath sigue encolando.
3) Timeouts de transporte (iSCSI/FC): hacer la falla explícita
Muchos “congelamientos de disco” en volúmenes SAN son en realidad atascos del transporte. Para iSCSI, los timeouts de sesión/transporte definen qué tan rápido se detecta una sesión perdida y qué tan rápido falla la E/S hacia el SO. Para FC, existen conceptos similares vía timers de fast I/O fail y timers de pérdida de dispositivo.
Por qué importa: si el SO piensa que el dispositivo aún existe, esperará. Si declara decisivamente “el dispositivo se fue”, multipath puede hacer failover (o el sistema puede fallar) de forma limpia.
Consejo operativo: Alinea los timeouts de transporte para que sean más cortos que el presupuesto de espera de tu aplicación, pero más largos que los parpadeos transitorios esperados. Si no sabes cómo son esos parpadeos, mídelo durante un evento de mantenimiento controlado. Sí, programa uno.
4) Timeouts NVMe: evitar tormentas de reinicio
En NVMe, timeouts demasiado cortos pueden causar que un controlador se reinicie repetidamente bajo carga si las latencias de completación se disparan. Las tormentas de reinicio son un tipo especial de miseria porque la “acción de recuperación” se vuelve el incidente.
Qué hacer en lugar de acortar timeouts a ciegas:
- Mide la latencia final bajo carga realista (Task 14).
- Revisa issues de firmware y entradas de log de error (Task 10).
- Valida la estabilidad del enlace PCIe (los logs del kernel suelen mostrar errores AER cuando hay problemas).
5) Timeouts de sistema de archivos y aplicación: no finjas que el disco es inmortal
Incluso si el kernel falla la E/S rápido, tu servicio aún puede colgarse si la capa de aplicación espera para siempre (o tiene timeouts absurdamente altos). Establece timeouts razonables y comportamiento de cancelación en:
- Drivers y pools de conexión de bases de datos
- Clientes RPC
- Watchdogs de systemd (cuando proceda)
- Health checks y fencing del cluster
Filosofía correcta: las fallas de almacenamiento deben dejar al nodo enfermo de forma rápida y obvia, no lenta y fantasmagórica.
Tres microhistorias corporativas desde el campo
Incidente causado por una suposición incorrecta: “Multipath significa sin outages”
Ejecutaban un conjunto de servidores API en Ubuntu. El almacenamiento era SAN-backed, con multipath activado, y todos dormían tranquilos porque había “dos rutas”. Durante un cambio en la capa de switching entre semana, una tela empezó a perder tramas de forma intermitente.
La suposición errónea fue sutil: el equipo creía que el failover de multipath sería casi instantáneo. En realidad, su configuración encolaba la E/S cuando no había ruta y la comprobación de rutas era lenta. Cuando la “ruta buena” también fluctuó, el sistema no falló. Esperó. Indefinidamente.
Desde fuera, las APIs parecían medio vivas. Algunas peticiones colgaban. Otras tenían éxito. Los balanceadores seguían enviando tráfico porque TCP aún funcionaba y los health checks eran demasiado superficiales. En los hosts, procesos se apilaron en D-state. Reiniciar servicios no ayudó; los scripts de reinicio también necesitaban E/S de disco.
La solución no fue heroica. Cambiaron multipath para dejar de encolar para siempre, ajustaron el timing de comprobación de rutas y—esto es lo que la gente se salta—hicieron que los health checks de la aplicación incluyeran una pequeña escritura/lectura en montajes críticos. Tras eso, una verdadera caída de almacenamiento hizo que los nodos fallaran rápido, se drenaran y dejaran de confundir a todos.
Optimización que salió mal: “Subamos la profundidad de cola y iodepth”
Un sprint de tuning de rendimiento apuntó a una tubería de ingestión por lotes. El equipo incrementó la concurrencia en todas partes: más hilos workers, más conexiones DB, y mayores profundidades de I/O en sus herramientas. Los benchmarks se veían geniales con almacenamiento tranquilo.
Entonces un pico de tráfico de producción golpeó durante un evento de mantenimiento del storage backend. La latencia subió, las colas se llenaron y esas profundidades mayores se convirtieron en una denegación de servicio auto-infligida. El sistema pasó más tiempo gestionando E/S encolada que completando trabajo útil. La latencia final se disparó.
Peor aún, sus timeouts seguían por defecto. Así que en lugar de fallar rápido y reencaminar jobs, el host se quedó atascado en largos ciclos de reintentos. El monitoring mostraba “host up”, pero el servicio estaba prácticamente muerto. Los operadores tuvieron que reiniciar a la fuerza los nodos para recuperar la capacidad de scheduling.
La solución fue acotar la concurrencia basada en el comportamiento medido del dispositivo, no en optimismo. Pusieron límites sensatos en depths de cola, usaron backpressure en la aplicación y ajustaron timeouts para que una falla real de almacenamiento produjera caminos de error predecibles en lugar de largos bloqueos. El throughput bajó un poco en el caso feliz; la disponibilidad mejoró dramáticamente en el caso infeliz. Ese intercambio suele valer la pena.
Práctica aburrida pero correcta que salvó el día: “Presupuesto de timeouts y simulacros regulares”
Otra organización corría una flota mixta: algunos NVMe locales, algunos SAN, algunos volúmenes cloud. Tenían una política que exigía que cada clase de almacenamiento tuviera un presupuesto de timeout documentado: cuánto puede esperar el SO, cuánto puede encolar multipath, qué tan rápido el orquestador cercaría.
No era glamuroso. El documento era una tabla. Se revisaba cada trimestre. El equipo también realizaba simulacros controlados de “tirar la ruta” en un SAN de staging y simulaban degradación de rendimiento de volúmenes cloud durante pruebas de carga.
Un día un controlador de almacenamiento en un sitio remoto empezó a fallar. Un puñado de nodos perdió una ruta y luego perdió la segunda brevemente. En lugar de colgarse, los nodos fallaron la E/S dentro del presupuesto acordado. El cluster los expulsó, las cargas se movieron y el incidente quedó en un problema menor de capacidad, no en una caída de plataforma completa.
Las notas del postmortem fueron cortas: “los timeouts se comportaron según el diseño.” Que es la mejor clase de frase en operaciones—aburrida, correcta y breve.
Errores comunes: síntoma → causa raíz → arreglo
1) Síntoma: host “se congela”, pero la CPU está baja
Causa raíz: procesos atascados en sueño no interrumpible (D-state) esperando E/S; a menudo un journal/log del sistema de archivos bloqueado.
Arreglo: identifica el dispositivo/montaje (Tasks 2–4), revisa los logs del kernel (Task 1) y detén el encolado indefinido en multipath si aplica.
2) Síntoma: el dispositivo multipath existe, pero la E/S se atasca por minutos cuando el SAN parpadea
Causa raíz: queue_if_no_path o no_path_retry demasiado generoso con comprobación de rutas lenta.
Arreglo: configura reintentos/acotación y alinea los intervalos de comprobación con tu presupuesto de timeout de servicio (Task 5, Task 11).
3) Síntoma: mensajes repetidos de “resetting controller” (NVMe o HBA)
Causa raíz: inestabilidad del dispositivo/firmware o timeouts demasiado agresivos bajo carga, causando tormentas de reinicio.
Arreglo: valida firmware/logs de salud (Task 10), revisa contadores de error y no acortes timeouts hasta entender la latencia final.
4) Síntoma: “blocked for more than 120 seconds” aparece, luego desaparece, luego regresa
Causa raíz: flaps intermitentes de ruta o throttling del backend causando picos de latencia final más allá de la tolerancia de la aplicación.
Arreglo: correlaciona con logs de multipath (Task 11) y eventos de transporte; ajusta failover y reduce la concurrencia para controlar la acumulación de colas.
5) Síntoma: errores de I/O en dmesg, sistemas de archivos remontan como solo lectura
Causa raíz: errores de medio reales, cable/ruta rota o falla del dispositivo en el backend devolviendo errores.
Arreglo: trátalo como riesgo de datos. Haz failover de servicios, captura logs y reemplaza/repara hardware o volumen. El tuning no arreglará un disco muerto.
6) Síntoma: “todo está lento” durante backups o jobs por lotes, sin errores del kernel
Causa raíz: saturación de profundidad de cola y congestión de writeback; a veces elección inadecuada de scheduler para el tipo de dispositivo.
Arreglo: limita concurrencia, programa jobs pesados, considera tuning del scheduler tras pruebas (Task 7) y ajusta parámetros de writeback con cuidado (Task 13).
7) Síntoma: solo un montaje se queda colgado, el resto del sistema está bien
Causa raíz: stall del journal/log de un sistema de archivos específico en un dispositivo o LV de LVM; otros montajes en otros dispositivos no afectados.
Arreglo: aisla y falla el montaje/servicio en lugar de reiniciar todo el host. Considera separar logs/journals en dispositivos distintos donde proceda.
Listas de verificación / plan paso a paso
Paso a paso: durante un incidente activo de “congelamiento bajo carga”
- Captura evidencia rápida: fragmentos de logs del kernel (Task 1), evidencia de procesos bloqueados (Task 2) y
iostat(Task 3). Guárdalos fuera del host si es posible. - Mapea el impacto: identifica qué montaje/dispositivo está involucrado (Task 4). Si es
/,/varo un montaje de base de datos, espera un gran radio de impacto. - Determina redundancia: ¿estás en multipath/RAID/cluster? Si es así, normalmente puedes aislar la ruta/dispositivo malo. Si no, planifica un reinicio controlado y reemplazo.
- Si hay multipath: confirma si estás encolando para siempre (Task 5). Si es así, decide si cambiar a comportamiento acotado como parte del plan de arreglo.
- Revisa errores reales de E/S: journalctl logs del kernel (Task 8) y mensajes del sistema de archivos (Task 12).
- Revisa drivers de carga: iotop (Task 9) para ver si es un único culpable o presión general.
- Mitiga: failover de servicios, drena el nodo o cercar/reiniciar. No sigas reiniciando apps que están bloqueadas en E/S.
- Tras la recuperación: ejecuta mediciones de latencia controladas (Task 14) para validar si la cola de latencia volvió a ser sensata.
Paso a paso: implementar tuning de timeouts de forma segura (plan de cambios)
- Define tu presupuesto de timeout (ejemplo: “un nodo puede bloquearse a lo sumo 30 segundos en almacenamiento antes de ser declarado unhealthy”). Sin esto, afinarás al azar.
- Inventaría tipos de almacenamiento: SATA/SAS local, NVMe, iSCSI/FC SAN, volúmenes cloud, dm-crypt, LVM, RAID, multipath.
- Registra ajustes actuales: timeouts SCSI, configuración multipath, timeouts de transporte, scheduler, profundidad de cola.
- Decide comportamiento ante falla: ¿prefieres errores de I/O rápidos (fail fast) o esperar (intentar sobrevivir blips)? La mayoría de sistemas distribuidos deben fallar rápido.
- Alinea capas:
- El transporte detecta pérdida de ruta dentro del presupuesto.
- Multipath hace failover o falla la E/S dentro del presupuesto.
- Los timeouts SCSI/NVMe no exceden el presupuesto por un orden de magnitud.
- Prueba con inyección de fallos: desconecta una ruta, deshabilita un target, limita un volumen y observa duración del bloqueo y comportamiento de la aplicación.
- Despliega gradualmente: un entorno, una clase de almacenamiento a la vez.
- Monitorea la latencia final y tasas de error durante el despliegue; revierte si causas tormentas de reinicio o falsos fallos.
Lista de sanidad: cómo luce “bien”
- Una sola ruta muerta desencadena failover de multipath rápido y visible en logs.
- No hay encolado indefinido en montajes críticos a menos que lo hayas elegido explícitamente.
- Las aplicaciones hacen timeout y reintentan a nivel de app en lugar de colgarse para siempre.
- Los health checks del nodo detectan indisponibilidad de almacenamiento (no solo “el proceso existe”).
- La latencia final se mantiene acotada bajo carga pico, no solo la latencia media.
Preguntas frecuentes
1) ¿Es esto un problema de Ubuntu 24.04, o un problema de Linux?
Mayormente es una realidad de Linux y hardware. Ubuntu 24.04 trae un kernel y userspace modernos, pero los modos de falla son inherentes a la pila de almacenamiento: los dispositivos pueden dejar de responder y el SO debe decidir cuánto esperar.
2) ¿Por qué un disco malo hace que todo el host parezca congelado?
Porque procesos críticos se bloquean en E/S. Si journald, rsyslog, servicios de paquetes o tu base de datos están en D-state, todo, desde el login hasta el monitoring, puede quedarse atrás.
3) ¿Debería bajar todos los timeouts a 1 segundo?
No. Crearás falsos fallos y tormentas de reinicio, especialmente en SAN y NVMe bajo carga. Ajusta los timeouts según la latencia final medida y el presupuesto de failover de tu servicio.
4) ¿Cuál es la configuración de multipath más peligrosa?
queue_if_no_path sin una política de reintentos acotada. Puede convertir “no hay rutas disponibles” en “el host parece muerto”, lo cual es una experiencia de usuario profundamente inútil.
5) ¿Cómo sé si es saturación de carga vs dispositivo que falla?
La saturación suele mostrar alta utilización y latencia creciente sin errores de I/O del kernel. Los dispositivos fallando muestran timeouts, reinicios y errores de I/O en los logs del kernel (Task 1 y Task 8).
6) ¿Los sistemas de archivos pueden causar bloqueos aun si el disco está bien?
Pueden amplificar problemas. Una carga que fuerza commits sync/journal frecuentes puede atorar el montaje bajo presión. Pero un disco realmente “bien” con bloqueos catastróficos del sistema de archivos es menos común de lo que la gente espera.
7) Mi volumen cloud a veces se pausa 20–60 segundos. ¿Debo aumentar timeouts?
Si esas pausas son reales y esperadas por tu proveedor, puede que necesites timeouts más largos para evitar falsos fallos—pero entonces debes asegurar que tu aplicación y orquestación toleren esas pausas. De lo contrario, diseña para failover a otros nodos y no dejes que un volumen atascado congele el host.
8) ¿Por qué matar el proceso bloqueado no arregla el congelamiento?
Porque el proceso está bloqueado en sueño kernel no interrumpible esperando E/S. El kernel no puede liberarlo de forma segura hasta que la E/S se complete o falle.
9) ¿Cuál es la forma más segura de probar tuning de timeouts?
Inyección de fallos en staging: deshabilita deliberadamente una ruta, pausa un target o limita un volumen mientras ejecutas una carga representativa. Mide la duración del bloqueo y el comportamiento de recuperación, luego ajusta.
10) ¿Cuándo es correcto reiniciar?
Cuando tienes un dispositivo no redundante que está trabado y no se recuperará, o cuando el kernel/driver está atascado en un bucle de reinicios y necesitas que el host vuelva rápido. Reiniciar no es una solución; es un torniquete.
Conclusión: siguientes pasos que puedes hacer hoy
Si tu host Ubuntu 24.04 “se congela” bajo carga de disco, no lo aceptes como un misterio. Trátalo como un problema de presupuesto de timeouts con un subplot de hardware. Tus siguientes pasos:
- Durante el próximo evento, recoge los tres elementos esenciales: líneas de timeout de
dmesg, evidencia de procesos en D-state y la salida deiostat -x(Tasks 1–3). - Mapea montajes a dispositivos para saber qué se está bloqueando realmente (Task 4). Adivinar pierde horas.
- Si usas multipath, audita si estás encolando para siempre y decide si eso coincide con tus objetivos de disponibilidad (Task 5). La mayoría de plataformas modernas deberían preferir fallo acotado.
- Escribe un presupuesto de timeouts para tu clase de almacenamiento y alinea SCSI/NVMe/transporte/multipath a él. Si no puedes decir “fallamos la E/S dentro de ~N segundos”, no controlas tus outages.
- Ejecuta un simulacro de fallo controlado y observa si tu nodo falla rápido o se estanca lentamente. Luego ajusta con datos, no con superstición.
Los congelamientos de disco no siempre son prevenibles. Los bloqueos a nivel de host normalmente sí. Haz que el sistema elija una falla clara, y rápido, y tu vida en on-call mejorará inmediatamente—aunque la vida del proveedor de almacenamiento siga siendo… formadora de carácter.