PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
brin_pageops.c File Reference
#include "postgres.h"
#include "access/brin_pageops.h"
#include "access/brin_page.h"
#include "access/brin_revmap.h"
#include "access/brin_xlog.h"
#include "access/xloginsert.h"
#include "miscadmin.h"
#include "storage/bufmgr.h"
#include "storage/freespace.h"
#include "storage/lmgr.h"
#include "storage/smgr.h"
#include "utils/rel.h"
Include dependency graph for brin_pageops.c:

Go to the source code of this file.

Macros

#define BrinMaxItemSize
 

Functions

static Buffer brin_getinsertbuffer (Relation irel, Buffer oldbuf, Size itemsz, bool *extended)
 
static Size br_page_get_freespace (Page page)
 
static void brin_initialize_empty_new_buffer (Relation idxrel, Buffer buffer)
 
bool brin_doupdate (Relation idxrel, BlockNumber pagesPerRange, BrinRevmap *revmap, BlockNumber heapBlk, Buffer oldbuf, OffsetNumber oldoff, const BrinTuple *origtup, Size origsz, const BrinTuple *newtup, Size newsz, bool samepage)
 
bool brin_can_do_samepage_update (Buffer buffer, Size origsz, Size newsz)
 
OffsetNumber brin_doinsert (Relation idxrel, BlockNumber pagesPerRange, BrinRevmap *revmap, Buffer *buffer, BlockNumber heapBlk, BrinTuple *tup, Size itemsz)
 
void brin_page_init (Page page, uint16 type)
 
void brin_metapage_init (Page page, BlockNumber pagesPerRange, uint16 version)
 
bool brin_start_evacuating_page (Relation idxRel, Buffer buf)
 
void brin_evacuate_page (Relation idxRel, BlockNumber pagesPerRange, BrinRevmap *revmap, Buffer buf)
 
bool brin_page_cleanup (Relation idxrel, Buffer buf)
 

Macro Definition Documentation

#define BrinMaxItemSize
Value:
MAXALIGN_DOWN(BLCKSZ - \
sizeof(ItemIdData)) + \
#define SizeOfPageHeaderData
Definition: bufpage.h:212
#define MAXALIGN(LEN)
Definition: c.h:588
#define MAXALIGN_DOWN(LEN)
Definition: c.h:600

Definition at line 30 of file brin_pageops.c.

Referenced by brin_doinsert(), brin_doupdate(), and brin_getinsertbuffer().

Function Documentation

static Size br_page_get_freespace ( Page  page)
static

Definition at line 882 of file brin_pageops.c.

References BRIN_EVACUATE_PAGE, BRIN_IS_REGULAR_PAGE, BrinPageFlags, and PageGetFreeSpace().

Referenced by brin_doinsert(), brin_doupdate(), brin_getinsertbuffer(), brin_initialize_empty_new_buffer(), and brin_page_cleanup().

883 {
884  if (!BRIN_IS_REGULAR_PAGE(page) ||
885  (BrinPageFlags(page) & BRIN_EVACUATE_PAGE) != 0)
886  return 0;
887  else
888  return PageGetFreeSpace(page);
889 }
#define BRIN_IS_REGULAR_PAGE(page)
Definition: brin_page.h:57
Size PageGetFreeSpace(Page page)
Definition: bufpage.c:582
#define BRIN_EVACUATE_PAGE
Definition: brin_page.h:60
#define BrinPageFlags(page)
Definition: brin_page.h:46
bool brin_can_do_samepage_update ( Buffer  buffer,
Size  origsz,
Size  newsz 
)

Definition at line 321 of file brin_pageops.c.

References BufferGetPage, and PageGetExactFreeSpace().

Referenced by brin_doupdate(), brininsert(), and summarize_range().

322 {
323  return
324  ((newsz <= origsz) ||
325  PageGetExactFreeSpace(BufferGetPage(buffer)) >= (newsz - origsz));
326 }
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
Size PageGetExactFreeSpace(Page page)
Definition: bufpage.c:633
OffsetNumber brin_doinsert ( Relation  idxrel,
BlockNumber  pagesPerRange,
BrinRevmap revmap,
Buffer buffer,
BlockNumber  heapBlk,
BrinTuple tup,
Size  itemsz 
)

Definition at line 340 of file brin_pageops.c.

References Assert, br_page_get_freespace(), BRIN_elog, brin_getinsertbuffer(), brin_page_init(), BRIN_PAGETYPE_REGULAR, brinLockRevmapPageForUpdate(), BrinMaxItemSize, brinRevmapExtend(), brinSetHeapBlockItemptr(), BUFFER_LOCK_EXCLUSIVE, BUFFER_LOCK_UNLOCK, BufferGetBlockNumber(), BufferGetPage, BufferIsValid, DEBUG2, elog, END_CRIT_SECTION, ereport, errcode(), errmsg(), ERROR, FreeSpaceMapVacuum(), xl_brin_insert::heapBlk, InvalidBuffer, InvalidOffsetNumber, ItemPointerSet, LockBuffer(), MarkBufferDirty(), MAXALIGN, xl_brin_insert::offnum, PageAddItem, PageSetLSN, xl_brin_insert::pagesPerRange, REGBUF_STANDARD, REGBUF_WILL_INIT, RelationGetRelationName, RelationNeedsWAL, SizeOfBrinInsert, START_CRIT_SECTION, UnlockReleaseBuffer(), XLOG_BRIN_INIT_PAGE, XLOG_BRIN_INSERT, XLogBeginInsert(), XLogInsert(), XLogRegisterBufData(), XLogRegisterBuffer(), and XLogRegisterData().

Referenced by form_and_insert_tuple(), and summarize_range().

