Математика відновлення ZFS RAIDZ: чому ще одна відмова може вас вбити

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

Ваш пейджер спрацьовує о 02:13. Один диск помер. ZFS виконує resilver. Усі хочуть одну відповідь: «За скільки ми будемо в безпеці?»
Погана новина в тому, що «в безпеці» — це не мітка часу. Це крива ймовірності, яка стає гидкою саме тоді, коли вам потрібно, щоб вона була спокійною.

Відновлення RAIDZ — це не тільки про пропускну здатність. Це про час експозиції, рівні помилок і скільки різних способів зберігання може вас підвести,
поки ви займаєтеся його ремонтом. Математика не складна. Наслідки — складні.

Терміни, що мають значення (і ті, які люди неправильно вживають)

RAIDZ — це не «RAID-5, але в ZFS»

RAIDZ — це парітетна схема RAID у ZFS. RAIDZ1 витримує одну відмову диска у vdev. RAIDZ2 витримує дві. RAIDZ3 — три.
Тактова відмовостійкість пулу — це відмовостійкість його найменш відмовостійкого vdev. Якщо у вас є RAIDZ2 vdev плюс окремий mirror vdev,
mirror не є найслабшим. Але наявність RAIDZ1 vdev у складі — це обов’язковий «слабкий ланцюг».

Resilver vs rebuild

«Rebuild» — загальний RAID-термін. ZFS виконує resilver: відтворює відсутні дані на замінний пристрій.
Ключова деталь: ZFS часто копіює лише виділені блоки (не весь диск), тож resilver може бути значно швидшим за класичні rebuild.
Але vdev все одно має прочитати багато даних, щоб перерахувати паритет і перевірити контрольні суми. Якщо ваш пул майже заповнений, «лише виділені блоки»
перетворюється на «більшість блоків», і різниця стає теоретичною.

Scrub не є резервною копією і не є resilver

Scrub читає дані та перевіряє контрольні суми, виправляючи корупцію за допомогою надмірності. Це не зробить вас захищеними від «ой, ми видалили прод».
Але scruby зменшують шанс того, що латентні помилки секторів ви виявите вперше саме під час resilver — коли ви вже втратили один диск.

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

URE означає «unrecoverable read error». Вендори публікують «unrecoverable bit error rate» (UBER), наприклад 10^-14 або 10^-15 біт.
Люди трактують це як «одна помилка на X ТБ», а потім припиняють думати. Фактичний ризик залежить від того:
скільки біт ви читаєте під час resilver, скільки дисків ви читаєте, що робить прошивка під навантаженням,
і чи ви виконували scrubs. Опубліковане число — це відправна точка, а не обіцянка.

Одна цитата, варта того, щоб тримати її на столі. Відому ідею Річарда Кука про складні системи часто стисло формулюють так:
«Успіх у складних операціях базується на адаптації; невдача трапляється, коли оборони вичерпуються.»
(парафразована ідея, Richard Cook)

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

Цікаві факти та коротка історія

  • ZFS був розроблений у середині 2000-х років щоб розглядати зберігання як систему, а не як набір пристроїв, впровадивши end-to-end контрольні суми та самовідновлення.
  • RAIDZ існує, щоб уникнути «write hole» RAID-5 шляхом інтеграції оновлень паритету з copy-on-write транзакційними групами.
  • На ранніх розгортаннях ZFS пам’яті бракувало; мем «ZFS потребує тонни RAM» виник через реальний голод ARC на старих системах, а не через забобони.
  • Реальність 4K секторів змінила все: невідповідності ashift (наприклад, 512e диски змушені працювати з 512-байтовим вирівнюванням) можуть назавжди підвищити навантаження і час відновлення.
  • Ємності дисків росли швидше за їх пропускну здатність; вікна експозиції під час rebuild розширилися, коли диски перейшли від сотень ГБ до десятків ТБ.
  • «Resilver лише використовувані блоки» був переломним порівняно з класичним RAID, але це працює лише за умови невеликої фрагментації і вільного місця.
  • Контрольні суми виявили безшумну корупцію; неприємний побічний ефект — ви знаходите корупцію під час scrubs/resilvers, коли пул під навантаженням.
  • Розширення RAIDZ з’явилося пізно у порівнянні з очікуваннями; оперативно це означало багато «просто додати більші диски і замінювати по черзі» планів.
  • Показники UBER корпоративних HDD покращилися, але сучасна поведінка прошивки під важким чергуванням все ще може викликати тайм-аути, які виглядають як «випадкові відмови».

Чому ще одна відмова може вбити

