PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
gistxlog.c File Reference
#include "postgres.h"
#include "access/bufmask.h"
#include "access/gist_private.h"
#include "access/gistxlog.h"
#include "access/xloginsert.h"
#include "access/xlogutils.h"
#include "utils/memutils.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 IndexTupledecodePageSplitRecord (char *begin, int len, int *n)
 
static void gistRedoPageSplitRecord (XLogReaderState *record)
 
static void gistRedoCreateIndex (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, SplitedPageLayout *dist, BlockNumber origrlink, GistNSN orignsn, Buffer leftchildbuf, bool markfollowright)
 
XLogRecPtr gistXLogUpdate (Buffer buffer, OffsetNumber *todelete, int ntodelete, IndexTuple *itup, int ituplen, Buffer leftchildbuf)
 

Variables

static MemoryContext opCtx
 

Function Documentation

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

Definition at line 167 of file gistxlog.c.

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

Referenced by gistRedoPageSplitRecord().

168 {
169  char *ptr;
170  int i = 0;
171  IndexTuple *tuples;
172 
173  /* extract the number of tuples */
174  memcpy(n, begin, sizeof(int));
175  ptr = begin + sizeof(int);
176 
177  tuples = palloc(*n * sizeof(IndexTuple));
178 
179  for (i = 0; i < *n; i++)
180  {
181  Assert(ptr - begin < len);
182  tuples[i] = (IndexTuple) ptr;
183  ptr += IndexTupleSize((IndexTuple) ptr);
184  }
185  Assert(ptr - begin == len);
186 
187  return tuples;
188 }
IndexTupleData * IndexTuple
Definition: itup.h:53
#define Assert(condition)
Definition: c.h:675
void * palloc(Size size)
Definition: mcxt.c:849
int i
#define IndexTupleSize(itup)
Definition: itup.h:70
void gist_mask ( char *  pagedata,
BlockNumber  blkno 
)

Definition at line 351 of file gistxlog.c.

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

352 {
353  Page page = (Page) pagedata;
354 
355  mask_page_lsn(page);
356 
357  mask_page_hint_bits(page);
358  mask_unused_space(page);
359 
360  /*
361  * NSN is nothing but a special purpose LSN. Hence, mask it for the same
362  * reason as mask_page_lsn.
363  */
364  GistPageSetNSN(page, (uint64) MASK_MARKER);
365 
366  /*
367  * We update F_FOLLOW_RIGHT flag on the left child after writing WAL
368  * record. Hence, mask this flag. See gistplacetopage() for details.
369  */
370  GistMarkFollowRight(page);
371 
372  if (GistPageIsLeaf(page))
373  {
374  /*
375  * In gist leaf pages, it is possible to modify the LP_FLAGS without
376  * emitting any WAL record. Hence, mask the line pointer flags. See
377  * gistkillitems() for details.
378  */
379  mask_lp_flags(page);
380  }
381 
382  /*
383  * During gist redo, we never mark a page as garbage. Hence, mask it to
384  * ignore any differences.
385  */
387 }
#define GistClearPageHasGarbage(page)
Definition: gist.h:145
void mask_page_hint_bits(Page page)
Definition: bufmask.c:44
#define GistPageSetNSN(page, val)
Definition: gist.h:152
void mask_unused_space(Page page)
Definition: bufmask.c:69
#define MASK_MARKER
Definition: bufmask.h:24
void mask_page_lsn(Page page)
Definition: bufmask.c:30
#define GistPageIsLeaf(page)
Definition: gist.h:132
#define GistMarkFollowRight(page)
Definition: gist.h:148
void mask_lp_flags(Page page)
Definition: bufmask.c:93
Pointer Page
Definition: bufpage.h:74
void gist_redo ( XLogReaderState record)

Definition at line 304 of file gistxlog.c.

References elog, gistRedoCreateIndex(), gistRedoPageSplitRecord(), gistRedoPageUpdateRecord(), MemoryContextReset(), MemoryContextSwitchTo(), PANIC, XLOG_GIST_CREATE_INDEX, XLOG_GIST_PAGE_SPLIT, XLOG_GIST_PAGE_UPDATE, XLogRecGetInfo, and XLR_INFO_MASK.

