ZFS zfs list -o space: Подання, яке пояснює «Куди воно поділося?»

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

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

zfs list -o space — це той рівень. Це «книга обліку простору», яка зіставляє датасети, знімки, reservation, refreservation і ті невидимі споживання, що роблять чергування цікавими. У продакшені це різниця між припущеннями та знанням — і між видаленням неправильного і виправленням реальної причини.

Що zfs list -o space насправді показує

Більшість суперечок «куди зник мій простір?» виникають через змішування двох валідних, але різних перспектив:

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

zfs list -o space — це відредагована карта другої перспективи. Вона розбиває «USED» на змістовні відсіки: дані, знімки, дочірні датасети, reservation, refreservation і метадані. Якщо ви дивилися лише zfs list з колонками за замовчуванням, ви пропускаєте квитанції.

Операційна замітка: скорочення space не магічне; це набір іменованих колонок. На багатьох системах воно розгортається у щось на кшталт:

  • name, avail, used, usedbysnapshots, usedbydataset, usedbychildren, usedbyrefreservation, usedbyreservation

Залежно від реалізації та версії ZFS, ви також можете побачити usedbyrefquota або вам доведеться запитувати інші властивості явно. Принцип лишається: перестаньте трактувати USED як одне число.

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

Корисно знати, з яким звіром працюєте:

  1. ZFS зʼявився в Sun Microsystems на початку 2000-х як комбінована файлова система і volume manager, тому він може робити знімки на рівні блоків без окремого шару LVM.
  2. Початковий дизайн ZFS зробив наскрізну контрольну суму та copy-on-write основними функціями, тому «видалення файлу» не обовʼязково означає негайне звільнення простору, якщо знімки все ще посилаються на блоки.
  3. Датасети ZFS дешеві і повинні бути численними; дизайн передбачає нарізку сховища за застосунком/орендарем і керування властивостями для кожного датасету.
  4. Облік простору в ZFS навмисно розрізняє «referenced» від «used»; клоні та знімки ускладнюють «власність», тому ZFS це відстежує.
  5. Reservation та refreservation існують, бо «best effort» зберігання неприйнятне для багатьох корпоративних навантажень; це обіцянки, підкріплені поведінкою аллокатора, а не просто слова.
  6. Zvols (блокові пристрої на ZFS) зʼявилися для обслуговування образів віртуальних машин і споживачів iSCSI/FC; вони ускладнюють інтуїцію простору, бо інструменти файлової системи не бачать їх вмісту.
  7. Стиснення було додано рано і стало широко використовуваним, оскільки це одна з небагатьох оптимізацій, яка може також зменшити write amplification і покращити ефективність кешу — якщо дані стискаються.
  8. Дедуплікація відома як геніальна і фінансово руйнівна при випадковому вмиканні; багато операторів мають історію «ми пробували дедуп once» і тепер ставляться до неї обережно.

Колонки простору, пояснення

Почніть з ментальної моделі: «хто утримує блоки?»

У ZFS блоки можуть бути спільними. Знімок — це не копія; це закладка. Коли ви змінюєте блок після того, як існує знімок, ZFS записує новий блок в інше місце (copy-on-write), а знімок продовжує вказувати на старий. Тому знімок «тримає» старі блоки живими. Ось чому видалення файлів не завжди повертає простір: ви видалили живе посилання, але знімок все ще посилається на дані.

zfs list -o space відповідає: скільки з USED цього датасету утримується з якої причини?

Пояснення по колонках (звичні підозрювані)

USED

Загальний простір, спожитий датасетом та всім «нижче» нього, залежно від контексту. Для датасету USED зазвичай включає власні дані і метадані, знімки (в сенсі унікального простору, що їм приписується), дочірні датасети, плюс впливи reservation/refreservation. Це вигляд для аллокатора. Саме це робить пули заповненими.

AVAIL

Простір доступний цьому датасету, з урахуванням вільного місця пулу та квот/резервів (і іноді спеціальних правил типу «slop space»). AVAIL — це число, яке відчуває ваша програма при записі.

USEDBYDATASET

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

USEDBYSNAPSHOTS

