PostgreSQL Source Code git master
Loading...
Searching...
No Matches
gistxlog.c File Reference
#include "postgres.h"
#include "access/bufmask.h"
#include "access/gist_private.h"
#include "access/gistxlog.h"
#include "access/transam.h"
#include "access/xloginsert.h"
#include "access/xlogutils.h"
#include "storage/standby.h"
#include "utils/memutils.h"
#include "utils/rel.h"
Include dependency graph for gistxlog.c:

Go to the source code of this file.

Functions

static void gistRedoClearFollowRight (XLogReaderState *record, uint8 block_id)
 
static void gistRedoPageUpdateRecord (XLogReaderState *record)
 
static void gistRedoDeleteRecord (XLogReaderState *record)
 
static IndexTupledecodePageSplitRecord (char *begin, int len, int *n)
 
static void gistRedoPageSplitRecord (XLogReaderState *record)
 
static void gistRedoPageDelete (XLogReaderState *record)
 
static void gistRedoPageReuse (XLogReaderState *record)
 
void gist_redo (XLogReaderState *record)
 
void gist_xlog_startup (void)
 
void gist_xlog_cleanup (void)
 
void gist_mask (char *pagedata, BlockNumber blkno)
 
XLogRecPtr gistXLogSplit (bool page_is_leaf, SplitPageLayout *dist, BlockNumber origrlink, GistNSN orignsn, Buffer leftchildbuf, bool markfollowright)
 
XLogRecPtr gistXLogPageDelete (Buffer buffer, FullTransactionId xid, Buffer parentBuffer, OffsetNumber downlinkOffset)
 
XLogRecPtr gistXLogAssignLSN (void)
 
void gistXLogPageReuse (Relation rel, Relation heaprel, BlockNumber blkno, FullTransactionId deleteXid)
 
XLogRecPtr gistXLogUpdate (Buffer buffer, OffsetNumber *todelete, int ntodelete, IndexTuple *itup, int ituplen, Buffer leftchildbuf)
 
XLogRecPtr gistXLogDelete (Buffer buffer, OffsetNumber *todelete, int ntodelete, TransactionId snapshotConflictHorizon, Relation heaprel)
 

Variables

static MemoryContext opCtx
 

Function Documentation

◆ decodePageSplitRecord()

static IndexTuple * decodePageSplitRecord ( char begin,
int  len,
int n 
)
static

Definition at line 221 of file gistxlog.c.

222{
223 char *ptr;
224 int i = 0;
225 IndexTuple *tuples;
226
227 /* extract the number of tuples */
228 memcpy(n, begin, sizeof(int));
229 ptr = begin + sizeof(int);
230
231 tuples = palloc(*n * sizeof(IndexTuple));
232
233 for (i = 0; i < *n; i++)
234 {
235 Assert(ptr - begin < len);
236 tuples[i] = (IndexTuple) ptr;
237 ptr += IndexTupleSize((IndexTuple) ptr);
238 }
239 Assert(ptr - begin == len);
240
241 return tuples;
242}
#define Assert(condition)
Definition c.h:873
int i
Definition isn.c:77
IndexTupleData * IndexTuple
Definition itup.h:53
static Size IndexTupleSize(const IndexTupleData *itup)
Definition itup.h:71
void * palloc(Size size)
Definition mcxt.c:1387
const void size_t len
static int fb(int x)

References Assert, fb(), i, IndexTupleSize(), len, and palloc().

Referenced by gistRedoPageSplitRecord().

◆ gist_mask()

void gist_mask ( char pagedata,
BlockNumber  blkno 
)

Definition at line 451 of file gistxlog.c.

