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_REQUESTED   0x0040 /* Checkpoint request has been made */
 
#define CHECKPOINT_CAUSE_XLOG   0x0080 /* XLOG consumption */
 
#define CHECKPOINT_CAUSE_TIME   0x0100 /* Elapsed time */
 
#define XLOG_INCLUDE_ORIGIN   0x01 /* include the replication origin */
 
#define XLOG_MARK_UNIMPORTANT   0x02 /* record not important for durability */
 
#define 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 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
 
bool wal_init_zero
 
bool wal_recycle
 
boolwal_consistency_checking
 
char * wal_consistency_checking_string
 
bool log_checkpoints
 
char * recoveryRestoreCommand
 
char * recoveryEndCommand
 
char * archiveCleanupCommand
 
bool recoveryTargetInclusive
 
int recoveryTargetAction
 
int recovery_min_apply_delay
 
char * PrimaryConnInfo
 
char * PrimarySlotName
 
TransactionId recoveryTargetXid
 
TimestampTz recoveryTargetTime
 
const char * recoveryTargetName
 
XLogRecPtr recoveryTargetLSN
 
RecoveryTargetType recoveryTarget
 
char * PromoteTriggerFile
 
RecoveryTargetTimeLineGoal recoveryTargetTimeLineGoal
 
TimeLineID recoveryTargetTLIRequested
 
TimeLineID recoveryTargetTLI
 
int CheckPointSegments
 
bool StandbyModeRequested
 
bool StandbyMode
 
int XLogArchiveMode
 
PGDLLIMPORT int wal_level
 
CheckpointStatsData CheckpointStats
 

Macro Definition Documentation

◆ BACKUP_LABEL_FILE

#define BACKUP_LABEL_FILE   "backup_label"

◆ BACKUP_LABEL_OLD

#define BACKUP_LABEL_OLD   "backup_label.old"

Definition at line 360 of file xlog.h.

Referenced by CancelBackup(), and StartupXLOG().

◆ CHECKPOINT_CAUSE_TIME

#define CHECKPOINT_CAUSE_TIME   0x0100 /* Elapsed time */

Definition at line 223 of file xlog.h.

Referenced by CheckpointerMain(), and LogCheckpointStart().

◆ CHECKPOINT_CAUSE_XLOG

#define CHECKPOINT_CAUSE_XLOG   0x0080 /* XLOG consumption */

Definition at line 222 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 212 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 216 of file xlog.h.

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

◆ CHECKPOINT_FORCE

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

◆ CHECKPOINT_IMMEDIATE

◆ CHECKPOINT_IS_SHUTDOWN

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

◆ CHECKPOINT_REQUESTED

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

Definition at line 220 of file xlog.h.

Referenced by RequestCheckpoint().

◆ CHECKPOINT_WAIT

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

◆ FALLBACK_PROMOTE_SIGNAL_FILE

#define FALLBACK_PROMOTE_SIGNAL_FILE   "fallback_promote"

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

Referenced by exitArchiveRecovery(), and readRecoverySignalFile().

◆ STANDBY_SIGNAL_FILE

#define STANDBY_SIGNAL_FILE   "standby.signal"

Definition at line 358 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 363 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 175 of file xlog.h.

Referenced by pgarch_ArchiverCopyLoop(), and ShutdownXLOG().

◆ XLogArchivingActive

◆ XLogArchivingAlways

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

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

◆ 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 340 of file xlog.h.

◆ WalLevel

enum WalLevel
Enumerator
WAL_LEVEL_MINIMAL 
WAL_LEVEL_REPLICA 
WAL_LEVEL_LOGICAL 

Definition at line 160 of file xlog.h.

Function Documentation

◆ assign_checkpoint_completion_target()

void assign_checkpoint_completion_target ( double  newval,
void *  extra 
)

Definition at line 2290 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

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

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2283 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