Простір, утримуваний через знімки. Це не «розмір знімків» в людському сенсі; це унікальний простір, який не можна звільнити, бо знімки посилаються на нього. Високе USEDBYSNAPSHOTS часто означає «ми часто переписуємо датасет із увімкненими знімками». Думайте про бази даних, образи VM, кеші CI-артефактів або все, що перезаписує великі файли на місці.

USEDBYCHILDREN

Простір, використаний дочірніми (descendant) датасетами і томами. Батько може виглядати «заповненим», коли він насправді просто контейнер. Це число рятує від звинувачення неправильного датасету.

USEDBYRESERVATION

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

USEDBYREFRESERVATION

Простір, спожитий через refreservation. На відміну від reservation, refreservation зазвичай застосовується до самого датасету (не до дітей) і часто зустрічається з zvol, що обслуговують VM. Це може бути «невидимий податок», який робить пул схожим на повний, хоча фактичних даних немає.

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

Повʼязані властивості, що зазвичай доповнюють картину

zfs list -o space — найшвидша лінза, але часто захочеться суміжні властивості, щоб дізнатися «чому»:

  • referenced: скільки простору вказує жива держава датасету (не рахуючи знімків). Чудово відповідати на питання «наскільки він великий насправді?»
  • logicalused / logicalreferenced: скільки даних було б без стиснення (і іноді до копій/дедупа). Корисно для виявлення переваг/втрат від стиснення.
  • compressratio: швидка підказка, чи допомагає стиснення.
  • written: скільки даних було записано з останнього знімка (або створення датасету). Хороша метрика для аналізу churn.
  • volsize / volblocksize: для поведінки zvol.
  • copies, dedup: перемикачі «чи ми множимо блоки?».

План швидкої діагностики

Це «03:17, пул 92%, pager співає» версія. Мета — не бути вишуканим; мета — не зробити гірше.

1) Підтвердіть істинний стан пулу

Перший питання: чи це справді проблема простору, чи фрагментація/алокація/метадані, що поводяться як проблема простору?

cr0x@server:~$ zpool list
NAME   SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank  10.9T  9.80T  1.10T        -         -    43%    89%  1.00x  ONLINE  -

Інтерпретація: CAP близько 90% — це зона ризику для багатьох пулів, особливо якщо FRAG високий і навантаження з випадковими записами. Якщо CAP низький, але AVAIL у датасетах низький, швидше за все ви маєте справу з квотами/резерваціями.

2) Знайдіть головних винуватців за фактичним обліком аллокатора

cr0x@server:~$ zfs list -o space -S used -r tank
NAME              AVAIL   USED  USEDSNAP  USEDDS  USEDCHILD  USEDREFRESERV  USEDRESERV
tank              1.10T  9.80T     3.20T    900G      5.70T            0B          0B
tank/vm           1.10T  6.10T     2.60T    400G      3.10T         80.0G          0B
tank/home         1.10T  2.90T     400G     2.30T     200G            0B          0B
tank/backup       1.10T  800G     200G      580G       20G            0B          0B

Інтерпретація: Тепер у вас є мапа: пул заповнений переважно через tank/vm; у ньому домінують знімки (USEDSNAP), також є слід refreservation.

3) Виберіть важіль, який безпечно тягнути: знімки, reservation чи реальні дані

В порядку від найменш ризикованого до найризикованішого:

  1. Обріжте знімки згідно політики зберігання (особливо автоматичні). Це зазвичай найбільший ефект з найменшою зоною ураження.
  2. Зменшіть/видаліть refreservation тільки якщо ви розумієте споживача (VM/zvol) і можете прийняти ризик overcommit.
  3. Видаляйте/переміщуйте живі дані тільки якщо ви впевнені, що знімки не є реальною причиною і ви не порушуєте очікування робочого навантаження.

4) Перевірте ще одним видом обліку перед дією

cr0x@server:~$ zfs get -o name,property,value -H used,referenced,logicalused,logicalreferenced,compressratio tank/vm
tank/vm	used	6.10T
tank/vm	referenced	410G
tank/vm	logicalused	7.90T
tank/vm	logicalreferenced	520G
tank/vm	compressratio	1.92x

Інтерпретація: Живі referenced дані — лише ~410G; решта — знімки/діти/резервації. Якщо ви почнете видаляти «живі» файли VM, ви не отримаєте багато назад. Левередж — у знімках.

