PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
xloginsert.c File Reference
#include "postgres.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "access/xlog_internal.h"
#include "access/xloginsert.h"
#include "catalog/pg_control.h"
#include "common/pg_lzcompress.h"
#include "miscadmin.h"
#include "replication/origin.h"
#include "storage/bufmgr.h"
#include "storage/proc.h"
#include "utils/memutils.h"
#include "pg_trace.h"
Include dependency graph for xloginsert.c:

Go to the source code of this file.

Data Structures

struct  registered_buffer
 

Macros

#define PGLZ_MAX_BLCKSZ   PGLZ_MAX_OUTPUT(BLCKSZ)
 
#define SizeOfXlogOrigin   (sizeof(RepOriginId) + sizeof(char))
 
#define HEADER_SCRATCH_SIZE
 

Functions

static XLogRecDataXLogRecordAssemble (RmgrId rmid, uint8 info, XLogRecPtr RedoRecPtr, bool doPageWrites, XLogRecPtr *fpw_lsn)
 
static bool XLogCompressBackupBlock (char *page, uint16 hole_offset, uint16 hole_length, char *dest, uint16 *dlen)
 
void XLogBeginInsert (void)
 
void XLogEnsureRecordSpace (int max_block_id, int ndatas)
 
void XLogResetInsertion (void)
 
void XLogRegisterBuffer (uint8 block_id, Buffer buffer, uint8 flags)
 
void XLogRegisterBlock (uint8 block_id, RelFileNode *rnode, ForkNumber forknum, BlockNumber blknum, Page page, uint8 flags)
 
void XLogRegisterData (char *data, int len)
 
void XLogRegisterBufData (uint8 block_id, char *data, int len)
 
void XLogSetRecordFlags (uint8 flags)
 
XLogRecPtr XLogInsert (RmgrId rmid, uint8 info)
 
bool XLogCheckBufferNeedsBackup (Buffer buffer)
 
XLogRecPtr XLogSaveBufferForHint (Buffer buffer, bool buffer_std)
 
XLogRecPtr log_newpage (RelFileNode *rnode, ForkNumber forkNum, BlockNumber blkno, Page page, bool page_std)
 
XLogRecPtr log_newpage_buffer (Buffer buffer, bool page_std)
 
void InitXLogInsert (void)
 

Variables

static registered_bufferregistered_buffers
 
static int max_registered_buffers
 
static int max_registered_block_id = 0
 
static XLogRecDatamainrdata_head
 
static XLogRecDatamainrdata_last = (XLogRecData *) &mainrdata_head
 
static uint32 mainrdata_len
 
static uint8 curinsert_flags = 0
 
static XLogRecData hdr_rdt
 
static char * hdr_scratch = NULL
 
static XLogRecDatardatas
 
static int num_rdatas
 
static int max_rdatas
 
static bool begininsert_called = false
 
static MemoryContext xloginsert_cxt
 

Macro Definition Documentation

#define HEADER_SCRATCH_SIZE
Value:
#define SizeOfXlogOrigin
Definition: xloginsert.c:90
#define XLR_MAX_BLOCK_ID
Definition: xlogrecord.h:221
#define SizeOfXLogRecord
Definition: xlogrecord.h:55
#define MaxSizeOfXLogRecordBlockHeader
Definition: xlogrecord.h:167
#define SizeOfXLogRecordDataHeaderLong
Definition: xlogrecord.h:208

Definition at line 92 of file xloginsert.c.

Referenced by InitXLogInsert().

#define PGLZ_MAX_BLCKSZ   PGLZ_MAX_OUTPUT(BLCKSZ)

Definition at line 36 of file xloginsert.c.

#define SizeOfXlogOrigin   (sizeof(RepOriginId) + sizeof(char))

Definition at line 90 of file xloginsert.c.

Function Documentation

void InitXLogInsert ( void  )

Definition at line 1028 of file xloginsert.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate(), hdr_scratch, HEADER_SCRATCH_SIZE, max_rdatas, max_registered_buffers, MemoryContextAlloc(), MemoryContextAllocZero(), NULL, TopMemoryContext, XLR_NORMAL_MAX_BLOCK_ID, and XLR_NORMAL_RDATAS.

Referenced by CreateCheckPoint(), and InitXLOGAccess().

1029 {
1030  /* Initialize the working areas */
1031  if (xloginsert_cxt == NULL)
1032  {
1034  "WAL record construction",
1036  }
1037 
1038  if (registered_buffers == NULL)
1039  {
1042  sizeof(registered_buffer) * (XLR_NORMAL_MAX_BLOCK_ID + 1));
1044  }
1045  if (rdatas == NULL)
1046  {
1048  sizeof(XLogRecData) * XLR_NORMAL_RDATAS);
1050  }
1051 
1052  /*
1053  * Allocate a buffer to hold the header information for a WAL record.
1054  */
1055  if (hdr_scratch == NULL)
1058 }
#define HEADER_SCRATCH_SIZE
Definition: xloginsert.c:92
#define XLR_NORMAL_RDATAS
Definition: xloginsert.h:27
static int max_registered_buffers
Definition: xloginsert.c:64
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
static int max_rdatas
Definition: xloginsert.c:102
MemoryContext TopMemoryContext
Definition: mcxt.c:43
static registered_buffer * registered_buffers
Definition: xloginsert.c:63
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:742
#define XLR_NORMAL_MAX_BLOCK_ID
Definition: xloginsert.h:26
#define NULL
Definition: c.h:229
static char * hdr_scratch
Definition: xloginsert.c:88
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:707
static MemoryContext xloginsert_cxt
Definition: xloginsert.c:107
static XLogRecData * rdatas
Definition: xloginsert.c:100
XLogRecPtr log_newpage ( RelFileNode rnode,
ForkNumber  forkNum,
BlockNumber  blkno,
Page  page,
bool  page_std 
)

Definition at line 972 of file xloginsert.c.

References PageIsNew, PageSetLSN, REGBUF_FORCE_IMAGE, REGBUF_STANDARD, XLOG_FPI, XLogBeginInsert(), XLogInsert(), and XLogRegisterBlock().

Referenced by _bt_blwritepage(), _hash_alloc_buckets(), _hash_init(), blbuildempty(), btbuildempty(), copy_relation_data(), end_heap_rewrite(), log_newpage_buffer(), raw_heap_insert(), and spgbuildempty().

974 {
975  int flags;
976  XLogRecPtr recptr;
977 
978  flags = REGBUF_FORCE_IMAGE;
979  if (page_std)
980  flags |= REGBUF_STANDARD;
981 
982  XLogBeginInsert();
983  XLogRegisterBlock(0, rnode, forkNum, blkno, page, flags);
984  recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI);
985 
986  /*
987  * The page may be uninitialized. If so, we can't set the LSN because that
988  * would corrupt the page.
989  */
990  if (!PageIsNew(page))
991  {
992  PageSetLSN(page, recptr);
993  }
994 
995  return recptr;
996 }
void XLogRegisterBlock(uint8 block_id, RelFileNode *rnode, ForkNumber forknum, BlockNumber blknum, Page page, uint8 flags)
Definition: xloginsert.c:266
#define REGBUF_STANDARD
Definition: xloginsert.h:35
#define REGBUF_FORCE_IMAGE
Definition: xloginsert.h:30
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define XLOG_FPI
Definition: pg_control.h:77
#define PageIsNew(page)
Definition: bufpage.h:226
void XLogBeginInsert(void)
Definition: xloginsert.c:120
#define PageSetLSN(page, lsn)
Definition: bufpage.h:365
XLogRecPtr log_newpage_buffer ( Buffer  buffer,
bool  page_std 
)

Definition at line 1009 of file xloginsert.c.

References Assert, BufferGetPage, BufferGetTag(), CritSectionCount, and log_newpage().

