PostgreSQL Source Code  git master
generic_xlog.h File Reference
#include "access/xlog.h"
#include "access/xlog_internal.h"
#include "access/xloginsert.h"
#include "storage/bufpage.h"
#include "utils/rel.h"
Include dependency graph for generic_xlog.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define MAX_GENERIC_XLOG_PAGES   XLR_NORMAL_MAX_BLOCK_ID
 
#define GENERIC_XLOG_FULL_IMAGE   0x0001 /* write full-page image */
 

Typedefs

typedef struct GenericXLogState GenericXLogState
 

Functions

GenericXLogStateGenericXLogStart (Relation relation)
 
Page GenericXLogRegisterBuffer (GenericXLogState *state, Buffer buffer, int flags)
 
XLogRecPtr GenericXLogFinish (GenericXLogState *state)
 
void GenericXLogAbort (GenericXLogState *state)
 
void generic_redo (XLogReaderState *record)
 
const char * generic_identify (uint8 info)
 
void generic_desc (StringInfo buf, XLogReaderState *record)
 
void generic_mask (char *pagedata, BlockNumber blkno)
 

Macro Definition Documentation

◆ GENERIC_XLOG_FULL_IMAGE

#define GENERIC_XLOG_FULL_IMAGE   0x0001 /* write full-page image */

Definition at line 26 of file generic_xlog.h.

Referenced by blinsert(), BloomInitMetapage(), flushCachedPage(), and GenericXLogFinish().

◆ MAX_GENERIC_XLOG_PAGES

#define MAX_GENERIC_XLOG_PAGES   XLR_NORMAL_MAX_BLOCK_ID

Typedef Documentation

◆ GenericXLogState

Definition at line 30 of file generic_xlog.h.

Function Documentation

◆ generic_desc()

void generic_desc ( StringInfo  buf,
XLogReaderState record 
)

Definition at line 25 of file genericdesc.c.

References appendStringInfo(), length(), XLogRecGetData, and XLogRecGetDataLen.

26 {
27  Pointer ptr = XLogRecGetData(record),
28  end = ptr + XLogRecGetDataLen(record);
29 
30  while (ptr < end)
31  {
32  OffsetNumber offset,
33  length;
34 
35  memcpy(&offset, ptr, sizeof(offset));
36  ptr += sizeof(offset);
37  memcpy(&length, ptr, sizeof(length));
38  ptr += sizeof(length);
39  ptr += length;
40 
41  if (ptr < end)
42  appendStringInfo(buf, "offset %u, length %u; ", offset, length);
43  else
44  appendStringInfo(buf, "offset %u, length %u", offset, length);
45  }
46 
47  return;
48 }
int length(const List *list)
Definition: list.c:1271
uint16 OffsetNumber
Definition: off.h:24
char * Pointer
Definition: c.h:273
#define XLogRecGetData(decoder)
Definition: xlogreader.h:226
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define XLogRecGetDataLen(decoder)
Definition: xlogreader.h:227

◆ generic_identify()

const char* generic_identify ( uint8  info)

Definition at line 55 of file genericdesc.c.

56 {
57  return "Generic";
58 }

◆ generic_mask()

void generic_mask ( char *  pagedata,
BlockNumber  blkno 
)

Definition at line 542 of file generic_xlog.c.

References mask_page_lsn_and_checksum(), and mask_unused_space().

543 {
545 
546  mask_unused_space(page);
547 }
void mask_unused_space(Page page)
Definition: bufmask.c:71
void mask_page_lsn_and_checksum(Page page)
Definition: bufmask.c:31

◆ generic_redo()

void generic_redo ( XLogReaderState record)

Definition at line 481 of file generic_xlog.c.

References generate_unaccent_rules::action, applyPageRedo(), Assert, BLK_NEEDS_REDO, BufferGetPage, BufferIsValid, XLogReaderState::EndRecPtr, InvalidBuffer, MarkBufferDirty(), XLogReaderState::max_block_id, MAX_GENERIC_XLOG_PAGES, PageSetLSN, PageHeaderData::pd_lower, PageHeaderData::pd_upper, UnlockReleaseBuffer(), XLogReadBufferForRedo(), XLogRecGetBlockData(), and XLogRecHasBlockRef.

