Квоти та резервації ZFS: пара контролю простору, яку потрібно зрозуміти

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

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

Якщо ви керуєте мультиарендними системами, CI-майстрами, фермою VM, флотом баз даних або будь-чим, де «хтось рано чи пізно заповнить пул», квоти й резервації — це різниця між тихим on-call і бойовою кімнатою о 02:00. Цей матеріал написано так, як ви насправді працюєте з ZFS: з командами, симптомами і заплутаною реальністю снапшотів, refquota та «чому немає місця, коли df каже, що є?»

1. Квота vs резервація: реальні визначення

Квота: «Ви не можете рости більше цього.»

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

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

Резервація: «Ось стільки місця моє, навіть якщо інші голодні.»

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

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

Дві короткі фрази, що збережуть ваш спокій

  • Квота — це обмеження швидкості. Ви можете їхати до нього, але вона не купує вам пальне.
  • Резервація — це талон на пальне. Вона не каже, куди їхати, але гарантує, що ви зможете кудись дістатися.

Жарт №1 (короткий і по темі): Квота — це коли фіндиректор каже «не витрачайте більше цього». Резервація — це коли фіндиректор фактично кладе гроші у ваш центр витрат — рідкісно, красиво і все одно якось заплутано.

2. Ментальна модель: стеля, підлога та хто платить

Більшість команд правильно налаштовують квоти з першого дня: «Кожному орендарю по 500G». Потім трапляється перший інцидент, бо квота не захищає пул. Вона лише захищає інші датасети від росту цього датасету. Якщо ви роздаєте квоти, які в сумі дорівнюють 200% місткості пулу (оверкоміт), ви ставитеся на поведінку. Іноді це прийнятно. Іноді так ви вивчаєте, що таке «write amplification під час компресії».

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

Думайте про три числа, а не одне

Коли ви відлагоджуєте місце, потрібно три різні поняття:

  • Used: те, що ZFS враховує як використане датасетами і снапшотами.
  • Available: те, що ZFS каже, що можна виділити (після slop-простору, резервацій тощо).
  • Referenced vs logical vs physical: скільки даних «ваші», скільки поділені снапшотами і скільки фактично на диску після компресії.

Квоти і резервації застосовуються на межі датасету

Датасети ZFS — це одиниця застосування. Квоти/резервації не діють на «папку», якщо ви не використовуєте проектні квоти (про них пізніше). Для VM zvol існують інші регулятори (volsize, refreservation) і плутанина зростає.

Що блокується, коли ви досягаєте квоти?

Записи, яким потрібні нові блоки. Перезаписи також можуть вимагати нових блоків, бо ZFS використовує copy-on-write. Це означає, що «я редагую файл на місці» все одно може виділити простір, і квоти все ще можуть вдарити.

Що стається, коли пул заповнений, але у вас є резервація?

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

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

Інженери зберігання люблять «просто». ZFS любить «правильно». Розрив між цими двома — те місце, де живуть квоти та резервації. Ось кілька контекстних пунктів, що допомагають пояснити поведінку системи:

  1. ZFS побудовано навколо copy-on-write, що означає, що перезаписи виділяють нові блоки. Облік простору має враховувати «старі» блоки, які тримають снапшоти, а не лише живу файлову систему.
  2. Ранній ZFS підкреслював цілісність від кінця до кінця (контрольні суми, самовідновлення) задовго до того, як це стало модно; застосування квот має працювати з транзакційною семантикою, а не «за найкращими зусиллями».
  3. Існують концепції «refquota» і «refreservation», бо снапшоти ускладнили наївну ідею «датасет використовує X». Referenced space і total space — різні рахунки.
  4. В ZFS є «slop space» (невеликий нездійсненний резерв на рівні пулу), щоб система працювала при майже заповненому пулі. Ось чому «чому зникає 5G?» — постійна загадка для новачків.
  5. Компресія змінює людське сприйняття використання: квота застосовується до логічного обліку простору, тоді як фізичне споживання може бути меншим. Користувачі не люблять, коли їм кажуть «ви вичерпані», коли диски не заповнені.
  6. Тонке провізування стало мейнстримом, і ZFS підтримав його датасетами й квотами — але резервації є противагою, коли потрібно гарантувати запас.
  7. Популярність VM підвищила використання zvol, і багато операційних помилок походять від того, що zvol трактують як файлову систему. volsize — це не квота; це розмір пристрою.
  8. Контейнеризація зробила мультиарендну FS-структуру нормою. Датасети ZFS стали чистою межею для квот і делегування, але тільки якщо ви розумієте нащадків і поведінку снапшотів.
  9. Проєктні квоти з’явилися, щоб вирішити «потрібні ліміти на директорії» без розростання датасетів. Вони потужні, але додають ще один шар обліку, який треба моніторити.

