Рано чи пізно кожна команда зберігання даних стикається з одним і тим самим винуватцем: «тимчасовим» vdev. Він з’явився під час кризи, вирішив проблему з ємністю, а тепер живе у пулі як поганий сусід, що не платить оренду. Ви хочете його видалити. ZFS, відома своєю обережністю, відповідає: можливо.
Видалення vdev — реальна й корисна можливість, але й досі повна гострих країв. У продакшені різниця між «працює» і «знищив мені вихідні» — це планування з урахуванням правил ZFS, а не ваших надій.
Ментальна модель: що насправді означає «видалення»
Пули ZFS будуються з vdev (віртуальних пристроїв). Vdev — це атомарна одиниця надлишковості й алокації. ZFS розподіляє дані по vdev, а не по окремих дисках. Ця думка має змінити ваше бачення видалення.
Коли ви виконуєте zpool remove, ви не «вимикаєте диск». Ви ініціюєте евакуацію: ZFS переписує кожен виділений блок, який знаходиться на цільовому vdev, на інші vdev у пулі. Лише після успішної евакуації vdev може бути від’єднаний від конфігурації пулу. Під час евакуації vdev має бути читабельним; решта пулу повинна мати достатньо вільного місця, щоб прийняти ці дані.
Це також означає, що видалення не миттєве. Це робота з переміщення даних по всьому пулу з реальними побічними ефектами: більше I/O, сильніший тиск на фрагментацію, піки затримки й багато «чому мій пул завантажений о 2:00 ранку?» повідомлень.
Ще одна суттєва деталь: видалення vdev — це не загальна можливість «звузити пул». Це дуже специфічна можливість з обмеженнями, і ZFS відмовиться робити це в багатьох конфігураціях. Якщо ви візьмете з собою лише одне правило: проектуйте пул так, ніби ви захочете змінювати його пізніше, бо ZFS не врятує вас від архітектурних помилок автоматично.
Терміни, які потрібні в операційній мові
- Top-level vdev: Vdev безпосередньо під пулом (наприклад, mirror vdev, raidz vdev або single-disk vdev). Більшість обговорень видалення стосуються top-level vdev.
- Leaf device: Диск або розділ всередині vdev. У mirror можна замінювати/від’єднувати leaf; це не «видалення vdev», а «заміна/від’єднання пристрою».
- Special vdev: Пристрій класу алокації для метаданих (і за бажанням — малих блоків). Потужний, але легко перетворити на одиничну точку відмови, якщо перестаратися.
- SLOG (log vdev): Окремий intent log для синхронних записів. Видаляється, але наслідки залежать від навантаження та налаштувань sync.
- L2ARC (cache vdev): Кеш читання. Завжди знімний; це підказка продуктивності, а не первинне сховище.
- Евакуація: Операція переміщення даних ZFS з видаленого vdev. Це основна робота.
Що можна видалити (а що ні)
Зазвичай можна видалити: кеш-пристрої (L2ARC)
L2ARC пристрої можна додавати й видаляти без впливу на коректність даних. Найгірший випадок — погіршення продуктивності, поки кеш не прогріється знову. Якщо пул здоровий, видалення L2ARC зазвичай проходить буденно.
Зазвичай можна видалити: лог-пристрої (SLOG)
Видалення лог-пристрою дозволене. ZFS повернеться до використання основного пулу для ZIL. Пул залишиться консистентним. Ризик — це затримка та пропускна здатність для синхронних записів, а не втрата даних. Якщо ви видалите SLOG під високим sync-навантаженням, ваші додатки повідомлять про це негайно, зазвичай таймаутами.
Можна видалити: top-level vdev у деяких конфігураціях (головне)
Видалення top-level vdev — це можливість, про яку говорять, коли кажуть «звузити пул». Вона існує, але залежить від реалізації та підтримки версії. Практично:
- Видалення цілого top-level mirror vdev зазвичай підтримується (якщо фіча доступна у вашій платформі та пулі).
- Видалення top-level single-disk vdev часто підтримується (знову ж таки: залежить від платформи/фічі).
- Видалення top-level raidz vdev зазвичай не підтримується в багатьох розгортаннях; навіть коли деякі платформи еволюціонують, слід вважати це «не підтримується», поки ви явно не перевірили на своїй реалізації та з відповідними флагами.
Можна видаляти: пристрої з mirror vdev (але це не «видалення vdev»)
Якщо у вас mirror vdev з двома дисками, ви можете від’єднати один диск і продовжувати працювати на залишеному диску (тепер це single-disk vdev). Це операція на leaf. Вона знижує надлишковість. Вона не евакуює блоки на інші vdev. Часто саме це люди мають на увазі під «видалити диск».
Special vdev: теоретично знімні, але небезпечно на практиці
Special vdev — місце, де продакшен зустрічає самонавію. Якщо special vdev містить метадані (а він містить), втрата його може зробити пул непридатним. Видалення special vdev може підтримуватися у вашому стеку, але вам слід розглядати це як проєкт міграції, а не як випадкову команду. Якщо ваш special vdev у дзеркалі й здоровий, ви можете планувати його видалення; якщо він деградований — ви в зоні екстреної операції.
Жарт #1: Special vdev — це як «тимчасовий» кластер Kubernetes: усі клянуться, що він лише для тестів, поки в п’ятницю вночі не стане критично важливим.
Жорсткі обмеження, які потрібно поважати
1) Ви не можете видалити те, що ZFS не може евакуювати
Евакуація вимагає вільного місця на решті vdev. Не «трохи» вільного — достатньо для перепису виділених блоків плюс оверхед, і щоб аллокатор пулу міг працювати. Якщо ваш пул заповнений на 85–90%, видалення — погана ідея. При 95% це самошкідництво.
2) Видалення залежить від фіч і реалізації
Не існує одного ZFS. Є OpenZFS, а також інтеграції ОС та дистрибуції вендорів з різними версіями, фічами та патчами. Сам пул також має feature flags: якщо в пулі немає потрібної фічі, нічого не вийде видалити.
3) Ви не можете «частково видалити» top-level raidz, щоб зменшити його
Люди питають: «Чи можу я прибрати один диск з raidz vdev і залишити raidz?» Ні. Ви можете замінювати диски на більші й розширювати (з відповідною підтримкою фіч), але зменшити ширину raidz шляхом видалення leaf — це не про дизайн ZFS. Якщо ви хочете гнучкого звуження, будуйте з mirror і жертвуйте місцем.
4) Не можна видалити останній top-level vdev
Пул потребує принаймні одного top-level vdev. Якщо ви хочете «видалити все», це не звуження — це міграція.
5) Видалення навантажує пул і конкурує з продакшен-навантаженням
Евакуація — це робота з перепису. Вона вдарить по дисках, ARC, метаданих і може погіршити фрагментацію. Якщо робити це під час піку, очікуйте зростання затримок і «загадкових» уповільнень додатків. Якщо потрібно робити онлайн — обмежуйте швидкість і ретельно моніторте.
6) Видалення відрізняється від resilvering і керування має різні налаштування
Resilvering — це реконструкція на замінний пристрій. Евакуація — це перерозподіл по пулу. Ви спостерігатимете інші симптоми: не тільки «швидкість скану», але й поведінку аллокатора, конфлікти metaslab і загальне чергування I/O.
7) Ви можете видалити vdev і все одно не отримати очікуваного вільного місця
Облік ZFS може дивувати. Снапшоти, reservations, refreservation, налаштування спеціальних малих блоків і копії впливають на те, чому «вільного місця не стало більше». Після видалення загальний розмір пулу зменшується — іноді різко — тому будь-який запас місця, на який ви розраховували, може зникнути. Плануйте ємність після видалення, а не тільки «чи можу я видалити».
Цитата, яку варто пам’ятати
John Allspaw (парафраз): «Надійність визначається тим, як системи поводяться під навантаженням, а не тим, як вони поводяться, коли все гаразд.»
Цікаві факти та коротка історія (бо ця фіча не впала з неба)
- ZFS був побудований навколо ідеї «vdev — назавжди». Ранні дизайни ZFS передбачали, що пули лише зростатимуть, а не звужуватимуться.
- Видалення top-level vdev з’явилося пізніше порівняно з базовими mirror/raidz; це визнання того, що реальні оператори роблять брудні речі під час інцидентів.
- «Класи алокації» (special vdev) змінили операційні ризики: перенесення метаданих на швидкі пристрої може бути чудовим, але робить ці пристрої критичними.
- ZIL завжди існує, навіть без SLOG; SLOG просто переміщує лог на швидший, з меншим латентністю пристрій.
- Вміст L2ARC — одноразовий за задумом; його створили як кеш, який можна втратити без сліз.
- Feature flags пулу — це односторонні двері: включення нових фіч може заблокувати імпорт на старих системах. Можливість видалення часто залежить від цих флагів.
- Scrub у ZFS передує більшості сучасних «cloud native» практик як рутинний спосіб виявлення мовчазної корупції з контрольними сумами end-to-end.
- Metaslab і space maps набагато важливіші під час евакуації: аллокатор стає пляшковим горлом задовго до того, як впаде завантаження CPU.
- Фрагментація — це не лише про продуктивність: вона може перетворити евакуацію на довге, зупинно-пускове переписування з неприємними спалахами латентності.
Швидкий план діагностики (знайдіть вузьке місце перед тим, як гадати)
Це «у мене є 15 хвилин до наступної наради і пул тане» потік. Не будьте креативними. Будьте систематичними.
По-перше: чи придатний пул для видалення vdev?
- Перевірте feature flags і версію/реалізацію ZFS.
- Підтвердіть, що ціль — знімний клас (не top-level raidz на стеку, що його не підтримує).
По-друге: чи достатньо місця для евакуації?
- Огляньте вільний простір пулу і фрагментацію.
- Перевірте snaphots і reservations, які блокуватимуть звільнення місця.
- Вирішіть, чи потрібно видалити/перемістити дані або додати тимчасову ємність спочатку.
По-третє: чи здатний пул пережити операцію?
- Є якісь деградовані vdev? Виправте їх перш ніж починати.
- Йде resilver або scrub? Розгляньте, чи чекати.
- Перевірте SMART на пристроях, які можуть померти під час евакуації.
По-четверте: якщо видалення йде повільно, на що воно чекає?
- Насичення IOPS дисків? Дивіться
iostatі латентність по vdev. - Один повільний диск? Шукайте пристрій з великими await-часами.
- Контенція аллокатора / фрагментація? Очікуйте нерівномірний прогрес і багато метаданих I/O.
- Recordsize/малі блоки? Робота з малими блоками може зробити евакуацію надзвичайно повільною.
Практичні завдання: команди, результати та рішення
Нижче — реальні операційні кроки. Кожен — «зроби, інтерпретуй вивід, прийми рішення». Це спосіб не перетворити зберігання на перформанс-арт.
Завдання 1: Ідентифікуйте топологію пулу
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
scan: scrub repaired 0B in 02:11:43 with 0 errors on Wed Dec 18 03:11:12 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-WDC_WD80EFAX-1 ONLINE 0 0 0
ata-WDC_WD80EFAX-2 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
ata-WDC_WD80EFAX-3 ONLINE 0 0 0
ata-WDC_WD80EFAX-4 ONLINE 0 0 0
logs
nvme-SAMSUNG_MZVLB256 ONLINE 0 0 0
cache
nvme-INTEL_SSDPEKNW512 ONLINE 0 0 0
errors: No known data errors
Що це означає: Два top-level mirror vdev, плюс log-пристрій і кеш-пристрій. Mirror — найбільш дружня до видалення топологія.
Рішення: Якщо мета — звузити ємність, кандидатом є mirror-1 (top-level). Якщо мета — спростити структуру, можна безпечніше видалити SLOG або L2ARC.
Завдання 2: Перевірте feature flags пулу (ворота придатності)
cr0x@server:~$ zpool get -H feature@device_removal tank
tank feature@device_removal active -
Що це означає: У пулі активовано feature device_removal.
Рішення: Продовжуйте з плануванням. Якщо тут disabled або -, ви, ймовірно, не зможете видалити top-level vdev без апгрейду/імпорту з фічами (а це окреме вікно змін).
Завдання 3: Перевірте, наскільки заповнений пул (чи зможете евакуювати?)
cr0x@server:~$ zfs list -o name,used,avail,refer,mountpoint -r tank
NAME USED AVAIL REFER MOUNTPOINT
tank 41.2T 6.3T 96K /tank
tank/home 11.1T 6.3T 10.9T /tank/home
tank/vm 28.7T 6.3T 28.7T /tank/vm
tank/backups 1.4T 6.3T 1.4T /tank/backups
Що це означає: Лише 6.3T вільних. Якщо на vdev, який ви хочете видалити, виділено більше даних, евакуація не завершиться.
Рішення: Перед видаленням top-level vdev оцініть, скільки даних на ньому. Якщо невпевненість — припустіть «приблизно пропорційно» і вимагайте комфортного запасу. Якщо не можете зробити запас, не починайте видалення.
Завдання 4: Перевірте ємність і фрагментацію пулу (прогноз болючості евакуації)
cr0x@server:~$ zpool list -o name,size,alloc,free,frag,health tank
NAME SIZE ALLOC FREE FRAG HEALTH
tank 47.5T 41.2T 6.3T 58% ONLINE
Що це означає: 58% фрагментація — це не «нормально». Це «це займе більше часу, ніж ви хочете, і вплине на продуктивність».
Рішення: Якщо потрібно робити негайно — плануйте обмеження швидкості і довший вікно. Якщо можна почекати — розгляньте переміщення холодних даних або інші стратегії дефрагментації перед спробою видалення.
Завдання 5: Перевірте, чи snaphots не блокують місце
cr0x@server:~$ zfs list -t snapshot -o name,used,refer -S used | head
NAME USED REFER
tank/vm@hourly-2025-12-25-0900 1.2T 28.7T
tank/vm@hourly-2025-12-25-0800 1.1T 28.7T
tank/home@daily-2025-12-24 640G 10.9T
tank/vm@hourly-2025-12-25-0700 610G 28.7T
Що це означає: Снапшоти споживають значну кількість простору. Видалення датасетів може не звільнити місце, якщо snaphots посилаються на старі блоки.
Рішення: Якщо потрібен запас для евакуації — зменшіть збереження snaphots або відреплікуйте snaphots за межі пулу, а потім радикально видаліть локально — обережно, узгодивши зі стейкхолдерами.
Завдання 6: Перевірте reservation, що можуть блокувати евакуацію
cr0x@server:~$ zfs get -H -o name,property,value -r reservation,refreservation tank | egrep -v '\t(none|0)\t' | head
tank/vm reservation 5T
tank/home refreservation 1T
Що це означає: Reservation вирізають простір, який інші операції не можуть використовувати, включно з простором для евакуації.
Рішення: Тимчасово зменшіть або видаліть reservation (згодом погодивши з власниками додатків), щоб створити реальний вільний простір. Поверніть їх після завершення.
Завдання 7: Підтвердіть здоров’я перед початком масштабних змін
cr0x@server:~$ zpool status tank
pool: tank
state: ONLINE
scan: scrub repaired 0B in 02:11:43 with 0 errors on Wed Dec 18 03:11:12 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-WDC_WD80EFAX-1 ONLINE 0 0 0
ata-WDC_WD80EFAX-2 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
ata-WDC_WD80EFAX-3 ONLINE 0 0 0
ata-WDC_WD80EFAX-4 ONLINE 0 0 0
logs
nvme-SAMSUNG_MZVLB256 ONLINE 0 0 0
cache
nvme-INTEL_SSDPEKNW512 ONLINE 0 0 0
Що це означає: ONLINE, без помилок, нещодавній scrub пройшов успішно. Так виглядає пул, придатний для ризикових робіт.
Рішення: Якщо бачите DEGRADED, FAULTED або зростання помилок контрольних сум, виправте спочатку. Видалення під деградацією — гра з високою ставкою.
Завдання 8: Видалити L2ARC-пристрій (безпечно, умовно оборотне)
cr0x@server:~$ sudo zpool remove tank nvme-INTEL_SSDPEKNW512
Що це означає: Кеш-пристрій відʼєднано від пулу. Зазвичай немає драматичного виводу.
Рішення: Моніторте латентність читання і коефіцієнт попадань у кеш (якщо відстежуєте). Якщо продуктивність впала, додайте його назад або замініть на кращий кеш-пристрій. Цілісність даних не під загрозою.
Завдання 9: Видалити SLOG-пристрій (очікуйте зміни в латентності sync-записів)
cr0x@server:~$ sudo zpool remove tank nvme-SAMSUNG_MZVLB256
Що це означає: ZFS повернеться до використання основного пулу для intent logging. Ваші додатки можуть це помітити.
Рішення: Якщо середовище залежить від sync-записів (бази даних, NFS з sync), заплануйте зміну або тимчасово попередьте користувачів. Якщо зʼявляться таймаути додатків — швидко поверніть SLOG.
Завдання 10: Розпочати видалення top-level vdev (евакуація починається)
cr0x@server:~$ sudo zpool remove tank mirror-1
Що це означає: Пул починає евакуювати дані з mirror-1 на залишені top-level vdev.
Рішення: Негайно запустіть моніторинг прогресу та продуктивності. Також: попередьте людей. Це не безшумна операція.
Завдання 11: Моніторинг прогресу через zpool status
cr0x@server:~$ zpool status tank
pool: tank
state: ONLINE
remove: Removal of vdev 1 copied 8.31T of 17.2T at 612M/s, 03:48:29 remaining
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-WDC_WD80EFAX-1 ONLINE 0 0 0
ata-WDC_WD80EFAX-2 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0 (removing)
ata-WDC_WD80EFAX-3 ONLINE 0 0 0
ata-WDC_WD80EFAX-4 ONLINE 0 0 0
errors: No known data errors
Що це означає: ZFS показує скопійовані байти, швидкість і оцінку часу. Швидкості будуть коливатися; не довіряйте ETA буквально.
Рішення: Якщо швидкість падає і латентність стрибає — обмежте або призупиніть навантаження. Якщо зʼявляються помилки — зупиніться й переоцініть стан апаратури.
Завдання 12: Слідкуйте за латентністю по пристроях під час видалення (знайдіть повільне колесо)
cr0x@server:~$ iostat -x 5
Linux 6.6.0 (server) 12/25/2025 _x86_64_ (32 CPU)
Device r/s w/s rkB/s wkB/s await svctm %util
sda 92.1 48.3 9840 5120 6.4 1.1 15.2
sdb 89.7 47.9 9600 4980 6.7 1.0 14.8
sdc 31.2 88.4 3200 10120 38.9 1.2 98.5
sdd 29.8 90.1 3100 10320 41.3 1.2 99.1
Що це означає: sdc і sdd насичені з високим await; швидше за все це vdev, що видаляється, або цільовий vdev під тиском.
Рішення: Якщо лише один пристрій повільний — підозрюйте відмову диска або проблему з кабелем/HBA. Якщо всі цільові пристрої завантажені — ви робите занадто багато I/O; обмежте видалення, зменшивши конкуренцію за ресурси.
Завдання 13: Перевірте поведінку TRIM/discard на SSD (прихований провал продуктивності)
cr0x@server:~$ zpool get -H autotrim tank
tank autotrim on -
Що це означає: Autotrim увімкнено. Під час інтенсивних переписів trim може додавати накладні витрати залежно від прошивки пристрою.
Рішення: Якщо бачите дивну ампліфікацію записів або спалахи латентності на SSD під час евакуації, протестуйте з autotrim=off у вікні обслуговування. Не перемикайте це без розуміння поведінки SSD у вашому парку.
Завдання 14: Знайдіть «чому місце не звільняється?» — логічне vs фізичне використання
cr0x@server:~$ zfs get -H -o name,property,value -r used,usedbysnapshots,usedbydataset,usedbyrefreservation tank/vm
tank/vm used 28.7T
tank/vm usedbysnapshots 6.4T
tank/vm usedbydataset 22.3T
tank/vm usedbyrefreservation 0B
Що це означає: Велика частина — це snaphots. Видалення файлів у tank/vm не звільнить місце, якщо snaphots посилаються на ці блоки.
Рішення: Скоригуйте політику snaphots або реплікуйте й обрізайте. Якщо ви намагаєтеся зробити місце для видалення, snaphots часто є справжнім блокатором.
Завдання 15: Підтвердіть, що видалений vdev зник (перевірка кінцевого стану)
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-WDC_WD80EFAX-1 ONLINE 0 0 0
ata-WDC_WD80EFAX-2 ONLINE 0 0 0
errors: No known data errors
Що це означає: mirror-1 зник. Розмір пулу відобразить звуження.
Рішення: Тепер ви можете використати диски, замінити їх або побудувати новий vdev деінде. Також: перевірте оповіщення про ємність. Ваші пороги мають змінитися, бо пул став меншим.
Завдання 16: Підтвердіть розмір пулу після зміни і запас місця (не робіть припущень)
cr0x@server:~$ zpool list -o name,size,alloc,free,frag,health tank
NAME SIZE ALLOC FREE FRAG HEALTH
tank 23.7T 21.1T 2.6T 64% ONLINE
Що це означає: Пул став значно меншим; вільного місця стало менше. Фрагментація зросла (поширено після великих переміщень).
Рішення: Якщо тепер вільного місця критично мало — перемістіть робочі навантаження, додайте нову ємність або скоригуйте правила збереження. Не святкуйте видалення й не забувайте, що ви тепер працюєте близько до повного пулу.
Три корпоративні міні-історії з практики
Інцидент: неправильне припущення («ми ж можемо видалити raidz vdev, чи не так?»)
Середня SaaS-компанія мала пул ZFS, що підтримував флот VM-хостів. Він починався як raidz2 через бажання ефективності і захисту. З часом додали ще один raidz2 vdev під час росту. Потім ріст уповільнився, бюджет на обладнання скоротився, і хтось запропонував «видалити новіший vdev», щоб перерозподілити диски в інший кластер.
План виглядав безпечним: запустити видалення в п’ятницю ввечері, нехай працює весь вікенд, у понеділок отримати менший пул. Оператор вже використовував zpool remove раніше — на кеш-пристроях. Вони припустили, що ця гнучкість поширюється на будь-який vdev. ZFS не погодилася.
Команда отримала грубу помилку, що тип vdev не знімається в їхньому середовищі. Більша проблема була не в помилці; вона була в тому, що сталося потім. Щоб «змусити» це, команда спробувала низку відчайдушних обхідних шляхів: від’єднання пристроїв, офлайн-диски й часткові заміни. Так вони перетворили здоровий raidz vdev у деградований під час зміни, працюючи в продакшені.
Їм вдалося відновитися, але це зайняло багато ночей: реонлайнити пристрої, resilvering і скасування плану «зменшення». Постмортем був простим: помилка була в тому, що вони сприйняли видалення vdev як загальний інструмент для звуження пулу. Це не так. Якщо хочете мати опцію звуження — вибирайте топологію, що це підтримує, і приймайте її вартість.
Оптимізація, що відкотилася: додання «тимчасового» special vdev для прискорення метаданих
Команда інженерів фінансових сервісів мала пул ZFS з великим деревом файлів з мільйонами малих файлів. Операції з метаданими були повільні, обходи директорій болісні, і в кожному інциденті була одна й та сама теза: «потрібно додати SSD». Вони додали. Додали special vdev на парі NVMe для метаданих і малих блоків. Продуктивність покращилася одразу.
Потім вони загралися. Щоб максимізувати ємність, налаштували special vdev так, що він був технічно надмірним, але операційно крихким: оновлення прошивки й обслуговування обробляв інший відділ, і команда сховища не отримувала повідомлень про нюанси NVMe. Передбачувано, один NVMe почав кидати помилки під тривалим навантаженням і інколи зникав/з’являвся на шині PCIe.
Нічого не зіпсувалося миттєво. Саме це робить ситуацію небезпечною. Пул почав логувати періодичні помилки контрольних сум, пов’язані з читаннями метаданих. Користувачі бачили «випадкові» I/O помилки. Інстинкт команди був простий: прибрати special vdev і повернутися назад. Але видалення вимагає здорового шляху для читання блоків і їх перепису. Їхня «оптимізація» стала залежністю.
Кінцеве рішення було прозаїчним: замінити нестабільний NVMe, resilver special mirror, зробити scrub до чистого стану, а потім плановано мігрувати/видаляти старий. Урок не в «ніколи не використовувати special vdev». Урок: якщо додаєте special vdev — ставтесь до нього як до першокласного рівня з життєвим циклом, моніторингом і контролем змін. Інакше це апгрейд продуктивності, який виставить вам рахунок пізніше.
Нудна, але правильна практика, що врятувала день: запас ємності й поетапна міграція
Команда внутрішньої платформи вели ZFS для NFS домашніх директорій і артефактів збірки. У них було правило, яке дратувало всіх: пул має залишатися менше ніж на 75% використаний, а збереження snaphots має бути обґрунтованим. Інженери скаржилися, бо це здавалося «марним» місцем.
Одного кварталу їм потрібно було вивести шасі старих дисків. Пул розширювали протягом років кількома top-level mirror vdev (не raidz), саме тому, що цінували оперативну гнучкість. Вони запланували видалення mirror vdev, розміщених на старому шасі.
Оскільки пул мав запас, евакуація могла виконуватися без паніки аллокатора. Оскільки snaphots контролювали, вони могли звільнити місце при необхідності. Оскільки вони регулярно перевіряли і міняли сумнівні диски, апаратних відмов не виявили під час багатоденної переписувальної роботи.
Видалення зайняло час, і пул працював гарячіше, ніж зазвичай, але залишався передбачуваним. Виведення шасі відбулося за графіком, і ніхто, крім відповідального за сховище, навіть не помітив. Ось сенс нудних практик: вони не створюють захопливих історій, але завдяки цьому ви продовжуєте їх виконувати.
Жарт #2: «Просто видаліть vdev» — це storage-версія «просто перезапустіть» — іноді вірно, але зазвичай без урахування того, що зламається далі.
Поширені помилки: симптом → причина → виправлення
1) Симптом: zpool remove відмовляється з повідомленням «operation not supported»
Причина: Feature flags пулу не включають device removal, або ваша реалізація/версія ZFS не підтримує видалення для цього типу vdev.
Виправлення: Перевірте feature flags, версію ZFS і тип vdev. Якщо це raidz — вважайте, що потрібна міграція, а не видалення. Не намагайтеся робити «креативні» detach/offline хаки.
2) Симптом: видалення починається, але прогрес повзе до практично нуля
Причина: Пул надто заповнений або сильно фрагментований; аллокатор і вибір metaslab стають дорогими, і записи конкурують з продакшен I/O.
Виправлення: Створіть запас (видаліть/реплікуйте дані, зменшіть snaphots), заплануйте роботу в тихий час і зменшіть конкуренцію навантаження. Якщо не можете — не проводьте видалення онлайн під піком.
3) Симптом: пул ONLINE, але додатки бачать стрибки латентності та таймаути під час видалення
Причина: Евакуація насичує диски і підвищує латентність для синхронних або метаданто-важких навантажень.
Виправлення: Додайте тимчасову ємність, щоб зменшити тиск руху, перемістіть «гарячі» навантаження, або обмежте швидкість на рівні додатків (rate-limit бекапів, призупиніть відновлення, чергуйте пакетні завдання). Моніторте на рівні SLO додатка, не лише метрики зберігання.
4) Симптом: «Ми звільнили 5TB, але zpool list вільного майже не показує»
Причина: Снапшоти ще посилаються на блоки; простір логічно видалено, але фізично утримується.
Виправлення: Визначте великі споживачі snaphots за допомогою zfs list -t snapshot і usedbysnapshots. Скоригуйте політику збереження, реплікуйте, а потім свідомо видаліть snaphots.
5) Симптом: після видалення SLOG продуктивність бази даних падає
Причина: Sync-записи тепер лягають на основний пул; латентність зросла радикально.
Виправлення: Добавте SLOG назад на низьколатентний пристрій з захистом від втрати електроживлення. Якщо не можете — оцініть, чи справді додаток потребує sync, або чи ви випадково змусили sync через налаштування експорту/монтування.
6) Симптом: видалення special vdev здається неможливим без ризику
Причина: Special vdev містить критичні метадані/малі блоки, і у вас немає безпечного цільового розміщення або запасу для міграції.
Виправлення: Розглядайте це як міграцію: додайте новий special vdev (в дзеркалі), мігруйте, зробіть scrub, потім видаліть старий. Якщо платформа не підтримує видалення — плануйте міграцію пулу.
7) Симптом: пул звузився, але вільного місця стало критично мало
Причина: Ви планували можливість евакуації, але не планували пост-видалення запасу для експлуатації.
Виправлення: Перерахуньте цільові показники ємності після видалення. Оновіть пороги оповіщень. Додайте ємність до того, як її почнуть вимагати під час відмови.
8) Симптом: один диск показує шалений await під час видалення
Причина: Несправний диск, проблемний кабель/HBA або пристрій з дивною поведінкою прошивки під навантаженням.
Виправлення: Перевірте апарат. Замініть підозрілий пристрій до продовження довгої евакуації. Якщо він помре під час операції, ви можете втратити можливість безпечно завершити евакуацію.
Контрольні списки / покроковий план (як робити це без імпровізацій о 3:00)
Перевірка перед вильотом: вирішіть, чи видалення — правильний інструмент
- Сформулюйте мету: звуження ємності, виведення обладнання, видалення рівня продуктивності або скасування тимчасового розширення.
- Ідентифікуйте ціль: cache/log/special/top-level data vdev.
- Перевірте підтримку: feature flags і реалізацію/версію ZFS для цієї цілі.
- Підтвердіть здоров’я пулу: жодних деградованих vdev, жодних невирішених помилок контрольних сум.
- Підтвердіть запас: вільне місце плюс операційний запас; скоригуйте snaphots/reservations.
- Сплануйте вплив на навантаження: заплануйте вікно, обмеження швидкості та комунікацію.
План виконання: видалення top-level vdev (дані)
- Зробіть конфігураційну «знімку» для власного спокою: зафіксуйте
zpool status,zpool list,zfs listі налаштування reservations. - Запустіть scrub перед видаленням, якщо не робили це недавно. Ви хочете виявити латентні помилки читання зараз, а не під час евакуації.
- Зменшіть або призупиніть непотрібні пакетні роботи: бекапи, великі відновлення, роботу, що створює багато записів.
- Почніть видалення:
zpool remove pool target. - Моніторте прогрес і латентність:
zpool statusтаiostat -x. - Якщо вплив на продуктивність неприйнятний: спочатку зменшіть конкуренцію навантаження. Не зупиняйте операцію в паніці, якщо у вас немає явного плану відкату.
- Після завершення перевірте топологію та ємність. Оновіть пороги моніторингу й прогнози ємності.
План виконання: видалення SLOG або L2ARC (підтримуючі vdev)
- Виміряйте базову латентність додатка і зберігання.
- Видаліть пристрій за допомогою
zpool remove. - Слідкуйте за синхронними записами (бази, NFS) при видаленні SLOG; для L2ARC очікуйте лише прогрів кеша.
- Вирішіть, чи замінити пристрій на кращий, чи працювати без нього.
Мислення про відкат (бо не завжди виходить як хочеш)
- Якщо видалення не підтримується: ваш відкат — «припинити спроби» і запланувати міграцію в новий пул з потрібною топологією.
- Якщо видалення підтримується, але надто руйнівне: відкат — операційний — обмежіть конкуренцію навантаження, додайте тимчасову ємність або перенесіть вікно. Ви не можете «переписати назад» евакуацію, яка вже виконана.
- Якщо апарат починає відмовляти під час видалення: ставте це як інцидент. Видаляємий vdev має залишатися читабельним, щоб завершити евакуацію безпечно.
Поширені питання
Чи можу я звузити пул ZFS так само, як LVM-том?
Зазвичай ні. ZFS спроєктований для зростання пулів. Видалення vdev — специфічна евакуаційна функція, а не загальний інструмент звуження, і вона обмежується типом vdev та підтримкою платформи.
Чи те саме видалити диск з mirror і видалити vdev?
Ні. Від’єднання leaf-диска з mirror змінює надлишковість всередині vdev. Видалення top-level vdev ініціює евакуацію виділених блоків на інші top-level vdev.
Чи можна видалити raidz vdev з пулу?
У багатьох реальних розгортаннях: фактично ні. Вважайте raidz top-level vdev постійними. Якщо потрібна гнучкість звуження, проектуйте з mirror або плануйте міграцію пулу.
Скільки часу займає видалення vdev?
Залежить від виділених даних на цільовому vdev, фрагментації пулу, швидкостей пристроїв та конкуренції навантажень. Очікуйте «години до днів», а не «хвилини» для багатотерабайтних vdev.
Що станеться, якщо диск у vdev, що видаляється, відмовить під час евакуації?
Якщо vdev стає нечитаємим, евакуація може завершитися невдало, і ви можете втратити можливість завершити видалення безпечно. Mirror дає більше стійкості; single-disk vdev безжалісні. Не починайте видалення на ненадійному обладнанні.
Чи ризикує видалення SLOG втратою даних?
Не в сенсі корупції даних. ZFS лишається консистентним. Ризик — продуктивність: latency синхронних записів може різко зрости, викликаючи таймаути додатків.
Чи ризикує видалення L2ARC втратою даних?
Ні. L2ARC — кеш. Видалення його знижує попадання в кеш, і показники відновляться з часом.
Чи можна безпечно видалити special vdev?
Іноді так, але це не «безпечне» у повсякденному розумінні. Special vdev містить метадані; потрібно забезпечити надлишковість, здоров’я, запас місця та підтримку платформи. Розглядайте це як міграцію з scrub і валідацією.
Чому вільне місце таке критичне для видалення?
Бо евакуація переписує виділені блоки в інші vdev. Якщо решта vdev не може прийняти дані, ZFS не зможе завершити переміщення. Крім того, дуже заповнені пули поводяться погано: алокація сповільнюється і продуктивність колапсує.
Чи варто віддавати перевагу mirror замість raidz, якщо хочу мати можливість видаляти vdev?
Так, якщо оперативна гнучкість важливіша за ефективність ємності. Mirror коштує дорожче в утилізованій площі, але дає простіше масштабування, заміни і (де підтримується) видалення.
Висновок: практичні наступні кроки
Якщо ви хочете щось видалити з пулу ZFS — почніть із класифікації. Кеш і лог-пристрої зазвичай — прості перемоги. Top-level data vdev можливі лише коли ваш пул і платформа явно це підтримують, і навіть тоді це контрольована міграція даних під навантаженням.
Наступні кроки, які віддають віддачу негайно:
- Запустіть перевірки придатності зараз (feature flags, топологія), перш ніж вам знадобиться опція під час інциденту.
- Забезпечте запас. Якщо ваш пул завжди вище ~80% використання, ви вибираєте життя в режимі кризи.
- Проєктуйте на зміни: якщо ви передбачаєте можливість звуження, віддавайте перевагу mirror-based top-level vdev і уникайте «тимчасових» макетів, які не можна відкотити.
- Практикуйте нудні дисципліни: scrubs, SMART-моніторинг, гігієна snaphots і розумні reservations, які можна пояснити скептичному колезі.
ZFS робитиме правильну річ, коли ви поважаєте її правила. Коли не поважаєте — вона все одно зробить правильну річ: відмовить. Це фіча. Ставтеся до неї як до переваги.