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

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

Все добре, поки пул не починає підводити. Сьогодні ви виконували рутинний zfs send; вже завтра хтось присилає вам у Slack скриншот з checksum error, ніби це гороскоп. Ви запускаєте zpool status, воно невизначено вказує на «corrupted data», і ваша впевненість отримує невеликий, але помітний удар по IOPS.

Ось тут і з’являється zdb. Це відладник ZFS: ліхтарик, який одночасно може бути лазером. Він скаже вам, що ZFS насправді бачить на диску, а не те, що ввічливі високорівневі інструменти звітують. Це також інструмент, якого люди уникають, поки він не знадобиться — бо він гострий, частково недокументований і не соромиться показувати незручні істини.

Що таке zdb (і чим він не є)

zdb — це інструмент інспекції ZFS. Якщо zpool — ваша панель управління флотом, а zfs — інтерфейс продукту, то zdb — це інженерська консоль з відкритою кришкою. Він читає структури на диску і може вивести внутрішні метадані: блокові вказівники, набори об’єктів, датасети, метаслаби, MOS (Meta Object Set), прапорці функцій, DDT (dedup tables), облік простору spacemap та інше. Це не «інструмент для ремонту» в тому сенсі, як на це сподіваються люди. Це інструмент правди. Відновлення зазвичай роблять scrub-ми, resilver-и, заміна апаратури або відновлення з відомих коректних копій.

Страх щодо zdb не є ірраціональним. Це «debugger» у буквальному сенсі: він показує вам внутрішню разводку, включно з місцями, де вона може вибухнути. І у нього є опції, які можуть бути дорогими або руйнівними, якщо запускати їх необережно на продакшн-системі в піковий час. Більшість часу ви використовуватимете його в режимі тільки для читання та безпечним способом. Ви питатимете: «Що ZFS бачить?» а не «Чи можу я ткнути сюди, поки щось зміниться?»

У чому zdb прекрасний

  • Підтвердження обліку простору: чому df не погоджується з zfs list, чому «used» не сходиться і куди пішли байти.
  • Пояснення продуктивності: фрагментація метаслабів, поведінка recordsize, коефіцієнти стиснення, непрямі блоки та чому vdev «кричить».
  • Дослідження корупції: зіставлення помилок до датасетів і іноді до об’єктів/блоків, особливо в парі з zpool status -v та результатами scrub.
  • Розуміння функцій: перевірка, що ввімкнено, активно або потрібне в пулі.
  • Форензика: іноді ідентифікація об’єктів, пов’язаних із шляхами, і розуміння змін між снапшотами.

Чим zdb не є

  • Не рутинний моніторинговий інструмент: його не варто запускати в cron щогодини по всіх пулах. Не робіть із глибоких дебаг-сканів «спостережуваність» за замовчуванням.
  • Не чарівна кнопка «відновити видалене»: ZFS — copy-on-write; снапшоти — ваш «undelete». Якщо їх немає, zdb може допомогти форензикою, але рідко робить чудеса.
  • Не заміна для scrub-ів: zpool scrub — це спосіб перевірити й виправити контрольні суми. zdb може вказати і пояснити; scrub може відновити (якщо є надмірність).

Корисний підхід: zdb — це мікроскоп, а не дефібрилятор. Якщо ви намагаєтеся «повернути пул до життя», ваші реальні інструменти — заміна апаратури, опції імпорту/відновлення, бекапи й спокій.

Цікаві факти та історія, що мають значення

Трохи контексту робить zdb менш містичним і більш механічним. Ось кілька конкретних моментів, які впливають на те, як варто про нього думати.

  1. ZFS народився в Sun Microsystems як файлово-томний менеджер з кінця в кінець для цілісності даних, а zdb — частина культури «довіряй, але перевіряй», вбудованої в інструменти.
  2. zdb існує тому, що метадані ZFS багаті: набори об’єктів, dnode, блокові вказівники, контрольні суми та карти простору — усе це першокласні елементи. Інструмент фактично друкує метадані з власними коментарями.
  3. Сучасні реалізації ZFS розбіжні (Illumos, OpenZFS, порти вендорів). Вивід і прапорці zdb можуть відрізнятися між платформами й версіями — сприймайте приклади в інтернеті як ескізи, а не догму.
  4. Прапорці функцій замінили номери версій у еволюції формату пулу на диску. zdb — один із найчистіших способів побачити, які функції ввімкнені й активні в пулі.
  5. Copy-on-write змінює нарратив про «корупцію»: старі блоки не перезаписуються на місці. Це добре для консистентності й снапшотів, але змінює міркування про «файл, який пошкодився вчора».
  6. Семантика scrub/resilver має значення: ZFS може відновити з надмірності, якщо знає, яка копія правильна (через контрольні суми). zdb допомагає зрозуміти, де і чому scrub скаржився.
  7. Dedup завжди був гострим ножем: DDT важкий по метаданих і може стати вузьким місцем продуктивності. zdb показує статистику DDT, яка краще пояснює «чому все повільне», ніж більшість панелей.
  8. Фрагментація метаслабів реальна і проявляється як біль аллокатора. zdb дає видимість на рівні аллокатора, коли «диски не повні, але запис повільний».
  9. zdb історично маркували як «для розробників» за тоном, а не за здатністю. У продакшні ним користуються SRE теж — якщо використовувати його свідомо й дозовано.

