ZFS zdb -C: Читання конфігурації пулу безпосередньо з диска

Було корисно?

Найгірші відмови зберігання даних не голосні. Вони тихі, ввічливі й наповнені порожніми списками:
zpool import нічого не показує, керівництво просить «просто перезавантажити ще раз», а ваш
на виклику мозок починає торгуватися з фізикою.

Коли ZFS не каже правду звичними інструментами, zdb -C скаже. Воно читає конфігурацію пулу
безпосередньо з міток диска — без cachefile, без надій, без «можливо в /etc/zfs». Це інструмент для тих моментів,
коли потрібні факти, а не відчуття.

Що насправді робить zdb -C (і чому це важливо)

zdb — відлагоджувач ZFS. Тримайте його так само, як fsck для файлових систем, що потребують
перевірки: потужний, не рутинний і не те, що ви запускаєте бездумно в продакшені під час пікового навантаження через цікавість.
Прапорець -C говорить zdb, щоб він вивів конфігурацію пулу, яку знаходить на диску.

Важливо: ця конфігурація — не те саме, що «те, що ця машина зараз думає про пул».
Це конфігурація, збережена в мітках ZFS на кожному vdev (диск, розділ або файл-пристрій), записана самим ZFS.
Тому zdb -C — це перевірка реальності, коли:

  • Пул не імпортується або імпортується деградований і ви не довіряєте GUI.
  • Ви переміщали диски між машинами, а cachefile застарів або відсутній.
  • Імена пристроїв змінилися (/dev/sda рулетка), але GUID залишилися.
  • Підозрюєте split-brain / multi-host ситуацію і потрібні докази на диску.
  • Потрібно зіставити «таємні диски» з vdev без ризику імпорту.

zpool import — вищого рівня та суб’єктивний. Воно намагається зібрати пул і повідомити стан.
zdb -C — нижчого рівня і різкий. Воно друкує те, що кажуть мітки ZFS, навіть якщо система спантеличена.

Позиція з безпеки: як не зробити поганий день гіршим

Використовуйте zdb -C для огляду в режимі тільки читання. Зазвичай воно не пише, але імпорт пулу може.
Якщо ви в судово-експертній чи відновлювальній ситуації, надавайте перевагу:

  • zpool import -N — імпорт без монтування датасетів, щоб зменшити потенційну шкоду.
  • zpool import -o readonly=on — якщо ваша платформа це підтримує для вашого робочого процесу.
  • Відключіть будь-яку іншу хост-машину, яка може імпортувати той самий пул (так, навіть «це не повинно»).

Жарт №1: ZFS не втрачає ваш пул. Люди просто ховають його в просторі імен пристроїв, а потім дивуються.

Де живе правда: мітки ZFS, uberblocks і дерева конфігурації

ZFS зберігає метадані пулу на кожному топ-рівневому vdev. Кожен vdev має кілька міток у фіксованих зсувів (історично
чотири мітки), що містять серіалізовану конфігурацію та інші метадані. Коли ви запускаєте zdb -C, воно читає ці
мітки і друкує дерево конфігурації, яке ZFS використає для збірки пулу.

Конфігурація — це вкладена структура: pool → vdev tree → діти → листи. Листи представляють фактичні пристрої
(диски, розділи, файли), кожен з GUID. Топ-рівневі vdev (mirror, raidz, draid) теж мають власні GUID.
Тому GUID — ваш якір, коли шляхи пристроїв змінюються.

Ключові елементи, які ви побачите в zdb -C

  • pool_guid: Ідентифікатор пулу. Якщо він інший — ви не дивитесь на той самий пул.
  • vdev_guid: Ідентичність вузла vdev у дереві.
  • path і devid: Залежні від ОС, часто застарівають при переміщенні між машинами.
  • txg: Транзакційна група. Більше означає «новіший» стан.
  • state: Чи мітки вважали пристрій здоровим, офлайн, видаленим тощо.
  • ashift: Вирівнювання секторів у степені двійки. Неправильний ashift не фатальний, але незмінний.
  • features: Флаги функцій, що впливають на сумісність.
  • hostid і hostname: Хлібні крихти для ситуацій з multi-host імпортом.

Чому zdb -C відрізняється від cachefile і zpool.cache

