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 "common/controldata_utils.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 "storage/sync.h"
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/ps_status.h"
#include "utils/relmapper.h"
#include "utils/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 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 readRecoverySignalFile (void)
 
static void validateRecoveryParameters (void)
 
static void exitArchiveRecovery (TimeLineID endTLI, XLogRecPtr endOfLog)
 
static bool recoveryStopsBefore (XLogReaderState *record)
 
static bool recoveryStopsAfter (XLogReaderState *record)
 
static void recoveryPausesHere (void)
 
static bool recoveryApplyDelay (XLogReaderState *record)
 
static void SetLatestXTime (TimestampTz xtime)
 
static void SetCurrentChunkStartTime (TimestampTz xtime)
 
static void CheckRequiredParameterValues (void)
 
static void XLogReportParameters (void)
 
static void checkTimeLineSwitch (XLogRecPtr lsn, TimeLineID newTLI, TimeLineID prevTLI)
 
static void LocalSetXLogInsertAllowed (void)
 
static void CreateEndOfRecoveryRecord (void)
 
static void CheckPointGuts (XLogRecPtr checkPointRedo, int flags)
 
static void KeepLogSeg (XLogRecPtr recptr, XLogSegNo *logSegNo)
 
static XLogRecPtr XLogGetReplicationSlotMinimumLSN (void)
 
static void AdvanceXLInsertBuffer (XLogRecPtr upto, bool opportunistic)
 
static bool XLogCheckpointNeeded (XLogSegNo new_segno)
 
static void XLogWrite (XLogwrtRqst WriteRqst, bool flexible)
 
static bool InstallXLogFileSegment (XLogSegNo *segno, char *tmppath, bool find_free, XLogSegNo max_segno, bool use_lock)
 
static int XLogFileRead (XLogSegNo segno, int emode, TimeLineID tli, int source, bool notfoundOk)
 
static int XLogFileReadAnyTLI (XLogSegNo segno, int emode, int source)
 
static int XLogPageRead (XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char *readBuf, TimeLineID *readTLI)
 
static bool WaitForWALToBecomeAvailable (XLogRecPtr RecPtr, bool randAccess, bool fetching_ckpt, XLogRecPtr tliRecPtr)
 
static int emode_for_corrupt_record (int emode, XLogRecPtr RecPtr)
 
static void XLogFileClose (void)
 
static void PreallocXlogFiles (XLogRecPtr endptr)
 
static void RemoveTempXlogFiles (void)
 
static void RemoveOldXlogFiles (XLogSegNo segno, XLogRecPtr RedoRecPtr, XLogRecPtr endptr)
 
static void RemoveXlogFile (const char *segname, XLogRecPtr RedoRecPtr, XLogRecPtr endptr)
 
static void UpdateLastRemovedPtr (char *filename)
 
static void ValidateXLOGDirectoryStructure (void)
 
static void CleanupBackupHistory (void)
 
static void UpdateMinRecoveryPoint (XLogRecPtr lsn, bool force)
 
static XLogRecordReadRecord (XLogReaderState *xlogreader, XLogRecPtr RecPtr, int emode, bool fetching_ckpt)
 
static void CheckRecoveryConsistency (void)
 
static XLogRecordReadCheckpointRecord (XLogReaderState *xlogreader, XLogRecPtr RecPtr, int whichChkpti, bool report)
 
static bool rescanLatestTimeLine (void)
 
static void WriteControlFile (void)
 
static void ReadControlFile (void)
 
static char * str_time (pg_time_t tnow)
 
static bool CheckForStandbyTrigger (void)
 
static void xlog_outdesc (StringInfo buf, XLogReaderState *record)
 
static void pg_start_backup_callback (int code, Datum arg)
 
static void pg_stop_backup_callback (int code, Datum arg)
 
static bool read_backup_label (XLogRecPtr *checkPointLoc, bool *backupEndRequired, bool *backupFromStandby)
 
static bool read_tablespace_map (List **tablespaces)
 
static void rm_redo_error_callback (void *arg)
 
static int get_sync_bit (int method)
 
static void CopyXLogRecordToWAL (int write_len, bool isLogSwitch, XLogRecData *rdata, XLogRecPtr StartPos, XLogRecPtr EndPos)
 
static void ReserveXLogInsertLocation (int size, XLogRecPtr *StartPos, XLogRecPtr *EndPos, XLogRecPtr *PrevPtr)
 
static bool ReserveXLogSwitch (XLogRecPtr *StartPos, XLogRecPtr *EndPos, XLogRecPtr *PrevPtr)
 
static XLogRecPtr WaitXLogInsertionsToFinish (XLogRecPtr upto)
 
static char * GetXLogBuffer (XLogRecPtr ptr)
 
static XLogRecPtr XLogBytePosToRecPtr (uint64 bytepos)
 
static XLogRecPtr XLogBytePosToEndRecPtr (uint64 bytepos)
 
static uint64 XLogRecPtrToBytePos (XLogRecPtr ptr)
 
static void checkXLogConsistency (XLogReaderState *record)
 
static void WALInsertLockAcquire (void)
 
static void WALInsertLockAcquireExclusive (void)
 
static void WALInsertLockRelease (void)
 
static void WALInsertLockUpdateInsertingAt (XLogRecPtr insertingAt)
 
XLogRecPtr XLogInsertRecord (XLogRecData *rdata, XLogRecPtr fpw_lsn, uint8 flags)
 
static void CalculateCheckpointSegments (void)
 
void assign_max_wal_size (int newval, void *extra)
 
void assign_checkpoint_completion_target (double newval, void *extra)
 
static XLogSegNo XLOGfileslop (XLogRecPtr RedoRecPtr)
 
void XLogSetAsyncXactLSN (XLogRecPtr asyncXactLSN)
 
void XLogSetReplicationSlotMinimumLSN (XLogRecPtr lsn)
 
void XLogFlush (XLogRecPtr record)
 
bool XLogBackgroundFlush (void)
 
bool XLogNeedsFlush (XLogRecPtr record)
 
int XLogFileInit (XLogSegNo logsegno, bool *use_existent, bool use_lock)
 
static void XLogFileCopy (XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno, int upto)
 
int XLogFileOpen (XLogSegNo segno)
 
void CheckXLogRemoved (XLogSegNo segno, TimeLineID tli)
 
XLogSegNo XLogGetLastRemovedSegno (void)
 
static void RemoveNonParentXlogFiles (XLogRecPtr switchpoint, TimeLineID newTLI)
 
void UpdateControlFile (void)
 
uint64 GetSystemIdentifier (void)
 
char * GetMockAuthenticationNonce (void)
 
bool DataChecksumsEnabled (void)
 
XLogRecPtr GetFakeLSNForUnloggedRel (void)
 
static int XLOGChooseNumBuffers (void)
 
bool check_wal_buffers (int *newval, void **extra, GucSource source)
 
void LocalProcessControlFile (bool reset)
 
Size XLOGShmemSize (void)
 
void XLOGShmemInit (void)
 
void BootStrapXLOG (void)
 
static bool getRecordTimestamp (XLogReaderState *record, TimestampTz *recordXtime)
 
bool RecoveryIsPaused (void)
 
void SetRecoveryPause (bool recoveryPause)
 
TimestampTz GetLatestXTime (void)
 
TimestampTz GetCurrentChunkReplayStartTime (void)
 
void GetXLogReceiptTime (TimestampTz *rtime, bool *fromStream)
 
void StartupXLOG (void)
 
bool RecoveryInProgress (void)
 
bool HotStandbyActive (void)
 
bool HotStandbyActiveInReplay (void)
 
bool XLogInsertAllowed (void)
 
void InitXLOGAccess (void)
 
XLogRecPtr GetRedoRecPtr (void)
 
void GetFullPageWriteInfo (XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p)
 
XLogRecPtr GetInsertRecPtr (void)
 
XLogRecPtr GetFlushRecPtr (void)
 
XLogRecPtr GetLastImportantRecPtr (void)
 
pg_time_t GetLastSegSwitchData (XLogRecPtr *lastSwitchLSN)
 
void 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 wal_init_zero = true
 
bool wal_recycle = true
 
bool log_checkpoints = false
 
int sync_method = DEFAULT_SYNC_METHOD
 
int wal_level = WAL_LEVEL_MINIMAL
 
int CommitDelay = 0
 
int CommitSiblings = 5
 
int wal_retrieve_retry_interval = 5000
 
int wal_segment_size = DEFAULT_XLOG_SEG_SIZE
 
int CheckPointSegments
 
static double CheckPointDistanceEstimate = 0
 
static double PrevCheckPointDistance = 0
 
const struct config_enum_entry sync_method_options []
 
const struct config_enum_entry archive_mode_options []
 
const struct config_enum_entry recovery_target_action_options []
 
CheckpointStatsData CheckpointStats
 
TimeLineID ThisTimeLineID = 0
 
bool InRecovery = false
 
HotStandbyState standbyState = STANDBY_DISABLED
 
static XLogRecPtr LastRec
 
static XLogRecPtr 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 standby_signal_file_found = false
 
static bool recovery_signal_file_found = false
 
static bool restoredFromArchive = false
 
static char * replay_image_masked = NULL
 
static char * master_image_masked = NULL
 
char * recoveryRestoreCommand = NULL
 
char * recoveryEndCommand = NULL
 
char * archiveCleanupCommand = NULL
 
RecoveryTargetType recoveryTarget = RECOVERY_TARGET_UNSET
 
bool recoveryTargetInclusive = true
 
int recoveryTargetAction = RECOVERY_TARGET_ACTION_PAUSE
 
TransactionId recoveryTargetXid
 
TimestampTz recoveryTargetTime
 
const char * recoveryTargetName
 
XLogRecPtr recoveryTargetLSN
 
int recovery_min_apply_delay = 0
 
TimestampTz recoveryDelayUntilTime
 
bool StandbyModeRequested = false
 
char * PrimaryConnInfo = NULL
 
char * PrimarySlotName = NULL
 
char * PromoteTriggerFile = 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
 
RecoveryTargetTimeLineGoal recoveryTargetTimeLineGoal = RECOVERY_TARGET_TIMELINE_LATEST
 
TimeLineID recoveryTargetTLIRequested = 0
 
TimeLineID recoveryTargetTLI = 0
 
static ListexpectedTLEs
 
static TimeLineID curFileTLI
 
XLogRecPtr ProcLastRecPtr = InvalidXLogRecPtr
 
XLogRecPtr XactLastRecEnd = InvalidXLogRecPtr
 
XLogRecPtr XactLastCommitEnd = InvalidXLogRecPtr
 
static XLogRecPtr RedoRecPtr
 
static bool doPageWrites
 
static bool doRequestWalReceiverReply
 
static XLogRecPtr RedoStartLSN = InvalidXLogRecPtr
 
static SessionBackupState sessionBackupState = SESSION_BACKUP_NONE
 
static XLogCtlDataXLogCtl = NULL
 
static WALInsertLockPaddedWALInsertLocks = NULL
 
static ControlFileDataControlFile = NULL
 
static int UsableBytesInSegment
 
static XLogwrtResult LogwrtResult = {0, 0}
 
static const char * xlogSourceNames [] = {"any", "archive", "pg_wal", "stream"}
 
static int openLogFile = -1
 
static XLogSegNo openLogSegNo = 0
 
static int readFile = -1
 
static XLogSegNo readSegNo = 0
 
static uint32 readOff = 0
 
static uint32 readLen = 0
 
static XLogSource readSource = 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 748 of file xlog.c.

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

◆ INSERT_FREESPACE

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

Definition at line 728 of file xlog.c.

Referenced by CopyXLogRecordToWAL(), and CreateCheckPoint().

◆ NextBufIdx

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

Definition at line 732 of file xlog.c.

Referenced by XLogWrite().

◆ NUM_XLOGINSERT_LOCKS

◆ RECOVERY_COMMAND_DONE

#define RECOVERY_COMMAND_DONE   "recovery.done"

Definition at line 83 of file xlog.c.

Referenced by readRecoverySignalFile().

◆ RECOVERY_COMMAND_FILE

#define RECOVERY_COMMAND_FILE   "recovery.conf"

Definition at line 82 of file xlog.c.

Referenced by readRecoverySignalFile().

◆ RecoveryRequiresIntParameter

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

Definition at line 6112 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 739 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 514 of file xlog.c.

◆ XLogSource

enum XLogSource
Enumerator
XLOG_FROM_ANY 
XLOG_FROM_ARCHIVE 
XLOG_FROM_PG_WAL 
XLOG_FROM_STREAM 

Definition at line 764 of file xlog.c.

765 {
766  XLOG_FROM_ANY = 0, /* request to read WAL from any source */
767  XLOG_FROM_ARCHIVE, /* restored using restore_command */
768  XLOG_FROM_PG_WAL, /* existing file in pg_wal */
769  XLOG_FROM_STREAM /* streamed from master */
770 } XLogSource;
XLogSource
Definition: xlog.c:764

Function Documentation

◆ AdvanceXLInsertBuffer()

static void AdvanceXLInsertBuffer ( XLogRecPtr  upto,
bool  opportunistic 
)
static

Definition at line 2087 of file xlog.c.

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

Referenced by GetXLogBuffer(), and XLogBackgroundFlush().

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

◆ assign_checkpoint_completion_target()

void assign_checkpoint_completion_target ( double  newval,
void *  extra 
)

Definition at line 2292 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

