PostgreSQLLa base de données la plus sophistiquée au monde.
Documentation PostgreSQL 10.23 » Administration du serveur » Configuration du serveur » Write Ahead Log

19.5. Write Ahead Log

Voir aussi la Section 30.4 pour plus d'informations sur la configuration de ces paramètres.

19.5.1. Paramètres

wal_level (enum)

wal_level détermine la quantité d'informations écrite dans les journaux de transactions. wal_level détermine la quantité d'information qui sera écrite dans les WAL. La valeur par défaut est replica, qui écrit suffisamment de données pour pouvoir utiliser l'archivage des WAL ainsi que la réplication, y compris exécuter des requêtes en lecture seule sur un serveur secondaire. minimal supprime toute la journalisation à l'exception des informations nécessaire pour pouvoir effectuer une récupération suite à un arrêt brutal ou un arrêt immédiat. Enfin, logical ajoute les informations nécessaires au support du décodage logique. Chaque niveau inclut les informations tracées dans les niveaux inférieurs. Ce paramètre peut seulement être configuré au lancement du serveur.

Au niveau minimal, certains enregistrements dans les journaux de transactions peuvent être évités, ce qui peut rendre ces opérations plus rapides (voir Section 14.4.7). Les opérations concernées par cette optimisation incluent :

CREATE TABLE AS
CREATE INDEX
CLUSTER
COPY dans des tables qui ont été créées ou tronquées dans la même transaction

Mais, du coup, les journaux au niveau minimal ne contiennent pas suffisamment d'informations pour reconstruire les données à partir d'une sauvegarde de base et des journaux de transactions. Donc, les niveaux replica ou supérieurs doivent être utilisés pour activer l'archivage des journaux de transactions (archive_mode) et la réplication en flux.

Dans le niveau logical, les mêmes informations sont enregistrées que pour le mode replica. Des informations supplémentaires sont ajoutées pour permettre d'extraire les modifications logiques depuis les journaux de transactions. En utilisant le niveau logical, le volume des journaux de transactions va augmenter, tout particulièrement si plusieurs tables sont configurées pour REPLICA IDENTITY FULL et que de nombreux UPDATE et DELETE sont exécutés.

Dans les versions antérieures à la 9.6, ce paramètre autorise aussi les valeurs archive et hot_standby. Elles sont toujours acceptées mais sont converties silencieusement en replica.

fsync (boolean)

Si ce paramètre est activé, le serveur PostgreSQL tente de s'assurer que les mises à jour sont écrites physiquement sur le disque à l'aide d'appels système fsync() ou de méthodes équivalentes (voir wal_sync_method). Cela permet de s'assurer que le cluster de bases de données peut revenir à un état cohérent après une panne matérielle ou du système d'exploitation.

Bien que désactiver fsync améliore fréquemment les performances, cela peut avoir pour conséquence une corruption des données non récupérables dans le cas d'une perte de courant ou d'un crash du système. Donc, il est seulement conseillé de désactiver fsync si vous pouvez facilement recréer la base de données complète à partir de données externes.

Quelques exemples de circonstances permettant de désactiver fsync : le chargement initial d'une nouvelle instance à partir d'une sauvegarde, l'utilisation de l'instance pour traiter un flot de données après quoi la base sera supprimée puis recréée, la création d'un clone d'une base en lecture seule, clone qui serait recréé fréquemment et n'est pas utilisé pour du failover. La haute qualité du matériel n'est pas une justification suffisante pour désactiver fsync.

Pour une restauration fiable lors de la modification de fsync de off à on, il est nécessaire de forcer tous les tampons modifiés disponibles dans le cache du noyau à être écrits sur un stockage durable. Ceci peut se faire alors que l'instance est arrêtée ou lorsque fsync est activé en exécutant initdb --sync-only, en exécutant sync, en démontant le système de fichiers ou en redémarrant le serveur.

Dans de nombreuses situations, désactiver synchronous_commit pour les transactions non critiques peut fournir une grande partie des performances de la désactivation de fsync, sans les risques associés de corruption de données.