452{
453 Page page = (Page) pagedata;
454
456
458 mask_unused_space(page);
459
460 /*
461 * NSN is nothing but a special purpose LSN. Hence, mask it for the same
462 * reason as mask_page_lsn_and_checksum.
463 */
465
466 /*
467 * We update F_FOLLOW_RIGHT flag on the left child after writing WAL
468 * record. Hence, mask this flag. See gistplacetopage() for details.
469 */
471
472 if (GistPageIsLeaf(page))
473 {
474 /*
475 * In gist leaf pages, it is possible to modify the LP_FLAGS without
476 * emitting any WAL record. Hence, mask the line pointer flags. See
477 * gistkillitems() for details.
478 */
479 mask_lp_flags(page);
480 }
481
482 /*
483 * During gist redo, we never mark a page as garbage. Hence, mask it to
484 * ignore any differences.
485 */
487}
void mask_lp_flags(Page page)
Definition bufmask.c:95
void mask_page_lsn_and_checksum(Page page)
Definition bufmask.c:31
void mask_unused_space(Page page)
Definition bufmask.c:71
void mask_page_hint_bits(Page page)
Definition bufmask.c:46
#define MASK_MARKER
Definition bufmask.h:24
PageData * Page
Definition bufpage.h:81
uint64_t uint64
Definition c.h:547
#define GistMarkFollowRight(page)
Definition gist.h:184
#define GistClearPageHasGarbage(page)
Definition gist.h:181
#define GistPageIsLeaf(page)
Definition gist.h:170
#define GistPageSetNSN(page, val)
Definition gist.h:188

References fb(), GistClearPageHasGarbage, GistMarkFollowRight, GistPageIsLeaf, GistPageSetNSN, mask_lp_flags(), MASK_MARKER, mask_page_hint_bits(), mask_page_lsn_and_checksum(), and mask_unused_space().

◆ gist_redo()

void gist_redo ( XLogReaderState record)

Definition at line 395 of file gistxlog.c.

396{
397 uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
399
400 /*
401 * GiST indexes do not require any conflict processing. NB: If we ever
402 * implement a similar optimization we have in b-tree, and remove killed
403 * tuples outside VACUUM, we'll need to handle that here.
404 */
405
407 switch (info)
408 {
411 break;
412 case XLOG_GIST_DELETE:
413 gistRedoDeleteRecord(record);
414 break;
416 gistRedoPageReuse(record);
417 break;
420 break;
422 gistRedoPageDelete(record);
423 break;
425 /* nop. See gistGetFakeLSN(). */
426 break;
427 default:
428 elog(PANIC, "gist_redo: unknown op code %u", info);
429 }
430
433}
uint8_t uint8
Definition c.h:544
#define PANIC
Definition elog.h:42
#define elog(elevel,...)
Definition elog.h:226
static void gistRedoPageReuse(XLogReaderState *record)
Definition gistxlog.c:374
static void gistRedoPageUpdateRecord(XLogReaderState *record)
Definition gistxlog.c:70
static void gistRedoPageSplitRecord(XLogReaderState *record)
Definition gistxlog.c:245
static void gistRedoPageDelete(XLogReaderState *record)
Definition gistxlog.c:340
static void gistRedoDeleteRecord(XLogReaderState *record)
Definition gistxlog.c:170
static MemoryContext opCtx
Definition gistxlog.c:26
#define XLOG_GIST_ASSIGN_LSN
Definition gistxlog.h:27
#define XLOG_GIST_PAGE_REUSE
Definition gistxlog.h:22
#define XLOG_GIST_PAGE_DELETE
Definition gistxlog.h:26
#define XLOG_GIST_DELETE
Definition gistxlog.h:21
#define XLOG_GIST_PAGE_SPLIT
Definition gistxlog.h:23
#define XLOG_GIST_PAGE_UPDATE
Definition gistxlog.h:20
void MemoryContextReset(MemoryContext context)
Definition mcxt.c:403
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
#define XLogRecGetInfo(decoder)
Definition xlogreader.h:409

References elog, fb(), gistRedoDeleteRecord(), gistRedoPageDelete(), gistRedoPageReuse(), gistRedoPageSplitRecord(), gistRedoPageUpdateRecord(), MemoryContextReset(), MemoryContextSwitchTo(), opCtx, PANIC, XLOG_GIST_ASSIGN_LSN, XLOG_GIST_DELETE, XLOG_GIST_PAGE_DELETE, XLOG_GIST_PAGE_REUSE, XLOG_GIST_PAGE_SPLIT, XLOG_GIST_PAGE_UPDATE, and XLogRecGetInfo.

