ginxlog.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*--------------------------------------------------------------------------
  2. * ginxlog.h
  3. * header file for postgres inverted index xlog implementation.
  4. *
  5. * Copyright (c) 2006-2022, PostgreSQL Global Development Group
  6. *
  7. * src/include/access/ginxlog.h
  8. *--------------------------------------------------------------------------
  9. */
  10. #ifndef GINXLOG_H
  11. #define GINXLOG_H
  12. #include "access/ginblock.h"
  13. #include "access/itup.h"
  14. #include "access/xlogreader.h"
  15. #include "lib/stringinfo.h"
  16. #include "storage/off.h"
  17. #define XLOG_GIN_CREATE_PTREE 0x10
  18. typedef struct ginxlogCreatePostingTree
  19. {
  20. uint32 size;
  21. /* A compressed posting list follows */
  22. } ginxlogCreatePostingTree;
  23. /*
  24. * The format of the insertion record varies depending on the page type.
  25. * ginxlogInsert is the common part between all variants.
  26. *
  27. * Backup Blk 0: target page
  28. * Backup Blk 1: left child, if this insertion finishes an incomplete split
  29. */
  30. #define XLOG_GIN_INSERT 0x20
  31. typedef struct
  32. {
  33. uint16 flags; /* GIN_INSERT_ISLEAF and/or GIN_INSERT_ISDATA */
  34. /*
  35. * FOLLOWS:
  36. *
  37. * 1. if not leaf page, block numbers of the left and right child pages
  38. * whose split this insertion finishes, as BlockIdData[2] (beware of
  39. * adding fields in this struct that would make them not 16-bit aligned)
  40. *
  41. * 2. a ginxlogInsertEntry or ginxlogRecompressDataLeaf struct, depending
  42. * on tree type.
  43. *
  44. * NB: the below structs are only 16-bit aligned when appended to a
  45. * ginxlogInsert struct! Beware of adding fields to them that require
  46. * stricter alignment.
  47. */
  48. } ginxlogInsert;
  49. typedef struct
  50. {
  51. OffsetNumber offset;
  52. bool isDelete;
  53. IndexTupleData tuple; /* variable length */
  54. } ginxlogInsertEntry;
  55. typedef struct
  56. {
  57. uint16 nactions;
  58. /* Variable number of 'actions' follow */
  59. } ginxlogRecompressDataLeaf;
  60. /*
  61. * Note: this struct is currently not used in code, and only acts as
  62. * documentation. The WAL record format is as specified here, but the code
  63. * uses straight access through a Pointer and memcpy to read/write these.
  64. */
  65. typedef struct
  66. {
  67. uint8 segno; /* segment this action applies to */
  68. char type; /* action type (see below) */
  69. /*
  70. * Action-specific data follows. For INSERT and REPLACE actions that is a
  71. * GinPostingList struct. For ADDITEMS, a uint16 for the number of items
  72. * added, followed by the items themselves as ItemPointers. DELETE actions
  73. * have no further data.
  74. */
  75. } ginxlogSegmentAction;
  76. /* Action types */
  77. #define GIN_SEGMENT_UNMODIFIED 0 /* no action (not used in WAL records) */
  78. #define GIN_SEGMENT_DELETE 1 /* a whole segment is removed */
  79. #define GIN_SEGMENT_INSERT 2 /* a whole segment is added */
  80. #define GIN_SEGMENT_REPLACE 3 /* a segment is replaced */
  81. #define GIN_SEGMENT_ADDITEMS 4 /* items are added to existing segment */
  82. typedef struct
  83. {
  84. OffsetNumber offset;
  85. PostingItem newitem;
  86. } ginxlogInsertDataInternal;
  87. /*
  88. * Backup Blk 0: new left page (= original page, if not root split)
  89. * Backup Blk 1: new right page
  90. * Backup Blk 2: original page / new root page, if root split
  91. * Backup Blk 3: left child, if this insertion completes an earlier split
  92. */
  93. #define XLOG_GIN_SPLIT 0x30
  94. typedef struct ginxlogSplit
  95. {
  96. RelFileNode node;
  97. BlockNumber rrlink; /* right link, or root's blocknumber if root
  98. * split */
  99. BlockNumber leftChildBlkno; /* valid on a non-leaf split */
  100. BlockNumber rightChildBlkno;
  101. uint16 flags; /* see below */
  102. } ginxlogSplit;
  103. /*
  104. * Flags used in ginxlogInsert and ginxlogSplit records
  105. */
  106. #define GIN_INSERT_ISDATA 0x01 /* for both insert and split records */
  107. #define GIN_INSERT_ISLEAF 0x02 /* ditto */
  108. #define GIN_SPLIT_ROOT 0x04 /* only for split records */
  109. /*
  110. * Vacuum simply WAL-logs the whole page, when anything is modified. This
  111. * is functionally identical to XLOG_FPI records, but is kept separate for
  112. * debugging purposes. (When inspecting the WAL stream, it's easier to see
  113. * what's going on when GIN vacuum records are marked as such, not as heap
  114. * records.) This is currently only used for entry tree leaf pages.
  115. */
  116. #define XLOG_GIN_VACUUM_PAGE 0x40
  117. /*
  118. * Vacuuming posting tree leaf page is WAL-logged like recompression caused
  119. * by insertion.
  120. */
  121. #define XLOG_GIN_VACUUM_DATA_LEAF_PAGE 0x90
  122. typedef struct ginxlogVacuumDataLeafPage
  123. {
  124. ginxlogRecompressDataLeaf data;
  125. } ginxlogVacuumDataLeafPage;
  126. /*
  127. * Backup Blk 0: deleted page
  128. * Backup Blk 1: parent
  129. * Backup Blk 2: left sibling
  130. */
  131. #define XLOG_GIN_DELETE_PAGE 0x50
  132. typedef struct ginxlogDeletePage
  133. {
  134. OffsetNumber parentOffset;
  135. BlockNumber rightLink;
  136. TransactionId deleteXid; /* last Xid which could see this page in scan */
  137. } ginxlogDeletePage;
  138. #define XLOG_GIN_UPDATE_META_PAGE 0x60
  139. /*
  140. * Backup Blk 0: metapage
  141. * Backup Blk 1: tail page
  142. */
  143. typedef struct ginxlogUpdateMeta
  144. {
  145. RelFileNode node;
  146. GinMetaPageData metadata;
  147. BlockNumber prevTail;
  148. BlockNumber newRightlink;
  149. int32 ntuples; /* if ntuples > 0 then metadata.tail was
  150. * updated with that many tuples; else new sub
  151. * list was inserted */
  152. /* array of inserted tuples follows */
  153. } ginxlogUpdateMeta;
  154. #define XLOG_GIN_INSERT_LISTPAGE 0x70
  155. typedef struct ginxlogInsertListPage
  156. {
  157. BlockNumber rightlink;
  158. int32 ntuples;
  159. /* array of inserted tuples follows */
  160. } ginxlogInsertListPage;
  161. /*
  162. * Backup Blk 0: metapage
  163. * Backup Blk 1 to (ndeleted + 1): deleted pages
  164. */
  165. #define XLOG_GIN_DELETE_LISTPAGE 0x80
  166. /*
  167. * The WAL record for deleting list pages must contain a block reference to
  168. * all the deleted pages, so the number of pages that can be deleted in one
  169. * record is limited by XLR_MAX_BLOCK_ID. (block_id 0 is used for the
  170. * metapage.)
  171. */
  172. #define GIN_NDELETE_AT_ONCE Min(16, XLR_MAX_BLOCK_ID - 1)
  173. typedef struct ginxlogDeleteListPages
  174. {
  175. GinMetaPageData metadata;
  176. int32 ndeleted;
  177. } ginxlogDeleteListPages;
  178. extern void gin_redo(XLogReaderState *record);
  179. extern void gin_desc(StringInfo buf, XLogReaderState *record);
  180. extern const char *gin_identify(uint8 info);
  181. extern void gin_xlog_startup(void);
  182. extern void gin_xlog_cleanup(void);
  183. extern void gin_mask(char *pagedata, BlockNumber blkno);
  184. #endif /* GINXLOG_H */