ZFS logicalused vs used: числа, що припиняють суперечки

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

Кожна дискусія про зберігання в корпоративному чаті в якийсь момент перетворюється на скріншот zfs list і впевнену заяву «ZFS брешуть». Це не так. Він просто веде облік за правилами, які відрізняються від тих, що ваш мозок вивчив на ext4, VMFS або в тому одному SAN-інтерфейсі, який округлює все до «приблизно багато».

Цей матеріал про два оманливо невеликі поля — logicalused і used — і чому вони різниця між спокійним on-call та ескалованим інцидентом. Ми зануримось достатньо глибоко, щоби задовольнити того, хто читає zdb заради розваги, але практично, щоби ви могли діагностувати кризу з місцем, поки хтось з фінансів питає, чому «ми платимо за диски, які не використовуємо».

Чому ці два числа важливі

У ZFS питання «скільки місця використано?» — не одне. Це щонайменше три питання:

  • Скільки місця зайняли б мої дані, якби їх зберігали без стиснення і без спільного використання блоків зі знімками/клонами?
  • Скільки фізичного місця наразі виділено на диску?
  • Скільки місця я можу звільнити, видаливши цей dataset, файл, знімок або клон?

logicalused і used відповідають на перші два питання. Переплутавши їх, ви:

  • Неправильно визначите розмір пулу (купите зайве, або, що гірше, замало).
  • Видалите не те під тиском (класичний момент «ми видалили dataset, але нічого не звільнилось»).
  • Звинуватите ZFS у своїй власній невірі — горда ІТ-традиція.

Короткий жарт, як того вимагає традиція: звіти ZFS про зберігання схожі на рахунки в ресторані — якщо ви не розумієте рядків, звинуватите офіціанта в крадіжці. Офіціант просто рахує по-іншому, ніж ви просили.

Визначення: used проти logicalused

Що означає used

used — це обсяг місця, який dataset виділив у пулі, виміряний у фактичному на-диску просторі. Він враховує ефекти стиснення, копій, накладні витрати на парність (опосередковано, бо виділення йде з реального простору пулу), і включає блоки, які посилаються лише цим dataset, а також блоки, що діляться із знімками/клонами, залежно від того, яке властивість ви читаєте.

Простіше: used — це фізичне виділення в пулі, приписане до простору імен цього dataset, так як ZFS це рахує.

Що означає logicalused

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

Простіше: logicalused — це «явний розмір» з погляду ZFS.

Чому вони розходяться

Різницю між ними здебільшого пояснюють:

  • Стиснення: logicalused залишається «великим», used зменшується.
  • Знімки і клони: видалення може не звільняти used, якщо блоки все ще посилаються звідкись.
  • Резерви: простір може бути «недоступним», не будучи «використаним даними».
  • Копії, recordsize/volblocksize, padding: накладні витрати і гранулярність виділення можуть зробити used більшим, ніж ви очікуєте.

Модель обліку простору (що ZFS насправді рахує)

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

Блоки, посилання і чому видалення не завжди повертає місце

У ZFS блоки звільняються, коли зникає останнє посилання. Файл у dataset посилається на блоки. Знімок також посилається на блоки (знімок — це точка в часі набору посилань). Клон теж посилається на блоки. Поки кожен об’єкт-посилання не відпустить блок, блоки залишаються виділеними.

Отже, ви можете видалити файл — і все одно нічого не звільнити — бо знімок тримає старі блоки. Це не «накладні витрати знімків», це робота знімка: зберігати старі дані.

«Використано датасетом» проти «використано знімками» — це облік, а не фізика

ZFS надає набір властивостей для розбиття використання. Головне — зрозуміти, що деякі властивості відповідають «що приписати цьому dataset», а інші — «що є винятково для цього dataset».

Якщо запам’ятати одну річ для on-call: used — це не те ж саме, що «місце, яке звільниться, якщо я знищу цей dataset». Для цього вам потрібні usedbydataset, usedbysnapshots, usedbychildren, usedbyrefreservation, і часто logicalused плюс logicalusedbydataset.

Стиснення — найпростіша причина, чому логічне і фізичне відрізняються

