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
 
char * recovery_target_time_string
 
const char * recoveryTargetName
 
XLogRecPtr recoveryTargetLSN
 
RecoveryTargetType recoveryTarget
 
char * PromoteTriggerFile
 
RecoveryTargetTimeLineGoal recoveryTargetTimeLineGoal
 
TimeLineID recoveryTargetTLIRequested
 
TimeLineID recoveryTargetTLI
 
int CheckPointSegments
 
bool StandbyModeRequested
 
bool StandbyMode
 
int XLogArchiveMode
 
PGDLLIMPORT int wal_level
 
CheckpointStatsData CheckpointStats
 

Macro Definition Documentation

◆ BACKUP_LABEL_FILE

#define BACKUP_LABEL_FILE   "backup_label"

◆ BACKUP_LABEL_OLD

#define BACKUP_LABEL_OLD   "backup_label.old"

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

typedef enum ArchiveMode ArchiveMode

◆ CheckpointStatsData

◆ SessionBackupState

◆ WalLevel

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

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

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

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2284 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

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

◆ BootStrapXLOG()

void BootStrapXLOG ( void  )

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

5088 {
5089  CheckPoint checkPoint;
5090  char *buffer;
5091  XLogPageHeader page;
5092  XLogLongPageHeader longpage;
5093  XLogRecord *record;
5094  char *recptr;
5095  bool use_existent;
5096  uint64 sysidentifier;
5097  char mock_auth_nonce[MOCK_AUTH_NONCE_LEN];
5098  struct timeval tv;
5099  pg_crc32c crc;
5100 
5101  /*
5102  * Select a hopefully-unique system identifier code for this installation.
5103  * We use the result of gettimeofday(), including the fractional seconds
5104  * field, as being about as unique as we can easily get. (Think not to
5105  * use random(), since it hasn't been seeded and there's no portable way
5106  * to seed it other than the system clock value...) The upper half of the
5107  * uint64 value is just the tv_sec part, while the lower half contains the
5108  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
5109  * PID for a little extra uniqueness. A person knowing this encoding can
5110  * determine the initialization time of the installation, which could
5111  * perhaps be useful sometimes.
5112  */
5113  gettimeofday(&tv, NULL);
5114  sysidentifier = ((uint64) tv.tv_sec) << 32;
5115  sysidentifier |= ((uint64) tv.tv_usec) << 12;
5116  sysidentifier |= getpid() & 0xFFF;
5117 
5118  /*
5119  * Generate a random nonce. This is used for authentication requests that
5120  * will fail because the user does not exist. The nonce is used to create
5121  * a genuine-looking password challenge for the non-existent user, in lieu
5122  * of an actual stored password.
5123  */
5124  if (!pg_strong_random(mock_auth_nonce, MOCK_AUTH_NONCE_LEN))
5125  ereport(PANIC,
5126  (errcode(ERRCODE_INTERNAL_ERROR),
5127  errmsg("could not generate secret authorization token")));
5128 
5129  /* First timeline ID is always 1 */
5130  ThisTimeLineID = 1;
5131 
5132  /* page buffer must be aligned suitably for O_DIRECT */
5133  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
5134  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
5135  memset(page, 0, XLOG_BLCKSZ);
5136 
5137  /*
5138  * Set up information for the initial checkpoint record
5139  *
5140  * The initial checkpoint record is written to the beginning of the WAL
5141  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5142  * used, so that we can use 0/0 to mean "before any valid WAL segment".
5143  */
5144  checkPoint.redo = wal_segment_size + SizeOfXLogLongPHD;
5145  checkPoint.ThisTimeLineID = ThisTimeLineID;
5146  checkPoint.PrevTimeLineID = ThisTimeLineID;
5147  checkPoint.fullPageWrites = fullPageWrites;
5148  checkPoint.nextFullXid =
5150  checkPoint.nextOid = FirstBootstrapObjectId;
5151  checkPoint.nextMulti = FirstMultiXactId;
5152  checkPoint.nextMultiOffset = 0;
5153  checkPoint.oldestXid = FirstNormalTransactionId;
5154  checkPoint.oldestXidDB = TemplateDbOid;
5155  checkPoint.oldestMulti = FirstMultiXactId;
5156  checkPoint.oldestMultiDB = TemplateDbOid;
5159  checkPoint.time = (pg_time_t) time(NULL);
5161 
5163  ShmemVariableCache->nextOid = checkPoint.nextOid;
5165  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5166  AdvanceOldestClogXid(checkPoint.oldestXid);
5167  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5168  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5170 
5171  /* Set up the XLOG page header */
5172  page->xlp_magic = XLOG_PAGE_MAGIC;
5173  page->xlp_info = XLP_LONG_HEADER;
5174  page->xlp_tli = ThisTimeLineID;
5176  longpage = (XLogLongPageHeader) page;
5177  longpage->xlp_sysid = sysidentifier;
5178  longpage->xlp_seg_size = wal_segment_size;
5179  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5180 
5181  /* Insert the initial checkpoint record */
5182  recptr = ((char *) page + SizeOfXLogLongPHD);
5183  record = (XLogRecord *) recptr;
5184  record->xl_prev = 0;
5185  record->xl_xid = InvalidTransactionId;
5186  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5188  record->xl_rmid = RM_XLOG_ID;
5189  recptr += SizeOfXLogRecord;
5190  /* fill the XLogRecordDataHeaderShort struct */
5191  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5192  *(recptr++) = sizeof(checkPoint);
5193  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5194  recptr += sizeof(checkPoint);
5195  Assert(recptr - (char *) record == record->xl_tot_len);
5196 
5197  INIT_CRC32C(crc);
5198  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5199  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5200  FIN_CRC32C(crc);
5201  record->xl_crc = crc;
5202 
5203  /* Create first XLOG segment file */
5204  use_existent = false;
5205  openLogFile = XLogFileInit(1, &use_existent, false);
5206 
5207  /* Write the first page with the initial record */
5208  errno = 0;
5210  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5211  {
5212  /* if write didn't set errno, assume problem is no disk space */
5213  if (errno == 0)
5214  errno = ENOSPC;
5215  ereport(PANIC,
5217  errmsg("could not write bootstrap write-ahead log file: %m")));
5218  }
5220 
5222  if (pg_fsync(openLogFile) != 0)
5223  ereport(PANIC,
5225  errmsg("could not fsync bootstrap write-ahead log file: %m")));
5227 
5228  if (close(openLogFile) != 0)
5229  ereport(PANIC,
5231  errmsg("could not close bootstrap write-ahead log file: %m")));
5232 
5233  openLogFile = -1;
5234 
5235  /* Now create pg_control */
5236 
5237  memset(ControlFile, 0, sizeof(ControlFileData));
5238  /* Initialize pg_control status fields */
5239  ControlFile->system_identifier = sysidentifier;
5240  memcpy(ControlFile->mock_authentication_nonce, mock_auth_nonce, MOCK_AUTH_NONCE_LEN);
5242  ControlFile->time = checkPoint.time;
5243  ControlFile->checkPoint = checkPoint.redo;
5244  ControlFile->checkPointCopy = checkPoint;
5246 
5247  /* Set important parameter values for use when replaying WAL */
5257 
5258  /* some additional ControlFile fields are set in WriteControlFile() */
5259 
5260  WriteControlFile();
5261 
5262  /* Bootstrap the commit log, too */
5263  BootStrapCLOG();
5267 
5268  pfree(buffer);
5269 
5270  /*
5271  * Force control file to be read - in contrast to normal processing we'd
5272  * otherwise never run the checks and GUC related initializations therein.
5273  */
5274  ReadControlFile();
5275 }
static void WriteControlFile(void)
Definition: xlog.c:4485
#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:3205
void BootStrapMultiXact(void)
Definition: multixact.c:1868
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:1056
#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:4577
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:1342
#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:779
static ControlFileData * ControlFile
Definition: xlog.c:721
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
Definition: multixact.c:2196
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:1318
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:949
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:331
#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:2162

◆ CheckPromoteSignal()

bool CheckPromoteSignal ( void  )

Definition at line 12240 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, PROMOTE_SIGNAL_FILE, and stat.

Referenced by sigusr1_handler().

12241 {
12242  struct stat stat_buf;
12243 
12244  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
12246  return true;
12247 
12248  return false;
12249 }
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:366
struct stat stat_buf
Definition: pg_standby.c:101
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.h:367
#define stat(a, b)
Definition: win32_port.h:255

◆ CheckXLogRemoved()

void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)

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

3847 {
3848  int save_errno = errno;
3849  XLogSegNo lastRemovedSegNo;
3850 
3852  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3854 
3855  if (segno <= lastRemovedSegNo)
3856  {
3857  char filename[MAXFNAMELEN];
3858 
3859  XLogFileName(filename, tli, segno, wal_segment_size);
3860  errno = save_errno;
3861  ereport(ERROR,
3863  errmsg("requested WAL segment %s has already been removed",
3864  filename)));
3865  }
3866  errno = save_errno;
3867 }
int wal_segment_size
Definition: xlog.c:112
slock_t info_lck
Definition: xlog.c:710
XLogSegNo lastRemovedSegNo
Definition: xlog.c:599
#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:713
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 8529 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().

8530 {
8531  bool shutdown;
8532  CheckPoint checkPoint;
8533  XLogRecPtr recptr;
8534  XLogSegNo _logSegNo;
8536  uint32 freespace;
8537  XLogRecPtr PriorRedoPtr;
8538  XLogRecPtr curInsert;
8539  XLogRecPtr last_important_lsn;
8540  VirtualTransactionId *vxids;
8541  int nvxids;
8542 
8543  /*
8544  * An end-of-recovery checkpoint is really a shutdown checkpoint, just
8545  * issued at a different time.
8546  */
8548  shutdown = true;
8549  else
8550  shutdown = false;
8551 
8552  /* sanity check */
8553  if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
8554  elog(ERROR, "can't create a checkpoint during recovery");
8555 
8556  /*
8557  * Initialize InitXLogInsert working areas before entering the critical
8558  * section. Normally, this is done by the first call to
8559  * RecoveryInProgress() or LocalSetXLogInsertAllowed(), but when creating
8560  * an end-of-recovery checkpoint, the LocalSetXLogInsertAllowed call is
8561  * done below in a critical section, and InitXLogInsert cannot be called
8562  * in a critical section.
8563  */
8564  InitXLogInsert();
8565 
8566  /*
8567  * Acquire CheckpointLock to ensure only one checkpoint happens at a time.
8568  * (This is just pro forma, since in the present system structure there is
8569  * only one process that is allowed to issue checkpoints at any given
8570  * time.)
8571  */
8572  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
8573 
8574  /*
8575  * Prepare to accumulate statistics.
8576  *
8577  * Note: because it is possible for log_checkpoints to change while a
8578  * checkpoint proceeds, we always accumulate stats, even if
8579  * log_checkpoints is currently off.
8580  */
8581  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
8583 
8584  /*
8585  * Use a critical section to force system panic if we have trouble.
8586  */
8588 
8589  if (shutdown)
8590  {
8591  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8593  ControlFile->time = (pg_time_t) time(NULL);
8595  LWLockRelease(ControlFileLock);
8596  }
8597 
8598  /*
8599  * Let smgr prepare for checkpoint; this has to happen before we determine
8600  * the REDO pointer. Note that smgr must not do anything that'd have to
8601  * be undone if we decide no checkpoint is needed.
8602  */
8604 
8605  /* Begin filling in the checkpoint WAL record */
8606  MemSet(&checkPoint, 0, sizeof(checkPoint));
8607  checkPoint.time = (pg_time_t) time(NULL);
8608 
8609  /*
8610  * For Hot Standby, derive the oldestActiveXid before we fix the redo
8611  * pointer. This allows us to begin accumulating changes to assemble our
8612  * starting snapshot of locks and transactions.
8613  */
8614  if (!shutdown && XLogStandbyInfoActive())
8616  else
8618 
8619  /*
8620  * Get location of last important record before acquiring insert locks (as
8621  * GetLastImportantRecPtr() also locks WAL locks).
8622  */
8623  last_important_lsn = GetLastImportantRecPtr();
8624 
8625  /*
8626  * We must block concurrent insertions while examining insert state to
8627  * determine the checkpoint REDO pointer.
8628  */
8630  curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
8631 
8632  /*
8633  * If this isn't a shutdown or forced checkpoint, and if there has been no
8634  * WAL activity requiring a checkpoint, skip it. The idea here is to
8635  * avoid inserting duplicate checkpoints when the system is idle.
8636  */
8637  if ((flags & (CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_END_OF_RECOVERY |
8638  CHECKPOINT_FORCE)) == 0)
8639  {
8640  if (last_important_lsn == ControlFile->checkPoint)
8641  {
8643  LWLockRelease(CheckpointLock);
8644  END_CRIT_SECTION();
8645  ereport(DEBUG1,
8646  (errmsg("checkpoint skipped because system is idle")));
8647  return;
8648  }
8649  }
8650 
8651  /*
8652  * An end-of-recovery checkpoint is created before anyone is allowed to
8653  * write WAL. To allow us to write the checkpoint record, temporarily
8654  * enable XLogInsertAllowed. (This also ensures ThisTimeLineID is
8655  * initialized, which we need here and in AdvanceXLInsertBuffer.)
8656  */
8657  if (flags & CHECKPOINT_END_OF_RECOVERY)
8659 
8660  checkPoint.ThisTimeLineID = ThisTimeLineID;
8661  if (flags & CHECKPOINT_END_OF_RECOVERY)
8662  checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
8663  else
8664  checkPoint.PrevTimeLineID = ThisTimeLineID;
8665 
8666  checkPoint.fullPageWrites = Insert->fullPageWrites;
8667 
8668  /*
8669  * Compute new REDO record ptr = location of next XLOG record.
8670  *
8671  * NB: this is NOT necessarily where the checkpoint record itself will be,
8672  * since other backends may insert more XLOG records while we're off doing
8673  * the buffer flush work. Those XLOG records are logically after the
8674  * checkpoint, even though physically before it. Got that?
8675  */
8676  freespace = INSERT_FREESPACE(curInsert);
8677  if (freespace == 0)
8678  {
8679  if (XLogSegmentOffset(curInsert, wal_segment_size) == 0)
8680  curInsert += SizeOfXLogLongPHD;
8681  else
8682  curInsert += SizeOfXLogShortPHD;
8683  }
8684  checkPoint.redo = curInsert;
8685 
8686  /*
8687  * Here we update the shared RedoRecPtr for future XLogInsert calls; this
8688  * must be done while holding all the insertion locks.
8689  *
8690  * Note: if we fail to complete the checkpoint, RedoRecPtr will be left
8691  * pointing past where it really needs to point. This is okay; the only
8692  * consequence is that XLogInsert might back up whole buffers that it
8693  * didn't really need to. We can't postpone advancing RedoRecPtr because
8694  * XLogInserts that happen while we are dumping buffers must assume that
8695  * their buffer changes are not included in the checkpoint.
8696  */
8697  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
8698 
8699  /*
8700  * Now we can release the WAL insertion locks, allowing other xacts to
8701  * proceed while we are flushing disk buffers.
8702  */
8704 
8705  /* Update the info_lck-protected copy of RedoRecPtr as well */
8707  XLogCtl->RedoRecPtr = checkPoint.redo;
8709 
8710  /*
8711  * If enabled, log checkpoint start. We postpone this until now so as not
8712  * to log anything if we decided to skip the checkpoint.
8713  */
8714  if (log_checkpoints)
8715  LogCheckpointStart(flags, false);
8716 
8717  TRACE_POSTGRESQL_CHECKPOINT_START(flags);
8718 
8719  /*
8720  * Get the other info we need for the checkpoint record.
8721  *
8722  * We don't need to save oldestClogXid in the checkpoint, it only matters
8723  * for the short period in which clog is being truncated, and if we crash
8724  * during that we'll redo the clog truncation and fix up oldestClogXid
8725  * there.
8726  */
8727  LWLockAcquire(XidGenLock, LW_SHARED);
8729  checkPoint.oldestXid = ShmemVariableCache->oldestXid;
8731  LWLockRelease(XidGenLock);
8732 
8733  LWLockAcquire(CommitTsLock, LW_SHARED);
8736  LWLockRelease(CommitTsLock);
8737 
8738  LWLockAcquire(OidGenLock, LW_SHARED);
8739  checkPoint.nextOid = ShmemVariableCache->nextOid;
8740  if (!shutdown)
8741  checkPoint.nextOid += ShmemVariableCache->oidCount;
8742  LWLockRelease(OidGenLock);
8743 
8744  MultiXactGetCheckptMulti(shutdown,
8745  &checkPoint.nextMulti,
8746  &checkPoint.nextMultiOffset,
8747  &checkPoint.oldestMulti,
8748  &checkPoint.oldestMultiDB);
8749 
8750  /*
8751  * Having constructed the checkpoint record, ensure all shmem disk buffers
8752  * and commit-log buffers are flushed to disk.
8753  *
8754  * This I/O could fail for various reasons. If so, we will fail to
8755  * complete the checkpoint, but there is no reason to force a system
8756  * panic. Accordingly, exit critical section while doing it.
8757  */
8758  END_CRIT_SECTION();
8759 
8760  /*
8761  * In some cases there are groups of actions that must all occur on one
8762  * side or the other of a checkpoint record. Before flushing the
8763  * checkpoint record we must explicitly wait for any backend currently
8764  * performing those groups of actions.
8765  *
8766  * One example is end of transaction, so we must wait for any transactions
8767  * that are currently in commit critical sections. If an xact inserted
8768  * its commit record into XLOG just before the REDO point, then a crash
8769  * restart from the REDO point would not replay that record, which means
8770  * that our flushing had better include the xact's update of pg_xact. So
8771  * we wait till he's out of his commit critical section before proceeding.
8772  * See notes in RecordTransactionCommit().
8773  *
8774  * Because we've already released the insertion locks, this test is a bit
8775  * fuzzy: it is possible that we will wait for xacts we didn't really need
8776  * to wait for. But the delay should be short and it seems better to make
8777  * checkpoint take a bit longer than to hold off insertions longer than
8778  * necessary. (In fact, the whole reason we have this issue is that xact.c
8779  * does commit record XLOG insertion and clog update as two separate steps
8780  * protected by different locks, but again that seems best on grounds of
8781  * minimizing lock contention.)
8782  *
8783  * A transaction that has not yet set delayChkpt when we look cannot be at
8784  * risk, since he's not inserted his commit record yet; and one that's
8785  * already cleared it is not at risk either, since he's done fixing clog
8786  * and we will correctly flush the update below. So we cannot miss any
8787  * xacts we need to wait for.
8788  */
8789  vxids = GetVirtualXIDsDelayingChkpt(&nvxids);
8790  if (nvxids > 0)
8791  {
8792  do
8793  {
8794  pg_usleep(10000L); /* wait for 10 msec */
8795  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids));
8796  }
8797  pfree(vxids);
8798 
8799  CheckPointGuts(checkPoint.redo, flags);
8800 
8801  /*
8802  * Take a snapshot of running transactions and write this to WAL. This
8803  * allows us to reconstruct the state of running transactions during
8804  * archive recovery, if required. Skip, if this info disabled.
8805  *
8806  * If we are shutting down, or Startup process is completing crash
8807  * recovery we don't need to write running xact data.
8808  */
8809  if (!shutdown && XLogStandbyInfoActive())
8811 
8813 
8814  /*
8815  * Now insert the checkpoint record into XLOG.
8816  */
8817  XLogBeginInsert();
8818  XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));
8819  recptr = XLogInsert(RM_XLOG_ID,
8820  shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
8822 
8823  XLogFlush(recptr);
8824 
8825  /*
8826  * We mustn't write any new WAL after a shutdown checkpoint, or it will be
8827  * overwritten at next startup. No-one should even try, this just allows
8828  * sanity-checking. In the case of an end-of-recovery checkpoint, we want
8829  * to just temporarily disable writing until the system has exited
8830  * recovery.
8831  */
8832  if (shutdown)
8833  {
8834  if (flags & CHECKPOINT_END_OF_RECOVERY)
8835  LocalXLogInsertAllowed = -1; /* return to "check" state */
8836  else
8837  LocalXLogInsertAllowed = 0; /* never again write WAL */
8838  }
8839 
8840  /*
8841  * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
8842  * = end of actual checkpoint record.
8843  */
8844  if (shutdown && checkPoint.redo != ProcLastRecPtr)
8845  ereport(PANIC,
8846  (errmsg("concurrent write-ahead log activity while database system is shutting down")));
8847 
8848  /*
8849  * Remember the prior checkpoint's redo ptr for
8850  * UpdateCheckPointDistanceEstimate()
8851  */
8852  PriorRedoPtr = ControlFile->checkPointCopy.redo;
8853 
8854  /*
8855  * Update the control file.
8856  */
8857  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8858  if (shutdown)
8861  ControlFile->checkPointCopy = checkPoint;
8862  ControlFile->time = (pg_time_t) time(NULL);
8863  /* crash recovery should always recover to the end of WAL */
8866 
8867  /*
8868  * Persist unloggedLSN value. It's reset on crash recovery, so this goes
8869  * unused on non-shutdown checkpoints, but seems useful to store it always
8870  * for debugging purposes.
8871  */
8875 
8877  LWLockRelease(ControlFileLock);
8878 
8879  /* Update shared-memory copy of checkpoint XID/epoch */
8881  XLogCtl->ckptFullXid = checkPoint.nextFullXid;
8883 
8884  /*
8885  * We are now done with critical updates; no need for system panic if we
8886  * have trouble while fooling with old log segments.
8887  */
8888  END_CRIT_SECTION();
8889 
8890  /*
8891  * Let smgr do post-checkpoint cleanup (eg, deleting old files).
8892  */
8894 
8895  /*
8896  * Update the average distance between checkpoints if the prior checkpoint
8897  * exists.
8898  */
8899  if (PriorRedoPtr != InvalidXLogRecPtr)
8901 
8902  /*
8903  * Delete old log files, those no longer needed for last checkpoint to
8904  * prevent the disk holding the xlog from growing full.
8905  */
8907  KeepLogSeg(recptr, &_logSegNo);
8908  _logSegNo--;
8909  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr);
8910 
8911  /*
8912  * Make more log segments if needed. (Do this after recycling old log
8913  * segments, since that may supply some of the needed files.)
8914  */
8915  if (!shutdown)
8916  PreallocXlogFiles(recptr);
8917 
8918  /*
8919  * Truncate pg_subtrans if possible. We can throw away all data before
8920  * the oldest XMIN of any running transaction. No future transaction will
8921  * attempt to reference any pg_subtrans entry older than that (see Asserts
8922  * in subtrans.c). During recovery, though, we mustn't do this because
8923  * StartupSUBTRANS hasn't been called yet.
8924  */
8925  if (!RecoveryInProgress())
8927 
8928  /* Real work is done, but log and update stats before releasing lock. */
8929  LogCheckpointEnd(false);
8930 
8931  TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
8932  NBuffers,
8936 
8937  LWLockRelease(CheckpointLock);
8938 }
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:8267
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8467
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:1690
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:1583
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1959
XLogRecPtr unloggedLSN
Definition: xlog.c:602
XLogRecPtr ProcLastRecPtr
Definition: xlog.c:351
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:710
#define END_CRIT_SECTION()
Definition: miscadmin.h:134
VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids)
Definition: procarray.c:2271
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: xlog.c:643
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:955
void MultiXactGetCheckptMulti(bool is_shutdown, MultiXactId *nextMulti, MultiXactOffset *nextMultiOffset, MultiXactId *oldestMulti, Oid *oldestMultiDB)
Definition: multixact.c:2120
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:8999
FullTransactionId nextFullXid
Definition: transam.h:164
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:590
TransactionId oldestXid
Definition: pg_control.h:47
bool RecoveryInProgress(void)
Definition: xlog.c:7917
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:565
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2798
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:4793
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
void pfree(void *pointer)
Definition: mcxt.c:1056
XLogRecPtr LogStandbySnapshot(void)
Definition: standby.c:901
#define ERROR
Definition: elog.h:43
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8382
static XLogRecPtr RedoRecPtr
Definition: xlog.c:365
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
XLogRecPtr unloggedLSN
Definition: pg_control.h:133
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3813
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:541
unsigned int uint32
Definition: c.h:358
XLogRecPtr RedoRecPtr
Definition: xlog.c:594
int ckpt_segs_removed
Definition: xlog.h:244
#define CHECKPOINT_FORCE
Definition: xlog.h:215
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:727
#define ereport(elevel, rest)
Definition: elog.h:141
TransactionId oldestCommitTsXid
Definition: transam.h:176
static void Insert(File file)
Definition: fd.c:1059
int ckpt_bufs_written
Definition: xlog.h:241
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8043
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:9319
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
Oid oldestMultiDB
Definition: pg_control.h:50
FullTransactionId ckptFullXid
Definition: xlog.c:595
#define XLogStandbyInfoActive()
Definition: xlog.h:195
static ControlFileData * ControlFile
Definition: xlog.c:721
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:3943
bool fullPageWrites
Definition: pg_control.h:42
TransactionId GetOldestXmin(Relation rel, int flags)
Definition: procarray.c:1304
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:1661
static XLogCtlData * XLogCtl
Definition: xlog.c:713
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:603
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:2109
int NBuffers
Definition: globals.c:131
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids)
Definition: procarray.c:2316
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr RedoRecPtr
Definition: xlog.c:563
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:37
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8364
#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 9069 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().

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

