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 InHotStandby   (standbyState >= STANDBY_SNAPSHOT_PENDING)
 
#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_CAUSE_XLOG   0x0040 /* XLOG consumption */
 
#define CHECKPOINT_CAUSE_TIME   0x0080 /* Elapsed time */
 
#define XLOG_INCLUDE_ORIGIN   0x01 /* include the replication origin */
 
#define XLOG_MARK_UNIMPORTANT   0x02 /* record not important for durability */
 
#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"
 
#define FALLBACK_PROMOTE_SIGNAL_FILE   "fallback_promote"
 

Typedefs

typedef enum ArchiveMode ArchiveMode
 
typedef enum WalLevel WalLevel
 
typedef struct CheckpointStatsData CheckpointStatsData
 
typedef enum SessionBackupState SessionBackupState
 

Enumerations

enum  HotStandbyState { STANDBY_DISABLED, STANDBY_INITIALIZED, STANDBY_SNAPSHOT_PENDING, STANDBY_SNAPSHOT_READY }
 
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  SessionBackupState { SESSION_BACKUP_NONE, SESSION_BACKUP_EXCLUSIVE, SESSION_BACKUP_NON_EXCLUSIVE }
 

Functions

XLogRecPtr XLogInsertRecord (struct XLogRecData *rdata, XLogRecPtr fpw_lsn, uint8 flags)
 
void XLogFlush (XLogRecPtr RecPtr)
 
bool XLogBackgroundFlush (void)
 
bool XLogNeedsFlush (XLogRecPtr RecPtr)
 
int XLogFileInit (XLogSegNo segno, bool *use_existent, bool use_lock)
 
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)
 
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)
 
bool RecoveryIsPaused (void)
 
void SetRecoveryPause (bool recoveryPause)
 
TimestampTz GetLatestXTime (void)
 
TimestampTz GetCurrentChunkReplayStartTime (void)
 
char * XLogFileNameP (TimeLineID tli, XLogSegNo segno)
 
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)
 
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 GetNextXidAndEpoch (TransactionId *xid, uint32 *epoch)
 
void RemovePromoteSignalFiles (void)
 
bool CheckPromoteSignal (void)
 
void WakeupRecovery (void)
 
void SetWalWriterSleeping (bool sleeping)
 
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, bool infotbssize, bool needtblspcmapfile)
 
XLogRecPtr do_pg_stop_backup (char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 
void do_pg_abort_backup (void)
 
SessionBackupState get_backup_status (void)
 

Variables

int sync_method
 
PGDLLIMPORT TimeLineID ThisTimeLineID
 
bool InRecovery
 
HotStandbyState standbyState
 
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_segments
 
int XLOGbuffers
 
int XLogArchiveTimeout
 
int wal_retrieve_retry_interval
 
char * XLogArchiveCommand
 
bool EnableHotStandby
 
bool fullPageWrites
 
bool wal_log_hints
 
bool wal_compression
 
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
 
TransactionId recoveryTargetXid
 
TimestampTz recoveryTargetTime
 
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 358 of file xlog.h.

Referenced by CancelBackup(), and StartupXLOG().

◆ CHECKPOINT_CAUSE_TIME

#define CHECKPOINT_CAUSE_TIME   0x0080 /* Elapsed time */

Definition at line 220 of file xlog.h.

Referenced by CheckpointerMain(), and LogCheckpointStart().

◆ CHECKPOINT_CAUSE_XLOG

#define CHECKPOINT_CAUSE_XLOG   0x0040 /* XLOG consumption */

Definition at line 219 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 210 of file xlog.h.

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

◆ CHECKPOINT_FLUSH_ALL

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

Definition at line 214 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_WAIT

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

◆ FALLBACK_PROMOTE_SIGNAL_FILE

#define FALLBACK_PROMOTE_SIGNAL_FILE   "fallback_promote"

Definition at line 365 of file xlog.h.

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

◆ InHotStandby

◆ PROMOTE_SIGNAL_FILE

#define PROMOTE_SIGNAL_FILE   "promote"

◆ RECOVERY_SIGNAL_FILE

#define RECOVERY_SIGNAL_FILE   "recovery.signal"

Definition at line 355 of file xlog.h.

Referenced by exitArchiveRecovery(), and readRecoverySignalFile().

◆ STANDBY_SIGNAL_FILE

#define STANDBY_SIGNAL_FILE   "standby.signal"

Definition at line 356 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 361 of file xlog.h.

Referenced by CancelBackup(), and StartupXLOG().

◆ XLOG_INCLUDE_ORIGIN

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

◆ XLOG_MARK_UNIMPORTANT

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

◆ XLogArchiveCommandSet

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

Definition at line 173 of file xlog.h.

Referenced by pgarch_ArchiverCopyLoop(), and ShutdownXLOG().

◆ XLogArchivingActive

◆ XLogArchivingAlways

Definition at line 171 of file xlog.h.

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

◆ XLogHintBitIsNeeded

◆ XLogIsNeeded

◆ XLogLogicalInfoActive

#define XLogLogicalInfoActive ( )    (wal_level >= WAL_LEVEL_LOGICAL)

◆ XLogStandbyInfoActive

Typedef Documentation

◆ ArchiveMode

◆ CheckpointStatsData

◆ SessionBackupState

◆ WalLevel

Enumeration Type Documentation

◆ ArchiveMode

Enumerator
ARCHIVE_MODE_OFF 
ARCHIVE_MODE_ON 
ARCHIVE_MODE_ALWAYS 

Definition at line 149 of file xlog.h.

150 {
151  ARCHIVE_MODE_OFF = 0, /* disabled */
152  ARCHIVE_MODE_ON, /* enabled while server is running normally */
153  ARCHIVE_MODE_ALWAYS /* enabled always (even during recovery) */
154 } ArchiveMode;
ArchiveMode
Definition: xlog.h:149

◆ HotStandbyState

Enumerator
STANDBY_DISABLED 
STANDBY_INITIALIZED 
STANDBY_SNAPSHOT_PENDING 
STANDBY_SNAPSHOT_READY 

Definition at line 64 of file xlog.h.

◆ RecoveryTargetTimeLineGoal

Enumerator
RECOVERY_TARGET_TIMELINE_CONTROLFILE 
RECOVERY_TARGET_TIMELINE_LATEST 
RECOVERY_TARGET_TIMELINE_NUMERIC 

Definition at line 93 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 80 of file xlog.h.

◆ SessionBackupState

Enumerator
SESSION_BACKUP_NONE 
SESSION_BACKUP_EXCLUSIVE 
SESSION_BACKUP_NON_EXCLUSIVE 

Definition at line 338 of file xlog.h.

◆ WalLevel

enum WalLevel
Enumerator
WAL_LEVEL_MINIMAL 
WAL_LEVEL_REPLICA 
WAL_LEVEL_LOGICAL 

Definition at line 158 of file xlog.h.

Function Documentation

◆ assign_checkpoint_completion_target()

void assign_checkpoint_completion_target ( double  newval,
void *  extra 
)

Definition at line 2292 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

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

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2285 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

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

◆ BootStrapXLOG()

void BootStrapXLOG ( void  )

Definition at line 5098 of file xlog.c.

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

Referenced by AuxiliaryProcessMain().

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

◆ CheckPromoteSignal()

bool CheckPromoteSignal ( void  )

Definition at line 12232 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, PROMOTE_SIGNAL_FILE, and stat.

Referenced by sigusr1_handler().

12233 {
12234  struct stat stat_buf;
12235 
12236  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
12238  return true;
12239 
12240  return false;
12241 }
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:364
struct stat stat_buf
Definition: pg_standby.c:102
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.h:365
#define stat(a, b)
Definition: win32_port.h:264

◆ CheckXLogRemoved()

void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)

