Configuration des options du noyau Linux pour optimiser PostgreSQL

Configuration des options du noyau Linux pour optimiser PostgreSQL Les performances optimales de PostgreSQL dépendent de paramètres du système d'exploitation correctement définis. Des paramètres du noyau du système d'exploitation mal configurés peuvent entraîner de mauvaises performances du serveur de base de données. Il est donc impératif que ces paramètres soient configurés en fonction du serveur de base de données et de sa charge de travail. Dans cet article, nous aborderons certains paramètres importants du noyau Linux qui peuvent affecter les performances du serveur de base de données et comment les configurer.

SHMMAX / SHMALL

SHMMAX est un paramètre du noyau utilisé pour déterminer la taille maximale d'un seul segment de mémoire partagée qu'un processus Linux peut allouer. Avant la version 9.2, PostgreSQL utilisait System V (SysV), qui nécessite le paramètre SHMMAX. Après la version 9.2, PostgreSQL est passé à la mémoire partagée POSIX. Ainsi, moins d’octets de mémoire partagée System V sont désormais requis.

Avant la version 9.3, SHMMAX était le paramètre le plus important du noyau. La valeur SHMMAX est spécifiée en octets.

De même, SHMALL est un autre paramètre du noyau utilisé pour déterminer
volume de pages de mémoire partagée à l'échelle du système. Pour afficher les valeurs SHMMAX, SHMALL ou SHMMIN actuelles, utilisez la commande IPC.

Détails SHM* - Linux

$ ipcs -lm

------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 1073741824
max total shared memory (kbytes) = 17179869184
min seg size (bytes) = 1

Détails SHM* - MacOS X

$ ipcs -M
IPC status from  as of Thu Aug 16 22:20:35 PKT 2018
shminfo:
	shmmax: 16777216	(max shared memory segment size)
	shmmin:       1	(min shared memory segment size)
	shmmni:      32	(max number of shared memory identifiers)
	shmseg:       8	(max shared memory segments per process)
	shmall:    1024	(max amount of shared memory in pages)

Utilisations de PostgreSQL Système V IPC pour allouer de la mémoire partagée. Ce paramètre est l'un des paramètres les plus importants du noyau. Chaque fois que vous recevez les messages d'erreur suivants, cela signifie que vous disposez d'une ancienne version de PostgreSQL et que votre valeur SHMMAX est très faible. Les utilisateurs doivent ajuster et augmenter la valeur en fonction de la mémoire partagée qu'ils ont l'intention d'utiliser.

Erreurs de configuration possibles

Si SHMMAX n'est pas configuré correctement, vous pouvez recevoir une erreur lorsque vous essayez d'initialiser un cluster PostgreSQL à l'aide de la commande base de données d'initialisation.

Échec d'initialisation de la base de données
DETAIL: Failed system call was shmget(key=1, size=2072576, 03600).

HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter. 
You can either reduce the request size or reconfigure the kernel with larger SHMMAX. To reduce the request size (currently 2072576 bytes),
reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.

If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter,
in which case raising the request size or reconfiguring SHMMIN is called for.

The PostgreSQL documentation contains more information about shared memory configuration. child process exited with exit code 1

De même, vous pouvez recevoir une erreur lors du démarrage du serveur PostgreSQL à l'aide de la commande pg_ctl.

Échec de pg_ctl
DETAIL: Failed system call was shmget(key=5432001, size=14385152, 03600).

HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter.

