27.3. Configuration de WAL
Il y a plusieurs paramètres de configuration associés à
WAL qui affectent les performances
de la base de de données. Cette section explique leur utilisation.
Consultez le Chapitre 17,
Configuration du serveur pour des détails sur la mise en place de
ces paramètres de configuration.
Dans la séquence des transactions, les points
de contrôles (checkpoints) sont des points qui garantissent que
les fichiers de données ont été mis à jour avec toutes les
informations enregistrées dans le journal avant le point de contrôle.
Au moment du point de contrôle, toutes les pages de données non
propres sont écrites sur le disque et une entrée spéciale, pour le
point de contrôle, est écrite dans le journal. En cas de défaillance,
la procédure de récupération recherche le dernier enregistrement d'un
point de vérification dans les traces (connu comme le
« redo log ») à partir duquel il
devra lancer l'opération REDO. Toute modification effectuée sur les
fichiers de données avant ce point est sûre d'avoir été enregistrée
sur disque. Du coup, après qu'un point de vérification soit effectué,
tous les segments de trace précédant celui contenant le
« redo record » ne sont plus
nécessaires et peuvent être soit recyclés soit supprimés (quand
l'archivage des WAL se fait, les
segments de traces doivent être archivés avant d'être recyclés ou
supprimés).
Le processus d'écriture en tâche de fond lancera automatiquement un
point de contrôle de temps en temps. Un point de contrôle est créé
tous les checkpoint_segments
segments de journaux ou dès que checkpoint_timeout
secondes se sont écoulées. Les paramètres par défaut sont
respectivement 3 segments et 300 secondes. Il est également possible
de forcer la création d'un point de contrôle en utilisant la commande
SQL
CHECKPOINT
.
La réduction de checkpoint_segments et/ou
checkpoint_timeout implique des points de
contrôle plus fréquents. Cela permet une récupération plus rapide
après défaillance (puisqu'il y a moins de travail à récupérer).
Cependant, il faut équilibrer cela avec l'augmentation du coût
d'écriture des pages de données non propres. Si full_page_writes
est configuré (comme la valeur par défaut), il reste un autre facteur
à considérer. Pour s'assurer de la cohérence des pages de données, la
première modification d'une page de données après chaque point de
vérification résulte dans le traçage du contenu entier de la page.
Dans ce cas, un intervalle de points de vérification plus petit
augmentera le volume en sortie des traces WAL, dégradant
partiellement le but d'utiliser un intervalle plus petit et
impliquant de toute façon plus d'entrées/sorties au niveau disque.
Les points de contrôle sont assez coûteux, tout d'abord parce qu'ils
écrivent tous les tampons utilisés, et ensuite parce que cela suscite
un trafic WAL supplémentaire comme indiqué ci-dessus. Du coup, il est
conseillé de configurer les paramètres en relation assez haut pour
que ces points de contrôle ne surviennent pas trop fréquemment. En
tant que simple vérification de santé de vos paramètres, vous pouvez
configurer le paramètre checkpoint_warning.
Si les points de contrôle arrivent plus rapidement que checkpoint_warning secondes, un message sera affiché
dans les journaux du serveur recommandant d'accroître checkpoint_segments. Une apparition occasionnelle d'un
message ne doit pas vous alarmer mais, s'il apparaît souvent, alors
les paramètres de contrôle devraient être augmentés. Les opérations
en masse, comme les gros transferts via
COPY
, pourraient être la cause de
l'apparition d'un tel nombre de messages d'avertissements si vous
n'avez pas configuré checkpoint_segments
avec une valeur suffisamment haute.
Il y aura au moins un fichier segment WAL et normalement pas plus de
2 * checkpoint_segments + 1 fichiers. Chaque
fichier de segment fait normalement 16 Mo (bien que cette taille
puisse être modifiée lors de la compilation du serveur). Vous pouvez
utiliser cela pour estimer l'espace disque nécessaire pour
WAL. D'habitude, quand les vieux
fichiers segment de journaux ne sont plus nécessaires, ils sont
recyclés (renommés pour devenir les prochains segments dans une
séquence numérotée). S'il y a plus de 2 * checkpoint_segments + 1 fichiers segments à cause d'un
pic temporaire du taux d'écriture des journaux, ceux inutilisés
seront effacés au lieu d'être recyclés jusqu'à ce que le système soit
en-dessous de cette limite.
Il y a deux fonctions WAL internes
couramment utilisées : LogInsert et
LogFlush. LogInsert est utilisée pour placer une nouvelle
entrée à l'intérieur des tampons WAL en mémoire partagée. S'il n'y a plus d'espace
pour une nouvelle entrée, LogInsert devra
écrire (bouger dans le cache du noyau) quelques tampons
WAL remplis. Ceci n'est pas
désirable parce que LogInsert est utilisée
lors de chaque modification bas niveau de la base (par exemple,
insertion d'une ligne) quand un verrou exclusif est posé sur des
pages de données affectées, donc l'opération nécessite d'être aussi
rapide que possible. Pire encore, écrire des tampons WAL peut aussi forcer la création d'un nouveau
segment de journal ce qui peut prendre beaucoup plus de temps.
Normalement, les tampons WAL
devraient être écrits et vidés par une requête de LogFlush qui est faite, la plupart du temps, au
moment de la validation d'une transaction pour assurer que les
entrées de la transaction sont écrites vers un stockage permanent.
Sur les systèmes avec une importante écriture de journaux, les
requêtes de LogFlush peuvent ne pas arriver
assez souvent pour empêcher LogInsert
d'avoir à écrire. Sur de tels systèmes, on devrait augmenter le
nombre de tampons WAL en modifiant
le paramètre de configuration wal_buffers. Par
défaut, le nombre de tampons est de 8. Augmenter cette valeur
augmentera considérablement l'utilisation de la mémoire partagée.
Quand full_page_writes
est configuré et que le système est très occupé, configurer cette
variable avec une valeur plus importante aidera à avoir des temps de
réponse plus réguliers lors de la période suivant chaque point de
vérification.
Le paramètre commit_delay définit
combien de micro-secondes le processus serveur dormira après
l'écriture d'une entrée de validation dans le journal avec LogInsert avant d'exécuter un LogFlush. Ce délai permet aux autres processus du
serveur d'ajouter leurs entrées de validation dans le fichier de
journal afin de tout écrire vers le disque avec une seule
synchronisation du journal. Aucune mise en sommeil n'aura lieu si
fsync
n'est pas disponible ou si moins de commit_siblings
autres sessions sont, à ce moment, dans des transactions actives ;
cela évite de dormir quand il est improbable qu'une autre session
fasse bientôt une validation. Notez que dans la plupart des
plate-formes, la résolution d'une requête de sommeil est de 10
millisecondes, donc un commit_delay
différent de zéro et configuré entre 1 et 10000 micro-secondes aura
le même effet. Les bonnes valeurs pour ce paramètre ne sont pas
encore claires ; les essais sont encouragés.
Le paramètre wal_sync_method
détermine comment PostgreSQL™
demandera au noyau de forcer les mises à jour WAL sur le disque. Toutes les options devraient
être les mêmes dans la mesure où la fiabilité ne disparaît pas, mais
c'est avec des options spécifiques à la plate-forme que ça sera le
plus rapide. Notez que ce paramètre est ignoré si fsync a été désactivé.
Configurer le paramètre wal_debug avec une
valeur différente de zéro aura pour résultat d'enregistrer dans les
journaux du serveur l'appel WAL à chaque LogInsert et LogFlush. En
ce moment, il n'est fait aucune différence entre les valeurs
supérieures à zéro. Cette option pourra être remplacée par un
mécanisme plus général dans le futur.
Activer le paramètre de configuration wal_debug (à
supposer que PostgreSQL™ ait
été compilé avec le support de ce paramètre) résultera dans
l'enregistrement de chaque appel WAL à LogInsert et
LogFlush dans les journaux du serveur.
Cette option pourrait être remplacée par un mécanisme plus général
dans le futur.