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 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 6191 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 2047 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 CopyXLogRecordToWAL(), GetXLogBuffer(), and XLogBackgroundFlush().

2048 {
2050  int nextidx;
2051  XLogRecPtr OldPageRqstPtr;
2052  XLogwrtRqst WriteRqst;
2053  XLogRecPtr NewPageEndPtr = InvalidXLogRecPtr;
2054  XLogRecPtr NewPageBeginPtr;
2055  XLogPageHeader NewPage;
2056  int npages = 0;
2057 
2058  LWLockAcquire(WALBufMappingLock, LW_EXCLUSIVE);
2059 
2060  /*
2061  * Now that we have the lock, check if someone initialized the page
2062  * already.
2063  */
2064  while (upto >= XLogCtl->InitializedUpTo || opportunistic)
2065  {
2067 
2068  /*
2069  * Get ending-offset of the buffer page we need to replace (this may
2070  * be zero if the buffer hasn't been used yet). Fall through if it's
2071  * already written out.
2072  */
2073  OldPageRqstPtr = XLogCtl->xlblocks[nextidx];
2074  if (LogwrtResult.Write < OldPageRqstPtr)
2075  {
2076  /*
2077  * Nope, got work to do. If we just want to pre-initialize as much
2078  * as we can without flushing, give up now.
2079  */
2080  if (opportunistic)
2081  break;
2082 
2083  /* Before waiting, get info_lck and update LogwrtResult */
2085  if (XLogCtl->LogwrtRqst.Write < OldPageRqstPtr)
2086  XLogCtl->LogwrtRqst.Write = OldPageRqstPtr;
2089 
2090  /*
2091  * Now that we have an up-to-date LogwrtResult value, see if we
2092  * still need to write it or if someone else already did.
2093  */
2094  if (LogwrtResult.Write < OldPageRqstPtr)
2095  {
2096  /*
2097  * Must acquire write lock. Release WALBufMappingLock first,
2098  * to make sure that all insertions that we need to wait for
2099  * can finish (up to this same position). Otherwise we risk
2100  * deadlock.
2101  */
2102  LWLockRelease(WALBufMappingLock);
2103 
2104  WaitXLogInsertionsToFinish(OldPageRqstPtr);
2105 
2106  LWLockAcquire(WALWriteLock, LW_EXCLUSIVE);
2107 
2109  if (LogwrtResult.Write >= OldPageRqstPtr)
2110  {
2111  /* OK, someone wrote it already */
2112  LWLockRelease(WALWriteLock);
2113  }
2114  else
2115  {
2116  /* Have to write it ourselves */
2117  TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_START();
2118  WriteRqst.Write = OldPageRqstPtr;
2119  WriteRqst.Flush = 0;
2120  XLogWrite(WriteRqst, false);
2121  LWLockRelease(WALWriteLock);
2122  TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_DONE();
2123  }
2124  /* Re-acquire WALBufMappingLock and retry */
2125  LWLockAcquire(WALBufMappingLock, LW_EXCLUSIVE);
2126  continue;
2127  }
2128  }
2129 
2130  /*
2131  * Now the next buffer slot is free and we can set it up to be the
2132  * next output page.
2133  */
2134  NewPageBeginPtr = XLogCtl->InitializedUpTo;
2135  NewPageEndPtr = NewPageBeginPtr + XLOG_BLCKSZ;
2136 
2137  Assert(XLogRecPtrToBufIdx(NewPageBeginPtr) == nextidx);
2138 
2139  NewPage = (XLogPageHeader) (XLogCtl->pages + nextidx * (Size) XLOG_BLCKSZ);
2140 
2141  /*
2142  * Be sure to re-zero the buffer so that bytes beyond what we've
2143  * written will look like zeroes and not valid XLOG records...
2144  */
2145  MemSet((char *) NewPage, 0, XLOG_BLCKSZ);
2146 
2147  /*
2148  * Fill the new page's header
2149  */
2150  NewPage->xlp_magic = XLOG_PAGE_MAGIC;
2151 
2152  /* NewPage->xlp_info = 0; */ /* done by memset */
2153  NewPage->xlp_tli = ThisTimeLineID;
2154  NewPage->xlp_pageaddr = NewPageBeginPtr;
2155 
2156  /* NewPage->xlp_rem_len = 0; */ /* done by memset */
2157 
2158  /*
2159  * If online backup is not in progress, mark the header to indicate
2160  * that* WAL records beginning in this page have removable backup
2161  * blocks. This allows the WAL archiver to know whether it is safe to
2162  * compress archived WAL data by transforming full-block records into
2163  * the non-full-block format. It is sufficient to record this at the
2164  * page level because we force a page switch (in fact a segment
2165  * switch) when starting a backup, so the flag will be off before any
2166  * records can be written during the backup. At the end of a backup,
2167  * the last page will be marked as all unsafe when perhaps only part
2168  * is unsafe, but at worst the archiver would miss the opportunity to
2169  * compress a few records.
2170  */
2171  if (!Insert->forcePageWrites)
2172  NewPage->xlp_info |= XLP_BKP_REMOVABLE;
2173 
2174  /*
2175  * If first page of an XLOG segment file, make it a long header.
2176  */
2177  if ((XLogSegmentOffset(NewPage->xlp_pageaddr, wal_segment_size)) == 0)
2178  {
2179  XLogLongPageHeader NewLongPage = (XLogLongPageHeader) NewPage;
2180 
2181  NewLongPage->xlp_sysid = ControlFile->system_identifier;
2182  NewLongPage->xlp_seg_size = wal_segment_size;
2183  NewLongPage->xlp_xlog_blcksz = XLOG_BLCKSZ;
2184  NewPage->xlp_info |= XLP_LONG_HEADER;
2185  }
2186 
2187  /*
2188  * Make sure the initialization of the page becomes visible to others
2189  * before the xlblocks update. GetXLogBuffer() reads xlblocks without
2190  * holding a lock.
2191  */
2192  pg_write_barrier();
2193 
2194  *((volatile XLogRecPtr *) &XLogCtl->xlblocks[nextidx]) = NewPageEndPtr;
2195 
2196  XLogCtl->InitializedUpTo = NewPageEndPtr;
2197 
2198  npages++;
2199  }
2200  LWLockRelease(WALBufMappingLock);
2201 
2202 #ifdef WAL_DEBUG
2203  if (XLOG_DEBUG && npages > 0)
2204  {
2205  elog(DEBUG1, "initialized %d pages, up to %X/%X",
2206  npages, (uint32) (NewPageEndPtr >> 32), (uint32) NewPageEndPtr);
2207  }
2208 #endif
2209 }
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:897
static XLogRecPtr WaitXLogInsertionsToFinish(XLogRecPtr upto)
Definition: xlog.c:1710
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:1724
#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:314
static void Insert(File file)
Definition: fd.c:1069
TimeLineID xlp_tli
Definition: xlog_internal.h:40
static void XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
Definition: xlog.c:2337
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:688
#define XLP_LONG_HEADER
Definition: xlog_internal.h:79
size_t Size
Definition: c.h:422
static XLogCtlData * XLogCtl
Definition: xlog.c:707
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1120
#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 2252 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