Стиснення змінює, скільки фізичних секторів виділено, але не змінює того, що додатки вважають вони записали. Ваша база все ще записала 1 ТБ сторінок; ZFS міг зберегти 300 ГБ, бо сильно стиснув. Саме тому існує logicalused: воно зберігає вигляд «що додаток думає, що він спожив», навіть коли ви зберігаєте дешевше.

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

Це не дрібниці заради дрібниць; вони пояснюють, чому ZFS звітує так, як звітує.

  1. ZFS створювався, щоб покласти край ритуалу ремонту файлових систем. Контрольні суми, копіювання при записі і наскрізна цілісність були основними цілями, і модель обліку пішла за цим: незмінні знімки і спільні блоки — це функції, а не крайні випадки.
  2. Ранній євангелізм ZFS просував ідею «знімки дешеві». Це правда для метаданих і незмінних блоків. Але змінені блоки накопичуються, і облік простору мав пояснювати цю реальність.
  3. «Пулове сховище» було філософським зсувом. Традиційні файлові системи жили на фіксованих розділах/LUN. ZFS перемістив обмеження в пул, через що dataset можуть мати незалежні квоти/резерви, але ділитися тим самим фізичним алокатором.
  4. Сімейство logicalused з’явилося, щоб зробити стиснення видимим. Операторам потрібен був спосіб відокремити «слід додатку» від «виплат на диск», особливо для планування ємності і внутрішнього розподілу витрат.
  5. Копіювання при записі — причина фрагментації та накладних витрат на алокацію. ZFS уникає перезапису на місці; він записує нові блоки і перемикає вказівники. Модель обліку простору тому повинна обробляти кілька версій блоків і короткочасні алокаційні сплески.
  6. Стандартизація OpenZFS важлива. Властивості на кшталт usedby* і logicalused* зараз широко доступні, але старі збірки вендорів і старі форки illumos-ери відрізнялися — що породило багато історій «але моя система не показує цю властивість».
  7. Великі розміри запису були навмисним вибором для продуктивності. Значення recordsize за замовчуванням (наприклад, 128K) обрали, щоб зробити послідовний IO ефективним, але вони також впливають на те, скільки фізичного простору виділяється для дрібних записів і наскільки дані підлягають стисненню.
  8. Облік простору став ареною підтримки. Постачальники зберігання і внутрішні платформи навчилися важким шляхом, що одна колонка «Used» породжує тікети. Детальні властивості існують, тому що оператори вимагали відповідей, а не відчуттів.

Як стиснення змінює картину

Стиснення — найпоширеніша причина, чому logicalused набагато перевищує used. Воно також причина, чому планування ємності ZFS може виглядати як магія для тих, хто не бачив, як пул заповнюється о 3:00 ранку.

Приклад: база даних, яка «використовує 10 ТБ» на пулі 4 ТБ

Я бачив панічне повідомлення: «Dataset говорить 10 ТБ used, а пул лише 4 ТБ — ZFS пошкоджений». Ні, він стиснутий. logicalused відстежує логічний розмір; used відстежує реальне виділення. Якщо ваші дані стискаються 3:1, логічні числа можуть бути більші за ємність пулу і при цьому бути цілком нормальними.

Коефіцієнт стиснення — не обіцянка

У момент, коли ваш робочий навантаження змінюється, «вільне місце» зміниться у спосіб, який здається несправедливим. Логи добре стискаються, поки не перестануть. VM-образи добре стискаються, поки хтось не ввімкне повне шифрування диска в гості. Резервні копії добре стискаються, поки ваше ПЗ для бекапу не почне власне стиснення та шифрування.

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

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

Знімки, клони та податківець

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

Знімки тримають блоки живими

Коли ви робите знімок dataset, ви фіксуєте набір вказівників на блоки. Подальші зміни виділяють нові блоки; старі блоки залишаються посиланими зі знімка. Ось чому:

  • Видалення файлу може не зменшити used суттєво (або взагалі).
  • Знищення старих знімків може раптово звільнити величезні обсяги простору.
  • usedbysnapshots може швидко рости при навантаженнях з частими змінами (VM, бази даних, CI-робочі області).

Клони — спільне володіння з паперовою тяганиною