4. Властивості, які ви реально використовуватимете (і їхні пастки)

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

quota і reservation: застосовуються до датасету + нащадків

quota обмежує загальний простір, спожитий датасетом і всіма його дітьми. Та сама історія для reservation: вона резервує для датасету і його нащадків.

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

refquota і refreservation: застосовуються лише до самого датасету (не до нащадків, не до снапшотів)

refquota — це квота на referenced простір датасету — зазвичай означає «живі дані», без урахування снапшотів і без урахування нащадків. Це ручка «я хочу обмежити те, що цей датасет сам реферує».

refreservation — відповідна «підлога» для referenced простору.

Операційно refquota — це спосіб припинити покарання орендарів політиками зберігання снапшотів (або припинити покарання себе, якщо ви зберігаєте сім днів історії).

Чому важливо «включає/виключає снапшоти»

Простір снапшотів є «реальним» простором у пулі, але не обов’язково «належить» так, як орендарі думають. Датасет може бути на своїй квоті і все одно потребувати виділення простору через copy-on-write churn, особливо коли снапшоти прикріплюють старі блоки. Ось як ви отримуєте класичну ситуацію: «Я видалив файли, але використання не впало». Ви не видалили блоки; ви видалили посилання. Снапшоти тримають старі посилання живими.

Резервації можуть бути більші за використане (і в цьому суть)

Коли ви встановлюєте резервацію, ви передвиділяєте доступність пулу, а не записуєте нулі. Якщо ви резервуєте 200G і використовуєте лише 20G, пул все одно буде поводитися так, ніби ті 200G недоступні для інших датасетів. Це навмисно. І це часта причина «таємничо» низького вільного простору пулу.

Делегація і реальність мультиаренди

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

5. Снапшоти: третя сторона в кожній суперечці

Снапшоти — причина, через яку ZFS приносить радість — і причина, через яку розмови про місце стають дивними.

Снапшоти не «займають» простір при створенні, але можуть тримати простір назавжди

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

Як снапшоти взаємодіють з квотами

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

  • quota враховує датасет і його нащадків; простір, який утримують снапшоти, все ще може призвести до відмов у виділенні, бо датасет не може виділити нові блоки без перевищення квоти.
  • refquota фокусується на referenced просторі (живі дані). Простір снапшотів не «реферується» датасетом так само, тому це кращий варіант, коли політики снапшотів управляються централізовано.

Часте відчуття «липкості» квот спричинене churn снапшотів

На практиці відчуття липкості — це copy-on-write плюс збереження історії. Бази даних, що перезаписують великі файли, завдання компактності, образи VM, кеші збірок — це всі навантаження з «чурном простору». Вони можуть вимагати тимчасового подвоєння простору під час перезапису. Якщо ви ставите квоти занадто близько до steady-state використання, ви створюєте систему, яка працює… поки не потрібно провести обслуговування.

Жарт №2 (короткий і по темі): Снапшоти — це як фотографувати свій гардероб. Видалення шкарпеток пізніше не робить фото меншими, і ZFS не вражений вашою новою мінімалістичною філософією.

6. Три міні-історії з корпоративного життя

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

Платформна команда вела спільний ZFS-пул для CI-раннерів. Кожному проєкту виділявся свій датасет під tank/ci, і кожен датасет мав квоту. Усі почувалися відповідальними. Усі почувалися в безпеці. Пул був розрахований на типовий навантаження та «сплески» збірок, а квоти мали запобігати одному проекту від розгулу.

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