◆ gist_xlog_cleanup()

void gist_xlog_cleanup ( void  )

Definition at line 442 of file gistxlog.c.

443{
445}
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:472

References MemoryContextDelete(), and opCtx.

◆ gist_xlog_startup()

void gist_xlog_startup ( void  )

Definition at line 436 of file gistxlog.c.

437{
439}
MemoryContext createTempGistContext(void)
Definition gist.c:129

References createTempGistContext(), and opCtx.

◆ gistRedoClearFollowRight()

static void gistRedoClearFollowRight ( XLogReaderState record,
uint8  block_id 
)
static

Definition at line 40 of file gistxlog.c.

41{
42 XLogRecPtr lsn = record->EndRecPtr;
43 Buffer buffer;
44 Page page;
46
47 /*
48 * Note that we still update the page even if it was restored from a full
49 * page image, because the updated NSN is not included in the image.
50 */
51 action = XLogReadBufferForRedo(record, block_id, &buffer);
52 if (action == BLK_NEEDS_REDO || action == BLK_RESTORED)
53 {
54 page = BufferGetPage(buffer);
55
56 GistPageSetNSN(page, lsn);
58
59 PageSetLSN(page, lsn);
60 MarkBufferDirty(buffer);
61 }
62 if (BufferIsValid(buffer))
63 UnlockReleaseBuffer(buffer);
64}
int Buffer
Definition buf.h:23
void UnlockReleaseBuffer(Buffer buffer)
Definition bufmgr.c:5518
void MarkBufferDirty(Buffer buffer)
Definition bufmgr.c:3056
static Page BufferGetPage(Buffer buffer)
Definition bufmgr.h:466
static bool BufferIsValid(Buffer bufnum)
Definition bufmgr.h:417
static void PageSetLSN(Page page, XLogRecPtr lsn)
Definition bufpage.h:390
#define GistClearFollowRight(page)
Definition gist.h:185
XLogRecPtr EndRecPtr
Definition xlogreader.h:206
uint64 XLogRecPtr
Definition xlogdefs.h:21
XLogRedoAction XLogReadBufferForRedo(XLogReaderState *record, uint8 block_id, Buffer *buf)
Definition xlogutils.c:303
XLogRedoAction
Definition xlogutils.h:73
@ BLK_RESTORED
Definition xlogutils.h:76
@ BLK_NEEDS_REDO
Definition xlogutils.h:74

References BLK_NEEDS_REDO, BLK_RESTORED, BufferGetPage(), BufferIsValid(), XLogReaderState::EndRecPtr, fb(), GistClearFollowRight, GistPageSetNSN, MarkBufferDirty(), PageSetLSN(), UnlockReleaseBuffer(), and XLogReadBufferForRedo().

Referenced by gistRedoPageSplitRecord(), and gistRedoPageUpdateRecord().

◆ gistRedoDeleteRecord()

static void gistRedoDeleteRecord ( XLogReaderState record)
static

Definition at line 170 of file gistxlog.c.

171{
172 XLogRecPtr lsn = record->EndRecPtr;
174 Buffer buffer;
175 Page page;
177
178 /*
179 * If we have any conflict processing to do, it must happen before we
180 * update the page.
181 *
182 * GiST delete records can conflict with standby queries. You might think
183 * that vacuum records would conflict as well, but we've handled that
184 * already. XLOG_HEAP2_PRUNE_VACUUM_SCAN records provide the highest xid
185 * cleaned by the vacuum of the heap and so we can resolve any conflicts
186 * just once when that arrives. After that we know that no conflicts
187 * exist from individual gist vacuum records on that index.
188 */
189 if (InHotStandby)
190 {
191 RelFileLocator rlocator;
192
193 XLogRecGetBlockTag(record, 0, &rlocator, NULL, NULL);
194
195 ResolveRecoveryConflictWithSnapshot(xldata->snapshotConflictHorizon,
196 xldata->isCatalogRel,
197 rlocator);
198 }
199
200 if (XLogReadBufferForRedo(record, 0, &buffer) == BLK_NEEDS_REDO)
201 {
202 page = BufferGetPage(buffer);
203
204 PageIndexMultiDelete(page, toDelete, xldata->ntodelete);
205
208
209 PageSetLSN(page, lsn);
210 MarkBufferDirty(buffer);
211 }
212
213 if (BufferIsValid(buffer))
214 UnlockReleaseBuffer(buffer);
215}
void PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
Definition bufpage.c:1160
#define GistMarkTuplesDeleted(page)
Definition gist.h:176
uint16 OffsetNumber
Definition off.h:24
void ResolveRecoveryConflictWithSnapshot(TransactionId snapshotConflictHorizon, bool isCatalogRel, RelFileLocator locator)
Definition standby.c:468
OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]
Definition gistxlog.h:56
void XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id, RelFileLocator *rlocator, ForkNumber *forknum, BlockNumber *blknum)
#define XLogRecGetData(decoder)
Definition xlogreader.h:414
#define InHotStandby
Definition xlogutils.h:60