Клон — це записуваний dataset, що починається як знімок. Він ділиться блоками, поки не відхилиться. Це ускладнює повернення місця, бо тепер кілька нащадків посилаються на ту саму історію. Якщо ви знищите джерело, думаючи, що звільните місце, то можете виявити, що клон став основним власником цих блоків.

Практичний наслідок

У відповіді на інциденти знімки — перше місце для перегляду «місця, що не йде». У звітності з ємності знімки — причина, через яку ніколи не варто трактувати «used датасету» як еквівалент «витрат».

Резерви, квоти, refquota: приховані угоди

Облік простору — це не тільки фізика; це політика. ZFS дозволяє вам давати обіцянки (резерви) і накладати обмеження (квоти). Ці обіцянки й обмеження проявляються так, що дивують тих, хто дивиться лише на used.

Quota проти refquota (і чому це важливо)

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

Якщо ви хочете заборонити одному dataset роздуватися, дозволяючи дітям рости незалежно, refquota — інструмент. Якщо ви хочете обмежити ціле піддерево — використовуйте quota.

Reservation проти refreservation

reservation резервує місце для dataset та його нащадків. refreservation резервує місце лише для самого dataset. Резерви зменшують те, що пул показує як доступне, навіть якщо dataset ще не записав ці дані.

Ось звідси й походять інциденти «чому пул повний?» — пул не повний даними, він повний обіцянками.

Refreservation з’являється як usedbyrefreservation

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

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

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

Завдання 1: Порівняйте used і logicalused для dataset

cr0x@server:~$ zfs list -o name,used,logicalused,avail,refer,logicalrefer -H tank/app
tank/app	320G	950G	1.2T	310G	920G

Інтерпретація: Dataset містить приблизно 950G логічних даних, але коштує лише близько 320G фізичного місця пулу — стиснення і/або спільне використання блоків зменшують витрати. Якщо пул мало вільного, видалення цього dataset може звільнити лише приблизно used-подібний обсяг (і можливо менше, якщо знімки/клони ділять блоки).

Завдання 2: Отримати розбивку використання (ті, що вмішають суперечки)

cr0x@server:~$ zfs list -o name,used,usedbydataset,usedbysnapshots,usedbychildren,usedbyrefreservation -H tank/app
tank/app	320G	180G	120G	0B	20G

Інтерпретація: 120G приписано знімкам, 20G зайнято refreservation. Якщо ви намагаєтесь звільнити місце, видалення знімків може бути ефективнішим, ніж видалення файлів.

Завдання 3: Перелічити знімки з впливом на місце

cr0x@server:~$ zfs list -t snapshot -o name,used,refer,logicalused -s used -H tank/app
tank/app@daily-2025-12-20	40G	310G	920G
tank/app@daily-2025-12-21	35G	312G	925G
tank/app@daily-2025-12-22	25G	315G	930G

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

Завдання 4: Перевірити налаштування стиснення і спостережуваний коефіцієнт

cr0x@server:~$ zfs get -o name,property,value -H compression,compressratio,logicalused,used tank/app
tank/app	compression	zstd
tank/app	compressratio	2.96x
tank/app	logicalused	950G
tank/app	used	320G

Інтерпретація: Приблизно 3x пояснює розрив. Якщо compressratio близький до 1.00x, але logicalused все ще великий, перевіряйте знімки/клони або накладні витрати алокації.

Завдання 5: Підтвердити, чи це volume (zvol) чи файловальна система

cr0x@server:~$ zfs get -H -o name,property,value type,volblocksize,recordsize tank/vm-001
tank/vm-001	type	volume
tank/vm-001	volblocksize	16K
tank/vm-001	recordsize	-

Інтерпретація: Volume поводяться інакше: дрібні випадкові записи, padding і вибір blocksize можуть змінити фізичне використання і зростання знімків.

Завдання 6: Помітити резерви і чому «avail» мале

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

Інтерпретація: Ці 50G refreservation з’являться в usedbyrefreservation і зменшать вільний простір пулу, навіть якщо dataset переважно порожній.

Завдання 7: Підтвердити здоров’я пулу і реальний вільний простір (не ігноруйте слоп)

