ZFS: Виявлення тихого псування даних — що scrub, коли й чому

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

Більшість збоїв голосні: контролер помирає, лінк обривається, диск вилітає з пулу як неввічливий учасник, що пішов раніше. Тихе псування — протилежність. Ваші програми продовжують повертати HTTP 200, а дані потихеньку «згнивають». І раптом ви відновлюєте резервну копію, запускаєте звіт, відкриваєте фото, відтворюєте відео або піднімаєте базу — і відчуваєте в животі, що таке «checksum mismatch».

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

Тихе псування: що це і чому ви можете цього не помітити

Тихе псування даних — це коли біти змінюються без повідомлення вашого програмного забезпечення. Немає помилки вводу/виводу. Немає паніки ядра. Немає контролера RAID, що кричить. Читання проходить успішно і повертає байти — просто не ті байти, які ви записали. Ось чому це проблема надійності, а не просто проблема заліза.

Є кілька поширених шляхів, як це трапляється:

  • Помилки носія, що не проявляються як помилки. Диски можуть повертати «успішні» читання з неправильними даними через внутрішні дефекти, баги прошивки, маргінальні сектори або алгоритми відновлення, які помиляються.
  • Неправильні записи. Втрата живлення, помилки кешування запису або ненадійні кабелі/контролери можуть призвести до того, що запис потрапляє неправильно або неповністю.
  • Пошкодження пам’яті. Дані були в порядку на диску, але RAM перевернула біт до того, як було обчислено контрольну суму або записано на диск.
  • Проблеми з DMA/кабелями. Трохи пошкоджений HBA, backplane або кабель може пошкодити дані в дорозі. Диск зробив саме те, що ви йому наказали. Проблема в тому, що ви наказали не те.

Класичні файлові системи зазвичай мають два вибори: довіряти стеку нижче або додати часткове контрольне сумування тільки для метаданих. ZFS не довіряє. Він верифікує.

Одна суха втіха: тихе псування рідкісне на добре збудованих системах. Одна суха застереження: «рідкісне» — це не стратегія. Також не спасе «ми маємо RAID».

Жарт №1: RAID означає «Redundant Array of Inexplicable Decisions» коли ви вважаєте, що воно перевіряє ваші дані. Зазвичай — ні.

Як ZFS ловить псування: контрольні суми, самовилікування та обмеження

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

Що означає «від початку до кінця» на практиці

Коли додаток записує блок:

  1. ZFS обчислює контрольну суму вмісту блоку.
  2. ZFS записує новий блок на диск (copy-on-write), потім оновлює метадані, щоб вказати на нього, включно з контрольною сумою.
  3. Пізніше, коли блок читають, ZFS повторно обчислює контрольну суму і порівнює її зі збереженою.

Якщо контрольна сума не збігається, ZFS знає, що дані неправильні. Це вже велика річ: виявлення кращє за тихий провал. Але ZFS також може відремонтувати їх, якщо ви надали надмірність.

Самовилікування: лише якщо є добра копія

З mirror або RAIDZ, ZFS може прочитати з іншої копії/набору парності, знайти правильну версію і перезаписати пошкоджену копію. Це те самовилікування, про яке ви чули. Без надмірності (пул з одним диском) ZFS все одно виявляє псування, але не може витягти правильні дані з нікуди.

Це незаперечна модель мислення:

  • Контрольні суми виявляють псування.
  • Надмірність ремонтує псування.
  • Scrub примушує верифікацію на масштабі.

Чим scrub не є

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

  • Не виправить псування, яке ідентично у всіх репліках (погані дані, записані консистентно).
  • Не виправить корупцію на рівні застосунку (додаток записав сміття; ZFS його вірно зберіг).
  • Не замінить резервних копій або версіонування. Якщо корупція стара і ви виявили її пізніше, вам можуть знадобитися історичні копії.

І scrub не те саме, що resilver. Resilver — цільова реконструкція після заміни або повторного підключення пристрою. Scrub — періодична верифікація всього.

Одна переписана ідея, яка добре старіє: paraphrased idea від John Allspaw (operations/reliability): «Системи ламаються хаотично та несподівано; потрібні зворотні звʼязки, які скажуть вам, коли реальність відхиляється від припущень». Scrub — один із таких зворотних звʼязків.

Що насправді робить scrub

Scrub ZFS обходить дерево блоків пулу та виконує читання для кожного виділеного блоку. Для кожного блоку він перевіряє контрольну суму. Якщо контрольна сума не проходить і є надмірність, ZFS читає альтернативні копії/парність, ремонтує пошкоджену і фіксує подію. Якщо надмірності немає або пошкодження невиліковне, ви побачите постійні помилки.

Профіль навантаження scrub

