Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

OOM-канарейка

Экспериментальная возможность

Обзор

Когда у хоста или 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.

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

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

Setting Default Description
oom_canary_enable false Включить OOM-канарейку.
oom_canary_size 104857600 (100 MB) Количество байтов, которое канарейка выделяет и использует. Чем больше значение, тем более вероятной целью при OOM она становится.
oom_canary_relaunch true Перезапускать канарейку после её завершения (если это не постоянный сбой инициализации и не штатная остановка) с учётом указанных ниже ограничений.
oom_canary_max_rapid_relaunches 10 Максимальное число последовательных быстрых перезапусков до отключения автоперезапуска, чтобы избежать постоянных циклов перезапуска. Счётчик сбрасывается, если канарейка проработает дольше oom_canary_max_backoff_seconds.
oom_canary_initial_backoff_seconds 1 Начальная задержка между перезапусками; каждый раз удваивается до максимального значения.
oom_canary_max_backoff_seconds 60 Максимальная задержка между перезапусками.
<clickhouse>
    <oom_canary_enable>1</oom_canary_enable>
    <oom_canary_size>104857600</oom_canary_size>
</clickhouse>

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

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

SELECT event_time, signal, signal_description
FROM system.crash_log
WHERE signal = 9 AND signal_description LIKE '%OOM Canary%'
ORDER BY event_time DESC;

Жизненный цикл канарейки и каждый этап реакции на OOM также записываются в журнал сервера.

Navigation