Вимкнення живлення. Вентилятори зупиняються. Телефон світи́ться сповіщенням. І настає те відчуття повільного тривожного передчуття: чи «впоралася» ZFS,
чи ви щойно підготували собі вихідні, витрачені на імпорт пулу, деградовані vdev і незручні пояснення?
Коректне завершення роботи, ініційоване UPS, — це одна з тих нудних, непомітних практик, яка вирізняє «вимкнули живлення» від «втратили довіру».
Але воно не захищає те, що більшість думає. Воно захищає узгодженість і передбачуваність — не апарат, не фізику і точно не віру в те, що RAID — це щит.
Що насправді захищає коректне завершення роботи (і що ні)
Визначимо «коректне завершення роботи» так, як це роблять у продакшені: ОС і сервіси зупиняються в упорядкованому порядку, ZFS
скидає і комітить те, що потрібно, а пул експортується або принаймні лишається у консистентному, відомому стані.
UPS — лиш посередник. Сам робочий процес завершення — це те, що захищає.
Що воно захищає
-
Робота з відтворення ZFS intent log (ZIL): при коректному зупиненні ви зменшуєте обсяг синхронної роботи,
що залишилася для відтворення під час імпорту. Менше реплею — менша затримка старту і менше сюрпризів для додатків, які не люблять вікна відновлення. -
Можливості узгодженості на рівні додатків: бази даних можуть зробити чекпоінт, скинути буфери або перестати приймати записи.
Файлова система може бути консистентною після збою, але додаток — ні. Коректне завершення дає змогу вирішити другу частину. -
Передбачувана поведінка при завантаженні/імпорті: коректне завершення уникатиме довгих «завислих» імпортів, важкого відновлення txg
та питань «чому пул імпортується 20 хвилин». -
Зменшення шансів каскадних відмов: якщо живлення флапає або батарея UPS вичерпується в хаосі, ви хочете,
щоб машина вже була вимкненою, а не напівзаписувала метадані, поки батарея помирає. -
Люди і процеси: коректне завершення означає, що сповіщення спрацьовують у правильному порядку, логи записані, і ви можете
відрізнити «вимкнули світло» від «сталася інцидент зі збереженням».
Що воно не захищає
-
Дані, які ніколи не були зафіксовані: якщо додаток буферизував записи і ніколи не викликав fsync, воно теж може їх втратити при коректному завершенні—
якщо тільки додаток не бере участь у процесі (або ОС не примусить це під час зупинки сервісів). -
Апаратні відмови, спричинені подіями живлення: стрибки напруги, brownout-и та дешеві блоки живлення все ще можуть пошкодити обладнання.
UPS допомагає, але це не талісман. -
Помилки припущень про «sync=disabled»: якщо ви відключили sync через бенчмарки, коректне завершення не воскресить підтверджені записи,
що насправді були тільки в ОЗП. - Кеші контролерів і прошивки без захисту від втрати живлення: якщо HBA або диск «бреше» про flush, ваша файлова система може робити все правильно і тим не менше втратити дані. ZFS не може переважити фізику.
-
Прихована корупція, що вже була: ZFS може виявити багато корупцій і відновити, коли є надлишковість,
але коректне завершення не зробить поганий диск хорошим заднім числом.
Є цитата, що вже стала операційною настановою: «Усе ламається постійно.»
— Werner Vogels.
Зріла дія — вирішити, які відмови зробити нудними.
Жарт №1: UPS як парасолька — корисна, але якщо намагатися з її допомогою зупинити ураган, ви просто станете ще мокрішими й злішими.
Зрозумілими операційними термінами: консистентність ZFS після збою
ZFS — транзакційна. Воно підготовлює зміни, а потім комітить їх групами транзакцій (txg). Коли txg комітиться, на-диску
структури оновлюються так, щоб після збою вони лишалися консистентними. Це основна обіцянка: ви можете втратити
нещодавні зміни, що не були закомічені, але у вас не повинно бути напівоновленої файлової системи, яка потребує fsck-подібного відновлення.
Підводний камінь: «консистентність» — це не «без простоїв» і не «без втрати даних». Це «без структурної нісенітниці». І другий камінь: решта стеку — ZIL, SLOG, додаток, гіпервізор, мережа —
все ще може змовитися, щоб ускладнити вам день.
Частини, що мають значення під час втрати живлення
-
TXG (transaction group): групує «брудні» дані й метадані, потім комітить. Збій означає: останній закомічений txg — безпечний;
txg в дорозі відкидається або відтворюється за потреби. -
ZIL (ZFS Intent Log): актуальний лише для синхронних записів. Він зберігає intent-записи, щоб після збою
ZFS міг відтворити те, що додаткам було обіцяно як «зафіксовано» при fsync/O_DSYNC. -
SLOG (відокремлений лог-пристрій): опціональний пристрій для швидшого (і безпечнішого, якщо є захист від втрати живлення) збереження ZIL.
Це не кеш записів для всього. Це спеціалізований лог для sync-записів. - ARC: кеш у RAM. Чудовий для продуктивності. Непотрібний для стійкості, коли живлення відсутнє.
- L2ARC: другий кеш читання. Не інструмент для стійкості. Після перезавантаження це більше «приємно, але холодно».
Шість–десять коротких фактів і історичний контекст (бо опси пам’ятають)
-
ZFS було створено в Sun Microsystems на початку 2000-х, щоб замінити традиційний розподіл volume manager + filesystem,
бо цей розподіл створював серйозні операційні проблеми в масштабі. -
Традиційні файлові системи часто покладалися на fsck після некоректних вимкнень; модель copy-on-write у ZFS була розроблена, щоб уникнути цього
циклу відновлення, зберігаючи стан на диску самоконсистентним. -
«ZIL» — це не журнал для всіх записів; він спеціально для синхронних семантик запису. Ця різниця все ще плутає людей
і підштовхує до неправильних покупок SLOG. -
Професійні масиви історично використовували батарейно-захищений кеш записів для безпечного підтвердження записів; синхронний шлях ZFS —
програмний підхід, який все ще залежить від чесної поведінки апаратних flush. -
Ранні споживчі SSD часто «брехали» про завершення запису і не мали конденсаторного завершення, через що «sync»
був менш значущим, ніж люди припускали. -
OpenZFS став спільнотно-орієнтованим продовженням після того, як Oracle взяла ZFS під свою опіку, що призвело до розгалуження екосистеми;
кращі практики поширились через вендорів та набиті шишки інциденти. -
Поширення віртуалізації та NFS/iSCSI зробило синхронну семантику більш поширеною в домашніх лабораторіях і малому/середньому бізнесі,
підвищивши реальну важливість правильності ZIL/SLOG. -
«Інтеграція UPS» раніше означала послідовні кабелі та вендорні демоні; зараз це здебільшого USB HID і мережеві інструменти UPS (NUT),
що простіше — і простіше неправильно налаштувати.
Коректне завершення не робить ZFS «більш консистентним». ZFS уже спроєктоване бути консистентним після збою.
Коректне завершення скоріше зменшує реплей, зменшує неоднозначність відновлення і дає додаткам час правильно закрити транзакції.
Цілі інтеграції UPS: контракт, який вам потрібен
Не ставтесь до інтеграції UPS як до «встановити демон і сподіватися». Сприймайте це як контракт з трьома пунктами:
виявити події живлення, прийняти рішення на основі часу роботи, і завершити у правильному порядку. Якщо ви не можете висловити свій контракт одним подихом,
у вас не контракт — у вас лише відчуття.
Пункт 1: Надійно виявляти подію живлення
USB зручний. Але USB також першим починає «плавати», коли хаби, дешеві кабелі і оновлення ядра зіштовхуються.
Якщо це продакшен, віддавайте перевагу мережевому UPS або виділеному серверу NUT, який живе довше, ніж будь-хост.
Пункт 2: Рішати на основі реального часу роботи, а не театру відсотків батареї
Відсоток батареї — не план. Це відчуття з числами. Вам потрібні оцінки часу роботи плюс запас,
і тригер завершення має спрацьовувати тоді, коли UPS ще стабільний. Режим brownout — не час, щоб виявляти синтаксичну помилку в скрипті завершення.
Пункт 3: Завершувати у правильному порядку
Для ZFS «правильний порядок» зазвичай означає: зупинити додатки, що генерують записи, припинити/зупинити мережевий експорт, а потім вимкнути ОС.
Якщо у вас під ZFS працюють віртуальні машини, гіпервізору потрібно час, щоб акуратно вимкнути їх перед завершенням хоста.
Жарт №2: Єдина річ більш оптимістична за «ми виправимо після відключення» — це «UPS впорається з цим».
План швидкої діагностики
Коли хтось каже «була подія живлення і ZFS поводиться повільно/дивно», вам потрібна швидка триажна перевірка, яка знайде вузьке місце
за хвилини, а не години. Ось порядок, що зазвичай окупається.
Перше: підтвердити, який тип завершення фактично відбувся
- Чи це було коректне завершення systemd, чи жорстке вимкнення живлення?
- Чи демон UPS зафіксував подію? Чи викликав він команду завершення? Чи хост дійшов до poweroff?
- Чи пул імпортувався автоматично, чи чекав/зависа́в?
Друге: перевірити здоров’я пулу і чи відбувається реплей або ресилвер
- Чи пул
ONLINE,DEGRADED, чи імпорт проходить повільно? - Чи йде scrub/resilver і чи обмежує це IO?
- Чи є помилки контрольних сум (це змінює всю розмову)?
Третє: вирішити, чи проблема в затримках синхронних записів (ZIL/SLOG) чи в загальному IO
- Якщо додатки скаржаться на fsync-затримки, зосередьтесь на здоров’ї SLOG, глибині черги і поведінці flush.
- Якщо все повільно — дивіться латентність vdev, один помираючий диск, скиди контролера або пул, що застряг у відновленні.
Четверте: перевірити порядок зупинки сервісів
- Чи зупинилися експорти NFS/iSCSI до того, як ZFS і мережа пішли вниз?
- Чи отримали бази даних сигнал зупинки і мали час для чекпоінта?
- Чи вимкнулися ВМ, або хост обірвався під ними?
Практичні завдання: команди, виводи, рішення (12+)
Ось завдання, які я реально виконую після подій живлення або під час роботи з інтеграцією UPS. Кожне має: команду, реалістичний вивід,
що вивід означає, і рішення, яке ви приймаєте. Команди передбачають Linux + OpenZFS; підлаштуйте шляхи під ваш дистрибутив.
Завдання 1: Підтвердити, чи останнє завершення було коректним (journald)
cr0x@server:~$ journalctl -b -1 -u systemd-shutdown --no-pager | tail -n 20
Dec 26 01:12:41 server systemd-shutdown[1]: Syncing filesystems and block devices.
Dec 26 01:12:44 server systemd-shutdown[1]: Sending SIGTERM to remaining processes...
Dec 26 01:12:46 server systemd-shutdown[1]: Sending SIGKILL to remaining processes...
Dec 26 01:12:47 server systemd-shutdown[1]: Unmounting file systems.
Dec 26 01:12:48 server systemd-shutdown[1]: Deactivating swaps.
Dec 26 01:12:48 server systemd-shutdown[1]: Detaching loop devices.
Dec 26 01:12:49 server systemd-shutdown[1]: All filesystems unmounted.
Dec 26 01:12:49 server systemd-shutdown[1]: Powering off.
Значення: це виглядає як впорядкований шлях завершення. При втраті живлення ви часто побачите обрізані логи.
Рішення: якщо це чисто, менш ймовірно, що ZFS постраждала; зосередьтесь більше на тому, чи коректно зупинилися додатки і чи спрацював UPS.
Завдання 2: Перевірити, чи демон UPS зафіксував «on battery» і «low battery» (NUT)
cr0x@server:~$ journalctl -u nut-monitor --since "today" --no-pager | egrep -i "on battery|low battery|shutdown" | tail -n 20
Dec 26 01:10:02 server upsmon[2314]: UPS ups@localhost on battery
Dec 26 01:12:05 server upsmon[2314]: UPS ups@localhost battery is low
Dec 26 01:12:06 server upsmon[2314]: Executing automatic power-fail shutdown
Значення: події UPS були виявлені і відпрацьовані. Якщо бачите лише «on battery», але немає shutdown — пороги тригерів налаштовані неправильно.
Рішення: якщо «battery is low» відбувається занадто пізно (безпосередньо перед втратою живлення), підвищте запас для тригеру часу роботи і протестуйте знову.
Завдання 3: Запитати статус UPS в реальному часі (NUT upsc)
cr0x@server:~$ upsc ups@localhost
battery.charge: 96
battery.runtime: 2480
battery.voltage: 27.3
device.mfr: APC
device.model: Smart-UPS 1500
input.voltage: 121.0
output.voltage: 120.0
ups.status: OL
ups.load: 22
Значення: ups.status: OL означає, що живлення в мережі. Runtime тут в секундах. Load помірний.
Рішення: використовуйте runtime (battery.runtime) як вхід для рішення про завершення. Налаштуйте shutdown при runtime менше за ваші вимоги плюс запас.
Завдання 4: Підтвердити стан пулу і лічильники помилок
cr0x@server:~$ sudo zpool status -x
all pools are healthy
Значення: немає відомих проблем. Це бажаний стан після аварії.
Рішення: якщо здоровий, не починайте «ритуали відновлення», що лише додають ризик. Перейдіть до перевірки на рівні додатків і продуктивності.
Завдання 5: Повний статус пулу з помилками vdev (після серйозної аварії)
cr0x@server:~$ sudo zpool status -v tank
pool: tank
state: DEGRADED
status: One or more devices has experienced an error resulting in data corruption.
action: Restore the file in question if possible. Otherwise restore the entire pool from backup.
scan: scrub repaired 0B in 00:12:31 with 2 errors on Thu Dec 26 01:44:09 2025
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
raidz2-0 DEGRADED 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 2 (repairing)
errors: Permanent errors have been detected in the following files:
tank/data/app.db
Значення: це вже не «просто відключення живлення». Є помилки контрольних сум і файл позначено як остаточно пошкоджений.
Рішення: зупиніть уражений додаток, відновіть файл з бекапу/снапшота і дослідіть диск sdd (SMART, кабелі, скиди контролера). Не ігноруйте помилки контрольних сум.
Завдання 6: Перевірити, чи йде resilver/scrub і його вікно впливу
cr0x@server:~$ sudo zpool status tank | sed -n '1,20p'
pool: tank
state: ONLINE
scan: resilver in progress since Thu Dec 26 01:20:12 2025
312G scanned at 1.02G/s, 88.4G issued at 289M/s, 3.50T total
88.4G resilvered, 2.46% done, 03:18:44 to go
Значення: йде ресилверинг і він «відбере» пропускну здатність та IOPS.
Рішення: якщо це продукційне навантаження, перенесіть інтенсивні IO-завдання за межі вікна ресилверу і налаштовуйте zfs_resilver_delay/zfs_scan_idle лише якщо розумієте компроміси.
Завдання 7: Перевірити історію імпортів і чи пул експортувався
cr0x@server:~$ sudo zpool history -il tank | tail -n 20
2025-12-26.01:12:48 zpool export tank
2025-12-26.01:12:49 system: shutdown initiated by upsmon
2025-12-26.01:18:02 zpool import tank
Значення: хтось (або автоматизація) експортував пул перед вимкненням. Це відмінна гігієна і зменшує неоднозначність імпорту.
Рішення: якщо не бачите експорту під час подій завершення, подумайте про контрольований експорт у шляху завершення UPS — обережно, з правильним порядком.
Завдання 8: Підтвердити налаштування sync для датасетів (щоб уникнути випадкового «швидко, але небезпечно»)
cr0x@server:~$ sudo zfs get -r sync tank | head -n 15
NAME PROPERTY VALUE SOURCE
tank sync standard default
tank/data sync standard inherited from tank
tank/data/postgres sync standard local
tank/vm sync disabled local
Значення: tank/vm має sync=disabled. Цей датасет підтверджує записи без гарантій надійності.
Рішення: якщо в tank/vm зберігаються диски ВМ або бази даних, змініть на standard (або always, де потрібно) і подумайте про реальний SLOG, якщо синхронна латентність — причина.
Завдання 9: Подивитися, чи взагалі є SLOG і який він
cr0x@server:~$ sudo zpool status tank | egrep -A3 "logs|cache|special"
logs
nvme0n1p2 ONLINE 0 0 0
Значення: є виділений лог-пристрій. Добре — якщо це правильний тип пристрою.
Рішення: перевірте, чи SLOG має захист від втрати живлення (PLP). Якщо ні — ви побудували «швидкий пристрій для краху».
Завдання 10: Підтвердити здоров’я SLOG і історію помилок (SMART)
cr0x@server:~$ sudo smartctl -a /dev/nvme0 | egrep -i "model|percentage used|media|power cycles|unsafe shutdowns"
Model Number: INTEL SSDPE2KX040T8
Percentage Used: 3%
Media and Data Integrity Errors: 0
Power Cycles: 38
Unsafe Shutdowns: 7
Значення: значення «Unsafe Shutdowns» відмінне від нуля — звично протягом життєвого циклу пристрою, але якщо воно зростає при кожному відключенні, ви регулярно не закінчуєте роботу коректно.
Рішення: корелюйте лічильник небезпечних вимкнень з подіями і тестами UPS. Якщо він зростає під час планових тестів — тригер завершення занадто пізній або порядок неправильний.
Завдання 11: Перевірити логи ядра на предмет скидів контролерів поруч із подією
cr0x@server:~$ dmesg -T | egrep -i "reset|link is down|I/O error|ata[0-9]" | tail -n 20
[Thu Dec 26 01:10:11 2025] ata3: link is slow to respond, please be patient (ready=0)
[Thu Dec 26 01:10:15 2025] ata3: COMRESET failed (errno=-16)
[Thu Dec 26 01:10:19 2025] sd 2:0:0:0: [sdd] tag#18 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[Thu Dec 26 01:10:19 2025] blk_update_request: I/O error, dev sdd, sector 812345672 op 0x1:(WRITE) flags 0x0 phys_seg 1 prio class 0
Значення: це не драматизація ZFS; це ядро, яке каже, що шлях зберігання був нестабільним.
Рішення: спочатку розглядайте це як апарат/кабель/контролер. Помилки ZFS часто є наслідком проблем транспорту.
Завдання 12: Швидко виміряти латентність пулу (iostat) і вирішити, чи вузьке місце в синхронних записах
cr0x@server:~$ sudo zpool iostat -v tank 1 5
capacity operations bandwidth
pool alloc free read write read write
-------------------------- ----- ----- ----- ----- ----- -----
tank 2.01T 1.49T 110 980 12.8M 94.1M
raidz2-0 2.01T 1.49T 110 980 12.8M 94.1M
sda - - 30 220 3.1M 21.1M
sdb - - 28 235 3.2M 22.4M
sdc - - 27 245 3.3M 23.0M
sdd - - 25 280 3.2M 27.6M
logs - - 0 600 0.0K 52.0M
nvme0n1p2 - - 0 600 0.0K 52.0M
-------------------------- ----- ----- ----- ----- ----- -----
Значення: лог-пристрій виконує значну кількість записів/пропускної здатності — класичний знак синхронно-важкого навантаження. Якщо там висока латентність, додатки це відчують.
Рішення: якщо скарги на продуктивність збігаються з активністю логу, зосередьтесь на продуктивності/PLP SLOG і на тому, чи навантаження справді потребує sync-записів.
Завдання 13: Переглянути історію подій ZFS на предмет підказок про імпорт/реплей
cr0x@server:~$ sudo zpool events -v | tail -n 25
TIME CLASS
Dec 26 2025 01:18:02.412345678 sysevent.fs.zfs.pool_import
pool: tank
guid: 1234567890123456789
Dec 26 2025 01:18:04.998877665 sysevent.fs.zfs.config_sync
pool: tank
Значення: ви можете бачити події імпорту і таймінги; це допомагає корелювати «завантаження відчувалося повільним» з реальними операціями імпорту.
Рішення: якщо події імпорту часті й пов’язані зі збоями, виправте надійність завершення перед тим, як гнатися за мікрооптимізаціями.
Завдання 14: Підтвердити, чи NFS/iSCSI сервіси зупинилися коректно перед завершенням
cr0x@server:~$ systemctl status nfs-server --no-pager
● nfs-server.service - NFS server and services
Loaded: loaded (/lib/systemd/system/nfs-server.service; enabled)
Active: active (running) since Thu 2025-12-26 01:18:22 UTC; 12min ago
Docs: man:rpc.nfsd(8)
Main PID: 1842 (rpc.nfsd)
Status: "running"
Значення: зараз сервіс запущений, але потрібно перевірити, чи зупинявся він перед останнім завершенням.
Рішення: перегляньте логи попереднього завантаження для часу зупинки сервісу. Якщо NFS залишався активним, поки ZFS намагався заспокоїтись, потрібно попрацювати над порядком.
Завдання 15: Перевірити systemd-порядок для хуків завершення, викликаних UPS
cr0x@server:~$ systemctl list-dependencies shutdown.target --no-pager | head -n 25
shutdown.target
● ├─systemd-remount-fs.service
● ├─systemd-poweroff.service
● ├─umount.target
● ├─final.target
● └─systemd-shutdown.service
Значення: це показує шлях завершення. Ваш демон UPS має викликати нормальний shutdown, а не «kill -9 все і молитися».
Рішення: якщо інтеграція UPS оминає systemd (кастомні скрипти викликають poweroff дивно), рефакторьте на стандартний shutdown, щоб сервіси могли зупинитися коректно.
Завдання 16: Тестувати тригер завершення без фактичного вимкнення (NUT upsmon -c fsd)
cr0x@server:~$ sudo upsmon -c fsd
Network UPS Tools upsmon 2.8.0
FSD set on UPS [ups@localhost]
Значення: це імітує обробку «форсованого завершення». Залежно від конфігурації, може почати миттєве завершення.
Рішення: виконайте це в межах вікна технічного обслуговування і спостерігайте за порядком зупинки сервісів і поведінкою експорту пулу. Якщо хаотично — виправте до наступного реального збою.
Три корпоративні міні-історії з фронту
Міні-історія 1: Інцидент через хибне припущення
Середня компанія тримала хост віртуалізації на ZFS для внутрішніх сервісів. У них був UPS. У них була впевненість.
Також у них було критичне припущення: «якщо UPS підключений по USB, завершення завжди станеться».
День, коли це не спрацювало, не був драматичним — просто коротке падіння живлення і генератор, що довше від очікуваного переходив на лінію.
Хост не вимкнувся. UPS намагався подати сигнал, але USB-пристрій після оновлення ядра має іншу нумерацію, і демон моніторингу тихо стежив не за тим шляхом пристрою.
Жодних сповіщень, бо «демон UPS працює» було єдиною перевіркою здоров’я.
Після відновлення живлення пул імпортувався. Корупції не було. Усі передчасно заспокоїлися. Потім файлові системи ВМ виявилися консистентними на структурному рівні, але додаткова консистентність була порушена:
база даних, яка підтверджувала записи, покладалася на хости flush-семантику, яку вони не верифікували. ВМ завантажилася, БД поскаржилася, і «коротке падіння живлення»
перетворилося на ескалацію, бо команди сперечалися, «хто винен».
Виправлення було нудним: додали NUT-сервер на стабільній машині з власним живленням, перейшли на мережевий моніторинг і додали явну періодичну валідацію:
опитувати статус UPS і аварійно сповіщати, якщо UPS зникає або демон повідомляє прострочені дані. Також провели аудит налаштувань sync і перестали обманювати себе, що USB = надійність.
Міні-історія 2: Оптимізація, що повернулася бумерангом
Інша команда використовувала ZFS для NFS-стору. Продуктивність була «нормальна», поки не з’явилося нове навантаження: билд-ферма, яка робила багато операцій з метаданими і вимагала передбачуваної латентності.
Команда шукала бенчмарки і знайшла «чарівний вимикач»: sync=disabled на датасеті. Латентність впала. Графіки стали гарні. Була хвиля привітань, яка завжди повинна активувати моніторинг.
Через кілька місяців сталося відключення живлення. UPS ініціював коректне завершення, хост акуратно вимкнувся. Здавалось, усе добре. Потім користувачі повідомили про відсутні артефакти збірки і «успішні» збірки з пошкодженими результатами.
Структурної корупції не було. ZFS була консистентною. Але дані на рівні додатку містили підтверджені записи, що жили в RAM і ніколи не потрапили на диск — бо вони навмисно сказали ZFS «брехати».
Постмортем був незручним: відключення було коротким і система «чисто вимкнулася». Ось пастка:
коректне завершення захищає від певних режимів відмови, але не від навмисного відключення гарантій надійності. Оптимізація перетворила «рідкісну втрату живлення» на «імовірний інцидент цілісності даних».
Ремедіація: знову ввімкнули sync і додали справжній SLOG з PLP. Також розділили навантаження: кеші збірок отримали інші налаштування, а сховище артефактів — захищене. Тюнінг продуктивності перейшов від «вимкнути небезпечну кнопку» до «проєктувати рівні збереження як дорослі».
Міні-історія 3: Нудна, але правильна практика, яка врятувала день
Команда фінансових сервісів використовувала ZFS-backed iSCSI для важливих внутрішніх систем.
Їх інтеграція UPS не була яскравою. Вона була записана, протестована щокварталу і входила в процеси змін.
У них було одне правило: кожен шлях завершення має бути тестованим без виривання вилки.
Вони використовували виділений NUT-сервер і налаштували клієнтів ініціювати завершення, коли runtime впаде нижче порогу, що включає «час на зупинку сервісів» плюс запас.
Процедура зупиняла iSCSI-таргети першими, потім говорила додаткам зупинитися, а потім давала ZFS час заспокоїтися. Вони не експортували пули в довільних скриптах; покладалися на стандартний порядок завершення,
а де додавали хуки — робили це як systemd-юнити з чіткими залежностями.
Коли стався реальний довший збій, системи вимикалися передбачувано, з чистими логами. Після повернення живлення бут пройшов нудно.
Імпорти були швидкими. Ніяких ресилверів. Ніяких містичних помилок. Користувачі переважно не помітили.
Найкраще: під час пост-інцидентного аналізу ніхто не сперечався, бо логи показували все очевидно, а процедура була відрепетирована. «Нудне» стало критерієм успіху — і вони його досягли.
Типові помилки: симптом → корінь проблеми → виправлення
1) Симптом: імпорт пулу займає вічність після відключень
Корінь: повторювані некоректні завершення, що призводять до більшої кількості роботи з відновлення; інколи ускладнюється маргінальним диском або скидами контролера.
Виправлення: переконайтеся, що UPS тригерить раніше; перевірте journalctl на предмет чистого завершення; огляньте dmesg на скиди лінків; замініть ненадійні кабелі/HBA перед тюнінгом ZFS.
2) Симптом: додатки повідомляють «корупцію бази даних», але статус ZFS чистий
Корінь: невідповідність на рівні додатка через вимкнений sync, відсутній fsync або різке вимкнення ВМ.
Виправлення: відновити з бекапу/снапшота; знову ввімкнути sync; забезпечити порядок вимкнення ВМ; перевірити налаштування БД (режим durable) і семантику збереження.
3) Симптом: NFS клієнти зависають під час відключення і повертаються зі застарілими дескрипторами
Корінь: неправильний порядок завершення: експорти залишалися активними, поки сховище відключалося, або клієнти не бачили коректного зупинення сервера.
Виправлення: порядок systemd: зупиняйте nfs-server (або iSCSI target) раніше при завершенні; переконайтеся, що UPS запускає стандартний shutdown, а не kill-скрипт.
4) Симптом: UPS «працює» у звичайний час, але відмовляє під час реальних аварій
Корінь: моніторинг є, але не верифікований; USB нестабільний; демон запущений, але відключений від пристрою.
Виправлення: сповіщення про свіжість телеметрії UPS; віддавайте перевагу мережевому UPS; проводьте імітовані FSD тести; записуйте очікувані рядки в лог і перевіряйте їх.
5) Симптом: латентність синхронних записів зростає після додавання SLOG
Корінь: SLOG-пристрій повільніший або не має PLP, що спричиняє затримки flush; або він підключений до спільної шини з конкуренцією.
Виправлення: обирайте корпоративний SSD/NVMe з PLP; ізолюйте його; перевіряйте через zpool iostat і SMART; видаляйте поганий SLOG замість того, щоб терпіти його.
6) Симптом: після подій живлення з’являються помилки контрольних сум
Корінь: реальна корупція від помираючого диска, нестабільного ланцюга живлення або проблем з контролером; інколи проявляється scrub після перезавантаження.
Виправлення: розглядайте як апаратний інцидент; запускайте SMART-тести; перепідключайте/замінюйте компоненти; відновлюйте пошкоджені файли з відомо-правильних копій; прогоніть scrub після ремонту.
7) Симптом: система вимикається занадто пізно, батарея вмирає під час завершення
Корінь: поріг завершення встановлено на «низька батарея» замість «достатньо часу на завершення», або оцінка runtime не відкалібрована.
Виправлення: встановіть завершення за залишковим часом з запасом; виміряйте реальний час завершення; включіть час на вимкнення ВМ і експорт сховища.
8) Симптом: після аварії пул ONLINE, але продуктивність жахлива
Корінь: іде ресилвер/скраб, або один диск має високу латентність; ARC холодний; або додатки відтворюють власне відновлення.
Виправлення: перевірте рядок скану в zpool status; огляньте IO по vdev у zpool iostat -v; ідентифікуйте повільний пристрій; повідомте власників додатків про очікуване вікно відновлення.
Чеклісти / покроковий план
Покроково: побудуйте інтеграцію UPS, що справді вас захищає
- Визначте мету: «Хост вимикається коректно до того, як runtime UPS впаде нижче X секунд; додатки зупиняються в порядку; пул імпортується швидко.»
- Виміряйте час завершення: зафіксуйте час повної зупинки сервісів і вимикання. Додайте запас. Не вгадуйте.
- Виберіть архітектуру: якщо багато хостів, запустіть виділений соніт-демон моніторингу UPS (NUT) і підключайте клієнтів.
- Налаштуйте тригери на основі runtime, а не відсотків: встановіть завершення, коли runtime < (measured shutdown time + margin).
- Підтвердьте порядок сервісів: зупиняйте першими сервіси з інтенсивними записами (БД, гіпервізори), потім експорти (NFS/iSCSI), потім ОС.
-
Аудит налаштувань стійкості ZFS: знайдіть усі датасети з
sync=disabledі обґрунтуйте їх письмово. - Підтвердьте правильність SLOG: якщо використовуєте SLOG — вимагайте PLP і моніторинг здоров’я пристрою.
- Тестуйте без відключення живлення: імітуйте FSD і перевіряйте очікувані логи й поведінку.
- Сповіщайте про свіжість телеметрії UPS: якщо демон не читає статус UPS, ви повинні знати про це до аварії.
-
Запускайте перевірку імпорту після тесту: після кожного тесту перевіряйте
zpool status, помилки і час імпорту.
Чекліст реакції на аварію: після повернення живлення
- Перевірте, чи було чисто: логи попереднього завантаження (
journalctl -b -1). - Перевірте здоров’я пулу:
zpool status -x, потім повнийzpool status -v, якщо щось не так. - Перевірте помилки ядра:
dmesgна предмет скидів і I/O помилок. - Перевірте наявність scrub/resilver: очікуйте вплив на продуктивність і оцініть залишковий час.
- Підтвердьте критичні датасети: перевірте налаштування
sync, наявність SLOG і помилки контрольних сум. - Потім перевіряйте додатки: відновлення БД, цілісність ВМ і підключення клієнтів.
Питання та відповіді
1) Чи коректне завершення запобігає корупції ZFS?
Воно зменшує ризик і роботу з відновлення, але ZFS спроєктована бути консистентною після збою навіть без цього. Коректне завершення головним чином захищає
узгодженість додатків, зменшує реплей ZIL і уникає хаосу апаратного/транспортного рівня під час втрати живлення.
2) Якщо ZFS консистентна після збою, навіщо взагалі потрібен UPS?
Тому що «консистентність після збою» — це не «без наслідків». Імпорти можуть бути повільнішими, додатки можуть втратити підтверджену роботу (залежно від налаштувань),
і повторні жорсткі втрати навантажують обладнання. Також: ваші цілі доступності зазвичай включають «не перезавантажуватися несподівано».
3) Чи потрібен SLOG для безпеки?
Ні. SLOG — це інструмент продуктивності для синхронних навантажень. Безпека походить від правильних sync-семантик і чесних апаратних flush.
Якщо додаєте SLOG, він має бути надійним (ідеально з PLP), інакше ви можете погіршити ситуацію.
4) Що насправді робить sync=disabled?
Воно наказує ZFS підтверджувати синхронні записи без очікування їх безпечного коміту. Ви отримуєте швидкість і жертвуєте стійкістю.
Якщо додаток думає, що дані зафіксовано — після збою це може виявитися помилкою, навіть при коректному завершенні, якщо таймінг не той.
5) Чи варто експортувати пул під час завершення?
Це може допомогти зробити наступний імпорт чистішим, але потрібно робити у правильному порядку. Якщо сервіси досі мають відкриті файли або клієнти пишуть,
експорт може зависнути або впасти. Віддавайте перевагу стандартному порядку завершення; додавайте експортні хуки лише якщо можете їх протестувати.
6) Чому мій scrub почався після перезавантаження?
Деякі системи чи адміністратори планують scrub, і він випадково запустився після перезавантаження; в інших випадках ви запускаєте його вручну для перевірки.
Scrub після аварії — корисна практика, коли подія була некоректною або підозрюєте апаратну нестабільність — очікуйте вплив на продуктивність.
7) UPS показує відсоток 40%. Чому він помер раніше?
Зміни навантаження, вік батареї, температура і калібрування впливають на runtime. Відсоток — ненадійний прогноз під змінним навантаженням.
Базуйте рішення на оцінках runtime і періодично виконуйте контрольні тести часу роботи для калібрування.
8) NUT чи apcupsd: що обрати?
Якщо у вас один APC UPS, підключений до одного хоста, apcupsd простий. Якщо у вас багато хостів, змішані вендори UPS
або потрібен мережевий моніторинг — NUT зазвичай краще підходить.
9) Як зрозуміти, що порядок завершення правильний?
Ви тестуєте. Імітуйте форсоване завершення (у вікні обслуговування), потім перевірте логи: додатки зупинилися першими, експорти зупинилися,
ZFS не була зайнята, і хост вимкнувся з запасом часу.
10) Після аварії негайно запустити zpool scrub?
Якщо завершення було чистим і zpool status -x показує здоров’я, можна почекати регулярного розкладу.
Якщо завершення було некоректним, або бачите I/O помилки, або це критичні навантаження — scrub запускати раніше, але після стабілізації апаратури.
Висновок: наступні кроки, що рятують від нічних дзвінків
Коректне завершення, ініційоване UPS, не дарує безсмертя дискам, базам даних чи поганим ідеям. Воно купує контрольоване приземлення:
менше «обіцянок у польоті», менше роботи з відновлення і система, що поводиться передбачувано, коли світло повертається.
Саме за це ви платите.
- Виміряйте реальний час завершення (включно з вимкненням ВМ/додатків) і встановіть тригери на основі runtime з запасом.
- Перевірте телеметрію UPS (оповіщення про свіжість) і віддавайте перевагу мережевому моніторингу для мультихостових налаштувань.
- Аудит налаштувань стійкості ZFS і припиніть використовувати
sync=disabledяк стратегію продуктивності для важливих даних. - Перевірте реальність SLOG: PLP, моніторинг здоров’я і видалення, якщо пристрій невідповідний.
- Репетируйте: проводьте імітаційні тести завершення і перевіряйте логи на впорядковану зупинку і коректну поведінку імпорту.
Якщо ви зробите ці п’ять кроків, відключення живлення стануть незручністю, а не сюжетним поворотом. І в цьому весь сенс.