Debian 13: TRIM не виконується — увімкніть таймер fstrim і перевірте, що він працює

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

Ви встановили Debian 13, перейшли на SSD (або NVMe) і очікували, що система сама по собі підтримуватиме порядок. Потім продуктивність стала трохи «липкою», показники зносу дисків виглядають гірше, ніж хотілося б, або ви помітили, що fstrim ніколи не запускалося. Класика.

TRIM — це одне з тих обслуговувань, яких не помічаєш, поки вони відсутні — як резервні копії, поки не знадобляться і їх немає. Налаштуємо Debian 13 так, щоб TRIM виконувався за розкладом, покажемо, що він справді щось робить, і пропишемо діагностику поширених пасток, коли команда успішно завершується, але стек зберігання кидає запит у нікуди.

Що таке TRIM (і чим він не є)

TRIM — це спосіб, яким операційна система повідомляє твердотільному сховищу, які блоки більше не містять корисних даних. Це звучить буденно, доки не згадаєш, як працюють SSD: флеш-пам’ять не може перезаписувати місцями; вона записує нові сторінки в інші місця і пізніше стирає старі блоки більшими кусками. Якщо накопичувач не знає, що блок вільний, він може вважати його «можливо ще в використанні», що збільшує write amplification, знижує стійку продуктивність запису та посилює знос.

У Linux ви зіштовхнетеся з TRIM через два механізми:

  • Періодичний TRIM: fstrim обходить змонтовані файлові системи й видає операції discard для вільного простору. Debian зазвичай планує це щотижнево через systemd таймер.
  • Безперервний discard: опція монтування discard (або варіанти, специфічні для файлової системи) видає discards у міру звільнення блоків.

Використовуйте періодичний TRIM, якщо у вас немає вагомої причини інакше. Безперервний discard може працювати добре, але також може додавати затримку під навантаженням запису й ускладнювати налагодження продуктивності. Періодичний TRIM — нудний. Нудний — це добре.

TRIM також не чарівна кнопка «зроби мій SSD швидким». Якщо ваше вузьке місце — випадкові зчитування при queue depth 1, TRIM вам не допоможе. Якщо ж проблема в тому, що хост VM бреше про підтримку discard, TRIM також не врятує вашу кар’єру.

Цитата, яку варто тримати в голові: Вернер Вогельс (CTO Amazon) сказав: «Все падає, весь час.» (перефразована думка). Сховище також це включає. Припускайте, що щось зламається — а потім перевіряйте.

Цікаві факти та контекст (для тих, хто любить знати чому)

  • Факт 1: SATA TRIM команда була введена як частина стандартів ATA приблизно в момент, коли SSD стали масовими; до того накопичувачам доводилося вгадувати, які дані застаріли.
  • Факт 2: На NVMe еквівалент називається Dataset Management / Deallocate, але Linux все одно трактує це в межах поняття «discard».
  • Факт 3: Ранні SSD іноді неправильно обробляли TRIM. Деякі версії прошивки працювали з discard дуже погано, через що адміністратори роками вимикали його по всьому флоту заради самозахисту.
  • Факт 4: Файлові системи не «потребують» TRIM для роботи. Вони потребують його, щоб уникнути того, щоб алгоритм збору сміття SSD перетворився на прихований податок продуктивності.
  • Факт 5: Більшість сучасних дистрибутивів Linux перейшли від постійного discard до планового fstrim, бо з ним легше мислити і він часто швидший загалом.
  • Факт 6: Тонкопровізіоноване сховище (LVM thin, віртуальні диски, SAN LUN) може звільняти ємність вгору по ланцюжку через discard — якщо кожен шар співпрацює. Один шар скаже «ні», і ви будете платити за блоки, які видалили місяці тому.
  • Факт 7: dm-crypt історично за замовчуванням не пропускав discards, оскільки вони можуть витікати інформацію про те, які блоки використовуються. Ви можете явно увімкнути цю опцію.
  • Факт 8: Багато RAID-контролерів і деякі стекові шари device-mapper колись повністю ігнорували discard-запити. Сучасні ядра кращі, але «кращий» не означає «гарантований».

Жарт №1: TRIM як прибирання на столі — ніхто не помічає, коли ви це робите, але всі помічають, коли не робите.

Швидкий план діагностики (перевірте це насамперед)

Якщо TRIM «не виконується», ви насправді налагоджуєте одну з трьох речей: планування, стану юнітів/дозволів або підтримки discard через стек зберігання. Не намагайтеся вирішити все одразу. Перевіряйте в такому порядку:

