Відмова спеціального vdev у ZFS: як вижити в нічному кошмарі

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

Ви прокидаєтеся від оповіщення: зростає затримка, додатки таймаутять, і хтось вставив в чат одну строку:
special vdev. Якщо ви знаєте — ви знаєте.

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

Що таке спеціальний vdev насправді (і чому він інший)

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

special vdev: що він зберігає

  • Метадані: вказівники блоків, непрямі блоки, dnodes, структури директорій, spacemaps тощо.
  • Опційно — малі блоки: залежно від special_small_blocks, невеликі дані файлів можуть розміщуватися на special.
  • Не кеш: на відміну від L2ARC, дані на special є авторитетними й потрібні, якщо вони там виділені.

Те, що боляче кусає: постійність розміщення

Коли блок виділено для спеціального vdev, він залишається там, поки його не перезапишуть в інше місце.
Якщо ви втрачаєте єдину копію, ZFS не зможе «відновити» її з повільних дисків. Немає магії «відбудувати метадані з парності»,
якщо метадані ніколи не існували на основних vdev.

Відмови special vdev особливо жорстокі, бо метадані — це карта. Втрата карти означає, що ви можете мати територію (ваші блоки даних)
і все одно не знайти до них дорогу.

Цікаві факти і історичний контекст (бо історія повторюється)

  1. Allocation classes з’явилися пізніше: special vdev з’явився після того, як ZFS уже здобув репутацію, тож багато старих «best practices» про нього не згадують.
  2. Функцію впровадили через реальний біль: великі пули на HDD з тисячами малих файлів були швидкими в потоках, але повільними при «ls -lR», і операційні команди вимагали рішення, яке не було «купіть більше RAM».
  3. ZFS завжди ставив метадані в перший клас: контрольні суми, copy-on-write і self-healing були про захист структури так само, як і вмісту.
  4. Люди плутають його з SLOG: бо обидва — «швидкі пристрої», які додають, але SLOG прискорює sync-записи; special — про постійне розміщення.
  5. Spacemaps мають значення: сучасний ZFS використовує spacemaps для відстеження вільного простору; якщо special тримає критичні spacemaps і він помирає, імпорт пулу може стати неможливим.
  6. Offload малих блоків став популярним з віртуалізацією: образи VM і шари контейнерів створюють тонни метаданих і дрібних випадкових IO; special часто різко знижував затримки.
  7. Домени відмов стали дивнішими: з special vdev ваш пул може бути «RAIDZ2» на HDD і «single SSD» для метаданих. Справжня надлишковість пулу стає «single SSD».
  8. Витривалість — реальне обмеження: метадані і малі блоки мають велику інтенсивність записів; споживчі SSD дохнуть раніше при duty special, особливо з atime або гучними навантаженнями.

Одне сухе правило: якщо вам незручно зберігати суперблок файлової системи на одному пристрої, не зберігайте там і метадані ZFS.

Сценарії-кошмари: що реально відбувається при його відмові

Сценарій A: special vdev деградований, пул все ще імпортується, усе повільно і дивно

Це «щасливий» випадок. Пристрій у зміненому mirrored special вмирає, але не повністю.
Читання можуть повторюватись, затримки підіймаються, ZFS починає кидати помилки контрольних сум, і ваш застосунок починає таймаутити.
Більшість команд марнує час, звинувачуючи мережу, потім гіпервізор, потім базу даних. Тим часом читання метаданих повільно йде через помираючий SSD.

Сценарій B: special vdev зник, пул не імпортується

Якщо special був single-disk (або дзеркало втратило занадто багато членів), ви можете опинитися з неможливістю імпорту.
ZFS може повідомляти про відсутні пристрої, або гірше: він «імпортує», але набори даних не монтуються, або обхід директорій повертає I/O помилки.
У цей момент ви не виконуєте «заміни диска». Ви робите інцидент-реакцію з набором хірурга для файлової системи.

Сценарій C: пул призупиняється під час IO

ZFS може призупинити пул, коли виявляє помилки достатньо серйозні, щоб подальша робота загрожувала корупцією.
Ви побачите «pool I/O is currently suspended» і сервіси впадуть у синхронізований хаос.
Ставтесь до цього як до запобіжного гальма, а не як до незручності.

Жарт №1: Призупинений пул — це ZFS, який каже: «Я можу продовжувати, але не хочу потім брати на себе відповідальність». Це найвідповідальніше ПЗ у вашій стояку.

Сценарій D: ви «полагодили», але продуктивність не повертається

Іноді відновлення вдається, але пул тепер працює з метаданими на HDD, бо ви видалили special або він перестав ефективно використовуватися.
Система «вгору», але користувачі скаржаться, що UI наче малюється через модем. Ви пережили вогонь; тепер живете в диму.

