PostgreSQL Source Code  git master
brin_xlog.c File Reference
#include "postgres.h"
#include "access/brin_page.h"
#include "access/brin_pageops.h"
#include "access/brin_xlog.h"
#include "access/bufmask.h"
#include "access/xlogutils.h"
Include dependency graph for brin_xlog.c:

Go to the source code of this file.

Functions

static void brin_xlog_createidx (XLogReaderState *record)
 
static void brin_xlog_insert_update (XLogReaderState *record, xl_brin_insert *xlrec)
 
static void brin_xlog_insert (XLogReaderState *record)
 
static void brin_xlog_update (XLogReaderState *record)
 
static void brin_xlog_samepage_update (XLogReaderState *record)
 
static void brin_xlog_revmap_extend (XLogReaderState *record)
 
static void brin_xlog_desummarize_page (XLogReaderState *record)
 
void brin_redo (XLogReaderState *record)
 
void brin_mask (char *pagedata, BlockNumber blkno)
 

Function Documentation

◆ brin_mask()

void brin_mask ( char *  pagedata,
BlockNumber  blkno 
)

Definition at line 342 of file brin_xlog.c.

343 {
344  Page page = (Page) pagedata;
345  PageHeader pagehdr = (PageHeader) page;
346 
348 
349  mask_page_hint_bits(page);
350 
351  /*
352  * Regular brin pages contain unused space which needs to be masked.
353  * Similarly for meta pages, but mask it only if pd_lower appears to have
354  * been set correctly.
355  */
356  if (BRIN_IS_REGULAR_PAGE(page) ||
357  (BRIN_IS_META_PAGE(page) && pagehdr->pd_lower > SizeOfPageHeaderData))
358  {
359  mask_unused_space(page);
360  }
361 
362  /*
363  * BRIN_EVACUATE_PAGE is not WAL-logged, since it's of no use in recovery.
364  * Mask it. See brin_start_evacuating_page() for details.
365  */
367 }
#define BRIN_IS_META_PAGE(page)
Definition: brin_page.h:55
#define BrinPageFlags(page)
Definition: brin_page.h:46
#define BRIN_EVACUATE_PAGE
Definition: brin_page.h:60
#define BRIN_IS_REGULAR_PAGE(page)
Definition: brin_page.h:57
void mask_page_lsn_and_checksum(Page page)
Definition: bufmask.c:31
void mask_unused_space(Page page)
Definition: bufmask.c:71
void mask_page_hint_bits(Page page)
Definition: bufmask.c:46
PageHeaderData * PageHeader
Definition: bufpage.h:170
Pointer Page
Definition: bufpage.h:78
#define SizeOfPageHeaderData
Definition: bufpage.h:213
LocationIndex pd_lower
Definition: bufpage.h:162

References BRIN_EVACUATE_PAGE, BRIN_IS_META_PAGE, BRIN_IS_REGULAR_PAGE, BrinPageFlags, mask_page_hint_bits(), mask_page_lsn_and_checksum(), mask_unused_space(), PageHeaderData::pd_lower, and SizeOfPageHeaderData.

◆ brin_redo()

void brin_redo ( XLogReaderState record)

Definition at line 309 of file brin_xlog.c.

310 {
311  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
312 
313  switch (info & XLOG_BRIN_OPMASK)
314  {
316  brin_xlog_createidx(record);
317  break;
318  case XLOG_BRIN_INSERT:
319  brin_xlog_insert(record);
320  break;
321  case XLOG_BRIN_UPDATE:
322  brin_xlog_update(record);
323  break;
326  break;
328  brin_xlog_revmap_extend(record);
329  break;
332  break;
333  default:
334  elog(PANIC, "brin_redo: unknown op code %u", info);
335  }
336 }
static void brin_xlog_desummarize_page(XLogReaderState *record)
Definition: brin_xlog.c:269
static void brin_xlog_update(XLogReaderState *record)
Definition: brin_xlog.c:135
static void brin_xlog_revmap_extend(XLogReaderState *record)
Definition: brin_xlog.c:208
static void brin_xlog_createidx(XLogReaderState *record)
Definition: brin_xlog.c:24
static void brin_xlog_insert(XLogReaderState *record)
Definition: brin_xlog.c:124
static void brin_xlog_samepage_update(XLogReaderState *record)
Definition: brin_xlog.c:170
#define XLOG_BRIN_REVMAP_EXTEND
Definition: brin_xlog.h:35
#define XLOG_BRIN_SAMEPAGE_UPDATE
Definition: brin_xlog.h:34
#define XLOG_BRIN_DESUMMARIZE
Definition: brin_xlog.h:36
#define XLOG_BRIN_CREATE_INDEX
Definition: brin_xlog.h:31
#define XLOG_BRIN_OPMASK
Definition: brin_xlog.h:38
#define XLOG_BRIN_UPDATE
Definition: brin_xlog.h:33
#define XLOG_BRIN_INSERT
Definition: brin_xlog.h:32
unsigned char uint8
Definition: c.h:504
#define PANIC
Definition: elog.h:42
#define elog(elevel,...)
Definition: elog.h:224
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:410
#define XLR_INFO_MASK
Definition: xlogrecord.h:62

