PostgreSQL Source Code  git master
xlog.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <math.h>
#include <time.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include "access/clog.h"
#include "access/commit_ts.h"
#include "access/multixact.h"
#include "access/rewriteheap.h"
#include "access/subtrans.h"
#include "access/timeline.h"
#include "access/transam.h"
#include "access/tuptoaster.h"
#include "access/twophase.h"
#include "access/xact.h"
#include "access/xlog_internal.h"
#include "access/xloginsert.h"
#include "access/xlogreader.h"
#include "access/xlogutils.h"
#include "catalog/catversion.h"
#include "catalog/pg_control.h"
#include "catalog/pg_database.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "port/atomics.h"
#include "postmaster/bgwriter.h"
#include "postmaster/walwriter.h"
#include "postmaster/startup.h"
#include "replication/basebackup.h"
#include "replication/logical.h"
#include "replication/slot.h"
#include "replication/origin.h"
#include "replication/snapbuild.h"
#include "replication/walreceiver.h"
#include "replication/walsender.h"
#include "storage/bufmgr.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/large_object.h"
#include "storage/latch.h"
#include "storage/pmsignal.h"
#include "storage/predicate.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/reinit.h"
#include "storage/smgr.h"
#include "storage/spin.h"
#include "utils/backend_random.h"
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/pg_lsn.h"
#include "utils/ps_status.h"
#include "utils/relmapper.h"
#include "utils/snapmgr.h"
#include "utils/timestamp.h"
#include "pg_trace.h"
Include dependency graph for xlog.c:

Go to the source code of this file.

Data Structures

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

Macros

#define RECOVERY_COMMAND_FILE   "recovery.conf"
 
#define RECOVERY_COMMAND_DONE   "recovery.done"
 
#define PROMOTE_SIGNAL_FILE   "promote"
 
#define FALLBACK_PROMOTE_SIGNAL_FILE   "fallback_promote"
 
#define NUM_XLOGINSERT_LOCKS   8
 
#define INSERT_FREESPACE(endptr)   (((endptr) % XLOG_BLCKSZ == 0) ? 0 : (XLOG_BLCKSZ - (endptr) % XLOG_BLCKSZ))
 
#define NextBufIdx(idx)   (((idx) == XLogCtl->XLogCacheBlck) ? 0 : ((idx) + 1))
 
#define XLogRecPtrToBufIdx(recptr)   (((recptr) / XLOG_BLCKSZ) % (XLogCtl->XLogCacheBlck + 1))
 
#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)
 
#define ConvertToXSegs(x, segsize)   (x / ((segsize) / (1024 * 1024)))
 
#define RecoveryRequiresIntParameter(param_name, currValue, minValue)
 

Typedefs

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

Enumerations

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

Functions

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

Variables

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

Macro Definition Documentation

◆ ConvertToXSegs

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

Definition at line 741 of file xlog.c.

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

◆ FALLBACK_PROMOTE_SIGNAL_FILE

#define FALLBACK_PROMOTE_SIGNAL_FILE   "fallback_promote"

Definition at line 85 of file xlog.c.

Referenced by CheckForStandbyTrigger(), CheckPromoteSignal(), and RemovePromoteSignalFiles().

◆ INSERT_FREESPACE

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

Definition at line 721 of file xlog.c.

Referenced by CopyXLogRecordToWAL(), and CreateCheckPoint().

◆ NextBufIdx

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

Definition at line 725 of file xlog.c.

Referenced by XLogWrite().

◆ NUM_XLOGINSERT_LOCKS

◆ PROMOTE_SIGNAL_FILE

#define PROMOTE_SIGNAL_FILE   "promote"

Definition at line 84 of file xlog.c.

Referenced by CheckForStandbyTrigger(), CheckPromoteSignal(), and RemovePromoteSignalFiles().

◆ RECOVERY_COMMAND_DONE