2284 {
2287 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2254
int max_wal_size_mb
Definition: xlog.c:86
#define newval

◆ BootStrapXLOG()

void BootStrapXLOG ( void  )

Definition at line 5086 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, FirstNormalUnloggedLSN, CheckPoint::fullPageWrites, fullPageWrites, FullTransactionIdFromEpochAndXid(), 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::nextFullXid, VariableCacheData::nextFullXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, VariableCacheData::nextOid, 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().

5087 {
5088  CheckPoint checkPoint;
5089  char *buffer;
5090  XLogPageHeader page;
5091  XLogLongPageHeader longpage;
5092  XLogRecord *record;
5093  char *recptr;
5094  bool use_existent;
5095  uint64 sysidentifier;
5096  char mock_auth_nonce[MOCK_AUTH_NONCE_LEN];
5097  struct timeval tv;
5098  pg_crc32c crc;
5099 
5100  /*
5101  * Select a hopefully-unique system identifier code for this installation.
5102  * We use the result of gettimeofday(), including the fractional seconds
5103  * field, as being about as unique as we can easily get. (Think not to
5104  * use random(), since it hasn't been seeded and there's no portable way
5105  * to seed it other than the system clock value...) The upper half of the
5106  * uint64 value is just the tv_sec part, while the lower half contains the
5107  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
5108  * PID for a little extra uniqueness. A person knowing this encoding can
5109  * determine the initialization time of the installation, which could
5110  * perhaps be useful sometimes.
5111  */
5112  gettimeofday(&tv, NULL);
5113  sysidentifier = ((uint64) tv.tv_sec) << 32;
5114  sysidentifier |= ((uint64) tv.tv_usec) << 12;
5115  sysidentifier |= getpid() & 0xFFF;
5116 
5117  /*
5118  * Generate a random nonce. This is used for authentication requests that
5119  * will fail because the user does not exist. The nonce is used to create
5120  * a genuine-looking password challenge for the non-existent user, in lieu
5121  * of an actual stored password.
5122  */
5123  if (!pg_strong_random(mock_auth_nonce, MOCK_AUTH_NONCE_LEN))
5124  ereport(PANIC,
5125  (errcode(ERRCODE_INTERNAL_ERROR),
5126  errmsg("could not generate secret authorization token")));
5127 
5128  /* First timeline ID is always 1 */
5129  ThisTimeLineID = 1;
5130 
5131  /* page buffer must be aligned suitably for O_DIRECT */
5132  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
5133  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
5134  memset(page, 0, XLOG_BLCKSZ);
5135 
5136  /*
5137  * Set up information for the initial checkpoint record
5138  *
5139  * The initial checkpoint record is written to the beginning of the WAL
5140  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5141  * used, so that we can use 0/0 to mean "before any valid WAL segment".
5142  */
5143  checkPoint.redo = wal_segment_size + SizeOfXLogLongPHD;
5144  checkPoint.ThisTimeLineID = ThisTimeLineID;
5145  checkPoint.PrevTimeLineID = ThisTimeLineID;
5146  checkPoint.fullPageWrites = fullPageWrites;
5147  checkPoint.nextFullXid =
5149  checkPoint.nextOid = FirstBootstrapObjectId;
5150  checkPoint.nextMulti = FirstMultiXactId;
5151  checkPoint.nextMultiOffset = 0;
5152  checkPoint.oldestXid = FirstNormalTransactionId;
5153  checkPoint.oldestXidDB = TemplateDbOid;
5154  checkPoint.oldestMulti = FirstMultiXactId;
5155  checkPoint.oldestMultiDB = TemplateDbOid;
5158  checkPoint.time = (pg_time_t) time(NULL);
5160 
5162  ShmemVariableCache->nextOid = checkPoint.nextOid;
5164  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5165  AdvanceOldestClogXid(checkPoint.oldestXid);
5166  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5167  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5169 
5170  /* Set up the XLOG page header */
5171  page->xlp_magic = XLOG_PAGE_MAGIC;
5172  page->xlp_info = XLP_LONG_HEADER;
5173  page->xlp_tli = ThisTimeLineID;
5175  longpage = (XLogLongPageHeader) page;
5176  longpage->xlp_sysid = sysidentifier;
5177  longpage->xlp_seg_size = wal_segment_size;
5178  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5179 
5180  /* Insert the initial checkpoint record */
5181  recptr = ((char *) page + SizeOfXLogLongPHD);
5182  record = (XLogRecord *) recptr;
5183  record->xl_prev = 0;
5184  record->xl_xid = InvalidTransactionId;
5185  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5187  record->xl_rmid = RM_XLOG_ID;
5188  recptr += SizeOfXLogRecord;
5189  /* fill the XLogRecordDataHeaderShort struct */
5190  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5191  *(recptr++) = sizeof(checkPoint);
5192  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5193  recptr += sizeof(checkPoint);
5194  Assert(recptr - (char *) record == record->xl_tot_len);
5195 
5196  INIT_CRC32C(crc);
5197  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5198  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5199  FIN_CRC32C(crc);
5200  record->xl_crc = crc;
5201 
5202  /* Create first XLOG segment file */
5203  use_existent = false;
5204  openLogFile = XLogFileInit(1, &use_existent, false);
5205 
5206  /* Write the first page with the initial record */
5207  errno = 0;
5209  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5210  {
5211  /* if write didn't set errno, assume problem is no disk space */
5212  if (errno == 0)
5213  errno = ENOSPC;
5214  ereport(PANIC,
5216  errmsg("could not write bootstrap write-ahead log file: %m")));
5217  }
5219 
5221  if (pg_fsync(openLogFile) != 0)
5222  ereport(PANIC,
5224  errmsg("could not fsync bootstrap write-ahead log file: %m")));
5226 
5227  if (close(openLogFile))
5228  ereport(PANIC,
5230  errmsg("could not close bootstrap write-ahead log file: %m")));
5231 
5232  openLogFile = -1;
5233 
5234  /* Now create pg_control */
5235 
5236  memset(ControlFile, 0, sizeof(ControlFileData));
5237  /* Initialize pg_control status fields */
5238  ControlFile->system_identifier = sysidentifier;
5239  memcpy(ControlFile->mock_authentication_nonce, mock_auth_nonce, MOCK_AUTH_NONCE_LEN);
5241  ControlFile->time = checkPoint.time;
5242  ControlFile->checkPoint = checkPoint.redo;
5243  ControlFile->checkPointCopy = checkPoint;
5245 
5246  /* Set important parameter values for use when replaying WAL */
5256 
5257  /* some additional ControlFile fields are set in WriteControlFile() */
5258 
5259  WriteControlFile();
5260 
5261  /* Bootstrap the commit log, too */
5262  BootStrapCLOG();
5266 
5267  pfree(buffer);
5268 
5269  /*
5270  * Force control file to be read - in contrast to normal processing we'd
5271  * otherwise never run the checks and GUC related initializations therein.
5272  */
5273  ReadControlFile();
5274 }
static void WriteControlFile(void)
Definition: xlog.c:4484
#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:112
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:159
#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:103
int XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
Definition: xlog.c:3204
void BootStrapMultiXact(void)
Definition: multixact.c:1866
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
int errcode(int sqlerrcode)
Definition: elog.c:570
RmgrId xl_rmid
Definition: xlogrecord.h:47
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:57
FullTransactionId nextFullXid
Definition: transam.h:164
CheckPoint checkPointCopy
Definition: pg_control.h:131
TransactionId oldestXid
Definition: pg_control.h:47
pg_time_t time
Definition: pg_control.h:51
#define PANIC
Definition: elog.h:53
uint32 bootstrap_data_checksum_version
Definition: bootstrap.c:53
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:74
#define MOCK_AUTH_NONCE_LEN
Definition: pg_control.h:28
bool fullPageWrites
Definition: xlog.c:94
void BootStrapSUBTRANS(void)
Definition: subtrans.c:212
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid)
Definition: varsup.c:313
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:118
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
static void ReadControlFile(void)
Definition: xlog.c:4576
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:140
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1343
#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
#define FirstNormalUnloggedLSN
Definition: xlogdefs.h:36
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:720
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
Definition: multixact.c:2194
TimeLineID ThisTimeLineID
Definition: xlog.c:187
Oid nextOid
Definition: pg_control.h:44
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:678
bool fullPageWrites
Definition: pg_control.h:42
bool wal_log_hints
Definition: xlog.c:95
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
FullTransactionId nextFullXid
Definition: pg_control.h:43
Oid oldestXidDB
Definition: pg_control.h:48
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1319
void SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid)
Definition: varsup.c:330
uint8 xl_info
Definition: xlogrecord.h:46
MultiXactId nextMulti
Definition: pg_control.h:45
static FullTransactionId FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
Definition: transam.h:65
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:223
TransactionId xl_xid
Definition: xlogrecord.h:44
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
void * palloc(Size size)
Definition: mcxt.c: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:37
#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 12193 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, PROMOTE_SIGNAL_FILE, and stat.

Referenced by sigusr1_handler().

12194 {
12195  struct stat stat_buf;
12196 
12197  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
12199  return true;
12200 
12201  return false;
12202 }
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:366
struct stat stat_buf
Definition: pg_standby.c:102
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.h:367
#define stat(a, b)
Definition: win32_port.h:264

◆ CheckXLogRemoved()

void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)

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

3846 {
3847  int save_errno = errno;
3848  XLogSegNo lastRemovedSegNo;
3849 
3851  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3853 
3854  if (segno <= lastRemovedSegNo)
3855  {
3856  char filename[MAXFNAMELEN];
3857 
3858  XLogFileName(filename, tli, segno, wal_segment_size);
3859  errno = save_errno;
3860  ereport(ERROR,
3862  errmsg("requested WAL segment %s has already been removed",
3863  filename)));
3864  }
3865  errno = save_errno;
3866 }
int wal_segment_size
Definition: xlog.c:112
slock_t info_lck
Definition: xlog.c:709
XLogSegNo lastRemovedSegNo
Definition: xlog.c:598
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define ERROR
Definition: elog.h:43
uint64 XLogSegNo
Definition: xlogdefs.h:41
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static XLogCtlData * XLogCtl
Definition: xlog.c:712
static char * filename
Definition: pg_dumpall.c:91
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ CreateCheckPoint()

void CreateCheckPoint ( int  flags)

Definition at line 8494 of file xlog.c.

References ControlFileData::checkPoint, CHECKPOINT_END_OF_RECOVERY, CHECKPOINT_FORCE, CHECKPOINT_IS_SHUTDOWN, ControlFileData::checkPointCopy, CheckPointGuts(), CheckpointStatsData::ckpt_bufs_written, CheckpointStatsData::ckpt_segs_added, CheckpointStatsData::ckpt_segs_recycled, CheckpointStatsData::ckpt_segs_removed, CheckpointStatsData::ckpt_start_t, XLogCtlData::ckptFullXid, XLogCtlInsert::CurrBytePos, DB_SHUTDOWNED, DB_SHUTDOWNING, DEBUG1, elog, END_CRIT_SECTION, ereport, errmsg(), ERROR, CheckPoint::fullPageWrites, XLogCtlInsert::fullPageWrites, GetCurrentTimestamp(), GetLastImportantRecPtr(), GetOldestActiveTransactionId(), 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::nextFullXid, VariableCacheData::nextFullXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, VariableCacheData::nextOid, 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, SpinLockAcquire, SpinLockRelease, START_CRIT_SECTION, ControlFileData::state, SyncPostCheckpoint(), SyncPreCheckpoint(), 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().

