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 | |