PostgreSQL Source Code  git master
xlog.h File Reference
#include "access/rmgr.h"
#include "access/xlogdefs.h"
#include "access/xloginsert.h"
#include "access/xlogreader.h"
#include "datatype/timestamp.h"
#include "lib/stringinfo.h"
#include "nodes/pg_list.h"
#include "storage/fd.h"
Include dependency graph for xlog.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  CheckpointStatsData
 

Macros

#define SYNC_METHOD_FSYNC   0
 
#define SYNC_METHOD_FDATASYNC   1
 
#define SYNC_METHOD_OPEN   2 /* for O_SYNC */
 
#define SYNC_METHOD_FSYNC_WRITETHROUGH   3
 
#define SYNC_METHOD_OPEN_DSYNC   4 /* for O_DSYNC */
 
#define XLogArchivingActive()   (AssertMacro(XLogArchiveMode == ARCHIVE_MODE_OFF || wal_level >= WAL_LEVEL_REPLICA), XLogArchiveMode > ARCHIVE_MODE_OFF)
 
#define XLogArchivingAlways()   (AssertMacro(XLogArchiveMode == ARCHIVE_MODE_OFF || wal_level >= WAL_LEVEL_REPLICA), XLogArchiveMode == ARCHIVE_MODE_ALWAYS)
 
#define XLogArchiveCommandSet()   (XLogArchiveCommand[0] != '\0')
 
#define XLogIsNeeded()   (wal_level >= WAL_LEVEL_REPLICA)
 
#define XLogHintBitIsNeeded()   (DataChecksumsEnabled() || wal_log_hints)
 
#define XLogStandbyInfoActive()   (wal_level >= WAL_LEVEL_REPLICA)
 
#define XLogLogicalInfoActive()   (wal_level >= WAL_LEVEL_LOGICAL)
 
#define CHECKPOINT_IS_SHUTDOWN   0x0001 /* Checkpoint is for shutdown */
 
#define CHECKPOINT_END_OF_RECOVERY
 
#define CHECKPOINT_IMMEDIATE   0x0004 /* Do it without delays */
 
#define CHECKPOINT_FORCE   0x0008 /* Force even if no activity */
 
#define CHECKPOINT_FLUSH_ALL
 
#define CHECKPOINT_WAIT   0x0020 /* Wait for completion */
 
#define CHECKPOINT_REQUESTED   0x0040 /* Checkpoint request has been made */
 
#define CHECKPOINT_CAUSE_XLOG   0x0080 /* XLOG consumption */
 
#define CHECKPOINT_CAUSE_TIME   0x0100 /* Elapsed time */
 
#define XLOG_INCLUDE_ORIGIN   0x01 /* include the replication origin */
 
#define XLOG_MARK_UNIMPORTANT   0x02 /* record not important for durability */
 
#define XLOG_INCLUDE_XID   0x04 /* include XID of top-level xact */
 
#define RECOVERY_SIGNAL_FILE   "recovery.signal"
 
#define STANDBY_SIGNAL_FILE   "standby.signal"
 
#define BACKUP_LABEL_FILE   "backup_label"
 
#define BACKUP_LABEL_OLD   "backup_label.old"
 
#define TABLESPACE_MAP   "tablespace_map"
 
#define TABLESPACE_MAP_OLD   "tablespace_map.old"
 
#define PROMOTE_SIGNAL_FILE   "promote"
 

Typedefs

typedef enum ArchiveMode ArchiveMode
 
typedef enum WalLevel WalLevel
 
typedef enum WalCompression WalCompression
 
typedef enum RecoveryState RecoveryState
 
typedef enum RecoveryPauseState RecoveryPauseState
 
typedef struct CheckpointStatsData CheckpointStatsData
 
typedef enum WALAvailability WALAvailability
 
typedef enum SessionBackupState SessionBackupState
 

Enumerations

enum  RecoveryTargetType {
  RECOVERY_TARGET_UNSET, RECOVERY_TARGET_XID, RECOVERY_TARGET_TIME, RECOVERY_TARGET_NAME,
  RECOVERY_TARGET_LSN, RECOVERY_TARGET_IMMEDIATE
}
 
enum  RecoveryTargetTimeLineGoal { RECOVERY_TARGET_TIMELINE_CONTROLFILE, RECOVERY_TARGET_TIMELINE_LATEST, RECOVERY_TARGET_TIMELINE_NUMERIC }
 
enum  ArchiveMode { ARCHIVE_MODE_OFF = 0, ARCHIVE_MODE_ON, ARCHIVE_MODE_ALWAYS }
 
enum  WalLevel { WAL_LEVEL_MINIMAL = 0, WAL_LEVEL_REPLICA, WAL_LEVEL_LOGICAL }
 
enum  WalCompression { WAL_COMPRESSION_NONE = 0, WAL_COMPRESSION_PGLZ, WAL_COMPRESSION_LZ4 }
 
enum  RecoveryState { RECOVERY_STATE_CRASH = 0, RECOVERY_STATE_ARCHIVE, RECOVERY_STATE_DONE }
 
enum  RecoveryPauseState { RECOVERY_NOT_PAUSED, RECOVERY_PAUSE_REQUESTED, RECOVERY_PAUSED }
 
enum  WALAvailability {
  WALAVAIL_INVALID_LSN, WALAVAIL_RESERVED, WALAVAIL_EXTENDED, WALAVAIL_UNRESERVED,
  WALAVAIL_REMOVED
}
 
enum  SessionBackupState { SESSION_BACKUP_NONE, SESSION_BACKUP_EXCLUSIVE, SESSION_BACKUP_NON_EXCLUSIVE }
 

Functions

XLogRecPtr XLogInsertRecord (struct XLogRecData *rdata, XLogRecPtr fpw_lsn, uint8 flags, int num_fpi)
 
void XLogFlush (XLogRecPtr RecPtr)
 
bool XLogBackgroundFlush (void)
 
bool XLogNeedsFlush (XLogRecPtr RecPtr)
 
int XLogFileInit (XLogSegNo segno)
 
int XLogFileOpen (XLogSegNo segno)
 
void CheckXLogRemoved (XLogSegNo segno, TimeLineID tli)
 
XLogSegNo XLogGetLastRemovedSegno (void)
 
void XLogSetAsyncXactLSN (XLogRecPtr record)
 
void XLogSetReplicationSlotMinimumLSN (XLogRecPtr lsn)
 
void xlog_redo (XLogReaderState *record)
 
void xlog_desc (StringInfo buf, XLogReaderState *record)
 
const char * xlog_identify (uint8 info)
 
void issue_xlog_fsync (int fd, XLogSegNo segno)
 
bool RecoveryInProgress (void)
 
RecoveryState GetRecoveryState (void)
 
bool HotStandbyActive (void)
 
bool HotStandbyActiveInReplay (void)
 
bool XLogInsertAllowed (void)
 
void GetXLogReceiptTime (TimestampTz *rtime, bool *fromStream)
 
XLogRecPtr GetXLogReplayRecPtr (TimeLineID *replayTLI)
 
XLogRecPtr GetXLogInsertRecPtr (void)
 
XLogRecPtr GetXLogWriteRecPtr (void)
 
RecoveryPauseState GetRecoveryPauseState (void)
 
void SetRecoveryPause (bool recoveryPause)
 
TimestampTz GetLatestXTime (void)
 
TimestampTz GetCurrentChunkReplayStartTime (void)
 
void UpdateControlFile (void)
 
uint64 GetSystemIdentifier (void)
 
char * GetMockAuthenticationNonce (void)
 
bool DataChecksumsEnabled (void)
 
XLogRecPtr GetFakeLSNForUnloggedRel (void)
 
Size XLOGShmemSize (void)
 
void XLOGShmemInit (void)
 
void BootStrapXLOG (void)
 
void LocalProcessControlFile (bool reset)
 
void StartupXLOG (void)
 
void ShutdownXLOG (int code, Datum arg)
 
void InitXLOGAccess (void)
 
void CreateCheckPoint (int flags)
 
bool CreateRestartPoint (int flags)
 
WALAvailability GetWALAvailability (XLogRecPtr targetLSN)
 
XLogRecPtr CalculateMaxmumSafeLSN (void)
 
void XLogPutNextOid (Oid nextOid)
 
XLogRecPtr XLogRestorePoint (const char *rpName)
 
void UpdateFullPageWrites (void)
 
void GetFullPageWriteInfo (XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p)
 
XLogRecPtr GetRedoRecPtr (void)
 
XLogRecPtr GetInsertRecPtr (void)
 
XLogRecPtr GetFlushRecPtr (void)
 
XLogRecPtr GetLastImportantRecPtr (void)
 
void RemovePromoteSignalFiles (void)
 
bool PromoteIsTriggered (void)
 
bool CheckPromoteSignal (void)
 
void WakeupRecovery (void)
 
void SetWalWriterSleeping (bool sleeping)
 
void StartupRequestWalReceiverRestart (void)
 
void XLogRequestWalReceiverReply (void)
 
void assign_max_wal_size (int newval, void *extra)
 
void assign_checkpoint_completion_target (double newval, void *extra)
 
XLogRecPtr do_pg_start_backup (const char *backupidstr, bool fast, TimeLineID *starttli_p, StringInfo labelfile, List **tablespaces, StringInfo tblspcmapfile)
 
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)
 
SessionBackupState get_backup_status (void)
 

Variables

int sync_method
 
PGDLLIMPORT TimeLineID ThisTimeLineID
 
XLogRecPtr ProcLastRecPtr
 
XLogRecPtr XactLastRecEnd
 
PGDLLIMPORT XLogRecPtr XactLastCommitEnd
 
bool reachedConsistency
 
int wal_segment_size
 
int min_wal_size_mb
 
int max_wal_size_mb
 
int wal_keep_size_mb
 
int max_slot_wal_keep_size_mb
 
int XLOGbuffers
 
int XLogArchiveTimeout
 
int wal_retrieve_retry_interval
 
char * XLogArchiveCommand
 
bool EnableHotStandby
 
bool fullPageWrites
 
bool wal_log_hints
 
int wal_compression
 
bool wal_init_zero
 
bool wal_recycle
 
boolwal_consistency_checking
 
char * wal_consistency_checking_string
 
bool log_checkpoints
 
char * recoveryRestoreCommand
 
char * recoveryEndCommand
 
char * archiveCleanupCommand
 
bool recoveryTargetInclusive
 
int recoveryTargetAction
 
int recovery_min_apply_delay
 
char * PrimaryConnInfo
 
char * PrimarySlotName
 
bool wal_receiver_create_temp_slot
 
bool track_wal_io_timing
 
TransactionId recoveryTargetXid
 
char * recovery_target_time_string
 
const char * recoveryTargetName
 
XLogRecPtr recoveryTargetLSN
 
RecoveryTargetType recoveryTarget
 
char * PromoteTriggerFile
 
RecoveryTargetTimeLineGoal recoveryTargetTimeLineGoal
 
TimeLineID recoveryTargetTLIRequested
 
TimeLineID recoveryTargetTLI
 
int CheckPointSegments
 
bool StandbyModeRequested
 
bool StandbyMode
 
int XLogArchiveMode
 
PGDLLIMPORT int wal_level
 
CheckpointStatsData CheckpointStats
 

Macro Definition Documentation

◆ BACKUP_LABEL_FILE

#define BACKUP_LABEL_FILE   "backup_label"

◆ BACKUP_LABEL_OLD

#define BACKUP_LABEL_OLD   "backup_label.old"

Definition at line 364 of file xlog.h.

Referenced by CancelBackup(), and StartupXLOG().

◆ CHECKPOINT_CAUSE_TIME

#define CHECKPOINT_CAUSE_TIME   0x0100 /* Elapsed time */

Definition at line 208 of file xlog.h.

Referenced by CheckpointerMain(), and LogCheckpointStart().

◆ CHECKPOINT_CAUSE_XLOG

#define CHECKPOINT_CAUSE_XLOG   0x0080 /* XLOG consumption */

Definition at line 207 of file xlog.h.

Referenced by CheckpointerMain(), LogCheckpointStart(), XLogPageRead(), and XLogWrite().

◆ CHECKPOINT_END_OF_RECOVERY

#define CHECKPOINT_END_OF_RECOVERY
Value:
0x0002 /* Like shutdown checkpoint, but
* issued at end of WAL recovery */

Definition at line 197 of file xlog.h.

Referenced by BufferSync(), CheckpointerMain(), CreateCheckPoint(), LogCheckpointStart(), StartupXLOG(), and update_checkpoint_display().

◆ CHECKPOINT_FLUSH_ALL

#define CHECKPOINT_FLUSH_ALL
Value:
0x0010 /* Flush all pages, including those
* belonging to unlogged tables */

Definition at line 201 of file xlog.h.

Referenced by BufferSync(), createdb(), LogCheckpointStart(), and movedb().

◆ CHECKPOINT_FORCE

#define CHECKPOINT_FORCE   0x0008 /* Force even if no activity */

◆ CHECKPOINT_IMMEDIATE

◆ CHECKPOINT_IS_SHUTDOWN

#define CHECKPOINT_IS_SHUTDOWN   0x0001 /* Checkpoint is for shutdown */

◆ CHECKPOINT_REQUESTED

#define CHECKPOINT_REQUESTED   0x0040 /* Checkpoint request has been made */

Definition at line 205 of file xlog.h.

Referenced by RequestCheckpoint().

◆ CHECKPOINT_WAIT

#define CHECKPOINT_WAIT   0x0020 /* Wait for completion */

◆ PROMOTE_SIGNAL_FILE

#define PROMOTE_SIGNAL_FILE   "promote"

Definition at line 370 of file xlog.h.

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

◆ RECOVERY_SIGNAL_FILE

#define RECOVERY_SIGNAL_FILE   "recovery.signal"

Definition at line 361 of file xlog.h.

Referenced by exitArchiveRecovery(), and readRecoverySignalFile().

◆ STANDBY_SIGNAL_FILE

#define STANDBY_SIGNAL_FILE   "standby.signal"

Definition at line 362 of file xlog.h.

Referenced by exitArchiveRecovery(), and readRecoverySignalFile().

◆ SYNC_METHOD_FDATASYNC

#define SYNC_METHOD_FDATASYNC   1

Definition at line 26 of file xlog.h.

Referenced by get_sync_bit(), and issue_xlog_fsync().

◆ SYNC_METHOD_FSYNC

#define SYNC_METHOD_FSYNC   0

Definition at line 25 of file xlog.h.

Referenced by get_sync_bit(), and issue_xlog_fsync().

◆ SYNC_METHOD_FSYNC_WRITETHROUGH

#define SYNC_METHOD_FSYNC_WRITETHROUGH   3

Definition at line 28 of file xlog.h.

Referenced by get_sync_bit(), issue_xlog_fsync(), and pg_fsync().

◆ SYNC_METHOD_OPEN

#define SYNC_METHOD_OPEN   2 /* for O_SYNC */

Definition at line 27 of file xlog.h.

Referenced by get_sync_bit(), issue_xlog_fsync(), and XLogWrite().

◆ SYNC_METHOD_OPEN_DSYNC

#define SYNC_METHOD_OPEN_DSYNC   4 /* for O_DSYNC */

Definition at line 29 of file xlog.h.

Referenced by get_sync_bit(), issue_xlog_fsync(), and XLogWrite().

◆ TABLESPACE_MAP

#define TABLESPACE_MAP   "tablespace_map"

◆ TABLESPACE_MAP_OLD

#define TABLESPACE_MAP_OLD   "tablespace_map.old"

Definition at line 367 of file xlog.h.

Referenced by CancelBackup(), and StartupXLOG().

◆ XLOG_INCLUDE_ORIGIN

#define XLOG_INCLUDE_ORIGIN   0x01 /* include the replication origin */

◆ XLOG_INCLUDE_XID

#define XLOG_INCLUDE_XID   0x04 /* include XID of top-level xact */

Definition at line 215 of file xlog.h.

Referenced by XLogRecordAssemble(), and XLogResetInsertion().

◆ XLOG_MARK_UNIMPORTANT

#define XLOG_MARK_UNIMPORTANT   0x02 /* record not important for durability */

◆ XLogArchiveCommandSet

#define XLogArchiveCommandSet ( )    (XLogArchiveCommand[0] != '\0')

Definition at line 160 of file xlog.h.

Referenced by pgarch_ArchiverCopyLoop(), and ShutdownXLOG().

◆ XLogArchivingActive

◆ XLogArchivingAlways

Definition at line 158 of file xlog.h.

Referenced by do_pg_stop_backup(), sigusr1_handler(), and XLogArchiveCheckDone().

◆ XLogHintBitIsNeeded

◆ XLogIsNeeded

◆ XLogLogicalInfoActive

◆ XLogStandbyInfoActive

Typedef Documentation

◆ ArchiveMode

typedef enum ArchiveMode ArchiveMode

◆ CheckpointStatsData

◆ RecoveryPauseState

◆ RecoveryState

◆ SessionBackupState

◆ WALAvailability

◆ WalCompression

◆ WalLevel

typedef enum WalLevel WalLevel

Enumeration Type Documentation

◆ ArchiveMode

Enumerator
ARCHIVE_MODE_OFF 
ARCHIVE_MODE_ON 
ARCHIVE_MODE_ALWAYS 

Definition at line 112 of file xlog.h.

113 {
114  ARCHIVE_MODE_OFF = 0, /* disabled */
115  ARCHIVE_MODE_ON, /* enabled while server is running normally */
116  ARCHIVE_MODE_ALWAYS /* enabled always (even during recovery) */
117 } ArchiveMode;
ArchiveMode
Definition: xlog.h:112

◆ RecoveryPauseState

Enumerator
RECOVERY_NOT_PAUSED 
RECOVERY_PAUSE_REQUESTED 
RECOVERY_PAUSED 

Definition at line 145 of file xlog.h.

