Відсутні шляхи пристроїв у ZFS: використовуємо by-id і WWN по-діловому

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

Ваш пул ZFS місяцями був у гарному стані, а після перезавантаження перетворюється на місце злочину: DEGRADED, один диск «UNAVAIL», а ім’я пристрою в zpool status
виглядає так, ніби його вибрав генератор випадкових чисел. Дані, ймовірно, в порядку. Проблема — в іменуванні.

Це розрив між «в лабораторії працювало» і «витримує продакшн»: стійкі шляхи пристроїв. Якщо ваш пул посилається на /dev/sdX,
ви вже вирішили, що наступний інцидент стане навчальним.

Чому /dev/sdX — пастка (і чому це повторюється)

/dev/sdX — це не ідентифікатор. Це посадкове місце. Linux видає ці букви в порядку виявлення, а порядок виявлення змінюється:
нова прошивка HBA, інше тренування слота PCIe, повільний диск, який відповідає пізніше після події живлення, таймінги multipath, скиди шасі — та що завгодно.
Ваш диск не став іншим диском. Ядро просто зустріло їх у іншому порядку.

ZFS цілком задоволений тим шляхом, який ви йому дали. Якщо ви створили пул як mirror /dev/sda /dev/sdb,
ZFS запише ті рядки. Пізніше, якщо /dev/sda вказує на інший диск, у вас дві проблеми:
ZFS не може знайти старий, і ви можете випадково «виправити» не той диск. Перше спричиняє деградацію пулу. Друге — оновлення в резюме.

Ліки — припинити використовувати ефемерні імена і почати використовувати стійкі ідентифікатори: /dev/disk/by-id і, зокрема, ідентифікатори на основі WWN.
Вони розроблені, щоб пережити перезавантаження, повторну нумерацію та більшість перестановок обладнання.

Жарт №1: Використовувати /dev/sdX у продакшні — це як маркувати сервери «той, що біля вікна». Працює, поки хтось не переставить стіл.

Цікаві факти та трохи історії

  • Факт 1: ZFS виникла в Sun Microsystems і була побудована навколо ідеї, що сховище може брехати; вона перевіряє дані наскрізно за контрольними сумами.
  • Факт 2: Імена пристроїв Linux на кшталт /dev/sda походять від підсистеми SCSI-дисків, навіть для SATA і USB-дисків, прокладених через SCSI-емуляцію.
  • Факт 3: WWN (World Wide Name) — глобально унікальний ідентифікатор із середовища Fibre Channel/SAS, пізніше застосований і для SATA через стандарти та адаптери.
  • Факт 4: Символьні посилання udev у /dev/disk/by-* існують саме тому, що нумерація пристроїв ядром нестабільна між перезавантаженнями.
  • Факт 5: ZFS зберігає мітки на диску (чотири мітки на члені vdev в типовій реалізації), тому пули часто можна імпортувати навіть коли шляхи змінилися.
  • Факт 6: Імена «by-path» кодують фізичний шлях з’єднання (шина PCI, порт HBA, слот шасі) і залишаються стабільними, поки ви не перемістите кабелі або HBA.
  • Факт 7: На ранніх етапах комодиті-накопичувачів серійні номери іноді дублювалися або форматувалися дивно мостовими контролерами; WWN зазвичай поводиться надійніше.
  • Факт 8: У мультипат-середовищах часто видно як вузли для кожного шляху, так і агрегований mapper-пристрій; вибір неправильного може спричинити «флапінг» пристроїв у ZFS.

Що варто використовувати: by-id, WWN і коли by-path прийнятний

Обирайте стійку ідентичність: символьні посилання на основі WWN

На більшості сучасних систем Linux ви знайдете символьні посилання під /dev/disk/by-id. Для SAS/SATA/NVMe зазвичай є кілька варіантів:
виробник/модель/серійний номер і часто WWN-подібний запис. WWN-записи звично виглядають як:
wwn-0x5000cca2... (SATA/SAS) або nvme-eui.000000... / nvme-uuid.... (NVMe).

Для ZFS віддавайте перевагу формам WWN/EUI/UUID, бо вони призначені бути глобально унікальними і рідше спотворюються USB–SATA мостом чи дивним HBA.
Якщо доступні лише символьні посилання vendor+serial, це також може бути прийнятно, але варто перевірити унікальність у всьому шассі.

Коли by-path корисний

/dev/disk/by-path показує, куди підключено диск. Це операційний скарб під час «знайди фізичний диск, щоб витягнути»
в шумному дата-центрі о 3:00 ночі. Але це не ідентичність, якщо плануєте перемістити диск на інший порт контролера. Це адреса.

Я використовую by-path для налагодження та картування слотів, а by-id/WWN — для членства в пулі. Такий розподіл зберігає здоровий глузд людей і стабільність пулів.

