Proxmox Ceph PG atascados/inactivos: qué hacer antes de que aumente el riesgo de datos

¿Te fue útil?

Notas que las máquinas virtuales se quedan congeladas. Las copias de seguridad se bloquean. La latencia se dispara. Luego Proxmox avisa con advertencias de Ceph: PGs atascados, PGs inactivos, quizá “peering”
durante más tiempo del que toleras. Aquí es donde los equipos o actúan con calma y realizan cambios reversibles, o empiezan a “arreglar” cosas hasta convertir el clúster
en un experimento de laboratorio.

Un PG atascado/inactivo no es un problema cosmético. Es Ceph diciéndote que no puede servir ni confirmar la colocación de datos de forma segura para algunos objetos. Tu trabajo es
encontrar qué restricción está bloqueando el progreso: disco, red, quórum, estado del OSD, reglas del pool, o simplemente dispositivos llenos; y luego aplicar el cambio mínimo que
lleve los PGs de vuelta a active+clean sin jugar con los datos.

El modelo mental: qué significa realmente “PG atascado/inactivo”

En Ceph, los objetos viven en Placement Groups (PGs). Un PG no es datos por sí mismo; es la unidad de colocación y consistencia. Cada PG se asigna a un conjunto de OSDs
mediante reglas CRUSH. A Ceph le importa el estado del PG porque es así como el clúster decide: “¿Puedo servir lecturas/escrituras de forma segura?” y “¿sabemos quién tiene la versión más reciente
de cada objeto?”

Inactivo significa que el PG no puede actualmente servir E/S porque no ha completado el peering hacia un conjunto actuante consistente (los OSDs actualmente
responsables). Puede faltar OSDs, carecer de conocimiento de quórum o estar atascado esperando historial. Atascado es una alarma basada en tiempo:
el PG ha estado en algún estado no ideal (peering, activando, backfilling, undersized, degraded) más tiempo del esperado.

La trampa peligrosa es tratar “inactivo” como un único bug. No lo es. Es una clase de síntoma. A veces la solución es aburrida (traer un OSD de vuelta, reemplazar un disco,
restaurar la red). A veces es quirúrgica (ajustar límites de recuperación). A veces exige decisiones (reducir temporalmente el size del pool, marcar un OSD como out, o como último
recurso, declarar datos perdidos).

Tu principio operativo seguro: no cambies la comprensión del clúster sobre los datos hasta que hayas confirmado por qué no puede ponerse de acuerdo. Si el PG no puede
hacer peering, normalmente es porque algún participante falta, es inconsistente o responde demasiado lento. Haz que responda, o elimínalo limpiamente—y solo con una evaluación clara del impacto.

Broma #1 (corta y relevante): La recuperación de Ceph es como un sistema de equipaje de aeropuerto: todo es “eventualmente consistente” hasta que tu maleta es la que falta.

Estados clave de PG que verás en clústeres Proxmox Ceph

  • active+clean: el estado objetivo.
  • active+degraded: la E/S funciona, pero faltan algunas réplicas; la recuperación intentará arreglarlo.
  • active+undersized: el conjunto actuante tiene menos OSDs de los que exige el size del pool; el riesgo aumenta.
  • peering / activating: en progreso el acuerdo; si está atascado, algo lo está bloqueando.
  • backfill_wait, backfilling, recovering: movimiento de datos; puede ser lento o bloqueado por throttles/discos llenos.
  • stale: el monitor no ha tenido noticias de los OSD(s) responsables; a menudo red o host caído.
  • incomplete: Ceph no puede encontrar datos autoritativos para el PG; aquí es donde frenas y piensas.

Qué significa en la práctica “antes de que aumente el riesgo de datos”

El riesgo de datos aumenta cuando cruzas cualquiera de estos umbrales:

  • Varios OSDs caen en el mismo dominio de fallo (mismo host, mismo rack, misma fuente de alimentación) para pools con size 3.
  • Los PGs pasan a incomplete o inactive para un pool que sirve discos de VM y sigues escribiendo de todos modos (o sigues forzando reinicios).
  • Los discos OSD están casi llenos y continúas el backfill, causando amplificación de escritura y posibles fallos de asignación en BlueStore.
  • Empiezas a usar comandos destructivos (ceph pg repair, ceph-objectstore-tool, ceph osd lost) sin evidencia.
  • Los monitores están a la deriva el quórum; los mapas del clúster cambian constantemente; los PGs no pueden estabilizarse.

Hechos y contexto interesantes (Ceph y PGs)

  • Los PGs existen para escalar el metadato: Ceph evita decisiones de metadatos por objeto agrupándolos en PGs; por eso el número de PGs importa para el rendimiento y la recuperación.
  • “Peering” es el consenso ligero por PG de Ceph: no es Paxos por objeto; es un intercambio de historial a nivel de PG para decidir el registro autoritativo.
  • CRUSH (raíces de investigación de 2006): la colocación de Ceph se basa en un algoritmo determinista diseñado para evitar tablas de búsqueda centrales.
  • Las banderas “nearfull/backfillfull/full” de Ceph son protecciones: están ahí porque quedarse sin espacio a mitad de una recuperación puede dejar PGs en estados desagradables.
  • Backfill no es “solo copiar”: compite con la E/S de clientes, amplifica escrituras y puede exponer problemas latentes de firmware en discos/SSD.
  • BlueStore cambió el perfil de fallo: en comparación con FileStore, BlueStore redujo penalizaciones de doble escritura pero hizo más visible la salud del dispositivo (DB/WAL y latencia).
  • El quórum de mon es una dependencia fuerte para los mapas: incluso si los OSDs están “up”, la inestabilidad de mapas puede mantener a los PGs rehaciendo peering.
  • El autoscaler de PG existe porque los humanos son malos en la matemática de PG: el ajuste manual de PGs causó años de incidentes evitables, especialmente tras añadir OSDs.
  • La programación de scrubs se volvió disciplina operativa: los scrubs detectan problemas tipo bitrot, pero configuraciones agresivas de scrub pueden arruinar ventanas de recuperación.

