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)
 
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 359 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 366 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 356 of file xlog.h.

Referenced by exitArchiveRecovery(), and readRecoverySignalFile().

◆ STANDBY_SIGNAL_FILE

#define STANDBY_SIGNAL_FILE   "standby.signal"

Definition at line 357 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 362 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 339 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:149

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

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

◆ CheckPromoteSignal()

bool CheckPromoteSignal ( void  )

Definition at line 12263 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, PROMOTE_SIGNAL_FILE, and stat.

Referenced by sigusr1_handler().

12264 {
12265  struct stat stat_buf;
12266 
12267  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
12269  return true;
12270 
12271  return false;
12272 }
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:365
struct stat stat_buf
Definition: pg_standby.c:100
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.h:366
#define stat(a, b)
Definition: win32_port.h:255

◆ CheckXLogRemoved()

void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)

Definition at line 3860 of file xlog.c.

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

Referenced by logical_read_xlog_page(), perform_base_backup(), and XLogSendPhysical().

3861 {
3862  int save_errno = errno;
3863  XLogSegNo lastRemovedSegNo;
3864 
3866  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3868 
3869  if (segno <= lastRemovedSegNo)
3870  {
3871  char filename[MAXFNAMELEN];
3872 
3873  XLogFileName(filename, tli, segno, wal_segment_size);
3874  errno = save_errno;
3875  ereport(ERROR,
3877  errmsg("requested WAL segment %s has already been removed",
3878  filename)));
3879  }
3880  errno = save_errno;
3881 }
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:631
#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:90
int errmsg(const char *fmt,...)
Definition: elog.c:822

◆ CreateCheckPoint()

void CreateCheckPoint ( int  flags)

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

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

