Vous n'êtes pas identifié(e).
Bonjour,
En naviguant dans les logs PG (v 9.6), je suis tombé sur ce warning:
WARNING: out of shared memory
Je sais que souvent ce message est accompagné d'une erreur et d'un "You might need to increase max_locks_per_transaction"
Mais là... non, juste le warning et rien d'autre... Du coup, je ne sais pas à quoi ce message peut bien se rapporter ni même si je dois m'inquiéter (je pense que oui quand même...). J'ai l'impression que j’atteins une limite de ressource mais je ne sais pas sur quoi agir.
Est ce que quelqu'un pourrait éclairer ma lanterne ?
Merci d'avance
Dernière modification par pitpoule (23/02/2021 13:22:47)
Hors ligne
En regardant le code source les seuls endroits où cette erreur peut être générée en dehors des phases de recovery sont liées au parallélisme. De ce que je vois la mémoire nécessaire devrait être allouée, et l'erreur ne devrait donc pas se produire.
Avez-vous la requête ayant généré l'erreur ? Avez-vous activé les paramètres nécessaires pour le parallélisme ? Est-ce que le problème est survenu plusieurs fois ? Avez vous plus de détail sur votre environnement (windows / linux, configuration etc).
Julien.
https://rjuju.github.io/
Hors ligne
En remontant dans les rapports pgbadger, le message apparait depuis des mois. Certains jours, il n'y en a pas et d'autres quelques dizaines (à remettre en visu des 10aines de millions de requêtes/jour)
Le phénomène est global car cela concerne des connexions frontend comme backend. Ça arrive par "salve".
Malheureusement, je n'ai pas les requêtes associées. De ce que je vois aussi, ça arrive à des périodes de grosse activité côté traitements backend (backend applicatif, pas les backend PG).
021-02-23 07:37:00 CET [62784]: [1-1] db=,user=,app= WARNING: out of shared memory
2021-02-23 07:37:00 CET [38903]: [79-1] db=base,user=user1,app=app1 - 127.0.0.1:27930 WARNING: out of shared memory
2021-02-23 07:37:00 CET [12358]: [29-1] db=base,user=user2,app=app2 - 127.0.0.1:52043 WARNING: out of shared memory
2021-02-23 07:37:00 CET [22598]: [1-1] db=,user=,app= WARNING: out of shared memory
2021-02-23 07:37:00 CET [12446]: [57-1] db=base,user=user2,app=app2 - 127.0.0.1:39765 WARNING: out of shared memory
2021-02-23 07:37:00 CET [3804]: [10-1] db=base,user=user2,app=app2 - 127.0.0.1:3883 WARNING: out of shared memory
2021-02-23 07:37:00 CET [62823]: [118-1] db=base,user=user2,app=app2 - 127.0.0.1:27047 WARNING: out of shared memory
2021-02-23 07:37:00 CET [12446]: [58-1] db=base,user=user2,app=app2 - 127.0.0.1:39765 WARNING: out of shared memory
2021-02-23 07:37:00 CET [12358]: [30-1] db=base,user=user2,app=app2 - 127.0.0.1:52043 WARNING: out of shared memory
2021-02-23 07:37:00 CET [22600]: [1-1] db=,user=,app= WARNING: out of shared memory
2021-02-23 07:37:00 CET [22600]: [2-1] db=,user=,app= WARNING: out of shared memory
2021-02-23 07:37:00 CET [22633]: [3-1] db=,user=,app= WARNING: out of shared memory
2021-02-23 07:37:00 CET [12446]: [59-1] db=base,user=user2,app=app2 - 127.0.0.1:39765 WARNING: out of shared memory
Au niveau de la configuration:
PG 9.6.18 / debian 10.4
shared_buffers = 96G
max_worker_processes = 20
max_parallel_workers_per_gather = 6
Dernière modification par pitpoule (23/02/2021 17:04:22)
Hors ligne
Info supplémentaire , les process
2021-02-23 07:37:00 CET [22600]: [1-1] db=,user=,app= WARNING: out of shared memory
ont l'air d'être des auto vacuum, ce qui me conforte dans l'idée que le problème est global
Hors ligne
Avoir ce type message dans des processus autovacuum semble assez bizarre, pareil pour l'absence des requêtes. Avez-vous positionné log_error_verbosity à terse ou est-il à default?
Pourriez-vous essayer de positionner log_error_verbosity à verbose, cela pourrait donner plus de détails.
Avez-vous des extensions externes configurées?
Julien.
https://rjuju.github.io/
Hors ligne
Name | Version | Schema | Description
-----------------+---------+------------+-------------------------------------------------------------------
btree_gist | 1.2 | public | support for indexing common datatypes in GiST
hstore | 1.4 | public | data type for storing sets of (key, value) pairs
ip4r | 2.1 | public |
pageinspect | 1.5 | public | inspect the contents of database pages at a low level
pg_buffercache | 1.2 | public | examine the shared buffer cache
pg_freespacemap | 1.1 | public | examine the free space map (FSM)
pg_repack | 1.4.5 | public | Reorganize tables in PostgreSQL databases with minimal locks
pg_trgm | 1.3 | public | text similarity measurement and index searching based on trigrams
pg_visibility | 1.1 | public | examine the visibility map (VM) and page-level visibility info
pgcrypto | 1.3 | public | cryptographic functions
pglogical | 2.3.1 | pglogical | PostgreSQL Logical Replication
pgstattuple | 1.4 | public | show tuple-level statistics
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
plpython3u | 1.0 | pg_catalog | PL/Python3U untrusted procedural language
plpythonu | 1.0 | pg_catalog | PL/PythonU untrusted procedural language
pltcl | 1.0 | pg_catalog | PL/Tcl procedural language
postgres_fdw | 1.0 | public | foreign-data wrapper for remote PostgreSQL servers
temporal_tables | 1.1.0 | public | temporal tables
tsm_system_rows | 1.0 | public | TABLESAMPLE method which accepts number of rows as a limit
tsm_system_time | 1.0 | public | TABLESAMPLE method which accepts time in milliseconds as a limit
unaccent | 1.1 | public | text search dictionary that removes accents
url_encode | 1.2 | public | url_encode, url_decode functions
Pour la verbosité des logs, je modifierai demain... on génère tellement de logs que j'ai peur que ça coince niveau disque
Hors ligne
Merci ! Pouvez-vous également montrer le contenu de shared_preload_libraries?
Effectivement, verbose va ajouter au moins une ligne supplémentaire pour chaque occurence. Mais le paramètre est pour le moment bien configuré à default?.
Julien.
https://rjuju.github.io/
Hors ligne
bonjour,
un shared_buffers à 96G ? combien de RAM y a t'il sur votre serveur ?
et avez-vous des alertes mémoire au niveau de l'OS ?
Dernière modification par ruizsebastien (23/02/2021 19:18:27)
Cordialement,
Sébastien.
Hors ligne
Je me souviens avoir eu à gérer des warnings de ce style sur une instance 9.6
La raison apparente était la même que les erreurs qui mènent au HINT "You might need to increase max_locks_per_transaction", c'est-à-dire que résoudre l'erreur supprime aussi les warnings
max_locks_per_transaction par défaut (64) est assez faible. Il suffit d'avoir une base avec des hiérarchies profondes avec éventuellement pas mal d'index et des requêtes dont le plan d'exécution va chercher toute la hiérarchie pour dépasser ou flirter avec la limite globale (max_locks_per_transaction * max_connections). Ou beaucoup de "large objects" utilisés dans une même transaction.
@DanielVerite
http://blog-postgresql.verite.pro/
Hors ligne
Je me souviens avoir eu à gérer des warnings de ce style sur une instance 9.6
La raison apparente était la même que les erreurs qui mènent au HINT "You might need to increase max_locks_per_transaction", c'est-à-dire que résoudre l'erreur supprime aussi les warningsmax_locks_per_transaction par défaut (64) est assez faible. Il suffit d'avoir une base avec des hiérarchies profondes avec éventuellement pas mal d'index et des requêtes dont le plan d'exécution va chercher toute la hiérarchie pour dépasser ou flirter avec la limite globale (max_locks_per_transaction * max_connections). Ou beaucoup de "large objects" utilisés dans une même transaction.
Je me suis fait la même réflexion... finalement, est ce qu'on n'est pas juste avant le déclenchement de l'erreur.
Est ce que max_locks_per_transaction peut être augmenté franchement ou bien faut il y aller en douceur ? Par exemple est ce que je peux le passer à 256 voir 512, d'entrée ?
Dernière modification par pitpoule (24/02/2021 09:15:07)
Hors ligne
Merci ! Pouvez-vous également montrer le contenu de shared_preload_libraries?
Effectivement, verbose va ajouter au moins une ligne supplémentaire pour chaque occurence. Mais le paramètre est pour le moment bien configuré à default?.
Oui, il est bien à default.
postgres=# show shared_preload_libraries;
shared_preload_libraries
--------------------------
pglogical
(1 row)
Hors ligne
bonjour,
un shared_buffers à 96G ? combien de RAM y a t'il sur votre serveur ?
et avez-vous des alertes mémoire au niveau de l'OS ?
le serveur possède 256G de RAM
La consommation de RAM est ok à chaque fois que les messages apparaissent
Hors ligne
Est ce que max_locks_per_transaction peut être augmenté franchement ou bien faut il y aller en douceur ? Par exemple est ce que je peux le passer à 256 voir 512, d'entrée ?
Dans la doc pour des versions maintenant obsolètes il y avait des formules de calcul
voir table 17.2 dans https://www.postgresql.org/docs/9.2/ker … urces.html
Notamment celles-là:
Connections (1800 + 270 * max_locks_per_transaction) * max_connections
Autovacuum workers (1800 + 270 * max_locks_per_transaction) * autovacuum_max_workers
Prepared transactions (770 + 270 * max_locks_per_transaction) * max_prepared_transactions
Dans la 9.6 (et en fait dès la 9.3) je ne les vois plus, peut-être à cause des background workers qui font que la conso de la mémoire partagée est devenue trop dynamique.
Mais je pense que les ordres de grandeur sont restés les mêmes, donc à chaque augmentation de max_locks_per_transaction c'est environ 270 octets * max_connections à allouer en plus. Il faut faire attention si max_connections est énorme ou si problème éventuel avec des serveurs secondaires moins puissants (car il faut qu'ils suivent aussi l'augmentation du paramètre).
Il me semble qu'il faut aussi logiquement augmenter max_pred_locks_per_transaction pour être au même niveau en isolation sérialisable.
Si par exemple max_connections est à 200 et max_locks_per_transaction agrandi à 512, l'ordre de grandeur pour les deux tables des locks serait de 2*(270*512*200) soit 53 Mo. Ca ne parait pas déraisonnable pour un serveur qui a 96 Go en shared_buffers.
@DanielVerite
http://blog-postgresql.verite.pro/
Hors ligne
Merci pour le retour
Dans mon cas, on a le max_connections est à 1000 et je partirai sur un max_locks_per_transaction à 256, ce qui amène à 131Mo, je pense que ça reste raisonnable par rapport à la shared_buffers
Hors ligne
on a le max_connections est à 1000
Petit détail en apparté, mais avec la taille de votre shared_buffers et le nombre de connexions, il est assez crucial d'avoir les huge pages activées si vous avez des connexions persistentes et/ou un pooler de connexion, sans quoi vous risquez de gacher une quantité phénoménale de mémoire pour les PTE (page table entry) et d'avoir des problèmes de performances assez importants et aléatoires. Vous pouvez consulter la documentation à https://docs.postgresql.fr/9.6/runtime- … ource.html pour plus de détail.
Julien.
https://rjuju.github.io/
Hors ligne
Petit détail en apparté, mais avec la taille de votre shared_buffers et le nombre de connexions, il est assez crucial d'avoir les huge pages activées si vous avez des connexions persistentes et/ou un pooler de connexion, sans quoi vous risquez de gacher une quantité phénoménale de mémoire pour les PTE (page table entry) et d'avoir des problèmes de performances assez importants et aléatoires. Vous pouvez consulter la documentation à https://docs.postgresql.fr/9.6/runtime- … ource.html pour plus de détail.
Le paramètre vaut "try".
En regardant la doc PG, je vois ces valeurs pour les hugepages
postgres$ grep ^VmPeak /proc/64027/status
VmPeak: 103100328 kB
postgres$ grep ^Hugepagesize /proc/meminfo
Hugepagesize: 2048 kB
postgres$ grep Huge /proc/meminfo
AnonHugePages: 14336 kB
ShmemHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 0 kB
C'est moi qui ne comprend pas bien mais j'ai l'impression qu'elles ne sont pas utilisées... est ce que c'est bien le cas ?
Dernière modification par pitpoule (25/02/2021 09:38:58)
Hors ligne
Apparemment non, les huge pages ne sont pas utilisées. Avez-vous configuré vm.nr_hugepages? Cette documentation vous indique comment calculer la valeur adéquate : https://www.postgresql.org/docs/current … HUGE-PAGES
Vous pouvez utiliser ce script pour calculer la consommation mémoire actuelle pour la PTE de vos processus postgres, en Mo:
for p in $(pgrep postgres); do grep "VmPTE:" /proc/$p/status; done | awk '{pte += $2} END {print pte / 1024}'
Cela pourrait vous indiquer si vous avez un problème latent on non. Attention cependant, même si la valeur actuelle est faible il est possible que cela explose en période de forte activité avec de très mauvaises conséquences.
Julien.
https://rjuju.github.io/
Hors ligne
postgres$ for p in $(pgrep postgres); do grep "VmPTE:" /proc/$p/status; done | awk '{pte += $2} END {print pte / 1024}'
35009.7
35G, je ne saurais dire, si c'est peu ou beaucoup
Hors ligne
J'aurais tendance à dire que c'est catastrophique. Vous pouvez regarder cet article pour plus de détail sur le problème et ses conséquences : https://rjuju.github.io/postgresqlfr/20 … ndues.html
Julien.
https://rjuju.github.io/
Hors ligne
J'aurais tendance à dire que c'est catastrophique. Vous pouvez regarder cet article pour plus de détail sur le problème et ses conséquences : https://rjuju.github.io/postgresqlfr/20 … ndues.html
Ah quand même.... est ce que si vm.nr_hugepages, il faut redémarrer le moteur PG ?
J'avais déjà lu votre article... fort intéressant d'ailleurs
Honnêtement, nous n'avons pas constaté des pertes de performances inexpliquées ou aléatoires... la moyenne des connexions à la base se situe entre 200 et 300, je dirais.
Dernière modification par pitpoule (25/02/2021 11:07:07)
Hors ligne
Merci
Oui il est nécessaire de redémarrer postgres, mais uniquement après s'être assuré que les huge pages sont disponibles. Il est possible que vous ayez besoin de redémarrer votre serveur pour ça. N'oubliez également pas de configurer /etc/sysctl.conf pour que le paramètre soit pris en compte au redémarrage. Tout est documenté https://www.postgresql.org/docs/current … HUGE-PAGES
En fonction de la charge vous n'avez peut être pas de gros problèmes de performances, mais cela représente quand même 35 Go de RAM perdu qui pourraient être mieux utilisés.
Julien.
https://rjuju.github.io/
Hors ligne
Merci pour vos conseils, je vais regarder ça pour une mise en place
Sinon pour mon problème initial, le passage en verbose à rajouter un petit peu d'information...
2021-02-24 16:22:53 CET [61131]: [23-1] db=db1,user=user1,app=app1 - 127.0.0.1:27233 WARNING: 53200: out of shared memory
2021-02-24 16:22:53 CET [61131]: [24-1] db=db1,user=user1,app=app1 - 127.0.0.1:27233 LOCATION: ShmemAlloc, shmem.c:212
Hors ligne
C'est très bizarre, ShmemAlloc n'est normalement utilisé (directement ou indirectement) que durant la phase de démarrage de postgres. La mémoire partagée ne pouvant pas être étendue à chaud, il n'y aurait de toutes façons que peu d'utilité.
Il y a cependant une exception : les 2 tables de hashage contenant les verrous ("Lock Hash" et "PROCLOCK hash") qui ne sont initialisées qu'à la moitié de leur capacité maximale. En fonction du nombre de verrous utilisés de manière concurrente, le système pourra alors allouer un peu plus d'espace après le démarrage. J'imagine que l'origine de ces messages vient de là, et cela expliquerait pourquoi les messages sont plus fréquents en cas de pic d'activité. Et si c'est le as, comme l'allocation échoue, les tables de hashages ne peuvent jamais être agrandies et le système continuera à essayer de les agrandir quand un verrou est demandé et qu'il ne tient pas (alors qu'il devrait du fait de la configuration type max_locks_per_transaction).
Maintenant je ne crois pas qu'il y ait eu un seul bug concernant cette partie du code depuis des années. La seule explication pour ce problème serait l'utilisation d'un module tiers allouant plus de mémoire partagée (ShmemAlloc() ou ShmemAlloc() ou similaire) qu'il n'avait réquisitionné à l'origine (avec RequestAddinShmemSpace()).
Les seules modules qui font ce genre d'opération sont normalement à configurer en shared_preload_libraries, ce qui laisserait donc comme coupable idéal pglogical. J'ai regardé rapidement et je n'ai pas vu de correctif de bug pouvant expliquer ce comportement, ni de problème avec le code actuel, et la partie du code qui fait ces allocations n'a pas changé depuis son implémentation initiale en octobre 2015. S'il y avait un problème pouvant générer ces erreurs j'imagine qu'il aurait été décelé et corrigé il y a bien longtemps. À tout hasard quelle version de pglogical utilisez vous ?
Une autre explication pourrait être une application devant être positionnée en shared_preload_libraries, mais qui ne l'est pas dans votre cas, et qui aurait le problème mentionné avec de sucroit un autre bug, car le code est censé s'assurer qu'il est bien positionné en shared_preload_libraries. Cela parait encore moins probable, mais cela reste possible, surtout que je ne connais pas toutes les extensions que vous utilisez.
Un moyen de supprimer ces messages d'erreurs serait d'augmenter max_locks_per_transaction. Le manque d'espace demandé par du code tiers pouvant alors être compensé par cet espace supplémentaire, du moins si vous n'utilisez pas plus de verrous.
Julien.
https://rjuju.github.io/
Hors ligne
Merci pour le retour détaillé
pglogical est en version 2.3.1 . On doit avoir deux versions de retard sur la version courante, on n'a pas encore effectué la mise à jour car nous ne l'utilisons pas pour le moment.
Nous avons une maintenance de prévue dans quelques jours, nous allons en profiter pour augmenter la valeur du max_locks_per_transaction.
Hors ligne
Petit retour sur le sujet, l'augmentation du paramètre max_locks_per_transaction a fait disparaître l’apparition des messages dans le log.
Merci à tous pour votre aide
Hors ligne