PostgreSQL Source Code  git master
xlog.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <math.h>
#include <time.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include "access/clog.h"
#include "access/commit_ts.h"
#include "access/heaptoast.h"
#include "access/multixact.h"
#include "access/rewriteheap.h"
#include "access/subtrans.h"
#include "access/timeline.h"
#include "access/transam.h"
#include "access/twophase.h"
#include "access/xact.h"
#include "access/xlog_internal.h"
#include "access/xlogarchive.h"
#include "access/xloginsert.h"
#include "access/xlogreader.h"
#include "access/xlogutils.h"
#include "catalog/catversion.h"
#include "catalog/pg_control.h"
#include "catalog/pg_database.h"
#include "commands/progress.h"
#include "commands/tablespace.h"
#include "common/controldata_utils.h"
#include "executor/instrument.h"
#include "miscadmin.h"
#include "pg_trace.h"
#include "pgstat.h"
#include "port/atomics.h"
#include "port/pg_iovec.h"
#include "postmaster/bgwriter.h"
#include "postmaster/startup.h"
#include "postmaster/walwriter.h"
#include "replication/basebackup.h"
#include "replication/logical.h"
#include "replication/origin.h"
#include "replication/slot.h"
#include "replication/snapbuild.h"
#include "replication/walreceiver.h"
#include "replication/walsender.h"
#include "storage/bufmgr.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/large_object.h"
#include "storage/latch.h"
#include "storage/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 "storage/sync.h"
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/ps_status.h"
#include "utils/relmapper.h"
#include "utils/pg_rusage.h"
#include "utils/snapmgr.h"
#include "utils/timeout.h"
#include "utils/timestamp.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 RECOVERY_COMMAND_FILE   "recovery.conf"
 
#define RECOVERY_COMMAND_DONE   "recovery.done"
 
#define BootstrapTimeLineID   1
 
#define NUM_XLOGINSERT_LOCKS   8
 
#define INSERT_FREESPACE(endptr)    (((endptr) % XLOG_BLCKSZ == 0) ? 0 : (XLOG_BLCKSZ - (endptr) % XLOG_BLCKSZ))
 
#define NextBufIdx(idx)    (((idx) == XLogCtl->XLogCacheBlck) ? 0 : ((idx) + 1))
 
#define XLogRecPtrToBufIdx(recptr)    (((recptr) / XLOG_BLCKSZ) % (XLogCtl->XLogCacheBlck + 1))
 
#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)
 
#define ConvertToXSegs(x, segsize)   XLogMBVarToSegs((x), (segsize))
 

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 readRecoverySignalFile (void)
 
static void validateRecoveryParameters (void)
 
static void exitArchiveRecovery (TimeLineID endTLI, XLogRecPtr endOfLog, TimeLineID newTLI)
 
static void CleanupAfterArchiveRecovery (TimeLineID EndOfLogTLI, XLogRecPtr EndOfLog, TimeLineID newTLI)
 
static bool recoveryStopsBefore (XLogReaderState *record)
 
static bool recoveryStopsAfter (XLogReaderState *record)
 
static char * getRecoveryStopReason (void)
 
static void ConfirmRecoveryPaused (void)
 
static void recoveryPausesHere (bool endOfRecovery)
 
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, TimeLineID replayTLI)
 
static void VerifyOverwriteContrecord (xl_overwrite_contrecord *xlrec, XLogReaderState *state)
 
static int LocalSetXLogInsertAllowed (void)
 
static void CreateEndOfRecoveryRecord (void)
 
static XLogRecPtr CreateOverwriteContrecordRecord (XLogRecPtr aborted_lsn)
 
static void CheckPointGuts (XLogRecPtr checkPointRedo, int flags)
 
static void KeepLogSeg (XLogRecPtr recptr, XLogSegNo *logSegNo)
 
static XLogRecPtr XLogGetReplicationSlotMinimumLSN (void)
 
static void AdvanceXLInsertBuffer (XLogRecPtr upto, TimeLineID tli, bool opportunistic)
 
static bool XLogCheckpointNeeded (XLogSegNo new_segno)
 
static void XLogWrite (XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
 
static bool InstallXLogFileSegment (XLogSegNo *segno, char *tmppath, bool find_free, XLogSegNo max_segno, TimeLineID tli)
 
static int XLogFileRead (XLogSegNo segno, int emode, TimeLineID tli, XLogSource source, bool notfoundOk)
 
static int XLogFileReadAnyTLI (XLogSegNo segno, int emode, XLogSource source)
 
static int XLogPageRead (XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char *readBuf)
 
static bool WaitForWALToBecomeAvailable (XLogRecPtr RecPtr, bool randAccess, bool fetching_ckpt, XLogRecPtr tliRecPtr, TimeLineID replayTLI, XLogRecPtr replayLSN)
 
static void XLogShutdownWalRcv (void)
 
static int emode_for_corrupt_record (int emode, XLogRecPtr RecPtr)
 
static void XLogFileClose (void)
 
static void PreallocXlogFiles (XLogRecPtr endptr, TimeLineID tli)
 
static void RemoveTempXlogFiles (void)
 
static void RemoveOldXlogFiles (XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr, TimeLineID insertTLI)
 
static void RemoveXlogFile (const char *segname, XLogSegNo recycleSegNo, XLogSegNo *endlogSegNo, TimeLineID insertTLI)
 
static void UpdateLastRemovedPtr (char *filename)
 
static void ValidateXLOGDirectoryStructure (void)
 
static void CleanupBackupHistory (void)
 
static void UpdateMinRecoveryPoint (XLogRecPtr lsn, bool force)
 
static XLogRecordReadRecord (XLogReaderState *xlogreader, int emode, bool fetching_ckpt, TimeLineID replayTLI)
 
static void CheckRecoveryConsistency (void)
 
static bool PerformRecoveryXLogAction (void)
 
static XLogRecordReadCheckpointRecord (XLogReaderState *xlogreader, XLogRecPtr RecPtr, int whichChkpt, bool report, TimeLineID replayTLI)
 
static bool rescanLatestTimeLine (TimeLineID replayTLI, XLogRecPtr replayLSN)
 
static void InitControlFile (uint64 sysidentifier)
 
static void WriteControlFile (void)
 
static void ReadControlFile (void)
 
static char * str_time (pg_time_t tnow)
 
static void SetPromoteIsTriggered (void)
 
static bool CheckForStandbyTrigger (void)
 
static void xlog_block_info (StringInfo buf, XLogReaderState *record)
 
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, TimeLineID *backupLabelTLI, 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, TimeLineID tli)
 
static void ReserveXLogInsertLocation (int size, XLogRecPtr *StartPos, XLogRecPtr *EndPos, XLogRecPtr *PrevPtr)
 
static bool ReserveXLogSwitch (XLogRecPtr *StartPos, XLogRecPtr *EndPos, XLogRecPtr *PrevPtr)
 
static XLogRecPtr WaitXLogInsertionsToFinish (XLogRecPtr upto)
 
static char * GetXLogBuffer (XLogRecPtr ptr, TimeLineID tli)
 
static XLogRecPtr XLogBytePosToRecPtr (uint64 bytepos)
 
static XLogRecPtr XLogBytePosToEndRecPtr (uint64 bytepos)
 
static uint64 XLogRecPtrToBytePos (XLogRecPtr ptr)
 
static void 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, int num_fpi, bool topxid_included)
 
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 lastredoptr)
 
void XLogSetAsyncXactLSN (XLogRecPtr asyncXactLSN)
 
void XLogSetReplicationSlotMinimumLSN (XLogRecPtr lsn)
 
void XLogFlush (XLogRecPtr record)
 
bool XLogBackgroundFlush (void)
 
bool XLogNeedsFlush (XLogRecPtr record)
 
static int XLogFileInitInternal (XLogSegNo logsegno, TimeLineID logtli, bool *added, char *path)
 
int XLogFileInit (XLogSegNo logsegno, TimeLineID logtli)
 
static void XLogFileCopy (TimeLineID destTLI, XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno, int upto)
 
int XLogFileOpen (XLogSegNo segno, TimeLineID tli)
 
void CheckXLogRemoved (XLogSegNo segno, TimeLineID tli)
 
XLogSegNo XLogGetLastRemovedSegno (void)
 
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)
 
RecoveryPauseState GetRecoveryPauseState (void)
 
void SetRecoveryPause (bool recoveryPause)
 
TimestampTz GetLatestXTime (void)
 
TimestampTz GetCurrentChunkReplayStartTime (void)
 
void GetXLogReceiptTime (TimestampTz *rtime, bool *fromStream)
 
static void RecoveryRequiresIntParameter (const char *param_name, int currValue, int minValue)
 
void StartupXLOG (void)
 
bool RecoveryInProgress (void)
 
RecoveryState GetRecoveryState (void)
 
bool HotStandbyActive (void)
 
bool HotStandbyActiveInReplay (void)
 
bool XLogInsertAllowed (void)
 
XLogRecPtr GetRedoRecPtr (void)
 
void GetFullPageWriteInfo (XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p)
 
XLogRecPtr GetInsertRecPtr (void)
 
XLogRecPtr GetFlushRecPtr (TimeLineID *insertTLI)
 
TimeLineID GetWALInsertionTimeLine (void)
 
XLogRecPtr GetLastImportantRecPtr (void)
 
pg_time_t GetLastSegSwitchData (XLogRecPtr *lastSwitchLSN)
 
void ShutdownXLOG (int code, Datum arg)
 
static void LogCheckpointStart (int flags, bool restartpoint)
 
static void LogCheckpointEnd (bool restartpoint)
 
static void UpdateCheckPointDistanceEstimate (uint64 nbytes)
 
static void update_checkpoint_display (int flags, bool restartpoint, bool reset)
 
void CreateCheckPoint (int flags)
 
static void RecoveryRestartPoint (const CheckPoint *checkPoint, XLogReaderState *record)
 
bool CreateRestartPoint (int flags)
 
WALAvailability GetWALAvailability (XLogRecPtr targetLSN)
 
void XLogPutNextOid (Oid nextOid)
 
XLogRecPtr RequestXLogSwitch (bool mark_unimportant)
 
XLogRecPtr XLogRestorePoint (const char *rpName)
 
void UpdateFullPageWrites (void)
 
void xlog_redo (XLogReaderState *record)
 
void assign_xlog_sync_method (int new_sync_method, void *extra)
 
void issue_xlog_fsync (int fd, XLogSegNo segno, TimeLineID tli)
 
XLogRecPtr do_pg_start_backup (const char *backupidstr, bool fast, TimeLineID *starttli_p, StringInfo labelfile, List **tablespaces, StringInfo tblspcmapfile)
 
SessionBackupState get_backup_status (void)
 