9088 {
9089  XLogRecPtr lastCheckPointRecPtr;
9090  XLogRecPtr lastCheckPointEndPtr;
9091  CheckPoint lastCheckPoint;
9092  XLogRecPtr PriorRedoPtr;
9093  XLogRecPtr receivePtr;
9094  XLogRecPtr replayPtr;
9095  TimeLineID replayTLI;
9096  XLogRecPtr endptr;
9097  XLogSegNo _logSegNo;
9098  TimestampTz xtime;
9099 
9100  /*
9101  * Acquire CheckpointLock to ensure only one restartpoint or checkpoint
9102  * happens at a time.
9103  */
9104  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
9105 
9106  /* Get a local copy of the last safe checkpoint record. */
9108  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
9109  lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
9110  lastCheckPoint = XLogCtl->lastCheckPoint;
9112 
9113  /*
9114  * Check that we're still in recovery mode. It's ok if we exit recovery
9115  * mode after this check, the restart point is valid anyway.
9116  */
9117  if (!RecoveryInProgress())
9118  {
9119  ereport(DEBUG2,
9120  (errmsg("skipping restartpoint, recovery has already ended")));
9121  LWLockRelease(CheckpointLock);
9122  return false;
9123  }
9124 
9125  /*
9126  * If the last checkpoint record we've replayed is already our last
9127  * restartpoint, we can't perform a new restart point. We still update
9128  * minRecoveryPoint in that case, so that if this is a shutdown restart
9129  * point, we won't start up earlier than before. That's not strictly
9130  * necessary, but when hot standby is enabled, it would be rather weird if
9131  * the database opened up for read-only connections at a point-in-time
9132  * before the last shutdown. Such time travel is still possible in case of
9133  * immediate shutdown, though.
9134  *
9135  * We don't explicitly advance minRecoveryPoint when we do create a
9136  * restartpoint. It's assumed that flushing the buffers will do that as a
9137  * side-effect.
9138  */
9139  if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
9140  lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
9141  {
9142  ereport(DEBUG2,
9143  (errmsg("skipping restartpoint, already performed at %X/%X",
9144  (uint32) (lastCheckPoint.redo >> 32),
9145  (uint32) lastCheckPoint.redo)));
9146 
9148  if (flags & CHECKPOINT_IS_SHUTDOWN)
9149  {
9150  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9152  ControlFile->time = (pg_time_t) time(NULL);
9154  LWLockRelease(ControlFileLock);
9155  }
9156  LWLockRelease(CheckpointLock);
9157  return false;
9158  }
9159 
9160  /*
9161  * Update the shared RedoRecPtr so that the startup process can calculate
9162  * the number of segments replayed since last restartpoint, and request a
9163  * restartpoint if it exceeds CheckPointSegments.
9164  *
9165  * Like in CreateCheckPoint(), hold off insertions to update it, although
9166  * during recovery this is just pro forma, because no WAL insertions are
9167  * happening.
9168  */
9170  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
9172 
9173  /* Also update the info_lck-protected copy */
9175  XLogCtl->RedoRecPtr = lastCheckPoint.redo;
9177 
9178  /*
9179  * Prepare to accumulate statistics.
9180  *
9181  * Note: because it is possible for log_checkpoints to change while a
9182  * checkpoint proceeds, we always accumulate stats, even if
9183  * log_checkpoints is currently off.
9184  */
9185  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
9187 
9188  if (log_checkpoints)
9189  LogCheckpointStart(flags, true);
9190 
9191  CheckPointGuts(lastCheckPoint.redo, flags);
9192 
9193  /*
9194  * Remember the prior checkpoint's redo ptr for
9195  * UpdateCheckPointDistanceEstimate()
9196  */
9197  PriorRedoPtr = ControlFile->checkPointCopy.redo;
9198 
9199  /*
9200  * Update pg_control, using current time. Check that it still shows
9201  * DB_IN_ARCHIVE_RECOVERY state and an older checkpoint, else do nothing;
9202  * this is a quick hack to make sure nothing really bad happens if somehow
9203  * we get here after the end-of-recovery checkpoint.
9204  */
9205  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9207  ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
9208  {
9209  ControlFile->checkPoint = lastCheckPointRecPtr;
9210  ControlFile->checkPointCopy = lastCheckPoint;
9211  ControlFile->time = (pg_time_t) time(NULL);
9212 
9213  /*
9214  * Ensure minRecoveryPoint is past the checkpoint record. Normally,
9215  * this will have happened already while writing out dirty buffers,
9216  * but not necessarily - e.g. because no buffers were dirtied. We do
9217  * this because a non-exclusive base backup uses minRecoveryPoint to
9218  * determine which WAL files must be included in the backup, and the
9219  * file (or files) containing the checkpoint record must be included,
9220  * at a minimum. Note that for an ordinary restart of recovery there's
9221  * no value in having the minimum recovery point any earlier than this
9222  * anyway, because redo will begin just after the checkpoint record.
9223  */
9224  if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
9225  {
9226  ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
9228 
9229  /* update local copy */
9232  }
9233  if (flags & CHECKPOINT_IS_SHUTDOWN)
9236  }
9237  LWLockRelease(ControlFileLock);
9238 
9239  /*
9240  * Update the average distance between checkpoints/restartpoints if the
9241  * prior checkpoint exists.
9242  */
9243  if (PriorRedoPtr != InvalidXLogRecPtr)
9245 
9246  /*
9247  * Delete old log files, those no longer needed for last restartpoint to
9248  * prevent the disk holding the xlog from growing full.
9249  */
9251 
9252  /*
9253  * Retreat _logSegNo using the current end of xlog replayed or received,
9254  * whichever is later.
9255  */
9256  receivePtr = GetWalRcvWriteRecPtr(NULL, NULL);
9257  replayPtr = GetXLogReplayRecPtr(&replayTLI);
9258  endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
9259  KeepLogSeg(endptr, &_logSegNo);
9260  _logSegNo--;
9261 
9262  /*
9263  * Try to recycle segments on a useful timeline. If we've been promoted
9264  * since the beginning of this restartpoint, use the new timeline chosen
9265  * at end of recovery (RecoveryInProgress() sets ThisTimeLineID in that
9266  * case). If we're still in recovery, use the timeline we're currently
9267  * replaying.
9268  *
9269  * There is no guarantee that the WAL segments will be useful on the
9270  * current timeline; if recovery proceeds to a new timeline right after
9271  * this, the pre-allocated WAL segments on this timeline will not be used,
9272  * and will go wasted until recycled on the next restartpoint. We'll live
9273  * with that.
9274  */
9275  if (RecoveryInProgress())
9276  ThisTimeLineID = replayTLI;
9277 
9278  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr);
9279 
9280  /*
9281  * Make more log segments if needed. (Do this after recycling old log
9282  * segments, since that may supply some of the needed files.)
9283  */
9284  PreallocXlogFiles(endptr);
9285 
9286  /*
9287  * ThisTimeLineID is normally not set when we're still in recovery.
9288  * However, recycling/preallocating segments above needed ThisTimeLineID
9289  * to determine which timeline to install the segments on. Reset it now,
9290  * to restore the normal state of affairs for debugging purposes.
9291  */
9292  if (RecoveryInProgress())
9293  ThisTimeLineID = 0;
9294 
9295  /*
9296  * Truncate pg_subtrans if possible. We can throw away all data before
9297  * the oldest XMIN of any running transaction. No future transaction will
9298  * attempt to reference any pg_subtrans entry older than that (see Asserts
9299  * in subtrans.c). When hot standby is disabled, though, we mustn't do
9300  * this because StartupSUBTRANS hasn't been called yet.
9301  */
9302  if (EnableHotStandby)
9304 
9305  /* Real work is done, but log and update before releasing lock. */
9306  LogCheckpointEnd(true);
9307 
9308  xtime = GetLatestXTime();
9310  (errmsg("recovery restart point at %X/%X",
9311  (uint32) (lastCheckPoint.redo >> 32), (uint32) lastCheckPoint.redo),
9312  xtime ? errdetail("Last completed transaction was at log time %s.",
9313  timestamptz_to_str(xtime)) : 0));
9314 
9315  LWLockRelease(CheckpointLock);
9316 
9317  /*
9318  * Finally, execute archive_cleanup_command, if any.
9319  */
9320  if (archiveCleanupCommand && strcmp(archiveCleanupCommand, "") != 0)
9322  "archive_cleanup_command",
9323  false);
9324 
9325  return true;
9326 }
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8485
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:2718
TimestampTz ckpt_start_t
Definition: xlog.h:235
slock_t info_lck
Definition: xlog.c:710
#define MemSet(start, val, len)
Definition: c.h:962
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:9017
TimestampTz GetLatestXTime(void)
Definition: xlog.c:6074
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:7935
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:4790
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8400
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
Definition: xlog.c:11172
#define DEBUG2
Definition: elog.h:24
static XLogRecPtr RedoRecPtr
Definition: xlog.c:365
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3827
uint64 XLogSegNo
Definition: xlogdefs.h:41
int errdetail(const char *fmt,...)
Definition: elog.c:955
unsigned int uint32
Definition: c.h:359
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:9337
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:3957
TransactionId GetOldestXmin(Relation rel, int flags)
Definition: procarray.c:1306
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:822
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:8382
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 4819 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().

