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

Go to the source code of this file.

Data Structures

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

Macros

#define RECOVERY_COMMAND_FILE   "recovery.conf"
 
#define RECOVERY_COMMAND_DONE   "recovery.done"
 
#define NUM_XLOGINSERT_LOCKS   8
 
#define INSERT_FREESPACE(endptr)   (((endptr) % XLOG_BLCKSZ == 0) ? 0 : (XLOG_BLCKSZ - (endptr) % XLOG_BLCKSZ))
 
#define NextBufIdx(idx)   (((idx) == XLogCtl->XLogCacheBlck) ? 0 : ((idx) + 1))
 
#define XLogRecPtrToBufIdx(recptr)   (((recptr) / XLOG_BLCKSZ) % (XLogCtl->XLogCacheBlck + 1))
 
#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)
 
#define ConvertToXSegs(x, segsize)   XLogMBVarToSegs((x), (segsize))
 

Typedefs

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

Enumerations

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

Functions

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

Variables

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

Macro Definition Documentation

◆ ConvertToXSegs

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

◆ INSERT_FREESPACE

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

Definition at line 754 of file xlog.c.

Referenced by CopyXLogRecordToWAL(), and CreateCheckPoint().

◆ NextBufIdx

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

Definition at line 758 of file xlog.c.

Referenced by XLogWrite().

◆ NUM_XLOGINSERT_LOCKS

◆ RECOVERY_COMMAND_DONE

#define RECOVERY_COMMAND_DONE   "recovery.done"

Definition at line 88 of file xlog.c.

Referenced by readRecoverySignalFile().

◆ RECOVERY_COMMAND_FILE

#define RECOVERY_COMMAND_FILE   "recovery.conf"

Definition at line 87 of file xlog.c.

Referenced by readRecoverySignalFile().

◆ UsableBytesInPage

#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)

◆ XLogRecPtrToBufIdx

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

Definition at line 765 of file xlog.c.

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

Typedef Documentation

◆ ExclusiveBackupState

◆ WALInsertLockPadded

◆ XLogCtlData

typedef struct XLogCtlData XLogCtlData

◆ XLogCtlInsert

typedef struct XLogCtlInsert XLogCtlInsert

◆ XLogPageReadPrivate

◆ XLogwrtResult

typedef struct XLogwrtResult XLogwrtResult

◆ XLogwrtRqst

typedef struct XLogwrtRqst XLogwrtRqst

Enumeration Type Documentation

◆ ExclusiveBackupState

Enumerator
EXCLUSIVE_BACKUP_NONE 
EXCLUSIVE_BACKUP_STARTING 
EXCLUSIVE_BACKUP_IN_PROGRESS 
EXCLUSIVE_BACKUP_STOPPING 

Definition at line 523 of file xlog.c.

◆ XLogSource

enum XLogSource
Enumerator
XLOG_FROM_ANY 
XLOG_FROM_ARCHIVE 
XLOG_FROM_PG_WAL 
XLOG_FROM_STREAM 

Definition at line 792 of file xlog.c.

793 {
794  XLOG_FROM_ANY = 0, /* request to read WAL from any source */
795  XLOG_FROM_ARCHIVE, /* restored using restore_command */
796  XLOG_FROM_PG_WAL, /* existing file in pg_wal */
797  XLOG_FROM_STREAM /* streamed from primary */
798 } XLogSource;
XLogSource
Definition: xlog.c:792

Function Documentation

◆ AdvanceXLInsertBuffer()

static void AdvanceXLInsertBuffer ( XLogRecPtr  upto,
bool  opportunistic 
)
static

Definition at line 2137 of file xlog.c.

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

Referenced by GetXLogBuffer(), and XLogBackgroundFlush().

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

◆ assign_checkpoint_completion_target()

void assign_checkpoint_completion_target ( double  newval,
void *  extra 
)

Definition at line 2343 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

2344 {
2347 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2307
#define newval
double CheckPointCompletionTarget
Definition: checkpointer.c:148

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2336 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

2337 {
2340 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2307
int max_wal_size_mb
Definition: xlog.c:91
#define newval

◆ assign_xlog_sync_method()

void assign_xlog_sync_method ( int  new_sync_method,
void *  extra 
)

Definition at line 10524 of file xlog.c.

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

10525 {
10526  if (sync_method != new_sync_method)
10527  {
10528  /*
10529  * To ensure that no blocks escape unsynced, force an fsync on the
10530  * currently open log segment (if any). Also, if the open flag is
10531  * changing, close the log file so it will be reopened (with new flag
10532  * bit) at next use.
10533  */
10534  if (openLogFile >= 0)
10535  {
10537  if (pg_fsync(openLogFile) != 0)
10538  {
10539  char xlogfname[MAXFNAMELEN];
10540  int save_errno;
10541 
10542  save_errno = errno;
10545  errno = save_errno;
10546  ereport(PANIC,
10548  errmsg("could not fsync file \"%s\": %m", xlogfname)));
10549  }
10550 
10552  if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
10553  XLogFileClose();
10554  }
10555  }
10556 }
int wal_segment_size
Definition: xlog.c:118
static int get_sync_bit(int method)
Definition: xlog.c:10468
#define PANIC
Definition: elog.h:55
static XLogSegNo openLogSegNo
Definition: xlog.c:810
static void XLogFileClose(void)
Definition: xlog.c:3881
int errcode_for_file_access(void)
Definition: elog.c:727
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1512
#define MAXFNAMELEN
static int openLogFile
Definition: xlog.c:809
TimeLineID ThisTimeLineID
Definition: xlog.c:193
#define ereport(elevel,...)
Definition: elog.h:155
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1488
int sync_method
Definition: xlog.c:107
int errmsg(const char *fmt,...)
Definition: elog.c:915
int pg_fsync(int fd)
Definition: fd.c:347

◆ BackupInProgress()

bool BackupInProgress ( void  )

Definition at line 11935 of file xlog.c.

References BACKUP_LABEL_FILE, and stat.

Referenced by pg_is_in_backup(), and PostmasterStateMachine().

11936 {
11937  struct stat stat_buf;
11938 
11939  return (stat(BACKUP_LABEL_FILE, &stat_buf) == 0);
11940 }
struct stat stat_buf
Definition: pg_standby.c:100
#define BACKUP_LABEL_FILE
Definition: xlog.h:389
#define stat
Definition: win32_port.h:275

◆ BootStrapXLOG()

void BootStrapXLOG ( void  )

Definition at line 5224 of file xlog.c.

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

Referenced by AuxiliaryProcessMain().

5225 {
5226  CheckPoint checkPoint;
5227  char *buffer;
5228  XLogPageHeader page;
5229  XLogLongPageHeader longpage;
5230  XLogRecord *record;
5231  char *recptr;
5232  bool use_existent;
5233  uint64 sysidentifier;
5234  struct timeval tv;
5235  pg_crc32c crc;
5236 
5237  /*
5238  * Select a hopefully-unique system identifier code for this installation.
5239  * We use the result of gettimeofday(), including the fractional seconds
5240  * field, as being about as unique as we can easily get. (Think not to
5241  * use random(), since it hasn't been seeded and there's no portable way
5242  * to seed it other than the system clock value...) The upper half of the
5243  * uint64 value is just the tv_sec part, while the lower half contains the
5244  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
5245  * PID for a little extra uniqueness. A person knowing this encoding can
5246  * determine the initialization time of the installation, which could
5247  * perhaps be useful sometimes.
5248  */
5249  gettimeofday(&tv, NULL);
5250  sysidentifier = ((uint64) tv.tv_sec) << 32;
5251  sysidentifier |= ((uint64) tv.tv_usec) << 12;
5252  sysidentifier |= getpid() & 0xFFF;
5253 
5254  /* First timeline ID is always 1 */
5255  ThisTimeLineID = 1;
5256 
5257  /* page buffer must be aligned suitably for O_DIRECT */
5258  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
5259  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
5260  memset(page, 0, XLOG_BLCKSZ);
5261 
5262  /*
5263  * Set up information for the initial checkpoint record
5264  *
5265  * The initial checkpoint record is written to the beginning of the WAL
5266  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5267  * used, so that we can use 0/0 to mean "before any valid WAL segment".
5268  */
5269  checkPoint.redo = wal_segment_size + SizeOfXLogLongPHD;
5270  checkPoint.ThisTimeLineID = ThisTimeLineID;
5271  checkPoint.PrevTimeLineID = ThisTimeLineID;
5272  checkPoint.fullPageWrites = fullPageWrites;
5273  checkPoint.nextXid =
5275  checkPoint.nextOid = FirstBootstrapObjectId;
5276  checkPoint.nextMulti = FirstMultiXactId;
5277  checkPoint.nextMultiOffset = 0;
5278  checkPoint.oldestXid = FirstNormalTransactionId;
5279  checkPoint.oldestXidDB = TemplateDbOid;
5280  checkPoint.oldestMulti = FirstMultiXactId;
5281  checkPoint.oldestMultiDB = TemplateDbOid;
5284  checkPoint.time = (pg_time_t) time(NULL);
5286 
5287  ShmemVariableCache->nextXid = checkPoint.nextXid;
5288  ShmemVariableCache->nextOid = checkPoint.nextOid;
5290  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5291  AdvanceOldestClogXid(checkPoint.oldestXid);
5292  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5293  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5295 
5296  /* Set up the XLOG page header */
5297  page->xlp_magic = XLOG_PAGE_MAGIC;
5298  page->xlp_info = XLP_LONG_HEADER;
5299  page->xlp_tli = ThisTimeLineID;
5301  longpage = (XLogLongPageHeader) page;
5302  longpage->xlp_sysid = sysidentifier;
5303  longpage->xlp_seg_size = wal_segment_size;
5304  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5305 
5306  /* Insert the initial checkpoint record */
5307  recptr = ((char *) page + SizeOfXLogLongPHD);
5308  record = (XLogRecord *) recptr;
5309  record->xl_prev = 0;
5310  record->xl_xid = InvalidTransactionId;
5311  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5313  record->xl_rmid = RM_XLOG_ID;
5314  recptr += SizeOfXLogRecord;
5315  /* fill the XLogRecordDataHeaderShort struct */
5316  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5317  *(recptr++) = sizeof(checkPoint);
5318  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5319  recptr += sizeof(checkPoint);
5320  Assert(recptr - (char *) record == record->xl_tot_len);
5321 
5322  INIT_CRC32C(crc);
5323  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5324  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5325  FIN_CRC32C(crc);
5326  record->xl_crc = crc;
5327 
5328  /* Create first XLOG segment file */
5329  use_existent = false;
5330  openLogFile = XLogFileInit(1, &use_existent, false);
5331 
5332  /*
5333  * We needn't bother with Reserve/ReleaseExternalFD here, since we'll
5334  * close the file again in a moment.
5335  */
5336 
5337  /* Write the first page with the initial record */
5338  errno = 0;
5340  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5341  {
5342  /* if write didn't set errno, assume problem is no disk space */
5343  if (errno == 0)
5344  errno = ENOSPC;
5345  ereport(PANIC,
5347  errmsg("could not write bootstrap write-ahead log file: %m")));
5348  }
5350 
5352  if (pg_fsync(openLogFile) != 0)
5353  ereport(PANIC,
5355  errmsg("could not fsync bootstrap write-ahead log file: %m")));
5357 
5358  if (close(openLogFile) != 0)
5359  ereport(PANIC,
5361  errmsg("could not close bootstrap write-ahead log file: %m")));
5362 
5363  openLogFile = -1;
5364 
5365  /* Now create pg_control */
5366  InitControlFile(sysidentifier);
5367  ControlFile->time = checkPoint.time;
5368  ControlFile->checkPoint = checkPoint.redo;
5369  ControlFile->checkPointCopy = checkPoint;
5370 
5371  /* some additional ControlFile fields are set in WriteControlFile() */
5372  WriteControlFile();
5373 
5374  /* Bootstrap the commit log, too */
5375  BootStrapCLOG();
5379 
5380  pfree(buffer);
5381 
5382  /*
5383  * Force control file to be read - in contrast to normal processing we'd
5384  * otherwise never run the checks and GUC related initializations therein.
5385  */
5386  ReadControlFile();
5387 }
static void WriteControlFile(void)
Definition: xlog.c:4641
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:104
int64 pg_time_t
Definition: pgtime.h:23
int wal_segment_size
Definition: xlog.c:118
pg_time_t time
Definition: pg_control.h:128
void SetCommitTsLimit(TransactionId oldestXact, TransactionId newestXact)
Definition: commit_ts.c:893
uint32 oidCount
Definition: transam.h:208
#define write(a, b, c)
Definition: win32.h:14
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:200
uint32 pg_crc32c
Definition: pg_crc32c.h:38
TransactionId oldestActiveXid
Definition: pg_control.h:63
int XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
Definition: xlog.c:3267
void BootStrapMultiXact(void)
Definition: multixact.c:1891
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
static void InitControlFile(uint64 sysidentifier)
Definition: xlog.c:4606
RmgrId xl_rmid
Definition: xlogrecord.h:47
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:54
CheckPoint checkPointCopy
Definition: pg_control.h:131
TransactionId oldestXid
Definition: pg_control.h:47
FullTransactionId nextXid
Definition: transam.h:213
pg_time_t time
Definition: pg_control.h:51
#define PANIC
Definition: elog.h:55
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:71
bool fullPageWrites
Definition: xlog.c:99
void BootStrapSUBTRANS(void)
Definition: subtrans.c:211
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid)
Definition: varsup.c:328
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
void pfree(void *pointer)
Definition: mcxt.c:1057
#define FirstNormalTransactionId
Definition: transam.h:34
uint32 xl_tot_len
Definition: xlogrecord.h:43
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
static void ReadControlFile(void)
Definition: xlog.c:4732
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
int errcode_for_file_access(void)
Definition: elog.c:727
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define InvalidTransactionId
Definition: transam.h:31
#define FirstBootstrapObjectId
Definition: transam.h:189
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1512
#define FirstMultiXactId
Definition: multixact.h:25
TimeLineID xlp_tli
Definition: xlog_internal.h:40
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
#define SizeOfXLogRecord
Definition: xlogrecord.h:55
TransactionId newestCommitTsXid
Definition: pg_control.h:54
Oid oldestMultiDB
Definition: pg_control.h:50
static int openLogFile
Definition: xlog.c:809
static ControlFileData * ControlFile
Definition: xlog.c:748
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
Definition: multixact.c:2210
TimeLineID ThisTimeLineID
Definition: xlog.c:193
Oid nextOid
Definition: pg_control.h:44
#define ereport(elevel,...)
Definition: elog.h:155
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:738
bool fullPageWrites
Definition: pg_control.h:42
void BootStrapCLOG(void)
Definition: clog.c:707
#define Assert(condition)
Definition: c.h:792
#define XLP_LONG_HEADER
Definition: xlog_internal.h:76
Oid oldestXidDB
Definition: pg_control.h:48
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1488
void SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid)
Definition: varsup.c:345
uint8 xl_info
Definition: xlogrecord.h:46
MultiXactId nextMulti
Definition: pg_control.h:45
static FullTransactionId FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
Definition: transam.h:71
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:223
TransactionId xl_xid
Definition: xlogrecord.h:44
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
void * palloc(Size size)
Definition: mcxt.c:950
int errmsg(const char *fmt,...)
Definition: elog.c:915
int pg_fsync(int fd)
Definition: fd.c:347
#define close(a)
Definition: win32.h:12
void BootStrapCommitTs(void)
Definition: commit_ts.c:586
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:89
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:94
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:37
#define offsetof(type, field)
Definition: c.h:715
FullTransactionId nextXid
Definition: pg_control.h:43
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:69
void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset)
Definition: multixact.c:2176