XLogRecPtr do_pg_stop_backup (char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 
void do_pg_abort_backup (int code, Datum arg)
 
void register_persistent_abort_backup_handler (void)
 
XLogRecPtr GetXLogReplayRecPtr (TimeLineID *replayTLI)
 
XLogRecPtr GetXLogInsertRecPtr (void)
 
XLogRecPtr GetXLogWriteRecPtr (void)
 
void GetOldestRestartPoint (XLogRecPtr *oldrecptr, TimeLineID *oldtli)
 
bool BackupInProgress (void)
 
void CancelBackup (void)
 
void StartupRequestWalReceiverRestart (void)
 
bool PromoteIsTriggered (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_size_mb = 0
 
int XLOGbuffers = -1
 
int XLogArchiveTimeout = 0
 
int XLogArchiveMode = ARCHIVE_MODE_OFF
 
char * XLogArchiveCommand = NULL
 
bool EnableHotStandby = false
 
bool fullPageWrites = true
 
bool wal_log_hints = false
 
int wal_compression = WAL_COMPRESSION_NONE
 
char * wal_consistency_checking_string = NULL
 
boolwal_consistency_checking = NULL
 
bool wal_init_zero = true
 
bool wal_recycle = true
 
bool log_checkpoints = true
 
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 max_slot_wal_keep_size_mb = -1
 
bool track_wal_io_timing = false
 
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 []
 
const struct config_enum_entry recovery_target_action_options []
 
CheckpointStatsData CheckpointStats
 
static XLogRecPtr flushedUpto = 0
 
static TimeLineID receiveTLI = 0
 
static XLogRecPtr abortedRecPtr
 
static XLogRecPtr missingContrecPtr
 
static bool lastFullPageWrites
 
static bool LocalRecoveryInProgress = true
 
static bool LocalHotStandbyActive = false
 
static bool LocalPromoteIsTriggered = false
 
static int LocalXLogInsertAllowed = -1
 
bool ArchiveRecoveryRequested = false
 
bool InArchiveRecovery = false
 
static bool standby_signal_file_found = false
 
static bool recovery_signal_file_found = false
 
static char * replay_image_masked = NULL
 
static char * primary_image_masked = NULL
 
char * recoveryRestoreCommand = NULL
 
char * recoveryEndCommand = NULL
 
char * archiveCleanupCommand = NULL
 
RecoveryTargetType recoveryTarget = RECOVERY_TARGET_UNSET
 
bool recoveryTargetInclusive = true
 
int recoveryTargetAction = RECOVERY_TARGET_ACTION_PAUSE
 
TransactionId recoveryTargetXid
 
char * recovery_target_time_string
 
static TimestampTz recoveryTargetTime
 
const char * recoveryTargetName
 
XLogRecPtr recoveryTargetLSN
 
int recovery_min_apply_delay = 0
 
bool StandbyModeRequested = false
 
char * PrimaryConnInfo = NULL
 
char * PrimarySlotName = NULL
 
char * PromoteTriggerFile = NULL
 
bool wal_receiver_create_temp_slot = false
 
bool StandbyMode = false
 
static TransactionId recoveryStopXid
 
static TimestampTz recoveryStopTime
 
static XLogRecPtr recoveryStopLSN
 
static char recoveryStopName [MAXFNAMELEN]
 
static bool recoveryStopAfter
 
RecoveryTargetTimeLineGoal recoveryTargetTimeLineGoal = RECOVERY_TARGET_TIMELINE_LATEST
 
TimeLineID recoveryTargetTLIRequested = 0
 
TimeLineID recoveryTargetTLI = 0
 
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 *const xlogSourceNames [] = {"any", "archive", "pg_wal", "stream"}
 
static int openLogFile = -1
 
static XLogSegNo openLogSegNo = 0
 
static TimeLineID openLogTLI = 0
 
static int readFile = -1
 
static XLogSegNo readSegNo = 0
 
static uint32 readOff = 0
 
static uint32 readLen = 0
 
static XLogSource readSource = XLOG_FROM_ANY
 
static XLogSource currentSource = XLOG_FROM_ANY
 
static bool lastSourceFailed = false
 
static bool pendingWalRcvRestart = false
 
static TimestampTz XLogReceiptTime = 0
 
static XLogSource XLogReceiptSource = XLOG_FROM_ANY
 
static XLogRecPtr minRecoveryPoint
 
static TimeLineID minRecoveryPointTLI
 
static bool updateMinRecoveryPoint = true
 
bool reachedConsistency = false
 
static bool InRedo = false
 
static int MyLockNo = 0
 
static bool holdingAllLocks = false
 

Macro Definition Documentation

◆ BootstrapTimeLineID

#define BootstrapTimeLineID   1

Definition at line 92 of file xlog.c.

◆ ConvertToXSegs

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

Definition at line 779 of file xlog.c.

◆ INSERT_FREESPACE

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

Definition at line 756 of file xlog.c.

◆ NextBufIdx

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

Definition at line 760 of file xlog.c.

◆ NUM_XLOGINSERT_LOCKS

#define NUM_XLOGINSERT_LOCKS   8

Definition at line 130 of file xlog.c.

◆ RECOVERY_COMMAND_DONE

#define RECOVERY_COMMAND_DONE   "recovery.done"

Definition at line 89 of file xlog.c.

◆ RECOVERY_COMMAND_FILE

#define RECOVERY_COMMAND_FILE   "recovery.conf"

Definition at line 88 of file xlog.c.

◆ UsableBytesInPage

#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)

Definition at line 773 of file xlog.c.

◆ XLogRecPtrToBufIdx

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

Definition at line 767 of file xlog.c.

Typedef Documentation

◆ ExclusiveBackupState

◆ WALInsertLockPadded

◆ XLogCtlData

typedef struct XLogCtlData XLogCtlData

◆ XLogCtlInsert

typedef struct XLogCtlInsert XLogCtlInsert

◆ XLogPageReadPrivate

◆ XLogwrtResult

typedef struct XLogwrtResult XLogwrtResult

◆ XLogwrtRqst

typedef struct XLogwrtRqst XLogwrtRqst

Enumeration Type Documentation

◆ ExclusiveBackupState

Enumerator
EXCLUSIVE_BACKUP_NONE 
EXCLUSIVE_BACKUP_STARTING 
EXCLUSIVE_BACKUP_IN_PROGRESS 
EXCLUSIVE_BACKUP_STOPPING 

Definition at line 512 of file xlog.c.

513 {
ExclusiveBackupState
Definition: xlog.c:513
@ EXCLUSIVE_BACKUP_STOPPING
Definition: xlog.c:517
@ EXCLUSIVE_BACKUP_NONE
Definition: xlog.c:514
@ EXCLUSIVE_BACKUP_STARTING
Definition: xlog.c:515
@ EXCLUSIVE_BACKUP_IN_PROGRESS
Definition: xlog.c:516

◆ XLogSource

enum XLogSource
Enumerator
XLOG_FROM_ANY 
XLOG_FROM_ARCHIVE 
XLOG_FROM_PG_WAL 
XLOG_FROM_STREAM 

Definition at line 794 of file xlog.c.

795 {
796  XLOG_FROM_ANY = 0, /* request to read WAL from any source */
797  XLOG_FROM_ARCHIVE, /* restored using restore_command */
798  XLOG_FROM_PG_WAL, /* existing file in pg_wal */
799  XLOG_FROM_STREAM /* streamed from primary */
800 } XLogSource;
XLogSource
Definition: xlog.c:795
@ XLOG_FROM_PG_WAL
Definition: xlog.c:798
@ XLOG_FROM_STREAM
Definition: xlog.c:799
@ XLOG_FROM_ARCHIVE
Definition: xlog.c:797
@ XLOG_FROM_ANY
Definition: xlog.c:796

Function Documentation

◆ AdvanceXLInsertBuffer()

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

Definition at line 2170 of file xlog.c.

2171 {
2173  int nextidx;
2174  XLogRecPtr OldPageRqstPtr;
2175  XLogwrtRqst WriteRqst;
2176  XLogRecPtr NewPageEndPtr = InvalidXLogRecPtr;
2177  XLogRecPtr NewPageBeginPtr;
2178  XLogPageHeader NewPage;
2179  int npages = 0;
2180 
2181  LWLockAcquire(WALBufMappingLock, LW_EXCLUSIVE);
2182 
2183  /*
2184  * Now that we have the lock, check if someone initialized the page
2185  * already.
2186  */
2187  while (upto >= XLogCtl->InitializedUpTo || opportunistic)
2188  {
2190 
2191  /*
2192  * Get ending-offset of the buffer page we need to replace (this may
2193  * be zero if the buffer hasn't been used yet). Fall through if it's
2194  * already written out.
2195  */
2196  OldPageRqstPtr = XLogCtl->xlblocks[nextidx];
2197  if (LogwrtResult.Write < OldPageRqstPtr)
2198  {
2199  /*
2200  * Nope, got work to do. If we just want to pre-initialize as much
2201  * as we can without flushing, give up now.
2202  */
2203  if (opportunistic)
2204  break;
2205 
2206  /* Before waiting, get info_lck and update LogwrtResult */
2208  if (XLogCtl->LogwrtRqst.Write < OldPageRqstPtr)
2209  XLogCtl->LogwrtRqst.Write = OldPageRqstPtr;
2212 
2213  /*
2214  * Now that we have an up-to-date LogwrtResult value, see if we
2215  * still need to write it or if someone else already did.
2216  */
2217  if (LogwrtResult.Write < OldPageRqstPtr)
2218  {
2219  /*
2220  * Must acquire write lock. Release WALBufMappingLock first,
2221  * to make sure that all insertions that we need to wait for
2222  * can finish (up to this same position). Otherwise we risk
2223  * deadlock.
2224  */
2225  LWLockRelease(WALBufMappingLock);
2226 
2227  WaitXLogInsertionsToFinish(OldPageRqstPtr);
2228 
2229  LWLockAcquire(WALWriteLock, LW_EXCLUSIVE);
2230 
2232  if (LogwrtResult.Write >= OldPageRqstPtr)
2233  {
2234  /* OK, someone wrote it already */
2235  LWLockRelease(WALWriteLock);
2236  }
2237  else
2238  {
2239  /* Have to write it ourselves */
2240  TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_START();
2241  WriteRqst.Write = OldPageRqstPtr;
2242  WriteRqst.Flush = 0;
2243  XLogWrite(WriteRqst, tli, false);
2244  LWLockRelease(WALWriteLock);
2246  TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_DONE();
2247  }
2248  /* Re-acquire WALBufMappingLock and retry */
2249  LWLockAcquire(WALBufMappingLock, LW_EXCLUSIVE);
2250  continue;
2251  }
2252  }
2253 
2254  /*
2255  * Now the next buffer slot is free and we can set it up to be the
2256  * next output page.
2257  */
2258  NewPageBeginPtr = XLogCtl->InitializedUpTo;
2259  NewPageEndPtr = NewPageBeginPtr + XLOG_BLCKSZ;
2260 
2261  Assert(XLogRecPtrToBufIdx(NewPageBeginPtr) == nextidx);
2262 
2263  NewPage = (XLogPageHeader) (XLogCtl->pages + nextidx * (Size) XLOG_BLCKSZ);
2264 
2265  /*
2266  * Be sure to re-zero the buffer so that bytes beyond what we've
2267  * written will look like zeroes and not valid XLOG records...
2268  */
2269  MemSet((char *) NewPage, 0, XLOG_BLCKSZ);
2270 
2271  /*
2272  * Fill the new page's header
2273  */
2274  NewPage->xlp_magic = XLOG_PAGE_MAGIC;
2275 
2276  /* NewPage->xlp_info = 0; */ /* done by memset */
2277  NewPage->xlp_tli = tli;
2278  NewPage->xlp_pageaddr = NewPageBeginPtr;
2279 
2280  /* NewPage->xlp_rem_len = 0; */ /* done by memset */
2281 
2282  /*
2283  * If online backup is not in progress, mark the header to indicate
2284  * that WAL records beginning in this page have removable backup
2285  * blocks. This allows the WAL archiver to know whether it is safe to
2286  * compress archived WAL data by transforming full-block records into
2287  * the non-full-block format. It is sufficient to record this at the
2288  * page level because we force a page switch (in fact a segment
2289  * switch) when starting a backup, so the flag will be off before any
2290  * records can be written during the backup. At the end of a backup,
2291  * the last page will be marked as all unsafe when perhaps only part
2292  * is unsafe, but at worst the archiver would miss the opportunity to
2293  * compress a few records.
2294  */
2295  if (!Insert->forcePageWrites)
2296  NewPage->xlp_info |= XLP_BKP_REMOVABLE;
2297 
2298  /*
2299  * If a record was found to be broken at the end of recovery, and
2300  * we're going to write on the page where its first contrecord was
2301  * lost, set the XLP_FIRST_IS_OVERWRITE_CONTRECORD flag on the page
2302  * header. See CreateOverwriteContrecordRecord().
2303  */
2304  if (missingContrecPtr == NewPageBeginPtr)
2305  {
2308  }
2309 
2310  /*
2311  * If first page of an XLOG segment file, make it a long header.
2312  */
2313  if ((XLogSegmentOffset(NewPage->xlp_pageaddr, wal_segment_size)) == 0)
2314  {
2315  XLogLongPageHeader NewLongPage = (XLogLongPageHeader) NewPage;
2316 
2317  NewLongPage->xlp_sysid = ControlFile->system_identifier;
2318  NewLongPage->xlp_seg_size = wal_segment_size;
2319  NewLongPage->xlp_xlog_blcksz = XLOG_BLCKSZ;
2320  NewPage->xlp_info |= XLP_LONG_HEADER;
2321  }
2322 
2323  /*
2324  * Make sure the initialization of the page becomes visible to others
2325  * before the xlblocks update. GetXLogBuffer() reads xlblocks without
2326  * holding a lock.
2327  */
2328  pg_write_barrier();
2329 
2330  *((volatile XLogRecPtr *) &XLogCtl->xlblocks[nextidx]) = NewPageEndPtr;
2331 
2332  XLogCtl->InitializedUpTo = NewPageEndPtr;
2333 
2334  npages++;
2335  }
2336  LWLockRelease(WALBufMappingLock);
2337 
2338 #ifdef WAL_DEBUG
2339  if (XLOG_DEBUG && npages > 0)
2340  {
2341  elog(DEBUG1, "initialized %d pages, up to %X/%X",
2342  npages, LSN_FORMAT_ARGS(NewPageEndPtr));
2343  }
2344 #endif
2345 }
#define pg_write_barrier()
Definition: atomics.h:159
#define MemSet(start, val, len)
Definition: c.h:1008
size_t Size
Definition: c.h:540
#define DEBUG1
Definition: elog.h:24
#define elog(elevel,...)
Definition: elog.h:218
static void Insert(File file)
Definition: fd.c:1304
Assert(fmt[strlen(fmt) - 1] !='\n')
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1199
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1803
@ LW_EXCLUSIVE
Definition: lwlock.h:104
PgStat_MsgWal WalStats
Definition: pgstat.c:129
#define SpinLockRelease(lock)
Definition: spin.h:64
#define SpinLockAcquire(lock)
Definition: spin.h:62
uint64 system_identifier
Definition: pg_control.h:108
PgStat_Counter m_wal_buffers_full
Definition: pgstat.h:497
XLogwrtRqst LogwrtRqst
Definition: xlog.c:593
slock_t info_lck
Definition: xlog.c:739
XLogRecPtr InitializedUpTo
Definition: xlog.c:625
char * pages
Definition: xlog.c:632
XLogwrtResult LogwrtResult
Definition: xlog.c:613
XLogCtlInsert Insert
Definition: xlog.c:590
XLogRecPtr * xlblocks
Definition: xlog.c:633
TimeLineID xlp_tli
Definition: xlog_internal.h:40
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
XLogRecPtr Write
Definition: xlog.c:437
XLogRecPtr Flush
Definition: xlog.c:432
XLogRecPtr Write
Definition: xlog.c:431
static XLogCtlData * XLogCtl
Definition: xlog.c:742
static XLogRecPtr WaitXLogInsertionsToFinish(XLogRecPtr upto)
Definition: xlog.c:1833
int wal_segment_size
Definition: xlog.c:123
static XLogRecPtr missingContrecPtr
Definition: xlog.c:205
static XLogwrtResult LogwrtResult
Definition: xlog.c:788
#define XLogRecPtrToBufIdx(recptr)
Definition: xlog.c:767
static void XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
Definition: xlog.c:2473
static ControlFileData * ControlFile
Definition: xlog.c:750
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:71
#define XLP_FIRST_IS_OVERWRITE_CONTRECORD
Definition: xlog_internal.h:80
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:54
#define XLP_LONG_HEADER
Definition: xlog_internal.h:76
#define XLP_BKP_REMOVABLE
Definition: xlog_internal.h:78
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
#define LSN_FORMAT_ARGS(lsn)
Definition: xlogdefs.h:43
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28

References Assert(), ControlFile, DEBUG1, elog, XLogwrtRqst::Flush, XLogCtlData::info_lck, XLogCtlData::InitializedUpTo, XLogCtlData::Insert, Insert(), InvalidXLogRecPtr, XLogCtlData::LogwrtResult, LogwrtResult, XLogCtlData::LogwrtRqst, LSN_FORMAT_ARGS, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), PgStat_MsgWal::m_wal_buffers_full, MemSet, missingContrecPtr, XLogCtlData::pages, pg_write_barrier, SpinLockAcquire, SpinLockRelease, ControlFileData::system_identifier, WaitXLogInsertionsToFinish(), wal_segment_size, WalStats, XLogwrtRqst::Write, XLogwrtResult::Write, XLogCtlData::xlblocks, XLOG_PAGE_MAGIC, XLogCtl, XLogRecPtrToBufIdx, XLogSegmentOffset, XLogWrite(), XLP_BKP_REMOVABLE, XLP_FIRST_IS_OVERWRITE_CONTRECORD, XLP_LONG_HEADER, XLogLongPageHeaderData::xlp_seg_size, XLogLongPageHeaderData::xlp_sysid, and XLogLongPageHeaderData::xlp_xlog_blcksz.

Referenced by GetXLogBuffer(), and XLogBackgroundFlush().

◆ assign_checkpoint_completion_target()

void assign_checkpoint_completion_target ( double  newval,
void *  extra 
)

Definition at line 2388 of file xlog.c.

2389 {
2392 }
double CheckPointCompletionTarget
Definition: checkpointer.c:145
#define newval
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2352

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2381 of file xlog.c.

2382 {
2385 }
int max_wal_size_mb
Definition: xlog.c:95

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

◆ assign_xlog_sync_method()

void assign_xlog_sync_method ( int  new_sync_method,
void *  extra 
)

Definition at line 10817 of file xlog.c.

10818 {
10819  if (sync_method != new_sync_method)
10820  {
10821  /*
10822  * To ensure that no blocks escape unsynced, force an fsync on the
10823  * currently open log segment (if any). Also, if the open flag is
10824  * changing, close the log file so it will be reopened (with new flag
10825  * bit) at next use.
10826  */
10827  if (openLogFile >= 0)
10828  {
10830  if (pg_fsync(openLogFile) != 0)
10831  {
10832  char xlogfname[MAXFNAMELEN];
10833  int save_errno;
10834 
10835  save_errno = errno;
10836  XLogFileName(xlogfname, openLogTLI, openLogSegNo,
10838  errno = save_errno;
10839  ereport(PANIC,
10841  errmsg("could not fsync file \"%s\": %m", xlogfname)));
10842  }
10843 
10845  if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
10846  XLogFileClose();
10847  }
10848  }
10849 }
int errcode_for_file_access(void)
Definition: elog.c:716
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define PANIC
Definition: elog.h:36
#define ereport(elevel,...)
Definition: elog.h:143
int pg_fsync(int fd)
Definition: fd.c:359
@ WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN
Definition: wait_event.h:227
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:262
static void pgstat_report_wait_end(void)
Definition: wait_event.h:278
static int openLogFile
Definition: xlog.c:813
static int get_sync_bit(int method)
Definition: xlog.c:10761
static TimeLineID openLogTLI
Definition: xlog.c:815
static void XLogFileClose(void)
Definition: xlog.c:3967
static XLogSegNo openLogSegNo
Definition: xlog.c:814
int sync_method
Definition: xlog.c:111
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
#define MAXFNAMELEN

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

◆ BackupInProgress()

bool BackupInProgress ( void  )

Definition at line 12285 of file xlog.c.

12286 {
12287  struct stat stat_buf;
12288 
12289  return (stat(BACKUP_LABEL_FILE, &stat_buf) == 0);
12290 }
#define stat
Definition: win32_port.h:283
#define BACKUP_LABEL_FILE
Definition: xlog.h:359

References BACKUP_LABEL_FILE, and stat.

Referenced by pg_is_in_backup(), and PostmasterStateMachine().

◆ BootStrapXLOG()

void BootStrapXLOG ( void  )

Definition at line 5347 of file xlog.c.

5348 {
5349  CheckPoint checkPoint;
5350  char *buffer;
5351  XLogPageHeader page;
5352  XLogLongPageHeader longpage;
5353  XLogRecord *record;
5354  char *recptr;
5355  uint64 sysidentifier;
5356  struct timeval tv;
5357  pg_crc32c crc;
5358 
5359  /* allow ordinary WAL segment creation, like StartupXLOG() would */
5360  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
5362  LWLockRelease(ControlFileLock);
5363 
5364  /*
5365  * Select a hopefully-unique system identifier code for this installation.
5366  * We use the result of gettimeofday(), including the fractional seconds
5367  * field, as being about as unique as we can easily get. (Think not to
5368  * use random(), since it hasn't been seeded and there's no portable way
5369  * to seed it other than the system clock value...) The upper half of the
5370  * uint64 value is just the tv_sec part, while the lower half contains the
5371  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
5372  * PID for a little extra uniqueness. A person knowing this encoding can
5373  * determine the initialization time of the installation, which could
5374  * perhaps be useful sometimes.
5375  */
5376  gettimeofday(&tv, NULL);
5377  sysidentifier = ((uint64) tv.tv_sec) << 32;
5378  sysidentifier |= ((uint64) tv.tv_usec) << 12;
5379  sysidentifier |= getpid() & 0xFFF;
5380 
5381  /* page buffer must be aligned suitably for O_DIRECT */
5382  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
5383  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
5384  memset(page, 0, XLOG_BLCKSZ);
5385 
5386  /*
5387  * Set up information for the initial checkpoint record
5388  *
5389  * The initial checkpoint record is written to the beginning of the WAL
5390  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5391  * used, so that we can use 0/0 to mean "before any valid WAL segment".
5392  */
5393  checkPoint.redo = wal_segment_size + SizeOfXLogLongPHD;
5394  checkPoint.ThisTimeLineID = BootstrapTimeLineID;
5395  checkPoint.PrevTimeLineID = BootstrapTimeLineID;
5396  checkPoint.fullPageWrites = fullPageWrites;
5397  checkPoint.nextXid =
5399  checkPoint.nextOid = FirstGenbkiObjectId;
5400  checkPoint.nextMulti = FirstMultiXactId;
5401  checkPoint.nextMultiOffset = 0;
5402  checkPoint.oldestXid = FirstNormalTransactionId;
5403  checkPoint.oldestXidDB = TemplateDbOid;
5404  checkPoint.oldestMulti = FirstMultiXactId;
5405  checkPoint.oldestMultiDB = TemplateDbOid;
5408  checkPoint.time = (pg_time_t) time(NULL);
5410 
5411  ShmemVariableCache->nextXid = checkPoint.nextXid;
5412  ShmemVariableCache->nextOid = checkPoint.nextOid;
5414  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5415  AdvanceOldestClogXid(checkPoint.oldestXid);
5416  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5417  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5419 
5420  /* Set up the XLOG page header */
5421  page->xlp_magic = XLOG_PAGE_MAGIC;
5422  page->xlp_info = XLP_LONG_HEADER;
5423  page->xlp_tli = BootstrapTimeLineID;
5425  longpage = (XLogLongPageHeader) page;
5426  longpage->xlp_sysid = sysidentifier;
5427  longpage->xlp_seg_size = wal_segment_size;
5428  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5429 
5430  /* Insert the initial checkpoint record */
5431  recptr = ((char *) page + SizeOfXLogLongPHD);
5432  record = (XLogRecord *) recptr;
5433  record->xl_prev = 0;
5434  record->xl_xid = InvalidTransactionId;
5435  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5437  record->xl_rmid = RM_XLOG_ID;
5438  recptr += SizeOfXLogRecord;
5439  /* fill the XLogRecordDataHeaderShort struct */
5440  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5441  *(recptr++) = sizeof(checkPoint);
5442  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5443  recptr += sizeof(checkPoint);
5444  Assert(recptr - (char *) record == record->xl_tot_len);
5445 
5446  INIT_CRC32C(crc);
5447  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5448  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5449  FIN_CRC32C(crc);
5450  record->xl_crc = crc;
5451 
5452  /* Create first XLOG segment file */
5455 
5456  /*
5457  * We needn't bother with Reserve/ReleaseExternalFD here, since we'll
5458  * close the file again in a moment.
5459  */
5460 
5461  /* Write the first page with the initial record */
5462  errno = 0;
5464  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5465  {
5466  /* if write didn't set errno, assume problem is no disk space */
5467  if (errno == 0)
5468  errno = ENOSPC;
5469  ereport(PANIC,
5471  errmsg("could not write bootstrap write-ahead log file: %m")));
5472  }
5474 
5476  if (pg_fsync(openLogFile) != 0)
5477  ereport(PANIC,
5479  errmsg("could not fsync bootstrap write-ahead log file: %m")));
5481 
5482  if (close(openLogFile) != 0)
5483  ereport(PANIC,
5485  errmsg("could not close bootstrap write-ahead log file: %m")));
5486 
5487  openLogFile = -1;
5488 
5489  /* Now create pg_control */
5490  InitControlFile(sysidentifier);
5491  ControlFile->time = checkPoint.time;
5492  ControlFile->checkPoint = checkPoint.redo;
5493  ControlFile->checkPointCopy = checkPoint;
5494 
5495  /* some additional ControlFile fields are set in WriteControlFile() */
5496  WriteControlFile();
5497 
5498  /* Bootstrap the commit log, too */
5499  BootStrapCLOG();
5503 
5504  pfree(buffer);
5505 
5506  /*
5507  * Force control file to be read - in contrast to normal processing we'd
5508  * otherwise never run the checks and GUC related initializations therein.
5509  */
5510  ReadControlFile();
5511 }
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:750
#define offsetof(type, field)
Definition: c.h:727
void BootStrapCLOG(void)
Definition: clog.c:712
void BootStrapCommitTs(void)
Definition: commit_ts.c:571
void SetCommitTsLimit(TransactionId oldestXact, TransactionId newestXact)
Definition: commit_ts.c:878
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:104
#define close(a)
Definition: win32.h:12
#define write(a, b, c)
Definition: win32.h:14
void pfree(void *pointer)
Definition: mcxt.c:1169
void * palloc(Size size)
Definition: mcxt.c:1062
void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset)
Definition: multixact.c:2179
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
Definition: multixact.c:2213
void BootStrapMultiXact(void)
Definition: multixact.c:1894
#define FirstMultiXactId
Definition: multixact.h:25
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
uint32 pg_crc32c
Definition: pg_crc32c.h:38
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:89
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:94
return crc
int64 pg_time_t
Definition: pgtime.h:23
Oid oldestMultiDB
Definition: pg_control.h:50
MultiXactId oldestMulti
Definition: pg_control.h:49
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
TransactionId newestCommitTsXid
Definition: pg_control.h:54
TransactionId oldestXid
Definition: pg_control.h:47
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
Oid nextOid
Definition: pg_control.h:44
TransactionId oldestActiveXid
Definition: pg_control.h:63
bool fullPageWrites
Definition: pg_control.h:42
MultiXactId nextMulti
Definition: pg_control.h:45
FullTransactionId nextXid
Definition: pg_control.h:43
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
pg_time_t time
Definition: pg_control.h:51
XLogRecPtr redo
Definition: pg_control.h:37
Oid oldestXidDB
Definition: pg_control.h:48
CheckPoint checkPointCopy
Definition: pg_control.h:133
pg_time_t time
Definition: pg_control.h:130
XLogRecPtr checkPoint
Definition: pg_control.h:131
FullTransactionId nextXid
Definition: transam.h:220
uint32 oidCount
Definition: transam.h:215
bool InstallXLogFileSegmentActive
Definition: xlog.c:667
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
uint8 xl_info
Definition: xlogrecord.h:46
uint32 xl_tot_len
Definition: xlogrecord.h:43
TransactionId xl_xid
Definition: xlogrecord.h:44
RmgrId xl_rmid
Definition: xlogrecord.h:47
void BootStrapSUBTRANS(void)
Definition: subtrans.c:211
#define InvalidTransactionId
Definition: transam.h:31
#define FirstGenbkiObjectId
Definition: transam.h:195
#define FirstNormalTransactionId
Definition: transam.h:34
static FullTransactionId FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
Definition: transam.h:71
void SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid)
Definition: varsup.c:345
void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid)
Definition: varsup.c:328
VariableCache ShmemVariableCache
Definition: varsup.c:34
@ WAIT_EVENT_WAL_BOOTSTRAP_SYNC
Definition: wait_event.h:218
@ WAIT_EVENT_WAL_BOOTSTRAP_WRITE
Definition: wait_event.h:219
int XLogFileInit(XLogSegNo logsegno, TimeLineID logtli)
Definition: xlog.c:3521
bool fullPageWrites
Definition: xlog.c:103
static void InitControlFile(uint64 sysidentifier)
Definition: xlog.c:4727
static void WriteControlFile(void)
Definition: xlog.c:4762
#define BootstrapTimeLineID
Definition: xlog.c:92
static void ReadControlFile(void)
Definition: xlog.c:4853
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:69
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:203
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:227
#define SizeOfXLogRecord
Definition: xlogrecord.h:55

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

Referenced by BootstrapModeMain().

◆ CalculateCheckpointSegments()

static void CalculateCheckpointSegments ( void  )
static

Definition at line 2352 of file xlog.c.

2353 {
2354  double target;
2355 
2356  /*-------
2357  * Calculate the distance at which to trigger a checkpoint, to avoid
2358  * exceeding max_wal_size_mb. This is based on two assumptions:
2359  *
2360  * a) we keep WAL for only one checkpoint cycle (prior to PG11 we kept
2361  * WAL for two checkpoint cycles to allow us to recover from the
2362  * secondary checkpoint if the first checkpoint failed, though we
2363  * only did this on the primary anyway, not on standby. Keeping just
2364  * one checkpoint simplifies processing and reduces disk space in
2365  * many smaller databases.)
2366  * b) during checkpoint, we consume checkpoint_completion_target *
2367  * number of segments consumed between checkpoints.
2368  *-------
2369  */
2370  target = (double) ConvertToXSegs(max_wal_size_mb, wal_segment_size) /
2372 
2373  /* round down */
2374  CheckPointSegments = (int) target;
2375 
2376  if (CheckPointSegments < 1)
2377  CheckPointSegments = 1;
2378 }
#define ConvertToXSegs(x, segsize)
Definition: xlog.c:779
int CheckPointSegments
Definition: xlog.c:136

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

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

◆ CancelBackup()

void CancelBackup ( void  )

Definition at line 12305 of file xlog.c.

12306 {
12307  struct stat stat_buf;
12308 
12309  /* if the backup_label file is not there, return */
12310  if (stat(BACKUP_LABEL_FILE, &stat_buf) < 0)
12311  return;
12312 
12313  /* remove leftover file from previously canceled backup if it exists */
12314  unlink(BACKUP_LABEL_OLD);
12315 
12317  {
12318  ereport(WARNING,
12320  errmsg("online backup mode was not canceled"),
12321  errdetail("File \"%s\" could not be renamed to \"%s\": %m.",
12323  return;
12324  }
12325 
12326  /* if the tablespace_map file is not there, return */
12327  if (stat(TABLESPACE_MAP, &stat_buf) < 0)
12328  {
12329  ereport(LOG,
12330  (errmsg("online backup mode canceled"),
12331  errdetail("File \"%s\" was renamed to \"%s\".",
12333  return;
12334  }
12335 
12336  /* remove leftover file from previously canceled backup if it exists */
12337  unlink(TABLESPACE_MAP_OLD);
12338 
12340  {
12341  ereport(LOG,
12342  (errmsg("online backup mode canceled"),
12343  errdetail("Files \"%s\" and \"%s\" were renamed to "
12344  "\"%s\" and \"%s\", respectively.",
12347  }
12348  else
12349  {
12350  ereport(WARNING,
12352  errmsg("online backup mode canceled"),
12353  errdetail("File \"%s\" was renamed to \"%s\", but "
12354  "file \"%s\" could not be renamed to \"%s\": %m.",
12357  }
12358 }
int errdetail(const char *fmt,...)
Definition: elog.c:1037
#define LOG
Definition: elog.h:25
#define WARNING
Definition: elog.h:30
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:699
#define TABLESPACE_MAP_OLD
Definition: xlog.h:363
#define TABLESPACE_MAP
Definition: xlog.h:362
#define BACKUP_LABEL_OLD
Definition: xlog.h:360

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().

◆ check_wal_buffers()

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

Definition at line 5138 of file xlog.c.

5139 {
5140  /*
5141  * -1 indicates a request for auto-tune.
5142  */
5143  if (*newval == -1)
5144  {
5145  /*
5146  * If we haven't yet changed the boot_val default of -1, just let it
5147  * be. We'll fix it when XLOGShmemSize is called.
5148  */
5149  if (XLOGbuffers == -1)
5150  return true;
5151 
5152  /* Otherwise, substitute the auto-tune value */
5154  }
5155 
5156  /*
5157  * We clamp manually-set values to at least 4 blocks. Prior to PostgreSQL
5158  * 9.1, a minimum of 4 was enforced by guc.c, but since that is no longer
5159  * the case, we just silently treat such values as a request for the
5160  * minimum. (We could throw an error instead, but that doesn't seem very
5161  * helpful.)
5162  */
5163  if (*newval < 4)
5164  *newval = 4;
5165 
5166  return true;
5167 }
static int XLOGChooseNumBuffers(void)
Definition: xlog.c:5122
int XLOGbuffers
Definition: xlog.c:98

References newval, XLOGbuffers, and XLOGChooseNumBuffers().

◆ CheckForStandbyTrigger()

static bool CheckForStandbyTrigger ( void  )
static

Definition at line 13158 of file xlog.c.

13159 {
13160  struct stat stat_buf;
13161 
13163  return true;
13164 
13166  {
13167  ereport(LOG, (errmsg("received promote request")));
13171  return true;
13172  }
13173 
13174  if (PromoteTriggerFile == NULL || strcmp(PromoteTriggerFile, "") == 0)
13175  return false;
13176 
13177  if (stat(PromoteTriggerFile, &stat_buf) == 0)
13178  {
13179  ereport(LOG,
13180  (errmsg("promote trigger file found: %s", PromoteTriggerFile)));
13181  unlink(PromoteTriggerFile);
13183  return true;
13184  }
13185  else if (errno != ENOENT)
13186  ereport(ERROR,
13188  errmsg("could not stat promote trigger file \"%s\": %m",
13189  PromoteTriggerFile)));
13190 
13191  return false;
13192 }
bool IsPromoteSignaled(void)
Definition: startup.c:296
void ResetPromoteSignaled(void)
Definition: startup.c:302
#define ERROR
Definition: elog.h:33
char * PromoteTriggerFile
Definition: xlog.c:285
bool CheckPromoteSignal(void)
Definition: xlog.c:13207
static bool LocalPromoteIsTriggered
Definition: xlog.c:232
static void SetPromoteIsTriggered(void)
Definition: xlog.c:13136
void RemovePromoteSignalFiles(void)
Definition: xlog.c:13198

References CheckPromoteSignal(), ereport, errcode_for_file_access(), errmsg(), ERROR, IsPromoteSignaled(), LocalPromoteIsTriggered, LOG, PromoteTriggerFile, RemovePromoteSignalFiles(), ResetPromoteSignaled(), SetPromoteIsTriggered(), and stat.

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

◆ CheckPointGuts()

static void CheckPointGuts ( XLogRecPtr  checkPointRedo,
int  flags 
)
static

Definition at line 9569 of file xlog.c.

9570 {
9576 
9577  /* Write out all dirty data in SLRUs and the main buffer pool */
9578  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_START(flags);
9580  CheckPointCLOG();
9585  CheckPointBuffers(flags);
9586 
9587  /* Perform all queued up fsyncs */
9588  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_SYNC_START();
9592  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_DONE();
9593 
9594  /* We deliberately delay 2PC checkpointing as long as possible */
9595  CheckPointTwoPhase(checkPointRedo);
9596 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1580
void CheckPointBuffers(int flags)
Definition: bufmgr.c:2724
void CheckPointCLOG(void)
Definition: clog.c:818
void CheckPointCommitTs(void)
Definition: commit_ts.c:792
void CheckPointMultiXact(void)
Definition: multixact.c:2155
void CheckPointReplicationOrigin(void)
Definition: origin.c:557
void CheckPointPredicate(void)
Definition: predicate.c:1069
void CheckPointRelationMap(void)
Definition: relmapper.c:546
void CheckPointLogicalRewriteHeap(void)
Definition: rewriteheap.c:1192
void CheckPointReplicationSlots(void)
Definition: slot.c:1360
void CheckPointSnapBuild(void)
Definition: snapbuild.c:1922
TimestampTz ckpt_write_t
Definition: xlog.h:217
TimestampTz ckpt_sync_end_t
Definition: xlog.h:219
TimestampTz ckpt_sync_t
Definition: xlog.h:218
void CheckPointSUBTRANS(void)
Definition: subtrans.c:284
void ProcessSyncRequests(void)
Definition: sync.c:281
void CheckPointTwoPhase(XLogRecPtr redo_horizon)
Definition: twophase.c:1759
CheckpointStatsData CheckpointStats
Definition: xlog.c:192

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

Referenced by CreateCheckPoint(), and CreateRestartPoint().

◆ CheckPromoteSignal()

bool CheckPromoteSignal ( void  )

Definition at line 13207 of file xlog.c.

13208 {
13209  struct stat stat_buf;
13210 
13211  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
13212  return true;
13213 
13214  return false;
13215 }
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:366

References PROMOTE_SIGNAL_FILE, and stat.

Referenced by CheckForStandbyTrigger(), and sigusr1_handler().

◆ CheckRecoveryConsistency()

static void CheckRecoveryConsistency ( void  )
static

Definition at line 8253 of file xlog.c.

8254 {
8255  XLogRecPtr lastReplayedEndRecPtr;
8256 
8257  /*
8258  * During crash recovery, we don't reach a consistent state until we've
8259  * replayed all the WAL.
8260  */
8262  return;
8263 
8265 
8266  /*
8267  * assume that we are called in the startup process, and hence don't need
8268  * a lock to read lastReplayedEndRecPtr
8269  */
8270  lastReplayedEndRecPtr = XLogCtl->lastReplayedEndRecPtr;
8271 
8272  /*
8273  * Have we reached the point where our base backup was completed?
8274  */
8276  ControlFile->backupEndPoint <= lastReplayedEndRecPtr)
8277  {
8278  /*
8279  * We have reached the end of base backup, as indicated by pg_control.
8280  * The data on disk is now consistent. Reset backupStartPoint and
8281  * backupEndPoint, and update minRecoveryPoint to make sure we don't
8282  * allow starting up at an earlier point even if recovery is stopped
8283  * and restarted soon after this.
8284  */
8285  elog(DEBUG1, "end of backup reached");
8286 
8287  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8288 
8289  if (ControlFile->minRecoveryPoint < lastReplayedEndRecPtr)
8290  ControlFile->minRecoveryPoint = lastReplayedEndRecPtr;
8291 
8294  ControlFile->backupEndRequired = false;
8296 
8297  LWLockRelease(ControlFileLock);
8298  }
8299 
8300  /*
8301  * Have we passed our safe starting point? Note that minRecoveryPoint is
8302  * known to be incorrectly set if ControlFile->backupEndRequired, until
8303  * the XLOG_BACKUP_END arrives to advise us of the correct
8304  * minRecoveryPoint. All we know prior to that is that we're not
8305  * consistent yet.
8306  */
8308  minRecoveryPoint <= lastReplayedEndRecPtr &&
8310  {
8311  /*
8312  * Check to see if the XLOG sequence contained any unresolved
8313  * references to uninitialized pages.
8314  */
8316 
8317  reachedConsistency = true;
8318  ereport(LOG,
8319  (errmsg("consistent recovery state reached at %X/%X",
8320  LSN_FORMAT_ARGS(lastReplayedEndRecPtr))));
8321  }
8322 
8323  /*
8324  * Have we got a valid starting snapshot that will allow queries to be
8325  * run? If so, we can tell postmaster that the database is consistent now,
8326  * enabling connections.
8327  */
8332  {
8336 
8337  LocalHotStandbyActive = true;
8338 
8340  }
8341 }
bool IsUnderPostmaster
Definition: globals.c:112
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:153
@ PMSIGNAL_BEGIN_HOT_STANDBY
Definition: pmsignal.h:36
XLogRecPtr backupStartPoint
Definition: pg_control.h:170
bool backupEndRequired
Definition: pg_control.h:172
XLogRecPtr backupEndPoint
Definition: pg_control.h:171
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:168
bool SharedHotStandbyActive
Definition: xlog.c:657
XLogRecPtr lastReplayedEndRecPtr
Definition: xlog.c:717
bool reachedConsistency
Definition: xlog.c:881
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:872
bool InArchiveRecovery
Definition: xlog.c:258
static bool LocalHotStandbyActive
Definition: xlog.c:226
void UpdateControlFile(void)
Definition: xlog.c:5053
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
HotStandbyState standbyState
Definition: xlogutils.c:55
void XLogCheckInvalidPages(void)
Definition: xlogutils.c:243
@ STANDBY_SNAPSHOT_READY
Definition: xlogutils.h:52

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

Referenced by ReadRecord(), and StartupXLOG().

◆ CheckRequiredParameterValues()

static void CheckRequiredParameterValues ( void  )
static

Definition at line 6637 of file xlog.c.

6638 {
6639  /*
6640  * For archive recovery, the WAL must be generated with at least 'replica'
6641  * wal_level.
6642  */
6644  {
6645  ereport(FATAL,
6646  (errmsg("WAL was generated with wal_level=minimal, cannot continue recovering"),
6647  errdetail("This happens if you temporarily set wal_level=minimal on the server."),
6648  errhint("Use a backup taken after setting wal_level to higher than minimal.")));
6649  }
6650 
6651  /*
6652  * For Hot Standby, the WAL must be generated with 'replica' mode, and we
6653  * must have at least as many backend slots as the primary.
6654  */
6656  {
6657  /* We ignore autovacuum_max_workers when we make this test. */
6658  RecoveryRequiresIntParameter("max_connections",
6661  RecoveryRequiresIntParameter("max_worker_processes",
6664  RecoveryRequiresIntParameter("max_wal_senders",
6667  RecoveryRequiresIntParameter("max_prepared_transactions",
6670  RecoveryRequiresIntParameter("max_locks_per_transaction",
6673  }
6674 }
int errhint(const char *fmt,...)
Definition: elog.c:1151
#define FATAL
Definition: elog.h:35
int MaxConnections
Definition: globals.c:136
int max_worker_processes
Definition: globals.c:137
int max_locks_per_xact
Definition: lock.c:55
int max_worker_processes
Definition: pg_control.h:181
int max_locks_per_xact
Definition: pg_control.h:184
int max_prepared_xacts
Definition: pg_control.h:183
int max_prepared_xacts
Definition: twophase.c:117
int max_wal_senders
Definition: walsender.c:121
bool EnableHotStandby
Definition: xlog.c:102
bool ArchiveRecoveryRequested
Definition: xlog.c:257
static void RecoveryRequiresIntParameter(const char *param_name, int currValue, int minValue)
Definition: xlog.c:6552
@ WAL_LEVEL_MINIMAL
Definition: xlog.h:121

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

Referenced by StartupXLOG(), and xlog_redo().

◆ checkTimeLineSwitch()

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

Definition at line 10256 of file xlog.c.

10258 {
10259  /* Check that the record agrees on what the current (old) timeline is */
10260  if (prevTLI != replayTLI)
10261  ereport(PANIC,
10262  (errmsg("unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record",
10263  prevTLI, replayTLI)));
10264 
10265  /*
10266  * The new timeline better be in the list of timelines we expect to see,
10267  * according to the timeline history. It should also not decrease.
10268  */
10269  if (newTLI < replayTLI || !tliInHistory(newTLI, expectedTLEs))
10270  ereport(PANIC,
10271  (errmsg("unexpected timeline ID %u (after %u) in checkpoint record",
10272  newTLI, replayTLI)));
10273 
10274  /*
10275  * If we have not yet reached min recovery point, and we're about to
10276  * switch to a timeline greater than the timeline of the min recovery
10277  * point: trouble. After switching to the new timeline, we could not
10278  * possibly visit the min recovery point on the correct timeline anymore.
10279  * This can happen if there is a newer timeline in the archive that
10280  * branched before the timeline the min recovery point is on, and you
10281  * attempt to do PITR to the new timeline.
10282  */
10284  lsn < minRecoveryPoint &&
10285  newTLI > minRecoveryPointTLI)
10286  ereport(PANIC,
10287  (errmsg("unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u",
10288  newTLI,
10291 
10292  /* Looks good */
10293 }
bool tliInHistory(TimeLineID tli, List *expectedTLEs)
Definition: timeline.c:534
static List * expectedTLEs
Definition: xlog.c:324
static TimeLineID minRecoveryPointTLI
Definition: xlog.c:873

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

Referenced by StartupXLOG().

◆ checkXLogConsistency()

static void checkXLogConsistency ( XLogReaderState record)
static

Definition at line 1452 of file xlog.c.

1453 {
1454  RmgrId rmid = XLogRecGetRmid(record);
1455  RelFileNode rnode;
1456  ForkNumber forknum;
1457  BlockNumber blkno;
1458  int block_id;
1459 
1460  /* Records with no backup blocks have no need for consistency checks. */
1461  if (!XLogRecHasAnyBlockRefs(record))
1462  return;
1463 
1464  Assert((XLogRecGetInfo(record) & XLR_CHECK_CONSISTENCY) != 0);
1465 
1466  for (block_id = 0; block_id <= record->max_block_id; block_id++)
1467  {
1468  Buffer buf;
1469  Page page;
1470 
1471  if (!XLogRecGetBlockTag(record, block_id, &rnode, &forknum, &blkno))
1472  {
1473  /*
1474  * WAL record doesn't contain a block reference with the given id.
1475  * Do nothing.
1476  */
1477  continue;
1478  }
1479 
1480  Assert(XLogRecHasBlockImage(record, block_id));
1481 
1482  if (XLogRecBlockImageApply(record, block_id))
1483  {
1484  /*
1485  * WAL record has already applied the page, so bypass the
1486  * consistency check as that would result in comparing the full
1487  * page stored in the record with itself.
1488  */
1489  continue;
1490  }
1491 
1492  /*
1493  * Read the contents from the current buffer and store it in a
1494  * temporary page.
1495  */
1496  buf = XLogReadBufferExtended(rnode, forknum, blkno,
1498  if (!BufferIsValid(buf))
1499  continue;
1500 
1502  page = BufferGetPage(buf);
1503 
1504  /*
1505  * Take a copy of the local page where WAL has been applied to have a
1506  * comparison base before masking it...
1507  */
1508  memcpy(replay_image_masked, page, BLCKSZ);
1509 
1510  /* No need for this page anymore now that a copy is in. */
1512 
1513  /*
1514  * If the block LSN is already ahead of this WAL record, we can't
1515  * expect contents to match. This can happen if recovery is
1516  * restarted.
1517  */
1518  if (PageGetLSN(replay_image_masked) > record->EndRecPtr)
1519  continue;
1520 
1521  /*
1522  * Read the contents from the backup copy, stored in WAL record and
1523  * store it in a temporary page. There is no need to allocate a new
1524  * page here, a local buffer is fine to hold its contents and a mask
1525  * can be directly applied on it.
1526  */
1527  if (!RestoreBlockImage(record, block_id, primary_image_masked))
1528  elog(ERROR, "failed to restore block image");
1529 
1530  /*
1531  * If masking function is defined, mask both the primary and replay
1532  * images
1533  */
1534  if (RmgrTable[rmid].rm_mask != NULL)
1535  {
1536  RmgrTable[rmid].rm_mask(replay_image_masked, blkno);
1537  RmgrTable[rmid].rm_mask(primary_image_masked, blkno);
1538  }
1539 
1540  /* Time to compare the primary and replay images. */
1541  if (memcmp(replay_image_masked, primary_image_masked, BLCKSZ) != 0)
1542  {
1543  elog(FATAL,
1544  "inconsistent page found, rel %u/%u/%u, forknum %u, blkno %u",
1545  rnode.spcNode, rnode.dbNode, rnode.relNode,
1546  forknum, blkno);
1547  }
1548  }
1549 }
uint32 BlockNumber
Definition: block.h:31
int Buffer
Definition: buf.h:23
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3780
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3996
#define BufferIsValid(bufnum)
Definition: bufmgr.h:123
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:98
@ RBM_NORMAL_NO_LOG
Definition: bufmgr.h:45
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
Pointer Page
Definition: bufpage.h:78
#define PageGetLSN(page)
Definition: bufpage.h:365
static char * buf
Definition: pg_test_fsync.c:70
ForkNumber
Definition: relpath.h:41
const RmgrData RmgrTable[RM_MAX_ID+1]
Definition: rmgr.c:36
uint8 RmgrId
Definition: rmgr.h:11
void(* rm_mask)(char *pagedata, BlockNumber blkno)
XLogRecPtr EndRecPtr
Definition: xlogreader.h:176
static char * primary_image_masked
Definition: xlog.c:265
static char * replay_image_masked
Definition: xlog.c:264
bool XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id, RelFileNode *rnode, ForkNumber *forknum, BlockNumber *blknum)
Definition: xlogreader.c:1531
bool RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page)
Definition: xlogreader.c:1584
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:315
#define XLogRecBlockImageApply(decoder, block_id)
Definition: xlogreader.h:327
#define XLogRecGetRmid(decoder)
Definition: xlogreader.h:316
#define XLogRecHasBlockImage(decoder, block_id)
Definition: xlogreader.h:325
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:322
#define XLR_CHECK_CONSISTENCY
Definition: xlogrecord.h:80
Buffer XLogReadBufferExtended(RelFileNode rnode, ForkNumber forknum, BlockNumber blkno, ReadBufferMode mode)
Definition: xlogutils.c:459

References Assert(), buf, BUFFER_LOCK_EXCLUSIVE, BufferGetPage, BufferIsValid, RelFileNode::dbNode, elog, XLogReaderState::EndRecPtr, ERROR, FATAL, LockBuffer(), XLogReaderState::max_block_id, PageGetLSN, primary_image_masked, 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().

◆ CheckXLogRemoved()

void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)

Definition at line 4055 of file xlog.c.

4056 {
4057  int save_errno = errno;
4058  XLogSegNo lastRemovedSegNo;
4059 
4061  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
4063 
4064  if (segno <= lastRemovedSegNo)
4065  {
4066  char filename[MAXFNAMELEN];
4067 
4068  XLogFileName(filename, tli, segno, wal_segment_size);
4069  errno = save_errno;
4070  ereport(ERROR,
4072  errmsg("requested WAL segment %s has already been removed",
4073  filename)));
4074  }
4075  errno = save_errno;
4076 }
static char * filename
Definition: pg_dumpall.c:92
XLogSegNo lastRemovedSegNo
Definition: xlog.c:599
uint64 XLogSegNo
Definition: xlogdefs.h:48

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

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

◆ CleanupAfterArchiveRecovery()

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

Definition at line 5802 of file xlog.c.

5804 {
5805  /*
5806  * Execute the recovery_end_command, if any.
5807  */
5808  if (recoveryEndCommand && strcmp(recoveryEndCommand, "") != 0)
5810  "recovery_end_command",
5811  true,
5813 
5814  /*
5815  * We switched to a new timeline. Clean up segments on the old timeline.
5816  *
5817  * If there are any higher-numbered segments on the old timeline, remove
5818  * them. They might contain valid WAL, but they might also be pre-allocated
5819  * files containing garbage. In any case, they are not part of the new
5820  * timeline's history so we don't need them.
5821  */
5822  RemoveNonParentXlogFiles(EndOfLog, newTLI);
5823 
5824  /*
5825  * If the switch happened in the middle of a segment, what to do with the
5826  * last, partial segment on the old timeline? If we don't archive it, and
5827  * the server that created the WAL never archives it either (e.g. because it
5828  * was hit by a meteor), it will never make it to the archive. That's OK
5829  * from our point of view, because the new segment that we created with the
5830  * new TLI contains all the WAL from the old timeline up to the switch
5831  * point. But if you later try to do PITR to the "missing" WAL on the old
5832  * timeline, recovery won't find it in the archive. It's physically present
5833  * in the new file with new TLI, but recovery won't look there when it's
5834  * recovering to the older timeline. On the other hand, if we archive the
5835  * partial segment, and the original server on that timeline is still
5836  * running and archives the completed version of the same segment later, it
5837  * will fail. (We used to do that in 9.4 and below, and it caused such
5838  * problems).
5839  *
5840  * As a compromise, we rename the last segment with the .partial suffix, and
5841  * archive it. Archive recovery will never try to read .partial segments, so
5842  * they will normally go unused. But in the odd PITR case, the administrator
5843  * can copy them manually to the pg_wal directory (removing the suffix).
5844  * They can be useful in debugging, too.
5845  *
5846  * If a .done or .ready file already exists for the old timeline, however,
5847  * we had already determined that the segment is complete, so we can let it
5848  * be archived normally. (In particular, if it was restored from the archive
5849  * to begin with, it's expected to have a .done file).
5850  */
5851  if (XLogSegmentOffset(EndOfLog, wal_segment_size) != 0 &&
5853  {
5854  char origfname[MAXFNAMELEN];
5855  XLogSegNo endLogSegNo;
5856 
5857  XLByteToPrevSeg(EndOfLog, endLogSegNo, wal_segment_size);
5858  XLogFileName(origfname, EndOfLogTLI, endLogSegNo, wal_segment_size);
5859 
5860  if (!XLogArchiveIsReadyOrDone(origfname))
5861  {
5862  char origpath[MAXPGPATH];
5863  char partialfname[MAXFNAMELEN];
5864  char partialpath[MAXPGPATH];
5865 
5866  XLogFilePath(origpath, EndOfLogTLI, endLogSegNo, wal_segment_size);
5867  snprintf(partialfname, MAXFNAMELEN, "%s.partial", origfname);
5868  snprintf(partialpath, MAXPGPATH, "%s.partial", origpath);
5869 
5870  /*
5871  * Make sure there's no .done or .ready file for the .partial
5872  * file.
5873  */
5874  XLogArchiveCleanup(partialfname);
5875 
5876  durable_rename(origpath, partialpath, ERROR);
5877  XLogArchiveNotify(partialfname);
5878  }
5879  }
5880 }
#define MAXPGPATH
#define snprintf
Definition: port.h:225
@ WAIT_EVENT_RECOVERY_END_COMMAND
Definition: wait_event.h:123
static void RemoveNonParentXlogFiles(XLogRecPtr switchpoint, TimeLineID newTLI)
Definition: xlog.c:4231
char * recoveryEndCommand
Definition: xlog.c:269
#define XLogArchivingActive()
Definition: xlog.h:153
#define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes)
#define XLogFilePath(path, tli, logSegNo, wal_segsz_bytes)
bool XLogArchiveIsReadyOrDone(const char *xlog)
Definition: xlogarchive.c:694
void ExecuteRecoveryCommand(const char *command, const char *commandName, bool failOnSignal, uint32 wait_event_info)
Definition: xlogarchive.c:290
void XLogArchiveNotify(const char *xlog)
Definition: xlogarchive.c:474
void XLogArchiveCleanup(const char *xlog)
Definition: xlogarchive.c:742

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

Referenced by StartupXLOG().

◆ CleanupBackupHistory()

static void CleanupBackupHistory ( void  )
static

Definition at line 4429 of file xlog.c.

4430 {
4431  DIR *xldir;
4432  struct dirent *xlde;
4433  char path[MAXPGPATH + sizeof(XLOGDIR)];
4434 
4435  xldir = AllocateDir(XLOGDIR);
4436 
4437  while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
4438  {
4439  if (IsBackupHistoryFileName(xlde->d_name))
4440  {
4441  if (XLogArchiveCheckDone(xlde->d_name))
4442  {
4443  elog(DEBUG2, "removing WAL backup history file \"%s\"",
4444  xlde->d_name);
4445  snprintf(path, sizeof(path), XLOGDIR "/%s", xlde->d_name);
4446  unlink(path);
4447  XLogArchiveCleanup(xlde->d_name);
4448  }
4449  }
4450  }
4451 
4452  FreeDir(xldir);
4453 }
#define DEBUG2
Definition: elog.h:23
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2788
int FreeDir(DIR *dir)
Definition: fd.c:2840
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2722
Definition: dirent.c:26
Definition: dirent.h:10
char d_name[MAX_PATH]
Definition: dirent.h:15
#define XLOGDIR
#define IsBackupHistoryFileName(fname)
bool XLogArchiveCheckDone(const char *xlog)
Definition: xlogarchive.c:595

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

Referenced by do_pg_stop_backup().

◆ ConfirmRecoveryPaused()

static void ConfirmRecoveryPaused ( void  )
static

Definition at line 6360 of file xlog.c.

6361 {
6362  /* If recovery pause is requested then set it paused */
6367 }
RecoveryPauseState recoveryPauseState
Definition: xlog.c:730
@ RECOVERY_PAUSED
Definition: xlog.h:147
@ RECOVERY_PAUSE_REQUESTED
Definition: xlog.h:146

References XLogCtlData::info_lck, RECOVERY_PAUSE_REQUESTED, RECOVERY_PAUSED, XLogCtlData::recoveryPauseState, SpinLockAcquire, SpinLockRelease, and XLogCtl.

Referenced by recoveryPausesHere(), and RecoveryRequiresIntParameter().

◆ CopyXLogRecordToWAL()

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

Definition at line 1556 of file xlog.c.

1558 {
1559  char *currpos;
1560  int freespace;
1561  int written;
1562  XLogRecPtr CurrPos;
1563  XLogPageHeader pagehdr;
1564 
1565  /*
1566  * Get a pointer to the right place in the right WAL buffer to start
1567  * inserting to.
1568  */
1569  CurrPos = StartPos;
1570  currpos = GetXLogBuffer(CurrPos, tli);
1571  freespace = INSERT_FREESPACE(CurrPos);
1572 
1573  /*
1574  * there should be enough space for at least the first field (xl_tot_len)
1575  * on this page.
1576  */
1577  Assert(freespace >= sizeof(uint32));
1578 
1579  /* Copy record data */
1580  written = 0;
1581  while (rdata != NULL)
1582  {
1583  char *rdata_data = rdata->data;
1584  int rdata_len = rdata->len;
1585 
1586  while (rdata_len > freespace)
1587  {
1588  /*
1589  * Write what fits on this page, and continue on the next page.
1590  */
1591  Assert(CurrPos % XLOG_BLCKSZ >= SizeOfXLogShortPHD || freespace == 0);
1592  memcpy(currpos, rdata_data, freespace);
1593  rdata_data += freespace;
1594  rdata_len -= freespace;
1595  written += freespace;
1596  CurrPos += freespace;
1597 
1598  /*
1599  * Get pointer to beginning of next page, and set the xlp_rem_len
1600  * in the page header. Set XLP_FIRST_IS_CONTRECORD.
1601  *
1602  * It's safe to set the contrecord flag and xlp_rem_len without a
1603  * lock on the page. All the other flags were already set when the
1604  * page was initialized, in AdvanceXLInsertBuffer, and we're the
1605  * only backend that needs to set the contrecord flag.
1606  */
1607  currpos = GetXLogBuffer(CurrPos, tli);
1608  pagehdr = (XLogPageHeader) currpos;
1609  pagehdr->xlp_rem_len = write_len - written;
1610  pagehdr->xlp_info |= XLP_FIRST_IS_CONTRECORD;
1611 
1612  /* skip over the page header */
1613  if (XLogSegmentOffset(CurrPos, wal_segment_size) == 0)
1614  {
1615  CurrPos += SizeOfXLogLongPHD;
1616  currpos += SizeOfXLogLongPHD;
1617  }
1618  else
1619  {
1620  CurrPos += SizeOfXLogShortPHD;
1621  currpos += SizeOfXLogShortPHD;
1622  }
1623  freespace = INSERT_FREESPACE(CurrPos);
1624  }
1625 
1626  Assert(CurrPos % XLOG_BLCKSZ >= SizeOfXLogShortPHD || rdata_len == 0);
1627  memcpy(currpos, rdata_data, rdata_len);
1628  currpos += rdata_len;
1629  CurrPos += rdata_len;
1630  freespace -= rdata_len;
1631  written += rdata_len;
1632 
1633  rdata = rdata->next;
1634  }
1635  Assert(written == write_len);
1636 
1637  /*
1638  * If this was an xlog-switch, it's not enough to write the switch record,
1639  * we also have to consume all the remaining space in the WAL segment. We
1640  * have already reserved that space, but we need to actually fill it.
1641  */
1642  if (isLogSwitch && XLogSegmentOffset(CurrPos, wal_segment_size) != 0)
1643  {
1644  /* An xlog-switch record doesn't contain any data besides the header */
1645  Assert(write_len == SizeOfXLogRecord);
1646 
1647  /* Assert that we did reserve the right amount of space */
1648  Assert(XLogSegmentOffset(EndPos, wal_segment_size) == 0);
1649 
1650  /* Use up all the remaining space on the current page */
1651  CurrPos += freespace;
1652 
1653  /*
1654  * Cause all remaining pages in the segment to be flushed, leaving the
1655  * XLog position where it should be, at the start of the next segment.
1656  * We do this one page at a time, to make sure we don't deadlock
1657  * against ourselves if wal_buffers < wal_segment_size.
1658  */
1659  while (CurrPos < EndPos)
1660  {
1661  /*
1662  * The minimal action to flush the page would be to call
1663  * WALInsertLockUpdateInsertingAt(CurrPos) followed by
1664  * AdvanceXLInsertBuffer(...). The page would be left initialized
1665  * mostly to zeros, except for the page header (always the short
1666  * variant, as this is never a segment's first page).
1667  *
1668  * The large vistas of zeros are good for compressibility, but the
1669  * headers interrupting them every XLOG_BLCKSZ (with values that
1670  * differ from page to page) are not. The effect varies with
1671  * compression tool, but bzip2 for instance compresses about an
1672  * order of magnitude worse if those headers are left in place.
1673  *
1674  * Rather than complicating AdvanceXLInsertBuffer itself (which is
1675  * called in heavily-loaded circumstances as well as this lightly-
1676  * loaded one) with variant behavior, we just use GetXLogBuffer
1677  * (which itself calls the two methods we need) to get the pointer
1678  * and zero most of the page. Then we just zero the page header.
1679  */
1680  currpos = GetXLogBuffer(CurrPos, tli);
1681  MemSet(currpos, 0, SizeOfXLogShortPHD);
1682 
1683  CurrPos += XLOG_BLCKSZ;
1684  }
1685  }
1686  else
1687  {
1688  /* Align the end position, so that the next record starts aligned */
1689  CurrPos = MAXALIGN64(CurrPos);
1690  }
1691 
1692  if (CurrPos != EndPos)
1693  elog(PANIC, "space reserved for WAL record does not match what was written");
1694 }
unsigned int uint32
Definition: c.h:441
#define MAXALIGN64(LEN)
Definition: c.h:782
struct XLogRecData * next
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:756
static char * GetXLogBuffer(XLogRecPtr ptr, TimeLineID tli)
Definition: xlog.c:1932
#define XLP_FIRST_IS_CONTRECORD
Definition: xlog_internal.h:74
#define SizeOfXLogShortPHD
Definition: xlog_internal.h:52

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().

◆ CreateCheckPoint()

void CreateCheckPoint ( int  flags)

Definition at line 9065 of file xlog.c.

9066 {
9067  bool shutdown;
9068  CheckPoint checkPoint;
9069  XLogRecPtr recptr;
9070  XLogSegNo _logSegNo;
9072  uint32 freespace;
9073  XLogRecPtr PriorRedoPtr;
9074  XLogRecPtr curInsert;
9075  XLogRecPtr last_important_lsn;
9076  VirtualTransactionId *vxids;
9077  int nvxids;
9078  int oldXLogAllowed = 0;
9079 
9080  /*
9081  * An end-of-recovery checkpoint is really a shutdown checkpoint, just
9082  * issued at a different time.
9083  */
9085  shutdown = true;
9086  else
9087  shutdown = false;
9088 
9089  /* sanity check */
9090  if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
9091  elog(ERROR, "can't create a checkpoint during recovery");
9092 
9093  /*
9094  * Prepare to accumulate statistics.
9095  *
9096  * Note: because it is possible for log_checkpoints to change while a
9097  * checkpoint proceeds, we always accumulate stats, even if
9098  * log_checkpoints is currently off.
9099  */
9100  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
9102 
9103  /*
9104  * Use a critical section to force system panic if we have trouble.
9105  */
9107 
9108  if (shutdown)
9109  {
9110  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9113  LWLockRelease(ControlFileLock);
9114  }
9115 
9116  /*
9117  * Let smgr prepare for checkpoint; this has to happen before we determine
9118  * the REDO pointer. Note that smgr must not do anything that'd have to
9119  * be undone if we decide no checkpoint is needed.
9120  */
9122 
9123  /* Begin filling in the checkpoint WAL record */
9124  MemSet(&checkPoint, 0, sizeof(checkPoint));
9125  checkPoint.time = (pg_time_t) time(NULL);
9126 
9127  /*
9128  * For Hot Standby, derive the oldestActiveXid before we fix the redo
9129  * pointer. This allows us to begin accumulating changes to assemble our
9130  * starting snapshot of locks and transactions.
9131  */
9132  if (!shutdown && XLogStandbyInfoActive())
9134  else
9136 
9137  /*
9138  * Get location of last important record before acquiring insert locks (as
9139  * GetLastImportantRecPtr() also locks WAL locks).
9140  */
9141  last_important_lsn = GetLastImportantRecPtr();
9142 
9143  /*
9144  * We must block concurrent insertions while examining insert state to
9145  * determine the checkpoint REDO pointer.
9146  */
9148  curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
9149 
9150  /*
9151  * If this isn't a shutdown or forced checkpoint, and if there has been no
9152  * WAL activity requiring a checkpoint, skip it. The idea here is to
9153  * avoid inserting duplicate checkpoints when the system is idle.
9154  */
9156  CHECKPOINT_FORCE)) == 0)
9157  {
9158  if (last_important_lsn == ControlFile->checkPoint)
9159  {
9161  END_CRIT_SECTION();
9162  ereport(DEBUG1,
9163  (errmsg_internal("checkpoint skipped because system is idle")));
9164  return;
9165  }
9166  }
9167 
9168  /*
9169  * An end-of-recovery checkpoint is created before anyone is allowed to
9170  * write WAL. To allow us to write the checkpoint record, temporarily
9171  * enable XLogInsertAllowed.
9172  */
9173  if (flags & CHECKPOINT_END_OF_RECOVERY)
9174  oldXLogAllowed = LocalSetXLogInsertAllowed();
9175 
9176  checkPoint.ThisTimeLineID = XLogCtl->InsertTimeLineID;
9177  if (flags & CHECKPOINT_END_OF_RECOVERY)
9178  checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
9179  else
9180  checkPoint.PrevTimeLineID = checkPoint.ThisTimeLineID;
9181 
9182  checkPoint.fullPageWrites = Insert->fullPageWrites;
9183 
9184  /*
9185  * Compute new REDO record ptr = location of next XLOG record.
9186  *
9187  * NB: this is NOT necessarily where the checkpoint record itself will be,
9188  * since other backends may insert more XLOG records while we're off doing
9189  * the buffer flush work. Those XLOG records are logically after the
9190  * checkpoint, even though physically before it. Got that?
9191  */
9192  freespace = INSERT_FREESPACE(curInsert);
9193  if (freespace == 0)
9194  {
9195  if (XLogSegmentOffset(curInsert, wal_segment_size) == 0)
9196  curInsert += SizeOfXLogLongPHD;
9197  else
9198  curInsert += SizeOfXLogShortPHD;
9199  }
9200  checkPoint.redo = curInsert;
9201 
9202  /*
9203  * Here we update the shared RedoRecPtr for future XLogInsert calls; this
9204  * must be done while holding all the insertion locks.
9205  *
9206  * Note: if we fail to complete the checkpoint, RedoRecPtr will be left
9207  * pointing past where it really needs to point. This is okay; the only
9208  * consequence is that XLogInsert might back up whole buffers that it
9209  * didn't really need to. We can't postpone advancing RedoRecPtr because
9210  * XLogInserts that happen while we are dumping buffers must assume that
9211  * their buffer changes are not included in the checkpoint.
9212  */
9213  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
9214 
9215  /*
9216  * Now we can release the WAL insertion locks, allowing other xacts to
9217  * proceed while we are flushing disk buffers.
9218  */
9220 
9221  /* Update the info_lck-protected copy of RedoRecPtr as well */
9223  XLogCtl->RedoRecPtr = checkPoint.redo;
9225 
9226  /*
9227  * If enabled, log checkpoint start. We postpone this until now so as not
9228  * to log anything if we decided to skip the checkpoint.
9229  */
9230  if (log_checkpoints)
9231  LogCheckpointStart(flags, false);
9232 
9233  /* Update the process title */
9234  update_checkpoint_display(flags, false, false);
9235 
9236  TRACE_POSTGRESQL_CHECKPOINT_START(flags);
9237 
9238  /*
9239  * Get the other info we need for the checkpoint record.
9240  *
9241  * We don't need to save oldestClogXid in the checkpoint, it only matters
9242  * for the short period in which clog is being truncated, and if we crash
9243  * during that we'll redo the clog truncation and fix up oldestClogXid
9244  * there.
9245  */
9246  LWLockAcquire(XidGenLock, LW_SHARED);
9247  checkPoint.nextXid = ShmemVariableCache->nextXid;
9248  checkPoint.oldestXid = ShmemVariableCache->oldestXid;
9250  LWLockRelease(XidGenLock);
9251 
9252  LWLockAcquire(CommitTsLock, LW_SHARED);
9255  LWLockRelease(CommitTsLock);
9256 
9257  LWLockAcquire(OidGenLock, LW_SHARED);
9258  checkPoint.nextOid = ShmemVariableCache->nextOid;
9259  if (!shutdown)
9260  checkPoint.nextOid += ShmemVariableCache->oidCount;
9261  LWLockRelease(OidGenLock);
9262 
9263  MultiXactGetCheckptMulti(shutdown,
9264  &checkPoint.nextMulti,
9265  &checkPoint.nextMultiOffset,
9266  &checkPoint.oldestMulti,
9267  &checkPoint.oldestMultiDB);
9268 
9269  /*
9270  * Having constructed the checkpoint record, ensure all shmem disk buffers
9271  * and commit-log buffers are flushed to disk.
9272  *
9273  * This I/O could fail for various reasons. If so, we will fail to
9274  * complete the checkpoint, but there is no reason to force a system
9275  * panic. Accordingly, exit critical section while doing it.
9276  */
9277  END_CRIT_SECTION();
9278 
9279  /*
9280  * In some cases there are groups of actions that must all occur on one
9281  * side or the other of a checkpoint record. Before flushing the
9282  * checkpoint record we must explicitly wait for any backend currently
9283  * performing those groups of actions.
9284  *
9285  * One example is end of transaction, so we must wait for any transactions
9286  * that are currently in commit critical sections. If an xact inserted
9287  * its commit record into XLOG just before the REDO point, then a crash
9288  * restart from the REDO point would not replay that record, which means
9289  * that our flushing had better include the xact's update of pg_xact. So
9290  * we wait till he's out of his commit critical section before proceeding.
9291  * See notes in RecordTransactionCommit().
9292  *
9293  * Because we've already released the insertion locks, this test is a bit
9294  * fuzzy: it is possible that we will wait for xacts we didn't really need
9295  * to wait for. But the delay should be short and it seems better to make
9296  * checkpoint take a bit longer than to hold off insertions longer than
9297  * necessary. (In fact, the whole reason we have this issue is that xact.c
9298  * does commit record XLOG insertion and clog update as two separate steps
9299  * protected by different locks, but again that seems best on grounds of
9300  * minimizing lock contention.)
9301  *
9302  * A transaction that has not yet set delayChkpt when we look cannot be at
9303  * risk, since he's not inserted his commit record yet; and one that's
9304  * already cleared it is not at risk either, since he's done fixing clog
9305  * and we will correctly flush the update below. So we cannot miss any
9306  * xacts we need to wait for.
9307  */
9308  vxids = GetVirtualXIDsDelayingChkpt(&nvxids);
9309  if (nvxids > 0)
9310  {
9311  do
9312  {
9313  pg_usleep(10000L); /* wait for 10 msec */
9314  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids));
9315  }
9316  pfree(vxids);
9317 
9318  CheckPointGuts(checkPoint.redo, flags);
9319 
9320  /*
9321  * Take a snapshot of running transactions and write this to WAL. This
9322  * allows us to reconstruct the state of running transactions during
9323  * archive recovery, if required. Skip, if this info disabled.
9324  *
9325  * If we are shutting down, or Startup process is completing crash
9326  * recovery we don't need to write running xact data.
9327  */
9328  if (!shutdown && XLogStandbyInfoActive())
9330 
9332 
9333  /*
9334  * Now insert the checkpoint record into XLOG.
9335  */
9336  XLogBeginInsert();
9337  XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));
9338  recptr = XLogInsert(RM_XLOG_ID,
9339  shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
9341 
9342  XLogFlush(recptr);
9343 
9344  /*
9345  * We mustn't write any new WAL after a shutdown checkpoint, or it will be
9346  * overwritten at next startup. No-one should even try, this just allows
9347  * sanity-checking. In the case of an end-of-recovery checkpoint, we want
9348  * to just temporarily disable writing until the system has exited
9349  * recovery.
9350  */
9351  if (shutdown)
9352  {
9353  if (flags & CHECKPOINT_END_OF_RECOVERY)
9354  LocalXLogInsertAllowed = oldXLogAllowed;
9355  else
9356  LocalXLogInsertAllowed = 0; /* never again write WAL */
9357  }
9358 
9359  /*
9360  * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
9361  * = end of actual checkpoint record.
9362  */
9363  if (shutdown && checkPoint.redo != ProcLastRecPtr)
9364  ereport(PANIC,
9365  (errmsg("concurrent write-ahead log activity while database system is shutting down")));
9366 
9367  /*
9368  * Remember the prior checkpoint's redo ptr for
9369  * UpdateCheckPointDistanceEstimate()
9370  */
9371  PriorRedoPtr = ControlFile->checkPointCopy.redo;
9372 
9373  /*
9374  * Update the control file.
9375  */
9376  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9377  if (shutdown)
9380  ControlFile->checkPointCopy = checkPoint;
9381  /* crash recovery should always recover to the end of WAL */
9384 
9385  /*
9386  * Persist unloggedLSN value. It's reset on crash recovery, so this goes
9387  * unused on non-shutdown checkpoints, but seems useful to store it always
9388  * for debugging purposes.
9389  */
9393 
9395  LWLockRelease(ControlFileLock);
9396 
9397  /* Update shared-memory copy of checkpoint XID/epoch */
9399  XLogCtl->ckptFullXid = checkPoint.nextXid;
9401 
9402  /*
9403  * We are now done with critical updates; no need for system panic if we
9404  * have trouble while fooling with old log segments.
9405  */
9406  END_CRIT_SECTION();
9407 
9408  /*
9409  * Let smgr do post-checkpoint cleanup (eg, deleting old files).
9410  */
9412 
9413  /*
9414  * Update the average distance between checkpoints if the prior checkpoint
9415  * exists.
9416  */
9417  if (PriorRedoPtr != InvalidXLogRecPtr)
9419 
9420  /*
9421  * Delete old log files, those no longer needed for last checkpoint to
9422  * prevent the disk holding the xlog from growing full.
9423  */
9425  KeepLogSeg(recptr, &_logSegNo);
9426  if (InvalidateObsoleteReplicationSlots(_logSegNo))
9427  {
9428  /*
9429  * Some slots have been invalidated; recalculate the old-segment
9430  * horizon, starting again from RedoRecPtr.
9431  */
9433  KeepLogSeg(recptr, &_logSegNo);
9434  }
9435  _logSegNo--;
9436  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr,
9437  checkPoint.ThisTimeLineID);
9438 
9439  /*
9440  * Make more log segments if needed. (Do this after recycling old log
9441  * segments, since that may supply some of the needed files.)
9442  */
9443  if (!shutdown)
9444  PreallocXlogFiles(recptr, checkPoint.ThisTimeLineID);
9445 
9446  /*
9447  * Truncate pg_subtrans if possible. We can throw away all data before
9448  * the oldest XMIN of any running transaction. No future transaction will
9449  * attempt to reference any pg_subtrans entry older than that (see Asserts
9450  * in subtrans.c). During recovery, though, we mustn't do this because
9451  * StartupSUBTRANS hasn't been called yet.
9452  */
9453  if (!RecoveryInProgress())
9455 
9456  /* Real work is done; log and update stats. */
9457  LogCheckpointEnd(false);
9458 
9459  /* Reset the process title */
9460  update_checkpoint_display(flags, false, true);
9461 
9462  TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
9463  NBuffers,
9467 }
int errmsg_internal(const char *fmt,...)
Definition: elog.c:991
int NBuffers
Definition: globals.c:135
@ LW_SHARED
Definition: lwlock.h:105
#define START_CRIT_SECTION()
Definition: miscadmin.h:147
#define END_CRIT_SECTION()
Definition: miscadmin.h:149
void MultiXactGetCheckptMulti(bool is_shutdown, MultiXactId *nextMulti, MultiXactOffset *nextMultiOffset, MultiXactId *oldestMulti, Oid *oldestMultiDB)
Definition: multixact.c:2133
@ DB_SHUTDOWNING
Definition: pg_control.h:92
@ DB_SHUTDOWNED
Definition: pg_control.h:90
#define XLOG_CHECKPOINT_ONLINE
Definition: pg_control.h:68
TransactionId GetOldestActiveTransactionId(void)
Definition: procarray.c:2895
TransactionId GetOldestTransactionIdConsideredRunning(void)
Definition: procarray.c:2034
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids)
Definition: procarray.c:3100
VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids)
Definition: procarray.c:3056
void pg_usleep(long microsec)
Definition: signal.c:53
bool InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno)
Definition: slot.c:1317
XLogRecPtr LogStandbySnapshot(void)
Definition: standby.c:1222
TimestampTz ckpt_start_t
Definition: xlog.h:216
int ckpt_segs_removed
Definition: xlog.h:225
int ckpt_segs_added
Definition: xlog.h:224
int ckpt_bufs_written
Definition: xlog.h:222
int ckpt_segs_recycled
Definition: xlog.h:226
XLogRecPtr unloggedLSN
Definition: pg_control.h:135
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:169
TransactionId newestCommitTsXid
Definition: transam.h:233
TransactionId oldestXid
Definition: transam.h:222
TransactionId oldestCommitTsXid
Definition: transam.h:232
FullTransactionId ckptFullXid
Definition: xlog.c:595
TimeLineID InsertTimeLineID
Definition: xlog.c:644
slock_t ulsn_lck
Definition: xlog.c:603
XLogRecPtr RedoRecPtr
Definition: xlog.c:594
XLogRecPtr unloggedLSN
Definition: xlog.c:602
TimeLineID PrevTimeLineID
Definition: xlog.c:645
XLogRecPtr RedoRecPtr
Definition: xlog.c:563
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:338
void SyncPreCheckpoint(void)
Definition: sync.c:181
void SyncPostCheckpoint(void)
Definition: sync.c:196
XLogRecPtr ProcLastRecPtr
Definition: xlog.c:342
bool RecoveryInProgress(void)
Definition: xlog.c:8404
static void WALInsertLockRelease(void)
Definition: xlog.c:1774
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:2043
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1745
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr, TimeLineID insertTLI)
Definition: xlog.c:4156
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8846
static XLogRecPtr RedoRecPtr
Definition: xlog.c:362
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8878
static void PreallocXlogFiles(XLogRecPtr endptr, TimeLineID tli)
Definition: xlog.c:4018
bool log_checkpoints
Definition: xlog.c:110
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9991
static int LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8533
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:8753
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8970
static int LocalXLogInsertAllowed
Definition: xlog.c:244
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2924
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:9569
static void update_checkpoint_display(int flags, bool restartpoint, bool reset)
Definition: xlog.c:9008
#define CHECKPOINT_END_OF_RECOVERY
Definition: xlog.h:195
#define CHECKPOINT_FORCE
Definition: xlog.h:197
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:194
#define XLogStandbyInfoActive()
Definition: xlog.h:178
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:429
void XLogBeginInsert(void)
Definition: xloginsert.c:136
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:337

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

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

◆ CreateEndOfRecoveryRecord()

static void CreateEndOfRecoveryRecord ( void  )
static

Definition at line 9478 of file xlog.c.

9479 {
9480  xl_end_of_recovery xlrec;
9481  XLogRecPtr recptr;
9482 
9483  /* sanity check */
9484  if (!RecoveryInProgress())
9485  elog(ERROR, "can only be used to end recovery");
9486 
9487  xlrec.end_time = GetCurrentTimestamp();
9488 
9493 
9495 
9496  XLogBeginInsert();
9497  XLogRegisterData((char *) &xlrec, sizeof(xl_end_of_recovery));
9498  recptr = XLogInsert(RM_XLOG_ID, XLOG_END_OF_RECOVERY);
9499 
9500  XLogFlush(recptr);
9501 
9502  /*
9503  * Update the control file so that crash recovery can follow the timeline
9504  * changes to this point.
9505  */
9506  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9507  ControlFile->minRecoveryPoint = recptr;
9508  ControlFile->minRecoveryPointTLI = xlrec.ThisTimeLineID;
9510  LWLockRelease(ControlFileLock);
9511 
9512  END_CRIT_SECTION();
9513 }
#define XLOG_END_OF_RECOVERY
Definition: pg_control.h:76
TimeLineID PrevTimeLineID
TimestampTz end_time
TimeLineID ThisTimeLineID

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

Referenced by PerformRecoveryXLogAction().

◆ CreateOverwriteContrecordRecord()

static XLogRecPtr CreateOverwriteContrecordRecord ( XLogRecPtr  aborted_lsn)
static

Definition at line 9536 of file xlog.c.

9537 {
9539  XLogRecPtr recptr;
9540 
9541  /* sanity check */
9542  if (!RecoveryInProgress())
9543  elog(ERROR, "can only be used at end of recovery");
9544 
9545  xlrec.overwritten_lsn = aborted_lsn;
9547 
9549 
9550  XLogBeginInsert();
9551  XLogRegisterData((char *) &xlrec, sizeof(xl_overwrite_contrecord));
9552 
9553  recptr = XLogInsert(RM_XLOG_ID, XLOG_OVERWRITE_CONTRECORD);
9554 
9555  XLogFlush(recptr);
9556 
9557  END_CRIT_SECTION();
9558 
9559  return recptr;
9560 }
#define XLOG_OVERWRITE_CONTRECORD
Definition: pg_control.h:80

References elog, END_CRIT_SECTION, ERROR, GetCurrentTimestamp(), xl_overwrite_contrecord::overwrite_time, xl_overwrite_contrecord::overwritten_lsn, RecoveryInProgress(), START_CRIT_SECTION, XLOG_OVERWRITE_CONTRECORD, XLogBeginInsert(), XLogFlush(), XLogInsert(), and XLogRegisterData().

Referenced by StartupXLOG().

◆ CreateRestartPoint()

bool CreateRestartPoint ( int  flags)

Definition at line 9650 of file xlog.c.

9651 {
9652  XLogRecPtr lastCheckPointRecPtr;
9653  XLogRecPtr lastCheckPointEndPtr;
9654  CheckPoint lastCheckPoint;
9655  XLogRecPtr PriorRedoPtr;
9656  XLogRecPtr receivePtr;
9657  XLogRecPtr replayPtr;
9658  TimeLineID replayTLI;
9659  XLogRecPtr endptr;
9660  XLogSegNo _logSegNo;
9661  TimestampTz xtime;
9662 
9663  /* Get a local copy of the last safe checkpoint record. */
9665  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
9666  lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
9667  lastCheckPoint = XLogCtl->lastCheckPoint;
9669 
9670  /*
9671  * Check that we're still in recovery mode. It's ok if we exit recovery
9672  * mode after this check, the restart point is valid anyway.
9673  */
9674  if (!RecoveryInProgress())
9675  {
9676  ereport(DEBUG2,
9677  (errmsg_internal("skipping restartpoint, recovery has already ended")));
9678  return false;
9679  }
9680 
9681  /*
9682  * If the last checkpoint record we've replayed is already our last
9683  * restartpoint, we can't perform a new restart point. We still update
9684  * minRecoveryPoint in that case, so that if this is a shutdown restart
9685  * point, we won't start up earlier than before. That's not strictly
9686  * necessary, but when hot standby is enabled, it would be rather weird if
9687  * the database opened up for read-only connections at a point-in-time
9688  * before the last shutdown. Such time travel is still possible in case of
9689  * immediate shutdown, though.
9690  *
9691  * We don't explicitly advance minRecoveryPoint when we do create a
9692  * restartpoint. It's assumed that flushing the buffers will do that as a
9693  * side-effect.
9694  */
9695  if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
9696  lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
9697  {
9698  ereport(DEBUG2,
9699  (errmsg_internal("skipping restartpoint, already performed at %X/%X",
9700  LSN_FORMAT_ARGS(lastCheckPoint.redo))));
9701 
9703  if (flags & CHECKPOINT_IS_SHUTDOWN)
9704  {
9705  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9708  LWLockRelease(ControlFileLock);
9709  }
9710  return false;
9711  }
9712 
9713  /*
9714  * Update the shared RedoRecPtr so that the startup process can calculate
9715  * the number of segments replayed since last restartpoint, and request a
9716  * restartpoint if it exceeds CheckPointSegments.
9717  *
9718  * Like in CreateCheckPoint(), hold off insertions to update it, although
9719  * during recovery this is just pro forma, because no WAL insertions are
9720  * happening.
9721  */
9723  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
9725 
9726  /* Also update the info_lck-protected copy */
9728  XLogCtl->RedoRecPtr = lastCheckPoint.redo;
9730 
9731  /*
9732  * Prepare to accumulate statistics.
9733  *
9734  * Note: because it is possible for log_checkpoints to change while a
9735  * checkpoint proceeds, we always accumulate stats, even if
9736  * log_checkpoints is currently off.
9737  */
9738  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
9740 
9741  if (log_checkpoints)
9742  LogCheckpointStart(flags, true);
9743 
9744  /* Update the process title */
9745  update_checkpoint_display(flags, true, false);
9746 
9747  CheckPointGuts(lastCheckPoint.redo, flags);
9748 
9749  /*
9750  * Remember the prior checkpoint's redo ptr for
9751  * UpdateCheckPointDistanceEstimate()
9752  */
9753  PriorRedoPtr = ControlFile->checkPointCopy.redo;
9754 
9755  /*
9756  * Update pg_control, using current time. Check that it still shows
9757  * DB_IN_ARCHIVE_RECOVERY state and an older checkpoint, else do nothing;
9758  * this is a quick hack to make sure nothing really bad happens if somehow
9759  * we get here after the end-of-recovery checkpoint.
9760  */
9761  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9763  ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
9764  {
9765  ControlFile->checkPoint = lastCheckPointRecPtr;
9766  ControlFile->checkPointCopy = lastCheckPoint;
9767 
9768  /*
9769  * Ensure minRecoveryPoint is past the checkpoint record. Normally,
9770  * this will have happened already while writing out dirty buffers,
9771  * but not necessarily - e.g. because no buffers were dirtied. We do
9772  * this because a non-exclusive base backup uses minRecoveryPoint to
9773  * determine which WAL files must be included in the backup, and the
9774  * file (or files) containing the checkpoint record must be included,
9775  * at a minimum. Note that for an ordinary restart of recovery there's
9776  * no value in having the minimum recovery point any earlier than this
9777  * anyway, because redo will begin just after the checkpoint record.
9778  */
9779  if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
9780  {
9781  ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
9783 
9784  /* update local copy */
9787  }
9788  if (flags & CHECKPOINT_IS_SHUTDOWN)
9791  }
9792  LWLockRelease(ControlFileLock);
9793 
9794  /*
9795  * Update the average distance between checkpoints/restartpoints if the
9796  * prior checkpoint exists.
9797  */
9798  if (PriorRedoPtr != InvalidXLogRecPtr)
9800 
9801  /*
9802  * Delete old log files, those no longer needed for last restartpoint to
9803  * prevent the disk holding the xlog from growing full.
9804  */
9806 
9807  /*
9808  * Retreat _logSegNo using the current end of xlog replayed or received,
9809  * whichever is later.
9810  */
9811  receivePtr = GetWalRcvFlushRecPtr(NULL, NULL);
9812  replayPtr = GetXLogReplayRecPtr(&replayTLI);
9813  endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
9814  KeepLogSeg(endptr, &_logSegNo);
9815  if (InvalidateObsoleteReplicationSlots(_logSegNo))
9816  {
9817  /*
9818  * Some slots have been invalidated; recalculate the old-segment
9819  * horizon, starting again from RedoRecPtr.
9820  */
9822  KeepLogSeg(endptr, &_logSegNo);
9823  }
9824  _logSegNo--;
9825 
9826  /*
9827  * Try to recycle segments on a useful timeline. If we've been promoted
9828  * since the beginning of this restartpoint, use the new timeline chosen
9829  * at end of recovery. If we're still in recovery, use the timeline we're
9830  * currently replaying.
9831  *
9832  * There is no guarantee that the WAL segments will be useful on the
9833  * current timeline; if recovery proceeds to a new timeline right after
9834  * this, the pre-allocated WAL segments on this timeline will not be used,
9835  * and will go wasted until recycled on the next restartpoint. We'll live
9836  * with that.
9837  */
9838  if (!RecoveryInProgress())
9839  replayTLI = XLogCtl->InsertTimeLineID;
9840 
9841  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr, replayTLI);
9842 
9843  /*
9844  * Make more log segments if needed. (Do this after recycling old log
9845  * segments, since that may supply some of the needed files.)
9846  */
9847  PreallocXlogFiles(endptr, replayTLI);
9848 
9849  /*
9850  * Truncate pg_subtrans if possible. We can throw away all data before
9851  * the oldest XMIN of any running transaction. No future transaction will
9852  * attempt to reference any pg_subtrans entry older than that (see Asserts
9853  * in subtrans.c). When hot standby is disabled, though, we mustn't do
9854  * this because StartupSUBTRANS hasn't been called yet.
9855  */
9856  if (EnableHotStandby)
9858 
9859  /* Real work is done; log and update stats. */
9860  LogCheckpointEnd(true);
9861 
9862  /* Reset the process title */
9863  update_checkpoint_display(flags, true, true);
9864 
9865  xtime = GetLatestXTime();
9867  (errmsg("recovery restart point at %X/%X",
9868  LSN_FORMAT_ARGS(lastCheckPoint.redo)),
9869  xtime ? errdetail("Last completed transaction was at log time %s.",
9870  timestamptz_to_str(xtime)) : 0));
9871 
9872  /*
9873  * Finally, execute archive_cleanup_command, if any.
9874  */
9875  if (archiveCleanupCommand && strcmp(archiveCleanupCommand, "") != 0)
9877  "archive_cleanup_command",
9878  false,
9880 
9881  return true;
9882 }
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1774
int64 TimestampTz
Definition: timestamp.h:39
@ DB_IN_ARCHIVE_RECOVERY
Definition: pg_control.h:94
@ DB_SHUTDOWNED_IN_RECOVERY
Definition: pg_control.h:91
CheckPoint lastCheckPoint
Definition: xlog.c:709
XLogRecPtr lastCheckPointRecPtr
Definition: xlog.c:707
XLogRecPtr lastCheckPointEndPtr
Definition: xlog.c:708
@ WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND
Definition: wait_event.h:83
XLogRecPtr GetWalRcvFlushRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI)
char * archiveCleanupCommand
Definition: xlog.c:270
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
Definition: xlog.c:11966
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition: xlog.c:2840
TimestampTz GetLatestXTime(void)
Definition: xlog.c:6489
uint32 TimeLineID
Definition: xlogdefs.h:59

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

Referenced by CheckpointerMain(), and ShutdownXLOG().

◆ DataChecksumsEnabled()

◆ do_pg_abort_backup()

void do_pg_abort_backup ( int  code,
Datum  arg 
)

Definition at line 11918 of file xlog.c.

11919 {
11920  bool emit_warning = DatumGetBool(arg);
11921 
11922  /*
11923  * Quick exit if session is not keeping around a non-exclusive backup
11924  * already started.
11925  */
11927  return;
11928 
11932 
11935  {
11936  XLogCtl->Insert.forcePageWrites = false;
11937  }
11939 
11940  if (emit_warning)
11941  ereport(WARNING,
11942  (errmsg("aborting backup due to backend exiting before pg_stop_backup was called")));
11943 }
void * arg
#define DatumGetBool(X)
Definition: postgres.h:437
bool forcePageWrites
Definition: xlog.c:564
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:575
int nonExclusiveBackups
Definition: xlog.c:576
static SessionBackupState sessionBackupState
Definition: xlog.c:524
@ SESSION_BACKUP_NON_EXCLUSIVE
Definition: xlog.h:344

References arg, Assert(), DatumGetBool, ereport, errmsg(), EXCLUSIVE_BACKUP_NONE, XLogCtlInsert::exclusiveBackupState, XLogCtlInsert::forcePageWrites, XLogCtlData::Insert, XLogCtlInsert::nonExclusiveBackups, SESSION_BACKUP_NON_EXCLUSIVE, sessionBackupState, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), WARNING, and XLogCtl.