#define RECOVERY_COMMAND_DONE   "recovery.done"

Definition at line 83 of file xlog.c.

Referenced by exitArchiveRecovery().

◆ RECOVERY_COMMAND_FILE

#define RECOVERY_COMMAND_FILE   "recovery.conf"

Definition at line 82 of file xlog.c.

Referenced by exitArchiveRecovery(), and readRecoveryCommandFile().

◆ RecoveryRequiresIntParameter

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

Definition at line 6274 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 732 of file xlog.c.

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

Typedef Documentation

◆ ExclusiveBackupState

◆ WALInsertLockPadded

◆ XLogCtlData

◆ XLogCtlInsert

◆ XLogPageReadPrivate

◆ XLogwrtResult

◆ XLogwrtRqst

Enumeration Type Documentation

◆ ExclusiveBackupState

Enumerator
EXCLUSIVE_BACKUP_NONE 
EXCLUSIVE_BACKUP_STARTING 
EXCLUSIVE_BACKUP_IN_PROGRESS 
EXCLUSIVE_BACKUP_STOPPING 

Definition at line 500 of file xlog.c.

◆ XLogSource

enum XLogSource
Enumerator
XLOG_FROM_ANY 
XLOG_FROM_ARCHIVE 
XLOG_FROM_PG_WAL 
XLOG_FROM_STREAM 

Definition at line 757 of file xlog.c.

758 {
759  XLOG_FROM_ANY = 0, /* request to read WAL from any source */
760  XLOG_FROM_ARCHIVE, /* restored using restore_command */
761  XLOG_FROM_PG_WAL, /* existing file in pg_wal */
762  XLOG_FROM_STREAM /* streamed from master */
763 } XLogSource;
XLogSource
Definition: xlog.c:757

Function Documentation

◆ AdvanceXLInsertBuffer()

static void AdvanceXLInsertBuffer ( XLogRecPtr  upto,
bool  opportunistic 
)
static

Definition at line 2074 of file xlog.c.

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

Referenced by GetXLogBuffer(), and XLogBackgroundFlush().

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

◆ assign_checkpoint_completion_target()

void assign_checkpoint_completion_target ( double  newval,
void *  extra 
)

Definition at line 2279 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

