Безшумна корупція даних у ZFS: що ZFS помічає, а RAID часто пропускає

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

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

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

Безшумна корупція: що це і чому RAID може її пропустити

Безшумна корупція (також «bit rot», «latent sector errors», «misdirected writes» або «oops the controller lied»)
— це будь‑який випадок, коли стек зберігання повертає дані, які не відповідають тому, що було записано, не видавши помилки I/O.
Ключове слово — безшумна: ОС отримує успішне читання, ваша програма отримує байти, і ніхто не кидає виключення.

RAID — особливо апаратний RAID або RAID «лише mdadm» — зазвичай фокусується на доступності пристрою. Диск виходить з ладу, парність або
дзеркало тримають том онлайн. Гарно. Але RAID часто має обмежену видимість щодо того, чи блок містить правильні дані такі, які записала програма.
Він може виявляти деякі помилки (наприклад, незчитуваний сектор), але також може спокійно повернути пошкоджені дані, бо не має енд‑ту‑енд перевірки від додатка → файлової системи → диска.

Ось неприємна правда: багато проєктів RAID припускають, що інші шари стеку чесні. У продакшені це ризиковано. Контролери мають баги у прошивці.
HBA мають особливості. Кабелі і бекплейни поводяться дивно у великому масштабі. Диски ремаплять сектори. DMA може збоїти.
Пам’ять іноді перевертaє біти. І, так, іноді люди «виправляють» проблему зі сховищем, переставляючи слоти, перекомпоновуючи кабелі або оновлюючи прошивку — і випадково створюють нову проблему.

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

Що ZFS «бачить», а класичний RAID часто — ні

Енд‑ту‑енд контрольні суми: головна ідея

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

Ця контрольна сума є енд‑ту‑енд: вона охоплює шлях з погляду файлової системи до пристрою. ZFS не покладається на внутрішнє ECC диска або парну логіку контролера як єдиний механізм цілісності.
Він використовує їх як defense‑in‑depth.

Самовідновні читання (коли є надлишковість)

Якщо pool має надлишковість (mirror, RAIDZ, dRAID), ZFS може спробувати альтернативні копії при виявленні корупції. Він читає
з іншої репліки, перевіряє контрольну суму і потім автоматично ремонтує пошкоджену копію. Це не «відбудова після смерті диска». Це — «відновити один пошкоджений блок, поки диск ще живий».

RAID‑парність може відтворити дані, коли диск відсутній. Але якщо диск повертає пошкоджений блок без помилки, RAID часто не знає, який диск неправий, і може не мати жодної вищого рівня контрольної суми, щоб це довести.
Ви отримуєте Шредінгерів блок: він одночасно правильний і неправильний, поки ви не спробуєте його використати.

scrub: проактивне виявлення замість несподіваної відмови

ZFS scrub проходить виділену область пулу, читає блоки, перевіряє контрольні суми і за можливості ремонтує. Так ви ловите latent sector errors до того,
як єдина добра копія буде перезаписана або до того, як вам знадобляться ці дані під час інциденту.

Copy‑on‑write: менше «половинних записів», інша поверхня відмов

ZFS реалізує copy‑on‑write (CoW). Він записує нові блоки в інші місця, а потім атомарно оновлює вказівники метаданих. CoW не запобігає всім видам корупції,
але зменшує класичну проблему RAID: часткові записи, що залишають файлову систему в неконсистентному стані (особливо після втрати живлення).
Традиційні файлові системи покладаються на журналювання і правильний порядок операцій. ZFS покладається на транзакційну семантику на рівні файлової системи.

Контрольні суми метаданих теж, бо втратити карту гірше, ніж втратити територію

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

Кращий облік помилок: ви отримуєте квитанції

Лічильники помилок ZFS розрізняють read errors, write errors і checksum errors. Остання категорія — найцікавіша:
диск не видав помилку, але дані не співпали з очікуванням. Багато налаштувань RAID ніколи не показують цієї нюансованості. ZFS
повідомить вам, коли стек зберігання «бреше».

Один перефразований вислів від W. Edwards Deming теж підходить для операцій зі сховищами: без вимірювань ви керуєте навмання (парафраз, Deming).
ZFS вимірює цілісність постійно.

Сильні сторони RAID і прогалини, які помилково сприймають за безпеку