У RAIDZ1 відмова одного диска ставить вас у стан, коли кожен блок, що залежить від відсутнього диска, має бути реконструйований з решти дисків.
Під час resilver ви працюєте в деградованому режимі: у вас немає надмірності. Ще одна додаткова відмова — другий диск, збій кабелю, перезавантаження контролера,
низка URE на невдалому диску — може перетворити «resilver в процесі» на «відновлення з резервних копій», якщо вони у вас є.

RAIDZ2 дає вам час і варіанти. Не нескінченну безпеку, але простір для маневру. Ви можете витримати другу відмову пристрою під час resilver.
І що важливіше, ви витримаєте кілька помилок читання без того, щоб vdev загнав себе у глухий кут. Практична різниця — психологічна:
інженери перестають робити поспішні, ризикові дії.

Режими відмов не незалежні

Красива математика припускає незалежні відмови: один диск падає, інші мають випадкові URE за вендорними ставками тощо.
Реальність складніша:

  • Диски з однієї партії відмовляються близько один від одного.
  • Навантаження під час resilver шкідливе: постійні читання, висока глибина черги та багато випадкових IO, якщо пул фрагментований.
  • Контролери та експандери напружуються; маргінальні кабелі перестають бути «гарними».
  • Тепловий режим змінюється: вийшов з ладу вентилятор або корпус з поганим повітрообміном перетворюють rebuild у тест на перегрів.
  • Людський фактор: хтось бачить «DEGRADED» і починає міняти залізо, як у грі whack-a-mole.

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

Математика відновлення, яку ви справді можете використати

1) Час експозиції: як довго ви живете небезпечно

Найпростіша й найкорисніша модель: ризик зростає з часом перебування в деградованому стані. Якщо ваш resilver триває 2 години, ви під загрозою 2 години.
Якщо 2 дні — загроза 2 дні. Деталі важливі, але цього достатньо, щоб пояснити, чому надвеликий RAIDZ1 vdev — пастка.

Практична оцінка часу resilver:

  • Дані для копіювання ≈ виділені байти на vdev (не на пул), скориговані вгору за фрагментацією та накладними витратами метаданих.
  • Ефективна пропускна здатність ≈ мінімум з (ширина читання диска, швидкість запису на новий диск, обчислення паритету для vdev, ліміти контролера/експандера та вплив навантаження пулу).
  • Час resilver ≈ дані-для-копіювання / ефективна-пропускна-здатність.

Якщо ви на 80–90% заповнення, очікуйте, що «дані-для-копіювання» буде настільки близько до «всього диска», що це буде незручно, і очікуйте домінування випадкового IO.
Саме тому досвідчені оператори тримають RAIDZ пули нижче приблизно 70–80%, якщо немає вагомої причини інакше.

2) Математика URE: класичний аргумент «чому RAID5 помер у масштабі» (і що змінює ZFS)

Канонічний приблизний підхід:
ймовірність принаймні одного URE при читанні B біт приблизно:
P ≈ 1 − (1 − p)B,
де p — ймовірність URE на біт (наприклад, 10^-14).

Якщо ви читаєте багато бітів, P зростає. Швидко. Помилка — трактувати це як догму в будь-яку сторону:
«URE обов’язково станеться» або «URE ніколи не трапляється на практиці». Обидва підходи ліниві.

Що змінює ZFS:

  • ZFS перевіряє контрольні суми, тож він може виявляти погані дані замість того, щоб подавати їх безшумно.
  • За наявності надмірності (RAIDZ2/3) ZFS часто може відновити блоки за допомогою паритету та інших копій.
  • Під час деградованого RAIDZ1 resilver помилка читання не в тому блоці може стати невиправною, бо відсутній диск знімав останню подушку безпеки.

3) «Скільки дисків треба читати?» — реальна відповідь

Під час RAIDZ resilver система читає з усіх решти дисків у vdev, щоб відновити відсутні дані. Це означає:
чим більше дисків у vdev, тим більше агрегованих читань, тим більше можливостей для:
тайм-аутів, URE і «цей диск був нормальний, поки ви не попросили його прочитати все».

Ширші vdev можуть чудово працювати для послідовної пропускної здатності. Вони також чудово концентрують ризик під час resilver.
RAIDZ2 з розумною шириною — зазвичай дорослий вибір для великих HDD пулів.

4) Математика продуктивності, яка кусає: малі блоки і фрагментація

Швидкість resilver не лише «MB/s диска». Якщо ваші дані складаються з малих блоків (бази даних, VM, поштова скринька),
ZFS виконує більше обходів метаданих, більше переміщень голівок, і ваша ефективна пропускна здатність руйнується.
Якщо у вас є стиснення, ви можете читати менше з диска, ніж логічний розмір даних. Якщо у вас є dedup, ви можете ускладнити собі життя іншими способами.

Справжня математика відновлення — це поєднання:
вікно експозиції × ймовірність додаткових відмов за одиницю часу × ймовірність невідновлюваних читань на прочитані дані.
Вам не потрібен PhD, щоб це використовувати. Потрібно просто перестати вважати, що час відновлення — константа.