Багато адміністраторів надто довіряють /etc/zfs/zpool.cache або тому, що використовує їхній дистрибутив.
Цей cachefile — зручність. Він може бути відсутнім, застарілим або неправильним після перекомутування, заміни HBA,
міграції VM або «хтось почистив /etc, бо виглядало неохайно».

Мітки на диску не є опційними. Якщо вони цілі — ZFS може відтворити конфігурацію пулу. Якщо вони пошкоджені,
ZFS починає поводитися суб’єктивно і непередбачувано — і ви опиняєтесь у зоні відновлення.

Цікаві факти та історичний контекст

  • ZFS виник у Sun Microsystems і з’явився в Solaris у середині 2000-х, побудований навколо end-to-end checksum і copy-on-write метаданих.
  • Мітки на диску надлишкові за дизайном: кілька міток на vdev, плюс кілька vdev, бо єдина точка відмови метаданих — це про інші файлові системи.
  • Ідентичність на базі GUID — свідомий вибір, щоб уникнути залежності від імен пристроїв. Перейменування Linux sda — це буденність.
  • Ера feature-flag замінила монолітні «версії ZFS», дозволивши поступово еволюціонувати пули, але зробила кросплатформений імпорт переговорною процедурою.
  • Запис hostid існує, бо multi-host імпорти можуть тихо пошкодити пул; ZFS намагається визначити «цей пул останнім імпортувався на іншому хості».
  • zdb спроектовано різким: воно відкриває внутрішні структури (MOS, uberblocks, блокові вказівники) і очікує, що ви знаєте, що робите.
  • zpool.cache з’явився пізніше як зручність при завантаженні, особливо важлива для root-on-ZFS сценаріїв, які не можуть занадто повільно сканувати всі диски при кожному завантаженні.
  • Вирівнювання 4K (ashift) стало джерелом проблем з появою дисків 512e і 4Kn; ZFS вирішив робити це явним, а не вгадувати.
  • Сучасний OpenZFS поширений по платформах (Linux, FreeBSD, illumos) з однаковим базовим форматом на диску, але флаги функцій все ще визначають сумісність.

Як читати вивід zdb -C, щоб мати відповіді

Вивід zdb -C густий, бо правда часто складна. Ваше завдання — звести його до відповідей:
«Які диски належать яким vdev?», «Чи це найновіший txg?», «Чи останній імпорт пулу був на іншому хості?»,
і «Що ZFS спробує зібрати, якщо я імпортуватиму?»

Зразки, на які варто звертати увагу

  • Різні конфігурації не погоджуються: якщо на різних дисках різні значення txg і трохи відмінні дерева, можливо, бракує пристроїв, був частковий запис або подія розщеплення.
  • Шляхи, яких не існує: /dev/disk/by-id/... можуть бути застарілими. Це нормально. GUID важливіші.
  • state і aux_state: пристрій може бути OFFLINE навмисно або UNAVAIL, бо його немає.
  • Флаги функцій: пул може бути цілком здоровим і одночасно неімпортованим на старішій системі.
  • hostid/hostname: якщо вказано, що пул останній раз імпортувався на іншому хості — вірте цьому і розслідуйте.

Коротка цитата для вашого рунабука

«Сподівання не є стратегією.» — парафраз ідеї, часто приписуваної культурі надійності в операціях.

Практичні завдання: команди, виводи та рішення (12+)

Ось завдання, які я реально виконую, коли пул відсутній, деградований або викликає підозри. Кожне завдання включає:
команду, що означає її вивід, і наступне рішення.

Завдання 1: Підтвердити, що ZFS вважає імпорт можливим

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

Значення: Сканування ZFS знайшло пул з іменем tank і може його зібрати.
Рішення: Якщо пул у списку, ймовірно, проблема з монтуванням, застарілим кешем або флагами функцій;
перейдіть до zdb -C tank, щоб підтвердити конфігурацію та hostid, потім розгляньте zpool import -N для безпечнішого імпорту.

Завдання 2: Вивести конфігурацію на диску для пулу за назвою

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'

Значення: Це авторитетне дерево, яке записав ZFS. Зверніть увагу на ashift, флаги функцій і останнього імпортера.
Рішення: Якщо hostname не ваш поточний хост — зупиніться і перевірте, щоб не допустити подвійного імпорту пулу.