1) Чи увімкнений таймер і чи спрацьовує він?

  • Перевірте, що fstrim.timer увімкнений і має час наступного запуску.
  • Перевірте, коли він востаннє запускався і чи успішно.

2) Чи працює вручну fstrim -av?

  • Якщо ручний trim зазнає невдачі: проблема не в плануванні. Шукайте підтримку, опції монтування або стек пристрою.
  • Якщо ручний trim працює, а таймер ні: дивіться на стан systemd-юнітів, masking або проблеми з годинником/таймерами.

3) Чи хвалить блоковий пристрій підтримку discard?

  • Використайте lsblk -D (розмір гранулярності/макс) і sanity-перевірки blkdiscard.
  • Для LUKS/LVM/RAID/VM перевіряйте, чи кожен шар пропускає discards.

4) Чи ви очищуєте саме те, що треба?

  • fstrim обрізає лише змонтовані файлові системи. Якщо важливий монтувальний пункт не змонтовано під час роботи таймера (рідко, але буває), його не буде обрізано.
  • Деякі файлові системи або опції монтування можуть повністю відключати discard.

Практичні завдання: команди, очікуваний вивід і рішення

Це серцевина. Кожне завдання містить: команду, що означає вивід, і рішення, яке ви приймаєте далі. Запускайте як root або з sudo, як вказано.

Завдання 1: Підтвердити, що Debian бачить ваші диски як підтримуючі discard

cr0x@server:~$ lsblk -D -o NAME,MODEL,ROTA,DISC-GRAN,DISC-MAX,DISC-ZERO
NAME        MODEL               ROTA DISC-GRAN DISC-MAX DISC-ZERO
nvme0n1     Samsung SSD 980      0      4K       2T         0
sda         ST1000DM010-2EP1     1      0B       0B         0

Значення: Наявність ненульових DISC-GRAN і DISC-MAX вказує, що пристрій заявляє про підтримку discard. Ротаційні диски (ROTA=1) зазвичай показують 0B, бо TRIM стосується SSD-подібних носіїв.

Рішення: Якщо ваш SSD/NVMe показує 0B/0B, не звинувачуйте systemd. Швидше за все, якийсь шар блокує discard (dm-crypt, RAID, тип віртуального диска) або пристрій дійсно його не підтримує.

Завдання 2: Перевірити стан таймера fstrim

cr0x@server:~$ systemctl status fstrim.timer
● fstrim.timer - Discard unused blocks once a week
     Loaded: loaded (/usr/lib/systemd/system/fstrim.timer; enabled; preset: enabled)
     Active: active (waiting) since Mon 2025-12-29 09:10:12 UTC; 3h ago
    Trigger: Sun 2026-01-04 00:24:31 UTC; 4 days left
   Triggers: ● fstrim.service

Значення: Увімкнено + active (waiting) з майбутнім часом тригера — це те, що вам потрібно. Якщо вивід показує disabled, inactive, masked або немає тригера, він не запуститься.

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

Завдання 3: Перелічити таймери і перевірити, що fstrim запланований

cr0x@server:~$ systemctl list-timers --all | grep -E 'fstrim|NEXT|LAST'
Sun 2026-01-04 00:24:31 UTC  4 days left Sun 2025-12-28 00:22:09 UTC  1 day ago  fstrim.timer  fstrim.service

Значення: Ви бачите NEXT і LAST часи запуску. Якщо LAST — «n/a», він ніколи не виконувався. Якщо NEXT — «n/a», він не запланований.

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

Завдання 4: Подивитися, чи сервіс викликався і що він зробив

cr0x@server:~$ systemctl status fstrim.service
● fstrim.service - Discard unused blocks on filesystems from /etc/fstab
     Loaded: loaded (/usr/lib/systemd/system/fstrim.service; static)
     Active: inactive (dead) since Sun 2025-12-28 00:22:12 UTC; 1 day ago
TriggeredBy: ● fstrim.timer
       Docs: man:fstrim(8)
    Process: 2021 ExecStart=/sbin/fstrim --fstab --verbose --quiet (code=exited, status=0/SUCCESS)
   Main PID: 2021 (code=exited, status=0/SUCCESS)

Значення: Статус 0/SUCCESS означає, що він запускался. «inactive (dead)» — нормальний стан після завершення oneshot сервісу.

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

Завдання 5: Прочитати журнал для деталей fstrim

cr0x@server:~$ journalctl -u fstrim.service -n 50 --no-pager
Dec 28 00:22:09 server systemd[1]: Starting fstrim.service - Discard unused blocks on filesystems from /etc/fstab...
Dec 28 00:22:09 server fstrim[2021]: /: 18.7 GiB (20068429824 bytes) trimmed on /dev/nvme0n1p2
Dec 28 00:22:12 server systemd[1]: fstrim.service: Deactivated successfully.
Dec 28 00:22:12 server systemd[1]: Finished fstrim.service - Discard unused blocks on filesystems from /etc/fstab.

