Les performances optimales de PostgreSQL dépendent des paramètres du système d'exploitation correctement définis. Des paramètres du noyau OS mal configurés peuvent entraîner une baisse des performances du serveur de base de données. Il est donc impératif que ces paramètres soient ajustés en fonction du serveur de base de données et de sa charge de travail. Dans cet article, nous allons discuter de certains paramètres importants du noyau Linux qui peuvent affecter les performances du serveur de base de données et de la manière de les configurer.
SHMMAX / SHMALL
SHMMAX est un paramètre du noyau utilisé pour définir la taille maximale d'un segment de mémoire partagée (shared memory) qu'un processus Linux peut allouer. Avant la version 9.2, PostgreSQL utilisait System V (SysV), pour lequel une configuration de SHMMAX est requise. Après 9.2, PostgreSQL a basculé vers la mémoire partagée POSIX. Il nécessite donc désormais moins d'octets de mémoire partagée System V.
Avant la version 9.3, SHMMAX était le paramètre du noyau le plus important. La valeur de SHMMAX est définie en octets.
De même, SHMALL est un autre paramètre du noyau utilisé pour définir
le volume total de pages de mémoire partagée (shared memory). Pour consulter les valeurs actuelles de SHMMAX, SHMALL ou SHMMIN, utilisez la commande ipcs.
Détails SHM* — Linux
$ ipcs -lm
------ Limites de mémoire partagée --------
Nombre max de segments = 4096
Taille max de seg (ko) = 1073741824
Mémoire partagée totale max (ko) = 17179869184
Taille min de seg (octets) = 1Détails SHM* — MacOS X
$ ipcs -M
Statut IPC à partir de au jeu. 16 août 22:20:35 PKT 2018
shminfo:
shmmax: 16777216 (taille max de segment de mémoire partagée)
shmmin: 1 (taille min de segment de mémoire partagée)
shmmni: 32 (nombre max d'identifiants de mémoire partagée)
shmseg: 8 (nombre max de segments de mémoire partagée par processus)
shmall: 1024 (montant max de mémoire partagée en pages)
PostgreSQL utilise System V IPC pour allouer de la mémoire partagée. Ce paramètre est l'un des plus importants du noyau. Chaque fois que vous recevez les messages d'erreur suivants, cela signifie que vous avez une version antérieure de PostgreSQL et que vous avez une valeur SHMMAX très basse. Les utilisateurs sont censés ajuster et augmenter la valeur en fonction de la mémoire partagée qu'ils prévoient d'utiliser.
Erreurs possibles de configuration incorrecte
Si SHMMAX est mal configuré, vous pouvez obtenir une erreur lors de l'initialisation du cluster PostgreSQL avec la commande initdb.
Échec d'initdb
DÉTAILS : L'appel système échoué était shmget(key=1, size=2072576, 03600).
ASTUCE : Cette erreur signifie généralement que la demande de PostgreSQL pour un segment de mémoire partagée a dépassé le paramètre SHMMAX de votre noyau.
Vous pouvez soit réduire la taille de la demande, soit reconfigurer le noyau avec un SHMMAX plus grand. Pour réduire la taille de la demande (actuellement 2072576 octets),
réduisez l'utilisation de la mémoire partagée de PostgreSQL, peut-être en diminuant shared_buffers ou max_connections.
Si la taille de la demande est déjà petite, il est possible qu'elle soit inférieure au paramètre SHMMIN de votre noyau,
dans ce cas, il est nécessaire d'augmenter la taille de la demande ou de reconfigurer SHMMIN.
La documentation de PostgreSQL contient plus d'informations sur la configuration de la mémoire partagée. le processus enfant s'est terminé avec le code de sortie 1
De même, vous pouvez rencontrer une erreur lors du démarrage du serveur PostgreSQL en utilisant la commande pg_ctl.
Échec de pg_ctl
DÉTAIL : L'appel système échoué était shmget(clé=5432001, taille=14385152, 03600).
ASTUCE : Cette erreur signifie généralement que la demande de PostgreSQL pour un segment de mémoire partagée a dépassé le paramètre SHMMAX de votre noyau.
Vous pouvez soit réduire la taille de la demande, soit reconfigurer le noyau avec un SHMMAX plus grand. Pour réduire la taille de la demande (actuellement 14385152 octets), réduisez l'utilisation de la mémoire partagée de PostgreSQL, peut-être en diminuant shared_buffers ou max_connections.
Si la taille de la demande est déjà petite, il est possible qu'elle soit inférieure au paramètre SHMMIN de votre noyau,
dans ce cas, il est nécessaire d'augmenter la taille de la demande ou de reconfigurer SHMMIN.
La documentation de PostgreSQL contient plus d'informations sur la configuration de la mémoire partagée.
Comprendre les différences dans les définitions
La définition des paramètres SHMMAX/SHMALL diffère légèrement entre Linux et MacOS X :
- Linux : kernel.shmmax, kernel.shmall
- MacOS X : kern.sysv.shmmax, kern.sysv.shmall
Commande sysctl peut être utilisé pour modifier temporairement la valeur. Pour définir des valeurs permanentes, ajoutez une entrée dans /etc/sysctl.conf. Les détails sont fournis ci-dessous.
Modification des paramètres du noyau sous MacOS X
# Get the value of SHMMAX
sudo sysctl kern.sysv.shmmax
kern.sysv.shmmax: 4096
# Get the value of SHMALL
sudo sysctl kern.sysv.shmall
kern.sysv.shmall: 4096
# Set the value of SHMMAX
sudo sysctl -w kern.sysv.shmmax=16777216
kern.sysv.shmmax: 4096 -> 16777216
# Set the value of SHMALL
sudo sysctl -w kern.sysv.shmall=16777216
kern.sysv.shmall: 4096 -> 16777216Modification des paramètres du noyau sous Linux
# Get the value of SHMMAX
sudo sysctl kernel.shmmax
kernel.shmmax: 4096
# Get the value of SHMALL
sudo sysctl kernel.shmall
kernel.shmall: 4096
# Set the value of SHMMAX
sudo sysctl -w kernel.shmmax=16777216
kernel.shmmax: 4096 -> 16777216
# Set the value of SHMALL
sudo sysctl -w kernel.shmall=16777216
kernel.shmall: 4096 -> 16777216N'oubliez pas: pour rendre les changements permanents, ajoutez ces valeurs dans /etc/sysctl.conf
Grandes pages (Huge Pages)
Sous Linux, les pages mémoire par défaut sont de 4 Ko, sous BSD — Super Pages, et sous Windows — Large Pages. Une page est une partie de la mémoire vive allouée à un processus. Un processus peut avoir plusieurs pages selon ses besoins en mémoire. Plus un processus nécessite de mémoire, plus il lui est alloué de pages. Le système d'exploitation maintient une table d'allocation de pages pour les processus. Plus la taille de la page est petite, plus la table est grande, plus il faut de temps pour rechercher une page dans cette table de pages. Ainsi, les grandes pages permettent d'utiliser une grande quantité de mémoire avec des frais généraux réduits ; moins de recherches de pages, moins d'erreurs de pages, des opérations de lecture/écriture plus rapides grâce à de grands tampons. En conséquence, cela améliore les performances.
PostgreSQL prend en charge les grandes pages uniquement sous Linux. Par défaut, Linux utilise des pages mémoire de 4 Ko, donc dans les cas où il y a trop d'opérations sur la mémoire, il est nécessaire de définir des pages de taille plus grande. Un gain de performance est observé lors de l'utilisation de grandes pages de 2 Mo à 1 Go. La taille des grandes pages peut être définie au démarrage. Vous pouvez facilement vérifier les paramètres des grandes pages et leur utilisation sur votre ordinateur Linux en utilisant la commande cat /proc/meminfo | grep -i huge.
Obtenir des informations sur les grandes pages (uniquement sur Linux)
Note : Ceci est uniquement pour Linux, pour les autres systèmes d'exploitation, cette opération est ignorée
$ cat /proc/meminfo | grep -i huge
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kBDans cet exemple, bien que la taille de la grande page soit définie à 2048 (2 Mo), le nombre total de grandes pages est de 0. Cela signifie que les grandes pages sont désactivées.
Script pour déterminer le nombre de grandes pages
C'est un script simple qui renvoie le nombre requis de grandes pages. Exécutez le script sur votre serveur Linux pendant que PostgreSQL fonctionne. Assurez-vous que la variable d'environnement $PGDATA est définie sur le répertoire des données de PostgreSQL.
Obtenir le nombre requis de grandes pages
#!/bin/bash
pid=`head -1 $PGDATA/postmaster.pid`
echo "Pid: $pid"
peak=`grep ^VmPeak /proc/$pid/status | awk '{ print $2 }'`
echo "VmPeak: $peak kB"
hps=`grep ^Hugepagesize /proc/meminfo | awk '{ print $2 }'`
echo "Hugepagesize: $hps kB"
hp=$((peak/hps))
echo Set Huge Pages: $hpLa sortie du script se présente comme suit :
Sortie du script
Pid: 12737
VmPeak: 180932 kB
Hugepagesize: 2048 kB
Set Huge Pages: 88La valeur recommandée pour les grandes pages est 88, donc vous devez régler la valeur à 88.
Configurer les grandes pages
sysctl -w vm.nr_hugepages=88Vérifiez les grandes pages maintenant, vous verrez que les grandes pages ne sont pas utilisées (HugePages_Free = HugePages_Total).
À nouveau des informations sur les grandes pages (uniquement sur Linux)
$ cat /proc/meminfo | grep -i huge
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
HugePages_Total: 88
HugePages_Free: 88
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kBMaintenant, définissez le paramètre huge_pages «on» dans $PGDATA/postgresql.conf et redémarrez le serveur.
Et à nouveau des informations sur les grandes pages (uniquement sur Linux)
$ cat /proc/meminfo | grep -i huge
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
HugePages_Total: 88
HugePages_Free: 81
HugePages_Rsvd: 64
HugePages_Surp: 0
Hugepagesize: 2048 kBVous pouvez maintenant voir qu'il y a très peu de grandes pages utilisées. Essayons maintenant d'ajouter des données à la base de données.
Certain operations with the database for managing large pages
postgres=# CREATE TABLE foo(a INTEGER);
CREATE TABLE
postgres=# INSERT INTO foo VALUES(generate_Series(1,10000000));
INSERT 0 10000000Let's see if we are currently using more large pages than before.
Again, information about large pages (only on Linux)
$ cat /proc/meminfo | grep -i huge
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
HugePages_Total: 88
HugePages_Free: 18
HugePages_Rsvd: 1
HugePages_Surp: 0
Hugepagesize: 2048 kBYou can now see that most of the large pages are in use.
Note: the approximate value for HugePages used here is very low, which is not a normal value for a production machine. Please assess the required number of pages for your system and set them accordingly based on load and resources.
vm.swappiness
vm.swappiness is another kernel parameter that can affect database performance. This parameter is used to manage the swapping behavior (swappiness) (swapping pages in and out of memory) in Linux. The value ranges from 0 to 100. It determines how much memory will be swapped out or freed. Zero means disabling swapping, while 100 means aggressive swapping.
You can achieve good performance by setting lower values.
Setting the value to 0 in newer kernels may cause the OOM Killer (Linux memory cleanup process) to terminate the process. Thus, setting the value to 1 is safe if you want to minimize swapping. The default value in Linux is 60. A higher value causes the MMU (Memory Management Unit) to use more swap space than RAM, while a lower value keeps more data/code in memory.
A lower value is a good bet for improving performance in PostgreSQL.
vm.overcommit_memory / vm.overcommit_ratio
Applications request memory and release it when it's no longer needed. But in some cases, an application might request too much memory and not release it. This can trigger the OOM killer. Here are possible values for the parameter vm.overcommit_memory with a description for each:
- Heuristic overcommit (default); kernel-based heuristic
- Allow overcommit in all cases
- Do not overcommit, do not exceed the overcommit ratio.
Link:
vm.overcommit_ratio — pourcentage de la mémoire vive disponible pour un sur-commutement. Une valeur de 50 % dans un système avec 2 Go de RAM peut allouer jusqu'à 3 Go de RAM.
Une valeur de 2 pour vm.overcommit_memory offre de meilleures performances pour PostgreSQL. Cette valeur maximise l'utilisation de la mémoire vive par le processus serveur sans risque significatif d'être tué par le processus OOM killer. L'application pourra redémarrer, mais seulement dans les limites du sur-commutement, ce qui réduit le risque que le OOM killer tue le processus. Par conséquent, une valeur de 2 offre de meilleures performances que la valeur par défaut de 0. Cependant, la fiabilité peut être améliorée en ne surchargant pas la mémoire au-delà de la limite autorisée. Cela exclut le risque que le processus soit tué par le OOM killer.
Dans les systèmes sans swap, un problème avec vm.overcommit_memory égal à 2 peut survenir.
vm.dirty_background_ratio / vm.dirty_background_bytes
vm.dirty_background_ratio — c'est le pourcentage de mémoire occupée par des pages sales qui doivent être écrites sur le disque. Le vidage sur disque se fait en arrière-plan. La valeur de ce paramètre varie de 0 à 100 ; cependant, une valeur inférieure à 5 peut être inefficace, et certains noyaux ne la prennent pas en charge. 10 est la valeur par défaut dans la plupart des systèmes Linux. Vous pouvez améliorer les performances pour les opérations à forte écriture avec un coefficient plus bas, ce qui signifie que Linux flush les pages sales en arrière-plan.
Vous devez définir la valeur vm.dirty_background_bytes en fonction de la vitesse de votre disque.
Il n'existe pas de « bonnes » valeurs pour ces deux paramètres, car les deux dépendent du matériel. Cependant, régler vm.dirty_background_ratio à 5 et vm.dirty_background_bytes à 25 % de la vitesse du disque, améliore les performances jusqu'à ~ 25 % dans la plupart des cas.
vm.dirty_ratio / dirty_bytes
C'est la même chose que vm.dirty_background_ratio / dirty_background_bytes, sauf que le vidage se fait dans une session de travail, bloquant ainsi l'application. Par conséquent, vm.dirty_ratio doit être supérieur à vm.dirty_background_ratio. Cela garantit que les processus de fond seront déclenchés plus tôt pour éviter le blocage maximal de l'application. Vous pouvez ajuster la différence entre ces deux ratios en fonction de la charge d'entrée/sortie disque.
Conclusion
Vous pouvez configurer d'autres paramètres pour améliorer les performances, mais les gains seront minimes et vous n'en tirerez pas de bénéfice significatif. Il faut se rappeler que tous les paramètres ne s'appliquent pas à tous les types d'applications. Certaines applications fonctionnent mieux avec certains paramètres optimisés, tandis que d'autres ne le nécessitent pas. Vous devez trouver le bon équilibre entre les configurations de ces paramètres en fonction de la charge de travail prévue et du type d'application, tout en tenant compte du comportement du système d'exploitation. Configurer les paramètres du noyau n'est pas aussi simple que de configurer ceux de la base de données : il est plus difficile de donner des recommandations à ce sujet.
Source : habr.com
