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