Skip to main content
OOM-канарейка является экспериментальной и по умолчанию отключена. Её поведение может меняться между версиями ClickHouse до завершения валидации в продакшне.

Обзор

Когда у хоста или cgroup памяти заканчивается память, OOM-killer в Linux завершает процесс с помощью SIGKILL — обычно самого крупного потребителя, которым на выделенном хосте является сам clickhouse-server. В результате вместо шанса на восстановление сервер целиком выходит из строя. OOM-канарейка меняет то, кто погибает первым. Она запускает небольшой жертвенный дочерний процесс, который делает себя наиболее привлекательной целью для OOM, чтобы ядро убило его, а не сервер. Затем сервер обнаруживает его завершение, подтверждает, что причиной был OOM, и сбрасывает давление на память, чтобы выжить. Канарейка не увеличивает никакой лимит памяти и не заменяет корректно настроенные ограничения (см. Оверкоммит памяти и max_server_memory_usage). Это последний рубеж защиты: за небольшой, фиксированный объём памяти она даёт шанс пережить резкий всплеск потребления памяти.

Как это работает

Канарейка — это отдельный процесс clickhouse oom-canary. Он устанавливает для себя oom_score_adj на максимум (1000), чтобы ядро выбрало его первой целью, затем выделяет oom_canary_size байт (по умолчанию 100 МБ), обращается к этой памяти и вызывает mlock, чтобы его резидентный объём памяти был реальным. Этот процесс автоматически завершается, если сервер останавливается. На сервере поток мониторинга следит за канарейкой (через pidfd) и реагирует, когда она завершается:
  • Завершена сигналом SIGKILL при наличии признаков OOM в cgroup → выполнить реакцию на OOM, затем заново запустить новую канарейку.
  • Завершена без признаков OOM (например, при ручном kill -9) или завершилась из-за временного сбоя → только перезапуск, без реакции.
  • Постоянная ошибка инициализации или остановка сервера → канарейка отключается сама.
Признаки OOM берутся только из счётчика oom_kill в memory.events.local cgroup v2. Это намеренно ограничено текущей cgroup: иерархические или общесистемные счётчики могут увеличиваться из-за несвязанных процессов и вызывать ложные срабатывания. При подтверждённом OOM реакция выполняет следующие независимые шаги: записывает сообщение FATAL в журнал, очищает арены аллокатора (jemalloc), по возможности отменяет все выполняющиеся запросы, отменяет все слияния и мутации и ставит событие в очередь system.crash_log. Системные журналы не сбрасываются на диск синхронно, потому что принудительный I/O при нехватке памяти может только ухудшить ситуацию.

Требования

  • Linux ≥ 5.3. Монитор управляет канарейкой через pidfd_open; на более старых ядрах канарейка отключается при запуске. На платформах, отличных от Linux, это не даёт никакого эффекта.
  • cgroup v2 с memory.events.local для реакции на OOM. Без этого канарейка всё равно перезапускается после SIGKILL, но не может подтвердить OOM, поэтому реакция не запускается (при запуске в журнал записывается предупреждение).
  • Привилегия mlock (необязательно). Чтобы заблокировать память канарейки, требуется CAP_IPC_LOCK или достаточный RLIMIT_MEMLOCK; если это не удаётся, канарейка записывает предупреждение, а её память может быть выгружена в swap, что снижает её эффективность как цели OOM.
memory.oom.groupЕсли для cgroup сервера в cgroup v2 включён memory.oom.group, ядро при OOM завершает всю cgroup как единое целое — сервер завершается вместе с канарейкой, и реакция не запускается. В этом режиме канарейка не может защитить сервер; при запуске в журнал записывается предупреждение.

Конфигурация

Работа канарейки управляется настройками сервера, которые задаются как элементы верхнего уровня конфигурации сервера и применяются после перезапуска.

Обсервабилити

Подтверждённый OOM создаёт строку в system.crash_log с signal = 9 и signal_description, где упоминается OOM Canary:
Жизненный цикл канарейки и каждый этап реакции на OOM также записываются в журнал сервера.
Последнее изменение 24 июля 2026 г.