4820 {
4821  Assert(ControlFile != NULL);
4822  return (ControlFile->data_checksum_version > 0);
4823 }
uint32 data_checksum_version
Definition: pg_control.h:220
static ControlFileData * ControlFile
Definition: xlog.c:721
#define Assert(condition)
Definition: c.h:739

◆ do_pg_abort_backup()

void do_pg_abort_backup ( void  )

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

11145 {
11146  /*
11147  * Quick exit if session is not keeping around a non-exclusive backup
11148  * already started.
11149  */
11151  return;
11152 
11157 
11160  {
11161  XLogCtl->Insert.forcePageWrites = false;
11162  }
11164 }
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:739
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 10220 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().

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

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

References sessionBackupState.

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

10719 {
10720  return sessionBackupState;
10721 }
static SessionBackupState sessionBackupState
Definition: xlog.c:525

◆ GetCurrentChunkReplayStartTime()

TimestampTz GetCurrentChunkReplayStartTime ( void  )

Definition at line 6104 of file xlog.c.

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

Referenced by GetReplicationApplyDelay().

6105 {
6106  TimestampTz xtime;
6107 
6109  xtime = XLogCtl->currentChunkStartTime;
6111 
6112  return xtime;
6113 }
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 4835 of file xlog.c.

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

Referenced by gistGetFakeLSN().

4836 {
4837  XLogRecPtr nextUnloggedLSN;
4838 
4839  /* increment the unloggedLSN counter, need SpinLock */
4841  nextUnloggedLSN = XLogCtl->unloggedLSN++;
4843 
4844  return nextUnloggedLSN;
4845 }
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 8267 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().

8268 {
8272 
8273  return LogwrtResult.Flush;
8274 }
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 8236 of file xlog.c.

References doPageWrites, and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

8237 {
8238  *RedoRecPtr_p = RedoRecPtr;
8239  *doPageWrites_p = doPageWrites;
8240 }
static bool doPageWrites
Definition: xlog.c:372
static XLogRecPtr RedoRecPtr
Definition: xlog.c:365

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )

Definition at line 8251 of file xlog.c.

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

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