Scrub переважно виконує послідовноподібні читання на рівні vdev, але патерн доступу залежить від фрагментації і recordsize. На спокійному пулі з великими записами scrubs можуть бути ввічливими. На сильно фрагментованому пулі з великою кількістю дрібних випадкових блоків scrub поводиться як повільний шторм випадкових читань.

Scrub конкурує з вашим реальним навантаженням за:

  • пропускну здатність дисків і IOPS
  • глибину черги HBA/контролера
  • ARC (кеш) і пропускну здатність пам’яті
  • CPU (обчислення контрольних сум, декомпресія, парність)

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

Що перевіряється

Scrub перевіряє виділені блоки, а не вільний простір. Він валідує і метадані, і блоки даних. Якщо у вас є snapshot-и, scrub охоплює блоки, на які посилаються snapshot-и, бо ті блоки все ще виділені. Саме тому scrubs на пулах з великою кількістю snapshot-ів можуть тривати вічно: ви попросили ZFS зберегти старі блоки, і він їх перевірить.

Чому scrubs важливі навіть якщо ви «ніколи не читаєте старі дані»

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

Що scrub (і з чим не плутати scrub)

Scrub виконуйте по пулу. Не по dataset. Не по директорії. Цілісність ZFS — це властивість рівня пулу. Ваша одиниця істини — zpool.

Цілі scrub: практичний список

  • Продукційні пулі з надмірністю (mirror/RAIDZ): scrub регулярно. Ви хочете автоматичний ремонт, поки це ще можна виправити.
  • Пули резервних копій: scrub ще ретельніше. Резервні копії, що не перевірені, — це просто оптимістичні архіви.
  • Пули з одним диском: scrubs все одно виявляють корупцію, але не прикидайтеся, що вони «виправляють» її. Поєднуйте з гарними резервними копіями і, за можливості, додавайте надмірність.
  • Холодне сховище з рідкими читаннями: scrubs — ваш єдиний рутинний шлях читання. Без scrub-ів ви на віддаленні від дня відновлення до жалю.

Не плутайте це зі scrub-ом

  • SMART тести перевіряють сигнали здоров’я диска, а не цілісність даних від початку до кінця.
  • RAID patrol read (апаратний RAID) читає смуги, але зазвичай не може валідувати коректність даних на рівні застосунку.
  • Перевірки файлових систем на нефайлових системах переважно валідують узгодженість метаданих, а не коректність даних.
  • Резервні копії не є верифікацією, якщо ви реально не тестуєте відновлення або принаймні не перевіряєте контрольні суми збережених обʼєктів.

Коли запускати scrub: розклади, що переживуть реальність

Люди питають про «правильний» інтервал scrub-ів. Його немає. Є лише інтервал, що відповідає вашій толерантності до ризику, температурі даних, розміру пристрою і операційному бюджету.

Ось опініонований базовий план, який працює в більшості команд:

  • Загальні продукційні пулі: scrub щомісяця.
  • Резервні/архівні пулі: scrub щомісяця, іноді раз на два тижні, якщо пул великий і RTO відновлення важливий.
  • Кластери з БД і VM з великою зміною даних: scrub щомісяця, але контролюйте вплив (вікна поза піком, налаштування, моніторинг). Якщо щомісячно занадто руйнівно, виправте недостатність I/O — не припиняйте перевірки.
  • Дуже великі пулі (сотні ТБ+): частота scrub-ів має враховувати тривалість scrub-а. Якщо scrub займає 20 днів, «щомісячно» стає комічним. Можливо, потрібно збільшити пропускну здатність, зменшити кількість snapshot-ів або розділити робочі навантаження.

Дві важливі обмеження важливіше за календарі:

  1. Час виявлення vs. час до відмови. Якщо у вас накопичуються латентні секторні помилки, ви хочете виявити їх до того, як інший диск відмовить і надмірність буде скомпрометована.
  2. Час завершення scrub-а. Scrub, що ніколи не закінчується — це ритуал, а не контроль.

Scrub-и також взаємодіють з ризиком під час resilver. Якщо ви відкладаєте scrub на рік і втрачаєте диск, resilver буде читати величезні обсяги даних, і тоді латентні помилки проявляться. Краще знаходити й виправляти латентні помилки під час scrub-а, поки пул здоровий.

Жарт №2: Пропуск scrub-ів через «продуктивність» — як уникати походу до стоматолога через брак часу. В результаті заплатите дорожче і будете кричати.

Коли не слід запускати scrub

  • Безпосередньо перед великою міграцією, відпрацюванням відновлення або ребалансуванням даних.
  • Під час відомих періодів деградації продуктивності (відновлення, resilver-інги, інтенсивна реплікація).
  • Коли у вас вже відсутня надмірність (пул degrad-ed). У такому випадку вирішіть усвідомлено: scrub деградованого пулу може додатково навантажити залишкові диски, але також може виявити непрочитувані блоки рано. Зробіть це усвідомлено.

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