Що визначає, наскільки погано

  • Надлишковість спеціального vdev: дзеркало проти single; ширина дзеркала; якість пристроїв.
  • Скільки було виділено на special: лише метадані або метадані плюс малі блоки.
  • Як довго працював деградовано: повтори та корупція кумулюються; час resilver зростає.
  • Операційна дисципліна: scrubs, оповіщення, запасні пристрої і документовані кроки відновлення.

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

Це послідовність, яка зазвичай ріже плутанину. Мета — швидко відповісти на три питання:
«Чи пул у безпеці?», «Чи задіяний special vdev?», «Яка найшвидша безпечна дія?»

Перший: підтвердити стан пулу і ідентифікувати стан special vdev

  • Запустіть zpool status -v і дивіться спеціально на клас vdev special та кількість помилок.
  • Перевірте, чи пул SUSPENDED, DEGRADED або FAULTED.
  • Проскануйте dmesg/системні логи на предмет скидань NVMe, таймаутів або видалень пристроїв.

Другий: визначити радіус ураження (лише метадані або також малі блоки)

  • Перевірте zfs get special_small_blocks на ключових наборах даних.
  • Шукайте симптоми: повільні списки директорій (метадані) або збої читання малих файлів (малі блоки на special).
  • Перевірте прапори функцій пулу і чи є special необхідним для імпорту (зазвичай так, якщо блоки там виділені).

Третій: оберіть безпечний шлях дій

  • Якщо special дзеркалений і впав лише один пристрій: замініть негайно, потім scrub, потім стежте за resilver.
  • Якщо special одиночний і впав: припиніть імпровізації. Вирішіть між відновленням з бекапу, спробою відновити пристрій або спеціалізованим forensic-імпортом.
  • Якщо пул призупинений: стабілізуйте апаратне забезпечення, export якщо можливо, і плануйте контрольований import; не давайте додаткам шалено писати до нього.

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

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

Нижче — практичні завдання, які можна виконати на Linux-хості з OpenZFS. Команди реальні. Виводи репрезентативні.
Суть не в точній формі; суть — що ви робите висновки і які подальші дії.

Завдання 1: Ідентифікувати відмову і підтвердити, що це special

cr0x@server:~$ sudo zpool status -v tank
  pool: tank
 state: DEGRADED
status: One or more devices has experienced an unrecoverable error.
action: Replace the device using 'zpool replace'.
  scan: scrub repaired 0B in 0 days 00:19:21 with 0 errors on Thu Dec 26 01:10:12 2025
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        DEGRADED     0     0     0
          raidz2-0                  ONLINE       0     0     0
            ata-HDD1                ONLINE       0     0     0
            ata-HDD2                ONLINE       0     0     0
            ata-HDD3                ONLINE       0     0     0
            ata-HDD4                ONLINE       0     0     0
            ata-HDD5                ONLINE       0     0     0
            ata-HDD6                ONLINE       0     0     0
        special
          mirror-1                  DEGRADED     7     0   118
            nvme-SAMSUNG_SSD_A      FAULTED     7     0   118  too many errors
            nvme-SAMSUNG_SSD_B      ONLINE       0     0     0

errors: No known data errors

Що це означає: пул деградований через пристрій в класі special, який faulted.
Помилки читання/CKSUM на special особливо серйозні, бо там живуть метадані.

Рішення: негайно замініть faulted NVMe. Не «чекайте вікна техобслуговування». Ви вже у ньому.

Завдання 2: Перевірити, чи пул призупинено

cr0x@server:~$ sudo zpool status tank | sed -n '1,12p'
  pool: tank
 state: ONLINE
status: Some supported and requested features are not enabled on the pool.
action: The pool can be imported using its name or numeric identifier.
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0

Що це означає: тут немає призупинення. Якщо ви бачите state: SUSPENDED, то план дій змінюється: припиніть IO, стабілізуйте, і плануйте контрольований recovery.

Рішення: продовжуйте заміну і resilver, обмеживши навантаження, але поки що не потрібно екстреного export/import.

Завдання 3: Погодити з помилками ядра (таймаути/скидання)

cr0x@server:~$ sudo dmesg -T | tail -n 12
[Thu Dec 26 02:14:03 2025] nvme nvme1: I/O 123 QID 6 timeout, completion polled
[Thu Dec 26 02:14:03 2025] nvme nvme1: Abort status: 0x371
[Thu Dec 26 02:14:04 2025] nvme nvme1: controller is down; will reset: CSTS=0x3, PCI_STATUS=0x10
[Thu Dec 26 02:14:06 2025] nvme nvme1: Removing after probe failure status: -19