Практичні завдання (команди + інтерпретація)

Це щоденні кроки, що перетворюють -o space із тривії в економію грошей і уникнення простоїв. Усі приклади припускають пул tank; підлаштуйте під свій випадок.

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

cr0x@server:~$ zfs list -o space -r tank
NAME        AVAIL   USED  USEDSNAP  USEDDS  USEDCHILD  USEDREFRESERV  USEDRESERV
tank        1.10T  9.80T     3.20T    900G      5.70T            0B          0B
tank/vm     1.10T  6.10T     2.60T    400G      3.10T         80.0G          0B
tank/home   1.10T  2.90T     400G     2.30T     200G            0B          0B

Інтерпретація: Використовуйте це, щоб відповісти «це знімки, діти чи сам датасет?» без здогадок.

Завдання 2: Сортувати за простором, утримуваним знімками, щоб знайти точки сильного churn

cr0x@server:~$ zfs list -o name,usedbysnapshots,usedbydataset,usedbychildren -S usedbysnapshots -r tank
NAME        USEDSNAP  USEDDS  USEDCHILD
tank/vm       2.60T    400G     3.10T
tank/home      400G   2.30T      200G
tank/backup     200G    580G       20G

Інтерпретація: Обрізка знімків має починатися з tank/vm. Це також натяк перевірити частоту знімків на датасетах з високим churn.

Завдання 3: Перелічити знімки та їхний інкрементний «used» слід

cr0x@server:~$ zfs list -t snapshot -o name,used,referenced -S used -r tank/vm | head
NAME                              USED  REFERENCED
tank/vm@auto-2025-12-24-2300       48G        410G
tank/vm@auto-2025-12-24-2200       41G        409G
tank/vm@auto-2025-12-24-2100       39G        409G
tank/vm@weekly-2025-w51            22G        405G

Інтерпретація: Snapshot USED — додатковий простір, спожитий у порівнянні з попереднім станом знімка. Великі числа означають сильний перепис між знімками.

Завдання 4: Швидко побачити churn з часу останнього знімка за допомогою written

cr0x@server:~$ zfs get -o name,property,value -H written tank/vm
tank/vm	written	312G

Інтерпретація: Якщо written величезний і знімки часті, зростання простору знімків буде великим. Класичні порушники — бази даних і образи VM.

Завдання 5: Виявити мінні поля refreservation (поширено для zvol-backed VM)

cr0x@server:~$ zfs list -o name,type,usedbyrefreservation,refreservation,volsize -r tank/vm
NAME              TYPE   USEDREFRESERV  REFRESERVATION  VOLSIZE
tank/vm           filesystem       80.0G             none        -
tank/vm/zvol0     volume          200G              200G      500G
tank/vm/zvol1     volume          300G              300G      300G

Інтерпретація: USEDREFRESERV показує, скільки простору відкладено. Якщо пул напружений, ці «відкладені» блоки можуть бути різницею між стабільністю та відмовою.

Завдання 6: Знайти датасети, де квоти роблять AVAIL меншим, ніж вільне в пулі

cr0x@server:~$ zfs get -o name,property,value -H quota,refquota,reservation,refreservation tank/home tank/vm
tank/home	quota	2.5T
tank/home	refquota	none
tank/home	reservation	none
tank/home	refreservation	none
tank/vm	quota	none
tank/vm	refquota	none
tank/vm	reservation	none
tank/vm	refreservation	none

Інтерпретація: Квота може змусити датасет повідомляти про низький AVAIL, навіть коли в пулі є вільне місце. Це питання політики, а не пулу.

Завдання 7: Порівняти вигляд живої файлової системи з виглядом аллокатора ZFS (і виявити невідповідність)

cr0x@server:~$ df -h /tank/vm
Filesystem      Size  Used Avail Use% Mounted on
tank/vm          11T  410G   11T   4% /tank/vm

cr0x@server:~$ zfs list -o name,used,referenced,usedbysnapshots tank/vm
NAME     USED  REFERENCED  USEDSNAP
tank/vm  6.10T       410G    2.60T

Інтерпретація: df показує те, що доступно в живій файловій системі. ZFS повідомляє те, що аллокатор пулу мусить утримувати. Коли вони сильно розходяться, зазвичай задіяні знімки/клони/резервації.