Все нижче має бути готовим для copy-paste. Суть не в команді. Суть у рішенні, яке ви приймете після її виконання.

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

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: ONLINE
status: One or more devices has experienced an error resulting in data corruption.
action: Restore the file in question if possible. Otherwise restore the entire pool from backup.
  scan: scrub repaired 0B in 03:12:41 with 2 errors on Sun Feb  4 02:11:03 2026
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     0

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

        tank/data/app.db

Що це означає: Пул ONLINE, але ZFS знайшов постійні помилки в файлі. «Repaired 0B» вказує, що він не зміг вилікувати ці блоки з надмірності, або пошкоджені блоки були в метаданих так, що ремонт неможливий.

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

Завдання 2: Запустити scrub (і зрозуміти, що ви щойно зробили)

cr0x@server:~$ sudo zpool scrub tank

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

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

Завдання 3: Моніторинг прогресу scrub-а

cr0x@server:~$ zpool status tank
  pool: tank
 state: ONLINE
  scan: scrub in progress since Mon Feb  4 01:13:22 2026
        1.20T scanned at 824M/s, 620G issued at 415M/s, 8.40T total
        0B repaired, 7.38% done, 05:20:11 to go
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     0

errors: No known data errors

Що це означає: «Scanned» vs «issued» важливі. Scanned — логічний прогрес; issued — фактично відправлені I/O. Якщо issued значно відстає, щось обмежує I/O або scrub конкурує з навантаженням.

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

Завдання 4: Поставити scrub на паузу (бо існує продакшн)

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

Що це означає: Scrub призупинено і може бути відновлено пізніше. (Підтримка залежить від реалізації ZFS; в OpenZFS це звичайно працює.)

Рішення: Якщо ви регулярно призупиняєте scrubs, ймовірно, у вас недостатньо I/O headroom. Виправте це, або ви врешті перестанете scrub-ити зовсім.

Завдання 5: Зупинити scrub (грубий інструмент)

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

Що це означає: Зупиняє scrub. Прогрес втрачено; наступний запуск починає з початку.

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

Завдання 6: Визначити, який vdev/пристрій дає помилки контрольної суми

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: DEGRADED
status: One or more devices could not be used because the label is missing or invalid.
  scan: scrub repaired 32M in 02:40:11 with 0 errors on Sun Feb  2 03:02:11 2026
config:

        NAME        STATE     READ WRITE CKSUM
        tank        DEGRADED     0     0     0
          mirror-0  DEGRADED     0     0     0
            sda     ONLINE       0     0    18
            sdb     UNAVAIL      0     0     0  cannot open

errors: No known data errors

Що це означає: sda повертає погані дані (CKSUM помилки). sdb недоступний. Ви працюєте без надмірності і залишковий диск вже підозрілий.

Рішення: Це ситуація «припиніть неважливі I/O». Негайно відновіть надмірність. Також витягніть SMART для sda і перевірте кабелі/HBA. Помилка контрольної суми часто вказує на проблему шляху, а не лише на диск.

Завдання 7: Зіставити імена пристроїв з фізичними дисками (щоб не замінити неправильний)

cr0x@server:~$ ls -l /dev/disk/by-id/ | grep -E 'sda|sdb'
lrwxrwxrwx 1 root root  9 Feb  4 01:22 ata-SAMSUNG_MZ7LM960HAJM_S3Z9NX0K123456 -> ../../sda
lrwxrwxrwx 1 root root  9 Feb  4 01:22 ata-SAMSUNG_MZ7LM960HAJM_S3Z9NX0K654321 -> ../../sdb

Що це означає: Ви можете ідентифікувати модель/серійник, привʼязаний до кожного вузла пристрою. Імена пристроїв у ZFS слід використовувати стабільні, де можливо.

Рішення: Використовуйте шляхи /dev/disk/by-id у конфігурації пулу надалі. При заміні звіряйте серійний номер, а не свої надії.

Завдання 8: Отримати SMART здоровʼя та лічильники помилок

cr0x@server:~$ sudo smartctl -a /dev/sda
=== START OF INFORMATION SECTION ===
Model Family:     Samsung based SSDs
Device Model:     SAMSUNG MZ7LM960HAJM-00005
Serial Number:    S3Z9NX0K123456
Firmware Version: GXT5204Q
...
SMART overall-health self-assessment test result: PASSED
...
ID# ATTRIBUTE_NAME          VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  5 Reallocated_Sector_Ct   100   100   010    Pre-fail  Always       -       0
187 Reported_Uncorrect      100   100   000    Old_age   Always       -       2
199 UDMA_CRC_Error_Count    200   200   000    Old_age   Always       -       38

