PostgreSQL Source Code  git master
xlog.h File Reference
#include "access/rmgr.h"
#include "access/xlogdefs.h"
#include "access/xloginsert.h"
#include "access/xlogreader.h"
#include "datatype/timestamp.h"
#include "lib/stringinfo.h"
#include "nodes/pg_list.h"
#include "storage/fd.h"
Include dependency graph for xlog.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  CheckpointStatsData
 

Macros

#define SYNC_METHOD_FSYNC   0
 
#define SYNC_METHOD_FDATASYNC   1
 
#define SYNC_METHOD_OPEN   2 /* for O_SYNC */
 
#define SYNC_METHOD_FSYNC_WRITETHROUGH   3
 
#define SYNC_METHOD_OPEN_DSYNC   4 /* for O_DSYNC */
 
#define InHotStandby   (standbyState >= STANDBY_SNAPSHOT_PENDING)
 
#define XLogArchivingActive()   (AssertMacro(XLogArchiveMode == ARCHIVE_MODE_OFF || wal_level >= WAL_LEVEL_REPLICA), XLogArchiveMode > ARCHIVE_MODE_OFF)
 
#define XLogArchivingAlways()   (AssertMacro(XLogArchiveMode == ARCHIVE_MODE_OFF || wal_level >= WAL_LEVEL_REPLICA), XLogArchiveMode == ARCHIVE_MODE_ALWAYS)
 
#define XLogArchiveCommandSet()   (XLogArchiveCommand[0] != '\0')
 
#define XLogIsNeeded()   (wal_level >= WAL_LEVEL_REPLICA)
 
#define XLogHintBitIsNeeded()   (DataChecksumsEnabled() || wal_log_hints)
 
#define XLogStandbyInfoActive()   (wal_level >= WAL_LEVEL_REPLICA)
 
#define XLogLogicalInfoActive()   (wal_level >= WAL_LEVEL_LOGICAL)
 
#define CHECKPOINT_IS_SHUTDOWN   0x0001 /* Checkpoint is for shutdown */
 
#define CHECKPOINT_END_OF_RECOVERY
 
#define CHECKPOINT_IMMEDIATE   0x0004 /* Do it without delays */
 
#define CHECKPOINT_FORCE   0x0008 /* Force even if no activity */
 
#define CHECKPOINT_FLUSH_ALL
 
#define CHECKPOINT_WAIT   0x0020 /* Wait for completion */
 
#define CHECKPOINT_CAUSE_XLOG   0x0040 /* XLOG consumption */
 
#define CHECKPOINT_CAUSE_TIME   0x0080 /* Elapsed time */
 
#define XLOG_INCLUDE_ORIGIN   0x01 /* include the replication origin */
 
#define XLOG_MARK_UNIMPORTANT   0x02 /* record not important for durability */
 
#define BACKUP_LABEL_FILE   "backup_label"
 
#define BACKUP_LABEL_OLD   "backup_label.old"
 
#define TABLESPACE_MAP   "tablespace_map"
 
#define TABLESPACE_MAP_OLD   "tablespace_map.old"
 

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  ArchiveMode { ARCHIVE_MODE_OFF = 0, ARCHIVE_MODE_ON, ARCHIVE_MODE_ALWAYS }
 
enum  WalLevel { WAL_LEVEL_MINIMAL = 0, WAL_LEVEL_REPLICA, WAL_LEVEL_LOGICAL }
 
enum  SessionBackupState { SESSION_BACKUP_NONE, SESSION_BACKUP_EXCLUSIVE, SESSION_BACKUP_NON_EXCLUSIVE }
 

Functions

XLogRecPtr XLogInsertRecord (struct XLogRecData *rdata, XLogRecPtr fpw_lsn, uint8 flags)
 
void XLogFlush (XLogRecPtr RecPtr)
 
bool XLogBackgroundFlush (void)
 
bool XLogNeedsFlush (XLogRecPtr RecPtr)
 
int XLogFileInit (XLogSegNo segno, bool *use_existent, bool use_lock)
 
int XLogFileOpen (XLogSegNo segno)
 
void CheckXLogRemoved (XLogSegNo segno, TimeLineID tli)
 
XLogSegNo XLogGetLastRemovedSegno (void)
 
void XLogSetAsyncXactLSN (XLogRecPtr record)
 
void XLogSetReplicationSlotMinimumLSN (XLogRecPtr lsn)
 
void xlog_redo (XLogReaderState *record)
 
void xlog_desc (StringInfo buf, XLogReaderState *record)
 
const char * xlog_identify (uint8 info)
 
void issue_xlog_fsync (int fd, XLogSegNo segno)
 
bool RecoveryInProgress (void)
 
bool HotStandbyActive (void)
 
bool HotStandbyActiveInReplay (void)
 
bool XLogInsertAllowed (void)
 
void GetXLogReceiptTime (TimestampTz *rtime, bool *fromStream)
 
XLogRecPtr GetXLogReplayRecPtr (TimeLineID *replayTLI)
 
XLogRecPtr GetXLogInsertRecPtr (void)
 
XLogRecPtr GetXLogWriteRecPtr (void)
 
bool RecoveryIsPaused (void)
 
void SetRecoveryPause (bool recoveryPause)
 
TimestampTz GetLatestXTime (void)
 
TimestampTz GetCurrentChunkReplayStartTime (void)
 
char * XLogFileNameP (TimeLineID tli, XLogSegNo segno)
 
void UpdateControlFile (void)
 
uint64 GetSystemIdentifier (void)
 
char * GetMockAuthenticationNonce (void)
 
bool DataChecksumsEnabled (void)
 
XLogRecPtr GetFakeLSNForUnloggedRel (void)
 
Size XLOGShmemSize (void)
 
void XLOGShmemInit (void)
 
void BootStrapXLOG (void)
 
void LocalProcessControlFile (bool reset)
 
void StartupXLOG (void)
 
void ShutdownXLOG (int code, Datum arg)
 
void InitXLOGAccess (void)
 
void CreateCheckPoint (int flags)
 
bool CreateRestartPoint (int flags)
 
void XLogPutNextOid (Oid nextOid)
 
XLogRecPtr XLogRestorePoint (const char *rpName)
 
void UpdateFullPageWrites (void)
 
void GetFullPageWriteInfo (XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p)
 
XLogRecPtr GetRedoRecPtr (void)
 
XLogRecPtr GetInsertRecPtr (void)
 
XLogRecPtr GetFlushRecPtr (void)
 
XLogRecPtr GetLastImportantRecPtr (void)
 
void GetNextXidAndEpoch (TransactionId *xid, uint32 *epoch)
 
void RemovePromoteSignalFiles (void)
 
bool CheckPromoteSignal (void)
 
void WakeupRecovery (void)
 
void SetWalWriterSleeping (bool sleeping)
 
void XLogRequestWalReceiverReply (void)
 
void assign_max_wal_size (int newval, void *extra)
 
void assign_checkpoint_completion_target (double newval, void *extra)
 
XLogRecPtr do_pg_start_backup (const char *backupidstr, bool fast, TimeLineID *starttli_p, StringInfo labelfile, List **tablespaces, StringInfo tblspcmapfile, bool infotbssize, bool needtblspcmapfile)
 