Одночасно кожні 15 хвилин робилися снапшоти для «швидкого відкату» образів раннерів. Ніхто не зіставив цю політику з артефактами CI. Чурн записів плюс часті снапшоти створили багато зафіксованих блоків. Каталоги збірок видалялися після завершення, але снапшоти зберігали чурн доти, поки не сплив термін збереження.

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

Кінцеве виправлення було нудним і правильним: встановити політику на рівні пулу (моніторити вільний простір пулу), перемістити артефакти CI в датасет з коротким зберіганням снапшотів (або без снапшотів) і залишити квоти як справедливість між орендарями — не як захист пулу. Також ввели невелику резервацію для системних датасетів (логи, кеші пакетів), щоб хости могли функціонувати під час аварій.

Міні-історія 2: Оптимізація, що повернулася бумерангом (резервації всюди «для надійності»)

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

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

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

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

Постмортем закінчився правилом: резервації — для виживання інфраструктури (системні датасети ОС, критичний DB WAL/запас) і для жорстких SLA. Усе інше — квоти й моніторинг. Команда також навчилася документувати резервації як «борг по місткості», який потрібно оплачувати реальними дисками.

Міні-історія 3: Нудна, але правильна практика, що врятувала ситуацію (refquota + кордони снапшотів)

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

Замість того, щоб використовувати quota скрізь, вони застосували патерн: датасети орендарів отримали refquota, щоб забезпечити ліміти живих даних. Снапшоти управлялися централізовано платформною командою з політиками зберігання, підібраними під навантаження (коротко для scratch, довше для курованих результатів).

Вони створили окреме піддерево датасетів для scratch/проміжних даних з агресивним обрізанням снапшотів і нижчими налаштуваннями recordsize. Найважливіше, вони вирівняли кордони снапшотів з власністю: орендарі не платили (через квоту) за платформну історію безпеки, а scratch-датасетам заборонили зберігати снапшоти довше короткого вікна.

Через місяці погана деплой викликала хвилю повторних завдань, які агресивно перезаписали проміжні файли. Чурн був реальний. Але система залишилася працездатною, бо: (1) scratch-датасети мали політику збереження, яка не фіксувала чурн довго, і (2) невелика резервація існувала для критичних системних датасетів, щоб логи й основні сервіси могли писати, поки команда стабілізувала завдання.

Жодної героїки. Жодної «магії зберігання». Просто чисті межі, консервативне застосування і смирення перед тим, що хтось обов’язково зробить щось дурне з диском.

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

Ось команди, до яких я дійсно тягнуся, коли пул тісний, датасет досяг обмежень або хтось каже «ZFS брешe». Команди показані з типовим виводом. Підлаштуйте імена пулів/датасетів під ваше середовище.

Завдання 1: Показати ємність пулу і стан

cr0x@server:~$ zpool list
NAME   SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank  7.25T  5.61T  1.64T        -         -    22%    77%  1.00x  ONLINE  -

Інтерпретація: Пул заповнений на 77%. Саме по собі це не аварія, але якщо це підніметься в високі 80/90%, виділення стають тендітними (і продуктивність може похитнутися). Цей вивід не показує резервації прямо.

Завдання 2: Перевірити «available» пулу з урахуванням slop

cr0x@server:~$ zfs get -H -o name,property,value available tank
tank	available	1.52T

Інтерпретація: ZFS може показувати менше, ніж FREE, через slop-простір та інший облік. Якщо zpool list показує free, але zfs get available низький, ви підбираєтесь до зони, де ENOSPC з’являється «раніше».

Завдання 3: Показати квоти і резервації у дереві датасетів

cr0x@server:~$ zfs get -r -o name,property,value -s local quota,reservation,refquota,refreservation tank/tenants
NAME                  PROPERTY        VALUE
tank/tenants          quota           -
tank/tenants          reservation     -
tank/tenants          refquota        -
tank/tenants          refreservation  -
tank/tenants/acme     quota           2T
tank/tenants/acme     reservation     -
tank/tenants/acme     refquota        1.5T
tank/tenants/acme     refreservation  200G
tank/tenants/zephyr   quota           1T
tank/tenants/zephyr   reservation     -
tank/tenants/zephyr   refquota        -
tank/tenants/zephyr   refreservation  -