◆ DataChecksumsEnabled()

bool DataChecksumsEnabled ( void  )

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

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

◆ do_pg_abort_backup()

void do_pg_abort_backup ( void  )

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

11122 {
11123  /*
11124  * Quick exit if session is not keeping around a non-exclusive backup
11125  * already started.
11126  */
11128  return;
11129 
11134 
11137  {
11138  XLogCtl->Insert.forcePageWrites = false;
11139  }
11141 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1690
static SessionBackupState sessionBackupState
Definition: xlog.c:525
XLogCtlInsert Insert
Definition: xlog.c:590
bool forcePageWrites
Definition: xlog.c:564
int nonExclusiveBackups
Definition: xlog.c:576
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:575
#define Assert(condition)
Definition: c.h:732
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1661
static XLogCtlData * XLogCtl
Definition: xlog.c:713

◆ 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 10197 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().

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

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

References sessionBackupState.

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

10696 {
10697  return sessionBackupState;
10698 }
static SessionBackupState sessionBackupState
Definition: xlog.c:525

◆ GetCurrentChunkReplayStartTime()

TimestampTz GetCurrentChunkReplayStartTime ( void  )

Definition at line 6100 of file xlog.c.

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

Referenced by GetReplicationApplyDelay().

6101 {
6102  TimestampTz xtime;
6103 
6105  xtime = XLogCtl->currentChunkStartTime;
6107 
6108  return xtime;
6109 }
int64 TimestampTz
Definition: timestamp.h:39
slock_t info_lck
Definition: xlog.c:710
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:713
TimestampTz currentChunkStartTime
Definition: xlog.c:700

◆ GetFakeLSNForUnloggedRel()

XLogRecPtr GetFakeLSNForUnloggedRel ( void  )

Definition at line 4838 of file xlog.c.

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

Referenced by gistGetFakeLSN().

4839 {
4840  XLogRecPtr nextUnloggedLSN;
4841 
4842  /* increment the unloggedLSN counter, need SpinLock */
4844  nextUnloggedLSN = XLogCtl->unloggedLSN++;
4846 
4847  return nextUnloggedLSN;
4848 }
XLogRecPtr unloggedLSN
Definition: xlog.c:602
#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:713
slock_t ulsn_lck
Definition: xlog.c:603

◆ GetFlushRecPtr()

XLogRecPtr GetFlushRecPtr ( void  )

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

8250 {
8254 
8255  return LogwrtResult.Flush;
8256 }
static XLogwrtResult LogwrtResult
Definition: xlog.c:757
slock_t info_lck
Definition: xlog.c:710
#define SpinLockAcquire(lock)
Definition: spin.h:62
XLogwrtResult LogwrtResult
Definition: xlog.c:613
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:713
XLogRecPtr Flush
Definition: xlog.c:439

◆ GetFullPageWriteInfo()

void GetFullPageWriteInfo ( XLogRecPtr RedoRecPtr_p,
bool doPageWrites_p 
)

Definition at line 8218 of file xlog.c.

References doPageWrites, and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

8219 {
8220  *RedoRecPtr_p = RedoRecPtr;
8221  *doPageWrites_p = doPageWrites;
8222 }
static bool doPageWrites
Definition: xlog.c:372
static XLogRecPtr RedoRecPtr
Definition: xlog.c:365

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )

Definition at line 8233 of file xlog.c.

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

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

8234 {
8235  XLogRecPtr recptr;
8236 
8238  recptr = XLogCtl->LogwrtRqst.Write;
8240 
8241  return recptr;
8242 }
slock_t info_lck
Definition: xlog.c:710
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
XLogRecPtr Write
Definition: xlog.c:432
XLogwrtRqst LogwrtRqst
Definition: xlog.c:593
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:713

◆ GetLastImportantRecPtr()

XLogRecPtr GetLastImportantRecPtr ( void  )

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

8268 {
8270  int i;
8271 
8272  for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
8273  {
8274  XLogRecPtr last_important;
8275 
8276  /*
8277  * Need to take a lock to prevent torn reads of the LSN, which are
8278  * possible on some of the supported platforms. WAL insert locks only
8279  * support exclusive mode, so we have to use that.
8280  */
8282  last_important = WALInsertLocks[i].l.lastImportantAt;
8283  LWLockRelease(&WALInsertLocks[i].l.lock);
8284 
8285  if (res < last_important)
8286  res = last_important;
8287  }
8288 
8289  return res;
8290 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
XLogRecPtr lastImportantAt
Definition: xlog.c:482
#define NUM_XLOGINSERT_LOCKS
Definition: xlog.c:119
WALInsertLock l
Definition: xlog.c:494
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:716

◆ GetLatestXTime()

TimestampTz GetLatestXTime ( void  )

Definition at line 6070 of file xlog.c.

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

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

6071 {
6072  TimestampTz xtime;
6073 
6075  xtime = XLogCtl->recoveryLastXTime;
6077 
6078  return xtime;
6079 }
int64 TimestampTz
Definition: timestamp.h:39
slock_t info_lck
Definition: xlog.c:710
#define SpinLockAcquire(lock)
Definition: spin.h:62
TimestampTz recoveryLastXTime
Definition: xlog.c:694
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:713

◆ GetMockAuthenticationNonce()

char* GetMockAuthenticationNonce ( void  )

Definition at line 4812 of file xlog.c.

References Assert, and ControlFileData::mock_authentication_nonce.

Referenced by scram_mock_salt().

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

◆ GetRedoRecPtr()

XLogRecPtr GetRedoRecPtr ( void  )

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

8191 {
8192  XLogRecPtr ptr;
8193 
8194  /*
8195  * The possibly not up-to-date copy in XlogCtl is enough. Even if we
8196  * grabbed a WAL insertion lock to read the master copy, someone might
8197  * update it just after we've released the lock.
8198  */
8200  ptr = XLogCtl->RedoRecPtr;
8202 
8203  if (RedoRecPtr < ptr)
8204  RedoRecPtr = ptr;
8205 
8206  return RedoRecPtr;
8207 }
slock_t info_lck
Definition: xlog.c:710
#define SpinLockAcquire(lock)
Definition: spin.h:62
static XLogRecPtr RedoRecPtr
Definition: xlog.c:365
XLogRecPtr RedoRecPtr
Definition: xlog.c:594
#define SpinLockRelease(lock)
Definition: spin.h:64
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:713

◆ GetSystemIdentifier()

uint64 GetSystemIdentifier ( void  )

Definition at line 4802 of file xlog.c.

References Assert, and ControlFileData::system_identifier.

Referenced by IdentifySystem(), and WalReceiverMain().

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

◆ GetXLogInsertRecPtr()

XLogRecPtr GetXLogInsertRecPtr ( void  )

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

11169 {
11171  uint64 current_bytepos;
11172 
11173  SpinLockAcquire(&Insert->insertpos_lck);
11174  current_bytepos = Insert->CurrBytePos;
11175  SpinLockRelease(&Insert->insertpos_lck);
11176 
11177  return XLogBytePosToRecPtr(current_bytepos);
11178 }
slock_t insertpos_lck
Definition: xlog.c:532
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1959
XLogCtlInsert Insert
Definition: xlog.c:590
#define SpinLockAcquire(lock)
Definition: spin.h:62
uint64 CurrBytePos
Definition: xlog.c:541
static void Insert(File file)
Definition: fd.c:1059
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:713

◆ GetXLogReceiptTime()

void GetXLogReceiptTime ( TimestampTz rtime,
bool fromStream 
)

Definition at line 6116 of file xlog.c.

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

Referenced by GetStandbyLimitTime().

6117 {
6118  /*
6119  * This must be executed in the startup process, since we don't export the
6120  * relevant state to shared memory.
6121  */
6122  Assert(InRecovery);
6123 
6124  *rtime = XLogReceiptTime;
6125  *fromStream = (XLogReceiptSource == XLOG_FROM_STREAM);
6126 }
static XLogSource XLogReceiptSource
Definition: xlog.c:822
bool InRecovery
Definition: xlog.c:200
static TimestampTz XLogReceiptTime
Definition: xlog.c:821
#define Assert(condition)
Definition: c.h:732

◆ GetXLogReplayRecPtr()

XLogRecPtr GetXLogReplayRecPtr ( TimeLineID replayTLI)

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

11150 {
11151  XLogRecPtr recptr;
11152  TimeLineID tli;
11153 
11155  recptr = XLogCtl->lastReplayedEndRecPtr;
11156  tli = XLogCtl->lastReplayedTLI;
11158 
11159  if (replayTLI)
11160  *replayTLI = tli;
11161  return recptr;
11162 }
uint32 TimeLineID
Definition: xlogdefs.h:52
slock_t info_lck
Definition: xlog.c:710
#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:713
TimeLineID lastReplayedTLI
Definition: xlog.c:690
XLogRecPtr lastReplayedEndRecPtr
Definition: xlog.c:689

◆ GetXLogWriteRecPtr()

XLogRecPtr GetXLogWriteRecPtr ( void  )

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

11185 {
11189 
11190  return LogwrtResult.Write;
11191 }
static XLogwrtResult LogwrtResult
Definition: xlog.c:757
slock_t info_lck
Definition: xlog.c:710
#define SpinLockAcquire(lock)
Definition: spin.h:62
XLogwrtResult LogwrtResult
Definition: xlog.c:613
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:713
XLogRecPtr Write
Definition: xlog.c:438

◆ HotStandbyActive()

bool HotStandbyActive ( void  )

Definition at line 7973 of file xlog.c.

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

Referenced by XLogWalRcvSendHSFeedback().

7974 {
7975  /*
7976  * We check shared state each time only until Hot Standby is active. We
7977  * can't de-activate Hot Standby, so there's no need to keep checking
7978  * after the shared variable has once been seen true.
7979  */
7981  return true;
7982  else
7983  {
7984  /* spinlock is essential on machines with weak memory ordering! */
7988 
7989  return LocalHotStandbyActive;
7990  }
7991 }
bool SharedHotStandbyActive
Definition: xlog.c:655
slock_t info_lck
Definition: xlog.c:710
#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:713

◆ HotStandbyActiveInReplay()

bool HotStandbyActiveInReplay ( void  )

Definition at line 7998 of file xlog.c.

References AmStartupProcess, Assert, IsPostmasterEnvironment, and LocalHotStandbyActive.

Referenced by btree_xlog_vacuum().

7999 {
8001  return LocalHotStandbyActive;
8002 }
#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 8164 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().

8165 {
8167 
8168  /* ThisTimeLineID doesn't change so we need no lock to copy it */
8171 
8172  /* set wal_segment_size */
8174 
8175  /* Use GetRedoRecPtr to copy the RedoRecPtr safely */
8176  (void) GetRedoRecPtr();
8177  /* Also update our copy of doPageWrites. */
8178  doPageWrites = (Insert->fullPageWrites || Insert->forcePageWrites);
8179 
8180  /* Also initialize the working areas for constructing WAL records */
8181  InitXLogInsert();
8182 }
int wal_segment_size
Definition: xlog.c:112
void InitXLogInsert(void)
Definition: xloginsert.c:1110
TimeLineID ThisTimeLineID
Definition: xlog.c:642
XLogCtlInsert Insert
Definition: xlog.c:590
bool fullPageWrites
Definition: xlog.c:565
uint32 xlog_seg_size
Definition: pg_control.h:209
static bool doPageWrites
Definition: xlog.c:372
bool forcePageWrites
Definition: xlog.c:564
static void Insert(File file)
Definition: fd.c:1059
static ControlFileData * ControlFile
Definition: xlog.c:721
TimeLineID ThisTimeLineID
Definition: xlog.c:187
#define Assert(condition)
Definition: c.h:732
static XLogCtlData * XLogCtl
Definition: xlog.c:713
XLogRecPtr GetRedoRecPtr(void)
Definition: xlog.c:8190
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:374

◆ issue_xlog_fsync()

void issue_xlog_fsync ( int  fd,
XLogSegNo  segno 
)

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

10105 {
10107  switch (sync_method)
10108  {
10109  case SYNC_METHOD_FSYNC:
10110  if (pg_fsync_no_writethrough(fd) != 0)
10111  ereport(PANIC,
10113  errmsg("could not fsync file \"%s\": %m",
10114  XLogFileNameP(ThisTimeLineID, segno))));
10115  break;
10116 #ifdef HAVE_FSYNC_WRITETHROUGH
10118  if (pg_fsync_writethrough(fd) != 0)
10119  ereport(PANIC,
10121  errmsg("could not fsync write-through file \"%s\": %m",
10122  XLogFileNameP(ThisTimeLineID, segno))));
10123  break;
10124 #endif
10125 #ifdef HAVE_FDATASYNC
10126  case SYNC_METHOD_FDATASYNC:
10127  if (pg_fdatasync(fd) != 0)
10128  ereport(PANIC,
10130  errmsg("could not fdatasync file \"%s\": %m",
10131  XLogFileNameP(ThisTimeLineID, segno))));
10132  break;
10133 #endif
10134  case SYNC_METHOD_OPEN:
10136  /* write synced it already */
10137  break;
10138  default:
10139  elog(PANIC, "unrecognized wal_sync_method: %d", sync_method);
10140  break;
10141  }
10143 }
int pg_fdatasync(int fd)
Definition: fd.c:383
#define SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:28
int pg_fsync_writethrough(int fd)
Definition: fd.c:360
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:348
#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:10149
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:1342
#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:1318
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 4922 of file xlog.c.

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

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

4923 {
4924  Assert(reset || ControlFile == NULL);
4925  ControlFile = palloc(sizeof(ControlFileData));
4926  ReadControlFile();
4927 }
static void ReadControlFile(void)
Definition: xlog.c:4577
static ControlFileData * ControlFile
Definition: xlog.c:721
#define Assert(condition)
Definition: c.h:732
void * palloc(Size size)
Definition: mcxt.c:949

◆ RecoveryInProgress()

bool RecoveryInProgress ( void  )

Definition at line 7917 of file xlog.c.

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

Referenced by BackgroundWriterMain(), brin_desummarize_range(), brin_summarize_range(), btree_index_mainfork_expected(), 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().

7918 {
7919  /*
7920  * We check shared state each time only until we leave recovery mode. We
7921  * can't re-enter recovery, so there's no need to keep checking after the
7922  * shared variable has once been seen false.
7923  */
7925  return false;
7926  else
7927  {
7928  /*
7929  * use volatile pointer to make sure we make a fresh read of the
7930  * shared variable.
7931  */
7932  volatile XLogCtlData *xlogctl = XLogCtl;
7933 
7935 
7936  /*
7937  * Initialize TimeLineID and RedoRecPtr when we discover that recovery
7938  * is finished. InitPostgres() relies upon this behaviour to ensure
7939  * that InitXLOGAccess() is called at backend startup. (If you change
7940  * this, see also LocalSetXLogInsertAllowed.)
7941  */
7943  {
7944  /*
7945  * If we just exited recovery, make sure we read TimeLineID and
7946  * RedoRecPtr after SharedRecoveryInProgress (for machines with
7947  * weak memory ordering).
7948  */
7950  InitXLOGAccess();
7951  }
7952 
7953  /*
7954  * Note: We don't need a memory barrier when we're still in recovery.
7955  * We might exit recovery immediately after return, so the caller
7956  * can't rely on 'true' meaning that we're still in recovery anyway.
7957  */
7958 
7959  return LocalRecoveryInProgress;
7960  }
7961 }
void InitXLOGAccess(void)
Definition: xlog.c:8164
bool SharedRecoveryInProgress
Definition: xlog.c:649
#define pg_memory_barrier()
Definition: atomics.h:145
static XLogCtlData * XLogCtl
Definition: xlog.c:713
static bool LocalRecoveryInProgress
Definition: xlog.c:223