You can either reduce the request size or reconfigure the kernel with larger SHMMAX.; To reduce the request size (currently 14385152 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.

If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter,
in which case raising the request size or reconfiguring SHMMIN is called for.

The PostgreSQL documentation contains more information about shared memory configuration.

Comprendre les différences dans les définitions

La définition des paramètres SHMMAX/SHMALL est légèrement différente sous Linux et MacOS X :

  • Linux : noyau.shmmax, noyau.shmall
  • MacOS X : kern.sysv.shmmax, kern.sysv.shmall

Équipe système peut être utilisé pour modifier temporairement la valeur. Pour définir des valeurs constantes, ajoutez une entrée à /etc/sysctl.conf. Les détails sont ci-dessous.

Modification des paramètres du noyau sur 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 -> 16777216

Modification 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 -> 16777216

Ne pas oublier: Pour rendre les modifications permanentes, ajoutez ces valeurs à /etc/sysctl.conf

Pages énormes

Linux utilise par défaut des pages mémoire de 4 Ko, BSD utilise des pages mémoire de XNUMX Ko. Super Pages, et sous Windows - Grandes pages. Une page est un morceau de RAM alloué à un processus. Un processus peut avoir plusieurs pages en fonction des besoins en mémoire. Plus un processus nécessite de mémoire, plus de pages lui sont allouées. Le système d'exploitation gère une table d'allocation de pages pour les processus. Plus la taille de la page est petite, plus le tableau est grand, plus il faut de temps pour trouver une page dans ce tableau de pages. Les grandes pages permettent donc d'utiliser de grandes quantités de mémoire avec une surcharge réduite ; moins de pages vues, moins de défauts de page, des opérations de lecture/écriture plus rapides sur des tampons plus grands. Le résultat est une performance améliorée.

PostgreSQL ne prend en charge que les grandes pages 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 mémoire, il est nécessaire de définir des pages plus grandes. Des gains de performances sont observés lors de l'utilisation de grandes pages de 2 Mo et jusqu'à 1 Go. La grande taille de page peut être définie au moment du démarrage. Vous pouvez facilement vérifier les paramètres des grandes pages et leur utilisation sur votre machine Linux à l'aide de la commande chat /proc/meminfo | grep -i énorme.

Obtenir des informations sur les grandes pages (Linux uniquement)

Note: This is only for Linux, for other OS this operation is ignored$ 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 kB

Dans cet exemple, bien que la taille des grandes pages soit définie sur 2048 2 (0 Mo), le nombre total de grandes pages est défini sur XNUMX. Cela signifie que les grandes pages sont désactivées.

Script pour déterminer le nombre de grandes pages

Ce script simple renvoie le nombre requis de grandes pages. Exécutez le script sur votre serveur Linux pendant que PostgreSQL est en cours d'exécution. Assurez-vous que pour la variable d'environnement $PGDONNEES Le répertoire de données PostgreSQL est spécifié.

Obtenir le nombre de grandes pages requises

#!/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:     $hp

Le résultat du script ressemble à ceci :

Sortie du script

Pid:            12737
VmPeak:         180932 kB
Hugepagesize:   2048 kB
Set Huge Pages: 88

La valeur recommandée pour les grandes pages est de 88, vous devez donc la définir sur 88.

Installation de grandes pages

sysctl -w vm.nr_hugepages=88

Vérifiez maintenant les grandes pages, vous verrez que les grandes pages ne sont pas utilisées (HugePages_Free = HugePages_Total).

Grandes pages revisitées (Linux uniquement)

$ 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 kB

Définissez maintenant le paramètre huge_pages sur "on" dans $PGDATA/postgresql.conf et redémarrez le serveur.

Encore une fois, des informations sur les grandes pages (Linux uniquement)

$ 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 kB

Vous pouvez désormais constater que très peu de grandes pages sont utilisées. Essayons maintenant d'ajouter quelques données à la base de données.

Quelques opérations de base de données pour recycler des pages volumineuses

postgres=# CREATE TABLE foo(a INTEGER);
CREATE TABLE
postgres=# INSERT INTO foo VALUES(generate_Series(1,10000000));
INSERT 0 10000000

Voyons si nous utilisons des pages plus volumineuses maintenant qu'auparavant.

Plus d'informations sur les grandes pages (Linux uniquement)

$ 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 kB

Vous pouvez maintenant voir que la plupart des grandes pages sont utilisées.

Remarque : La valeur estimée pour HugePages utilisée ici est très faible, ce qui n'est pas une valeur normale pour une machine exécutant un environnement de produit. Veuillez estimer le nombre de pages requis pour votre système et les définir en conséquence en fonction de la charge et des ressources.

vm.swappiness

vm.swappiness est un autre paramètre du noyau qui peut affecter les performances de la base de données. Cette option est utilisée pour contrôler le comportement du swappiness (échange de pages dans et hors de la mémoire) sous Linux. La valeur est comprise entre 0 et 100. Elle détermine la quantité de mémoire qui sera paginée ou paginée. Zéro signifie aucun échange et 100 signifie un échange agressif.

Vous pouvez obtenir de bonnes performances en définissant des valeurs plus faibles.

Définir cette valeur sur 0 sur les noyaux les plus récents peut entraîner l'arrêt du processus par OOM Killer (le processus de nettoyage de la mémoire de Linux). Il est donc prudent de le définir sur 1 si vous souhaitez minimiser les échanges. La valeur par défaut sous Linux est 60. Une valeur plus élevée amène la MMU (unité de gestion de la mémoire) à utiliser plus d'espace de swap que la RAM, tandis qu'une valeur inférieure conserve plus de données/codes en mémoire.

Une valeur inférieure est un bon pari pour améliorer les performances dans PostgreSQL.

vm.overcommit_memory / vm.overcommit_ratio

Les applications acquièrent de la mémoire et la libèrent lorsqu'elles ne sont plus nécessaires. Mais dans certains cas, l'application obtient trop de mémoire et ne la libère pas. Cela peut provoquer un tueur de MOO. Voici les valeurs possibles des paramètres vm.overcommit_memory avec une description pour chacun :

  1. Surengagement heuristique (par défaut) ; heuristique basée sur le noyau
  2. Autoriser le surengagement quand même
  3. N'en faites pas trop, ne dépassez pas le ratio de surengagement.

Link: https://www.kernel.org/doc/Documentation/vm/overcommit-accounting

vm.overcommit_ratio — pourcentage de RAM disponible pour la surcharge. Une valeur de 50 % sur un système doté de 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 RAM du processus serveur sans risque significatif d'être tué par le processus tueur de MOO. L'application pourra se recharger, mais uniquement dans les limites du dépassement, ce qui réduit le risque qu'un tueur de MOO interrompe le processus. Par conséquent, une valeur de 2 donne de meilleures performances que la valeur par défaut de 0. Cependant, la fiabilité peut être améliorée en garantissant que la mémoire hors plage n'est pas surchargée. Cela élimine le risque que le processus soit interrompu par un tueur de MOO.

Sur les systèmes sans échange, un problème avec vm.overcommit_memory égal à 2 peut survenir.

https://www.postgresql.org/docs/current/static/kernel-resources.html#LINUX-MEMORY-OVERCOMMIT

vm.dirty_background_ratio / vm.dirty_background_bytes

vm.dirty_background_ratio est le pourcentage de mémoire remplie de pages sales qui doivent être écrites sur le disque. Le vidage sur le disque s'effectue en arrière-plan. La valeur de ce paramètre est comprise entre 0 et 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 sur la plupart des systèmes Linux. Vous pouvez améliorer les performances des opérations gourmandes en écriture d'un facteur plus petit, ce qui signifie que Linux videra les pages sales en arrière-plan.

Vous devez définir la valeur vm.dirty_background_bytes en fonction de la vitesse de votre trajet.

Il n'y a pas de « bonnes » valeurs pour ces deux paramètres car tous deux dépendent du matériel. Cependant, définir vm.dirty_background_ratio sur 5 et vm.dirty_background_bytes sur 25 % de la vitesse du disque améliore les performances jusqu'à environ 25 % dans la plupart des cas.

vm.dirty_ratio/dirty_bytes

C'est le même que vm.dirty_background_ratio/dirty_background_bytes, sauf que la réinitialisation est effectuée dans une session de travail, bloquant l'application. Par conséquent, vm.dirty_ratio devrait être supérieur à vm.dirty_background_ratio. Cela garantit que les processus en arrière-plan démarrent plus tôt pour éviter autant que possible de bloquer l'application. Vous pouvez ajuster la différence entre ces deux ratios en fonction de la charge d'E/S du disque.

Total

Vous pouvez modifier d'autres paramètres pour améliorer les performances, mais les améliorations seront minimes et vous n'en verrez pas beaucoup d'avantages. Il ne faut pas oublier que toutes les options ne s’appliquent pas à tous les types d’applications. Certaines applications fonctionnent mieux lorsque nous ajustons certains paramètres, et d'autres non. Vous devez trouver le bon équilibre entre la configuration de ces paramètres en fonction de votre charge de travail attendue et du type d'application, et vous devez également prendre en compte le comportement du système d'exploitation lors du réglage. La configuration des paramètres du noyau n'est pas aussi simple que la configuration des paramètres de la base de données ; il est plus difficile de faire des recommandations.

Source: habr.com

Ajouter un commentaire