І так: zdb може відчуватися як читання гекс-дампу з амбіціями. Але він структурований, послідовний, і коли ви вивчите кілька типових виводів, він перетворюється на практичний інструмент — а не на привид.

Правила безпеки: як не перетворити дебаг на інцидент

Правило нуль: не запускайте важкі команди zdb на пулі, який уже кульгає, якщо ви не розумієте витрат. Коли латентність „горить“, ваша «швидка перевірка» може стати останньою краплею.

Операційні обмежувачі

  • Віддавайте перевагу операціям лише для читання і уникайте опцій, які сканують кожен блок, якщо ви не в оф-пік або не на репліці.
  • Збирайте контекст спочатку: zpool status, zpool get, zfs get, arcstat (якщо доступно) та системні статистики I/O. zdb — не перший інструмент, це «покажи мені внутрішнє» інструмент.
  • Зафіксуйте очікувані версії: прапорці zdb різняться. Запустіть zdb -? і довіряйте локальній довідці більше, ніж м’язовій пам’яті.
  • Не «оптимізуйте» тільки на основі zdb: він показує внутрішнє, а не досвід користувача. Завжди корелюйте з затримкою додатка, глибинами черг і логами помилок.
  • Ніколи не тестуйте прапорці відновлення на єдиній копії: якщо ви випробовуєте опції імпорту/відновлення, спочатку тренуйтеся на клоні або репліці зі снапшотами.

Жарт №1: zdb — це як відкрити капот під час руху — технічно можливо, соціально не схвалюється.

Одна цитата надійності, яку варто тримати під рукою

Надія — це не стратегія. — генерал Гордон Р. Салліван

zdb — це інструмент, який ви використовуєте, коли перестаєте сподіватися і починаєте доводити.

Ментальна модель: що zdb бачить, а zfs/zpool ні

ZFS багаторівневий. Коли ви набираєте zfs list, ви питаєте дружню бібліотеку: «Які датасети ти знаєш?» Коли ви набираєте zdb, ви питаєте: «Що записано на диску, в MOS, у наборах об’єктів, у блокових деревах?» Ця різниця важлива, коли метадані неконсистентні, пул імпортовано частково або коли ви займаєтесь форензикою.

Кілька внутрішніх імен, які потрібно знати

  • Pool / SPA: аллокатор пулу — логіка верхнього рівня.
  • MOS (Meta Object Set): «файлова система» метаданих пулу. Якщо MOS хворий, усе хворе.
  • Dataset: поняття ZFS для файлової системи/тома/снапшота з властивостями й посиланнями на блоки.
  • Object set: колекція об’єктів (dnodes) для датасету.
  • Dnode: метадані, що описують об’єкт (файл, каталог, ZVOL-пристрій тощо).
  • Block pointer (blkptr): посилання на блок, включно з розміром, контрольною сумою, birth txg і фізичними DVA (де він зберігається).
  • TXG: transaction group. Як часовий відрізок змін, зафіксований разом.
  • Metaslab: одиниця аллокатора простору на vdev. Тут живе фрагментація й вільний простір.

Більшість продакшн-використання zdb вкладається в дві категорії: (1) «скажи мені, чому простір/продуктивність виглядає неправильно», і (2) «скажи мені, який блок/об’єкт зламаний і наскільки це погано». Якщо тримати цей поділ у голові, ви краще обиратимете команди й припините спелеологію заради спорту.

Швидкий план діагностики (перевірити перше/друге/третє)

Це версія для on-call. Ви маєте право бути втомленими, але не маєте права діяти випадково.