Що це означає: пристрій зник або багаторазово скидалася контролер. Це не «помилка ZFS». Це апарат/прошивка/живлення/шлях PCIe.

Рішення: вважайте пристрій ненадійним, навіть якщо він повернувся після перезавантаження. Замініть його; не довіряйте йому метадані знову.

Завдання 4: Ідентифікувати за by-id імена (щоб не поміняти не той диск)

cr0x@server:~$ ls -l /dev/disk/by-id/ | egrep 'nvme-SAMSUNG_SSD_A|nvme-SAMSUNG_SSD_B'
lrwxrwxrwx 1 root root 13 Dec 26 01:59 nvme-SAMSUNG_SSD_A -> ../../nvme1n1
lrwxrwxrwx 1 root root 13 Dec 26 01:59 nvme-SAMSUNG_SSD_B -> ../../nvme0n1

Що це означає: у вас стабільні ідентифікатори. Добре. Якщо ви користуєтесь тільки /dev/nvme1n1, ви в одній перезавантаженні від помилкової заміни.

Рішення: робіть всі операції ZFS із шляхами /dev/disk/by-id.

Завдання 5: Підтвердити політику набору даних для малих блоків (перевірка радіусу ураження)

cr0x@server:~$ sudo zfs get -r -o name,property,value special_small_blocks tank
NAME                 PROPERTY              VALUE
tank                 special_small_blocks  0
tank/vm              special_small_blocks  16K
tank/home            special_small_blocks  0
tank/containers      special_small_blocks  8K

Що це означає: деякі набори даних розміщують малі блоки файлів на special (vm, containers).
Втрата special тут — це не лише «незручність метаданих». Це може позбавити доступу реальні дані файлів.

Рішення: пріоритетизуйте відновлення для цих наборів даних; пізніше розгляньте більш жорстку надлишковість і консервативніші пороги.

Завдання 6: Перевірити, чи пристрої special дзеркалені (так має бути)

cr0x@server:~$ sudo zpool status tank | sed -n '/special/,$p'
        special
          mirror-1                  DEGRADED     7     0   118
            nvme-SAMSUNG_SSD_A      FAULTED     7     0   118  too many errors
            nvme-SAMSUNG_SSD_B      ONLINE       0     0     0

errors: No known data errors

Що це означає: mirrored special vdev. У вас ще є копія метаданих. Ви в «режимі ремонту», а не «фоpензики».

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

Завдання 7: Замінити несправний пристрій special

cr0x@server:~$ sudo zpool replace tank nvme-SAMSUNG_SSD_A /dev/disk/by-id/nvme-SAMSUNG_SSD_NEW
cannot open 'nvme-SAMSUNG_SSD_A': no such device in pool

Що це означає: ви використали неправильний рядок-ідентифікатор. ZFS хоче точний vdev-токен з zpool status або шлях GUID.

Рішення: копіюйте точно токен з zpool status або використайте zpool status -g для посилання по GUID безпечно.

cr0x@server:~$ sudo zpool status -g tank | sed -n '/special/,$p'
        special
          mirror-1                  DEGRADED
            12293847561234567890    FAULTED  too many errors
            99887766554433221100    ONLINE

Що це означає: доступні GUID-и. Це уникає неоднозначності, якщо шляхи пристроїв змінилися.

Рішення: замінюйте за GUID.

cr0x@server:~$ sudo zpool replace tank 12293847561234567890 /dev/disk/by-id/nvme-SAMSUNG_SSD_NEW
invalid vdev specification
use '-f' to override the following errors:
/dev/disk/by-id/nvme-SAMSUNG_SSD_NEW is part of potentially active pool 'rpool'

Що це означає: новий пристрій містить старі ZFS-лейбли (можливо його брали з іншого хоста або він вже використовувався).
Це звично для «маємо один на полиці» дисків.

Рішення: обережно витріть ZFS-лейбли на новому диску, після чого повторіть заміну.

Завдання 8: Очистити старі лейбли на диску-заміннику (обережно)

cr0x@server:~$ sudo zpool labelclear -f /dev/disk/by-id/nvme-SAMSUNG_SSD_NEW

Що це означає: лейбл успішно очищено (успіх без виводу).

Рішення: продовжуйте з zpool replace.

cr0x@server:~$ sudo zpool replace tank 12293847561234567890 /dev/disk/by-id/nvme-SAMSUNG_SSD_NEW
cr0x@server:~$ sudo zpool status tank | sed -n '/scan/,$p'
  scan: resilver in progress since Thu Dec 26 02:21:12 2025
        19.2G scanned at 1.12G/s, 2.88G issued at 170M/s, 19.2G total
        2.90G resilvered, 14.98% done, 0:01:12 to go
