ZFS Scrub: як часто запускати та що він доводить

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

Ваш пул ZFS виглядає нормально. Додатки працюють. SMART показує «PASSED». Потім помирає диск, починається resilver, і раптом ви виявляєте, що місяцями жили з прихованою корупцією.
Саме в цей момент люди дізнаються, для чого потрібен scrub.

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

Що насправді робить scrub (і чого він не робить)

Scrub ZFS — це повна перевірка цілісності пулу. ZFS читає всі алоковані блоки, перевіряє контрольні суми і — якщо є надлишковість — ремонтує пошкоджені дані, переписуючи правильні копії.
Ось у чому суть: scrub — це проходження перевірки читання з опціональним відновленням.

Що робить scrub

  • Читає алоковані дані у datasets/zvols/snapshots, а не вільний простір.
  • Перевіряє контрольні суми наскрізь (контрольна сума ZFS зберігається окремо від даних, тому «диск щось повернув» недостатньо).
  • Ремонтує, коли це можливо, використовуючи паритет/дзеркальні копії та переписуючи виправлені блоки (самовідновлюване читання).
  • Виявляє приховані помилки секторів та ненадійні шляхи, які звичайні робочі навантаження можуть не торкнутися.
  • Накопичує докази: лічильники помилок, уражені vdev’и та чи є корупція постійною (немає доброї копії) чи виправлюваною.

Чого scrub не робить

  • Він не перевіряє семантику вашого додатка. Якщо ваш додаток послідовно записав невірні байти, ZFS із задоволенням їх збереже.
  • Він не гарантує відновлюваність резервних копій. Scrub — це не тест відновлення.
  • Він не виправляє «поганий апаратний дизайн.» Якщо ваш HBA, expander або backplane «бреше», scrub може показати симптоми, але не лікує причину.
  • Він не обов’язково читає вільний простір. Корупція в вільному просторі має значення тільки під час алокації, а ZFS не витрачає час на перевірку блоків, яких не існує.

Scrub також не є resilver. Resilver відтворює відсутні дані для заміненого диска або повторно підключеного пристрою. Scrub перевіряє наявні дані і, якщо є надлишковість, лікує їх.
Плутання цих двох призводить до креативних інцидентів.

Жарт №1: Scrub — як зубна нитка: ніхто не любить це робити, але всі обіцяють робити частіше, коли щось починає кровоточити.

Що доводить scrub (і що він лише натякає)

Операції — це мистецтво розуміти, що ваші інструменти можуть довести. Scrub дає сильний сигнал про надійність, але не всезнання.
Трактуйте результати scrub як сигнал надійності з обмеженнями.

Scrub достовірно доводить (з високою впевненістю)

  • ZFS може прочитати алоковані блоки та перевірити їх по контрольних сумах на момент scrub. Якщо scrub завершився чисто, дані пулу на момент читання відповідали записаним контрольним сумах.
  • Шляхи надлишковості можуть доставити правильні дані для блоків, які були невірними на одному пристрої. Показник «repaired» означає, що ZFS мав принаймні одну хорошу копію та переписав її назад.
  • Ваша система здатна витримати повне послідовне читання пулу без колапсу. Це важливо, бо resilver і відновлення в загальному подібні з точки зору навантаження на зберігання.

Scrub натякає (корисно, але не гарантовано)

  • Стан медіа диска. Чистий scrub натякає, що медіа наразі в порядку, але він не прогнозує майбутні відмови. Диски можуть відмовити в будь-який момент.
  • Цілісність контролера/кабелів. Якщо під час scrub з’являються помилки, шлях підозрілий. Якщо помилок не видно, це ще не сертифікат добрих кабелів — просто відсутність спостережених відмов.
  • Запас міцності під навантаження. Швидкість scrub та вплив на затримки виявляють конкуренцію, але «швидкий scrub» не означає, що ваше випадкове I/O навантаження безпечне під тиском.

Чого він не може довести

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

Корисна ментальна модель: scrub відповідає на питання «Чи можу я зараз прочитати все, що мені важливо, і якщо ні — чи можу я це виправити за допомогою надлишковості?»
Це дуже хороше питання. Але не єдине.

Один вислів, який варто тримати у рукописному плані; він болісно правдивий:
«Надія — це не стратегія.» — Генерал Гордон Р. Салліван

Як часто запускати scrub: правила для production

«Правильна» частота scrub — це інженерний компроміс між латентністю виявлення і експлуатаційною вартістю.
Латентність виявлення — це те, як довго ви готові носити приховану корупцію, перш ніж знайдете її. Експлуатаційна вартість — це вплив на продуктивність, знос та увага людей.

Моя стандартна рекомендація (і чому)

  • Домашнє використання / невеликий NAS: щомісячний scrub.
  • Бізнес-файлові та VM пули: кожні 2–4 тижні, орієнтуючись ближче до 2 тижнів для більших пулів.
  • Критичні дані + довге збереження snapshot’ів: кожні 1–2 тижні.
  • Архів / холодне зберігання: щомісяця або щокварталу, але лише якщо ви також робите періодичні відпрацювання відновлення і тримаєте сумісні запасні диски.

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