RAID про доступність, а не про правильність

Основне завдання RAID — тримати блочний пристрій онлайн, коли диск виходить з ладу. Він у цьому хороший. Також він добре ховає від ОС відмови дисків,
що може бути зручно і водночас небезпечно: зручно, бо сервери продовжують працювати; небезпечно, бо перший раз ви помітите проблему,
коли RAID‑картка вже балансує кілька деградованих станів.

«Але RAID‑контролер має батарею та patrol read»

Кеш із батарейним (або flash‑backed) записом чудово підвищує продуктивність і знижує деякі ризики при втраті живлення. Patrol read може виявляти незчитувані сектори.
Жодне з цього не гарантує енд‑ту‑енд коректність.

  • Patrol read — інструмент здоров’я поверхні диска. Він не перевіряє, що байти, які читаються, відповідають тим, що додаток записав місяці тому.
  • Деякі стек‑контролери використовують контрольні суми внутрішньо, але вони зазвичай не експонуються файловій системі і не захищають від misdirected writes або корупції на боці хоста.

Дірка у записі та кошмари парності

Записи парності в RAID5/6 можуть постраждати від «write hole», якщо втрачається живлення посеред оновлення стрічки. Сучасні контролери пом’якшують це за допомогою кешу + журналювання,
але реалізації відрізняються. Програмний RAID має власні стратегії пом’якшення, також змінні. ZFS оминує класичну write hole за дизайном, бо ніколи не перезаписує на місці; він комітить нові консистентні дерева.

Коли RAID відбудовує, він навантажує ваш найслабший ланцюг

Rebuild/resilver читає величезні обсяги даних. Саме тоді виявляються latent read errors. Rebuild у RAID6 може все ще провалитися, якщо занадто багато незчитуваних секторів одночасно.
Resilver ZFS може бути швидшим у деяких сценаріях, бо він відновлює лише виділені блоки, а не кожен сектор диска.

Жарт №1: RAID — як запасне колесо: радієш, що воно є, аж поки не виявиш, що воно пусте вже кілька місяців.

Факти та історичний контекст, які варто знати

  1. ZFS з’явився в Sun Microsystems на початку‑середині 2000‑х і був спроєктований, щоб об’єднати управління томами і файлову систему в єдиний узгоджений стек.
  2. Енд‑ту‑енд контрольні суми були базовою ідеєю від самого початку: ZFS розглядав безшумну корупцію як першорядну проблему, а не як крайній випадок.
  3. Copy‑on‑write снапшоти не були «приємним доповненням» — вони структурно пов’язані з транзакційною консистентністю і безпечними он‑дисковими оновленнями.
  4. RAID передував сучасним багатотерабайтним дискам на десятиліття; багато припущень RAID формувалися, коли вікна відновлення були коротші, а ризик URE — менший.
  5. Апаратні RAID‑контролери стали популярні частково, щоб знизити навантаження на CPU і стандартизувати управління дисками, у часи, коли парне обчислення та кешування були критичними.
  6. scrub у ZFS формалізував те, що багато адміністраторів робили вручну: періодичні повні читання, щоб виявити латентні помилки до того, як вони стануть втратою даних.
  7. Ентерпрайзні диски рекламують URE‑рівні (unrecoverable read errors), що нагадує: «диск, який ще не зламався», все ще може вийти під час rebuild.
  8. OpenZFS став мультиплатформеним нащадком, з активною розробкою в illumos, FreeBSD, Linux та інших — це важливо, бо баги в зберіганні не цікавляться межами ОС.
  9. «Bit rot» — не єдиний феномен; це узагальнена категорія для дефектів носія, багів прошивки, misdirected writes і збоїв RAM/cable/controller.

Режими відмов: як корупція трапляється в реальних парках

Misdirected writes: найстрашніша корупція, яка не попереджає

Misdirected write — це коли система записує правильні дані в неправильне місце. Ваш додаток записує блок A, але диск/контролер записує його в блок B.
Обидва записи «успішні». RAID охоче дзеркалить або захищає парністю неправильне місце. Пізніше читання повертають дані, які проходять ECC диска, і RAID думає, що все в порядку.

ZFS ловить це, бо контрольна сума, збережена в метаданих для блоку A, не співпадатиме з тим, що наразі лежить у блоці A. За наявності надлишковості ZFS може прочитати іншу копію і відремонтувати.

