PostgreSQL Source Code  git master
hashinsert.c File Reference
#include "postgres.h"
#include "access/hash.h"
#include "access/hash_xlog.h"
#include "access/heapam.h"
#include "miscadmin.h"
#include "utils/rel.h"
#include "storage/lwlock.h"
#include "storage/buf_internals.h"
#include "storage/predicate.h"
Include dependency graph for hashinsert.c:

Go to the source code of this file.

Functions

static void _hash_vacuum_one_page (Relation rel, Buffer metabuf, Buffer buf, RelFileNode hnode)
 
void _hash_doinsert (Relation rel, IndexTuple itup, Relation heapRel)
 
OffsetNumber _hash_pgaddtup (Relation rel, Buffer buf, Size itemsize, IndexTuple itup)
 
void _hash_pgaddmultitup (Relation rel, Buffer buf, IndexTuple *itups, OffsetNumber *itup_offsets, uint16 nitups)
 

Function Documentation

◆ _hash_doinsert()

void _hash_doinsert ( Relation  rel,
IndexTuple  itup,
Relation  heapRel 
)

Definition at line 37 of file hashinsert.c.

References _hash_addovflpage(), _hash_dropbuf(), _hash_expandtable(), _hash_finish_split(), _hash_get_indextuple_hashkey(), _hash_getbucketbuf_from_hashkey(), _hash_getbuf(), _hash_pgaddtup(), _hash_relbuf(), _hash_vacuum_one_page(), Assert, BlockNumberIsValid, buf, BUFFER_LOCK_EXCLUSIVE, BUFFER_LOCK_UNLOCK, BufferGetPage, CheckForSerializableConflictIn(), END_CRIT_SECTION, ereport, errcode(), errhint(), errmsg(), ERROR, H_BUCKET_BEING_SPLIT, H_HAS_DEAD_TUPLES, HASH_METAPAGE, HASH_NOLOCK, HASH_WRITE, HashMetaPageData::hashm_ffactor, HashMetaPageData::hashm_highmask, HashMetaPageData::hashm_lowmask, HashMetaPageData::hashm_maxbucket, HashMetaPageData::hashm_ntuples, HashMaxItemSize, HashPageOpaqueData::hasho_bucket, HashPageOpaqueData::hasho_flag, HashPageOpaqueData::hasho_nextblkno, HashPageGetMeta, IndexTupleSize, InvalidBuffer, IsBufferCleanupOK(), LH_META_PAGE, LH_OVERFLOW_PAGE, LH_PAGE_TYPE, LockBuffer(), MarkBufferDirty(), MAXALIGN, xl_hash_insert::offnum, PageGetFreeSpace(), PageGetSpecialPointer, PageSetLSN, RelationData::rd_node, REGBUF_STANDARD, RelationNeedsWAL, SizeOfHashInsert, START_CRIT_SECTION, XLOG_HASH_INSERT, XLogBeginInsert(), XLogInsert(), XLogRegisterBufData(), XLogRegisterBuffer(), and XLogRegisterData().

Referenced by _h_indexbuild(), hashbuildCallback(), and hashinsert().

