journalctl disk usage — vacuum — черпак, SystemMaxUse — кран
journalctl disk usage с замерами: что считает --disk-usage, почему после --vacuum-size всё возвращается и какой один drop-in навсегда закрывает кран.
SystemMaxUse — это вентиль на трубе.Что на самом деле измеряет journalctl --disk-usage?
Главное предложение: journalctl --disk-usage показывает размер файлов журнала на диске — и архивных, и активных, — которые живут в /var/log/journal на любой постоянной установке. Это чтение: команда ничего не удаляет и ничего не перезапускает. На стендовой VM, до добавления каких-либо логов:
$ sudo journalctl --disk-usage
Archived and active journals take up 48.2M in the file system.
$ ls /var/log/journal/
fd766b9ea5a540e68e6c43ea74f98a15 ← one directory per machine-id
проверка: стоковый Arch несёт /var/log/journal сразу — Storage=auto (закомментированный дефолт #Storage=persistent) означает persistent с первой загрузки. Запускай с sudo: без членства в adm/systemd-journal/wheel чтение обычного пользователя покрывает только его собственные файлы — стенд замерил 16M от пользователя и 48.2M от root в одну и ту же секунду.
Здесь людей подводят две вещи. Первая: число включает активный журнал — файл, в который journald пишет прямо сейчас, — так что даже свежая загрузка никогда не равна нулю. Вторая: если /var/log/journal не существует, journald волатилен: всё живёт в /run/log/journal (tmpfs), читается около нуля и умирает при перезагрузке. Это не «маленький журнал» — это отсутствие истории журнала вообще. sudo mkdir -p /var/log/journal && sudo systemctl restart systemd-journald переключает тебя на persistent.
Почему журнал всё растёт и растёт?
Потому что кран открыт — так задумано. Стоковый /etc/systemd/journald.conf несёт все ручки размера закомментированными:
$ grep -E '^#(Storage|Compress|SystemMaxUse)' /etc/systemd/journald.conf
#Storage=persistent
#Compress=yes
#SystemMaxUse=
проверка: скопировано со стендовой машины — SystemMaxUse есть в файле только как комментарий; journald читает его как незаданный и не держит никакого потолка.
Без потолка ничто не стареет и ничто не ограничивает: болтливый сервис или один шумный cron добавляют мегабайты в день — вечно. Стенд доказал наклон честным способом — устроить поток, форсировать ротацию и снова прочитать счётчик:
$ for i in $(seq 1 400); do logger -t benchflood "entry $i: …~1KB line…"; done
$ sudo journalctl -t benchflood --no-pager | wc -l # all 400 landed
400
$ sudo journalctl --rotate # close the active file
$ sudo journalctl --disk-usage
Archived and active journals take up 56.2M in the file system.
проверка: 48.2M → 56.2M от одного небольшого потока. В этом спрятаны две квитанции: рост становится виден только на ротации — journald преаллоцирует активный файл чанками по 8M, так что потоки внутри файла не двигают счётчик, пока файл не закроется, — и du -sh /var/log/journal (57M) сходится с числом самого journald в пределах округления.
Поток был 400 строк по килобайту — погрешность округления на фоне дневного шума настоящей машины. Размер не главное; главное — направление: без потолка единственное устойчивое состояние — «больше», шагами по 8M, которые ты не выбирал.
Удаляет ли journalctl --vacuum-size это насовсем?
Нет — и признание напечатано в собственном выводе команды. Vacuum — ведро для вычерпывания: один зачерпок, мгновенное облегчение, конструктивно ничего:
$ sudo journalctl --vacuum-size=1M
Deleted archived journal …/system@…-adf16c8ac48706f4.journal~ (8M).
Deleted archived journal …/system@d1d286….journal (8.2M).
Deleted archived journal …/user-1000@…journal~ (8M).
Deleted archived journal …/system@…c3f9281226bbfdc4.journal~ (8M).
Deleted archived journal …/system@…5244-….journal (4.4M).
Deleted archived journal …/user-1000@…57b6-….journal (3.4M).
Deleted archived journal …/system@…59c8-….journal (976K).
Deleted archived journal …/user-1000@…59cb-….journal (296K).
Vacuuming done, freed 41.4M of archived journals from /var/log/journal/fd766b9e….
$ sudo journalctl --disk-usage
Archived and active journals take up 16M in the file system.
проверка: список удалений и «Vacuuming done, freed 41.4M» — это собственный stdout --vacuum-size, вставлен как есть — 56.2M упал до 16M.
Всмотрись в пол, потому что именно его cron-задачи никогда не замечают: 16M остались. Это два активных файла журнала — system.journal и user-1000.journal, преаллоцированные по 8M каждый, — а --vacuum-size удаляет только архивные файлы. Vacuum не может срезаться ниже того, в что journald пишет прямо сейчас, каким бы маленьким ни было переданное число.
Затем тест на долив — часть, которую никто не запускает. Тот же поток снова, ротация, чтение:
$ sudo journalctl --disk-usage
Archived and active journals take up 20.3M in the file system.
$ sudo du -sh /var/log/journal
21M /var/log/journal
проверка: 16M → 20.3M от идентичного потока в 400 строк — vacuum удалил историю; о завтрашнем дне он не изменил ничего.
Вот почему vacuum-cron — народное средство, которое так и не работает как надо: он борется с краном ведром, по расписанию, вечно. Если cron еженедельно запускает --vacuum-size=100M, а журнал достигает 1G посреди недели, читатели платят за 1G всю неделю. И каждый проход — тихое событие потери данных: освобождаются самые старые строки, ровно та история, за которой ты тянешься во время инцидента.
Как ограничить размер журнала навсегда?
Один drop-in, один рестарт — и дальше journald сам держит потолок, на каждой ротации, вечно:
$ sudo mkdir -p /etc/systemd/journald.conf.d
$ sudo tee /etc/systemd/journald.conf.d/size.conf >/dev/null <<'EOF'
[Journal]
SystemMaxUse=5M
EOF
$ sudo systemctl restart systemd-journald
$ sudo systemd-analyze cat-config systemd/journald.conf | grep SystemMaxUse
SystemMaxUse=5M
проверка: systemd-analyze cat-config печатает ОБЪЕДИНЁННЫЙ конфиг — SystemMaxUse=5M из drop-in живой, а не просто записан в файл, который никто не читает.
Теперь тот же идентичный поток, который поднял вычерпанный журнал до 20.3M:
$ for i in $(seq 1 400); do logger -t benchflood "entry $i: …"; done
$ sudo journalctl --rotate
$ sudo journalctl --disk-usage
Archived and active journals take up 1.2M in the file system.
$ sudo ls -lh /var/log/journal/*/ | awk '{print $5, $9}'
640K system.journal
640K user-1000.journal
$ sudo journalctl -t benchflood --no-pager | wc -l
0
проверка: тот же поток, который поднял журнал без потолка до 20.3M, оставил журнал с потолком на 1.2M — journald ротировал, применил потолок и удалил поток начисто: 400 записей вошло, 0 удержано, без cron, без надзора.
Заметь, что потолок сделал то, чего не мог vacuum: он спустился ниже пола в 16M. Vacuum никогда не трогает активные файлы, но потолок управляет самой ротацией — journald пересоздаёт активные файлы меньшими, как только потолок живой. Это разница между вычерпыванием и сантехникой.
Выбирай число по запасу, а не по вкусу: проверь сегодняшний размер через journalctl --disk-usage, затем поставь SystemMaxUse примерно в максимум, который ты вообще хочешь держать — 100M или 200M для рабочей станции более чем достаточно; загруженному серверу может понадобиться 1G. SystemKeepFree=1G — родной брат «ремня и подтяжек»: ограничь журнал и пообещай файловой системе пол. Удаляется всегда самое старое из архивных файлов — journald держит активный файл и всё, что влезает под твой потолок.
Лечение, по порядку
Черпак против вентиля, одним взглядом
| инструмент | что делает | когда помогает | замерено на стенде |
|---|---|---|---|
--vacuum-size=1M | удаляет старейшие архивные журналы до заданного размера, один раз | экстренно: диск полон прямо сейчас | 56.2M → 16M (освобождено 41.4M), снова 20.3M от следующего идентичного потока |
--vacuum-time=2weeks | то же, по возрасту вместо размера | разовая чистка архива | та же форма одного выстрела — ничто не остановит отрастание |
SystemMaxUse=5M drop-in | journald сам держит потолок на каждой ротации | навсегда: кран закрывается | идентичный поток удержан на 1.2M — записи потока удалены начисто (400 вошло, 0 осталось) |
SystemKeepFree=1G | обещает файловой системе свободное место, независимо от потолка | маленькие диски, вместе с потолком | дух стокового дефолта, теперь явно |
«Vacuum вычерпывает ванну; SystemMaxUse закрывает кран. Вычерпывают все — ванна побеждает по умолчанию.»
чего стенд не покрыл
Замерено: одна свежая VM Arch (systemd 262, 262.1-1-arch) — базовое использование, поток в 400 строк с форсированной ротацией, --vacuum-size=1M с его полным stdout, идентичный поток-долив, drop-in SystemMaxUse=5M + рестарт с перечитыванием объединённого конфига, идентичный поток под потолком и файловые свидетели du/ls на каждом шаге. Не замерено: взаимодействие SystemMaxFileSize/числа файлов под потолком, per-unit журналы LogNamespace=, удалённый сбор логов (systemd-journal-remote), запечатывание с forward secrecy (Seal=) и удержание по времени (MaxRetentionSec). Строки потока шли через syslog-сокет, который обрезает длинные строки (дошло ~1 KB) — на учёт не влияет, поскольку каждое число выше — собственный --disk-usage journald, перекрёстно проверенный через du. Базовая линия несла архивы прошлой загрузки (обжитые 48.2M, как на любой настоящей машине). Одна машина, одна сборка: переносима — чтение «кран против черпака»; твой собственный --disk-usage — вердикт.
СТЕНД, ПРОВЕРЕННЫЙ ВРУЧНУЮ · systemd 262 (262.1-1-arch) · свежая VM Arch · последний тест 2026-11-12
Одно число говорит правду — journalctl --disk-usage. Одна строка держит её правдой — SystemMaxUse. Закрой кран; ведро — на пенсию. ■