2253 {
2256 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2216
#define newval
double CheckPointCompletionTarget
Definition: checkpointer.c:147

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2245 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

2246 {
2249 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2216
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 10082 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().

10083 {
10084  if (sync_method != new_sync_method)
10085  {
10086  /*
10087  * To ensure that no blocks escape unsynced, force an fsync on the
10088  * currently open log segment (if any). Also, if the open flag is
10089  * changing, close the log file so it will be reopened (with new flag
10090  * bit) at next use.
10091  */
10092  if (openLogFile >= 0)
10093  {
10095  if (pg_fsync(openLogFile) != 0)
10096  ereport(PANIC,
10098  errmsg("could not fsync log segment %s: %m",
10101  if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
10102  XLogFileClose();
10103  }
10104  }
10105 }
static int get_sync_bit(int method)
Definition: xlog.c:10026
#define PANIC
Definition: elog.h:53
static XLogSegNo openLogSegNo
Definition: xlog.c:775
static void XLogFileClose(void)
Definition: xlog.c:3707
char * XLogFileNameP(TimeLineID tli, XLogSegNo segno)
Definition: xlog.c:10158
int errcode_for_file_access(void)
Definition: elog.c:598
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1260
#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:1236
int sync_method
Definition: xlog.c:103
int errmsg(const char *fmt,...)
Definition: elog.c:797
int pg_fsync(int fd)
Definition: fd.c:348

◆ BackupInProgress()

bool BackupInProgress ( void  )

Definition at line 11450 of file xlog.c.

References BACKUP_LABEL_FILE, and stat.

Referenced by pg_is_in_backup(), and PostmasterStateMachine().

11451 {
11452  struct stat stat_buf;
11453 
11454  return (stat(BACKUP_LABEL_FILE, &stat_buf) == 0);
11455 }
struct stat stat_buf
Definition: pg_standby.c:103
#define stat(a, b)
Definition: win32_port.h:266
#define BACKUP_LABEL_FILE
Definition: xlog.h:322

◆ BootStrapXLOG()

void BootStrapXLOG ( void  )

Definition at line 4996 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, TemplateDbOid, 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().

4997 {
4998  CheckPoint checkPoint;
4999  char *buffer;
5000  XLogPageHeader page;
5001  XLogLongPageHeader longpage;
5002  XLogRecord *record;
5003  char *recptr;
5004  bool use_existent;
5005  uint64 sysidentifier;
5006  char mock_auth_nonce[MOCK_AUTH_NONCE_LEN];
5007  struct timeval tv;
5008  pg_crc32c crc;
5009 
5010  /*
5011  * Select a hopefully-unique system identifier code for this installation.
5012  * We use the result of gettimeofday(), including the fractional seconds
5013  * field, as being about as unique as we can easily get. (Think not to
5014  * use random(), since it hasn't been seeded and there's no portable way
5015  * to seed it other than the system clock value...) The upper half of the
5016  * uint64 value is just the tv_sec part, while the lower half contains the
5017  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
5018  * PID for a little extra uniqueness. A person knowing this encoding can
5019  * determine the initialization time of the installation, which could
5020  * perhaps be useful sometimes.
5021  */
5022  gettimeofday(&tv, NULL);
5023  sysidentifier = ((uint64) tv.tv_sec) << 32;
5024  sysidentifier |= ((uint64) tv.tv_usec) << 12;
5025  sysidentifier |= getpid() & 0xFFF;
5026 
5027  /*
5028  * Generate a random nonce. This is used for authentication requests that
5029  * will fail because the user does not exist. The nonce is used to create
5030  * a genuine-looking password challenge for the non-existent user, in lieu
5031  * of an actual stored password.
5032  */
5033  if (!pg_backend_random(mock_auth_nonce, MOCK_AUTH_NONCE_LEN))
5034  ereport(PANIC,
5035  (errcode(ERRCODE_INTERNAL_ERROR),
5036  errmsg("could not generate secret authorization token")));
5037 
5038  /* First timeline ID is always 1 */
5039  ThisTimeLineID = 1;
5040 
5041  /* page buffer must be aligned suitably for O_DIRECT */
5042  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
5043  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
5044  memset(page, 0, XLOG_BLCKSZ);
5045 
5046  /*
5047  * Set up information for the initial checkpoint record
5048  *
5049  * The initial checkpoint record is written to the beginning of the WAL
5050  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5051  * used, so that we can use 0/0 to mean "before any valid WAL segment".
5052  */
5053  checkPoint.redo = wal_segment_size + SizeOfXLogLongPHD;
5054  checkPoint.ThisTimeLineID = ThisTimeLineID;
5055  checkPoint.PrevTimeLineID = ThisTimeLineID;
5056  checkPoint.fullPageWrites = fullPageWrites;
5057  checkPoint.nextXidEpoch = 0;
5058  checkPoint.nextXid = FirstNormalTransactionId;
5059  checkPoint.nextOid = FirstBootstrapObjectId;
5060  checkPoint.nextMulti = FirstMultiXactId;
5061  checkPoint.nextMultiOffset = 0;
5062  checkPoint.oldestXid = FirstNormalTransactionId;
5063  checkPoint.oldestXidDB = TemplateDbOid;
5064  checkPoint.oldestMulti = FirstMultiXactId;
5065  checkPoint.oldestMultiDB = TemplateDbOid;
5068  checkPoint.time = (pg_time_t) time(NULL);
5070 
5071  ShmemVariableCache->nextXid = checkPoint.nextXid;
5072  ShmemVariableCache->nextOid = checkPoint.nextOid;
5074  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5075  AdvanceOldestClogXid(checkPoint.oldestXid);
5076  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5077  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5079 
5080  /* Set up the XLOG page header */
5081  page->xlp_magic = XLOG_PAGE_MAGIC;
5082  page->xlp_info = XLP_LONG_HEADER;
5083  page->xlp_tli = ThisTimeLineID;
5085  longpage = (XLogLongPageHeader) page;
5086  longpage->xlp_sysid = sysidentifier;
5087  longpage->xlp_seg_size = wal_segment_size;
5088  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5089 
5090  /* Insert the initial checkpoint record */
5091  recptr = ((char *) page + SizeOfXLogLongPHD);
5092  record = (XLogRecord *) recptr;
5093  record->xl_prev = 0;
5094  record->xl_xid = InvalidTransactionId;
5095  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5097  record->xl_rmid = RM_XLOG_ID;
5098  recptr += SizeOfXLogRecord;
5099  /* fill the XLogRecordDataHeaderShort struct */
5100  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5101  *(recptr++) = sizeof(checkPoint);
5102  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5103  recptr += sizeof(checkPoint);
5104  Assert(recptr - (char *) record == record->xl_tot_len);
5105 
5106  INIT_CRC32C(crc);
5107  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5108  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5109  FIN_CRC32C(crc);
5110  record->xl_crc = crc;
5111 
5112  /* Create first XLOG segment file */
5113  use_existent = false;
5114  openLogFile = XLogFileInit(1, &use_existent, false);
5115 
5116  /* Write the first page with the initial record */
5117  errno = 0;
5119  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5120  {
5121  /* if write didn't set errno, assume problem is no disk space */
5122  if (errno == 0)
5123  errno = ENOSPC;
5124  ereport(PANIC,
5126  errmsg("could not write bootstrap write-ahead log file: %m")));
5127  }
5129 
5131  if (pg_fsync(openLogFile) != 0)
5132  ereport(PANIC,
5134  errmsg("could not fsync bootstrap write-ahead log file: %m")));
5136 
5137  if (close(openLogFile))
5138  ereport(PANIC,
5140  errmsg("could not close bootstrap write-ahead log file: %m")));
5141 
5142  openLogFile = -1;
5143 
5144  /* Now create pg_control */
5145 
5146  memset(ControlFile, 0, sizeof(ControlFileData));
5147  /* Initialize pg_control status fields */
5148  ControlFile->system_identifier = sysidentifier;
5149  memcpy(ControlFile->mock_authentication_nonce, mock_auth_nonce, MOCK_AUTH_NONCE_LEN);
5151  ControlFile->time = checkPoint.time;
5152  ControlFile->checkPoint = checkPoint.redo;
5153  ControlFile->checkPointCopy = checkPoint;
5154  ControlFile->unloggedLSN = 1;
5155 
5156  /* Set important parameter values for use when replaying WAL */
5165 
5166  /* some additional ControlFile fields are set in WriteControlFile() */
5167 
5168  WriteControlFile();
5169 
5170  /* Bootstrap the commit log, too */
5171  BootStrapCLOG();
5175 
5176  pfree(buffer);
5177 
5178  /*
5179  * Force control file to be read - in contrast to normal processing we'd
5180  * otherwise never run the checks and GUC related initializations therein.
5181  */
5182  ReadControlFile();
5183 }
static void WriteControlFile(void)
Definition: xlog.c:4375
#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:3160
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:936
#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:4464
uint32 nextXidEpoch
Definition: pg_control.h:42
bool track_commit_timestamp
Definition: commit_ts.c:103
#define TemplateDbOid
Definition: pg_database.h:80
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:1260
#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:124
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:634
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:688
#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:215
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1236
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:835
int errmsg(const char *fmt,...)
Definition: elog.c:797
int max_worker_processes
Definition: globals.c:125
int pg_fsync(int fd)
Definition: fd.c:348
#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:73
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:78
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:36
#define offsetof(type, field)
Definition: c.h:611
#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 2216 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().

2217 {
2218  double target;
2219 
2220  /*-------
2221  * Calculate the distance at which to trigger a checkpoint, to avoid
2222  * exceeding max_wal_size_mb. This is based on two assumptions:
2223  *
2224  * a) we keep WAL for only one checkpoint cycle (prior to PG11 we kept
2225  * WAL for two checkpoint cycles to allow us to recover from the
2226  * secondary checkpoint if the first checkpoint failed, though we
2227  * only did this on the master anyway, not on standby. Keeping just
2228  * one checkpoint simplifies processing and reduces disk space in
2229  * many smaller databases.)
2230  * b) during checkpoint, we consume checkpoint_completion_target *
2231  * number of segments consumed between checkpoints.
2232  *-------
2233  */
2234  target = (double) ConvertToXSegs(max_wal_size_mb, wal_segment_size) /
2236 
2237  /* round down */
2238  CheckPointSegments = (int) target;
2239 
2240  if (CheckPointSegments < 1)
2241  CheckPointSegments = 1;
2242 }
#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 11470 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().

11471 {
11472  struct stat stat_buf;
11473 
11474  /* if the backup_label file is not there, return */
11475  if (stat(BACKUP_LABEL_FILE, &stat_buf) < 0)
11476  return;
11477 
11478  /* remove leftover file from previously canceled backup if it exists */
11479  unlink(BACKUP_LABEL_OLD);
11480 
11482  {
11483  ereport(WARNING,
11485  errmsg("online backup mode was not canceled"),
11486  errdetail("File \"%s\" could not be renamed to \"%s\": %m.",
11488  return;
11489  }
11490 
11491  /* if the tablespace_map file is not there, return */
11492  if (stat(TABLESPACE_MAP, &stat_buf) < 0)
11493  {
11494  ereport(LOG,
11495  (errmsg("online backup mode canceled"),
11496  errdetail("File \"%s\" was renamed to \"%s\".",
11498  return;
11499  }
11500 
11501  /* remove leftover file from previously canceled backup if it exists */
11502  unlink(TABLESPACE_MAP_OLD);
11503 
11505  {
11506  ereport(LOG,
11507  (errmsg("online backup mode canceled"),
11508  errdetail("Files \"%s\" and \"%s\" were renamed to "
11509  "\"%s\" and \"%s\", respectively.",
11512  }
11513  else
11514  {
11515  ereport(WARNING,
11517  errmsg("online backup mode canceled"),
11518  errdetail("File \"%s\" was renamed to \"%s\", but "
11519  "file \"%s\" could not be renamed to \"%s\": %m.",
11522  }
11523 }
#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:103
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:608
#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 4787 of file xlog.c.

References XLOGbuffers, and XLOGChooseNumBuffers().

4788 {
4789  /*
4790  * -1 indicates a request for auto-tune.
4791  */
4792  if (*newval == -1)
4793  {
4794  /*
4795  * If we haven't yet changed the boot_val default of -1, just let it
4796  * be. We'll fix it when XLOGShmemSize is called.
4797  */
4798  if (XLOGbuffers == -1)
4799  return true;
4800 
4801  /* Otherwise, substitute the auto-tune value */
4803  }
4804 
4805  /*
4806  * We clamp manually-set values to at least 4 blocks. Prior to PostgreSQL
4807  * 9.1, a minimum of 4 was enforced by guc.c, but since that is no longer
4808  * the case, we just silently treat such values as a request for the
4809  * minimum. (We could throw an error instead, but that doesn't seem very
4810  * helpful.)
4811  */
4812  if (*newval < 4)
4813  *newval = 4;
4814 
4815  return true;
4816 }
static int XLOGChooseNumBuffers(void)
Definition: xlog.c:4771
#define newval
int XLOGbuffers
Definition: xlog.c:92

◆ CheckForStandbyTrigger()

static bool CheckForStandbyTrigger ( void  )
static

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

12117 {
12118  struct stat stat_buf;
12119  static bool triggered = false;
12120 
12121  if (triggered)
12122  return true;
12123 
12124  if (IsPromoteTriggered())
12125  {
12126  /*
12127  * In 9.1 and 9.2 the postmaster unlinked the promote file inside the
12128  * signal handler. It now leaves the file in place and lets the
12129  * Startup process do the unlink. This allows Startup to know whether
12130  * it should create a full checkpoint before starting up (fallback
12131  * mode). Fast promotion takes precedence.
12132  */
12133  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
12134  {
12135  unlink(PROMOTE_SIGNAL_FILE);
12137  fast_promote = true;
12138  }
12139  else if (stat(FALLBACK_PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
12140  {
12142  fast_promote = false;
12143  }
12144 
12145  ereport(LOG, (errmsg("received promote request")));
12146 
12148  triggered = true;
12149  return true;
12150  }
12151 
12152  if (TriggerFile == NULL)
12153  return false;
12154 
12155  if (stat(TriggerFile, &stat_buf) == 0)
12156  {
12157  ereport(LOG,
12158  (errmsg("trigger file found: %s", TriggerFile)));
12159  unlink(TriggerFile);
12160  triggered = true;
12161  fast_promote = true;
12162  return true;
12163  }
12164  else if (errno != ENOENT)
12165  ereport(ERROR,
12167  errmsg("could not stat trigger file \"%s\": %m",
12168  TriggerFile)));
12169 
12170  return false;
12171 }
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:103
#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 9033 of file xlog.c.

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

Referenced by CreateCheckPoint(), and CreateRestartPoint().

9034 {
9035  CheckPointCLOG();
9044  CheckPointBuffers(flags); /* performs all required fsyncs */
9046  /* We deliberately delay 2PC checkpointing as long as possible */
9047  CheckPointTwoPhase(checkPointRedo);
9048 }
void CheckPointBuffers(int flags)
Definition: bufmgr.c:2574
void CheckPointLogicalRewriteHeap(void)
Definition: rewriteheap.c:1201
void CheckPointReplicationOrigin(void)
Definition: origin.c:545
void CheckPointSnapBuild(void)
Definition: snapbuild.c:1861
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:1043
void CheckPointTwoPhase(XLogRecPtr redo_horizon)
Definition: twophase.c:1651
void CheckPointReplicationSlots(void)
Definition: slot.c:1055

◆ CheckPromoteSignal()

bool CheckPromoteSignal ( void  )

Definition at line 12188 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, PROMOTE_SIGNAL_FILE, and stat.

Referenced by sigusr1_handler().

12189 {
12190  struct stat stat_buf;
12191 
12192  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
12194  return true;
12195 
12196  return false;
12197 }
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.c:85
struct stat stat_buf
Definition: pg_standby.c:103
#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 7820 of file xlog.c.

References ControlFileData::backupEndPoint, ControlFileData::backupEndRequired, ControlFileData::backupStartPoint, DEBUG1, elog, ereport, errmsg(), 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().

7821 {
7822  XLogRecPtr lastReplayedEndRecPtr;
7823 
7824  /*
7825  * During crash recovery, we don't reach a consistent state until we've
7826  * replayed all the WAL.
7827  */
7829  return;
7830 
7831  /*
7832  * assume that we are called in the startup process, and hence don't need
7833  * a lock to read lastReplayedEndRecPtr
7834  */
7835  lastReplayedEndRecPtr = XLogCtl->lastReplayedEndRecPtr;
7836 
7837  /*
7838  * Have we reached the point where our base backup was completed?
7839  */
7841  ControlFile->backupEndPoint <= lastReplayedEndRecPtr)
7842  {
7843  /*
7844  * We have reached the end of base backup, as indicated by pg_control.
7845  * The data on disk is now consistent. Reset backupStartPoint and
7846  * backupEndPoint, and update minRecoveryPoint to make sure we don't
7847  * allow starting up at an earlier point even if recovery is stopped
7848  * and restarted soon after this.
7849  */
7850  elog(DEBUG1, "end of backup reached");
7851 
7852  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7853 
7854  if (ControlFile->minRecoveryPoint < lastReplayedEndRecPtr)
7855  ControlFile->minRecoveryPoint = lastReplayedEndRecPtr;
7856 
7859  ControlFile->backupEndRequired = false;
7861 
7862  LWLockRelease(ControlFileLock);
7863  }
7864 
7865  /*
7866  * Have we passed our safe starting point? Note that minRecoveryPoint is
7867  * known to be incorrectly set if ControlFile->backupEndRequired, until
7868  * the XLOG_BACKUP_END arrives to advise us of the correct
7869  * minRecoveryPoint. All we know prior to that is that we're not
7870  * consistent yet.
7871  */
7873  minRecoveryPoint <= lastReplayedEndRecPtr &&
7875  {
7876  /*
7877  * Check to see if the XLOG sequence contained any unresolved
7878  * references to uninitialized pages.
7879  */
7881 
7882  reachedConsistency = true;
7883  ereport(LOG,
7884  (errmsg("consistent recovery state reached at %X/%X",
7885  (uint32) (lastReplayedEndRecPtr >> 32),
7886  (uint32) lastReplayedEndRecPtr)));
7887  }
7888 
7889  /*
7890  * Have we got a valid starting snapshot that will allow queries to be
7891  * run? If so, we can tell postmaster that the database is consistent now,
7892  * enabling connections.
7893  */
7898  {
7902 
7903  LocalHotStandbyActive = true;
7904 
7906  }
7907 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define DEBUG1
Definition: elog.h:25
void XLogCheckInvalidPages(void)
Definition: xlogutils.c:221
bool SharedHotStandbyActive
Definition: xlog.c:649
slock_t info_lck
Definition: xlog.c:704
#define LOG
Definition: elog.h:26
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1724
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:4663
bool IsUnderPostmaster
Definition: globals.c:101
unsigned int uint32
Definition: c.h:314
#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:834
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:707
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1120
int errmsg(const char *fmt,...)
Definition: elog.c:797
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:113
#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:824
XLogRecPtr lastReplayedEndRecPtr
Definition: xlog.c:683

◆ CheckRequiredParameterValues()

static void CheckRequiredParameterValues ( void  )
static

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

6214 {
6215  /*
6216  * For archive recovery, the WAL must be generated with at least 'replica'
6217  * wal_level.
6218  */
6220  {
6221  ereport(WARNING,
6222  (errmsg("WAL was generated with wal_level=minimal, data may be missing"),
6223  errhint("This happens if you temporarily set wal_level=minimal without taking a new base backup.")));
6224  }
6225 
6226  /*
6227  * For Hot Standby, the WAL must be generated with 'replica' mode, and we
6228  * must have at least as many backend slots as the primary.
6229  */
6231  {
6233  ereport(ERROR,
6234  (errmsg("hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server"),
6235  errhint("Either set wal_level to \"replica\" on the master, or turn off hot_standby here.")));
6236 
6237  /* We ignore autovacuum_max_workers when we make this test. */
6238  RecoveryRequiresIntParameter("max_connections",
6241  RecoveryRequiresIntParameter("max_worker_processes",
6244  RecoveryRequiresIntParameter("max_prepared_transactions",
6247  RecoveryRequiresIntParameter("max_locks_per_transaction",
6250  }
6251 }
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:124
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:125
#define RecoveryRequiresIntParameter(param_name, currValue, minValue)
Definition: xlog.c:6191

◆ checkTimeLineSwitch()

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

Definition at line 9590 of file xlog.c.

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

Referenced by StartupXLOG().

9591 {
9592  /* Check that the record agrees on what the current (old) timeline is */
9593  if (prevTLI != ThisTimeLineID)
9594  ereport(PANIC,
9595  (errmsg("unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record",
9596  prevTLI, ThisTimeLineID)));
9597 
9598  /*
9599  * The new timeline better be in the list of timelines we expect to see,
9600  * according to the timeline history. It should also not decrease.
9601  */
9602  if (newTLI < ThisTimeLineID || !tliInHistory(newTLI, expectedTLEs))
9603  ereport(PANIC,
9604  (errmsg("unexpected timeline ID %u (after %u) in checkpoint record",
9605  newTLI, ThisTimeLineID)));
9606 
9607  /*
9608  * If we have not yet reached min recovery point, and we're about to
9609  * switch to a timeline greater than the timeline of the min recovery
9610  * point: trouble. After switching to the new timeline, we could not
9611  * possibly visit the min recovery point on the correct timeline anymore.
9612  * This can happen if there is a newer timeline in the archive that
9613  * branched before the timeline the min recovery point is on, and you
9614  * attempt to do PITR to the new timeline.
9615  */
9617  lsn < minRecoveryPoint &&
9618  newTLI > minRecoveryPointTLI)
9619  ereport(PANIC,
9620  (errmsg("unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u",
9621  newTLI,
9622  (uint32) (minRecoveryPoint >> 32),
9625 
9626  /* Looks good */
9627 }
static List * expectedTLEs
Definition: xlog.c:320
#define PANIC
Definition: elog.h:53
unsigned int uint32
Definition: c.h:314
#define ereport(elevel, rest)
Definition: elog.h:122
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
static TimeLineID minRecoveryPointTLI
Definition: xlog.c:826
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:824

◆ checkXLogConsistency()

static void checkXLogConsistency ( XLogReaderState record)
static

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

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

◆ CheckXLogRemoved()

void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)

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

3775 {
3776  int save_errno = errno;
3777  XLogSegNo lastRemovedSegNo;
3778 
3780  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3782 
3783  if (segno <= lastRemovedSegNo)
3784  {
3785  char filename[MAXFNAMELEN];
3786 
3787  XLogFileName(filename, tli, segno, wal_segment_size);
3788  errno = save_errno;
3789  ereport(ERROR,
3791  errmsg("requested WAL segment %s has already been removed",
3792  filename)));
3793  }
3794  errno = save_errno;
3795 }
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:85
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ CleanupBackupHistory()

static void CleanupBackupHistory ( void  )
static

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

4103 {
4104  DIR *xldir;
4105  struct dirent *xlde;
4106  char path[MAXPGPATH + sizeof(XLOGDIR)];
4107 
4108  xldir = AllocateDir(XLOGDIR);
4109 
4110  while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
4111  {
4112  if (IsBackupHistoryFileName(xlde->d_name))
4113  {
4114  if (XLogArchiveCheckDone(xlde->d_name))
4115  {
4116  elog(DEBUG2, "removing WAL backup history file \"%s\"",
4117  xlde->d_name);
4118  snprintf(path, sizeof(path), XLOGDIR "/%s", xlde->d_name);
4119  unlink(path);
4120  XLogArchiveCleanup(xlde->d_name);
4121  }
4122  }
4123  }
4124 
4125  FreeDir(xldir);
4126 }
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:2607
#define IsBackupHistoryFileName(fname)
#define XLOGDIR
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2673
char d_name[MAX_PATH]
Definition: dirent.h:14
#define elog
Definition: elog.h:219
int FreeDir(DIR *dir)
Definition: fd.c:2725

◆ CopyXLogRecordToWAL()

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

Definition at line 1453 of file xlog.c.

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

Referenced by XLogInsertRecord().

1455 {
1456  char *currpos;
1457  int freespace;
1458  int written;
1459  XLogRecPtr CurrPos;
1460  XLogPageHeader pagehdr;
1461 
1462  /*
1463  * Get a pointer to the right place in the right WAL buffer to start
1464  * inserting to.
1465  */
1466  CurrPos = StartPos;
1467  currpos = GetXLogBuffer(CurrPos);
1468  freespace = INSERT_FREESPACE(CurrPos);
1469 
1470  /*
1471  * there should be enough space for at least the first field (xl_tot_len)
1472  * on this page.
1473  */
1474  Assert(freespace >= sizeof(uint32));
1475 
1476  /* Copy record data */
1477  written = 0;
1478  while (rdata != NULL)
1479  {
1480  char *rdata_data = rdata->data;
1481  int rdata_len = rdata->len;
1482 
1483  while (rdata_len > freespace)
1484  {
1485  /*
1486  * Write what fits on this page, and continue on the next page.
1487  */
1488  Assert(CurrPos % XLOG_BLCKSZ >= SizeOfXLogShortPHD || freespace == 0);
1489  memcpy(currpos, rdata_data, freespace);
1490  rdata_data += freespace;
1491  rdata_len -= freespace;
1492  written += freespace;
1493  CurrPos += freespace;
1494 
1495  /*
1496  * Get pointer to beginning of next page, and set the xlp_rem_len
1497  * in the page header. Set XLP_FIRST_IS_CONTRECORD.
1498  *
1499  * It's safe to set the contrecord flag and xlp_rem_len without a
1500  * lock on the page. All the other flags were already set when the
1501  * page was initialized, in AdvanceXLInsertBuffer, and we're the
1502  * only backend that needs to set the contrecord flag.
1503  */
1504  currpos = GetXLogBuffer(CurrPos);
1505  pagehdr = (XLogPageHeader) currpos;
1506  pagehdr->xlp_rem_len = write_len - written;
1507  pagehdr->xlp_info |= XLP_FIRST_IS_CONTRECORD;
1508 
1509  /* skip over the page header */
1510  if (XLogSegmentOffset(CurrPos, wal_segment_size) == 0)
1511  {
1512  CurrPos += SizeOfXLogLongPHD;
1513  currpos += SizeOfXLogLongPHD;
1514  }
1515  else
1516  {
1517  CurrPos += SizeOfXLogShortPHD;
1518  currpos += SizeOfXLogShortPHD;
1519  }
1520  freespace = INSERT_FREESPACE(CurrPos);
1521  }
1522 
1523  Assert(CurrPos % XLOG_BLCKSZ >= SizeOfXLogShortPHD || rdata_len == 0);
1524  memcpy(currpos, rdata_data, rdata_len);
1525  currpos += rdata_len;
1526  CurrPos += rdata_len;
1527  freespace -= rdata_len;
1528  written += rdata_len;
1529 
1530  rdata = rdata->next;
1531  }
1532  Assert(written == write_len);
1533 
1534  /*
1535  * If this was an xlog-switch, it's not enough to write the switch record,
1536  * we also have to consume all the remaining space in the WAL segment. We
1537  * have already reserved it for us, but we still need to make sure it's
1538  * allocated and zeroed in the WAL buffers so that when the caller (or
1539  * someone else) does XLogWrite(), it can really write out all the zeros.
1540  */
1541  if (isLogSwitch && XLogSegmentOffset(CurrPos, wal_segment_size) != 0)
1542  {
1543  /* An xlog-switch record doesn't contain any data besides the header */
1544  Assert(write_len == SizeOfXLogRecord);
1545 
1546  /*
1547  * We do this one page at a time, to make sure we don't deadlock
1548  * against ourselves if wal_buffers < wal_segment_size.
1549  */
1550  Assert(XLogSegmentOffset(EndPos, wal_segment_size) == 0);
1551 
1552  /* Use up all the remaining space on the first page */
1553  CurrPos += freespace;
1554 
1555  while (CurrPos < EndPos)
1556  {
1557  /* initialize the next page (if not initialized already) */
1559  AdvanceXLInsertBuffer(CurrPos, false);
1560  CurrPos += XLOG_BLCKSZ;
1561  }
1562  }
1563  else
1564  {
1565  /* Align the end position, so that the next record starts aligned */
1566  CurrPos = MAXALIGN64(CurrPos);
1567  }
1568 
1569  if (CurrPos != EndPos)
1570  elog(PANIC, "space reserved for WAL record does not match what was written");
1571 }
int wal_segment_size
Definition: xlog.c:113
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:57
#define PANIC
Definition: elog.h:53
static char * GetXLogBuffer(XLogRecPtr ptr)
Definition: xlog.c:1809
#define MAXALIGN64(LEN)
Definition: c.h:666
static void WALInsertLockUpdateInsertingAt(XLogRecPtr insertingAt)
Definition: xlog.c:1677
unsigned int uint32
Definition: c.h:314
#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:688
#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
static void AdvanceXLInsertBuffer(XLogRecPtr upto, bool opportunistic)
Definition: xlog.c:2047
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72

◆ CreateCheckPoint()

void CreateCheckPoint ( int  flags)

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

8558 {
8559  bool shutdown;
8560  CheckPoint checkPoint;
8561  XLogRecPtr recptr;
8563  uint32 freespace;
8564  XLogRecPtr PriorRedoPtr;
8565  XLogRecPtr curInsert;
8566  XLogRecPtr last_important_lsn;
8567  VirtualTransactionId *vxids;
8568  int nvxids;
8569 
8570  /*
8571  * An end-of-recovery checkpoint is really a shutdown checkpoint, just
8572  * issued at a different time.
8573  */
8575  shutdown = true;
8576  else
8577  shutdown = false;
8578 
8579  /* sanity check */
8580  if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
8581  elog(ERROR, "can't create a checkpoint during recovery");
8582 
8583  /*
8584  * Initialize InitXLogInsert working areas before entering the critical
8585  * section. Normally, this is done by the first call to
8586  * RecoveryInProgress() or LocalSetXLogInsertAllowed(), but when creating
8587  * an end-of-recovery checkpoint, the LocalSetXLogInsertAllowed call is
8588  * done below in a critical section, and InitXLogInsert cannot be called
8589  * in a critical section.
8590  */
8591  InitXLogInsert();
8592 
8593  /*
8594  * Acquire CheckpointLock to ensure only one checkpoint happens at a time.
8595  * (This is just pro forma, since in the present system structure there is
8596  * only one process that is allowed to issue checkpoints at any given
8597  * time.)
8598  */
8599  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
8600 
8601  /*
8602  * Prepare to accumulate statistics.
8603  *
8604  * Note: because it is possible for log_checkpoints to change while a
8605  * checkpoint proceeds, we always accumulate stats, even if
8606  * log_checkpoints is currently off.
8607  */
8608  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
8610 
8611  /*
8612  * Use a critical section to force system panic if we have trouble.
8613  */
8615 
8616  if (shutdown)
8617  {
8618  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8620  ControlFile->time = (pg_time_t) time(NULL);
8622  LWLockRelease(ControlFileLock);
8623  }
8624 
8625  /*
8626  * Let smgr prepare for checkpoint; this has to happen before we determine
8627  * the REDO pointer. Note that smgr must not do anything that'd have to
8628  * be undone if we decide no checkpoint is needed.
8629  */
8630  smgrpreckpt();
8631 
8632  /* Begin filling in the checkpoint WAL record */
8633  MemSet(&checkPoint, 0, sizeof(checkPoint));
8634  checkPoint.time = (pg_time_t) time(NULL);
8635 
8636  /*
8637  * For Hot Standby, derive the oldestActiveXid before we fix the redo
8638  * pointer. This allows us to begin accumulating changes to assemble our
8639  * starting snapshot of locks and transactions.
8640  */
8641  if (!shutdown && XLogStandbyInfoActive())
8643  else
8645 
8646  /*
8647  * Get location of last important record before acquiring insert locks (as
8648  * GetLastImportantRecPtr() also locks WAL locks).
8649  */
8650  last_important_lsn = GetLastImportantRecPtr();
8651 
8652  /*
8653  * We must block concurrent insertions while examining insert state to
8654  * determine the checkpoint REDO pointer.
8655  */
8657  curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
8658 
8659  /*
8660  * If this isn't a shutdown or forced checkpoint, and if there has been no
8661  * WAL activity requiring a checkpoint, skip it. The idea here is to
8662  * avoid inserting duplicate checkpoints when the system is idle.
8663  */
8664  if ((flags & (CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_END_OF_RECOVERY |
8665  CHECKPOINT_FORCE)) == 0)
8666  {
8667  if (last_important_lsn == ControlFile->checkPoint)
8668  {
8670  LWLockRelease(CheckpointLock);
8671  END_CRIT_SECTION();
8672  ereport(DEBUG1,
8673  (errmsg("checkpoint skipped because system is idle")));
8674  return;
8675  }
8676  }
8677 
8678  /*
8679  * An end-of-recovery checkpoint is created before anyone is allowed to
8680  * write WAL. To allow us to write the checkpoint record, temporarily
8681  * enable XLogInsertAllowed. (This also ensures ThisTimeLineID is
8682  * initialized, which we need here and in AdvanceXLInsertBuffer.)
8683  */
8684  if (flags & CHECKPOINT_END_OF_RECOVERY)
8686 
8687  checkPoint.ThisTimeLineID = ThisTimeLineID;
8688  if (flags & CHECKPOINT_END_OF_RECOVERY)
8689  checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
8690  else
8691  checkPoint.PrevTimeLineID = ThisTimeLineID;
8692 
8693  checkPoint.fullPageWrites = Insert->fullPageWrites;
8694 
8695  /*
8696  * Compute new REDO record ptr = location of next XLOG record.
8697  *
8698  * NB: this is NOT necessarily where the checkpoint record itself will be,
8699  * since other backends may insert more XLOG records while we're off doing
8700  * the buffer flush work. Those XLOG records are logically after the
8701  * checkpoint, even though physically before it. Got that?
8702  */
8703  freespace = INSERT_FREESPACE(curInsert);
8704  if (freespace == 0)
8705  {
8706  if (XLogSegmentOffset(curInsert, wal_segment_size) == 0)
8707  curInsert += SizeOfXLogLongPHD;
8708  else
8709  curInsert += SizeOfXLogShortPHD;
8710  }
8711  checkPoint.redo = curInsert;
8712 
8713  /*
8714  * Here we update the shared RedoRecPtr for future XLogInsert calls; this
8715  * must be done while holding all the insertion locks.
8716  *
8717  * Note: if we fail to complete the checkpoint, RedoRecPtr will be left
8718  * pointing past where it really needs to point. This is okay; the only
8719  * consequence is that XLogInsert might back up whole buffers that it
8720  * didn't really need to. We can't postpone advancing RedoRecPtr because
8721  * XLogInserts that happen while we are dumping buffers must assume that
8722  * their buffer changes are not included in the checkpoint.
8723  */
8724  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
8725 
8726  /*
8727  * Now we can release the WAL insertion locks, allowing other xacts to
8728  * proceed while we are flushing disk buffers.
8729  */
8731 
8732  /* Update the info_lck-protected copy of RedoRecPtr as well */
8734  XLogCtl->RedoRecPtr = checkPoint.redo;
8736 
8737  /*
8738  * If enabled, log checkpoint start. We postpone this until now so as not
8739  * to log anything if we decided to skip the checkpoint.
8740  */
8741  if (log_checkpoints)
8742  LogCheckpointStart(flags, false);
8743 
8744  TRACE_POSTGRESQL_CHECKPOINT_START(flags);
8745 
8746  /*
8747  * Get the other info we need for the checkpoint record.
8748  *
8749  * We don't need to save oldestClogXid in the checkpoint, it only matters
8750  * for the short period in which clog is being truncated, and if we crash
8751  * during that we'll redo the clog truncation and fix up oldestClogXid
8752  * there.
8753  */
8754  LWLockAcquire(XidGenLock, LW_SHARED);
8755  checkPoint.nextXid = ShmemVariableCache->nextXid;
8756  checkPoint.oldestXid = ShmemVariableCache->oldestXid;
8758  LWLockRelease(XidGenLock);
8759 
8760  LWLockAcquire(CommitTsLock, LW_SHARED);
8763  LWLockRelease(CommitTsLock);
8764 
8765  /* Increase XID epoch if we've wrapped around since last checkpoint */
8767  if (checkPoint.nextXid < ControlFile->checkPointCopy.nextXid)
8768  checkPoint.nextXidEpoch++;
8769 
8770  LWLockAcquire(OidGenLock, LW_SHARED);
8771  checkPoint.nextOid = ShmemVariableCache->nextOid;
8772  if (!shutdown)
8773  checkPoint.nextOid += ShmemVariableCache->oidCount;
8774  LWLockRelease(OidGenLock);
8775 
8776  MultiXactGetCheckptMulti(shutdown,
8777  &checkPoint.nextMulti,
8778  &checkPoint.nextMultiOffset,
8779  &checkPoint.oldestMulti,
8780  &checkPoint.oldestMultiDB);
8781 
8782  /*
8783  * Having constructed the checkpoint record, ensure all shmem disk buffers
8784  * and commit-log buffers are flushed to disk.
8785  *
8786  * This I/O could fail for various reasons. If so, we will fail to
8787  * complete the checkpoint, but there is no reason to force a system
8788  * panic. Accordingly, exit critical section while doing it.
8789  */
8790  END_CRIT_SECTION();
8791 
8792  /*
8793  * In some cases there are groups of actions that must all occur on one
8794  * side or the other of a checkpoint record. Before flushing the
8795  * checkpoint record we must explicitly wait for any backend currently
8796  * performing those groups of actions.
8797  *
8798  * One example is end of transaction, so we must wait for any transactions
8799  * that are currently in commit critical sections. If an xact inserted
8800  * its commit record into XLOG just before the REDO point, then a crash
8801  * restart from the REDO point would not replay that record, which means
8802  * that our flushing had better include the xact's update of pg_xact. So
8803  * we wait till he's out of his commit critical section before proceeding.
8804  * See notes in RecordTransactionCommit().
8805  *
8806  * Because we've already released the insertion locks, this test is a bit
8807  * fuzzy: it is possible that we will wait for xacts we didn't really need
8808  * to wait for. But the delay should be short and it seems better to make
8809  * checkpoint take a bit longer than to hold off insertions longer than
8810  * necessary. (In fact, the whole reason we have this issue is that xact.c
8811  * does commit record XLOG insertion and clog update as two separate steps
8812  * protected by different locks, but again that seems best on grounds of
8813  * minimizing lock contention.)
8814  *
8815  * A transaction that has not yet set delayChkpt when we look cannot be at
8816  * risk, since he's not inserted his commit record yet; and one that's
8817  * already cleared it is not at risk either, since he's done fixing clog
8818  * and we will correctly flush the update below. So we cannot miss any
8819  * xacts we need to wait for.
8820  */
8821  vxids = GetVirtualXIDsDelayingChkpt(&nvxids);
8822  if (nvxids > 0)
8823  {
8824  do
8825  {
8826  pg_usleep(10000L); /* wait for 10 msec */
8827  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids));
8828  }
8829  pfree(vxids);
8830 
8831  CheckPointGuts(checkPoint.redo, flags);
8832 
8833  /*
8834  * Take a snapshot of running transactions and write this to WAL. This
8835  * allows us to reconstruct the state of running transactions during
8836  * archive recovery, if required. Skip, if this info disabled.
8837  *
8838  * If we are shutting down, or Startup process is completing crash
8839  * recovery we don't need to write running xact data.
8840  */
8841  if (!shutdown && XLogStandbyInfoActive())
8843 
8845 
8846  /*
8847  * Now insert the checkpoint record into XLOG.
8848  */
8849  XLogBeginInsert();
8850  XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));
8851  recptr = XLogInsert(RM_XLOG_ID,
8852  shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
8854 
8855  XLogFlush(recptr);
8856 
8857  /*
8858  * We mustn't write any new WAL after a shutdown checkpoint, or it will be
8859  * overwritten at next startup. No-one should even try, this just allows
8860  * sanity-checking. In the case of an end-of-recovery checkpoint, we want
8861  * to just temporarily disable writing until the system has exited
8862  * recovery.
8863  */
8864  if (shutdown)
8865  {
8866  if (flags & CHECKPOINT_END_OF_RECOVERY)
8867  LocalXLogInsertAllowed = -1; /* return to "check" state */
8868  else
8869  LocalXLogInsertAllowed = 0; /* never again write WAL */
8870  }
8871 
8872  /*
8873  * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
8874  * = end of actual checkpoint record.
8875  */
8876  if (shutdown && checkPoint.redo != ProcLastRecPtr)
8877  ereport(PANIC,
8878  (errmsg("concurrent write-ahead log activity while database system is shutting down")));
8879 
8880  /*
8881  * Remember the prior checkpoint's redo ptr for
8882  * UpdateCheckPointDistanceEstimate()
8883  */
8884  PriorRedoPtr = ControlFile->checkPointCopy.redo;
8885 
8886  /*
8887  * Update the control file.
8888  */
8889  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8890  if (shutdown)
8893  ControlFile->checkPointCopy = checkPoint;
8894  ControlFile->time = (pg_time_t) time(NULL);
8895  /* crash recovery should always recover to the end of WAL */
8898 
8899  /*
8900  * Persist unloggedLSN value. It's reset on crash recovery, so this goes
8901  * unused on non-shutdown checkpoints, but seems useful to store it always
8902  * for debugging purposes.
8903  */
8907 
8909  LWLockRelease(ControlFileLock);
8910 
8911  /* Update shared-memory copy of checkpoint XID/epoch */
8913  XLogCtl->ckptXidEpoch = checkPoint.nextXidEpoch;
8914  XLogCtl->ckptXid = checkPoint.nextXid;
8916 
8917  /*
8918  * We are now done with critical updates; no need for system panic if we
8919  * have trouble while fooling with old log segments.
8920  */
8921  END_CRIT_SECTION();
8922 
8923  /*
8924  * Let smgr do post-checkpoint cleanup (eg, deleting old files).
8925  */
8926  smgrpostckpt();
8927 
8928  /*
8929  * Delete old log files and recycle them
8930  */
8931  if (PriorRedoPtr != InvalidXLogRecPtr)
8932  {
8933  XLogSegNo _logSegNo;
8934 
8935  /* Update the average distance between checkpoints. */
8937 
8938  /* Trim from the last checkpoint, not the last - 1 */
8940  KeepLogSeg(recptr, &_logSegNo);
8941  _logSegNo--;
8942  RemoveOldXlogFiles(_logSegNo, PriorRedoPtr, recptr);
8943  }
8944 
8945  /*
8946  * Make more log segments if needed. (Do this after recycling old log
8947  * segments, since that may supply some of the needed files.)
8948  */
8949  if (!shutdown)
8950  PreallocXlogFiles(recptr);
8951 
8952  /*
8953  * Truncate pg_subtrans if possible. We can throw away all data before
8954  * the oldest XMIN of any running transaction. No future transaction will
8955  * attempt to reference any pg_subtrans entry older than that (see Asserts
8956  * in subtrans.c). During recovery, though, we mustn't do this because
8957  * StartupSUBTRANS hasn't been called yet.
8958  */
8959  if (!RecoveryInProgress())
8961 
8962  /* Real work is done, but log and update stats before releasing lock. */
8963  LogCheckpointEnd(false);
8964 
8965  TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
8966  NBuffers,
8970 
8971  LWLockRelease(CheckpointLock);
8972 }
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:8269
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8495
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:1651
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:1570
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1920
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:2254
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:897
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
Definition: xlog.c:3842
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:9033
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:7919
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:2763
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1724
#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:4663
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
void pfree(void *pointer)
Definition: mcxt.c:936
XLogRecPtr LogStandbySnapshot(void)
Definition: standby.c:909
#define ERROR
Definition: elog.h:43
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8410
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:3741
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:314
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:1069
int ckpt_bufs_written
Definition: xlog.h:205
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8045
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:9356
#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:1315
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:1622
static XLogCtlData * XLogCtl
Definition: xlog.c:707
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1120
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:2092
int NBuffers
Definition: globals.c:123
#define elog
Definition: elog.h:219
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids)
Definition: procarray.c:2299
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:8392
#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 8984 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().

8985 {
8986  xl_end_of_recovery xlrec;
8987  XLogRecPtr recptr;
8988 
8989  /* sanity check */
8990  if (!RecoveryInProgress())
8991  elog(ERROR, "can only be used to end recovery");
8992 
8993  xlrec.end_time = GetCurrentTimestamp();
8994 
8999 
9001 
9003 
9004  XLogBeginInsert();
9005  XLogRegisterData((char *) &xlrec, sizeof(xl_end_of_recovery));
9006  recptr = XLogInsert(RM_XLOG_ID, XLOG_END_OF_RECOVERY);
9007 
9008  XLogFlush(recptr);
9009 
9010  /*
9011  * Update the control file so that crash recovery can follow the timeline
9012  * changes to this point.
9013  */
9014  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9015  ControlFile->time = (pg_time_t) time(NULL);
9016  ControlFile->minRecoveryPoint = recptr;
9019  LWLockRelease(ControlFileLock);
9020 
9021  END_CRIT_SECTION();
9022 
9023  LocalXLogInsertAllowed = -1; /* return to "check" state */
9024 }
static int LocalXLogInsertAllowed
Definition: xlog.c:235
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1651
pg_time_t time
Definition: pg_control.h:128
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
TimeLineID PrevTimeLineID
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1570
#define END_CRIT_SECTION()
Definition: miscadmin.h:133
TimeLineID PrevTimeLineID
Definition: xlog.c:631
#define START_CRIT_SECTION()
Definition: miscadmin.h:131
bool RecoveryInProgress(void)
Definition: xlog.c:7919
#define XLOG_END_OF_RECOVERY
Definition: pg_control.h:76
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2763
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1724
void UpdateControlFile(void)
Definition: xlog.c:4663
#define ERROR
Definition: elog.h:43
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8045
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:1622
static XLogCtlData * XLogCtl
Definition: xlog.c:707
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1120
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 9103 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().

9104 {
9105  XLogRecPtr lastCheckPointRecPtr;
9106  XLogRecPtr lastCheckPointEndPtr;
9107  CheckPoint lastCheckPoint;
9108  XLogRecPtr PriorRedoPtr;
9109  TimestampTz xtime;
9110 
9111  /*
9112  * Acquire CheckpointLock to ensure only one restartpoint or checkpoint
9113  * happens at a time.
9114  */
9115  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
9116 
9117  /* Get a local copy of the last safe checkpoint record. */
9119  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
9120  lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
9121  lastCheckPoint = XLogCtl->lastCheckPoint;
9123 
9124  /*
9125  * Check that we're still in recovery mode. It's ok if we exit recovery
9126  * mode after this check, the restart point is valid anyway.
9127  */
9128  if (!RecoveryInProgress())
9129  {
9130  ereport(DEBUG2,
9131  (errmsg("skipping restartpoint, recovery has already ended")));
9132  LWLockRelease(CheckpointLock);
9133  return false;
9134  }
9135 
9136  /*
9137  * If the last checkpoint record we've replayed is already our last
9138  * restartpoint, we can't perform a new restart point. We still update
9139  * minRecoveryPoint in that case, so that if this is a shutdown restart
9140  * point, we won't start up earlier than before. That's not strictly
9141  * necessary, but when hot standby is enabled, it would be rather weird if
9142  * the database opened up for read-only connections at a point-in-time
9143  * before the last shutdown. Such time travel is still possible in case of
9144  * immediate shutdown, though.
9145  *
9146  * We don't explicitly advance minRecoveryPoint when we do create a
9147  * restartpoint. It's assumed that flushing the buffers will do that as a
9148  * side-effect.
9149  */
9150  if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
9151  lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
9152  {
9153  ereport(DEBUG2,
9154  (errmsg("skipping restartpoint, already performed at %X/%X",
9155  (uint32) (lastCheckPoint.redo >> 32),
9156  (uint32) lastCheckPoint.redo)));
9157 
9159  if (flags & CHECKPOINT_IS_SHUTDOWN)
9160  {
9161  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9163  ControlFile->time = (pg_time_t) time(NULL);
9165  LWLockRelease(ControlFileLock);
9166  }
9167  LWLockRelease(CheckpointLock);
9168  return false;
9169  }
9170 
9171  /*
9172  * Update the shared RedoRecPtr so that the startup process can calculate
9173  * the number of segments replayed since last restartpoint, and request a
9174  * restartpoint if it exceeds CheckPointSegments.
9175  *
9176  * Like in CreateCheckPoint(), hold off insertions to update it, although
9177  * during recovery this is just pro forma, because no WAL insertions are
9178  * happening.
9179  */
9181  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
9183 
9184  /* Also update the info_lck-protected copy */
9186  XLogCtl->RedoRecPtr = lastCheckPoint.redo;
9188 
9189  /*
9190  * Prepare to accumulate statistics.
9191  *
9192  * Note: because it is possible for log_checkpoints to change while a
9193  * checkpoint proceeds, we always accumulate stats, even if
9194  * log_checkpoints is currently off.
9195  */
9196  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
9198 
9199  if (log_checkpoints)
9200  LogCheckpointStart(flags, true);
9201 
9202  CheckPointGuts(lastCheckPoint.redo, flags);
9203 
9204  /*
9205  * Remember the prior checkpoint's redo ptr for
9206  * UpdateCheckPointDistanceEstimate()
9207  */
9208  PriorRedoPtr = ControlFile->checkPointCopy.redo;
9209 
9210  /*
9211  * Update pg_control, using current time. Check that it still shows
9212  * IN_ARCHIVE_RECOVERY state and an older checkpoint, else do nothing;
9213  * this is a quick hack to make sure nothing really bad happens if somehow
9214  * we get here after the end-of-recovery checkpoint.
9215  */
9216  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9218  ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
9219  {
9220  ControlFile->checkPoint = lastCheckPointRecPtr;
9221  ControlFile->checkPointCopy = lastCheckPoint;
9222  ControlFile->time = (pg_time_t) time(NULL);
9223 
9224  /*
9225  * Ensure minRecoveryPoint is past the checkpoint record. Normally,
9226  * this will have happened already while writing out dirty buffers,
9227  * but not necessarily - e.g. because no buffers were dirtied. We do
9228  * this because a non-exclusive base backup uses minRecoveryPoint to
9229  * determine which WAL files must be included in the backup, and the
9230  * file (or files) containing the checkpoint record must be included,
9231  * at a minimum. Note that for an ordinary restart of recovery there's
9232  * no value in having the minimum recovery point any earlier than this
9233  * anyway, because redo will begin just after the checkpoint record.
9234  */
9235  if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
9236  {
9237  ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
9239 
9240  /* update local copy */
9243  }
9244  if (flags & CHECKPOINT_IS_SHUTDOWN)
9247  }
9248  LWLockRelease(ControlFileLock);
9249 
9250  /*
9251  * Delete old log files (those no longer needed even for previous
9252  * checkpoint/restartpoint) to prevent the disk holding the xlog from
9253  * growing full.
9254  */
9255  if (PriorRedoPtr != InvalidXLogRecPtr)
9256  {
9257  XLogRecPtr receivePtr;
9258  XLogRecPtr replayPtr;
9259  TimeLineID replayTLI;
9260  XLogRecPtr endptr;
9261  XLogSegNo _logSegNo;
9262 
9263  /* Update the average distance between checkpoints/restartpoints. */
9265 
9266  XLByteToSeg(PriorRedoPtr, _logSegNo, wal_segment_size);
9267 
9268  /*
9269  * Get the current end of xlog replayed or received, whichever is
9270  * later.
9271  */
9272  receivePtr = GetWalRcvWriteRecPtr(NULL, NULL);
9273  replayPtr = GetXLogReplayRecPtr(&replayTLI);
9274  endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
9275 
9276  KeepLogSeg(endptr, &_logSegNo);
9277  _logSegNo--;
9278 
9279  /*
9280  * Try to recycle segments on a useful timeline. If we've been
9281  * promoted since the beginning of this restartpoint, use the new
9282  * timeline chosen at end of recovery (RecoveryInProgress() sets
9283  * ThisTimeLineID in that case). If we're still in recovery, use the
9284  * timeline we're currently replaying.
9285  *
9286  * There is no guarantee that the WAL segments will be useful on the
9287  * current timeline; if recovery proceeds to a new timeline right
9288  * after this, the pre-allocated WAL segments on this timeline will
9289  * not be used, and will go wasted until recycled on the next
9290  * restartpoint. We'll live with that.
9291  */
9292  if (RecoveryInProgress())
9293  ThisTimeLineID = replayTLI;
9294 
9295  RemoveOldXlogFiles(_logSegNo, PriorRedoPtr, endptr);
9296 
9297  /*
9298  * Make more log segments if needed. (Do this after recycling old log
9299  * segments, since that may supply some of the needed files.)
9300  */
9301  PreallocXlogFiles(endptr);
9302 
9303  /*
9304  * ThisTimeLineID is normally not set when we're still in recovery.
9305  * However, recycling/preallocating segments above needed
9306  * ThisTimeLineID to determine which timeline to install the segments
9307  * on. Reset it now, to restore the normal state of affairs for
9308  * debugging purposes.
9309  */
9310  if (RecoveryInProgress())
9311  ThisTimeLineID = 0;
9312  }
9313 
9314  /*
9315  * Truncate pg_subtrans if possible. We can throw away all data before
9316  * the oldest XMIN of any running transaction. No future transaction will
9317  * attempt to reference any pg_subtrans entry older than that (see Asserts
9318  * in subtrans.c). When hot standby is disabled, though, we mustn't do
9319  * this because StartupSUBTRANS hasn't been called yet.
9320  */
9321  if (EnableHotStandby)
9323 
9324  /* Real work is done, but log and update before releasing lock. */
9325  LogCheckpointEnd(true);
9326 
9327  xtime = GetLatestXTime();
9329  (errmsg("recovery restart point at %X/%X",
9330  (uint32) (lastCheckPoint.redo >> 32), (uint32) lastCheckPoint.redo),
9331  xtime ? errdetail("last completed transaction was at log time %s",
9332  timestamptz_to_str(xtime)) : 0));
9333 
9334  LWLockRelease(CheckpointLock);
9335 
9336  /*
9337  * Finally, execute archive_cleanup_command, if any.
9338  */
9341  "archive_cleanup_command",
9342  false);
9343 
9344  return true;
9345 }
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8495
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:1651
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:1570
int64 TimestampTz
Definition: timestamp.h:39
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition: xlog.c:2688
TimestampTz ckpt_start_t
Definition: xlog.h:199
slock_t info_lck
Definition: xlog.c:704
#define MemSet(start, val, len)
Definition: c.h:897
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
Definition: xlog.c:3842
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:9033
TimestampTz GetLatestXTime(void)
Definition: xlog.c:6129
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:7919
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:354
XLogRecPtr lastCheckPointRecPtr
Definition: xlog.c:673
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1724
#define SpinLockAcquire(lock)
Definition: spin.h:62
void UpdateControlFile(void)
Definition: xlog.c:4663
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8410
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
Definition: xlog.c:11155
#define DEBUG2
Definition: elog.h:24
static XLogRecPtr RedoRecPtr
Definition: xlog.c:352
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3741
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errdetail(const char *fmt,...)
Definition: elog.c:873
unsigned int uint32
Definition: c.h:314
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:826
#define PROCARRAY_FLAGS_DEFAULT
Definition: procarray.h:50
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9356
static ControlFileData * ControlFile
Definition: xlog.c:715
TimeLineID ThisTimeLineID
Definition: xlog.c:181
TransactionId GetOldestXmin(Relation rel, int flags)
Definition: procarray.c:1315
uint64 XLogRecPtr
Definition: xlogdefs.h:21
CheckpointStatsData CheckpointStats
Definition: xlog.c:175
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1622
static XLogCtlData * XLogCtl
Definition: xlog.c:707
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1120
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:8392
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:176
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:824
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1710
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ DataChecksumsEnabled()

bool DataChecksumsEnabled ( void  )

Definition at line 4731 of file xlog.c.

References Assert, and ControlFileData::data_checksum_version.

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

4732 {
4733  Assert(ControlFile != NULL);
4734  return (ControlFile->data_checksum_version > 0);
4735 }
uint32 data_checksum_version
Definition: pg_control.h:221
static ControlFileData * ControlFile
Definition: xlog.c:715
#define Assert(condition)
Definition: c.h:688

◆ do_pg_abort_backup()

void do_pg_abort_backup ( void  )

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

11128 {
11129  /*
11130  * Quick exit if session is not keeping around a non-exclusive backup
11131  * already started.
11132  */
11134  return;
11135 
11140 
11143  {
11144  XLogCtl->Insert.forcePageWrites = false;
11145  }
11147 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1651
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:688
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1622
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 10205 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().

10209 {
10210  bool exclusive = (labelfile == NULL);
10211  bool backup_started_in_recovery = false;
10212  XLogRecPtr checkpointloc;
10213  XLogRecPtr startpoint;
10214  TimeLineID starttli;
10215  pg_time_t stamp_time;
10216  char strfbuf[128];
10217  char xlogfilename[MAXFNAMELEN];
10218  XLogSegNo _logSegNo;
10219  struct stat stat_buf;
10220  FILE *fp;
10221 
10222  backup_started_in_recovery = RecoveryInProgress();
10223 
10224  /*
10225  * Currently only non-exclusive backup can be taken during recovery.
10226  */
10227  if (backup_started_in_recovery && exclusive)
10228  ereport(ERROR,
10229  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10230  errmsg("recovery is in progress"),
10231  errhint("WAL control functions cannot be executed during recovery.")));
10232 
10233  /*
10234  * During recovery, we don't need to check WAL level. Because, if WAL
10235  * level is not sufficient, it's impossible to get here during recovery.
10236  */
10237  if (!backup_started_in_recovery && !XLogIsNeeded())
10238  ereport(ERROR,
10239  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10240  errmsg("WAL level not sufficient for making an online backup"),
10241  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
10242 
10243  if (strlen(backupidstr) > MAXPGPATH)
10244  ereport(ERROR,
10245  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
10246  errmsg("backup label too long (max %d bytes)",
10247  MAXPGPATH)));
10248 
10249  /*
10250  * Mark backup active in shared memory. We must do full-page WAL writes
10251  * during an on-line backup even if not doing so at other times, because
10252  * it's quite possible for the backup dump to obtain a "torn" (partially
10253  * written) copy of a database page if it reads the page concurrently with
10254  * our write to the same page. This can be fixed as long as the first
10255  * write to the page in the WAL sequence is a full-page write. Hence, we
10256  * turn on forcePageWrites and then force a CHECKPOINT, to ensure there
10257  * are no dirty pages in shared memory that might get dumped while the
10258  * backup is in progress without having a corresponding WAL record. (Once
10259  * the backup is complete, we need not force full-page writes anymore,
10260  * since we expect that any pages not modified during the backup interval
10261  * must have been correctly captured by the backup.)
10262  *
10263  * Note that forcePageWrites has no effect during an online backup from
10264  * the standby.
10265  *
10266  * We must hold all the insertion locks to change the value of
10267  * forcePageWrites, to ensure adequate interlocking against
10268  * XLogInsertRecord().
10269  */
10271  if (exclusive)
10272  {
10273  /*
10274  * At first, mark that we're now starting an exclusive backup, to
10275  * ensure that there are no other sessions currently running
10276  * pg_start_backup() or pg_stop_backup().
10277  */
10279  {
10281  ereport(ERROR,
10282  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10283  errmsg("a backup is already in progress"),
10284  errhint("Run pg_stop_backup() and try again.")));
10285  }
10287  }
10288  else
10290  XLogCtl->Insert.forcePageWrites = true;
10292 
10293  /* Ensure we release forcePageWrites if fail below */
10295  {
10296  bool gotUniqueStartpoint = false;
10297  DIR *tblspcdir;
10298  struct dirent *de;
10299  tablespaceinfo *ti;
10300  int datadirpathlen;
10301 
10302  /*
10303  * Force an XLOG file switch before the checkpoint, to ensure that the
10304  * WAL segment the checkpoint is written to doesn't contain pages with
10305  * old timeline IDs. That would otherwise happen if you called
10306  * pg_start_backup() right after restoring from a PITR archive: the
10307  * first WAL segment containing the startup checkpoint has pages in
10308  * the beginning with the old timeline ID. That can cause trouble at
10309  * recovery: we won't have a history file covering the old timeline if
10310  * pg_wal directory was not included in the base backup and the WAL
10311  * archive was cleared too before starting the backup.
10312  *
10313  * This also ensures that we have emitted a WAL page header that has
10314  * XLP_BKP_REMOVABLE off before we emit the checkpoint record.
10315  * Therefore, if a WAL archiver (such as pglesslog) is trying to
10316  * compress out removable backup blocks, it won't remove any that
10317  * occur after this point.
10318  *
10319  * During recovery, we skip forcing XLOG file switch, which means that
10320  * the backup taken during recovery is not available for the special
10321  * recovery case described above.
10322  */
10323  if (!backup_started_in_recovery)
10324  RequestXLogSwitch(false);
10325 
10326  do
10327  {
10328  bool checkpointfpw;
10329 
10330  /*
10331  * Force a CHECKPOINT. Aside from being necessary to prevent torn
10332  * page problems, this guarantees that two successive backup runs
10333  * will have different checkpoint positions and hence different
10334  * history file names, even if nothing happened in between.
10335  *
10336  * During recovery, establish a restartpoint if possible. We use
10337  * the last restartpoint as the backup starting checkpoint. This
10338  * means that two successive backup runs can have same checkpoint
10339  * positions.
10340  *
10341  * Since the fact that we are executing do_pg_start_backup()
10342  * during recovery means that checkpointer is running, we can use
10343  * RequestCheckpoint() to establish a restartpoint.
10344  *
10345  * We use CHECKPOINT_IMMEDIATE only if requested by user (via
10346  * passing fast = true). Otherwise this can take awhile.
10347  */
10349  (fast ? CHECKPOINT_IMMEDIATE : 0));
10350 
10351  /*
10352  * Now we need to fetch the checkpoint record location, and also
10353  * its REDO pointer. The oldest point in WAL that would be needed
10354  * to restore starting from the checkpoint is precisely the REDO
10355  * pointer.
10356  */
10357  LWLockAcquire(ControlFileLock, LW_SHARED);
10358  checkpointloc = ControlFile->checkPoint;
10359  startpoint = ControlFile->checkPointCopy.redo;
10361  checkpointfpw = ControlFile->checkPointCopy.fullPageWrites;
10362  LWLockRelease(ControlFileLock);
10363 
10364  if (backup_started_in_recovery)
10365  {
10366  XLogRecPtr recptr;
10367 
10368  /*
10369  * Check to see if all WAL replayed during online backup
10370  * (i.e., since last restartpoint used as backup starting
10371  * checkpoint) contain full-page writes.
10372  */
10374  recptr = XLogCtl->lastFpwDisableRecPtr;
10376 
10377  if (!checkpointfpw || startpoint <= recptr)
10378  ereport(ERROR,
10379  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10380  errmsg("WAL generated with full_page_writes=off was replayed "
10381  "since last restartpoint"),
10382  errhint("This means that the backup being taken on the standby "
10383  "is corrupt and should not be used. "
10384  "Enable full_page_writes and run CHECKPOINT on the master, "
10385  "and then try an online backup again.")));
10386 
10387  /*
10388  * During recovery, since we don't use the end-of-backup WAL
10389  * record and don't write the backup history file, the
10390  * starting WAL location doesn't need to be unique. This means
10391  * that two base backups started at the same time might use
10392  * the same checkpoint as starting locations.
10393  */
10394  gotUniqueStartpoint = true;
10395  }
10396 
10397  /*
10398  * If two base backups are started at the same time (in WAL sender
10399  * processes), we need to make sure that they use different
10400  * checkpoints as starting locations, because we use the starting
10401  * WAL location as a unique identifier for the base backup in the
10402  * end-of-backup WAL record and when we write the backup history
10403  * file. Perhaps it would be better generate a separate unique ID
10404  * for each backup instead of forcing another checkpoint, but
10405  * taking a checkpoint right after another is not that expensive
10406  * either because only few buffers have been dirtied yet.
10407  */
10409  if (XLogCtl->Insert.lastBackupStart < startpoint)
10410  {
10411  XLogCtl->Insert.lastBackupStart = startpoint;
10412  gotUniqueStartpoint = true;
10413  }
10415  } while (!gotUniqueStartpoint);
10416 
10417  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
10418  XLogFileName(xlogfilename, starttli, _logSegNo, wal_segment_size);
10419 
10420  /*
10421  * Construct tablespace_map file
10422  */
10423  if (exclusive)
10424  tblspcmapfile = makeStringInfo();
10425 
10426  datadirpathlen = strlen(DataDir);
10427 
10428  /* Collect information about all tablespaces */
10429  tblspcdir = AllocateDir("pg_tblspc");
10430  while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL)
10431  {
10432  char fullpath[MAXPGPATH + 10];
10433  char linkpath[MAXPGPATH];
10434  char *relpath = NULL;
10435  int rllen;
10436  StringInfoData buflinkpath;
10437  char *s = linkpath;
10438 
10439  /* Skip special stuff */
10440  if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
10441  continue;
10442 
10443  snprintf(fullpath, sizeof(fullpath), "pg_tblspc/%s", de->d_name);
10444 
10445 #if defined(HAVE_READLINK) || defined(WIN32)
10446  rllen = readlink(fullpath, linkpath, sizeof(linkpath));
10447  if (rllen < 0)
10448  {
10449  ereport(WARNING,
10450  (errmsg("could not read symbolic link \"%s\": %m",
10451  fullpath)));
10452  continue;
10453  }
10454  else if (rllen >= sizeof(linkpath))
10455  {
10456  ereport(WARNING,
10457  (errmsg("symbolic link \"%s\" target is too long",
10458  fullpath)));
10459  continue;
10460  }
10461  linkpath[rllen] = '\0';
10462 
10463  /*
10464  * Add the escape character '\\' before newline in a string to
10465  * ensure that we can distinguish between the newline in the
10466  * tablespace path and end of line while reading tablespace_map
10467  * file during archive recovery.
10468  */
10469  initStringInfo(&buflinkpath);
10470 
10471  while (*s)
10472  {
10473  if ((*s == '\n' || *s == '\r') && needtblspcmapfile)
10474  appendStringInfoChar(&buflinkpath, '\\');
10475  appendStringInfoChar(&buflinkpath, *s++);
10476  }
10477 
10478  /*
10479  * Relpath holds the relative path of the tablespace directory
10480  * when it's located within PGDATA, or NULL if it's located
10481  * elsewhere.
10482  */
10483  if (rllen > datadirpathlen &&
10484  strncmp(linkpath, DataDir, datadirpathlen) == 0 &&
10485  IS_DIR_SEP(linkpath[datadirpathlen]))
10486  relpath = linkpath + datadirpathlen + 1;
10487 
10488  ti = palloc(sizeof(tablespaceinfo));
10489  ti->oid = pstrdup(de->d_name);
10490  ti->path = pstrdup(buflinkpath.data);
10491  ti->rpath = relpath ? pstrdup(relpath) : NULL;
10492  ti->size = infotbssize ? sendTablespace(fullpath, true) : -1;
10493 
10494  if (tablespaces)
10495  *tablespaces = lappend(*tablespaces, ti);
10496 
10497  appendStringInfo(tblspcmapfile, "%s %s\n", ti->oid, ti->path);
10498 
10499  pfree(buflinkpath.data);
10500 #else
10501 
10502  /*
10503  * If the platform does not have symbolic links, it should not be
10504  * possible to have tablespaces - clearly somebody else created
10505  * them. Warn about it and ignore.
10506  */
10507  ereport(WARNING,
10508  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
10509  errmsg("tablespaces are not supported on this platform")));
10510 #endif
10511  }
10512  FreeDir(tblspcdir);
10513 
10514  /*
10515  * Construct backup label file
10516  */
10517  if (exclusive)
10518  labelfile = makeStringInfo();
10519 
10520  /* Use the log timezone here, not the session timezone */
10521  stamp_time = (pg_time_t) time(NULL);
10522  pg_strftime(strfbuf, sizeof(strfbuf),
10523  "%Y-%m-%d %H:%M:%S %Z",
10524  pg_localtime(&stamp_time, log_timezone));
10525  appendStringInfo(labelfile, "START WAL LOCATION: %X/%X (file %s)\n",
10526  (uint32) (startpoint >> 32), (uint32) startpoint, xlogfilename);
10527  appendStringInfo(labelfile, "CHECKPOINT LOCATION: %X/%X\n",
10528  (uint32) (checkpointloc >> 32), (uint32) checkpointloc);
10529  appendStringInfo(labelfile, "BACKUP METHOD: %s\n",
10530  exclusive ? "pg_start_backup" : "streamed");
10531  appendStringInfo(labelfile, "BACKUP FROM: %s\n",
10532  backup_started_in_recovery ? "standby" : "master");
10533  appendStringInfo(labelfile, "START TIME: %s\n", strfbuf);
10534  appendStringInfo(labelfile, "LABEL: %s\n", backupidstr);
10535  appendStringInfo(labelfile, "START TIMELINE: %u\n", starttli);
10536 
10537  /*
10538  * Okay, write the file, or return its contents to caller.
10539  */
10540  if (exclusive)
10541  {
10542  /*
10543  * Check for existing backup label --- implies a backup is already
10544  * running. (XXX given that we checked exclusiveBackupState
10545  * above, maybe it would be OK to just unlink any such label
10546  * file?)
10547  */
10548  if (stat(BACKUP_LABEL_FILE, &stat_buf) != 0)
10549  {
10550  if (errno != ENOENT)
10551  ereport(ERROR,
10553  errmsg("could not stat file \"%s\": %m",
10554  BACKUP_LABEL_FILE)));
10555  }
10556  else
10557  ereport(ERROR,
10558  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10559  errmsg("a backup is already in progress"),
10560  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
10561  BACKUP_LABEL_FILE)));
10562 
10563  fp = AllocateFile(BACKUP_LABEL_FILE, "w");
10564 
10565  if (!fp)
10566  ereport(ERROR,
10568  errmsg("could not create file \"%s\": %m",
10569  BACKUP_LABEL_FILE)));
10570  if (fwrite(labelfile->data, labelfile->len, 1, fp) != 1 ||
10571  fflush(fp) != 0 ||
10572  pg_fsync(fileno(fp)) != 0 ||
10573  ferror(fp) ||
10574  FreeFile(fp))
10575  ereport(ERROR,
10577  errmsg("could not write file \"%s\": %m",
10578  BACKUP_LABEL_FILE)));
10579  /* Allocated locally for exclusive backups, so free separately */
10580  pfree(labelfile->data);
10581  pfree(labelfile);
10582 
10583  /* Write backup tablespace_map file. */
10584  if (tblspcmapfile->len > 0)
10585  {
10586  if (stat(TABLESPACE_MAP, &stat_buf) != 0)
10587  {
10588  if (errno != ENOENT)
10589  ereport(ERROR,
10591  errmsg("could not stat file \"%s\": %m",
10592  TABLESPACE_MAP)));
10593  }
10594  else
10595  ereport(ERROR,
10596  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10597  errmsg("a backup is already in progress"),
10598  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
10599  TABLESPACE_MAP)));
10600 
10601  fp = AllocateFile(TABLESPACE_MAP, "w");
10602 
10603  if (!fp)
10604  ereport(ERROR,
10606  errmsg("could not create file \"%s\": %m",
10607  TABLESPACE_MAP)));
10608  if (fwrite(tblspcmapfile->data, tblspcmapfile->len, 1, fp) != 1 ||
10609  fflush(fp) != 0 ||
10610  pg_fsync(fileno(fp)) != 0 ||
10611  ferror(fp) ||
10612  FreeFile(fp))
10613  ereport(ERROR,
10615  errmsg("could not write file \"%s\": %m",
10616  TABLESPACE_MAP)));
10617  }
10618 
10619  /* Allocated locally for exclusive backups, so free separately */
10620  pfree(tblspcmapfile->data);
10621  pfree(tblspcmapfile);
10622  }
10623  }
10625 
10626  /*
10627  * Mark that start phase has correctly finished for an exclusive backup.
10628  * Session-level locks are updated as well to reflect that state.
10629  *
10630  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating
10631  * backup counters and session-level lock. Otherwise they can be
10632  * updated inconsistently, and which might cause do_pg_abort_backup()
10633  * to fail.
10634  */
10635  if (exclusive)
10636  {
10639 
10640  /* Set session-level lock */
10643  }
10644  else
10646 
10647  /*
10648  * We're done. As a convenience, return the starting WAL location.
10649  */
10650  if (starttli_p)
10651  *starttli_p = starttli;
10652  return startpoint;
10653 }
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:9433
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:1651
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:1063
#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:7919
static bool backup_started_in_recovery
Definition: basebackup.c:73
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:1724
#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:936
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:103
#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:2353
unsigned int uint32
Definition: c.h:314
int64 sendTablespace(char *path, bool sizeonly)
Definition: basebackup.c:902
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2607
#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:10657
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:562
uintptr_t Datum
Definition: postgres.h:365
static ControlFileData * ControlFile
Definition: xlog.c:715
#define BoolGetDatum(X)
Definition: postgres.h:385
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:2673
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1622
static XLogCtlData * XLogCtl
Definition: xlog.c:707
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1120
#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:2545
void * palloc(Size size)
Definition: mcxt.c:835
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:71
char * DataDir
Definition: globals.c:60
#define BACKUP_LABEL_FILE
Definition: xlog.h:322
int pg_fsync(int fd)
Definition: fd.c:348
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:2725
void RequestCheckpoint(int flags)
Definition: checkpointer.c:967
#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 10723 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().