Перше: встановіть, чи це проблема надійності чи продуктивності

  • Сигнали надійності: помилки контрольних сум, помилки I/O, degraded/faulted vdevs, помилки scrub, несподівані помилки читання/запису.
  • Сигнали продуктивності: висока затримка при «healthy» пулі, повільні записи, повільні читання, майже повний простір, дивна поведінка вільного простору, ARC misses, thrash аллокатора.

Друге: вирішіть, чи потрібен zdb

  • Якщо zpool status чітко вказує на диск і надмірність може вилікувати, спочатку замініть/resilver-те/запустіть scrub. zdb корисний, але не завжди обов’язковий.
  • Якщо симптом — «простір не сходиться», «метаслаби фрагментовані», «який датасет споживає простір» або «які функції активні», zdb часто дає найшвидшу відповідь.
  • Якщо пул не імпортується, zdb може сказати, чи виглядають labels/MOS адекватно, перш ніж починати опції відновлення.

Третє: запускайте найдешевші запити zdb, які відповідають на питання

  1. Конфіг пулу і прапорці функцій: підтверджує, з чим ви маєте справу і чи ймовірний mismatch при імпорті.
  2. Облік простору: перевіряє, куди пішов простір, не обходячи кожен блок.
  3. Статистика метаслабів: перевіряє фрагментацію й поведінку алокації.
  4. Цільова інспекція об’єкта: лише коли у вас вже є підозрілий датасет/об’єкт.

Якщо шукаєте вузьке місце швидко: визначте, чи обмежені ви (a) латентністю одного vdev, (b) тиском алокації/фрагментацією, (c) dedup/DDT, (d) дрібними записами, (e) sync-записами/лог-пристроєм, або (f) банально апаратними помилками. zdb найбільше допомагає з (b) і (c), і пояснює (a) після факту.

Практичні завдання: команди, значення виводу та рішення

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

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

cr0x@server:~$ sudo zdb -C tank
MOS Configuration:
        vdev_tree:
            type: 'root'
            id: 0
            guid: 12345678901234567890
            children[0]:
                type: 'raidz'
                id: 0
                guid: 9876543210987654321
                ashift: 12
                nparity: 2
                children[0]:
                    type: 'disk'
                    path: '/dev/disk/by-id/ata-SAMSUNG_SSD_1'
                    guid: 1111
                children[1]:
                    type: 'disk'
                    path: '/dev/disk/by-id/ata-SAMSUNG_SSD_2'
                    guid: 2222
features_for_read:
        com.delphix:hole_birth
        org.openzfs:embedded_data
        org.openzfs:project_quota

Що це означає: Це друкує конфігурацію MOS: топологію vdev, ashift, GUID-и та функції, потрібні для читання. Це джерело правди «що диск каже про пул».

Рішення: Якщо шляхи пристроїв ОС змінилися, але GUID-и збігаються — добре. Якщо features_for_read включає те, що ваша цільова хост-система не підтримує, імпорт в іншому місці завершиться невдало. Плануйте оновлення відповідно.

Завдання 2: Перелічити датасети й простір на рівні внутрішнього обліку пулу

cr0x@server:~$ sudo zdb -Lbbbs tank
Dataset tank [ZPL], ID 50, cr_txg 4, 1.23G used, 7.88T available
Dataset tank/home [ZPL], ID 54, cr_txg 120, 310G used, 7.55T available
Dataset tank/vm [ZVOL], ID 61, cr_txg 2201, 2.10T used, 5.75T available

Що це означає: zdb підсумовує використання датасетів з внутрішніх структур ZFS, а не з df. Він може виявити датасети, про які ви забули (особливо zvol-и).

Рішення: Якщо датасет дивує вас, припиніть гадати. Підтвердіть через zfs list -o space і вирішіть, чи потрібні вам квоти, резервації або очищення снапшотів.

Завдання 3: Перевірити прапорці функцій і чи вони активні

cr0x@server:~$ sudo zdb -S tank
Storage pool tank:
        version: 5000
        features:
                async_destroy
                        enabled
                        active
                embedded_data
                        enabled
                        active
                spacemap_histogram
                        enabled
                        active

Що це означає: Пул використовує прапорці функцій; «enabled» означає, що пул підтримує цю функцію, «active» — що вона була використана й тепер потрібна для сумісності.

Рішення: Якщо плануєте міграцію пулу на старіший пристрій/хост, «active» функції — це ваші сумісні бар’єри. Не дізнавайтеся про це під час міграції.

Завдання 4: Перевірити мітки vdev і GUID-и (санітарна перевірка ідентичності диска)

