PostgreSQL Source Code  git master
xlog.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <math.h>
#include <time.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include "access/clog.h"
#include "access/commit_ts.h"
#include "access/multixact.h"
#include "access/rewriteheap.h"
#include "access/subtrans.h"
#include "access/timeline.h"
#include "access/transam.h"
#include "access/tuptoaster.h"
#include "access/twophase.h"
#include "access/xact.h"
#include "access/xlog_internal.h"
#include "access/xloginsert.h"
#include "access/xlogreader.h"
#include "access/xlogutils.h"
#include "catalog/catversion.h"
#include "catalog/pg_control.h"
#include "catalog/pg_database.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "port/atomics.h"
#include "postmaster/bgwriter.h"
#include "postmaster/walwriter.h"
#include "postmaster/startup.h"
#include "replication/basebackup.h"
#include "replication/logical.h"
#include "replication/slot.h"
#include "replication/origin.h"
#include "replication/snapbuild.h"
#include "replication/walreceiver.h"
#include "replication/walsender.h"
#include "storage/bufmgr.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/large_object.h"
#include "storage/latch.h"
#include "storage/pmsignal.h"
#include "storage/predicate.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/reinit.h"
#include "storage/smgr.h"
#include "storage/spin.h"
#include "utils/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 GetNextXidAndEpoch (TransactionId *xid, uint32 *epoch)
 
void ShutdownXLOG (int code, Datum arg)
 
static void LogCheckpointStart (int flags, bool restartpoint)
 
static void LogCheckpointEnd (bool restartpoint)
 
static void UpdateCheckPointDistanceEstimate (uint64 nbytes)
 
void CreateCheckPoint (int flags)
 
static void RecoveryRestartPoint (const CheckPoint *checkPoint)
 
bool CreateRestartPoint (int flags)
 
void XLogPutNextOid (Oid nextOid)
 
XLogRecPtr RequestXLogSwitch (bool mark_unimportant)
 
XLogRecPtr XLogRestorePoint (const char *rpName)
 
void UpdateFullPageWrites (void)
 
void xlog_redo (XLogReaderState *record)
 
void assign_xlog_sync_method (int new_sync_method, void *extra)
 
void issue_xlog_fsync (int fd, XLogSegNo segno)
 
char * XLogFileNameP (TimeLineID tli, XLogSegNo segno)
 
XLogRecPtr do_pg_start_backup (const char *backupidstr, bool fast, TimeLineID *starttli_p, StringInfo labelfile, List **tablespaces, StringInfo tblspcmapfile, bool infotbssize, bool needtblspcmapfile)
 
SessionBackupState get_backup_status (void)
 