Що це означає: «PASSED» — не чисте свідоцтво здоровʼя. UDMA_CRC_Error_Count часто вказує на кабель/backplane/HBA. Reported_Uncorrect означає, що пристрій бачив некориговані помилки.

Рішення: Якщо CRC-помилки зростають, замініть кабель/слот backplane, переставте або перемістіть диск на інший порт перед заміною диска. Якщо кількість некоригованих помилок зростає, плануйте заміну диска.

Завдання 9: Перевірити лічильники помилок ZFS з часом (базова лінія важлива)

cr0x@server:~$ zpool status -P tank
  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 03:12:41 with 0 errors on Sun Feb  2 03:02:11 2026
config:

        NAME                                            STATE     READ WRITE CKSUM
        tank                                            ONLINE       0     0     0
          mirror-0                                      ONLINE       0     0     0
            /dev/disk/by-id/ata-SAMSUNG...123456        ONLINE       0     0     1
            /dev/disk/by-id/ata-SAMSUNG...654321        ONLINE       0     0     0

errors: No known data errors

Що це означає: Є 1 помилка контрольної суми на одній стороні mirror-а. Одна помилка може бути давньою або поточною тенденцією.

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

Завдання 10: Подивитися властивості пулу і vdev, що впливають на поведінку scrub

cr0x@server:~$ zpool get all tank | egrep 'ashift|autoreplace|autotrim|failmode|autoexpand'
tank  ashift       12                    local
tank  autoexpand   off                   default
tank  autoreplace  off                   default
tank  autotrim     on                    local
tank  failmode     wait                  default

Що це означає: ashift=12 (4K сектора) типовий. autotrim впливає на поведінку SSD. Це не безпосередні регулятори scrub-а, але впливають на write amplification, процеси заміни і стабільність продуктивності пристрою.

Рішення: Якщо ви використовуєте SSD, тримайте autotrim=on, якщо немає вагомої причини інакше. Для автоматизації заміни подумайте про autoreplace уважно — автоматизація чудова, поки вона не впевнено замінює неправильну річ.

Завдання 11: Перевірити налаштування датасетів, що посилюють біль від scrub (compression, recordsize, snapshots)

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

Що це означає: Розумні значення за замовчуванням: LZ4, 128K recordsize, atime вимкнено. Менший recordsize для VM-образів може збільшити метадані й фрагментацію, впливаючи на поведінку scrub-а.

Рішення: Для VM zvol/dataset свідомо налаштовуйте recordsize/volblocksize. Не звинувачуйте scrub у макеті, який ви самі створили.

Завдання 12: З’ясувати, чи помилки прив’язані до конкретного файлу

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 02:58:03 with 1 errors on Sun Feb  2 03:02:11 2026
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     0

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

        tank/data/logs/2026-01-17.gz

Що це означає: ZFS інколи може вказати імʼя ураженого файлу. Не завжди, але коли може — прийміть цей подарунок.

Рішення: Відновіть або згенеруйте файл наново. Для логів ви можете прийняти втрату; для баз даних — ні. У будь-якому разі — розглядайте це як сигнал для розслідування шляху/пристрою.

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

cr0x@server:~$ sudo dd if=/tank/data/logs/2026-01-17.gz of=/dev/null bs=1M status=progress
104857600 bytes (105 MB, 100 MiB) copied, 0.42 s, 249 MB/s

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

Рішення: Якщо читання дає I/O помилки або файл не читається — потрібне відновлення з резервної копії або snapshot-а. Не намагайтеся «cat» шляхом обходу реальної корупції.

Завдання 14: Проінспектувати I/O навантаження під час scrub-а (приклад для Linux)

