La validation asynchrone est une option qui permet aux transactions de se terminer plus rapidement. Le risque encouru est de perdre les transactions les plus récentes dans le cas où le serveur s'arrête brutalement. Dans beaucoup d'applications, le compromis est acceptable.
Comme le décrit la section précédente, la validation d'une transaction est habituellement synchrone : le serveur attend que les enregistrements des journaux de transaction soient bien sauvegardés sur le stockage permanent avant d'informer le client du succès de l'opération. Le client a donc la garantie qu'une transaction validée est stockée de façon sûre, donc même en cas d'arrêt brutal immédiatement après. Néanmoins, pour les petites transactions, ce délai est une partie importante de la durée totale d'exécution de la transaction. Sélectionner le mode de validation asynchrone signifie que le serveur annonce le succès de l'opération dès que la transaction est terminée logiquement, donc avant que les enregistrements du journal de transaction que cette transaction a générés ne soient réellement stockés sur disque. Ceci peut apporter une accélération importante pour les petites transactions.
La validation asynchrone introduit le risque des pertes de données. Il existe un petit délai entre le moment où le rapport de la fin d'une transaction est envoyé au client et celui où la transaction est réellement enregistrée (c'est-à-dire le moment où le résultat de cette transaction ne pourra pas être perdu même en cas d'arrêt brutal du serveur). Du coup, la validation asynchrone ne devrait pas être utilisée si le client se base sur le fait que la transaction est enregistrée de façon sûre. Par exemple, une banque ne devra pas utiliser la validation asynchrone pour une transaction enregistrant la sortie d'argent d'un distributeur bancaire. Dans de nombreux autres scénarios, comme la trace d'événements, il n'y a pas besoin de garantie forte de ce type.
Le risque pris avec l'utilisation de la validation asynchrone concerne la perte de données, pas la corruption de données. Si le serveur s'arrête brutalement, il redémarrera en rejouant les journaux de transaction jusqu'au dernier enregistrement vidé sur disque. La base sera donc restaurée dans un état cohérent mais toutes les transactions qui n'auront pas été enregistrées sur disque n'y apparaîtront pas. L'effet immédiat est donc la perte des toutes dernières transactions. Comme les transactions sont rejouées dans l'ordre de validation, aucune incohérence ne sera introduite -- par exemple, si la transaction B fait des modifications sur les effets d'une précédente transaction A, il n'est pas possible que les effets de A soient perdus alors que les effets de B sont préservés.
L'utilisateur peut sélectionner le mode de validation de chaque
transaction ; il est donc possible d'avoir en même temps des transactions
validées en synchrone et en asynchrone.
Cela offre une grande flexibilité dans le choix entre la performance
et la certitude de la durabilité des transactions.
Le mode de validation est contrôlé par le paramètre utilisateur
synchronous_commit, qui peut être modifié comme
tout autre paramètre utilisateur. Le mode utilisé pour une
transaction dépend de la valeur de synchronous_commit
quand démarre la validation de la transaction.
Certaines commandes, par exemple DROP TABLE
, sont
forcées en mode synchrone quelle que soit la valeur du paramètre
synchronous_commit
. Ceci a pour but de s'assurer de
la cohérence entre le système de fichiers du serveur et l'état logique
de la base de données. Les commandes gérant la validation en deux phases
(two-phase commit),
comme PREPARE TRANSACTION
, sont aussi toujours
synchrones.
Si la base de données s'arrête brutalement dans la fenêtre de
vulnérabilité entre une validation asynchrone
et l'écriture des enregistrements dans le journal
des transactions, les modifications réalisées lors de cette transaction
seront perdues. Cette fenêtre est limitée
car un processus en tâche de fond (le « wal writer »)
écrit sur le disque
les enregistrements non écrits des journaux de transaction
toutes les wal_writer_delay millisecondes.
La fenêtre de vulnérabilité s'étend en réalité à trois fois
wal_writer_delay
car le processus d'écriture des
journaux de transaction est conçu pour favoriser l'écriture de pages
complètes lors des périodes de grosses activités.
Un arrêt en mode immédiat est équivalent à un arrêt brutal et causera du coup la perte des validations asynchrones.
La validation asynchrone fournit un comportement différent de la simple
désactivation de fsync. fsync
est
un paramètre pour le serveur entier qui modifie le comportement de toutes
les transactions.
Il désactive dans PostgreSQL
toute la logique qui tente de synchroniser les
écritures dans les différentes parties de la base,
et donc un arrêt brutal (plus précisément
un arrêt brutal du matériel ou du système d'exploitation, pas un plantage
de PostgreSQL lui-même) pourrait résulter
en une corruption arbitraire de l'état de la base de données. Dans de
nombreux scénarios, la validation asynchrone fournit la majorité des
améliorations de performances obtenues par la désactivation de
fsync
, mais sans le risque de la corruption de données.
commit_delay semble aussi très similaire à la
validation asynchrone mais il s'agit en fait d'une méthode de validation
synchrone (en fait, commit_delay
est ignoré lors d'une
validation asynchrone). commit_delay
provoque un délai avant la mise à jour sur disque
du WAL d'une transaction,
dans l'espoir que l'opération profite à d'autres transactions
commitées à peu près au même moment. Ce paramètre peut
être vu comme le moyen d'augmenter la fenêtre de temps durant laquelle
chaque transaction peut participer à un même vidage sur disque, pour amortir
son coût sur plusieurs transactions.