Завдання 3: Вивести конфігурації шляхом сканування пристроїв (назва пулу не потрібна)

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'

Значення: Навіть якщо розв’язання імені пулу зазнає невдачі, zdb -C все одно може знайти мітки на блочних пристроях.
Рішення: Використовуйте це, коли zpool import нічого не показує. Це скаже, чи мітки взагалі існують.

Завдання 4: Перевірити відповідність ідентичності диска за 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

Значення: Шляхи в zdb -C можуть бути by-id; переконайтеся, що вони резольвляться в реальні пристрої.
Рішення: Якщо by-id шляхи більше не існують, плануйте імпорт з -d /dev/disk/by-id і покладайтесь на GUID, а не на /dev/sdX.

Завдання 5: Перевірити cachefile, який може вам брехати

cr0x@server:~$ sudo zpool get cachefile tank
NAME  PROPERTY   VALUE                       SOURCE
tank  cachefile  /etc/zfs/zpool.cache         local

Значення: Пул налаштовано на використання шляху cachefile.
Рішення: Якщо ви перемістили диски на новий хост або змінили HBA, тимчасово імпортуйте з zpool import -o cachefile=none, щоб уникнути отруєння застарілим кешем.

Завдання 6: Імпорт без монтування, щоб зменшити ризик

cr0x@server:~$ sudo zpool import -N tank

Значення: Пул імпортовано; датасети не змонтовано.
Рішення: Запустіть zpool status і приймайте рішення щодо zfs mount свідомо. Це безпечна позиція, коли підозрюєте частковий збій або невідповідність флагів.

Завдання 7: Перевірити здоров’я і лічильники помилок vdev після імпорту

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

Значення: Один член відсутній; ZFS пам’ятає його за GUID і попереднім шляхом.
Рішення: Якщо це mirror і диск у вас є — знайдіть його по апаратному інвентарю та підключіть; якщо ні — плануйте заміну після перевірки, що ви не видаляєте невірний диск.

Завдання 8: Зіставити відсутній GUID зі zpool status до GUID листа в 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'

Значення: Ви можете зіставити відсутній GUID з його очікуваною ідентичністю.
Рішення: Використайте це, щоб уникнути класичної помилки: замінити неправильний диск через зміну /dev/sdX.

Завдання 9: Перевірити флаги функцій, які можуть блокувати імпорт на цьому хості

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

Значення: Ці функції мають підтримуватися для RW-імпорту; іноді можливий лише RO-імпорт в залежності від платформи/інструментів.
Рішення: Якщо OpenZFS на вашій системі старіший — оновіть пакети/модулі перед спробою імпорту. Не «форсувати» імпорт через прогалини в функціях, якщо ви не любите ризикувати роботою.

Завдання 10: Перевірити невідповідність hostid (ризик multi-host)

cr0x@server:~$ hostid
7f3a19c2

Значення: Поточний hostid відрізняється від зафіксованого в мітках.
Рішення: Розслідуйте, чи має інший хост доступ. Якщо пул спільно доступний через SAS, iSCSI LUN cloning або VM snapshotting — зупиніться і забезпечте семантику одноразового записувача.

Завдання 11: Імпорт із конкретного каталогу пристроїв, щоб уникнути невірних збігів

cr0x@server:~$ sudo zpool import -d /dev/disk/by-id -N tank

Значення: Імпорт розглядає лише пристрої з вказаного каталогу.
Рішення: Використовуйте це, коли в системі багато дисків і ви хочете уникнути випадкового імпорту невірного пулу (таке трапляється в лабораторіях і тимчасових recovery VM).

Завдання 12: Перевірити мітки безпосередньо (коли підозрюєте пошкодження міток)

cr0x@server:~$ sudo zdb -l /dev/sdb
------------------------------------
LABEL 0
------------------------------------
    version: 5000
    name: 'tank'
    state: 0
    txg: 1483921
    pool_guid: 5486843001296116957
    guid: 1183942225006373321