Дві змінні, що мають насправді змінити ваш розклад

1) Розмір пулу і математика відновлення

Великі пули потребують більше часу на scrub. Довші scrub відкривають ширше вікно, коли ще одна відмова може співпасти з тим, що ви вже під стресом.
Також час відновлення масштабується з ємністю і поведінкою пристроїв під навантаженням. Якщо resilver займає дні, вам слід запускати scrubs частіше, а не рідше, оскільки ви хочете знайти приховані помилки, поки все ще є надлишковість.

2) Ваші об’єми змін даних і збереження snapshot’ів

Scrub читає алоковані блоки, включно з блоками, на які посилаються лише snapshot’и. Довге збереження snapshot’ів збільшує «алоковані дані», навіть якщо живі datasets малі.
Якщо ви зберігаєте місяці snapshot’ів, ви несе більше історичних блоків, які потрібно періодично перевіряти. Інакше ви дізнаєтесь про стару корупцію саме тоді, коли треба відновлювати старі дані. Це не приємний жанр сюрпризів.

А SSD? Чи варто робити scrub рідше?

Ні. Можливо, варто scrub запускати принаймні так само часто, оскільки SSD відмовляють у способи, що виглядають «чистими» до певного моменту.
SSD також мають внутрішню корекцію помилок, яка може маскувати деградацію NAND, поки диск не досягне «обриву».
Scrub — це ваш запит до повного стеку, end-to-end, щоб довести, що пристрій все ще читає і перевіряє контрольні суми.

Вплив на продуктивність: не бійтеся, керуйте

Scrub конкурує за I/O. На HDD пулах це часто великий послідовний читач, який усе одно порушує випадкову I/O латентність.
При змішаних навантаженнях (VM + scrub) користувачі не скаржаться на пропускну здатність; вони скаржаться на стрибки латентності.

Відповідь рідко «ніколи не робити scrub». Відповідь — «робити scrub з запобіжниками»: розклад, обмеження та моніторинг. Ви можете зробити scrubs нудними. Це і є мета.

Scrub за тригером (на додаток до розкладу)

Заплановані scrubs — базова гігієна. Тригери — для певних ризикових подій:

  • Після заміни диска і завершення resilver — запустіть scrub, щоб підтвердити новий стабільний стан.
  • Після переміщення обладнання (новий HBA/backplane/кабелі) — запустіть scrub, щоб виявити проблеми шляху.
  • Після подій живлення або оновлень ядра/драйверів зберігання — запустіть scrub у вікні низької активності.
  • Після появи будь-яких ненульових помилок контрольних сум — scrub запускайте швидше, а не пізніше, після стабілізації системи.

Цікавинки та історія: навіщо існує scrubbing

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

  1. ZFS був розроблений з наскрізними контрольними сумами з самого початку (ера Sun), оскільки контролери і диски можуть повертати «успішні» читання з неправильними даними.
  2. Термін «scrub» існував і до ZFS у зберіганні: RAID-масиви та корпоративні SAN використовували patrol reads для виявлення прихованих секторних помилок перед відновленням.
  3. Проблема прихованих секторних помилок стала важливою, коли ємності дисків перевищили часи відновлення; чим довше відновлення, тим вища ймовірність потрапити на бракований блок під час нього.
  4. ZFS зберігає контрольні суми окремо від блоку, який вони захищають (у метаданих), уникаючи режиму відмови «корупція пошкоджує й контрольну суму» характерного для слабших дизайнів.
  5. ZFS може ремонтувати лише за наявності надлишковості. Однодисковий пул може виявити невідповідності контрольних сум, але не може відновити правильні дані.
  6. Scrub читає також snapshot’и, бо snapshot’и посилаються на старі блоки; це одночасно вигода (верифікація) і витрати (більше для читання).
  7. Деякі помилки — «виправлювані», а деякі — постійні. Це величезна операційна різниця: виправлювані помилки часто вказують на нестабільний пристрій або шлях; постійні помилки означають втрату даних, якщо немає резервної копії.
  8. Scrubs свідомо переривні (pause/stop і resume залежно від реалізації), враховуючи реальні вікна підтримки в production.
  9. Сучасні реалізації ZFS надають налаштування для обмеження впливу scrub, відображаючи перехід від «великих вікон обслуговування» до «завжди ввімкнених мультиорендарних систем».

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

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

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

cr0x@server:~$ zpool status
  pool: tank
 state: ONLINE
  scan: none requested
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          mirror-0                  ONLINE       0     0     0
            ata-WDC_WD80EAZZ-00BKLB0  ONLINE       0     0     0
            ata-WDC_WD80EAZZ-00BKLB0  ONLINE       0     0     0

errors: No known data errors

Значення: Пул онлайн; скан не виконувався; лічильники помилок нулі.
Рішення: Безпечно запускати scrub. Якщо пул DEGRADED, потрібно вирішити, чи scrub терміновий (щоб знайти більше помилок), чи ризиковий (щоб не навантажувати залишені пристрої).