XLogRecPtr do_pg_stop_backup (char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 
void do_pg_abort_backup (void)
 
XLogRecPtr GetXLogReplayRecPtr (TimeLineID *replayTLI)
 
XLogRecPtr GetXLogInsertRecPtr (void)
 
XLogRecPtr GetXLogWriteRecPtr (void)
 
void GetOldestRestartPoint (XLogRecPtr *oldrecptr, TimeLineID *oldtli)
 
bool BackupInProgress (void)
 
void CancelBackup (void)
 
void RemovePromoteSignalFiles (void)
 
bool CheckPromoteSignal (void)
 
void WakeupRecovery (void)
 
void SetWalWriterSleeping (bool sleeping)
 
void XLogRequestWalReceiverReply (void)
 

Variables

uint32 bootstrap_data_checksum_version
 
int max_wal_size_mb = 1024
 
int min_wal_size_mb = 80
 
int wal_keep_segments = 0
 
int XLOGbuffers = -1
 
int XLogArchiveTimeout = 0
 
int XLogArchiveMode = ARCHIVE_MODE_OFF
 
char * XLogArchiveCommand = NULL
 
bool EnableHotStandby = false
 
bool fullPageWrites = true
 
bool wal_log_hints = false
 
bool wal_compression = false
 
char * wal_consistency_checking_string = NULL
 
boolwal_consistency_checking = NULL
 
bool log_checkpoints = false
 
int sync_method = DEFAULT_SYNC_METHOD
 
int wal_level = WAL_LEVEL_MINIMAL
 
int CommitDelay = 0
 
int CommitSiblings = 5
 
int wal_retrieve_retry_interval = 5000
 
int wal_segment_size = DEFAULT_XLOG_SEG_SIZE
 
int CheckPointSegments
 
static double CheckPointDistanceEstimate = 0
 
static double PrevCheckPointDistance = 0
 
const struct config_enum_entry sync_method_options []
 
const struct config_enum_entry archive_mode_options []
 
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
 
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 uint32 openLogOff = 0
 
static int readFile = -1
 
static XLogSegNo readSegNo = 0
 
static uint32 readOff = 0
 
static uint32 readLen = 0
 
static XLogSource readSource = 0
 
static XLogSource currentSource = 0
 
static bool lastSourceFailed = false
 
static TimestampTz XLogReceiptTime = 0
 
static XLogSource XLogReceiptSource = 0
 
static XLogRecPtr ReadRecPtr
 
static XLogRecPtr EndRecPtr
 
static XLogRecPtr minRecoveryPoint
 
static TimeLineID minRecoveryPointTLI
 
static bool updateMinRecoveryPoint = true
 
bool reachedConsistency = false
 
static bool InRedo = false
 
static bool bgwriterLaunched = false
 
static int MyLockNo = 0
 
static bool holdingAllLocks = false
 

Macro Definition Documentation

◆ ConvertToXSegs

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

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

Referenced by CopyXLogRecordToWAL(), and CreateCheckPoint().

◆ NextBufIdx

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

Definition at line 729 of file xlog.c.

Referenced by XLogWrite().

◆ NUM_XLOGINSERT_LOCKS

◆ RECOVERY_COMMAND_DONE

#define RECOVERY_COMMAND_DONE   "recovery.done"

Definition at line 81 of file xlog.c.

Referenced by readRecoverySignalFile().

◆ RECOVERY_COMMAND_FILE

#define RECOVERY_COMMAND_FILE   "recovery.conf"

Definition at line 80 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 6120 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 736 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 510 of file xlog.c.

◆ XLogSource

enum XLogSource
Enumerator
XLOG_FROM_ANY 
XLOG_FROM_ARCHIVE 
XLOG_FROM_PG_WAL 
XLOG_FROM_STREAM 

Definition at line 761 of file xlog.c.

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

Function Documentation

◆ AdvanceXLInsertBuffer()

static void AdvanceXLInsertBuffer ( XLogRecPtr  upto,
bool  opportunistic 
)
static

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

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

◆ assign_checkpoint_completion_target()

void assign_checkpoint_completion_target ( double  newval,
void *  extra 
)

Definition at line 2291 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

2292 {
2295 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2255
#define newval
double CheckPointCompletionTarget
Definition: checkpointer.c:147

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2284 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

2285 {
2288 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2255
int max_wal_size_mb
Definition: xlog.c:84
#define newval

◆ assign_xlog_sync_method()

void assign_xlog_sync_method ( int  new_sync_method,
void *  extra 
)

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

10086 {
10087  if (sync_method != new_sync_method)
10088  {
10089  /*
10090  * To ensure that no blocks escape unsynced, force an fsync on the
10091  * currently open log segment (if any). Also, if the open flag is
10092  * changing, close the log file so it will be reopened (with new flag
10093  * bit) at next use.
10094  */
10095  if (openLogFile >= 0)
10096  {
10098  if (pg_fsync(openLogFile) != 0)
10099  ereport(PANIC,
10101  errmsg("could not fsync file \"%s\": %m",
10104  if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
10105  XLogFileClose();
10106  }
10107  }
10108 }
static int get_sync_bit(int method)
Definition: xlog.c:10029
#define PANIC
Definition: elog.h:53
static XLogSegNo openLogSegNo
Definition: xlog.c:779
static void XLogFileClose(void)
Definition: xlog.c:3758
char * XLogFileNameP(TimeLineID tli, XLogSegNo segno)
Definition: xlog.c:10163
int errcode_for_file_access(void)
Definition: elog.c:593
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1262
#define ereport(elevel, rest)
Definition: elog.h:141
static int openLogFile
Definition: xlog.c:778
TimeLineID ThisTimeLineID
Definition: xlog.c:183
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1238
int sync_method
Definition: xlog.c:98
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 11459 of file xlog.c.

References BACKUP_LABEL_FILE, and stat.

Referenced by pg_is_in_backup(), and PostmasterStateMachine().

11460 {
11461  struct stat stat_buf;
11462 
11463  return (stat(BACKUP_LABEL_FILE, &stat_buf) == 0);
11464 }
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:357

◆ BootStrapXLOG()

void BootStrapXLOG ( void  )

Definition at line 5097 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, CheckPoint::fullPageWrites, fullPageWrites, gettimeofday(), INIT_CRC32C, InvalidTransactionId, max_locks_per_xact, ControlFileData::max_locks_per_xact, max_prepared_xacts, ControlFileData::max_prepared_xacts, max_worker_processes, ControlFileData::max_worker_processes, MaxConnections, ControlFileData::MaxConnections, MOCK_AUTH_NONCE_LEN, ControlFileData::mock_authentication_nonce, MultiXactSetNextMXact(), CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, VariableCacheData::nextOid, CheckPoint::nextXid, VariableCacheData::nextXid, CheckPoint::nextXidEpoch, offsetof, VariableCacheData::oidCount, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, openLogFile, palloc(), PANIC, pfree(), pg_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().

5098 {
5099  CheckPoint checkPoint;
5100  char *buffer;
5101  XLogPageHeader page;
5102  XLogLongPageHeader longpage;
5103  XLogRecord *record;
5104  char *recptr;
5105  bool use_existent;
5106  uint64 sysidentifier;
5107  char mock_auth_nonce[MOCK_AUTH_NONCE_LEN];
5108  struct timeval tv;
5109  pg_crc32c crc;
5110 
5111  /*
5112  * Select a hopefully-unique system identifier code for this installation.
5113  * We use the result of gettimeofday(), including the fractional seconds
5114  * field, as being about as unique as we can easily get. (Think not to
5115  * use random(), since it hasn't been seeded and there's no portable way
5116  * to seed it other than the system clock value...) The upper half of the
5117  * uint64 value is just the tv_sec part, while the lower half contains the
5118  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
5119  * PID for a little extra uniqueness. A person knowing this encoding can
5120  * determine the initialization time of the installation, which could
5121  * perhaps be useful sometimes.
5122  */
5123  gettimeofday(&tv, NULL);
5124  sysidentifier = ((uint64) tv.tv_sec) << 32;
5125  sysidentifier |= ((uint64) tv.tv_usec) << 12;
5126  sysidentifier |= getpid() & 0xFFF;
5127 
5128  /*
5129  * Generate a random nonce. This is used for authentication requests that
5130  * will fail because the user does not exist. The nonce is used to create
5131  * a genuine-looking password challenge for the non-existent user, in lieu
5132  * of an actual stored password.
5133  */
5134  if (!pg_strong_random(mock_auth_nonce, MOCK_AUTH_NONCE_LEN))
5135  ereport(PANIC,
5136  (errcode(ERRCODE_INTERNAL_ERROR),
5137  errmsg("could not generate secret authorization token")));
5138 
5139  /* First timeline ID is always 1 */
5140  ThisTimeLineID = 1;
5141 
5142  /* page buffer must be aligned suitably for O_DIRECT */
5143  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
5144  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
5145  memset(page, 0, XLOG_BLCKSZ);
5146 
5147  /*
5148  * Set up information for the initial checkpoint record
5149  *
5150  * The initial checkpoint record is written to the beginning of the WAL
5151  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5152  * used, so that we can use 0/0 to mean "before any valid WAL segment".
5153  */
5154  checkPoint.redo = wal_segment_size + SizeOfXLogLongPHD;
5155  checkPoint.ThisTimeLineID = ThisTimeLineID;
5156  checkPoint.PrevTimeLineID = ThisTimeLineID;
5157  checkPoint.fullPageWrites = fullPageWrites;
5158  checkPoint.nextXidEpoch = 0;
5159  checkPoint.nextXid = FirstNormalTransactionId;
5160  checkPoint.nextOid = FirstBootstrapObjectId;
5161  checkPoint.nextMulti = FirstMultiXactId;
5162  checkPoint.nextMultiOffset = 0;
5163  checkPoint.oldestXid = FirstNormalTransactionId;
5164  checkPoint.oldestXidDB = TemplateDbOid;
5165  checkPoint.oldestMulti = FirstMultiXactId;
5166  checkPoint.oldestMultiDB = TemplateDbOid;
5169  checkPoint.time = (pg_time_t) time(NULL);
5171 
5172  ShmemVariableCache->nextXid = checkPoint.nextXid;
5173  ShmemVariableCache->nextOid = checkPoint.nextOid;
5175  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5176  AdvanceOldestClogXid(checkPoint.oldestXid);
5177  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5178  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5180 
5181  /* Set up the XLOG page header */
5182  page->xlp_magic = XLOG_PAGE_MAGIC;
5183  page->xlp_info = XLP_LONG_HEADER;
5184  page->xlp_tli = ThisTimeLineID;
5186  longpage = (XLogLongPageHeader) page;
5187  longpage->xlp_sysid = sysidentifier;
5188  longpage->xlp_seg_size = wal_segment_size;
5189  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5190 
5191  /* Insert the initial checkpoint record */
5192  recptr = ((char *) page + SizeOfXLogLongPHD);
5193  record = (XLogRecord *) recptr;
5194  record->xl_prev = 0;
5195  record->xl_xid = InvalidTransactionId;
5196  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5198  record->xl_rmid = RM_XLOG_ID;
5199  recptr += SizeOfXLogRecord;
5200  /* fill the XLogRecordDataHeaderShort struct */
5201  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5202  *(recptr++) = sizeof(checkPoint);
5203  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5204  recptr += sizeof(checkPoint);
5205  Assert(recptr - (char *) record == record->xl_tot_len);
5206 
5207  INIT_CRC32C(crc);
5208  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5209  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5210  FIN_CRC32C(crc);
5211  record->xl_crc = crc;
5212 
5213  /* Create first XLOG segment file */
5214  use_existent = false;
5215  openLogFile = XLogFileInit(1, &use_existent, false);
5216 
5217  /* Write the first page with the initial record */
5218  errno = 0;
5220  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5221  {
5222  /* if write didn't set errno, assume problem is no disk space */
5223  if (errno == 0)
5224  errno = ENOSPC;
5225  ereport(PANIC,
5227  errmsg("could not write bootstrap write-ahead log file: %m")));
5228  }
5230 
5232  if (pg_fsync(openLogFile) != 0)
5233  ereport(PANIC,
5235  errmsg("could not fsync bootstrap write-ahead log file: %m")));
5237 
5238  if (close(openLogFile))
5239  ereport(PANIC,
5241  errmsg("could not close bootstrap write-ahead log file: %m")));
5242 
5243  openLogFile = -1;
5244 
5245  /* Now create pg_control */
5246 
5247  memset(ControlFile, 0, sizeof(ControlFileData));
5248  /* Initialize pg_control status fields */
5249  ControlFile->system_identifier = sysidentifier;
5250  memcpy(ControlFile->mock_authentication_nonce, mock_auth_nonce, MOCK_AUTH_NONCE_LEN);
5252  ControlFile->time = checkPoint.time;
5253  ControlFile->checkPoint = checkPoint.redo;
5254  ControlFile->checkPointCopy = checkPoint;
5255  ControlFile->unloggedLSN = 1;
5256 
5257  /* Set important parameter values for use when replaying WAL */
5266 
5267  /* some additional ControlFile fields are set in WriteControlFile() */
5268 
5269  WriteControlFile();
5270 
5271  /* Bootstrap the commit log, too */
5272  BootStrapCLOG();
5276 
5277  pfree(buffer);
5278 
5279  /*
5280  * Force control file to be read - in contrast to normal processing we'd
5281  * otherwise never run the checks and GUC related initializations therein.
5282  */
5283  ReadControlFile();
5284 }
static void WriteControlFile(void)
Definition: xlog.c:4458
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
int max_locks_per_xact
Definition: pg_control.h:181
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:105
int max_prepared_xacts
Definition: pg_control.h:180
int64 pg_time_t
Definition: pgtime.h:23
int wal_segment_size
Definition: xlog.c:108
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:116
#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:99
int XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
Definition: xlog.c:3210
void BootStrapMultiXact(void)
Definition: multixact.c:1866
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: pg_control.h:39
int errcode(int sqlerrcode)
Definition: elog.c:570
RmgrId xl_rmid
Definition: xlogrecord.h:47
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:57
CheckPoint checkPointCopy
Definition: pg_control.h:131
TransactionId oldestXid
Definition: pg_control.h:47
TransactionId nextXid
Definition: pg_control.h:43
pg_time_t time
Definition: pg_control.h:51
#define PANIC
Definition: elog.h:53
uint32 bootstrap_data_checksum_version
Definition: bootstrap.c:53
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:74
#define MOCK_AUTH_NONCE_LEN
Definition: pg_control.h:27
bool fullPageWrites
Definition: xlog.c:92
void BootStrapSUBTRANS(void)
Definition: subtrans.c:212
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid)
Definition: varsup.c:263
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
void pfree(void *pointer)
Definition: mcxt.c:1031
#define FirstNormalTransactionId
Definition: transam.h:34
int max_prepared_xacts
Definition: twophase.c:117
uint64 system_identifier
Definition: pg_control.h:106
uint32 xl_tot_len
Definition: xlogrecord.h:43
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
TransactionId nextXid
Definition: transam.h:121
static void ReadControlFile(void)
Definition: xlog.c:4550
uint32 nextXidEpoch
Definition: pg_control.h:42
bool track_commit_timestamp
Definition: commit_ts.c:103
uint32 data_checksum_version
Definition: pg_control.h:221
#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:97
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1262
#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
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
#define SizeOfXLogRecord
Definition: xlogrecord.h:55
TransactionId newestCommitTsXid
Definition: pg_control.h:54
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition: pg_control.h:228
int MaxConnections
Definition: globals.c:132
Oid oldestMultiDB
Definition: pg_control.h:50
static int openLogFile
Definition: xlog.c:778
static ControlFileData * ControlFile
Definition: xlog.c:719
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
Definition: multixact.c:2194
TimeLineID ThisTimeLineID
Definition: xlog.c:183
Oid nextOid
Definition: pg_control.h:44
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:678
bool fullPageWrites
Definition: pg_control.h:41
bool wal_log_hints
Definition: xlog.c:93
void BootStrapCLOG(void)
Definition: clog.c:712
bool pg_strong_random(void *buf, size_t len)
bool track_commit_timestamp
Definition: pg_control.h:182
#define Assert(condition)
Definition: c.h:732
#define XLP_LONG_HEADER
Definition: xlog_internal.h:79
Oid oldestXidDB
Definition: pg_control.h:48
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1238
void SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid)
Definition: varsup.c:280
uint8 xl_info
Definition: xlogrecord.h:46
MultiXactId nextMulti
Definition: pg_control.h:45
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:223
TransactionId xl_xid
Definition: xlogrecord.h:44
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
void * palloc(Size size)
Definition: mcxt.c:924
int errmsg(const char *fmt,...)
Definition: elog.c: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:36
#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 2255 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().

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