XLogRecPtr do_pg_stop_backup (char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 
void do_pg_abort_backup (void)
 
SessionBackupState get_backup_status (void)
 

Variables

int sync_method
 
PGDLLIMPORT TimeLineID ThisTimeLineID
 
bool InRecovery
 
HotStandbyState standbyState
 
XLogRecPtr ProcLastRecPtr
 
XLogRecPtr XactLastRecEnd
 
PGDLLIMPORT XLogRecPtr XactLastCommitEnd
 
bool reachedConsistency
 
int wal_segment_size
 
int min_wal_size_mb
 
int max_wal_size_mb
 
int wal_keep_segments
 
int XLOGbuffers
 
int XLogArchiveTimeout
 
int wal_retrieve_retry_interval
 
char * XLogArchiveCommand
 
bool EnableHotStandby
 
bool fullPageWrites
 
bool wal_log_hints
 
bool wal_compression
 
boolwal_consistency_checking
 
char * wal_consistency_checking_string
 
bool log_checkpoints
 
int CheckPointSegments
 
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 323 of file xlog.h.

Referenced by CancelBackup(), and StartupXLOG().

◆ CHECKPOINT_CAUSE_TIME

#define CHECKPOINT_CAUSE_TIME   0x0080 /* Elapsed time */

Definition at line 187 of file xlog.h.

Referenced by CheckpointerMain(), and LogCheckpointStart().

◆ CHECKPOINT_CAUSE_XLOG

#define CHECKPOINT_CAUSE_XLOG   0x0040 /* XLOG consumption */

Definition at line 186 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 177 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 181 of file xlog.h.

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

◆ CHECKPOINT_FORCE

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

◆ CHECKPOINT_IMMEDIATE

◆ CHECKPOINT_IS_SHUTDOWN

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

◆ CHECKPOINT_WAIT

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

◆ InHotStandby

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

Referenced by pgarch_ArchiverCopyLoop(), and ShutdownXLOG().

◆ XLogArchivingActive

◆ XLogArchivingAlways

Definition at line 138 of file xlog.h.

Referenced by do_pg_stop_backup(), and sigusr1_handler().

◆ XLogHintBitIsNeeded

◆ XLogIsNeeded

◆ XLogLogicalInfoActive

#define XLogLogicalInfoActive ( )    (wal_level >= WAL_LEVEL_LOGICAL)

Definition at line 163 of file xlog.h.

Referenced by AssignTransactionId(), and XactLogCommitRecord().

◆ XLogStandbyInfoActive

Typedef Documentation

◆ ArchiveMode

◆ CheckpointStatsData

◆ SessionBackupState

◆ WalLevel

Enumeration Type Documentation

◆ ArchiveMode

Enumerator
ARCHIVE_MODE_OFF 
ARCHIVE_MODE_ON 
ARCHIVE_MODE_ALWAYS 

Definition at line 116 of file xlog.h.

117 {
118  ARCHIVE_MODE_OFF = 0, /* disabled */
119  ARCHIVE_MODE_ON, /* enabled while server is running normally */
120  ARCHIVE_MODE_ALWAYS /* enabled always (even during recovery) */
121 } ArchiveMode;
ArchiveMode
Definition: xlog.h:116

◆ HotStandbyState

Enumerator
STANDBY_DISABLED 
STANDBY_INITIALIZED 
STANDBY_SNAPSHOT_PENDING 
STANDBY_SNAPSHOT_READY 

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

◆ WalLevel

enum WalLevel
Enumerator
WAL_LEVEL_MINIMAL 
WAL_LEVEL_REPLICA 
WAL_LEVEL_LOGICAL 

Definition at line 125 of file xlog.h.

Function Documentation

◆ assign_checkpoint_completion_target()

void assign_checkpoint_completion_target ( double  newval,
void *  extra 
)

Definition at line 2252 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

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

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2245 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

2246 {
2249 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2216
int max_wal_size_mb
Definition: xlog.c:89
#define newval

◆ BootStrapXLOG()

void BootStrapXLOG ( void  )

Definition at line 4996 of file xlog.c.

References AdvanceOldestClogXid(), Assert, bootstrap_data_checksum_version, BootStrapCLOG(), BootStrapCommitTs(), BootStrapMultiXact(), BootStrapSUBTRANS(), buffer, ControlFileData::checkPoint, ControlFileData::checkPointCopy, close, COMP_CRC32C, ControlFileData::data_checksum_version, DB_SHUTDOWNED, ereport, errcode(), errcode_for_file_access(), errmsg(), FIN_CRC32C, FirstBootstrapObjectId, FirstMultiXactId, FirstNormalTransactionId, CheckPoint::fullPageWrites, fullPageWrites, gettimeofday(), INIT_CRC32C, InvalidTransactionId, max_locks_per_xact, ControlFileData::max_locks_per_xact, max_prepared_xacts, ControlFileData::max_prepared_xacts, max_worker_processes, ControlFileData::max_worker_processes, MaxConnections, ControlFileData::MaxConnections, MOCK_AUTH_NONCE_LEN, ControlFileData::mock_authentication_nonce, MultiXactSetNextMXact(), CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, VariableCacheData::nextOid, CheckPoint::nextXid, VariableCacheData::nextXid, CheckPoint::nextXidEpoch, offsetof, VariableCacheData::oidCount, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, openLogFile, palloc(), PANIC, pfree(), pg_backend_random(), pg_fsync(), pgstat_report_wait_end(), pgstat_report_wait_start(), CheckPoint::PrevTimeLineID, ReadControlFile(), CheckPoint::redo, SetCommitTsLimit(), SetMultiXactIdLimit(), SetTransactionIdLimit(), ShmemVariableCache, SizeOfXLogLongPHD, SizeOfXLogRecord, SizeOfXLogRecordDataHeaderShort, ControlFileData::state, ControlFileData::system_identifier, TemplateDbOid, 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().

4997 {
4998  CheckPoint checkPoint;
4999  char *buffer;
5000  XLogPageHeader page;
5001  XLogLongPageHeader longpage;
5002  XLogRecord *record;
5003  char *recptr;
5004  bool use_existent;
5005  uint64 sysidentifier;
5006  char mock_auth_nonce[MOCK_AUTH_NONCE_LEN];
5007  struct timeval tv;
5008  pg_crc32c crc;
5009 
5010  /*
5011  * Select a hopefully-unique system identifier code for this installation.
5012  * We use the result of gettimeofday(), including the fractional seconds
5013  * field, as being about as unique as we can easily get. (Think not to
5014  * use random(), since it hasn't been seeded and there's no portable way
5015  * to seed it other than the system clock value...) The upper half of the
5016  * uint64 value is just the tv_sec part, while the lower half contains the
5017  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
5018  * PID for a little extra uniqueness. A person knowing this encoding can
5019  * determine the initialization time of the installation, which could
5020  * perhaps be useful sometimes.
5021  */
5022  gettimeofday(&tv, NULL);
5023  sysidentifier = ((uint64) tv.tv_sec) << 32;
5024  sysidentifier |= ((uint64) tv.tv_usec) << 12;
5025  sysidentifier |= getpid() & 0xFFF;
5026 
5027  /*
5028  * Generate a random nonce. This is used for authentication requests that
5029  * will fail because the user does not exist. The nonce is used to create
5030  * a genuine-looking password challenge for the non-existent user, in lieu
5031  * of an actual stored password.
5032  */
5033  if (!pg_backend_random(mock_auth_nonce, MOCK_AUTH_NONCE_LEN))
5034  ereport(PANIC,
5035  (errcode(ERRCODE_INTERNAL_ERROR),
5036  errmsg("could not generate secret authorization token")));
5037 
5038  /* First timeline ID is always 1 */
5039  ThisTimeLineID = 1;
5040 
5041  /* page buffer must be aligned suitably for O_DIRECT */
5042  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
5043  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
5044  memset(page, 0, XLOG_BLCKSZ);
5045 
5046  /*
5047  * Set up information for the initial checkpoint record
5048  *
5049  * The initial checkpoint record is written to the beginning of the WAL
5050  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5051  * used, so that we can use 0/0 to mean "before any valid WAL segment".
5052  */
5053  checkPoint.redo = wal_segment_size + SizeOfXLogLongPHD;
5054  checkPoint.ThisTimeLineID = ThisTimeLineID;
5055  checkPoint.PrevTimeLineID = ThisTimeLineID;
5056  checkPoint.fullPageWrites = fullPageWrites;
5057  checkPoint.nextXidEpoch = 0;
5058  checkPoint.nextXid = FirstNormalTransactionId;
5059  checkPoint.nextOid = FirstBootstrapObjectId;
5060  checkPoint.nextMulti = FirstMultiXactId;
5061  checkPoint.nextMultiOffset = 0;
5062  checkPoint.oldestXid = FirstNormalTransactionId;
5063  checkPoint.oldestXidDB = TemplateDbOid;
5064  checkPoint.oldestMulti = FirstMultiXactId;
5065  checkPoint.oldestMultiDB = TemplateDbOid;
5068  checkPoint.time = (pg_time_t) time(NULL);
5070 
5071  ShmemVariableCache->nextXid = checkPoint.nextXid;
5072  ShmemVariableCache->nextOid = checkPoint.nextOid;
5074  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5075  AdvanceOldestClogXid(checkPoint.oldestXid);
5076  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5077  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5079 
5080  /* Set up the XLOG page header */
5081  page->xlp_magic = XLOG_PAGE_MAGIC;
5082  page->xlp_info = XLP_LONG_HEADER;
5083  page->xlp_tli = ThisTimeLineID;
5085  longpage = (XLogLongPageHeader) page;
5086  longpage->xlp_sysid = sysidentifier;
5087  longpage->xlp_seg_size = wal_segment_size;
5088  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5089 
5090  /* Insert the initial checkpoint record */
5091  recptr = ((char *) page + SizeOfXLogLongPHD);
5092  record = (XLogRecord *) recptr;
5093  record->xl_prev = 0;
5094  record->xl_xid = InvalidTransactionId;
5095  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5097  record->xl_rmid = RM_XLOG_ID;
5098  recptr += SizeOfXLogRecord;
5099  /* fill the XLogRecordDataHeaderShort struct */
5100  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5101  *(recptr++) = sizeof(checkPoint);
5102  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5103  recptr += sizeof(checkPoint);
5104  Assert(recptr - (char *) record == record->xl_tot_len);
5105 
5106  INIT_CRC32C(crc);
5107  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5108  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5109  FIN_CRC32C(crc);
5110  record->xl_crc = crc;
5111 
5112  /* Create first XLOG segment file */
5113  use_existent = false;
5114  openLogFile = XLogFileInit(1, &use_existent, false);
5115 
5116  /* Write the first page with the initial record */
5117  errno = 0;
5119  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5120  {
5121  /* if write didn't set errno, assume problem is no disk space */
5122  if (errno == 0)
5123  errno = ENOSPC;
5124  ereport(PANIC,
5126  errmsg("could not write bootstrap write-ahead log file: %m")));
5127  }
5129 
5131  if (pg_fsync(openLogFile) != 0)
5132  ereport(PANIC,
5134  errmsg("could not fsync bootstrap write-ahead log file: %m")));
5136 
5137  if (close(openLogFile))
5138  ereport(PANIC,
5140  errmsg("could not close bootstrap write-ahead log file: %m")));
5141 
5142  openLogFile = -1;
5143 
5144  /* Now create pg_control */
5145 
5146  memset(ControlFile, 0, sizeof(ControlFileData));
5147  /* Initialize pg_control status fields */
5148  ControlFile->system_identifier = sysidentifier;
5149  memcpy(ControlFile->mock_authentication_nonce, mock_auth_nonce, MOCK_AUTH_NONCE_LEN);
5151  ControlFile->time = checkPoint.time;
5152  ControlFile->checkPoint = checkPoint.redo;
5153  ControlFile->checkPointCopy = checkPoint;
5154  ControlFile->unloggedLSN = 1;
5155 
5156  /* Set important parameter values for use when replaying WAL */
5165 
5166  /* some additional ControlFile fields are set in WriteControlFile() */
5167 
5168  WriteControlFile();
5169 
5170  /* Bootstrap the commit log, too */
5171  BootStrapCLOG();
5175 
5176  pfree(buffer);
5177 
5178  /*
5179  * Force control file to be read - in contrast to normal processing we'd
5180  * otherwise never run the checks and GUC related initializations therein.
5181  */
5182  ReadControlFile();
5183 }
static void WriteControlFile(void)
Definition: xlog.c:4375
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
int max_locks_per_xact
Definition: pg_control.h:181
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:105
int max_prepared_xacts
Definition: pg_control.h:180
int64 pg_time_t
Definition: pgtime.h:23
int wal_segment_size
Definition: xlog.c:113
pg_time_t time
Definition: pg_control.h:128
void SetCommitTsLimit(TransactionId oldestXact, TransactionId newestXact)
Definition: commit_ts.c:849
uint32 oidCount
Definition: transam.h:112
#define write(a, b, c)
Definition: win32.h:14
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:201
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:104
int XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
Definition: xlog.c:3160
void BootStrapMultiXact(void)
Definition: multixact.c:1866
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: pg_control.h:39
int errcode(int sqlerrcode)
Definition: elog.c:575
RmgrId xl_rmid
Definition: xlogrecord.h:47
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:57
CheckPoint checkPointCopy
Definition: pg_control.h:131
TransactionId oldestXid
Definition: pg_control.h:47
TransactionId nextXid
Definition: pg_control.h:43
pg_time_t time
Definition: pg_control.h:51
#define PANIC
Definition: elog.h:53
uint32 bootstrap_data_checksum_version
Definition: bootstrap.c:50
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:74
#define MOCK_AUTH_NONCE_LEN
Definition: pg_control.h:27
bool fullPageWrites
Definition: xlog.c:97
void BootStrapSUBTRANS(void)
Definition: subtrans.c:212
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid)
Definition: varsup.c:271
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
void pfree(void *pointer)
Definition: mcxt.c:936
#define FirstNormalTransactionId
Definition: transam.h:34
int max_prepared_xacts
Definition: twophase.c:117
uint64 system_identifier
Definition: pg_control.h:106
uint32 xl_tot_len
Definition: xlogrecord.h:43
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
TransactionId nextXid
Definition: transam.h:117
static void ReadControlFile(void)
Definition: xlog.c:4464
uint32 nextXidEpoch
Definition: pg_control.h:42
bool track_commit_timestamp
Definition: commit_ts.c:103
#define TemplateDbOid
Definition: pg_database.h:80
uint32 data_checksum_version
Definition: pg_control.h:221
bool pg_backend_random(char *dst, int len)
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
XLogRecPtr unloggedLSN
Definition: pg_control.h:133
int errcode_for_file_access(void)
Definition: elog.c:598
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define InvalidTransactionId
Definition: transam.h:31
#define FirstBootstrapObjectId
Definition: transam.h:93
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1244
#define FirstMultiXactId
Definition: multixact.h:24
#define ereport(elevel, rest)
Definition: elog.h:122
int max_locks_per_xact
Definition: lock.c:54
TimeLineID xlp_tli
Definition: xlog_internal.h:40
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
#define SizeOfXLogRecord
Definition: xlogrecord.h:55
TransactionId newestCommitTsXid
Definition: pg_control.h:54
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition: pg_control.h:228
int MaxConnections
Definition: globals.c:123
Oid oldestMultiDB
Definition: pg_control.h:50
static int openLogFile
Definition: xlog.c:774
static ControlFileData * ControlFile
Definition: xlog.c:715
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
Definition: multixact.c:2194
TimeLineID ThisTimeLineID
Definition: xlog.c:181
Oid nextOid
Definition: pg_control.h:44
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:626
bool fullPageWrites
Definition: pg_control.h:41
bool wal_log_hints
Definition: xlog.c:98
void BootStrapCLOG(void)
Definition: clog.c:712
bool track_commit_timestamp
Definition: pg_control.h:182
#define Assert(condition)
Definition: c.h:680
#define XLP_LONG_HEADER
Definition: xlog_internal.h:79
Oid oldestXidDB
Definition: pg_control.h:48
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1220
void SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid)
Definition: varsup.c:288
uint8 xl_info
Definition: xlogrecord.h:46
MultiXactId nextMulti
Definition: pg_control.h:45
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:224
TransactionId xl_xid
Definition: xlogrecord.h:44
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
void * palloc(Size size)
Definition: mcxt.c:835
int errmsg(const char *fmt,...)
Definition: elog.c:797
int max_worker_processes
Definition: globals.c:124
int pg_fsync(int fd)
Definition: fd.c:347
#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:73
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:78
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:36
#define offsetof(type, field)
Definition: c.h:603
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset)
Definition: multixact.c:2160

