xlogrecord.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. * xlogrecord.h
  3. *
  4. * Definitions for the WAL record format.
  5. *
  6. * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
  7. * Portions Copyright (c) 1994, Regents of the University of California
  8. *
  9. * src/include/access/xlogrecord.h
  10. */
  11. #ifndef XLOGRECORD_H
  12. #define XLOGRECORD_H
  13. #include "access/rmgr.h"
  14. #include "access/xlogdefs.h"
  15. #include "port/pg_crc32c.h"
  16. #include "storage/block.h"
  17. #include "storage/relfilenode.h"
  18. /*
  19. * The overall layout of an XLOG record is:
  20. * Fixed-size header (XLogRecord struct)
  21. * XLogRecordBlockHeader struct
  22. * XLogRecordBlockHeader struct
  23. * ...
  24. * XLogRecordDataHeader[Short|Long] struct
  25. * block data
  26. * block data
  27. * ...
  28. * main data
  29. *
  30. * There can be zero or more XLogRecordBlockHeaders, and 0 or more bytes of
  31. * rmgr-specific data not associated with a block. XLogRecord structs
  32. * always start on MAXALIGN boundaries in the WAL files, but the rest of
  33. * the fields are not aligned.
  34. *
  35. * The XLogRecordBlockHeader, XLogRecordDataHeaderShort and
  36. * XLogRecordDataHeaderLong structs all begin with a single 'id' byte. It's
  37. * used to distinguish between block references, and the main data structs.
  38. */
  39. typedef struct XLogRecord
  40. {
  41. uint32 xl_tot_len; /* total len of entire record */
  42. TransactionId xl_xid; /* xact id */
  43. XLogRecPtr xl_prev; /* ptr to previous record in log */
  44. uint8 xl_info; /* flag bits, see below */
  45. RmgrId xl_rmid; /* resource manager for this record */
  46. /* 2 bytes of padding here, initialize to zero */
  47. pg_crc32c xl_crc; /* CRC for this record */
  48. /* XLogRecordBlockHeaders and XLogRecordDataHeader follow, no padding */
  49. } XLogRecord;
  50. #define SizeOfXLogRecord (offsetof(XLogRecord, xl_crc) + sizeof(pg_crc32c))
  51. /*
  52. * The high 4 bits in xl_info may be used freely by rmgr. The
  53. * XLR_SPECIAL_REL_UPDATE bit can be passed by XLogInsert caller. The rest
  54. * are set internally by XLogInsert.
  55. */
  56. #define XLR_INFO_MASK 0x0F
  57. #define XLR_RMGR_INFO_MASK 0xF0
  58. /*
  59. * If a WAL record modifies any relation files, in ways not covered by the
  60. * usual block references, this flag is set. This is not used for anything
  61. * by PostgreSQL itself, but it allows external tools that read WAL and keep
  62. * track of modified blocks to recognize such special record types.
  63. */
  64. #define XLR_SPECIAL_REL_UPDATE 0x01
  65. /*
  66. * Header info for block data appended to an XLOG record.
  67. *
  68. * 'data_length' is the length of the rmgr-specific payload data associated
  69. * with this block. It does not include the possible full page image, nor
  70. * XLogRecordBlockHeader struct itself.
  71. *
  72. * Note that we don't attempt to align the XLogRecordBlockHeader struct!
  73. * So, the struct must be copied to aligned local storage before use.
  74. */
  75. typedef struct XLogRecordBlockHeader
  76. {
  77. uint8 id; /* block reference ID */
  78. uint8 fork_flags; /* fork within the relation, and flags */
  79. uint16 data_length; /* number of payload bytes (not including page
  80. * image) */
  81. /* If BKPBLOCK_HAS_IMAGE, an XLogRecordBlockImageHeader struct follows */
  82. /* If BKPBLOCK_SAME_REL is not set, a RelFileNode follows */
  83. /* BlockNumber follows */
  84. } XLogRecordBlockHeader;
  85. #define SizeOfXLogRecordBlockHeader (offsetof(XLogRecordBlockHeader, data_length) + sizeof(uint16))
  86. /*
  87. * Additional header information when a full-page image is included
  88. * (i.e. when BKPBLOCK_HAS_IMAGE is set).
  89. *
  90. * As a trivial form of data compression, the XLOG code is aware that
  91. * PG data pages usually contain an unused "hole" in the middle, which
  92. * contains only zero bytes. If the length of "hole" > 0 then we have removed
  93. * such a "hole" from the stored data (and it's not counted in the
  94. * XLOG record's CRC, either). Hence, the amount of block data actually
  95. * present is BLCKSZ - the length of "hole" bytes.
  96. *
  97. * When wal_compression is enabled, a full page image which "hole" was
  98. * removed is additionally compressed using PGLZ compression algorithm.
  99. * This can reduce the WAL volume, but at some extra cost of CPU spent
  100. * on the compression during WAL logging. In this case, since the "hole"
  101. * length cannot be calculated by subtracting the number of page image bytes
  102. * from BLCKSZ, basically it needs to be stored as an extra information.
  103. * But when no "hole" exists, we can assume that the "hole" length is zero
  104. * and no such an extra information needs to be stored. Note that
  105. * the original version of page image is stored in WAL instead of the
  106. * compressed one if the number of bytes saved by compression is less than
  107. * the length of extra information. Hence, when a page image is successfully
  108. * compressed, the amount of block data actually present is less than
  109. * BLCKSZ - the length of "hole" bytes - the length of extra information.
  110. */
  111. typedef struct XLogRecordBlockImageHeader
  112. {
  113. uint16 length; /* number of page image bytes */
  114. uint16 hole_offset; /* number of bytes before "hole" */
  115. uint8 bimg_info; /* flag bits, see below */
  116. /*
  117. * If BKPIMAGE_HAS_HOLE and BKPIMAGE_IS_COMPRESSED, an
  118. * XLogRecordBlockCompressHeader struct follows.
  119. */
  120. } XLogRecordBlockImageHeader;
  121. #define SizeOfXLogRecordBlockImageHeader \
  122. (offsetof(XLogRecordBlockImageHeader, bimg_info) + sizeof(uint8))
  123. /* Information stored in bimg_info */
  124. #define BKPIMAGE_HAS_HOLE 0x01 /* page image has "hole" */
  125. #define BKPIMAGE_IS_COMPRESSED 0x02 /* page image is compressed */
  126. /*
  127. * Extra header information used when page image has "hole" and
  128. * is compressed.
  129. */
  130. typedef struct XLogRecordBlockCompressHeader
  131. {
  132. uint16 hole_length; /* number of bytes in "hole" */
  133. } XLogRecordBlockCompressHeader;
  134. #define SizeOfXLogRecordBlockCompressHeader \
  135. sizeof(XLogRecordBlockCompressHeader)
  136. /*
  137. * Maximum size of the header for a block reference. This is used to size a
  138. * temporary buffer for constructing the header.
  139. */
  140. #define MaxSizeOfXLogRecordBlockHeader \
  141. (SizeOfXLogRecordBlockHeader + \
  142. SizeOfXLogRecordBlockImageHeader + \
  143. SizeOfXLogRecordBlockCompressHeader + \
  144. sizeof(RelFileNode) + \
  145. sizeof(BlockNumber))
  146. /*
  147. * The fork number fits in the lower 4 bits in the fork_flags field. The upper
  148. * bits are used for flags.
  149. */
  150. #define BKPBLOCK_FORK_MASK 0x0F
  151. #define BKPBLOCK_FLAG_MASK 0xF0
  152. #define BKPBLOCK_HAS_IMAGE 0x10 /* block data is an XLogRecordBlockImage */
  153. #define BKPBLOCK_HAS_DATA 0x20
  154. #define BKPBLOCK_WILL_INIT 0x40 /* redo will re-init the page */
  155. #define BKPBLOCK_SAME_REL 0x80 /* RelFileNode omitted, same as previous */
  156. /*
  157. * XLogRecordDataHeaderShort/Long are used for the "main data" portion of
  158. * the record. If the length of the data is less than 256 bytes, the short
  159. * form is used, with a single byte to hold the length. Otherwise the long
  160. * form is used.
  161. *
  162. * (These structs are currently not used in the code, they are here just for
  163. * documentation purposes).
  164. */
  165. typedef struct XLogRecordDataHeaderShort
  166. {
  167. uint8 id; /* XLR_BLOCK_ID_DATA_SHORT */
  168. uint8 data_length; /* number of payload bytes */
  169. } XLogRecordDataHeaderShort;
  170. #define SizeOfXLogRecordDataHeaderShort (sizeof(uint8) * 2)
  171. typedef struct XLogRecordDataHeaderLong
  172. {
  173. uint8 id; /* XLR_BLOCK_ID_DATA_LONG */
  174. /* followed by uint32 data_length, unaligned */
  175. } XLogRecordDataHeaderLong;
  176. #define SizeOfXLogRecordDataHeaderLong (sizeof(uint8) + sizeof(uint32))
  177. /*
  178. * Block IDs used to distinguish different kinds of record fragments. Block
  179. * references are numbered from 0 to XLR_MAX_BLOCK_ID. A rmgr is free to use
  180. * any ID number in that range (although you should stick to small numbers,
  181. * because the WAL machinery is optimized for that case). A couple of ID
  182. * numbers are reserved to denote the "main" data portion of the record.
  183. *
  184. * The maximum is currently set at 32, quite arbitrarily. Most records only
  185. * need a handful of block references, but there are a few exceptions that
  186. * need more.
  187. */
  188. #define XLR_MAX_BLOCK_ID 32
  189. #define XLR_BLOCK_ID_DATA_SHORT 255
  190. #define XLR_BLOCK_ID_DATA_LONG 254
  191. #define XLR_BLOCK_ID_ORIGIN 253
  192. #endif /* XLOGRECORD_H */