8252 {
8253  XLogRecPtr recptr;
8254 
8256  recptr = XLogCtl->LogwrtRqst.Write;
8258 
8259  return recptr;
8260 }
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 8285 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().

8286 {
8288  int i;
8289 
8290  for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
8291  {
8292  XLogRecPtr last_important;
8293 
8294  /*
8295  * Need to take a lock to prevent torn reads of the LSN, which are
8296  * possible on some of the supported platforms. WAL insert locks only
8297  * support exclusive mode, so we have to use that.
8298  */
8300  last_important = WALInsertLocks[i].l.lastImportantAt;
8301  LWLockRelease(&WALInsertLocks[i].l.lock);
8302 
8303  if (res < last_important)
8304  res = last_important;
8305  }
8306 
8307  return res;
8308 }
#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 6074 of file xlog.c.

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

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

6075 {
6076  TimestampTz xtime;
6077 
6079  xtime = XLogCtl->recoveryLastXTime;
6081 
6082  return xtime;
6083 }
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 4809 of file xlog.c.

References Assert, and ControlFileData::mock_authentication_nonce.

Referenced by scram_mock_salt().

4810 {
4811  Assert(ControlFile != NULL);
4813 }
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition: pg_control.h:227
static ControlFileData * ControlFile
Definition: xlog.c:721
#define Assert(condition)
Definition: c.h:739

◆ GetRedoRecPtr()

XLogRecPtr GetRedoRecPtr ( void  )

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

8209 {
8210  XLogRecPtr ptr;
8211 
8212  /*
8213  * The possibly not up-to-date copy in XlogCtl is enough. Even if we
8214  * grabbed a WAL insertion lock to read the master copy, someone might
8215  * update it just after we've released the lock.
8216  */
8218  ptr = XLogCtl->RedoRecPtr;
8220 
8221  if (RedoRecPtr < ptr)
8222  RedoRecPtr = ptr;
8223 
8224  return RedoRecPtr;
8225 }
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 4799 of file xlog.c.

References Assert, and ControlFileData::system_identifier.

Referenced by IdentifySystem(), and WalReceiverMain().

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

◆ GetXLogInsertRecPtr()

XLogRecPtr GetXLogInsertRecPtr ( void  )

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

11192 {
11194  uint64 current_bytepos;
11195 
11196  SpinLockAcquire(&Insert->insertpos_lck);
11197  current_bytepos = Insert->CurrBytePos;
11198  SpinLockRelease(&Insert->insertpos_lck);
11199 
11200  return XLogBytePosToRecPtr(current_bytepos);
11201 }
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:1096
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:713

◆ GetXLogReceiptTime()

void GetXLogReceiptTime ( TimestampTz rtime,
bool fromStream 
)

Definition at line 6120 of file xlog.c.

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

Referenced by GetStandbyLimitTime().

6121 {
6122  /*
6123  * This must be executed in the startup process, since we don't export the
6124  * relevant state to shared memory.
6125  */
6126  Assert(InRecovery);
6127 
6128  *rtime = XLogReceiptTime;
6129  *fromStream = (XLogReceiptSource == XLOG_FROM_STREAM);
6130 }
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:739

◆ GetXLogReplayRecPtr()

XLogRecPtr GetXLogReplayRecPtr ( TimeLineID replayTLI)

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

11173 {
11174  XLogRecPtr recptr;
11175  TimeLineID tli;
11176 
11178  recptr = XLogCtl->lastReplayedEndRecPtr;
11179  tli = XLogCtl->lastReplayedTLI;
11181 
11182  if (replayTLI)
11183  *replayTLI = tli;
11184  return recptr;
11185 }
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 11207 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().

11208 {
11212 
11213  return LogwrtResult.Write;
11214 }
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 7991 of file xlog.c.

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

Referenced by XLogWalRcvSendHSFeedback().

7992 {
7993  /*
7994  * We check shared state each time only until Hot Standby is active. We
7995  * can't de-activate Hot Standby, so there's no need to keep checking
7996  * after the shared variable has once been seen true.
7997  */
7999  return true;
8000  else
8001  {
8002  /* spinlock is essential on machines with weak memory ordering! */
8006 
8007  return LocalHotStandbyActive;
8008  }
8009 }
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 8016 of file xlog.c.

References AmStartupProcess, Assert, IsPostmasterEnvironment, and LocalHotStandbyActive.

Referenced by btree_xlog_vacuum().

8017 {
8019  return LocalHotStandbyActive;
8020 }
#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:739