10724 {
10725  bool exclusive = (labelfile == NULL);
10726  bool backup_started_in_recovery = false;
10727  XLogRecPtr startpoint;
10728  XLogRecPtr stoppoint;
10729  TimeLineID stoptli;
10730  pg_time_t stamp_time;
10731  char strfbuf[128];
10732  char histfilepath[MAXPGPATH];
10733  char startxlogfilename[MAXFNAMELEN];
10734  char stopxlogfilename[MAXFNAMELEN];
10735  char lastxlogfilename[MAXFNAMELEN];
10736  char histfilename[MAXFNAMELEN];
10737  char backupfrom[20];
10738  XLogSegNo _logSegNo;
10739  FILE *lfp;
10740  FILE *fp;
10741  char ch;
10742  int seconds_before_warning;
10743  int waits = 0;
10744  bool reported_waiting = false;
10745  char *remaining;
10746  char *ptr;
10747  uint32 hi,
10748  lo;
10749 
10750  backup_started_in_recovery = RecoveryInProgress();
10751 
10752  /*
10753  * Currently only non-exclusive backup can be taken during recovery.
10754  */
10755  if (backup_started_in_recovery && exclusive)
10756  ereport(ERROR,
10757  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10758  errmsg("recovery is in progress"),
10759  errhint("WAL control functions cannot be executed during recovery.")));
10760 
10761  /*
10762  * During recovery, we don't need to check WAL level. Because, if WAL
10763  * level is not sufficient, it's impossible to get here during recovery.
10764  */
10765  if (!backup_started_in_recovery && !XLogIsNeeded())
10766  ereport(ERROR,
10767  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10768  errmsg("WAL level not sufficient for making an online backup"),
10769  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
10770 
10771  if (exclusive)
10772  {
10773  /*
10774  * At first, mark that we're now stopping an exclusive backup, to
10775  * ensure that there are no other sessions currently running
10776  * pg_start_backup() or pg_stop_backup().
10777  */
10780  {
10782  ereport(ERROR,
10783  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10784  errmsg("exclusive backup not in progress")));
10785  }
10788 
10789  /*
10790  * Remove backup_label. In case of failure, the state for an exclusive
10791  * backup is switched back to in-progress.
10792  */
10794  {
10795  /*
10796  * Read the existing label file into memory.
10797  */
10798  struct stat statbuf;
10799  int r;
10800 
10801  if (stat(BACKUP_LABEL_FILE, &statbuf))
10802  {
10803  /* should not happen per the upper checks */
10804  if (errno != ENOENT)
10805  ereport(ERROR,
10807  errmsg("could not stat file \"%s\": %m",
10808  BACKUP_LABEL_FILE)));
10809  ereport(ERROR,
10810  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10811  errmsg("a backup is not in progress")));
10812  }
10813 
10814  lfp = AllocateFile(BACKUP_LABEL_FILE, "r");
10815  if (!lfp)
10816  {
10817  ereport(ERROR,
10819  errmsg("could not read file \"%s\": %m",
10820  BACKUP_LABEL_FILE)));
10821  }
10822  labelfile = palloc(statbuf.st_size + 1);
10823  r = fread(labelfile, statbuf.st_size, 1, lfp);
10824  labelfile[statbuf.st_size] = '\0';
10825 
10826  /*
10827  * Close and remove the backup label file
10828  */
10829  if (r != 1 || ferror(lfp) || FreeFile(lfp))
10830  ereport(ERROR,
10832  errmsg("could not read file \"%s\": %m",
10833  BACKUP_LABEL_FILE)));
10835 
10836  /*
10837  * Remove tablespace_map file if present, it is created only if
10838  * there are tablespaces.
10839  */
10841  }
10843  }
10844 
10845  /*
10846  * OK to update backup counters, forcePageWrites and session-level lock.
10847  *
10848  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating them.
10849  * Otherwise they can be updated inconsistently, and which might cause
10850  * do_pg_abort_backup() to fail.
10851  */
10853  if (exclusive)
10854  {
10856  }
10857  else
10858  {
10859  /*
10860  * The user-visible pg_start/stop_backup() functions that operate on
10861  * exclusive backups can be called at any time, but for non-exclusive
10862  * backups, it is expected that each do_pg_start_backup() call is
10863  * matched by exactly one do_pg_stop_backup() call.
10864  */
10867  }
10868 
10871  {
10872  XLogCtl->Insert.forcePageWrites = false;
10873  }
10874 
10875  /*
10876  * Clean up session-level lock.
10877  *
10878  * You might think that WALInsertLockRelease() can be called
10879  * before cleaning up session-level lock because session-level
10880  * lock doesn't need to be protected with WAL insertion lock.
10881  * But since CHECK_FOR_INTERRUPTS() can occur in it,
10882  * session-level lock must be cleaned up before it.
10883  */
10885 
10887 
10888  /*
10889  * Read and parse the START WAL LOCATION line (this code is pretty crude,
10890  * but we are not expecting any variability in the file format).
10891  */
10892  if (sscanf(labelfile, "START WAL LOCATION: %X/%X (file %24s)%c",
10893  &hi, &lo, startxlogfilename,
10894  &ch) != 4 || ch != '\n')
10895  ereport(ERROR,
10896  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10897  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
10898  startpoint = ((uint64) hi) << 32 | lo;
10899  remaining = strchr(labelfile, '\n') + 1; /* %n is not portable enough */
10900 
10901  /*
10902  * Parse the BACKUP FROM line. If we are taking an online backup from the
10903  * standby, we confirm that the standby has not been promoted during the
10904  * backup.
10905  */
10906  ptr = strstr(remaining, "BACKUP FROM:");
10907  if (!ptr || sscanf(ptr, "BACKUP FROM: %19s\n", backupfrom) != 1)
10908  ereport(ERROR,
10909  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10910  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
10911  if (strcmp(backupfrom, "standby") == 0 && !backup_started_in_recovery)
10912  ereport(ERROR,
10913  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10914  errmsg("the standby was promoted during online backup"),
10915  errhint("This means that the backup being taken is corrupt "
10916  "and should not be used. "
10917  "Try taking another online backup.")));
10918 
10919  /*
10920  * During recovery, we don't write an end-of-backup record. We assume that
10921  * pg_control was backed up last and its minimum recovery point can be
10922  * available as the backup end location. Since we don't have an
10923  * end-of-backup record, we use the pg_control value to check whether
10924  * we've reached the end of backup when starting recovery from this
10925  * backup. We have no way of checking if pg_control wasn't backed up last
10926  * however.
10927  *
10928  * We don't force a switch to new WAL file but it is still possible to
10929  * wait for all the required files to be archived if waitforarchive is
10930  * true. This is okay if we use the backup to start a standby and fetch
10931  * the missing WAL using streaming replication. But in the case of an
10932  * archive recovery, a user should set waitforarchive to true and wait for
10933  * them to be archived to ensure that all the required files are
10934  * available.
10935  *
10936  * We return the current minimum recovery point as the backup end
10937  * location. Note that it can be greater than the exact backup end
10938  * location if the minimum recovery point is updated after the backup of
10939  * pg_control. This is harmless for current uses.
10940  *
10941  * XXX currently a backup history file is for informational and debug
10942  * purposes only. It's not essential for an online backup. Furthermore,
10943  * even if it's created, it will not be archived during recovery because
10944  * an archiver is not invoked. So it doesn't seem worthwhile to write a
10945  * backup history file during recovery.
10946  */
10947  if (backup_started_in_recovery)
10948  {
10949  XLogRecPtr recptr;
10950 
10951  /*
10952  * Check to see if all WAL replayed during online backup contain
10953  * full-page writes.
10954  */
10956  recptr = XLogCtl->lastFpwDisableRecPtr;
10958 
10959  if (startpoint <= recptr)
10960  ereport(ERROR,
10961  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10962  errmsg("WAL generated with full_page_writes=off was replayed "
10963  "during online backup"),
10964  errhint("This means that the backup being taken on the standby "
10965  "is corrupt and should not be used. "
10966  "Enable full_page_writes and run CHECKPOINT on the master, "
10967  "and then try an online backup again.")));
10968 
10969 
10970  LWLockAcquire(ControlFileLock, LW_SHARED);
10971  stoppoint = ControlFile->minRecoveryPoint;
10972  stoptli = ControlFile->minRecoveryPointTLI;
10973  LWLockRelease(ControlFileLock);
10974  }
10975  else
10976  {
10977  /*
10978  * Write the backup-end xlog record
10979  */
10980  XLogBeginInsert();
10981  XLogRegisterData((char *) (&startpoint), sizeof(startpoint));
10982  stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
10983  stoptli = ThisTimeLineID;
10984 
10985  /*
10986  * Force a switch to a new xlog segment file, so that the backup is
10987  * valid as soon as archiver moves out the current segment file.
10988  */
10989  RequestXLogSwitch(false);
10990 
10991  XLByteToPrevSeg(stoppoint, _logSegNo, wal_segment_size);
10992  XLogFileName(stopxlogfilename, stoptli, _logSegNo, wal_segment_size);
10993 
10994  /* Use the log timezone here, not the session timezone */
10995  stamp_time = (pg_time_t) time(NULL);
10996  pg_strftime(strfbuf, sizeof(strfbuf),
10997  "%Y-%m-%d %H:%M:%S %Z",
10998  pg_localtime(&stamp_time, log_timezone));
10999 
11000  /*
11001  * Write the backup history file
11002  */
11003  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
11004  BackupHistoryFilePath(histfilepath, stoptli, _logSegNo,
11005  startpoint, wal_segment_size);
11006  fp = AllocateFile(histfilepath, "w");
11007  if (!fp)
11008  ereport(ERROR,
11010  errmsg("could not create file \"%s\": %m",
11011  histfilepath)));
11012  fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n",
11013  (uint32) (startpoint >> 32), (uint32) startpoint, startxlogfilename);
11014  fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
11015  (uint32) (stoppoint >> 32), (uint32) stoppoint, stopxlogfilename);
11016  /*
11017  * Transfer remaining lines including label and start timeline to
11018  * history file.
11019  */
11020  fprintf(fp, "%s", remaining);
11021  fprintf(fp, "STOP TIME: %s\n", strfbuf);
11022  fprintf(fp, "STOP TIMELINE: %u\n", stoptli);
11023  if (fflush(fp) || ferror(fp) || FreeFile(fp))
11024  ereport(ERROR,
11026  errmsg("could not write file \"%s\": %m",
11027  histfilepath)));
11028 
11029  /*
11030  * Clean out any no-longer-needed history files. As a side effect,
11031  * this will post a .ready file for the newly created history file,
11032  * notifying the archiver that history file may be archived
11033  * immediately.
11034  */
11036  }
11037 
11038  /*
11039  * If archiving is enabled, wait for all the required WAL files to be
11040  * archived before returning. If archiving isn't enabled, the required WAL
11041  * needs to be transported via streaming replication (hopefully with
11042  * wal_keep_segments set high enough), or some more exotic mechanism like
11043  * polling and copying files from pg_wal with script. We have no knowledge
11044  * of those mechanisms, so it's up to the user to ensure that he gets all
11045  * the required WAL.
11046  *
11047  * We wait until both the last WAL file filled during backup and the
11048  * history file have been archived, and assume that the alphabetic sorting
11049  * property of the WAL files ensures any earlier WAL files are safely
11050  * archived as well.
11051  *
11052  * We wait forever, since archive_command is supposed to work and we
11053  * assume the admin wanted his backup to work completely. If you don't
11054  * wish to wait, then either waitforarchive should be passed in as false,
11055  * or you can set statement_timeout. Also, some notices are issued to
11056  * clue in anyone who might be doing this interactively.
11057  */
11058 
11059  if (waitforarchive &&
11060  ((!backup_started_in_recovery && XLogArchivingActive()) ||
11061  (backup_started_in_recovery && XLogArchivingAlways())))
11062  {
11063  XLByteToPrevSeg(stoppoint, _logSegNo, wal_segment_size);
11064  XLogFileName(lastxlogfilename, stoptli, _logSegNo, wal_segment_size);
11065 
11066  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
11067  BackupHistoryFileName(histfilename, stoptli, _logSegNo,
11068  startpoint, wal_segment_size);
11069 
11070  seconds_before_warning = 60;
11071  waits = 0;
11072 
11073  while (XLogArchiveIsBusy(lastxlogfilename) ||
11074  XLogArchiveIsBusy(histfilename))
11075  {
11077 
11078  if (!reported_waiting && waits > 5)
11079  {
11080  ereport(NOTICE,
11081  (errmsg("pg_stop_backup cleanup done, waiting for required WAL segments to be archived")));
11082  reported_waiting = true;
11083  }
11084 
11085  pg_usleep(1000000L);
11086 
11087  if (++waits >= seconds_before_warning)
11088  {
11089  seconds_before_warning *= 2; /* This wraps in >10 years... */
11090  ereport(WARNING,
11091  (errmsg("pg_stop_backup still waiting for all required WAL segments to be archived (%d seconds elapsed)",
11092  waits),
11093  errhint("Check that your archive_command is executing properly. "
11094  "pg_stop_backup can be canceled safely, "
11095  "but the database backup will not be usable without all the WAL segments.")));
11096  }
11097  }
11098 
11099  ereport(NOTICE,
11100  (errmsg("pg_stop_backup complete, all required WAL segments have been archived")));
11101  }
11102  else if (waitforarchive)
11103  ereport(NOTICE,
11104  (errmsg("WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup")));
11105 
11106  /*
11107  * We're done. As a convenience, return the ending WAL location.
11108  */
11109  if (stoptli_p)
11110  *stoptli_p = stoptli;
11111  return stoppoint;
11112 }
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:9433
#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:1651
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:7919
static bool backup_started_in_recovery
Definition: basebackup.c:73
pg_tz * log_timezone
Definition: pgtz.c:31
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1724
#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:4102
#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:2353
unsigned int uint32
Definition: c.h:314
#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:365
static ControlFileData * ControlFile
Definition: xlog.c:715
#define BoolGetDatum(X)
Definition: postgres.h:385
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:688
#define XLogArchivingActive()
Definition: xlog.h:135
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1622
static XLogCtlData * XLogCtl
Definition: xlog.c:707
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1120
static void pg_stop_backup_callback(int code, Datum arg)
Definition: xlog.c:10686
#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:691
int FreeFile(FILE *file)
Definition: fd.c:2545
void * palloc(Size size)
Definition: mcxt.c:835
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 12097 of file xlog.c.

References DEBUG1, LOG, readSource, and XLOG_FROM_PG_WAL.

Referenced by ReadRecord(), and XLogPageRead().

12098 {
12099  static XLogRecPtr lastComplaint = 0;
12100 
12101  if (readSource == XLOG_FROM_PG_WAL && emode == LOG)
12102  {
12103  if (RecPtr == lastComplaint)
12104  emode = DEBUG1;
12105  else
12106  lastComplaint = RecPtr;
12107  }
12108  return emode;
12109 }
#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 5533 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().

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