Тонке виділення — це бюджетна зустріч у маскуванні під функцію зберігання. Усе виглядає чудово, поки реальність не подасть рахунок.
З розрідженими томами ZFS (thin zvols) ви навмисно можете видати більше «диска», ніж фактично маєте. Само по собі це не кримінал.
Погано — робити це легковажно й дивуватися, коли пул досягає 100% і радіус ураження нагадує вправу з довіри на рівні всього дата-центру.
Це практичний посібник із пастки перевиділення: що насправді закінчується першим, що ламається, як виглядають сигнали,
і що саме перевіряти, коли пахне димом. Ви отримаєте конкретні команди, що означають їхні виходи, і які рішення з цього випливають.
Що насправді означають «розріджені томи» в ZFS
В ZFS zvol — це блочний пристрій, підкріплений dataset. Його використовують для ВМ, iSCSI LUN, баз даних, які потребують «сирих» блочних пристроїв,
або будь-яких систем, що мислять блоками, а не файлами. «Розріджений» zvol — це тонке виділення: його volsize (розмір, який ви показуєте клієнту) може бути більшим, ніж
простір, який наразі виділено в пулі.
Головне: розріджений не означає вільний. Це означає «виділяється при записі». Пул залишається пулом. Якщо споживачі запишуть достатньо,
ZFS мусить виділити реальні блоки. Коли не може — повертає помилки. Ці помилки доходять до файлової системи гостя, бази даних або гіпервізора,
зазвичай в найменш чемний спосіб.
Чому людям подобаються розріджені zvol? Бо альтернатива — песимізм: попереднє виділення повного обсягу для кожної ВМ або LUN означає купівлю дисків зарані,
а потім роки святкування пустого простору, за який ви заплатили. Тонке виділення — прагматичне. Проблема в тому, що це також обіцянка, яку можна порушити.
Два числа, які потрібно розрізняти в голові
- Логічний розмір: що ви сказали клієнту, що він може використовувати (
volsize). - Фізичне виділення: що ZFS фактично виділив у пулі для цього zvol (плюс метадані, парність, копії тощо).
Перевиділення відбувається, коли сума логічних розмірів перевищує фізичну ємність. Саме по собі це не одразу катастрофа.
Воно стає проблемою, коли шаблони записів (або календар) змушують виконати логічну обіцянку.
Пастка перевиділення: чому це ламається так раптово
Тонке виділення ламається ось як: усе здається в порядку, а потім раптом ні. Це тому, що споживання сховища буває грудкуватим.
Бекапи, тижневі пакетні завдання, сплески логів, ланцюги snapshot-ів ВМ, компактінг баз даних, реіндексація та «ми щось мігрували» — все це швидко виділяє реальні блоки.
Пули, що місяцями сидять на 70%, можуть за день підскочити до 95%, а за годину — до 100%.
ZFS — не «м’яка» файлова система щодо виснаження простору. Майже заповнені пули викликають фрагментацію, проблеми аллокатора й тиск на метадані.
Коли пул справді закінчується, ви отримуєте ENOSPC і потім каскадні відмови: диски ВМ стають лише для читання, бази даних панікують або гіпервізор не може записати
логи, потрібні для відновлення. Тонке виділення — каталізатор; справжній вогонь — операційна самовпевненість.
Є також тонкість: навіть якщо пул показує «трохи вільного простору», ви все одно можете не вміти виконати алокацію через slop space,
фрагментацію, ефекти recordsize/volblocksize і метадані, які потрібно записати, щоб зберегти консистентність.
Вільний простір — це не одне число. Це «вільний простір, який можна виділити в потрібній формі і класі».
Жарт №1: Тонке виділення як замовлення штанів «коли-небудь я влізу в них». День настав о 2:00, а вашим ременем став pager.
Що ламається першим у реальному житті
- Файлові системи гостей бачать помилки вводу/виводу. Журнальні файлові системи рятують до певного моменту.
- Бази даних отримують часткові записи або не можуть розширити файли, потім заходять у відновлення в найневдалий момент.
- Гіпервізори можуть призупиняти ВМ, маркувати диски як ушкоджені або провалювати snapshot-и.
- Реплікація може застрягти, бо не може записати буфи прийому або нові snapshot-и.
- Сам ZFS може мати труднощі з поверненням простору, якщо потрібно видалити snapshot-и, але не можна надійно записати оновлення метаданих.
Пул, що перевищує приблизно ~80–85%, не є моральною помилкою. Це сигнал. Ви можете працювати вище, якщо знаєте навантаження і дисципліновані.
Але з тонким виділенням дисципліна означає моніторинг і запас, а не оптимізм і відчуття.
Цікаві факти і контекст (те, що пояснює дивність)
- ZFS ввів поняття pooled storage як ідею першого класу, тому «файлова система переповнена» стала «пул переповнений». Це зміщує домени відмов із одного монту до всього.
- Тонке виділення стало популярним у корпоративних SAN задовго до широкого застосування zvol у ZFS; ZFS успадкував і переваги, і гострі кути.
- Облік простору в ZFS навмисно консервативний у кількох місцях (slop space, резерви метаданих) щоб запобігти катастрофічним дедлокам.
- Copy-on-write означає, що перезаписи спочатку алокують нові блоки, а потім звільняють старі. Майже заповнені пули карають навантаження з «оновленнями на місці».
- Snapshot-и не «витрачають простір» при створенні, але вони фіксують старі блоки. Видалення й перезаписи стають новими алокаціями замість повторного використання.
- Стиснення змінює арифметику перевиділення, бо logicalused може бути набагато більшим за фізично використаний — доки дані залишаються стискуваними (привіт, зашифровані бекапи).
- Надбавка RAIDZ через парність залежить від навантаження: малі випадкові записи можуть підсилити алокацію через вирівнювання і padding (залежить від реалізації і ashift).
- Спеціальні класи алокації (special vdevs) можуть перемістити метадані/малі блоки з шпиндельних дисків, але вони створюють ще один поріг ємності, якщо недоплановані.
- Підтримка Discard/TRIM дозрівала довше в екосистемі віртуалізації; гості, що не віддають discard, означають, що ZFS не знає, що блоки вивільнені.
Механіка, яка має значення: volsize, referenced, logicalused та блоки, яких не уникнути
Розріджені zvol: властивості, що визначають вашу долю
ZFS дає кілька важелів. Більшість людей тягнуть лише один (створити розріджений) і ігнорують решту. Ось як ви опиняєтесь із «таємничо» повним пулом.
volsize: видимий розмір блочного пристрою. Це обіцянка.refreservation: гарантований простір для dataset (zvol). Це важіль «ми не перевиділимо цю частину».reservation: схоже для файлових систем; для zvol зазвичай використовуютьrefreservation.volblocksize: градація алокації для zvol; впливає на продуктивність і ефективність використання простору.compression: може значно збільшити запас — поки ваші дані стискуються.sync: як ZFS обробляє синхронні записи; його зміна може вплинути на продуктивність і поведінку при відмовах.
Терміни обліку простору, які потрібно вміти швидко читати
Для zvol USED та інші в zfs list легко неправильно витлумачити. Додайте ці колонки — і світ стає яснішим:
used: фактичний простір, спожитий у пулі (включаючи метадані та копії залежно від погляду).referenced: простір, доступний цьому dataset на його голові (без урахування snapshot-ів).logicalused: незжаті логічні байти, на які посилаються (корисно для реалістичної перевірки compressratio).logicalreferenced: логічний referenced на голівці dataset.usedbysnapshots: простір, який фіксують snapshot-и; причина «чому видалення не звільняє простір».
Частина, яку ніхто не бюджетує: метадані, фрагментація та «простір, який не можна витратити»
ZFS потрібно деяке місце для дихання. Коли ви підходите до межі заповнення, у аллокатора менше варіантів, metaslab-и фрагментуються,
і записи сповільнюються. Це сповільнення саме по собі може викликати додаткові записи: тайм-аути, повтори, зростання логів, файли відновлення.
Це петля зворотного зв’язку з чорним гумором, яким ви не поділитесь.
Одна корисна ідея про надійність походить із інженерної культури, а не з деталей ZFS:
Надія — не стратегія.
(парафраз ідеї, часто приписуваної тренінгам з операцій та надійності)
Якщо ви запускаєте розріджені zvol без резервувань, ви керуєте системою, де модель ємності — це буквально надія.
Можна робити краще.
Сигнали моніторингу, що реально прогнозують відмову
Моніторинг тонкого виділення — це не «аліерт на 90% пулу». Це один алерт, і він запізнюється.
Потрібен невеликий набір сигналів, що пояснюють і ємність, і швидкість зміни, плюс «речі, що роблять повернення простору неможливим».
Сигнали для відстеження (і чому)
- Відсоток алокації пулу (
zpool list): великий очевидний показник. Відстежуйте тренд, а не тільки поточне значення. - Вільний простір по класах (
zpool list -vна деяких платформах; такожzpool status): special vdev і log vdev можуть мати власні обриви. - Простір у snapshot-ах (
usedbysnapshots): пул може бути «повним» через приховану споживаність збережень. - Коефіцієнт перевиділення: сума
volsizezvol поділена на фізичний розмір пулу (і/або на «безпечний придатний» простір). - Накопичений бруд / тиск txg (
zfs-statsабо платформи-еквіваленти): сплески часто корелюють із великими хвилями записів. - Індикатори підсилення записів: високі IOPS при помірному пропускному каналі, зростання латентності і фрагментація аллокатора (histogram metaslab).
- Дрейф коефіцієнта стиснення: коли нові навантаження несжаті, крива споживання пула стає крутішою.
- Ефективність discard: чи видають гості discard і чи призводить це до звільнення простору в ZFS з часом.
Пороги алертів, яким можна довіряти (переважно)
Використовуйте поетапні алерти, а не один великий обрив:
- 75%: «увага». Перевірте тренд росту і політику збереження snapshot-ів. Почніть планування.
- 85%: «дія». Заморозьте неважливі snapshot-штормі, перевірте місце для реплікації, переконайтеся, що видалення дійсно повертає простір.
- 90%: «зміна режиму». Перестаньте створювати нові тонкі томи. Перемістіть навантаження. Додайте vdev або зменшіть ретеншн. Трактуйте як попередження інциденту.
- 95%: «інцидент». Тепер ви платите податок фрагментації і ризик відмови алокації. Виконуйте runbook, а не дебати.
Ці пороги залежать від навантаження і розкладки vdev. RAIDZ плюс випадкові записи потребує більше запасу, ніж дзеркала з переважно послідовними записами.
Але якщо ви тонко виділяєте і не знаєте форму навантаження, оберіть консервативні пороги і насолоджуйтеся сном.
Практичні завдання: команди, значення виводу, рішення
Цей розділ навмисне операційний. Мета — не милуватися ZFS. Мета — знати, що робити о 3:00 ранку.
Кожне завдання містить виконувану команду, що означає її вивід, і яке рішення приймати.
Завдання 1: Швидко перевірити ємність і стан пулу
cr0x@server:~$ zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 21.8T 18.9T 2.90T - - 41% 86% 1.00x ONLINE -
Що це означає: CAP 86% у зоні «дій». FRAG 41% вказує на наближення проблем з аллокатором.
Рішення: Припиніть непотрібні записи (snapshot-шторм, міграції). Почніть перевірку snapshot/ретеншн і планування ємності прямо зараз.
Завдання 2: Підтвердити, що пристрої не відмовляють, поки ви ганяєтеся за «примарами простору»
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
status: One or more devices has experienced an unrecoverable error. An
attempt was made to correct the error. Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
using 'zpool clear' or replace the device with 'zpool replace'.
scan: scrub repaired 0B in 09:12:44 with 0 errors on Sun Dec 22 09:12:55 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
ata-WDC_WD140EDGZ-... ONLINE 0 0 1
ata-WDC_WD140EDGZ-... ONLINE 0 0 0
ata-WDC_WD140EDGZ-... ONLINE 0 0 0
ata-WDC_WD140EDGZ-... ONLINE 0 0 0
errors: Permanent errors have been detected in the following files:
tank/vmstore/zvol-104-disk-0
Що це означає: Є помилка контрольної суми, пов’язана з конкретним zvol. Це не проблема ємності, але може маскуватися під неї.
Рішення: Тріаж цілісності даних окремо: перевірте диск гостя, результати scrub, розгляньте заміну диска і відновлення даних ВМ за потреби.
Завдання 3: Перелік zvol і виявлення картини перевиділення
cr0x@server:~$ zfs list -t volume -o name,volsize,used,referenced,logicalused,refreservation -r tank/vmstore
NAME VOLSIZE USED REFER LUSED REFRESERV
tank/vmstore/vm-101-disk-0 500G 412G 401G 603G none
tank/vmstore/vm-102-disk-0 2T 1.31T 1.28T 1.28T none
tank/vmstore/vm-103-disk-0 1T 74G 72G 92G none
tank/vmstore/vm-104-disk-0 4T 3.61T 3.55T 3.55T none
Що це означає: Це розріджені (немає refreservation). Логічні обіцянки великі. Є стиснення (vm-101 показує logical > physical).
Рішення: Якщо це продакшен, оберіть: встановити refreservation для критичних zvol або забезпечити жорсткий запас пулу з алертами та управлінням ємністю.
Завдання 4: Порахувати «обіцяний капітал» (сума volsize)
cr0x@server:~$ zfs list -H -p -t volume -o volsize -r tank/vmstore | awk '{s+=$1} END{printf("total_volsize_bytes=%d\n",s)}'
total_volsize_bytes=8246337208320
Що це означає: Ви пообіцяли приблизно ~8.2 TB гостям у цьому піддереві. Саме по собі це число не зло; воно потребує контексту.
Рішення: Порівняйте з придатним простором пулу (після парності, slop space політики і росту). Визначте максимальний коефіцієнт перевиділення і застосуйте його.
Завдання 5: Подивитися тиск snapshot-ів для дерева dataset
cr0x@server:~$ zfs list -o name,used,usedbysnapshots,usedbydataset,usedbychildren -r tank/vmstore | head -n 8
NAME USED USEDSNAP USEDDS USEDCH
tank/vmstore 6.12T 2.04T 4.01T 77.6G
tank/vmstore/vm-101 622G 211G 401G 9.6G
tank/vmstore/vm-102 1.53T 243G 1.28T 12.4G
tank/vmstore/vm-103 119G 42.1G 72G 4.9G
tank/vmstore/vm-104 3.85T 1.52T 3.55T 18.6G
Що це означає: 2 TB у snapshot-ах — це не «безкоштовно». Це виділений і зафіксований простір. Видалення в гостях цього не звільнить.
Рішення: Якщо є дефіцит ємності, відрегулюйте ретеншн. Видаліть snapshot-и стратегічно (найстаріші, з найбільшими дельтами) і спочатку підтвердіть залежності реплікації.
Завдання 6: Швидко знайти головних споживачів простору
cr0x@server:~$ zfs list -o name,used,usedbysnapshots -s used -r tank/vmstore | tail -n 6
tank/vmstore/vm-103 119G 42.1G
tank/vmstore/vm-101 622G 211G
tank/vmstore/vm-102 1.53T 243G
tank/vmstore/vm-104 3.85T 1.52T
Що це означає: vm-104 несе величезну «баластну» вагу snapshot-ів.
Рішення: Для швидкого звільнення простору навантаження з великою кількістю snapshot-ів — найвідновлюваніші, після валідації бізнес/бекап-вимог.
Завдання 7: Перевірити реальність стиснення (і виявити момент «зашифрований бекап все зруйнував»)
cr0x@server:~$ zfs get -H -o name,property,value compression,compressratio -r tank/vmstore | head
tank/vmstore compression zstd
tank/vmstore compressratio 1.24x
tank/vmstore/vm-101 compression zstd
tank/vmstore/vm-101 compressratio 1.46x
tank/vmstore/vm-102 compression zstd
tank/vmstore/vm-102 compressratio 1.02x
Що це означає: vm-102 фактично несжимається. Якщо він росте, буде споживати сирий простір майже 1:1.
Рішення: Не враховуйте економію від стиснення для навантажень, які шифрують дані всередині гостя або зберігають вже стиснуті бінарні дані. Плануйте ємність як 1.0x.
Завдання 8: Перевірити reservation/refreservation (так звані «хто може потопити корабель»)
cr0x@server:~$ zfs get -o name,property,value -r tank/vmstore | egrep 'refreservation|reservation' | head -n 12
tank/vmstore reservation none
tank/vmstore refreservation none
tank/vmstore/vm-101 reservation none
tank/vmstore/vm-101 refreservation none
tank/vmstore/vm-102 reservation none
tank/vmstore/vm-102 refreservation none
Що це означає: Ніхто не має гарантованого простору. Це означає, що останній записувач перемагає, поки пул не програє.
Рішення: Для томів «мають писати обов’язково» (бази даних, control plane, identity) встановіть refreservation, щоб вони могли продовжувати запис навіть під тиском.
Завдання 9: Встановити refreservation для критичного zvol (і зрозуміти наслідки)
cr0x@server:~$ sudo zfs set refreservation=600G tank/vmstore/vm-101-disk-0
cr0x@server:~$ zfs get -H -o name,property,value refreservation tank/vmstore/vm-101-disk-0
tank/vmstore/vm-101-disk-0 refreservation 644245094400
Що це означає: ZFS тепер резервує ~600G для цього тому. Вільний простір пулу зменшується відповідно.
Рішення: Ось як ви запобігаєте тому, щоб критичні навантаження були задушені чийсь runaway job. Використовуйте свідомо; це зменшує гнучкість.
Завдання 10: Перевірити ashift і розкладку vdev (арифметика ємності залежить від цього)
cr0x@server:~$ zdb -C tank | egrep 'ashift|raidz|mirror' | head -n 20
ashift: 12
type: 'raidz'
nparity: 2
Що це означає: ashift 12 натякає на 4K сектора. Існує RAIDZ2-верховий оверхед. Малі записи можуть підсилювати алокацію.
Рішення: Якщо ви вже тісно із простором, зміна шаблонів роботи (більше випадкових записів, менші блоки) може прискорити споживання і фрагментацію. Врахуйте це в ризику.
Завдання 11: Інспектувати фрагментацію вільного простору та гістограми metaslab
cr0x@server:~$ sudo zdb -mm tank | head -n 40
Metaslab 0:
size 1090519040
alloc 1019215872
free 71303168
free segments: 142
histogram:
000: ------------------------------------------------------------
001: ******************* 19
002: ***************************** 29
003: ******************** 20
Що це означає: Багато малих вільних сегментів означає «вільний простір є, але він порізаний». Алокація сповільнюється і може не вистачити для великих суміжних потреб.
Рішення: Розглядайте високу фрагментацію + високу заповненість як множник ризику. Створіть запас, звільнивши простір і уникаючи сильного churn (snapshot-и, перезаписи).
Завдання 12: Підтвердити, що discard в гостях увімкнено (тонке виділення без discard — це брехня)
cr0x@server:~$ lsblk -D
NAME DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sda 0 512B 2G 0
sdb 0 512B 2G 0
Що це означає: Блочні пристрої показують градацію discard. Це необхідно, але не достатньо.
Рішення: Переконайтеся, що гіпервізор передає discard/TRIM, а гостьова ФС його виконує (опції монтування, таймер fstrim). Інакше видалення не звільнить простір.
Завдання 13: Спостерігати, чи справді звільнення даних повертає простір на хості
cr0x@server:~$ zfs get -H -o name,property,value written tank/vmstore/vm-101-disk-0
tank/vmstore/vm-101-disk-0 written 103215702016
Що це означає: written може допомогти оцінити недавній churn. Якщо гості «видалили багато», але used не впадає, підозрівайте snapshot-и або відсутній discard.
Рішення: Якщо snapshot-и фіксують блоки, discard не допоможе. Якщо snapshot-ів мало, увімкніть discard по всьому ланцюгу і запустіть trims.
Завдання 14: Знайти dataset-и з величезними дельтами snapshot-ів (кандидати для швидкого звільнення)
cr0x@server:~$ zfs list -t snapshot -o name,used,referenced -s used -r tank/vmstore | tail -n 5
tank/vmstore/vm-104@auto-2025-12-20 188G 3.55T
tank/vmstore/vm-104@auto-2025-12-21 201G 3.55T
tank/vmstore/vm-104@auto-2025-12-22 214G 3.55T
tank/vmstore/vm-102@auto-2025-12-22 61G 1.28T
tank/vmstore/vm-101@auto-2025-12-22 49G 401G
Що це означає: Snapshot-и з великим USED споживають багато унікальних блоків. Видалення одного може повернути значний простір.
Рішення: Якщо реплікація дозволяє — видаліть найбільші/найстаріші snapshot-и першими. Якщо реплікація їх потребує, потрібен інший план (розширити ємність або змінити реплікацію).
Завдання 15: Коли близько до повного, перевірити вплив slop space
cr0x@server:~$ zfs get -H -o property,value slop_space tank
slop_space 12884901888
Що це означає: ZFS тримає деякий простір фактично поза доступом, щоб зменшити сценарії «пул такий повний, що не може працювати».
Рішення: Не плануйте використання останніх кількох ГБ/ТБ. Плануйте ніколи не бачити 100% поза лабораторією. Якщо ви володієте slop space, ви вже запізнилися.
Завдання 16: Перевірити, чи можна взагалі видалити (іноді не можна, і це історія жахів)
cr0x@server:~$ sudo zfs destroy tank/vmstore/vm-104@auto-2025-12-20
cannot destroy 'tank/vmstore/vm-104@auto-2025-12-20': out of space
Що це означає: Ви в зоні «не можеш звільнити простір, бо звільнення потребує простору» (оновлення метаданих все ще вимагають алокацій).
Рішення: Зупиніть всі записи, експортуйте некритичні dataset-и, якщо можливо, додайте простір (тимчасово приєднайте vdev) або звільніть простір з іншого пулу через send/receive. Це інцидент.
Жарт №2: Пул на 99% схожий на нараду, яка «займе лише п’ять хвилин». Всі знають, що трапиться далі.
Швидкий план діагностики
Коли середовище з тонким виділенням поводиться дивно, люди сперечаються про «сховище», ніби це погода. Не варто.
Виконайте коротку послідовність, яка скаже: ми закінчилися по ємності, по цілісності чи по правді?
Перше: підтвердити режим відмови (ємність vs цілісність vs продуктивність)
- Ємність пулу і фрагментація:
zpool list. Якщо CAP > 85% і FRAG зростає, трактуйте як інцидент тиску ємності навіть якщо ви не «повні». - Стан пулу:
zpool status -v. Якщо є помилки — виправляйте цілісність перед тим, як ганятися за «математикою тонкого виділення». - Фіксація snapshot-ів:
zfs list -o usedbysnapshotsпо відповідному дереву. Якщо використання snapshot-ів велике, видалення в гостях не допоможе.
Друге: знайти споживача і швидкість росту
- Топ dataset-ів/zvol за USED:
zfs list -s used. - Топ snapshot-ів за USED:
zfs list -t snapshot -s used. - Індикатори churn:
zfs get writtenна ймовірних підозрюваних; корелюйте з розкладом задач і активністю ВМ.
Третє: вирішити, чи можна повернути простір або потрібно розширити
- Якщо підлягає поверненню: видаліть snapshot-и (обережно), зменшіть ретеншн, увімкніть discard, компактнуйте всередині гостей, там де це реально звільнить блоки.
- Якщо швидко не відновити: додайте ємність (нові vdev) або перемістіть навантаження з пулу; не намагайтеся героїчно діяти на 95–100% пулі.
- Захистіть критичні навантаження: застосуйте
refreservationдля важливих zvol перед тим, як почнете видаляти неправильні речі.
Типові помилки (симптом → корінна причина → виправлення)
1) «Гості показують вільний простір, але записи падають з ENOSPC»
Симптом: ФС у ВМ показує простір, додатки помиляться, в логах гіпервізора «No space left on device».
Корінна причина: Пул ZFS повний (або фактично повний через slop space / фрагментацію). Гість не бачить виснаження хоста до моменту помилок запису.
Виправлення: Негайно звільніть простір у пулі (видаліть snapshot-и, перемістіть dataset-и), додайте ємність, а потім ввести запаси і, за потреби, refreservation для критичних дисків.
2) «Видалення файлів у гості не звільняє простір у пулі»
Симптом: Використання в гості падає; ZFS USED не змінюється.
Корінна причина: Snapshot-и фіксують блоки, або discard не працює по всьому ланцюгу, або файлова система гостя не виконує trim.
Виправлення: Перевірте usedbysnapshots. Якщо воно високое — видаліть/вистаркуйте snapshot-и. Якщо низьке — увімкніть discard у гіпервізорі + гостей і запускайте періодичний fstrim.
3) «Пул 88% і все повільно»
Симптом: Сплески латентності, призупинки ВМ, синхронні записи повільні.
Корінна причина: Фрагментація і конкуренція аллокатора при високому заповненні; copy-on-write підсилює малі перезаписи; RAIDZ може посилювати малі випадкові записи.
Виправлення: Створіть запас (ціль <80–85%), зменшіть churn (snapshot-и, часті перезаписи), налаштуйте розміри блоків там, де доречно, і подумайте про іншу розкладку для наступної збірки (дзеркала для IOPS-важких навантажень).
4) «Ми ввімкнули тонке виділення, бо стиснення нас врятує»
Симптом: Крива росту пула раптово підкрутилася.
Корінна причина: Нові дані несжаті (зашифровані бекапи, медіа, вже стиснуті архіви). Припущення щодо коефіцієнта стиснення стало фантазією.
Виправлення: Відстежуйте дрейф compressratio і плануйте з коефіцієнтом 1.0x для ненадійних навантажень. Перемістіть несжаті дані в окремі пули або на інші рівні.
5) «Видалення snapshot-ів займає вічність, і простір не повертається»
Симптом: Видалення snapshot-ів повільне; пул залишається під тиском.
Корінна причина: Висока фрагментація і масивні ланцюги snapshot-ів роблять звільнення дорогим; плюс простір повертається поступово, коли завершуються оновлення метаданих.
Виправлення: Видаляйте snapshot-и партіями у непіковий час, уникайте гігантських ланцюгів, тримайте запас, і розгляньте зміну стратегії бекапів (менше довгоживучих snapshot-ів, більше інкрементальних відправлень кудись ще).
6) «Ми не можемо видалити snapshot-и, бо пул заповнений»
Симптом: zfs destroy повертає out-of-space.
Корінна причина: Пул настільки повний, що метадані операцій не можуть алокуватися; ви перейшли від «очищення» до «стабілізації».
Виправлення: Зупиніть записи, додайте тимчасову ємність (новий vdev — чистий підхід), або евакуюйте dataset-и через send/receive, якщо можливо. Потім встановіть жорсткі операційні межі.
Три корпоративні міні-історії з передової тонкого виділення
Міні-історія 1: Інцидент, спричинений неправильною припущення
Середня SaaS-компанія експлуатувала охайний кластер віртуалізації на ZFS-backed zvol. Команда зберігання була спокійна щодо тонкого виділення, бо «ВМ ніколи не заповнюють диски».
Це було правдою, поки не стало неправдою.
Одного кварталу фінанси захотіли довший ретеншн для аудитних логів. Команда застосунку погодилась, збільшивши деталізацію логів і зберігаючи більше історії на тих же дисках ВМ.
Ніхто не повідомив storage. Ніхто не вважав за потрібне.
Через два тижні пул досяг високих 80%. Продуктивність стала липкою, але ніхто не кричав. Потім розпочався maintenance window: snapshot-и ВМ для бекапів і апгрейд додатку, що переписав великі масиви даних.
Copy-on-write зробив свою справу: перезаписи вимагали свіжих алокацій. Пул переміг від «незручно» до «повний» швидше, ніж моніторинг встиг вивести пейджер.
Першим видимим симптомом не був «пул повний». Це були збої записів бази даних в гості, потім цикли падіння і помилки «файлова система тільки для читання».
Канал інциденту заповнився теоріями: SAN, баг ядра, «можливо, гіпервізор нестабільний».
Виправлення було нудним: видалити старі snapshot-и, зменшити ретеншн і додати vdev. Урок не в тому, що тонке виділення — зло.
Урок у тому, що тонке виділення — контракт, і контракт ніколи не був записаний.
Міні-історія 2: Оптимізація, що обернулась проти
У великому підприємстві платформа хотіла кращої ефективності сховища. Вони увімкнули агресивне snapshot-ування — щогодини тиждень, щодня місяць — на dataset-ах zvol ВМ.
Графіки виглядали чудово: швидкі відкати, легкі відновлення, менше заявок на бекапи.
Потім вони додали нове CI-навантаження з великою кількістю короткочасних ВМ. Ці ВМ часто писали, видаляли, переписували і повторювали. Всередині гостей файли постійно з’являлися й зникали.
На ZFS із snapshot-ами видалення не означає «звільнення». Воно означає «звільнення пізніше, якщо ніхто не посилається на старі блоки». Snapshot-и посилалися на все.
Використання простору зростало поступово, але команда раціоналізувала: «Snapshot-и того варті». Пул деякий час тримався під 80%.
Пастка була в тому, що фрагментація зростала, а ланцюг snapshot-ів перетворював кожне перезаписування в нову чисту алокацію.
Коли пул перетнув високі 80%, латентність підскочила. CI-завдання сповільнились, що викликало тайм-аути. Тайм-аути викликали повтори. Повтори викликали більше записів.
Це було не просто тиск ємності; це була спіраль підсилення записів, спричинена «оптимізацією», яку ніхто не переглянув.
Вони виправили це, розділивши класи навантажень: CI-ВМ перейшли на пул з іншим політиком snapshot-ів (короткий ретеншн), а «золоті rollback» snapshot-и залишили для довгоживучих станів.
Snapshot-ування не скасували. Його зробили навмисним.
Міні-історія 3: Нудна, але правильна практика, що врятувала день
Одна медична компанія експлуатувала ZFS zvol для критичних систем. Їхній lead по storage наполягав на двох правилах:
тримати заповнення пулу нижче жорсткої межі і встановлювати refreservation для кількох томів, які ніколи не повинні зазнавати помилок запису.
Це було непопулярно. Резервування робить пулик «меншим», і дашборди люблять великі вільні числа.
Під час звичайного закриття місяця звітна система пішла в атаку і почала генерувати величезні проміжні файли на диску своєї ВМ.
Вона заповнила те, що їй обіцяли. У тонко виділеній інсталяції без запобіжників це стало б проблемою для всіх.
Натомість звітна ВМ отримала помилки вводу/виводу і перестала рости. Це було неприємно, але воно було локалізованим.
Бази даних і служби ідентифікації зберегли свої гарантовані місця і залишились здоровими.
Команда операцій мала час відреагувати: коректно розширити диск звітної ВМ, відбалансувати ретеншн і додати ємність за графіком замість панічних дій.
Нічого не потрапило в заголовки. Ось у чому суть.
Перевірочні списки / покроковий план
Чекліст A: Перед увімкненням розріджених zvol у продакшені
- Визначте політику перевиділення: максимальний коефіцієнт, хто може перевиділювати та що відбувається при перетині порогів.
- Оберіть цілі запасу: жорстка межа CAP пулу (зазвичай 80–85% для змішаних навантажень; більш консервативно для RAIDZ + випадкових записів).
- Визначте томи «повинні писати»: встановіть
refreservationдля них і прийміть видимий втрату вільного простору як плату за надійність. - Ретеншн snapshot-ів по класах: не застосовуйте однаковий ретеншн до CI scratch-дисків і баз даних.
- План discard/TRIM: підтвердіть підтримку гіпервізором і гостями; заплануйте
fstrimабо еквівалент. - Моніторинг і алерти: CAP пулу, FRAG, використання snapshot-ів, дрейф compressratio та алерти по швидкості росту.
Чекліст B: Щотижневий операційний огляд (15 хв, заощаджує вихідні)
- Перевірити
zpool listна тренди CAP і FRAG. - Перевірити топ використання snapshot-ів за допомогою
zfs list -o usedbysnapshots. - Переглянути топ росту dataset-ів/zvol:
zfs list -s used. - Підтвердити, що scrub-и проходять і чисті:
zpool status. - Помітити зміни compressratio на основних dataset-ах.
- Переконатися, що цілі реплікації теж мають запас (тонке виділення по обох кінцях — шлях до синхронізованих катастроф).
Чекліст C: Коли пул досягає 85% (ставитися як до контрольованого інциденту)
- Заморозити churn: призупиніть масові міграції, призупиніть неважливі snapshot job-и, зупиніть тест-пайплайни, що трясуть диск.
- Виявити простір для повернення: найбільші snapshot-и, dataset-и з великою кількістю snapshot-ів.
- Підтвердити шлях discard: якщо покладаєтесь на повернення через видалення, переконайтеся, що це взагалі можливо.
- Захистити критичних записувачів: застосуйте
refreservation, якщо відсутній, до погіршення стану пулу. - Вирішити: розширення чи відновлення: якщо не вдасться безпечно звільнити достатньо, заплануйте додавання ємності негайно.
Чекліст D: Коли пул досягає 95% (припиніть імпровізації)
- Зупиніть записи де можливо (throttle додатки, припиніть створення ВМ, зупиніть бекап-сторми).
- Не запускайте «скрипти прибирання», що видаляють випадкові речі; ви видалите те, що легко, а не те, що ефективно.
- Переважно видаліть великі snapshot-и, безпечні для видалення (підтвердіть реплікацію і потреби відновлення).
- Підготуйтеся додати vdev. Часто це найшвидший безпечний вихід.
- Після стабілізації: зробіть постмортем політики перевиділення і впровадьте алерти по швидкості змін.
Питання та відповіді
1) Чи однакові розріджені zvol і «тонке виділення» на SAN?
За концепцією — так: ви представляєте більше логічної ємності, ніж фізично виділено. Операційно ZFS додає copy-on-write, snapshot-и і pooled allocation,
що може зробити режими відмов гострішими, якщо ви працюєте «гарячо» по простору.
2) Чи завжди перевиділення — це погано?
Ні. Перевиділення — інструмент. Воно стає поганим, коли ви не вимірюєте його, не обмежуєте і не тримаєте запас для сплесків та поведінки copy-on-write.
Якщо ви не можете пояснити свій коефіцієнт перевиділення і план відновлення — ви не перевиділяєте, а граєтеся в азартну гру.
3) Чи варто ставити refreservation на кожен zvol?
Зазвичай ні. Резервування всього підриває сенс тонкого виділення. Використовуйте його для критичних томів, де помилка запису неприйнятна (бази даних, control plane, shared services),
а для решти покладайтесь на запас і алерти.
4) Чому ZFS сповільнюється, коли пул майже повний?
Тому що аллокаторам потрібен вибір. Майже повні пули мають менше вільних сегментів, вищу фрагментацію і copy-on-write перезаписи, які вимагають нових алокацій.
На RAIDZ малі випадкові записи можуть додавати оверхед. Результат — зростання латентності і колапс пропускної здатності.
5) Чи можна покладатися на видалення даних у гостях для звільнення простору пулу?
Лише якщо виконуються дві умови: snapshot-и не фіксують ці блоки, і discard/TRIM працює по всьому ланцюгу.
Без discard хост часто не знає, що блоки вивільнені. А зі snapshot-ами вони не вільні, навіть якщо гість їх видалив.
6) Який найнадійніший спосіб швидко повернути простір?
Видалення великих старих snapshot-ів з значним USED часто найпередбачуваніший шлях — за умови, що ви перевірили реплікацію і потреби відновлення.
Випадкове видалення файлів у гостях менш передбачуване, якщо ви не впевнені в ефективності discard і відсутності snapshot-ів.
7) Чи стиснення та dedup змінюють ризик перевиділення?
Стиснення може дуже допомогти, але воно залежить від навантаження і може змінюватися з часом. Dedup може бути небезпечним операційно через тиск пам’яті і складність;
воно також не скасовує фундаментальну істину «записи потребують фізичних блоків». Моделюйте ризик так, ніби стиснення може впасти до 1.0x.
8) Як налаштувати алерти спеціально для тонкого виділення?
Алертуйте по CAP пулу з кількома порогами, відстежуйте зростання використання snapshot-ів і коефіцієнт перевиділення (сума volsize vs придатний пул).
Додайте алерти по швидкості зміни: «pool used +5% за 1 годину» ловить сплески, які статичні пороги пропускають.
9) Який прийнятний коефіцієнт перевиділення?
Універсального числа немає. Для передбачуваних корпоративних VM-флотів з хорошою гігієною 1.5–2.0x може бути допустимим.
Для змішаних навантажень з великою кількістю snapshot-ів і невідомими командами тримайте ближче до 1.0–1.2x або застосовуйте reservation для критичних підрозділів.
10) Чи прийнятно жити на 90%?
Іноді — на короткий термін, з відомими навантаженнями, дзеркалами, низьким churn і репетиційним планом відновлення. Загалом 90% — це коли ZFS починає «нараховувати відсотки».
Якщо ви тонко виділяєте і постійно на 90% — ви обираєте драму.
Висновок: наступні кроки, що запобігають pager’у
Розріджені zvol не є лиходіями. Лиходій — необмежені обіцянки. Якщо ви хочете тонке виділення без тонких виправдань,
трактуйте ємність як SLO з бюджетами, алертами і запобіжниками.
Зробіть наступне:
- Інструментуйте базові показники: CAP пулу, FRAG, використання snapshot-ів, дрейф compressratio і алерти по швидкості росту.
- Напишіть політику перевиділення: визначте максимальний коефіцієнт і що тригерить «припинити створювати нові тонкі томи».
- Захистіть критичні zvol: додайте
refreservationтам, де помилка запису неприйнятна. - Виправте механіку повернення простору: перевірте snapshot-и і поведінку discard; не припускайте, що видалення звільняє.
- Програйте runbook для 95%: знайте точно, як звільнити або розширити ще до того, як це знадобиться.
Тонке виділення може бути конкурентною перевагою: краща утилізація, швидше провізіонування, менше панічних покупок дисків.
Але лише якщо ви чесні щодо рахунку, що настає. ZFS стягне його вчасно, кожного разу.