146 {
147  RECOVERY_NOT_PAUSED, /* pause not requested */
148  RECOVERY_PAUSE_REQUESTED, /* pause requested, but not yet paused */
149  RECOVERY_PAUSED /* recovery is paused */
RecoveryPauseState
Definition: xlog.h:145

◆ RecoveryState

Enumerator
RECOVERY_STATE_CRASH 
RECOVERY_STATE_ARCHIVE 
RECOVERY_STATE_DONE 

Definition at line 137 of file xlog.h.

138 {
139  RECOVERY_STATE_CRASH = 0, /* crash recovery */
140  RECOVERY_STATE_ARCHIVE, /* archive recovery */
141  RECOVERY_STATE_DONE /* currently in production */
142 } RecoveryState;
RecoveryState
Definition: xlog.h:137

◆ RecoveryTargetTimeLineGoal

Enumerator
RECOVERY_TARGET_TIMELINE_CONTROLFILE 
RECOVERY_TARGET_TIMELINE_LATEST 
RECOVERY_TARGET_TIMELINE_NUMERIC 

Definition at line 51 of file xlog.h.

◆ RecoveryTargetType

Enumerator
RECOVERY_TARGET_UNSET 
RECOVERY_TARGET_XID 
RECOVERY_TARGET_TIME 
RECOVERY_TARGET_NAME 
RECOVERY_TARGET_LSN 
RECOVERY_TARGET_IMMEDIATE 

Definition at line 38 of file xlog.h.

◆ SessionBackupState

Enumerator
SESSION_BACKUP_NONE 
SESSION_BACKUP_EXCLUSIVE 
SESSION_BACKUP_NON_EXCLUSIVE 

Definition at line 344 of file xlog.h.

◆ WALAvailability

Enumerator
WALAVAIL_INVALID_LSN 
WALAVAIL_RESERVED 
WALAVAIL_EXTENDED 
WALAVAIL_UNRESERVED 
WALAVAIL_REMOVED 

Definition at line 246 of file xlog.h.

247 {
248  WALAVAIL_INVALID_LSN, /* parameter error */
249  WALAVAIL_RESERVED, /* WAL segment is within max_wal_size */
250  WALAVAIL_EXTENDED, /* WAL segment is reserved by a slot or
251  * wal_keep_size */
252  WALAVAIL_UNRESERVED, /* no longer reserved, but not removed yet */
253  WALAVAIL_REMOVED /* WAL segment has been removed */
WALAvailability
Definition: xlog.h:246

◆ WalCompression

Enumerator
WAL_COMPRESSION_NONE 
WAL_COMPRESSION_PGLZ 
WAL_COMPRESSION_LZ4 

Definition at line 129 of file xlog.h.

◆ WalLevel

enum WalLevel
Enumerator
WAL_LEVEL_MINIMAL 
WAL_LEVEL_REPLICA 
WAL_LEVEL_LOGICAL 

Definition at line 121 of file xlog.h.

Function Documentation

◆ assign_checkpoint_completion_target()

void assign_checkpoint_completion_target ( double  newval,
void *  extra 
)

Definition at line 2330 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

2331 {
2334 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2294
#define newval
double CheckPointCompletionTarget
Definition: checkpointer.c:148

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2323 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

2324 {
2327 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2294
int max_wal_size_mb
Definition: xlog.c:91
#define newval

◆ BootStrapXLOG()

void BootStrapXLOG ( void  )

Definition at line 5246 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, FirstGenbkiObjectId, FirstMultiXactId, FirstNormalTransactionId, CheckPoint::fullPageWrites, fullPageWrites, FullTransactionIdFromEpochAndXid(), gettimeofday(), INIT_CRC32C, InitControlFile(), XLogCtlData::InstallXLogFileSegmentActive, InvalidTransactionId, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), 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().

5247 {
5248  CheckPoint checkPoint;
5249  char *buffer;
5250  XLogPageHeader page;
5251  XLogLongPageHeader longpage;
5252  XLogRecord *record;
5253  char *recptr;
5254  uint64 sysidentifier;
5255  struct timeval tv;
5256  pg_crc32c crc;
5257 
5258  /* allow ordinary WAL segment creation, like StartupXLOG() would */
5259  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
5261  LWLockRelease(ControlFileLock);
5262 
5263  /*
5264  * Select a hopefully-unique system identifier code for this installation.
5265  * We use the result of gettimeofday(), including the fractional seconds
5266  * field, as being about as unique as we can easily get. (Think not to
5267  * use random(), since it hasn't been seeded and there's no portable way
5268  * to seed it other than the system clock value...) The upper half of the
5269  * uint64 value is just the tv_sec part, while the lower half contains the
5270  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
5271  * PID for a little extra uniqueness. A person knowing this encoding can
5272  * determine the initialization time of the installation, which could
5273  * perhaps be useful sometimes.
5274  */
5275  gettimeofday(&tv, NULL);
5276  sysidentifier = ((uint64) tv.tv_sec) << 32;
5277  sysidentifier |= ((uint64) tv.tv_usec) << 12;
5278  sysidentifier |= getpid() & 0xFFF;
5279 
5280  /* First timeline ID is always 1 */
5281  ThisTimeLineID = 1;
5282 
5283  /* page buffer must be aligned suitably for O_DIRECT */
5284  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
5285  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
5286  memset(page, 0, XLOG_BLCKSZ);
5287 
5288  /*
5289  * Set up information for the initial checkpoint record
5290  *
5291  * The initial checkpoint record is written to the beginning of the WAL
5292  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5293  * used, so that we can use 0/0 to mean "before any valid WAL segment".
5294  */
5295  checkPoint.redo = wal_segment_size + SizeOfXLogLongPHD;
5296  checkPoint.ThisTimeLineID = ThisTimeLineID;
5297  checkPoint.PrevTimeLineID = ThisTimeLineID;
5298  checkPoint.fullPageWrites = fullPageWrites;
5299  checkPoint.nextXid =
5301  checkPoint.nextOid = FirstGenbkiObjectId;
5302  checkPoint.nextMulti = FirstMultiXactId;
5303  checkPoint.nextMultiOffset = 0;
5304  checkPoint.oldestXid = FirstNormalTransactionId;
5305  checkPoint.oldestXidDB = TemplateDbOid;
5306  checkPoint.oldestMulti = FirstMultiXactId;
5307  checkPoint.oldestMultiDB = TemplateDbOid;
5310  checkPoint.time = (pg_time_t) time(NULL);
5312 
5313  ShmemVariableCache->nextXid = checkPoint.nextXid;
5314  ShmemVariableCache->nextOid = checkPoint.nextOid;
5316  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5317  AdvanceOldestClogXid(checkPoint.oldestXid);
5318  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5319  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5321 
5322  /* Set up the XLOG page header */
5323  page->xlp_magic = XLOG_PAGE_MAGIC;
5324  page->xlp_info = XLP_LONG_HEADER;
5325  page->xlp_tli = ThisTimeLineID;
5327  longpage = (XLogLongPageHeader) page;
5328  longpage->xlp_sysid = sysidentifier;
5329  longpage->xlp_seg_size = wal_segment_size;
5330  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5331 
5332  /* Insert the initial checkpoint record */
5333  recptr = ((char *) page + SizeOfXLogLongPHD);
5334  record = (XLogRecord *) recptr;
5335  record->xl_prev = 0;
5336  record->xl_xid = InvalidTransactionId;
5337  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5339  record->xl_rmid = RM_XLOG_ID;
5340  recptr += SizeOfXLogRecord;
5341  /* fill the XLogRecordDataHeaderShort struct */
5342  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5343  *(recptr++) = sizeof(checkPoint);
5344  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5345  recptr += sizeof(checkPoint);
5346  Assert(recptr - (char *) record == record->xl_tot_len);
5347 
5348  INIT_CRC32C(crc);
5349  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5350  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5351  FIN_CRC32C(crc);
5352  record->xl_crc = crc;
5353 
5354  /* Create first XLOG segment file */
5356 
5357  /*
5358  * We needn't bother with Reserve/ReleaseExternalFD here, since we'll
5359  * close the file again in a moment.
5360  */
5361 
5362  /* Write the first page with the initial record */
5363  errno = 0;
5365  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5366  {
5367  /* if write didn't set errno, assume problem is no disk space */
5368  if (errno == 0)
5369  errno = ENOSPC;
5370  ereport(PANIC,
5372  errmsg("could not write bootstrap write-ahead log file: %m")));
5373  }
5375 
5377  if (pg_fsync(openLogFile) != 0)
5378  ereport(PANIC,
5380  errmsg("could not fsync bootstrap write-ahead log file: %m")));
5382 
5383  if (close(openLogFile) != 0)
5384  ereport(PANIC,
5386  errmsg("could not close bootstrap write-ahead log file: %m")));
5387 
5388  openLogFile = -1;
5389 
5390  /* Now create pg_control */
5391  InitControlFile(sysidentifier);
5392  ControlFile->time = checkPoint.time;
5393  ControlFile->checkPoint = checkPoint.redo;
5394  ControlFile->checkPointCopy = checkPoint;
5395 
5396  /* some additional ControlFile fields are set in WriteControlFile() */
5397  WriteControlFile();
5398 
5399  /* Bootstrap the commit log, too */
5400  BootStrapCLOG();
5404 
5405  pfree(buffer);
5406 
5407  /*
5408  * Force control file to be read - in contrast to normal processing we'd
5409  * otherwise never run the checks and GUC related initializations therein.
5410  */
5411  ReadControlFile();
5412 }
static void WriteControlFile(void)
Definition: xlog.c:4661
#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
static void pgstat_report_wait_end(void)
Definition: wait_event.h:278
int wal_segment_size
Definition: xlog.c:119
pg_time_t time
Definition: pg_control.h:128
void SetCommitTsLimit(TransactionId oldestXact, TransactionId newestXact)
Definition: commit_ts.c:877
uint32 oidCount
Definition: transam.h:215
#define write(a, b, c)
Definition: win32.h:14
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:204
uint32 pg_crc32c
Definition: pg_crc32c.h:38
TransactionId oldestActiveXid
Definition: pg_control.h:63
void BootStrapMultiXact(void)
Definition: multixact.c:1894
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
static void InitControlFile(uint64 sysidentifier)
Definition: xlog.c:4626
int XLogFileInit(XLogSegNo logsegno)
Definition: xlog.c:3448
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:220
pg_time_t time
Definition: pg_control.h:51
#define PANIC
Definition: elog.h:50
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:71
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1803
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:1169
#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:4752
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
int errcode_for_file_access(void)
Definition: elog.c:721
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define InvalidTransactionId
Definition: transam.h:31
#define FirstMultiXactId
Definition: multixact.h:25
bool InstallXLogFileSegmentActive
Definition: xlog.c:654
TimeLineID xlp_tli
Definition: xlog_internal.h:40
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:262
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:798
static ControlFileData * ControlFile
Definition: xlog.c:737
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
Definition: multixact.c:2213
TimeLineID ThisTimeLineID
Definition: xlog.c:194
Oid nextOid
Definition: pg_control.h:44
#define ereport(elevel,...)
Definition: elog.h:157
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:750
bool fullPageWrites
Definition: pg_control.h:42
void BootStrapCLOG(void)
Definition: clog.c:712
#define Assert(condition)
Definition: c.h:804
#define XLP_LONG_HEADER
Definition: xlog_internal.h:76
Oid oldestXidDB
Definition: pg_control.h:48
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 XLogCtlData * XLogCtl
Definition: xlog.c:729
static FullTransactionId FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
Definition: transam.h:71
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1199
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:227
TransactionId xl_xid
Definition: xlogrecord.h:44
#define FirstGenbkiObjectId
Definition: transam.h:195
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
int pg_fsync(int fd)
Definition: fd.c:352
#define close(a)
Definition: win32.h:12
void BootStrapCommitTs(void)
Definition: commit_ts.c:570
#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:727
FullTransactionId nextXid
Definition: pg_control.h:43
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:69
void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset)
Definition: multixact.c:2179

◆ CalculateMaxmumSafeLSN()

XLogRecPtr CalculateMaxmumSafeLSN ( void  )

◆ CheckPromoteSignal()

bool CheckPromoteSignal ( void  )

Definition at line 12963 of file xlog.c.

References PROMOTE_SIGNAL_FILE, and stat.

Referenced by CheckForStandbyTrigger(), and sigusr1_handler().

12964 {
12965  struct stat stat_buf;
12966 
12967  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
12968  return true;
12969 
12970  return false;
12971 }
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:370
#define stat
Definition: win32_port.h:275

◆ CheckXLogRemoved()

void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)

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

3976 {
3977  int save_errno = errno;
3978  XLogSegNo lastRemovedSegNo;
3979 
3981  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3983 
3984  if (segno <= lastRemovedSegNo)
3985  {
3986  char filename[MAXFNAMELEN];
3987 
3988  XLogFileName(filename, tli, segno, wal_segment_size);
3989  errno = save_errno;
3990  ereport(ERROR,
3992  errmsg("requested WAL segment %s has already been removed",
3993  filename)));
3994  }
3995  errno = save_errno;
3996 }
int wal_segment_size
Definition: xlog.c:119
slock_t info_lck
Definition: xlog.c:726
XLogSegNo lastRemovedSegNo
Definition: xlog.c:588
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define ERROR
Definition: elog.h:46
uint64 XLogSegNo
Definition: xlogdefs.h:48
int errcode_for_file_access(void)
Definition: elog.c:721
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
#define ereport(elevel,...)
Definition: elog.h:157
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static XLogCtlData * XLogCtl
Definition: xlog.c:729
static char * filename
Definition: pg_dumpall.c:92
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ CreateCheckPoint()

void CreateCheckPoint ( int  flags)

Definition at line 8908 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(), errmsg_internal(), 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().