◆ CalculateCheckpointSegments()

static void CalculateCheckpointSegments ( void  )
static

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

2308 {
2309  double target;
2310 
2311  /*-------
2312  * Calculate the distance at which to trigger a checkpoint, to avoid
2313  * exceeding max_wal_size_mb. This is based on two assumptions:
2314  *
2315  * a) we keep WAL for only one checkpoint cycle (prior to PG11 we kept
2316  * WAL for two checkpoint cycles to allow us to recover from the
2317  * secondary checkpoint if the first checkpoint failed, though we
2318  * only did this on the primary anyway, not on standby. Keeping just
2319  * one checkpoint simplifies processing and reduces disk space in
2320  * many smaller databases.)
2321  * b) during checkpoint, we consume checkpoint_completion_target *
2322  * number of segments consumed between checkpoints.
2323  *-------
2324  */
2325  target = (double) ConvertToXSegs(max_wal_size_mb, wal_segment_size) /
2327 
2328  /* round down */
2329  CheckPointSegments = (int) target;
2330 
2331  if (CheckPointSegments < 1)
2332  CheckPointSegments = 1;
2333 }
#define ConvertToXSegs(x, segsize)
Definition: xlog.c:777
int wal_segment_size
Definition: xlog.c:118
int max_wal_size_mb
Definition: xlog.c:91
int CheckPointSegments
Definition: xlog.c:131
double CheckPointCompletionTarget
Definition: checkpointer.c:148

◆ CancelBackup()

void CancelBackup ( void  )

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