Як насправді працює resilver у ZFS (і чому він інколи перемагає)

Copy-on-write і transaction groups

ZFS — це copy-on-write. Він записує нові блоки, потім оновлює вказівники. Це зменшує експозицію «write hole», бо ZFS може зберігати консистентний стан на диску
через transaction groups. Паритет RAIDZ інтегрований у ці записи.

Чому «лише виділені блоки» одночасно правда й оманлива

ZFS виконує resilver на основі того, що вважає зайнятим, а не «на кожному LBA на диску». Це добре.
Але є три підводні камені:

  • Заповненість пулу: якщо ви на 85% — виділені блоки становлять більшість диска.
  • Фрагментація: виділені блоки розкидані, тож resilver стає випадковим IO.
  • Накладні витрати метаданих: непрямі блоки, spacemap-и й gang blocks додають читань та навантаження на CPU.

Послідовний resilver проти лікувального resilver

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

Жарт №2: Найшвидший resilver — той, який ви запланували до того, як диск відмовив — на жаль, диски відмовляються отримувати календарні запрошення.

Що справді сповільнює resilver

1) Пул зайнятий, і ZFS поводиться ввічливо

ZFS навмисно уникає захоплення всієї системи. Resilver IO конкурує зі звичайним IO.
Це чудово для користувачів. Це жахливо для «повернути надмірність якнайшвидше».
Ви можете налаштувати це, але робити це бездумно — значить погіршити затримки продакшну і спричинити тайм-аути, що виглядатимуть як апаратні збої.

2) Один повільний диск тягне весь vdev

RAIDZ vdev поводяться як команда веслярів. Один весляр похмурий — усі повертають на місці.
Маргінальний диск, що не «помер», може стати вузьким місцем читань, викликаючи довгі resilver-и і більше стресу.

3) Контролери, експандери та кабельні з’єднання

Rebuild-и чудово виявляють те, що ви ніколи не тестували: непевний порт SAS-експандера, кабель, що «гарний» на холостому ходу,
баг у прошивці контролера, або бекплейн, що нагрівається і починає кидати помилки.
Якщо логи показують скиди лінків під час resilver — трактуйте це як інцидент надійності, а не як загадкову проблему продуктивності.

4) Помилки ashift — назавжди

Якщо пул створено з неправильним ashift, кожен запис буде не вирівняний. Це збільшує IO і гірше впливає на час відновлення.
Ви не можете виправити ashift на місці. Вирішуєте це, перебудувавши пул правильно. Ось чому «просто швидко створити пул» — кар’єрно обмежувальний крок.

5) CPU зазвичай не вузьке місце — поки ним не стане

Сучасні CPU зазвичай справляються з паритетом RAIDZ і контрольними сумами. Але сильна компресія, шифрування та високі IOPS можуть змінити це.
Слідкуйте за CPU під час resilver. Якщо він завантажений по максимуму — ваші диски чекають на обчислення.

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

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

Перший крок: підтвердіть домен відмов і реальний радіус ураження

  • Чи це один vdev у DEGRADED, чи кілька?
  • Чи пул насправді повертає помилки, чи лише відновлюється?
  • Чи є помилки контрольних сум (погані дані) або лише помилки пристрою (проблема шляху)?

Другий крок: ідентифікуйте клас вузького місця

  • Один повільний диск: один диск показує високу латентність / низьку пропускну здатність.
  • Проблема шини/шляху: скиди лінків, помилки SAS, тайм-аути, блимання multipath.
  • Конкуренція навантаження: продакшн IO відбирає ресурси у resilver.
  • Навантеження CPU/пам’яті: компресія/шифрування або треш ARC уповільнюють усе.

Третій крок: вжити найменш ризикову коригувальну дію

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

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

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

Нижче — польові завдання, які ви можете виконати прямо зараз. Кожне містить: команду, що означає вивід, і рішення, яке треба прийняти.
Імена хостів, пула та пристроїв — приклади; підлаштуйте під своє середовище.

Завдання 1: Перевірити стан пулу та статус resilver

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: DEGRADED
status: One or more devices is currently being resilvered.
action: Wait for the resilver to complete.
  scan: resilver in progress since Fri Dec 26 02:20:17 2025
        3.12T scanned at 410M/s, 1.84T issued at 242M/s, 6.20T total
        1.84T resilvered, 29.68% done, 6:05:11 to go
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        DEGRADED     0     0     0
          raidz2-0                  DEGRADED     0     0     0
            sda                     ONLINE       0     0     0
            sdb                     ONLINE       0     0     2
            sdc                     ONLINE       0     0     0
            sdd                     ONLINE       0     0     0
            sde                     ONLINE       0     0     0
            sdf                     ONLINE       0     0     0
            sdg                     ONLINE       0     0     0
            sdh                     ONLINE       0     0     0
            replacing-1             DEGRADED     0     0     0
              sdi                   FAULTED      0     0     0  too many errors
              sdz                   ONLINE       0     0     0  (resilvering)