DMA / корупція пам’яті: файловій системі не виправити те, що вона не бачить

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

Ось чому ECC‑пам’ять важлива в системах ZFS. ZFS — це система цілісності; йому потрібна надійна пам’ять.

Часткові записи та порядок: живлення не ввічливе

Раптова втрата живлення може створити torn writes: наполовину старі, наполовину нові дані. Деякі диски брешуть про завершення flush. Деякі контролери змінюють порядок.
Файлові системи намагаються впоратися журналюванням, бар’єрами та акуратними flush.

Транзакційна модель CoW у ZFS зменшує вплив, але вам все ще потрібен здоровий порядок записів і чесні semantics flush. Якщо ваш диск підтверджує записи, які не були фізично записані, ви все ще можете втратити останні секунди даних.
Різниця: менше шансів отримати пошкоджену структуру файлової системи; більше шансів втратити недавні транзакції.

Пошкоджені сектори: класичний, нудний лиходій

Latent sector errors з’являються в найгірший момент: під час rebuild, scrub або відновлення. RAID може відтворити, якщо він може ідентифікувати погане читання і все ще має достатню надлишковість.
ZFS може робити те саме, але ще й перевіряє правильність за допомогою контрольних сум і може ремонтувати, поки диск залишається онлайн.

Жарт №2: Вендори сховищ обіцяють «п’ять дев’яток», але вони ніколи не кажуть, чи ті дев’ятки стосуються аптайму чи вашого сну.

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

Коли ви підозрюєте корупцію або бачите помилки ZFS, швидкість важлива. Не тому, що ZFS крихкий — а тому, що чим довше ви працюєте в деградованому стані, тим більше шансів накопичити додаткові відмови.
Ось швидкий практичний порядок дій, який працює в реальному on‑call житті.

1) Підтвердьте, чи це проблема цілісності (checksum) чи I/O (читання/запис)

  • Перевірте zpool status -v спочатку. Якщо бачите інкременти CKSUM, це «пристрій повернув дані, але вони були неправильні».
  • Якщо бачите READ або WRITE помилки, це більш класична відмова пристрою або транспорту.

2) Визначте, чи може надлишковість вилікувати проблему

  • Mirrors і RAIDZ можуть автоматично виправити багато checksum помилок.
  • Single‑disk pools не можуть. Вони виявляють корупцію, але не ремонтують її.

3) Локалізуйте проблему: один диск, один шлях або системна

  • Якщо помилки групуються на одному члені vdev, підозрівайте той диск, його кабель, ту корзину або порт HBA.
  • Якщо кілька дисків на тому самому HBA мають проблеми, підозрівайте контролер, бекплейн, expander або прошивку.
  • Якщо checksum помилки з’являються на багатьох пристроях без закономірності, підозрівайте пам’ять, нестабільність CPU або баг драйвера.

4) Рішення: scrub, відключити/замінити або зупинити записи

  • Запустіть scrub, якщо є надлишковість і пул стабільний; він виявить і виправить більше проблем.
  • Відключіть/замініть пристрій, який постійно накопичує помилки.
  • Зупиніть запис (або заморозьте навантаження), якщо бачите активну корупцію без чіткої стратегії ізоляції.

5) Підтверджуйте бекапи відновленням, а не вірою

Якщо підозрюється корупція, зробіть реальний тест відновлення представницьких даних. ZFS захищає те, що зберігає, а не те, як зберігає ваше рішення для бекапів.

Практичні завдання: команди, вихід і що робити далі

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

Завдання 1: Визначити корупцію проти I/O відмови

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 00:12:41 with 3 errors on Wed Dec 25 03:10:12 2025
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          raidz1-0  ONLINE       0     0     0
            sda     ONLINE       0     0     3
            sdb     ONLINE       0     0     0
            sdc     ONLINE       0     0     0

errors: Permanent errors have been detected in the following files:
        tank/vmstore@auto-2025-12-24:/vm/guest1/disk0.img

Значення: CKSUM помилки на sda вказують на те, що пристрій повернув неправильні дані без помилки I/O. ZFS знайшов щонайменше одну permanent error у конкретному файлі.