8909 {
8910  bool shutdown;
8911  CheckPoint checkPoint;
8912  XLogRecPtr recptr;
8913  XLogSegNo _logSegNo;
8915  uint32 freespace;
8916  XLogRecPtr PriorRedoPtr;
8917  XLogRecPtr curInsert;
8918  XLogRecPtr last_important_lsn;
8919  VirtualTransactionId *vxids;
8920  int nvxids;
8921 
8922  /*
8923  * An end-of-recovery checkpoint is really a shutdown checkpoint, just
8924  * issued at a different time.
8925  */
8927  shutdown = true;
8928  else
8929  shutdown = false;
8930 
8931  /* sanity check */
8932  if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
8933  elog(ERROR, "can't create a checkpoint during recovery");
8934 
8935  /*
8936  * Initialize InitXLogInsert working areas before entering the critical
8937  * section. Normally, this is done by the first call to
8938  * RecoveryInProgress() or LocalSetXLogInsertAllowed(), but when creating
8939  * an end-of-recovery checkpoint, the LocalSetXLogInsertAllowed call is
8940  * done below in a critical section, and InitXLogInsert cannot be called
8941  * in a critical section.
8942  */
8943  InitXLogInsert();
8944 
8945  /*
8946  * Prepare to accumulate statistics.
8947  *
8948  * Note: because it is possible for log_checkpoints to change while a
8949  * checkpoint proceeds, we always accumulate stats, even if
8950  * log_checkpoints is currently off.
8951  */
8952  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
8954 
8955  /*
8956  * Use a critical section to force system panic if we have trouble.
8957  */
8959 
8960  if (shutdown)
8961  {
8962  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8964  ControlFile->time = (pg_time_t) time(NULL);
8966  LWLockRelease(ControlFileLock);
8967  }
8968 
8969  /*
8970  * Let smgr prepare for checkpoint; this has to happen before we determine
8971  * the REDO pointer. Note that smgr must not do anything that'd have to
8972  * be undone if we decide no checkpoint is needed.
8973  */
8975 
8976  /* Begin filling in the checkpoint WAL record */
8977  MemSet(&checkPoint, 0, sizeof(checkPoint));
8978  checkPoint.time = (pg_time_t) time(NULL);
8979 
8980  /*
8981  * For Hot Standby, derive the oldestActiveXid before we fix the redo
8982  * pointer. This allows us to begin accumulating changes to assemble our
8983  * starting snapshot of locks and transactions.
8984  */
8985  if (!shutdown && XLogStandbyInfoActive())
8987  else
8989 
8990  /*
8991  * Get location of last important record before acquiring insert locks (as
8992  * GetLastImportantRecPtr() also locks WAL locks).
8993  */
8994  last_important_lsn = GetLastImportantRecPtr();
8995 
8996  /*
8997  * We must block concurrent insertions while examining insert state to
8998  * determine the checkpoint REDO pointer.
8999  */
9001  curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
9002 
9003  /*
9004  * If this isn't a shutdown or forced checkpoint, and if there has been no
9005  * WAL activity requiring a checkpoint, skip it. The idea here is to
9006  * avoid inserting duplicate checkpoints when the system is idle.
9007  */
9008  if ((flags & (CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_END_OF_RECOVERY |
9009  CHECKPOINT_FORCE)) == 0)
9010  {
9011  if (last_important_lsn == ControlFile->checkPoint)
9012  {
9014  END_CRIT_SECTION();
9015  ereport(DEBUG1,
9016  (errmsg_internal("checkpoint skipped because system is idle")));
9017  return;
9018  }
9019  }
9020 
9021  /*
9022  * An end-of-recovery checkpoint is created before anyone is allowed to
9023  * write WAL. To allow us to write the checkpoint record, temporarily
9024  * enable XLogInsertAllowed. (This also ensures ThisTimeLineID is
9025  * initialized, which we need here and in AdvanceXLInsertBuffer.)
9026  */
9027  if (flags & CHECKPOINT_END_OF_RECOVERY)
9029 
9030  checkPoint.ThisTimeLineID = ThisTimeLineID;
9031  if (flags & CHECKPOINT_END_OF_RECOVERY)
9032  checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
9033  else
9034  checkPoint.PrevTimeLineID = ThisTimeLineID;
9035 
9036  checkPoint.fullPageWrites = Insert->fullPageWrites;
9037 
9038  /*
9039  * Compute new REDO record ptr = location of next XLOG record.
9040  *
9041  * NB: this is NOT necessarily where the checkpoint record itself will be,
9042  * since other backends may insert more XLOG records while we're off doing
9043  * the buffer flush work. Those XLOG records are logically after the
9044  * checkpoint, even though physically before it. Got that?
9045  */
9046  freespace = INSERT_FREESPACE(curInsert);
9047  if (freespace == 0)
9048  {
9049  if (XLogSegmentOffset(curInsert, wal_segment_size) == 0)
9050  curInsert += SizeOfXLogLongPHD;
9051  else
9052  curInsert += SizeOfXLogShortPHD;
9053  }
9054  checkPoint.redo = curInsert;
9055 
9056  /*
9057  * Here we update the shared RedoRecPtr for future XLogInsert calls; this
9058  * must be done while holding all the insertion locks.
9059  *
9060  * Note: if we fail to complete the checkpoint, RedoRecPtr will be left
9061  * pointing past where it really needs to point. This is okay; the only
9062  * consequence is that XLogInsert might back up whole buffers that it
9063  * didn't really need to. We can't postpone advancing RedoRecPtr because
9064  * XLogInserts that happen while we are dumping buffers must assume that
9065  * their buffer changes are not included in the checkpoint.
9066  */
9067  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
9068 
9069  /*
9070  * Now we can release the WAL insertion locks, allowing other xacts to
9071  * proceed while we are flushing disk buffers.
9072  */
9074 
9075  /* Update the info_lck-protected copy of RedoRecPtr as well */
9077  XLogCtl->RedoRecPtr = checkPoint.redo;
9079 
9080  /*
9081  * If enabled, log checkpoint start. We postpone this until now so as not
9082  * to log anything if we decided to skip the checkpoint.
9083  */
9084  if (log_checkpoints)
9085  LogCheckpointStart(flags, false);
9086 
9087  /* Update the process title */
9088  update_checkpoint_display(flags, false, false);
9089 
9090  TRACE_POSTGRESQL_CHECKPOINT_START(flags);
9091 
9092  /*
9093  * Get the other info we need for the checkpoint record.
9094  *
9095  * We don't need to save oldestClogXid in the checkpoint, it only matters
9096  * for the short period in which clog is being truncated, and if we crash
9097  * during that we'll redo the clog truncation and fix up oldestClogXid
9098  * there.
9099  */
9100  LWLockAcquire(XidGenLock, LW_SHARED);
9101  checkPoint.nextXid = ShmemVariableCache->nextXid;
9102  checkPoint.oldestXid = ShmemVariableCache->oldestXid;
9104  LWLockRelease(XidGenLock);
9105 
9106  LWLockAcquire(CommitTsLock, LW_SHARED);
9109  LWLockRelease(CommitTsLock);
9110 
9111  LWLockAcquire(OidGenLock, LW_SHARED);
9112  checkPoint.nextOid = ShmemVariableCache->nextOid;
9113  if (!shutdown)
9114  checkPoint.nextOid += ShmemVariableCache->oidCount;
9115  LWLockRelease(OidGenLock);
9116 
9117  MultiXactGetCheckptMulti(shutdown,
9118  &checkPoint.nextMulti,
9119  &checkPoint.nextMultiOffset,
9120  &checkPoint.oldestMulti,
9121  &checkPoint.oldestMultiDB);
9122 
9123  /*
9124  * Having constructed the checkpoint record, ensure all shmem disk buffers
9125  * and commit-log buffers are flushed to disk.
9126  *
9127  * This I/O could fail for various reasons. If so, we will fail to
9128  * complete the checkpoint, but there is no reason to force a system
9129  * panic. Accordingly, exit critical section while doing it.
9130  */
9131  END_CRIT_SECTION();
9132 
9133  /*
9134  * In some cases there are groups of actions that must all occur on one
9135  * side or the other of a checkpoint record. Before flushing the
9136  * checkpoint record we must explicitly wait for any backend currently
9137  * performing those groups of actions.
9138  *
9139  * One example is end of transaction, so we must wait for any transactions
9140  * that are currently in commit critical sections. If an xact inserted
9141  * its commit record into XLOG just before the REDO point, then a crash
9142  * restart from the REDO point would not replay that record, which means
9143  * that our flushing had better include the xact's update of pg_xact. So
9144  * we wait till he's out of his commit critical section before proceeding.
9145  * See notes in RecordTransactionCommit().
9146  *
9147  * Because we've already released the insertion locks, this test is a bit
9148  * fuzzy: it is possible that we will wait for xacts we didn't really need
9149  * to wait for. But the delay should be short and it seems better to make
9150  * checkpoint take a bit longer than to hold off insertions longer than
9151  * necessary. (In fact, the whole reason we have this issue is that xact.c
9152  * does commit record XLOG insertion and clog update as two separate steps
9153  * protected by different locks, but again that seems best on grounds of
9154  * minimizing lock contention.)
9155  *
9156  * A transaction that has not yet set delayChkpt when we look cannot be at
9157  * risk, since he's not inserted his commit record yet; and one that's
9158  * already cleared it is not at risk either, since he's done fixing clog
9159  * and we will correctly flush the update below. So we cannot miss any
9160  * xacts we need to wait for.
9161  */
9162  vxids = GetVirtualXIDsDelayingChkpt(&nvxids);
9163  if (nvxids > 0)
9164  {
9165  do
9166  {
9167  pg_usleep(10000L); /* wait for 10 msec */
9168  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids));
9169  }
9170  pfree(vxids);
9171 
9172  CheckPointGuts(checkPoint.redo, flags);
9173 
9174  /*
9175  * Take a snapshot of running transactions and write this to WAL. This
9176  * allows us to reconstruct the state of running transactions during
9177  * archive recovery, if required. Skip, if this info disabled.
9178  *
9179  * If we are shutting down, or Startup process is completing crash
9180  * recovery we don't need to write running xact data.
9181  */
9182  if (!shutdown && XLogStandbyInfoActive())
9184 
9186 
9187  /*
9188  * Now insert the checkpoint record into XLOG.
9189  */
9190  XLogBeginInsert();
9191  XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));
9192  recptr = XLogInsert(RM_XLOG_ID,
9193  shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
9195 
9196  XLogFlush(recptr);
9197 
9198  /*
9199  * We mustn't write any new WAL after a shutdown checkpoint, or it will be
9200  * overwritten at next startup. No-one should even try, this just allows
9201  * sanity-checking. In the case of an end-of-recovery checkpoint, we want
9202  * to just temporarily disable writing until the system has exited
9203  * recovery.
9204  */
9205  if (shutdown)
9206  {
9207  if (flags & CHECKPOINT_END_OF_RECOVERY)
9208  LocalXLogInsertAllowed = -1; /* return to "check" state */
9209  else
9210  LocalXLogInsertAllowed = 0; /* never again write WAL */
9211  }
9212 
9213  /*
9214  * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
9215  * = end of actual checkpoint record.
9216  */
9217  if (shutdown && checkPoint.redo != ProcLastRecPtr)
9218  ereport(PANIC,
9219  (errmsg("concurrent write-ahead log activity while database system is shutting down")));
9220 
9221  /*
9222  * Remember the prior checkpoint's redo ptr for
9223  * UpdateCheckPointDistanceEstimate()
9224  */
9225  PriorRedoPtr = ControlFile->checkPointCopy.redo;
9226 
9227  /*
9228  * Update the control file.
9229  */
9230  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9231  if (shutdown)
9234  ControlFile->checkPointCopy = checkPoint;
9235  ControlFile->time = (pg_time_t) time(NULL);
9236  /* crash recovery should always recover to the end of WAL */
9239 
9240  /*
9241  * Persist unloggedLSN value. It's reset on crash recovery, so this goes
9242  * unused on non-shutdown checkpoints, but seems useful to store it always
9243  * for debugging purposes.
9244  */
9248 
9250  LWLockRelease(ControlFileLock);
9251 
9252  /* Update shared-memory copy of checkpoint XID/epoch */
9254  XLogCtl->ckptFullXid = checkPoint.nextXid;
9256 
9257  /*
9258  * We are now done with critical updates; no need for system panic if we
9259  * have trouble while fooling with old log segments.
9260  */
9261  END_CRIT_SECTION();
9262 
9263  /*
9264  * Let smgr do post-checkpoint cleanup (eg, deleting old files).
9265  */
9267 
9268  /*
9269  * Update the average distance between checkpoints if the prior checkpoint
9270  * exists.
9271  */
9272  if (PriorRedoPtr != InvalidXLogRecPtr)
9274 
9275  /*
9276  * Delete old log files, those no longer needed for last checkpoint to
9277  * prevent the disk holding the xlog from growing full.
9278  */
9280  KeepLogSeg(recptr, &_logSegNo);
9281  if (InvalidateObsoleteReplicationSlots(_logSegNo))
9282  {
9283  /*
9284  * Some slots have been invalidated; recalculate the old-segment
9285  * horizon, starting again from RedoRecPtr.
9286  */
9288  KeepLogSeg(recptr, &_logSegNo);
9289  }
9290  _logSegNo--;
9291  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr);
9292 
9293  /*
9294  * Make more log segments if needed. (Do this after recycling old log
9295  * segments, since that may supply some of the needed files.)
9296  */
9297  if (!shutdown)
9298  PreallocXlogFiles(recptr);
9299 
9300  /*
9301  * Truncate pg_subtrans if possible. We can throw away all data before
9302  * the oldest XMIN of any running transaction. No future transaction will
9303  * attempt to reference any pg_subtrans entry older than that (see Asserts
9304  * in subtrans.c). During recovery, though, we mustn't do this because
9305  * StartupSUBTRANS hasn't been called yet.
9306  */
9307  if (!RecoveryInProgress())
9309 
9310  /* Real work is done; log and update stats. */
9311  LogCheckpointEnd(false);
9312 
9313  /* Reset the process title */
9314  update_checkpoint_display(flags, false, true);
9315 
9316  TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
9317  NBuffers,
9321 }
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:8596
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8813
static int LocalXLogInsertAllowed
Definition: xlog.c:239
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:1728
int wal_segment_size
Definition: xlog.c:119
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:215
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1580
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1997
XLogRecPtr unloggedLSN
Definition: xlog.c:591
XLogRecPtr ProcLastRecPtr
Definition: xlog.c:343
TransactionId oldestActiveXid
Definition: pg_control.h:63
void InitXLogInsert(void)
Definition: xloginsert.c:1249
TimestampTz ckpt_start_t
Definition: xlog.h:221
slock_t info_lck
Definition: xlog.c:726
#define END_CRIT_SECTION()
Definition: miscadmin.h:149
VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids)
Definition: procarray.c:3043
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: xlog.c:632
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
#define START_CRIT_SECTION()
Definition: miscadmin.h:147
int ckpt_segs_recycled
Definition: xlog.h:231
TransactionId oldestXid
Definition: transam.h:222
#define MemSet(start, val, len)
Definition: c.h:1008
void MultiXactGetCheckptMulti(bool is_shutdown, MultiXactId *nextMulti, MultiXactOffset *nextMultiOffset, MultiXactId *oldestMulti, Oid *oldestMultiDB)
Definition: multixact.c:2133
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:9381
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:579
TransactionId oldestXid
Definition: pg_control.h:47
bool RecoveryInProgress(void)
Definition: xlog.c:8226
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:338
FullTransactionId nextXid
Definition: transam.h:220
pg_time_t time
Definition: pg_control.h:51
#define PANIC
Definition: elog.h:50
bool fullPageWrites
Definition: xlog.c:554
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2863
static void update_checkpoint_display(int flags, bool restartpoint, bool reset)
Definition: xlog.c:8851
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1803
#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:4952
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
void pfree(void *pointer)
Definition: mcxt.c:1169
XLogRecPtr LogStandbySnapshot(void)
Definition: standby.c:1220
#define ERROR
Definition: elog.h:46
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8721
bool InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno)
Definition: slot.c:1305
static XLogRecPtr RedoRecPtr
Definition: xlog.c:357
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
XLogRecPtr unloggedLSN
Definition: pg_control.h:133
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3938
uint64 XLogSegNo
Definition: xlogdefs.h:48
#define CHECKPOINT_END_OF_RECOVERY
Definition: xlog.h:197
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define InvalidTransactionId
Definition: transam.h:31
uint64 CurrBytePos
Definition: xlog.c:529
unsigned int uint32
Definition: c.h:441
XLogRecPtr RedoRecPtr
Definition: xlog.c:583
int ckpt_segs_removed
Definition: xlog.h:230
#define CHECKPOINT_FORCE
Definition: xlog.h:200
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:743
TransactionId oldestCommitTsXid
Definition: transam.h:232
static void Insert(File file)
Definition: fd.c:1266
int ckpt_bufs_written
Definition: xlog.h:227
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8370
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:340
#define SpinLockRelease(lock)
Definition: spin.h:64
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:432
TransactionId newestCommitTsXid
Definition: pg_control.h:54
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9814
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
Oid oldestMultiDB
Definition: pg_control.h:50
FullTransactionId ckptFullXid
Definition: xlog.c:584
#define XLogStandbyInfoActive()
Definition: xlog.h:180
static ControlFileData * ControlFile
Definition: xlog.c:737
TimeLineID ThisTimeLineID
Definition: xlog.c:194
Oid nextOid
Definition: pg_control.h:44
#define ereport(elevel,...)
Definition: elog.h:157
bool fullPageWrites
Definition: pg_control.h:42
int errmsg_internal(const char *fmt,...)
Definition: elog.c:996
uint64 XLogRecPtr
Definition: xlogdefs.h:21
Oid oldestXidDB
Definition: pg_control.h:48
TransactionId newestCommitTsXid
Definition: transam.h:233
CheckpointStatsData CheckpointStats
Definition: xlog.c:188
#define SizeOfXLogShortPHD
Definition: xlog_internal.h:52
MultiXactId nextMulti
Definition: pg_control.h:45
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1699
static XLogCtlData * XLogCtl
Definition: xlog.c:729
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1199
TransactionId GetOldestTransactionIdConsideredRunning(void)
Definition: procarray.c:2034
int ckpt_segs_added
Definition: xlog.h:229
slock_t ulsn_lck
Definition: xlog.c:592
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr)
Definition: xlog.c:4073
void SyncPostCheckpoint(void)
Definition: sync.c:195
TransactionId GetOldestActiveTransactionId(void)
Definition: procarray.c:2882
int NBuffers
Definition: globals.c:135
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids)
Definition: procarray.c:3087
void XLogBeginInsert(void)
Definition: xloginsert.c:135
XLogRecPtr RedoRecPtr
Definition: xlog.c:552
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:37
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8689
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:196
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)

◆ CreateRestartPoint()

bool CreateRestartPoint ( int  flags)

Definition at line 9462 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(), errmsg_internal(), 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(), LSN_FORMAT_ARGS, 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().

9463 {
9464  XLogRecPtr lastCheckPointRecPtr;
9465  XLogRecPtr lastCheckPointEndPtr;
9466  CheckPoint lastCheckPoint;
9467  XLogRecPtr PriorRedoPtr;
9468  XLogRecPtr receivePtr;
9469  XLogRecPtr replayPtr;
9470  TimeLineID replayTLI;
9471  XLogRecPtr endptr;
9472  XLogSegNo _logSegNo;
9473  TimestampTz xtime;
9474 
9475  /* Get a local copy of the last safe checkpoint record. */
9477  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
9478  lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
9479  lastCheckPoint = XLogCtl->lastCheckPoint;
9481 
9482  /*
9483  * Check that we're still in recovery mode. It's ok if we exit recovery
9484  * mode after this check, the restart point is valid anyway.
9485  */
9486  if (!RecoveryInProgress())
9487  {
9488  ereport(DEBUG2,
9489  (errmsg_internal("skipping restartpoint, recovery has already ended")));
9490  return false;
9491  }
9492 
9493  /*
9494  * If the last checkpoint record we've replayed is already our last
9495  * restartpoint, we can't perform a new restart point. We still update
9496  * minRecoveryPoint in that case, so that if this is a shutdown restart
9497  * point, we won't start up earlier than before. That's not strictly
9498  * necessary, but when hot standby is enabled, it would be rather weird if
9499  * the database opened up for read-only connections at a point-in-time
9500  * before the last shutdown. Such time travel is still possible in case of
9501  * immediate shutdown, though.
9502  *
9503  * We don't explicitly advance minRecoveryPoint when we do create a
9504  * restartpoint. It's assumed that flushing the buffers will do that as a
9505  * side-effect.
9506  */
9507  if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
9508  lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
9509  {
9510  ereport(DEBUG2,
9511  (errmsg_internal("skipping restartpoint, already performed at %X/%X",
9512  LSN_FORMAT_ARGS(lastCheckPoint.redo))));
9513 
9515  if (flags & CHECKPOINT_IS_SHUTDOWN)
9516  {
9517  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9519  ControlFile->time = (pg_time_t) time(NULL);
9521  LWLockRelease(ControlFileLock);
9522  }
9523  return false;
9524  }
9525 
9526  /*
9527  * Update the shared RedoRecPtr so that the startup process can calculate
9528  * the number of segments replayed since last restartpoint, and request a
9529  * restartpoint if it exceeds CheckPointSegments.
9530  *
9531  * Like in CreateCheckPoint(), hold off insertions to update it, although
9532  * during recovery this is just pro forma, because no WAL insertions are
9533  * happening.
9534  */
9536  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
9538 
9539  /* Also update the info_lck-protected copy */
9541  XLogCtl->RedoRecPtr = lastCheckPoint.redo;
9543 
9544  /*
9545  * Prepare to accumulate statistics.
9546  *
9547  * Note: because it is possible for log_checkpoints to change while a
9548  * checkpoint proceeds, we always accumulate stats, even if
9549  * log_checkpoints is currently off.
9550  */
9551  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
9553 
9554  if (log_checkpoints)
9555  LogCheckpointStart(flags, true);
9556 
9557  /* Update the process title */
9558  update_checkpoint_display(flags, true, false);
9559 
9560  CheckPointGuts(lastCheckPoint.redo, flags);
9561 
9562  /*
9563  * Remember the prior checkpoint's redo ptr for
9564  * UpdateCheckPointDistanceEstimate()
9565  */
9566  PriorRedoPtr = ControlFile->checkPointCopy.redo;
9567 
9568  /*
9569  * Update pg_control, using current time. Check that it still shows
9570  * DB_IN_ARCHIVE_RECOVERY state and an older checkpoint, else do nothing;
9571  * this is a quick hack to make sure nothing really bad happens if somehow
9572  * we get here after the end-of-recovery checkpoint.
9573  */
9574  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9576  ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
9577  {
9578  ControlFile->checkPoint = lastCheckPointRecPtr;
9579  ControlFile->checkPointCopy = lastCheckPoint;
9580  ControlFile->time = (pg_time_t) time(NULL);
9581 
9582  /*
9583  * Ensure minRecoveryPoint is past the checkpoint record. Normally,
9584  * this will have happened already while writing out dirty buffers,
9585  * but not necessarily - e.g. because no buffers were dirtied. We do
9586  * this because a non-exclusive base backup uses minRecoveryPoint to
9587  * determine which WAL files must be included in the backup, and the
9588  * file (or files) containing the checkpoint record must be included,
9589  * at a minimum. Note that for an ordinary restart of recovery there's
9590  * no value in having the minimum recovery point any earlier than this
9591  * anyway, because redo will begin just after the checkpoint record.
9592  */
9593  if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
9594  {
9595  ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
9597 
9598  /* update local copy */
9601  }
9602  if (flags & CHECKPOINT_IS_SHUTDOWN)
9605  }
9606  LWLockRelease(ControlFileLock);
9607 
9608  /*
9609  * Update the average distance between checkpoints/restartpoints if the
9610  * prior checkpoint exists.
9611  */
9612  if (PriorRedoPtr != InvalidXLogRecPtr)
9614 
9615  /*
9616  * Delete old log files, those no longer needed for last restartpoint to
9617  * prevent the disk holding the xlog from growing full.
9618  */
9620 
9621  /*
9622  * Retreat _logSegNo using the current end of xlog replayed or received,
9623  * whichever is later.
9624  */
9625  receivePtr = GetWalRcvFlushRecPtr(NULL, NULL);
9626  replayPtr = GetXLogReplayRecPtr(&replayTLI);
9627  endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
9628  KeepLogSeg(endptr, &_logSegNo);
9629  if (InvalidateObsoleteReplicationSlots(_logSegNo))
9630  {
9631  /*
9632  * Some slots have been invalidated; recalculate the old-segment
9633  * horizon, starting again from RedoRecPtr.
9634  */
9636  KeepLogSeg(endptr, &_logSegNo);
9637  }
9638  _logSegNo--;
9639 
9640  /*
9641  * Try to recycle segments on a useful timeline. If we've been promoted
9642  * since the beginning of this restartpoint, use the new timeline chosen
9643  * at end of recovery (RecoveryInProgress() sets ThisTimeLineID in that
9644  * case). If we're still in recovery, use the timeline we're currently
9645  * replaying.
9646  *
9647  * There is no guarantee that the WAL segments will be useful on the
9648  * current timeline; if recovery proceeds to a new timeline right after
9649  * this, the pre-allocated WAL segments on this timeline will not be used,
9650  * and will go wasted until recycled on the next restartpoint. We'll live
9651  * with that.
9652  */
9653  if (RecoveryInProgress())
9654  ThisTimeLineID = replayTLI;
9655 
9656  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr);
9657 
9658  /*
9659  * Make more log segments if needed. (Do this after recycling old log
9660  * segments, since that may supply some of the needed files.)
9661  */
9662  PreallocXlogFiles(endptr);
9663 
9664  /*
9665  * ThisTimeLineID is normally not set when we're still in recovery.
9666  * However, recycling/preallocating segments above needed ThisTimeLineID
9667  * to determine which timeline to install the segments on. Reset it now,
9668  * to restore the normal state of affairs for debugging purposes.
9669  */
9670  if (RecoveryInProgress())
9671  ThisTimeLineID = 0;
9672 
9673  /*
9674  * Truncate pg_subtrans if possible. We can throw away all data before
9675  * the oldest XMIN of any running transaction. No future transaction will
9676  * attempt to reference any pg_subtrans entry older than that (see Asserts
9677  * in subtrans.c). When hot standby is disabled, though, we mustn't do
9678  * this because StartupSUBTRANS hasn't been called yet.
9679  */
9680  if (EnableHotStandby)
9682 
9683  /* Real work is done; log and update stats. */
9684  LogCheckpointEnd(true);
9685 
9686  /* Reset the process title */
9687  update_checkpoint_display(flags, true, true);
9688 
9689  xtime = GetLatestXTime();
9691  (errmsg("recovery restart point at %X/%X",
9692  LSN_FORMAT_ARGS(lastCheckPoint.redo)),
9693  xtime ? errdetail("Last completed transaction was at log time %s.",
9694  timestamptz_to_str(xtime)) : 0));
9695 
9696  /*
9697  * Finally, execute archive_cleanup_command, if any.
9698  */
9699  if (archiveCleanupCommand && strcmp(archiveCleanupCommand, "") != 0)
9701  "archive_cleanup_command",
9702  false);
9703 
9704  return true;
9705 }
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8813
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:59
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1728
int wal_segment_size
Definition: xlog.c:119
pg_time_t time
Definition: pg_control.h:128
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1580
int64 TimestampTz
Definition: timestamp.h:39
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition: xlog.c:2779
TimestampTz ckpt_start_t
Definition: xlog.h:221
slock_t info_lck
Definition: xlog.c:726
#define MemSet(start, val, len)
Definition: c.h:1008
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:9381
TimestampTz GetLatestXTime(void)
Definition: xlog.c:6298
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:579
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:8226
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:338
XLogRecPtr lastCheckPointRecPtr
Definition: xlog.c:694
static void update_checkpoint_display(int flags, bool restartpoint, bool reset)
Definition: xlog.c:8851
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1803
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define LSN_FORMAT_ARGS(lsn)
Definition: xlogdefs.h:43
void UpdateControlFile(void)
Definition: xlog.c:4952
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8721
bool InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno)
Definition: slot.c:1305
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
Definition: xlog.c:11751
#define DEBUG2
Definition: elog.h:24
static XLogRecPtr RedoRecPtr
Definition: xlog.c:357
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3938
uint64 XLogSegNo
Definition: xlogdefs.h:48
int errdetail(const char *fmt,...)
Definition: elog.c:1042
XLogRecPtr RedoRecPtr
Definition: xlog.c:583
CheckPoint lastCheckPoint
Definition: xlog.c:696
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
#define SpinLockRelease(lock)
Definition: spin.h:64
static TimeLineID minRecoveryPointTLI
Definition: xlog.c:860
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9814
static ControlFileData * ControlFile
Definition: xlog.c:737
TimeLineID ThisTimeLineID
Definition: xlog.c:194
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg_internal(const char *fmt,...)
Definition: elog.c:996
uint64 XLogRecPtr
Definition: xlogdefs.h:21
CheckpointStatsData CheckpointStats
Definition: xlog.c:188
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1699
static XLogCtlData * XLogCtl
Definition: xlog.c:729
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1199
TransactionId GetOldestTransactionIdConsideredRunning(void)
Definition: procarray.c:2034
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:909
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr)
Definition: xlog.c:4073
XLogRecPtr RedoRecPtr
Definition: xlog.c:552
XLogRecPtr lastCheckPointEndPtr
Definition: xlog.c:695
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:37
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8689
char * archiveCleanupCommand
Definition: xlog.c:265
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:196
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:859
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1774
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ DataChecksumsEnabled()