Завдання 8: Виявити клони, що тримають простір (сюрприз «я видалив базовий образ»)

cr0x@server:~$ zfs list -o name,origin,used,referenced -r tank/vm
NAME                 ORIGIN                          USED  REFERENCED
tank/vm/base         -                               60G        60G
tank/vm/base@golden   -                               0B        60G
tank/vm/clone01       tank/vm/base@golden            80G        75G
tank/vm/clone02       tank/vm/base@golden            95G        88G

Інтерпретація: Клони залежать від оригінального знімка. Видаляйте origin snapshot без підготовки — отримаєте блокування, або ще гірше, неправильно сплануєте ємність, бо origin ще не можна видалити.

Завдання 9: Перевірити ефективність стиснення, коли логічне і фізичне розходяться

cr0x@server:~$ zfs get -o name,property,value -H logicalused,used,compressratio compression tank/home
tank/home	logicalused	3.40T
tank/home	used	2.90T
tank/home	compressratio	1.17x
tank/home	compression	lz4

Інтерпретація: Стиснення трохи допомагає, але не суттєво. Якщо logicalused значно більше за used, у вас реальні виграші; якщо близькі — не варто сподіватися на стиснення для планування ємності.

Завдання 10: Знайти датасети з несподівано високими метаданими (опосередковано)

cr0x@server:~$ zfs list -o name,used,referenced,recordsize,special_small_blocks -r tank | head -n 10
NAME       USED  REFERENCED  RECORDSIZE  SPECIAL_SMALL_BLOCKS
tank       9.80T      900G     128K      0
tank/home  2.90T     2.30T     128K      0
tank/vm    6.10T      410G     128K      0

Інтерпретація: ZFS не показує «використані метадані» як просту властивість у zfs list, але невідповідності між referenced і used, тип навантаження (мільйони малих файлів) і налаштування special vdev можуть сильно натякнути. Якщо підозрюєте метадані, підтвердіть на рівні пулу іншими інструментами і обережно розгляньте стратегії special vdev.

Завдання 11: Використовуйте zfs list -p для скриптів та невідформатованих одиниць

cr0x@server:~$ zfs list -o space -p -r tank/vm | head -n 3
NAME	AVAIL	USED	USEDSNAP	USEDDS	USEDCHILD	USEDREFRESERV	USEDRESERV
tank/vm	1209462790553	6713214521344	2858730235904	429496729600	3420000000000	85899345920	0
tank/vm/zvol0	1209462790553	650000000000	0	650000000000	0	214748364800	0

Інтерпретація: Використовуйте це при побудові алертів або звітів. Для людей — зручні одиниці; для автоматизації — цілі числа.

Завдання 12: Переконатися, що буде звільнено після видалення знімка (думка в режимі dry-run)

cr0x@server:~$ zfs list -t snapshot -o name,used -S used -r tank/vm | head -n 5
NAME                              USED
tank/vm@auto-2025-12-24-2300       48G
tank/vm@auto-2025-12-24-2200       41G
tank/vm@auto-2025-12-24-2100       39G
tank/vm@weekly-2025-w51            22G

Інтерпретація: Якщо ви видалите tank/vm@auto-2025-12-24-2300, верхня межа негайного відновлення — близько 48G — часто менше, якщо блоки спільні з клонами або іншими знімками. Цей рейтинг допомагає вирішити, що обрізати першочергово.

Завдання 13: Показати, що споживає батька: датасет чи діти

cr0x@server:~$ zfs list -o name,usedbydataset,usedbychildren,usedbysnapshots -r tank | grep -E 'tank$|tank/vm$|tank/home$'
tank       900G      5.70T     3.20T
tank/vm    400G      3.10T     2.60T
tank/home  2.30T      200G      400G

Інтерпретація: Чудово підходить, щоб визначити «який піддерево проблема?» і уникнути класичної помилки видалення у батька, коли дитина — основний споживач.

Завдання 14: Підтвердити, що reservation — причина низького AVAIL

cr0x@server:~$ zfs get -o name,property,value -H reservation,refreservation tank/vm/zvol1
tank/vm/zvol1	reservation	none
tank/vm/zvol1	refreservation	300G

