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 2291 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

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

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2284 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

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

◆ BootStrapXLOG()

void BootStrapXLOG ( void  )

Definition at line 5097 of file xlog.c.

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

Referenced by AuxiliaryProcessMain().

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

References FALLBACK_PROMOTE_SIGNAL_FILE, PROMOTE_SIGNAL_FILE, and stat.

Referenced by sigusr1_handler().

12251 {
12252  struct stat stat_buf;
12253 
12254  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
12256  return true;
12257 
12258  return false;
12259 }
#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 3825 of file xlog.c.

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

Referenced by perform_base_backup(), and XLogRead().

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

◆ CreateCheckPoint()

void CreateCheckPoint ( int  flags)

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

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

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

◆ DataChecksumsEnabled()

bool DataChecksumsEnabled ( void  )

Definition at line 4832 of file xlog.c.

References Assert, and ControlFileData::data_checksum_version.

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

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

◆ do_pg_abort_backup()

void do_pg_abort_backup ( void  )

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

11144 {
11145  /*
11146  * Quick exit if session is not keeping around a non-exclusive backup
11147  * already started.
11148  */
11150  return;
11151 
11156 
11159  {
11160  XLogCtl->Insert.forcePageWrites = false;
11161  }
11163 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1690
static SessionBackupState sessionBackupState
Definition: xlog.c:522
XLogCtlInsert Insert
Definition: xlog.c:587
bool forcePageWrites
Definition: xlog.c:561
int nonExclusiveBackups
Definition: xlog.c:573
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:572
#define Assert(condition)
Definition: c.h:732
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1661
static XLogCtlData * XLogCtl
Definition: xlog.c:711

◆ do_pg_start_backup()

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

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

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

◆ do_pg_stop_backup()

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

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

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

References sessionBackupState.

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

10718 {
10719  return sessionBackupState;
10720 }
static SessionBackupState sessionBackupState
Definition: xlog.c:522

◆ GetCurrentChunkReplayStartTime()

TimestampTz GetCurrentChunkReplayStartTime ( void  )

Definition at line 6089 of file xlog.c.

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

Referenced by GetReplicationApplyDelay().

6090 {
6091  TimestampTz xtime;
6092 
6094  xtime = XLogCtl->currentChunkStartTime;
6096 
6097  return xtime;
6098 }
int64 TimestampTz
Definition: timestamp.h:39
slock_t info_lck
Definition: xlog.c:708
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:711
TimestampTz currentChunkStartTime
Definition: xlog.c:698

◆ GetFakeLSNForUnloggedRel()

XLogRecPtr GetFakeLSNForUnloggedRel ( void  )

Definition at line 4848 of file xlog.c.

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

Referenced by gistGetFakeLSN().

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

◆ GetFlushRecPtr()

XLogRecPtr GetFlushRecPtr ( void  )

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

8231 {
8235 
8236  return LogwrtResult.Flush;
8237 }
static XLogwrtResult LogwrtResult
Definition: xlog.c:755
slock_t info_lck
Definition: xlog.c:708
#define SpinLockAcquire(lock)
Definition: spin.h:62
XLogwrtResult LogwrtResult
Definition: xlog.c:611
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:711
XLogRecPtr Flush
Definition: xlog.c:436

◆ GetFullPageWriteInfo()

void GetFullPageWriteInfo ( XLogRecPtr RedoRecPtr_p,
bool doPageWrites_p 
)

Definition at line 8199 of file xlog.c.

References doPageWrites, and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

8200 {
8201  *RedoRecPtr_p = RedoRecPtr;
8202  *doPageWrites_p = doPageWrites;
8203 }
static bool doPageWrites
Definition: xlog.c:369
static XLogRecPtr RedoRecPtr
Definition: xlog.c:362

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )

Definition at line 8214 of file xlog.c.

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

Referenced by CheckpointerMain(), and IsCheckpointOnSchedule().

8215 {
8216  XLogRecPtr recptr;
8217 
8219  recptr = XLogCtl->LogwrtRqst.Write;
8221 
8222  return recptr;
8223 }
slock_t info_lck
Definition: xlog.c:708
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
XLogRecPtr Write
Definition: xlog.c:429
XLogwrtRqst LogwrtRqst
Definition: xlog.c:590
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:711

