aboutsummaryrefslogtreecommitdiff
path: root/doc/src/sgml/generic-wal.sgml
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/sgml/generic-wal.sgml')
-rw-r--r--doc/src/sgml/generic-wal.sgml141
1 files changed, 141 insertions, 0 deletions
diff --git a/doc/src/sgml/generic-wal.sgml b/doc/src/sgml/generic-wal.sgml
new file mode 100644
index 00000000000..6655f22f3a7
--- /dev/null
+++ b/doc/src/sgml/generic-wal.sgml
@@ -0,0 +1,141 @@
+<!-- doc/src/sgml/generic-wal.sgml -->
+
+<chapter id="generic-wal">
+ <title>Generic WAL records</title>
+
+ <para>
+ Despite all built-in access methods and WAL-logged modules having their own
+ types of WAL records, there is also a generic WAL record type, which describes
+ changes to pages in a generic way. This is useful for extensions that
+ provide custom access methods, because they cannot register their own
+ WAL redo routines.
+ </para>
+
+ <para>
+ The API for contructing generic WAL records is defined in
+ <filename>generic_xlog.h</> and implemented in <filename>generic_xlog.c</>.
+ Each generic WAL record must be constructed by following these steps:
+
+ <orderedlist>
+ <listitem>
+ <para>
+ <function>state = GenericXLogStart(relation)</> &mdash; start
+ construction of a generic xlog record for the given relation.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <function>page = GenericXLogRegister(state, buffer, isNew)</> &mdash;
+ register one or more buffers (one at a time) for the current generic
+ xlog record. This function returns a copy of the page image, where
+ modifications can be made. The second argument indicates if the page
+ is new (eventually, this will result in a full page image being put into
+ the xlog record).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Apply modifications to page images obtained in the previous step.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <function>GenericXLogAbort(state)</> &mdash; finish construction of
+ a generic xlog record.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+
+ <para>
+ The xlog record construction can be canceled between any of the above
+ steps by calling <function>GenericXLogAbort()</>. This will discard all
+ changes to the page image copies.
+ </para>
+
+ <para>
+ Please note the following points when constructing generic xlog records:
+ <itemizedlist>
+ <listitem>
+ <para>
+ No direct modifications of page images are allowed! All modifications
+ must be done in copies acquired from <function>GenericXLogRegister()</>.
+ In other words, code which makes generic xlog records must never call
+ <function>BufferGetPage()</>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Registrations of buffers (step 2) and modifications of page images
+ (step 3) can be mixed freely, i.e., both steps may be repeated in any
+ sequence. The only restriction is that you can modify a page image
+ only after the registration of the corresponding buffer.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ After registration, the buffer can also be unregistered by calling
+ <function>GenericXLogUnregister(buffer)</>. In this case, the changes
+ made to that particular page image copy will be discarded.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Generic xlog assumes that pages are using standard layout. I.e., all
+ information between pd_lower and pd_upper will be discarded.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The maximum number of buffers that can be simultaneously registered
+ for a generic xlog is <literal>MAX_GENERIC_XLOG_PAGES</>. An error will
+ be thrown if this limit is exceeded.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Since you modify copies of page images, <function>GenericXLogStart()</>
+ does not start a critical section. Thus, you can do memory allocation,
+ error throwing, etc. between <function>GenericXLogStart()</> and
+ <function>GenericXLogFinish()</>. The actual critical section is present
+ inside <function>GenericXLogFinish()</>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>GenericXLogFinish()</> takes care of marking buffers as dirty
+ and setting their LSNs. You do not need to do this explicitly.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ For unlogged relations, everything works the same except there is no
+ WAL record produced. Thus, you typically do not need to do any explicit
+ checks for unlogged relations.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If a registered buffer is not new, the generic xlog record contains
+ a delta between the old and the new page images. This delta is produced
+ using per byte comparison. The current delta mechanism is not effective
+ for moving data within a page and may be improved in the future.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The generic xlog redo function will acquire exclusive locks to buffers
+ in the same order as they were registered. After redoing all changes,
+ the locks will be released in the same order.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+</chapter>