◆ CheckPromoteSignal()

bool CheckPromoteSignal ( void  )

Definition at line 12119 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, PROMOTE_SIGNAL_FILE, and stat.

Referenced by sigusr1_handler().

12120 {
12121  struct stat stat_buf;
12122 
12123  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
12125  return true;
12126 
12127  return false;
12128 }
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.c:85
struct stat stat_buf
Definition: pg_standby.c:103
#define PROMOTE_SIGNAL_FILE
Definition: xlog.c:84
#define stat(a, b)
Definition: win32_port.h:266

◆ CheckXLogRemoved()

void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)

Definition at line 3774 of file xlog.c.

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

Referenced by perform_base_backup(), and XLogRead().

3775 {
3776  int save_errno = errno;
3777  XLogSegNo lastRemovedSegNo;
3778 
3780  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3782 
3783  if (segno <= lastRemovedSegNo)
3784  {
3785  char filename[MAXFNAMELEN];
3786 
3787  XLogFileName(filename, tli, segno, wal_segment_size);
3788  errno = save_errno;
3789  ereport(ERROR,
3791  errmsg("requested WAL segment %s has already been removed",
3792  filename)));
3793  }
3794  errno = save_errno;
3795 }
int wal_segment_size
Definition: xlog.c:113
slock_t info_lck
Definition: xlog.c:704
XLogSegNo lastRemovedSegNo
Definition: xlog.c:587
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define ERROR
Definition: elog.h:43
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static XLogCtlData * XLogCtl
Definition: xlog.c:707
static char * filename
Definition: pg_dumpall.c:90
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ CreateCheckPoint()

void CreateCheckPoint ( int  flags)

Definition at line 8560 of file xlog.c.

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

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

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

◆ CreateRestartPoint()

bool CreateRestartPoint ( int  flags)

Definition at line 9106 of file xlog.c.

References XLogCtlData::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().

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

◆ DataChecksumsEnabled()

bool DataChecksumsEnabled ( void  )

Definition at line 4731 of file xlog.c.

References Assert, and ControlFileData::data_checksum_version.

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

4732 {
4733  Assert(ControlFile != NULL);
4734  return (ControlFile->data_checksum_version > 0);
4735 }
uint32 data_checksum_version
Definition: pg_control.h:221
static ControlFileData * ControlFile
Definition: xlog.c:715
#define Assert(condition)
Definition: c.h:680

◆ do_pg_abort_backup()

void do_pg_abort_backup ( void  )

Definition at line 11105 of file xlog.c.

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

Referenced by base_backup_cleanup(), and nonexclusive_base_backup_cleanup().

11106 {
11110 
11113  {
11114  XLogCtl->Insert.forcePageWrites = false;
11115  }
11117 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1651
XLogCtlInsert Insert
Definition: xlog.c:577
bool forcePageWrites
Definition: xlog.c:551
int nonExclusiveBackups
Definition: xlog.c:563
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:562
#define Assert(condition)
Definition: c.h:680
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1622
static XLogCtlData * XLogCtl
Definition: xlog.c:707

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

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

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

References sessionBackupState.

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

10700 {
10701  return sessionBackupState;
10702 }
static SessionBackupState sessionBackupState
Definition: xlog.c:512

◆ GetCurrentChunkReplayStartTime()

TimestampTz GetCurrentChunkReplayStartTime ( void  )

Definition at line 6159 of file xlog.c.

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

Referenced by GetReplicationApplyDelay().

6160 {
6161  TimestampTz xtime;
6162 
6164  xtime = XLogCtl->currentChunkStartTime;
6166 
6167  return xtime;
6168 }
int64 TimestampTz
Definition: timestamp.h:39
slock_t info_lck
Definition: xlog.c:704
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:707
TimestampTz currentChunkStartTime
Definition: xlog.c:694

◆ GetFakeLSNForUnloggedRel()

XLogRecPtr GetFakeLSNForUnloggedRel ( void  )

Definition at line 4747 of file xlog.c.

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

Referenced by gistGetFakeLSN().

4748 {
4749  XLogRecPtr nextUnloggedLSN;
4750 
4751  /* increment the unloggedLSN counter, need SpinLock */
4753  nextUnloggedLSN = XLogCtl->unloggedLSN++;
4755 
4756  return nextUnloggedLSN;
4757 }
XLogRecPtr unloggedLSN
Definition: xlog.c:590
#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:707
slock_t ulsn_lck
Definition: xlog.c:591

◆ GetFlushRecPtr()

XLogRecPtr GetFlushRecPtr ( void  )

Definition at line 8254 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(), read_local_xlog_page(), StartReplication(), WalSndWaitForWal(), XLogSendLogical(), and XLogSendPhysical().

8255 {
8259 
8260  return LogwrtResult.Flush;
8261 }
static XLogwrtResult LogwrtResult
Definition: xlog.c:751
slock_t info_lck
Definition: xlog.c:704
#define SpinLockAcquire(lock)
Definition: spin.h:62
XLogwrtResult LogwrtResult
Definition: xlog.c:601
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:707
XLogRecPtr Flush
Definition: xlog.c:426

◆ GetFullPageWriteInfo()

void GetFullPageWriteInfo ( XLogRecPtr RedoRecPtr_p,
bool doPageWrites_p 
)

Definition at line 8223 of file xlog.c.

References doPageWrites, and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

8224 {
8225  *RedoRecPtr_p = RedoRecPtr;
8226  *doPageWrites_p = doPageWrites;
8227 }
static bool doPageWrites
Definition: xlog.c:359
static XLogRecPtr RedoRecPtr
Definition: xlog.c:352

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )

Definition at line 8238 of file xlog.c.

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

Referenced by CheckpointerMain(), and IsCheckpointOnSchedule().

8239 {
8240  XLogRecPtr recptr;
8241 
8243  recptr = XLogCtl->LogwrtRqst.Write;
8245 
8246  return recptr;
8247 }
slock_t info_lck
Definition: xlog.c:704
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
XLogRecPtr Write
Definition: xlog.c:419
XLogwrtRqst LogwrtRqst
Definition: xlog.c:580
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:707

◆ GetLastImportantRecPtr()

XLogRecPtr GetLastImportantRecPtr ( void  )

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

8273 {
8275  int i;
8276 
8277  for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
8278  {
8279  XLogRecPtr last_important;
8280 
8281  /*
8282  * Need to take a lock to prevent torn reads of the LSN, which are
8283  * possible on some of the supported platforms. WAL insert locks only
8284  * support exclusive mode, so we have to use that.
8285  */
8287  last_important = WALInsertLocks[i].l.lastImportantAt;
8288  LWLockRelease(&WALInsertLocks[i].l.lock);
8289 
8290  if (res < last_important)
8291  res = last_important;
8292  }
8293 
8294  return res;
8295 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
XLogRecPtr lastImportantAt
Definition: xlog.c:469
#define NUM_XLOGINSERT_LOCKS
Definition: xlog.c:120
WALInsertLock l
Definition: xlog.c:481
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1722
uint64 XLogRecPtr
Definition: xlogdefs.h:21
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1118
int i
static WALInsertLockPadded * WALInsertLocks
Definition: xlog.c:710

◆ GetLatestXTime()

TimestampTz GetLatestXTime ( void  )

Definition at line 6129 of file xlog.c.

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

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

6130 {
6131  TimestampTz xtime;
6132 
6134  xtime = XLogCtl->recoveryLastXTime;
6136 
6137  return xtime;
6138 }
int64 TimestampTz
Definition: timestamp.h:39
slock_t info_lck
Definition: xlog.c:704
#define SpinLockAcquire(lock)
Definition: spin.h:62
TimestampTz recoveryLastXTime
Definition: xlog.c:688
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:707

◆ GetMockAuthenticationNonce()

char* GetMockAuthenticationNonce ( void  )

Definition at line 4721 of file xlog.c.

References Assert, and ControlFileData::mock_authentication_nonce.

Referenced by scram_mock_salt().

4722 {
4723  Assert(ControlFile != NULL);
4725 }
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition: pg_control.h:228
static ControlFileData * ControlFile
Definition: xlog.c:715
#define Assert(condition)
Definition: c.h:680

◆ GetNextXidAndEpoch()

void GetNextXidAndEpoch ( TransactionId xid,
uint32 epoch 
)

Definition at line 8323 of file xlog.c.

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

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

8324 {
8325  uint32 ckptXidEpoch;
8326  TransactionId ckptXid;
8327  TransactionId nextXid;
8328 
8329  /* Must read checkpoint info first, else have race condition */
8331  ckptXidEpoch = XLogCtl->ckptXidEpoch;
8332  ckptXid = XLogCtl->ckptXid;
8334 
8335  /* Now fetch current nextXid */
8336  nextXid = ReadNewTransactionId();
8337 
8338  /*
8339  * nextXid is certainly logically later than ckptXid. So if it's
8340  * numerically less, it must have wrapped into the next epoch.
8341  */
8342  if (nextXid < ckptXid)
8343  ckptXidEpoch++;
8344 
8345  *xid = nextXid;
8346  *epoch = ckptXidEpoch;
8347 }
TransactionId ckptXid
Definition: xlog.c:583
uint32 TransactionId
Definition: c.h:455
slock_t info_lck
Definition: xlog.c:704
uint32 ckptXidEpoch
Definition: xlog.c:582
#define SpinLockAcquire(lock)
Definition: spin.h:62
TransactionId ReadNewTransactionId(void)
Definition: varsup.c:250
unsigned int uint32
Definition: c.h:306
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:707
static const unsigned __int64 epoch
Definition: gettimeofday.c:34

◆ GetRedoRecPtr()

XLogRecPtr GetRedoRecPtr ( void  )

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

8196 {
8197  XLogRecPtr ptr;
8198 
8199  /*
8200  * The possibly not up-to-date copy in XlogCtl is enough. Even if we
8201  * grabbed a WAL insertion lock to read the master copy, someone might
8202  * update it just after we've released the lock.
8203  */
8205  ptr = XLogCtl->RedoRecPtr;
8207 
8208  if (RedoRecPtr < ptr)
8209  RedoRecPtr = ptr;
8210 
8211  return RedoRecPtr;
8212 }
slock_t info_lck
Definition: xlog.c:704
#define SpinLockAcquire(lock)
Definition: spin.h:62
static XLogRecPtr RedoRecPtr
Definition: xlog.c:352
XLogRecPtr RedoRecPtr
Definition: xlog.c:581
#define SpinLockRelease(lock)
Definition: spin.h:64
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:707

◆ GetSystemIdentifier()

uint64 GetSystemIdentifier ( void  )

Definition at line 4711 of file xlog.c.

References Assert, and ControlFileData::system_identifier.

Referenced by IdentifySystem(), and WalReceiverMain().

4712 {
4713  Assert(ControlFile != NULL);
4715 }
uint64 system_identifier
Definition: pg_control.h:106
static ControlFileData * ControlFile
Definition: xlog.c:715
#define Assert(condition)
Definition: c.h:680

◆ GetXLogInsertRecPtr()

XLogRecPtr GetXLogInsertRecPtr ( void  )

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

11145 {
11147  uint64 current_bytepos;
11148 
11149  SpinLockAcquire(&Insert->insertpos_lck);
11150  current_bytepos = Insert->CurrBytePos;
11151  SpinLockRelease(&Insert->insertpos_lck);
11152 
11153  return XLogBytePosToRecPtr(current_bytepos);
11154 }
slock_t insertpos_lck
Definition: xlog.c:519
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1920
XLogCtlInsert Insert
Definition: xlog.c:577
#define SpinLockAcquire(lock)
Definition: spin.h:62
uint64 CurrBytePos
Definition: xlog.c:528
static void Insert(File file)
Definition: fd.c:1068
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:707

◆ GetXLogReceiptTime()

void GetXLogReceiptTime ( TimestampTz rtime,
bool fromStream 
)

Definition at line 6175 of file xlog.c.

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

Referenced by GetStandbyLimitTime().

6176 {
6177  /*
6178  * This must be executed in the startup process, since we don't export the
6179  * relevant state to shared memory.
6180  */
6181  Assert(InRecovery);
6182 
6183  *rtime = XLogReceiptTime;
6184  *fromStream = (XLogReceiptSource == XLOG_FROM_STREAM);
6185 }
static XLogSource XLogReceiptSource
Definition: xlog.c:818
bool InRecovery
Definition: xlog.c:194
static TimestampTz XLogReceiptTime
Definition: xlog.c:817
#define Assert(condition)
Definition: c.h:680

◆ GetXLogReplayRecPtr()

XLogRecPtr GetXLogReplayRecPtr ( TimeLineID replayTLI)

Definition at line 11125 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(), read_local_xlog_page(), WalReceiverMain(), WalSndWaitForWal(), and XLogWalRcvSendReply().

11126 {
11127  XLogRecPtr recptr;
11128  TimeLineID tli;
11129 
11131  recptr = XLogCtl->lastReplayedEndRecPtr;
11132  tli = XLogCtl->lastReplayedTLI;
11134 
11135  if (replayTLI)
11136  *replayTLI = tli;
11137  return recptr;
11138 }
uint32 TimeLineID
Definition: xlogdefs.h:45
slock_t info_lck
Definition: xlog.c:704
#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:707
TimeLineID lastReplayedTLI
Definition: xlog.c:684
XLogRecPtr lastReplayedEndRecPtr
Definition: xlog.c:683

◆ GetXLogWriteRecPtr()

XLogRecPtr GetXLogWriteRecPtr ( void  )

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

11161 {
11165 
11166  return LogwrtResult.Write;
11167 }
static XLogwrtResult LogwrtResult
Definition: xlog.c:751
slock_t info_lck
Definition: xlog.c:704
#define SpinLockAcquire(lock)
Definition: spin.h:62
XLogwrtResult LogwrtResult
Definition: xlog.c:601
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:707
XLogRecPtr Write
Definition: xlog.c:425

◆ HotStandbyActive()

bool HotStandbyActive ( void  )

Definition at line 7978 of file xlog.c.

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

Referenced by XLogWalRcvSendHSFeedback().

7979 {
7980  /*
7981  * We check shared state each time only until Hot Standby is active. We
7982  * can't de-activate Hot Standby, so there's no need to keep checking
7983  * after the shared variable has once been seen true.
7984  */
7986  return true;
7987  else
7988  {
7989  /* spinlock is essential on machines with weak memory ordering! */
7993 
7994  return LocalHotStandbyActive;
7995  }
7996 }
bool SharedHotStandbyActive
Definition: xlog.c:649
slock_t info_lck
Definition: xlog.c:704
#define SpinLockAcquire(lock)
Definition: spin.h:62
static bool LocalHotStandbyActive
Definition: xlog.c:223
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:707

◆ HotStandbyActiveInReplay()

bool HotStandbyActiveInReplay ( void  )

Definition at line 8003 of file xlog.c.

References AmStartupProcess, Assert, IsPostmasterEnvironment, and LocalHotStandbyActive.

Referenced by btree_xlog_vacuum().

8004 {
8006  return LocalHotStandbyActive;
8007 }
#define AmStartupProcess()
Definition: miscadmin.h:405
bool IsPostmasterEnvironment
Definition: globals.c:100
static bool LocalHotStandbyActive
Definition: xlog.c:223
#define Assert(condition)
Definition: c.h:680

◆ InitXLOGAccess()

void InitXLOGAccess ( void  )

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

8170 {
8172 
8173  /* ThisTimeLineID doesn't change so we need no lock to copy it */
8176 
8177  /* set wal_segment_size */
8179 
8180  /* Use GetRedoRecPtr to copy the RedoRecPtr safely */
8181  (void) GetRedoRecPtr();
8182  /* Also update our copy of doPageWrites. */
8183  doPageWrites = (Insert->fullPageWrites || Insert->forcePageWrites);
8184 
8185  /* Also initialize the working areas for constructing WAL records */
8186  InitXLogInsert();
8187 }
int wal_segment_size
Definition: xlog.c:113
void InitXLogInsert(void)
Definition: xloginsert.c:1028
TimeLineID ThisTimeLineID
Definition: xlog.c:630
XLogCtlInsert Insert
Definition: xlog.c:577
bool fullPageWrites
Definition: xlog.c:552
uint32 xlog_seg_size
Definition: pg_control.h:208
static bool doPageWrites
Definition: xlog.c:359
bool forcePageWrites
Definition: xlog.c:551
static void Insert(File file)
Definition: fd.c:1068
static ControlFileData * ControlFile
Definition: xlog.c:715
TimeLineID ThisTimeLineID
Definition: xlog.c:181
#define Assert(condition)
Definition: c.h:680
static XLogCtlData * XLogCtl
Definition: xlog.c:707
XLogRecPtr GetRedoRecPtr(void)
Definition: xlog.c:8195
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:367

◆ issue_xlog_fsync()

void issue_xlog_fsync ( int  fd,
XLogSegNo  segno 
)

Definition at line 10118 of file xlog.c.

References elog, ereport, errcode_for_file_access(), errmsg(), PANIC, pg_fdatasync(), pg_fsync_no_writethrough(), pg_fsync_writethrough(), sync_method, SYNC_METHOD_FDATASYNC, SYNC_METHOD_FSYNC, SYNC_METHOD_FSYNC_WRITETHROUGH, SYNC_METHOD_OPEN, SYNC_METHOD_OPEN_DSYNC, ThisTimeLineID, and XLogFileNameP().

Referenced by XLogWalRcvFlush(), and XLogWrite().

10119 {
10120  switch (sync_method)
10121  {
10122  case SYNC_METHOD_FSYNC:
10123  if (pg_fsync_no_writethrough(fd) != 0)
10124  ereport(PANIC,
10126  errmsg("could not fsync log file %s: %m",
10127  XLogFileNameP(ThisTimeLineID, segno))));
10128  break;
10129 #ifdef HAVE_FSYNC_WRITETHROUGH
10131  if (pg_fsync_writethrough(fd) != 0)
10132  ereport(PANIC,
10134  errmsg("could not fsync write-through log file %s: %m",
10135  XLogFileNameP(ThisTimeLineID, segno))));
10136  break;
10137 #endif
10138 #ifdef HAVE_FDATASYNC
10139  case SYNC_METHOD_FDATASYNC:
10140  if (pg_fdatasync(fd) != 0)
10141  ereport(PANIC,
10143  errmsg("could not fdatasync log file %s: %m",
10144  XLogFileNameP(ThisTimeLineID, segno))));
10145  break;
10146 #endif
10147  case SYNC_METHOD_OPEN:
10149  /* write synced it already */
10150  break;
10151  default:
10152  elog(PANIC, "unrecognized wal_sync_method: %d", sync_method);
10153  break;
10154  }
10155 }
int pg_fdatasync(int fd)
Definition: fd.c:399
#define SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:28
int pg_fsync_writethrough(int fd)
Definition: fd.c:376
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:364
#define PANIC
Definition: elog.h:53
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define SYNC_METHOD_OPEN_DSYNC
Definition: xlog.h:29
char * XLogFileNameP(TimeLineID tli, XLogSegNo segno)
Definition: xlog.c:10161
int errcode_for_file_access(void)
Definition: elog.c:598
#define SYNC_METHOD_FSYNC
Definition: xlog.h:25
#define ereport(elevel, rest)
Definition: elog.h:122
#define SYNC_METHOD_OPEN
Definition: xlog.h:27
TimeLineID ThisTimeLineID
Definition: xlog.c:181
int sync_method
Definition: xlog.c:103
#define SYNC_METHOD_FDATASYNC
Definition: xlog.h:26
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219