8495 {
8496  bool shutdown;
8497  CheckPoint checkPoint;
8498  XLogRecPtr recptr;
8499  XLogSegNo _logSegNo;
8501  uint32 freespace;
8502  XLogRecPtr PriorRedoPtr;
8503  XLogRecPtr curInsert;
8504  XLogRecPtr last_important_lsn;
8505  VirtualTransactionId *vxids;
8506  int nvxids;
8507 
8508  /*
8509  * An end-of-recovery checkpoint is really a shutdown checkpoint, just
8510  * issued at a different time.
8511  */
8513  shutdown = true;
8514  else
8515  shutdown = false;
8516 
8517  /* sanity check */
8518  if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
8519  elog(ERROR, "can't create a checkpoint during recovery");
8520 
8521  /*
8522  * Initialize InitXLogInsert working areas before entering the critical
8523  * section. Normally, this is done by the first call to
8524  * RecoveryInProgress() or LocalSetXLogInsertAllowed(), but when creating
8525  * an end-of-recovery checkpoint, the LocalSetXLogInsertAllowed call is
8526  * done below in a critical section, and InitXLogInsert cannot be called
8527  * in a critical section.
8528  */
8529  InitXLogInsert();
8530 
8531  /*
8532  * Acquire CheckpointLock to ensure only one checkpoint happens at a time.
8533  * (This is just pro forma, since in the present system structure there is
8534  * only one process that is allowed to issue checkpoints at any given
8535  * time.)
8536  */
8537  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
8538 
8539  /*
8540  * Prepare to accumulate statistics.
8541  *
8542  * Note: because it is possible for log_checkpoints to change while a
8543  * checkpoint proceeds, we always accumulate stats, even if
8544  * log_checkpoints is currently off.
8545  */
8546  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
8548 
8549  /*
8550  * Use a critical section to force system panic if we have trouble.
8551  */
8553 
8554  if (shutdown)
8555  {
8556  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8558  ControlFile->time = (pg_time_t) time(NULL);
8560  LWLockRelease(ControlFileLock);
8561  }
8562 
8563  /*
8564  * Let smgr prepare for checkpoint; this has to happen before we determine
8565  * the REDO pointer. Note that smgr must not do anything that'd have to
8566  * be undone if we decide no checkpoint is needed.
8567  */
8569 
8570  /* Begin filling in the checkpoint WAL record */
8571  MemSet(&checkPoint, 0, sizeof(checkPoint));
8572  checkPoint.time = (pg_time_t) time(NULL);
8573 
8574  /*
8575  * For Hot Standby, derive the oldestActiveXid before we fix the redo
8576  * pointer. This allows us to begin accumulating changes to assemble our
8577  * starting snapshot of locks and transactions.
8578  */
8579  if (!shutdown && XLogStandbyInfoActive())
8581  else
8583 
8584  /*
8585  * Get location of last important record before acquiring insert locks (as
8586  * GetLastImportantRecPtr() also locks WAL locks).
8587  */
8588  last_important_lsn = GetLastImportantRecPtr();
8589 
8590  /*
8591  * We must block concurrent insertions while examining insert state to
8592  * determine the checkpoint REDO pointer.
8593  */
8595  curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
8596 
8597  /*
8598  * If this isn't a shutdown or forced checkpoint, and if there has been no
8599  * WAL activity requiring a checkpoint, skip it. The idea here is to
8600  * avoid inserting duplicate checkpoints when the system is idle.
8601  */
8602  if ((flags & (CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_END_OF_RECOVERY |
8603  CHECKPOINT_FORCE)) == 0)
8604  {
8605  if (last_important_lsn == ControlFile->checkPoint)
8606  {
8608  LWLockRelease(CheckpointLock);
8609  END_CRIT_SECTION();
8610  ereport(DEBUG1,
8611  (errmsg("checkpoint skipped because system is idle")));
8612  return;
8613  }
8614  }
8615 
8616  /*
8617  * An end-of-recovery checkpoint is created before anyone is allowed to
8618  * write WAL. To allow us to write the checkpoint record, temporarily
8619  * enable XLogInsertAllowed. (This also ensures ThisTimeLineID is
8620  * initialized, which we need here and in AdvanceXLInsertBuffer.)
8621  */
8622  if (flags & CHECKPOINT_END_OF_RECOVERY)
8624 
8625  checkPoint.ThisTimeLineID = ThisTimeLineID;
8626  if (flags & CHECKPOINT_END_OF_RECOVERY)
8627  checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
8628  else
8629  checkPoint.PrevTimeLineID = ThisTimeLineID;
8630 
8631  checkPoint.fullPageWrites = Insert->fullPageWrites;
8632 
8633  /*
8634  * Compute new REDO record ptr = location of next XLOG record.
8635  *
8636  * NB: this is NOT necessarily where the checkpoint record itself will be,
8637  * since other backends may insert more XLOG records while we're off doing
8638  * the buffer flush work. Those XLOG records are logically after the
8639  * checkpoint, even though physically before it. Got that?
8640  */
8641  freespace = INSERT_FREESPACE(curInsert);
8642  if (freespace == 0)
8643  {
8644  if (XLogSegmentOffset(curInsert, wal_segment_size) == 0)
8645  curInsert += SizeOfXLogLongPHD;
8646  else
8647  curInsert += SizeOfXLogShortPHD;
8648  }
8649  checkPoint.redo = curInsert;
8650 
8651  /*
8652  * Here we update the shared RedoRecPtr for future XLogInsert calls; this
8653  * must be done while holding all the insertion locks.
8654  *
8655  * Note: if we fail to complete the checkpoint, RedoRecPtr will be left
8656  * pointing past where it really needs to point. This is okay; the only
8657  * consequence is that XLogInsert might back up whole buffers that it
8658  * didn't really need to. We can't postpone advancing RedoRecPtr because
8659  * XLogInserts that happen while we are dumping buffers must assume that
8660  * their buffer changes are not included in the checkpoint.
8661  */
8662  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
8663 
8664  /*
8665  * Now we can release the WAL insertion locks, allowing other xacts to
8666  * proceed while we are flushing disk buffers.
8667  */
8669 
8670  /* Update the info_lck-protected copy of RedoRecPtr as well */
8672  XLogCtl->RedoRecPtr = checkPoint.redo;
8674 
8675  /*
8676  * If enabled, log checkpoint start. We postpone this until now so as not
8677  * to log anything if we decided to skip the checkpoint.
8678  */
8679  if (log_checkpoints)
8680  LogCheckpointStart(flags, false);
8681 
8682  TRACE_POSTGRESQL_CHECKPOINT_START(flags);
8683 
8684  /*
8685  * Get the other info we need for the checkpoint record.
8686  *
8687  * We don't need to save oldestClogXid in the checkpoint, it only matters
8688  * for the short period in which clog is being truncated, and if we crash
8689  * during that we'll redo the clog truncation and fix up oldestClogXid
8690  * there.
8691  */
8692  LWLockAcquire(XidGenLock, LW_SHARED);
8694  checkPoint.oldestXid = ShmemVariableCache->oldestXid;
8696  LWLockRelease(XidGenLock);
8697 
8698  LWLockAcquire(CommitTsLock, LW_SHARED);
8701  LWLockRelease(CommitTsLock);
8702 
8703  LWLockAcquire(OidGenLock, LW_SHARED);
8704  checkPoint.nextOid = ShmemVariableCache->nextOid;
8705  if (!shutdown)
8706  checkPoint.nextOid += ShmemVariableCache->oidCount;
8707  LWLockRelease(OidGenLock);
8708 
8709  MultiXactGetCheckptMulti(shutdown,
8710  &checkPoint.nextMulti,
8711  &checkPoint.nextMultiOffset,
8712  &checkPoint.oldestMulti,
8713  &checkPoint.oldestMultiDB);
8714 
8715  /*
8716  * Having constructed the checkpoint record, ensure all shmem disk buffers
8717  * and commit-log buffers are flushed to disk.
8718  *
8719  * This I/O could fail for various reasons. If so, we will fail to
8720  * complete the checkpoint, but there is no reason to force a system
8721  * panic. Accordingly, exit critical section while doing it.
8722  */
8723  END_CRIT_SECTION();
8724 
8725  /*
8726  * In some cases there are groups of actions that must all occur on one
8727  * side or the other of a checkpoint record. Before flushing the
8728  * checkpoint record we must explicitly wait for any backend currently
8729  * performing those groups of actions.
8730  *
8731  * One example is end of transaction, so we must wait for any transactions
8732  * that are currently in commit critical sections. If an xact inserted
8733  * its commit record into XLOG just before the REDO point, then a crash
8734  * restart from the REDO point would not replay that record, which means
8735  * that our flushing had better include the xact's update of pg_xact. So
8736  * we wait till he's out of his commit critical section before proceeding.
8737  * See notes in RecordTransactionCommit().
8738  *
8739  * Because we've already released the insertion locks, this test is a bit
8740  * fuzzy: it is possible that we will wait for xacts we didn't really need
8741  * to wait for. But the delay should be short and it seems better to make
8742  * checkpoint take a bit longer than to hold off insertions longer than
8743  * necessary. (In fact, the whole reason we have this issue is that xact.c
8744  * does commit record XLOG insertion and clog update as two separate steps
8745  * protected by different locks, but again that seems best on grounds of
8746  * minimizing lock contention.)
8747  *
8748  * A transaction that has not yet set delayChkpt when we look cannot be at
8749  * risk, since he's not inserted his commit record yet; and one that's
8750  * already cleared it is not at risk either, since he's done fixing clog
8751  * and we will correctly flush the update below. So we cannot miss any
8752  * xacts we need to wait for.
8753  */
8754  vxids = GetVirtualXIDsDelayingChkpt(&nvxids);
8755  if (nvxids > 0)
8756  {
8757  do
8758  {
8759  pg_usleep(10000L); /* wait for 10 msec */
8760  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids));
8761  }
8762  pfree(vxids);
8763 
8764  CheckPointGuts(checkPoint.redo, flags);
8765 
8766  /*
8767  * Take a snapshot of running transactions and write this to WAL. This
8768  * allows us to reconstruct the state of running transactions during
8769  * archive recovery, if required. Skip, if this info disabled.
8770  *
8771  * If we are shutting down, or Startup process is completing crash
8772  * recovery we don't need to write running xact data.
8773  */
8774  if (!shutdown && XLogStandbyInfoActive())
8776 
8778 
8779  /*
8780  * Now insert the checkpoint record into XLOG.
8781  */
8782  XLogBeginInsert();
8783  XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));
8784  recptr = XLogInsert(RM_XLOG_ID,
8785  shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
8787 
8788  XLogFlush(recptr);
8789 
8790  /*
8791  * We mustn't write any new WAL after a shutdown checkpoint, or it will be
8792  * overwritten at next startup. No-one should even try, this just allows
8793  * sanity-checking. In the case of an end-of-recovery checkpoint, we want
8794  * to just temporarily disable writing until the system has exited
8795  * recovery.
8796  */
8797  if (shutdown)
8798  {
8799  if (flags & CHECKPOINT_END_OF_RECOVERY)
8800  LocalXLogInsertAllowed = -1; /* return to "check" state */
8801  else
8802  LocalXLogInsertAllowed = 0; /* never again write WAL */
8803  }
8804 
8805  /*
8806  * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
8807  * = end of actual checkpoint record.
8808  */
8809  if (shutdown && checkPoint.redo != ProcLastRecPtr)
8810  ereport(PANIC,
8811  (errmsg("concurrent write-ahead log activity while database system is shutting down")));
8812 
8813  /*
8814  * Remember the prior checkpoint's redo ptr for
8815  * UpdateCheckPointDistanceEstimate()
8816  */
8817  PriorRedoPtr = ControlFile->checkPointCopy.redo;
8818 
8819  /*
8820  * Update the control file.
8821  */
8822  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8823  if (shutdown)
8826  ControlFile->checkPointCopy = checkPoint;
8827  ControlFile->time = (pg_time_t) time(NULL);
8828  /* crash recovery should always recover to the end of WAL */
8831 
8832  /*
8833  * Persist unloggedLSN value. It's reset on crash recovery, so this goes
8834  * unused on non-shutdown checkpoints, but seems useful to store it always
8835  * for debugging purposes.
8836  */
8840 
8842  LWLockRelease(ControlFileLock);
8843 
8844  /* Update shared-memory copy of checkpoint XID/epoch */
8846  XLogCtl->ckptFullXid = checkPoint.nextFullXid;
8848 
8849  /*
8850  * We are now done with critical updates; no need for system panic if we
8851  * have trouble while fooling with old log segments.
8852  */
8853  END_CRIT_SECTION();
8854 
8855  /*
8856  * Let smgr do post-checkpoint cleanup (eg, deleting old files).
8857  */
8859 
8860  /*
8861  * Update the average distance between checkpoints if the prior checkpoint
8862  * exists.
8863  */
8864  if (PriorRedoPtr != InvalidXLogRecPtr)
8866 
8867  /*
8868  * Delete old log files, those no longer needed for last checkpoint to
8869  * prevent the disk holding the xlog from growing full.
8870  */
8872  KeepLogSeg(recptr, &_logSegNo);
8873  _logSegNo--;
8874  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr);
8875 
8876  /*
8877  * Make more log segments if needed. (Do this after recycling old log
8878  * segments, since that may supply some of the needed files.)
8879  */
8880  if (!shutdown)
8881  PreallocXlogFiles(recptr);
8882 
8883  /*
8884  * Truncate pg_subtrans if possible. We can throw away all data before
8885  * the oldest XMIN of any running transaction. No future transaction will
8886  * attempt to reference any pg_subtrans entry older than that (see Asserts
8887  * in subtrans.c). During recovery, though, we mustn't do this because
8888  * StartupSUBTRANS hasn't been called yet.
8889  */
8890  if (!RecoveryInProgress())
8892 
8893  /* Real work is done, but log and update stats before releasing lock. */
8894  LogCheckpointEnd(false);
8895 
8896  TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
8897  NBuffers,
8901 
8902  LWLockRelease(CheckpointLock);
8903 }
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:8232
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8432
static int LocalXLogInsertAllowed
Definition: xlog.c:241
bool log_checkpoints
Definition: xlog.c:101
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define DEBUG1
Definition: elog.h:25
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1689
int wal_segment_size
Definition: xlog.c:112
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:159
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1591
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1958
XLogRecPtr unloggedLSN
Definition: xlog.c:601
XLogRecPtr ProcLastRecPtr
Definition: xlog.c:350
TransactionId oldestActiveXid
Definition: pg_control.h:63
void InitXLogInsert(void)
Definition: xloginsert.c:1110
TimestampTz ckpt_start_t
Definition: xlog.h:235
slock_t info_lck
Definition: xlog.c:709
#define END_CRIT_SECTION()
Definition: miscadmin.h:134
VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids)
Definition: procarray.c:2273
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: xlog.c:642
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
#define START_CRIT_SECTION()
Definition: miscadmin.h:132
int ckpt_segs_recycled
Definition: xlog.h:245
TransactionId oldestXid
Definition: transam.h:166
#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:8964
FullTransactionId nextFullXid
Definition: transam.h:164
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:589
TransactionId oldestXid
Definition: pg_control.h:47
bool RecoveryInProgress(void)
Definition: xlog.c:7882
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:356
pg_time_t time
Definition: pg_control.h:51
#define PANIC
Definition: elog.h:53
bool fullPageWrites
Definition: xlog.c:564
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2797
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1726
#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:4792
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:8347
static XLogRecPtr RedoRecPtr
Definition: xlog.c:364
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
XLogRecPtr unloggedLSN
Definition: pg_control.h:133
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3812
uint64 XLogSegNo
Definition: xlogdefs.h:41
#define CHECKPOINT_END_OF_RECOVERY
Definition: xlog.h:212
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define InvalidTransactionId
Definition: transam.h:31
uint64 CurrBytePos
Definition: xlog.c:540
unsigned int uint32
Definition: c.h:358
XLogRecPtr RedoRecPtr
Definition: xlog.c:593
int ckpt_segs_removed
Definition: xlog.h:244
#define CHECKPOINT_FORCE
Definition: xlog.h:215
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:726
#define ereport(elevel, rest)
Definition: elog.h:141
TransactionId oldestCommitTsXid
Definition: transam.h:176
static void Insert(File file)
Definition: fd.c:1061
int ckpt_bufs_written
Definition: xlog.h:241
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8008
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:9284
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
Oid oldestMultiDB
Definition: pg_control.h:50
FullTransactionId ckptFullXid
Definition: xlog.c:594
#define XLogStandbyInfoActive()
Definition: xlog.h:195
static ControlFileData * ControlFile
Definition: xlog.c:720
TimeLineID ThisTimeLineID
Definition: xlog.c:187
Oid nextOid
Definition: pg_control.h:44
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr RedoRecPtr, XLogRecPtr endptr)
Definition: xlog.c:3942
bool fullPageWrites
Definition: pg_control.h:42
TransactionId GetOldestXmin(Relation rel, int flags)
Definition: procarray.c:1307
uint64 XLogRecPtr
Definition: xlogdefs.h:21
FullTransactionId nextFullXid
Definition: pg_control.h:43
Oid oldestXidDB
Definition: pg_control.h:48
TransactionId newestCommitTsXid
Definition: transam.h:177
CheckpointStatsData CheckpointStats
Definition: xlog.c:181
#define SizeOfXLogShortPHD
Definition: xlog_internal.h:55
MultiXactId nextMulti
Definition: pg_control.h:45
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1660
static XLogCtlData * XLogCtl
Definition: xlog.c:712
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1122
int ckpt_segs_added
Definition: xlog.h:243
slock_t ulsn_lck
Definition: xlog.c:602
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
void SyncPostCheckpoint(void)
Definition: sync.c:174
TransactionId GetOldestActiveTransactionId(void)
Definition: procarray.c:2111
int NBuffers
Definition: globals.c:131
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids)
Definition: procarray.c:2318
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr RedoRecPtr
Definition: xlog.c:562
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:37
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8329
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:211
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
void SyncPreCheckpoint(void)
Definition: sync.c:159
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ CreateRestartPoint()

bool CreateRestartPoint ( int  flags)

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

9035 {
9036  XLogRecPtr lastCheckPointRecPtr;
9037  XLogRecPtr lastCheckPointEndPtr;
9038  CheckPoint lastCheckPoint;
9039  XLogRecPtr PriorRedoPtr;
9040  XLogRecPtr receivePtr;
9041  XLogRecPtr replayPtr;
9042  TimeLineID replayTLI;
9043  XLogRecPtr endptr;
9044  XLogSegNo _logSegNo;
9045  TimestampTz xtime;
9046 
9047  /*
9048  * Acquire CheckpointLock to ensure only one restartpoint or checkpoint
9049  * happens at a time.
9050  */
9051  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
9052 
9053  /* Get a local copy of the last safe checkpoint record. */
9055  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
9056  lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
9057  lastCheckPoint = XLogCtl->lastCheckPoint;
9059 
9060  /*
9061  * Check that we're still in recovery mode. It's ok if we exit recovery
9062  * mode after this check, the restart point is valid anyway.
9063  */
9064  if (!RecoveryInProgress())
9065  {
9066  ereport(DEBUG2,
9067  (errmsg("skipping restartpoint, recovery has already ended")));
9068  LWLockRelease(CheckpointLock);
9069  return false;
9070  }
9071 
9072  /*
9073  * If the last checkpoint record we've replayed is already our last
9074  * restartpoint, we can't perform a new restart point. We still update
9075  * minRecoveryPoint in that case, so that if this is a shutdown restart
9076  * point, we won't start up earlier than before. That's not strictly
9077  * necessary, but when hot standby is enabled, it would be rather weird if
9078  * the database opened up for read-only connections at a point-in-time
9079  * before the last shutdown. Such time travel is still possible in case of
9080  * immediate shutdown, though.
9081  *
9082  * We don't explicitly advance minRecoveryPoint when we do create a
9083  * restartpoint. It's assumed that flushing the buffers will do that as a
9084  * side-effect.
9085  */
9086  if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
9087  lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
9088  {
9089  ereport(DEBUG2,
9090  (errmsg("skipping restartpoint, already performed at %X/%X",
9091  (uint32) (lastCheckPoint.redo >> 32),
9092  (uint32) lastCheckPoint.redo)));
9093 
9095  if (flags & CHECKPOINT_IS_SHUTDOWN)
9096  {
9097  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9099  ControlFile->time = (pg_time_t) time(NULL);
9101  LWLockRelease(ControlFileLock);
9102  }
9103  LWLockRelease(CheckpointLock);
9104  return false;
9105  }
9106 
9107  /*
9108  * Update the shared RedoRecPtr so that the startup process can calculate
9109  * the number of segments replayed since last restartpoint, and request a
9110  * restartpoint if it exceeds CheckPointSegments.
9111  *
9112  * Like in CreateCheckPoint(), hold off insertions to update it, although
9113  * during recovery this is just pro forma, because no WAL insertions are
9114  * happening.
9115  */
9117  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
9119 
9120  /* Also update the info_lck-protected copy */
9122  XLogCtl->RedoRecPtr = lastCheckPoint.redo;
9124 
9125  /*
9126  * Prepare to accumulate statistics.
9127  *
9128  * Note: because it is possible for log_checkpoints to change while a
9129  * checkpoint proceeds, we always accumulate stats, even if
9130  * log_checkpoints is currently off.
9131  */
9132  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
9134 
9135  if (log_checkpoints)
9136  LogCheckpointStart(flags, true);
9137 
9138  CheckPointGuts(lastCheckPoint.redo, flags);
9139 
9140  /*
9141  * Remember the prior checkpoint's redo ptr for
9142  * UpdateCheckPointDistanceEstimate()
9143  */
9144  PriorRedoPtr = ControlFile->checkPointCopy.redo;
9145 
9146  /*
9147  * Update pg_control, using current time. Check that it still shows
9148  * IN_ARCHIVE_RECOVERY state and an older checkpoint, else do nothing;
9149  * this is a quick hack to make sure nothing really bad happens if somehow
9150  * we get here after the end-of-recovery checkpoint.
9151  */
9152  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9154  ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
9155  {
9156  ControlFile->checkPoint = lastCheckPointRecPtr;
9157  ControlFile->checkPointCopy = lastCheckPoint;
9158  ControlFile->time = (pg_time_t) time(NULL);
9159 
9160  /*
9161  * Ensure minRecoveryPoint is past the checkpoint record. Normally,
9162  * this will have happened already while writing out dirty buffers,
9163  * but not necessarily - e.g. because no buffers were dirtied. We do
9164  * this because a non-exclusive base backup uses minRecoveryPoint to
9165  * determine which WAL files must be included in the backup, and the
9166  * file (or files) containing the checkpoint record must be included,
9167  * at a minimum. Note that for an ordinary restart of recovery there's
9168  * no value in having the minimum recovery point any earlier than this
9169  * anyway, because redo will begin just after the checkpoint record.
9170  */
9171  if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
9172  {
9173  ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
9175 
9176  /* update local copy */
9179  }
9180  if (flags & CHECKPOINT_IS_SHUTDOWN)
9183  }
9184  LWLockRelease(ControlFileLock);
9185 
9186  /*
9187  * Update the average distance between checkpoints/restartpoints if the
9188  * prior checkpoint exists.
9189  */
9190  if (PriorRedoPtr != InvalidXLogRecPtr)
9192 
9193  /*
9194  * Delete old log files, those no longer needed for last restartpoint to
9195  * prevent the disk holding the xlog from growing full.
9196  */
9198 
9199  /*
9200  * Retreat _logSegNo using the current end of xlog replayed or received,
9201  * whichever is later.
9202  */
9203  receivePtr = GetWalRcvWriteRecPtr(NULL, NULL);
9204  replayPtr = GetXLogReplayRecPtr(&replayTLI);
9205  endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
9206  KeepLogSeg(endptr, &_logSegNo);
9207  _logSegNo--;
9208 
9209  /*
9210  * Try to recycle segments on a useful timeline. If we've been promoted
9211  * since the beginning of this restartpoint, use the new timeline chosen
9212  * at end of recovery (RecoveryInProgress() sets ThisTimeLineID in that
9213  * case). If we're still in recovery, use the timeline we're currently
9214  * replaying.
9215  *
9216  * There is no guarantee that the WAL segments will be useful on the
9217  * current timeline; if recovery proceeds to a new timeline right after
9218  * this, the pre-allocated WAL segments on this timeline will not be used,
9219  * and will go wasted until recycled on the next restartpoint. We'll live
9220  * with that.
9221  */
9222  if (RecoveryInProgress())
9223  ThisTimeLineID = replayTLI;
9224 
9225  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr);
9226 
9227  /*
9228  * Make more log segments if needed. (Do this after recycling old log
9229  * segments, since that may supply some of the needed files.)
9230  */
9231  PreallocXlogFiles(endptr);
9232 
9233  /*
9234  * ThisTimeLineID is normally not set when we're still in recovery.
9235  * However, recycling/preallocating segments above needed ThisTimeLineID
9236  * to determine which timeline to install the segments on. Reset it now,
9237  * to restore the normal state of affairs for debugging purposes.
9238  */
9239  if (RecoveryInProgress())
9240  ThisTimeLineID = 0;
9241 
9242  /*
9243  * Truncate pg_subtrans if possible. We can throw away all data before
9244  * the oldest XMIN of any running transaction. No future transaction will
9245  * attempt to reference any pg_subtrans entry older than that (see Asserts
9246  * in subtrans.c). When hot standby is disabled, though, we mustn't do
9247  * this because StartupSUBTRANS hasn't been called yet.
9248  */
9249  if (EnableHotStandby)
9251 
9252  /* Real work is done, but log and update before releasing lock. */
9253  LogCheckpointEnd(true);
9254 
9255  xtime = GetLatestXTime();
9257  (errmsg("recovery restart point at %X/%X",
9258  (uint32) (lastCheckPoint.redo >> 32), (uint32) lastCheckPoint.redo),
9259  xtime ? errdetail("Last completed transaction was at log time %s.",
9260  timestamptz_to_str(xtime)) : 0));
9261 
9262  LWLockRelease(CheckpointLock);
9263 
9264  /*
9265  * Finally, execute archive_cleanup_command, if any.
9266  */
9267  if (archiveCleanupCommand && strcmp(archiveCleanupCommand, "") != 0)
9269  "archive_cleanup_command",
9270  false);
9271 
9272  return true;
9273 }
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8432
bool log_checkpoints
Definition: xlog.c:101
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:52
int64 pg_time_t
Definition: pgtime.h:23
XLogRecPtr GetWalRcvWriteRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI)
static void WALInsertLockRelease(void)
Definition: xlog.c:1689
int wal_segment_size
Definition: xlog.c:112
pg_time_t time
Definition: pg_control.h:128
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1591
int64 TimestampTz
Definition: timestamp.h:39
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition: xlog.c:2710
TimestampTz ckpt_start_t
Definition: xlog.h:235
slock_t info_lck
Definition: xlog.c:709
#define MemSet(start, val, len)
Definition: c.h:941
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:8964
TimestampTz GetLatestXTime(void)
Definition: xlog.c:6048
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:589
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:7882
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:356
XLogRecPtr lastCheckPointRecPtr
Definition: xlog.c:678
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1726
#define SpinLockAcquire(lock)
Definition: spin.h:62
void UpdateControlFile(void)
Definition: xlog.c:4792
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8347
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
Definition: xlog.c:11114
#define DEBUG2
Definition: elog.h:24
static XLogRecPtr RedoRecPtr
Definition: xlog.c:364
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3812
uint64 XLogSegNo
Definition: xlogdefs.h:41
int errdetail(const char *fmt,...)
Definition: elog.c:860
unsigned int uint32
Definition: c.h:358
XLogRecPtr RedoRecPtr
Definition: xlog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
CheckPoint lastCheckPoint
Definition: xlog.c:680
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
#define SpinLockRelease(lock)
Definition: spin.h:64
static TimeLineID minRecoveryPointTLI
Definition: xlog.c:835
#define PROCARRAY_FLAGS_DEFAULT
Definition: procarray.h:50
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9284
static ControlFileData * ControlFile
Definition: xlog.c:720
TimeLineID ThisTimeLineID
Definition: xlog.c:187
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr RedoRecPtr, XLogRecPtr endptr)
Definition: xlog.c:3942
TransactionId GetOldestXmin(Relation rel, int flags)
Definition: procarray.c:1307
uint64 XLogRecPtr
Definition: xlogdefs.h:21
CheckpointStatsData CheckpointStats
Definition: xlog.c:181
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1660
static XLogCtlData * XLogCtl
Definition: xlog.c:712
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1122
bool EnableHotStandby
Definition: xlog.c:93
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
int errmsg(const char *fmt,...)
Definition: elog.c:784
XLogRecPtr RedoRecPtr
Definition: xlog.c:562
XLogRecPtr lastCheckPointEndPtr
Definition: xlog.c:679
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:37
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8329
char * archiveCleanupCommand
Definition: xlog.c:270
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:211
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:834
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1751
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ DataChecksumsEnabled()

