Ланцюги клонів — це одна з тих можливостей ZFS, яка здається фокусом доти, поки не настане день, коли ви не зможете видалити знімок, не вдається звільнити простір, а ваша робота реплікації починає тягнути історію, яку ви клянетесь видаляли минулого кварталу. Інструмент, який виведе вас із цього вузла, — zfs promote. Це не гламурно, але це різниця між «приберу це після обіду» і «чому дзвінок на чергування розплавляється?»
Ця стаття написана з боку продакшну: там, де датасети мають власників, SLA мають зуби, і ви під час інцидентної наради виявляєте нові залежності клонів. Ми зануримось достатньо глибоко, щоб бути точними, але не так академічно, щоб ви не могли це застосувати о 3-й ночі.
Що фактично робить zfs promote
У ZFS клон — це записуваний датасет, створений зі знімка. Знімок — це «origin» для цього клону. Під капотом клон спочатку ділиться блоками зі своїм origin-знімком і відгалужується по мірі запису нових даних (класична поведінка copy-on-write).
Ключовий операційний наслідок: клон створює залежність. Доки існує клон, origin-знімок не можна знищити, тому що ZFS все ще потребує його, щоб уявити початковий стан клону. Саме тому іноді ви натрапляєте на стіну «cannot destroy snapshot: snapshot has dependent clones».
zfs promote — це аварійний вихід: він обертає залежність між клоном і його origin. Після промоції клон стає «основним» датасетом, а старий батько стає залежним клонном (точніше: origin-зв’язок перевертається, тому просунутий датасет більше не залежить від старого origin-знімка).
Уявіть це як зміну того, який датасет вважається предком у відношенні origin. Ви не копіюєте дані; ви змінюєте, який знімок вважається опорною точкою для зв’язку клонів. Ось чому промоція швидка: це операція над метаданими, а не переписування даних.
Одне речення, яке можна повторювати під час вікна технічного обслуговування: promote змінює, хто від кого залежить; воно не «зливає» датасети.
Перший жарт (короткий і болісно точний): якщо ви ніколи не сказали «це просто клон» і відразу не пошкодували, вітаю з мирною і підозріло короткою кар’єрою в зберіганні даних.
Ключові терміни, які треба тримати в голові
- Знімок: лише для читання точка в часі датасету.
- Клон: записуваний датасет, створений зі знімка.
- Origin: знімок, від якого створено клон (видно через властивість
origin). - Ланцюг клонів: коли клон має знімки, і з цих знімків створюють нові клони, формуючи граф залежностей.
- Промоція: перевертання залежності origin, так що просунутий датасет більше не блокується старим предком.
Ланцюги клонів: сімейне дерево, яке ви не мали на меті створити
Простий випадок виглядає так:
pool/appмає знімокpool/app@baselinepool/app_cloneстворено зpool/app@baseline
На цьому етапі pool/app@baseline зафіксовано. Ви не можете його знищити, поки існує pool/app_clone, бо цей знімок визначає початковий стан клону.
Тепер пройшов час і людська креативність. Хтось робить знімки клону. Хтось створює ще один клон із клону. Хтось перейменовує датасети. Хтось реплікує на DR-пул. Простий двохвузловий зв’язок стає малою екосистемою.
У продакшні ланцюги клонів зазвичай виникають у трьох передбачуваних місцях:
- Шаблони віртуальних машин і золоті образи: базовий знімок датасету породжує десятки клонів (диски ВМ), далі нові «шаблони» клонують з цих клонів, бо це було зручно.
- CI/CD середовища: епhemeral клони створюються під кожну збірку, але базові знімки зберігаються «на всякий випадок», і згодом стають критичними для бізнесу.
- Освіження баз даних: знімок продакшну клонують у стенд, стенд стає «місцем для виправлень», і раптом у стенду є знімки та діти, які треба зберегти.
Операційна пастка: ланцюги клонів можуть створювати враження, що пул «підтікає» простором. Ви видаляєте старі знімки, але «USED» ледве рухається. Ви знищуєте те, що здається останнім залежним датасетом, а інший все ще фіксує origin-знімок. Тим часом політика утримання тихо перетворюється на «вічно».
Чому промоція важлива в реальному житті
Промоція дозволяє вам:
- Звільнити старіший датасет для видалення, зберігши новіший датасет.
- Перефокусувати походження робочого навантаження на датасет, який зараз дійсно важливий.
- Очистити дерево знімків, де «батьківський» датасет мертвий, але його знімок все ще блокує все інше.
- Зробити процеси реплікації більш передбачуваними, стабілізувавши, який датасет є авторитетним джерелом.
Цікаві факти & історичний контекст
- Клони ZFS існували до сучасного буму контейнерів: клони вже були практичним способом швидко піднімати записувані копії задовго до того, як «copy-on-write шари» стали модним словом в інших екосистемах.
- Промоція з’явилася тому, що видалення цінніше за створення: клонування просте; безпечний прибирання вимагало команди першого класу.
- «Origin» — це властивість, а не відчуття: ZFS явно записує origin-знімок, саме тому ви можете запитувати і логічно аналізувати залежності, а не гадати.
- Ланцюги клонів — це графи, а не списки: один знімок може мати кілька клонів; кожен клон може мати свої знімки і клони. Люди кажуть «ланцюг», бо він здається лінійним, поки таким не стане.
- Простір утримується посиланнями на блоки, а не вашими намірами: видалення знімка звільняє лише ті блоки, на які більше ніхто не посилається. Клони — це «десь ще».
- Промоція зазвичай метадані: вона швидка, бо ZFS регулює облік походження, а не копіює терабайти. (Вона все одно може зайняти час на навантажених системах через синхронізацію і транзакційні групи.)
- Перейменування не змінює походження:
zfs renameзмінює імена; воно не змінює origin-відношення. Ось чому «ми перейменували, отже це нове» стає інцидентом по зберіганню. - Політики збереження знімків часто ігнорують клони: саморобні скрипти утилення знімків зазвичай знищують найстаріші — потім натрапляють на залежний клон і зупиняються — або ще гірше, частково виконуються і залишають безлад.
Коли варто промотувати (і коли не варто)
Промотуйте коли…
- Ви хочете видалити початковий датасет (або його старі знімки), але на ньому залежать клони.
- Клон став реальним робочим навантаженням, а оригінальний датасет тепер «лише історія».
- Ви успадкували пул, де поточний продакшн — це клон клона зі знімка 2019 року, і ваша політика утримання фактично музей.
- Потрібно розірвати залежність, щоб видалення знімків або обрізка реплікації могли виконатися.
Не промотуйте коли…
- Ви не впевнені, який датасет є авторитетним джерелом і upstream-реплікація очікує конкретної лінії походження.
- У вас є автоматизація, яка припускає, що певний датасет — батько, і використовує
originабо умовні іменування як логіку. - Ви намагаєтесь «злити зміни назад» у батька. Промоція не зливає; вона лише переставляє, хто є origin.
Другий жарт (бо всім потрібен ще один): Промоція неправильного датасету — як «reply all» в електронній пошті: технічно вражає, соціально дорого і миттєво незабутньо для всіх.
Практичні завдання з командами (і що означає їхній вивід)
Це реальні операційні завдання: «покажи залежність», «підтверди, який знімок зафіксовано», «безпечно промотувати», «провалідовати після». Команди припускають пул з ім’ям tank і датасети на кшталт tank/app. Налаштуйте під своє середовище.
Завдання 1: Знайти клони та їх origin
cr0x@server:~$ zfs list -t filesystem,volume -o name,origin
NAME ORIGIN
tank/app -
tank/app-clone tank/app@baseline
tank/db -
tank/db-staging tank/db@weekly-2025w51
Тлумачення: Будь-який датасет з origin, відмінним від -, — це клон. Тут tank/app-clone залежить від tank/app@baseline.
Завдання 2: Побачити, який знімок відмовляється померти (помилка залежності)
cr0x@server:~$ zfs destroy tank/app@baseline
cannot destroy 'tank/app@baseline': snapshot has dependent clones
use '-R' to destroy the following datasets:
tank/app-clone
Тлумачення: ZFS точно каже, що зафіксовано. Ви можете знищити клон (-R рекурсивно знищить), або промотувати клон, щоб видалити стару історію origin без руйнування активного робочого навантаження.
Завдання 3: Показати простір знімка і «чому він все ще зайнятий»
cr0x@server:~$ zfs list -t snapshot -o name,used,refer,creation -s creation tank/app
NAME USED REFER CREATION
tank/app@baseline 0B 5.20G Mon Nov 10 09:12 2025
tank/app@post-upgrade 88M 5.45G Tue Nov 18 14:03 2025
Тлумачення: USED знімка — це простір, унікально належний цьому знімку порівняно з живим датасетом, а не загальний простір, зафіксований його існуванням. Клони все одно можуть змусити цей знімок існувати, навіть якщо він показує «0B».
Завдання 4: Перевірити облік простору датасету, що вказує на клони/знімки
cr0x@server:~$ zfs get -H -o name,property,value used,usedbysnapshots,usedbychildren,usedbydataset tank/app
tank/app used 220G
tank/app usedbysnapshots 12G
tank/app usedbychildren 180G
tank/app usedbydataset 28G
Тлумачення: Якщо usedbychildren великий, діти датасету (включно з клонованими деінде) тримають простір. Якщо usedbysnapshots великий, підозрюйте збереження знімків.
Завдання 5: Знайти, де змонтовано клон (щоб не промотувати не те)
cr0x@server:~$ zfs get -H -o name,value mountpoint tank/app tank/app-clone
tank/app /srv/app
tank/app-clone /srv/app-staging
Тлумачення: Так ви прив’язуєте ім’я датасету до реального робочого навантаження. Перед промоцією підтвердіть, який з них дійсно пише в production.
Завдання 6: Промотувати клон (основна операція)
cr0x@server:~$ sudo zfs promote tank/app-clone
Тлумачення: Після цього tank/app-clone стане незалежним від tank/app@baseline в тому сенсі, який важливий операційно: старий «батько» стане залежним у відношенні origin.
Завдання 7: Перевірити origin після промоції
cr0x@server:~$ zfs list -o name,origin tank/app tank/app-clone
NAME ORIGIN
tank/app tank/app-clone@baseline
tank/app-clone -
Тлумачення: Просунутий датасет тепер не має origin. Старий батько вказує назад на знімок просунутого датасету. Це і є переворот. Це також пояснює, чому промоція може створювати/вимагати відповідного посилання на знімок у лінії просунутого датасету.
Завдання 8: Тепер видаліть стару історію знімків (очищення)
cr0x@server:~$ sudo zfs destroy tank/app@baseline
cannot destroy 'tank/app@baseline': snapshot has dependent clones
Тлумачення: Якщо ви все ще бачите цю помилку, можливо, існує більше одного клона або глибший граф. Промоція вирішує одне відношення; вона не розплутує автоматично всі залежності, якщо кілька клонів прив’язані до того ж знімка.
Завдання 9: Перерахувати всі клони знімка (картографування залежностей)
cr0x@server:~$ zfs get -H -o name,value clones tank/app@baseline
tank/app@baseline tank/app-clone,tank/app-ci-112,tank/app-ci-113
Тлумачення: Це каже, хто фіксує цей знімок. Ви зможете його знищити лише тоді, коли жоден із них не існує (або кожен буде належним чином промотований і лінія походження оновлена).
Завдання 10: Безпечно перейменувати після промоції (стабілізація імен)
cr0x@server:~$ sudo zfs rename tank/app tank/app-old
cr0x@server:~$ sudo zfs rename tank/app-clone tank/app
Тлумачення: Промоція змінює походження; перейменування змінює імена, які використовують ваші інструменти та люди. На практиці часто промотують, а потім перейменовують, щоб production залишався на канонічному імені датасету.
Завдання 11: Підтвердити, що mountpoint не змінився (або виправити)
cr0x@server:~$ zfs get -H -o name,value mountpoint tank/app tank/app-old
tank/app /srv/app
tank/app-old /srv/app-staging
Тлумачення: Перейменування не завжди магічно робить те, що ви хочете з mountpoint, якщо вони були явно встановлені. Підтвердіть і встановіть їх свідомо.
cr0x@server:~$ sudo zfs set mountpoint=/srv/app tank/app
cr0x@server:~$ sudo zfs set mountpoint=/srv/app-old tank/app-old
Завдання 12: Перевірити ефект «зафіксованого простору» після очищення
cr0x@server:~$ zfs list -o name,used,usedbysnapshots,usedbychildren,usedbydataset tank/app-old
NAME USED USEDBYSNAPSHOTS USEDBYCHILDREN USEDBYDATASET
tank/app-old 28G 0B 0B 28G
Тлумачення: Старий датасет тепер звичайний (або клон) без дітей/знімків, що тримають простір. Якщо ви виводите його з експлуатації, тепер простіше виконувати знімки/знищення за політикою.
Завдання 13: Знайти всі клони в піддереві (аудит перед обслуговуванням)
cr0x@server:~$ zfs list -r -o name,origin tank | awk '$2 != "-" {print}'
tank/app-ci-112 tank/app@baseline
tank/app-ci-113 tank/app@baseline
tank/db-staging tank/db@weekly-2025w51
Тлумачення: Це швидкий і брудний інвентар. У більших середовищах розростання клонів рідко документується; ви виявляєте його, питаючи ZFS, а не Slack.
Завдання 14: Перевірити холди, що перешкоджають знищенню знімків (інша проблема, схожий симптом)
cr0x@server:~$ zfs holds tank/app@baseline
NAME TAG TIMESTAMP
tank/app@baseline keep Wed Dec 10 10:21 2025
Тлумачення: Якщо знищення не вдається, але клони не винні, можливо, існує користувацький холд. Промоція вам тут не допоможе; потрібно звільнити холд.
cr0x@server:~$ sudo zfs release keep tank/app@baseline
Завдання 15: Прогон «знищити рекурсивно» з zfs destroy -nvp
cr0x@server:~$ sudo zfs destroy -nvp tank/app@baseline
would destroy tank/app@baseline
would destroy tank/app-ci-112
would destroy tank/app-ci-113
would reclaim 41.2G
Тлумачення: Так ви уникнете кар’єрного кроку стирання CI-середовища, яке хтось тихо перетворив на продакшн минулого року.
Реплікація та бекапи: zfs send/receive з клонованими даними
Ланцюги клонів ускладнюють не лише видалення; вони ускладнюють реплікацію. Як тільки ви покладаєтесь на інкрементальні відправки, ви неявно приймаєте лінію походження як контракт: «цей датасет на приймачі ділиться історією знімків з відправником». Клони вводять форки в цю історію.
Що зазвичай йде не так
Дві класичні несподіванки:
- Реплікація надсилає більше, ніж очікувалося, бо ви випадково реплікували не ту гілку або зберегли origin-знімок живим, тож приймач також мусить його тримати.
- Реплікація завершується помилкою «incremental source does not match», бо хтось промотував/перейменував на одній стороні, а на іншій — ні, і це порушило очікувану лінію знімків.
Сама по собі промоція не несумісна з реплікацією, але це структурна зміна. Якщо ви промотуєте датасет, що реплікується інкрементально, ставтесь до цього як до міграції схеми: координуйте, документуйте і перевіряйте обидві сторони.
Завдання 16: Переглянути лінію знімків для реплікації (спільна база)
cr0x@server:~$ zfs list -t snapshot -o name,creation -s creation tank/app | tail -n 5
tank/app@replica-2025-12-20 Sat Dec 20 01:00 2025
tank/app@replica-2025-12-21 Sun Dec 21 01:00 2025
tank/app@replica-2025-12-22 Mon Dec 22 01:00 2025
tank/app@replica-2025-12-23 Tue Dec 23 01:00 2025
tank/app@replica-2025-12-24 Wed Dec 24 01:00 2025
Тлумачення: Стабільна, передбачувана схема іменування знімків — ваш друг. Якщо знімки хаотичні, залежності клонів складніше аналізувати і чисто реплікувати.
Завдання 17: Обережно використовувати поток реплікації (приклад інкрементальний)
cr0x@server:~$ sudo zfs send -I tank/app@replica-2025-12-23 tank/app@replica-2025-12-24 | sudo zfs receive -u backup/app
Тлумачення: -I відправляє всі проміжні знімки. Якщо ланцюги клонів і промоції змінили доступні знімки, приймач може не мати очікуваної бази. Завжди підтверджуйте наявність базового знімка на обох кінцях перед запуском інкрементальних відправок.
Завдання 18: Підтвердити origin і ідентичність у вигляді GUID-подібної думки (практична перевірка)
cr0x@server:~$ zfs get -H -o name,property,value origin tank/app backup/app
tank/app origin -
backup/app origin -
Тлумачення: Для інкрементальної реплікації приймач не зобов’язаний бути клоном, але потрібні спільні знімки для інкрементів. Не плутайте «origin» (зв’язок клонів) зі «спільною історією» (набором знімків для реплікації). Вони концептуально перетинаються, але це різні механізми.
Три корпоративні міні-історії
1) Інцидент через неправильне припущення: «видалення знімка звільнить простір»
У великому, звичайному підприємстві, команда додатку вела власний пул ZFS для артефактів збірки й «тимчасових» середовищ. Їхній скрипт утримання простий: знищувати знімки старші за 30 днів. Коли пул підповз до 90% заповнення, вони зробили те, що робить кожен під тиском: видалили більше знімків.
Це нічого не дало. zfs list показував менше знімків, але zpool list не просунувся. Інженер на чергуванні припустив, що ZFS «повільно звільняє простір», і запланував ребут, бо — ну — іноді це допомагає в інших випадках.
Ребут не звільнив простір. Пул досяг ще вищої межі, алокації почали падати, і кілька задач почали виробляти пошкоджені результати (не через те, що ZFS їх пошкодив, а через те, що інструменти вгорі не обробляли ENOSPC коректно). Міст інциденту наповнився звуками людей, які відкривали, що «диск заповнений» — це крос-функціональне хобі.
Виправлення було незручно просте: знімки, які вони видаляли, були зафіксовані кланами, створеними для CI-завдань. Ті клони зберігалися довше ніж 30 днів, бо комусь подобалося мати «відтворювані старі збірки». Скрипт утримання ніколи не перевіряв залежності клонів і тихо пропускав знімки, які не можна було видалити. Це була найгірша помилка — тиха.
Вони провели аудит origin-ів, промотували кілька клонів, що стали постійними середовищами, і видалили дійсно епhemeral датасети клонів. Простір впав одразу, і інцидент закінчився звичними висновками: ZFS зробив саме те, що обіцяв; люди — ні.
2) Оптимізація, що дала зворотний ефект: «давайте клонувати все, щоб зекономити час»
Платформна команда хотіла пришвидшити освіження баз даних для QA. У них був порядок: знімок продакшн щонічно, реплікація, відновлення в QA. Це було повільно, і команда відчувала тиск щодо продуктивності. Хтось придумав хитру ідею: припинити відновлення; просто клонувати останній знімок і віддати QA як записуваний датасет. Освіження стало б миттєвим.
Це працювало блискуче місяць. QA полюбив це. Команда насолоджувалася рідким відчуттям того, що вони вирішили час. Потім простір почав виглядати дивно: утримання знімків не звільняло місце, потоки реплікації збільшились, а DR-пул зберігав історію далеко за межами політики. Усі звинувачували «накладні витрати ZFS». Ніхто не назвав вголос «залежність клонів», поки хтось не спробував видалити древній знімок і не натрапив на помилку dependent-clone.
Справжня проблема була організаційною, а не технічною. Оптимізація перетворила QA-датасети на довгоживучі продакшн-подібні середовища зі своїми звичками знімків. Інженери почали створювати клони з клонів для паралельних тестів. Утворений граф зафіксував місяці продакшн-знімків. Трюк «миттєвого освіження» тихо переписав контракт утримання для всієї системи.
Вони відновились, встановивши чіткі межі: епhemeral клони отримали TTL, примусово керований автоматизацією, а довгоживучі QA-середовища були промотовані, щоб вони більше не якорили історію продакшн-знімків. Вони зберегли оптимізацію, але додали запобіжники: інвентар походжень клонів, явні точки промоції і політику «клони — це cattle, якщо не промотовано».
3) Нудна, але правильна практика, що врятувала день: «називайте знімки свідомо і репетируйте промоцію»
Одна команда, пов’язана з фінансами, вела ферму ВМ на ZFS. У них була звична складність: шаблони, клоновані диски ВМ і купа знімків для патчінгу і відкатів. Нічого особливого — достатньо рухомих частин, щоб зробити інцидент пікантним.
Їхня нудна практика була така: кожен клон диску ВМ мав тег у властивостях ZFS для власника і середовища, кожен шаблон-знімок мав стабільне ім’я, і раз на квартал вони проводили репетицію обслуговування, де навмисно промотували клон у лабораторному пулі і перевіряли, що бекап/реплікація все ще працює.
Одного дня інженер спробував вивести зі служби старий шаблон-датасет. Видалення його знімків не вдалось через залежні клони. Тут команди зазвичай панікують. Але інвентар цієї команди чітко показав, які клони довгоживучі, а які епhemeral. Вони промотували довгоживучі, потім знищили решту і нарешті видалили стару історію шаблону.
Найкраще було не в промоції — а в тому, наскільки це було нудно. Жодного непередбачуваного простою. Жодної археології «хто володіє цим датасетом?». Жодного розвалу реплікації. Зміна в трекері була банальною — найвища похвала для роботи зі сховищем.
Швидкий план діагностики
Це послідовність «у мене 15 хвилин до того, як пул досягне 95% і мій пейджер почне писати поезію». Мета — ідентифікувати, чи вузьке місце — клони, що фіксують знімки, утримання знімків, дочірні датасети або щось інше.
По-перше: підтвердити проблему на рівні пулу і її природу
cr0x@server:~$ zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 7.25T 6.71T 560G - - 38% 92% 1.00x ONLINE -
Тлумачення: Високий CAP — це надзвичайна ситуація. Фрагментація може мати значення, але зазвичай вона не перша причина того, чому видалення не звільнило простір.
По-друге: знайти найбільших споживачів і чи це знімки або діти
cr0x@server:~$ zfs list -o name,used,usedbysnapshots,usedbychildren,usedbydataset -S used | head -n 10
NAME USED USEDBYSNAPSHOTS USEDBYCHILDREN USEDBYDATASET
tank/vm 4.90T 900G 3.80T 200G
tank/app 220G 12G 180G 28G
tank/db 140G 60G 0B 80G
Тлумачення: Якщо домінує usedbychildren, ваш простір у дочірніх (часто клони). Якщо домінує usedbysnapshots, підозрюйте утримання знімків. Якщо домінує usedbydataset, живі дані великі і ви видаляєте не те.
По-третє: перевірити залежності клонів, що фіксують старі знімки
cr0x@server:~$ zfs list -t filesystem,volume -o name,origin -r tank/vm | awk '$2 != "-" {print}' | head
tank/vm/qa-01 tank/vm/template@golden
tank/vm/qa-02 tank/vm/template@golden
tank/vm/prod-17 tank/vm/template@2025q3
Тлумачення: Це каже, чи існують клони і що вони фіксують. Якщо не можете видалити знімок, зазвичай це причина.
По-четверте: для конкретного зафіксованого знімка перерахувати його клони
cr0x@server:~$ zfs get -H -o value clones tank/vm/template@golden
tank/vm/qa-01,tank/vm/qa-02,tank/vm/ci-881,tank/vm/ci-882
Тлумачення: Тепер у вас є список справ: знищити епhemeral клони, промотувати ті, що мають жити далі, і тільки тоді видаляти старий знімок.
По-п’яте: перевірити тиск I/O перед важкими операціями
cr0x@server:~$ zpool iostat -v 1 3
capacity operations bandwidth
pool alloc free read write read write
-------------------------- ----- ----- ----- ----- ----- -----
tank 6.71T 560G 380 520 42.1M 88.3M
mirror-0 3.35T 280G 190 260 21.0M 44.1M
sda - - 95 130 10.5M 22.1M
sdb - - 95 130 10.5M 22.0M
mirror-1 3.36T 280G 190 260 21.1M 44.2M
sdc - - 95 130 10.6M 22.1M
sdd - - 95 130 10.5M 22.1M
Тлумачення: Промоції зазвичай швидкі, але операції очищення, що викликають багато звільнень блоків, можуть поєднатися з інтенсивними записами і погіршити затримки. Якщо ви й так на межі, плануйте очищення або обмежуйте навантаження.
Поширені помилки, симптоми та виправлення
Помилка 1: Прагнути знищити origin-знімок, не розібравшись з клонами
Симптом: cannot destroy ... snapshot has dependent clones
Виправлення: Визначте залежні клони за допомогою zfs get clones pool/ds@snap. Прийміть рішення: видалити клони (епhemeral) або промотувати клони (довгоживучі), потім повторіть спробу знищення знімка.
Помилка 2: Промотувати датасет, який планували видалити
Симптом: Після промоції «не той» датасет має origin=-, і ваша автоматизація вказує на неправильний mountpoint.
Виправлення: До промоції підтвердіть mountpoint і активних записувачів. Використовуйте zfs get mountpoint і системні перевірки (який процес пише куди). Якщо вже промотовано, все ще можна відновити, перейменувавши датасети і виправивши mountpoint; дані не втрачені, але ваша лінійка змінена, тож оновіть рукописи і налаштування реплікації.
Помилка 3: Припущення, що промоція одразу звільнить простір
Симптом: Ви промотували клон, але використання пула не впало.
Виправлення: Промоція нічого не видаляє. Вона лише дозволяє вам знищити старі знімки/датасети, які раніше були зафіксовані. Дійте далі: знищіть застарілі знімки/датасети після перевірки, що залежності зникли.
Помилка 4: Плутанина між «USED знімка» і «простором, зафіксованим знімком»
Симптом: Знімок показує USED=0B, але його знищення блокується і/або він здається тим, що фіксує багато простору.
Виправлення: Використовуйте zfs get clones і властивості usedby* на рівні датасету, щоб зрозуміти простір. USED знімка — не повний облік того, що він дозволяє іншим датасетам тримати.
Помилка 5: Дозволити розростанню клонів стати політикою випадково
Симптом: Старі «baseline» знімки не можна видалити через роки; реплікація тримає величезні історії; ніхто не знає, що можна видалити.
Виправлення: Додайте метадані (властивості типу owner/env), TTL-автоматизацію для епhemeral клонів і щоквартальний аудит: перерахунок клонів і їх origin-ів, визначення, які потрібно промотувати до незалежних ліній.
Помилка 6: Зламати інкрементальну реплікацію, змінивши лінію походження односторонньо
Симптом: Інкрементальний send падає, бо приймач не має очікуваного базового знімка; після промоції імена й походження знімків не збігаються.
Виправлення: Координуйте промоцію з реплікацією. Перевіряйте спільні знімки на обох кінцях. У деяких випадках потрібно перестворити носій повним send або налаштувати реплікацію на нові бази.
Чеклісти / покроковий план
Чекліст A: «Потрібно видалити старий датасет, але його знімки зафіксовано»
- Визначте датасет і конкретні знімки, які треба видалити.
- Перелічіть клони цих знімків за допомогою
zfs get clones. - Класифікуйте кожен клон: епhemeral (безпечно видалити) або довгоживучий (треба зберегти).
- Для кожного довгоживучого клона підтвердіть, що це саме датасет для збереження (mountpoint, власник, активні записувачі).
- Промотуйте довгоживучі клони (
zfs promote). - Видаліть епhemeral клони (спочатку рекомендовано
zfs destroy -nvp). - Видаліть тепер розблоковані знімки.
- Знищіть або заархівуйте виведений датасет (після фінального знімка за політикою, якщо потрібно).
Чекліст B: «Я промотую клон, який є (або може бути) продакшн»
- Заморозьте вікно змін; повідомте власників додатків і бекапів про зміну лінії походження.
- Перевірте датасет і mountpoint; підтвердіть, що робоче навантаження використовує саме цей mount.
- Зробіть страхувальний знімок батька і клона.
- Задокументуйте вивід
zfs list -o name,originдо зміни. - Запустіть
zfs promote. - Перевірте переворот origin за допомогою
zfs list -o name,origin. - За потреби перейменуйте датасети, щоб відновити канонічні імена.
- Перевірте I/O додатку, mount-і і завдання реплікації.
- Тільки після цього видаляйте старі батьківські знімки/датасети.
Чекліст C: «Потрібно запобігти тому, щоб ланцюги клонів ставали сюрпризом кожен квартал»
- Визначте, які датасети дозволено використовувати як джерела клонів (шаблони, baseline-и).
- Позначайте клони властивостями власника/середовища у ZFS.
- Автоматизуйте TTL-очищення для епhemeral клонів і їхніх знімків.
- Щотижня запускайте аудит: перелікуйте всі датасети з непорожнім
origin. - Переглядайте «зафіксовані знімки»: ті, що мають багато клонів.
- Промотуйте довгоживучі клони свідомо, а не випадково.
FAQ
1) Чи копіює zfs promote дані?
Ні. Промоція — це передусім операція над метаданими, яка змінює відношення origin. Ваші блоки залишаються на місці; ZFS змінює облік походження і залежностей.
2) Чи звільнить промоція клонів простір одразу?
Ні. Промоція дозволяє вам видалити знімки/датасети, які раніше були зафіксовані. Простір звільняється, коли ви знищите тепер непотрібні знімки/датасети і їхні блоки більше ніде не будуть посилатися.
3) Чи можна промотувати датасет з дітьми?
На практиці — так, але будьте обережні: дочірні датасети, знімки і клони можуть зробити граф залежностей більшим, ніж ви думаєте. Проведіть аудит піддерева спочатку (zfs list -r -o name,origin), щоб не загнатися в ще більш заплутану ситуацію.
4) Що відбувається з властивістю origin після промоції?
Просунутий датасет покаже origin=-. Датасет, який раніше був батьком, зазвичай отримає origin, що вказує на знімок просунутого датасету (відношення перевертається).
5) Чи безпечно промотувати на живій системі?
Це часто роблять на живих системах, але «безпечно» залежить від того, що ще відбувається: інтенсивний I/O, запуски реплікації і автоматизація, що реагує на зміни датасетів, можуть зробити просту операцію шумною. Промотуйте в контрольоване вікно і перевіряйте mount-и та інструменти після.
6) Чому не можу знищити знімок, хоча клонів немає?
Дві часті причини: існує користувацький холд (zfs holds), або знімок потрібен для інкрементальної реплікації (не технічно блокер у ZFS, але ваш процес може залежати від нього). ZFS сам підкаже, якщо знищенню заважають клони; холди — окрема справа.
7) Чи допомагає перейменування датасету з залежностями клонів?
Ні. Перейменування змінює ім’я, а не походження. Якщо знімок зафіксовано клонами, перейменування не зніме фіксацію. Залежність змінюється через промоцію або знищення клонів.
8) Як знайти всі знімки, що мають клони?
Можна перебрати знімки і перевірити властивість clones. Практично почніть з датасетів, де простір «завис», і опитуйте їх старі знімки на наявність клону. У багатьох середовищах швидше спочатку перелічити всі датасети з виставленим origin, а потім зіставити їх зі знімками походження.
9) Чи може промоція зламати інкрементальну реплікацію?
Може, якщо ваш процес реплікації припускає певну лінію знімків і ви змінюєте її на відправнику без координації з приймачем. Розглядайте промоцію як зміну лінії походження: перевіряйте спільні знімки і будьте готові до перевідправки повного набору або перенастроювання баз.
10) Який найнадійніший спосіб потренуватися промоції?
Робіть це на тестовому пулі з невеликим датасетом, що імітує вашу структуру: створіть знімок, клон, додайте знімки по обидва боки, створіть клон-від-клона, потім промотуйте і спостерігайте перевороти origin. М’язова пам’ять окупиться, коли будете робити це під тиском.
Висновок
zfs promote — одна з тих команд, що здаються вузьким куточком ZFS, допоки ви не зрозумієте, що це ключ до безпечного видалення речей у світі, повному клонів. Промоція не переміщує дані; вона переміщує відповідальність. Вона дозволяє вам сказати: «цей датасет — нова істина», а потім чисто вивести стару істину, не зрізавши теперішнє.
Підхід виробничого рівня — послідовний: інвентаризуйте походження клонів, промотуйте свідомо, перевіряйте після і тільки потім знищуйте знімки і датасети, які мали бути виведені з експлуатації. Якщо діяти так, ланцюги клонів перестануть лякати. Вони стануть ще одним інструментом, яким можна користуватися — упевнено — без сплати прихованих відсотків з часом.