Рішення: Якщо є надлишковість, замініть sda і відновіть або пересоздайте постраждалий файл. Якщо файл — диск VM, ставтесь до нього як до критичного: відновіть із відомої доброї snapshot/резервної копії.

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

cr0x@server:~$ sudo zpool scrub tank

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

Рішення: Плануйте scrubs регулярно; запускайте після заміни апаратури або підозрілої події (втрата живлення, перестановка кабелів, скидання контролера).

Завдання 3: Перевірити прогрес scrub і чи він лікує чи просто читає

cr0x@server:~$ zpool status tank
  pool: tank
 state: ONLINE
  scan: scrub in progress since Thu Dec 26 01:20:41 2025
        412G scanned at 1.31G/s, 88G issued at 288M/s, 6.02T total
        0B repaired, 1.43% done, 06:12: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

Значення: «0B repaired» — добре; якщо «repaired» зростає, ZFS активно лікує.

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

Завдання 4: Переглянути лічильники помилок з часом

cr0x@server:~$ zpool status -p tank
  pool: tank
 state: ONLINE
config:

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

Значення: CKSUM помилки — це кумулятивні лічильники. Вони не скидаються автоматично.

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

Завдання 5: Очистити помилки після того, як щось виправили (не раніше)

cr0x@server:~$ sudo zpool clear tank sda

Значення: Очищає лічильники помилок для sda, щоб нові помилки були видимі.

Рішення: Робіть це лише після того, як ви пересілили/замінили апарат; інакше ви видаляєте докази під час розслідування.

Завдання 6: Перелічити datasets і mountpoints (щоб знайти, які дані можуть бути під загрозою)

cr0x@server:~$ zfs list -o name,used,avail,refer,mountpoint -r tank
NAME             USED  AVAIL  REFER  MOUNTPOINT
tank             4.12T  2.55T   128K  /tank
tank/vmstore     3.40T  2.55T  3.40T  /tank/vmstore
tank/backups      612G  2.55T   612G  /tank/backups

Значення: Ви можете швидко зіставити проблеми зі здоров’ям пулу з наборами даних, що мають бізнес‑вплив.

Рішення: Якщо permanent errors посилаються на шлях, ідентифікуйте dataset і вирішіть, відновлювати, реґенерувати з реплікації чи перебудувати згенеровані дані.

Завдання 7: Знайти snapshots (корисно для відкату пошкоджених даних)

cr0x@server:~$ zfs list -t snapshot -o name,creation -r tank/vmstore | tail
tank/vmstore@auto-2025-12-24-0100  Wed Dec 24 01:00 2025
tank/vmstore@auto-2025-12-25-0100  Thu Dec 25 01:00 2025
tank/vmstore@auto-2025-12-26-0100  Fri Dec 26 01:00 2025

Значення: Якщо корупція сталася нещодавно, snapshot з до‑події може бути чистим.

Рішення: Розгляньте клонування і валідацію перед відкатом. Не робіть сліпого rollback зайнятого dataset без координації з власниками додатків.

Завдання 8: Перевірити властивості пулу, що впливають на поведінку цілісності

cr0x@server:~$ zfs get -o name,property,value -s local,default checksum,compression,recordsize tank/vmstore
NAME          PROPERTY     VALUE
tank/vmstore  checksum     on
tank/vmstore  compression  lz4
tank/vmstore  recordsize   128K

Значення: Checksumming увімкнено за замовчуванням; вимикати його — саботаж самим собі.

Рішення: Залишайте checksum=on. Якщо ви успадкували дивні властивості від шаблонів, виправте їх перед продакшеном.

Завдання 9: Шукати пристрої за persistent IDs (уникати «sda рулетки»)

cr0x@server:~$ ls -l /dev/disk/by-id/ | egrep 'ata-|scsi-' | head
lrwxrwxrwx 1 root root  9 Dec 26 00:10 ata-ST8000NM000A_ZR123ABC -> ../../sda
lrwxrwxrwx 1 root root  9 Dec 26 00:10 ata-ST8000NM000A_ZR123DEF -> ../../sdb
lrwxrwxrwx 1 root root  9 Dec 26 00:10 ata-ST8000NM000A_ZR123GHI -> ../../sdc

Значення: Імена пристроїв як /dev/sda можуть змінюватися між завантаженнями; by‑id стабільні.