cr0x@server:~$ sudo zdb -l /dev/disk/by-id/ata-SAMSUNG_SSD_2
------------------------------------
LABEL 0
------------------------------------
version: 5000
name: 'tank'
state: 0
txg: 902341
pool_guid: 12345678901234567890
vdev_guid: 2222
top_guid: 9876543210987654321

Що це означає: Це читає мітку ZFS на диску. Це те, як ви доводите «цей диск належить цьому пулу», незалежно від імен у Linux.

Рішення: Коли хтось переставив кабелі або контролер перенумерував диски, це запобігає заміні невірного диска. Якщо мітка диска вказує на інший пул — зупиніться й розслідуйте, перш ніж робити щось руйнівне.

Завдання 5: Перевірити фрагментацію метаслабів і стан алокації

cr0x@server:~$ sudo zdb -mm tank
Metaslab statistics for pool 'tank':
  vdev 0: raidz
    metaslabs: 512
    free space: 5.75T
    fragmentation: 62%
    largest free segment: 128M

Що це означає: Фрагментація тут — це фрагментація аллокатора, а не «фрагментація файлів». Висока фрагментація з малим найбільшим вільним сегментом означає, що алокації стають дорогими, особливо для великих блоків.

Рішення: Якщо фрагментація висока й записи повільні, або (a) звільніть простір (видаліть + zpool trim для SSD, залежно від налаштувань), або (b) додайте vdev-и, щоб збільшити вільний простір і зменшити тиск аллокатора, або (c) сплануйте перепис/міграцію. Не намагайтеся «дефрагментувати» ZFS — це не працює так.

Завдання 6: Переглянути карти простору і підказки гістограми (чому облік простору дивний?)

cr0x@server:~$ sudo zdb -DD tank
DDT-sha256-zap-duplicate: 1248 entries, size 1.10M on disk, 2.40M in core
DDT-sha256-zap-unique:  98122 entries, size 86.0M on disk, 210M in core

Що це означає: Це інформація про таблицю дедуплікації. «In core» натякає на тиск пам’яті, коли dedup ввімкнено і активно використовується.

Рішення: Якщо dedup увімкнено і ваш ARC/пам’ять обмежені, очікуйте зниження продуктивності під навантаженням. Якщо dedup не є критичним, плануйте міграцію від нього, а не сподівайтеся, що він поводитиметься добре.

Завдання 7: Визначити, який номер об’єкта відповідає файловому шляху (цільова форензика)

cr0x@server:~$ sudo zdb -vvv tank/home 2>/dev/null | head -n 20
Dataset tank/home [ZPL], ID 54, cr_txg 120, 310G used, 7.55T available
Object  Number  Type
    1    1      ZFS plain file
    2    2      ZFS directory
    3    3      ZFS plain file

Що це означає: Виведення повних переліків об’єктів дороге; навіть вибірка показує модель об’єктів. На багатьох системах ви використовуватимете більш цільові підходи (наприклад, знаходження інодів спочатку), а не дамп всього.

Рішення: Якщо ви розслідуєте відомий файл, не йдіть «в лоб». Використовуйте відображення inode → об’єкт (наступне завдання), щоб інспектувати тільки те, що важливо.

Завдання 8: Зіставити інод Linux з об’єктом ZFS і перевірити його блоки

cr0x@server:~$ stat -c 'inode=%i path=%n' /tank/home/app/logs/badfile.log
inode=914227 path=/tank/home/app/logs/badfile.log
cr0x@server:~$ sudo zdb -dddd tank/home 914227 | sed -n '1,25p'
Object  lvl   iblk   dblk  dsize  dnsize  bonus  type
914227   1   128K    16K   512K    512    320   ZFS plain file
        path    /app/logs/badfile.log
        gen     7241
        size    501760
        parent  912000
Indirect blocks:
        0 L1 0:10000:20000 20000L/10000P F=1 B=81234/81234 cksum=on

Що це означає: На багатьох платформах номери об’єктів ZFS відповідають inode-ам. zdb -dddd виводить dnode і дерево блоків. Поля типу DVA показують, де розташовані блоки; налаштування контрольних сум і рівні показують структуру.

Рішення: Якщо zpool status -v посилається на файл і ви можете зіставити його з об’єктом, ви з’ясуєте, чи це ізольований малий об’єкт або частина ширшого пошкодження метаданих. Якщо ізольовано і є надмірність — scrub/resilver, ймовірно, виправить; якщо ні — відновіть файл зі снапшота/бекапу.

Завдання 9: Перевірити облік простору пулу на рівні MOS (чому «used» не сходиться)