config:

        NAME                          STATE     READ WRITE CKSUM
        tank                          DEGRADED     0     0     0
          raidz2-0                    ONLINE       0     0     0
            ata-HDD1                  ONLINE       0     0     0
            ata-HDD2                  ONLINE       0     0     0
            ata-HDD3                  ONLINE       0     0     0
            ata-HDD4                  ONLINE       0     0     0
            ata-HDD5                  ONLINE       0     0     0
            ata-HDD6                  ONLINE       0     0     0
        special
          mirror-1                    DEGRADED     0     0     0
            replacing-0               DEGRADED     0     0     0
              12293847561234567890    FAULTED     0     0     0  too many errors
              nvme-SAMSUNG_SSD_NEW    ONLINE       0     0     0  (resilvering)
            99887766554433221100      ONLINE       0     0     0

Що це означає: resilver в процесі; ZFS реконструює відсутню репліку на новому SSD.
У цей період виживший SSD — ваша єдина добра копія метаданих. Захищайте його.

Рішення: зменшіть навантаження, уникайте перезавантажень і стежте за IO-помилками на вижившому пристрої.

Завдання 9: Моніторити завершення resilver і лічильники помилок

cr0x@server:~$ watch -n 10 'sudo zpool status tank'
  pool: tank
 state: ONLINE
  scan: resilvered 19.2G in 0 days 00:03:18 with 0 errors on Thu Dec 26 02:24:30 2025
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          raidz2-0                  ONLINE       0     0     0
            ata-HDD1                ONLINE       0     0     0
            ata-HDD2                ONLINE       0     0     0
            ata-HDD3                ONLINE       0     0     0
            ata-HDD4                ONLINE       0     0     0
            ata-HDD5                ONLINE       0     0     0
            ata-HDD6                ONLINE       0     0     0
        special
          mirror-1                  ONLINE       0     0     0
            nvme-SAMSUNG_SSD_NEW    ONLINE       0     0     0
            nvme-SAMSUNG_SSD_B      ONLINE       0     0     0

errors: No known data errors

Що це означає: resilver завершився чисто. Надлишковість відновлена.

Рішення: тепер запустіть scrub і валідуйте; не оголошуйте перемогу лише по resilver.

Завдання 10: Запустити scrub для підтвердження цілісності end-to-end

cr0x@server:~$ sudo zpool scrub tank
cr0x@server:~$ sudo zpool status tank | sed -n '1,18p'
  pool: tank
 state: ONLINE
  scan: scrub in progress since Thu Dec 26 02:27:01 2025
        412G scanned at 1.88G/s, 64.1G issued at 291M/s, 2.41T total
        0B repaired, 2.59% done, 0 days 02:19:31 to go

Що це означає: scrub читає і перевіряє контрольні суми по всьому пулу, ремонтує за надлишковістю там, де можливо.

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

Завдання 11: Перевірити SMART/NVMe здоров’я для вижившого і нового пристроїв

cr0x@server:~$ sudo smartctl -a /dev/nvme0n1 | egrep -i 'critical_warning|media_errors|percentage_used|data_units_written'
Critical Warning:                   0x00
Percentage Used:                   12%
Media and Data Integrity Errors:   0
Data Units Written:                9,812,334

Що це означає: немає критичного попередження, низький знос, без помилок медіа. SSD виглядає здоровим.

Рішення: залишайте його. Якщо Media and Data Integrity Errors або Critical Warning більше нуля, плануйте заміну навіть якщо ZFS тимчасово спокійний.

Завдання 12: Виміряти, чи метадані є вузьким місцем (триаж затримки)

cr0x@server:~$ sudo zpool iostat -v tank 2 3
                              capacity     operations     bandwidth
pool                        alloc   free   read  write   read  write
--------------------------  -----  -----  -----  -----  -----  -----
tank                         1.2T  1.1T    820    410  62.1M  28.4M
  raidz2-0                   1.2T  1.1T    120    360  51.2M  26.9M
    ata-HDD1                    -      -     20     60  8.40M  4.60M
    ata-HDD2                    -      -     19     60  8.22M  4.58M
    ata-HDD3                    -      -     21     60  8.62M  4.56M
    ata-HDD4                    -      -     20     60  8.51M  4.51M
    ata-HDD5                    -      -     20     60  8.70M  4.54M
    ata-HDD6                    -      -     20     60  8.75M  4.55M
special                         -      -    700     50  10.9M  1.50M
  mirror-1                      -      -    700     50  10.9M  1.50M
    nvme-SAMSUNG_SSD_NEW         -      -    350     25  5.40M  0.76M
    nvme-SAMSUNG_SSD_B           -      -    350     25  5.50M  0.74M
--------------------------  -----  -----  -----  -----  -----  -----