11956 {
11957  struct stat stat_buf;
11958 
11959  /* if the backup_label file is not there, return */
11960  if (stat(BACKUP_LABEL_FILE, &stat_buf) < 0)
11961  return;
11962 
11963  /* remove leftover file from previously canceled backup if it exists */
11964  unlink(BACKUP_LABEL_OLD);
11965 
11967  {
11968  ereport(WARNING,
11970  errmsg("online backup mode was not canceled"),
11971  errdetail("File \"%s\" could not be renamed to \"%s\": %m.",
11973  return;
11974  }
11975 
11976  /* if the tablespace_map file is not there, return */
11977  if (stat(TABLESPACE_MAP, &stat_buf) < 0)
11978  {
11979  ereport(LOG,
11980  (errmsg("online backup mode canceled"),
11981  errdetail("File \"%s\" was renamed to \"%s\".",
11983  return;
11984  }
11985 
11986  /* remove leftover file from previously canceled backup if it exists */
11987  unlink(TABLESPACE_MAP_OLD);
11988 
11990  {
11991  ereport(LOG,
11992  (errmsg("online backup mode canceled"),
11993  errdetail("Files \"%s\" and \"%s\" were renamed to "
11994  "\"%s\" and \"%s\", respectively.",
11997  }
11998  else
11999  {
12000  ereport(WARNING,
12002  errmsg("online backup mode canceled"),
12003  errdetail("File \"%s\" was renamed to \"%s\", but "
12004  "file \"%s\" could not be renamed to \"%s\": %m.",
12007  }
12008 }
#define DEBUG1
Definition: elog.h:25
#define LOG
Definition: elog.h:26
#define BACKUP_LABEL_OLD
Definition: xlog.h:390
#define TABLESPACE_MAP
Definition: xlog.h:392
struct stat stat_buf
Definition: pg_standby.c:100
int errdetail(const char *fmt,...)
Definition: elog.c:1048
int errcode_for_file_access(void)
Definition: elog.c:727
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:687
#define WARNING
Definition: elog.h:40
#define ereport(elevel,...)
Definition: elog.h:155
#define TABLESPACE_MAP_OLD
Definition: xlog.h:393
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define BACKUP_LABEL_FILE
Definition: xlog.h:389
#define stat
Definition: win32_port.h:275

◆ check_wal_buffers()

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

Definition at line 5017 of file xlog.c.

References XLOGbuffers, and XLOGChooseNumBuffers().

5018 {
5019  /*
5020  * -1 indicates a request for auto-tune.
5021  */
5022  if (*newval == -1)
5023  {
5024  /*
5025  * If we haven't yet changed the boot_val default of -1, just let it
5026  * be. We'll fix it when XLOGShmemSize is called.
5027  */
5028  if (XLOGbuffers == -1)
5029  return true;
5030 
5031  /* Otherwise, substitute the auto-tune value */
5033  }
5034 
5035  /*
5036  * We clamp manually-set values to at least 4 blocks. Prior to PostgreSQL
5037  * 9.1, a minimum of 4 was enforced by guc.c, but since that is no longer
5038  * the case, we just silently treat such values as a request for the
5039  * minimum. (We could throw an error instead, but that doesn't seem very
5040  * helpful.)
5041  */
5042  if (*newval < 4)
5043  *newval = 4;
5044 
5045  return true;
5046 }
static int XLOGChooseNumBuffers(void)
Definition: xlog.c:5001
#define newval
int XLOGbuffers
Definition: xlog.c:94

◆ CheckForStandbyTrigger()

static bool CheckForStandbyTrigger ( void  )
static

Definition at line 12749 of file xlog.c.

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

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

12750 {
12751  struct stat stat_buf;
12752 
12754  return true;
12755 
12757  {
12758  ereport(LOG, (errmsg("received promote request")));
12762  return true;
12763  }
12764 
12765  if (PromoteTriggerFile == NULL || strcmp(PromoteTriggerFile, "") == 0)
12766  return false;
12767 
12768  if (stat(PromoteTriggerFile, &stat_buf) == 0)
12769  {
12770  ereport(LOG,
12771  (errmsg("promote trigger file found: %s", PromoteTriggerFile)));
12772  unlink(PromoteTriggerFile);
12774  return true;
12775  }
12776  else if (errno != ENOENT)
12777  ereport(ERROR,
12779  errmsg("could not stat promote trigger file \"%s\": %m",
12780  PromoteTriggerFile)));
12781 
12782  return false;
12783 }
char * PromoteTriggerFile
Definition: xlog.c:298
bool CheckPromoteSignal(void)
Definition: xlog.c:12798
bool IsPromoteSignaled(void)
Definition: startup.c:234
static bool LocalPromoteIsTriggered
Definition: xlog.c:242
#define LOG
Definition: elog.h:26
static void SetPromoteIsTriggered(void)
Definition: xlog.c:12735
#define ERROR
Definition: elog.h:45
struct stat stat_buf
Definition: pg_standby.c:100
int errcode_for_file_access(void)
Definition: elog.c:727
void RemovePromoteSignalFiles(void)
Definition: xlog.c:12789
#define ereport(elevel,...)
Definition: elog.h:155
void ResetPromoteSignaled(void)
Definition: startup.c:240
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define stat
Definition: win32_port.h:275

◆ CheckPointGuts()

static void CheckPointGuts ( XLogRecPtr  checkPointRedo,
int  flags 
)
static

Definition at line 9307 of file xlog.c.

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

Referenced by CreateCheckPoint(), and CreateRestartPoint().

9308 {
9314 
9315  /* Write out all dirty data in SLRUs and the main buffer pool */
9316  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_START(flags);
9318  CheckPointCLOG();
9323  CheckPointBuffers(flags);
9324 
9325  /* Perform all queued up fsyncs */
9326  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_SYNC_START();
9330  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_DONE();
9331 
9332  /* We deliberately delay 2PC checkpointing as long as possible */
9333  CheckPointTwoPhase(checkPointRedo);
9334 }
void ProcessSyncRequests(void)
Definition: sync.c:257
void CheckPointBuffers(int flags)
Definition: bufmgr.c:2650
TimestampTz ckpt_sync_end_t
Definition: xlog.h:249
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1578
void CheckPointLogicalRewriteHeap(void)
Definition: rewriteheap.c:1193
void CheckPointReplicationOrigin(void)
Definition: origin.c:540
void CheckPointSnapBuild(void)
Definition: snapbuild.c:1943
void CheckPointCLOG(void)
Definition: clog.c:818
void CheckPointMultiXact(void)
Definition: multixact.c:2152
void CheckPointCommitTs(void)
Definition: commit_ts.c:807
CheckpointStatsData CheckpointStats
Definition: xlog.c:187
TimestampTz ckpt_write_t
Definition: xlog.h:247
void CheckPointSUBTRANS(void)
Definition: subtrans.c:284
void CheckPointRelationMap(void)
Definition: relmapper.c:546
TimestampTz ckpt_sync_t
Definition: xlog.h:248
void CheckPointPredicate(void)
Definition: predicate.c:1069
void CheckPointTwoPhase(XLogRecPtr redo_horizon)
Definition: twophase.c:1691
void CheckPointReplicationSlots(void)
Definition: slot.c:1271

◆ CheckPromoteSignal()

bool CheckPromoteSignal ( void  )

Definition at line 12798 of file xlog.c.

References PROMOTE_SIGNAL_FILE, and stat.

Referenced by CheckForStandbyTrigger(), and sigusr1_handler().

12799 {
12800  struct stat stat_buf;
12801 
12802  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
12803  return true;
12804 
12805  return false;
12806 }
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:396
struct stat stat_buf
Definition: pg_standby.c:100
#define stat
Definition: win32_port.h:275

◆ CheckRecoveryConsistency()

static void CheckRecoveryConsistency ( void  )
static

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

8048 {
8049  XLogRecPtr lastReplayedEndRecPtr;
8050 
8051  /*
8052  * During crash recovery, we don't reach a consistent state until we've
8053  * replayed all the WAL.
8054  */
8056  return;
8057 
8059 
8060  /*
8061  * assume that we are called in the startup process, and hence don't need
8062  * a lock to read lastReplayedEndRecPtr
8063  */
8064  lastReplayedEndRecPtr = XLogCtl->lastReplayedEndRecPtr;
8065 
8066  /*
8067  * Have we reached the point where our base backup was completed?
8068  */
8070  ControlFile->backupEndPoint <= lastReplayedEndRecPtr)
8071  {
8072  /*
8073  * We have reached the end of base backup, as indicated by pg_control.
8074  * The data on disk is now consistent. Reset backupStartPoint and
8075  * backupEndPoint, and update minRecoveryPoint to make sure we don't
8076  * allow starting up at an earlier point even if recovery is stopped
8077  * and restarted soon after this.
8078  */
8079  elog(DEBUG1, "end of backup reached");
8080 
8081  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8082 
8083  if (ControlFile->minRecoveryPoint < lastReplayedEndRecPtr)
8084  ControlFile->minRecoveryPoint = lastReplayedEndRecPtr;
8085 
8088  ControlFile->backupEndRequired = false;
8090 
8091  LWLockRelease(ControlFileLock);
8092  }
8093 
8094  /*
8095  * Have we passed our safe starting point? Note that minRecoveryPoint is
8096  * known to be incorrectly set if ControlFile->backupEndRequired, until
8097  * the XLOG_BACKUP_END arrives to advise us of the correct
8098  * minRecoveryPoint. All we know prior to that is that we're not
8099  * consistent yet.
8100  */
8102  minRecoveryPoint <= lastReplayedEndRecPtr &&
8104  {
8105  /*
8106  * Check to see if the XLOG sequence contained any unresolved
8107  * references to uninitialized pages.
8108  */
8110 
8111  reachedConsistency = true;
8112  ereport(LOG,
8113  (errmsg("consistent recovery state reached at %X/%X",
8114  (uint32) (lastReplayedEndRecPtr >> 32),
8115  (uint32) lastReplayedEndRecPtr)));
8116  }
8117 
8118  /*
8119  * Have we got a valid starting snapshot that will allow queries to be
8120  * run? If so, we can tell postmaster that the database is consistent now,
8121  * enabling connections.
8122  */
8127  {
8131 
8132  LocalHotStandbyActive = true;
8133 
8135  }
8136 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define DEBUG1
Definition: elog.h:25
void XLogCheckInvalidPages(void)
Definition: xlogutils.c:223
bool SharedHotStandbyActive
Definition: xlog.c:666
slock_t info_lck
Definition: xlog.c:737
#define LOG
Definition: elog.h:26
bool InArchiveRecovery
Definition: xlog.c:268
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1810
bool backupEndRequired
Definition: pg_control.h:170
#define SpinLockAcquire(lock)
Definition: spin.h:62
static bool LocalHotStandbyActive
Definition: xlog.c:236
void UpdateControlFile(void)
Definition: xlog.c:4932
bool IsUnderPostmaster
Definition: globals.c:110
unsigned int uint32
Definition: c.h:429
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
#define SpinLockRelease(lock)
Definition: spin.h:64
static ControlFileData * ControlFile
Definition: xlog.c:748
#define ereport(elevel,...)
Definition: elog.h:155
XLogRecPtr backupEndPoint
Definition: pg_control.h:169
bool reachedConsistency
Definition: xlog.c:881
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:792
static XLogCtlData * XLogCtl
Definition: xlog.c:740
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define elog(elevel,...)
Definition: elog.h:228
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:153
HotStandbyState standbyState
Definition: xlog.c:209
XLogRecPtr backupStartPoint
Definition: pg_control.h:168
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:872
XLogRecPtr lastReplayedEndRecPtr
Definition: xlog.c:716

◆ CheckRequiredParameterValues()

static void CheckRequiredParameterValues ( void  )
static

Definition at line 6330 of file xlog.c.

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

Referenced by StartupXLOG(), and xlog_redo().

6331 {
6332  /*
6333  * For archive recovery, the WAL must be generated with at least 'replica'
6334  * wal_level.
6335  */
6337  {
6338  ereport(WARNING,
6339  (errmsg("WAL was generated with wal_level=minimal, data may be missing"),
6340  errhint("This happens if you temporarily set wal_level=minimal without taking a new base backup.")));
6341  }
6342 
6343  /*
6344  * For Hot Standby, the WAL must be generated with 'replica' mode, and we
6345  * must have at least as many backend slots as the primary.
6346  */
6348  {
6350  ereport(ERROR,
6351  (errmsg("hot standby is not possible because wal_level was not set to \"replica\" or higher on the primary server"),
6352  errhint("Either set wal_level to \"replica\" on the primary, or turn off hot_standby here.")));
6353 
6354  /* We ignore autovacuum_max_workers when we make this test. */
6355  RecoveryRequiresIntParameter("max_connections",
6358  RecoveryRequiresIntParameter("max_worker_processes",
6361  RecoveryRequiresIntParameter("max_wal_senders",
6364  RecoveryRequiresIntParameter("max_prepared_transactions",
6367  RecoveryRequiresIntParameter("max_locks_per_transaction",
6370  }
6371 }
bool ArchiveRecoveryRequested
Definition: xlog.c:267
int max_locks_per_xact
Definition: pg_control.h:182
int errhint(const char *fmt,...)
Definition: elog.c:1162
int max_prepared_xacts
Definition: pg_control.h:181
static void RecoveryRequiresIntParameter(const char *param_name, int currValue, int minValue)
Definition: xlog.c:6261
int max_worker_processes
Definition: pg_control.h:179
#define ERROR
Definition: elog.h:45
int max_prepared_xacts
Definition: twophase.c:117
int max_locks_per_xact
Definition: lock.c:54
int max_wal_senders
Definition: walsender.c:121
#define WARNING
Definition: elog.h:40
int MaxConnections
Definition: globals.c:134
static ControlFileData * ControlFile
Definition: xlog.c:748
#define ereport(elevel,...)
Definition: elog.h:155
bool EnableHotStandby
Definition: xlog.c:98
int errmsg(const char *fmt,...)
Definition: elog.c:915
int max_worker_processes
Definition: globals.c:135

◆ checkTimeLineSwitch()

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

Definition at line 10003 of file xlog.c.

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

Referenced by StartupXLOG().

10004 {
10005  /* Check that the record agrees on what the current (old) timeline is */
10006  if (prevTLI != ThisTimeLineID)
10007  ereport(PANIC,
10008  (errmsg("unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record",
10009  prevTLI, ThisTimeLineID)));
10010 
10011  /*
10012  * The new timeline better be in the list of timelines we expect to see,
10013  * according to the timeline history. It should also not decrease.
10014  */
10015  if (newTLI < ThisTimeLineID || !tliInHistory(newTLI, expectedTLEs))
10016  ereport(PANIC,
10017  (errmsg("unexpected timeline ID %u (after %u) in checkpoint record",
10018  newTLI, ThisTimeLineID)));
10019 
10020  /*
10021  * If we have not yet reached min recovery point, and we're about to
10022  * switch to a timeline greater than the timeline of the min recovery
10023  * point: trouble. After switching to the new timeline, we could not
10024  * possibly visit the min recovery point on the correct timeline anymore.
10025  * This can happen if there is a newer timeline in the archive that
10026  * branched before the timeline the min recovery point is on, and you
10027  * attempt to do PITR to the new timeline.
10028  */
10030  lsn < minRecoveryPoint &&
10031  newTLI > minRecoveryPointTLI)
10032  ereport(PANIC,
10033  (errmsg("unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u",
10034  newTLI,
10035  (uint32) (minRecoveryPoint >> 32),
10038 
10039  /* Looks good */
10040 }
static List * expectedTLEs
Definition: xlog.c:343
#define PANIC
Definition: elog.h:55
unsigned int uint32
Definition: c.h:429
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
static TimeLineID minRecoveryPointTLI
Definition: xlog.c:873
TimeLineID ThisTimeLineID
Definition: xlog.c:193
#define ereport(elevel,...)
Definition: elog.h:155
int errmsg(const char *fmt,...)
Definition: elog.c:915
bool tliInHistory(TimeLineID tli, List *expectedTLEs)
Definition: timeline.c:534
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:872

◆ checkXLogConsistency()

static void checkXLogConsistency ( XLogReaderState record)
static

Definition at line 1418 of file xlog.c.

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

Referenced by StartupXLOG().

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

◆ CheckXLogRemoved()

void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)

Definition at line 3956 of file xlog.c.

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

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

3957 {
3958  int save_errno = errno;
3959  XLogSegNo lastRemovedSegNo;
3960 
3962  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3964 
3965  if (segno <= lastRemovedSegNo)
3966  {
3967  char filename[MAXFNAMELEN];
3968 
3969  XLogFileName(filename, tli, segno, wal_segment_size);
3970  errno = save_errno;
3971  ereport(ERROR,
3973  errmsg("requested WAL segment %s has already been removed",
3974  filename)));
3975  }
3976  errno = save_errno;
3977 }
int wal_segment_size
Definition: xlog.c:118
slock_t info_lck
Definition: xlog.c:737
XLogSegNo lastRemovedSegNo
Definition: xlog.c:610
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define ERROR
Definition: elog.h:45
uint64 XLogSegNo
Definition: xlogdefs.h:41
int errcode_for_file_access(void)
Definition: elog.c:727
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
#define ereport(elevel,...)
Definition: elog.h:155
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static XLogCtlData * XLogCtl
Definition: xlog.c:740
static char * filename
Definition: pg_dumpall.c:91
int errmsg(const char *fmt,...)
Definition: elog.c:915

◆ CleanupBackupHistory()

static void CleanupBackupHistory ( void  )
static

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

4321 {
4322  DIR *xldir;
4323  struct dirent *xlde;
4324  char path[MAXPGPATH + sizeof(XLOGDIR)];
4325 
4326  xldir = AllocateDir(XLOGDIR);
4327 
4328  while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
4329  {
4330  if (IsBackupHistoryFileName(xlde->d_name))
4331  {
4332  if (XLogArchiveCheckDone(xlde->d_name))
4333  {
4334  elog(DEBUG2, "removing WAL backup history file \"%s\"",
4335  xlde->d_name);
4336  snprintf(path, sizeof(path), XLOGDIR "/%s", xlde->d_name);
4337  unlink(path);
4338  XLogArchiveCleanup(xlde->d_name);
4339  }
4340  }
4341  }
4342 
4343  FreeDir(xldir);
4344 }
Definition: dirent.h:9
void XLogArchiveCleanup(const char *xlog)
Definition: xlogarchive.c:719
Definition: dirent.c:25
bool XLogArchiveCheckDone(const char *xlog)
Definition: xlogarchive.c:572
#define MAXPGPATH
#define DEBUG2
Definition: elog.h:24
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2615
#define IsBackupHistoryFileName(fname)
#define XLOGDIR
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2681
#define elog(elevel,...)
Definition: elog.h:228
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:215
int FreeDir(DIR *dir)
Definition: fd.c:2733

◆ CopyXLogRecordToWAL()

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

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

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

◆ CreateCheckPoint()

void CreateCheckPoint ( int  flags)

Definition at line 8830 of file xlog.c.

References ControlFileData::checkPoint, CHECKPOINT_END_OF_RECOVERY, CHECKPOINT_FORCE, CHECKPOINT_IS_SHUTDOWN, ControlFileData::checkPointCopy, CheckPointGuts(), CheckpointStatsData::ckpt_bufs_written, CheckpointStatsData::ckpt_segs_added, CheckpointStatsData::ckpt_segs_recycled, CheckpointStatsData::ckpt_segs_removed, CheckpointStatsData::ckpt_start_t, XLogCtlData::ckptFullXid, XLogCtlInsert::CurrBytePos, DB_SHUTDOWNED, DB_SHUTDOWNING, DEBUG1, elog, END_CRIT_SECTION, ereport, errmsg(), ERROR, CheckPoint::fullPageWrites, XLogCtlInsert::fullPageWrites, GetCurrentTimestamp(), GetLastImportantRecPtr(), GetOldestActiveTransactionId(), GetOldestTransactionIdConsideredRunning(), GetVirtualXIDsDelayingChkpt(), HaveVirtualXIDsDelayingChkpt(), XLogCtlData::info_lck, InitXLogInsert(), Insert(), XLogCtlData::Insert, INSERT_FREESPACE, InvalidateObsoleteReplicationSlots(), InvalidTransactionId, InvalidXLogRecPtr, KeepLogSeg(), LocalSetXLogInsertAllowed(), LocalXLogInsertAllowed, log_checkpoints, LogCheckpointEnd(), LogCheckpointStart(), LogStandbySnapshot(), LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockRelease(), MemSet, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, MultiXactGetCheckptMulti(), NBuffers, CheckPoint::newestCommitTsXid, VariableCacheData::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, VariableCacheData::nextOid, CheckPoint::nextXid, VariableCacheData::nextXid, VariableCacheData::oidCount, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, VariableCacheData::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, VariableCacheData::oldestXid, CheckPoint::oldestXidDB, VariableCacheData::oldestXidDB, PANIC, pfree(), pg_usleep(), PreallocXlogFiles(), CheckPoint::PrevTimeLineID, XLogCtlData::PrevTimeLineID, ProcLastRecPtr, RecoveryInProgress(), CheckPoint::redo, RedoRecPtr, XLogCtlInsert::RedoRecPtr, XLogCtlData::RedoRecPtr, RemoveOldXlogFiles(), ShmemVariableCache, SizeOfXLogLongPHD, SizeOfXLogShortPHD, SpinLockAcquire, SpinLockRelease, START_CRIT_SECTION, ControlFileData::state, SyncPostCheckpoint(), SyncPreCheckpoint(), CheckPoint::ThisTimeLineID, ThisTimeLineID, CheckPoint::time, ControlFileData::time, TruncateSUBTRANS(), XLogCtlData::ulsn_lck, ControlFileData::unloggedLSN, XLogCtlData::unloggedLSN, update_checkpoint_display(), 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().

8831 {
8832  bool shutdown;
8833  CheckPoint checkPoint;
8834  XLogRecPtr recptr;
8835  XLogSegNo _logSegNo;
8837  uint32 freespace;
8838  XLogRecPtr PriorRedoPtr;
8839  XLogRecPtr curInsert;
8840  XLogRecPtr last_important_lsn;
8841  VirtualTransactionId *vxids;
8842  int nvxids;
8843 
8844  /*
8845  * An end-of-recovery checkpoint is really a shutdown checkpoint, just
8846  * issued at a different time.
8847  */
8849  shutdown = true;
8850  else
8851  shutdown = false;
8852 
8853  /* sanity check */
8854  if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
8855  elog(ERROR, "can't create a checkpoint during recovery");
8856 
8857  /*
8858  * Initialize InitXLogInsert working areas before entering the critical
8859  * section. Normally, this is done by the first call to
8860  * RecoveryInProgress() or LocalSetXLogInsertAllowed(), but when creating
8861  * an end-of-recovery checkpoint, the LocalSetXLogInsertAllowed call is
8862  * done below in a critical section, and InitXLogInsert cannot be called
8863  * in a critical section.
8864  */
8865  InitXLogInsert();
8866 
8867  /*
8868  * Acquire CheckpointLock to ensure only one checkpoint happens at a time.
8869  * (This is just pro forma, since in the present system structure there is
8870  * only one process that is allowed to issue checkpoints at any given
8871  * time.)
8872  */
8873  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
8874 
8875  /*
8876  * Prepare to accumulate statistics.
8877  *
8878  * Note: because it is possible for log_checkpoints to change while a
8879  * checkpoint proceeds, we always accumulate stats, even if
8880  * log_checkpoints is currently off.
8881  */
8882  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
8884 
8885  /*
8886  * Use a critical section to force system panic if we have trouble.
8887  */
8889 
8890  if (shutdown)
8891  {
8892  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8894  ControlFile->time = (pg_time_t) time(NULL);
8896  LWLockRelease(ControlFileLock);
8897  }
8898 
8899  /*
8900  * Let smgr prepare for checkpoint; this has to happen before we determine
8901  * the REDO pointer. Note that smgr must not do anything that'd have to
8902  * be undone if we decide no checkpoint is needed.
8903  */
8905 
8906  /* Begin filling in the checkpoint WAL record */
8907  MemSet(&checkPoint, 0, sizeof(checkPoint));
8908  checkPoint.time = (pg_time_t) time(NULL);
8909 
8910  /*
8911  * For Hot Standby, derive the oldestActiveXid before we fix the redo
8912  * pointer. This allows us to begin accumulating changes to assemble our
8913  * starting snapshot of locks and transactions.
8914  */
8915  if (!shutdown && XLogStandbyInfoActive())
8917  else
8919 
8920  /*
8921  * Get location of last important record before acquiring insert locks (as
8922  * GetLastImportantRecPtr() also locks WAL locks).
8923  */
8924  last_important_lsn = GetLastImportantRecPtr();
8925 
8926  /*
8927  * We must block concurrent insertions while examining insert state to
8928  * determine the checkpoint REDO pointer.
8929  */
8931  curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
8932 
8933  /*
8934  * If this isn't a shutdown or forced checkpoint, and if there has been no
8935  * WAL activity requiring a checkpoint, skip it. The idea here is to
8936  * avoid inserting duplicate checkpoints when the system is idle.
8937  */
8938  if ((flags & (CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_END_OF_RECOVERY |
8939  CHECKPOINT_FORCE)) == 0)
8940  {
8941  if (last_important_lsn == ControlFile->checkPoint)
8942  {
8944  LWLockRelease(CheckpointLock);
8945  END_CRIT_SECTION();
8946  ereport(DEBUG1,
8947  (errmsg("checkpoint skipped because system is idle")));
8948  return;
8949  }
8950  }
8951 
8952  /*
8953  * An end-of-recovery checkpoint is created before anyone is allowed to
8954  * write WAL. To allow us to write the checkpoint record, temporarily
8955  * enable XLogInsertAllowed. (This also ensures ThisTimeLineID is
8956  * initialized, which we need here and in AdvanceXLInsertBuffer.)
8957  */
8958  if (flags & CHECKPOINT_END_OF_RECOVERY)
8960 
8961  checkPoint.ThisTimeLineID = ThisTimeLineID;
8962  if (flags & CHECKPOINT_END_OF_RECOVERY)
8963  checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
8964  else
8965  checkPoint.PrevTimeLineID = ThisTimeLineID;
8966 
8967  checkPoint.fullPageWrites = Insert->fullPageWrites;
8968 
8969  /*
8970  * Compute new REDO record ptr = location of next XLOG record.
8971  *
8972  * NB: this is NOT necessarily where the checkpoint record itself will be,
8973  * since other backends may insert more XLOG records while we're off doing
8974  * the buffer flush work. Those XLOG records are logically after the
8975  * checkpoint, even though physically before it. Got that?
8976  */
8977  freespace = INSERT_FREESPACE(curInsert);
8978  if (freespace == 0)
8979  {
8980  if (XLogSegmentOffset(curInsert, wal_segment_size) == 0)
8981  curInsert += SizeOfXLogLongPHD;
8982  else
8983  curInsert += SizeOfXLogShortPHD;
8984  }
8985  checkPoint.redo = curInsert;
8986 
8987  /*
8988  * Here we update the shared RedoRecPtr for future XLogInsert calls; this
8989  * must be done while holding all the insertion locks.
8990  *
8991  * Note: if we fail to complete the checkpoint, RedoRecPtr will be left
8992  * pointing past where it really needs to point. This is okay; the only
8993  * consequence is that XLogInsert might back up whole buffers that it
8994  * didn't really need to. We can't postpone advancing RedoRecPtr because
8995  * XLogInserts that happen while we are dumping buffers must assume that
8996  * their buffer changes are not included in the checkpoint.
8997  */
8998  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
8999 
9000  /*
9001  * Now we can release the WAL insertion locks, allowing other xacts to
9002  * proceed while we are flushing disk buffers.
9003  */
9005 
9006  /* Update the info_lck-protected copy of RedoRecPtr as well */
9008  XLogCtl->RedoRecPtr = checkPoint.redo;
9010 
9011  /*
9012  * If enabled, log checkpoint start. We postpone this until now so as not
9013  * to log anything if we decided to skip the checkpoint.
9014  */
9015  if (log_checkpoints)
9016  LogCheckpointStart(flags, false);
9017 
9018  /* Update the process title */
9019  update_checkpoint_display(flags, false, false);
9020 
9021  TRACE_POSTGRESQL_CHECKPOINT_START(flags);
9022 
9023  /*
9024  * Get the other info we need for the checkpoint record.
9025  *
9026  * We don't need to save oldestClogXid in the checkpoint, it only matters
9027  * for the short period in which clog is being truncated, and if we crash
9028  * during that we'll redo the clog truncation and fix up oldestClogXid
9029  * there.
9030  */
9031  LWLockAcquire(XidGenLock, LW_SHARED);
9032  checkPoint.nextXid = ShmemVariableCache->nextXid;
9033  checkPoint.oldestXid = ShmemVariableCache->oldestXid;
9035  LWLockRelease(XidGenLock);
9036 
9037  LWLockAcquire(CommitTsLock, LW_SHARED);
9040  LWLockRelease(CommitTsLock);
9041 
9042  LWLockAcquire(OidGenLock, LW_SHARED);
9043  checkPoint.nextOid = ShmemVariableCache->nextOid;
9044  if (!shutdown)
9045  checkPoint.nextOid += ShmemVariableCache->oidCount;
9046  LWLockRelease(OidGenLock);
9047 
9048  MultiXactGetCheckptMulti(shutdown,
9049  &checkPoint.nextMulti,
9050  &checkPoint.nextMultiOffset,
9051  &checkPoint.oldestMulti,
9052  &checkPoint.oldestMultiDB);
9053 
9054  /*
9055  * Having constructed the checkpoint record, ensure all shmem disk buffers
9056  * and commit-log buffers are flushed to disk.
9057  *
9058  * This I/O could fail for various reasons. If so, we will fail to
9059  * complete the checkpoint, but there is no reason to force a system
9060  * panic. Accordingly, exit critical section while doing it.
9061  */
9062  END_CRIT_SECTION();
9063 
9064  /*
9065  * In some cases there are groups of actions that must all occur on one
9066  * side or the other of a checkpoint record. Before flushing the
9067  * checkpoint record we must explicitly wait for any backend currently
9068  * performing those groups of actions.
9069  *
9070  * One example is end of transaction, so we must wait for any transactions
9071  * that are currently in commit critical sections. If an xact inserted
9072  * its commit record into XLOG just before the REDO point, then a crash
9073  * restart from the REDO point would not replay that record, which means
9074  * that our flushing had better include the xact's update of pg_xact. So
9075  * we wait till he's out of his commit critical section before proceeding.
9076  * See notes in RecordTransactionCommit().
9077  *
9078  * Because we've already released the insertion locks, this test is a bit
9079  * fuzzy: it is possible that we will wait for xacts we didn't really need
9080  * to wait for. But the delay should be short and it seems better to make
9081  * checkpoint take a bit longer than to hold off insertions longer than
9082  * necessary. (In fact, the whole reason we have this issue is that xact.c
9083  * does commit record XLOG insertion and clog update as two separate steps
9084  * protected by different locks, but again that seems best on grounds of
9085  * minimizing lock contention.)
9086  *
9087  * A transaction that has not yet set delayChkpt when we look cannot be at
9088  * risk, since he's not inserted his commit record yet; and one that's
9089  * already cleared it is not at risk either, since he's done fixing clog
9090  * and we will correctly flush the update below. So we cannot miss any
9091  * xacts we need to wait for.
9092  */
9093  vxids = GetVirtualXIDsDelayingChkpt(&nvxids);
9094  if (nvxids > 0)
9095  {
9096  do
9097  {
9098  pg_usleep(10000L); /* wait for 10 msec */
9099  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids));
9100  }
9101  pfree(vxids);
9102 
9103  CheckPointGuts(checkPoint.redo, flags);
9104 
9105  /*
9106  * Take a snapshot of running transactions and write this to WAL. This
9107  * allows us to reconstruct the state of running transactions during
9108  * archive recovery, if required. Skip, if this info disabled.
9109  *
9110  * If we are shutting down, or Startup process is completing crash
9111  * recovery we don't need to write running xact data.
9112  */
9113  if (!shutdown && XLogStandbyInfoActive())
9115 
9117 
9118  /*
9119  * Now insert the checkpoint record into XLOG.
9120  */
9121  XLogBeginInsert();
9122  XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));
9123  recptr = XLogInsert(RM_XLOG_ID,
9124  shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
9126 
9127  XLogFlush(recptr);
9128 
9129  /*
9130  * We mustn't write any new WAL after a shutdown checkpoint, or it will be
9131  * overwritten at next startup. No-one should even try, this just allows
9132  * sanity-checking. In the case of an end-of-recovery checkpoint, we want
9133  * to just temporarily disable writing until the system has exited
9134  * recovery.
9135  */
9136  if (shutdown)
9137  {
9138  if (flags & CHECKPOINT_END_OF_RECOVERY)
9139  LocalXLogInsertAllowed = -1; /* return to "check" state */
9140  else
9141  LocalXLogInsertAllowed = 0; /* never again write WAL */
9142  }
9143 
9144  /*
9145  * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
9146  * = end of actual checkpoint record.
9147  */
9148  if (shutdown && checkPoint.redo != ProcLastRecPtr)
9149  ereport(PANIC,
9150  (errmsg("concurrent write-ahead log activity while database system is shutting down")));
9151 
9152  /*
9153  * Remember the prior checkpoint's redo ptr for
9154  * UpdateCheckPointDistanceEstimate()
9155  */
9156  PriorRedoPtr = ControlFile->checkPointCopy.redo;
9157 
9158  /*
9159  * Update the control file.
9160  */
9161  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9162  if (shutdown)
9165  ControlFile->checkPointCopy = checkPoint;
9166  ControlFile->time = (pg_time_t) time(NULL);
9167  /* crash recovery should always recover to the end of WAL */
9170 
9171  /*
9172  * Persist unloggedLSN value. It's reset on crash recovery, so this goes
9173  * unused on non-shutdown checkpoints, but seems useful to store it always
9174  * for debugging purposes.
9175  */
9179 
9181  LWLockRelease(ControlFileLock);
9182 
9183  /* Update shared-memory copy of checkpoint XID/epoch */
9185  XLogCtl->ckptFullXid = checkPoint.nextXid;
9187 
9188  /*
9189  * We are now done with critical updates; no need for system panic if we
9190  * have trouble while fooling with old log segments.
9191  */
9192  END_CRIT_SECTION();
9193 
9194  /*
9195  * Let smgr do post-checkpoint cleanup (eg, deleting old files).
9196  */
9198 
9199  /*
9200  * Update the average distance between checkpoints if the prior checkpoint
9201  * exists.
9202  */
9203  if (PriorRedoPtr != InvalidXLogRecPtr)
9205 
9206  /*
9207  * Delete old log files, those no longer needed for last checkpoint to
9208  * prevent the disk holding the xlog from growing full.
9209  */
9211  KeepLogSeg(recptr, &_logSegNo);
9213  _logSegNo--;
9214  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr);
9215 
9216  /*
9217  * Make more log segments if needed. (Do this after recycling old log
9218  * segments, since that may supply some of the needed files.)
9219  */
9220  if (!shutdown)
9221  PreallocXlogFiles(recptr);
9222 
9223  /*
9224  * Truncate pg_subtrans if possible. We can throw away all data before
9225  * the oldest XMIN of any running transaction. No future transaction will
9226  * attempt to reference any pg_subtrans entry older than that (see Asserts
9227  * in subtrans.c). During recovery, though, we mustn't do this because
9228  * StartupSUBTRANS hasn't been called yet.
9229  */
9230  if (!RecoveryInProgress())
9232 
9233  /* Real work is done, but log and update stats before releasing lock. */
9234  LogCheckpointEnd(false);
9235 
9236  /* Reset the process title */
9237  update_checkpoint_display(flags, false, true);
9238 
9239  TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
9240  NBuffers,
9244 
9245  LWLockRelease(CheckpointLock);
9246 }
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:8518
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8735
static int LocalXLogInsertAllowed
Definition: xlog.c:254
bool log_checkpoints
Definition: xlog.c:106
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define DEBUG1
Definition: elog.h:25
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1740
int wal_segment_size
Definition: xlog.c:118
pg_time_t time
Definition: pg_control.h:128
#define XLOG_CHECKPOINT_ONLINE
Definition: pg_control.h:68
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
uint32 oidCount
Definition: transam.h:208
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1578
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:2010
XLogRecPtr unloggedLSN
Definition: xlog.c:613
XLogRecPtr ProcLastRecPtr
Definition: xlog.c:361
TransactionId oldestActiveXid
Definition: pg_control.h:63
void InitXLogInsert(void)
Definition: xloginsert.c:1197
TimestampTz ckpt_start_t
Definition: xlog.h:246
slock_t info_lck
Definition: xlog.c:737
#define END_CRIT_SECTION()
Definition: miscadmin.h:135
VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids)
Definition: procarray.c:2946
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: xlog.c:654
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
#define START_CRIT_SECTION()
Definition: miscadmin.h:133
int ckpt_segs_recycled
Definition: xlog.h:256
TransactionId oldestXid
Definition: transam.h:215
#define MemSet(start, val, len)
Definition: c.h:996
void MultiXactGetCheckptMulti(bool is_shutdown, MultiXactId *nextMulti, MultiXactOffset *nextMultiOffset, MultiXactId *oldestMulti, Oid *oldestMultiDB)
Definition: multixact.c:2130
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:9307
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:601
TransactionId oldestXid
Definition: pg_control.h:47
bool RecoveryInProgress(void)
Definition: xlog.c:8148
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:338
FullTransactionId nextXid
Definition: transam.h:213
pg_time_t time
Definition: pg_control.h:51
#define PANIC
Definition: elog.h:55
bool fullPageWrites
Definition: xlog.c:576
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2860
static void update_checkpoint_display(int flags, bool restartpoint, bool reset)
Definition: xlog.c:8773
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1810
#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:4932
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
void pfree(void *pointer)
Definition: mcxt.c:1057
XLogRecPtr LogStandbySnapshot(void)
Definition: standby.c:1155
#define ERROR
Definition: elog.h:45
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8643
static XLogRecPtr RedoRecPtr
Definition: xlog.c:375
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
XLogRecPtr unloggedLSN
Definition: pg_control.h:133
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3923
uint64 XLogSegNo
Definition: xlogdefs.h:41
#define CHECKPOINT_END_OF_RECOVERY
Definition: xlog.h:222
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define InvalidTransactionId
Definition: transam.h:31
uint64 CurrBytePos
Definition: xlog.c:551
unsigned int uint32
Definition: c.h:429
XLogRecPtr RedoRecPtr
Definition: xlog.c:605
int ckpt_segs_removed
Definition: xlog.h:255
#define CHECKPOINT_FORCE
Definition: xlog.h:225
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:754
TransactionId oldestCommitTsXid
Definition: transam.h:225
static void Insert(File file)
Definition: fd.c:1203
int ckpt_bufs_written
Definition: xlog.h:252
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8292
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:330
#define SpinLockRelease(lock)
Definition: spin.h:64
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:422
TransactionId newestCommitTsXid
Definition: pg_control.h:54
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9738
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
Oid oldestMultiDB
Definition: pg_control.h:50
FullTransactionId ckptFullXid
Definition: xlog.c:606
#define XLogStandbyInfoActive()
Definition: xlog.h:205
static ControlFileData * ControlFile
Definition: xlog.c:748
TimeLineID ThisTimeLineID
Definition: xlog.c:193
Oid nextOid
Definition: pg_control.h:44
#define ereport(elevel,...)
Definition: elog.h:155
bool fullPageWrites
Definition: pg_control.h:42
uint64 XLogRecPtr
Definition: xlogdefs.h:21
Oid oldestXidDB
Definition: pg_control.h:48
TransactionId newestCommitTsXid
Definition: transam.h:226
CheckpointStatsData CheckpointStats
Definition: xlog.c:187
#define SizeOfXLogShortPHD
Definition: xlog_internal.h:52
MultiXactId nextMulti
Definition: pg_control.h:45
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1711
static XLogCtlData * XLogCtl
Definition: xlog.c:740
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206
TransactionId GetOldestTransactionIdConsideredRunning(void)
Definition: procarray.c:1937
int ckpt_segs_added
Definition: xlog.h:254
slock_t ulsn_lck
Definition: xlog.c:614
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
int errmsg(const char *fmt,...)
Definition: elog.c:915
void InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno)
Definition: slot.c:1155
#define elog(elevel,...)
Definition: elog.h:228
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr)
Definition: xlog.c:4054
void SyncPostCheckpoint(void)
Definition: sync.c:195
TransactionId GetOldestActiveTransactionId(void)
Definition: procarray.c:2785
int NBuffers
Definition: globals.c:133
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids)
Definition: procarray.c:2990
void XLogBeginInsert(void)
Definition: xloginsert.c:123
XLogRecPtr RedoRecPtr
Definition: xlog.c:574
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:37
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8611
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:221
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
void SyncPreCheckpoint(void)
Definition: sync.c:180
FullTransactionId nextXid
Definition: pg_control.h:43
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:69
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ CreateEndOfRecoveryRecord()

static void CreateEndOfRecoveryRecord ( void  )
static

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

9259 {
9260  xl_end_of_recovery xlrec;
9261  XLogRecPtr recptr;
9262 
9263  /* sanity check */
9264  if (!RecoveryInProgress())
9265  elog(ERROR, "can only be used to end recovery");
9266 
9267  xlrec.end_time = GetCurrentTimestamp();
9268 
9273 
9275 
9277 
9278  XLogBeginInsert();
9279  XLogRegisterData((char *) &xlrec, sizeof(xl_end_of_recovery));
9280  recptr = XLogInsert(RM_XLOG_ID, XLOG_END_OF_RECOVERY);
9281 
9282  XLogFlush(recptr);
9283 
9284  /*
9285  * Update the control file so that crash recovery can follow the timeline
9286  * changes to this point.
9287  */
9288  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9289  ControlFile->time = (pg_time_t) time(NULL);
9290  ControlFile->minRecoveryPoint = recptr;
9293  LWLockRelease(ControlFileLock);
9294 
9295  END_CRIT_SECTION();
9296 
9297  LocalXLogInsertAllowed = -1; /* return to "check" state */
9298 }
static int LocalXLogInsertAllowed
Definition: xlog.c:254
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1740
pg_time_t time
Definition: pg_control.h:128
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
TimeLineID PrevTimeLineID
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1578
#define END_CRIT_SECTION()
Definition: miscadmin.h:135
TimeLineID PrevTimeLineID
Definition: xlog.c:654
#define START_CRIT_SECTION()
Definition: miscadmin.h:133
bool RecoveryInProgress(void)
Definition: xlog.c:8148
#define XLOG_END_OF_RECOVERY
Definition: pg_control.h:76
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2860
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1810
void UpdateControlFile(void)
Definition: xlog.c:4932
#define ERROR
Definition: elog.h:45
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8292
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:330
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:422
static ControlFileData * ControlFile
Definition: xlog.c:748
TimeLineID ThisTimeLineID
Definition: xlog.c:193
TimestampTz end_time
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1711
static XLogCtlData * XLogCtl
Definition: xlog.c:740
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206
TimeLineID ThisTimeLineID
#define elog(elevel,...)
Definition: elog.h:228
void XLogBeginInsert(void)
Definition: xloginsert.c:123
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166

◆ CreateRestartPoint()

bool CreateRestartPoint ( int  flags)

Definition at line 9389 of file xlog.c.

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

Referenced by CheckpointerMain(), and ShutdownXLOG().

9390 {
9391  XLogRecPtr lastCheckPointRecPtr;
9392  XLogRecPtr lastCheckPointEndPtr;
9393  CheckPoint lastCheckPoint;
9394  XLogRecPtr PriorRedoPtr;
9395  XLogRecPtr receivePtr;
9396  XLogRecPtr replayPtr;
9397  TimeLineID replayTLI;
9398  XLogRecPtr endptr;
9399  XLogSegNo _logSegNo;
9400  TimestampTz xtime;
9401 
9402  /*
9403  * Acquire CheckpointLock to ensure only one restartpoint or checkpoint
9404  * happens at a time.
9405  */
9406  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
9407 
9408  /* Get a local copy of the last safe checkpoint record. */
9410  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
9411  lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
9412  lastCheckPoint = XLogCtl->lastCheckPoint;
9414 
9415  /*
9416  * Check that we're still in recovery mode. It's ok if we exit recovery
9417  * mode after this check, the restart point is valid anyway.
9418  */
9419  if (!RecoveryInProgress())
9420  {
9421  ereport(DEBUG2,
9422  (errmsg("skipping restartpoint, recovery has already ended")));
9423  LWLockRelease(CheckpointLock);
9424  return false;
9425  }
9426 
9427  /*
9428  * If the last checkpoint record we've replayed is already our last
9429  * restartpoint, we can't perform a new restart point. We still update
9430  * minRecoveryPoint in that case, so that if this is a shutdown restart
9431  * point, we won't start up earlier than before. That's not strictly
9432  * necessary, but when hot standby is enabled, it would be rather weird if
9433  * the database opened up for read-only connections at a point-in-time
9434  * before the last shutdown. Such time travel is still possible in case of
9435  * immediate shutdown, though.
9436  *
9437  * We don't explicitly advance minRecoveryPoint when we do create a
9438  * restartpoint. It's assumed that flushing the buffers will do that as a
9439  * side-effect.
9440  */
9441  if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
9442  lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
9443  {
9444  ereport(DEBUG2,
9445  (errmsg("skipping restartpoint, already performed at %X/%X",
9446  (uint32) (lastCheckPoint.redo >> 32),
9447  (uint32) lastCheckPoint.redo)));
9448 
9450  if (flags & CHECKPOINT_IS_SHUTDOWN)
9451  {
9452  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9454  ControlFile->time = (pg_time_t) time(NULL);
9456  LWLockRelease(ControlFileLock);
9457  }
9458  LWLockRelease(CheckpointLock);
9459  return false;
9460  }
9461 
9462  /*
9463  * Update the shared RedoRecPtr so that the startup process can calculate
9464  * the number of segments replayed since last restartpoint, and request a
9465  * restartpoint if it exceeds CheckPointSegments.
9466  *
9467  * Like in CreateCheckPoint(), hold off insertions to update it, although
9468  * during recovery this is just pro forma, because no WAL insertions are
9469  * happening.
9470  */
9472  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
9474 
9475  /* Also update the info_lck-protected copy */
9477  XLogCtl->RedoRecPtr = lastCheckPoint.redo;
9479 
9480  /*
9481  * Prepare to accumulate statistics.
9482  *
9483  * Note: because it is possible for log_checkpoints to change while a
9484  * checkpoint proceeds, we always accumulate stats, even if
9485  * log_checkpoints is currently off.
9486  */
9487  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
9489 
9490  if (log_checkpoints)
9491  LogCheckpointStart(flags, true);
9492 
9493  /* Update the process title */
9494  update_checkpoint_display(flags, true, false);
9495 
9496  CheckPointGuts(lastCheckPoint.redo, flags);
9497 
9498  /*
9499  * Remember the prior checkpoint's redo ptr for
9500  * UpdateCheckPointDistanceEstimate()
9501  */
9502  PriorRedoPtr = ControlFile->checkPointCopy.redo;
9503 
9504  /*
9505  * Update pg_control, using current time. Check that it still shows
9506  * DB_IN_ARCHIVE_RECOVERY state and an older checkpoint, else do nothing;
9507  * this is a quick hack to make sure nothing really bad happens if somehow
9508  * we get here after the end-of-recovery checkpoint.
9509  */
9510  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9512  ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
9513  {
9514  ControlFile->checkPoint = lastCheckPointRecPtr;
9515  ControlFile->checkPointCopy = lastCheckPoint;
9516  ControlFile->time = (pg_time_t) time(NULL);
9517 
9518  /*
9519  * Ensure minRecoveryPoint is past the checkpoint record. Normally,
9520  * this will have happened already while writing out dirty buffers,
9521  * but not necessarily - e.g. because no buffers were dirtied. We do
9522  * this because a non-exclusive base backup uses minRecoveryPoint to
9523  * determine which WAL files must be included in the backup, and the
9524  * file (or files) containing the checkpoint record must be included,
9525  * at a minimum. Note that for an ordinary restart of recovery there's
9526  * no value in having the minimum recovery point any earlier than this
9527  * anyway, because redo will begin just after the checkpoint record.
9528  */
9529  if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
9530  {
9531  ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
9533 
9534  /* update local copy */
9537  }
9538  if (flags & CHECKPOINT_IS_SHUTDOWN)
9541  }
9542  LWLockRelease(ControlFileLock);
9543 
9544  /*
9545  * Update the average distance between checkpoints/restartpoints if the
9546  * prior checkpoint exists.
9547  */
9548  if (PriorRedoPtr != InvalidXLogRecPtr)
9550 
9551  /*
9552  * Delete old log files, those no longer needed for last restartpoint to
9553  * prevent the disk holding the xlog from growing full.
9554  */
9556 
9557  /*
9558  * Retreat _logSegNo using the current end of xlog replayed or received,
9559  * whichever is later.
9560  */
9561  receivePtr = GetWalRcvFlushRecPtr(NULL, NULL);
9562  replayPtr = GetXLogReplayRecPtr(&replayTLI);
9563  endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
9564  KeepLogSeg(endptr, &_logSegNo);
9566  _logSegNo--;
9567 
9568  /*
9569  * Try to recycle segments on a useful timeline. If we've been promoted
9570  * since the beginning of this restartpoint, use the new timeline chosen
9571  * at end of recovery (RecoveryInProgress() sets ThisTimeLineID in that
9572  * case). If we're still in recovery, use the timeline we're currently
9573  * replaying.
9574  *
9575  * There is no guarantee that the WAL segments will be useful on the
9576  * current timeline; if recovery proceeds to a new timeline right after
9577  * this, the pre-allocated WAL segments on this timeline will not be used,
9578  * and will go wasted until recycled on the next restartpoint. We'll live
9579  * with that.
9580  */
9581  if (RecoveryInProgress())
9582  ThisTimeLineID = replayTLI;
9583 
9584  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr);
9585 
9586  /*
9587  * Make more log segments if needed. (Do this after recycling old log
9588  * segments, since that may supply some of the needed files.)
9589  */
9590  PreallocXlogFiles(endptr);
9591 
9592  /*
9593  * ThisTimeLineID is normally not set when we're still in recovery.
9594  * However, recycling/preallocating segments above needed ThisTimeLineID
9595  * to determine which timeline to install the segments on. Reset it now,
9596  * to restore the normal state of affairs for debugging purposes.
9597  */
9598  if (RecoveryInProgress())
9599  ThisTimeLineID = 0;
9600 
9601  /*
9602  * Truncate pg_subtrans if possible. We can throw away all data before
9603  * the oldest XMIN of any running transaction. No future transaction will
9604  * attempt to reference any pg_subtrans entry older than that (see Asserts
9605  * in subtrans.c). When hot standby is disabled, though, we mustn't do
9606  * this because StartupSUBTRANS hasn't been called yet.
9607  */
9608  if (EnableHotStandby)
9610 
9611  /* Real work is done, but log and update before releasing lock. */
9612  LogCheckpointEnd(true);
9613 
9614  /* Reset the process title */
9615  update_checkpoint_display(flags, true, true);
9616 
9617  xtime = GetLatestXTime();
9619  (errmsg("recovery restart point at %X/%X",
9620  (uint32) (lastCheckPoint.redo >> 32), (uint32) lastCheckPoint.redo),
9621  xtime ? errdetail("Last completed transaction was at log time %s.",
9622  timestamptz_to_str(xtime)) : 0));
9623 
9624  LWLockRelease(CheckpointLock);
9625 
9626  /*
9627  * Finally, execute archive_cleanup_command, if any.
9628  */
9629  if (archiveCleanupCommand && strcmp(archiveCleanupCommand, "") != 0)
9631  "archive_cleanup_command",
9632  false);
9633 
9634  return true;
9635 }
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8735
bool log_checkpoints
Definition: xlog.c:106
void ExecuteRecoveryCommand(const char *command, const char *commandName, bool failOnSignal)
Definition: xlogarchive.c:287
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
uint32 TimeLineID
Definition: xlogdefs.h:52
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1740
int wal_segment_size
Definition: xlog.c:118
pg_time_t time
Definition: pg_control.h:128
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1578
int64 TimestampTz
Definition: timestamp.h:39
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition: xlog.c:2773
TimestampTz ckpt_start_t
Definition: xlog.h:246
slock_t info_lck
Definition: xlog.c:737
#define MemSet(start, val, len)
Definition: c.h:996
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:9307
TimestampTz GetLatestXTime(void)
Definition: xlog.c:6198
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:601
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:8148
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:338
XLogRecPtr lastCheckPointRecPtr
Definition: xlog.c:706
static void update_checkpoint_display(int flags, bool restartpoint, bool reset)
Definition: xlog.c:8773
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1810
#define SpinLockAcquire(lock)
Definition: spin.h:62
void UpdateControlFile(void)
Definition: xlog.c:4932
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8643
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
Definition: xlog.c:11638
#define DEBUG2
Definition: elog.h:24
static XLogRecPtr RedoRecPtr
Definition: xlog.c:375
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3923
uint64 XLogSegNo
Definition: xlogdefs.h:41
int errdetail(const char *fmt,...)
Definition: elog.c:1048
unsigned int uint32
Definition: c.h:429
XLogRecPtr RedoRecPtr
Definition: xlog.c:605
CheckPoint lastCheckPoint
Definition: xlog.c:708
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
#define SpinLockRelease(lock)
Definition: spin.h:64
static TimeLineID minRecoveryPointTLI
Definition: xlog.c:873
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9738
static ControlFileData * ControlFile
Definition: xlog.c:748
TimeLineID ThisTimeLineID
Definition: xlog.c:193
#define ereport(elevel,...)
Definition: elog.h:155
uint64 XLogRecPtr
Definition: xlogdefs.h:21
CheckpointStatsData CheckpointStats
Definition: xlog.c:187
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1711
static XLogCtlData * XLogCtl
Definition: xlog.c:740
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206
TransactionId GetOldestTransactionIdConsideredRunning(void)
Definition: procarray.c:1937
XLogRecPtr GetWalRcvFlushRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI)
bool EnableHotStandby
Definition: xlog.c:98
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
int errmsg(const char *fmt,...)
Definition: elog.c:915
void InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno)
Definition: slot.c:1155
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr)
Definition: xlog.c:4054
XLogRecPtr RedoRecPtr
Definition: xlog.c:574
XLogRecPtr lastCheckPointEndPtr
Definition: xlog.c:707
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:37
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8611
char * archiveCleanupCommand
Definition: xlog.c:283
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:221
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:872
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1772
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ DataChecksumsEnabled()

bool DataChecksumsEnabled ( void  )

Definition at line 4961 of file xlog.c.

References Assert, and ControlFileData::data_checksum_version.

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

4962 {
4963  Assert(ControlFile != NULL);
4964  return (ControlFile->data_checksum_version > 0);
4965 }
uint32 data_checksum_version
Definition: pg_control.h:220
static ControlFileData * ControlFile
Definition: xlog.c:748
#define Assert(condition)
Definition: c.h:792

◆ do_pg_abort_backup()

void do_pg_abort_backup ( int  code,
Datum  arg 
)

Definition at line 11590 of file xlog.c.

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

Referenced by perform_base_backup(), and register_persistent_abort_backup_handler().

11591 {
11592  bool emit_warning = DatumGetBool(arg);
11593 
11594  /*
11595  * Quick exit if session is not keeping around a non-exclusive backup
11596  * already started.
11597  */
11599  return;
11600 
11604 
11607  {
11608  XLogCtl->Insert.forcePageWrites = false;
11609  }
11611 
11612  if (emit_warning)
11613  ereport(WARNING,
11614  (errmsg("aborting backup due to backend exiting before pg_stop_backup was called")));
11615 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1740
static SessionBackupState sessionBackupState
Definition: xlog.c:535
XLogCtlInsert Insert
Definition: xlog.c:601
bool forcePageWrites
Definition: xlog.c:575
#define DatumGetBool(X)
Definition: postgres.h:393
#define WARNING
Definition: elog.h:40
int nonExclusiveBackups
Definition: xlog.c:587
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:586
#define ereport(elevel,...)
Definition: elog.h:155
#define Assert(condition)
Definition: c.h:792
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1711
static XLogCtlData * XLogCtl
Definition: xlog.c:740
int errmsg(const char *fmt,...)
Definition: elog.c:915
void * arg

◆ do_pg_start_backup()

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

Definition at line 10659 of file xlog.c.

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

Referenced by perform_base_backup(), and pg_start_backup().

10662 {
10663  bool exclusive = (labelfile == NULL);
10664  bool backup_started_in_recovery = false;
10665  XLogRecPtr checkpointloc;
10666  XLogRecPtr startpoint;
10667  TimeLineID starttli;
10668  pg_time_t stamp_time;
10669  char strfbuf[128];
10670  char xlogfilename[MAXFNAMELEN];
10671  XLogSegNo _logSegNo;
10672  struct stat stat_buf;
10673  FILE *fp;
10674 
10675  backup_started_in_recovery = RecoveryInProgress();
10676 
10677  /*
10678  * Currently only non-exclusive backup can be taken during recovery.
10679  */
10680  if (backup_started_in_recovery && exclusive)
10681  ereport(ERROR,
10682  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10683  errmsg("recovery is in progress"),
10684  errhint("WAL control functions cannot be executed during recovery.")));
10685 
10686  /*
10687  * During recovery, we don't need to check WAL level. Because, if WAL
10688  * level is not sufficient, it's impossible to get here during recovery.
10689  */
10690  if (!backup_started_in_recovery && !XLogIsNeeded())
10691  ereport(ERROR,
10692  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10693  errmsg("WAL level not sufficient for making an online backup"),
10694  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
10695 
10696  if (strlen(backupidstr) > MAXPGPATH)
10697  ereport(ERROR,
10698  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
10699  errmsg("backup label too long (max %d bytes)",
10700  MAXPGPATH)));
10701 
10702  /*
10703  * Mark backup active in shared memory. We must do full-page WAL writes
10704  * during an on-line backup even if not doing so at other times, because
10705  * it's quite possible for the backup dump to obtain a "torn" (partially
10706  * written) copy of a database page if it reads the page concurrently with
10707  * our write to the same page. This can be fixed as long as the first
10708  * write to the page in the WAL sequence is a full-page write. Hence, we
10709  * turn on forcePageWrites and then force a CHECKPOINT, to ensure there
10710  * are no dirty pages in shared memory that might get dumped while the
10711  * backup is in progress without having a corresponding WAL record. (Once
10712  * the backup is complete, we need not force full-page writes anymore,
10713  * since we expect that any pages not modified during the backup interval
10714  * must have been correctly captured by the backup.)
10715  *
10716  * Note that forcePageWrites has no effect during an online backup from
10717  * the standby.
10718  *
10719  * We must hold all the insertion locks to change the value of
10720  * forcePageWrites, to ensure adequate interlocking against
10721  * XLogInsertRecord().
10722  */
10724  if (exclusive)
10725  {
10726  /*
10727  * At first, mark that we're now starting an exclusive backup, to
10728  * ensure that there are no other sessions currently running
10729  * pg_start_backup() or pg_stop_backup().
10730  */
10732  {
10734  ereport(ERROR,
10735  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10736  errmsg("a backup is already in progress"),
10737  errhint("Run pg_stop_backup() and try again.")));
10738  }
10740  }
10741  else
10743  XLogCtl->Insert.forcePageWrites = true;
10745 
10746  /* Ensure we release forcePageWrites if fail below */
10748  {
10749  bool gotUniqueStartpoint = false;
10750  DIR *tblspcdir;
10751  struct dirent *de;
10752  tablespaceinfo *ti;
10753  int datadirpathlen;
10754 
10755  /*
10756  * Force an XLOG file switch before the checkpoint, to ensure that the
10757  * WAL segment the checkpoint is written to doesn't contain pages with
10758  * old timeline IDs. That would otherwise happen if you called
10759  * pg_start_backup() right after restoring from a PITR archive: the
10760  * first WAL segment containing the startup checkpoint has pages in
10761  * the beginning with the old timeline ID. That can cause trouble at
10762  * recovery: we won't have a history file covering the old timeline if
10763  * pg_wal directory was not included in the base backup and the WAL
10764  * archive was cleared too before starting the backup.
10765  *
10766  * This also ensures that we have emitted a WAL page header that has
10767  * XLP_BKP_REMOVABLE off before we emit the checkpoint record.
10768  * Therefore, if a WAL archiver (such as pglesslog) is trying to
10769  * compress out removable backup blocks, it won't remove any that
10770  * occur after this point.
10771  *
10772  * During recovery, we skip forcing XLOG file switch, which means that
10773  * the backup taken during recovery is not available for the special
10774  * recovery case described above.
10775  */
10776  if (!backup_started_in_recovery)
10777  RequestXLogSwitch(false);
10778 
10779  do
10780  {
10781  bool checkpointfpw;
10782 
10783  /*
10784  * Force a CHECKPOINT. Aside from being necessary to prevent torn
10785  * page problems, this guarantees that two successive backup runs
10786  * will have different checkpoint positions and hence different
10787  * history file names, even if nothing happened in between.
10788  *
10789  * During recovery, establish a restartpoint if possible. We use
10790  * the last restartpoint as the backup starting checkpoint. This
10791  * means that two successive backup runs can have same checkpoint
10792  * positions.
10793  *
10794  * Since the fact that we are executing do_pg_start_backup()
10795  * during recovery means that checkpointer is running, we can use
10796  * RequestCheckpoint() to establish a restartpoint.
10797  *
10798  * We use CHECKPOINT_IMMEDIATE only if requested by user (via
10799  * passing fast = true). Otherwise this can take awhile.
10800  */
10802  (fast ? CHECKPOINT_IMMEDIATE : 0));
10803 
10804  /*
10805  * Now we need to fetch the checkpoint record location, and also
10806  * its REDO pointer. The oldest point in WAL that would be needed
10807  * to restore starting from the checkpoint is precisely the REDO
10808  * pointer.
10809  */
10810  LWLockAcquire(ControlFileLock, LW_SHARED);
10811  checkpointloc = ControlFile->checkPoint;
10812  startpoint = ControlFile->checkPointCopy.redo;
10814  checkpointfpw = ControlFile->checkPointCopy.fullPageWrites;
10815  LWLockRelease(ControlFileLock);
10816 
10817  if (backup_started_in_recovery)
10818  {
10819  XLogRecPtr recptr;
10820 
10821  /*
10822  * Check to see if all WAL replayed during online backup
10823  * (i.e., since last restartpoint used as backup starting
10824  * checkpoint) contain full-page writes.
10825  */
10827  recptr = XLogCtl->lastFpwDisableRecPtr;
10829 
10830  if (!checkpointfpw || startpoint <= recptr)
10831  ereport(ERROR,
10832  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10833  errmsg("WAL generated with full_page_writes=off was replayed "
10834  "since last restartpoint"),
10835  errhint("This means that the backup being taken on the standby "
10836  "is corrupt and should not be used. "
10837  "Enable full_page_writes and run CHECKPOINT on the primary, "
10838  "and then try an online backup again.")));
10839 
10840  /*
10841  * During recovery, since we don't use the end-of-backup WAL
10842  * record and don't write the backup history file, the
10843  * starting WAL location doesn't need to be unique. This means
10844  * that two base backups started at the same time might use
10845  * the same checkpoint as starting locations.
10846  */
10847  gotUniqueStartpoint = true;
10848  }
10849 
10850  /*
10851  * If two base backups are started at the same time (in WAL sender
10852  * processes), we need to make sure that they use different
10853  * checkpoints as starting locations, because we use the starting
10854  * WAL location as a unique identifier for the base backup in the
10855  * end-of-backup WAL record and when we write the backup history
10856  * file. Perhaps it would be better generate a separate unique ID
10857  * for each backup instead of forcing another checkpoint, but
10858  * taking a checkpoint right after another is not that expensive
10859  * either because only few buffers have been dirtied yet.
10860  */
10862  if (XLogCtl->Insert.lastBackupStart < startpoint)
10863  {
10864  XLogCtl->Insert.lastBackupStart = startpoint;
10865  gotUniqueStartpoint = true;
10866  }
10868  } while (!gotUniqueStartpoint);
10869 
10870  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
10871  XLogFileName(xlogfilename, starttli, _logSegNo, wal_segment_size);
10872 
10873  /*
10874  * Construct tablespace_map file
10875  */
10876  if (exclusive)
10877  tblspcmapfile = makeStringInfo();
10878 
10879  datadirpathlen = strlen(DataDir);
10880 
10881  /* Collect information about all tablespaces */
10882  tblspcdir = AllocateDir("pg_tblspc");
10883  while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL)
10884  {
10885  char fullpath[MAXPGPATH + 10];
10886  char linkpath[MAXPGPATH];
10887  char *relpath = NULL;
10888  int rllen;
10889  StringInfoData buflinkpath;
10890  char *s = linkpath;
10891 
10892  /* Skip special stuff */
10893  if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
10894  continue;
10895 
10896  snprintf(fullpath, sizeof(fullpath), "pg_tblspc/%s", de->d_name);
10897 
10898 #if defined(HAVE_READLINK) || defined(WIN32)
10899  rllen = readlink(fullpath, linkpath, sizeof(linkpath));
10900  if (rllen < 0)
10901  {
10902  ereport(WARNING,
10903  (errmsg("could not read symbolic link \"%s\": %m",
10904  fullpath)));
10905  continue;
10906  }
10907  else if (rllen >= sizeof(linkpath))
10908  {
10909  ereport(WARNING,
10910  (errmsg("symbolic link \"%s\" target is too long",
10911  fullpath)));
10912  continue;
10913  }
10914  linkpath[rllen] = '\0';
10915 
10916  /*
10917  * Add the escape character '\\' before newline in a string to
10918  * ensure that we can distinguish between the newline in the
10919  * tablespace path and end of line while reading tablespace_map
10920  * file during archive recovery.
10921  */
10922  initStringInfo(&buflinkpath);
10923 
10924  while (*s)
10925  {
10926  if ((*s == '\n' || *s == '\r') && needtblspcmapfile)
10927  appendStringInfoChar(&buflinkpath, '\\');
10928  appendStringInfoChar(&buflinkpath, *s++);
10929  }
10930 
10931  /*
10932  * Relpath holds the relative path of the tablespace directory
10933  * when it's located within PGDATA, or NULL if it's located
10934  * elsewhere.
10935  */
10936  if (rllen > datadirpathlen &&
10937  strncmp(linkpath, DataDir, datadirpathlen) == 0 &&
10938  IS_DIR_SEP(linkpath[datadirpathlen]))
10939  relpath = linkpath + datadirpathlen + 1;
10940 
10941  ti = palloc(sizeof(tablespaceinfo));
10942  ti->oid = pstrdup(de->d_name);
10943  ti->path = pstrdup(buflinkpath.data);
10944  ti->rpath = relpath ? pstrdup(relpath) : NULL;
10945  ti->size = -1;
10946 
10947  if (tablespaces)
10948  *tablespaces = lappend(*tablespaces, ti);
10949 
10950  appendStringInfo(tblspcmapfile, "%s %s\n", ti->oid, ti->path);
10951 
10952  pfree(buflinkpath.data);
10953 #else
10954 
10955  /*
10956  * If the platform does not have symbolic links, it should not be
10957  * possible to have tablespaces - clearly somebody else created
10958  * them. Warn about it and ignore.
10959  */
10960  ereport(WARNING,
10961  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
10962  errmsg("tablespaces are not supported on this platform")));
10963 #endif
10964  }
10965  FreeDir(tblspcdir);
10966 
10967  /*
10968  * Construct backup label file
10969  */
10970  if (exclusive)
10971  labelfile = makeStringInfo();
10972 
10973  /* Use the log timezone here, not the session timezone */
10974  stamp_time = (pg_time_t) time(NULL);
10975  pg_strftime(strfbuf, sizeof(strfbuf),
10976  "%Y-%m-%d %H:%M:%S %Z",
10977  pg_localtime(&stamp_time, log_timezone));
10978  appendStringInfo(labelfile, "START WAL LOCATION: %X/%X (file %s)\n",
10979  (uint32) (startpoint >> 32), (uint32) startpoint, xlogfilename);
10980  appendStringInfo(labelfile, "CHECKPOINT LOCATION: %X/%X\n",
10981  (uint32) (checkpointloc >> 32), (uint32) checkpointloc);
10982  appendStringInfo(labelfile, "BACKUP METHOD: %s\n",
10983  exclusive ? "pg_start_backup" : "streamed");
10984  appendStringInfo(labelfile, "BACKUP FROM: %s\n",
10985  backup_started_in_recovery ? "standby" : "primary");
10986  appendStringInfo(labelfile, "START TIME: %s\n", strfbuf);
10987  appendStringInfo(labelfile, "LABEL: %s\n", backupidstr);
10988  appendStringInfo(labelfile, "START TIMELINE: %u\n", starttli);
10989 
10990  /*
10991  * Okay, write the file, or return its contents to caller.
10992  */
10993  if (exclusive)
10994  {
10995  /*
10996  * Check for existing backup label --- implies a backup is already
10997  * running. (XXX given that we checked exclusiveBackupState
10998  * above, maybe it would be OK to just unlink any such label
10999  * file?)
11000  */
11001  if (stat(BACKUP_LABEL_FILE, &stat_buf) != 0)
11002  {
11003  if (errno != ENOENT)
11004  ereport(ERROR,
11006  errmsg("could not stat file \"%s\": %m",
11007  BACKUP_LABEL_FILE)));
11008  }
11009  else
11010  ereport(ERROR,
11011  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11012  errmsg("a backup is already in progress"),
11013  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
11014  BACKUP_LABEL_FILE)));
11015 
11016  fp = AllocateFile(BACKUP_LABEL_FILE, "w");
11017 
11018  if (!fp)
11019  ereport(ERROR,
11021  errmsg("could not create file \"%s\": %m",
11022  BACKUP_LABEL_FILE)));
11023  if (fwrite(labelfile->data, labelfile->len, 1, fp) != 1 ||
11024  fflush(fp) != 0 ||
11025  pg_fsync(fileno(fp)) != 0 ||
11026  ferror(fp) ||
11027  FreeFile(fp))
11028  ereport(ERROR,
11030  errmsg("could not write file \"%s\": %m",
11031  BACKUP_LABEL_FILE)));
11032  /* Allocated locally for exclusive backups, so free separately */
11033  pfree(labelfile->data);
11034  pfree(labelfile);
11035 
11036  /* Write backup tablespace_map file. */
11037  if (tblspcmapfile->len > 0)
11038  {
11039  if (stat(TABLESPACE_MAP, &stat_buf) != 0)
11040  {
11041  if (errno != ENOENT)
11042  ereport(ERROR,
11044  errmsg("could not stat file \"%s\": %m",
11045  TABLESPACE_MAP)));
11046  }
11047  else
11048  ereport(ERROR,
11049  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11050  errmsg("a backup is already in progress"),
11051  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
11052  TABLESPACE_MAP)));
11053 
11054  fp = AllocateFile(TABLESPACE_MAP, "w");
11055 
11056  if (!fp)
11057  ereport(ERROR,
11059  errmsg("could not create file \"%s\": %m",
11060  TABLESPACE_MAP)));
11061  if (fwrite(tblspcmapfile->data, tblspcmapfile->len, 1, fp) != 1 ||
11062  fflush(fp) != 0 ||
11063  pg_fsync(fileno(fp)) != 0 ||
11064  ferror(fp) ||
11065  FreeFile(fp))
11066  ereport(ERROR,
11068  errmsg("could not write file \"%s\": %m",
11069  TABLESPACE_MAP)));
11070  }
11071 
11072  /* Allocated locally for exclusive backups, so free separately */
11073  pfree(tblspcmapfile->data);
11074  pfree(tblspcmapfile);
11075  }
11076  }
11078 
11079  /*
11080  * Mark that start phase has correctly finished for an exclusive backup.
11081  * Session-level locks are updated as well to reflect that state.
11082  *
11083  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating backup
11084  * counters and session-level lock. Otherwise they can be updated
11085  * inconsistently, and which might cause do_pg_abort_backup() to fail.
11086  */
11087  if (exclusive)
11088  {
11091 
11092  /* Set session-level lock */
11095  }
11096  else
11098 
11099  /*
11100  * We're done. As a convenience, return the starting WAL location.
11101  */
11102  if (starttli_p)
11103  *starttli_p = starttli;
11104  return startpoint;
11105 }
size_t pg_strftime(char *s, size_t max, const char *format, const struct pg_tm *tm)
Definition: strftime.c:128
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9831
int errhint(const char *fmt,...)
Definition: elog.c:1162
uint32 TimeLineID
Definition: xlogdefs.h:52
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1740
int wal_segment_size
Definition: xlog.c:118
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:735
static SessionBackupState sessionBackupState
Definition: xlog.c:535
XLogRecPtr lastBackupStart
Definition: xlog.c:588
char * pstrdup(const char *in)
Definition: mcxt.c:1187
#define XLogIsNeeded()
Definition: xlog.h:191
char * rpath
Definition: basebackup.h:27
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
slock_t info_lck
Definition: xlog.c:737
int errcode(int sqlerrcode)
Definition: elog.c:704
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:601
bool RecoveryInProgress(void)
Definition: xlog.c:8148
static bool backup_started_in_recovery
Definition: basebackup.c:88
Definition: dirent.h:9
#define IS_DIR_SEP(ch)
Definition: port.h:84
pg_tz * log_timezone
Definition: pgtz.c:31
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1810
#define TABLESPACE_MAP
Definition: xlog.h:392
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:47
void pfree(void *pointer)
Definition: mcxt.c:1057
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
bool forcePageWrites
Definition: xlog.c:575
Definition: dirent.c:25
#define ERROR
Definition: elog.h:45
struct stat stat_buf
Definition: pg_standby.c:100
#define MAXPGPATH
uint64 XLogSegNo
Definition: xlogdefs.h:41
#define readlink(path, buf, size)
Definition: win32_port.h:228
int errcode_for_file_access(void)
Definition: elog.c:727
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2354
unsigned int uint32
Definition: c.h:429
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2615
#define CHECKPOINT_FORCE
Definition: xlog.h:225
List * lappend(List *list, void *datum)
Definition: list.c:321
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define WARNING
Definition: elog.h:40
int nonExclusiveBackups
Definition: xlog.c:587
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
static void pg_start_backup_callback(int code, Datum arg)
Definition: xlog.c:11109
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:586
uintptr_t Datum
Definition: postgres.h:367
static ControlFileData * ControlFile
Definition: xlog.c:748
#define BoolGetDatum(X)
Definition: postgres.h:402
#define ereport(elevel,...)
Definition: elog.h:155
bool fullPageWrites
Definition: pg_control.h:42
#define CHECKPOINT_WAIT
Definition: xlog.h:229
uint64 XLogRecPtr
Definition: xlogdefs.h:21
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2681
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1711
static XLogCtlData * XLogCtl
Definition: xlog.c:740
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206
#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:52
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1342
int FreeFile(FILE *file)
Definition: fd.c:2553
void * palloc(Size size)
Definition: mcxt.c:950
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:224
#define relpath(rnode, forknum)
Definition: relpath.h:87
char * DataDir
Definition: globals.c:63
#define BACKUP_LABEL_FILE
Definition: xlog.h:389
int pg_fsync(int fd)
Definition: fd.c:347
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:215
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:37
int FreeDir(DIR *dir)
Definition: fd.c:2733
#define stat
Definition: win32_port.h:275
void RequestCheckpoint(int flags)
Definition: checkpointer.c:916
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ do_pg_stop_backup()

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