38 {
40  Buffer bucket_buf;
41  Buffer metabuf;
42  HashMetaPage metap;
43  HashMetaPage usedmetap = NULL;
44  Page metapage;
45  Page page;
46  HashPageOpaque pageopaque;
47  Size itemsz;
48  bool do_expand;
49  uint32 hashkey;
50  Bucket bucket;
51  OffsetNumber itup_off;
52 
53  /*
54  * Get the hash key for the item (it's stored in the index tuple itself).
55  */
56  hashkey = _hash_get_indextuple_hashkey(itup);
57 
58  /* compute item size too */
59  itemsz = IndexTupleSize(itup);
60  itemsz = MAXALIGN(itemsz); /* be safe, PageAddItem will do this but we
61  * need to be consistent */
62 
63 restart_insert:
64 
65  /*
66  * Read the metapage. We don't lock it yet; HashMaxItemSize() will
67  * examine pd_pagesize_version, but that can't change so we can examine it
68  * without a lock.
69  */
71  metapage = BufferGetPage(metabuf);
72 
73  /*
74  * Check whether the item can fit on a hash page at all. (Eventually, we
75  * ought to try to apply TOAST methods if not.) Note that at this point,
76  * itemsz doesn't include the ItemId.
77  *
78  * XXX this is useless code if we are only storing hash keys.
79  */
80  if (itemsz > HashMaxItemSize(metapage))
81  ereport(ERROR,
82  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
83  errmsg("index row size %zu exceeds hash maximum %zu",
84  itemsz, HashMaxItemSize(metapage)),
85  errhint("Values larger than a buffer page cannot be indexed.")));
86 
87  /* Lock the primary bucket page for the target bucket. */
88  buf = _hash_getbucketbuf_from_hashkey(rel, hashkey, HASH_WRITE,
89  &usedmetap);
90  Assert(usedmetap != NULL);
91 
92  CheckForSerializableConflictIn(rel, NULL, buf);
93 
94  /* remember the primary bucket buffer to release the pin on it at end. */
95  bucket_buf = buf;
96 
97  page = BufferGetPage(buf);
98  pageopaque = (HashPageOpaque) PageGetSpecialPointer(page);
99  bucket = pageopaque->hasho_bucket;
100 
101  /*
102  * If this bucket is in the process of being split, try to finish the
103  * split before inserting, because that might create room for the
104  * insertion to proceed without allocating an additional overflow page.
105  * It's only interesting to finish the split if we're trying to insert
106  * into the bucket from which we're removing tuples (the "old" bucket),
107  * not if we're trying to insert into the bucket into which tuples are
108  * being moved (the "new" bucket).
109  */
110  if (H_BUCKET_BEING_SPLIT(pageopaque) && IsBufferCleanupOK(buf))
111  {
112  /* release the lock on bucket buffer, before completing the split. */
114 
115  _hash_finish_split(rel, metabuf, buf, bucket,
116  usedmetap->hashm_maxbucket,
117  usedmetap->hashm_highmask,
118  usedmetap->hashm_lowmask);
119 
120  /* release the pin on old and meta buffer. retry for insert. */
121  _hash_dropbuf(rel, buf);
122  _hash_dropbuf(rel, metabuf);
123  goto restart_insert;
124  }
125 
126  /* Do the insertion */
127  while (PageGetFreeSpace(page) < itemsz)
128  {
129  BlockNumber nextblkno;
130 
131  /*
132  * Check if current page has any DEAD tuples. If yes, delete these
133  * tuples and see if we can get a space for the new item to be
134  * inserted before moving to the next page in the bucket chain.
135  */
136  if (H_HAS_DEAD_TUPLES(pageopaque))
137  {
138 
139  if (IsBufferCleanupOK(buf))
140  {
141  _hash_vacuum_one_page(rel, metabuf, buf, heapRel->rd_node);
142 
143  if (PageGetFreeSpace(page) >= itemsz)
144  break; /* OK, now we have enough space */
145  }
146  }
147 
148  /*
149  * no space on this page; check for an overflow page
150  */
151  nextblkno = pageopaque->hasho_nextblkno;
152 
153  if (BlockNumberIsValid(nextblkno))
154  {
155  /*
156  * ovfl page exists; go get it. if it doesn't have room, we'll
157  * find out next pass through the loop test above. we always
158  * release both the lock and pin if this is an overflow page, but
159  * only the lock if this is the primary bucket page, since the pin
160  * on the primary bucket must be retained throughout the scan.
161  */
162  if (buf != bucket_buf)
163  _hash_relbuf(rel, buf);
164  else
166  buf = _hash_getbuf(rel, nextblkno, HASH_WRITE, LH_OVERFLOW_PAGE);
167  page = BufferGetPage(buf);
168  }
169  else
170  {
171  /*
172  * we're at the end of the bucket chain and we haven't found a
173  * page with enough room. allocate a new overflow page.
174  */
175 
176  /* release our write lock without modifying buffer */
178 
179  /* chain to a new overflow page */
180  buf = _hash_addovflpage(rel, metabuf, buf, (buf == bucket_buf) ? true : false);
181  page = BufferGetPage(buf);
182 
183  /* should fit now, given test above */
184  Assert(PageGetFreeSpace(page) >= itemsz);
185  }
186  pageopaque = (HashPageOpaque) PageGetSpecialPointer(page);
187  Assert((pageopaque->hasho_flag & LH_PAGE_TYPE) == LH_OVERFLOW_PAGE);
188  Assert(pageopaque->hasho_bucket == bucket);
189  }
190 
191  /*
192  * Write-lock the metapage so we can increment the tuple count. After
193  * incrementing it, check to see if it's time for a split.
194  */
196 
197  /* Do the update. No ereport(ERROR) until changes are logged */
199 
200  /* found page with enough space, so add the item here */
201  itup_off = _hash_pgaddtup(rel, buf, itemsz, itup);
202  MarkBufferDirty(buf);
203 
204  /* metapage operations */
205  metap = HashPageGetMeta(metapage);
206  metap->hashm_ntuples += 1;
207 
208  /* Make sure this stays in sync with _hash_expandtable() */
209  do_expand = metap->hashm_ntuples >
210  (double) metap->hashm_ffactor * (metap->hashm_maxbucket + 1);
211 
212  MarkBufferDirty(metabuf);
213 
214  /* XLOG stuff */
215  if (RelationNeedsWAL(rel))
216  {
217  xl_hash_insert xlrec;
218  XLogRecPtr recptr;
219 
220  xlrec.offnum = itup_off;
221 
222  XLogBeginInsert();
223  XLogRegisterData((char *) &xlrec, SizeOfHashInsert);
224 
225  XLogRegisterBuffer(1, metabuf, REGBUF_STANDARD);
226 
228  XLogRegisterBufData(0, (char *) itup, IndexTupleSize(itup));
229 
230  recptr = XLogInsert(RM_HASH_ID, XLOG_HASH_INSERT);
231 
232  PageSetLSN(BufferGetPage(buf), recptr);
233  PageSetLSN(BufferGetPage(metabuf), recptr);
234  }
235 
237 
238  /* drop lock on metapage, but keep pin */
239  LockBuffer(metabuf, BUFFER_LOCK_UNLOCK);
240 
241  /*
242  * Release the modified page and ensure to release the pin on primary
243  * page.
244  */
245  _hash_relbuf(rel, buf);
246  if (buf != bucket_buf)
247  _hash_dropbuf(rel, bucket_buf);
248 
249  /* Attempt to split if a split is needed */
250  if (do_expand)
251  _hash_expandtable(rel, metabuf);
252 
253  /* Finally drop our pin on the metapage */
254  _hash_dropbuf(rel, metabuf);
255 }
void XLogRegisterBufData(uint8 block_id, char *data, int len)
Definition: xloginsert.c:361
#define HashMaxItemSize(page)
Definition: hash.h:277
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
#define XLOG_HASH_INSERT
Definition: hash_xlog.h:29
int errhint(const char *fmt,...)
Definition: elog.c:987
#define LH_META_PAGE
Definition: hash.h:67
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
uint16 hashm_ffactor
Definition: hash.h:254
uint32 hashm_highmask
Definition: hash.h:260
#define InvalidBuffer
Definition: buf.h:25
#define START_CRIT_SECTION()
Definition: miscadmin.h:131
int errcode(int sqlerrcode)
Definition: elog.c:575
Buffer _hash_getbucketbuf_from_hashkey(Relation rel, uint32 hashkey, int access, HashMetaPage *cachedmetap)
Definition: hashpage.c:1567
uint32 BlockNumber
Definition: block.h:31
void _hash_dropbuf(Relation rel, Buffer buf)
Definition: hashpage.c:286
Buffer _hash_getbuf(Relation rel, BlockNumber blkno, int access, int flags)
Definition: hashpage.c:79
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:89
uint32 hashm_lowmask
Definition: hash.h:261
void CheckForSerializableConflictIn(Relation relation, HeapTuple tuple, Buffer buffer)
Definition: predicate.c:4280
Size PageGetFreeSpace(Page page)
Definition: bufpage.c:578
uint16 OffsetNumber
Definition: off.h:24
#define LH_PAGE_TYPE
Definition: hash.h:73
uint32 Bucket
Definition: hash.h:34
#define SizeOfHashInsert
Definition: hash_xlog.h:80
#define ERROR
Definition: elog.h:43
uint32 _hash_get_indextuple_hashkey(IndexTuple itup)
Definition: hashutil.c:299
void _hash_finish_split(Relation rel, Buffer metabuf, Buffer obuf, Bucket obucket, uint32 maxbucket, uint32 highmask, uint32 lowmask)
Definition: hashpage.c:1363
static char * buf
Definition: pg_test_fsync.c:67
#define HASH_WRITE
Definition: hash.h:330
#define HASH_NOLOCK
Definition: hash.h:331
#define REGBUF_STANDARD
Definition: xloginsert.h:34
unsigned int uint32
Definition: c.h:325
void _hash_expandtable(Relation rel, Buffer metabuf)
Definition: hashpage.c:626
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define ereport(elevel, rest)
Definition: elog.h:122
bool IsBufferCleanupOK(Buffer buffer)
Definition: bufmgr.c:3774
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
#define HASH_METAPAGE
Definition: hash.h:206
double hashm_ntuples
Definition: hash.h:253
#define LH_OVERFLOW_PAGE
Definition: hash.h:64
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
void _hash_relbuf(Relation rel, Buffer buf)
Definition: hashpage.c:275
#define BlockNumberIsValid(blockNumber)
Definition: block.h:70
#define H_BUCKET_BEING_SPLIT(opaque)
Definition: hash.h:99
RelFileNode rd_node
Definition: rel.h:55
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:699
Bucket hasho_bucket
Definition: hash.h:91
size_t Size
Definition: c.h:433
#define PageGetSpecialPointer(page)
Definition: bufpage.h:322
HashPageOpaqueData * HashPageOpaque
Definition: hash.h:96
OffsetNumber offnum
Definition: hash_xlog.h:77
Buffer _hash_addovflpage(Relation rel, Buffer metabuf, Buffer buf, bool retain_pin)
Definition: hashovfl.c:111
#define MAXALIGN(LEN)
Definition: c.h:652
#define RelationNeedsWAL(relation)
Definition: rel.h:510
uint32 hashm_maxbucket
Definition: hash.h:259
OffsetNumber _hash_pgaddtup(Relation rel, Buffer buf, Size itemsize, IndexTuple itup)
Definition: hashinsert.c:269
static void _hash_vacuum_one_page(Relation rel, Buffer metabuf, Buffer buf, RelFileNode hnode)
Definition: hashinsert.c:339
uint16 hasho_flag
Definition: hash.h:92
#define HashPageGetMeta(page)
Definition: hash.h:313
int errmsg(const char *fmt,...)
Definition: elog.c:797
BlockNumber hasho_nextblkno
Definition: hash.h:90
void XLogBeginInsert(void)
Definition: xloginsert.c:120
#define PageSetLSN(page, lsn)
Definition: bufpage.h:364
int Buffer
Definition: buf.h:23
#define H_HAS_DEAD_TUPLES(opaque)
Definition: hash.h:101
Pointer Page
Definition: bufpage.h:74
#define IndexTupleSize(itup)
Definition: itup.h:71