Значення: Це ваше підтвердження. Тут видно, які точки монтування були обрізані і скільки байт.

Рішення: Якщо в списку лише деякі файлові системи — перевірте /etc/fstab і стан монтувань. Якщо він постійно обрізає 0 байт — перевірте підтримку discard; можливо, вона блокується або просто немає нічого нового для обрізання.

Завдання 6: Запустити fstrim вручну по всіх змонтованих файлових системах

cr0x@server:~$ sudo fstrim -av
/: 18.7 GiB (20068429824 bytes) trimmed on /dev/nvme0n1p2
/var: 2.1 GiB (2254857830 bytes) trimmed on /dev/nvme0n1p3

Значення: -a означає «усі змонтовані файлові системи, які це підтримують»; -v показує, що сталося. Якщо бачите «Operation not supported», маєте проблему зі стеком або обмеження файлової системи.

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

Завдання 7: Перевірити, які файлові системи підлягають обрізанню (змонтовані та в fstab)

cr0x@server:~$ findmnt -no TARGET,SOURCE,FSTYPE,OPTIONS /
/ /dev/nvme0n1p2 ext4 rw,relatime,errors=remount-ro

Значення: Показує опції монтування і тип файлової системи. Для періодичного fstrim опція discard не є обов’язковою.

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

Завдання 8: Підтвердити, що fstrim розглядатиме файлову систему (фільтр fstab)

cr0x@server:~$ grep -vE '^\s*#|^\s*$' /etc/fstab
UUID=8c2b1f2a-6a3f-4ad4-9b7f-3d2b0b7b6f12 /     ext4 defaults,errors=remount-ro 0 1
UUID=0f3f0c1a-27ae-4f1c-a90f-8b0b7fe1f5c1 /var  ext4 defaults                  0 2

Значення: Debianський fstrim.service зазвичай запускає fstrim --fstab, тобто використовує записи fstab, а не «що змонтовано». Якщо ви монтуєте щось вручну і це не в fstab, таймер може ніколи його не обрізати.

Рішення: Якщо монтувальна точка має бути обрізана — додайте її в fstab або змініть стратегію TRIM.

Завдання 9: Переконатися, що таймер не замаскований і не перевизначений

cr0x@server:~$ systemctl is-enabled fstrim.timer
enabled

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

Рішення: Якщо masked — розмаскуйте і увімкніть (показано нижче). Якщо disabled — увімкніть.

Завдання 10: Перевірити, чи є переозначення unit, що змінює поведінку

cr0x@server:~$ systemctl cat fstrim.service
# /usr/lib/systemd/system/fstrim.service
[Unit]
Description=Discard unused blocks on filesystems from /etc/fstab
Documentation=man:fstrim(8)

[Service]
Type=oneshot
ExecStart=/sbin/fstrim --fstab --verbose --quiet

Значення: Якщо ви бачите додаткові секції під /etc/systemd/system/fstrim.service.d/, у вас може бути override. Переозначення — потужний інструмент і також хороший спосіб заплутати Майбутнього Вас.

Рішення: Якщо є override — переконайтеся, що він все ще обрізає те, що потрібно, і що вивід/логування не приховано.

Завдання 11: Перевірити підтримку discard через dm-crypt (LUKS)

cr0x@server:~$ sudo cryptsetup status cryptroot
/dev/mapper/cryptroot is active.
  type:    LUKS2
  cipher:  aes-xts-plain64
  keysize: 512 bits
  key location: keyring
  device:  /dev/nvme0n1p2
  sector size:  512
  offset:  32768 sectors
  size:    1953125000 sectors
  mode:    read/write

Значення: Це прямо не каже, чи увімкнено discard. Для цього зазвичай перевіряють /etc/crypttab або таблицю device-mapper. Але бачити dm-crypt у шляху — це сигнал: discards можуть бути заблоковані, якщо явно не дозволені.

Рішення: Якщо ви використовуєте LUKS і хочете TRIM, плануйте увімкнути discards обдумано (зважаючи на компроміс витоку метаданих).

Завдання 12: Підтвердити ліміти discard на вузлах device-mapper

cr0x@server:~$ lsblk -D -o NAME,TYPE,DISC-GRAN,DISC-MAX /dev/mapper/cryptroot
NAME     TYPE DISC-GRAN DISC-MAX
cryptroot crypt     4K       2T