Значення: Ви можете бачити, чи мітка існує, який txg вона рекламує і до якого пулу/vdev належить.
Рішення: Якщо мітки відсутні на деяких vdev (або показують дуже різні txg), вважайте ситуацію частковою втратою метаданих і дійте обережно: намагайтеся імпортувати з найбільш повним набором пристроїв і уникайте запису, поки не зрозумієте розбіжності.

Завдання 13: Порівняти txg між пристроями, щоб знайти найновішу узгоджену конфігурацію

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

Значення: /dev/sdb має новіший txg, ніж /dev/sdc.
Рішення: Це може вказувати, що sdc був офлайн або відставав. Не відключайте/не замінюйте сліпо; спробуйте повернути старого члена в онлайн і провести resilver, але спочатку перевірте апаратне здоров’я.

Завдання 14: Знайти, у якому фізичному слоті диск знаходиться (щоб витягнути правильний)

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

Значення: Це корелює Linux-пристрій зі стабільним WWN і шляхом шини.
Рішення: Використовуйте це, щоб зіставити те, що каже zdb -C, з тим, що можуть торкнутися ваші руки в ЦОДі. У щільному шасі «витягти sdb» — це не план.

Завдання 15: Перевірити розмір сектора та очікування вирівнювання (перевірка ashift)

cr0x@server:~$ sudo blockdev --getss /dev/sdb
512

Значення: Це логічний розмір сектора; фізичний може відрізнятися.
Рішення: Якщо zdb -C показує ashift: 12 (4K), але пристрій повідомляє 512 — це нормально (512e). Якщо бачите ashift: 9 на сучасних дисках, очікуйте проблем із продуктивністю — не перебудовуйте пул лише через це, але не повторюйте помилку при створенні нових пулів.

Швидкий план діагностики

Коли у вас є п’ять хвилин, щоб зупинити витік, потрібна послідовність дій, що уникне зайвих відволікань.
Ось послідовність, яка швидко знаходить вузьке місце і не дозволяє «виправити» неправильне.

1) Підтвердити видимість: чи існують диски і чи це правильні?

  • Запустіть lsblk і ls -l /dev/disk/by-id, щоб підтвердити наявність пристроїв.
  • Якщо SAN/LUN: переконайтеся, що multipath стабільний перед роботою з 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

Рішення: Якщо диски невидимі — зупиніться. Виправте кабелі/HBA/multipath. ZFS не зможе імпортувати диски, які не видно.

2) Запитайте ZFS ввічливо: що бачить 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.

Рішення: Якщо він з’являється — проблема, ймовірно, не в тому, що «пул зник». Часто це mountpoints, ключі або попередження hostid.

3) Якщо скан імпорту пустий або підозрілий — перейдіть до правди на диску з zdb -C і 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'

Рішення: Якщо zdb бачить мітки, але zpool import — ні, підозрюйте плутанину з cachefile, доступом до пристроїв або невідповідність флагів функцій.

4) Визначте тип вузького місця

  • Невидимі: апаратна/OS-сканування.
  • Видимі, але не імпортуються: флаги функцій, hostid, відсутні vdev або пошкоджені мітки.
  • Імпортовано, але деградовано: відсутні диски, неправильні шляхи або переривчасті помилки I/O.
  • Імпортовано, але повільно: окрема справа — scrub, resilver, несумісність recordsize або питання ashift.

Поширені помилки: симптом → корінь проблеми → виправлення

1) «zpool import нічого не показує», але диски присутні

Симптоми: zpool import не повертає пулів; lsblk показує диски.

Корінь проблеми: Модулі ZFS не завантажені, скановано неправильний каталог пристроїв або проблеми з правами/udev після завантаження в initramfs.

Виправлення: Завантажте модулі ZFS, скануйте правильне місце і перевірте мітки.

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 попереджає: останній доступ з іншої системи»

Симптоми: Попередження про інший хост; zdb -C показує різний hostid/hostname.

Корінь проблеми: Пул недавно імпортувався на іншому хості (або клон має ідентичні мітки). Ризик подвійного доступу.

Виправлення: Підтвердьте одноразовий записувач. Вимкніть інший вузол або видаліть шляхи доступу. Якщо ви імпортуєте клон навмисно — дотримуйтесь процедур для уникнення колізій GUID (обробка клонів залежить від платформи).