◆ LocalProcessControlFile()

void LocalProcessControlFile ( bool  reset)

Definition at line 4831 of file xlog.c.

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

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

4832 {
4833  Assert(reset || ControlFile == NULL);
4834  ControlFile = palloc(sizeof(ControlFileData));
4835  ReadControlFile();
4836 }
static void ReadControlFile(void)
Definition: xlog.c:4464
static ControlFileData * ControlFile
Definition: xlog.c:715
#define Assert(condition)
Definition: c.h:680
void * palloc(Size size)
Definition: mcxt.c:835

◆ RecoveryInProgress()

bool RecoveryInProgress ( void  )

Definition at line 7922 of file xlog.c.

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

Referenced by BackgroundWriterMain(), 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_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(), XLogBackgroundFlush(), XLogInsertAllowed(), XLogNeedsFlush(), and XLogSendPhysical().

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

◆ RecoveryIsPaused()

bool RecoveryIsPaused ( void  )

Definition at line 5998 of file xlog.c.

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

Referenced by pg_is_wal_replay_paused(), and recoveryPausesHere().

5999 {
6000  bool recoveryPause;
6001 
6003  recoveryPause = XLogCtl->recoveryPause;
6005 
6006  return recoveryPause;
6007 }
slock_t info_lck
Definition: xlog.c:704
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
bool recoveryPause
Definition: xlog.c:696
static XLogCtlData * XLogCtl
Definition: xlog.c:707

◆ RemovePromoteSignalFiles()

void RemovePromoteSignalFiles ( void  )

Definition at line 12108 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, and PROMOTE_SIGNAL_FILE.

Referenced by PostmasterMain().

12109 {
12110  unlink(PROMOTE_SIGNAL_FILE);
12112 }
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.c:85
#define PROMOTE_SIGNAL_FILE
Definition: xlog.c:84

◆ SetRecoveryPause()

void SetRecoveryPause ( bool  recoveryPause)

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

6011 {
6013  XLogCtl->recoveryPause = recoveryPause;
6015 }
slock_t info_lck
Definition: xlog.c:704
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
bool recoveryPause
Definition: xlog.c:696
static XLogCtlData * XLogCtl
Definition: xlog.c:707

◆ SetWalWriterSleeping()

void SetWalWriterSleeping ( bool  sleeping)

Definition at line 12144 of file xlog.c.

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

Referenced by WalWriterMain().

12145 {
12147  XLogCtl->WalWriterSleeping = sleeping;
12149 }
slock_t info_lck
Definition: xlog.c:704
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
bool WalWriterSleeping
Definition: xlog.c:656
static XLogCtlData * XLogCtl
Definition: xlog.c:707

◆ ShutdownXLOG()

void ShutdownXLOG ( int  code,
Datum  arg 
)

Definition at line 8353 of file xlog.c.

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

Referenced by CheckpointerMain(), and InitPostgres().