343 {
344  Page page;
345  BlockNumber blk;
346  OffsetNumber off;
347  Buffer revmapbuf;
348  ItemPointerData tid;
349  bool extended;
350 
351  Assert(itemsz == MAXALIGN(itemsz));
352 
353  /* If the item is oversized, don't even bother. */
354  if (itemsz > BrinMaxItemSize)
355  {
356  ereport(ERROR,
357  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
358  errmsg("index row size %zu exceeds maximum %zu for index \"%s\"",
359  itemsz, BrinMaxItemSize, RelationGetRelationName(idxrel))));
360  return InvalidOffsetNumber; /* keep compiler quiet */
361  }
362 
363  /* Make sure the revmap is long enough to contain the entry we need */
364  brinRevmapExtend(revmap, heapBlk);
365 
366  /*
367  * Acquire lock on buffer supplied by caller, if any. If it doesn't have
368  * enough space, unpin it to obtain a new one below.
369  */
370  if (BufferIsValid(*buffer))
371  {
372  /*
373  * It's possible that another backend (or ourselves!) extended the
374  * revmap over the page we held a pin on, so we cannot assume that
375  * it's still a regular page.
376  */
379  {
382  }
383  }
384 
385  /*
386  * If we still don't have a usable buffer, have brin_getinsertbuffer
387  * obtain one for us.
388  */
389  if (!BufferIsValid(*buffer))
390  {
391  do
392  *buffer = brin_getinsertbuffer(idxrel, InvalidBuffer, itemsz, &extended);
393  while (!BufferIsValid(*buffer));
394  }
395  else
396  extended = false;
397 
398  /* Now obtain lock on revmap buffer */
399  revmapbuf = brinLockRevmapPageForUpdate(revmap, heapBlk);
400 
401  page = BufferGetPage(*buffer);
403 
404  /* Execute the actual insertion */
406  if (extended)
408  off = PageAddItem(page, (Item) tup, itemsz, InvalidOffsetNumber,
409  false, false);
410  if (off == InvalidOffsetNumber)
411  elog(ERROR, "could not insert new index tuple to page");
413 
414  BRIN_elog((DEBUG2, "inserted tuple (%u,%u) for range starting at %u",
415  blk, off, heapBlk));
416 
417  ItemPointerSet(&tid, blk, off);
418  brinSetHeapBlockItemptr(revmapbuf, pagesPerRange, heapBlk, tid);
419  MarkBufferDirty(revmapbuf);
420 
421  /* XLOG stuff */
422  if (RelationNeedsWAL(idxrel))
423  {
424  xl_brin_insert xlrec;
425  XLogRecPtr recptr;
426  uint8 info;
427 
428  info = XLOG_BRIN_INSERT | (extended ? XLOG_BRIN_INIT_PAGE : 0);
429  xlrec.heapBlk = heapBlk;
430  xlrec.pagesPerRange = pagesPerRange;
431  xlrec.offnum = off;
432 
433  XLogBeginInsert();
434  XLogRegisterData((char *) &xlrec, SizeOfBrinInsert);
435 
437  XLogRegisterBufData(0, (char *) tup, itemsz);
438 
439  XLogRegisterBuffer(1, revmapbuf, 0);
440 
441  recptr = XLogInsert(RM_BRIN_ID, info);
442 
443  PageSetLSN(page, recptr);
444  PageSetLSN(BufferGetPage(revmapbuf), recptr);
445  }
446 
448 
449  /* Tuple is firmly on buffer; we can release our locks */
451  LockBuffer(revmapbuf, BUFFER_LOCK_UNLOCK);
452 
453  if (extended)
454  FreeSpaceMapVacuum(idxrel);
455 
456  return off;
457 }
void XLogRegisterBufData(uint8 block_id, char *data, int len)
Definition: xloginsert.c:361
BlockNumber heapBlk
Definition: brin_xlog.h:65
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
#define BRIN_elog(args)
Definition: brin_internal.h:81
#define SizeOfBrinInsert
Definition: brin_xlog.h:74
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:1450
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
Definition: xloginsert.c:213
#define END_CRIT_SECTION()
Definition: miscadmin.h:133
unsigned char uint8
Definition: c.h:266
Pointer Item
Definition: item.h:17
#define InvalidBuffer
Definition: buf.h:25
Buffer brinLockRevmapPageForUpdate(BrinRevmap *revmap, BlockNumber heapBlk)
Definition: brin_revmap.c:137
#define REGBUF_WILL_INIT
Definition: xloginsert.h:32
#define START_CRIT_SECTION()
Definition: miscadmin.h:131
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
Definition: bufpage.h:412
uint32 BlockNumber
Definition: block.h:31
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:89
uint16 OffsetNumber
Definition: off.h:24
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
#define ERROR
Definition: elog.h:43
#define BRIN_PAGETYPE_REGULAR
Definition: brin_page.h:53
#define DEBUG2
Definition: elog.h:24
void brinRevmapExtend(BrinRevmap *revmap, BlockNumber heapBlk)
Definition: brin_revmap.c:115
BlockNumber pagesPerRange
Definition: brin_xlog.h:68
#define REGBUF_STANDARD
Definition: xloginsert.h:34
static Size br_page_get_freespace(Page page)
Definition: brin_pageops.c:882
#define RelationGetRelationName(relation)
Definition: rel.h:436
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define ereport(elevel, rest)
Definition: elog.h:122
void FreeSpaceMapVacuum(Relation rel)
Definition: freespace.c:379
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
#define XLOG_BRIN_INIT_PAGE
Definition: brin_xlog.h:43
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
#define XLOG_BRIN_INSERT
Definition: brin_xlog.h:32
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
#define InvalidOffsetNumber
Definition: off.h:26
#define BrinMaxItemSize
Definition: brin_pageops.c:30
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:676
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
OffsetNumber offnum
Definition: brin_xlog.h:71
#define MAXALIGN(LEN)
Definition: c.h:588
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
#define RelationNeedsWAL(relation)
Definition: rel.h:505
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:2605
int errmsg(const char *fmt,...)
Definition: elog.c:797
static Buffer brin_getinsertbuffer(Relation irel, Buffer oldbuf, Size itemsz, bool *extended)
Definition: brin_pageops.c:662
#define elog
Definition: elog.h:219
void brinSetHeapBlockItemptr(Buffer buf, BlockNumber pagesPerRange, BlockNumber heapBlk, ItemPointerData tid)
Definition: brin_revmap.c:158
void XLogBeginInsert(void)
Definition: xloginsert.c:120
#define PageSetLSN(page, lsn)
Definition: bufpage.h:364
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
#define ItemPointerSet(pointer, blockNumber, offNum)
Definition: itemptr.h:105
void brin_page_init(Page page, uint16 type)
Definition: brin_pageops.c:465
bool brin_doupdate ( Relation  idxrel,
BlockNumber  pagesPerRange,
BrinRevmap revmap,
BlockNumber  heapBlk,
Buffer  oldbuf,
OffsetNumber  oldoff,
const BrinTuple origtup,
Size  origsz,
const BrinTuple newtup,
Size  newsz,
bool  samepage 
)