3) «Імпортується, але пристрої показуються як UNAVAIL з старими /dev шляхами»

Симптоми: vdev показує was /dev/sdX; новий хост використовує інші імена.

Корінь проблеми: Шляхи пристроїв нестабільні; ZFS зберіг шлях, який більше не резольвиться.

Виправлення: Використовуйте /dev/disk/by-id і дайте ZFS зіставити по GUID; потім очищуйте/замінюйте за потреби.

4) «Флаги функцій заважають імпорту після відкату ОС»

Симптоми: Імпорт не вдається через непідтримувані функції; zdb -C показує функції, яких ваш стек не розуміє.

Корінь проблеми: Ви оновили ZFS, ввімкнули нові функції, потім запустили старіший ZFS (часто після завантаження з rescue медіа).

Виправлення: Завантажте систему з підтримкою рівня або новішої версії OpenZFS. Не перемикайте флаги легковажно; ставтеся до них як до міграції схеми.

5) «Один диск показує старіший txg і постійно відключається»

Симптоми: Учасник mirror часто офлайнить; txg в мітці відстає; zpool status показує переривчасті помилки.

Корінь проблеми: Реальні I/O проблеми: поганий кабель, нестабільний порт HBA, проблеми з живленням або SSD на межі відмови.

Виправлення: Замініть підозрілі деталі. Не очищуйте помилки постійно, вдаючи, що все нормально. Після стабілізації апаратури запустіть scrub.

6) «Пул імпортовано на неправильному хості, бо cachefile вказував не те»

Симптоми: Несподіваний імпорт пулу; пул не відповідає очікуваним vdev.

Корінь проблеми: Застарілий cachefile, клоновані образи VM з ідентичним zpool.cache або кілька пулів з подібними іменами.

Виправлення: Імпортуйте з -d /dev/disk/by-id, перевірте з zdb -C перед монтуванням і розгляньте -o cachefile=none під час відновлення.

Три міні-історії з корпоративного життя

Міні-історія 1: Інцидент через неправильне припущення

Середній SaaS-магазин перемістив шельф зберігання з одного вузла бази даних на інший під час технічного вікна.
План був простий: вимкнути вузол A, перемістити кабелі SAS, завантажити вузол B, імпортувати пул, готово. Оператор
виконав фізичну роботу чисто. Завантаження пройшло нормально. zpool import нічого не показував.

На виклику припустили вголос, що «ZFS має втратити пул, бо cachefile не прийшов». Вони скопіювали /etc/zfs/zpool.cache
з останнього бекапу вузла A на вузол B. Все одно нічого. Потім перезавантажилися, бо звісно.

Насправді справа була банальною: HBA вузла B перерахував шельф як інший набір вузлів пристроїв,
але правила udev, що створювали /dev/disk/by-id посилання, були відсутні в initramfs середовищі, яке використовувалося під час раннього завантаження.
ZFS не «втратив» нічого; воно просто не могло бачити стабільні ідентифікатори в момент, коли намагалося імпортувати.

Хтось нарешті запустив zdb -C проти raw блочних пристроїв після завантаження, побачив цілі мітки і правильний
pool_guid. Вони імпортували з zpool import -d /dev після того, як ОС повністю піднялася, а потім виправили initramfs,
щоб by-id шляхи були доступні на ранньому етапі завантаження. Неправильне припущення було не в тому, що cachefiles існують; неправильне було в тому, що вони авторитетні. Вони — ні.

Міні-історія 2: Оптимізація, яка відбилася боком

Компанія з великим аналітичним кластером вирішила, що час завантаження занадто повільний. На вузлах було багато різних дисків:
OS SSD, ephemeral NVMe і набір спільних JBOD шельфів. Хтось «оптимізував», прив’язавши імпорти ZFS до вузького каталогу пристроїв і відключивши широке сканування. Це зекономило кілька секунд при завантаженні. Усі аплодували.

Місяць потому шельф замінили по гарантії. Та сама модель, такий самий об’єм, але інші WWN. udev-посилання
під /dev/disk/by-id змінилися. Скрипт імпорту під час завантаження все ще вказував на застарілий каталог і, що гірше, фільтрував за застарілим патерном імен.