482 {
483  XLogRecPtr lsn = record->EndRecPtr;
485  uint8 block_id;
486 
487  /* Protect limited size of buffers[] array */
489 
490  /* Iterate over blocks */
491  for (block_id = 0; block_id <= record->max_block_id; block_id++)
492  {
494 
495  if (!XLogRecHasBlockRef(record, block_id))
496  {
497  buffers[block_id] = InvalidBuffer;
498  continue;
499  }
500 
501  action = XLogReadBufferForRedo(record, block_id, &buffers[block_id]);
502 
503  /* Apply redo to given block if needed */
504  if (action == BLK_NEEDS_REDO)
505  {
506  Page page;
507  PageHeader pageHeader;
508  char *blockDelta;
509  Size blockDeltaSize;
510 
511  page = BufferGetPage(buffers[block_id]);
512  blockDelta = XLogRecGetBlockData(record, block_id, &blockDeltaSize);
513  applyPageRedo(page, blockDelta, blockDeltaSize);
514 
515  /*
516  * Since the delta contains no information about what's in the
517  * "hole" between pd_lower and pd_upper, set that to zero to
518  * ensure we produce the same page state that application of the
519  * logged action by GenericXLogFinish did.
520  */
521  pageHeader = (PageHeader) page;
522  memset(page + pageHeader->pd_lower, 0,
523  pageHeader->pd_upper - pageHeader->pd_lower);
524 
525  PageSetLSN(page, lsn);
526  MarkBufferDirty(buffers[block_id]);
527  }
528  }
529 
530  /* Changes are done: unlock and release all buffers */
531  for (block_id = 0; block_id <= record->max_block_id; block_id++)
532  {
533  if (BufferIsValid(buffers[block_id]))
534  UnlockReleaseBuffer(buffers[block_id]);
535  }
536 }
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:1450
unsigned char uint8
Definition: c.h:294
#define InvalidBuffer
Definition: buf.h:25
#define XLogRecHasBlockRef(decoder, block_id)
Definition: xlogreader.h:229
XLogRecPtr EndRecPtr
Definition: xlogreader.h:120
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
char * XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len)
Definition: xlogreader.c:1333
static void applyPageRedo(Page page, const char *delta, Size deltaSize)
Definition: generic_xlog.c:456
XLogRedoAction XLogReadBufferForRedo(XLogReaderState *record, uint8 block_id, Buffer *buf)
Definition: xlogutils.c:290
PageHeaderData * PageHeader
Definition: bufpage.h:162
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:670
XLogRedoAction
Definition: xlogutils.h:27
size_t Size
Definition: c.h:404
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
LocationIndex pd_upper
Definition: bufpage.h:155
#define MAX_GENERIC_XLOG_PAGES
Definition: generic_xlog.h:23
#define PageSetLSN(page, lsn)
Definition: bufpage.h:364
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
LocationIndex pd_lower
Definition: bufpage.h:154

◆ GenericXLogAbort()

void GenericXLogAbort ( GenericXLogState state)

Definition at line 447 of file generic_xlog.c.

References pfree().

Referenced by blbulkdelete(), and blinsert().

448 {
449  pfree(state);
450 }
void pfree(void *pointer)
Definition: mcxt.c:949

◆ GenericXLogFinish()

XLogRecPtr GenericXLogFinish ( GenericXLogState state)

Definition at line 336 of file generic_xlog.c.

References PageData::buffer, BufferGetPage, BufferIsInvalid, computeDelta(), PageData::delta, PageData::deltaLen, END_CRIT_SECTION, PageData::flags, GENERIC_XLOG_FULL_IMAGE, i, PageData::image, InvalidXLogRecPtr, GenericXLogState::isLogged, MarkBufferDirty(), MAX_GENERIC_XLOG_PAGES, GenericXLogState::pages, PageSetLSN, PageHeaderData::pd_lower, PageHeaderData::pd_upper, pfree(), REGBUF_FORCE_IMAGE, REGBUF_STANDARD, START_CRIT_SECTION, XLogBeginInsert(), XLogInsert(), XLogRegisterBufData(), and XLogRegisterBuffer().

Referenced by blbulkdelete(), blinsert(), BloomInitMetapage(), and flushCachedPage().