Чого уникати

  • Уникайте: постійного використання /dev/sdX. Навіть на «простих» серверах. Особливо на «простих» серверах.
  • Уникайте: використання цілого диска без розділів, якщо в середовищі є інструменти, що можуть записувати метадані (деякі інсталятори, деякі RAID-утиліти).
  • Уникайте: змішування mapper-мультипат-пристроїв і сирих шляхів всередині одного пулу.
  • Уникайте: покладатися на /dev/disk/by-label або мітки файлових систем для ідентифікації vdev у ZFS; це не їхнє призначення.

Як ZFS запам’ятовує пристрої (і що означає «відсутній шлях пристрою»)

ZFS не просто довіряє рядку шляху. Воно записує конфігурацію пулу і мітки vdev прямо на диски. Саме тому можна перенести пул на інший хост,
імпортувати його, і ZFS часто зможе визначити, що до чого належить. Але шлях має значення, бо ZFS спочатку намагається відкрити саме його, і саме його бачать оператори в оповіщеннях.

Ситуація «відсутній шлях пристрою» зазвичай потрапляє в одну з цих категорій:

  • Шлях змінився, диск присутній: диск в порядку, але ОС представила його під іншим вузлом. Класичний випадок «/dev/sdX» шардування.
  • Диск повністю відсутній: проблеми з HBA, бекплейном, живленням, кабелюванням, помилкова конфігурація multipath або реальний вихід диска з ладу.
  • Диск присутній, але відмовляється: невідповідність розміру сектора, застаріла таблиця розділів, неправильний диск-замінник або неправильний вузол пристрою (наприклад, одна стежка мультипату).
  • Права/таймінг udev: ранній імпорт під час завантаження, відсутні правила udev в initramfs або шари шифрування ще не відкриті.

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

Одне висловлювання варто прикріпити на стікері (парафразована ідея): Надія — не стратегія. У сфері зберігання це часто дуже буквально.

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

Це порядок дій, який я застосовую, коли дзвінок каже «ZFS DEGRADED», і хтось вже питає, чи треба фейловерити. Мета — швидко знайти вузьке місце:
чи то іменування, чи підключення, чи відмова пристрою?

Спочатку: підтвердіть, що ZFS вважає відсутнім

  • Запустіть zpool status -P, щоб вивести повні шляхи і зафіксувати точну назву «UNAVAIL».
  • Перевірте, чи відсутній запис — це сирий диск, розділ чи mapper-пристрій.

Друге: підтвердіть, чи ОС бачить диск за стійкими ідентифікаторами

  • Перегляньте /dev/disk/by-id і /dev/disk/by-path.
  • Використайте lsblk -o NAME,SIZE,MODEL,SERIAL,WWN,HCTL,TYPE,MOUNTPOINTS, щоб зв’язати ідентичність із топологією.

Третє: вирішіть, чи це «дрейф шляху», чи «втрата обладнання»

  • Якщо WWN існує і відповідає інвентарю/записам, ймовірно, це дрейф імен. Використайте zpool online або zpool replace з правильним by-id шляхом.
  • Якщо WWN відсутній або диск відсутній у lsblk, перевірте журнали ядра (dmesg) і стан контролера.

Четверте: припиніть робити гірше

  • Не витягуйте диски, орієнтуючись на /dev/sdX.
  • Не запускайте zpool clear як «ремонт». Це лише очищає помилки; не повертає диски до життя.

П’яте: оберіть найменшу безпечну дію

  • Для чистого дрейфу шляху: оновіть ZFS до стійкого шляху через replace (навіть заміну пристрою самим собою, використовуючи стійке ім’я).
  • Для реально відмовившого пристрою: замініть його на новий та дочекайтеся resilver. Якщо є помилки контрольних сум в інших місцях, вважайте пул потенційно ураженим і зробіть scrub.

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

Це реальні речі, які ви запускаєте в консолі. Кожна включає, що означає її вивід і яке рішення має спричинити.
Використовуйте їх як будівельні блоки; не переносіть механічно в скрипти без розуміння середовища (multipath і шари шифрування змінюють правила).

Завдання 1: Перевірка стану пулу з повними шляхами

cr0x@server:~$ sudo zpool status -P
  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
            /dev/sda2                             UNAVAIL      0     0     0  cannot open
            /dev/disk/by-id/wwn-0x5000c500a1b2c3d4-part2  ONLINE       0     0     0

errors: No known data errors

Що це означає: ZFS відсутній /dev/sda2. Інша сторона mirror присутня. Це сильно нагадує дрейф шляху.
Рішення: Поки що не міняйте обладнання. Спочатку знайдіть, який диск раніше був /dev/sda, і переприйміть ZFS на by-id шлях.

Завдання 2: Підтвердити, що диск існує в by-id