Definition at line 3826 of file xlog.c.

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

Referenced by perform_base_backup(), and XLogRead().

3827 {
3828  int save_errno = errno;
3829  XLogSegNo lastRemovedSegNo;
3830 
3832  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3834 
3835  if (segno <= lastRemovedSegNo)
3836  {
3837  char filename[MAXFNAMELEN];
3838 
3839  XLogFileName(filename, tli, segno, wal_segment_size);
3840  errno = save_errno;
3841  ereport(ERROR,
3843  errmsg("requested WAL segment %s has already been removed",
3844  filename)));
3845  }
3846  errno = save_errno;
3847 }
int wal_segment_size
Definition: xlog.c:109
slock_t info_lck
Definition: xlog.c:709
XLogSegNo lastRemovedSegNo
Definition: xlog.c:598
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define ERROR
Definition: elog.h:43
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static XLogCtlData * XLogCtl
Definition: xlog.c:712
static char * filename
Definition: pg_dumpall.c:88
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ CreateCheckPoint()

void CreateCheckPoint ( int  flags)

Definition at line 8535 of file xlog.c.

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

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

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

◆ CreateRestartPoint()

bool CreateRestartPoint ( int  flags)

Definition at line 9081 of file xlog.c.

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

Referenced by CheckpointerMain(), and ShutdownXLOG().

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

◆ DataChecksumsEnabled()

bool DataChecksumsEnabled ( void  )

Definition at line 4833 of file xlog.c.

References Assert, and ControlFileData::data_checksum_version.

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

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

◆ do_pg_abort_backup()

void do_pg_abort_backup ( void  )

Definition at line 11126 of file xlog.c.

References Assert, EXCLUSIVE_BACKUP_NONE, XLogCtlInsert::exclusiveBackupState, XLogCtlInsert::forcePageWrites, XLogCtlData::Insert, XLogCtlInsert::nonExclusiveBackups, SESSION_BACKUP_NON_EXCLUSIVE, SESSION_BACKUP_NONE, sessionBackupState, WALInsertLockAcquireExclusive(), and WALInsertLockRelease().

Referenced by base_backup_cleanup(), and nonexclusive_base_backup_cleanup().

11127 {
11128  /*
11129  * Quick exit if session is not keeping around a non-exclusive backup
11130  * already started.
11131  */
11133  return;
11134 
11139 
11142  {
11143  XLogCtl->Insert.forcePageWrites = false;
11144  }
11146 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1691
static SessionBackupState sessionBackupState
Definition: xlog.c:523
XLogCtlInsert Insert
Definition: xlog.c:588
bool forcePageWrites
Definition: xlog.c:562
int nonExclusiveBackups
Definition: xlog.c:574
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:573
#define Assert(condition)
Definition: c.h:732
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1662
static XLogCtlData * XLogCtl
Definition: xlog.c:712

◆ do_pg_start_backup()

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

Definition at line 10204 of file xlog.c.

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

Referenced by perform_base_backup(), and pg_start_backup().

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

◆ do_pg_stop_backup()

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

Definition at line 10721 of file xlog.c.

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

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

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

◆ get_backup_status()

SessionBackupState get_backup_status ( void  )

Definition at line 10702 of file xlog.c.

References sessionBackupState.

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

10703 {
10704  return sessionBackupState;
10705 }
static SessionBackupState sessionBackupState
Definition: xlog.c:523

◆ GetCurrentChunkReplayStartTime()

TimestampTz GetCurrentChunkReplayStartTime ( void  )

Definition at line 6082 of file xlog.c.

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

Referenced by GetReplicationApplyDelay().

6083 {
6084  TimestampTz xtime;
6085 
6087  xtime = XLogCtl->currentChunkStartTime;
6089 
6090  return xtime;
6091 }
int64 TimestampTz
Definition: timestamp.h:39
slock_t info_lck
Definition: xlog.c:709
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:712
TimestampTz currentChunkStartTime
Definition: xlog.c:699

◆ GetFakeLSNForUnloggedRel()

XLogRecPtr GetFakeLSNForUnloggedRel ( void  )

Definition at line 4849 of file xlog.c.

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

Referenced by gistGetFakeLSN().

4850 {
4851  XLogRecPtr nextUnloggedLSN;
4852 
4853  /* increment the unloggedLSN counter, need SpinLock */
4855  nextUnloggedLSN = XLogCtl->unloggedLSN++;
4857 
4858  return nextUnloggedLSN;
4859 }
XLogRecPtr unloggedLSN
Definition: xlog.c:601
#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:712
slock_t ulsn_lck
Definition: xlog.c:602

◆ GetFlushRecPtr()

XLogRecPtr GetFlushRecPtr ( void  )

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

8221 {
8225 
8226  return LogwrtResult.Flush;
8227 }
static XLogwrtResult LogwrtResult
Definition: xlog.c:756
slock_t info_lck
Definition: xlog.c:709
#define SpinLockAcquire(lock)
Definition: spin.h:62
XLogwrtResult LogwrtResult
Definition: xlog.c:612
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:712
XLogRecPtr Flush
Definition: xlog.c:437

◆ GetFullPageWriteInfo()

void GetFullPageWriteInfo ( XLogRecPtr RedoRecPtr_p,
bool doPageWrites_p 
)

Definition at line 8189 of file xlog.c.

References doPageWrites, and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

8190 {
8191  *RedoRecPtr_p = RedoRecPtr;
8192  *doPageWrites_p = doPageWrites;
8193 }
static bool doPageWrites
Definition: xlog.c:370
static XLogRecPtr RedoRecPtr
Definition: xlog.c:363

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )

Definition at line 8204 of file xlog.c.

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

Referenced by CheckpointerMain(), and IsCheckpointOnSchedule().

8205 {
8206  XLogRecPtr recptr;
8207 
8209  recptr = XLogCtl->LogwrtRqst.Write;
8211 
8212  return recptr;
8213 }
slock_t info_lck
Definition: xlog.c:709
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
XLogRecPtr Write
Definition: xlog.c:430
XLogwrtRqst LogwrtRqst
Definition: xlog.c:591
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:712