errors: No known data errors

Значення: «issued» — це фактично виконана робота; «scanned» може бути вищим. Збільшення CKSUM на живому диску (sdb) — тривожний сигнал.

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

Завдання 2: Побачити IO по vdev, щоб виявити повільний пристрій

cr0x@server:~$ zpool iostat -v tank 5 3
                              capacity     operations     bandwidth
pool                        alloc   free   read  write   read  write
--------------------------  -----  -----  -----  -----  -----  -----
tank                        92.1T  28.7T  1.02K   210   310M  52.1M
  raidz2-0                  92.1T  28.7T  1.02K   210   310M  52.1M
    sda                         -      -    120    25  38.5M  6.3M
    sdb                         -      -     11    24   1.2M  6.2M
    sdc                         -      -    121    25  38.7M  6.2M
    sdd                         -      -    122    24  38.8M  6.1M
    sde                         -      -    121    26  38.6M  6.4M
    sdf                         -      -    120    25  38.5M  6.3M
    sdg                         -      -    121    25  38.6M  6.2M
    sdh                         -      -    120    25  38.4M  6.1M
    sdz                         -      -    287    22  66.1M  5.9M
--------------------------  -----  -----  -----  -----  -----  -----

Значення: sdb майже не дає читальної пропускної здатності порівняно з іншими.

Рішення: Негайно перевірте sdb (SMART, кабелі, шлях контролера). «Повільний, але онлайн» диск може вбити вікно вашого resilver.

Завдання 3: Переглянути нещодавні події ZFS на предмет блимання пристроїв

cr0x@server:~$ zpool events -v | tail -n 20
TIME                           CLASS
Dec 26 2025 02:14:03.129812000  sysevent.fs.zfs.dev_remove
    pool = tank
    vdev_path = /dev/sdi
    vdev_guid = 1234567890123456789
Dec 26 2025 02:16:44.410223000  sysevent.fs.zfs.config_sync
    pool = tank
Dec 26 2025 02:20:17.004901000  sysevent.fs.zfs.resilver_start
    pool = tank
    vdev_path = /dev/sdz

Значення: Підтверджує хронологію remove/replace; корисно для кореляції з логами і діями людей.

Рішення: Якщо ви бачите повторювані події remove/add — сприймайте це як нестабільність шляху (експандер/кабель/HBA), а не як «поганий диск».

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

cr0x@server:~$ zpool status -x
pool 'tank' is not healthy

Значення: Все ще DEGRADED; без нюансів, але це швидка перевірка стану для дашбордів і рунбуків.

Рішення: Використовуйте її як умову очищення alert-ів лише після перегляду детального статусу.

Завдання 5: Витягнути SMART та лічильники помилок для підозрілого диска

cr0x@server:~$ sudo smartctl -a /dev/sdb | egrep -i "Model|Serial|Reallocated|Pending|Offline_Uncorrectable|UDMA_CRC|Error|SMART overall"
Device Model:     WDC WD140EDGZ-11B2DA2
Serial Number:    9JH3K1AB
SMART overall-health self-assessment test result: PASSED
Reallocated_Sector_Ct   0x0033   100   100   010    Pre-fail  Always       -       0
Current_Pending_Sector  0x0012   100   100   000    Old_age   Always       -       8
Offline_Uncorrectable   0x0010   100   100   000    Old_age   Offline      -       8
UDMA_CRC_Error_Count    0x003e   200   199   000    Old_age   Always       -       3

Значення: Pending/offline uncorrectable sectors — погано; CRC помилки вказують на проблеми з кабелем/бекплейном/HBA.

Рішення: Pending sectors під час resilver? Замініть диск. CRC, що зростають? Перепідключіть/заміни кабель, перевірте логи експандера/HBA.

Завдання 6: Запустити короткий SMART-тест (якщо дозволяєте)

cr0x@server:~$ sudo smartctl -t short /dev/sdb
Please wait 2 minutes for test to complete.
Test will complete after Fri Dec 26 03:01:42 2025

Значення: Короткий тест може швидко виявити очевидні відмови.

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

Завдання 7: Слідкувати за логами ядра на предмет скидів лінків і тайм-аутів