bool DataChecksumsEnabled ( void  )

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

4982 {
4983  Assert(ControlFile != NULL);
4984  return (ControlFile->data_checksum_version > 0);
4985 }
uint32 data_checksum_version
Definition: pg_control.h:220
static ControlFileData * ControlFile
Definition: xlog.c:737
#define Assert(condition)
Definition: c.h:804

◆ do_pg_abort_backup()

void do_pg_abort_backup ( int  code,
Datum  arg 
)

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

11704 {
11705  bool emit_warning = DatumGetBool(arg);
11706 
11707  /*
11708  * Quick exit if session is not keeping around a non-exclusive backup
11709  * already started.
11710  */
11712  return;
11713 
11717 
11720  {
11721  XLogCtl->Insert.forcePageWrites = false;
11722  }
11724 
11725  if (emit_warning)
11726  ereport(WARNING,
11727  (errmsg("aborting backup due to backend exiting before pg_stop_backup was called")));
11728 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1728
static SessionBackupState sessionBackupState
Definition: xlog.c:513
XLogCtlInsert Insert
Definition: xlog.c:579
bool forcePageWrites
Definition: xlog.c:553
#define DatumGetBool(X)
Definition: postgres.h:437
#define WARNING
Definition: elog.h:40
int nonExclusiveBackups
Definition: xlog.c:565
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:564
#define ereport(elevel,...)
Definition: elog.h:157
#define Assert(condition)
Definition: c.h:804
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1699
static XLogCtlData * XLogCtl
Definition: xlog.c:729
int errmsg(const char *fmt,...)
Definition: elog.c:909
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 
)

Definition at line 10770 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, LSN_FORMAT_ARGS, 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().

10773 {
10774  bool exclusive = (labelfile == NULL);
10775  bool backup_started_in_recovery = false;
10776  XLogRecPtr checkpointloc;
10777  XLogRecPtr startpoint;
10778  TimeLineID starttli;
10779  pg_time_t stamp_time;
10780  char strfbuf[128];
10781  char xlogfilename[MAXFNAMELEN];
10782  XLogSegNo _logSegNo;
10783  struct stat stat_buf;
10784  FILE *fp;
10785 
10786  backup_started_in_recovery = RecoveryInProgress();
10787 
10788  /*
10789  * Currently only non-exclusive backup can be taken during recovery.
10790  */
10791  if (backup_started_in_recovery && exclusive)
10792  ereport(ERROR,
10793  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10794  errmsg("recovery is in progress"),
10795  errhint("WAL control functions cannot be executed during recovery.")));
10796 
10797  /*
10798  * During recovery, we don't need to check WAL level. Because, if WAL
10799  * level is not sufficient, it's impossible to get here during recovery.
10800  */
10801  if (!backup_started_in_recovery && !XLogIsNeeded())
10802  ereport(ERROR,
10803  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10804  errmsg("WAL level not sufficient for making an online backup"),
10805  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
10806 
10807  if (strlen(backupidstr) > MAXPGPATH)
10808  ereport(ERROR,
10809  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
10810  errmsg("backup label too long (max %d bytes)",
10811  MAXPGPATH)));
10812 
10813  /*
10814  * Mark backup active in shared memory. We must do full-page WAL writes
10815  * during an on-line backup even if not doing so at other times, because
10816  * it's quite possible for the backup dump to obtain a "torn" (partially
10817  * written) copy of a database page if it reads the page concurrently with
10818  * our write to the same page. This can be fixed as long as the first
10819  * write to the page in the WAL sequence is a full-page write. Hence, we
10820  * turn on forcePageWrites and then force a CHECKPOINT, to ensure there
10821  * are no dirty pages in shared memory that might get dumped while the
10822  * backup is in progress without having a corresponding WAL record. (Once
10823  * the backup is complete, we need not force full-page writes anymore,
10824  * since we expect that any pages not modified during the backup interval
10825  * must have been correctly captured by the backup.)
10826  *
10827  * Note that forcePageWrites has no effect during an online backup from
10828  * the standby.
10829  *
10830  * We must hold all the insertion locks to change the value of
10831  * forcePageWrites, to ensure adequate interlocking against
10832  * XLogInsertRecord().
10833  */
10835  if (exclusive)
10836  {
10837  /*
10838  * At first, mark that we're now starting an exclusive backup, to
10839  * ensure that there are no other sessions currently running
10840  * pg_start_backup() or pg_stop_backup().
10841  */
10843  {
10845  ereport(ERROR,
10846  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10847  errmsg("a backup is already in progress"),
10848  errhint("Run pg_stop_backup() and try again.")));
10849  }
10851  }
10852  else
10854  XLogCtl->Insert.forcePageWrites = true;
10856 
10857  /* Ensure we release forcePageWrites if fail below */
10859  {
10860  bool gotUniqueStartpoint = false;
10861  DIR *tblspcdir;
10862  struct dirent *de;
10863  tablespaceinfo *ti;
10864  int datadirpathlen;
10865 
10866  /*
10867  * Force an XLOG file switch before the checkpoint, to ensure that the
10868  * WAL segment the checkpoint is written to doesn't contain pages with
10869  * old timeline IDs. That would otherwise happen if you called
10870  * pg_start_backup() right after restoring from a PITR archive: the
10871  * first WAL segment containing the startup checkpoint has pages in
10872  * the beginning with the old timeline ID. That can cause trouble at
10873  * recovery: we won't have a history file covering the old timeline if
10874  * pg_wal directory was not included in the base backup and the WAL
10875  * archive was cleared too before starting the backup.
10876  *
10877  * This also ensures that we have emitted a WAL page header that has
10878  * XLP_BKP_REMOVABLE off before we emit the checkpoint record.
10879  * Therefore, if a WAL archiver (such as pglesslog) is trying to
10880  * compress out removable backup blocks, it won't remove any that
10881  * occur after this point.
10882  *
10883  * During recovery, we skip forcing XLOG file switch, which means that
10884  * the backup taken during recovery is not available for the special
10885  * recovery case described above.
10886  */
10887  if (!backup_started_in_recovery)
10888  RequestXLogSwitch(false);
10889 
10890  do
10891  {
10892  bool checkpointfpw;
10893 
10894  /*
10895  * Force a CHECKPOINT. Aside from being necessary to prevent torn
10896  * page problems, this guarantees that two successive backup runs
10897  * will have different checkpoint positions and hence different
10898  * history file names, even if nothing happened in between.
10899  *
10900  * During recovery, establish a restartpoint if possible. We use
10901  * the last restartpoint as the backup starting checkpoint. This
10902  * means that two successive backup runs can have same checkpoint
10903  * positions.
10904  *
10905  * Since the fact that we are executing do_pg_start_backup()
10906  * during recovery means that checkpointer is running, we can use
10907  * RequestCheckpoint() to establish a restartpoint.
10908  *
10909  * We use CHECKPOINT_IMMEDIATE only if requested by user (via
10910  * passing fast = true). Otherwise this can take awhile.
10911  */
10913  (fast ? CHECKPOINT_IMMEDIATE : 0));
10914 
10915  /*
10916  * Now we need to fetch the checkpoint record location, and also
10917  * its REDO pointer. The oldest point in WAL that would be needed
10918  * to restore starting from the checkpoint is precisely the REDO
10919  * pointer.
10920  */
10921  LWLockAcquire(ControlFileLock, LW_SHARED);
10922  checkpointloc = ControlFile->checkPoint;
10923  startpoint = ControlFile->checkPointCopy.redo;
10925  checkpointfpw = ControlFile->checkPointCopy.fullPageWrites;
10926  LWLockRelease(ControlFileLock);
10927 
10928  if (backup_started_in_recovery)
10929  {
10930  XLogRecPtr recptr;
10931 
10932  /*
10933  * Check to see if all WAL replayed during online backup
10934  * (i.e., since last restartpoint used as backup starting
10935  * checkpoint) contain full-page writes.
10936  */
10938  recptr = XLogCtl->lastFpwDisableRecPtr;
10940 
10941  if (!checkpointfpw || startpoint <= recptr)
10942  ereport(ERROR,
10943  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10944  errmsg("WAL generated with full_page_writes=off was replayed "
10945  "since last restartpoint"),
10946  errhint("This means that the backup being taken on the standby "
10947  "is corrupt and should not be used. "
10948  "Enable full_page_writes and run CHECKPOINT on the primary, "
10949  "and then try an online backup again.")));
10950 
10951  /*
10952  * During recovery, since we don't use the end-of-backup WAL
10953  * record and don't write the backup history file, the
10954  * starting WAL location doesn't need to be unique. This means
10955  * that two base backups started at the same time might use
10956  * the same checkpoint as starting locations.
10957  */
10958  gotUniqueStartpoint = true;
10959  }
10960 
10961  /*
10962  * If two base backups are started at the same time (in WAL sender
10963  * processes), we need to make sure that they use different
10964  * checkpoints as starting locations, because we use the starting
10965  * WAL location as a unique identifier for the base backup in the
10966  * end-of-backup WAL record and when we write the backup history
10967  * file. Perhaps it would be better generate a separate unique ID
10968  * for each backup instead of forcing another checkpoint, but
10969  * taking a checkpoint right after another is not that expensive
10970  * either because only few buffers have been dirtied yet.
10971  */
10973  if (XLogCtl->Insert.lastBackupStart < startpoint)
10974  {
10975  XLogCtl->Insert.lastBackupStart = startpoint;
10976  gotUniqueStartpoint = true;
10977  }
10979  } while (!gotUniqueStartpoint);
10980 
10981  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
10982  XLogFileName(xlogfilename, starttli, _logSegNo, wal_segment_size);
10983 
10984  /*
10985  * Construct tablespace_map file. If caller isn't interested in this,
10986  * we make a local StringInfo.
10987  */
10988  if (tblspcmapfile == NULL)
10989  tblspcmapfile = makeStringInfo();
10990 
10991  datadirpathlen = strlen(DataDir);
10992 
10993  /* Collect information about all tablespaces */
10994  tblspcdir = AllocateDir("pg_tblspc");
10995  while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL)
10996  {
10997  char fullpath[MAXPGPATH + 10];
10998  char linkpath[MAXPGPATH];
10999  char *relpath = NULL;
11000  int rllen;
11001  StringInfoData escapedpath;
11002  char *s;
11003 
11004  /* Skip anything that doesn't look like a tablespace */
11005  if (strspn(de->d_name, "0123456789") != strlen(de->d_name))
11006  continue;
11007 
11008  snprintf(fullpath, sizeof(fullpath), "pg_tblspc/%s", de->d_name);
11009 
11010 #if defined(HAVE_READLINK) || defined(WIN32)
11011  rllen = readlink(fullpath, linkpath, sizeof(linkpath));
11012  if (rllen < 0)
11013  {
11014  ereport(WARNING,
11015  (errmsg("could not read symbolic link \"%s\": %m",
11016  fullpath)));
11017  continue;
11018  }
11019  else if (rllen >= sizeof(linkpath))
11020  {
11021  ereport(WARNING,
11022  (errmsg("symbolic link \"%s\" target is too long",
11023  fullpath)));
11024  continue;
11025  }
11026  linkpath[rllen] = '\0';
11027 
11028  /*
11029  * Build a backslash-escaped version of the link path to include
11030  * in the tablespace map file.
11031  */
11032  initStringInfo(&escapedpath);
11033  for (s = linkpath; *s; s++)
11034  {
11035  if (*s == '\n' || *s == '\r' || *s == '\\')
11036  appendStringInfoChar(&escapedpath, '\\');
11037  appendStringInfoChar(&escapedpath, *s);
11038  }
11039 
11040  /*
11041  * Relpath holds the relative path of the tablespace directory
11042  * when it's located within PGDATA, or NULL if it's located
11043  * elsewhere.
11044  */
11045  if (rllen > datadirpathlen &&
11046  strncmp(linkpath, DataDir, datadirpathlen) == 0 &&
11047  IS_DIR_SEP(linkpath[datadirpathlen]))
11048  relpath = linkpath + datadirpathlen + 1;
11049 
11050  ti = palloc(sizeof(tablespaceinfo));
11051  ti->oid = pstrdup(de->d_name);
11052  ti->path = pstrdup(linkpath);
11053  ti->rpath = relpath ? pstrdup(relpath) : NULL;
11054  ti->size = -1;
11055 
11056  if (tablespaces)
11057  *tablespaces = lappend(*tablespaces, ti);
11058 
11059  appendStringInfo(tblspcmapfile, "%s %s\n",
11060  ti->oid, escapedpath.data);
11061 
11062  pfree(escapedpath.data);
11063 #else
11064 
11065  /*
11066  * If the platform does not have symbolic links, it should not be
11067  * possible to have tablespaces - clearly somebody else created
11068  * them. Warn about it and ignore.
11069  */
11070  ereport(WARNING,
11071  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
11072  errmsg("tablespaces are not supported on this platform")));
11073 #endif
11074  }
11075  FreeDir(tblspcdir);
11076 
11077  /*
11078  * Construct backup label file. If caller isn't interested in this,
11079  * we make a local StringInfo.
11080  */
11081  if (labelfile == NULL)
11082  labelfile = makeStringInfo();
11083 
11084  /* Use the log timezone here, not the session timezone */
11085  stamp_time = (pg_time_t) time(NULL);
11086  pg_strftime(strfbuf, sizeof(strfbuf),
11087  "%Y-%m-%d %H:%M:%S %Z",
11088  pg_localtime(&stamp_time, log_timezone));
11089  appendStringInfo(labelfile, "START WAL LOCATION: %X/%X (file %s)\n",
11090  LSN_FORMAT_ARGS(startpoint), xlogfilename);
11091  appendStringInfo(labelfile, "CHECKPOINT LOCATION: %X/%X\n",
11092  LSN_FORMAT_ARGS(checkpointloc));
11093  appendStringInfo(labelfile, "BACKUP METHOD: %s\n",
11094  exclusive ? "pg_start_backup" : "streamed");
11095  appendStringInfo(labelfile, "BACKUP FROM: %s\n",
11096  backup_started_in_recovery ? "standby" : "primary");
11097  appendStringInfo(labelfile, "START TIME: %s\n", strfbuf);
11098  appendStringInfo(labelfile, "LABEL: %s\n", backupidstr);
11099  appendStringInfo(labelfile, "START TIMELINE: %u\n", starttli);
11100 
11101  /*
11102  * Okay, write the file, or return its contents to caller.
11103  */
11104  if (exclusive)
11105  {
11106  /*
11107  * Check for existing backup label --- implies a backup is already
11108  * running. (XXX given that we checked exclusiveBackupState
11109  * above, maybe it would be OK to just unlink any such label
11110  * file?)
11111  */
11112  if (stat(BACKUP_LABEL_FILE, &stat_buf) != 0)
11113  {
11114  if (errno != ENOENT)
11115  ereport(ERROR,
11117  errmsg("could not stat file \"%s\": %m",
11118  BACKUP_LABEL_FILE)));
11119  }
11120  else
11121  ereport(ERROR,
11122  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11123  errmsg("a backup is already in progress"),
11124  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
11125  BACKUP_LABEL_FILE)));
11126 
11127  fp = AllocateFile(BACKUP_LABEL_FILE, "w");
11128 
11129  if (!fp)
11130  ereport(ERROR,
11132  errmsg("could not create file \"%s\": %m",
11133  BACKUP_LABEL_FILE)));
11134  if (fwrite(labelfile->data, labelfile->len, 1, fp) != 1 ||
11135  fflush(fp) != 0 ||
11136  pg_fsync(fileno(fp)) != 0 ||
11137  ferror(fp) ||
11138  FreeFile(fp))
11139  ereport(ERROR,
11141  errmsg("could not write file \"%s\": %m",
11142  BACKUP_LABEL_FILE)));
11143  /* Allocated locally for exclusive backups, so free separately */
11144  pfree(labelfile->data);
11145  pfree(labelfile);
11146 
11147  /* Write backup tablespace_map file. */
11148  if (tblspcmapfile->len > 0)
11149  {
11150  if (stat(TABLESPACE_MAP, &stat_buf) != 0)
11151  {
11152  if (errno != ENOENT)
11153  ereport(ERROR,
11155  errmsg("could not stat file \"%s\": %m",
11156  TABLESPACE_MAP)));
11157  }
11158  else
11159  ereport(ERROR,
11160  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11161  errmsg("a backup is already in progress"),
11162  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
11163  TABLESPACE_MAP)));
11164 
11165  fp = AllocateFile(TABLESPACE_MAP, "w");
11166 
11167  if (!fp)
11168  ereport(ERROR,
11170  errmsg("could not create file \"%s\": %m",
11171  TABLESPACE_MAP)));
11172  if (fwrite(tblspcmapfile->data, tblspcmapfile->len, 1, fp) != 1 ||
11173  fflush(fp) != 0 ||
11174  pg_fsync(fileno(fp)) != 0 ||
11175  ferror(fp) ||
11176  FreeFile(fp))
11177  ereport(ERROR,
11179  errmsg("could not write file \"%s\": %m",
11180  TABLESPACE_MAP)));
11181  }
11182 
11183  /* Allocated locally for exclusive backups, so free separately */
11184  pfree(tblspcmapfile->data);
11185  pfree(tblspcmapfile);
11186  }
11187  }
11189 
11190  /*
11191  * Mark that start phase has correctly finished for an exclusive backup.
11192  * Session-level locks are updated as well to reflect that state.
11193  *
11194  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating backup
11195  * counters and session-level lock. Otherwise they can be updated
11196  * inconsistently, and which might cause do_pg_abort_backup() to fail.
11197  */
11198  if (exclusive)
11199  {
11202 
11203  /* Set session-level lock */
11206  }
11207  else
11209 
11210  /*
11211  * We're done. As a convenience, return the starting WAL location.
11212  */
11213  if (starttli_p)
11214  *starttli_p = starttli;
11215  return startpoint;
11216 }
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:9907
int errhint(const char *fmt,...)
Definition: elog.c:1156
uint32 TimeLineID
Definition: xlogdefs.h:59
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1728
int wal_segment_size
Definition: xlog.c:119
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:724
static SessionBackupState sessionBackupState
Definition: xlog.c:513
XLogRecPtr lastBackupStart
Definition: xlog.c:566
char * pstrdup(const char *in)
Definition: mcxt.c:1299
#define XLogIsNeeded()
Definition: xlog.h:166
char * rpath
Definition: basebackup.h:32
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
slock_t info_lck
Definition: xlog.c:726
int errcode(int sqlerrcode)
Definition: elog.c:698
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:579
bool RecoveryInProgress(void)
Definition: xlog.c:8226
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:1803
#define TABLESPACE_MAP
Definition: xlog.h:366
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define LSN_FORMAT_ARGS(lsn)
Definition: xlogdefs.h:43
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:47
void pfree(void *pointer)
Definition: mcxt.c:1169
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
bool forcePageWrites
Definition: xlog.c:553
Definition: dirent.c:25
#define ERROR
Definition: elog.h:46
#define MAXPGPATH
uint64 XLogSegNo
Definition: xlogdefs.h:48
#define readlink(path, buf, size)
Definition: win32_port.h:228
int errcode_for_file_access(void)
Definition: elog.c:721
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2417
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2678
#define CHECKPOINT_FORCE
Definition: xlog.h:200
List * lappend(List *list, void *datum)
Definition: list.c:336
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:565
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
static void pg_start_backup_callback(int code, Datum arg)
Definition: xlog.c:11220
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:564
uintptr_t Datum
Definition: postgres.h:411
static ControlFileData * ControlFile
Definition: xlog.c:737
#define BoolGetDatum(X)
Definition: postgres.h:446
#define ereport(elevel,...)
Definition: elog.h:157
bool fullPageWrites
Definition: pg_control.h:42
#define CHECKPOINT_WAIT
Definition: xlog.h:204
uint64 XLogRecPtr
Definition: xlogdefs.h:21
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2744
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1699
static XLogCtlData * XLogCtl
Definition: xlog.c:729
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1199
#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:2616
void * palloc(Size size)
Definition: mcxt.c:1062
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:199
#define relpath(rnode, forknum)
Definition: relpath.h:87
char * DataDir
Definition: globals.c:65
#define BACKUP_LABEL_FILE
Definition: xlog.h:363
int pg_fsync(int fd)
Definition: fd.c:352
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:216
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:37
int FreeDir(DIR *dir)
Definition: fd.c:2796
#define stat
Definition: win32_port.h:275
void RequestCheckpoint(int flags)
Definition: checkpointer.c:927
#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 11288 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, LSN_FORMAT_ARGS, LW_SHARED, LWLockAcquire(), LWLockRelease(), MAXFNAMELEN, MAXPGPATH, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, MyLatch, XLogCtlInsert::nonExclusiveBackups, NOTICE, palloc(), PG_END_ENSURE_ERROR_CLEANUP, PG_ENSURE_ERROR_CLEANUP, pg_localtime(), pg_stop_backup_callback(), pg_strftime(), RecoveryInProgress(), remaining, RequestXLogSwitch(), ResetLatch(), SESSION_BACKUP_NONE, sessionBackupState, SpinLockAcquire, SpinLockRelease, stat::st_size, stat, TABLESPACE_MAP, ThisTimeLineID, WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE, WaitLatch(), wal_segment_size, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), WARNING, WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, WL_TIMEOUT, 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().