305 {
306  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
307  MemoryContext oldCxt;
308 
309  /*
310  * GiST indexes do not require any conflict processing. NB: If we ever
311  * implement a similar optimization we have in b-tree, and remove killed
312  * tuples outside VACUUM, we'll need to handle that here.
313  */
314 
315  oldCxt = MemoryContextSwitchTo(opCtx);
316  switch (info)
317  {
319  gistRedoPageUpdateRecord(record);
320  break;
322  gistRedoPageSplitRecord(record);
323  break;
325  gistRedoCreateIndex(record);
326  break;
327  default:
328  elog(PANIC, "gist_redo: unknown op code %u", info);
329  }
330 
331  MemoryContextSwitchTo(oldCxt);
333 }
static void gistRedoPageUpdateRecord(XLogReaderState *record)
Definition: gistxlog.c:67
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
unsigned char uint8
Definition: c.h:266
#define XLOG_GIST_CREATE_INDEX
Definition: gistxlog.h:24
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:135
#define PANIC
Definition: elog.h:53
#define XLOG_GIST_PAGE_SPLIT
Definition: gistxlog.h:22
static void gistRedoPageSplitRecord(XLogReaderState *record)
Definition: gistxlog.c:191
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:216
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
static MemoryContext opCtx
Definition: gistxlog.c:23
#define elog
Definition: elog.h:219
#define XLOG_GIST_PAGE_UPDATE
Definition: gistxlog.h:20
static void gistRedoCreateIndex(XLogReaderState *record)
Definition: gistxlog.c:285
void gist_xlog_cleanup ( void  )

Definition at line 342 of file gistxlog.c.

References MemoryContextDelete().