Що це означає: висока кількість операцій на special відносно пропускної здатності вказує на метадані-важкий IO (багато малих випадкових читань).
Це нормально для обходу директорій, контейнерів, інтенсивного churn метаданих.

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

Завдання 13: Підтвердити використання special vdev і тиск метаданих

cr0x@server:~$ sudo zdb -bbbs tank | sed -n '1,24p'
Dataset tank [ZPL], ID 53, cr_txg 5, 3.12T, 2 objects
Object  lvl   iblk   dblk  dsize  dnsize  lsize   %full  type
     1    2   128K    16K  3.20K    512   16.0K  100.0  DMU dnode
    17    1   128K    16K  3.20K    512   16.0K  100.0  ZAP

Що це означає: zdb може показати структури метаданих і розміри. Це не щоденний інструмент, але корисний для доведення «це навантаження — метадані».

Рішення: якщо середовище заповнене дрібними файлами/VM-метаданими, розмірюйте special відповідно і дзеркальте його щиро.

Завдання 14: Якщо імпорт не вдається, виведіть імпортовані пулі та відсутні пристрої

cr0x@server:~$ sudo zpool import
   pool: tank
     id: 1234567890123456789
  state: UNAVAIL
status: One or more devices are missing from the system.
action: The pool cannot be imported. Attach the missing devices and try again.
   see: zpool-import(8)
config:

        tank                        UNAVAIL  missing device
          raidz2-0                  ONLINE
            ata-HDD1                ONLINE
            ata-HDD2                ONLINE
            ata-HDD3                ONLINE
            ata-HDD4                ONLINE
            ata-HDD5                ONLINE
            ata-HDD6                ONLINE
        special
          nvme-SAMSUNG_SSD_A         UNAVAIL

Що це означає: пул недоступний через відсутній пристрій special. Якщо special був single-disk, це так погано, як здається.

Рішення: не намагайтесь випадкових імпортів з -f. Ваш кращий крок — відновити шлях до пристрою (апаратний фікс) або переключитися на відновлення з бекапу/репліки.

Завдання 15: Якщо пул призупинено, підтвердьте це і припиніть навантаження

cr0x@server:~$ sudo zpool status -x
pool 'tank' is suspended

Що це означає: ZFS призупинив IO для захисту цілісності. Ваші додатки будуть повторювати запити і робити все гірше.

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

Завдання 16: Перевірити, що special vdev присутній у макеті пулу (аудит після відновлення)

cr0x@server:~$ sudo zpool get -H -o property,value ashift,autotrim tank
ashift  12
autotrim on

Що це означає: ashift фіксований при створенні пулу; невідповідність може впливати на продуктивність і довговічність SSD. autotrim допомагає поведінці SSD з часом.

Рішення: тримайте autotrim=on для SSD-backed special vdev, якщо немає специфічної причини проти. Якщо ashift неправильний — плануйте міграцію; не «налаштовуйте» це догори дригом.

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

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

Середня SaaS-компанія розгорнула нове сховище для платформи контейнерів. Інженер, що робив збірку, мав чисту ментальну модель:
дзеркальні HDD vdev для ємності і «швидкий SSD» для метаданих. Він раніше використовував L2ARC і припускав, що special vdev поводиться схоже.
«У найгіршому випадку ми втрачаємо трохи продуктивності», — сказав він команді. Ніхто не посперечався.

Навантаження було класичним метаданним блендером: шари образів контейнерів, купа дрібних конфігураційних файлів і CI, що цілий день розпаковував і видаляв дерева.
SSD для special швидко став «гарячим» — не по пропускній здатності, а по IOPS. Він також став найважливішим пристроєм у пулі.
Вони не мали оповіщень про помилки NVMe, бо шаблон моніторингу був побудований навколо SMART для HDD.

Якось у п’ятницю SSD почав кидати скидання. ZFS позначив його як faulted. Пул став недоступним після перезавантаження.
Їхня перша реакція була «просто імпортувати з примусом», бо rust vdevs були в порядку і вони бачили всі диски.
Імпорт не працював. Потім вони спробували ще раз. І ще. Тим часом автоматика продовжувала намагатись монтувати і запускати сервіси, засипаючи хост IO.

Зрештою хтось помітив, що конфіг пулу включає special vdev і що це єдине місце відмови.
Фікс був не хитрий: знайти ідентичну модель SSD, перемістити її в відомий слот і відновити оригінальний пристрій достатньо, щоб клонувати його на рівні блоків.
Ця порятунок дала їм імпорт і шанс переслати дані кудись інде.

Висновок післярозбору був болісно простим: special vdev — це не опціональне сховище. Це структурна частина.
Їхнє припущення («це як кеш») коштувало їм вихідних і змусило уважно поглянути, скільки інших «швидких доповнень» насправді критичні.

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