Завдання 2: Запустити scrub (і знати, що він читає)

cr0x@server:~$ sudo zpool scrub tank

Значення: ZFS починає читати алоковані блоки у tank.
Рішення: Робіть це у вікні, де додатковий I/O прийнятний. Якщо це VM-хост о 10:00 в понеділок — ви самі підписались на відгук користувачів.

Завдання 3: Слідкуйте за прогресом scrub і оцініть час до завершення

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: ONLINE
  scan: scrub in progress since Mon Dec 23 01:12:43 2025
        3.21T scanned at 612M/s, 1.04T issued at 198M/s, 18.7T total
        0B repaired, 5.57% done, 1 days 02:11:09 to go
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          mirror-0                  ONLINE       0     0     0
            ata-WDC_WD80EAZZ-00BKLB0  ONLINE       0     0     0
            ata-WDC_WD80EAZZ-00BKLB0  ONLINE       0     0     0

errors: No known data errors

Значення: «Scanned» може випереджати «issued» залежно від обліку; звертайте увагу на issued rate і тренди ETA. Repaired = 0 — добре.
Рішення: Якщо ETA зростає під час робочого часу, розгляньте обмеження через системні налаштування, перенесення вікна scrub або паузу (див. наступні завдання).

Завдання 4: Визначити, чи scrub конкурує з вашим навантаженням