cr0x@server:~$ iostat -x 1 3
Linux 6.6.0 (server)  02/04/2026  _x86_64_ (16 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.10    0.00    5.55   18.40    0.00   63.95

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s w_await aqu-sz  %util
sda             820.0  345000.0     0.0   0.00   12.40   420.7      5.0     120.0  5.20   10.2   96.0
sdb             790.0  339000.0     0.0   0.00   11.90   429.1      4.0     100.0  4.80   10.0   94.5

Що це означає: Диски максимально завантажені (~95% util). Затримка читання (~12 ms) може бути прийнятною або катастрофічною залежно від вашого навантаження.

Рішення: Якщо латентність продакшну страждає, плануйте scrub-и поза піком, збільшуйте кількість vdev (більше шпинделів), або відокремте робочі навантаження. «Просто не scrub-ити» — так ви станете навчальним прикладом.

Завдання 15: Переконатися, що ви не scrub-ите через фантомні стрибки часу або пропущені запуски

cr0x@server:~$ zpool history -i tank | tail -n 12
2026-02-02.03:02:11 zpool scrub tank
2026-02-02.05:58:14 zpool scrub -s tank
2026-02-03.02:01:00 zpool scrub tank
2026-02-03.06:12:09 zpool scrub -p tank
2026-02-04.01:13:22 zpool scrub tank

Що це означає: Оператори (або автоматизація) часто стартують/зупиняють scrub-и. Це запах проблем: або розклад неправильний, або вплив занадто великий, або обидва.

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

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

Коли scrub повільний або зʼявляються помилки, потрібно швидко відповісти на три питання: Чи він взагалі просувається? Чи він заблокований через I/O, CPU чи щось дивне? Ми бачимо справжню корупцію чи помилки транспорту?

Перше: Чи просувається scrub і чи зростають помилки?

  1. Запустіть zpool status двічі через 60 секунд.
  2. Порівняйте «scanned» і «issued» і перевірте, чи лічильники READ/WRITE/CKSUM зростають.
cr0x@server:~$ zpool status tank
  pool: tank
 state: ONLINE
  scan: scrub in progress since Mon Feb  4 01:13:22 2026
        1.30T scanned at 815M/s, 700G issued at 430M/s, 8.40T total
        0B repaired, 8.10% done, 05:10:11 to go
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     0

errors: No known data errors

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

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

Друге: Що це — IOPS, пропускна здатність, CPU чи конкуренція?

  • Диск завантажений: iostat -x показує високий %util і зростаючий await → ви обмежені I/O або конкуруєте з навантаженням.
  • CPU завантажений: top показує високий system/kernel, накладні витрати на контрольні суми/парність, можливо декомпресію. Швидкість scrub-а може падати на RAIDZ з слабким CPU.
  • ARC churn: тиск пам’яті може спричиняти додаткові читання; перевірте free -h і інструменти ARC для вашої платформи.
cr0x@server:~$ top -b -n 1 | head -n 15
top - 02:11:08 up 31 days,  6:22,  2 users,  load average: 12.44, 10.80, 9.21
Tasks: 312 total,   2 running, 310 sleeping,   0 stopped,   0 zombie
%Cpu(s): 22.0 us,  0.5 sy,  0.0 ni, 70.0 id,  7.5 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  64256.0 total,   3120.4 free,  23120.9 used,  38014.7 buff/cache
MiB Swap:   4096.0 total,   4096.0 free,      0.0 used.  40110.2 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 1421 root      20   0       0      0      0 I  18.2   0.0  12:44.21 z_wr_iss
 1412 root      20   0       0      0      0 I  14.7   0.0  10:03.88 z_rd_iss

Рішення: Якщо CPU простий/вільний і iowait високий — ви звʼязані зі сховищем. Якщо CPU завантажений, а диски — ні — ви обмежені обробкою або чимось іншим (наприклад, однопоточні вузькі місця на старому залізі). Міняйте одну змінну за раз: графік, layout vdev, або апаратний запас потужності.

Третє: Помилки CKSUM — «поганий диск» чи «поганий шлях»?

Помилки контрольних сум можуть бути спричинені:

  • Фактична корупція носія на пристрої
  • Поганий SATA/SAS кабель або expander
  • Ненадійна прошивка або драйвер HBA
  • Нестабільне живлення для диска/backplane

Коруеліруйте лічильники ZFS CKSUM з SMART CRC-помилками та логами ядра.

cr0x@server:~$ dmesg | egrep -i 'ata|sas|scsi|reset|crc|error' | tail -n 10
[123456.789] ata4: hard resetting link
[123457.012] ata4: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[123457.345] ata4.00: configured for UDMA/133
[123457.678] ata4.00: failed command: READ DMA EXT
[123457.679] ata4.00: status: { DRDY ERR }
[123457.680] ata4.00: error: { ICRC ABRT }

Рішення: Якщо бачите ICRC/CRC помилки і ресети лінку — спочатку підозрюйте шлях. Замініть кабель, перемістіть на інший порт, оновіть прошивку HBA. Диски часто звинувачують у багатьох гріхах, які вони не скоїли.

Три міні-історії з реального життя

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

Компанія працювала на великій платформі даних, що виглядала сучасною здалеку: контейнери, service mesh і монітори скрізь. Сховище «було вирішено» парою mirror-пулів на вузол. У них був квартальний «тиждень технічного обслуговування», коли хтось запускав scrub, якщо згадав. Зазвичай — не згадували.

Неправильне припущення було простим: «Mirrors захищають нас від відмов дисків, і додаток реплікує дані все одно». Mirror вважали як ковдру від RAID1, а не як систему цілісності даних. Ніхто не питав, як швидко корупція буде виявлена, або що станеться, якщо поганий блок з’явиться на обох сторонах mirror-а, тому що корупція була введена ще до запису на диск.

Потім з’явився запит на відновлення — нічого драматичного. Команді потрібен був старий датасет для повторного навчання. Робота впала з помилками контрольних сум на кількох блоках. Інженери робили те, що роблять під тиском: повторювали спроби, перезапускали, переносили навантаження. Помилки пересувалися разом із ним.

Зрештою хтось запустив zpool status -v і побачив постійні помилки в файлах, які давно не читали. Пул був технічно «ONLINE», тож моніторинг мовчав. Mirror тихо віддавав пошкоджені блоки, бо ніхто не примусив верифікацію холодних даних. Щомісячний scrub знайшов би це раніше й виправив із надмірності або з snapshot-ів, що ще залишалися. Натомість єдиними доступними копіями були вже однаково неправильні.

Урок не в тому, що «ZFS провалився». ZFS зробив саме те, що обіцяв: виявив корупцію. Система провалилася, бо організація вважала перевірку необовʼязковою. Контролі цілісності, які не застосовуються, — просто віра з CLI-синтаксисом.

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

Середня SaaS-компанія працювала ZFS на спільному шарі зберігання. Scrub-и були заплановані щомісяця, але інженери скаржилися, що вони викликають стрибки латентності в базах клієнтів. Тому команда зробила «оптимізацію»: збільшили частоту до щотижневої, але налаштували її на роботу в робочий час з нижчим пріоритетом I/O на рівні ОС і дозволили scrub-у «йти скільки треба».

На папері це виглядало респонсибельно: постійне легке сканування замість великого щомісячного заходу. На практиці воно стало постійним фоновим шумом. Scrub ніколи не встигав завершитися до наступного запуску. Оператори звикли бачити «scrub in progress» як норму, тож ніхто не помітив, коли швидкість scrub-а впала на 80% після того, як HBA почав логувати ресети лінку.

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

Після інциденту вони змінили правило: scrub має завершуватися в межах визначеного вікна, і ніякі scrub-и не запускаються під час деградації пулу або resilver-а без явного дозволу. Також додали алерти на «scrub працює довше, ніж X» і «пропускна здатність scrub менша Y протягом Z хвилин». Успіх оптимізації був не в тонкому налаштуванні, а в обмеженнях робіт.

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

Фінансова компанія славилася консервативними операціями. Не захопливо. Не модно. Але вони запускали scrub-и щомісяця на кожному пулі ZFS і вели невеликий ранобук, де оператори записували: час останнього scrub-а, відремонтовані байти і лічильники помилок пристроїв. Також вони проводили щоквартальні відпрацювання відновлення для вибірки датасетів. Люди скаржилися, що це паперова тяганина. Саме цього і хотіли.

Одного місяця scrub відремонтував трохи даних на RAIDZ2 — нічого масштабного, але не нуль. Лічильники показували кілька CKSUM помилок, локалізованих на одному пристрої. SMART виглядав «добре». Оскільки вони відстежували тренди, було видно, що кількість помилок контрольної суми зросла з минулого місяця. Вони спочатку замінили кабель. Помилки продовжилися. На наступному вікні вони замінили диск.

Через два тижні інший диск у тому самому vdev почав давати помилки читання. Якби перший диск не замінили проактивно, вони опинилися б у RAIDZ2 з двома маргінальними пристроями під час вікна відновлення — саме тоді латентні помилки проявляються. Натомість пул залишився здоровим, scrub-и чисті, інцидент не стався.

Нічого героїчного. Жодних нічних залів збору. Жодних ескалацій на рівні керівництва. Лише буденний цикл зворотного звʼязку: scrub, запис, реакція. Нудне — це фіча інженерії зберігання.

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

1) «Пул ONLINE, отже все добре»