Пул не імпортувався автоматично, але система піднімалася «здоровою» іншим чином. Моніторинг був прив’язаний до змонтованих датасетів, тому алерти прийшли запізно. Коли на виклику спробували ручний імпорт, він частково зібрав пул, використавши ті диски, що знайшов, і залишив деякі vdev відсутніми. ZFS справедливо відмовився від чистого імпорту.

zdb -C виручило, зробивши невідповідність очевидною: конфігурація на диску перераховувала GUID vdev, яких не було в відфільтрованому наборі пристроїв. Вирішення — перестати хитрувати: сканувати /dev/disk/by-id широко і сигналізувати про «пул не імпортовано» явно, а не лише про «файлова система не змонтована». Оптимізація не була злою; вона просто припустила, що апаратна ідентичність ніколи не зміниться. Апаратура любить спростовувати такі припущення.

Міні-історія 3: Нудна, але правильна практика, що врятувала ситуацію

Команда фінансових послуг тримала дзеркальні буут-пули і окремий raidz для даних. Вони також мали сувору, нудну звичку: кожен відсік диска мав фізичну наліпку, що відповідала WWN, і кожен змінний тикет містив фрагмент виходу zdb -C, заархівований з pool_guid і GUID vdev.

В одному кварталі після поспішного переміщення дата-центру data pool піднявся деградований. Два диски були присутні, один — відсутній. Молодший технік на місці наполягав, що встановив усі диски. ОС показувала диск у відсіку,
але ZFS не бачив його як частину пулу.

На виклику використали заархівований знімок zdb -C, щоб ідентифікувати відсутній GUID листа і очікуваний WWN. Потім порівняли це з udevadm info для фізично встановленого диска. Це був правий розмір, але неправильний WWN: хтось вставив запасний з іншого шельфу, той самий виробник, та сама кольорова наліпка. Для людини зовні — майже те саме. Для ZFS — недостатньо.

Вони замінили на правильний диск, провели resilver і продовжили роботу. Без героїзму. Без втрати даних. Просто рутинна дисципліна, яка робить зберігання надійним. Жарт №2: Найпотужніша функція зберігання — це все ще «маркуйте свої диски», на жаль рідко зустрічається у маркетингових буклетах.

Чек-листи / покроковий план

Чек-лист A: Ви не можете імпортувати пул і спочатку потрібні відповіді

  1. Підтвердіть пристрої: lsblk, dmesg для скидів лінків та перевірте наявність /dev/disk/by-id.
  2. Запустіть sudo zpool import -d /dev/disk/by-id. Якщо результат пустий — переходьте далі.
  3. Запустіть sudo zdb -C (режим сканування). Підтвердіть, що бачите очікуваний pool_guid.
  4. Запустіть sudo zdb -l для кожного кандидата і порівняйте pool_guid та txg.
  5. Перевірте features_for_read і підтвердіть, що ваша платформа їх підтримує.
  6. Перевірте hostid/hostname в мітках і переконайтеся, що інший хост не може імпортувати.
  7. Вирішіть режим імпорту: спочатку zpool import -N, опційно з -o cachefile=none.

Чек-лист B: Ви знайшли пул, але пристрої — UNAVAIL

  1. Запустіть zpool status -v і зафіксуйте відсутні GUID.
  2. Зіставте GUID з шляхами за допомогою zdb -C poolname і знайдіть відповідні WWN.
  3. Перевірте фізичну наявність і шлях шини через udevadm info.
  4. Виправте проблему з апаратним шляхом спочатку (кабелі/HBA/backplane). Потім спробуйте онлайнові/замінні дії.
  5. Після змін — scrub або принаймні стежте за завершенням resilver і лічильниками помилок.

Чек-лист C: Ви робите планову міграцію (профілактика)

  1. Перед вимкненням зафіксуйте: zpool status -v, zdb -C pool і WWN пристроїв.
  2. Переконайтеся, що цільовий хост має сумісну підтримку OpenZFS feature.
  3. Використовуйте стабільні імена пристроїв (/dev/disk/by-id) на цільовому; у скриптах уникайте /dev/sdX.
  4. Імпортуйте спочатку з -N, перевірте, потім монтируйте свідомо.
  5. Тільки після успішного імпорту оновлюйте cachefile, якщо ви його використовуєте.