Definition at line 55 of file brin_pageops.c.

References Assert, BlockNumberIsValid, br_page_get_freespace(), brin_can_do_samepage_update(), BRIN_EVACUATE_PAGE, brin_getinsertbuffer(), brin_initialize_empty_new_buffer(), brin_page_init(), BRIN_PAGETYPE_REGULAR, brin_tuples_equal(), brinLockRevmapPageForUpdate(), BrinMaxItemSize, BrinPageFlags, brinRevmapExtend(), brinSetHeapBlockItemptr(), BUFFER_LOCK_EXCLUSIVE, BUFFER_LOCK_UNLOCK, BufferGetBlockNumber(), BufferGetPage, BufferIsValid, elog, END_CRIT_SECTION, ereport, errcode(), errmsg(), ERROR, FreeSpaceMapVacuum(), xl_brin_insert::heapBlk, xl_brin_update::insert, InvalidBlockNumber, InvalidBuffer, InvalidOffsetNumber, ItemIdGetLength, ItemIdIsNormal, ItemPointerSet, LockBuffer(), MarkBufferDirty(), MAXALIGN, xl_brin_insert::offnum, xl_brin_samepage_update::offnum, xl_brin_update::oldOffnum, PageAddItem, PageGetItem, PageGetItemId, PageIndexTupleDeleteNoCompact(), PageIndexTupleOverwrite(), PageSetLSN, xl_brin_insert::pagesPerRange, RecordPageWithFreeSpace(), REGBUF_STANDARD, REGBUF_WILL_INIT, RelationGetRelationName, RelationNeedsWAL, SizeOfBrinSamepageUpdate, SizeOfBrinUpdate, START_CRIT_SECTION, UnlockReleaseBuffer(), XLOG_BRIN_INIT_PAGE, XLOG_BRIN_SAMEPAGE_UPDATE, XLOG_BRIN_UPDATE, XLogBeginInsert(), XLogInsert(), XLogRegisterBufData(), XLogRegisterBuffer(), and XLogRegisterData().

Referenced by brin_evacuate_page(), brininsert(), and summarize_range().