References brin_xlog_createidx(), brin_xlog_desummarize_page(), brin_xlog_insert(), brin_xlog_revmap_extend(), brin_xlog_samepage_update(), brin_xlog_update(), elog, PANIC, XLOG_BRIN_CREATE_INDEX, XLOG_BRIN_DESUMMARIZE, XLOG_BRIN_INSERT, XLOG_BRIN_OPMASK, XLOG_BRIN_REVMAP_EXTEND, XLOG_BRIN_SAMEPAGE_UPDATE, XLOG_BRIN_UPDATE, XLogRecGetInfo, and XLR_INFO_MASK.

◆ brin_xlog_createidx()

static void brin_xlog_createidx ( XLogReaderState record)
static

Definition at line 24 of file brin_xlog.c.

25 {
26  XLogRecPtr lsn = record->EndRecPtr;
28  Buffer buf;
29  Page page;
30 
31  /* create the index' metapage */
32  buf = XLogInitBufferForRedo(record, 0);
34  page = (Page) BufferGetPage(buf);
35  brin_metapage_init(page, xlrec->pagesPerRange, xlrec->version);
36  PageSetLSN(page, lsn);
39 }
void brin_metapage_init(Page page, BlockNumber pagesPerRange, uint16 version)
Definition: brin_pageops.c:486
int Buffer
Definition: buf.h:23
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:4867
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:2474
static Page BufferGetPage(Buffer buffer)
Definition: bufmgr.h:408
static bool BufferIsValid(Buffer bufnum)
Definition: bufmgr.h:359
static void PageSetLSN(Page page, XLogRecPtr lsn)
Definition: bufpage.h:388
#define Assert(condition)
Definition: c.h:858
static char * buf
Definition: pg_test_fsync.c:73
XLogRecPtr EndRecPtr
Definition: xlogreader.h:207
BlockNumber pagesPerRange
Definition: brin_xlog.h:52
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define XLogRecGetData(decoder)
Definition: xlogreader.h:415
Buffer XLogInitBufferForRedo(XLogReaderState *record, uint8 block_id)
Definition: xlogutils.c:326

References Assert, brin_metapage_init(), buf, BufferGetPage(), BufferIsValid(), XLogReaderState::EndRecPtr, MarkBufferDirty(), PageSetLSN(), xl_brin_createidx::pagesPerRange, UnlockReleaseBuffer(), xl_brin_createidx::version, XLogInitBufferForRedo(), and XLogRecGetData.

Referenced by brin_redo().

◆ brin_xlog_desummarize_page()

static void brin_xlog_desummarize_page ( XLogReaderState record)
static

Definition at line 269 of file brin_xlog.c.

270 {
271  XLogRecPtr lsn = record->EndRecPtr;
272  xl_brin_desummarize *xlrec;
273  Buffer buffer;
275 
276  xlrec = (xl_brin_desummarize *) XLogRecGetData(record);
277 
278  /* Update the revmap */
279  action = XLogReadBufferForRedo(record, 0, &buffer);
280  if (action == BLK_NEEDS_REDO)
281  {
282  ItemPointerData iptr;
283 
284  ItemPointerSetInvalid(&iptr);
285  brinSetHeapBlockItemptr(buffer, xlrec->pagesPerRange, xlrec->heapBlk, iptr);
286 
287  PageSetLSN(BufferGetPage(buffer), lsn);
288  MarkBufferDirty(buffer);
289  }
290  if (BufferIsValid(buffer))
291  UnlockReleaseBuffer(buffer);
292 
293  /* remove the leftover entry from the regular page */
294  action = XLogReadBufferForRedo(record, 1, &buffer);
295  if (action == BLK_NEEDS_REDO)
296  {
297  Page regPg = BufferGetPage(buffer);
298 
300 
301  PageSetLSN(regPg, lsn);
302  MarkBufferDirty(buffer);
303  }
304  if (BufferIsValid(buffer))
305  UnlockReleaseBuffer(buffer);
306 }
void brinSetHeapBlockItemptr(Buffer buf, BlockNumber pagesPerRange, BlockNumber heapBlk, ItemPointerData tid)
Definition: brin_revmap.c:155
void PageIndexTupleDeleteNoCompact(Page page, OffsetNumber offnum)
Definition: bufpage.c:1295
static void ItemPointerSetInvalid(ItemPointerData *pointer)
Definition: itemptr.h:184
BlockNumber pagesPerRange
Definition: brin_xlog.h:135
BlockNumber heapBlk
Definition: brin_xlog.h:137
OffsetNumber regOffset
Definition: brin_xlog.h:139
XLogRedoAction XLogReadBufferForRedo(XLogReaderState *record, uint8 block_id, Buffer *buf)
Definition: xlogutils.c:314
XLogRedoAction
Definition: xlogutils.h:70
@ BLK_NEEDS_REDO
Definition: xlogutils.h:71

