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 *page, 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.

◆ MAX_GENERIC_XLOG_PAGES

#define MAX_GENERIC_XLOG_PAGES   XLR_NORMAL_MAX_BLOCK_ID

Definition at line 23 of file generic_xlog.h.

Typedef Documentation

◆ GenericXLogState

Definition at line 1 of file generic_xlog.h.

Function Documentation

◆ generic_desc()

void generic_desc ( StringInfo  buf,
XLogReaderState record 
)

Definition at line 25 of file genericdesc.c.

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 }
char * Pointer
Definition: c.h:472
uint16 OffsetNumber
Definition: off.h:24
static char * buf
Definition: pg_test_fsync.c:73
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
#define XLogRecGetDataLen(decoder)
Definition: xlogreader.h:416
#define XLogRecGetData(decoder)
Definition: xlogreader.h:415

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

◆ generic_identify()

const char* generic_identify ( uint8  info)

Definition at line 53 of file genericdesc.c.

54 {
55  return "Generic";
56 }

◆ generic_mask()

void generic_mask ( char *  page,
BlockNumber  blkno 
)

Definition at line 540 of file generic_xlog.c.

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

References mask_page_lsn_and_checksum(), and mask_unused_space().

◆ generic_redo()

void generic_redo ( XLogReaderState record)

Definition at line 479 of file generic_xlog.c.

480 {
481  XLogRecPtr lsn = record->EndRecPtr;
483  uint8 block_id;
484 
485  /* Protect limited size of buffers[] array */
487 
488  /* Iterate over blocks */
489  for (block_id = 0; block_id <= XLogRecMaxBlockId(record); block_id++)
490  {
492 
493  if (!XLogRecHasBlockRef(record, block_id))
494  {
495  buffers[block_id] = InvalidBuffer;
496  continue;
497  }
498 
499  action = XLogReadBufferForRedo(record, block_id, &buffers[block_id]);
500 
501  /* Apply redo to given block if needed */
502  if (action == BLK_NEEDS_REDO)
503  {
504  Page page;
505  PageHeader pageHeader;
506  char *blockDelta;
507  Size blockDeltaSize;
508 
509  page = BufferGetPage(buffers[block_id]);
510  blockDelta = XLogRecGetBlockData(record, block_id, &blockDeltaSize);
511  applyPageRedo(page, blockDelta, blockDeltaSize);
512 
513  /*
514  * Since the delta contains no information about what's in the
515  * "hole" between pd_lower and pd_upper, set that to zero to
516  * ensure we produce the same page state that application of the
517  * logged action by GenericXLogFinish did.
518  */
519  pageHeader = (PageHeader) page;
520  memset(page + pageHeader->pd_lower, 0,
521  pageHeader->pd_upper - pageHeader->pd_lower);
522 
523  PageSetLSN(page, lsn);
524  MarkBufferDirty(buffers[block_id]);
525  }
526  }
527 
528  /* Changes are done: unlock and release all buffers */
529  for (block_id = 0; block_id <= XLogRecMaxBlockId(record); block_id++)
530  {
531  if (BufferIsValid(buffers[block_id]))
532  UnlockReleaseBuffer(buffers[block_id]);
533  }
534 }
int Buffer
Definition: buf.h:23
#define InvalidBuffer
Definition: buf.h:25
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:4590
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:2198
static Page BufferGetPage(Buffer buffer)
Definition: bufmgr.h:350
static bool BufferIsValid(Buffer bufnum)
Definition: bufmgr.h:301
PageHeaderData * PageHeader
Definition: bufpage.h:170
Pointer Page
Definition: bufpage.h:78
static void PageSetLSN(Page page, XLogRecPtr lsn)
Definition: bufpage.h:388
unsigned char uint8
Definition: c.h:493
size_t Size
Definition: c.h:594
static void applyPageRedo(Page page, const char *delta, Size deltaSize)
Definition: generic_xlog.c:454
#define MAX_GENERIC_XLOG_PAGES
Definition: generic_xlog.h:23
Assert(fmt[strlen(fmt) - 1] !='\n')
LocationIndex pd_upper
Definition: bufpage.h:163
LocationIndex pd_lower
Definition: bufpage.h:162
XLogRecPtr EndRecPtr
Definition: xlogreader.h:207
uint64 XLogRecPtr
Definition: xlogdefs.h:21
char * XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len)
Definition: xlogreader.c:2002
#define XLogRecMaxBlockId(decoder)
Definition: xlogreader.h:418
#define XLogRecHasBlockRef(decoder, block_id)
Definition: xlogreader.h:420
XLogRedoAction XLogReadBufferForRedo(XLogReaderState *record, uint8 block_id, Buffer *buf)
Definition: xlogutils.c:317
XLogRedoAction
Definition: xlogutils.h:70
@ BLK_NEEDS_REDO
Definition: xlogutils.h:71

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

◆ GenericXLogAbort()

void GenericXLogAbort ( GenericXLogState state)

Definition at line 445 of file generic_xlog.c.

446 {
447  pfree(state);
448 }
void pfree(void *pointer)
Definition: mcxt.c:1456
Definition: regguts.h:323

References pfree().

Referenced by blbulkdelete(), and blinsert().

◆ GenericXLogFinish()

XLogRecPtr GenericXLogFinish ( GenericXLogState state)

Definition at line 338 of file generic_xlog.c.