cr0x@server:~$ sudo zdb -b tank | sed -n '1,40p'
Traversing all blocks...
blocks = 14723918
leaked = 0
compressed = 1.82T, uncompressed = 2.61T, ratio = 1.43x
bp logical = 2.61T, bp physical = 1.82T

Що це означає: Це повне обхідне проходження блоків. Воно може бути дорогим. «leaked=0» — добре: немає виявлених невідкритих, але виділених блоків за результатами обходу.

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

Завдання 10: Зрозуміти ефективність стиснення по датасету

cr0x@server:~$ sudo zdb -DDDDD tank/vm | sed -n '1,25p'
Dataset tank/vm [ZVOL], ID 61, cr_txg 2201
bp logical = 2.40T, bp physical = 2.33T, ratio = 1.03x
compression: lz4

Що це означає: Стиснення увімкнено, але дає майже нічого. Для образів VM це звично, залежно від файлової системи й ентропії даних.

Рішення: Не вимикайте стиснення автоматично; lz4 дешевий і все ще корисний для метаданих і нульових блоків. Але не чекайте, що стиснення «врятує» місце на вже стиснених даних. Плануйте ємність відповідально.

Завдання 11: Інспектувати конкретний block pointer (глибока робота з корупцією)

cr0x@server:~$ sudo zdb -bbbb tank 0:10000:20000
Block 0:10000:20000
        size=131072L/65536P compression=lz4
        birth=81234 fill=1
        cksum=sha256 2f3a...9c1d
        DVA[0]=<0:10000:20000>

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

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

Завдання 12: Друк підказок ZIL та intent log (болі синхронних записів)

cr0x@server:~$ sudo zdb -iv tank | sed -n '1,60p'
ZFS_DBGMSG(zil): zil_claim: txg 902340 replayed 0 blocks
ZFS_DBGMSG(zil): zil_itxg_clean: cleaned up log blocks

Що це означає: На деяких системах zdb може виводити пов’язані з ZIL повідомлення. Це допомагає підтвердити, чи відбулося відтворення логів і чи пул вважається чистим.

Рішення: Якщо додаток скаржиться на відсутні нещодавні sync-записи після крашу, підтвердіть, чи відбулося відтворення ZIL. Якщо ні — розслідуйте семантику імпорту і чи пул імпортовано read-only або з прапорцями відновлення.

Завдання 13: Помітити занадто малий ashift після факту (продуктивність і знос)

cr0x@server:~$ sudo zdb -C tank | grep -n 'ashift'
18:                ashift: 9

Що це означає: ashift — це розмір сектора, який ZFS використовує для вирівнювання. ashift: 9 означає 512B сектори. На сучасних SSD і багатьох HDD розумним дефолтом є вирівнювання 4K (ashift 12).

Рішення: Якщо ashift занадто малий, змінити його на місці неможливо. Плануйте міграцію або перебудову. Якщо продуктивність наразі прийнятна, все одно заплануйте це — бо посилений знос проявиться поступово.

Завдання 14: Перевірити, чи ви платите «податок special vdev» чи користуєтесь перевагами

cr0x@server:~$ sudo zdb -C tank | sed -n '1,120p' | grep -n "special" -n
74:            children[1]:
75:                type: 'special'
76:                id: 1
77:                guid: 3333

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

Рішення: Якщо у вас є special vdev, ставтеся до нього як до Tier-0 сховища з надмірністю і моніторингом. Якщо він помре і не має надмірності, пул може стати непридатним. Це не «приємність» — це структурний елемент.

Завдання 15: Підтвердити, як ZFS бачить історію uberblock (параноя імпорту)

cr0x@server:~$ sudo zdb -u tank | head -n 20
Uberblock[0]
        magic = 0000000000bab10c
        version = 5000
        txg = 902341
        guid_sum = 2222222222222222
        timestamp = 2025-12-26 12:41:03
Uberblock[1]
        txg = 902340
        timestamp = 2025-12-26 12:40:52

Що це означає: Uberblock-и — це «контрольні точки», що використовуються для імпорту пулу. Бачити кілька свіжих uberblock-ів з монотонним наростанням txg — заспокійливо.

Рішення: Якщо останній uberblock значно відстає або часові відмітки дивні, підозрюйте неповні записи, проблеми з кешуванням контролера або диск, що не фіксує дані. Це змінює план відновлення: перестаньте довіряти «це має бути там».

Жарт №2: вивід zdb — найочевидніша поезія для інженерів зберігання — головним чином тому, що ніхто інший її не читає.

Три корпоративні міні-історії з краю «здавалося розумним»

1) Інцидент, спричинений неправильною припущенням: «Якщо імпортується — значить ок»