Значення: Якщо dm-crypt-мапінг показує підтримку discard, шлях принаймні правдоподібний. Якщо він показує 0B/0B — discards блокуються на цьому шарі.

Рішення: 0B/0B тут: виправте опції crypttab або прийміть рішення «нема TRIM» для цього тому.

Завдання 13: Перевірити, чи файлова система підтримує обрізання

cr0x@server:~$ df -T /
Filesystem     Type  1K-blocks      Used Available Use% Mounted on
/dev/nvme0n1p2 ext4  960379552 302118912 609136192  34% /

Значення: ext4, xfs, btrfs зазвичай підтримують TRIM. Деякі рідкісні або старі файлові системи можуть не підтримувати або вимагати специфічних опцій.

Рішення: Якщо у вас щось екзотичне — перевірте підтримку і очікування. Якщо це ext4/xfs/btrfs і discard не працює — проблема ймовірно нижче файлової системи.

Завдання 14: Перевірити, чи ви віртуальна машина, якій не передають discards

cr0x@server:~$ systemd-detect-virt
kvm

Значення: Віртуалізація сама по собі не забороняє TRIM, але це означає, що гіпервізор і тип віртуального диска мають бути налаштовані на передачу discard/unmap.

Рішення: Якщо це VM — координуйтеся з платформною командою (або з собою, якщо ви й є та команда), щоб увімкнути передачу discard/unmap наскрізь.

Завдання 15: Сухий запуск, чи відхиляють discards на блоці

cr0x@server:~$ sudo blkdiscard -v -n /dev/nvme0n1p2
blkdiscard: /dev/nvme0n1p2: 0 bytes were discarded

Значення: -n — сухий запуск на багатьох системах (не виконує реального discard). Це перевіряє, що ioctl-шлях існує. Якщо ви отримуєте «Operation not supported», ядро не приймає discards для цього пристрою.

Рішення: Якщо тут не підтримується — fstrim цього не виправить. Виправте нижчий шар або припиніть спроби.

Завдання 16: Підтвердити, що таймер справді спрацював у вказаний час (час і пропущені запуски)

cr0x@server:~$ systemctl show -p LastTriggerUSec,LastTriggerUSecMonotonic fstrim.timer
LastTriggerUSec=Sun 2025-12-28 00:22:09 UTC
LastTriggerUSecMonotonic=120394889230

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

Рішення: Якщо таймер не тригерить — перевірте поведінку systemd-таймерів, системний годинник і чи не інгібується юніт.

Увімкнення таймера fstrim у Debian 13 (правильний спосіб)

У Debian з systemd ви хочете таймер, а не якийсь невідомий cron з блогу 2014 року. Таймер інтегрується з логуванням сервісів, залежностями та єдиним керуванням. Це також спрощує аудит.

Увімкнути й запустити таймер

cr0x@server:~$ sudo systemctl enable --now fstrim.timer
Created symlink /etc/systemd/system/timers.target.wants/fstrim.timer → /usr/lib/systemd/system/fstrim.timer.

Значення: Увімкнено для автозапуску при загрузці і запущено негайно. Відтепер Debian повинен щотижня автоматично виконувати TRIM.

Рішення: Якщо ви керуєте флотом — включіть це в базовий образ (Ansible, Salt тощо). Не покладайтеся на «комусь запам’ятається».

Якщо він замаскований — розмаскуйте

cr0x@server:~$ sudo systemctl unmask fstrim.timer
Removed "/etc/systemd/system/fstrim.timer".

Значення: Маскування — це «я дійсно хочу відключити» налаштування. Розмаскування знімає жорстку блокаду.

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

Примусово запустити зараз (не чекаючи тижня)

cr0x@server:~$ sudo systemctl start fstrim.service

Значення: Відсутність виводу — норма; перевіряйте журнал для результатів.

Рішення: Завжди перевіряйте в журналах, скільки байт обрізано. «Успішний запуск», що нічого не обрізав, може все одно вказувати на проблему.

Налаштувати розклад (обережно)

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

Якщо треба змінити розклад, використовуйте systemd override для таймера, а не редагування vendor unit. Наприклад: запуск щодня в передбачуваний час.

cr0x@server:~$ sudo systemctl edit fstrim.timer

Потім додайте override, наприклад (редактор systemd відкриється):

cr0x@server:~$ cat /etc/systemd/system/fstrim.timer.d/override.conf
[Timer]
OnCalendar=daily
RandomizedDelaySec=1h
Persistent=true