cr0x@server:~$ sudo dmesg -T | egrep -i "sas|scsi|reset|timeout|link|I/O error" | tail -n 12
[Fri Dec 26 02:44:18 2025] sd 5:0:7:0: [sdb] tag#913 FAILED Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_OK
[Fri Dec 26 02:44:18 2025] sd 5:0:7:0: [sdb] CDB: Read(16) 88 00 00 00 00 10 2a 3f 00 00 00 00 80 00 00 00
[Fri Dec 26 02:44:19 2025] sas: phy-7: reset complete
[Fri Dec 26 02:44:22 2025] sd 5:0:7:0: [sdb] Sense Key : Medium Error [current]
[Fri Dec 26 02:44:22 2025] sd 5:0:7:0: [sdb] Add. Sense: Unrecovered read error

Значення: Тайм-аути + помилки носія під час важких читань — саме те, що викликає resilver.

Рішення: Помилки носія: замінити диск. Повторні PHY reset на кількох дисках: підозрюйте експандер/HBA/кабелі/прошивку.

Завдання 8: Визначити, чи пул занадто заповнений (resilver буде тягнути довше)

cr0x@server:~$ zfs list -o name,used,avail,refer,mountpoint -S used tank | head
NAME            USED  AVAIL  REFER  MOUNTPOINT
tank            92.1T  28.7T   128K  /tank
tank/vm         41.8T  28.7T  41.8T  /tank/vm
tank/backups    28.2T  28.7T  28.2T  /tank/backups
tank/home       13.4T  28.7T  13.4T  /tank/home

Значення: ~76% виділено. Керовано, але якщо б це було 90%+, боль від resilver збільшується різко.

Рішення: Якщо >80% використано — плануйте звільнення місця або додавання ємності після інциденту; не нормалізуйте «майже повні» RAIDZ пули.

Завдання 9: Перевірити фрагментацію (тихий вбивця resilver)

cr0x@server:~$ zpool list -o name,alloc,free,frag,cap,health
NAME   ALLOC   FREE  FRAG  CAP  HEALTH
tank   92.1T  28.7T   41%  76%  DEGRADED

Значення: 41% фрагментації перетворить «копіювання виділених блоків» у безліч пошуків.

Рішення: Висока frag + повільний resilver: зменшіть навантаження, очікуйте довшого вікна; розгляньте майбутню переробку (більше vdev-ів, інший recordsize, тримати пули менш заповненими).

Завдання 10: Перевірити ashift (вирівнювання) vdev

cr0x@server:~$ zdb -C tank | egrep "vdev|ashift" | head -n 20
        vdev_tree:
            type: 'raidz'
            id: 0
            guid: 9876543210123456789
            ashift: 12
            nparity: 2

Значення: ashift 12 означає вирівнювання під 4K. Добре для сучасних HDD/SSD. ashift 9 на 4K-native/512e — класична власна помилка.

Рішення: Якщо ashift невірний — не «налаштовуйте» систему; заплануйте правильну міграцію на коректно створений пул.

Завдання 11: Підтвердити recordsize / volblocksize для ключових datasets (впливає на розташування даних і поведінку resilver)

cr0x@server:~$ zfs get -o name,property,value -s local recordsize,volblocksize tank/vm tank/home
NAME      PROPERTY     VALUE
tank/vm   volblocksize 16K
tank/home recordsize   128K

Значення: VM zvols з volblocksize 16K можуть створювати багато seeks; home dataset з recordsize 128K більш послідовний.

Рішення: Якщо resilver-и хронічно повільні на пулах з великою кількістю VM — розгляньте спеціальні vdev-і для метаданих, більше vdev-ів або mirrors для шарів, чутливих до IOPS.

Завдання 12: Призупинити конкуруючу роботу: знайти топ споживачів I/O