◆ GetLastImportantRecPtr()

XLogRecPtr GetLastImportantRecPtr ( void  )

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

8239 {
8241  int i;
8242 
8243  for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
8244  {
8245  XLogRecPtr last_important;
8246 
8247  /*
8248  * Need to take a lock to prevent torn reads of the LSN, which are
8249  * possible on some of the supported platforms. WAL insert locks only
8250  * support exclusive mode, so we have to use that.
8251  */
8253  last_important = WALInsertLocks[i].l.lastImportantAt;
8254  LWLockRelease(&WALInsertLocks[i].l.lock);
8255 
8256  if (res < last_important)
8257  res = last_important;
8258  }
8259 
8260  return res;
8261 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
XLogRecPtr lastImportantAt
Definition: xlog.c:480
#define NUM_XLOGINSERT_LOCKS
Definition: xlog.c:116
WALInsertLock l
Definition: xlog.c:492
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
uint64 XLogRecPtr
Definition: xlogdefs.h:21
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
int i
static WALInsertLockPadded * WALInsertLocks
Definition: xlog.c:715

◆ GetLatestXTime()

TimestampTz GetLatestXTime ( void  )

Definition at line 6052 of file xlog.c.

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

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

6053 {
6054  TimestampTz xtime;
6055 
6057  xtime = XLogCtl->recoveryLastXTime;
6059 
6060  return xtime;
6061 }
int64 TimestampTz
Definition: timestamp.h:39
slock_t info_lck
Definition: xlog.c:709
#define SpinLockAcquire(lock)
Definition: spin.h:62
TimestampTz recoveryLastXTime
Definition: xlog.c:693
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:712

◆ GetMockAuthenticationNonce()

char* GetMockAuthenticationNonce ( void  )

Definition at line 4823 of file xlog.c.

References Assert, and ControlFileData::mock_authentication_nonce.

Referenced by scram_mock_salt().

4824 {
4825  Assert(ControlFile != NULL);
4827 }
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition: pg_control.h:228
static ControlFileData * ControlFile
Definition: xlog.c:720
#define Assert(condition)
Definition: c.h:732

◆ GetNextXidAndEpoch()

void GetNextXidAndEpoch ( TransactionId xid,
uint32 epoch 
)

Definition at line 8289 of file xlog.c.

References XLogCtlData::ckptXid, XLogCtlData::ckptXidEpoch, XLogCtlData::info_lck, ReadNewTransactionId(), SpinLockAcquire, and SpinLockRelease.

Referenced by load_xid_epoch(), TransactionIdInRecentPast(), and XLogWalRcvSendHSFeedback().

8290 {
8291  uint32 ckptXidEpoch;
8292  TransactionId ckptXid;
8293  TransactionId nextXid;
8294 
8295  /* Must read checkpoint info first, else have race condition */
8297  ckptXidEpoch = XLogCtl->ckptXidEpoch;
8298  ckptXid = XLogCtl->ckptXid;
8300 
8301  /* Now fetch current nextXid */
8302  nextXid = ReadNewTransactionId();
8303 
8304  /*
8305  * nextXid is certainly logically later than ckptXid. So if it's
8306  * numerically less, it must have wrapped into the next epoch.
8307  */
8308  if (nextXid < ckptXid)
8309  ckptXidEpoch++;
8310 
8311  *xid = nextXid;
8312  *epoch = ckptXidEpoch;
8313 }
TransactionId ckptXid
Definition: xlog.c:594
uint32 TransactionId
Definition: c.h:507
slock_t info_lck
Definition: xlog.c:709
uint32 ckptXidEpoch
Definition: xlog.c:593
#define SpinLockAcquire(lock)
Definition: spin.h:62
TransactionId ReadNewTransactionId(void)
Definition: varsup.c:242
unsigned int uint32
Definition: c.h:358
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:712
static const unsigned __int64 epoch
Definition: gettimeofday.c:34

◆ GetRedoRecPtr()

XLogRecPtr GetRedoRecPtr ( void  )

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

8162 {
8163  XLogRecPtr ptr;
8164 
8165  /*
8166  * The possibly not up-to-date copy in XlogCtl is enough. Even if we
8167  * grabbed a WAL insertion lock to read the master copy, someone might
8168  * update it just after we've released the lock.
8169  */
8171  ptr = XLogCtl->RedoRecPtr;
8173 
8174  if (RedoRecPtr < ptr)
8175  RedoRecPtr = ptr;
8176 
8177  return RedoRecPtr;
8178 }
slock_t info_lck
Definition: xlog.c:709
#define SpinLockAcquire(lock)
Definition: spin.h:62
static XLogRecPtr RedoRecPtr
Definition: xlog.c:363
XLogRecPtr RedoRecPtr
Definition: xlog.c:592
#define SpinLockRelease(lock)
Definition: spin.h:64
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:712

◆ GetSystemIdentifier()

uint64 GetSystemIdentifier ( void  )

Definition at line 4813 of file xlog.c.

References Assert, and ControlFileData::system_identifier.

Referenced by IdentifySystem(), and WalReceiverMain().

4814 {
4815  Assert(ControlFile != NULL);
4817 }
uint64 system_identifier
Definition: pg_control.h:106
static ControlFileData * ControlFile
Definition: xlog.c:720
#define Assert(condition)
Definition: c.h:732

◆ GetXLogInsertRecPtr()

XLogRecPtr GetXLogInsertRecPtr ( void  )

Definition at line 11173 of file xlog.c.

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

Referenced by GetSnapshotData(), logical_begin_heap_rewrite(), pg_current_wal_insert_lsn(), and ReplicationSlotReserveWal().

11174 {
11176  uint64 current_bytepos;
11177 
11178  SpinLockAcquire(&Insert->insertpos_lck);
11179  current_bytepos = Insert->CurrBytePos;
11180  SpinLockRelease(&Insert->insertpos_lck);
11181 
11182  return XLogBytePosToRecPtr(current_bytepos);
11183 }
slock_t insertpos_lck
Definition: xlog.c:530
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1960
XLogCtlInsert Insert
Definition: xlog.c:588
#define SpinLockAcquire(lock)
Definition: spin.h:62
uint64 CurrBytePos
Definition: xlog.c:539
static void Insert(File file)
Definition: fd.c:1035
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:712

◆ GetXLogReceiptTime()

void GetXLogReceiptTime ( TimestampTz rtime,
bool fromStream 
)

Definition at line 6098 of file xlog.c.

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

Referenced by GetStandbyLimitTime().

6099 {
6100  /*
6101  * This must be executed in the startup process, since we don't export the
6102  * relevant state to shared memory.
6103  */
6104  Assert(InRecovery);
6105 
6106  *rtime = XLogReceiptTime;
6107  *fromStream = (XLogReceiptSource == XLOG_FROM_STREAM);
6108 }
static XLogSource XLogReceiptSource
Definition: xlog.c:823
bool InRecovery
Definition: xlog.c:197
static TimestampTz XLogReceiptTime
Definition: xlog.c:822
#define Assert(condition)
Definition: c.h:732

◆ GetXLogReplayRecPtr()

XLogRecPtr GetXLogReplayRecPtr ( TimeLineID replayTLI)

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

11155 {
11156  XLogRecPtr recptr;
11157  TimeLineID tli;
11158 
11160  recptr = XLogCtl->lastReplayedEndRecPtr;
11161  tli = XLogCtl->lastReplayedTLI;
11163 
11164  if (replayTLI)
11165  *replayTLI = tli;
11166  return recptr;
11167 }
uint32 TimeLineID
Definition: xlogdefs.h:45
slock_t info_lck
Definition: xlog.c:709
#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:712
TimeLineID lastReplayedTLI
Definition: xlog.c:689
XLogRecPtr lastReplayedEndRecPtr
Definition: xlog.c:688

◆ GetXLogWriteRecPtr()

XLogRecPtr GetXLogWriteRecPtr ( void  )

Definition at line 11189 of file xlog.c.

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

Referenced by pg_attribute_noreturn(), and pg_current_wal_lsn().

11190 {
11194 
11195  return LogwrtResult.Write;
11196 }
static XLogwrtResult LogwrtResult
Definition: xlog.c:756
slock_t info_lck
Definition: xlog.c:709
#define SpinLockAcquire(lock)
Definition: spin.h:62
XLogwrtResult LogwrtResult
Definition: xlog.c:612
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:712
XLogRecPtr Write
Definition: xlog.c:436

◆ HotStandbyActive()

bool HotStandbyActive ( void  )

Definition at line 7944 of file xlog.c.

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

Referenced by XLogWalRcvSendHSFeedback().

7945 {
7946  /*
7947  * We check shared state each time only until Hot Standby is active. We
7948  * can't de-activate Hot Standby, so there's no need to keep checking
7949  * after the shared variable has once been seen true.
7950  */
7952  return true;
7953  else
7954  {
7955  /* spinlock is essential on machines with weak memory ordering! */
7959 
7960  return LocalHotStandbyActive;
7961  }
7962 }
bool SharedHotStandbyActive
Definition: xlog.c:654
slock_t info_lck
Definition: xlog.c:709
#define SpinLockAcquire(lock)
Definition: spin.h:62
static bool LocalHotStandbyActive
Definition: xlog.c:226
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:712

◆ HotStandbyActiveInReplay()

bool HotStandbyActiveInReplay ( void  )

Definition at line 7969 of file xlog.c.

References AmStartupProcess, Assert, IsPostmasterEnvironment, and LocalHotStandbyActive.

Referenced by btree_xlog_vacuum().

7970 {
7972  return LocalHotStandbyActive;
7973 }
#define AmStartupProcess()
Definition: miscadmin.h:412
bool IsPostmasterEnvironment
Definition: globals.c:108
static bool LocalHotStandbyActive
Definition: xlog.c:226
#define Assert(condition)
Definition: c.h:732

◆ InitXLOGAccess()

void InitXLOGAccess ( void  )

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

8136 {
8138 
8139  /* ThisTimeLineID doesn't change so we need no lock to copy it */
8142 
8143  /* set wal_segment_size */
8145 
8146  /* Use GetRedoRecPtr to copy the RedoRecPtr safely */
8147  (void) GetRedoRecPtr();
8148  /* Also update our copy of doPageWrites. */
8149  doPageWrites = (Insert->fullPageWrites || Insert->forcePageWrites);
8150 
8151  /* Also initialize the working areas for constructing WAL records */
8152  InitXLogInsert();
8153 }
int wal_segment_size
Definition: xlog.c:109
void InitXLogInsert(void)
Definition: xloginsert.c:1028
TimeLineID ThisTimeLineID
Definition: xlog.c:641
XLogCtlInsert Insert
Definition: xlog.c:588
bool fullPageWrites
Definition: xlog.c:563
uint32 xlog_seg_size
Definition: pg_control.h:208
static bool doPageWrites
Definition: xlog.c:370
bool forcePageWrites
Definition: xlog.c:562
static void Insert(File file)
Definition: fd.c:1035
static ControlFileData * ControlFile
Definition: xlog.c:720
TimeLineID ThisTimeLineID
Definition: xlog.c:184
#define Assert(condition)
Definition: c.h:732
static XLogCtlData * XLogCtl
Definition: xlog.c:712
XLogRecPtr GetRedoRecPtr(void)
Definition: xlog.c:8161
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:374

◆ issue_xlog_fsync()

void issue_xlog_fsync ( int  fd,
XLogSegNo  segno 
)

Definition at line 10112 of file xlog.c.

References elog, ereport, errcode_for_file_access(), errmsg(), 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, WAIT_EVENT_WAL_SYNC, and XLogFileNameP().

Referenced by XLogWalRcvFlush(), and XLogWrite().

10113 {
10115  switch (sync_method)
10116  {
10117  case SYNC_METHOD_FSYNC:
10118  if (pg_fsync_no_writethrough(fd) != 0)
10119  ereport(PANIC,
10121  errmsg("could not fsync file \"%s\": %m",
10122  XLogFileNameP(ThisTimeLineID, segno))));
10123  break;
10124 #ifdef HAVE_FSYNC_WRITETHROUGH
10126  if (pg_fsync_writethrough(fd) != 0)
10127  ereport(PANIC,
10129  errmsg("could not fsync write-through file \"%s\": %m",
10130  XLogFileNameP(ThisTimeLineID, segno))));
10131  break;
10132 #endif
10133 #ifdef HAVE_FDATASYNC
10134  case SYNC_METHOD_FDATASYNC:
10135  if (pg_fdatasync(fd) != 0)
10136  ereport(PANIC,
10138  errmsg("could not fdatasync file \"%s\": %m",
10139  XLogFileNameP(ThisTimeLineID, segno))));
10140  break;
10141 #endif
10142  case SYNC_METHOD_OPEN:
10144  /* write synced it already */
10145  break;
10146  default:
10147  elog(PANIC, "unrecognized wal_sync_method: %d", sync_method);
10148  break;
10149  }
10151 }
int pg_fdatasync(int fd)
Definition: fd.c:385
#define SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:28
int pg_fsync_writethrough(int fd)
Definition: fd.c:362
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:350
#define PANIC
Definition: elog.h:53
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define SYNC_METHOD_OPEN_DSYNC
Definition: xlog.h:29
char * XLogFileNameP(TimeLineID tli, XLogSegNo segno)
Definition: xlog.c:10157
int errcode_for_file_access(void)
Definition: elog.c:593
#define SYNC_METHOD_FSYNC
Definition: xlog.h:25
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1262
#define ereport(elevel, rest)
Definition: elog.h:141
#define SYNC_METHOD_OPEN
Definition: xlog.h:27
TimeLineID ThisTimeLineID
Definition: xlog.c:184
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1238
int sync_method
Definition: xlog.c:99
#define SYNC_METHOD_FDATASYNC
Definition: xlog.h:26
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226