Фінансова організація мала ZFS-пул для домашніх директорій користувачів і багато дрібних файлів проектів. Постійні скарги на продуктивність:
повільні пошуки, повільні обходи директорій, повільне індексування IDE. Винуватцем спочатку називали сховище, потім мережу, потім кінцеві точки.
Хтось запропонував special vdev з special_small_blocks=128K на головному наборі даних. «Покладіть все дрібне на SSD — проблема вирішена».

Це дійсно вирішило проблему. Деякий час.
Індексація стала швидшою, git-операції покращилися, черга helpdesk зменшилась. Команда зберігання оголосила успіх і перейшла далі.
Але special-пристрої були невеликими enterprise SSD, призначеними для «метаданих», а не «метадані плюс гора дрібних файлів».

Через шість місяців пул був здоровий, але special майже заповнений. ZFS не вибухнув миттєво — просто стало некомфортно:
виділення обмежилися, фрагментація зросла, і деякі операції знову сповільнилися.
Потім один SSD вдарив сплеск помилок медіа і дзеркало resilver мусило записати багато даних — бо special тримав великий обсяг реальних блоків файлів.

Resilver зайняв більше часу, і виживший SSD був під сильним тиском. Вони пощастило. Оптимізація змінила режим відмов з «помер пристрій метаданих — заміни швидко» на «special тримає критичні файли користувачів і жорстко пише під час resilver».

Ретроспектива не була «ніколи не використовувати special_small_blocks». Вона була «ставтеся до нього як до tier-0 сховища».
Якщо ви зберігаєте там блоки даних, розмірюйте його, дзеркальте правильно і моніторьте як production-critical — бо так воно і є.

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

Медіа-компанія використовувала ZFS для змішаного навантаження: VM, артефакти збірки і багато дрібних ресурсів.
Керівник сховища був без романтики. Кожен пул мав дзеркальний special vdev, і кожен special mirror мав SSD однакової моделі з захистом від втрати живлення.
Вони регулярно запускали scrub, тестували відновлення і мали runbook для «замінити члена special» з командами copy-paste.

Одного дня NVMe у mirror special почав логувати помилки медіа.
Моніторинг зловив це, бо вони мали явні оповіщення по NVMe-метриках і помилках контрольних сум ZFS, а не просто «диск онлайн».
On-call не дебатував. Вони обмежили важкі роботи, замінили диск і спостерігали за resilver.

Resilver пройшов швидко. Вони запустили scrub. Ніяких ремонтів. Жодної драми.
Більшість компанії й не дізналася, що щось сталося — це і є правильний результат інциденту зі сховищем.

Найкраще: команда також документувала, які набори даних використовують special_small_blocks і чому.
Тож коли керівництво питало «можемо зменшити витрати на SSD наступного кварталу», вони не плутались.
Показали, які навантаження залежать від special і який вигляд має відмова. Бюджетні дискусії стали простішими, бо реальність була задокументована.

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

1) Симптом: пул не імпортується, rust vdev виглядають нормально

  • Корінь: відсутній single-disk special vdev (метадані, виділені там, потрібні для імпорту).
  • Виправлення: відновіть відсутній шлях до пристрою (апарат/PCIe/живлення), або відновіть з бекапу/реплікації. Якщо special не був дзеркалений — опції обмежені і неприємні.

2) Симптом: «ls» і навантаження на stat дуже повільні, але тест пропускної здатності нормальний

  • Корінь: special vdev деградований або нездоровий; читання метаданих повторюються, спричиняючи ампліфікацію затримки.
  • Виправлення: перевірте zpool status -v, zpool iostat -v і NVMe логи; замініть несправного члена special; після цього scrub.

3) Симптом: після заміни продуктивність гірша, ніж була

  • Корінь: special vdev видалено/ніколи не використовувався як очікувалось, або політика special_small_blocks змінена і дані не перемістилися.
  • Виправлення: підтвердьте властивості наборів даних; зрозумійте, що існуючі блоки не переміщуються без перезапису; заплануйте міграцію на основі перепису (send/recv або перекопіювання), якщо потрібно репопулювати special.

4) Симптом: пул призупиняється під час пікового навантаження

  • Корінь: серйозні IO-помилки на special vdev змушують ZFS захищатися; іноді невдалий HBA/backplane ускладнює ситуацію.
  • Виправлення: зупиніть IO-хаос, стабілізуйте апарат, потім замініть пристрої. Не дозволяйте сервісам безперервно повторювати запити в призупинений пул.

