Crash de Gladys lors de la sauvegarde GladysPlus

Je suis embêté depuis plusieurs semaines avec ma sauvegarde Gladys, mais je n’avais pas pris le temps de faire les vérifications nécessaires.

En fait, chaque nuit quand la sauvegarde se déclenche, Gladys se bloque (plus d’affichage du dashboard, plus de déclenchement de scènes, …), cela dure environ 2h, puis je reçois dans Telegram le message « Gladys vient de redémarrer » (c’est le résultat d’une scène ayant pour déclencheur « Gladys démarre »), et tout fonctionne à nouveau.

Avec l’aide de Claude ce matin, j’ai exploré le souci. Lors d’une étape de son analyse, j’ai répondu que j’avais « une base moyenne (quelques gigas) », mais je ne suis pas sûr d’avoir bien répondu. Dans l’historique de mes sauvegardes, je vois ça :

En première action, Claude m’a suggéré de modifier la RAM allouée à Gladys (avec la commande sudo docker update --memory="6g" --memory-swap="8g" gladys), pour que mon souci ne provoque plus un blocage pendant plusieurs heures. Et effectivement quand j’ai relancé manuellement une sauvegarde, le crash et la remise en route se sont faits en 3-4 minutes. C’est mieux pour ne pas bloquer ma domotique, mais ça ne résoud pas encore le souci de sauvegarde en échec :wink:

Je tourne sur un mini-PC Intel NUC5PPYB, processeur N3700 4 cœurs 1.6GHz, 8Go de RAM, sous Ubuntu 22.04, et Gladys a été installé avec la commande « docker run » standard. Je n’ai pas d’autre chose que Gladys sur ce serveur.

Voilà le rapport final de Claude :

Pic mémoire / OOM-kill pendant la sauvegarde GladysPlus

Résumé

Chaque sauvegarde GladysPlus (automatique 2h-4h ou manuelle) fait grimper la RAM du
conteneur Gladys au point de déclencher un OOM-kill du process Node, suivi d’un
redémarrage automatique du conteneur.

Environnement

  • Gladys en Docker sur Mini PC/NUC
  • RAM totale de l’hôte : 7,7 Go (8 Go non extensible)
  • Base de données : taille moyenne (quelques Go)
  • Conteneur gladys limité manuellement à 6 Go de RAM (docker update --memory)
    pour éviter que l’OOM ne déstabilise tout l’hôte (swap-thrashing observé avant
    la mise en place de cette limite)

Reproduction

Sauvegarde manuelle déclenchée à 09h36.

  • 09:36:01 - RSS avant backup : 4388,77 MB, Heap 233,97/392,50 MB
  • 09:36:01 - DuckDB avant backup : Total 2248,75 MB (BASE_TABLE: 2246,00 MB,
    IN_MEMORY_TABLE: 2,75 MB)
  • 09:36:04 - Ouverture d’une seconde instance DuckDB dédiée au backup
    (duckDbCreateBackupInstance, memory_limit=1024MB, threads=2, READ_ONLY)
    pour exporter vers un dossier Parquet
  • 09:38 - RAM du conteneur : ~6 Go (limite atteinte)
  • 09:40 - Out of memory: Killed process ... (MainThread)
  • 09:41 - Conteneur redémarré, Gladys de nouveau fonctionnel

Sans la limite de 6 Go posée manuellement au niveau Docker, le même phénomène en
conditions réelles (sauvegarde nocturne automatique) a provoqué un épisode de
swap-thrashing sur l’hôte entier de 02h23 à 04h44 (dashboard et scènes
inutilisables), le RSS du process ayant atteint 6774,54 MB avant kill (dmesg :
Out of memory: Killed process 1542 (MainThread) total-vm:30424440kB, anon-rss:6774536kB).

Hypothèse

La nouvelle instance DuckDB créée pour le backup (limitée à 1024 MB) semble
s’additionner à la mémoire déjà occupée par l’instance DuckDB principale
(~2,25 Go), plutôt que de partager/respecter un budget mémoire global du process.
Sur une machine où le process tourne déjà à ~4,4 Go au repos, l’ajout de
~1 Go supplémentaire suffit à dépasser la RAM disponible.

Question pour les mainteneurs

  • Est-il normal que BASE_TABLE reste quasi intégralement en mémoire (2,25 Go)
    au repos, hors sauvegarde, pour une base de taille moyenne ?
  • Le memory_limit=1024MB de l’instance de backup peut-il être abaissé, ou le
    process de backup peut-il streamer/traiter par lots au lieu de charger autant
    en mémoire, pour rester dans une enveloppe totale raisonnable même sur du
    matériel à 8 Go de RAM ?

@pierre-gilles je ne suis pas sûr que tu auras le temps de regarder ça avant tes vacances… Ça attendra ton retour si ce n’est pas possible :wink:

Je laisse @mutmut t’aider :slight_smile: (ou quelqu’un d’autres!)