◆ RecoveryIsPaused()

bool RecoveryIsPaused ( void  )

Definition at line 5932 of file xlog.c.

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

Referenced by pg_is_wal_replay_paused(), and recoveryPausesHere().

5933 {
5934  bool recoveryPause;
5935 
5937  recoveryPause = XLogCtl->recoveryPause;
5939 
5940  return recoveryPause;
5941 }
slock_t info_lck
Definition: xlog.c:710
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
bool recoveryPause
Definition: xlog.c:702
static XLogCtlData * XLogCtl
Definition: xlog.c:713

◆ RemovePromoteSignalFiles()

void RemovePromoteSignalFiles ( void  )

Definition at line 12229 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, and PROMOTE_SIGNAL_FILE.

Referenced by PostmasterMain().

12230 {
12231  unlink(PROMOTE_SIGNAL_FILE);
12233 }
#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 5944 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().

5945 {
5947  XLogCtl->recoveryPause = recoveryPause;
5949 }
slock_t info_lck
Definition: xlog.c:710
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
bool recoveryPause
Definition: xlog.c:702
static XLogCtlData * XLogCtl
Definition: xlog.c:713

◆ SetWalWriterSleeping()

void SetWalWriterSleeping ( bool  sleeping)

Definition at line 12265 of file xlog.c.

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