cr0x@server:~$ iostat -x 5 3
Linux 6.8.0 (server)  12/25/2025  _x86_64_  (32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.12    0.00    2.41   18.77    0.00   73.70

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s w_await aqu-sz  %util
sda              92.0  184320.0     0.0   0.00   28.44  2003.5      6.2     512.0  12.21   3.42   98.7
sdb              89.5  179200.0     0.0   0.00   31.02  2002.8      6.0     480.0  14.10   3.64   99.1

Значення: Диски завантажені (~99% util), read await високий (28–31ms). Це нормально для HDD scrub, але може вбити чутливі до латентності навантаження.
Рішення: Якщо користувачі скаржаться або VМ мають стрибки латентності, обмежте вплив scrub або плануйте його на ніч. Якщо await високий і в неробочий час — досліджуйте здоров’я дисків/кабелів.

Завдання 5: Знайти «реальний розмір» того, що потрібно читати (включно зі snapshot’ами)

cr0x@server:~$ zfs list -o name,used,usedbysnapshots,refer,avail -r tank
NAME                 USED  USEDBYSNAPSHOTS  REFER  AVAIL
tank                18.7T             6.2T   128K  12.1T
tank/vm             11.4T             4.8T  6.6T   12.1T
tank/home            2.1T             1.2T  0.9T   12.1T
tank/backups         5.2T             0.2T  5.0T   12.1T

Значення: Scrub читає алоковані блоки; 6.2T — це лише snapshot’и. Це додатковий час scrub, про який ви могли «забути».
Рішення: Якщо scrubs займають надто довго, регулюйте збереження snapshot’ів або розділіть datasets/pools за критичністю, а не за відчуттями.

Завдання 6: Подивитись історію scrub і чи ви взагалі їх робите

cr0x@server:~$ zpool history -il tank | tail -n 12
2025-12-23.01:12:43 zpool scrub tank
2025-11-23.01:09:51 zpool scrub tank
2025-10-23.01:11:02 zpool scrub tank
2025-09-22.01:08:37 zpool scrub tank

Значення: Хтось (або таймер) запускав щомісячні scrubs. Якщо є пропуски — ви працюєте надією.
Рішення: Покладіть scrubs під планувальник, який можна аудитити (systemd timers, cron) і ставте оповіщення про «просрочений scrub».

Завдання 7: Вловіть помилки контрольних сум рано та ідентифікуйте проблемний vdev

cr0x@server:~$ zpool status tank
  pool: tank
 state: ONLINE
status: One or more devices has experienced an error resulting in data
        corruption.  Applications may be affected.
action: Restore the file in question if possible.  Otherwise restore the
        entire pool from backup.
  scan: scrub repaired 0B in 05:41:10 with 2 errors on Mon Dec 23 06:53:53 2025
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          mirror-0                  ONLINE       0     0     0
            ata-WDC_WD80EAZZ-00BKLB0  ONLINE       0     0     2
            ata-WDC_WD80EAZZ-00BKLB0  ONLINE       0     0     0

errors: Permanent errors have been detected in the following files:

        tank/vm@auto-2025-12-01:vm-103-disk-0

Значення: Дві помилки контрольних сум і постійні помилки: ZFS не зміг відновити, бо всі копії були пошкоджені або надлишковість була недостатня для цих блоків.
Рішення: Припиніть стверджувати, що «все нормально». Відновіть уражені дані з бекапу/snapshot’ів (якщо snapshot’и чисті) і негайно почніть розслідування апаратури/шляху.

Завдання 8: Очистити лічильники помилок лише після дій

cr0x@server:~$ sudo zpool clear tank

Значення: Скидає лічильники помилок і очищає статус «errors». Це не виправляє дані.
Рішення: Очищайте лише після: (1) збереження доказів, (2) заміни/підтвердження апаратури і (3) запуску повторного scrub для перевірки стабільності. Інакше ви видаляєте місце злочину.

Завдання 9: Поставити на паузу або зупинити scrub, коли це шкодить (і продовжити пізніше)

cr0x@server:~$ sudo zpool scrub -p tank
cr0x@server:~$ zpool status tank
  pool: tank
 state: ONLINE
  scan: scrub paused since Mon Dec 23 10:04:11 2025
        7.12T scanned at 590M/s, 2.98T issued at 248M/s, 18.7T total
        0B repaired, 15.9% done, scrub paused
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
...

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

cr0x@server:~$ sudo zpool scrub -s tank

Значення: Зупиняє scrub.
Рішення: Використовуйте stop, коли потрібно змінити апарат або коли сам scrub викликає помилки, які треба вирішити спочатку (тайм-аути, ресети).

Завдання 10: Розрізняти scrub і resilver у виводі статусу

cr0x@server:~$ zpool status 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 Tue Dec 24 02:01:17 2025
        1.44T scanned at 312M/s, 620G issued at 134M/s, 6.60T total
        620G resilvered, 9.16% done, 0 days 11:08:33 to go
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        DEGRADED     0     0     0
          mirror-0                  DEGRADED     0     0     0
            ata-WDC_WD80EAZZ-00BKLB0  ONLINE       0     0     0
            replacing-1             DEGRADED     0     0     0
              ata-WDC_WD80EAZZ-00BKLB0  FAULTED     0     0     0  too many errors
              ata-WDC_WD80EAZZ-00BKLB0  ONLINE       0     0     0  (resilvering)

errors: No known data errors

Значення: Це resilver, не scrub. Інший профіль ризику: ви відновлюєте надлишковість.
Рішення: Уникайте запуску scrub під час resilver, якщо лише ви навмисно не перевіряєте хиткий пул і не можете дозволити додаткове I/O. Зазвичай: дочекайтесь завершення resilver, потім запустіть scrub.

Завдання 11: Перевірте журнали пристроїв (Linux), коли scrub викликає ресети

cr0x@server:~$ sudo dmesg -T | tail -n 20
[Mon Dec 23 03:18:11 2025] ata9.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 frozen
[Mon Dec 23 03:18:11 2025] ata9.00: failed command: READ FPDMA QUEUED
[Mon Dec 23 03:18:11 2025] ata9: hard resetting link
[Mon Dec 23 03:18:12 2025] ata9: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[Mon Dec 23 03:18:14 2025] ata9.00: configured for UDMA/133

Значення: Ресети лінків під час важких читань. Це кричить про проблеми з кабелями/backplane/HBA, а не «ZFS надто прискіпливий».
Рішення: Виправляйте фізичний шлях. Scrub лише посланець, який змусив постійні читання.

Завдання 12: Отримати SMART-дані і вирішити, чи замінювати диск

cr0x@server:~$ sudo smartctl -a /dev/sda | egrep -i "Reallocated|Pending|Offline_Uncorrectable|UDMA_CRC|Power_On_Hours"
  9 Power_On_Hours          0x0032   086   086   000    Old_age   Always       -       31254
 197 Current_Pending_Sector  0x0012   100   100   000    Old_age   Always       -       8
 198 Offline_Uncorrectable   0x0010   100   100   000    Old_age   Offline      -       8
 199 UDMA_CRC_Error_Count    0x003e   200   200   000    Old_age   Always       -       14

Значення: Pending/uncorrectable сектори вказують на реальні проблеми медіа. UDMA CRC помилки часто вказують на кабелі/backplane.
Рішення: Якщо pending/uncorrectable > 0 і scrub виявив помилки контрольної суми: замініть диск. Якщо тільки CRC зростає: перепідключіть/замініть кабель/ланку backplane і продовжуйте спостереження.

Завдання 13: Підтвердити ashift і чому це важливо для часу scrub

cr0x@server:~$ zdb -C tank | egrep "ashift|vdev_tree" -n | head
42:        vdev_tree:
57:            ashift: 12

Значення: ashift=12 означає 4K сектори. Неправильний ashift (забагато малий) може викликати читально-модифікуй-запис ампліфікацію і загалом погану поведінку.
Рішення: Якщо ashift неправильний, ви не «налаштовуєте» його. Потрібно планувати міграцію до правильно створеного пулу. Scrub не врятує від фундаментальної помилки.

Завдання 14: Виявити, чи dataset створює патологічні I/O під час scrub

cr0x@server:~$ zfs get -o name,property,value -s local recordsize,compression,atime,dedup tank/vm
NAME     PROPERTY     VALUE
tank/vm  recordsize   128K
tank/vm  compression  lz4
tank/vm  atime        off
tank/vm  dedup        off

Значення: Розумні налаштування для багатьох VM-навантажень. Dedup off — розумний вибір для більшості організацій.
Рішення: Якщо бачите dedup увімкнутий і scrubs/reslivers повільні зі стресом пам’яті, досліджуйте ARC/пам’ять і DDT. Не вгадуйте; вимірюйте.

Завдання 15: Перевірити, що scrub не «швидкий», бо мало читає

cr0x@server:~$ zpool list -o name,size,alloc,free,fragmentation,health
NAME  SIZE   ALLOC  FREE  FRAG  HEALTH
tank  29.1T  18.7T  10.4T   42%  ONLINE

Значення: Allocated = 18.7T. Scrub, що «завершився» за 15 хвилин, ймовірно, не читав 18.7T; ви неправильно читаєте подію (або дивитесь на інший пул).
Рішення: Перевірте тривалість scrub проти alloc і реалістичної пропускної здатності пристроїв. Коли числа не сходяться з фізикою, припускайте, що ви пропускаєте інформацію.

Завдання 16: Використайте журнали подій, щоб скорелювати помилки scrub з часом

cr0x@server:~$ sudo zpool events -v | tail -n 20
TIME                            CLASS
Dec 23 2025 03:18:12.123456789  ereport.fs.zfs.checksum
    zevent.fsname = tank
    zevent.vdev_path = /dev/disk/by-id/ata-WDC_WD80EAZZ-00BKLB0_XXXX
    zevent.vdev_guid = 1234567890123456789
Dec 23 2025 03:18:12.223456789  ereport.fs.zfs.io
    zevent.fsname = tank
    zevent.vdev_path = /dev/disk/by-id/ata-WDC_WD80EAZZ-00BKLB0_XXXX

Значення: ZFS повідомляє, коли і де він бачив помилки контрольної суми/вводу-виводу.
Рішення: Скорелюйте з dmesg та SMART. Якщо події збігаються з ресетами лінків, «поганий диск» може бути лише поганим шляхом.

Швидкий план діагностики: знайти вузьке місце швидко

Коли scrub повільний або викидає помилки, ви можете годинами філософствувати — або виконати швидку триаж, що звузить коло до: диск, шлях, CPU/пам’ять або конкуренція навантажень.
Ось практичний порядок, що економить час.

Перше: що каже ZFS?

  • Перевірте: zpool status -v tank
  • Шукайте: «scrub in progress» vs «resilver»; repaired bytes; «errors: Permanent errors»; який vdev показує приріст READ/WRITE/CKSUM.
  • Рішення: Якщо з’явилися постійні помилки, перемикайтесь із «продуктивності» в режим «відновлення даних». Зберіть докази, ідентифікуйте уражені об’єкти/датасети, плануйте відновлення.

Друге: чи це нестабільність апаратного шляху?

  • Перевірте: dmesg -T | tail -n 200 на ресети/тайм-аути; smartctl на CRC-помилки; журнали HBA, якщо доступні.
  • Шукайте: SATA link resets, SCSI aborts, NVMe resets, «I/O error» спам, що з’являється лише під навантаженням scrub.
  • Рішення: Якщо ресети є: спочатку вважайте це проблемою шляху (кабелі/backplane/HBA/expander/прошивка). Замініть найпростіший підозрілий компонент перш ніж звинувачувати ZFS.

Третє: чи це просто насичення I/O або конкуренція?

  • Перевірте: iostat -x 5, плюс вашу телеметрію латентності.
  • Шукайте: 100% util, високі await, зростання queue depth і вплив на записи.
  • Рішення: Якщо це «нормальне насичення», керуйте ним: плануйте, обмежуйте або ізолюйте навантаження. Якщо await екстремальний навіть при низькій util — підозрюйте прошивку/проблеми диска.

Четверте: чи ZFS/OS позбавлені ресурсів (CPU, RAM, ARC)

  • Перевірте: vmstat 5, тиск пам’яті, розмір ARC, і чи система свопить.
  • Шукайте: активність свопу; kswapd; CPU завантажений в системному режимі.
  • Рішення: Якщо своп активний під scrub — вирішіть проблему з пам’яттю першочергово. Scrub — це читальне навантаження; він не має перетворювати сервер на демон свопу.

П’яте: чи scrub повільний, бо багато читати?

  • Перевірте: zfs list (usedbysnapshots) і zpool list alloc.
  • Шукайте: надмірні snapshot’и, несподівану алокацію або фрагментацію, що призводить до великої кількості seeks.
  • Рішення: Якщо пул просто великий і завантажений — прийміть довший час scrub, але затягніть планування й алерти. Надійність не безкоштовна; вона оплачується IOPS.

Три корпоративні міні-історії зі «скрубових» бойових

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

Середня компанія працювала ZFS на парі серверів зберігання, що обслуговували віртуалізацію. Дзеркала скрізь. Вони почувалися в безпеці — поширена передумова для навчання.
Scrubs вважалися «необов’язковими», бо «RAID1 і enterprise диски».

Диск відмовив у напружений тиждень. Почався resilver. На півдорозі пул почав логувати помилки контрольних сум на живому боці одного дзеркала.
Команда припустила: «ZFS драматизує; воно вилікує». Це припущення стало інцидентом.

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

Операційна помилка була не в тому, що «диск помер». Диски відмовляють. Помилка була в тому, що приймали невідому цілісність тижнями, бо scrubs не були заплановані і відслідковані.
У них були бекапи, але відновлення було повільним і політично важким. Відмова стала питанням на рівні керівництва.

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

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

Інша організація мала великий HDD пул, що скрабився повільно. Користувачі скаржилися на повільність у понеділок вранці.
Хтось запропонував оптимізацію: запускати scrub постійно, але «нізко» обмеживши CPU і дозволивши йому капати. Вони також перенесли вікно scrub у робочий час, бо «воно буде м’яким».

На папері — м’яко. Насправді це створило постійне низько-ступеневе навантаження. Scrub ніколи не отримував достатньо суцільного часу, щоб завершитись швидко, тож він перекривався з кожним піком.
Стрибки латентності не були драматичними; вони були постійними. Це гірше. Люди терплять бурі; вони звільняються через моросяк.

Тим часом scrubs, що тривають вічно, збільшують експозицію. Чим довше пул сканується, тим більше шансів співпасти з не спорідненими відмовами:
глюки контролера, особливості прошивки або просто невдала черга, коли диск вирішив почати тайм-аутити.

Зрештою вони повернулися до строгого нічного scrub з жорстким тайм-аутом в кінці вікна підтримки, потім відновлювали наступної ночі.
Та сама робота, менше страждань користувачів, швидше завершення і менше інцидентів, коли scrub співпав з чимось дивним.

Урок: «завжди вмикнений але повільний» не обов’язково безпечніший. Завершити scrub — це віхова подія надійності. Каплеювати scrub через робочий день — як винайти новий стандарт посередності.

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

Команда фінансових послуг працювала ZFS на дзеркальних vdev’ах для VM-зберігання. Ніякої екзотики. Але була нудна рутина:
двотижневі scrubs, оповіщення про завершення і тикет при будь-якому русі CKSUM.
Вони також логували тривалість scrub і порівнювали з історичними базовими показниками.

Одного циклу scrub завершився, але зайняв помітно більше часу. Помилок не було, просто повільніше. Алерт не підняв нікого, але створив тикет для розслідування, бо тривалість перевищила поріг.
Інженер подивився iostat під час наступного scrub і помітив один диск з вищим await, ніж його дзеркальний партнер.

SMART не показував релокованих секторів, але показував зростання CRC помилок. Вони поміняли кабель і перепідключили диск у backplane.
Наступний scrub повернувся до нормальної швидкості. І все ще без помилок.

Через два тижні той самий слот backplane почав викидати ресети лінків під час традингового вікна з високими IOPS — але тепер команда вже ідентифікувала слот як підозрілий.
Вони переключили трафік, замінили backplane і уникли корупції даних та ширшого інциденту.

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

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

Більшість проблем зі scrub не екзотичні. Це ті самі кілька режимів відмов у різних масках.
Ось короткий список, який я хотів би бачити у більше хто в runbook’ах.

1) Scrub показує помилки контрольної суми, SMART виглядає «добре»

  • Симптом: zpool status показує CKSUM > 0, інколи «Permanent errors». SMART загальний статус — PASSED.
  • Корінь: SMART «PASSED» — не гарантія здоров’я. Корупція також може походити від шляху (кабель/HBA) або RAM, а не лише від медіа.
  • Виправлення: Скорелюйте події ZFS з dmesg. Перевірте CRC помилки. Запустіть повторний scrub після перепідключення/заміни кабелів або перенесення диска на інший порт. Якщо помилки повторюються на тому ж диску через порти — замініть диск.