Значення: RandomizedDelaySec не дозволяє всім серверам у флоті обрізати одночасно. Persistent=true означає, що якщо машина була вимкнена у запланований час, systemd виконає пропущене завдання при наступному завантаженні.

Рішення: Для флоту зберігайте рандомізацію. Якщо хочете «точно о 02:00», прийміть, що можете спричинити невелику проблему синхронного навантаження.

cr0x@server:~$ sudo systemctl daemon-reload
cr0x@server:~$ sudo systemctl restart fstrim.timer

Перевірка TRIM наскрізно (те, що люди пропускають)

Неприємна правда: бачити, що fstrim повідомляє «X GiB trimmed» — добре, але не завжди достатньо. У VM, тонкопровізіонованому LUN, SAN або багатошаровому device-mapper важливо, чи пропагуються discards до фізичного бекенду.

Перевіряйте від файлової системи назовні

Почніть з виводу fstrim -av і записів у журналі. Якщо вони показують обрізані байти без помилок, файлова система видає discards.

Далі перевірте, чи блоковий пристрій дійсно підтримує discard за допомогою lsblk -D. Потрібні ненульові значення на найнижчому релевантному шарі (фізичний NVMe/SATA) і на мапованому шарі, який ви обрізаєте (LUKS/LVM).

Знайте, що означає «0 байт обрізано» насправді

Нуль обрізаних байтів може бути цілком нормальним. Якщо ви виконали trim вчора і з того часу нічого не змінилося — нічого обрізати. Це також може означати:

  • файлова система не підтримує TRIM,
  • пристрій не підтримує discard,
  • discard блокується проміжним шаром,
  • ви обрізаєте монтувальну точку, яка не на SSD-підтриманому сховищі.

Переконайтеся, що розклад дійсно виконується, коли машина «увімкнена»

Ноутбуки, лабораторні сервери та edge-вузли відомі тим, що їх вимикають ночами, ставлять у сплячий режим у вихідні, і їхні таймери ніколи не спрацьовують. Саме тому існує Persistent=true — використовуйте його там, де доречно.

Жарт №2: Якщо ваш таймер працює тільки тоді, коли сервер вимкнено — вітаємо, ви винайшли вікно обслуговування Шредінґера.

Де TRIM гине: шифрування, LVM, RAID, SAN та віртуальні машини

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

LUKS/dm-crypt: безпека проти звільнення

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

У Debian увімкнення discard для зашифрованого кореневого розділу часто вимагає додати discard до відповідного запису в /etc/crypttab, потім перебудувати initramfs і перезавантажитися. Не робіть цього необдумано у продакшені без розуміння ланцюжка завантаження і шляху відновлення.

cr0x@server:~$ sudo grep -vE '^\s*#|^\s*$' /etc/crypttab
cryptroot UUID=2d4f1f67-8f5f-4a4b-9a0e-2c6d52f9c5a1 none luks,discard

Значення: Опція discard каже dm-crypt передавати discard-запити далі. Без неї маповані пристрої часто показують 0B у lsblk -D.

Рішення: Вирішіть на підставі моделі загроз. Якщо увімкнули — перевірте lsblk -D як для dm-crypt шару, так і для підлеглого пристрою після перезавантаження.

LVM (thick і thin)

Класичний (thick) LVM на SSD зазвичай обрізається нормально, якщо базовий PV підтримує discard і нічого його не блокує. LVM thin provisioning — тут треба особливо обережно: discards можуть звільняти простір у thin pool, але налаштування й поведінка ядра мають значення.

Якщо ваша мета — звільняти простір у thin pool (або в upstream SAN), ви займаєтеся не тільки здоров’ям SSD, а й управлінням ємкістю. Перевірте весь ланцюжок.

mdadm RAID і апаратний RAID

Підтримка discard у програмному RAID (md) покращилась з часом, але залежить від рівня RAID і поведінки ядра. Апаратний RAID — окремий всесвіт: деякі контролери транслюють discard правильно; інші — відкидають. Часто єдиний спосіб дізнатися — тест і спостереження за звільненням ємності вгору по ланцюжку.

Віртуальні машини: гіпервізор має співпрацювати

У KVM/QEMU підтримка discard залежить від типу віртуального диска (virtio-scsi vs virtio-blk), налаштувань типу «discard=unmap» і бекенду зберігання. У VMware — від типу провізування віртуального диска та того, чи дозволено UNMAP. У хмарних провайдерів — від того, що вони експонують.

Гостьова ОС може бути налаштована ідеально, але все одно відправляти TRIM-запити у порожнечу, якщо хост відмовиться їх передавати.

