1<!-- doc/src/sgml/generic-wal.sgml -->
2
3<chapter id="generic-wal">
4 <title>Generic WAL Records</title>
5
6  <para>
7   Although all built-in WAL-logged modules have their own types of WAL
8   records, there is also a generic WAL record type, which describes changes
9   to pages in a generic way.  This is useful for extensions that provide
10   custom access methods, because they cannot register their own WAL redo
11   routines.
12  </para>
13
14  <para>
15   The API for constructing generic WAL records is defined in
16   <filename>access/generic_xlog.h</filename> and implemented
17   in <filename>access/transam/generic_xlog.c</filename>.
18  </para>
19
20  <para>
21   To perform a WAL-logged data update using the generic WAL record
22   facility, follow these steps:
23
24   <orderedlist>
25    <listitem>
26     <para>
27      <function>state = GenericXLogStart(relation)</function> &mdash; start
28      construction of a generic WAL record for the given relation.
29     </para>
30    </listitem>
31
32    <listitem>
33     <para>
34      <function>page = GenericXLogRegisterBuffer(state, buffer, flags)</function>
35      &mdash; register a buffer to be modified within the current generic WAL
36      record.  This function returns a pointer to a temporary copy of the
37      buffer's page, where modifications should be made.  (Do not modify the
38      buffer's contents directly.)  The third argument is a bit mask of flags
39      applicable to the operation.  Currently the only such flag is
40      <literal>GENERIC_XLOG_FULL_IMAGE</literal>, which indicates that a full-page
41      image rather than a delta update should be included in the WAL record.
42      Typically this flag would be set if the page is new or has been
43      rewritten completely.
44      <function>GenericXLogRegisterBuffer</function> can be repeated if the
45      WAL-logged action needs to modify multiple pages.
46     </para>
47    </listitem>
48
49    <listitem>
50     <para>
51      Apply modifications to the page images obtained in the previous step.
52     </para>
53    </listitem>
54
55    <listitem>
56     <para>
57      <function>GenericXLogFinish(state)</function> &mdash; apply the changes to
58      the buffers and emit the generic WAL record.
59     </para>
60    </listitem>
61   </orderedlist>
62  </para>
63
64  <para>
65   WAL record construction can be canceled between any of the above steps by
66   calling <function>GenericXLogAbort(state)</function>.  This will discard all
67   changes to the page image copies.
68  </para>
69
70  <para>
71   Please note the following points when using the generic WAL record
72   facility:
73
74   <itemizedlist>
75    <listitem>
76     <para>
77      No direct modifications of buffers are allowed!  All modifications must
78      be done in copies acquired from <function>GenericXLogRegisterBuffer()</function>.
79      In other words, code that makes generic WAL records should never call
80      <function>BufferGetPage()</function> for itself.  However, it remains the
81      caller's responsibility to pin/unpin and lock/unlock the buffers at
82      appropriate times.  Exclusive lock must be held on each target buffer
83      from before <function>GenericXLogRegisterBuffer()</function> until after
84      <function>GenericXLogFinish()</function>.
85     </para>
86    </listitem>
87
88    <listitem>
89     <para>
90      Registrations of buffers (step 2) and modifications of page images
91      (step 3) can be mixed freely, i.e., both steps may be repeated in any
92      sequence.  Keep in mind that buffers should be registered in the same
93      order in which locks are to be obtained on them during replay.
94     </para>
95    </listitem>
96
97    <listitem>
98     <para>
99      The maximum number of buffers that can be registered for a generic WAL
100      record is <literal>MAX_GENERIC_XLOG_PAGES</literal>.  An error will be thrown
101      if this limit is exceeded.
102     </para>
103    </listitem>
104
105    <listitem>
106     <para>
107      Generic WAL assumes that the pages to be modified have standard
108      layout, and in particular that there is no useful data between
109      <structfield>pd_lower</structfield> and <structfield>pd_upper</structfield>.
110     </para>
111    </listitem>
112
113    <listitem>
114     <para>
115      Since you are modifying copies of buffer
116      pages, <function>GenericXLogStart()</function> does not start a critical
117      section.  Thus, you can safely do memory allocation, error throwing,
118      etc. between <function>GenericXLogStart()</function> and
119      <function>GenericXLogFinish()</function>.  The only actual critical section is
120      present inside <function>GenericXLogFinish()</function>.  There is no need to
121      worry about calling  <function>GenericXLogAbort()</function> during an error
122      exit, either.
123     </para>
124    </listitem>
125
126    <listitem>
127     <para>
128      <function>GenericXLogFinish()</function> takes care of marking buffers dirty
129      and setting their LSNs.  You do not need to do this explicitly.
130     </para>
131    </listitem>
132
133    <listitem>
134     <para>
135      For unlogged relations, everything works the same except that no
136      actual WAL record is emitted.  Thus, you typically do not need to do
137      any explicit checks for unlogged relations.
138     </para>
139    </listitem>
140
141    <listitem>
142     <para>
143      The generic WAL redo function will acquire exclusive locks to buffers
144      in the same order as they were registered.  After redoing all changes,
145      the locks will be released in the same order.
146     </para>
147    </listitem>
148
149    <listitem>
150     <para>
151      If <literal>GENERIC_XLOG_FULL_IMAGE</literal> is not specified for a
152      registered buffer, the generic WAL record contains a delta between
153      the old and the new page images.  This delta is based on byte-by-byte
154      comparison.  This is not very compact for the case of moving data
155      within a page, and might be improved in the future.
156     </para>
157    </listitem>
158   </itemizedlist>
159  </para>
160</chapter>
161