Referenced by brin_initialize_empty_new_buffer(), brinbuildempty(), FreeSpaceMapTruncateRel(), ginbuildempty(), gistbuildempty(), lazy_scan_heap(), and visibilitymap_truncate().

1010 {
1011  Page page = BufferGetPage(buffer);
1012  RelFileNode rnode;
1013  ForkNumber forkNum;
1014  BlockNumber blkno;
1015 
1016  /* Shared buffers should be modified in a critical section. */
1017  Assert(CritSectionCount > 0);
1018 
1019  BufferGetTag(buffer, &rnode, &forkNum, &blkno);
1020 
1021  return log_newpage(&rnode, forkNum, blkno, page, page_std);
1022 }
uint32 BlockNumber
Definition: block.h:31
volatile uint32 CritSectionCount
Definition: globals.c:36
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
ForkNumber
Definition: relpath.h:24
#define Assert(condition)
Definition: c.h:675
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:211
XLogRecPtr log_newpage(RelFileNode *rnode, ForkNumber forkNum, BlockNumber blkno, Page page, bool page_std)
Definition: xloginsert.c:972
void BufferGetTag(Buffer buffer, RelFileNode *rnode, ForkNumber *forknum, BlockNumber *blknum)
Definition: bufmgr.c:2626
Pointer Page
Definition: bufpage.h:74
void XLogBeginInsert ( void  )

Definition at line 120 of file xloginsert.c.

References Assert, begininsert_called, elog, ERROR, mainrdata_len, max_registered_block_id, and XLogInsertAllowed().

Referenced by _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_log_reuse_page(), _bt_mark_page_halfdead(), _bt_newroot(), _bt_split(), _bt_unlink_halfdead_page(), _hash_addovflpage(), _hash_doinsert(), _hash_expandtable(), _hash_freeovflpage(), _hash_init(), _hash_splitbucket(), _hash_squeezebucket(), _hash_vacuum_one_page(), addLeafTuple(), AlterSequence(), AssignTransactionId(), brin_doinsert(), brin_doupdate(), brinbuild(), brinRevmapDesummarizeRange(), CreateCheckPoint(), createdb(), CreateEndOfRecoveryRecord(), createPostingTree(), CreateTableSpace(), do_pg_stop_backup(), do_setval(), doPickSplit(), DropTableSpace(), EndPrepare(), fill_seq_with_data(), GenericXLogFinish(), ginbuild(), ginDeletePage(), ginHeapTupleFastInsert(), ginPlaceToPage(), ginUpdateStats(), ginVacuumPostingTreeLeaf(), gistbuild(), gistXLogSplit(), gistXLogUpdate(), hashbucketcleanup(), hashbulkdelete(), heap_abort_speculative(), heap_delete(), heap_finish_speculative(), heap_inplace_update(), heap_insert(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), heap_multi_insert(), heap_update(), log_heap_clean(), log_heap_cleanup_info(), log_heap_freeze(), log_heap_new_cid(), log_heap_update(), log_heap_visible(), log_newpage(), log_smgrcreate(), log_split_page(), LogAccessExclusiveLocks(), LogCurrentRunningXacts(), logical_heap_rewrite_flush_mappings(), LogLogicalMessage(), LogStandbyInvalidations(), movedb(), moveLeafs(), MultiXactIdCreateFromMembers(), nextval_internal(), pg_truncate_visibility_map(), RelationTruncate(), remove_dbtablespaces(), replorigin_advance(), replorigin_drop(), RequestXLogSwitch(), revmap_physical_extend(), shiftList(), spgAddNodeAction(), spgbuild(), spgSplitNodeAction(), UpdateFullPageWrites(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), write_relmap_file(), writeListPage(), WriteMTruncateXlogRec(), WriteMZeroPageXlogRec(), WriteSetTimestampXlogRec(), WriteTruncateXlogRec(), WriteZeroPageXlogRec(), XactLogAbortRecord(), XactLogCommitRecord(), XLogPutNextOid(), XLogReportParameters(), XLogRestorePoint(), XLogSaveBufferForHint(), and xlogVacuumPage().

121 {
124  Assert(mainrdata_len == 0);
125 
126  /* cross-check on whether we should be here or not */
127  if (!XLogInsertAllowed())
128  elog(ERROR, "cannot make new WAL entries during recovery");
129 
130  if (begininsert_called)
131  elog(ERROR, "XLogBeginInsert was already called");
132 
133  begininsert_called = true;
134 }
static uint32 mainrdata_len
Definition: xloginsert.c:74
static bool begininsert_called
Definition: xloginsert.c:104
#define ERROR
Definition: elog.h:43
static XLogRecData * mainrdata_head
Definition: xloginsert.c:72
bool XLogInsertAllowed(void)
Definition: xlog.c:7968
static XLogRecData * mainrdata_last
Definition: xloginsert.c:73
#define Assert(condition)
Definition: c.h:675
static int max_registered_block_id
Definition: xloginsert.c:65
#define elog
Definition: elog.h:219
bool XLogCheckBufferNeedsBackup ( Buffer  buffer)

Definition at line 855 of file xloginsert.c.

References BufferGetPage, doPageWrites, GetFullPageWriteInfo(), PageGetLSN, and RedoRecPtr.

Referenced by log_heap_update().

856 {
858  bool doPageWrites;
859  Page page;
860 
861  GetFullPageWriteInfo(&RedoRecPtr, &doPageWrites);
862 
863  page = BufferGetPage(buffer);
864 
865  if (doPageWrites && PageGetLSN(page) <= RedoRecPtr)
866  return true; /* buffer requires backup */
867 
868  return false; /* buffer does not need to be backed up */
869 }
static bool doPageWrites
Definition: xlog.c:357
static XLogRecPtr RedoRecPtr
Definition: xlog.c:350
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
uint64 XLogRecPtr
Definition: xlogdefs.h:21
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:211
#define PageGetLSN(page)
Definition: bufpage.h:363
void GetFullPageWriteInfo(XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p)
Definition: xlog.c:8191
Pointer Page
Definition: bufpage.h:74
static bool XLogCompressBackupBlock ( char *  page,
uint16  hole_offset,
uint16  hole_length,
char *  dest,
uint16 dlen 
)
static

Definition at line 805 of file xloginsert.c.

References pglz_compress(), PGLZ_strategy_default, and SizeOfXLogRecordBlockCompressHeader.

Referenced by XLogRecordAssemble().

807 {
808  int32 orig_len = BLCKSZ - hole_length;
809  int32 len;
810  int32 extra_bytes = 0;
811  char *source;
812  char tmp[BLCKSZ];
813 
814  if (hole_length != 0)
815  {
816  /* must skip the hole */
817  source = tmp;
818  memcpy(source, page, hole_offset);
819  memcpy(source + hole_offset,
820  page + (hole_offset + hole_length),
821  BLCKSZ - (hole_length + hole_offset));
822 
823  /*
824  * Extra data needs to be stored in WAL record for the compressed
825  * version of block image if the hole exists.
826  */
828  }
829  else
830  source = page;
831 
832  /*
833  * We recheck the actual size even if pglz_compress() reports success and
834  * see if the number of bytes saved by compression is larger than the
835  * length of extra data needed for the compressed version of block image.
836  */
837  len = pglz_compress(source, orig_len, dest, PGLZ_strategy_default);
838  if (len >= 0 &&
839  len + extra_bytes < orig_len)
840  {
841  *dlen = (uint16) len; /* successful compression */
842  return true;
843  }
844  return false;
845 }
signed int int32
Definition: c.h:256
unsigned short uint16
Definition: c.h:267
int32 pglz_compress(const char *source, int32 slen, char *dest, const PGLZ_Strategy *strategy)
const PGLZ_Strategy *const PGLZ_strategy_default
#define SizeOfXLogRecordBlockCompressHeader
Definition: xlogrecord.h:160
void XLogEnsureRecordSpace ( int  max_block_id,
int  ndatas 
)