Файлові системи: нюанси ext4, xfs, btrfs

  • ext4: Періодичний fstrim — нормальна практика. Опція монтування discard існує, але не обов’язкова.
  • xfs: Також підтримує fstrim. Добре працює на великих файлових системах; обрізання зазвичай просте.
  • btrfs: Підтримує discard і має свої нюанси. Багато адміністраторів досі віддають перевагу періодичному fstrim, щоб зробити поведінку явною.

Три корпоративні міні-історії з практики

Інцидент через хибне припущення: «Ми на SSD, отже TRIM має бути увімкнений»

Середня компанія мігрувала пакетний кластер з SATA SSD на нові NVMe. Вони зробили міграцію «розумно»: образи ОС запікалися один раз і розгорталися скрізь, а зберігання — за стандартною зашифрованою LVM-структурою. Усі припускали, що продуктивність автоматично покращиться.

Так і було — спочатку. Потім через кілька тижнів вузли з інтенсивними записами почали показувати довші часи виконання завдань. Нічого драматичного, але іноді вони не витримували внутрішні SLO. Графіки виглядали як повільний приплив, а не різке падіння. Це найгірший тип.

Команда шукала звичних підозрюваних: «шумних» сусідів, оновлення ядра, мережеві затримки, регресії на рівні додатків. Один розумний інженер запустив lsblk -D і помітив, що dm-crypt шар показує 0B discard. Ручний fstrim «працював» лише на деяких монтуваннях і обрізав малі обсяги. Диски робили garbage collection, не знаючи, що є вільним. Write amplification виріс, і стійка продуктивність просіла.

Виправлення не було екзотичним: вони явно увімкнули discards для зашифрованих розділів (після перевірки безпеки) і щотижня перевіряли байти в journald. Продуктивність стабілізувалася. Більший урок: «SSD» — це не конфігурація. Це апаратний факт. ПЗ-шлях усе ще треба налаштувати.

Після цього вони додали перевірку відповідності: якщо SSD-backed монтування показує 0B discard на мапованому шарі, вузол не проходить readiness. Це було трохи дратівливо, але врятувало від повторення помилки в наступному середовищі.

Оптимізація, що обернулась проти: увімкнули continuous discard скрізь

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

Ефект спочатку був тонким. Перцентилі затримок підповзали вгору, особливо під час пікового навантаження. Не постійно — просто достатньо, щоб дні на виклику були напруженими. Команда бачила зростання I/O wait, але не могла чітко пов’язати це з якоюсь зміною додатка.

Зрештою хтось зв’язав сплески з частими операціями discard у трасах блочного рівня. Безперервний discard додавав синхронну роботу в невдалих місцях, і бекенд зберігання не був у захваті від постійного шуму unmap. Оптимізація перетворилась на джиттер.

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

Нудна, але правильна практика, що врятувала ситуацію: логування та перевірки як рутина

Одна фінансова команда працювала на Debian з зашифрованими NVMe, поєднуючи bare metal і VM. Вони мали стандартний щотижневий операційний чекліст, який включав перевірку здоров’я systemd таймерів і запевнення, що набір сервісів з технічного обслуговування працює. Так, це було нудно. Так, це було ефективно.

Одного тижня вони помітили зміни у записах журналу fstrim: все ще «SUCCESS», але обрізані байти раптово впали майже до нуля у кількох VM, які зазвичай обрізали кілька гігабайт. Тригери не дали помилок, тому сповіщення не спрацювали. Люди помітили, бо дивились журнали.

Виявилось, що платформа віртуалізації оновилась і за замовчуванням змінилась: discard/unmap більше не передавалися гістьовим ОС для підмножини типів дисків. Гості продовжували відправляти discards; хост ввічливо їх ігнорував. Тонкопровізіоноване сховище почало роздуватися, і SAN-команда майже мала б поганий місяць.

Оскільки ops команда помітила це рано, виправлення пройшло чисто: оновили конфігурацію віртуальних дисків, дозволили discard і перевірили гостю- та хост-рівневі звіти про звільнення простору. Жодної екстреної покупки ємності, жодного уїк-енд-вікна, жодного «як ми це пропустили?» на рівні керівництва. Нудна практика окупилася тихо, як більшість хорошої роботи SRE.

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

1) «TRIM не виконується», але таймер вимкнений

Симптом: systemctl status fstrim.timer показує disabled/inactive; list-timers не містить запису про fstrim.

Корінна причина: Таймер ніколи не був увімкнений (або образ бази вимикав його давно).

Виправлення: Увімкніть і запустіть: systemctl enable --now fstrim.timer. Потім виконайте systemctl start fstrim.service і перевірте journalctl -u fstrim.service.