Інтерпретація: Це показує, у кого є ліміти й гарантії. Зверніть увагу на мікс: quota обмежує усе піддерево; refquota обмежує живі дані лише того датасету; refreservation гарантує живий запас.

Завдання 4: Знайти найбільші датасети швидко

cr0x@server:~$ zfs list -o name,used,avail,refer,mountpoint -S used | head -n 12
NAME                 USED  AVAIL  REFER  MOUNTPOINT
tank                 5.61T 1.52T   128K  /tank
tank/tenants         4.90T 1.52T    96K  /tank/tenants
tank/tenants/acme    1.92T  800G  1.44T  /tank/tenants/acme
tank/tenants/zephyr  1.31T 1.52T  1.05T  /tank/tenants/zephyr
tank/vm              420G  1.52T    96K  /tank/vm
tank/logs            180G  1.52T   160G  /tank/logs

Інтерпретація: USED включає снапшоти і нащадків. REFER — це «живі дані», які реферує цей датасет. Коли USED набагато більше за REFER, зазвичай причиною є снапшоти/діти.

Завдання 5: Виявити датасети з великою кількістю снапшотів (різниця USED vs REFER)

cr0x@server:~$ zfs list -t filesystem -o name,used,refer -S used | head -n 10
NAME                 USED  REFER
tank/tenants/acme    1.92T 1.44T
tank/tenants/zephyr  1.31T 1.05T
tank/logs            180G  160G
tank/ci              140G   18G
tank/home            110G   45G

Інтерпретація: tank/ci — тривожний знак: 140G used, лише 18G referenced. Зазвичай це снапшоти, що тримають чурн, або багато дочірніх датасетів.

Завдання 6: Переглянути снапшоти та їхній простір

cr0x@server:~$ zfs list -t snapshot -o name,used,refer,creation -S used | head -n 8
NAME                                   USED  REFER  CREATION
tank/ci@autosnap_2025-12-24_0100        22.4G    0B  Wed Dec 24 01:00 2025
tank/ci@autosnap_2025-12-24_0045        18.1G    0B  Wed Dec 24 00:45 2025
tank/tenants/acme@daily_2025-12-23      12.7G    0B  Tue Dec 23 02:00 2025
tank/home@hourly_2025-12-24_0100         6.2G    0B  Wed Dec 24 01:00 2025

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

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

cr0x@server:~$ zfs get -o property,value -p used,usedbysnapshots,usedbydataset,usedbychildren,usedbyrefreservation tank/ci
PROPERTY             VALUE
used                 150323855360
usedbysnapshots      126406688768
usedbydataset        19327352832
usedbychildren       0
usedbyrefreservation 0

Інтерпретація: Снапшоти споживають близько ~126G унікального простору. Тут і зник ваш пул.

Завдання 8: Встановити квоту (обмеження) на датасеті

cr0x@server:~$ sudo zfs set quota=500G tank/tenants/zephyr
cr0x@server:~$ zfs get -H -o name,property,value quota tank/tenants/zephyr
tank/tenants/zephyr	quota	500G

Інтерпретація: zephyr (і будь-які діти під ним) не можуть споживати більше ніж 500G загалом. Якщо він вже перебуває вище 500G, операції запису зазнаватимуть невдач, поки використання не зменшиться.

Завдання 9: Встановити резервацію (гарантію) для критичного запасу

cr0x@server:~$ sudo zfs set reservation=50G tank/logs
cr0x@server:~$ zfs get -H -o name,property,value reservation tank/logs
tank/logs	reservation	50G

Інтерпретація: 50G вилучається з «available» для інших і резервується для tank/logs (і його нащадків). Це допомагає логам продовжувати писати під тиском пулу.

Завдання 10: Використати refquota, щоб обмежити лише живі дані (безпечні для снапшотів ліміти орендарів)

cr0x@server:~$ sudo zfs set refquota=300G tank/tenants/acme
cr0x@server:~$ zfs get -H -o name,property,value refquota tank/tenants/acme
tank/tenants/acme	refquota	300G