61 {
62  Page oldpage;
63  ItemId oldlp;
64  BrinTuple *oldtup;
65  Size oldsz;
66  Buffer newbuf;
67  bool extended;
68 
69  Assert(newsz == MAXALIGN(newsz));
70 
71  /* If the item is oversized, don't bother. */
72  if (newsz > BrinMaxItemSize)
73  {
74  ereport(ERROR,
75  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
76  errmsg("index row size %zu exceeds maximum %zu for index \"%s\"",
77  newsz, BrinMaxItemSize, RelationGetRelationName(idxrel))));
78  return false; /* keep compiler quiet */
79  }
80 
81  /* make sure the revmap is long enough to contain the entry we need */
82  brinRevmapExtend(revmap, heapBlk);
83 
84  if (!samepage)
85  {
86  /* need a page on which to put the item */
87  newbuf = brin_getinsertbuffer(idxrel, oldbuf, newsz, &extended);
88  if (!BufferIsValid(newbuf))
89  {
90  Assert(!extended);
91  return false;
92  }
93 
94  /*
95  * Note: it's possible (though unlikely) that the returned newbuf is
96  * the same as oldbuf, if brin_getinsertbuffer determined that the old
97  * buffer does in fact have enough space.
98  */
99  if (newbuf == oldbuf)
100  {
101  Assert(!extended);
102  newbuf = InvalidBuffer;
103  }
104  }
105  else
106  {
108  newbuf = InvalidBuffer;
109  extended = false;
110  }
111  oldpage = BufferGetPage(oldbuf);
112  oldlp = PageGetItemId(oldpage, oldoff);
113 
114  /*
115  * Check that the old tuple wasn't updated concurrently: it might have
116  * moved someplace else entirely ...
117  */
118  if (!ItemIdIsNormal(oldlp))
119  {
121 
122  /*
123  * If this happens, and the new buffer was obtained by extending the
124  * relation, then we need to ensure we don't leave it uninitialized or
125  * forget about it.
126  */
127  if (BufferIsValid(newbuf))
128  {
129  if (extended)
130  brin_initialize_empty_new_buffer(idxrel, newbuf);
131  UnlockReleaseBuffer(newbuf);
132  if (extended)
133  FreeSpaceMapVacuum(idxrel);
134  }
135  return false;
136  }
137 
138  oldsz = ItemIdGetLength(oldlp);
139  oldtup = (BrinTuple *) PageGetItem(oldpage, oldlp);
140 
141  /*
142  * ... or it might have been updated in place to different contents.
143  */
144  if (!brin_tuples_equal(oldtup, oldsz, origtup, origsz))
145  {
147  if (BufferIsValid(newbuf))
148  {
149  if (extended)
150  brin_initialize_empty_new_buffer(idxrel, newbuf);
151  UnlockReleaseBuffer(newbuf);
152  if (extended)
153  FreeSpaceMapVacuum(idxrel);
154  }
155  return false;
156  }
157 
158  /*
159  * Great, the old tuple is intact. We can proceed with the update.
160  *
161  * If there's enough room in the old page for the new tuple, replace it.
162  *
163  * Note that there might now be enough space on the page even though the
164  * caller told us there isn't, if a concurrent update moved another tuple
165  * elsewhere or replaced a tuple with a smaller one.
166  */
167  if (((BrinPageFlags(oldpage) & BRIN_EVACUATE_PAGE) == 0) &&
168  brin_can_do_samepage_update(oldbuf, origsz, newsz))
169  {
170  if (BufferIsValid(newbuf))
171  {
172  /* as above */
173  if (extended)
174  brin_initialize_empty_new_buffer(idxrel, newbuf);
175  UnlockReleaseBuffer(newbuf);
176  }
177 
179  if (!PageIndexTupleOverwrite(oldpage, oldoff, (Item) newtup, newsz))
180  elog(ERROR, "failed to replace BRIN tuple");
181  MarkBufferDirty(oldbuf);
182 
183  /* XLOG stuff */
184  if (RelationNeedsWAL(idxrel))
185  {
187  XLogRecPtr recptr;
189 
190  xlrec.offnum = oldoff;
191 
192  XLogBeginInsert();
193  XLogRegisterData((char *) &xlrec, SizeOfBrinSamepageUpdate);
194 
196  XLogRegisterBufData(0, (char *) newtup, newsz);
197 
198  recptr = XLogInsert(RM_BRIN_ID, info);
199 
200  PageSetLSN(oldpage, recptr);
201  }
202 
204 
206 
207  if (extended)
208  FreeSpaceMapVacuum(idxrel);
209 
210  return true;
211  }
212  else if (newbuf == InvalidBuffer)
213  {
214  /*
215  * Not enough space, but caller said that there was. Tell them to
216  * start over.
217  */
219  return false;
220  }
221  else
222  {
223  /*
224  * Not enough free space on the oldpage. Put the new tuple on the new
225  * page, and update the revmap.
226  */
227  Page newpage = BufferGetPage(newbuf);
228  Buffer revmapbuf;
229  ItemPointerData newtid;
230  OffsetNumber newoff;
232  Size freespace = 0;
233 
234  revmapbuf = brinLockRevmapPageForUpdate(revmap, heapBlk);
235 
237 
238  /*
239  * We need to initialize the page if it's newly obtained. Note we
240  * will WAL-log the initialization as part of the update, so we don't
241  * need to do that here.
242  */
243  if (extended)
245 
246  PageIndexTupleDeleteNoCompact(oldpage, oldoff);
247  newoff = PageAddItem(newpage, (Item) newtup, newsz,
248  InvalidOffsetNumber, false, false);
249  if (newoff == InvalidOffsetNumber)
250  elog(ERROR, "failed to add BRIN tuple to new page");
251  MarkBufferDirty(oldbuf);
252  MarkBufferDirty(newbuf);
253 
254  /* needed to update FSM below */
255  if (extended)
256  {
257  newblk = BufferGetBlockNumber(newbuf);
258  freespace = br_page_get_freespace(newpage);
259  }
260 
261  ItemPointerSet(&newtid, BufferGetBlockNumber(newbuf), newoff);
262  brinSetHeapBlockItemptr(revmapbuf, pagesPerRange, heapBlk, newtid);
263  MarkBufferDirty(revmapbuf);
264 
265  /* XLOG stuff */
266  if (RelationNeedsWAL(idxrel))
267  {
268  xl_brin_update xlrec;
269  XLogRecPtr recptr;
270  uint8 info;
271 
272  info = XLOG_BRIN_UPDATE | (extended ? XLOG_BRIN_INIT_PAGE : 0);
273 
274  xlrec.insert.offnum = newoff;
275  xlrec.insert.heapBlk = heapBlk;
276  xlrec.insert.pagesPerRange = pagesPerRange;
277  xlrec.oldOffnum = oldoff;
278 
279  XLogBeginInsert();
280 
281  /* new page */
282  XLogRegisterData((char *) &xlrec, SizeOfBrinUpdate);
283 
284  XLogRegisterBuffer(0, newbuf, REGBUF_STANDARD | (extended ? REGBUF_WILL_INIT : 0));
285  XLogRegisterBufData(0, (char *) newtup, newsz);
286 
287  /* revmap page */
288  XLogRegisterBuffer(1, revmapbuf, 0);
289 
290  /* old page */
292 
293  recptr = XLogInsert(RM_BRIN_ID, info);
294 
295  PageSetLSN(oldpage, recptr);
296  PageSetLSN(newpage, recptr);
297  PageSetLSN(BufferGetPage(revmapbuf), recptr);
298  }
299 
301 
302  LockBuffer(revmapbuf, BUFFER_LOCK_UNLOCK);
304  UnlockReleaseBuffer(newbuf);
305 
306  if (extended)
307  {
308  Assert(BlockNumberIsValid(newblk));
309  RecordPageWithFreeSpace(idxrel, newblk, freespace);
310  FreeSpaceMapVacuum(idxrel);
311  }
312 
313  return true;
314  }
315 }
void XLogRegisterBufData(uint8 block_id, char *data, int len)
Definition: xloginsert.c:361
BlockNumber heapBlk
Definition: brin_xlog.h:65
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
void RecordPageWithFreeSpace(Relation rel, BlockNumber heapBlk, Size spaceAvail)
Definition: freespace.c:181
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:1450
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
Definition: xloginsert.c:213
#define END_CRIT_SECTION()
Definition: miscadmin.h:133
OffsetNumber offnum
Definition: brin_xlog.h:104
unsigned char uint8
Definition: c.h:266
Pointer Item
Definition: item.h:17
#define InvalidBuffer
Definition: buf.h:25
Buffer brinLockRevmapPageForUpdate(BrinRevmap *revmap, BlockNumber heapBlk)
Definition: brin_revmap.c:137
#define REGBUF_WILL_INIT
Definition: xloginsert.h:32
#define START_CRIT_SECTION()
Definition: miscadmin.h:131
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
Definition: bufpage.h:412
uint32 BlockNumber
Definition: block.h:31
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:89
uint16 OffsetNumber
Definition: off.h:24
#define SizeOfBrinUpdate
Definition: brin_xlog.h:95
#define XLOG_BRIN_UPDATE
Definition: brin_xlog.h:33
#define ItemIdGetLength(itemId)
Definition: itemid.h:58
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
#define ERROR
Definition: elog.h:43
#define BRIN_PAGETYPE_REGULAR
Definition: brin_page.h:53
void brinRevmapExtend(BrinRevmap *revmap, BlockNumber heapBlk)
Definition: brin_revmap.c:115
bool PageIndexTupleOverwrite(Page page, OffsetNumber offnum, Item newtup, Size newsize)
Definition: bufpage.c:1066
bool brin_tuples_equal(const BrinTuple *a, Size alen, const BrinTuple *b, Size blen)
Definition: brin_tuple.c:340
BlockNumber pagesPerRange
Definition: brin_xlog.h:68
#define REGBUF_STANDARD
Definition: xloginsert.h:34
static Size br_page_get_freespace(Page page)
Definition: brin_pageops.c:882
#define RelationGetRelationName(relation)
Definition: rel.h:436
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define ereport(elevel, rest)
Definition: elog.h:122
bool brin_can_do_samepage_update(Buffer buffer, Size origsz, Size newsz)
Definition: brin_pageops.c:321
void FreeSpaceMapVacuum(Relation rel)
Definition: freespace.c:379
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:231
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
#define XLOG_BRIN_INIT_PAGE
Definition: brin_xlog.h:43
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
#define InvalidOffsetNumber
Definition: off.h:26
xl_brin_insert insert
Definition: brin_xlog.h:92
#define BlockNumberIsValid(blockNumber)
Definition: block.h:70
void PageIndexTupleDeleteNoCompact(Page page, OffsetNumber offnum)
Definition: bufpage.c:958
#define BrinMaxItemSize
Definition: brin_pageops.c:30
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:676
#define ItemIdIsNormal(itemId)
Definition: itemid.h:98
#define SizeOfBrinSamepageUpdate
Definition: brin_xlog.h:107
size_t Size
Definition: c.h:356
#define XLOG_BRIN_SAMEPAGE_UPDATE
Definition: brin_xlog.h:34
#define InvalidBlockNumber
Definition: block.h:33
OffsetNumber offnum
Definition: brin_xlog.h:71
static void brin_initialize_empty_new_buffer(Relation idxrel, Buffer buffer)
Definition: brin_pageops.c:850
#define MAXALIGN(LEN)
Definition: c.h:588
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
#define RelationNeedsWAL(relation)
Definition: rel.h:505
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:2605
int errmsg(const char *fmt,...)
Definition: elog.c:797
static Buffer brin_getinsertbuffer(Relation irel, Buffer oldbuf, Size itemsz, bool *extended)
Definition: brin_pageops.c:662
#define BRIN_EVACUATE_PAGE
Definition: brin_page.h:60
#define elog
Definition: elog.h:219
#define BrinPageFlags(page)
Definition: brin_page.h:46
void brinSetHeapBlockItemptr(Buffer buf, BlockNumber pagesPerRange, BlockNumber heapBlk, ItemPointerData tid)
Definition: brin_revmap.c:158
void XLogBeginInsert(void)
Definition: xloginsert.c:120
#define PageSetLSN(page, lsn)
Definition: bufpage.h:364
OffsetNumber oldOffnum
Definition: brin_xlog.h:90
int Buffer
Definition: buf.h:23
#define PageGetItem(page, itemId)
Definition: bufpage.h:336
Pointer Page
Definition: bufpage.h:74
#define ItemPointerSet(pointer, blockNumber, offNum)
Definition: itemptr.h:105
void brin_page_init(Page page, uint16 type)
Definition: brin_pageops.c:465
void brin_evacuate_page ( Relation  idxRel,
BlockNumber  pagesPerRange,
BrinRevmap revmap,
Buffer  buf 
)