Guía de diagnóstico rápido (primeras/segundas/terceras comprobaciones)

Cuando los PGs están atascados/inactivos, no necesitas más paneles. Necesitas un árbol de decisiones claro.
El objetivo es identificar el cuello de botella que impide el peering/activación, y si estás frente a dolor de disponibilidad o riesgo de integridad.

Primero: confirma el radio de impacto y los estados exactos de los PGs (2 minutos)

  • ¿Cuántos PGs, qué pools y en qué estados?
  • ¿Es inactive, stale, incomplete o solo una recuperación lenta?
  • ¿Están los monitores en quórum y estables?

Segundo: encuentra los participantes ausentes (5 minutos)

  • ¿Qué OSDs están down/out?
  • ¿Están down porque el host está caído, el disco falló o el demonio está bloqueado?
  • ¿Hay partición de red (fallos de heartbeat de OSD)?

Tercero: revisa capacidad y throttles (5–10 minutos)

  • ¿Algún OSD está nearfull/backfillfull/full?
  • ¿Las configuraciones de recovery/backfill son demasiado estrictas (clúster lento) o muy agresivas (clúster saturado)?
  • ¿Hay operaciones lentas que indiquen un dispositivo o nodo específico?

Cuarto: decide la estrategia de recuperación (y actúa)

  • Si el OSD es recuperable: recupéralo, deja que el peering complete, haz los cambios mínimos.
  • Si el disco del OSD está fallando: márcalo out, reemplázalo y reconstruye; no sigas reiniciándolo y empeorando la corrupción.
  • Si el PG está incomplete: no improvises; identifica los OSDs autoritativos recientes, revisa logs y planifica con cuidado. “Forzar” no es una estrategia.

Broma #2 (corta y relevante): Lo único más permanente que un ajuste temporal de Ceph es el ticket preguntando por qué sigue configurado seis meses después.

Tareas prácticas con comandos, salidas y decisiones (12+)

Los comandos a continuación asumen que usas la integración de Ceph de Proxmox (así que el CLI ceph está disponible en un nodo con keyring de administrador),
y que los servicios mon/mgr/osd están gestionados por systemd. Ajusta nombres de host/IDs a tu realidad.

Tarea 1: Obtén el mensaje real de salud (no adivines)

cr0x@server:~$ ceph -s
  cluster:
    id:     6c2a6d0c-3a7f-4c50-9c90-2d14c5d1f9aa
    health: HEALTH_WARN
            12 pgs inactive
            4 pgs peering
            1 osds down
            37 slow ops, oldest one blocked for 412 sec

  services:
    mon: 3 daemons, quorum pve1,pve2,pve3 (age 17m)
    mgr: pve1(active), standbys: pve2
    osd: 24 osds: 23 up (since 3m), 24 in (since 2h)

  data:
    pools:   4 pools, 512 pgs
    objects: 3.1M objects, 12 TiB
    usage:   36 TiB used, 48 TiB / 84 TiB avail
    pgs:     488 active+clean
             12 inactive
             4 peering

Qué significa: la salud ya te indica si esto es “solo recuperación” o “no podemos servir E/S de forma segura.” Los PGs inactivos afectan la disponibilidad.
El conteo “osds down” insinúa un participante faltante; “slow ops” insinúa un cuello de botella de rendimiento.

Decisión: Si algún PG está inactive o incomplete, prioriza restaurar el peering sobre afinar el rendimiento. El ajuste puede esperar; la corrección no.

Tarea 2: Identifica qué PGs están atascados y por qué Ceph lo cree así

cr0x@server:~$ ceph health detail
HEALTH_WARN 12 pgs inactive; 4 pgs peering; 1 osds down; 37 slow ops
[WRN] PG_AVAILABILITY: 12 pgs inactive
    pg 1.2f is stuck inactive for 611.243 seconds, current state inactive, last acting [3,7,12]
    pg 2.9a is stuck inactive for 603.991 seconds, current state inactive, last acting [5,9,21]
[WRN] PG_DEGRADED: 4 pgs peering
    pg 1.31 is stuck peering for 503.102 seconds, current state peering, last acting [7,12,18]
[WRN] OSD_DOWN: 1 osds down
    osd.12 is down
[WRN] SLOW_OPS: 37 slow ops, oldest one blocked for 412 sec

Qué significa: ahora tienes IDs de PG específicas y su último conjunto actuante. Ese conjunto actuante es tu rastro.
Si varios PGs atascados comparten un ID de OSD, ese OSD suele ser el villano (o la víctima).

Decisión: Pivotar hacia los OSD(s) compartidos. No reinicies todo a lo loco.

Tarea 3: Volcar el estado de un PG problemático (ver en quién está esperando)

cr0x@server:~$ ceph pg 1.2f query
{
  "state": "inactive",
  "acting": [3,7,12],
  "up": [3,7,12],
  "blocked_by": ["osd.12"],
  "peering_blocked_by": ["osd.12"],
  "info": {
    "last_update": "145'9023",
    "last_complete": "145'9001"
  }
}

Qué significa: esto es oro. Te dice que el PG no puede activarse porque osd.12 no está participando.
A veces blocked_by no aparece; entonces revisas logs de peering y el rendimiento del OSD.