◆ LocalProcessControlFile()

void LocalProcessControlFile ( bool  reset)

Definition at line 4933 of file xlog.c.

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

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

4934 {
4935  Assert(reset || ControlFile == NULL);
4936  ControlFile = palloc(sizeof(ControlFileData));
4937  ReadControlFile();
4938 }
static void ReadControlFile(void)
Definition: xlog.c:4551
static ControlFileData * ControlFile
Definition: xlog.c:720
#define Assert(condition)
Definition: c.h:732
void * palloc(Size size)
Definition: mcxt.c:924

◆ RecoveryInProgress()

bool RecoveryInProgress ( void  )

Definition at line 7888 of file xlog.c.

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

Referenced by BackgroundWriterMain(), brin_desummarize_range(), brin_summarize_range(), check_transaction_read_only(), check_XactIsoLevel(), CheckArchiveTimeout(), CheckLogicalDecodingRequirements(), CheckpointerMain(), CreateCheckPoint(), CreateEndOfRecoveryRecord(), CreateRestartPoint(), do_pg_start_backup(), do_pg_stop_backup(), error_commit_ts_disabled(), get_relation_info(), GetNewMultiXactId(), GetNewObjectId(), GetNewTransactionId(), GetOldestActiveTransactionId(), GetOldestSafeDecodingTransactionId(), GetOldestXmin(), GetRunningTransactionData(), GetSerializableTransactionSnapshot(), GetSerializableTransactionSnapshotInt(), GetSnapshotData(), gin_clean_pending_list(), heap_page_prune_opt(), IdentifySystem(), InitPostgres(), InitTempTableNamespace(), IsCheckpointOnSchedule(), LockAcquireExtended(), MarkBufferDirtyHint(), OldSerXidSetActiveSerXmin(), perform_base_backup(), pg_create_restore_point(), pg_current_wal_flush_lsn(), pg_current_wal_insert_lsn(), pg_current_wal_lsn(), 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(), sendDir(), ShutdownXLOG(), SnapBuildWaitSnapshot(), standard_ProcessUtility(), StartLogicalReplication(), StartTransaction(), TransactionIdIsInProgress(), TruncateMultiXact(), UpdateFullPageWrites(), WalReceiverMain(), WalSndWaitForWal(), XLogArchiveCheckDone(), XLogBackgroundFlush(), XLogInsertAllowed(), XLogNeedsFlush(), and XLogSendPhysical().

