Skip to main content
L’OOM canary est expérimental et désactivé par défaut. Son comportement peut évoluer d’une version de ClickHouse à l’autre jusqu’à la fin de la validation en production.

Vue d’ensemble

Lorsqu’un hôte ou un cgroup mémoire tombe à court de mémoire, le killer OOM (out-of-memory) de Linux termine un processus avec SIGKILL — généralement le plus gros consommateur, qui, sur un hôte dédié, est clickhouse-server lui-même. On perd alors l’ensemble du serveur au lieu de lui laisser une chance de se rétablir. L’OOM canary change l’ordre des victimes. Il exécute un petit processus enfant sacrificiel qui se rend lui-même prioritaire pour l’OOM killer, afin que le noyau le tue à la place du serveur. Le serveur détecte alors sa mort, confirme qu’il s’agissait d’un événement OOM, puis réduit la pression mémoire pour pouvoir survivre. Le canary n’augmente aucune limite mémoire et ne remplace pas des limites correctement définies (voir Memory overcommit et max_server_memory_usage). Il constitue une dernière ligne de défense qui échange une petite quantité fixe de mémoire contre une chance de survivre à un pic de consommation mémoire.

Comment cela fonctionne

Le canary est un processus clickhouse oom-canary distinct. Il définit son propre oom_score_adj au maximum (1000) pour que le noyau le cible en premier, puis alloue, touche et applique mlock à oom_canary_size octets (100 Mo par défaut) afin que sa mémoire résidente soit bien réelle. Il est automatiquement tué si le serveur s’arrête. Dans le serveur, un thread de surveillance observe le canary (via pidfd) et réagit lorsqu’il meurt :
  • Tué par SIGKILL avec preuve d’OOM au niveau du cgroup → exécuter la réponse OOM, puis relancer un nouveau canary.
  • Tué sans preuve d’OOM (par exemple, un kill -9 manuel), ou arrêté après une défaillance transitoire → relance uniquement, sans réponse.
  • Échec permanent de l’initialisation, ou arrêt du serveur → le canary se désactive.
La preuve d’OOM provient uniquement du compteur oom_kill de memory.events.local du cgroup v2. Elle est volontairement locale au cgroup : des compteurs hiérarchiques ou à l’échelle de l’hôte peuvent être incrémentés par des processus sans rapport et déclencheraient de fausses réponses. Lorsqu’un OOM est confirmé, la réponse exécute ces étapes indépendantes : consigner un message FATAL, purger les arènes de l’allocator (jemalloc), annuler dans la mesure du possible toutes les queries en cours d’exécution, annuler tous les merges et mutations, et mettre en file d’attente un événement dans system.crash_log. Les log système ne sont pas vidés de manière synchrone, car forcer des E/S sous pression mémoire peut aggraver la situation.

Exigences

  • Linux ≥ 5.3. Le moniteur détient le canari via pidfd_open ; sur les noyaux plus anciens, le canari se désactive au démarrage. Cela est sans effet sur les plateformes non Linux.
  • cgroup v2 avec memory.events.local pour la réponse OOM. Sans cela, le canari se relance bien après un SIGKILL, mais ne peut pas confirmer un OOM ; la réponse n’est donc jamais exécutée (un avertissement est consigné au démarrage).
  • Capacité mlock (facultative). Le verrouillage de la mémoire du canari nécessite CAP_IPC_LOCK ou une valeur RLIMIT_MEMLOCK suffisante ; en cas d’échec, le canari consigne un avertissement et sa mémoire peut être paginée sur disque, ce qui le rend moins efficace comme cible OOM.
memory.oom.groupSi memory.oom.group de cgroup v2 est activé pour le cgroup du serveur, le noyau tue l’ensemble du cgroup comme une seule unité en cas d’OOM : le serveur meurt en même temps que le canari et la réponse n’est jamais exécutée. Le canari ne peut pas protéger le serveur dans ce mode ; un avertissement est consigné au démarrage.

Configuration

Le canary est contrôlé par les paramètres du serveur, définis comme éléments de premier niveau de la configuration du serveur et appliqués au redémarrage.

Observabilité

Un OOM confirmé génère une ligne dans system.crash_log avec signal = 9 et un signal_description mentionnant OOM Canary :
Le cycle de vie du canary et chaque étape de la réponse aux OOM sont également consignés dans le journal du serveur.
Dernière modification le 24 juillet 2026