2) Scrubs «тривають вічно» після збільшення snapshot’ів

  • Симптом: Час scrub подвоївся за місяці; апаратних змін не було; пул в іншому виглядає нормально.
  • Корінь: Збільшення збереження snapshot’ів збільшило алоковані блоки. Scrub читає блоки, на які посилаються snapshot’и, навіть якщо live dataset малий.
  • Виправлення: Перевірте usedbysnapshots. Скорегуйте політику збереження або перемістіть довготривалі snapshot’и на інший пул/рівень зберігання. Переоцінивайте базову тривалість scrub після приведення політики у порядок.

3) Scrub викликає стрибки латентності VM і тикети «storage повільний»

  • Симптом: Під час scrub латентність зростає; користувачі скаржаться; бази даних гальмують; VМ «підвисає» на хвилини.
  • Корінь: HDD насичені scrub-читаннями; черги зростають; синхронні записи чекають за scrub I/O.
  • Виправлення: Плануйте scrubs у негодинні періоди. Розгляньте обмеження через OS/ZFS налаштування на вашій платформі. Якщо це хронічно — реальний фікс: більше шпинделів, SSD або розподіл пулів за навантаженнями.

4) Scrub кожного разу «ремонтує» невелику кількість байт

  • Симптом: Кожен scrub повідомляє про якісь відремонтовані байти, але нічого не ескалується до явного фейлу.
  • Корінь: Маргінальне апаратне чи шляхове поводження викликає періодичні погані читання; ZFS лікує це завдяки надлишковості, маскуючи проблему, поки вона не погіршиться.
  • Виправлення: Розглядайте повторювані ремонти як апаратний інцидент. Ідентифікуйте vdev з ростом помилок. Замініть кабелі/порти, проведіть тривалі тести SMART, замініть пристрій якщо поведінка слідує за ним.