7889 {
7890  /*
7891  * We check shared state each time only until we leave recovery mode. We
7892  * can't re-enter recovery, so there's no need to keep checking after the
7893  * shared variable has once been seen false.
7894  */
7896  return false;
7897  else
7898  {
7899  /*
7900  * use volatile pointer to make sure we make a fresh read of the
7901  * shared variable.
7902  */
7903  volatile XLogCtlData *xlogctl = XLogCtl;
7904 
7906 
7907  /*
7908  * Initialize TimeLineID and RedoRecPtr when we discover that recovery
7909  * is finished. InitPostgres() relies upon this behaviour to ensure
7910  * that InitXLOGAccess() is called at backend startup. (If you change
7911  * this, see also LocalSetXLogInsertAllowed.)
7912  */
7914  {
7915  /*
7916  * If we just exited recovery, make sure we read TimeLineID and
7917  * RedoRecPtr after SharedRecoveryInProgress (for machines with
7918  * weak memory ordering).
7919  */
7921  InitXLOGAccess();
7922  }
7923 
7924  /*
7925  * Note: We don't need a memory barrier when we're still in recovery.
7926  * We might exit recovery immediately after return, so the caller
7927  * can't rely on 'true' meaning that we're still in recovery anyway.
7928  */
7929 
7930  return LocalRecoveryInProgress;
7931  }
7932 }
void InitXLOGAccess(void)
Definition: xlog.c:8135
bool SharedRecoveryInProgress
Definition: xlog.c:648
#define pg_memory_barrier()
Definition: atomics.h:148
static XLogCtlData * XLogCtl
Definition: xlog.c:712
static bool LocalRecoveryInProgress
Definition: xlog.c:220

◆ RecoveryIsPaused()

bool RecoveryIsPaused ( void  )

Definition at line 5921 of file xlog.c.

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

Referenced by pg_is_wal_replay_paused(), and recoveryPausesHere().

5922 {
5923  bool recoveryPause;
5924 
5926  recoveryPause = XLogCtl->recoveryPause;
5928 
5929  return recoveryPause;
5930 }
slock_t info_lck
Definition: xlog.c:709
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
bool recoveryPause
Definition: xlog.c:701
static XLogCtlData * XLogCtl
Definition: xlog.c:712

◆ RemovePromoteSignalFiles()

void RemovePromoteSignalFiles ( void  )

Definition at line 12221 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, and PROMOTE_SIGNAL_FILE.

Referenced by PostmasterMain().

12222 {
12223  unlink(PROMOTE_SIGNAL_FILE);
12225 }
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:364
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.h:365

◆ SetRecoveryPause()

void SetRecoveryPause ( bool  recoveryPause)

Definition at line 5933 of file xlog.c.

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

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

5934 {
5936  XLogCtl->recoveryPause = recoveryPause;
5938 }
slock_t info_lck
Definition: xlog.c:709
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
bool recoveryPause
Definition: xlog.c:701
static XLogCtlData * XLogCtl
Definition: xlog.c:712

◆ SetWalWriterSleeping()

void SetWalWriterSleeping ( bool  sleeping)

Definition at line 12257 of file xlog.c.

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

Referenced by WalWriterMain().

12258 {
12260  XLogCtl->WalWriterSleeping = sleeping;
12262 }
slock_t info_lck
Definition: xlog.c:709
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
bool WalWriterSleeping
Definition: xlog.c:661
static XLogCtlData * XLogCtl
Definition: xlog.c:712

◆ ShutdownXLOG()

void ShutdownXLOG ( int  code,
Datum  arg 
)

Definition at line 8319 of file xlog.c.

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

Referenced by CheckpointerMain(), and InitPostgres().