cr0x@server:~$ zpool list -o name,size,alloc,free,frag,capacity,health
NAME   SIZE  ALLOC   FREE  FRAG  CAPACITY  HEALTH
tank  7.25T  6.70T   550G   48%       92%  ONLINE

Інтерпретація: 92% заповнення — це «почніть скасовувати зустрічі». Навіть якщо datasets показують «avail», фрагментація пулу і потреби алокатора можуть призвести до відмов записів раніше, ніж очікують люди.

Завдання 8: Показати топ dataset за фізичним used

cr0x@server:~$ zfs list -o name,used,logicalused,compressratio -S used | head -n 10
NAME             USED  LOGICALUSED  COMPRESSRATIO
tank/vm          2.4T  2.6T         1.08x
tank/backups     1.9T  6.1T         3.21x
tank/home        980G  1.1T         1.12x
tank/app         320G  950G         2.96x

Інтерпретація: Починайте з того, що коштує фізичного місця, а не з того, що виглядає великим логічно. 6.1T логічних бекапів — лише 1.9T реальних; VM дорогі, бо погано стискуються.

Завдання 9: Швидко ідентифікувати datasets з великою вагою знімків

cr0x@server:~$ zfs list -o name,used,usedbysnapshots,logicalused -S usedbysnapshots | head -n 10
NAME           USED  USEDBYSNAPSHOTS  LOGICALUSED
tank/vm        2.4T  820G             2.6T
tank/app       320G  120G             950G
tank/home      980G  40G              1.1T

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

Завдання 10: Перевірити, чи dataset має клони, що залежать від знімків

cr0x@server:~$ zfs get -H -o name,property,value clones tank/app@daily-2025-12-20
tank/app@daily-2025-12-20	clones	tank/app-clone-qa

Інтерпретація: Ви не можете знищити цей знімок без роботи з клонованим dataset. Якщо хтось каже «ми видалили знімки, але місце не звільнилось», клони — головний підозрюваний.

Завдання 11: Оцінити, що звільните при знищенні знімка (сухий прогін)

cr0x@server:~$ zfs list -t snapshot -o name,used -s used -H tank/app | tail -n 5
tank/app@daily-2025-11-30	2G
tank/app@daily-2025-12-01	3G
tank/app@daily-2025-12-02	4G
tank/app@daily-2025-12-03	9G
tank/app@daily-2025-12-04	15G

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

Завдання 12: Безпечно знищувати знімки за шаблоном (і перевіряти)

cr0x@server:~$ zfs destroy -n -v tank/app@daily-2025-12-0{1,2,3}
would destroy tank/app@daily-2025-12-01
would destroy tank/app@daily-2025-12-02
would destroy tank/app@daily-2025-12-03
cr0x@server:~$ zfs destroy -v tank/app@daily-2025-12-0{1,2,3}
will destroy tank/app@daily-2025-12-01
will destroy tank/app@daily-2025-12-02
will destroy tank/app@daily-2025-12-03
cr0x@server:~$ zfs list -o name,used,avail -H tank/app
tank/app	250G	1.3T

Інтерпретація: Спочатку використовуйте -n. Потім виконайте. Потім перевірте. У продакшені різниця між героєм і заголовком — один сухий прогін.

Завдання 13: Перевірити, чи простір «застряг» через refreservation

cr0x@server:~$ zfs list -o name,usedbyrefreservation,refreservation -H tank/app
tank/app	20G	50G
cr0x@server:~$ zfs set refreservation=none tank/app
cr0x@server:~$ zfs list -o name,used,avail -H tank/app
tank/app	230G	1.4T

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

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

cr0x@server:~$ df -hT /tank/app
Filesystem     Type  Size  Used Avail Use% Mounted on
tank/app       zfs   1.5T  310G  1.2T  21% /tank/app
cr0x@server:~$ du -sh /tank/app
910G	/tank/app

Інтерпретація: du — це погляд через простір імен файлової системи і може бути спотворений розрідженими файлами, правами доступу та живими змінами. Трактуйте його як підтвердження, а не істину. Властивості ZFS зазвичай консистентніші для обліку.

Завдання 15: Якщо ви підозрюєте розріджені файли у VM або БД