References BLK_NEEDS_REDO, BufferGetPage(), BufferIsValid(), XLogReaderState::EndRecPtr, fb(), GistClearPageHasGarbage, GistMarkTuplesDeleted, InHotStandby, MarkBufferDirty(), gistxlogDelete::offsets, PageIndexMultiDelete(), PageSetLSN(), ResolveRecoveryConflictWithSnapshot(), UnlockReleaseBuffer(), XLogReadBufferForRedo(), XLogRecGetBlockTag(), and XLogRecGetData.

Referenced by gist_redo().

◆ gistRedoPageDelete()

static void gistRedoPageDelete ( XLogReaderState record)
static

Definition at line 340 of file gistxlog.c.

341{
342 XLogRecPtr lsn = record->EndRecPtr;
346
348 {
350
351 GistPageSetDeleted(page, xldata->deleteXid);
352
353 PageSetLSN(page, lsn);
355 }
356
358 {
360
361 PageIndexTupleDelete(page, xldata->downlinkOffset);
362
363 PageSetLSN(page, lsn);
365 }
366
371}
void PageIndexTupleDelete(Page page, OffsetNumber offnum)
Definition bufpage.c:1051
static void GistPageSetDeleted(Page page, FullTransactionId deletexid)
Definition gist.h:205

References BLK_NEEDS_REDO, BufferGetPage(), BufferIsValid(), XLogReaderState::EndRecPtr, fb(), GistPageSetDeleted(), MarkBufferDirty(), PageIndexTupleDelete(), PageSetLSN(), UnlockReleaseBuffer(), XLogReadBufferForRedo(), and XLogRecGetData.

Referenced by gist_redo().

◆ gistRedoPageReuse()

static void gistRedoPageReuse ( XLogReaderState record)
static

Definition at line 374 of file gistxlog.c.

375{
377
378 /*
379 * PAGE_REUSE records exist to provide a conflict point when we reuse
380 * pages in the index via the FSM. That's all they do though.
381 *
382 * snapshotConflictHorizon was the page's deleteXid. The
383 * GlobalVisCheckRemovableFullXid(deleteXid) test in gistPageRecyclable()
384 * conceptually mirrors the PGPROC->xmin > limitXmin test in
385 * GetConflictingVirtualXIDs(). Consequently, one XID value achieves the
386 * same exclusion effect on primary and standby.
387 */
388 if (InHotStandby)
389 ResolveRecoveryConflictWithSnapshotFullXid(xlrec->snapshotConflictHorizon,
390 xlrec->isCatalogRel,
391 xlrec->locator);
392}
void ResolveRecoveryConflictWithSnapshotFullXid(FullTransactionId snapshotConflictHorizon, bool isCatalogRel, RelFileLocator locator)
Definition standby.c:512

References fb(), InHotStandby, ResolveRecoveryConflictWithSnapshotFullXid(), and XLogRecGetData.

Referenced by gist_redo().

◆ gistRedoPageSplitRecord()

static void gistRedoPageSplitRecord ( XLogReaderState record)
static

Definition at line 245 of file gistxlog.c.