References generate_unaccent_rules::action, BLK_NEEDS_REDO, brinSetHeapBlockItemptr(), BufferGetPage(), BufferIsValid(), XLogReaderState::EndRecPtr, xl_brin_desummarize::heapBlk, ItemPointerSetInvalid(), MarkBufferDirty(), PageIndexTupleDeleteNoCompact(), PageSetLSN(), xl_brin_desummarize::pagesPerRange, xl_brin_desummarize::regOffset, UnlockReleaseBuffer(), XLogReadBufferForRedo(), and XLogRecGetData.

Referenced by brin_redo().

◆ brin_xlog_insert()

static void brin_xlog_insert ( XLogReaderState record)
static

Definition at line 124 of file brin_xlog.c.

125 {
126  xl_brin_insert *xlrec = (xl_brin_insert *) XLogRecGetData(record);
127 
128  brin_xlog_insert_update(record, xlrec);
129 }
static void brin_xlog_insert_update(XLogReaderState *record, xl_brin_insert *xlrec)
Definition: brin_xlog.c:46

References brin_xlog_insert_update(), and XLogRecGetData.

Referenced by brin_redo().

◆ brin_xlog_insert_update()

static void brin_xlog_insert_update ( XLogReaderState record,
xl_brin_insert xlrec 
)
static

Definition at line 46 of file brin_xlog.c.

48 {
49  XLogRecPtr lsn = record->EndRecPtr;
50  Buffer buffer;
51  BlockNumber regpgno;
52  Page page;
54 
55  /*
56  * If we inserted the first and only tuple on the page, re-initialize the
57  * page from scratch.
58  */
59  if (XLogRecGetInfo(record) & XLOG_BRIN_INIT_PAGE)
60  {
61  buffer = XLogInitBufferForRedo(record, 0);
62  page = BufferGetPage(buffer);
65  }
66  else
67  {
68  action = XLogReadBufferForRedo(record, 0, &buffer);
69  }
70 
71  /* need this page's blkno to store in revmap */
72  regpgno = BufferGetBlockNumber(buffer);
73 
74  /* insert the index item into the page */
75  if (action == BLK_NEEDS_REDO)
76  {
77  OffsetNumber offnum;
78  BrinTuple *tuple;
79  Size tuplen;
80 
81  tuple = (BrinTuple *) XLogRecGetBlockData(record, 0, &tuplen);
82 
83  Assert(tuple->bt_blkno == xlrec->heapBlk);
84 
85  page = (Page) BufferGetPage(buffer);
86  offnum = xlrec->offnum;
87  if (PageGetMaxOffsetNumber(page) + 1 < offnum)
88  elog(PANIC, "brin_xlog_insert_update: invalid max offset number");
89 
90  offnum = PageAddItem(page, (Item) tuple, tuplen, offnum, true, false);
91  if (offnum == InvalidOffsetNumber)
92  elog(PANIC, "brin_xlog_insert_update: failed to add tuple");
93 
94  PageSetLSN(page, lsn);
95  MarkBufferDirty(buffer);
96  }
97  if (BufferIsValid(buffer))
98  UnlockReleaseBuffer(buffer);
99 
100  /* update the revmap */
101  action = XLogReadBufferForRedo(record, 1, &buffer);
102  if (action == BLK_NEEDS_REDO)
103  {
104  ItemPointerData tid;
105 
106  ItemPointerSet(&tid, regpgno, xlrec->offnum);
107  page = (Page) BufferGetPage(buffer);
108 
109  brinSetHeapBlockItemptr(buffer, xlrec->pagesPerRange, xlrec->heapBlk,
110  tid);
111  PageSetLSN(page, lsn);
112  MarkBufferDirty(buffer);
113  }
114  if (BufferIsValid(buffer))
115  UnlockReleaseBuffer(buffer);
116 
117  /* XXX no FSM updates here ... */
118 }
uint32 BlockNumber
Definition: block.h:31
#define BRIN_PAGETYPE_REGULAR
Definition: brin_page.h:53
void brin_page_init(Page page, uint16 type)
Definition: brin_pageops.c:475
#define XLOG_BRIN_INIT_PAGE
Definition: brin_xlog.h:43
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:3667
static OffsetNumber PageGetMaxOffsetNumber(Page page)
Definition: bufpage.h:369
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
Definition: bufpage.h:468
size_t Size
Definition: c.h:605
Pointer Item
Definition: item.h:17
static void ItemPointerSet(ItemPointerData *pointer, BlockNumber blockNumber, OffsetNumber offNum)
Definition: itemptr.h:135
#define InvalidOffsetNumber
Definition: off.h:26
uint16 OffsetNumber
Definition: off.h:24
BlockNumber bt_blkno
Definition: brin_tuple.h:66
OffsetNumber offnum
Definition: brin_xlog.h:71
BlockNumber pagesPerRange
Definition: brin_xlog.h:68
BlockNumber heapBlk
Definition: brin_xlog.h:65
char * XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len)
Definition: xlogreader.c:2025

