У ZFS «незнищуваний снапшот» зазвичай означає «снапшот із залежністю, яку ви не помітили». ZFS безжально послідовний: він не видалить історію, яка все ще потрібна комусь іншому — чи то клон, тег hold від конвеєра бекапів, політика реплікації, чи ваше власне раннє рішення трактувати снапшоти як кошик для сміття.
Це практичний польовий посібник, як зробити ці снапшоти зниклими безпечно. Ми розглянемо, що саме блокує видалення, як довести це командами та як прибрати зайве, не перетворивши здоровий пул на фіаско. Я опиратимусь на дві істини ZFS, які ви вивчаєте в продукції: дані завжди мають власника, і рахунок завжди приходить.
Що насправді означає «незнищуваний» у ZFS
Коли люди кажуть, що вони «не можуть видалити снапшот ZFS», система зазвичай повідомляє їм одну з цих причин:
- Існує hold на снапшоті, тому ZFS відмовляється його знищити, доки hold не буде звільнений.
- Клон залежить від нього (записуваний датасет, створений зі снапшоту). ZFS не видалить снапшот, бо він буквально є походженням живої файлової системи.
- Снапшот «зайнятий» через поточні операції (send/receive, створення снапшотів або щось, що тримає посилання).
- Реплікація, інструменти бекапу або політики продовжують його відтворювати, тому здається, що видалення «не працює».
- Ви видаляєте не те (наприклад, ви видалили снапшот на джерелі, але на мішені він ще є; або ви знищили bookmark замість снапшоту; або ім’я снапшоту містить спецсимволи і shell вас обманув).
І ще одна поширена скарга — «я видалив снапшоти, але простір не звільнився» — це не про незнищуваність. Це про облік. Простір у ZFS не звільняється доти, доки останнє посилання на блоки не зникне, і ці блоки можуть бути ще посиланнями для новіших снапшотів, клонів або просто даних, які присутні у живій файловій системі. ZFS багато чого робить, але він не магічна шредерна машина.
Перша жартівлива ремарка (як обіцяно, всього дві): снапшоти ZFS схожі на чеки — легко накопичувати, важко позбутися, і вони потрібні саме тоді, коли вже було прийнято жахливе рішення.
Цікаві факти та коротка історія: чому ZFS так поводиться
Невеликий контекст допоможе зрозуміти, що це не саботаж, а інженерія:
- Снапшоти ZFS — це копіювання-при-записі (copy-on-write) вигляди. Немає перезапису на місці; снапшоти тримають посилання на старі версії блоків. Саме тому вони миттєві і саме тому вони можуть «закріплювати» простір.
- «Незнищуваний» часто — це функція. Holds були створені спеціально, щоб автоматизація не видаляла снапшоти, потрібні для відповідності, вікон бекапу або цілісності реплікації.
- Клони — це реальні файлові системи. Клон — це не «копія», а датасет, що ділиться блоками з вихідним снапшотом. Видалення походження «осиротило б» походження лінії клонів.
- ZFS створювали як власний менеджер томів. Саме тому він може відслідковувати власність блоків на рівні, який робить залежності снапшотів примусовими — і безповоротними.
- Снапшоти можуть «утримуватися» віддаленими системами. При реплікації приймач може тримати снапшоти або вимагати їх як інкрементні бази. Ваше «видалення» на джерелі не примушує приймач забути.
- Система властивостей датасетів — частина контрольної площини. Властивості на кшталт
readonly,canmountіmountpointзмінюють поведінку без зміни даних; holds і origin клонів — схожі «метадані-сила». - Спадщина Solaris відчутна. Багато поведінкових рис ZFS (включно зі строгістю інваріантів) походять від очікувань корпоративного зберігання: правильність перш за все, зручність — потім.
- Знищення — транзакційне. Зміни ZFS атомарні; коли він відмовляється знищити снапшот, він захищає послідовний на диску граф посилань.
- Bookmarks існують не просто так. Bookmarks — це легкі вказівники на транзакційну групу снапшоту, які використовують для збереження інкрементної бази без збереження всіх метаданих снапшоту. Люди плутають їх зі снапшотами і дивуються, чому простір не змінився.
Швидка діагностика — план дій (перше, друге, третє)
Якщо ви на виклику і система зберігання вас тривожить, не блукайте. Робіть це в такому порядку:
1) Підтвердіть, що саме «незнищуване» і чому ZFS заперечує
Спробуйте destroy і прочитайте точну помилку. ZFS зазвичай конкретний. «snapshot has dependent clones» і «snapshot is held» — не натяки.
2) Негайно шукайте holds і залежності клонів
Holds і клони — причина більшості «чому не видаляється». Перевіряйте holds за допомогою zfs holds. Перевіряйте клони за допомогою zfs get origin (або зворотного пошуку через zfs list -t all і grep).
3) Якщо проблема в просторі, знайдіть, що його реально споживає
Використовуйте usedbysnapshots, usedbydataset і usedbychildren. Якщо снапшоти споживають простір, визначте, які саме снапшоти важкі і чи закріплені вони клон/holds.
4) Якщо видалення «працює», але снапшоти повертаються, шукайте творця
Зазвичай це cron, systemd timer, апарат бекапу або інструмент реплікації, який вважає, що відповідає за утримання. Видалення симптомів не вилікує хворобу.
Основні механіки: holds, клоні, «заняті» датасети та реплікація
Holds: ввічливе «ні»
Hold — це тег на снапшоті, який забороняє знищення. Снапшот може мати кілька hold’ів, зазвичай по одному на кожен робочий процес: «backup», «replicate», «legal», «before-upgrade» та сумнозвісний «temp», що стає постійним.
Ключова операційна деталь: ви не «видаляєте hold», ви його звільняєте за ім’ям. Якщо існує кілька тегів, потрібно звільнити їх усі (або обережно використовувати шаблони з -r). Тут zfs release — ваш друг, але саме тут ви можете собі нашкодити, звільнивши hold, який очікує система бекапу.
Клони: тиха залежність
Клони — це датасети, створені зі снапшоту. Вони тримають снапшот живим, бо снапшот є origin для клону. ZFS не знищить origin снапшоту, поки ви або не знищите клон, або не promote-нете його (зробивши клон незалежним і перевернувши напрямок залежності).
Практичний підступ: клони можуть з’являтися в очікуваних місцях: CI-пайплайни, «тимчасові» оточення розробників, шаблони віртуалізацій, оновлення БД для тестів. Якщо пощастить, клон має чесну назву. Якщо ні — він називається prod2 і всі вдають, що це неважливо.
«Зайняті» снапшоти та операційні блокування
ZFS може позначати снапшоти як зайняті, якщо вони беруть участь у поточних операціях. Поширені причини:
zfs send/zfs receiveпотоки в процесі- довготривале знищення снапшотів (особливо при величезній кількості снапшотів)
- інструменти, які тримають відкриті посилання на датасети довше, ніж очікувалося
«Зайнятий» зазвичай тимчасовий стан, але в заплутаних середовищах може стати постійним через петлі автоматизації.
Реплікація та інкрементні бази
Пайплайни реплікації часто потребують спільного снапшоту між джерелом і ціллю для відправки інкрементів. Деякі інструменти це забезпечують, ставлячи holds на снапшоти до підтвердження прийому або утримуючи певні снимки як «якорі».
Операційно, вам потрібно знати, чи снимається снапшот тому, що ZFS так каже (holds/клони), чи тому, що ваші інструменти так кажуть (відтворені снапшоти, політики утримання або віддалені обмеження).
Практичні завдання: команди, які справді вирішують проблему (з інтерпретацією)
Нижчеподані завдання написані як для використання в консолі, з достатньою інтерпретацією, щоб вберегти вас від проблем. Налаштуйте імена датасетів під своє середовище.
Task 1: List snapshots and sort by space impact
cr0x@server:~$ zfs list -t snapshot -o name,used,refer,creation -s used tank/data
NAME USED REFER CREATION
tank/data@autosnap_2025-12-20 84G 1.2T Sat Dec 20 03:00 2025
tank/data@autosnap_2025-12-21 91G 1.2T Sun Dec 21 03:00 2025
tank/data@autosnap_2025-12-22 12G 1.2T Mon Dec 22 03:00 2025
Інтерпретація: USED тут — це «унікальне для цього снапшоту місце, враховуючи все інше, що існує». Якщо ви полюєте за простором, сортуйте за used і починайте з найбільших порушників. Якщо список снапшотів величезний — звужуйте до піддерева датасету.
Task 2: Attempt destroy and capture the real error
cr0x@server:~$ sudo zfs destroy tank/data@autosnap_2025-12-21
cannot destroy snapshot tank/data@autosnap_2025-12-21: snapshot is held
Інтерпретація: Не здогадуйтеся. Рядок помилки підкаже, у якій гілці дерева рішень ви знаходитесь: held, has dependent clones, busy тощо.
Task 3: Show holds on a snapshot
cr0x@server:~$ sudo zfs holds tank/data@autosnap_2025-12-21
NAME TAG TIMESTAMP
tank/data@autosnap_2025-12-21 backup Tue Dec 23 01:12 2025
tank/data@autosnap_2025-12-21 replicate Tue Dec 23 01:13 2025
Інтерпретація: Дві різні системи (або дві фази однієї системи) поставили holds. Потрібно звільнити обидва теги, перш ніж destroy спрацює. Також: ці теги — підказки — знайдіть їхніх власників перед тим, як усе порвати.
Task 4: Release a single hold tag with zfs release
cr0x@server:~$ sudo zfs release backup tank/data@autosnap_2025-12-21
Інтерпретація: Це знімає лише hold backup. Якщо видалення все ще не вдається, існує принаймні ще один тег або зовсім інший блокувальник.
Task 5: Release multiple holds, then destroy
cr0x@server:~$ sudo zfs release backup tank/data@autosnap_2025-12-21
cr0x@server:~$ sudo zfs release replicate tank/data@autosnap_2025-12-21
cr0x@server:~$ sudo zfs destroy tank/data@autosnap_2025-12-21
Інтерпретація: Чисто і явно краще за хитромудрість. У проді я віддаю перевагу двом командам, які можна перевірити, а не одній, що «має спрацювати».
Task 6: Find clones that depend on a snapshot (origin search)
Найнадійніший спосіб: шукати датасети, чиє origin співпадає з вашим снапшотом.
cr0x@server:~$ zfs get -H -o name,value origin -r tank | grep 'tank/data@autosnap_2025-12-20'
tank/dev-jenkins-workspace tank/data@autosnap_2025-12-20
tank/vm-templates/ubuntu tank/data@autosnap_2025-12-20
Інтерпретація: Ці датасети — клони (або нащадки клонів), прив’язані до того снапшоту. Снапшот не помре, поки з цими не розберуться.
Task 7: Confirm a dataset is a clone and see its origin
cr0x@server:~$ zfs get origin tank/dev-jenkins-workspace
NAME PROPERTY VALUE SOURCE
tank/dev-jenkins-workspace origin tank/data@autosnap_2025-12-20 -
Інтерпретація: Цей датасет залежить від того снапшоту. У вас є опції: знищити клон або промотувати його (якщо він має жити).
Task 8: Destroy a clone (and its children) to unblock snapshot destruction
cr0x@server:~$ sudo zfs destroy -r tank/dev-jenkins-workspace
Інтерпретація: -r знищує датасет і всіх нащадків. Це правильно для CI-воркспейсів та ефермерних девдатасетів. Це не правильно для чогось, що хтось підступно почав вважати продукцією.
Task 9: Promote a clone to remove dependency on the origin snapshot
cr0x@server:~$ sudo zfs promote tank/vm-templates/ubuntu
Інтерпретація: Промоція перевертає залежність, роблячи клон «батьком» лінії. Після промоції оригінальний снапшот може стати знищуваним (за умови відсутності інших клонів/hold’ів). Промоція змінює відносини між снапшотами; ставтеся до неї як до запиту на зміну, а не як до випадкового виправлення.
Task 10: Identify snapshot space vs dataset space (why space didn’t free)
cr0x@server:~$ zfs list -o name,used,usedbysnapshots,usedbydataset,usedbychildren -r tank/data
NAME USED USEDBYSNAPSHOTS USEDBYDATASET USEDBYCHILDREN
tank/data 3.1T 1.4T 1.5T 0.2T
Інтерпретація: Снапшоти тут складають 1.4T. Якщо ви видалите снапшоти і це число не впаде, у вас все ще є снапшоти (можливо на нащадках), holds/клони, що перешкоджають видаленню, або ви видаляєте ті, що не володіють простором, який вас цікавить.
Task 11: See which snapshots exist on descendants (the “I deleted it” trap)
cr0x@server:~$ zfs list -t snapshot -r -o name,used -s used tank/data | tail -n 10
tank/data/projects@autosnap_2025-12-21 110G
tank/data/projects@autosnap_2025-12-22 95G
tank/data/home@autosnap_2025-12-21 70G
tank/data/home@autosnap_2025-12-22 68G
Інтерпретація: Ви могли знищити снапшот на tank/data, але важке використання — на tank/data/projects та tank/data/home. Снапшоти належать датасету; рекурсія має значення.
Task 12: Destroy a snapshot recursively (carefully)
cr0x@server:~$ sudo zfs destroy -r tank/data@autosnap_2025-12-21
Інтерпретація: Це знищує снапшот з такою назвою на датасеті і всіх нащадках. Це потужно і легко зловживати. Переконайтеся, що правила найменування снапшотів послідовні і що ви дійсно маєте на увазі рекурсію.
Task 13: Find snapshots that are held across a whole tree
ZFS не дає єдиної команди «перелічити всі утримувані снапшоти» з повними деталями одним махом, тому зазвичай ми скриптуємо це обережним способом.
cr0x@server:~$ for s in $(zfs list -H -t snapshot -o name -r tank/data); do
> zfs holds "$s" 2>/dev/null | awk 'NR==1{next} {print $1" "$2}'
> done | head
tank/data@autosnap_2025-12-20 replicate
tank/data/projects@autosnap_2025-12-20 replicate
tank/data/projects@autosnap_2025-12-20 backup
Інтерпретація: Це показує, які снапшоти захищені і якими тегами. У заплутаному середовищі назви тегів — це розшифровка, яка допомагає зрозуміти, яка система «володіє» утриманням.
Task 14: Verify whether replication/backup is recreating snapshots
Якщо снапшоти «повертаються», перевірте часи створення та закономірності. Це найменш гламурний, але найефективніший підхід: доведіть джерело істини.
cr0x@server:~$ zfs list -t snapshot -o name,creation -s creation tank/data | tail -n 5
tank/data@autosnap_2025-12-25_0000 Thu Dec 25 00:00 2025
tank/data@autosnap_2025-12-25_0100 Thu Dec 25 01:00 2025
tank/data@autosnap_2025-12-25_0200 Thu Dec 25 02:00 2025
tank/data@autosnap_2025-12-25_0300 Thu Dec 25 03:00 2025
tank/data@autosnap_2025-12-25_0400 Thu Dec 25 04:00 2025
Інтерпретація: Годинний інтервал кричить «автоматизація». Видаляти без виправлення планувальника — це як вичерпувати воду з човна, поки в ньому ще свердлять дірки.
Task 15: Check for an in-progress send/receive that may hold things “busy”
Це залежить від ОС та інструментів, але зазвичай активні ZFS-потоки можна помітити у списку процесів.
cr0x@server:~$ ps aux | egrep 'zfs (send|receive)|mbuffer|ssh .*zfs receive' | grep -v egrep
root 18244 2.1 0.0 17768 4100 ? Ss 03:02 0:01 zfs send -I tank/data@autosnap_2025-12-24 tank/data@autosnap_2025-12-25_0300
root 18245 0.8 0.0 10432 2820 ? S 03:02 0:00 ssh backup-target zfs receive -uF tank/replica/data
Інтерпретація: Якщо ви знищите снапшот, який зараз є базою для інкрементного send, робота може впасти або перезапуститися і знову поставити hold. Координуйтеся з вікнами реплікації.
Task 16: Use dry-run thinking before destructive commands
ZFS не має універсального --dry-run для destroy. Ваш «dry run» — це інспекція: перелічте holds, клони, залежності, підтвердьте найменування і сферу дії (-r проти не-рекурсивного).
cr0x@server:~$ zfs holds tank/data@autosnap_2025-12-20
cr0x@server:~$ zfs get -H -o name,value origin -r tank | grep 'tank/data@autosnap_2025-12-20' || true
cr0x@server:~$ zfs list -t snapshot -r -o name tank/data | grep '@autosnap_2025-12-20' | head
Інтерпретація: Ця послідовність відповідає на питання: «Чи є hold?», «Чи є клони?» і «Що саме торкнеться рекурсія?». Це нудно. Це працює.
Три міні-історії з корпоративних боїв
Міні-історія 1: Інцидент через неправильне припущення
Припущення: «Якщо снапшот старий — його безпечно видалити». Адмін зберігання (компетентний, уважний, просто квапився) побачив пул на 90% і почав обрізати снапшоти старші за 30 днів. Команда destroy не спрацювала для підмножини через «dependent clones», тож вони пішли далі і видалили те, що могли. Простір не відновився достатньо. Паніка зросла. Послідувало більше видалень.
Що вони не помітили: команда розробників мала «тимчасовий» аналітичний sandbox, клонований з місячного снапшоту продукційного датасету. Він використовувався для ad-hoc-запитів, і хтось направив внутрішню панель на нього, бо «швидко». Ніяких заявок. Ніякої документації. Просто тиха залежність, прикріплена до снапшоту як присоска.
Дорога реагування стала поганою, бо помилка не сказала «це живить ваші дашборди». Вона просто сказала «dependent clones». Команда спробувала промотувати клон, не розуміючи наслідків, що переставило лінії походження і зламало скрипт утримання, який припускав, що origin знаходяться в одному місці. Реплікаційні інкременти не могли знайти свої бази. Роботи впали. Активації помилок помножилися.
Що виправило ситуацію — не геройство, а дорослий крок: інвентаризація клонів, ідентифікація власників, планування простою для sandbox і або знищення його, або переведення в окремий датасет з явним утриманням. Висновок: «старий» — це не критерій безпеки. Критерій — залежність.
Міні-історія 2: Оптимізація, що обернулася проти
Мета була благородна: зменшити кількість снапшотів. Команда платформи змінила політику з «годинні снапшоти протягом 7 днів» на «годинні протягом 24 годин, потім щоденні протягом 30 днів». Вони також додали зручність: створювати клон з вчорашнього снапшоту для кожного розробника, хто хотів свіже оточення. Створення клонів було автоматизованим і швидким. Розробники були в захваті.
Через два місяці пул почав рости без видимої причини. Вони видаляли снапшоти за графіком; графіки відповідали політиці. Але usedbysnapshots лишався високим. Інженер зберігання розібрався і знайшов десятки довгоживучих клонів, створених з «вчорашнього» снапшоту, які стали напівпостійними, бо використовувалися для відтворення багів, запуску бенчмарків або зберігання «на всякий випадок» даних.
Оптимізація обернулася проти, бо політика утримання передбачала лише снапшоти як механізм закріплення. Клони тихо перетворили «короткотривалу історію снапшотів» на «довготривале утримання блоків», і система робила саме те, про що їй сказали: захищати блоки origin клону. Виправлення — ввести життєвий цикл для клонів також: авто-видалення, авто-промоція (де доречно) і примусову політику іменування та власності.
Класична корпоративна історія: ви оптимізуєте одну метрику (кількість снапшотів) і випадково монетизуєте іншу (утримання блоків). Сховище байдуже до таблиць у ваших звітах — воно нараховує в терабайтах.
Міні-історія 3: Нудна, але правильна практика, що врятувала день
В іншому середовищі очищення снапшотів ніколи не було захоплюючим — і саме тому воно працювало. Було письмове правило: кожен тег hold має включати назву системи та призначення (наприклад, backup:daily, replicate:dr, legal:case123). Кожен клон повинен мати префікс власника і дату закінчення в назві датасету. Кожна зміна політики утримання вимагає простого peer review.
Потім сталася загроза шифрувальника. Команда безпеки захотіла зберегти старі снапшоти під час розслідування. Інструменти бекапу почали ставити holds усюди. Використання зросло. Пул наближався до неприємного порогу. І ось де «нудна практичність» виблискує: оскільки теги були інформативні, команда зберігання могла швидко побачити, які holds були спричинені безпекою, а які — реплікацією. Вони вибірково звільнили holds після завершення терміну розслідування, не порушивши DR-реплікацію.
У них також був щотижневий звіт (так, нудний CSV) зі списком клонів старших за строк їхнього життя. Коли інцидент стався, вони вже знали, що безпечно видалити. Ніякої археології, ніякого гадання, ніяких опівнічних листів «хто володіє цим датасетом».
День врятувала річ, якою ніхто не хизується: послідовне іменування, видима власність і історія аудиту. Найбільш недооцінена функція продуктивності в ZFS — організація, яка знає, що вона попросила ZFS робити.
Чек-листи / покроковий план
Checklist A: Remove a snapshot blocked by holds (safely)
- Спробуйте destroy, щоб зафіксувати точне повідомлення про помилку.
- Перелічіть holds за допомогою
zfs holds. - Визначте власника кожного тега hold (backup, replication, compliance).
- Пауза/координація будь-якого робочого процесу, що знову додасть hold.
- Звільніть holds командою
zfs release <tag> <snapshot>для кожного тегу. - Знищіть снапшот.
- Перевірте список снапшотів і облік простору.
Checklist B: Remove a snapshot blocked by clones
- Підтвердьте повідомлення «has dependent clones» або знайдіть origin, що посилаються на снапшот.
- Перелічіть клони за допомогою
zfs get origin -rі зіставте зі снапшотом. - Для кожного клона: вирішіть — знищувати чи промотувати.
- Якщо знищувати: використайте
zfs destroy -rна датасеті клона (не на снапшоті). - Якщо промотувати: виконайте
zfs promoteта повторно перевірте залежності. - Знищіть оригінальний снапшот, коли залежності зникнуть.
Checklist C: Space isn’t freeing after snapshot deletion
- Перевірте
usedbysnapshotsна піддереві датасетів. - Визначте важкі снапшоти через
zfs list -t snapshot -o used. - Перевірте наявність залишкових holds і клонів.
- Підтвердьте, що ви видаляли снапшоти в правильних датасетах (рекурсія має значення).
- Пошукайте інші посилання: новіші снапшоти, клони або сам живий датасет.
- Перевірте рівень пулу на вільний простір та reservation/refreservation, якщо це застосовно.
Друга жартівлива ремарка (остання): найшвидший спосіб зменшити кількість снапшотів — rm -rf /, але це також чудовий спосіб зменшити кількість працівників.
Поширені помилки (симптоми + виправлення)
Mistake 1: Releasing holds without coordinating with replication/backup
Симптом: Снапшоти видаляються, потім реплікаційні задачі падають або бекапи скаржаться на відсутні інкрементні бази.
Виправлення: Визначте, чому існує hold. Якщо це реплікаційний анкер, або завершите реплікаційний цикл спочатку, або відрегулюєте стратегію реплікації, щоб використовувати іншу базу. В деяких середовищах правильне рішення — тимчасово зупинити службу реплікації, почистити, а потім перезапустити з новою базою.
Mistake 2: Destroying recursively when you meant a single dataset snapshot
Симптом: Багато датасетів втрачають снапшоти одночасно. Розробники питають, куди поділась їхня «точка відновлення».
Виправлення: Перед використанням -r перелічте снапшоти в піддереві і підтвердіть, що іменування послідовне. Якщо середовище використовує змішане іменування снапшотів, уникайте рекурсивних destroy і цільте конкретні датасети.
Mistake 3: Confusing snapshot USED with “how big the snapshot is”
Симптом: Ви видаляєте снапшот з USED=0 і чекаєте, що простір повернеться; нічого не змінюється, або ви видаляєте не ті снапшоти першими.
Виправлення: Зрозумійте, що USED — це унікальний простір, що приписується цьому снапшоту. Снапшот з низьким USED може бути критично важливим як інкрементна база; снапшот з високим USED — там, де ви отримаєте простір назад.
Mistake 4: Forgetting clones exist (or not recognizing them)
Симптом: Помилки «dependent clones» або простір не звільняється, незважаючи на обрізку снапшотів.
Виправлення: Шукайте датасети з origin, що вказує на снапшот. Вирішіть: знищувати чи промотувати. Впровадьте правила життєвого циклу клонів, щоб це не повторювалося.
Mistake 5: Deleting snapshots that automation recreates
Симптом: Ви знищуєте снапшоти, і вони з’являються знову з новими timestamp.
Виправлення: Знайдіть і змініть планувальник/політику, що їх створює. Видалення снапшоту — це дія очищення, а не політика утримання. Політика утримання живе в рушії політик.
Mistake 6: Ignoring dataset reservations and refreservations
Симптом: Пул все ще виглядає заповненим після значущого видалення снапшотів, або датасети не можуть виділити простір, незважаючи на наявність «вільного» десь ще.
Виправлення: Перевірте властивості reservation і refreservation. Резерви можуть робити простір «недоступним». Налаштовуйте обережно — резерви часто стоять на захисті критичних робочих навантажень.
Mistake 7: Fighting “busy” snapshots with force instead of patience and coordination
Симптом: Destroy не вдається з повідомленням «dataset is busy» під час вікон реплікації або бекапу.
Виправлення: Визначте активні пайплайни zfs send/receive. Або дочекайтеся завершення, або координуйте їх зупинку. Постійні спроби destroy в циклі лише додають хаосу.
FAQ
1) What does zfs release actually do?
Він знімає іменований тег hold зі снапшоту. Holds забороняють знищення снапшоту. Якщо снапшот має кілька hold’ів, потрібно звільнити їх усі (інакше залишкові holds і надалі блокуватимуть destroy).
2) Why does ZFS allow holds at all? It feels like it’s fighting me.
Тому що в реальних операціях автоматизація й люди помиляються. Holds — це огорожі: «цей снапшот потрібен для бекапу/реплікації/відповідності». Без них скрипт очищення може видалити ваші точки відновлення швидше, ніж ваша команда реагування встигне щось зробити.
3) I released holds and destroyed the snapshot. Why didn’t I get space back?
Тому що блоки можуть усе ще посилатися новіші снапшоти, клони або ж сама жива файлов система. Використовуйте zfs list з usedbysnapshots і сортуйте снапшоти за used, щоб знайти, де реально закріплений простір.
4) What’s the difference between a snapshot and a bookmark?
Снапшот включає повні метадані контрольної точки. Bookmark — це легке посилання, здебільшого використовуване як інкрементна база для реплікації. Знищення bookmark не звільнить простір снапшоту, бо це не снапшот; знищення снапшоту може звільнити простір, якщо блоки більше ніде не посилаються.
5) How do I know whether a snapshot is kept because of clones?
Шукайте датасети, чиє origin дорівнює цьому снапшоту. Якщо такі є, снапшот є origin і не може бути знищений, поки ці клони не знищать або не буде виконана промоція.
6) Is it safe to use zfs destroy -r on a snapshot name?
Це може бути безпечно, якщо ви навмисно знищуєте той снапшот у чітко зрозумілому дереві датасетів з послідовним іменуванням. Це небезпечно, якщо дочірні датасети мають інше значення або інших власників. «Рекурсивно» — це не флажок зручності, це множник сфери впливу.
7) What’s the safest way to clean up snapshots in a replicated environment?
Приймайте рішення про утримання в одному джерелі істини (source-of-truth), кооперуйте вікна реплікації і уникайте видалення інкрементних баз, які потрібні реплікації. На практиці це означає: зрозуміти очікування вашого інструмента реплікації, поважати теги hold, які він ставить, і прибирати в контрольованому вікні змін, коли потрібно «вламувати скло».
8) Can I force-destroy a held snapshot?
Не в сенсі «переписати hold’и». Правильний метод — звільнити holds. Якщо ви не контролюєте holds (наприклад, їх наклала служба відповідності), ваша реальна робота — управління: з’ясувати, хто володіє політикою hold і за яких умов їх можна звільнити.
9) Why do I get “snapshot has dependent clones” when I don’t remember creating clones?
Тому що хтось інший їх створив. Інструменти віртуалізації, CI-пайплайни, самообслуговування розробників і деякі робочі процеси бекапу можуть створювати клони. Імена датасетів і властивість origin підкажуть, що пов’язано — навіть якщо ніхто не пам’ятає.
10) How do I prevent “undeletable snapshots” from happening again?
Стандартизувати теги hold, ввести життєвий цикл клонів (термін дії/власництво) і робити зміни політики утримання явними і переглянутими. Технічно ZFS робить правильну річ; операційно вам потрібно переконатися, що правильні люди та системи встановлюють ці обмеження.
Висновок
У ZFS снапшоти не є незнищуваними. Вони — підзвітні. Якщо снапшот не хоче померти, це тому, що щось ще на нього покладається — це задумано. Практичний шлях завжди однаковий: прочитайте точну помилку, перевірте holds, перевірте клони, потім перевірте, чи автоматизація не відтворює те, що ви видаляєте. Коли ви почнете трактувати снапшоти як частину графа залежностей, а не як «старі файли», zfs release перестане бути містичною інкантацією і стане тим, чим він є: контрольованим способом прибрати блокувальний замок.
Робіть нудні перевірки спочатку, координуйтеся з власниками реплікації/бекапу і будьте явними щодо сфери дії. ZFS зустріне вас наполовину — відразу після того, як переконається, що ви не збираєтеся видаляти єдину рятувальну шхуну.