Decisión: Enfócate en restaurar osd.12 o eliminarlo limpiamente (out) si el disco está frito.

Tarea 4: Confirma la topología y el estado del OSD (up/in/out y mapeo de host)

cr0x@server:~$ ceph osd tree
ID  CLASS  WEIGHT   TYPE NAME      STATUS  REWEIGHT  PRI-AFF
-1         84.00000 root default
-3         28.00000     host pve1
 0   ssd    3.50000         osd.0      up   1.00000  1.00000
 1   ssd    3.50000         osd.1      up   1.00000  1.00000
 2   ssd    3.50000         osd.2      up   1.00000  1.00000
-5         28.00000     host pve2
 3   ssd    3.50000         osd.3      up   1.00000  1.00000
 7   ssd    3.50000         osd.7      up   1.00000  1.00000
12   ssd    3.50000         osd.12    down  1.00000  1.00000
-7         28.00000     host pve3
 5   ssd    3.50000         osd.5      up   1.00000  1.00000
 9   ssd    3.50000         osd.9      up   1.00000  1.00000
21   ssd    3.50000         osd.21     up   1.00000  1.00000

Qué significa: ves dónde vive osd.12 (host pve2), y si está solo down o también out.
En tu salida está down pero aún in, lo que puede bloquear PGs que lo necesitan para peering.

Decisión: Ve a pve2, investiga por qué el OSD está down y decide “reiniciar” vs “reemplazar”.

Tarea 5: Comprueba el estado del servicio OSD y logs recientes en el host

cr0x@server:~$ ssh pve2 -- systemctl status ceph-osd@12 --no-pager
● ceph-osd@12.service - Ceph object storage daemon osd.12
     Loaded: loaded (/lib/systemd/system/ceph-osd@.service; enabled)
     Active: failed (Result: exit-code) since Fri 2025-12-26 08:14:02 UTC; 2min 11s ago
    Process: 11472 ExecStart=/usr/bin/ceph-osd -f --cluster ceph --id 12 (code=exited, status=1/FAILURE)
   Main PID: 11472 (code=exited, status=1/FAILURE)

Dec 26 08:14:02 pve2 ceph-osd[11472]: bluestore(/var/lib/ceph/osd/ceph-12) _read_bdev_label failed: (5) Input/output error
Dec 26 08:14:02 pve2 ceph-osd[11472]: OSD:init: unable to mount object store
Dec 26 08:14:02 pve2 systemd[1]: ceph-osd@12.service: Failed with result 'exit-code'.

Qué significa: esto no es “Ceph siendo Ceph.” Es un error de I/O en el dispositivo. BlueStore no puede leer su etiqueta.
Normalmente es un disco muriendo, un path de controladora roto o un dispositivo de reemplazo mal cableado.

Decisión: No entres en un bucle de reinicios. Pasa a comprobaciones de salud del dispositivo y al flujo de trabajo de reemplazo.

Tarea 6: Verifica la capa de dispositivo (SMART, dmesg). Confirma que es dolor de hardware real.

cr0x@server:~$ ssh pve2 -- sudo dmesg -T | tail -n 12
[Fri Dec 26 08:13:51 2025] blk_update_request: I/O error, dev sdd, sector 129024 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0
[Fri Dec 26 08:13:51 2025] Buffer I/O error on dev sdd1, logical block 16128, async page read
[Fri Dec 26 08:13:52 2025] sd 6:0:9:0: [sdd] tag#18 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[Fri Dec 26 08:13:52 2025] sd 6:0:9:0: [sdd] Sense Key : Medium Error [current]
[Fri Dec 26 08:13:52 2025] sd 6:0:9:0: [sdd] Add. Sense: Unrecovered read error

Qué significa: el kernel confirma errores de lectura no recuperados. Eso no es un problema de tuning.

Decisión: Trata osd.12 como hardware fallido. Márcalo out y planifica el reemplazo.

Tarea 7: Confirma que los monitores están en quórum y no flapping (los PGs no se asientan sin mapas)

cr0x@server:~$ ceph quorum_status
{
  "quorum": [0,1,2],
  "quorum_names": ["pve1","pve2","pve3"],
  "quorum_age": 1052,
  "election_epoch": 94
}

Qué significa: el quórum está presente y estable (quorum_age ~17 minutos). Bien. Si el quórum estuviera inestable, arregla eso primero.

Decisión: Procede con la remediación del OSD; no persigas comportamientos fantasma de PG causados por churn de mon.

Tarea 8: Comprueba nearfull/backfillfull/full (la capacidad puede bloquear la recuperación y mantener PGs atascados)

cr0x@server:~$ ceph df
--- RAW STORAGE ---
CLASS  SIZE     AVAIL    USED     RAW USED  %RAW USED
ssd    84 TiB   48 TiB   36 TiB    36 TiB       42.86
TOTAL  84 TiB   48 TiB   36 TiB    36 TiB       42.86

--- POOLS ---
POOL         ID  PGS  STORED   OBJECTS  USED     %USED  MAX AVAIL
rbd          1   256  9.8 TiB  2.1M     29 TiB   60.42  14 TiB
cephfs_data  2   128  2.0 TiB  0.7M     6.0 TiB  12.50  14 TiB

Qué significa: el uso raw está bien. Si vieras un pool con MAX AVAIL pequeño, o raw > 85%, esperarías bloqueos de backfill o advertencias nearfull.

Decisión: La capacidad no es el bloqueador; procede con el reemplazo/out del OSD.

Tarea 9: Antes de marcar out, mira si el clúster ya está degradado/undersized y cuánto

cr0x@server:~$ ceph osd stat
24 osds: 23 up, 24 in; epoch: e4123