2) Таймер увімкнений, але нічого не відбувається тижнями

Симптом: Таймер увімкнений; LAST — «n/a» або дуже давній; машина часто вимкнена/у сні.

Корінна причина: Система не була увімкнена у запланований час; таймер не є persistent.

Виправлення: Додайте override таймера з Persistent=true. Або заплануйте частіше з рандомізацією.

3) Ручний fstrim зазнає невдачі з «Operation not supported»

Симптом: sudo fstrim -av показує помилки; blkdiscard повідомляє про відсутність підтримки; lsblk -D показує 0B discard.

Корінна причина: Пристрій або один із шарів (LUKS, RAID, гіпервізор) не підтримує/не передає discard.

Виправлення: Знайдіть шар, що показує 0B у lsblk -D. Увімкніть passthrough discard (опції crypttab/налаштування гіпервізора) або прийміть, що для цього шляху TRIM недоступний.

4) fstrim запускається, але обрізає лише «/» і пропускає /var або дані

Симптом: Журнал показує trim лише для деяких монтувань.

Корінна причина: fstrim --fstab обрізає лише монтування, визначені у fstab; монтування не в fstab або не змонтоване у час запуску.

Виправлення: Додайте монтувальну точку в /etc/fstab (або змініть юніт, щоб використовувати -a без --fstab, якщо ви справді хочете «те, що змонтовано»). Переконайтеся, що вона змонтована під час роботи таймера.

5) «0 байт обрізано» вічно, хоча ви очікували більше

Симптом: Trim успішний, завжди обрізає 0 байт.

Корінна причина: Немає нових звільнених блоків з часу останнього trim; файлова система майже заповнена; або discards зливаються/ігноруються вгору по ланцюжку.

Виправлення: Звільніть трохи місця і повторіть тест. Перевірте підтримку discard через lsblk -D на кожному шарі. У тонкопровізіонованих середовищах перевіряйте reclaim на бекенді окремо.

6) Ви увімкнули discard на зашифрованих томах і занервували через безпеку

Симптом: Перевірка безпеки вказує на ризик витоку метаданих.

Корінна причина: Discards можуть відкривати поведінку алокації.

Виправлення: Зробіть усвідомлене рішення. Якщо модель загроз вимагає цього — залишайте discards вимкненими й прийміть компроміс щодо продуктивності/зносу. Не «напівувімкнюйте» так, щоб ніхто пізніше не розумів поведінки.

7) Ви спробували «полагодити» через cron і тепер маєте два конкуруючих trims

Симптом: Trim-и запускаються двічі, журнали заплутані, інколи накладаються.

Корінна причина: Cron job та systemd таймер обидва активні.

Виправлення: Видаліть cron job. Залиште systemd таймер. Один керує процесом.

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

Чекліст A: Мінімальне виправлення (один хост Debian 13, bare metal SSD)

  1. Перевірте можливість discard: запустіть lsblk -D. Підтвердьте, що ваш SSD показує ненульові значення discard.
  2. Увімкніть таймер: systemctl enable --now fstrim.timer.
  3. Примусово запустіть: systemctl start fstrim.service.
  4. Перевірте результати: journalctl -u fstrim.service -n 50. Шукайте «X bytes trimmed» на очікуваних монтуваннях.
  5. Підтвердьте розклад: systemctl list-timers --all | grep fstrim.

Чекліст B: Багатошарове сховище (LUKS + LVM + SSD)

  1. Перевірте discard базового пристрою: lsblk -D /dev/nvme0n1.
  2. Перевірте discard мапованого пристрою: lsblk -D /dev/mapper/cryptroot (та LVs, якщо є).
  3. Якщо на мапованому шарі 0B discard — перегляньте /etc/crypttab на предмет опції discard, потім застосуйте зміну безпечно (initramfs + перезавантаження, якщо root зашифрований).
  4. Запустіть fstrim -av і підтвердіть обрізані байти.
  5. Підтвердьте щотижневу автоматизацію через таймер і журнали.

Чекліст C: Гість VM на спільному сховищі (план «довіряй, але перевіряй»)

  1. У гості: lsblk -D має показувати підтримку discard на віртуальному диску.
  2. У гості: запустіть fstrim -av. Підтвердьте відсутність «Operation not supported».
  3. Підтвердьте розклад таймера й записи journald з часом.
  4. На хості/сторіні зберігання: перевірте, що unmap/discard увімкнено для типу диску VM і що звільнення ємності спостерігається (залежить від платформи).
  5. Документуйте це. «Ми думаємо, що працює» — не є контролем.