Середня компанія експлуатувала платформу віртуальних машин на двох серверах зберігання на ZFS. Після відключення живлення один вузол увімкнувся, імпортував пул і виглядав «достатньо здоровим». Адмін не бачив degraded vdev-ів. Кластер гіпервізора почав запускати ВМи знову. Всі видихнули.

Через два дні кілька ВМ почали логувати помилки файлової системи. Потім інстанс бази даних впав із повідомленнями про помилки контрольних сум всередині гостя. ZFS звітував про зростаючий список помилок контрольних сум, але тільки під певними шаблонами читання. Команда припустила «битий біт», запустила scrub і повернулася на зустрічі.

Scrub майже не просувався. Він повз і іноді зависав. Тим часом затримки вдаряли по ВМам у робочий час. Вони замінили диск, який здавався «повільним», але помилки не зникли. Тільки тоді хтось нарешті запустив zdb -u і zdb -l для підозрілих пристроїв.

Мітки показали негарну картину: шлях контролера час від часу повертав застарілі дані. Пул імпортувався, бо метадані були достатньо консистентні, але «останні» uberblock-и не були такими свіжими, як припускала команда. zdb -u виявив підозрілий розрив у прогресії txg після події з відключенням живлення. У поєднанні з логами ядра це вказало на проблему з кешем запису/флашем — пристрій підтверджував записи, які ніколи не потрапили на стабільне сховище.

Виправлення не було «магією» файлової системи. Це була апаратна й політична дія: заміна контролера, перевірка налаштувань кешування і запуск scrub-ів із ізоляцією I/O. Вони відновили невелику кількість пошкоджених дисків ВМ зі снапшотів, реплікованих на інший вузол. Урок: успішний імпорт — не те саме, що цілісність. zdb не «полагодив» нічого; він довів, що хронологія брехала.

2) Оптимізація, що відкотилася: dedup як диво економії

Велика внутрішня команда отримала директиву: «Зменшити зайнятість сховища». Вони помітили багато дублікатів шаблонів ВМ і шарів контейнерів. Хтось запропонував увімкнути дедуп на головному пулі. Короткий тест виглядав перспективним: зайнятість впала для невеликого датасету, і всі тихо потиснули руки.

Вони ввімкнули dedup ширше. Спочатку все було нормально. Потім настав понеділок. Затримка підвищилась, потім знову підвищилась. Ноди зберігання почали свопитися під навантаженням. Записи сповільнилися. Читання почали ставати в чергу. Це не був катастрофічний збій; це був повільний відкат, де всі додавали панелі моніторингу, поки й ті не почали таймаутитись.

Вони запустили zdb -DD і побачили розміри DDT і оцінки in-core. Це було очевидно. Пул платив метаданковий податок, якого не вистачало у RAM, тож кожен I/O став пошуком по холодних метаданих. ARC-hit упав; CPU був зайнятий роботою, яку ніхто не бажав.

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

Проблема не в тому, що dedup поганий. Справжня помилка — ввімкнути його без моделювання пам’яті, навантаження і вихідних витрат. zdb зробив витрати видимими. Він не зробив рішення зворотним.

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

Одна корпоративна команда експлуатувала кілька пулів ZFS по різних шафах. Нічого особливого. Вони послідовно робили три речі: (1) кожен диск мав стабільні шляхи by-id, зафіксовані в інвентарі, (2) у кожного пулу були гарячі запасні диски й ясні процедури заміни, і (3) щоквартально вони репетирували кроки імпорту й відновлення на staging-хості, використовуючи репліковані снапшоти.

Однієї ночі вузол зберігання впав. Хардверна команда замінила бекплейн, і раптом ОС перенумерувала диски інакше. Молодший адміністратор на чергуванні зробив правильну, нудну річ: перед будь-якими замінами він запустив zdb -C для пулу і zdb -l для кількох пристроїв, щоб перевірити членство і GUID-и.

Вони виявили, що два диски присутні, але за іншим шляхом, а один «втрачен» диск насправді був — просто перейменований. Без цієї перевірки вони могли б випадково відключити невірний диск і перевести пул у degraded під час імпорту.

Пул імпортувався чисто. Scrub було заплановано. Продуктивність залишалась стабільною. Ніхто не писав постмортем, бо нічого не зламалося. Справжній успіх — процедура: інвентар + перевірка міток + репетиція. zdb був тихою допоміжною роллю, яка зробила «спокійно правильно» можливим.

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

1) Симптом: «zfs list каже одне, df каже інше»

