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> — 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 — 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> — 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