Інтерпретація: Це обмежує «acme» живими реферованими даними. Якщо платформа збільшує USED снапшотами, refquota менш імовірно покарає орендаря за політику збереження історії.

Завдання 11: Використати refreservation, щоб гарантувати живий запас для записів

cr0x@server:~$ sudo zfs set refreservation=20G tank/tenants/acme
cr0x@server:~$ zfs get -H -o name,property,value refreservation tank/tenants/acme
tank/tenants/acme	refreservation	20G

Інтерпретація: Гарантує 20G referenced простору для власних записів цього датасету. Корисно для WAL баз даних або scratch, які не повинні зупинятися під час тиску пулу.

Завдання 12: Підтвердити, чому датасет показує низьке «avail» (натиск квот/резервацій)

cr0x@server:~$ zfs get -o name,quota,refquota,reservation,refreservation,used,avail,refer tank/tenants/acme
NAME               QUOTA  REFQUOTA  RESERV  REFRESERV  USED  AVAIL  REFER
tank/tenants/acme     2T     300G       -      20G   1.92T  0B   1.44T

Інтерпретація: AVAIL 0B — ключ. Це означає, що з перспективи ZFS цей датасет не може виділяти більше простору, ймовірно через застосований refquota, що нижчий за поточний REFER. Іншими словами: ліміти неконсистентні з реальністю; ви просто застебнули пасок безпеки після краху.

Завдання 13: Зменшити тиск снапшотів, видаливши старі снапшоти (обережно)

cr0x@server:~$ zfs list -t snapshot -o name,used -S used | grep '^tank/ci@' | head
tank/ci@autosnap_2025-12-24_0100   22.4G
tank/ci@autosnap_2025-12-24_0045   18.1G
tank/ci@autosnap_2025-12-24_0030   15.9G
cr0x@server:~$ sudo zfs destroy tank/ci@autosnap_2025-12-24_0030

Інтерпретація: Знищення снапшоту звільняє простір лише якщо блоки унікальні для нього. Завжди підтверджуйте політики й залежності реплікації перед видаленням снапшотів у продакшені.

Завдання 14: Виявити прихованих «споживачів» простору за допомогою «written» (недавній чурн)

cr0x@server:~$ zfs get -H -o name,property,value written@autosnap_2025-12-24_0045 tank/ci
tank/ci	written@autosnap_2025-12-24_0045	41234597888

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

Завдання 15: Порівняти облік ZFS з поглядом файлової системи

cr0x@server:~$ df -h /tank/ci
Filesystem      Size  Used Avail Use% Mounted on
tank/ci         1.6T   19G  0B  100% /tank/ci

Інтерпретація: Монтований розділ показує 0B доступних, бо ZFS застосовує доступність датасету після квот/резервацій. Якщо користувачі кажуть «df каже, що повно», повірте їм, а потім перевірте властивості ZFS, щоб зрозуміти чому.

Завдання 16: Знайти резервації, що «крадуть» доступність пулу

cr0x@server:~$ zfs get -r -H -o name,property,value reservation,refreservation tank | egrep -v '\t-\s*$' | head -n 20
tank/logs	reservation	50G
tank/system	reservation	30G
tank/tenants/acme	refreservation	20G

Інтерпретація: Будь-яке значення, відмінне від -, зменшує алокований простір пулу. Якщо «available» здається низьким, цей список часто дає пояснення.

8. Плейбук швидкої діагностики

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

Крок 1: Це пул, датасет чи ліміт?

cr0x@server:~$ zpool list tank
NAME   SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank  7.25T  6.98T   270G        -         -    29%    96%  1.00x  ONLINE  -
cr0x@server:~$ zfs get -H -o name,property,value available tank
tank	available	120G

Інтерпретація: Якщо CAP пулу >90% і tank available низький, маєте подію з ємністю пулу. Якщо пул виглядає нормально, але датасет повний, зазвичай це квоти, резервації або фіксація снапшотами.

Крок 2: Визначити, який датасет обмежений

cr0x@server:~$ zfs list -o name,used,avail,refer -S used | head -n 15
NAME                 USED  AVAIL  REFER
tank                 6.98T  120G   128K
tank/tenants         5.80T  120G    96K
tank/tenants/acme    2.40T    0B  1.90T
tank/tenants/zephyr  1.70T  120G  1.65T
tank/ci              650G     0B   40G