246{
247 XLogRecPtr lsn = record->EndRecPtr;
250 Buffer buffer;
251 Page page;
252 int i;
253 bool isrootsplit = false;
254
255 /*
256 * We must hold lock on the first-listed page throughout the action,
257 * including while updating the left child page (if any). We can unlock
258 * remaining pages in the list as soon as they've been written, because
259 * there is no path for concurrent queries to reach those pages without
260 * first visiting the first-listed page.
261 */
262
263 /* loop around all pages */
264 for (i = 0; i < xldata->npage; i++)
265 {
266 int flags;
267 char *data;
268 Size datalen;
269 int num;
270 BlockNumber blkno;
271 IndexTuple *tuples;
272
273 XLogRecGetBlockTag(record, i + 1, NULL, NULL, &blkno);
274 if (blkno == GIST_ROOT_BLKNO)
275 {
276 Assert(i == 0);
277 isrootsplit = true;
278 }
279
280 buffer = XLogInitBufferForRedo(record, i + 1);
281 page = BufferGetPage(buffer);
282 data = XLogRecGetBlockData(record, i + 1, &datalen);
283
284 tuples = decodePageSplitRecord(data, datalen, &num);
285
286 /* ok, clear buffer */
287 if (xldata->origleaf && blkno != GIST_ROOT_BLKNO)
288 flags = F_LEAF;
289 else
290 flags = 0;
291 GISTInitBuffer(buffer, flags);
292
293 /* and fill it */
294 gistfillbuffer(page, tuples, num, FirstOffsetNumber);
295
296 if (blkno == GIST_ROOT_BLKNO)
297 {
298 GistPageGetOpaque(page)->rightlink = InvalidBlockNumber;
299 GistPageSetNSN(page, xldata->orignsn);
301 }
302 else
303 {
304 if (i < xldata->npage - 1)
305 {
306 BlockNumber nextblkno;
307
308 XLogRecGetBlockTag(record, i + 2, NULL, NULL, &nextblkno);
309 GistPageGetOpaque(page)->rightlink = nextblkno;
310 }
311 else
312 GistPageGetOpaque(page)->rightlink = xldata->origrlink;
313 GistPageSetNSN(page, xldata->orignsn);
314 if (i < xldata->npage - 1 && !isrootsplit &&
315 xldata->markfollowright)
317 else
319 }
320
321 PageSetLSN(page, lsn);
322 MarkBufferDirty(buffer);
323
324 if (i == 0)
325 firstbuffer = buffer;
326 else
327 UnlockReleaseBuffer(buffer);
328 }
329
330 /* Fix follow-right data on left child page, if any */
331 if (XLogRecHasBlockRef(record, 0))
332 gistRedoClearFollowRight(record, 0);
333
334 /* Finally, release lock on the first page */
336}
uint32 BlockNumber
Definition block.h:31
#define InvalidBlockNumber
Definition block.h:33
#define InvalidBuffer
Definition buf.h:25
size_t Size
Definition c.h:619
#define F_LEAF
Definition gist.h:49
#define GistPageGetOpaque(page)
Definition gist.h:168
#define GIST_ROOT_BLKNO
void gistfillbuffer(Page page, IndexTuple *itup, int len, OffsetNumber off)
Definition gistutil.c:34
void GISTInitBuffer(Buffer b, uint32 f)
Definition gistutil.c:773
static IndexTuple * decodePageSplitRecord(char *begin, int len, int *n)
Definition gistxlog.c:221
static void gistRedoClearFollowRight(XLogReaderState *record, uint8 block_id)
Definition gistxlog.c:40
#define FirstOffsetNumber
Definition off.h:27
const void * data
char * XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len)
#define XLogRecHasBlockRef(decoder, block_id)
Definition xlogreader.h:419
Buffer XLogInitBufferForRedo(XLogReaderState *record, uint8 block_id)
Definition xlogutils.c:315

References Assert, BufferGetPage(), data, decodePageSplitRecord(), XLogReaderState::EndRecPtr, F_LEAF, fb(), FirstOffsetNumber, GIST_ROOT_BLKNO, GistClearFollowRight, gistfillbuffer(), GISTInitBuffer(), GistMarkFollowRight, GistPageGetOpaque, GistPageSetNSN, gistRedoClearFollowRight(), i, InvalidBlockNumber, InvalidBuffer, MarkBufferDirty(), PageSetLSN(), UnlockReleaseBuffer(), XLogInitBufferForRedo(), XLogRecGetBlockData(), XLogRecGetBlockTag(), XLogRecGetData, and XLogRecHasBlockRef.

