Оновлення OpenZFS зазвичай не ламаються через поганий код. Вони ламаються через людський оптимізм, короткі вікна змін і тонку сумісність. Поломка здебільшого не драматична — вона тиха: реплікація припиняє працювати через два дні, boot pool не імпортується після оновлення ядра або ви ввімкнули feature flag «бо він був» і тепер пул застряг на старих хостах.
Якщо ви керуєте продуктивним сховищем, ви не просто «оновлюєте ZFS». Ви оновлюєте екосистему: модулі ядра, утиліти userland, підтримку завантажувача, feature flags пулів, властивості датасетів, моніторинг і всі скрипти, що припускають поведінку минулого року. Це чекліст, який не дає цій екосистемі підвести вас.
Що насправді ламається під час оновлень OpenZFS
Більшість гайдів з «оновлення ZFS» зосереджуються на команді zpool upgrade. Це як зосереджуватись на ремені безпеки літака, ігноруючи двигуни. Реальні випадки поломок групуються в кілька категорій:
1) Ви оновили userland, але не модуль ядра (або навпаки)
На Linux OpenZFS часто постачається як модуль ядра через DKMS або пакети, що відстежують kABI. Якщо ядро оновилося, а модуль не зібрався або не завантажився — ZFS у вас відсутній. Якщо утиліти userland новіші за модуль, ви отримаєте попередження, дивну поведінку або відсутні можливості. На FreeBSD ZFS зазвичай інтегровано, але все одно можна створити нерівність версій між boot environment або jail.
2) Feature flags роблять пул «новішим» за деякі хости
OpenZFS використовує feature flags у пулах. Після їх увімкнення деякі прапори стають «active» і їх не вимкнути. Практичний наслідок: увімкнення прапора може назавжди заблокувати імпорт пулу на старіших реалізаціях OpenZFS. Це стає проблемою, коли «старіша реалізація» — ваш DR-сайт.
3) Boot pool і підтримка завантажувача — це окремий всесвіт
Root-on-ZFS чудовий, поки ви не дізнаєтесь, що ваш завантажувач розуміє лише підмножину можливостей OpenZFS. Пул може бути цілком здоровим, але система не завантажується, бо завантажувач не читає структури на диску, створені новішими фічами. Якщо ви оновлюєте boot pool, план відкату має бути безпроблемним.
4) Сумісність реплікації — це операційний контракт
zfs send/zfs receive — це ваш канал передачі даних. Якщо ви увімкнете фічі або зміните властивості, що змінюють сумісність стріму, ваша реплікація може не працювати, тихо пропускати очікуване або змусити вас повністю перелаштувати seed. «Він все ще робить снапшоти» — не те саме, що «він все ще реплікує».
5) Регресії продуктивності зазвичай — це невідповідність конфігурації
Оновлення можуть змінювати налаштування за замовчуванням, поведінку ARC, патерни prefetch або те, як певні робочі навантаження взаємодіють із компресією, recordsize і special vdevs. Код може бути в порядку; ваш робочий навантаження може просто виявити, що попереднє тонке налаштування було не тим. Потрібна база продуктивності до і після, інакше тиждень буде витрачено на сперечання з графіками.
Одна перефразована ідея від Gene Kim, який усе життя перетворює операційний біль на мову для керівників: надійність походить від швидких, безпечних змін з петлями зворотного зв’язку. Це і є суть цього чекліста — зробіть зміну безпечною, спостережуваною та відкатною.
Цікаві факти та історичний контекст (корисний вид)
- ZFS популяризував енд-ту-енд контрольні суми для даних і метаданих, що змінює ставлення до «мовчазної корупції» порівняно з традиційними RAID-стеками.
- Feature flags OpenZFS замінили старі номери версій пулів, дозволивши реалізаціям розвиватися без єдиної лінійної версії.
- Copy-on-write — причина дешевизни снапшотів, але це також означає, що патерни фрагментації вільного простору можуть здивувати після інтенсивних змін.
- ARC — це не просто кеш; це адаптивний кеш із поведінкою витіснення, що може визначати розмови про пам’ять під змішаними навантаженнями.
- L2ARC — це не читальний кеш так, як багато хто уявляє; це кеш другого рівня з витратами на прогрів та накладними витратами на метадані, що може зашкодити, якщо його неправильно розмірити або розмістити на ненадійних носіях.
- Спеціальні vdev-и (для метаданих і дрібних блоків) можуть бути трансформаційними, але вони також вводять «малі, критичні, швидкі пристрої», що можуть вивести весь пул з ладу, якщо не мати резервування.
- ZFS send стріми еволюціонували, щоб підтримувати властивості, великі блоки, вбудовані дані та відновлювані receive; не кожен receiver розуміє кожен тип стріму.
- Root-on-ZFS набув масового вживання в кількох ОС, бо boot environments разом зі снапшотами роблять оновлення відкатними — коли ви поважаєте обмеження завантажувача.
Підготовка: визначте, що означає «оновлення» у вашому середовищі
Перш ніж торкатися пакетів, відповідайте на три питання. Якщо ви не можете відповісти — ви не оновлюєте, ви кидаєте кості в серверній.
Визначте обсяг оновлення
- Лише userland? Утиліти на кшталт
zfs,zpool,zed(демон подій). - Модуль ядра? На Linux: версія ZFS-модуля, SPL, стан збірки DKMS, initramfs.
- Feature flags пулу? Чи будете ви запускати
zpool upgradeабо залишите пули як є. - Зміни властивостей датасетів? Деякі команди «оновлюють» ще й увімкненням компресії всюди. Це не оновлення. Це міграція поведінки I/O.
Перерахуйте поверхню сумісності
Перелічіть кожну систему, яка може імпортувати цей пул або отримувати стріми реплікації:
- Початкові хости
- DR-хости
- Цілі резервного копіювання
- Форензичні/відновлювальні робочі станції (так, хтось рано чи пізно спробує імпортувати пул на ноутбуку)
- Можливості завантажувача, якщо це boot pool
Задокументуйте стратегію відкату
Є лише дві дорослі стратегії відкату:
- Відкат boot environment (system ZFS, root-on-ZFS): створіть снапшот/клон кореневого датасету і зберігайте відому добру boot environment, вибірну при завантаженні.
- Зовнішній відкат (не-root ZFS): зберігайте старі пакети, старе ядро доступними і ніколи не вмикайте незворотні фічі пулу, поки не будете впевнені.
Жарт №1: ZFS — як професійна кухня — усе марковано, має контрольно-суму і організовано, але один стажер усе одно може підпалити місце.
Практичні завдання: команди, вивід і рішення (12+)
Це завдання для продакшену. Кожне містить команду, приклад виводу, що це означає і яке рішення. Запустіть їх до і після оновлення. Зберігайте вивід у вашому change ticket. Майбутній ви буде вдячний, і майбутній ви зазвичай тримає пейджер.
Завдання 1: Підтвердіть, який ZFS у вас фактично запущений
cr0x@server:~$ zfs --version
zfs-2.2.2-1
zfs-kmod-2.2.2-1
Що це означає: Показані версії userland і модуля ядра (варіюється за дистрибутивом). Якщо ви бачите лише userland, перевірте модуль окремо.
Рішення: Якщо версії не збігаються після оновлення — зупиніться і виправте паритет пакетів/модуля перед роботою з пулами.
Завдання 2: Перевірте, чи завантажений модуль ядра (Linux)
cr0x@server:~$ lsmod | grep -E '^zfs '
zfs 8843264 6
Що це означає: Модуль ZFS завантажено; останнє число — «users».
Рішення: Якщо модуль не завантажено — перевірте логи збірки DKMS, initramfs та чи не зламався збірку модуля апдейт ядра.
Завдання 3: Перевірте стан пулу і лічильники помилок перед змінами
cr0x@server:~$ zpool status -x
all pools are healthy
Що це означає: Жодних відомих проблем. Якщо ви бачите інше — маєте роботу перед оновленням.
Рішення: Якщо є помилки контрольної суми, resilvering або деградовані vdev-и: відкладіть оновлення. Виправте пул спочатку, потім оновлюйте.
Завдання 4: Отримайте повний статус, а не лише заспокійливу зведену інформацію
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
status: One or more devices has experienced an unrecoverable error.
action: Determine if the device needs to be replaced, and clear the errors
scan: scrub repaired 0B in 00:12:33 with 0 errors on Thu Dec 19 03:12:01 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz1-0 ONLINE 0 0 0
sda ONLINE 0 0 2 (repairable)
sdb ONLINE 0 0 0
sdc ONLINE 0 0 0
errors: Permanent errors have been detected in the following files:
/tank/vmstore/vm-104-disk-0
Що це означає: «Healthy» може приховувати відремонтовані, але реальні помилки. Постійні помилки показують уражені файли.
Рішення: Розслідуйте та усуньте постійні помилки (відновіть з репліки/резервної копії) перед оновленням. Також оцініть диск sda для заміни.
Завдання 5: Підтвердіть, що у вас були нещодавні scrubs і вони не кричать
cr0x@server:~$ zpool get -H scrub tank
tank scrub scrub repaired 0B in 00:12:33 with 0 errors on Thu Dec 19 03:12:01 2025 -
Що це означає: Результат і час останнього scrub.
Рішення: Якщо scrubs старі або показують помилки — виконайте scrub перед оновленням. Ви хочете відомі добрі дані перш ніж змінювати стек.
Завдання 6: Збережіть feature flags, що зараз увімкнені та активні
cr0x@server:~$ zpool get -H -o name,property,value all tank | grep -E '^tank feature@'
tank feature@async_destroy enabled
tank feature@empty_bpobj active
tank feature@spacemap_histogram enabled
tank feature@extensible_dataset enabled
Що це означає: enabled означає, що пул може його використовувати; active означає, що він використовується на диску.
Рішення: Якщо ви бачите фічі, які не підтримуються DR/backup хостами — не запускайте zpool upgrade поки не побудуєте матрицю сумісності.
Завдання 7: Подивіться, які оновлення взагалі доступні (і не застосовуйте їх сліпо)
cr0x@server:~$ zpool upgrade
This system supports ZFS pool feature flags.
The following pools are formatted with legacy version numbers and can be upgraded:
tank
The following feature flags are supported:
spacemap_histogram
enabled_txg
hole_birth
extensible_dataset
...
Що це означає: Показує підтримувані фічі і чи використовують пули застарілі версії.
Рішення: Оновлення формату пулу — це явне рішення щодо сумісності. Якщо є хоча б шанс імпорту на старіших системах — відкладіть оновлення пулу поки всі системи не будуть оновлені і протестовані.
Завдання 8: Перевірте властивості датасетів, що впливають на продуктивність і реплікацію
cr0x@server:~$ zfs get -r -o name,property,value -s local,received compression,recordsize,atime,xattr,acltype,encryption,keylocation tank
NAME PROPERTY VALUE
tank compression zstd
tank recordsize 128K
tank atime off
tank/vmstore recordsize 16K
tank/vmstore compression lz4
tank/backup atime on
Що це означає: Локальні і отримані властивості, що визначають розкладку на диску, патерни I/O і поведінку.
Рішення: Заморожуйте зміни властивостей під час вікна оновлення. Якщо ви хочете «виправити властивості» — зробіть це окремим зміною з власним планом відкату.
Завдання 9: Перевірте стан снапшотів/реплікації перед оновленням
cr0x@server:~$ zfs list -t snapshot -o name,creation -S creation | head
NAME CREATION
tank/vmstore@autosnap_2025-12-26_0000 Fri Dec 26 00:00 2025
tank/home@autosnap_2025-12-26_0000 Fri Dec 26 00:00 2025
tank@autosnap_2025-12-26_0000 Fri Dec 26 00:00 2025
Що це означає: Снапшоти існують і свіжі.
Рішення: Якщо снапшоти неактуальні — виправте автоматизацію перед оновленням. Відсутність снапшотів означає відсутність швидкого відкату для помилок з даними.
Завдання 10: Перевірте сумісність стріму реплікації на практиці (сухий запуск з resumable receive)
cr0x@server:~$ zfs send -nP tank/vmstore@autosnap_2025-12-26_0000 | head
size 1234567896
Що це означає: -nP оцінює розмір send без відправлення. Якщо це провалюється — у вас проблема на боці відправника.
Рішення: Якщо оцінка провалиться після оновлення — ймовірно, ви натрапили на невідповідність фіч або зміну формату стріму. Розберіться до наступного запланованого запуску реплікації.
Завдання 11: Підтвердіть, що ви справді можете імпортувати пул на оновленому хості (і чому він може не імпортуватись)
cr0x@server:~$ zpool import
pool: tank
id: 1234567890123456789
state: ONLINE
action: The pool can be imported using its name or numeric identifier.
config:
tank ONLINE
raidz1-0 ONLINE
sda ONLINE
sdb ONLINE
sdc ONLINE
Що це означає: Виявлено пул, що можна імпортувати. На реальній системі ви не станете це робити на активному хості, якщо не в режимі відновлення; це корисно на стендбаї чи в rescue-середовищі.
Рішення: Якщо import показує «unsupported features» — ви довели наявність розриву сумісності. Не оновлюйте фічі пулу, доки кожен імпортер не буде готовий.
Завдання 12: Перевірте обмеження boot pool (середовища root-on-ZFS)
cr0x@server:~$ zpool list -o name,size,alloc,free,ashift,health
NAME SIZE ALLOC FREE ASHIFT HEALTH
bpool 1.8G 612M 1.2G 12 ONLINE
rpool 1.8T 1.1T 724G 12 ONLINE
Що це означає: Імовірно, у вас є окремий bpool (boot pool) з консервативними фічами, плюс rpool для кореневої файлової системи.
Рішення: Сприймайте bpool як «сумісне зі завантажувачем сховище». Будьте надзвичайно обережні при його оновленні чи увімкненні фіч.
Завдання 13: Підтвердіть, що ZED працює і буде повідомляти про проблеми
cr0x@server:~$ systemctl status zfs-zed.service --no-pager
● zfs-zed.service - ZFS Event Daemon (zed)
Loaded: loaded (/lib/systemd/system/zfs-zed.service; enabled)
Active: active (running) since Thu 2025-12-26 00:10:11 UTC; 2h 3min ago
Що це означає: Демон подій ZFS активний. Без нього ви можете пропустити події про збій диска і оповіщення про scrubs.
Рішення: Якщо ZED не працює — виправте це перед оновленням. Видимість — частина безпеки.
Завдання 14: Перевірте поведінку ARC до/після (швидка перевірка, а не сліпе тонке налаштування)
cr0x@server:~$ arcstat 1 3
time read miss miss% dmis dm% pmis pm% mmis mm% size c
00:00:01 912 34 3 9 1% 21 2% 4 0% 28.1G 31.9G
00:00:02 877 29 3 8 1% 17 2% 4 0% 28.1G 31.9G
00:00:03 940 35 3 9 1% 22 2% 4 0% 28.1G 31.9G
Що це означає: Рівні промахів і розмір ARC. Різкий стрибок miss% після оновлення може вказувати на зміну поведінки prefetch або тиск пам’яті.
Рішення: Якщо miss% підскакує і підвищується затримка — почніть з перевірки навантаження та пам’яті перед зміною налаштувань.
Завдання 15: Підтвердіть, що оновлення не змінило поводження mount або видимість датасетів
cr0x@server:~$ zfs mount | head
tank /tank
tank/home /tank/home
tank/vmstore /tank/vmstore
Що це означає: Змонтовані датасети і точки монтування.
Рішення: Якщо очікувані датасети не змонтовано після оновлення/перезавантаження — перевірте canmount, mountpoint і чи не змінилось порядку монтування systemd.
Завдання 16: Після оновлення: переконайтесь, що пул все ще чистий і журнал подій не ховає драму
cr0x@server:~$ zpool events -v | tail -n 12
TIME CLASS
Dec 26 02:11:03.123456 2025 sysevent.fs.zfs.config_sync
pool: tank
vdev: /dev/sdb
Dec 26 02:11:04.654321 2025 sysevent.fs.zfs.history_event
history: zpool scrub tank
Що це означає: Останні події ZFS. Корисно після оновлень, щоб побачити, чи зникли пристрої, змінилось multipath або був config sync.
Рішення: Якщо ви бачите повторювані події видалення/додавання пристроїв — зупиніться і розберіться з кабелями, HBA, конфігурацією multipath або змінами найменувань udev перед тим, як довіряти пулу.
Чеклісти / покроковий план (той, який можна виконати о 2:00)
Цей план передбачає, що ви оновлюєте OpenZFS на продакшен-хості. Підлаштуйте під вашу платформу, але не пропускайте логіку. ZFS карає імпровізацію.
Фаза 0: Планування сумісності (зробіть це до вікна змін)
- Запишіть усіх імпортерів. Кожен хост, що може імпортувати пул, включно з DR, backup і rescue-носіями.
- Запишіть усіх отримувачів реплікації. Кожну ціль, що отримує
zfs sendстріми. - Визначте найстарішу версію OpenZFS у цьому наборі. Та версія — ваш мінімум сумісності.
- Вирішіть, чи будете запускати
zpool upgrade. Стандартна відповідь на змішаному середовищі: ні. Спочатку оновлюйте код, потім — фічі. - Для boot pool: ідентифікуйте обмеження завантажувача. Якщо не можете чітко сказати, що може читати ваш завантажувач — забороняйте оновлення boot pool, доки не буде підтверджено безпеку.
- Побудуйте план відкату, що не спирається на надію. Старе ядро доступне, старі пакети доступні, boot environment якщо root-on-ZFS, і задокументований шлях «як отримати шелл» (IPMI/iLO/консоль).
Фаза 1: Перевірки перед зміною (безпосередньо перед)
- Підтвердьте версії ZFS (
zfs --version). - Підтвердьте завантаження модуля (
lsmod | grep zfsна Linux). - Підтвердьте стан пулу (
zpool status -x, потімzpool status -v). - Підтвердьте актуальність scrub (
zpool get scrub). - Зафіксуйте feature flags (
zpool get feature@*або відфільтрований вивід). - Зафіксуйте ключові властивості датасетів (
zfs get -rдля compression/recordsize/atime/encryption). - Підтвердьте, що снапшоти існують і реплікація останньо пройшла успішно (ваші інструменти +
zfs list -t snapshot). - Підтвердьте запас вільного простору. Потрібен оперативний запас для resilver та росту метаданих.
Фаза 2: Виконання оновлення (спочатку код, потім фічі)
- Оновіть пакети. Запишіть версії до/після.
- Перегенеруйте initramfs, якщо потрібно. На Linux ZFS в initramfs важливий для boot pool.
- Перезавантажтеся в межах вікна. Якщо ви не перезавантажуєтесь — ви не тестуєте найскладнішу частину.
- Після завантаження перевірте модуль + імпорт пулу + монтування. Перевірте
zfs mount, сервіси та I/O додатків. - Не запускайте
zpool upgradeу перший день. Спочатку спостерігайте стабільність.
Фаза 3: Перевірка після оновлення (негайно і ще раз через 24 години)
- Перевірте стан пулу і помилки.
- Перевірте ZED і канал оповіщень.
- Запустіть scrub (якщо вікно дозволяє) або заплануйте його найближчим часом.
- Ініціюйте запуск реплікації та перевірте сторону прийому.
- Порівняйте базові показники продуктивності: латентність, IOPS, використання CPU, показники miss ARC.
- Перегляньте
zpool events -vна предмет змін у пристроях.
Фаза 4: Оновлення feature flags (тільки після готовності флоту)
Коли — і лише коли — кожен імпортер і отримувач сумісні з OpenZFS, і ви протестували шляхи відкату, можна розглядати увімкнення нових фіч пулу.
- Перегляньте підтримувані фічі (
zpool upgrade). - Увімкнуйте фічі цілеспрямовано, невеликими наборами, з записом змін.
- Перевірте, що реплікація після цього працює.
- Оновіть документацію «мінімум сумісності». Мінімальна версія вашого флоту щойно змінилася.
Жарт №2: Єдине, що більш постійне за feature flag — пам’ять людини, яка його увімкнула за п’ять хвилин до відпустки.
Швидкий план діагностики
Після оновлення OpenZFS ви зазвичай отримаєте один із трьох сигналів болю: система не завантажується/не імпортується, стало повільно або реплікація не працює. Цей план упорядкований так, щоб швидко знайти вузьке місце, а не філософствувати.
Перше: чи бачить система пул і пристрої?
- Перевірте завантаження модуля:
lsmod | grep zfs(Linux) або підтвердіть, що ядро має ZFS і userland збігаються. - Перевірте стабільність імен пристроїв: пошукайте відсутні диски, змінені WWN, проблеми multipath.
- Перевірте імпортованість:
zpool import(у rescue-середовищі або на стендбаї). - Перевірте стан пулу:
zpool status -vна наявність деградованих vdev-ів і помилок контрольної суми.
Друге: це проблема сумісності/feature flags?
- Якщо пул не імпортується і ви бачите «unsupported feature(s)», зупиніться. Це не питання тонкого налаштування.
- Порівняйте
zpool get feature@*між робочим і тим, що падає хостом. - Для boot-фейлів: підозрюйте обмеження завантажувача, а не «ZFS зламався».
Третє: це регрес продуктивності або проблема I/O-шляху?
- Перевірте латентність на пулі:
zpool iostat -v 1 10(не показано вище, але варто запустити). - Перевірте промахи ARC і тиск пам’яті:
arcstatі системні метрики пам’яті. - Перевірте використання CPU в потоках ядра: високий system CPU може вказувати на накладні витрати на контрольні суми/компресію або патологічний патерн навантаження.
- Перевірте дрейф recordsize/compression: оновлення не змінює існуючі блоки, але може виявити, що «один розмір під усіх» — була брехня.
Четверте: це реплікація/інструменти?
- Запустіть вручну
zfs send -nPі перевірте помилки. - Підтвердіть, що receiver може прийняти стрім (версія/підтримка фіч).
- Перевірте, чи ваша система реплікації правильно парсить вивід, який міг змінитися тонко.
Поширені помилки: симптом → корінна причина → виправлення
1) Симптом: пул не імпортується після оновлення; повідомлення згадує unsupported features
Корінна причина: Фічі пулу були увімкнені на іншому хості (або ви запустили zpool upgrade), і тепер ви намагаєтеся імпортувати на старішу реалізацію OpenZFS.
Виправлення: Оновіть середовище імпорту до сумісної версії OpenZFS. Якщо це DR і ви не можете — єдиний шлях відновлення — відновлення з реплікації/резервної копії, що спрямована на сумісний пул. Більшість активних фіч не вимкнути.
2) Симптом: система завантажується в initramfs або emergency shell; root pool не знайдено
Корінна причина: Модуль ZFS не включено/не зібрано для нового ядра, initramfs позбавлений ZFS або модуль не завантажився.
Виправлення: Завантажтеся з старого ядра через завантажувач (тримайте одне), перебудуйте DKMS/модуль, перебудуйте initramfs і перезавантажтесь. Після цього перевірте паритет zfs --version.
3) Симптом: завантажувач не читає boot pool, але пул імпортується з rescue-носія
Корінна причина: Фічі boot pool не підтримуються завантажувачем. Ви оновили/змінили щось у bpool або використали несумісний ashift/набір фіч для загрузчика.
Виправлення: Відновіть boot pool з відомого доброго снапшота/boot environment, якщо доступно. Інакше перевстановіть завантажувач із сумісним дизайном boot pool (часто: робіть boot pool консервативним і відокремленим).
4) Симптом: реплікація починає падати після оновлення зі стрім-помилками
Корінна причина: Відправник тепер генерує стріми з фічами, які receiver не може прийняти, або ваш скрипт реплікації припускає стару поведінку/флаги zfs send.
Виправлення: Оновіть сторону прийому першою (або збережіть сумісність відправника), і відкоригуйте інструменти реплікації, щоб використовувати сумісні флаги. Перевірте з zfs send -nP і на малому тестовому датасеті.
5) Симптом: падіння продуктивності; стрибки CPU; зростання I/O wait
Корінна причина: Часто не те, що «ZFS став повільнішим», а зміна ядра, планувальника I/O, реалізації компресії або поведінки вивільнення пам’яті, що взаємодіє з ARC.
Виправлення: Порівняйте бази до/після. Перевірте arcstat miss rates, zpool iostat латентність і чи змінилося робоче навантаження. Тільки після цього розглядайте цілеспрямоване тонке налаштування. Не міняйте zfs_arc_max за відчуттями.
6) Симптом: датасети не змонтовані після перезавантаження; сервіси падають через відсутні шляхи
Корінна причина: Властивості датасету, як-от canmount, mountpoint, або порядок systemd змінились; інколи отримана властивість переважує локальні очікування.
Виправлення: Перегляньте властивості за допомогою zfs get, виправте джерело (local vs received) і переконайтеся, що залежності сервісів очікують монтування ZFS.
7) Симптом: команди zfs працюють, але операції з пулом дають дивні помилки; логи показують несумісність версій
Корінна причина: Невідповідність версій userland і модуля ядра після часткового оновлення.
Виправлення: Узгодьте версії. На Linux це означає переконатися, що модуль ZFS зібрано для запущеного ядра і що пакети userland відповідають тій самій лінії релізу.
Три міні-історії з корпоративного життя (анонімізовано, болісно правдоподібно)
Міні-історія №1: Інцидент через неправильне припущення
Середня компанія мала пару серверів зберігання: primary і DR. Primary оновлювали щоквартально. DR була «стабільною», як старий хліб. Припущення було просте: реплікація ZFS — це просто снапшоти по мережі, отже поки датасети є, сумісність вирішиться сама собою.
Під час планового оновлення інженер запустив zpool upgrade, бо команда виглядала як наступний логічний крок. Пул залишився онлайн, нічого не впало, і зміна закрилася раніше терміну. Наступні дні реплікаційні завдання почали падати, але тільки на деяких датасетах. Помилки були настільки періодичні, що їх ігнорували, і настільки голосні, що дратували всіх.
Потім справжній інцидент вразив primary — HBA почав скидати ресети під навантаженням. Вони переключились на DR і виявили, що пул не імпортується. «Unsupported features» при імпорті. DR працював на старішому OpenZFS, який не розумів деякі активні feature flags. Пул не був пошкоджений. Він просто став надто сучасним для середовища, яке найпотрібніше.
Відновлення було нудним і дорогим: оновлення DR до нового стека, потім відновлення даних із того, що ще реплікувалося. Насправді аварія сталась не через ZFS, а через припущення, що feature flags — опціональні і зворотні. Вони не такі.
Міні-історія №2: Оптимізація, що відбилася боком
Інша організація мала кластер віртуалізації на ZFS. Після оновлення OpenZFS інженер вирішив «використати нову версію» і змінив компресію з lz4 на zstd по всьому VM-датасету. Рationale був простий: краща компресія — менше I/O — краща продуктивність. Це добра теорія у світі, де CPU — безкоштовний, а латентність — уявна.
На практиці кластер мав змішане навантаження: дрібні випадкові записи, сплески операцій з метаданими і іноді резервні шторми. Після зміни латентність погіршилася у пікові години. CPU підскочив. On-call почав бачити таймаути VM, яких раніше не було. Графіки на рівні дисків виглядали нормально, що додавало гостроти: усі звинувачували мережу.
Корінь проблеми не в тому, що zstd — поганий. Він у тому, що вони змінили властивість, що визначає робоче навантаження, в тому ж вікні, що й оновлення OpenZFS, без базових порівнянь. Рівні компресії й накладні витрати CPU важливі. Також існуючі блоки не перекомпресовуються, тому поведінка була непостійною між VM в залежності від віку даних. Ідеально для плутанини.
Виправили, повернувши компресію для «гарячих» VM до lz4, залишивши zstd для холодніших даних, і розділивши «оновлення стека» та «зміну поведінки зберігання». Оновлення не було лиходієм. Поганою була упаковка змін.
Міні-історія №3: Нудна, але правильна практика, що врятувала ситуацію
Фінансово споріднена компанія мала root-on-ZFS скрізь. Вони мали політику, через яку інженери закочували очі: кожне оновлення хоста вимагало створення нового boot environment і пост-оновлювального перезавантаження в межах вікна. Без винятків. Політика з’явилася після того, як колись хтось втомився від «ми перезавантажимо пізніше» як евфемізму для «ми виявимо це під час інциденту».
Під час оновлення OpenZFS один хост повернувся з помилкою: служби ZFS не змонтували датасет. Причина була банальною: поєднання порядку запуску сервісів і властивості монтування датасету, яка успадкувалась несподівано. Хост технічно був в мережі, але додатки були мертві. Інженер на чергуванні не робив хитрих фіксів на поламаній системі під тиском.
Вони вибрали попередній boot environment у завантажувачі, повернулись в старий стек і відновили сервіс. Потім у робочий час відтворили проблему в стенді, виправили порядок монтування і повторили оновлення. Проста втрата часу була мінімальна, бо відкат не був теоретичним — він був частиною м’язової пам’яті.
Це та практика, що виглядає повільною, поки не виявиться швидшою за всі альтернативи.
ЧаПи
1) Чи потрібно запускати zpool upgrade відразу після оновлення OpenZFS?
Ні, не за замовчуванням. Спочатку оновіть стек програмного забезпечення, перевірте стабільність і реплікацію, потім оновлюйте фічі пулу, коли всі імпортери/отримувачі готові.
2) У чому різниця між оновленням OpenZFS і оновленням пулу?
Оновлення OpenZFS змінює код, що читає/записує ваш пул. Оновлення пулу змінює on-disk feature flags. Останнє може бути незворотним і впливає на сумісність між хостами.
3) Чи можна відкотити OpenZFS, якщо щось пішло не так?
Зазвичай можна відкотити програмне забезпечення, якщо ви не включали нові фічі пулу і ваш дистрибутив підтримує відкат пакетів. Якщо ви активували фічі, старі реалізації можуть більше не імпортувати пул.
4) Чому мій пул каже «healthy», але в мене є постійні помилки?
zpool status -x — це зведення. Постійні помилки можуть існувати навіть коли пул online. Завжди переглядайте zpool status -v перед оновленням.
5) Чи треба запускати scrub перед оновленням?
Якщо ви давно не робили scrub — так. Scrub — це спосіб перевірити цілісність даних по всьому пулу. Ви хочете мати відомі добрі дані перед зміною модулів ядра і коду зберігання.
6) Що з шифрованими датасетами — є якісь особливі застереження?
Переконайтесь, що керування ключами працює через перезавантаження: перевірте keylocation, протестуйте процедури розблокування і підтвердіть, що ранній етап завантаження може отримати ключі, якщо кореневий датасет зашифровано.
7) Мій реплікаційний таргет старіший. Чи можу я оновити відправника?
Часто так, якщо ви уникаєте увімкнення несумісних фіч і зберігаєте сумісність стрімів реплікації. Але потрібно тестувати: запустіть zfs send -nP і перевірте receive на старішому таргеті.
8) Чому люди відокремлюють boot pool (bpool) від root pool (rpool)?
Завантажувачі часто підтримують менше фіч ZFS, ніж ОС. Консервативний boot pool знижує ризик того, що оновлення фіч зробить систему незавантажувальною.
9) Якщо продуктивність змінилась після оновлення, який перший метрик довіряти?
Латентність на рівні пулу і vdev, плюс показники промахів ARC під тим самим навантаженням. Графіки пропускної здатності самі по собі можуть приховувати хвіст-латентності, що ламає додатки.
10) Чи має сенс L2ARC після оновлення?
Тільки якщо ви можете довести його користь. L2ARC додає складності і може «красти» пам’ять для метаданих. Виміряйте до і після; не розглядайте його як обряд посвячення.
Висновок: наступні кроки, які вам справді слід зробити
Ось практичний шлях, що дозволяє уникнути більшості болів при оновленні OpenZFS:
- Перерахуйте імпортери та отримувачі. Сумісність — властивість флоту, а не окремого хоста.
- Оновіть код спочатку, перезавантажтесь, перевірте. Якщо ви не перезавантажитесь, ви відкладаєте реальний тест на гірший час.
- Відкладіть
zpool upgrade, поки вся екосистема не буде готова. Сприймайте feature flags як міграції схеми: плановані, перевірені і таймінговані. - Збирайте докази. Збережіть pre/post виводи для версій, стану пулу, feature flags, властивостей і тестів реплікації.
- Запустіть один контрольований тест реплікації. Якщо ви не можете довести, що send/receive ще працює — у вас не DR, а оповідь.
Оновлення OpenZFS може бути нудним. Це й є мета. Чекліст — не ритуал; це спосіб уберегти черговий період від перетворення на професійний розвиток під час інциденту.