bool DataChecksumsEnabled ( void  )

Definition at line 4821 of file xlog.c.

References Assert, and ControlFileData::data_checksum_version.

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

4822 {
4823  Assert(ControlFile != NULL);
4824  return (ControlFile->data_checksum_version > 0);
4825 }
uint32 data_checksum_version
Definition: pg_control.h:222
static ControlFileData * ControlFile
Definition: xlog.c:720
#define Assert(condition)
Definition: c.h:732

◆ do_pg_abort_backup()

void do_pg_abort_backup ( void  )

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

11087 {
11088  /*
11089  * Quick exit if session is not keeping around a non-exclusive backup
11090  * already started.
11091  */
11093  return;
11094 
11099 
11102  {
11103  XLogCtl->Insert.forcePageWrites = false;
11104  }
11106 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1689
static SessionBackupState sessionBackupState
Definition: xlog.c:524
XLogCtlInsert Insert
Definition: xlog.c:589
bool forcePageWrites
Definition: xlog.c:563
int nonExclusiveBackups
Definition: xlog.c:575
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:574
#define Assert(condition)
Definition: c.h:732
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1660
static XLogCtlData * XLogCtl
Definition: xlog.c:712

◆ do_pg_start_backup()

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

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

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

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

References sessionBackupState.

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

10661 {
10662  return sessionBackupState;
10663 }
static SessionBackupState sessionBackupState
Definition: xlog.c:524

◆ GetCurrentChunkReplayStartTime()

TimestampTz GetCurrentChunkReplayStartTime ( void  )

Definition at line 6078 of file xlog.c.

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

Referenced by GetReplicationApplyDelay().

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

◆ GetFakeLSNForUnloggedRel()

XLogRecPtr GetFakeLSNForUnloggedRel ( void  )

Definition at line 4837 of file xlog.c.

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

Referenced by gistGetFakeLSN().

4838 {
4839  XLogRecPtr nextUnloggedLSN;
4840 
4841  /* increment the unloggedLSN counter, need SpinLock */
4843  nextUnloggedLSN = XLogCtl->unloggedLSN++;
4845 
4846  return nextUnloggedLSN;
4847 }
XLogRecPtr unloggedLSN
Definition: xlog.c:601
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:712
slock_t ulsn_lck
Definition: xlog.c:602

◆ GetFlushRecPtr()

XLogRecPtr GetFlushRecPtr ( void  )

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

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

◆ GetFullPageWriteInfo()

void GetFullPageWriteInfo ( XLogRecPtr RedoRecPtr_p,
bool doPageWrites_p 
)

Definition at line 8183 of file xlog.c.

References doPageWrites, and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

8184 {
8185  *RedoRecPtr_p = RedoRecPtr;
8186  *doPageWrites_p = doPageWrites;
8187 }
static bool doPageWrites
Definition: xlog.c:371
static XLogRecPtr RedoRecPtr
Definition: xlog.c:364

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )

Definition at line 8198 of file xlog.c.

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

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

8199 {
8200  XLogRecPtr recptr;
8201 
8203  recptr = XLogCtl->LogwrtRqst.Write;
8205 
8206  return recptr;
8207 }
slock_t info_lck
Definition: xlog.c:709
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
XLogRecPtr Write
Definition: xlog.c:431
XLogwrtRqst LogwrtRqst
Definition: xlog.c:592
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:712

◆ GetLastImportantRecPtr()

XLogRecPtr GetLastImportantRecPtr ( void  )

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

8233 {
8235  int i;
8236 
8237  for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
8238  {
8239  XLogRecPtr last_important;
8240 
8241  /*
8242  * Need to take a lock to prevent torn reads of the LSN, which are
8243  * possible on some of the supported platforms. WAL insert locks only
8244  * support exclusive mode, so we have to use that.
8245  */
8247  last_important = WALInsertLocks[i].l.lastImportantAt;
8248  LWLockRelease(&WALInsertLocks[i].l.lock);
8249 
8250  if (res < last_important)
8251  res = last_important;
8252  }
8253 
8254  return res;
8255 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
XLogRecPtr lastImportantAt
Definition: xlog.c:481
#define NUM_XLOGINSERT_LOCKS
Definition: xlog.c:119
WALInsertLock l
Definition: xlog.c:493
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1726
uint64 XLogRecPtr
Definition: xlogdefs.h:21
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1122
int i
static WALInsertLockPadded * WALInsertLocks
Definition: xlog.c:715

◆ GetLatestXTime()

TimestampTz GetLatestXTime ( void  )

Definition at line 6048 of file xlog.c.

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

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

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

◆ GetMockAuthenticationNonce()

char* GetMockAuthenticationNonce ( void  )

Definition at line 4811 of file xlog.c.

References Assert, and ControlFileData::mock_authentication_nonce.

Referenced by scram_mock_salt().

4812 {
4813  Assert(ControlFile != NULL);
4815 }
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition: pg_control.h:229
static ControlFileData * ControlFile
Definition: xlog.c:720
#define Assert(condition)
Definition: c.h:732

◆ GetRedoRecPtr()

XLogRecPtr GetRedoRecPtr ( void  )

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

8156 {
8157  XLogRecPtr ptr;
8158 
8159  /*
8160  * The possibly not up-to-date copy in XlogCtl is enough. Even if we
8161  * grabbed a WAL insertion lock to read the master copy, someone might
8162  * update it just after we've released the lock.
8163  */
8165  ptr = XLogCtl->RedoRecPtr;
8167 
8168  if (RedoRecPtr < ptr)
8169  RedoRecPtr = ptr;
8170 
8171  return RedoRecPtr;
8172 }
slock_t info_lck
Definition: xlog.c:709
#define SpinLockAcquire(lock)
Definition: spin.h:62
static XLogRecPtr RedoRecPtr
Definition: xlog.c:364
XLogRecPtr RedoRecPtr
Definition: xlog.c:593
#define SpinLockRelease(lock)
Definition: spin.h:64
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:712

◆ GetSystemIdentifier()

uint64 GetSystemIdentifier ( void  )

Definition at line 4801 of file xlog.c.

References Assert, and ControlFileData::system_identifier.

Referenced by IdentifySystem(), and WalReceiverMain().

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

◆ GetXLogInsertRecPtr()

XLogRecPtr GetXLogInsertRecPtr ( void  )

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

11134 {
11136  uint64 current_bytepos;
11137 
11138  SpinLockAcquire(&Insert->insertpos_lck);
11139  current_bytepos = Insert->CurrBytePos;
11140  SpinLockRelease(&Insert->insertpos_lck);
11141 
11142  return XLogBytePosToRecPtr(current_bytepos);
11143 }
slock_t insertpos_lck
Definition: xlog.c:531
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1958
XLogCtlInsert Insert
Definition: xlog.c:589
#define SpinLockAcquire(lock)
Definition: spin.h:62
uint64 CurrBytePos
Definition: xlog.c:540
static void Insert(File file)
Definition: fd.c:1061
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:712

◆ GetXLogReceiptTime()

void GetXLogReceiptTime ( TimestampTz rtime,
bool fromStream 
)

Definition at line 6094 of file xlog.c.

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

Referenced by GetStandbyLimitTime().

6095 {
6096  /*
6097  * This must be executed in the startup process, since we don't export the
6098  * relevant state to shared memory.
6099  */
6100  Assert(InRecovery);
6101 
6102  *rtime = XLogReceiptTime;
6103  *fromStream = (XLogReceiptSource == XLOG_FROM_STREAM);
6104 }
static XLogSource XLogReceiptSource
Definition: xlog.c:821
bool InRecovery
Definition: xlog.c:200
static TimestampTz XLogReceiptTime
Definition: xlog.c:820
#define Assert(condition)
Definition: c.h:732

◆ GetXLogReplayRecPtr()

XLogRecPtr GetXLogReplayRecPtr ( TimeLineID replayTLI)

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

11115 {
11116  XLogRecPtr recptr;
11117  TimeLineID tli;
11118 
11120  recptr = XLogCtl->lastReplayedEndRecPtr;
11121  tli = XLogCtl->lastReplayedTLI;
11123 
11124  if (replayTLI)
11125  *replayTLI = tli;
11126  return recptr;
11127 }
uint32 TimeLineID
Definition: xlogdefs.h:52
slock_t info_lck
Definition: xlog.c:709
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:712
TimeLineID lastReplayedTLI
Definition: xlog.c:689
XLogRecPtr lastReplayedEndRecPtr
Definition: xlog.c:688

◆ GetXLogWriteRecPtr()

XLogRecPtr GetXLogWriteRecPtr ( void  )

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

11150 {
11154 
11155  return LogwrtResult.Write;
11156 }
static XLogwrtResult LogwrtResult
Definition: xlog.c:756
slock_t info_lck
Definition: xlog.c:709
#define SpinLockAcquire(lock)
Definition: spin.h:62
XLogwrtResult LogwrtResult
Definition: xlog.c:612
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:712
XLogRecPtr Write
Definition: xlog.c:437

◆ HotStandbyActive()

bool HotStandbyActive ( void  )

Definition at line 7938 of file xlog.c.

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

Referenced by XLogWalRcvSendHSFeedback().

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

◆ HotStandbyActiveInReplay()

bool HotStandbyActiveInReplay ( void  )

Definition at line 7963 of file xlog.c.

References AmStartupProcess, Assert, IsPostmasterEnvironment, and LocalHotStandbyActive.

Referenced by btree_xlog_vacuum().

7964 {
7966  return LocalHotStandbyActive;
7967 }
#define AmStartupProcess()
Definition: miscadmin.h:412
bool IsPostmasterEnvironment
Definition: globals.c:108
static bool LocalHotStandbyActive
Definition: xlog.c:229
#define Assert(condition)
Definition: c.h:732

◆ InitXLOGAccess()

void InitXLOGAccess ( void  )

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

8130 {
8132 
8133  /* ThisTimeLineID doesn't change so we need no lock to copy it */
8136 
8137  /* set wal_segment_size */
8139 
8140  /* Use GetRedoRecPtr to copy the RedoRecPtr safely */
8141  (void) GetRedoRecPtr();
8142  /* Also update our copy of doPageWrites. */
8143  doPageWrites = (Insert->fullPageWrites || Insert->forcePageWrites);
8144 
8145  /* Also initialize the working areas for constructing WAL records */
8146  InitXLogInsert();
8147 }
int wal_segment_size
Definition: xlog.c:112
void InitXLogInsert(void)
Definition: xloginsert.c:1110
TimeLineID ThisTimeLineID
Definition: xlog.c:641
XLogCtlInsert Insert
Definition: xlog.c:589
bool fullPageWrites
Definition: xlog.c:564
uint32 xlog_seg_size
Definition: pg_control.h:209
static bool doPageWrites
Definition: xlog.c:371
bool forcePageWrites
Definition: xlog.c:563
static void Insert(File file)
Definition: fd.c:1061
static ControlFileData * ControlFile
Definition: xlog.c:720
TimeLineID ThisTimeLineID
Definition: xlog.c:187
#define Assert(condition)
Definition: c.h:732
static XLogCtlData * XLogCtl
Definition: xlog.c:712
XLogRecPtr GetRedoRecPtr(void)
Definition: xlog.c:8155
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:374

◆ issue_xlog_fsync()

void issue_xlog_fsync ( int  fd,
XLogSegNo  segno 
)

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

10070 {
10072  switch (sync_method)
10073  {
10074  case SYNC_METHOD_FSYNC:
10075  if (pg_fsync_no_writethrough(fd) != 0)
10076  ereport(PANIC,
10078  errmsg("could not fsync file \"%s\": %m",
10079  XLogFileNameP(ThisTimeLineID, segno))));
10080  break;
10081 #ifdef HAVE_FSYNC_WRITETHROUGH
10083  if (pg_fsync_writethrough(fd) != 0)
10084  ereport(PANIC,
10086  errmsg("could not fsync write-through file \"%s\": %m",
10087  XLogFileNameP(ThisTimeLineID, segno))));
10088  break;
10089 #endif
10090 #ifdef HAVE_FDATASYNC
10091  case SYNC_METHOD_FDATASYNC:
10092  if (pg_fdatasync(fd) != 0)
10093  ereport(PANIC,
10095  errmsg("could not fdatasync file \"%s\": %m",
10096  XLogFileNameP(ThisTimeLineID, segno))));
10097  break;
10098 #endif
10099  case SYNC_METHOD_OPEN:
10101  /* write synced it already */
10102  break;
10103  default:
10104  elog(PANIC, "unrecognized wal_sync_method: %d", sync_method);
10105  break;
10106  }
10108 }
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:10114
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:1343
#define ereport(elevel, rest)
Definition: elog.h:141
#define SYNC_METHOD_OPEN
Definition: xlog.h:27
TimeLineID ThisTimeLineID
Definition: xlog.c:187
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1319
int sync_method
Definition: xlog.c:102
#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 4921 of file xlog.c.

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

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

4922 {
4923  Assert(reset || ControlFile == NULL);
4924  ControlFile = palloc(sizeof(ControlFileData));
4925  ReadControlFile();
4926 }
void reset(void)
Definition: sql-declare.c:577
static void ReadControlFile(void)
Definition: xlog.c:4576
static ControlFileData * ControlFile
Definition: xlog.c:720
#define Assert(condition)
Definition: c.h:732
void * palloc(Size size)
Definition: mcxt.c:924

◆ RecoveryInProgress()

bool RecoveryInProgress ( void  )

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

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

◆ RecoveryIsPaused()

bool RecoveryIsPaused ( void  )

Definition at line 5917 of file xlog.c.

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

Referenced by pg_is_wal_replay_paused(), and recoveryPausesHere().

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

◆ RemovePromoteSignalFiles()

void RemovePromoteSignalFiles ( void  )

Definition at line 12182 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, and PROMOTE_SIGNAL_FILE.

Referenced by PostmasterMain().

12183 {
12184  unlink(PROMOTE_SIGNAL_FILE);
12186 }
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:366
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.h:367

◆ SetRecoveryPause()

void SetRecoveryPause ( bool  recoveryPause)

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

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

◆ SetWalWriterSleeping()

void SetWalWriterSleeping ( bool  sleeping)