◆ CancelBackup()

void CancelBackup ( void  )

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

11480 {
11481  struct stat stat_buf;
11482 
11483  /* if the backup_label file is not there, return */
11484  if (stat(BACKUP_LABEL_FILE, &stat_buf) < 0)
11485  return;
11486 
11487  /* remove leftover file from previously canceled backup if it exists */
11488  unlink(BACKUP_LABEL_OLD);
11489 
11491  {
11492  ereport(WARNING,
11494  errmsg("online backup mode was not canceled"),
11495  errdetail("File \"%s\" could not be renamed to \"%s\": %m.",
11497  return;
11498  }
11499 
11500  /* if the tablespace_map file is not there, return */
11501  if (stat(TABLESPACE_MAP, &stat_buf) < 0)
11502  {
11503  ereport(LOG,
11504  (errmsg("online backup mode canceled"),
11505  errdetail("File \"%s\" was renamed to \"%s\".",
11507  return;
11508  }
11509 
11510  /* remove leftover file from previously canceled backup if it exists */
11511  unlink(TABLESPACE_MAP_OLD);
11512 
11514  {
11515  ereport(LOG,
11516  (errmsg("online backup mode canceled"),
11517  errdetail("Files \"%s\" and \"%s\" were renamed to "
11518  "\"%s\" and \"%s\", respectively.",
11521  }
11522  else
11523  {
11524  ereport(WARNING,
11526  errmsg("online backup mode canceled"),
11527  errdetail("File \"%s\" was renamed to \"%s\", but "
11528  "file \"%s\" could not be renamed to \"%s\": %m.",
11531  }
11532 }
#define DEBUG1
Definition: elog.h:25
#define LOG
Definition: elog.h:26
#define BACKUP_LABEL_OLD
Definition: xlog.h:358
#define TABLESPACE_MAP
Definition: xlog.h:360
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:589
#define WARNING
Definition: elog.h:40
#define stat(a, b)
Definition: win32_port.h:264
#define TABLESPACE_MAP_OLD
Definition: xlog.h:361
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define BACKUP_LABEL_FILE
Definition: xlog.h:357

◆ check_wal_buffers()

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

Definition at line 4888 of file xlog.c.

References XLOGbuffers, and XLOGChooseNumBuffers().

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

◆ CheckForStandbyTrigger()

static bool CheckForStandbyTrigger ( void  )
static

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

12170 {
12171  struct stat stat_buf;
12172  static bool triggered = false;
12173 
12174  if (triggered)
12175  return true;
12176 
12177  if (IsPromoteTriggered())
12178  {
12179  /*
12180  * In 9.1 and 9.2 the postmaster unlinked the promote file inside the
12181  * signal handler. It now leaves the file in place and lets the
12182  * Startup process do the unlink. This allows Startup to know whether
12183  * it should create a full checkpoint before starting up (fallback
12184  * mode). Fast promotion takes precedence.
12185  */
12186  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
12187  {
12188  unlink(PROMOTE_SIGNAL_FILE);
12190  fast_promote = true;
12191  }
12192  else if (stat(FALLBACK_PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
12193  {
12195  fast_promote = false;
12196  }
12197 
12198  ereport(LOG, (errmsg("received promote request")));
12199 
12201  triggered = true;
12202  return true;
12203  }
12204 
12205  if (PromoteTriggerFile == NULL || strcmp(PromoteTriggerFile, "") == 0)
12206  return false;
12207 
12208  if (stat(PromoteTriggerFile, &stat_buf) == 0)
12209  {
12210  ereport(LOG,
12211  (errmsg("promote trigger file found: %s", PromoteTriggerFile)));
12212  unlink(PromoteTriggerFile);
12213  triggered = true;
12214  fast_promote = true;
12215  return true;
12216  }
12217  else if (errno != ENOENT)
12218  ereport(ERROR,
12220  errmsg("could not stat promote trigger file \"%s\": %m",
12221  PromoteTriggerFile)));
12222 
12223  return false;
12224 }
char * PromoteTriggerFile
Definition: xlog.c:281
void ResetPromoteTriggered(void)
Definition: startup.c:243
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:364
#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:365
#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:287

◆ CheckPointGuts()

static void CheckPointGuts ( XLogRecPtr  checkPointRedo,
int  flags 
)
static

Definition at line 9017 of file xlog.c.

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

Referenced by CreateCheckPoint(), and CreateRestartPoint().

9018 {
9019  CheckPointCLOG();
9028  CheckPointBuffers(flags); /* performs all required fsyncs */
9030  /* We deliberately delay 2PC checkpointing as long as possible */
9031  CheckPointTwoPhase(checkPointRedo);
9032 }
void CheckPointBuffers(int flags)
Definition: bufmgr.c:2580
void CheckPointLogicalRewriteHeap(void)
Definition: rewriteheap.c:1220
void CheckPointReplicationOrigin(void)
Definition: origin.c:545
void CheckPointSnapBuild(void)
Definition: snapbuild.c:1925
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:300
void CheckPointRelationMap(void)
Definition: relmapper.c:546
void CheckPointPredicate(void)
Definition: predicate.c:997
void CheckPointTwoPhase(XLogRecPtr redo_horizon)
Definition: twophase.c:1735
void CheckPointReplicationSlots(void)
Definition: slot.c:1074

◆ CheckPromoteSignal()

bool CheckPromoteSignal ( void  )

Definition at line 12241 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, PROMOTE_SIGNAL_FILE, and stat.

Referenced by sigusr1_handler().

12242 {
12243  struct stat stat_buf;
12244 
12245  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
12247  return true;
12248 
12249  return false;
12250 }
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:364
struct stat stat_buf
Definition: pg_standby.c:102
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.h:365
#define stat(a, b)
Definition: win32_port.h:264

◆ CheckRecoveryConsistency()

static void CheckRecoveryConsistency ( void  )
static

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

7794 {
7795  XLogRecPtr lastReplayedEndRecPtr;
7796 
7797  /*
7798  * During crash recovery, we don't reach a consistent state until we've
7799  * replayed all the WAL.
7800  */
7802  return;
7803 
7805 
7806  /*
7807  * assume that we are called in the startup process, and hence don't need
7808  * a lock to read lastReplayedEndRecPtr
7809  */
7810  lastReplayedEndRecPtr = XLogCtl->lastReplayedEndRecPtr;
7811 
7812  /*
7813  * Have we reached the point where our base backup was completed?
7814  */
7816  ControlFile->backupEndPoint <= lastReplayedEndRecPtr)
7817  {
7818  /*
7819  * We have reached the end of base backup, as indicated by pg_control.
7820  * The data on disk is now consistent. Reset backupStartPoint and
7821  * backupEndPoint, and update minRecoveryPoint to make sure we don't
7822  * allow starting up at an earlier point even if recovery is stopped
7823  * and restarted soon after this.
7824  */
7825  elog(DEBUG1, "end of backup reached");
7826 
7827  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7828 
7829  if (ControlFile->minRecoveryPoint < lastReplayedEndRecPtr)
7830  ControlFile->minRecoveryPoint = lastReplayedEndRecPtr;
7831 
7834  ControlFile->backupEndRequired = false;
7836 
7837  LWLockRelease(ControlFileLock);
7838  }
7839 
7840  /*
7841  * Have we passed our safe starting point? Note that minRecoveryPoint is
7842  * known to be incorrectly set if ControlFile->backupEndRequired, until
7843  * the XLOG_BACKUP_END arrives to advise us of the correct
7844  * minRecoveryPoint. All we know prior to that is that we're not
7845  * consistent yet.
7846  */
7848  minRecoveryPoint <= lastReplayedEndRecPtr &&
7850  {
7851  /*
7852  * Check to see if the XLOG sequence contained any unresolved
7853  * references to uninitialized pages.
7854  */
7856 
7857  reachedConsistency = true;
7858  ereport(LOG,
7859  (errmsg("consistent recovery state reached at %X/%X",
7860  (uint32) (lastReplayedEndRecPtr >> 32),
7861  (uint32) lastReplayedEndRecPtr)));
7862  }
7863 
7864  /*
7865  * Have we got a valid starting snapshot that will allow queries to be
7866  * run? If so, we can tell postmaster that the database is consistent now,
7867  * enabling connections.
7868  */
7873  {
7877 
7878  LocalHotStandbyActive = true;
7879 
7881  }
7882 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define DEBUG1
Definition: elog.h:25
void XLogCheckInvalidPages(void)
Definition: xlogutils.c:220
bool SharedHotStandbyActive
Definition: xlog.c:653
slock_t info_lck
Definition: xlog.c:708
#define LOG
Definition: elog.h:26
bool InArchiveRecovery
Definition: xlog.c:251
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
bool backupEndRequired
Definition: pg_control.h:170
#define SpinLockAcquire(lock)
Definition: spin.h:62
static bool LocalHotStandbyActive
Definition: xlog.c:225
void UpdateControlFile(void)
Definition: xlog.c:4762
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:719
XLogRecPtr backupEndPoint
Definition: pg_control.h:169
bool reachedConsistency
Definition: xlog.c:844
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:732
static XLogCtlData * XLogCtl
Definition: xlog.c:711
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
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:199
XLogRecPtr backupStartPoint
Definition: pg_control.h:168
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:835
XLogRecPtr lastReplayedEndRecPtr
Definition: xlog.c:687

◆ CheckRequiredParameterValues()

static void CheckRequiredParameterValues ( void  )
static

Definition at line 6142 of file xlog.c.

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

Referenced by StartupXLOG(), and xlog_redo().

6143 {
6144  /*
6145  * For archive recovery, the WAL must be generated with at least 'replica'
6146  * wal_level.
6147  */
6149  {
6150  ereport(WARNING,
6151  (errmsg("WAL was generated with wal_level=minimal, data may be missing"),
6152  errhint("This happens if you temporarily set wal_level=minimal without taking a new base backup.")));
6153  }
6154 
6155  /*
6156  * For Hot Standby, the WAL must be generated with 'replica' mode, and we
6157  * must have at least as many backend slots as the primary.
6158  */
6160  {
6162  ereport(ERROR,
6163  (errmsg("hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server"),
6164  errhint("Either set wal_level to \"replica\" on the master, or turn off hot_standby here.")));
6165 
6166  /* We ignore autovacuum_max_workers when we make this test. */
6167  RecoveryRequiresIntParameter("max_connections",
6170  RecoveryRequiresIntParameter("max_worker_processes",
6173  RecoveryRequiresIntParameter("max_prepared_transactions",
6176  RecoveryRequiresIntParameter("max_locks_per_transaction",
6179  }
6180 }
bool ArchiveRecoveryRequested
Definition: xlog.c:250
int max_locks_per_xact
Definition: pg_control.h:181
int errhint(const char *fmt,...)
Definition: elog.c:974
int max_prepared_xacts
Definition: pg_control.h:180
int max_worker_processes
Definition: pg_control.h:179
#define ERROR
Definition: elog.h:43
int max_prepared_xacts
Definition: twophase.c:117
#define ereport(elevel, rest)
Definition: elog.h:141
int max_locks_per_xact
Definition: lock.c:54
#define WARNING
Definition: elog.h:40
int MaxConnections
Definition: globals.c:132
static ControlFileData * ControlFile
Definition: xlog.c:719
bool EnableHotStandby
Definition: xlog.c:91
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:6120

◆ checkTimeLineSwitch()

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

Definition at line 9579 of file xlog.c.

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

Referenced by StartupXLOG().

9580 {
9581  /* Check that the record agrees on what the current (old) timeline is */
9582  if (prevTLI != ThisTimeLineID)
9583  ereport(PANIC,
9584  (errmsg("unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record",
9585  prevTLI, ThisTimeLineID)));
9586 
9587  /*
9588  * The new timeline better be in the list of timelines we expect to see,
9589  * according to the timeline history. It should also not decrease.
9590  */
9591  if (newTLI < ThisTimeLineID || !tliInHistory(newTLI, expectedTLEs))
9592  ereport(PANIC,
9593  (errmsg("unexpected timeline ID %u (after %u) in checkpoint record",
9594  newTLI, ThisTimeLineID)));
9595 
9596  /*
9597  * If we have not yet reached min recovery point, and we're about to
9598  * switch to a timeline greater than the timeline of the min recovery
9599  * point: trouble. After switching to the new timeline, we could not
9600  * possibly visit the min recovery point on the correct timeline anymore.
9601  * This can happen if there is a newer timeline in the archive that
9602  * branched before the timeline the min recovery point is on, and you
9603  * attempt to do PITR to the new timeline.
9604  */
9606  lsn < minRecoveryPoint &&
9607  newTLI > minRecoveryPointTLI)
9608  ereport(PANIC,
9609  (errmsg("unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u",
9610  newTLI,
9611  (uint32) (minRecoveryPoint >> 32),
9614 
9615  /* Looks good */
9616 }
static List * expectedTLEs
Definition: xlog.c:330
#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:836
TimeLineID ThisTimeLineID
Definition: xlog.c:183
int errmsg(const char *fmt,...)
Definition: elog.c:784
bool tliInHistory(TimeLineID tli, List *expectedTLEs)
Definition: timeline.c:515
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:835

◆ checkXLogConsistency()

static void checkXLogConsistency ( XLogReaderState record)
static

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

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

◆ CheckXLogRemoved()

void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)

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

3826 {
3827  int save_errno = errno;
3828  XLogSegNo lastRemovedSegNo;
3829 
3831  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3833 
3834  if (segno <= lastRemovedSegNo)
3835  {
3836  char filename[MAXFNAMELEN];
3837 
3838  XLogFileName(filename, tli, segno, wal_segment_size);
3839  errno = save_errno;
3840  ereport(ERROR,
3842  errmsg("requested WAL segment %s has already been removed",
3843  filename)));
3844  }
3845  errno = save_errno;
3846 }
int wal_segment_size
Definition: xlog.c:108
slock_t info_lck
Definition: xlog.c:708
XLogSegNo lastRemovedSegNo
Definition: xlog.c:597
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define ERROR
Definition: elog.h:43
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errcode_for_file_access(void)
Definition: elog.c: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:711
static char * filename
Definition: pg_dumpall.c:88
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ CleanupBackupHistory()

static void CleanupBackupHistory ( void  )
static

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

4183 {
4184  DIR *xldir;
4185  struct dirent *xlde;
4186  char path[MAXPGPATH + sizeof(XLOGDIR)];
4187 
4188  xldir = AllocateDir(XLOGDIR);
4189 
4190  while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
4191  {
4192  if (IsBackupHistoryFileName(xlde->d_name))
4193  {
4194  if (XLogArchiveCheckDone(xlde->d_name))
4195  {
4196  elog(DEBUG2, "removing WAL backup history file \"%s\"",
4197  xlde->d_name);
4198  snprintf(path, sizeof(path), XLOGDIR "/%s", xlde->d_name);
4199  unlink(path);
4200  XLogArchiveCleanup(xlde->d_name);
4201  }
4202  }
4203  }
4204 
4205  FreeDir(xldir);
4206 }
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:2446
#define IsBackupHistoryFileName(fname)
#define XLOGDIR
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2512
#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:2564

◆ CopyXLogRecordToWAL()

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

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

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

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

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

8542 {
8543  bool shutdown;
8544  CheckPoint checkPoint;
8545  XLogRecPtr recptr;
8546  XLogSegNo _logSegNo;
8548  uint32 freespace;
8549  XLogRecPtr PriorRedoPtr;
8550  XLogRecPtr curInsert;
8551  XLogRecPtr last_important_lsn;
8552  VirtualTransactionId *vxids;
8553  int nvxids;
8554 
8555  /*
8556  * An end-of-recovery checkpoint is really a shutdown checkpoint, just
8557  * issued at a different time.
8558  */
8560  shutdown = true;
8561  else
8562  shutdown = false;
8563 
8564  /* sanity check */
8565  if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
8566  elog(ERROR, "can't create a checkpoint during recovery");
8567 
8568  /*
8569  * Initialize InitXLogInsert working areas before entering the critical
8570  * section. Normally, this is done by the first call to
8571  * RecoveryInProgress() or LocalSetXLogInsertAllowed(), but when creating
8572  * an end-of-recovery checkpoint, the LocalSetXLogInsertAllowed call is
8573  * done below in a critical section, and InitXLogInsert cannot be called
8574  * in a critical section.
8575  */
8576  InitXLogInsert();
8577 
8578  /*
8579  * Acquire CheckpointLock to ensure only one checkpoint happens at a time.
8580  * (This is just pro forma, since in the present system structure there is
8581  * only one process that is allowed to issue checkpoints at any given
8582  * time.)
8583  */
8584  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
8585 
8586  /*
8587  * Prepare to accumulate statistics.
8588  *
8589  * Note: because it is possible for log_checkpoints to change while a
8590  * checkpoint proceeds, we always accumulate stats, even if
8591  * log_checkpoints is currently off.
8592  */
8593  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
8595 
8596  /*
8597  * Use a critical section to force system panic if we have trouble.
8598  */
8600 
8601  if (shutdown)
8602  {
8603  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8605  ControlFile->time = (pg_time_t) time(NULL);
8607  LWLockRelease(ControlFileLock);
8608  }
8609 
8610  /*
8611  * Let smgr prepare for checkpoint; this has to happen before we determine
8612  * the REDO pointer. Note that smgr must not do anything that'd have to
8613  * be undone if we decide no checkpoint is needed.
8614  */
8615  smgrpreckpt();
8616 
8617  /* Begin filling in the checkpoint WAL record */
8618  MemSet(&checkPoint, 0, sizeof(checkPoint));
8619  checkPoint.time = (pg_time_t) time(NULL);
8620 
8621  /*
8622  * For Hot Standby, derive the oldestActiveXid before we fix the redo
8623  * pointer. This allows us to begin accumulating changes to assemble our
8624  * starting snapshot of locks and transactions.
8625  */
8626  if (!shutdown && XLogStandbyInfoActive())
8628  else
8630 
8631  /*
8632  * Get location of last important record before acquiring insert locks (as
8633  * GetLastImportantRecPtr() also locks WAL locks).
8634  */
8635  last_important_lsn = GetLastImportantRecPtr();
8636 
8637  /*
8638  * We must block concurrent insertions while examining insert state to
8639  * determine the checkpoint REDO pointer.
8640  */
8642  curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
8643 
8644  /*
8645  * If this isn't a shutdown or forced checkpoint, and if there has been no
8646  * WAL activity requiring a checkpoint, skip it. The idea here is to
8647  * avoid inserting duplicate checkpoints when the system is idle.
8648  */
8649  if ((flags & (CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_END_OF_RECOVERY |
8650  CHECKPOINT_FORCE)) == 0)
8651  {
8652  if (last_important_lsn == ControlFile->checkPoint)
8653  {
8655  LWLockRelease(CheckpointLock);
8656  END_CRIT_SECTION();
8657  ereport(DEBUG1,
8658  (errmsg("checkpoint skipped because system is idle")));
8659  return;
8660  }
8661  }
8662 
8663  /*
8664  * An end-of-recovery checkpoint is created before anyone is allowed to
8665  * write WAL. To allow us to write the checkpoint record, temporarily
8666  * enable XLogInsertAllowed. (This also ensures ThisTimeLineID is
8667  * initialized, which we need here and in AdvanceXLInsertBuffer.)
8668  */
8669  if (flags & CHECKPOINT_END_OF_RECOVERY)
8671 
8672  checkPoint.ThisTimeLineID = ThisTimeLineID;
8673  if (flags & CHECKPOINT_END_OF_RECOVERY)
8674  checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
8675  else
8676  checkPoint.PrevTimeLineID = ThisTimeLineID;
8677 
8678  checkPoint.fullPageWrites = Insert->fullPageWrites;
8679 
8680  /*
8681  * Compute new REDO record ptr = location of next XLOG record.
8682  *
8683  * NB: this is NOT necessarily where the checkpoint record itself will be,
8684  * since other backends may insert more XLOG records while we're off doing
8685  * the buffer flush work. Those XLOG records are logically after the
8686  * checkpoint, even though physically before it. Got that?
8687  */
8688  freespace = INSERT_FREESPACE(curInsert);
8689  if (freespace == 0)
8690  {
8691  if (XLogSegmentOffset(curInsert, wal_segment_size) == 0)
8692  curInsert += SizeOfXLogLongPHD;
8693  else
8694  curInsert += SizeOfXLogShortPHD;
8695  }
8696  checkPoint.redo = curInsert;
8697 
8698  /*
8699  * Here we update the shared RedoRecPtr for future XLogInsert calls; this
8700  * must be done while holding all the insertion locks.
8701  *
8702  * Note: if we fail to complete the checkpoint, RedoRecPtr will be left
8703  * pointing past where it really needs to point. This is okay; the only
8704  * consequence is that XLogInsert might back up whole buffers that it
8705  * didn't really need to. We can't postpone advancing RedoRecPtr because
8706  * XLogInserts that happen while we are dumping buffers must assume that
8707  * their buffer changes are not included in the checkpoint.
8708  */
8709  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
8710 
8711  /*
8712  * Now we can release the WAL insertion locks, allowing other xacts to
8713  * proceed while we are flushing disk buffers.
8714  */
8716 
8717  /* Update the info_lck-protected copy of RedoRecPtr as well */
8719  XLogCtl->RedoRecPtr = checkPoint.redo;
8721 
8722  /*
8723  * If enabled, log checkpoint start. We postpone this until now so as not
8724  * to log anything if we decided to skip the checkpoint.
8725  */
8726  if (log_checkpoints)
8727  LogCheckpointStart(flags, false);
8728 
8729  TRACE_POSTGRESQL_CHECKPOINT_START(flags);
8730 
8731  /*
8732  * Get the other info we need for the checkpoint record.
8733  *
8734  * We don't need to save oldestClogXid in the checkpoint, it only matters
8735  * for the short period in which clog is being truncated, and if we crash
8736  * during that we'll redo the clog truncation and fix up oldestClogXid
8737  * there.
8738  */
8739  LWLockAcquire(XidGenLock, LW_SHARED);
8740  checkPoint.nextXid = ShmemVariableCache->nextXid;
8741  checkPoint.oldestXid = ShmemVariableCache->oldestXid;
8743  LWLockRelease(XidGenLock);
8744 
8745  LWLockAcquire(CommitTsLock, LW_SHARED);
8748  LWLockRelease(CommitTsLock);
8749 
8750  /* Increase XID epoch if we've wrapped around since last checkpoint */
8752  if (checkPoint.nextXid < ControlFile->checkPointCopy.nextXid)
8753  checkPoint.nextXidEpoch++;
8754 
8755  LWLockAcquire(OidGenLock, LW_SHARED);
8756  checkPoint.nextOid = ShmemVariableCache->nextOid;
8757  if (!shutdown)
8758  checkPoint.nextOid += ShmemVariableCache->oidCount;
8759  LWLockRelease(OidGenLock);
8760 
8761  MultiXactGetCheckptMulti(shutdown,
8762  &checkPoint.nextMulti,
8763  &checkPoint.nextMultiOffset,
8764  &checkPoint.oldestMulti,
8765  &checkPoint.oldestMultiDB);
8766 
8767  /*
8768  * Having constructed the checkpoint record, ensure all shmem disk buffers
8769  * and commit-log buffers are flushed to disk.
8770  *
8771  * This I/O could fail for various reasons. If so, we will fail to
8772  * complete the checkpoint, but there is no reason to force a system
8773  * panic. Accordingly, exit critical section while doing it.
8774  */
8775  END_CRIT_SECTION();
8776 
8777  /*
8778  * In some cases there are groups of actions that must all occur on one
8779  * side or the other of a checkpoint record. Before flushing the
8780  * checkpoint record we must explicitly wait for any backend currently
8781  * performing those groups of actions.
8782  *
8783  * One example is end of transaction, so we must wait for any transactions
8784  * that are currently in commit critical sections. If an xact inserted
8785  * its commit record into XLOG just before the REDO point, then a crash
8786  * restart from the REDO point would not replay that record, which means
8787  * that our flushing had better include the xact's update of pg_xact. So
8788  * we wait till he's out of his commit critical section before proceeding.
8789  * See notes in RecordTransactionCommit().
8790  *
8791  * Because we've already released the insertion locks, this test is a bit
8792  * fuzzy: it is possible that we will wait for xacts we didn't really need
8793  * to wait for. But the delay should be short and it seems better to make
8794  * checkpoint take a bit longer than to hold off insertions longer than
8795  * necessary. (In fact, the whole reason we have this issue is that xact.c
8796  * does commit record XLOG insertion and clog update as two separate steps
8797  * protected by different locks, but again that seems best on grounds of
8798  * minimizing lock contention.)
8799  *
8800  * A transaction that has not yet set delayChkpt when we look cannot be at
8801  * risk, since he's not inserted his commit record yet; and one that's
8802  * already cleared it is not at risk either, since he's done fixing clog
8803  * and we will correctly flush the update below. So we cannot miss any
8804  * xacts we need to wait for.
8805  */
8806  vxids = GetVirtualXIDsDelayingChkpt(&nvxids);
8807  if (nvxids > 0)
8808  {
8809  do
8810  {
8811  pg_usleep(10000L); /* wait for 10 msec */
8812  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids));
8813  }
8814  pfree(vxids);
8815 
8816  CheckPointGuts(checkPoint.redo, flags);
8817 
8818  /*
8819  * Take a snapshot of running transactions and write this to WAL. This
8820  * allows us to reconstruct the state of running transactions during
8821  * archive recovery, if required. Skip, if this info disabled.
8822  *
8823  * If we are shutting down, or Startup process is completing crash
8824  * recovery we don't need to write running xact data.
8825  */
8826  if (!shutdown && XLogStandbyInfoActive())
8828 
8830 
8831  /*
8832  * Now insert the checkpoint record into XLOG.
8833  */
8834  XLogBeginInsert();
8835  XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));
8836  recptr = XLogInsert(RM_XLOG_ID,
8837  shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
8839 
8840  XLogFlush(recptr);
8841 
8842  /*
8843  * We mustn't write any new WAL after a shutdown checkpoint, or it will be
8844  * overwritten at next startup. No-one should even try, this just allows
8845  * sanity-checking. In the case of an end-of-recovery checkpoint, we want
8846  * to just temporarily disable writing until the system has exited
8847  * recovery.
8848  */
8849  if (shutdown)
8850  {
8851  if (flags & CHECKPOINT_END_OF_RECOVERY)
8852  LocalXLogInsertAllowed = -1; /* return to "check" state */
8853  else
8854  LocalXLogInsertAllowed = 0; /* never again write WAL */
8855  }
8856 
8857  /*
8858  * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
8859  * = end of actual checkpoint record.
8860  */
8861  if (shutdown && checkPoint.redo != ProcLastRecPtr)
8862  ereport(PANIC,
8863  (errmsg("concurrent write-ahead log activity while database system is shutting down")));
8864 
8865  /*
8866  * Remember the prior checkpoint's redo ptr for
8867  * UpdateCheckPointDistanceEstimate()
8868  */
8869  PriorRedoPtr = ControlFile->checkPointCopy.redo;
8870 
8871  /*
8872  * Update the control file.
8873  */
8874  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8875  if (shutdown)
8878  ControlFile->checkPointCopy = checkPoint;
8879  ControlFile->time = (pg_time_t) time(NULL);
8880  /* crash recovery should always recover to the end of WAL */
8883 
8884  /*
8885  * Persist unloggedLSN value. It's reset on crash recovery, so this goes
8886  * unused on non-shutdown checkpoints, but seems useful to store it always
8887  * for debugging purposes.
8888  */
8892 
8894  LWLockRelease(ControlFileLock);
8895 
8896  /* Update shared-memory copy of checkpoint XID/epoch */
8898  XLogCtl->ckptXidEpoch = checkPoint.nextXidEpoch;
8899  XLogCtl->ckptXid = checkPoint.nextXid;
8901 
8902  /*
8903  * We are now done with critical updates; no need for system panic if we
8904  * have trouble while fooling with old log segments.
8905  */
8906  END_CRIT_SECTION();
8907 
8908  /*
8909  * Let smgr do post-checkpoint cleanup (eg, deleting old files).
8910  */
8911  smgrpostckpt();
8912 
8913  /*
8914  * Update the average distance between checkpoints if the prior checkpoint
8915  * exists.
8916  */
8917  if (PriorRedoPtr != InvalidXLogRecPtr)
8919 
8920  /*
8921  * Delete old log files, those no longer needed for last checkpoint to
8922  * prevent the disk holding the xlog from growing full.
8923  */
8925  KeepLogSeg(recptr, &_logSegNo);
8926  _logSegNo--;
8927  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr);
8928 
8929  /*
8930  * Make more log segments if needed. (Do this after recycling old log
8931  * segments, since that may supply some of the needed files.)
8932  */
8933  if (!shutdown)
8934  PreallocXlogFiles(recptr);
8935 
8936  /*
8937  * Truncate pg_subtrans if possible. We can throw away all data before
8938  * the oldest XMIN of any running transaction. No future transaction will
8939  * attempt to reference any pg_subtrans entry older than that (see Asserts
8940  * in subtrans.c). During recovery, though, we mustn't do this because
8941  * StartupSUBTRANS hasn't been called yet.
8942  */
8943  if (!RecoveryInProgress())
8945 
8946  /* Real work is done, but log and update stats before releasing lock. */
8947  LogCheckpointEnd(false);
8948 
8949  TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
8950  NBuffers,
8954 
8955  LWLockRelease(CheckpointLock);
8956 }
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:8244
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8479
static int LocalXLogInsertAllowed
Definition: xlog.c:237
bool log_checkpoints
Definition: xlog.c:97
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define DEBUG1
Definition: elog.h:25
int64 pg_time_t
Definition: pgtime.h:23
TransactionId ckptXid
Definition: xlog.c:593
static void WALInsertLockRelease(void)
Definition: xlog.c:1690
int wal_segment_size
Definition: xlog.c:108
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:116
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1570
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1959
XLogRecPtr unloggedLSN
Definition: xlog.c:600
XLogRecPtr ProcLastRecPtr
Definition: xlog.c:348
TransactionId oldestActiveXid
Definition: pg_control.h:63
void InitXLogInsert(void)
Definition: xloginsert.c:1028
TimestampTz ckpt_start_t
Definition: xlog.h:232
slock_t info_lck
Definition: xlog.c:708
#define END_CRIT_SECTION()
Definition: miscadmin.h:134
VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids)
Definition: procarray.c:2287
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: xlog.c:641
TimeLineID PrevTimeLineID
Definition: pg_control.h:39
#define START_CRIT_SECTION()
Definition: miscadmin.h:132
int ckpt_segs_recycled
Definition: xlog.h:242
TransactionId oldestXid
Definition: transam.h:123
#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:9017
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:587
TransactionId oldestXid
Definition: pg_control.h:47
bool RecoveryInProgress(void)
Definition: xlog.c:7894
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:354
uint32 ckptXidEpoch
Definition: xlog.c:592
TransactionId nextXid
Definition: pg_control.h:43
pg_time_t time
Definition: pg_control.h:51
#define PANIC
Definition: elog.h:53
bool fullPageWrites
Definition: xlog.c:562
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2803
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
#define SpinLockAcquire(lock)
Definition: spin.h:62
void pg_usleep(long microsec)
Definition: signal.c:53
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
void UpdateControlFile(void)
Definition: xlog.c:4762
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:8394
TransactionId nextXid
Definition: transam.h:121
uint32 nextXidEpoch
Definition: pg_control.h:42
static XLogRecPtr RedoRecPtr
Definition: xlog.c:362
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
XLogRecPtr unloggedLSN
Definition: pg_control.h:133
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3792
uint64 XLogSegNo
Definition: xlogdefs.h:34
#define CHECKPOINT_END_OF_RECOVERY
Definition: xlog.h:210
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define InvalidTransactionId
Definition: transam.h:31
uint64 CurrBytePos
Definition: xlog.c:538
unsigned int uint32
Definition: c.h:358
XLogRecPtr RedoRecPtr
Definition: xlog.c:591
int ckpt_segs_removed
Definition: xlog.h:241
#define CHECKPOINT_FORCE
Definition: xlog.h:213
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:725
#define ereport(elevel, rest)
Definition: elog.h:141
TransactionId oldestCommitTsXid
Definition: transam.h:133
static void Insert(File file)
Definition: fd.c:1035
int ckpt_bufs_written
Definition: xlog.h:238
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8020
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:9337
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
Oid oldestMultiDB
Definition: pg_control.h:50
#define XLogStandbyInfoActive()
Definition: xlog.h:193
static ControlFileData * ControlFile
Definition: xlog.c:719
TimeLineID ThisTimeLineID
Definition: xlog.c:183
Oid nextOid
Definition: pg_control.h:44
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr RedoRecPtr, XLogRecPtr endptr)
Definition: xlog.c:3922
bool fullPageWrites
Definition: pg_control.h:41
TransactionId GetOldestXmin(Relation rel, int flags)
Definition: procarray.c:1321
void smgrpreckpt(void)
Definition: smgr.c:759
uint64 XLogRecPtr
Definition: xlogdefs.h:21
Oid oldestXidDB
Definition: pg_control.h:48
TransactionId newestCommitTsXid
Definition: transam.h:134
CheckpointStatsData CheckpointStats
Definition: xlog.c:177
#define SizeOfXLogShortPHD
Definition: xlog_internal.h:55
MultiXactId nextMulti
Definition: pg_control.h:45
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1661
static XLogCtlData * XLogCtl
Definition: xlog.c:711
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
int ckpt_segs_added
Definition: xlog.h:240
slock_t ulsn_lck
Definition: xlog.c:601
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
TransactionId GetOldestActiveTransactionId(void)
Definition: procarray.c:2125
int NBuffers
Definition: globals.c:131
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids)
Definition: procarray.c:2332
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr RedoRecPtr
Definition: xlog.c:560
void smgrpostckpt(void)
Definition: smgr.c:789
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:36
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8376
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:209
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ CreateEndOfRecoveryRecord()

static void CreateEndOfRecoveryRecord ( void  )
static

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

8969 {
8970  xl_end_of_recovery xlrec;
8971  XLogRecPtr recptr;
8972 
8973  /* sanity check */
8974  if (!RecoveryInProgress())
8975  elog(ERROR, "can only be used to end recovery");
8976 
8977  xlrec.end_time = GetCurrentTimestamp();
8978 
8983 
8985 
8987 
8988  XLogBeginInsert();
8989  XLogRegisterData((char *) &xlrec, sizeof(xl_end_of_recovery));
8990  recptr = XLogInsert(RM_XLOG_ID, XLOG_END_OF_RECOVERY);
8991 
8992  XLogFlush(recptr);
8993 
8994  /*
8995  * Update the control file so that crash recovery can follow the timeline
8996  * changes to this point.
8997  */
8998  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8999  ControlFile->time = (pg_time_t) time(NULL);
9000  ControlFile->minRecoveryPoint = recptr;
9003  LWLockRelease(ControlFileLock);
9004 
9005  END_CRIT_SECTION();
9006 
9007  LocalXLogInsertAllowed = -1; /* return to "check" state */
9008 }
static int LocalXLogInsertAllowed
Definition: xlog.c:237
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1690
pg_time_t time
Definition: pg_control.h:128
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
TimeLineID PrevTimeLineID
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1570
#define END_CRIT_SECTION()
Definition: miscadmin.h:134
TimeLineID PrevTimeLineID
Definition: xlog.c:641
#define START_CRIT_SECTION()
Definition: miscadmin.h:132
bool RecoveryInProgress(void)
Definition: xlog.c:7894
#define XLOG_END_OF_RECOVERY
Definition: pg_control.h:76
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2803
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
void UpdateControlFile(void)
Definition: xlog.c:4762
#define ERROR
Definition: elog.h:43
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8020
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:719
TimeLineID ThisTimeLineID
Definition: xlog.c:183
TimestampTz end_time
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1661
static XLogCtlData * XLogCtl
Definition: xlog.c:711
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
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 9087 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().

9088 {
9089  XLogRecPtr lastCheckPointRecPtr;
9090  XLogRecPtr lastCheckPointEndPtr;
9091  CheckPoint lastCheckPoint;
9092  XLogRecPtr PriorRedoPtr;
9093  XLogRecPtr receivePtr;
9094  XLogRecPtr replayPtr;
9095  TimeLineID replayTLI;
9096  XLogRecPtr endptr;
9097  XLogSegNo _logSegNo;
9098  TimestampTz xtime;
9099 
9100  /*
9101  * Acquire CheckpointLock to ensure only one restartpoint or checkpoint
9102  * happens at a time.
9103  */
9104  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
9105 
9106  /* Get a local copy of the last safe checkpoint record. */
9108  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
9109  lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
9110  lastCheckPoint = XLogCtl->lastCheckPoint;
9112 
9113  /*
9114  * Check that we're still in recovery mode. It's ok if we exit recovery
9115  * mode after this check, the restart point is valid anyway.
9116  */
9117  if (!RecoveryInProgress())
9118  {
9119  ereport(DEBUG2,
9120  (errmsg("skipping restartpoint, recovery has already ended")));
9121  LWLockRelease(CheckpointLock);
9122  return false;
9123  }
9124 
9125  /*
9126  * If the last checkpoint record we've replayed is already our last
9127  * restartpoint, we can't perform a new restart point. We still update
9128  * minRecoveryPoint in that case, so that if this is a shutdown restart
9129  * point, we won't start up earlier than before. That's not strictly
9130  * necessary, but when hot standby is enabled, it would be rather weird if
9131  * the database opened up for read-only connections at a point-in-time
9132  * before the last shutdown. Such time travel is still possible in case of
9133  * immediate shutdown, though.
9134  *
9135  * We don't explicitly advance minRecoveryPoint when we do create a
9136  * restartpoint. It's assumed that flushing the buffers will do that as a
9137  * side-effect.
9138  */
9139  if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
9140  lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
9141  {
9142  ereport(DEBUG2,
9143  (errmsg("skipping restartpoint, already performed at %X/%X",
9144  (uint32) (lastCheckPoint.redo >> 32),
9145  (uint32) lastCheckPoint.redo)));
9146 
9148  if (flags & CHECKPOINT_IS_SHUTDOWN)
9149  {
9150  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9152  ControlFile->time = (pg_time_t) time(NULL);
9154  LWLockRelease(ControlFileLock);
9155  }
9156  LWLockRelease(CheckpointLock);
9157  return false;
9158  }
9159 
9160  /*
9161  * Update the shared RedoRecPtr so that the startup process can calculate
9162  * the number of segments replayed since last restartpoint, and request a
9163  * restartpoint if it exceeds CheckPointSegments.
9164  *
9165  * Like in CreateCheckPoint(), hold off insertions to update it, although
9166  * during recovery this is just pro forma, because no WAL insertions are
9167  * happening.
9168  */
9170  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
9172 
9173  /* Also update the info_lck-protected copy */
9175  XLogCtl->RedoRecPtr = lastCheckPoint.redo;
9177 
9178  /*
9179  * Prepare to accumulate statistics.
9180  *
9181  * Note: because it is possible for log_checkpoints to change while a
9182  * checkpoint proceeds, we always accumulate stats, even if
9183  * log_checkpoints is currently off.
9184  */
9185  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
9187 
9188  if (log_checkpoints)
9189  LogCheckpointStart(flags, true);
9190 
9191  CheckPointGuts(lastCheckPoint.redo, flags);
9192 
9193  /*
9194  * Remember the prior checkpoint's redo ptr for
9195  * UpdateCheckPointDistanceEstimate()
9196  */
9197  PriorRedoPtr = ControlFile->checkPointCopy.redo;
9198 
9199  /*
9200  * Update pg_control, using current time. Check that it still shows
9201  * IN_ARCHIVE_RECOVERY state and an older checkpoint, else do nothing;
9202  * this is a quick hack to make sure nothing really bad happens if somehow
9203  * we get here after the end-of-recovery checkpoint.
9204  */
9205  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9207  ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
9208  {
9209  ControlFile->checkPoint = lastCheckPointRecPtr;
9210  ControlFile->checkPointCopy = lastCheckPoint;
9211  ControlFile->time = (pg_time_t) time(NULL);
9212 
9213  /*
9214  * Ensure minRecoveryPoint is past the checkpoint record. Normally,
9215  * this will have happened already while writing out dirty buffers,
9216  * but not necessarily - e.g. because no buffers were dirtied. We do
9217  * this because a non-exclusive base backup uses minRecoveryPoint to
9218  * determine which WAL files must be included in the backup, and the
9219  * file (or files) containing the checkpoint record must be included,
9220  * at a minimum. Note that for an ordinary restart of recovery there's
9221  * no value in having the minimum recovery point any earlier than this
9222  * anyway, because redo will begin just after the checkpoint record.
9223  */
9224  if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
9225  {
9226  ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
9228 
9229  /* update local copy */
9232  }
9233  if (flags & CHECKPOINT_IS_SHUTDOWN)
9236  }
9237  LWLockRelease(ControlFileLock);
9238 
9239  /*
9240  * Update the average distance between checkpoints/restartpoints if the
9241  * prior checkpoint exists.
9242  */
9243  if (PriorRedoPtr != InvalidXLogRecPtr)
9245 
9246  /*
9247  * Delete old log files, those no longer needed for last restartpoint to
9248  * prevent the disk holding the xlog from growing full.
9249  */
9251 
9252  /*
9253  * Retreat _logSegNo using the current end of xlog replayed or received,
9254  * whichever is later.
9255  */
9256  receivePtr = GetWalRcvWriteRecPtr(NULL, NULL);
9257  replayPtr = GetXLogReplayRecPtr(&replayTLI);
9258  endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
9259  KeepLogSeg(endptr, &_logSegNo);
9260  _logSegNo--;
9261 
9262  /*
9263  * Try to recycle segments on a useful timeline. If we've been promoted
9264  * since the beginning of this restartpoint, use the new timeline chosen
9265  * at end of recovery (RecoveryInProgress() sets ThisTimeLineID in that
9266  * case). If we're still in recovery, use the timeline we're currently
9267  * replaying.
9268  *
9269  * There is no guarantee that the WAL segments will be useful on the
9270  * current timeline; if recovery proceeds to a new timeline right after
9271  * this, the pre-allocated WAL segments on this timeline will not be used,
9272  * and will go wasted until recycled on the next restartpoint. We'll live
9273  * with that.
9274  */
9275  if (RecoveryInProgress())
9276  ThisTimeLineID = replayTLI;
9277 
9278  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr);
9279 
9280  /*
9281  * Make more log segments if needed. (Do this after recycling old log
9282  * segments, since that may supply some of the needed files.)
9283  */
9284  PreallocXlogFiles(endptr);
9285 
9286  /*
9287  * ThisTimeLineID is normally not set when we're still in recovery.
9288  * However, recycling/preallocating segments above needed ThisTimeLineID
9289  * to determine which timeline to install the segments on. Reset it now,
9290  * to restore the normal state of affairs for debugging purposes.
9291  */
9292  if (RecoveryInProgress())
9293  ThisTimeLineID = 0;
9294 
9295  /*
9296  * Truncate pg_subtrans if possible. We can throw away all data before
9297  * the oldest XMIN of any running transaction. No future transaction will
9298  * attempt to reference any pg_subtrans entry older than that (see Asserts
9299  * in subtrans.c). When hot standby is disabled, though, we mustn't do
9300  * this because StartupSUBTRANS hasn't been called yet.
9301  */
9302  if (EnableHotStandby)
9304 
9305  /* Real work is done, but log and update before releasing lock. */
9306  LogCheckpointEnd(true);
9307 
9308  xtime = GetLatestXTime();
9310  (errmsg("recovery restart point at %X/%X",
9311  (uint32) (lastCheckPoint.redo >> 32), (uint32) lastCheckPoint.redo),
9312  xtime ? errdetail("Last completed transaction was at log time %s.",
9313  timestamptz_to_str(xtime)) : 0));
9314 
9315  LWLockRelease(CheckpointLock);
9316 
9317  /*
9318  * Finally, execute archive_cleanup_command, if any.
9319  */
9320  if (archiveCleanupCommand && strcmp(archiveCleanupCommand, "") != 0)
9322  "archive_cleanup_command",
9323  false);
9324 
9325  return true;
9326 }
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8479
bool log_checkpoints
Definition: xlog.c:97
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:45
int64 pg_time_t
Definition: pgtime.h:23
XLogRecPtr GetWalRcvWriteRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI)
static void WALInsertLockRelease(void)
Definition: xlog.c:1690
int wal_segment_size
Definition: xlog.c:108
pg_time_t time
Definition: pg_control.h:128
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1570
int64 TimestampTz
Definition: timestamp.h:39
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition: xlog.c:2716
TimestampTz ckpt_start_t
Definition: xlog.h:232
slock_t info_lck
Definition: xlog.c:708
#define MemSet(start, val, len)
Definition: c.h:941
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:9017
TimestampTz GetLatestXTime(void)
Definition: xlog.c:6058
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:587
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:7894
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:354
XLogRecPtr lastCheckPointRecPtr
Definition: xlog.c:677
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
#define SpinLockAcquire(lock)
Definition: spin.h:62
void UpdateControlFile(void)
Definition: xlog.c:4762
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8394
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
Definition: xlog.c:11163
#define DEBUG2
Definition: elog.h:24
static XLogRecPtr RedoRecPtr
Definition: xlog.c:362
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3792
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errdetail(const char *fmt,...)
Definition: elog.c:860
unsigned int uint32
Definition: c.h:358
XLogRecPtr RedoRecPtr
Definition: xlog.c:591
#define ereport(elevel, rest)
Definition: elog.h:141
CheckPoint lastCheckPoint
Definition: xlog.c:679
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
#define SpinLockRelease(lock)
Definition: spin.h:64
static TimeLineID minRecoveryPointTLI
Definition: xlog.c:836
#define PROCARRAY_FLAGS_DEFAULT
Definition: procarray.h:50
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9337
static ControlFileData * ControlFile
Definition: xlog.c:719
TimeLineID ThisTimeLineID
Definition: xlog.c:183
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr RedoRecPtr, XLogRecPtr endptr)
Definition: xlog.c:3922
TransactionId GetOldestXmin(Relation rel, int flags)
Definition: procarray.c:1321
uint64 XLogRecPtr
Definition: xlogdefs.h:21
CheckpointStatsData CheckpointStats
Definition: xlog.c:177
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1661
static XLogCtlData * XLogCtl
Definition: xlog.c:711
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
bool EnableHotStandby
Definition: xlog.c:91
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
int errmsg(const char *fmt,...)
Definition: elog.c:784
XLogRecPtr RedoRecPtr
Definition: xlog.c:560
XLogRecPtr lastCheckPointEndPtr
Definition: xlog.c:678
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:36
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8376
char * archiveCleanupCommand
Definition: xlog.c:266
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:209
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:835
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1730
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ DataChecksumsEnabled()

bool DataChecksumsEnabled ( void  )

Definition at line 4832 of file xlog.c.

References Assert, and ControlFileData::data_checksum_version.

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

4833 {
4834  Assert(ControlFile != NULL);
4835  return (ControlFile->data_checksum_version > 0);
4836 }
uint32 data_checksum_version
Definition: pg_control.h:221
static ControlFileData * ControlFile
Definition: xlog.c:719
#define Assert(condition)
Definition: c.h:732

◆ do_pg_abort_backup()

void do_pg_abort_backup ( void  )

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

11136 {
11137  /*
11138  * Quick exit if session is not keeping around a non-exclusive backup
11139  * already started.
11140  */
11142  return;
11143 
11148 
11151  {
11152  XLogCtl->Insert.forcePageWrites = false;
11153  }
11155 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1690
static SessionBackupState sessionBackupState
Definition: xlog.c:522
XLogCtlInsert Insert
Definition: xlog.c:587
bool forcePageWrites
Definition: xlog.c:561
int nonExclusiveBackups
Definition: xlog.c:573
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:572
#define Assert(condition)
Definition: c.h:732
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1661
static XLogCtlData * XLogCtl
Definition: xlog.c:711

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

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

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

References DEBUG1, LOG, readSource, and XLOG_FROM_PG_WAL.

Referenced by ReadRecord(), and XLogPageRead().

12151 {
12152  static XLogRecPtr lastComplaint = 0;
12153 
12154  if (readSource == XLOG_FROM_PG_WAL && emode == LOG)
12155  {
12156  if (RecPtr == lastComplaint)
12157  emode = DEBUG1;
12158  else
12159  lastComplaint = RecPtr;
12160  }
12161  return emode;
12162 }
#define DEBUG1
Definition: elog.h:25
static XLogSource readSource
Definition: xlog.c:794
#define LOG
Definition: elog.h:26
uint64 XLogRecPtr
Definition: xlogdefs.h:21

◆ exitArchiveRecovery()

static void exitArchiveRecovery ( TimeLineID  endTLI,
XLogRecPtr  endOfLog 
)
static

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

5460 {
5461  char recoveryPath[MAXPGPATH];
5462  char xlogfname[MAXFNAMELEN];
5463  XLogSegNo endLogSegNo;
5464  XLogSegNo startLogSegNo;
5465 
5466  /* we always switch to a new timeline after archive recovery */
5467  Assert(endTLI != ThisTimeLineID);
5468 
5469  /*
5470  * We are no longer in archive recovery state.
5471  */
5472  InArchiveRecovery = false;
5473 
5474  /*
5475  * Update min recovery point one last time.
5476  */
5478 
5479  /*
5480  * If the ending log segment is still open, close it (to avoid problems on
5481  * Windows with trying to rename or delete an open file).
5482  */
5483  if (readFile >= 0)
5484  {
5485  close(readFile);
5486  readFile = -1;
5487  }
5488 
5489  /*
5490  * Calculate the last segment on the old timeline, and the first segment
5491  * on the new timeline. If the switch happens in the middle of a segment,
5492  * they are the same, but if the switch happens exactly at a segment
5493  * boundary, startLogSegNo will be endLogSegNo + 1.
5494  */
5495  XLByteToPrevSeg(endOfLog, endLogSegNo, wal_segment_size);
5496  XLByteToSeg(endOfLog, startLogSegNo, wal_segment_size);
5497 
5498  /*
5499  * Initialize the starting WAL segment for the new timeline. If the switch
5500  * happens in the middle of a segment, copy data from the last WAL segment
5501  * of the old timeline up to the switch point, to the starting WAL segment
5502  * on the new timeline.
5503  */
5504  if (endLogSegNo == startLogSegNo)
5505  {
5506  /*
5507  * Make a copy of the file on the new timeline.
5508  *
5509  * Writing WAL isn't allowed yet, so there are no locking
5510  * considerations. But we should be just as tense as XLogFileInit to
5511  * avoid emplacing a bogus file.
5512  */
5513  XLogFileCopy(endLogSegNo, endTLI, endLogSegNo,
5514  XLogSegmentOffset(endOfLog, wal_segment_size));
5515  }
5