◆ GetLastImportantRecPtr()

XLogRecPtr GetLastImportantRecPtr ( void  )

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

8249 {
8251  int i;
8252 
8253  for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
8254  {
8255  XLogRecPtr last_important;
8256 
8257  /*
8258  * Need to take a lock to prevent torn reads of the LSN, which are
8259  * possible on some of the supported platforms. WAL insert locks only
8260  * support exclusive mode, so we have to use that.
8261  */
8263  last_important = WALInsertLocks[i].l.lastImportantAt;
8264  LWLockRelease(&WALInsertLocks[i].l.lock);
8265 
8266  if (res < last_important)
8267  res = last_important;
8268  }
8269 
8270  return res;
8271 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
XLogRecPtr lastImportantAt
Definition: xlog.c:479
#define NUM_XLOGINSERT_LOCKS
Definition: xlog.c:115
WALInsertLock l
Definition: xlog.c:491
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:714

◆ GetLatestXTime()

TimestampTz GetLatestXTime ( void  )

Definition at line 6059 of file xlog.c.

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

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

6060 {
6061  TimestampTz xtime;
6062 
6064  xtime = XLogCtl->recoveryLastXTime;
6066 
6067  return xtime;
6068 }
int64 TimestampTz
Definition: timestamp.h:39
slock_t info_lck
Definition: xlog.c:708
#define SpinLockAcquire(lock)
Definition: spin.h:62
TimestampTz recoveryLastXTime
Definition: xlog.c:692
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:711

◆ GetMockAuthenticationNonce()

char* GetMockAuthenticationNonce ( void  )

Definition at line 4822 of file xlog.c.

References Assert, and ControlFileData::mock_authentication_nonce.

Referenced by scram_mock_salt().

4823 {
4824  Assert(ControlFile != NULL);
4826 }
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition: pg_control.h:229
static ControlFileData * ControlFile
Definition: xlog.c:719
#define Assert(condition)
Definition: c.h:732

◆ GetNextXidAndEpoch()

void GetNextXidAndEpoch ( TransactionId xid,
uint32 epoch 
)

Definition at line 8299 of file xlog.c.

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

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

8300 {
8301  uint32 ckptXidEpoch;
8302  TransactionId ckptXid;
8303  TransactionId nextXid;
8304 
8305  /* Must read checkpoint info first, else have race condition */
8307  ckptXidEpoch = XLogCtl->ckptXidEpoch;
8308  ckptXid = XLogCtl->ckptXid;
8310 
8311  /* Now fetch current nextXid */
8312  nextXid = ReadNewTransactionId();
8313 
8314  /*
8315  * nextXid is certainly logically later than ckptXid. So if it's
8316  * numerically less, it must have wrapped into the next epoch.
8317  */
8318  if (nextXid < ckptXid)
8319  ckptXidEpoch++;
8320 
8321  *xid = nextXid;
8322  *epoch = ckptXidEpoch;
8323 }
TransactionId ckptXid
Definition: xlog.c:593
uint32 TransactionId
Definition: c.h:507
slock_t info_lck
Definition: xlog.c:708
uint32 ckptXidEpoch
Definition: xlog.c:592
#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:711
static const unsigned __int64 epoch
Definition: gettimeofday.c:34

◆ GetRedoRecPtr()

XLogRecPtr GetRedoRecPtr ( void  )

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

8172 {
8173  XLogRecPtr ptr;
8174 
8175  /*
8176  * The possibly not up-to-date copy in XlogCtl is enough. Even if we
8177  * grabbed a WAL insertion lock to read the master copy, someone might
8178  * update it just after we've released the lock.
8179  */
8181  ptr = XLogCtl->RedoRecPtr;
8183 
8184  if (RedoRecPtr < ptr)
8185  RedoRecPtr = ptr;
8186 
8187  return RedoRecPtr;
8188 }
slock_t info_lck
Definition: xlog.c:708
#define SpinLockAcquire(lock)
Definition: spin.h:62
static XLogRecPtr RedoRecPtr
Definition: xlog.c:362
XLogRecPtr RedoRecPtr
Definition: xlog.c:591
#define SpinLockRelease(lock)
Definition: spin.h:64
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:711

◆ GetSystemIdentifier()

uint64 GetSystemIdentifier ( void  )

Definition at line 4812 of file xlog.c.

References Assert, and ControlFileData::system_identifier.

Referenced by IdentifySystem(), and WalReceiverMain().

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

◆ GetXLogInsertRecPtr()

XLogRecPtr GetXLogInsertRecPtr ( void  )

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

11191 {
11193  uint64 current_bytepos;
11194 
11195  SpinLockAcquire(&Insert->insertpos_lck);
11196  current_bytepos = Insert->CurrBytePos;
11197  SpinLockRelease(&Insert->insertpos_lck);
11198 
11199  return XLogBytePosToRecPtr(current_bytepos);
11200 }
slock_t insertpos_lck
Definition: xlog.c:529
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1959
XLogCtlInsert Insert
Definition: xlog.c:587
#define SpinLockAcquire(lock)
Definition: spin.h:62
uint64 CurrBytePos
Definition: xlog.c:538
static void Insert(File file)
Definition: fd.c:1035
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:711

◆ GetXLogReceiptTime()

void GetXLogReceiptTime ( TimestampTz rtime,
bool fromStream 
)

Definition at line 6105 of file xlog.c.

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

Referenced by GetStandbyLimitTime().

6106 {
6107  /*
6108  * This must be executed in the startup process, since we don't export the
6109  * relevant state to shared memory.
6110  */
6111  Assert(InRecovery);
6112 
6113  *rtime = XLogReceiptTime;
6114  *fromStream = (XLogReceiptSource == XLOG_FROM_STREAM);
6115 }
static XLogSource XLogReceiptSource
Definition: xlog.c:822
bool InRecovery
Definition: xlog.c:196
static TimestampTz XLogReceiptTime
Definition: xlog.c:821
#define Assert(condition)
Definition: c.h:732

◆ GetXLogReplayRecPtr()

XLogRecPtr GetXLogReplayRecPtr ( TimeLineID replayTLI)

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

11172 {
11173  XLogRecPtr recptr;
11174  TimeLineID tli;
11175 
11177  recptr = XLogCtl->lastReplayedEndRecPtr;
11178  tli = XLogCtl->lastReplayedTLI;
11180 
11181  if (replayTLI)
11182  *replayTLI = tli;
11183  return recptr;
11184 }
uint32 TimeLineID
Definition: xlogdefs.h:45
slock_t info_lck
Definition: xlog.c:708
#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:711
TimeLineID lastReplayedTLI
Definition: xlog.c:688
XLogRecPtr lastReplayedEndRecPtr
Definition: xlog.c:687

◆ GetXLogWriteRecPtr()

XLogRecPtr GetXLogWriteRecPtr ( void  )

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

11207 {
11211 
11212  return LogwrtResult.Write;
11213 }
static XLogwrtResult LogwrtResult
Definition: xlog.c:755
slock_t info_lck
Definition: xlog.c:708
#define SpinLockAcquire(lock)
Definition: spin.h:62
XLogwrtResult LogwrtResult
Definition: xlog.c:611
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:711
XLogRecPtr Write
Definition: xlog.c:435

◆ HotStandbyActive()

bool HotStandbyActive ( void  )

Definition at line 7954 of file xlog.c.

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

Referenced by XLogWalRcvSendHSFeedback().

7955 {
7956  /*
7957  * We check shared state each time only until Hot Standby is active. We
7958  * can't de-activate Hot Standby, so there's no need to keep checking
7959  * after the shared variable has once been seen true.
7960  */
7962  return true;
7963  else
7964  {
7965  /* spinlock is essential on machines with weak memory ordering! */
7969 
7970  return LocalHotStandbyActive;
7971  }
7972 }
bool SharedHotStandbyActive
Definition: xlog.c:653
slock_t info_lck
Definition: xlog.c:708
#define SpinLockAcquire(lock)
Definition: spin.h:62
static bool LocalHotStandbyActive
Definition: xlog.c:225
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:711

◆ HotStandbyActiveInReplay()

bool HotStandbyActiveInReplay ( void  )

Definition at line 7979 of file xlog.c.

References AmStartupProcess, Assert, IsPostmasterEnvironment, and LocalHotStandbyActive.

Referenced by btree_xlog_vacuum().

7980 {
7982  return LocalHotStandbyActive;
7983 }
#define AmStartupProcess()
Definition: miscadmin.h:412
bool IsPostmasterEnvironment
Definition: globals.c:108
static bool LocalHotStandbyActive
Definition: xlog.c:225
#define Assert(condition)
Definition: c.h:732

◆ InitXLOGAccess()

void InitXLOGAccess ( void  )

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

8146 {
8148 
8149  /* ThisTimeLineID doesn't change so we need no lock to copy it */
8152 
8153  /* set wal_segment_size */
8155 
8156  /* Use GetRedoRecPtr to copy the RedoRecPtr safely */
8157  (void) GetRedoRecPtr();
8158  /* Also update our copy of doPageWrites. */
8159  doPageWrites = (Insert->fullPageWrites || Insert->forcePageWrites);
8160 
8161  /* Also initialize the working areas for constructing WAL records */
8162  InitXLogInsert();
8163 }
int wal_segment_size
Definition: xlog.c:108
void InitXLogInsert(void)
Definition: xloginsert.c:1028
TimeLineID ThisTimeLineID
Definition: xlog.c:640
XLogCtlInsert Insert
Definition: xlog.c:587
bool fullPageWrites
Definition: xlog.c:562
uint32 xlog_seg_size
Definition: pg_control.h:209
static bool doPageWrites
Definition: xlog.c:369
bool forcePageWrites
Definition: xlog.c:561
static void Insert(File file)
Definition: fd.c:1035
static ControlFileData * ControlFile
Definition: xlog.c:719
TimeLineID ThisTimeLineID
Definition: xlog.c:183
#define Assert(condition)
Definition: c.h:732
static XLogCtlData * XLogCtl
Definition: xlog.c:711
XLogRecPtr GetRedoRecPtr(void)
Definition: xlog.c:8171
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:374

◆ issue_xlog_fsync()

void issue_xlog_fsync ( int  fd,
XLogSegNo  segno 
)

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

10127 {
10129  switch (sync_method)
10130  {
10131  case SYNC_METHOD_FSYNC:
10132  if (pg_fsync_no_writethrough(fd) != 0)
10133  ereport(PANIC,
10135  errmsg("could not fsync file \"%s\": %m",
10136  XLogFileNameP(ThisTimeLineID, segno))));
10137  break;
10138 #ifdef HAVE_FSYNC_WRITETHROUGH
10140  if (pg_fsync_writethrough(fd) != 0)
10141  ereport(PANIC,
10143  errmsg("could not fsync write-through file \"%s\": %m",
10144  XLogFileNameP(ThisTimeLineID, segno))));
10145  break;
10146 #endif
10147 #ifdef HAVE_FDATASYNC
10148  case SYNC_METHOD_FDATASYNC:
10149  if (pg_fdatasync(fd) != 0)
10150  ereport(PANIC,
10152  errmsg("could not fdatasync file \"%s\": %m",
10153  XLogFileNameP(ThisTimeLineID, segno))));
10154  break;
10155 #endif
10156  case SYNC_METHOD_OPEN:
10158  /* write synced it already */
10159  break;
10160  default:
10161  elog(PANIC, "unrecognized wal_sync_method: %d", sync_method);
10162  break;
10163  }
10165 }
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:10171
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:1272
#define ereport(elevel, rest)
Definition: elog.h:141
#define SYNC_METHOD_OPEN
Definition: xlog.h:27
TimeLineID ThisTimeLineID
Definition: xlog.c:183
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1248
int sync_method
Definition: xlog.c:98
#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 4932 of file xlog.c.

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

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