Інтерпретація: Датасети з AVAIL 0B — це ті, де застосунки вперше зазнають невдач.

Крок 3: Перевірити, чи це квоти/резервації або снапшоти

cr0x@server:~$ zfs get -o name,quota,refquota,reservation,refreservation,used,usedbysnapshots,refer,avail tank/ci
NAME     QUOTA  REFQUOTA  RESERV  REFRESERV  USED  USEDBYSNAPSHOTS  REFER  AVAIL
tank/ci  200G   -         -       -          650G  590G             40G    0B

Інтерпретація: Тут квота 200G, але датасет використовує 650G (ймовірно через нащадків або снапшоти; також можливо, що квоту застосували пізніше або не на тому рівні). USEDBYSNAPSHOTS величезний, тож снапшоти — негайний важіль.

Крок 4: Вирішити тимчасовий правильний засіб

  • Екстрений випадок — повний пул: видаліть найбезпечніші до видалення снапшоти першими (найбільші USED) або скоротіть політику збереження. Уникайте «rm -rf», якщо ви не розумієте, що снапшоти все одно тримають простір.
  • Орендар досягає квоти: вирішіть, чи піднімати квоту або зменшити використання; перевірте, чи політика снапшотів не спричиняє «невидимий» ріст.
  • Все голодує, але пул не повний: аудитуйте reservation/refreservation і скасуйте передзайм гарантованого простору.

9. Часті помилки, симптоми та виправлення

Помилка 1: Ставити квоту як «захист пулу»

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

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

Виправлення: Моніторте вільний простір пулу і встановлюйте оперативні запобіжники (оповіщення на 80/85/90%). Використовуйте резервації лише для критичних датасетів. Тримайте квоти для справедливості, а не для безпеки.

Помилка 2: Встановлювати резервації «про всяк випадок» скрізь

Симптом: Пул виглядає як би має вільний простір, але багато датасетів показують низьке AVAIL або записи відмовляються непередбачувано. Команди бачать конфліктні числа між інструментами.

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

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

Помилка 3: Використовувати quota, коли мали на увазі refquota (снапшоти боляче кусають)

Симптом: Орендарі скаржаться, що використання не падає після видалень; вони досягають квоти, незважаючи на «очищення».

Чому відбувається: Снапшоти утримують старі блоки. quota не розділяє живі дані й історію снапшотів так, як орендарі очікують.

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

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

Симптом: Квота «нічого не робить» або має несподіваний охоп. Дочірній датасет заповнює батьківську квоту несподівано.

Чому відбувається: quota застосовується до датасету + нащадків. Неправильний батьківський рівень змінює охоплення.

Виправлення: Візуалізуйте дерево датасетів. Застосовуйте квоти до кореня орендаря. Використовуйте refquota, якщо ви хочете обмежити лише рефероване використання одного датасету.

Помилка 5: Плутати розмір zvol з квотами

Симптом: Диск VM «закінчується», хоча квота датасету виглядає щедрою, або пул раптово заповнюється через припущення тонкої провізії.

Чому відбувається: volsize zvol визначає розмір пристрою; простір алокується під час записів, а снапшоти теж можуть прикріплювати старі блоки. Поведінка квот/резервацій може відрізнятися залежно від способу провізії.

Виправлення: Для VM на zvol відстежуйте використання zvol і політику снапшотів уважно. Розгляньте refreservation для критичних zvol, якщо оверкоміт ризикований.

Помилка 6: Встановлювати квоти занадто щільно для copy-on-write навантажень

Симптом: Компакція бази даних, оновлення образа VM або кроки збірки зазнають невдач, хоча steady-state використання нижче квоти.

Чому відбувається: Перезаписи потребують тимчасового додаткового алокації; снапшоти це підсилюють. Потрібен запас для транзакційного перезапису.

Виправлення: Плануйте простір для сплесків. Використовуйте refreservation або просто встановлюйте квоти з запасом. Зменшіть частоту снапшотів на чурн-важких датасетах.

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