Qué significa: el OSD está down pero todavía “in”, así que Ceph sigue intentando usarlo. Eso puede detener el peering según los PGs y su historial.

Decisión: Si el disco está muerto y no volverá pronto, márcalo out para que Ceph remapee y recupere en otros sitios.

Tarea 10: Marca el OSD fallado como out (remapeo controlado) y observa la recuperación

cr0x@server:~$ ceph osd out 12
marked out osd.12.

Qué significa: Ceph empezará a remapear los PGs que tenían a osd.12 en su conjunto actuante. Esto dispara backfill/recuperación.

Decisión: Si tienes poca capacidad o ya hay degradación en otros sitios, considera pausar cargas intensas de cliente o ajustar temporalmente los throttles de recuperación (con cuidado).

Tarea 11: Comprueba el progreso de recuperación y si los PGs dejan de estar inactive/peering

cr0x@server:~$ ceph -s
  cluster:
    health: HEALTH_WARN
            0 pgs inactive
            18 pgs degraded
            52 pgs recovering
            19 slow ops, oldest one blocked for 98 sec
  data:
    pgs:     442 active+clean
             52 active+recovering
             18 active+degraded

Qué significa: el problema inmediato de disponibilidad (PGs inactivos) desapareció. Ahora estás en modo recuperación. Eso es mejor: la E/S funciona, el riesgo se redujo, el clúster sana.

Decisión: Mantén la recuperación estable. No reinicies OSDs “para acelerarla.” Si persisten slow ops, identifica el dispositivo o nodo lento.

Tarea 12: Identifica a los culpables de slow ops (a menudo un OSD o un host)

cr0x@server:~$ ceph health detail | grep -A3 -i slow
[WRN] SLOW_OPS: 19 slow ops, oldest one blocked for 98 sec
    osd.7 has slow ops
    osd.21 has slow ops

Qué significa: ahora tienes OSDs candidatos para inspeccionar. Las slow ops durante la recuperación son comunes, pero las slow ops sostenidas pueden mantener el peering/recuperación lento o atascado.

Decisión: Revisa estadísticas de rendimiento del OSD y latencia a nivel de host; no subas indiscriminadamente los parámetros de recuperación.

Tarea 13: Comprueba contadores de rendimiento del OSD (latencia de commit/aplicar)

cr0x@server:~$ ceph osd perf
osd  commit_latency(ms)  apply_latency(ms)
0    7                   11
3    9                   14
7    120                 220
21   85                  160

Qué significa: los OSDs 7 y 21 son lentos comparados con los demás. Puede ser contención de disco, NIC saturada, SSD defectuoso o problema en el dispositivo DB/WAL.

Decisión: Investiga esos hosts antes de afinar. Si un OSD es patológico, la recuperación se quedará detrás y los PGs pueden parecer “atascados.”

Tarea 14: Revisa la salud de la red rápidamente (Ceph es almacenamiento distribuido, no disco local disfrazado)

cr0x@server:~$ ceph config get osd public_network
10.10.0.0/24
cr0x@server:~$ ssh pve2 -- ping -c 3 10.10.0.11
PING 10.10.0.11 (10.10.0.11) 56(84) bytes of data.
64 bytes from 10.10.0.11: icmp_seq=1 ttl=64 time=0.411 ms
64 bytes from 10.10.0.11: icmp_seq=2 ttl=64 time=0.399 ms
64 bytes from 10.10.0.11: icmp_seq=3 ttl=64 time=0.405 ms

--- 10.10.0.11 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2033ms
rtt min/avg/max/mdev = 0.399/0.405/0.411/0.005 ms

Qué significa: la latencia es baja y estable en un ping básico. Esto no prueba que la red sea perfecta, pero elimina particiones obvias.

Decisión: Si el ping muestra pérdida/picos, para. Arregla la red primero o terminarás “arreglando” Ceph hacia un agujero más profundo.

Tarea 15: Inspecciona la lista de PGs atascados en masa (patrones ahorran tiempo)

cr0x@server:~$ ceph pg dump_stuck inactive
PG_STAT  STATE     UP      UP_PRIMARY  ACTING  ACTING_PRIMARY  LAST_SCRUB  SCRUB_STAMP  LAST_DEEP_SCRUB  DEEP_SCRUB_STAMP

Qué significa: si esta salida está vacía, limpiaste los PGs inactivos. Si no, la lista puede mostrar si los mismos IDs de OSD aparecen repetidamente.

Decisión: conjuntos actuantes compartidos implican un problema de nodo/OSD específico; patrones dispersos implican red/quórum/reglas/capacidad.

Tarea 16: Comprueba si algún pool está mal configurado (size/min_size mal emparejados pueden mantener PGs infelices)

cr0x@server:~$ ceph osd pool ls detail
pool 1 'rbd' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 256 pgp_num 256 autoscale_mode on
pool 2 'cephfs_data' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 128 pgp_num 128 autoscale_mode on

Qué significa: para pools replicados, size es el número de réplicas; min_size es el mínimo requerido para servir escrituras.
Si min_size es demasiado alto respecto a la disponibilidad actual de OSDs, puedes terminar con escrituras bloqueadas o PGs no saludables durante fallos.

Decisión: No bajes min_size a la ligera. Puede mantener el clúster escribible, pero aumenta el riesgo. Úsalo solo con aceptación explícita de posible pérdida de datos ante fallos adicionales.

Tarea 17: Valida que el clúster no esté en pausa (sí, esto sucede)

cr0x@server:~$ ceph osd dump | egrep 'pause|noup|nodown|noin|nobackfill|norecover|noscrub|nodeep-scrub'
flags nodown,noin,nobackfill,norecover