Рішення: Використовуйте шляхи by‑id при створенні пулів і при заміні пристроїв, щоб уникнути помилкової заміни диска (реальна і популярна помилка).

Завдання 10: Перевірити SMART‑здоров’я для ранніх попереджень

cr0x@server:~$ sudo smartctl -a /dev/sda | egrep 'SMART overall-health|Reallocated_Sector_Ct|Current_Pending_Sector|UDMA_CRC_Error_Count'
SMART overall-health self-assessment test result: PASSED
  5 Reallocated_Sector_Ct   0x0033   098   098   010    Pre-fail  Always       12
197 Current_Pending_Sector  0x0012   100   100   000    Old_age   Always       1
199 UDMA_CRC_Error_Count    0x003e   200   200   000    Old_age   Always       37

Значення: Pending sectors і CRC помилки вказують на проблеми носія і/або кабелю. «PASSED» не означає «здоровий», це означає «ще не мертвий».

Рішення: Замініть диск, якщо pending sectors зберігаються або reallocated сектори ростуть. Якщо CRC помилки зростають, замініть кабель/slot бекплейна і подивіться, чи помилки зупиняться.

Завдання 11: Підтвердити, що пул не побудовано випадково на RAID‑контролері LUN

cr0x@server:~$ lsblk -o NAME,SIZE,TYPE,MODEL
NAME        SIZE TYPE MODEL
sda       7.3T  disk ST8000NM000A
sdb       7.3T  disk ST8000NM000A
sdc       7.3T  disk ST8000NM000A
nvme0n1   1.8T  disk Samsung SSD 990

Значення: Якщо ви бачите один великий «disk», що насправді є RAID LUN від контролера, ZFS не бачить окремих дисків і не зможе робити коректне self‑healing по пристрою.

Рішення: Віддавайте перевагу HBA/JBOD режиму для ZFS. Якщо ви вже розгорнуті на RAID LUN, плануйте міграцію; не чекайте, поки контролер стане вашим єдиним джерелом жалю.

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

cr0x@server:~$ sudo zpool replace tank /dev/disk/by-id/ata-ST8000NM000A_ZR123ABC /dev/disk/by-id/ata-ST8000NM000A_ZR999XYZ

Значення: ZFS починає resilvering на новий диск.

Рішення: Моніторьте resilver. Не витягайте старий диск, поки не побачите новий online і прогрес resilver.

Завдання 13: Моніторити resilver і правильно інтерпретувати «resilvered X»

cr0x@server:~$ zpool status tank
  pool: tank
 state: ONLINE
  scan: resilver in progress since Fri Dec 26 02:11:05 2025
        842G scanned at 780M/s, 216G issued at 200M/s, 2.90T total
        216G resilvered, 7.43% done, 05:41:32 to go
config:

        NAME                                                   STATE     READ WRITE CKSUM
        tank                                                   ONLINE       0     0     0
          mirror-0                                             ONLINE       0     0     0
            replacing-0                                        ONLINE       0     0     0
              /dev/disk/by-id/ata-ST8000NM000A_ZR123ABC        ONLINE       0     0    24
              /dev/disk/by-id/ata-ST8000NM000A_ZR999XYZ        ONLINE       0     0     0
            sdb                                                ONLINE       0     0     0

Значення: Resilver «issued» показує, що записується; «scanned» включає те, що перевіряється. Старий диск все ще має історію контрольних сум; це нормально.

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

Завдання 14: Після resilver перевірити відсутність нових помилок і запустити scrub

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: ONLINE
  scan: resilvered 2.90T in 05:55:12 with 0 errors on Fri Dec 26 08:06:17 2025
config:

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

Значення: Resilver завершився чисто.

Рішення: Запустіть scrub незабаром після інциденту, особливо якщо він був пов’язаний з нестабільністю кабелів/контролера. Потрібна впевненість, а не відчуття.

Завдання 15: Перевірити історію подій ZFS для хронології

cr0x@server:~$ sudo zpool events -v | tail -n 20
TIME                           CLASS
Dec 26 2025 01:18:43.221001000  ereport.fs.zfs.checksum
Dec 26 2025 02:11:05.102334000  sysevent.fs.zfs.resilver_start
Dec 26 2025 08:06:17.552190000  sysevent.fs.zfs.resilver_finish

Значення: Події показують, коли почалися checksum проблеми і які ремедіації відбулися.

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