Чекліст A: Проєктування зберігання для орендарів (план «не турбуйте мене»)

  1. Створіть датасет на орендаря (або на середовище) як межу управління.
  2. Розв’яжіть: снапшоти — у власності орендаря чи платформи. Не розділяйте відповідальність випадково.
  3. Якщо снапшоти — у платформи, віддавайте перевагу refquota для обмежень орендарів.
  4. Встановлюйте quota лише тоді, коли ви явно хочете включити дітей (поширено для «кореня орендаря»).
  5. Додавайте невелику reservation або refreservation лише для навантажень, які повинні продовжувати писати під тиском пулу.
  6. Ставте оповіщення за ємністю пулу, а не лише за використанням датасетів. Квоти не врятують вас від сумарного росту.
  7. Документуйте: які датасети мають право на резервації і чому.

Чекліст B: Реагування на «нема місця» у продакшені

  1. Перевірте ємність пулу: zpool list.
  2. Перевірте алокований простір пулу: zfs get available tank.
  3. Знайдіть датасети з AVAIL 0B: zfs list -o name,used,avail,refer -S used.
  4. Для ураженого датасету перегляньте ліміти та використання снапшотів: zfs get usedbysnapshots,quota,refquota,reservation,refreservation.
  5. Якщо снапшоти винні, видаліть/обріжте снапшоти згідно політики; не чекайте, що простір звільниться просто від rm.
  6. Якщо резервації голодують пул, зменшіть/видаліть некритичні резервації.
  7. Лише потім розгляньте підняття квот (і ставте це як планування місткості, а не як тимчасову латку).

Чекліст C: Квартальна гігієна (нудна практика, що працює)

  1. Інвентаризуйте всі нестандартні quota/refquota/reservation/refreservation.
  2. Підтвердіть, що резервації відповідають критичності та прогнозам зростання.
  3. Перегляньте політики снапшотів на чурн-важких датасетах (CI, scratch, тимчасові БД).
  4. Знайдіть датасети, де USED значно більше за REFER; розслідуйте причину.
  5. Перевірте моніторинг: оповіщення за ємністю пулу, зростання снапшотів і «датасети з AVAIL близько нуля».

11. FAQ

Q1: Якщо я встановлю квоту, чи ZFS «алокує» той простір?

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

Q2: Якщо я встановлю резервацію, чи ZFS запише нулі на диск?

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

Q3: Мені використовувати quota чи refquota для орендарів?

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

Q4: Чому видалення файлів не звільнило місце?

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

Q5: Чому df не сходиться з zpool list?

df показує доступність на рівні датасету після квот/резервацій. zpool list показує сирі алокації пулу. Обидва праві — просто відповідають на різні питання. Коли вони розходяться, дивіться на квоти, резервації і slop-простір.

Q6: Чи можуть резервації спричинити outage?

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

Q7: Чи враховують квоти компресію?

Квоти ґрунтуються на логічному обліку ZFS, а не на кількості секторів диску після компресії, як користувачі очікують. Компресія може зробити фізичне використання меншим, але квоти все одно можна досягнути за логічним referenced простором. Це добре для передбачуваності, дратує при поясненнях.

Q8: Який найпростіший безпечний патерн для критичних системних датасетів?

Дайте системним датасетам (логи, основні сервіси) помірну резервацію, щоб ОС могла писати під час події тиску пулу. Тримайте резервацію малою, регулярно переглядайте і обґрунтовуйте — достатньо для виживання інциденту, але не стільки, щоб перетворитися на мовчазний оверкоміт.

Q9: Якщо у мене є резервації, чи можу я все ще оверкомітити пул квотами?

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

Q10: Як швидко визначити, чи снапшоти — основна причина?

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

12. Висновок

Квота і резервація — це не суперечливі фічі. Це пара: quota перешкоджає датасету займати занадто багато, а reservation перешкоджає виштовхуванню датасету. У реальних продакшн-системах зазвичай потрібні обидва — просто не всюди і не без розуміння снапшотів.

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

← Попередня
Hyper-Threading розкрито: магічні потоки чи хитрощі планувальника?
Наступна →
NPU для AI на CPU: що це і навіщо вони існують

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