5) Scrub «завершується миттєво» на великому пулі

  • Симптом: Scrub завершено за хвилини; пул має десятки ТБ алокованих; ніхто не вірить у числа.
  • Корінь: Ви зробили scrub не того пулу, дивитесь статус з іншого хоста, або пул має дуже мало алокованих даних (thin allocation, переважно вільно).
  • Виправлення: Підтвердьте zpool list alloc, ім’я пулу, що ви на правильній машині, перевірте історію і валідуйте часові мітки статусу.

6) З’явились постійні помилки, і хтось їх одразу очистив

  • Симптом: «errors: Permanent errors» з’являється, потім зникає після zpool clear, але відновлення не виконувалось.
  • Корінь: Ставлення до стану помилки як до косметичного; тиск на те, щоб прилади показували зелений статус.
  • Виправлення: Політика: ніколи не очищайте до збереження zpool status -v, ідентифікації уражених об’єктів та спроби відновлення. Вимагайте чистого scruba після ремедіації перед закриттям тикету.

7) Швидкість scrub падає після додавання «швидшого» кешу або спеціального пристрою

  • Симптом: Після змін (L2ARC, special vdev) час scrub і латентність погіршились.
  • Корінь: Розміщення метаданих і асиметрія пристроїв може змінити I/O шаблони. Спеціальний vdev, що надто малий або перевантажений, може стати вузьким місцем.
  • Виправлення: Виміряйте використання пристроїв під час scrub. Якщо спеціальний vdev насичений — розширте його або переробіть дизайн. Не підключайте «акселерацію» до пулу без планування поведінки scrub/resilver.