Питання та відповіді

1) Чи безпечно запускати zdb -C в продакшені?

Це орієнтовано на читання і зазвичай безпечне, але «безпечно» залежить від вашого операційного контексту. Якщо зберігання вже відмовляє і кожен I/O викликає тайм-аути, навіть читання міток може додати навантаження. Використовуйте обережно.

2) Чому zdb -C показує шляхи, яких не існує?

Бо шляхи — підказки, а не ідентичність. ZFS зберігає той шлях, який останнім знав. Ідентичність — це GUID, часто пов’язаний з WWN/devid. Використовуйте by-id посилання і зіставлення GUID для узгодження.

3) У чому різниця між zdb -C і zpool import?

zpool import намагається зібрати і показати імпортовані пули, використовуючи відкриття ОС і евристики.
zdb -C виводить збережену конфігурацію з міток, навіть коли збірка не вдається.

4) Чи допоможе zdb -C, якщо ім’я пулу невідоме?

Так. Запустіть zdb -C без імені пулу, щоб просканувати пристрої і вивести знайдені конфігурації. Поєднуйте з zdb -l для конкретних пристроїв для ясності.

5) Що говорить txg під час відновлення?

Більший txg зазвичай означає новіші метадані. Якщо деякі мітки vdev показують значно старіший txg, цей пристрій, ймовірно, пропустив записи (був офлайн, пошкоджений або відключений). Це підказка, а не вирок.

6) Якщо я бачу невідповідність hostid — що робити?

Вважайте ризик реальним, поки не доведете протилежне. Переконайтеся, що інший хост вимкнений або немає шляхів доступу.
Потім імпортуйте обережно (часто з -N) і перевірте перед монтуванням чи записом.

7) Як флаги функцій в zdb -C впливають на помилки імпорту?

Пули можуть вимагати розуміння певних функцій. Якщо ваша система не підтримує потрібну функцію, імпорт
може зазнати краху. Виправлення зазвичай — оновлення OpenZFS, а не «форсування» імпорту.

8) Чому ZFS пам’ятає відсутній диск за числом (GUID), а не ім’ям пристрою?

Бо імена пристроїв нестабільні між завантаженнями і хостами. GUID — стабільна ідентичність, записана в мітках.
Це одне з найкращих дизайнерських рішень ZFS — особливо корисне о 03:00, коли ви втомлені.

9) Чи можна використати zdb -C, щоб спланувати безпечну заміну диска?

Так. Використовуйте його, щоб зіставити GUID листа і очікуваний by-id шлях/WWN, потім знайдіть це в апаратному інвентарі через
udevadm info. Це зменшує ймовірність замінити неправильний диск у mirror/raidz.

10) Що робити, якщо мітки пошкоджені на одному диску?

Якщо є надлишковість (mirror/raidz) і інші мітки цілі, ZFS зазвичай зможе імпортувати і відновити.
Якщо кілька пристроїв мають пошкоджені мітки — припиніть імпровізації і розглядайте ситуацію як відновлення даних:
стабілізуйте апарат, клонуйте диски за потреби і працюйте з найбільш повним набором міток, який можете прочитати.

Висновок: практичні кроки далі

zdb -C — це спосіб припинити гадання. Воно читає конфігурацію пулу прямо з міток диска і дає факти, які потрібні,
коли імпорт зазнає невдачі, пристрої перейменовуються або хтось наполягає «нічого не змінилося».

Наступні кроки, які можна зробити вже сьогодні, до наступного збою:

  • Додайте в рунабук розділ: zpool importzdb -Czdb -l з діагностичним деревом рішень.
  • Стандартизуйтесь на /dev/disk/by-id для імпортів і моніторингу, а не на /dev/sdX.
  • Архівуйте вихід zdb -C після важливих змін у сховище. Це дешева страховка і відмінна безвинна доказова інформація.
  • Навчіть команду зіставляти GUID з WWN та фізичними слотами. Це запобігає інцидентам «ми замінили неправильний диск».
← Попередня
AVX: інструкції, що пришвидшують навантаження — й роблять CPU гарячішими
Наступна →
WordPress «Максимальний час виконання перевищено»: чому це відбувається й безпечні виправлення

Залишити коментар