Завдання 16: Підтвердити ashift і уникнути випадкових 512e пасток продуктивності/латентності

cr0x@server:~$ zdb -C tank | egrep 'ashift|path' | head -n 10
        path: /dev/disk/by-id/ata-ST8000NM000A_ZR123DEF
        ashift: 12
        path: /dev/disk/by-id/ata-ST8000NM000A_ZR123GHI
        ashift: 12

Значення: ashift=12 вказує на 4K сектори. Неправильний ashift може спричинити write amplification і таймаути, що виглядають як нестабільні диски.

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

Три корпоративні міні‑історії з виробництва

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

Середня SaaS‑компанія тримала кластер бази даних на «ентерпрайзному» сховищі: двоконтролерний SAN, RAID6, звичні заспокійливі абревіатури.
Команда вважала: RAID6 означає, що корупція даних фактично не проблема. Вони зосередилися на відмовах дисків і запасних накопичувачах, а не на цілісності даних.

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

Поворотною точкою став тест відновлення (не під час простою — просто запланований вогневий дрил). Відновлена база пройшла контрольні суми на рівні БД для більшості таблиць, але кілька індексів були тонко пошкоджені.
Резервні копії захопили корупцію, бо вона вже була присутня і безшумна.

Вони перенесли навантаження на ZFS mirror на звичайних серверах з ECC‑пам’яттю, робили щотижневі scrubs і ввели часті snapshots. Страшне було не в тому, що RAID «провалився» — він зробив те, що обіцяв.
Неправильне припущення було в тому, що RAID обіцяв правильність. RAID обіцяв «том залишається онлайн, коли диск помирає». Інший контракт.

Міні‑історія 2: Оптимізація, яка відплатилась

Інша організація мала віртуалізаційний кластер на ZFS на Linux. Продуктивність була нормальною, але хтось захотів «кращих» чисел:
нижча латентність, більше IOPS. Додали L2ARC і агресивно налаштували recordsize та кешування. Потім ризикнули: вимкнули sync writes на рівні dataset для VM‑зберігання, бо «UPS надійний».

Через місяці оновлення прошивки контролера спричинило непередбачуваний цикл перезавантаження на одному хості. UPS дійсно був надійним.
Хост — ні. Після всього кілька VM не змогли завантажитися. Сам ZFS був консистентним — CoW зробив свою роботу — але файлові системи гостьових ОС втратили транзакції, які вони вважали довговічними.

Оптимізація не була в L2ARC. Вона була у рішенні брехати щодо durable‑поведінки. Вимкнення sync — як зняти ремінь безпеки, бо він мнеться. Класно виглядає до першого різкого гальмування.

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

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

Департамент фінансових послуг тримав OpenZFS для зберігання документів. Нічого гламурного. Команда мала три нудні звички:
щомісячні scrubs, щоквартальні тести відновлення і правило: будь‑яка checksum помилка — фізична інспекція всього шляху: диск, корзина, бекплейн, порт HBA, кабель.

Одного місяця scrub повідомив кілька checksum ремонтів на одному члені mirror. Ніяких відмов, ніяких скарг користувачів. Інженер on‑call створив тікет і дотримався правила: подивився SMART, перевірив CRC помилки, оглянув SAS‑кабель. SMART показав зростання CRC, але диск виглядав інакше добре.

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

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

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

1) Симптом: CKSUM помилки зростають, але SMART виглядає «PASSED»

Корінна причина: Загальний статус SMART надто грубий; checksum помилки часто вказують на транспорт, прошивку або misdirected writes, а не тільки на помираючий носій.

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

2) Симптом: Permanent errors у файлах після scrub

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

Виправлення: Відновіть постраждалі файли з бекапу або чистого snapshot/репліки. Потім розберіться, чому надлишковість не врятувала (single‑disk vdev, деградований пул під час події, множинні відмови).

3) Симптом: Scrub триває вічно і сильно впливає на продуктивність

Корінна причина: Недостатній I/O, шторм повторних спроб від невдалих дисків або дизайн пулу, що вимагає широкого читання. Іноді просто «ви створили зайнятий пул і запланували scrub у піковий час».

Виправлення: Запускайте scrubs у непіковий час, перевірте повільні пристрої, обмежте пріоритет scrub/resilver де можливо, і розгляньте більше vdev/mirror для паралелізму.

