PostgreSQL Source Code  git master
xlog.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <math.h>
#include <time.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include "access/clog.h"
#include "access/commit_ts.h"
#include "access/heaptoast.h"
#include "access/multixact.h"
#include "access/rewriteheap.h"
#include "access/subtrans.h"
#include "access/timeline.h"
#include "access/transam.h"
#include "access/twophase.h"
#include "access/xact.h"
#include "access/xlog_internal.h"
#include "access/xlogarchive.h"
#include "access/xloginsert.h"
#include "access/xlogreader.h"
#include "access/xlogrecovery.h"
#include "access/xlogutils.h"
#include "backup/basebackup.h"
#include "catalog/catversion.h"
#include "catalog/pg_control.h"
#include "catalog/pg_database.h"
#include "common/controldata_utils.h"
#include "common/file_utils.h"
#include "executor/instrument.h"
#include "miscadmin.h"
#include "pg_trace.h"
#include "pgstat.h"
#include "port/atomics.h"
#include "postmaster/bgwriter.h"
#include "postmaster/startup.h"
#include "postmaster/walsummarizer.h"
#include "postmaster/walwriter.h"
#include "replication/origin.h"
#include "replication/slot.h"
#include "replication/snapbuild.h"
#include "replication/walreceiver.h"
#include "replication/walsender.h"
#include "storage/bufmgr.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/large_object.h"
#include "storage/latch.h"
#include "storage/predicate.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/reinit.h"
#include "storage/spin.h"
#include "storage/sync.h"
#include "utils/guc_hooks.h"
#include "utils/guc_tables.h"
#include "utils/injection_point.h"
#include "utils/ps_status.h"
#include "utils/relmapper.h"
#include "utils/snapmgr.h"
#include "utils/timeout.h"
#include "utils/timestamp.h"
#include "utils/varlena.h"
Include dependency graph for xlog.c:

Go to the source code of this file.

Data Structures

struct  XLogwrtRqst
 
struct  XLogwrtResult
 
struct  WALInsertLock
 
union  WALInsertLockPadded
 
struct  XLogCtlInsert
 
struct  XLogCtlData
 

Macros

#define BootstrapTimeLineID   1
 
#define NUM_XLOGINSERT_LOCKS   8
 
#define INSERT_FREESPACE(endptr)    (((endptr) % XLOG_BLCKSZ == 0) ? 0 : (XLOG_BLCKSZ - (endptr) % XLOG_BLCKSZ))
 
#define NextBufIdx(idx)    (((idx) == XLogCtl->XLogCacheBlck) ? 0 : ((idx) + 1))
 
#define XLogRecPtrToBufIdx(recptr)    (((recptr) / XLOG_BLCKSZ) % (XLogCtl->XLogCacheBlck + 1))
 
#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)
 
#define ConvertToXSegs(x, segsize)   XLogMBVarToSegs((x), (segsize))
 
#define RefreshXLogWriteResult(_target)
 

Typedefs

typedef struct XLogwrtRqst XLogwrtRqst
 
typedef struct XLogwrtResult XLogwrtResult
 
typedef union WALInsertLockPadded WALInsertLockPadded
 
typedef struct XLogCtlInsert XLogCtlInsert
 
typedef struct XLogCtlData XLogCtlData
 

Enumerations

enum  WalInsertClass { WALINSERT_NORMAL , WALINSERT_SPECIAL_SWITCH , WALINSERT_SPECIAL_CHECKPOINT }
 

Functions

static void CleanupAfterArchiveRecovery (TimeLineID EndOfLogTLI, XLogRecPtr EndOfLog, TimeLineID newTLI)
 
static void CheckRequiredParameterValues (void)
 
static void XLogReportParameters (void)
 
static int LocalSetXLogInsertAllowed (void)
 
static void CreateEndOfRecoveryRecord (void)
 
static XLogRecPtr CreateOverwriteContrecordRecord (XLogRecPtr aborted_lsn, XLogRecPtr pagePtr, TimeLineID newTLI)
 
static void CheckPointGuts (XLogRecPtr checkPointRedo, int flags)
 
static void KeepLogSeg (XLogRecPtr recptr, XLogSegNo *logSegNo)
 
static XLogRecPtr XLogGetReplicationSlotMinimumLSN (void)
 
static void AdvanceXLInsertBuffer (XLogRecPtr upto, TimeLineID tli, bool opportunistic)
 
static void XLogWrite (XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
 
static bool InstallXLogFileSegment (XLogSegNo *segno, char *tmppath, bool find_free, XLogSegNo max_segno, TimeLineID tli)
 
static void XLogFileClose (void)
 
static void PreallocXlogFiles (XLogRecPtr endptr, TimeLineID tli)
 
static void RemoveTempXlogFiles (void)
 
static void RemoveOldXlogFiles (XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr, TimeLineID insertTLI)
 
static void RemoveXlogFile (const struct dirent *segment_de, XLogSegNo recycleSegNo, XLogSegNo *endlogSegNo, TimeLineID insertTLI)
 
static void UpdateLastRemovedPtr (char *filename)
 
static void ValidateXLOGDirectoryStructure (void)
 
static void CleanupBackupHistory (void)
 
static void UpdateMinRecoveryPoint (XLogRecPtr lsn, bool force)
 
static bool PerformRecoveryXLogAction (void)
 
static void InitControlFile (uint64 sysidentifier, uint32 data_checksum_version)
 
static void WriteControlFile (void)
 
static void ReadControlFile (void)
 
static void UpdateControlFile (void)
 
static char * str_time (pg_time_t tnow)
 
static int get_sync_bit (int method)
 
static void CopyXLogRecordToWAL (int write_len, bool isLogSwitch, XLogRecData *rdata, XLogRecPtr StartPos, XLogRecPtr EndPos, TimeLineID tli)
 
static void ReserveXLogInsertLocation (int size, XLogRecPtr *StartPos, XLogRecPtr *EndPos, XLogRecPtr *PrevPtr)
 
static bool ReserveXLogSwitch (XLogRecPtr *StartPos, XLogRecPtr *EndPos, XLogRecPtr *PrevPtr)
 
static XLogRecPtr WaitXLogInsertionsToFinish (XLogRecPtr upto)
 
static char * GetXLogBuffer (XLogRecPtr ptr, TimeLineID tli)
 
static XLogRecPtr XLogBytePosToRecPtr (uint64 bytepos)
 
static XLogRecPtr XLogBytePosToEndRecPtr (uint64 bytepos)
 
static uint64 XLogRecPtrToBytePos (XLogRecPtr ptr)
 
static void WALInsertLockAcquire (void)
 
static void WALInsertLockAcquireExclusive (void)
 
static void WALInsertLockRelease (void)
 
static void WALInsertLockUpdateInsertingAt (XLogRecPtr insertingAt)
 
XLogRecPtr XLogInsertRecord (XLogRecData *rdata, XLogRecPtr fpw_lsn, uint8 flags, int num_fpi, bool topxid_included)
 
Size WALReadFromBuffers (char *dstbuf, XLogRecPtr startptr, Size count, TimeLineID tli)
 
static void CalculateCheckpointSegments (void)
 
void assign_max_wal_size (int newval, void *extra)
 
void assign_checkpoint_completion_target (double newval, void *extra)
 
bool check_wal_segment_size (int *newval, void **extra, GucSource source)
 
bool check_max_slot_wal_keep_size (int *newval, void **extra, GucSource source)
 
static XLogSegNo XLOGfileslop (XLogRecPtr lastredoptr)
 
bool XLogCheckpointNeeded (XLogSegNo new_segno)
 
void XLogSetAsyncXactLSN (XLogRecPtr asyncXactLSN)
 
void XLogSetReplicationSlotMinimumLSN (XLogRecPtr lsn)
 
void XLogFlush (XLogRecPtr record)
 
bool XLogBackgroundFlush (void)
 
bool XLogNeedsFlush (XLogRecPtr record)
 
static int XLogFileInitInternal (XLogSegNo logsegno, TimeLineID logtli, bool *added, char *path)
 
int XLogFileInit (XLogSegNo logsegno, TimeLineID logtli)
 
static void XLogFileCopy (TimeLineID destTLI, XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno, int upto)
 
int XLogFileOpen (XLogSegNo segno, TimeLineID tli)
 
void CheckXLogRemoved (XLogSegNo segno, TimeLineID tli)
 
XLogSegNo XLogGetLastRemovedSegno (void)
 
XLogSegNo XLogGetOldestSegno (TimeLineID tli)
 
void RemoveNonParentXlogFiles (XLogRecPtr switchpoint, TimeLineID newTLI)
 
uint64 GetSystemIdentifier (void)
 
char * GetMockAuthenticationNonce (void)
 
bool DataChecksumsEnabled (void)
 
XLogRecPtr GetFakeLSNForUnloggedRel (void)
 
static int XLOGChooseNumBuffers (void)
 
bool check_wal_buffers (int *newval, void **extra, GucSource source)
 
bool check_wal_consistency_checking (char **newval, void **extra, GucSource source)
 
void assign_wal_consistency_checking (const char *newval, void *extra)
 
void InitializeWalConsistencyChecking (void)
 
const char * show_archive_command (void)
 
const char * show_in_hot_standby (void)
 
void LocalProcessControlFile (bool reset)
 
WalLevel GetActiveWalLevelOnStandby (void)
 
Size XLOGShmemSize (void)
 
void XLOGShmemInit (void)
 
void BootStrapXLOG (uint32 data_checksum_version)
 
static void XLogInitNewTimeline (TimeLineID endTLI, XLogRecPtr endOfLog, TimeLineID newTLI)
 
void StartupXLOG (void)
 
void SwitchIntoArchiveRecovery (XLogRecPtr EndRecPtr, TimeLineID replayTLI)
 
void ReachedEndOfBackup (XLogRecPtr EndRecPtr, TimeLineID tli)
 
bool RecoveryInProgress (void)
 
RecoveryState GetRecoveryState (void)
 
bool XLogInsertAllowed (void)
 
XLogRecPtr GetRedoRecPtr (void)
 
void GetFullPageWriteInfo (XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p)
 
XLogRecPtr GetInsertRecPtr (void)
 
XLogRecPtr GetFlushRecPtr (TimeLineID *insertTLI)
 
TimeLineID GetWALInsertionTimeLine (void)
 
TimeLineID GetWALInsertionTimeLineIfSet (void)
 
XLogRecPtr GetLastImportantRecPtr (void)
 
pg_time_t GetLastSegSwitchData (XLogRecPtr *lastSwitchLSN)
 
void ShutdownXLOG (int code, Datum arg)
 
static void LogCheckpointStart (int flags, bool restartpoint)
 
static void LogCheckpointEnd (bool restartpoint)
 
static void UpdateCheckPointDistanceEstimate (uint64 nbytes)
 
static void update_checkpoint_display (int flags, bool restartpoint, bool reset)
 
bool CreateCheckPoint (int flags)
 
static void RecoveryRestartPoint (const CheckPoint *checkPoint, XLogReaderState *record)
 
bool CreateRestartPoint (int flags)
 
WALAvailability GetWALAvailability (XLogRecPtr targetLSN)
 
void XLogPutNextOid (Oid nextOid)
 
XLogRecPtr RequestXLogSwitch (bool mark_unimportant)
 
XLogRecPtr XLogRestorePoint (const char *rpName)
 
void UpdateFullPageWrites (void)
 
void xlog_redo (XLogReaderState *record)
 
void assign_wal_sync_method (int new_wal_sync_method, void *extra)
 
void issue_xlog_fsync (int fd, XLogSegNo segno, TimeLineID tli)
 
void do_pg_backup_start (const char *backupidstr, bool fast, List **tablespaces, BackupState *state, StringInfo tblspcmapfile)
 
SessionBackupState get_backup_status (void)
 
void do_pg_backup_stop (BackupState *state, bool waitforarchive)
 
void do_pg_abort_backup (int code, Datum arg)
 
void register_persistent_abort_backup_handler (void)
 
XLogRecPtr GetXLogInsertRecPtr (void)
 
XLogRecPtr GetXLogWriteRecPtr (void)
 
void GetOldestRestartPoint (XLogRecPtr *oldrecptr, TimeLineID *oldtli)
 
void XLogShutdownWalRcv (void)
 
void SetInstallXLogFileSegmentActive (void)
 
bool IsInstallXLogFileSegmentActive (void)
 
void SetWalWriterSleeping (bool sleeping)
 

Variables

int max_wal_size_mb = 1024
 
int min_wal_size_mb = 80
 
int wal_keep_size_mb = 0
 
int XLOGbuffers = -1
 
int XLogArchiveTimeout = 0
 
int XLogArchiveMode = ARCHIVE_MODE_OFF
 
char * XLogArchiveCommand = NULL
 
bool EnableHotStandby = false
 
bool fullPageWrites = true
 
bool wal_log_hints = false
 
int wal_compression = WAL_COMPRESSION_NONE
 
char * wal_consistency_checking_string = NULL
 
bool * wal_consistency_checking = NULL
 
bool wal_init_zero = true
 
bool wal_recycle = true
 
bool log_checkpoints = true
 
int wal_sync_method = DEFAULT_WAL_SYNC_METHOD
 
int wal_level = WAL_LEVEL_REPLICA
 
int CommitDelay = 0
 
int CommitSiblings = 5
 
int wal_retrieve_retry_interval = 5000
 
int max_slot_wal_keep_size_mb = -1
 
int wal_decode_buffer_size = 512 * 1024
 
bool track_wal_io_timing = false
 
int wal_segment_size = DEFAULT_XLOG_SEG_SIZE
 
int CheckPointSegments
 
static double CheckPointDistanceEstimate = 0
 
static double PrevCheckPointDistance = 0
 
static bool check_wal_consistency_checking_deferred = false
 
const struct config_enum_entry wal_sync_method_options []
 
const struct config_enum_entry archive_mode_options []
 
CheckpointStatsData CheckpointStats
 
static bool lastFullPageWrites
 
static bool LocalRecoveryInProgress = true
 
static int LocalXLogInsertAllowed = -1
 
XLogRecPtr ProcLastRecPtr = InvalidXLogRecPtr
 
XLogRecPtr XactLastRecEnd = InvalidXLogRecPtr
 
XLogRecPtr XactLastCommitEnd = InvalidXLogRecPtr
 
static XLogRecPtr RedoRecPtr
 
static bool doPageWrites
 
static SessionBackupState sessionBackupState = SESSION_BACKUP_NONE
 
static XLogCtlDataXLogCtl = NULL
 
static WALInsertLockPaddedWALInsertLocks = NULL
 
static ControlFileDataControlFile = NULL
 
static int UsableBytesInSegment
 
static XLogwrtResult LogwrtResult = {0, 0}
 
static int openLogFile = -1
 
static XLogSegNo openLogSegNo = 0
 
static TimeLineID openLogTLI = 0
 
static XLogRecPtr LocalMinRecoveryPoint
 
static TimeLineID LocalMinRecoveryPointTLI
 
static bool updateMinRecoveryPoint = true
 
static int MyLockNo = 0
 
static bool holdingAllLocks = false
 

Macro Definition Documentation

◆ BootstrapTimeLineID

#define BootstrapTimeLineID   1

Definition at line 111 of file xlog.c.

◆ ConvertToXSegs

#define ConvertToXSegs (   x,
  segsize 
)    XLogMBVarToSegs((x), (segsize))

Definition at line 603 of file xlog.c.

◆ INSERT_FREESPACE

#define INSERT_FREESPACE (   endptr)     (((endptr) % XLOG_BLCKSZ == 0) ? 0 : (XLOG_BLCKSZ - (endptr) % XLOG_BLCKSZ))

Definition at line 580 of file xlog.c.

◆ NextBufIdx

#define NextBufIdx (   idx)     (((idx) == XLogCtl->XLogCacheBlck) ? 0 : ((idx) + 1))

Definition at line 584 of file xlog.c.

◆ NUM_XLOGINSERT_LOCKS

#define NUM_XLOGINSERT_LOCKS   8

Definition at line 150 of file xlog.c.

◆ RefreshXLogWriteResult

#define RefreshXLogWriteResult (   _target)
Value:
do { \
pg_read_barrier(); \
} while (0)
static uint64 pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr)
Definition: atomics.h:467
pg_atomic_uint64 logWriteResult
Definition: xlog.c:472
pg_atomic_uint64 logFlushResult
Definition: xlog.c:473
static XLogCtlData * XLogCtl
Definition: xlog.c:566

Definition at line 620 of file xlog.c.

◆ UsableBytesInPage

#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)

Definition at line 597 of file xlog.c.

◆ XLogRecPtrToBufIdx

#define XLogRecPtrToBufIdx (   recptr)     (((recptr) / XLOG_BLCKSZ) % (XLogCtl->XLogCacheBlck + 1))

Definition at line 591 of file xlog.c.

Typedef Documentation

◆ WALInsertLockPadded

◆ XLogCtlData

typedef struct XLogCtlData XLogCtlData

◆ XLogCtlInsert

typedef struct XLogCtlInsert XLogCtlInsert

◆ XLogwrtResult

typedef struct XLogwrtResult XLogwrtResult

◆ XLogwrtRqst

typedef struct XLogwrtRqst XLogwrtRqst

Enumeration Type Documentation

◆ WalInsertClass

Enumerator
WALINSERT_NORMAL 
WALINSERT_SPECIAL_SWITCH 
WALINSERT_SPECIAL_CHECKPOINT 

Definition at line 559 of file xlog.c.