2280 {
2283 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2243
#define newval
double CheckPointCompletionTarget
Definition: checkpointer.c:147

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2272 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

2273 {
2276 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2243
int max_wal_size_mb
Definition: xlog.c:89
#define newval

◆ assign_xlog_sync_method()

void assign_xlog_sync_method ( int  new_sync_method,
void *  extra 
)

Definition at line 10237 of file xlog.c.

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

10238 {
10239  if (sync_method != new_sync_method)
10240  {
10241  /*
10242  * To ensure that no blocks escape unsynced, force an fsync on the
10243  * currently open log segment (if any). Also, if the open flag is
10244  * changing, close the log file so it will be reopened (with new flag
10245  * bit) at next use.
10246  */
10247  if (openLogFile >= 0)
10248  {
10250  if (pg_fsync(openLogFile) != 0)
10251  ereport(PANIC,
10253  errmsg("could not fsync log segment %s: %m",
10256  if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
10257  XLogFileClose();
10258  }
10259  }
10260 }
static int get_sync_bit(int method)
Definition: xlog.c:10181
#define PANIC
Definition: elog.h:53
static XLogSegNo openLogSegNo
Definition: xlog.c:775
static void XLogFileClose(void)
Definition: xlog.c:3743
char * XLogFileNameP(TimeLineID tli, XLogSegNo segno)
Definition: xlog.c:10315
int errcode_for_file_access(void)
Definition: elog.c:598
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1261
#define ereport(elevel, rest)
Definition: elog.h:122
static int openLogFile
Definition: xlog.c:774
TimeLineID ThisTimeLineID
Definition: xlog.c:181
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1237
int sync_method
Definition: xlog.c:103
int errmsg(const char *fmt,...)
Definition: elog.c:797
int pg_fsync(int fd)
Definition: fd.c:341

◆ BackupInProgress()

bool BackupInProgress ( void  )

Definition at line 11608 of file xlog.c.

References BACKUP_LABEL_FILE, and stat.

Referenced by pg_is_in_backup(), and PostmasterStateMachine().

11609 {
11610  struct stat stat_buf;
11611 
11612  return (stat(BACKUP_LABEL_FILE, &stat_buf) == 0);
11613 }
struct stat stat_buf
Definition: pg_standby.c:102
#define stat(a, b)
Definition: win32_port.h:266
#define BACKUP_LABEL_FILE
Definition: xlog.h:322

◆ BootStrapXLOG()

void BootStrapXLOG ( void  )

Definition at line 5079 of file xlog.c.

References AdvanceOldestClogXid(), Assert, bootstrap_data_checksum_version, BootStrapCLOG(), BootStrapCommitTs(), BootStrapMultiXact(), BootStrapSUBTRANS(), buffer, ControlFileData::checkPoint, ControlFileData::checkPointCopy, close, COMP_CRC32C, ControlFileData::data_checksum_version, DB_SHUTDOWNED, ereport, errcode(), errcode_for_file_access(), errmsg(), FIN_CRC32C, FirstBootstrapObjectId, FirstMultiXactId, FirstNormalTransactionId, CheckPoint::fullPageWrites, fullPageWrites, gettimeofday(), INIT_CRC32C, InvalidTransactionId, max_locks_per_xact, ControlFileData::max_locks_per_xact, max_prepared_xacts, ControlFileData::max_prepared_xacts, max_worker_processes, ControlFileData::max_worker_processes, MaxConnections, ControlFileData::MaxConnections, MOCK_AUTH_NONCE_LEN, ControlFileData::mock_authentication_nonce, MultiXactSetNextMXact(), CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, VariableCacheData::nextOid, CheckPoint::nextXid, VariableCacheData::nextXid, CheckPoint::nextXidEpoch, offsetof, VariableCacheData::oidCount, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, openLogFile, palloc(), PANIC, pfree(), pg_backend_random(), pg_fsync(), pgstat_report_wait_end(), pgstat_report_wait_start(), CheckPoint::PrevTimeLineID, ReadControlFile(), CheckPoint::redo, SetCommitTsLimit(), SetMultiXactIdLimit(), SetTransactionIdLimit(), ShmemVariableCache, SizeOfXLogLongPHD, SizeOfXLogRecord, SizeOfXLogRecordDataHeaderShort, ControlFileData::state, ControlFileData::system_identifier, CheckPoint::ThisTimeLineID, ThisTimeLineID, CheckPoint::time, ControlFileData::time, track_commit_timestamp, ControlFileData::track_commit_timestamp, TYPEALIGN, ControlFileData::unloggedLSN, WAIT_EVENT_WAL_BOOTSTRAP_SYNC, WAIT_EVENT_WAL_BOOTSTRAP_WRITE, wal_level, ControlFileData::wal_level, wal_log_hints, ControlFileData::wal_log_hints, wal_segment_size, write, WriteControlFile(), XLogRecord::xl_info, XLogRecord::xl_prev, XLogRecord::xl_rmid, XLogRecord::xl_tot_len, XLogRecord::xl_xid, XLOG_CHECKPOINT_SHUTDOWN, XLOG_PAGE_MAGIC, XLogFileInit(), XLogPageHeaderData::xlp_info, XLP_LONG_HEADER, XLogPageHeaderData::xlp_magic, XLogPageHeaderData::xlp_pageaddr, XLogLongPageHeaderData::xlp_seg_size, XLogLongPageHeaderData::xlp_sysid, XLogPageHeaderData::xlp_tli, XLogLongPageHeaderData::xlp_xlog_blcksz, and XLR_BLOCK_ID_DATA_SHORT.

Referenced by AuxiliaryProcessMain().

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

◆ CalculateCheckpointSegments()

static void CalculateCheckpointSegments ( void  )
static

Definition at line 2243 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().

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

◆ CancelBackup()

void CancelBackup ( void  )

Definition at line 11628 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().

11629 {
11630  struct stat stat_buf;
11631 
11632  /* if the backup_label file is not there, return */
11633  if (stat(BACKUP_LABEL_FILE, &stat_buf) < 0)
11634  return;
11635 
11636  /* remove leftover file from previously canceled backup if it exists */
11637  unlink(BACKUP_LABEL_OLD);
11638 
11640  {
11641  ereport(WARNING,
11643  errmsg("online backup mode was not canceled"),
11644  errdetail("File \"%s\" could not be renamed to \"%s\": %m.",
11646  return;
11647  }
11648 
11649  /* if the tablespace_map file is not there, return */
11650  if (stat(TABLESPACE_MAP, &stat_buf) < 0)
11651  {
11652  ereport(LOG,
11653  (errmsg("online backup mode canceled"),
11654  errdetail("File \"%s\" was renamed to \"%s\".",
11656  return;
11657  }
11658 
11659  /* remove leftover file from previously canceled backup if it exists */
11660  unlink(TABLESPACE_MAP_OLD);
11661 
11663  {
11664  ereport(LOG,
11665  (errmsg("online backup mode canceled"),
11666  errdetail("Files \"%s\" and \"%s\" were renamed to "
11667  "\"%s\" and \"%s\", respectively.",
11670  }
11671  else
11672  {
11673  ereport(WARNING,
11675  errmsg("online backup mode canceled"),
11676  errdetail("File \"%s\" was renamed to \"%s\", but "
11677  "file \"%s\" could not be renamed to \"%s\": %m.",
11680  }
11681 }
#define DEBUG1
Definition: elog.h:25
#define LOG
Definition: elog.h:26
#define BACKUP_LABEL_OLD
Definition: xlog.h:323
#define TABLESPACE_MAP
Definition: xlog.h:325
struct stat stat_buf
Definition: pg_standby.c:102
int errdetail(const char *fmt,...)
Definition: elog.c:873
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:601
#define WARNING
Definition: elog.h:40
#define stat(a, b)
Definition: win32_port.h:266
#define TABLESPACE_MAP_OLD
Definition: xlog.h:326
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define BACKUP_LABEL_FILE
Definition: xlog.h:322

◆ check_wal_buffers()

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

Definition at line 4870 of file xlog.c.

References XLOGbuffers, and XLOGChooseNumBuffers().

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

◆ CheckForStandbyTrigger()

static bool CheckForStandbyTrigger ( void  )
static

Definition at line 12327 of file xlog.c.

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

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

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

◆ CheckPointGuts()

static void CheckPointGuts ( XLogRecPtr  checkPointRedo,
int  flags 
)
static

Definition at line 9174 of file xlog.c.

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

Referenced by CreateCheckPoint(), and CreateRestartPoint().

9175 {
9176  CheckPointCLOG();
9185  CheckPointBuffers(flags); /* performs all required fsyncs */
9187  /* We deliberately delay 2PC checkpointing as long as possible */
9188  CheckPointTwoPhase(checkPointRedo);
9189 }
void CheckPointBuffers(int flags)
Definition: bufmgr.c:2574
void CheckPointLogicalRewriteHeap(void)
Definition: rewriteheap.c:1207
void CheckPointReplicationOrigin(void)
Definition: origin.c:545
void CheckPointSnapBuild(void)
Definition: snapbuild.c:1917
void CheckPointCLOG(void)
Definition: clog.c:842
void CheckPointMultiXact(void)
Definition: multixact.c:2140
void CheckPointCommitTs(void)
Definition: commit_ts.c:761
void CheckPointSUBTRANS(void)
Definition: subtrans.c:300
void CheckPointRelationMap(void)
Definition: relmapper.c:524
void CheckPointPredicate(void)
Definition: predicate.c:997
void CheckPointTwoPhase(XLogRecPtr redo_horizon)
Definition: twophase.c:1744
void CheckPointReplicationSlots(void)
Definition: slot.c:1070

◆ CheckPromoteSignal()

bool CheckPromoteSignal ( void  )

Definition at line 12399 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, PROMOTE_SIGNAL_FILE, and stat.

Referenced by sigusr1_handler().

12400 {
12401  struct stat stat_buf;
12402 
12403  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
12405  return true;
12406 
12407  return false;
12408 }
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.c:85
struct stat stat_buf
Definition: pg_standby.c:102
#define PROMOTE_SIGNAL_FILE
Definition: xlog.c:84
#define stat(a, b)
Definition: win32_port.h:266

◆ CheckRecoveryConsistency()

static void CheckRecoveryConsistency ( void  )
static

Definition at line 7950 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().

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

◆ CheckRequiredParameterValues()

static void CheckRequiredParameterValues ( void  )
static

Definition at line 6296 of file xlog.c.

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

Referenced by StartupXLOG(), and xlog_redo().

6297 {
6298  /*
6299  * For archive recovery, the WAL must be generated with at least 'replica'
6300  * wal_level.
6301  */
6303  {
6304  ereport(WARNING,
6305  (errmsg("WAL was generated with wal_level=minimal, data may be missing"),
6306  errhint("This happens if you temporarily set wal_level=minimal without taking a new base backup.")));
6307  }
6308 
6309  /*
6310  * For Hot Standby, the WAL must be generated with 'replica' mode, and we
6311  * must have at least as many backend slots as the primary.
6312  */
6314  {
6316  ereport(ERROR,
6317  (errmsg("hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server"),
6318  errhint("Either set wal_level to \"replica\" on the master, or turn off hot_standby here.")));
6319 
6320  /* We ignore autovacuum_max_workers when we make this test. */
6321  RecoveryRequiresIntParameter("max_connections",
6324  RecoveryRequiresIntParameter("max_worker_processes",
6327  RecoveryRequiresIntParameter("max_prepared_transactions",
6330  RecoveryRequiresIntParameter("max_locks_per_transaction",
6333  }
6334 }
bool ArchiveRecoveryRequested
Definition: xlog.c:248
int max_locks_per_xact
Definition: pg_control.h:181
int errhint(const char *fmt,...)
Definition: elog.c:987
int max_prepared_xacts
Definition: pg_control.h:180
int max_worker_processes
Definition: pg_control.h:179
#define ERROR
Definition: elog.h:43
int max_prepared_xacts
Definition: twophase.c:117
#define ereport(elevel, rest)
Definition: elog.h:122
int max_locks_per_xact
Definition: lock.c:54
#define WARNING
Definition: elog.h:40
int MaxConnections
Definition: globals.c:131
static ControlFileData * ControlFile
Definition: xlog.c:715
bool EnableHotStandby
Definition: xlog.c:96
int errmsg(const char *fmt,...)
Definition: elog.c:797
int max_worker_processes
Definition: globals.c:132
#define RecoveryRequiresIntParameter(param_name, currValue, minValue)
Definition: xlog.c:6274

◆ checkTimeLineSwitch()

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

Definition at line 9731 of file xlog.c.

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

Referenced by StartupXLOG().

9732 {
9733  /* Check that the record agrees on what the current (old) timeline is */
9734  if (prevTLI != ThisTimeLineID)
9735  ereport(PANIC,
9736  (errmsg("unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record",
9737  prevTLI, ThisTimeLineID)));
9738 
9739  /*
9740  * The new timeline better be in the list of timelines we expect to see,
9741  * according to the timeline history. It should also not decrease.
9742  */
9743  if (newTLI < ThisTimeLineID || !tliInHistory(newTLI, expectedTLEs))
9744  ereport(PANIC,
9745  (errmsg("unexpected timeline ID %u (after %u) in checkpoint record",
9746  newTLI, ThisTimeLineID)));
9747 
9748  /*
9749  * If we have not yet reached min recovery point, and we're about to
9750  * switch to a timeline greater than the timeline of the min recovery
9751  * point: trouble. After switching to the new timeline, we could not
9752  * possibly visit the min recovery point on the correct timeline anymore.
9753  * This can happen if there is a newer timeline in the archive that
9754  * branched before the timeline the min recovery point is on, and you
9755  * attempt to do PITR to the new timeline.
9756  */
9758  lsn < minRecoveryPoint &&
9759  newTLI > minRecoveryPointTLI)
9760  ereport(PANIC,
9761  (errmsg("unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u",
9762  newTLI,
9763  (uint32) (minRecoveryPoint >> 32),
9766 
9767  /* Looks good */
9768 }
static List * expectedTLEs
Definition: xlog.c:320
#define PANIC
Definition: elog.h:53
unsigned int uint32
Definition: c.h:325
#define ereport(elevel, rest)
Definition: elog.h:122
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
static TimeLineID minRecoveryPointTLI
Definition: xlog.c:832
TimeLineID ThisTimeLineID
Definition: xlog.c:181
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool tliInHistory(TimeLineID tli, List *expectedTLEs)
Definition: timeline.c:515
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:831

◆ checkXLogConsistency()

static void checkXLogConsistency ( XLogReaderState record)
static

Definition at line 1356 of file xlog.c.

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

Referenced by StartupXLOG().

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

◆ CheckXLogRemoved()

void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)

Definition at line 3810 of file xlog.c.

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

Referenced by perform_base_backup(), and XLogRead().

3811 {
3812  int save_errno = errno;
3813  XLogSegNo lastRemovedSegNo;
3814 
3816  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3818 
3819  if (segno <= lastRemovedSegNo)
3820  {
3821  char filename[MAXFNAMELEN];
3822 
3823  XLogFileName(filename, tli, segno, wal_segment_size);
3824  errno = save_errno;
3825  ereport(ERROR,
3827  errmsg("requested WAL segment %s has already been removed",
3828  filename)));
3829  }
3830  errno = save_errno;
3831 }
int wal_segment_size
Definition: xlog.c:113
slock_t info_lck
Definition: xlog.c:704
XLogSegNo lastRemovedSegNo
Definition: xlog.c:587
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define ERROR
Definition: elog.h:43
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static XLogCtlData * XLogCtl
Definition: xlog.c:707
static char * filename
Definition: pg_dumpall.c:88
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ CleanupBackupHistory()

static void CleanupBackupHistory ( void  )
static

Definition at line 4167 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().

4168 {
4169  DIR *xldir;
4170  struct dirent *xlde;
4171  char path[MAXPGPATH + sizeof(XLOGDIR)];
4172 
4173  xldir = AllocateDir(XLOGDIR);
4174 
4175  while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
4176  {
4177  if (IsBackupHistoryFileName(xlde->d_name))
4178  {
4179  if (XLogArchiveCheckDone(xlde->d_name))
4180  {
4181  elog(DEBUG2, "removing WAL backup history file \"%s\"",
4182  xlde->d_name);
4183  snprintf(path, sizeof(path), XLOGDIR "/%s", xlde->d_name);
4184  unlink(path);
4185  XLogArchiveCleanup(xlde->d_name);
4186  }
4187  }
4188  }
4189 
4190  FreeDir(xldir);
4191 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
Definition: dirent.h:9
void XLogArchiveCleanup(const char *xlog)
Definition: xlogarchive.c:752
Definition: dirent.c:25
bool XLogArchiveCheckDone(const char *xlog)
Definition: xlogarchive.c:619
#define MAXPGPATH
#define DEBUG2
Definition: elog.h:24
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2590
#define IsBackupHistoryFileName(fname)
#define XLOGDIR
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2656
char d_name[MAX_PATH]
Definition: dirent.h:14
#define elog
Definition: elog.h:219
int FreeDir(DIR *dir)
Definition: fd.c:2708

◆ CopyXLogRecordToWAL()

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

Definition at line 1460 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().

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

◆ CreateCheckPoint()

void CreateCheckPoint ( int  flags)

Definition at line 8698 of file xlog.c.

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

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

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

◆ CreateEndOfRecoveryRecord()

static void CreateEndOfRecoveryRecord ( void  )
static

Definition at line 9125 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().

9126 {
9127  xl_end_of_recovery xlrec;
9128  XLogRecPtr recptr;
9129 
9130  /* sanity check */
9131  if (!RecoveryInProgress())
9132  elog(ERROR, "can only be used to end recovery");
9133 
9134  xlrec.end_time = GetCurrentTimestamp();
9135 
9140 
9142 
9144 
9145  XLogBeginInsert();
9146  XLogRegisterData((char *) &xlrec, sizeof(xl_end_of_recovery));
9147  recptr = XLogInsert(RM_XLOG_ID, XLOG_END_OF_RECOVERY);
9148 
9149  XLogFlush(recptr);
9150 
9151  /*
9152  * Update the control file so that crash recovery can follow the timeline
9153  * changes to this point.
9154  */
9155  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9156  ControlFile->time = (pg_time_t) time(NULL);
9157  ControlFile->minRecoveryPoint = recptr;
9160  LWLockRelease(ControlFileLock);
9161 
9162  END_CRIT_SECTION();
9163 
9164  LocalXLogInsertAllowed = -1; /* return to "check" state */
9165 }
static int LocalXLogInsertAllowed
Definition: xlog.c:235
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1678
pg_time_t time
Definition: pg_control.h:128
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
TimeLineID PrevTimeLineID
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1569
#define END_CRIT_SECTION()
Definition: miscadmin.h:133
TimeLineID PrevTimeLineID
Definition: xlog.c:631
#define START_CRIT_SECTION()
Definition: miscadmin.h:131
bool RecoveryInProgress(void)
Definition: xlog.c:8051
#define XLOG_END_OF_RECOVERY
Definition: pg_control.h:76
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2796
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
void UpdateControlFile(void)
Definition: xlog.c:4746
#define ERROR
Definition: elog.h:43
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8177
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
static ControlFileData * ControlFile
Definition: xlog.c:715
TimeLineID ThisTimeLineID
Definition: xlog.c:181
TimestampTz end_time
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1649
static XLogCtlData * XLogCtl
Definition: xlog.c:707
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
TimeLineID ThisTimeLineID
#define elog
Definition: elog.h:219
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166

◆ CreateRestartPoint()

bool CreateRestartPoint ( int  flags)

Definition at line 9244 of file xlog.c.

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

Referenced by CheckpointerMain(), and ShutdownXLOG().

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

◆ DataChecksumsEnabled()

bool DataChecksumsEnabled ( void  )

Definition at line 4814 of file xlog.c.

References Assert, and ControlFileData::data_checksum_version.

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

4815 {
4816  Assert(ControlFile != NULL);
4817  return (ControlFile->data_checksum_version > 0);
4818 }
uint32 data_checksum_version
Definition: pg_control.h:221
static ControlFileData * ControlFile
Definition: xlog.c:715
#define Assert(condition)
Definition: c.h:699

◆ do_pg_abort_backup()

void do_pg_abort_backup ( void  )

Definition at line 11284 of file xlog.c.

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

Referenced by base_backup_cleanup(), and nonexclusive_base_backup_cleanup().

11285 {
11286  /*
11287  * Quick exit if session is not keeping around a non-exclusive backup
11288  * already started.
11289  */
11291  return;
11292 
11297 
11300  {
11301  XLogCtl->Insert.forcePageWrites = false;
11302  }
11304 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1678
static SessionBackupState sessionBackupState
Definition: xlog.c:512
XLogCtlInsert Insert
Definition: xlog.c:577
bool forcePageWrites
Definition: xlog.c:551
int nonExclusiveBackups
Definition: xlog.c:563
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:562
#define Assert(condition)
Definition: c.h:699
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1649
static XLogCtlData * XLogCtl
Definition: xlog.c:707

◆ do_pg_start_backup()

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

Definition at line 10362 of file xlog.c.

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

Referenced by perform_base_backup(), and pg_start_backup().

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

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

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

◆ emode_for_corrupt_record()

static int emode_for_corrupt_record ( int  emode,
XLogRecPtr  RecPtr 
)
static

Definition at line 12308 of file xlog.c.

References DEBUG1, LOG, readSource, and XLOG_FROM_PG_WAL.

Referenced by ReadRecord(), and XLogPageRead().

12309 {
12310  static XLogRecPtr lastComplaint = 0;
12311 
12312  if (readSource == XLOG_FROM_PG_WAL && emode == LOG)
12313  {
12314  if (RecPtr == lastComplaint)
12315  emode = DEBUG1;
12316  else
12317  lastComplaint = RecPtr;
12318  }
12319  return emode;
12320 }
#define DEBUG1
Definition: elog.h:25
static XLogSource readSource
Definition: xlog.c:790
#define LOG
Definition: elog.h:26
uint64 XLogRecPtr
Definition: xlogdefs.h:21

◆ exitArchiveRecovery()

static void exitArchiveRecovery ( TimeLineID  endTLI,
XLogRecPtr  endOfLog 
)
static

Definition at line 5616 of file xlog.c.

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

Referenced by StartupXLOG().

5617 {
5618  char recoveryPath[MAXPGPATH];
5619  char xlogfname[MAXFNAMELEN];
5620  XLogSegNo endLogSegNo;
5621  XLogSegNo startLogSegNo;
5622 
5623  /* we always switch to a new timeline after archive recovery */
5624  Assert(endTLI != ThisTimeLineID);
5625 
5626  /*
5627  * We are no longer in archive recovery state.
5628  */
5629  InArchiveRecovery = false;
5630 
5631  /*
5632  * Update min recovery point one last time.
5633  */
5635 
5636  /*
5637  * If the ending log segment is still open, close it (to avoid problems on
5638  * Windows with trying to rename or delete an open file).
5639  */
5640  if (readFile >= 0)
5641  {
5642  close(readFile);
5643  readFile = -1;
5644  }
5645 
5646  /*
5647  * Calculate the last segment on the old timeline, and the first segment
5648  * on the new timeline. If the switch happens in the middle of a segment,
5649  * they are the same, but if the switch happens exactly at a segment
5650  * boundary, startLogSegNo will be endLogSegNo + 1.
5651  */
5652  XLByteToPrevSeg(endOfLog, endLogSegNo, wal_segment_size);
5653  XLByteToSeg(endOfLog, startLogSegNo, wal_segment_size);
5654 
5655  /*
5656  * Initialize the starting WAL segment for the new timeline. If the switch
5657  * happens in the middle of a segment, copy data from the last WAL segment
5658  * of the old timeline up to the switch point, to the starting WAL segment
5659  * on the new timeline.
5660  */
5661  if (endLogSegNo == startLogSegNo)
5662  {
5663  /*
5664  * Make a copy of the file on the new timeline.
5665  *
5666  * Writing WAL isn't allowed yet, so there are no locking
5667  * considerations. But we should be just as tense as XLogFileInit to
5668  * avoid emplacing a bogus file.
5669  */
5670  XLogFileCopy(endLogSegNo, endTLI, endLogSegNo,