◆ InitXLOGAccess()

void InitXLOGAccess ( void  )

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

8183 {
8185 
8186  /* ThisTimeLineID doesn't change so we need no lock to copy it */
8189 
8190  /* set wal_segment_size */
8192 
8193  /* Use GetRedoRecPtr to copy the RedoRecPtr safely */
8194  (void) GetRedoRecPtr();
8195  /* Also update our copy of doPageWrites. */
8196  doPageWrites = (Insert->fullPageWrites || Insert->forcePageWrites);
8197 
8198  /* Also initialize the working areas for constructing WAL records */
8199  InitXLogInsert();
8200 }
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:1096
static ControlFileData * ControlFile
Definition: xlog.c:721
TimeLineID ThisTimeLineID
Definition: xlog.c:187
#define Assert(condition)
Definition: c.h:739
static XLogCtlData * XLogCtl
Definition: xlog.c:713
XLogRecPtr GetRedoRecPtr(void)
Definition: xlog.c:8208
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:374

◆ issue_xlog_fsync()

void issue_xlog_fsync ( int  fd,
XLogSegNo  segno 
)

Definition at line 10131 of file xlog.c.

References _, elog, ereport, errcode_for_file_access(), errmsg(), MAXFNAMELEN, PANIC, pg_fdatasync(), pg_fsync_no_writethrough(), pg_fsync_writethrough(), pgstat_report_wait_end(), pgstat_report_wait_start(), sync_method, SYNC_METHOD_FDATASYNC, SYNC_METHOD_FSYNC, SYNC_METHOD_FSYNC_WRITETHROUGH, SYNC_METHOD_OPEN, SYNC_METHOD_OPEN_DSYNC, ThisTimeLineID, WAIT_EVENT_WAL_SYNC, wal_segment_size, and XLogFileName.

Referenced by XLogWalRcvFlush(), and XLogWrite().

10132 {
10133  char *msg = NULL;
10134 
10136  switch (sync_method)
10137  {
10138  case SYNC_METHOD_FSYNC:
10139  if (pg_fsync_no_writethrough(fd) != 0)
10140  msg = _("could not fsync file \"%s\": %m");
10141  break;
10142 #ifdef HAVE_FSYNC_WRITETHROUGH
10144  if (pg_fsync_writethrough(fd) != 0)
10145  msg = _("could not fsync write-through file \"%s\": %m");
10146  break;
10147 #endif
10148 #ifdef HAVE_FDATASYNC
10149  case SYNC_METHOD_FDATASYNC:
10150  if (pg_fdatasync(fd) != 0)
10151  msg = _("could not fdatasync file \"%s\": %m");
10152  break;
10153 #endif
10154  case SYNC_METHOD_OPEN:
10156  /* write synced it already */
10157  break;
10158  default:
10159  elog(PANIC, "unrecognized wal_sync_method: %d", sync_method);
10160  break;
10161  }
10162 
10163  /* PANIC if failed to fsync */
10164  if (msg)
10165  {
10166  char xlogfname[MAXFNAMELEN];
10167  int save_errno = errno;
10168 
10169  XLogFileName(xlogfname, ThisTimeLineID, segno,
10171  errno = save_errno;
10172  ereport(PANIC,
10174  errmsg(msg, xlogfname)));
10175  }
10176 
10178 }
int pg_fdatasync(int fd)
Definition: fd.c:420
int wal_segment_size
Definition: xlog.c:112
#define SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:28
int pg_fsync_writethrough(int fd)
Definition: fd.c:397
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:385
#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
int errcode_for_file_access(void)
Definition: elog.c:631
#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
#define MAXFNAMELEN
TimeLineID ThisTimeLineID
Definition: xlog.c:187
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
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:822
#define elog(elevel,...)
Definition: elog.h:228
#define _(x)
Definition: elog.c:87

◆ LocalProcessControlFile()

void LocalProcessControlFile ( bool  reset)

Definition at line 4919 of file xlog.c.

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

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

4920 {
4921  Assert(reset || ControlFile == NULL);
4922  ControlFile = palloc(sizeof(ControlFileData));
4923  ReadControlFile();
4924 }
static void ReadControlFile(void)
Definition: xlog.c:4590
static ControlFileData * ControlFile
Definition: xlog.c:721
#define Assert(condition)
Definition: c.h:739
void * palloc(Size size)
Definition: mcxt.c:949

◆ RecoveryInProgress()

