diff options
Diffstat (limited to 'doc/src/sgml/generic-wal.sgml')
-rw-r--r-- | doc/src/sgml/generic-wal.sgml | 141 |
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)</> — 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> |