◆ _hash_pgaddmultitup()

void _hash_pgaddmultitup ( Relation  rel,
Buffer  buf,
IndexTuple itups,
OffsetNumber itup_offsets,
uint16  nitups 
)

Definition at line 300 of file hashinsert.c.

References _hash_binsearch(), _hash_checkpage(), _hash_get_indextuple_hashkey(), BufferGetPage, elog, ERROR, i, IndexTupleSize, InvalidOffsetNumber, LH_BUCKET_PAGE, LH_OVERFLOW_PAGE, MAXALIGN, PageAddItem, and RelationGetRelationName.

Referenced by _hash_freeovflpage(), _hash_splitbucket(), and _hash_squeezebucket().

302 {
303  OffsetNumber itup_off;
304  Page page;
305  uint32 hashkey;
306  int i;
307 
309  page = BufferGetPage(buf);
310 
311  for (i = 0; i < nitups; i++)
312  {
313  Size itemsize;
314 
315  itemsize = IndexTupleSize(itups[i]);
316  itemsize = MAXALIGN(itemsize);
317 
318  /* Find where to insert the tuple (preserving page's hashkey ordering) */
319  hashkey = _hash_get_indextuple_hashkey(itups[i]);
320  itup_off = _hash_binsearch(page, hashkey);
321 
322  itup_offsets[i] = itup_off;
323 
324  if (PageAddItem(page, (Item) itups[i], itemsize, itup_off, false, false)
326  elog(ERROR, "failed to add index item to \"%s\"",
328  }
329 }
Pointer Item
Definition: item.h:17
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
Definition: bufpage.h:412
uint16 OffsetNumber
Definition: off.h:24
#define ERROR
Definition: elog.h:43
uint32 _hash_get_indextuple_hashkey(IndexTuple itup)
Definition: hashutil.c:299
static char * buf
Definition: pg_test_fsync.c:67
#define RelationGetRelationName(relation)
Definition: rel.h:441
unsigned int uint32
Definition: c.h:325
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
void _hash_checkpage(Relation rel, Buffer buf, int flags)
Definition: hashutil.c:225
#define LH_OVERFLOW_PAGE
Definition: hash.h:64
#define InvalidOffsetNumber
Definition: off.h:26
OffsetNumber _hash_binsearch(Page page, uint32 hash_value)
Definition: hashutil.c:358
#define LH_BUCKET_PAGE
Definition: hash.h:65
size_t Size
Definition: c.h:433
#define MAXALIGN(LEN)
Definition: c.h:652
int i
#define elog
Definition: elog.h:219
Pointer Page
Definition: bufpage.h:74
#define IndexTupleSize(itup)
Definition: itup.h:71

◆ _hash_pgaddtup()

OffsetNumber _hash_pgaddtup ( Relation  rel,
Buffer  buf,
Size  itemsize,
IndexTuple  itup 
)

Definition at line 269 of file hashinsert.c.

References _hash_binsearch(), _hash_checkpage(), _hash_get_indextuple_hashkey(), BufferGetPage, elog, ERROR, InvalidOffsetNumber, LH_BUCKET_PAGE, LH_OVERFLOW_PAGE, PageAddItem, and RelationGetRelationName.

Referenced by _hash_doinsert().

270 {
271  OffsetNumber itup_off;
272  Page page;
273  uint32 hashkey;
274 
276  page = BufferGetPage(buf);
277 
278  /* Find where to insert the tuple (preserving page's hashkey ordering) */
279  hashkey = _hash_get_indextuple_hashkey(itup);
280  itup_off = _hash_binsearch(page, hashkey);
281 
282  if (PageAddItem(page, (Item) itup, itemsize, itup_off, false, false)
284  elog(ERROR, "failed to add index item to \"%s\"",
286 
287  return itup_off;
288 }
Pointer Item
Definition: item.h:17
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
Definition: bufpage.h:412
uint16 OffsetNumber
Definition: off.h:24
#define ERROR
Definition: elog.h:43
uint32 _hash_get_indextuple_hashkey(IndexTuple itup)
Definition: hashutil.c:299
static char * buf
Definition: pg_test_fsync.c:67
#define RelationGetRelationName(relation)
Definition: rel.h:441
unsigned int uint32
Definition: c.h:325
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
void _hash_checkpage(Relation rel, Buffer buf, int flags)
Definition: hashutil.c:225
#define LH_OVERFLOW_PAGE
Definition: hash.h:64
#define InvalidOffsetNumber
Definition: off.h:26
OffsetNumber _hash_binsearch(Page page, uint32 hash_value)
Definition: hashutil.c:358
#define LH_BUCKET_PAGE
Definition: hash.h:65
#define elog
Definition: elog.h:219
Pointer Page
Definition: bufpage.h:74

◆ _hash_vacuum_one_page()

static void _hash_vacuum_one_page ( Relation  rel,
Buffer  metabuf,
Buffer  buf,
RelFileNode  hnode 
)
static

Definition at line 339 of file hashinsert.c.

References BUFFER_LOCK_EXCLUSIVE, BUFFER_LOCK_UNLOCK, BufferGetPage, END_CRIT_SECTION, FirstOffsetNumber, HashMetaPageData::hashm_ntuples, HashPageOpaqueData::hasho_flag, HashPageGetMeta, xl_hash_vacuum_one_page::hnode, ItemIdIsDead, LH_PAGE_HAS_DEAD_TUPLES, LockBuffer(), MarkBufferDirty(), MaxOffsetNumber, xl_hash_vacuum_one_page::ntuples, OffsetNumberNext, PageGetItemId, PageGetMaxOffsetNumber, PageGetSpecialPointer, PageIndexMultiDelete(), PageSetLSN, REGBUF_STANDARD, RelationNeedsWAL, SizeOfHashVacuumOnePage, START_CRIT_SECTION, XLOG_HASH_VACUUM_ONE_PAGE, XLogBeginInsert(), XLogInsert(), XLogRegisterBuffer(), and XLogRegisterData().

Referenced by _hash_doinsert().

341 {
342  OffsetNumber deletable[MaxOffsetNumber];
343  int ndeletable = 0;
344  OffsetNumber offnum,
345  maxoff;
346  Page page = BufferGetPage(buf);
347  HashPageOpaque pageopaque;
348  HashMetaPage metap;
349 
350  /* Scan each tuple in page to see if it is marked as LP_DEAD */
351  maxoff = PageGetMaxOffsetNumber(page);
352  for (offnum = FirstOffsetNumber;
353  offnum <= maxoff;
354  offnum = OffsetNumberNext(offnum))
355  {
356  ItemId itemId = PageGetItemId(page, offnum);
357 
358  if (ItemIdIsDead(itemId))
359  deletable[ndeletable++] = offnum;
360  }
361 
362  if (ndeletable > 0)
363  {
364  /*
365  * Write-lock the meta page so that we can decrement tuple count.
366  */
368 
369  /* No ereport(ERROR) until changes are logged */
371 
372  PageIndexMultiDelete(page, deletable, ndeletable);
373 
374  /*
375  * Mark the page as not containing any LP_DEAD items. This is not
376  * certainly true (there might be some that have recently been marked,
377  * but weren't included in our target-item list), but it will almost
378  * always be true and it doesn't seem worth an additional page scan to
379  * check it. Remember that LH_PAGE_HAS_DEAD_TUPLES is only a hint
380  * anyway.
381  */
382  pageopaque = (HashPageOpaque) PageGetSpecialPointer(page);
383  pageopaque->hasho_flag &= ~LH_PAGE_HAS_DEAD_TUPLES;
384 
385  metap = HashPageGetMeta(BufferGetPage(metabuf));
386  metap->hashm_ntuples -= ndeletable;
387 
389  MarkBufferDirty(metabuf);
390 
391  /* XLOG stuff */
392  if (RelationNeedsWAL(rel))
393  {
395  XLogRecPtr recptr;
396 
397  xlrec.hnode = hnode;
398  xlrec.ntuples = ndeletable;
399 
400  XLogBeginInsert();
402  XLogRegisterData((char *) &xlrec, SizeOfHashVacuumOnePage);
403 
404  /*
405  * We need the target-offsets array whether or not we store the
406  * whole buffer, to allow us to find the latestRemovedXid on a
407  * standby server.
408  */
409  XLogRegisterData((char *) deletable,
410  ndeletable * sizeof(OffsetNumber));
411 
412  XLogRegisterBuffer(1, metabuf, REGBUF_STANDARD);
413 
414  recptr = XLogInsert(RM_HASH_ID, XLOG_HASH_VACUUM_ONE_PAGE);
415 
416  PageSetLSN(BufferGetPage(buf), recptr);
417  PageSetLSN(BufferGetPage(metabuf), recptr);
418  }
419 
421 
422  /*
423  * Releasing write lock on meta page as we have updated the tuple
424  * count.
425  */
426  LockBuffer(metabuf, BUFFER_LOCK_UNLOCK);
427  }
428 }
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:1450
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
Definition: xloginsert.c:213
#define MaxOffsetNumber
Definition: off.h:28
#define END_CRIT_SECTION()
Definition: miscadmin.h:133
#define START_CRIT_SECTION()
Definition: miscadmin.h:131
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:89
#define ItemIdIsDead(itemId)
Definition: itemid.h:112
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:353
uint16 OffsetNumber
Definition: off.h:24
static char * buf
Definition: pg_test_fsync.c:67
#define FirstOffsetNumber
Definition: off.h:27
#define REGBUF_STANDARD
Definition: xloginsert.h:34
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:231
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
#define SizeOfHashVacuumOnePage
Definition: hash_xlog.h:272
double hashm_ntuples
Definition: hash.h:253
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
#define XLOG_HASH_VACUUM_ONE_PAGE
Definition: hash_xlog.h:45
uint64 XLogRecPtr
Definition: xlogdefs.h:21
void PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
Definition: bufpage.c:832
#define OffsetNumberNext(offsetNumber)
Definition: off.h:53
#define PageGetSpecialPointer(page)
Definition: bufpage.h:322
HashPageOpaqueData * HashPageOpaque
Definition: hash.h:96
#define RelationNeedsWAL(relation)
Definition: rel.h:510
uint16 hasho_flag
Definition: hash.h:92
#define HashPageGetMeta(page)
Definition: hash.h:313
void XLogBeginInsert(void)
Definition: xloginsert.c:120
#define PageSetLSN(page, lsn)
Definition: bufpage.h:364
#define LH_PAGE_HAS_DEAD_TUPLES
Definition: hash.h:71
Pointer Page
Definition: bufpage.h:74