5) Симптом: special vdev продовжує несподівано заповнюватися

  • Корінь: special_small_blocks встановлено велике для наборів даних з великою кількістю дрібних-середніх файлів; special тепер зберігає значну частину файлів.
  • Виправлення: зменшіть special_small_blocks для нових алокацій (старі блоки не переїдуть), додайте ємність до special (дзеркальні vdev), і заплануйте перепис даних, якщо потрібно евакуювати.

6) Симптом: resilver тягнеться вічно і пул повільний

  • Корінь: special vdev містить великий обсяг малих блоків; resilver сильно навантажує IOPS і конкурує з продакшеном.
  • Виправлення: плануйте resilver при зменшеному навантаженні, переконайтесь, що SSD не троттлиться термічно, і розгляньте ширші дзеркала або швидші пристрої для special.

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

  • Корінь: нестабільність імен пристроїв, неправильний слот, поганий backplane або покладання на /dev/nvmeXn1 імена.
  • Виправлення: використовуйте /dev/disk/by-id; перевірте кабелі/PCIe-лани; уникайте хаосу hotplug без плану.

Запобігання, що працює (і що — культ)

Дзеркаліть special vdev. Завжди.

Якщо пам’ятаєте одне: single-disk special vdev робить весь пул залежним від цього одного пристрою.
Це не «трохи ризиковано». Це проєктна помилка.
Дзеркальте його, бажано двома пристроями однакової моделі і класу витривалості. Якщо ваше середовище критичне — розгляньте 3-way дзеркало.

Вибирайте SSD як дорослий

Метадані і малі блоки — це write-heavy і latency-sensitive. Вам потрібні:
захист від втрати живлення, передбачувана затримка під навантаженням і витривалість, що відповідає вашому churn.
Споживчі SSD можуть працювати в лабораторії і зрадити в продакшені о 2 ранку — саме тоді апарат «виражає свої почуття».

Жарт №2: Використовувати споживчі SSD у ролі special — це як давати інтерну root: інколи блискуче, інколи катастрофічно, і завжди у найнепідходящіший момент.

Дійте свідомо з special_small_blocks

special_small_blocks — потужний параметр. Він також — найпростіший шлях перетворити «пристрій для метаданих» в «зберігає дані користувача».
Це може бути саме те, що вам потрібно для VM boot-штормів, шарів контейнерів або репозиторіїв з дрібними файлами.
Але це змінює планування ємності, поведінку resilver і радіус ураження при відмові.

  • Якщо ви ставите: розмірюйте special під дані, а не лише під метадані.
  • Застосовуйте на рівні набору даних: не робіть blanket-налаштувань по всьому пулу, якщо не розумієте кожне навантаження.
  • Документуйте причину: майбутній ви забуде і звинуватить не те.

Моніторьте важливе (ZFS плюс NVMe)

Потрібні оповіщення на:
помилки контрольних сум ZFS, помилки пристроїв, аномалії resilver/scrub і NVMe media/data integrity errors.
«Диск онлайн» — марна метрика. Диски можуть бути онлайн і брехати.

Операційна дисципліна краща за героїзм

Планові scrubs ловлять латентні проблеми до того, як rebuild змусить читати все під тиском.
Надійні запаси зменшують спокусу використовувати випадкові відновлені диски з таємничою історією.
Runbook знижує шанс замінити не той vdev під час паніки.

Цитата про надійність (перефразована думка)

Перефразована думка: операційний підхід Gene Kranz: будьте «жорсткі та компетентні» у кризах — залишайтеся дисциплінованими, користуйтесь чеклістами і не імпровізуйте у гірший бік.

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

Чекліст A: Коли special vdev стає DEGRADED (дзеркало)

  1. Запустіть zpool status -v; підтвердьте, що помилки на special і ідентифікуйте device token/GUID.
  2. Заморозьте ризикові зміни: зупиніть деплое, відкладіть перезавантаження, зменшіть IO-важкі пакетні задачі.
  3. Перевірте логи ядра на предмет скидань/таймаутів; підтвердьте, що це не спільний контролер/backplane.
  4. Підтвердіть, що у вас правильний пристрій-замінник і при потребі очистіть старі лейбли.
  5. Виконайте zpool replace; моніторте прогрес resilver і лічильники помилок.
  6. Після resilver запустіть scrub; перевірте «0 errors».
  7. Після інциденту: витягніть SMART/NVMe логи, зафіксуйте режим відмови і налаштуйте threshold моніторингу.