cr0x@server:~$ sudo iostat -x 5 2
Linux 6.5.0 (server)  12/26/2025  _x86_64_  (32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.41    0.00    6.32   18.77    0.00   62.50

Device            r/s     w/s   rkB/s   wkB/s  await  svctm  %util
sda             98.1    22.4  39512    6821   28.4   3.1   95.2
sdb             11.3    21.9   1290    6720  412.7  10.2   99.8
sdz            210.4    18.2  67711    5812   16.9   2.7   89.4

Значення: sdb має 400ms await і 99.8% util під час дрібних читань. Це «похмурий» весляр.

Рішення: Якщо латентність диска крайня — не чекайте, поки він «відновиться». Замініть його або виправте шлях; інакше ваш resilver — повільне лихо у рухомому режимі.

Завдання 13: Знайти помилки контрольних сум на рівні dataset (латентна корупція)

cr0x@server:~$ zpool status -v tank | sed -n '/errors:/,$p'
errors: Permanent errors have been detected in the following files:

        tank/home@daily-2025-12-25:/documents/finance.xlsx

Значення: Є як мінімум одна permanent error: ZFS не зміг відновити цей блок із надмірності.

Рішення: Запустіть інцидент-реакцію: ідентифікуйте власників даних, відновіть з резервної копії/реплікації snapshot-ів і перегляньте рівень надмірності та частоту scrub.

Завдання 14: Запустити scrub після resilver (перевірочний прохід)

cr0x@server:~$ sudo zpool scrub tank
cr0x@server:~$ zpool status tank | egrep -A3 "scan:"
  scan: scrub in progress since Fri Dec 26 09:02:11 2025
        1.34T scanned at 620M/s, 410G issued at 190M/s, 120T total
        0B repaired, 0.34% done, 178:22:10 to go

Значення: Scrub повільніший на великих пулах; «repaired» рівний 0 — добре, але «to go» важливий для планування.

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

Три корпоративні міні-історії (анонімізовані, правдоподібні, болючі)

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

Компанія середнього розміру тримала один великий ZFS пул для «усіх даних, що не в базі». Це був RAIDZ1, бо хтось запам’ятав,
що RAIDZ2 «витрачає надто багато місця», і таблиці в Excel люблять вигравати дискусії.

Диск відмовив у п’ятницю вночі. On-call замінив його і спостерігав за індикатором прогресу resilver. Він рухався повільно.
Команда припустила, що єдиний ризик — друга відмова диска, що здавалося малоймовірним на вихідних.
Вони залишили пул під повною продуктивністю, бо «клієнти не можуть мати простою».

Через дванадцять годин ZFS почав логувати помилки контрольних сум на іншому диску. SMART показував «PASSED», тому команда відмахнулася.
Resilver тривав. Потім другий диск почав видавати велику кількість непрочитаних секторів саме на блоках, потрібних для реконструкції даних з відсутнього диска.
RAIDZ1 не мав запасного паритету. vdev зіпсувався настільки, що пул перестав бути надійним.

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

Відновлення було брудним: відновлення з об’єктних резервних копій для більшості даних, часткова втрата даних для кількох орендарів,
і місяць витраченого часу на перебудову з RAIDZ2 та суворішу політику scrub. Висновок постмортему був жорстким:
«Ми трактували паритет як страхування, а потім скасували поліс у тиждень, коли він нам був потрібен».

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

Внутрішня аналітична платформа з ZFS пулом для ферми VM почала отримувати скарги: спайки затримки запису,
іноді зависання під час snapshot-ів. Доброзичливий інженер налаштував пул для пропускної здатності: ширші RAIDZ vdev-і («більше дисків = швидше»),
агресивне стиснення для всього і більший recordsize, бо «великий IO ефективний».

В бенчмарках виглядало добре. Послідовні читання літали. Скарги зменшилися. Через шість місяців один диск відмовив. Resilver був крижаним.
Не лише «години», а «дні», хоча пул не був майже заповнений.

Причина: навантаження складалося з малих випадкових IO від VM, з інтенсивною роботою з метаданими і численними snapshot-ми.
Широкий vdev означав, що більше дисків брало участь у кожній операції реконструкції. Стиснення підвищило навантаження на CPU під час resilver
саме тоді, коли система вже виконувала паритетні та контрольні обчислення. А великий recordsize на невідповідних датасетах
збільшив write amplification і фрагментацію з часом.

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

Після цього вони переробили архітектуру: менші, численніші vdev-і; RAIDZ2; ретельне тонке налаштування datasets (VM відокремлені від bulk storage);
і правило, що будь-яка зміна продуктивності має містити тест «що відбувається під час resilver» як частину приймання.
Оптимізація не зазнала поразки, бо була дурною. Вона зазнала поразки, бо ігнорувала математику відновлення.

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

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

Їх дизайн був навмисно непримітний: RAIDZ2 vdev-і помірної ширини, гарячі спейри, щомісячні SMART long тести,
і scrubs за графіком, що відповідав їх домену відмов. Вони також дотримувалися жорсткої цільової заповненості: як тільки пули наближалися до неї,
робота з розширення ємності ставала запланованою і фінансованою як будь-яке інше production-завдання.

Коли диск відмовив, on-call слідував рунбуку: підтвердити, що інші диски не мають зростаючих CRC, зменшити неважливі batch-завдання,
замінити диск, спостерігати за resilver, потім виконати scrub. Resilver завершився за години, а не дні, бо пул мав запас і низьку фрагментацію.

Через тиждень інший диск показав зростання pending sectors. Він ще не відмовив, але його замінили проактивно у вікні техобслуговування.
Ніякого простою. Ніякої драми. «Витрат» — кілька додаткових дисків і трохи часу в календарі. Це дешево.

Що їх врятувало — не магічний прапорець ZFS. Це дисципліна працювати зі стороною зберігання як із системою, що має залишатися відновлюваною,
а не лише швидкою. Їх нудні практики запобігли захоплюючому інциденту.

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

1) Resilver «застряг» на низькому відсотку