Referenced by gist_redo().

◆ gistRedoPageUpdateRecord()

static void gistRedoPageUpdateRecord ( XLogReaderState record)
static

Definition at line 70 of file gistxlog.c.

71{
72 XLogRecPtr lsn = record->EndRecPtr;
74 Buffer buffer;
75 Page page;
76
77 if (XLogReadBufferForRedo(record, 0, &buffer) == BLK_NEEDS_REDO)
78 {
79 char *begin;
80 char *data;
81 Size datalen;
83
84 data = begin = XLogRecGetBlockData(record, 0, &datalen);
85
86 page = BufferGetPage(buffer);
87
88 if (xldata->ntodelete == 1 && xldata->ntoinsert == 1)
89 {
90 /*
91 * When replacing one tuple with one other tuple, we must use
92 * PageIndexTupleOverwrite for consistency with gistplacetopage.
93 */
94 OffsetNumber offnum = *((OffsetNumber *) data);
95 IndexTuple itup;
97
98 data += sizeof(OffsetNumber);
99 itup = (IndexTuple) data;
100 itupsize = IndexTupleSize(itup);
101 if (!PageIndexTupleOverwrite(page, offnum, itup, itupsize))
102 elog(ERROR, "failed to add item to GiST index page, size %zu bytes", itupsize);
103 data += itupsize;
104 /* should be nothing left after consuming 1 tuple */
105 Assert(data - begin == datalen);
106 /* update insertion count for assert check below */
107 ninserted++;
108 }
109 else if (xldata->ntodelete > 0)
110 {
111 /* Otherwise, delete old tuples if any */
113
114 data += sizeof(OffsetNumber) * xldata->ntodelete;
115
116 PageIndexMultiDelete(page, todelete, xldata->ntodelete);
117 if (GistPageIsLeaf(page))
119 }
120
121 /* Add new tuples if any */
122 if (data - begin < datalen)
123 {
126
127 while (data - begin < datalen)
128 {
129 IndexTuple itup = (IndexTuple) data;
130 Size sz = IndexTupleSize(itup);
131 OffsetNumber l;
132
133 data += sz;
134
135 l = PageAddItem(page, itup, sz, off, false, false);
136 if (l == InvalidOffsetNumber)
137 elog(ERROR, "failed to add item to GiST index page, size %zu bytes", sz);
138 off++;
139 ninserted++;
140 }
141 }
142
143 /* Check that XLOG record contained expected number of tuples */
144 Assert(ninserted == xldata->ntoinsert);
145
146 PageSetLSN(page, lsn);
147 MarkBufferDirty(buffer);
148 }
149
150 /*
151 * Fix follow-right data on left child page
152 *
153 * This must be done while still holding the lock on the target page. Note
154 * that even if the target page no longer exists, we still attempt to
155 * replay the change on the child page.
156 */
157 if (XLogRecHasBlockRef(record, 1))
158 gistRedoClearFollowRight(record, 1);
159
160 if (BufferIsValid(buffer))
161 UnlockReleaseBuffer(buffer);
162}
bool PageIndexTupleOverwrite(Page page, OffsetNumber offnum, const void *newtup, Size newsize)
Definition bufpage.c:1404
static bool PageIsEmpty(const PageData *page)
Definition bufpage.h:223
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
Definition bufpage.h:471
static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)
Definition bufpage.h:371
#define PG_USED_FOR_ASSERTS_ONLY
Definition c.h:223
#define ERROR
Definition elog.h:39
#define InvalidOffsetNumber
Definition off.h:26
#define OffsetNumberNext(offsetNumber)
Definition off.h:52