2293 {
2296 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2256
#define newval
double CheckPointCompletionTarget
Definition: checkpointer.c:148

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2285 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

2286 {
2289 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2256
int max_wal_size_mb
Definition: xlog.c:86
#define newval

◆ assign_xlog_sync_method()

void assign_xlog_sync_method ( int  new_sync_method,
void *  extra 
)

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

10039 {
10040  if (sync_method != new_sync_method)
10041  {
10042  /*
10043  * To ensure that no blocks escape unsynced, force an fsync on the
10044  * currently open log segment (if any). Also, if the open flag is
10045  * changing, close the log file so it will be reopened (with new flag
10046  * bit) at next use.
10047  */
10048  if (openLogFile >= 0)
10049  {
10051  if (pg_fsync(openLogFile) != 0)
10052  ereport(PANIC,
10054  errmsg("could not fsync file \"%s\": %m",
10057  if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
10058  XLogFileClose();
10059  }
10060  }
10061 }
static int get_sync_bit(int method)
Definition: xlog.c:9982
#define PANIC
Definition: elog.h:53
static XLogSegNo openLogSegNo
Definition: xlog.c:781
static void XLogFileClose(void)
Definition: xlog.c:3780
char * XLogFileNameP(TimeLineID tli, XLogSegNo segno)
Definition: xlog.c:10116
int errcode_for_file_access(void)
Definition: elog.c:593
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1316
#define ereport(elevel, rest)
Definition: elog.h:141
static int openLogFile
Definition: xlog.c:780
TimeLineID ThisTimeLineID
Definition: xlog.c:187
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1292
int sync_method
Definition: xlog.c:102
int errmsg(const char *fmt,...)
Definition: elog.c:784
int pg_fsync(int fd)
Definition: fd.c:333

◆ BackupInProgress()

bool BackupInProgress ( void  )

Definition at line 11412 of file xlog.c.

References BACKUP_LABEL_FILE, and stat.

Referenced by pg_is_in_backup(), and PostmasterStateMachine().

11413 {
11414  struct stat stat_buf;
11415 
11416  return (stat(BACKUP_LABEL_FILE, &stat_buf) == 0);
11417 }
struct stat stat_buf
Definition: pg_standby.c:102
#define stat(a, b)
Definition: win32_port.h:264
#define BACKUP_LABEL_FILE
Definition: xlog.h:359

◆ BootStrapXLOG()

void BootStrapXLOG ( void  )

Definition at line 5088 of file xlog.c.

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

Referenced by AuxiliaryProcessMain().

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

◆ CalculateCheckpointSegments()

static void CalculateCheckpointSegments ( void  )
static

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

2257 {
2258  double target;
2259 
2260  /*-------
2261  * Calculate the distance at which to trigger a checkpoint, to avoid
2262  * exceeding max_wal_size_mb. This is based on two assumptions:
2263  *
2264  * a) we keep WAL for only one checkpoint cycle (prior to PG11 we kept
2265  * WAL for two checkpoint cycles to allow us to recover from the
2266  * secondary checkpoint if the first checkpoint failed, though we
2267  * only did this on the master anyway, not on standby. Keeping just
2268  * one checkpoint simplifies processing and reduces disk space in
2269  * many smaller databases.)
2270  * b) during checkpoint, we consume checkpoint_completion_target *
2271  * number of segments consumed between checkpoints.
2272  *-------
2273  */
2274  target = (double) ConvertToXSegs(max_wal_size_mb, wal_segment_size) /
2276 
2277  /* round down */
2278  CheckPointSegments = (int) target;
2279 
2280  if (CheckPointSegments < 1)
2281  CheckPointSegments = 1;
2282 }
#define ConvertToXSegs(x, segsize)
Definition: xlog.c:748
int wal_segment_size
Definition: xlog.c:112
int max_wal_size_mb
Definition: xlog.c:86
int CheckPointSegments
Definition: xlog.c:125
double CheckPointCompletionTarget
Definition: checkpointer.c:148

◆ CancelBackup()

void CancelBackup ( void  )

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

11433 {
11434  struct stat stat_buf;
11435 
11436  /* if the backup_label file is not there, return */
11437  if (stat(BACKUP_LABEL_FILE, &stat_buf) < 0)
11438  return;
11439 
11440  /* remove leftover file from previously canceled backup if it exists */
11441  unlink(BACKUP_LABEL_OLD);
11442 
11444  {
11445  ereport(WARNING,
11447  errmsg("online backup mode was not canceled"),
11448  errdetail("File \"%s\" could not be renamed to \"%s\": %m.",
11450  return;
11451  }
11452 
11453  /* if the tablespace_map file is not there, return */
11454  if (stat(TABLESPACE_MAP, &stat_buf) < 0)
11455  {
11456  ereport(LOG,
11457  (errmsg("online backup mode canceled"),
11458  errdetail("File \"%s\" was renamed to \"%s\".",
11460  return;
11461  }
11462 
11463  /* remove leftover file from previously canceled backup if it exists */
11464  unlink(TABLESPACE_MAP_OLD);
11465 
11467  {
11468  ereport(LOG,
11469  (errmsg("online backup mode canceled"),
11470  errdetail("Files \"%s\" and \"%s\" were renamed to "
11471  "\"%s\" and \"%s\", respectively.",
11474  }
11475  else
11476  {
11477  ereport(WARNING,
11479  errmsg("online backup mode canceled"),
11480  errdetail("File \"%s\" was renamed to \"%s\", but "
11481  "file \"%s\" could not be renamed to \"%s\": %m.",
11484  }
11485 }
#define DEBUG1
Definition: elog.h:25
#define LOG
Definition: elog.h:26
#define BACKUP_LABEL_OLD
Definition: xlog.h:360
#define TABLESPACE_MAP
Definition: xlog.h:362
struct stat stat_buf
Definition: pg_standby.c:102
int errdetail(const char *fmt,...)
Definition: elog.c:860
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:608
#define WARNING
Definition: elog.h:40
#define stat(a, b)
Definition: win32_port.h:264
#define TABLESPACE_MAP_OLD
Definition: xlog.h:363
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define BACKUP_LABEL_FILE
Definition: xlog.h:359

◆ check_wal_buffers()

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

Definition at line 4879 of file xlog.c.

References XLOGbuffers, and XLOGChooseNumBuffers().

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

◆ CheckForStandbyTrigger()

static bool CheckForStandbyTrigger ( void  )
static

Definition at line 12123 of file xlog.c.

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

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

12124 {
12125  struct stat stat_buf;
12126  static bool triggered = false;
12127 
12128  if (triggered)
12129  return true;
12130 
12131  if (IsPromoteTriggered())
12132  {
12133  /*
12134  * In 9.1 and 9.2 the postmaster unlinked the promote file inside the
12135  * signal handler. It now leaves the file in place and lets the
12136  * Startup process do the unlink. This allows Startup to know whether
12137  * it should create a full checkpoint before starting up (fallback
12138  * mode). Fast promotion takes precedence.
12139  */
12140  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
12141  {
12142  unlink(PROMOTE_SIGNAL_FILE);
12144  fast_promote = true;
12145  }
12146  else if (stat(FALLBACK_PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
12147  {
12149  fast_promote = false;
12150  }
12151 
12152  ereport(LOG, (errmsg("received promote request")));
12153 
12155  triggered = true;
12156  return true;
12157  }
12158 
12159  if (PromoteTriggerFile == NULL || strcmp(PromoteTriggerFile, "") == 0)
12160  return false;
12161 
12162  if (stat(PromoteTriggerFile, &stat_buf) == 0)
12163  {
12164  ereport(LOG,
12165  (errmsg("promote trigger file found: %s", PromoteTriggerFile)));
12166  unlink(PromoteTriggerFile);
12167  triggered = true;
12168  fast_promote = true;
12169  return true;
12170  }
12171  else if (errno != ENOENT)
12172  ereport(ERROR,
12174  errmsg("could not stat promote trigger file \"%s\": %m",
12175  PromoteTriggerFile)));
12176 
12177  return false;
12178 }
char * PromoteTriggerFile
Definition: xlog.c:285
void ResetPromoteTriggered(void)
Definition: startup.c:243
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:366
#define LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:43
struct stat stat_buf
Definition: pg_standby.c:102
int errcode_for_file_access(void)
Definition: elog.c:593
bool IsPromoteTriggered(void)
Definition: startup.c:237
#define ereport(elevel, rest)
Definition: elog.h:141
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.h:367
#define stat(a, b)
Definition: win32_port.h:264
int errmsg(const char *fmt,...)
Definition: elog.c:784
static bool fast_promote
Definition: xlog.c:291

◆ CheckPointGuts()

static void CheckPointGuts ( XLogRecPtr  checkPointRedo,
int  flags 
)
static

Definition at line 8966 of file xlog.c.

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

Referenced by CreateCheckPoint(), and CreateRestartPoint().

8967 {
8968  CheckPointCLOG();
8977  CheckPointBuffers(flags); /* performs all required fsyncs */
8979  /* We deliberately delay 2PC checkpointing as long as possible */
8980  CheckPointTwoPhase(checkPointRedo);
8981 }
void CheckPointBuffers(int flags)
Definition: bufmgr.c:2580
void CheckPointLogicalRewriteHeap(void)
Definition: rewriteheap.c:1222
void CheckPointReplicationOrigin(void)
Definition: origin.c:545
void CheckPointSnapBuild(void)
Definition: snapbuild.c:1937
void CheckPointCLOG(void)
Definition: clog.c:842
void CheckPointMultiXact(void)
Definition: multixact.c:2140
void CheckPointCommitTs(void)
Definition: commit_ts.c:760
void CheckPointSUBTRANS(void)
Definition: subtrans.c:302
void CheckPointRelationMap(void)
Definition: relmapper.c:546
void CheckPointPredicate(void)
Definition: predicate.c:1018
void CheckPointTwoPhase(XLogRecPtr redo_horizon)
Definition: twophase.c:1751
void CheckPointReplicationSlots(void)
Definition: slot.c:1074

◆ CheckPromoteSignal()

bool CheckPromoteSignal ( void  )

Definition at line 12195 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, PROMOTE_SIGNAL_FILE, and stat.

Referenced by sigusr1_handler().

12196 {
12197  struct stat stat_buf;
12198 
12199  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
12201  return true;
12202 
12203  return false;
12204 }
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:366
struct stat stat_buf
Definition: pg_standby.c:102
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.h:367
#define stat(a, b)
Definition: win32_port.h:264

◆ CheckRecoveryConsistency()

static void CheckRecoveryConsistency ( void  )
static

Definition at line 7783 of file xlog.c.

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

Referenced by ReadRecord(), and StartupXLOG().

7784 {
7785  XLogRecPtr lastReplayedEndRecPtr;
7786 
7787  /*
7788  * During crash recovery, we don't reach a consistent state until we've
7789  * replayed all the WAL.
7790  */
7792  return;
7793 
7795 
7796  /*
7797  * assume that we are called in the startup process, and hence don't need
7798  * a lock to read lastReplayedEndRecPtr
7799  */
7800  lastReplayedEndRecPtr = XLogCtl->lastReplayedEndRecPtr;
7801 
7802  /*
7803  * Have we reached the point where our base backup was completed?
7804  */
7806  ControlFile->backupEndPoint <= lastReplayedEndRecPtr)
7807  {
7808  /*
7809  * We have reached the end of base backup, as indicated by pg_control.
7810  * The data on disk is now consistent. Reset backupStartPoint and
7811  * backupEndPoint, and update minRecoveryPoint to make sure we don't
7812  * allow starting up at an earlier point even if recovery is stopped
7813  * and restarted soon after this.
7814  */
7815  elog(DEBUG1, "end of backup reached");
7816 
7817  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7818 
7819  if (ControlFile->minRecoveryPoint < lastReplayedEndRecPtr)
7820  ControlFile->minRecoveryPoint = lastReplayedEndRecPtr;
7821 
7824  ControlFile->backupEndRequired = false;
7826 
7827  LWLockRelease(ControlFileLock);
7828  }
7829 
7830  /*
7831  * Have we passed our safe starting point? Note that minRecoveryPoint is
7832  * known to be incorrectly set if ControlFile->backupEndRequired, until
7833  * the XLOG_BACKUP_END arrives to advise us of the correct
7834  * minRecoveryPoint. All we know prior to that is that we're not
7835  * consistent yet.
7836  */
7838  minRecoveryPoint <= lastReplayedEndRecPtr &&
7840  {
7841  /*
7842  * Check to see if the XLOG sequence contained any unresolved
7843  * references to uninitialized pages.
7844  */
7846 
7847  reachedConsistency = true;
7848  ereport(LOG,
7849  (errmsg("consistent recovery state reached at %X/%X",
7850  (uint32) (lastReplayedEndRecPtr >> 32),
7851  (uint32) lastReplayedEndRecPtr)));
7852  }
7853 
7854  /*
7855  * Have we got a valid starting snapshot that will allow queries to be
7856  * run? If so, we can tell postmaster that the database is consistent now,
7857  * enabling connections.
7858  */
7863  {
7867 
7868  LocalHotStandbyActive = true;
7869 
7871  }
7872 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define DEBUG1
Definition: elog.h:25
void XLogCheckInvalidPages(void)
Definition: xlogutils.c:220
bool SharedHotStandbyActive
Definition: xlog.c:656
slock_t info_lck
Definition: xlog.c:711
#define LOG
Definition: elog.h:26
bool InArchiveRecovery
Definition: xlog.c:255
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1726
bool backupEndRequired
Definition: pg_control.h:170
#define SpinLockAcquire(lock)
Definition: spin.h:62
static bool LocalHotStandbyActive
Definition: xlog.c:229
void UpdateControlFile(void)
Definition: xlog.c:4794
bool IsUnderPostmaster
Definition: globals.c:109
unsigned int uint32
Definition: c.h:358
#define ereport(elevel, rest)
Definition: elog.h:141
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
#define SpinLockRelease(lock)
Definition: spin.h:64
static ControlFileData * ControlFile
Definition: xlog.c:722
XLogRecPtr backupEndPoint
Definition: pg_control.h:169
bool reachedConsistency
Definition: xlog.c:845
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:732
static XLogCtlData * XLogCtl
Definition: xlog.c:714
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1122
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:146
HotStandbyState standbyState
Definition: xlog.c:203
XLogRecPtr backupStartPoint
Definition: pg_control.h:168
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:836
XLogRecPtr lastReplayedEndRecPtr
Definition: xlog.c:690

◆ CheckRequiredParameterValues()

static void CheckRequiredParameterValues ( void  )
static

Definition at line 6134 of file xlog.c.

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

Referenced by StartupXLOG(), and xlog_redo().

6135 {
6136  /*
6137  * For archive recovery, the WAL must be generated with at least 'replica'
6138  * wal_level.
6139  */
6141  {
6142  ereport(WARNING,
6143  (errmsg("WAL was generated with wal_level=minimal, data may be missing"),
6144  errhint("This happens if you temporarily set wal_level=minimal without taking a new base backup.")));
6145  }
6146 
6147  /*
6148  * For Hot Standby, the WAL must be generated with 'replica' mode, and we
6149  * must have at least as many backend slots as the primary.
6150  */
6152  {
6154  ereport(ERROR,
6155  (errmsg("hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server"),
6156  errhint("Either set wal_level to \"replica\" on the master, or turn off hot_standby here.")));
6157 
6158  /* We ignore autovacuum_max_workers when we make this test. */
6159  RecoveryRequiresIntParameter("max_connections",
6162  RecoveryRequiresIntParameter("max_worker_processes",
6165  RecoveryRequiresIntParameter("max_wal_senders",
6168  RecoveryRequiresIntParameter("max_prepared_transactions",
6171  RecoveryRequiresIntParameter("max_locks_per_transaction",
6174  }
6175 }
bool ArchiveRecoveryRequested
Definition: xlog.c:254
int max_locks_per_xact
Definition: pg_control.h:182
int errhint(const char *fmt,...)
Definition: elog.c:974
int max_prepared_xacts
Definition: pg_control.h:181
int max_worker_processes
Definition: pg_control.h:179
#define ERROR
Definition: elog.h:43
int max_prepared_xacts
Definition: twophase.c:118
#define ereport(elevel, rest)
Definition: elog.h:141
int max_locks_per_xact
Definition: lock.c:54
int max_wal_senders
Definition: walsender.c:120
#define WARNING
Definition: elog.h:40
int MaxConnections
Definition: globals.c:132
static ControlFileData * ControlFile
Definition: xlog.c:722
bool EnableHotStandby
Definition: xlog.c:93
int errmsg(const char *fmt,...)
Definition: elog.c:784
int max_worker_processes
Definition: globals.c:133
#define RecoveryRequiresIntParameter(param_name, currValue, minValue)
Definition: xlog.c:6112

◆ checkTimeLineSwitch()

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

Definition at line 9531 of file xlog.c.

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

Referenced by StartupXLOG().

9532 {
9533  /* Check that the record agrees on what the current (old) timeline is */
9534  if (prevTLI != ThisTimeLineID)
9535  ereport(PANIC,
9536  (errmsg("unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record",
9537  prevTLI, ThisTimeLineID)));
9538 
9539  /*
9540  * The new timeline better be in the list of timelines we expect to see,
9541  * according to the timeline history. It should also not decrease.
9542  */
9543  if (newTLI < ThisTimeLineID || !tliInHistory(newTLI, expectedTLEs))
9544  ereport(PANIC,
9545  (errmsg("unexpected timeline ID %u (after %u) in checkpoint record",
9546  newTLI, ThisTimeLineID)));
9547 
9548  /*
9549  * If we have not yet reached min recovery point, and we're about to
9550  * switch to a timeline greater than the timeline of the min recovery
9551  * point: trouble. After switching to the new timeline, we could not
9552  * possibly visit the min recovery point on the correct timeline anymore.
9553  * This can happen if there is a newer timeline in the archive that
9554  * branched before the timeline the min recovery point is on, and you
9555  * attempt to do PITR to the new timeline.
9556  */
9558  lsn < minRecoveryPoint &&
9559  newTLI > minRecoveryPointTLI)
9560  ereport(PANIC,
9561  (errmsg("unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u",
9562  newTLI,
9563  (uint32) (minRecoveryPoint >> 32),
9566 
9567  /* Looks good */
9568 }
static List * expectedTLEs
Definition: xlog.c:334
#define PANIC
Definition: elog.h:53
unsigned int uint32
Definition: c.h:358
#define ereport(elevel, rest)
Definition: elog.h:141
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
static TimeLineID minRecoveryPointTLI
Definition: xlog.c:837
TimeLineID ThisTimeLineID
Definition: xlog.c:187
int errmsg(const char *fmt,...)
Definition: elog.c:784
bool tliInHistory(TimeLineID tli, List *expectedTLEs)
Definition: timeline.c:517
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:836

◆ checkXLogConsistency()

static void checkXLogConsistency ( XLogReaderState record)
static

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

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

◆ CheckXLogRemoved()

void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)

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

3848 {
3849  int save_errno = errno;
3850  XLogSegNo lastRemovedSegNo;
3851 
3853  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3855 
3856  if (segno <= lastRemovedSegNo)
3857  {
3858  char filename[MAXFNAMELEN];
3859 
3860  XLogFileName(filename, tli, segno, wal_segment_size);
3861  errno = save_errno;
3862  ereport(ERROR,
3864  errmsg("requested WAL segment %s has already been removed",
3865  filename)));
3866  }
3867  errno = save_errno;
3868 }
int wal_segment_size
Definition: xlog.c:112
slock_t info_lck
Definition: xlog.c:711
XLogSegNo lastRemovedSegNo
Definition: xlog.c:600
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define ERROR
Definition: elog.h:43
uint64 XLogSegNo
Definition: xlogdefs.h:41
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static XLogCtlData * XLogCtl
Definition: xlog.c:714
static char * filename
Definition: pg_dumpall.c:91
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ CleanupBackupHistory()

static void CleanupBackupHistory ( void  )
static

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

4211 {
4212  DIR *xldir;
4213  struct dirent *xlde;
4214  char path[MAXPGPATH + sizeof(XLOGDIR)];
4215 
4216  xldir = AllocateDir(XLOGDIR);
4217 
4218  while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
4219  {
4220  if (IsBackupHistoryFileName(xlde->d_name))
4221  {
4222  if (XLogArchiveCheckDone(xlde->d_name))
4223  {
4224  elog(DEBUG2, "removing WAL backup history file \"%s\"",
4225  xlde->d_name);
4226  snprintf(path, sizeof(path), XLOGDIR "/%s", xlde->d_name);
4227  unlink(path);
4228  XLogArchiveCleanup(xlde->d_name);
4229  }
4230  }
4231  }
4232 
4233  FreeDir(xldir);
4234 }
Definition: dirent.h:9
void XLogArchiveCleanup(const char *xlog)
Definition: xlogarchive.c:749
Definition: dirent.c:25
bool XLogArchiveCheckDone(const char *xlog)
Definition: xlogarchive.c:609
#define MAXPGPATH
#define DEBUG2
Definition: elog.h:24
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2472
#define IsBackupHistoryFileName(fname)
#define XLOGDIR
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2538
#define elog(elevel,...)
Definition: elog.h:226
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192
int FreeDir(DIR *dir)
Definition: fd.c:2590

◆ CopyXLogRecordToWAL()

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

Definition at line 1473 of file xlog.c.

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

Referenced by XLogInsertRecord().

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

◆ CreateCheckPoint()

void CreateCheckPoint ( int  flags)

Definition at line 8496 of file xlog.c.

References ControlFileData::checkPoint, CHECKPOINT_END_OF_RECOVERY, CHECKPOINT_FORCE, CHECKPOINT_IS_SHUTDOWN, ControlFileData::checkPointCopy, CheckPointGuts(), CheckpointStatsData::ckpt_bufs_written, CheckpointStatsData::ckpt_segs_added, CheckpointStatsData::ckpt_segs_recycled, CheckpointStatsData::ckpt_segs_removed, CheckpointStatsData::ckpt_start_t, XLogCtlData::ckptFullXid, XLogCtlInsert::CurrBytePos, DB_SHUTDOWNED, DB_SHUTDOWNING, DEBUG1, elog, END_CRIT_SECTION, ereport, errmsg(), ERROR, CheckPoint::fullPageWrites, XLogCtlInsert::fullPageWrites, GetCurrentTimestamp(), GetLastImportantRecPtr(), GetOldestActiveTransactionId(), 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::nextFullXid, VariableCacheData::nextFullXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, VariableCacheData::nextOid, 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, SpinLockAcquire, SpinLockRelease, START_CRIT_SECTION, ControlFileData::state, SyncPostCheckpoint(), SyncPreCheckpoint(), CheckPoint::ThisTimeLineID, ThisTimeLineID, CheckPoint::time, ControlFileData::time, TruncateSUBTRANS(), XLogCtlData::ulsn_lck, ControlFileData::unloggedLSN, XLogCtlData::unloggedLSN, UpdateCheckPointDistanceEstimate(), UpdateControlFile(), wal_segment_size, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), XLByteToSeg, XLOG_CHECKPOINT_ONLINE, XLOG_CHECKPOINT_SHUTDOWN, XLogBeginInsert(), XLogBytePosToRecPtr(), XLogFlush(), XLogInsert(), XLogRegisterData(), XLogSegmentOffset, and XLogStandbyInfoActive.

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

8497 {
8498  bool shutdown;
8499  CheckPoint checkPoint;
8500  XLogRecPtr recptr;
8501  XLogSegNo _logSegNo;
8503  uint32 freespace;
8504  XLogRecPtr PriorRedoPtr;
8505  XLogRecPtr curInsert;
8506  XLogRecPtr last_important_lsn;
8507  VirtualTransactionId *vxids;
8508  int nvxids;
8509 
8510  /*
8511  * An end-of-recovery checkpoint is really a shutdown checkpoint, just
8512  * issued at a different time.
8513  */
8515  shutdown = true;
8516  else
8517  shutdown = false;
8518 
8519  /* sanity check */
8520  if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
8521  elog(ERROR, "can't create a checkpoint during recovery");
8522 
8523  /*
8524  * Initialize InitXLogInsert working areas before entering the critical
8525  * section. Normally, this is done by the first call to
8526  * RecoveryInProgress() or LocalSetXLogInsertAllowed(), but when creating
8527  * an end-of-recovery checkpoint, the LocalSetXLogInsertAllowed call is
8528  * done below in a critical section, and InitXLogInsert cannot be called
8529  * in a critical section.
8530  */
8531  InitXLogInsert();
8532 
8533  /*
8534  * Acquire CheckpointLock to ensure only one checkpoint happens at a time.
8535  * (This is just pro forma, since in the present system structure there is
8536  * only one process that is allowed to issue checkpoints at any given
8537  * time.)
8538  */
8539  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
8540 
8541  /*
8542  * Prepare to accumulate statistics.
8543  *
8544  * Note: because it is possible for log_checkpoints to change while a
8545  * checkpoint proceeds, we always accumulate stats, even if
8546  * log_checkpoints is currently off.
8547  */
8548  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
8550 
8551  /*
8552  * Use a critical section to force system panic if we have trouble.
8553  */
8555 
8556  if (shutdown)
8557  {
8558  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8560  ControlFile->time = (pg_time_t) time(NULL);
8562  LWLockRelease(ControlFileLock);
8563  }
8564 
8565  /*
8566  * Let smgr prepare for checkpoint; this has to happen before we determine
8567  * the REDO pointer. Note that smgr must not do anything that'd have to
8568  * be undone if we decide no checkpoint is needed.
8569  */
8571 
8572  /* Begin filling in the checkpoint WAL record */
8573  MemSet(&checkPoint, 0, sizeof(checkPoint));
8574  checkPoint.time = (pg_time_t) time(NULL);
8575 
8576  /*
8577  * For Hot Standby, derive the oldestActiveXid before we fix the redo
8578  * pointer. This allows us to begin accumulating changes to assemble our
8579  * starting snapshot of locks and transactions.
8580  */
8581  if (!shutdown && XLogStandbyInfoActive())
8583  else
8585 
8586  /*
8587  * Get location of last important record before acquiring insert locks (as
8588  * GetLastImportantRecPtr() also locks WAL locks).
8589  */
8590  last_important_lsn = GetLastImportantRecPtr();
8591 
8592  /*
8593  * We must block concurrent insertions while examining insert state to
8594  * determine the checkpoint REDO pointer.
8595  */
8597  curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
8598 
8599  /*
8600  * If this isn't a shutdown or forced checkpoint, and if there has been no
8601  * WAL activity requiring a checkpoint, skip it. The idea here is to
8602  * avoid inserting duplicate checkpoints when the system is idle.
8603  */
8604  if ((flags & (CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_END_OF_RECOVERY |
8605  CHECKPOINT_FORCE)) == 0)
8606  {
8607  if (last_important_lsn == ControlFile->checkPoint)
8608  {
8610  LWLockRelease(CheckpointLock);
8611  END_CRIT_SECTION();
8612  ereport(DEBUG1,
8613  (errmsg("checkpoint skipped because system is idle")));
8614  return;
8615  }
8616  }
8617 
8618  /*
8619  * An end-of-recovery checkpoint is created before anyone is allowed to
8620  * write WAL. To allow us to write the checkpoint record, temporarily
8621  * enable XLogInsertAllowed. (This also ensures ThisTimeLineID is
8622  * initialized, which we need here and in AdvanceXLInsertBuffer.)
8623  */
8624  if (flags & CHECKPOINT_END_OF_RECOVERY)
8626 
8627  checkPoint.ThisTimeLineID = ThisTimeLineID;
8628  if (flags & CHECKPOINT_END_OF_RECOVERY)
8629  checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
8630  else
8631  checkPoint.PrevTimeLineID = ThisTimeLineID;
8632 
8633  checkPoint.fullPageWrites = Insert->fullPageWrites;
8634 
8635  /*
8636  * Compute new REDO record ptr = location of next XLOG record.
8637  *
8638  * NB: this is NOT necessarily where the checkpoint record itself will be,
8639  * since other backends may insert more XLOG records while we're off doing
8640  * the buffer flush work. Those XLOG records are logically after the
8641  * checkpoint, even though physically before it. Got that?
8642  */
8643  freespace = INSERT_FREESPACE(curInsert);
8644  if (freespace == 0)
8645  {
8646  if (XLogSegmentOffset(curInsert, wal_segment_size) == 0)
8647  curInsert += SizeOfXLogLongPHD;
8648  else
8649  curInsert += SizeOfXLogShortPHD;
8650  }
8651  checkPoint.redo = curInsert;
8652 
8653  /*
8654  * Here we update the shared RedoRecPtr for future XLogInsert calls; this
8655  * must be done while holding all the insertion locks.
8656  *
8657  * Note: if we fail to complete the checkpoint, RedoRecPtr will be left
8658  * pointing past where it really needs to point. This is okay; the only
8659  * consequence is that XLogInsert might back up whole buffers that it
8660  * didn't really need to. We can't postpone advancing RedoRecPtr because
8661  * XLogInserts that happen while we are dumping buffers must assume that
8662  * their buffer changes are not included in the checkpoint.
8663  */
8664  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
8665 
8666  /*
8667  * Now we can release the WAL insertion locks, allowing other xacts to
8668  * proceed while we are flushing disk buffers.
8669  */
8671 
8672  /* Update the info_lck-protected copy of RedoRecPtr as well */
8674  XLogCtl->RedoRecPtr = checkPoint.redo;
8676 
8677  /*
8678  * If enabled, log checkpoint start. We postpone this until now so as not
8679  * to log anything if we decided to skip the checkpoint.
8680  */
8681  if (log_checkpoints)
8682  LogCheckpointStart(flags, false);
8683 
8684  TRACE_POSTGRESQL_CHECKPOINT_START(flags);
8685 
8686  /*
8687  * Get the other info we need for the checkpoint record.
8688  *
8689  * We don't need to save oldestClogXid in the checkpoint, it only matters
8690  * for the short period in which clog is being truncated, and if we crash
8691  * during that we'll redo the clog truncation and fix up oldestClogXid
8692  * there.
8693  */
8694  LWLockAcquire(XidGenLock, LW_SHARED);
8696  checkPoint.oldestXid = ShmemVariableCache->oldestXid;
8698  LWLockRelease(XidGenLock);
8699 
8700  LWLockAcquire(CommitTsLock, LW_SHARED);
8703  LWLockRelease(CommitTsLock);
8704 
8705  LWLockAcquire(OidGenLock, LW_SHARED);
8706  checkPoint.nextOid = ShmemVariableCache->nextOid;
8707  if (!shutdown)
8708  checkPoint.nextOid += ShmemVariableCache->oidCount;
8709  LWLockRelease(OidGenLock);
8710 
8711  MultiXactGetCheckptMulti(shutdown,
8712  &checkPoint.nextMulti,
8713  &checkPoint.nextMultiOffset,
8714  &checkPoint.oldestMulti,
8715  &checkPoint.oldestMultiDB);
8716 
8717  /*
8718  * Having constructed the checkpoint record, ensure all shmem disk buffers
8719  * and commit-log buffers are flushed to disk.
8720  *
8721  * This I/O could fail for various reasons. If so, we will fail to
8722  * complete the checkpoint, but there is no reason to force a system
8723  * panic. Accordingly, exit critical section while doing it.
8724  */
8725  END_CRIT_SECTION();
8726 
8727  /*
8728  * In some cases there are groups of actions that must all occur on one
8729  * side or the other of a checkpoint record. Before flushing the
8730  * checkpoint record we must explicitly wait for any backend currently
8731  * performing those groups of actions.
8732  *
8733  * One example is end of transaction, so we must wait for any transactions
8734  * that are currently in commit critical sections. If an xact inserted
8735  * its commit record into XLOG just before the REDO point, then a crash
8736  * restart from the REDO point would not replay that record, which means
8737  * that our flushing had better include the xact's update of pg_xact. So
8738  * we wait till he's out of his commit critical section before proceeding.
8739  * See notes in RecordTransactionCommit().
8740  *
8741  * Because we've already released the insertion locks, this test is a bit
8742  * fuzzy: it is possible that we will wait for xacts we didn't really need
8743  * to wait for. But the delay should be short and it seems better to make
8744  * checkpoint take a bit longer than to hold off insertions longer than
8745  * necessary. (In fact, the whole reason we have this issue is that xact.c
8746  * does commit record XLOG insertion and clog update as two separate steps
8747  * protected by different locks, but again that seems best on grounds of
8748  * minimizing lock contention.)
8749  *
8750  * A transaction that has not yet set delayChkpt when we look cannot be at
8751  * risk, since he's not inserted his commit record yet; and one that's
8752  * already cleared it is not at risk either, since he's done fixing clog
8753  * and we will correctly flush the update below. So we cannot miss any
8754  * xacts we need to wait for.
8755  */
8756  vxids = GetVirtualXIDsDelayingChkpt(&nvxids);
8757  if (nvxids > 0)
8758  {
8759  do
8760  {
8761  pg_usleep(10000L); /* wait for 10 msec */
8762  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids));
8763  }
8764  pfree(vxids);
8765 
8766  CheckPointGuts(checkPoint.redo, flags);
8767 
8768  /*
8769  * Take a snapshot of running transactions and write this to WAL. This
8770  * allows us to reconstruct the state of running transactions during
8771  * archive recovery, if required. Skip, if this info disabled.
8772  *
8773  * If we are shutting down, or Startup process is completing crash
8774  * recovery we don't need to write running xact data.
8775  */
8776  if (!shutdown && XLogStandbyInfoActive())
8778 
8780 
8781  /*
8782  * Now insert the checkpoint record into XLOG.
8783  */
8784  XLogBeginInsert();
8785  XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));
8786  recptr = XLogInsert(RM_XLOG_ID,
8787  shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
8789 
8790  XLogFlush(recptr);
8791 
8792  /*
8793  * We mustn't write any new WAL after a shutdown checkpoint, or it will be
8794  * overwritten at next startup. No-one should even try, this just allows
8795  * sanity-checking. In the case of an end-of-recovery checkpoint, we want
8796  * to just temporarily disable writing until the system has exited
8797  * recovery.
8798  */
8799  if (shutdown)
8800  {
8801  if (flags & CHECKPOINT_END_OF_RECOVERY)
8802  LocalXLogInsertAllowed = -1; /* return to "check" state */
8803  else
8804  LocalXLogInsertAllowed = 0; /* never again write WAL */
8805  }
8806 
8807  /*
8808  * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
8809  * = end of actual checkpoint record.
8810  */
8811  if (shutdown && checkPoint.redo != ProcLastRecPtr)
8812  ereport(PANIC,
8813  (errmsg("concurrent write-ahead log activity while database system is shutting down")));
8814 
8815  /*
8816  * Remember the prior checkpoint's redo ptr for
8817  * UpdateCheckPointDistanceEstimate()
8818  */
8819  PriorRedoPtr = ControlFile->checkPointCopy.redo;
8820 
8821  /*
8822  * Update the control file.
8823  */
8824  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8825  if (shutdown)
8828  ControlFile->checkPointCopy = checkPoint;
8829  ControlFile->time = (pg_time_t) time(NULL);
8830  /* crash recovery should always recover to the end of WAL */
8833 
8834  /*
8835  * Persist unloggedLSN value. It's reset on crash recovery, so this goes
8836  * unused on non-shutdown checkpoints, but seems useful to store it always
8837  * for debugging purposes.
8838  */
8842 
8844  LWLockRelease(ControlFileLock);
8845 
8846  /* Update shared-memory copy of checkpoint XID/epoch */
8848  XLogCtl->ckptFullXid = checkPoint.nextFullXid;
8850 
8851  /*
8852  * We are now done with critical updates; no need for system panic if we
8853  * have trouble while fooling with old log segments.
8854  */
8855  END_CRIT_SECTION();
8856 
8857  /*
8858  * Let smgr do post-checkpoint cleanup (eg, deleting old files).
8859  */
8861 
8862  /*
8863  * Update the average distance between checkpoints if the prior checkpoint
8864  * exists.
8865  */
8866  if (PriorRedoPtr != InvalidXLogRecPtr)
8868 
8869  /*
8870  * Delete old log files, those no longer needed for last checkpoint to
8871  * prevent the disk holding the xlog from growing full.
8872  */
8874  KeepLogSeg(recptr, &_logSegNo);
8875  _logSegNo--;
8876  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr);
8877 
8878  /*
8879  * Make more log segments if needed. (Do this after recycling old log
8880  * segments, since that may supply some of the needed files.)
8881  */
8882  if (!shutdown)
8883  PreallocXlogFiles(recptr);
8884 
8885  /*
8886  * Truncate pg_subtrans if possible. We can throw away all data before
8887  * the oldest XMIN of any running transaction. No future transaction will
8888  * attempt to reference any pg_subtrans entry older than that (see Asserts
8889  * in subtrans.c). During recovery, though, we mustn't do this because
8890  * StartupSUBTRANS hasn't been called yet.
8891  */
8892  if (!RecoveryInProgress())
8894 
8895  /* Real work is done, but log and update stats before releasing lock. */
8896  LogCheckpointEnd(false);
8897 
8898  TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
8899  NBuffers,
8903 
8904  LWLockRelease(CheckpointLock);
8905 }
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:8234
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8434
static int LocalXLogInsertAllowed
Definition: xlog.c:241
bool log_checkpoints
Definition: xlog.c:101
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define DEBUG1
Definition: elog.h:25
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1691
int wal_segment_size
Definition: xlog.c:112
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:159
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1591
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1960
XLogRecPtr unloggedLSN
Definition: xlog.c:603
XLogRecPtr ProcLastRecPtr
Definition: xlog.c:352
TransactionId oldestActiveXid
Definition: pg_control.h:63
void InitXLogInsert(void)
Definition: xloginsert.c:1110
TimestampTz ckpt_start_t
Definition: xlog.h:235
slock_t info_lck
Definition: xlog.c:711
#define END_CRIT_SECTION()
Definition: miscadmin.h:134
VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids)
Definition: procarray.c:2273
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: xlog.c:644
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
#define START_CRIT_SECTION()
Definition: miscadmin.h:132
int ckpt_segs_recycled
Definition: xlog.h:245
TransactionId oldestXid
Definition: transam.h:166
#define MemSet(start, val, len)
Definition: c.h:941
void MultiXactGetCheckptMulti(bool is_shutdown, MultiXactId *nextMulti, MultiXactOffset *nextMultiOffset, MultiXactId *oldestMulti, Oid *oldestMultiDB)
Definition: multixact.c:2118
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:8966
FullTransactionId nextFullXid
Definition: transam.h:164
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:591
TransactionId oldestXid
Definition: pg_control.h:47
bool RecoveryInProgress(void)
Definition: xlog.c:7884
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:356
pg_time_t time
Definition: pg_control.h:51
#define PANIC
Definition: elog.h:53
bool fullPageWrites
Definition: xlog.c:566
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2799
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1726
#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:4794
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
void pfree(void *pointer)
Definition: mcxt.c:1031
XLogRecPtr LogStandbySnapshot(void)
Definition: standby.c:901
#define ERROR
Definition: elog.h:43
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8349
static XLogRecPtr RedoRecPtr
Definition: xlog.c:366
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
XLogRecPtr unloggedLSN
Definition: pg_control.h:133
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3814
uint64 XLogSegNo
Definition: xlogdefs.h:41
#define CHECKPOINT_END_OF_RECOVERY
Definition: xlog.h:212
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define InvalidTransactionId
Definition: transam.h:31
uint64 CurrBytePos
Definition: xlog.c:542
unsigned int uint32
Definition: c.h:358
XLogRecPtr RedoRecPtr
Definition: xlog.c:595
int ckpt_segs_removed
Definition: xlog.h:244
#define CHECKPOINT_FORCE
Definition: xlog.h:215
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:728
#define ereport(elevel, rest)
Definition: elog.h:141
TransactionId oldestCommitTsXid
Definition: transam.h:176
static void Insert(File file)
Definition: fd.c:1061
int ckpt_bufs_written
Definition: xlog.h:241
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8010
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:9286
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
Oid oldestMultiDB
Definition: pg_control.h:50
FullTransactionId ckptFullXid
Definition: xlog.c:596
#define XLogStandbyInfoActive()
Definition: xlog.h:195
static ControlFileData * ControlFile
Definition: xlog.c:722
TimeLineID ThisTimeLineID
Definition: xlog.c:187
Oid nextOid
Definition: pg_control.h:44
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr RedoRecPtr, XLogRecPtr endptr)
Definition: xlog.c:3944
bool fullPageWrites
Definition: pg_control.h:42
TransactionId GetOldestXmin(Relation rel, int flags)
Definition: procarray.c:1307
uint64 XLogRecPtr
Definition: xlogdefs.h:21
FullTransactionId nextFullXid
Definition: pg_control.h:43
Oid oldestXidDB
Definition: pg_control.h:48
TransactionId newestCommitTsXid
Definition: transam.h:177
CheckpointStatsData CheckpointStats
Definition: xlog.c:181
#define SizeOfXLogShortPHD
Definition: xlog_internal.h:55
MultiXactId nextMulti
Definition: pg_control.h:45
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1662
static XLogCtlData * XLogCtl
Definition: xlog.c:714
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1122
int ckpt_segs_added
Definition: xlog.h:243
slock_t ulsn_lck
Definition: xlog.c:604
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
void SyncPostCheckpoint(void)
Definition: sync.c:174
TransactionId GetOldestActiveTransactionId(void)
Definition: procarray.c:2111
int NBuffers
Definition: globals.c:131
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids)
Definition: procarray.c:2318
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr RedoRecPtr
Definition: xlog.c:564
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:37
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8331
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:211
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
void SyncPreCheckpoint(void)
Definition: sync.c:159
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ CreateEndOfRecoveryRecord()

static void CreateEndOfRecoveryRecord ( void  )
static

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

8918 {
8919  xl_end_of_recovery xlrec;
8920  XLogRecPtr recptr;
8921 
8922  /* sanity check */
8923  if (!RecoveryInProgress())
8924  elog(ERROR, "can only be used to end recovery");
8925 
8926  xlrec.end_time = GetCurrentTimestamp();
8927 
8932 
8934 
8936 
8937  XLogBeginInsert();
8938  XLogRegisterData((char *) &xlrec, sizeof(xl_end_of_recovery));
8939  recptr = XLogInsert(RM_XLOG_ID, XLOG_END_OF_RECOVERY);
8940 
8941  XLogFlush(recptr);
8942 
8943  /*
8944  * Update the control file so that crash recovery can follow the timeline
8945  * changes to this point.
8946  */
8947  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8948  ControlFile->time = (pg_time_t) time(NULL);
8949  ControlFile->minRecoveryPoint = recptr;
8952  LWLockRelease(ControlFileLock);
8953 
8954  END_CRIT_SECTION();
8955 
8956  LocalXLogInsertAllowed = -1; /* return to "check" state */
8957 }
static int LocalXLogInsertAllowed
Definition: xlog.c:241
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1691
pg_time_t time
Definition: pg_control.h:128
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
TimeLineID PrevTimeLineID
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1591
#define END_CRIT_SECTION()
Definition: miscadmin.h:134
TimeLineID PrevTimeLineID
Definition: xlog.c:644
#define START_CRIT_SECTION()
Definition: miscadmin.h:132
bool RecoveryInProgress(void)
Definition: xlog.c:7884
#define XLOG_END_OF_RECOVERY
Definition: pg_control.h:76
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2799
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1726
void UpdateControlFile(void)
Definition: xlog.c:4794
#define ERROR
Definition: elog.h:43
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8010
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:722
TimeLineID ThisTimeLineID
Definition: xlog.c:187
TimestampTz end_time
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1662
static XLogCtlData * XLogCtl
Definition: xlog.c:714
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1122
TimeLineID ThisTimeLineID
#define elog(elevel,...)
Definition: elog.h:226
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166

◆ CreateRestartPoint()

bool CreateRestartPoint ( int  flags)

Definition at line 9036 of file xlog.c.

References archiveCleanupCommand, ControlFileData::checkPoint, CHECKPOINT_IS_SHUTDOWN, ControlFileData::checkPointCopy, CheckPointGuts(), CheckpointStatsData::ckpt_start_t, DB_IN_ARCHIVE_RECOVERY, DB_SHUTDOWNED_IN_RECOVERY, DEBUG2, EnableHotStandby, ereport, errdetail(), errmsg(), ExecuteRecoveryCommand(), GetCurrentTimestamp(), GetLatestXTime(), 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().

9037 {
9038  XLogRecPtr lastCheckPointRecPtr;
9039  XLogRecPtr lastCheckPointEndPtr;
9040  CheckPoint lastCheckPoint;
9041  XLogRecPtr PriorRedoPtr;
9042  XLogRecPtr receivePtr;
9043  XLogRecPtr replayPtr;
9044  TimeLineID replayTLI;
9045  XLogRecPtr endptr;
9046  XLogSegNo _logSegNo;
9047  TimestampTz xtime;
9048 
9049  /*
9050  * Acquire CheckpointLock to ensure only one restartpoint or checkpoint
9051  * happens at a time.
9052  */
9053  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
9054 
9055  /* Get a local copy of the last safe checkpoint record. */
9057  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
9058  lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
9059  lastCheckPoint = XLogCtl->lastCheckPoint;
9061 
9062  /*
9063  * Check that we're still in recovery mode. It's ok if we exit recovery
9064  * mode after this check, the restart point is valid anyway.
9065  */
9066  if (!RecoveryInProgress())
9067  {
9068  ereport(DEBUG2,
9069  (errmsg("skipping restartpoint, recovery has already ended")));
9070  LWLockRelease(CheckpointLock);
9071  return false;
9072  }
9073 
9074  /*
9075  * If the last checkpoint record we've replayed is already our last
9076  * restartpoint, we can't perform a new restart point. We still update
9077  * minRecoveryPoint in that case, so that if this is a shutdown restart
9078  * point, we won't start up earlier than before. That's not strictly
9079  * necessary, but when hot standby is enabled, it would be rather weird if
9080  * the database opened up for read-only connections at a point-in-time
9081  * before the last shutdown. Such time travel is still possible in case of
9082  * immediate shutdown, though.
9083  *
9084  * We don't explicitly advance minRecoveryPoint when we do create a
9085  * restartpoint. It's assumed that flushing the buffers will do that as a
9086  * side-effect.
9087  */
9088  if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
9089  lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
9090  {
9091  ereport(DEBUG2,
9092  (errmsg("skipping restartpoint, already performed at %X/%X",
9093  (uint32) (lastCheckPoint.redo >> 32),
9094  (uint32) lastCheckPoint.redo)));
9095 
9097  if (flags & CHECKPOINT_IS_SHUTDOWN)
9098  {
9099  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9101  ControlFile->time = (pg_time_t) time(NULL);
9103  LWLockRelease(ControlFileLock);
9104  }
9105  LWLockRelease(CheckpointLock);
9106  return false;
9107  }
9108 
9109  /*
9110  * Update the shared RedoRecPtr so that the startup process can calculate
9111  * the number of segments replayed since last restartpoint, and request a
9112  * restartpoint if it exceeds CheckPointSegments.
9113  *
9114  * Like in CreateCheckPoint(), hold off insertions to update it, although
9115  * during recovery this is just pro forma, because no WAL insertions are
9116  * happening.
9117  */
9119  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
9121 
9122  /* Also update the info_lck-protected copy */
9124  XLogCtl->RedoRecPtr = lastCheckPoint.redo;
9126 
9127  /*
9128  * Prepare to accumulate statistics.
9129  *
9130  * Note: because it is possible for log_checkpoints to change while a
9131  * checkpoint proceeds, we always accumulate stats, even if
9132  * log_checkpoints is currently off.
9133  */
9134  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
9136 
9137  if (log_checkpoints)
9138  LogCheckpointStart(flags, true);
9139 
9140  CheckPointGuts(lastCheckPoint.redo, flags);
9141 
9142  /*
9143  * Remember the prior checkpoint's redo ptr for
9144  * UpdateCheckPointDistanceEstimate()
9145  */
9146  PriorRedoPtr = ControlFile->checkPointCopy.redo;
9147 
9148  /*
9149  * Update pg_control, using current time. Check that it still shows
9150  * IN_ARCHIVE_RECOVERY state and an older checkpoint, else do nothing;
9151  * this is a quick hack to make sure nothing really bad happens if somehow
9152  * we get here after the end-of-recovery checkpoint.
9153  */
9154  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9156  ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
9157  {
9158  ControlFile->checkPoint = lastCheckPointRecPtr;
9159  ControlFile->checkPointCopy = lastCheckPoint;
9160  ControlFile->time = (pg_time_t) time(NULL);
9161 
9162  /*
9163  * Ensure minRecoveryPoint is past the checkpoint record. Normally,
9164  * this will have happened already while writing out dirty buffers,
9165  * but not necessarily - e.g. because no buffers were dirtied. We do
9166  * this because a non-exclusive base backup uses minRecoveryPoint to
9167  * determine which WAL files must be included in the backup, and the
9168  * file (or files) containing the checkpoint record must be included,
9169  * at a minimum. Note that for an ordinary restart of recovery there's
9170  * no value in having the minimum recovery point any earlier than this
9171  * anyway, because redo will begin just after the checkpoint record.
9172  */
9173  if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
9174  {
9175  ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
9177 
9178  /* update local copy */
9181  }
9182  if (flags & CHECKPOINT_IS_SHUTDOWN)
9185  }
9186  LWLockRelease(ControlFileLock);
9187 
9188  /*
9189  * Update the average distance between checkpoints/restartpoints if the
9190  * prior checkpoint exists.
9191  */
9192  if (PriorRedoPtr != InvalidXLogRecPtr)
9194 
9195  /*
9196  * Delete old log files, those no longer needed for last restartpoint to
9197  * prevent the disk holding the xlog from growing full.
9198  */
9200 
9201  /*
9202  * Retreat _logSegNo using the current end of xlog replayed or received,
9203  * whichever is later.
9204  */
9205  receivePtr = GetWalRcvWriteRecPtr(NULL, NULL);
9206  replayPtr = GetXLogReplayRecPtr(&replayTLI);
9207  endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
9208  KeepLogSeg(endptr, &_logSegNo);
9209  _logSegNo--;
9210 
9211  /*
9212  * Try to recycle segments on a useful timeline. If we've been promoted
9213  * since the beginning of this restartpoint, use the new timeline chosen
9214  * at end of recovery (RecoveryInProgress() sets ThisTimeLineID in that
9215  * case). If we're still in recovery, use the timeline we're currently
9216  * replaying.
9217  *
9218  * There is no guarantee that the WAL segments will be useful on the
9219  * current timeline; if recovery proceeds to a new timeline right after
9220  * this, the pre-allocated WAL segments on this timeline will not be used,
9221  * and will go wasted until recycled on the next restartpoint. We'll live
9222  * with that.
9223  */
9224  if (RecoveryInProgress())
9225  ThisTimeLineID = replayTLI;
9226 
9227  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr);
9228 
9229  /*
9230  * Make more log segments if needed. (Do this after recycling old log
9231  * segments, since that may supply some of the needed files.)
9232  */
9233  PreallocXlogFiles(endptr);
9234 
9235  /*
9236  * ThisTimeLineID is normally not set when we're still in recovery.
9237  * However, recycling/preallocating segments above needed ThisTimeLineID
9238  * to determine which timeline to install the segments on. Reset it now,
9239  * to restore the normal state of affairs for debugging purposes.
9240  */
9241  if (RecoveryInProgress())
9242  ThisTimeLineID = 0;
9243 
9244  /*
9245  * Truncate pg_subtrans if possible. We can throw away all data before
9246  * the oldest XMIN of any running transaction. No future transaction will
9247  * attempt to reference any pg_subtrans entry older than that (see Asserts
9248  * in subtrans.c). When hot standby is disabled, though, we mustn't do
9249  * this because StartupSUBTRANS hasn't been called yet.
9250  */
9251  if (EnableHotStandby)
9253 
9254  /* Real work is done, but log and update before releasing lock. */
9255  LogCheckpointEnd(true);
9256 
9257  xtime = GetLatestXTime();
9259  (errmsg("recovery restart point at %X/%X",
9260  (uint32) (lastCheckPoint.redo >> 32), (uint32) lastCheckPoint.redo),
9261  xtime ? errdetail("Last completed transaction was at log time %s.",
9262  timestamptz_to_str(xtime)) : 0));
9263 
9264  LWLockRelease(CheckpointLock);
9265 
9266  /*
9267  * Finally, execute archive_cleanup_command, if any.
9268  */
9269  if (archiveCleanupCommand && strcmp(archiveCleanupCommand, "") != 0)
9271  "archive_cleanup_command",
9272  false);
9273 
9274  return true;
9275 }
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8434
bool log_checkpoints
Definition: xlog.c:101
void ExecuteRecoveryCommand(const char *command, const char *commandName, bool failOnSignal)
Definition: xlogarchive.c:324
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
uint32 TimeLineID
Definition: xlogdefs.h:52
int64 pg_time_t
Definition: pgtime.h:23
XLogRecPtr GetWalRcvWriteRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI)
static void WALInsertLockRelease(void)
Definition: xlog.c:1691
int wal_segment_size
Definition: xlog.c:112
pg_time_t time
Definition: pg_control.h:128
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1591
int64 TimestampTz
Definition: timestamp.h:39
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition: xlog.c:2712
TimestampTz ckpt_start_t
Definition: xlog.h:235
slock_t info_lck
Definition: xlog.c:711
#define MemSet(start, val, len)
Definition: c.h:941
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:8966
TimestampTz GetLatestXTime(void)
Definition: xlog.c:6050
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:591
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:7884
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:356
XLogRecPtr lastCheckPointRecPtr
Definition: xlog.c:680
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1726
#define SpinLockAcquire(lock)
Definition: spin.h:62
void UpdateControlFile(void)
Definition: xlog.c:4794
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8349
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
Definition: xlog.c:11116
#define DEBUG2
Definition: elog.h:24
static XLogRecPtr RedoRecPtr
Definition: xlog.c:366
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3814
uint64 XLogSegNo
Definition: xlogdefs.h:41
int errdetail(const char *fmt,...)
Definition: elog.c:860
unsigned int uint32
Definition: c.h:358
XLogRecPtr RedoRecPtr
Definition: xlog.c:595
#define ereport(elevel, rest)
Definition: elog.h:141
CheckPoint lastCheckPoint
Definition: xlog.c:682
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
#define SpinLockRelease(lock)
Definition: spin.h:64
static TimeLineID minRecoveryPointTLI
Definition: xlog.c:837
#define PROCARRAY_FLAGS_DEFAULT
Definition: procarray.h:50
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9286
static ControlFileData * ControlFile
Definition: xlog.c:722
TimeLineID ThisTimeLineID
Definition: xlog.c:187
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr RedoRecPtr, XLogRecPtr endptr)
Definition: xlog.c:3944
TransactionId GetOldestXmin(Relation rel, int flags)
Definition: procarray.c:1307
uint64 XLogRecPtr
Definition: xlogdefs.h:21
CheckpointStatsData CheckpointStats
Definition: xlog.c:181
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1662
static XLogCtlData * XLogCtl
Definition: xlog.c:714
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1122
bool EnableHotStandby
Definition: xlog.c:93
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
int errmsg(const char *fmt,...)
Definition: elog.c:784
XLogRecPtr RedoRecPtr
Definition: xlog.c:564
XLogRecPtr lastCheckPointEndPtr
Definition: xlog.c:681
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:37
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8331
char * archiveCleanupCommand
Definition: xlog.c:270
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:211
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:836
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1751
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ DataChecksumsEnabled()

bool DataChecksumsEnabled ( void  )

Definition at line 4823 of file xlog.c.

References Assert, and ControlFileData::data_checksum_version.

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

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

◆ do_pg_abort_backup()

void do_pg_abort_backup ( void  )

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

11089 {
11090  /*
11091  * Quick exit if session is not keeping around a non-exclusive backup
11092  * already started.
11093  */
11095  return;
11096 
11101 
11104  {
11105  XLogCtl->Insert.forcePageWrites = false;
11106  }
11108 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1691
static SessionBackupState sessionBackupState
Definition: xlog.c:526
XLogCtlInsert Insert
Definition: xlog.c:591
bool forcePageWrites
Definition: xlog.c:565
int nonExclusiveBackups
Definition: xlog.c:577
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:576
#define Assert(condition)
Definition: c.h:732
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1662
static XLogCtlData * XLogCtl
Definition: xlog.c:714

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

10168 {
10169  bool exclusive = (labelfile == NULL);
10170  bool backup_started_in_recovery = false;
10171  XLogRecPtr checkpointloc;
10172  XLogRecPtr startpoint;
10173  TimeLineID starttli;
10174  pg_time_t stamp_time;
10175  char strfbuf[128];
10176  char xlogfilename[MAXFNAMELEN];
10177  XLogSegNo _logSegNo;
10178  struct stat stat_buf;
10179  FILE *fp;
10180 
10181  backup_started_in_recovery = RecoveryInProgress();
10182 
10183  /*
10184  * Currently only non-exclusive backup can be taken during recovery.
10185  */
10186  if (backup_started_in_recovery && exclusive)
10187  ereport(ERROR,
10188  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10189  errmsg("recovery is in progress"),
10190  errhint("WAL control functions cannot be executed during recovery.")));
10191 
10192  /*
10193  * During recovery, we don't need to check WAL level. Because, if WAL
10194  * level is not sufficient, it's impossible to get here during recovery.
10195  */
10196  if (!backup_started_in_recovery && !XLogIsNeeded())
10197  ereport(ERROR,
10198  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10199  errmsg("WAL level not sufficient for making an online backup"),
10200  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
10201 
10202  if (strlen(backupidstr) > MAXPGPATH)
10203  ereport(ERROR,
10204  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
10205  errmsg("backup label too long (max %d bytes)",
10206  MAXPGPATH)));
10207 
10208  /*
10209  * Mark backup active in shared memory. We must do full-page WAL writes
10210  * during an on-line backup even if not doing so at other times, because
10211  * it's quite possible for the backup dump to obtain a "torn" (partially
10212  * written) copy of a database page if it reads the page concurrently with
10213  * our write to the same page. This can be fixed as long as the first
10214  * write to the page in the WAL sequence is a full-page write. Hence, we
10215  * turn on forcePageWrites and then force a CHECKPOINT, to ensure there
10216  * are no dirty pages in shared memory that might get dumped while the
10217  * backup is in progress without having a corresponding WAL record. (Once
10218  * the backup is complete, we need not force full-page writes anymore,
10219  * since we expect that any pages not modified during the backup interval
10220  * must have been correctly captured by the backup.)
10221  *
10222  * Note that forcePageWrites has no effect during an online backup from
10223  * the standby.
10224  *
10225  * We must hold all the insertion locks to change the value of
10226  * forcePageWrites, to ensure adequate interlocking against
10227  * XLogInsertRecord().
10228  */
10230  if (exclusive)
10231  {
10232  /*
10233  * At first, mark that we're now starting an exclusive backup, to
10234  * ensure that there are no other sessions currently running
10235  * pg_start_backup() or pg_stop_backup().
10236  */
10238  {
10240  ereport(ERROR,
10241  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10242  errmsg("a backup is already in progress"),
10243  errhint("Run pg_stop_backup() and try again.")));
10244  }
10246  }
10247  else
10249  XLogCtl->Insert.forcePageWrites = true;
10251 
10252  /* Ensure we release forcePageWrites if fail below */
10254  {
10255  bool gotUniqueStartpoint = false;
10256  DIR *tblspcdir;
10257  struct dirent *de;
10258  tablespaceinfo *ti;
10259  int datadirpathlen;
10260 
10261  /*
10262  * Force an XLOG file switch before the checkpoint, to ensure that the
10263  * WAL segment the checkpoint is written to doesn't contain pages with
10264  * old timeline IDs. That would otherwise happen if you called
10265  * pg_start_backup() right after restoring from a PITR archive: the
10266  * first WAL segment containing the startup checkpoint has pages in
10267  * the beginning with the old timeline ID. That can cause trouble at
10268  * recovery: we won't have a history file covering the old timeline if
10269  * pg_wal directory was not included in the base backup and the WAL
10270  * archive was cleared too before starting the backup.
10271  *
10272  * This also ensures that we have emitted a WAL page header that has
10273  * XLP_BKP_REMOVABLE off before we emit the checkpoint record.
10274  * Therefore, if a WAL archiver (such as pglesslog) is trying to
10275  * compress out removable backup blocks, it won't remove any that
10276  * occur after this point.
10277  *
10278  * During recovery, we skip forcing XLOG file switch, which means that
10279  * the backup taken during recovery is not available for the special
10280  * recovery case described above.
10281  */
10282  if (!backup_started_in_recovery)
10283  RequestXLogSwitch(false);
10284 
10285  do
10286  {
10287  bool checkpointfpw;
10288 
10289  /*
10290  * Force a CHECKPOINT. Aside from being necessary to prevent torn
10291  * page problems, this guarantees that two successive backup runs
10292  * will have different checkpoint positions and hence different
10293  * history file names, even if nothing happened in between.
10294  *
10295  * During recovery, establish a restartpoint if possible. We use
10296  * the last restartpoint as the backup starting checkpoint. This
10297  * means that two successive backup runs can have same checkpoint
10298  * positions.
10299  *
10300  * Since the fact that we are executing do_pg_start_backup()
10301  * during recovery means that checkpointer is running, we can use
10302  * RequestCheckpoint() to establish a restartpoint.
10303  *
10304  * We use CHECKPOINT_IMMEDIATE only if requested by user (via
10305  * passing fast = true). Otherwise this can take awhile.
10306  */
10308  (fast ? CHECKPOINT_IMMEDIATE : 0));
10309 
10310  /*
10311  * Now we need to fetch the checkpoint record location, and also
10312  * its REDO pointer. The oldest point in WAL that would be needed
10313  * to restore starting from the checkpoint is precisely the REDO
10314  * pointer.
10315  */
10316  LWLockAcquire(ControlFileLock, LW_SHARED);
10317  checkpointloc = ControlFile->checkPoint;
10318  startpoint = ControlFile->checkPointCopy.redo;
10320  checkpointfpw = ControlFile->checkPointCopy.fullPageWrites;
10321  LWLockRelease(ControlFileLock);
10322 
10323  if (backup_started_in_recovery)
10324  {
10325  XLogRecPtr recptr;
10326 
10327  /*
10328  * Check to see if all WAL replayed during online backup
10329  * (i.e., since last restartpoint used as backup starting
10330  * checkpoint) contain full-page writes.
10331  */
10333  recptr = XLogCtl->lastFpwDisableRecPtr;
10335 
10336  if (!checkpointfpw || startpoint <= recptr)
10337  ereport(ERROR,
10338  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10339  errmsg("WAL generated with full_page_writes=off was replayed "
10340  "since last restartpoint"),
10341  errhint("This means that the backup being taken on the standby "
10342  "is corrupt and should not be used. "
10343  "Enable full_page_writes and run CHECKPOINT on the master, "
10344  "and then try an online backup again.")));
10345 
10346  /*
10347  * During recovery, since we don't use the end-of-backup WAL
10348  * record and don't write the backup history file, the
10349  * starting WAL location doesn't need to be unique. This means
10350  * that two base backups started at the same time might use
10351  * the same checkpoint as starting locations.
10352  */
10353  gotUniqueStartpoint = true;
10354  }
10355 
10356  /*
10357  * If two base backups are started at the same time (in WAL sender
10358  * processes), we need to make sure that they use different
10359  * checkpoints as starting locations, because we use the starting
10360  * WAL location as a unique identifier for the base backup in the
10361  * end-of-backup WAL record and when we write the backup history
10362  * file. Perhaps it would be better generate a separate unique ID
10363  * for each backup instead of forcing another checkpoint, but
10364  * taking a checkpoint right after another is not that expensive
10365  * either because only few buffers have been dirtied yet.
10366  */
10368  if (XLogCtl->Insert.lastBackupStart < startpoint)
10369  {
10370  XLogCtl->Insert.lastBackupStart = startpoint;
10371  gotUniqueStartpoint = true;
10372  }
10374  } while (!gotUniqueStartpoint);
10375 
10376  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
10377  XLogFileName(xlogfilename, starttli, _logSegNo, wal_segment_size);
10378 
10379  /*
10380  * Construct tablespace_map file
10381  */
10382  if (exclusive)
10383  tblspcmapfile = makeStringInfo();
10384 
10385  datadirpathlen = strlen(DataDir);
10386 
10387  /* Collect information about all tablespaces */
10388  tblspcdir = AllocateDir("pg_tblspc");
10389  while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL)
10390  {
10391  char fullpath[MAXPGPATH + 10];
10392  char linkpath[MAXPGPATH];
10393  char *relpath = NULL;
10394  int rllen;
10395  StringInfoData buflinkpath;
10396  char *s = linkpath;
10397 
10398  /* Skip special stuff */
10399  if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
10400  continue;
10401 
10402  snprintf(fullpath, sizeof(fullpath), "pg_tblspc/%s", de->d_name);
10403 
10404 #if defined(HAVE_READLINK) || defined(WIN32)
10405  rllen = readlink(fullpath, linkpath, sizeof(linkpath));
10406  if (rllen < 0)
10407  {
10408  ereport(WARNING,
10409  (errmsg("could not read symbolic link \"%s\": %m",
10410  fullpath)));
10411  continue;
10412  }
10413  else if (rllen >= sizeof(linkpath))
10414  {
10415  ereport(WARNING,
10416  (errmsg("symbolic link \"%s\" target is too long",
10417  fullpath)));
10418  continue;
10419  }
10420  linkpath[rllen] = '\0';
10421 
10422  /*
10423  * Add the escape character '\\' before newline in a string to
10424  * ensure that we can distinguish between the newline in the
10425  * tablespace path and end of line while reading tablespace_map
10426  * file during archive recovery.
10427  */
10428  initStringInfo(&buflinkpath);
10429 
10430  while (*s)
10431  {
10432  if ((*s == '\n' || *s == '\r') && needtblspcmapfile)
10433  appendStringInfoChar(&buflinkpath, '\\');
10434  appendStringInfoChar(&buflinkpath, *s++);
10435  }
10436 
10437  /*
10438  * Relpath holds the relative path of the tablespace directory
10439  * when it's located within PGDATA, or NULL if it's located
10440  * elsewhere.
10441  */
10442  if (rllen > datadirpathlen &&
10443  strncmp(linkpath, DataDir, datadirpathlen) == 0 &&
10444  IS_DIR_SEP(linkpath[datadirpathlen]))
10445  relpath = linkpath + datadirpathlen + 1;
10446 
10447  ti = palloc(sizeof(tablespaceinfo));
10448  ti->oid = pstrdup(de->d_name);
10449  ti->path = pstrdup(buflinkpath.data);
10450  ti->rpath = relpath ? pstrdup(relpath) : NULL;
10451  ti->size = infotbssize ? sendTablespace(fullpath, true) : -1;
10452 
10453  if (tablespaces)
10454  *tablespaces = lappend(*tablespaces, ti);
10455 
10456  appendStringInfo(tblspcmapfile, "%s %s\n", ti->oid, ti->path);
10457 
10458  pfree(buflinkpath.data);
10459 #else
10460 
10461  /*
10462  * If the platform does not have symbolic links, it should not be
10463  * possible to have tablespaces - clearly somebody else created
10464  * them. Warn about it and ignore.
10465  */
10466  ereport(WARNING,
10467  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
10468  errmsg("tablespaces are not supported on this platform")));
10469 #endif
10470  }
10471  FreeDir(tblspcdir);
10472 
10473  /*
10474  * Construct backup label file
10475  */
10476  if (exclusive)
10477  labelfile = makeStringInfo();
10478 
10479  /* Use the log timezone here, not the session timezone */
10480  stamp_time = (pg_time_t) time(NULL);
10481  pg_strftime(strfbuf, sizeof(strfbuf),
10482  "%Y-%m-%d %H:%M:%S %Z",
10483  pg_localtime(&stamp_time, log_timezone));
10484  appendStringInfo(labelfile, "START WAL LOCATION: %X/%X (file %s)\n",
10485  (uint32) (startpoint >> 32), (uint32) startpoint, xlogfilename);
10486  appendStringInfo(labelfile, "CHECKPOINT LOCATION: %X/%X\n",
10487  (uint32) (checkpointloc >> 32), (uint32) checkpointloc);
10488  appendStringInfo(labelfile, "BACKUP METHOD: %s\n",
10489  exclusive ? "pg_start_backup" : "streamed");
10490  appendStringInfo(labelfile, "BACKUP FROM: %s\n",
10491  backup_started_in_recovery ? "standby" : "master");
10492  appendStringInfo(labelfile, "START TIME: %s\n", strfbuf);
10493  appendStringInfo(labelfile, "LABEL: %s\n", backupidstr);
10494  appendStringInfo(labelfile, "START TIMELINE: %u\n", starttli);
10495 
10496  /*
10497  * Okay, write the file, or return its contents to caller.
10498  */
10499  if (exclusive)
10500  {
10501  /*
10502  * Check for existing backup label --- implies a backup is already
10503  * running. (XXX given that we checked exclusiveBackupState
10504  * above, maybe it would be OK to just unlink any such label
10505  * file?)
10506  */
10507  if (stat(BACKUP_LABEL_FILE, &stat_buf) != 0)
10508  {
10509  if (errno != ENOENT)
10510  ereport(ERROR,
10512  errmsg("could not stat file \"%s\": %m",
10513  BACKUP_LABEL_FILE)));
10514  }
10515  else
10516  ereport(ERROR,
10517  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10518  errmsg("a backup is already in progress"),
10519  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
10520  BACKUP_LABEL_FILE)));
10521 
10522  fp = AllocateFile(BACKUP_LABEL_FILE, "w");
10523 
10524  if (!fp)
10525  ereport(ERROR,
10527  errmsg("could not create file \"%s\": %m",
10528  BACKUP_LABEL_FILE)));
10529  if (fwrite(labelfile->data, labelfile->len, 1, fp) != 1 ||
10530  fflush(fp) != 0 ||
10531  pg_fsync(fileno(fp)) != 0 ||
10532  ferror(fp) ||
10533  FreeFile(fp))
10534  ereport(ERROR,
10536  errmsg("could not write file \"%s\": %m",
10537  BACKUP_LABEL_FILE)));
10538  /* Allocated locally for exclusive backups, so free separately */
10539  pfree(labelfile->data);
10540  pfree(labelfile);
10541 
10542  /* Write backup tablespace_map file. */
10543  if (tblspcmapfile->len > 0)
10544  {
10545  if (stat(TABLESPACE_MAP, &stat_buf) != 0)
10546  {
10547  if (errno != ENOENT)
10548  ereport(ERROR,
10550  errmsg("could not stat file \"%s\": %m",
10551  TABLESPACE_MAP)));
10552  }
10553  else
10554  ereport(ERROR,
10555  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10556  errmsg("a backup is already in progress"),
10557  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
10558  TABLESPACE_MAP)));
10559 
10560  fp = AllocateFile(TABLESPACE_MAP, "w");
10561 
10562  if (!fp)
10563  ereport(ERROR,
10565  errmsg("could not create file \"%s\": %m",
10566  TABLESPACE_MAP)));
10567  if (fwrite(tblspcmapfile->data, tblspcmapfile->len, 1, fp) != 1 ||
10568  fflush(fp) != 0 ||
10569  pg_fsync(fileno(fp)) != 0 ||
10570  ferror(fp) ||
10571  FreeFile(fp))
10572  ereport(ERROR,
10574  errmsg("could not write file \"%s\": %m",
10575  TABLESPACE_MAP)));
10576  }
10577 
10578  /* Allocated locally for exclusive backups, so free separately */
10579  pfree(tblspcmapfile->data);
10580  pfree(tblspcmapfile);
10581  }
10582  }
10584 
10585  /*
10586  * Mark that start phase has correctly finished for an exclusive backup.
10587  * Session-level locks are updated as well to reflect that state.
10588  *
10589  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating backup
10590  * counters and session-level lock. Otherwise they can be updated
10591  * inconsistently, and which might cause do_pg_abort_backup() to fail.
10592  */
10593  if (exclusive)
10594  {
10597 
10598  /* Set session-level lock */
10601  }
10602  else
10604 
10605  /*
10606  * We're done. As a convenience, return the starting WAL location.
10607  */
10608  if (starttli_p)
10609  *starttli_p = starttli;
10610  return startpoint;
10611 }
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:9363
int errhint(const char *fmt,...)
Definition: elog.c:974
uint32 TimeLineID
Definition: xlogdefs.h:52
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1691
int wal_segment_size
Definition: xlog.c:112
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:709
static SessionBackupState sessionBackupState
Definition: xlog.c:526
XLogRecPtr lastBackupStart
Definition: xlog.c:578
char * pstrdup(const char *in)
Definition: mcxt.c:1161
#define XLogIsNeeded()
Definition: xlog.h:181
char * rpath
Definition: basebackup.h:28
StringInfo makeStringInfo(void)
Definition: stringinfo.c:28
slock_t info_lck
Definition: xlog.c:711
int errcode(int sqlerrcode)
Definition: elog.c:570
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:591
bool RecoveryInProgress(void)
Definition: xlog.c:7884
static bool backup_started_in_recovery
Definition: basebackup.c:78
Definition: dirent.h:9
#define IS_DIR_SEP(ch)
Definition: port.h:84
pg_tz * log_timezone
Definition: pgtz.c:31
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1726
#define TABLESPACE_MAP
Definition: xlog.h:362
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:47
void pfree(void *pointer)
Definition: mcxt.c:1031
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
bool forcePageWrites
Definition: xlog.c:565
Definition: dirent.c:25
#define ERROR
Definition: elog.h:43
struct stat stat_buf
Definition: pg_standby.c:102
#define MAXPGPATH
uint64 XLogSegNo
Definition: xlogdefs.h:41
#define readlink(path, buf, size)
Definition: win32_port.h:231
int errcode_for_file_access(void)
Definition: elog.c:593
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2211
unsigned int uint32
Definition: c.h:358
int64 sendTablespace(char *path, bool sizeonly)
Definition: basebackup.c:969
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2472
#define CHECKPOINT_FORCE
Definition: xlog.h:215
#define ereport(elevel, rest)
Definition: elog.h:141
List * lappend(List *list, void *datum)
Definition: list.c:128
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:175
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define WARNING
Definition: elog.h:40
int nonExclusiveBackups
Definition: xlog.c:577
#define stat(a, b)
Definition: win32_port.h:264
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
static void pg_start_backup_callback(int code, Datum arg)
Definition: xlog.c:10615
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:576
uintptr_t Datum
Definition: postgres.h:367
static ControlFileData * ControlFile
Definition: xlog.c:722
#define BoolGetDatum(X)
Definition: postgres.h:402
bool fullPageWrites
Definition: pg_control.h:42
#define CHECKPOINT_WAIT
Definition: xlog.h:219
uint64 XLogRecPtr
Definition: xlogdefs.h:21
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2538
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1662
static XLogCtlData * XLogCtl
Definition: xlog.c:714
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1122
#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:52
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1374
int FreeFile(FILE *file)
Definition: fd.c:2410
void * palloc(Size size)
Definition: mcxt.c:924
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:214
#define relpath(rnode, forknum)
Definition: relpath.h:87
char * DataDir
Definition: globals.c:62
#define BACKUP_LABEL_FILE
Definition: xlog.h:359
int pg_fsync(int fd)
Definition: fd.c:333
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:37
int FreeDir(DIR *dir)
Definition: fd.c:2590
void RequestCheckpoint(int flags)
Definition: checkpointer.c:952
#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 10683 of file xlog.c.

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

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