11289 {
11290  bool exclusive = (labelfile == NULL);
11291  bool backup_started_in_recovery = false;
11292  XLogRecPtr startpoint;
11293  XLogRecPtr stoppoint;
11294  TimeLineID stoptli;
11295  pg_time_t stamp_time;
11296  char strfbuf[128];
11297  char histfilepath[MAXPGPATH];
11298  char startxlogfilename[MAXFNAMELEN];
11299  char stopxlogfilename[MAXFNAMELEN];
11300  char lastxlogfilename[MAXFNAMELEN];
11301  char histfilename[MAXFNAMELEN];
11302  char backupfrom[20];
11303  XLogSegNo _logSegNo;
11304  FILE *lfp;
11305  FILE *fp;
11306  char ch;
11307  int seconds_before_warning;
11308  int waits = 0;
11309  bool reported_waiting = false;
11310  char *remaining;
11311  char *ptr;
11312  uint32 hi,
11313  lo;
11314 
11315  backup_started_in_recovery = RecoveryInProgress();
11316 
11317  /*
11318  * Currently only non-exclusive backup can be taken during recovery.
11319  */
11320  if (backup_started_in_recovery && exclusive)
11321  ereport(ERROR,
11322  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11323  errmsg("recovery is in progress"),
11324  errhint("WAL control functions cannot be executed during recovery.")));
11325 
11326  /*
11327  * During recovery, we don't need to check WAL level. Because, if WAL
11328  * level is not sufficient, it's impossible to get here during recovery.
11329  */
11330  if (!backup_started_in_recovery && !XLogIsNeeded())
11331  ereport(ERROR,
11332  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11333  errmsg("WAL level not sufficient for making an online backup"),
11334  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
11335 
11336  if (exclusive)
11337  {
11338  /*
11339  * At first, mark that we're now stopping an exclusive backup, to
11340  * ensure that there are no other sessions currently running
11341  * pg_start_backup() or pg_stop_backup().
11342  */
11345  {
11347  ereport(ERROR,
11348  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11349  errmsg("exclusive backup not in progress")));
11350  }
11353 
11354  /*
11355  * Remove backup_label. In case of failure, the state for an exclusive
11356  * backup is switched back to in-progress.
11357  */
11359  {
11360  /*
11361  * Read the existing label file into memory.
11362  */
11363  struct stat statbuf;
11364  int r;
11365 
11366  if (stat(BACKUP_LABEL_FILE, &statbuf))
11367  {
11368  /* should not happen per the upper checks */
11369  if (errno != ENOENT)
11370  ereport(ERROR,
11372  errmsg("could not stat file \"%s\": %m",
11373  BACKUP_LABEL_FILE)));
11374  ereport(ERROR,
11375  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11376  errmsg("a backup is not in progress")));
11377  }
11378 
11379  lfp = AllocateFile(BACKUP_LABEL_FILE, "r");
11380  if (!lfp)
11381  {
11382  ereport(ERROR,
11384  errmsg("could not read file \"%s\": %m",
11385  BACKUP_LABEL_FILE)));
11386  }
11387  labelfile = palloc(statbuf.st_size + 1);
11388  r = fread(labelfile, statbuf.st_size, 1, lfp);
11389  labelfile[statbuf.st_size] = '\0';
11390 
11391  /*
11392  * Close and remove the backup label file
11393  */
11394  if (r != 1 || ferror(lfp) || FreeFile(lfp))
11395  ereport(ERROR,
11397  errmsg("could not read file \"%s\": %m",
11398  BACKUP_LABEL_FILE)));
11400 
11401  /*
11402  * Remove tablespace_map file if present, it is created only if
11403  * there are tablespaces.
11404  */
11406  }
11408  }
11409 
11410  /*
11411  * OK to update backup counters, forcePageWrites and session-level lock.
11412  *
11413  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating them.
11414  * Otherwise they can be updated inconsistently, and which might cause
11415  * do_pg_abort_backup() to fail.
11416  */
11418  if (exclusive)
11419  {
11421  }
11422  else
11423  {
11424  /*
11425  * The user-visible pg_start/stop_backup() functions that operate on
11426  * exclusive backups can be called at any time, but for non-exclusive
11427  * backups, it is expected that each do_pg_start_backup() call is
11428  * matched by exactly one do_pg_stop_backup() call.
11429  */
11432  }
11433 
11436  {
11437  XLogCtl->Insert.forcePageWrites = false;
11438  }
11439 
11440  /*
11441  * Clean up session-level lock.
11442  *
11443  * You might think that WALInsertLockRelease() can be called before
11444  * cleaning up session-level lock because session-level lock doesn't need
11445  * to be protected with WAL insertion lock. But since
11446  * CHECK_FOR_INTERRUPTS() can occur in it, session-level lock must be
11447  * cleaned up before it.
11448  */
11450 
11452 
11453  /*
11454  * Read and parse the START WAL LOCATION line (this code is pretty crude,
11455  * but we are not expecting any variability in the file format).
11456  */
11457  if (sscanf(labelfile, "START WAL LOCATION: %X/%X (file %24s)%c",
11458  &hi, &lo, startxlogfilename,
11459  &ch) != 4 || ch != '\n')
11460  ereport(ERROR,
11461  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11462  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
11463  startpoint = ((uint64) hi) << 32 | lo;
11464  remaining = strchr(labelfile, '\n') + 1; /* %n is not portable enough */
11465 
11466  /*
11467  * Parse the BACKUP FROM line. If we are taking an online backup from the
11468  * standby, we confirm that the standby has not been promoted during the
11469  * backup.
11470  */
11471  ptr = strstr(remaining, "BACKUP FROM:");
11472  if (!ptr || sscanf(ptr, "BACKUP FROM: %19s\n", backupfrom) != 1)
11473  ereport(ERROR,
11474  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11475  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
11476  if (strcmp(backupfrom, "standby") == 0 && !backup_started_in_recovery)
11477  ereport(ERROR,
11478  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11479  errmsg("the standby was promoted during online backup"),
11480  errhint("This means that the backup being taken is corrupt "
11481  "and should not be used. "
11482  "Try taking another online backup.")));
11483 
11484  /*
11485  * During recovery, we don't write an end-of-backup record. We assume that
11486  * pg_control was backed up last and its minimum recovery point can be
11487  * available as the backup end location. Since we don't have an
11488  * end-of-backup record, we use the pg_control value to check whether
11489  * we've reached the end of backup when starting recovery from this
11490  * backup. We have no way of checking if pg_control wasn't backed up last
11491  * however.
11492  *
11493  * We don't force a switch to new WAL file but it is still possible to
11494  * wait for all the required files to be archived if waitforarchive is
11495  * true. This is okay if we use the backup to start a standby and fetch
11496  * the missing WAL using streaming replication. But in the case of an
11497  * archive recovery, a user should set waitforarchive to true and wait for
11498  * them to be archived to ensure that all the required files are
11499  * available.
11500  *
11501  * We return the current minimum recovery point as the backup end
11502  * location. Note that it can be greater than the exact backup end
11503  * location if the minimum recovery point is updated after the backup of
11504  * pg_control. This is harmless for current uses.
11505  *
11506  * XXX currently a backup history file is for informational and debug
11507  * purposes only. It's not essential for an online backup. Furthermore,
11508  * even if it's created, it will not be archived during recovery because
11509  * an archiver is not invoked. So it doesn't seem worthwhile to write a
11510  * backup history file during recovery.
11511  */
11512  if (backup_started_in_recovery)
11513  {
11514  XLogRecPtr recptr;
11515 
11516  /*
11517  * Check to see if all WAL replayed during online backup contain
11518  * full-page writes.
11519  */
11521  recptr = XLogCtl->lastFpwDisableRecPtr;
11523 
11524  if (startpoint <= recptr)
11525  ereport(ERROR,
11526  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11527  errmsg("WAL generated with full_page_writes=off was replayed "
11528  "during online backup"),
11529  errhint("This means that the backup being taken on the standby "
11530  "is corrupt and should not be used. "
11531  "Enable full_page_writes and run CHECKPOINT on the primary, "
11532  "and then try an online backup again.")));
11533 
11534 
11535  LWLockAcquire(ControlFileLock, LW_SHARED);
11536  stoppoint = ControlFile->minRecoveryPoint;
11537  stoptli = ControlFile->minRecoveryPointTLI;
11538  LWLockRelease(ControlFileLock);
11539  }
11540  else
11541  {
11542  /*
11543  * Write the backup-end xlog record
11544  */
11545  XLogBeginInsert();
11546  XLogRegisterData((char *) (&startpoint), sizeof(startpoint));
11547  stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
11548  stoptli = ThisTimeLineID;
11549 
11550  /*
11551  * Force a switch to a new xlog segment file, so that the backup is
11552  * valid as soon as archiver moves out the current segment file.
11553  */
11554  RequestXLogSwitch(false);
11555 
11556  XLByteToPrevSeg(stoppoint, _logSegNo, wal_segment_size);
11557  XLogFileName(stopxlogfilename, stoptli, _logSegNo, wal_segment_size);
11558 
11559  /* Use the log timezone here, not the session timezone */
11560  stamp_time = (pg_time_t) time(NULL);
11561  pg_strftime(strfbuf, sizeof(strfbuf),
11562  "%Y-%m-%d %H:%M:%S %Z",
11563  pg_localtime(&stamp_time, log_timezone));
11564 
11565  /*
11566  * Write the backup history file
11567  */
11568  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
11569  BackupHistoryFilePath(histfilepath, stoptli, _logSegNo,
11570  startpoint, wal_segment_size);
11571  fp = AllocateFile(histfilepath, "w");
11572  if (!fp)
11573  ereport(ERROR,
11575  errmsg("could not create file \"%s\": %m",
11576  histfilepath)));
11577  fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n",
11578  LSN_FORMAT_ARGS(startpoint), startxlogfilename);
11579  fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
11580  LSN_FORMAT_ARGS(stoppoint), stopxlogfilename);
11581 
11582  /*
11583  * Transfer remaining lines including label and start timeline to
11584  * history file.
11585  */
11586  fprintf(fp, "%s", remaining);
11587  fprintf(fp, "STOP TIME: %s\n", strfbuf);
11588  fprintf(fp, "STOP TIMELINE: %u\n", stoptli);
11589  if (fflush(fp) || ferror(fp) || FreeFile(fp))
11590  ereport(ERROR,
11592  errmsg("could not write file \"%s\": %m",
11593  histfilepath)));
11594 
11595  /*
11596  * Clean out any no-longer-needed history files. As a side effect,
11597  * this will post a .ready file for the newly created history file,
11598  * notifying the archiver that history file may be archived
11599  * immediately.
11600  */
11602  }
11603 
11604  /*
11605  * If archiving is enabled, wait for all the required WAL files to be
11606  * archived before returning. If archiving isn't enabled, the required WAL
11607  * needs to be transported via streaming replication (hopefully with
11608  * wal_keep_size set high enough), or some more exotic mechanism like
11609  * polling and copying files from pg_wal with script. We have no knowledge
11610  * of those mechanisms, so it's up to the user to ensure that he gets all
11611  * the required WAL.
11612  *
11613  * We wait until both the last WAL file filled during backup and the
11614  * history file have been archived, and assume that the alphabetic sorting
11615  * property of the WAL files ensures any earlier WAL files are safely
11616  * archived as well.
11617  *
11618  * We wait forever, since archive_command is supposed to work and we
11619  * assume the admin wanted his backup to work completely. If you don't
11620  * wish to wait, then either waitforarchive should be passed in as false,
11621  * or you can set statement_timeout. Also, some notices are issued to
11622  * clue in anyone who might be doing this interactively.
11623  */
11624 
11625  if (waitforarchive &&
11626  ((!backup_started_in_recovery && XLogArchivingActive()) ||
11627  (backup_started_in_recovery && XLogArchivingAlways())))
11628  {
11629  XLByteToPrevSeg(stoppoint, _logSegNo, wal_segment_size);
11630  XLogFileName(lastxlogfilename, stoptli, _logSegNo, wal_segment_size);
11631 
11632  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
11633  BackupHistoryFileName(histfilename, stoptli, _logSegNo,
11634  startpoint, wal_segment_size);
11635 
11636  seconds_before_warning = 60;
11637  waits = 0;
11638 
11639  while (XLogArchiveIsBusy(lastxlogfilename) ||
11640  XLogArchiveIsBusy(histfilename))
11641  {
11643 
11644  if (!reported_waiting && waits > 5)
11645  {
11646  ereport(NOTICE,
11647  (errmsg("base backup done, waiting for required WAL segments to be archived")));
11648  reported_waiting = true;
11649  }
11650 
11651  (void) WaitLatch(MyLatch,
11653  1000L,
11656 
11657  if (++waits >= seconds_before_warning)
11658  {
11659  seconds_before_warning *= 2; /* This wraps in >10 years... */
11660  ereport(WARNING,
11661  (errmsg("still waiting for all required WAL segments to be archived (%d seconds elapsed)",
11662  waits),
11663  errhint("Check that your archive_command is executing properly. "
11664  "You can safely cancel this backup, "
11665  "but the database backup will not be usable without all the WAL segments.")));
11666  }
11667  }
11668 
11669  ereport(NOTICE,
11670  (errmsg("all required WAL segments have been archived")));
11671  }
11672  else if (waitforarchive)
11673  ereport(NOTICE,
11674  (errmsg("WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup")));
11675 
11676  /*
11677  * We're done. As a convenience, return the ending WAL location.
11678  */
11679  if (stoptli_p)
11680  *stoptli_p = stoptli;
11681  return stoppoint;
11682 }
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:9907
#define DEBUG1
Definition: elog.h:25
int errhint(const char *fmt,...)
Definition: elog.c:1156
uint32 TimeLineID
Definition: xlogdefs.h:59
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1728
#define WL_TIMEOUT
Definition: latch.h:128
int wal_segment_size
Definition: xlog.c:119
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:724
static SessionBackupState sessionBackupState
Definition: xlog.c:513
#define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes)
#define XLogIsNeeded()
Definition: xlog.h:166
slock_t info_lck
Definition: xlog.c:726
int errcode(int sqlerrcode)
Definition: elog.c:698
XLogCtlInsert Insert
Definition: xlog.c:579
#define BackupHistoryFileName(fname, tli, logSegNo, startpoint, wal_segsz_bytes)
bool RecoveryInProgress(void)
Definition: xlog.c:8226
static bool backup_started_in_recovery
Definition: basebackup.c:88
#define fprintf
Definition: port.h:220
void ResetLatch(Latch *latch)
Definition: latch.c:660
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:452
pg_tz * log_timezone
Definition: pgtz.c:31
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1803
#define TABLESPACE_MAP
Definition: xlog.h:366
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define LSN_FORMAT_ARGS(lsn)
Definition: xlogdefs.h:43
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:47
#define XLogArchivingAlways()
Definition: xlog.h:158
bool forcePageWrites
Definition: xlog.c:553
#define ERROR
Definition: elog.h:46
static void CleanupBackupHistory(void)
Definition: xlog.c:4340
#define MAXPGPATH
uint64 XLogSegNo
Definition: xlogdefs.h:48
int errcode_for_file_access(void)
Definition: elog.c:721
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2417
unsigned int uint32
Definition: c.h:441
#define XLOG_BACKUP_END
Definition: pg_control.h:72
#define WARNING
Definition: elog.h:40
int nonExclusiveBackups
Definition: xlog.c:565
#define MAXFNAMELEN
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:340
#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:432
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:564
uintptr_t Datum
Definition: postgres.h:411
static ControlFileData * ControlFile
Definition: xlog.c:737
#define BoolGetDatum(X)
Definition: postgres.h:446
TimeLineID ThisTimeLineID
Definition: xlog.c:194
#define ereport(elevel,...)
Definition: elog.h:157
#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:804
#define XLogArchivingActive()
Definition: xlog.h:155
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1699
static XLogCtlData * XLogCtl
Definition: xlog.c:729
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1199
static void pg_stop_backup_callback(int code, Datum arg)
Definition: xlog.c:11249
#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:782
int FreeFile(FILE *file)
Definition: fd.c:2616
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
struct Latch * MyLatch
Definition: globals.c:57
#define BACKUP_LABEL_FILE
Definition: xlog.h:363
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:120
void XLogBeginInsert(void)
Definition: xloginsert.c:135
#define WL_LATCH_SET
Definition: latch.h:125
#define stat
Definition: win32_port.h:275
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:130
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ get_backup_status()