8) Scrub викликає тайм-аути пристрою тільки під навантаженням

  • Симптом: Звичні навантаження в порядку. Scrub викликає I/O помилки, ресети, відключення.
  • Корінь: Маргінальна прошивка, перегрів, проблеми з живленням або шлях, що відмовляє під тривалим пропускним навантаженням.
  • Виправлення: Перевірте температури, живлення, кабелювання, HBA прошивку. Запустіть довгі SMART тести. Розгляньте пониження одночасного навантаження (планування scrub), поки не виправите апаратну проблему.

Жарт №2: Scrub не «виробляє» відмови дисків; він лише просить диск виконувати свою роботу більше, ніж п’ять хвилин.

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

Чек-лист A: Встановіть політику scrub, яку можна захистити

  1. Оберіть частоту за ризиком: почніть з кожні 2–4 тижні для production-пулів.
  2. Визначте поріг «просрочено» (наприклад, 2× ваш інтервал), що тригерить алерт/тикет.
  3. Визначте прийнятний вплив scrub: максимальне вікно, офф-години, правила паузи.
  4. Запишіть, що означає «ненульові помилки» операційно: хто піднімається на виклик, хто розбирається, як доводиться закриття інциденту.
  5. Базуйте тривалість scrub і пропускну здатність; алертуйте про регресії, а не лише про відмови.

Чек-лист B: Операційний runbook для кожного циклу scrub

  1. Перед початком: zpool status (підтвердьте ONLINE і зафіксуйте існуючі лічильники помилок).
  2. Запустіть scrub: zpool scrub tank.
  3. Під час scrub: моніторте zpool status -v і iostat -x для впливу.
  4. Якщо є біль від продуктивності: призупиніть (zpool scrub -p) і відновіть у тихий час.
  5. Після завершення: збережіть вивід zpool status -v для записів.
  6. Якщо repaired > 0 або CKSUM > 0: відкрийте інцидент; зберіть SMART + dmesg + zpool events; плануйте ремедіацію.
  7. Після ремедіації: запустіть повторний scrub і вимагайте його чистого завершення.

Чек-лист C: Коли scrub повідомляє про постійні помилки

  1. Припиніть зміни. Зафіксуйте: zpool status -v, zpool events -v, dmesg -T, SMART-дані для всіх членів.
  2. Ідентифікуйте уражені об’єкти/файли, перелічені в статусі; зіставте їх з datasets/сервісами.
  3. Вирішіть шлях відновлення: відновлення з бекапу, від старішого snapshot’а, або перебудова враженої VM/датасету.
  4. Вирішіть ймовірну причину (замініть диск, виправте шлях, перевірте пам’ять, якщо патерн корупції вказує на це).
  5. Запустіть scrub після ремонту і лише тоді очищайте помилки, якщо потрібно для гігієни.