10684 {
10685  bool exclusive = (labelfile == NULL);
10686  bool backup_started_in_recovery = false;
10687  XLogRecPtr startpoint;
10688  XLogRecPtr stoppoint;
10689  TimeLineID stoptli;
10690  pg_time_t stamp_time;
10691  char strfbuf[128];
10692  char histfilepath[MAXPGPATH];
10693  char startxlogfilename[MAXFNAMELEN];
10694  char stopxlogfilename[MAXFNAMELEN];
10695  char lastxlogfilename[MAXFNAMELEN];
10696  char histfilename[MAXFNAMELEN];
10697  char backupfrom[20];
10698  XLogSegNo _logSegNo;
10699  FILE *lfp;
10700  FILE *fp;
10701  char ch;
10702  int seconds_before_warning;
10703  int waits = 0;
10704  bool reported_waiting = false;
10705  char *remaining;
10706  char *ptr;
10707  uint32 hi,
10708  lo;
10709 
10710  backup_started_in_recovery = RecoveryInProgress();
10711 
10712  /*
10713  * Currently only non-exclusive backup can be taken during recovery.
10714  */
10715  if (backup_started_in_recovery && exclusive)
10716  ereport(ERROR,
10717  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10718  errmsg("recovery is in progress"),
10719  errhint("WAL control functions cannot be executed during recovery.")));
10720 
10721  /*
10722  * During recovery, we don't need to check WAL level. Because, if WAL
10723  * level is not sufficient, it's impossible to get here during recovery.
10724  */
10725  if (!backup_started_in_recovery && !XLogIsNeeded())
10726  ereport(ERROR,
10727  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10728  errmsg("WAL level not sufficient for making an online backup"),
10729  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
10730 
10731  if (exclusive)
10732  {
10733  /*
10734  * At first, mark that we're now stopping an exclusive backup, to
10735  * ensure that there are no other sessions currently running
10736  * pg_start_backup() or pg_stop_backup().
10737  */
10740  {
10742  ereport(ERROR,
10743  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10744  errmsg("exclusive backup not in progress")));
10745  }
10748 
10749  /*
10750  * Remove backup_label. In case of failure, the state for an exclusive
10751  * backup is switched back to in-progress.
10752  */
10754  {
10755  /*
10756  * Read the existing label file into memory.
10757  */
10758  struct stat statbuf;
10759  int r;
10760 
10761  if (stat(BACKUP_LABEL_FILE, &statbuf))
10762  {
10763  /* should not happen per the upper checks */
10764  if (errno != ENOENT)
10765  ereport(ERROR,
10767  errmsg("could not stat file \"%s\": %m",
10768  BACKUP_LABEL_FILE)));
10769  ereport(ERROR,
10770  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10771  errmsg("a backup is not in progress")));
10772  }
10773 
10774  lfp = AllocateFile(BACKUP_LABEL_FILE, "r");
10775  if (!lfp)
10776  {
10777  ereport(ERROR,
10779  errmsg("could not read file \"%s\": %m",
10780  BACKUP_LABEL_FILE)));
10781  }
10782  labelfile = palloc(statbuf.st_size + 1);
10783  r = fread(labelfile, statbuf.st_size, 1, lfp);
10784  labelfile[statbuf.st_size] = '\0';
10785 
10786  /*
10787  * Close and remove the backup label file
10788  */
10789  if (r != 1 || ferror(lfp) || FreeFile(lfp))
10790  ereport(ERROR,
10792  errmsg("could not read file \"%s\": %m",
10793  BACKUP_LABEL_FILE)));
10795 
10796  /*
10797  * Remove tablespace_map file if present, it is created only if
10798  * there are tablespaces.
10799  */
10801  }
10803  }
10804 
10805  /*
10806  * OK to update backup counters, forcePageWrites and session-level lock.
10807  *
10808  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating them.
10809  * Otherwise they can be updated inconsistently, and which might cause
10810  * do_pg_abort_backup() to fail.
10811  */
10813  if (exclusive)
10814  {
10816  }
10817  else
10818  {
10819  /*
10820  * The user-visible pg_start/stop_backup() functions that operate on
10821  * exclusive backups can be called at any time, but for non-exclusive
10822  * backups, it is expected that each do_pg_start_backup() call is
10823  * matched by exactly one do_pg_stop_backup() call.
10824  */
10827  }
10828 
10831  {
10832  XLogCtl->Insert.forcePageWrites = false;
10833  }
10834 
10835  /*
10836  * Clean up session-level lock.
10837  *
10838  * You might think that WALInsertLockRelease() can be called before
10839  * cleaning up session-level lock because session-level lock doesn't need
10840  * to be protected with WAL insertion lock. But since
10841  * CHECK_FOR_INTERRUPTS() can occur in it, session-level lock must be
10842  * cleaned up before it.
10843  */
10845 
10847 
10848  /*
10849  * Read and parse the START WAL LOCATION line (this code is pretty crude,
10850  * but we are not expecting any variability in the file format).
10851  */
10852  if (sscanf(labelfile, "START WAL LOCATION: %X/%X (file %24s)%c",
10853  &hi, &lo, startxlogfilename,
10854  &ch) != 4 || ch != '\n')
10855  ereport(ERROR,
10856  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10857  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
10858  startpoint = ((uint64) hi) << 32 | lo;
10859  remaining = strchr(labelfile, '\n') + 1; /* %n is not portable enough */
10860 
10861  /*
10862  * Parse the BACKUP FROM line. If we are taking an online backup from the
10863  * standby, we confirm that the standby has not been promoted during the
10864  * backup.
10865  */
10866  ptr = strstr(remaining, "BACKUP FROM:");
10867  if (!ptr || sscanf(ptr, "BACKUP FROM: %19s\n", backupfrom) != 1)
10868  ereport(ERROR,
10869  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10870  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
10871  if (strcmp(backupfrom, "standby") == 0 && !backup_started_in_recovery)
10872  ereport(ERROR,
10873  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10874  errmsg("the standby was promoted during online backup"),
10875  errhint("This means that the backup being taken is corrupt "
10876  "and should not be used. "
10877  "Try taking another online backup.")));
10878 
10879  /*
10880  * During recovery, we don't write an end-of-backup record. We assume that
10881  * pg_control was backed up last and its minimum recovery point can be
10882  * available as the backup end location. Since we don't have an
10883  * end-of-backup record, we use the pg_control value to check whether
10884  * we've reached the end of backup when starting recovery from this
10885  * backup. We have no way of checking if pg_control wasn't backed up last
10886  * however.
10887  *
10888  * We don't force a switch to new WAL file but it is still possible to
10889  * wait for all the required files to be archived if waitforarchive is
10890  * true. This is okay if we use the backup to start a standby and fetch
10891  * the missing WAL using streaming replication. But in the case of an
10892  * archive recovery, a user should set waitforarchive to true and wait for
10893  * them to be archived to ensure that all the required files are
10894  * available.
10895  *
10896  * We return the current minimum recovery point as the backup end
10897  * location. Note that it can be greater than the exact backup end
10898  * location if the minimum recovery point is updated after the backup of
10899  * pg_control. This is harmless for current uses.
10900  *
10901  * XXX currently a backup history file is for informational and debug
10902  * purposes only. It's not essential for an online backup. Furthermore,
10903  * even if it's created, it will not be archived during recovery because
10904  * an archiver is not invoked. So it doesn't seem worthwhile to write a
10905  * backup history file during recovery.
10906  */
10907  if (backup_started_in_recovery)
10908  {
10909  XLogRecPtr recptr;
10910 
10911  /*
10912  * Check to see if all WAL replayed during online backup contain
10913  * full-page writes.
10914  */
10916  recptr = XLogCtl->lastFpwDisableRecPtr;
10918 
10919  if (startpoint <= recptr)
10920  ereport(ERROR,
10921  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10922  errmsg("WAL generated with full_page_writes=off was replayed "
10923  "during online backup"),
10924  errhint("This means that the backup being taken on the standby "
10925  "is corrupt and should not be used. "
10926  "Enable full_page_writes and run CHECKPOINT on the master, "
10927  "and then try an online backup again.")));
10928 
10929 
10930  LWLockAcquire(ControlFileLock, LW_SHARED);
10931  stoppoint = ControlFile->minRecoveryPoint;
10932  stoptli = ControlFile->minRecoveryPointTLI;
10933  LWLockRelease(ControlFileLock);
10934  }
10935  else
10936  {
10937  /*
10938  * Write the backup-end xlog record
10939  */
10940  XLogBeginInsert();
10941  XLogRegisterData((char *) (&startpoint), sizeof(startpoint));
10942  stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
10943  stoptli = ThisTimeLineID;
10944 
10945  /*
10946  * Force a switch to a new xlog segment file, so that the backup is
10947  * valid as soon as archiver moves out the current segment file.
10948  */
10949  RequestXLogSwitch(false);
10950 
10951  XLByteToPrevSeg(stoppoint, _logSegNo, wal_segment_size);
10952  XLogFileName(stopxlogfilename, stoptli, _logSegNo, wal_segment_size);
10953 
10954  /* Use the log timezone here, not the session timezone */
10955  stamp_time = (pg_time_t) time(NULL);
10956  pg_strftime(strfbuf, sizeof(strfbuf),
10957  "%Y-%m-%d %H:%M:%S %Z",
10958  pg_localtime(&stamp_time, log_timezone));
10959 
10960  /*
10961  * Write the backup history file
10962  */
10963  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
10964  BackupHistoryFilePath(histfilepath, stoptli, _logSegNo,
10965  startpoint, wal_segment_size);
10966  fp = AllocateFile(histfilepath, "w");
10967  if (!fp)
10968  ereport(ERROR,
10970  errmsg("could not create file \"%s\": %m",
10971  histfilepath)));
10972  fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n",
10973  (uint32) (startpoint >> 32), (uint32) startpoint, startxlogfilename);
10974  fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
10975  (uint32) (stoppoint >> 32), (uint32) stoppoint, stopxlogfilename);
10976 
10977  /*
10978  * Transfer remaining lines including label and start timeline to
10979  * history file.
10980  */
10981  fprintf(fp, "%s", remaining);
10982  fprintf(fp, "STOP TIME: %s\n", strfbuf);
10983  fprintf(fp, "STOP TIMELINE: %u\n", stoptli);
10984  if (fflush(fp) || ferror(fp) || FreeFile(fp))
10985  ereport(ERROR,
10987  errmsg("could not write file \"%s\": %m",
10988  histfilepath)));
10989 
10990  /*
10991  * Clean out any no-longer-needed history files. As a side effect,
10992  * this will post a .ready file for the newly created history file,
10993  * notifying the archiver that history file may be archived
10994  * immediately.
10995  */
10997  }
10998 
10999  /*
11000  * If archiving is enabled, wait for all the required WAL files to be
11001  * archived before returning. If archiving isn't enabled, the required WAL
11002  * needs to be transported via streaming replication (hopefully with
11003  * wal_keep_segments set high enough), or some more exotic mechanism like
11004  * polling and copying files from pg_wal with script. We have no knowledge
11005  * of those mechanisms, so it's up to the user to ensure that he gets all
11006  * the required WAL.
11007  *
11008  * We wait until both the last WAL file filled during backup and the
11009  * history file have been archived, and assume that the alphabetic sorting
11010  * property of the WAL files ensures any earlier WAL files are safely
11011  * archived as well.
11012  *
11013  * We wait forever, since archive_command is supposed to work and we
11014  * assume the admin wanted his backup to work completely. If you don't
11015  * wish to wait, then either waitforarchive should be passed in as false,
11016  * or you can set statement_timeout. Also, some notices are issued to
11017  * clue in anyone who might be doing this interactively.
11018  */
11019 
11020  if (waitforarchive &&
11021  ((!backup_started_in_recovery && XLogArchivingActive()) ||
11022  (backup_started_in_recovery && XLogArchivingAlways())))
11023  {
11024  XLByteToPrevSeg(stoppoint, _logSegNo, wal_segment_size);
11025  XLogFileName(lastxlogfilename, stoptli, _logSegNo, wal_segment_size);
11026 
11027  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
11028  BackupHistoryFileName(histfilename, stoptli, _logSegNo,
11029  startpoint, wal_segment_size);
11030 
11031  seconds_before_warning = 60;
11032  waits = 0;
11033 
11034  while (XLogArchiveIsBusy(lastxlogfilename) ||
11035  XLogArchiveIsBusy(histfilename))
11036  {
11038 
11039  if (!reported_waiting && waits > 5)
11040  {
11041  ereport(NOTICE,
11042  (errmsg("base backup done, waiting for required WAL segments to be archived")));
11043  reported_waiting = true;
11044  }
11045 
11046  pg_usleep(1000000L);
11047 
11048  if (++waits >= seconds_before_warning)
11049  {
11050  seconds_before_warning *= 2; /* This wraps in >10 years... */
11051  ereport(WARNING,
11052  (errmsg("still waiting for all required WAL segments to be archived (%d seconds elapsed)",
11053  waits),
11054  errhint("Check that your archive_command is executing properly. "
11055  "You can safely cancel this backup, "
11056  "but the database backup will not be usable without all the WAL segments.")));
11057  }
11058  }
11059 
11060  ereport(NOTICE,
11061  (errmsg("all required WAL segments have been archived")));
11062  }
11063  else if (waitforarchive)
11064  ereport(NOTICE,
11065  (errmsg("WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup")));
11066 
11067  /*
11068  * We're done. As a convenience, return the ending WAL location.
11069  */
11070  if (stoptli_p)
11071  *stoptli_p = stoptli;
11072  return stoppoint;
11073 }
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:9363
#define DEBUG1
Definition: elog.h:25
int errhint(const char *fmt,...)
Definition: elog.c:974
uint32 TimeLineID
Definition: xlogdefs.h:52
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1691
int wal_segment_size
Definition: xlog.c:112
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:709
static SessionBackupState sessionBackupState
Definition: xlog.c:526
#define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes)
#define XLogIsNeeded()
Definition: xlog.h:181
slock_t info_lck
Definition: xlog.c:711
int errcode(int sqlerrcode)
Definition: elog.c:570
XLogCtlInsert Insert
Definition: xlog.c:591
#define BackupHistoryFileName(fname, tli, logSegNo, startpoint, wal_segsz_bytes)
bool RecoveryInProgress(void)
Definition: xlog.c:7884
static bool backup_started_in_recovery
Definition: basebackup.c:78
#define fprintf
Definition: port.h:196
pg_tz * log_timezone
Definition: pgtz.c:31
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1726
#define TABLESPACE_MAP
Definition: xlog.h:362
#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:173
bool forcePageWrites
Definition: xlog.c:565
#define ERROR
Definition: elog.h:43
static void CleanupBackupHistory(void)
Definition: xlog.c:4210
#define MAXPGPATH
uint64 XLogSegNo
Definition: xlogdefs.h:41
int errcode_for_file_access(void)
Definition: elog.c:593
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2211
unsigned int uint32
Definition: c.h:358
#define ereport(elevel, rest)
Definition: elog.h:141
#define XLOG_BACKUP_END
Definition: pg_control.h:72
#define WARNING
Definition: elog.h:40
int nonExclusiveBackups
Definition: xlog.c:577
#define stat(a, b)
Definition: win32_port.h:264
#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:576
uintptr_t Datum
Definition: postgres.h:367
static ControlFileData * ControlFile
Definition: xlog.c:722
#define BoolGetDatum(X)
Definition: postgres.h:402
TimeLineID ThisTimeLineID
Definition: xlog.c:187
#define NOTICE
Definition: elog.h:37
bool XLogArchiveIsBusy(const char *xlog)
Definition: xlogarchive.c:656
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:732
#define XLogArchivingActive()
Definition: xlog.h:170
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1662
static XLogCtlData * XLogCtl
Definition: xlog.c:714
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1122
static void pg_stop_backup_callback(int code, Datum arg)
Definition: xlog.c:10644
#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:52
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1374
int durable_unlink(const char *fname, int elevel)
Definition: fd.c:698
int FreeFile(FILE *file)
Definition: fd.c:2410
void * palloc(Size size)
Definition: mcxt.c:924
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define BACKUP_LABEL_FILE
Definition: xlog.h:359
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ emode_for_corrupt_record()