Симптом: Усе зелено, але пізніше ви бачите постійні помилки у старих файлах.

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

Виправлення: Запускайте scrub регулярно і налаштуйте алерти на будь-які рядки errors: у zpool status, а не лише на стан пулу. Інтегруйте результати scrub-а в моніторинг.

2) Scrub-и ніколи не завершуються

Симптом: zpool status завжди показує «scrub in progress», ETA безглузда, оператори ігнорують повідомлення.

Корінна причина: Недостатньо I/O headroom; scrub заплановано занадто часто; велика кількість snapshot-ів; фрагментація; конкуренція з навантаженням.

Виправлення: Встановіть SLO завершення: scrub має завершуватися в X годин/днів. Зменшіть кількість snapshot-ів, збільшіть паралелізм vdev, плануйте поза піком або розділіть пули за навантаженням.

3) Зростання CKSUM на одному пристрої, але SMART говорить PASSED

Симптом: zpool status показує інкременти CKSUM; SMART overall health каже PASSED.

Корінна причина: Часто транспорт: поганий кабель, ненадійний HBA, проблеми backplane/expander. SMART не є джерелом істини щодо цілісності даних.

Виправлення: Перевірте UDMA_CRC_Error_Count (SATA), логи ядра на ресети лінку, переставте/замініть кабель, змініть порти, оновіть прошивку HBA. Замініть диск, якщо помилки не зникають.