Definition at line 541 of file brin_pageops.c.

References Assert, brin_copy_tuple(), brin_doupdate(), BRIN_EVACUATE_PAGE, BRIN_IS_REGULAR_PAGE, BrinPageFlags, BrinTuple::bt_blkno, BUFFER_LOCK_SHARE, BUFFER_LOCK_UNLOCK, BufferGetPage, CHECK_FOR_INTERRUPTS, FirstOffsetNumber, ItemIdGetLength, ItemIdIsUsed, LockBuffer(), NULL, PageGetItem, PageGetItemId, PageGetMaxOffsetNumber, and UnlockReleaseBuffer().

Referenced by revmap_physical_extend().

543 {
544  OffsetNumber off;
545  OffsetNumber maxoff;
546  Page page;
547  BrinTuple *btup = NULL;
548  Size btupsz = 0;
549 
550  page = BufferGetPage(buf);
551 
553 
554  maxoff = PageGetMaxOffsetNumber(page);
555  for (off = FirstOffsetNumber; off <= maxoff; off++)
556  {
557  BrinTuple *tup;
558  Size sz;
559  ItemId lp;
560 
562 
563  lp = PageGetItemId(page, off);
564  if (ItemIdIsUsed(lp))
565  {
566  sz = ItemIdGetLength(lp);
567  tup = (BrinTuple *) PageGetItem(page, lp);
568  tup = brin_copy_tuple(tup, sz, btup, &btupsz);
569 
571 
572  if (!brin_doupdate(idxRel, pagesPerRange, revmap, tup->bt_blkno,
573  buf, off, tup, sz, tup, sz, false))
574  off--; /* retry */
575 
577 
578  /* It's possible that someone extended the revmap over this page */
579  if (!BRIN_IS_REGULAR_PAGE(page))
580  break;
581  }
582  }
583 
585 }
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
BrinTuple * brin_copy_tuple(BrinTuple *tuple, Size len, BrinTuple *dest, Size *destsz)
Definition: brin_tuple.c:321
#define ItemIdIsUsed(itemId)
Definition: itemid.h:91
#define BRIN_IS_REGULAR_PAGE(page)
Definition: brin_page.h:57
bool brin_doupdate(Relation idxrel, BlockNumber pagesPerRange, BrinRevmap *revmap, BlockNumber heapBlk, Buffer oldbuf, OffsetNumber oldoff, const BrinTuple *origtup, Size origsz, const BrinTuple *newtup, Size newsz, bool samepage)
Definition: brin_pageops.c:55
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:353
uint16 OffsetNumber
Definition: off.h:24
#define ItemIdGetLength(itemId)
Definition: itemid.h:58
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
static char * buf
Definition: pg_test_fsync.c:66
#define FirstOffsetNumber
Definition: off.h:27
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:231
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
BlockNumber bt_blkno
Definition: brin_tuple.h:57
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:676
size_t Size
Definition: c.h:356
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:88
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:98
#define BRIN_EVACUATE_PAGE
Definition: brin_page.h:60
#define BrinPageFlags(page)
Definition: brin_page.h:46
#define PageGetItem(page, itemId)
Definition: bufpage.h:336
Pointer Page
Definition: bufpage.h:74
static Buffer brin_getinsertbuffer ( Relation  irel,
Buffer  oldbuf,
Size  itemsz,
bool extended 
)
static