343 {
345 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
static MemoryContext opCtx
Definition: gistxlog.c:23
void gist_xlog_startup ( void  )

Definition at line 336 of file gistxlog.c.

References createTempGistContext().

337 {
339 }
MemoryContext createTempGistContext(void)
Definition: gist.c:110
static MemoryContext opCtx
Definition: gistxlog.c:23
static void gistRedoClearFollowRight ( XLogReaderState record,
uint8  block_id 
)
static

Definition at line 37 of file gistxlog.c.

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

Referenced by gistRedoPageSplitRecord(), and gistRedoPageUpdateRecord().

38 {
39  XLogRecPtr lsn = record->EndRecPtr;
40  Buffer buffer;
41  Page page;
42  XLogRedoAction action;
43 
44  /*
45  * Note that we still update the page even if it was restored from a full
46  * page image, because the updated NSN is not included in the image.
47  */
48  action = XLogReadBufferForRedo(record, block_id, &buffer);
49  if (action == BLK_NEEDS_REDO || action == BLK_RESTORED)
50  {
51  page = BufferGetPage(buffer);
52 
53  GistPageSetNSN(page, lsn);
55 
56  PageSetLSN(page, lsn);
57  MarkBufferDirty(buffer);
58  }
59  if (BufferIsValid(buffer))
60  UnlockReleaseBuffer(buffer);
61 }
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:1450
#define GistPageSetNSN(page, val)
Definition: gist.h:152
XLogRecPtr EndRecPtr
Definition: xlogreader.h:115
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define GistClearFollowRight(page)
Definition: gist.h:149
XLogRedoAction XLogReadBufferForRedo(XLogReaderState *record, uint8 block_id, Buffer *buf)
Definition: xlogutils.c:290
uint64 XLogRecPtr
Definition: xlogdefs.h:21
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
XLogRedoAction
Definition: xlogutils.h:27
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
#define PageSetLSN(page, lsn)
Definition: bufpage.h:364
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
static void gistRedoCreateIndex ( XLogReaderState record)
static

Definition at line 285 of file gistxlog.c.

References Assert, buffer, BufferGetBlockNumber(), BufferGetPage, XLogReaderState::EndRecPtr, F_LEAF, GIST_ROOT_BLKNO, GISTInitBuffer(), MarkBufferDirty(), PageSetLSN, UnlockReleaseBuffer(), and XLogInitBufferForRedo().

Referenced by gist_redo().

286 {
287  XLogRecPtr lsn = record->EndRecPtr;
288  Buffer buffer;
289  Page page;
290 
291  buffer = XLogInitBufferForRedo(record, 0);
293  page = (Page) BufferGetPage(buffer);
294 
295  GISTInitBuffer(buffer, F_LEAF);
296 
297  PageSetLSN(page, lsn);
298 
299  MarkBufferDirty(buffer);
300  UnlockReleaseBuffer(buffer);
301 }
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:1450
XLogRecPtr EndRecPtr
Definition: xlogreader.h:115
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
Buffer XLogInitBufferForRedo(XLogReaderState *record, uint8 block_id)
Definition: xlogutils.c:302
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:675
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:2605
#define F_LEAF
Definition: gist.h:42
#define GIST_ROOT_BLKNO
Definition: gist_private.h:249
void GISTInitBuffer(Buffer b, uint32 f)
Definition: gistutil.c:701
#define PageSetLSN(page, lsn)
Definition: bufpage.h:364
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
static void gistRedoPageSplitRecord ( XLogReaderState record)
static

Definition at line 191 of file gistxlog.c.

References Assert, GistBDItem::blkno, buffer, BufferGetPage, decodePageSplitRecord(), XLogReaderState::EndRecPtr, F_LEAF, FirstOffsetNumber, GIST_ROOT_BLKNO, GistClearFollowRight, gistfillbuffer(), GISTInitBuffer(), GistMarkFollowRight, GistPageGetOpaque, GistPageSetNSN, gistRedoClearFollowRight(), i, InvalidBlockNumber, InvalidBuffer, MarkBufferDirty(), gistxlogPageSplit::markfollowright, gistxlogPageSplit::npage, NULL, gistxlogPageSplit::origleaf, gistxlogPageSplit::orignsn, gistxlogPageSplit::origrlink, PageSetLSN, UnlockReleaseBuffer(), XLogInitBufferForRedo(), XLogRecGetBlockData(), XLogRecGetBlockTag(), XLogRecGetData, and XLogRecHasBlockRef.

Referenced by gist_redo().

192 {
193  XLogRecPtr lsn = record->EndRecPtr;
194  gistxlogPageSplit *xldata = (gistxlogPageSplit *) XLogRecGetData(record);
195  Buffer firstbuffer = InvalidBuffer;
196  Buffer buffer;
197  Page page;
198  int i;
199  bool isrootsplit = false;
200 
201  /*
202  * We must hold lock on the first-listed page throughout the action,
203  * including while updating the left child page (if any). We can unlock
204  * remaining pages in the list as soon as they've been written, because
205  * there is no path for concurrent queries to reach those pages without
206  * first visiting the first-listed page.
207  */
208 
209  /* loop around all pages */
210  for (i = 0; i < xldata->npage; i++)
211  {
212  int flags;
213  char *data;
214  Size datalen;
215  int num;
216  BlockNumber blkno;
217  IndexTuple *tuples;
218 
219  XLogRecGetBlockTag(record, i + 1, NULL, NULL, &blkno);
220  if (blkno == GIST_ROOT_BLKNO)
221  {
222  Assert(i == 0);
223  isrootsplit = true;
224  }
225 
226  buffer = XLogInitBufferForRedo(record, i + 1);
227  page = (Page) BufferGetPage(buffer);
228  data = XLogRecGetBlockData(record, i + 1, &datalen);
229 
230  tuples = decodePageSplitRecord(data, datalen, &num);
231 
232  /* ok, clear buffer */
233  if (xldata->origleaf && blkno != GIST_ROOT_BLKNO)
234  flags = F_LEAF;
235  else
236  flags = 0;
237  GISTInitBuffer(buffer, flags);
238 
239  /* and fill it */
240  gistfillbuffer(page, tuples, num, FirstOffsetNumber);
241 
242  if (blkno == GIST_ROOT_BLKNO)
243  {
244  GistPageGetOpaque(page)->rightlink = InvalidBlockNumber;
245  GistPageSetNSN(page, xldata->orignsn);
246  GistClearFollowRight(page);
247  }
248  else
249  {
250  if (i < xldata->npage - 1)
251  {
252  BlockNumber nextblkno;
253 
254  XLogRecGetBlockTag(record, i + 2, NULL, NULL, &nextblkno);
255  GistPageGetOpaque(page)->rightlink = nextblkno;
256  }
257  else
258  GistPageGetOpaque(page)->rightlink = xldata->origrlink;
259  GistPageSetNSN(page, xldata->orignsn);
260  if (i < xldata->npage - 1 && !isrootsplit &&
261  xldata->markfollowright)
262  GistMarkFollowRight(page);
263  else
264  GistClearFollowRight(page);
265  }
266 
267  PageSetLSN(page, lsn);
268  MarkBufferDirty(buffer);
269 
270  if (i == 0)
271  firstbuffer = buffer;
272  else
273  UnlockReleaseBuffer(buffer);
274  }
275 
276  /* Fix follow-right data on left child page, if any */
277  if (XLogRecHasBlockRef(record, 0))
278  gistRedoClearFollowRight(record, 0);
279 
280  /* Finally, release lock on the first page */
281  UnlockReleaseBuffer(firstbuffer);
282 }
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:1450
bool markfollowright
Definition: gistxlog.h:55
void gistfillbuffer(Page page, IndexTuple *itup, int len, OffsetNumber off)
Definition: gistutil.c:33
#define GistPageSetNSN(page, val)
Definition: gist.h:152
#define InvalidBuffer
Definition: buf.h:25
#define XLogRecHasBlockRef(decoder, block_id)
Definition: xlogreader.h:223
uint32 BlockNumber
Definition: block.h:31
XLogRecPtr EndRecPtr
Definition: xlogreader.h:115
#define XLogRecGetData(decoder)
Definition: xlogreader.h:220
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
Buffer XLogInitBufferForRedo(XLogReaderState *record, uint8 block_id)
Definition: xlogutils.c:302
#define FirstOffsetNumber
Definition: off.h:27
static IndexTuple * decodePageSplitRecord(char *begin, int len, int *n)
Definition: gistxlog.c:167
BlockNumber origrlink
Definition: gistxlog.h:50
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
GistNSN orignsn
Definition: gistxlog.h:51
bool XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id, RelFileNode *rnode, ForkNumber *forknum, BlockNumber *blknum)
Definition: xlogreader.c:1307
#define GistClearFollowRight(page)
Definition: gist.h:149
char * XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len)
Definition: xlogreader.c:1331
#define GistPageGetOpaque(page)
Definition: gist.h:130
#define NULL
Definition: c.h:229
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:675
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
static void gistRedoClearFollowRight(XLogReaderState *record, uint8 block_id)
Definition: gistxlog.c:37
size_t Size
Definition: c.h:356
#define InvalidBlockNumber
Definition: block.h:33
#define GistMarkFollowRight(page)
Definition: gist.h:148
#define F_LEAF
Definition: gist.h:42
int i
#define GIST_ROOT_BLKNO
Definition: gist_private.h:249
void GISTInitBuffer(Buffer b, uint32 f)
Definition: gistutil.c:701
#define PageSetLSN(page, lsn)
Definition: bufpage.h:364
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
static void gistRedoPageUpdateRecord ( XLogReaderState record)
static