Qué significa: alguien estableció banderas que previenen la curación normal (norecover, nobackfill). A veces es deliberado durante mantenimiento. A veces se olvida.

Decisión: Si no estás en una ventana de mantenimiento controlada, elimina las banderas. De lo contrario, tus PGs se quedarán degradados/atascados para siempre.

cr0x@server:~$ ceph osd unset norecover
unset norecover
cr0x@server:~$ ceph osd unset nobackfill
unset nobackfill
cr0x@server:~$ ceph osd unset noin
unset noin
cr0x@server:~$ ceph osd unset nodown
unset nodown

Tarea 18: Si un OSD es lento, comprueba la saturación de IO del host (sanity check rápido)

cr0x@server:~$ ssh pve2 -- iostat -x 1 3
Linux 6.8.12-pve (pve2)  12/26/2025  _x86_64_ (32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.11    0.00    6.24   18.52    0.00   63.13

Device            r/s     w/s   rkB/s   wkB/s  avgrq-sz avgqu-sz   await  r_await  w_await  svctm  %util
nvme0n1         120.0   310.0  7800.0  21400.0    92.0     8.40   24.10   12.30   28.70   1.20  51.00
sdd              15.0    40.0   800.0   1900.0    84.0    22.10  410.00  380.00  421.00  7.10  98.50

Qué significa: sdd está al ~98% de utilización con ~410 ms de await. Eso absolutamente crea slow ops y prolonga la recuperación.

Decisión: Si este es un disco de datos OSD, prepárate para reemplazarlo. Si es un dispositivo DB/WAL compartido por varios OSDs, encontraste el amplificador de latencia del clúster.

Tarea 19: Mapea PG a OSDs actuantes y luego a hosts (para fallos correlacionados)

cr0x@server:~$ ceph pg map 1.2f
osdmap e4123 pg 1.2f (1.2f) -> up [3,7,18] acting [3,7,18]

Qué significa: después de marcar out osd.12, el PG se remapeó a un nuevo conjunto actuante. Esto debería eliminar las condiciones “blocked_by osd.12”.

Decisión: Si el mapeo de PG sigue rebotando, sospecha problemas de quórum de mon, OSDs flapping o red inestable.

Tarea 20: Solo si tienes evidencia de inconsistencia de metadatos: intenta un PG repair (raro, con precaución)

cr0x@server:~$ ceph pg repair 1.31
instructing pg 1.31 on osd.7 to repair

Qué significa: ceph pg repair puede ayudar cuando un PG está atascado por réplicas inconsistentes. También puede consumir CPU y E/S y
empeorar las cosas si la causa subyacente son OSDs faltantes o discos rotos.

Decisión: Ejecuta repair solo después de restaurar quórum estable y disponibilidad de OSDs. Si te falta un OSD, repair suele ser teatro.

Una cita para mantener las manos firmes: Werner Vogels (idea parafraseada): “Todo falla, todo el tiempo: diseña y opera como si eso fuera normal.”

Modos de fallo que mantienen PGs atascados

1) Un OSD está down, pero aún “in”, y el PG lo necesita para peer

Este es el patrón de incidente más común en Proxmox con Ceph: un host se reinicia, un disco muere, una controladora se resetea o un OSD se bloquea. Ceph lo marca como down.
Si permanece “in”, algunos PGs esperarán por él (especialmente si antes contenía datos autoritativos y los demás necesitan su historial para ponerse de acuerdo).

La acción correcta depende de la causa raíz:

  • Daemon crash, dispositivo sano: reinicia el OSD, confirma que se mantiene arriba.
  • Errores de I/O en el dispositivo: márcalo out, reemplaza y reconstruye. No sigas encendiendo y apagando un disco moribundo; no se pondrá mejor por terquedad.
  • Host caído: restaura host/red/energía primero; decide si marcar out según el MTTR esperado y la redundancia actual.

2) Inestabilidad de quórum de mon causa churn constante de mapas

Si los monitores no logran mantener quórum, los mapas de OSD y los mapeos de PG pueden rebotar. Los PGs hacen peering, luego re-peering, y otra vez. Verás peering atascado,
pero el problema real es la gobernanza: el clúster no puede acordar la verdad actual.

Las causas raíz incluyen particiones de red, deriva del reloj, mons sobrecargados o discos lentos donde vive la BD del mon. En Proxmox es común ejecutar mons en nodos muy cargados.
Puede funcionar—hasta que no.

3) Nearfull/backfillfull/full bloquea movimiento y crea deadlocks

Ceph se protege de quedarse sin espacio restringiendo backfill y, en el peor caso, escrituras. Si algunos OSDs están nearfull, CRUSH puede seguir colocando datos en
los restantes, haciéndolos nearfull también. La recuperación se ralentiza, y tu “arreglo” (añadir carga o reiniciar) lo empeora.

Si estás nearfull y tienes PGs inactivos, las opciones se vuelven limitadas:

  • Añadir capacidad (la mejor respuesta, si puedes hacerlo rápido).
  • Borrar datos (solo si estás absolutamente seguro de lo que borras).
  • Ajustar temporalmente ratios de full (arriesgado; intercambias salvaguardas de corrección por tiempo).

4) El tuning de backfill/recuperación se volvió autolesivo

Las configuraciones de recuperación no son “boosters” de rendimiento. Son compensaciones. Si pones la recuperación demasiado agresiva, puedes saturar discos y redes,
provocando timeouts de I/O de cliente, OSDs pareciendo “down” por retrasos en el heartbeat, y PGs atascados en peering porque los participantes están sobrecargados.

Si pones la recuperación demasiado conservadora, puedes extender la ventana de fallo de minutos a horas—suficiente para que ocurra otro fallo. A los clústeres no les gustan las ventanas largas de exposición.