Referenced by WalWriterMain().

12266 {
12268  XLogCtl->WalWriterSleeping = sleeping;
12270 }
slock_t info_lck
Definition: xlog.c:710
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
bool WalWriterSleeping
Definition: xlog.c:662
static XLogCtlData * XLogCtl
Definition: xlog.c:713

◆ ShutdownXLOG()

void ShutdownXLOG ( int  code,
Datum  arg 
)

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

8314 {
8315  /*
8316  * We should have an aux process resource owner to use, and we should not
8317  * be in a transaction that's installed some other resowner.
8318  */
8320  Assert(CurrentResourceOwner == NULL ||
8323 
8324  /* Don't be chatty in standalone mode */
8326  (errmsg("shutting down")));
8327 
8328  /*
8329  * Signal walsenders to move to stopping state.
8330  */
8332 
8333  /*
8334  * Wait for WAL senders to be in stopping state. This prevents commands
8335  * from writing new WAL.
8336  */
8338 
8339  if (RecoveryInProgress())
8341  else
8342  {
8343  /*
8344  * If archiving is enabled, rotate the last XLOG file so that all the
8345  * remaining records are archived (postmaster wakes up the archiver
8346  * process one more time at the end of shutdown). The checkpoint
8347  * record will go to the next XLOG file and won't be archived (yet).
8348  */
8350  RequestXLogSwitch(false);
8351 
8353  }
8354  ShutdownCLOG();
8355  ShutdownCommitTs();
8356  ShutdownSUBTRANS();
8358 }
bool IsPostmasterEnvironment
Definition: globals.c:108
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9396
void ShutdownSUBTRANS(void)
Definition: subtrans.c:285
void CreateCheckPoint(int flags)
Definition: xlog.c:8529
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void ShutdownCLOG(void)
Definition: clog.c:823
bool CreateRestartPoint(int flags)
Definition: xlog.c:9069
#define XLogArchiveCommandSet()
Definition: xlog.h:175
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:7917
ResourceOwner AuxProcessResourceOwner
Definition: resowner.c:145
void WalSndWaitStopping(void)
Definition: walsender.c:3128
void ShutdownMultiXact(void)
Definition: multixact.c:2107
#define ereport(elevel, rest)
Definition: elog.h:141
#define NOTICE
Definition: elog.h:37
void WalSndInitStopping(void)
Definition: walsender.c:3102
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 6201 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, 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, XLogReaderState::seg, 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(), WALOpenSegment::ws_tli, 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, XLOGDIR, 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().

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