| 1 | /*------------------------------------------------------------------------- |
| 2 | * |
| 3 | * hash_xlog.h |
| 4 | * header file for Postgres hash AM implementation |
| 5 | * |
| 6 | * |
| 7 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
| 8 | * Portions Copyright (c) 1994, Regents of the University of California |
| 9 | * |
| 10 | * src/include/access/hash_xlog.h |
| 11 | * |
| 12 | *------------------------------------------------------------------------- |
| 13 | */ |
| 14 | #ifndef HASH_XLOG_H |
| 15 | #define HASH_XLOG_H |
| 16 | |
| 17 | #include "access/xlogreader.h" |
| 18 | #include "lib/stringinfo.h" |
| 19 | #include "storage/off.h" |
| 20 | |
| 21 | /* Number of buffers required for XLOG_HASH_SQUEEZE_PAGE operation */ |
| 22 | #define HASH_XLOG_FREE_OVFL_BUFS 6 |
| 23 | |
| 24 | /* |
| 25 | * XLOG records for hash operations |
| 26 | */ |
| 27 | #define XLOG_HASH_INIT_META_PAGE 0x00 /* initialize the meta page */ |
| 28 | #define XLOG_HASH_INIT_BITMAP_PAGE 0x10 /* initialize the bitmap page */ |
| 29 | #define XLOG_HASH_INSERT 0x20 /* add index tuple without split */ |
| 30 | #define XLOG_HASH_ADD_OVFL_PAGE 0x30 /* add overflow page */ |
| 31 | #define XLOG_HASH_SPLIT_ALLOCATE_PAGE 0x40 /* allocate new page for split */ |
| 32 | #define XLOG_HASH_SPLIT_PAGE 0x50 /* split page */ |
| 33 | #define XLOG_HASH_SPLIT_COMPLETE 0x60 /* completion of split operation */ |
| 34 | #define XLOG_HASH_MOVE_PAGE_CONTENTS 0x70 /* remove tuples from one page |
| 35 | * and add to another page */ |
| 36 | #define XLOG_HASH_SQUEEZE_PAGE 0x80 /* add tuples to one of the previous |
| 37 | * pages in chain and free the ovfl |
| 38 | * page */ |
| 39 | #define XLOG_HASH_DELETE 0x90 /* delete index tuples from a page */ |
| 40 | #define XLOG_HASH_SPLIT_CLEANUP 0xA0 /* clear split-cleanup flag in primary |
| 41 | * bucket page after deleting tuples |
| 42 | * that are moved due to split */ |
| 43 | #define XLOG_HASH_UPDATE_META_PAGE 0xB0 /* update meta page after vacuum */ |
| 44 | |
| 45 | #define XLOG_HASH_VACUUM_ONE_PAGE 0xC0 /* remove dead tuples from index |
| 46 | * page */ |
| 47 | |
| 48 | /* |
| 49 | * xl_hash_split_allocate_page flag values, 8 bits are available. |
| 50 | */ |
| 51 | #define XLH_SPLIT_META_UPDATE_MASKS (1<<0) |
| 52 | #define XLH_SPLIT_META_UPDATE_SPLITPOINT (1<<1) |
| 53 | |
| 54 | /* |
| 55 | * This is what we need to know about a HASH index create. |
| 56 | * |
| 57 | * Backup block 0: metapage |
| 58 | */ |
| 59 | typedef struct xl_hash_createidx |
| 60 | { |
| 61 | double num_tuples; |
| 62 | RegProcedure procid; |
| 63 | uint16 ffactor; |
| 64 | } xl_hash_createidx; |
| 65 | #define SizeOfHashCreateIdx (offsetof(xl_hash_createidx, ffactor) + sizeof(uint16)) |
| 66 | |
| 67 | /* |
| 68 | * This is what we need to know about simple (without split) insert. |
| 69 | * |
| 70 | * This data record is used for XLOG_HASH_INSERT |
| 71 | * |
| 72 | * Backup Blk 0: original page (data contains the inserted tuple) |
| 73 | * Backup Blk 1: metapage (HashMetaPageData) |
| 74 | */ |
| 75 | typedef struct xl_hash_insert |
| 76 | { |
| 77 | OffsetNumber offnum; |
| 78 | } xl_hash_insert; |
| 79 | |
| 80 | #define SizeOfHashInsert (offsetof(xl_hash_insert, offnum) + sizeof(OffsetNumber)) |
| 81 | |
| 82 | /* |
| 83 | * This is what we need to know about addition of overflow page. |
| 84 | * |
| 85 | * This data record is used for XLOG_HASH_ADD_OVFL_PAGE |
| 86 | * |
| 87 | * Backup Blk 0: newly allocated overflow page |
| 88 | * Backup Blk 1: page before new overflow page in the bucket chain |
| 89 | * Backup Blk 2: bitmap page |
| 90 | * Backup Blk 3: new bitmap page |
| 91 | * Backup Blk 4: metapage |
| 92 | */ |
| 93 | typedef struct xl_hash_add_ovfl_page |
| 94 | { |
| 95 | uint16 bmsize; |
| 96 | bool bmpage_found; |
| 97 | } xl_hash_add_ovfl_page; |
| 98 | |
| 99 | #define SizeOfHashAddOvflPage \ |
| 100 | (offsetof(xl_hash_add_ovfl_page, bmpage_found) + sizeof(bool)) |
| 101 | |
| 102 | /* |
| 103 | * This is what we need to know about allocating a page for split. |
| 104 | * |
| 105 | * This data record is used for XLOG_HASH_SPLIT_ALLOCATE_PAGE |
| 106 | * |
| 107 | * Backup Blk 0: page for old bucket |
| 108 | * Backup Blk 1: page for new bucket |
| 109 | * Backup Blk 2: metapage |
| 110 | */ |
| 111 | typedef struct xl_hash_split_allocate_page |
| 112 | { |
| 113 | uint32 new_bucket; |
| 114 | uint16 old_bucket_flag; |
| 115 | uint16 new_bucket_flag; |
| 116 | uint8 flags; |
| 117 | } xl_hash_split_allocate_page; |
| 118 | |
| 119 | #define SizeOfHashSplitAllocPage \ |
| 120 | (offsetof(xl_hash_split_allocate_page, flags) + sizeof(uint8)) |
| 121 | |
| 122 | /* |
| 123 | * This is what we need to know about completing the split operation. |
| 124 | * |
| 125 | * This data record is used for XLOG_HASH_SPLIT_COMPLETE |
| 126 | * |
| 127 | * Backup Blk 0: page for old bucket |
| 128 | * Backup Blk 1: page for new bucket |
| 129 | */ |
| 130 | typedef struct xl_hash_split_complete |
| 131 | { |
| 132 | uint16 old_bucket_flag; |
| 133 | uint16 new_bucket_flag; |
| 134 | } xl_hash_split_complete; |
| 135 | |
| 136 | #define SizeOfHashSplitComplete \ |
| 137 | (offsetof(xl_hash_split_complete, new_bucket_flag) + sizeof(uint16)) |
| 138 | |
| 139 | /* |
| 140 | * This is what we need to know about move page contents required during |
| 141 | * squeeze operation. |
| 142 | * |
| 143 | * This data record is used for XLOG_HASH_MOVE_PAGE_CONTENTS |
| 144 | * |
| 145 | * Backup Blk 0: bucket page |
| 146 | * Backup Blk 1: page containing moved tuples |
| 147 | * Backup Blk 2: page from which tuples will be removed |
| 148 | */ |
| 149 | typedef struct xl_hash_move_page_contents |
| 150 | { |
| 151 | uint16 ntups; |
| 152 | bool is_prim_bucket_same_wrt; /* true if the page to which |
| 153 | * tuples are moved is same as |
| 154 | * primary bucket page */ |
| 155 | } xl_hash_move_page_contents; |
| 156 | |
| 157 | #define SizeOfHashMovePageContents \ |
| 158 | (offsetof(xl_hash_move_page_contents, is_prim_bucket_same_wrt) + sizeof(bool)) |
| 159 | |
| 160 | /* |
| 161 | * This is what we need to know about the squeeze page operation. |
| 162 | * |
| 163 | * This data record is used for XLOG_HASH_SQUEEZE_PAGE |
| 164 | * |
| 165 | * Backup Blk 0: page containing tuples moved from freed overflow page |
| 166 | * Backup Blk 1: freed overflow page |
| 167 | * Backup Blk 2: page previous to the freed overflow page |
| 168 | * Backup Blk 3: page next to the freed overflow page |
| 169 | * Backup Blk 4: bitmap page containing info of freed overflow page |
| 170 | * Backup Blk 5: meta page |
| 171 | */ |
| 172 | typedef struct xl_hash_squeeze_page |
| 173 | { |
| 174 | BlockNumber prevblkno; |
| 175 | BlockNumber nextblkno; |
| 176 | uint16 ntups; |
| 177 | bool is_prim_bucket_same_wrt; /* true if the page to which |
| 178 | * tuples are moved is same as |
| 179 | * primary bucket page */ |
| 180 | bool is_prev_bucket_same_wrt; /* true if the page to which |
| 181 | * tuples are moved is the page |
| 182 | * previous to the freed overflow |
| 183 | * page */ |
| 184 | } xl_hash_squeeze_page; |
| 185 | |
| 186 | #define SizeOfHashSqueezePage \ |
| 187 | (offsetof(xl_hash_squeeze_page, is_prev_bucket_same_wrt) + sizeof(bool)) |
| 188 | |
| 189 | /* |
| 190 | * This is what we need to know about the deletion of index tuples from a page. |
| 191 | * |
| 192 | * This data record is used for XLOG_HASH_DELETE |
| 193 | * |
| 194 | * Backup Blk 0: primary bucket page |
| 195 | * Backup Blk 1: page from which tuples are deleted |
| 196 | */ |
| 197 | typedef struct xl_hash_delete |
| 198 | { |
| 199 | bool clear_dead_marking; /* true if this operation clears |
| 200 | * LH_PAGE_HAS_DEAD_TUPLES flag */ |
| 201 | bool is_primary_bucket_page; /* true if the operation is for |
| 202 | * primary bucket page */ |
| 203 | } xl_hash_delete; |
| 204 | |
| 205 | #define SizeOfHashDelete (offsetof(xl_hash_delete, is_primary_bucket_page) + sizeof(bool)) |
| 206 | |
| 207 | /* |
| 208 | * This is what we need for metapage update operation. |
| 209 | * |
| 210 | * This data record is used for XLOG_HASH_UPDATE_META_PAGE |
| 211 | * |
| 212 | * Backup Blk 0: meta page |
| 213 | */ |
| 214 | typedef struct xl_hash_update_meta_page |
| 215 | { |
| 216 | double ntuples; |
| 217 | } xl_hash_update_meta_page; |
| 218 | |
| 219 | #define SizeOfHashUpdateMetaPage \ |
| 220 | (offsetof(xl_hash_update_meta_page, ntuples) + sizeof(double)) |
| 221 | |
| 222 | /* |
| 223 | * This is what we need to initialize metapage. |
| 224 | * |
| 225 | * This data record is used for XLOG_HASH_INIT_META_PAGE |
| 226 | * |
| 227 | * Backup Blk 0: meta page |
| 228 | */ |
| 229 | typedef struct xl_hash_init_meta_page |
| 230 | { |
| 231 | double num_tuples; |
| 232 | RegProcedure procid; |
| 233 | uint16 ffactor; |
| 234 | } xl_hash_init_meta_page; |
| 235 | |
| 236 | #define SizeOfHashInitMetaPage \ |
| 237 | (offsetof(xl_hash_init_meta_page, ffactor) + sizeof(uint16)) |
| 238 | |
| 239 | /* |
| 240 | * This is what we need to initialize bitmap page. |
| 241 | * |
| 242 | * This data record is used for XLOG_HASH_INIT_BITMAP_PAGE |
| 243 | * |
| 244 | * Backup Blk 0: bitmap page |
| 245 | * Backup Blk 1: meta page |
| 246 | */ |
| 247 | typedef struct xl_hash_init_bitmap_page |
| 248 | { |
| 249 | uint16 bmsize; |
| 250 | } xl_hash_init_bitmap_page; |
| 251 | |
| 252 | #define SizeOfHashInitBitmapPage \ |
| 253 | (offsetof(xl_hash_init_bitmap_page, bmsize) + sizeof(uint16)) |
| 254 | |
| 255 | /* |
| 256 | * This is what we need for index tuple deletion and to |
| 257 | * update the meta page. |
| 258 | * |
| 259 | * This data record is used for XLOG_HASH_VACUUM_ONE_PAGE |
| 260 | * |
| 261 | * Backup Blk 0: bucket page |
| 262 | * Backup Blk 1: meta page |
| 263 | */ |
| 264 | typedef struct xl_hash_vacuum_one_page |
| 265 | { |
| 266 | TransactionId latestRemovedXid; |
| 267 | int ntuples; |
| 268 | |
| 269 | /* TARGET OFFSET NUMBERS FOLLOW AT THE END */ |
| 270 | } xl_hash_vacuum_one_page; |
| 271 | |
| 272 | #define SizeOfHashVacuumOnePage \ |
| 273 | (offsetof(xl_hash_vacuum_one_page, ntuples) + sizeof(int)) |
| 274 | |
| 275 | extern void hash_redo(XLogReaderState *record); |
| 276 | extern void hash_desc(StringInfo buf, XLogReaderState *record); |
| 277 | extern const char *hash_identify(uint8 info); |
| 278 | extern void hash_mask(char *pagedata, BlockNumber blkno); |
| 279 | |
| 280 | #endif /* HASH_XLOG_H */ |
| 281 | |