fsync ne peut être configuré que dans le fichier postgresql.conf ou indiqué sur la ligne de commande. Si ce paramètre est désactivé (off), il est intéressant de désactiver aussi full_page_writes.

synchronous_commit (enum)

Indique quel traitement des WAL doit se faire avant que le serveur de bases de données ne renvoie une indication de « succès » au client. Les valeurs valides sont remote_apply, on (par défaut), remote_write, local et off.

Si synchronous_standby_names est vide, les seules valeurs sensées sont on et off ; remote_apply, remote_write et local fournissent toutes le même niveau de synchronisation locale que on. Le comportement local de tous les modes différents de off est d'attendre le vidage local sur disque des WAL. Dans le mode off, il n'y a pas d'attente, donc il peut y avoir un délai entre le retour du succès au client et le fait que la transaction est garantie d'être sécurisée contre un crash du serveur. (Le délai maximum est de trois fois wal_writer_delay.) Contrairement à fsync, la configuration de ce paramètre à off n'implique aucun risque d'incohérence dans la base de données : un arrêt brutal du système d'exploitation ou d'une base de données peut résulter en quelques transactions récentes prétendument validées perdues malgré tout. Cependant, l'état de la base de données est identique à celui obtenu si les transactions avaient été correctement annulées. C'est pourquoi la désactivation de synchronous_commit est une alternative utile quand la performance est plus importante que la sûreté de la transaction. Pour plus de discussion, voir Section 30.3.

Si synchronous_standby_names n'est pas vide, synchronous_commit contrôle aussi si les validations de transactions attendront que leurs enregistrements WAL soient traités sur le serveur secondaire.

Quand il est configuré à remote_apply, les validations attendront la réponse des serveurs secondaires synchrones indiquant qu'ils ont bien reçu l'enregistrement de validation de la transaction et qu'ils l'ont bien appliqués, pour qu'elle devienne visible aux requêtes sur les serveurs secondaires, et aussi écrites sur un stockage durable. Ceci causera les plus gros délais de validation par rapport aux configurations précédentes car il faut attendre le rejeu des WAL. Quand il est configuré à on, les validations attendent que les réponses des serveurs secondaires synchrones indiquent qu'ils ont reçu l'enregistrement de validation de la transaction et qu'ils l'ont écrit sur un stockage durable. Ceci assure que la transaction ne sera pas perdu sauf si le primaire et les secondaires synchrones souffrent de corruption au niveau disque. Quand il est configuré à remote_write, les validations attendront que les réponses des serveurs secondaires synchrones indiquent avoir reçu l'enregistrement de validation de la transaction et l'avoir écrit sur disque. Ce paramétrage assure de la préservation des données si une instance secondaire de PostgreSQL s'arrête brutalement, mais pas si le serveur secondaire souffre d'un crash au niveau du système d'exploitation parce que les données n'ont pas nécessairement atteint un stockage durable sur le secondaire. Le paramétrage local fait que les validations attendent uniquement le vidage local sur disque, mais n'attendent pas le retour des serveurs secondaires synchrones. Ceci n'est généralement pas souhaité quand la réplication synchrone est utilisée mais est fourni pour être complet.

Ce paramètre peut être changé à tout moment ; le comportement pour toute transaction est déterminé par la configuration en cours lors de la validation. Il est donc possible et utile d'avoir certaines validations validées en synchrone et d'autres en asynchrone. Par exemple, pour réaliser une validation asynchrone de transaction à plusieurs instructions avec une valeur par défaut inverse, on exécute l'instruction SET LOCAL synchronous_commit TO OFF dans la transaction.

Tableau 19.1 résume les possibilités de configuration de synchronous_commit.

Tableau 19.1. Modes pour synchronous_commit

synchronous_commitvalidation locale durablevalide durable du standby après un crash de PGvalide durable du standby après un crash de l'OScohérence des requêtes sur le standby
remote_apply
on 
remote_write  
local   
off    