Definition at line 11177 of file xlog.c.

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

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

11178 {
11179  bool exclusive = (labelfile == NULL);
11180  bool backup_started_in_recovery = false;
11181  XLogRecPtr startpoint;
11182  XLogRecPtr stoppoint;
11183  TimeLineID stoptli;
11184  pg_time_t stamp_time;
11185  char strfbuf[128];
11186  char histfilepath[MAXPGPATH];
11187  char startxlogfilename[MAXFNAMELEN];
11188  char stopxlogfilename[MAXFNAMELEN];
11189  char lastxlogfilename[MAXFNAMELEN];
11190  char histfilename[MAXFNAMELEN];
11191  char backupfrom[20];
11192  XLogSegNo _logSegNo;
11193  FILE *lfp;
11194  FILE *fp;
11195  char ch;
11196  int seconds_before_warning;
11197  int waits = 0;
11198  bool reported_waiting = false;
11199  char *remaining;
11200  char *ptr;
11201  uint32 hi,
11202  lo;
11203 
11204  backup_started_in_recovery = RecoveryInProgress();
11205 
11206  /*
11207  * Currently only non-exclusive backup can be taken during recovery.
11208  */
11209  if (backup_started_in_recovery && exclusive)
11210  ereport(ERROR,
11211  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11212  errmsg("recovery is in progress"),
11213  errhint("WAL control functions cannot be executed during recovery.")));
11214 
11215  /*
11216  * During recovery, we don't need to check WAL level. Because, if WAL
11217  * level is not sufficient, it's impossible to get here during recovery.
11218  */
11219  if (!backup_started_in_recovery && !XLogIsNeeded())
11220  ereport(ERROR,
11221  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11222  errmsg("WAL level not sufficient for making an online backup"),
11223  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
11224 
11225  if (exclusive)
11226  {
11227  /*
11228  * At first, mark that we're now stopping an exclusive backup, to
11229  * ensure that there are no other sessions currently running
11230  * pg_start_backup() or pg_stop_backup().
11231  */
11234  {
11236  ereport(ERROR,
11237  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11238  errmsg("exclusive backup not in progress")));
11239  }
11242 
11243  /*
11244  * Remove backup_label. In case of failure, the state for an exclusive
11245  * backup is switched back to in-progress.
11246  */
11248  {
11249  /*
11250  * Read the existing label file into memory.
11251  */
11252  struct stat statbuf;
11253  int r;
11254 
11255  if (stat(BACKUP_LABEL_FILE, &statbuf))
11256  {
11257  /* should not happen per the upper checks */
11258  if (errno != ENOENT)
11259  ereport(ERROR,
11261  errmsg("could not stat file \"%s\": %m",
11262  BACKUP_LABEL_FILE)));
11263  ereport(ERROR,
11264  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11265  errmsg("a backup is not in progress")));
11266  }
11267 
11268  lfp = AllocateFile(BACKUP_LABEL_FILE, "r");
11269  if (!lfp)
11270  {
11271  ereport(ERROR,
11273  errmsg("could not read file \"%s\": %m",
11274  BACKUP_LABEL_FILE)));
11275  }
11276  labelfile = palloc(statbuf.st_size + 1);
11277  r = fread(labelfile, statbuf.st_size, 1, lfp);
11278  labelfile[statbuf.st_size] = '\0';
11279 
11280  /*
11281  * Close and remove the backup label file
11282  */
11283  if (r != 1 || ferror(lfp) || FreeFile(lfp))
11284  ereport(ERROR,
11286  errmsg("could not read file \"%s\": %m",
11287  BACKUP_LABEL_FILE)));
11289 
11290  /*
11291  * Remove tablespace_map file if present, it is created only if
11292  * there are tablespaces.
11293  */
11295  }
11297  }
11298 
11299  /*
11300  * OK to update backup counters, forcePageWrites and session-level lock.
11301  *
11302  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating them.
11303  * Otherwise they can be updated inconsistently, and which might cause
11304  * do_pg_abort_backup() to fail.
11305  */
11307  if (exclusive)
11308  {
11310  }
11311  else
11312  {
11313  /*
11314  * The user-visible pg_start/stop_backup() functions that operate on
11315  * exclusive backups can be called at any time, but for non-exclusive
11316  * backups, it is expected that each do_pg_start_backup() call is
11317  * matched by exactly one do_pg_stop_backup() call.
11318  */
11321  }
11322 
11325  {
11326  XLogCtl->Insert.forcePageWrites = false;
11327  }
11328 
11329  /*
11330  * Clean up session-level lock.
11331  *
11332  * You might think that WALInsertLockRelease() can be called before
11333  * cleaning up session-level lock because session-level lock doesn't need
11334  * to be protected with WAL insertion lock. But since
11335  * CHECK_FOR_INTERRUPTS() can occur in it, session-level lock must be
11336  * cleaned up before it.
11337  */
11339 
11341 
11342  /*
11343  * Read and parse the START WAL LOCATION line (this code is pretty crude,
11344  * but we are not expecting any variability in the file format).
11345  */
11346  if (sscanf(labelfile, "START WAL LOCATION: %X/%X (file %24s)%c",
11347  &hi, &lo, startxlogfilename,
11348  &ch) != 4 || ch != '\n')
11349  ereport(ERROR,
11350  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11351  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
11352  startpoint = ((uint64) hi) << 32 | lo;
11353  remaining = strchr(labelfile, '\n') + 1; /* %n is not portable enough */
11354 
11355  /*
11356  * Parse the BACKUP FROM line. If we are taking an online backup from the
11357  * standby, we confirm that the standby has not been promoted during the
11358  * backup.
11359  */
11360  ptr = strstr(remaining, "BACKUP FROM:");
11361  if (!ptr || sscanf(ptr, "BACKUP FROM: %19s\n", backupfrom) != 1)
11362  ereport(ERROR,
11363  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11364  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
11365  if (strcmp(backupfrom, "standby") == 0 && !backup_started_in_recovery)
11366  ereport(ERROR,
11367  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11368  errmsg("the standby was promoted during online backup"),
11369  errhint("This means that the backup being taken is corrupt "
11370  "and should not be used. "
11371  "Try taking another online backup.")));
11372 
11373  /*
11374  * During recovery, we don't write an end-of-backup record. We assume that
11375  * pg_control was backed up last and its minimum recovery point can be
11376  * available as the backup end location. Since we don't have an
11377  * end-of-backup record, we use the pg_control value to check whether
11378  * we've reached the end of backup when starting recovery from this
11379  * backup. We have no way of checking if pg_control wasn't backed up last
11380  * however.
11381  *
11382  * We don't force a switch to new WAL file but it is still possible to
11383  * wait for all the required files to be archived if waitforarchive is
11384  * true. This is okay if we use the backup to start a standby and fetch
11385  * the missing WAL using streaming replication. But in the case of an
11386  * archive recovery, a user should set waitforarchive to true and wait for
11387  * them to be archived to ensure that all the required files are
11388  * available.
11389  *
11390  * We return the current minimum recovery point as the backup end
11391  * location. Note that it can be greater than the exact backup end
11392  * location if the minimum recovery point is updated after the backup of
11393  * pg_control. This is harmless for current uses.
11394  *
11395  * XXX currently a backup history file is for informational and debug
11396  * purposes only. It's not essential for an online backup. Furthermore,
11397  * even if it's created, it will not be archived during recovery because
11398  * an archiver is not invoked. So it doesn't seem worthwhile to write a
11399  * backup history file during recovery.
11400  */
11401  if (backup_started_in_recovery)
11402  {
11403  XLogRecPtr recptr;
11404 
11405  /*
11406  * Check to see if all WAL replayed during online backup contain
11407  * full-page writes.
11408  */
11410  recptr = XLogCtl->lastFpwDisableRecPtr;
11412 
11413  if (startpoint <= recptr)
11414  ereport(ERROR,
11415  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11416  errmsg("WAL generated with full_page_writes=off was replayed "
11417  "during online backup"),
11418  errhint("This means that the backup being taken on the standby "
11419  "is corrupt and should not be used. "
11420  "Enable full_page_writes and run CHECKPOINT on the primary, "
11421  "and then try an online backup again.")));
11422 
11423 
11424  LWLockAcquire(ControlFileLock, LW_SHARED);
11425  stoppoint = ControlFile->minRecoveryPoint;
11426  stoptli = ControlFile->minRecoveryPointTLI;
11427  LWLockRelease(ControlFileLock);
11428  }
11429  else
11430  {
11431  /*
11432  * Write the backup-end xlog record
11433  */
11434  XLogBeginInsert();
11435  XLogRegisterData((char *) (&startpoint), sizeof(startpoint));
11436  stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
11437  stoptli = ThisTimeLineID;
11438 
11439  /*
11440  * Force a switch to a new xlog segment file, so that the backup is
11441  * valid as soon as archiver moves out the current segment file.
11442  */
11443  RequestXLogSwitch(false);
11444 
11445  XLByteToPrevSeg(stoppoint, _logSegNo, wal_segment_size);
11446  XLogFileName(stopxlogfilename, stoptli, _logSegNo, wal_segment_size);
11447 
11448  /* Use the log timezone here, not the session timezone */
11449  stamp_time = (pg_time_t) time(NULL);
11450  pg_strftime(strfbuf, sizeof(strfbuf),
11451  "%Y-%m-%d %H:%M:%S %Z",
11452  pg_localtime(&stamp_time, log_timezone));
11453 
11454  /*
11455  * Write the backup history file
11456  */
11457  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
11458  BackupHistoryFilePath(histfilepath, stoptli, _logSegNo,
11459  startpoint, wal_segment_size);
11460  fp = AllocateFile(histfilepath, "w");
11461  if (!fp)
11462  ereport(ERROR,
11464  errmsg("could not create file \"%s\": %m",
11465  histfilepath)));
11466  fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n",
11467  (uint32) (startpoint >> 32), (uint32) startpoint, startxlogfilename);
11468  fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
11469  (uint32) (stoppoint >> 32), (uint32) stoppoint, stopxlogfilename);
11470 
11471  /*
11472  * Transfer remaining lines including label and start timeline to
11473  * history file.
11474  */
11475  fprintf(fp, "%s", remaining);
11476  fprintf(fp, "STOP TIME: %s\n", strfbuf);
11477  fprintf(fp, "STOP TIMELINE: %u\n", stoptli);
11478  if (fflush(fp) || ferror(fp) || FreeFile(fp))
11479  ereport(ERROR,
11481  errmsg("could not write file \"%s\": %m",
11482  histfilepath)));
11483 
11484  /*
11485  * Clean out any no-longer-needed history files. As a side effect,
11486  * this will post a .ready file for the newly created history file,
11487  * notifying the archiver that history file may be archived
11488  * immediately.
11489  */
11491  }
11492 
11493  /*
11494  * If archiving is enabled, wait for all the required WAL files to be
11495  * archived before returning. If archiving isn't enabled, the required WAL
11496  * needs to be transported via streaming replication (hopefully with
11497  * wal_keep_size set high enough), or some more exotic mechanism like
11498  * polling and copying files from pg_wal with script. We have no knowledge
11499  * of those mechanisms, so it's up to the user to ensure that he gets all
11500  * the required WAL.
11501  *
11502  * We wait until both the last WAL file filled during backup and the
11503  * history file have been archived, and assume that the alphabetic sorting
11504  * property of the WAL files ensures any earlier WAL files are safely
11505  * archived as well.
11506  *
11507  * We wait forever, since archive_command is supposed to work and we
11508  * assume the admin wanted his backup to work completely. If you don't
11509  * wish to wait, then either waitforarchive should be passed in as false,
11510  * or you can set statement_timeout. Also, some notices are issued to
11511  * clue in anyone who might be doing this interactively.
11512  */
11513 
11514  if (waitforarchive &&
11515  ((!backup_started_in_recovery && XLogArchivingActive()) ||
11516  (backup_started_in_recovery && XLogArchivingAlways())))
11517  {
11518  XLByteToPrevSeg(stoppoint, _logSegNo, wal_segment_size);
11519  XLogFileName(lastxlogfilename, stoptli, _logSegNo, wal_segment_size);
11520 
11521  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
11522  BackupHistoryFileName(histfilename, stoptli, _logSegNo,
11523  startpoint, wal_segment_size);
11524 
11525  seconds_before_warning = 60;
11526  waits = 0;
11527 
11528  while (XLogArchiveIsBusy(lastxlogfilename) ||
11529  XLogArchiveIsBusy(histfilename))
11530  {
11532 
11533  if (!reported_waiting && waits > 5)
11534  {
11535  ereport(NOTICE,
11536  (errmsg("base backup done, waiting for required WAL segments to be archived")));
11537  reported_waiting = true;
11538  }
11539 
11541  pg_usleep(1000000L);
11543 
11544  if (++waits >= seconds_before_warning)
11545  {
11546  seconds_before_warning *= 2; /* This wraps in >10 years... */
11547  ereport(WARNING,
11548  (errmsg("still waiting for all required WAL segments to be archived (%d seconds elapsed)",
11549  waits),
11550  errhint("Check that your archive_command is executing properly. "
11551  "You can safely cancel this backup, "
11552  "but the database backup will not be usable without all the WAL segments.")));
11553  }
11554  }
11555 
11556  ereport(NOTICE,
11557  (errmsg("all required WAL segments have been archived")));
11558  }
11559  else if (waitforarchive)
11560  ereport(NOTICE,
11561  (errmsg("WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup")));
11562 
11563  /*
11564  * We're done. As a convenience, return the ending WAL location.
11565  */
11566  if (stoptli_p)
11567  *stoptli_p = stoptli;
11568  return stoppoint;
11569 }
int remaining
Definition: informix.c:667
size_t pg_strftime(char *s, size_t max, const char *format, const struct pg_tm *tm)
Definition: strftime.c:128
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9831
#define DEBUG1
Definition: elog.h:25
int errhint(const char *fmt,...)
Definition: elog.c:1162
uint32 TimeLineID
Definition: xlogdefs.h:52
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1740
int wal_segment_size
Definition: xlog.c:118
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:735
static SessionBackupState sessionBackupState
Definition: xlog.c:535
#define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes)
#define XLogIsNeeded()
Definition: xlog.h:191
slock_t info_lck
Definition: xlog.c:737
int errcode(int sqlerrcode)
Definition: elog.c:704
XLogCtlInsert Insert
Definition: xlog.c:601
#define BackupHistoryFileName(fname, tli, logSegNo, startpoint, wal_segsz_bytes)
bool RecoveryInProgress(void)
Definition: xlog.c:8148
static bool backup_started_in_recovery
Definition: basebackup.c:88
#define fprintf
Definition: port.h:219
pg_tz * log_timezone
Definition: pgtz.c:31
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1810
#define TABLESPACE_MAP
Definition: xlog.h:392
#define SpinLockAcquire(lock)
Definition: spin.h:62
void pg_usleep(long microsec)
Definition: signal.c:53
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:47
#define XLogArchivingAlways()
Definition: xlog.h:183
bool forcePageWrites
Definition: xlog.c:575
#define ERROR
Definition: elog.h:45
static void CleanupBackupHistory(void)
Definition: xlog.c:4320
#define MAXPGPATH
uint64 XLogSegNo
Definition: xlogdefs.h:41
int errcode_for_file_access(void)
Definition: elog.c:727
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2354
unsigned int uint32
Definition: c.h:429
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1512
#define XLOG_BACKUP_END
Definition: pg_control.h:72
#define WARNING
Definition: elog.h:40
int nonExclusiveBackups
Definition: xlog.c:587
#define MAXFNAMELEN
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:330
#define SpinLockRelease(lock)
Definition: spin.h:64
#define BackupHistoryFilePath(path, tli, logSegNo, startpoint, wal_segsz_bytes)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:422
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:586
uintptr_t Datum
Definition: postgres.h:367
static ControlFileData * ControlFile
Definition: xlog.c:748
#define BoolGetDatum(X)
Definition: postgres.h:402
TimeLineID ThisTimeLineID
Definition: xlog.c:193
#define ereport(elevel,...)
Definition: elog.h:155
#define NOTICE
Definition: elog.h:37
bool XLogArchiveIsBusy(const char *xlog)
Definition: xlogarchive.c:626
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:792
#define XLogArchivingActive()
Definition: xlog.h:180
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1488
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1711
static XLogCtlData * XLogCtl
Definition: xlog.c:740
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206
static void pg_stop_backup_callback(int code, Datum arg)
Definition: xlog.c:11138
#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:52
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1342
int durable_unlink(const char *fname, int elevel)
Definition: fd.c:777
int FreeFile(FILE *file)
Definition: fd.c:2553
void * palloc(Size size)
Definition: mcxt.c:950
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define BACKUP_LABEL_FILE
Definition: xlog.h:389
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:100
void XLogBeginInsert(void)
Definition: xloginsert.c:123
#define stat
Definition: win32_port.h:275
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ emode_for_corrupt_record()

