Vous n'êtes pas identifié(e).
Pages : 1
Bonjour,
J'utilise Postgres 8.4.4 sur un serveur en production (Debian Lenny avec 4Go de RAM) sur lequel j'ai environ 300 connexions simultanées et sur lequel j'ai activé l'archive mode (warm standby sur un autre serveur).
Je n'avais pas de soucis jusqu'à présent mais depuis peu mon serveur s'est mis à utiliser la swap sans pour autant utiliser la RAM à fond.
Voici les paramètres de mon poste:
Coté sysctl:
swappiness est à 60.
kernel.shmmax=3758096384
kernel.shmall=3758096384
vm.overcommit_memory=2
Coté postgresql.conf
shared_buffers = 2560MB
work_mem = 10MB
maintenance_work_mem = 256MB
checkpoint_segments = 20
effective_cache_size = 4GB
Dans un premier temps j'ai basculé comme ceci:
Coté sysctl:
swappiness est à 80.
Les problèmes ont continués, j'ai donc fait ceci:
Coté postgresql.conf
shared_buffers = 1560MB
work_mem = 5MB
maintenance_work_mem = 128MB
checkpoint_segments = 10
Je n'ai alors plus eu de probleme de swap...
Du coups j'ai rebasculé ainsi:
Coté sysctl:
swappiness est à 60.
Coté postgresql.conf
[color=blue]shared_buffers = 1560MB
work_mem = 20MB (jai eu pas mal de fichiers tmp de créés quand j'étais à 5MB)
maintenance_work_mem = 256MB
checkpoint_segments = 10
Et la swap ne m'embête plus.
Je devrais être content sauf que je ne comprends pas bien ce qui a pu se passer.
Je pense que je ne maitrise pas la gestion de la mémoire sous postgres: J'ai 4Go de RAM, je ne veux pas swapper: mes valeurs semblent elles correctes?Je sais que trop mettre de shared_buffer peut finir par être néfaste.
Mais finalement mes question sont
1) shared_buffer définie-t-il le max de mémoire que peut prendre postgres dans sa globalité (work_mem + maintenance_mem + cœur de postgres + ...)?
2) Dans ma tete, en ce moment, je pense ainsi: postgres utilise:
shared_buffer + work_mem * (nombre d'opérations de tri,... à l'instant t) + (maintenance_worker qui tournent à l'instant t) * maintenance_work_mem
Suis-je à peu prés juste?
3) checkpoint_segment peut-il jouer sur l'utilisation de la ram? est-ce que postgres alloue cela dans le shared_mem ou bien est-ce en plus du shared_mem?
4) En gros, le shared mem est il seulement de la mémoire vive, et que comprend-il?
Je me suis pas mal documenté mais j'avoue ne pas vraiment bien faire le lien entre tous ces points... désolé si je suis un peu confus.
Merci pour votre lecture de ce post.
Olivier B.
Hors ligne
Bonjour,
1) shared_buffers ne définie le max de mémoire globale alloué par PostgreSQL, mais la taille d'un espace mémoire partagé entre le postmaster (processus maître de Postgres) et les différents processus serveurs.
2) en gros, oui.
3) checkpoint_segments ne joue pas sur l'utilisation de la RAM mais va influer sur le nombre de WAL en ligne et par conséquent sur vos performances en écritures (en gros, plus il y en a, mieux c'est...). En revanche, un tampon est alloué, or espace shared_buffers, de la taille de wal_buffers et qui a une influence sur les perfs en écriture (par défaut, sa valeur est de 64 ou 128Ko, j'ai l'habitude de le passer à 1Mo, voire au-delà si le besoin s'en fait sentir).
4) depuis la 8.2 et sur un serveur dédié, on a tendance à utiliser 1/4 de la RAM. Dans votre cas 1Go. On peut aller au-delà évidemment.
Pour moi, le gros point noir dans votre conf est de passer work_mem à 20 Mo. Vous avez bien compris l'impact que cela a sur la consommation mémoire, cf question 2. Avez-vous réellement besoin d'allouer autant de mémoire pour les tris ? Par ailleurs, je conseille souvent aux développeurs de laisser work_mem à 1MB et de l'augmenter dynamiquement (ALTER SESSION SET work_mem = xxMB je crois) au besoin.
Si vous avez de réels problèmes de performance avec work_mem à 5MB, voyez en abaissant shared_buffers à 1Go, ou en augmentant la quantité de RAM physique du serveur.
En dehors de cela, votre configuration me semble bien faite.
Thomas Reiss
Hors ligne
Merci pour votre réponse.
J'ai testé un work_mem à 5MB dans l'un de mes tests mais j'avais une forte utilisation des fichiers de pgsql_tmp donc j'ai pensé augmenter cette valeur.
L'analyse des logs donne à la même seconde, pour le meme utilisateur, une vingtaine de lignes comme celle-ci:
2010-09-29 12:08:21 CEST -- toto : LOG: fichier temporaire : chemin « base/pgsql_tmp/pgsql_tmp5405.350 », taille 1910352
J'ai fais en gros les calculs ainsi: 1,9MB*20=38MB, ça me semblait beaucoup (300 clients, on a vite fais d'avoir pas mal de requetes simultanées), j'ai donc mis 20 pour limiter le nombre d'ecritures dans ce repertoire psql_tmp
Là ca tourne pas mal donc tant mieux, maintenant si vous pensez que c'est une erreur, je le baisserai.
Depuis que j'ai diminué mon shared_mem de 2500 à 1500 les choses vont déjà mieux. Il y a un fort interet à utiliser plus de 1GB pour la shared_mem? Parce que finalement, je me dis que si cette valeur ne concerne pas les clients, je peux la baisser comme vous dites pour attribuer d'avantage de mémoire aux autres opérations.
Pour le point 3) , augmenter la taille de mes wal_buffer à 1Mo aura comme conséquences que mon serveur en warm standby recevra les wal moins souvent mais de plus grande taille non?
De plus, si je comprend, c'est mon shared_buffer qui donne l'espace pour mes wal.
Cependant, si checkpoint_segment est à 10, c'est donc que je vais ecrire mes wal sur le disque tous les 16Mo*10=160Mo de wal non (si on oublie la contrainte de timeout)?
Finalement, quel est l'interet (si vous le suggerez c'est qu'il y en a un j'imagine) d'avoir des 160 wals de 1Mo plutot que 8 fois plus de wal de 256ko?
Olivier B
Hors ligne
La valeur de shared_buffers concerne les clients aussi, même si c'est un espace mémoire alloué par le postmaster. PostgreSQL s'en sert pour rendre accessible les blocs de données aux processus fils, modifier les lignes, etc.
Le mieux est probablement que je cite la documentation:
Si vous disposez d'un serveur dédié à la base de données, avec 1 Go de mémoire ou plus, une valeur de départ raisonnable pour ce paramètre est de 25% la mémoire de votre système. Certains cas peuvent nécessiter une valeur encore plus importante pour le shared_buffers mais comme PostgreSQL™ profite aussi du cache du système d'exploitation, il est peu probable qu'une allocation de plus de 40% de la mémoire fonctionnera mieux qu'une valeur plus restreinte.
Sans dire que c'est une erreur de positionner work_mem à 20Mo, je pense que c'est une valeur beaucoup trop haute pour une utilisation courante, surtout si le serveur se met à swapper. Avez-vous ce comportement pour toutes les sessions utilisateurs ? Ou est-ce que cela apparaît de manière ponctuelle ?
Pour revenir au point 3, attention, il n'y a pas de lien entre la taille d'un fichier WAL et de l'espace mémoire wal_buffers. Un fichier WAL fait nécessairement 16Mo. Pour schématiser, l'espace mémoire wal_buffers est plutôt un espace qui sert à PostgreSQL à stocker les données à inscrire dans les fichiers WAL ; plus cet espace est grand, plus PostgreSQL pourra écrire de données simultanément dans les WAL et vos performances en écriture n'en seront que meilleures.
Il n'y a donc aucune conséquence pour votre serveur en warm-standby.
Thomas Reiss
Hors ligne
En tout cas, ce qui est sûr, c'est que vous avez modifié swapiness dans le mauvais sens si vous voulez limiter l'activité de swap: plus swapiness est grand, plus la machine a tendance à swapper.
Ensuite : shared_buffers ne doit pas dépasser le quart de votre mémoire totale, en première approximation. C'est ce qui ressort de tous les tests d'optimisations faits ces dernières années. Donc redescendez vos shared_buffers à 1Go. PostgreSQL utilise le cache du système d'exploitation comme cache secondaire.
Un shared_buffers de 2,5 Go est beaucoup trop grand par rapport à la mémoire que vous avez disponible. C'est ce qui fait que votre machine swap.
Dernière modification par Marc Cousin (29/09/2010 17:01:52)
Marc.
Hors ligne
Merci pour vos explications.
Les choses s'éclaircissent un peu plus dans ma tête.
Savez-vous, pour terminer, si un schéma expliquant le fonctionnement détaillé l'utilisation mémoire a déjà été fait ?
Cordialement,
Olivier B.
Hors ligne
Je ne crois pas en avoir déjà rencontré.
Marc.
Hors ligne
J'ai pas mal cherché et je n'ai pas vraiment trouvé mon bonheur, effectivement.
Il y a bien un article ici mais le schéma final est sommaire (bien que l'article soit trés instructif).
Concernant la swappiness dont nous parlions au début, ne serait-il pas judicieux de ne pas la laisser à 60 sur un serveur dédié à postgres, de manière à mettre le maximum en mémoire vive?
Est-ce une pratique que vous encouragez? J'ai vu que pour un systeme Linux il y a plusieurs écoles à ce sujet mais pour un serveur dédié postgres, la réponse est peut etre plus tranchée..
Cordialement,
Olivier B.
Hors ligne
le swapiness ne modifiera pas ça.
Le swapiness modifie le choix que postgresql devra effectuer quand il sera à court de ram : préférer récupérer du cache pour en refaire de la mémoire libre, ou pousser de la mémoire dans le swap. Plus il sera proche de 0, plus il privilégiera la récupération de cache, plus il sera proche de 100, plus il privilégiera l'écriture dans le swap.
Marc.
Hors ligne
Etant donné qu'on fait ce qu'on peut pour éviter d'etre à cours de RAM en optimisant nos parametres postgresql.conf, le swappiness est donc une chose qui ne sera probablement pas utilisée alors.
Merci en tout cas pour vos réponses!
Hors ligne
Exactement. En tout cas, un peu de swap rempli, ce n'est pas un problème en soit. Ce qui est gênant, c'est si le système swap continuellement, pas s'il a swappé. Ca se surveille par les colonnes si et so de vmstat.
On peut très bien (je l'ai déjà vu) avoir un système avec 4Go de RAM, 2 ou 3 Go de swap utilisé, et qui fonctionne très bien, simplement parce qu'il fait tourner quelques applications très mal écrites qui utilisent ponctuellement beaucoup de mémoire et ne la libèrent jamais, ou des programmes très lourds, mais utilisés une seule fois par jour (voire par semaine), et qui vivent dans le swap le reste du temps.
Marc.
Hors ligne
Pages : 1