PostgreSQL Source Code git master
Loading...
Searching...
No Matches
xloginsert.h File Reference
#include "access/rmgr.h"
#include "access/xlogdefs.h"
#include "storage/block.h"
#include "storage/buf.h"
#include "storage/bufpage.h"
#include "storage/relfilelocator.h"
#include "utils/relcache.h"
Include dependency graph for xloginsert.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define XLR_NORMAL_MAX_BLOCK_ID   4
 
#define XLR_NORMAL_RDATAS   20
 
#define REGBUF_FORCE_IMAGE   0x01 /* force a full-page image */
 
#define REGBUF_NO_IMAGE   0x02 /* don't take a full-page image */
 
#define REGBUF_WILL_INIT
 
#define REGBUF_STANDARD
 
#define REGBUF_KEEP_DATA
 
#define REGBUF_NO_CHANGE   0x20 /* intentionally register clean buffer */
 

Functions

void XLogBeginInsert (void)
 
void XLogSetRecordFlags (uint8 flags)
 
XLogRecPtr XLogInsert (RmgrId rmid, uint8 info)
 
XLogRecPtr XLogSimpleInsertInt64 (RmgrId rmid, uint8 info, int64 value)
 
void XLogEnsureRecordSpace (int max_block_id, int ndatas)
 
void XLogRegisterData (const void *data, uint32 len)
 
void XLogRegisterBuffer (uint8 block_id, Buffer buffer, uint8 flags)
 
void XLogRegisterBlock (uint8 block_id, RelFileLocator *rlocator, ForkNumber forknum, BlockNumber blknum, const PageData *page, uint8 flags)
 
void XLogRegisterBufData (uint8 block_id, const void *data, uint32 len)
 
void XLogResetInsertion (void)
 
bool XLogCheckBufferNeedsBackup (Buffer buffer)
 
XLogRecPtr log_newpage (RelFileLocator *rlocator, ForkNumber forknum, BlockNumber blkno, Page page, bool page_std)
 
void log_newpages (RelFileLocator *rlocator, 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)
 
XLogRecPtr XLogSaveBufferForHint (Buffer buffer, bool buffer_std)
 
XLogRecPtr XLogGetFakeLSN (Relation rel)
 
void InitXLogInsert (void)
 

Macro Definition Documentation

◆ REGBUF_FORCE_IMAGE

#define REGBUF_FORCE_IMAGE   0x01 /* force a full-page image */

Definition at line 32 of file xloginsert.h.

◆ REGBUF_KEEP_DATA

#define REGBUF_KEEP_DATA
Value:
0x10 /* include data even if a full-page image
* is taken */

Definition at line 36 of file xloginsert.h.

◆ REGBUF_NO_CHANGE

#define REGBUF_NO_CHANGE   0x20 /* intentionally register clean buffer */

Definition at line 37 of file xloginsert.h.

◆ REGBUF_NO_IMAGE

#define REGBUF_NO_IMAGE   0x02 /* don't take a full-page image */

Definition at line 33 of file xloginsert.h.

◆ REGBUF_STANDARD

#define REGBUF_STANDARD
Value:
0x08 /* page follows "standard" page layout,
* (data between pd_lower and pd_upper
* will be skipped) */

Definition at line 35 of file xloginsert.h.

◆ REGBUF_WILL_INIT

#define REGBUF_WILL_INIT
Value:
(0x04 | 0x02) /* page will be re-initialized at
* replay (implies NO_IMAGE) */

Definition at line 34 of file xloginsert.h.

◆ XLR_NORMAL_MAX_BLOCK_ID

#define XLR_NORMAL_MAX_BLOCK_ID   4

Definition at line 28 of file xloginsert.h.

◆ XLR_NORMAL_RDATAS

#define XLR_NORMAL_RDATAS   20

Definition at line 29 of file xloginsert.h.

Function Documentation

◆ InitXLogInsert()

void InitXLogInsert ( void  )
extern

Definition at line 1424 of file xloginsert.c.

1425{
1426#ifdef USE_ASSERT_CHECKING
1427
1428 /*
1429 * Check that any records assembled can be decoded. This is capped based
1430 * on what XLogReader would require at its maximum bound. The XLOG_BLCKSZ
1431 * addend covers the larger allocate_recordbuf() demand. This code path
1432 * is called once per backend, more than enough for this check.
1433 */
1434 size_t max_required =
1436
1438#endif
1439
1440 /* Initialize the working areas */
1441 if (xloginsert_cxt == NULL)
1442 {
1444 "WAL record construction",
1446 }
1447
1448 if (registered_buffers == NULL)
1449 {
1454 }
1455 if (rdatas == NULL)
1456 {
1458 sizeof(XLogRecData) * XLR_NORMAL_RDATAS);
1460 }
1461
1462 /*
1463 * Allocate a buffer to hold the header information for a WAL record.
1464 */
1465 if (hdr_scratch == NULL)
1468}
#define Assert(condition)
Definition c.h:945
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1232
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition mcxt.c:1266
MemoryContext TopMemoryContext
Definition mcxt.c:166
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160
#define AllocSizeIsValid(size)
Definition memutils.h:42
static int fb(int x)
static int max_registered_buffers
Definition xloginsert.c:93
static MemoryContext xloginsert_cxt
Definition xloginsert.c:138
static char * hdr_scratch
Definition xloginsert.c:117
static XLogRecData * rdatas
Definition xloginsert.c:131
static registered_buffer * registered_buffers
Definition xloginsert.c:92
static int max_rdatas
Definition xloginsert.c:133
#define HEADER_SCRATCH_SIZE
Definition xloginsert.c:122
#define XLR_NORMAL_MAX_BLOCK_ID
Definition xloginsert.h:28
#define XLR_NORMAL_RDATAS
Definition xloginsert.h:29
size_t DecodeXLogRecordRequiredSpace(size_t xl_tot_len)
#define XLogRecordMaxSize
Definition xlogrecord.h:74

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, AllocSizeIsValid, Assert, DecodeXLogRecordRequiredSpace(), fb(), hdr_scratch, HEADER_SCRATCH_SIZE, max_rdatas, max_registered_buffers, MemoryContextAlloc(), MemoryContextAllocZero(), rdatas, registered_buffers, TopMemoryContext, xloginsert_cxt, XLogRecordMaxSize, XLR_NORMAL_MAX_BLOCK_ID, and XLR_NORMAL_RDATAS.

Referenced by BaseInit().

◆ log_newpage()

XLogRecPtr log_newpage ( RelFileLocator rlocator,
ForkNumber  forknum,
BlockNumber  blkno,
Page  page,
bool  page_std 
)
extern

Definition at line 1218 of file xloginsert.c.

1220{
1221 int flags;
1223
1224 flags = REGBUF_FORCE_IMAGE;
1225 if (page_std)
1226 flags |= REGBUF_STANDARD;
1227
1229 XLogRegisterBlock(0, rlocator, forknum, blkno, page, flags);
1231
1232 /*
1233 * The page may be uninitialized. If so, we can't set the LSN because that
1234 * would corrupt the page.
1235 */
1236 if (!PageIsNew(page))
1237 {
1238 PageSetLSN(page, recptr);
1239 }
1240
1241 return recptr;
1242}
static bool PageIsNew(const PageData *page)
Definition bufpage.h:259
static void PageSetLSN(Page page, XLogRecPtr lsn)
Definition bufpage.h:417
#define XLOG_FPI
Definition pg_control.h:80
uint64 XLogRecPtr
Definition xlogdefs.h:21
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition xloginsert.c:479
void XLogRegisterBlock(uint8 block_id, RelFileLocator *rlocator, ForkNumber forknum, BlockNumber blknum, const PageData *page, uint8 flags)
Definition xloginsert.c:314
void XLogBeginInsert(void)
Definition xloginsert.c:153
#define REGBUF_STANDARD
Definition xloginsert.h:35
#define REGBUF_FORCE_IMAGE
Definition xloginsert.h:32

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

Referenced by _hash_alloc_buckets(), _hash_init(), and log_newpage_buffer().

◆ log_newpage_buffer()

XLogRecPtr log_newpage_buffer ( Buffer  buffer,
bool  page_std 
)
extern

Definition at line 1312 of file xloginsert.c.

1313{
1314 Page page = BufferGetPage(buffer);
1315 RelFileLocator rlocator;
1316 ForkNumber forknum;
1317 BlockNumber blkno;
1318
1319 /* Shared buffers should be modified in a critical section. */
1321
1322 BufferGetTag(buffer, &rlocator, &forknum, &blkno);
1323
1324 return log_newpage(&rlocator, forknum, blkno, page, page_std);
1325}
uint32 BlockNumber
Definition block.h:31
void BufferGetTag(Buffer buffer, RelFileLocator *rlocator, ForkNumber *forknum, BlockNumber *blknum)
Definition bufmgr.c:4378
static Page BufferGetPage(Buffer buffer)
Definition bufmgr.h:470
PageData * Page
Definition bufpage.h:81
volatile uint32 CritSectionCount
Definition globals.c:45
ForkNumber
Definition relpath.h:56
XLogRecPtr log_newpage(RelFileLocator *rlocator, ForkNumber forknum, BlockNumber blkno, Page page, bool page_std)

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

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

◆ log_newpage_range()

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

Definition at line 1345 of file xloginsert.c.

1348{
1349 int flags;
1350 BlockNumber blkno;
1351
1352 flags = REGBUF_FORCE_IMAGE;
1353 if (page_std)
1354 flags |= REGBUF_STANDARD;
1355
1356 /*
1357 * Iterate over all the pages in the range. They are collected into
1358 * batches of XLR_MAX_BLOCK_ID pages, and a single WAL-record is written
1359 * for each batch.
1360 */
1362
1363 blkno = startblk;
1364 while (blkno < endblk)
1365 {
1368 int nbufs;
1369 int i;
1370
1372
1373 /* Collect a batch of blocks. */
1374 nbufs = 0;
1375 while (nbufs < XLR_MAX_BLOCK_ID && blkno < endblk)
1376 {
1377 Buffer buf = ReadBufferExtended(rel, forknum, blkno,
1378 RBM_NORMAL, NULL);
1379
1381
1382 /*
1383 * Completely empty pages are not WAL-logged. Writing a WAL record
1384 * would change the LSN, and we don't want that. We want the page
1385 * to stay empty.
1386 */
1388 bufpack[nbufs++] = buf;
1389 else
1391 blkno++;
1392 }
1393
1394 /* Nothing more to do if all remaining blocks were empty. */
1395 if (nbufs == 0)
1396 break;
1397
1398 /* Write WAL record for this batch. */
1400
1402 for (i = 0; i < nbufs; i++)
1403 {
1405 XLogRegisterBuffer(i, bufpack[i], flags);
1406 }
1407
1409
1410 for (i = 0; i < nbufs; i++)
1412
1414
1415 for (i = 0; i < nbufs; i++)
1417 }
1418}
int Buffer
Definition buf.h:23
void UnlockReleaseBuffer(Buffer buffer)
Definition bufmgr.c:5522
void MarkBufferDirty(Buffer buffer)
Definition bufmgr.c:3063
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition bufmgr.c:921
@ BUFFER_LOCK_EXCLUSIVE
Definition bufmgr.h:220
static void LockBuffer(Buffer buffer, BufferLockMode mode)
Definition bufmgr.h:332
@ RBM_NORMAL
Definition bufmgr.h:46
int i
Definition isn.c:77
#define START_CRIT_SECTION()
Definition miscadmin.h:150
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:123
#define END_CRIT_SECTION()
Definition miscadmin.h:152
static char buf[DEFAULT_XLOG_SEG_SIZE]
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
Definition xloginsert.c:246
void XLogEnsureRecordSpace(int max_block_id, int ndatas)
Definition xloginsert.c:179
#define XLR_MAX_BLOCK_ID
Definition xlogrecord.h:239

References buf, BUFFER_LOCK_EXCLUSIVE, BufferGetPage(), CHECK_FOR_INTERRUPTS, END_CRIT_SECTION, fb(), 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().

◆ log_newpages()

void log_newpages ( RelFileLocator rlocator,
ForkNumber  forknum,
int  num_pages,
BlockNumber blknos,
Page pages,
bool  page_std 
)
extern

Definition at line 1250 of file xloginsert.c.

1252{
1253 int flags;
1255 int i;
1256 int j;
1257
1258 flags = REGBUF_FORCE_IMAGE;
1259 if (page_std)
1260 flags |= REGBUF_STANDARD;
1261
1262 /*
1263 * Iterate over all the pages. They are collected into batches of
1264 * XLR_MAX_BLOCK_ID pages, and a single WAL-record is written for each
1265 * batch.
1266 */
1268
1269 i = 0;
1270 while (i < num_pages)
1271 {
1272 int batch_start = i;
1273 int nbatch;
1274
1276
1277 nbatch = 0;
1278 while (nbatch < XLR_MAX_BLOCK_ID && i < num_pages)
1279 {
1280 XLogRegisterBlock(nbatch, rlocator, forknum, blknos[i], pages[i], flags);
1281 i++;
1282 nbatch++;
1283 }
1284
1286
1287 for (j = batch_start; j < i; j++)
1288 {
1289 /*
1290 * The page may be uninitialized. If so, we can't set the LSN
1291 * because that would corrupt the page.
1292 */
1293 if (!PageIsNew(pages[j]))
1294 {
1295 PageSetLSN(pages[j], recptr);
1296 }
1297 }
1298 }
1299}
int j
Definition isn.c:78
Datum batch_start(PG_FUNCTION_ARGS)
Definition test_aio.c:668

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

Referenced by smgr_bulk_flush().

◆ XLogBeginInsert()

void XLogBeginInsert ( void  )
extern

Definition at line 153 of file xloginsert.c.

154{
157 Assert(mainrdata_len == 0);
158
159 /* cross-check on whether we should be here or not */
160 if (!XLogInsertAllowed())
161 elog(ERROR, "cannot make new WAL entries during recovery");
162
164 elog(ERROR, "XLogBeginInsert was already called");
165
166 begininsert_called = true;
167}
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
bool XLogInsertAllowed(void)
Definition xlog.c:6499
static XLogRecData * mainrdata_head
Definition xloginsert.c:101
static uint64 mainrdata_len
Definition xloginsert.c:103
static bool begininsert_called
Definition xloginsert.c:135
static int max_registered_block_id
Definition xloginsert.c:94
static XLogRecData * mainrdata_last
Definition xloginsert.c:102

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

Referenced by _bt_allocbuf(), _bt_dedup_pass(), _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_mark_page_halfdead(), _bt_newlevel(), _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(), CreateDatabaseUsingFileCopy(), CreateDirAndVersionFile(), CreateEndOfRecoveryRecord(), CreateOverwriteContrecordRecord(), createPostingTree(), CreateTableSpace(), do_pg_backup_stop(), doPickSplit(), DropTableSpace(), EndPrepare(), ExecuteTruncateGuts(), fill_seq_fork_with_data(), GenericXLogFinish(), ginDeletePostingPage(), ginHeapTupleFastInsert(), ginPlaceToPage(), ginUpdateStats(), ginVacuumPostingTreeLeaf(), gistXLogDelete(), gistXLogPageDelete(), gistXLogPageReuse(), gistXLogSplit(), gistXLogUpdate(), hashbucketcleanup(), hashbulkdelete(), heap_abort_speculative(), heap_delete(), heap_finish_speculative(), heap_inplace_update_and_unlock(), heap_insert(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), heap_multi_insert(), heap_update(), log_heap_new_cid(), log_heap_prune_and_freeze(), 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_state_clear(), RequestXLogSwitch(), revmap_physical_extend(), SetSequence(), shiftList(), spgAddNodeAction(), spgSplitNodeAction(), test_custom_rmgrs_insert_wal_record(), UpdateFullPageWrites(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), write_logical_decoding_status_update_record(), write_relmap_file(), writeListPage(), WriteMTruncateXlogRec(), WriteTruncateXlogRec(), WriteTruncateXlogRec(), XactLogAbortRecord(), XactLogCommitRecord(), XLogAssignLSN(), XLogPutNextOid(), XLogReportParameters(), XLogRestorePoint(), XLogSaveBufferForHint(), XLogSimpleInsertInt64(), and xlogVacuumPage().

◆ XLogCheckBufferNeedsBackup()

bool XLogCheckBufferNeedsBackup ( Buffer  buffer)
extern

Definition at line 1101 of file xloginsert.c.

1102{
1104 bool doPageWrites;
1105 Page page;
1106
1108
1109 page = BufferGetPage(buffer);
1110
1111 if (doPageWrites && PageGetLSN(page) <= RedoRecPtr)
1112 return true; /* buffer requires backup */
1113
1114 return false; /* buffer does not need to be backed up */
1115}
static XLogRecPtr PageGetLSN(const PageData *page)
Definition bufpage.h:411
void GetFullPageWriteInfo(XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p)
Definition xlog.c:6577
static XLogRecPtr RedoRecPtr
Definition xlog.c:277
static bool doPageWrites
Definition xlog.c:290

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

Referenced by heap_page_will_freeze(), and log_heap_update().

◆ XLogEnsureRecordSpace()

void XLogEnsureRecordSpace ( int  max_block_id,
int  ndatas 
)
extern

Definition at line 179 of file xloginsert.c.

180{
181 int nbuffers;
182
183 /*
184 * This must be called before entering a critical section, because
185 * allocating memory inside a critical section can fail. repalloc() will
186 * check the same, but better to check it here too so that we fail
187 * consistently even if the arrays happen to be large enough already.
188 */
190
191 /* the minimum values can't be decreased */
192 if (max_block_id < XLR_NORMAL_MAX_BLOCK_ID)
193 max_block_id = XLR_NORMAL_MAX_BLOCK_ID;
196
197 if (max_block_id > XLR_MAX_BLOCK_ID)
198 elog(ERROR, "maximum number of WAL record block references exceeded");
199 nbuffers = max_block_id + 1;
200
201 if (nbuffers > max_registered_buffers)
202 {
204 repalloc(registered_buffers, sizeof(registered_buffer) * nbuffers);
205
206 /*
207 * At least the padding bytes in the structs must be zeroed, because
208 * they are included in WAL data, but initialize it all for tidiness.
209 */
211 (nbuffers - max_registered_buffers) * sizeof(registered_buffer));
212 max_registered_buffers = nbuffers;
213 }
214
215 if (ndatas > max_rdatas)
216 {
219 }
220}
#define MemSet(start, val, len)
Definition c.h:1109
void * repalloc(void *pointer, Size size)
Definition mcxt.c:1632

References Assert, CritSectionCount, elog, ERROR, fb(), max_rdatas, max_registered_buffers, MemSet, rdatas, registered_buffers, 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().

◆ XLogGetFakeLSN()

XLogRecPtr XLogGetFakeLSN ( Relation  rel)
extern

Definition at line 559 of file xloginsert.c.

560{
561 if (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
562 {
563 /*
564 * Temporary relations are only accessible in our session, so a simple
565 * backend-local counter will do.
566 */
567 static XLogRecPtr counter = FirstNormalUnloggedLSN;
568
569 return counter++;
570 }
571 else if (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
572 {
573 /*
574 * Unlogged relations are accessible from other backends, and survive
575 * (clean) restarts. GetFakeLSNForUnloggedRel() handles that for us.
576 */
578 }
579 else
580 {
581 /*
582 * WAL-logging on this relation will start after commit, so its LSNs
583 * must be distinct numbers smaller than the LSN at the next commit.
584 * Emit a dummy WAL record if insert-LSN hasn't advanced after the
585 * last call.
586 */
589
592
593 /* No need for an actual record if we already have a distinct LSN */
596
598 return currlsn;
599 }
600}
#define RelationNeedsWAL(relation)
Definition rel.h:637
#define RelationIsPermanent(relation)
Definition rel.h:626
Form_pg_class rd_rel
Definition rel.h:111
XLogRecPtr GetFakeLSNForUnloggedRel(void)
Definition xlog.c:4660
XLogRecPtr GetXLogInsertEndRecPtr(void)
Definition xlog.c:9630
XLogRecPtr XLogAssignLSN(void)
Definition xlog.c:8237
#define XLogRecPtrIsValid(r)
Definition xlogdefs.h:29
#define FirstNormalUnloggedLSN
Definition xlogdefs.h:37
#define InvalidXLogRecPtr
Definition xlogdefs.h:28

References Assert, fb(), FirstNormalUnloggedLSN, GetFakeLSNForUnloggedRel(), GetXLogInsertEndRecPtr(), InvalidXLogRecPtr, RelationData::rd_rel, RelationIsPermanent, RelationNeedsWAL, XLogAssignLSN(), and XLogRecPtrIsValid.

Referenced by _bt_dedup_pass(), _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_mark_page_halfdead(), _bt_newlevel(), _bt_set_cleanup_info(), _bt_split(), _bt_unlink_halfdead_page(), gistdeletepage(), gistplacetopage(), gistprunepage(), gistvacuumpage(), and gistvacuumscan().

◆ XLogInsert()

XLogRecPtr XLogInsert ( RmgrId  rmid,
uint8  info 
)
extern

Definition at line 479 of file xloginsert.c.

480{
482
483 /* XLogBeginInsert() must have been called. */
485 elog(ERROR, "XLogBeginInsert was not called");
486
487 /*
488 * The caller can set rmgr bits, XLR_SPECIAL_REL_UPDATE and
489 * XLR_CHECK_CONSISTENCY; the rest are reserved for use by me.
490 */
491 if ((info & ~(XLR_RMGR_INFO_MASK |
494 elog(PANIC, "invalid xlog info mask %02X", info);
495
496 TRACE_POSTGRESQL_WAL_INSERT(rmid, info);
497
498 /*
499 * In bootstrap mode, we don't actually log anything but XLOG resources;
500 * return a phony record pointer.
501 */
502 if (IsBootstrapProcessingMode() && rmid != RM_XLOG_ID)
503 {
505 EndPos = SizeOfXLogLongPHD; /* start of 1st chkpt record */
506 return EndPos;
507 }
508
509 do
510 {
512 bool doPageWrites;
513 bool topxid_included = false;
516 int num_fpi = 0;
517 uint64 fpi_bytes = 0;
518
519 /*
520 * Get values needed to decide whether to do full-page writes. Since
521 * we don't yet have an insertion lock, these could change under us,
522 * but XLogInsertRecord will recheck them once it has a lock.
523 */
525
529
532 } while (!XLogRecPtrIsValid(EndPos));
533
535
536 return EndPos;
537}
uint64_t uint64
Definition c.h:619
#define PANIC
Definition elog.h:42
#define IsBootstrapProcessingMode()
Definition miscadmin.h:477
XLogRecPtr XLogInsertRecord(XLogRecData *rdata, XLogRecPtr fpw_lsn, uint8 flags, int num_fpi, uint64 fpi_bytes, bool topxid_included)
Definition xlog.c:750
#define SizeOfXLogLongPHD
static uint8 curinsert_flags
Definition xloginsert.c:106
void XLogResetInsertion(void)
Definition xloginsert.c:226
static XLogRecData * XLogRecordAssemble(RmgrId rmid, uint8 info, XLogRecPtr RedoRecPtr, bool doPageWrites, XLogRecPtr *fpw_lsn, int *num_fpi, uint64 *fpi_bytes, bool *topxid_included)
Definition xloginsert.c:618
#define XLR_RMGR_INFO_MASK
Definition xlogrecord.h:63
#define XLR_SPECIAL_REL_UPDATE
Definition xlogrecord.h:82
#define XLR_CHECK_CONSISTENCY
Definition xlogrecord.h:91

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

Referenced by _bt_allocbuf(), _bt_dedup_pass(), _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_mark_page_halfdead(), _bt_newlevel(), _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(), CreateDatabaseUsingFileCopy(), CreateDirAndVersionFile(), CreateEndOfRecoveryRecord(), CreateOverwriteContrecordRecord(), createPostingTree(), CreateTableSpace(), do_pg_backup_stop(), doPickSplit(), DropTableSpace(), EndPrepare(), ExecuteTruncateGuts(), fill_seq_fork_with_data(), GenericXLogFinish(), ginDeletePostingPage(), ginHeapTupleFastInsert(), ginPlaceToPage(), ginUpdateStats(), ginVacuumPostingTreeLeaf(), gistXLogDelete(), gistXLogPageDelete(), gistXLogPageReuse(), gistXLogSplit(), gistXLogUpdate(), hashbucketcleanup(), hashbulkdelete(), heap_abort_speculative(), heap_delete(), heap_finish_speculative(), heap_inplace_update_and_unlock(), heap_insert(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), heap_multi_insert(), heap_update(), log_heap_new_cid(), log_heap_prune_and_freeze(), 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_state_clear(), RequestXLogSwitch(), revmap_physical_extend(), SetSequence(), shiftList(), spgAddNodeAction(), spgSplitNodeAction(), test_custom_rmgrs_insert_wal_record(), UpdateFullPageWrites(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), write_logical_decoding_status_update_record(), write_relmap_file(), writeListPage(), WriteMTruncateXlogRec(), WriteTruncateXlogRec(), WriteTruncateXlogRec(), XactLogAbortRecord(), XactLogCommitRecord(), XLogAssignLSN(), XLogPutNextOid(), XLogReportParameters(), XLogRestorePoint(), XLogSaveBufferForHint(), XLogSimpleInsertInt64(), and xlogVacuumPage().

◆ XLogRegisterBlock()

void XLogRegisterBlock ( uint8  block_id,
RelFileLocator rlocator,
ForkNumber  forknum,
BlockNumber  blknum,
const PageData page,
uint8  flags 
)
extern

Definition at line 314 of file xloginsert.c.

316{
318
320
323
325 elog(ERROR, "too many registered buffers");
326
328
329 regbuf->rlocator = *rlocator;
330 regbuf->forkno = forknum;
331 regbuf->block = blknum;
332 regbuf->page = page;
333 regbuf->flags = flags;
334 regbuf->rdata_tail = (XLogRecData *) &regbuf->rdata_head;
335 regbuf->rdata_len = 0;
336
337 /*
338 * Check that this page hasn't already been registered with some other
339 * block_id.
340 */
341#ifdef USE_ASSERT_CHECKING
342 {
343 int i;
344
345 for (i = 0; i < max_registered_block_id; i++)
346 {
348
349 if (i == block_id || !regbuf_old->in_use)
350 continue;
351
352 Assert(!RelFileLocatorEquals(regbuf_old->rlocator, regbuf->rlocator) ||
353 regbuf_old->forkno != regbuf->forkno ||
354 regbuf_old->block != regbuf->block);
355 }
356 }
357#endif
358
359 regbuf->in_use = true;
360}
#define RelFileLocatorEquals(locator1, locator2)
RelFileLocator rlocator
Definition xloginsert.c:75

References Assert, begininsert_called, elog, ERROR, fb(), i, max_registered_block_id, max_registered_buffers, registered_buffers, RelFileLocatorEquals, and registered_buffer::rlocator.

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

◆ XLogRegisterBufData()

void XLogRegisterBufData ( uint8  block_id,
const void data,
uint32  len 
)
extern

Definition at line 410 of file xloginsert.c.

411{
414
416
417 /* find the registered buffer struct */
419 if (!regbuf->in_use)
420 elog(ERROR, "no block with id %d registered with WAL insertion",
421 block_id);
422
423 /*
424 * Check against max_rdatas and ensure we do not register more data per
425 * buffer than can be handled by the physical data format; i.e. that
426 * regbuf->rdata_len does not grow beyond what
427 * XLogRecordBlockHeader->data_length can hold.
428 */
429 if (num_rdatas >= max_rdatas)
431 (errmsg_internal("too much WAL data"),
432 errdetail_internal("%d out of %d data segments are already in use.",
434 if (regbuf->rdata_len + len > UINT16_MAX || len > UINT16_MAX)
436 (errmsg_internal("too much WAL data"),
437 errdetail_internal("Registering more than maximum %u bytes allowed to block %u: current %u bytes, adding %u bytes.",
438 UINT16_MAX, block_id, regbuf->rdata_len, len)));
439
440 rdata = &rdatas[num_rdatas++];
441
442 rdata->data = data;
443 rdata->len = len;
444
445 regbuf->rdata_tail->next = rdata;
446 regbuf->rdata_tail = rdata;
447 regbuf->rdata_len += len;
448}
int int errdetail_internal(const char *fmt,...) pg_attribute_printf(1
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define ereport(elevel,...)
Definition elog.h:150
const void size_t len
const void * data
const void * data
static int num_rdatas
Definition xloginsert.c:132

References Assert, begininsert_called, XLogRecData::data, data, elog, ereport, errdetail_internal(), errmsg_internal(), ERROR, fb(), len, max_rdatas, num_rdatas, rdatas, and registered_buffers.

Referenced by _bt_dedup_pass(), _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_newlevel(), _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_and_unlock(), heap_insert(), heap_multi_insert(), log_heap_prune_and_freeze(), log_heap_update(), and writeListPage().

◆ XLogRegisterBuffer()

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

Definition at line 246 of file xloginsert.c.

247{
249
250 /* NO_IMAGE doesn't make sense with FORCE_IMAGE */
251 Assert(!((flags & REGBUF_FORCE_IMAGE) && (flags & (REGBUF_NO_IMAGE))));
253
254 /*
255 * Ordinarily, buffer should be exclusive-locked and marked dirty before
256 * we get here, otherwise we could end up violating one of the rules in
257 * access/transam/README.
258 *
259 * Some callers intentionally register a clean page and never update that
260 * page's LSN; in that case they can pass the flag REGBUF_NO_CHANGE to
261 * bypass these checks.
262 */
263#ifdef USE_ASSERT_CHECKING
264 if (!(flags & REGBUF_NO_CHANGE))
266 BufferIsDirty(buffer));
267#endif
268
270 {
272 elog(ERROR, "too many registered buffers");
274 }
275
277
278 BufferGetTag(buffer, &regbuf->rlocator, &regbuf->forkno, &regbuf->block);
279 regbuf->page = BufferGetPage(buffer);
280 regbuf->flags = flags;
281 regbuf->rdata_tail = (XLogRecData *) &regbuf->rdata_head;
282 regbuf->rdata_len = 0;
283
284 /*
285 * Check that this page hasn't already been registered with some other
286 * block_id.
287 */
288#ifdef USE_ASSERT_CHECKING
289 {
290 int i;
291
292 for (i = 0; i < max_registered_block_id; i++)
293 {
295
296 if (i == block_id || !regbuf_old->in_use)
297 continue;
298
299 Assert(!RelFileLocatorEquals(regbuf_old->rlocator, regbuf->rlocator) ||
300 regbuf_old->forkno != regbuf->forkno ||
301 regbuf_old->block != regbuf->block);
302 }
303 }
304#endif
305
306 regbuf->in_use = true;
307}
bool BufferIsLockedByMeInMode(Buffer buffer, BufferLockMode mode)
Definition bufmgr.c:3003
bool BufferIsDirty(Buffer buffer)
Definition bufmgr.c:3030
#define REGBUF_NO_CHANGE
Definition xloginsert.h:37
#define REGBUF_NO_IMAGE
Definition xloginsert.h:33

References Assert, begininsert_called, BUFFER_LOCK_EXCLUSIVE, BufferGetPage(), BufferGetTag(), BufferIsDirty(), BufferIsLockedByMeInMode(), elog, ERROR, fb(), i, max_registered_block_id, max_registered_buffers, REGBUF_FORCE_IMAGE, REGBUF_NO_CHANGE, REGBUF_NO_IMAGE, registered_buffers, and RelFileLocatorEquals.

Referenced by _bt_dedup_pass(), _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_mark_page_halfdead(), _bt_newlevel(), _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(), dataExecPlaceToPageInternal(), dataExecPlaceToPageLeaf(), doPickSplit(), entryExecPlaceToPage(), fill_seq_fork_with_data(), GenericXLogFinish(), ginDeletePostingPage(), ginHeapTupleFastInsert(), ginPlaceToPage(), ginUpdateStats(), ginVacuumPostingTreeLeaf(), gistXLogDelete(), gistXLogPageDelete(), gistXLogSplit(), gistXLogUpdate(), hashbucketcleanup(), hashbulkdelete(), heap_abort_speculative(), heap_delete(), heap_finish_speculative(), heap_insert(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), heap_multi_insert(), heap_update(), log_heap_prune_and_freeze(), log_heap_update(), log_heap_visible(), log_newpage_range(), log_split_page(), moveLeafs(), nextval_internal(), revmap_physical_extend(), SetSequence(), shiftList(), spgAddNodeAction(), spgSplitNodeAction(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), writeListPage(), and xlogVacuumPage().

◆ XLogRegisterData()

void XLogRegisterData ( const void data,
uint32  len 
)
extern

Definition at line 369 of file xloginsert.c.

370{
372
374
375 if (num_rdatas >= max_rdatas)
377 (errmsg_internal("too much WAL data"),
378 errdetail_internal("%d out of %d data segments are already in use.",
380 rdata = &rdatas[num_rdatas++];
381
382 rdata->data = data;
383 rdata->len = len;
384
385 /*
386 * we use the mainrdata_last pointer to track the end of the chain, so no
387 * need to clear 'next' here.
388 */
389
392
394}
struct XLogRecData * next

References Assert, begininsert_called, XLogRecData::data, data, ereport, errdetail_internal(), errmsg_internal(), ERROR, fb(), len, mainrdata_last, mainrdata_len, max_rdatas, XLogRecData::next, num_rdatas, and rdatas.

Referenced by _bt_allocbuf(), _bt_dedup_pass(), _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_mark_page_halfdead(), _bt_newlevel(), _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(), CreateDatabaseUsingFileCopy(), CreateDirAndVersionFile(), CreateEndOfRecoveryRecord(), CreateOverwriteContrecordRecord(), createPostingTree(), CreateTableSpace(), do_pg_backup_stop(), doPickSplit(), DropTableSpace(), EndPrepare(), ExecuteTruncateGuts(), fill_seq_fork_with_data(), ginDeletePostingPage(), ginHeapTupleFastInsert(), ginPlaceToPage(), ginUpdateStats(), gistXLogDelete(), gistXLogPageDelete(), gistXLogPageReuse(), gistXLogSplit(), gistXLogUpdate(), hashbucketcleanup(), hashbulkdelete(), heap_abort_speculative(), heap_delete(), heap_finish_speculative(), heap_inplace_update_and_unlock(), heap_insert(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), heap_multi_insert(), heap_update(), log_heap_new_cid(), log_heap_prune_and_freeze(), 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_state_clear(), revmap_physical_extend(), SetSequence(), shiftList(), spgAddNodeAction(), spgSplitNodeAction(), test_custom_rmgrs_insert_wal_record(), UpdateFullPageWrites(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), write_logical_decoding_status_update_record(), write_relmap_file(), writeListPage(), WriteMTruncateXlogRec(), WriteTruncateXlogRec(), WriteTruncateXlogRec(), XactLogAbortRecord(), XactLogCommitRecord(), XLogAssignLSN(), XLogPutNextOid(), XLogReportParameters(), XLogRestorePoint(), and XLogSimpleInsertInt64().

◆ XLogResetInsertion()

void XLogResetInsertion ( void  )
extern

◆ XLogSaveBufferForHint()

XLogRecPtr XLogSaveBufferForHint ( Buffer  buffer,
bool  buffer_std 
)
extern

Definition at line 1137 of file xloginsert.c.

1138{
1140 XLogRecPtr lsn;
1142
1143 /* this also verifies that we hold an appropriate lock */
1144 Assert(BufferIsDirty(buffer));
1145
1146 /*
1147 * Update RedoRecPtr so that we can make the right decision. It's possible
1148 * that a new checkpoint will start just after GetRedoRecPtr(), but that
1149 * is ok, as the buffer is already dirty, ensuring that any BufferSync()
1150 * started after the buffer was marked dirty cannot complete without
1151 * flushing this buffer. If a checkpoint started between marking the
1152 * buffer dirty and this check, we will emit an unnecessary WAL record (as
1153 * the buffer will be written out as part of the checkpoint), but the
1154 * window for that is not big.
1155 */
1157
1158 /*
1159 * We assume page LSN is first data on *every* page that can be passed to
1160 * XLogInsert, whether it has the standard page layout or not.
1161 */
1162 lsn = PageGetLSN(BufferGetPage(buffer));
1163
1164 if (lsn <= RedoRecPtr)
1165 {
1166 int flags = 0;
1168 char *origdata = (char *) BufferGetBlock(buffer);
1169 RelFileLocator rlocator;
1170 ForkNumber forkno;
1171 BlockNumber blkno;
1172
1173 /*
1174 * Copy buffer so we don't have to worry about concurrent hint bit or
1175 * lsn updates. We assume pd_lower/upper cannot be changed without an
1176 * exclusive lock, so the contents bkp are not racy.
1177 */
1178 if (buffer_std)
1179 {
1180 /* Assume we can omit data between pd_lower and pd_upper */
1181 Page page = BufferGetPage(buffer);
1182 uint16 lower = ((PageHeader) page)->pd_lower;
1183 uint16 upper = ((PageHeader) page)->pd_upper;
1184
1187 }
1188 else
1190
1192
1193 if (buffer_std)
1194 flags |= REGBUF_STANDARD;
1195
1196 BufferGetTag(buffer, &rlocator, &forkno, &blkno);
1197 XLogRegisterBlock(0, &rlocator, forkno, blkno, copied_buffer.data, flags);
1198
1200 }
1201
1202 return recptr;
1203}
static Block BufferGetBlock(Buffer buffer)
Definition bufmgr.h:437
PageHeaderData * PageHeader
Definition bufpage.h:199
uint16_t uint16
Definition c.h:617
Datum lower(PG_FUNCTION_ARGS)
Datum upper(PG_FUNCTION_ARGS)
#define XLOG_FPI_FOR_HINT
Definition pg_control.h:79
XLogRecPtr GetRedoRecPtr(void)
Definition xlog.c:6547

References Assert, BufferGetBlock(), BufferGetPage(), BufferGetTag(), BufferIsDirty(), fb(), GetRedoRecPtr(), InvalidXLogRecPtr, lower(), PageGetLSN(), RedoRecPtr, REGBUF_STANDARD, upper(), XLOG_FPI_FOR_HINT, XLogBeginInsert(), XLogInsert(), and XLogRegisterBlock().

Referenced by MarkSharedBufferDirtyHint().

◆ XLogSetRecordFlags()

◆ XLogSimpleInsertInt64()

XLogRecPtr XLogSimpleInsertInt64 ( RmgrId  rmid,
uint8  info,
int64  value 
)
extern

Definition at line 544 of file xloginsert.c.

545{
547 XLogRegisterData(&value, sizeof(value));
548 return XLogInsert(rmid, info);
549}
static struct @174 value
void XLogRegisterData(const void *data, uint32 len)
Definition xloginsert.c:369

References value, XLogBeginInsert(), XLogInsert(), and XLogRegisterData().

Referenced by ExtendCLOG(), ExtendCommitTs(), ExtendMultiXactMember(), and ExtendMultiXactOffset().