8320 {
8321  /*
8322  * We should have an aux process resource owner to use, and we should not
8323  * be in a transaction that's installed some other resowner.
8324  */
8326  Assert(CurrentResourceOwner == NULL ||
8329 
8330  /* Don't be chatty in standalone mode */
8332  (errmsg("shutting down")));
8333 
8334  /*
8335  * Signal walsenders to move to stopping state.
8336  */
8338 
8339  /*
8340  * Wait for WAL senders to be in stopping state. This prevents commands
8341  * from writing new WAL.
8342  */
8344 
8345  if (RecoveryInProgress())
8347  else
8348  {
8349  /*
8350  * If archiving is enabled, rotate the last XLOG file so that all the
8351  * remaining records are archived (postmaster wakes up the archiver
8352  * process one more time at the end of shutdown). The checkpoint
8353  * record will go to the next XLOG file and won't be archived (yet).
8354  */
8356  RequestXLogSwitch(false);
8357 
8359  }
8360  ShutdownCLOG();
8361  ShutdownCommitTs();
8362  ShutdownSUBTRANS();
8364 }
bool IsPostmasterEnvironment
Definition: globals.c:108
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9408
void ShutdownSUBTRANS(void)
Definition: subtrans.c:283
void CreateCheckPoint(int flags)
Definition: xlog.c:8535
ResourceOwner CurrentResourceOwner
Definition: resowner.c:141
void ShutdownCLOG(void)
Definition: clog.c:823
bool CreateRestartPoint(int flags)
Definition: xlog.c:9081
#define XLogArchiveCommandSet()
Definition: xlog.h:173
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:7888
ResourceOwner AuxProcessResourceOwner
Definition: resowner.c:144
void WalSndWaitStopping(void)
Definition: walsender.c:3126
void ShutdownMultiXact(void)
Definition: multixact.c:2105
#define ereport(elevel, rest)
Definition: elog.h:141
#define NOTICE
Definition: elog.h:37
void WalSndInitStopping(void)
Definition: walsender.c:3100
void ShutdownCommitTs(void)
Definition: commit_ts.c:744
#define Assert(condition)
Definition: c.h:732
#define XLogArchivingActive()
Definition: xlog.h:168
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:212
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:209

◆ StartupXLOG()

void StartupXLOG ( void  )

Definition at line 6180 of file xlog.c.

References 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::ckptXid, XLogCtlData::ckptXidEpoch, 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, EndRecPtr, ereport, errcode(), errcode_for_file_access(), errdetail(), errhint(), errmsg(), errmsg_internal(), ERROR, error_context_stack, ExecuteRecoveryCommand(), exitArchiveRecovery(), fast_promote, FATAL, findNewestTimeLine(), XLogwrtRqst::Flush, XLogwrtResult::Flush, CheckPoint::fullPageWrites, XLogCtlInsert::fullPageWrites, GetCurrentTimestamp(), GetLatestXTime(), HandleStartupProcInterrupts(), InArchiveRecovery, XLogCtlData::info_lck, XLogCtlData::InitializedUpTo, InitRecoveryTransactionEnvironment(), initStringInfo(), InRecovery, InRedo, Insert(), XLogCtlData::Insert, InvalidXLogRecPtr, IsPostmasterEnvironment, IsUnderPostmaster, lastFullPageWrites, LastRec, XLogCtlData::lastReplayedEndRecPtr, XLogCtlData::lastReplayedTLI, XLogCtlData::lastSegSwitchLSN, XLogCtlData::lastSegSwitchTime, RunningTransactionsData::latestCompletedXid, VariableCacheData::latestCompletedXid, lfirst, LocalSetXLogInsertAllowed(), LocalXLogInsertAllowed, LOG, XLogCtlData::LogwrtResult, LogwrtResult, XLogCtlData::LogwrtRqst, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), master_image_masked, 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, CheckPoint::nextXidEpoch, 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_usleep(), pgstat_reset_all(), PMSIGNAL_RECOVERY_STARTED, PreallocXlogFiles(), PrescanPreparedTransactions(), XLogCtlInsert::PrevBytePos, ErrorContextCallback::previous, CheckPoint::PrevTimeLineID, xl_end_of_recovery::PrevTimeLineID, XLogCtlData::PrevTimeLineID, proc_exit(), ProcArrayApplyRecoveryInfo(), ProcArrayInitRecovery(), psprintf(), PublishStartupProcessInformation(), reachedConsistency, read_backup_label(), read_tablespace_map(), XLogReaderState::readBuf, ReadCheckpointRecord(), readFile, readOff, XLogReaderState::readPageTLI, ReadRecord(), readRecoverySignalFile(), ReadRecPtr, RecordKnownAssignedTransactionIds(), RecoverPreparedTransactions(), 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_XID, recoveryApplyDelay(), recoveryEndCommand, XLogCtlData::recoveryLastXTime, XLogCtlData::recoveryPause, recoveryPausesHere(), recoveryStopAfter, recoveryStopLSN, recoveryStopName, recoveryStopsAfter(), recoveryStopsBefore(), recoveryStopTime, recoveryStopXid, 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, SendPostmasterSignal(), SetCommitTsLimit(), SetForwardFsyncRequests(), SetMultiXactIdLimit(), SetRecoveryPause(), SetTransactionIdLimit(), XLogCtlData::SharedRecoveryInProgress, ShmemVariableCache, ShutdownRecoveryTransactionEnvironment(), ShutdownWalRcv(), 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, TransactionIdAdvance, TransactionIdFollowsOrEquals(), TransactionIdIsNormal, TransactionIdIsValid, TransactionIdRetreat, TrimCLOG(), TrimMultiXact(), UNLOGGED_RELATION_CLEANUP, UNLOGGED_RELATION_INIT, ControlFileData::unloggedLSN, XLogCtlData::unloggedLSN, UpdateControlFile(), UpdateFullPageWrites(), validateRecoveryParameters(), ValidateXLOGDirectoryStructure(), wal_segment_size, WalRcvForceReply(), WalSndWakeup(), XLogwrtRqst::Write, XLogwrtResult::Write, writeTimeLineHistory(), RunningTransactionsData::xcnt, RunningTransactionsData::xids, XLogRecord::xl_info, XLogRecord::xl_rmid, XLogRecord::xl_xid, XLogCtlData::xlblocks, XLByteToPrevSeg, XLOG_CHECKPOINT_SHUTDOWN, XLOG_END_OF_RECOVERY, xlog_outdesc(), XLogArchiveCleanup(), XLogArchiveIsReadyOrDone(), XLogArchiveNotify(), XLogArchivingActive, XLogFileName, XLogFilePath, XLogPageRead(), XLogReaderAllocate(), XLogReaderFree(), XLogReceiptTime, XLogRecGetData, XLogRecPtrIsInvalid, XLogRecPtrToBufIdx, XLogRecPtrToBytePos(), XLogReportParameters(), XLogSegmentOffset, XLR_CHECK_CONSISTENCY, XLR_INFO_MASK, and XRecOffIsValid.

Referenced by InitPostgres(), and StartupProcessMain().

