El canario OOM es experimental y está desactivado por defecto. Su comportamiento puede cambiar
entre versiones de ClickHouse hasta que se complete la validación en producción.
Descripción general
SIGKILL, normalmente el mayor consumidor, que
en un host dedicado es el propio clickhouse-server. Se pierde todo
el servidor en lugar de darle la oportunidad de recuperarse.
El canario OOM cambia quién muere primero. Ejecuta un pequeño proceso hijo
de sacrificio que se convierte en el objetivo OOM más atractivo, para que el kernel lo mate
a él en lugar del servidor. Luego, el servidor detecta la muerte, confirma que fue un evento
de OOM y alivia la presión de memoria para poder sobrevivir.
El canario no aumenta ningún límite de memoria ni sustituye unos
límites correctos (consulta Memory overcommit y
max_server_memory_usage). Es una última línea de defensa que intercambia una cantidad pequeña
y fija de memoria por la posibilidad de sobrevivir a un pico de uso de memoria.
Cómo funciona
clickhouse oom-canary independiente. Ajusta su propio
oom_score_adj al máximo (1000) para que el kernel lo seleccione primero; luego
reserva, accede a y aplica mlock sobre oom_canary_size bytes (100 MB de forma predeterminada) para que
su conjunto residente sea real. Se termina automáticamente si el servidor se detiene.
En el servidor, un hilo de monitorización observa al canario (mediante pidfd) y reacciona cuando
muere:
- Lo mata
SIGKILLcon evidencia de OOM en el cgroup → ejecuta la respuesta ante OOM y luego relanza un canario nuevo. - Lo mata sin evidencia de OOM (por ejemplo, con un
kill -9manual), o termina por un fallo transitorio → solo se relanza; no hay respuesta. - Fallo permanente durante la configuración, o apagado del servidor → el canario se desactiva.
oom_kill de memory.events.local en cgroup v2.
Es intencionadamente local al cgroup: los contadores jerárquicos o de todo el host pueden
incrementarse por procesos no relacionados y provocar respuestas falsas.
Ante un OOM confirmado, la respuesta ejecuta estos pasos independientes: registrar un mensaje FATAL,
purgar las arenas del asignador (jemalloc), intentar cancelar todas las
consultas en ejecución, cancelar todas las fusiones y mutaciones, y encolar un evento en
system.crash_log. Los registros del sistema no se
vacían de forma síncrona, porque forzar E/S bajo presión de memoria puede empeorar las cosas.
Requisitos
- Linux ≥ 5.3. El monitor controla el canario mediante
pidfd_open; en kernels más antiguos el canario se desactiva al arrancar. No tiene efecto en plataformas que no son Linux. - cgroup v2 con
memory.events.localpara la respuesta ante OOM. Sin ello, el canario sigue relanzándose después de unSIGKILL, pero no puede confirmar un OOM, por lo que la respuesta nunca se ejecuta (se registra una advertencia al arrancar). - capacidad
mlock(opcional). Bloquear la memoria del canario requiereCAP_IPC_LOCKo unRLIMIT_MEMLOCKsuficiente; si falla, el canario registra una advertencia y su memoria puede enviarse a swap, lo que debilita su función como objetivo de OOM.
Configuración
Observabilidad
system.crash_log con signal = 9 y una
signal_description que menciona OOM Canary: