PostgreSQL Source Code  git master
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 "executor/instrument.h"
#include "miscadmin.h"
#include "pg_trace.h"
#include "replication/origin.h"
#include "storage/bufmgr.h"
#include "storage/proc.h"
#include "utils/memutils.h"
Include dependency graph for xloginsert.c:

Go to the source code of this file.

Data Structures

struct  registered_buffer
 

Macros

#define LZ4_MAX_BLCKSZ   0
 
#define PGLZ_MAX_BLCKSZ   PGLZ_MAX_OUTPUT(BLCKSZ)
 
#define COMPRESS_BUFSIZE   Max(PGLZ_MAX_BLCKSZ, LZ4_MAX_BLCKSZ)
 
#define SizeOfXlogOrigin   (sizeof(RepOriginId) + sizeof(char))
 
#define SizeOfXLogTransactionId   (sizeof(TransactionId) + sizeof(char))
 
#define HEADER_SCRATCH_SIZE
 

Functions

static XLogRecDataXLogRecordAssemble (RmgrId rmid, uint8 info, XLogRecPtr RedoRecPtr, bool doPageWrites, XLogRecPtr *fpw_lsn, int *num_fpi)
 
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)
 
void log_newpages (RelFileNode *rnode, ForkNumber forkNum, int num_pages, BlockNumber *blknos, Page *pages, bool page_std)
 
XLogRecPtr log_newpage_buffer (Buffer buffer, bool page_std)
 
void log_newpage_range (Relation rel, ForkNumber forkNum, BlockNumber startblk, BlockNumber endblk, 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

◆ COMPRESS_BUFSIZE

#define COMPRESS_BUFSIZE   Max(PGLZ_MAX_BLCKSZ, LZ4_MAX_BLCKSZ)

Definition at line 49 of file xloginsert.c.

Referenced by XLogCompressBackupBlock().

◆ HEADER_SCRATCH_SIZE

#define HEADER_SCRATCH_SIZE
Value:
MaxSizeOfXLogRecordBlockHeader * (XLR_MAX_BLOCK_ID + 1) + \
#define SizeOfXlogOrigin
Definition: xloginsert.c:103
#define SizeOfXLogTransactionId
Definition: xloginsert.c:104
#define XLR_MAX_BLOCK_ID
Definition: xlogrecord.h:225
#define SizeOfXLogRecord
Definition: xlogrecord.h:55
#define SizeOfXLogRecordDataHeaderLong
Definition: xlogrecord.h:212

Definition at line 106 of file xloginsert.c.

Referenced by InitXLogInsert().

◆ LZ4_MAX_BLCKSZ

#define LZ4_MAX_BLCKSZ   0

Definition at line 44 of file xloginsert.c.

◆ PGLZ_MAX_BLCKSZ

#define PGLZ_MAX_BLCKSZ   PGLZ_MAX_OUTPUT(BLCKSZ)

Definition at line 47 of file xloginsert.c.

◆ SizeOfXlogOrigin

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

Definition at line 103 of file xloginsert.c.

◆ SizeOfXLogTransactionId

#define SizeOfXLogTransactionId   (sizeof(TransactionId) + sizeof(char))

Definition at line 104 of file xloginsert.c.

Function Documentation

◆ InitXLogInsert()

void InitXLogInsert ( void  )

Definition at line 1249 of file xloginsert.c.

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

Referenced by CreateCheckPoint(), and InitXLOGAccess().

1250 {
1251  /* Initialize the working areas */
1252  if (xloginsert_cxt == NULL)
1253  {
1255  "WAL record construction",
1257  }
1258 
1259  if (registered_buffers == NULL)
1260  {
1263  sizeof(registered_buffer) * (XLR_NORMAL_MAX_BLOCK_ID + 1));
1265  }
1266  if (rdatas == NULL)
1267  {
1269  sizeof(XLogRecData) * XLR_NORMAL_RDATAS);
1271  }
1272 
1273  /*
1274  * Allocate a buffer to hold the header information for a WAL record.
1275  */
1276  if (hdr_scratch == NULL)
1279 }
#define AllocSetContextCreate
Definition: memutils.h:173
#define HEADER_SCRATCH_SIZE
Definition: xloginsert.c:106
#define XLR_NORMAL_RDATAS
Definition: xloginsert.h:28
static int max_registered_buffers
Definition: xloginsert.c:77
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:195
static int max_rdatas
Definition: xloginsert.c:117
MemoryContext TopMemoryContext
Definition: mcxt.c:48
static registered_buffer * registered_buffers
Definition: xloginsert.c:76
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:906
#define XLR_NORMAL_MAX_BLOCK_ID
Definition: xloginsert.h:27
static char * hdr_scratch
Definition: xloginsert.c:101
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
static MemoryContext xloginsert_cxt
Definition: xloginsert.c:122
static XLogRecData * rdatas
Definition: xloginsert.c:115

◆ log_newpage()

XLogRecPtr log_newpage ( RelFileNode rnode,
ForkNumber  forkNum,
BlockNumber  blkno,
Page  page,
bool  page_std 
)

Definition at line 1048 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(), end_heap_rewrite(), gist_indexsortbuild(), log_newpage_buffer(), raw_heap_insert(), RelationCopyStorage(), and spgbuildempty().

1050 {
1051  int flags;
1052  XLogRecPtr recptr;
1053 
1054  flags = REGBUF_FORCE_IMAGE;
1055  if (page_std)
1056  flags |= REGBUF_STANDARD;
1057 
1058  XLogBeginInsert();
1059  XLogRegisterBlock(0, rnode, forkNum, blkno, page, flags);
1060  recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI);
1061 
1062  /*
1063  * The page may be uninitialized. If so, we can't set the LSN because that
1064  * would corrupt the page.
1065  */
1066  if (!PageIsNew(page))
1067  {
1068  PageSetLSN(page, recptr);
1069  }
1070 
1071  return recptr;
1072 }
void XLogRegisterBlock(uint8 block_id, RelFileNode *rnode, ForkNumber forknum, BlockNumber blknum, Page page, uint8 flags)
Definition: xloginsert.c:285
#define REGBUF_STANDARD
Definition: xloginsert.h:35
#define REGBUF_FORCE_IMAGE
Definition: xloginsert.h:31
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:432
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define XLOG_FPI
Definition: pg_control.h:78
#define PageIsNew(page)
Definition: bufpage.h:229
void XLogBeginInsert(void)
Definition: xloginsert.c:135
#define PageSetLSN(page, lsn)
Definition: bufpage.h:368

◆ log_newpage_buffer()

XLogRecPtr log_newpage_buffer ( Buffer  buffer,
bool  page_std 
)

Definition at line 1142 of file xloginsert.c.

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

Referenced by brin_initialize_empty_new_buffer(), brinbuildempty(), FreeSpaceMapPrepareTruncateRel(), ginbuildempty(), gistbuildempty(), heap_force_common(), lazy_scan_heap(), and visibilitymap_prepare_truncate().

1143 {
1144  Page page = BufferGetPage(buffer);
1145  RelFileNode rnode;
1146  ForkNumber forkNum;
1147  BlockNumber blkno;
1148 
1149  /* Shared buffers should be modified in a critical section. */
1150  Assert(CritSectionCount > 0);
1151 
1152  BufferGetTag(buffer, &rnode, &forkNum, &blkno);
1153 
1154  return log_newpage(&rnode, forkNum, blkno, page, page_std);
1155 }
uint32 BlockNumber
Definition: block.h:31
volatile uint32 CritSectionCount
Definition: globals.c:41
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
ForkNumber
Definition: relpath.h:40
#define Assert(condition)
Definition: c.h:804
XLogRecPtr log_newpage(RelFileNode *rnode, ForkNumber forkNum, BlockNumber blkno, Page page, bool page_std)
Definition: xloginsert.c:1048
void BufferGetTag(Buffer buffer, RelFileNode *rnode, ForkNumber *forknum, BlockNumber *blknum)
Definition: bufmgr.c:2773
Pointer Page
Definition: bufpage.h:78

◆ log_newpage_range()

void log_newpage_range ( Relation  rel,
ForkNumber  forkNum,
BlockNumber  startblk,
BlockNumber  endblk,
bool  page_std 
)

Definition at line 1175 of file xloginsert.c.

References buf, BUFFER_LOCK_EXCLUSIVE, BufferGetPage, CHECK_FOR_INTERRUPTS, END_CRIT_SECTION, i, LockBuffer(), MarkBufferDirty(), PageIsNew, PageSetLSN, RBM_NORMAL, ReadBufferExtended(), REGBUF_FORCE_IMAGE, REGBUF_STANDARD, START_CRIT_SECTION, UnlockReleaseBuffer(), XLOG_FPI, XLogBeginInsert(), XLogEnsureRecordSpace(), XLogInsert(), XLogRegisterBuffer(), and XLR_MAX_BLOCK_ID.

Referenced by ginbuild(), gistbuild(), smgrDoPendingSyncs(), and spgbuild().

1178 {
1179  int flags;
1180  BlockNumber blkno;
1181 
1182  flags = REGBUF_FORCE_IMAGE;
1183  if (page_std)
1184  flags |= REGBUF_STANDARD;
1185 
1186  /*
1187  * Iterate over all the pages in the range. They are collected into
1188  * batches of XLR_MAX_BLOCK_ID pages, and a single WAL-record is written
1189  * for each batch.
1190  */
1192 
1193  blkno = startblk;
1194  while (blkno < endblk)
1195  {
1196  Buffer bufpack[XLR_MAX_BLOCK_ID];
1197  XLogRecPtr recptr;
1198  int nbufs;
1199  int i;
1200 
1202 
1203  /* Collect a batch of blocks. */
1204  nbufs = 0;
1205  while (nbufs < XLR_MAX_BLOCK_ID && blkno < endblk)
1206  {
1207  Buffer buf = ReadBufferExtended(rel, forkNum, blkno,
1208  RBM_NORMAL, NULL);
1209 
1211 
1212  /*
1213  * Completely empty pages are not WAL-logged. Writing a WAL record
1214  * would change the LSN, and we don't want that. We want the page
1215  * to stay empty.
1216  */
1217  if (!PageIsNew(BufferGetPage(buf)))
1218  bufpack[nbufs++] = buf;
1219  else
1220  UnlockReleaseBuffer(buf);
1221  blkno++;
1222  }
1223 
1224  /* Write WAL record for this batch. */
1225  XLogBeginInsert();
1226 
1228  for (i = 0; i < nbufs; i++)
1229  {
1230  XLogRegisterBuffer(i, bufpack[i], flags);
1231  MarkBufferDirty(bufpack[i]);
1232  }
1233 
1234  recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI);
1235 
1236  for (i = 0; i < nbufs; i++)
1237  {
1238  PageSetLSN(BufferGetPage(bufpack[i]), recptr);
1239  UnlockReleaseBuffer(bufpack[i]);
1240  }
1241  END_CRIT_SECTION();
1242  }
1243 }
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:1556
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
Definition: xloginsert.c:232
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:741
#define END_CRIT_SECTION()
Definition: miscadmin.h:149
#define START_CRIT_SECTION()
Definition: miscadmin.h:147
uint32 BlockNumber
Definition: block.h:31
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:98
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3795
static char * buf
Definition: pg_test_fsync.c:68
#define REGBUF_STANDARD
Definition: xloginsert.h:35
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
#define XLR_MAX_BLOCK_ID
Definition: xlogrecord.h:225
#define REGBUF_FORCE_IMAGE
Definition: xloginsert.h:31
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:432
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:4011
uint64 XLogRecPtr
Definition: xlogdefs.h:21
void XLogEnsureRecordSpace(int max_block_id, int ndatas)
Definition: xloginsert.c:161
#define XLOG_FPI
Definition: pg_control.h:78
#define PageIsNew(page)
Definition: bufpage.h:229
int i
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:120
void XLogBeginInsert(void)
Definition: xloginsert.c:135
#define PageSetLSN(page, lsn)
Definition: bufpage.h:368
int Buffer
Definition: buf.h:23

◆ log_newpages()

void log_newpages ( RelFileNode rnode,
ForkNumber  forkNum,
int  num_pages,
BlockNumber blknos,
Page pages,
bool  page_std 
)

Definition at line 1080 of file xloginsert.c.

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

Referenced by gist_indexsortbuild_flush_ready_pages().

1082 {
1083  int flags;
1084  XLogRecPtr recptr;
1085  int i;
1086  int j;
1087 
1088  flags = REGBUF_FORCE_IMAGE;
1089  if (page_std)
1090  flags |= REGBUF_STANDARD;
1091 
1092  /*
1093  * Iterate over all the pages. They are collected into batches of
1094  * XLR_MAX_BLOCK_ID pages, and a single WAL-record is written for each
1095  * batch.
1096  */
1098 
1099  i = 0;
1100  while (i < num_pages)
1101  {
1102  int batch_start = i;
1103  int nbatch;
1104 
1105  XLogBeginInsert();
1106 
1107  nbatch = 0;
1108  while (nbatch < XLR_MAX_BLOCK_ID && i < num_pages)
1109  {
1110  XLogRegisterBlock(nbatch, rnode, forkNum, blknos[i], pages[i], flags);
1111  i++;
1112  nbatch++;
1113  }
1114 
1115  recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI);
1116 
1117  for (j = batch_start; j < i; j++)
1118  {
1119  /*
1120  * The page may be uninitialized. If so, we can't set the LSN
1121  * because that would corrupt the page.
1122  */
1123  if (!PageIsNew(pages[j]))
1124  {
1125  PageSetLSN(pages[j], recptr);
1126  }
1127  }
1128  }
1129 }
void XLogRegisterBlock(uint8 block_id, RelFileNode *rnode, ForkNumber forknum, BlockNumber blknum, Page page, uint8 flags)
Definition: xloginsert.c:285
#define REGBUF_STANDARD
Definition: xloginsert.h:35
#define XLR_MAX_BLOCK_ID
Definition: xlogrecord.h:225
#define REGBUF_FORCE_IMAGE
Definition: xloginsert.h:31
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:432
uint64 XLogRecPtr
Definition: xlogdefs.h:21
void XLogEnsureRecordSpace(int max_block_id, int ndatas)
Definition: xloginsert.c:161
#define XLOG_FPI
Definition: pg_control.h:78
#define PageIsNew(page)
Definition: bufpage.h:229
int i
void XLogBeginInsert(void)
Definition: xloginsert.c:135
#define PageSetLSN(page, lsn)
Definition: bufpage.h:368

◆ XLogBeginInsert()

void XLogBeginInsert ( void  )

Definition at line 135 of file xloginsert.c.

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

Referenced by _bt_dedup_pass(), _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_log_reuse_page(), _bt_mark_page_halfdead(), _bt_newroot(), _bt_set_cleanup_info(), _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(), AssignTransactionId(), brin_doinsert(), brin_doupdate(), brinbuild(), brinRevmapDesummarizeRange(), CreateCheckPoint(), createdb(), CreateEndOfRecoveryRecord(), createPostingTree(), CreateTableSpace(), do_pg_stop_backup(), do_setval(), doPickSplit(), DropTableSpace(), EndPrepare(), ExecuteTruncateGuts(), fill_seq_with_data(), GenericXLogFinish(), ginDeletePage(), ginHeapTupleFastInsert(), ginPlaceToPage(), ginUpdateStats(), ginVacuumPostingTreeLeaf(), gistXLogAssignLSN(), gistXLogDelete(), gistXLogPageDelete(), gistXLogPageReuse(), 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_page_prune(), heap_update(), lazy_vacuum_heap_page(), log_heap_freeze(), log_heap_new_cid(), log_heap_update(), log_heap_visible(), log_newpage(), log_newpage_range(), log_newpages(), log_smgrcreate(), log_split_page(), LogAccessExclusiveLocks(), LogCurrentRunningXacts(), logical_heap_rewrite_flush_mappings(), LogLogicalInvalidations(), LogLogicalMessage(), LogStandbyInvalidations(), movedb(), moveLeafs(), MultiXactIdCreateFromMembers(), nextval_internal(), pg_truncate_visibility_map(), RelationTruncate(), remove_dbtablespaces(), replorigin_advance(), replorigin_drop_guts(), RequestXLogSwitch(), revmap_physical_extend(), shiftList(), spgAddNodeAction(), spgSplitNodeAction(), UpdateFullPageWrites(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), write_relmap_file(), writeListPage(), WriteMTruncateXlogRec(), WriteMZeroPageXlogRec(), WriteTruncateXlogRec(), WriteZeroPageXlogRec(), XactLogAbortRecord(), XactLogCommitRecord(), XLogPutNextOid(), XLogReportParameters(), XLogRestorePoint(), XLogSaveBufferForHint(), and xlogVacuumPage().

136 {
139  Assert(mainrdata_len == 0);
140 
141  /* cross-check on whether we should be here or not */
142  if (!XLogInsertAllowed())
143  elog(ERROR, "cannot make new WAL entries during recovery");
144 
145  if (begininsert_called)
146  elog(ERROR, "XLogBeginInsert was already called");
147 
148  begininsert_called = true;
149 }
static uint32 mainrdata_len
Definition: xloginsert.c:87
static bool begininsert_called
Definition: xloginsert.c:119
#define ERROR
Definition: elog.h:46
static XLogRecData * mainrdata_head
Definition: xloginsert.c:85
bool XLogInsertAllowed(void)
Definition: xlog.c:8330
static XLogRecData * mainrdata_last
Definition: xloginsert.c:86
#define Assert(condition)
Definition: c.h:804
static int max_registered_block_id
Definition: xloginsert.c:78
#define elog(elevel,...)
Definition: elog.h:232

◆ XLogCheckBufferNeedsBackup()

bool XLogCheckBufferNeedsBackup ( Buffer  buffer)

Definition at line 932 of file xloginsert.c.

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

Referenced by log_heap_update().

933 {
935  bool doPageWrites;
936  Page page;
937 
938  GetFullPageWriteInfo(&RedoRecPtr, &doPageWrites);
939 
940  page = BufferGetPage(buffer);
941 
942  if (doPageWrites && PageGetLSN(page) <= RedoRecPtr)
943  return true; /* buffer requires backup */
944 
945  return false; /* buffer does not need to be backed up */
946 }
static bool doPageWrites
Definition: xlog.c:364
static XLogRecPtr RedoRecPtr
Definition: xlog.c:357
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define PageGetLSN(page)
Definition: bufpage.h:366
void GetFullPageWriteInfo(XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p)
Definition: xlog.c:8538
Pointer Page
Definition: bufpage.h:78

◆ XLogCompressBackupBlock()

static bool XLogCompressBackupBlock ( char *  page,
uint16  hole_offset,
uint16  hole_length,
char *  dest,
uint16 dlen 
)
static

Definition at line 860 of file xloginsert.c.

References Assert, COMPRESS_BUFSIZE, PGAlignedBlock::data, elog, ERROR, pglz_compress(), PGLZ_strategy_default, SizeOfXLogRecordBlockCompressHeader, source, wal_compression, WAL_COMPRESSION_LZ4, WAL_COMPRESSION_NONE, and WAL_COMPRESSION_PGLZ.

Referenced by XLogRecordAssemble().

862 {
863  int32 orig_len = BLCKSZ - hole_length;
864  int32 len = -1;
865  int32 extra_bytes = 0;
866  char *source;
867  PGAlignedBlock tmp;
868 
869  if (hole_length != 0)
870  {
871  /* must skip the hole */
872  source = tmp.data;
873  memcpy(source, page, hole_offset);
874  memcpy(source + hole_offset,
875  page + (hole_offset + hole_length),
876  BLCKSZ - (hole_length + hole_offset));
877 
878  /*
879  * Extra data needs to be stored in WAL record for the compressed
880  * version of block image if the hole exists.
881  */
883  }
884  else
885  source = page;
886 
888  {
890  len = pglz_compress(source, orig_len, dest, PGLZ_strategy_default);
891  break;
892 
893  case WAL_COMPRESSION_LZ4:
894 #ifdef USE_LZ4
895  len = LZ4_compress_default(source, dest, orig_len,
897  if (len <= 0)
898  len = -1; /* failure */
899 #else
900  elog(ERROR, "LZ4 is not supported by this build");
901 #endif
902  break;
903 
905  Assert(false); /* cannot happen */
906  break;
907  /* no default case, so that compiler will warn */
908  }
909 
910  /*
911  * We recheck the actual size even if compression reports success and see
912  * if the number of bytes saved by compression is larger than the length
913  * of extra data needed for the compressed version of block image.
914  */
915  if (len >= 0 &&
916  len + extra_bytes < orig_len)
917  {
918  *dlen = (uint16) len; /* successful compression */
919  return true;
920  }
921  return false;
922 }
#define COMPRESS_BUFSIZE
Definition: xloginsert.c:49
signed int int32
Definition: c.h:429
char data[BLCKSZ]
Definition: c.h:1141
unsigned short uint16
Definition: c.h:440
#define ERROR
Definition: elog.h:46
int32 pglz_compress(const char *source, int32 slen, char *dest, const PGLZ_Strategy *strategy)
int wal_compression
Definition: xlog.c:101
WalCompression
Definition: xlog.h:129
#define Assert(condition)
Definition: c.h:804
static rewind_source * source
Definition: pg_rewind.c:79
#define elog(elevel,...)
Definition: elog.h:232
const PGLZ_Strategy *const PGLZ_strategy_default
#define SizeOfXLogRecordBlockCompressHeader
Definition: xlogrecord.h:164

◆ XLogEnsureRecordSpace()

void XLogEnsureRecordSpace ( int  max_block_id,
int  ndatas 
)

Definition at line 161 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(), log_newpage_range(), log_newpages(), and shiftList().

162 {
163  int nbuffers;
164 
165  /*
166  * This must be called before entering a critical section, because
167  * allocating memory inside a critical section can fail. repalloc() will
168  * check the same, but better to check it here too so that we fail
169  * consistently even if the arrays happen to be large enough already.
170  */
171  Assert(CritSectionCount == 0);
172 
173  /* the minimum values can't be decreased */
174  if (max_block_id < XLR_NORMAL_MAX_BLOCK_ID)
175  max_block_id = XLR_NORMAL_MAX_BLOCK_ID;
176  if (ndatas < XLR_NORMAL_RDATAS)
177  ndatas = XLR_NORMAL_RDATAS;
178 
179  if (max_block_id > XLR_MAX_BLOCK_ID)
180  elog(ERROR, "maximum number of WAL record block references exceeded");
181  nbuffers = max_block_id + 1;
182 
183  if (nbuffers > max_registered_buffers)
184  {
186  repalloc(registered_buffers, sizeof(registered_buffer) * nbuffers);
187 
188  /*
189  * At least the padding bytes in the structs must be zeroed, because
190  * they are included in WAL data, but initialize it all for tidiness.
191  */
193  (nbuffers - max_registered_buffers) * sizeof(registered_buffer));
194  max_registered_buffers = nbuffers;
195  }
196 
197  if (ndatas > max_rdatas)
198  {
199  rdatas = (XLogRecData *) repalloc(rdatas, sizeof(XLogRecData) * ndatas);
200  max_rdatas = ndatas;
201  }
202 }
#define XLR_NORMAL_RDATAS
Definition: xloginsert.h:28
#define MemSet(start, val, len)
Definition: c.h:1008
#define ERROR
Definition: elog.h:46
static int max_registered_buffers
Definition: xloginsert.c:77
volatile uint32 CritSectionCount
Definition: globals.c:41
static int max_rdatas
Definition: xloginsert.c:117
#define XLR_MAX_BLOCK_ID
Definition: xlogrecord.h:225
static registered_buffer * registered_buffers
Definition: xloginsert.c:76
#define XLR_NORMAL_MAX_BLOCK_ID
Definition: xloginsert.h:27
#define Assert(condition)
Definition: c.h:804
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1182
#define elog(elevel,...)
Definition: elog.h:232
static XLogRecData * rdatas
Definition: xloginsert.c:115

◆ XLogInsert()

XLogRecPtr XLogInsert ( RmgrId  rmid,
uint8  info 
)

Definition at line 432 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_dedup_pass(), _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_log_reuse_page(), _bt_mark_page_halfdead(), _bt_newroot(), _bt_set_cleanup_info(), _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(), AssignTransactionId(), brin_doinsert(), brin_doupdate(), brinbuild(), brinRevmapDesummarizeRange(), CreateCheckPoint(), createdb(), CreateEndOfRecoveryRecord(), createPostingTree(), CreateTableSpace(), do_pg_stop_backup(), do_setval(), doPickSplit(), DropTableSpace(), EndPrepare(), ExecuteTruncateGuts(), fill_seq_with_data(), GenericXLogFinish(), ginDeletePage(), ginHeapTupleFastInsert(), ginPlaceToPage(), ginUpdateStats(), ginVacuumPostingTreeLeaf(), gistXLogAssignLSN(), gistXLogDelete(), gistXLogPageDelete(), gistXLogPageReuse(), 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_page_prune(), heap_update(), lazy_vacuum_heap_page(), log_heap_freeze(), log_heap_new_cid(), log_heap_update(), log_heap_visible(), log_newpage(), log_newpage_range(), log_newpages(), log_smgrcreate(), log_split_page(), LogAccessExclusiveLocks(), LogCurrentRunningXacts(), logical_heap_rewrite_flush_mappings(), LogLogicalInvalidations(), LogLogicalMessage(), LogStandbyInvalidations(), movedb(), moveLeafs(), MultiXactIdCreateFromMembers(), nextval_internal(), pg_truncate_visibility_map(), RelationTruncate(), remove_dbtablespaces(), replorigin_advance(), replorigin_drop_guts(), RequestXLogSwitch(), revmap_physical_extend(), shiftList(), spgAddNodeAction(), spgSplitNodeAction(), UpdateFullPageWrites(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), write_relmap_file(), writeListPage(), WriteMTruncateXlogRec(), WriteMZeroPageXlogRec(), WriteTruncateXlogRec(), WriteZeroPageXlogRec(), XactLogAbortRecord(), XactLogCommitRecord(), XLogPutNextOid(), XLogReportParameters(), XLogRestorePoint(), XLogSaveBufferForHint(), and xlogVacuumPage().

433 {
434  XLogRecPtr EndPos;
435 
436  /* XLogBeginInsert() must have been called. */
437  if (!begininsert_called)
438  elog(ERROR, "XLogBeginInsert was not called");
439 
440  /*
441  * The caller can set rmgr bits, XLR_SPECIAL_REL_UPDATE and
442  * XLR_CHECK_CONSISTENCY; the rest are reserved for use by me.
443  */
444  if ((info & ~(XLR_RMGR_INFO_MASK |
446  XLR_CHECK_CONSISTENCY)) != 0)
447  elog(PANIC, "invalid xlog info mask %02X", info);
448 
449  TRACE_POSTGRESQL_WAL_INSERT(rmid, info);
450 
451  /*
452  * In bootstrap mode, we don't actually log anything but XLOG resources;
453  * return a phony record pointer.
454  */
455  if (IsBootstrapProcessingMode() && rmid != RM_XLOG_ID)
456  {
458  EndPos = SizeOfXLogLongPHD; /* start of 1st chkpt record */
459  return EndPos;
460  }
461 
462  do
463  {
465  bool doPageWrites;
466  XLogRecPtr fpw_lsn;
467  XLogRecData *rdt;
468  int num_fpi = 0;
469 
470  /*
471  * Get values needed to decide whether to do full-page writes. Since
472  * we don't yet have an insertion lock, these could change under us,
473  * but XLogInsertRecord will recheck them once it has a lock.
474  */
475  GetFullPageWriteInfo(&RedoRecPtr, &doPageWrites);
476 
477  rdt = XLogRecordAssemble(rmid, info, RedoRecPtr, doPageWrites,
478  &fpw_lsn, &num_fpi);
479 
480  EndPos = XLogInsertRecord(rdt, fpw_lsn, curinsert_flags, num_fpi);
481  } while (EndPos == InvalidXLogRecPtr);
482 
484 
485  return EndPos;
486 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define XLR_SPECIAL_REL_UPDATE
Definition: xlogrecord.h:71
static bool begininsert_called
Definition: xloginsert.c:119
#define PANIC
Definition: elog.h:50
#define XLR_CHECK_CONSISTENCY
Definition: xlogrecord.h:80
static bool doPageWrites
Definition: xlog.c:364
#define ERROR
Definition: elog.h:46
void XLogResetInsertion(void)
Definition: xloginsert.c:208
static XLogRecData * XLogRecordAssemble(RmgrId rmid, uint8 info, XLogRecPtr RedoRecPtr, bool doPageWrites, XLogRecPtr *fpw_lsn, int *num_fpi)
Definition: xloginsert.c:501
static XLogRecPtr RedoRecPtr
Definition: xlog.c:357
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:406
void GetFullPageWriteInfo(XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p)
Definition: xlog.c:8538
#define elog(elevel,...)
Definition: elog.h:232
XLogRecPtr XLogInsertRecord(XLogRecData *rdata, XLogRecPtr fpw_lsn, uint8 flags, int num_fpi)
Definition: xlog.c:998
static uint8 curinsert_flags
Definition: xloginsert.c:90
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:69
#define XLR_RMGR_INFO_MASK
Definition: xlogrecord.h:63

◆ XLogRecordAssemble()

static XLogRecData * XLogRecordAssemble ( RmgrId  rmid,
uint8  info,
XLogRecPtr  RedoRecPtr,
bool  doPageWrites,
XLogRecPtr fpw_lsn,
int *  num_fpi 
)
static

Definition at line 501 of file xloginsert.c.

References Assert, XLogRecordBlockImageHeader::bimg_info, registered_buffer::bkp_rdatas, BKPBLOCK_HAS_DATA, BKPBLOCK_HAS_IMAGE, BKPBLOCK_SAME_REL, BKPBLOCK_WILL_INIT, BKPIMAGE_APPLY, BKPIMAGE_COMPRESS_LZ4, BKPIMAGE_COMPRESS_PGLZ, BKPIMAGE_HAS_HOLE, registered_buffer::block, COMP_CRC32C, registered_buffer::compressed_page, curinsert_flags, XLogRecData::data, XLogRecordBlockHeader::data_length, elog, ERROR, registered_buffer::flags, XLogRecordBlockHeader::fork_flags, registered_buffer::forkno, GetCurrentTransactionIdIfAny(), GetTopTransactionIdIfAny(), hdr_rdt, hdr_scratch, XLogRecordBlockCompressHeader::hole_length, XLogRecordBlockImageHeader::hole_offset, XLogRecordBlockHeader::id, registered_buffer::in_use, INIT_CRC32C, InvalidRepOriginId, InvalidXLogRecPtr, IsSubTransactionAssignmentPending(), XLogRecData::len, XLogRecordBlockImageHeader::length, lower(), mainrdata_head, mainrdata_last, mainrdata_len, max_registered_block_id, XLogRecData::next, 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_COMPRESSION_LZ4, WAL_COMPRESSION_NONE, WAL_COMPRESSION_PGLZ, 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, XLOG_INCLUDE_XID, XLogCompressBackupBlock(), XLogSetRecordFlags(), XLR_BLOCK_ID_DATA_LONG, XLR_BLOCK_ID_DATA_SHORT, XLR_BLOCK_ID_ORIGIN, XLR_BLOCK_ID_TOPLEVEL_XID, and XLR_CHECK_CONSISTENCY.

Referenced by XLogInsert().

504 {
505  XLogRecData *rdt;
506  uint32 total_len = 0;
507  int block_id;
508  pg_crc32c rdata_crc;
509  registered_buffer *prev_regbuf = NULL;
510  XLogRecData *rdt_datas_last;
511  XLogRecord *rechdr;
512  char *scratch = hdr_scratch;
513 
514  /*
515  * Note: this function can be called multiple times for the same record.
516  * All the modifications we do to the rdata chains below must handle that.
517  */
518 
519  /* The record begins with the fixed-size header */
520  rechdr = (XLogRecord *) scratch;
521  scratch += SizeOfXLogRecord;
522 
523  hdr_rdt.next = NULL;
524  rdt_datas_last = &hdr_rdt;
526 
527  /*
528  * Enforce consistency checks for this record if user is looking for it.
529  * Do this before at the beginning of this routine to give the possibility
530  * for callers of XLogInsert() to pass XLR_CHECK_CONSISTENCY directly for
531  * a record.
532  */
533  if (wal_consistency_checking[rmid])
534  info |= XLR_CHECK_CONSISTENCY;
535 
536  /*
537  * Make an rdata chain containing all the data portions of all block
538  * references. This includes the data for full-page images. Also append
539  * the headers for the block references in the scratch buffer.
540  */
541  *fpw_lsn = InvalidXLogRecPtr;
542  for (block_id = 0; block_id < max_registered_block_id; block_id++)
543  {
544  registered_buffer *regbuf = &registered_buffers[block_id];
545  bool needs_backup;
546  bool needs_data;
549  XLogRecordBlockCompressHeader cbimg = {0};
550  bool samerel;
551  bool is_compressed = false;
552  bool include_image;
553 
554  if (!regbuf->in_use)
555  continue;
556 
557  /* Determine if this block needs to be backed up */
558  if (regbuf->flags & REGBUF_FORCE_IMAGE)
559  needs_backup = true;
560  else if (regbuf->flags & REGBUF_NO_IMAGE)
561  needs_backup = false;
562  else if (!doPageWrites)
563  needs_backup = false;
564  else
565  {
566  /*
567  * We assume page LSN is first data on *every* page that can be
568  * passed to XLogInsert, whether it has the standard page layout
569  * or not.
570  */
571  XLogRecPtr page_lsn = PageGetLSN(regbuf->page);
572 
573  needs_backup = (page_lsn <= RedoRecPtr);
574  if (!needs_backup)
575  {
576  if (*fpw_lsn == InvalidXLogRecPtr || page_lsn < *fpw_lsn)
577  *fpw_lsn = page_lsn;
578  }
579  }
580 
581  /* Determine if the buffer data needs to included */
582  if (regbuf->rdata_len == 0)
583  needs_data = false;
584  else if ((regbuf->flags & REGBUF_KEEP_DATA) != 0)
585  needs_data = true;
586  else
587  needs_data = !needs_backup;
588 
589  bkpb.id = block_id;
590  bkpb.fork_flags = regbuf->forkno;
591  bkpb.data_length = 0;
592 
593  if ((regbuf->flags & REGBUF_WILL_INIT) == REGBUF_WILL_INIT)
595 
596  /*
597  * If needs_backup is true or WAL checking is enabled for current
598  * resource manager, log a full-page write for the current block.
599  */
600  include_image = needs_backup || (info & XLR_CHECK_CONSISTENCY) != 0;
601 
602  if (include_image)
603  {
604  Page page = regbuf->page;
605  uint16 compressed_len = 0;
606 
607  /*
608  * The page needs to be backed up, so calculate its hole length
609  * and offset.
610  */
611  if (regbuf->flags & REGBUF_STANDARD)
612  {
613  /* Assume we can omit data between pd_lower and pd_upper */
614  uint16 lower = ((PageHeader) page)->pd_lower;
615  uint16 upper = ((PageHeader) page)->pd_upper;
616 
617  if (lower >= SizeOfPageHeaderData &&
618  upper > lower &&
619  upper <= BLCKSZ)
620  {
621  bimg.hole_offset = lower;
622  cbimg.hole_length = upper - lower;
623  }
624  else
625  {
626  /* No "hole" to remove */
627  bimg.hole_offset = 0;
628  cbimg.hole_length = 0;
629  }
630  }
631  else
632  {
633  /* Not a standard page header, don't try to eliminate "hole" */
634  bimg.hole_offset = 0;
635  cbimg.hole_length = 0;
636  }
637 
638  /*
639  * Try to compress a block image if wal_compression is enabled
640  */
642  {
643  is_compressed =
645  cbimg.hole_length,
646  regbuf->compressed_page,
647  &compressed_len);
648  }
649 
650  /*
651  * Fill in the remaining fields in the XLogRecordBlockHeader
652  * struct
653  */
655 
656  /* Report a full page image constructed for the WAL record */
657  *num_fpi += 1;
658 
659  /*
660  * Construct XLogRecData entries for the page content.
661  */
662  rdt_datas_last->next = &regbuf->bkp_rdatas[0];
663  rdt_datas_last = rdt_datas_last->next;
664 
665  bimg.bimg_info = (cbimg.hole_length == 0) ? 0 : BKPIMAGE_HAS_HOLE;
666 
667  /*
668  * If WAL consistency checking is enabled for the resource manager
669  * of this WAL record, a full-page image is included in the record
670  * for the block modified. During redo, the full-page is replayed
671  * only if BKPIMAGE_APPLY is set.
672  */
673  if (needs_backup)
674  bimg.bimg_info |= BKPIMAGE_APPLY;
675 
676  if (is_compressed)
677  {
678  /* The current compression is stored in the WAL record */
679  bimg.length = compressed_len;
680 
681  /* Set the compression method used for this block */
683  {
686  break;
687 
688  case WAL_COMPRESSION_LZ4:
689 #ifdef USE_LZ4
691 #else
692  elog(ERROR, "LZ4 is not supported by this build");
693 #endif
694  break;
695 
697  Assert(false); /* cannot happen */
698  break;
699  /* no default case, so that compiler will warn */
700  }
701 
702  rdt_datas_last->data = regbuf->compressed_page;
703  rdt_datas_last->len = compressed_len;
704  }
705  else
706  {
707  bimg.length = BLCKSZ - cbimg.hole_length;
708 
709  if (cbimg.hole_length == 0)
710  {
711  rdt_datas_last->data = page;
712  rdt_datas_last->len = BLCKSZ;
713  }
714  else
715  {
716  /* must skip the hole */
717  rdt_datas_last->data = page;
718  rdt_datas_last->len = bimg.hole_offset;
719 
720  rdt_datas_last->next = &regbuf->bkp_rdatas[1];
721  rdt_datas_last = rdt_datas_last->next;
722 
723  rdt_datas_last->data =
724  page + (bimg.hole_offset + cbimg.hole_length);
725  rdt_datas_last->len =
726  BLCKSZ - (bimg.hole_offset + cbimg.hole_length);
727  }
728  }
729 
730  total_len += bimg.length;
731  }
732 
733  if (needs_data)
734  {
735  /*
736  * Link the caller-supplied rdata chain for this buffer to the
737  * overall list.
738  */
740  bkpb.data_length = regbuf->rdata_len;
741  total_len += regbuf->rdata_len;
742 
743  rdt_datas_last->next = regbuf->rdata_head;
744  rdt_datas_last = regbuf->rdata_tail;
745  }
746 
747  if (prev_regbuf && RelFileNodeEquals(regbuf->rnode, prev_regbuf->rnode))
748  {
749  samerel = true;
751  }
752  else
753  samerel = false;
754  prev_regbuf = regbuf;
755 
756  /* Ok, copy the header to the scratch buffer */
757  memcpy(scratch, &bkpb, SizeOfXLogRecordBlockHeader);
758  scratch += SizeOfXLogRecordBlockHeader;
759  if (include_image)
760  {
761  memcpy(scratch, &bimg, SizeOfXLogRecordBlockImageHeader);
763  if (cbimg.hole_length != 0 && is_compressed)
764  {
765  memcpy(scratch, &cbimg,
768  }
769  }
770  if (!samerel)
771  {
772  memcpy(scratch, &regbuf->rnode, sizeof(RelFileNode));
773  scratch += sizeof(RelFileNode);
774  }
775  memcpy(scratch, &regbuf->block, sizeof(BlockNumber));
776  scratch += sizeof(BlockNumber);
777  }
778 
779  /* followed by the record's origin, if any */
782  {
783  *(scratch++) = (char) XLR_BLOCK_ID_ORIGIN;
784  memcpy(scratch, &replorigin_session_origin, sizeof(replorigin_session_origin));
785  scratch += sizeof(replorigin_session_origin);
786  }
787 
788  /* followed by toplevel XID, if not already included in previous record */
790  {
792 
793  /* update the flag (later used by XLogResetInsertion) */
795 
796  *(scratch++) = (char) XLR_BLOCK_ID_TOPLEVEL_XID;
797  memcpy(scratch, &xid, sizeof(TransactionId));
798  scratch += sizeof(TransactionId);
799  }
800 
801  /* followed by main data, if any */
802  if (mainrdata_len > 0)
803  {
804  if (mainrdata_len > 255)
805  {
806  *(scratch++) = (char) XLR_BLOCK_ID_DATA_LONG;
807  memcpy(scratch, &mainrdata_len, sizeof(uint32));
808  scratch += sizeof(uint32);
809  }
810  else
811  {
812  *(scratch++) = (char) XLR_BLOCK_ID_DATA_SHORT;
813  *(scratch++) = (uint8) mainrdata_len;
814  }
815  rdt_datas_last->next = mainrdata_head;
816  rdt_datas_last = mainrdata_last;
817  total_len += mainrdata_len;
818  }
819  rdt_datas_last->next = NULL;
820 
821  hdr_rdt.len = (scratch - hdr_scratch);
822  total_len += hdr_rdt.len;
823 
824  /*
825  * Calculate CRC of the data
826  *
827  * Note that the record header isn't added into the CRC initially since we
828  * don't know the prev-link yet. Thus, the CRC will represent the CRC of
829  * the whole record in the order: rdata, then backup blocks, then record
830  * header.
831  */
832  INIT_CRC32C(rdata_crc);
834  for (rdt = hdr_rdt.next; rdt != NULL; rdt = rdt->next)
835  COMP_CRC32C(rdata_crc, rdt->data, rdt->len);
836 
837  /*
838  * Fill in the fields in the record header. Prev-link is filled in later,
839  * once we know where in the WAL the record will be inserted. The CRC does
840  * not include the record header yet.
841  */
843  rechdr->xl_tot_len = total_len;
844  rechdr->xl_info = info;
845  rechdr->xl_rmid = rmid;
846  rechdr->xl_prev = InvalidXLogRecPtr;
847  rechdr->xl_crc = rdata_crc;
848 
849  return &hdr_rdt;
850 }
static XLogRecData hdr_rdt
Definition: xloginsert.c:100
#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:146
static uint32 mainrdata_len
Definition: xloginsert.c:87
uint32 TransactionId
Definition: c.h:587
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
#define XLR_BLOCK_ID_DATA_LONG
Definition: xlogrecord.h:228
uint32 pg_crc32c
Definition: pg_crc32c.h:38
BlockNumber block
Definition: xloginsert.c:61
unsigned char uint8
Definition: c.h:439
#define REGBUF_WILL_INIT
Definition: xloginsert.h:33
RmgrId xl_rmid
Definition: xlogrecord.h:47
#define XLOG_INCLUDE_ORIGIN
Definition: xlog.h:213
uint32 BlockNumber
Definition: block.h:31
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
XLogRecData * rdata_head
Definition: xloginsert.c:64
#define SizeOfPageHeaderData
Definition: bufpage.h:216
#define XLR_CHECK_CONSISTENCY
Definition: xlogrecord.h:80
RelFileNode rnode
Definition: xloginsert.c:59
unsigned short uint16
Definition: c.h:440
static bool doPageWrites
Definition: xlog.c:364
#define ERROR
Definition: elog.h:46
#define XLR_BLOCK_ID_TOPLEVEL_XID
Definition: xlogrecord.h:230
uint32 xl_tot_len
Definition: xlogrecord.h:43
#define SizeOfXLogRecordBlockImageHeader
Definition: xlogrecord.h:142
static XLogRecPtr RedoRecPtr
Definition: xlog.c:357
#define BKPIMAGE_APPLY
Definition: xlogrecord.h:147
struct RelFileNode RelFileNode
static XLogRecData * mainrdata_head
Definition: xloginsert.c:85
#define REGBUF_STANDARD
Definition: xloginsert.h:35
TransactionId GetCurrentTransactionIdIfAny(void)
Definition: xact.c:455
unsigned int uint32
Definition: c.h:441
TransactionId GetTopTransactionIdIfAny(void)
Definition: xact.c:425
void XLogSetRecordFlags(uint8 flags)
Definition: xloginsert.c:414
#define BKPBLOCK_WILL_INIT
Definition: xlogrecord.h:186
XLogRecData * rdata_tail
Definition: xloginsert.c:66
static registered_buffer * registered_buffers
Definition: xloginsert.c:76
#define SizeOfXLogRecord
Definition: xlogrecord.h:55
#define REGBUF_FORCE_IMAGE
Definition: xloginsert.h:31
int wal_compression
Definition: xlog.c:101
#define BKPBLOCK_SAME_REL
Definition: xlogrecord.h:187
#define REGBUF_KEEP_DATA
Definition: xloginsert.h:38
#define BKPBLOCK_HAS_IMAGE
Definition: xlogrecord.h:184
bool IsSubTransactionAssignmentPending(void)
Definition: xact.c:6096
#define XLOG_INCLUDE_XID
Definition: xlog.h:215
WalCompression
Definition: xlog.h:129
static XLogRecData * mainrdata_last
Definition: xloginsert.c:86
PageHeaderData * PageHeader
Definition: bufpage.h:166
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:804
RepOriginId replorigin_session_origin
Definition: origin.c:154
bool * wal_consistency_checking
Definition: xlog.c:103
uint8 xl_info
Definition: xlogrecord.h:46
#define REGBUF_NO_IMAGE
Definition: xloginsert.h:32
#define XLR_BLOCK_ID_ORIGIN
Definition: xlogrecord.h:229
ForkNumber forkno
Definition: xloginsert.c:60
char compressed_page[COMPRESS_BUFSIZE]
Definition: xloginsert.c:73
pg_crc32c xl_crc
Definition: xlogrecord.h:49
struct XLogRecData * next
#define InvalidRepOriginId
Definition: origin.h:33
#define PageGetLSN(page)
Definition: bufpage.h:366
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:227
static char * hdr_scratch
Definition: xloginsert.c:101
TransactionId xl_xid
Definition: xlogrecord.h:44
#define BKPIMAGE_COMPRESS_LZ4
Definition: xlogrecord.h:151
static int max_registered_block_id
Definition: xloginsert.c:78
#define BKPIMAGE_COMPRESS_PGLZ
Definition: xlogrecord.h:150
#define elog(elevel,...)
Definition: elog.h:232
static bool XLogCompressBackupBlock(char *page, uint16 hole_offset, uint16 hole_length, char *dest, uint16 *dlen)
Definition: xloginsert.c:860
static uint8 curinsert_flags
Definition: xloginsert.c:90
XLogRecData bkp_rdatas[2]
Definition: xloginsert.c:69
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:89
#define SizeOfXLogRecordBlockCompressHeader
Definition: xlogrecord.h:164
Pointer Page
Definition: bufpage.h:78
#define RelFileNodeEquals(node1, node2)
Definition: relfilenode.h:88
#define BKPBLOCK_HAS_DATA
Definition: xlogrecord.h:185
#define SizeOfXLogRecordBlockHeader
Definition: xlogrecord.h:104

◆ XLogRegisterBlock()

void XLogRegisterBlock ( uint8  block_id,
RelFileNode rnode,
ForkNumber  forknum,
BlockNumber  blknum,
Page  page,
uint8  flags 
)

Definition at line 285 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, RelFileNodeEquals, and registered_buffer::rnode.

Referenced by log_newpage(), log_newpages(), and XLogSaveBufferForHint().

287 {
288  registered_buffer *regbuf;
289 
291 
292  if (block_id >= max_registered_block_id)
293  max_registered_block_id = block_id + 1;
294 
295  if (block_id >= max_registered_buffers)
296  elog(ERROR, "too many registered buffers");
297 
298  regbuf = &registered_buffers[block_id];
299 
300  regbuf->rnode = *rnode;
301  regbuf->forkno = forknum;
302  regbuf->block = blknum;
303  regbuf->page = page;
304  regbuf->flags = flags;
305  regbuf->rdata_tail = (XLogRecData *) &regbuf->rdata_head;
306  regbuf->rdata_len = 0;
307 
308  /*
309  * Check that this page hasn't already been registered with some other
310  * block_id.
311  */
312 #ifdef USE_ASSERT_CHECKING
313  {
314  int i;
315 
316  for (i = 0; i < max_registered_block_id; i++)
317  {
318  registered_buffer *regbuf_old = &registered_buffers[i];
319 
320  if (i == block_id || !regbuf_old->in_use)
321  continue;
322 
323  Assert(!RelFileNodeEquals(regbuf_old->rnode, regbuf->rnode) ||
324  regbuf_old->forkno != regbuf->forkno ||
325  regbuf_old->block != regbuf->block);
326  }
327  }
328 #endif
329 
330  regbuf->in_use = true;
331 }
BlockNumber block
Definition: xloginsert.c:61
static bool begininsert_called
Definition: xloginsert.c:119
XLogRecData * rdata_head
Definition: xloginsert.c:64
RelFileNode rnode
Definition: xloginsert.c:59
#define ERROR
Definition: elog.h:46
static int max_registered_buffers
Definition: xloginsert.c:77
XLogRecData * rdata_tail
Definition: xloginsert.c:66
static registered_buffer * registered_buffers
Definition: xloginsert.c:76
#define Assert(condition)
Definition: c.h:804
ForkNumber forkno
Definition: xloginsert.c:60
static int max_registered_block_id
Definition: xloginsert.c:78
#define elog(elevel,...)
Definition: elog.h:232
int i
#define RelFileNodeEquals(node1, node2)
Definition: relfilenode.h:88

◆ XLogRegisterBufData()

void XLogRegisterBufData ( uint8  block_id,
char *  data,
int  len 
)

Definition at line 378 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_dedup_pass(), _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_newroot(), _bt_set_cleanup_info(), _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(), heap_page_prune(), lazy_vacuum_heap_page(), log_heap_freeze(), log_heap_update(), and writeListPage().

379 {
380  registered_buffer *regbuf;
381  XLogRecData *rdata;
382 
384 
385  /* find the registered buffer struct */
386  regbuf = &registered_buffers[block_id];
387  if (!regbuf->in_use)
388  elog(ERROR, "no block with id %d registered with WAL insertion",
389  block_id);
390 
391  if (num_rdatas >= max_rdatas)
392  elog(ERROR, "too much WAL data");
393  rdata = &rdatas[num_rdatas++];
394 
395  rdata->data = data;
396  rdata->len = len;
397 
398  regbuf->rdata_tail->next = rdata;
399  regbuf->rdata_tail = rdata;
400  regbuf->rdata_len += len;
401 }
static bool begininsert_called
Definition: xloginsert.c:119
#define ERROR
Definition: elog.h:46
XLogRecData * rdata_tail
Definition: xloginsert.c:66
static int max_rdatas
Definition: xloginsert.c:117
static registered_buffer * registered_buffers
Definition: xloginsert.c:76
static int num_rdatas
Definition: xloginsert.c:116
#define Assert(condition)
Definition: c.h:804
struct XLogRecData * next
#define elog(elevel,...)
Definition: elog.h:232
static XLogRecData * rdatas
Definition: xloginsert.c:115

◆ XLogRegisterBuffer()

void XLogRegisterBuffer ( uint8  block_id,
Buffer  buffer,
uint8  flags 
)

Definition at line 232 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_dedup_pass(), _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_mark_page_halfdead(), _bt_newroot(), _bt_set_cleanup_info(), _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(), brin_doinsert(), brin_doupdate(), brinbuild(), brinRevmapDesummarizeRange(), createPostingTree(), do_setval(), doPickSplit(), fill_seq_with_data(), GenericXLogFinish(), ginDeletePage(), ginHeapTupleFastInsert(), ginPlaceToPage(), ginUpdateStats(), ginVacuumPostingTreeLeaf(), gistXLogDelete(), gistXLogPageDelete(), 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_page_prune(), heap_update(), lazy_vacuum_heap_page(), log_heap_freeze(), log_heap_update(), log_heap_visible(), log_newpage_range(), log_split_page(), moveLeafs(), nextval_internal(), revmap_physical_extend(), shiftList(), spgAddNodeAction(), spgSplitNodeAction(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), writeListPage(), and xlogVacuumPage().

233 {
234  registered_buffer *regbuf;
235 
236  /* NO_IMAGE doesn't make sense with FORCE_IMAGE */
237  Assert(!((flags & REGBUF_FORCE_IMAGE) && (flags & (REGBUF_NO_IMAGE))));
239 
240  if (block_id >= max_registered_block_id)
241  {
242  if (block_id >= max_registered_buffers)
243  elog(ERROR, "too many registered buffers");
244  max_registered_block_id = block_id + 1;
245  }
246 
247  regbuf = &registered_buffers[block_id];
248 
249  BufferGetTag(buffer, &regbuf->rnode, &regbuf->forkno, &regbuf->block);
250  regbuf->page = BufferGetPage(buffer);
251  regbuf->flags = flags;
252  regbuf->rdata_tail = (XLogRecData *) &regbuf->rdata_head;
253  regbuf->rdata_len = 0;
254 
255  /*
256  * Check that this page hasn't already been registered with some other
257  * block_id.
258  */
259 #ifdef USE_ASSERT_CHECKING
260  {
261  int i;
262 
263  for (i = 0; i < max_registered_block_id; i++)
264  {
265  registered_buffer *regbuf_old = &registered_buffers[i];
266 
267  if (i == block_id || !regbuf_old->in_use)
268  continue;
269 
270  Assert(!RelFileNodeEquals(regbuf_old->rnode, regbuf->rnode) ||
271  regbuf_old->forkno != regbuf->forkno ||
272  regbuf_old->block != regbuf->block);
273  }
274  }
275 #endif
276 
277  regbuf->in_use = true;
278 }
BlockNumber block
Definition: xloginsert.c:61
static bool begininsert_called
Definition: xloginsert.c:119
XLogRecData * rdata_head
Definition: xloginsert.c:64
RelFileNode rnode
Definition: xloginsert.c:59
#define ERROR
Definition: elog.h:46
static int max_registered_buffers
Definition: xloginsert.c:77
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
XLogRecData * rdata_tail
Definition: xloginsert.c:66
static registered_buffer * registered_buffers
Definition: xloginsert.c:76
#define REGBUF_FORCE_IMAGE
Definition: xloginsert.h:31
#define Assert(condition)
Definition: c.h:804
#define REGBUF_NO_IMAGE
Definition: xloginsert.h:32
ForkNumber forkno
Definition: xloginsert.c:60
static int max_registered_block_id
Definition: xloginsert.c:78
#define elog(elevel,...)
Definition: elog.h:232
int i
void BufferGetTag(Buffer buffer, RelFileNode *rnode, ForkNumber *forknum, BlockNumber *blknum)
Definition: bufmgr.c:2773
#define RelFileNodeEquals(node1, node2)
Definition: relfilenode.h:88

◆ XLogRegisterData()

void XLogRegisterData ( char *  data,
int  len 
)

Definition at line 340 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_dedup_pass(), _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(), AssignTransactionId(), brin_doinsert(), brin_doupdate(), brinbuild(), brinRevmapDesummarizeRange(), CreateCheckPoint(), createdb(), CreateEndOfRecoveryRecord(), createPostingTree(), CreateTableSpace(), do_pg_stop_backup(), do_setval(), doPickSplit(), DropTableSpace(), EndPrepare(), ExecuteTruncateGuts(), fill_seq_with_data(), ginDeletePage(), ginHeapTupleFastInsert(), ginPlaceToPage(), ginUpdateStats(), gistXLogAssignLSN(), gistXLogDelete(), gistXLogPageDelete(), gistXLogPageReuse(), 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_page_prune(), heap_update(), lazy_vacuum_heap_page(), log_heap_freeze(), log_heap_new_cid(), log_heap_update(), log_heap_visible(), log_smgrcreate(), LogAccessExclusiveLocks(), LogCurrentRunningXacts(), logical_heap_rewrite_flush_mappings(), LogLogicalInvalidations(), LogLogicalMessage(), LogStandbyInvalidations(), movedb(), moveLeafs(), MultiXactIdCreateFromMembers(), nextval_internal(), pg_truncate_visibility_map(), RelationTruncate(), remove_dbtablespaces(), replorigin_advance(), replorigin_drop_guts(), revmap_physical_extend(), shiftList(), spgAddNodeAction(), spgSplitNodeAction(), UpdateFullPageWrites(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), write_relmap_file(), writeListPage(), WriteMTruncateXlogRec(), WriteMZeroPageXlogRec(), WriteTruncateXlogRec(), WriteZeroPageXlogRec(), XactLogAbortRecord(), XactLogCommitRecord(), XLogPutNextOid(), XLogReportParameters(), and XLogRestorePoint().

341 {
342  XLogRecData *rdata;
343 
345 
346  if (num_rdatas >= max_rdatas)
347  elog(ERROR, "too much WAL data");
348  rdata = &rdatas[num_rdatas++];
349 
350  rdata->data = data;
351  rdata->len = len;
352 
353  /*
354  * we use the mainrdata_last pointer to track the end of the chain, so no
355  * need to clear 'next' here.
356  */
357 
358  mainrdata_last->next = rdata;
359  mainrdata_last = rdata;
360 
361  mainrdata_len += len;
362 }
static uint32 mainrdata_len
Definition: xloginsert.c:87
static bool begininsert_called
Definition: xloginsert.c:119
#define ERROR
Definition: elog.h:46
static int max_rdatas
Definition: xloginsert.c:117
static XLogRecData * mainrdata_last
Definition: xloginsert.c:86
static int num_rdatas
Definition: xloginsert.c:116
#define Assert(condition)
Definition: c.h:804
struct XLogRecData * next
#define elog(elevel,...)
Definition: elog.h:232
static XLogRecData * rdatas
Definition: xloginsert.c:115

◆ XLogResetInsertion()

void XLogResetInsertion ( void  )

Definition at line 208 of file xloginsert.c.

References begininsert_called, curinsert_flags, i, mainrdata_len, MarkSubTransactionAssigned(), max_registered_block_id, num_rdatas, and XLOG_INCLUDE_XID.

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

209 {
210  int i;
211 
212  /* reset the subxact assignment flag (if needed) */
215 
216  for (i = 0; i < max_registered_block_id; i++)
217  registered_buffers[i].in_use = false;
218 
219  num_rdatas = 0;
220  max_registered_block_id = 0;
221  mainrdata_len = 0;
223  curinsert_flags = 0;
224  begininsert_called = false;
225 }
void MarkSubTransactionAssigned(void)
Definition: xact.c:6124
static uint32 mainrdata_len
Definition: xloginsert.c:87
static bool begininsert_called
Definition: xloginsert.c:119
static XLogRecData * mainrdata_head
Definition: xloginsert.c:85
static registered_buffer * registered_buffers
Definition: xloginsert.c:76
#define XLOG_INCLUDE_XID
Definition: xlog.h:215
static XLogRecData * mainrdata_last
Definition: xloginsert.c:86
static int num_rdatas
Definition: xloginsert.c:116
static int max_registered_block_id
Definition: xloginsert.c:78
int i
static uint8 curinsert_flags
Definition: xloginsert.c:90

◆ XLogSaveBufferForHint()

XLogRecPtr XLogSaveBufferForHint ( Buffer  buffer,
bool  buffer_std 
)

Definition at line 970 of file xloginsert.c.

References Assert, BufferGetBlock, BufferGetLSNAtomic(), BufferGetPage, BufferGetTag(), PGAlignedBlock::data, PGPROC::delayChkpt, GetRedoRecPtr(), InvalidXLogRecPtr, lower(), MyProc, RedoRecPtr, REGBUF_STANDARD, upper(), XLOG_FPI_FOR_HINT, XLogBeginInsert(), XLogInsert(), and XLogRegisterBlock().

Referenced by MarkBufferDirtyHint().

971 {
972  XLogRecPtr recptr = InvalidXLogRecPtr;
973  XLogRecPtr lsn;
975 
976  /*
977  * Ensure no checkpoint can change our view of RedoRecPtr.
978  */
980 
981  /*
982  * Update RedoRecPtr so that we can make the right decision
983  */
984  RedoRecPtr = GetRedoRecPtr();
985 
986  /*
987  * We assume page LSN is first data on *every* page that can be passed to
988  * XLogInsert, whether it has the standard page layout or not. Since we're
989  * only holding a share-lock on the page, we must take the buffer header
990  * lock when we look at the LSN.
991  */
992  lsn = BufferGetLSNAtomic(buffer);
993 
994  if (lsn <= RedoRecPtr)
995  {
996  int flags = 0;
997  PGAlignedBlock copied_buffer;
998  char *origdata = (char *) BufferGetBlock(buffer);
999  RelFileNode rnode;
1000  ForkNumber forkno;
1001  BlockNumber blkno;
1002 
1003  /*
1004  * Copy buffer so we don't have to worry about concurrent hint bit or
1005  * lsn updates. We assume pd_lower/upper cannot be changed without an
1006  * exclusive lock, so the contents bkp are not racy.
1007  */
1008  if (buffer_std)
1009  {
1010  /* Assume we can omit data between pd_lower and pd_upper */
1011  Page page = BufferGetPage(buffer);
1012  uint16 lower = ((PageHeader) page)->pd_lower;
1013  uint16 upper = ((PageHeader) page)->pd_upper;
1014 
1015  memcpy(copied_buffer.data, origdata, lower);
1016  memcpy(copied_buffer.data + upper, origdata + upper, BLCKSZ - upper);
1017  }
1018  else
1019  memcpy(copied_buffer.data, origdata, BLCKSZ);
1020 
1021  XLogBeginInsert();
1022 
1023  if (buffer_std)
1024  flags |= REGBUF_STANDARD;
1025 
1026  BufferGetTag(buffer, &rnode, &forkno, &blkno);
1027  XLogRegisterBlock(0, &rnode, forkno, blkno, copied_buffer.data, flags);
1028 
1029  recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI_FOR_HINT);
1030  }
1031 
1032  return recptr;
1033 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
PGPROC * MyProc
Definition: proc.c:68
uint32 BlockNumber
Definition: block.h:31
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
char data[BLCKSZ]
Definition: c.h:1141
void XLogRegisterBlock(uint8 block_id, RelFileNode *rnode, ForkNumber forknum, BlockNumber blknum, Page page, uint8 flags)
Definition: xloginsert.c:285
unsigned short uint16
Definition: c.h:440
bool delayChkpt
Definition: proc.h:187
static XLogRecPtr RedoRecPtr
Definition: xlog.c:357
XLogRecPtr BufferGetLSNAtomic(Buffer buffer)
Definition: bufmgr.c:3012
#define REGBUF_STANDARD
Definition: xloginsert.h:35
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
ForkNumber
Definition: relpath.h:40
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:432
PageHeaderData * PageHeader
Definition: bufpage.h:166
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:804
#define XLOG_FPI_FOR_HINT
Definition: pg_control.h:77
XLogRecPtr GetRedoRecPtr(void)
Definition: xlog.c:8509
void BufferGetTag(Buffer buffer, RelFileNode *rnode, ForkNumber *forknum, BlockNumber *blknum)
Definition: bufmgr.c:2773
void XLogBeginInsert(void)
Definition: xloginsert.c:135
#define BufferGetBlock(buffer)
Definition: bufmgr.h:136
Pointer Page
Definition: bufpage.h:78

◆ XLogSetRecordFlags()

Variable Documentation

◆ begininsert_called

◆ curinsert_flags

uint8 curinsert_flags = 0
static

◆ hdr_rdt

XLogRecData hdr_rdt
static

Definition at line 100 of file xloginsert.c.

Referenced by XLogRecordAssemble().

◆ hdr_scratch

char* hdr_scratch = NULL
static

Definition at line 101 of file xloginsert.c.

Referenced by InitXLogInsert(), and XLogRecordAssemble().

◆ mainrdata_head

XLogRecData* mainrdata_head
static

Definition at line 85 of file xloginsert.c.

Referenced by XLogRecordAssemble().

◆ mainrdata_last

XLogRecData* mainrdata_last = (XLogRecData *) &mainrdata_head
static

Definition at line 86 of file xloginsert.c.

Referenced by XLogRecordAssemble().

◆ mainrdata_len

uint32 mainrdata_len
static

◆ max_rdatas

int max_rdatas
static

◆ max_registered_block_id

int max_registered_block_id = 0
static

◆ max_registered_buffers

int max_registered_buffers
static

◆ num_rdatas

int num_rdatas
static

Definition at line 116 of file xloginsert.c.

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

◆ rdatas

XLogRecData* rdatas
static

Definition at line 115 of file xloginsert.c.

◆ registered_buffers

registered_buffer* registered_buffers
static

Definition at line 76 of file xloginsert.c.

◆ xloginsert_cxt

MemoryContext xloginsert_cxt
static

Definition at line 122 of file xloginsert.c.