References Assert, BLK_NEEDS_REDO, BufferGetPage(), BufferIsValid(), data, elog, XLogReaderState::EndRecPtr, ERROR, fb(), FirstOffsetNumber, GistMarkTuplesDeleted, GistPageIsLeaf, gistRedoClearFollowRight(), IndexTupleSize(), InvalidOffsetNumber, MarkBufferDirty(), OffsetNumberNext, PageAddItem, PageGetMaxOffsetNumber(), PageIndexMultiDelete(), PageIndexTupleOverwrite(), PageIsEmpty(), PageSetLSN(), PG_USED_FOR_ASSERTS_ONLY, UnlockReleaseBuffer(), XLogReadBufferForRedo(), XLogRecGetBlockData(), XLogRecGetData, and XLogRecHasBlockRef.

Referenced by gist_redo().

◆ gistXLogAssignLSN()

XLogRecPtr gistXLogAssignLSN ( void  )

Definition at line 574 of file gistxlog.c.

575{
576 int dummy = 0;
577
578 /*
579 * Records other than XLOG_SWITCH must have content. We use an integer 0
580 * to follow the restriction.
581 */
584 XLogRegisterData(&dummy, sizeof(dummy));
586}
#define XLOG_MARK_UNIMPORTANT
Definition xlog.h:166
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition xloginsert.c:478
void XLogRegisterData(const void *data, uint32 len)
Definition xloginsert.c:368
void XLogSetRecordFlags(uint8 flags)
Definition xloginsert.c:460
void XLogBeginInsert(void)
Definition xloginsert.c:152

References fb(), XLOG_GIST_ASSIGN_LSN, XLOG_MARK_UNIMPORTANT, XLogBeginInsert(), XLogInsert(), XLogRegisterData(), and XLogSetRecordFlags().

Referenced by gistGetFakeLSN().

◆ gistXLogDelete()

XLogRecPtr gistXLogDelete ( Buffer  buffer,
OffsetNumber todelete,
int  ntodelete,
TransactionId  snapshotConflictHorizon,
Relation  heaprel 
)

Definition at line 668 of file gistxlog.c.

670{
673
675 xlrec.snapshotConflictHorizon = snapshotConflictHorizon;
676 xlrec.ntodelete = ntodelete;
677
680
681 /*
682 * We need the target-offsets array whether or not we store the whole
683 * buffer, to allow us to find the snapshotConflictHorizon on a standby
684 * server.
685 */
686 XLogRegisterData(todelete, ntodelete * sizeof(OffsetNumber));
687
689
691
692 return recptr;
693}
#define SizeOfGistxlogDelete
Definition gistxlog.h:59
#define RelationIsAccessibleInLogicalDecoding(relation)
Definition rel.h:693
bool isCatalogRel
Definition gistxlog.h:52
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
Definition xloginsert.c:245
#define REGBUF_STANDARD
Definition xloginsert.h:35

References fb(), gistxlogDelete::isCatalogRel, REGBUF_STANDARD, RelationIsAccessibleInLogicalDecoding, SizeOfGistxlogDelete, XLOG_GIST_DELETE, XLogBeginInsert(), XLogInsert(), XLogRegisterBuffer(), and XLogRegisterData().

Referenced by gistprunepage().

◆ gistXLogPageDelete()

XLogRecPtr gistXLogPageDelete ( Buffer  buffer,
FullTransactionId  xid,
Buffer  parentBuffer,
OffsetNumber  downlinkOffset 
)

◆ gistXLogPageReuse()

void gistXLogPageReuse ( Relation  rel,
Relation  heaprel,
BlockNumber  blkno,
FullTransactionId  deleteXid 
)

Definition at line 592 of file gistxlog.c.

594{
596
597 /*
598 * Note that we don't register the buffer with the record, because this
599 * operation doesn't modify the page. This record only exists to provide a
600 * conflict point for Hot Standby.
601 */
602
603 /* XLOG stuff */
605 xlrec_reuse.locator = rel->rd_locator;
606 xlrec_reuse.block = blkno;
607 xlrec_reuse.snapshotConflictHorizon = deleteXid;
608
611
613}
#define SizeOfGistxlogPageReuse
Definition gistxlog.h:106
RelFileLocator rd_locator
Definition rel.h:57