Приклад: планування через systemd timers (нудно, ефективно)

cr0x@server:~$ cat /etc/systemd/system/zfs-scrub@.service
[Unit]
Description=ZFS scrub on %i

[Service]
Type=oneshot
ExecStart=/sbin/zpool scrub %i
cr0x@server:~$ cat /etc/systemd/system/zfs-scrub@tank.timer
[Unit]
Description=Run ZFS scrub on tank monthly

[Timer]
OnCalendar=monthly
Persistent=true

[Install]
WantedBy=timers.target
cr0x@server:~$ sudo systemctl enable --now zfs-scrub@tank.timer
Created symlink /etc/systemd/system/timers.target.wants/zfs-scrub@tank.timer → /etc/systemd/system/zfs-scrub@tank.timer.

Значення: Тепер у вас аудитується розклад. «Persistent=true» запускає пропущені таймери після простою.
Рішення: Додайте моніторинг, що перевіряє час останнього завершення scrub і результат. Планування без видимості — це просто оптимізм з часовими мітками.

Питання й відповіді (FAQ)

1) Чи запускати scrub на DEGRADED пулі?

Іноді. Якщо підозрюєте приховану корупцію, scrub може показати масштаб. Але він також нагружає залишені пристрої.
Якщо пул деградований через відсутній диск і у вас є заміна під рукою — пріоритет заміні/resilver, потім scrub.

2) Чи те саме scrub і SMART long tests?

Ні. SMART long tests — діагностика на рівні пристрою. Scrub — end-to-end валідація цілісності через файлову систему, контролер і диск.
Робіть обидва. Вони ловлять різні класи відмов.

3) Чи scrub валідує вільний простір?

Загалом ні; він читає алоковані блоки (включно зі snapshot’ами). Вільний простір — це не дані. Ризик у блоках, які вам може знадобитися прочитати пізніше — це алоковані блоки.

4) Чому scrub уповільнюється ближче до кінця?

На початку scrub натрапляє на великі суцільні регіони і кеші; пізні фази можуть включати більше фрагментованих метаданих і розкиданих блоків, що збільшує seeks і знижує пропускну здатність — особливо на HDD.

5) Якщо scrub відремонтував дані, чи тепер я в безпеці?

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

6) Чи можна scrub робити занадто часто?

Можна так часто, що ви постійно конкуруєте з власним технічним навантаженням. Це не «безпечніше», це самонанесена латентність.
Якщо ваші scrubs постійно перекриваються — або пул занадто завантажений, або занадто повільний, або політика snapshot’ів вийшла з-під контролю.

7) Різниця між READ/WRITE/CKSUM помилками у zpool status?

В загальних рисах: READ/WRITE вказують на I/O відмови (тайм-аути, помилки пристрою). CKSUM вказує, що дані прочитано, але вони не відповідають очікуваній контрольній сумі (може бути медіа, шлях, контролер, RAM).
CKSUM помилки мають викликати більший скептицизм щодо «диск каже, що він в порядку».

8) Чи потрібно scrub після заміни диска?

Так, після завершення resilver. Resilver відновлює надлишковість; scrub валідує end-to-end коректність по всьому алокованому простору.
Це різниця між «ми відновили» і «ми перевірили».

9) Чи потрібно scrub, якщо у мене є бекапи?

Так. Резервні копії для відновлення, scrubs — для раннього виявлення. Без scrub ви можете дізнатись про корупцію тільки під час відновлення — часто задовго після останньої відомо доброї копії.

10) Як вирішити, замінювати диск після помилок scrub?

Якщо помилки їдуть за диском через порти/кабелі — замініть диск. Якщо помилки слідують за портом/кабелем/слотом backplane — виправляйте шлях.
Повторні виправлювані помилки не «в нормі». Це таймер відліку з невідомою тривалістю.

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

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

Зробіть наступне

  1. Оберіть частоту: за замовчуванням кожні 2–4 тижні для production-пулів; жорсткіше, якщо пул великий або resilver довгий.
  2. Плануйте scrubs за допомогою аудиторного інструмента (systemd timer/cron) і ставте оповіщення про «просрочені» та «з помилками».
  3. Базуйте тривалість scrub і пропускну здатність, потім алертуйте про регресії — повільність часто перший симптом.
  4. Напишіть політику ескалації для будь-якої ненульової помилки контрольної суми або відремонтованих байт.
  5. Після будь-якої апаратної зміни (диск, кабель, HBA) запустіть scrub у контрольованому вікні і підтвердьте його чисте завершення.

У вашому майбутньому постмортемі аварії буде або «ми знайшли це під час рутинного scrub», або «ми виявили це під час відновлення».
Одне з цих формулювань краще для керівництва. І, що важливіше, одне зазвичай життєздатніше.

← Попередня
MySQL vs MariaDB max_connections: зупиніть OOM-крахи на невеликих серверах
Наступна →
Помилки контрольної суми ZFS у Proxmox: диск чи кабель — як це довести

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