8354 {
8355  /* Don't be chatty in standalone mode */
8357  (errmsg("shutting down")));
8358 
8359  /*
8360  * Signal walsenders to move to stopping state.
8361  */
8363 
8364  /*
8365  * Wait for WAL senders to be in stopping state. This prevents commands
8366  * from writing new WAL.
8367  */
8369 
8370  if (RecoveryInProgress())
8372  else
8373  {
8374  /*
8375  * If archiving is enabled, rotate the last XLOG file so that all the
8376  * remaining records are archived (postmaster wakes up the archiver
8377  * process one more time at the end of shutdown). The checkpoint
8378  * record will go to the next XLOG file and won't be archived (yet).
8379  */
8381  RequestXLogSwitch(false);
8382 
8384  }
8385  ShutdownCLOG();
8386  ShutdownCommitTs();
8387  ShutdownSUBTRANS();
8389 }
bool IsPostmasterEnvironment
Definition: globals.c:100
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9436
void ShutdownSUBTRANS(void)
Definition: subtrans.c:283
void CreateCheckPoint(int flags)
Definition: xlog.c:8560
void ShutdownCLOG(void)
Definition: clog.c:823
bool CreateRestartPoint(int flags)
Definition: xlog.c:9106
#define XLogArchiveCommandSet()
Definition: xlog.h:140
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:7922
void WalSndWaitStopping(void)
Definition: walsender.c:3067
void ShutdownMultiXact(void)
Definition: multixact.c:2105
#define ereport(elevel, rest)
Definition: elog.h:122
#define NOTICE
Definition: elog.h:37
void WalSndInitStopping(void)
Definition: walsender.c:3041
void ShutdownCommitTs(void)
Definition: commit_ts.c:745
#define XLogArchivingActive()
Definition: xlog.h:135
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:179
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:176

◆ StartupXLOG()

void StartupXLOG ( void  )

Definition at line 6257 of file xlog.c.

References AdvanceOldestClogXid(), AllowCascadeReplication, appendStringInfo(), appendStringInfoString(), archiveCleanupCommand, XLogCtlData::archiveCleanupCommand, ArchiveRecoveryRequested, ErrorContextCallback::arg, Assert, BACKUP_LABEL_FILE, BACKUP_LABEL_OLD, ControlFileData::backupEndPoint, ControlFileData::backupEndRequired, ControlFileData::backupStartPoint, bgwriterLaunched, buf, ErrorContextCallback::callback, ControlFileData::checkPoint, CHECKPOINT_END_OF_RECOVERY, CHECKPOINT_FORCE, CHECKPOINT_IMMEDIATE, CHECKPOINT_WAIT, ControlFileData::checkPointCopy, CheckRecoveryConsistency(), CheckRequiredParameterValues(), checkTimeLineSwitch(), checkXLogConsistency(), XLogCtlData::ckptXid, XLogCtlData::ckptXidEpoch, close, CompleteCommitTsInitialization(), CreateCheckPoint(), CreateEndOfRecoveryRecord(), XLogCtlInsert::CurrBytePos, XLogCtlData::currentChunkStartTime, StringInfoData::data, DataDir, DB_IN_ARCHIVE_RECOVERY, DB_IN_CRASH_RECOVERY, DB_IN_PRODUCTION, DB_SHUTDOWNED, DB_SHUTDOWNED_IN_RECOVERY, DB_SHUTDOWNING, DEBUG1, DEBUG2, DEBUG3, DeleteAllExportedSnapshotFiles(), DisownLatch(), doPageWrites, doRequestWalReceiverReply, durable_rename(), elog, EnableHotStandby, EndRecPtr, ereport, errcode(), errcode_for_file_access(), errdetail(), errhint(), errmsg(), errmsg_internal(), ERROR, error_context_stack, ExecuteRecoveryCommand(), exitArchiveRecovery(), fast_promote, FATAL, findNewestTimeLine(), XLogwrtRqst::Flush, XLogwrtResult::Flush, CheckPoint::fullPageWrites, XLogCtlInsert::fullPageWrites, GetCurrentTimestamp(), GetLatestXTime(), HandleStartupProcInterrupts(), InArchiveRecovery, XLogCtlData::info_lck, XLogCtlData::InitializedUpTo, InitRecoveryTransactionEnvironment(), initStringInfo(), InRecovery, InRedo, Insert(), XLogCtlData::Insert, InvalidXLogRecPtr, IsPostmasterEnvironment, IsUnderPostmaster, lastFullPageWrites, LastRec, XLogCtlData::lastReplayedEndRecPtr, XLogCtlData::lastReplayedTLI, XLogCtlData::lastSegSwitchLSN, XLogCtlData::lastSegSwitchTime, RunningTransactionsData::latestCompletedXid, VariableCacheData::latestCompletedXid, lfirst, LocalSetXLogInsertAllowed(), LocalXLogInsertAllowed, LOG, XLogCtlData::LogwrtResult, LogwrtResult, XLogCtlData::LogwrtRqst, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), master_image_masked, MAXFNAMELEN, MAXPGPATH, MemSet, ControlFileData::minRecoveryPoint, minRecoveryPoint, ControlFileData::minRecoveryPointTLI, minRecoveryPointTLI, MultiXactSetNextMXact(), CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, VariableCacheData::nextOid, CheckPoint::nextXid, RunningTransactionsData::nextXid, VariableCacheData::nextXid, CheckPoint::nextXidEpoch, NIL, NOTICE, tablespaceinfo::oid, VariableCacheData::oidCount, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, RunningTransactionsData::oldestRunningXid, CheckPoint::oldestXid, CheckPoint::oldestXidDB, OwnLatch(), XLogCtlData::pages, palloc(), PANIC, tablespaceinfo::path, pfree(), pg_usleep(), pgstat_reset_all(), PMSIGNAL_RECOVERY_STARTED, PreallocXlogFiles(), PrescanPreparedTransactions(), XLogCtlInsert::PrevBytePos, ErrorContextCallback::previous, CheckPoint::PrevTimeLineID, xl_end_of_recovery::PrevTimeLineID, XLogCtlData::PrevTimeLineID, proc_exit(), ProcArrayApplyRecoveryInfo(), ProcArrayInitRecovery(), psprintf(), PublishStartupProcessInformation(), reachedConsistency, read_backup_label(), read_tablespace_map(), XLogReaderState::readBuf, ReadCheckpointRecord(), readFile, readOff, XLogReaderState::readPageTLI, ReadRecord(), readRecoveryCommandFile(), 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(), replay_image_masked, XLogCtlData::replayEndRecPtr, XLogCtlData::replayEndTLI, RequestCheckpoint(), ResetUnloggedRelations(), restoreTimeLineHistoryFiles(), restoreTwoPhaseData(), RmgrData::rm_cleanup, RM_MAX_ID, RmgrData::rm_redo, rm_redo_error_callback(), RmgrData::rm_startup, RmgrTable, SendPostmasterSignal(), SetCommitTsLimit(), SetForwardFsyncRequests(), SetMultiXactIdLimit(), SetRecoveryPause(), SetTransactionIdLimit(), XLogCtlData::SharedRecoveryInProgress, ShmemVariableCache, ShutdownRecoveryTransactionEnvironment(), ShutdownWalRcv(), snprintf(), SpinLockAcquire, SpinLockRelease, STANDBY_DISABLED, STANDBY_INITIALIZED, StandbyMode, StandbyModeRequested, StandbyRecoverPreparedTransactions(), standbyState, StartupCLOG(), StartupCommitTs(), StartupMultiXact(), StartupReorderBuffer(), StartupReplicationOrigin(), StartupReplicationSlots(), StartupSUBTRANS(), stat, ControlFileData::state, str_time(), strlcpy(), 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, track_commit_timestamp, ControlFileData::track_commit_timestamp, TransactionIdAdvance, TransactionIdFollowsOrEquals(), TransactionIdIsNormal, TransactionIdIsValid, TransactionIdRetreat, TrimCLOG(), TrimMultiXact(), UNLOGGED_RELATION_CLEANUP, UNLOGGED_RELATION_INIT, ControlFileData::unloggedLSN, XLogCtlData::unloggedLSN, UpdateControlFile(), UpdateFullPageWrites(), ValidateXLOGDirectoryStructure(), wal_segment_size, WalRcvForceReply(), WalSndWakeup(), XLogwrtRqst::Write, XLogwrtResult::Write, writeTimeLineHistory(), RunningTransactionsData::xcnt, RunningTransactionsData::xids, XLogRecord::xl_info, XLogRecord::xl_rmid, XLogRecord::xl_xid, XLogCtlData::xlblocks, XLByteToPrevSeg, XLOG_CHECKPOINT_SHUTDOWN, XLOG_END_OF_RECOVERY, xlog_outdesc(), XLogArchiveCleanup(), XLogArchiveIsReadyOrDone(), XLogArchiveNotify(), XLogArchivingActive, XLogFileName, XLogFilePath, XLogPageRead(), XLogReaderAllocate(), XLogReaderFree(), XLogReceiptTime, XLogRecGetData, XLogRecPtrIsInvalid, XLogRecPtrToBufIdx, XLogRecPtrToBytePos(), XLogReportParameters(), XLogSegmentOffset, XLR_CHECK_CONSISTENCY, XLR_INFO_MASK, and XRecOffIsValid.

Referenced by InitPostgres(), and StartupProcessMain().

