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)
 
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:945
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 448 of file gistxlog.c.

449{
450 Page page = (Page) pagedata;
451
453
455 mask_unused_space(page);
456
457 /*
458 * NSN is nothing but a special purpose LSN. Hence, mask it for the same
459 * reason as mask_page_lsn_and_checksum.
460 */
462
463 /*
464 * We update F_FOLLOW_RIGHT flag on the left child after writing WAL
465 * record. Hence, mask this flag. See gistplacetopage() for details.
466 */
468
469 if (GistPageIsLeaf(page))
470 {
471 /*
472 * In gist leaf pages, it is possible to modify the LP_FLAGS without
473 * emitting any WAL record. Hence, mask the line pointer flags. See
474 * gistkillitems() for details.
475 */
476 mask_lp_flags(page);
477 }
478
479 /*
480 * During gist redo, we never mark a page as garbage. Hence, mask it to
481 * ignore any differences.
482 */
484}
void mask_lp_flags(Page page)
Definition bufmask.c:94
void mask_page_lsn_and_checksum(Page page)
Definition bufmask.c:31
void mask_unused_space(Page page)
Definition bufmask.c:70
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:619
#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;
424 default:
425 elog(PANIC, "gist_redo: unknown op code %u", info);
426 }
427
430}
uint8_t uint8
Definition c.h:616
#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_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:410

References elog, fb(), gistRedoDeleteRecord(), gistRedoPageDelete(), gistRedoPageReuse(), gistRedoPageSplitRecord(), gistRedoPageUpdateRecord(), MemoryContextReset(), MemoryContextSwitchTo(), opCtx, PANIC, 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 439 of file gistxlog.c.

440{
442}
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:472

References MemoryContextDelete(), and opCtx.

◆ gist_xlog_startup()

void gist_xlog_startup ( void  )

Definition at line 433 of file gistxlog.c.

434{
436}
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:5583
void MarkBufferDirty(Buffer buffer)
Definition bufmgr.c:3132
static Page BufferGetPage(Buffer buffer)
Definition bufmgr.h:472
static bool BufferIsValid(Buffer bufnum)
Definition bufmgr.h:423
static void PageSetLSN(Page page, XLogRecPtr lsn)
Definition bufpage.h:417
#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:470
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:415
#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:515

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:691
#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:420
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:249
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
Definition bufpage.h:504
static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)
Definition bufpage.h:397
#define PG_USED_FOR_ASSERTS_ONLY
Definition c.h:243
#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().

◆ gistXLogDelete()

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

Definition at line 647 of file gistxlog.c.

649{
652
654 xlrec.snapshotConflictHorizon = snapshotConflictHorizon;
655 xlrec.ntodelete = ntodelete;
656
659
660 /*
661 * We need the target-offsets array whether or not we store the whole
662 * buffer, to allow us to find the snapshotConflictHorizon on a standby
663 * server.
664 */
665 XLogRegisterData(todelete, ntodelete * sizeof(OffsetNumber));
666
668
670
671 return recptr;
672}
#define SizeOfGistxlogDelete
Definition gistxlog.h:59
#define RelationIsAccessibleInLogicalDecoding(relation)
Definition rel.h:693
bool isCatalogRel
Definition gistxlog.h:52
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition xloginsert.c:482
void XLogRegisterData(const void *data, uint32 len)
Definition xloginsert.c:372
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
Definition xloginsert.c:246
void XLogBeginInsert(void)
Definition xloginsert.c:153
#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 571 of file gistxlog.c.

573{
575
576 /*
577 * Note that we don't register the buffer with the record, because this
578 * operation doesn't modify the page. This record only exists to provide a
579 * conflict point for Hot Standby.
580 */
581
582 /* XLOG stuff */
584 xlrec_reuse.locator = rel->rd_locator;
585 xlrec_reuse.block = blkno;
586 xlrec_reuse.snapshotConflictHorizon = deleteXid;
587
590
592}
#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 490 of file gistxlog.c.

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

610{
612 int i;
614
615 xlrec.ntodelete = ntodelete;
616 xlrec.ntoinsert = ituplen;
617
620
622 XLogRegisterBufData(0, todelete, sizeof(OffsetNumber) * ntodelete);
623
624 /* new tuples */
625 for (i = 0; i < ituplen; i++)
626 XLogRegisterBufData(0, itup[i], IndexTupleSize(itup[i]));
627
628 /*
629 * Include a full page image of the child buf. (only necessary if a
630 * checkpoint happened since the child page was split)
631 */
634
636
637 return recptr;
638}

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().