Definition at line 67 of file gistxlog.c.

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

Referenced by gist_redo().

68 {
69  XLogRecPtr lsn = record->EndRecPtr;
71  Buffer buffer;
72  Page page;
73 
74  if (XLogReadBufferForRedo(record, 0, &buffer) == BLK_NEEDS_REDO)
75  {
76  char *begin;
77  char *data;
78  Size datalen;
79  int ninserted = 0;
80 
81  data = begin = XLogRecGetBlockData(record, 0, &datalen);
82 
83  page = (Page) BufferGetPage(buffer);
84 
85  if (xldata->ntodelete == 1 && xldata->ntoinsert == 1)
86  {
87  /*
88  * When replacing one tuple with one other tuple, we must use
89  * PageIndexTupleOverwrite for consistency with gistplacetopage.
90  */
91  OffsetNumber offnum = *((OffsetNumber *) data);
92  IndexTuple itup;
93  Size itupsize;
94 
95  data += sizeof(OffsetNumber);
96  itup = (IndexTuple) data;
97  itupsize = IndexTupleSize(itup);
98  if (!PageIndexTupleOverwrite(page, offnum, (Item) itup, itupsize))
99  elog(ERROR, "failed to add item to GiST index page, size %d bytes",
100  (int) itupsize);
101  data += itupsize;
102  /* should be nothing left after consuming 1 tuple */
103  Assert(data - begin == datalen);
104  /* update insertion count for assert check below */
105  ninserted++;
106  }
107  else if (xldata->ntodelete > 0)
108  {
109  /* Otherwise, delete old tuples if any */
110  OffsetNumber *todelete = (OffsetNumber *) data;
111 
112  data += sizeof(OffsetNumber) * xldata->ntodelete;
113 
114  PageIndexMultiDelete(page, todelete, xldata->ntodelete);
115  if (GistPageIsLeaf(page))
116  GistMarkTuplesDeleted(page);
117  }
118 
119  /* Add new tuples if any */
120  if (data - begin < datalen)
121  {
122  OffsetNumber off = (PageIsEmpty(page)) ? FirstOffsetNumber :
124 
125  while (data - begin < datalen)
126  {
127  IndexTuple itup = (IndexTuple) data;
128  Size sz = IndexTupleSize(itup);
129  OffsetNumber l;
130 
131  data += sz;
132 
133  l = PageAddItem(page, (Item) itup, sz, off, false, false);
134  if (l == InvalidOffsetNumber)
135  elog(ERROR, "failed to add item to GiST index page, size %d bytes",
136  (int) sz);
137  off++;
138  ninserted++;
139  }
140  }
141 
142  /* Check that XLOG record contained expected number of tuples */
143  Assert(ninserted == xldata->ntoinsert);
144 
145  PageSetLSN(page, lsn);
146  MarkBufferDirty(buffer);
147  }
148 
149  /*
150  * Fix follow-right data on left child page
151  *
152  * This must be done while still holding the lock on the target page. Note
153  * that even if the target page no longer exists, we still attempt to
154  * replay the change on the child page.
155  */
156  if (XLogRecHasBlockRef(record, 1))
157  gistRedoClearFollowRight(record, 1);
158 
159  if (BufferIsValid(buffer))
160  UnlockReleaseBuffer(buffer);
161 }
#define PageIsEmpty(page)
Definition: bufpage.h:218
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:1450
#define GistMarkTuplesDeleted(page)
Definition: gist.h:140
Pointer Item
Definition: item.h:17
#define XLogRecHasBlockRef(decoder, block_id)
Definition: xlogreader.h:223
uint16 ntoinsert
Definition: gistxlog.h:36
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
Definition: bufpage.h:412
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:353
uint16 ntodelete
Definition: gistxlog.h:35
XLogRecPtr EndRecPtr
Definition: xlogreader.h:115
uint16 OffsetNumber
Definition: off.h:24
#define XLogRecGetData(decoder)
Definition: xlogreader.h:220
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
#define ERROR
Definition: elog.h:43
bool PageIndexTupleOverwrite(Page page, OffsetNumber offnum, Item newtup, Size newsize)
Definition: bufpage.c:1066
#define FirstOffsetNumber
Definition: off.h:27
IndexTupleData * IndexTuple
Definition: itup.h:53
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define GistPageIsLeaf(page)
Definition: gist.h:132
char * XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len)
Definition: xlogreader.c:1331
#define InvalidOffsetNumber
Definition: off.h:26
XLogRedoAction XLogReadBufferForRedo(XLogReaderState *record, uint8 block_id, Buffer *buf)
Definition: xlogutils.c:290
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:675
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
static void gistRedoClearFollowRight(XLogReaderState *record, uint8 block_id)
Definition: gistxlog.c:37
void PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
Definition: bufpage.c:836
#define OffsetNumberNext(offsetNumber)
Definition: off.h:53
size_t Size
Definition: c.h:356
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
#define elog
Definition: elog.h:219
#define PageSetLSN(page, lsn)
Definition: bufpage.h:364
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
#define IndexTupleSize(itup)
Definition: itup.h:70
XLogRecPtr gistXLogSplit ( bool  page_is_leaf,
SplitedPageLayout dist,
BlockNumber  origrlink,
GistNSN  orignsn,
Buffer  leftchildbuf,
bool  markfollowright 
)