References generate_unaccent_rules::action, Assert, BLK_NEEDS_REDO, brin_page_init(), BRIN_PAGETYPE_REGULAR, brinSetHeapBlockItemptr(), BrinTuple::bt_blkno, BufferGetBlockNumber(), BufferGetPage(), BufferIsValid(), elog, XLogReaderState::EndRecPtr, xl_brin_insert::heapBlk, InvalidOffsetNumber, ItemPointerSet(), MarkBufferDirty(), xl_brin_insert::offnum, PageAddItem, PageGetMaxOffsetNumber(), PageSetLSN(), xl_brin_insert::pagesPerRange, PANIC, UnlockReleaseBuffer(), XLOG_BRIN_INIT_PAGE, XLogInitBufferForRedo(), XLogReadBufferForRedo(), XLogRecGetBlockData(), and XLogRecGetInfo.

Referenced by brin_xlog_insert(), and brin_xlog_update().

◆ brin_xlog_revmap_extend()

static void brin_xlog_revmap_extend ( XLogReaderState record)
static

Definition at line 208 of file brin_xlog.c.

209 {
210  XLogRecPtr lsn = record->EndRecPtr;
211  xl_brin_revmap_extend *xlrec;
212  Buffer metabuf;
213  Buffer buf;
214  Page page;
215  BlockNumber targetBlk;
217 
218  xlrec = (xl_brin_revmap_extend *) XLogRecGetData(record);
219 
220  XLogRecGetBlockTag(record, 1, NULL, NULL, &targetBlk);
221  Assert(xlrec->targetBlk == targetBlk);
222 
223  /* Update the metapage */
224  action = XLogReadBufferForRedo(record, 0, &metabuf);
225  if (action == BLK_NEEDS_REDO)
226  {
227  Page metapg;
228  BrinMetaPageData *metadata;
229 
230  metapg = BufferGetPage(metabuf);
231  metadata = (BrinMetaPageData *) PageGetContents(metapg);
232 
233  Assert(metadata->lastRevmapPage == xlrec->targetBlk - 1);
234  metadata->lastRevmapPage = xlrec->targetBlk;
235 
236  PageSetLSN(metapg, lsn);
237 
238  /*
239  * Set pd_lower just past the end of the metadata. This is essential,
240  * because without doing so, metadata will be lost if xlog.c
241  * compresses the page. (We must do this here because pre-v11
242  * versions of PG did not set the metapage's pd_lower correctly, so a
243  * pg_upgraded index might contain the wrong value.)
244  */
245  ((PageHeader) metapg)->pd_lower =
246  ((char *) metadata + sizeof(BrinMetaPageData)) - (char *) metapg;
247 
248  MarkBufferDirty(metabuf);
249  }
250 
251  /*
252  * Re-init the target block as a revmap page. There's never a full- page
253  * image here.
254  */
255 
256  buf = XLogInitBufferForRedo(record, 1);
257  page = (Page) BufferGetPage(buf);
259 
260  PageSetLSN(page, lsn);
262 
264  if (BufferIsValid(metabuf))
265  UnlockReleaseBuffer(metabuf);
266 }
#define BRIN_PAGETYPE_REVMAP
Definition: brin_page.h:52
static char * PageGetContents(Page page)
Definition: bufpage.h:254
BlockNumber lastRevmapPage
Definition: brin_page.h:69
BlockNumber targetBlk
Definition: brin_xlog.h:121
void XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id, RelFileLocator *rlocator, ForkNumber *forknum, BlockNumber *blknum)
Definition: xlogreader.c:1971