bool RecoveryInProgress ( void  )

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

7936 {
7937  /*
7938  * We check shared state each time only until we leave recovery mode. We
7939  * can't re-enter recovery, so there's no need to keep checking after the
7940  * shared variable has once been seen false.
7941  */
7943  return false;
7944  else
7945  {
7946  /*
7947  * use volatile pointer to make sure we make a fresh read of the
7948  * shared variable.
7949  */
7950  volatile XLogCtlData *xlogctl = XLogCtl;
7951 
7953 
7954  /*
7955  * Initialize TimeLineID and RedoRecPtr when we discover that recovery
7956  * is finished. InitPostgres() relies upon this behaviour to ensure
7957  * that InitXLOGAccess() is called at backend startup. (If you change
7958  * this, see also LocalSetXLogInsertAllowed.)
7959  */
7961  {
7962  /*
7963  * If we just exited recovery, make sure we read TimeLineID and
7964  * RedoRecPtr after SharedRecoveryInProgress (for machines with
7965  * weak memory ordering).
7966  */
7968  InitXLOGAccess();
7969  }
7970 
7971  /*
7972  * Note: We don't need a memory barrier when we're still in recovery.
7973  * We might exit recovery immediately after return, so the caller
7974  * can't rely on 'true' meaning that we're still in recovery anyway.
7975  */
7976 
7977  return LocalRecoveryInProgress;
7978  }
7979 }
void InitXLOGAccess(void)
Definition: xlog.c:8182
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 5936 of file xlog.c.

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

Referenced by pg_is_wal_replay_paused(), and recoveryPausesHere().

5937 {
5938  bool recoveryPause;
5939 
5941  recoveryPause = XLogCtl->recoveryPause;
5943 
5944  return recoveryPause;
5945 }
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 12252 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, and PROMOTE_SIGNAL_FILE.

Referenced by PostmasterMain().

12253 {
12254  unlink(PROMOTE_SIGNAL_FILE);
12256 }
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:365
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.h:366

◆ SetRecoveryPause()

void SetRecoveryPause ( bool  recoveryPause)

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

5949 {
5951  XLogCtl->recoveryPause = recoveryPause;
5953 }
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 12288 of file xlog.c.

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

Referenced by WalWriterMain().

12289 {
12291  XLogCtl->WalWriterSleeping = sleeping;
12293 }
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 8331 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().

8332 {
8333  /*
8334  * We should have an aux process resource owner to use, and we should not
8335  * be in a transaction that's installed some other resowner.
8336  */
8338  Assert(CurrentResourceOwner == NULL ||
8341 
8342  /* Don't be chatty in standalone mode */
8344  (errmsg("shutting down")));
8345 
8346  /*
8347  * Signal walsenders to move to stopping state.
8348  */
8350 
8351  /*
8352  * Wait for WAL senders to be in stopping state. This prevents commands
8353  * from writing new WAL.
8354  */
8356 
8357  if (RecoveryInProgress())
8359  else
8360  {
8361  /*
8362  * If archiving is enabled, rotate the last XLOG file so that all the
8363  * remaining records are archived (postmaster wakes up the archiver
8364  * process one more time at the end of shutdown). The checkpoint
8365  * record will go to the next XLOG file and won't be archived (yet).
8366  */
8368  RequestXLogSwitch(false);
8369 
8371  }
8372  ShutdownCLOG();
8373  ShutdownCommitTs();
8374  ShutdownSUBTRANS();
8376 }
bool IsPostmasterEnvironment
Definition: globals.c:108
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9414
void ShutdownSUBTRANS(void)
Definition: subtrans.c:285
void CreateCheckPoint(int flags)
Definition: xlog.c:8547
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void ShutdownCLOG(void)
Definition: clog.c:823
bool CreateRestartPoint(int flags)
Definition: xlog.c:9087
#define XLogArchiveCommandSet()
Definition: xlog.h:175
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:7935
ResourceOwner AuxProcessResourceOwner
Definition: resowner.c:145
void WalSndWaitStopping(void)
Definition: walsender.c:3088
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:3062
void ShutdownCommitTs(void)
Definition: commit_ts.c:744
#define Assert(condition)
Definition: c.h:739
#define XLogArchivingActive()
Definition: xlog.h:170
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:214
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:211

◆ StartupXLOG()

void StartupXLOG ( void  )

Definition at line 6205 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(), FirstNormalUnloggedLSN, 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().

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