cr0x@server:~$ zfs list -o name,avail,usedbyrefreservation -r tank/vm | grep zvol1
tank/vm/zvol1  1209462790553  322122547200

Інтерпретація: Якщо пул напружений, refreservation — це «витрачений» простір з точки зору аллокатора. Якщо ви його видалите, ви змінюєте контракт з тією VM або блоковим споживачем.

Жарт №2: Облік простору як бюджет — все гаразд, поки ви категоризуєте витрати.

Три міні-історії з корпоративного світу

1) Інцидент через неправильне припущення: «Ми видалили дані, отже простір має звільнитися»

Квиток прийшов як рутинний алерт ємності: пул 88%, зростає. Власник сервісу запевняв, що нічого суттєвого не змінилося. Сисадмін зробив нормальний первинний огляд: du -sh у точці монтування, побачив пару сотень гігабайтів, знизав плечима і вирішив, що алерт шумить. Не так.

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

Корінна причина: сильний churn на датасеті образів VM разом з агресивним створенням знімків. Система CI створювала великі артефакти, копіювала їх у диски VM, потім видаляла і повторювала. Живий датасет залишався малим, бо pipeline очищався сам. Але знімки тримали попередні версії блоків як музей, що відмовляється віддавати експонати.

zfs list -o space зробив соромно за лічені секунди: USEDBYSNAPSHOTS затулив усе інше. Виправлення не було в «видаліть більше файлів», а в «обрізанні знімків відповідно до реальності» і «переміщенні еферемних робочих навантажень у датасет з іншою політикою знімків». Вони скоригували ретеншн, перемістили еферемні навантаження, і алерт зник назавжди.

Урок залишився: інструменти файлової системи говорять те, що видно; ZFS говорить те, що виділено. Якщо слухати тільки одне, ви приймете неправильне рішення під тиском.

2) Оптимізація, що відкотилась назад: «Збільшимо частоту знімків для кращого RPO»

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

На практиці навантаження постійно переписувало великі файли. Образи VM так роблять: логи в гостях, сторінки баз даних, оновлення пакетів, тимчасові файли. Copy-on-write означав, що кожен знімок заморожував сукупність вказівників блоків, тож наступний перепис мусив виділити нові блоки. Помножте це на дванадцять знімків на годину і пул аллокатор почав бігати весь день.

Другий ефект: реплікація. Інкременти стали більшими і частішими. Мережевий і приймаючий I/O зросли. Завдання з видалення знімків стали повільнішими через їх кількість і облік блоків. Люди помітили «ZFS повільний» і почали пропонувати радикальні зміни, включно з відключенням контрольних сум в інших системах і купівлею термінових дисків. Класична спіраль неправильного діагнозу.

Вони відкатились, але не просто повернулись до годинного інтервалу. Розділили датасети: критичні дані з низьким churn отримали часті знімки; датасети з високим churn отримали менше. Також переглянули ретеншн: багато пʼятихвилинних знімків на кілька годин, менше hourly для дня, потім щоденні. Пул стабілізувався без втрати реального RPO.

Операційний урок: частота знімків не є моральною чеснотою. Це функція витрат. zfs list -o space показує рахунок.

3) Нудна, але правильна практика, що врятувала день: «Завжди резервувати запас і міряти ZFS, а не враження»

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

По-перше: вони відмовлялись тримати пули «гарячими». Алерти по ємності спрацьовували на порогах, що здавалися консервативними для команд додатків. Суперечки були передбачувані: «Ми заплатили за диски; чого б не використовувати їх?» Команда відповіла операційною реальністю: поведінка аллокатора погіршується, навантаження resilver зростає, а екстрені видалення — місце для помилок. Вони хотіли запас, не драму.

По-друге: вони будували дашборди з zfs list -o space -p, а не з du або даних від додатків. Дашборди явно розбирали USEDBYSNAPSHOTS і USEDBYREFRESERVATION, тож «таємний ріст» перетворювався на «неспівпадіння ретеншн знімків» або «повзуча refreservation», а не в гру вину.

По-третє: вони робили політику знімків явною для кожного класу датасетів і переглядали її щоквартально. Нічого особливого — просто достатньо, щоб зловити «CI-cached датасет успадкував базову політику бази даних».