cr0x@server:~$ ls -lh /tank/vm/images/vm-001.img
-rw------- 1 root root 500G Dec 25 10:11 /tank/vm/images/vm-001.img
cr0x@server:~$ du -h /tank/vm/images/vm-001.img
120G	/tank/vm/images/vm-001.img

Інтерпретація: Цей файл розріджений: логічний розмір 500G, фізичне споживання 120G. logicalused у ZFS зазвичай відповідає «500G світогляду», тоді як used — «120G реальності», модульовано стисненням і знімками.

Міні-історії з корпоративного продакшена

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

Команду зберігання зателефонували через «пул на 95%» у п’ятницю вдень — такий час, що підказує, що всесвіт має календар і почуття гумору. Власник застосунку послався на logicalused: їх dataset «містив кілька терабайт», отже вони — лиходій. Вони погодилися видалити пакет старих експортів. Усі пораділи; ніхто не перевірив знімки.

Експорти були видалені. du впав. Slack заповнився підняттями рук. Пул не зрушився. Наступна інтенсивна записова робота зіткнулась з ENOSPC через годину і вивела з ладу pipeline інгесту. Тепер це був інцидент з керівництвом, а не лише інженерами.

Ми нарешті зробили дорослу річ: запустили zfs list -o usedby* і відсортували знімки за used. Dataset мав агресивний графік знімків — кожні 15 хвилин — для «легкого відкату», і навантаження постійно перезаписувало великі файли. Знімки були не дешеві. Вони збирали вчорашні блоки як куратор музею з обмеженим бюджетом.

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

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

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

Платформна команда хотіла кращої продуктивності VM і вирішила «оптимізувати знімки», перемкнувши VM dataset на менший розмір блоку і збільшивши частоту знімків, вважаючи, що менші блоки означають менші дельти. Теорія звучала правдоподібно на зустрічі. Теорія часто така.

На практиці менші блоки збільшили накладні витрати на метадані і перетворили записи на конфетті виділень. Робоче навантаження VM — багато випадкових записів — породило постійний потік нових блоків. Знімки захоплювали старі. Використання простору знімків росло швидше, а не повільніше. Коефіцієнт стиснення також погіршився, бо менші, більш випадкові блоки гірше стискуються.

Першим сигналом була не панель — це була латентність. Пул став фрагментованим і навантаженим. Потім з’явилась проблема ємності: usedbysnapshots став домінантним терміном. Команда спробувала видалити «старі» знімки, але клони з CI-воркфлоу утримували посилання, тож великі звільнення так і не настали.

План відновлення був непомітний: повернути частоту знімків до розумних значень, переоцінити вибір blocksize для навантаження і припинити клонування з довго збережених знімків. Справжня оптимізація була не «ще більше ручок», а узгодження політики (знімки) з обсягом змін і розуміння, що logicalused — не рахунок.

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

Інша організація мала правило: кожне сповіщення про ємність мало обов’язковий «знімок обліку простору» — чотири команди, вставлені в тікет: zpool list, zfs list -o usedby* для топових datasets, список знімків відсортований за used і перевірка резервацій/квот. Це було так нудно, що інженери скаржились на бюрократію. Це також причина, чому їх інциденти закінчувались швидко.

Однієї ночі пул почав несподівано зростати. On-call виконав чеклист, виявив один dataset зі стрибком usedbyrefreservation і побачив, що автоматика застосувала великий refreservation для «захисту продуктивності» під час міграції. Міграція закінчилась; резервація залишилась.

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

Коментар on-call після інциденту був такий, що варто зберегти в рамку: «Ми не полагодили зберігання; ми полагодили облік». Саме так закінчуються більшість інцидентів з простором у ZFS.

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

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

Перше: чи справді пул тугий?

cr0x@server:~$ zpool list -o name,size,alloc,free,capacity,frag,health
NAME   SIZE  ALLOC   FREE  CAPACITY  FRAG  HEALTH
tank  7.25T  6.70T   550G       92%   48%  ONLINE

Рішення: Якщо заповнення вище ~80–85% на багатьох пулах (особливо понад 90%), припускайте ризик продуктивності та алокації. Не сперечайтесь про числа dataset; стабілізуйте пул.

Друге: які datasets займають найбільше фізичного місця?

cr0x@server:~$ zfs list -o name,used,avail,logicalused,compressratio -S used | head -n 15