Definition at line 146 of file xloginsert.c.

References Assert, CritSectionCount, elog, ERROR, max_rdatas, max_registered_buffers, MemSet, repalloc(), XLR_MAX_BLOCK_ID, XLR_NORMAL_MAX_BLOCK_ID, and XLR_NORMAL_RDATAS.

Referenced by _hash_freeovflpage(), _hash_squeezebucket(), EndPrepare(), gistplacetopage(), and shiftList().

147 {
148  int nbuffers;
149 
150  /*
151  * This must be called before entering a critical section, because
152  * allocating memory inside a critical section can fail. repalloc() will
153  * check the same, but better to check it here too so that we fail
154  * consistently even if the arrays happen to be large enough already.
155  */
156  Assert(CritSectionCount == 0);
157 
158  /* the minimum values can't be decreased */
159  if (max_block_id < XLR_NORMAL_MAX_BLOCK_ID)
160  max_block_id = XLR_NORMAL_MAX_BLOCK_ID;
161  if (ndatas < XLR_NORMAL_RDATAS)
162  ndatas = XLR_NORMAL_RDATAS;
163 
164  if (max_block_id > XLR_MAX_BLOCK_ID)
165  elog(ERROR, "maximum number of WAL record block references exceeded");
166  nbuffers = max_block_id + 1;
167 
168  if (nbuffers > max_registered_buffers)
169  {
171  repalloc(registered_buffers, sizeof(registered_buffer) * nbuffers);
172 
173  /*
174  * At least the padding bytes in the structs must be zeroed, because
175  * they are included in WAL data, but initialize it all for tidiness.
176  */
178  (nbuffers - max_registered_buffers) * sizeof(registered_buffer));
179  max_registered_buffers = nbuffers;
180  }
181 
182  if (ndatas > max_rdatas)
183  {
184  rdatas = (XLogRecData *) repalloc(rdatas, sizeof(XLogRecData) * ndatas);
185  max_rdatas = ndatas;
186  }
187 }
#define XLR_NORMAL_RDATAS
Definition: xloginsert.h:27
#define MemSet(start, val, len)
Definition: c.h:857
#define ERROR
Definition: elog.h:43
static int max_registered_buffers
Definition: xloginsert.c:64
volatile uint32 CritSectionCount
Definition: globals.c:36
static int max_rdatas
Definition: xloginsert.c:102
#define XLR_MAX_BLOCK_ID
Definition: xlogrecord.h:221
static registered_buffer * registered_buffers
Definition: xloginsert.c:63
#define XLR_NORMAL_MAX_BLOCK_ID
Definition: xloginsert.h:26
#define Assert(condition)
Definition: c.h:675
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:963
#define elog
Definition: elog.h:219
static XLogRecData * rdatas
Definition: xloginsert.c:100
XLogRecPtr XLogInsert ( RmgrId  rmid,
uint8  info 
)

Definition at line 415 of file xloginsert.c.

References begininsert_called, curinsert_flags, doPageWrites, elog, ERROR, GetFullPageWriteInfo(), InvalidXLogRecPtr, IsBootstrapProcessingMode, PANIC, RedoRecPtr, SizeOfXLogLongPHD, XLogInsertRecord(), XLogRecordAssemble(), XLogResetInsertion(), XLR_CHECK_CONSISTENCY, XLR_RMGR_INFO_MASK, and XLR_SPECIAL_REL_UPDATE.

Referenced by _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_log_reuse_page(), _bt_mark_page_halfdead(), _bt_newroot(), _bt_split(), _bt_unlink_halfdead_page(), _hash_addovflpage(), _hash_doinsert(), _hash_expandtable(), _hash_freeovflpage(), _hash_init(), _hash_splitbucket(), _hash_squeezebucket(), _hash_vacuum_one_page(), addLeafTuple(), AlterSequence(), AssignTransactionId(), brin_doinsert(), brin_doupdate(), brinbuild(), brinRevmapDesummarizeRange(), CreateCheckPoint(), createdb(), CreateEndOfRecoveryRecord(), createPostingTree(), CreateTableSpace(), do_pg_stop_backup(), do_setval(), doPickSplit(), DropTableSpace(), EndPrepare(), fill_seq_with_data(), GenericXLogFinish(), ginbuild(), ginDeletePage(), ginHeapTupleFastInsert(), ginPlaceToPage(), ginUpdateStats(), ginVacuumPostingTreeLeaf(), gistbuild(), gistXLogSplit(), gistXLogUpdate(), hashbucketcleanup(), hashbulkdelete(), heap_abort_speculative(), heap_delete(), heap_finish_speculative(), heap_inplace_update(), heap_insert(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), heap_multi_insert(), heap_update(), log_heap_clean(), log_heap_cleanup_info(), log_heap_freeze(), log_heap_new_cid(), log_heap_update(), log_heap_visible(), log_newpage(), log_smgrcreate(), log_split_page(), LogAccessExclusiveLocks(), LogCurrentRunningXacts(), logical_heap_rewrite_flush_mappings(), LogLogicalMessage(), LogStandbyInvalidations(), movedb(), moveLeafs(), MultiXactIdCreateFromMembers(), nextval_internal(), pg_truncate_visibility_map(), RelationTruncate(), remove_dbtablespaces(), replorigin_advance(), replorigin_drop(), RequestXLogSwitch(), revmap_physical_extend(), shiftList(), spgAddNodeAction(), spgbuild(), spgSplitNodeAction(), UpdateFullPageWrites(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), write_relmap_file(), writeListPage(), WriteMTruncateXlogRec(), WriteMZeroPageXlogRec(), WriteSetTimestampXlogRec(), WriteTruncateXlogRec(), WriteZeroPageXlogRec(), XactLogAbortRecord(), XactLogCommitRecord(), XLogPutNextOid(), XLogReportParameters(), XLogRestorePoint(), XLogSaveBufferForHint(), and xlogVacuumPage().