6258 {
6260  CheckPoint checkPoint;
6261  bool wasShutdown;
6262  bool reachedStopPoint = false;
6263  bool haveBackupLabel = false;
6264  bool haveTblspcMap = false;
6265  XLogRecPtr RecPtr,
6266  checkPointLoc,
6267  EndOfLog;
6268  TimeLineID EndOfLogTLI;
6269  TimeLineID PrevTimeLineID;
6270  XLogRecord *record;
6271  TransactionId oldestActiveXID;
6272  bool backupEndRequired = false;
6273  bool backupFromStandby = false;
6274  DBState dbstate_at_startup;
6275  XLogReaderState *xlogreader;
6276  XLogPageReadPrivate private;
6277  bool fast_promoted = false;
6278  struct stat st;
6279 
6280  /*
6281  * Verify XLOG status looks valid.
6282  */
6283  if (ControlFile->state < DB_SHUTDOWNED ||
6286  ereport(FATAL,
6287  (errmsg("control file contains invalid data")));
6288 
6290  {
6291  /* This is the expected case, so don't be chatty in standalone mode */
6293  (errmsg("database system was shut down at %s",
6294  str_time(ControlFile->time))));
6295  }
6297  ereport(LOG,
6298  (errmsg("database system was shut down in recovery at %s",
6299  str_time(ControlFile->time))));
6300  else if (ControlFile->state == DB_SHUTDOWNING)
6301  ereport(LOG,
6302  (errmsg("database system shutdown was interrupted; last known up at %s",
6303  str_time(ControlFile->time))));
6304  else if (ControlFile->state == DB_IN_CRASH_RECOVERY)
6305  ereport(LOG,
6306  (errmsg("database system was interrupted while in recovery at %s",
6308  errhint("This probably means that some data is corrupted and"
6309  " you will have to use the last backup for recovery.")));
6311  ereport(LOG,
6312  (errmsg("database system was interrupted while in recovery at log time %s",
6314  errhint("If this has occurred more than once some data might be corrupted"
6315  " and you might need to choose an earlier recovery target.")));
6316  else if (ControlFile->state == DB_IN_PRODUCTION)
6317  ereport(LOG,
6318  (errmsg("database system was interrupted; last known up at %s",
6319  str_time(ControlFile->time))));
6320 
6321  /* This is just to allow attaching to startup process with a debugger */
6322 #ifdef XLOG_REPLAY_DELAY
6324  pg_usleep(60000000L);
6325 #endif
6326 
6327  /*
6328  * Verify that pg_wal and pg_wal/archive_status exist. In cases where
6329  * someone has performed a copy for PITR, these directories may have been
6330  * excluded and need to be re-created.
6331  */
6333 
6334  /*
6335  * If we previously crashed, there might be data which we had written,
6336  * intending to fsync it, but which we had not actually fsync'd yet.
6337  * Therefore, a power failure in the near future might cause earlier
6338  * unflushed writes to be lost, even though more recent data written to
6339  * disk from here on would be persisted. To avoid that, fsync the entire
6340  * data directory.
6341  */
6342  if (ControlFile->state != DB_SHUTDOWNED &&
6345 
6346  /*
6347  * Initialize on the assumption we want to recover to the latest timeline
6348  * that's active according to pg_control.
6349  */
6353  else
6355 
6356  /*
6357  * Check for recovery control file, and if so set up state for offline
6358  * recovery
6359  */
6361 
6362  /*
6363  * Save archive_cleanup_command in shared memory so that other processes
6364  * can see it.
6365  */
6368  sizeof(XLogCtl->archiveCleanupCommand));
6369 
6371  {
6373  ereport(LOG,
6374  (errmsg("entering standby mode")));
6375  else if (recoveryTarget == RECOVERY_TARGET_XID)
6376  ereport(LOG,
6377  (errmsg("starting point-in-time recovery to XID %u",
6378  recoveryTargetXid)));
6380  ereport(LOG,
6381  (errmsg("starting point-in-time recovery to %s",
6384  ereport(LOG,
6385  (errmsg("starting point-in-time recovery to \"%s\"",
6386  recoveryTargetName)));
6387  else if (recoveryTarget == RECOVERY_TARGET_LSN)
6388  ereport(LOG,
6389  (errmsg("starting point-in-time recovery to WAL location (LSN) \"%X/%X\"",
6390  (uint32) (recoveryTargetLSN >> 32),
6393  ereport(LOG,
6394  (errmsg("starting point-in-time recovery to earliest consistent point")));
6395  else
6396  ereport(LOG,
6397  (errmsg("starting archive recovery")));
6398  }
6399 
6400  /*
6401  * Take ownership of the wakeup latch if we're going to sleep during
6402  * recovery.
6403  */
6406 
6407  /* Set up XLOG reader facility */
6408  MemSet(&private, 0, sizeof(XLogPageReadPrivate));
6409  xlogreader = XLogReaderAllocate(wal_segment_size, &XLogPageRead, &private);
6410  if (!xlogreader)
6411  ereport(ERROR,
6412  (errcode(ERRCODE_OUT_OF_MEMORY),
6413  errmsg("out of memory"),
6414  errdetail("Failed while allocating a WAL reading processor.")));
6416 
6417  /*
6418  * Allocate pages dedicated to WAL consistency checks, those had better be
6419  * aligned.
6420  */
6421  replay_image_masked = (char *) palloc(BLCKSZ);
6422  master_image_masked = (char *) palloc(BLCKSZ);
6423 
6424  if (read_backup_label(&checkPointLoc, &backupEndRequired,
6425  &backupFromStandby))
6426  {
6427  List *tablespaces = NIL;
6428 
6429  /*
6430  * Archive recovery was requested, and thanks to the backup label
6431  * file, we know how far we need to replay to reach consistency. Enter
6432  * archive recovery directly.
6433  */
6434  InArchiveRecovery = true;
6436  StandbyMode = true;
6437 
6438  /*
6439  * When a backup_label file is present, we want to roll forward from
6440  * the checkpoint it identifies, rather than using pg_control.
6441  */
6442  record = ReadCheckpointRecord(xlogreader, checkPointLoc, 0, true);
6443  if (record != NULL)
6444  {
6445  memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
6446  wasShutdown = ((record->xl_info & ~XLR_INFO_MASK) == XLOG_CHECKPOINT_SHUTDOWN);
6447  ereport(DEBUG1,
6448  (errmsg("checkpoint record is at %X/%X",
6449  (uint32) (checkPointLoc >> 32), (uint32) checkPointLoc)));
6450  InRecovery = true; /* force recovery even if SHUTDOWNED */
6451 
6452  /*
6453  * Make sure that REDO location exists. This may not be the case
6454  * if there was a crash during an online backup, which left a
6455  * backup_label around that references a WAL segment that's
6456  * already been archived.
6457  */
6458  if (checkPoint.redo < checkPointLoc)
6459  {
6460  if (!ReadRecord(xlogreader, checkPoint.redo, LOG, false))
6461  ereport(FATAL,
6462  (errmsg("could not find redo location referenced by checkpoint record"),
6463  errhint("If you are not restoring from a backup, try removing the file \"%s/backup_label\".", DataDir)));
6464  }
6465  }
6466  else
6467  {
6468  ereport(FATAL,
6469  (errmsg("could not locate required checkpoint record"),
6470  errhint("If you are not restoring from a backup, try removing the file \"%s/backup_label\".", DataDir)));
6471  wasShutdown = false; /* keep compiler quiet */
6472  }
6473 
6474  /* read the tablespace_map file if present and create symlinks. */
6475  if (read_tablespace_map(&tablespaces))
6476  {
6477  ListCell *lc;
6478 
6479  foreach(lc, tablespaces)
6480  {
6481  tablespaceinfo *ti = lfirst(lc);
6482  char *linkloc;
6483 
6484  linkloc = psprintf("pg_tblspc/%s", ti->oid);
6485 
6486  /*
6487  * Remove the existing symlink if any and Create the symlink
6488  * under PGDATA.
6489  */
6490  remove_tablespace_symlink(linkloc);
6491 
6492  if (symlink(ti->path, linkloc) < 0)
6493  ereport(ERROR,
6495  errmsg("could not create symbolic link \"%s\": %m",
6496  linkloc)));
6497 
6498  pfree(ti->oid);
6499  pfree(ti->path);
6500  pfree(ti);
6501  }
6502 
6503  /* set flag to delete it later */
6504  haveTblspcMap = true;
6505  }
6506 
6507  /* set flag to delete it later */
6508  haveBackupLabel = true;
6509  }
6510  else
6511  {
6512  /*
6513  * If tablespace_map file is present without backup_label file, there
6514  * is no use of such file. There is no harm in retaining it, but it
6515  * is better to get rid of the map file so that we don't have any
6516  * redundant file in data directory and it will avoid any sort of
6517  * confusion. It seems prudent though to just rename the file out of
6518  * the way rather than delete it completely, also we ignore any error
6519  * that occurs in rename operation as even if map file is present
6520  * without backup_label file, it is harmless.
6521  */
6522  if (stat(TABLESPACE_MAP, &st) == 0)
6523  {
6524  unlink(TABLESPACE_MAP_OLD);
6526  ereport(LOG,
6527  (errmsg("ignoring file \"%s\" because no file \"%s\" exists",
6529  errdetail("File \"%s\" was renamed to \"%s\".",
6531  else
6532  ereport(LOG,
6533  (errmsg("ignoring file \"%s\" because no file \"%s\" exists",
6535  errdetail("Could not rename file \"%s\" to \"%s\": %m.",
6537  }
6538 
6539  /*
6540  * It's possible that archive recovery was requested, but we don't
6541  * know how far we need to replay the WAL before we reach consistency.
6542  * This can happen for example if a base backup is taken from a
6543  * running server using an atomic filesystem snapshot, without calling
6544  * pg_start/stop_backup. Or if you just kill a running master server
6545  * and put it into archive recovery by creating a recovery.conf file.
6546  *
6547  * Our strategy in that case is to perform crash recovery first,
6548  * replaying all the WAL present in pg_wal, and only enter archive
6549  * recovery after that.
6550  *
6551  * But usually we already know how far we need to replay the WAL (up
6552  * to minRecoveryPoint, up to backupEndPoint, or until we see an
6553  * end-of-backup record), and we can enter archive recovery directly.
6554  */
6560  {
6561  InArchiveRecovery = true;
6563  StandbyMode = true;
6564  }
6565 
6566  /*
6567  * Get the last valid checkpoint record. If the latest one according
6568  * to pg_control is broken, try the next-to-last one.
6569  */
6570  checkPointLoc = ControlFile->checkPoint;
6572  record = ReadCheckpointRecord(xlogreader, checkPointLoc, 1, true);
6573  if (record != NULL)
6574  {
6575  ereport(DEBUG1,
6576  (errmsg("checkpoint record is at %X/%X",
6577  (uint32) (checkPointLoc >> 32), (uint32) checkPointLoc)));
6578  }
6579  else
6580  {
6581  /*
6582  * We used to attempt to go back to a secondary checkpoint record
6583  * here, but only when not in standby_mode. We now just fail if we
6584  * can't read the last checkpoint because this allows us to
6585  * simplify processing around checkpoints.
6586  */
6587  ereport(PANIC,
6588  (errmsg("could not locate a valid checkpoint record")));
6589  }
6590  memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
6591  wasShutdown = ((record->xl_info & ~XLR_INFO_MASK) == XLOG_CHECKPOINT_SHUTDOWN);
6592  }
6593 
6594  /*
6595  * Clear out any old relcache cache files. This is *necessary* if we do
6596  * any WAL replay, since that would probably result in the cache files
6597  * being out of sync with database reality. In theory we could leave them
6598  * in place if the database had been cleanly shut down, but it seems
6599  * safest to just remove them always and let them be rebuilt during the
6600  * first backend startup. These files needs to be removed from all
6601  * directories including pg_tblspc, however the symlinks are created only
6602  * after reading tablespace_map file in case of archive recovery from
6603  * backup, so needs to clear old relcache files here after creating
6604  * symlinks.
6605  */
6607 
6608  /*
6609  * If the location of the checkpoint record is not on the expected
6610  * timeline in the history of the requested timeline, we cannot proceed:
6611  * the backup is not part of the history of the requested timeline.
6612  */
6613  Assert(expectedTLEs); /* was initialized by reading checkpoint
6614  * record */
6615  if (tliOfPointInHistory(checkPointLoc, expectedTLEs) !=
6616  checkPoint.ThisTimeLineID)
6617  {
6618  XLogRecPtr switchpoint;
6619 
6620  /*
6621  * tliSwitchPoint will throw an error if the checkpoint's timeline is
6622  * not in expectedTLEs at all.
6623  */
6625  ereport(FATAL,
6626  (errmsg("requested timeline %u is not a child of this server's history",
6628  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.",
6629  (uint32) (ControlFile->checkPoint >> 32),
6632  (uint32) (switchpoint >> 32),
6633  (uint32) switchpoint)));
6634  }
6635 
6636  /*
6637  * The min recovery point should be part of the requested timeline's
6638  * history, too.
6639  */
6643  ereport(FATAL,
6644  (errmsg("requested timeline %u does not contain minimum recovery point %X/%X on timeline %u",
6646  (uint32) (ControlFile->minRecoveryPoint >> 32),
6649 
6650  LastRec = RecPtr = checkPointLoc;
6651 
6652  ereport(DEBUG1,
6653  (errmsg_internal("redo record is at %X/%X; shutdown %s",
6654  (uint32) (checkPoint.redo >> 32), (uint32) checkPoint.redo,
6655  wasShutdown ? "true" : "false")));
6656  ereport(DEBUG1,
6657  (errmsg_internal("next transaction ID: %u:%u; next OID: %u",
6658  checkPoint.nextXidEpoch, checkPoint.nextXid,
6659  checkPoint.nextOid)));
6660  ereport(DEBUG1,
6661  (errmsg_internal("next MultiXactId: %u; next MultiXactOffset: %u",
6662  checkPoint.nextMulti, checkPoint.nextMultiOffset)));
6663  ereport(DEBUG1,
6664  (errmsg_internal("oldest unfrozen transaction ID: %u, in database %u",
6665  checkPoint.oldestXid, checkPoint.oldestXidDB)));
6666  ereport(DEBUG1,
6667  (errmsg_internal("oldest MultiXactId: %u, in database %u",
6668  checkPoint.oldestMulti, checkPoint.oldestMultiDB)));
6669  ereport(DEBUG1,
6670  (errmsg_internal("commit timestamp Xid oldest/newest: %u/%u",
6671  checkPoint.oldestCommitTsXid,
6672  checkPoint.newestCommitTsXid)));
6673  if (!TransactionIdIsNormal(checkPoint.nextXid))
6674  ereport(PANIC,
6675  (errmsg("invalid next transaction ID")));
6676 
6677  /* initialize shared memory variables from the checkpoint record */
6678  ShmemVariableCache->nextXid = checkPoint.nextXid;
6679  ShmemVariableCache->nextOid = checkPoint.nextOid;
6681  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
6682  AdvanceOldestClogXid(checkPoint.oldestXid);
6683  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
6684  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
6686  checkPoint.newestCommitTsXid);
6687  XLogCtl->ckptXidEpoch = checkPoint.nextXidEpoch;
6688  XLogCtl->ckptXid = checkPoint.nextXid;
6689 
6690  /*
6691  * Initialize replication slots, before there's a chance to remove
6692  * required resources.
6693  */
6695 
6696  /*
6697  * Startup logical state, needs to be setup now so we have proper data
6698  * during crash recovery.
6699  */
6701 
6702  /*
6703  * Startup MultiXact. We need to do this early to be able to replay
6704  * truncations.
6705  */
6706  StartupMultiXact();
6707 
6708  /*
6709  * Ditto commit timestamps. In a standby, we do it if setting is enabled
6710  * in ControlFile; in a master we base the decision on the GUC itself.
6711  */
6714  StartupCommitTs();
6715 
6716  /*
6717  * Recover knowledge about replay progress of known replication partners.
6718  */
6720 
6721  /*
6722  * Initialize unlogged LSN. On a clean shutdown, it's restored from the
6723  * control file. On recovery, all unlogged relations are blown away, so
6724  * the unlogged LSN counter can be reset too.
6725  */
6728  else
6729  XLogCtl->unloggedLSN = 1;
6730 
6731  /*
6732  * We must replay WAL entries using the same TimeLineID they were created
6733  * under, so temporarily adopt the TLI indicated by the checkpoint (see
6734  * also xlog_redo()).
6735  */
6736  ThisTimeLineID = checkPoint.ThisTimeLineID;
6737 
6738  /*
6739  * Copy any missing timeline history files between 'now' and the recovery
6740  * target timeline from archive to pg_wal. While we don't need those files
6741  * ourselves - the history file of the recovery target timeline covers all
6742  * the previous timelines in the history too - a cascading standby server
6743  * might be interested in them. Or, if you archive the WAL from this
6744  * server to a different archive than the master, it'd be good for all the
6745  * history files to get archived there after failover, so that you can use
6746  * one of the old timelines as a PITR target. Timeline history files are
6747  * small, so it's better to copy them unnecessarily than not copy them and
6748  * regret later.
6749  */
6751 
6752  /*
6753  * Before running in recovery, scan pg_twophase and fill in its status to
6754  * be able to work on entries generated by redo. Doing a scan before
6755  * taking any recovery action has the merit to discard any 2PC files that
6756  * are newer than the first record to replay, saving from any conflicts at
6757  * replay. This avoids as well any subsequent scans when doing recovery
6758  * of the on-disk two-phase data.
6759  */
6761 
6762  lastFullPageWrites = checkPoint.fullPageWrites;
6763 
6766 
6767  if (RecPtr < checkPoint.redo)
6768  ereport(PANIC,
6769  (errmsg("invalid redo in checkpoint record")));
6770 
6771  /*
6772  * Check whether we need to force recovery from WAL. If it appears to
6773  * have been a clean shutdown and we did not have a recovery.conf file,
6774  * then assume no recovery needed.
6775  */
6776  if (checkPoint.redo < RecPtr)
6777  {
6778  if (wasShutdown)
6779  ereport(PANIC,
6780  (errmsg("invalid redo record in shutdown checkpoint")));
6781  InRecovery = true;
6782  }
6783  else if (ControlFile->state != DB_SHUTDOWNED)
6784  InRecovery = true;
6785  else if (ArchiveRecoveryRequested)
6786  {
6787  /* force recovery due to presence of recovery.conf */
6788  InRecovery = true;
6789  }
6790 
6791  /* REDO */
6792  if (InRecovery)
6793  {
6794  int rmid;
6795 
6796  /*
6797  * Update pg_control to show that we are recovering and to show the
6798  * selected checkpoint as the place we are starting from. We also mark
6799  * pg_control with any minimum recovery stop point obtained from a
6800  * backup history file.
6801  */
6802  dbstate_at_startup = ControlFile->state;
6803  if (InArchiveRecovery)