Рішення: Сфокусуйтесь на used для негайного полегшення, а не на logicalused. Пул може виділяти лише фізичне.

Третє: чи прив’язано місце знімками/клонами?

cr0x@server:~$ zfs list -o name,used,usedbysnapshots,usedbydataset,usedbychildren -S usedbysnapshots | head -n 15
cr0x@server:~$ zfs list -t snapshot -o name,used -s used | tail -n 20

Рішення: Якщо usedbysnapshots велике, перегляньте політику знімків/клони. Знищення знімків — часто найбезпечніший важіль для звільнення — після перевірки залежностей.

Четверте: чи роблять резерви «вільне» меншим, ніж воно є?

cr0x@server:~$ zfs list -o name,usedbyrefreservation,refreservation -S usedbyrefreservation | head -n 15

Рішення: Якщо резерви домінують, ви не втратили диск — у вас закінчився неподілений диск. Це політичне питання і часто швидке виправлення.

П’яте: чи маскує стиснення ризик росту?

cr0x@server:~$ zfs get -o name,property,value -H compressratio,compression tank | head

Рішення: Якщо ваш план ґрунтується на високому стисненні, припускайте, що воно впаде при зміні навантаження (шифрування, уже стислені дані, зміни VM). Додайте запас.

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

Помилка 1: Трактувати logicalused як фізичне споживання

Симптом: Паніка «dataset більший за пул», або внутрішній розподіл коштів, що виставляє команди за терабайти, які вони насправді не спричинили.

Виправлення: Використовуйте used (фізичний) для ємності та вартості. Використовуйте logicalused для сліду додатку та прогнозування регресій стиснення. У сумнівах показуйте обидва, плюс compressratio.

Помилка 2: Видаляти файли, щоб звільнити місце, коли є знімки

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

Виправлення: Перевірте usedbysnapshots. Перелічіть знімки за used. Підтвердіть клони. Знищуйте знімки відповідно до політики після валідації вимог відновлення.

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

Симптом: «Вільне» пулу мале, але datasets не виглядають великими. usedbyrefreservation немалий. Нові алокації відмовляються раніше, ніж очікують.

Виправлення: Проведіть інвентар refreservation/reservation і валідуйте кожну. Видаліть або скорегуйте. Документуйте причину.

Помилка 4: Ігнорувати клони при очищенні знімків

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

Виправлення: Перевірте властивість clones на знімках. Вирішіть, чи потрібні клони; якщо так — прийміть прив’язане місце або перемістіть дані клонів кудись ще.

Помилка 5: Неправильне читання refer проти used

Симптом: Хтось каже «refer менший, отже він малий», тоді як used величезний через дітей/знімки/резерви.

Виправлення: Використовуйте zfs list -o usedby* і вирішіть, чи витрати в dataset, його знімках, дітях або в резервуваннях.

Помилка 6: Тримати пули занадто заповненими через «ZFS має знімки і стиснення»

Симптом: Продуктивність погіршується, алокації стають непередбачуваними, час scrub/resilver збільшується, і потім невеликий сплеск викликає ENOSPC.

Виправлення: Тримайте резерв. Побудуйте оповіщення за заповненням пулу, а не лише за avail датасету. Для більшості продакшен-пулів трактуйте 90% як аварійний поріг.

Помилка 7: Планування ємності на основі одного тижня compressratio

Симптом: Пул «раптом» заповнюється після зміни навантаження (шифрування, нові типи даних), незважаючи на стабільне логічне зростання.

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

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

Чек-лист при суперечці про простір (завершити спори, а не дружбу)

  1. Зняти zpool list для правди на рівні пулу: ємність, вільне, фрагментація.
  2. Зняти zfs list -o used,logicalused,compressratio для топових datasets, відсортованих за used.
  3. Для трьох найвпливовіших dataset зняти zfs list -o usedbydataset,usedbysnapshots,usedbychildren,usedbyrefreservation.
  4. Перелічити знімки на головному порушнику, відсортовані за used.
  5. Перевірити клони на будь-яких знімках з великим used.
  6. Перевірити резерви/квоти: reservation, refreservation, quota, refquota.
  7. Вирішити дію: знищити знімки, видалити резерви, видалити datasets або розширити пул.
  8. Після змін зняти ті самі команди і прикріпити до тікета для закриття.