References fb(), gistxlogPageReuse::isCatalogRel, RelationData::rd_locator, RelationIsAccessibleInLogicalDecoding, SizeOfGistxlogPageReuse, XLOG_GIST_PAGE_REUSE, XLogBeginInsert(), XLogInsert(), and XLogRegisterData().

Referenced by gistNewBuffer().

◆ gistXLogSplit()

XLogRecPtr gistXLogSplit ( bool  page_is_leaf,
SplitPageLayout dist,
BlockNumber  origrlink,
GistNSN  orignsn,
Buffer  leftchildbuf,
bool  markfollowright 
)

Definition at line 493 of file gistxlog.c.

497{
499 SplitPageLayout *ptr;
500 int npage = 0;
502 int i;
503
504 for (ptr = dist; ptr; ptr = ptr->next)
505 npage++;
506
507 xlrec.origrlink = origrlink;
508 xlrec.orignsn = orignsn;
509 xlrec.origleaf = page_is_leaf;
510 xlrec.npage = (uint16) npage;
511 xlrec.markfollowright = markfollowright;
512
514
515 /*
516 * Include a full page image of the child buf. (only necessary if a
517 * checkpoint happened since the child page was split)
518 */
521
522 /*
523 * NOTE: We register a lot of data. The caller must've called
524 * XLogEnsureRecordSpace() to prepare for that. We cannot do it here,
525 * because we're already in a critical section. If you change the number
526 * of buffer or data registrations here, make sure you modify the
527 * XLogEnsureRecordSpace() calls accordingly!
528 */
530
531 i = 1;
532 for (ptr = dist; ptr; ptr = ptr->next)
533 {
535 XLogRegisterBufData(i, &(ptr->block.num), sizeof(int));
536 XLogRegisterBufData(i, ptr->list, ptr->lenlist);
537 i++;
538 }
539
541
542 return recptr;
543}
uint16_t uint16
Definition c.h:545
gistxlogPage block
struct SplitPageLayout * next
IndexTupleData * list
void XLogRegisterBufData(uint8 block_id, const void *data, uint32 len)
Definition xloginsert.c:409
#define REGBUF_WILL_INIT
Definition xloginsert.h:34

References SplitPageLayout::block, SplitPageLayout::buffer, BufferIsValid(), fb(), i, SplitPageLayout::lenlist, SplitPageLayout::list, SplitPageLayout::next, gistxlogPage::num, REGBUF_STANDARD, REGBUF_WILL_INIT, XLOG_GIST_PAGE_SPLIT, XLogBeginInsert(), XLogInsert(), XLogRegisterBufData(), XLogRegisterBuffer(), and XLogRegisterData().

Referenced by gistplacetopage().

◆ gistXLogUpdate()

XLogRecPtr gistXLogUpdate ( Buffer  buffer,
OffsetNumber todelete,
int  ntodelete,
IndexTuple itup,
int  ituplen,
Buffer  leftchildbuf 
)

Definition at line 627 of file gistxlog.c.

631{
633 int i;
635
636 xlrec.ntodelete = ntodelete;
637 xlrec.ntoinsert = ituplen;
638
641
643 XLogRegisterBufData(0, todelete, sizeof(OffsetNumber) * ntodelete);
644
645 /* new tuples */
646 for (i = 0; i < ituplen; i++)
647 XLogRegisterBufData(0, itup[i], IndexTupleSize(itup[i]));
648
649 /*
650 * Include a full page image of the child buf. (only necessary if a
651 * checkpoint happened since the child page was split)
652 */
655
657
658 return recptr;
659}

References BufferIsValid(), fb(), i, IndexTupleSize(), gistxlogPageUpdate::ntodelete, REGBUF_STANDARD, XLOG_GIST_PAGE_UPDATE, XLogBeginInsert(), XLogInsert(), XLogRegisterBufData(), XLogRegisterBuffer(), and XLogRegisterData().

Referenced by gistplacetopage(), and gistvacuumpage().

Variable Documentation

◆ opCtx

MemoryContext opCtx
static

Definition at line 26 of file gistxlog.c.

Referenced by gist_redo(), gist_xlog_cleanup(), and gist_xlog_startup().