Definition at line 662 of file brin_pageops.c.

References Assert, br_page_get_freespace(), BRIN_elog, brin_initialize_empty_new_buffer(), BRIN_IS_REGULAR_PAGE, BrinMaxItemSize, buf, BUFFER_LOCK_EXCLUSIVE, BUFFER_LOCK_UNLOCK, BufferGetBlockNumber(), BufferGetPage, BufferIsValid, CHECK_FOR_INTERRUPTS, DEBUG2, ereport, errcode(), errmsg(), ERROR, ExclusiveLock, GetPageWithFreeSpace(), InvalidBlockNumber, InvalidBuffer, LockBuffer(), LockRelationForExtension(), P_NEW, ReadBuffer(), RecordAndGetPageWithFreeSpace(), RecordPageWithFreeSpace(), RELATION_IS_LOCAL, RelationGetRelationName, RelationGetTargetBlock, RelationSetTargetBlock, ReleaseBuffer(), UnlockRelationForExtension(), and UnlockReleaseBuffer().

Referenced by brin_doinsert(), and brin_doupdate().

664 {
665  BlockNumber oldblk;
666  BlockNumber newblk;
667  Page page;
668  Size freespace;
669 
670  /* callers must have checked */
671  Assert(itemsz <= BrinMaxItemSize);
672 
673  *extended = false;
674 
675  if (BufferIsValid(oldbuf))
676  oldblk = BufferGetBlockNumber(oldbuf);
677  else
678  oldblk = InvalidBlockNumber;
679 
680  /*
681  * Loop until we find a page with sufficient free space. By the time we
682  * return to caller out of this loop, both buffers are valid and locked;
683  * if we have to restart here, neither buffer is locked and buf is not a
684  * pinned buffer.
685  */
686  newblk = RelationGetTargetBlock(irel);
687  if (newblk == InvalidBlockNumber)
688  newblk = GetPageWithFreeSpace(irel, itemsz);
689  for (;;)
690  {
691  Buffer buf;
692  bool extensionLockHeld = false;
693 
695 
696  if (newblk == InvalidBlockNumber)
697  {
698  /*
699  * There's not enough free space in any existing index page,
700  * according to the FSM: extend the relation to obtain a shiny new
701  * page.
702  */
703  if (!RELATION_IS_LOCAL(irel))
704  {
706  extensionLockHeld = true;
707  }
708  buf = ReadBuffer(irel, P_NEW);
709  newblk = BufferGetBlockNumber(buf);
710  *extended = true;
711 
712  BRIN_elog((DEBUG2, "brin_getinsertbuffer: extending to page %u",
713  BufferGetBlockNumber(buf)));
714  }
715  else if (newblk == oldblk)
716  {
717  /*
718  * There's an odd corner-case here where the FSM is out-of-date,
719  * and gave us the old page.
720  */
721  buf = oldbuf;
722  }
723  else
724  {
725  buf = ReadBuffer(irel, newblk);
726  }
727 
728  /*
729  * We lock the old buffer first, if it's earlier than the new one; but
730  * before we do, we need to check that it hasn't been turned into a
731  * revmap page concurrently; if we detect that it happened, give up
732  * and tell caller to start over.
733  */
734  if (BufferIsValid(oldbuf) && oldblk < newblk)
735  {
737  if (!BRIN_IS_REGULAR_PAGE(BufferGetPage(oldbuf)))
738  {
740 
741  /*
742  * It is possible that the new page was obtained from
743  * extending the relation. In that case, we must be sure to
744  * record it in the FSM before leaving, because otherwise the
745  * space would be lost forever. However, we cannot let an
746  * uninitialized page get in the FSM, so we need to initialize
747  * it first.
748  */
749  if (*extended)
750  {
752  /* shouldn't matter, but don't confuse caller */
753  *extended = false;
754  }
755 
756  if (extensionLockHeld)
758 
759  ReleaseBuffer(buf);
760  return InvalidBuffer;
761  }
762  }
763 
765 
766  if (extensionLockHeld)
768 
769  page = BufferGetPage(buf);
770 
771  /*
772  * We have a new buffer to insert into. Check that the new page has
773  * enough free space, and return it if it does; otherwise start over.
774  * Note that we allow for the FSM to be out of date here, and in that
775  * case we update it and move on.
776  *
777  * (br_page_get_freespace also checks that the FSM didn't hand us a
778  * page that has since been repurposed for the revmap.)
779  */
780  freespace = *extended ?
782  if (freespace >= itemsz)
783  {
785 
786  /*
787  * Since the target block specification can get lost on cache
788  * invalidations, make sure we update the more permanent FSM with
789  * data about it before going away.
790  */
791  if (*extended)
793  freespace);
794 
795  /*
796  * Lock the old buffer if not locked already. Note that in this
797  * case we know for sure it's a regular page: it's later than the
798  * new page we just got, which is not a revmap page, and revmap
799  * pages are always consecutive.
800  */
801  if (BufferIsValid(oldbuf) && oldblk > newblk)
802  {
805  }
806 
807  return buf;
808  }
809 
810  /* This page is no good. */
811 
812  /*
813  * If an entirely new page does not contain enough free space for the
814  * new item, then surely that item is oversized. Complain loudly; but
815  * first make sure we initialize the page and record it as free, for
816  * next time.
817  */
818  if (*extended)
819  {
821 
822  ereport(ERROR,
823  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
824  errmsg("index row size %zu exceeds maximum %zu for index \"%s\"",
825  itemsz, freespace, RelationGetRelationName(irel))));
826  return InvalidBuffer; /* keep compiler quiet */
827  }
828 
829  if (newblk != oldblk)
830  UnlockReleaseBuffer(buf);
831  if (BufferIsValid(oldbuf) && oldblk <= newblk)
833 
834  newblk = RecordAndGetPageWithFreeSpace(irel, newblk, freespace, itemsz);
835  }
836 }
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
#define BRIN_elog(args)
Definition: brin_internal.h:81
void RecordPageWithFreeSpace(Relation rel, BlockNumber heapBlk, Size spaceAvail)
Definition: freespace.c:181
#define ExclusiveLock
Definition: lockdefs.h:44
#define RELATION_IS_LOCAL(relation)
Definition: rel.h:523
#define InvalidBuffer
Definition: buf.h:25
int errcode(int sqlerrcode)
Definition: elog.c:575
#define BRIN_IS_REGULAR_PAGE(page)
Definition: brin_page.h:57
uint32 BlockNumber
Definition: block.h:31
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3309
#define P_NEW
Definition: bufmgr.h:82
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:89
#define RelationGetTargetBlock(relation)
Definition: rel.h:488
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
#define ERROR
Definition: elog.h:43
#define DEBUG2
Definition: elog.h:24
static char * buf
Definition: pg_test_fsync.c:66
static Size br_page_get_freespace(Page page)
Definition: brin_pageops.c:882
#define RelationGetRelationName(relation)
Definition: rel.h:436
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define ereport(elevel, rest)
Definition: elog.h:122
void LockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:332
void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:382
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
#define BrinMaxItemSize
Definition: brin_pageops.c:30
#define Assert(condition)
Definition: c.h:676
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:594
#define RelationSetTargetBlock(relation, targblock)
Definition: rel.h:495
size_t Size
Definition: c.h:356
#define InvalidBlockNumber
Definition: block.h:33
static void brin_initialize_empty_new_buffer(Relation idxrel, Buffer buffer)
Definition: brin_pageops.c:850
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:2605
int errmsg(const char *fmt,...)
Definition: elog.c:797
BlockNumber GetPageWithFreeSpace(Relation rel, Size spaceNeeded)
Definition: freespace.c:132
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:98
BlockNumber RecordAndGetPageWithFreeSpace(Relation rel, BlockNumber oldPage, Size oldSpaceAvail, Size spaceNeeded)
Definition: freespace.c:149
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
static void brin_initialize_empty_new_buffer ( Relation  idxrel,
Buffer  buffer 
)
static