План екстреного відновлення місця (коли ви вище 90%)

  1. Заморозити неважливу зміну: призупинити великі CI-запуски, вимкнути важкі відновлення, відкласти пакетні роботи.
  2. Знищувати найвпливовіші знімки першими (після підтвердження відсутності клонів і вимог відновлення).
  3. Видалити випадкові резерви і застарілі квоти, що блокують записи.
  4. Якщо потрібно видаляти дані, націлюйтесь на datasets з високим usedbydataset (відносно ексклюзивні), а не на ті, що домінують за рахунок знімків.
  5. Коли стабільність відновлена, налаштуйте збереження/кадренс знімків відповідно до змін і заплануйте розширення з запасом.

План звітності ємності (припинити війни через рахунки)

  1. Звітуйте і фізичне, і логічне: used і logicalused.
  2. Включайте compressratio і розбивку по знімках (usedbysnapshots).
  3. Для внутрішнього розподілу витрат виставляйте рахунки за фізичним used, але показуйте логічне як «сигнал попиту».
  4. Переглядайте резерви щоквартально; трактуйте їх як контракти з власником.

Питання та відповіді

1) Яке число використовувати для планування ємності: used чи logicalused?

Використовуйте used для питання «чи заповниться пул?», бо воно відображає фізичне виділення. Використовуйте logicalused для «який слід додатку?» і для прогнозування, наскільки болісною може бути регресія стиснення.

2) Чому logicalused перевищує розмір пулу?

Бо воно ігнорує стиснення і може відображати розріджені файли або дані, що добре стискаються. Воно звітує логічний розмір, а не вартість на диску. Якщо used поміщається і пул має вільне місце — це не помилка.

3) Я видалив 500 GB і нічого не звільнилось. Що сталося?

Ймовірно знімки (або клони) все ще посилаються на видалені блоки. Перевірте usedbysnapshots, перелічіть знімки за used і перевірте властивість clones на знімках перед їх видаленням.

4) Чи знищення знімка завжди звільняє його used обсяг?

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

5) У чому різниця між refer і used?

refer — це обсяг даних, доступних через dataset (приблизно «те, що ви бачите»). used включає простір, приписаний знімкам, дітям і резервам залежно від контексту. У сумнівах використовуйте розбивку usedby*.

6) Чому avail у dataset відрізняється від вільного простору пулу?

avail dataset обмежується квотами/резервами і обмеженнями батьків. Вільне місце пулу — фізичне. Також при високому заповненні пулу ефективно доступний простір може бути меншим за «free» через фрагментацію і потреби алокатора.

7) Чи завжди високий compressratio — це добре?

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

8) Як резерви потрапляють у «used», якщо дані не записані?

Резерви зменшують доступний простір і відображаються в обліку через usedbyrefreservation (та пов’язані властивості). Це навмисні попередні алокації, а не блоки даних.

9) Який найшвидший спосіб знайти, що тримає простір?

Запустіть zfs list -o usedbydataset,usedbysnapshots,usedbychildren,usedbyrefreservation на найбільших datasets за used. Один з цих пунктів зазвичай покаже, де застряг простір.

10) Чи можна «дефрагментувати» ZFS, щоб повернути місце?

Фрагментація в основному впливає на продуктивність і ефективність алокації, а не на правильність обліку. Щоб «повернути місце», потрібно видалити посилання (знищити знімки/клони/дані) або додати ємність, а не шукати міфічну кнопку дефрагментації.

Висновок

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

Коли ви діагностуєте ємність, починайте з реальності пулу (zpool list), потім знайдіть, хто платить фізичний рахунок (used), потім запитайте, хто прив’язує історію (usedbysnapshots) і хто підписував контракти (refreservation). Робіть це послідовно — і ви припините сперечатися про числа ZFS, бо нарешті навчитесь їх читати.

← Попередня
PostgreSQL проти SQLite: повнотекстовий пошук — коли SQLite дивує (а коли ні)
Наступна →
Оформлення замовлення WooCommerce не працює: діагностика SSL, платежів і конфліктів плагінів

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