cr0x@server:~$ ls -l /dev/disk/by-id/ | sed -n '1,12p'
total 0
lrwxrwxrwx 1 root root  9 Dec 26 02:10 ata-SAMSUNG_MZ7KM960HAHP-00005_S3Z1NX0K123456 -> ../../sdb
lrwxrwxrwx 1 root root 10 Dec 26 02:10 ata-SAMSUNG_MZ7KM960HAHP-00005_S3Z1NX0K123456-part2 -> ../../sdb2
lrwxrwxrwx 1 root root  9 Dec 26 02:10 wwn-0x5002538d4098abcd -> ../../sdb
lrwxrwxrwx 1 root root 10 Dec 26 02:10 wwn-0x5002538d4098abcd-part2 -> ../../sdb2
lrwxrwxrwx 1 root root  9 Dec 26 02:10 wwn-0x5000c500a1b2c3d4 -> ../../sdc
lrwxrwxrwx 1 root root 10 Dec 26 02:10 wwn-0x5000c500a1b2c3d4-part2 -> ../../sdc2

Що це означає: У вас є стійкі дескриптори. Відсутній /dev/sda2 імовірно став /dev/sdb2 або /dev/sdc2.
Рішення: Визначте, який WWN належить відсутньому члену vdev (через мітки ZFS або попередні записи), потім приєднайте його через той by-id шлях.

Завдання 3: Зв’язати вузли пристроїв з WWN/серією/топологією в одному вигляді

cr0x@server:~$ lsblk -o NAME,SIZE,MODEL,SERIAL,WWN,HCTL,TYPE,MOUNTPOINTS
NAME   SIZE MODEL              SERIAL          WWN                HCTL       TYPE MOUNTPOINTS
sdb  893.8G SAMSUNG MZ7KM960   S3Z1NX0K123456  0x5002538d4098abcd 1:0:0:0    disk
├─sdb1   1G                                      0x5002538d4098abcd 1:0:0:0  part
└─sdb2 892G                                      0x5002538d4098abcd 1:0:0:0  part
sdc  893.8G SAMSUNG MZ7KM960   S3Z1NX0K654321  0x5000c500a1b2c3d4  2:0:0:0    disk
├─sdc1   1G                                      0x5000c500a1b2c3d4 2:0:0:0  part
└─sdc2 892G                                      0x5000c500a1b2c3d4 2:0:0:0  part

Що це означає: Тепер ви можете говорити в термінах ідентичностей (WWN/серія) і фізичних кінцевих точок (HCTL).
Рішення: Якщо у вас є ранбук або примітки, що маплять WWN у слот, тут закінчується вгадування.

Завдання 4: Швидко шукати помилки на рівні ядра

cr0x@server:~$ dmesg -T | egrep -i 'sd[a-z]|nvme|ata|sas|scsi|reset|I/O error|timed out' | tail -n 20
[Thu Dec 26 02:09:51 2025] sd 2:0:0:0: [sdc] tag#13 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_OK cmd_age=0s
[Thu Dec 26 02:09:51 2025] sd 2:0:0:0: [sdc] tag#13 Sense Key : Not Ready [current]
[Thu Dec 26 02:09:51 2025] sd 2:0:0:0: [sdc] tag#13 Add. Sense: Logical unit not ready, cause not reportable
[Thu Dec 26 02:09:52 2025] sd 2:0:0:0: [sdc] tag#21 timing out command, waited 180s
[Thu Dec 26 02:10:04 2025] scsi 2:0:0:0: rejecting I/O to offline device

Що це означає: Це не «тільки іменування». Шлях диску/контролера хворий: таймаути та «offline device».
Рішення: Розглядайте як проблему апаратного підключення. Перевірте кабелі/бекплейн/HBA і плануйте заміну. Не просто oneline-те й сподівайтесь.

Завдання 5: Запитати події ZFS, щоб побачити останні зміни пристроїв

cr0x@server:~$ sudo zpool events -v | tail -n 25
TIME                           CLASS
Dec 26 02:10:06.912726000      resource.fs.zfs.statechange
  pool = tank
  vdev_guid = 11801824156334312345
  vdev_path = /dev/sda2
  vdev_state = UNAVAIL
  vdev_ashift = 12
Dec 26 02:10:07.102938000      resource.fs.zfs.statechange
  pool = tank
  vdev_guid = 9938450195345123456
  vdev_path = /dev/disk/by-id/wwn-0x5000c500a1b2c3d4-part2
  vdev_state = ONLINE
  vdev_ashift = 12

Що це означає: ZFS вважає, що /dev/sda2 був реальним шляхом vdev. Ви також дізнаєтесь ashift (важливо при заміні).
Рішення: Якщо плануєте replace, підберіть відповідний ashift. Також використовуйте ці події для хроніки інциденту; вони часто ясніші за шум syslog.

Завдання 6: Знайти відсутній vdev за GUID у мітках на диску

cr0x@server:~$ sudo zdb -l /dev/disk/by-id/wwn-0x5002538d4098abcd | sed -n '1,40p'
------------------------------------
LABEL 0
------------------------------------
    version: 5000
    name: 'tank'
    state: 0
    txg: 1923481
    pool_guid: 8012456789012345678
    vdev_tree:
        type: 'disk'
        id: 0
        guid: 11801824156334312345
        path: '/dev/sda2'
        phys_path: 'pci-0000:3b:00.0-sas-0x5000c500d00dbeef-lun-0'