5) Un dispositivo patológico único (a menudo DB/WAL) envenena todo el clúster

BlueStore usa RocksDB y un WAL. Si DB/WAL está en un SSD compartido que falla o está saturado, múltiples OSDs pueden volverse “lentos pero no muertos.”
Eso es lo peor: todo está técnicamente arriba, pero los PGs no avanzan lo suficiente y las slow ops se acumulan.

6) Cambios en CRUSH/reglas o parámetros de pool crean sorpresas

Cambiar dominios de fallo, clases de dispositivo o reglas CRUSH puede disparar remaps masivos. Durante un estado degradado, es una excelente manera de crear un segundo incidente
sin resolver el primero. Si los PGs están inactivos, el clúster ya está frágil: reduce cambios, no los aumentes.

7) PGs incomplete: cuando Ceph no puede encontrar datos autoritativos

incomplete es donde “incidente de disponibilidad” se vuelve “incidente de integridad de datos.” Puede ocurrir si demasiados OSDs que guardaban un PG se van
(o se marcan como lost), o si las réplicas restantes no tienen suficiente historial de logs para ponerse de acuerdo.

Tu trabajo es determinar si:

  • Esos OSDs pueden volver (lo mejor).
  • Puedes restaurar desde backup/snapshot (a menudo la decisión empresarial correcta).
  • Debes declarar datos perdidos para PGs específicos (último recurso, decisión de negocio, no reflejo de CLI).

Tres microrelatos de la vida corporativa

Microrelato 1: El incidente causado por una suposición incorrecta

Una empresa mediana ejecutaba Proxmox con Ceph en tres nodos. Alguien vio 12 pgs inactive tras un reinicio por actualización del kernel de un nodo.
Supusieron que “inactive” significaba “re-equilibrando.” El ticket de soporte decía “el almacenamiento está lento”, así que lo trataron como un problema de rendimiento.

Subieron las configuraciones de recovery: más backfills, más recovery activo. Parecía progreso—más E/S, más red. Entretanto, el nodo reiniciado
tenía una NIC que arrancó a velocidad incorrecta por un problema de autonegociación. Los heartbeats caían. Los OSDs flappeaban, no fallaban limpiamente.

La suposición errónea fue sutil: creer que Ceph era libre de mover datos si lo necesitaba. Pero el peering necesitaba una membresía estable primero. El tráfico de recuperación incrementado
hizo que la NIC tambaleante perdiera más paquetes, lo que hizo que más OSDs parecieran down, lo que provocó que más PGs intentaran peer otra vez. Un bonito bucle de realimentación.

Al final, “arreglaron” el problema reiniciando todo—porque reiniciar es el solvente universal de hipótesis malas. El clúster volvió, pero la recuperación
tomó más tiempo y los clientes vieron más timeouts de los que habría habido con la solución aburrida: forzar la velocidad/duplex correctos de la NIC, estabilizar los heartbeats y dejar
que el peering termine.

La lección: la inactividad de PG suele ser un problema de membresía, no de ancho de banda. Arregla la participación (OSDs, red, quórum) antes de ajustar la recuperación.

Microrelato 2: La optimización que salió mal

Una empresa más grande quiso recuperar más rápido tras fallos de disco. Su equipo de almacenamiento aumentó la concurrencia en todo: más backfills, más hilos de recuperación,
mayor prioridad para la recuperación. En laboratorio redujo el MTTR.

En producción coincidió con un lote de firmware malo en SSDs de un subconjunto de nodos. Esos SSDs no fallaban de golpe; se volvían lentos bajo presión de escritura sostenida.
La “optimización” forzó a los SSDs lentos hacia su peor comportamiento: picos largos de latencia y resets ocasionales.

Cuando un dispositivo empieza a quedarse colgado, Ceph hace lo que los sistemas distribuidos hacen: reintenta, encola, re-peer, registra slow ops. De pronto el clúster no solo
estaba recuperando—estaba esperando colectivamente a un puñado de dispositivos técnicamente vivos. Los PGs comenzaron a atascarse en peering y backfill_wait porque
el clúster no podía mantener un ritmo estable.

Revirtieron las afinaciones e instituyeron una política: durante un evento degradado, la recuperación puede ser agresiva solo si la latencia de los dispositivos permanece dentro de un
umbral definido. Si no, se reduce la recuperación para preservar el servicio y evitar el flapping de OSDs. Esa política evitó que futuras “optimizaciones” convirtieran fallos
en colapsos.

La lección: el tuning de recuperación debe sujetarse a la latencia observada, no al optimismo. La concurrencia es un arma; no te la dispares en el pie.

Microrelato 3: La práctica aburrida y correcta que salvó el día

Una organización del sector financiero tenía una disciplina de cambios rígida para su clúster Proxmox Ceph. No era glamorosa. Mantenían un runbook y requerían una
“captura de salud del clúster” (realmente solo ceph -s y ceph health detail pegados en el ticket) antes y después del mantenimiento.

Una mañana vieron pgs inactive tras un reinicio de un switch top-of-rack. El de guardia siguió el runbook: comprobar quórum de mon, OSD down,
identificar conjuntos actuantes compartidos y verificar la conectividad entre las redes públicas/cluster de Ceph. Encontraron que un trunk VLAN no había vuelto correctamente.

Aquí viene lo aburrido: no reiniciaron OSDs. No tocaron recovery. No marcaron nada como perdido. Arreglaron el trunk, esperaron a que los heartbeats de OSD se estabilizaran,
vieron cómo los PGs hacían peering y luego monitorizaron la recuperación. El incidente siguió siendo un parpadeo de disponibilidad, no un evento de datos.