Definition at line 393 of file gistxlog.c.

References SplitedPageLayout::block, SplitedPageLayout::buffer, BufferIsValid, i, SplitedPageLayout::lenlist, SplitedPageLayout::list, gistxlogPageSplit::markfollowright, SplitedPageLayout::next, gistxlogPageSplit::npage, gistxlogPage::num, gistxlogPageSplit::origleaf, gistxlogPageSplit::orignsn, gistxlogPageSplit::origrlink, REGBUF_STANDARD, REGBUF_WILL_INIT, XLOG_GIST_PAGE_SPLIT, XLogBeginInsert(), XLogInsert(), XLogRegisterBufData(), XLogRegisterBuffer(), and XLogRegisterData().

Referenced by gistplacetopage().

397 {
398  gistxlogPageSplit xlrec;
399  SplitedPageLayout *ptr;
400  int npage = 0;
401  XLogRecPtr recptr;
402  int i;
403 
404  for (ptr = dist; ptr; ptr = ptr->next)
405  npage++;
406 
407  xlrec.origrlink = origrlink;
408  xlrec.orignsn = orignsn;
409  xlrec.origleaf = page_is_leaf;
410  xlrec.npage = (uint16) npage;
411  xlrec.markfollowright = markfollowright;
412 
413  XLogBeginInsert();
414 
415  /*
416  * Include a full page image of the child buf. (only necessary if a
417  * checkpoint happened since the child page was split)
418  */
419  if (BufferIsValid(leftchildbuf))
420  XLogRegisterBuffer(0, leftchildbuf, REGBUF_STANDARD);
421 
422  /*
423  * NOTE: We register a lot of data. The caller must've called
424  * XLogEnsureRecordSpace() to prepare for that. We cannot do it here,
425  * because we're already in a critical section. If you change the number
426  * of buffer or data registrations here, make sure you modify the
427  * XLogEnsureRecordSpace() calls accordingly!
428  */
429  XLogRegisterData((char *) &xlrec, sizeof(gistxlogPageSplit));
430 
431  i = 1;
432  for (ptr = dist; ptr; ptr = ptr->next)
433  {
435  XLogRegisterBufData(i, (char *) &(ptr->block.num), sizeof(int));
436  XLogRegisterBufData(i, (char *) ptr->list, ptr->lenlist);
437  i++;
438  }
439 
440  recptr = XLogInsert(RM_GIST_ID, XLOG_GIST_PAGE_SPLIT);
441 
442  return recptr;
443 }
void XLogRegisterBufData(uint8 block_id, char *data, int len)
Definition: xloginsert.c:361
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
Definition: xloginsert.c:213
bool markfollowright
Definition: gistxlog.h:55
#define REGBUF_WILL_INIT
Definition: xloginsert.h:32
IndexTupleData * list
Definition: gist_private.h:190
gistxlogPage block
Definition: gist_private.h:189
unsigned short uint16
Definition: c.h:267
#define XLOG_GIST_PAGE_SPLIT
Definition: gistxlog.h:22
#define REGBUF_STANDARD
Definition: xloginsert.h:34
BlockNumber origrlink
Definition: gistxlog.h:50
struct SplitedPageLayout * next
Definition: gist_private.h:196
GistNSN orignsn
Definition: gistxlog.h:51
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
int i
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr gistXLogUpdate ( Buffer  buffer,
OffsetNumber todelete,
int  ntodelete,
IndexTuple itup,
int  ituplen,
Buffer  leftchildbuf 
)