Definition at line 12218 of file xlog.c.

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

Referenced by WalWriterMain().

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

◆ ShutdownXLOG()

void ShutdownXLOG ( int  code,
Datum  arg 
)

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

8279 {
8280  /*
8281  * We should have an aux process resource owner to use, and we should not
8282  * be in a transaction that's installed some other resowner.
8283  */
8285  Assert(CurrentResourceOwner == NULL ||
8288 
8289  /* Don't be chatty in standalone mode */
8291  (errmsg("shutting down")));
8292 
8293  /*
8294  * Signal walsenders to move to stopping state.
8295  */
8297 
8298  /*
8299  * Wait for WAL senders to be in stopping state. This prevents commands
8300  * from writing new WAL.
8301  */
8303 
8304  if (RecoveryInProgress())
8306  else
8307  {
8308  /*
8309  * If archiving is enabled, rotate the last XLOG file so that all the
8310  * remaining records are archived (postmaster wakes up the archiver
8311  * process one more time at the end of shutdown). The checkpoint
8312  * record will go to the next XLOG file and won't be archived (yet).
8313  */
8315  RequestXLogSwitch(false);
8316 
8318  }
8319  ShutdownCLOG();
8320  ShutdownCommitTs();
8321  ShutdownSUBTRANS();
8323 }
bool IsPostmasterEnvironment
Definition: globals.c:108
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9361
void ShutdownSUBTRANS(void)
Definition: subtrans.c:285
void CreateCheckPoint(int flags)
Definition: xlog.c:8494
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void ShutdownCLOG(void)
Definition: clog.c:823
bool CreateRestartPoint(int flags)
Definition: xlog.c:9034
#define XLogArchiveCommandSet()
Definition: xlog.h:175
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:7882
ResourceOwner AuxProcessResourceOwner
Definition: resowner.c:145
void WalSndWaitStopping(void)
Definition: walsender.c:3139
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:3113
void ShutdownCommitTs(void)
Definition: commit_ts.c:744
#define Assert(condition)
Definition: c.h:732
#define XLogArchivingActive()
Definition: xlog.h:170
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:214
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:211

◆ StartupXLOG()

void StartupXLOG ( void  )

Definition at line 6179 of file xlog.c.

References AdvanceNextFullTransactionIdPastXid(), AdvanceOldestClogXid(), AllowCascadeReplication, appendStringInfo(), appendStringInfoString(), ArchiveRecoveryRequested, ErrorContextCallback::arg, Assert, AuxProcessResourceOwner, BACKUP_LABEL_FILE, BACKUP_LABEL_OLD, ControlFileData::backupEndPoint, ControlFileData::backupEndRequired, ControlFileData::backupStartPoint, bgwriterLaunched, buf, ErrorContextCallback::callback, ControlFileData::checkPoint, CHECKPOINT_END_OF_RECOVERY, CHECKPOINT_FORCE, CHECKPOINT_IMMEDIATE, CHECKPOINT_WAIT, ControlFileData::checkPointCopy, CheckRecoveryConsistency(), CheckRequiredParameterValues(), checkTimeLineSwitch(), checkXLogConsistency(), XLogCtlData::ckptFullXid, close, CompleteCommitTsInitialization(), CreateCheckPoint(), CreateEndOfRecoveryRecord(), XLogCtlInsert::CurrBytePos, XLogCtlData::currentChunkStartTime, CurrentResourceOwner, StringInfoData::data, DataDir, DB_IN_ARCHIVE_RECOVERY, DB_IN_CRASH_RECOVERY, DB_IN_PRODUCTION, DB_SHUTDOWNED, DB_SHUTDOWNED_IN_RECOVERY, DB_SHUTDOWNING, DEBUG1, DEBUG2, DEBUG3, DeleteAllExportedSnapshotFiles(), DisownLatch(), doPageWrites, doRequestWalReceiverReply, durable_rename(), elog, EnableHotStandby, EnableSyncRequestForwarding(), EndRecPtr, ereport, errcode(), errcode_for_file_access(), errdetail(), errhint(), errmsg(), errmsg_internal(), ERROR, error_context_stack, ExecuteRecoveryCommand(), exitArchiveRecovery(), 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::nextFullXid, VariableCacheData::nextFullXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, VariableCacheData::nextOid, RunningTransactionsData::nextXid, NIL, NOTICE, tablespaceinfo::oid, VariableCacheData::oidCount, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, RunningTransactionsData::oldestRunningXid, CheckPoint::oldestXid, CheckPoint::oldestXidDB, OwnLatch(), XLogCtlData::pages, palloc(), PANIC, tablespaceinfo::path, pfree(), pg_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(), 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, TransactionIdIsNormal, TransactionIdIsValid, TransactionIdRetreat, TrimCLOG(), TrimMultiXact(), U64FromFullTransactionId, UINT64_FORMAT, 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, XidFromFullTransactionId, 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().

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