Що це означає: Ви знайшли диск, який ZFS вважає /dev/sda2. Мітка навіть зберігає старий шлях.
Рішення: Цей диск — ваш відсутній член. Тепер можете повторно прив’язати його під стійким шляхом без вгадувань, який саме sdX це сьогодні.

Завдання 7: Заміна пристрою самим собою, щоб оновити шлях на by-id

cr0x@server:~$ sudo zpool replace tank /dev/sda2 /dev/disk/by-id/wwn-0x5002538d4098abcd-part2
invalid vdev specification
use '-f' to override the following errors:
/dev/disk/by-id/wwn-0x5002538d4098abcd-part2 is part of active pool 'tank'

Що це означає: ZFS захищає вас від неоднозначних дій. Ви намагаєтесь «замінити» пристрій тим, що вже в пулі.
Рішення: Використайте -f навмисно при трюку «replace-with-self», щоб перезаписати збережений шлях на стійкий симлинк.

cr0x@server:~$ sudo zpool replace -f tank /dev/sda2 /dev/disk/by-id/wwn-0x5002538d4098abcd-part2

Що це означає: Немає новин — це добре. ZFS прийняла нове відображення шляху.
Рішення: Повторно запустіть zpool status -P і підтвердіть, що пул тепер посилається на by-id записи скрізь.

Завдання 8: Підняти пристрій онлайн після транзитної втрати

cr0x@server:~$ sudo zpool online tank /dev/disk/by-id/wwn-0x5000c500a1b2c3d4-part2
bringing device online

Що це означає: ZFS спробує відновити I/O. Якщо базовий шлях все ще падає, воно знову впаде.
Рішення: Якщо диск постійно відключається, перестаньте вважати це транзитним. Передайте на апаратне обстеження і плануйте заміну.

Завдання 9: Слідкуйте за прогресом resilver уважно

cr0x@server:~$ sudo zpool status -P tank
  pool: tank
 state: DEGRADED
status: One or more devices is currently being resilvered.
config:

        NAME                                              STATE     READ WRITE CKSUM
        tank                                              DEGRADED     0     0     0
          mirror-0                                        DEGRADED     0     0     0
            /dev/disk/by-id/wwn-0x5002538d4098abcd-part2  ONLINE       0     0     0  (resilvering)
            /dev/disk/by-id/wwn-0x5000c500a1b2c3d4-part2  ONLINE       0     0     0

scan: resilver in progress since Thu Dec 26 02:14:03 2025
        128G / 892G scanned at 1.12G/s, 6.5G / 892G issued at 58.1M/s, 0% done, 04:14:23 to go

Що це означає: Issued — це те, що реально записується. Якщо scanned швидко, а issued повільно, ви обмежені записами, а не читаннями.
Рішення: Якщо час resilver занадто великий, подумайте про зниження навантаження, перевірте наявність SMR-дисків або дослідіть тротлінг контролера.

Завдання 10: Підтвердити, що кожен vdev тепер використовує стійкі шляхи

cr0x@server:~$ sudo zpool status -P | egrep '/dev/(sd|vd|xvd)'

Що це означає: Немає виводу — це мета: означає, що ви не посилаєтесь на ефемерні вузли.
Рішення: Якщо ви все ще бачите /dev/sd*, сплануйте контрольоване обслуговування, щоб переписати їх через replace-with-self.

Завдання 11: Визначити, чи ви випадково використовуєте окремий шлях у мультипат-середовищі

cr0x@server:~$ lsblk -o NAME,TYPE,SIZE,WWN,PKNAME | egrep 'mpath|dm-|sd[a-z] '
sda  disk  1.8T 0x600508b1001c2d3e4f5a6b7c8d9e0001
dm-2 mpath 1.8T 0x600508b1001c2d3e4f5a6b7c8d9e0001
sdb  disk  1.8T 0x600508b1001c2d3e4f5a6b7c8d9e0001

Що це означає: Той самий WWN з’являється на кількох sd* вузлах (різні шляхи), і також на dm-2 як мультипат-пристрій.
Рішення: Для ZFS в мультипаті зазвичай бажаний агрегований mapper-пристрій (наприклад /dev/mapper/mpath*) або стабільний DM-путь,
а не одна з сирих ніжок /dev/sd*. Змішування викликає періодичні «видалення пристрою».

Завдання 12: Показати властивості udev для конкретного диска (чому змінився by-id?)

cr0x@server:~$ udevadm info --query=property --name=/dev/sdb | egrep 'ID_SERIAL=|ID_WWN=|ID_MODEL=|ID_PATH='
ID_MODEL=SAMSUNG_MZ7KM960HAHP-00005
ID_SERIAL=SAMSUNG_MZ7KM960HAHP-00005_S3Z1NX0K123456
ID_WWN=0x5002538d4098abcd
ID_PATH=pci-0000:3b:00.0-sas-0x5000c500d00dbeef-lun-0

Що це означає: udev показує WWN і фізичний шлях. Якщо ID_WWN відсутній, ви можете бути за мостом, який не повідомляє його.
Рішення: Якщо WWN відсутній, використайте найбільш стабільний доступний by-id запис і перевірте унікальність серед усіх дисків.