560 {
WalInsertClass
Definition: xlog.c:560
@ WALINSERT_SPECIAL_SWITCH
Definition: xlog.c:562
@ WALINSERT_NORMAL
Definition: xlog.c:561
@ WALINSERT_SPECIAL_CHECKPOINT
Definition: xlog.c:563

Function Documentation

◆ AdvanceXLInsertBuffer()

static void AdvanceXLInsertBuffer ( XLogRecPtr  upto,
TimeLineID  tli,
bool  opportunistic 
)
static

Definition at line 1985 of file xlog.c.

1986 {
1988  int nextidx;
1989  XLogRecPtr OldPageRqstPtr;
1990  XLogwrtRqst WriteRqst;
1991  XLogRecPtr NewPageEndPtr = InvalidXLogRecPtr;
1992  XLogRecPtr NewPageBeginPtr;
1993  XLogPageHeader NewPage;
1994  int npages pg_attribute_unused() = 0;
1995 
1996  LWLockAcquire(WALBufMappingLock, LW_EXCLUSIVE);
1997 
1998  /*
1999  * Now that we have the lock, check if someone initialized the page
2000  * already.
2001  */
2002  while (upto >= XLogCtl->InitializedUpTo || opportunistic)
2003  {
2005 
2006  /*
2007  * Get ending-offset of the buffer page we need to replace (this may
2008  * be zero if the buffer hasn't been used yet). Fall through if it's
2009  * already written out.
2010  */
2011  OldPageRqstPtr = pg_atomic_read_u64(&XLogCtl->xlblocks[nextidx]);
2012  if (LogwrtResult.Write < OldPageRqstPtr)
2013  {
2014  /*
2015  * Nope, got work to do. If we just want to pre-initialize as much
2016  * as we can without flushing, give up now.
2017  */
2018  if (opportunistic)
2019  break;
2020 
2021  /* Advance shared memory write request position */
2023  if (XLogCtl->LogwrtRqst.Write < OldPageRqstPtr)
2024  XLogCtl->LogwrtRqst.Write = OldPageRqstPtr;
2026 
2027  /*
2028  * Acquire an up-to-date LogwrtResult value and see if we still
2029  * need to write it or if someone else already did.
2030  */
2032  if (LogwrtResult.Write < OldPageRqstPtr)
2033  {
2034  /*
2035  * Must acquire write lock. Release WALBufMappingLock first,
2036  * to make sure that all insertions that we need to wait for
2037  * can finish (up to this same position). Otherwise we risk
2038  * deadlock.
2039  */
2040  LWLockRelease(WALBufMappingLock);
2041 
2042  WaitXLogInsertionsToFinish(OldPageRqstPtr);
2043 
2044  LWLockAcquire(WALWriteLock, LW_EXCLUSIVE);
2045 
2047  if (LogwrtResult.Write >= OldPageRqstPtr)
2048  {
2049  /* OK, someone wrote it already */
2050  LWLockRelease(WALWriteLock);
2051  }
2052  else
2053  {
2054  /* Have to write it ourselves */
2055  TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_START();
2056  WriteRqst.Write = OldPageRqstPtr;
2057  WriteRqst.Flush = 0;
2058  XLogWrite(WriteRqst, tli, false);
2059  LWLockRelease(WALWriteLock);
2061  TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_DONE();
2062  }
2063  /* Re-acquire WALBufMappingLock and retry */
2064  LWLockAcquire(WALBufMappingLock, LW_EXCLUSIVE);
2065  continue;
2066  }
2067  }
2068 
2069  /*
2070  * Now the next buffer slot is free and we can set it up to be the
2071  * next output page.
2072  */
2073  NewPageBeginPtr = XLogCtl->InitializedUpTo;
2074  NewPageEndPtr = NewPageBeginPtr + XLOG_BLCKSZ;
2075 
2076  Assert(XLogRecPtrToBufIdx(NewPageBeginPtr) == nextidx);
2077 
2078  NewPage = (XLogPageHeader) (XLogCtl->pages + nextidx * (Size) XLOG_BLCKSZ);
2079 
2080  /*
2081  * Mark the xlblock with InvalidXLogRecPtr and issue a write barrier
2082  * before initializing. Otherwise, the old page may be partially
2083  * zeroed but look valid.
2084  */
2086  pg_write_barrier();
2087 
2088  /*
2089  * Be sure to re-zero the buffer so that bytes beyond what we've
2090  * written will look like zeroes and not valid XLOG records...
2091  */
2092  MemSet((char *) NewPage, 0, XLOG_BLCKSZ);
2093 
2094  /*
2095  * Fill the new page's header
2096  */
2097  NewPage->xlp_magic = XLOG_PAGE_MAGIC;
2098 
2099  /* NewPage->xlp_info = 0; */ /* done by memset */
2100  NewPage->xlp_tli = tli;
2101  NewPage->xlp_pageaddr = NewPageBeginPtr;
2102 
2103  /* NewPage->xlp_rem_len = 0; */ /* done by memset */
2104 
2105  /*
2106  * If online backup is not in progress, mark the header to indicate
2107  * that WAL records beginning in this page have removable backup
2108  * blocks. This allows the WAL archiver to know whether it is safe to
2109  * compress archived WAL data by transforming full-block records into
2110  * the non-full-block format. It is sufficient to record this at the
2111  * page level because we force a page switch (in fact a segment
2112  * switch) when starting a backup, so the flag will be off before any
2113  * records can be written during the backup. At the end of a backup,
2114  * the last page will be marked as all unsafe when perhaps only part
2115  * is unsafe, but at worst the archiver would miss the opportunity to
2116  * compress a few records.
2117  */
2118  if (Insert->runningBackups == 0)
2119  NewPage->xlp_info |= XLP_BKP_REMOVABLE;
2120 
2121  /*
2122  * If first page of an XLOG segment file, make it a long header.
2123  */
2124  if ((XLogSegmentOffset(NewPage->xlp_pageaddr, wal_segment_size)) == 0)
2125  {
2126  XLogLongPageHeader NewLongPage = (XLogLongPageHeader) NewPage;
2127 
2128  NewLongPage->xlp_sysid = ControlFile->system_identifier;
2129  NewLongPage->xlp_seg_size = wal_segment_size;
2130  NewLongPage->xlp_xlog_blcksz = XLOG_BLCKSZ;
2131  NewPage->xlp_info |= XLP_LONG_HEADER;
2132  }
2133 
2134  /*
2135  * Make sure the initialization of the page becomes visible to others
2136  * before the xlblocks update. GetXLogBuffer() reads xlblocks without
2137  * holding a lock.
2138  */
2139  pg_write_barrier();
2140 
2141  pg_atomic_write_u64(&XLogCtl->xlblocks[nextidx], NewPageEndPtr);
2142  XLogCtl->InitializedUpTo = NewPageEndPtr;
2143 
2144  npages++;
2145  }
2146  LWLockRelease(WALBufMappingLock);
2147 
2148 #ifdef WAL_DEBUG
2149  if (XLOG_DEBUG && npages > 0)
2150  {
2151  elog(DEBUG1, "initialized %d pages, up to %X/%X",
2152  npages, LSN_FORMAT_ARGS(NewPageEndPtr));
2153  }
2154 #endif
2155 }
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:485
#define pg_write_barrier()
Definition: atomics.h:157
#define pg_attribute_unused()
Definition: c.h:130
#define Assert(condition)
Definition: c.h:812
#define MemSet(start, val, len)
Definition: c.h:974
size_t Size
Definition: c.h:559
#define DEBUG1
Definition: elog.h:30
#define elog(elevel,...)
Definition: elog.h:225
static void Insert(File file)
Definition: fd.c:1312
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1168
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1781
@ LW_EXCLUSIVE
Definition: lwlock.h:114
PgStat_PendingWalStats PendingWalStats
Definition: pgstat_wal.c:24
#define SpinLockRelease(lock)
Definition: spin.h:61
#define SpinLockAcquire(lock)
Definition: spin.h:59
uint64 system_identifier
Definition: pg_control.h:110
PgStat_Counter wal_buffers_full
Definition: pgstat.h:504
XLogwrtRqst LogwrtRqst
Definition: xlog.c:455
slock_t info_lck
Definition: xlog.c:553
XLogRecPtr InitializedUpTo
Definition: xlog.c:485
char * pages
Definition: xlog.c:492
pg_atomic_uint64 * xlblocks
Definition: xlog.c:493
XLogCtlInsert Insert
Definition: xlog.c:452
TimeLineID xlp_tli
Definition: xlog_internal.h:40
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
XLogRecPtr Write
Definition: xlog.c:327
XLogRecPtr Flush
Definition: xlog.c:322
XLogRecPtr Write
Definition: xlog.c:321
static XLogRecPtr WaitXLogInsertionsToFinish(XLogRecPtr upto)
Definition: xlog.c:1504
#define RefreshXLogWriteResult(_target)
Definition: xlog.c:620
int wal_segment_size
Definition: xlog.c:143
static XLogwrtResult LogwrtResult
Definition: xlog.c:612
#define XLogRecPtrToBufIdx(recptr)
Definition: xlog.c:591
static void XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
Definition: xlog.c:2314
static ControlFileData * ControlFile
Definition: xlog.c:574
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:71
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:54
#define XLP_LONG_HEADER
Definition: xlog_internal.h:76
#define XLP_BKP_REMOVABLE
Definition: xlog_internal.h:78
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
#define LSN_FORMAT_ARGS(lsn)
Definition: xlogdefs.h:43
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28

References Assert, ControlFile, DEBUG1, elog, XLogwrtRqst::Flush, XLogCtlData::info_lck, XLogCtlData::InitializedUpTo, XLogCtlData::Insert, Insert(), InvalidXLogRecPtr, LogwrtResult, XLogCtlData::LogwrtRqst, LSN_FORMAT_ARGS, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MemSet, XLogCtlData::pages, PendingWalStats, pg_atomic_read_u64(), pg_atomic_write_u64(), pg_attribute_unused, pg_write_barrier, RefreshXLogWriteResult, SpinLockAcquire, SpinLockRelease, ControlFileData::system_identifier, WaitXLogInsertionsToFinish(), PgStat_PendingWalStats::wal_buffers_full, wal_segment_size, XLogwrtRqst::Write, XLogwrtResult::Write, XLogCtlData::xlblocks, XLOG_PAGE_MAGIC, XLogCtl, XLogRecPtrToBufIdx, XLogSegmentOffset, XLogWrite(), XLP_BKP_REMOVABLE, XLP_LONG_HEADER, XLogLongPageHeaderData::xlp_seg_size, XLogLongPageHeaderData::xlp_sysid, and XLogLongPageHeaderData::xlp_xlog_blcksz.

Referenced by GetXLogBuffer(), and XLogBackgroundFlush().

◆ assign_checkpoint_completion_target()

void assign_checkpoint_completion_target ( double  newval,
void *  extra 
)

Definition at line 2198 of file xlog.c.

2199 {
2202 }
double CheckPointCompletionTarget
Definition: checkpointer.c:138
#define newval
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2162

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2191 of file xlog.c.

2192 {
2195 }
int max_wal_size_mb
Definition: xlog.c:114

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

◆ assign_wal_consistency_checking()

void assign_wal_consistency_checking ( const char *  newval,
void *  extra 
)

Definition at line 4757 of file xlog.c.

4758 {
4759  /*
4760  * If some checks were deferred, it's possible that the checks will fail
4761  * later during InitializeWalConsistencyChecking(). But in that case, the
4762  * postmaster will exit anyway, so it's safe to proceed with the
4763  * assignment.
4764  *
4765  * Any built-in resource managers specified are assigned immediately,
4766  * which affects WAL created before shared_preload_libraries are
4767  * processed. Any custom resource managers specified won't be assigned
4768  * until after shared_preload_libraries are processed, but that's OK
4769  * because WAL for a custom resource manager can't be written before the
4770  * module is loaded anyway.
4771  */
4772  wal_consistency_checking = extra;
4773 }
bool * wal_consistency_checking
Definition: xlog.c:126

References wal_consistency_checking.

◆ assign_wal_sync_method()

void assign_wal_sync_method ( int  new_wal_sync_method,
void *  extra 
)

Definition at line 8641 of file xlog.c.

8642 {
8643  if (wal_sync_method != new_wal_sync_method)
8644  {
8645  /*
8646  * To ensure that no blocks escape unsynced, force an fsync on the
8647  * currently open log segment (if any). Also, if the open flag is
8648  * changing, close the log file so it will be reopened (with new flag
8649  * bit) at next use.
8650  */
8651  if (openLogFile >= 0)
8652  {
8653  pgstat_report_wait_start(WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN);
8654  if (pg_fsync(openLogFile) != 0)
8655  {
8656  char xlogfname[MAXFNAMELEN];
8657  int save_errno;
8658 
8659  save_errno = errno;
8660  XLogFileName(xlogfname, openLogTLI, openLogSegNo,
8662  errno = save_errno;
8663  ereport(PANIC,
8665  errmsg("could not fsync file \"%s\": %m", xlogfname)));
8666  }
8667 
8669  if (get_sync_bit(wal_sync_method) != get_sync_bit(new_wal_sync_method))
8670  XLogFileClose();
8671  }
8672  }
8673 }
int errcode_for_file_access(void)
Definition: elog.c:876
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define PANIC
Definition: elog.h:42
#define ereport(elevel,...)
Definition: elog.h:149
int pg_fsync(int fd)
Definition: fd.c:385
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:85
static void pgstat_report_wait_end(void)
Definition: wait_event.h:101
static int openLogFile
Definition: xlog.c:635
static int get_sync_bit(int method)
Definition: xlog.c:8593
int wal_sync_method
Definition: xlog.c:130
static TimeLineID openLogTLI
Definition: xlog.c:637
static void XLogFileClose(void)
Definition: xlog.c:3639
static XLogSegNo openLogSegNo
Definition: xlog.c:636
#define MAXFNAMELEN
static void XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)

References ereport, errcode_for_file_access(), errmsg(), get_sync_bit(), MAXFNAMELEN, openLogFile, openLogSegNo, openLogTLI, PANIC, pg_fsync(), pgstat_report_wait_end(), pgstat_report_wait_start(), wal_segment_size, wal_sync_method, XLogFileClose(), and XLogFileName().

◆ BootStrapXLOG()

void BootStrapXLOG ( uint32  data_checksum_version)

Definition at line 5033 of file xlog.c.

5034 {
5035  CheckPoint checkPoint;
5036  char *buffer;
5037  XLogPageHeader page;
5038  XLogLongPageHeader longpage;
5039  XLogRecord *record;
5040  char *recptr;
5041  uint64 sysidentifier;
5042  struct timeval tv;
5043  pg_crc32c crc;
5044 
5045  /* allow ordinary WAL segment creation, like StartupXLOG() would */
5047 
5048  /*
5049  * Select a hopefully-unique system identifier code for this installation.
5050  * We use the result of gettimeofday(), including the fractional seconds
5051  * field, as being about as unique as we can easily get. (Think not to
5052  * use random(), since it hasn't been seeded and there's no portable way
5053  * to seed it other than the system clock value...) The upper half of the
5054  * uint64 value is just the tv_sec part, while the lower half contains the
5055  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
5056  * PID for a little extra uniqueness. A person knowing this encoding can
5057  * determine the initialization time of the installation, which could
5058  * perhaps be useful sometimes.
5059  */
5060  gettimeofday(&tv, NULL);
5061  sysidentifier = ((uint64) tv.tv_sec) << 32;
5062  sysidentifier |= ((uint64) tv.tv_usec) << 12;
5063  sysidentifier |= getpid() & 0xFFF;
5064 
5065  /* page buffer must be aligned suitably for O_DIRECT */
5066  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
5067  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
5068  memset(page, 0, XLOG_BLCKSZ);
5069 
5070  /*
5071  * Set up information for the initial checkpoint record
5072  *
5073  * The initial checkpoint record is written to the beginning of the WAL
5074  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5075  * used, so that we can use 0/0 to mean "before any valid WAL segment".
5076  */
5077  checkPoint.redo = wal_segment_size + SizeOfXLogLongPHD;
5078  checkPoint.ThisTimeLineID = BootstrapTimeLineID;
5079  checkPoint.PrevTimeLineID = BootstrapTimeLineID;
5080  checkPoint.fullPageWrites = fullPageWrites;
5081  checkPoint.wal_level = wal_level;
5082  checkPoint.nextXid =
5084  checkPoint.nextOid = FirstGenbkiObjectId;
5085  checkPoint.nextMulti = FirstMultiXactId;
5086  checkPoint.nextMultiOffset = 0;
5087  checkPoint.oldestXid = FirstNormalTransactionId;
5088  checkPoint.oldestXidDB = Template1DbOid;
5089  checkPoint.oldestMulti = FirstMultiXactId;
5090  checkPoint.oldestMultiDB = Template1DbOid;
5093  checkPoint.time = (pg_time_t) time(NULL);
5095 
5096  TransamVariables->nextXid = checkPoint.nextXid;
5097  TransamVariables->nextOid = checkPoint.nextOid;
5099  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5100  AdvanceOldestClogXid(checkPoint.oldestXid);
5101  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5102  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5104 
5105  /* Set up the XLOG page header */
5106  page->xlp_magic = XLOG_PAGE_MAGIC;
5107  page->xlp_info = XLP_LONG_HEADER;
5108  page->xlp_tli = BootstrapTimeLineID;
5110  longpage = (XLogLongPageHeader) page;
5111  longpage->xlp_sysid = sysidentifier;
5112  longpage->xlp_seg_size = wal_segment_size;
5113  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5114 
5115  /* Insert the initial checkpoint record */
5116  recptr = ((char *) page + SizeOfXLogLongPHD);
5117  record = (XLogRecord *) recptr;
5118  record->xl_prev = 0;
5119  record->xl_xid = InvalidTransactionId;
5120  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5122  record->xl_rmid = RM_XLOG_ID;
5123  recptr += SizeOfXLogRecord;
5124  /* fill the XLogRecordDataHeaderShort struct */
5125  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5126  *(recptr++) = sizeof(checkPoint);
5127  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5128  recptr += sizeof(checkPoint);
5129  Assert(recptr - (char *) record == record->xl_tot_len);
5130 
5131  INIT_CRC32C(crc);
5132  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5133  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5134  FIN_CRC32C(crc);
5135  record->xl_crc = crc;
5136 
5137  /* Create first XLOG segment file */
5140 
5141  /*
5142  * We needn't bother with Reserve/ReleaseExternalFD here, since we'll
5143  * close the file again in a moment.
5144  */
5145 
5146  /* Write the first page with the initial record */
5147  errno = 0;
5148  pgstat_report_wait_start(WAIT_EVENT_WAL_BOOTSTRAP_WRITE);
5149  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5150  {
5151  /* if write didn't set errno, assume problem is no disk space */
5152  if (errno == 0)
5153  errno = ENOSPC;
5154  ereport(PANIC,
5156  errmsg("could not write bootstrap write-ahead log file: %m")));
5157  }
5159 
5160  pgstat_report_wait_start(WAIT_EVENT_WAL_BOOTSTRAP_SYNC);
5161  if (pg_fsync(openLogFile) != 0)
5162  ereport(PANIC,
5164  errmsg("could not fsync bootstrap write-ahead log file: %m")));
5166 
5167  if (close(openLogFile) != 0)
5168  ereport(PANIC,
5170  errmsg("could not close bootstrap write-ahead log file: %m")));
5171 
5172  openLogFile = -1;
5173 
5174  /* Now create pg_control */
5175  InitControlFile(sysidentifier, data_checksum_version);
5176  ControlFile->time = checkPoint.time;
5177  ControlFile->checkPoint = checkPoint.redo;
5178  ControlFile->checkPointCopy = checkPoint;
5179 
5180  /* some additional ControlFile fields are set in WriteControlFile() */
5181  WriteControlFile();
5182 
5183  /* Bootstrap the commit log, too */
5184  BootStrapCLOG();
5188 
5189  pfree(buffer);
5190 
5191  /*
5192  * Force control file to be read - in contrast to normal processing we'd
5193  * otherwise never run the checks and GUC related initializations therein.
5194  */
5195  ReadControlFile();
5196 }
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:758
uint64_t uint64
Definition: c.h:486
void BootStrapCLOG(void)
Definition: clog.c:833
void BootStrapCommitTs(void)
Definition: commit_ts.c:596
void SetCommitTsLimit(TransactionId oldestXact, TransactionId newestXact)
Definition: commit_ts.c:909
#define close(a)
Definition: win32.h:12
#define write(a, b, c)
Definition: win32.h:14
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc(Size size)
Definition: mcxt.c:1317
void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset)
Definition: multixact.c:2328
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
Definition: multixact.c:2362
void BootStrapMultiXact(void)
Definition: multixact.c:2034
#define FirstMultiXactId
Definition: multixact.h:25
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:68
uint32 pg_crc32c
Definition: pg_crc32c.h:38
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:98
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:103
return crc
int64 pg_time_t
Definition: pgtime.h:23
Oid oldestMultiDB
Definition: pg_control.h:51
MultiXactId oldestMulti
Definition: pg_control.h:50
MultiXactOffset nextMultiOffset
Definition: pg_control.h:47
TransactionId newestCommitTsXid
Definition: pg_control.h:55
TransactionId oldestXid
Definition: pg_control.h:48
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
Oid nextOid
Definition: pg_control.h:45
TransactionId oldestActiveXid
Definition: pg_control.h:64
bool fullPageWrites
Definition: pg_control.h:42
MultiXactId nextMulti
Definition: pg_control.h:46
FullTransactionId nextXid
Definition: pg_control.h:44
TransactionId oldestCommitTsXid
Definition: pg_control.h:53
pg_time_t time
Definition: pg_control.h:52
int wal_level
Definition: pg_control.h:43
XLogRecPtr redo
Definition: pg_control.h:37
Oid oldestXidDB
Definition: pg_control.h:49
CheckPoint checkPointCopy
Definition: pg_control.h:135
pg_time_t time
Definition: pg_control.h:132
XLogRecPtr checkPoint
Definition: pg_control.h:133
FullTransactionId nextXid
Definition: transam.h:220
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
uint8 xl_info
Definition: xlogrecord.h:46
uint32 xl_tot_len
Definition: xlogrecord.h:43
TransactionId xl_xid
Definition: xlogrecord.h:44
RmgrId xl_rmid
Definition: xlogrecord.h:47
void BootStrapSUBTRANS(void)
Definition: subtrans.c:270
#define InvalidTransactionId
Definition: transam.h:31
#define FirstGenbkiObjectId
Definition: transam.h:195
#define FirstNormalTransactionId
Definition: transam.h:34
static FullTransactionId FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
Definition: transam.h:71
void SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid)
Definition: varsup.c:372
void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid)
Definition: varsup.c:355
TransamVariablesData * TransamVariables
Definition: varsup.c:34
int gettimeofday(struct timeval *tp, void *tzp)
int XLogFileInit(XLogSegNo logsegno, TimeLineID logtli)
Definition: xlog.c:3380
bool fullPageWrites
Definition: xlog.c:122
static void InitControlFile(uint64 sysidentifier, uint32 data_checksum_version)
Definition: xlog.c:4204
void SetInstallXLogFileSegmentActive(void)
Definition: xlog.c:9484
int wal_level
Definition: xlog.c:131
static void WriteControlFile(void)
Definition: xlog.c:4239
#define BootstrapTimeLineID
Definition: xlog.c:111
static void ReadControlFile(void)
Definition: xlog.c:4321
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:69
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:217
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:241
#define SizeOfXLogRecord
Definition: xlogrecord.h:55

References AdvanceOldestClogXid(), Assert, BootStrapCLOG(), BootStrapCommitTs(), BootStrapMultiXact(), BootStrapSUBTRANS(), BootstrapTimeLineID, ControlFileData::checkPoint, ControlFileData::checkPointCopy, close, COMP_CRC32C, ControlFile, crc, ereport, errcode_for_file_access(), errmsg(), FIN_CRC32C, FirstGenbkiObjectId, FirstMultiXactId, FirstNormalTransactionId, fullPageWrites, CheckPoint::fullPageWrites, FullTransactionIdFromEpochAndXid(), gettimeofday(), INIT_CRC32C, InitControlFile(), InvalidTransactionId, MultiXactSetNextMXact(), CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, TransamVariablesData::nextOid, CheckPoint::nextOid, TransamVariablesData::nextXid, CheckPoint::nextXid, TransamVariablesData::oidCount, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, openLogFile, openLogTLI, palloc(), PANIC, pfree(), pg_fsync(), pgstat_report_wait_end(), pgstat_report_wait_start(), CheckPoint::PrevTimeLineID, ReadControlFile(), CheckPoint::redo, SetCommitTsLimit(), SetInstallXLogFileSegmentActive(), SetMultiXactIdLimit(), SetTransactionIdLimit(), SizeOfXLogLongPHD, SizeOfXLogRecord, SizeOfXLogRecordDataHeaderShort, CheckPoint::ThisTimeLineID, CheckPoint::time, ControlFileData::time, TransamVariables, TYPEALIGN, wal_level, CheckPoint::wal_level, wal_segment_size, write, WriteControlFile(), XLogRecord::xl_crc, XLogRecord::xl_info, XLogRecord::xl_prev, XLogRecord::xl_rmid, XLogRecord::xl_tot_len, XLogRecord::xl_xid, XLOG_CHECKPOINT_SHUTDOWN, XLOG_PAGE_MAGIC, XLogFileInit(), XLogPageHeaderData::xlp_info, XLP_LONG_HEADER, XLogPageHeaderData::xlp_magic, XLogPageHeaderData::xlp_pageaddr, XLogLongPageHeaderData::xlp_seg_size, XLogLongPageHeaderData::xlp_sysid, XLogPageHeaderData::xlp_tli, XLogLongPageHeaderData::xlp_xlog_blcksz, and XLR_BLOCK_ID_DATA_SHORT.

Referenced by BootstrapModeMain().

◆ CalculateCheckpointSegments()

static void CalculateCheckpointSegments ( void  )
static

Definition at line 2162 of file xlog.c.

2163 {
2164  double target;
2165 
2166  /*-------
2167  * Calculate the distance at which to trigger a checkpoint, to avoid
2168  * exceeding max_wal_size_mb. This is based on two assumptions:
2169  *
2170  * a) we keep WAL for only one checkpoint cycle (prior to PG11 we kept
2171  * WAL for two checkpoint cycles to allow us to recover from the
2172  * secondary checkpoint if the first checkpoint failed, though we
2173  * only did this on the primary anyway, not on standby. Keeping just
2174  * one checkpoint simplifies processing and reduces disk space in
2175  * many smaller databases.)
2176  * b) during checkpoint, we consume checkpoint_completion_target *
2177  * number of segments consumed between checkpoints.
2178  *-------
2179  */
2180  target = (double) ConvertToXSegs(max_wal_size_mb, wal_segment_size) /
2182 
2183  /* round down */
2184  CheckPointSegments = (int) target;
2185 
2186  if (CheckPointSegments < 1)
2187  CheckPointSegments = 1;
2188 }
#define ConvertToXSegs(x, segsize)
Definition: xlog.c:603
int CheckPointSegments
Definition: xlog.c:156

References CheckPointCompletionTarget, CheckPointSegments, ConvertToXSegs, max_wal_size_mb, and wal_segment_size.

Referenced by assign_checkpoint_completion_target(), assign_max_wal_size(), and ReadControlFile().

◆ check_max_slot_wal_keep_size()

bool check_max_slot_wal_keep_size ( int *  newval,
void **  extra,
GucSource  source 
)

Definition at line 2223 of file xlog.c.

2224 {
2225  if (IsBinaryUpgrade && *newval != -1)
2226  {
2227  GUC_check_errdetail("\"%s\" must be set to -1 during binary upgrade mode.",
2228  "max_slot_wal_keep_size");
2229  return false;
2230  }
2231 
2232  return true;
2233 }
bool IsBinaryUpgrade
Definition: globals.c:120
#define GUC_check_errdetail
Definition: guc.h:476

References GUC_check_errdetail, IsBinaryUpgrade, and newval.

◆ check_wal_buffers()

bool check_wal_buffers ( int *  newval,
void **  extra,
GucSource  source 
)

Definition at line 4637 of file xlog.c.

4638 {
4639  /*
4640  * -1 indicates a request for auto-tune.
4641  */
4642  if (*newval == -1)
4643  {
4644  /*
4645  * If we haven't yet changed the boot_val default of -1, just let it
4646  * be. We'll fix it when XLOGShmemSize is called.
4647  */
4648  if (XLOGbuffers == -1)
4649  return true;
4650 
4651  /* Otherwise, substitute the auto-tune value */
4653  }
4654 
4655  /*
4656  * We clamp manually-set values to at least 4 blocks. Prior to PostgreSQL
4657  * 9.1, a minimum of 4 was enforced by guc.c, but since that is no longer
4658  * the case, we just silently treat such values as a request for the
4659  * minimum. (We could throw an error instead, but that doesn't seem very
4660  * helpful.)
4661  */
4662  if (*newval < 4)
4663  *newval = 4;
4664 
4665  return true;
4666 }
static int XLOGChooseNumBuffers(void)
Definition: xlog.c:4621
int XLOGbuffers
Definition: xlog.c:117

References newval, XLOGbuffers, and XLOGChooseNumBuffers().

◆ check_wal_consistency_checking()

bool check_wal_consistency_checking ( char **  newval,
void **  extra,
GucSource  source 
)

Definition at line 4672 of file xlog.c.

4673 {
4674  char *rawstring;
4675  List *elemlist;
4676  ListCell *l;
4677  bool newwalconsistency[RM_MAX_ID + 1];
4678 
4679  /* Initialize the array */
4680  MemSet(newwalconsistency, 0, (RM_MAX_ID + 1) * sizeof(bool));
4681 
4682  /* Need a modifiable copy of string */
4683  rawstring = pstrdup(*newval);
4684 
4685  /* Parse string into list of identifiers */
4686  if (!SplitIdentifierString(rawstring, ',', &elemlist))
4687  {
4688  /* syntax error in list */
4689  GUC_check_errdetail("List syntax is invalid.");
4690  pfree(rawstring);
4691  list_free(elemlist);
4692  return false;
4693  }
4694 
4695  foreach(l, elemlist)
4696  {
4697  char *tok = (char *) lfirst(l);
4698  int rmid;
4699 
4700  /* Check for 'all'. */
4701  if (pg_strcasecmp(tok, "all") == 0)
4702  {
4703  for (rmid = 0; rmid <= RM_MAX_ID; rmid++)
4704  if (RmgrIdExists(rmid) && GetRmgr(rmid).rm_mask != NULL)
4705  newwalconsistency[rmid] = true;
4706  }
4707  else
4708  {
4709  /* Check if the token matches any known resource manager. */
4710  bool found = false;
4711 
4712  for (rmid = 0; rmid <= RM_MAX_ID; rmid++)
4713  {
4714  if (RmgrIdExists(rmid) && GetRmgr(rmid).rm_mask != NULL &&
4715  pg_strcasecmp(tok, GetRmgr(rmid).rm_name) == 0)
4716  {
4717  newwalconsistency[rmid] = true;
4718  found = true;
4719  break;
4720  }
4721  }
4722  if (!found)
4723  {
4724  /*
4725  * During startup, it might be a not-yet-loaded custom
4726  * resource manager. Defer checking until
4727  * InitializeWalConsistencyChecking().
4728  */
4730  {
4732  }
4733  else
4734  {
4735  GUC_check_errdetail("Unrecognized key word: \"%s\".", tok);
4736  pfree(rawstring);
4737  list_free(elemlist);
4738  return false;
4739  }
4740  }
4741  }
4742  }
4743 
4744  pfree(rawstring);
4745  list_free(elemlist);
4746 
4747  /* assign new value */
4748  *extra = guc_malloc(ERROR, (RM_MAX_ID + 1) * sizeof(bool));
4749  memcpy(*extra, newwalconsistency, (RM_MAX_ID + 1) * sizeof(bool));
4750  return true;
4751 }
#define ERROR
Definition: elog.h:39
void * guc_malloc(int elevel, size_t size)
Definition: guc.c:638
void list_free(List *list)
Definition: list.c:1546
char * pstrdup(const char *in)
Definition: mcxt.c:1696
bool process_shared_preload_libraries_done
Definition: miscinit.c:1840
#define lfirst(lc)
Definition: pg_list.h:172
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
#define RM_MAX_ID
Definition: rmgr.h:33
Definition: pg_list.h:54
void(* rm_mask)(char *pagedata, BlockNumber blkno)
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3432
static bool check_wal_consistency_checking_deferred
Definition: xlog.c:166
static RmgrData GetRmgr(RmgrId rmid)
static bool RmgrIdExists(RmgrId rmid)

References check_wal_consistency_checking_deferred, ERROR, GetRmgr(), GUC_check_errdetail, guc_malloc(), lfirst, list_free(), MemSet, newval, pfree(), pg_strcasecmp(), process_shared_preload_libraries_done, pstrdup(), RmgrData::rm_mask, RM_MAX_ID, RmgrIdExists(), and SplitIdentifierString().

◆ check_wal_segment_size()

bool check_wal_segment_size ( int *  newval,
void **  extra,
GucSource  source 
)

Definition at line 2205 of file xlog.c.

2206 {
2207  if (!IsValidWalSegSize(*newval))
2208  {
2209  GUC_check_errdetail("The WAL segment size must be a power of two between 1 MB and 1 GB.");
2210  return false;
2211  }
2212 
2213  return true;
2214 }
#define IsValidWalSegSize(size)
Definition: xlog_internal.h:96

References GUC_check_errdetail, IsValidWalSegSize, and newval.

◆ CheckPointGuts()

static void CheckPointGuts ( XLogRecPtr  checkPointRedo,
int  flags 
)
static

Definition at line 7510 of file xlog.c.

7511 {
7517 
7518  /* Write out all dirty data in SLRUs and the main buffer pool */
7519  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_START(flags);
7521  CheckPointCLOG();
7526  CheckPointBuffers(flags);
7527 
7528  /* Perform all queued up fsyncs */
7529  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_SYNC_START();
7533  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_DONE();
7534 
7535  /* We deliberately delay 2PC checkpointing as long as possible */
7536  CheckPointTwoPhase(checkPointRedo);
7537 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1644
void CheckPointBuffers(int flags)
Definition: bufmgr.c:3710
void CheckPointCLOG(void)
Definition: clog.c:937
void CheckPointCommitTs(void)
Definition: commit_ts.c:820
void CheckPointMultiXact(void)
Definition: multixact.c:2304
void CheckPointReplicationOrigin(void)
Definition: origin.c:577
void CheckPointPredicate(void)
Definition: predicate.c:1041
void CheckPointRelationMap(void)
Definition: relmapper.c:611
void CheckPointLogicalRewriteHeap(void)
Definition: rewriteheap.c:1155
void CheckPointReplicationSlots(bool is_shutdown)
Definition: slot.c:1867
void CheckPointSnapBuild(void)
Definition: snapbuild.c:1922
TimestampTz ckpt_write_t
Definition: xlog.h:162
TimestampTz ckpt_sync_end_t
Definition: xlog.h:164
TimestampTz ckpt_sync_t
Definition: xlog.h:163
void CheckPointSUBTRANS(void)
Definition: subtrans.c:355
void ProcessSyncRequests(void)
Definition: sync.c:286
void CheckPointTwoPhase(XLogRecPtr redo_horizon)
Definition: twophase.c:1822
CheckpointStatsData CheckpointStats
Definition: xlog.c:209
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:139

References CHECKPOINT_IS_SHUTDOWN, CheckPointBuffers(), CheckPointCLOG(), CheckPointCommitTs(), CheckPointLogicalRewriteHeap(), CheckPointMultiXact(), CheckPointPredicate(), CheckPointRelationMap(), CheckPointReplicationOrigin(), CheckPointReplicationSlots(), CheckPointSnapBuild(), CheckpointStats, CheckPointSUBTRANS(), CheckPointTwoPhase(), CheckpointStatsData::ckpt_sync_end_t, CheckpointStatsData::ckpt_sync_t, CheckpointStatsData::ckpt_write_t, GetCurrentTimestamp(), and ProcessSyncRequests().

Referenced by CreateCheckPoint(), and CreateRestartPoint().

◆ CheckRequiredParameterValues()

static void CheckRequiredParameterValues ( void  )
static

Definition at line 5385 of file xlog.c.

5386 {
5387  /*
5388  * For archive recovery, the WAL must be generated with at least 'replica'
5389  * wal_level.
5390  */
5392  {
5393  ereport(FATAL,
5394  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
5395  errmsg("WAL was generated with \"wal_level=minimal\", cannot continue recovering"),
5396  errdetail("This happens if you temporarily set \"wal_level=minimal\" on the server."),
5397  errhint("Use a backup taken after setting \"wal_level\" to higher than \"minimal\".")));
5398  }
5399 
5400  /*
5401  * For Hot Standby, the WAL must be generated with 'replica' mode, and we
5402  * must have at least as many backend slots as the primary.
5403  */
5405  {
5406  /* We ignore autovacuum_max_workers when we make this test. */
5407  RecoveryRequiresIntParameter("max_connections",
5410  RecoveryRequiresIntParameter("max_worker_processes",
5413  RecoveryRequiresIntParameter("max_wal_senders",
5416  RecoveryRequiresIntParameter("max_prepared_transactions",
5419  RecoveryRequiresIntParameter("max_locks_per_transaction",
5422  }
5423 }
int errdetail(const char *fmt,...)
Definition: elog.c:1203
int errhint(const char *fmt,...)
Definition: elog.c:1317
int errcode(int sqlerrcode)
Definition: elog.c:853
#define FATAL
Definition: elog.h:41
int MaxConnections
Definition: globals.c:142
int max_worker_processes
Definition: globals.c:143
int max_locks_per_xact
Definition: lock.c:52
int max_worker_processes
Definition: pg_control.h:181
int max_locks_per_xact
Definition: pg_control.h:184
int max_prepared_xacts
Definition: pg_control.h:183
int max_prepared_xacts
Definition: twophase.c:115
int max_wal_senders
Definition: walsender.c:121
bool EnableHotStandby
Definition: xlog.c:121
@ WAL_LEVEL_MINIMAL
Definition: xlog.h:74
bool ArchiveRecoveryRequested
Definition: xlogrecovery.c:137
void RecoveryRequiresIntParameter(const char *param_name, int currValue, int minValue)

References ArchiveRecoveryRequested, ControlFile, EnableHotStandby, ereport, errcode(), errdetail(), errhint(), errmsg(), FATAL, max_locks_per_xact, ControlFileData::max_locks_per_xact, max_prepared_xacts, ControlFileData::max_prepared_xacts, max_wal_senders, ControlFileData::max_wal_senders, max_worker_processes, ControlFileData::max_worker_processes, MaxConnections, ControlFileData::MaxConnections, RecoveryRequiresIntParameter(), ControlFileData::wal_level, and WAL_LEVEL_MINIMAL.

Referenced by StartupXLOG(), and xlog_redo().

◆ CheckXLogRemoved()

void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)

Definition at line 3727 of file xlog.c.

3728 {
3729  int save_errno = errno;
3730  XLogSegNo lastRemovedSegNo;
3731 
3733  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3735 
3736  if (segno <= lastRemovedSegNo)
3737  {
3738  char filename[MAXFNAMELEN];
3739 
3740  XLogFileName(filename, tli, segno, wal_segment_size);
3741  errno = save_errno;
3742  ereport(ERROR,
3744  errmsg("requested WAL segment %s has already been removed",
3745  filename)));
3746  }
3747  errno = save_errno;
3748 }
static char * filename
Definition: pg_dumpall.c:119
XLogSegNo lastRemovedSegNo
Definition: xlog.c:461
uint64 XLogSegNo
Definition: xlogdefs.h:48

References ereport, errcode_for_file_access(), errmsg(), ERROR, filename, XLogCtlData::info_lck, XLogCtlData::lastRemovedSegNo, MAXFNAMELEN, SpinLockAcquire, SpinLockRelease, wal_segment_size, XLogCtl, and XLogFileName().

Referenced by logical_read_xlog_page(), perform_base_backup(), and XLogSendPhysical().

◆ CleanupAfterArchiveRecovery()

static void CleanupAfterArchiveRecovery ( TimeLineID  EndOfLogTLI,
XLogRecPtr  EndOfLog,
TimeLineID  newTLI 
)
static

Definition at line 5289 of file xlog.c.

5291 {
5292  /*
5293  * Execute the recovery_end_command, if any.
5294  */
5295  if (recoveryEndCommand && strcmp(recoveryEndCommand, "") != 0)
5297  "recovery_end_command",
5298  true,
5299  WAIT_EVENT_RECOVERY_END_COMMAND);
5300 
5301  /*
5302  * We switched to a new timeline. Clean up segments on the old timeline.
5303  *
5304  * If there are any higher-numbered segments on the old timeline, remove
5305  * them. They might contain valid WAL, but they might also be
5306  * pre-allocated files containing garbage. In any case, they are not part
5307  * of the new timeline's history so we don't need them.
5308  */
5309  RemoveNonParentXlogFiles(EndOfLog, newTLI);
5310 
5311  /*
5312  * If the switch happened in the middle of a segment, what to do with the
5313  * last, partial segment on the old timeline? If we don't archive it, and
5314  * the server that created the WAL never archives it either (e.g. because
5315  * it was hit by a meteor), it will never make it to the archive. That's
5316  * OK from our point of view, because the new segment that we created with
5317  * the new TLI contains all the WAL from the old timeline up to the switch
5318  * point. But if you later try to do PITR to the "missing" WAL on the old
5319  * timeline, recovery won't find it in the archive. It's physically
5320  * present in the new file with new TLI, but recovery won't look there
5321  * when it's recovering to the older timeline. On the other hand, if we
5322  * archive the partial segment, and the original server on that timeline
5323  * is still running and archives the completed version of the same segment
5324  * later, it will fail. (We used to do that in 9.4 and below, and it
5325  * caused such problems).
5326  *
5327  * As a compromise, we rename the last segment with the .partial suffix,
5328  * and archive it. Archive recovery will never try to read .partial
5329  * segments, so they will normally go unused. But in the odd PITR case,
5330  * the administrator can copy them manually to the pg_wal directory
5331  * (removing the suffix). They can be useful in debugging, too.
5332  *
5333  * If a .done or .ready file already exists for the old timeline, however,
5334  * we had already determined that the segment is complete, so we can let
5335  * it be archived normally. (In particular, if it was restored from the
5336  * archive to begin with, it's expected to have a .done file).
5337  */
5338  if (XLogSegmentOffset(EndOfLog, wal_segment_size) != 0 &&
5340  {
5341  char origfname[MAXFNAMELEN];
5342  XLogSegNo endLogSegNo;
5343 
5344  XLByteToPrevSeg(EndOfLog, endLogSegNo, wal_segment_size);
5345  XLogFileName(origfname, EndOfLogTLI, endLogSegNo, wal_segment_size);
5346 
5347  if (!XLogArchiveIsReadyOrDone(origfname))
5348  {
5349  char origpath[MAXPGPATH];
5350  char partialfname[MAXFNAMELEN];
5351  char partialpath[MAXPGPATH];
5352 
5353  /*
5354  * If we're summarizing WAL, we can't rename the partial file
5355  * until the summarizer finishes with it, else it will fail.
5356  */
5357  if (summarize_wal)
5358  WaitForWalSummarization(EndOfLog);
5359 
5360  XLogFilePath(origpath, EndOfLogTLI, endLogSegNo, wal_segment_size);
5361  snprintf(partialfname, MAXFNAMELEN, "%s.partial", origfname);
5362  snprintf(partialpath, MAXPGPATH, "%s.partial", origpath);
5363 
5364  /*
5365  * Make sure there's no .done or .ready file for the .partial
5366  * file.
5367  */
5368  XLogArchiveCleanup(partialfname);
5369 
5370  durable_rename(origpath, partialpath, ERROR);
5371  XLogArchiveNotify(partialfname);
5372  }
5373  }
5374 }
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:781
#define MAXPGPATH
#define snprintf
Definition: port.h:238
bool summarize_wal
void WaitForWalSummarization(XLogRecPtr lsn)
void RemoveNonParentXlogFiles(XLogRecPtr switchpoint, TimeLineID newTLI)
Definition: xlog.c:3940
#define XLogArchivingActive()
Definition: xlog.h:99
#define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes)
static void XLogFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
bool XLogArchiveIsReadyOrDone(const char *xlog)
Definition: xlogarchive.c:664
void ExecuteRecoveryCommand(const char *command, const char *commandName, bool failOnSignal, uint32 wait_event_info)
Definition: xlogarchive.c:295
void XLogArchiveNotify(const char *xlog)
Definition: xlogarchive.c:444
void XLogArchiveCleanup(const char *xlog)
Definition: xlogarchive.c:712
char * recoveryEndCommand
Definition: xlogrecovery.c:83

References durable_rename(), ERROR, ExecuteRecoveryCommand(), MAXFNAMELEN, MAXPGPATH, recoveryEndCommand, RemoveNonParentXlogFiles(), snprintf, summarize_wal, WaitForWalSummarization(), wal_segment_size, XLByteToPrevSeg, XLogArchiveCleanup(), XLogArchiveIsReadyOrDone(), XLogArchiveNotify(), XLogArchivingActive, XLogFileName(), XLogFilePath(), and XLogSegmentOffset.

Referenced by StartupXLOG().

◆ CleanupBackupHistory()

static void CleanupBackupHistory ( void  )
static

Definition at line 4161 of file xlog.c.

4162 {
4163  DIR *xldir;
4164  struct dirent *xlde;
4165  char path[MAXPGPATH + sizeof(XLOGDIR)];
4166 
4167  xldir = AllocateDir(XLOGDIR);
4168 
4169  while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
4170  {
4171  if (IsBackupHistoryFileName(xlde->d_name))
4172  {
4173  if (XLogArchiveCheckDone(xlde->d_name))
4174  {
4175  elog(DEBUG2, "removing WAL backup history file \"%s\"",
4176  xlde->d_name);
4177  snprintf(path, sizeof(path), XLOGDIR "/%s", xlde->d_name);
4178  unlink(path);
4179  XLogArchiveCleanup(xlde->d_name);
4180  }
4181  }
4182  }
4183 
4184  FreeDir(xldir);
4185 }
#define DEBUG2
Definition: elog.h:29
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2931
int FreeDir(DIR *dir)
Definition: fd.c:2983
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2865
Definition: dirent.c:26
Definition: dirent.h:10
char d_name[MAX_PATH]
Definition: dirent.h:15
#define XLOGDIR
static bool IsBackupHistoryFileName(const char *fname)
bool XLogArchiveCheckDone(const char *xlog)
Definition: xlogarchive.c:565

References AllocateDir(), dirent::d_name, DEBUG2, elog, FreeDir(), IsBackupHistoryFileName(), MAXPGPATH, ReadDir(), snprintf, XLogArchiveCheckDone(), XLogArchiveCleanup(), and XLOGDIR.

Referenced by do_pg_backup_stop().

◆ CopyXLogRecordToWAL()

static void CopyXLogRecordToWAL ( int  write_len,
bool  isLogSwitch,
XLogRecData rdata,
XLogRecPtr  StartPos,
XLogRecPtr  EndPos,
TimeLineID  tli 
)
static

Definition at line 1225 of file xlog.c.

1227 {
1228  char *currpos;
1229  int freespace;
1230  int written;
1231  XLogRecPtr CurrPos;
1232  XLogPageHeader pagehdr;
1233 
1234  /*
1235  * Get a pointer to the right place in the right WAL buffer to start
1236  * inserting to.
1237  */
1238  CurrPos = StartPos;
1239  currpos = GetXLogBuffer(CurrPos, tli);
1240  freespace = INSERT_FREESPACE(CurrPos);
1241 
1242  /*
1243  * there should be enough space for at least the first field (xl_tot_len)
1244  * on this page.
1245  */
1246  Assert(freespace >= sizeof(uint32));
1247 
1248  /* Copy record data */
1249  written = 0;
1250  while (rdata != NULL)
1251  {
1252  const char *rdata_data = rdata->data;
1253  int rdata_len = rdata->len;
1254 
1255  while (rdata_len > freespace)
1256  {
1257  /*
1258  * Write what fits on this page, and continue on the next page.
1259  */
1260  Assert(CurrPos % XLOG_BLCKSZ >= SizeOfXLogShortPHD || freespace == 0);
1261  memcpy(currpos, rdata_data, freespace);
1262  rdata_data += freespace;
1263  rdata_len -= freespace;
1264  written += freespace;
1265  CurrPos += freespace;
1266 
1267  /*
1268  * Get pointer to beginning of next page, and set the xlp_rem_len
1269  * in the page header. Set XLP_FIRST_IS_CONTRECORD.
1270  *
1271  * It's safe to set the contrecord flag and xlp_rem_len without a
1272  * lock on the page. All the other flags were already set when the
1273  * page was initialized, in AdvanceXLInsertBuffer, and we're the
1274  * only backend that needs to set the contrecord flag.
1275  */
1276  currpos = GetXLogBuffer(CurrPos, tli);
1277  pagehdr = (XLogPageHeader) currpos;
1278  pagehdr->xlp_rem_len = write_len - written;
1279  pagehdr->xlp_info |= XLP_FIRST_IS_CONTRECORD;
1280 
1281  /* skip over the page header */
1282  if (XLogSegmentOffset(CurrPos, wal_segment_size) == 0)
1283  {
1284  CurrPos += SizeOfXLogLongPHD;
1285  currpos += SizeOfXLogLongPHD;
1286  }
1287  else
1288  {
1289  CurrPos += SizeOfXLogShortPHD;
1290  currpos += SizeOfXLogShortPHD;
1291  }
1292  freespace = INSERT_FREESPACE(CurrPos);
1293  }
1294 
1295  Assert(CurrPos % XLOG_BLCKSZ >= SizeOfXLogShortPHD || rdata_len == 0);
1296  memcpy(currpos, rdata_data, rdata_len);
1297  currpos += rdata_len;
1298  CurrPos += rdata_len;
1299  freespace -= rdata_len;
1300  written += rdata_len;
1301 
1302  rdata = rdata->next;
1303  }
1304  Assert(written == write_len);
1305 
1306  /*
1307  * If this was an xlog-switch, it's not enough to write the switch record,
1308  * we also have to consume all the remaining space in the WAL segment. We
1309  * have already reserved that space, but we need to actually fill it.
1310  */
1311  if (isLogSwitch && XLogSegmentOffset(CurrPos, wal_segment_size) != 0)
1312  {
1313  /* An xlog-switch record doesn't contain any data besides the header */
1314  Assert(write_len == SizeOfXLogRecord);
1315 
1316  /* Assert that we did reserve the right amount of space */
1317  Assert(XLogSegmentOffset(EndPos, wal_segment_size) == 0);
1318 
1319  /* Use up all the remaining space on the current page */
1320  CurrPos += freespace;
1321 
1322  /*
1323  * Cause all remaining pages in the segment to be flushed, leaving the
1324  * XLog position where it should be, at the start of the next segment.
1325  * We do this one page at a time, to make sure we don't deadlock
1326  * against ourselves if wal_buffers < wal_segment_size.
1327  */
1328  while (CurrPos < EndPos)
1329  {
1330  /*
1331  * The minimal action to flush the page would be to call
1332  * WALInsertLockUpdateInsertingAt(CurrPos) followed by
1333  * AdvanceXLInsertBuffer(...). The page would be left initialized
1334  * mostly to zeros, except for the page header (always the short
1335  * variant, as this is never a segment's first page).
1336  *
1337  * The large vistas of zeros are good for compressibility, but the
1338  * headers interrupting them every XLOG_BLCKSZ (with values that
1339  * differ from page to page) are not. The effect varies with
1340  * compression tool, but bzip2 for instance compresses about an
1341  * order of magnitude worse if those headers are left in place.
1342  *
1343  * Rather than complicating AdvanceXLInsertBuffer itself (which is
1344  * called in heavily-loaded circumstances as well as this lightly-
1345  * loaded one) with variant behavior, we just use GetXLogBuffer
1346  * (which itself calls the two methods we need) to get the pointer
1347  * and zero most of the page. Then we just zero the page header.
1348  */
1349  currpos = GetXLogBuffer(CurrPos, tli);
1350  MemSet(currpos, 0, SizeOfXLogShortPHD);
1351 
1352  CurrPos += XLOG_BLCKSZ;
1353  }
1354  }
1355  else
1356  {
1357  /* Align the end position, so that the next record starts aligned */
1358  CurrPos = MAXALIGN64(CurrPos);
1359  }
1360 
1361  if (CurrPos != EndPos)
1362  ereport(PANIC,
1364  errmsg_internal("space reserved for WAL record does not match what was written"));
1365 }
uint32_t uint32
Definition: c.h:485
#define MAXALIGN64(LEN)
Definition: c.h:790
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1157
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:41
const char * data
struct XLogRecData * next
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:580
static char * GetXLogBuffer(XLogRecPtr ptr, TimeLineID tli)
Definition: xlog.c:1632
#define XLP_FIRST_IS_CONTRECORD
Definition: xlog_internal.h:74
#define SizeOfXLogShortPHD
Definition: xlog_internal.h:52

References Assert, XLogRecData::data, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg_internal(), GetXLogBuffer(), INSERT_FREESPACE, XLogRecData::len, MAXALIGN64, MemSet, XLogRecData::next, PANIC, SizeOfXLogLongPHD, SizeOfXLogRecord, SizeOfXLogShortPHD, wal_segment_size, XLogSegmentOffset, XLP_FIRST_IS_CONTRECORD, XLogPageHeaderData::xlp_info, and XLogPageHeaderData::xlp_rem_len.

Referenced by XLogInsertRecord().

◆ CreateCheckPoint()

bool CreateCheckPoint ( int  flags)

Definition at line 6889 of file xlog.c.

6890 {
6891  bool shutdown;
6892  CheckPoint checkPoint;
6893  XLogRecPtr recptr;
6894  XLogSegNo _logSegNo;
6896  uint32 freespace;
6897  XLogRecPtr PriorRedoPtr;
6898  XLogRecPtr last_important_lsn;
6899  VirtualTransactionId *vxids;
6900  int nvxids;
6901  int oldXLogAllowed = 0;
6902 
6903  /*
6904  * An end-of-recovery checkpoint is really a shutdown checkpoint, just
6905  * issued at a different time.
6906  */
6908  shutdown = true;
6909  else
6910  shutdown = false;
6911 
6912  /* sanity check */
6913  if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
6914  elog(ERROR, "can't create a checkpoint during recovery");
6915 
6916  /*
6917  * Prepare to accumulate statistics.
6918  *
6919  * Note: because it is possible for log_checkpoints to change while a
6920  * checkpoint proceeds, we always accumulate stats, even if
6921  * log_checkpoints is currently off.
6922  */
6923  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
6925 
6926  /*
6927  * Let smgr prepare for checkpoint; this has to happen outside the
6928  * critical section and before we determine the REDO pointer. Note that
6929  * smgr must not do anything that'd have to be undone if we decide no
6930  * checkpoint is needed.
6931  */
6933 
6934  /*
6935  * Use a critical section to force system panic if we have trouble.
6936  */
6938 
6939  if (shutdown)
6940  {
6941  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6944  LWLockRelease(ControlFileLock);
6945  }
6946 
6947  /* Begin filling in the checkpoint WAL record */
6948  MemSet(&checkPoint, 0, sizeof(checkPoint));
6949  checkPoint.time = (pg_time_t) time(NULL);
6950 
6951  /*
6952  * For Hot Standby, derive the oldestActiveXid before we fix the redo
6953  * pointer. This allows us to begin accumulating changes to assemble our
6954  * starting snapshot of locks and transactions.
6955  */
6956  if (!shutdown && XLogStandbyInfoActive())
6958  else
6960 
6961  /*
6962  * Get location of last important record before acquiring insert locks (as
6963  * GetLastImportantRecPtr() also locks WAL locks).
6964  */
6965  last_important_lsn = GetLastImportantRecPtr();
6966 
6967  /*
6968  * If this isn't a shutdown or forced checkpoint, and if there has been no
6969  * WAL activity requiring a checkpoint, skip it. The idea here is to
6970  * avoid inserting duplicate checkpoints when the system is idle.
6971  */
6973  CHECKPOINT_FORCE)) == 0)
6974  {
6975  if (last_important_lsn == ControlFile->checkPoint)
6976  {
6977  END_CRIT_SECTION();
6978  ereport(DEBUG1,
6979  (errmsg_internal("checkpoint skipped because system is idle")));
6980  return false;
6981  }
6982  }
6983 
6984  /*
6985  * An end-of-recovery checkpoint is created before anyone is allowed to
6986  * write WAL. To allow us to write the checkpoint record, temporarily
6987  * enable XLogInsertAllowed.
6988  */
6989  if (flags & CHECKPOINT_END_OF_RECOVERY)
6990  oldXLogAllowed = LocalSetXLogInsertAllowed();
6991 
6992  checkPoint.ThisTimeLineID = XLogCtl->InsertTimeLineID;
6993  if (flags & CHECKPOINT_END_OF_RECOVERY)
6994  checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
6995  else
6996  checkPoint.PrevTimeLineID = checkPoint.ThisTimeLineID;
6997 
6998  /*
6999  * We must block concurrent insertions while examining insert state.
7000  */
7002 
7003  checkPoint.fullPageWrites = Insert->fullPageWrites;
7004  checkPoint.wal_level = wal_level;
7005 
7006  if (shutdown)
7007  {
7008  XLogRecPtr curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
7009 
7010  /*
7011  * Compute new REDO record ptr = location of next XLOG record.
7012  *
7013  * Since this is a shutdown checkpoint, there can't be any concurrent
7014  * WAL insertion.
7015  */
7016  freespace = INSERT_FREESPACE(curInsert);
7017  if (freespace == 0)
7018  {
7019  if (XLogSegmentOffset(curInsert, wal_segment_size) == 0)
7020  curInsert += SizeOfXLogLongPHD;
7021  else
7022  curInsert += SizeOfXLogShortPHD;
7023  }
7024  checkPoint.redo = curInsert;
7025 
7026  /*
7027  * Here we update the shared RedoRecPtr for future XLogInsert calls;
7028  * this must be done while holding all the insertion locks.
7029  *
7030  * Note: if we fail to complete the checkpoint, RedoRecPtr will be
7031  * left pointing past where it really needs to point. This is okay;
7032  * the only consequence is that XLogInsert might back up whole buffers
7033  * that it didn't really need to. We can't postpone advancing
7034  * RedoRecPtr because XLogInserts that happen while we are dumping
7035  * buffers must assume that their buffer changes are not included in
7036  * the checkpoint.
7037  */
7038  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
7039  }
7040 
7041  /*
7042  * Now we can release the WAL insertion locks, allowing other xacts to
7043  * proceed while we are flushing disk buffers.
7044  */
7046 
7047  /*
7048  * If this is an online checkpoint, we have not yet determined the redo
7049  * point. We do so now by inserting the special XLOG_CHECKPOINT_REDO
7050  * record; the LSN at which it starts becomes the new redo pointer. We
7051  * don't do this for a shutdown checkpoint, because in that case no WAL
7052  * can be written between the redo point and the insertion of the
7053  * checkpoint record itself, so the checkpoint record itself serves to
7054  * mark the redo point.
7055  */
7056  if (!shutdown)
7057  {
7058  /* Include WAL level in record for WAL summarizer's benefit. */
7059  XLogBeginInsert();
7060  XLogRegisterData((char *) &wal_level, sizeof(wal_level));
7061  (void) XLogInsert(RM_XLOG_ID, XLOG_CHECKPOINT_REDO);
7062 
7063  /*
7064  * XLogInsertRecord will have updated XLogCtl->Insert.RedoRecPtr in
7065  * shared memory and RedoRecPtr in backend-local memory, but we need
7066  * to copy that into the record that will be inserted when the
7067  * checkpoint is complete.
7068  */
7069  checkPoint.redo = RedoRecPtr;
7070  }
7071 
7072  /* Update the info_lck-protected copy of RedoRecPtr as well */
7074  XLogCtl->RedoRecPtr = checkPoint.redo;
7076 
7077  /*
7078  * If enabled, log checkpoint start. We postpone this until now so as not
7079  * to log anything if we decided to skip the checkpoint.
7080  */
7081  if (log_checkpoints)
7082  LogCheckpointStart(flags, false);
7083 
7084  /* Update the process title */
7085  update_checkpoint_display(flags, false, false);
7086 
7087  TRACE_POSTGRESQL_CHECKPOINT_START(flags);
7088 
7089  /*
7090  * Get the other info we need for the checkpoint record.
7091  *
7092  * We don't need to save oldestClogXid in the checkpoint, it only matters
7093  * for the short period in which clog is being truncated, and if we crash
7094  * during that we'll redo the clog truncation and fix up oldestClogXid
7095  * there.
7096  */
7097  LWLockAcquire(XidGenLock, LW_SHARED);
7098  checkPoint.nextXid = TransamVariables->nextXid;
7099  checkPoint.oldestXid = TransamVariables->oldestXid;
7101  LWLockRelease(XidGenLock);
7102 
7103  LWLockAcquire(CommitTsLock, LW_SHARED);
7106  LWLockRelease(CommitTsLock);
7107 
7108  LWLockAcquire(OidGenLock, LW_SHARED);
7109  checkPoint.nextOid = TransamVariables->nextOid;
7110  if (!shutdown)
7111  checkPoint.nextOid += TransamVariables->oidCount;
7112  LWLockRelease(OidGenLock);
7113 
7114  MultiXactGetCheckptMulti(shutdown,
7115  &checkPoint.nextMulti,
7116  &checkPoint.nextMultiOffset,
7117  &checkPoint.oldestMulti,
7118  &checkPoint.oldestMultiDB);
7119 
7120  /*
7121  * Having constructed the checkpoint record, ensure all shmem disk buffers
7122  * and commit-log buffers are flushed to disk.
7123  *
7124  * This I/O could fail for various reasons. If so, we will fail to
7125  * complete the checkpoint, but there is no reason to force a system
7126  * panic. Accordingly, exit critical section while doing it.
7127  */
7128  END_CRIT_SECTION();
7129 
7130  /*
7131  * In some cases there are groups of actions that must all occur on one
7132  * side or the other of a checkpoint record. Before flushing the
7133  * checkpoint record we must explicitly wait for any backend currently
7134  * performing those groups of actions.
7135  *
7136  * One example is end of transaction, so we must wait for any transactions
7137  * that are currently in commit critical sections. If an xact inserted
7138  * its commit record into XLOG just before the REDO point, then a crash
7139  * restart from the REDO point would not replay that record, which means
7140  * that our flushing had better include the xact's update of pg_xact. So
7141  * we wait till he's out of his commit critical section before proceeding.
7142  * See notes in RecordTransactionCommit().
7143  *
7144  * Because we've already released the insertion locks, this test is a bit
7145  * fuzzy: it is possible that we will wait for xacts we didn't really need
7146  * to wait for. But the delay should be short and it seems better to make
7147  * checkpoint take a bit longer than to hold off insertions longer than
7148  * necessary. (In fact, the whole reason we have this issue is that xact.c
7149  * does commit record XLOG insertion and clog update as two separate steps
7150  * protected by different locks, but again that seems best on grounds of
7151  * minimizing lock contention.)
7152  *
7153  * A transaction that has not yet set delayChkptFlags when we look cannot
7154  * be at risk, since it has not inserted its commit record yet; and one
7155  * that's already cleared it is not at risk either, since it's done fixing
7156  * clog and we will correctly flush the update below. So we cannot miss
7157  * any xacts we need to wait for.
7158  */
7160  if (nvxids > 0)
7161  {
7162  do
7163  {
7164  /*
7165  * Keep absorbing fsync requests while we wait. There could even
7166  * be a deadlock if we don't, if the process that prevents the
7167  * checkpoint is trying to add a request to the queue.
7168  */
7170 
7171  pgstat_report_wait_start(WAIT_EVENT_CHECKPOINT_DELAY_START);
7172  pg_usleep(10000L); /* wait for 10 msec */
7174  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids,
7176  }
7177  pfree(vxids);
7178 
7179  CheckPointGuts(checkPoint.redo, flags);
7180 
7182  if (nvxids > 0)
7183  {
7184  do
7185  {
7187 
7188  pgstat_report_wait_start(WAIT_EVENT_CHECKPOINT_DELAY_COMPLETE);
7189  pg_usleep(10000L); /* wait for 10 msec */
7191  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids,
7193  }
7194  pfree(vxids);
7195 
7196  /*
7197  * Take a snapshot of running transactions and write this to WAL. This
7198  * allows us to reconstruct the state of running transactions during
7199  * archive recovery, if required. Skip, if this info disabled.
7200  *
7201  * If we are shutting down, or Startup process is completing crash
7202  * recovery we don't need to write running xact data.
7203  */
7204  if (!shutdown && XLogStandbyInfoActive())
7206 
7208 
7209  /*
7210  * Now insert the checkpoint record into XLOG.
7211  */
7212  XLogBeginInsert();
7213  XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));
7214  recptr = XLogInsert(RM_XLOG_ID,
7215  shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
7217 
7218  XLogFlush(recptr);
7219 
7220  /*
7221  * We mustn't write any new WAL after a shutdown checkpoint, or it will be
7222  * overwritten at next startup. No-one should even try, this just allows
7223  * sanity-checking. In the case of an end-of-recovery checkpoint, we want
7224  * to just temporarily disable writing until the system has exited
7225  * recovery.
7226  */
7227  if (shutdown)
7228  {
7229  if (flags & CHECKPOINT_END_OF_RECOVERY)
7230  LocalXLogInsertAllowed = oldXLogAllowed;
7231  else
7232  LocalXLogInsertAllowed = 0; /* never again write WAL */
7233  }
7234 
7235  /*
7236  * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
7237  * = end of actual checkpoint record.
7238  */
7239  if (shutdown && checkPoint.redo != ProcLastRecPtr)
7240  ereport(PANIC,
7241  (errmsg("concurrent write-ahead log activity while database system is shutting down")));
7242 
7243  /*
7244  * Remember the prior checkpoint's redo ptr for
7245  * UpdateCheckPointDistanceEstimate()
7246  */
7247  PriorRedoPtr = ControlFile->checkPointCopy.redo;
7248 
7249  /*
7250  * Update the control file.
7251  */
7252  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7253  if (shutdown)
7256  ControlFile->checkPointCopy = checkPoint;
7257  /* crash recovery should always recover to the end of WAL */
7260 
7261  /*
7262  * Persist unloggedLSN value. It's reset on crash recovery, so this goes
7263  * unused on non-shutdown checkpoints, but seems useful to store it always
7264  * for debugging purposes.
7265  */
7267 
7269  LWLockRelease(ControlFileLock);
7270 
7271  /* Update shared-memory copy of checkpoint XID/epoch */
7273  XLogCtl->ckptFullXid = checkPoint.nextXid;
7275 
7276  /*
7277  * We are now done with critical updates; no need for system panic if we
7278  * have trouble while fooling with old log segments.
7279  */
7280  END_CRIT_SECTION();
7281 
7282  /*
7283  * WAL summaries end when the next XLOG_CHECKPOINT_REDO or
7284  * XLOG_CHECKPOINT_SHUTDOWN record is reached. This is the first point
7285  * where (a) we're not inside of a critical section and (b) we can be
7286  * certain that the relevant record has been flushed to disk, which must
7287  * happen before it can be summarized.
7288  *
7289  * If this is a shutdown checkpoint, then this happens reasonably
7290  * promptly: we've only just inserted and flushed the
7291  * XLOG_CHECKPOINT_SHUTDOWN record. If this is not a shutdown checkpoint,
7292  * then this might not be very prompt at all: the XLOG_CHECKPOINT_REDO
7293  * record was written before we began flushing data to disk, and that
7294  * could be many minutes ago at this point. However, we don't XLogFlush()
7295  * after inserting that record, so we're not guaranteed that it's on disk
7296  * until after the above call that flushes the XLOG_CHECKPOINT_ONLINE
7297  * record.
7298  */
7300 
7301  /*
7302  * Let smgr do post-checkpoint cleanup (eg, deleting old files).
7303  */
7305 
7306  /*
7307  * Update the average distance between checkpoints if the prior checkpoint
7308  * exists.
7309  */
7310  if (PriorRedoPtr != InvalidXLogRecPtr)
7312 
7313  /*
7314  * Delete old log files, those no longer needed for last checkpoint to
7315  * prevent the disk holding the xlog from growing full.
7316  */
7318  KeepLogSeg(recptr, &_logSegNo);
7320  _logSegNo, InvalidOid,
7322  {
7323  /*
7324  * Some slots have been invalidated; recalculate the old-segment
7325  * horizon, starting again from RedoRecPtr.
7326  */
7328  KeepLogSeg(recptr, &_logSegNo);
7329  }
7330  _logSegNo--;
7331  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr,
7332  checkPoint.ThisTimeLineID);
7333 
7334  /*
7335  * Make more log segments if needed. (Do this after recycling old log
7336  * segments, since that may supply some of the needed files.)
7337  */
7338  if (!shutdown)
7339  PreallocXlogFiles(recptr, checkPoint.ThisTimeLineID);
7340 
7341  /*
7342  * Truncate pg_subtrans if possible. We can throw away all data before
7343  * the oldest XMIN of any running transaction. No future transaction will
7344  * attempt to reference any pg_subtrans entry older than that (see Asserts
7345  * in subtrans.c). During recovery, though, we mustn't do this because
7346  * StartupSUBTRANS hasn't been called yet.
7347  */
7348  if (!RecoveryInProgress())
7350 
7351  /* Real work is done; log and update stats. */
7352  LogCheckpointEnd(false);
7353 
7354  /* Reset the process title */
7355  update_checkpoint_display(flags, false, true);
7356 
7357  TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
7358  NBuffers,
7362 
7363  return true;
7364 }
static uint64 pg_atomic_read_membarrier_u64(volatile pg_atomic_uint64 *ptr)
Definition: atomics.h:476
void AbsorbSyncRequests(void)
int NBuffers
Definition: globals.c:141
@ LW_SHARED
Definition: lwlock.h:115
#define START_CRIT_SECTION()
Definition: miscadmin.h:149
#define END_CRIT_SECTION()
Definition: miscadmin.h:151
void MultiXactGetCheckptMulti(bool is_shutdown, MultiXactId *nextMulti, MultiXactOffset *nextMultiOffset, MultiXactId *oldestMulti, Oid *oldestMultiDB)
Definition: multixact.c:2282
#define XLOG_CHECKPOINT_REDO
Definition: pg_control.h:82
@ DB_SHUTDOWNING
Definition: pg_control.h:94
@ DB_SHUTDOWNED
Definition: pg_control.h:92
#define XLOG_CHECKPOINT_ONLINE
Definition: pg_control.h:69
#define InvalidOid
Definition: postgres_ext.h:36
#define DELAY_CHKPT_START
Definition: proc.h:119
#define DELAY_CHKPT_COMPLETE
Definition: proc.h:120
VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
Definition: procarray.c:3043
TransactionId GetOldestActiveTransactionId(void)
Definition: procarray.c:2880
TransactionId GetOldestTransactionIdConsideredRunning(void)
Definition: procarray.c:2034
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)
Definition: procarray.c:3089
void pg_usleep(long microsec)
Definition: signal.c:53
bool InvalidateObsoleteReplicationSlots(ReplicationSlotInvalidationCause cause, XLogSegNo oldestSegno, Oid dboid, TransactionId snapshotConflictHorizon)
Definition: slot.c:1811
@ RS_INVAL_WAL_REMOVED
Definition: slot.h:54
XLogRecPtr LogStandbySnapshot(void)
Definition: standby.c:1281
TimestampTz ckpt_start_t
Definition: xlog.h:161
int ckpt_segs_removed
Definition: xlog.h:171
int ckpt_segs_added
Definition: xlog.h:170
int ckpt_bufs_written
Definition: xlog.h:167
int ckpt_segs_recycled
Definition: xlog.h:172
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:168
XLogRecPtr unloggedLSN
Definition: pg_control.h:137
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:169
TransactionId oldestCommitTsXid
Definition: transam.h:232
TransactionId newestCommitTsXid
Definition: transam.h:233
TransactionId oldestXid
Definition: transam.h:222
FullTransactionId ckptFullXid
Definition: xlog.c:457
TimeLineID InsertTimeLineID
Definition: xlog.c:509
XLogRecPtr RedoRecPtr
Definition: xlog.c:456
TimeLineID PrevTimeLineID
Definition: xlog.c:510
pg_atomic_uint64 unloggedLSN
Definition: xlog.c:464
XLogRecPtr RedoRecPtr
Definition: xlog.c:430
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:411
void SyncPreCheckpoint(void)
Definition: sync.c:177
void SyncPostCheckpoint(void)
Definition: sync.c:202
void WakeupWalSummarizer(void)
XLogRecPtr ProcLastRecPtr
Definition: xlog.c:253
bool RecoveryInProgress(void)
Definition: xlog.c:6334
static void WALInsertLockRelease(void)
Definition: xlog.c:1445
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1858
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1416
static void UpdateControlFile(void)
Definition: xlog.c:4559
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr, TimeLineID insertTLI)
Definition: xlog.c:3865
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:6649
static XLogRecPtr RedoRecPtr
Definition: xlog.c:273
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:6681
static void PreallocXlogFiles(XLogRecPtr endptr, TimeLineID tli)
Definition: xlog.c:3690
bool log_checkpoints
Definition: xlog.c:129
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:7953
static int LocalSetXLogInsertAllowed(void)
Definition: xlog.c:6422
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:6556
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:6786
static int LocalXLogInsertAllowed
Definition: xlog.c:236
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2802
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:7510
static void update_checkpoint_display(int flags, bool restartpoint, bool reset)
Definition: xlog.c:6824
#define CHECKPOINT_END_OF_RECOVERY
Definition: xlog.h:140
#define CHECKPOINT_FORCE
Definition: xlog.h:142
#define XLogStandbyInfoActive()
Definition: xlog.h:123
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:474
void XLogRegisterData(const char *data, uint32 len)
Definition: xloginsert.c:364
void XLogBeginInsert(void)
Definition: xloginsert.c:149

References AbsorbSyncRequests(), ControlFileData::checkPoint, CHECKPOINT_END_OF_RECOVERY, CHECKPOINT_FORCE, CHECKPOINT_IS_SHUTDOWN, ControlFileData::checkPointCopy, CheckPointGuts(), CheckpointStats, CheckpointStatsData::ckpt_bufs_written, CheckpointStatsData::ckpt_segs_added, CheckpointStatsData::ckpt_segs_recycled, CheckpointStatsData::ckpt_segs_removed, CheckpointStatsData::ckpt_start_t, XLogCtlData::ckptFullXid, ControlFile, DB_SHUTDOWNED, DB_SHUTDOWNING, DEBUG1, DELAY_CHKPT_COMPLETE, DELAY_CHKPT_START, elog, END_CRIT_SECTION, ereport, errmsg(), errmsg_internal(), ERROR, CheckPoint::fullPageWrites, GetCurrentTimestamp(), GetLastImportantRecPtr(), GetOldestActiveTransactionId(), GetOldestTransactionIdConsideredRunning(), GetVirtualXIDsDelayingChkpt(), HaveVirtualXIDsDelayingChkpt(), XLogCtlData::info_lck, XLogCtlData::Insert, Insert(), INSERT_FREESPACE, XLogCtlData::InsertTimeLineID, InvalidateObsoleteReplicationSlots(), InvalidOid, InvalidTransactionId, InvalidXLogRecPtr, KeepLogSeg(), LocalSetXLogInsertAllowed(), LocalXLogInsertAllowed, log_checkpoints, LogCheckpointEnd(), LogCheckpointStart(), LogStandbySnapshot(), LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockRelease(), MemSet, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, MultiXactGetCheckptMulti(), NBuffers, TransamVariablesData::newestCommitTsXid, CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, TransamVariablesData::nextOid, CheckPoint::nextOid, TransamVariablesData::nextXid, CheckPoint::nextXid, TransamVariablesData::oidCount, CheckPoint::oldestActiveXid, TransamVariablesData::oldestCommitTsXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, TransamVariablesData::oldestXid, CheckPoint::oldestXid, TransamVariablesData::oldestXidDB, CheckPoint::oldestXidDB, PANIC, pfree(), pg_atomic_read_membarrier_u64(), pg_usleep(), pgstat_report_wait_end(), pgstat_report_wait_start(), PreallocXlogFiles(), XLogCtlData::PrevTimeLineID, CheckPoint::PrevTimeLineID, ProcLastRecPtr, RecoveryInProgress(), CheckPoint::redo, RedoRecPtr, XLogCtlInsert::RedoRecPtr, XLogCtlData::RedoRecPtr, RemoveOldXlogFiles(), RS_INVAL_WAL_REMOVED, SizeOfXLogLongPHD, SizeOfXLogShortPHD, SpinLockAcquire, SpinLockRelease, START_CRIT_SECTION, ControlFileData::state, SyncPostCheckpoint(), SyncPreCheckpoint(), CheckPoint::ThisTimeLineID, CheckPoint::time, TransamVariables, TruncateSUBTRANS(), XLogCtlData::unloggedLSN, ControlFileData::unloggedLSN, update_checkpoint_display(), UpdateCheckPointDistanceEstimate(), UpdateControlFile(), WakeupWalSummarizer(), wal_level, CheckPoint::wal_level, wal_segment_size, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), XLByteToSeg, XLOG_CHECKPOINT_ONLINE, XLOG_CHECKPOINT_REDO, XLOG_CHECKPOINT_SHUTDOWN, XLogBeginInsert(), XLogBytePosToRecPtr(), XLogCtl, XLogFlush(), XLogInsert(), XLogRegisterData(), XLogSegmentOffset, and XLogStandbyInfoActive.

Referenced by CheckpointerMain(), RequestCheckpoint(), and ShutdownXLOG().

◆ CreateEndOfRecoveryRecord()

static void CreateEndOfRecoveryRecord ( void  )
static

Definition at line 7375 of file xlog.c.

7376 {
7377  xl_end_of_recovery xlrec;
7378  XLogRecPtr recptr;
7379 
7380  /* sanity check */
7381  if (!RecoveryInProgress())
7382  elog(ERROR, "can only be used to end recovery");
7383 
7384  xlrec.end_time = GetCurrentTimestamp();
7385  xlrec.wal_level = wal_level;
7386 
7391 
7393 
7394  XLogBeginInsert();
7395  XLogRegisterData((char *) &xlrec, sizeof(xl_end_of_recovery));
7396  recptr = XLogInsert(RM_XLOG_ID, XLOG_END_OF_RECOVERY);
7397 
7398  XLogFlush(recptr);
7399 
7400  /*
7401  * Update the control file so that crash recovery can follow the timeline
7402  * changes to this point.
7403  */
7404  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7405  ControlFile->minRecoveryPoint = recptr;
7406  ControlFile->minRecoveryPointTLI = xlrec.ThisTimeLineID;
7408  LWLockRelease(ControlFileLock);
7409 
7410  END_CRIT_SECTION();
7411 }
#define XLOG_END_OF_RECOVERY
Definition: pg_control.h:77
TimeLineID PrevTimeLineID
TimestampTz end_time
TimeLineID ThisTimeLineID

References ControlFile, elog, END_CRIT_SECTION, xl_end_of_recovery::end_time, ERROR, GetCurrentTimestamp(), XLogCtlData::InsertTimeLineID, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, XLogCtlData::PrevTimeLineID, xl_end_of_recovery::PrevTimeLineID, RecoveryInProgress(), START_CRIT_SECTION, xl_end_of_recovery::ThisTimeLineID, UpdateControlFile(), wal_level, xl_end_of_recovery::wal_level, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), XLOG_END_OF_RECOVERY, XLogBeginInsert(), XLogCtl, XLogFlush(), XLogInsert(), and XLogRegisterData().

Referenced by PerformRecoveryXLogAction().

◆ CreateOverwriteContrecordRecord()

static XLogRecPtr CreateOverwriteContrecordRecord ( XLogRecPtr  aborted_lsn,
XLogRecPtr  pagePtr,
TimeLineID  newTLI 
)
static

Definition at line 7440 of file xlog.c.

7442 {
7444  XLogRecPtr recptr;
7445  XLogPageHeader pagehdr;
7446  XLogRecPtr startPos;
7447 
7448  /* sanity checks */
7449  if (!RecoveryInProgress())
7450  elog(ERROR, "can only be used at end of recovery");
7451  if (pagePtr % XLOG_BLCKSZ != 0)
7452  elog(ERROR, "invalid position for missing continuation record %X/%X",
7453  LSN_FORMAT_ARGS(pagePtr));
7454 
7455  /* The current WAL insert position should be right after the page header */
7456  startPos = pagePtr;
7457  if (XLogSegmentOffset(startPos, wal_segment_size) == 0)
7458  startPos += SizeOfXLogLongPHD;
7459  else
7460  startPos += SizeOfXLogShortPHD;
7461  recptr = GetXLogInsertRecPtr();
7462  if (recptr != startPos)
7463  elog(ERROR, "invalid WAL insert position %X/%X for OVERWRITE_CONTRECORD",
7464  LSN_FORMAT_ARGS(recptr));
7465 
7467 
7468  /*
7469  * Initialize the XLOG page header (by GetXLogBuffer), and set the
7470  * XLP_FIRST_IS_OVERWRITE_CONTRECORD flag.
7471  *
7472  * No other backend is allowed to write WAL yet, so acquiring the WAL
7473  * insertion lock is just pro forma.
7474  */
7476  pagehdr = (XLogPageHeader) GetXLogBuffer(pagePtr, newTLI);
7479 
7480  /*
7481  * Insert the XLOG_OVERWRITE_CONTRECORD record as the first record on the
7482  * page. We know it becomes the first record, because no other backend is
7483  * allowed to write WAL yet.
7484  */
7485  XLogBeginInsert();
7486  xlrec.overwritten_lsn = aborted_lsn;
7488  XLogRegisterData((char *) &xlrec, sizeof(xl_overwrite_contrecord));
7489  recptr = XLogInsert(RM_XLOG_ID, XLOG_OVERWRITE_CONTRECORD);
7490 
7491  /* check that the record was inserted to the right place */
7492  if (ProcLastRecPtr != startPos)
7493  elog(ERROR, "OVERWRITE_CONTRECORD was inserted to unexpected position %X/%X",
7495 
7496  XLogFlush(recptr);
7497 
7498  END_CRIT_SECTION();
7499 
7500  return recptr;
7501 }
#define XLOG_OVERWRITE_CONTRECORD
Definition: pg_control.h:81
static void WALInsertLockAcquire(void)
Definition: xlog.c:1371
XLogRecPtr GetXLogInsertRecPtr(void)
Definition: xlog.c:9435
#define XLP_FIRST_IS_OVERWRITE_CONTRECORD
Definition: xlog_internal.h:80

References elog, END_CRIT_SECTION, ERROR, GetCurrentTimestamp(), GetXLogBuffer(), GetXLogInsertRecPtr(), LSN_FORMAT_ARGS, xl_overwrite_contrecord::overwrite_time, xl_overwrite_contrecord::overwritten_lsn, ProcLastRecPtr, RecoveryInProgress(), SizeOfXLogLongPHD, SizeOfXLogShortPHD, START_CRIT_SECTION, wal_segment_size, WALInsertLockAcquire(), WALInsertLockRelease(), XLOG_OVERWRITE_CONTRECORD, XLogBeginInsert(), XLogFlush(), XLogInsert(), XLogRegisterData(), XLogSegmentOffset, XLP_FIRST_IS_OVERWRITE_CONTRECORD, and XLogPageHeaderData::xlp_info.

Referenced by StartupXLOG().

◆ CreateRestartPoint()

bool CreateRestartPoint ( int  flags)

Definition at line 7591 of file xlog.c.

7592 {
7593  XLogRecPtr lastCheckPointRecPtr;
7594  XLogRecPtr lastCheckPointEndPtr;
7595  CheckPoint lastCheckPoint;
7596  XLogRecPtr PriorRedoPtr;
7597  XLogRecPtr receivePtr;
7598  XLogRecPtr replayPtr;
7599  TimeLineID replayTLI;
7600  XLogRecPtr endptr;
7601  XLogSegNo _logSegNo;
7602  TimestampTz xtime;
7603 
7604  /* Concurrent checkpoint/restartpoint cannot happen */
7606 
7607  /* Get a local copy of the last safe checkpoint record. */
7609  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
7610  lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
7611  lastCheckPoint = XLogCtl->lastCheckPoint;
7613 
7614  /*
7615  * Check that we're still in recovery mode. It's ok if we exit recovery
7616  * mode after this check, the restart point is valid anyway.
7617  */
7618  if (!RecoveryInProgress())
7619  {
7620  ereport(DEBUG2,
7621  (errmsg_internal("skipping restartpoint, recovery has already ended")));
7622  return false;
7623  }
7624 
7625  /*
7626  * If the last checkpoint record we've replayed is already our last
7627  * restartpoint, we can't perform a new restart point. We still update
7628  * minRecoveryPoint in that case, so that if this is a shutdown restart
7629  * point, we won't start up earlier than before. That's not strictly
7630  * necessary, but when hot standby is enabled, it would be rather weird if
7631  * the database opened up for read-only connections at a point-in-time
7632  * before the last shutdown. Such time travel is still possible in case of
7633  * immediate shutdown, though.
7634  *
7635  * We don't explicitly advance minRecoveryPoint when we do create a
7636  * restartpoint. It's assumed that flushing the buffers will do that as a
7637  * side-effect.
7638  */
7639  if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
7640  lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
7641  {
7642  ereport(DEBUG2,
7643  (errmsg_internal("skipping restartpoint, already performed at %X/%X",
7644  LSN_FORMAT_ARGS(lastCheckPoint.redo))));
7645 
7647  if (flags & CHECKPOINT_IS_SHUTDOWN)
7648  {
7649  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7652  LWLockRelease(ControlFileLock);
7653  }
7654  return false;
7655  }
7656 
7657  /*
7658  * Update the shared RedoRecPtr so that the startup process can calculate
7659  * the number of segments replayed since last restartpoint, and request a
7660  * restartpoint if it exceeds CheckPointSegments.
7661  *
7662  * Like in CreateCheckPoint(), hold off insertions to update it, although
7663  * during recovery this is just pro forma, because no WAL insertions are
7664  * happening.
7665  */
7667  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
7669 
7670  /* Also update the info_lck-protected copy */
7672  XLogCtl->RedoRecPtr = lastCheckPoint.redo;
7674 
7675  /*
7676  * Prepare to accumulate statistics.
7677  *
7678  * Note: because it is possible for log_checkpoints to change while a
7679  * checkpoint proceeds, we always accumulate stats, even if
7680  * log_checkpoints is currently off.
7681  */
7682  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
7684 
7685  if (log_checkpoints)
7686  LogCheckpointStart(flags, true);
7687 
7688  /* Update the process title */
7689  update_checkpoint_display(flags, true, false);
7690 
7691  CheckPointGuts(lastCheckPoint.redo, flags);
7692 
7693  /*
7694  * This location needs to be after CheckPointGuts() to ensure that some
7695  * work has already happened during this checkpoint.
7696  */
7697  INJECTION_POINT("create-restart-point");
7698 
7699  /*
7700  * Remember the prior checkpoint's redo ptr for
7701  * UpdateCheckPointDistanceEstimate()
7702  */
7703  PriorRedoPtr = ControlFile->checkPointCopy.redo;
7704 
7705  /*
7706  * Update pg_control, using current time. Check that it still shows an
7707  * older checkpoint, else do nothing; this is a quick hack to make sure
7708  * nothing really bad happens if somehow we get here after the
7709  * end-of-recovery checkpoint.
7710  */
7711  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7712  if (ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
7713  {
7714  /*
7715  * Update the checkpoint information. We do this even if the cluster
7716  * does not show DB_IN_ARCHIVE_RECOVERY to match with the set of WAL
7717  * segments recycled below.
7718  */
7719  ControlFile->checkPoint = lastCheckPointRecPtr;
7720  ControlFile->checkPointCopy = lastCheckPoint;
7721 
7722  /*
7723  * Ensure minRecoveryPoint is past the checkpoint record and update it
7724  * if the control file still shows DB_IN_ARCHIVE_RECOVERY. Normally,
7725  * this will have happened already while writing out dirty buffers,
7726  * but not necessarily - e.g. because no buffers were dirtied. We do
7727  * this because a backup performed in recovery uses minRecoveryPoint
7728  * to determine which WAL files must be included in the backup, and
7729  * the file (or files) containing the checkpoint record must be
7730  * included, at a minimum. Note that for an ordinary restart of
7731  * recovery there's no value in having the minimum recovery point any
7732  * earlier than this anyway, because redo will begin just after the
7733  * checkpoint record.
7734  */
7736  {
7737  if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
7738  {
7739  ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
7741 
7742  /* update local copy */
7745  }
7746  if (flags & CHECKPOINT_IS_SHUTDOWN)
7748  }
7750  }
7751  LWLockRelease(ControlFileLock);
7752 
7753  /*
7754  * Update the average distance between checkpoints/restartpoints if the
7755  * prior checkpoint exists.
7756  */
7757  if (PriorRedoPtr != InvalidXLogRecPtr)
7759 
7760  /*
7761  * Delete old log files, those no longer needed for last restartpoint to
7762  * prevent the disk holding the xlog from growing full.
7763  */
7765 
7766  /*
7767  * Retreat _logSegNo using the current end of xlog replayed or received,
7768  * whichever is later.
7769  */
7770  receivePtr = GetWalRcvFlushRecPtr(NULL, NULL);
7771  replayPtr = GetXLogReplayRecPtr(&replayTLI);
7772  endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
7773  KeepLogSeg(endptr, &_logSegNo);
7775  _logSegNo, InvalidOid,
7777  {
7778  /*
7779  * Some slots have been invalidated; recalculate the old-segment
7780  * horizon, starting again from RedoRecPtr.
7781  */
7783  KeepLogSeg(endptr, &_logSegNo);
7784  }
7785  _logSegNo--;
7786 
7787  /*
7788  * Try to recycle segments on a useful timeline. If we've been promoted
7789  * since the beginning of this restartpoint, use the new timeline chosen
7790  * at end of recovery. If we're still in recovery, use the timeline we're
7791  * currently replaying.
7792  *
7793  * There is no guarantee that the WAL segments will be useful on the
7794  * current timeline; if recovery proceeds to a new timeline right after
7795  * this, the pre-allocated WAL segments on this timeline will not be used,
7796  * and will go wasted until recycled on the next restartpoint. We'll live
7797  * with that.
7798  */
7799  if (!RecoveryInProgress())
7800  replayTLI = XLogCtl->InsertTimeLineID;
7801 
7802  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr, replayTLI);
7803 
7804  /*
7805  * Make more log segments if needed. (Do this after recycling old log
7806  * segments, since that may supply some of the needed files.)
7807  */
7808  PreallocXlogFiles(endptr, replayTLI);
7809 
7810  /*
7811  * Truncate pg_subtrans if possible. We can throw away all data before
7812  * the oldest XMIN of any running transaction. No future transaction will
7813  * attempt to reference any pg_subtrans entry older than that (see Asserts
7814  * in subtrans.c). When hot standby is disabled, though, we mustn't do
7815  * this because StartupSUBTRANS hasn't been called yet.
7816  */
7817  if (EnableHotStandby)
7819 
7820  /* Real work is done; log and update stats. */
7821  LogCheckpointEnd(true);
7822 
7823  /* Reset the process title */
7824  update_checkpoint_display(flags, true, true);
7825 
7826  xtime = GetLatestXTime();
7828  (errmsg("recovery restart point at %X/%X",
7829  LSN_FORMAT_ARGS(lastCheckPoint.redo)),
7830  xtime ? errdetail("Last completed transaction was at log time %s.",
7831  timestamptz_to_str(xtime)) : 0));
7832 
7833  /*
7834  * Finally, execute archive_cleanup_command, if any.
7835  */
7836  if (archiveCleanupCommand && strcmp(archiveCleanupCommand, "") != 0)
7838  "archive_cleanup_command",
7839  false,
7840  WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND);
7841 
7842  return true;
7843 }
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1843
int64 TimestampTz
Definition: timestamp.h:39
#define LOG
Definition: elog.h:31
bool IsUnderPostmaster
Definition: globals.c:119
#define INJECTION_POINT(name)
@ B_CHECKPOINTER
Definition: miscadmin.h:355
BackendType MyBackendType
Definition: miscinit.c:64
@ DB_IN_ARCHIVE_RECOVERY
Definition: pg_control.h:96
@ DB_SHUTDOWNED_IN_RECOVERY
Definition: pg_control.h:93
CheckPoint lastCheckPoint
Definition: xlog.c:545
XLogRecPtr lastCheckPointRecPtr
Definition: xlog.c:543
XLogRecPtr lastCheckPointEndPtr
Definition: xlog.c:544
XLogRecPtr GetWalRcvFlushRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI)
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition: xlog.c:2722
static XLogRecPtr LocalMinRecoveryPoint
Definition: xlog.c:646
static TimeLineID LocalMinRecoveryPointTLI
Definition: xlog.c:647
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
uint32 TimeLineID
Definition: xlogdefs.h:59
char * archiveCleanupCommand
Definition: xlogrecovery.c:84
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
TimestampTz GetLatestXTime(void)

References archiveCleanupCommand, Assert, B_CHECKPOINTER, ControlFileData::checkPoint, CHECKPOINT_IS_SHUTDOWN, ControlFileData::checkPointCopy, CheckPointGuts(), CheckpointStats, CheckpointStatsData::ckpt_start_t, ControlFile, DB_IN_ARCHIVE_RECOVERY, DB_SHUTDOWNED_IN_RECOVERY, DEBUG2, EnableHotStandby, ereport, errdetail(), errmsg(), errmsg_internal(), ExecuteRecoveryCommand(), GetCurrentTimestamp(), GetLatestXTime(), GetOldestTransactionIdConsideredRunning(), GetWalRcvFlushRecPtr(), GetXLogReplayRecPtr(), XLogCtlData::info_lck, INJECTION_POINT, XLogCtlData::Insert, XLogCtlData::InsertTimeLineID, InvalidateObsoleteReplicationSlots(), InvalidOid, InvalidTransactionId, InvalidXLogRecPtr, IsUnderPostmaster, KeepLogSeg(), XLogCtlData::lastCheckPoint, XLogCtlData::lastCheckPointEndPtr, XLogCtlData::lastCheckPointRecPtr, LocalMinRecoveryPoint, LocalMinRecoveryPointTLI, LOG, log_checkpoints, LogCheckpointEnd(), LogCheckpointStart(), LSN_FORMAT_ARGS, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MemSet, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, MyBackendType, PreallocXlogFiles(), RecoveryInProgress(), CheckPoint::redo, RedoRecPtr, XLogCtlInsert::RedoRecPtr, XLogCtlData::RedoRecPtr, RemoveOldXlogFiles(), RS_INVAL_WAL_REMOVED, SpinLockAcquire, SpinLockRelease, ControlFileData::state, CheckPoint::ThisTimeLineID, timestamptz_to_str(), TruncateSUBTRANS(), update_checkpoint_display(), UpdateCheckPointDistanceEstimate(), UpdateControlFile(), UpdateMinRecoveryPoint(), wal_segment_size, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), XLByteToSeg, XLogCtl, and XLogRecPtrIsInvalid.

Referenced by CheckpointerMain(), and ShutdownXLOG().

◆ DataChecksumsEnabled()

◆ do_pg_abort_backup()

void do_pg_abort_backup ( int  code,
Datum  arg 
)

Definition at line 9394 of file xlog.c.

9395 {
9396  bool during_backup_start = DatumGetBool(arg);
9397 
9398  /* If called during backup start, there shouldn't be one already running */
9399  Assert(!during_backup_start || sessionBackupState == SESSION_BACKUP_NONE);
9400 
9401  if (during_backup_start || sessionBackupState != SESSION_BACKUP_NONE)
9402  {
9406 
9409 
9410  if (!during_backup_start)
9411  ereport(WARNING,
9412  errmsg("aborting backup due to backend exiting before pg_backup_stop was called"));
9413  }
9414 }
#define WARNING
Definition: elog.h:36
void * arg
static bool DatumGetBool(Datum X)
Definition: postgres.h:90
int runningBackups
Definition: xlog.c:438
static SessionBackupState sessionBackupState
Definition: xlog.c:391
@ SESSION_BACKUP_NONE
Definition: xlog.h:287

References arg, Assert, DatumGetBool(), ereport, errmsg(), XLogCtlData::Insert, XLogCtlInsert::runningBackups, SESSION_BACKUP_NONE, sessionBackupState, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), WARNING, and XLogCtl.

Referenced by do_pg_backup_start(), perform_base_backup(), and register_persistent_abort_backup_handler().

◆ do_pg_backup_start()

void do_pg_backup_start ( const char *  backupidstr,
bool  fast,
List **  tablespaces,
BackupState state,
StringInfo  tblspcmapfile 
)

Definition at line 8792 of file xlog.c.

8794 {
8796 
8797  Assert(state != NULL);
8799 
8800  /*
8801  * During recovery, we don't need to check WAL level. Because, if WAL
8802  * level is not sufficient, it's impossible to get here during recovery.
8803  */
8805  ereport(ERROR,
8806  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8807  errmsg("WAL level not sufficient for making an online backup"),
8808  errhint("\"wal_level\" must be set to \"replica\" or \"logical\" at server start.")));
8809 
8810  if (strlen(backupidstr) > MAXPGPATH)
8811  ereport(ERROR,
8812  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8813  errmsg("backup label too long (max %d bytes)",
8814  MAXPGPATH)));
8815 
8816  strlcpy(state->name, backupidstr, sizeof(state->name));
8817 
8818  /*
8819  * Mark backup active in shared memory. We must do full-page WAL writes
8820  * during an on-line backup even if not doing so at other times, because
8821  * it's quite possible for the backup dump to obtain a "torn" (partially
8822  * written) copy of a database page if it reads the page concurrently with
8823  * our write to the same page. This can be fixed as long as the first
8824  * write to the page in the WAL sequence is a full-page write. Hence, we
8825  * increment runningBackups then force a CHECKPOINT, to ensure there are
8826  * no dirty pages in shared memory that might get dumped while the backup
8827  * is in progress without having a corresponding WAL record. (Once the
8828  * backup is complete, we need not force full-page writes anymore, since
8829  * we expect that any pages not modified during the backup interval must
8830  * have been correctly captured by the backup.)
8831  *
8832  * Note that forcing full-page writes has no effect during an online
8833  * backup from the standby.
8834  *
8835  * We must hold all the insertion locks to change the value of
8836  * runningBackups, to ensure adequate interlocking against
8837  * XLogInsertRecord().
8838  */
8842 
8843  /*
8844  * Ensure we decrement runningBackups if we fail below. NB -- for this to
8845  * work correctly, it is critical that sessionBackupState is only updated
8846  * after this block is over.
8847  */
8849  {
8850  bool gotUniqueStartpoint = false;
8851  DIR *tblspcdir;
8852  struct dirent *de;
8853  tablespaceinfo *ti;
8854  int datadirpathlen;
8855 
8856  /*
8857  * Force an XLOG file switch before the checkpoint, to ensure that the
8858  * WAL segment the checkpoint is written to doesn't contain pages with
8859  * old timeline IDs. That would otherwise happen if you called
8860  * pg_backup_start() right after restoring from a PITR archive: the
8861  * first WAL segment containing the startup checkpoint has pages in
8862  * the beginning with the old timeline ID. That can cause trouble at
8863  * recovery: we won't have a history file covering the old timeline if
8864  * pg_wal directory was not included in the base backup and the WAL
8865  * archive was cleared too before starting the backup.
8866  *
8867  * This also ensures that we have emitted a WAL page header that has
8868  * XLP_BKP_REMOVABLE off before we emit the checkpoint record.
8869  * Therefore, if a WAL archiver (such as pglesslog) is trying to
8870  * compress out removable backup blocks, it won't remove any that
8871  * occur after this point.
8872  *
8873  * During recovery, we skip forcing XLOG file switch, which means that
8874  * the backup taken during recovery is not available for the special
8875  * recovery case described above.
8876  */
8878  RequestXLogSwitch(false);
8879 
8880  do
8881  {
8882  bool checkpointfpw;
8883 
8884  /*
8885  * Force a CHECKPOINT. Aside from being necessary to prevent torn
8886  * page problems, this guarantees that two successive backup runs
8887  * will have different checkpoint positions and hence different
8888  * history file names, even if nothing happened in between.
8889  *
8890  * During recovery, establish a restartpoint if possible. We use
8891  * the last restartpoint as the backup starting checkpoint. This
8892  * means that two successive backup runs can have same checkpoint
8893  * positions.
8894  *
8895  * Since the fact that we are executing do_pg_backup_start()
8896  * during recovery means that checkpointer is running, we can use
8897  * RequestCheckpoint() to establish a restartpoint.
8898  *
8899  * We use CHECKPOINT_IMMEDIATE only if requested by user (via
8900  * passing fast = true). Otherwise this can take awhile.
8901  */
8903  (fast ? CHECKPOINT_IMMEDIATE : 0));
8904 
8905  /*
8906  * Now we need to fetch the checkpoint record location, and also
8907  * its REDO pointer. The oldest point in WAL that would be needed
8908  * to restore starting from the checkpoint is precisely the REDO
8909  * pointer.
8910  */
8911  LWLockAcquire(ControlFileLock, LW_SHARED);
8912  state->checkpointloc = ControlFile->checkPoint;
8913  state->startpoint = ControlFile->checkPointCopy.redo;
8915  checkpointfpw = ControlFile->checkPointCopy.fullPageWrites;
8916  LWLockRelease(ControlFileLock);
8917 
8919  {
8920  XLogRecPtr recptr;
8921 
8922  /*
8923  * Check to see if all WAL replayed during online backup
8924  * (i.e., since last restartpoint used as backup starting
8925  * checkpoint) contain full-page writes.
8926  */
8928  recptr = XLogCtl->lastFpwDisableRecPtr;
8930 
8931  if (!checkpointfpw || state->startpoint <= recptr)
8932  ereport(ERROR,
8933  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8934  errmsg("WAL generated with \"full_page_writes=off\" was replayed "
8935  "since last restartpoint"),
8936  errhint("This means that the backup being taken on the standby "
8937  "is corrupt and should not be used. "
8938  "Enable \"full_page_writes\" and run CHECKPOINT on the primary, "
8939  "and then try an online backup again.")));
8940 
8941  /*
8942  * During recovery, since we don't use the end-of-backup WAL
8943  * record and don't write the backup history file, the
8944  * starting WAL location doesn't need to be unique. This means
8945  * that two base backups started at the same time might use
8946  * the same checkpoint as starting locations.
8947  */
8948  gotUniqueStartpoint = true;
8949  }
8950 
8951  /*
8952  * If two base backups are started at the same time (in WAL sender
8953  * processes), we need to make sure that they use different
8954  * checkpoints as starting locations, because we use the starting
8955  * WAL location as a unique identifier for the base backup in the
8956  * end-of-backup WAL record and when we write the backup history
8957  * file. Perhaps it would be better generate a separate unique ID
8958  * for each backup instead of forcing another checkpoint, but
8959  * taking a checkpoint right after another is not that expensive
8960  * either because only few buffers have been dirtied yet.
8961  */
8963  if (XLogCtl->Insert.lastBackupStart < state->startpoint)
8964  {
8965  XLogCtl->Insert.lastBackupStart = state->startpoint;
8966  gotUniqueStartpoint = true;
8967  }
8969  } while (!gotUniqueStartpoint);
8970 
8971  /*
8972  * Construct tablespace_map file.
8973  */
8974  datadirpathlen = strlen(DataDir);
8975 
8976  /* Collect information about all tablespaces */
8977  tblspcdir = AllocateDir(PG_TBLSPC_DIR);
8978  while ((de = ReadDir(tblspcdir, PG_TBLSPC_DIR)) != NULL)
8979  {
8980  char fullpath[MAXPGPATH + sizeof(PG_TBLSPC_DIR)];
8981  char linkpath[MAXPGPATH];
8982  char *relpath = NULL;
8983  char *s;
8984  PGFileType de_type;
8985  char *badp;
8986  Oid tsoid;
8987 
8988  /*
8989  * Try to parse the directory name as an unsigned integer.
8990  *
8991  * Tablespace directories should be positive integers that can be
8992  * represented in 32 bits, with no leading zeroes or trailing
8993  * garbage. If we come across a name that doesn't meet those
8994  * criteria, skip it.
8995  */
8996  if (de->d_name[0] < '1' || de->d_name[1] > '9')
8997  continue;
8998  errno = 0;
8999  tsoid = strtoul(de->d_name, &badp, 10);
9000  if (*badp != '\0' || errno == EINVAL || errno == ERANGE)
9001  continue;
9002 
9003  snprintf(fullpath, sizeof(fullpath), "%s/%s", PG_TBLSPC_DIR, de->d_name);
9004 
9005  de_type = get_dirent_type(fullpath, de, false, ERROR);
9006 
9007  if (de_type == PGFILETYPE_LNK)
9008  {
9009  StringInfoData escapedpath;
9010  int rllen;
9011 
9012  rllen = readlink(fullpath, linkpath, sizeof(linkpath));
9013  if (rllen < 0)
9014  {
9015  ereport(WARNING,
9016  (errmsg("could not read symbolic link \"%s\": %m",
9017  fullpath)));
9018  continue;
9019  }
9020  else if (rllen >= sizeof(linkpath))
9021  {
9022  ereport(WARNING,
9023  (errmsg("symbolic link \"%s\" target is too long",
9024  fullpath)));
9025  continue;
9026  }
9027  linkpath[rllen] = '\0';
9028 
9029  /*
9030  * Relpath holds the relative path of the tablespace directory
9031  * when it's located within PGDATA, or NULL if it's located
9032  * elsewhere.
9033  */
9034  if (rllen > datadirpathlen &&
9035  strncmp(linkpath, DataDir, datadirpathlen) == 0 &&
9036  IS_DIR_SEP(linkpath[datadirpathlen]))
9037  relpath = pstrdup(linkpath + datadirpathlen + 1);
9038 
9039  /*
9040  * Add a backslash-escaped version of the link path to the
9041  * tablespace map file.
9042  */
9043  initStringInfo(&escapedpath);
9044  for (s = linkpath; *s; s++)
9045  {
9046  if (*s == '\n' || *s == '\r' || *s == '\\')
9047  appendStringInfoChar(&escapedpath, '\\');
9048  appendStringInfoChar(&escapedpath, *s);
9049  }
9050  appendStringInfo(tblspcmapfile, "%s %s\n",
9051  de->d_name, escapedpath.data);
9052  pfree(escapedpath.data);
9053  }
9054  else if (de_type == PGFILETYPE_DIR)
9055  {
9056  /*
9057  * It's possible to use allow_in_place_tablespaces to create
9058  * directories directly under pg_tblspc, for testing purposes
9059  * only.
9060  *
9061  * In this case, we store a relative path rather than an
9062  * absolute path into the tablespaceinfo.
9063  */
9064  snprintf(linkpath, sizeof(linkpath), "%s/%s",
9065  PG_TBLSPC_DIR, de->d_name);
9066  relpath = pstrdup(linkpath);
9067  }
9068  else
9069  {
9070  /* Skip any other file type that appears here. */
9071  continue;
9072  }
9073 
9074  ti = palloc(sizeof(tablespaceinfo));
9075  ti->oid = tsoid;
9076  ti->path = pstrdup(linkpath);
9077  ti->rpath = relpath;
9078  ti->size = -1;
9079 
9080  if (tablespaces)
9081  *tablespaces = lappend(*tablespaces, ti);
9082  }
9083  FreeDir(tblspcdir);
9084 
9085  state->starttime = (pg_time_t) time(NULL);
9086  }
9088 
9089  state->started_in_recovery = backup_started_in_recovery;
9090 
9091  /*
9092  * Mark that the start phase has correctly finished for the backup.
9093  */
9095 }
static bool backup_started_in_recovery
Definition: basebackup.c:123
void RequestCheckpoint(int flags)
Definition: checkpointer.c:952
PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
Definition: file_utils.c:526
PGFileType
Definition: file_utils.h:19
@ PGFILETYPE_LNK
Definition: file_utils.h:24
@ PGFILETYPE_DIR
Definition: file_utils.h:23
char * DataDir
Definition: globals.c:70
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:47
#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:52
List * lappend(List *list, void *datum)
Definition: list.c:339
#define IS_DIR_SEP(ch)
Definition: port.h:102
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
unsigned int Oid
Definition: postgres_ext.h:31
#define relpath(rlocator, forknum)
Definition: relpath.h:102
#define PG_TBLSPC_DIR
Definition: relpath.h:41
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:94
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:191
void initStringInfo(StringInfo str)
Definition: stringinfo.c:56
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:551
XLogRecPtr lastBackupStart
Definition: xlog.c:439
Definition: regguts.h:323
char * rpath
Definition: basebackup.h:32
#define readlink(path, buf, size)
Definition: win32_port.h:236
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:8060
void do_pg_abort_backup(int code, Datum arg)
Definition: xlog.c:9394
@ SESSION_BACKUP_RUNNING
Definition: xlog.h:288
#define CHECKPOINT_WAIT
Definition: xlog.h:145
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:141
#define XLogIsNeeded()
Definition: xlog.h:109

References AllocateDir(), appendStringInfo(), appendStringInfoChar(), Assert, backup_started_in_recovery, ControlFileData::checkPoint, CHECKPOINT_FORCE, CHECKPOINT_IMMEDIATE, CHECKPOINT_WAIT, ControlFileData::checkPointCopy, ControlFile, dirent::d_name, StringInfoData::data, DataDir, DatumGetBool(), do_pg_abort_backup(), ereport, errcode(), errhint(), errmsg(), ERROR, FreeDir(), CheckPoint::fullPageWrites, get_dirent_type(), XLogCtlData::info_lck, initStringInfo(), XLogCtlData::Insert, IS_DIR_SEP, lappend(), XLogCtlInsert::lastBackupStart, XLogCtlData::lastFpwDisableRecPtr, LW_SHARED, LWLockAcquire(), LWLockRelease(), MAXPGPATH, tablespaceinfo::oid, palloc(), tablespaceinfo::path, pfree(), PG_END_ENSURE_ERROR_CLEANUP, PG_ENSURE_ERROR_CLEANUP, PG_TBLSPC_DIR, PGFILETYPE_DIR, PGFILETYPE_LNK, pstrdup(), ReadDir(), readlink, RecoveryInProgress(), CheckPoint::redo, relpath, RequestCheckpoint(), RequestXLogSwitch(), tablespaceinfo::rpath, XLogCtlInsert::runningBackups, SESSION_BACKUP_RUNNING, sessionBackupState, tablespaceinfo::size, snprintf, SpinLockAcquire, SpinLockRelease, strlcpy(), CheckPoint::ThisTimeLineID, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), WARNING, XLogCtl, and XLogIsNeeded.

Referenced by perform_base_backup(), and pg_backup_start().

◆ do_pg_backup_stop()

void do_pg_backup_stop ( BackupState state,
bool  waitforarchive 
)

Definition at line 9120 of file xlog.c.

9121 {
9122  bool backup_stopped_in_recovery = false;
9123  char histfilepath[MAXPGPATH];
9124  char lastxlogfilename[MAXFNAMELEN];
9125  char histfilename[MAXFNAMELEN];
9126  XLogSegNo _logSegNo;
9127  FILE *fp;
9128  int seconds_before_warning;
9129  int waits = 0;
9130  bool reported_waiting = false;
9131 
9132  Assert(state != NULL);
9133 
9134  backup_stopped_in_recovery = RecoveryInProgress();
9135 
9136  /*
9137  * During recovery, we don't need to check WAL level. Because, if WAL
9138  * level is not sufficient, it's impossible to get here during recovery.
9139  */
9140  if (!backup_stopped_in_recovery && !XLogIsNeeded())
9141  ereport(ERROR,
9142  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
9143  errmsg("WAL level not sufficient for making an online backup"),
9144  errhint("\"wal_level\" must be set to \"replica\" or \"logical\" at server start.")));
9145 
9146  /*
9147  * OK to update backup counter and session-level lock.
9148  *
9149  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating them,
9150  * otherwise they can be updated inconsistently, which might cause
9151  * do_pg_abort_backup() to fail.
9152  */
9154 
9155  /*
9156  * It is expected that each do_pg_backup_start() call is matched by
9157  * exactly one do_pg_backup_stop() call.
9158  */
9161 
9162  /*
9163  * Clean up session-level lock.
9164  *
9165  * You might think that WALInsertLockRelease() can be called before
9166  * cleaning up session-level lock because session-level lock doesn't need
9167  * to be protected with WAL insertion lock. But since
9168  * CHECK_FOR_INTERRUPTS() can occur in it, session-level lock must be
9169  * cleaned up before it.
9170  */
9172 
9174 
9175  /*
9176  * If we are taking an online backup from the standby, we confirm that the
9177  * standby has not been promoted during the backup.
9178  */
9179  if (state->started_in_recovery && !backup_stopped_in_recovery)
9180  ereport(ERROR,
9181  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
9182  errmsg("the standby was promoted during online backup"),
9183  errhint("This means that the backup being taken is corrupt "
9184  "and should not be used. "
9185  "Try taking another online backup.")));
9186 
9187  /*
9188  * During recovery, we don't write an end-of-backup record. We assume that
9189  * pg_control was backed up last and its minimum recovery point can be
9190  * available as the backup end location. Since we don't have an
9191  * end-of-backup record, we use the pg_control value to check whether
9192  * we've reached the end of backup when starting recovery from this
9193  * backup. We have no way of checking if pg_control wasn't backed up last
9194  * however.
9195  *
9196  * We don't force a switch to new WAL file but it is still possible to
9197  * wait for all the required files to be archived if waitforarchive is
9198  * true. This is okay if we use the backup to start a standby and fetch
9199  * the missing WAL using streaming replication. But in the case of an
9200  * archive recovery, a user should set waitforarchive to true and wait for
9201  * them to be archived to ensure that all the required files are
9202  * available.
9203  *
9204  * We return the current minimum recovery point as the backup end
9205  * location. Note that it can be greater than the exact backup end
9206  * location if the minimum recovery point is updated after the backup of
9207  * pg_control. This is harmless for current uses.
9208  *
9209  * XXX currently a backup history file is for informational and debug
9210  * purposes only. It's not essential for an online backup. Furthermore,
9211  * even if it's created, it will not be archived during recovery because
9212  * an archiver is not invoked. So it doesn't seem worthwhile to write a
9213  * backup history file during recovery.
9214  */
9215  if (backup_stopped_in_recovery)
9216  {
9217  XLogRecPtr recptr;
9218 
9219  /*
9220  * Check to see if all WAL replayed during online backup contain
9221  * full-page writes.
9222  */
9224  recptr = XLogCtl->lastFpwDisableRecPtr;
9226 
9227  if (state->startpoint <= recptr)
9228  ereport(ERROR,
9229  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
9230  errmsg("WAL generated with \"full_page_writes=off\" was replayed "
9231  "during online backup"),
9232  errhint("This means that the backup being taken on the standby "
9233  "is corrupt and should not be used. "
9234  "Enable \"full_page_writes\" and run CHECKPOINT on the primary, "
9235  "and then try an online backup again.")));
9236 
9237 
9238  LWLockAcquire(ControlFileLock, LW_SHARED);
9239  state->stoppoint = ControlFile->minRecoveryPoint;
9241  LWLockRelease(ControlFileLock);
9242  }
9243  else
9244  {
9245  char *history_file;
9246 
9247  /*
9248  * Write the backup-end xlog record
9249  */
9250  XLogBeginInsert();
9251  XLogRegisterData((char *) (&state->startpoint),
9252  sizeof(state->startpoint));
9253  state->stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
9254 
9255  /*
9256  * Given that we're not in recovery, InsertTimeLineID is set and can't
9257  * change, so we can read it without a lock.
9258  */
9259  state->stoptli = XLogCtl->InsertTimeLineID;
9260 
9261  /*
9262  * Force a switch to a new xlog segment file, so that the backup is
9263  * valid as soon as archiver moves out the current segment file.
9264  */
9265  RequestXLogSwitch(false);
9266 
9267  state->stoptime = (pg_time_t) time(NULL);
9268 
9269  /*
9270  * Write the backup history file
9271  */
9272  XLByteToSeg(state->startpoint, _logSegNo, wal_segment_size);
9273  BackupHistoryFilePath(histfilepath, state->stoptli, _logSegNo,
9274  state->startpoint, wal_segment_size);
9275  fp = AllocateFile(histfilepath, "w");
9276  if (!fp)
9277  ereport(ERROR,
9279  errmsg("could not create file \"%s\": %m",
9280  histfilepath)));
9281 
9282  /* Build and save the contents of the backup history file */
9283  history_file = build_backup_content(state, true);
9284  fprintf(fp, "%s", history_file);
9285  pfree(history_file);
9286 
9287  if (fflush(fp) || ferror(fp) || FreeFile(fp))
9288  ereport(ERROR,
9290  errmsg("could not write file \"%s\": %m",
9291  histfilepath)));
9292 
9293  /*
9294  * Clean out any no-longer-needed history files. As a side effect,
9295  * this will post a .ready file for the newly created history file,
9296  * notifying the archiver that history file may be archived
9297  * immediately.
9298  */
9300  }
9301 
9302  /*
9303  * If archiving is enabled, wait for all the required WAL files to be
9304  * archived before returning. If archiving isn't enabled, the required WAL
9305  * needs to be transported via streaming replication (hopefully with
9306  * wal_keep_size set high enough), or some more exotic mechanism like
9307  * polling and copying files from pg_wal with script. We have no knowledge
9308  * of those mechanisms, so it's up to the user to ensure that he gets all
9309  * the required WAL.
9310  *
9311  * We wait until both the last WAL file filled during backup and the
9312  * history file have been archived, and assume that the alphabetic sorting
9313  * property of the WAL files ensures any earlier WAL files are safely
9314  * archived as well.
9315  *
9316  * We wait forever, since archive_command is supposed to work and we
9317  * assume the admin wanted his backup to work completely. If you don't
9318  * wish to wait, then either waitforarchive should be passed in as false,
9319  * or you can set statement_timeout. Also, some notices are issued to
9320  * clue in anyone who might be doing this interactively.
9321  */
9322 
9323  if (waitforarchive &&
9324  ((!backup_stopped_in_recovery && XLogArchivingActive()) ||
9325  (backup_stopped_in_recovery && XLogArchivingAlways())))
9326  {
9327  XLByteToPrevSeg(state->stoppoint, _logSegNo, wal_segment_size);
9328  XLogFileName(lastxlogfilename, state->stoptli, _logSegNo,
9330 
9331  XLByteToSeg(state->startpoint, _logSegNo, wal_segment_size);
9332  BackupHistoryFileName(histfilename, state->stoptli, _logSegNo,
9333  state->startpoint, wal_segment_size);
9334 
9335  seconds_before_warning = 60;
9336  waits = 0;
9337 
9338  while (XLogArchiveIsBusy(lastxlogfilename) ||
9339  XLogArchiveIsBusy(histfilename))
9340  {
9342 
9343  if (!reported_waiting && waits > 5)
9344  {
9345  ereport(NOTICE,
9346  (errmsg("base backup done, waiting for required WAL segments to be archived")));
9347  reported_waiting = true;
9348  }
9349 
9350  (void) WaitLatch(MyLatch,
9352  1000L,
9353  WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE);
9355 
9356  if (++waits >= seconds_before_warning)
9357  {
9358  seconds_before_warning *= 2; /* This wraps in >10 years... */
9359  ereport(WARNING,
9360  (errmsg("still waiting for all required WAL segments to be archived (%d seconds elapsed)",
9361  waits),
9362  errhint("Check that your \"archive_command\" is executing properly. "
9363  "You can safely cancel this backup, "
9364  "but the database backup will not be usable without all the WAL segments.")));
9365  }
9366  }
9367 
9368  ereport(NOTICE,
9369  (errmsg("all required WAL segments have been archived")));
9370  }
9371  else if (waitforarchive)
9372  ereport(NOTICE,
9373  (errmsg("WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup")));
9374 }
#define NOTICE
Definition: elog.h:35
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2605
int FreeFile(FILE *file)
Definition: fd.c:2803
struct Latch * MyLatch
Definition: globals.c:62
void ResetLatch(Latch *latch)
Definition: latch.c:724
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:517
#define WL_TIMEOUT
Definition: latch.h:130
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:132
#define WL_LATCH_SET
Definition: latch.h:127
static void const char fflush(stdout)
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
#define XLOG_BACKUP_END
Definition: pg_control.h:73
#define fprintf
Definition: port.h:242
static void CleanupBackupHistory(void)
Definition: xlog.c:4161
#define XLogArchivingAlways()
Definition: xlog.h:102
static void BackupHistoryFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr startpoint, int wal_segsz_bytes)
static void BackupHistoryFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr startpoint, int wal_segsz_bytes)
bool XLogArchiveIsBusy(const char *xlog)
Definition: xlogarchive.c:619
char * build_backup_content(BackupState *state, bool ishistoryfile)
Definition: xlogbackup.c:29

References AllocateFile(), Assert, BackupHistoryFileName(), BackupHistoryFilePath(), build_backup_content(), CHECK_FOR_INTERRUPTS, CleanupBackupHistory(), ControlFile, ereport, errcode(), errcode_for_file_access(), errhint(), errmsg(), ERROR, fflush(), fprintf, FreeFile(), XLogCtlData::info_lck, XLogCtlData::Insert, XLogCtlData::InsertTimeLineID, XLogCtlData::lastFpwDisableRecPtr, LW_SHARED, LWLockAcquire(), LWLockRelease(), MAXFNAMELEN, MAXPGPATH, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, MyLatch, NOTICE, pfree(), RecoveryInProgress(), RequestXLogSwitch(), ResetLatch(), XLogCtlInsert::runningBackups, SESSION_BACKUP_NONE, sessionBackupState, SpinLockAcquire, SpinLockRelease, WaitLatch(), wal_segment_size, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), WARNING, WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, WL_TIMEOUT, XLByteToPrevSeg, XLByteToSeg, XLOG_BACKUP_END, XLogArchiveIsBusy(), XLogArchivingActive, XLogArchivingAlways, XLogBeginInsert(), XLogCtl, XLogFileName(), XLogInsert(), XLogIsNeeded, and XLogRegisterData().

Referenced by perform_base_backup(), and pg_backup_stop().

◆ get_backup_status()

SessionBackupState get_backup_status ( void  )

Definition at line 9101 of file xlog.c.

9102 {
9103  return sessionBackupState;
9104 }

References sessionBackupState.

Referenced by pg_backup_start(), pg_backup_stop(), and SendBaseBackup().

◆ get_sync_bit()

static int get_sync_bit ( int  method)
static

Definition at line 8593 of file xlog.c.

8594 {
8595  int o_direct_flag = 0;
8596 
8597  /*
8598  * Use O_DIRECT if requested, except in walreceiver process. The WAL
8599  * written by walreceiver is normally read by the startup process soon
8600  * after it's written. Also, walreceiver performs unaligned writes, which
8601  * don't work with O_DIRECT, so it is required for correctness too.
8602  */
8604  o_direct_flag = PG_O_DIRECT;
8605 
8606  /* If fsync is disabled, never open in sync mode */
8607  if (!enableFsync)
8608  return o_direct_flag;
8609 
8610  switch (method)
8611  {
8612  /*
8613  * enum values for all sync options are defined even if they are
8614  * not supported on the current platform. But if not, they are
8615  * not included in the enum option array, and therefore will never
8616  * be seen here.
8617  */
8618  case WAL_SYNC_METHOD_FSYNC:
8621  return o_direct_flag;
8622 #ifdef O_SYNC
8623  case WAL_SYNC_METHOD_OPEN:
8624  return O_SYNC | o_direct_flag;
8625 #endif
8626 #ifdef O_DSYNC
8628  return O_DSYNC | o_direct_flag;
8629 #endif
8630  default:
8631  /* can't happen (unless we are out of sync with option array) */
8632  elog(ERROR, "unrecognized \"wal_sync_method\": %d", method);
8633  return 0; /* silence warning */
8634  }
8635 }
int io_direct_flags
Definition: fd.c:167
#define IO_DIRECT_WAL
Definition: fd.h:55
#define PG_O_DIRECT
Definition: fd.h:97
bool enableFsync
Definition: globals.c:128
#define AmWalReceiverProcess()
Definition: miscadmin.h:381
#define O_DSYNC
Definition: win32_port.h:352
@ WAL_SYNC_METHOD_OPEN
Definition: xlog.h:26
@ WAL_SYNC_METHOD_FDATASYNC
Definition: xlog.h:25
@ WAL_SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:27
@ WAL_SYNC_METHOD_OPEN_DSYNC
Definition: xlog.h:28
@ WAL_SYNC_METHOD_FSYNC
Definition: xlog.h:24

References AmWalReceiverProcess, elog, enableFsync, ERROR, io_direct_flags, IO_DIRECT_WAL, O_DSYNC, PG_O_DIRECT, WAL_SYNC_METHOD_FDATASYNC, WAL_SYNC_METHOD_FSYNC, WAL_SYNC_METHOD_FSYNC_WRITETHROUGH, WAL_SYNC_METHOD_OPEN, and WAL_SYNC_METHOD_OPEN_DSYNC.

Referenced by assign_wal_sync_method(), XLogFileInit(), XLogFileInitInternal(), and XLogFileOpen().

◆ GetActiveWalLevelOnStandby()

WalLevel GetActiveWalLevelOnStandby ( void  )

Definition at line 4859 of file xlog.c.

4860 {
4861  return ControlFile->wal_level;
4862 }

References ControlFile, and ControlFileData::wal_level.

Referenced by CheckLogicalDecodingRequirements().

◆ GetFakeLSNForUnloggedRel()

XLogRecPtr GetFakeLSNForUnloggedRel ( void  )

Definition at line 4604 of file xlog.c.

4605 {
4607 }
static uint64 pg_atomic_fetch_add_u64(volatile pg_atomic_uint64 *ptr, int64 add_)
Definition: atomics.h:522

References pg_atomic_fetch_add_u64(), XLogCtlData::unloggedLSN, and XLogCtl.

Referenced by gistGetFakeLSN().

◆ GetFlushRecPtr()

XLogRecPtr GetFlushRecPtr ( TimeLineID insertTLI)

Definition at line 6499 of file xlog.c.

6500 {
6502 
6504 
6505  /*
6506  * If we're writing and flushing WAL, the time line can't be changing, so
6507  * no lock is required.
6508  */
6509  if (insertTLI)
6510  *insertTLI = XLogCtl->InsertTimeLineID;
6511 
6512  return LogwrtResult.Flush;
6513 }
RecoveryState SharedRecoveryState
Definition: xlog.c:516
XLogRecPtr Flush
Definition: xlog.c:328
@ RECOVERY_STATE_DONE
Definition: xlog.h:93

References Assert, XLogwrtResult::Flush, XLogCtlData::InsertTimeLineID, LogwrtResult, RECOVERY_STATE_DONE, RefreshXLogWriteResult, XLogCtlData::SharedRecoveryState, and XLogCtl.

Referenced by binary_upgrade_logical_slot_has_caught_up(), get_flush_position(), GetCurrentLSN(), GetLatestLSN(), IdentifySystem(), pg_current_wal_flush_lsn(), pg_logical_slot_get_changes_guts(), pg_replication_slot_advance(), read_local_xlog_page_guts(), StartReplication(), WalSndWaitForWal(), XLogSendLogical(), and XLogSendPhysical().

◆ GetFullPageWriteInfo()

void GetFullPageWriteInfo ( XLogRecPtr RedoRecPtr_p,
bool *  doPageWrites_p 
)

Definition at line 6467 of file xlog.c.

6468 {
6469  *RedoRecPtr_p = RedoRecPtr;
6470  *doPageWrites_p = doPageWrites;
6471 }
static bool doPageWrites
Definition: xlog.c:286

References doPageWrites, and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )

Definition at line 6482 of file xlog.c.

6483 {
6484  XLogRecPtr recptr;
6485 
6487  recptr = XLogCtl->LogwrtRqst.Write;
6489 
6490  return recptr;
6491 }

References XLogCtlData::info_lck, XLogCtlData::LogwrtRqst, SpinLockAcquire, SpinLockRelease, XLogwrtRqst::Write, and XLogCtl.

Referenced by CheckpointerMain(), gistvacuumscan(), and IsCheckpointOnSchedule().

◆ GetLastImportantRecPtr()

XLogRecPtr GetLastImportantRecPtr ( void  )

Definition at line 6556 of file xlog.c.

6557 {
6559  int i;
6560 
6561  for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
6562  {
6563  XLogRecPtr last_important;
6564 
6565  /*
6566  * Need to take a lock to prevent torn reads of the LSN, which are
6567  * possible on some of the supported platforms. WAL insert locks only
6568  * support exclusive mode, so we have to use that.
6569  */
6571  last_important = WALInsertLocks[i].l.lastImportantAt;
6572  LWLockRelease(&WALInsertLocks[i].l.lock);
6573 
6574  if (res < last_important)
6575  res = last_important;
6576  }
6577 
6578  return res;
6579 }
int i
Definition: isn.c:72
XLogRecPtr lastImportantAt
Definition: xlog.c:371
WALInsertLock l
Definition: xlog.c:383
static WALInsertLockPadded * WALInsertLocks
Definition: xlog.c:569
#define NUM_XLOGINSERT_LOCKS
Definition: xlog.c:150

References i, InvalidXLogRecPtr, WALInsertLockPadded::l, WALInsertLock::lastImportantAt, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), NUM_XLOGINSERT_LOCKS, res, and WALInsertLocks.

Referenced by BackgroundWriterMain(), CheckArchiveTimeout(), and CreateCheckPoint().

◆ GetLastSegSwitchData()

pg_time_t GetLastSegSwitchData ( XLogRecPtr lastSwitchLSN)

Definition at line 6585 of file xlog.c.

6586 {
6587  pg_time_t result;
6588 
6589  /* Need WALWriteLock, but shared lock is sufficient */
6590  LWLockAcquire(WALWriteLock, LW_SHARED);
6591  result = XLogCtl->lastSegSwitchTime;
6592  *lastSwitchLSN = XLogCtl->lastSegSwitchLSN;
6593  LWLockRelease(WALWriteLock);
6594 
6595  return result;
6596 }
pg_time_t lastSegSwitchTime
Definition: xlog.c:467
XLogRecPtr lastSegSwitchLSN
Definition: xlog.c:468

References XLogCtlData::lastSegSwitchLSN, XLogCtlData::lastSegSwitchTime, LW_SHARED, LWLockAcquire(), LWLockRelease(), and XLogCtl.

Referenced by CheckArchiveTimeout().

◆ GetMockAuthenticationNonce()

char* GetMockAuthenticationNonce ( void  )

Definition at line 4578 of file xlog.c.

4579 {
4580  Assert(ControlFile != NULL);
4582 }
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition: pg_control.h:229

References Assert, ControlFile, and ControlFileData::mock_authentication_nonce.

Referenced by scram_mock_salt().

◆ GetOldestRestartPoint()

void GetOldestRestartPoint ( XLogRecPtr oldrecptr,
TimeLineID oldtli 
)

Definition at line 9463 of file xlog.c.

9464 {
9465  LWLockAcquire(ControlFileLock, LW_SHARED);
9466  *oldrecptr = ControlFile->checkPointCopy.redo;
9468  LWLockRelease(ControlFileLock);
9469 }

References ControlFileData::checkPointCopy, ControlFile, LW_SHARED, LWLockAcquire(), LWLockRelease(), CheckPoint::redo, and CheckPoint::ThisTimeLineID.

Referenced by ExecuteRecoveryCommand(), and RestoreArchivedFile().

◆ GetRecoveryState()

RecoveryState GetRecoveryState ( void  )

Definition at line 6370 of file xlog.c.

6371 {
6372  RecoveryState retval;
6373 
6375  retval = XLogCtl->SharedRecoveryState;
6377 
6378  return retval;
6379 }
RecoveryState
Definition: xlog.h:90

References XLogCtlData::info_lck, XLogCtlData::SharedRecoveryState, SpinLockAcquire, SpinLockRelease, and XLogCtl.

Referenced by XLogArchiveCheckDone().

◆ GetRedoRecPtr()

XLogRecPtr GetRedoRecPtr ( void  )

Definition at line 6437 of file xlog.c.

6438 {
6439  XLogRecPtr ptr;
6440 
6441  /*
6442  * The possibly not up-to-date copy in XlogCtl is enough. Even if we
6443  * grabbed a WAL insertion lock to read the authoritative value in
6444  * Insert->RedoRecPtr, someone might update it just after we've released
6445  * the lock.
6446  */
6448  ptr = XLogCtl->RedoRecPtr;
6450 
6451  if (RedoRecPtr < ptr)
6452  RedoRecPtr = ptr;
6453 
6454  return RedoRecPtr;
6455 }

References XLogCtlData::info_lck, RedoRecPtr, XLogCtlData::RedoRecPtr, SpinLockAcquire, SpinLockRelease, and XLogCtl.

Referenced by CheckPointLogicalRewriteHeap(), CheckPointSnapBuild(), MaybeRemoveOldWalSummaries(), nextval_internal(), pgstat_before_server_shutdown(), ReplicationSlotReserveWal(), smgr_bulk_finish(), smgr_bulk_start_smgr(), XLogPageRead(), XLogSaveBufferForHint(), and XLogWrite().

◆ GetSystemIdentifier()

uint64 GetSystemIdentifier ( void  )

◆ GetWALAvailability()

WALAvailability GetWALAvailability ( XLogRecPtr  targetLSN)

Definition at line 7869 of file xlog.c.

7870 {
7871  XLogRecPtr currpos; /* current write LSN */
7872  XLogSegNo currSeg; /* segid of currpos */
7873  XLogSegNo targetSeg; /* segid of targetLSN */
7874  XLogSegNo oldestSeg; /* actual oldest segid */
7875  XLogSegNo oldestSegMaxWalSize; /* oldest segid kept by max_wal_size */
7876  XLogSegNo oldestSlotSeg; /* oldest segid kept by slot */
7877  uint64 keepSegs;
7878 
7879  /*
7880  * slot does not reserve WAL. Either deactivated, or has never been active
7881  */
7882  if (XLogRecPtrIsInvalid(targetLSN))
7883  return WALAVAIL_INVALID_LSN;
7884 
7885  /*
7886  * Calculate the oldest segment currently reserved by all slots,
7887  * considering wal_keep_size and max_slot_wal_keep_size. Initialize
7888  * oldestSlotSeg to the current segment.
7889  */
7890  currpos = GetXLogWriteRecPtr();
7891  XLByteToSeg(currpos, oldestSlotSeg, wal_segment_size);
7892  KeepLogSeg(currpos, &oldestSlotSeg);
7893 
7894  /*
7895  * Find the oldest extant segment file. We get 1 until checkpoint removes
7896  * the first WAL segment file since startup, which causes the status being
7897  * wrong under certain abnormal conditions but that doesn't actually harm.
7898  */
7899  oldestSeg = XLogGetLastRemovedSegno() + 1;
7900 
7901  /* calculate oldest segment by max_wal_size */
7902  XLByteToSeg(currpos, currSeg, wal_segment_size);
7904 
7905  if (currSeg > keepSegs)
7906  oldestSegMaxWalSize = currSeg - keepSegs;
7907  else
7908  oldestSegMaxWalSize = 1;
7909 
7910  /* the segment we care about */
7911  XLByteToSeg(targetLSN, targetSeg, wal_segment_size);
7912 
7913  /*
7914  * No point in returning reserved or extended status values if the
7915  * targetSeg is known to be lost.
7916  */
7917  if (targetSeg >= oldestSlotSeg)
7918  {
7919  /* show "reserved" when targetSeg is within max_wal_size */
7920  if (targetSeg >= oldestSegMaxWalSize)
7921  return WALAVAIL_RESERVED;
7922 
7923  /* being retained by slots exceeding max_wal_size */
7924  return WALAVAIL_EXTENDED;
7925  }
7926 
7927  /* WAL segments are no longer retained but haven't been removed yet */
7928  if (targetSeg >= oldestSeg)
7929  return WALAVAIL_UNRESERVED;
7930 
7931  /* Definitely lost */
7932  return WALAVAIL_REMOVED;
7933 }
XLogSegNo XLogGetLastRemovedSegno(void)
Definition: xlog.c:3758
XLogRecPtr GetXLogWriteRecPtr(void)
Definition: xlog.c:9451
@ WALAVAIL_REMOVED
Definition: xlog.h:194
@ WALAVAIL_RESERVED
Definition: xlog.h:190
@ WALAVAIL_UNRESERVED
Definition: xlog.h:193
@ WALAVAIL_EXTENDED
Definition: xlog.h:191
@ WALAVAIL_INVALID_LSN
Definition: xlog.h:189

References ConvertToXSegs, GetXLogWriteRecPtr(), KeepLogSeg(), max_wal_size_mb, wal_segment_size, WALAVAIL_EXTENDED, WALAVAIL_INVALID_LSN, WALAVAIL_REMOVED, WALAVAIL_RESERVED, WALAVAIL_UNRESERVED, XLByteToSeg, XLogGetLastRemovedSegno(), and XLogRecPtrIsInvalid.

Referenced by pg_get_replication_slots().

◆ GetWALInsertionTimeLine()

TimeLineID GetWALInsertionTimeLine ( void  )

Definition at line 6520 of file xlog.c.

6521 {
6523 
6524  /* Since the value can't be changing, no lock is required. */
6525  return XLogCtl->InsertTimeLineID;
6526 }

References Assert, XLogCtlData::InsertTimeLineID, RECOVERY_STATE_DONE, XLogCtlData::SharedRecoveryState, and XLogCtl.

Referenced by logical_read_xlog_page(), pg_walfile_name(), pg_walfile_name_offset(), ReadReplicationSlot(), WALReadFromBuffers(), and XLogSendPhysical().

◆ GetWALInsertionTimeLineIfSet()

TimeLineID GetWALInsertionTimeLineIfSet ( void  )

Definition at line 6536 of file xlog.c.

6537 {
6538  TimeLineID insertTLI;
6539 
6541  insertTLI = XLogCtl->InsertTimeLineID;
6543 
6544  return insertTLI;
6545 }

References XLogCtlData::info_lck, XLogCtlData::InsertTimeLineID, SpinLockAcquire, SpinLockRelease, and XLogCtl.

Referenced by GetLatestLSN().

◆ GetXLogBuffer()

static char * GetXLogBuffer ( XLogRecPtr  ptr,
TimeLineID  tli 
)
static

Definition at line 1632 of file xlog.c.

1633 {
1634  int idx;
1635  XLogRecPtr endptr;
1636  static uint64 cachedPage = 0;
1637  static char *cachedPos = NULL;
1638  XLogRecPtr expectedEndPtr;
1639 
1640  /*
1641  * Fast path for the common case that we need to access again the same
1642  * page as last time.
1643  */
1644  if (ptr / XLOG_BLCKSZ == cachedPage)
1645  {
1646  Assert(((XLogPageHeader) cachedPos)->xlp_magic == XLOG_PAGE_MAGIC);
1647  Assert(((XLogPageHeader) cachedPos)->xlp_pageaddr == ptr - (ptr % XLOG_BLCKSZ));
1648  return cachedPos + ptr % XLOG_BLCKSZ;
1649  }
1650 
1651  /*
1652  * The XLog buffer cache is organized so that a page is always loaded to a
1653  * particular buffer. That way we can easily calculate the buffer a given
1654  * page must be loaded into, from the XLogRecPtr alone.
1655  */
1656  idx = XLogRecPtrToBufIdx(ptr);
1657 
1658  /*
1659  * See what page is loaded in the buffer at the moment. It could be the
1660  * page we're looking for, or something older. It can't be anything newer
1661  * - that would imply the page we're looking for has already been written
1662  * out to disk and evicted, and the caller is responsible for making sure
1663  * that doesn't happen.
1664  *
1665  * We don't hold a lock while we read the value. If someone is just about
1666  * to initialize or has just initialized the page, it's possible that we
1667  * get InvalidXLogRecPtr. That's ok, we'll grab the mapping lock (in
1668  * AdvanceXLInsertBuffer) and retry if we see anything other than the page
1669  * we're looking for.
1670  */
1671  expectedEndPtr = ptr;
1672  expectedEndPtr += XLOG_BLCKSZ - ptr % XLOG_BLCKSZ;
1673 
1674  endptr = pg_atomic_read_u64(&XLogCtl->xlblocks[idx]);
1675  if (expectedEndPtr != endptr)
1676  {
1677  XLogRecPtr initializedUpto;
1678 
1679  /*
1680  * Before calling AdvanceXLInsertBuffer(), which can block, let others
1681  * know how far we're finished with inserting the record.
1682  *
1683  * NB: If 'ptr' points to just after the page header, advertise a
1684  * position at the beginning of the page rather than 'ptr' itself. If
1685  * there are no other insertions running, someone might try to flush
1686  * up to our advertised location. If we advertised a position after
1687  * the page header, someone might try to flush the page header, even
1688  * though page might actually not be initialized yet. As the first
1689  * inserter on the page, we are effectively responsible for making
1690  * sure that it's initialized, before we let insertingAt to move past
1691  * the page header.
1692  */
1693  if (ptr % XLOG_BLCKSZ == SizeOfXLogShortPHD &&
1694  XLogSegmentOffset(ptr, wal_segment_size) > XLOG_BLCKSZ)
1695  initializedUpto = ptr - SizeOfXLogShortPHD;
1696  else if (ptr % XLOG_BLCKSZ == SizeOfXLogLongPHD &&
1697  XLogSegmentOffset(ptr, wal_segment_size) < XLOG_BLCKSZ)
1698  initializedUpto = ptr - SizeOfXLogLongPHD;
1699  else
1700  initializedUpto = ptr;
1701 
1702  WALInsertLockUpdateInsertingAt(initializedUpto);
1703 
1704  AdvanceXLInsertBuffer(ptr, tli, false);
1705  endptr = pg_atomic_read_u64(&XLogCtl->xlblocks[idx]);
1706 
1707  if (expectedEndPtr != endptr)
1708  elog(PANIC, "could not find WAL buffer for %X/%X",
1709  LSN_FORMAT_ARGS(ptr));
1710  }
1711  else
1712  {
1713  /*
1714  * Make sure the initialization of the page is visible to us, and
1715  * won't arrive later to overwrite the WAL data we write on the page.
1716  */
1718  }
1719 
1720  /*
1721  * Found the buffer holding this page. Return a pointer to the right
1722  * offset within the page.
1723  */
1724  cachedPage = ptr / XLOG_BLCKSZ;
1725  cachedPos = XLogCtl->pages + idx * (Size) XLOG_BLCKSZ;
1726 
1727  Assert(((XLogPageHeader) cachedPos)->xlp_magic == XLOG_PAGE_MAGIC);
1728  Assert(((XLogPageHeader) cachedPos)->xlp_pageaddr == ptr - (ptr % XLOG_BLCKSZ));
1729 
1730  return cachedPos + ptr % XLOG_BLCKSZ;
1731 }
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
#define pg_memory_barrier()
Definition: atomics.h:143
static void WALInsertLockUpdateInsertingAt(XLogRecPtr insertingAt)
Definition: xlog.c:1471
static void AdvanceXLInsertBuffer(XLogRecPtr upto, TimeLineID tli, bool opportunistic)
Definition: xlog.c:1985

References AdvanceXLInsertBuffer(), Assert, elog, idx(), LSN_FORMAT_ARGS, XLogCtlData::pages, PANIC, pg_atomic_read_u64(), pg_memory_barrier, SizeOfXLogLongPHD, SizeOfXLogShortPHD, wal_segment_size, WALInsertLockUpdateInsertingAt(), XLogCtlData::xlblocks, XLOG_PAGE_MAGIC, XLogCtl, XLogRecPtrToBufIdx, and XLogSegmentOffset.

Referenced by CopyXLogRecordToWAL(), and CreateOverwriteContrecordRecord().

◆ GetXLogInsertRecPtr()

XLogRecPtr GetXLogInsertRecPtr ( void  )

Definition at line 9435 of file xlog.c.

9436 {
9438  uint64 current_bytepos;
9439 
9440  SpinLockAcquire(&Insert->insertpos_lck);
9441  current_bytepos = Insert->CurrBytePos;
9442  SpinLockRelease(&Insert->insertpos_lck);
9443 
9444  return XLogBytePosToRecPtr(current_bytepos);
9445 }

References XLogCtlData::Insert, Insert(), SpinLockAcquire, SpinLockRelease, XLogBytePosToRecPtr(), and XLogCtl.

Referenced by CreateOverwriteContrecordRecord(), gistGetFakeLSN(), logical_begin_heap_rewrite(), pg_current_wal_insert_lsn(), and ReplicationSlotReserveWal().

◆ GetXLogWriteRecPtr()

XLogRecPtr GetXLogWriteRecPtr ( void  )

◆ InitControlFile()

static void InitControlFile ( uint64  sysidentifier,
uint32  data_checksum_version 
)
static

Definition at line 4204 of file xlog.c.

4205 {
4206  char mock_auth_nonce[MOCK_AUTH_NONCE_LEN];
4207 
4208  /*
4209  * Generate a random nonce. This is used for authentication requests that
4210  * will fail because the user does not exist. The nonce is used to create
4211  * a genuine-looking password challenge for the non-existent user, in lieu
4212  * of an actual stored password.
4213  */
4214  if (!pg_strong_random(mock_auth_nonce, MOCK_AUTH_NONCE_LEN))
4215  ereport(PANIC,
4216  (errcode(ERRCODE_INTERNAL_ERROR),
4217  errmsg("could not generate secret authorization token")));
4218 
4219  memset(ControlFile, 0, sizeof(ControlFileData));
4220  /* Initialize pg_control status fields */
4221  ControlFile->system_identifier = sysidentifier;
4222  memcpy(ControlFile->mock_authentication_nonce, mock_auth_nonce, MOCK_AUTH_NONCE_LEN);
4225 
4226  /* Set important parameter values for use when replaying WAL */
4235  ControlFile->data_checksum_version = data_checksum_version;
4236 }
bool track_commit_timestamp
Definition: commit_ts.c:109
#define MOCK_AUTH_NONCE_LEN
Definition: pg_control.h:28
bool pg_strong_random(void *buf, size_t len)
bool track_commit_timestamp
Definition: pg_control.h:185
bool wal_log_hints
Definition: xlog.c:123
#define FirstNormalUnloggedLSN
Definition: xlogdefs.h:36

References ControlFile, ControlFileData::data_checksum_version, DB_SHUTDOWNED, ereport, errcode(), errmsg(), FirstNormalUnloggedLSN, max_locks_per_xact, ControlFileData::max_locks_per_xact, max_prepared_xacts, ControlFileData::max_prepared_xacts, max_wal_senders, ControlFileData::max_wal_senders, max_worker_processes, ControlFileData::max_worker_processes, MaxConnections, ControlFileData::MaxConnections, MOCK_AUTH_NONCE_LEN, ControlFileData::mock_authentication_nonce, PANIC, pg_strong_random(), ControlFileData::state, ControlFileData::system_identifier, track_commit_timestamp, ControlFileData::track_commit_timestamp, ControlFileData::unloggedLSN, wal_level, ControlFileData::wal_level, wal_log_hints, and ControlFileData::wal_log_hints.

Referenced by BootStrapXLOG().

◆ InitializeWalConsistencyChecking()

void InitializeWalConsistencyChecking ( void  )

Definition at line 4784 of file xlog.c.

4785 {
4787 
4789  {
4790  struct config_generic *guc;
4791 
4792  guc = find_option("wal_consistency_checking", false, false, ERROR);
4793 
4795 
4796  set_config_option_ext("wal_consistency_checking",
4798  guc->scontext, guc->source, guc->srole,
4799  GUC_ACTION_SET, true, ERROR, false);
4800 
4801  /* checking should not be deferred again */
4803  }
4804 }
struct config_generic * find_option(const char *name, bool create_placeholders, bool skip_errors, int elevel)
Definition: guc.c:1235
int set_config_option_ext(const char *name, const char *value, GucContext context, GucSource source, Oid srole, GucAction action, bool changeVal, int elevel, bool is_reload)
Definition: guc.c:3382
@ GUC_ACTION_SET
Definition: guc.h:199
GucContext scontext
Definition: guc_tables.h:167
GucSource source
Definition: guc_tables.h:165
char * wal_consistency_checking_string
Definition: xlog.c:125

References Assert, check_wal_consistency_checking_deferred, ERROR, find_option(), GUC_ACTION_SET, process_shared_preload_libraries_done, config_generic::scontext, set_config_option_ext(), config_generic::source, config_generic::srole, and wal_consistency_checking_string.

Referenced by PostgresSingleUserMain(), and PostmasterMain().

◆ InstallXLogFileSegment()

static bool InstallXLogFileSegment ( XLogSegNo segno,
char *  tmppath,
bool  find_free,
XLogSegNo  max_segno,
TimeLineID  tli 
)
static

Definition at line 3563 of file xlog.c.

3565 {
3566  char path[MAXPGPATH];
3567  struct stat stat_buf;
3568 
3569  Assert(tli != 0);
3570 
3571  XLogFilePath(path, tli, *segno, wal_segment_size);
3572 
3573  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
3575  {
3576  LWLockRelease(ControlFileLock);
3577  return false;
3578  }
3579 
3580  if (!find_free)
3581  {
3582  /* Force installation: get rid of any pre-existing segment file */
3583  durable_unlink(path, DEBUG1);
3584  }
3585  else
3586  {
3587  /* Find a free slot to put it in */
3588  while (stat(path, &stat_buf) == 0)
3589  {
3590  if ((*segno) >= max_segno)
3591  {
3592  /* Failed to find a free slot within specified range */
3593  LWLockRelease(ControlFileLock);
3594  return false;
3595  }
3596  (*segno)++;
3597  XLogFilePath(path, tli, *segno, wal_segment_size);
3598  }
3599  }
3600 
3601  Assert(access(path, F_OK) != 0 && errno == ENOENT);
3602  if (durable_rename(tmppath, path, LOG) != 0)
3603  {
3604  LWLockRelease(ControlFileLock);
3605  /* durable_rename already emitted log message */
3606  return false;
3607  }
3608 
3609  LWLockRelease(ControlFileLock);
3610 
3611  return true;
3612 }
int durable_unlink(const char *fname, int elevel)
Definition: fd.c:871
short access
Definition: preproc-type.c:36
bool InstallXLogFileSegmentActive
Definition: xlog.c:526
#define stat
Definition: win32_port.h:284

References Assert, DEBUG1, durable_rename(), durable_unlink(), XLogCtlData::InstallXLogFileSegmentActive, LOG, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MAXPGPATH, stat, wal_segment_size, XLogCtl, and XLogFilePath().

Referenced by RemoveXlogFile(), XLogFileCopy(), and XLogFileInitInternal().

◆ IsInstallXLogFileSegmentActive()

bool IsInstallXLogFileSegmentActive ( void  )

Definition at line 9492 of file xlog.c.

9493 {
9494  bool result;
9495 
9496  LWLockAcquire(ControlFileLock, LW_SHARED);
9498  LWLockRelease(ControlFileLock);
9499 
9500  return result;
9501 }

References XLogCtlData::InstallXLogFileSegmentActive, LW_SHARED, LWLockAcquire(), LWLockRelease(), and XLogCtl.

Referenced by XLogFileRead().

◆ issue_xlog_fsync()

void issue_xlog_fsync ( int  fd,
XLogSegNo  segno,
TimeLineID  tli 
)

Definition at line 8683 of file xlog.c.

8684 {
8685  char *msg = NULL;
8686  instr_time start;
8687 
8688  Assert(tli != 0);
8689 
8690  /*
8691  * Quick exit if fsync is disabled or write() has already synced the WAL
8692  * file.
8693  */
8694  if (!enableFsync ||
8697  return;
8698 
8699  /* Measure I/O timing to sync the WAL file */
8700  if (track_wal_io_timing)
8702  else
8704 
8705  pgstat_report_wait_start(WAIT_EVENT_WAL_SYNC);
8706  switch (wal_sync_method)
8707  {
8708  case WAL_SYNC_METHOD_FSYNC:
8709  if (pg_fsync_no_writethrough(fd) != 0)
8710  msg = _("could not fsync file \"%s\": %m");
8711  break;
8712 #ifdef HAVE_FSYNC_WRITETHROUGH
8714  if (pg_fsync_writethrough(fd) != 0)
8715  msg = _("could not fsync write-through file \"%s\": %m");
8716  break;
8717 #endif
8719  if (pg_fdatasync(fd) != 0)
8720  msg = _("could not fdatasync file \"%s\": %m");
8721  break;
8722  case WAL_SYNC_METHOD_OPEN:
8724  /* not reachable */
8725  Assert(false);
8726  break;
8727  default:
8728  ereport(PANIC,
8729  errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8730  errmsg_internal("unrecognized \"wal_sync_method\": %d", wal_sync_method));
8731  break;
8732  }
8733 
8734  /* PANIC if failed to fsync */
8735  if (msg)
8736  {
8737  char xlogfname[MAXFNAMELEN];
8738  int save_errno = errno;
8739 
8740  XLogFileName(xlogfname, tli, segno, wal_segment_size);
8741  errno = save_errno;
8742  ereport(PANIC,
8744  errmsg(msg, xlogfname)));
8745  }
8746 
8748 
8749  /*
8750  * Increment the I/O timing and the number of times WAL files were synced.
8751  */
8752  if (track_wal_io_timing)
8753  {
8754  instr_time end;
8755 
8758  }
8759 
8761 }
#define _(x)
Definition: elog.c:90
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:440
int pg_fdatasync(int fd)
Definition: fd.c:479
int pg_fsync_writethrough(int fd)
Definition: fd.c:460
return str start
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:122
#define INSTR_TIME_SET_ZERO(t)
Definition: instr_time.h:172
#define INSTR_TIME_ACCUM_DIFF(x, y, z)
Definition: instr_time.h:184
static int fd(const char *x, int i)
Definition: preproc-init.c:105
instr_time wal_sync_time
Definition: pgstat.h:508
PgStat_Counter wal_sync
Definition: pgstat.h:506
bool track_wal_io_timing
Definition: xlog.c:137

References _, Assert, enableFsync, ereport, errcode(), errcode_for_file_access(), errmsg(), errmsg_internal(), fd(), INSTR_TIME_ACCUM_DIFF, INSTR_TIME_SET_CURRENT, INSTR_TIME_SET_ZERO, MAXFNAMELEN, PANIC, PendingWalStats, pg_fdatasync(), pg_fsync_no_writethrough(), pg_fsync_writethrough(), pgstat_report_wait_end(), pgstat_report_wait_start(), start, track_wal_io_timing, wal_segment_size, PgStat_PendingWalStats::wal_sync, wal_sync_method, WAL_SYNC_METHOD_FDATASYNC, WAL_SYNC_METHOD_FSYNC, WAL_SYNC_METHOD_FSYNC_WRITETHROUGH, WAL_SYNC_METHOD_OPEN, WAL_SYNC_METHOD_OPEN_DSYNC, PgStat_PendingWalStats::wal_sync_time, and XLogFileName().

Referenced by XLogWalRcvFlush(), and XLogWrite().

◆ KeepLogSeg()

static void KeepLogSeg ( XLogRecPtr  recptr,
XLogSegNo logSegNo 
)
static

Definition at line 7953 of file xlog.c.

7954 {
7955  XLogSegNo currSegNo;
7956  XLogSegNo segno;
7957  XLogRecPtr keep;
7958 
7959  XLByteToSeg(recptr, currSegNo, wal_segment_size);
7960  segno = currSegNo;
7961 
7962  /*
7963  * Calculate how many segments are kept by slots first, adjusting for
7964  * max_slot_wal_keep_size.
7965  */
7967  if (keep != InvalidXLogRecPtr && keep < recptr)
7968  {
7969  XLByteToSeg(keep, segno, wal_segment_size);
7970 
7971  /* Cap by max_slot_wal_keep_size ... */
7972  if (max_slot_wal_keep_size_mb >= 0)
7973  {
7974  uint64 slot_keep_segs;
7975 
7976  slot_keep_segs =
7978 
7979  if (currSegNo - segno > slot_keep_segs)
7980  segno = currSegNo - slot_keep_segs;
7981  }
7982  }
7983 
7984  /*
7985  * If WAL summarization is in use, don't remove WAL that has yet to be
7986  * summarized.
7987  */
7988  keep = GetOldestUnsummarizedLSN(NULL, NULL);
7989  if (keep != InvalidXLogRecPtr)
7990  {
7991  XLogSegNo unsummarized_segno;
7992 
7993  XLByteToSeg(keep, unsummarized_segno, wal_segment_size);
7994  if (unsummarized_segno < segno)
7995  segno = unsummarized_segno;
7996  }
7997 
7998  /* but, keep at least wal_keep_size if that's set */
7999  if (wal_keep_size_mb > 0)
8000  {
8001  uint64 keep_segs;
8002 
8004  if (currSegNo - segno < keep_segs)
8005  {
8006  /* avoid underflow, don't go below 1 */
8007  if (currSegNo <= keep_segs)
8008  segno = 1;
8009  else
8010  segno = currSegNo - keep_segs;
8011  }
8012  }
8013 
8014  /* don't delete WAL segments newer than the calculated segment */
8015  if (segno < *logSegNo)
8016  *logSegNo = segno;
8017 }
XLogRecPtr GetOldestUnsummarizedLSN(TimeLineID *tli, bool *lsn_is_exact)
int wal_keep_size_mb
Definition: xlog.c:116
static XLogRecPtr XLogGetReplicationSlotMinimumLSN(void)
Definition: xlog.c:2701
int max_slot_wal_keep_size_mb
Definition: xlog.c:135

References ConvertToXSegs, GetOldestUnsummarizedLSN(), InvalidXLogRecPtr, max_slot_wal_keep_size_mb, wal_keep_size_mb, wal_segment_size, XLByteToSeg, and XLogGetReplicationSlotMinimumLSN().

Referenced by CreateCheckPoint(), CreateRestartPoint(), and GetWALAvailability().

◆ LocalProcessControlFile()

void LocalProcessControlFile ( bool  reset)

Definition at line 4846 of file xlog.c.

4847 {
4848  Assert(reset || ControlFile == NULL);
4849  ControlFile = palloc(sizeof(ControlFileData));
4850  ReadControlFile();
4851 }
void reset(void)
Definition: sql-declare.c:600

References Assert, ControlFile, palloc(), ReadControlFile(), and reset().

Referenced by PostgresSingleUserMain(), PostmasterMain(), and PostmasterStateMachine().

◆ LocalSetXLogInsertAllowed()

static int LocalSetXLogInsertAllowed ( void  )
static

Definition at line 6422 of file xlog.c.

6423 {
6424  int oldXLogAllowed = LocalXLogInsertAllowed;
6425 
6427 
6428  return oldXLogAllowed;
6429 }

References LocalXLogInsertAllowed.

Referenced by CreateCheckPoint(), and StartupXLOG().

◆ LogCheckpointEnd()

static void LogCheckpointEnd ( bool  restartpoint)
static

Definition at line 6681 of file xlog.c.

6682 {
6683  long write_msecs,
6684  sync_msecs,
6685  total_msecs,
6686  longest_msecs,
6687  average_msecs;
6688  uint64 average_sync_time;
6689 
6691 
6694 
6697 
6698  /* Accumulate checkpoint timing summary data, in milliseconds. */
6699  PendingCheckpointerStats.write_time += write_msecs;
6700  PendingCheckpointerStats.sync_time += sync_msecs;
6701 
6702  /*
6703  * All of the published timing statistics are accounted for. Only
6704  * continue if a log message is to be written.
6705  */
6706  if (!log_checkpoints)
6707  return;
6708 
6711 
6712  /*
6713  * Timing values returned from CheckpointStats are in microseconds.
6714  * Convert to milliseconds for consistent printing.
6715  */
6716  longest_msecs = (long) ((CheckpointStats.ckpt_longest_sync + 999) / 1000);
6717 
6718  average_sync_time = 0;
6720  average_sync_time = CheckpointStats.ckpt_agg_sync_time /
6722  average_msecs = (long) ((average_sync_time + 999) / 1000);
6723 
6724  /*
6725  * ControlFileLock is not required to see ControlFile->checkPoint and
6726  * ->checkPointCopy here as we are the only updator of those variables at
6727  * this moment.
6728  */
6729  if (restartpoint)
6730  ereport(LOG,
6731  (errmsg("restartpoint complete: wrote %d buffers (%.1f%%), "
6732  "wrote %d SLRU buffers; %d WAL file(s) added, "
6733  "%d removed, %d recycled; write=%ld.%03d s, "
6734  "sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, "
6735  "longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, "
6736  "estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X",
6738  (double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
6743  write_msecs / 1000, (int) (write_msecs % 1000),
6744  sync_msecs / 1000, (int) (sync_msecs % 1000),
6745  total_msecs / 1000, (int) (total_msecs % 1000),
6747  longest_msecs / 1000, (int) (longest_msecs % 1000),
6748  average_msecs / 1000, (int) (average_msecs % 1000),
6749  (int) (PrevCheckPointDistance / 1024.0),
6750  (int) (CheckPointDistanceEstimate / 1024.0),
6753  else
6754  ereport(LOG,
6755  (errmsg("checkpoint complete: wrote %d buffers (%.1f%%), "
6756  "wrote %d SLRU buffers; %d WAL file(s) added, "
6757  "%d removed, %d recycled; write=%ld.%03d s, "
6758  "sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, "
6759  "longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, "
6760  "estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X",
6762  (double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
6767  write_msecs / 1000, (int) (write_msecs % 1000),
6768  sync_msecs / 1000, (int) (sync_msecs % 1000),
6769  total_msecs / 1000, (int) (total_msecs % 1000),
6771  longest_msecs / 1000, (int) (longest_msecs % 1000),
6772  average_msecs / 1000, (int) (average_msecs % 1000),
6773  (int) (PrevCheckPointDistance / 1024.0),
6774  (int) (CheckPointDistanceEstimate / 1024.0),
6777 }
long TimestampDifferenceMilliseconds(TimestampTz start_time, TimestampTz stop_time)
Definition: timestamp.c:1756
PgStat_CheckpointerStats PendingCheckpointerStats
uint64 ckpt_agg_sync_time
Definition: xlog.h:176
uint64 ckpt_longest_sync
Definition: xlog.h:175
TimestampTz ckpt_end_t
Definition: xlog.h:165
int ckpt_slru_written
Definition: xlog.h:168
int ckpt_sync_rels
Definition: xlog.h:174
PgStat_Counter sync_time
Definition: pgstat.h:317
PgStat_Counter write_time
Definition: pgstat.h:316
static double CheckPointDistanceEstimate
Definition: xlog.c:159
static double PrevCheckPointDistance
Definition: xlog.c:160

References ControlFileData::checkPoint, ControlFileData::checkPointCopy, CheckPointDistanceEstimate, CheckpointStats, CheckpointStatsData::ckpt_agg_sync_time, CheckpointStatsData::ckpt_bufs_written, CheckpointStatsData::ckpt_end_t, CheckpointStatsData::ckpt_longest_sync, CheckpointStatsData::ckpt_segs_added, CheckpointStatsData::ckpt_segs_recycled, CheckpointStatsData::ckpt_segs_removed, CheckpointStatsData::ckpt_slru_written, CheckpointStatsData::ckpt_start_t, CheckpointStatsData::ckpt_sync_end_t, CheckpointStatsData::ckpt_sync_rels, CheckpointStatsData::ckpt_sync_t, CheckpointStatsData::ckpt_write_t, ControlFile, ereport, errmsg(), GetCurrentTimestamp(), LOG, log_checkpoints, LSN_FORMAT_ARGS, NBuffers, PendingCheckpointerStats, PrevCheckPointDistance, CheckPoint::redo, PgStat_CheckpointerStats::sync_time, TimestampDifferenceMilliseconds(), and PgStat_CheckpointerStats::write_time.

Referenced by CreateCheckPoint(), and CreateRestartPoint().

◆ LogCheckpointStart()

static void LogCheckpointStart ( int  flags,
bool  restartpoint 
)
static

Definition at line 6649 of file xlog.c.

6650 {
6651  if (restartpoint)
6652  ereport(LOG,
6653  /* translator: the placeholders show checkpoint options */
6654  (errmsg("restartpoint starting:%s%s%s%s%s%s%s%s",
6655  (flags & CHECKPOINT_IS_SHUTDOWN) ? " shutdown" : "",
6656  (flags & CHECKPOINT_END_OF_RECOVERY) ? " end-of-recovery" : "",
6657  (flags & CHECKPOINT_IMMEDIATE) ? " immediate" : "",
6658  (flags & CHECKPOINT_FORCE) ? " force" : "",
6659  (flags & CHECKPOINT_WAIT) ? " wait" : "",
6660  (flags & CHECKPOINT_CAUSE_XLOG) ? " wal" : "",
6661  (flags & CHECKPOINT_CAUSE_TIME) ? " time" : "",
6662  (flags & CHECKPOINT_FLUSH_ALL) ? " flush-all" : "")));
6663  else
6664  ereport(LOG,
6665  /* translator: the placeholders show checkpoint options */
6666  (errmsg("checkpoint starting:%s%s%s%s%s%s%s%s",
6667  (flags & CHECKPOINT_IS_SHUTDOWN) ? " shutdown" : "",
6668  (flags & CHECKPOINT_END_OF_RECOVERY) ? " end-of-recovery" : "",
6669  (flags & CHECKPOINT_IMMEDIATE) ? " immediate" : "",
6670  (flags & CHECKPOINT_FORCE) ? " force" : "",
6671  (flags & CHECKPOINT_WAIT) ? " wait" : "",
6672  (flags & CHECKPOINT_CAUSE_XLOG) ? " wal" : "",
6673  (flags & CHECKPOINT_CAUSE_TIME) ? " time" : "",
6674  (flags & CHECKPOINT_FLUSH_ALL) ? " flush-all" : "")));
6675 }
#define CHECKPOINT_CAUSE_XLOG
Definition: xlog.h:148
#define CHECKPOINT_FLUSH_ALL
Definition: xlog.h:143
#define CHECKPOINT_CAUSE_TIME
Definition: xlog.h:149

References CHECKPOINT_CAUSE_TIME, CHECKPOINT_CAUSE_XLOG, CHECKPOINT_END_OF_RECOVERY, CHECKPOINT_FLUSH_ALL, CHECKPOINT_FORCE, CHECKPOINT_IMMEDIATE, CHECKPOINT_IS_SHUTDOWN, CHECKPOINT_WAIT, ereport, errmsg(), and LOG.

Referenced by CreateCheckPoint(), and CreateRestartPoint().

◆ PerformRecoveryXLogAction()

static bool PerformRecoveryXLogAction ( void  )
static

Definition at line 6284 of file xlog.c.

6285 {
6286  bool promoted = false;
6287 
6288  /*
6289  * Perform a checkpoint to update all our recovery activity to disk.
6290  *
6291  * Note that we write a shutdown checkpoint rather than an on-line one.
6292  * This is not particularly critical, but since we may be assigning a new
6293  * TLI, using a shutdown checkpoint allows us to have the rule that TLI
6294  * only changes in shutdown checkpoints, which allows some extra error
6295  * checking in xlog_redo.
6296  *
6297  * In promotion, only create a lightweight end-of-recovery record instead
6298  * of a full checkpoint. A checkpoint is requested later, after we're
6299  * fully out of recovery mode and already accepting queries.
6300  */
6303  {
6304  promoted = true;
6305 
6306  /*
6307  * Insert a special WAL record to mark the end of recovery, since we
6308  * aren't doing a checkpoint. That means that the checkpointer process
6309  * may likely be in the middle of a time-smoothed restartpoint and
6310  * could continue to be for minutes after this. That sounds strange,
6311  * but the effect is roughly the same and it would be stranger to try
6312  * to come out of the restartpoint and then checkpoint. We request a
6313  * checkpoint later anyway, just for safety.
6314  */
6316  }
6317  else
6318  {
6321  CHECKPOINT_WAIT);
6322  }
6323 
6324  return promoted;
6325 }
static void CreateEndOfRecoveryRecord(void)
Definition: xlog.c:7375
bool PromoteIsTriggered(void)

References ArchiveRecoveryRequested, CHECKPOINT_END_OF_RECOVERY, CHECKPOINT_IMMEDIATE, CHECKPOINT_WAIT, CreateEndOfRecoveryRecord(), IsUnderPostmaster, PromoteIsTriggered(), and RequestCheckpoint().

Referenced by StartupXLOG().

◆ PreallocXlogFiles()

static void PreallocXlogFiles ( XLogRecPtr  endptr,
TimeLineID  tli 
)
static

Definition at line 3690 of file xlog.c.

3691 {
3692  XLogSegNo _logSegNo;
3693  int lf;
3694  bool added;
3695  char path[MAXPGPATH];
3696  uint64 offset;
3697 
3699  return; /* unlocked check says no */
3700 
3701  XLByteToPrevSeg(endptr, _logSegNo, wal_segment_size);
3702  offset = XLogSegmentOffset(endptr - 1, wal_segment_size);
3703  if (offset >= (uint32) (0.75 * wal_segment_size))
3704  {
3705  _logSegNo++;
3706  lf = XLogFileInitInternal(_logSegNo, tli, &added, path);
3707  if (lf >= 0)
3708  close(lf);
3709  if (added)
3711  }
3712 }
static int XLogFileInitInternal(XLogSegNo logsegno, TimeLineID logtli, bool *added, char *path)
Definition: xlog.c:3210

References CheckpointStats, CheckpointStatsData::ckpt_segs_added, close, XLogCtlData::InstallXLogFileSegmentActive, MAXPGPATH, wal_segment_size, XLByteToPrevSeg, XLogCtl, XLogFileInitInternal(), and XLogSegmentOffset.

Referenced by CreateCheckPoint(), CreateRestartPoint(), and StartupXLOG().

◆ ReachedEndOfBackup()

void ReachedEndOfBackup ( XLogRecPtr  EndRecPtr,
TimeLineID  tli 
)

Definition at line 6247 of file xlog.c.

6248 {
6249  /*
6250  * We have reached the end of base backup, as indicated by pg_control. The
6251  * data on disk is now consistent (unless minRecoveryPoint is further
6252  * ahead, which can happen if we crashed during previous recovery). Reset
6253  * backupStartPoint and backupEndPoint, and update minRecoveryPoint to
6254  * make sure we don't allow starting up at an earlier point even if
6255  * recovery is stopped and restarted soon after this.
6256  */
6257  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6258 
6259  if (ControlFile->minRecoveryPoint < EndRecPtr)
6260  {
6261  ControlFile->minRecoveryPoint = EndRecPtr;
6263  }
6264 
6267  ControlFile->backupEndRequired = false;
6269 
6270  LWLockRelease(ControlFileLock);
6271 }
XLogRecPtr backupStartPoint
Definition: pg_control.h:170
bool backupEndRequired
Definition: pg_control.h:172
XLogRecPtr backupEndPoint
Definition: pg_control.h:171

References ControlFileData::backupEndPoint, ControlFileData::backupEndRequired, ControlFileData::backupStartPoint, ControlFile, InvalidXLogRecPtr, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, and UpdateControlFile().

Referenced by CheckRecoveryConsistency().

◆ ReadControlFile()

static void ReadControlFile ( void  )
static

Definition at line 4321 of file xlog.c.

4322 {
4323  pg_crc32c crc;
4324  int fd;
4325  char wal_segsz_str[20];
4326  int r;
4327 
4328  /*
4329  * Read data...
4330  */
4332  O_RDWR | PG_BINARY);
4333  if (fd < 0)
4334  ereport(PANIC,
4336  errmsg("could not open file \"%s\": %m",
4337  XLOG_CONTROL_FILE)));
4338 
4339  pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_READ);
4340  r = read(fd, ControlFile, sizeof(ControlFileData));
4341  if (r != sizeof(ControlFileData))
4342  {
4343  if (r < 0)
4344  ereport(PANIC,
4346  errmsg("could not read file \"%s\": %m",
4347  XLOG_CONTROL_FILE)));
4348  else
4349  ereport(PANIC,
4351  errmsg("could not read file \"%s\": read %d of %zu",
4352  XLOG_CONTROL_FILE, r, sizeof(ControlFileData))));
4353  }
4355 
4356  close(fd);
4357 
4358  /*
4359  * Check for expected pg_control format version. If this is wrong, the
4360  * CRC check will likely fail because we'll be checking the wrong number
4361  * of bytes. Complaining about wrong version will probably be more
4362  * enlightening than complaining about wrong CRC.
4363  */
4364 
4366  ereport(FATAL,
4367  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4368