Más tarde, en el postmortem, lo compararon con un evento similar meses antes (antes del runbook) donde alguien había marcado un OSD out prematuramente,
causando una tormenta de recuperación mayor en horas de oficina. El runbook no hizo a los ingenieros más listos. Los hizo menos improvisadores.

La lección: las prácticas aburridas reducen el daño creativo. En almacenamiento, la creatividad está sobrevalorada.

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

1) Síntoma: “PGs atascados en peering” después de un reinicio de nodo

Causa raíz: los OSDs están flappeando porque el nodo volvió con red rota, MTU incorrecto o problemas de sincronización horaria; el peering nunca se estabiliza.

Solución: Estabiliza el nodo: verifica velocidad/duplex de NIC, consistencia de MTU, rutas/VLANs y NTP/chrony. Solo entonces reinicia los demonios OSD afectados si hace falta.

2) Síntoma: “PGs inactivos” y ceph pg query muestra blocked_by osd.X

Causa raíz: ese OSD está down, colgado o demasiado lento para responder, y es necesario para el historial de peering.

Solución: Si es recuperable: restaura el OSD (servicio + dispositivo). Si no: márcalo out y reemplázalo. No ejecutes ceph pg repair para compensar OSDs faltantes.

3) Síntoma: la recuperación no arranca, los PGs permanecen degradados, pero “todo está up”

Causa raíz: se establecieron flags del clúster como norecover o nobackfill durante mantenimiento y se olvidaron.

Solución: Limpia las banderas (ceph osd unset ...). Luego monitoriza ceph -s para confirmar que la recuperación se reanuda.

4) Síntoma: las slow ops explotan durante la recuperación; los OSDs comienzan a hacer timeouts

Causa raíz: la concurrencia de recovery es demasiado alta para el hardware/red. Los heartbeats se retrasan, provocando flaps de OSD y churn de peering.

Solución: Reduce la concurrencia de recovery/backfill. En términos de Proxmox: afina con prudencia, observa ceph osd perf y prioriza la estabilidad sobre la velocidad.

5) Síntoma: PGs atascados con backfill_wait por mucho tiempo

Causa raíz: o bien los throttles son demasiado estrictos, o hay un cuello de botella oculto: OSDs nearfull, OSDs objetivo lentos o limitaciones de red.

Solución: Revisa ceph df y ceph osd perf. Arregla el dispositivo lento o la presión de capacidad antes de aumentar límites de backfill.

6) Síntoma: PGs inactivos/incomplete tras múltiples fallos de disco en el mismo host

Causa raíz: desajuste del dominio de fallo. CRUSH creyó que las réplicas estaban separadas, pero no lo estaban (o un host tenía demasiados OSDs para el dominio).

Solución: Reevalúa el dominio de fallo CRUSH (host/rack) y la distribución de OSDs. Esto es una corrección de diseño, no un vendaje de incidente. Para el incidente: restaura OSDs faltantes o recupera desde backup.

7) Síntoma: PGs atascados después de cambiar size/min_size o reglas del pool

Causa raíz: cambiaste la colocación mientras el clúster ya estaba no saludable; los remaps se apilaron sobre la recuperación.

Solución: Deja de cambiar reglas durante degradación. Revierte si es seguro, estabiliza la disponibilidad de OSD y luego aplica los cambios en una ventana controlada.

8) Síntoma: Ceph muestra PGs “stale”

Causa raíz: mons/OSDs no reciben heartbeats (partición de red, host congelado o firewall que bloquea puertos Ceph).

Solución: Repara la conectividad de red y la salud del host. No marques OSDs stale como lost a menos que estés preparado para declaraciones de pérdida de datos permanentes.

Listas de verificación / plan paso a paso

Plan paso a paso para un incidente en vivo (PG atascado/inactivo)

  1. Congela cambios riesgosos.
    Deja de afinar, deja de “actualizar rápido”, deja de reiniciar demonios como si sacudieras una máquina expendedora.
  2. Captura la verdad actual.
    Ejecuta ceph -s y ceph health detail. Guarda las salidas en el canal/ticket del incidente.
  3. Lista los PGs atascados e identifica OSDs actuantes compartidos.
    Usa ceph health detail y ceph pg dump_stuck inactive.
  4. Confirma la estabilidad del quórum de mon.
    ceph quorum_status. Si el quórum es inestable, arregla eso primero.
  5. Comprueba el estado y la ubicación de los OSDs.
    ceph osd tree y ceph osd stat.
  6. Para un OSD sospechoso, inspecciona servicio + logs + mensajes del kernel.
    Si ves errores de I/O, trátalo como hardware, no como mal humor de software.
  7. Decide: restaurar vs marcar out.
    Si el OSD puede volver pronto y limpio, recupéralo. Si no, márcalo out y reemplázalo.
  8. Observa el cambio de estados de PG.
    Tu primera condición de éxito es “sin PGs inactivos.” La segunda es “el conteo de degraded disminuye.”
  9. Gestiona la carga de recuperación si es necesario.
    Si hay slow ops y dolor de cliente severo, reduce la concurrencia de recuperación. Si la recuperación es muy lenta y el clúster es estable, incrementa un poco. Nunca pases de 1 a 11.
  10. Tras la estabilización, arregla la causa raíz.
    Reemplaza hardware, corrige la red y documenta la cadena de evidencia (salidas, logs y decisiones).

Lista de seguridad antes de usar “herramientas afiladas”

  • Quórum de mon estable durante al menos varios minutos (sin elecciones rápidas).
  • Puedes nombrar los PG(s) específicos y los OSD(s) específicos implicados.
  • Has verificado logs de dispositivo/kernel por errores de hardware.
  • Entiendes el impacto de size y min_size del pool en la seguridad de los datos.
  • Tienes un plan de reversión o al menos una “condición de parada.”
  • Las partes interesadas están al tanto si consideras ceph osd lost o bajar min_size.