4) «Ми scrub-или і він відремонтував; усе добре»

Симптом: Scrub відремонтував байти; команда знехтувала і пішла далі.

Корінна причина: Подія ремонту — це пожежна сигналізація, а не святкування. Щось віддавало неправильні дані.

Виправлення: Розслідуйте, який пристрій/vdev бачив помилки; зіставте з SMART і логами; після змін запустіть ще один scrub, щоб підтвердити стабільність.

5) Scrub деградованого пулу без думок

Симптом: Продуктивність падає; під час scrub/resilver з’являються додаткові помилки пристроїв.

Корінна причина: Додаткові читання на вже завантажені диски; scrub конкурує з resilver-ом; вікна відновлення посилюють латентні помилки.

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

6) Плутання корупції застосунку з корупцією зберігання

Симптом: Логічні невідповідності в базі; ZFS повідомляє про чисті scrub-и.

Корінна причина: Додаток записав погані дані або стався баг/логіка на рівні застосунку. ZFS вірно зберіг те, що йому дали.

Виправлення: Використовуйте прикладні контрольні суми, резервні копії і незмінні snapshot-и з політикою збереження. ZFS — необхідна, але не достатня умова коректності.

7) Розклад scrub-ів скопійований з блогу, а не з реальності пулу

Симптом: Scrub-и викликають повторні інциденти з клієнтами або їх вимикають.

Корінна причина: Розклад не відповідає кількості пристроїв, розміру пулу і бізнес-навантаженню.

Виправлення: Почніть з щомісячного scrub-а, виміряйте тривалість і вплив. Налаштуйте вікно і запас пропускної здатності. Ставте scrub як обовʼязковий контроль, а не як опціональну задачу.

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

Базовий план для нового пулу ZFS (орієнтований на продакшн)

  1. Виберіть надмірність свідомо: mirror для IOPS і простого відновлення; RAIDZ2/3 для ємності і толерантності до відмов.
  2. Іменуйте пристрої стабільними ID: будуйте пулі з використанням шляхів /dev/disk/by-id.
  3. Встановіть розклад scrub-ів: за замовчуванням щомісяця; підтвердіть, що він може завершитися у вашому вікні.
  4. Вирішіть політику збереження snapshot-ів: зберігайте те, що можете дозволити собі перевіряти. Спалах snapshot-ів реальний.
  5. Моніторинг: алерт на (a) scrub не запускали N днів, (b) scrub відремонтував байти > 0, (c) будь-які нові READ/WRITE/CKSUM помилки, (d) пул DEGRADED/FAULTED, (e) scrub триває занадто довго.
  6. Запустіть тестовий scrub після вводу в експлуатацію: виміряйте пропускну здатність і вплив; зафіксуйте базову тривалість.

Щомісячна операційна рутина (нудно, повторювано, правильно)

  1. Запустіть zpool status і зафіксуйте лічильники.
  2. Запустіть/підтвердіть завершення scrub-а.
  3. Перегляньте результати scrub-а: відремонтовані байти, кількість помилок, тривалість.
  4. Зберіть SMART підсумки для всіх пристроїв; шукайте CRC/link помилки і переназначені/очікувані сектори.
  5. Підтвердьте хоча б один шлях відновлення: невелика відновлювальна репетиція датасету або перевірка контрольних сум відомих артефактів.

Рутина при інциденті, коли бачите помилки контрольних сум

  1. Не писати панічно: уникайте інтенсивних записів, які ускладнять відновлення метаданих.
  2. Зафіксуйте стан: збережіть zpool status -v, витяги з dmesg та SMART звіти.
  3. Визначте масштаб: постійні помилки на рівні файлу vs лише лічильники пристроїв.
  4. Стабілізувати апаратний шлях: кабелі/порти/HBA.
  5. Відновити надмірність: замініть вийшлі/недоступні пристрої.
  6. Запустити scrub ще раз: підтвердити, що помилки перестали збільшуватися і scrub завершився чисто.
  7. Відновити уражені обʼєкти: з резервної копії/snapshot-а; перевірити цілісність.