References generate_unaccent_rules::action, Assert, BLK_NEEDS_REDO, brin_page_init(), BRIN_PAGETYPE_REVMAP, buf, BufferGetPage(), BufferIsValid(), XLogReaderState::EndRecPtr, BrinMetaPageData::lastRevmapPage, MarkBufferDirty(), PageGetContents(), PageSetLSN(), xl_brin_revmap_extend::targetBlk, UnlockReleaseBuffer(), XLogInitBufferForRedo(), XLogReadBufferForRedo(), XLogRecGetBlockTag(), and XLogRecGetData.

Referenced by brin_redo().

◆ brin_xlog_samepage_update()

static void brin_xlog_samepage_update ( XLogReaderState record)
static

Definition at line 170 of file brin_xlog.c.

171 {
172  XLogRecPtr lsn = record->EndRecPtr;
174  Buffer buffer;
176 
177  xlrec = (xl_brin_samepage_update *) XLogRecGetData(record);
178  action = XLogReadBufferForRedo(record, 0, &buffer);
179  if (action == BLK_NEEDS_REDO)
180  {
181  Size tuplen;
182  BrinTuple *brintuple;
183  Page page;
184  OffsetNumber offnum;
185 
186  brintuple = (BrinTuple *) XLogRecGetBlockData(record, 0, &tuplen);
187 
188  page = (Page) BufferGetPage(buffer);
189 
190  offnum = xlrec->offnum;
191 
192  if (!PageIndexTupleOverwrite(page, offnum, (Item) brintuple, tuplen))
193  elog(PANIC, "brin_xlog_samepage_update: failed to replace tuple");
194 
195  PageSetLSN(page, lsn);
196  MarkBufferDirty(buffer);
197  }
198  if (BufferIsValid(buffer))
199  UnlockReleaseBuffer(buffer);
200 
201  /* XXX no FSM updates here ... */
202 }
bool PageIndexTupleOverwrite(Page page, OffsetNumber offnum, Item newtup, Size newsize)
Definition: bufpage.c:1405
OffsetNumber offnum
Definition: brin_xlog.h:104

References generate_unaccent_rules::action, BLK_NEEDS_REDO, BufferGetPage(), BufferIsValid(), elog, XLogReaderState::EndRecPtr, MarkBufferDirty(), xl_brin_samepage_update::offnum, PageIndexTupleOverwrite(), PageSetLSN(), PANIC, UnlockReleaseBuffer(), XLogReadBufferForRedo(), XLogRecGetBlockData(), and XLogRecGetData.

Referenced by brin_redo().

◆ brin_xlog_update()

static void brin_xlog_update ( XLogReaderState record)
static

Definition at line 135 of file brin_xlog.c.

136 {
137  XLogRecPtr lsn = record->EndRecPtr;
138  xl_brin_update *xlrec = (xl_brin_update *) XLogRecGetData(record);
139  Buffer buffer;
141 
142  /* First remove the old tuple */
143  action = XLogReadBufferForRedo(record, 2, &buffer);
144  if (action == BLK_NEEDS_REDO)
145  {
146  Page page;
147  OffsetNumber offnum;
148 
149  page = (Page) BufferGetPage(buffer);
150 
151  offnum = xlrec->oldOffnum;
152 
153  PageIndexTupleDeleteNoCompact(page, offnum);
154 
155  PageSetLSN(page, lsn);
156  MarkBufferDirty(buffer);
157  }
158 
159  /* Then insert the new tuple and update revmap, like in an insertion. */
160  brin_xlog_insert_update(record, &xlrec->insert);
161 
162  if (BufferIsValid(buffer))
163  UnlockReleaseBuffer(buffer);
164 }
OffsetNumber oldOffnum
Definition: brin_xlog.h:90
xl_brin_insert insert
Definition: brin_xlog.h:92

References generate_unaccent_rules::action, BLK_NEEDS_REDO, brin_xlog_insert_update(), BufferGetPage(), BufferIsValid(), XLogReaderState::EndRecPtr, xl_brin_update::insert, MarkBufferDirty(), xl_brin_update::oldOffnum, PageIndexTupleDeleteNoCompact(), PageSetLSN(), UnlockReleaseBuffer(), XLogReadBufferForRedo(), and XLogRecGetData.

Referenced by brin_redo().