Симптом: «resilver in progress… 2% done… time remaining: days» майже не змінюється.

Корінна причина: Сильна фрагментація, важке випадкове IO або один повільний диск, що тягне швидкість читання.

Виправлення: Ідентифікуйте повільний диск через zpool iostat -v і iostat -x; зменшіть навантаження; замініть підозрілий диск; тримайте пула менш заповненими в довгостроковій перспективі.

2) Зростаючі CKSUM на «ONLINE» диску під час resilver

Симптом: zpool status показує інкременти CKSUM на живому пристрої.

Корінна причина: Справжні помилки носія або (дуже часто) нестабільність шляху: SAS скиди, поганий кабель, проблеми експандера.

Виправлення: Перевірте dmesg на скиди/тайм-аути; перевірте SMART CRC-лічильники; пересадіть/замістьіть кабелі; оновіть прошивку HBA; замініть диск при появі medium errors/pending sectors.

3) Пул переходить у FAULTED під час rebuild RAIDZ1

Симптом: Після другої «невеликої» проблеми пул стає недоступним або повідомляє permanent errors.

Корінна причина: RAIDZ1 не мав запасу; URE або друга відмова пристрою/шляху зробили деякі блоки невідновлюваними.

Виправлення: Відновлення з backup/snapshots; перебудувати з RAIDZ2 або mirrors; збільшити частоту scrub; не використовувати RAIDZ1 для великих HDD vdev-ів у продакшні.

4) Rebuild повільний лише в одному шасі/поличці

Симптом: Схожі пули в інших місцях відновлюються швидше; цей завжди тягне.

Корінна причина: Бекплейн/експандер як вузьке місце, теплове тротлінг або погане кабелювання, локалізоване в цьому корпусі.

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

5) Scrubs постійно знаходять «кілька помилок», але ніхто не звертає уваги

Симптом: Регулярні ремонти контрольних сум або випадкові permanent errors нормалізовані.

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

Виправлення: Ставте ремонти scrub як інциденти з порогами; замінюйте підозрілі диски; перевіряйте кабелювання; переконайтеся, що рівень надмірності відповідає реальності.

6) Додавання більшого налаштування погіршило resilver

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

Корінна причина: Налаштування, що збільшують IO-ампліфікацію або навантаження на CPU; широкі vdev-і; неправильний recordsize; надмірна компресія/шифрування без запасу ресурсів.

Виправлення: Відкотіть зміни; перегляньте їх з точки зору шляхів відновлення; проєктуйте для rebuild, а не лише для дашбордів.

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

Коли диск відмовляє (RAIDZ): інцидентний рунбук

  1. Закріпіть сцену: зафіксуйте zpool status -v, zpool events -v та dmesg -T для хронології.
  2. Підтвердьте залишкову надмірність: RAIDZ1 degraded = нуль запасу. RAIDZ2 degraded = один запас. Відкоригуйте терміновість відповідно.
  3. Перевірте на наявність другого слабкого диска: запустіть SMART на всіх дисках vdev, принаймні на підозрілих (та сама модель, той самий слот, та сама ланцюжок експандера).
  4. Стабілізуйте шлях: CRC-помилки або скиди лінків означають: виправте кабелювання/HBA перед тим, як «спалити» ще диски.
  5. Правильно замініть відмовлений пристрій: використовуйте zpool replace з постійними ідентифікаторами пристрою; уникайте roulette /dev/sdX.
  6. Зменште конкуруюче навантаження: призупиніть важкі батчі, зменште міграцію VM, відкладіть резервні копії, що плюються на пул.
  7. Моніторьте швидкість resilver і помилки: стежте за зростанням CKSUM і зниженням пропускної здатності, що сигналізує про формування другої відмови.
  8. Після resilver — scrub: валідація пулу і вишукування латентної корупції поки ще є надмірність.
  9. Проведіть післяінцидентний огляд проєкту і ємності: якщо resilver тривав «надто довго», це проблема дизайну, а не просто невдача.

Чек-лист дизайну: будувати RAIDZ з урахуванням математики відновлення

  1. Віддавайте перевагу RAIDZ2 для великих HDD vdev-ів: розглядайте RAIDZ1 як архівний або для дисків малого обсягу, де вікна експозиції короткі.
  2. Тримайте ширину vdev розумною: дуже широкі vdev-і збільшують читальний fan-out і концентрацію ризику.
  3. Тримайте пули в межах цільової заповненості: плануйте 70–80% як «норму», а не «марнування».
  4. Scrub за графіком, який ви можете пояснити: часто достатньо, щоб виловити латентні помилки до відмови; не настільки часто, щоб потопити продакшн.
  5. Стандартизуйте на постійних іменах пристроїв: шляхи by-id, а не /dev/sdX.
  6. Тестуйте поведінку resilver: у staging симулюйте заміну диска і вимірюйте час rebuild під типовим навантаженням.
  7. Майте запаси і людські резерви: гарячий спейр — добре; людина, яка знає процедуру — краще.

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

