PostgreSQL peut quelque fois dépasser les limites des ressources du système d'exploitation, tout spécialement quand plusieurs copies du serveur s'exécutent sur le même système, ou sur des très grosses installations. Cette section explique les ressources du noyau utilisées par PostgreSQL et les étapes à suivre pour résoudre les problèmes liés à la consommation des ressources du noyau.
PostgreSQL a besoin que le système d'exploitation fournisse des fonctionnalités de communication inter-processus (IPC), en particulier de la mémoire partagée et des sémaphores. Les systèmes dérivés d'Unix fournissent « System V » IPC, « POSIX » IPC ou les deux. Windows qui fournit sa propre implémentation de ces fonctionnalités ne sera pas approfondi ici.
Le manque complet de fonctionnalités est généralement manifesté par une erreur « illegal system call » au lancement du serveur. Dans ce cas, il n'y a rien à faire à part reconfigurer votre noyau. PostgreSQL ne fonctionnera pas sans. Néanmoins, cette situation est rare parmi les systèmes d'exploitation modernes.
Par défaut, PostgreSQL alloue
une très petite quantité de mémoire partagée System V, ainsi
qu'une quantité bien plus importante de mémoire partagée anonyme
mmap
.
Autre possibilité : utiliser un seul gros bloc de mémoire partagée
System V (voir shared_memory_type).
De plus, un nombre important de sémaphores de style System V ou POSIX sont
créés au démarrage du serveur. Actuellement, les sémaphores POSIX sont
utilisés sur les systèmes Linux et FreeBSD, alors que les autres plateformes
utilisent les sémaphores System V.
Avant la version 9.3 de PostgreSQL mémoire partagée System V était utilisée, ce qui fait que la quantité de mémoire partagée System V nécessaire pour démarrer le serveur était bien plus importante. Si vous utilisez une version plus ancienne, référez vous à la documentation de votre version.
Les fonctionnalités System V IPC sont habituellement restreintes par les limites d'allocation au niveau système. Quand PostgreSQL dépasse une des nombreuses limites IPC, le serveur refusera de s'exécuter et lèvera un message d'erreur instructif décrivant le problème rencontré et que faire avec (voir aussi la Section 18.3.1). Les paramètres adéquats du noyau sont nommés de façon cohérente parmi les différents systèmes ; le Tableau 18.1 donne un aperçu. Néanmoins, les méthodes pour les obtenir varient. Les suggestions pour quelques plateformes sont données ci-dessous.
Tableau 18.1. Paramètres System V IPC
Nom | Description | Valeurs nécessaires pour faire fonctionner une instance PostgreSQL |
---|---|---|
SHMMAX | Taille maximum du segment de mémoire partagée (en octets) | au moins 1 ko, mais la valeur par défaut est normalement bien plus grande |
SHMMIN | Taille minimum du segment de mémoire partagée (en octets) | 1 |
SHMALL | Total de la mémoire partagée disponible (en octets ou pages) | si octets, identique à SHMMAX ;
si pages, ceil(SHMMAX/PAGE_SIZE) ,
plus de la marge pour les autres applications |
SHMSEG | Nombre maximum de segments de mémoire partagée par processus | seul un segment est nécessaire, mais la valeur par défaut est bien plus importante |
SHMMNI | Nombre maximum de segments de mémoire partagée pour tout le système | comme SHMSEG plus de la place pour les autres
applications |
SEMMNI | Nombre maximum d'identifiants de sémaphores (c'est-à-dire d'ensembles) | au moins ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16) plus de la marge pour les autres applications |
SEMMNS | nombre maximum de sémaphores répartis dans le système | ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16) * 17 plus la place
pour les autres applications |
SEMMSL | Nombre maximum de sémaphores par ensemble | au moins 17 |
SEMMAP | Nombre d'entrées dans la carte des sémaphores | voir le texte |
SEMVMX | Valeur maximum d'un sémaphore | au moins 1000 (vaut souvent par défaut 32767 ; ne pas changer sauf si vous êtes forcé.) |
PostgreSQL requiert quelques octets de mémoire
partagée System V (typiquement 48 octets sur des plateformes 64 bits) pour
chaque copie du serveur. Sur la plupart des systèmes d'exploitation modernes,
cette quantité est facilement allouable. Néanmoins, si vous exécutez
plusieurs copies du serveur
ou si vous le configurez explicitement pour utiliser de grandes quantités
de mémoire partagée System V (voir shared_memory_type
et dynamic_shared_memory_type),
il pourrait être nécessaire d'augmenter
SHMALL
, correspondant à la quantité
totale de mémoire partagée System V pour tout le système. Notez que
SHMALL
est en nombre de blocs disques, et non pas en
nombre d'octets sur de nombreux systèmes.
La taille minimum des segments de mémoire partagée (SHMMIN
) est
moins sensible aux problèmes. Elle devrait être au plus à environ
32 octets pour PostgreSQL (il est habituellement à 1). Le
nombre maximum de segments au travers du système (SHMMNI
) ou par
processus (SHMSEG
) a peu de chances de causer un problème sauf
s'ils sont configurés à zéro sur votre système.
Lors de l'utilisation de sémaphores System V,
PostgreSQL utilise un sémaphore par connexion
autorisée (max_connections), par processus
autovacuum worker autorisé (autovacuum_max_workers), par processus WAL sender autorisé (max_wal_senders) et par
processus en tâche de fond autorisé réclamant un accès à la mémoire
partagée, le tout par ensemble de 16. Chacun de ces ensembles contiendra
aussi un 17è sémaphore qui contient un « nombre magique » pour
détecter la collision avec des ensembles de sémaphore utilisés par les
autres applications. Le nombre maximum de sémaphores dans le système est
initialisé par SEMMNS
, qui en conséquence doit être au
moins aussi haut que max_connections
plus
autovacuum_max_workers
plus
max_wal_senders
plus
max_worker_processes
,
plus 1 encore pour chacune des 16 connexions autorisées,
plus les workers (voir la formule dans le Tableau 18.1). Le paramètre SEMMNI
détermine la limite du nombre d'ensembles de sémaphores qui peuvent
exister sur le système à un instant précis. Ce paramètre doit donc être
au moins égal à
ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16)
.
Baisser le
nombre de connexions autorisées est un contournement temporaire pour les
échecs qui sont habituellement indiqués par le message « no space
left on device », à partir de la fonction
semget
.
Dans certains cas, il pourrait être nécessaire d'augmenter
SEMMAP
pour être au moins dans l'ordre de
SEMMNS
. Si le système dispose de ce paramètre (ce n'est
pas le cas pour beaucoup d'entre eux), il définit la taille de
la carte de ressources de sémaphores, dans laquelle chaque bloc contigu de
sémaphores disponibles a besoin d'une entrée. Lorsqu'un ensemble de
sémaphores est libéré, soit il est ajouté à une entrée existante,
soit il est enregistré sous une nouvelle entrée dans la carte.
Si la carte est pleine, les sémaphores libérés sont perdus
(jusqu'au redémarrage). La fragmentation de l'espace des sémaphores
peut mener au fil du temps à rendre moins de sémaphores disponibles qu'il
ne devrait y avoir.
D'autres paramètres en relation avec l'« annulation de sémaphores »,
tels que SEMMNU
et SEMUME
, n'affectent pas
PostgreSQL.
Lors de l'utilisation de sémaphores POSIX, le nombre de sémaphores nécessaires est le même que pour System V, c'est-à-dire un sémaphore par connexion autorisée (max_connections), par processus autovacuum worker autorisé (autovacuum_max_workers), par processus WAL sender autorisé (max_wal_senders) et par processus en tâche de fond (max_worker_processes). Sur les plateformes où cette option est préférée, le noyau ne spécifie pas de limite au nombre de sémaphores POSIX.
À partir de la version 5.1, il ne doit plus être nécessaire de faire
une configuration spéciale pour les paramètres tels que
SHMMAX
, car c'est configuré de façon à ce que toute
la mémoire puisse être utilisée en tant que mémoire partagée.
C'est le type de configuration habituellement utilisée pour d'autres
bases de données comme DB/2.
Néanmoins, il pourrait être nécessaire de modifier l'information
globale ulimit
dans
/etc/security/limits
car les limites en dur par
défaut pour les tailles de fichiers (fsize
) et
les nombres de fichiers (nofiles
) pourraient être
trop bas.
Les paramètres IPC par défaut peuvent être modifiés en utilisant la commande
sysctl
ou loader
. Les paramètres
suivants peuvent être configurés en utilisant
sysctl
:
#
sysctl kern.ipc.shmall=32768
#
sysctl kern.ipc.shmmax=134217728
Pour que ces paramètres persistent après les redémarrages, modifiez
/etc/sysctl.conf
.
Les paramètres restant, concernant les sémaphores, sont en lecture seule
en ce qui concerne sysctl
, mais peuvent être
configurés dans /boot/loader.conf
:
kern.ipc.semmni=256 kern.ipc.semmns=512
Après la modification de ce fichier, un redémarrage est nécessaire pour que le nouveau paramétrage prenne effet.
Vous pourriez aussi vouloir configurer votre noyau pour verrouiller la
mémoire partagée System V en RAM et l'empêcher d'être envoyée dans la swap. Ceci
s'accomplit en utilisant le paramètre
kern.ipc.shm_use_phys
de sysctl
.
En cas d'exécution dans une cage FreeBSD en activant
security.jail.sysvipc_allowed
de sysctl,
les postmaster exécutés dans différentes cages
devront être exécutés par différents utilisateurs du système d'exploitation.
Ceci améliore la sécurité car cela empêche les utilisateurs non root
d'interférer avec la mémoire partagée ou les sémaphores d'une cage
différente et cela permet au code de nettoyage des IPC PostgreSQL de
fonctionner correctement (dans FreeBSD 6.0 et ultérieurs, le code de
nettoyage IPC ne détecte pas proprement les processus des autres
cages, empêchant les postmaster en cours d'exécution d'utiliser le
même port dans différentes cages).
Les FreeBSD, avant la 4.0, fonctionnent comme l'ancien OpenBSD (voir ci-dessous).
Avec NetBSD 5.0 et
ultérieur, les paramètres IPC peuvent être ajustés en utilisant
sysctl
. Par exemple :
#
sysctl -w kern.ipc.semmni=100
Pour que ce paramètrage persiste après un redémarrage, modifiez
le fichier /etc/sysctl.conf
.
Habituellement, vous voudrez augmenter kern.ipc.semmni
et kern.ipc.semmns
, car les valeurs par défaut de ces
paramètres pour NetBSD sont trop
basses.
Vous pourriez aussi vouloir configurer votre noyau pour verrouiller
la mémoire partagée System V en RAM et l'empêcher d'être mise dans le swap.
Cela peut se faire en utilisant le paramètre
kern.ipc.shm_use_phys
de sysctl
.
Les versions de NetBSD
antérieures à la 5.0 fonctionnent comme les vieux OpenBSD (voir ci-dessous), sauf que
les paramètres du noyau doivent être configurés avec le mot clé
options
, et non pas option
.
Pour OpenBSD 3.3 et ultérieurs,
les paramètres IPC peuvent être ajustés en utilisant
sysctl
, par exemple :
#
sysctl kern.seminfo.semmni=100
Pour que ce paramétrage persiste lors des redémarrages, il faut modifier
/etc/sysctl.conf
.
Vous voudrez habituellement augmenter
kern.seminfo.semmni
et
kern.seminfo.semmns
, car les valeurs par défaut de ces
paramètres sur OpenBSD sont bien
trop bas.
Dans les anciennes versions
d'OpenBSD, vous devrez construire un noyau
personnalisé pour modifier les paramètres IPC. Assurez-vous que les options
SYSVSHM
et SYSVSEM
sont aussi
activées (elles le sont par défaut). Ce qui suit montre un exemple de la
configuration de différents paramètres dans le fichier de configuration du
noyau :
option SYSVSHM option SHMMAXPGS=4096 option SHMSEG=256 option SYSVSEM option SEMMNI=256 option SEMMNS=512 option SEMMNU=256
Les paramètres par défaut tendent à suffire pour des installations
normales. Sur HP-UX 10, la valeur par défaut de
SEMMNS
est 128, qui pourrait être trop basse pour de gros
sites de bases de données.
Les paramètres IPC peuvent être initialisés dans System Administration Manager (SAM) sous → . Choisissez une fois terminé.
La taille maximale du segment par défaut est de 32 Mo et la taille totale maximale par
défaut est de 2 097 152 pages. Une page équivaut pratiquement toujours
à 4096 octets sauf pour certaines configurations inhabituelles du
noyau comme « huge pages » (utilisez
getconf PAGE_SIZE
pour vérifier).
La configuration de la taille de mémoire partagée peut être modifiée
avec l'interface proposée par la commande sysctl
.
Par exemple, pour permettre l'utilisation de 16 Go :
$
sysctl -w kernel.shmmax=17179869184
$
sysctl -w kernel.shmall=4194304
Ces paramètres peuvent aussi être préservés entre des redémarrages
dans le fichier /etc/sysctl.conf
. Il est
recommandé de le faire.
Les anciennes distributions peuvent ne pas avoir le programme
sysctl
mais des modifications équivalentes peuvent
se faire en manipulant le système de fichiers
/proc
:
$
echo 17179869184 >/proc/sys/kernel/shmmax
$
echo 4194304 >/proc/sys/kernel/shmall
Les autres valeurs par défaut sont taillées de façon assez généreuses pour ne pas nécessiter de modifications.
La méthode recommandée pour configurer la mémoire partagée sous macOS
est de créer un fichier nommé /etc/sysctl.conf
contenant des affectations de variables comme :
kern.sysv.shmmax=4194304 kern.sysv.shmmin=1 kern.sysv.shmmni=32 kern.sysv.shmseg=8 kern.sysv.shmall=1024
Notez que, dans certaines versions de macOS, les
cinq paramètres de mémoire partagée doivent être configurés
dans /etc/sysctl.conf
, sinon les valeurs seront
ignorées.
Attention au fait que les versions récentes de macOS ignorent les tentatives
de configuration de SHMMAX
à une valeur qui n'est pas
un multiple exact de 4096.
SHMALL
est mesuré en page de 4 ko sur cette
plateforme.
Dans les anciennes versions de macOS, vous aurez besoin de redémarrer
pour que les modifications de la mémoire partagée soient prises en
considération. À partir de la version 10.5, il est possible de tous
les modifier en ligne sauf SHMMNI
, grâce à
sysctl. Mais il est toujours préférable de
configurer vos valeurs préférées dans
/etc/sysctl.conf
, pour que les nouvelles valeurs
soient conservées après un redémarrage.
Le fichier /etc/sysctl.conf
est seulement honoré
à partir de la version 1.0.3.9 de macOS. Si vous utilisez une version
antérieure, vous devez modifier le fichier /etc/rc
et changer les valeurs dans les commandes suivantes :
sysctl -w kern.sysv.shmmax sysctl -w kern.sysv.shmmin sysctl -w kern.sysv.shmmni sysctl -w kern.sysv.shmseg sysctl -w kern.sysv.shmall
Notez que /etc/rc
est habituellement écrasé lors
de mises à jour systèmes de macOS, donc vous devez vous attendre à les
modifier manuellement après chaque mise à jour.
En 10.2 et avant cette version, modifiez ces commandes dans le fichier
/System/Library/StartupItems/SystemTuning/SystemTuning
.
La configuration est modifiable dans
/etc/system
, par exemple :
set shmsys:shminfo_shmmax=0x2000000 set shmsys:shminfo_shmmin=1 set shmsys:shminfo_shmmni=256 set shmsys:shminfo_shmseg=256 set semsys:seminfo_semmap=256 set semsys:seminfo_semmni=512 set semsys:seminfo_semmns=512 set semsys:seminfo_semmsl=32
Vous avez besoin de redémarrer pour que les modifications prennent effet. Voir aussi http://sunsite.uakom.sk/sunworldonline/swol-09-1997/swol-09-insidesolaris.html pour des informations sur la configuration de la mémoire partagée sur des versions plus anciennes de Solaris.
Dans Solaris 10 (et les versions ultérieures) et OpenSolaris, la configuration de la mémoire
partagée et des sémaphores par défaut sont suffisamment bonnes
pour la majorité des configurations de
PostgreSQL. La valeur par défaut de
Solaris pour SHMMAX
correspond maintenant à
un quart de la mémoire disponible sur le système. Pour configurer
plus finement ce paramètre, vous devez utiliser une
configuration de projet associé à l'utilisateur
postgres
. Par exemple, exécutez ce qui suit
en tant qu'utilisateur root
:
projadd -c "PostgreSQL DB User" -K "project.max-shm-memory=(privileged,8GB,deny)" -U postgres -G postgres user.postgres
Cette commande ajoute le projet user.postgres
et configure le maximum de mémoire partagée pour l'utilisateur
postgres
à 8 Go. Cela prend effet à chaque
fois que l'utilisateur se connecte et quand vous redémarrez
PostgreSQL. La ligne ci-dessus
suppose que PostgreSQL est exécuté
par l'utilisateur postgres
dans le groupe
postgres
. Aucun redémarrage du serveur n'est
requis.
Sur un serveur de bases de données ayant beaucoup de connexions, les autres modifications recommandés pour le noyau sont :
project.max-shm-ids=(priv,32768,deny) project.max-sem-ids=(priv,4096,deny) project.max-msg-ids=(priv,4096,deny)
De plus, si vous exécutez PostgreSQL
dans une zone, vous pourriez avoir besoin d'augmenter les limites
d'utilisation des ressources pour la zone. Voir
Chapter2: Projects and Tasks dans
System Administrator's Guide
pour plus d'informations sur les projets
et
prctl
.
Si systemd est utilisé, certaines précautions
sont de mise pour que les ressources IPC (incluant la mémoire partagée)
ne soient pas supprimées par le système d'exploitation. Cela est
particulièrement important lors de l'installation de PostgreSQL via les
sources. Les utilisateurs de versions packagées par la distribution ont moins
de chance d'être affectés, l'utilisateur postgres
étant
habituellement créé en tant qu'utilisateur système.
Le paramètre RemoveIPC
dans logind.conf
contrôle si les objets IPC sont supprimés lors de déconnexion
complète d'un utilisateur. Les utilisateurs système sont exclus.
Ce paramètre est par défaut actif sur la version originale de
systemd, mais certaines distributions
positionnent ce paramètre à off.
Quand ce paramètre est à on, un effet typiquement observé est que les objets de mémoire partagée utilisés par un serveur PostgreSQL sont supprimés à des moments paraissant aléatoires, ce qui engendre des erreurs et des avertissements lors que le serveur essaie de les ouvrir et supprimer, par exemple
WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No such file or directory
Différents types d'objets IPC (mémoire partagée et sémaphores, System V et POSIX) sont traités de manière légèrement différente par systemd, et l'on peut observer que certaines ressources IPC ne sont pas supprimées de la même manière que les autres. Il n'est toutefois pas conseillé de compter sur ces subtiles différences.
Une « déconnexion utilisateur » peut survenir lors d'une
opération de maintenance ou manuellement lorsqu'un administrateur se
connecte avec le compte postgres
ou un compte similaire,
ce qui est difficile à éviter en général.
Ce qu'est un « utilisateur système » est déterminé à la
compilation de systemd par le paramètre
SYS_UID_MAX
dans /etc/login.defs
.
Les scripts de packaging et déploiement devront faire attention à créer
l'utilisateur postgres
en tant qu'utilisateur système
avec useradd -r
, adduser --system
,
ou une commande équivalente.
Sinon, si le compte utilisateur a été créé de manière incorrecte ou ne peut être modifié, il est recommandé de configurer
RemoveIPC=no
dans /etc/systemd/logind.conf
ou un autre fichier de
configuration approprié.
Au moins une de ces deux choses doit être garantie, sinon le serveur PostgreSQL ne pourra être considéré comme fiable.
Les systèmes d'exploitation style Unix renforcent différents types de
limites de ressources qui pourraient interférer avec les opérations de votre
serveur PostgreSQL. Les limites sur le nombre de
processus par utilisateur, le nombre de fichiers ouverts par un processus et la
taille mémoire disponible pour chaque processus sont d'une grande
importance. Chacun d'entre elles ont une limite « dure » et une
limite « souple ». La limite souple est réellement ce qui compte
mais cela pourrait être changé par l'utilisateur jusqu'à la limite dure. La
limite dure pourrait seulement être modifiée par l'utilisateur root. L'appel
système setrlimit
est responsable de l'initialisation
de ces paramètres. La commande interne du shell ulimit
(shells Bourne) ou limit
(csh) est
utilisé pour contrôler les limites de ressource à partir de la ligne de
commande. Sur les systèmes dérivés BSD, le fichier
/etc/login.conf
contrôle les différentes limites de
ressource initialisées à la connexion. Voir la documentation du système
d'exploitation pour les détails. Les paramètres en question sont
maxproc
, openfiles
et
datasize
. par exemple :
default:\ ... :datasize-cur=256M:\ :maxproc-cur=256:\ :openfiles-cur=256:\ ...
(-cur
est la limite douce. Ajoutez
-max
pour configurer la limite dure.)
Les noyaux peuvent aussi avoir des limites sur le système complet pour certaines ressources.
Sur linux, le paramètre système
fs.file-max
détermine le nombre maximum de fichiers
ouverts que le noyau supportera. Ce nombre est modifiable avec
sysctl -w fs.file-max=
.
Pour rendre la configuration persistante entre les redémarrages, ajoutez
l'affectation dans N
/etc/sysctl.conf
. La limite des
fichiers par processus est fixée lors de la compilation du noyau ;
voir /usr/src/linux/documentation/proc.txt
pour plus
d'informations.
Le serveur PostgreSQL utilise un processus par connexion de façon à ce que vous puissiez fournir au moins autant de processus que de connexions autorisées, en plus de ce dont vous avez besoin pour le reste de votre système. Ceci n'est habituellement pas un problème mais si vous exécutez plusieurs serveurs sur une seule machine, cela pourrait devenir étroit.
La limite par défaut des fichiers ouverts est souvent initialisée pour être « amicalement sociale », pour permettre à de nombreux utilisateurs de coexister sur une machine sans utiliser une fraction inappropriée des ressources du système. Si vous lancez un grand nombre de serveurs sur une machine, cela pourrait être quelque chose que vous souhaitez mais sur les serveurs dédiés, vous pourriez vouloir augmenter cette limite.
D'un autre côté, certains systèmes autorisent l'ouverture d'un grand nombre de fichiers à des processus individuels ; si un plus grand nombre le font, alors les limites du système peuvent facilement être dépassées. Si vous rencontrez ce cas et que vous ne voulez pas modifier la limite du système, vous pouvez initialiser le paramètre de configuration max_files_per_process de PostgreSQL pour limiter la consommation de fichiers ouverts.
Une autre limite du noyau, intéressante quand le serveur doit supporter de
nombreuses connexions de clients, est la longueur maximale de la queue de
connexions sur la socket. Si un plus grand nombre de requêtes de connexions
arrivent dans une très courte période de temps, certaines pourraient être
rejetées avant que le processus postmaster ne puisse les traiter. Les
clients reçoivent alors des messages d'erreur peu utiles, comme
« Resource temporarily unavailable » ou « Connection
refused ». La longueur par défaut de la queue est de 128 pour
plusieurs plateformes. Pour l'augmenter, ajustez le paramètre approprié du
noyau via sysctl, puis redémarrez le service
PostgreSQL. Le paramètre est souvent nommé
net.core.somaxconn
sous Linux,
kern.ipc.soacceptqueue
sous les FreeBSD les plus récents,
et kern.ipc.somaxconn
sur macOS et les autres variants
BSD.
Dans Linux 2.4 et suivants, le comportement par défaut de la mémoire virtuelle n'est pas optimal pour PostgreSQL. Du fait de l'implémentation du « memory overcommit » par le noyau, celui-ci peut arrêter le serveur PostgreSQL (le processus serveur maître, « postmaster ») si les demandes de mémoire de PostgreSQL ou d'un autre processus provoque un manque de mémoire virtuelle au niveau du système.
Si cela se produit, un message du noyau qui ressemble à ceci (consulter la documentation et la configuration du système pour savoir où chercher un tel message) :
Out of Memory: Killed process 12345 (postgres)
peut survenir.
Ceci indique que le processus postgres
a été terminé
à cause d'un problème de mémoire. Bien que les connexions en cours
continuent de fonctionner normalement, aucune nouvelle
connexion n'est acceptée. Pour revenir à un état normal,
PostgreSQL doit être relancé.
Une façon d'éviter ce problème revient à lancer PostgreSQL sur une machine où vous pouvez vous assurer que les autres processus ne mettront pas la machine en manque de mémoire. S'il y a peu de mémoire, augmenter la swap peut aider à éviter le problème car un système peut tuer des processus lorsque la mémoire physique et la mémoire swap sont utilisées entièrement.
Si PostgreSQL lui-même est la cause d'un manque
de mémoire du système, vous pouvez éviter le problème en modifiant votre
configuration. Dans certains cas, baisser les paramètres de configuration
de la mémoire peut aider, tout particulièrement
shared_buffers
et work_mem
. Dans
d'autres cas, le problème peut être causé par l'autorisation d'un trop grand
nombre de connexions au serveur de bases de données. Dans beaucoup de cas,
il est préférable de réduire max_connections
et
d'utiliser à la place un logiciel de multiplexage de connexions
(connection pooling).
Sur Linux 2.6 et ultérieur, il est possible de modifier
le comportement du noyau avec le « overcommit memory ».
Bien que ce paramétrage n'empêchera pas ce comportement, il réduira sa
fréquence de façon significative et contribuera du coup à un système
plus robuste. Ceci se fait en sélectionnant le mode strict de
l'overcommit via sysctl
:
sysctl -w vm.overcommit_memory=2
ou en plaçant une entrée équivalente dans /etc/sysctl.conf
.
Vous pourriez souhaiter modifier le paramétrage relatif
vm.overcommit_ratio
. Pour les détails, voir la documentation du
noyau (https://www.kernel.org/doc/Documentation/vm/overcommit-accounting).
Une autre approche, qui peut aussi utiliser la modification de
vm.overcommit_memory
, est de configurer la valeur de la
variable d'ajustement du score OOM, valeur par processus, pour le
processus postmaster à -1000
, garantissant ainsi qu'il ne
sera pas la cible de OOM. La façon la plus simple de le faire est
d'exécuter
echo -1000 > /proc/self/oom_score_adj
dans le script de démarrage de postmaster juste avant d'appeler postmaster. Notez que cette action doit être faite en tant qu'utilisateur root. Dans le cas contraire, elle n'aura aucun effet. Du coup, un script de démarrage, exécuté par root, est le meilleur endroit où placer ce code. Si vous le faites, vous devriez aussi configurer ces variables d'environnement dans le script de démarrage avant d'invoquer le processus postmaster :
export PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj export PG_OOM_ADJUST_VALUE=0
Ces paramètres vont faire en sorte que les processus fils du postmaster
s'exécuteront avec l'ajustement de score OOm normal (0), pour que l'OOM
puisse encore les cibler si cela s'avère nécessaire. Vous pouvez utiliser
d'autres valeurs pour PG_OOM_ADJUST_VALUE
si vous voulez
que les processus fils s'exécutent avec un autre ajustement de score.
(PG_OOM_ADJUST_VALUE
peut aussi être omis, auquel cas sa
valeur par défaut est zéro.) Si vous ne voulez pas configurer
PG_OOM_ADJUST_FILE
, les processus fils s'exécuteront avec
le même ajustement de score OOM que le processus père postmaster, ce qui
n'est pas conseillé car le but est de s'assurer que le processus
postmaster soit protégé par la configuration.
Les anciens noyaux Linux ne proposent pas /proc/self/oom_score_adj
,
mais peuvent avoir une ancienne version de la même fonctionnalité, nommé
/proc/self/oom_adj
. Cela fonctionne de façon identique
sauf que la valeur de désactivation est -17
, et non pas
-1000
.
Quelques noyaux 2.4 de vendeurs ont des pré-versions de l'overcommit du
2.6. Néanmoins, configurer vm.overcommit_memory
à 2 sur un noyau
2.4 qui n'a pas le code correspondant rendra les choses pires qu'elles
n'étaient. Il est recommandé d'inspecter le code source du noyau (voir la
fonction vm_enough_memory
dans le fichier
mm/mmap.c
) pour vérifier ce qui est supporté dans votre noyau
avant d'essayer ceci avec une installation 2.4. La présence du fichier de
documentation overcommit-accounting
ne devrait pas
être pris comme une preuve de la présence de cette fonctionnalité. En cas de
doute, consultez un expert du noyau ou le vendeur de votre noyau.
L'utilisation des huge pages réduit la
surcharge lors de l'utilisation de gros morceaux contigus de mémoire,
ce que fait
PostgreSQL, tout particulièrement lors de
l'utilisation de grosses valeurs pour shared_buffers.
Pour activer cette fonctionnalité avec
PostgreSQL, vous avez besoin d'un noyau compilé
avec CONFIG_HUGETLBFS=y
et
CONFIG_HUGETLB_PAGE=y
. Vous devez aussi configurer le
paramètre noyau vm.nr_hugepages
. Pour estimer le nombre
nécessaire de huge pages,
lancer PostgreSQL
sans activer les huge pages
et vérifiez la taille du segment de mémoire
partagée anonyme pour le processus postmaster, ainsi que la taille
des huge pages pour le système en utilisant
le système de fichiers
/proc
. Cela pourrait ressembler à ceci :
$head -1 $PGDATA/postmaster.pid
4170 $pmap 4170 | awk '/rw-s/ && /zero/ {print $2}'
6490428K $grep ^Hugepagesize /proc/meminfo
Hugepagesize: 2048 kB
6490428
/ 2048
donne approximativement
3169.154
. Donc, dans cet exemple, nous avons besoin d'au
moins 3170
huge pages,
ce que nous pouvons configurer avec :
$ sysctl -w vm.nr_hugepages=3170
Une configuration plus importante serait appropriée si les autres
programmes du serveur avaient aussi besoin de
huge pages. N'oubliez pas
d'ajouter cette configuration à /etc/sysctl.conf
pour
qu'elle soit appliquée à chaque redémarrage.
Parfois, le noyau n'est pas capable d'allouer immédiatement le nombre souhaité de huge pages, donc il peut être nécessaire de répéter cette commande ou de redémarrer. (Tout de suite après un redémarrage, la plupart de la mémoire de la machine doit être disponible à une conversion en huge pages.) Pour vérifier la situation au niveau de l'allocation des huge pages, utilisez :
$ grep Huge /proc/meminfo
Il pourrait être nécessaire de donner le droit à l'utilisateur du système
d'exploitation du serveur de bases de données en configurant
vm.hugetlb_shm_group
via
sysctl, et/ou en donnant le droit de
verrouiller la mémoire avec ulimit -l
.
Il est aussi nécessaire de donner le droit d'utiliser les
huge pages à
l'utilisateur système qui exécute PostgreSQL. Cela se fait en configurant
vm.hugetlb_shm_group
via
sysctl, et le droit de verrouiller la mémoire
avec ulimit -l
.
Le comportement par défaut pour les
huge pages dans
PostgreSQL est de les utiliser quand cela est
possible et de revenir aux pages normales dans le cas contraire. Pour
forcer l'utilisation des huge pages,
vous pouvez configurer huge_pages à on
dans le fichier
postgresql.conf
. Notez que, avec ce paramètre
configuré ainsi, PostgreSQL refusera de démarrer
s'il ne peut pas récupérer suffisamment de
huge pages.
Pour une description détaillée des huge pages sous Linux, lisez https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt.