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 "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/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 NUM_XLOGINSERT_LOCKS   8
 
#define INSERT_FREESPACE(endptr)   (((endptr) % XLOG_BLCKSZ == 0) ? 0 : (XLOG_BLCKSZ - (endptr) % XLOG_BLCKSZ))
 
#define NextBufIdx(idx)   (((idx) == XLogCtl->XLogCacheBlck) ? 0 : ((idx) + 1))
 
#define XLogRecPtrToBufIdx(recptr)   (((recptr) / XLOG_BLCKSZ) % (XLogCtl->XLogCacheBlck + 1))
 
#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)
 
#define ConvertToXSegs(x, segsize)   XLogMBVarToSegs((x), (segsize))
 
#define RecoveryRequiresIntParameter(param_name, currValue, minValue)
 

Typedefs

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

Enumerations

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

Functions

static void readRecoverySignalFile (void)
 
static void validateRecoveryParameters (void)
 
static void exitArchiveRecovery (TimeLineID endTLI, XLogRecPtr endOfLog)
 
static bool recoveryStopsBefore (XLogReaderState *record)
 
static bool recoveryStopsAfter (XLogReaderState *record)
 
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)
 
static void LocalSetXLogInsertAllowed (void)
 
static void CreateEndOfRecoveryRecord (void)
 
static void CheckPointGuts (XLogRecPtr checkPointRedo, int flags)
 
static void KeepLogSeg (XLogRecPtr recptr, XLogSegNo *logSegNo)
 
static XLogRecPtr XLogGetReplicationSlotMinimumLSN (void)
 
static void AdvanceXLInsertBuffer (XLogRecPtr upto, bool opportunistic)
 
static bool XLogCheckpointNeeded (XLogSegNo new_segno)
 
static void XLogWrite (XLogwrtRqst WriteRqst, bool flexible)
 
static bool InstallXLogFileSegment (XLogSegNo *segno, char *tmppath, bool find_free, XLogSegNo max_segno, bool use_lock)
 
static int XLogFileRead (XLogSegNo segno, int emode, TimeLineID tli, 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)
 
static int emode_for_corrupt_record (int emode, XLogRecPtr RecPtr)
 
static void XLogFileClose (void)
 
static void PreallocXlogFiles (XLogRecPtr endptr)
 
static void RemoveTempXlogFiles (void)
 
static void RemoveOldXlogFiles (XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr)
 
static void RemoveXlogFile (const char *segname, XLogRecPtr lastredoptr, XLogRecPtr endptr)
 
static void UpdateLastRemovedPtr (char *filename)
 
static void ValidateXLOGDirectoryStructure (void)
 
static void CleanupBackupHistory (void)
 
static void UpdateMinRecoveryPoint (XLogRecPtr lsn, bool force)
 
static XLogRecordReadRecord (XLogReaderState *xlogreader, int emode, bool fetching_ckpt)
 
static void CheckRecoveryConsistency (void)
 
static XLogRecordReadCheckpointRecord (XLogReaderState *xlogreader, XLogRecPtr RecPtr, int whichChkpt, bool report)
 
static bool rescanLatestTimeLine (void)
 
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, bool *backupEndRequired, bool *backupFromStandby)
 
static bool read_tablespace_map (List **tablespaces)
 
static void rm_redo_error_callback (void *arg)
 
static int get_sync_bit (int method)
 
static void CopyXLogRecordToWAL (int write_len, bool isLogSwitch, XLogRecData *rdata, XLogRecPtr StartPos, XLogRecPtr EndPos)
 
static void ReserveXLogInsertLocation (int size, XLogRecPtr *StartPos, XLogRecPtr *EndPos, XLogRecPtr *PrevPtr)
 
static bool ReserveXLogSwitch (XLogRecPtr *StartPos, XLogRecPtr *EndPos, XLogRecPtr *PrevPtr)
 
static XLogRecPtr WaitXLogInsertionsToFinish (XLogRecPtr upto)
 
static char * GetXLogBuffer (XLogRecPtr ptr)
 
static XLogRecPtr XLogBytePosToRecPtr (uint64 bytepos)
 
static XLogRecPtr XLogBytePosToEndRecPtr (uint64 bytepos)
 
static uint64 XLogRecPtrToBytePos (XLogRecPtr ptr)
 
static void checkXLogConsistency (XLogReaderState *record)
 
static void WALInsertLockAcquire (void)
 
static void WALInsertLockAcquireExclusive (void)
 
static void WALInsertLockRelease (void)
 
static void WALInsertLockUpdateInsertingAt (XLogRecPtr insertingAt)
 
XLogRecPtr XLogInsertRecord (XLogRecData *rdata, XLogRecPtr fpw_lsn, uint8 flags, int num_fpi)
 
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)
 
int XLogFileInit (XLogSegNo logsegno, bool *use_existent, bool use_lock)
 
static void XLogFileCopy (XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno, int upto)
 
int XLogFileOpen (XLogSegNo segno)
 
void CheckXLogRemoved (XLogSegNo segno, TimeLineID tli)
 
XLogSegNo XLogGetLastRemovedSegno (void)
 
static void RemoveNonParentXlogFiles (XLogRecPtr switchpoint, TimeLineID newTLI)
 
void UpdateControlFile (void)
 
uint64 GetSystemIdentifier (void)
 
char * GetMockAuthenticationNonce (void)
 
bool DataChecksumsEnabled (void)
 
XLogRecPtr GetFakeLSNForUnloggedRel (void)
 
static int XLOGChooseNumBuffers (void)
 
bool check_wal_buffers (int *newval, void **extra, GucSource source)
 
void LocalProcessControlFile (bool reset)
 
Size XLOGShmemSize (void)
 
void XLOGShmemInit (void)
 
void BootStrapXLOG (void)
 
static bool getRecordTimestamp (XLogReaderState *record, TimestampTz *recordXtime)
 
bool RecoveryIsPaused (void)
 
void SetRecoveryPause (bool recoveryPause)
 
TimestampTz GetLatestXTime (void)
 
TimestampTz GetCurrentChunkReplayStartTime (void)
 
void GetXLogReceiptTime (TimestampTz *rtime, bool *fromStream)
 
void StartupXLOG (void)
 
bool RecoveryInProgress (void)
 
RecoveryState GetRecoveryState (void)
 
bool HotStandbyActive (void)
 
bool HotStandbyActiveInReplay (void)
 
bool XLogInsertAllowed (void)
 
void InitXLOGAccess (void)
 
XLogRecPtr GetRedoRecPtr (void)
 
void GetFullPageWriteInfo (XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p)
 
XLogRecPtr GetInsertRecPtr (void)
 
XLogRecPtr GetFlushRecPtr (void)
 
XLogRecPtr GetLastImportantRecPtr (void)
 
pg_time_t GetLastSegSwitchData (XLogRecPtr *lastSwitchLSN)
 
void ShutdownXLOG (int code, Datum arg)
 
static void LogCheckpointStart (int flags, bool restartpoint)
 
static void LogCheckpointEnd (bool restartpoint)
 
static void UpdateCheckPointDistanceEstimate (uint64 nbytes)
 
void CreateCheckPoint (int flags)
 
static void RecoveryRestartPoint (const CheckPoint *checkPoint)
 
bool CreateRestartPoint (int flags)
 
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)
 
XLogRecPtr do_pg_start_backup (const char *backupidstr, bool fast, TimeLineID *starttli_p, StringInfo labelfile, List **tablespaces, StringInfo tblspcmapfile, bool needtblspcmapfile)
 
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
 
bool wal_compression = false
 
char * wal_consistency_checking_string = NULL
 
boolwal_consistency_checking = NULL
 
bool wal_init_zero = true
 
bool wal_recycle = true
 
bool log_checkpoints = false
 
int sync_method = DEFAULT_SYNC_METHOD
 
int wal_level = WAL_LEVEL_MINIMAL
 
int CommitDelay = 0
 
int CommitSiblings = 5
 
int wal_retrieve_retry_interval = 5000
 
int max_slot_wal_keep_size_mb = -1
 
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
 
TimeLineID ThisTimeLineID = 0
 
bool InRecovery = false
 
HotStandbyState standbyState = STANDBY_DISABLED
 
static XLogRecPtr LastRec
 
static XLogRecPtr flushedUpto = 0
 
static TimeLineID receiveTLI = 0
 
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 bool restoredFromArchive = 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 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 ReadRecPtr
 
static XLogRecPtr EndRecPtr
 
static XLogRecPtr minRecoveryPoint
 
static TimeLineID minRecoveryPointTLI
 
static bool updateMinRecoveryPoint = true
 
bool reachedConsistency = false
 
static bool InRedo = false
 
static bool bgwriterLaunched = false
 
static int MyLockNo = 0
 
static bool holdingAllLocks = false
 

Macro Definition Documentation

◆ ConvertToXSegs

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

◆ INSERT_FREESPACE

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

Definition at line 743 of file xlog.c.

Referenced by CopyXLogRecordToWAL(), and CreateCheckPoint().

◆ NextBufIdx

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

Definition at line 747 of file xlog.c.

Referenced by XLogWrite().

◆ NUM_XLOGINSERT_LOCKS

◆ RECOVERY_COMMAND_DONE

#define RECOVERY_COMMAND_DONE   "recovery.done"

Definition at line 87 of file xlog.c.

Referenced by readRecoverySignalFile().

◆ RECOVERY_COMMAND_FILE

#define RECOVERY_COMMAND_FILE   "recovery.conf"

Definition at line 86 of file xlog.c.

Referenced by readRecoverySignalFile().

◆ RecoveryRequiresIntParameter

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

Definition at line 6238 of file xlog.c.

Referenced by CheckRequiredParameterValues().

◆ UsableBytesInPage

#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)

◆ XLogRecPtrToBufIdx

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

Definition at line 754 of file xlog.c.

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

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 522 of file xlog.c.

◆ XLogSource

enum XLogSource
Enumerator
XLOG_FROM_ANY 
XLOG_FROM_ARCHIVE 
XLOG_FROM_PG_WAL 
XLOG_FROM_STREAM 

Definition at line 781 of file xlog.c.

782 {
783  XLOG_FROM_ANY = 0, /* request to read WAL from any source */
784  XLOG_FROM_ARCHIVE, /* restored using restore_command */
785  XLOG_FROM_PG_WAL, /* existing file in pg_wal */
786  XLOG_FROM_STREAM /* streamed from primary */
787 } XLogSource;
XLogSource
Definition: xlog.c:781

Function Documentation

◆ AdvanceXLInsertBuffer()

static void AdvanceXLInsertBuffer ( XLogRecPtr  upto,
bool  opportunistic 
)
static

Definition at line 2124 of file xlog.c.

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

Referenced by GetXLogBuffer(), and XLogBackgroundFlush().

2125 {
2127  int nextidx;
2128  XLogRecPtr OldPageRqstPtr;
2129  XLogwrtRqst WriteRqst;
2130  XLogRecPtr NewPageEndPtr = InvalidXLogRecPtr;
2131  XLogRecPtr NewPageBeginPtr;
2132  XLogPageHeader NewPage;
2133  int npages = 0;
2134 
2135  LWLockAcquire(WALBufMappingLock, LW_EXCLUSIVE);
2136 
2137  /*
2138  * Now that we have the lock, check if someone initialized the page
2139  * already.
2140  */
2141  while (upto >= XLogCtl->InitializedUpTo || opportunistic)
2142  {
2144 
2145  /*
2146  * Get ending-offset of the buffer page we need to replace (this may
2147  * be zero if the buffer hasn't been used yet). Fall through if it's
2148  * already written out.
2149  */
2150  OldPageRqstPtr = XLogCtl->xlblocks[nextidx];
2151  if (LogwrtResult.Write < OldPageRqstPtr)
2152  {
2153  /*
2154  * Nope, got work to do. If we just want to pre-initialize as much
2155  * as we can without flushing, give up now.
2156  */
2157  if (opportunistic)
2158  break;
2159 
2160  /* Before waiting, get info_lck and update LogwrtResult */
2162  if (XLogCtl->LogwrtRqst.Write < OldPageRqstPtr)
2163  XLogCtl->LogwrtRqst.Write = OldPageRqstPtr;
2166 
2167  /*
2168  * Now that we have an up-to-date LogwrtResult value, see if we
2169  * still need to write it or if someone else already did.
2170  */
2171  if (LogwrtResult.Write < OldPageRqstPtr)
2172  {
2173  /*
2174  * Must acquire write lock. Release WALBufMappingLock first,
2175  * to make sure that all insertions that we need to wait for
2176  * can finish (up to this same position). Otherwise we risk
2177  * deadlock.
2178  */
2179  LWLockRelease(WALBufMappingLock);
2180 
2181  WaitXLogInsertionsToFinish(OldPageRqstPtr);
2182 
2183  LWLockAcquire(WALWriteLock, LW_EXCLUSIVE);
2184 
2186  if (LogwrtResult.Write >= OldPageRqstPtr)
2187  {
2188  /* OK, someone wrote it already */
2189  LWLockRelease(WALWriteLock);
2190  }
2191  else
2192  {
2193  /* Have to write it ourselves */
2194  TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_START();
2195  WriteRqst.Write = OldPageRqstPtr;
2196  WriteRqst.Flush = 0;
2197  XLogWrite(WriteRqst, false);
2198  LWLockRelease(WALWriteLock);
2200  TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_DONE();
2201  }
2202  /* Re-acquire WALBufMappingLock and retry */
2203  LWLockAcquire(WALBufMappingLock, LW_EXCLUSIVE);
2204  continue;
2205  }
2206  }
2207 
2208  /*
2209  * Now the next buffer slot is free and we can set it up to be the
2210  * next output page.
2211  */
2212  NewPageBeginPtr = XLogCtl->InitializedUpTo;
2213  NewPageEndPtr = NewPageBeginPtr + XLOG_BLCKSZ;
2214 
2215  Assert(XLogRecPtrToBufIdx(NewPageBeginPtr) == nextidx);
2216 
2217  NewPage = (XLogPageHeader) (XLogCtl->pages + nextidx * (Size) XLOG_BLCKSZ);
2218 
2219  /*
2220  * Be sure to re-zero the buffer so that bytes beyond what we've
2221  * written will look like zeroes and not valid XLOG records...
2222  */
2223  MemSet((char *) NewPage, 0, XLOG_BLCKSZ);
2224 
2225  /*
2226  * Fill the new page's header
2227  */
2228  NewPage->xlp_magic = XLOG_PAGE_MAGIC;
2229 
2230  /* NewPage->xlp_info = 0; */ /* done by memset */
2231  NewPage->xlp_tli = ThisTimeLineID;
2232  NewPage->xlp_pageaddr = NewPageBeginPtr;
2233 
2234  /* NewPage->xlp_rem_len = 0; */ /* done by memset */
2235 
2236  /*
2237  * If online backup is not in progress, mark the header to indicate
2238  * that WAL records beginning in this page have removable backup
2239  * blocks. This allows the WAL archiver to know whether it is safe to
2240  * compress archived WAL data by transforming full-block records into
2241  * the non-full-block format. It is sufficient to record this at the
2242  * page level because we force a page switch (in fact a segment
2243  * switch) when starting a backup, so the flag will be off before any
2244  * records can be written during the backup. At the end of a backup,
2245  * the last page will be marked as all unsafe when perhaps only part
2246  * is unsafe, but at worst the archiver would miss the opportunity to
2247  * compress a few records.
2248  */
2249  if (!Insert->forcePageWrites)
2250  NewPage->xlp_info |= XLP_BKP_REMOVABLE;
2251 
2252  /*
2253  * If first page of an XLOG segment file, make it a long header.
2254  */
2255  if ((XLogSegmentOffset(NewPage->xlp_pageaddr, wal_segment_size)) == 0)
2256  {
2257  XLogLongPageHeader NewLongPage = (XLogLongPageHeader) NewPage;
2258 
2259  NewLongPage->xlp_sysid = ControlFile->system_identifier;
2260  NewLongPage->xlp_seg_size = wal_segment_size;
2261  NewLongPage->xlp_xlog_blcksz = XLOG_BLCKSZ;
2262  NewPage->xlp_info |= XLP_LONG_HEADER;
2263  }
2264 
2265  /*
2266  * Make sure the initialization of the page becomes visible to others
2267  * before the xlblocks update. GetXLogBuffer() reads xlblocks without
2268  * holding a lock.
2269  */
2270  pg_write_barrier();
2271 
2272  *((volatile XLogRecPtr *) &XLogCtl->xlblocks[nextidx]) = NewPageEndPtr;
2273 
2274  XLogCtl->InitializedUpTo = NewPageEndPtr;
2275 
2276  npages++;
2277  }
2278  LWLockRelease(WALBufMappingLock);
2279 
2280 #ifdef WAL_DEBUG
2281  if (XLOG_DEBUG && npages > 0)
2282  {
2283  elog(DEBUG1, "initialized %d pages, up to %X/%X",
2284  npages, (uint32) (NewPageEndPtr >> 32), (uint32) NewPageEndPtr);
2285  }
2286 #endif
2287 }
XLogRecPtr InitializedUpTo
Definition: xlog.c:635
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define DEBUG1
Definition: elog.h:25
int wal_segment_size
Definition: xlog.c:117
XLogRecPtr * xlblocks
Definition: xlog.c:643
static XLogwrtResult LogwrtResult
Definition: xlog.c:775
slock_t info_lck
Definition: xlog.c:726
#define MemSet(start, val, len)
Definition: c.h:950
static XLogRecPtr WaitXLogInsertionsToFinish(XLogRecPtr upto)
Definition: xlog.c:1787
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:54
XLogCtlInsert Insert
Definition: xlog.c:600
XLogRecPtr Flush
Definition: xlog.c:442
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:71
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define XLP_BKP_REMOVABLE
Definition: xlog_internal.h:78
bool forcePageWrites
Definition: xlog.c:574
uint64 system_identifier
Definition: pg_control.h:106
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
XLogwrtResult LogwrtResult
Definition: xlog.c:623
unsigned int uint32
Definition: c.h:375
static void Insert(File file)
Definition: fd.c:1175
PgStat_Counter m_wal_buffers_full
Definition: pgstat.h:462
TimeLineID xlp_tli
Definition: xlog_internal.h:40
static void XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
Definition: xlog.c:2415
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
#define SpinLockRelease(lock)
Definition: spin.h:64
XLogRecPtr Write
Definition: xlog.c:441
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
PgStat_MsgWal WalStats
Definition: pgstat.c:144
static ControlFileData * ControlFile
Definition: xlog.c:737
XLogwrtRqst LogwrtRqst
Definition: xlog.c:603
TimeLineID ThisTimeLineID
Definition: xlog.c:192
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:746
#define XLP_LONG_HEADER
Definition: xlog_internal.h:76
size_t Size
Definition: c.h:474
static XLogCtlData * XLogCtl
Definition: xlog.c:729
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208
#define XLogRecPtrToBufIdx(recptr)
Definition: xlog.c:754
XLogRecPtr Write
Definition: xlog.c:447
#define elog(elevel,...)
Definition: elog.h:214
#define pg_write_barrier()
Definition: atomics.h:159
char * pages
Definition: xlog.c:642

◆ assign_checkpoint_completion_target()

void assign_checkpoint_completion_target ( double  newval,
void *  extra 
)

Definition at line 2330 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

2331 {
2334 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2294
#define newval
double CheckPointCompletionTarget
Definition: checkpointer.c:148

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2323 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

2324 {
2327 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2294
int max_wal_size_mb
Definition: xlog.c:90
#define newval

◆ assign_xlog_sync_method()

void assign_xlog_sync_method ( int  new_sync_method,
void *  extra 
)

Definition at line 10386 of file xlog.c.

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

10387 {
10388  if (sync_method != new_sync_method)
10389  {
10390  /*
10391  * To ensure that no blocks escape unsynced, force an fsync on the
10392  * currently open log segment (if any). Also, if the open flag is
10393  * changing, close the log file so it will be reopened (with new flag
10394  * bit) at next use.
10395  */
10396  if (openLogFile >= 0)
10397  {
10399  if (pg_fsync(openLogFile) != 0)
10400  {
10401  char xlogfname[MAXFNAMELEN];
10402  int save_errno;
10403 
10404  save_errno = errno;
10407  errno = save_errno;
10408  ereport(PANIC,
10410  errmsg("could not fsync file \"%s\": %m", xlogfname)));
10411  }
10412 
10414  if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
10415  XLogFileClose();
10416  }
10417  }
10418 }
int wal_segment_size
Definition: xlog.c:117
static int get_sync_bit(int method)
Definition: xlog.c:10330
#define PANIC
Definition: elog.h:53
static XLogSegNo openLogSegNo
Definition: xlog.c:799
static void XLogFileClose(void)
Definition: xlog.c:3853
int errcode_for_file_access(void)
Definition: elog.c:633
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1460
#define MAXFNAMELEN
static int openLogFile
Definition: xlog.c:798
TimeLineID ThisTimeLineID
Definition: xlog.c:192
#define ereport(elevel,...)
Definition: elog.h:144
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1436
int sync_method
Definition: xlog.c:106
int errmsg(const char *fmt,...)
Definition: elog.c:821
int pg_fsync(int fd)
Definition: fd.c:346

◆ BackupInProgress()

bool BackupInProgress ( void  )

Definition at line 11797 of file xlog.c.

References BACKUP_LABEL_FILE, and stat.

Referenced by pg_is_in_backup(), and PostmasterStateMachine().

11798 {
11799  struct stat stat_buf;
11800 
11801  return (stat(BACKUP_LABEL_FILE, &stat_buf) == 0);
11802 }
struct stat stat_buf
Definition: pg_standby.c:100
#define BACKUP_LABEL_FILE
Definition: xlog.h:389
#define stat
Definition: win32_port.h:275

◆ BootStrapXLOG()

void BootStrapXLOG ( void  )

Definition at line 5196 of file xlog.c.

References AdvanceOldestClogXid(), Assert, BootStrapCLOG(), BootStrapCommitTs(), BootStrapMultiXact(), BootStrapSUBTRANS(), ControlFileData::checkPoint, ControlFileData::checkPointCopy, close, COMP_CRC32C, ereport, errcode_for_file_access(), errmsg(), FIN_CRC32C, FirstBootstrapObjectId, FirstMultiXactId, FirstNormalTransactionId, CheckPoint::fullPageWrites, fullPageWrites, FullTransactionIdFromEpochAndXid(), gettimeofday(), INIT_CRC32C, InitControlFile(), InvalidTransactionId, MultiXactSetNextMXact(), CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, VariableCacheData::nextOid, CheckPoint::nextXid, VariableCacheData::nextXid, offsetof, VariableCacheData::oidCount, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, openLogFile, 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, ThisTimeLineID, CheckPoint::time, ControlFileData::time, TYPEALIGN, WAIT_EVENT_WAL_BOOTSTRAP_SYNC, WAIT_EVENT_WAL_BOOTSTRAP_WRITE, wal_segment_size, write, WriteControlFile(), XLogRecord::xl_info, XLogRecord::xl_prev, XLogRecord::xl_rmid, XLogRecord::xl_tot_len, XLogRecord::xl_xid, XLOG_CHECKPOINT_SHUTDOWN, XLOG_PAGE_MAGIC, XLogFileInit(), XLogPageHeaderData::xlp_info, XLP_LONG_HEADER, XLogPageHeaderData::xlp_magic, XLogPageHeaderData::xlp_pageaddr, XLogLongPageHeaderData::xlp_seg_size, XLogLongPageHeaderData::xlp_sysid, XLogPageHeaderData::xlp_tli, XLogLongPageHeaderData::xlp_xlog_blcksz, and XLR_BLOCK_ID_DATA_SHORT.

Referenced by AuxiliaryProcessMain().

5197 {
5198  CheckPoint checkPoint;
5199  char *buffer;
5200  XLogPageHeader page;
5201  XLogLongPageHeader longpage;
5202  XLogRecord *record;
5203  char *recptr;
5204  bool use_existent;
5205  uint64 sysidentifier;
5206  struct timeval tv;
5207  pg_crc32c crc;
5208 
5209  /*
5210  * Select a hopefully-unique system identifier code for this installation.
5211  * We use the result of gettimeofday(), including the fractional seconds
5212  * field, as being about as unique as we can easily get. (Think not to
5213  * use random(), since it hasn't been seeded and there's no portable way
5214  * to seed it other than the system clock value...) The upper half of the
5215  * uint64 value is just the tv_sec part, while the lower half contains the
5216  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
5217  * PID for a little extra uniqueness. A person knowing this encoding can
5218  * determine the initialization time of the installation, which could
5219  * perhaps be useful sometimes.
5220  */
5221  gettimeofday(&tv, NULL);
5222  sysidentifier = ((uint64) tv.tv_sec) << 32;
5223  sysidentifier |= ((uint64) tv.tv_usec) << 12;
5224  sysidentifier |= getpid() & 0xFFF;
5225 
5226  /* First timeline ID is always 1 */
5227  ThisTimeLineID = 1;
5228 
5229  /* page buffer must be aligned suitably for O_DIRECT */
5230  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
5231  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
5232  memset(page, 0, XLOG_BLCKSZ);
5233 
5234  /*
5235  * Set up information for the initial checkpoint record
5236  *
5237  * The initial checkpoint record is written to the beginning of the WAL
5238  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5239  * used, so that we can use 0/0 to mean "before any valid WAL segment".
5240  */
5241  checkPoint.redo = wal_segment_size + SizeOfXLogLongPHD;
5242  checkPoint.ThisTimeLineID = ThisTimeLineID;
5243  checkPoint.PrevTimeLineID = ThisTimeLineID;
5244  checkPoint.fullPageWrites = fullPageWrites;
5245  checkPoint.nextXid =
5247  checkPoint.nextOid = FirstBootstrapObjectId;
5248  checkPoint.nextMulti = FirstMultiXactId;
5249  checkPoint.nextMultiOffset = 0;
5250  checkPoint.oldestXid = FirstNormalTransactionId;
5251  checkPoint.oldestXidDB = TemplateDbOid;
5252  checkPoint.oldestMulti = FirstMultiXactId;
5253  checkPoint.oldestMultiDB = TemplateDbOid;
5256  checkPoint.time = (pg_time_t) time(NULL);
5258 
5259  ShmemVariableCache->nextXid = checkPoint.nextXid;
5260  ShmemVariableCache->nextOid = checkPoint.nextOid;
5262  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5263  AdvanceOldestClogXid(checkPoint.oldestXid);
5264  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5265  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5267 
5268  /* Set up the XLOG page header */
5269  page->xlp_magic = XLOG_PAGE_MAGIC;
5270  page->xlp_info = XLP_LONG_HEADER;
5271  page->xlp_tli = ThisTimeLineID;
5273  longpage = (XLogLongPageHeader) page;
5274  longpage->xlp_sysid = sysidentifier;
5275  longpage->xlp_seg_size = wal_segment_size;
5276  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5277 
5278  /* Insert the initial checkpoint record */
5279  recptr = ((char *) page + SizeOfXLogLongPHD);
5280  record = (XLogRecord *) recptr;
5281  record->xl_prev = 0;
5282  record->xl_xid = InvalidTransactionId;
5283  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5285  record->xl_rmid = RM_XLOG_ID;
5286  recptr += SizeOfXLogRecord;
5287  /* fill the XLogRecordDataHeaderShort struct */
5288  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5289  *(recptr++) = sizeof(checkPoint);
5290  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5291  recptr += sizeof(checkPoint);
5292  Assert(recptr - (char *) record == record->xl_tot_len);
5293 
5294  INIT_CRC32C(crc);
5295  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5296  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5297  FIN_CRC32C(crc);
5298  record->xl_crc = crc;
5299 
5300  /* Create first XLOG segment file */
5301  use_existent = false;
5302  openLogFile = XLogFileInit(1, &use_existent, false);
5303 
5304  /*
5305  * We needn't bother with Reserve/ReleaseExternalFD here, since we'll
5306  * close the file again in a moment.
5307  */
5308 
5309  /* Write the first page with the initial record */
5310  errno = 0;
5312  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5313  {
5314  /* if write didn't set errno, assume problem is no disk space */
5315  if (errno == 0)
5316  errno = ENOSPC;
5317  ereport(PANIC,
5319  errmsg("could not write bootstrap write-ahead log file: %m")));
5320  }
5322 
5324  if (pg_fsync(openLogFile) != 0)
5325  ereport(PANIC,
5327  errmsg("could not fsync bootstrap write-ahead log file: %m")));
5329 
5330  if (close(openLogFile) != 0)
5331  ereport(PANIC,
5333  errmsg("could not close bootstrap write-ahead log file: %m")));
5334 
5335  openLogFile = -1;
5336 
5337  /* Now create pg_control */
5338  InitControlFile(sysidentifier);
5339  ControlFile->time = checkPoint.time;
5340  ControlFile->checkPoint = checkPoint.redo;
5341  ControlFile->checkPointCopy = checkPoint;
5342 
5343  /* some additional ControlFile fields are set in WriteControlFile() */
5344  WriteControlFile();
5345 
5346  /* Bootstrap the commit log, too */
5347  BootStrapCLOG();
5351 
5352  pfree(buffer);
5353 
5354  /*
5355  * Force control file to be read - in contrast to normal processing we'd
5356  * otherwise never run the checks and GUC related initializations therein.
5357  */
5358  ReadControlFile();
5359 }
static void WriteControlFile(void)
Definition: xlog.c:4613
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:104
int64 pg_time_t
Definition: pgtime.h:23
int wal_segment_size
Definition: xlog.c:117
pg_time_t time
Definition: pg_control.h:128
void SetCommitTsLimit(TransactionId oldestXact, TransactionId newestXact)
Definition: commit_ts.c:892
uint32 oidCount
Definition: transam.h:208
#define write(a, b, c)
Definition: win32.h:14
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:200
uint32 pg_crc32c
Definition: pg_crc32c.h:38
TransactionId oldestActiveXid
Definition: pg_control.h:63
int XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
Definition: xlog.c:3254
void BootStrapMultiXact(void)
Definition: multixact.c:1889
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
static void InitControlFile(uint64 sysidentifier)
Definition: xlog.c:4578
RmgrId xl_rmid
Definition: xlogrecord.h:47
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:54
CheckPoint checkPointCopy
Definition: pg_control.h:131
TransactionId oldestXid
Definition: pg_control.h:47
FullTransactionId nextXid
Definition: transam.h:213
pg_time_t time
Definition: pg_control.h:51
#define PANIC
Definition: elog.h:53
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:71
bool fullPageWrites
Definition: xlog.c:98
void BootStrapSUBTRANS(void)
Definition: subtrans.c:210
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid)
Definition: varsup.c:328
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
void pfree(void *pointer)
Definition: mcxt.c:1057
#define FirstNormalTransactionId
Definition: transam.h:34
uint32 xl_tot_len
Definition: xlogrecord.h:43
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
static void ReadControlFile(void)
Definition: xlog.c:4704
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
int errcode_for_file_access(void)
Definition: elog.c:633
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define InvalidTransactionId
Definition: transam.h:31
#define FirstBootstrapObjectId
Definition: transam.h:189
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1460
#define FirstMultiXactId
Definition: multixact.h:25
TimeLineID xlp_tli
Definition: xlog_internal.h:40
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
#define SizeOfXLogRecord
Definition: xlogrecord.h:55
TransactionId newestCommitTsXid
Definition: pg_control.h:54
Oid oldestMultiDB
Definition: pg_control.h:50
static int openLogFile
Definition: xlog.c:798
static ControlFileData * ControlFile
Definition: xlog.c:737
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
Definition: multixact.c:2208
TimeLineID ThisTimeLineID
Definition: xlog.c:192
Oid nextOid
Definition: pg_control.h:44
#define ereport(elevel,...)
Definition: elog.h:144
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:692
bool fullPageWrites
Definition: pg_control.h:42
void BootStrapCLOG(void)
Definition: clog.c:706
#define Assert(condition)
Definition: c.h:746
#define XLP_LONG_HEADER
Definition: xlog_internal.h:76
Oid oldestXidDB
Definition: pg_control.h:48
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1436
void SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid)
Definition: varsup.c:345
uint8 xl_info
Definition: xlogrecord.h:46
MultiXactId nextMulti
Definition: pg_control.h:45
static FullTransactionId FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
Definition: transam.h:71
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:223
TransactionId xl_xid
Definition: xlogrecord.h:44
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
void * palloc(Size size)
Definition: mcxt.c:950
int errmsg(const char *fmt,...)
Definition: elog.c:821
int pg_fsync(int fd)
Definition: fd.c:346
#define close(a)
Definition: win32.h:12
void BootStrapCommitTs(void)
Definition: commit_ts.c:585
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:89
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:94
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:37
#define offsetof(type, field)
Definition: c.h:669
FullTransactionId nextXid
Definition: pg_control.h:43
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:69
void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset)
Definition: multixact.c:2174

◆ CalculateCheckpointSegments()

static void CalculateCheckpointSegments ( void  )
static

Definition at line 2294 of file xlog.c.

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

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

2295 {
2296  double target;
2297 
2298  /*-------
2299  * Calculate the distance at which to trigger a checkpoint, to avoid
2300  * exceeding max_wal_size_mb. This is based on two assumptions:
2301  *
2302  * a) we keep WAL for only one checkpoint cycle (prior to PG11 we kept
2303  * WAL for two checkpoint cycles to allow us to recover from the
2304  * secondary checkpoint if the first checkpoint failed, though we
2305  * only did this on the primary anyway, not on standby. Keeping just
2306  * one checkpoint simplifies processing and reduces disk space in
2307  * many smaller databases.)
2308  * b) during checkpoint, we consume checkpoint_completion_target *
2309  * number of segments consumed between checkpoints.
2310  *-------
2311  */
2312  target = (double) ConvertToXSegs(max_wal_size_mb, wal_segment_size) /
2314 
2315  /* round down */
2316  CheckPointSegments = (int) target;
2317 
2318  if (CheckPointSegments < 1)
2319  CheckPointSegments = 1;
2320 }
#define ConvertToXSegs(x, segsize)
Definition: xlog.c:766
int wal_segment_size
Definition: xlog.c:117
int max_wal_size_mb
Definition: xlog.c:90
int CheckPointSegments
Definition: xlog.c:130
double CheckPointCompletionTarget
Definition: checkpointer.c:148

◆ CancelBackup()

void CancelBackup ( void  )

Definition at line 11817 of file xlog.c.

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

Referenced by PostmasterStateMachine().

11818 {
11819  struct stat stat_buf;
11820 
11821  /* if the backup_label file is not there, return */
11822  if (stat(BACKUP_LABEL_FILE, &stat_buf) < 0)
11823  return;
11824 
11825  /* remove leftover file from previously canceled backup if it exists */
11826  unlink(BACKUP_LABEL_OLD);
11827 
11829  {
11830  ereport(WARNING,
11832  errmsg("online backup mode was not canceled"),
11833  errdetail("File \"%s\" could not be renamed to \"%s\": %m.",
11835  return;
11836  }
11837 
11838  /* if the tablespace_map file is not there, return */
11839  if (stat(TABLESPACE_MAP, &stat_buf) < 0)
11840  {
11841  ereport(LOG,
11842  (errmsg("online backup mode canceled"),
11843  errdetail("File \"%s\" was renamed to \"%s\".",
11845  return;
11846  }
11847 
11848  /* remove leftover file from previously canceled backup if it exists */
11849  unlink(TABLESPACE_MAP_OLD);
11850 
11852  {
11853  ereport(LOG,
11854  (errmsg("online backup mode canceled"),
11855  errdetail("Files \"%s\" and \"%s\" were renamed to "
11856  "\"%s\" and \"%s\", respectively.",
11859  }
11860  else
11861  {
11862  ereport(WARNING,
11864  errmsg("online backup mode canceled"),
11865  errdetail("File \"%s\" was renamed to \"%s\", but "
11866  "file \"%s\" could not be renamed to \"%s\": %m.",
11869  }
11870 }
#define DEBUG1
Definition: elog.h:25
#define LOG
Definition: elog.h:26
#define BACKUP_LABEL_OLD
Definition: xlog.h:390
#define TABLESPACE_MAP
Definition: xlog.h:392
struct stat stat_buf
Definition: pg_standby.c:100
int errdetail(const char *fmt,...)
Definition: elog.c:954
int errcode_for_file_access(void)
Definition: elog.c:633
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:659
#define WARNING
Definition: elog.h:40
#define ereport(elevel,...)
Definition: elog.h:144
#define TABLESPACE_MAP_OLD
Definition: xlog.h:393
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define BACKUP_LABEL_FILE
Definition: xlog.h:389
#define stat
Definition: win32_port.h:275

◆ check_wal_buffers()

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

Definition at line 4989 of file xlog.c.

References XLOGbuffers, and XLOGChooseNumBuffers().

4990 {
4991  /*
4992  * -1 indicates a request for auto-tune.
4993  */
4994  if (*newval == -1)
4995  {
4996  /*
4997  * If we haven't yet changed the boot_val default of -1, just let it
4998  * be. We'll fix it when XLOGShmemSize is called.
4999  */
5000  if (XLOGbuffers == -1)
5001  return true;
5002 
5003  /* Otherwise, substitute the auto-tune value */
5005  }
5006 
5007  /*
5008  * We clamp manually-set values to at least 4 blocks. Prior to PostgreSQL
5009  * 9.1, a minimum of 4 was enforced by guc.c, but since that is no longer
5010  * the case, we just silently treat such values as a request for the
5011  * minimum. (We could throw an error instead, but that doesn't seem very
5012  * helpful.)
5013  */
5014  if (*newval < 4)
5015  *newval = 4;
5016 
5017  return true;
5018 }
static int XLOGChooseNumBuffers(void)
Definition: xlog.c:4973
#define newval
int XLOGbuffers
Definition: xlog.c:93

◆ CheckForStandbyTrigger()

static bool CheckForStandbyTrigger ( void  )
static

Definition at line 12611 of file xlog.c.

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

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

12612 {
12613  struct stat stat_buf;
12614 
12616  return true;
12617 
12619  {
12620  ereport(LOG, (errmsg("received promote request")));
12624  return true;
12625  }
12626 
12627  if (PromoteTriggerFile == NULL || strcmp(PromoteTriggerFile, "") == 0)
12628  return false;
12629 
12630  if (stat(PromoteTriggerFile, &stat_buf) == 0)
12631  {
12632  ereport(LOG,
12633  (errmsg("promote trigger file found: %s", PromoteTriggerFile)));
12634  unlink(PromoteTriggerFile);
12636  return true;
12637  }
12638  else if (errno != ENOENT)
12639  ereport(ERROR,
12641  errmsg("could not stat promote trigger file \"%s\": %m",
12642  PromoteTriggerFile)));
12643 
12644  return false;
12645 }
char * PromoteTriggerFile
Definition: xlog.c:297
bool CheckPromoteSignal(void)
Definition: xlog.c:12660
bool IsPromoteSignaled(void)
Definition: startup.c:234
static bool LocalPromoteIsTriggered
Definition: xlog.c:241
#define LOG
Definition: elog.h:26
static void SetPromoteIsTriggered(void)
Definition: xlog.c:12597
#define ERROR
Definition: elog.h:43
struct stat stat_buf
Definition: pg_standby.c:100
int errcode_for_file_access(void)
Definition: elog.c:633
void RemovePromoteSignalFiles(void)
Definition: xlog.c:12651
#define ereport(elevel,...)
Definition: elog.h:144
void ResetPromoteSignaled(void)
Definition: startup.c:240
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define stat
Definition: win32_port.h:275

◆ CheckPointGuts()

static void CheckPointGuts ( XLogRecPtr  checkPointRedo,
int  flags 
)
static

Definition at line 9175 of file xlog.c.

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

Referenced by CreateCheckPoint(), and CreateRestartPoint().

9176 {
9182 
9183  /* Write out all dirty data in SLRUs and the main buffer pool */
9184  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_START(flags);
9186  CheckPointCLOG();
9191  CheckPointBuffers(flags);
9192 
9193  /* Perform all queued up fsyncs */
9194  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_SYNC_START();
9198  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_DONE();
9199 
9200  /* We deliberately delay 2PC checkpointing as long as possible */
9201  CheckPointTwoPhase(checkPointRedo);
9202 }
void ProcessSyncRequests(void)
Definition: sync.c:258
void CheckPointBuffers(int flags)
Definition: bufmgr.c:2637
TimestampTz ckpt_sync_end_t
Definition: xlog.h:249
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1578
void CheckPointLogicalRewriteHeap(void)
Definition: rewriteheap.c:1195
void CheckPointReplicationOrigin(void)
Definition: origin.c:540
void CheckPointSnapBuild(void)
Definition: snapbuild.c:1933
void CheckPointCLOG(void)
Definition: clog.c:817
void CheckPointMultiXact(void)
Definition: multixact.c:2150
void CheckPointCommitTs(void)
Definition: commit_ts.c:806
CheckpointStatsData CheckpointStats
Definition: xlog.c:186
TimestampTz ckpt_write_t
Definition: xlog.h:247
void CheckPointSUBTRANS(void)
Definition: subtrans.c:283
void CheckPointRelationMap(void)
Definition: relmapper.c:546
TimestampTz ckpt_sync_t
Definition: xlog.h:248
void CheckPointPredicate(void)
Definition: predicate.c:1013
void CheckPointTwoPhase(XLogRecPtr redo_horizon)
Definition: twophase.c:1691
void CheckPointReplicationSlots(void)
Definition: slot.c:1271

◆ CheckPromoteSignal()

bool CheckPromoteSignal ( void  )

Definition at line 12660 of file xlog.c.

References PROMOTE_SIGNAL_FILE, and stat.

Referenced by CheckForStandbyTrigger(), and sigusr1_handler().

12661 {
12662  struct stat stat_buf;
12663 
12664  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
12665  return true;
12666 
12667  return false;
12668 }
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:396
struct stat stat_buf
Definition: pg_standby.c:100
#define stat
Definition: win32_port.h:275

◆ CheckRecoveryConsistency()

static void CheckRecoveryConsistency ( void  )
static

Definition at line 7975 of file xlog.c.

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

Referenced by ReadRecord(), and StartupXLOG().

7976 {
7977  XLogRecPtr lastReplayedEndRecPtr;
7978 
7979  /*
7980  * During crash recovery, we don't reach a consistent state until we've
7981  * replayed all the WAL.
7982  */
7984  return;
7985 
7987 
7988  /*
7989  * assume that we are called in the startup process, and hence don't need
7990  * a lock to read lastReplayedEndRecPtr
7991  */
7992  lastReplayedEndRecPtr = XLogCtl->lastReplayedEndRecPtr;
7993 
7994  /*
7995  * Have we reached the point where our base backup was completed?
7996  */
7998  ControlFile->backupEndPoint <= lastReplayedEndRecPtr)
7999  {
8000  /*
8001  * We have reached the end of base backup, as indicated by pg_control.
8002  * The data on disk is now consistent. Reset backupStartPoint and
8003  * backupEndPoint, and update minRecoveryPoint to make sure we don't
8004  * allow starting up at an earlier point even if recovery is stopped
8005  * and restarted soon after this.
8006  */
8007  elog(DEBUG1, "end of backup reached");
8008 
8009  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8010 
8011  if (ControlFile->minRecoveryPoint < lastReplayedEndRecPtr)
8012  ControlFile->minRecoveryPoint = lastReplayedEndRecPtr;
8013 
8016  ControlFile->backupEndRequired = false;
8018 
8019  LWLockRelease(ControlFileLock);
8020  }
8021 
8022  /*
8023  * Have we passed our safe starting point? Note that minRecoveryPoint is
8024  * known to be incorrectly set if ControlFile->backupEndRequired, until
8025  * the XLOG_BACKUP_END arrives to advise us of the correct
8026  * minRecoveryPoint. All we know prior to that is that we're not
8027  * consistent yet.
8028  */
8030  minRecoveryPoint <= lastReplayedEndRecPtr &&
8032  {
8033  /*
8034  * Check to see if the XLOG sequence contained any unresolved
8035  * references to uninitialized pages.
8036  */
8038 
8039  reachedConsistency = true;
8040  ereport(LOG,
8041  (errmsg("consistent recovery state reached at %X/%X",
8042  (uint32) (lastReplayedEndRecPtr >> 32),
8043  (uint32) lastReplayedEndRecPtr)));
8044  }
8045 
8046  /*
8047  * Have we got a valid starting snapshot that will allow queries to be
8048  * run? If so, we can tell postmaster that the database is consistent now,
8049  * enabling connections.
8050  */
8055  {
8059 
8060  LocalHotStandbyActive = true;
8061 
8063  }
8064 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define DEBUG1
Definition: elog.h:25
void XLogCheckInvalidPages(void)
Definition: xlogutils.c:224
bool SharedHotStandbyActive
Definition: xlog.c:665
slock_t info_lck
Definition: xlog.c:726
#define LOG
Definition: elog.h:26
bool InArchiveRecovery
Definition: xlog.c:267
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
bool backupEndRequired
Definition: pg_control.h:170
#define SpinLockAcquire(lock)
Definition: spin.h:62
static bool LocalHotStandbyActive
Definition: xlog.c:235
void UpdateControlFile(void)
Definition: xlog.c:4904
bool IsUnderPostmaster
Definition: globals.c:109
unsigned int uint32
Definition: c.h:375
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
#define SpinLockRelease(lock)
Definition: spin.h:64
static ControlFileData * ControlFile
Definition: xlog.c:737
#define ereport(elevel,...)
Definition: elog.h:144
XLogRecPtr backupEndPoint
Definition: pg_control.h:169
bool reachedConsistency
Definition: xlog.c:870
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:746
static XLogCtlData * XLogCtl
Definition: xlog.c:729
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define elog(elevel,...)
Definition: elog.h:214
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:146
HotStandbyState standbyState
Definition: xlog.c:208
XLogRecPtr backupStartPoint
Definition: pg_control.h:168
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:861
XLogRecPtr lastReplayedEndRecPtr
Definition: xlog.c:705

◆ CheckRequiredParameterValues()

static void CheckRequiredParameterValues ( void  )
static

Definition at line 6258 of file xlog.c.

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

Referenced by StartupXLOG(), and xlog_redo().

6259 {
6260  /*
6261  * For archive recovery, the WAL must be generated with at least 'replica'
6262  * wal_level.
6263  */
6265  {
6266  ereport(WARNING,
6267  (errmsg("WAL was generated with wal_level=minimal, data may be missing"),
6268  errhint("This happens if you temporarily set wal_level=minimal without taking a new base backup.")));
6269  }
6270 
6271  /*
6272  * For Hot Standby, the WAL must be generated with 'replica' mode, and we
6273  * must have at least as many backend slots as the primary.
6274  */
6276  {
6278  ereport(ERROR,
6279  (errmsg("hot standby is not possible because wal_level was not set to \"replica\" or higher on the primary server"),
6280  errhint("Either set wal_level to \"replica\" on the primary, or turn off hot_standby here.")));
6281 
6282  /* We ignore autovacuum_max_workers when we make this test. */
6283  RecoveryRequiresIntParameter("max_connections",
6286  RecoveryRequiresIntParameter("max_worker_processes",
6289  RecoveryRequiresIntParameter("max_wal_senders",
6292  RecoveryRequiresIntParameter("max_prepared_transactions",
6295  RecoveryRequiresIntParameter("max_locks_per_transaction",
6298  }
6299 }
bool ArchiveRecoveryRequested
Definition: xlog.c:266
int max_locks_per_xact
Definition: pg_control.h:182
int errhint(const char *fmt,...)
Definition: elog.c:1068
int max_prepared_xacts
Definition: pg_control.h:181
int max_worker_processes
Definition: pg_control.h:179
#define ERROR
Definition: elog.h:43
int max_prepared_xacts
Definition: twophase.c:117
int max_locks_per_xact
Definition: lock.c:54
int max_wal_senders
Definition: walsender.c:121
#define WARNING
Definition: elog.h:40
int MaxConnections
Definition: globals.c:133
static ControlFileData * ControlFile
Definition: xlog.c:737
#define ereport(elevel,...)
Definition: elog.h:144
bool EnableHotStandby
Definition: xlog.c:97
int errmsg(const char *fmt,...)
Definition: elog.c:821
int max_worker_processes
Definition: globals.c:134
#define RecoveryRequiresIntParameter(param_name, currValue, minValue)
Definition: xlog.c:6238

◆ checkTimeLineSwitch()

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

Definition at line 9865 of file xlog.c.

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

Referenced by StartupXLOG().

9866 {
9867  /* Check that the record agrees on what the current (old) timeline is */
9868  if (prevTLI != ThisTimeLineID)
9869  ereport(PANIC,
9870  (errmsg("unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record",
9871  prevTLI, ThisTimeLineID)));
9872 
9873  /*
9874  * The new timeline better be in the list of timelines we expect to see,
9875  * according to the timeline history. It should also not decrease.
9876  */
9877  if (newTLI < ThisTimeLineID || !tliInHistory(newTLI, expectedTLEs))
9878  ereport(PANIC,
9879  (errmsg("unexpected timeline ID %u (after %u) in checkpoint record",
9880  newTLI, ThisTimeLineID)));
9881 
9882  /*
9883  * If we have not yet reached min recovery point, and we're about to
9884  * switch to a timeline greater than the timeline of the min recovery
9885  * point: trouble. After switching to the new timeline, we could not
9886  * possibly visit the min recovery point on the correct timeline anymore.
9887  * This can happen if there is a newer timeline in the archive that
9888  * branched before the timeline the min recovery point is on, and you
9889  * attempt to do PITR to the new timeline.
9890  */
9892  lsn < minRecoveryPoint &&
9893  newTLI > minRecoveryPointTLI)
9894  ereport(PANIC,
9895  (errmsg("unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u",
9896  newTLI,
9897  (uint32) (minRecoveryPoint >> 32),
9900 
9901  /* Looks good */
9902 }
static List * expectedTLEs
Definition: xlog.c:342
#define PANIC
Definition: elog.h:53
unsigned int uint32
Definition: c.h:375
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
static TimeLineID minRecoveryPointTLI
Definition: xlog.c:862
TimeLineID ThisTimeLineID
Definition: xlog.c:192
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:821
bool tliInHistory(TimeLineID tli, List *expectedTLEs)
Definition: timeline.c:534
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:861

◆ checkXLogConsistency()

static void checkXLogConsistency ( XLogReaderState record)
static

Definition at line 1406 of file xlog.c.

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

1407 {
1408  RmgrId rmid = XLogRecGetRmid(record);
1409  RelFileNode rnode;
1410  ForkNumber forknum;
1411  BlockNumber blkno;
1412  int block_id;
1413 
1414  /* Records with no backup blocks have no need for consistency checks. */
1415  if (!XLogRecHasAnyBlockRefs(record))
1416  return;
1417 
1418  Assert((XLogRecGetInfo(record) & XLR_CHECK_CONSISTENCY) != 0);
1419 
1420  for (block_id = 0; block_id <= record->max_block_id; block_id++)
1421  {
1422  Buffer buf;
1423  Page page;
1424 
1425  if (!XLogRecGetBlockTag(record, block_id, &rnode, &forknum, &blkno))
1426  {
1427  /*
1428  * WAL record doesn't contain a block reference with the given id.
1429  * Do nothing.
1430  */
1431  continue;
1432  }
1433 
1434  Assert(XLogRecHasBlockImage(record, block_id));
1435 
1436  if (XLogRecBlockImageApply(record, block_id))
1437  {
1438  /*
1439  * WAL record has already applied the page, so bypass the
1440  * consistency check as that would result in comparing the full
1441  * page stored in the record with itself.
1442  */
1443  continue;
1444  }
1445 
1446  /*
1447  * Read the contents from the current buffer and store it in a
1448  * temporary page.
1449  */
1450  buf = XLogReadBufferExtended(rnode, forknum, blkno,
1452  if (!BufferIsValid(buf))
1453  continue;
1454 
1456  page = BufferGetPage(buf);
1457 
1458  /*
1459  * Take a copy of the local page where WAL has been applied to have a
1460  * comparison base before masking it...
1461  */
1462  memcpy(replay_image_masked, page, BLCKSZ);
1463 
1464  /* No need for this page anymore now that a copy is in. */
1465  UnlockReleaseBuffer(buf);
1466 
1467  /*
1468  * If the block LSN is already ahead of this WAL record, we can't
1469  * expect contents to match. This can happen if recovery is
1470  * restarted.
1471  */
1472  if (PageGetLSN(replay_image_masked) > record->EndRecPtr)
1473  continue;
1474 
1475  /*
1476  * Read the contents from the backup copy, stored in WAL record and
1477  * store it in a temporary page. There is no need to allocate a new
1478  * page here, a local buffer is fine to hold its contents and a mask
1479  * can be directly applied on it.
1480  */
1481  if (!RestoreBlockImage(record, block_id, primary_image_masked))
1482  elog(ERROR, "failed to restore block image");
1483 
1484  /*
1485  * If masking function is defined, mask both the primary and replay
1486  * images
1487  */
1488  if (RmgrTable[rmid].rm_mask != NULL)
1489  {
1490  RmgrTable[rmid].rm_mask(replay_image_masked, blkno);
1491  RmgrTable[rmid].rm_mask(primary_image_masked, blkno);
1492  }
1493 
1494  /* Time to compare the primary and replay images. */
1495  if (memcmp(replay_image_masked, primary_image_masked, BLCKSZ) != 0)
1496  {
1497  elog(FATAL,
1498  "inconsistent page found, rel %u/%u/%u, forknum %u, blkno %u",
1499  rnode.spcNode, rnode.dbNode, rnode.relNode,
1500  forknum, blkno);
1501  }
1502  }
1503 }
#define XLogRecHasBlockImage(decoder, block_id)
Definition: xlogreader.h:315
Buffer XLogReadBufferExtended(RelFileNode rnode, ForkNumber forknum, BlockNumber blkno, ReadBufferMode mode)
Definition: xlogutils.c:441
const RmgrData RmgrTable[RM_MAX_ID+1]
Definition: rmgr.c:36
uint32 BlockNumber
Definition: block.h:31
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:98
#define XLR_CHECK_CONSISTENCY
Definition: xlogrecord.h:80
XLogRecPtr EndRecPtr
Definition: xlogreader.h:176
static char * replay_image_masked
Definition: xlog.c:276
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3534
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
static char * buf
Definition: pg_test_fsync.c:68
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:305
ForkNumber
Definition: relpath.h:40
void(* rm_mask)(char *pagedata, BlockNumber blkno)
bool XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id, RelFileNode *rnode, ForkNumber *forknum, BlockNumber *blknum)
Definition: xlogreader.c:1498
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3750
uint8 RmgrId
Definition: rmgr.h:11
#define Assert(condition)
Definition: c.h:746
static char * primary_image_masked
Definition: xlog.c:277
#define BufferIsValid(bufnum)
Definition: bufmgr.h:123
bool RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page)
Definition: xlogreader.c:1551
#define PageGetLSN(page)
Definition: bufpage.h:366
#define elog(elevel,...)
Definition: elog.h:214
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:312
#define XLogRecBlockImageApply(decoder, block_id)
Definition: xlogreader.h:317
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:78
#define XLogRecGetRmid(decoder)
Definition: xlogreader.h:306

◆ CheckXLogRemoved()

void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)

Definition at line 3928 of file xlog.c.

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

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

3929 {
3930  int save_errno = errno;
3931  XLogSegNo lastRemovedSegNo;
3932 
3934  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3936 
3937  if (segno <= lastRemovedSegNo)
3938  {
3939  char filename[MAXFNAMELEN];
3940 
3941  XLogFileName(filename, tli, segno, wal_segment_size);
3942  errno = save_errno;
3943  ereport(ERROR,
3945  errmsg("requested WAL segment %s has already been removed",
3946  filename)));
3947  }
3948  errno = save_errno;
3949 }
int wal_segment_size
Definition: xlog.c:117
slock_t info_lck
Definition: xlog.c:726
XLogSegNo lastRemovedSegNo
Definition: xlog.c:609
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define ERROR
Definition: elog.h:43
uint64 XLogSegNo
Definition: xlogdefs.h:41
int errcode_for_file_access(void)
Definition: elog.c:633
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
#define ereport(elevel,...)
Definition: elog.h:144
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static XLogCtlData * XLogCtl
Definition: xlog.c:729
static char * filename
Definition: pg_dumpall.c:91
int errmsg(const char *fmt,...)
Definition: elog.c:821

◆ CleanupBackupHistory()

static void CleanupBackupHistory ( void  )
static

Definition at line 4292 of file xlog.c.

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

Referenced by do_pg_stop_backup().

4293 {
4294  DIR *xldir;
4295  struct dirent *xlde;
4296  char path[MAXPGPATH + sizeof(XLOGDIR)];
4297 
4298  xldir = AllocateDir(XLOGDIR);
4299 
4300  while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
4301  {
4302  if (IsBackupHistoryFileName(xlde->d_name))
4303  {
4304  if (XLogArchiveCheckDone(xlde->d_name))
4305  {
4306  elog(DEBUG2, "removing WAL backup history file \"%s\"",
4307  xlde->d_name);
4308  snprintf(path, sizeof(path), XLOGDIR "/%s", xlde->d_name);
4309  unlink(path);
4310  XLogArchiveCleanup(xlde->d_name);
4311  }
4312  }
4313  }
4314 
4315  FreeDir(xldir);
4316 }
Definition: dirent.h:9
void XLogArchiveCleanup(const char *xlog)
Definition: xlogarchive.c:718
Definition: dirent.c:25
bool XLogArchiveCheckDone(const char *xlog)
Definition: xlogarchive.c:571
#define MAXPGPATH
#define DEBUG2
Definition: elog.h:24
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2583
#define IsBackupHistoryFileName(fname)
#define XLOGDIR
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2649
#define elog(elevel,...)
Definition: elog.h:214
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:215
int FreeDir(DIR *dir)
Definition: fd.c:2701

◆ CopyXLogRecordToWAL()

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

Definition at line 1510 of file xlog.c.

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

Referenced by XLogInsertRecord().

1512 {
1513  char *currpos;
1514  int freespace;
1515  int written;
1516  XLogRecPtr CurrPos;
1517  XLogPageHeader pagehdr;
1518 
1519  /*
1520  * Get a pointer to the right place in the right WAL buffer to start
1521  * inserting to.
1522  */
1523  CurrPos = StartPos;
1524  currpos = GetXLogBuffer(CurrPos);
1525  freespace = INSERT_FREESPACE(CurrPos);
1526 
1527  /*
1528  * there should be enough space for at least the first field (xl_tot_len)
1529  * on this page.
1530  */
1531  Assert(freespace >= sizeof(uint32));
1532 
1533  /* Copy record data */
1534  written = 0;
1535  while (rdata != NULL)
1536  {
1537  char *rdata_data = rdata->data;
1538  int rdata_len = rdata->len;
1539 
1540  while (rdata_len > freespace)
1541  {
1542  /*
1543  * Write what fits on this page, and continue on the next page.
1544  */
1545  Assert(CurrPos % XLOG_BLCKSZ >= SizeOfXLogShortPHD || freespace == 0);
1546  memcpy(currpos, rdata_data, freespace);
1547  rdata_data += freespace;
1548  rdata_len -= freespace;
1549  written += freespace;
1550  CurrPos += freespace;
1551 
1552  /*
1553  * Get pointer to beginning of next page, and set the xlp_rem_len
1554  * in the page header. Set XLP_FIRST_IS_CONTRECORD.
1555  *
1556  * It's safe to set the contrecord flag and xlp_rem_len without a
1557  * lock on the page. All the other flags were already set when the
1558  * page was initialized, in AdvanceXLInsertBuffer, and we're the
1559  * only backend that needs to set the contrecord flag.
1560  */
1561  currpos = GetXLogBuffer(CurrPos);
1562  pagehdr = (XLogPageHeader) currpos;
1563  pagehdr->xlp_rem_len = write_len - written;
1564  pagehdr->xlp_info |= XLP_FIRST_IS_CONTRECORD;
1565 
1566  /* skip over the page header */
1567  if (XLogSegmentOffset(CurrPos, wal_segment_size) == 0)
1568  {
1569  CurrPos += SizeOfXLogLongPHD;
1570  currpos += SizeOfXLogLongPHD;
1571  }
1572  else
1573  {
1574  CurrPos += SizeOfXLogShortPHD;
1575  currpos += SizeOfXLogShortPHD;
1576  }
1577  freespace = INSERT_FREESPACE(CurrPos);
1578  }
1579 
1580  Assert(CurrPos % XLOG_BLCKSZ >= SizeOfXLogShortPHD || rdata_len == 0);
1581  memcpy(currpos, rdata_data, rdata_len);
1582  currpos += rdata_len;
1583  CurrPos += rdata_len;
1584  freespace -= rdata_len;
1585  written += rdata_len;
1586 
1587  rdata = rdata->next;
1588  }
1589  Assert(written == write_len);
1590 
1591  /*
1592  * If this was an xlog-switch, it's not enough to write the switch record,
1593  * we also have to consume all the remaining space in the WAL segment. We
1594  * have already reserved that space, but we need to actually fill it.
1595  */
1596  if (isLogSwitch && XLogSegmentOffset(CurrPos, wal_segment_size) != 0)
1597  {
1598  /* An xlog-switch record doesn't contain any data besides the header */
1599  Assert(write_len == SizeOfXLogRecord);
1600 
1601  /* Assert that we did reserve the right amount of space */
1602  Assert(XLogSegmentOffset(EndPos, wal_segment_size) == 0);
1603 
1604  /* Use up all the remaining space on the current page */
1605  CurrPos += freespace;
1606 
1607  /*
1608  * Cause all remaining pages in the segment to be flushed, leaving the
1609  * XLog position where it should be, at the start of the next segment.
1610  * We do this one page at a time, to make sure we don't deadlock
1611  * against ourselves if wal_buffers < wal_segment_size.
1612  */
1613  while (CurrPos < EndPos)
1614  {
1615  /*
1616  * The minimal action to flush the page would be to call
1617  * WALInsertLockUpdateInsertingAt(CurrPos) followed by
1618  * AdvanceXLInsertBuffer(...). The page would be left initialized
1619  * mostly to zeros, except for the page header (always the short
1620  * variant, as this is never a segment's first page).
1621  *
1622  * The large vistas of zeros are good for compressibility, but the
1623  * headers interrupting them every XLOG_BLCKSZ (with values that
1624  * differ from page to page) are not. The effect varies with
1625  * compression tool, but bzip2 for instance compresses about an
1626  * order of magnitude worse if those headers are left in place.
1627  *
1628  * Rather than complicating AdvanceXLInsertBuffer itself (which is
1629  * called in heavily-loaded circumstances as well as this lightly-
1630  * loaded one) with variant behavior, we just use GetXLogBuffer
1631  * (which itself calls the two methods we need) to get the pointer
1632  * and zero most of the page. Then we just zero the page header.
1633  */
1634  currpos = GetXLogBuffer(CurrPos);
1635  MemSet(currpos, 0, SizeOfXLogShortPHD);
1636 
1637  CurrPos += XLOG_BLCKSZ;
1638  }
1639  }
1640  else
1641  {
1642  /* Align the end position, so that the next record starts aligned */
1643  CurrPos = MAXALIGN64(CurrPos);
1644  }
1645 
1646  if (CurrPos != EndPos)
1647  elog(PANIC, "space reserved for WAL record does not match what was written");
1648 }
int wal_segment_size
Definition: xlog.c:117
#define MemSet(start, val, len)
Definition: c.h:950
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:54
#define PANIC
Definition: elog.h:53
static char * GetXLogBuffer(XLogRecPtr ptr)
Definition: xlog.c:1886
#define MAXALIGN64(LEN)
Definition: c.h:724
unsigned int uint32
Definition: c.h:375
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:743
#define SizeOfXLogRecord
Definition: xlogrecord.h:55
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:746
#define SizeOfXLogShortPHD
Definition: xlog_internal.h:52
#define XLP_FIRST_IS_CONTRECORD
Definition: xlog_internal.h:74
struct XLogRecData * next
#define elog(elevel,...)
Definition: elog.h:214
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:69

◆ CreateCheckPoint()

void CreateCheckPoint ( int  flags)

Definition at line 8704 of file xlog.c.

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

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

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

◆ CreateEndOfRecoveryRecord()

static void CreateEndOfRecoveryRecord ( void  )
static

Definition at line 9126 of file xlog.c.

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

Referenced by StartupXLOG().

9127 {
9128  xl_end_of_recovery xlrec;
9129  XLogRecPtr recptr;
9130 
9131  /* sanity check */
9132  if (!RecoveryInProgress())
9133  elog(ERROR, "can only be used to end recovery");
9134 
9135  xlrec.end_time = GetCurrentTimestamp();
9136 
9141 
9143 
9145 
9146  XLogBeginInsert();
9147  XLogRegisterData((char *) &xlrec, sizeof(xl_end_of_recovery));
9148  recptr = XLogInsert(RM_XLOG_ID, XLOG_END_OF_RECOVERY);
9149 
9150  XLogFlush(recptr);
9151 
9152  /*
9153  * Update the control file so that crash recovery can follow the timeline
9154  * changes to this point.
9155  */
9156  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9157  ControlFile->time = (pg_time_t) time(NULL);
9158  ControlFile->minRecoveryPoint = recptr;
9161  LWLockRelease(ControlFileLock);
9162 
9163  END_CRIT_SECTION();
9164 
9165  LocalXLogInsertAllowed = -1; /* return to "check" state */
9166 }
static int LocalXLogInsertAllowed
Definition: xlog.c:253
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1728
pg_time_t time
Definition: pg_control.h:128
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
TimeLineID PrevTimeLineID
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1578
#define END_CRIT_SECTION()
Definition: miscadmin.h:134
TimeLineID PrevTimeLineID
Definition: xlog.c:653
#define START_CRIT_SECTION()
Definition: miscadmin.h:132
bool RecoveryInProgress(void)
Definition: xlog.c:8076
#define XLOG_END_OF_RECOVERY
Definition: pg_control.h:76
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2847
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
void UpdateControlFile(void)
Definition: xlog.c:4904
#define ERROR
Definition: elog.h:43
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8220
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:330
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:422
static ControlFileData * ControlFile
Definition: xlog.c:737
TimeLineID ThisTimeLineID
Definition: xlog.c:192
TimestampTz end_time
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1699
static XLogCtlData * XLogCtl
Definition: xlog.c:729
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208
TimeLineID ThisTimeLineID
#define elog(elevel,...)
Definition: elog.h:214
void XLogBeginInsert(void)
Definition: xloginsert.c:123
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166

◆ CreateRestartPoint()

bool CreateRestartPoint ( int  flags)

Definition at line 9257 of file xlog.c.

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

Referenced by CheckpointerMain(), and ShutdownXLOG().

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

◆ DataChecksumsEnabled()

bool DataChecksumsEnabled ( void  )

Definition at line 4933 of file xlog.c.

References Assert, and ControlFileData::data_checksum_version.

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

4934 {
4935  Assert(ControlFile != NULL);
4936  return (ControlFile->data_checksum_version > 0);
4937 }
uint32 data_checksum_version
Definition: pg_control.h:220
static ControlFileData * ControlFile
Definition: xlog.c:737
#define Assert(condition)
Definition: c.h:746

◆ do_pg_abort_backup()

void do_pg_abort_backup ( int  code,
Datum  arg 
)

Definition at line 11452 of file xlog.c.

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

Referenced by perform_base_backup(), and register_persistent_abort_backup_handler().

11453 {
11454  bool emit_warning = DatumGetBool(arg);
11455 
11456  /*
11457  * Quick exit if session is not keeping around a non-exclusive backup
11458  * already started.
11459  */
11461  return;
11462 
11466 
11469  {
11470  XLogCtl->Insert.forcePageWrites = false;
11471  }
11473 
11474  if (emit_warning)
11475  ereport(WARNING,
11476  (errmsg("aborting backup due to backend exiting before pg_stop_backup was called")));
11477 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1728
static SessionBackupState sessionBackupState
Definition: xlog.c:534
XLogCtlInsert Insert
Definition: xlog.c:600
bool forcePageWrites
Definition: xlog.c:574
#define DatumGetBool(X)
Definition: postgres.h:393
#define WARNING
Definition: elog.h:40
int nonExclusiveBackups
Definition: xlog.c:586
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:585
#define ereport(elevel,...)
Definition: elog.h:144
#define Assert(condition)
Definition: c.h:746
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1699
static XLogCtlData * XLogCtl
Definition: xlog.c:729
int errmsg(const char *fmt,...)
Definition: elog.c:821
void * arg

◆ do_pg_start_backup()

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

Definition at line 10521 of file xlog.c.

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

Referenced by perform_base_backup(), and pg_start_backup().

10524 {
10525  bool exclusive = (labelfile == NULL);
10526  bool backup_started_in_recovery = false;
10527  XLogRecPtr checkpointloc;
10528  XLogRecPtr startpoint;
10529  TimeLineID starttli;
10530  pg_time_t stamp_time;
10531  char strfbuf[128];
10532  char xlogfilename[MAXFNAMELEN];
10533  XLogSegNo _logSegNo;
10534  struct stat stat_buf;
10535  FILE *fp;
10536 
10537  backup_started_in_recovery = RecoveryInProgress();
10538 
10539  /*
10540  * Currently only non-exclusive backup can be taken during recovery.
10541  */
10542  if (backup_started_in_recovery && exclusive)
10543  ereport(ERROR,
10544  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10545  errmsg("recovery is in progress"),
10546  errhint("WAL control functions cannot be executed during recovery.")));
10547 
10548  /*
10549  * During recovery, we don't need to check WAL level. Because, if WAL
10550  * level is not sufficient, it's impossible to get here during recovery.
10551  */
10552  if (!backup_started_in_recovery && !XLogIsNeeded())
10553  ereport(ERROR,
10554  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10555  errmsg("WAL level not sufficient for making an online backup"),
10556  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
10557 
10558  if (strlen(backupidstr) > MAXPGPATH)
10559  ereport(ERROR,
10560  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
10561  errmsg("backup label too long (max %d bytes)",
10562  MAXPGPATH)));
10563 
10564  /*
10565  * Mark backup active in shared memory. We must do full-page WAL writes
10566  * during an on-line backup even if not doing so at other times, because
10567  * it's quite possible for the backup dump to obtain a "torn" (partially
10568  * written) copy of a database page if it reads the page concurrently with
10569  * our write to the same page. This can be fixed as long as the first
10570  * write to the page in the WAL sequence is a full-page write. Hence, we
10571  * turn on forcePageWrites and then force a CHECKPOINT, to ensure there
10572  * are no dirty pages in shared memory that might get dumped while the
10573  * backup is in progress without having a corresponding WAL record. (Once
10574  * the backup is complete, we need not force full-page writes anymore,
10575  * since we expect that any pages not modified during the backup interval
10576  * must have been correctly captured by the backup.)
10577  *
10578  * Note that forcePageWrites has no effect during an online backup from
10579  * the standby.
10580  *
10581  * We must hold all the insertion locks to change the value of
10582  * forcePageWrites, to ensure adequate interlocking against
10583  * XLogInsertRecord().
10584  */
10586  if (exclusive)
10587  {
10588  /*
10589  * At first, mark that we're now starting an exclusive backup, to
10590  * ensure that there are no other sessions currently running
10591  * pg_start_backup() or pg_stop_backup().
10592  */
10594  {
10596  ereport(ERROR,
10597  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10598  errmsg("a backup is already in progress"),
10599  errhint("Run pg_stop_backup() and try again.")));
10600  }
10602  }
10603  else
10605  XLogCtl->Insert.forcePageWrites = true;
10607 
10608  /* Ensure we release forcePageWrites if fail below */
10610  {
10611  bool gotUniqueStartpoint = false;
10612  DIR *tblspcdir;
10613  struct dirent *de;
10614  tablespaceinfo *ti;
10615  int datadirpathlen;
10616 
10617  /*
10618  * Force an XLOG file switch before the checkpoint, to ensure that the
10619  * WAL segment the checkpoint is written to doesn't contain pages with
10620  * old timeline IDs. That would otherwise happen if you called
10621  * pg_start_backup() right after restoring from a PITR archive: the
10622  * first WAL segment containing the startup checkpoint has pages in
10623  * the beginning with the old timeline ID. That can cause trouble at
10624  * recovery: we won't have a history file covering the old timeline if
10625  * pg_wal directory was not included in the base backup and the WAL
10626  * archive was cleared too before starting the backup.
10627  *
10628  * This also ensures that we have emitted a WAL page header that has
10629  * XLP_BKP_REMOVABLE off before we emit the checkpoint record.
10630  * Therefore, if a WAL archiver (such as pglesslog) is trying to
10631  * compress out removable backup blocks, it won't remove any that
10632  * occur after this point.
10633  *
10634  * During recovery, we skip forcing XLOG file switch, which means that
10635  * the backup taken during recovery is not available for the special
10636  * recovery case described above.
10637  */
10638  if (!backup_started_in_recovery)
10639  RequestXLogSwitch(false);
10640 
10641  do
10642  {
10643  bool checkpointfpw;
10644 
10645  /*
10646  * Force a CHECKPOINT. Aside from being necessary to prevent torn
10647  * page problems, this guarantees that two successive backup runs
10648  * will have different checkpoint positions and hence different
10649  * history file names, even if nothing happened in between.
10650  *
10651  * During recovery, establish a restartpoint if possible. We use
10652  * the last restartpoint as the backup starting checkpoint. This
10653  * means that two successive backup runs can have same checkpoint
10654  * positions.
10655  *
10656  * Since the fact that we are executing do_pg_start_backup()
10657  * during recovery means that checkpointer is running, we can use
10658  * RequestCheckpoint() to establish a restartpoint.
10659  *
10660  * We use CHECKPOINT_IMMEDIATE only if requested by user (via
10661  * passing fast = true). Otherwise this can take awhile.
10662  */
10664  (fast ? CHECKPOINT_IMMEDIATE : 0));
10665 
10666  /*
10667  * Now we need to fetch the checkpoint record location, and also
10668  * its REDO pointer. The oldest point in WAL that would be needed
10669  * to restore starting from the checkpoint is precisely the REDO
10670  * pointer.
10671  */
10672  LWLockAcquire(ControlFileLock, LW_SHARED);
10673  checkpointloc = ControlFile->checkPoint;
10674  startpoint = ControlFile->checkPointCopy.redo;
10676  checkpointfpw = ControlFile->checkPointCopy.fullPageWrites;
10677  LWLockRelease(ControlFileLock);
10678 
10679  if (backup_started_in_recovery)
10680  {
10681  XLogRecPtr recptr;
10682 
10683  /*
10684  * Check to see if all WAL replayed during online backup
10685  * (i.e., since last restartpoint used as backup starting
10686  * checkpoint) contain full-page writes.
10687  */
10689  recptr = XLogCtl->lastFpwDisableRecPtr;
10691 
10692  if (!checkpointfpw || startpoint <= recptr)
10693  ereport(ERROR,
10694  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10695  errmsg("WAL generated with full_page_writes=off was replayed "
10696  "since last restartpoint"),
10697  errhint("This means that the backup being taken on the standby "
10698  "is corrupt and should not be used. "
10699  "Enable full_page_writes and run CHECKPOINT on the primary, "
10700  "and then try an online backup again.")));
10701 
10702  /*
10703  * During recovery, since we don't use the end-of-backup WAL
10704  * record and don't write the backup history file, the
10705  * starting WAL location doesn't need to be unique. This means
10706  * that two base backups started at the same time might use
10707  * the same checkpoint as starting locations.
10708  */
10709  gotUniqueStartpoint = true;
10710  }
10711 
10712  /*
10713  * If two base backups are started at the same time (in WAL sender
10714  * processes), we need to make sure that they use different
10715  * checkpoints as starting locations, because we use the starting
10716  * WAL location as a unique identifier for the base backup in the
10717  * end-of-backup WAL record and when we write the backup history
10718  * file. Perhaps it would be better generate a separate unique ID
10719  * for each backup instead of forcing another checkpoint, but
10720  * taking a checkpoint right after another is not that expensive
10721  * either because only few buffers have been dirtied yet.
10722  */
10724  if (XLogCtl->Insert.lastBackupStart < startpoint)
10725  {
10726  XLogCtl->Insert.lastBackupStart = startpoint;
10727  gotUniqueStartpoint = true;
10728  }
10730  } while (!gotUniqueStartpoint);
10731 
10732  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
10733  XLogFileName(xlogfilename, starttli, _logSegNo, wal_segment_size);
10734 
10735  /*
10736  * Construct tablespace_map file
10737  */
10738  if (exclusive)
10739  tblspcmapfile = makeStringInfo();
10740 
10741  datadirpathlen = strlen(DataDir);
10742 
10743  /* Collect information about all tablespaces */
10744  tblspcdir = AllocateDir("pg_tblspc");
10745  while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL)
10746  {
10747  char fullpath[MAXPGPATH + 10];
10748  char linkpath[MAXPGPATH];
10749  char *relpath = NULL;
10750  int rllen;
10751  StringInfoData buflinkpath;
10752  char *s = linkpath;
10753 
10754  /* Skip special stuff */
10755  if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
10756  continue;
10757 
10758  snprintf(fullpath, sizeof(fullpath), "pg_tblspc/%s", de->d_name);
10759 
10760 #if defined(HAVE_READLINK) || defined(WIN32)
10761  rllen = readlink(fullpath, linkpath, sizeof(linkpath));
10762  if (rllen < 0)
10763  {
10764  ereport(WARNING,
10765  (errmsg("could not read symbolic link \"%s\": %m",
10766  fullpath)));
10767  continue;
10768  }
10769  else if (rllen >= sizeof(linkpath))
10770  {
10771  ereport(WARNING,
10772  (errmsg("symbolic link \"%s\" target is too long",
10773  fullpath)));
10774  continue;
10775  }
10776  linkpath[rllen] = '\0';
10777 
10778  /*
10779  * Add the escape character '\\' before newline in a string to
10780  * ensure that we can distinguish between the newline in the
10781  * tablespace path and end of line while reading tablespace_map
10782  * file during archive recovery.
10783  */
10784  initStringInfo(&buflinkpath);
10785 
10786  while (*s)
10787  {
10788  if ((*s == '\n' || *s == '\r') && needtblspcmapfile)
10789  appendStringInfoChar(&buflinkpath, '\\');
10790  appendStringInfoChar(&buflinkpath, *s++);
10791  }
10792 
10793  /*
10794  * Relpath holds the relative path of the tablespace directory
10795  * when it's located within PGDATA, or NULL if it's located
10796  * elsewhere.
10797  */
10798  if (rllen > datadirpathlen &&
10799  strncmp(linkpath, DataDir, datadirpathlen) == 0 &&
10800  IS_DIR_SEP(linkpath[datadirpathlen]))
10801  relpath = linkpath + datadirpathlen + 1;
10802 
10803  ti = palloc(sizeof(tablespaceinfo));
10804  ti->oid = pstrdup(de->d_name);
10805  ti->path = pstrdup(buflinkpath.data);
10806  ti->rpath = relpath ? pstrdup(relpath) : NULL;
10807  ti->size = -1;
10808 
10809  if (tablespaces)
10810  *tablespaces = lappend(*tablespaces, ti);
10811 
10812  appendStringInfo(tblspcmapfile, "%s %s\n", ti->oid, ti->path);
10813 
10814  pfree(buflinkpath.data);
10815 #else
10816 
10817  /*
10818  * If the platform does not have symbolic links, it should not be
10819  * possible to have tablespaces - clearly somebody else created
10820  * them. Warn about it and ignore.
10821  */
10822  ereport(WARNING,
10823  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
10824  errmsg("tablespaces are not supported on this platform")));
10825 #endif
10826  }
10827  FreeDir(tblspcdir);
10828 
10829  /*
10830  * Construct backup label file
10831  */
10832  if (exclusive)
10833  labelfile = makeStringInfo();
10834 
10835  /* Use the log timezone here, not the session timezone */
10836  stamp_time = (pg_time_t) time(NULL);
10837  pg_strftime(strfbuf, sizeof(strfbuf),
10838  "%Y-%m-%d %H:%M:%S %Z",
10839  pg_localtime(&stamp_time, log_timezone));
10840  appendStringInfo(labelfile, "START WAL LOCATION: %X/%X (file %s)\n",
10841  (uint32) (startpoint >> 32), (uint32) startpoint, xlogfilename);
10842  appendStringInfo(labelfile, "CHECKPOINT LOCATION: %X/%X\n",
10843  (uint32) (checkpointloc >> 32), (uint32) checkpointloc);
10844  appendStringInfo(labelfile, "BACKUP METHOD: %s\n",
10845  exclusive ? "pg_start_backup" : "streamed");
10846  appendStringInfo(labelfile, "BACKUP FROM: %s\n",
10847  backup_started_in_recovery ? "standby" : "primary");
10848  appendStringInfo(labelfile, "START TIME: %s\n", strfbuf);
10849  appendStringInfo(labelfile, "LABEL: %s\n", backupidstr);
10850  appendStringInfo(labelfile, "START TIMELINE: %u\n", starttli);
10851 
10852  /*
10853  * Okay, write the file, or return its contents to caller.
10854  */
10855  if (exclusive)
10856  {
10857  /*
10858  * Check for existing backup label --- implies a backup is already
10859  * running. (XXX given that we checked exclusiveBackupState
10860  * above, maybe it would be OK to just unlink any such label
10861  * file?)
10862  */
10863  if (stat(BACKUP_LABEL_FILE, &stat_buf) != 0)
10864  {
10865  if (errno != ENOENT)
10866  ereport(ERROR,
10868  errmsg("could not stat file \"%s\": %m",
10869  BACKUP_LABEL_FILE)));
10870  }
10871  else
10872  ereport(ERROR,
10873  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10874  errmsg("a backup is already in progress"),
10875  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
10876  BACKUP_LABEL_FILE)));
10877 
10878  fp = AllocateFile(BACKUP_LABEL_FILE, "w");
10879 
10880  if (!fp)
10881  ereport(ERROR,
10883  errmsg("could not create file \"%s\": %m",
10884  BACKUP_LABEL_FILE)));
10885  if (fwrite(labelfile->data, labelfile->len, 1, fp) != 1 ||
10886  fflush(fp) != 0 ||
10887  pg_fsync(fileno(fp)) != 0 ||
10888  ferror(fp) ||
10889  FreeFile(fp))
10890  ereport(ERROR,
10892  errmsg("could not write file \"%s\": %m",
10893  BACKUP_LABEL_FILE)));
10894  /* Allocated locally for exclusive backups, so free separately */
10895  pfree(labelfile->data);
10896  pfree(labelfile);
10897 
10898  /* Write backup tablespace_map file. */
10899  if (tblspcmapfile->len > 0)
10900  {
10901  if (stat(TABLESPACE_MAP, &stat_buf) != 0)
10902  {
10903  if (errno != ENOENT)
10904  ereport(ERROR,
10906  errmsg("could not stat file \"%s\": %m",
10907  TABLESPACE_MAP)));
10908  }
10909  else
10910  ereport(ERROR,
10911  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10912  errmsg("a backup is already in progress"),
10913  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
10914  TABLESPACE_MAP)));
10915 
10916  fp = AllocateFile(TABLESPACE_MAP, "w");
10917 
10918  if (!fp)
10919  ereport(ERROR,
10921  errmsg("could not create file \"%s\": %m",
10922  TABLESPACE_MAP)));
10923  if (fwrite(tblspcmapfile->data, tblspcmapfile->len, 1, fp) != 1 ||
10924  fflush(fp) != 0 ||
10925  pg_fsync(fileno(fp)) != 0 ||
10926  ferror(fp) ||
10927  FreeFile(fp))
10928  ereport(ERROR,
10930  errmsg("could not write file \"%s\": %m",
10931  TABLESPACE_MAP)));
10932  }
10933 
10934  /* Allocated locally for exclusive backups, so free separately */
10935  pfree(tblspcmapfile->data);
10936  pfree(tblspcmapfile);
10937  }
10938  }
10940 
10941  /*
10942  * Mark that start phase has correctly finished for an exclusive backup.
10943  * Session-level locks are updated as well to reflect that state.
10944  *
10945  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating backup
10946  * counters and session-level lock. Otherwise they can be updated
10947  * inconsistently, and which might cause do_pg_abort_backup() to fail.
10948  */
10949  if (exclusive)
10950  {
10953 
10954  /* Set session-level lock */
10957  }
10958  else
10960 
10961  /*
10962  * We're done. As a convenience, return the starting WAL location.
10963  */
10964  if (starttli_p)
10965  *starttli_p = starttli;
10966  return startpoint;
10967 }
size_t pg_strftime(char *s, size_t max, const char *format, const struct pg_tm *tm)
Definition: strftime.c:128
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9693
int errhint(const char *fmt,...)
Definition: elog.c:1068
uint32 TimeLineID
Definition: xlogdefs.h:52
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1728
int wal_segment_size
Definition: xlog.c:117
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:724
static SessionBackupState sessionBackupState
Definition: xlog.c:534
XLogRecPtr lastBackupStart
Definition: xlog.c:587
char * pstrdup(const char *in)
Definition: mcxt.c:1187
#define XLogIsNeeded()
Definition: xlog.h:191
char * rpath
Definition: basebackup.h:27
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
slock_t info_lck
Definition: xlog.c:726
int errcode(int sqlerrcode)
Definition: elog.c:610
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:600
bool RecoveryInProgress(void)
Definition: xlog.c:8076
static bool backup_started_in_recovery
Definition: basebackup.c:88
Definition: dirent.h:9
#define IS_DIR_SEP(ch)
Definition: port.h:84
pg_tz * log_timezone
Definition: pgtz.c:31
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
#define TABLESPACE_MAP
Definition: xlog.h:392
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:47
void pfree(void *pointer)
Definition: mcxt.c:1057
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
bool forcePageWrites
Definition: xlog.c:574
Definition: dirent.c:25
#define ERROR
Definition: elog.h:43
struct stat stat_buf
Definition: pg_standby.c:100
#define MAXPGPATH
uint64 XLogSegNo
Definition: xlogdefs.h:41
#define readlink(path, buf, size)
Definition: win32_port.h:228
int errcode_for_file_access(void)
Definition: elog.c:633
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2322
unsigned int uint32
Definition: c.h:375
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2583
#define CHECKPOINT_FORCE
Definition: xlog.h:225
List * lappend(List *list, void *datum)
Definition: list.c:321
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define WARNING
Definition: elog.h:40
int nonExclusiveBackups
Definition: xlog.c:586
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
static void pg_start_backup_callback(int code, Datum arg)
Definition: xlog.c:10971
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:585
uintptr_t Datum
Definition: postgres.h:367
static ControlFileData * ControlFile
Definition: xlog.c:737
#define BoolGetDatum(X)
Definition: postgres.h:402
#define ereport(elevel,...)
Definition: elog.h:144
bool fullPageWrites
Definition: pg_control.h:42
#define CHECKPOINT_WAIT
Definition: xlog.h:229
uint64 XLogRecPtr
Definition: xlogdefs.h:21
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2649
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1699
static XLogCtlData * XLogCtl
Definition: xlog.c:729
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208
#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:52
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1342
int FreeFile(FILE *file)
Definition: fd.c:2521
void * palloc(Size size)
Definition: mcxt.c:950
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:224
#define relpath(rnode, forknum)
Definition: relpath.h:87
char * DataDir
Definition: globals.c:62
#define BACKUP_LABEL_FILE
Definition: xlog.h:389
int pg_fsync(int fd)
Definition: fd.c:346
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:215
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:37
int FreeDir(DIR *dir)
Definition: fd.c:2701
#define stat
Definition: win32_port.h:275
void RequestCheckpoint(int flags)
Definition: checkpointer.c:916
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ do_pg_stop_backup()

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

Definition at line 11039 of file xlog.c.

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

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

11040 {
11041  bool exclusive = (labelfile == NULL);
11042  bool backup_started_in_recovery = false;
11043  XLogRecPtr startpoint;
11044  XLogRecPtr stoppoint;
11045  TimeLineID stoptli;
11046  pg_time_t stamp_time;
11047  char strfbuf[128];
11048  char histfilepath[MAXPGPATH];
11049  char startxlogfilename[MAXFNAMELEN];
11050  char stopxlogfilename[MAXFNAMELEN];
11051  char lastxlogfilename[MAXFNAMELEN];
11052  char histfilename[MAXFNAMELEN];
11053  char backupfrom[20];
11054  XLogSegNo _logSegNo;
11055  FILE *lfp;
11056  FILE *fp;
11057  char ch;
11058  int seconds_before_warning;
11059  int waits = 0;
11060  bool reported_waiting = false;
11061  char *remaining;
11062  char *ptr;
11063  uint32 hi,
11064  lo;
11065 
11066  backup_started_in_recovery = RecoveryInProgress();
11067 
11068  /*
11069  * Currently only non-exclusive backup can be taken during recovery.
11070  */
11071  if (backup_started_in_recovery && exclusive)
11072  ereport(ERROR,
11073  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11074  errmsg("recovery is in progress"),
11075  errhint("WAL control functions cannot be executed during recovery.")));
11076 
11077  /*
11078  * During recovery, we don't need to check WAL level. Because, if WAL
11079  * level is not sufficient, it's impossible to get here during recovery.
11080  */
11081  if (!backup_started_in_recovery && !XLogIsNeeded())
11082  ereport(ERROR,
11083  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11084  errmsg("WAL level not sufficient for making an online backup"),
11085  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
11086 
11087  if (exclusive)
11088  {
11089  /*
11090  * At first, mark that we're now stopping an exclusive backup, to
11091  * ensure that there are no other sessions currently running
11092  * pg_start_backup() or pg_stop_backup().
11093  */
11096  {
11098  ereport(ERROR,
11099  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11100  errmsg("exclusive backup not in progress")));
11101  }
11104 
11105  /*
11106  * Remove backup_label. In case of failure, the state for an exclusive
11107  * backup is switched back to in-progress.
11108  */
11110  {
11111  /*
11112  * Read the existing label file into memory.
11113  */
11114  struct stat statbuf;
11115  int r;
11116 
11117  if (stat(BACKUP_LABEL_FILE, &statbuf))
11118  {
11119  /* should not happen per the upper checks */
11120  if (errno != ENOENT)
11121  ereport(ERROR,
11123  errmsg("could not stat file \"%s\": %m",
11124  BACKUP_LABEL_FILE)));
11125  ereport(ERROR,
11126  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11127  errmsg("a backup is not in progress")));
11128  }
11129 
11130  lfp = AllocateFile(BACKUP_LABEL_FILE, "r");
11131  if (!lfp)
11132  {
11133  ereport(ERROR,
11135  errmsg("could not read file \"%s\": %m",
11136  BACKUP_LABEL_FILE)));
11137  }
11138  labelfile = palloc(statbuf.st_size + 1);
11139  r = fread(labelfile, statbuf.st_size, 1, lfp);
11140  labelfile[statbuf.st_size] = '\0';
11141 
11142  /*
11143  * Close and remove the backup label file
11144  */
11145  if (r != 1 || ferror(lfp) || FreeFile(lfp))
11146  ereport(ERROR,
11148  errmsg("could not read file \"%s\": %m",
11149  BACKUP_LABEL_FILE)));
11151 
11152  /*
11153  * Remove tablespace_map file if present, it is created only if
11154  * there are tablespaces.
11155  */
11157  }
11159  }
11160 
11161  /*
11162  * OK to update backup counters, forcePageWrites and session-level lock.
11163  *
11164  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating them.
11165  * Otherwise they can be updated inconsistently, and which might cause
11166  * do_pg_abort_backup() to fail.
11167  */
11169  if (exclusive)
11170  {
11172  }
11173  else
11174  {
11175  /*
11176  * The user-visible pg_start/stop_backup() functions that operate on
11177  * exclusive backups can be called at any time, but for non-exclusive
11178  * backups, it is expected that each do_pg_start_backup() call is
11179  * matched by exactly one do_pg_stop_backup() call.
11180  */
11183  }
11184 
11187  {
11188  XLogCtl->Insert.forcePageWrites = false;
11189  }
11190 
11191  /*
11192  * Clean up session-level lock.
11193  *
11194  * You might think that WALInsertLockRelease() can be called before
11195  * cleaning up session-level lock because session-level lock doesn't need
11196  * to be protected with WAL insertion lock. But since
11197  * CHECK_FOR_INTERRUPTS() can occur in it, session-level lock must be
11198  * cleaned up before it.
11199  */
11201 
11203 
11204  /*
11205  * Read and parse the START WAL LOCATION line (this code is pretty crude,
11206  * but we are not expecting any variability in the file format).
11207  */
11208  if (sscanf(labelfile, "START WAL LOCATION: %X/%X (file %24s)%c",
11209  &hi, &lo, startxlogfilename,
11210  &ch) != 4 || ch != '\n')
11211  ereport(ERROR,
11212  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11213  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
11214  startpoint = ((uint64) hi) << 32 | lo;
11215  remaining = strchr(labelfile, '\n') + 1; /* %n is not portable enough */
11216 
11217  /*
11218  * Parse the BACKUP FROM line. If we are taking an online backup from the
11219  * standby, we confirm that the standby has not been promoted during the
11220  * backup.
11221  */
11222  ptr = strstr(remaining, "BACKUP FROM:");
11223  if (!ptr || sscanf(ptr, "BACKUP FROM: %19s\n", backupfrom) != 1)
11224  ereport(ERROR,
11225  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11226  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
11227  if (strcmp(backupfrom, "standby") == 0 && !backup_started_in_recovery)
11228  ereport(ERROR,
11229  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11230  errmsg("the standby was promoted during online backup"),
11231  errhint("This means that the backup being taken is corrupt "
11232  "and should not be used. "
11233  "Try taking another online backup.")));
11234 
11235  /*
11236  * During recovery, we don't write an end-of-backup record. We assume that
11237  * pg_control was backed up last and its minimum recovery point can be
11238  * available as the backup end location. Since we don't have an
11239  * end-of-backup record, we use the pg_control value to check whether
11240  * we've reached the end of backup when starting recovery from this
11241  * backup. We have no way of checking if pg_control wasn't backed up last
11242  * however.
11243  *
11244  * We don't force a switch to new WAL file but it is still possible to
11245  * wait for all the required files to be archived if waitforarchive is
11246  * true. This is okay if we use the backup to start a standby and fetch
11247  * the missing WAL using streaming replication. But in the case of an
11248  * archive recovery, a user should set waitforarchive to true and wait for
11249  * them to be archived to ensure that all the required files are
11250  * available.
11251  *
11252  * We return the current minimum recovery point as the backup end
11253  * location. Note that it can be greater than the exact backup end
11254  * location if the minimum recovery point is updated after the backup of
11255  * pg_control. This is harmless for current uses.
11256  *
11257  * XXX currently a backup history file is for informational and debug
11258  * purposes only. It's not essential for an online backup. Furthermore,
11259  * even if it's created, it will not be archived during recovery because
11260  * an archiver is not invoked. So it doesn't seem worthwhile to write a
11261  * backup history file during recovery.
11262  */
11263  if (backup_started_in_recovery)
11264  {
11265  XLogRecPtr recptr;
11266 
11267  /*
11268  * Check to see if all WAL replayed during online backup contain
11269  * full-page writes.
11270  */
11272  recptr = XLogCtl->lastFpwDisableRecPtr;
11274 
11275  if (startpoint <= recptr)
11276  ereport(ERROR,
11277  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11278  errmsg("WAL generated with full_page_writes=off was replayed "
11279  "during online backup"),
11280  errhint("This means that the backup being taken on the standby "
11281  "is corrupt and should not be used. "
11282  "Enable full_page_writes and run CHECKPOINT on the primary, "
11283  "and then try an online backup again.")));
11284 
11285 
11286  LWLockAcquire(ControlFileLock, LW_SHARED);
11287  stoppoint = ControlFile->minRecoveryPoint;
11288  stoptli = ControlFile->minRecoveryPointTLI;
11289  LWLockRelease(ControlFileLock);
11290  }
11291  else
11292  {
11293  /*
11294  * Write the backup-end xlog record
11295  */
11296  XLogBeginInsert();
11297  XLogRegisterData((char *) (&startpoint), sizeof(startpoint));
11298  stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
11299  stoptli = ThisTimeLineID;
11300 
11301  /*
11302  * Force a switch to a new xlog segment file, so that the backup is
11303  * valid as soon as archiver moves out the current segment file.
11304  */
11305  RequestXLogSwitch(false);
11306 
11307  XLByteToPrevSeg(stoppoint, _logSegNo, wal_segment_size);
11308  XLogFileName(stopxlogfilename, stoptli, _logSegNo, wal_segment_size);
11309 
11310  /* Use the log timezone here, not the session timezone */
11311  stamp_time = (pg_time_t) time(NULL);
11312  pg_strftime(strfbuf, sizeof(strfbuf),
11313  "%Y-%m-%d %H:%M:%S %Z",
11314  pg_localtime(&stamp_time, log_timezone));
11315 
11316  /*
11317  * Write the backup history file
11318  */
11319  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
11320  BackupHistoryFilePath(histfilepath, stoptli, _logSegNo,
11321  startpoint, wal_segment_size);
11322  fp = AllocateFile(histfilepath, "w");
11323  if (!fp)
11324  ereport(ERROR,
11326  errmsg("could not create file \"%s\": %m",
11327  histfilepath)));
11328  fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n",
11329  (uint32) (startpoint >> 32), (uint32) startpoint, startxlogfilename);
11330  fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
11331  (uint32) (stoppoint >> 32), (uint32) stoppoint, stopxlogfilename);
11332 
11333  /*
11334  * Transfer remaining lines including label and start timeline to
11335  * history file.
11336  */
11337  fprintf(fp, "%s", remaining);
11338  fprintf(fp, "STOP TIME: %s\n", strfbuf);
11339  fprintf(fp, "STOP TIMELINE: %u\n", stoptli);
11340  if (fflush(fp) || ferror(fp) || FreeFile(fp))
11341  ereport(ERROR,
11343  errmsg("could not write file \"%s\": %m",
11344  histfilepath)));
11345 
11346  /*
11347  * Clean out any no-longer-needed history files. As a side effect,
11348  * this will post a .ready file for the newly created history file,
11349  * notifying the archiver that history file may be archived
11350  * immediately.
11351  */
11353  }
11354 
11355  /*
11356  * If archiving is enabled, wait for all the required WAL files to be
11357  * archived before returning. If archiving isn't enabled, the required WAL
11358  * needs to be transported via streaming replication (hopefully with
11359  * wal_keep_size set high enough), or some more exotic mechanism like
11360  * polling and copying files from pg_wal with script. We have no knowledge
11361  * of those mechanisms, so it's up to the user to ensure that he gets all
11362  * the required WAL.
11363  *
11364  * We wait until both the last WAL file filled during backup and the
11365  * history file have been archived, and assume that the alphabetic sorting
11366  * property of the WAL files ensures any earlier WAL files are safely
11367  * archived as well.
11368  *
11369  * We wait forever, since archive_command is supposed to work and we
11370  * assume the admin wanted his backup to work completely. If you don't
11371  * wish to wait, then either waitforarchive should be passed in as false,
11372  * or you can set statement_timeout. Also, some notices are issued to
11373  * clue in anyone who might be doing this interactively.
11374  */
11375 
11376  if (waitforarchive &&
11377  ((!backup_started_in_recovery && XLogArchivingActive()) ||
11378  (backup_started_in_recovery && XLogArchivingAlways())))
11379  {
11380  XLByteToPrevSeg(stoppoint, _logSegNo, wal_segment_size);
11381  XLogFileName(lastxlogfilename, stoptli, _logSegNo, wal_segment_size);
11382 
11383  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
11384  BackupHistoryFileName(histfilename, stoptli, _logSegNo,
11385  startpoint, wal_segment_size);
11386 
11387  seconds_before_warning = 60;
11388  waits = 0;
11389 
11390  while (XLogArchiveIsBusy(lastxlogfilename) ||
11391  XLogArchiveIsBusy(histfilename))
11392  {
11394 
11395  if (!reported_waiting && waits > 5)
11396  {
11397  ereport(NOTICE,
11398  (errmsg("base backup done, waiting for required WAL segments to be archived")));
11399  reported_waiting = true;
11400  }
11401 
11403  pg_usleep(1000000L);
11405 
11406  if (++waits >= seconds_before_warning)
11407  {
11408  seconds_before_warning *= 2; /* This wraps in >10 years... */
11409  ereport(WARNING,
11410  (errmsg("still waiting for all required WAL segments to be archived (%d seconds elapsed)",
11411  waits),
11412  errhint("Check that your archive_command is executing properly. "
11413  "You can safely cancel this backup, "
11414  "but the database backup will not be usable without all the WAL segments.")));
11415  }
11416  }
11417 
11418  ereport(NOTICE,
11419  (errmsg("all required WAL segments have been archived")));
11420  }
11421  else if (waitforarchive)
11422  ereport(NOTICE,
11423  (errmsg("WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup")));
11424 
11425  /*
11426  * We're done. As a convenience, return the ending WAL location.
11427  */
11428  if (stoptli_p)
11429  *stoptli_p = stoptli;
11430  return stoppoint;
11431 }
int remaining
Definition: informix.c:667
size_t pg_strftime(char *s, size_t max, const char *format, const struct pg_tm *tm)
Definition: strftime.c:128
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9693
#define DEBUG1
Definition: elog.h:25
int errhint(const char *fmt,...)
Definition: elog.c:1068
uint32 TimeLineID
Definition: xlogdefs.h:52
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1728
int wal_segment_size
Definition: xlog.c:117
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:724
static SessionBackupState sessionBackupState
Definition: xlog.c:534
#define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes)
#define XLogIsNeeded()
Definition: xlog.h:191
slock_t info_lck
Definition: xlog.c:726
int errcode(int sqlerrcode)
Definition: elog.c:610
XLogCtlInsert Insert
Definition: xlog.c:600
#define BackupHistoryFileName(fname, tli, logSegNo, startpoint, wal_segsz_bytes)
bool RecoveryInProgress(void)
Definition: xlog.c:8076
static bool backup_started_in_recovery
Definition: basebackup.c:88
#define fprintf
Definition: port.h:219
pg_tz * log_timezone
Definition: pgtz.c:31
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
#define TABLESPACE_MAP
Definition: xlog.h:392
#define SpinLockAcquire(lock)
Definition: spin.h:62
void pg_usleep(long microsec)
Definition: signal.c:53
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:47
#define XLogArchivingAlways()
Definition: xlog.h:183
bool forcePageWrites
Definition: xlog.c:574
#define ERROR
Definition: elog.h:43
static void CleanupBackupHistory(void)
Definition: xlog.c:4292
#define MAXPGPATH
uint64 XLogSegNo
Definition: xlogdefs.h:41
int errcode_for_file_access(void)
Definition: elog.c:633
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2322
unsigned int uint32
Definition: c.h:375
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1460
#define XLOG_BACKUP_END
Definition: pg_control.h:72
#define WARNING
Definition: elog.h:40
int nonExclusiveBackups
Definition: xlog.c:586
#define MAXFNAMELEN
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:330
#define SpinLockRelease(lock)
Definition: spin.h:64
#define BackupHistoryFilePath(path, tli, logSegNo, startpoint, wal_segsz_bytes)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:422
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:585
uintptr_t Datum
Definition: postgres.h:367
static ControlFileData * ControlFile
Definition: xlog.c:737
#define BoolGetDatum(X)
Definition: postgres.h:402
TimeLineID ThisTimeLineID
Definition: xlog.c:192
#define ereport(elevel,...)
Definition: elog.h:144
#define NOTICE
Definition: elog.h:37
bool XLogArchiveIsBusy(const char *xlog)
Definition: xlogarchive.c:625
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:746
#define XLogArchivingActive()
Definition: xlog.h:180
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1436
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1699
static XLogCtlData * XLogCtl
Definition: xlog.c:729
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208
static void pg_stop_backup_callback(int code, Datum arg)
Definition: xlog.c:11000
#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:52
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1342
int durable_unlink(const char *fname, int elevel)
Definition: fd.c:749
int FreeFile(FILE *file)
Definition: fd.c:2521
void * palloc(Size size)
Definition: mcxt.c:950
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define BACKUP_LABEL_FILE
Definition: xlog.h:389
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
void XLogBeginInsert(void)
Definition: xloginsert.c:123
#define stat
Definition: win32_port.h:275
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ emode_for_corrupt_record()

static int emode_for_corrupt_record ( int  emode,
XLogRecPtr  RecPtr 
)
static

Definition at line 12558 of file xlog.c.

References DEBUG1, LOG, readSource, and XLOG_FROM_PG_WAL.

Referenced by ReadRecord(), and XLogPageRead().

12559 {
12560  static XLogRecPtr lastComplaint = 0;
12561 
12562  if (readSource == XLOG_FROM_PG_WAL && emode == LOG)
12563  {
12564  if (RecPtr == lastComplaint)
12565  emode = DEBUG1;
12566  else
12567  lastComplaint = RecPtr;
12568  }
12569  return emode;
12570 }
#define DEBUG1
Definition: elog.h:25
static XLogSource readSource
Definition: xlog.c:816
#define LOG
Definition: elog.h:26
uint64 XLogRecPtr
Definition: xlogdefs.h:21

◆ exitArchiveRecovery()

static void exitArchiveRecovery ( TimeLineID  endTLI,
XLogRecPtr  endOfLog 
)
static

Definition at line 5546 of file xlog.c.

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, ThisTimeLineID, UpdateMinRecoveryPoint(), wal_segment_size, XLByteToPrevSeg, XLByteToSeg, XLogArchiveCleanup(), XLogFileCopy(), XLogFileInit(), XLogFileName, and XLogSegmentOffset.

Referenced by StartupXLOG().

5547 {
5548  char xlogfname[MAXFNAMELEN];
5549  XLogSegNo endLogSegNo;
5550  XLogSegNo startLogSegNo;
5551 
5552  /* we always switch to a new timeline after archive recovery */
5553  Assert(endTLI != ThisTimeLineID);
5554 
5555  /*
5556  * We are no longer in archive recovery state.
5557  */
5558  InArchiveRecovery = false;
5559 
5560  /*
5561  * Update min recovery point one last time.
5562  */
5564 
5565  /*
5566  * If the ending log segment is still open, close it (to avoid problems on
5567  * Windows with trying to rename or delete an open file).
5568  */
5569  if (readFile >= 0)
5570  {
5571  close(readFile);
5572  readFile = -1;
5573  }
5574 
5575  /*
5576  * Calculate the last segment on the old timeline, and the first segment
5577  * on the new timeline. If the switch happens in the middle of a segment,
5578  * they are the same, but if the switch happens exactly at a segment
5579  * boundary, startLogSegNo will be endLogSegNo + 1.
5580  */
5581  XLByteToPrevSeg(endOfLog, endLogSegNo, wal_segment_size);
5582  XLByteToSeg(endOfLog, startLogSegNo, wal_segment_size);
5583 
5584  /*
5585  * Initialize the starting WAL segment for the new timeline. If the switch
5586  * happens in the middle of a segment, copy data from the last WAL segment
5587  * of the old timeline up to the switch point, to the starting WAL segment
5588  * on the new timeline.
5589  */
5590  if (endLogSegNo == startLogSegNo)
5591  {
5592  /*
5593  * Make a copy of the file on the new timeline.
5594  *
5595  * Writing WAL isn't allowed yet, so there are no locking
5596  * considerations. But we should be just as tense as XLogFileInit to
5597  * avoid emplacing a bogus file.
5598  */
5599  XLogFileCopy(endLogSegNo, endTLI, endLogSegNo,
5600  XLogSegmentOffset(endOfLog, wal_segment_size));
5601  }
5602  else
5603  {
5604  /*
5605  * The switch happened at a segment boundary, so just create the next
5606  * segment on the new timeline.
5607  */
5608  bool use_existent = true;
5609  int fd;
5610 
5611  fd = XLogFileInit(startLogSegNo, &use_existent, true);
5612 
5613  if (close(fd) != 0)
5614  {
5615  char xlogfname[MAXFNAMELEN];
5616  int save_errno = errno;
5617 
5618  XLogFileName(xlogfname, ThisTimeLineID, startLogSegNo,
5620  errno = save_errno;
5621  ereport(ERROR,
5623  errmsg("could not close file \"%s\": %m", xlogfname)));
5624  }
5625  }
5626