Introduction
A plusieurs reprises, des utilisateurs se sont plaints d’une perte de connexion entre leur application et leur base PostgreSQL, hébergée sur une Linux Centos 6.
Le premier réflexe est de hausser mentalement les épaules en accusant le réseau ou le connecteur de client, tant la base était jusqu’alors stable et solide.
Mais la conscience professionnelle étant prioritaire en toutes circonstances, il fallait tout de même vérifier les logs locaux du serveur avant de passer élégamment le problème à quelqu’un d’autre…
Preuve, si besoin, qu’il faut toujours vérifier au lieu de supposer : sur la machine, la situation était loin d’être claire…
Le problème
Autour de l’heure de l’incident – et autour de celle des incidents précédents – il y a cette série de message :
<br data-mce-bogus="1"> 2116-31-12 16:52:04 CET [1634]: [5-1] app=,user=,db=,client= LOG: server process (PID 18349) was terminated by signal 9: Killed 2116-31-12 16:52:04 CET [1634]: [6-1] app=,user=,db=,client= DETAIL: Failed process was running: EXECUTE procstock_186e0 2116-31-12 16:52:04 CET [1634]: [7-1] app=,user=,db=,client= LOG: terminating any other active server processes 2116-31-12 16:52:04 CET [19124]: [3-1] app=[unknown],user=UsualSuspect,db=LaDB,client=192.168.001.001(50525) WARNING: terminating connection because of crash of another server process 2116-31-12 16:52:04 CET [19124]: [4-1] app=[unknown],user=UsualSuspect,db=LaDB,client=192.168.001.001(50525) DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
Cela correspondant à une session interrompue violemment (kill -9, SIGKILL…).
L’explication
Le postmaster protège sa mémoire partagée d’un risque de corruption en ré-initialisant les backends (le terme désignant une session cliente dans PostgreSQL). C’est un comportement voulu et indiqué dans la documentation. Si l’application sait se reconnecter automatiquement, l’incident est transparent. Il est même invisible si vous ne surveillez pas les messages d’erreur dans le log.
Dans le cas présent, la loi de Murphy triomphe puisque l’application est incapable de se reconnecter toute seule. Et les actions effectuées suite à l’alerte (bascule du serveur d’application, de la base de données, relance…) n’ont fait que brouiller encore plus les traces, démontrant, s’il le fallait, que faire passer des commandes sans comprendre la cause d’un problème n’apporte jamais rien de bon.
Après une recherche sérieuse (comprendre : « faite par nous »; L’humilité est si rare que nous la laissons aux autres), d’autres messages ont été trouvés et permettent de reconstituer le déroulement d’un incident :
- PostgreSQL intercepte une interruption brutale d’une session et, comme prévu, relance tous les backends.
- Cela provoque la déconnexion de l’application qui, incapable de se reconnecter, reste bloquée.
- S’en suit une série d’actions qui finissent par remettre le service en état. Affaire classée jusqu’à la prochaine fois.
Mais d’où vient le « SIGKILL » qui est à l’origine de la réaction de protection du Postmaster ?
Le fin mot de l’histoire se trouve dans le log système Linux :
dmseg
Qui, au milieu de milliers de lignes, indiquait :
Out of memory: Kill process 18349 (postmaster) score 851 or sacrifice child Killed process 18349, UID 91, (postmaster) total-vm:9880016kB, anon-rss:7289732kB, file-rss:55132kB
Ah ben oui forcément, si le système d’exploitation considère que PostgreSQL consomme trop de mémoire et le descend en plein vol, cela explique bien le coup de faiblesse de ce dernier. Difficile de rester serein lorsqu’on vous tire dessus à balles réelles.
Conclusion
La combinaison « PostgreSQL + Linux » est une solution remarquablement stable une fois configurée correctement.
Dans le cas présent, justement, c’est la configuration du système d’exploitation qui avait été modifiée, ré-activant par erreur le Out-Of-Memory Killer (plus d’informations ici ) avec l’effet malheureux que nous avons vu. Cela aurait pu se produire avec n’importe quel programme consommateur de mémoire (pour l’anecdote, ça nous ait arrivé il y a des années avec un serveur Sybase IQ. Mais siiiiii… le stockage colonne de Sybase. Révolutionnaire ! Rupture technologique ! Vous avez oublié ? Comme tout le monde).
L’administrateur système a re-configuré ce mécanisme – normal – de Linux et plus d’incidents.
Alors, que retenir de cet incident ?
Qu’il faut aller au-delà de la présomption d’innocence et en trouver des preuves, quand c’est possible.
Que les actions prises dans l’urgence et sans méthode aggravent la situation.
Qu’une série d’actions qui « font tomber en marche » après un problème ne le résoud pas. Du coup, il apparaîtra de nouveau. Au plus mauvais moment.
Que votre première impression était correcte : ce n’était pas la faute de la base de données.
C’est bon de le savoir. Ça l’est encore plus de le démontrer !
Des problèmes ? des questions ? Exprimez-vous ! Les commentaires sont ouverts. Coquilles et fautes de grammaires sont notre lot quotidien : signalez-les nous à m.capello@dbsqware.com
Crédit photo : le célèbre Ash, de la série Evil Dead, interprété par le non moins célèbre Bruce Campbell. Et le Duo Dynamique Bougret et Charolles, tels qu’immortalisés par la plume de Marcel Gotlieb, dans les Rubriques-à-brac, chez Dargaud.