Lista de estabilización tras el incidente

  • Elimina banderas temporales: verifica que no queden norecover, nobackfill, noscrub.
  • Confirma que los PGs estén active+clean (o tienes un estado degraded aceptable con plan).
  • Revisa outliers de rendimiento de OSD (ceph osd perf) y reemplaza/repara dispositivos débiles.
  • Verifica la sincronización horaria entre nodos; a Ceph no le gusta el drama temporal.
  • Registra: qué falló, tiempo de detección, puntos de decisión y qué cambiaste.

FAQ

1) ¿“PGs atascados” y “PGs inactivos” son lo mismo?

No. “Atascado” es una alarma por duración: un PG ha permanecido en algún estado demasiado tiempo. “Inactivo” es un estado: el PG no puede servir E/S de forma segura. Inactivo es más urgente.

2) ¿Puedo simplemente reiniciar los servicios de Ceph en todos los nodos?

Puedes, pero es un instrumento contundente y a menudo oculta la causa raíz. Si el problema son errores de I/O de disco, particiones de red o inestabilidad de quórum,
los reinicios pueden hacer que el peering tarde más y aumenten el churn de mapas. Reinicia solo el componente para el que tengas evidencia.

3) ¿Cuándo debo marcar un OSD como out?

Márcalo out cuando tengas una razón creíble de que no volverá pronto y limpio: errores confirmados de I/O en disco, crashes repetidos, fallo de hardware del host,
o un MTTR largo. Si es un reinicio corto con discos sanos, suele ser mejor esperar unos minutos—a menos que ya estés a un fallo de distancia de problema mayor.

4) ¿Cuál es la forma más rápida de ver en qué espera un PG inactivo?

Empieza con ceph health detail para los IDs de PG y el acting set, luego ceph pg <pgid> query. Busca blocked_by o bloqueadores de peering.

5) ¿Debo ejecutar ceph pg repair cuando el peering está atascado?

Normalmente no. Si el PG está atascado porque falta un OSD o el clúster está inestable, repair no soluciona al participante faltante. Usa repair cuando tengas evidencia de inconsistencia con todos los OSDs requeridos presentes y estables.

6) ¿Qué significa active+undersized para mis discos de VM?

Significa que el PG está activo (la E/S puede proceder) pero existen menos réplicas de las que exige el size del pool. El riesgo aumenta: otro fallo en el lugar equivocado puede
dejar datos indisponibles o perdidos. Trátalo como “funcionando con la rueda de repuesto.”

7) ¿Por qué los PGs se atascan durante el backfill aun cuando el hardware parece bien?

Razones comunes: throttles/banderas (nobackfill, norecover), restricciones nearfull, o un OSD mucho más lento que el resto.
La recuperación tiende a moverse a la velocidad del participante crítico más lento.

8) ¿Es seguro bajar min_size para que vuelvan las escrituras?

Puede ser necesario operativamente, pero es un intercambio de riesgo deliberado. Bajar min_size puede permitir escrituras con menos réplicas, lo que aumenta la posibilidad
de pérdida de datos si otro OSD falla antes de completar la recuperación. Hazlo documentado, con límite temporal y con una condición clara de salida.

9) ¿Las actualizaciones de Proxmox comunmente causan eventos de PG inactivos?

Las actualizaciones en sí no son la causa; lo son los reinicios y reinicios de servicios. Reinicios en rolling sin verificar la salud del clúster, o reiniciar múltiples nodos Ceph a la vez,
es una forma fiable de aprender nuevos estados de PG.

10) Si tengo PGs incomplete, ¿qué debo hacer primero?

Deja de hacer cambios y concéntrate en restaurar cualquier OSD faltante que pueda contener datos autoritativos. Si se han ido, pasa a planificar backup/restore.
Las opciones “forzar” son último recurso y deben ser decisiones de negocio, no bravatas técnicas.

Conclusión: próximos pasos para reducir el dolor futuro

Cuando los PGs están atascados/inactivos, el clúster te está diciendo que no puede completar un apretón de manos crítico para la seguridad. Tu trabajo no es “hacer que la advertencia desaparezca.”
Tu trabajo es restaurar la participación estable: quórum, red, disponibilidad de OSDs y un margen de capacidad sensato.

Pasos prácticos siguientes:

  • Codifica la guía de diagnóstico rápido en tus notas de guardia: ceph -s, ceph health detail, ceph pg query, ceph osd tree, quórum, capacidad, perf.
  • Rastrea y reemplaza dispositivos lentos antes de que se vuelvan “no lo bastante muertos” para fallar rápido. Los outliers en ceph osd perf son advertencias tempranas.
  • Mantén el tuning de recuperación mínimo y acotado en el tiempo. Si lo cambias, regístralo, pon un recordatorio y revierte.
  • Diseña dominios de fallo que reflejen la realidad. La separación a nivel de host no es opcional cuando tus “hosts” comparten energía o un switch.
  • Practica el enfoque aburrido. Evidencia, cambio mínimo, observa, repite. No es heroico. Funciona.

Si recuerdas una cosa: la inactividad de PG es una alarma de corrección primero, un problema de rendimiento segundo. Trátala así y tendrás menos postmortems de “aumentamos el riesgo”.

← Anterior
ZFS zpool status: Leer la salud como un analista forense
Siguiente →
Debian 13: registro de consultas lentas de MySQL — encuentra la consulta que te está matando en silencio

Deja un comentario