wal_sync_method (enum)

Méthode utilisée pour forcer les mises à jour des WAL sur le disque. Si fsync est désactivé, alors ce paramètre est inapplicable, car les mises à jour des journaux de transactions ne sont pas du tout forcées. Les valeurs possibles sont :

  • open_datasync (écrit les fichiers WAL avec l'option O_DSYNC de open())

  • fdatasync (appelle fdatasync() à chaque validation)

  • fsync_writethrough (appelle fsync() à chaque validation, forçant le mode write-through de tous les caches disque en écriture)

  • fsync (appelle fsync() à chaque validation)

  • open_sync (écrit les fichiers WAL avec l'option O_SYNC de open())

Ces options ne sont pas toutes disponibles sur toutes les plateformes. La valeur par défaut est la première méthode de la liste ci-dessus supportée par la plateforme, sauf que fdatasync est la valeur par défaut sur Linux et FreeBSD. Les options open_* utilisent aussi O_DIRECT s'il est disponible. L'outil src/tools/fsync disponible dans le code source de PostgreSQL permet de tester les performances des différentes méthodes de synchronisation. Ce paramètre ne peut être configuré que dans le fichier postgresql.conf ou indiqué sur la ligne de commande.

full_page_writes (boolean)

Quand ce paramètre est activé, le serveur écrit l'intégralité du contenu de chaque page disque dans les WAL lors de la première modification de cette page qui intervient après un point de vérification. C'est nécessaire car l'écriture d'une page lors d'un plantage du système d'exploitation peut n'être que partielle, ce qui conduit à une page sur disque qui contient un mélange d'anciennes et de nouvelles données. Les données de modification de niveau ligne stockées habituellement dans les WAL ne sont pas suffisantes pour restaurer complètement une telle page lors de la récupération qui suit la panne. Le stockage de l'image de la page complète garantit une restauration correcte de la page, mais au prix d'un accroissement de la quantité de données à écrire dans les WAL. (Parce que la relecture des WAL démarre toujours à un point de vérification, il suffit de faire cela lors de la première modification de chaque page survenant après un point de vérification. De ce fait, une façon de réduire le coût d'écriture de pages complètes consiste à augmenter le paramètre réglant les intervalles entre points de vérification.)

La désactivation de ce paramètre accélère les opérations normales, mais peut aboutir soit à une corruption impossible à corriger soit à une corruption silencieuse, après un échec système. Les risques sont similaires à la désactivation de fsync, bien que moindres. Sa désactivation devrait se faire en se basant sur les mêmes recommandations que cet autre paramètre.

La désactivation de ce paramètre n'affecte pas l'utilisation de l'archivage des WAL pour la récupération d'un instantané, aussi appelé PITR (voir Section 25.3).

Ce paramètre ne peut être configuré que dans le fichier postgresql.conf ou indiqué sur la ligne de commande. Activé par défaut (on).

wal_log_hints (boolean)

Quand ce paramètre a la valeur on, le serveur PostgreSQL écrit le contenu entier de chaque page disque dans les journaux de transactions lors de la première modification de cette page après un checkpoint, même pour des modifications non critiques comme les hint bits.

Si les sommes de contrôle sont activées, la mise à jour des hint bits est toujours enregistrée dans les journaux et ce paramètre est ignoré. Vous pouvez utiliser ce paramètre pour tester le volume supplémentaire de journaux induit par l'activiation des sommes de contrôle sur les fichiers de données.

Ce paramètre n'est configurable qu'au démarrage du serveur. La valeur par défaut vaut off.

wal_compression (boolean)

Lorsque ce paramètre est à on, le serveur PostgreSQL compresse une image d'une page complète écrite dans les WAL lorsque full_page_writes est à on ou durant une sauvegarde de base. Une image compressée d'une page sera décompressée durant le rejeu des WAL. La valeur par défaut est à off. Seuls les superutilisateurs peuvent modifier ce paramètre.

Activer ce paramètre peut réduire le volume des WAL sans augmenter le risque de données corrompues irrécupérables, mais avec l'effet d'avoir un coût supplémentaire en terme de puissance CPU sur la compression durant l'écriture des WAL et sur la décompression lors du rejeu des WAL.

wal_buffers (integer)

La quantité de mémoire partagée utilisée pour les données des journaux de transactions qui n'ont pas encore été écrites sur disque. La configuration par défaut de -1 sélectionne une taille égale à 1/32 (environ 3%) de shared_buffers, mais pas moins de 64kB, et pas plus que la taille d'un journal de transactions, soit généralement 16MB. Cette valeur peut être configurée manuellement si le choix automatique est trop élevé ou trop faible, mais tout valeur positive inférieure à 32kB sera traitée comme étant exactement 32kB. Ce paramètre ne peut être configuré qu'au démarrage du serveur.

Le contenu du cache des journaux de transactions est écrit sur le disque à chaque validation d'une transaction, donc des valeurs très importantes ont peu de chance d'apporter un gain significatif. Néanmoins, configurer cette valeur à au moins quelques mégaoctets peut améliorer les performances en écriture sur un serveur chargé quand plusieurs clients valident en même temps. La configuration automatique sélectionnée par défaut avec la valeur -1 devrait être convenable.

wal_writer_delay (integer)

Indique à quelle fréquence le walwriter vide les journaux sur disque. Après avoir vidé les journaux sur disque, il s'endort pour wal_writer_delay millisecondes sauf s'il est réveillé par une transaction validée en asynchrone. Dans le cas où le dernier vidage est survenu il y a moins de wal_writer_delay millisecondes et que moins de wal_writer_flush_after octets ont été produits dans les WAL depuis, le WAL est seulement écrit via le système d'exploitation mais pas forcément écrit sur disque. La valeur par défaut est 200 millisecondes (200ms). Notez que sur de nombreux systèmes, la résolution réelle du délai d'endormissement est de 10 millisecondes ; configurer wal_writer_delay à une valeur qui n'est pas un multiple de 10 pourrait avoir le même résultat que de le configurer au prochain multiple de 10. Ce paramètre est seulement configurable dans le fichier postgresql.conf ainsi que sur la ligne de commande du serveur.

wal_writer_flush_after (integer)

Indique à quelle fréquence le walwriter vide les journaux sur disque. Dans le cas où le dernier vidage est arrivé il y a moins de wal_writer_delay millisecondes et que moins de wal_writer_flush_after octets de WAL ont été produits depuis, les WAL sont seulement écrit via le système d'exploitation, et pas forcé sur disque. Si wal_writer_flush_after est configuré à 0, le WAL est écrit et vidé à chaque fois que le walwriter doit écrire dans un WAL. La valeur par défaut est 1MB. Ce paramètre est seulement configurable dans le fichier postgresql.conf ainsi que sur la ligne de commande du serveur.

commit_delay (integer)

commit_delay ajoute un délai, exprimé en microsecondes avant qu'un vidage du journal de transactions ne soit effectué. Ceci peut améliorer les performances de la validation en groupe en permettant la validation d'un grand nombre transactions en un seul vidage des journaux, si la charge système est suffisamment importante pour que des transactions supplémentaires soient prêt ç être valider dans le même intervalle. Néanmoins, cela augmente aussi la latence jusqu'à commit_delay microsecondes pour chaque vidage de journaux. Comme le délai est perdu si aucune autre transaction n'est prête à être validée, un délai n'est respecté que si au moins commit_siblings autres transactions sont actives quand un vidage doit être initié. De plus, aucun délai ne sera pris en compte si fsync est désactivé. La valeur par défaut de commit_delay est zéro (aucun délai). Seuls les superutilisateurs peuvent modifier cette configuration.

Dans les versions de PostgreSQL antérieures à la 9.3, commit_delay se comportait différemment et était bien moins efficace : il n'affectait que les validations plutôt que les vidages de journaux et attendait que le délai complet soit passé même si le vidage du journal était terminé avant. À partir de PostgreSQL 9.3, le premier processus prêt à vider le journal attend pendant l'intervalle configuré alors que les autres processus attendent que le premier termine l'opération de vidage.

commit_siblings (integer)

Nombre minimum de transactions concurrentes ouvertes en même temps nécessaires avant d'attendre le délai commit_delay. Une valeur plus importante rend plus probable le fait qu'au moins une autre transaction soit prête à valider pendant le délai. La valeur par défaut est de cinq transactions.

19.5.2. Points de vérification

checkpoint_timeout (integer)

Temps maximum entre deux points de vérification automatique des WAL, en secondes. L'intervalle valide se situe entre 30 secondes et un jour. La valeur par défaut est de cinq minutes. Augmenter ce paramètre peut accroitre le temps nécessaire à une récupération après un arrêt brutal. Ce paramètre ne peut être configuré que dans le fichier postgresql.conf ou indiqué sur la ligne de commande.

checkpoint_completion_target (floating point)

Précise la cible pour la fin du CHECKPOINT, sous le format d'une fraction de temps entre deux CHECKPOINT. La valeur par défaut est 0.5. Ce paramètre ne peut être configuré que dans le fichier postgresql.conf ou indiqué sur la ligne de commande.

checkpoint_flush_after (integer)

Quand plus de checkpoint_flush_after octets ont été écrit par le processus d'écriture en tâche de fond (bgwriter), tente de forcer le système d'exploitation à écrire les données sur disque. Faire cela limite la quantité de données modifiées dans le cache disque du noyau, réduisant le risque de petites pauses dues à l'exécution d'un fsync à la fin d'un checkpoint ou à l'écriture massive en tâche de fond des données modifiées. Souvent, cela réduira fortement la latence des transactions mais il existe aussi quelques cas de dégradation des performances, tout spécialement avec les charges de travail plus importantes que shared_buffers, mais plus petites que le cache disque du système d'exploitation. Ce paramètre pourrait ne pas avoir d'effet sur certaines plateformes. L'intervalle valide se situe entre 0, qui désactive le « writeback » forcé, et 2MB. La valeur par défaut est 256KB sur Linux, 0 ailleurs. (Si BLCKSZ ne vaut pas 8 Ko, les valeurs par défaut et maximale n'évoluent pas de façon proportionnelle à cette constante.) Ce paramètre est seulement configurable dans le fichier postgresql.conf et à la ligne de commande.

checkpoint_warning (integer)

Si deux points de vérification imposés par le remplissage des fichiers segment interviennent dans un délai plus court que celui indiqué par ce paramètre (ce qui laisse supposer qu'il faut augmenter la valeur du paramètre max_wal_size), un message est écrit dans le fichier de traces du serveur. Par défaut, 30 secondes. Une valeur nulle (0) désactive cet avertissement. Aucun avertissement ne sera fait si checkpoint_timeout est inférieur à checkpoint_warning. Ce paramètre ne peut être configuré que dans le fichier postgresql.conf ou indiqué sur la ligne de commande.

max_wal_size (integer)

Taille maximale de l'augmentation des WAL entre deux points de vérification automatique des WAL. C'est une limite souple ; la taille des WAL peut excéder max_wal_size sous certaines circonstances, comme une surcharge du serveur, une commande archive_command qui échoue, ou une configuration haute pour wal_keep_segments. La valeur par défaut est 1 Go. Augmenter ce paramètre peut augmenter le temps nécessaire pour le rejeu suite à un crash. Ce paramètre ne peut être configuré que dans le fichier postgresql.conf ou indiqué sur la ligne de commande.

min_wal_size (integer)

Tant que l'occupation disque reste sous la valeur de ce paramètre, les anciens fichiers WAL sont toujours recyclés pour une utilisation future lors des points de vérification, plutôt que supprimés. Ceci peut être utilisé pour s'assurer qu'un espace suffisant est réservé pour faire face à des pics dans l'usage des WAL, par exemple lorsque d'importants travaux en lots sont lancés. La valeur par défaut est 80 Mo. Ce paramètre ne peut être configuré que dans le fichier postgresql.conf ou indiqué sur la ligne de commande.

19.5.3. Archivage

archive_mode (enum)

Quand archive_mode est activé, les segments WAL remplis peuvent être archivés en configurant archive_command. En plus de off, pour désactiver, il y a deux autres modes : on, et always. Lors du fonctionnement normal du serveur, il n'y a pas de différences entre les deux modes, mais lorsqu'il est positionné sur always, l'archiveur des WAL est aussi activé lors d'un rejeu des archives et en mode standby. Dans le mode always, tous les fichiers restaurés à partir de l'archive ou envoyés lors de la réplication en continue seront archivés (à nouveau). Voir Section 26.2.9 pour des détails.

archive_mode et archive_command sont des variables séparées de façon à ce que archive_command puisse être modifiée sans quitter le mode d'archivage. Ce paramètre ne peut être configuré qu'au lancement du serveur. archive_mode ne peut pas être activé quand wal_level est configuré à minimal.

archive_command (string)

Commande shell à exécuter pour archiver un segment terminé de la série des fichiers WAL. Tout %p dans la chaîne est remplacé par le chemin du fichier à archiver et tout %f par le seul nom du fichier. (Le chemin est relatif au répertoire de travail du serveur, c'est-à-dire le répertoire de données du cluster.) %% est utilisé pour intégrer un caractère % dans la commande. Il est important que la commande renvoit un code zéro seulement si elle a réussit l'archivage. Pour plus d'informations, voir Section 25.3.1.

Ce paramètre ne peut être configuré que dans le fichier postgresql.conf ou indiqué sur la ligne de commande. Il est ignoré sauf si archive_mode a été activé au lancement du serveur. Si archive_command est une chaîne vide (la valeur par défaut) alors que archive_mode est activé, alors l'archivage des journaux de transactions est désactivé temporairement mais le serveur continue d'accumuler les fichiers des journaux de transactions dans l'espoir qu'une commande lui soit rapidement proposée. Configurer archive_command à une commande qui ne fait rien tout en renvoyant true, par exemple /bin/true (REM sur Windows), désactive l'archivage mais casse aussi la chaîne des fichiers des journaux de transactions nécessaires pour la restauration d'une archive. Cela ne doit donc être utilisé quand lors de circonstances inhabituelles.

archive_timeout (integer)

Le archive_command n'est appelé que pour les segments WAL remplis. De ce fait, si le serveur n'engendre que peu de trafic WAL (ou qu'il y a des périodes de plus faible activité), il se peut qu'un long moment s'écoule entre la fin d'une transaction et son archivage certain. Pour limiter l'âge des données non encore archivées, archive_timeout peut être configuré pour forcer le serveur à basculer périodiquement sur un nouveau segment WAL. Lorsque ce paramètre est positif, le serveur bascule sur un nouveau segment à chaque fois que archive_timeout secondes se sont écoulées depuis le dernier changement de segment et qu'il n'y a pas eu d'activité de la base de données, y compris un seul CHECKPOINT. (les points de reprise sont ne sont pas effectués s'il n'y a pas d'activité sur les bases.) Les fichiers archivés clos par anticipation suite à une bascule imposée sont toujours de la même taille que les fichiers complets. Il est donc déconseillé de configurer un temps très court pour archive_timeout -- cela va faire exploser la taille du stockage des archives. Un paramétrage d'archive_timeout de l'ordre de la minute est habituellement raisonnable. Cependant, vous devriez considérer l'utilisation de la réplication en flux à la place de l'archivage si vous voulez que les données soient envoyées du serveur maître plus rapidement que cela. Ce paramètre ne peut être configuré que dans le fichier postgresql.conf ou indiqué sur la ligne de commande.