mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Add Generic WAL interface
This interface is designed to give an access to WAL for extensions which could implement new access method, for example. Previously it was impossible because restoring from custom WAL would need to access system catalog to find a redo custom function. This patch suggests generic way to describe changes on page with standart layout. Bump XLOG_PAGE_MAGIC because of new record type. Author: Alexander Korotkov with a help of Petr Jelinek, Markus Nullmeier and minor editorization by my Reviewers: Petr Jelinek, Alvaro Herrera, Teodor Sigaev, Jim Nasby, Michael Paquier
This commit is contained in:
@ -100,6 +100,7 @@
|
||||
<!ENTITY sources SYSTEM "sources.sgml">
|
||||
<!ENTITY storage SYSTEM "storage.sgml">
|
||||
<!ENTITY tablesample-method SYSTEM "tablesample-method.sgml">
|
||||
<!ENTITY generic-wal SYSTEM "generic-wal.sgml">
|
||||
|
||||
<!-- contrib information -->
|
||||
<!ENTITY contrib SYSTEM "contrib.sgml">
|
||||
|
141
doc/src/sgml/generic-wal.sgml
Normal file
141
doc/src/sgml/generic-wal.sgml
Normal file
@ -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)</> — start
|
||||
construction of a generic xlog record for the given relation.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<function>page = GenericXLogRegister(state, buffer, isNew)</> —
|
||||
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)</> — 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>
|
@ -247,6 +247,7 @@
|
||||
&custom-scan;
|
||||
&geqo;
|
||||
&indexam;
|
||||
&generic-wal;
|
||||
&gist;
|
||||
&spgist;
|
||||
&gin;
|
||||
|
Reference in New Issue
Block a user