Завдання 13: Перевірити таблицю розділів і переконатися, що ви використовуєте правильний розділ

cr0x@server:~$ sudo sgdisk -p /dev/disk/by-id/wwn-0x5002538d4098abcd
Disk /dev/disk/by-id/wwn-0x5002538d4098abcd: 1875385008 sectors, 894.3 GiB
Sector size (logical/physical): 512/4096 bytes
Disk identifier (GUID): 7A2B2C0D-9D2A-4B4A-8C31-2E1DA1A0C9B8
Partition table holds up to 128 entries
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         2099199   1024.0 MiB  EF00  EFI System
   2         2099200      1875384319   893.3 GiB   BF01  ZFS

Що це означає: Ви можете підтвердити, який розділ є членом ZFS (тут код розділу BF01).
Рішення: Якщо ви випадково вказали ZFS на цілий диск, коли ваш стандарт — розділи (або навпаки), зупиніться і виправте перед заміною.

Завдання 14: Імпорт пулу, коли шляхи змінилися (спочатку в безпечному режимі)

cr0x@server:~$ sudo zpool import
   pool: tank
     id: 8012456789012345678
  state: DEGRADED
 action: The pool can be imported despite missing or damaged devices.
 config:

        tank                                      DEGRADED
          mirror-0                                DEGRADED
            11801824156334312345                  UNAVAIL  cannot open
            wwn-0x5000c500a1b2c3d4-part2           ONLINE

Що це означає: ZFS може побачити пул, читаючи мітки, навіть якщо один vdev відсутній. Зверніть увагу: воно показує GUID замість шляху для відсутнього.
Рішення: Імпортуйте лише в режимі тільки для читання, якщо ви не впевнені, чи дивитесь на правильні диски, особливо в спільних сховищах.

cr0x@server:~$ sudo zpool import -o readonly=on -d /dev/disk/by-id tank
cannot import 'tank': one or more devices is currently unavailable

Що це означає: Навіть із явним скануванням by-id щось настільки відсутнє, що блокує імпорт (політика залежить від топології vdev).
Рішення: Не форсуйте імпорт, якщо не розумієте рівень відмовостійкості. Знайдіть відсутній пристрій через кабелі/журнали HBA або підтвердьте, що у вас достатньо реплік.

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

Міні-історія 1: Інцидент, спричинений хибним припущенням

Середня компанія експлуатувала платформу VM на кількох серверах зі ZFS. Нічого екзотичного: полиці SAS, mirror vdev, пристойний моніторинг.
Пул спочатку створили під час «термінового міграційного вікенду», і саме так народжується технічний борг. Члени vdev додавалися, використовуючи /dev/sdX.

Через кілька місяців додали новий HBA і перемістили кабель полиці, щоб привести стійку до ладу. Наступне перезавантаження принесло деградований пул і один член vdev «відсутній».
Інженер на виклику побачив відсутність /dev/sdc і припустив, що це «третій диск у тій шасі», бо людям подобається порядкове мислення.
Він витягнув те, що вважав правильним диском, замінив його і запустив zpool replace на новому /dev/sdc.

Система прийняла команду. Звісно, тому що /dev/sdc існував. Просто це не був той диск, який вони думали. «Відсутній» диск був присутній,
перейменований на /dev/sdf після зміни контролера. Тим часом вони фізично вийняли цілком здорову сторону mirror і поставили чистий диск.
Короткий час почався resilver, поки залишився оригінальний диск тримав весь vdev один.

Наступний поворот був передбачуваний і жорстокий: під час resilver залишився оригінальний диск почав видавати помилки читання. Старість, латентні сектора, що завгодно.
Тепер єдиний хороший копій деяких блоків був на диску, який витягли. Результат — не повна втрата пулу, але пошкоджені образи VM і тиждень чистки.
Постмортем був прямим: тригером не була «відмова диска», а те, що «ми трактували /dev/sdX як ідентичність».

Вони перебудували операційну практику навколо найменування WWN і додали правило: ніхто не торкається лотка, поки WWN на консолі не співпаде з WWN на фізичній етикетці.
Це уповільнило заміни на п’ять хвилин. Це врятувало їх від самих себе назавжди.

Міні-історія 2: Оптимізація, що повернулась бумерангом

Інша команда мала інженера, який любив охайні системи. Він хотів, щоб імена vdev відображали номери слотів, тому стандартизувався на /dev/disk/by-path.
У zpool status це виглядало красиво: можна було показати ліхтариком на стійку і знайти диск швидко.

Потім закупівля підкинула нову модель SAS HBA, бо стара була «end of life». Той самий виробник, той самий тип кабелю, ті ж полиці. Команда апаратного забезпечення оновила картки.
Раптом всі симлінки by-path змінились, бо адреси PCI та нумерація SAS-експандера змінились. З дисками нічого не сталося. «Адреси» змінились.