SessionBackupState get_backup_status ( void  )

Definition at line 11267 of file xlog.c.

References sessionBackupState.

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

11268 {
11269  return sessionBackupState;
11270 }
static SessionBackupState sessionBackupState
Definition: xlog.c:513

◆ GetCurrentChunkReplayStartTime()

TimestampTz GetCurrentChunkReplayStartTime ( void  )

Definition at line 6328 of file xlog.c.

References XLogCtlData::currentChunkStartTime, XLogCtlData::info_lck, SpinLockAcquire, and SpinLockRelease.

Referenced by GetReplicationApplyDelay().

6329 {
6330  TimestampTz xtime;
6331 
6333  xtime = XLogCtl->currentChunkStartTime;
6335 
6336  return xtime;
6337 }
int64 TimestampTz
Definition: timestamp.h:39
slock_t info_lck
Definition: xlog.c:726
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:729
TimestampTz currentChunkStartTime
Definition: xlog.c:715

◆ GetFakeLSNForUnloggedRel()

XLogRecPtr GetFakeLSNForUnloggedRel ( void  )

Definition at line 4997 of file xlog.c.

References SpinLockAcquire, SpinLockRelease, XLogCtlData::ulsn_lck, and XLogCtlData::unloggedLSN.

Referenced by gistGetFakeLSN().

4998 {
4999  XLogRecPtr nextUnloggedLSN;
5000 
5001  /* increment the unloggedLSN counter, need SpinLock */
5003  nextUnloggedLSN = XLogCtl->unloggedLSN++;
5005 
5006  return nextUnloggedLSN;
5007 }
XLogRecPtr unloggedLSN
Definition: xlog.c:591
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:729
slock_t ulsn_lck
Definition: xlog.c:592

◆ GetFlushRecPtr()

XLogRecPtr GetFlushRecPtr ( void  )

Definition at line 8578 of file xlog.c.

References XLogwrtResult::Flush, XLogCtlData::info_lck, XLogCtlData::LogwrtResult, SpinLockAcquire, and SpinLockRelease.

Referenced by get_flush_position(), IdentifySystem(), pg_current_wal_flush_lsn(), pg_logical_slot_get_changes_guts(), pg_replication_slot_advance(), read_local_xlog_page(), StartReplication(), WalSndWaitForWal(), XLogSendLogical(), and XLogSendPhysical().

8579 {
8583 
8584  return LogwrtResult.Flush;
8585 }
static XLogwrtResult LogwrtResult
Definition: xlog.c:775
slock_t info_lck
Definition: xlog.c:726
#define SpinLockAcquire(lock)
Definition: spin.h:62
XLogwrtResult LogwrtResult
Definition: xlog.c:602
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:729
XLogRecPtr Flush
Definition: xlog.c:427

◆ GetFullPageWriteInfo()

void GetFullPageWriteInfo ( XLogRecPtr RedoRecPtr_p,
bool doPageWrites_p 
)

Definition at line 8547 of file xlog.c.

References doPageWrites, and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

8548 {
8549  *RedoRecPtr_p = RedoRecPtr;
8550  *doPageWrites_p = doPageWrites;
8551 }
static bool doPageWrites
Definition: xlog.c:364
static XLogRecPtr RedoRecPtr
Definition: xlog.c:357

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )

Definition at line 8562 of file xlog.c.

References XLogCtlData::info_lck, XLogCtlData::LogwrtRqst, SpinLockAcquire, SpinLockRelease, and XLogwrtRqst::Write.

Referenced by CheckpointerMain(), gistvacuumscan(), and IsCheckpointOnSchedule().

8563 {
8564  XLogRecPtr recptr;
8565 
8567  recptr = XLogCtl->LogwrtRqst.Write;
8569 
8570  return recptr;
8571 }
slock_t info_lck
Definition: xlog.c:726
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
XLogRecPtr Write
Definition: xlog.c:420
XLogwrtRqst LogwrtRqst
Definition: xlog.c:582
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:729

◆ GetLastImportantRecPtr()

XLogRecPtr GetLastImportantRecPtr ( void  )

Definition at line 8596 of file xlog.c.

References i, InvalidXLogRecPtr, WALInsertLockPadded::l, WALInsertLock::lastImportantAt, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), and NUM_XLOGINSERT_LOCKS.

Referenced by BackgroundWriterMain(), CheckArchiveTimeout(), and CreateCheckPoint().

