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.