4933 {
4934  Assert(reset || ControlFile == NULL);
4935  ControlFile = palloc(sizeof(ControlFileData));
4936  ReadControlFile();
4937 }
void reset(void)
Definition: sql-declare.c:577
static void ReadControlFile(void)
Definition: xlog.c:4550
static ControlFileData * ControlFile
Definition: xlog.c:719
#define Assert(condition)
Definition: c.h:732
void * palloc(Size size)
Definition: mcxt.c:924

◆ RecoveryInProgress()

bool RecoveryInProgress ( void  )

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

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

◆ RecoveryIsPaused()

bool RecoveryIsPaused ( void  )

Definition at line 5928 of file xlog.c.

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

Referenced by pg_is_wal_replay_paused(), and recoveryPausesHere().

5929 {
5930  bool recoveryPause;
5931 
5933  recoveryPause = XLogCtl->recoveryPause;
5935 
5936  return recoveryPause;
5937 }
slock_t info_lck
Definition: xlog.c:708
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
bool recoveryPause
Definition: xlog.c:700
static XLogCtlData * XLogCtl
Definition: xlog.c:711

◆ RemovePromoteSignalFiles()

void RemovePromoteSignalFiles ( void  )

Definition at line 12239 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, and PROMOTE_SIGNAL_FILE.