Коли команда додатків випадково розгорнула шторм логів, що переписував великий диск VM, пул почав рости. Дашборди показали знімки як утримувача за кілька хвилин. Вони безпечно обрізали, відкоригували політику для цього датасету і продовжили. Ніяких all-hands, ніяких термінових покупок дисків, ніякого «ZFS haunted» фольклору. Нудно, правильно, ефективно.

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

Помилка 1: Довіряти du для пояснення алокації пулу

Симптом: du показує мале використання; пул майже повний; видалення файлів не допомагає.

Чому так відбувається: Знімки, клони, zvols, стиснення і метадані не відображаються у вигляді, який ви очікуєте при обході директорії.

Виправлення: Спочатку використовуйте облік ZFS.

cr0x@server:~$ zfs list -o space -S used -r tank

Помилка 2: Видаляти неправильний датасет через погляд на USED батька

Симптом: Ви видаляєте з mountpoint tank, нічого не змінюється або ви ламаєте щось не повʼязане.

Чому так відбувається: USED батька включає дітей через USEDBYCHILDREN.

Виправлення: Порівняйте USEDDS проти USEDCHILD перед дією.

cr0x@server:~$ zfs list -o name,usedbydataset,usedbychildren,usedbysnapshots -r tank

Помилка 3: Припускати, що «розмір» знімка дорівнює «used» знімка

Симптом: Знімки здаються маленькими окремо, але USEDBYSNAPSHOTS величезний.

Чому так відбувається: Багато малих інкрементів складаються; також довге зберігання + churn накопичує блоки.

Виправлення: Сортуйте знімки за USED і обрізайте за політикою ретеншн, а не по зовнішньому вигляду імен.

cr0x@server:~$ zfs list -t snapshot -o name,used -S used -r tank/dataset

Помилка 4: Забувати про refreservation на zvols

Симптом: Пул виглядає незрозуміло тісним; видалення даних не звільняє очікувано; датасети з VM показують високе USEDREFRESERV.

Чому так відбувається: refreservation попередньо виділяє «гарантований» простір і відображається у обліку аллокатора.

Виправлення: Проведіть аудит refreservation і вирішіть, чи дійсно потрібні гарантії або можна допустити overcommit.

cr0x@server:~$ zfs list -o name,usedbyrefreservation,refreservation -r tank/vm

Помилка 5: Плутати quota з вільним місцем пулу

Симптом: Додаток каже «немає місця», але zpool list показує достатньо; AVAIL датасету малий.

Чому так відбувається: Квоти обмежують ріст датасету незалежно від вільного в пулі.

Виправлення: Перевірте quota/refquota і регулюйте усвідомлено.

cr0x@server:~$ zfs get -o name,property,value -H quota,refquota tank/app

Помилка 6: Вважати, що «видалення знімків» завжди безпечне

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

Чому так відбувається: Клони залежать від origin snapshots; спільні блоки між знімками можуть зменшити відновлення простору.

Виправлення: Перевірте на наявність клонів через origin і сплануйте підняття клону або зміну життєвого циклу.

cr0x@server:~$ zfs list -o name,origin -r tank | grep -v '^-'