8597 {
8599  int i;
8600 
8601  for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
8602  {
8603  XLogRecPtr last_important;
8604 
8605  /*
8606  * Need to take a lock to prevent torn reads of the LSN, which are
8607  * possible on some of the supported platforms. WAL insert locks only
8608  * support exclusive mode, so we have to use that.
8609  */
8611  last_important = WALInsertLocks[i].l.lastImportantAt;
8612  LWLockRelease(&WALInsertLocks[i].l.lock);
8613 
8614  if (res < last_important)
8615  res = last_important;
8616  }
8617 
8618  return res;
8619 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
XLogRecPtr lastImportantAt
Definition: xlog.c:470
#define NUM_XLOGINSERT_LOCKS
Definition: xlog.c:126
WALInsertLock l
Definition: xlog.c:482
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1803
uint64 XLogRecPtr
Definition: xlogdefs.h:21
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1199
int i
static WALInsertLockPadded * WALInsertLocks
Definition: xlog.c:732

◆ GetLatestXTime()

TimestampTz GetLatestXTime ( void  )

Definition at line 6298 of file xlog.c.

References XLogCtlData::info_lck, XLogCtlData::recoveryLastXTime, SpinLockAcquire, and SpinLockRelease.

Referenced by CreateRestartPoint(), pg_last_xact_replay_timestamp(), and StartupXLOG().

6299 {
6300  TimestampTz xtime;
6301 
6303  xtime = XLogCtl->recoveryLastXTime;
6305 
6306  return xtime;
6307 }
int64 TimestampTz
Definition: timestamp.h:39
slock_t info_lck
Definition: xlog.c:726
#define SpinLockAcquire(lock)
Definition: spin.h:62
TimestampTz recoveryLastXTime
Definition: xlog.c:709
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:729

◆ GetMockAuthenticationNonce()

char* GetMockAuthenticationNonce ( void  )

Definition at line 4971 of file xlog.c.

References Assert, and ControlFileData::mock_authentication_nonce.

Referenced by scram_mock_salt().

4972 {
4973  Assert(ControlFile != NULL);
4975 }
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition: pg_control.h:227
static ControlFileData * ControlFile
Definition: xlog.c:737
#define Assert(condition)
Definition: c.h:804

◆ GetRecoveryPauseState()

RecoveryPauseState GetRecoveryPauseState ( void  )

Definition at line 6138 of file xlog.c.

References XLogCtlData::info_lck, XLogCtlData::recoveryPauseState, SpinLockAcquire, and SpinLockRelease.

Referenced by pg_get_wal_replay_pause_state(), pg_is_wal_replay_paused(), recoveryPausesHere(), and RecoveryRequiresIntParameter().

6139 {
6141 
6143  state = XLogCtl->recoveryPauseState;
6145 
6146  return state;
6147 }
RecoveryPauseState recoveryPauseState
Definition: xlog.c:717
slock_t info_lck
Definition: xlog.c:726
#define SpinLockAcquire(lock)
Definition: spin.h:62
RecoveryPauseState
Definition: xlog.h:145
#define SpinLockRelease(lock)
Definition: spin.h:64
Definition: regguts.h:317
static XLogCtlData * XLogCtl
Definition: xlog.c:729

◆ GetRecoveryState()

RecoveryState GetRecoveryState ( void  )

Definition at line 8279 of file xlog.c.

References XLogCtlData::info_lck, XLogCtlData::SharedRecoveryState, SpinLockAcquire, and SpinLockRelease.

Referenced by XLogArchiveCheckDone().

8280 {
8281  RecoveryState retval;
8282 
8284  retval = XLogCtl->SharedRecoveryState;
8286 
8287  return retval;
8288 }
slock_t info_lck
Definition: xlog.c:726
#define SpinLockAcquire(lock)
Definition: spin.h:62
RecoveryState SharedRecoveryState
Definition: xlog.c:638
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:729
RecoveryState
Definition: xlog.h:137

◆ GetRedoRecPtr()

XLogRecPtr GetRedoRecPtr ( void  )

Definition at line 8518 of file xlog.c.

References XLogCtlData::info_lck, RedoRecPtr, XLogCtlData::RedoRecPtr, SpinLockAcquire, and SpinLockRelease.

Referenced by CheckPointLogicalRewriteHeap(), CheckPointSnapBuild(), InitXLOGAccess(), nextval_internal(), ReplicationSlotReserveWal(), XLogPageRead(), XLogSaveBufferForHint(), and XLogWrite().

8519 {
8520  XLogRecPtr ptr;
8521 
8522  /*
8523  * The possibly not up-to-date copy in XlogCtl is enough. Even if we
8524  * grabbed a WAL insertion lock to read the authoritative value in
8525  * Insert->RedoRecPtr, someone might update it just after we've released
8526  * the lock.
8527  */
8529  ptr = XLogCtl->RedoRecPtr;
8531 
8532  if (RedoRecPtr < ptr)
8533  RedoRecPtr = ptr;
8534 
8535  return RedoRecPtr;
8536 }
slock_t info_lck
Definition: xlog.c:726
#define SpinLockAcquire(lock)
Definition: spin.h:62
static XLogRecPtr RedoRecPtr
Definition: xlog.c:357
XLogRecPtr RedoRecPtr
Definition: xlog.c:583
#define SpinLockRelease(lock)
Definition: spin.h:64
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:729

◆ GetSystemIdentifier()

uint64 GetSystemIdentifier ( void  )

Definition at line 4961 of file xlog.c.

References Assert, and ControlFileData::system_identifier.

Referenced by IdentifySystem(), ReplicationSlotNameForTablesync(), and WalReceiverMain().

4962 {
4963  Assert(ControlFile != NULL);
4965 }
uint64 system_identifier
Definition: pg_control.h:106
static ControlFileData * ControlFile
Definition: xlog.c:737
#define Assert(condition)
Definition: c.h:804

◆ GetWALAvailability()

WALAvailability GetWALAvailability ( XLogRecPtr  targetLSN)

Definition at line 9730 of file xlog.c.

References ConvertToXSegs, GetXLogWriteRecPtr(), KeepLogSeg(), max_wal_size_mb, wal_segment_size, WALAVAIL_EXTENDED, WALAVAIL_INVALID_LSN, WALAVAIL_REMOVED, WALAVAIL_RESERVED, WALAVAIL_UNRESERVED, XLByteToSeg, XLogGetLastRemovedSegno(), and XLogRecPtrIsInvalid.

Referenced by pg_get_replication_slots().

9731 {
9732  XLogRecPtr currpos; /* current write LSN */
9733  XLogSegNo currSeg; /* segid of currpos */
9734  XLogSegNo targetSeg; /* segid of targetLSN */
9735  XLogSegNo oldestSeg; /* actual oldest segid */
9736  XLogSegNo oldestSegMaxWalSize; /* oldest segid kept by max_wal_size */
9737  XLogSegNo oldestSlotSeg; /* oldest segid kept by slot */
9738  uint64 keepSegs;
9739 
9740  /*
9741  * slot does not reserve WAL. Either deactivated, or has never been active
9742  */
9743  if (XLogRecPtrIsInvalid(targetLSN))
9744  return WALAVAIL_INVALID_LSN;
9745 
9746  /*
9747  * Calculate the oldest segment currently reserved by all slots,
9748  * considering wal_keep_size and max_slot_wal_keep_size. Initialize
9749  * oldestSlotSeg to the current segment.
9750  */
9751  currpos = GetXLogWriteRecPtr();
9752  XLByteToSeg(currpos, oldestSlotSeg, wal_segment_size);
9753  KeepLogSeg(currpos, &oldestSlotSeg);
9754 
9755  /*
9756  * Find the oldest extant segment file. We get 1 until checkpoint removes
9757  * the first WAL segment file since startup, which causes the status being
9758  * wrong under certain abnormal conditions but that doesn't actually harm.
9759  */
9760  oldestSeg = XLogGetLastRemovedSegno() + 1;
9761 
9762  /* calculate oldest segment by max_wal_size */
9763  XLByteToSeg(currpos, currSeg, wal_segment_size);
9765 
9766  if (currSeg > keepSegs)
9767  oldestSegMaxWalSize = currSeg - keepSegs;
9768  else
9769  oldestSegMaxWalSize = 1;
9770 
9771  /* the segment we care about */
9772  XLByteToSeg(targetLSN, targetSeg, wal_segment_size);
9773 
9774  /*
9775  * No point in returning reserved or extended status values if the
9776  * targetSeg is known to be lost.
9777  */
9778  if (targetSeg >= oldestSlotSeg)
9779  {
9780  /* show "reserved" when targetSeg is within max_wal_size */
9781  if (targetSeg >= oldestSegMaxWalSize)
9782  return WALAVAIL_RESERVED;
9783 
9784  /* being retained by slots exceeding max_wal_size */
9785  return WALAVAIL_EXTENDED;
9786  }
9787 
9788  /* WAL segments are no longer retained but haven't been removed yet */
9789  if (targetSeg >= oldestSeg)
9790  return WALAVAIL_UNRESERVED;
9791 
9792  /* Definitely lost */
9793  return WALAVAIL_REMOVED;
9794 }
#define ConvertToXSegs(x, segsize)
Definition: xlog.c:766
int wal_segment_size
Definition: xlog.c:119
XLogSegNo XLogGetLastRemovedSegno(void)
Definition: xlog.c:4006
int max_wal_size_mb
Definition: xlog.c:91
uint64 XLogSegNo
Definition: xlogdefs.h:48
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9814
XLogRecPtr GetXLogWriteRecPtr(void)
Definition: xlog.c:11786
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ GetXLogInsertRecPtr()

XLogRecPtr GetXLogInsertRecPtr ( void  )

Definition at line 11770 of file xlog.c.

References XLogCtlInsert::CurrBytePos, Insert(), XLogCtlData::Insert, XLogCtlInsert::insertpos_lck, SpinLockAcquire, SpinLockRelease, and XLogBytePosToRecPtr().

Referenced by GetSnapshotDataInitOldSnapshot(), gistGetFakeLSN(), logical_begin_heap_rewrite(), pg_current_wal_insert_lsn(), and ReplicationSlotReserveWal().

11771 {
11773  uint64 current_bytepos;
11774 
11775  SpinLockAcquire(&Insert->insertpos_lck);
11776  current_bytepos = Insert->CurrBytePos;
11777  SpinLockRelease(&Insert->insertpos_lck);
11778 
11779  return XLogBytePosToRecPtr(current_bytepos);
11780 }
slock_t insertpos_lck
Definition: xlog.c:520
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1997
XLogCtlInsert Insert
Definition: xlog.c:579
#define SpinLockAcquire(lock)
Definition: spin.h:62
uint64 CurrBytePos
Definition: xlog.c:529
static void Insert(File file)
Definition: fd.c:1266
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:729

◆ GetXLogReceiptTime()

void GetXLogReceiptTime ( TimestampTz rtime,
bool fromStream 
)

Definition at line 6344 of file xlog.c.

References Assert, InRecovery, XLOG_FROM_STREAM, XLogReceiptSource, and XLogReceiptTime.

Referenced by GetStandbyLimitTime().

6345 {
6346  /*
6347  * This must be executed in the startup process, since we don't export the
6348  * relevant state to shared memory.
6349  */
6350  Assert(InRecovery);
6351 
6352  *rtime = XLogReceiptTime;
6353  *fromStream = (XLogReceiptSource == XLOG_FROM_STREAM);
6354 }
static XLogSource XLogReceiptSource
Definition: xlog.c:846
bool InRecovery
Definition: xlogutils.c:52
static TimestampTz XLogReceiptTime
Definition: xlog.c:845
#define Assert(condition)
Definition: c.h:804

◆ GetXLogReplayRecPtr()

XLogRecPtr GetXLogReplayRecPtr ( TimeLineID replayTLI)

Definition at line 11751 of file xlog.c.

References XLogCtlData::info_lck, XLogCtlData::lastReplayedEndRecPtr, XLogCtlData::lastReplayedTLI, SpinLockAcquire, and SpinLockRelease.

Referenced by CheckpointerMain(), CreateRestartPoint(), GetReplicationApplyDelay(), GetStandbyFlushRecPtr(), IsCheckpointOnSchedule(), pg_last_wal_replay_lsn(), pg_logical_slot_get_changes_guts(), pg_replication_slot_advance(), read_local_xlog_page(), WalReceiverMain(), WalSndWaitForWal(), and XLogWalRcvSendReply().

11752 {
11753  XLogRecPtr recptr;
11754  TimeLineID tli;
11755 
11757  recptr = XLogCtl->lastReplayedEndRecPtr;
11758  tli = XLogCtl->lastReplayedTLI;
11760 
11761  if (replayTLI)
11762  *replayTLI = tli;
11763  return recptr;
11764 }
uint32 TimeLineID
Definition: xlogdefs.h:59
slock_t info_lck
Definition: xlog.c:726
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:729
TimeLineID lastReplayedTLI
Definition: xlog.c:705
XLogRecPtr lastReplayedEndRecPtr
Definition: xlog.c:704

◆ GetXLogWriteRecPtr()

XLogRecPtr GetXLogWriteRecPtr ( void  )

Definition at line 11786 of file xlog.c.

References XLogCtlData::info_lck, XLogCtlData::LogwrtResult, SpinLockAcquire, SpinLockRelease, and XLogwrtResult::Write.

Referenced by GetWALAvailability(), pg_attribute_noreturn(), pg_current_wal_lsn(), and pg_get_replication_slots().

11787 {
11791 
11792  return LogwrtResult.Write;
11793 }
static XLogwrtResult LogwrtResult
Definition: xlog.c:775
slock_t info_lck
Definition: xlog.c:726
#define SpinLockAcquire(lock)
Definition: spin.h:62
XLogwrtResult LogwrtResult
Definition: xlog.c:602
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:729
XLogRecPtr Write
Definition: xlog.c:426

◆ HotStandbyActive()

bool HotStandbyActive ( void  )

Definition at line 8300 of file xlog.c.

References XLogCtlData::info_lck, LocalHotStandbyActive, XLogCtlData::SharedHotStandbyActive, SpinLockAcquire, and SpinLockRelease.

Referenced by XLogWalRcvSendHSFeedback().

8301 {
8302  /*
8303  * We check shared state each time only until Hot Standby is active. We
8304  * can't de-activate Hot Standby, so there's no need to keep checking
8305  * after the shared variable has once been seen true.
8306  */
8308  return true;
8309  else
8310  {
8311  /* spinlock is essential on machines with weak memory ordering! */
8315 
8316  return LocalHotStandbyActive;
8317  }
8318 }
bool SharedHotStandbyActive
Definition: xlog.c:644
slock_t info_lck
Definition: xlog.c:726
#define SpinLockAcquire(lock)
Definition: spin.h:62
static bool LocalHotStandbyActive
Definition: xlog.c:221
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:729

◆ HotStandbyActiveInReplay()

bool HotStandbyActiveInReplay ( void  )

Definition at line 8325 of file xlog.c.

References AmStartupProcess, Assert, IsPostmasterEnvironment, and LocalHotStandbyActive.

8326 {
8328  return LocalHotStandbyActive;
8329 }
#define AmStartupProcess()
Definition: miscadmin.h:445
bool IsPostmasterEnvironment
Definition: globals.c:111
static bool LocalHotStandbyActive
Definition: xlog.c:221
#define Assert(condition)
Definition: c.h:804

◆ InitXLOGAccess()

void InitXLOGAccess ( void  )

Definition at line 8492 of file xlog.c.

References Assert, doPageWrites, XLogCtlInsert::forcePageWrites, XLogCtlInsert::fullPageWrites, GetRedoRecPtr(), InitXLogInsert(), Insert(), XLogCtlData::Insert, IsBootstrapProcessingMode, ThisTimeLineID, XLogCtlData::ThisTimeLineID, wal_segment_size, and ControlFileData::xlog_seg_size.

Referenced by AuxiliaryProcessMain(), LocalSetXLogInsertAllowed(), and RecoveryInProgress().

8493 {
8495 
8496  /* ThisTimeLineID doesn't change so we need no lock to copy it */
8499 
8500  /* set wal_segment_size */
8502 
8503  /* Use GetRedoRecPtr to copy the RedoRecPtr safely */
8504  (void) GetRedoRecPtr();
8505  /* Also update our copy of doPageWrites. */
8506  doPageWrites = (Insert->fullPageWrites || Insert->forcePageWrites);
8507 
8508  /* Also initialize the working areas for constructing WAL records */
8509  InitXLogInsert();
8510 }
int wal_segment_size
Definition: xlog.c:119
void InitXLogInsert(void)
Definition: xloginsert.c:1249
TimeLineID ThisTimeLineID
Definition: xlog.c:631
XLogCtlInsert Insert
Definition: xlog.c:579
bool fullPageWrites
Definition: xlog.c:554
uint32 xlog_seg_size
Definition: pg_control.h:209
static bool doPageWrites
Definition: xlog.c:364
bool forcePageWrites
Definition: xlog.c:553
static void Insert(File file)
Definition: fd.c:1266
static ControlFileData * ControlFile
Definition: xlog.c:737
TimeLineID ThisTimeLineID
Definition: xlog.c:194
#define Assert(condition)
Definition: c.h:804
static XLogCtlData * XLogCtl
Definition: xlog.c:729
XLogRecPtr GetRedoRecPtr(void)
Definition: xlog.c:8518
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:406

◆ issue_xlog_fsync()

void issue_xlog_fsync ( int  fd,
XLogSegNo  segno 
)

Definition at line 10650 of file xlog.c.

References _, Assert, duration, elog, enableFsync, ereport, errcode_for_file_access(), errmsg(), INSTR_TIME_GET_MICROSEC, INSTR_TIME_SET_CURRENT, INSTR_TIME_SUBTRACT, PgStat_MsgWal::m_wal_sync, PgStat_MsgWal::m_wal_sync_time, MAXFNAMELEN, PANIC, pg_fdatasync(), pg_fsync_no_writethrough(), pg_fsync_writethrough(), pgstat_report_wait_end(), pgstat_report_wait_start(), sync_method, SYNC_METHOD_FDATASYNC, SYNC_METHOD_FSYNC, SYNC_METHOD_FSYNC_WRITETHROUGH, SYNC_METHOD_OPEN, SYNC_METHOD_OPEN_DSYNC, ThisTimeLineID, track_wal_io_timing, WAIT_EVENT_WAL_SYNC, wal_segment_size, WalStats, and XLogFileName.

Referenced by XLogWalRcvFlush(), and XLogWrite().

10651 {
10652  char *msg = NULL;
10653  instr_time start;
10654 
10655  /*
10656  * Quick exit if fsync is disabled or write() has already synced the WAL
10657  * file.
10658  */
10659  if (!enableFsync ||
10662  return;
10663 
10664  /* Measure I/O timing to sync the WAL file */
10665  if (track_wal_io_timing)
10666  INSTR_TIME_SET_CURRENT(start);
10667 
10669  switch (sync_method)
10670  {
10671  case SYNC_METHOD_FSYNC:
10672  if (pg_fsync_no_writethrough(fd) != 0)
10673  msg = _("could not fsync file \"%s\": %m");
10674  break;
10675 #ifdef HAVE_FSYNC_WRITETHROUGH
10677  if (pg_fsync_writethrough(fd) != 0)
10678  msg = _("could not fsync write-through file \"%s\": %m");
10679  break;
10680 #endif
10681 #ifdef HAVE_FDATASYNC
10682  case SYNC_METHOD_FDATASYNC:
10683  if (pg_fdatasync(fd) != 0)
10684  msg = _("could not fdatasync file \"%s\": %m");
10685  break;
10686 #endif
10687  case SYNC_METHOD_OPEN:
10689  /* not reachable */
10690  Assert(false);
10691  break;
10692  default:
10693  elog(PANIC, "unrecognized wal_sync_method: %d", sync_method);
10694  break;
10695  }
10696 
10697  /* PANIC if failed to fsync */
10698  if (msg)
10699  {
10700  char xlogfname[MAXFNAMELEN];
10701  int save_errno = errno;
10702 
10703  XLogFileName(xlogfname, ThisTimeLineID, segno,
10705  errno = save_errno;
10706  ereport(PANIC,
10708  errmsg(msg, xlogfname)));
10709  }
10710 
10712 
10713  /*
10714  * Increment the I/O timing and the number of times WAL files were synced.
10715  */
10716  if (track_wal_io_timing)
10717  {
10719 
10720  INSTR_TIME_SET_CURRENT(duration);
10721  INSTR_TIME_SUBTRACT(duration, start);
10723  }
10724 
10725  WalStats.m_wal_sync++;
10726 }
static void pgstat_report_wait_end(void)
Definition: wait_event.h:278
int pg_fdatasync(int fd)
Definition: fd.c:442
int wal_segment_size
Definition: xlog.c:119
#define SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:28
int pg_fsync_writethrough(int fd)
Definition: fd.c:419
struct timeval instr_time
Definition: instr_time.h:150
PgStat_Counter m_wal_sync
Definition: pgstat.h:497
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:407
#define PANIC
Definition: elog.h:50
static int fd(const char *x, int i)
Definition: preproc-init.c:105
PgStat_Counter m_wal_sync_time
Definition: pgstat.h:500
int duration
Definition: pgbench.c:184
#define SYNC_METHOD_OPEN_DSYNC
Definition: xlog.h:29
bool track_wal_io_timing
Definition: xlog.c:113
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:170
int errcode_for_file_access(void)
Definition: elog.c:721
#define SYNC_METHOD_FSYNC
Definition: xlog.h:25
#define SYNC_METHOD_OPEN
Definition: xlog.h:27
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:262
#define MAXFNAMELEN
PgStat_MsgWal WalStats
Definition: pgstat.c:132
TimeLineID ThisTimeLineID
Definition: xlog.c:194
#define ereport(elevel,...)
Definition: elog.h:157
#define Assert(condition)
Definition: c.h:804
#define INSTR_TIME_GET_MICROSEC(t)
Definition: instr_time.h:205
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
int sync_method
Definition: xlog.c:107
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:156
bool enableFsync
Definition: globals.c:122
#define SYNC_METHOD_FDATASYNC
Definition: xlog.h:26
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
#define _(x)
Definition: elog.c:89

◆ LocalProcessControlFile()

void LocalProcessControlFile ( bool  reset)

Definition at line 5081 of file xlog.c.

References Assert, palloc(), and ReadControlFile().

Referenced by BackendRun(), PostgresMain(), PostmasterMain(), and PostmasterStateMachine().

5082 {
5083  Assert(reset || ControlFile == NULL);
5084  ControlFile = palloc(sizeof(ControlFileData));
5085  ReadControlFile();
5086 }
void reset(void)
Definition: sql-declare.c:562
static void ReadControlFile(void)
Definition: xlog.c:4752
static ControlFileData * ControlFile
Definition: xlog.c:737
#define Assert(condition)
Definition: c.h:804
void * palloc(Size size)
Definition: mcxt.c:1062

◆ PromoteIsTriggered()

bool PromoteIsTriggered ( void  )

Definition at line 12874 of file xlog.c.

References XLogCtlData::info_lck, LocalPromoteIsTriggered, XLogCtlData::SharedPromoteIsTriggered, SpinLockAcquire, and SpinLockRelease.

Referenced by pg_wal_replay_pause(), and pg_wal_replay_resume().

12875 {
12876  /*
12877  * We check shared state each time only until a standby promotion is
12878  * triggered. We can't trigger a promotion again, so there's no need to
12879  * keep checking after the shared variable has once been seen true.
12880  */
12882  return true;
12883 
12887 
12888  return LocalPromoteIsTriggered;
12889 }
slock_t info_lck
Definition: xlog.c:726
static bool LocalPromoteIsTriggered
Definition: xlog.c:227
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:729
bool SharedPromoteIsTriggered
Definition: xlog.c:660

◆ RecoveryInProgress()

bool RecoveryInProgress ( void  )

Definition at line 8226 of file xlog.c.

References InitXLOGAccess(), LocalRecoveryInProgress, pg_memory_barrier, RECOVERY_STATE_DONE, XLogCtlData::SharedRecoveryState, and XLogCtl.

Referenced by BackgroundWriterMain(), BeginReportingGUCOptions(), brin_desummarize_range(), brin_summarize_range(), btree_index_mainfork_expected(), check_transaction_read_only(), check_XactIsoLevel(), CheckArchiveTimeout(), CheckLogicalDecodingRequirements(), CheckpointerMain(), ComputeXidHorizons(), CreateCheckPoint(), CreateEndOfRecoveryRecord(), CreateRestartPoint(), do_pg_start_backup(), do_pg_stop_backup(), error_commit_ts_disabled(), get_relation_info(), GetNewMultiXactId(), GetNewObjectId(), GetNewTransactionId(), GetOldestActiveTransactionId(), GetOldestSafeDecodingTransactionId(), GetRunningTransactionData(), GetSerializableTransactionSnapshot(), GetSerializableTransactionSnapshotInt(), GetSnapshotData(), gin_clean_pending_list(), GlobalVisHorizonKindForRel(), heap_force_common(), heap_page_prune_opt(), IdentifySystem(), InitPostgres(), InitTempTableNamespace(), IsCheckpointOnSchedule(), LockAcquireExtended(), MaintainLatestCompletedXid(), MarkBufferDirtyHint(), perform_base_backup(), pg_create_restore_point(), pg_current_wal_flush_lsn(), pg_current_wal_insert_lsn(), pg_current_wal_lsn(), pg_get_wal_replay_pause_state(), pg_is_in_recovery(), pg_is_wal_replay_paused(), pg_logical_slot_get_changes_guts(), pg_promote(), pg_replication_slot_advance(), pg_switch_wal(), pg_wal_replay_pause(), pg_wal_replay_resume(), pg_walfile_name(), pg_walfile_name_offset(), PrepareRedoAdd(), PrepareRedoRemove(), PreventCommandDuringRecovery(), ProcSendSignal(), ProcSleep(), read_local_xlog_page(), ReplicationSlotReserveWal(), replorigin_check_prerequisites(), ReportChangedGUCOptions(), sendDir(), SerialSetActiveSerXmin(), show_in_hot_standby(), ShutdownXLOG(), SnapBuildWaitSnapshot(), standard_ProcessUtility(), StartLogicalReplication(), StartReplication(), StartTransaction(), TransactionIdIsInProgress(), TruncateMultiXact(), UpdateFullPageWrites(), WalReceiverMain(), WalSndWaitForWal(), XLogBackgroundFlush(), XLogInsertAllowed(), XLogNeedsFlush(), and XLogSendPhysical().

8227 {
8228  /*
8229  * We check shared state each time only until we leave recovery mode. We
8230  * can't re-enter recovery, so there's no need to keep checking after the
8231  * shared variable has once been seen false.
8232  */
8234  return false;
8235  else
8236  {
8237  /*
8238  * use volatile pointer to make sure we make a fresh read of the
8239  * shared variable.
8240  */
8241  volatile XLogCtlData *xlogctl = XLogCtl;
8242 
8244 
8245  /*
8246  * Initialize TimeLineID and RedoRecPtr when we discover that recovery
8247  * is finished. InitPostgres() relies upon this behaviour to ensure
8248  * that InitXLOGAccess() is called at backend startup. (If you change
8249  * this, see also LocalSetXLogInsertAllowed.)
8250  */
8252  {
8253  /*
8254  * If we just exited recovery, make sure we read TimeLineID and
8255  * RedoRecPtr after SharedRecoveryState (for machines with weak
8256  * memory ordering).
8257  */
8259  InitXLOGAccess();
8260  }
8261 
8262  /*
8263  * Note: We don't need a memory barrier when we're still in recovery.
8264  * We might exit recovery immediately after return, so the caller
8265  * can't rely on 'true' meaning that we're still in recovery anyway.
8266  */
8267 
8268  return LocalRecoveryInProgress;
8269  }
8270 }
void InitXLOGAccess(void)
Definition: xlog.c:8492
RecoveryState SharedRecoveryState
Definition: xlog.c:638
#define pg_memory_barrier()
Definition: atomics.h:145
static XLogCtlData * XLogCtl
Definition: xlog.c:729
static bool LocalRecoveryInProgress
Definition: xlog.c:215

◆ register_persistent_abort_backup_handler()

void register_persistent_abort_backup_handler ( void  )

Definition at line 11735 of file xlog.c.

References before_shmem_exit(), DatumGetBool, and do_pg_abort_backup().

Referenced by pg_start_backup().

11736 {
11737  static bool already_done = false;
11738 
11739  if (already_done)
11740  return;
11742  already_done = true;
11743 }
void do_pg_abort_backup(int code, Datum arg)
Definition: xlog.c:11703
#define DatumGetBool(X)
Definition: postgres.h:437
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:333

◆ RemovePromoteSignalFiles()

void RemovePromoteSignalFiles ( void  )

Definition at line 12954 of file xlog.c.

References PROMOTE_SIGNAL_FILE.

Referenced by CheckForStandbyTrigger(), and PostmasterMain().

12955 {
12956  unlink(PROMOTE_SIGNAL_FILE);
12957 }
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:370

◆ SetRecoveryPause()

void SetRecoveryPause ( bool  recoveryPause)

Definition at line 6158 of file xlog.c.

References ConditionVariableBroadcast(), XLogCtlData::info_lck, RECOVERY_NOT_PAUSED, RECOVERY_PAUSE_REQUESTED, XLogCtlData::recoveryNotPausedCV, XLogCtlData::recoveryPauseState, SpinLockAcquire, and SpinLockRelease.

Referenced by pg_wal_replay_pause(), pg_wal_replay_resume(), RecoveryRequiresIntParameter(), SetPromoteIsTriggered(), and StartupXLOG().

6159 {
6161 
6162  if (!recoveryPause)
6166 
6168 
6169  if (!recoveryPause)
6171 }
RecoveryPauseState recoveryPauseState
Definition: xlog.c:717
slock_t info_lck
Definition: xlog.c:726
void ConditionVariableBroadcast(ConditionVariable *cv)
#define SpinLockAcquire(lock)
Definition: spin.h:62
ConditionVariable recoveryNotPausedCV
Definition: xlog.c:718
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:729

◆ SetWalWriterSleeping()

void SetWalWriterSleeping ( bool  sleeping)

Definition at line 12987 of file xlog.c.

References XLogCtlData::info_lck, SpinLockAcquire, SpinLockRelease, and XLogCtlData::WalWriterSleeping.

Referenced by WalWriterMain().

12988 {
12990  XLogCtl->WalWriterSleeping = sleeping;
12992 }
slock_t info_lck
Definition: xlog.c:726
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
bool WalWriterSleeping
Definition: xlog.c:667
static XLogCtlData * XLogCtl
Definition: xlog.c:729

◆ ShutdownXLOG()

void ShutdownXLOG ( int  code,
Datum  arg 
)

Definition at line 8642 of file xlog.c.

References Assert, AuxProcessResourceOwner, CHECKPOINT_IMMEDIATE, CHECKPOINT_IS_SHUTDOWN, CreateCheckPoint(), CreateRestartPoint(), CurrentResourceOwner, ereport, errmsg(), IsPostmasterEnvironment, LOG, NOTICE, RecoveryInProgress(), RequestXLogSwitch(), WalSndInitStopping(), WalSndWaitStopping(), XLogArchiveCommandSet, and XLogArchivingActive.

Referenced by HandleCheckpointerInterrupts(), and InitPostgres().

8643 {
8644  /*
8645  * We should have an aux process resource owner to use, and we should not
8646  * be in a transaction that's installed some other resowner.
8647  */
8649  Assert(CurrentResourceOwner == NULL ||
8652 
8653  /* Don't be chatty in standalone mode */
8655  (errmsg("shutting down")));
8656 
8657  /*
8658  * Signal walsenders to move to stopping state.
8659  */
8661 
8662  /*
8663  * Wait for WAL senders to be in stopping state. This prevents commands
8664  * from writing new WAL.
8665  */
8667 
8668  if (RecoveryInProgress())
8670  else
8671  {
8672  /*
8673  * If archiving is enabled, rotate the last XLOG file so that all the
8674  * remaining records are archived (postmaster wakes up the archiver
8675  * process one more time at the end of shutdown). The checkpoint
8676  * record will go to the next XLOG file and won't be archived (yet).
8677  */
8679  RequestXLogSwitch(false);
8680 
8682  }
8683 }
bool IsPostmasterEnvironment
Definition: globals.c:111
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9907
void CreateCheckPoint(int flags)
Definition: xlog.c:8908
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
bool CreateRestartPoint(int flags)
Definition: xlog.c:9462
#define XLogArchiveCommandSet()
Definition: xlog.h:160
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:8226
ResourceOwner AuxProcessResourceOwner
Definition: resowner.c:149
void WalSndWaitStopping(void)
Definition: walsender.c:3191
#define ereport(elevel,...)
Definition: elog.h:157
#define NOTICE
Definition: elog.h:37
void WalSndInitStopping(void)
Definition: walsender.c:3165
#define Assert(condition)
Definition: c.h:804
#define XLogArchivingActive()
Definition: xlog.h:155
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:199
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:196

◆ StartupRequestWalReceiverRestart()

void StartupRequestWalReceiverRestart ( void  )

Definition at line 12812 of file xlog.c.

References currentSource, ereport, errmsg(), LOG, pendingWalRcvRestart, WalRcvRunning(), and XLOG_FROM_STREAM.

Referenced by StartupRereadConfig().

12813 {
12815  {
12816  ereport(LOG,
12817  (errmsg("WAL receiver process shutdown requested")));
12818 
12819  pendingWalRcvRestart = true;
12820  }
12821 }
#define LOG
Definition: elog.h:26
static bool pendingWalRcvRestart
Definition: xlog.c:828
#define ereport(elevel,...)
Definition: elog.h:157
static XLogSource currentSource
Definition: xlog.c:826
int errmsg(const char *fmt,...)
Definition: elog.c:909
bool WalRcvRunning(void)

◆ StartupXLOG()

void StartupXLOG ( void  )

Definition at line 6489 of file xlog.c.

References AdvanceNextFullTransactionIdPastXid(), AdvanceOldestClogXid(), AllowCascadeReplication, appendStringInfo(), appendStringInfoString(), ArchiveRecoveryRequested, ErrorContextCallback::arg, Assert, AuxProcessResourceOwner, BACKUP_LABEL_FILE, BACKUP_LABEL_OLD, ControlFileData::backupEndPoint, ControlFileData::backupEndRequired, ControlFileData::backupStartPoint, bgwriterLaunched, buf, ErrorContextCallback::callback, ControlFileData::checkPoint, CHECKPOINT_END_OF_RECOVERY, CHECKPOINT_FORCE, CHECKPOINT_IMMEDIATE, CHECKPOINT_WAIT, ControlFileData::checkPointCopy, CheckRecoveryConsistency(), CheckRequiredParameterValues(), checkTimeLineSwitch(), checkXLogConsistency(), XLogCtlData::ckptFullXid, close, CompleteCommitTsInitialization(), CreateCheckPoint(), CreateEndOfRecoveryRecord(), XLogCtlInsert::CurrBytePos, XLogCtlData::currentChunkStartTime, CurrentResourceOwner, StringInfoData::data, DataDir, DB_IN_ARCHIVE_RECOVERY, DB_IN_CRASH_RECOVERY, DB_IN_PRODUCTION, DB_SHUTDOWNED, DB_SHUTDOWNED_IN_RECOVERY, DB_SHUTDOWNING, DEBUG1, DEBUG2, DEBUG3, DeleteAllExportedSnapshotFiles(), DisownLatch(), doPageWrites, doRequestWalReceiverReply, durable_rename(), elog, EnableHotStandby, EnableSyncRequestForwarding(), EndRecPtr, ereport, errcode(), errcode_for_file_access(), errdetail(), errhint(), errmsg(), errmsg_internal(), ERROR, error_context_stack, ExecuteRecoveryCommand(), exitArchiveRecovery(), FATAL, findNewestTimeLine(), FirstNormalUnloggedLSN, XLogwrtRqst::Flush, XLogwrtResult::Flush, CheckPoint::fullPageWrites, XLogCtlInsert::fullPageWrites, FullTransactionIdRetreat(), GetCurrentTimestamp(), GetLatestXTime(), getRecoveryStopReason(), HandleStartupProcInterrupts(), InArchiveRecovery, XLogCtlData::info_lck, XLogCtlData::InitializedUpTo, InitRecoveryTransactionEnvironment(), initStringInfo(), InRecovery, InRedo, Insert(), XLogCtlData::Insert, XLogCtlData::InstallXLogFileSegmentActive, InvalidXLogRecPtr, IsPostmasterEnvironment, IsUnderPostmaster, lastFullPageWrites, LastRec, XLogCtlData::lastReplayedEndRecPtr, XLogCtlData::lastReplayedTLI, XLogCtlData::lastSegSwitchLSN, XLogCtlData::lastSegSwitchTime, RunningTransactionsData::latestCompletedXid, VariableCacheData::latestCompletedXid, lfirst, LocalPromoteIsTriggered, LocalSetXLogInsertAllowed(), LocalXLogInsertAllowed, LOG, XLogCtlData::LogwrtResult, LogwrtResult, XLogCtlData::LogwrtRqst, LSN_FORMAT_ARGS, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MAXFNAMELEN, MAXPGPATH, MemSet, ControlFileData::minRecoveryPoint, minRecoveryPoint, ControlFileData::minRecoveryPointTLI, minRecoveryPointTLI, MultiXactSetNextMXact(), CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, VariableCacheData::nextOid, CheckPoint::nextXid, RunningTransactionsData::nextXid, VariableCacheData::nextXid, NIL, NOTICE, tablespaceinfo::oid, VariableCacheData::oidCount, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, RunningTransactionsData::oldestRunningXid, CheckPoint::oldestXid, CheckPoint::oldestXidDB, OwnLatch(), XLogCtlData::pages, palloc(), PANIC, tablespaceinfo::path, pfree(), pg_rusage_init(), pg_rusage_show(), pg_usleep(), pgstat_reset_all(), PMSIGNAL_RECOVERY_STARTED, PreallocXlogFiles(), PrescanPreparedTransactions(), XLogCtlInsert::PrevBytePos, ErrorContextCallback::previous, CheckPoint::PrevTimeLineID, xl_end_of_recovery::PrevTimeLineID, XLogCtlData::PrevTimeLineID, primary_image_masked, proc_exit(), ProcArrayApplyRecoveryInfo(), ProcArrayInitRecovery(), psprintf(), PublishStartupProcessInformation(), reachedConsistency, read_backup_label(), read_tablespace_map(), XLogReaderState::readBuf, ReadCheckpointRecord(), readFile, readOff, ReadRecord(), readRecoverySignalFile(), ReadRecPtr, RecordKnownAssignedTransactionIds(), RecoverPreparedTransactions(), RECOVERY_NOT_PAUSED, RECOVERY_STATE_ARCHIVE, RECOVERY_STATE_CRASH, RECOVERY_STATE_DONE, RECOVERY_TARGET_ACTION_PAUSE, RECOVERY_TARGET_ACTION_PROMOTE, RECOVERY_TARGET_ACTION_SHUTDOWN, RECOVERY_TARGET_IMMEDIATE, RECOVERY_TARGET_LSN, RECOVERY_TARGET_NAME, RECOVERY_TARGET_TIME, RECOVERY_TARGET_UNSET, RECOVERY_TARGET_XID, recoveryApplyDelay(), recoveryEndCommand, XLogCtlData::recoveryLastXTime, recoveryPausesHere(), XLogCtlData::recoveryPauseState, recoveryStopsAfter(), recoveryStopsBefore(), recoveryTarget, recoveryTargetAction, recoveryTargetLSN, recoveryTargetName, recoveryTargetTime, recoveryTargetTLI, recoveryTargetXid, XLogCtlData::recoveryWakeupLatch, CheckPoint::redo, RedoRecPtr, XLogCtlInsert::RedoRecPtr, XLogCtlData::RedoRecPtr, RedoStartLSN, RelationCacheInitFileRemove(), remove_tablespace_symlink(), RemoveNonParentXlogFiles(), RemoveTempXlogFiles(), replay_image_masked, XLogCtlData::replayEndRecPtr, XLogCtlData::replayEndTLI, RequestCheckpoint(), ResetUnloggedRelations(), restoreTimeLineHistoryFiles(), restoreTwoPhaseData(), RmgrData::rm_cleanup, RM_MAX_ID, RmgrData::rm_redo, rm_redo_error_callback(), RmgrData::rm_startup, RmgrTable, XLogReaderState::seg, SendPostmasterSignal(), SetCommitTsLimit(), SetMultiXactIdLimit(), SetRecoveryPause(), SetTransactionIdLimit(), XLogCtlData::SharedRecoveryState, ShmemVariableCache, ShutdownRecoveryTransactionEnvironment(), snprintf, SpinLockAcquire, SpinLockRelease, STANDBY_DISABLED, STANDBY_INITIALIZED, StandbyMode, StandbyModeRequested, StandbyRecoverPreparedTransactions(), standbyState, StartupCLOG(), StartupCommitTs(), StartupMultiXact(), StartupReorderBuffer(), StartupReplicationOrigin(), StartupReplicationSlots(), StartupSUBTRANS(), stat, ControlFileData::state, str_time(), RunningTransactionsData::subxcnt, RunningTransactionsData::subxid_overflow, symlink, SyncDataDirectory(), ControlFileData::system_identifier, XLogReaderState::system_identifier, TABLESPACE_MAP, TABLESPACE_MAP_OLD, CheckPoint::ThisTimeLineID, ThisTimeLineID, xl_end_of_recovery::ThisTimeLineID, XLogCtlData::ThisTimeLineID, CheckPoint::time, ControlFileData::time, timestamptz_to_str(), tliOfPointInHistory(), tliSwitchPoint(), trace_recovery_messages, ControlFileData::track_commit_timestamp, TransactionIdIsNormal, TransactionIdIsValid, TransactionIdRetreat, TrimCLOG(), TrimMultiXact(), U64FromFullTransactionId, UINT64_FORMAT, UNLOGGED_RELATION_CLEANUP, UNLOGGED_RELATION_INIT, ControlFileData::unloggedLSN, XLogCtlData::unloggedLSN, UpdateControlFile(), UpdateFullPageWrites(), validateRecoveryParameters(), ValidateXLOGDirectoryStructure(), wal_segment_close(), wal_segment_size, WalRcvForceReply(), WalRcvStreaming(), WalSndWakeup(), XLogwrtRqst::Write, XLogwrtResult::Write, writeTimeLineHistory(), WALOpenSegment::ws_tli, RunningTransactionsData::xcnt, XidFromFullTransactionId, RunningTransactionsData::xids, XLogRecord::xl_info, XLogRecord::xl_rmid, XL_ROUTINE, XLogRecord::xl_xid, XLogCtlData::xlblocks, XLByteToPrevSeg, XLOG_CHECKPOINT_SHUTDOWN, XLOG_END_OF_RECOVERY, xlog_outdesc(), XLogArchiveCleanup(), XLogArchiveIsReadyOrDone(), XLogArchiveNotify(), XLogArchivingActive, XLogBeginRead(), XLOGDIR, XLogFileName, XLogFilePath, XLogPageRead(), xlogreader, XLogReaderAllocate(), XLogReaderFree(), XLogReceiptTime, XLogRecGetData, XLogRecPtrIsInvalid, XLogRecPtrToBufIdx, XLogRecPtrToBytePos(), XLogReportParameters(), XLogSegmentOffset, XLogShutdownWalRcv(), XLR_CHECK_CONSISTENCY, XLR_INFO_MASK, and XRecOffIsValid.

Referenced by InitPostgres(), and StartupProcessMain().

6490 {
6492  CheckPoint checkPoint;
6493  bool wasShutdown;
6494  bool reachedRecoveryTarget = false;
6495  bool haveBackupLabel = false;
6496  bool haveTblspcMap = false;
6497  XLogRecPtr RecPtr,
6498  checkPointLoc,
6499  EndOfLog;
6500  TimeLineID EndOfLogTLI;
6501  TimeLineID PrevTimeLineID;
6502  XLogRecord *record;
6503  TransactionId oldestActiveXID;
6504  bool backupEndRequired = false;
6505  bool backupFromStandby = false;
6506  DBState dbstate_at_startup;
6508  XLogPageReadPrivate private;
6509  bool promoted = false;
6510  struct stat st;
6511 
6512  /*
6513  * We should have an aux process resource owner to use, and we should not
6514  * be in a transaction that's installed some other resowner.
6515  */
6517  Assert(CurrentResourceOwner == NULL ||
6520 
6521  /*
6522  * Check that contents look valid.
6523  */
6525  ereport(FATAL,
6526  (errmsg("control file contains invalid checkpoint location")));
6527 
6528  switch (ControlFile->state)
6529  {
6530  case DB_SHUTDOWNED:
6531 
6532  /*
6533  * This is the expected case, so don't be chatty in standalone
6534  * mode
6535  */
6537  (errmsg("database system was shut down at %s",
6538  str_time(ControlFile->time))));
6539  break;
6540 
6542  ereport(LOG,
6543  (errmsg("database system was shut down in recovery at %s",
6544  str_time(ControlFile->time))));
6545  break;
6546 
6547  case DB_SHUTDOWNING:
6548  ereport(LOG,
6549  (errmsg("database system shutdown was interrupted; last known up at %s",
6550  str_time(ControlFile->time))));
6551  break;
6552 
6553  case DB_IN_CRASH_RECOVERY:
6554  ereport(LOG,
6555  (errmsg("database system was interrupted while in recovery at %s",
6557  errhint("This probably means that some data is corrupted and"
6558  " you will have to use the last backup for recovery.")));
6559  break;
6560 
6562  ereport(LOG,
6563  (errmsg("database system was interrupted while in recovery at log time %s",
6565  errhint("If this has occurred more than once some data might be corrupted"
6566  " and you might need to choose an earlier recovery target.")));
6567  break;
6568 
6569  case DB_IN_PRODUCTION:
6570  ereport(LOG,
6571  (errmsg("database system was interrupted; last known up at %s",
6572  str_time(ControlFile->time))));
6573  break;
6574 
6575  default:
6576  ereport(FATAL,
6577  (errmsg("control file contains invalid database cluster state")));
6578  }
6579 
6580  /* This is just to allow attaching to startup process with a debugger */
6581 #ifdef XLOG_REPLAY_DELAY
6583  pg_usleep(60000000L);
6584 #endif
6585 
6586  /*
6587  * Verify that pg_wal and pg_wal/archive_status exist. In cases where
6588  * someone has performed a copy for PITR, these directories may have been
6589  * excluded and need to be re-created.
6590  */
6592 
6593  /*----------
6594  * If we previously crashed, perform a couple of actions:
6595  *
6596  * - The pg_wal directory may still include some temporary WAL segments
6597  * used when creating a new segment, so perform some clean up to not
6598  * bloat this path. This is done first as there is no point to sync
6599  * this temporary data.
6600  *
6601  * - There might be data which we had written, intending to fsync it, but
6602  * which we had not actually fsync'd yet. Therefore, a power failure in
6603  * the near future might cause earlier unflushed writes to be lost, even
6604  * though more recent data written to disk from here on would be
6605  * persisted. To avoid that, fsync the entire data directory.
6606  */
6607  if (ControlFile->state != DB_SHUTDOWNED &&
6609  {
6612  }
6613 
6614  /*
6615  * Initialize on the assumption we want to recover to the latest timeline
6616  * that's active according to pg_control.
6617  */
6621  else
6623 
6624  /*
6625  * Check for signal files, and if so set up state for offline recovery
6626  */
6629 
6631  {
6633  ereport(LOG,
6634  (errmsg("entering standby mode")));
6635  else if (recoveryTarget == RECOVERY_TARGET_XID)