339 {
340  XLogRecPtr lsn;
341  int i;
342 
343  if (state->isLogged)
344  {
345  /* Logged relation: make xlog record in critical section. */
346  XLogBeginInsert();
347 
349 
350  /*
351  * Compute deltas if necessary, write changes to buffers, mark buffers
352  * dirty, and register changes.
353  */
354  for (i = 0; i < MAX_GENERIC_XLOG_PAGES; i++)
355  {
356  PageData *pageData = &state->pages[i];
357  Page page;
358  PageHeader pageHeader;
359 
360  if (BufferIsInvalid(pageData->buffer))
361  continue;
362 
363  page = BufferGetPage(pageData->buffer);
364  pageHeader = (PageHeader) pageData->image;
365 
366  /*
367  * Compute delta while we still have both the unmodified page and
368  * the new image. Not needed if we are logging the full image.
369  */
370  if (!(pageData->flags & GENERIC_XLOG_FULL_IMAGE))
371  computeDelta(pageData, page, (Page) pageData->image);
372 
373  /*
374  * Apply the image, being careful to zero the "hole" between
375  * pd_lower and pd_upper in order to avoid divergence between
376  * actual page state and what replay would produce.
377  */
378  memcpy(page, pageData->image, pageHeader->pd_lower);
379  memset(page + pageHeader->pd_lower, 0,
380  pageHeader->pd_upper - pageHeader->pd_lower);
381  memcpy(page + pageHeader->pd_upper,
382  pageData->image + pageHeader->pd_upper,
383  BLCKSZ - pageHeader->pd_upper);
384 
385  MarkBufferDirty(pageData->buffer);
386 
387  if (pageData->flags & GENERIC_XLOG_FULL_IMAGE)
388  {
389  XLogRegisterBuffer(i, pageData->buffer,
391  }
392  else
393  {
395  XLogRegisterBufData(i, pageData->delta, pageData->deltaLen);
396  }
397  }
398 
399  /* Insert xlog record */
400  lsn = XLogInsert(RM_GENERIC_ID, 0);
401 
402  /* Set LSN */
403  for (i = 0; i < MAX_GENERIC_XLOG_PAGES; i++)
404  {
405  PageData *pageData = &state->pages[i];
406 
407  if (BufferIsInvalid(pageData->buffer))
408  continue;
409  PageSetLSN(BufferGetPage(pageData->buffer), lsn);
410  }
412  }
413  else
414  {
415  /* Unlogged relation: skip xlog-related stuff */
417  for (i = 0; i < MAX_GENERIC_XLOG_PAGES; i++)
418  {
419  PageData *pageData = &state->pages[i];
420 
421  if (BufferIsInvalid(pageData->buffer))
422  continue;
423  memcpy(BufferGetPage(pageData->buffer),
424  pageData->image,
425  BLCKSZ);
426  /* We don't worry about zeroing the "hole" in this case */
427  MarkBufferDirty(pageData->buffer);
428  }
430  /* We don't have a LSN to return, in this case */
431  lsn = InvalidXLogRecPtr;
432  }
433 
434  pfree(state);
435 
436  return lsn;
437 }
#define BufferIsInvalid(buffer)
Definition: buf.h:31
static void computeDelta(PageData *pageData, Page curpage, Page targetpage)
Definition: generic_xlog.c:229
#define GENERIC_XLOG_FULL_IMAGE
Definition: generic_xlog.h:26
int i
Definition: isn.c:73
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
#define START_CRIT_SECTION()
Definition: miscadmin.h:148
#define END_CRIT_SECTION()
Definition: miscadmin.h:150
char * image
Definition: generic_xlog.c:56
char delta[MAX_DELTA_SIZE]
Definition: generic_xlog.c:58
int deltaLen
Definition: generic_xlog.c:55
Buffer buffer
Definition: generic_xlog.c:53
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:475
void XLogRegisterBufData(uint8 block_id, char *data, uint32 len)
Definition: xloginsert.c:406
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
Definition: xloginsert.c:243
void XLogBeginInsert(void)
Definition: xloginsert.c:150
#define REGBUF_STANDARD
Definition: xloginsert.h:34
#define REGBUF_FORCE_IMAGE
Definition: xloginsert.h:31

References PageData::buffer, BufferGetPage(), BufferIsInvalid, computeDelta(), PageData::delta, PageData::deltaLen, END_CRIT_SECTION, PageData::flags, GENERIC_XLOG_FULL_IMAGE, i, if(), PageData::image, InvalidXLogRecPtr, MarkBufferDirty(), MAX_GENERIC_XLOG_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().

◆ GenericXLogRegisterBuffer()

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

Definition at line 300 of file generic_xlog.c.

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

References PageData::buffer, BufferGetPage(), BufferIsInvalid, elog(), ERROR, PageData::flags, PageData::image, and MAX_GENERIC_XLOG_PAGES.

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

◆ GenericXLogStart()

GenericXLogState* GenericXLogStart ( Relation  relation)

Definition at line 270 of file generic_xlog.c.

271 {
273  int i;
274 
277  0);
278  state->isLogged = RelationNeedsWAL(relation);
279 
280  for (i = 0; i < MAX_GENERIC_XLOG_PAGES; i++)
281  {
282  state->pages[i].image = state->images[i].data;
283  state->pages[i].buffer = InvalidBuffer;
284  }
285 
286  return state;
287 }
void * palloc_aligned(Size size, Size alignto, int flags)
Definition: mcxt.c:1446
#define PG_IO_ALIGN_SIZE
#define RelationNeedsWAL(relation)
Definition: rel.h:629

References i, InvalidBuffer, MAX_GENERIC_XLOG_PAGES, palloc_aligned(), PG_IO_ALIGN_SIZE, and RelationNeedsWAL.

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