Імпорт ZFS почав давати збої під час раннього завантаження, бо initramfs не мав оновлених правил udev і бо by-path імена ще не створені.
Оператори пробували латати це, додаючи затримки в скрипти завантаження. Це не інженерія; це забобони.

Вони врешті мігрували на WWN-орієнтований by-id для членства в пулі і зберегли by-path лише для інструментів мапування людей. «Оптимізація» дала читабельність у ZFS,
але перетворила конфіг пулів на заручників топології шини. Гарно для діаграм; жахливо для надійності.

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

Велика команда підприємства експлуатувала пули ZFS для артефактів збірки і образів контейнерів. Середовище навмисно було нудним: mirror vdev,
гарячі спари і письмовий стандарт: всі пули використовують WWN-based by-id і лише розділи; після заміни завжди scrub після resilver.
Нікому це не подобалось. Це була процедура.

Одного вікенду стрибок напруги підкинув стійку. Після перезавантаження один сервер піднявся з деградованим пулом і двома дисками з дивною поведінкою в логах ядра.
На виклику одразу визначили, які фізичні диски задіяні, бо їхній ранбук зберігав WWN і мапу слотів шасі.
Вони не гадали. Не «пробували кілька команд». Виконали чекліст.

Один диск був справді мертвий. Інший був цілий, але переенумерувався. Оскільки пул використовував стійкі WWN-шляхи, ZFS не заплутався.
Єдиною дією була заміна мертвого диска і дозволення resilver. Система продовжувала обслуговувати весь час з передбачуваною продуктивністю.

Тиха перемога полягала в тому, що нічого дивного не сталося. Менеджмент про це не дізнався. Ось сенс нудної практики: інциденти, що не перетворюються на наради.

Міграція існуючого пулу на стійкі шляхи (без драм)

Якщо ви побудували пул з /dev/sdX, можна виправити це без перебудови. Техніка проста: замініть кожен член vdev
самим собою, але вказаним через стійкий by-id шлях. ZFS оновить збережений шлях, і у вашому майбутньому zpool status перестане брехати.

Правила перед роботою в продакшні

  • Підтвердіть унікальність: Переконайтеся, що кожне by-id ім’я, яке ви плануєте використати, відповідає точно одному диску.
  • Віддавайте перевагу розділам: Якщо ви стандартизувалися на -part2 (або подібному), дотримуйтеся цього. Послідовність важлива для автоматизації замін і безпеки.
  • По одному диску: Особливо на RAIDZ, де помилку важче відкотити, але й на mirror теж — люди стають надто впевненими.
  • Зафіксуйте стан: Збережіть вивід zpool status -P до і після змін.

Практична послідовність міграції

Почніть зі списку пулу з повними шляхами. Потім для кожного члена, що є сирим /dev/sd* шляхом, знайдіть відповідний by-id і виконайте примусову replace.
Приклад для mirror-члена, записаного як /dev/sda2:

cr0x@server:~$ sudo zpool status -P tank
  pool: tank
 state: ONLINE
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            /dev/sda2  ONLINE     0     0     0
            /dev/sdb2  ONLINE     0     0     0

Тепер співставте /dev/sda2 зі стійким ID:

cr0x@server:~$ readlink -f /dev/disk/by-id/wwn-0x5002538d4098abcd-part2
/dev/sda2

Потім замініть самим собою, щоб переписати збережений шлях:

cr0x@server:~$ sudo zpool replace -f tank /dev/sda2 /dev/disk/by-id/wwn-0x5002538d4098abcd-part2

Повторіть для кожного решти /dev/sd* члена. Коли закінчите, zpool status -P повинен показувати лише by-id шляхи.
Якщо ви все ще бачите поодинокий /dev/sdX, не ігноруйте його. Саме так стандарти помирають: одне виключення за раз.

Жарт №2: Аварії в зберіганні нагадують стоматологію — їх можна уникнути регулярним технічним обслуговуванням, але люди віддають перевагу вчитися складним шляхом.

Типові помилки: симптом → причина → виправлення

1) Пул показує UNAVAIL для /dev/sdX після перезавантаження

Симптоми: zpool status показує відсутній шлях /dev/sdX; диски «перемістились».

Причина: Перенумерація пристроїв ядром; ZFS записав нестабільні імена.

Виправлення: Визначте правильний диск за WWN/серією (lsblk, zdb -l) і перепишіть шляхи за допомогою zpool replace -f на by-id.

2) Заміна диска «працює», але починає resilver неправильний диск

Симптоми: Resilver починається на диску, який ви не мали на увазі; інший диск стає відсутнім; паніка.

Причина: Ви використали /dev/sdX і замінили неправильний вузол, або неправильно ідентифікували фізичний диск і логічний пристрій.

Виправлення: Зупиніться. Підтвердіть WWN і мітки ZFS. Використайте zpool status -P, lsblk і zdb -l. Якщо потрібно, offline-те помилково цільовий пристрій і перепроаналізуйте перед продовженням.

3) Імпорт пулу не вдається під час раннього завантаження, але працює вручну пізніше

Симптоми: Система завантажується без пулу; ручний zpool import пізніше проходить.