Referenced by perform_base_backup(), and register_persistent_abort_backup_handler().

◆ do_pg_start_backup()

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

Definition at line 10980 of file xlog.c.

10983 {
10984  bool exclusive = (labelfile == NULL);
10985  bool backup_started_in_recovery = false;
10986  XLogRecPtr checkpointloc;
10987  XLogRecPtr startpoint;
10988  TimeLineID starttli;
10989  pg_time_t stamp_time;
10990  char strfbuf[128];
10991  char xlogfilename[MAXFNAMELEN];
10992  XLogSegNo _logSegNo;
10993  struct stat stat_buf;
10994  FILE *fp;
10995 
10997 
10998  /*
10999  * Currently only non-exclusive backup can be taken during recovery.
11000  */
11001  if (backup_started_in_recovery && exclusive)
11002  ereport(ERROR,
11003  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11004  errmsg("recovery is in progress"),
11005  errhint("WAL control functions cannot be executed during recovery.")));
11006 
11007  /*
11008  * During recovery, we don't need to check WAL level. Because, if WAL
11009  * level is not sufficient, it's impossible to get here during recovery.
11010  */
11012  ereport(ERROR,
11013  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11014  errmsg("WAL level not sufficient for making an online backup"),
11015  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
11016 
11017  if (strlen(backupidstr) > MAXPGPATH)
11018  ereport(ERROR,
11019  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
11020  errmsg("backup label too long (max %d bytes)",
11021  MAXPGPATH)));
11022 
11023  /*
11024  * Mark backup active in shared memory. We must do full-page WAL writes
11025  * during an on-line backup even if not doing so at other times, because
11026  * it's quite possible for the backup dump to obtain a "torn" (partially
11027  * written) copy of a database page if it reads the page concurrently with
11028  * our write to the same page. This can be fixed as long as the first
11029  * write to the page in the WAL sequence is a full-page write. Hence, we
11030  * turn on forcePageWrites and then force a CHECKPOINT, to ensure there
11031  * are no dirty pages in shared memory that might get dumped while the
11032  * backup is in progress without having a corresponding WAL record. (Once
11033  * the backup is complete, we need not force full-page writes anymore,
11034  * since we expect that any pages not modified during the backup interval
11035  * must have been correctly captured by the backup.)
11036  *
11037  * Note that forcePageWrites has no effect during an online backup from
11038  * the standby.
11039  *
11040  * We must hold all the insertion locks to change the value of
11041  * forcePageWrites, to ensure adequate interlocking against
11042  * XLogInsertRecord().
11043  */
11045  if (exclusive)
11046  {
11047  /*
11048  * At first, mark that we're now starting an exclusive backup, to
11049  * ensure that there are no other sessions currently running
11050  * pg_start_backup() or pg_stop_backup().
11051  */
11053  {
11055  ereport(ERROR,
11056  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11057  errmsg("a backup is already in progress"),
11058  errhint("Run pg_stop_backup() and try again.")));
11059  }
11061  }
11062  else
11064  XLogCtl->Insert.forcePageWrites = true;
11066 
11067  /* Ensure we release forcePageWrites if fail below */
11069  {
11070  bool gotUniqueStartpoint = false;
11071  DIR *tblspcdir;
11072  struct dirent *de;
11073  tablespaceinfo *ti;
11074  int datadirpathlen;
11075 
11076  /*
11077  * Force an XLOG file switch before the checkpoint, to ensure that the
11078  * WAL segment the checkpoint is written to doesn't contain pages with
11079  * old timeline IDs. That would otherwise happen if you called
11080  * pg_start_backup() right after restoring from a PITR archive: the
11081  * first WAL segment containing the startup checkpoint has pages in
11082  * the beginning with the old timeline ID. That can cause trouble at
11083  * recovery: we won't have a history file covering the old timeline if
11084  * pg_wal directory was not included in the base backup and the WAL
11085  * archive was cleared too before starting the backup.
11086  *
11087  * This also ensures that we have emitted a WAL page header that has
11088  * XLP_BKP_REMOVABLE off before we emit the checkpoint record.
11089  * Therefore, if a WAL archiver (such as pglesslog) is trying to
11090  * compress out removable backup blocks, it won't remove any that
11091  * occur after this point.
11092  *
11093  * During recovery, we skip forcing XLOG file switch, which means that
11094  * the backup taken during recovery is not available for the special
11095  * recovery case described above.
11096  */
11098  RequestXLogSwitch(false);
11099 
11100  do
11101  {
11102  bool checkpointfpw;
11103 
11104  /*
11105  * Force a CHECKPOINT. Aside from being necessary to prevent torn
11106  * page problems, this guarantees that two successive backup runs
11107  * will have different checkpoint positions and hence different
11108  * history file names, even if nothing happened in between.
11109  *
11110  * During recovery, establish a restartpoint if possible. We use
11111  * the last restartpoint as the backup starting checkpoint. This
11112  * means that two successive backup runs can have same checkpoint
11113  * positions.
11114  *
11115  * Since the fact that we are executing do_pg_start_backup()
11116  * during recovery means that checkpointer is running, we can use
11117  * RequestCheckpoint() to establish a restartpoint.
11118  *
11119  * We use CHECKPOINT_IMMEDIATE only if requested by user (via
11120  * passing fast = true). Otherwise this can take awhile.
11121  */
11123  (fast ? CHECKPOINT_IMMEDIATE : 0));
11124 
11125  /*
11126  * Now we need to fetch the checkpoint record location, and also
11127  * its REDO pointer. The oldest point in WAL that would be needed
11128  * to restore starting from the checkpoint is precisely the REDO
11129  * pointer.
11130  */
11131  LWLockAcquire(ControlFileLock, LW_SHARED);
11132  checkpointloc = ControlFile->checkPoint;
11133  startpoint = ControlFile->checkPointCopy.redo;
11135  checkpointfpw = ControlFile->checkPointCopy.fullPageWrites;
11136  LWLockRelease(ControlFileLock);
11137 
11139  {
11140  XLogRecPtr recptr;
11141 
11142  /*
11143  * Check to see if all WAL replayed during online backup
11144  * (i.e., since last restartpoint used as backup starting
11145  * checkpoint) contain full-page writes.
11146  */
11148  recptr = XLogCtl->lastFpwDisableRecPtr;
11150 
11151  if (!checkpointfpw || startpoint <= recptr)
11152  ereport(ERROR,
11153  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11154  errmsg("WAL generated with full_page_writes=off was replayed "
11155  "since last restartpoint"),
11156  errhint("This means that the backup being taken on the standby "
11157  "is corrupt and should not be used. "
11158  "Enable full_page_writes and run CHECKPOINT on the primary, "
11159  "and then try an online backup again.")));
11160 
11161  /*
11162  * During recovery, since we don't use the end-of-backup WAL
11163  * record and don't write the backup history file, the
11164  * starting WAL location doesn't need to be unique. This means
11165  * that two base backups started at the same time might use
11166  * the same checkpoint as starting locations.
11167  */
11168  gotUniqueStartpoint = true;
11169  }
11170 
11171  /*
11172  * If two base backups are started at the same time (in WAL sender
11173  * processes), we need to make sure that they use different
11174  * checkpoints as starting locations, because we use the starting
11175  * WAL location as a unique identifier for the base backup in the
11176  * end-of-backup WAL record and when we write the backup history
11177  * file. Perhaps it would be better generate a separate unique ID
11178  * for each backup instead of forcing another checkpoint, but
11179  * taking a checkpoint right after another is not that expensive
11180  * either because only few buffers have been dirtied yet.
11181  */
11183  if (XLogCtl->Insert.lastBackupStart < startpoint)
11184  {
11185  XLogCtl->Insert.lastBackupStart = startpoint;
11186  gotUniqueStartpoint = true;
11187  }
11189  } while (!gotUniqueStartpoint);
11190 
11191  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
11192  XLogFileName(xlogfilename, starttli, _logSegNo, wal_segment_size);
11193 
11194  /*
11195  * Construct tablespace_map file. If caller isn't interested in this,
11196  * we make a local StringInfo.
11197  */
11198  if (tblspcmapfile == NULL)
11199  tblspcmapfile = makeStringInfo();
11200 
11201  datadirpathlen = strlen(DataDir);
11202 
11203  /* Collect information about all tablespaces */
11204  tblspcdir = AllocateDir("pg_tblspc");
11205  while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL)
11206  {
11207  char fullpath[MAXPGPATH + 10];
11208  char linkpath[MAXPGPATH];
11209  char *relpath = NULL;
11210  int rllen;
11211  StringInfoData escapedpath;
11212  char *s;
11213 
11214  /* Skip anything that doesn't look like a tablespace */
11215  if (strspn(de->d_name, "0123456789") != strlen(de->d_name))
11216  continue;
11217 
11218  snprintf(fullpath, sizeof(fullpath), "pg_tblspc/%s", de->d_name);
11219 
11220 #if defined(HAVE_READLINK) || defined(WIN32)
11221  rllen = readlink(fullpath, linkpath, sizeof(linkpath));
11222  if (rllen < 0)
11223  {
11224  ereport(WARNING,
11225  (errmsg("could not read symbolic link \"%s\": %m",
11226  fullpath)));
11227  continue;
11228  }
11229  else if (rllen >= sizeof(linkpath))
11230  {
11231  ereport(WARNING,
11232  (errmsg("symbolic link \"%s\" target is too long",
11233  fullpath)));
11234  continue;
11235  }
11236  linkpath[rllen] = '\0';
11237 
11238  /*
11239  * Build a backslash-escaped version of the link path to include
11240  * in the tablespace map file.
11241  */
11242  initStringInfo(&escapedpath);
11243  for (s = linkpath; *s; s++)
11244  {
11245  if (*s == '\n' || *s == '\r' || *s == '\\')
11246  appendStringInfoChar(&escapedpath, '\\');
11247  appendStringInfoChar(&escapedpath, *s);
11248  }
11249 
11250  /*
11251  * Relpath holds the relative path of the tablespace directory
11252  * when it's located within PGDATA, or NULL if it's located
11253  * elsewhere.
11254  */
11255  if (rllen > datadirpathlen &&
11256  strncmp(linkpath, DataDir, datadirpathlen) == 0 &&
11257  IS_DIR_SEP(linkpath[datadirpathlen]))
11258  relpath = linkpath + datadirpathlen + 1;
11259 
11260  ti = palloc(sizeof(tablespaceinfo));
11261  ti->oid = pstrdup(de->d_name);
11262  ti->path = pstrdup(linkpath);
11263  ti->rpath = relpath ? pstrdup(relpath) : NULL;
11264  ti->size = -1;
11265 
11266  if (tablespaces)
11267  *tablespaces = lappend(*tablespaces, ti);
11268 
11269  appendStringInfo(tblspcmapfile, "%s %s\n",
11270  ti->oid, escapedpath.data);
11271 
11272  pfree(escapedpath.data);
11273 #else
11274 
11275  /*
11276  * If the platform does not have symbolic links, it should not be
11277  * possible to have tablespaces - clearly somebody else created
11278  * them. Warn about it and ignore.
11279  */
11280  ereport(WARNING,
11281  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
11282  errmsg("tablespaces are not supported on this platform")));
11283 #endif
11284  }
11285  FreeDir(tblspcdir);
11286 
11287  /*
11288  * Construct backup label file. If caller isn't interested in this,
11289  * we make a local StringInfo.
11290  */
11291  if (labelfile == NULL)
11292  labelfile = makeStringInfo();
11293 
11294  /* Use the log timezone here, not the session timezone */
11295  stamp_time = (pg_time_t) time(NULL);
11296  pg_strftime(strfbuf, sizeof(strfbuf),
11297  "%Y-%m-%d %H:%M:%S %Z",
11298  pg_localtime(&stamp_time, log_timezone));
11299  appendStringInfo(labelfile, "START WAL LOCATION: %X/%X (file %s)\n",
11300  LSN_FORMAT_ARGS(startpoint), xlogfilename);
11301  appendStringInfo(labelfile, "CHECKPOINT LOCATION: %X/%X\n",
11302  LSN_FORMAT_ARGS(checkpointloc));
11303  appendStringInfo(labelfile, "BACKUP METHOD: %s\n",
11304  exclusive ? "pg_start_backup" : "streamed");
11305  appendStringInfo(labelfile, "BACKUP FROM: %s\n",
11306  backup_started_in_recovery ? "standby" : "primary");
11307  appendStringInfo(labelfile, "START TIME: %s\n", strfbuf);
11308  appendStringInfo(labelfile, "LABEL: %s\n", backupidstr);
11309  appendStringInfo(labelfile, "START TIMELINE: %u\n", starttli);
11310 
11311  /*
11312  * Okay, write the file, or return its contents to caller.
11313  */
11314  if (exclusive)
11315  {
11316  /*
11317  * Check for existing backup label --- implies a backup is already
11318  * running. (XXX given that we checked exclusiveBackupState
11319  * above, maybe it would be OK to just unlink any such label
11320  * file?)
11321  */
11322  if (stat(BACKUP_LABEL_FILE, &stat_buf) != 0)
11323  {
11324  if (errno != ENOENT)
11325  ereport(ERROR,
11327  errmsg("could not stat file \"%s\": %m",
11328  BACKUP_LABEL_FILE)));
11329  }
11330  else
11331  ereport(ERROR,
11332  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11333  errmsg("a backup is already in progress"),
11334  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
11335  BACKUP_LABEL_FILE)));
11336 
11337  fp = AllocateFile(BACKUP_LABEL_FILE, "w");
11338 
11339  if (!fp)
11340  ereport(ERROR,
11342  errmsg("could not create file \"%s\": %m",
11343  BACKUP_LABEL_FILE)));
11344  if (fwrite(labelfile->data, labelfile->len, 1, fp) != 1 ||
11345  fflush(fp) != 0 ||
11346  pg_fsync(fileno(fp)) != 0 ||
11347  ferror(fp) ||
11348  FreeFile(fp))
11349  ereport(ERROR,
11351  errmsg("could not write file \"%s\": %m",
11352  BACKUP_LABEL_FILE)));
11353  /* Allocated locally for exclusive backups, so free separately */
11354  pfree(labelfile->data);
11355  pfree(labelfile);
11356 
11357  /* Write backup tablespace_map file. */
11358  if (tblspcmapfile->len > 0)
11359  {
11360  if (stat(TABLESPACE_MAP, &stat_buf) != 0)
11361  {
11362  if (errno != ENOENT)
11363  ereport(ERROR,
11365  errmsg("could not stat file \"%s\": %m",
11366  TABLESPACE_MAP)));
11367  }
11368  else
11369  ereport(ERROR,
11370  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11371  errmsg("a backup is already in progress"),
11372  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
11373  TABLESPACE_MAP)));
11374 
11375  fp = AllocateFile(TABLESPACE_MAP, "w");
11376 
11377  if (!fp)
11378  ereport(ERROR,
11380  errmsg("could not create file \"%s\": %m",
11381  TABLESPACE_MAP)));
11382  if (fwrite(tblspcmapfile->data, tblspcmapfile->len, 1, fp) != 1 ||
11383  fflush(fp) != 0 ||
11384  pg_fsync(fileno(fp)) != 0 ||
11385  ferror(fp) ||
11386  FreeFile(fp))
11387  ereport(ERROR,
11389  errmsg("could not write file \"%s\": %m",
11390  TABLESPACE_MAP)));
11391  }
11392 
11393  /* Allocated locally for exclusive backups, so free separately */
11394  pfree(tblspcmapfile->data);
11395  pfree(tblspcmapfile);
11396  }
11397  }
11399 
11400  /*
11401  * Mark that start phase has correctly finished for an exclusive backup.
11402  * Session-level locks are updated as well to reflect that state.
11403  *
11404  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating backup
11405  * counters and session-level lock. Otherwise they can be updated
11406  * inconsistently, and which might cause do_pg_abort_backup() to fail.
11407  */
11408  if (exclusive)
11409  {
11412 
11413  /* Set session-level lock */
11416  }
11417  else
11419 
11420  /*
11421  * We're done. As a convenience, return the starting WAL location.
11422  */
11423  if (starttli_p)
11424  *starttli_p = starttli;
11425  return startpoint;
11426 }
static bool backup_started_in_recovery
Definition: basebackup.c:93
void RequestCheckpoint(int flags)
Definition: checkpointer.c:920
int errcode(int sqlerrcode)
Definition: elog.c:693
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2461
int FreeFile(FILE *file)
Definition: fd.c:2660
char * DataDir
Definition: globals.c:65
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:47
#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:52
static void const char fflush(stdout)
List * lappend(List *list, void *datum)
Definition: list.c:336
char * pstrdup(const char *in)
Definition: mcxt.c:1299
pg_tz * log_timezone
Definition: pgtz.c:31
size_t pg_strftime(char *s, size_t max, const char *format, const struct pg_tm *tm)
Definition: strftime.c:128
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1342
#define IS_DIR_SEP(ch)
Definition: port.h:87
uintptr_t Datum
Definition: postgres.h:411
#define BoolGetDatum(X)
Definition: postgres.h:446
#define relpath(rnode, forknum)
Definition: relpath.h:87
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:737
XLogRecPtr lastBackupStart
Definition: xlog.c:577
char * rpath
Definition: basebackup.h:32
#define readlink(path, buf, size)
Definition: win32_port.h:236
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:10084
static void pg_start_backup_callback(int code, Datum arg)
Definition: xlog.c:11430
@ SESSION_BACKUP_EXCLUSIVE
Definition: xlog.h:343
#define CHECKPOINT_WAIT
Definition: xlog.h:200
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:196
#define XLogIsNeeded()
Definition: xlog.h:164

References AllocateDir(), AllocateFile(), appendStringInfo(), appendStringInfoChar(), BACKUP_LABEL_FILE, backup_started_in_recovery, BoolGetDatum, ControlFileData::checkPoint, CHECKPOINT_FORCE, CHECKPOINT_IMMEDIATE, CHECKPOINT_WAIT, ControlFileData::checkPointCopy, ControlFile, 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, fflush(), XLogCtlInsert::forcePageWrites, FreeDir(), FreeFile(), CheckPoint::fullPageWrites, XLogCtlData::info_lck, initStringInfo(), XLogCtlData::Insert, IS_DIR_SEP, lappend(), XLogCtlInsert::lastBackupStart, XLogCtlData::lastFpwDisableRecPtr, StringInfoData::len, log_timezone, LSN_FORMAT_ARGS, 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, 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, XLogCtl, XLogFileName, and XLogIsNeeded.

Referenced by perform_base_backup(), and pg_start_backup().

◆ do_pg_stop_backup()

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

Definition at line 11498 of file xlog.c.

11499 {
11500  bool exclusive = (labelfile == NULL);
11501  bool backup_started_in_recovery = false;
11502  XLogRecPtr startpoint;
11503  XLogRecPtr stoppoint;
11504  TimeLineID stoptli;
11505  pg_time_t stamp_time;
11506  char strfbuf[128];
11507  char histfilepath[MAXPGPATH];
11508  char startxlogfilename[MAXFNAMELEN];
11509  char stopxlogfilename[MAXFNAMELEN];
11510  char lastxlogfilename[MAXFNAMELEN];
11511  char histfilename[MAXFNAMELEN];
11512  char backupfrom[20];
11513  XLogSegNo _logSegNo;
11514  FILE *lfp;
11515  FILE *fp;
11516  char ch;
11517  int seconds_before_warning;
11518  int waits = 0;
11519  bool reported_waiting = false;
11520  char *remaining;
11521  char *ptr;
11522  uint32 hi,
11523  lo;
11524 
11526 
11527  /*
11528  * Currently only non-exclusive backup can be taken during recovery.
11529  */
11530  if (backup_started_in_recovery && exclusive)
11531  ereport(ERROR,
11532  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11533  errmsg("recovery is in progress"),
11534  errhint("WAL control functions cannot be executed during recovery.")));
11535 
11536  /*
11537  * During recovery, we don't need to check WAL level. Because, if WAL
11538  * level is not sufficient, it's impossible to get here during recovery.
11539  */
11541  ereport(ERROR,
11542  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11543  errmsg("WAL level not sufficient for making an online backup"),
11544  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
11545 
11546  if (exclusive)
11547  {
11548  /*
11549  * At first, mark that we're now stopping an exclusive backup, to
11550  * ensure that there are no other sessions currently running
11551  * pg_start_backup() or pg_stop_backup().
11552  */
11555  {
11557  ereport(ERROR,
11558  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11559  errmsg("exclusive backup not in progress")));
11560  }
11563 
11564  /*
11565  * Remove backup_label. In case of failure, the state for an exclusive
11566  * backup is switched back to in-progress.
11567  */
11569  {
11570  /*
11571  * Read the existing label file into memory.
11572  */
11573  struct stat statbuf;
11574  int r;
11575 
11576  if (stat(BACKUP_LABEL_FILE, &statbuf))
11577  {
11578  /* should not happen per the upper checks */
11579  if (errno != ENOENT)
11580  ereport(ERROR,
11582  errmsg("could not stat file \"%s\": %m",
11583  BACKUP_LABEL_FILE)));
11584  ereport(ERROR,
11585  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11586  errmsg("a backup is not in progress")));
11587  }
11588 
11589  lfp = AllocateFile(BACKUP_LABEL_FILE, "r");
11590  if (!lfp)
11591  {
11592  ereport(ERROR,
11594  errmsg("could not read file \"%s\": %m",
11595  BACKUP_LABEL_FILE)));
11596  }
11597  labelfile = palloc(statbuf.st_size + 1);
11598  r = fread(labelfile, statbuf.st_size, 1, lfp);
11599  labelfile[statbuf.st_size] = '\0';
11600 
11601  /*
11602  * Close and remove the backup label file
11603  */
11604  if (r != 1 || ferror(lfp) || FreeFile(lfp))
11605  ereport(ERROR,
11607  errmsg("could not read file \"%s\": %m",
11608  BACKUP_LABEL_FILE)));
11610 
11611  /*
11612  * Remove tablespace_map file if present, it is created only if
11613  * there are tablespaces.
11614  */
11616  }
11618  }
11619 
11620  /*
11621  * OK to update backup counters, forcePageWrites and session-level lock.
11622  *
11623  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating them.
11624  * Otherwise they can be updated inconsistently, and which might cause
11625  * do_pg_abort_backup() to fail.
11626  */
11628  if (exclusive)
11629  {
11631  }
11632  else
11633  {
11634  /*
11635  * The user-visible pg_start/stop_backup() functions that operate on
11636  * exclusive backups can be called at any time, but for non-exclusive
11637  * backups, it is expected that each do_pg_start_backup() call is
11638  * matched by exactly one do_pg_stop_backup() call.
11639  */
11642  }
11643 
11646  {
11647  XLogCtl->Insert.forcePageWrites = false;
11648  }
11649 
11650  /*
11651  * Clean up session-level lock.
11652  *
11653  * You might think that WALInsertLockRelease() can be called before
11654  * cleaning up session-level lock because session-level lock doesn't need
11655  * to be protected with WAL insertion lock. But since
11656  * CHECK_FOR_INTERRUPTS() can occur in it, session-level lock must be
11657  * cleaned up before it.
11658  */
11660 
11662 
11663  /*
11664  * Read and parse the START WAL LOCATION line (this code is pretty crude,
11665  * but we are not expecting any variability in the file format).
11666  */
11667  if (sscanf(labelfile, "START WAL LOCATION: %X/%X (file %24s)%c",
11668  &hi, &lo, startxlogfilename,
11669  &ch) != 4 || ch != '\n')
11670  ereport(ERROR,
11671  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11672  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
11673  startpoint = ((uint64) hi) << 32 | lo;
11674  remaining = strchr(labelfile, '\n') + 1; /* %n is not portable enough */
11675 
11676  /*
11677  * Parse the BACKUP FROM line. If we are taking an online backup from the
11678  * standby, we confirm that the standby has not been promoted during the
11679  * backup.
11680  */
11681  ptr = strstr(remaining, "BACKUP FROM:");
11682  if (!ptr || sscanf(ptr, "BACKUP FROM: %19s\n", backupfrom) != 1)
11683  ereport(ERROR,
11684  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11685  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
11686  if (strcmp(backupfrom, "standby") == 0 && !backup_started_in_recovery)
11687  ereport(ERROR,
11688  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11689  errmsg("the standby was promoted during online backup"),
11690  errhint("This means that the backup being taken is corrupt "
11691  "and should not be used. "
11692  "Try taking another online backup.")));
11693 
11694  /*
11695  * During recovery, we don't write an end-of-backup record. We assume that
11696  * pg_control was backed up last and its minimum recovery point can be
11697  * available as the backup end location. Since we don't have an
11698  * end-of-backup record, we use the pg_control value to check whether
11699  * we've reached the end of backup when starting recovery from this
11700  * backup. We have no way of checking if pg_control wasn't backed up last
11701  * however.
11702  *
11703  * We don't force a switch to new WAL file but it is still possible to
11704  * wait for all the required files to be archived if waitforarchive is
11705  * true. This is okay if we use the backup to start a standby and fetch
11706  * the missing WAL using streaming replication. But in the case of an
11707  * archive recovery, a user should set waitforarchive to true and wait for
11708  * them to be archived to ensure that all the required files are
11709  * available.
11710  *
11711  * We return the current minimum recovery point as the backup end
11712  * location. Note that it can be greater than the exact backup end
11713  * location if the minimum recovery point is updated after the backup of
11714  * pg_control. This is harmless for current uses.
11715  *
11716  * XXX currently a backup history file is for informational and debug
11717  * purposes only. It's not essential for an online backup. Furthermore,
11718  * even if it's created, it will not be archived during recovery because
11719  * an archiver is not invoked. So it doesn't seem worthwhile to write a
11720  * backup history file during recovery.
11721  */
11723  {
11724  XLogRecPtr recptr;
11725 
11726  /*
11727  * Check to see if all WAL replayed during online backup contain
11728  * full-page writes.
11729  */
11731  recptr = XLogCtl->lastFpwDisableRecPtr;
11733 
11734  if (startpoint <= recptr)
11735  ereport(ERROR,
11736  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11737  errmsg("WAL generated with full_page_writes=off was replayed "
11738  "during online backup"),
11739  errhint("This means that the backup being taken on the standby "
11740  "is corrupt and should not be used. "
11741  "Enable full_page_writes and run CHECKPOINT on the primary, "
11742  "and then try an online backup again.")));
11743 
11744 
11745  LWLockAcquire(ControlFileLock, LW_SHARED);
11746  stoppoint = ControlFile->minRecoveryPoint;
11747  stoptli = ControlFile->minRecoveryPointTLI;
11748  LWLockRelease(ControlFileLock);
11749  }
11750  else
11751  {
11752  /*
11753  * Write the backup-end xlog record
11754  */
11755  XLogBeginInsert();
11756  XLogRegisterData((char *) (&startpoint), sizeof(startpoint));
11757  stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
11758 
11759  /*
11760  * Given that we're not in recovery, InsertTimeLineID is set and can't
11761  * change, so we can read it without a lock.
11762  */
11763  stoptli = XLogCtl->InsertTimeLineID;
11764 
11765  /*
11766  * Force a switch to a new xlog segment file, so that the backup is
11767  * valid as soon as archiver moves out the current segment file.
11768  */
11769  RequestXLogSwitch(false);
11770 
11771  XLByteToPrevSeg(stoppoint, _logSegNo, wal_segment_size);
11772  XLogFileName(stopxlogfilename, stoptli, _logSegNo, wal_segment_size);
11773 
11774  /* Use the log timezone here, not the session timezone */
11775  stamp_time = (pg_time_t) time(NULL);
11776  pg_strftime(strfbuf, sizeof(strfbuf),
11777  "%Y-%m-%d %H:%M:%S %Z",
11778  pg_localtime(&stamp_time, log_timezone));
11779 
11780  /*
11781  * Write the backup history file
11782  */
11783  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
11784  BackupHistoryFilePath(histfilepath, stoptli, _logSegNo,
11785  startpoint, wal_segment_size);
11786  fp = AllocateFile(histfilepath, "w");
11787  if (!fp)
11788  ereport(ERROR,
11790  errmsg("could not create file \"%s\": %m",
11791  histfilepath)));
11792  fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n",
11793  LSN_FORMAT_ARGS(startpoint), startxlogfilename);
11794  fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
11795  LSN_FORMAT_ARGS(stoppoint), stopxlogfilename);
11796 
11797  /*
11798  * Transfer remaining lines including label and start timeline to
11799  * history file.
11800  */
11801  fprintf(fp, "%s", remaining);
11802  fprintf(fp, "STOP TIME: %s\n", strfbuf);
11803  fprintf(fp, "STOP TIMELINE: %u\n", stoptli);
11804  if (fflush(fp) || ferror(fp) || FreeFile(fp))
11805  ereport(ERROR,
11807  errmsg("could not write file \"%s\": %m",
11808  histfilepath)));
11809 
11810  /*
11811  * Clean out any no-longer-needed history files. As a side effect,
11812  * this will post a .ready file for the newly created history file,
11813  * notifying the archiver that history file may be archived
11814  * immediately.
11815  */
11817  }
11818 
11819  /*
11820  * If archiving is enabled, wait for all the required WAL files to be
11821  * archived before returning. If archiving isn't enabled, the required WAL
11822  * needs to be transported via streaming replication (hopefully with
11823  * wal_keep_size set high enough), or some more exotic mechanism like
11824  * polling and copying files from pg_wal with script. We have no knowledge
11825  * of those mechanisms, so it's up to the user to ensure that he gets all
11826  * the required WAL.
11827  *
11828  * We wait until both the last WAL file filled during backup and the
11829  * history file have been archived, and assume that the alphabetic sorting
11830  * property of the WAL files ensures any earlier WAL files are safely
11831  * archived as well.
11832  *
11833  * We wait forever, since archive_command is supposed to work and we
11834  * assume the admin wanted his backup to work completely. If you don't
11835  * wish to wait, then either waitforarchive should be passed in as false,
11836  * or you can set statement_timeout. Also, some notices are issued to
11837  * clue in anyone who might be doing this interactively.
11838  */
11839 
11840  if (waitforarchive &&
11843  {
11844  XLByteToPrevSeg(stoppoint, _logSegNo, wal_segment_size);
11845  XLogFileName(lastxlogfilename, stoptli, _logSegNo, wal_segment_size);
11846 
11847  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
11848  BackupHistoryFileName(histfilename, stoptli, _logSegNo,
11849  startpoint, wal_segment_size);
11850 
11851  seconds_before_warning = 60;
11852  waits = 0;
11853 
11854  while (XLogArchiveIsBusy(lastxlogfilename) ||
11855  XLogArchiveIsBusy(histfilename))
11856  {
11858 
11859  if (!reported_waiting && waits > 5)
11860  {
11861  ereport(NOTICE,
11862  (errmsg("base backup done, waiting for required WAL segments to be archived")));
11863  reported_waiting = true;
11864  }
11865 
11866  (void) WaitLatch(MyLatch,
11868  1000L,
11871 
11872  if (++waits >= seconds_before_warning)
11873  {
11874  seconds_before_warning *= 2; /* This wraps in >10 years... */
11875  ereport(WARNING,
11876  (errmsg("still waiting for all required WAL segments to be archived (%d seconds elapsed)",
11877  waits),
11878  errhint("Check that your archive_command is executing properly. "
11879  "You can safely cancel this backup, "
11880  "but the database backup will not be usable without all the WAL segments.")));
11881  }
11882  }
11883 
11884  ereport(NOTICE,
11885  (errmsg("all required WAL segments have been archived")));
11886  }
11887  else if (waitforarchive)
11888  ereport(NOTICE,
11889  (errmsg("WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup")));
11890 
11891  /*
11892  * We're done. As a convenience, return the ending WAL location.
11893  */
11894  if (stoptli_p)
11895  *stoptli_p = stoptli;
11896  return stoppoint;
11897 }
#define NOTICE
Definition: elog.h:29
int durable_unlink(const char *fname, int elevel)
Definition: fd.c:789
struct Latch * MyLatch
Definition: globals.c:57
int remaining
Definition: informix.c:667
void ResetLatch(Latch *latch)
Definition: latch.c:660
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:452
#define WL_TIMEOUT
Definition: latch.h:128
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:130
#define WL_LATCH_SET
Definition: latch.h:125
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:120
#define XLOG_BACKUP_END
Definition: pg_control.h:72
#define fprintf
Definition: port.h:229
@ WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE
Definition: wait_event.h:86
static void CleanupBackupHistory(void)
Definition: xlog.c:4429
static void pg_stop_backup_callback(int code, Datum arg)
Definition: xlog.c:11459
@ SESSION_BACKUP_NONE
Definition: xlog.h:342
#define XLogArchivingAlways()
Definition: xlog.h:156
#define BackupHistoryFileName(fname, tli, logSegNo, startpoint, wal_segsz_bytes)
#define BackupHistoryFilePath(path, tli, logSegNo, startpoint, wal_segsz_bytes)
bool XLogArchiveIsBusy(const char *xlog)
Definition: xlogarchive.c:649

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

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

◆ emode_for_corrupt_record()

static int emode_for_corrupt_record ( int  emode,
XLogRecPtr  RecPtr 
)
static

Definition at line 13097 of file xlog.c.

13098 {
13099  static XLogRecPtr lastComplaint = 0;
13100 
13101  if (readSource == XLOG_FROM_PG_WAL && emode == LOG)
13102  {
13103  if (RecPtr == lastComplaint)
13104  emode = DEBUG1;
13105  else
13106  lastComplaint = RecPtr;
13107  }
13108  return emode;
13109 }
static XLogSource readSource
Definition: xlog.c:830

References DEBUG1, LOG, readSource, and XLOG_FROM_PG_WAL.

Referenced by ReadRecord(), and XLogPageRead().

◆ exitArchiveRecovery()

static void exitArchiveRecovery ( TimeLineID  endTLI,
XLogRecPtr  endOfLog,
TimeLineID  newTLI 
)
static

Definition at line 5698 of file xlog.c.

5699 {
5700  char xlogfname[MAXFNAMELEN];
5701  XLogSegNo endLogSegNo;
5702  XLogSegNo startLogSegNo;
5703 
5704  /* we always switch to a new timeline after archive recovery */
5705  Assert(endTLI != newTLI);
5706 
5707  /*
5708  * We are no longer in archive recovery state.
5709  */
5710  InArchiveRecovery = false;
5711 
5712  /*
5713  * Update min recovery point one last time.
5714  */
5716 
5717  /*
5718  * If the ending log segment is still open, close it (to avoid problems on
5719  * Windows with trying to rename or delete an open file).
5720  */
5721  if (readFile >= 0)
5722  {
5723  close(readFile);
5724  readFile = -1;
5725  }
5726 
5727  /*
5728  * Calculate the last segment on the old timeline, and the first segment
5729  * on the new timeline. If the switch happens in the middle of a segment,
5730  * they are the same, but if the switch happens exactly at a segment
5731  * boundary, startLogSegNo will be endLogSegNo + 1.
5732  */
5733  XLByteToPrevSeg(endOfLog, endLogSegNo, wal_segment_size);
5734  XLByteToSeg(endOfLog, startLogSegNo, wal_segment_size);
5735 
5736  /*
5737  * Initialize the starting WAL segment for the new timeline. If the switch
5738  * happens in the middle of a segment, copy data from the last WAL segment
5739  * of the old timeline up to the switch point, to the starting WAL segment
5740  * on the new timeline.
5741  */
5742  if (endLogSegNo == startLogSegNo)
5743  {
5744  /*
5745  * Make a copy of the file on the new timeline.
5746  *
5747  * Writing WAL isn't allowed yet, so there are no locking
5748  * considerations. But we should be just as tense as XLogFileInit to
5749  * avoid emplacing a bogus file.
5750  */
5751  XLogFileCopy(newTLI, endLogSegNo, endTLI, endLogSegNo,
5752  XLogSegmentOffset(endOfLog, wal_segment_size));
5753  }
5754  else
5755  {
5756  /*
5757  * The switch happened at a segment boundary, so just create the next
5758  * segment on the new timeline.
5759  */
5760  int fd;
5761 
5762  fd = XLogFileInit(startLogSegNo, newTLI);
5763 
5764  if (close(fd) != 0)
5765  {
5766  char xlogfname[MAXFNAMELEN];
5767  int save_errno = errno;
5768 
5769  XLogFileName(xlogfname, newTLI, startLogSegNo, wal_segment_size);
5770  errno = save_errno;
5771  ereport(ERROR,
5773  errmsg("could not close file \"%s\": %m", xlogfname)));
5774  }
5775  }
5776 
5777  /*
5778  * Let's just make real sure there are not .ready or .done flags posted
5779  * for the new segment.
5780  */
5781  XLogFileName(xlogfname, newTLI, startLogSegNo, wal_segment_size);
5782  XLogArchiveCleanup(xlogfname);
5783 
5784  /*
5785  * Remove the signal files out of the way, so that we don't accidentally
5786  * re-enter archive recovery mode in a subsequent crash.
5787  */
5790 
5793 
5794  ereport(LOG,
5795  (errmsg("archive recovery complete")));
5796 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static bool standby_signal_file_found
Definition: xlog.c:260
static int readFile
Definition: xlog.c:826
static void XLogFileCopy(TimeLineID destTLI, XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno, int upto)
Definition: xlog.c:3558
static bool recovery_signal_file_found
Definition: xlog.c:261
#define STANDBY_SIGNAL_FILE
Definition: xlog.h:358
#define RECOVERY_SIGNAL_FILE
Definition: xlog.h:357

References Assert(), close, durable_unlink(), ereport, errcode_for_file_access(), errmsg(), ERROR, FATAL, fd(), InArchiveRecovery, InvalidXLogRecPtr, LOG, MAXFNAMELEN, readFile, RECOVERY_SIGNAL_FILE, recovery_signal_file_found, STANDBY_SIGNAL_FILE, standby_signal_file_found, UpdateMinRecoveryPoint(), wal_segment_size, XLByteToPrevSeg, XLByteToSeg, XLogArchiveCleanup(), XLogFileCopy(), XLogFileInit(), XLogFileName, and XLogSegmentOffset.

Referenced by StartupXLOG().

◆ get_backup_status()

SessionBackupState get_backup_status ( void  )

Definition at line 11477 of file xlog.c.

11478 {
11479  return sessionBackupState;
11480 }

References sessionBackupState.

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

◆ get_sync_bit()

static int get_sync_bit ( int  method)
static

Definition at line 10761 of file xlog.c.

10762 {
10763  int o_direct_flag = 0;
10764 
10765  /* If fsync is disabled, never open in sync mode */
10766  if (!enableFsync)
10767  return 0;
10768 
10769  /*
10770  * Optimize writes by bypassing kernel cache with O_DIRECT when using
10771  * O_SYNC/O_FSYNC and O_DSYNC. But only if archiving and streaming are
10772  * disabled, otherwise the archive command or walsender process will read
10773  * the WAL soon after writing it, which is guaranteed to cause a physical
10774  * read if we bypassed the kernel cache. We also skip the
10775  * posix_fadvise(POSIX_FADV_DONTNEED) call in XLogFileClose() for the same
10776  * reason.
10777  *
10778  * Never use O_DIRECT in walreceiver process for similar reasons; the WAL
10779  * written by walreceiver is normally read by the startup process soon
10780  * after it's written. Also, walreceiver performs unaligned writes, which
10781  * don't work with O_DIRECT, so it is required for correctness too.
10782  */
10783  if (!XLogIsNeeded() && !AmWalReceiverProcess())
10784  o_direct_flag = PG_O_DIRECT;
10785 
10786  switch (method)
10787  {
10788  /*
10789  * enum values for all sync options are defined even if they are
10790  * not supported on the current platform. But if not, they are
10791  * not included in the enum option array, and therefore will never
10792  * be seen here.
10793  */
10794  case SYNC_METHOD_FSYNC:
10796  case SYNC_METHOD_FDATASYNC:
10797  return 0;
10798 #ifdef OPEN_SYNC_FLAG
10799  case SYNC_METHOD_OPEN:
10800  return OPEN_SYNC_FLAG | o_direct_flag;
10801 #endif
10802 #ifdef OPEN_DATASYNC_FLAG
10804  return OPEN_DATASYNC_FLAG | o_direct_flag;
10805 #endif
10806  default:
10807  /* can't happen (unless we are out of sync with option array) */
10808  elog(ERROR, "unrecognized wal_sync_method: %d", method);
10809  return 0; /* silence warning */
10810  }
10811 }
#define PG_O_DIRECT
Definition: fd.h:95
bool enableFsync
Definition: globals.c:122
#define AmWalReceiverProcess()
Definition: miscadmin.h:449
#define SYNC_METHOD_FSYNC
Definition: xlog.h:25
#define SYNC_METHOD_OPEN
Definition: xlog.h:27
#define SYNC_METHOD_FDATASYNC
Definition: xlog.h:26
#define SYNC_METHOD_OPEN_DSYNC
Definition: xlog.h:29
#define SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:28

References AmWalReceiverProcess, elog, enableFsync, ERROR, PG_O_DIRECT, SYNC_METHOD_FDATASYNC, SYNC_METHOD_FSYNC, SYNC_METHOD_FSYNC_WRITETHROUGH, SYNC_METHOD_OPEN, SYNC_METHOD_OPEN_DSYNC, and XLogIsNeeded.

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

◆ GetCurrentChunkReplayStartTime()

TimestampTz GetCurrentChunkReplayStartTime ( void  )

Definition at line 6519 of file xlog.c.

6520 {
6521  TimestampTz xtime;
6522 
6524  xtime = XLogCtl->currentChunkStartTime;
6526 
6527  return xtime;
6528 }
TimestampTz currentChunkStartTime
Definition: xlog.c:728

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

Referenced by GetReplicationApplyDelay().

◆ GetFakeLSNForUnloggedRel()

XLogRecPtr GetFakeLSNForUnloggedRel ( void  )

Definition at line 5098 of file xlog.c.

5099 {
5100  XLogRecPtr nextUnloggedLSN;
5101 
5102  /* increment the unloggedLSN counter, need SpinLock */
5104  nextUnloggedLSN = XLogCtl->unloggedLSN++;
5106 
5107  return nextUnloggedLSN;
5108 }

References SpinLockAcquire, SpinLockRelease, XLogCtlData::ulsn_lck, XLogCtlData::unloggedLSN, and XLogCtl.

Referenced by gistGetFakeLSN().

◆ GetFlushRecPtr()

XLogRecPtr GetFlushRecPtr ( TimeLineID insertTLI)

Definition at line 8713 of file xlog.c.

8714 {
8716 
8720 
8721  /*
8722  * If we're writing and flushing WAL, the time line can't be changing,
8723  * so no lock is required.
8724  */
8725  if (insertTLI)
8726  *insertTLI = XLogCtl->InsertTimeLineID;
8727 
8728  return LogwrtResult.Flush;
8729 }
RecoveryState SharedRecoveryState
Definition: xlog.c:651
XLogRecPtr Flush
Definition: xlog.c:438
@ RECOVERY_STATE_DONE
Definition: xlog.h:139

References Assert(), XLogwrtResult::Flush, XLogCtlData::info_lck, XLogCtlData::InsertTimeLineID, XLogCtlData::LogwrtResult, LogwrtResult, RECOVERY_STATE_DONE, XLogCtlData::SharedRecoveryState, SpinLockAcquire, SpinLockRelease, and XLogCtl.

Referenced by get_flush_position(), IdentifySystem(), pg_current_wal_flush_lsn(), pg_logical_slot_get_changes_guts(), pg_replication_slot_advance(), read_local_xlog_page(), StartReplication(), WalSndWaitForWal(), XLogSendLogical(), and XLogSendPhysical().

◆ GetFullPageWriteInfo()

void GetFullPageWriteInfo ( XLogRecPtr RedoRecPtr_p,
bool doPageWrites_p 
)

Definition at line 8681 of file xlog.c.

8682 {
8683  *RedoRecPtr_p = RedoRecPtr;
8684  *doPageWrites_p = doPageWrites;
8685 }
static bool doPageWrites
Definition: xlog.c:375

References doPageWrites, and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )

Definition at line 8696 of file xlog.c.

8697 {
8698  XLogRecPtr recptr;
8699 
8701  recptr = XLogCtl->LogwrtRqst.Write;
8703 
8704  return recptr;
8705 }

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

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

◆ GetLastImportantRecPtr()

XLogRecPtr GetLastImportantRecPtr ( void  )

Definition at line 8753 of file xlog.c.

8754 {
8756  int i;
8757 
8758  for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
8759  {
8760  XLogRecPtr last_important;
8761 
8762  /*
8763  * Need to take a lock to prevent torn reads of the LSN, which are
8764  * possible on some of the supported platforms. WAL insert locks only
8765  * support exclusive mode, so we have to use that.
8766  */
8768  last_important = WALInsertLocks[i].l.lastImportantAt;
8769  LWLockRelease(&WALInsertLocks[i].l.lock);
8770 
8771  if (res < last_important)
8772  res = last_important;
8773  }
8774 
8775  return res;
8776 }
int i
Definition: isn.c:73
XLogRecPtr lastImportantAt
Definition: xlog.c:481
WALInsertLock l
Definition: xlog.c:493
static WALInsertLockPadded * WALInsertLocks
Definition: xlog.c:745
#define NUM_XLOGINSERT_LOCKS
Definition: xlog.c:130

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

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

◆ GetLastSegSwitchData()

pg_time_t GetLastSegSwitchData ( XLogRecPtr lastSwitchLSN)

Definition at line 8782 of file xlog.c.

8783 {
8784  pg_time_t result;
8785 
8786  /* Need WALWriteLock, but shared lock is sufficient */
8787  LWLockAcquire(WALWriteLock, LW_SHARED);
8788  result = XLogCtl->lastSegSwitchTime;
8789  *lastSwitchLSN = XLogCtl->lastSegSwitchLSN;
8790  LWLockRelease(WALWriteLock);
8791 
8792  return result;
8793 }
pg_time_t lastSegSwitchTime
Definition: xlog.c:606
XLogRecPtr lastSegSwitchLSN
Definition: xlog.c:607

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

Referenced by CheckArchiveTimeout().

◆ GetLatestXTime()

TimestampTz GetLatestXTime ( void  )

Definition at line 6489 of file xlog.c.

6490 {
6491  TimestampTz xtime;
6492 
6494  xtime = XLogCtl->recoveryLastXTime;
6496 
6497  return xtime;
6498 }
TimestampTz recoveryLastXTime
Definition: xlog.c:722

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

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

◆ GetMockAuthenticationNonce()

char* GetMockAuthenticationNonce ( void  )

Definition at line 5072 of file xlog.c.

5073 {
5074  Assert(ControlFile != NULL);
5076 }
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition: pg_control.h:229

References Assert(), ControlFile, and ControlFileData::mock_authentication_nonce.

Referenced by scram_mock_salt().

◆ GetOldestRestartPoint()

void GetOldestRestartPoint ( XLogRecPtr oldrecptr,
TimeLineID oldtli 
)

Definition at line 12015 of file xlog.c.

12016 {
12017  LWLockAcquire(ControlFileLock, LW_SHARED);
12018  *oldrecptr = ControlFile->checkPointCopy.redo;
12020  LWLockRelease(ControlFileLock);
12021 }

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

Referenced by ExecuteRecoveryCommand(), and RestoreArchivedFile().

◆ getRecordTimestamp()

static bool getRecordTimestamp ( XLogReaderState record,
TimestampTz recordXtime 
)
static

Definition at line 5891 of file xlog.c.

5892 {
5893  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
5894  uint8 xact_info = info & XLOG_XACT_OPMASK;
5895  uint8 rmid = XLogRecGetRmid(record);
5896 
5897  if (rmid == RM_XLOG_ID && info == XLOG_RESTORE_POINT)
5898  {
5899  *recordXtime = ((xl_restore_point *) XLogRecGetData(record))->rp_time;
5900  return true;
5901  }
5902  if (rmid == RM_XACT_ID && (xact_info == XLOG_XACT_COMMIT ||
5903  xact_info == XLOG_XACT_COMMIT_PREPARED))
5904  {
5905  *recordXtime = ((xl_xact_commit *) XLogRecGetData(record))->xact_time;
5906  return true;
5907  }
5908  if (rmid == RM_XACT_ID && (xact_info == XLOG_XACT_ABORT ||
5909  xact_info == XLOG_XACT_ABORT_PREPARED))
5910  {
5911  *recordXtime = ((xl_xact_abort *) XLogRecGetData(record))->xact_time;
5912  return true;
5913  }
5914  return false;
5915 }
unsigned char uint8
Definition: c.h:439
#define XLOG_RESTORE_POINT
Definition: pg_control.h:74
#define XLOG_XACT_COMMIT_PREPARED
Definition: xact.h:151
#define XLOG_XACT_COMMIT
Definition: xact.h:148
#define XLOG_XACT_OPMASK
Definition: xact.h:158
#define XLOG_XACT_ABORT
Definition: xact.h:150
#define XLOG_XACT_ABORT_PREPARED
Definition: xact.h:152
#define XLogRecGetData(decoder)
Definition: xlogreader.h:320
#define XLR_INFO_MASK
Definition: xlogrecord.h:62

References XLOG_RESTORE_POINT, XLOG_XACT_ABORT, XLOG_XACT_ABORT_PREPARED, XLOG_XACT_COMMIT, XLOG_XACT_COMMIT_PREPARED, XLOG_XACT_OPMASK, XLogRecGetData, XLogRecGetInfo, XLogRecGetRmid, and XLR_INFO_MASK.

Referenced by recoveryApplyDelay(), recoveryStopsAfter(), and recoveryStopsBefore().

◆ GetRecoveryPauseState()

RecoveryPauseState GetRecoveryPauseState ( void  )

◆ GetRecoveryState()

RecoveryState GetRecoveryState ( void  )

Definition at line 8440 of file xlog.c.

8441 {
8442  RecoveryState retval;
8443 
8445  retval = XLogCtl->SharedRecoveryState;
8447 
8448  return retval;
8449 }
RecoveryState
Definition: xlog.h:136

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

Referenced by XLogArchiveCheckDone().

◆ getRecoveryStopReason()

static char * getRecoveryStopReason ( void  )
static

Definition at line 6234 of file xlog.c.

6235 {
6236  char reason[200];
6237 
6239  snprintf(reason, sizeof(reason),
6240  "%s transaction %u",
6241  recoveryStopAfter ? "after" : "before",
6242  recoveryStopXid);
6244  snprintf(reason, sizeof(reason),
6245  "%s %s\n",
6246  recoveryStopAfter ? "after" : "before",
6248  else if (recoveryTarget == RECOVERY_TARGET_LSN)
6249  snprintf(reason, sizeof(reason),
6250  "%s LSN %X/%X\n",
6251  recoveryStopAfter ? "after" : "before",