4) Симптом: RAID‑контролер показує «healthy», але ZFS всередині VM повідомляє корупцію

Корінна причина: ZFS не бачить фізичних дисків; він бачить віртуальний диск або RAID LUN. Корупція може вводитись нижчим шаром під гостем.

Виправлення: Віддавайте перевагу passthrough HBA/disks до ZFS (JBOD/HBA mode) або запускайте ZFS на хості. Якщо потрібно віртуалізувати, переконайтеся, що нижній шар надає гарантії цілісності і стабільні flush semantics.

5) Симптом: Після подій живлення додатки скаржаться на втрачені записи, але ZFS pool — «ONLINE»

Корінна причина: Sync writes були вимкнені, або диски/контролери солгали про flush, або навантаження очікувало гарантії довговічності, якої не було.

Виправлення: Увімкніть sync semantics, використайте правильний SLOG якщо потрібно, і перевірте політики кешу запису. Розглядайте «підтверджено, але не збережено» як втрачені дані за дизайном.

6) Симптом: Повторювані помилки на кількох дисках на тому самому хості

Корінна причина: Відмова спільного шляху: HBA, expander, бекплейн, прошивка, живлення або нестабільність пам’яті.

Виправлення: Перемістіть один диск на інший контролерний шлях і спостерігайте. Оновіть прошивку. Перевірте dmesg на link resets. Перевірте здоров’я ECC і запустіть діагностику пам’яті.

7) Симптом: Після заміни диска checksum помилки не зупиняються

Корінна причина: Ви замінили «жертву», а не «винуватця». Часто проблема в кабелі, корзині або контролері, або в моделі/прошивці диска з відомою проблемою.

Виправлення: Поміняйте кабель, змініть корзину, оновіть прошивку, і при потребі замініть HBA. Трекуйте помилки за фізичним слотом і by‑id, а не за іменами як sda.

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

Чекліст введення в експлуатацію (перед продакшен‑трафіком)

  1. Використовуйте ECC‑пам’ять. Якщо не можете — хоча б явно визнайте ризик у дизайні.
  2. Використовуйте HBA в IT/JBOD режимі, а не апаратні RAID‑томи, щоб ZFS бачив і керував дисками напряму.
  3. Будуйте пули з persistent device paths (/dev/disk/by-id).
  4. Оберіть надлишковість відповідну до blast radius: дзеркала для IOPS і швидкого resilver; RAIDZ для ємності з обережними очікуваннями rebuild.
  5. Встановіть і задокументуйте графік scrub (звично: щомісяця для великих пулів, частіше для критичних даних).
  6. Увімкніть snapshots і реплікацію; визначте ретеншн на основі RTO/RPO, а не на бажанні.
  7. Протестуйте відновлення представницьких наборів даних перед go‑live.

Чекліст оперативної гігієни (щотижня/щомісяця)

  1. Переглядайте zpool status по всьому парку; налаштуйте алерти на ненульові READ/WRITE/CKSUM дельти.
  2. Перевіряйте атрибути SMART за трендами, а не лише за прапорцями відмов.
  3. Запускайте заплановані scrubs; перевіряйте їх завершення і чи щось ремонтували.
  4. Відстежуйте час resilver; збільшення часу — раннє попередження старіння дисків або перевантаження дизайну.
  5. Проводьте тест відновлення щоквартально. Вибирайте випадкові зразки і реально перевіряйте цілісність на рівні додатка.

План реагування на інцидент (виявлено checksum помилки)

  1. Зупиніть ризиковані зміни. Забороніть «допоміжні» перезавантаження і оновлення прошивки під час інциденту.
  2. Запустіть zpool status -v і збережіть вивід у квитку.
  3. Якщо є надлишковість — стартуйте scrub і моніторьте ремонти і нові помилки.
  4. Перевірте SMART і dmesg на link resets і CRC помилки; міняйте кабелі/корзини за показаннями.
  5. Замініть пристрої, які продовжують накопичувати помилки. Використовуйте zpool replace з by‑id шляхами.
  6. Після ремедіації очистіть лічильники, знову запустіть scrub і підтвердіть стабільність щонайменше за один повний цикл scrub.
  7. Відновіть уражені файли/VM з snapshot або бекапу; перевірте їх на рівні додатка.
  8. Занотуйте, що було замінено (серійний номер диска, корзина, кабель), щоб наступний інженер не повторив ту саму помилку.