Definition at line 457 of file gistxlog.c.

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

Referenced by gistbulkdelete(), gistplacetopage(), and gistvacuumpage().

461 {
462  gistxlogPageUpdate xlrec;
463  int i;
464  XLogRecPtr recptr;
465 
466  xlrec.ntodelete = ntodelete;
467  xlrec.ntoinsert = ituplen;
468 
469  XLogBeginInsert();
470  XLogRegisterData((char *) &xlrec, sizeof(gistxlogPageUpdate));
471 
473  XLogRegisterBufData(0, (char *) todelete, sizeof(OffsetNumber) * ntodelete);
474 
475  /* new tuples */
476  for (i = 0; i < ituplen; i++)
477  XLogRegisterBufData(0, (char *) (itup[i]), IndexTupleSize(itup[i]));
478 
479  /*
480  * Include a full page image of the child buf. (only necessary if a
481  * checkpoint happened since the child page was split)
482  */
483  if (BufferIsValid(leftchildbuf))
484  XLogRegisterBuffer(1, leftchildbuf, REGBUF_STANDARD);
485 
486  recptr = XLogInsert(RM_GIST_ID, XLOG_GIST_PAGE_UPDATE);
487 
488  return recptr;
489 }
void XLogRegisterBufData(uint8 block_id, char *data, int len)
Definition: xloginsert.c:361
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
Definition: xloginsert.c:213
uint16 ntoinsert
Definition: gistxlog.h:36
uint16 ntodelete
Definition: gistxlog.h:35
uint16 OffsetNumber
Definition: off.h:24
#define REGBUF_STANDARD
Definition: xloginsert.h:34
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
uint64 XLogRecPtr
Definition: xlogdefs.h:21
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
int i
#define XLOG_GIST_PAGE_UPDATE
Definition: gistxlog.h:20
void XLogBeginInsert(void)
Definition: xloginsert.c:120
#define IndexTupleSize(itup)
Definition: itup.h:70

Variable Documentation

MemoryContext opCtx
static

Definition at line 23 of file gistxlog.c.