Контрольні списки / покроковий план

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

  1. Підтвердіть стан пулу та тренд по ємності.
    cr0x@server:~$ zpool list
    cr0x@server:~$ zpool status

    Інтерпретація: Переконайтеся, що ви не плутаєте проблему ємності з деградованим vdev/резильвер проблемою.

  2. Знайдіть топ датасетів за USED, а потім за простором, утримуваним знімками.
    cr0x@server:~$ zfs list -o space -S used -r tank | head -n 30
    cr0x@server:~$ zfs list -o name,usedbysnapshots,usedbydataset,usedbychildren -S usedbysnapshots -r tank | head -n 30

    Інтерпретація: Визначте, чи ріст — це живі дані, знімки, діти або резервації.

  3. Якщо домінують знімки — знайдіть політику знімків і churn.
    cr0x@server:~$ zfs list -t snapshot -o name,used -S used -r tank/offender | head
    cr0x@server:~$ zfs get -o name,property,value -H written tank/offender

    Інтерпретація: Великий written + багато знімків = передбачуваний тиск простору.

  4. Якщо refreservation домінує — інвентаризація zvols і контрактів.
    cr0x@server:~$ zfs list -o name,type,usedbyrefreservation,refreservation,volsize -r tank/offender

    Інтерпретація: Вирішіть, чи потрібні гарантії, чи можна безпечно зменшити утримуваний простір.

  5. Якщо діти домінують — заглиблюйтесь рекурсивно і уникайте видалень на невірному рівні.
    cr0x@server:~$ zfs list -o space -S used -r tank/offender

    Інтерпретація: Знайдіть реальне піддерево; не «чищайте» випадкові шляхи.

  6. Після будь-якої зміни — перевірте розподіл простору і CAP пулу знову.
    cr0x@server:~$ zfs list -o space tank/offender
    cr0x@server:~$ zpool list

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

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

  1. Підтвердіть датасет і іменування/політику знімків (не видаляйте останню робочу точку відновлення).
  2. Перевірте на наявність клонів, що залежать від цих знімків (origin відносини).
  3. Віддавайте перевагу видаленню найстаріших знімків, щоб покращити передбачуваність відновлення (якщо політика не вимагає інакше).
  4. Оцініть очікуване відновлення, використовуючи сортування знімків за USED (знаючи, що це верхня межа).

Контрольний список: перед зміною reservation/refreservation

  1. Ідентифікуйте споживача (хост VM, iSCSI target, вимога додатку).
  2. Підтвердіть, чи гарантія потрібна для коректності або це просто психологічний комфорт.
  3. Змінюйте поступово під час стабільних періодів; спостерігайте CAP пулу і поведінку навантаження.

Поширені питання (FAQ)

1) Чому df показує вдосталь місця, а ZFS каже, що пул майже повний?

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

2) У чому різниця між USED і REFERENCED?

REFERENCED — скільки простору вказує жива держава датасету. USED — вигляд для аллокатора і може включати простір, утримуваний знімками, дітей і впливи reservation залежно від контексту. Коли знімків багато, USED може значно перевищувати REFERENCED.

3) Чи дорівнює USEDBYSNAPSHOTS сумі значень USED всіх знімків?

Не завжди, бо спільне використання блоків і межі обліку можуть ускладнити наївні суми — особливо з клонованими датасетами і спільними блоками. Розглядайте snapshot USED як «інкрементний ріст за знімок», а USEDBYSNAPSHOTS як «простір, утримуваний знімками» на рівні датасету.

4) Я видалив багато знімків, але простір не повернувся одразу. Чому?

Звичайні причини: блоки все ще посилаються іншими знімками, клонами або станами датасету; асинхронне звільнення може зайняти час; або тиск спричинений reservation/refreservation. Перевірте zfs list -o space ще раз і шукайте клони через origin.

5) Чи є reservation і refreservation «реальним використанням»?

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

6) Чому датасети VM часто мають величезне використання знімків?

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

7) Як швидко знайти один найбільший «пожирач простору»?

Почніть з:

cr0x@server:~$ zfs list -o space -S used -r tank | head -n 30

Потім вирішіть, чи пожирач — це знімки, діти, датасет чи резервації, читаючи колонки розподілу.

8) Коли використовувати вивід з -p?

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

9) Чи можу я «вирішити» проблеми простору, вимкнувши знімки?

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

10) Якщо USEDBYDATASET велике, але додаток каже, що він прибирав — що робити?

Можливо, ви маєте справу з даними, не видимими в точці монтування (zvols), прихованими накладами mount або прибирання відбулося всередині гостя (VM), а хост бачить великий віртуальний диск, який не зменшився. Перевірте, що насправді містить датасет і чи це volume або filesystem.

Висновок

zfs list -o space — найкорисніший вигляд «правди про ємність» в щоденних операціях ZFS, бо відповідає на єдине питання, яке має значення під час інциденту: хто утримує блоки? Коли ви зможете відділити простір, утримуваний знімками, від живих даних і від обіцянок резервів, таємниця зникає — і ваші варіанти виправлення стають ясними, безпечними та швидкими.

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

← Попередня
Права доступу Docker при bind‑mount на Windows: найменш болюча конфігурація
Наступна →
Вибір планувальника IO для ZFS: mq-deadline чи none для HDD, SSD і NVMe

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