FAQ

Чи запобігає ZFS усій корупції?

Ні. ZFS виявляє on‑disk корупцію і корупцію в I/O шляху після обчислення контрольної суми. Якщо дані були пошкоджені в RAM до того, як контрольна сума обчислена, ZFS чесно збереже пошкоджені дані з відповідною контрольної сумою. Використовуйте ECC‑пам’ять і стабільне обладнання.

Якщо я вже маю RAID, чи потрібен мені ZFS?

Якщо вашим пріоритетом є правильність даних, потрібен шар енд‑ту‑енд цілісності десь. ZFS дає це на рівні файлової системи + тома. RAID дає надлишковість пристроїв.
Комбінувати їх зазвичай надмірно і ускладнює (complexity), якщо тільки ви не використовуєте RAID як просту JBOD абстракцію — в такому випадку краще HBA режим.

Чому ZFS повідомляє checksum помилки, коли диск каже, що все в порядку?

Тому що диск може повернути неправильні дані без повідомлення про помилку (баги прошивки, misdirected reads, пошкодження транспорту). ZFS перевіряє вміст, а не впевненість пристрою.

У чому різниця між READ помилками і CKSUM помилками у zpool status?

READ помилки означають, що пристрій не зміг повернути дані (I/O відмова). CKSUM помилки означають, що пристрій повернув дані, але вони не співпали з очікуваною контрольної сумою. CKSUM часто більш тривожна, бо вказує на безшумну корупцію.

Як часто треба запускати scrub?

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

Чи scrub виправить корупцію?

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

Чи дзеркала безпечніші за RAIDZ?

Дзеркала зазвичай швидше resilver і простіші в експлуатації; вони також дають кращі випадкові read IOPS. RAIDZ більш ємнісно ефективний, але може мати довші вікна rebuild і ширші домени помилок. «Безпечніше» залежить від навантаження, розміру дисків і дисципліни операцій. Якщо ви не робите scrubs регулярно, жоден з варіантів не буде безпечним.

Чи можу я запускати ZFS поверх апаратного RAID‑тома?

Можна, але ви при цьому засліплюєте ZFS щодо поведінки фізичних дисків і втрачаєте можливість локалізувати помилки і self‑heal на коректному рівні. Якщо вам важлива цілісність, дайте ZFS прямий доступ до дисків.

Що робити, коли ZFS повідомляє «Permanent errors»?

Розглядайте це як втрату даних для вказаних файлів(ів). Відновіть з бекапу або чистого snapshot/репліки, потім виправте апаратний/шляховий дефект і запустіть scrub знову. Не припускайте, що «він сам собою вилікувався», якщо повідомляється permanent.

Чи впливає compression або recordsize на виявлення корупції?

Checksumming працює і за стисненням. Compression змінює фізичні блоки, які записуються, але вони все одно контролюються контрольними сумами. Recordsize впливає на I/O патерни і поведінку rebuild, що може змінювати, як швидко ви помічаєте проблеми і наскільки болючими є scrub/resilver.

Практичні наступні кроки

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

  1. Увімкніть (і дійсно моніторьте) scrubs ZFS. Заплануйте їх у календар і налаштуйте алерти на ремонти та помилки.
  2. Проєктуйте надлишковість так, щоб вона могла лікувати: дзеркала або RAIDZ/dRAID з реалістичними вікнами rebuild.
  3. Використовуйте ECC‑пам’ять і HBA в JBOD/IT режимі, щоб ZFS бачив реальні диски.
  4. Коли з’являються checksum помилки — не сперечайтеся з ними. Локалізуйте шлях, замініть винних, знову scrub і відновіть постраждалі дані.
  5. Доведіть бекапи через відновлення. Корупція, яка вже була в джерелі, охоче перейде в «успішні» бекапи.

Операційний виграш простий: ZFS перетворює безшумну корупцію на голосну. Голосні проблеми виправляють. Безшумні — стають бойовими інцидентами.

← Попередня
GPU для робочих станцій проти ігрових: за що ви насправді платите
Наступна →
Невеликі випадкові записи в ZFS: чому дзеркала часто випереджають парність

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