337 {
338  XLogRecPtr lsn;
339  int i;
340 
341  if (state->isLogged)
342  {
343  /* Logged relation: make xlog record in critical section. */
344  XLogBeginInsert();
345 
347 
348  for (i = 0; i < MAX_GENERIC_XLOG_PAGES; i++)
349  {
350  PageData *pageData = &state->pages[i];
351  Page page;
352  PageHeader pageHeader;
353 
354  if (BufferIsInvalid(pageData->buffer))
355  continue;
356 
357  page = BufferGetPage(pageData->buffer);
358  pageHeader = (PageHeader) pageData->image;
359 
360  if (pageData->flags & GENERIC_XLOG_FULL_IMAGE)
361  {
362  /*
363  * A full-page image does not require us to supply any xlog
364  * data. Just apply the image, being careful to zero the
365  * "hole" between pd_lower and pd_upper in order to avoid
366  * divergence between actual page state and what replay would
367  * produce.
368  */
369  memcpy(page, pageData->image, pageHeader->pd_lower);
370  memset(page + pageHeader->pd_lower, 0,
371  pageHeader->pd_upper - pageHeader->pd_lower);
372  memcpy(page + pageHeader->pd_upper,
373  pageData->image + pageHeader->pd_upper,
374  BLCKSZ - pageHeader->pd_upper);
375 
376  XLogRegisterBuffer(i, pageData->buffer,
378  }
379  else
380  {
381  /*
382  * In normal mode, calculate delta and write it as xlog data
383  * associated with this page.
384  */
385  computeDelta(pageData, page, (Page) pageData->image);
386 
387  /* Apply the image, with zeroed "hole" as above */
388  memcpy(page, pageData->image, pageHeader->pd_lower);
389  memset(page + pageHeader->pd_lower, 0,
390  pageHeader->pd_upper - pageHeader->pd_lower);
391  memcpy(page + pageHeader->pd_upper,
392  pageData->image + pageHeader->pd_upper,
393  BLCKSZ - pageHeader->pd_upper);
394 
396  XLogRegisterBufData(i, pageData->delta, pageData->deltaLen);
397  }
398  }
399 
400  /* Insert xlog record */
401  lsn = XLogInsert(RM_GENERIC_ID, 0);
402 
403  /* Set LSN and mark buffers dirty */
404  for (i = 0; i < MAX_GENERIC_XLOG_PAGES; i++)
405  {
406  PageData *pageData = &state->pages[i];
407 
408  if (BufferIsInvalid(pageData->buffer))
409  continue;
410  PageSetLSN(BufferGetPage(pageData->buffer), lsn);
411  MarkBufferDirty(pageData->buffer);
412  }
414  }
415  else
416  {
417  /* Unlogged relation: skip xlog-related stuff */
419  for (i = 0; i < MAX_GENERIC_XLOG_PAGES; i++)
420  {
421  PageData *pageData = &state->pages[i];
422 
423  if (BufferIsInvalid(pageData->buffer))
424  continue;
425  memcpy(BufferGetPage(pageData->buffer),
426  pageData->image,
427  BLCKSZ);
428  /* We don't worry about zeroing the "hole" in this case */
429  MarkBufferDirty(pageData->buffer);
430  }
432  /* We don't have a LSN to return, in this case */
433  lsn = InvalidXLogRecPtr;
434  }
435 
436  pfree(state);
437 
438  return lsn;
439 }
void XLogRegisterBufData(uint8 block_id, char *data, int len)
Definition: xloginsert.c:361
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
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
#define START_CRIT_SECTION()
Definition: miscadmin.h:131
void pfree(void *pointer)
Definition: mcxt.c:949
char delta[MAX_DELTA_SIZE]
Definition: generic_xlog.c:58
#define BufferIsInvalid(buffer)
Definition: buf.h:31
#define REGBUF_STANDARD
Definition: xloginsert.h:34
PageData pages[MAX_GENERIC_XLOG_PAGES]
Definition: generic_xlog.c:70
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
Buffer buffer
Definition: generic_xlog.c:53
static void computeDelta(PageData *pageData, Page curpage, Page targetpage)
Definition: generic_xlog.c:229
#define REGBUF_FORCE_IMAGE
Definition: xloginsert.h:30
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
char * image
Definition: generic_xlog.c:56
PageHeaderData * PageHeader
Definition: bufpage.h:162
uint64 XLogRecPtr
Definition: xlogdefs.h:21
int i
LocationIndex pd_upper
Definition: bufpage.h:155
#define MAX_GENERIC_XLOG_PAGES
Definition: generic_xlog.h:23
void XLogBeginInsert(void)
Definition: xloginsert.c:120
#define PageSetLSN(page, lsn)
Definition: bufpage.h:364
#define GENERIC_XLOG_FULL_IMAGE
Definition: generic_xlog.h:26
Pointer Page
Definition: bufpage.h:74
LocationIndex pd_lower
Definition: bufpage.h:154
int deltaLen
Definition: generic_xlog.c:55

◆ GenericXLogRegisterBuffer()

Page GenericXLogRegisterBuffer ( GenericXLogState state,
Buffer  buffer,
int  flags 
)

Definition at line 298 of file generic_xlog.c.

References PageData::buffer, buffer, BufferGetPage, BufferIsInvalid, elog, ERROR, PageData::flags, PageData::image, MAX_GENERIC_XLOG_PAGES, and GenericXLogState::pages.

Referenced by blbulkdelete(), blinsert(), BloomInitMetapage(), and flushCachedPage().

299 {
300  int block_id;
301 
302  /* Search array for existing entry or first unused slot */
303  for (block_id = 0; block_id < MAX_GENERIC_XLOG_PAGES; block_id++)
304  {
305  PageData *page = &state->pages[block_id];
306 
307  if (BufferIsInvalid(page->buffer))
308  {
309  /* Empty slot, so use it (there cannot be a match later) */
310  page->buffer = buffer;
311  page->flags = flags;
312  memcpy(page->image, BufferGetPage(buffer), BLCKSZ);
313  return (Page) page->image;
314  }
315  else if (page->buffer == buffer)
316  {
317  /*
318  * Buffer is already registered. Just return the image, which is
319  * already prepared.
320  */
321  return (Page) page->image;
322  }
323  }
324 
325  elog(ERROR, "maximum number %d of generic xlog buffers is exceeded",
326  MAX_GENERIC_XLOG_PAGES);
327  /* keep compiler quiet */
328  return NULL;
329 }
#define ERROR
Definition: elog.h:43
#define BufferIsInvalid(buffer)
Definition: buf.h:31
PageData pages[MAX_GENERIC_XLOG_PAGES]
Definition: generic_xlog.c:70
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
Buffer buffer
Definition: generic_xlog.c:53
char * image
Definition: generic_xlog.c:56
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
#define elog
Definition: elog.h:219
#define MAX_GENERIC_XLOG_PAGES
Definition: generic_xlog.h:23
Pointer Page
Definition: bufpage.h:74

◆ GenericXLogStart()

GenericXLogState* GenericXLogStart ( Relation  relation)

Definition at line 270 of file generic_xlog.c.

References PageData::buffer, i, PageData::image, GenericXLogState::images, InvalidBuffer, GenericXLogState::isLogged, MAX_GENERIC_XLOG_PAGES, GenericXLogState::pages, palloc(), and RelationNeedsWAL.

Referenced by blbulkdelete(), blinsert(), BloomInitMetapage(), and flushCachedPage().

271 {
273  int i;
274 
275  state = (GenericXLogState *) palloc(sizeof(GenericXLogState));
276  state->isLogged = RelationNeedsWAL(relation);
277 
278  for (i = 0; i < MAX_GENERIC_XLOG_PAGES; i++)
279  {
280  state->pages[i].image = state->images + BLCKSZ * i;
281  state->pages[i].buffer = InvalidBuffer;
282  }
283 
284  return state;
285 }
#define InvalidBuffer
Definition: buf.h:25
PageData pages[MAX_GENERIC_XLOG_PAGES]
Definition: generic_xlog.c:70
Buffer buffer
Definition: generic_xlog.c:53
char * image
Definition: generic_xlog.c:56
char images[MAX_GENERIC_XLOG_PAGES *BLCKSZ]
Definition: generic_xlog.c:69
Definition: regguts.h:298
#define RelationNeedsWAL(relation)
Definition: rel.h:514
void * palloc(Size size)
Definition: mcxt.c:848
int i
#define MAX_GENERIC_XLOG_PAGES
Definition: generic_xlog.h:23