Цікаві факти та історичний контекст

  • Факт 1: ZFS було спроєктовано в Sun Microsystems з чіткою метою забезпечити цілісність даних від початку до кінця, а не лише керування ємністю.
  • Факт 2: Традиційний RAID перевіряє парність, але зазвичай не валідує, що дані, які повертаються, відповідають тим, які файловій системі був записані спочатку.
  • Факт 3: ZFS зберігає контрольні суми в батьківських метаданих, тому контрольна сума блоку не лежить у тому ж секторі, що й сам блок.
  • Факт 4: Copy-on-write означає, що ZFS ніколи не перезаписує живі дані на місці; він записує нові блоки і потім переключає вказівники, зменшуючи ризики «torn write».
  • Факт 5: Scrub перевіряє виділені блоки, включно з блоками, утримуваними snapshot-ами; збереження snapshot-ів безпосередньо впливає на обсяг роботи scrub-а.
  • Факт 6: «Самовилікування» вимагає надмірності; пул з одним диском може виявляти корупцію, але не може її виправити.
  • Факт 7: Помилки контрольних сум можуть походити від шару транспорту (кабелі/HBA), а не лише від носія — SMART «PASSED» цього не спростовує.
  • Факт 8: Resilver і scrub — різні скани: resilver — цільова реконструкція після подій з пристроями; scrub — повна верифікація вмісту пулу.
  • Факт 9: Диски великої ємності збільшують вікно часу, коли латентні помилки мають значення, бо відновлення/скан читає більше даних і триває довше.

FAQ

1) Як часто я повинен запускати scrub пулу ZFS?

Щомісяця — базове налаштування, що працює в більшості середовищ. Якщо ваш scrub не встигає завершитися щомісяця, виправте запас пропускної здатності/спалах snapshot-ів або змініть архітектуру — не кидайте верифікацію.

2) Чи перевіряє scrub вільний простір?

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

3) У чому різниця між scrub і resilver?

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

4) Якщо у мене є mirror-и, чи мені все ще потрібні scrub-и?

Так. Mirror дає другу копію, але без scrub-ів ви можете не виявити корупцію, поки не прочитаєте блок під час інциденту або під час resilver-а, коли система вже під стресом.

5) Чи ZFS може автоматично виправити корупцію?

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

6) Чому я бачу CKSUM помилки, але немає READ/WRITE помилок?

Тому що пристрій успішно повернув дані, але дані не відповідали збереженій контрольній сумі. Це вказує на тиху корупцію або на проблеми транспорту (кабель/HBA/backplane).

7) Чи небезпечні scrub-и для здоровʼя дисків?

Вони збільшують навантаження на читання, що може виявити маргінальні диски. Це не причина уникати scrub-ів; це причина знаходити слабкі диски під контролем, а не під час відмови.

8) Чи слід scrub-ити SSD-пули інакше, ніж HDD?

Мета цілісності та ж сама. SSD часто scrub-ять швидше через сильні випадкові читання, але вони також можуть мати баги прошивки і проблеми шляху. Тримайте scrubs регулярними і слідкуйте за зносом/SMART.

9) Мій scrub відремонтував байти. Це нормально?

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

10) Чи потрібна ECC RAM для цілісності ZFS?

ECC настійно рекомендується для систем, де важлива коректність даних. ZFS може виявляти корупцію на диску, але він не може надійно виявити корупцію, що виникла в RAM до обчислення контрольної суми.

Висновок: наступні кроки на цей тиждень

Якщо ви використовуєте ZFS і не запускаєте scrub-и — ви покладаєтеся на ідеальність стеку зберігання назавжди. Це мило. Але, будь ласка, не робіть так.

  1. Встановіть розклад scrub-ів (щомісяця як базовий) і переконайтеся, що він завершується.
  2. Додайте алерти для: простроченого scrub-а, scrub-repaired bytes > 0, будь-яких нових READ/WRITE/CKSUM помилок і виконання scrub-а довшим за ваше вікно.
  3. Запустіть scrub зараз у контрольованому вікні, а потім зафіксуйте тривалість і пропускну здатність як базову.
  4. Коли бачите помилки контрольних сум, зіставляйте з SMART CRC/link reset перед тим, як сліпо замінювати апарат.
  5. Тестуйте відновлення хоча б для одного репрезентативного датасету. Scrub-и перевіряють те, що там є; відпрацювання відновлення перевіряє, що ви зможете відновити, якщо цього немає.

Мета не в тому, щоб «довіряти ZFS». Мета — операціоналізувати верифікацію. Scrub-и — це момент, коли ви припиняєте вірити і починаєте знати.

← Попередня
«Мережевий шлях не знайдено» (0x80070035): виправлення за 5 хвилин
Наступна →
Proxmox PBS: резервні копії успішні, а відновлення зазнають невдачі — чеклист, який це виявляє

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