Чекліст B: Коли special vdev UNAVAIL і пул не імпортується

  1. Запустіть zpool import; ідентифікуйте відсутні пристрої і підтвердьте, що це special.
  2. Стоп. Не робіть циклічних імпортів з примусом. Кожна спроба може погіршити стрес на пристрої або створити плутанину.
  3. Працюйте з апаратурою: пересадіть у відомий гарний слот, перевірте BIOS/PCIe помилки, живлення, кабелі/backplane.
  4. Якщо пристрій видимий хоч іноді — пріоритезуйте відновлення даних: клонування, іміджування або стабілізація на час імпорту.
  5. Якщо special не дзеркалений і пристрій мертвий: переключайтесь на бекапи/реплікацію. Будьте відвертими щодо втрати; не обіцяйте магію.
  6. Після відновлення: переробіть дизайн пулу. Single special vdev має стати «ніколи знову».

Чекліст C: Після відновлення (те, що команди пропускають)

  1. Підтвердіть, що пул ONLINE і scrub чистий.
  2. Перевірте налаштування special_small_blocks на критичних наборах даних і задокументуйте причину.
  3. Аудитуйте ємність special і запас головного простору; плануйте розширення до того, як стане критично.
  4. Перегляньте моніторинг: помилки ZFS, здоров’я NVMe, термальні тротлінги, PCIe AER події.
  5. Протестуйте відновлення або реплікаційний failover протягом місяця. Якщо не тестуєте — ви не маєте відновлення.

Поширені питання

1) Чи special vdev по суті те саме, що L2ARC?

Ні. L2ARC — це кеш; його втрата неприємна. Special — авторитетне сховище; його втрата може унеможливити імпорт або зробити файли недоступними.

2) Чи special vdev по суті те саме, що SLOG?

Ні. SLOG прискорює синхронні записи для певних навантажень і його можна видалити з обмеженими наслідками. Special тримає метадані і, можливо, блоки даних.

3) Якщо я дзеркалюю основні vdev RAIDZ2, чи потрібно дзеркалити special?

Так. Надлишковість пулу обмежується найменш надлишковим, необхідним компонентом. Один спеціальний пристрій може стати реальною точкою відмови.

4) Яке найбезпечніше значення special_small_blocks?

Для багатьох змішаних навантажень: 0 (тільки метадані) — найбезпечніше. Якщо ви встановлюєте — робіть це по наборах даних і розмірюйте special під фактичні дані.

5) Чи можна видалити special vdev після додавання?

На практиці плануйте «ні» для операційного планування. Навіть якщо платформа підтримує окремі сценарії видалення, блоки, що вже виділені там, треба обробити безпечно.
Трактуйте special як постійну частину дизайну пулу.

6) Якщо пристрій special відмовляє, чи треба перезавантажувати?

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

7) Чому все виглядає добре в бенчмарках пропускної здатності, але користувачі скаржаться?

Багато користувацьких операцій — метадані-важкі: обходи директорій, виклики stat, відкриття дрібних файлів.
Проблеми special вражають IOPS/латентність першими, а не послідовну пропускну здатність.

8) Після заміни special чи потрібен scrub?

Так. Resilver відновлює надлишковість для виділених блоків, але не замінює повної перевірки end-to-end.
Scrub підтверджує цілісність по всьому пулу і може виявити інші слабкі пристрої.

9) Чи можна «вилікуватися» від втрати single-disk special без бекапів?

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

10) Який найкращий ранній сигнал, що special у біді?

Зростання помилок контрольних сум на special, NVMe media/data integrity errors і логи ядра з таймаутами/скиданнями.
Пікі затримки при низькій пропускній здатності теж класичний знак.

Висновок: що можна зробити цього тижня

Відмова special vdev — один з тих інцидентів, де технічна правда різка: якщо ви поклали метадані на один пристрій, ви зробили весь пул залежним від нього.
Вихід — не хитрі команди. Це надлишковість, верифікація і відмова трактувати tier-0 пристрої як аксесуари.

Зробіть ці кроки

  • Аудит: запустіть zpool status і підтвердіть, що special vdev дзеркалені всюди.
  • Перевірка політик: інвентаризуйте special_small_blocks по наборах даних; вирішіть, де це виправдано, а де випадково.
  • Моніторинг: оповіщайте про помилки контрольних сум ZFS і NVMe media/data integrity errors, а не лише «online».
  • Практика: відрепетируйте заміну члена special на непроизводчому пулі; зробіть це нудним.
  • Бекапи/реплікація: перевірте, що ви можете відновити або перемкнутися без геройств. Якщо не можете — виправте це перед наступним відходом диска.

Сценарій-кошмар стає переживаним, коли ви трактуєте special vdev як те, чим він є: нервовою системою файлової системи.
Захищайте її, моніторьте і коли вона дає збій — реагуйте, ніби це має значення.

← Попередня
NAT через VPN: Підключайте конфліктні мережі, не руйнуючи сервіси
Наступна →
Itanium: як «майбутнє серверів» стало предметом жартів

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