Чекліст D: Базова політика для флоту (що вам автоматизувати)

  1. Переконайтеся, що fstrim.timer увімкнений на всіх вузлах на SSD.
  2. Перекрийте таймер override-ом з рандомізацією і персистентністю там, де доречно.
  3. Щоденний/щотижневий аудит: перевіряти systemctl is-enabled fstrim.timer і парсити journalctl -u fstrim.service на предмет останніх успішних запусків.
  4. Налаштуйте сповіщення на «Operation not supported» і на раптове глобальне падіння обрізаних байт по кластеру (це спосіб вловити регресії гіпервізора).

Поширені запитання (FAQ)

1) Мені використовувати опцію монтування discard чи щотижневий fstrim?

Для більшості систем використовуйте щотижневий fstrim. Це передбачувано і простіше для розуміння. Безперервний discard застосовуйте лише після вимірювань і переконання, що він не шкодить профілю затримок.

2) Чому Debian використовує таймер замість cron?

systemd таймери інтегруються з управлінням залежностями і журналами journald. Операційно їх легше інспектувати і аудитувати (list-timers, логи на рівні юніта), ніж загадковий crontab.

3) Якщо fstrim каже «X GiB trimmed», чи означає це, що SSD дійсно звільнив простір?

Це означає, що файлова система видала discards і ядро їх прийняло. У багатошарових конфігураціях (VM, SAN, тонке провізіювання) треба додатково підтвердити, що бекенд їх шанує.

4) Чи безпечно увімкнути discard на LUKS?

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

5) Чому fstrim пропускає деякі монтування?

Часто тому, що Debian запускає fstrim --fstab. Якщо монтування не в /etc/fstab (або не змонтоване), воно не буде включене. Підтвердіть через журнал і findmnt.

6) Чи погано, якщо fstrim обрізає 0 байт?

Не обов’язково. Якщо нічого нового не було звільнено, 0 — очікувано. Якщо на завантаженій системі завжди 0 і ви регулярно видаляєте дані — дослідіть підтримку discard через lsblk -D і перевірте, чи discards блокуються.

7) Чи може TRIM спричинити проблеми з продуктивністю?

Періодичний TRIM зазвичай має мінімальний вплив. Безперервний discard може додавати затримку в деяких навантаженнях. Також обрізання величезних файлових систем у піковий час може конкурувати за I/O — плануйте розумно.

8) Чи потрібен TRIM на enterprise SSD або NVMe?

Так, зазвичай. Enterprise-диски мають кращі контролери і прошивки, але їм все одно корисно, коли вони точно знають, який простір вільний, щоб зменшувати write amplification і підтримувати стабільну продуктивність.

9) Що щодо swap-розділів і TRIM?

Swap на SSD можна обрізати, але поведінка залежить від ядра і конфігурації. У більшості випадків важливішим є обрізання основних файлових систем і перевірка правильної підтримки discard.

10) Як довести, що TRIM виконується регулярно для аудиту?

Використовуйте systemctl list-timers для доказу розкладу і journalctl -u fstrim.service для доказу виконання та обрізаних байт. Це операційно переконливо й відтворювано.

Висновок: подальші кроки, що реально зменшують ризик

Увімкніть таймер, один раз виконайте trim і перевірте журнали. Це базова дія. Далі зробіть «дорослу» частину: підтвердіть підтримку discard через кожен шар зберігання, від якого ви залежите. Якщо ви в VM або на тонкопровізіонованому сховищі, вважайте «TRIM працює» багатокомандним контрактом, а не налаштуванням лише в гості.

Практичні наступні кроки:

  1. Запустіть lsblk -D і знайдіть, де discard стає 0B/0B.
  2. Увімкніть і запустіть fstrim.timer; вручну виконайте fstrim.service один раз.
  3. Перевірте журнали — чи показують вони значущі обрізані байти на потрібних монтуваннях.
  4. Якщо шифрування: вирішіть щодо discard в crypttab відповідно до моделі загроз, а потім впровадьте акуратно і перевірте після перезавантаження.
  5. Якщо віртуалізовано: перевірте налаштування гіпервізора для discard/unmap і підтвердіть звільнення на бекенді.
  6. Для флоту: додайте перевірку відповідності — таймер увімкнений + недавні успішні записи trim у журналі, і налаштуйте сповіщення на зміни у поведінці trim.

TRIM не гламурний. Саме тому він тихо виходить з ладу. Зробіть його знову нудним — увімкненим, перевіреним і буденним.

← Попередня
Proxmox: збій PCI passthrough — групи IOMMU і класичні пастки
Наступна →
Docker «manifest unknown»: теги проти дайджестів — пояснення й виправлення

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