static int emode_for_corrupt_record ( int  emode,
XLogRecPtr  RecPtr 
)
static

Definition at line 12104 of file xlog.c.

References DEBUG1, LOG, readSource, and XLOG_FROM_PG_WAL.

Referenced by ReadRecord(), and XLogPageRead().

12105 {
12106  static XLogRecPtr lastComplaint = 0;
12107 
12108  if (readSource == XLOG_FROM_PG_WAL && emode == LOG)
12109  {
12110  if (RecPtr == lastComplaint)
12111  emode = DEBUG1;
12112  else
12113  lastComplaint = RecPtr;
12114  }
12115  return emode;
12116 }
#define DEBUG1
Definition: elog.h:25
static XLogSource readSource
Definition: xlog.c:795
#define LOG
Definition: elog.h:26
uint64 XLogRecPtr
Definition: xlogdefs.h:21

◆ exitArchiveRecovery()

static void exitArchiveRecovery ( TimeLineID  endTLI,
XLogRecPtr  endOfLog 
)
static

Definition at line 5451 of file xlog.c.

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

Referenced by StartupXLOG().

5452 {
5453  char recoveryPath[MAXPGPATH];
5454  char xlogfname[MAXFNAMELEN];
5455  XLogSegNo endLogSegNo;
5456  XLogSegNo startLogSegNo;
5457 
5458  /* we always switch to a new timeline after archive recovery */
5459  Assert(endTLI != ThisTimeLineID);
5460 
5461  /*
5462  * We are no longer in archive recovery state.
5463  */
5464  InArchiveRecovery = false;
5465 
5466  /*
5467  * Update min recovery point one last time.
5468  */
5470 
5471  /*
5472  * If the ending log segment is still open, close it (to avoid problems on
5473  * Windows with trying to rename or delete an open file).
5474  */
5475  if (readFile >= 0)
5476  {
5477  close(readFile);
5478  readFile = -1;
5479  }
5480 
5481  /*
5482  * Calculate the last segment on the old timeline, and the first segment
5483  * on the new timeline. If the switch happens in the middle of a segment,
5484  * they are the same, but if the switch happens exactly at a segment
5485  * boundary, startLogSegNo will be endLogSegNo + 1.
5486  */
5487  XLByteToPrevSeg(endOfLog, endLogSegNo, wal_segment_size);
5488  XLByteToSeg(endOfLog, startLogSegNo, wal_segment_size);
5489 
5490  /*
5491  * Initialize the starting WAL segment for the new timeline. If the switch
5492  * happens in the middle of a segment, copy data from the last WAL segment
5493  * of the old timeline up to the switch point, to the starting WAL segment
5494  * on the new timeline.
5495  */
5496  if (endLogSegNo == startLogSegNo)
5497  {
5498  /*
5499  * Make a copy of the file on the new timeline.
5500  *
5501