6181 {
6183  CheckPoint checkPoint;
6184  bool wasShutdown;
6185  bool reachedStopPoint = false;
6186  bool haveBackupLabel = false;
6187  bool haveTblspcMap = false;
6188  XLogRecPtr RecPtr,
6189  checkPointLoc,
6190  EndOfLog;
6191  TimeLineID EndOfLogTLI;
6192  TimeLineID PrevTimeLineID;
6193  XLogRecord *record;
6194  TransactionId oldestActiveXID;
6195  bool backupEndRequired = false;
6196  bool backupFromStandby = false;
6197  DBState dbstate_at_startup;
6198  XLogReaderState *xlogreader;
6199  XLogPageReadPrivate private;
6200  bool fast_promoted = false;
6201  struct stat st;
6202 
6203  /*
6204  * We should have an aux process resource owner to use, and we should not
6205  * be in a transaction that's installed some other resowner.
6206  */
6208  Assert(CurrentResourceOwner == NULL ||
6211 
6212  /*
6213  * Verify XLOG status looks valid.
6214  */
6215  if (ControlFile->state < DB_SHUTDOWNED ||
6218  ereport(FATAL,
6219  (errmsg("control file contains invalid data")));
6220 
6222  {
6223  /* This is the expected case, so don't be chatty in standalone mode */
6225  (errmsg("database system was shut down at %s",
6226  str_time(ControlFile->time))));
6227  }
6229  ereport(LOG,
6230  (errmsg("database system was shut down in recovery at %s",
6231  str_time(ControlFile->time))));
6232  else if (ControlFile->state == DB_SHUTDOWNING)
6233  ereport(LOG,
6234  (errmsg("database system shutdown was interrupted; last known up at %s",
6235  str_time(ControlFile->time))));
6236  else if (ControlFile->state == DB_IN_CRASH_RECOVERY)
6237  ereport(LOG,
6238  (errmsg("database system was interrupted while in recovery at %s",
6240  errhint("This probably means that some data is corrupted and"
6241  " you will have to use the last backup for recovery.")));
6243  ereport(LOG,
6244  (errmsg("database system was interrupted while in recovery at log time %s",
6246  errhint("If this has occurred more than once some data might be corrupted"
6247  " and you might need to choose an earlier recovery target.")));
6248  else if (ControlFile->state == DB_IN_PRODUCTION)
6249  ereport(LOG,
6250  (errmsg("database system was interrupted; last known up at %s",
6251  str_time(ControlFile->time))));
6252 
6253  /* This is just to allow attaching to startup process with a debugger */
6254 #ifdef XLOG_REPLAY_DELAY
6256  pg_usleep(60000000L);
6257 #endif
6258 
6259  /*
6260  * Verify that pg_wal and pg_wal/archive_status exist. In cases where
6261  * someone has performed a copy for PITR, these directories may have been
6262  * excluded and need to be re-created.
6263  */
6265 
6266  /*----------
6267  * If we previously crashed, perform a couple of actions:
6268  * - The pg_wal directory may still include some temporary WAL segments
6269  * used when creating a new segment, so perform some clean up to not
6270  * bloat this path. This is done first as there is no point to sync this
6271  * temporary data.
6272  * - There might be data which we had written, intending to fsync it,
6273  * but which we had not actually fsync'd yet. Therefore, a power failure
6274  * in the near future might cause earlier unflushed writes to be lost,
6275  * even though more recent data written to disk from here on would be
6276  * persisted. To avoid that, fsync the entire data directory.
6277  *---------
6278  */
6279  if (ControlFile->state != DB_SHUTDOWNED &&
6281  {
6284  }
6285 
6286  /*
6287  * Initialize on the assumption we want to recover to the latest timeline
6288  * that's active according to pg_control.
6289  */
6293  else
6295 
6296  /*
6297  * Check for signal files, and if so set up state for offline recovery
6298  */
6301 
6303  {
6305  ereport(LOG,
6306  (errmsg("entering standby mode")));
6307  else if (recoveryTarget == RECOVERY_TARGET_XID)
6308  ereport(LOG,
6309  (errmsg("starting point-in-time recovery to XID %u",
6310  recoveryTargetXid)));
6312  ereport(LOG,
6313  (errmsg("starting point-in-time recovery to %s",
6316  ereport(LOG,
6317  (errmsg("starting point-in-time recovery to \"%s\"",
6318  recoveryTargetName)));
6319  else if (recoveryTarget == RECOVERY_TARGET_LSN)
6320  ereport(LOG,
6321  (errmsg("starting point-in-time recovery to WAL location (LSN) \"%X/%X\"",
6322  (uint32) (recoveryTargetLSN >> 32),
6325  ereport(LOG,
6326  (errmsg("starting point-in-time recovery to earliest consistent point")));
6327  else
6328  ereport(LOG,
6329  (errmsg("starting archive recovery")));
6330  }
6331 
6332  /*
6333  * Take ownership of the wakeup latch if we're going to sleep during
6334  * recovery.
6335  */
6338 
6339  /* Set up XLOG reader facility */
6340  MemSet(&private, 0, sizeof(XLogPageReadPrivate));
6341  xlogreader = XLogReaderAllocate(wal_segment_size, &XLogPageRead, &private);
6342  if (!xlogreader)
6343  ereport(ERROR,
6344  (errcode(ERRCODE_OUT_OF_MEMORY),
6345  errmsg("out of memory"),
6346  errdetail("Failed while allocating a WAL reading processor.")));
6348 
6349  /*
6350  * Allocate two page buffers dedicated to WAL consistency checks. We do
6351  * it this way, rather than just making static arrays, for two reasons:
6352  * (1) no need to waste the storage in most instantiations of the backend;
6353  * (2) a static char array isn't guaranteed to have any particular
6354  * alignment, whereas palloc() will provide MAXALIGN'd storage.
6355  */
6356  replay_image_masked = (char *) palloc(BLCKSZ);
6357  master_image_masked = (char *) palloc(BLCKSZ);
6358 
6359  if (read_backup_label(&checkPointLoc, &backupEndRequired,
6360  &backupFromStandby))
6361  {
6362  List *tablespaces = NIL;
6363 
6364  /*
6365  * Archive recovery was requested, and thanks to the backup label
6366  * file, we know how far we need to replay to reach consistency. Enter
6367  * archive recovery directly.
6368  */
6369  InArchiveRecovery = true;
6371  StandbyMode = true;
6372 
6373  /*
6374  * When a backup_label file is present, we want to roll forward from
6375  * the checkpoint it identifies, rather than using pg_control.
6376  */
6377  record = ReadCheckpointRecord(xlogreader, checkPointLoc, 0, true);
6378  if (record != NULL)
6379  {
6380  memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
6381  wasShutdown = ((record->xl_info & ~XLR_INFO_MASK) == XLOG_CHECKPOINT_SHUTDOWN);
6382  ereport(DEBUG1,
6383  (errmsg("checkpoint record is at %X/%X",
6384  (uint32) (checkPointLoc >> 32), (uint32) checkPointLoc)));
6385  InRecovery = true; /* force recovery even if SHUTDOWNED */
6386 
6387  /*
6388  * Make sure that REDO location exists. This may not be the case
6389  * if there was a crash during an online backup, which left a
6390  * backup_label around that references a WAL segment that's
6391  * already been archived.
6392  */
6393  if (checkPoint.redo < checkPointLoc)
6394  {
6395  if (!ReadRecord(xlogreader, checkPoint.redo, LOG, false))
6396  ereport(FATAL,
6397  (errmsg("could not find redo location referenced by checkpoint record"),
6398  errhint("If you are not restoring from a backup, try removing the file \"%s/backup_label\".", DataDir)));
6399  }
6400  }
6401  else
6402  {
6403  ereport(FATAL,
6404  (errmsg("could not locate required checkpoint record"),
6405  errhint("If you are not restoring from a backup, try removing the file \"%s/backup_label\".", DataDir)));
6406  wasShutdown = false; /* keep compiler quiet */
6407  }
6408 
6409  /* read the tablespace_map file if present and create symlinks. */
6410  if (read_tablespace_map(&tablespaces))
6411  {
6412  ListCell *lc;
6413 
6414  foreach(lc, tablespaces)
6415  {
6416  tablespaceinfo *ti = lfirst(lc);
6417  char *linkloc;
6418 
6419  linkloc = psprintf("pg_tblspc/%s", ti->oid);
6420 
6421  /*
6422  * Remove the existing symlink if any and Create the symlink
6423  * under PGDATA.
6424  */
6425  remove_tablespace_symlink(linkloc);
6426 
6427  if (symlink(ti->path, linkloc) < 0)
6428  ereport(ERROR,
6430  errmsg("could not create symbolic link \"%s\": %m",
6431  linkloc)));
6432 
6433  pfree(ti->oid);
6434  pfree(ti->path);
6435  pfree(ti);
6436  }
6437 
6438  /* set flag to delete it later */
6439  haveTblspcMap = true;
6440  }
6441 
6442  /* set flag to delete it later */
6443  haveBackupLabel = true;
6444  }
6445  else
6446  {
6447  /*
6448  * If tablespace_map file is present without backup_label file, there
6449  * is no use of such file. There is no harm in retaining it, but it
6450  * is better to get rid of the map file so that we don't have any
6451  * redundant file in data directory and it will avoid any sort of
6452  * confusion. It seems prudent though to just rename the file out of
6453  * the way rather than delete it completely, also we ignore any error
6454  * that occurs in rename operation as even if map file is present
6455  * without backup_label file, it is harmless.
6456  */
6457  if (stat(TABLESPACE_MAP, &st) == 0)
6458  {
6459  unlink(TABLESPACE_MAP_OLD);
6461  ereport(LOG,
6462  (errmsg("ignoring file \"%s\" because no file \"%s\" exists",
6464  errdetail("File \"%s\" was renamed to \"%s\".",
6466  else
6467  ereport(LOG,
6468  (errmsg("ignoring file \"%s\" because no file \"%s\" exists",
6470  errdetail("Could not rename file \"%s\" to \"%s\": %m.",
6472  }
6473 
6474  /*
6475  * It's possible that archive recovery was requested, but we don't
6476  * know how far we need to replay the WAL before we reach consistency.
6477  * This can happen for example if a base backup is taken from a
6478  * running server using an atomic filesystem snapshot, without calling
6479  * pg_start/stop_backup. Or if you just kill a running master server
6480  * and put it into archive recovery by creating a recovery signal
6481  * file.
6482  *
6483  * Our strategy in that case is to perform crash recovery first,
6484  * replaying all the WAL present in pg_wal, and only enter archive
6485  * recovery after that.
6486  *
6487  * But usually we already know how far we need to replay the WAL (up
6488  * to minRecoveryPoint, up to backupEndPoint, or until we see an
6489  * end-of-backup record), and we can enter archive recovery directly.
6490  */
6496  {
6497  InArchiveRecovery = true;
6499  StandbyMode = true;
6500  }
6501 
6502  /* Get the last valid checkpoint record. */
6503  checkPointLoc = ControlFile->checkPoint;
6505  record = ReadCheckpointRecord(xlogreader, checkPointLoc, 1, true);
6506  if (record != NULL)
6507  {
6508  ereport(DEBUG1,
6509  (errmsg("checkpoint record is at %X/%X",
6510  (uint32) (checkPointLoc >> 32), (uint32) checkPointLoc)));
6511  }
6512  else
6513  {
6514  /*
6515  * We used to attempt to go back to a secondary checkpoint record
6516  * here, but only when not in standby mode. We now just fail if we
6517  * can't read the last checkpoint because this allows us to
6518  * simplify processing around checkpoints.
6519  */
6520  ereport(PANIC,
6521  (errmsg("could not locate a valid checkpoint record")));
6522  }
6523  memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
6524  wasShutdown = ((record->xl_info & ~XLR_INFO_MASK) == XLOG_CHECKPOINT_SHUTDOWN);
6525  }
6526 
6527  /*
6528  * Clear out any old relcache cache files. This is *necessary* if we do
6529  * any WAL replay, since that would probably result in the cache files
6530  * being out of sync with database reality. In theory we could leave them
6531  * in place if the database had been cleanly shut down, but it seems
6532  * safest to just remove them always and let them be rebuilt during the
6533  * first backend startup. These files needs to be removed from all
6534  * directories including pg_tblspc, however the symlinks are created only
6535  * after reading tablespace_map file in case of archive recovery from
6536  * backup, so needs to clear old relcache files here after creating
6537  * symlinks.
6538  */
6540 
6541  /*
6542  * If the location of the checkpoint record is not on the expected
6543  * timeline in the history of the requested timeline, we cannot proceed:
6544  * the backup is not part of the history of the requested timeline.
6545  */
6546  Assert(expectedTLEs); /* was initialized by reading checkpoint
6547  * record */
6548  if (tliOfPointInHistory(checkPointLoc, expectedTLEs) !=
6549  checkPoint.ThisTimeLineID)
6550  {
6551  XLogRecPtr switchpoint;
6552 
6553  /*
6554  * tliSwitchPoint will throw an error if the checkpoint's timeline is
6555  * not in expectedTLEs at all.
6556  */
6558  ereport(FATAL,
6559  (errmsg("requested timeline %u is not a child of this server's history",
6561  errdetail("Latest checkpoint is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X.",
6562  (uint32) (ControlFile->checkPoint >> 32),
6565  (uint32) (switchpoint >> 32),
6566  (uint32) switchpoint)));
6567  }
6568 
6569  /*
6570  * The min recovery point should be part of the requested timeline's
6571  * history, too.
6572  */
6576  ereport(FATAL,
6577  (errmsg("requested timeline %u does not contain minimum recovery point %X/%X on timeline %u",
6579  (uint32) (ControlFile->minRecoveryPoint >> 32),
6582 
6583