static int emode_for_corrupt_record ( int  emode,
XLogRecPtr  RecPtr 
)
static

Definition at line 12696 of file xlog.c.

References DEBUG1, LOG, readSource, and XLOG_FROM_PG_WAL.

Referenced by ReadRecord(), and XLogPageRead().

12697 {
12698  static XLogRecPtr lastComplaint = 0;
12699 
12700  if (readSource == XLOG_FROM_PG_WAL && emode == LOG)
12701  {
12702  if (RecPtr == lastComplaint)
12703  emode = DEBUG1;
12704  else
12705  lastComplaint = RecPtr;
12706  }
12707  return emode;
12708 }
#define DEBUG1
Definition: elog.h:25
static XLogSource readSource
Definition: xlog.c:827
#define LOG
Definition: elog.h:26
uint64 XLogRecPtr
Definition: xlogdefs.h:21

◆ exitArchiveRecovery()

static void exitArchiveRecovery ( TimeLineID  endTLI,
XLogRecPtr  endOfLog 
)
static

Definition at line 5574 of file xlog.c.

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

Referenced by StartupXLOG().

5575 {
5576  char xlogfname[MAXFNAMELEN];
5577  XLogSegNo endLogSegNo;
5578  XLogSegNo startLogSegNo;
5579 
5580  /* we always switch to a new timeline after archive recovery */
5581  Assert(endTLI != ThisTimeLineID);
5582 
5583  /*
5584  * We are no longer in archive recovery state.
5585  */
5586  InArchiveRecovery = false;
5587 
5588  /*
5589  * Update min recovery point one last time.
5590  */
5592 
5593  /*
5594  * If the ending log segment is still open, close it (to avoid problems on
5595  * Windows with trying to rename or delete an open file).
5596  */
5597  if (readFile >= 0)
5598  {
5599  close(readFile);
5600  readFile = -1;
5601  }
5602 
5603  /*
5604  * Calculate the last segment on the old timeline, and the first segment
5605  * on the new timeline. If the switch happens in the middle of a segment,
5606  * they are the same, but if the switch happens exactly at a segment
5607  * boundary, startLogSegNo will be endLogSegNo + 1.
5608  */
5609  XLByteToPrevSeg(endOfLog, endLogSegNo, wal_segment_size);
5610  XLByteToSeg(endOfLog, startLogSegNo, wal_segment_size);
5611 
5612  /*
5613  * Initialize the starting WAL segment for the new timeline. If the switch
5614  * happens in the middle of a segment, copy data from the last WAL segment
5615  * of the old timeline up to the switch point, to the starting WAL segment
5616  * on the new timeline.
5617  */
5618  if (endLogSegNo == startLogSegNo)
5619  {
5620  /*
5621  * Make a copy of the file on the new timeline.
5622  *
5623  * Writing WAL isn't allowed yet, so there are no locking
5624  * considerations. But we should be just as tense as XLogFileInit to
5625  * avoid emplacing a bogus file.
5626  */
5627  XLogFileCopy(endLogSegNo, endTLI, endLogSegNo,
5628  XLogSegmentOffset(endOfLog, wal_segment_size));
5629  }
5630  else
5631  {
5632  /*
5633  * The switch happened at a segment boundary, so just create the next
5634  * segment on the new timeline.
5635  */
5636  bool use_existent = true;
5637  int fd;
5638 
5639  fd = XLogFileInit(startLogSegNo, &use_existent, true);
5640 
5641  if (close(fd) != 0)
5642  {
5643  char xlogfname[MAXFNAMELEN];
5644  int save_errno = errno;
5645 
5646  XLogFileName(xlogfname, ThisTimeLineID, startLogSegNo,
5648  errno = save_errno;
5649