Definition at line 850 of file brin_pageops.c.

References br_page_get_freespace(), BRIN_elog, brin_page_init(), BRIN_PAGETYPE_REGULAR, BufferGetBlockNumber(), BufferGetPage, DEBUG2, END_CRIT_SECTION, log_newpage_buffer(), MarkBufferDirty(), RecordPageWithFreeSpace(), and START_CRIT_SECTION.

Referenced by brin_doupdate(), brin_getinsertbuffer(), and brin_page_cleanup().

851 {
852  Page page;
853 
854  BRIN_elog((DEBUG2,
855  "brin_initialize_empty_new_buffer: initializing blank page %u",
857 
859  page = BufferGetPage(buffer);
862  log_newpage_buffer(buffer, true);
864 
865  /*
866  * We update the FSM for this page, but this is not WAL-logged. This is
867  * acceptable because VACUUM will scan the index and update the FSM with
868  * pages whose FSM records were forgotten in a crash.
869  */
871  br_page_get_freespace(page));
872 }
#define BRIN_elog(args)
Definition: brin_internal.h:81
XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std)
Definition: xloginsert.c:1009
void RecordPageWithFreeSpace(Relation rel, BlockNumber heapBlk, Size spaceAvail)
Definition: freespace.c:181
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:1450
#define END_CRIT_SECTION()
Definition: miscadmin.h:133
#define START_CRIT_SECTION()
Definition: miscadmin.h:131
#define BRIN_PAGETYPE_REGULAR
Definition: brin_page.h:53
#define DEBUG2
Definition: elog.h:24
static Size br_page_get_freespace(Page page)
Definition: brin_pageops.c:882
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:2605
Pointer Page
Definition: bufpage.h:74
void brin_page_init(Page page, uint16 type)
Definition: brin_pageops.c:465
void brin_metapage_init ( Page  page,
BlockNumber  pagesPerRange,
uint16  version 
)

Definition at line 476 of file brin_pageops.c.

References BRIN_META_MAGIC, brin_page_init(), BRIN_PAGETYPE_META, BrinMetaPageData::brinMagic, BrinMetaPageData::brinVersion, BrinMetaPageData::lastRevmapPage, PageGetContents, and BrinMetaPageData::pagesPerRange.

Referenced by brin_xlog_createidx(), brinbuild(), and brinbuildempty().

