Las peores interrupciones de almacenamiento no son ruidosas. Son silenciosas, educadas y llenas de listados vacíos:
zpool import no muestra nada, la dirección pide “simplemente reinícelo otra vez” y tu cerebro de guardia empieza a negociar con la física.
Cuando ZFS no te dice la verdad con las herramientas habituales, zdb -C lo hará. Lee la configuración del pool
directamente de las etiquetas en disco—sin cachefile, sin ilusiones, sin “quizá está en /etc/zfs.” Esta es la herramienta que usas cuando necesitas hechos, no sensaciones.
Qué hace realmente zdb -C (y por qué te importa)
zdb es el depurador de ZFS. Trátalo como tratas a fsck en sistemas de ficheros que lo necesitan: potente,
no rutinario, y no algo que ejecutes a la ligera en producción durante el pico de tráfico porque tienes curiosidad.
El indicador -C le dice a zdb que vuelque la configuración del pool que encuentra en disco.
Crucialmente, esta configuración no es lo mismo que “lo que este host actualmente cree que es el pool.”
Es la configuración almacenada en las etiquetas ZFS en cada vdev (disco, partición o dispositivo respaldado por archivo), escrita por ZFS
mismo. Eso convierte a zdb -C en una comprobación de la realidad cuando:
- El pool no se importa o se importa degradado y no confías en la interfaz gráfica.
- Moviste discos entre máquinas y el cachefile está obsoleto o falta.
- Los nombres de dispositivos cambiaron (
/dev/sdaruleta), pero los GUID no. - Sospechas de un split-brain / situación multi-host y necesitas evidencia en disco.
- Necesitas mapear “discos misteriosos” a vdevs sin arriesgar una importación.
zpool import es de más alto nivel y tiene opinión. Intenta ensamblar un pool y reportar un estado.
zdb -C es de nivel inferior y directo. Imprime lo que las etiquetas ZFS dicen, incluso si el sistema está confundido.
Postura de seguridad: cómo no empeorar un mal día
Usa zdb -C para inspección de solo lectura. Generalmente no escribe, pero el acto de importar un pool sí puede.
Si estás en una situación forense o de recuperación, prefiere:
zpool import -Npara importar sin montar datasets, reduciendo el radio de acción.zpool import -o readonly=onsi tu plataforma lo soporta para tu flujo de trabajo.- Desconecta cualquier otro host que pueda importar el mismo pool (sí, incluso “no debería”).
Broma #1: ZFS no pierde tu pool. Los humanos simplemente lo esconden en el espacio de nombres de dispositivos y luego se sorprenden.
Dónde vive la verdad: etiquetas ZFS, uberblocks y árboles de configuración
ZFS almacena metadatos del pool en cada vdev de primer nivel. Cada vdev tiene múltiples etiquetas en desplazamientos fijos (históricamente
cuatro etiquetas), que contienen una configuración serializada y otros metadatos. Cuando ejecutas zdb -C, lee esas
etiquetas y muestra el árbol de configuración que ZFS usará para ensamblar el pool.
La configuración es una estructura anidada: pool → árbol de vdev → hijos → hojas. Las hojas representan dispositivos reales
(discos, particiones, archivos), cada uno con un GUID. Los vdevs de primer nivel (mirror, raidz, draid) también tienen sus propios GUID.
Por eso los GUID son tu ancla cuando cambian las rutas de dispositivo.
Piezas clave que verás en zdb -C
- pool_guid: La identidad del pool. Si esto cambia, no estás viendo el mismo pool.
- vdev_guid: Identidad de un nodo vdev en el árbol.
- path y devid: Dependientes del SO, a menudo obsoletos entre máquinas.
- txg: Grupo de transacción. Más alto significa estado “más nuevo”.
- state: Si las etiquetas creen que el dispositivo estaba sano, offline, removido, etc.
- ashift: Alineación de sector potencia de dos. Un
ashiftincorrecto no es fatal, pero es para siempre. - features: Banderas de características que afectan la compatibilidad.
- hostid y hostname: Migas de pan para importaciones multi-host.
Por qué zdb -C es diferente del cachefile y zpool.cache
Muchos administradores confían en exceso en /etc/zfs/zpool.cache o en lo que use su distro. Ese cachefile es una
conveniencia. Puede faltar, estar obsoleto o ser incorrecto tras recableados, swaps de HBA, migraciones de VM o “alguien limpió
/etc porque parecía desordenado.”
Las etiquetas en disco no son opcionales. Si están intactas, ZFS puede reconstruir la configuración del pool. Si están dañadas,
ZFS se vuelve opinativo de forma poco útil—y estás en territorio de recuperación.
Datos interesantes y contexto histórico
- ZFS se originó en Sun Microsystems y se incluyó en Solaris a mediados de los 2000, construido alrededor de sumas de comprobación end-to-end y metadatos copy-on-write.
- Las etiquetas en disco son redundantes por diseño: múltiples etiquetas por vdev, además de múltiples vdevs, porque los puntos únicos de fallo de metadatos son para otros sistemas de ficheros.
- La identidad basada en GUID fue una elección deliberada para evitar la dependencia del nombre de dispositivo. El renombrado de Linux
sdano es una sorpresa; es un martes. - La era de flags de características reemplazó las monolíticas “versiones de ZFS” para que los pools pudieran evolucionar incrementalmente, pero también convirtió las importaciones entre plataformas en una negociación.
- El registro de hostid existe porque las importaciones multi-host pueden corromper pools silenciosamente; ZFS intenta detectar “este pool fue importado por otro host.”
- zdb es intencionalmente afilado: expone estructuras internas (MOS, uberblocks, punteros de bloque) y asume que sabes lo que haces.
- zpool.cache llegó después como conveniencia de arranque, especialmente importante para flujos de arranque con root-on-ZFS que no pueden escanear todo lentamente cada vez.
- Alineación de sectores 4K (ashift) se convirtió en un punto doloroso cuando llegaron discos “512e” y “4Kn”; ZFS lo dejó explícito en lugar de adivinar.
- OpenZFS moderno se extiende por plataformas (Linux, FreeBSD, illumos) con el mismo formato en disco básico, pero los flags de características todavía regulan la compatibilidad.
Cómo leer la salida de zdb -C como corresponde
La salida de zdb -C es densa porque la verdad es densa. Tu trabajo es reducirla a respuestas:
“¿Qué discos pertenecen a qué vdev?”, “¿Es este el txg más nuevo?”, “¿Se importó este pool por otro host?”, y “¿Qué intentará ensamblar ZFS si importo?”
Patrones a buscar
- Configuraciones múltiples en desacuerdo: Si distintos discos muestran valores txg diferentes y árboles ligeramente distintos, puede que falten dispositivos, haya una escritura parcial o un evento de división.
- Rutas que no existen: Los valores
/dev/disk/by-id/...podrían estar antiguos. Está bien. Los GUID importan más. - State y aux_state: Un dispositivo puede estar
OFFLINEintencionalmente, oUNAVAILporque desapareció. - Feature flags: Un pool puede estar perfectamente sano y aun así no poder importarse en un sistema más antiguo.
- hostid/hostname: Si dice que el pool fue importado por otro host, créelo e investiga.
Una cita que deberías tatuar en tus runbooks
“La esperanza no es una estrategia.” — idea parafraseada atribuida frecuentemente a la cultura de confiabilidad en operaciones.
Tareas prácticas: comandos, salidas y decisiones (12+)
Estas son las tareas que realmente ejecuto cuando un pool falta, está degradado o es sospechoso. Cada tarea incluye:
un comando, qué significa la salida y la decisión que tomas a continuación.
Task 1: Confirmar lo que ZFS piensa que es importable
cr0x@server:~$ sudo zpool import
pool: tank
id: 5486843001296116957
state: ONLINE
action: The pool can be imported using its name or numeric identifier.
config:
tank ONLINE
mirror-0 ONLINE
sdb ONLINE
sdc ONLINE
Significado: El escaneo de ZFS encontró un pool llamado tank y puede ensamblarlo.
Decisión: Si el pool aparece, probablemente estés ante problemas de puntos de montaje, cache obsoleto o features;
procede a zdb -C tank para confirmar la configuración y el hostid, luego considera zpool import -N para una importación más segura.
Task 2: Volcar la configuración en disco de un pool por nombre
cr0x@server:~$ sudo zdb -C tank
MOS Configuration:
pool_guid: 5486843001296116957
vdev_tree:
type: 'root'
id: 0
guid: 5486843001296116957
children[0]:
type: 'mirror'
id: 0
guid: 15320114977311041256
ashift: 12
children[0]:
type: 'disk'
id: 0
guid: 1183942225006373321
path: '/dev/disk/by-id/ata-SAMSUNG_SSD_870_QVO_1TB_S5R8...'
children[1]:
type: 'disk'
id: 1
guid: 10622090183881642744
path: '/dev/disk/by-id/ata-SAMSUNG_SSD_870_QVO_1TB_S5R8...'
features_for_read:
com.delphix:hole_birth
org.openzfs:project_quota
hostid: 0x8d3f2a11
hostname: 'db-node-02'
Significado: Este es el árbol autoritativo que ZFS registró. Fíjate en ashift, las flags de características y el último importador.
Decisión: Si hostname no es tu máquina actual, detente y verifica que no vas a hacer un dual-import del pool.
Task 3: Volcar configuraciones escaneando dispositivos (no se requiere nombre de pool)
cr0x@server:~$ sudo zdb -C
zdb: can't open 'tank': no such pool
zdb: examining /dev/sdb ...
MOS Configuration:
pool_guid: 5486843001296116957
vdev_tree:
type: 'root'
children[0]:
type: 'mirror'
children[0]:
path: '/dev/sdb'
children[1]:
path: '/dev/sdc'
Significado: Incluso si la resolución por nombre de pool falla, zdb -C aún puede encontrar etiquetas en dispositivos de bloque.
Decisión: Usa esto cuando zpool import no muestra nada. Te dice si las etiquetas existen en absoluto.
Task 4: Verificar el mapeo de identidad del disco usando by-id
cr0x@server:~$ ls -l /dev/disk/by-id/ | egrep 'SAMSUNG_SSD_870_QVO|wwn|scsi'
lrwxrwxrwx 1 root root 9 Dec 26 10:11 ata-SAMSUNG_SSD_870_QVO_1TB_S5R8... -> ../../sdb
lrwxrwxrwx 1 root root 9 Dec 26 10:11 ata-SAMSUNG_SSD_870_QVO_1TB_S5R8... -> ../../sdc
lrwxrwxrwx 1 root root 9 Dec 26 10:11 wwn-0x5002538f4123abcd -> ../../sdb
lrwxrwxrwx 1 root root 9 Dec 26 10:11 wwn-0x5002538f4fedcba -> ../../sdc
Significado: Las rutas en zdb -C podrían ser by-id; asegúrate de que resuelvan a dispositivos reales.
Decisión: Si las rutas by-id ya no existen, planea importar usando -d /dev/disk/by-id y confía en los GUID, no en /dev/sdX.
Task 5: Comprobar el cachefile que podría estar mintiéndote
cr0x@server:~$ sudo zpool get cachefile tank
NAME PROPERTY VALUE SOURCE
tank cachefile /etc/zfs/zpool.cache local
Significado: El pool está configurado para usar una ruta de cachefile.
Decisión: Si moviste discos a un host nuevo o cambiaste HBAs, considera importar temporalmente con zpool import -o cachefile=none para evitar envenenamiento por cache obsoleto.
Task 6: Importar sin montar para reducir el riesgo
cr0x@server:~$ sudo zpool import -N tank
Significado: Pool importado; datasets no montados.
Decisión: Ejecuta zpool status y zfs mount y toma decisiones intencionales. Esta es la postura segura cuando sospechas fallo parcial o incompatibilidad de features.
Task 7: Inspeccionar salud y contadores de errores de vdev después de importar
cr0x@server:~$ sudo zpool status -v tank
pool: tank
state: DEGRADED
status: One or more devices could not be opened. Sufficient replicas exist for
the pool to continue functioning in a degraded state.
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
wwn-0x5002538f4123abcd ONLINE 0 0 0
10622090183881642744 UNAVAIL 0 0 0 was /dev/sdc
errors: No known data errors
Significado: Falta un miembro; ZFS lo recuerda por GUID y ruta previa.
Decisión: Si esto es un mirror y tienes el disco, encuéntralo mediante inventario de hardware y vuelve a adjuntarlo; si no lo tienes, planea un replace tras verificar que no faltes con el disco equivocado.
Task 8: Emparejar GUID faltante de zpool status con el GUID de la hoja en zdb -C
cr0x@server:~$ sudo zdb -C tank | egrep "guid:|path:"
guid: 1183942225006373321
path: '/dev/disk/by-id/wwn-0x5002538f4123abcd'
guid: 10622090183881642744
path: '/dev/disk/by-id/wwn-0x5002538f4fedcba'
Significado: Puedes mapear el GUID faltante a su identidad esperada.
Decisión: Usa esto para evitar el error clásico: reemplazar el disco equivocado porque /dev/sdX cambió.
Task 9: Comprobar flags de características que pueden bloquear la importación en este host
cr0x@server:~$ sudo zdb -C tank | sed -n '/features_for_read:/,/hostid:/p'
features_for_read:
com.delphix:hole_birth
org.openzfs:embedded_data
org.openzfs:project_quota
hostid: 0x8d3f2a11
Significado: Estas características deben ser soportadas para importar en modo lectura-escritura; a veces es posible una importación de solo lectura dependiendo de la plataforma/herramientas.
Decisión: Si el OpenZFS de tu sistema es más antiguo, actualiza los paquetes/módulos ZFS antes de intentar la importación. No “forces” importaciones a través de brechas de features a menos que te guste apostar tu puesto.
Task 10: Comprobar mismatch de hostid (riesgo multi-host)
cr0x@server:~$ hostid
7f3a19c2
Significado: El hostid actual difiere del registrado en las etiquetas.
Decisión: Investiga si otro host sigue teniendo acceso. Si este pool se compartía vía SAS shelf, iSCSI LUN cloning o snapshotting de VM, detente y asegura semántica de escritor único.
Task 11: Importar desde un directorio de dispositivos específico para evitar coincidencias erróneas
cr0x@server:~$ sudo zpool import -d /dev/disk/by-id -N tank
Significado: La importación solo considera dispositivos encontrados bajo el directorio dado.
Decisión: Usa esto cuando el sistema tiene muchos discos y quieres evitar importar accidentalmente el pool equivocado (sí, eso pasa en laboratorios y en VMs de recuperación “temporales”).
Task 12: Inspeccionar etiquetas directamente (cuando sospechas daño en las etiquetas)
cr0x@server:~$ sudo zdb -l /dev/sdb
------------------------------------
LABEL 0
------------------------------------
version: 5000
name: 'tank'
state: 0
txg: 1483921
pool_guid: 5486843001296116957
guid: 1183942225006373321
Significado: Puedes ver si la etiqueta existe, qué txg anuncia y a qué pool/vdev pertenece.
Decisión: Si faltan etiquetas en algunos vdevs (o muestran txg muy diferentes), trata la situación como pérdida parcial de metadatos y procede con cautela: intenta la importación con el conjunto de dispositivos más completo y evita escribir hasta entender la divergencia.
Task 13: Comparar txg entre dispositivos para encontrar la configuración consistente más nueva
cr0x@server:~$ for d in /dev/sdb /dev/sdc; do echo "== $d =="; sudo zdb -l $d | egrep "LABEL|txg:|pool_guid:"; done
== /dev/sdb ==
LABEL 0
txg: 1483921
pool_guid: 5486843001296116957
LABEL 1
txg: 1483921
pool_guid: 5486843001296116957
== /dev/sdc ==
LABEL 0
txg: 1481200
pool_guid: 5486843001296116957
LABEL 1
txg: 1481200
pool_guid: 5486843001296116957
Significado: /dev/sdb tiene un txg más nuevo que /dev/sdc.
Decisión: Esto puede indicar que sdc estuvo offline o con retraso. No desvincules/replaces a ciegas; intenta traer el miembro antiguo online y resilver, pero valida primero la salud del hardware.
Task 14: Encontrar en qué bahía física está un disco (para sacar el correcto)
cr0x@server:~$ sudo udevadm info --query=all --name=/dev/sdb | egrep "ID_SERIAL=|ID_WWN=|ID_PATH="
E: ID_SERIAL=SAMSUNG_SSD_870_QVO_1TB_S5R8...
E: ID_WWN=0x5002538f4123abcd
E: ID_PATH=pci-0000:3b:00.0-scsi-0:0:10:0
Significado: Esto correlaciona el dispositivo Linux con un WWN estable y una ruta de bus.
Decisión: Usa esto para emparejar lo que dice zdb -C con lo que puede tocar tu equipo en el DC. En un chasis denso, “extraer el disco sdb” no es un plan.
Task 15: Validar el tamaño de sector y expectativas de alineación (verificar ashift)
cr0x@server:~$ sudo blockdev --getss /dev/sdb
512
Significado: Este es el tamaño de sector lógico; el físico puede diferir.
Decisión: Si zdb -C muestra ashift: 12 (4K) pero el dispositivo reporta 512, eso está bien (512e). Si ves ashift: 9 en discos modernos, espera problemas de rendimiento—no reconstruyas el pool solo por eso, pero evita repetir el error en pools nuevos.
Guion de diagnóstico rápido
Cuando tienes cinco minutos para detener la hemorragia, necesitas un orden de operaciones que evite madrigueras.
Aquí está la secuencia que encuentra el cuello de botella rápidamente y evita que “arregles” lo equivocado.
1) Confirmar visibilidad: ¿existen los discos y son los correctos?
- Ejecuta
lsblkyls -l /dev/disk/by-idpara confirmar los dispositivos presentes. - Si es SAN/LUN: confirma que multipath está estable antes de tocar ZFS.
cr0x@server:~$ lsblk -o NAME,SIZE,MODEL,SERIAL,WWN,TYPE
NAME SIZE MODEL SERIAL WWN TYPE
sdb 931.5G Samsung SSD 870 S5R8... 0x5002538f4123abcd disk
sdc 931.5G Samsung SSD 870 S5R8... 0x5002538f4fedcba disk
Decisión: Si los discos no son visibles, detente. Arregla cableado/HBA/multipath primero. ZFS no puede importar discos que no puede ver.
2) Pregunta a ZFS educadamente: ¿qué ve zpool import?
cr0x@server:~$ sudo zpool import -d /dev/disk/by-id
pool: tank
id: 5486843001296116957
state: ONLINE
action: The pool can be imported using its name or numeric identifier.
Decisión: Si aparece, tu problema probablemente no sea “el pool desapareció.” A menudo son puntos de montaje, claves o advertencias de hostid.
3) Si el escaneo de import está vacío o es sospechoso, ve a la verdad del disco con zdb -C y zdb -l
cr0x@server:~$ sudo zdb -C | head -n 30
zdb: examining /dev/sdb ...
MOS Configuration:
pool_guid: 5486843001296116957
vdev_tree:
type: 'root'
children[0]:
type: 'mirror'
Decisión: Si zdb ve etiquetas pero zpool import no, sospecha confusión por cachefile, permisos de acceso a dispositivos o incompatibilidad de features.
4) Identificar el tipo de cuello de botella
- No visible: descubrimiento de hardware/SO.
- Visible pero no importable: flags de características, hostid, vdevs faltantes o etiquetas corruptas.
- Importable pero degradado: discos faltantes, rutas malas o errores I/O intermitentes.
- Importado pero lento: pista separada—scrubs, resilvers, recordsize mismatch o remordimientos de ashift.
Errores comunes: síntomas → causa raíz → solución
1) “zpool import no muestra nada” pero los discos están presentes
Síntomas: zpool import no devuelve pools; lsblk muestra discos.
Causa raíz: Módulos ZFS no cargados, directorio de dispositivos incorrecto escaneado, o permisos/temporización de udev después del arranque en contexto initramfs.
Solución: Carga ZFS, escanea el lugar correcto y verifica etiquetas.
cr0x@server:~$ sudo modprobe zfs
cr0x@server:~$ sudo zpool import -d /dev/disk/by-id
cr0x@server:~$ sudo zdb -l /dev/sdb | head
2) “zpool import advierte: accedido por otro sistema”
Síntomas: Advertencia de import sobre otro host; zdb -C muestra hostid/hostname diferentes.
Causa raíz: El pool fue importado en otro sitio recientemente (o una copia tiene etiquetas idénticas). Riesgo de acceso dual.
Solución: Confirma escritor único. Apaga el otro nodo o elimina rutas de acceso. Si importas una copia intencionadamente, usa procedimientos adecuados para evitar colisiones de GUID (el manejo de clones difiere según plataforma).
3) “Se importa pero muestra dispositivos UNAVAIL con rutas /dev antiguas”
Síntomas: vdevs muestran was /dev/sdX; el host nuevo usa un nombrado diferente.
Causa raíz: Las rutas de dispositivo no son estables; ZFS almacenó una ruta que ya no se resuelve.
Solución: Usa /dev/disk/by-id y deja que ZFS haga match por GUID; luego limpia/reemplaza según sea necesario.
4) “Flags de características impiden import tras rollback del SO”
Síntomas: La importación falla por features no soportadas; zdb -C muestra features que tu pila no soporta.
Causa raíz: Actualizaste ZFS, activaste nuevas features y luego iniciaste un ZFS más antiguo (común tras arrancar con medios de rescate).
Solución: Arranca en un sistema con OpenZFS igual o más nuevo. No toggles features a la ligera; trátalas como migraciones de esquema.
5) “Un disco muestra txg más antiguo y sigue desconectándose”
Síntomas: Miembro de mirror se pone offline frecuentemente; txg de etiqueta atrasa; zpool status muestra errores intermitentes.
Causa raíz: Problemas reales de I/O: cable malo, puerto HBA inestable, problemas de alimentación o un SSD moribundo.
Solución: Reemplaza partes sospechosas. No “limpies” errores repetidamente y finjas que se arregló. Haz un scrub tras estabilizar el hardware.
6) “Pool importado en host equivocado porque el cachefile apuntaba a lo incorrecto”
Síntomas: Nombre de pool importado inesperado; el pool no coincide con los vdevs esperados.
Causa raíz: Cachefile obsoleto, imágenes de VM clonadas con zpool.cache idénticos, o múltiples pools con nombres similares.
Solución: Importa usando -d /dev/disk/by-id, verifica con zdb -C antes de montar y considera -o cachefile=none durante recuperación.
Tres micro-historias del mundo corporativo
Micro-historia 1: Un incidente causado por una suposición equivocada
Una empresa SaaS mediana migró una estantería de almacenamiento de un nodo de base de datos a otro durante una ventana de mantenimiento.
El plan era simple: apagar el nodo A, mover los cables SAS, arrancar el nodo B, importar el pool, listo. El operador hizo
el trabajo físico sin errores. El arranque fue bien. zpool import no mostró nada.
El on-call asumió, en voz alta, que “ZFS debió haber perdido el pool porque el cachefile no vino.” Copiaron /etc/zfs/zpool.cache desde la última copia de seguridad del nodo A al nodo B. Aún nada. Luego reiniciaron,
porque claro que sí.
El problema real fue más banal: el HBA del nodo B enumeró la estantería como un conjunto diferente de nodos de dispositivo,
pero las reglas de udev que creaban los enlaces /dev/disk/by-id faltaban en el entorno initramfs usado durante el arranque temprano.
ZFS no “perdía” nada; simplemente no pudo ver identificadores estables en el momento en que intentó importar.
Alguien finalmente ejecutó zdb -C contra los dispositivos de bloque crudos después del arranque, vio etiquetas intactas y el pool_guid correcto. Importaron con zpool import -d /dev una vez que el SO estuvo completamente activo, y luego arreglaron el initramfs
para que las rutas by-id existieran temprano. La suposición equivocada no fue que los cachefiles existen; fue creer que son autoritativos. No lo son.
Micro-historia 2: Una optimización que salió mal
Una empresa con un gran clúster de análisis decidió que el tiempo de arranque era demasiado lento. Sus nodos tenían un zoológico de discos:
SSD de SO, NVMe efímero y un conjunto de estanterías JBOD compartidas. Alguien “optimizó” pinneando las importaciones de ZFS a un
directorio de dispositivos estrecho y deshabilitando escaneos amplios. Ahorró segundos en el arranque. Todos aplaudieron.
Meses después, una estantería fue reemplazada en garantía. Mismo modelo, misma capacidad, WWNs diferentes. Los enlaces udev
bajo /dev/disk/by-id cambiaron de forma. El script de importación de arranque seguía apuntando a un directorio obsoleto y,
peor, filtraba por un patrón de nombre desactualizado.
El pool no se importó automáticamente, pero el sistema arrancó “saludable” de otra manera. El monitoreo estaba ligado a
datasets montados, por lo que las alertas llegaron tarde. Cuando el on-call intentó la importación manual, ensambló parcialmente el pool
usando los discos que pudo encontrar, dejando algunos vdevs faltantes. ZFS correctamente rechazó una importación limpia.
zdb -C salvó el día mostrando claramente la discrepancia: la configuración en disco listaba GUIDs de vdev que no
existían en el conjunto de dispositivos filtrado. La solución fue dejar de ser demasiado listo: escanear /dev/disk/by-id ampliamente, y alertar
explícitamente sobre “pool no importado”, no solo “sistema de ficheros no montado.” La optimización no era malvada; simplemente
asumió que la identidad del hardware nunca cambiaría. El hardware disfruta demostrártelo.
Micro-historia 3: Una práctica aburrida pero correcta que salvó el día
Un equipo de servicios financieros gestionaba pools de arranque en espejo y un pool raidz separado para datos. También tenían la rígida,
aburrida práctica: cada bahía de disco tenía una etiqueta física que coincidía con el WWN, y cada ticket de cambio incluía un fragmento
de la salida de zdb -C archivada con el pool_guid y los GUIDs de vdev.
En un trimestre, tras una mudanza apresurada del centro de datos, un pool de datos arrancó degradado. Dos discos aparecían, uno faltaba.
El técnico junior en sitio insistió en que había instalado todos los discos. El SO mostraba un disco en la bahía,
pero ZFS no lo veía como parte del pool.
El on-call usó el snapshot archivado de zdb -C para identificar el GUID de hoja faltante y el WWN esperado. Luego lo
comparó con udevadm info del disco físicamente instalado. Era el tamaño correcto, WWN equivocado: alguien había
insertado un repuesto de otra estantería, mismo proveedor, mismo color de etiqueta. Suficiente para humanos. No suficiente para ZFS.
Reemplazaron con el disco correcto, resilverearon y siguieron. Sin heroísmos. Sin pérdida de datos. Solo la clase de
procedimientos rutinarios que hace al almacenamiento fiable. Broma #2: La característica de almacenamiento más poderosa sigue siendo “etiqueta tus discos,” molesta por su ausencia en la mayoría de los folletos de marketing.
Listas de verificación / plan paso a paso
Checklist A: No puedes importar el pool y necesitas respuestas primero
- Confirma dispositivos:
lsblk,dmesgpor reinicios de enlace, y verifica que/dev/disk/by-idexista. - Ejecuta
sudo zpool import -d /dev/disk/by-id. Si está vacío, continúa. - Ejecuta
sudo zdb -C(modo escaneo). Confirma que ves elpool_guidesperado. - Ejecuta
sudo zdb -lpara cada disco candidato y comparapool_guidytxg. - Comprueba
features_for_ready confirma que tu plataforma las soporte. - Revisa
hostid/hostnameen las etiquetas y asegúrate de que ningún otro host pueda importar. - Decide modo de importación:
zpool import -Nprimero, opcionalmente con-o cachefile=none.
Checklist B: Encontraste el pool, pero los dispositivos están UNAVAIL
- Ejecuta
zpool status -vy registra los GUIDs faltantes. - Mapea GUIDs a rutas usando
zdb -C poolnamey localiza los WWNs correspondientes. - Verifica la presencia física y la ruta del bus con
udevadm info. - Arregla primero problemas de ruta de hardware (cables/HBA/backplane). Luego intenta acciones online/replace.
- Tras los cambios, haz un scrub o al menos monitoriza la finalización del resilver y los contadores de error.
Checklist C: Estás haciendo una migración planificada (medicina preventiva)
- Antes del apagado, captura:
zpool status -v,zdb -C pool, y los WWNs de dispositivos. - Asegura que el host destino tenga soporte de features de OpenZFS compatible.
- Usa nombres de dispositivo estables (
/dev/disk/by-id) en el host destino; evita/dev/sdXen scripts. - Importa con
-Nprimero, valida, luego monta intencionalmente. - Sólo después de una importación exitosa, actualiza el cachefile si usas uno.
Preguntas frecuentes
1) ¿Es seguro ejecutar zdb -C en producción?
Está orientado a lectura y típicamente es seguro, pero “seguro” depende de tu contexto operativo. Si tu almacenamiento
ya está fallando y cada I/O provoca timeouts, incluso leer etiquetas puede añadir carga. Úsalo deliberadamente.
2) ¿Por qué zdb -C muestra rutas que no existen?
Porque las rutas son pistas, no identidad. ZFS almacena la ruta que conoció por última vez. La identidad es el GUID, a menudo
correlacionado con WWN/devid. Usa enlaces by-id y el mapeo de GUID para conciliar.
3) ¿Cuál es la diferencia entre zdb -C y zpool import?
zpool import intenta ensamblar y presentar pools importables usando el descubrimiento del SO y heurísticas.
zdb -C vuelca la configuración almacenada en las etiquetas, incluso cuando el ensamblaje falla.
4) ¿Puede zdb -C ayudar si el nombre del pool es desconocido?
Sí. Ejecuta zdb -C sin nombre de pool para escanear dispositivos e imprimir las configuraciones que encuentre. Combínalo con zdb -l
en dispositivos específicos para mayor claridad.
5) ¿Qué me dice txg durante la recuperación?
Un txg más alto generalmente significa metadatos más nuevos. Si algunos vdevs anuncian un txg mucho más antiguo, ese dispositivo
probablemente perdió escrituras (offline, fallando o desconectado). Es una pista, no un veredicto.
6) Si veo un mismatch de hostid, ¿qué debo hacer?
Asume que el riesgo es real hasta que se demuestre lo contrario. Verifica que el otro host esté apagado o no tenga rutas de acceso.
Luego importa con cautela (a menudo con -N) y valida antes de montar o escribir.
7) ¿Cómo se relacionan las flags de características en zdb -C con fallos de importación?
Los pools pueden requerir ciertas features para ser entendidos. Si tu sistema no soporta una feature requerida, la importación
puede fallar de plano. La solución suele ser actualizar OpenZFS, no “forzar” nada.
8) ¿Por qué ZFS recuerda un disco faltante por un número (GUID) en lugar de por un nombre de dispositivo?
Porque los nombres de dispositivo no son estables entre arranques y hosts. Los GUID son identidades estables escritas en las etiquetas.
Esta es una de las mejores decisiones de diseño de ZFS—especialmente cuando estás cansado y son las 03:00.
9) ¿Puedo usar zdb -C para planear un reemplazo seguro de disco?
Sí. Úsalo para mapear el GUID de la hoja y la ruta by-id/WWN esperada, luego empareja eso con el inventario físico via
udevadm info. Reduce la posibilidad de reemplazar el disco equivocado en un mirror/raidz.
10) ¿Y si las etiquetas están corruptas en un disco?
Si existe redundancia (mirror/raidz) y otras etiquetas están intactas, ZFS usualmente puede importar y reconstruir.
Si múltiples dispositivos tienen etiquetas dañadas, deja de improvisar y trátalo como recuperación de datos: estabiliza el hardware,
clona discos si es necesario y trabaja desde el conjunto más completo de etiquetas que puedas leer.
Conclusión: pasos prácticos siguientes
zdb -C es cómo dejas de adivinar. Lee la configuración del pool directamente desde las etiquetas en disco y te da
los hechos que necesitas cuando las importaciones fallan, los dispositivos se renombran o alguien jura “no cambió nada.”
Pasos siguientes que puedes hacer hoy, antes del próximo incidente:
- Agrega una sección al runbook:
zpool import→zdb -C→zdb -lcon un árbol de decisiones. - Estandariza en
/dev/disk/by-idpara importaciones y monitoreo, no en/dev/sdX. - Archiva la salida de
zdb -Ctras cambios importantes en almacenamiento. Es un seguro barato y excelente evidencia sin culpas. - Entrena a tu equipo para mapear GUIDs a WWNs y a bahías físicas. Así evitas incidentes de “reemplazamos el disco equivocado”.