1 /*------------------------------------------------------------------------- 2 * 3 * spgxlog.h 4 * xlog declarations for SP-GiST access method. 5 * 6 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group 7 * Portions Copyright (c) 1994, Regents of the University of California 8 * 9 * src/include/access/spgxlog.h 10 * 11 *------------------------------------------------------------------------- 12 */ 13 #ifndef SPGXLOG_H 14 #define SPGXLOG_H 15 16 #include "access/xlogreader.h" 17 #include "lib/stringinfo.h" 18 #include "storage/off.h" 19 20 /* XLOG record types for SPGiST */ 21 /* #define XLOG_SPGIST_CREATE_INDEX 0x00 */ /* not used anymore */ 22 #define XLOG_SPGIST_ADD_LEAF 0x10 23 #define XLOG_SPGIST_MOVE_LEAFS 0x20 24 #define XLOG_SPGIST_ADD_NODE 0x30 25 #define XLOG_SPGIST_SPLIT_TUPLE 0x40 26 #define XLOG_SPGIST_PICKSPLIT 0x50 27 #define XLOG_SPGIST_VACUUM_LEAF 0x60 28 #define XLOG_SPGIST_VACUUM_ROOT 0x70 29 #define XLOG_SPGIST_VACUUM_REDIRECT 0x80 30 31 /* 32 * Some redo functions need an SpGistState, although only a few of its fields 33 * need to be valid. spgxlogState carries the required info in xlog records. 34 * (See fillFakeState in spgxlog.c for more comments.) 35 */ 36 typedef struct spgxlogState 37 { 38 TransactionId myXid; 39 bool isBuild; 40 } spgxlogState; 41 42 /* 43 * Backup Blk 0: destination page for leaf tuple 44 * Backup Blk 1: parent page (if any) 45 */ 46 typedef struct spgxlogAddLeaf 47 { 48 bool newPage; /* init dest page? */ 49 bool storesNulls; /* page is in the nulls tree? */ 50 OffsetNumber offnumLeaf; /* offset where leaf tuple gets placed */ 51 OffsetNumber offnumHeadLeaf; /* offset of head tuple in chain, if any */ 52 53 OffsetNumber offnumParent; /* where the parent downlink is, if any */ 54 uint16 nodeI; 55 56 /* new leaf tuple follows (unaligned!) */ 57 } spgxlogAddLeaf; 58 59 /* 60 * Backup Blk 0: source leaf page 61 * Backup Blk 1: destination leaf page 62 * Backup Blk 2: parent page 63 */ 64 typedef struct spgxlogMoveLeafs 65 { 66 uint16 nMoves; /* number of tuples moved from source page */ 67 bool newPage; /* init dest page? */ 68 bool replaceDead; /* are we replacing a DEAD source tuple? */ 69 bool storesNulls; /* pages are in the nulls tree? */ 70 71 /* where the parent downlink is */ 72 OffsetNumber offnumParent; 73 uint16 nodeI; 74 75 spgxlogState stateSrc; 76 77 /*---------- 78 * data follows: 79 * array of deleted tuple numbers, length nMoves 80 * array of inserted tuple numbers, length nMoves + 1 or 1 81 * list of leaf tuples, length nMoves + 1 or 1 (unaligned!) 82 * 83 * Note: if replaceDead is true then there is only one inserted tuple 84 * number and only one leaf tuple in the data, because we are not copying 85 * the dead tuple from the source 86 *---------- 87 */ 88 OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; 89 } spgxlogMoveLeafs; 90 91 #define SizeOfSpgxlogMoveLeafs offsetof(spgxlogMoveLeafs, offsets) 92 93 /* 94 * Backup Blk 0: original page 95 * Backup Blk 1: where new tuple goes, if not same place 96 * Backup Blk 2: where parent downlink is, if updated and different from 97 * the old and new 98 */ 99 typedef struct spgxlogAddNode 100 { 101 /* 102 * Offset of the original inner tuple, in the original page (on backup 103 * block 0). 104 */ 105 OffsetNumber offnum; 106 107 /* 108 * Offset of the new tuple, on the new page (on backup block 1). Invalid, 109 * if we overwrote the old tuple in the original page). 110 */ 111 OffsetNumber offnumNew; 112 bool newPage; /* init new page? */ 113 114 /*---- 115 * Where is the parent downlink? parentBlk indicates which page it's on, 116 * and offnumParent is the offset within the page. The possible values for 117 * parentBlk are: 118 * 119 * 0: parent == original page 120 * 1: parent == new page 121 * 2: parent == different page (blk ref 2) 122 * -1: parent not updated 123 *---- 124 */ 125 int8 parentBlk; 126 OffsetNumber offnumParent; /* offset within the parent page */ 127 128 uint16 nodeI; 129 130 spgxlogState stateSrc; 131 132 /* 133 * updated inner tuple follows (unaligned!) 134 */ 135 } spgxlogAddNode; 136 137 /* 138 * Backup Blk 0: where the prefix tuple goes 139 * Backup Blk 1: where the postfix tuple goes (if different page) 140 */ 141 typedef struct spgxlogSplitTuple 142 { 143 /* where the prefix tuple goes */ 144 OffsetNumber offnumPrefix; 145 146 /* where the postfix tuple goes */ 147 OffsetNumber offnumPostfix; 148 bool newPage; /* need to init that page? */ 149 bool postfixBlkSame; /* was postfix tuple put on same page as 150 * prefix? */ 151 152 /* 153 * new prefix inner tuple follows, then new postfix inner tuple (both are 154 * unaligned!) 155 */ 156 } spgxlogSplitTuple; 157 158 /* 159 * Buffer references in the rdata array are: 160 * Backup Blk 0: Src page (only if not root) 161 * Backup Blk 1: Dest page (if used) 162 * Backup Blk 2: Inner page 163 * Backup Blk 3: Parent page (if any, and different from Inner) 164 */ 165 typedef struct spgxlogPickSplit 166 { 167 bool isRootSplit; 168 169 uint16 nDelete; /* n to delete from Src */ 170 uint16 nInsert; /* n to insert on Src and/or Dest */ 171 bool initSrc; /* re-init the Src page? */ 172 bool initDest; /* re-init the Dest page? */ 173 174 /* where to put new inner tuple */ 175 OffsetNumber offnumInner; 176 bool initInner; /* re-init the Inner page? */ 177 178 bool storesNulls; /* pages are in the nulls tree? */ 179 180 /* where the parent downlink is, if any */ 181 bool innerIsParent; /* is parent the same as inner page? */ 182 OffsetNumber offnumParent; 183 uint16 nodeI; 184 185 spgxlogState stateSrc; 186 187 /*---------- 188 * data follows: 189 * array of deleted tuple numbers, length nDelete 190 * array of inserted tuple numbers, length nInsert 191 * array of page selector bytes for inserted tuples, length nInsert 192 * new inner tuple (unaligned!) 193 * list of leaf tuples, length nInsert (unaligned!) 194 *---------- 195 */ 196 OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; 197 } spgxlogPickSplit; 198 199 #define SizeOfSpgxlogPickSplit offsetof(spgxlogPickSplit, offsets) 200 201 typedef struct spgxlogVacuumLeaf 202 { 203 uint16 nDead; /* number of tuples to become DEAD */ 204 uint16 nPlaceholder; /* number of tuples to become PLACEHOLDER */ 205 uint16 nMove; /* number of tuples to move */ 206 uint16 nChain; /* number of tuples to re-chain */ 207 208 spgxlogState stateSrc; 209 210 /*---------- 211 * data follows: 212 * tuple numbers to become DEAD 213 * tuple numbers to become PLACEHOLDER 214 * tuple numbers to move from (and replace with PLACEHOLDER) 215 * tuple numbers to move to (replacing what is there) 216 * tuple numbers to update nextOffset links of 217 * tuple numbers to insert in nextOffset links 218 *---------- 219 */ 220 OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; 221 } spgxlogVacuumLeaf; 222 223 #define SizeOfSpgxlogVacuumLeaf offsetof(spgxlogVacuumLeaf, offsets) 224 225 typedef struct spgxlogVacuumRoot 226 { 227 /* vacuum a root page when it is also a leaf */ 228 uint16 nDelete; /* number of tuples to delete */ 229 230 spgxlogState stateSrc; 231 232 /* offsets of tuples to delete follow */ 233 OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; 234 } spgxlogVacuumRoot; 235 236 #define SizeOfSpgxlogVacuumRoot offsetof(spgxlogVacuumRoot, offsets) 237 238 typedef struct spgxlogVacuumRedirect 239 { 240 uint16 nToPlaceholder; /* number of redirects to make placeholders */ 241 OffsetNumber firstPlaceholder; /* first placeholder tuple to remove */ 242 TransactionId newestRedirectXid; /* newest XID of removed redirects */ 243 244 /* offsets of redirect tuples to make placeholders follow */ 245 OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; 246 } spgxlogVacuumRedirect; 247 248 #define SizeOfSpgxlogVacuumRedirect offsetof(spgxlogVacuumRedirect, offsets) 249 250 extern void spg_redo(XLogReaderState *record); 251 extern void spg_desc(StringInfo buf, XLogReaderState *record); 252 extern const char *spg_identify(uint8 info); 253 extern void spg_xlog_startup(void); 254 extern void spg_xlog_cleanup(void); 255 extern void spg_mask(char *pagedata, BlockNumber blkno); 256 257 #endif /* SPGXLOG_H */ 258