Referenced by PostmasterMain().

12240 {
12241  unlink(PROMOTE_SIGNAL_FILE);
12243 }
#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 5940 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().

5941 {
5943  XLogCtl->recoveryPause = recoveryPause;
5945 }
slock_t info_lck
Definition: xlog.c:708
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
bool recoveryPause
Definition: xlog.c:700
static XLogCtlData * XLogCtl
Definition: xlog.c:711

◆ SetWalWriterSleeping()

void SetWalWriterSleeping ( bool  sleeping)

Definition at line 12275 of file xlog.c.

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

Referenced by WalWriterMain().

12276 {
12278  XLogCtl->WalWriterSleeping = sleeping;
12280 }
slock_t info_lck
Definition: xlog.c:708
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
bool WalWriterSleeping
Definition: xlog.c:660
static XLogCtlData * XLogCtl
Definition: xlog.c:711

◆ ShutdownXLOG()

void ShutdownXLOG ( int  code,
Datum  arg 
)

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

8330 {
8331  /*
8332  * We should have an aux process resource owner to use, and we should not
8333  * be in a transaction that's installed some other resowner.
8334  */
8336  Assert(CurrentResourceOwner == NULL ||
8339 
8340  /* Don't be chatty in standalone mode */
8342  (errmsg("shutting down")));
8343 
8344  /*
8345  * Signal walsenders to move to stopping state.
8346  */
8348 
8349  /*
8350  * Wait for WAL senders to be in stopping state. This prevents commands
8351  * from writing new WAL.
8352  */
8354 
8355  if (RecoveryInProgress())
8357  else
8358  {
8359  /*
8360  * If archiving is enabled, rotate the last XLOG file so that all the
8361  * remaining records are archived (postmaster wakes up the archiver
8362  * process one more time at the end of shutdown). The checkpoint
8363  * record will go to the next XLOG file and won't be archived (yet).
8364  */
8366  RequestXLogSwitch(false);
8367 
8369  }
8370  ShutdownCLOG();
8371  ShutdownCommitTs();
8372  ShutdownSUBTRANS();
8374 }
bool IsPostmasterEnvironment
Definition: globals.c:108
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9418
void ShutdownSUBTRANS(void)
Definition: subtrans.c:283
void CreateCheckPoint(int flags)
Definition: xlog.c:8545
ResourceOwner CurrentResourceOwner
Definition: resowner.c:141
void ShutdownCLOG(void)
Definition: clog.c:823
bool CreateRestartPoint(int flags)
Definition: xlog.c:9091
#define XLogArchiveCommandSet()
Definition: xlog.h:173
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:7898
ResourceOwner AuxProcessResourceOwner
Definition: resowner.c:144
void WalSndWaitStopping(void)
Definition: walsender.c:3122
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:3096
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 6190 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().

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