416 {
417  XLogRecPtr EndPos;
418 
419  /* XLogBeginInsert() must have been called. */
420  if (!begininsert_called)
421  elog(ERROR, "XLogBeginInsert was not called");
422 
423  /*
424  * The caller can set rmgr bits, XLR_SPECIAL_REL_UPDATE and
425  * XLR_CHECK_CONSISTENCY; the rest are reserved for use by me.
426  */
427  if ((info & ~(XLR_RMGR_INFO_MASK |
429  XLR_CHECK_CONSISTENCY)) != 0)
430  elog(PANIC, "invalid xlog info mask %02X", info);
431 
432  TRACE_POSTGRESQL_WAL_INSERT(rmid, info);
433 
434  /*
435  * In bootstrap mode, we don't actually log anything but XLOG resources;
436  * return a phony record pointer.
437  */
438  if (IsBootstrapProcessingMode() && rmid != RM_XLOG_ID)
439  {
441  EndPos = SizeOfXLogLongPHD; /* start of 1st chkpt record */
442  return EndPos;
443  }
444 
445  do
446  {
448  bool doPageWrites;
449  XLogRecPtr fpw_lsn;
450  XLogRecData *rdt;
451 
452  /*
453  * Get values needed to decide whether to do full-page writes. Since
454  * we don't yet have an insertion lock, these could change under us,
455  * but XLogInsertRecord will recheck them once it has a lock.
456  */
457  GetFullPageWriteInfo(&RedoRecPtr, &doPageWrites);
458 
459  rdt = XLogRecordAssemble(rmid, info, RedoRecPtr, doPageWrites,
460  &fpw_lsn);
461 
462  EndPos = XLogInsertRecord(rdt, fpw_lsn, curinsert_flags);
463  } while (EndPos == InvalidXLogRecPtr);
464 
466 
467  return EndPos;
468 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define XLR_SPECIAL_REL_UPDATE
Definition: xlogrecord.h:71
static bool begininsert_called
Definition: xloginsert.c:104
#define PANIC
Definition: elog.h:53
#define XLR_CHECK_CONSISTENCY
Definition: xlogrecord.h:80
static bool doPageWrites
Definition: xlog.c:357
#define ERROR
Definition: elog.h:43
void XLogResetInsertion(void)
Definition: xloginsert.c:193
XLogRecPtr XLogInsertRecord(XLogRecData *rdata, XLogRecPtr fpw_lsn, uint8 flags)
Definition: xlog.c:957
static XLogRecPtr RedoRecPtr
Definition: xlog.c:350
static XLogRecData * XLogRecordAssemble(RmgrId rmid, uint8 info, XLogRecPtr RedoRecPtr, bool doPageWrites, XLogRecPtr *fpw_lsn)
Definition: xloginsert.c:483
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:365
void GetFullPageWriteInfo(XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p)
Definition: xlog.c:8191
#define elog
Definition: elog.h:219
static uint8 curinsert_flags
Definition: xloginsert.c:77
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
#define XLR_RMGR_INFO_MASK
Definition: xlogrecord.h:63
static XLogRecData * XLogRecordAssemble ( RmgrId  rmid,
uint8  info,
XLogRecPtr  RedoRecPtr,
bool  doPageWrites,
XLogRecPtr fpw_lsn 
)
static

Definition at line 483 of file xloginsert.c.

References XLogRecordBlockImageHeader::bimg_info, registered_buffer::bkp_rdatas, BKPBLOCK_HAS_DATA, BKPBLOCK_HAS_IMAGE, BKPBLOCK_SAME_REL, BKPBLOCK_WILL_INIT, BKPIMAGE_APPLY, BKPIMAGE_HAS_HOLE, BKPIMAGE_IS_COMPRESSED, registered_buffer::block, COMP_CRC32C, registered_buffer::compressed_page, curinsert_flags, XLogRecData::data, XLogRecordBlockHeader::data_length, registered_buffer::flags, XLogRecordBlockHeader::fork_flags, registered_buffer::forkno, GetCurrentTransactionIdIfAny(), hdr_rdt, hdr_scratch, XLogRecordBlockCompressHeader::hole_length, XLogRecordBlockImageHeader::hole_offset, XLogRecordBlockHeader::id, registered_buffer::in_use, INIT_CRC32C, InvalidRepOriginId, InvalidXLogRecPtr, XLogRecData::len, XLogRecordBlockImageHeader::length, lower(), mainrdata_head, mainrdata_last, mainrdata_len, max_registered_block_id, XLogRecData::next, NULL, registered_buffer::page, PageGetLSN, registered_buffer::rdata_head, registered_buffer::rdata_len, registered_buffer::rdata_tail, RedoRecPtr, REGBUF_FORCE_IMAGE, REGBUF_KEEP_DATA, REGBUF_NO_IMAGE, REGBUF_STANDARD, REGBUF_WILL_INIT, RelFileNodeEquals, replorigin_session_origin, registered_buffer::rnode, SizeOfPageHeaderData, SizeOfXLogRecord, SizeOfXLogRecordBlockCompressHeader, SizeOfXLogRecordBlockHeader, SizeOfXLogRecordBlockImageHeader, upper(), wal_compression, wal_consistency_checking, XLogRecord::xl_crc, XLogRecord::xl_info, XLogRecord::xl_prev, XLogRecord::xl_rmid, XLogRecord::xl_tot_len, XLogRecord::xl_xid, XLOG_INCLUDE_ORIGIN, XLogCompressBackupBlock(), XLR_BLOCK_ID_DATA_LONG, XLR_BLOCK_ID_DATA_SHORT, XLR_BLOCK_ID_ORIGIN, and XLR_CHECK_CONSISTENCY.

Referenced by XLogInsert().

486 {
487  XLogRecData *rdt;
488  uint32 total_len = 0;
489  int block_id;
490  pg_crc32c rdata_crc;
491  registered_buffer *prev_regbuf = NULL;
492  XLogRecData *rdt_datas_last;
493  XLogRecord *rechdr;
494  char *scratch = hdr_scratch;
495 
496  /*
497  * Note: this function can be called multiple times for the same record.
498  * All the modifications we do to the rdata chains below must handle that.
499  */
500 
501  /* The record begins with the fixed-size header */
502  rechdr = (XLogRecord *) scratch;
503  scratch += SizeOfXLogRecord;
504 
505  hdr_rdt.next = NULL;
506  rdt_datas_last = &hdr_rdt;
508 
509  /*
510  * Enforce consistency checks for this record if user is looking for it.
511  * Do this before at the beginning of this routine to give the possibility
512  * for callers of XLogInsert() to pass XLR_CHECK_CONSISTENCY directly for
513  * a record.
514  */
515  if (wal_consistency_checking[rmid])
516  info |= XLR_CHECK_CONSISTENCY;
517 
518  /*
519  * Make an rdata chain containing all the data portions of all block
520  * references. This includes the data for full-page images. Also append
521  * the headers for the block references in the scratch buffer.
522  */
523  *fpw_lsn = InvalidXLogRecPtr;
524  for (block_id = 0; block_id < max_registered_block_id; block_id++)
525  {
526  registered_buffer *regbuf = &registered_buffers[block_id];
527  bool needs_backup;
528  bool needs_data;
531  XLogRecordBlockCompressHeader cbimg = {0};
532  bool samerel;
533  bool is_compressed = false;
534  bool include_image;
535 
536  if (!regbuf->in_use)
537  continue;
538 
539  /* Determine if this block needs to be backed up */
540  if (regbuf->flags & REGBUF_FORCE_IMAGE)
541  needs_backup = true;
542  else if (regbuf->flags & REGBUF_NO_IMAGE)
543  needs_backup = false;
544  else if (!doPageWrites)
545  needs_backup = false;
546  else
547  {
548  /*
549  * We assume page LSN is first data on *every* page that can be
550  * passed to XLogInsert, whether it has the standard page layout
551  * or not.
552  */
553  XLogRecPtr page_lsn = PageGetLSN(regbuf->page);
554 
555  needs_backup = (page_lsn <= RedoRecPtr);
556  if (!needs_backup)
557  {
558  if (*fpw_lsn == InvalidXLogRecPtr || page_lsn < *fpw_lsn)
559  *fpw_lsn = page_lsn;
560  }
561  }
562 
563  /* Determine if the buffer data needs to included */
564  if (regbuf->rdata_len == 0)
565  needs_data = false;
566  else if ((regbuf->flags & REGBUF_KEEP_DATA) != 0)
567  needs_data = true;
568  else
569  needs_data = !needs_backup;
570 
571  bkpb.id = block_id;
572  bkpb.fork_flags = regbuf->forkno;
573  bkpb.data_length = 0;
574 
575  if ((regbuf->flags & REGBUF_WILL_INIT) == REGBUF_WILL_INIT)
577 
578  /*
579  * If needs_backup is true or WAL checking is enabled for current
580  * resource manager, log a full-page write for the current block.
581  */
582  include_image = needs_backup || (info & XLR_CHECK_CONSISTENCY) != 0;
583 
584  if (include_image)
585  {
586  Page page = regbuf->page;
587  uint16 compressed_len;
588 
589  /*
590  * The page needs to be backed up, so calculate its hole length
591  * and offset.
592  */
593  if (regbuf->flags & REGBUF_STANDARD)
594  {
595  /* Assume we can omit data between pd_lower and pd_upper */
596  uint16 lower = ((PageHeader) page)->pd_lower;
597  uint16 upper = ((PageHeader) page)->pd_upper;
598 
599  if (lower >= SizeOfPageHeaderData &&
600  upper > lower &&
601  upper <= BLCKSZ)
602  {
603  bimg.hole_offset = lower;
604  cbimg.hole_length = upper - lower;
605  }
606  else
607  {
608  /* No "hole" to compress out */
609  bimg.hole_offset = 0;
610  cbimg.hole_length = 0;
611  }
612  }
613  else
614  {
615  /* Not a standard page header, don't try to eliminate "hole" */
616  bimg.hole_offset = 0;
617  cbimg.hole_length = 0;
618  }
619 
620  /*
621  * Try to compress a block image if wal_compression is enabled
622  */
623  if (wal_compression)
624  {
625  is_compressed =
627  cbimg.hole_length,
628  regbuf->compressed_page,
629  &compressed_len);
630  }
631 
632  /*
633  * Fill in the remaining fields in the XLogRecordBlockHeader
634  * struct
635  */
637 
638  /*
639  * Construct XLogRecData entries for the page content.
640  */
641  rdt_datas_last->next = &regbuf->bkp_rdatas[0];
642  rdt_datas_last = rdt_datas_last->next;
643 
644  bimg.bimg_info = (cbimg.hole_length == 0) ? 0 : BKPIMAGE_HAS_HOLE;
645 
646  /*
647  * If WAL consistency checking is enabled for the resource manager
648  * of this WAL record, a full-page image is included in the record
649  * for the block modified. During redo, the full-page is replayed
650  * only if BKPIMAGE_APPLY is set.
651  */
652  if (needs_backup)
653  bimg.bimg_info |= BKPIMAGE_APPLY;
654 
655  if (is_compressed)
656  {
657  bimg.length = compressed_len;
659 
660  rdt_datas_last->data = regbuf->compressed_page;
661  rdt_datas_last->len = compressed_len;
662  }
663  else
664  {
665  bimg.length = BLCKSZ - cbimg.hole_length;
666 
667  if (cbimg.hole_length == 0)
668  {
669  rdt_datas_last->data = page;
670  rdt_datas_last->len = BLCKSZ;
671  }
672  else
673  {
674  /* must skip the hole */
675  rdt_datas_last->data = page;
676  rdt_datas_last->len = bimg.hole_offset;
677 
678  rdt_datas_last->next = &regbuf->bkp_rdatas[1];
679  rdt_datas_last = rdt_datas_last->next;
680 
681  rdt_datas_last->data =
682  page + (bimg.hole_offset + cbimg.hole_length);
683  rdt_datas_last->len =
684  BLCKSZ - (bimg.hole_offset + cbimg.hole_length);
685  }
686  }
687 
688  total_len += bimg.length;
689  }
690 
691  if (needs_data)
692  {
693  /*
694  * Link the caller-supplied rdata chain for this buffer to the
695  * overall list.
696  */
698  bkpb.data_length = regbuf->rdata_len;
699  total_len += regbuf->rdata_len;
700 
701  rdt_datas_last->next = regbuf->rdata_head;
702  rdt_datas_last = regbuf->rdata_tail;
703  }
704 
705  if (prev_regbuf && RelFileNodeEquals(regbuf->rnode, prev_regbuf->rnode))
706  {
707  samerel = true;
709  }
710  else
711  samerel = false;
712  prev_regbuf = regbuf;
713 
714  /* Ok, copy the header to the scratch buffer */
715  memcpy(scratch, &bkpb, SizeOfXLogRecordBlockHeader);
716  scratch += SizeOfXLogRecordBlockHeader;
717  if (include_image)
718  {
719  memcpy(scratch, &bimg, SizeOfXLogRecordBlockImageHeader);
721  if (cbimg.hole_length != 0 && is_compressed)
722  {
723  memcpy(scratch, &cbimg,
726  }
727  }
728  if (!samerel)
729  {
730  memcpy(scratch, &regbuf->rnode, sizeof(RelFileNode));
731  scratch += sizeof(RelFileNode);
732  }
733  memcpy(scratch, &regbuf->block, sizeof(BlockNumber));
734  scratch += sizeof(BlockNumber);
735  }
736 
737  /* followed by the record's origin, if any */
740  {
741  *(scratch++) = (char) XLR_BLOCK_ID_ORIGIN;
742  memcpy(scratch, &replorigin_session_origin, sizeof(replorigin_session_origin));
743  scratch += sizeof(replorigin_session_origin);
744  }
745 
746  /* followed by main data, if any */
747  if (mainrdata_len > 0)
748  {
749  if (mainrdata_len > 255)
750  {
751  *(scratch++) = (char) XLR_BLOCK_ID_DATA_LONG;
752  memcpy(scratch, &mainrdata_len, sizeof(uint32));
753  scratch += sizeof(uint32);
754  }
755  else
756  {
757  *(scratch++) = (char) XLR_BLOCK_ID_DATA_SHORT;
758  *(scratch++) = (uint8) mainrdata_len;
759  }
760  rdt_datas_last->next = mainrdata_head;
761  rdt_datas_last = mainrdata_last;
762  total_len += mainrdata_len;
763  }
764  rdt_datas_last->next = NULL;
765 
766  hdr_rdt.len = (scratch - hdr_scratch);
767  total_len += hdr_rdt.len;
768 
769  /*
770  * Calculate CRC of the data
771  *
772  * Note that the record header isn't added into the CRC initially since we
773  * don't know the prev-link yet. Thus, the CRC will represent the CRC of
774  * the whole record in the order: rdata, then backup blocks, then record
775  * header.
776  */
777  INIT_CRC32C(rdata_crc);
779  for (rdt = hdr_rdt.next; rdt != NULL; rdt = rdt->next)
780  COMP_CRC32C(rdata_crc, rdt->data, rdt->len);
781 
782  /*
783  * Fill in the fields in the record header. Prev-link is filled in later,
784  * once we know where in the WAL the record will be inserted. The CRC does
785  * not include the record header yet.
786  */
788  rechdr->xl_tot_len = total_len;
789  rechdr->xl_info = info;
790  rechdr->xl_rmid = rmid;
791  rechdr->xl_prev = InvalidXLogRecPtr;
792  rechdr->xl_crc = rdata_crc;
793 
794  return &hdr_rdt;
795 }
static XLogRecData hdr_rdt
Definition: xloginsert.c:87
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define BKPIMAGE_HAS_HOLE
Definition: xlogrecord.h:147
static uint32 mainrdata_len
Definition: xloginsert.c:74
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
#define XLR_BLOCK_ID_DATA_LONG
Definition: xlogrecord.h:224
uint32 pg_crc32c
Definition: pg_crc32c.h:38
BlockNumber block
Definition: xloginsert.c:48
unsigned char uint8
Definition: c.h:266
#define REGBUF_WILL_INIT
Definition: xloginsert.h:32
RmgrId xl_rmid
Definition: xlogrecord.h:47
#define XLOG_INCLUDE_ORIGIN
Definition: xlog.h:192
uint32 BlockNumber
Definition: block.h:31
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:74
XLogRecData * rdata_head
Definition: xloginsert.c:51
#define SizeOfPageHeaderData
Definition: bufpage.h:213
#define XLR_CHECK_CONSISTENCY
Definition: xlogrecord.h:80
RelFileNode rnode
Definition: xloginsert.c:46
unsigned short uint16
Definition: c.h:267
static bool doPageWrites
Definition: xlog.c:357
uint32 xl_tot_len
Definition: xlogrecord.h:43
#define SizeOfXLogRecordBlockImageHeader
Definition: xlogrecord.h:143
static XLogRecPtr RedoRecPtr
Definition: xlog.c:350
#define BKPIMAGE_APPLY
Definition: xlogrecord.h:149
struct RelFileNode RelFileNode
static XLogRecData * mainrdata_head
Definition: xloginsert.c:72
#define REGBUF_STANDARD
Definition: xloginsert.h:35
TransactionId GetCurrentTransactionIdIfAny(void)
Definition: xact.c:434
unsigned int uint32
Definition: c.h:268
#define BKPBLOCK_WILL_INIT
Definition: xlogrecord.h:182
XLogRecData * rdata_tail
Definition: xloginsert.c:53
static registered_buffer * registered_buffers
Definition: xloginsert.c:63
#define SizeOfXLogRecord
Definition: xlogrecord.h:55
#define REGBUF_FORCE_IMAGE
Definition: xloginsert.h:30
#define BKPBLOCK_SAME_REL
Definition: xlogrecord.h:183
#define BKPIMAGE_IS_COMPRESSED
Definition: xlogrecord.h:148
#define REGBUF_KEEP_DATA
Definition: xloginsert.h:38
#define BKPBLOCK_HAS_IMAGE
Definition: xlogrecord.h:180
static XLogRecData * mainrdata_last
Definition: xloginsert.c:73
PageHeaderData * PageHeader
Definition: bufpage.h:162
#define NULL
Definition: c.h:229
uint64 XLogRecPtr
Definition: xlogdefs.h:21
RepOriginId replorigin_session_origin
Definition: origin.c:150
bool * wal_consistency_checking
Definition: xlog.c:101
uint8 xl_info
Definition: xlogrecord.h:46
#define REGBUF_NO_IMAGE
Definition: xloginsert.h:31
#define XLR_BLOCK_ID_ORIGIN
Definition: xlogrecord.h:225
ForkNumber forkno
Definition: xloginsert.c:47
pg_crc32c xl_crc
Definition: xlogrecord.h:49
struct XLogRecData * next
#define InvalidRepOriginId
Definition: origin.h:34
#define PageGetLSN(page)
Definition: bufpage.h:363
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:223
static char * hdr_scratch
Definition: xloginsert.c:88
TransactionId xl_xid
Definition: xlogrecord.h:44
static int max_registered_block_id
Definition: xloginsert.c:65
char compressed_page[PGLZ_MAX_BLCKSZ]
Definition: xloginsert.c:60
bool wal_compression
Definition: xlog.c:99
static bool XLogCompressBackupBlock(char *page, uint16 hole_offset, uint16 hole_length, char *dest, uint16 *dlen)
Definition: xloginsert.c:805
static uint8 curinsert_flags
Definition: xloginsert.c:77
XLogRecData bkp_rdatas[2]
Definition: xloginsert.c:56
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:73
#define SizeOfXLogRecordBlockCompressHeader
Definition: xlogrecord.h:160
Pointer Page
Definition: bufpage.h:74
#define RelFileNodeEquals(node1, node2)
Definition: relfilenode.h:88
#define BKPBLOCK_HAS_DATA
Definition: xlogrecord.h:181
#define SizeOfXLogRecordBlockHeader
Definition: xlogrecord.h:104
void XLogRegisterBlock ( uint8  block_id,
RelFileNode rnode,
ForkNumber  forknum,
BlockNumber  blknum,
Page  page,
uint8  flags 
)

Definition at line 266 of file xloginsert.c.

References Assert, begininsert_called, registered_buffer::block, elog, ERROR, registered_buffer::flags, registered_buffer::forkno, i, registered_buffer::in_use, max_registered_block_id, max_registered_buffers, registered_buffer::page, registered_buffer::rdata_head, registered_buffer::rdata_len, registered_buffer::rdata_tail, REGBUF_FORCE_IMAGE, RelFileNodeEquals, and registered_buffer::rnode.

Referenced by log_newpage(), and XLogSaveBufferForHint().

268 {
269  registered_buffer *regbuf;
270 
271  /* This is currently only used to WAL-log a full-page image of a page */
272  Assert(flags & REGBUF_FORCE_IMAGE);
274 
275  if (block_id >= max_registered_block_id)
276  max_registered_block_id = block_id + 1;
277 
278  if (block_id >= max_registered_buffers)
279  elog(ERROR, "too many registered buffers");
280 
281  regbuf = &registered_buffers[block_id];
282 
283  regbuf->rnode = *rnode;
284  regbuf->forkno = forknum;
285  regbuf->block = blknum;
286  regbuf->page = page;
287  regbuf->flags = flags;
288  regbuf->rdata_tail = (XLogRecData *) &regbuf->rdata_head;
289  regbuf->rdata_len = 0;
290 
291  /*
292  * Check that this page hasn't already been registered with some other
293  * block_id.
294  */
295 #ifdef USE_ASSERT_CHECKING
296  {
297  int i;
298 
299  for (i = 0; i < max_registered_block_id; i++)
300  {
301  registered_buffer *regbuf_old = &registered_buffers[i];
302 
303  if (i == block_id || !regbuf_old->in_use)
304  continue;
305 
306  Assert(!RelFileNodeEquals(regbuf_old->rnode, regbuf->rnode) ||
307  regbuf_old->forkno != regbuf->forkno ||
308  regbuf_old->block != regbuf->block);
309  }
310  }
311 #endif
312 
313  regbuf->in_use = true;
314 }
BlockNumber block
Definition: xloginsert.c:48
static bool begininsert_called
Definition: xloginsert.c:104
XLogRecData * rdata_head
Definition: xloginsert.c:51
RelFileNode rnode
Definition: xloginsert.c:46
#define ERROR
Definition: elog.h:43
static int max_registered_buffers
Definition: xloginsert.c:64
XLogRecData * rdata_tail
Definition: xloginsert.c:53
static registered_buffer * registered_buffers
Definition: xloginsert.c:63
#define REGBUF_FORCE_IMAGE
Definition: xloginsert.h:30
#define Assert(condition)
Definition: c.h:675
ForkNumber forkno
Definition: xloginsert.c:47
static int max_registered_block_id
Definition: xloginsert.c:65
int i
#define elog
Definition: elog.h:219
#define RelFileNodeEquals(node1, node2)
Definition: relfilenode.h:88
void XLogRegisterBufData ( uint8  block_id,
char *  data,
int  len 
)

Definition at line 361 of file xloginsert.c.

References Assert, begininsert_called, XLogRecData::data, elog, ERROR, registered_buffer::in_use, XLogRecData::len, max_rdatas, XLogRecData::next, num_rdatas, registered_buffer::rdata_len, and registered_buffer::rdata_tail.

Referenced by _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_newroot(), _bt_split(), _bt_unlink_halfdead_page(), _hash_addovflpage(), _hash_doinsert(), _hash_expandtable(), _hash_freeovflpage(), _hash_squeezebucket(), brin_doinsert(), brin_doupdate(), dataExecPlaceToPageInternal(), dataExecPlaceToPageLeaf(), entryExecPlaceToPage(), GenericXLogFinish(), ginHeapTupleFastInsert(), ginVacuumPostingTreeLeaf(), gistXLogSplit(), gistXLogUpdate(), hashbucketcleanup(), heap_inplace_update(), heap_insert(), heap_multi_insert(), log_heap_clean(), log_heap_freeze(), log_heap_update(), and writeListPage().

362 {
363  registered_buffer *regbuf;
364  XLogRecData *rdata;
365 
367 
368  /* find the registered buffer struct */
369  regbuf = &registered_buffers[block_id];
370  if (!regbuf->in_use)
371  elog(ERROR, "no block with id %d registered with WAL insertion",
372  block_id);
373 
374  if (num_rdatas >= max_rdatas)
375  elog(ERROR, "too much WAL data");
376  rdata = &rdatas[num_rdatas++];
377 
378  rdata->data = data;
379  rdata->len = len;
380 
381  regbuf->rdata_tail->next = rdata;
382  regbuf->rdata_tail = rdata;
383  regbuf->rdata_len += len;
384 }
static bool begininsert_called
Definition: xloginsert.c:104
#define ERROR
Definition: elog.h:43
XLogRecData * rdata_tail
Definition: xloginsert.c:53
static int max_rdatas
Definition: xloginsert.c:102
static registered_buffer * registered_buffers
Definition: xloginsert.c:63
static int num_rdatas
Definition: xloginsert.c:101
#define Assert(condition)
Definition: c.h:675
struct XLogRecData * next
#define elog
Definition: elog.h:219
static XLogRecData * rdatas
Definition: xloginsert.c:100
void XLogRegisterBuffer ( uint8  block_id,
Buffer  buffer,
uint8  flags 
)

Definition at line 213 of file xloginsert.c.

References Assert, begininsert_called, registered_buffer::block, BufferGetPage, BufferGetTag(), elog, ERROR, registered_buffer::flags, registered_buffer::forkno, i, registered_buffer::in_use, max_registered_block_id, max_registered_buffers, registered_buffer::page, registered_buffer::rdata_head, registered_buffer::rdata_len, registered_buffer::rdata_tail, REGBUF_FORCE_IMAGE, REGBUF_NO_IMAGE, RelFileNodeEquals, and registered_buffer::rnode.

Referenced by _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_mark_page_halfdead(), _bt_newroot(), _bt_split(), _bt_unlink_halfdead_page(), _hash_addovflpage(), _hash_doinsert(), _hash_expandtable(), _hash_freeovflpage(), _hash_init(), _hash_splitbucket(), _hash_squeezebucket(), _hash_vacuum_one_page(), addLeafTuple(), AlterSequence(), brin_doinsert(), brin_doupdate(), brinbuild(), brinRevmapDesummarizeRange(), createPostingTree(), do_setval(), doPickSplit(), fill_seq_with_data(), GenericXLogFinish(), ginbuild(), ginDeletePage(), ginHeapTupleFastInsert(), ginPlaceToPage(), ginUpdateStats(), ginVacuumPostingTreeLeaf(), gistbuild(), gistXLogSplit(), gistXLogUpdate(), hashbucketcleanup(), hashbulkdelete(), heap_abort_speculative(), heap_delete(), heap_finish_speculative(), heap_inplace_update(), heap_insert(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), heap_multi_insert(), heap_update(), log_heap_clean(), log_heap_freeze(), log_heap_update(), log_heap_visible(), log_split_page(), moveLeafs(), nextval_internal(), revmap_physical_extend(), shiftList(), spgAddNodeAction(), spgbuild(), spgSplitNodeAction(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), writeListPage(), and xlogVacuumPage().

214 {
215  registered_buffer *regbuf;
216 
217  /* NO_IMAGE doesn't make sense with FORCE_IMAGE */
218  Assert(!((flags & REGBUF_FORCE_IMAGE) && (flags & (REGBUF_NO_IMAGE))));
220 
221  if (block_id >= max_registered_block_id)
222  {
223  if (block_id >= max_registered_buffers)
224  elog(ERROR, "too many registered buffers");
225  max_registered_block_id = block_id + 1;
226  }
227 
228  regbuf = &registered_buffers[block_id];
229 
230  BufferGetTag(buffer, &regbuf->rnode, &regbuf->forkno, &regbuf->block);
231  regbuf->page = BufferGetPage(buffer);
232  regbuf->flags = flags;
233  regbuf->rdata_tail = (XLogRecData *) &regbuf->rdata_head;
234  regbuf->rdata_len = 0;
235 
236  /*
237  * Check that this page hasn't already been registered with some other
238  * block_id.
239  */
240 #ifdef USE_ASSERT_CHECKING
241  {
242  int i;
243 
244  for (i = 0; i < max_registered_block_id; i++)
245  {
246  registered_buffer *regbuf_old = &registered_buffers[i];
247 
248  if (i == block_id || !regbuf_old->in_use)
249  continue;
250 
251  Assert(!RelFileNodeEquals(regbuf_old->rnode, regbuf->rnode) ||
252  regbuf_old->forkno != regbuf->forkno ||
253  regbuf_old->block != regbuf->block);
254  }
255  }
256 #endif
257 
258  regbuf->in_use = true;
259 }
BlockNumber block
Definition: xloginsert.c:48
static bool begininsert_called
Definition: xloginsert.c:104
XLogRecData * rdata_head
Definition: xloginsert.c:51
RelFileNode rnode
Definition: xloginsert.c:46
#define ERROR
Definition: elog.h:43
static int max_registered_buffers
Definition: xloginsert.c:64
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
XLogRecData * rdata_tail
Definition: xloginsert.c:53
static registered_buffer * registered_buffers
Definition: xloginsert.c:63
#define REGBUF_FORCE_IMAGE
Definition: xloginsert.h:30
#define Assert(condition)
Definition: c.h:675
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:211
#define REGBUF_NO_IMAGE
Definition: xloginsert.h:31
ForkNumber forkno
Definition: xloginsert.c:47
static int max_registered_block_id
Definition: xloginsert.c:65
int i
#define elog
Definition: elog.h:219
void BufferGetTag(Buffer buffer, RelFileNode *rnode, ForkNumber *forknum, BlockNumber *blknum)
Definition: bufmgr.c:2626
#define RelFileNodeEquals(node1, node2)
Definition: relfilenode.h:88
void XLogRegisterData ( char *  data,
int  len 
)

Definition at line 323 of file xloginsert.c.

References Assert, begininsert_called, XLogRecData::data, elog, ERROR, XLogRecData::len, mainrdata_len, max_rdatas, XLogRecData::next, and num_rdatas.

Referenced by _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_log_reuse_page(), _bt_mark_page_halfdead(), _bt_newroot(), _bt_split(), _bt_unlink_halfdead_page(), _hash_addovflpage(), _hash_doinsert(), _hash_expandtable(), _hash_freeovflpage(), _hash_init(), _hash_splitbucket(), _hash_squeezebucket(), _hash_vacuum_one_page(), addLeafTuple(), AlterSequence(), AssignTransactionId(), brin_doinsert(), brin_doupdate(), brinbuild(), brinRevmapDesummarizeRange(), CreateCheckPoint(), createdb(), CreateEndOfRecoveryRecord(), createPostingTree(), CreateTableSpace(), do_pg_stop_backup(), do_setval(), doPickSplit(), DropTableSpace(), EndPrepare(), fill_seq_with_data(), ginDeletePage(), ginHeapTupleFastInsert(), ginPlaceToPage(), ginUpdateStats(), gistXLogSplit(), gistXLogUpdate(), hashbucketcleanup(), hashbulkdelete(), heap_abort_speculative(), heap_delete(), heap_finish_speculative(), heap_inplace_update(), heap_insert(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), heap_multi_insert(), heap_update(), log_heap_clean(), log_heap_cleanup_info(), log_heap_freeze(), log_heap_new_cid(), log_heap_update(), log_heap_visible(), log_smgrcreate(), LogAccessExclusiveLocks(), LogCurrentRunningXacts(), logical_heap_rewrite_flush_mappings(), LogLogicalMessage(), LogStandbyInvalidations(), movedb(), moveLeafs(), MultiXactIdCreateFromMembers(), nextval_internal(), pg_truncate_visibility_map(), RelationTruncate(), remove_dbtablespaces(), replorigin_advance(), replorigin_drop(), revmap_physical_extend(), shiftList(), spgAddNodeAction(), spgSplitNodeAction(), UpdateFullPageWrites(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), write_relmap_file(), writeListPage(), WriteMTruncateXlogRec(), WriteMZeroPageXlogRec(), WriteSetTimestampXlogRec(), WriteTruncateXlogRec(), WriteZeroPageXlogRec(), XactLogAbortRecord(), XactLogCommitRecord(), XLogPutNextOid(), XLogReportParameters(), and XLogRestorePoint().

324 {
325  XLogRecData *rdata;
326 
328 
329  if (num_rdatas >= max_rdatas)
330  elog(ERROR, "too much WAL data");
331  rdata = &rdatas[num_rdatas++];
332 
333  rdata->data = data;
334  rdata->len = len;
335 
336  /*
337  * we use the mainrdata_last pointer to track the end of the chain, so no
338  * need to clear 'next' here.
339  */
340 
341  mainrdata_last->next = rdata;
342  mainrdata_last = rdata;
343 
344  mainrdata_len += len;
345 }
static uint32 mainrdata_len
Definition: xloginsert.c:74
static bool begininsert_called
Definition: xloginsert.c:104
#define ERROR
Definition: elog.h:43
static int max_rdatas
Definition: xloginsert.c:102
static XLogRecData * mainrdata_last
Definition: xloginsert.c:73
static int num_rdatas
Definition: xloginsert.c:101
#define Assert(condition)
Definition: c.h:675
struct XLogRecData * next
#define elog
Definition: elog.h:219
static XLogRecData * rdatas
Definition: xloginsert.c:100
void XLogResetInsertion ( void  )

Definition at line 193 of file xloginsert.c.

References begininsert_called, curinsert_flags, i, mainrdata_len, max_registered_block_id, and num_rdatas.

Referenced by AbortSubTransaction(), AbortTransaction(), and XLogInsert().

194 {
195  int i;
196 
197  for (i = 0; i < max_registered_block_id; i++)
198  registered_buffers[i].in_use = false;
199 
200  num_rdatas = 0;
201  max_registered_block_id = 0;
202  mainrdata_len = 0;
204  curinsert_flags = 0;
205  begininsert_called = false;
206 }
static uint32 mainrdata_len
Definition: xloginsert.c:74
static bool begininsert_called
Definition: xloginsert.c:104
static XLogRecData * mainrdata_head
Definition: xloginsert.c:72
static registered_buffer * registered_buffers
Definition: xloginsert.c:63
static XLogRecData * mainrdata_last
Definition: xloginsert.c:73
static int num_rdatas
Definition: xloginsert.c:101
static int max_registered_block_id
Definition: xloginsert.c:65
int i
static uint8 curinsert_flags
Definition: xloginsert.c:77
XLogRecPtr XLogSaveBufferForHint ( Buffer  buffer,
bool  buffer_std 
)

Definition at line 893 of file xloginsert.c.

References Assert, BufferGetBlock, BufferGetLSNAtomic(), BufferGetPage, BufferGetTag(), PGXACT::delayChkpt, GetRedoRecPtr(), InvalidXLogRecPtr, lower(), MyPgXact, RedoRecPtr, REGBUF_FORCE_IMAGE, REGBUF_STANDARD, upper(), XLOG_FPI_FOR_HINT, XLogBeginInsert(), XLogInsert(), and XLogRegisterBlock().

Referenced by MarkBufferDirtyHint().

894 {
895  XLogRecPtr recptr = InvalidXLogRecPtr;
896  XLogRecPtr lsn;
898 
899  /*
900  * Ensure no checkpoint can change our view of RedoRecPtr.
901  */
903 
904  /*
905  * Update RedoRecPtr so that we can make the right decision
906  */
907  RedoRecPtr = GetRedoRecPtr();
908 
909  /*
910  * We assume page LSN is first data on *every* page that can be passed to
911  * XLogInsert, whether it has the standard page layout or not. Since we're
912  * only holding a share-lock on the page, we must take the buffer header
913  * lock when we look at the LSN.
914  */
915  lsn = BufferGetLSNAtomic(buffer);
916 
917  if (lsn <= RedoRecPtr)
918  {
919  int flags;
920  char copied_buffer[BLCKSZ];
921  char *origdata = (char *) BufferGetBlock(buffer);
922  RelFileNode rnode;
923  ForkNumber forkno;
924  BlockNumber blkno;
925 
926  /*
927  * Copy buffer so we don't have to worry about concurrent hint bit or
928  * lsn updates. We assume pd_lower/upper cannot be changed without an
929  * exclusive lock, so the contents bkp are not racy.
930  */
931  if (buffer_std)
932  {
933  /* Assume we can omit data between pd_lower and pd_upper */
934  Page page = BufferGetPage(buffer);
935  uint16 lower = ((PageHeader) page)->pd_lower;
936  uint16 upper = ((PageHeader) page)->pd_upper;
937 
938  memcpy(copied_buffer, origdata, lower);
939  memcpy(copied_buffer + upper, origdata + upper, BLCKSZ - upper);
940  }
941  else
942  memcpy(copied_buffer, origdata, BLCKSZ);
943 
944  XLogBeginInsert();
945 
946  flags = REGBUF_FORCE_IMAGE;
947  if (buffer_std)
948  flags |= REGBUF_STANDARD;
949 
950  BufferGetTag(buffer, &rnode, &forkno, &blkno);
951  XLogRegisterBlock(0, &rnode, forkno, blkno, copied_buffer, flags);
952 
953  recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI_FOR_HINT);
954  }
955 
956  return recptr;
957 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
uint32 BlockNumber
Definition: block.h:31
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:74
PGXACT * MyPgXact
Definition: proc.c:68
void XLogRegisterBlock(uint8 block_id, RelFileNode *rnode, ForkNumber forknum, BlockNumber blknum, Page page, uint8 flags)
Definition: xloginsert.c:266
unsigned short uint16
Definition: c.h:267
static XLogRecPtr RedoRecPtr
Definition: xlog.c:350
XLogRecPtr BufferGetLSNAtomic(Buffer buffer)
Definition: bufmgr.c:2832
#define REGBUF_STANDARD
Definition: xloginsert.h:35
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
bool delayChkpt
Definition: proc.h:220
ForkNumber
Definition: relpath.h:24
#define REGBUF_FORCE_IMAGE
Definition: xloginsert.h:30
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
PageHeaderData * PageHeader
Definition: bufpage.h:162
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:675
#define XLOG_FPI_FOR_HINT
Definition: pg_control.h:76
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:211
XLogRecPtr GetRedoRecPtr(void)
Definition: xlog.c:8163
void BufferGetTag(Buffer buffer, RelFileNode *rnode, ForkNumber *forknum, BlockNumber *blknum)
Definition: bufmgr.c:2626
void XLogBeginInsert(void)
Definition: xloginsert.c:120
#define BufferGetBlock(buffer)
Definition: bufmgr.h:127
Pointer Page
Definition: bufpage.h:74
void XLogSetRecordFlags ( uint8  flags)

Definition at line 397 of file xloginsert.c.

References Assert, begininsert_called, and curinsert_flags.

Referenced by heap_delete(), heap_finish_speculative(), heap_insert(), heap_multi_insert(), log_heap_update(), LogAccessExclusiveLocks(), LogCurrentRunningXacts(), LogLogicalMessage(), RequestXLogSwitch(), and XactLogCommitRecord().

398 {
400  curinsert_flags = flags;
401 }
static bool begininsert_called
Definition: xloginsert.c:104
#define Assert(condition)
Definition: c.h:675
static uint8 curinsert_flags
Definition: xloginsert.c:77

Variable Documentation

uint8 curinsert_flags = 0
static
XLogRecData hdr_rdt
static

Definition at line 87 of file xloginsert.c.

Referenced by XLogRecordAssemble().

char* hdr_scratch = NULL
static

Definition at line 88 of file xloginsert.c.

Referenced by InitXLogInsert(), and XLogRecordAssemble().

XLogRecData* mainrdata_head
static

Definition at line 72 of file xloginsert.c.

Referenced by XLogRecordAssemble().

XLogRecData* mainrdata_last = (XLogRecData *) &mainrdata_head
static

Definition at line 73 of file xloginsert.c.

Referenced by XLogRecordAssemble().

uint32 mainrdata_len
static
int max_rdatas
static
int max_registered_block_id = 0
static
int max_registered_buffers
static
int num_rdatas
static

Definition at line 101 of file xloginsert.c.

Referenced by XLogRegisterBufData(), XLogRegisterData(), and XLogResetInsertion().

XLogRecData* rdatas
static

Definition at line 100 of file xloginsert.c.

registered_buffer* registered_buffers
static

Definition at line 63 of file xloginsert.c.

MemoryContext xloginsert_cxt
static

Definition at line 107 of file xloginsert.c.