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/multixact.h"
#include "access/rewriteheap.h"
#include "access/subtrans.h"
#include "access/timeline.h"
#include "access/transam.h"
#include "access/tuptoaster.h"
#include "access/twophase.h"
#include "access/xact.h"
#include "access/xlog_internal.h"
#include "access/xloginsert.h"
#include "access/xlogreader.h"
#include "access/xlogutils.h"
#include "catalog/catversion.h"
#include "catalog/pg_control.h"
#include "catalog/pg_database.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "port/atomics.h"
#include "postmaster/bgwriter.h"
#include "postmaster/walwriter.h"
#include "postmaster/startup.h"
#include "replication/basebackup.h"
#include "replication/logical.h"
#include "replication/slot.h"
#include "replication/origin.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/pmsignal.h"
#include "storage/predicate.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/reinit.h"
#include "storage/smgr.h"
#include "storage/spin.h"
#include "utils/backend_random.h"
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/pg_lsn.h"
#include "utils/ps_status.h"
#include "utils/relmapper.h"
#include "utils/snapmgr.h"
#include "utils/timestamp.h"
#include "pg_trace.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
 
struct  XLogPageReadPrivate
 

Macros

#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)   (x / ((segsize) / (1024 * 1024)))
 
#define RecoveryRequiresIntParameter(param_name, currValue, minValue)
 

Typedefs

typedef struct XLogwrtRqst XLogwrtRqst
 
typedef struct XLogwrtResult XLogwrtResult
 
typedef union WALInsertLockPadded WALInsertLockPadded
 
typedef enum ExclusiveBackupState ExclusiveBackupState
 
typedef struct XLogCtlInsert XLogCtlInsert
 
typedef struct XLogCtlData XLogCtlData
 
typedef struct XLogPageReadPrivate XLogPageReadPrivate
 

Enumerations

enum  ExclusiveBackupState { EXCLUSIVE_BACKUP_NONE = 0, EXCLUSIVE_BACKUP_STARTING, EXCLUSIVE_BACKUP_IN_PROGRESS, EXCLUSIVE_BACKUP_STOPPING }
 
enum  XLogSource { XLOG_FROM_ANY = 0, XLOG_FROM_ARCHIVE, XLOG_FROM_PG_WAL, XLOG_FROM_STREAM }
 

Functions

static void readRecoveryCommandFile (void)
 
static void exitArchiveRecovery (TimeLineID endTLI, XLogRecPtr endOfLog)
 
static bool recoveryStopsBefore (XLogReaderState *record)
 
static bool recoveryStopsAfter (XLogReaderState *record)
 
static void recoveryPausesHere (void)
 
static bool recoveryApplyDelay (XLogReaderState *record)
 
static void SetLatestXTime (TimestampTz xtime)
 
static void SetCurrentChunkStartTime (TimestampTz xtime)
 
static void CheckRequiredParameterValues (void)
 
static void XLogReportParameters (void)
 
static void checkTimeLineSwitch (XLogRecPtr lsn, TimeLineID newTLI, TimeLineID prevTLI)
 
static void LocalSetXLogInsertAllowed (void)
 
static void CreateEndOfRecoveryRecord (void)
 
static void CheckPointGuts (XLogRecPtr checkPointRedo, int flags)
 
static void KeepLogSeg (XLogRecPtr recptr, XLogSegNo *logSegNo)
 
static XLogRecPtr XLogGetReplicationSlotMinimumLSN (void)
 
static void AdvanceXLInsertBuffer (XLogRecPtr upto, bool opportunistic)
 
static bool XLogCheckpointNeeded (XLogSegNo new_segno)
 
static void XLogWrite (XLogwrtRqst WriteRqst, bool flexible)
 
static bool InstallXLogFileSegment (XLogSegNo *segno, char *tmppath, bool find_free, XLogSegNo max_segno, bool use_lock)
 
static int XLogFileRead (XLogSegNo segno, int emode, TimeLineID tli, int source, bool notfoundOk)
 
static int XLogFileReadAnyTLI (XLogSegNo segno, int emode, int source)
 
static int XLogPageRead (XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char *readBuf, TimeLineID *readTLI)
 
static bool WaitForWALToBecomeAvailable (XLogRecPtr RecPtr, bool randAccess, bool fetching_ckpt, XLogRecPtr tliRecPtr)
 
static int emode_for_corrupt_record (int emode, XLogRecPtr RecPtr)
 
static void XLogFileClose (void)
 
static void PreallocXlogFiles (XLogRecPtr endptr)
 
static void RemoveTempXlogFiles (void)
 
static void RemoveOldXlogFiles (XLogSegNo segno, XLogRecPtr RedoRecPtr, XLogRecPtr endptr)
 
static void RemoveXlogFile (const char *segname, XLogRecPtr RedoRecPtr, XLogRecPtr endptr)
 
static void UpdateLastRemovedPtr (char *filename)
 
static void ValidateXLOGDirectoryStructure (void)
 
static void CleanupBackupHistory (void)
 
static void UpdateMinRecoveryPoint (XLogRecPtr lsn, bool force)
 
static XLogRecordReadRecord (XLogReaderState *xlogreader, XLogRecPtr RecPtr, int emode, bool fetching_ckpt)
 
static void CheckRecoveryConsistency (void)
 
static XLogRecordReadCheckpointRecord (XLogReaderState *xlogreader, XLogRecPtr RecPtr, int whichChkpti, bool report)
 
static bool rescanLatestTimeLine (void)
 
static void WriteControlFile (void)
 
static void ReadControlFile (void)
 
static char * str_time (pg_time_t tnow)
 
static bool CheckForStandbyTrigger (void)
 
static void xlog_outdesc (StringInfo buf, XLogReaderState *record)
 
static void pg_start_backup_callback (int code, Datum arg)
 
static void pg_stop_backup_callback (int code, Datum arg)
 
static bool read_backup_label (XLogRecPtr *checkPointLoc, bool *backupEndRequired, bool *backupFromStandby)
 
static bool read_tablespace_map (List **tablespaces)
 
static void rm_redo_error_callback (void *arg)
 
static int get_sync_bit (int method)
 
static void CopyXLogRecordToWAL (int write_len, bool isLogSwitch, XLogRecData *rdata, XLogRecPtr StartPos, XLogRecPtr EndPos)
 
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)
 
static XLogRecPtr XLogBytePosToRecPtr (uint64 bytepos)
 
static XLogRecPtr XLogBytePosToEndRecPtr (uint64 bytepos)
 
static uint64 XLogRecPtrToBytePos (XLogRecPtr ptr)
 
static void checkXLogConsistency (XLogReaderState *record)
 
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)
 
static void CalculateCheckpointSegments (void)
 
void assign_max_wal_size (int newval, void *extra)
 
void assign_checkpoint_completion_target (double newval, void *extra)
 
static XLogSegNo XLOGfileslop (XLogRecPtr RedoRecPtr)
 
void XLogSetAsyncXactLSN (XLogRecPtr asyncXactLSN)
 
void XLogSetReplicationSlotMinimumLSN (XLogRecPtr lsn)
 
void XLogFlush (XLogRecPtr record)
 
bool XLogBackgroundFlush (void)
 
bool XLogNeedsFlush (XLogRecPtr record)
 
int XLogFileInit (XLogSegNo logsegno, bool *use_existent, bool use_lock)
 
static void XLogFileCopy (XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno, int upto)
 
int XLogFileOpen (XLogSegNo segno)
 
void CheckXLogRemoved (XLogSegNo segno, TimeLineID tli)
 
XLogSegNo XLogGetLastRemovedSegno (void)
 
static void RemoveNonParentXlogFiles (XLogRecPtr switchpoint, TimeLineID newTLI)
 
void UpdateControlFile (void)
 
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)
 
void LocalProcessControlFile (bool reset)
 
Size XLOGShmemSize (void)
 
void XLOGShmemInit (void)
 
void BootStrapXLOG (void)
 
static bool getRecordTimestamp (XLogReaderState *record, TimestampTz *recordXtime)
 
bool RecoveryIsPaused (void)
 
void SetRecoveryPause (bool recoveryPause)
 
TimestampTz GetLatestXTime (void)
 
TimestampTz GetCurrentChunkReplayStartTime (void)
 
void GetXLogReceiptTime (TimestampTz *rtime, bool *fromStream)
 
void StartupXLOG (void)
 
bool RecoveryInProgress (void)
 
bool HotStandbyActive (void)
 
bool HotStandbyActiveInReplay (void)
 
bool XLogInsertAllowed (void)
 
void InitXLOGAccess (void)
 
XLogRecPtr GetRedoRecPtr (void)
 
void GetFullPageWriteInfo (XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p)
 
XLogRecPtr GetInsertRecPtr (void)
 
XLogRecPtr GetFlushRecPtr (void)
 
XLogRecPtr GetLastImportantRecPtr (void)
 
pg_time_t GetLastSegSwitchData (XLogRecPtr *lastSwitchLSN)
 
void GetNextXidAndEpoch (TransactionId *xid, uint32 *epoch)
 
void ShutdownXLOG (int code, Datum arg)
 
static void LogCheckpointStart (int flags, bool restartpoint)
 
static void LogCheckpointEnd (bool restartpoint)
 
static void UpdateCheckPointDistanceEstimate (uint64 nbytes)
 
void CreateCheckPoint (int flags)
 
static void RecoveryRestartPoint (const CheckPoint *checkPoint)
 
bool CreateRestartPoint (int flags)
 
void XLogPutNextOid (Oid nextOid)
 
XLogRecPtr RequestXLogSwitch (bool mark_unimportant)
 
XLogRecPtr XLogRestorePoint (const char *rpName)
 
void UpdateFullPageWrites (void)
 
void xlog_redo (XLogReaderState *record)
 
void assign_xlog_sync_method (int new_sync_method, void *extra)
 
void issue_xlog_fsync (int fd, XLogSegNo segno)
 
char * XLogFileNameP (TimeLineID tli, XLogSegNo segno)
 
XLogRecPtr do_pg_start_backup (const char *backupidstr, bool fast, TimeLineID *starttli_p, StringInfo labelfile, List **tablespaces, StringInfo tblspcmapfile, bool infotbssize, bool needtblspcmapfile)
 
SessionBackupState get_backup_status (void)
 
XLogRecPtr do_pg_stop_backup (char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 
void do_pg_abort_backup (void)
 
XLogRecPtr GetXLogReplayRecPtr (TimeLineID *replayTLI)
 
XLogRecPtr GetXLogInsertRecPtr (void)
 
XLogRecPtr GetXLogWriteRecPtr (void)
 
void GetOldestRestartPoint (XLogRecPtr *oldrecptr, TimeLineID *oldtli)
 
bool BackupInProgress (void)
 
void CancelBackup (void)
 
void RemovePromoteSignalFiles (void)
 
bool CheckPromoteSignal (void)
 
void WakeupRecovery (void)
 
void SetWalWriterSleeping (bool sleeping)
 
void XLogRequestWalReceiverReply (void)
 

Variables

uint32 bootstrap_data_checksum_version
 
int max_wal_size_mb = 1024
 
int min_wal_size_mb = 80
 
int wal_keep_segments = 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
 
bool wal_compression = false
 
char * wal_consistency_checking_string = NULL
 
boolwal_consistency_checking = NULL
 
bool log_checkpoints = false
 
int sync_method = DEFAULT_SYNC_METHOD
 
int wal_level = WAL_LEVEL_MINIMAL
 
int CommitDelay = 0
 
int CommitSiblings = 5
 
int wal_retrieve_retry_interval = 5000
 
int wal_segment_size = DEFAULT_XLOG_SEG_SIZE
 
int CheckPointSegments
 
static double CheckPointDistanceEstimate = 0
 
static double PrevCheckPointDistance = 0
 
const struct config_enum_entry sync_method_options []
 
const struct config_enum_entry archive_mode_options []
 
CheckpointStatsData CheckpointStats
 
TimeLineID ThisTimeLineID = 0
 
bool InRecovery = false
 
HotStandbyState standbyState = STANDBY_DISABLED
 
static XLogRecPtr LastRec
 
static XLogRecPtr receivedUpto = 0
 
static TimeLineID receiveTLI = 0
 
static bool lastFullPageWrites
 
static bool LocalRecoveryInProgress = true
 
static bool LocalHotStandbyActive = false
 
static int LocalXLogInsertAllowed = -1
 
bool ArchiveRecoveryRequested = false
 
bool InArchiveRecovery = false
 
static bool restoredFromArchive = false
 
static char * replay_image_masked = NULL
 
static char * master_image_masked = NULL
 
char * recoveryRestoreCommand = NULL
 
static char * recoveryEndCommand = NULL
 
static char * archiveCleanupCommand = NULL
 
static RecoveryTargetType recoveryTarget = RECOVERY_TARGET_UNSET
 
static bool recoveryTargetInclusive = true
 
static RecoveryTargetAction recoveryTargetAction = RECOVERY_TARGET_ACTION_PAUSE
 
static TransactionId recoveryTargetXid
 
static TimestampTz recoveryTargetTime
 
static char * recoveryTargetName
 
static XLogRecPtr recoveryTargetLSN
 
static int recovery_min_apply_delay = 0
 
static TimestampTz recoveryDelayUntilTime
 
static bool StandbyModeRequested = false
 
static char * PrimaryConnInfo = NULL
 
static char * PrimarySlotName = NULL
 
static char * TriggerFile = NULL
 
bool StandbyMode = false
 
static bool fast_promote = false
 
static TransactionId recoveryStopXid
 
static TimestampTz recoveryStopTime
 
static XLogRecPtr recoveryStopLSN
 
static char recoveryStopName [MAXFNAMELEN]
 
static bool recoveryStopAfter
 
static TimeLineID recoveryTargetTLI
 
static bool recoveryTargetIsLatest = false
 
static ListexpectedTLEs
 
static TimeLineID curFileTLI
 
XLogRecPtr ProcLastRecPtr = InvalidXLogRecPtr
 
XLogRecPtr XactLastRecEnd = InvalidXLogRecPtr
 
XLogRecPtr XactLastCommitEnd = InvalidXLogRecPtr
 
static XLogRecPtr RedoRecPtr
 
static bool doPageWrites
 
static bool doRequestWalReceiverReply
 
static XLogRecPtr RedoStartLSN = InvalidXLogRecPtr
 
static SessionBackupState sessionBackupState = SESSION_BACKUP_NONE
 
static XLogCtlDataXLogCtl = NULL
 
static WALInsertLockPaddedWALInsertLocks = NULL
 
static ControlFileDataControlFile = NULL
 
static int UsableBytesInSegment
 
static XLogwrtResult LogwrtResult = {0, 0}
 
static const char * xlogSourceNames [] = {"any", "archive", "pg_wal", "stream"}
 
static int openLogFile = -1
 
static XLogSegNo openLogSegNo = 0
 
static uint32 openLogOff = 0
 
static int readFile = -1
 
static XLogSegNo readSegNo = 0
 
static uint32 readOff = 0
 
static uint32 readLen = 0
 
static XLogSource readSource = 0
 
static XLogSource currentSource = 0
 
static bool lastSourceFailed = false
 
static TimestampTz XLogReceiptTime = 0
 
static XLogSource XLogReceiptSource = 0
 
static XLogRecPtr ReadRecPtr
 
static XLogRecPtr EndRecPtr
 
static XLogRecPtr minRecoveryPoint
 
static TimeLineID minRecoveryPointTLI
 
static bool updateMinRecoveryPoint = true
 
bool reachedConsistency = false
 
static bool InRedo = false
 
static bool bgwriterLaunched = false
 
static int MyLockNo = 0
 
static bool holdingAllLocks = false
 

Macro Definition Documentation

◆ ConvertToXSegs

#define ConvertToXSegs (   x,
  segsize 
)    (x / ((segsize) / (1024 * 1024)))

Definition at line 735 of file xlog.c.

Referenced by CalculateCheckpointSegments(), ReadControlFile(), and XLOGfileslop().

◆ INSERT_FREESPACE

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

Definition at line 715 of file xlog.c.

Referenced by CopyXLogRecordToWAL(), and CreateCheckPoint().

◆ NextBufIdx

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

Definition at line 719 of file xlog.c.

Referenced by XLogWrite().

◆ NUM_XLOGINSERT_LOCKS

◆ RecoveryRequiresIntParameter

#define RecoveryRequiresIntParameter (   param_name,
  currValue,
  minValue 
)
Value:
do { \
if ((currValue) < (minValue)) \
ereport(ERROR, \
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), \
errmsg("hot standby is not possible because " \
"%s = %d is a lower setting than on the master server " \
"(its value was %d)", \
param_name, \
currValue, \
minValue))); \
} while(0)
int errcode(int sqlerrcode)
Definition: elog.c:570
#define ERROR
Definition: elog.h:43
int errmsg(const char *fmt,...)
Definition: elog.c:784

Definition at line 6284 of file xlog.c.

Referenced by CheckRequiredParameterValues().

◆ UsableBytesInPage

#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)

◆ XLogRecPtrToBufIdx

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

Definition at line 726 of file xlog.c.

Referenced by AdvanceXLInsertBuffer(), GetXLogBuffer(), StartupXLOG(), and XLogWrite().

Typedef Documentation

◆ ExclusiveBackupState

◆ WALInsertLockPadded

◆ XLogCtlData

◆ XLogCtlInsert

◆ XLogPageReadPrivate

◆ XLogwrtResult

◆ XLogwrtRqst

Enumeration Type Documentation

◆ ExclusiveBackupState

Enumerator
EXCLUSIVE_BACKUP_NONE 
EXCLUSIVE_BACKUP_STARTING 
EXCLUSIVE_BACKUP_IN_PROGRESS 
EXCLUSIVE_BACKUP_STOPPING 

Definition at line 494 of file xlog.c.

◆ XLogSource

enum XLogSource
Enumerator
XLOG_FROM_ANY 
XLOG_FROM_ARCHIVE 
XLOG_FROM_PG_WAL 
XLOG_FROM_STREAM 

Definition at line 751 of file xlog.c.

752 {
753  XLOG_FROM_ANY = 0, /* request to read WAL from any source */
754  XLOG_FROM_ARCHIVE, /* restored using restore_command */
755  XLOG_FROM_PG_WAL, /* existing file in pg_wal */
756  XLOG_FROM_STREAM /* streamed from master */
757 } XLogSource;
XLogSource
Definition: xlog.c:751

Function Documentation

◆ AdvanceXLInsertBuffer()

static void AdvanceXLInsertBuffer ( XLogRecPtr  upto,
bool  opportunistic 
)
static

Definition at line 2075 of file xlog.c.

References Assert, DEBUG1, elog, XLogwrtRqst::Flush, XLogCtlInsert::forcePageWrites, XLogCtlData::info_lck, XLogCtlData::InitializedUpTo, Insert(), XLogCtlData::Insert, InvalidXLogRecPtr, XLogCtlData::LogwrtResult, XLogCtlData::LogwrtRqst, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MemSet, XLogCtlData::pages, pg_write_barrier, SpinLockAcquire, SpinLockRelease, ControlFileData::system_identifier, ThisTimeLineID, WaitXLogInsertionsToFinish(), wal_segment_size, XLogwrtRqst::Write, XLogwrtResult::Write, XLogCtlData::xlblocks, XLOG_PAGE_MAGIC, 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().

2076 {
2078  int nextidx;
2079  XLogRecPtr OldPageRqstPtr;
2080  XLogwrtRqst WriteRqst;
2081  XLogRecPtr NewPageEndPtr = InvalidXLogRecPtr;
2082  XLogRecPtr NewPageBeginPtr;
2083  XLogPageHeader NewPage;
2084  int npages = 0;
2085 
2086  LWLockAcquire(WALBufMappingLock, LW_EXCLUSIVE);
2087 
2088  /*
2089  * Now that we have the lock, check if someone initialized the page
2090  * already.
2091  */
2092  while (upto >= XLogCtl->InitializedUpTo || opportunistic)
2093  {
2095 
2096  /*
2097  * Get ending-offset of the buffer page we need to replace (this may
2098  * be zero if the buffer hasn't been used yet). Fall through if it's
2099  * already written out.
2100  */
2101  OldPageRqstPtr = XLogCtl->xlblocks[nextidx];
2102  if (LogwrtResult.Write < OldPageRqstPtr)
2103  {
2104  /*
2105  * Nope, got work to do. If we just want to pre-initialize as much
2106  * as we can without flushing, give up now.
2107  */
2108  if (opportunistic)
2109  break;
2110 
2111  /* Before waiting, get info_lck and update LogwrtResult */
2113  if (XLogCtl->LogwrtRqst.Write < OldPageRqstPtr)
2114  XLogCtl->LogwrtRqst.Write = OldPageRqstPtr;
2117 
2118  /*
2119  * Now that we have an up-to-date LogwrtResult value, see if we
2120  * still need to write it or if someone else already did.
2121  */
2122  if (LogwrtResult.Write < OldPageRqstPtr)
2123  {
2124  /*
2125  * Must acquire write lock. Release WALBufMappingLock first,
2126  * to make sure that all insertions that we need to wait for
2127  * can finish (up to this same position). Otherwise we risk
2128  * deadlock.
2129  */
2130  LWLockRelease(WALBufMappingLock);
2131 
2132  WaitXLogInsertionsToFinish(OldPageRqstPtr);
2133 
2134  LWLockAcquire(WALWriteLock, LW_EXCLUSIVE);
2135 
2137  if (LogwrtResult.Write >= OldPageRqstPtr)
2138  {
2139  /* OK, someone wrote it already */
2140  LWLockRelease(WALWriteLock);
2141  }
2142  else
2143  {
2144  /* Have to write it ourselves */
2145  TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_START();
2146  WriteRqst.Write = OldPageRqstPtr;
2147  WriteRqst.Flush = 0;
2148  XLogWrite(WriteRqst, false);
2149  LWLockRelease(WALWriteLock);
2150  TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_DONE();
2151  }
2152  /* Re-acquire WALBufMappingLock and retry */
2153  LWLockAcquire(WALBufMappingLock, LW_EXCLUSIVE);
2154  continue;
2155  }
2156  }
2157 
2158  /*
2159  * Now the next buffer slot is free and we can set it up to be the
2160  * next output page.
2161  */
2162  NewPageBeginPtr = XLogCtl->InitializedUpTo;
2163  NewPageEndPtr = NewPageBeginPtr + XLOG_BLCKSZ;
2164 
2165  Assert(XLogRecPtrToBufIdx(NewPageBeginPtr) == nextidx);
2166 
2167  NewPage = (XLogPageHeader) (XLogCtl->pages + nextidx * (Size) XLOG_BLCKSZ);
2168 
2169  /*
2170  * Be sure to re-zero the buffer so that bytes beyond what we've
2171  * written will look like zeroes and not valid XLOG records...
2172  */
2173  MemSet((char *) NewPage, 0, XLOG_BLCKSZ);
2174 
2175  /*
2176  * Fill the new page's header
2177  */
2178  NewPage->xlp_magic = XLOG_PAGE_MAGIC;
2179 
2180  /* NewPage->xlp_info = 0; */ /* done by memset */
2181  NewPage->xlp_tli = ThisTimeLineID;
2182  NewPage->xlp_pageaddr = NewPageBeginPtr;
2183 
2184  /* NewPage->xlp_rem_len = 0; */ /* done by memset */
2185 
2186  /*
2187  * If online backup is not in progress, mark the header to indicate
2188  * that WAL records beginning in this page have removable backup
2189  * blocks. This allows the WAL archiver to know whether it is safe to
2190  * compress archived WAL data by transforming full-block records into
2191  * the non-full-block format. It is sufficient to record this at the
2192  * page level because we force a page switch (in fact a segment
2193  * switch) when starting a backup, so the flag will be off before any
2194  * records can be written during the backup. At the end of a backup,
2195  * the last page will be marked as all unsafe when perhaps only part
2196  * is unsafe, but at worst the archiver would miss the opportunity to
2197  * compress a few records.
2198  */
2199  if (!Insert->forcePageWrites)
2200  NewPage->xlp_info |= XLP_BKP_REMOVABLE;
2201 
2202  /*
2203  * If first page of an XLOG segment file, make it a long header.
2204  */
2205  if ((XLogSegmentOffset(NewPage->xlp_pageaddr, wal_segment_size)) == 0)
2206  {
2207  XLogLongPageHeader NewLongPage = (XLogLongPageHeader) NewPage;
2208 
2209  NewLongPage->xlp_sysid = ControlFile->system_identifier;
2210  NewLongPage->xlp_seg_size = wal_segment_size;
2211  NewLongPage->xlp_xlog_blcksz = XLOG_BLCKSZ;
2212  NewPage->xlp_info |= XLP_LONG_HEADER;
2213  }
2214 
2215  /*
2216  * Make sure the initialization of the page becomes visible to others
2217  * before the xlblocks update. GetXLogBuffer() reads xlblocks without
2218  * holding a lock.
2219  */
2220  pg_write_barrier();
2221 
2222  *((volatile XLogRecPtr *) &XLogCtl->xlblocks[nextidx]) = NewPageEndPtr;
2223 
2224  XLogCtl->InitializedUpTo = NewPageEndPtr;
2225 
2226  npages++;
2227  }
2228  LWLockRelease(WALBufMappingLock);
2229 
2230 #ifdef WAL_DEBUG
2231  if (XLOG_DEBUG && npages > 0)
2232  {
2233  elog(DEBUG1, "initialized %d pages, up to %X/%X",
2234  npages, (uint32) (NewPageEndPtr >> 32), (uint32) NewPageEndPtr);
2235  }
2236 #endif
2237 }
XLogRecPtr InitializedUpTo
Definition: xlog.c:607
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define DEBUG1
Definition: elog.h:25
int wal_segment_size
Definition: xlog.c:107
XLogRecPtr * xlblocks
Definition: xlog.c:615
static XLogwrtResult LogwrtResult
Definition: xlog.c:745
slock_t info_lck
Definition: xlog.c:698
#define MemSet(start, val, len)
Definition: c.h:941
static XLogRecPtr WaitXLogInsertionsToFinish(XLogRecPtr upto)
Definition: xlog.c:1738
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:57
XLogCtlInsert Insert
Definition: xlog.c:571
XLogRecPtr Flush
Definition: xlog.c:414
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:74
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define XLP_BKP_REMOVABLE
Definition: xlog_internal.h:81
bool forcePageWrites
Definition: xlog.c:545
uint64 system_identifier
Definition: pg_control.h:106
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
XLogwrtResult LogwrtResult
Definition: xlog.c:595
unsigned int uint32
Definition: c.h:358
static void Insert(File file)
Definition: fd.c:1034
TimeLineID xlp_tli
Definition: xlog_internal.h:40
static void XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
Definition: xlog.c:2365
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
#define SpinLockRelease(lock)
Definition: spin.h:64
XLogRecPtr Write
Definition: xlog.c:413
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
static ControlFileData * ControlFile
Definition: xlog.c:709
XLogwrtRqst LogwrtRqst
Definition: xlog.c:574
TimeLineID ThisTimeLineID
Definition: xlog.c:175
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:732
#define XLP_LONG_HEADER
Definition: xlog_internal.h:79
size_t Size
Definition: c.h:466
static XLogCtlData * XLogCtl
Definition: xlog.c:701
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
#define XLogRecPtrToBufIdx(recptr)
Definition: xlog.c:726
XLogRecPtr Write
Definition: xlog.c:419
#define elog(elevel,...)
Definition: elog.h:226
#define pg_write_barrier()
Definition: atomics.h:162
char * pages
Definition: xlog.c:614

◆ assign_checkpoint_completion_target()

void assign_checkpoint_completion_target ( double  newval,
void *  extra 
)

Definition at line 2280 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

2281 {
2284 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2244
#define newval
double CheckPointCompletionTarget
Definition: checkpointer.c:147

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2273 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

2274 {
2277 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2244
int max_wal_size_mb
Definition: xlog.c:83
#define newval

◆ assign_xlog_sync_method()

void assign_xlog_sync_method ( int  new_sync_method,
void *  extra 
)

Definition at line 10256 of file xlog.c.

References ereport, errcode_for_file_access(), errmsg(), get_sync_bit(), openLogFile, openLogSegNo, PANIC, pg_fsync(), pgstat_report_wait_end(), pgstat_report_wait_start(), sync_method, ThisTimeLineID, WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN, XLogFileClose(), and XLogFileNameP().

10257 {
10258  if (sync_method != new_sync_method)
10259  {
10260  /*
10261  * To ensure that no blocks escape unsynced, force an fsync on the
10262  * currently open log segment (if any). Also, if the open flag is
10263  * changing, close the log file so it will be reopened (with new flag
10264  * bit) at next use.
10265  */
10266  if (openLogFile >= 0)
10267  {
10269  if (pg_fsync(openLogFile) != 0)
10270  ereport(PANIC,
10272  errmsg("could not fsync file \"%s\": %m",
10275  if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
10276  XLogFileClose();
10277  }
10278  }
10279 }
static int get_sync_bit(int method)
Definition: xlog.c:10200
#define PANIC
Definition: elog.h:53
static XLogSegNo openLogSegNo
Definition: xlog.c:769
static void XLogFileClose(void)
Definition: xlog.c:3747
char * XLogFileNameP(TimeLineID tli, XLogSegNo segno)
Definition: xlog.c:10334
int errcode_for_file_access(void)
Definition: elog.c:593
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1262
#define ereport(elevel, rest)
Definition: elog.h:141
static int openLogFile
Definition: xlog.c:768
TimeLineID ThisTimeLineID
Definition: xlog.c:175
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1238
int sync_method
Definition: xlog.c:97
int errmsg(const char *fmt,...)
Definition: elog.c:784
int pg_fsync(int fd)
Definition: fd.c:331

◆ BackupInProgress()

bool BackupInProgress ( void  )

Definition at line 11627 of file xlog.c.

References BACKUP_LABEL_FILE, and stat.

Referenced by pg_is_in_backup(), and PostmasterStateMachine().

11628 {
11629  struct stat stat_buf;
11630 
11631  return (stat(BACKUP_LABEL_FILE, &stat_buf) == 0);
11632 }
struct stat stat_buf
Definition: pg_standby.c:102
#define stat(a, b)
Definition: win32_port.h:266
#define BACKUP_LABEL_FILE
Definition: xlog.h:324

◆ BootStrapXLOG()

void BootStrapXLOG ( void  )

Definition at line 5089 of file xlog.c.

References AdvanceOldestClogXid(), Assert, bootstrap_data_checksum_version, BootStrapCLOG(), BootStrapCommitTs(), BootStrapMultiXact(), BootStrapSUBTRANS(), ControlFileData::checkPoint, ControlFileData::checkPointCopy, close, COMP_CRC32C, ControlFileData::data_checksum_version, DB_SHUTDOWNED, ereport, errcode(), errcode_for_file_access(), errmsg(), FIN_CRC32C, FirstBootstrapObjectId, FirstMultiXactId, FirstNormalTransactionId, CheckPoint::fullPageWrites, fullPageWrites, gettimeofday(), INIT_CRC32C, InvalidTransactionId, max_locks_per_xact, ControlFileData::max_locks_per_xact, max_prepared_xacts, ControlFileData::max_prepared_xacts, max_worker_processes, ControlFileData::max_worker_processes, MaxConnections, ControlFileData::MaxConnections, MOCK_AUTH_NONCE_LEN, ControlFileData::mock_authentication_nonce, MultiXactSetNextMXact(), CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, VariableCacheData::nextOid, CheckPoint::nextXid, VariableCacheData::nextXid, CheckPoint::nextXidEpoch, offsetof, VariableCacheData::oidCount, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, openLogFile, palloc(), PANIC, pfree(), pg_backend_random(), pg_fsync(), pgstat_report_wait_end(), pgstat_report_wait_start(), CheckPoint::PrevTimeLineID, ReadControlFile(), CheckPoint::redo, SetCommitTsLimit(), SetMultiXactIdLimit(), SetTransactionIdLimit(), ShmemVariableCache, SizeOfXLogLongPHD, SizeOfXLogRecord, SizeOfXLogRecordDataHeaderShort, ControlFileData::state, ControlFileData::system_identifier, CheckPoint::ThisTimeLineID, ThisTimeLineID, CheckPoint::time, ControlFileData::time, track_commit_timestamp, ControlFileData::track_commit_timestamp, TYPEALIGN, ControlFileData::unloggedLSN, WAIT_EVENT_WAL_BOOTSTRAP_SYNC, WAIT_EVENT_WAL_BOOTSTRAP_WRITE, wal_level, ControlFileData::wal_level, wal_log_hints, ControlFileData::wal_log_hints, wal_segment_size, write, WriteControlFile(), 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 AuxiliaryProcessMain().

5090 {
5091  CheckPoint checkPoint;
5092  char *buffer;
5093  XLogPageHeader page;
5094  XLogLongPageHeader longpage;
5095  XLogRecord *record;
5096  char *recptr;
5097  bool use_existent;
5098  uint64 sysidentifier;
5099  char mock_auth_nonce[MOCK_AUTH_NONCE_LEN];
5100  struct timeval tv;
5101  pg_crc32c crc;
5102 
5103  /*
5104  * Select a hopefully-unique system identifier code for this installation.
5105  * We use the result of gettimeofday(), including the fractional seconds
5106  * field, as being about as unique as we can easily get. (Think not to
5107  * use random(), since it hasn't been seeded and there's no portable way
5108  * to seed it other than the system clock value...) The upper half of the
5109  * uint64 value is just the tv_sec part, while the lower half contains the
5110  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
5111  * PID for a little extra uniqueness. A person knowing this encoding can
5112  * determine the initialization time of the installation, which could
5113  * perhaps be useful sometimes.
5114  */
5115  gettimeofday(&tv, NULL);
5116  sysidentifier = ((uint64) tv.tv_sec) << 32;
5117  sysidentifier |= ((uint64) tv.tv_usec) << 12;
5118  sysidentifier |= getpid() & 0xFFF;
5119 
5120  /*
5121  * Generate a random nonce. This is used for authentication requests that
5122  * will fail because the user does not exist. The nonce is used to create
5123  * a genuine-looking password challenge for the non-existent user, in lieu
5124  * of an actual stored password.
5125  */
5126  if (!pg_backend_random(mock_auth_nonce, MOCK_AUTH_NONCE_LEN))
5127  ereport(PANIC,
5128  (errcode(ERRCODE_INTERNAL_ERROR),
5129  errmsg("could not generate secret authorization token")));
5130 
5131  /* First timeline ID is always 1 */
5132  ThisTimeLineID = 1;
5133 
5134  /* page buffer must be aligned suitably for O_DIRECT */
5135  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
5136  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
5137  memset(page, 0, XLOG_BLCKSZ);
5138 
5139  /*
5140  * Set up information for the initial checkpoint record
5141  *
5142  * The initial checkpoint record is written to the beginning of the WAL
5143  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5144  * used, so that we can use 0/0 to mean "before any valid WAL segment".
5145  */
5146  checkPoint.redo = wal_segment_size + SizeOfXLogLongPHD;
5147  checkPoint.ThisTimeLineID = ThisTimeLineID;
5148  checkPoint.PrevTimeLineID = ThisTimeLineID;
5149  checkPoint.fullPageWrites = fullPageWrites;
5150  checkPoint.nextXidEpoch = 0;
5151  checkPoint.nextXid = FirstNormalTransactionId;
5152  checkPoint.nextOid = FirstBootstrapObjectId;
5153  checkPoint.nextMulti = FirstMultiXactId;
5154  checkPoint.nextMultiOffset = 0;
5155  checkPoint.oldestXid = FirstNormalTransactionId;
5156  checkPoint.oldestXidDB = TemplateDbOid;
5157  checkPoint.oldestMulti = FirstMultiXactId;
5158  checkPoint.oldestMultiDB = TemplateDbOid;
5161  checkPoint.time = (pg_time_t) time(NULL);
5163 
5164  ShmemVariableCache->nextXid = checkPoint.nextXid;
5165  ShmemVariableCache->nextOid = checkPoint.nextOid;
5167  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5168  AdvanceOldestClogXid(checkPoint.oldestXid);
5169  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5170  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5172 
5173  /* Set up the XLOG page header */
5174  page->xlp_magic = XLOG_PAGE_MAGIC;
5175  page->xlp_info = XLP_LONG_HEADER;
5176  page->xlp_tli = ThisTimeLineID;
5178  longpage = (XLogLongPageHeader) page;
5179  longpage->xlp_sysid = sysidentifier;
5180  longpage->xlp_seg_size = wal_segment_size;
5181  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5182 
5183  /* Insert the initial checkpoint record */
5184  recptr = ((char *) page + SizeOfXLogLongPHD);
5185  record = (XLogRecord *) recptr;
5186  record->xl_prev = 0;
5187  record->xl_xid = InvalidTransactionId;
5188  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5190  record->xl_rmid = RM_XLOG_ID;
5191  recptr += SizeOfXLogRecord;
5192  /* fill the XLogRecordDataHeaderShort struct */
5193  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5194  *(recptr++) = sizeof(checkPoint);
5195  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5196  recptr += sizeof(checkPoint);
5197  Assert(recptr - (char *) record == record->xl_tot_len);
5198 
5199  INIT_CRC32C(crc);
5200  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5201  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5202  FIN_CRC32C(crc);
5203  record->xl_crc = crc;
5204 
5205  /* Create first XLOG segment file */
5206  use_existent = false;
5207  openLogFile = XLogFileInit(1, &use_existent, false);
5208 
5209  /* Write the first page with the initial record */
5210  errno = 0;
5212  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5213  {
5214  /* if write didn't set errno, assume problem is no disk space */
5215  if (errno == 0)
5216  errno = ENOSPC;
5217  ereport(PANIC,
5219  errmsg("could not write bootstrap write-ahead log file: %m")));
5220  }
5222 
5224  if (pg_fsync(openLogFile) != 0)
5225  ereport(PANIC,
5227  errmsg("could not fsync bootstrap write-ahead log file: %m")));
5229 
5230  if (close(openLogFile))
5231  ereport(PANIC,
5233  errmsg("could not close bootstrap write-ahead log file: %m")));
5234 
5235  openLogFile = -1;
5236 
5237  /* Now create pg_control */
5238 
5239  memset(ControlFile, 0, sizeof(ControlFileData));
5240  /* Initialize pg_control status fields */
5241  ControlFile->system_identifier = sysidentifier;
5242  memcpy(ControlFile->mock_authentication_nonce, mock_auth_nonce, MOCK_AUTH_NONCE_LEN);
5244  ControlFile->time = checkPoint.time;
5245  ControlFile->checkPoint = checkPoint.redo;
5246  ControlFile->checkPointCopy = checkPoint;
5247  ControlFile->unloggedLSN = 1;
5248 
5249  /* Set important parameter values for use when replaying WAL */
5258 
5259  /* some additional ControlFile fields are set in WriteControlFile() */
5260 
5261  WriteControlFile();
5262 
5263  /* Bootstrap the commit log, too */
5264  BootStrapCLOG();
5268 
5269  pfree(buffer);
5270 
5271  /*
5272  * Force control file to be read - in contrast to normal processing we'd
5273  * otherwise never run the checks and GUC related initializations therein.
5274  */
5275  ReadControlFile();
5276 }
static void WriteControlFile(void)
Definition: xlog.c:4450
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
int max_locks_per_xact
Definition: pg_control.h:181
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:105
int max_prepared_xacts
Definition: pg_control.h:180
int64 pg_time_t
Definition: pgtime.h:23
int wal_segment_size
Definition: xlog.c:107
pg_time_t time
Definition: pg_control.h:128
void SetCommitTsLimit(TransactionId oldestXact, TransactionId newestXact)
Definition: commit_ts.c:848
uint32 oidCount
Definition: transam.h:112
#define write(a, b, c)
Definition: win32.h:14
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:201
int max_worker_processes
Definition: pg_control.h:179
uint32 pg_crc32c
Definition: pg_crc32c.h:38
TransactionId oldestActiveXid
Definition: pg_control.h:63
int wal_level
Definition: xlog.c:98
int XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
Definition: xlog.c:3199
void BootStrapMultiXact(void)
Definition: multixact.c:1866
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: pg_control.h:39
int errcode(int sqlerrcode)
Definition: elog.c:570
RmgrId xl_rmid
Definition: xlogrecord.h:47
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:57
CheckPoint checkPointCopy
Definition: pg_control.h:131
TransactionId oldestXid
Definition: pg_control.h:47
TransactionId nextXid
Definition: pg_control.h:43
pg_time_t time
Definition: pg_control.h:51
#define PANIC
Definition: elog.h:53
uint32 bootstrap_data_checksum_version
Definition: bootstrap.c:51
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:74
#define MOCK_AUTH_NONCE_LEN
Definition: pg_control.h:27
bool fullPageWrites
Definition: xlog.c:91
void BootStrapSUBTRANS(void)
Definition: subtrans.c:212
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid)
Definition: varsup.c:263
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
void pfree(void *pointer)
Definition: mcxt.c:1031
#define FirstNormalTransactionId
Definition: transam.h:34
int max_prepared_xacts
Definition: twophase.c:117
uint64 system_identifier
Definition: pg_control.h:106
uint32 xl_tot_len
Definition: xlogrecord.h:43
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
TransactionId nextXid
Definition: transam.h:117
static void ReadControlFile(void)
Definition: xlog.c:4542
uint32 nextXidEpoch
Definition: pg_control.h:42
bool track_commit_timestamp
Definition: commit_ts.c:103
uint32 data_checksum_version
Definition: pg_control.h:221
bool pg_backend_random(char *dst, int len)
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
XLogRecPtr unloggedLSN
Definition: pg_control.h:133
int errcode_for_file_access(void)
Definition: elog.c:593
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define InvalidTransactionId
Definition: transam.h:31
#define FirstBootstrapObjectId
Definition: transam.h:93
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1262
#define FirstMultiXactId
Definition: multixact.h:24
#define ereport(elevel, rest)
Definition: elog.h:141
int max_locks_per_xact
Definition: lock.c:54
TimeLineID xlp_tli
Definition: xlog_internal.h:40
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
#define SizeOfXLogRecord
Definition: xlogrecord.h:55
TransactionId newestCommitTsXid
Definition: pg_control.h:54
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition: pg_control.h:228
int MaxConnections
Definition: globals.c:132
Oid oldestMultiDB
Definition: pg_control.h:50
static int openLogFile
Definition: xlog.c:768
static ControlFileData * ControlFile
Definition: xlog.c:709
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
Definition: multixact.c:2194
TimeLineID ThisTimeLineID
Definition: xlog.c:175
Oid nextOid
Definition: pg_control.h:44
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:678
bool fullPageWrites
Definition: pg_control.h:41
bool wal_log_hints
Definition: xlog.c:92
void BootStrapCLOG(void)
Definition: clog.c:712
bool track_commit_timestamp
Definition: pg_control.h:182
#define Assert(condition)
Definition: c.h:732
#define XLP_LONG_HEADER
Definition: xlog_internal.h:79
Oid oldestXidDB
Definition: pg_control.h:48
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1238
void SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid)
Definition: varsup.c:280
uint8 xl_info
Definition: xlogrecord.h:46
MultiXactId nextMulti
Definition: pg_control.h:45
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:224
TransactionId xl_xid
Definition: xlogrecord.h:44
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
void * palloc(Size size)
Definition: mcxt.c:924
int errmsg(const char *fmt,...)
Definition: elog.c:784
int max_worker_processes
Definition: globals.c:133
int pg_fsync(int fd)
Definition: fd.c:331
#define close(a)
Definition: win32.h:12
void BootStrapCommitTs(void)
Definition: commit_ts.c:523
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:89
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:94
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:36
#define offsetof(type, field)
Definition: c.h:655
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset)
Definition: multixact.c:2160

◆ CalculateCheckpointSegments()

static void CalculateCheckpointSegments ( void  )
static

Definition at line 2244 of file xlog.c.

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

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

2245 {
2246  double target;
2247 
2248  /*-------
2249  * Calculate the distance at which to trigger a checkpoint, to avoid
2250  * exceeding max_wal_size_mb. This is based on two assumptions:
2251  *
2252  * a) we keep WAL for only one checkpoint cycle (prior to PG11 we kept
2253  * WAL for two checkpoint cycles to allow us to recover from the
2254  * secondary checkpoint if the first checkpoint failed, though we
2255  * only did this on the master anyway, not on standby. Keeping just
2256  * one checkpoint simplifies processing and reduces disk space in
2257  * many smaller databases.)
2258  * b) during checkpoint, we consume checkpoint_completion_target *
2259  * number of segments consumed between checkpoints.
2260  *-------
2261  */
2262  target = (double) ConvertToXSegs(max_wal_size_mb, wal_segment_size) /
2264 
2265  /* round down */
2266  CheckPointSegments = (int) target;
2267 
2268  if (CheckPointSegments < 1)
2269  CheckPointSegments = 1;
2270 }
#define ConvertToXSegs(x, segsize)
Definition: xlog.c:735
int wal_segment_size
Definition: xlog.c:107
int max_wal_size_mb
Definition: xlog.c:83
int CheckPointSegments
Definition: xlog.c:120
double CheckPointCompletionTarget
Definition: checkpointer.c:147

◆ CancelBackup()

void CancelBackup ( void  )

Definition at line 11647 of file xlog.c.

References BACKUP_LABEL_FILE, BACKUP_LABEL_OLD, DEBUG1, durable_rename(), ereport, errcode_for_file_access(), errdetail(), errmsg(), LOG, stat, TABLESPACE_MAP, TABLESPACE_MAP_OLD, and WARNING.

Referenced by PostmasterStateMachine().

11648 {
11649  struct stat stat_buf;
11650 
11651  /* if the backup_label file is not there, return */
11652  if (stat(BACKUP_LABEL_FILE, &stat_buf) < 0)
11653  return;
11654 
11655  /* remove leftover file from previously canceled backup if it exists */
11656  unlink(BACKUP_LABEL_OLD);
11657 
11659  {
11660  ereport(WARNING,
11662  errmsg("online backup mode was not canceled"),
11663  errdetail("File \"%s\" could not be renamed to \"%s\": %m.",
11665  return;
11666  }
11667 
11668  /* if the tablespace_map file is not there, return */
11669  if (stat(TABLESPACE_MAP, &stat_buf) < 0)
11670  {
11671  ereport(LOG,
11672  (errmsg("online backup mode canceled"),
11673  errdetail("File \"%s\" was renamed to \"%s\".",
11675  return;
11676  }
11677 
11678  /* remove leftover file from previously canceled backup if it exists */
11679  unlink(TABLESPACE_MAP_OLD);
11680 
11682  {
11683  ereport(LOG,
11684  (errmsg("online backup mode canceled"),
11685  errdetail("Files \"%s\" and \"%s\" were renamed to "
11686  "\"%s\" and \"%s\", respectively.",
11689  }
11690  else
11691  {
11692  ereport(WARNING,
11694  errmsg("online backup mode canceled"),
11695  errdetail("File \"%s\" was renamed to \"%s\", but "
11696  "file \"%s\" could not be renamed to \"%s\": %m.",
11699  }
11700 }
#define DEBUG1
Definition: elog.h:25
#define LOG
Definition: elog.h:26
#define BACKUP_LABEL_OLD
Definition: xlog.h:325
#define TABLESPACE_MAP
Definition: xlog.h:327
struct stat stat_buf
Definition: pg_standby.c:102
int errdetail(const char *fmt,...)
Definition: elog.c:860
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:589
#define WARNING
Definition: elog.h:40
#define stat(a, b)
Definition: win32_port.h:266
#define TABLESPACE_MAP_OLD
Definition: xlog.h:328
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define BACKUP_LABEL_FILE
Definition: xlog.h:324

◆ check_wal_buffers()

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

Definition at line 4880 of file xlog.c.

References XLOGbuffers, and XLOGChooseNumBuffers().

4881 {
4882  /*
4883  * -1 indicates a request for auto-tune.
4884  */
4885  if (*newval == -1)
4886  {
4887  /*
4888  * If we haven't yet changed the boot_val default of -1, just let it
4889  * be. We'll fix it when XLOGShmemSize is called.
4890  */
4891  if (XLOGbuffers == -1)
4892  return true;
4893 
4894  /* Otherwise, substitute the auto-tune value */
4896  }
4897 
4898  /*
4899  * We clamp manually-set values to at least 4 blocks. Prior to PostgreSQL
4900  * 9.1, a minimum of 4 was enforced by guc.c, but since that is no longer
4901  * the case, we just silently treat such values as a request for the
4902  * minimum. (We could throw an error instead, but that doesn't seem very
4903  * helpful.)
4904  */
4905  if (*newval < 4)
4906  *newval = 4;
4907 
4908  return true;
4909 }
static int XLOGChooseNumBuffers(void)
Definition: xlog.c:4864
#define newval
int XLOGbuffers
Definition: xlog.c:86

◆ CheckForStandbyTrigger()

static bool CheckForStandbyTrigger ( void  )
static

Definition at line 12334 of file xlog.c.

References ereport, errcode_for_file_access(), errmsg(), ERROR, FALLBACK_PROMOTE_SIGNAL_FILE, fast_promote, IsPromoteTriggered(), LOG, PROMOTE_SIGNAL_FILE, ResetPromoteTriggered(), stat, and TriggerFile.

Referenced by ReadRecord(), recoveryApplyDelay(), and WaitForWALToBecomeAvailable().

12335 {
12336  struct stat stat_buf;
12337  static bool triggered = false;
12338 
12339  if (triggered)
12340  return true;
12341 
12342  if (IsPromoteTriggered())
12343  {
12344  /*
12345  * In 9.1 and 9.2 the postmaster unlinked the promote file inside the
12346  * signal handler. It now leaves the file in place and lets the
12347  * Startup process do the unlink. This allows Startup to know whether
12348  * it should create a full checkpoint before starting up (fallback
12349  * mode). Fast promotion takes precedence.
12350  */
12351  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
12352  {
12353  unlink(PROMOTE_SIGNAL_FILE);
12355  fast_promote = true;
12356  }
12357  else if (stat(FALLBACK_PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
12358  {
12360  fast_promote = false;
12361  }
12362 
12363  ereport(LOG, (errmsg("received promote request")));
12364 
12366  triggered = true;
12367  return true;
12368  }
12369 
12370  if (TriggerFile == NULL)
12371  return false;
12372 
12373  if (stat(TriggerFile, &stat_buf) == 0)
12374  {
12375  ereport(LOG,
12376  (errmsg("trigger file found: %s", TriggerFile)));
12377  unlink(TriggerFile);
12378  triggered = true;
12379  fast_promote = true;
12380  return true;
12381  }
12382  else if (errno != ENOENT)
12383  ereport(ERROR,
12385  errmsg("could not stat trigger file \"%s\": %m",
12386  TriggerFile)));
12387 
12388  return false;
12389 }
void ResetPromoteTriggered(void)
Definition: startup.c:247
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:331
#define LOG
Definition: elog.h:26
static char * TriggerFile
Definition: xlog.c:270
#define ERROR
Definition: elog.h:43
struct stat stat_buf
Definition: pg_standby.c:102
int errcode_for_file_access(void)
Definition: elog.c:593
bool IsPromoteTriggered(void)
Definition: startup.c:241
#define ereport(elevel, rest)
Definition: elog.h:141
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.h:332
#define stat(a, b)
Definition: win32_port.h:266
int errmsg(const char *fmt,...)
Definition: elog.c:784
static bool fast_promote
Definition: xlog.c:276

◆ CheckPointGuts()

static void CheckPointGuts ( XLogRecPtr  checkPointRedo,
int  flags 
)
static

Definition at line 9188 of file xlog.c.

References CheckPointBuffers(), CheckPointCLOG(), CheckPointCommitTs(), CheckPointLogicalRewriteHeap(), CheckPointMultiXact(), CheckPointPredicate(), CheckPointRelationMap(), CheckPointReplicationOrigin(), CheckPointReplicationSlots(), CheckPointSnapBuild(), CheckPointSUBTRANS(), and CheckPointTwoPhase().

Referenced by CreateCheckPoint(), and CreateRestartPoint().

9189 {
9190  CheckPointCLOG();
9199  CheckPointBuffers(flags); /* performs all required fsyncs */
9201  /* We deliberately delay 2PC checkpointing as long as possible */
9202  CheckPointTwoPhase(checkPointRedo);
9203 }
void CheckPointBuffers(int flags)
Definition: bufmgr.c:2574
void CheckPointLogicalRewriteHeap(void)
Definition: rewriteheap.c:1221
void CheckPointReplicationOrigin(void)
Definition: origin.c:545
void CheckPointSnapBuild(void)
Definition: snapbuild.c:1922
void CheckPointCLOG(void)
Definition: clog.c:842
void CheckPointMultiXact(void)
Definition: multixact.c:2140
void CheckPointCommitTs(void)
Definition: commit_ts.c:760
void CheckPointSUBTRANS(void)
Definition: subtrans.c:300
void CheckPointRelationMap(void)
Definition: relmapper.c:546
void CheckPointPredicate(void)
Definition: predicate.c:997
void CheckPointTwoPhase(XLogRecPtr redo_horizon)
Definition: twophase.c:1735
void CheckPointReplicationSlots(void)
Definition: slot.c:1074

◆ CheckPromoteSignal()

bool CheckPromoteSignal ( void  )

Definition at line 12406 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, PROMOTE_SIGNAL_FILE, and stat.

Referenced by sigusr1_handler().

12407 {
12408  struct stat stat_buf;
12409 
12410  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
12412  return true;
12413 
12414  return false;
12415 }
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:331
struct stat stat_buf
Definition: pg_standby.c:102
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.h:332
#define stat(a, b)
Definition: win32_port.h:266

◆ CheckRecoveryConsistency()

static void CheckRecoveryConsistency ( void  )
static

Definition at line 7964 of file xlog.c.

References Assert, ControlFileData::backupEndPoint, ControlFileData::backupEndRequired, ControlFileData::backupStartPoint, DEBUG1, elog, ereport, errmsg(), InArchiveRecovery, XLogCtlData::info_lck, InvalidXLogRecPtr, IsUnderPostmaster, XLogCtlData::lastReplayedEndRecPtr, LocalHotStandbyActive, LOG, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), ControlFileData::minRecoveryPoint, minRecoveryPoint, PMSIGNAL_BEGIN_HOT_STANDBY, reachedConsistency, SendPostmasterSignal(), XLogCtlData::SharedHotStandbyActive, SpinLockAcquire, SpinLockRelease, STANDBY_SNAPSHOT_READY, standbyState, UpdateControlFile(), XLogCheckInvalidPages(), and XLogRecPtrIsInvalid.

Referenced by ReadRecord(), and StartupXLOG().

7965 {
7966  XLogRecPtr lastReplayedEndRecPtr;
7967 
7968  /*
7969  * During crash recovery, we don't reach a consistent state until we've
7970  * replayed all the WAL.
7971  */
7973  return;
7974 
7976 
7977  /*
7978  * assume that we are called in the startup process, and hence don't need
7979  * a lock to read lastReplayedEndRecPtr
7980  */
7981  lastReplayedEndRecPtr = XLogCtl->lastReplayedEndRecPtr;
7982 
7983  /*
7984  * Have we reached the point where our base backup was completed?
7985  */
7987  ControlFile->backupEndPoint <= lastReplayedEndRecPtr)
7988  {
7989  /*
7990  * We have reached the end of base backup, as indicated by pg_control.
7991  * The data on disk is now consistent. Reset backupStartPoint and
7992  * backupEndPoint, and update minRecoveryPoint to make sure we don't
7993  * allow starting up at an earlier point even if recovery is stopped
7994  * and restarted soon after this.
7995  */
7996  elog(DEBUG1, "end of backup reached");
7997 
7998  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7999 
8000  if (ControlFile->minRecoveryPoint < lastReplayedEndRecPtr)
8001  ControlFile->minRecoveryPoint = lastReplayedEndRecPtr;
8002 
8005  ControlFile->backupEndRequired = false;
8007 
8008  LWLockRelease(ControlFileLock);
8009  }
8010 
8011  /*
8012  * Have we passed our safe starting point? Note that minRecoveryPoint is
8013  * known to be incorrectly set if ControlFile->backupEndRequired, until
8014  * the XLOG_BACKUP_END arrives to advise us of the correct
8015  * minRecoveryPoint. All we know prior to that is that we're not
8016  * consistent yet.
8017  */
8019  minRecoveryPoint <= lastReplayedEndRecPtr &&
8021  {
8022  /*
8023  * Check to see if the XLOG sequence contained any unresolved
8024  * references to uninitialized pages.
8025  */
8027 
8028  reachedConsistency = true;
8029  ereport(LOG,
8030  (errmsg("consistent recovery state reached at %X/%X",
8031  (uint32) (lastReplayedEndRecPtr >> 32),
8032  (uint32) lastReplayedEndRecPtr)));
8033  }
8034 
8035  /*
8036  * Have we got a valid starting snapshot that will allow queries to be
8037  * run? If so, we can tell postmaster that the database is consistent now,
8038  * enabling connections.
8039  */
8044  {
8048 
8049  LocalHotStandbyActive = true;
8050 
8052  }
8053 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define DEBUG1
Definition: elog.h:25
void XLogCheckInvalidPages(void)
Definition: xlogutils.c:220
bool SharedHotStandbyActive
Definition: xlog.c:643
slock_t info_lck
Definition: xlog.c:698
#define LOG
Definition: elog.h:26
bool InArchiveRecovery
Definition: xlog.c:243
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
bool backupEndRequired
Definition: pg_control.h:170
#define SpinLockAcquire(lock)
Definition: spin.h:62
static bool LocalHotStandbyActive
Definition: xlog.c:217
void UpdateControlFile(void)
Definition: xlog.c:4754
bool IsUnderPostmaster
Definition: globals.c:109
unsigned int uint32
Definition: c.h:358
#define ereport(elevel, rest)
Definition: elog.h:141
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
#define SpinLockRelease(lock)
Definition: spin.h:64
static ControlFileData * ControlFile
Definition: xlog.c:709
XLogRecPtr backupEndPoint
Definition: pg_control.h:169
bool reachedConsistency
Definition: xlog.c:834
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:732
static XLogCtlData * XLogCtl
Definition: xlog.c:701
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:146
HotStandbyState standbyState
Definition: xlog.c:191
XLogRecPtr backupStartPoint
Definition: pg_control.h:168
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:825
XLogRecPtr lastReplayedEndRecPtr
Definition: xlog.c:677

◆ CheckRequiredParameterValues()

static void CheckRequiredParameterValues ( void  )
static

Definition at line 6306 of file xlog.c.

References ArchiveRecoveryRequested, EnableHotStandby, ereport, errhint(), errmsg(), ERROR, max_locks_per_xact, ControlFileData::max_locks_per_xact, max_prepared_xacts, ControlFileData::max_prepared_xacts, max_worker_processes, ControlFileData::max_worker_processes, MaxConnections, ControlFileData::MaxConnections, RecoveryRequiresIntParameter, ControlFileData::wal_level, WAL_LEVEL_MINIMAL, WAL_LEVEL_REPLICA, and WARNING.

Referenced by StartupXLOG(), and xlog_redo().

6307 {
6308  /*
6309  * For archive recovery, the WAL must be generated with at least 'replica'
6310  * wal_level.
6311  */
6313  {
6314  ereport(WARNING,
6315  (errmsg("WAL was generated with wal_level=minimal, data may be missing"),
6316  errhint("This happens if you temporarily set wal_level=minimal without taking a new base backup.")));
6317  }
6318 
6319  /*
6320  * For Hot Standby, the WAL must be generated with 'replica' mode, and we
6321  * must have at least as many backend slots as the primary.
6322  */
6324  {
6326  ereport(ERROR,
6327  (errmsg("hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server"),
6328  errhint("Either set wal_level to \"replica\" on the master, or turn off hot_standby here.")));
6329 
6330  /* We ignore autovacuum_max_workers when we make this test. */
6331  RecoveryRequiresIntParameter("max_connections",
6334  RecoveryRequiresIntParameter("max_worker_processes",
6337  RecoveryRequiresIntParameter("max_prepared_transactions",
6340  RecoveryRequiresIntParameter("max_locks_per_transaction",
6343  }
6344 }
bool ArchiveRecoveryRequested
Definition: xlog.c:242
int max_locks_per_xact
Definition: pg_control.h:181
int errhint(const char *fmt,...)
Definition: elog.c:974
int max_prepared_xacts
Definition: pg_control.h:180
int max_worker_processes
Definition: pg_control.h:179
#define ERROR
Definition: elog.h:43
int max_prepared_xacts
Definition: twophase.c:117
#define ereport(elevel, rest)
Definition: elog.h:141
int max_locks_per_xact
Definition: lock.c:54
#define WARNING
Definition: elog.h:40
int MaxConnections
Definition: globals.c:132
static ControlFileData * ControlFile
Definition: xlog.c:709
bool EnableHotStandby
Definition: xlog.c:90
int errmsg(const char *fmt,...)
Definition: elog.c:784
int max_worker_processes
Definition: globals.c:133
#define RecoveryRequiresIntParameter(param_name, currValue, minValue)
Definition: xlog.c:6284

◆ checkTimeLineSwitch()

static void checkTimeLineSwitch ( XLogRecPtr  lsn,
TimeLineID  newTLI,
TimeLineID  prevTLI 
)
static

Definition at line 9750 of file xlog.c.

References ereport, errmsg(), minRecoveryPoint, minRecoveryPointTLI, PANIC, ThisTimeLineID, tliInHistory(), and XLogRecPtrIsInvalid.

Referenced by StartupXLOG().

9751 {
9752  /* Check that the record agrees on what the current (old) timeline is */
9753  if (prevTLI != ThisTimeLineID)
9754  ereport(PANIC,
9755  (errmsg("unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record",
9756  prevTLI, ThisTimeLineID)));
9757 
9758  /*
9759  * The new timeline better be in the list of timelines we expect to see,
9760  * according to the timeline history. It should also not decrease.
9761  */
9762  if (newTLI < ThisTimeLineID || !tliInHistory(newTLI, expectedTLEs))
9763  ereport(PANIC,
9764  (errmsg("unexpected timeline ID %u (after %u) in checkpoint record",
9765  newTLI, ThisTimeLineID)));
9766 
9767  /*
9768  * If we have not yet reached min recovery point, and we're about to
9769  * switch to a timeline greater than the timeline of the min recovery
9770  * point: trouble. After switching to the new timeline, we could not
9771  * possibly visit the min recovery point on the correct timeline anymore.
9772  * This can happen if there is a newer timeline in the archive that
9773  * branched before the timeline the min recovery point is on, and you
9774  * attempt to do PITR to the new timeline.
9775  */
9777  lsn < minRecoveryPoint &&
9778  newTLI > minRecoveryPointTLI)
9779  ereport(PANIC,
9780  (errmsg("unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u",
9781  newTLI,
9782  (uint32) (minRecoveryPoint >> 32),
9785 
9786  /* Looks good */
9787 }
static List * expectedTLEs
Definition: xlog.c:314
#define PANIC
Definition: elog.h:53
unsigned int uint32
Definition: c.h:358
#define ereport(elevel, rest)
Definition: elog.h:141
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
static TimeLineID minRecoveryPointTLI
Definition: xlog.c:826
TimeLineID ThisTimeLineID
Definition: xlog.c:175
int errmsg(const char *fmt,...)
Definition: elog.c:784
bool tliInHistory(TimeLineID tli, List *expectedTLEs)
Definition: timeline.c:515
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:825

◆ checkXLogConsistency()

static void checkXLogConsistency ( XLogReaderState record)
static

Definition at line 1357 of file xlog.c.

References Assert, buf, BUFFER_LOCK_EXCLUSIVE, BufferGetPage, BufferIsValid, RelFileNode::dbNode, elog, XLogReaderState::EndRecPtr, ERROR, FATAL, LockBuffer(), master_image_masked, XLogReaderState::max_block_id, PageGetLSN, RBM_NORMAL_NO_LOG, RelFileNode::relNode, replay_image_masked, RestoreBlockImage(), RmgrData::rm_mask, RmgrTable, RelFileNode::spcNode, UnlockReleaseBuffer(), XLogReadBufferExtended(), XLogRecBlockImageApply, XLogRecGetBlockTag(), XLogRecGetInfo, XLogRecGetRmid, XLogRecHasAnyBlockRefs, XLogRecHasBlockImage, and XLR_CHECK_CONSISTENCY.

Referenced by StartupXLOG().

1358 {
1359  RmgrId rmid = XLogRecGetRmid(record);
1360  RelFileNode rnode;
1361  ForkNumber forknum;
1362  BlockNumber blkno;
1363  int block_id;
1364 
1365  /* Records with no backup blocks have no need for consistency checks. */
1366  if (!XLogRecHasAnyBlockRefs(record))
1367  return;
1368 
1369  Assert((XLogRecGetInfo(record) & XLR_CHECK_CONSISTENCY) != 0);
1370 
1371  for (block_id = 0; block_id <= record->max_block_id; block_id++)
1372  {
1373  Buffer buf;
1374  Page page;
1375 
1376  if (!XLogRecGetBlockTag(record, block_id, &rnode, &forknum, &blkno))
1377  {
1378  /*
1379  * WAL record doesn't contain a block reference with the given id.
1380  * Do nothing.
1381  */
1382  continue;
1383  }
1384 
1385  Assert(XLogRecHasBlockImage(record, block_id));
1386 
1387  if (XLogRecBlockImageApply(record, block_id))
1388  {
1389  /*
1390  * WAL record has already applied the page, so bypass the
1391  * consistency check as that would result in comparing the full
1392  * page stored in the record with itself.
1393  */
1394  continue;
1395  }
1396 
1397  /*
1398  * Read the contents from the current buffer and store it in a
1399  * temporary page.
1400  */
1401  buf = XLogReadBufferExtended(rnode, forknum, blkno,
1403  if (!BufferIsValid(buf))
1404  continue;
1405 
1407  page = BufferGetPage(buf);
1408 
1409  /*
1410  * Take a copy of the local page where WAL has been applied to have a
1411  * comparison base before masking it...
1412  */
1413  memcpy(replay_image_masked, page, BLCKSZ);
1414 
1415  /* No need for this page anymore now that a copy is in. */
1416  UnlockReleaseBuffer(buf);
1417 
1418  /*
1419  * If the block LSN is already ahead of this WAL record, we can't
1420  * expect contents to match. This can happen if recovery is
1421  * restarted.
1422  */
1423  if (PageGetLSN(replay_image_masked) > record->EndRecPtr)
1424  continue;
1425 
1426  /*
1427  * Read the contents from the backup copy, stored in WAL record and
1428  * store it in a temporary page. There is no need to allocate a new
1429  * page here, a local buffer is fine to hold its contents and a mask
1430  * can be directly applied on it.
1431  */
1432  if (!RestoreBlockImage(record, block_id, master_image_masked))
1433  elog(ERROR, "failed to restore block image");
1434 
1435  /*
1436  * If masking function is defined, mask both the master and replay
1437  * images
1438  */
1439  if (RmgrTable[rmid].rm_mask != NULL)
1440  {
1441  RmgrTable[rmid].rm_mask(replay_image_masked, blkno);
1442  RmgrTable[rmid].rm_mask(master_image_masked, blkno);
1443  }
1444 
1445  /* Time to compare the master and replay images. */
1446  if (memcmp(replay_image_masked, master_image_masked, BLCKSZ) != 0)
1447  {
1448  elog(FATAL,
1449  "inconsistent page found, rel %u/%u/%u, forknum %u, blkno %u",
1450  rnode.spcNode, rnode.dbNode, rnode.relNode,
1451  forknum, blkno);
1452  }
1453  }
1454 }
#define XLogRecHasBlockImage(decoder, block_id)
Definition: xlogreader.h:235
Buffer XLogReadBufferExtended(RelFileNode rnode, ForkNumber forknum, BlockNumber blkno, ReadBufferMode mode)
Definition: xlogutils.c:437
const RmgrData RmgrTable[RM_MAX_ID+1]
Definition: rmgr.c:36
uint32 BlockNumber
Definition: block.h:31
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:89
#define XLR_CHECK_CONSISTENCY
Definition: xlogrecord.h:80
XLogRecPtr EndRecPtr
Definition: xlogreader.h:120
static char * replay_image_masked
Definition: xlog.c:249
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
static char * buf
Definition: pg_test_fsync.c:67
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:226
ForkNumber
Definition: relpath.h:40
void(* rm_mask)(char *pagedata, BlockNumber blkno)
bool XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id, RelFileNode *rnode, ForkNumber *forknum, BlockNumber *blknum)
Definition: xlogreader.c:1358
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
uint8 RmgrId
Definition: rmgr.h:11
#define Assert(condition)
Definition: c.h:732
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
bool RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page)
Definition: xlogreader.c:1411
#define PageGetLSN(page)
Definition: bufpage.h:362
#define elog(elevel,...)
Definition: elog.h:226
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:232
#define XLogRecBlockImageApply(decoder, block_id)
Definition: xlogreader.h:237
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
#define XLogRecGetRmid(decoder)
Definition: xlogreader.h:227
static char * master_image_masked
Definition: xlog.c:250

◆ CheckXLogRemoved()

void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)

Definition at line 3814 of file xlog.c.

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

Referenced by perform_base_backup(), and XLogRead().

3815 {
3816  int save_errno = errno;
3817  XLogSegNo lastRemovedSegNo;
3818 
3820  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3822 
3823  if (segno <= lastRemovedSegNo)
3824  {
3825  char filename[MAXFNAMELEN];
3826 
3827  XLogFileName(filename, tli, segno, wal_segment_size);
3828  errno = save_errno;
3829  ereport(ERROR,
3831  errmsg("requested WAL segment %s has already been removed",
3832  filename)));
3833  }
3834  errno = save_errno;
3835 }
int wal_segment_size
Definition: xlog.c:107
slock_t info_lck
Definition: xlog.c:698
XLogSegNo lastRemovedSegNo
Definition: xlog.c:581
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define ERROR
Definition: elog.h:43
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static XLogCtlData * XLogCtl
Definition: xlog.c:701
static char * filename
Definition: pg_dumpall.c:88
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ CleanupBackupHistory()

static void CleanupBackupHistory ( void  )
static

Definition at line 4171 of file xlog.c.

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

Referenced by do_pg_stop_backup().

4172 {
4173  DIR *xldir;
4174  struct dirent *xlde;
4175  char path[MAXPGPATH + sizeof(XLOGDIR)];
4176 
4177  xldir = AllocateDir(XLOGDIR);
4178 
4179  while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
4180  {
4181  if (IsBackupHistoryFileName(xlde->d_name))
4182  {
4183  if (XLogArchiveCheckDone(xlde->d_name))
4184  {
4185  elog(DEBUG2, "removing WAL backup history file \"%s\"",
4186  xlde->d_name);
4187  snprintf(path, sizeof(path), XLOGDIR "/%s", xlde->d_name);
4188  unlink(path);
4189  XLogArchiveCleanup(xlde->d_name);
4190  }
4191  }
4192  }
4193 
4194  FreeDir(xldir);
4195 }
Definition: dirent.h:9
void XLogArchiveCleanup(const char *xlog)
Definition: xlogarchive.c:759
Definition: dirent.c:25
bool XLogArchiveCheckDone(const char *xlog)
Definition: xlogarchive.c:619
#define MAXPGPATH
#define DEBUG2
Definition: elog.h:24
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2431
#define IsBackupHistoryFileName(fname)
#define XLOGDIR
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2497
#define elog(elevel,...)
Definition: elog.h:226
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192
int FreeDir(DIR *dir)
Definition: fd.c:2549

◆ CopyXLogRecordToWAL()

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

Definition at line 1461 of file xlog.c.

References Assert, XLogRecData::data, elog, 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().

1463 {
1464  char *currpos;
1465  int freespace;
1466  int written;
1467  XLogRecPtr CurrPos;
1468  XLogPageHeader pagehdr;
1469 
1470  /*
1471  * Get a pointer to the right place in the right WAL buffer to start
1472  * inserting to.
1473  */
1474  CurrPos = StartPos;
1475  currpos = GetXLogBuffer(CurrPos);
1476  freespace = INSERT_FREESPACE(CurrPos);
1477 
1478  /*
1479  * there should be enough space for at least the first field (xl_tot_len)
1480  * on this page.
1481  */
1482  Assert(freespace >= sizeof(uint32));
1483 
1484  /* Copy record data */
1485  written = 0;
1486  while (rdata != NULL)
1487  {
1488  char *rdata_data = rdata->data;
1489  int rdata_len = rdata->len;
1490 
1491  while (rdata_len > freespace)
1492  {
1493  /*
1494  * Write what fits on this page, and continue on the next page.
1495  */
1496  Assert(CurrPos % XLOG_BLCKSZ >= SizeOfXLogShortPHD || freespace == 0);
1497  memcpy(currpos, rdata_data, freespace);
1498  rdata_data += freespace;
1499  rdata_len -= freespace;
1500  written += freespace;
1501  CurrPos += freespace;
1502 
1503  /*
1504  * Get pointer to beginning of next page, and set the xlp_rem_len
1505  * in the page header. Set XLP_FIRST_IS_CONTRECORD.
1506  *
1507  * It's safe to set the contrecord flag and xlp_rem_len without a
1508  * lock on the page. All the other flags were already set when the
1509  * page was initialized, in AdvanceXLInsertBuffer, and we're the
1510  * only backend that needs to set the contrecord flag.
1511  */
1512  currpos = GetXLogBuffer(CurrPos);
1513  pagehdr = (XLogPageHeader) currpos;
1514  pagehdr->xlp_rem_len = write_len - written;
1515  pagehdr->xlp_info |= XLP_FIRST_IS_CONTRECORD;
1516 
1517  /* skip over the page header */
1518  if (XLogSegmentOffset(CurrPos, wal_segment_size) == 0)
1519  {
1520  CurrPos += SizeOfXLogLongPHD;
1521  currpos += SizeOfXLogLongPHD;
1522  }
1523  else
1524  {
1525  CurrPos += SizeOfXLogShortPHD;
1526  currpos += SizeOfXLogShortPHD;
1527  }
1528  freespace = INSERT_FREESPACE(CurrPos);
1529  }
1530 
1531  Assert(CurrPos % XLOG_BLCKSZ >= SizeOfXLogShortPHD || rdata_len == 0);
1532  memcpy(currpos, rdata_data, rdata_len);
1533  currpos += rdata_len;
1534  CurrPos += rdata_len;
1535  freespace -= rdata_len;
1536  written += rdata_len;
1537 
1538  rdata = rdata->next;
1539  }
1540  Assert(written == write_len);
1541 
1542  /*
1543  * If this was an xlog-switch, it's not enough to write the switch record,
1544  * we also have to consume all the remaining space in the WAL segment. We
1545  * have already reserved that space, but we need to actually fill it.
1546  */
1547  if (isLogSwitch && XLogSegmentOffset(CurrPos, wal_segment_size) != 0)
1548  {
1549  /* An xlog-switch record doesn't contain any data besides the header */
1550  Assert(write_len == SizeOfXLogRecord);
1551 
1552  /* Assert that we did reserve the right amount of space */
1553  Assert(XLogSegmentOffset(EndPos, wal_segment_size) == 0);
1554 
1555  /* Use up all the remaining space on the current page */
1556  CurrPos += freespace;
1557 
1558  /*
1559  * Cause all remaining pages in the segment to be flushed, leaving the
1560  * XLog position where it should be, at the start of the next segment.
1561  * We do this one page at a time, to make sure we don't deadlock
1562  * against ourselves if wal_buffers < wal_segment_size.
1563  */
1564  while (CurrPos < EndPos)
1565  {
1566  /*
1567  * The minimal action to flush the page would be to call
1568  * WALInsertLockUpdateInsertingAt(CurrPos) followed by
1569  * AdvanceXLInsertBuffer(...). The page would be left initialized
1570  * mostly to zeros, except for the page header (always the short
1571  * variant, as this is never a segment's first page).
1572  *
1573  * The large vistas of zeros are good for compressibility, but the
1574  * headers interrupting them every XLOG_BLCKSZ (with values that
1575  * differ from page to page) are not. The effect varies with
1576  * compression tool, but bzip2 for instance compresses about an
1577  * order of magnitude worse if those headers are left in place.
1578  *
1579  * Rather than complicating AdvanceXLInsertBuffer itself (which is
1580  * called in heavily-loaded circumstances as well as this lightly-
1581  * loaded one) with variant behavior, we just use GetXLogBuffer
1582  * (which itself calls the two methods we need) to get the pointer
1583  * and zero most of the page. Then we just zero the page header.
1584  */
1585  currpos = GetXLogBuffer(CurrPos);
1586  MemSet(currpos, 0, SizeOfXLogShortPHD);
1587 
1588  CurrPos += XLOG_BLCKSZ;
1589  }
1590  }
1591  else
1592  {
1593  /* Align the end position, so that the next record starts aligned */
1594  CurrPos = MAXALIGN64(CurrPos);
1595  }
1596 
1597  if (CurrPos != EndPos)
1598  elog(PANIC, "space reserved for WAL record does not match what was written");
1599 }
int wal_segment_size
Definition: xlog.c:107
#define MemSet(start, val, len)
Definition: c.h:941
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:57
#define PANIC
Definition: elog.h:53
static char * GetXLogBuffer(XLogRecPtr ptr)
Definition: xlog.c:1837
#define MAXALIGN64(LEN)
Definition: c.h:710
unsigned int uint32
Definition: c.h:358
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:715
#define SizeOfXLogRecord
Definition: xlogrecord.h:55
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:732
#define SizeOfXLogShortPHD
Definition: xlog_internal.h:55
#define XLP_FIRST_IS_CONTRECORD
Definition: xlog_internal.h:77
struct XLogRecData * next
#define elog(elevel,...)
Definition: elog.h:226
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72

◆ CreateCheckPoint()

void CreateCheckPoint ( int  flags)

Definition at line 8712 of file xlog.c.

References ControlFileData::checkPoint, CHECKPOINT_END_OF_RECOVERY, CHECKPOINT_FORCE, CHECKPOINT_IS_SHUTDOWN, ControlFileData::checkPointCopy, CheckPointGuts(), CheckpointStatsData::ckpt_bufs_written, CheckpointStatsData::ckpt_segs_added, CheckpointStatsData::ckpt_segs_recycled, CheckpointStatsData::ckpt_segs_removed, CheckpointStatsData::ckpt_start_t, XLogCtlData::ckptXid, XLogCtlData::ckptXidEpoch, XLogCtlInsert::CurrBytePos, DB_SHUTDOWNED, DB_SHUTDOWNING, DEBUG1, elog, END_CRIT_SECTION, ereport, errmsg(), ERROR, CheckPoint::fullPageWrites, XLogCtlInsert::fullPageWrites, GetCurrentTimestamp(), GetLastImportantRecPtr(), GetOldestActiveTransactionId(), GetOldestXmin(), GetVirtualXIDsDelayingChkpt(), HaveVirtualXIDsDelayingChkpt(), XLogCtlData::info_lck, InitXLogInsert(), Insert(), XLogCtlData::Insert, INSERT_FREESPACE, InvalidTransactionId, InvalidXLogRecPtr, KeepLogSeg(), LocalSetXLogInsertAllowed(), LocalXLogInsertAllowed, log_checkpoints, LogCheckpointEnd(), LogCheckpointStart(), LogStandbySnapshot(), LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockRelease(), MemSet, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, MultiXactGetCheckptMulti(), NBuffers, CheckPoint::newestCommitTsXid, VariableCacheData::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, VariableCacheData::nextOid, CheckPoint::nextXid, VariableCacheData::nextXid, CheckPoint::nextXidEpoch, VariableCacheData::oidCount, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, VariableCacheData::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, VariableCacheData::oldestXid, CheckPoint::oldestXidDB, VariableCacheData::oldestXidDB, PANIC, pfree(), pg_usleep(), PreallocXlogFiles(), CheckPoint::PrevTimeLineID, XLogCtlData::PrevTimeLineID, PROCARRAY_FLAGS_DEFAULT, ProcLastRecPtr, RecoveryInProgress(), CheckPoint::redo, RedoRecPtr, XLogCtlInsert::RedoRecPtr, XLogCtlData::RedoRecPtr, RemoveOldXlogFiles(), ShmemVariableCache, SizeOfXLogLongPHD, SizeOfXLogShortPHD, smgrpostckpt(), smgrpreckpt(), SpinLockAcquire, SpinLockRelease, START_CRIT_SECTION, ControlFileData::state, CheckPoint::ThisTimeLineID, ThisTimeLineID, CheckPoint::time, ControlFileData::time, TruncateSUBTRANS(), XLogCtlData::ulsn_lck, ControlFileData::unloggedLSN, XLogCtlData::unloggedLSN, UpdateCheckPointDistanceEstimate(), UpdateControlFile(), wal_segment_size, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), XLByteToSeg, XLOG_CHECKPOINT_ONLINE, XLOG_CHECKPOINT_SHUTDOWN, XLogBeginInsert(), XLogBytePosToRecPtr(), XLogFlush(), XLogInsert(), XLogRegisterData(), XLogSegmentOffset, and XLogStandbyInfoActive.

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

8713 {
8714  bool shutdown;
8715  CheckPoint checkPoint;
8716  XLogRecPtr recptr;
8717  XLogSegNo _logSegNo;
8719  uint32 freespace;
8720  XLogRecPtr PriorRedoPtr;
8721  XLogRecPtr curInsert;
8722  XLogRecPtr last_important_lsn;
8723  VirtualTransactionId *vxids;
8724  int nvxids;
8725 
8726  /*
8727  * An end-of-recovery checkpoint is really a shutdown checkpoint, just
8728  * issued at a different time.
8729  */
8731  shutdown = true;
8732  else
8733  shutdown = false;
8734 
8735  /* sanity check */
8736  if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
8737  elog(ERROR, "can't create a checkpoint during recovery");
8738 
8739  /*
8740  * Initialize InitXLogInsert working areas before entering the critical
8741  * section. Normally, this is done by the first call to
8742  * RecoveryInProgress() or LocalSetXLogInsertAllowed(), but when creating
8743  * an end-of-recovery checkpoint, the LocalSetXLogInsertAllowed call is
8744  * done below in a critical section, and InitXLogInsert cannot be called
8745  * in a critical section.
8746  */
8747  InitXLogInsert();
8748 
8749  /*
8750  * Acquire CheckpointLock to ensure only one checkpoint happens at a time.
8751  * (This is just pro forma, since in the present system structure there is
8752  * only one process that is allowed to issue checkpoints at any given
8753  * time.)
8754  */
8755  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
8756 
8757  /*
8758  * Prepare to accumulate statistics.
8759  *
8760  * Note: because it is possible for log_checkpoints to change while a
8761  * checkpoint proceeds, we always accumulate stats, even if
8762  * log_checkpoints is currently off.
8763  */
8764  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
8766 
8767  /*
8768  * Use a critical section to force system panic if we have trouble.
8769  */
8771 
8772  if (shutdown)
8773  {
8774  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8776  ControlFile->time = (pg_time_t) time(NULL);
8778  LWLockRelease(ControlFileLock);
8779  }
8780 
8781  /*
8782  * Let smgr prepare for checkpoint; this has to happen before we determine
8783  * the REDO pointer. Note that smgr must not do anything that'd have to
8784  * be undone if we decide no checkpoint is needed.
8785  */
8786  smgrpreckpt();
8787 
8788  /* Begin filling in the checkpoint WAL record */
8789  MemSet(&checkPoint, 0, sizeof(checkPoint));
8790  checkPoint.time = (pg_time_t) time(NULL);
8791 
8792  /*
8793  * For Hot Standby, derive the oldestActiveXid before we fix the redo
8794  * pointer. This allows us to begin accumulating changes to assemble our
8795  * starting snapshot of locks and transactions.
8796  */
8797  if (!shutdown && XLogStandbyInfoActive())
8799  else
8801 
8802  /*
8803  * Get location of last important record before acquiring insert locks (as
8804  * GetLastImportantRecPtr() also locks WAL locks).
8805  */
8806  last_important_lsn = GetLastImportantRecPtr();
8807 
8808  /*
8809  * We must block concurrent insertions while examining insert state to
8810  * determine the checkpoint REDO pointer.
8811  */
8813  curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
8814 
8815  /*
8816  * If this isn't a shutdown or forced checkpoint, and if there has been no
8817  * WAL activity requiring a checkpoint, skip it. The idea here is to
8818  * avoid inserting duplicate checkpoints when the system is idle.
8819  */
8820  if ((flags & (CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_END_OF_RECOVERY |
8821  CHECKPOINT_FORCE)) == 0)
8822  {
8823  if (last_important_lsn == ControlFile->checkPoint)
8824  {
8826  LWLockRelease(CheckpointLock);
8827  END_CRIT_SECTION();
8828  ereport(DEBUG1,
8829  (errmsg("checkpoint skipped because system is idle")));
8830  return;
8831  }
8832  }
8833 
8834  /*
8835  * An end-of-recovery checkpoint is created before anyone is allowed to
8836  * write WAL. To allow us to write the checkpoint record, temporarily
8837  * enable XLogInsertAllowed. (This also ensures ThisTimeLineID is
8838  * initialized, which we need here and in AdvanceXLInsertBuffer.)
8839  */
8840  if (flags & CHECKPOINT_END_OF_RECOVERY)
8842 
8843  checkPoint.ThisTimeLineID = ThisTimeLineID;
8844  if (flags & CHECKPOINT_END_OF_RECOVERY)
8845  checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
8846  else
8847  checkPoint.PrevTimeLineID = ThisTimeLineID;
8848 
8849  checkPoint.fullPageWrites = Insert->fullPageWrites;
8850 
8851  /*
8852  * Compute new REDO record ptr = location of next XLOG record.
8853  *
8854  * NB: this is NOT necessarily where the checkpoint record itself will be,
8855  * since other backends may insert more XLOG records while we're off doing
8856  * the buffer flush work. Those XLOG records are logically after the
8857  * checkpoint, even though physically before it. Got that?
8858  */
8859  freespace = INSERT_FREESPACE(curInsert);
8860  if (freespace == 0)
8861  {
8862  if (XLogSegmentOffset(curInsert, wal_segment_size) == 0)
8863  curInsert += SizeOfXLogLongPHD;
8864  else
8865  curInsert += SizeOfXLogShortPHD;
8866  }
8867  checkPoint.redo = curInsert;
8868 
8869  /*
8870  * Here we update the shared RedoRecPtr for future XLogInsert calls; this
8871  * must be done while holding all the insertion locks.
8872  *
8873  * Note: if we fail to complete the checkpoint, RedoRecPtr will be left
8874  * pointing past where it really needs to point. This is okay; the only
8875  * consequence is that XLogInsert might back up whole buffers that it
8876  * didn't really need to. We can't postpone advancing RedoRecPtr because
8877  * XLogInserts that happen while we are dumping buffers must assume that
8878  * their buffer changes are not included in the checkpoint.
8879  */
8880  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
8881 
8882  /*
8883  * Now we can release the WAL insertion locks, allowing other xacts to
8884  * proceed while we are flushing disk buffers.
8885  */
8887 
8888  /* Update the info_lck-protected copy of RedoRecPtr as well */
8890  XLogCtl->RedoRecPtr = checkPoint.redo;
8892 
8893  /*
8894  * If enabled, log checkpoint start. We postpone this until now so as not
8895  * to log anything if we decided to skip the checkpoint.
8896  */
8897  if (log_checkpoints)
8898  LogCheckpointStart(flags, false);
8899 
8900  TRACE_POSTGRESQL_CHECKPOINT_START(flags);
8901 
8902  /*
8903  * Get the other info we need for the checkpoint record.
8904  *
8905  * We don't need to save oldestClogXid in the checkpoint, it only matters
8906  * for the short period in which clog is being truncated, and if we crash
8907  * during that we'll redo the clog truncation and fix up oldestClogXid
8908  * there.
8909  */
8910  LWLockAcquire(XidGenLock, LW_SHARED);
8911  checkPoint.nextXid = ShmemVariableCache->nextXid;
8912  checkPoint.oldestXid = ShmemVariableCache->oldestXid;
8914  LWLockRelease(XidGenLock);
8915 
8916  LWLockAcquire(CommitTsLock, LW_SHARED);
8919  LWLockRelease(CommitTsLock);
8920 
8921  /* Increase XID epoch if we've wrapped around since last checkpoint */
8923  if (checkPoint.nextXid < ControlFile->checkPointCopy.nextXid)
8924  checkPoint.nextXidEpoch++;
8925 
8926  LWLockAcquire(OidGenLock, LW_SHARED);
8927  checkPoint.nextOid = ShmemVariableCache->nextOid;
8928  if (!shutdown)
8929  checkPoint.nextOid += ShmemVariableCache->oidCount;
8930  LWLockRelease(OidGenLock);
8931 
8932  MultiXactGetCheckptMulti(shutdown,
8933  &checkPoint.nextMulti,
8934  &checkPoint.nextMultiOffset,
8935  &checkPoint.oldestMulti,
8936  &checkPoint.oldestMultiDB);
8937 
8938  /*
8939  * Having constructed the checkpoint record, ensure all shmem disk buffers
8940  * and commit-log buffers are flushed to disk.
8941  *
8942  * This I/O could fail for various reasons. If so, we will fail to
8943  * complete the checkpoint, but there is no reason to force a system
8944  * panic. Accordingly, exit critical section while doing it.
8945  */
8946  END_CRIT_SECTION();
8947 
8948  /*
8949  * In some cases there are groups of actions that must all occur on one
8950  * side or the other of a checkpoint record. Before flushing the
8951  * checkpoint record we must explicitly wait for any backend currently
8952  * performing those groups of actions.
8953  *
8954  * One example is end of transaction, so we must wait for any transactions
8955  * that are currently in commit critical sections. If an xact inserted
8956  * its commit record into XLOG just before the REDO point, then a crash
8957  * restart from the REDO point would not replay that record, which means
8958  * that our flushing had better include the xact's update of pg_xact. So
8959  * we wait till he's out of his commit critical section before proceeding.
8960  * See notes in RecordTransactionCommit().
8961  *
8962  * Because we've already released the insertion locks, this test is a bit
8963  * fuzzy: it is possible that we will wait for xacts we didn't really need
8964  * to wait for. But the delay should be short and it seems better to make
8965  * checkpoint take a bit longer than to hold off insertions longer than
8966  * necessary. (In fact, the whole reason we have this issue is that xact.c
8967  * does commit record XLOG insertion and clog update as two separate steps
8968  * protected by different locks, but again that seems best on grounds of
8969  * minimizing lock contention.)
8970  *
8971  * A transaction that has not yet set delayChkpt when we look cannot be at
8972  * risk, since he's not inserted his commit record yet; and one that's
8973  * already cleared it is not at risk either, since he's done fixing clog
8974  * and we will correctly flush the update below. So we cannot miss any
8975  * xacts we need to wait for.
8976  */
8977  vxids = GetVirtualXIDsDelayingChkpt(&nvxids);
8978  if (nvxids > 0)
8979  {
8980  do
8981  {
8982  pg_usleep(10000L); /* wait for 10 msec */
8983  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids));
8984  }
8985  pfree(vxids);
8986 
8987  CheckPointGuts(checkPoint.redo, flags);
8988 
8989  /*
8990  * Take a snapshot of running transactions and write this to WAL. This
8991  * allows us to reconstruct the state of running transactions during
8992  * archive recovery, if required. Skip, if this info disabled.
8993  *
8994  * If we are shutting down, or Startup process is completing crash
8995  * recovery we don't need to write running xact data.
8996  */
8997  if (!shutdown && XLogStandbyInfoActive())
8999 
9001 
9002  /*
9003  * Now insert the checkpoint record into XLOG.
9004  */
9005  XLogBeginInsert();
9006  XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));
9007  recptr = XLogInsert(RM_XLOG_ID,
9008  shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
9010 
9011  XLogFlush(recptr);
9012 
9013  /*
9014  * We mustn't write any new WAL after a shutdown checkpoint, or it will be
9015  * overwritten at next startup. No-one should even try, this just allows
9016  * sanity-checking. In the case of an end-of-recovery checkpoint, we want
9017  * to just temporarily disable writing until the system has exited
9018  * recovery.
9019  */
9020  if (shutdown)
9021  {
9022  if (flags & CHECKPOINT_END_OF_RECOVERY)
9023  LocalXLogInsertAllowed = -1; /* return to "check" state */
9024  else
9025  LocalXLogInsertAllowed = 0; /* never again write WAL */
9026  }
9027 
9028  /*
9029  * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
9030  * = end of actual checkpoint record.
9031  */
9032  if (shutdown && checkPoint.redo != ProcLastRecPtr)
9033  ereport(PANIC,
9034  (errmsg("concurrent write-ahead log activity while database system is shutting down")));
9035 
9036  /*
9037  * Remember the prior checkpoint's redo ptr for
9038  * UpdateCheckPointDistanceEstimate()
9039  */
9040  PriorRedoPtr = ControlFile->checkPointCopy.redo;
9041 
9042  /*
9043  * Update the control file.
9044  */
9045  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9046  if (shutdown)
9049  ControlFile->checkPointCopy = checkPoint;
9050  ControlFile->time = (pg_time_t) time(NULL);
9051  /* crash recovery should always recover to the end of WAL */
9054 
9055  /*
9056  * Persist unloggedLSN value. It's reset on crash recovery, so this goes
9057  * unused on non-shutdown checkpoints, but seems useful to store it always
9058  * for debugging purposes.
9059  */
9063 
9065  LWLockRelease(ControlFileLock);
9066 
9067  /* Update shared-memory copy of checkpoint XID/epoch */
9069  XLogCtl->ckptXidEpoch = checkPoint.nextXidEpoch;
9070  XLogCtl->ckptXid = checkPoint.nextXid;
9072 
9073  /*
9074  * We are now done with critical updates; no need for system panic if we
9075  * have trouble while fooling with old log segments.
9076  */
9077  END_CRIT_SECTION();
9078 
9079  /*
9080  * Let smgr do post-checkpoint cleanup (eg, deleting old files).
9081  */
9082  smgrpostckpt();
9083 
9084  /*
9085  * Update the average distance between checkpoints if the prior checkpoint
9086  * exists.
9087  */
9088  if (PriorRedoPtr != InvalidXLogRecPtr)
9090 
9091  /*
9092  * Delete old log files, those no longer needed for last checkpoint to
9093  * prevent the disk holding the xlog from growing full.
9094  */
9096  KeepLogSeg(recptr, &_logSegNo);
9097  _logSegNo--;
9098  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr);
9099 
9100  /*
9101  * Make more log segments if needed. (Do this after recycling old log
9102  * segments, since that may supply some of the needed files.)
9103  */
9104  if (!shutdown)
9105  PreallocXlogFiles(recptr);
9106 
9107  /*
9108  * Truncate pg_subtrans if possible. We can throw away all data before
9109  * the oldest XMIN of any running transaction. No future transaction will
9110  * attempt to reference any pg_subtrans entry older than that (see Asserts
9111  * in subtrans.c). During recovery, though, we mustn't do this because
9112  * StartupSUBTRANS hasn't been called yet.
9113  */
9114  if (!RecoveryInProgress())
9116 
9117  /* Real work is done, but log and update stats before releasing lock. */
9118  LogCheckpointEnd(false);
9119 
9120  TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
9121  NBuffers,
9125 
9126  LWLockRelease(CheckpointLock);
9127 }
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:8415
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8650
static int LocalXLogInsertAllowed
Definition: xlog.c:229
bool log_checkpoints
Definition: xlog.c:96
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define DEBUG1
Definition: elog.h:25
int64 pg_time_t
Definition: pgtime.h:23
TransactionId ckptXid
Definition: xlog.c:577
static void WALInsertLockRelease(void)
Definition: xlog.c:1679
int wal_segment_size
Definition: xlog.c:107
pg_time_t time
Definition: pg_control.h:128
#define XLOG_CHECKPOINT_ONLINE
Definition: pg_control.h:68
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
uint32 oidCount
Definition: transam.h:112
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1570
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1948
XLogRecPtr unloggedLSN
Definition: xlog.c:584
XLogRecPtr ProcLastRecPtr
Definition: xlog.c:332
TransactionId oldestActiveXid
Definition: pg_control.h:63
void InitXLogInsert(void)
Definition: xloginsert.c:1028
TimestampTz ckpt_start_t
Definition: xlog.h:199
slock_t info_lck
Definition: xlog.c:698
#define END_CRIT_SECTION()
Definition: miscadmin.h:134
VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids)
Definition: procarray.c:2287
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: xlog.c:625
TimeLineID PrevTimeLineID
Definition: pg_control.h:39
#define START_CRIT_SECTION()
Definition: miscadmin.h:132
int ckpt_segs_recycled
Definition: xlog.h:209
TransactionId oldestXid
Definition: transam.h:119
#define MemSet(start, val, len)
Definition: c.h:941
void MultiXactGetCheckptMulti(bool is_shutdown, MultiXactId *nextMulti, MultiXactOffset *nextMultiOffset, MultiXactId *oldestMulti, Oid *oldestMultiDB)
Definition: multixact.c:2118
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:9188
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:571
TransactionId oldestXid
Definition: pg_control.h:47
bool RecoveryInProgress(void)
Definition: xlog.c:8065
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:354
uint32 ckptXidEpoch
Definition: xlog.c:576
TransactionId nextXid
Definition: pg_control.h:43
pg_time_t time
Definition: pg_control.h:51
#define PANIC
Definition: elog.h:53
bool fullPageWrites
Definition: xlog.c:546
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2792
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
#define SpinLockAcquire(lock)
Definition: spin.h:62
void pg_usleep(long microsec)
Definition: signal.c:53
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
void UpdateControlFile(void)
Definition: xlog.c:4754
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
void pfree(void *pointer)
Definition: mcxt.c:1031
XLogRecPtr LogStandbySnapshot(void)
Definition: standby.c:901
#define ERROR
Definition: elog.h:43
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8565
TransactionId nextXid
Definition: transam.h:117
uint32 nextXidEpoch
Definition: pg_control.h:42
static XLogRecPtr RedoRecPtr
Definition: xlog.c:346
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
XLogRecPtr unloggedLSN
Definition: pg_control.h:133
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3781
uint64 XLogSegNo
Definition: xlogdefs.h:34
#define CHECKPOINT_END_OF_RECOVERY
Definition: xlog.h:177
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define InvalidTransactionId
Definition: transam.h:31
uint64 CurrBytePos
Definition: xlog.c:522
unsigned int uint32
Definition: c.h:358
XLogRecPtr RedoRecPtr
Definition: xlog.c:575
int ckpt_segs_removed
Definition: xlog.h:208
#define CHECKPOINT_FORCE
Definition: xlog.h:180
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:715
#define ereport(elevel, rest)
Definition: elog.h:141
TransactionId oldestCommitTsXid
Definition: transam.h:129
static void Insert(File file)
Definition: fd.c:1034
int ckpt_bufs_written
Definition: xlog.h:205
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8191
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
#define SpinLockRelease(lock)
Definition: spin.h:64
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
TransactionId newestCommitTsXid
Definition: pg_control.h:54
#define PROCARRAY_FLAGS_DEFAULT
Definition: procarray.h:50
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9508
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
Oid oldestMultiDB
Definition: pg_control.h:50
#define XLogStandbyInfoActive()
Definition: xlog.h:160
static ControlFileData * ControlFile
Definition: xlog.c:709
TimeLineID ThisTimeLineID
Definition: xlog.c:175
Oid nextOid
Definition: pg_control.h:44
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr RedoRecPtr, XLogRecPtr endptr)
Definition: xlog.c:3911
bool fullPageWrites
Definition: pg_control.h:41
TransactionId GetOldestXmin(Relation rel, int flags)
Definition: procarray.c:1321
void smgrpreckpt(void)
Definition: smgr.c:759
uint64 XLogRecPtr
Definition: xlogdefs.h:21
Oid oldestXidDB
Definition: pg_control.h:48
TransactionId newestCommitTsXid
Definition: transam.h:130
CheckpointStatsData CheckpointStats
Definition: xlog.c:169
#define SizeOfXLogShortPHD
Definition: xlog_internal.h:55
MultiXactId nextMulti
Definition: pg_control.h:45
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1650
static XLogCtlData * XLogCtl
Definition: xlog.c:701
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
int ckpt_segs_added
Definition: xlog.h:207
slock_t ulsn_lck
Definition: xlog.c:585
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
TransactionId GetOldestActiveTransactionId(void)
Definition: procarray.c:2125
int NBuffers
Definition: globals.c:131
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids)
Definition: procarray.c:2332
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr RedoRecPtr
Definition: xlog.c:544
void smgrpostckpt(void)
Definition: smgr.c:789
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:36
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8547
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:176
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ CreateEndOfRecoveryRecord()

static void CreateEndOfRecoveryRecord ( void  )
static

Definition at line 9139 of file xlog.c.

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

Referenced by StartupXLOG().

9140 {
9141  xl_end_of_recovery xlrec;
9142  XLogRecPtr recptr;
9143 
9144  /* sanity check */
9145  if (!RecoveryInProgress())
9146  elog(ERROR, "can only be used to end recovery");
9147 
9148  xlrec.end_time = GetCurrentTimestamp();
9149 
9154 
9156 
9158 
9159  XLogBeginInsert();
9160  XLogRegisterData((char *) &xlrec, sizeof(xl_end_of_recovery));
9161  recptr = XLogInsert(RM_XLOG_ID, XLOG_END_OF_RECOVERY);
9162 
9163  XLogFlush(recptr);
9164 
9165  /*
9166  * Update the control file so that crash recovery can follow the timeline
9167  * changes to this point.
9168  */
9169  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9170  ControlFile->time = (pg_time_t) time(NULL);
9171  ControlFile->minRecoveryPoint = recptr;
9174  LWLockRelease(ControlFileLock);
9175 
9176  END_CRIT_SECTION();
9177 
9178  LocalXLogInsertAllowed = -1; /* return to "check" state */
9179 }
static int LocalXLogInsertAllowed
Definition: xlog.c:229
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1679
pg_time_t time
Definition: pg_control.h:128
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
TimeLineID PrevTimeLineID
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1570
#define END_CRIT_SECTION()
Definition: miscadmin.h:134
TimeLineID PrevTimeLineID
Definition: xlog.c:625
#define START_CRIT_SECTION()
Definition: miscadmin.h:132
bool RecoveryInProgress(void)
Definition: xlog.c:8065
#define XLOG_END_OF_RECOVERY
Definition: pg_control.h:76
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2792
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
void UpdateControlFile(void)
Definition: xlog.c:4754
#define ERROR
Definition: elog.h:43
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8191
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
static ControlFileData * ControlFile
Definition: xlog.c:709
TimeLineID ThisTimeLineID
Definition: xlog.c:175
TimestampTz end_time
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1650
static XLogCtlData * XLogCtl
Definition: xlog.c:701
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
TimeLineID ThisTimeLineID
#define elog(elevel,...)
Definition: elog.h:226
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166

◆ CreateRestartPoint()

bool CreateRestartPoint ( int  flags)

Definition at line 9258 of file xlog.c.

References XLogCtlData::archiveCleanupCommand, ControlFileData::checkPoint, CHECKPOINT_IS_SHUTDOWN, ControlFileData::checkPointCopy, CheckPointGuts(), CheckpointStatsData::ckpt_start_t, DB_IN_ARCHIVE_RECOVERY, DB_SHUTDOWNED_IN_RECOVERY, DEBUG2, EnableHotStandby, ereport, errdetail(), errmsg(), ExecuteRecoveryCommand(), GetCurrentTimestamp(), GetLatestXTime(), GetOldestXmin(), GetWalRcvWriteRecPtr(), GetXLogReplayRecPtr(), XLogCtlData::info_lck, XLogCtlData::Insert, InvalidXLogRecPtr, KeepLogSeg(), XLogCtlData::lastCheckPoint, XLogCtlData::lastCheckPointEndPtr, XLogCtlData::lastCheckPointRecPtr, LOG, log_checkpoints, LogCheckpointEnd(), LogCheckpointStart(), LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MemSet, ControlFileData::minRecoveryPoint, minRecoveryPoint, ControlFileData::minRecoveryPointTLI, minRecoveryPointTLI, PreallocXlogFiles(), PROCARRAY_FLAGS_DEFAULT, RecoveryInProgress(), CheckPoint::redo, RedoRecPtr, XLogCtlInsert::RedoRecPtr, XLogCtlData::RedoRecPtr, RemoveOldXlogFiles(), SpinLockAcquire, SpinLockRelease, ControlFileData::state, CheckPoint::ThisTimeLineID, ThisTimeLineID, ControlFileData::time, timestamptz_to_str(), TruncateSUBTRANS(), UpdateCheckPointDistanceEstimate(), UpdateControlFile(), UpdateMinRecoveryPoint(), wal_segment_size, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), XLByteToSeg, and XLogRecPtrIsInvalid.

Referenced by CheckpointerMain(), and ShutdownXLOG().

9259 {
9260  XLogRecPtr lastCheckPointRecPtr;
9261  XLogRecPtr lastCheckPointEndPtr;
9262  CheckPoint lastCheckPoint;
9263  XLogRecPtr PriorRedoPtr;
9264  XLogRecPtr receivePtr;
9265  XLogRecPtr replayPtr;
9266  TimeLineID replayTLI;
9267  XLogRecPtr endptr;
9268  XLogSegNo _logSegNo;
9269  TimestampTz xtime;
9270 
9271  /*
9272  * Acquire CheckpointLock to ensure only one restartpoint or checkpoint
9273  * happens at a time.
9274  */
9275  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
9276 
9277  /* Get a local copy of the last safe checkpoint record. */
9279  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
9280  lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
9281  lastCheckPoint = XLogCtl->lastCheckPoint;
9283 
9284  /*
9285  * Check that we're still in recovery mode. It's ok if we exit recovery
9286  * mode after this check, the restart point is valid anyway.
9287  */
9288  if (!RecoveryInProgress())
9289  {
9290  ereport(DEBUG2,
9291  (errmsg("skipping restartpoint, recovery has already ended")));
9292  LWLockRelease(CheckpointLock);
9293  return false;
9294  }
9295 
9296  /*
9297  * If the last checkpoint record we've replayed is already our last
9298  * restartpoint, we can't perform a new restart point. We still update
9299  * minRecoveryPoint in that case, so that if this is a shutdown restart
9300  * point, we won't start up earlier than before. That's not strictly
9301  * necessary, but when hot standby is enabled, it would be rather weird if
9302  * the database opened up for read-only connections at a point-in-time
9303  * before the last shutdown. Such time travel is still possible in case of
9304  * immediate shutdown, though.
9305  *
9306  * We don't explicitly advance minRecoveryPoint when we do create a
9307  * restartpoint. It's assumed that flushing the buffers will do that as a
9308  * side-effect.
9309  */
9310  if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
9311  lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
9312  {
9313  ereport(DEBUG2,
9314  (errmsg("skipping restartpoint, already performed at %X/%X",
9315  (uint32) (lastCheckPoint.redo >> 32),
9316  (uint32) lastCheckPoint.redo)));
9317 
9319  if (flags & CHECKPOINT_IS_SHUTDOWN)
9320  {
9321  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9323  ControlFile->time = (pg_time_t) time(NULL);
9325  LWLockRelease(ControlFileLock);
9326  }
9327  LWLockRelease(CheckpointLock);
9328  return false;
9329  }
9330 
9331  /*
9332  * Update the shared RedoRecPtr so that the startup process can calculate
9333  * the number of segments replayed since last restartpoint, and request a
9334  * restartpoint if it exceeds CheckPointSegments.
9335  *
9336  * Like in CreateCheckPoint(), hold off insertions to update it, although
9337  * during recovery this is just pro forma, because no WAL insertions are
9338  * happening.
9339  */
9341  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
9343 
9344  /* Also update the info_lck-protected copy */
9346  XLogCtl->RedoRecPtr = lastCheckPoint.redo;
9348 
9349  /*
9350  * Prepare to accumulate statistics.
9351  *
9352  * Note: because it is possible for log_checkpoints to change while a
9353  * checkpoint proceeds, we always accumulate stats, even if
9354  * log_checkpoints is currently off.
9355  */
9356  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
9358 
9359  if (log_checkpoints)
9360  LogCheckpointStart(flags, true);
9361 
9362  CheckPointGuts(lastCheckPoint.redo, flags);
9363 
9364  /*
9365  * Remember the prior checkpoint's redo ptr for
9366  * UpdateCheckPointDistanceEstimate()
9367  */
9368  PriorRedoPtr = ControlFile->checkPointCopy.redo;
9369 
9370  /*
9371  * Update pg_control, using current time. Check that it still shows
9372  * IN_ARCHIVE_RECOVERY state and an older checkpoint, else do nothing;
9373  * this is a quick hack to make sure nothing really bad happens if somehow
9374  * we get here after the end-of-recovery checkpoint.
9375  */
9376  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9378  ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
9379  {
9380  ControlFile->checkPoint = lastCheckPointRecPtr;
9381  ControlFile->checkPointCopy = lastCheckPoint;
9382  ControlFile->time = (pg_time_t) time(NULL);
9383 
9384  /*
9385  * Ensure minRecoveryPoint is past the checkpoint record. Normally,
9386  * this will have happened already while writing out dirty buffers,
9387  * but not necessarily - e.g. because no buffers were dirtied. We do
9388  * this because a non-exclusive base backup uses minRecoveryPoint to
9389  * determine which WAL files must be included in the backup, and the
9390  * file (or files) containing the checkpoint record must be included,
9391  * at a minimum. Note that for an ordinary restart of recovery there's
9392  * no value in having the minimum recovery point any earlier than this
9393  * anyway, because redo will begin just after the checkpoint record.
9394  */
9395  if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
9396  {
9397  ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
9399 
9400  /* update local copy */
9403  }
9404  if (flags & CHECKPOINT_IS_SHUTDOWN)
9407  }
9408  LWLockRelease(ControlFileLock);
9409 
9410  /*
9411  * Update the average distance between checkpoints/restartpoints if the
9412  * prior checkpoint exists.
9413  */
9414  if (PriorRedoPtr != InvalidXLogRecPtr)
9416 
9417  /*
9418  * Delete old log files, those no longer needed for last restartpoint to
9419  * prevent the disk holding the xlog from growing full.
9420  */
9422 
9423  /*
9424  * Retreat _logSegNo using the current end of xlog replayed or received,
9425  * whichever is later.
9426  */
9427  receivePtr = GetWalRcvWriteRecPtr(NULL, NULL);
9428  replayPtr = GetXLogReplayRecPtr(&replayTLI);
9429  endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
9430  KeepLogSeg(endptr, &_logSegNo);
9431  _logSegNo--;
9432 
9433  /*
9434  * Try to recycle segments on a useful timeline. If we've been promoted
9435  * since the beginning of this restartpoint, use the new timeline chosen
9436  * at end of recovery (RecoveryInProgress() sets ThisTimeLineID in that
9437  * case). If we're still in recovery, use the timeline we're currently
9438  * replaying.
9439  *
9440  * There is no guarantee that the WAL segments will be useful on the
9441  * current timeline; if recovery proceeds to a new timeline right after
9442  * this, the pre-allocated WAL segments on this timeline will not be used,
9443  * and will go wasted until recycled on the next restartpoint. We'll live
9444  * with that.
9445  */
9446  if (RecoveryInProgress())
9447  ThisTimeLineID = replayTLI;
9448 
9449  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr);
9450 
9451  /*
9452  * Make more log segments if needed. (Do this after recycling old log
9453  * segments, since that may supply some of the needed files.)
9454  */
9455  PreallocXlogFiles(endptr);
9456 
9457  /*
9458  * ThisTimeLineID is normally not set when we're still in recovery.
9459  * However, recycling/preallocating segments above needed ThisTimeLineID
9460  * to determine which timeline to install the segments on. Reset it now,
9461  * to restore the normal state of affairs for debugging purposes.
9462  */
9463  if (RecoveryInProgress())
9464  ThisTimeLineID = 0;
9465 
9466  /*
9467  * Truncate pg_subtrans if possible. We can throw away all data before
9468  * the oldest XMIN of any running transaction. No future transaction will
9469  * attempt to reference any pg_subtrans entry older than that (see Asserts
9470  * in subtrans.c). When hot standby is disabled, though, we mustn't do
9471  * this because StartupSUBTRANS hasn't been called yet.
9472  */
9473  if (EnableHotStandby)
9475 
9476  /* Real work is done, but log and update before releasing lock. */
9477  LogCheckpointEnd(true);
9478 
9479  xtime = GetLatestXTime();
9481  (errmsg("recovery restart point at %X/%X",
9482  (uint32) (lastCheckPoint.redo >> 32), (uint32) lastCheckPoint.redo),
9483  xtime ? errdetail("Last completed transaction was at log time %s.",
9484  timestamptz_to_str(xtime)) : 0));
9485 
9486  LWLockRelease(CheckpointLock);
9487 
9488  /*
9489  * Finally, execute archive_cleanup_command, if any.
9490  */
9493  "archive_cleanup_command",
9494  false);
9495 
9496  return true;
9497 }
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8650
bool log_checkpoints
Definition: xlog.c:96
void ExecuteRecoveryCommand(const char *command, const char *commandName, bool failOnSignal)
Definition: xlogarchive.c:330
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
uint32 TimeLineID
Definition: xlogdefs.h:45
int64 pg_time_t
Definition: pgtime.h:23
XLogRecPtr GetWalRcvWriteRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI)
static void WALInsertLockRelease(void)
Definition: xlog.c:1679
int wal_segment_size
Definition: xlog.c:107
pg_time_t time
Definition: pg_control.h:128
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1570
int64 TimestampTz
Definition: timestamp.h:39
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition: xlog.c:2705
TimestampTz ckpt_start_t
Definition: xlog.h:199
slock_t info_lck
Definition: xlog.c:698
#define MemSet(start, val, len)
Definition: c.h:941
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:9188
TimestampTz GetLatestXTime(void)
Definition: xlog.c:6222
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:571
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:8065
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:354
XLogRecPtr lastCheckPointRecPtr
Definition: xlog.c:667
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
#define SpinLockAcquire(lock)
Definition: spin.h:62
void UpdateControlFile(void)
Definition: xlog.c:4754
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8565
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
Definition: xlog.c:11331
#define DEBUG2
Definition: elog.h:24
static XLogRecPtr RedoRecPtr
Definition: xlog.c:346
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3781
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errdetail(const char *fmt,...)
Definition: elog.c:860
unsigned int uint32
Definition: c.h:358
XLogRecPtr RedoRecPtr
Definition: xlog.c:575
#define ereport(elevel, rest)
Definition: elog.h:141
CheckPoint lastCheckPoint
Definition: xlog.c:669
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
#define SpinLockRelease(lock)
Definition: spin.h:64
static TimeLineID minRecoveryPointTLI
Definition: xlog.c:826
#define PROCARRAY_FLAGS_DEFAULT
Definition: procarray.h:50
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9508
static ControlFileData * ControlFile
Definition: xlog.c:709
TimeLineID ThisTimeLineID
Definition: xlog.c:175
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr RedoRecPtr, XLogRecPtr endptr)
Definition: xlog.c:3911
TransactionId GetOldestXmin(Relation rel, int flags)
Definition: procarray.c:1321
uint64 XLogRecPtr
Definition: xlogdefs.h:21
CheckpointStatsData CheckpointStats
Definition: xlog.c:169
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1650
static XLogCtlData * XLogCtl
Definition: xlog.c:701
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
char archiveCleanupCommand[MAXPGPATH]
Definition: xlog.c:631
bool EnableHotStandby
Definition: xlog.c:90
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
int errmsg(const char *fmt,...)
Definition: elog.c:784
XLogRecPtr RedoRecPtr
Definition: xlog.c:544
XLogRecPtr lastCheckPointEndPtr
Definition: xlog.c:668
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:36
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8547
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:176
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:825
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1730
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ DataChecksumsEnabled()

bool DataChecksumsEnabled ( void  )

Definition at line 4824 of file xlog.c.

References Assert, and ControlFileData::data_checksum_version.

Referenced by PageIsVerified(), PageSetChecksumCopy(), PageSetChecksumInplace(), ReadControlFile(), and sendFile().

4825 {
4826  Assert(ControlFile != NULL);
4827  return (ControlFile->data_checksum_version > 0);
4828 }
uint32 data_checksum_version
Definition: pg_control.h:221
static ControlFileData * ControlFile
Definition: xlog.c:709
#define Assert(condition)
Definition: c.h:732

◆ do_pg_abort_backup()

void do_pg_abort_backup ( void  )

Definition at line 11303 of file xlog.c.

References Assert, EXCLUSIVE_BACKUP_NONE, XLogCtlInsert::exclusiveBackupState, XLogCtlInsert::forcePageWrites, XLogCtlData::Insert, XLogCtlInsert::nonExclusiveBackups, SESSION_BACKUP_NON_EXCLUSIVE, SESSION_BACKUP_NONE, sessionBackupState, WALInsertLockAcquireExclusive(), and WALInsertLockRelease().

Referenced by base_backup_cleanup(), and nonexclusive_base_backup_cleanup().

11304 {
11305  /*
11306  * Quick exit if session is not keeping around a non-exclusive backup
11307  * already started.
11308  */
11310  return;
11311 
11316 
11319  {
11320  XLogCtl->Insert.forcePageWrites = false;
11321  }
11323 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1679
static SessionBackupState sessionBackupState
Definition: xlog.c:506
XLogCtlInsert Insert
Definition: xlog.c:571
bool forcePageWrites
Definition: xlog.c:545
int nonExclusiveBackups
Definition: xlog.c:557
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:556
#define Assert(condition)
Definition: c.h:732
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1650
static XLogCtlData * XLogCtl
Definition: xlog.c:701

◆ do_pg_start_backup()

XLogRecPtr do_pg_start_backup ( const char *  backupidstr,
bool  fast,
TimeLineID starttli_p,
StringInfo  labelfile,
List **  tablespaces,
StringInfo  tblspcmapfile,
bool  infotbssize,
bool  needtblspcmapfile 
)

Definition at line 10381 of file xlog.c.

References AllocateDir(), AllocateFile(), appendStringInfo(), appendStringInfoChar(), BACKUP_LABEL_FILE, backup_started_in_recovery, BoolGetDatum, ControlFileData::checkPoint, CHECKPOINT_FORCE, CHECKPOINT_IMMEDIATE, CHECKPOINT_WAIT, ControlFileData::checkPointCopy, dirent::d_name, StringInfoData::data, DataDir, ereport, errcode(), errcode_for_file_access(), errhint(), errmsg(), ERROR, EXCLUSIVE_BACKUP_IN_PROGRESS, EXCLUSIVE_BACKUP_NONE, EXCLUSIVE_BACKUP_STARTING, XLogCtlInsert::exclusiveBackupState, XLogCtlInsert::forcePageWrites, FreeDir(), FreeFile(), CheckPoint::fullPageWrites, XLogCtlData::info_lck, initStringInfo(), XLogCtlData::Insert, IS_DIR_SEP, lappend(), XLogCtlInsert::lastBackupStart, XLogCtlData::lastFpwDisableRecPtr, StringInfoData::len, log_timezone, LW_SHARED, LWLockAcquire(), LWLockRelease(), makeStringInfo(), MAXFNAMELEN, MAXPGPATH, XLogCtlInsert::nonExclusiveBackups, tablespaceinfo::oid, palloc(), tablespaceinfo::path, pfree(), PG_END_ENSURE_ERROR_CLEANUP, PG_ENSURE_ERROR_CLEANUP, pg_fsync(), pg_localtime(), pg_start_backup_callback(), pg_strftime(), pstrdup(), ReadDir(), readlink, RecoveryInProgress(), CheckPoint::redo, relpath, RequestCheckpoint(), RequestXLogSwitch(), tablespaceinfo::rpath, sendTablespace(), SESSION_BACKUP_EXCLUSIVE, SESSION_BACKUP_NON_EXCLUSIVE, sessionBackupState, tablespaceinfo::size, snprintf, SpinLockAcquire, SpinLockRelease, stat, TABLESPACE_MAP, CheckPoint::ThisTimeLineID, wal_segment_size, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), WARNING, XLByteToSeg, XLogFileName, and XLogIsNeeded.

Referenced by perform_base_backup(), and pg_start_backup().

10385 {
10386  bool exclusive = (labelfile == NULL);
10387  bool backup_started_in_recovery = false;
10388  XLogRecPtr checkpointloc;
10389  XLogRecPtr startpoint;
10390  TimeLineID starttli;
10391  pg_time_t stamp_time;
10392  char strfbuf[128];
10393  char xlogfilename[MAXFNAMELEN];
10394  XLogSegNo _logSegNo;
10395  struct stat stat_buf;
10396  FILE *fp;
10397 
10398  backup_started_in_recovery = RecoveryInProgress();
10399 
10400  /*
10401  * Currently only non-exclusive backup can be taken during recovery.
10402  */
10403  if (backup_started_in_recovery && exclusive)
10404  ereport(ERROR,
10405  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10406  errmsg("recovery is in progress"),
10407  errhint("WAL control functions cannot be executed during recovery.")));
10408 
10409  /*
10410  * During recovery, we don't need to check WAL level. Because, if WAL
10411  * level is not sufficient, it's impossible to get here during recovery.
10412  */
10413  if (!backup_started_in_recovery && !XLogIsNeeded())
10414  ereport(ERROR,
10415  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10416  errmsg("WAL level not sufficient for making an online backup"),
10417  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
10418 
10419  if (strlen(backupidstr) > MAXPGPATH)
10420  ereport(ERROR,
10421  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
10422  errmsg("backup label too long (max %d bytes)",
10423  MAXPGPATH)));
10424 
10425  /*
10426  * Mark backup active in shared memory. We must do full-page WAL writes
10427  * during an on-line backup even if not doing so at other times, because
10428  * it's quite possible for the backup dump to obtain a "torn" (partially
10429  * written) copy of a database page if it reads the page concurrently with
10430  * our write to the same page. This can be fixed as long as the first
10431  * write to the page in the WAL sequence is a full-page write. Hence, we
10432  * turn on forcePageWrites and then force a CHECKPOINT, to ensure there
10433  * are no dirty pages in shared memory that might get dumped while the
10434  * backup is in progress without having a corresponding WAL record. (Once
10435  * the backup is complete, we need not force full-page writes anymore,
10436  * since we expect that any pages not modified during the backup interval
10437  * must have been correctly captured by the backup.)
10438  *
10439  * Note that forcePageWrites has no effect during an online backup from
10440  * the standby.
10441  *
10442  * We must hold all the insertion locks to change the value of
10443  * forcePageWrites, to ensure adequate interlocking against
10444  * XLogInsertRecord().
10445  */
10447  if (exclusive)
10448  {
10449  /*
10450  * At first, mark that we're now starting an exclusive backup, to
10451  * ensure that there are no other sessions currently running
10452  * pg_start_backup() or pg_stop_backup().
10453  */
10455  {
10457  ereport(ERROR,
10458  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10459  errmsg("a backup is already in progress"),
10460  errhint("Run pg_stop_backup() and try again.")));
10461  }
10463  }
10464  else
10466  XLogCtl->Insert.forcePageWrites = true;
10468 
10469  /* Ensure we release forcePageWrites if fail below */
10471  {
10472  bool gotUniqueStartpoint = false;
10473  DIR *tblspcdir;
10474  struct dirent *de;
10475  tablespaceinfo *ti;
10476  int datadirpathlen;
10477 
10478  /*
10479  * Force an XLOG file switch before the checkpoint, to ensure that the
10480  * WAL segment the checkpoint is written to doesn't contain pages with
10481  * old timeline IDs. That would otherwise happen if you called
10482  * pg_start_backup() right after restoring from a PITR archive: the
10483  * first WAL segment containing the startup checkpoint has pages in
10484  * the beginning with the old timeline ID. That can cause trouble at
10485  * recovery: we won't have a history file covering the old timeline if
10486  * pg_wal directory was not included in the base backup and the WAL
10487  * archive was cleared too before starting the backup.
10488  *
10489  * This also ensures that we have emitted a WAL page header that has
10490  * XLP_BKP_REMOVABLE off before we emit the checkpoint record.
10491  * Therefore, if a WAL archiver (such as pglesslog) is trying to
10492  * compress out removable backup blocks, it won't remove any that
10493  * occur after this point.
10494  *
10495  * During recovery, we skip forcing XLOG file switch, which means that
10496  * the backup taken during recovery is not available for the special
10497  * recovery case described above.
10498  */
10499  if (!backup_started_in_recovery)
10500  RequestXLogSwitch(false);
10501 
10502  do
10503  {
10504  bool checkpointfpw;
10505 
10506  /*
10507  * Force a CHECKPOINT. Aside from being necessary to prevent torn
10508  * page problems, this guarantees that two successive backup runs
10509  * will have different checkpoint positions and hence different
10510  * history file names, even if nothing happened in between.
10511  *
10512  * During recovery, establish a restartpoint if possible. We use
10513  * the last restartpoint as the backup starting checkpoint. This
10514  * means that two successive backup runs can have same checkpoint
10515  * positions.
10516  *
10517  * Since the fact that we are executing do_pg_start_backup()
10518  * during recovery means that checkpointer is running, we can use
10519  * RequestCheckpoint() to establish a restartpoint.
10520  *
10521  * We use CHECKPOINT_IMMEDIATE only if requested by user (via
10522  * passing fast = true). Otherwise this can take awhile.
10523  */
10525  (fast ? CHECKPOINT_IMMEDIATE : 0));
10526 
10527  /*
10528  * Now we need to fetch the checkpoint record location, and also
10529  * its REDO pointer. The oldest point in WAL that would be needed
10530  * to restore starting from the checkpoint is precisely the REDO
10531  * pointer.
10532  */
10533  LWLockAcquire(ControlFileLock, LW_SHARED);
10534  checkpointloc = ControlFile->checkPoint;
10535  startpoint = ControlFile->checkPointCopy.redo;
10537  checkpointfpw = ControlFile->checkPointCopy.fullPageWrites;
10538  LWLockRelease(ControlFileLock);
10539 
10540  if (backup_started_in_recovery)
10541  {
10542  XLogRecPtr recptr;
10543 
10544  /*
10545  * Check to see if all WAL replayed during online backup
10546  * (i.e., since last restartpoint used as backup starting
10547  * checkpoint) contain full-page writes.
10548  */
10550  recptr = XLogCtl->lastFpwDisableRecPtr;
10552 
10553  if (!checkpointfpw || startpoint <= recptr)
10554  ereport(ERROR,
10555  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10556  errmsg("WAL generated with full_page_writes=off was replayed "
10557  "since last restartpoint"),
10558  errhint("This means that the backup being taken on the standby "
10559  "is corrupt and should not be used. "
10560  "Enable full_page_writes and run CHECKPOINT on the master, "
10561  "and then try an online backup again.")));
10562 
10563  /*
10564  * During recovery, since we don't use the end-of-backup WAL
10565  * record and don't write the backup history file, the
10566  * starting WAL location doesn't need to be unique. This means
10567  * that two base backups started at the same time might use
10568  * the same checkpoint as starting locations.
10569  */
10570  gotUniqueStartpoint = true;
10571  }
10572 
10573  /*
10574  * If two base backups are started at the same time (in WAL sender
10575  * processes), we need to make sure that they use different
10576  * checkpoints as starting locations, because we use the starting
10577  * WAL location as a unique identifier for the base backup in the
10578  * end-of-backup WAL record and when we write the backup history
10579  * file. Perhaps it would be better generate a separate unique ID
10580  * for each backup instead of forcing another checkpoint, but
10581  * taking a checkpoint right after another is not that expensive
10582  * either because only few buffers have been dirtied yet.
10583  */
10585  if (XLogCtl->Insert.lastBackupStart < startpoint)
10586  {
10587  XLogCtl->Insert.lastBackupStart = startpoint;
10588  gotUniqueStartpoint = true;
10589  }
10591  } while (!gotUniqueStartpoint);
10592 
10593  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
10594  XLogFileName(xlogfilename, starttli, _logSegNo, wal_segment_size);
10595 
10596  /*
10597  * Construct tablespace_map file
10598  */
10599  if (exclusive)
10600  tblspcmapfile = makeStringInfo();
10601 
10602  datadirpathlen = strlen(DataDir);
10603 
10604  /* Collect information about all tablespaces */
10605  tblspcdir = AllocateDir("pg_tblspc");
10606  while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL)
10607  {
10608  char fullpath[MAXPGPATH + 10];
10609  char linkpath[MAXPGPATH];
10610  char *relpath = NULL;
10611  int rllen;
10612  StringInfoData buflinkpath;
10613  char *s = linkpath;
10614 
10615  /* Skip special stuff */
10616  if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
10617  continue;
10618 
10619  snprintf(fullpath, sizeof(fullpath), "pg_tblspc/%s", de->d_name);
10620 
10621 #if defined(HAVE_READLINK) || defined(WIN32)
10622  rllen = readlink(fullpath, linkpath, sizeof(linkpath));
10623  if (rllen < 0)
10624  {
10625  ereport(WARNING,
10626  (errmsg("could not read symbolic link \"%s\": %m",
10627  fullpath)));
10628  continue;
10629  }
10630  else if (rllen >= sizeof(linkpath))
10631  {
10632  ereport(WARNING,
10633  (errmsg("symbolic link \"%s\" target is too long",
10634  fullpath)));
10635  continue;
10636  }
10637  linkpath[rllen] = '\0';
10638 
10639  /*
10640  * Add the escape character '\\' before newline in a string to
10641  * ensure that we can distinguish between the newline in the
10642  * tablespace path and end of line while reading tablespace_map
10643  * file during archive recovery.
10644  */
10645  initStringInfo(&buflinkpath);
10646 
10647  while (*s)
10648  {
10649  if ((*s == '\n' || *s == '\r') && needtblspcmapfile)
10650  appendStringInfoChar(&buflinkpath, '\\');
10651  appendStringInfoChar(&buflinkpath, *s++);
10652  }
10653 
10654  /*
10655  * Relpath holds the relative path of the tablespace directory
10656  * when it's located within PGDATA, or NULL if it's located
10657  * elsewhere.
10658  */
10659  if (rllen > datadirpathlen &&
10660  strncmp(linkpath, DataDir, datadirpathlen) == 0 &&
10661  IS_DIR_SEP(linkpath[datadirpathlen]))
10662  relpath = linkpath + datadirpathlen + 1;
10663 
10664  ti = palloc(sizeof(tablespaceinfo));
10665  ti->oid = pstrdup(de->d_name);
10666  ti->path = pstrdup(buflinkpath.data);
10667  ti->rpath = relpath ? pstrdup(relpath) : NULL;
10668  ti->size = infotbssize ? sendTablespace(fullpath, true) : -1;
10669 
10670  if (tablespaces)
10671  *tablespaces = lappend(*tablespaces, ti);
10672 
10673  appendStringInfo(tblspcmapfile, "%s %s\n", ti->oid, ti->path);
10674 
10675  pfree(buflinkpath.data);
10676 #else
10677 
10678  /*
10679  * If the platform does not have symbolic links, it should not be
10680  * possible to have tablespaces - clearly somebody else created
10681  * them. Warn about it and ignore.
10682  */
10683  ereport(WARNING,
10684  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
10685  errmsg("tablespaces are not supported on this platform")));
10686 #endif
10687  }
10688  FreeDir(tblspcdir);
10689 
10690  /*
10691  * Construct backup label file
10692  */
10693  if (exclusive)
10694  labelfile = makeStringInfo();
10695 
10696  /* Use the log timezone here, not the session timezone */
10697  stamp_time = (pg_time_t) time(NULL);
10698  pg_strftime(strfbuf, sizeof(strfbuf),
10699  "%Y-%m-%d %H:%M:%S %Z",
10700  pg_localtime(&stamp_time, log_timezone));
10701  appendStringInfo(labelfile, "START WAL LOCATION: %X/%X (file %s)\n",
10702  (uint32) (startpoint >> 32), (uint32) startpoint, xlogfilename);
10703  appendStringInfo(labelfile, "CHECKPOINT LOCATION: %X/%X\n",
10704  (uint32) (checkpointloc >> 32), (uint32) checkpointloc);
10705  appendStringInfo(labelfile, "BACKUP METHOD: %s\n",
10706  exclusive ? "pg_start_backup" : "streamed");
10707  appendStringInfo(labelfile, "BACKUP FROM: %s\n",
10708  backup_started_in_recovery ? "standby" : "master");
10709  appendStringInfo(labelfile, "START TIME: %s\n", strfbuf);
10710  appendStringInfo(labelfile, "LABEL: %s\n", backupidstr);
10711  appendStringInfo(labelfile, "START TIMELINE: %u\n", starttli);
10712 
10713  /*
10714  * Okay, write the file, or return its contents to caller.
10715  */
10716  if (exclusive)
10717  {
10718  /*
10719  * Check for existing backup label --- implies a backup is already
10720  * running. (XXX given that we checked exclusiveBackupState
10721  * above, maybe it would be OK to just unlink any such label
10722  * file?)
10723  */
10724  if (stat(BACKUP_LABEL_FILE, &stat_buf) != 0)
10725  {
10726  if (errno != ENOENT)
10727  ereport(ERROR,
10729  errmsg("could not stat file \"%s\": %m",
10730  BACKUP_LABEL_FILE)));
10731  }
10732  else
10733  ereport(ERROR,
10734  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10735  errmsg("a backup is already in progress"),
10736  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
10737  BACKUP_LABEL_FILE)));
10738 
10739  fp = AllocateFile(BACKUP_LABEL_FILE, "w");
10740 
10741  if (!fp)
10742  ereport(ERROR,
10744  errmsg("could not create file \"%s\": %m",
10745  BACKUP_LABEL_FILE)));
10746  if (fwrite(labelfile->data, labelfile->len, 1, fp) != 1 ||
10747  fflush(fp) != 0 ||
10748  pg_fsync(fileno(fp)) != 0 ||
10749  ferror(fp) ||
10750  FreeFile(fp))
10751  ereport(ERROR,
10753  errmsg("could not write file \"%s\": %m",
10754  BACKUP_LABEL_FILE)));
10755  /* Allocated locally for exclusive backups, so free separately */
10756  pfree(labelfile->data);
10757  pfree(labelfile);
10758 
10759  /* Write backup tablespace_map file. */
10760  if (tblspcmapfile->len > 0)
10761  {
10762  if (stat(TABLESPACE_MAP, &stat_buf) != 0)
10763  {
10764  if (errno != ENOENT)
10765  ereport(ERROR,
10767  errmsg("could not stat file \"%s\": %m",
10768  TABLESPACE_MAP)));
10769  }
10770  else
10771  ereport(ERROR,
10772  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10773  errmsg("a backup is already in progress"),
10774  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
10775  TABLESPACE_MAP)));
10776 
10777  fp = AllocateFile(TABLESPACE_MAP, "w");
10778 
10779  if (!fp)
10780  ereport(ERROR,
10782  errmsg("could not create file \"%s\": %m",
10783  TABLESPACE_MAP)));
10784  if (fwrite(tblspcmapfile->data, tblspcmapfile->len, 1, fp) != 1 ||
10785  fflush(fp) != 0 ||
10786  pg_fsync(fileno(fp)) != 0 ||
10787  ferror(fp) ||
10788  FreeFile(fp))
10789  ereport(ERROR,
10791  errmsg("could not write file \"%s\": %m",
10792  TABLESPACE_MAP)));
10793  }
10794 
10795  /* Allocated locally for exclusive backups, so free separately */
10796  pfree(tblspcmapfile->data);
10797  pfree(tblspcmapfile);
10798  }
10799  }
10801 
10802  /*
10803  * Mark that start phase has correctly finished for an exclusive backup.
10804  * Session-level locks are updated as well to reflect that state.
10805  *
10806  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating backup
10807  * counters and session-level lock. Otherwise they can be updated
10808  * inconsistently, and which might cause do_pg_abort_backup() to fail.
10809  */
10810  if (exclusive)
10811  {
10814 
10815  /* Set session-level lock */
10818  }
10819  else
10821 
10822  /*
10823  * We're done. As a convenience, return the starting WAL location.
10824  */
10825  if (starttli_p)
10826  *starttli_p = starttli;
10827  return startpoint;
10828 }
size_t pg_strftime(char *s, size_t max, const char *format, const struct pg_tm *tm)
Definition: strftime.c:122
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9585
int errhint(const char *fmt,...)
Definition: elog.c:974
uint32 TimeLineID
Definition: xlogdefs.h:45
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1679
int wal_segment_size
Definition: xlog.c:107
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:696
static SessionBackupState sessionBackupState
Definition: xlog.c:506
XLogRecPtr lastBackupStart
Definition: xlog.c:558
char * pstrdup(const char *in)
Definition: mcxt.c:1161
#define XLogIsNeeded()
Definition: xlog.h:146
char * rpath
Definition: basebackup.h:28
StringInfo makeStringInfo(void)
Definition: stringinfo.c:28
slock_t info_lck
Definition: xlog.c:698
int errcode(int sqlerrcode)
Definition: elog.c:570
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:571
bool RecoveryInProgress(void)
Definition: xlog.c:8065
static bool backup_started_in_recovery
Definition: basebackup.c:78
Definition: dirent.h:9
#define IS_DIR_SEP(ch)
Definition: port.h:84
pg_tz * log_timezone
Definition: pgtz.c:31
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
#define TABLESPACE_MAP
Definition: xlog.h:327
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:47
void pfree(void *pointer)
Definition: mcxt.c:1031
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
bool forcePageWrites
Definition: xlog.c:545
Definition: dirent.c:25
#define ERROR
Definition: elog.h:43
struct stat stat_buf
Definition: pg_standby.c:102
#define MAXPGPATH
uint64 XLogSegNo
Definition: xlogdefs.h:34
#define readlink(path, buf, size)
Definition: win32_port.h:233
int errcode_for_file_access(void)
Definition: elog.c:593
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2177
unsigned int uint32
Definition: c.h:358
int64 sendTablespace(char *path, bool sizeonly)
Definition: basebackup.c:962
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2431
#define CHECKPOINT_FORCE
Definition: xlog.h:180
#define ereport(elevel, rest)
Definition: elog.h:141
List * lappend(List *list, void *datum)
Definition: list.c:128
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:175
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define WARNING
Definition: elog.h:40
int nonExclusiveBackups
Definition: xlog.c:557
#define stat(a, b)
Definition: win32_port.h:266
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
static void pg_start_backup_callback(int code, Datum arg)
Definition: xlog.c:10832
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:556
uintptr_t Datum
Definition: postgres.h:367
static ControlFileData * ControlFile
Definition: xlog.c:709
#define BoolGetDatum(X)
Definition: postgres.h:387
bool fullPageWrites
Definition: pg_control.h:41
#define CHECKPOINT_WAIT
Definition: xlog.h:184
uint64 XLogRecPtr
Definition: xlogdefs.h:21
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2497
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1650
static XLogCtlData * XLogCtl
Definition: xlog.c:701
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:52
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1374
int FreeFile(FILE *file)
Definition: fd.c:2369
void * palloc(Size size)
Definition: mcxt.c:924
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:179
#define relpath(rnode, forknum)
Definition: relpath.h:87
char * DataDir
Definition: globals.c:62
#define BACKUP_LABEL_FILE
Definition: xlog.h:324
int pg_fsync(int fd)
Definition: fd.c:331
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:36
int FreeDir(DIR *dir)
Definition: fd.c:2549
void RequestCheckpoint(int flags)
Definition: checkpointer.c:951
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ do_pg_stop_backup()

XLogRecPtr do_pg_stop_backup ( char *  labelfile,
bool  waitforarchive,
TimeLineID stoptli_p 
)

Definition at line 10898 of file xlog.c.

References AllocateFile(), Assert, BACKUP_LABEL_FILE, backup_started_in_recovery, BackupHistoryFileName, BackupHistoryFilePath, BoolGetDatum, CHECK_FOR_INTERRUPTS, CleanupBackupHistory(), DEBUG1, durable_unlink(), ereport, errcode(), errcode_for_file_access(), errhint(), errmsg(), ERROR, EXCLUSIVE_BACKUP_IN_PROGRESS, EXCLUSIVE_BACKUP_NONE, EXCLUSIVE_BACKUP_STOPPING, XLogCtlInsert::exclusiveBackupState, XLogCtlInsert::forcePageWrites, fprintf, FreeFile(), XLogCtlData::info_lck, XLogCtlData::Insert, XLogCtlData::lastFpwDisableRecPtr, log_timezone, LW_SHARED, LWLockAcquire(), LWLockRelease(), MAXFNAMELEN, MAXPGPATH, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, XLogCtlInsert::nonExclusiveBackups, NOTICE, palloc(), PG_END_ENSURE_ERROR_CLEANUP, PG_ENSURE_ERROR_CLEANUP, pg_localtime(), pg_stop_backup_callback(), pg_strftime(), pg_usleep(), RecoveryInProgress(), remaining, RequestXLogSwitch(), SESSION_BACKUP_NONE, sessionBackupState, SpinLockAcquire, SpinLockRelease, stat, TABLESPACE_MAP, ThisTimeLineID, wal_segment_size, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), WARNING, XLByteToPrevSeg, XLByteToSeg, XLOG_BACKUP_END, XLogArchiveIsBusy(), XLogArchivingActive, XLogArchivingAlways, XLogBeginInsert(), XLogFileName, XLogInsert(), XLogIsNeeded, and XLogRegisterData().

Referenced by perform_base_backup(), pg_stop_backup(), and pg_stop_backup_v2().

10899 {
10900  bool exclusive = (labelfile == NULL);
10901  bool backup_started_in_recovery = false;
10902  XLogRecPtr startpoint;
10903  XLogRecPtr stoppoint;
10904  TimeLineID stoptli;
10905  pg_time_t stamp_time;
10906  char strfbuf[128];
10907  char histfilepath[MAXPGPATH];
10908  char startxlogfilename[MAXFNAMELEN];
10909  char stopxlogfilename[MAXFNAMELEN];
10910  char lastxlogfilename[MAXFNAMELEN];
10911  char histfilename[MAXFNAMELEN];
10912  char backupfrom[20];
10913  XLogSegNo _logSegNo;
10914  FILE *lfp;
10915  FILE *fp;
10916  char ch;
10917  int seconds_before_warning;
10918  int waits = 0;
10919  bool reported_waiting = false;
10920  char *remaining;
10921  char *ptr;
10922  uint32 hi,
10923  lo;
10924 
10925  backup_started_in_recovery = RecoveryInProgress();
10926 
10927  /*
10928  * Currently only non-exclusive backup can be taken during recovery.
10929  */
10930  if (backup_started_in_recovery && exclusive)
10931  ereport(ERROR,
10932  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10933  errmsg("recovery is in progress"),
10934  errhint("WAL control functions cannot be executed during recovery.")));
10935 
10936  /*
10937  * During recovery, we don't need to check WAL level. Because, if WAL
10938  * level is not sufficient, it's impossible to get here during recovery.
10939  */
10940  if (!backup_started_in_recovery && !XLogIsNeeded())
10941  ereport(ERROR,
10942  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10943  errmsg("WAL level not sufficient for making an online backup"),
10944  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
10945 
10946  if (exclusive)
10947  {
10948  /*
10949  * At first, mark that we're now stopping an exclusive backup, to
10950  * ensure that there are no other sessions currently running
10951  * pg_start_backup() or pg_stop_backup().
10952  */
10955  {
10957  ereport(ERROR,
10958  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10959  errmsg("exclusive backup not in progress")));
10960  }
10963 
10964  /*
10965  * Remove backup_label. In case of failure, the state for an exclusive
10966  * backup is switched back to in-progress.
10967  */
10969  {
10970  /*
10971  * Read the existing label file into memory.
10972  */
10973  struct stat statbuf;
10974  int r;
10975 
10976  if (stat(BACKUP_LABEL_FILE, &statbuf))
10977  {
10978  /* should not happen per the upper checks */
10979  if (errno != ENOENT)
10980  ereport(ERROR,
10982  errmsg("could not stat file \"%s\": %m",
10983  BACKUP_LABEL_FILE)));
10984  ereport(ERROR,
10985  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10986  errmsg("a backup is not in progress")));
10987  }
10988 
10989  lfp = AllocateFile(BACKUP_LABEL_FILE, "r");
10990  if (!lfp)
10991  {
10992  ereport(ERROR,
10994  errmsg("could not read file \"%s\": %m",
10995  BACKUP_LABEL_FILE)));
10996  }
10997  labelfile = palloc(statbuf.st_size + 1);
10998  r = fread(labelfile, statbuf.st_size, 1, lfp);
10999  labelfile[statbuf.st_size] = '\0';
11000 
11001  /*
11002  * Close and remove the backup label file
11003  */
11004  if (r != 1 || ferror(lfp) || FreeFile(lfp))
11005  ereport(ERROR,
11007  errmsg("could not read file \"%s\": %m",
11008  BACKUP_LABEL_FILE)));
11010 
11011  /*
11012  * Remove tablespace_map file if present, it is created only if
11013  * there are tablespaces.
11014  */
11016  }
11018  }
11019 
11020  /*
11021  * OK to update backup counters, forcePageWrites and session-level lock.
11022  *
11023  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating them.
11024  * Otherwise they can be updated inconsistently, and which might cause
11025  * do_pg_abort_backup() to fail.
11026  */
11028  if (exclusive)
11029  {
11031  }
11032  else
11033  {
11034  /*
11035  * The user-visible pg_start/stop_backup() functions that operate on
11036  * exclusive backups can be called at any time, but for non-exclusive
11037  * backups, it is expected that each do_pg_start_backup() call is
11038  * matched by exactly one do_pg_stop_backup() call.
11039  */
11042  }
11043 
11046  {
11047  XLogCtl->Insert.forcePageWrites = false;
11048  }
11049 
11050  /*
11051  * Clean up session-level lock.
11052  *
11053  * You might think that WALInsertLockRelease() can be called before
11054  * cleaning up session-level lock because session-level lock doesn't need
11055  * to be protected with WAL insertion lock. But since
11056  * CHECK_FOR_INTERRUPTS() can occur in it, session-level lock must be
11057  * cleaned up before it.
11058  */
11060 
11062 
11063  /*
11064  * Read and parse the START WAL LOCATION line (this code is pretty crude,
11065  * but we are not expecting any variability in the file format).
11066  */
11067  if (sscanf(labelfile, "START WAL LOCATION: %X/%X (file %24s)%c",
11068  &hi, &lo, startxlogfilename,
11069  &ch) != 4 || ch != '\n')
11070  ereport(ERROR,
11071  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11072  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
11073  startpoint = ((uint64) hi) << 32 | lo;
11074  remaining = strchr(labelfile, '\n') + 1; /* %n is not portable enough */
11075 
11076  /*
11077  * Parse the BACKUP FROM line. If we are taking an online backup from the
11078  * standby, we confirm that the standby has not been promoted during the
11079  * backup.
11080  */
11081  ptr = strstr(remaining, "BACKUP FROM:");
11082  if (!ptr || sscanf(ptr, "BACKUP FROM: %19s\n", backupfrom) != 1)
11083  ereport(ERROR,
11084  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11085  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
11086  if (strcmp(backupfrom, "standby") == 0 && !backup_started_in_recovery)
11087  ereport(ERROR,
11088  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11089  errmsg("the standby was promoted during online backup"),
11090  errhint("This means that the backup being taken is corrupt "
11091  "and should not be used. "
11092  "Try taking another online backup.")));
11093 
11094  /*
11095  * During recovery, we don't write an end-of-backup record. We assume that
11096  * pg_control was backed up last and its minimum recovery point can be
11097  * available as the backup end location. Since we don't have an
11098  * end-of-backup record, we use the pg_control value to check whether
11099  * we've reached the end of backup when starting recovery from this
11100  * backup. We have no way of checking if pg_control wasn't backed up last
11101  * however.
11102  *
11103  * We don't force a switch to new WAL file but it is still possible to
11104  * wait for all the required files to be archived if waitforarchive is
11105  * true. This is okay if we use the backup to start a standby and fetch
11106  * the missing WAL using streaming replication. But in the case of an
11107  * archive recovery, a user should set waitforarchive to true and wait for
11108  * them to be archived to ensure that all the required files are
11109  * available.
11110  *
11111  * We return the current minimum recovery point as the backup end
11112  * location. Note that it can be greater than the exact backup end
11113  * location if the minimum recovery point is updated after the backup of
11114  * pg_control. This is harmless for current uses.
11115  *
11116  * XXX currently a backup history file is for informational and debug
11117  * purposes only. It's not essential for an online backup. Furthermore,
11118  * even if it's created, it will not be archived during recovery because
11119  * an archiver is not invoked. So it doesn't seem worthwhile to write a
11120  * backup history file during recovery.
11121  */
11122  if (backup_started_in_recovery)
11123  {
11124  XLogRecPtr recptr;
11125 
11126  /*
11127  * Check to see if all WAL replayed during online backup contain
11128  * full-page writes.
11129  */
11131  recptr = XLogCtl->lastFpwDisableRecPtr;
11133 
11134  if (startpoint <= recptr)
11135  ereport(ERROR,
11136  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11137  errmsg("WAL generated with full_page_writes=off was replayed "
11138  "during online backup"),
11139  errhint("This means that the backup being taken on the standby "
11140  "is corrupt and should not be used. "
11141  "Enable full_page_writes and run CHECKPOINT on the master, "
11142  "and then try an online backup again.")));
11143 
11144 
11145  LWLockAcquire(ControlFileLock, LW_SHARED);
11146  stoppoint = ControlFile->minRecoveryPoint;
11147  stoptli = ControlFile->minRecoveryPointTLI;
11148  LWLockRelease(ControlFileLock);
11149  }
11150  else
11151  {
11152  /*
11153  * Write the backup-end xlog record
11154  */
11155  XLogBeginInsert();
11156  XLogRegisterData((char *) (&startpoint), sizeof(startpoint));
11157  stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
11158  stoptli = ThisTimeLineID;
11159 
11160  /*
11161  * Force a switch to a new xlog segment file, so that the backup is
11162  * valid as soon as archiver moves out the current segment file.
11163  */
11164  RequestXLogSwitch(false);
11165 
11166  XLByteToPrevSeg(stoppoint, _logSegNo, wal_segment_size);
11167  XLogFileName(stopxlogfilename, stoptli, _logSegNo, wal_segment_size);
11168 
11169  /* Use the log timezone here, not the session timezone */
11170  stamp_time = (pg_time_t) time(NULL);
11171  pg_strftime(strfbuf, sizeof(strfbuf),
11172  "%Y-%m-%d %H:%M:%S %Z",
11173  pg_localtime(&stamp_time, log_timezone));
11174 
11175  /*
11176  * Write the backup history file
11177  */
11178  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
11179  BackupHistoryFilePath(histfilepath, stoptli, _logSegNo,
11180  startpoint, wal_segment_size);
11181  fp = AllocateFile(histfilepath, "w");
11182  if (!fp)
11183  ereport(ERROR,
11185  errmsg("could not create file \"%s\": %m",
11186  histfilepath)));
11187  fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n",
11188  (uint32) (startpoint >> 32), (uint32) startpoint, startxlogfilename);
11189  fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
11190  (uint32) (stoppoint >> 32), (uint32) stoppoint, stopxlogfilename);
11191 
11192  /*
11193  * Transfer remaining lines including label and start timeline to
11194  * history file.
11195  */
11196  fprintf(fp, "%s", remaining);
11197  fprintf(fp, "STOP TIME: %s\n", strfbuf);
11198  fprintf(fp, "STOP TIMELINE: %u\n", stoptli);
11199  if (fflush(fp) || ferror(fp) || FreeFile(fp))
11200  ereport(ERROR,
11202  errmsg("could not write file \"%s\": %m",
11203  histfilepath)));
11204 
11205  /*
11206  * Clean out any no-longer-needed history files. As a side effect,
11207  * this will post a .ready file for the newly created history file,
11208  * notifying the archiver that history file may be archived
11209  * immediately.
11210  */
11212  }
11213 
11214  /*
11215  * If archiving is enabled, wait for all the required WAL files to be
11216  * archived before returning. If archiving isn't enabled, the required WAL
11217  * needs to be transported via streaming replication (hopefully with
11218  * wal_keep_segments set high enough), or some more exotic mechanism like
11219  * polling and copying files from pg_wal with script. We have no knowledge
11220  * of those mechanisms, so it's up to the user to ensure that he gets all
11221  * the required WAL.
11222  *
11223  * We wait until both the last WAL file filled during backup and the
11224  * history file have been archived, and assume that the alphabetic sorting
11225  * property of the WAL files ensures any earlier WAL files are safely
11226  * archived as well.
11227  *
11228  * We wait forever, since archive_command is supposed to work and we
11229  * assume the admin wanted his backup to work completely. If you don't
11230  * wish to wait, then either waitforarchive should be passed in as false,
11231  * or you can set statement_timeout. Also, some notices are issued to
11232  * clue in anyone who might be doing this interactively.
11233  */
11234 
11235  if (waitforarchive &&
11236  ((!backup_started_in_recovery && XLogArchivingActive()) ||
11237  (backup_started_in_recovery && XLogArchivingAlways())))
11238  {
11239  XLByteToPrevSeg(stoppoint, _logSegNo, wal_segment_size);
11240  XLogFileName(lastxlogfilename, stoptli, _logSegNo, wal_segment_size);
11241 
11242  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
11243  BackupHistoryFileName(histfilename, stoptli, _logSegNo,
11244  startpoint, wal_segment_size);
11245 
11246  seconds_before_warning = 60;
11247  waits = 0;
11248 
11249  while (XLogArchiveIsBusy(lastxlogfilename) ||
11250  XLogArchiveIsBusy(histfilename))
11251  {
11253 
11254  if (!reported_waiting && waits > 5)
11255  {
11256  ereport(NOTICE,
11257  (errmsg("pg_stop_backup cleanup done, waiting for required WAL segments to be archived")));
11258  reported_waiting = true;
11259  }
11260 
11261  pg_usleep(1000000L);
11262 
11263  if (++waits >= seconds_before_warning)
11264  {
11265  seconds_before_warning *= 2; /* This wraps in >10 years... */
11266  ereport(WARNING,
11267  (errmsg("pg_stop_backup still waiting for all required WAL segments to be archived (%d seconds elapsed)",
11268  waits),
11269  errhint("Check that your archive_command is executing properly. "
11270  "pg_stop_backup can be canceled safely, "
11271  "but the database backup will not be usable without all the WAL segments.")));
11272  }
11273  }
11274 
11275  ereport(NOTICE,
11276  (errmsg("pg_stop_backup complete, all required WAL segments have been archived")));
11277  }
11278  else if (waitforarchive)
11279  ereport(NOTICE,
11280  (errmsg("WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup")));
11281 
11282  /*
11283  * We're done. As a convenience, return the ending WAL location.
11284  */
11285  if (stoptli_p)
11286  *stoptli_p = stoptli;
11287  return stoppoint;
11288 }
int remaining
Definition: informix.c:692
size_t pg_strftime(char *s, size_t max, const char *format, const struct pg_tm *tm)
Definition: strftime.c:122
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9585
#define DEBUG1
Definition: elog.h:25
int errhint(const char *fmt,...)
Definition: elog.c:974
uint32 TimeLineID
Definition: xlogdefs.h:45
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1679
int wal_segment_size
Definition: xlog.c:107
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:696
static SessionBackupState sessionBackupState
Definition: xlog.c:506
#define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes)
#define XLogIsNeeded()
Definition: xlog.h:146
slock_t info_lck
Definition: xlog.c:698
int errcode(int sqlerrcode)
Definition: elog.c:570
XLogCtlInsert Insert
Definition: xlog.c:571
#define BackupHistoryFileName(fname, tli, logSegNo, startpoint, wal_segsz_bytes)
bool RecoveryInProgress(void)
Definition: xlog.c:8065
static bool backup_started_in_recovery
Definition: basebackup.c:78
#define fprintf
Definition: port.h:196
pg_tz * log_timezone
Definition: pgtz.c:31
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
#define TABLESPACE_MAP
Definition: xlog.h:327
#define SpinLockAcquire(lock)
Definition: spin.h:62
void pg_usleep(long microsec)
Definition: signal.c:53
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:47
#define XLogArchivingAlways()
Definition: xlog.h:138
bool forcePageWrites
Definition: xlog.c:545
#define ERROR
Definition: elog.h:43
static void CleanupBackupHistory(void)
Definition: xlog.c:4171
#define MAXPGPATH
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errcode_for_file_access(void)
Definition: elog.c:593
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2177
unsigned int uint32
Definition: c.h:358
#define ereport(elevel, rest)
Definition: elog.h:141
#define XLOG_BACKUP_END
Definition: pg_control.h:72
#define WARNING
Definition: elog.h:40
int nonExclusiveBackups
Definition: xlog.c:557
#define stat(a, b)
Definition: win32_port.h:266
#define MAXFNAMELEN
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
#define SpinLockRelease(lock)
Definition: spin.h:64
#define BackupHistoryFilePath(path, tli, logSegNo, startpoint, wal_segsz_bytes)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:556
uintptr_t Datum
Definition: postgres.h:367
static ControlFileData * ControlFile
Definition: xlog.c:709
#define BoolGetDatum(X)
Definition: postgres.h:387
TimeLineID ThisTimeLineID
Definition: xlog.c:175
#define NOTICE
Definition: elog.h:37
bool XLogArchiveIsBusy(const char *xlog)
Definition: xlogarchive.c:666
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:732
#define XLogArchivingActive()
Definition: xlog.h:135
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1650
static XLogCtlData * XLogCtl
Definition: xlog.c:701
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
static void pg_stop_backup_callback(int code, Datum arg)
Definition: xlog.c:10861
#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:52
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1374
int durable_unlink(const char *fname, int elevel)
Definition: fd.c:672
int FreeFile(FILE *file)
Definition: fd.c:2369
void * palloc(Size size)
Definition: mcxt.c:924
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define BACKUP_LABEL_FILE
Definition: xlog.h:324
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ emode_for_corrupt_record()

static int emode_for_corrupt_record ( int  emode,
XLogRecPtr  RecPtr 
)
static

Definition at line 12315 of file xlog.c.

References DEBUG1, LOG, readSource, and XLOG_FROM_PG_WAL.

Referenced by ReadRecord(), and XLogPageRead().

12316 {
12317  static XLogRecPtr lastComplaint = 0;
12318 
12319  if (readSource == XLOG_FROM_PG_WAL && emode == LOG)
12320  {
12321  if (RecPtr == lastComplaint)
12322  emode = DEBUG1;
12323  else
12324  lastComplaint = RecPtr;
12325  }
12326  return emode;
12327 }
#define DEBUG1
Definition: elog.h:25
static XLogSource readSource
Definition: xlog.c:784
#define LOG
Definition: elog.h:26
uint64 XLogRecPtr
Definition: xlogdefs.h:21

◆ exitArchiveRecovery()

static void exitArchiveRecovery ( TimeLineID  endTLI,
XLogRecPtr  endOfLog 
)
static

Definition at line 5626 of file xlog.c.

References Assert, close, durable_rename(), ereport, errcode_for_file_access(), errmsg(), ERROR, FATAL, fd(), InArchiveRecovery, InvalidXLogRecPtr, LOG, MAXFNAMELEN, MAXPGPATH, readFile, RECOVERY_COMMAND_DONE, RECOVERY_COMMAND_FILE, snprintf, ThisTimeLineID, UpdateMinRecoveryPoint(), wal_segment_size, XLByteToPrevSeg, XLByteToSeg, XLogArchiveCleanup(), XLOGDIR, XLogFileCopy(), XLogFileInit(), XLogFileName, XLogFileNameP(), and XLogSegmentOffset.

Referenced by StartupXLOG().

5627 {
5628  char recoveryPath[MAXPGPATH];
5629  char xlogfname[MAXFNAMELEN];
5630  XLogSegNo endLogSegNo;
5631  XLogSegNo startLogSegNo;
5632 
5633  /* we always switch to a new timeline after archive recovery */
5634  Assert(endTLI != ThisTimeLineID);
5635 
5636  /*
5637  * We are no longer in archive recovery state.
5638  */
5639  InArchiveRecovery = false;
5640 
5641  /*
5642  * Update min recovery point one last time.
5643  */
5645 
5646  /*
5647  * If the ending log segment is still open, close it (to avoid problems on
5648  * Windows with trying to rename or delete an open file).
5649  */
5650  if (readFile >= 0)
5651  {
5652  close(readFile);
5653  readFile = -1;
5654  }
5655 
5656  /*
5657  * Calculate the last segment on the old timeline, and the first segment
5658  * on the new timeline. If the switch happens in the middle of a segment,
5659  * they are the same, but if the switch happens exactly at a segment
5660  * boundary, startLogSegNo will be endLogSegNo + 1.
5661  */
5662  XLByteToPrevSeg(endOfLog, endLogSegNo, wal_segment_size);
5663  XLByteToSeg(endOfLog, startLogSegNo, wal_segment_size);
5664 
5665  /*
5666  * Initialize the starting WAL segment for the new timeline. If the switch
5667  * happens in the middle of a segment, copy data from the last WAL segment
5668  * of the old timeline up to the switch point, to the starting WAL segment
5669  * on the new timeline.
5670  */
5671  if (endLogSegNo == startLogSegNo)
5672  {
5673  /*
5674  * Make a copy of the file on the new timeline.
5675  *
5676  * Writing WAL isn't allowed yet, so there are no locking
5677  * considerations. But we should be just as tense as XLogFileInit to
5678  * avoid emplacing a bogus file.
5679  */
5680  XLogFileCopy(endLogSegNo, endTLI, endLogSegNo,
5681  XLogSegmentOffset(endOfLog, wal_segment_size));
5682  }
5683  else
5684  {
5685  /*
5686  * The switch happened at a segment boundary, so just create the next
5687  * segment on the new timeline.
5688  */
5689  bool use_existent = true;
5690  int fd;
5691 
5692  fd = XLogFileInit(startLogSegNo, &use_existent, true);
5693 
5694  if (close(fd))
5695  ereport(ERROR,
5697  errmsg("could not close file \"%s\": %m",
5698  XLogFileNameP(ThisTimeLineID, startLogSegNo))));
5699  }
5700 
5701  /*
5702  * Let's just make real sure there are not .ready or .done flags posted
5703  * for the new segment.
5704  */
5705  XLogFileName(xlogfname, ThisTimeLineID, startLogSegNo, wal_segment_size);
5706  XLogArchiveCleanup(xlogfname);
5707 
5708