Причина: Симлінки udev відсутні в initramfs; гонка між виявленням пристроїв і сервісом імпорту; шари шифрування не відкриті.

Виправлення: Переконайтеся, що initramfs містить необхідні правила udev і модулі; впорядкуйте сервіси так, щоб блок-пристрої з’являлися до імпорту; для зашифрованих vdev забезпечте запуск zfs-load-key/cryptsetup перед імпортом/монтуванням.

4) Пристрої постійно переходять ONLINE/OFFLINE під навантаженням

Симптоми: Логи ядра показують таймаути; ZFS відмічає vdev як offline; повертається і повторюється.

Причина: Поганий кабель, бекплейн, проблеми прошивки HBA або використання одношляхового пристрою в мультипат-середовищі.

Виправлення: Перевірте dmesg, підтвердіть конфігурацію multipath, замініть підозрілий кабель/слот бекплейна, оновіть прошивку після верифікації. Для мультипату віддавайте перевагу агрегованим mapper-пристроям.

5) Імена by-id змінились після оновлення прошивки

Симптоми: Симлінк by-id диска виглядає інакше ніж раніше (формат серійного номера, префікс вендора).

Причина: Прошивка/мостові контролери можуть змінити, як повертаються інфо-запити; правила udev формують ID з цих рядків.

Виправлення: Віддавайте перевагу WWN/EUI ідентифікаторам; перевірте через udevadm info. Якщо ідентифікатори змінились, оновіть шляхи ZFS через replace-with-self на нову стійку форму.

6) Ви використовували by-path, потім перемістили кабелі під час обслуговування

Симптоми: Пул піднявся деградованим; всі «адреси» виглядають інакше; оператори наполягають «диски в тих самих слотах».

Причина: by-path кодує топологію підключення; переміщення кабелю чи HBA її змінює.

Виправлення: Використовуйте by-id/WWN для членства в пулі. Залишайте by-path для картографування/світлодіодних робіт, а не як авторитетний ідентифікатор у ZFS.

7) Диск-замінник приєднався, але під час resilver працює дуже повільно

Симптоми: Resilver повзає; пінги зростають; «issued» пропускна здатність низька.

Причина: SMR-диск у навантаженні, що очікує CMR; політика кешу контролера; невідповідність розміру сектора спричиняє read-modify-write; велике виробниче навантаження.

Виправлення: Перевірте модель диска, політику кешу і розміри секторів. Розгляньте використання відомого класу дисків для заміни і зниження навантаження під час resilver.

8) ZFS бачить диск, але відмовляється використовувати без -f

Симптоми: zpool replace скаржиться, що пристрій є частиною активного пулу або має існуючі мітки.

Причина: Ви замінюєте шлях (перезапис), або диск має застарілі мітки ZFS від попереднього членства.

Виправлення: Для перепису шляху використайте zpool replace -f навмисно. Для справжнього нового диска очистіть мітки командою zpool labelclear на правильному пристрої перед продовженням.

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

Чекліст A: Створити новий пул по-діловому

  1. Ідентифікуйте диски за WWN/EUI/UUID, а не за /dev/sdX.
  2. Використовуйте розділи послідовно (наприклад, -part2 для членів ZFS).
  3. Запишіть мапу WWN → слот шасі/відсік у вашому ранбуці.
  4. Створюйте пул, використовуючи шляхи /dev/disk/by-id/wwn-...-partN.
  5. Негайно перевірте zpool status -P, щоб переконатися, що ZFS зберіг by-id шляхи.
  6. Проведіть scrub після «виробничого пригорання» і періодично; використовуйте scrub як раннє попередження, а не як опціональну гігієну.

Чекліст B: Після перезавантаження пул деградований з відсутнім шляхом

  1. Запустіть zpool status -P і зафіксуйте вивід.
  2. Перевірте lsblk -o NAME,SIZE,MODEL,SERIAL,WWN,HCTL для ідентифікації відсутнього диска.
  3. Пошукайте в dmesg помилки I/O/таймаути. Якщо є — вважайте апаратну проблему до доведення протилежного.
  4. Використайте zdb -l на кандидатах у by-id, щоб зіставити GUID/шлях vdev.
  5. Якщо це дрейф шляху: zpool replace -f на by-id шлях і підтвердіть стан.
  6. Якщо це втрата обладнання: заплануйте заміну; не намагайтеся «очистити» фізику.

Чекліст C: Контрольована міграція зі sdX на by-id в існуючому пулі

  1. Заплануйте вікно техобслуговування, якщо пул критичний; це безпечно, але безпека включає людей і час.
  2. Запустіть zpool status -P і знайдіть усі записи /dev/sd*.
  3. Для кожного підтвердіть, що цільовий симлінк by-id резолвиться в той само розділ (readlink -f).
  4. Запускайте zpool replace -f pool oldpath new-by-id-path по одному пристрою за раз.
  5. Після кожної зміни перезапускайте zpool status -P і підтверджуйте, що новий шлях збережено.
  6. Коли завершите, прогляньте на наявність залишків /dev/sd і виправте їх.
  7. Задокументуйте список WWN у вашому ранбуці і, якщо є, у CMDB.