1) Чи безпечніше resilver у RAIDZ у порівнянні з класичними RAID rebuild?

Часто безпечніше, бо ZFS має end-to-end контрольні суми і може resilver лише виділені блоки, а не кожен LBA.
Але деградований RAIDZ1 все ще на лезі бритви: ще одна відмова диска, шляхова проблема або невідновлюваний сектор можуть вбити vdev.

2) Чому «scanned» перевищує «issued» у zpool status?

«Scanned» — це обсяг, який ZFS оглянув; «issued» — IO, фактично відправлені для resilver. Сканування може включати обходи метаданих і роботу, що не конвертується 1:1 у записи.
Якщо issued низький — часто ви обмежені випадковим IO, конкуренцією або повільним диском.

3) Чи варто піднімати пріоритет resilver, щоб завершити швидше?

Іноді так, але лише з розумом. Якщо ви занадто задушите продакшн IO, можете спричинити тайм-аути і вторинні відмови.
Безпечніший хід — спочатку зменшити навантаження (поставити батчі на паузу, стягнути VM), а потім тонко налаштувати.

4) Чи гарантує RAIDZ2, що я не втратю дані під час rebuild?

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

5) Наскільки широким має бути RAIDZ2 vdev?

Однозначної відповіді немає. Операційно «розумна ширина» означає: час відновлення прийнятний, і латентність окремого диска не домінує.
Для HDD пулів багато команд вибирають помірну ширину RAIDZ2 vdev-ів, а не ультра-широкі монстри. Вимірюйте на власному навантаженні.

6) Чому мій resilver став повільнішим на 60% ніж на 10%?

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

7) Якщо SMART каже PASSED, чи диск в порядку?

Ні. SMART overall — грубий підсумок. Дивіться на pending sectors, offline uncorrectables і CRC помилки.
Диск може «PASS», одночасно саботуючи ваш resilver.

8) Чи треба виконувати scrub частіше чи рідше?

Частіше, ніж «ніколи», рідше, ніж «постійно». Мета — виявити латентні помилки поки ще є надмірність і до того, як відмова змусить виконати resilver.
Якщо scrubs впливають на продакшн, плануйте їх і контролюйте навантаження; не кидайте їх.

9) Mirrors vs RAIDZ у ризику відновлення — який компроміс?

Mirrors відновлюються копіюванням з одного живого диска на заміну, зазвичай швидше і з меншим читальним fan-out.
RAIDZ має кращу ємнісну ефективність, але більший blast radius при відновленні. Якщо у вас IOPS-чутливий робочий навантаження або строгий RTO — mirrors часто краще.

10) Чи можу я просто «додати ще один диск» до RAIDZ vdev, щоб зменшити ризик?

Ризик — це радше рівень паритету, час експозиції при відновленні та поведінка помилок. Додавання дисків може підвищити пропускну здатність, але також розширити домен відмов.
Якщо вам потрібна більша безпека — підвищуйте паритет (RAIDZ2/3) або змінюйте топологію vdev, а не лише ширину.

Наступні кроки, які варто зробити цього тижня

Якщо ви експлуатуєте RAIDZ у продакшні, ставтеся до математики resilver як до бюджету. Ви витрачаєте безпеку з кожною годиною деградації.
Завдання — скоротити вікно і збільшити запас.

  1. Аудит рівня паритету: знайдіть будь-які RAIDZ1 vdev-і, що підтримують критичні дані. Якщо диски — великі HDD, плануйте міграцію на RAIDZ2 або mirrors.
  2. Виміряйте реальний час resilver: не довіряйте вендорським MB/s. Проведіть контрольну заміну в staging або некритичному пулі і занотуйте часи.
  3. Встановіть графік scrub і пороги: вирішіть, яка кількість відремонтованих/контрольних помилок триггерить заміну диска або перевірку кабелів.
  4. Перевірте заповненість пулу і фрагментацію: якщо ви живете вище 80% — ви свідомо вибираєте довші, ризиковіші відновлення.
  5. Укріпіть нудні речі: постійні імена пристроїв, запасні диски, відомі-good прошивки і рунбуки, що не припускають героїчних дій.

День, коли ви втратите дані, рідко співпадає з днем першої відмови диска. Це день, коли ви зрозумієте, що ваші припущення про відновлення були фантазією.
Зробіть математику реальною зараз, поки ви ще можете обирати форму вашого провалу.

← Попередня
Debian 13: журнал повільних запитів MySQL — знайдіть запит, що тихо вбиває сервер
Наступна →
Аварії оновлень: як один поганий патч може вивести з ладу весь світ

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