Корінь: Ви змішуєте точки зору: логічний простір датасету vs фізичний простір пулу, снапшоти, refreservation і те, що df показує вид файлової системи після властивостей типу refquota.

Виправлення: Використовуйте zfs list -o space як перший крок, потім підтвердіть через zdb -Lbbbs pool для внутрішнього погляду. Якщо датасет має refreservation або велике використання снапшотів, налаштуйте квоти/резервації і впровадьте політику утримання снапшотів.

2) Симптом: Пул «ONLINE», але scrub постійно знаходить помилки контрольних сум

Корінь: Пристрій/шлях контролера повертає неправильні дані періодично, або є латентні пошкоджені сектори, які надмірність іноді, але не завжди, може виправити.

Виправлення: Замініть підозрілий диск або контролер, а не «поганьте scrub ще сильніше». Використовуйте zdb -l для підтвердження ідентичності диска та корелюйте місця помилок. Після апаратного виправлення запустіть scrub.

3) Симптом: Записи сильно уповільнюються, коли пул ~80–90% заповнений

Корінь: Тиск аллокатора і фрагментація метаслабів; вільний простір існує, але не в корисних сегментах.

Виправлення: Перевірте статистику метаслабів через zdb -mm. Звільніть простір (видаліть дані й снапшоти), щоб знизити завантаження, або додайте vdev ємності. Довгостроково: не експлуатуйте пули на такому рівні заповнення, якщо вам важлива затримка.

4) Симптом: Після ввімкнення dedup усе ніби тягнеться крізь мед

Корінь: Метадані DDT не влізли в RAM, спричиняючи постійні пропуски кешу і важкий випадковий I/O.

Виправлення: Використайте zdb -DD для кількісної оцінки. Якщо dedup вже активний, плануйте міграцію з dedup off. Якщо ще не вмикали — не вмикайте без моделі пам’яті і плану виходу.

5) Симптом: Імпорт пулу провалюється на іншому хості «хоч це ті самі диски»

Корінь: Потрібні для читання прапорці функцій не підтримуються ZFS-версією цільового хоста.

Виправлення: Використайте zdb -C pool і zdb -S pool, щоб побачити потрібні/активні функції. Оновіть цільовий хост або оберіть стратегію сумісності перед переміщенням дисків.

6) Симптом: Дрібні випадкові записи жахливі, sync-важке навантаження зупиняється

Корінь: Відсутній/неправильно налаштований SLOG, або проблеми з латентністю пристрою; також mismatch recordsize/volblocksize для навантаження.

Виправлення: Перевірте поведінку intent log і латентність пристрою. zdb може дати підказки, але рішення зазвичай залежить від навантаження. Для zvol-ів встановіть volblocksize правильно при створенні; для файлових систем налаштуйте recordsize і патерни I/O додатку.

7) Симптом: Після заміни диска помилки не зникають; витягли «не той» диск

Корінь: Спиралися на імена пристроїв ОС на кшталт /dev/sdX замість стабільних ідентифікаторів і міток на диску.

Виправлення: Завжди ідентифікуйте диски через /dev/disk/by-id і перевіряйте через zdb -l перед виведенням/заміною.

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

Чекліст A: Перед запуском zdb у продакшні

  1. Запишіть питання, на яке ви намагаєтеся відповісти (простір? продуктивність? корупція? імпорт?).
  2. Зберіть базу: zpool status, zpool get all pool, zfs get all dataset (або принаймні релевантні властивості).
  3. Перевірте навантаження: якщо латентність уже висока, уникайте обходів блоків.
  4. Підтвердіть платформу/версію: запустіть zdb -? і перевірте наявність очікуваних прапорців.
  5. Віддавайте перевагу цільовим командам (-C, -S, -mm, -l) перед повними обходами.
  6. Логируйте виводи в тикет або документ інциденту. Вивід zdb — це доказ.

Чекліст B: Загадка простору («пул повний, але я не бачу дані»)

  1. Перевірте використання снапшотів і клонів на рівні датасету (спочатку високорівнево).
  2. Використайте zdb -Lbbbs pool для підтвердження внутрішнього використання датасетів і пошуку сюрпризів (zvol-и, приховані датасети).
  3. Якщо підозрюєте витоки/невідповідність обліку і можете дозволити скан — запустіть zdb -b pool у позаробочий час.
  4. Точка рішення: якщо простір утримують снапшоти — виправляйте політику утримання; якщо тиск через фрагментацію — додайте ємність або мігруйте.

