Bien que tous les modules internes traçant dans les journaux de transactions ont leur propre type d'enregistrements WAL, il existe aussi un type d'enregistrement générique. Ce type d'enregistrement décrit les modifications de pages d'une façon générique. Ceci est utile pour les extensions fournissant des méthodes d'accès personnalisés car elles ne peuvent pas enregistrer leurs propres routines de rejeu des journaux de transactions.
L'API de construction des enregistrements génériques pour les journaux de transactions est définie dans access/generic_xlog.h et implémentée dans access/transam/generic_xlog.c.
Pour réaliser une mise à jour de données tracée dans les journaux de transactions en utilisant le système d'enregistrement générique, suivez ces étapes :
state = GenericXLogStart(relation) -- lance la construction d'un enregistrement générique pour la relation spécifiée.
page = GenericXLogRegisterBuffer(state, buffer, flags) -- enregistre un tampon à modifier dans l'enregistrement générique actuel du journal de transactions. Cette fonction renvoie un pointeur vers une copie temporaire de la page du tampon, où les modifications doivent survenir. (Ne modifiez pas le contenu du tampon.) Le troisième argument est un masque de bits pour les drapeaux applicables à l'opération. Actuellement, le seul drapeau disponible est GENERIC_XLOG_FULL_IMAGE, qui indique qu'une image d'une page complète doit être inclue dans l'enregistrement WAL, plutôt qu'un delta. Typiquement, ce drapeau doit être configurée si le bloc est nouveau ou s'il a été complètement réécrit. GenericXLogRegisterBuffer peut être répété si l'action tracée doit modifier plusieurs blocs.
Réalisez des modifications à l'image des pages obtenue à l'étape précédente.
GenericXLogFinish(state) -- applique les modifications aux tampons et émet l'enregistrement générique.
La construction d'enregistrements de journaux de transactions peut être annulée entre n'importe laquelle des étapes ci-dessus en appelant la fonction GenericXLogAbort(state). Ceci annulera toutes les modifications aux copies d'image de bloc.
Merci de noter les points suivants lors de l'utilisation de la fonctionnalité d'enregistrements génériques pour les journaux de transactions :
Aucune modification directe des tampons n'est autorisée ! Toutes les modifications doivent se faire dans les copies récupérées de GenericXLogRegisterBuffer(). Autrement dit, le code réalisant les enregistrements génériques ne doit jamais appeler lui-même BufferGetPage(). Néanmoins, il est de la responsabilité de l'appelant du bloquer/débloquer et de verrouiller/déverrouiller les tampons au bon moment. Un verrou exclusif doit être obtenu et conservé pour chaque tampon cible avant l'appel à GenericXLogRegisterBuffer() et jusqu'à l'appel à GenericXLogFinish().
Les enregistrements de tampons (étape 2) et les modifications des images de page (étape 3) peuvent être librement mélangés. Les deux étapes peuvent donc être répétées dans n'importe quelle séquence. Gardez en tête que les tampons doivent être enregistrés dans le même ordre que l'obtention des verrous lors de leur rejeu.
Le nombre maximum de tampons qui peut être enregistré pour un enregistrement générique dépend de la constante MAX_GENERIC_XLOG_PAGES. Une erreur est renvoyée si cette limite est dépassée.
Un enregistrement générique suppose que les blocs à modifier aient un schéma standard et, en particulier, qu'il n'y ait pas de données utiles entre pd_lower et pd_upper.
Comme vous modifiez des copies de pages de tampon, GenericXLogStart() ne commence pas une section critique. De ce fait, vous pouvez faire de l'allocation mémoire de façon sûre, en renvoyant des erreurs le cas échéant, entre GenericXLogStart() et GenericXLogFinish(). La seule section réellement critique se trouve dans GenericXLogFinish(). Il n'est pas non plus nécessaire de s'inquiéter lors de l'appel de GenericXLogAbort() pendant une sortie en erreur.
GenericXLogFinish() fait attention à marquer les tampons comme modifiés et à configurer leur LSN. Vous n'avez pas besoin de le faire explicitement.
Pour les relations non journalisées, tout fonctionne de la même façon sauf qu'aucun enregistrement n'est réellement émis. De ce fait, vous n'avez pas besoin de faire une quelconque vérification explicite pour les relations non journalisées.
La fonction de rejeu des enregistrements génériques acquiert des verrous exclusifs sur les tampons dans le même ordre qu'ils ont été enregistrés. Après l'exécution du rejeu, les verrous sont relachés dans le même ordre.
Si GENERIC_XLOG_FULL_IMAGE n'est pas spécifié pour un tampon enregistré, l'enregistrement générique contient un delta entre les ancienne et nouvelle images. Ce delta est basé sur une comparaison octet par octet. Ceci n'est pas spécialement compact dans le cas d'un déplacement de données dans une page, et pourrait être amélioré dans le futur.