Чекліст D: Заміна диска без створення саспенсу

  1. Ідентифікуйте збійний диск за WWN у виводі ZFS, а не за буквою пристрою.
  2. Зіставте WWN з фізичним слотом за вашою картиною шасі.
  3. Виведіть vdev-член з онлайну (якщо він ще ONLINE, але підозрілий) перед витяганням апаратури.
  4. Вставте заміну і підтвердіть, що її WWN і розмір відповідають очікуванням.
  5. Розмітьте розділи послідовно (або скопіюйте таблицю розділів зі здорового брата).
  6. Запустіть zpool replace використовуючи by-id шляхи, потім моніторте resilver до завершення.
  7. Після resilver запустіть scrub і уважно проаналізуйте помилки контрольних сум.

FAQ

1) Якщо ZFS зберігає мітки на диску, навіщо взагалі важливі шляхи?

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

2) Використовувати /dev/disk/by-id чи /dev/disk/by-uuid?

Для vdev ZFS використовуйте /dev/disk/by-id (стилі WWN/EUI/UUID). by-uuid зазвичай стосується UUID файлових систем; ZFS — не «файлова система на блочному пристрої» в цьому сенсі.

3) Чи достатньо vendor+serial у by-id?

Часто так, особливо для корпоративних SAS/SATA дисків. Але WWN/EUI зазвичай кращий. Якщо ви за мостом USB або дешевим контролером,
vendor+serial може бути ненадійним або дубльованим. Перевірте унікальність перед довірою.

4) А як щодо NVMe? /dev/nvme0n1 теж змінюється.

Правильно. Нумерація NVMe контролерів може змінюватись. Використовуйте by-id записи, як nvme-eui.* або nvme-uuid.* для членства в ZFS.
Ставтеся до nvme0n1 як до тимчасового прізвиська.

5) Чи можна змінити шляхи vdev без resilver?

Заміна пристрою самим собою для оновлення шляху зазвичай не вимагає копіювання даних, якщо це дійсно той самий пристрій.
ZFS може виконати деякі перевірки. Важливо — переконатися в ідентичності спочатку (WWN + zdb -l).

6) Використовувати цілі диски чи розділи для vdev?

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

7) Що означає «cannot open» у zpool status?

Це означає, що ZFS намагалося відкрити записаний шлях і зазнало невдачі. Це може бути через те, що шлях більше не існує (перейменований),
пристрій зник або права/доступність неправильні під час завантаження. Наступний крок — перевірка видимості ОС (lsblk, dmesg, /dev/disk/by-id).

8) Чи колись by-path — правильний вибір для ZFS?

Рідко, і лише якщо ваша операційна модель трактує фізичне підключення як стійку ідентичність (фіксований бекплейн, без перестановок кабелів і постійні контролери),
і ви готові прийняти, що обслуговування апаратури може переписати «ідентичності». Більшість команд так не працюють. Використовуйте WWN для ідентичності; by-path для локації.

9) Мій симлінк by-id вказує на інший sdX після перезавантаження. Це погано?

Це нормально і саме через це існує by-id. Симлінк слідує за ідентичністю диска, навіть коли буквене призначення ядра змінюється.
ZFS має посилатися на симлінк, а не на underlying sdX.

10) Чи можу я імпортувати пул, скануючи лише /dev/disk/by-id?

Так, з zpool import -d /dev/disk/by-id. Це може зменшити неоднозначність на хостах із великою кількістю транзитних пристроїв.
Це не вирішить відсутність апаратури, але допоможе уникнути імпорту неправильного пулу з неправильного набору дисків.

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

Якщо ви запам’ятаєте одне: /dev/sdX — це не ідентичність диска. Це настрій ядра. ZFS вірно запам’ятовує те, що ви йому скажете,
і це заспокійливо доти, поки не стане джерелом проблем.

Практичні кроки:

  1. Запустіть zpool status -P на кожному хості і перевірте наявність /dev/sd* (або /dev/nvme*) у шляхах vdev.
  2. Для кожного нестабільного запису зіставте його з WWN-based by-id симлінком і виконайте контрольовану заміну самим собою за допомогою zpool replace -f.
  3. Запишіть мапу WWN → слоти і тримайте її доступною для on-call.
  4. Оновіть стандарти: нові пули створюють лише з by-id/WWN шляхами, послідовно розміченими розділами.
  5. Коли пул деградує, дотримуйтеся плану: ідентифікуйте, підтвердіть, а потім дійте. Ніяких вгадувань. Ніякого «clear і молитви».

Зробіть це один раз правильно, і наступного разу, коли буква диска зміниться, ви й не помітите. Це найкраща похвала, яку може дати продакшн.

← Попередня
Бум метавсесвіту: як «майбутнє» стало мемом за одну ніч
Наступна →
Docker CPU на 100%: Знайдіть шумний контейнер і правильно обмежте його

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