477 {
478  BrinMetaPageData *metadata;
479 
481 
482  metadata = (BrinMetaPageData *) PageGetContents(page);
483 
484  metadata->brinMagic = BRIN_META_MAGIC;
485  metadata->brinVersion = version;
486  metadata->pagesPerRange = pagesPerRange;
487 
488  /*
489  * Note we cheat here a little. 0 is not a valid revmap block number
490  * (because it's the metapage buffer), but doing this enables the first
491  * revmap page to be created when the index is.
492  */
493  metadata->lastRevmapPage = 0;
494 }
uint32 brinVersion
Definition: brin_page.h:67
uint32 brinMagic
Definition: brin_page.h:66
#define BRIN_PAGETYPE_META
Definition: brin_page.h:51
BlockNumber lastRevmapPage
Definition: brin_page.h:69
#define PageGetContents(page)
Definition: bufpage.h:242
BlockNumber pagesPerRange
Definition: brin_page.h:68
void brin_page_init(Page page, uint16 type)
Definition: brin_pageops.c:465
#define BRIN_META_MAGIC
Definition: brin_page.h:73
bool brin_page_cleanup ( Relation  idxrel,
Buffer  buf 
)

Definition at line 595 of file brin_pageops.c.

References br_page_get_freespace(), brin_initialize_empty_new_buffer(), BRIN_IS_META_PAGE, BRIN_IS_REVMAP_PAGE, BUFFER_LOCK_EXCLUSIVE, BUFFER_LOCK_UNLOCK, BufferGetBlockNumber(), BufferGetPage, GetRecordedFreeSpace(), LockBuffer(), LockRelationForExtension(), PageIsNew, RecordPageWithFreeSpace(), ShareLock, and UnlockRelationForExtension().

Referenced by brin_vacuum_scan().

596 {
597  Page page = BufferGetPage(buf);
598  Size freespace;
599 
600  /*
601  * If a page was left uninitialized, initialize it now; also record it in
602  * FSM.
603  *
604  * Somebody else might be extending the relation concurrently. To avoid
605  * re-initializing the page before they can grab the buffer lock, we
606  * acquire the extension lock momentarily. Since they hold the extension
607  * lock from before getting the page and after its been initialized, we're
608  * sure to see their initialization.
609  */
610  if (PageIsNew(page))
611  {
614 
616  if (PageIsNew(page))
617  {
620  return true;
621  }
623  }
624 
625  /* Nothing to be done for non-regular index pages */
628  return false;
629 
630  /* Measure free space and record it */
631  freespace = br_page_get_freespace(page);
632  if (freespace > GetRecordedFreeSpace(idxrel, BufferGetBlockNumber(buf)))
633  {
634  RecordPageWithFreeSpace(idxrel, BufferGetBlockNumber(buf), freespace);
635  return true;
636  }
637 
638  return false;
639 }
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
void RecordPageWithFreeSpace(Relation rel, BlockNumber heapBlk, Size spaceAvail)
Definition: freespace.c:181
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:89
static char * buf
Definition: pg_test_fsync.c:66
static Size br_page_get_freespace(Page page)
Definition: brin_pageops.c:882
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
void LockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:332
#define BRIN_IS_META_PAGE(page)
Definition: brin_page.h:55
Size GetRecordedFreeSpace(Relation rel, BlockNumber heapBlk)
Definition: freespace.c:270
void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:382
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
#define BRIN_IS_REVMAP_PAGE(page)
Definition: brin_page.h:56
size_t Size
Definition: c.h:356
static void brin_initialize_empty_new_buffer(Relation idxrel, Buffer buffer)
Definition: brin_pageops.c:850
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:2605
#define PageIsNew(page)
Definition: bufpage.h:225
#define ShareLock
Definition: lockdefs.h:41
Pointer Page
Definition: bufpage.h:74
void brin_page_init ( Page  page,
uint16  type 
)

Definition at line 465 of file brin_pageops.c.

References BrinPageType, and PageInit().

Referenced by brin_doinsert(), brin_doupdate(), brin_initialize_empty_new_buffer(), brin_metapage_init(), brin_xlog_insert_update(), brin_xlog_revmap_extend(), and revmap_physical_extend().

466 {
467  PageInit(page, BLCKSZ, sizeof(BrinSpecialSpace));
468 
469  BrinPageType(page) = type;
470 }
#define BrinPageType(page)
Definition: brin_page.h:42
void PageInit(Page page, Size pageSize, Size specialSize)
Definition: bufpage.c:41
bool brin_start_evacuating_page ( Relation  idxRel,
Buffer  buf 
)

Definition at line 506 of file brin_pageops.c.

References BRIN_EVACUATE_PAGE, BrinPageFlags, BufferGetPage, FirstOffsetNumber, ItemIdIsUsed, MarkBufferDirtyHint(), PageGetItemId, PageGetMaxOffsetNumber, and PageIsNew.

Referenced by revmap_physical_extend().

507 {
508  OffsetNumber off;
509  OffsetNumber maxoff;
510  Page page;
511 
512  page = BufferGetPage(buf);
513 
514  if (PageIsNew(page))
515  return false;
516 
517  maxoff = PageGetMaxOffsetNumber(page);
518  for (off = FirstOffsetNumber; off <= maxoff; off++)
519  {
520  ItemId lp;
521 
522  lp = PageGetItemId(page, off);
523  if (ItemIdIsUsed(lp))
524  {
525  /* prevent other backends from adding more stuff to this page */
527  MarkBufferDirtyHint(buf, true);
528 
529  return true;
530  }
531  }
532  return false;
533 }
void MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
Definition: bufmgr.c:3379
#define ItemIdIsUsed(itemId)
Definition: itemid.h:91
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:353
uint16 OffsetNumber
Definition: off.h:24
static char * buf
Definition: pg_test_fsync.c:66
#define FirstOffsetNumber
Definition: off.h:27
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:231
#define PageIsNew(page)
Definition: bufpage.h:225
#define BRIN_EVACUATE_PAGE
Definition: brin_page.h:60
#define BrinPageFlags(page)
Definition: brin_page.h:46
Pointer Page
Definition: bufpage.h:74