Чекліст C: Розслідування корупції («помилки контрольних сум»)

  1. За zpool status -v визначте уражені файли/датасети, якщо вони перелічені.
  2. Підтвердьте стан надмірності: degraded? faulted? скільки помилок?
  3. Перевірте ідентичність підозрілого диска через zdb -l перед заміною чого-небудь.
  4. Якщо можна зіставити до файлу — зіставте inode в об’єкт і інспектуйте через zdb -dddd dataset object.
  5. Точка рішення: якщо є надмірність — scrub після апаратного ремонту; якщо ні — відновіть уражені об’єкти із снапшота/бекапу.
  6. Після: заплануйте scrub і перегляньте логи кабелів/контролера. ZFS часто каже, що «щось» не так; він не замінює дисципліну в пошуку кореня.

Чекліст D: Регрес продуктивності («минулого тижня було швидко»)

  1. Підтвердіть заповненість пулу й фрагментацію через zdb -mm і нормальні статистики пулу.
  2. Перевірте, чи задіяний dedup і як виглядає DDT (zdb -DD).
  3. Підтвердіть ashift і макет vdev через zdb -C.
  4. Точка рішення: якщо фрагментація висока — знизьте завантаження/додайте vdev; якщо dedup тисне на пам’ять — мігруйте; якщо макет vdev неправильний — плануйте перебудову.

FAQ

Чи безпечно запускати zdb на робочому продакшн-пулі?

Переважно так, якщо ви дотримуєтесь сумарних/міткових/метаслаб-сумарних операцій. Уникайте повних обходів (наприклад, обходів блоків) під час пікового навантаження. Сприймайте це як діагностику, що споживає I/O і CPU.

Чи може zdb відремонтувати корупцію?

Ні. Він діагностує. Відновлення приходить від надмірності (scrub/resilver) або відновлення зі снапшотів/бекапів. zdb допомагає зрозуміти масштаб і ймовірний корінь проблеми.

Чому вивід zdb відрізняється між серверами?

Реалізації ZFS і версії відрізняються. Прапорці й формати виводу можуть змінюватися. Завжди перевіряйте zdb -? на хості, який ви використовуєте, і не припускайте, що приклад у блозі відповідає вашій платформі.

Коли слід використовувати zdb замість zpool/zfs?

Коли потрібна внутрішня правда: прапорці функцій, мітки, фрагментація метаслабів, статистика DDT, історія uberblock-ів або деталі об’єктів/блоків, які високорівневі інструменти приховують.

Чи допоможе zdb знайти, що тримає простір після видалення файлів?

Опосередковано. zdb може підтвердити використання датасетів і іноді виявити, що снапшоти/клони утримують блоки. «Виправлення» зазвичай — політика утримання снапшотів, а не ще більше zdb.

Чи допомагає zdb з відновленням видалених файлів?

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

Яка найкорисніша команда zdb, яку запам’ятати?

zdb -C pool. Вона каже, що пул є: макет vdev, ashift і вимоги функцій. Це запобігає дурним помилкам під час замін і міграцій.

Як дізнатися, чи dedup мені шкодить?

Якщо dedup активний і in-core потреби DDT перевищують доступну пам’ять, ви побачите пропуски кешу і посилене I/O. zdb -DD pool дає підказки про розмір DDT, які сильно корелюють із проблемами.

Чи може zdb пояснити, чому мій пул повільний, хоча не заповнений?

Так, через статистику фрагментації метаслабів та алокації (zdb -mm). «Не повний» — не те саме, що «легко алокувати». Фрагментація може змусити напівпорожній пул поводитись як перепована парковка.

Висновок: що робити наступного разу до паніки

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

Практичні наступні кроки, які окупляться:

  • Потренуйтеся на некритичному пулі: запускайте zdb -C, zdb -S, zdb -mm і zdb -l доти, поки виводи не стануть знайомими.
  • Стандартизуйтесь з ідентифікацією дисків через шляхи by-id і перевірки міток перед замінами. Зробіть це політикою, а не героїзмом.
  • Запишіть вашу послідовність «швидкої діагностики» і тримайте її в runbook для чергових. zdb найефективніший, коли відповідає на конкретне питання.
  • Виділіть час для незворотних рішень: dedup, special vdev-и, ashift і макет vdev — це архітектура. zdb покаже наслідки; він не може їх скасувати.

Коли пул поводиться погано, вам не потрібна ще більша таємниця. Вам потрібні докази. zdb — це доказ, поданий діалектом, який винагороджує терпіння і карає імпровізацію.

← Попередня
Плавлення роз’ємів: коли «стандарт» перетворюється на скандал
Наступна →
Основи ZFS iostat: перетворення цифр на вузьке місце

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