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(), sigusr1_handler(), and XLogArchiveCheckDone().

◆ XLogHintBitIsNeeded

◆ XLogIsNeeded

◆ XLogLogicalInfoActive

#define XLogLogicalInfoActive ( )    (wal_level >= WAL_LEVEL_LOGICAL)

◆ XLogStandbyInfoActive

Typedef Documentation

◆ ArchiveMode

◆ CheckpointStatsData

◆ SessionBackupState

◆ WalLevel

Enumeration Type Documentation

◆ ArchiveMode

Enumerator
ARCHIVE_MODE_OFF 
ARCHIVE_MODE_ON 
ARCHIVE_MODE_ALWAYS 

Definition at line 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 2286 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

2287 {
2290 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2250
#define newval
double CheckPointCompletionTarget
Definition: checkpointer.c:147

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2279 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

2280 {
2283 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2250
int max_wal_size_mb
Definition: xlog.c:89
#define newval

◆ BootStrapXLOG()

void BootStrapXLOG ( void  )

Definition at line 5106 of file xlog.c.

References AdvanceOldestClogXid(), Assert, bootstrap_data_checksum_version, BootStrapCLOG(), BootStrapCommitTs(), BootStrapMultiXact(), BootStrapSUBTRANS(), ControlFileData::checkPoint, ControlFileData::checkPointCopy, close, COMP_CRC32C, ControlFileData::data_checksum_version, DB_SHUTDOWNED, ereport, errcode(), errcode_for_file_access(), errmsg(), FIN_CRC32C, FirstBootstrapObjectId, FirstMultiXactId, FirstNormalTransactionId, CheckPoint::fullPageWrites, fullPageWrites, gettimeofday(), INIT_CRC32C, InvalidTransactionId, max_locks_per_xact, ControlFileData::max_locks_per_xact, max_prepared_xacts, ControlFileData::max_prepared_xacts, max_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, 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().

5107 {
5108  CheckPoint checkPoint;
5109  char *buffer;
5110  XLogPageHeader page;
5111  XLogLongPageHeader longpage;
5112  XLogRecord *record;
5113  char *recptr;
5114  bool use_existent;
5115  uint64 sysidentifier;
5116  char mock_auth_nonce[MOCK_AUTH_NONCE_LEN];
5117  struct timeval tv;
5118  pg_crc32c crc;
5119 
5120  /*
5121  * Select a hopefully-unique system identifier code for this installation.
5122  * We use the result of gettimeofday(), including the fractional seconds
5123  * field, as being about as unique as we can easily get. (Think not to
5124  * use random(), since it hasn't been seeded and there's no portable way
5125  * to seed it other than the system clock value...) The upper half of the
5126  * uint64 value is just the tv_sec part, while the lower half contains the
5127  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
5128  * PID for a little extra uniqueness. A person knowing this encoding can
5129  * determine the initialization time of the installation, which could
5130  * perhaps be useful sometimes.
5131  */
5132  gettimeofday(&tv, NULL);
5133  sysidentifier = ((uint64) tv.tv_sec) << 32;
5134  sysidentifier |= ((uint64) tv.tv_usec) << 12;
5135  sysidentifier |= getpid() & 0xFFF;
5136 
5137  /*
5138  * Generate a random nonce. This is used for authentication requests that
5139  * will fail because the user does not exist. The nonce is used to create
5140  * a genuine-looking password challenge for the non-existent user, in lieu
5141  * of an actual stored password.
5142  */
5143  if (!pg_backend_random(mock_auth_nonce, MOCK_AUTH_NONCE_LEN))
5144  ereport(PANIC,
5145  (errcode(ERRCODE_INTERNAL_ERROR),
5146  errmsg("could not generate secret authorization token")));
5147 
5148  /* First timeline ID is always 1 */
5149  ThisTimeLineID = 1;
5150 
5151  /* page buffer must be aligned suitably for O_DIRECT */
5152  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
5153  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
5154  memset(page, 0, XLOG_BLCKSZ);
5155 
5156  /*
5157  * Set up information for the initial checkpoint record
5158  *
5159  * The initial checkpoint record is written to the beginning of the WAL
5160  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5161  * used, so that we can use 0/0 to mean "before any valid WAL segment".
5162  */
5163  checkPoint.redo = wal_segment_size + SizeOfXLogLongPHD;
5164  checkPoint.ThisTimeLineID = ThisTimeLineID;
5165  checkPoint.PrevTimeLineID = ThisTimeLineID;
5166  checkPoint.fullPageWrites = fullPageWrites;
5167  checkPoint.nextXidEpoch = 0;
5168  checkPoint.nextXid = FirstNormalTransactionId;
5169  checkPoint.nextOid = FirstBootstrapObjectId;
5170  checkPoint.nextMulti = FirstMultiXactId;
5171  checkPoint.nextMultiOffset = 0;
5172  checkPoint.oldestXid = FirstNormalTransactionId;
5173  checkPoint.oldestXidDB = TemplateDbOid;
5174  checkPoint.oldestMulti = FirstMultiXactId;
5175  checkPoint.oldestMultiDB = TemplateDbOid;
5178  checkPoint.time = (pg_time_t) time(NULL);
5180 
5181  ShmemVariableCache->nextXid = checkPoint.nextXid;
5182  ShmemVariableCache->nextOid = checkPoint.nextOid;
5184  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5185  AdvanceOldestClogXid(checkPoint.oldestXid);
5186  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5187  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5189 
5190  /* Set up the XLOG page header */
5191  page->xlp_magic = XLOG_PAGE_MAGIC;
5192  page->xlp_info = XLP_LONG_HEADER;
5193  page->xlp_tli = ThisTimeLineID;
5195  longpage = (XLogLongPageHeader) page;
5196  longpage->xlp_sysid = sysidentifier;
5197  longpage->xlp_seg_size = wal_segment_size;
5198  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5199 
5200  /* Insert the initial checkpoint record */
5201  recptr = ((char *) page + SizeOfXLogLongPHD);
5202  record = (XLogRecord *) recptr;
5203  record->xl_prev = 0;
5204  record->xl_xid = InvalidTransactionId;
5205  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5207  record->xl_rmid = RM_XLOG_ID;
5208  recptr += SizeOfXLogRecord;
5209  /* fill the XLogRecordDataHeaderShort struct */
5210  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5211  *(recptr++) = sizeof(checkPoint);
5212  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5213  recptr += sizeof(checkPoint);
5214  Assert(recptr - (char *) record == record->xl_tot_len);
5215 
5216  INIT_CRC32C(crc);
5217  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5218  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5219  FIN_CRC32C(crc);
5220  record->xl_crc = crc;
5221 
5222  /* Create first XLOG segment file */
5223  use_existent = false;
5224  openLogFile = XLogFileInit(1, &use_existent, false);
5225 
5226  /* Write the first page with the initial record */
5227  errno = 0;
5229  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5230  {
5231  /* if write didn't set errno, assume problem is no disk space */
5232  if (errno == 0)
5233  errno = ENOSPC;
5234  ereport(PANIC,
5236  errmsg("could not write bootstrap write-ahead log file: %m")));
5237  }
5239 
5241  if (pg_fsync(openLogFile) != 0)
5242  ereport(PANIC,
5244  errmsg("could not fsync bootstrap write-ahead log file: %m")));
5246 
5247  if (close(openLogFile))
5248  ereport(PANIC,
5250  errmsg("could not close bootstrap write-ahead log file: %m")));
5251 
5252  openLogFile = -1;
5253 
5254  /* Now create pg_control */
5255 
5256  memset(ControlFile, 0, sizeof(ControlFileData));
5257  /* Initialize pg_control status fields */
5258  ControlFile->system_identifier = sysidentifier;
5259  memcpy(ControlFile->mock_authentication_nonce, mock_auth_nonce, MOCK_AUTH_NONCE_LEN);
5261  ControlFile->time = checkPoint.time;
5262  ControlFile->checkPoint = checkPoint.redo;
5263  ControlFile->checkPointCopy = checkPoint;
5264  ControlFile->unloggedLSN = 1;
5265 
5266  /* Set important parameter values for use when replaying WAL */
5275 
5276  /* some additional ControlFile fields are set in WriteControlFile() */
5277 
5278  WriteControlFile();
5279 
5280  /* Bootstrap the commit log, too */
5281  BootStrapCLOG();
5285 
5286  pfree(buffer);
5287 
5288  /*
5289  * Force control file to be read - in contrast to normal processing we'd
5290  * otherwise never run the checks and GUC related initializations therein.
5291  */
5292  ReadControlFile();
5293 }
static void WriteControlFile(void)
Definition: xlog.c:4467
#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:848
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:3216
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:572
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:51
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:1031
#define FirstNormalTransactionId
Definition: transam.h:34
int max_prepared_xacts
Definition: twophase.c:117
uint64 system_identifier
Definition: pg_control.h:106
uint32 xl_tot_len
Definition: xlogrecord.h:43
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
TransactionId nextXid
Definition: transam.h:117
static void ReadControlFile(void)
Definition: xlog.c:4559
uint32 nextXidEpoch
Definition: pg_control.h:42
bool track_commit_timestamp
Definition: commit_ts.c:103
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:595
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:1261
#define FirstMultiXactId
Definition: multixact.h:24
#define ereport(elevel, rest)
Definition: elog.h:141
int max_locks_per_xact
Definition: lock.c:54
TimeLineID xlp_tli
Definition: xlog_internal.h:40
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:131
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:678
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:732
#define XLP_LONG_HEADER
Definition: xlog_internal.h:79
Oid oldestXidDB
Definition: pg_control.h:48
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1237
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:924
int errmsg(const char *fmt,...)
Definition: elog.c:786
int max_worker_processes
Definition: globals.c:132
int pg_fsync(int fd)
Definition: fd.c:341
#define close(a)
Definition: win32.h:12
void BootStrapCommitTs(void)
Definition: commit_ts.c:523
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:89
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:94
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:36
#define offsetof(type, field)
Definition: c.h:655
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset)
Definition: multixact.c:2160

◆ CheckPromoteSignal()

bool CheckPromoteSignal ( void  )

Definition at line 12436 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, PROMOTE_SIGNAL_FILE, and stat.

Referenced by sigusr1_handler().

12437 {
12438  struct stat stat_buf;
12439 
12440  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
12442  return true;
12443 
12444  return false;
12445 }
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.c:85
struct stat stat_buf
Definition: pg_standby.c:102
#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 3831 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().

3832 {
3833  int save_errno = errno;
3834  XLogSegNo lastRemovedSegNo;
3835 
3837  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3839 
3840  if (segno <= lastRemovedSegNo)
3841  {
3842  char filename[MAXFNAMELEN];
3843 
3844  XLogFileName(filename, tli, segno, wal_segment_size);
3845  errno = save_errno;
3846  ereport(ERROR,
3848  errmsg("requested WAL segment %s has already been removed",
3849  filename)));
3850  }
3851  errno = save_errno;
3852 }
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:595
#define ereport(elevel, rest)
Definition: elog.h:141
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static XLogCtlData * XLogCtl
Definition: xlog.c:707
static char * filename
Definition: pg_dumpall.c:88
int errmsg(const char *fmt,...)
Definition: elog.c:786

◆ CreateCheckPoint()

void CreateCheckPoint ( int  flags)

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

8730 {
8731  bool shutdown;
8732  CheckPoint checkPoint;
8733  XLogRecPtr recptr;
8734  XLogSegNo _logSegNo;
8736  uint32 freespace;
8737  XLogRecPtr PriorRedoPtr;
8738  XLogRecPtr curInsert;
8739  XLogRecPtr last_important_lsn;
8740  VirtualTransactionId *vxids;
8741  int nvxids;
8742 
8743  /*
8744  * An end-of-recovery checkpoint is really a shutdown checkpoint, just
8745  * issued at a different time.
8746  */
8748  shutdown = true;
8749  else
8750  shutdown = false;
8751 
8752  /* sanity check */
8753  if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
8754  elog(ERROR, "can't create a checkpoint during recovery");
8755 
8756  /*
8757  * Initialize InitXLogInsert working areas before entering the critical
8758  * section. Normally, this is done by the first call to
8759  * RecoveryInProgress() or LocalSetXLogInsertAllowed(), but when creating
8760  * an end-of-recovery checkpoint, the LocalSetXLogInsertAllowed call is
8761  * done below in a critical section, and InitXLogInsert cannot be called
8762  * in a critical section.
8763  */
8764  InitXLogInsert();
8765 
8766  /*
8767  * Acquire CheckpointLock to ensure only one checkpoint happens at a time.
8768  * (This is just pro forma, since in the present system structure there is
8769  * only one process that is allowed to issue checkpoints at any given
8770  * time.)
8771  */
8772  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
8773 
8774  /*
8775  * Prepare to accumulate statistics.
8776  *
8777  * Note: because it is possible for log_checkpoints to change while a
8778  * checkpoint proceeds, we always accumulate stats, even if
8779  * log_checkpoints is currently off.
8780  */
8781  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
8783 
8784  /*
8785  * Use a critical section to force system panic if we have trouble.
8786  */
8788 
8789  if (shutdown)
8790  {
8791  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8793  ControlFile->time = (pg_time_t) time(NULL);
8795  LWLockRelease(ControlFileLock);
8796  }
8797 
8798  /*
8799  * Let smgr prepare for checkpoint; this has to happen before we determine
8800  * the REDO pointer. Note that smgr must not do anything that'd have to
8801  * be undone if we decide no checkpoint is needed.
8802  */
8803  smgrpreckpt();
8804 
8805  /* Begin filling in the checkpoint WAL record */
8806  MemSet(&checkPoint, 0, sizeof(checkPoint));
8807  checkPoint.time = (pg_time_t) time(NULL);
8808 
8809  /*
8810  * For Hot Standby, derive the oldestActiveXid before we fix the redo
8811  * pointer. This allows us to begin accumulating changes to assemble our
8812  * starting snapshot of locks and transactions.
8813  */
8814  if (!shutdown && XLogStandbyInfoActive())
8816  else
8818 
8819  /*
8820  * Get location of last important record before acquiring insert locks (as
8821  * GetLastImportantRecPtr() also locks WAL locks).
8822  */
8823  last_important_lsn = GetLastImportantRecPtr();
8824 
8825  /*
8826  * We must block concurrent insertions while examining insert state to
8827  * determine the checkpoint REDO pointer.
8828  */
8830  curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
8831 
8832  /*
8833  * If this isn't a shutdown or forced checkpoint, and if there has been no
8834  * WAL activity requiring a checkpoint, skip it. The idea here is to
8835  * avoid inserting duplicate checkpoints when the system is idle.
8836  */
8837  if ((flags & (CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_END_OF_RECOVERY |
8838  CHECKPOINT_FORCE)) == 0)
8839  {
8840  if (last_important_lsn == ControlFile->checkPoint)
8841  {
8843  LWLockRelease(CheckpointLock);
8844  END_CRIT_SECTION();
8845  ereport(DEBUG1,
8846  (errmsg("checkpoint skipped because system is idle")));
8847  return;
8848  }
8849  }
8850 
8851  /*
8852  * An end-of-recovery checkpoint is created before anyone is allowed to
8853  * write WAL. To allow us to write the checkpoint record, temporarily
8854  * enable XLogInsertAllowed. (This also ensures ThisTimeLineID is
8855  * initialized, which we need here and in AdvanceXLInsertBuffer.)
8856  */
8857  if (flags & CHECKPOINT_END_OF_RECOVERY)
8859 
8860  checkPoint.ThisTimeLineID = ThisTimeLineID;
8861  if (flags & CHECKPOINT_END_OF_RECOVERY)
8862  checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
8863  else
8864  checkPoint.PrevTimeLineID = ThisTimeLineID;
8865 
8866  checkPoint.fullPageWrites = Insert->fullPageWrites;
8867 
8868  /*
8869  * Compute new REDO record ptr = location of next XLOG record.
8870  *
8871  * NB: this is NOT necessarily where the checkpoint record itself will be,
8872  * since other backends may insert more XLOG records while we're off doing
8873  * the buffer flush work. Those XLOG records are logically after the
8874  * checkpoint, even though physically before it. Got that?
8875  */
8876  freespace = INSERT_FREESPACE(curInsert);
8877  if (freespace == 0)
8878  {
8879  if (XLogSegmentOffset(curInsert, wal_segment_size) == 0)
8880  curInsert += SizeOfXLogLongPHD;
8881  else
8882  curInsert += SizeOfXLogShortPHD;
8883  }
8884  checkPoint.redo = curInsert;
8885 
8886  /*
8887  * Here we update the shared RedoRecPtr for future XLogInsert calls; this
8888  * must be done while holding all the insertion locks.
8889  *
8890  * Note: if we fail to complete the checkpoint, RedoRecPtr will be left
8891  * pointing past where it really needs to point. This is okay; the only
8892  * consequence is that XLogInsert might back up whole buffers that it
8893  * didn't really need to. We can't postpone advancing RedoRecPtr because
8894  * XLogInserts that happen while we are dumping buffers must assume that
8895  * their buffer changes are not included in the checkpoint.
8896  */
8897  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
8898 
8899  /*
8900  * Now we can release the WAL insertion locks, allowing other xacts to
8901  * proceed while we are flushing disk buffers.
8902  */
8904 
8905  /* Update the info_lck-protected copy of RedoRecPtr as well */
8907  XLogCtl->RedoRecPtr = checkPoint.redo;
8909 
8910  /*
8911  * If enabled, log checkpoint start. We postpone this until now so as not
8912  * to log anything if we decided to skip the checkpoint.
8913  */
8914  if (log_checkpoints)
8915  LogCheckpointStart(flags, false);
8916 
8917  TRACE_POSTGRESQL_CHECKPOINT_START(flags);
8918 
8919  /*
8920  * Get the other info we need for the checkpoint record.
8921  *
8922  * We don't need to save oldestClogXid in the checkpoint, it only matters
8923  * for the short period in which clog is being truncated, and if we crash
8924  * during that we'll redo the clog truncation and fix up oldestClogXid
8925  * there.
8926  */
8927  LWLockAcquire(XidGenLock, LW_SHARED);
8928  checkPoint.nextXid = ShmemVariableCache->nextXid;
8929  checkPoint.oldestXid = ShmemVariableCache->oldestXid;
8931  LWLockRelease(XidGenLock);
8932 
8933  LWLockAcquire(CommitTsLock, LW_SHARED);
8936  LWLockRelease(CommitTsLock);
8937 
8938  /* Increase XID epoch if we've wrapped around since last checkpoint */
8940  if (checkPoint.nextXid < ControlFile->checkPointCopy.nextXid)
8941  checkPoint.nextXidEpoch++;
8942 
8943  LWLockAcquire(OidGenLock, LW_SHARED);
8944  checkPoint.nextOid = ShmemVariableCache->nextOid;
8945  if (!shutdown)
8946  checkPoint.nextOid += ShmemVariableCache->oidCount;
8947  LWLockRelease(OidGenLock);
8948 
8949  MultiXactGetCheckptMulti(shutdown,
8950  &checkPoint.nextMulti,
8951  &checkPoint.nextMultiOffset,
8952  &checkPoint.oldestMulti,
8953  &checkPoint.oldestMultiDB);
8954 
8955  /*
8956  * Having constructed the checkpoint record, ensure all shmem disk buffers
8957  * and commit-log buffers are flushed to disk.
8958  *
8959  * This I/O could fail for various reasons. If so, we will fail to
8960  * complete the checkpoint, but there is no reason to force a system
8961  * panic. Accordingly, exit critical section while doing it.
8962  */
8963  END_CRIT_SECTION();
8964 
8965  /*
8966  * In some cases there are groups of actions that must all occur on one
8967  * side or the other of a checkpoint record. Before flushing the
8968  * checkpoint record we must explicitly wait for any backend currently
8969  * performing those groups of actions.
8970  *
8971  * One example is end of transaction, so we must wait for any transactions
8972  * that are currently in commit critical sections. If an xact inserted
8973  * its commit record into XLOG just before the REDO point, then a crash
8974  * restart from the REDO point would not replay that record, which means
8975  * that our flushing had better include the xact's update of pg_xact. So
8976  * we wait till he's out of his commit critical section before proceeding.
8977  * See notes in RecordTransactionCommit().
8978  *
8979  * Because we've already released the insertion locks, this test is a bit
8980  * fuzzy: it is possible that we will wait for xacts we didn't really need
8981  * to wait for. But the delay should be short and it seems better to make
8982  * checkpoint take a bit longer than to hold off insertions longer than
8983  * necessary. (In fact, the whole reason we have this issue is that xact.c
8984  * does commit record XLOG insertion and clog update as two separate steps
8985  * protected by different locks, but again that seems best on grounds of
8986  * minimizing lock contention.)
8987  *
8988  * A transaction that has not yet set delayChkpt when we look cannot be at
8989  * risk, since he's not inserted his commit record yet; and one that's
8990  * already cleared it is not at risk either, since he's done fixing clog
8991  * and we will correctly flush the update below. So we cannot miss any
8992  * xacts we need to wait for.
8993  */
8994  vxids = GetVirtualXIDsDelayingChkpt(&nvxids);
8995  if (nvxids > 0)
8996  {
8997  do
8998  {
8999  pg_usleep(10000L); /* wait for 10 msec */
9000  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids));
9001  }
9002  pfree(vxids);
9003 
9004  CheckPointGuts(checkPoint.redo, flags);
9005 
9006  /*
9007  * Take a snapshot of running transactions and write this to WAL. This
9008  * allows us to reconstruct the state of running transactions during
9009  * archive recovery, if required. Skip, if this info disabled.
9010  *
9011  * If we are shutting down, or Startup process is completing crash
9012  * recovery we don't need to write running xact data.
9013  */
9014  if (!shutdown && XLogStandbyInfoActive())
9016 
9018 
9019  /*
9020  * Now insert the checkpoint record into XLOG.
9021  */
9022  XLogBeginInsert();
9023  XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));
9024  recptr = XLogInsert(RM_XLOG_ID,
9025  shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
9027 
9028  XLogFlush(recptr);
9029 
9030  /*
9031  * We mustn't write any new WAL after a shutdown checkpoint, or it will be
9032  * overwritten at next startup. No-one should even try, this just allows
9033  * sanity-checking. In the case of an end-of-recovery checkpoint, we want
9034  * to just temporarily disable writing until the system has exited
9035  * recovery.
9036  */
9037  if (shutdown)
9038  {
9039  if (flags & CHECKPOINT_END_OF_RECOVERY)
9040  LocalXLogInsertAllowed = -1; /* return to "check" state */
9041  else
9042  LocalXLogInsertAllowed = 0; /* never again write WAL */
9043  }
9044 
9045  /*
9046  * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
9047  * = end of actual checkpoint record.
9048  */
9049  if (shutdown && checkPoint.redo != ProcLastRecPtr)
9050  ereport(PANIC,
9051  (errmsg("concurrent write-ahead log activity while database system is shutting down")));
9052 
9053  /*
9054  * Remember the prior checkpoint's redo ptr for
9055  * UpdateCheckPointDistanceEstimate()
9056  */
9057  PriorRedoPtr = ControlFile->checkPointCopy.redo;
9058 
9059  /*
9060  * Update the control file.
9061  */
9062  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9063  if (shutdown)
9066  ControlFile->checkPointCopy = checkPoint;
9067  ControlFile->time = (pg_time_t) time(NULL);
9068  /* crash recovery should always recover to the end of WAL */
9071 
9072  /*
9073  * Persist unloggedLSN value. It's reset on crash recovery, so this goes
9074  * unused on non-shutdown checkpoints, but seems useful to store it always
9075  * for debugging purposes.
9076  */
9080 
9082  LWLockRelease(ControlFileLock);
9083 
9084  /* Update shared-memory copy of checkpoint XID/epoch */
9086  XLogCtl->ckptXidEpoch = checkPoint.nextXidEpoch;
9087  XLogCtl->ckptXid = checkPoint.nextXid;
9089 
9090  /*
9091  * We are now done with critical updates; no need for system panic if we
9092  * have trouble while fooling with old log segments.
9093  */
9094  END_CRIT_SECTION();
9095 
9096  /*
9097  * Let smgr do post-checkpoint cleanup (eg, deleting old files).
9098  */
9099  smgrpostckpt();
9100 
9101  /*
9102  * Update the average distance between checkpoints if the prior checkpoint
9103  * exists.
9104  */
9105  if (PriorRedoPtr != InvalidXLogRecPtr)
9107 
9108  /*
9109  * Delete old log files, those no longer needed for last checkpoint to
9110  * prevent the disk holding the xlog from growing full.
9111  */
9113  KeepLogSeg(recptr, &_logSegNo);
9114  _logSegNo--;
9115  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr);
9116 
9117  /*
9118  * Make more log segments if needed. (Do this after recycling old log
9119  * segments, since that may supply some of the needed files.)
9120  */
9121  if (!shutdown)
9122  PreallocXlogFiles(recptr);
9123 
9124  /*
9125  * Truncate pg_subtrans if possible. We can throw away all data before
9126  * the oldest XMIN of any running transaction. No future transaction will
9127  * attempt to reference any pg_subtrans entry older than that (see Asserts
9128  * in subtrans.c). During recovery, though, we mustn't do this because
9129  * StartupSUBTRANS hasn't been called yet.
9130  */
9131  if (!RecoveryInProgress())
9133 
9134  /* Real work is done, but log and update stats before releasing lock. */
9135  LogCheckpointEnd(false);
9136 
9137  TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
9138  NBuffers,
9142 
9143  LWLockRelease(CheckpointLock);
9144 }
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:8432
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8667
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:1685
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:1954
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:2273
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:941
void MultiXactGetCheckptMulti(bool is_shutdown, MultiXactId *nextMulti, MultiXactOffset *nextMultiOffset, MultiXactId *oldestMulti, Oid *oldestMultiDB)
Definition: multixact.c:2118
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:9205
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:8082
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:2809
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
#define SpinLockAcquire(lock)
Definition: spin.h:62
void pg_usleep(long microsec)
Definition: signal.c:53
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
void UpdateControlFile(void)
Definition: xlog.c:4771
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
void pfree(void *pointer)
Definition: mcxt.c:1031
XLogRecPtr LogStandbySnapshot(void)
Definition: standby.c:901
#define ERROR
Definition: elog.h:43
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8582
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:3798
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:358
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:141
TransactionId oldestCommitTsXid
Definition: transam.h:129
static void Insert(File file)
Definition: fd.c:1062
int ckpt_bufs_written
Definition: xlog.h:205
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8208
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:9525
#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
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr RedoRecPtr, XLogRecPtr endptr)
Definition: xlog.c:3928
bool fullPageWrites
Definition: pg_control.h:41
TransactionId GetOldestXmin(Relation rel, int flags)
Definition: procarray.c:1317
void smgrpreckpt(void)
Definition: smgr.c:759
uint64 XLogRecPtr
Definition: xlogdefs.h:21
Oid oldestXidDB
Definition: pg_control.h:48
TransactionId newestCommitTsXid
Definition: transam.h: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:1656
static XLogCtlData * XLogCtl
Definition: xlog.c:707
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
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:786
#define elog(elevel,...)
Definition: elog.h:226
TransactionId GetOldestActiveTransactionId(void)
Definition: procarray.c:2111
int NBuffers
Definition: globals.c:130
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids)
Definition: procarray.c:2318
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr RedoRecPtr
Definition: xlog.c:550
void smgrpostckpt(void)
Definition: smgr.c:789
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:36
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8564
#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 9275 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().

9276 {
9277  XLogRecPtr lastCheckPointRecPtr;
9278  XLogRecPtr lastCheckPointEndPtr;
9279  CheckPoint lastCheckPoint;
9280  XLogRecPtr PriorRedoPtr;
9281  XLogRecPtr receivePtr;
9282  XLogRecPtr replayPtr;
9283  TimeLineID replayTLI;
9284  XLogRecPtr endptr;
9285  XLogSegNo _logSegNo;
9286  TimestampTz xtime;
9287 
9288  /*
9289  * Acquire CheckpointLock to ensure only one restartpoint or checkpoint
9290  * happens at a time.
9291  */
9292  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
9293 
9294  /* Get a local copy of the last safe checkpoint record. */
9296  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
9297  lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
9298  lastCheckPoint = XLogCtl->lastCheckPoint;
9300 
9301  /*
9302  * Check that we're still in recovery mode. It's ok if we exit recovery
9303  * mode after this check, the restart point is valid anyway.
9304  */
9305  if (!RecoveryInProgress())
9306  {
9307  ereport(DEBUG2,
9308  (errmsg("skipping restartpoint, recovery has already ended")));
9309  LWLockRelease(CheckpointLock);
9310  return false;
9311  }
9312 
9313  /*
9314  * If the last checkpoint record we've replayed is already our last
9315  * restartpoint, we can't perform a new restart point. We still update
9316  * minRecoveryPoint in that case, so that if this is a shutdown restart
9317  * point, we won't start up earlier than before. That's not strictly
9318  * necessary, but when hot standby is enabled, it would be rather weird if
9319  * the database opened up for read-only connections at a point-in-time
9320  * before the last shutdown. Such time travel is still possible in case of
9321  * immediate shutdown, though.
9322  *
9323  * We don't explicitly advance minRecoveryPoint when we do create a
9324  * restartpoint. It's assumed that flushing the buffers will do that as a
9325  * side-effect.
9326  */
9327  if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
9328  lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
9329  {
9330  ereport(DEBUG2,
9331  (errmsg("skipping restartpoint, already performed at %X/%X",
9332  (uint32) (lastCheckPoint.redo >> 32),
9333  (uint32) lastCheckPoint.redo)));
9334 
9336  if (flags & CHECKPOINT_IS_SHUTDOWN)
9337  {
9338  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9340  ControlFile->time = (pg_time_t) time(NULL);
9342  LWLockRelease(ControlFileLock);
9343  }
9344  LWLockRelease(CheckpointLock);
9345  return false;
9346  }
9347 
9348  /*
9349  * Update the shared RedoRecPtr so that the startup process can calculate
9350  * the number of segments replayed since last restartpoint, and request a
9351  * restartpoint if it exceeds CheckPointSegments.
9352  *
9353  * Like in CreateCheckPoint(), hold off insertions to update it, although
9354  * during recovery this is just pro forma, because no WAL insertions are
9355  * happening.
9356  */
9358  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
9360 
9361  /* Also update the info_lck-protected copy */
9363  XLogCtl->RedoRecPtr = lastCheckPoint.redo;
9365 
9366  /*
9367  * Prepare to accumulate statistics.
9368  *
9369  * Note: because it is possible for log_checkpoints to change while a
9370  * checkpoint proceeds, we always accumulate stats, even if
9371  * log_checkpoints is currently off.
9372  */
9373  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
9375 
9376  if (log_checkpoints)
9377  LogCheckpointStart(flags, true);
9378 
9379  CheckPointGuts(lastCheckPoint.redo, flags);
9380 
9381  /*
9382  * Remember the prior checkpoint's redo ptr for
9383  * UpdateCheckPointDistanceEstimate()
9384  */
9385  PriorRedoPtr = ControlFile->checkPointCopy.redo;
9386 
9387  /*
9388  * Update pg_control, using current time. Check that it still shows
9389  * IN_ARCHIVE_RECOVERY state and an older checkpoint, else do nothing;
9390  * this is a quick hack to make sure nothing really bad happens if somehow
9391  * we get here after the end-of-recovery checkpoint.
9392  */
9393  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9395  ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
9396  {
9397  ControlFile->checkPoint = lastCheckPointRecPtr;
9398  ControlFile->checkPointCopy = lastCheckPoint;
9399  ControlFile->time = (pg_time_t) time(NULL);
9400 
9401  /*
9402  * Ensure minRecoveryPoint is past the checkpoint record. Normally,
9403  * this will have happened already while writing out dirty buffers,
9404  * but not necessarily - e.g. because no buffers were dirtied. We do
9405  * this because a non-exclusive base backup uses minRecoveryPoint to
9406  * determine which WAL files must be included in the backup, and the
9407  * file (or files) containing the checkpoint record must be included,
9408  * at a minimum. Note that for an ordinary restart of recovery there's
9409  * no value in having the minimum recovery point any earlier than this
9410  * anyway, because redo will begin just after the checkpoint record.
9411  */
9412  if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
9413  {
9414  ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
9416 
9417  /* update local copy */
9420  }
9421  if (flags & CHECKPOINT_IS_SHUTDOWN)
9424  }
9425  LWLockRelease(ControlFileLock);
9426 
9427  /*
9428  * Update the average distance between checkpoints/restartpoints if the
9429  * prior checkpoint exists.
9430  */
9431  if (PriorRedoPtr != InvalidXLogRecPtr)
9433 
9434  /*
9435  * Delete old log files, those no longer needed for last restartpoint to
9436  * prevent the disk holding the xlog from growing full.
9437  */
9439 
9440  /*
9441  * Retreat _logSegNo using the current end of xlog replayed or received,
9442  * whichever is later.
9443  */
9444  receivePtr = GetWalRcvWriteRecPtr(NULL, NULL);
9445  replayPtr = GetXLogReplayRecPtr(&replayTLI);
9446  endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
9447  KeepLogSeg(endptr, &_logSegNo);
9448  _logSegNo--;
9449 
9450  /*
9451  * Try to recycle segments on a useful timeline. If we've been promoted
9452  * since the beginning of this restartpoint, use the new timeline chosen
9453  * at end of recovery (RecoveryInProgress() sets ThisTimeLineID in that
9454  * case). If we're still in recovery, use the timeline we're currently
9455  * replaying.
9456  *
9457  * There is no guarantee that the WAL segments will be useful on the
9458  * current timeline; if recovery proceeds to a new timeline right after
9459  * this, the pre-allocated WAL segments on this timeline will not be used,
9460  * and will go wasted until recycled on the next restartpoint. We'll live
9461  * with that.
9462  */
9463  if (RecoveryInProgress())
9464  ThisTimeLineID = replayTLI;
9465 
9466  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr);
9467 
9468  /*
9469  * Make more log segments if needed. (Do this after recycling old log
9470  * segments, since that may supply some of the needed files.)
9471  */
9472  PreallocXlogFiles(endptr);
9473 
9474  /*
9475  * ThisTimeLineID is normally not set when we're still in recovery.
9476  * However, recycling/preallocating segments above needed ThisTimeLineID
9477  * to determine which timeline to install the segments on. Reset it now,
9478  * to restore the normal state of affairs for debugging purposes.
9479  */
9480  if (RecoveryInProgress())
9481  ThisTimeLineID = 0;
9482 
9483  /*
9484  * Truncate pg_subtrans if possible. We can throw away all data before
9485  * the oldest XMIN of any running transaction. No future transaction will
9486  * attempt to reference any pg_subtrans entry older than that (see Asserts
9487  * in subtrans.c). When hot standby is disabled, though, we mustn't do
9488  * this because StartupSUBTRANS hasn't been called yet.
9489  */
9490  if (EnableHotStandby)
9492 
9493  /* Real work is done, but log and update before releasing lock. */
9494  LogCheckpointEnd(true);
9495 
9496  xtime = GetLatestXTime();
9498  (errmsg("recovery restart point at %X/%X",
9499  (uint32) (lastCheckPoint.redo >> 32), (uint32) lastCheckPoint.redo),
9500  xtime ? errdetail("Last completed transaction was at log time %s.",
9501  timestamptz_to_str(xtime)) : 0));
9502 
9503  LWLockRelease(CheckpointLock);
9504 
9505  /*
9506  * Finally, execute archive_cleanup_command, if any.
9507  */
9510  "archive_cleanup_command",
9511  false);
9512 
9513  return true;
9514 }
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8667
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:1685
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:2722
TimestampTz ckpt_start_t
Definition: xlog.h:199
slock_t info_lck
Definition: xlog.c:704
#define MemSet(start, val, len)
Definition: c.h:941
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:9205
TimestampTz GetLatestXTime(void)
Definition: xlog.c:6239
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:8082
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:354
XLogRecPtr lastCheckPointRecPtr
Definition: xlog.c:673
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
#define SpinLockAcquire(lock)
Definition: spin.h:62
void UpdateControlFile(void)
Definition: xlog.c:4771
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8582
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
Definition: xlog.c:11348
#define DEBUG2
Definition: elog.h:24
static XLogRecPtr RedoRecPtr
Definition: xlog.c:352
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3798
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errdetail(const char *fmt,...)
Definition: elog.c:862
unsigned int uint32
Definition: c.h:358
XLogRecPtr RedoRecPtr
Definition: xlog.c:581
#define ereport(elevel, rest)
Definition: elog.h:141
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:832
#define PROCARRAY_FLAGS_DEFAULT
Definition: procarray.h:50
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9525
static ControlFileData * ControlFile
Definition: xlog.c:715
TimeLineID ThisTimeLineID
Definition: xlog.c:181
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr RedoRecPtr, XLogRecPtr endptr)
Definition: xlog.c:3928
TransactionId GetOldestXmin(Relation rel, int flags)
Definition: procarray.c:1317
uint64 XLogRecPtr
Definition: xlogdefs.h:21
CheckpointStatsData CheckpointStats
Definition: xlog.c:175
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1656
static XLogCtlData * XLogCtl
Definition: xlog.c:707
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
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:786
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:8564
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:176
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:831
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1730
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)

◆ DataChecksumsEnabled()

bool DataChecksumsEnabled ( void  )

Definition at line 4841 of file xlog.c.

References Assert, and ControlFileData::data_checksum_version.

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

4842 {
4843  Assert(ControlFile != NULL);
4844  return (ControlFile->data_checksum_version > 0);
4845 }
uint32 data_checksum_version
Definition: pg_control.h:221
static ControlFileData * ControlFile
Definition: xlog.c:715
#define Assert(condition)
Definition: c.h:732

◆ do_pg_abort_backup()

void do_pg_abort_backup ( void  )

Definition at line 11320 of file xlog.c.

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

Referenced by base_backup_cleanup(), and nonexclusive_base_backup_cleanup().

11321 {
11322  /*
11323  * Quick exit if session is not keeping around a non-exclusive backup
11324  * already started.
11325  */
11327  return;
11328 
11333 
11336  {
11337  XLogCtl->Insert.forcePageWrites = false;
11338  }
11340 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1685
static SessionBackupState sessionBackupState
Definition: xlog.c:512
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:732
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1656
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 10398 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().

10402 {
10403  bool exclusive = (labelfile == NULL);
10404  bool backup_started_in_recovery = false;
10405  XLogRecPtr checkpointloc;
10406  XLogRecPtr startpoint;
10407  TimeLineID starttli;
10408  pg_time_t stamp_time;
10409  char strfbuf[128];
10410  char xlogfilename[MAXFNAMELEN];
10411  XLogSegNo _logSegNo;
10412  struct stat stat_buf;
10413  FILE *fp;
10414 
10415  backup_started_in_recovery = RecoveryInProgress();
10416 
10417  /*
10418  * Currently only non-exclusive backup can be taken during recovery.
10419  */
10420  if (backup_started_in_recovery && exclusive)
10421  ereport(ERROR,
10422  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10423  errmsg("recovery is in progress"),
10424  errhint("WAL control functions cannot be executed during recovery.")));
10425 
10426  /*
10427  * During recovery, we don't need to check WAL level. Because, if WAL
10428  * level is not sufficient, it's impossible to get here during recovery.
10429  */
10430  if (!backup_started_in_recovery && !XLogIsNeeded())
10431  ereport(ERROR,
10432  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10433  errmsg("WAL level not sufficient for making an online backup"),
10434  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
10435 
10436  if (strlen(backupidstr) > MAXPGPATH)
10437  ereport(ERROR,
10438  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
10439  errmsg("backup label too long (max %d bytes)",
10440  MAXPGPATH)));
10441 
10442  /*
10443  * Mark backup active in shared memory. We must do full-page WAL writes
10444  * during an on-line backup even if not doing so at other times, because
10445  * it's quite possible for the backup dump to obtain a "torn" (partially
10446  * written) copy of a database page if it reads the page concurrently with
10447  * our write to the same page. This can be fixed as long as the first
10448  * write to the page in the WAL sequence is a full-page write. Hence, we
10449  * turn on forcePageWrites and then force a CHECKPOINT, to ensure there
10450  * are no dirty pages in shared memory that might get dumped while the
10451  * backup is in progress without having a corresponding WAL record. (Once
10452  * the backup is complete, we need not force full-page writes anymore,
10453  * since we expect that any pages not modified during the backup interval
10454  * must have been correctly captured by the backup.)
10455  *
10456  * Note that forcePageWrites has no effect during an online backup from
10457  * the standby.
10458  *
10459  * We must hold all the insertion locks to change the value of
10460  * forcePageWrites, to ensure adequate interlocking against
10461  * XLogInsertRecord().
10462  */
10464  if (exclusive)
10465  {
10466  /*
10467  * At first, mark that we're now starting an exclusive backup, to
10468  * ensure that there are no other sessions currently running
10469  * pg_start_backup() or pg_stop_backup().
10470  */
10472  {
10474  ereport(ERROR,
10475  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10476  errmsg("a backup is already in progress"),
10477  errhint("Run pg_stop_backup() and try again.")));
10478  }
10480  }
10481  else
10483  XLogCtl->Insert.forcePageWrites = true;
10485 
10486  /* Ensure we release forcePageWrites if fail below */
10488  {
10489  bool gotUniqueStartpoint = false;
10490  DIR *tblspcdir;
10491  struct dirent *de;
10492  tablespaceinfo *ti;
10493  int datadirpathlen;
10494 
10495  /*
10496  * Force an XLOG file switch before the checkpoint, to ensure that the
10497  * WAL segment the checkpoint is written to doesn't contain pages with
10498  * old timeline IDs. That would otherwise happen if you called
10499  * pg_start_backup() right after restoring from a PITR archive: the
10500  * first WAL segment containing the startup checkpoint has pages in
10501  * the beginning with the old timeline ID. That can cause trouble at
10502  * recovery: we won't have a history file covering the old timeline if
10503  * pg_wal directory was not included in the base backup and the WAL
10504  * archive was cleared too before starting the backup.
10505  *
10506  * This also ensures that we have emitted a WAL page header that has
10507  * XLP_BKP_REMOVABLE off before we emit the checkpoint record.
10508  * Therefore, if a WAL archiver (such as pglesslog) is trying to
10509  * compress out removable backup blocks, it won't remove any that
10510  * occur after this point.
10511  *
10512  * During recovery, we skip forcing XLOG file switch, which means that
10513  * the backup taken during recovery is not available for the special
10514  * recovery case described above.
10515  */
10516  if (!backup_started_in_recovery)
10517  RequestXLogSwitch(false);
10518 
10519  do
10520  {
10521  bool checkpointfpw;
10522 
10523  /*
10524  * Force a CHECKPOINT. Aside from being necessary to prevent torn
10525  * page problems, this guarantees that two successive backup runs
10526  * will have different checkpoint positions and hence different
10527  * history file names, even if nothing happened in between.
10528  *
10529  * During recovery, establish a restartpoint if possible. We use
10530  * the last restartpoint as the backup starting checkpoint. This
10531  * means that two successive backup runs can have same checkpoint
10532  * positions.
10533  *
10534  * Since the fact that we are executing do_pg_start_backup()
10535  * during recovery means that checkpointer is running, we can use
10536  * RequestCheckpoint() to establish a restartpoint.
10537  *
10538  * We use CHECKPOINT_IMMEDIATE only if requested by user (via
10539  * passing fast = true). Otherwise this can take awhile.
10540  */
10542  (fast ? CHECKPOINT_IMMEDIATE : 0));
10543 
10544  /*
10545  * Now we need to fetch the checkpoint record location, and also
10546  * its REDO pointer. The oldest point in WAL that would be needed
10547  * to restore starting from the checkpoint is precisely the REDO
10548  * pointer.
10549  */
10550  LWLockAcquire(ControlFileLock, LW_SHARED);
10551  checkpointloc = ControlFile->checkPoint;
10552  startpoint = ControlFile->checkPointCopy.redo;
10554  checkpointfpw = ControlFile->checkPointCopy.fullPageWrites;
10555  LWLockRelease(ControlFileLock);
10556 
10557  if (backup_started_in_recovery)
10558  {
10559  XLogRecPtr recptr;
10560 
10561  /*
10562  * Check to see if all WAL replayed during online backup
10563  * (i.e., since last restartpoint used as backup starting
10564  * checkpoint) contain full-page writes.
10565  */
10567  recptr = XLogCtl->lastFpwDisableRecPtr;
10569 
10570  if (!checkpointfpw || startpoint <= recptr)
10571  ereport(ERROR,
10572  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10573  errmsg("WAL generated with full_page_writes=off was replayed "
10574  "since last restartpoint"),
10575  errhint("This means that the backup being taken on the standby "
10576  "is corrupt and should not be used. "
10577  "Enable full_page_writes and run CHECKPOINT on the master, "
10578  "and then try an online backup again.")));
10579 
10580  /*
10581  * During recovery, since we don't use the end-of-backup WAL
10582  * record and don't write the backup history file, the
10583  * starting WAL location doesn't need to be unique. This means
10584  * that two base backups started at the same time might use
10585  * the same checkpoint as starting locations.
10586  */
10587  gotUniqueStartpoint = true;
10588  }
10589 
10590  /*
10591  * If two base backups are started at the same time (in WAL sender
10592  * processes), we need to make sure that they use different
10593  * checkpoints as starting locations, because we use the starting
10594  * WAL location as a unique identifier for the base backup in the
10595  * end-of-backup WAL record and when we write the backup history
10596  * file. Perhaps it would be better generate a separate unique ID
10597  * for each backup instead of forcing another checkpoint, but
10598  * taking a checkpoint right after another is not that expensive
10599  * either because only few buffers have been dirtied yet.
10600  */
10602  if (XLogCtl->Insert.lastBackupStart < startpoint)
10603  {
10604  XLogCtl->Insert.lastBackupStart = startpoint;
10605  gotUniqueStartpoint = true;
10606  }
10608  } while (!gotUniqueStartpoint);
10609 
10610  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
10611  XLogFileName(xlogfilename, starttli, _logSegNo, wal_segment_size);
10612 
10613  /*
10614  * Construct tablespace_map file
10615  */
10616  if (exclusive)
10617  tblspcmapfile = makeStringInfo();
10618 
10619  datadirpathlen = strlen(DataDir);
10620 
10621  /* Collect information about all tablespaces */
10622  tblspcdir = AllocateDir("pg_tblspc");
10623  while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL)
10624  {
10625  char fullpath[MAXPGPATH + 10];
10626  char linkpath[MAXPGPATH];
10627  char *relpath = NULL;
10628  int rllen;
10629  StringInfoData buflinkpath;
10630  char *s = linkpath;
10631 
10632  /* Skip special stuff */
10633  if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
10634  continue;
10635 
10636  snprintf(fullpath, sizeof(fullpath), "pg_tblspc/%s", de->d_name);
10637 
10638 #if defined(HAVE_READLINK) || defined(WIN32)
10639  rllen = readlink(fullpath, linkpath, sizeof(linkpath));
10640  if (rllen < 0)
10641  {
10642  ereport(WARNING,
10643  (errmsg("could not read symbolic link \"%s\": %m",
10644  fullpath)));
10645  continue;
10646  }
10647  else if (rllen >= sizeof(linkpath))
10648  {
10649  ereport(WARNING,
10650  (errmsg("symbolic link \"%s\" target is too long",
10651  fullpath)));
10652  continue;
10653  }
10654  linkpath[rllen] = '\0';
10655 
10656  /*
10657  * Add the escape character '\\' before newline in a string to
10658  * ensure that we can distinguish between the newline in the
10659  * tablespace path and end of line while reading tablespace_map
10660  * file during archive recovery.
10661  */
10662  initStringInfo(&buflinkpath);
10663 
10664  while (*s)
10665  {
10666  if ((*s == '\n' || *s == '\r') && needtblspcmapfile)
10667  appendStringInfoChar(&buflinkpath, '\\');
10668  appendStringInfoChar(&buflinkpath, *s++);
10669  }
10670 
10671  /*
10672  * Relpath holds the relative path of the tablespace directory
10673  * when it's located within PGDATA, or NULL if it's located
10674  * elsewhere.
10675  */
10676  if (rllen > datadirpathlen &&
10677  strncmp(linkpath, DataDir, datadirpathlen) == 0 &&
10678  IS_DIR_SEP(linkpath[datadirpathlen]))
10679  relpath = linkpath + datadirpathlen + 1;
10680 
10681  ti = palloc(sizeof(tablespaceinfo));
10682  ti->oid = pstrdup(de->d_name);
10683  ti->path = pstrdup(buflinkpath.data);
10684  ti->rpath = relpath ? pstrdup(relpath) : NULL;
10685  ti->size = infotbssize ? sendTablespace(fullpath, true) : -1;
10686 
10687  if (tablespaces)
10688  *tablespaces = lappend(*tablespaces, ti);
10689 
10690  appendStringInfo(tblspcmapfile, "%s %s\n", ti->oid, ti->path);
10691 
10692  pfree(buflinkpath.data);
10693 #else
10694 
10695  /*
10696  * If the platform does not have symbolic links, it should not be
10697  * possible to have tablespaces - clearly somebody else created
10698  * them. Warn about it and ignore.
10699  */
10700  ereport(WARNING,
10701  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
10702  errmsg("tablespaces are not supported on this platform")));
10703 #endif
10704  }
10705  FreeDir(tblspcdir);
10706 
10707  /*
10708  * Construct backup label file
10709  */
10710  if (exclusive)
10711  labelfile = makeStringInfo();
10712 
10713  /* Use the log timezone here, not the session timezone */
10714  stamp_time = (pg_time_t) time(NULL);
10715  pg_strftime(strfbuf, sizeof(strfbuf),
10716  "%Y-%m-%d %H:%M:%S %Z",
10717  pg_localtime(&stamp_time, log_timezone));
10718  appendStringInfo(labelfile, "START WAL LOCATION: %X/%X (file %s)\n",
10719  (uint32) (startpoint >> 32), (uint32) startpoint, xlogfilename);
10720  appendStringInfo(labelfile, "CHECKPOINT LOCATION: %X/%X\n",
10721  (uint32) (checkpointloc >> 32), (uint32) checkpointloc);
10722  appendStringInfo(labelfile, "BACKUP METHOD: %s\n",
10723  exclusive ? "pg_start_backup" : "streamed");
10724  appendStringInfo(labelfile, "BACKUP FROM: %s\n",
10725  backup_started_in_recovery ? "standby" : "master");
10726  appendStringInfo(labelfile, "START TIME: %s\n", strfbuf);
10727  appendStringInfo(labelfile, "LABEL: %s\n", backupidstr);
10728  appendStringInfo(labelfile, "START TIMELINE: %u\n", starttli);
10729 
10730  /*
10731  * Okay, write the file, or return its contents to caller.
10732  */
10733  if (exclusive)
10734  {
10735  /*
10736  * Check for existing backup label --- implies a backup is already
10737  * running. (XXX given that we checked exclusiveBackupState
10738  * above, maybe it would be OK to just unlink any such label
10739  * file?)
10740  */
10741  if (stat(BACKUP_LABEL_FILE, &stat_buf) != 0)
10742  {
10743  if (errno != ENOENT)
10744  ereport(ERROR,
10746  errmsg("could not stat file \"%s\": %m",
10747  BACKUP_LABEL_FILE)));
10748  }
10749  else
10750  ereport(ERROR,
10751  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10752  errmsg("a backup is already in progress"),
10753  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
10754  BACKUP_LABEL_FILE)));
10755 
10756  fp = AllocateFile(BACKUP_LABEL_FILE, "w");
10757 
10758  if (!fp)
10759  ereport(ERROR,
10761  errmsg("could not create file \"%s\": %m",
10762  BACKUP_LABEL_FILE)));
10763  if (fwrite(labelfile->data, labelfile->len, 1, fp) != 1 ||
10764  fflush(fp) != 0 ||
10765  pg_fsync(fileno(fp)) != 0 ||
10766  ferror(fp) ||
10767  FreeFile(fp))
10768  ereport(ERROR,
10770  errmsg("could not write file \"%s\": %m",
10771  BACKUP_LABEL_FILE)));
10772  /* Allocated locally for exclusive backups, so free separately */
10773  pfree(labelfile->data);
10774  pfree(labelfile);
10775 
10776  /* Write backup tablespace_map file. */
10777  if (tblspcmapfile->len > 0)
10778  {
10779  if (stat(TABLESPACE_MAP, &stat_buf) != 0)
10780  {
10781  if (errno != ENOENT)
10782  ereport(ERROR,
10784  errmsg("could not stat file \"%s\": %m",
10785  TABLESPACE_MAP)));
10786  }
10787  else
10788  ereport(ERROR,
10789  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10790  errmsg("a backup is already in progress"),
10791  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
10792  TABLESPACE_MAP)));
10793 
10794  fp = AllocateFile(TABLESPACE_MAP, "w");
10795 
10796  if (!fp)
10797  ereport(ERROR,
10799  errmsg("could not create file \"%s\": %m",
10800  TABLESPACE_MAP)));
10801  if (fwrite(tblspcmapfile->data, tblspcmapfile->len, 1, fp) != 1 ||
10802  fflush(fp) != 0 ||
10803  pg_fsync(fileno(fp)) != 0 ||
10804  ferror(fp) ||
10805  FreeFile(fp))
10806  ereport(ERROR,
10808  errmsg("could not write file \"%s\": %m",
10809  TABLESPACE_MAP)));
10810  }
10811 
10812  /* Allocated locally for exclusive backups, so free separately */
10813  pfree(tblspcmapfile->data);
10814  pfree(tblspcmapfile);
10815  }
10816  }
10818 
10819  /*
10820  * Mark that start phase has correctly finished for an exclusive backup.
10821  * Session-level locks are updated as well to reflect that state.
10822  *
10823  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating backup
10824  * counters and session-level lock. Otherwise they can be updated
10825  * inconsistently, and which might cause do_pg_abort_backup() to fail.
10826  */
10827  if (exclusive)
10828  {
10831 
10832  /* Set session-level lock */
10835  }
10836  else
10838 
10839  /*
10840  * We're done. As a convenience, return the starting WAL location.
10841  */
10842  if (starttli_p)
10843  *starttli_p = starttli;
10844  return startpoint;
10845 }
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:9602
int errhint(const char *fmt,...)
Definition: elog.c:976
uint32 TimeLineID
Definition: xlogdefs.h:45
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1685
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:1161
#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:572
CheckPoint checkPointCopy
Definition: pg_control.h:131
XLogCtlInsert Insert
Definition: xlog.c:577
bool RecoveryInProgress(void)
Definition: xlog.c:8082
static bool backup_started_in_recovery
Definition: basebackup.c:78
Definition: dirent.h:9
#define IS_DIR_SEP(ch)
Definition: port.h:84
pg_tz * log_timezone
Definition: pgtz.c:31
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
#define TABLESPACE_MAP
Definition: xlog.h: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:1031
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:102
#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:595
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2336
unsigned int uint32
Definition: c.h:358
int64 sendTablespace(char *path, bool sizeonly)
Definition: basebackup.c:962
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2590
#define CHECKPOINT_FORCE
Definition: xlog.h:180
#define ereport(elevel, rest)
Definition: elog.h:141
List * lappend(List *list, void *datum)
Definition: list.c:128
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:175
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define WARNING
Definition: elog.h:40
int nonExclusiveBackups
Definition: xlog.c: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:10849
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:562
uintptr_t Datum
Definition: postgres.h:367
static ControlFileData * ControlFile
Definition: xlog.c:715
#define BoolGetDatum(X)
Definition: postgres.h:387
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:2656
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1656
static XLogCtlData * XLogCtl
Definition: xlog.c:707
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:52
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1314
int FreeFile(FILE *file)
Definition: fd.c:2528
void * palloc(Size size)
Definition: mcxt.c:924
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
int errmsg(const char *fmt,...)
Definition: elog.c:786
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:179
#define relpath(rnode, forknum)
Definition: relpath.h:87
char * DataDir
Definition: globals.c:61
#define BACKUP_LABEL_FILE
Definition: xlog.h:322
int pg_fsync(int fd)
Definition: fd.c:341
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:36
int FreeDir(DIR *dir)
Definition: fd.c:2708
void RequestCheckpoint(int flags)
Definition: checkpointer.c:951
#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 10915 of file xlog.c.

References AllocateFile(), Assert, BACKUP_LABEL_FILE, backup_started_in_recovery, BackupHistoryFileName, BackupHistoryFilePath, BoolGetDatum, CHECK_FOR_INTERRUPTS, CleanupBackupHistory(), DEBUG1, durable_unlink(), ereport, errcode(), errcode_for_file_access(), errhint(), errmsg(), ERROR, EXCLUSIVE_BACKUP_IN_PROGRESS, EXCLUSIVE_BACKUP_NONE, EXCLUSIVE_BACKUP_STOPPING, XLogCtlInsert::exclusiveBackupState, XLogCtlInsert::forcePageWrites, fprintf, FreeFile(), XLogCtlData::info_lck, XLogCtlData::Insert, XLogCtlData::lastFpwDisableRecPtr, log_timezone, LW_SHARED, LWLockAcquire(), LWLockRelease(), MAXFNAMELEN, MAXPGPATH, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, XLogCtlInsert::nonExclusiveBackups, NOTICE, palloc(), PG_END_ENSURE_ERROR_CLEANUP, PG_ENSURE_ERROR_CLEANUP, pg_localtime(), pg_stop_backup_callback(), pg_strftime(), pg_usleep(), RecoveryInProgress(), remaining, RequestXLogSwitch(), SESSION_BACKUP_NONE, sessionBackupState, SpinLockAcquire, SpinLockRelease, stat, TABLESPACE_MAP, ThisTimeLineID, wal_segment_size, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), WARNING, XLByteToPrevSeg, XLByteToSeg, XLOG_BACKUP_END, XLogArchiveIsBusy(), XLogArchivingActive, XLogArchivingAlways, XLogBeginInsert(), XLogFileName, XLogInsert(), XLogIsNeeded, and XLogRegisterData().

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

10916 {
10917  bool exclusive = (labelfile == NULL);
10918  bool backup_started_in_recovery = false;
10919  XLogRecPtr startpoint;
10920  XLogRecPtr stoppoint;
10921  TimeLineID stoptli;
10922  pg_time_t stamp_time;
10923  char strfbuf[128];
10924  char histfilepath[MAXPGPATH];
10925  char startxlogfilename[MAXFNAMELEN];
10926  char stopxlogfilename[MAXFNAMELEN];
10927  char lastxlogfilename[MAXFNAMELEN];
10928  char histfilename[MAXFNAMELEN];
10929  char backupfrom[20];
10930  XLogSegNo _logSegNo;
10931  FILE *lfp;
10932  FILE *fp;
10933  char ch;
10934  int seconds_before_warning;
10935  int waits = 0;
10936  bool reported_waiting = false;
10937  char *remaining;
10938  char *ptr;
10939  uint32 hi,
10940  lo;
10941 
10942  backup_started_in_recovery = RecoveryInProgress();
10943 
10944  /*
10945  * Currently only non-exclusive backup can be taken during recovery.
10946  */
10947  if (backup_started_in_recovery && exclusive)
10948  ereport(ERROR,
10949  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10950  errmsg("recovery is in progress"),
10951  errhint("WAL control functions cannot be executed during recovery.")));
10952 
10953  /*
10954  * During recovery, we don't need to check WAL level. Because, if WAL
10955  * level is not sufficient, it's impossible to get here during recovery.
10956  */
10957  if (!backup_started_in_recovery && !XLogIsNeeded())
10958  ereport(ERROR,
10959  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10960  errmsg("WAL level not sufficient for making an online backup"),
10961  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
10962 
10963  if (exclusive)
10964  {
10965  /*
10966  * At first, mark that we're now stopping an exclusive backup, to
10967  * ensure that there are no other sessions currently running
10968  * pg_start_backup() or pg_stop_backup().
10969  */
10972  {
10974  ereport(ERROR,
10975  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10976  errmsg("exclusive backup not in progress")));
10977  }
10980 
10981  /*
10982  * Remove backup_label. In case of failure, the state for an exclusive
10983  * backup is switched back to in-progress.
10984  */
10986  {
10987  /*
10988  * Read the existing label file into memory.
10989  */
10990  struct stat statbuf;
10991  int r;
10992 
10993  if (stat(BACKUP_LABEL_FILE, &statbuf))
10994  {
10995  /* should not happen per the upper checks */
10996  if (errno != ENOENT)
10997  ereport(ERROR,
10999  errmsg("could not stat file \"%s\": %m",
11000  BACKUP_LABEL_FILE)));
11001  ereport(ERROR,
11002  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11003  errmsg("a backup is not in progress")));
11004  }
11005 
11006  lfp = AllocateFile(BACKUP_LABEL_FILE, "r");
11007  if (!lfp)
11008  {
11009  ereport(ERROR,
11011  errmsg("could not read file \"%s\": %m",
11012  BACKUP_LABEL_FILE)));
11013  }
11014  labelfile = palloc(statbuf.st_size + 1);
11015  r = fread(labelfile, statbuf.st_size, 1, lfp);
11016  labelfile[statbuf.st_size] = '\0';
11017 
11018  /*
11019  * Close and remove the backup label file
11020  */
11021  if (r != 1 || ferror(lfp) || FreeFile(lfp))
11022  ereport(ERROR,
11024  errmsg("could not read file \"%s\": %m",
11025  BACKUP_LABEL_FILE)));
11027 
11028  /*
11029  * Remove tablespace_map file if present, it is created only if
11030  * there are tablespaces.
11031  */
11033  }
11035  }
11036 
11037  /*
11038  * OK to update backup counters, forcePageWrites and session-level lock.
11039  *
11040  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating them.
11041  * Otherwise they can be updated inconsistently, and which might cause
11042  * do_pg_abort_backup() to fail.
11043  */
11045  if (exclusive)
11046  {
11048  }
11049  else
11050  {
11051  /*
11052  * The user-visible pg_start/stop_backup() functions that operate on
11053  * exclusive backups can be called at any time, but for non-exclusive
11054  * backups, it is expected that each do_pg_start_backup() call is
11055  * matched by exactly one do_pg_stop_backup() call.
11056  */
11059  }
11060 
11063  {
11064  XLogCtl->Insert.forcePageWrites = false;
11065  }
11066 
11067  /*
11068  * Clean up session-level lock.
11069  *
11070  * You might think that WALInsertLockRelease() can be called before
11071  * cleaning up session-level lock because session-level lock doesn't need
11072  * to be protected with WAL insertion lock. But since
11073  * CHECK_FOR_INTERRUPTS() can occur in it, session-level lock must be
11074  * cleaned up before it.
11075  */
11077 
11079 
11080  /*
11081  * Read and parse the START WAL LOCATION line (this code is pretty crude,
11082  * but we are not expecting any variability in the file format).
11083  */
11084  if (sscanf(labelfile, "START WAL LOCATION: %X/%X (file %24s)%c",
11085  &hi, &lo, startxlogfilename,
11086  &ch) != 4 || ch != '\n')
11087  ereport(ERROR,
11088  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11089  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
11090  startpoint = ((uint64) hi) << 32 | lo;
11091  remaining = strchr(labelfile, '\n') + 1; /* %n is not portable enough */
11092 
11093  /*
11094  * Parse the BACKUP FROM line. If we are taking an online backup from the
11095  * standby, we confirm that the standby has not been promoted during the
11096  * backup.
11097  */
11098  ptr = strstr(remaining, "BACKUP FROM:");
11099  if (!ptr || sscanf(ptr, "BACKUP FROM: %19s\n", backupfrom) != 1)
11100  ereport(ERROR,
11101  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11102  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
11103  if (strcmp(backupfrom, "standby") == 0 && !backup_started_in_recovery)
11104  ereport(ERROR,
11105  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11106  errmsg("the standby was promoted during online backup"),
11107  errhint("This means that the backup being taken is corrupt "
11108  "and should not be used. "
11109  "Try taking another online backup.")));
11110 
11111  /*
11112  * During recovery, we don't write an end-of-backup record. We assume that
11113  * pg_control was backed up last and its minimum recovery point can be
11114  * available as the backup end location. Since we don't have an
11115  * end-of-backup record, we use the pg_control value to check whether
11116  * we've reached the end of backup when starting recovery from this
11117  * backup. We have no way of checking if pg_control wasn't backed up last
11118  * however.
11119  *
11120  * We don't force a switch to new WAL file but it is still possible to
11121  * wait for all the required files to be archived if waitforarchive is
11122  * true. This is okay if we use the backup to start a standby and fetch
11123  * the missing WAL using streaming replication. But in the case of an
11124  * archive recovery, a user should set waitforarchive to true and wait for
11125  * them to be archived to ensure that all the required files are
11126  * available.
11127  *
11128  * We return the current minimum recovery point as the backup end
11129  * location. Note that it can be greater than the exact backup end
11130  * location if the minimum recovery point is updated after the backup of
11131  * pg_control. This is harmless for current uses.
11132  *
11133  * XXX currently a backup history file is for informational and debug
11134  * purposes only. It's not essential for an online backup. Furthermore,
11135  * even if it's created, it will not be archived during recovery because
11136  * an archiver is not invoked. So it doesn't seem worthwhile to write a
11137  * backup history file during recovery.
11138  */
11139  if (backup_started_in_recovery)
11140  {
11141  XLogRecPtr recptr;
11142 
11143  /*
11144  * Check to see if all WAL replayed during online backup contain
11145  * full-page writes.
11146  */
11148  recptr = XLogCtl->lastFpwDisableRecPtr;
11150 
11151  if (startpoint <= recptr)
11152  ereport(ERROR,
11153  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11154  errmsg("WAL generated with full_page_writes=off was replayed "
11155  "during online backup"),
11156  errhint("This means that the backup being taken on the standby "
11157  "is corrupt and should not be used. "
11158  "Enable full_page_writes and run CHECKPOINT on the master, "
11159  "and then try an online backup again.")));
11160 
11161 
11162  LWLockAcquire(ControlFileLock, LW_SHARED);
11163  stoppoint = ControlFile->minRecoveryPoint;
11164  stoptli = ControlFile->minRecoveryPointTLI;
11165  LWLockRelease(ControlFileLock);
11166  }
11167  else
11168  {
11169  /*
11170  * Write the backup-end xlog record
11171  */
11172  XLogBeginInsert();
11173  XLogRegisterData((char *) (&startpoint), sizeof(startpoint));
11174  stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
11175  stoptli = ThisTimeLineID;
11176 
11177  /*
11178  * Force a switch to a new xlog segment file, so that the backup is
11179  * valid as soon as archiver moves out the current segment file.
11180  */
11181  RequestXLogSwitch(false);
11182 
11183  XLByteToPrevSeg(stoppoint, _logSegNo, wal_segment_size);
11184  XLogFileName(stopxlogfilename, stoptli, _logSegNo, wal_segment_size);
11185 
11186  /* Use the log timezone here, not the session timezone */
11187  stamp_time = (pg_time_t) time(NULL);
11188  pg_strftime(strfbuf, sizeof(strfbuf),
11189  "%Y-%m-%d %H:%M:%S %Z",
11190  pg_localtime(&stamp_time, log_timezone));
11191 
11192  /*
11193  * Write the backup history file
11194  */
11195  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
11196  BackupHistoryFilePath(histfilepath, stoptli, _logSegNo,
11197  startpoint, wal_segment_size);
11198  fp = AllocateFile(histfilepath, "w");
11199  if (!fp)
11200  ereport(ERROR,
11202  errmsg("could not create file \"%s\": %m",
11203  histfilepath)));
11204  fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n",
11205  (uint32) (startpoint >> 32), (uint32) startpoint, startxlogfilename);
11206  fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
11207  (uint32) (stoppoint >> 32), (uint32) stoppoint, stopxlogfilename);
11208 
11209  /*
11210  * Transfer remaining lines including label and start timeline to
11211  * history file.
11212  */
11213  fprintf(fp, "%s", remaining);
11214  fprintf(fp, "STOP TIME: %s\n", strfbuf);
11215  fprintf(fp, "STOP TIMELINE: %u\n", stoptli);
11216  if (fflush(fp) || ferror(fp) || FreeFile(fp))
11217  ereport(ERROR,
11219  errmsg("could not write file \"%s\": %m",
11220  histfilepath)));
11221 
11222  /*
11223  * Clean out any no-longer-needed history files. As a side effect,
11224  * this will post a .ready file for the newly created history file,
11225  * notifying the archiver that history file may be archived
11226  * immediately.
11227  */
11229  }
11230 
11231  /*
11232  * If archiving is enabled, wait for all the required WAL files to be
11233  * archived before returning. If archiving isn't enabled, the required WAL
11234  * needs to be transported via streaming replication (hopefully with
11235  * wal_keep_segments set high enough), or some more exotic mechanism like
11236  * polling and copying files from pg_wal with script. We have no knowledge
11237  * of those mechanisms, so it's up to the user to ensure that he gets all
11238  * the required WAL.
11239  *
11240  * We wait until both the last WAL file filled during backup and the
11241  * history file have been archived, and assume that the alphabetic sorting
11242  * property of the WAL files ensures any earlier WAL files are safely
11243  * archived as well.
11244  *
11245  * We wait forever, since archive_command is supposed to work and we
11246  * assume the admin wanted his backup to work completely. If you don't
11247  * wish to wait, then either waitforarchive should be passed in as false,
11248  * or you can set statement_timeout. Also, some notices are issued to
11249  * clue in anyone who might be doing this interactively.
11250  */
11251 
11252  if (waitforarchive &&
11253  ((!backup_started_in_recovery && XLogArchivingActive()) ||
11254  (backup_started_in_recovery && XLogArchivingAlways())))
11255  {
11256  XLByteToPrevSeg(stoppoint, _logSegNo, wal_segment_size);
11257  XLogFileName(lastxlogfilename, stoptli, _logSegNo, wal_segment_size);
11258 
11259  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
11260  BackupHistoryFileName(histfilename, stoptli, _logSegNo,
11261  startpoint, wal_segment_size);
11262 
11263  seconds_before_warning = 60;
11264  waits = 0;
11265 
11266  while (XLogArchiveIsBusy(lastxlogfilename) ||
11267  XLogArchiveIsBusy(histfilename))
11268  {
11270 
11271  if (!reported_waiting && waits > 5)
11272  {
11273  ereport(NOTICE,
11274  (errmsg("pg_stop_backup cleanup done, waiting for required WAL segments to be archived")));
11275  reported_waiting = true;
11276  }
11277 
11278  pg_usleep(1000000L);
11279 
11280  if (++waits >= seconds_before_warning)
11281  {
11282  seconds_before_warning *= 2; /* This wraps in >10 years... */
11283  ereport(WARNING,
11284  (errmsg("pg_stop_backup still waiting for all required WAL segments to be archived (%d seconds elapsed)",
11285  waits),
11286  errhint("Check that your archive_command is executing properly. "
11287  "pg_stop_backup can be canceled safely, "
11288  "but the database backup will not be usable without all the WAL segments.")));
11289  }
11290  }
11291 
11292  ereport(NOTICE,
11293  (errmsg("pg_stop_backup complete, all required WAL segments have been archived")));
11294  }
11295  else if (waitforarchive)
11296  ereport(NOTICE,
11297  (errmsg("WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup")));
11298 
11299  /*
11300  * We're done. As a convenience, return the ending WAL location.
11301  */
11302  if (stoptli_p)
11303  *stoptli_p = stoptli;
11304  return stoppoint;
11305 }
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:9602
#define DEBUG1
Definition: elog.h:25
int errhint(const char *fmt,...)
Definition: elog.c:976
uint32 TimeLineID
Definition: xlogdefs.h:45
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1685
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:572
XLogCtlInsert Insert
Definition: xlog.c:577
#define BackupHistoryFileName(fname, tli, logSegNo, startpoint, wal_segsz_bytes)
bool RecoveryInProgress(void)
Definition: xlog.c:8082
static bool backup_started_in_recovery
Definition: basebackup.c:78
#define fprintf
Definition: port.h:196
pg_tz * log_timezone
Definition: pgtz.c:31
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
#define TABLESPACE_MAP
Definition: xlog.h: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:4188
#define MAXPGPATH
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errcode_for_file_access(void)
Definition: elog.c:595
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2336
unsigned int uint32
Definition: c.h:358
#define ereport(elevel, rest)
Definition: elog.h:141
#define XLOG_BACKUP_END
Definition: pg_control.h:72
#define WARNING
Definition: elog.h:40
int nonExclusiveBackups
Definition: xlog.c: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:367
static ControlFileData * ControlFile
Definition: xlog.c:715
#define BoolGetDatum(X)
Definition: postgres.h:387
TimeLineID ThisTimeLineID
Definition: xlog.c:181
#define NOTICE
Definition: elog.h:37
bool XLogArchiveIsBusy(const char *xlog)
Definition: xlogarchive.c:666
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:732
#define XLogArchivingActive()
Definition: xlog.h:135
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1656
static XLogCtlData * XLogCtl
Definition: xlog.c:707
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
static void pg_stop_backup_callback(int code, Datum arg)
Definition: xlog.c:10878
#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:684
int FreeFile(FILE *file)
Definition: fd.c:2528
void * palloc(Size size)
Definition: mcxt.c:924
int errmsg(const char *fmt,...)
Definition: elog.c:786
#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 10896 of file xlog.c.

References sessionBackupState.

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

10897 {
10898  return sessionBackupState;
10899 }
static SessionBackupState sessionBackupState
Definition: xlog.c:512

◆ GetCurrentChunkReplayStartTime()

TimestampTz GetCurrentChunkReplayStartTime ( void  )

Definition at line 6269 of file xlog.c.

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

Referenced by GetReplicationApplyDelay().

6270 {
6271  TimestampTz xtime;
6272 
6274  xtime = XLogCtl->currentChunkStartTime;
6276 
6277  return xtime;
6278 }
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 4857 of file xlog.c.

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

Referenced by gistGetFakeLSN().

4858 {
4859  XLogRecPtr nextUnloggedLSN;
4860 
4861  /* increment the unloggedLSN counter, need SpinLock */
4863  nextUnloggedLSN = XLogCtl->unloggedLSN++;
4865 
4866  return nextUnloggedLSN;
4867 }
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 8414 of file xlog.c.

References XLogwrtResult::Flush, XLogCtlData::info_lck, XLogCtlData::LogwrtResult, SpinLockAcquire, and SpinLockRelease.

Referenced by get_flush_position(), IdentifySystem(), pg_current_wal_flush_lsn(), pg_logical_slot_get_changes_guts(), pg_replication_slot_advance(), read_local_xlog_page(), StartReplication(), WalSndWaitForWal(), XLogSendLogical(), and XLogSendPhysical().

8415 {
8419 
8420  return LogwrtResult.Flush;
8421 }
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 8383 of file xlog.c.

References doPageWrites, and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

8384 {
8385  *RedoRecPtr_p = RedoRecPtr;
8386  *doPageWrites_p = doPageWrites;
8387 }
static bool doPageWrites
Definition: xlog.c:359
static XLogRecPtr RedoRecPtr
Definition: xlog.c:352

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )

Definition at line 8398 of file xlog.c.

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

Referenced by CheckpointerMain(), and IsCheckpointOnSchedule().

8399 {
8400  XLogRecPtr recptr;
8401 
8403  recptr = XLogCtl->LogwrtRqst.Write;
8405 
8406  return recptr;
8407 }
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 8432 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().

8433 {
8435  int i;
8436 
8437  for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
8438  {
8439  XLogRecPtr last_important;
8440 
8441  /*
8442  * Need to take a lock to prevent torn reads of the LSN, which are
8443  * possible on some of the supported platforms. WAL insert locks only
8444  * support exclusive mode, so we have to use that.
8445  */
8447  last_important = WALInsertLocks[i].l.lastImportantAt;
8448  LWLockRelease(&WALInsertLocks[i].l.lock);
8449 
8450  if (res < last_important)
8451  res = last_important;
8452  }
8453 
8454  return res;
8455 }
#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:1725
uint64 XLogRecPtr
Definition: xlogdefs.h:21
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
int i
static WALInsertLockPadded * WALInsertLocks
Definition: xlog.c:710

◆ GetLatestXTime()

TimestampTz GetLatestXTime ( void  )

Definition at line 6239 of file xlog.c.

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

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

6240 {
6241  TimestampTz xtime;
6242 
6244  xtime = XLogCtl->recoveryLastXTime;
6246 
6247  return xtime;
6248 }
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 4831 of file xlog.c.

References Assert, and ControlFileData::mock_authentication_nonce.

Referenced by scram_mock_salt().

4832 {
4833  Assert(ControlFile != NULL);
4835 }
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:732

◆ GetNextXidAndEpoch()

void GetNextXidAndEpoch ( TransactionId xid,
uint32 epoch 
)

Definition at line 8483 of file xlog.c.

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

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

8484 {
8485  uint32 ckptXidEpoch;
8486  TransactionId ckptXid;
8487  TransactionId nextXid;
8488 
8489  /* Must read checkpoint info first, else have race condition */
8491  ckptXidEpoch = XLogCtl->ckptXidEpoch;
8492  ckptXid = XLogCtl->ckptXid;
8494 
8495  /* Now fetch current nextXid */
8496  nextXid = ReadNewTransactionId();
8497 
8498  /*
8499  * nextXid is certainly logically later than ckptXid. So if it's
8500  * numerically less, it must have wrapped into the next epoch.
8501  */
8502  if (nextXid < ckptXid)
8503  ckptXidEpoch++;
8504 
8505  *xid = nextXid;
8506  *epoch = ckptXidEpoch;
8507 }
TransactionId ckptXid
Definition: xlog.c:583
uint32 TransactionId
Definition: c.h:507
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:358
#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 8355 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().

8356 {
8357  XLogRecPtr ptr;
8358 
8359  /*
8360  * The possibly not up-to-date copy in XlogCtl is enough. Even if we
8361  * grabbed a WAL insertion lock to read the master copy, someone might
8362  * update it just after we've released the lock.
8363  */
8365  ptr = XLogCtl->RedoRecPtr;
8367 
8368  if (RedoRecPtr < ptr)
8369  RedoRecPtr = ptr;
8370 
8371  return RedoRecPtr;
8372 }
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 4821 of file xlog.c.

References Assert, and ControlFileData::system_identifier.

Referenced by IdentifySystem(), and WalReceiverMain().

4822 {
4823  Assert(ControlFile != NULL);
4825 }
uint64 system_identifier
Definition: pg_control.h:106
static ControlFileData * ControlFile
Definition: xlog.c:715
#define Assert(condition)
Definition: c.h:732

◆ GetXLogInsertRecPtr()

XLogRecPtr GetXLogInsertRecPtr ( void  )

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

11368 {
11370  uint64 current_bytepos;
11371 
11372  SpinLockAcquire(&Insert->insertpos_lck);
11373  current_bytepos = Insert->CurrBytePos;
11374  SpinLockRelease(&Insert->insertpos_lck);
11375 
11376  return XLogBytePosToRecPtr(current_bytepos);
11377 }
slock_t insertpos_lck
Definition: xlog.c:519
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1954
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:1062
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:707

◆ GetXLogReceiptTime()

void GetXLogReceiptTime ( TimestampTz rtime,
bool fromStream 
)

Definition at line 6285 of file xlog.c.

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

Referenced by GetStandbyLimitTime().

6286 {
6287  /*
6288  * This must be executed in the startup process, since we don't export the
6289  * relevant state to shared memory.
6290  */
6291  Assert(InRecovery);
6292 
6293  *rtime = XLogReceiptTime;
6294  *fromStream = (XLogReceiptSource == XLOG_FROM_STREAM);
6295 }
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:732

◆ GetXLogReplayRecPtr()

XLogRecPtr GetXLogReplayRecPtr ( TimeLineID replayTLI)

Definition at line 11348 of file xlog.c.

References XLogCtlData::info_lck, XLogCtlData::lastReplayedEndRecPtr, XLogCtlData::lastReplayedTLI, SpinLockAcquire, and SpinLockRelease.

Referenced by CheckpointerMain(), CreateRestartPoint(), GetReplicationApplyDelay(), GetStandbyFlushRecPtr(), IsCheckpointOnSchedule(), pg_last_wal_replay_lsn(), pg_logical_slot_get_changes_guts(), pg_replication_slot_advance(), read_local_xlog_page(), WalReceiverMain(), WalSndWaitForWal(), and XLogWalRcvSendReply().

11349 {
11350  XLogRecPtr recptr;
11351  TimeLineID tli;
11352 
11354  recptr = XLogCtl->lastReplayedEndRecPtr;
11355  tli = XLogCtl->lastReplayedTLI;
11357 
11358  if (replayTLI)
11359  *replayTLI = tli;
11360  return recptr;
11361 }
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 11383 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().

11384 {
11388 
11389  return LogwrtResult.Write;
11390 }
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 8138 of file xlog.c.

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

Referenced by XLogWalRcvSendHSFeedback().

8139 {
8140  /*
8141  * We check shared state each time only until Hot Standby is active. We
8142  * can't de-activate Hot Standby, so there's no need to keep checking
8143  * after the shared variable has once been seen true.
8144  */
8146  return true;
8147  else
8148  {
8149  /* spinlock is essential on machines with weak memory ordering! */
8153 
8154  return LocalHotStandbyActive;
8155  }
8156 }
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 8163 of file xlog.c.

References AmStartupProcess, Assert, IsPostmasterEnvironment, and LocalHotStandbyActive.

Referenced by btree_xlog_vacuum().

8164 {
8166  return LocalHotStandbyActive;
8167 }
#define AmStartupProcess()
Definition: miscadmin.h:410
bool IsPostmasterEnvironment
Definition: globals.c:107
static bool LocalHotStandbyActive
Definition: xlog.c:223
#define Assert(condition)
Definition: c.h:732

◆ InitXLOGAccess()

void InitXLOGAccess ( void  )

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

8330 {
8332 
8333  /* ThisTimeLineID doesn't change so we need no lock to copy it */
8336 
8337  /* set wal_segment_size */
8339 
8340  /* Use GetRedoRecPtr to copy the RedoRecPtr safely */
8341  (void) GetRedoRecPtr();
8342  /* Also update our copy of doPageWrites. */
8343  doPageWrites = (Insert->fullPageWrites || Insert->forcePageWrites);
8344 
8345  /* Also initialize the working areas for constructing WAL records */
8346  InitXLogInsert();
8347 }
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:1062
static ControlFileData * ControlFile
Definition: xlog.c:715
TimeLineID ThisTimeLineID
Definition: xlog.c:181
#define Assert(condition)
Definition: c.h:732
static XLogCtlData * XLogCtl
Definition: xlog.c:707
XLogRecPtr GetRedoRecPtr(void)
Definition: xlog.c:8355
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:372

◆ issue_xlog_fsync()

void issue_xlog_fsync ( int  fd,
XLogSegNo  segno 
)

Definition at line 10306 of file xlog.c.

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

Referenced by XLogWalRcvFlush(), and XLogWrite().

10307 {
10309  switch (sync_method)
10310  {
10311  case SYNC_METHOD_FSYNC:
10312  if (pg_fsync_no_writethrough(fd) != 0)
10313  ereport(PANIC,
10315  errmsg("could not fsync file \"%s\": %m",
10316  XLogFileNameP(ThisTimeLineID, segno))));
10317  break;
10318 #ifdef HAVE_FSYNC_WRITETHROUGH
10320  if (pg_fsync_writethrough(fd) != 0)
10321  ereport(PANIC,
10323  errmsg("could not fsync write-through file \"%s\": %m",
10324  XLogFileNameP(ThisTimeLineID, segno))));
10325  break;
10326 #endif
10327 #ifdef HAVE_FDATASYNC
10328  case SYNC_METHOD_FDATASYNC:
10329  if (pg_fdatasync(fd) != 0)
10330  ereport(PANIC,
10332  errmsg("could not fdatasync file \"%s\": %m",
10333  XLogFileNameP(ThisTimeLineID, segno))));
10334  break;
10335 #endif
10336  case SYNC_METHOD_OPEN:
10338  /* write synced it already */
10339  break;
10340  default:
10341  elog(PANIC, "unrecognized wal_sync_method: %d", sync_method);
10342  break;
10343  }
10345 }
int pg_fdatasync(int fd)
Definition: fd.c:393
#define SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:28
int pg_fsync_writethrough(int fd)
Definition: fd.c:370
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:358
#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:10351
int errcode_for_file_access(void)
Definition: elog.c:595
#define SYNC_METHOD_FSYNC
Definition: xlog.h:25
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1261
#define ereport(elevel, rest)
Definition: elog.h:141
#define SYNC_METHOD_OPEN
Definition: xlog.h:27
TimeLineID ThisTimeLineID
Definition: xlog.c:181
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1237
int sync_method
Definition: xlog.c:103
#define SYNC_METHOD_FDATASYNC
Definition: xlog.h:26
int errmsg(const char *fmt,...)
Definition: elog.c:786
#define elog(elevel,...)
Definition: elog.h:226

◆ LocalProcessControlFile()

void LocalProcessControlFile ( bool  reset)

Definition at line 4941 of file xlog.c.

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

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

4942 {
4943  Assert(reset || ControlFile == NULL);
4944  ControlFile = palloc(sizeof(ControlFileData));
4945  ReadControlFile();
4946 }
static void ReadControlFile(void)
Definition: xlog.c:4559
static ControlFileData * ControlFile
Definition: xlog.c:715
#define Assert(condition)
Definition: c.h:732
void * palloc(Size size)
Definition: mcxt.c:924

◆ RecoveryInProgress()

bool RecoveryInProgress ( void  )

Definition at line 8082 of file xlog.c.

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

Referenced by BackgroundWriterMain(), brin_desummarize_range(), brin_summarize_range(), check_transaction_read_only(), check_XactIsoLevel(), CheckArchiveTimeout(), CheckLogicalDecodingRequirements(), CheckpointerMain(), CreateCheckPoint(), CreateEndOfRecoveryRecord(), CreateRestartPoint(), do_pg_start_backup(), do_pg_stop_backup(), error_commit_ts_disabled(), get_relation_info(), GetNewMultiXactId(), GetNewObjectId(), GetNewTransactionId(), GetOldestActiveTransactionId(), GetOldestSafeDecodingTransactionId(), GetOldestXmin(), GetRunningTransactionData(), GetSerializableTransactionSnapshot(), GetSerializableTransactionSnapshotInt(), GetSnapshotData(), gin_clean_pending_list(), heap_page_prune_opt(), IdentifySystem(), InitPostgres(), InitTempTableNamespace(), IsCheckpointOnSchedule(), LockAcquireExtended(), MarkBufferDirtyHint(), OldSerXidSetActiveSerXmin(), perform_base_backup(), pg_create_restore_point(), pg_current_wal_flush_lsn(), pg_current_wal_insert_lsn(), pg_current_wal_lsn(), pg_is_in_recovery(), pg_is_wal_replay_paused(), pg_logical_slot_get_changes_guts(), pg_replication_slot_advance(), pg_switch_wal(), pg_wal_replay_pause(), pg_wal_replay_resume(), pg_walfile_name(), pg_walfile_name_offset(), PrepareRedoAdd(), PrepareRedoRemove(), PreventCommandDuringRecovery(), ProcSendSignal(), ProcSleep(), read_local_xlog_page(), ReplicationSlotReserveWal(), replorigin_check_prerequisites(), sendDir(), ShutdownXLOG(), SnapBuildWaitSnapshot(), standard_ProcessUtility(), StartLogicalReplication(), StartTransaction(), TransactionIdIsInProgress(), TruncateMultiXact(), UpdateFullPageWrites(), WalReceiverMain(), WalSndWaitForWal(), XLogArchiveCheckDone(), XLogBackgroundFlush(), XLogInsertAllowed(), XLogNeedsFlush(), and XLogSendPhysical().

8083 {
8084  /*
8085  * We check shared state each time only until we leave recovery mode. We
8086  * can't re-enter recovery, so there's no need to keep checking after the
8087  * shared variable has once been seen false.
8088  */
8090  return false;
8091  else
8092  {
8093  /*
8094  * use volatile pointer to make sure we make a fresh read of the
8095  * shared variable.
8096  */
8097  volatile XLogCtlData *xlogctl = XLogCtl;
8098 
8100 
8101  /*
8102  * Initialize TimeLineID and RedoRecPtr when we discover that recovery
8103  * is finished. InitPostgres() relies upon this behaviour to ensure
8104  * that InitXLOGAccess() is called at backend startup. (If you change
8105  * this, see also LocalSetXLogInsertAllowed.)
8106  */
8108  {
8109  /*
8110  * If we just exited recovery, make sure we read TimeLineID and
8111  * RedoRecPtr after SharedRecoveryInProgress (for machines with
8112  * weak memory ordering).
8113  */
8115  InitXLOGAccess();
8116  }
8117 
8118  /*
8119  * Note: We don't need a memory barrier when we're still in recovery.
8120  * We might exit recovery immediately after return, so the caller
8121  * can't rely on 'true' meaning that we're still in recovery anyway.
8122  */
8123 
8124  return LocalRecoveryInProgress;
8125  }
8126 }
void InitXLOGAccess(void)
Definition: xlog.c:8329
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 6108 of file xlog.c.

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

Referenced by pg_is_wal_replay_paused(), and recoveryPausesHere().

6109 {
6110  bool recoveryPause;
6111 
6113  recoveryPause = XLogCtl->recoveryPause;
6115 
6116  return recoveryPause;
6117 }
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 12425 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, and PROMOTE_SIGNAL_FILE.

Referenced by PostmasterMain().

12426 {
12427  unlink(PROMOTE_SIGNAL_FILE);
12429 }
#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 6120 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().

6121 {
6123  XLogCtl->recoveryPause = recoveryPause;
6125 }
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 12461 of file xlog.c.

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

Referenced by WalWriterMain().

12462 {
12464  XLogCtl->WalWriterSleeping = sleeping;
12466 }
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 8513 of file xlog.c.

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

Referenced by CheckpointerMain(), and InitPostgres().

8514 {
8515  /*
8516  * We should have an aux process resource owner to use, and we should not
8517  * be in a transaction that's installed some other resowner.
8518  */
8520  Assert(CurrentResourceOwner == NULL ||
8523 
8524  /* Don't be chatty in standalone mode */
8526  (errmsg("shutting down")));
8527 
8528  /*
8529  * Signal walsenders to move to stopping state.
8530  */
8532 
8533  /*
8534  * Wait for WAL senders to be in stopping state. This prevents commands
8535  * from writing new WAL.
8536  */
8538 
8539  if (RecoveryInProgress())
8541  else
8542  {
8543  /*
8544  * If archiving is enabled, rotate the last XLOG file so that all the
8545  * remaining records are archived (postmaster wakes up the archiver
8546  * process one more time at the end of shutdown). The checkpoint
8547  * record will go to the next XLOG file and won't be archived (yet).
8548  */
8550  RequestXLogSwitch(false);
8551 
8553  }
8554  ShutdownCLOG();
8555  ShutdownCommitTs();
8556  ShutdownSUBTRANS();
8558 }
bool IsPostmasterEnvironment
Definition: globals.c:107
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9602
void ShutdownSUBTRANS(void)
Definition: subtrans.c:283
void CreateCheckPoint(int flags)
Definition: xlog.c:8729
ResourceOwner CurrentResourceOwner
Definition: resowner.c:141
void ShutdownCLOG(void)
Definition: clog.c:823
bool CreateRestartPoint(int flags)
Definition: xlog.c:9275
#define XLogArchiveCommandSet()
Definition: xlog.h:140
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:8082
ResourceOwner AuxProcessResourceOwner
Definition: resowner.c:144
void WalSndWaitStopping(void)
Definition: walsender.c:3113
void ShutdownMultiXact(void)
Definition: multixact.c:2105
#define ereport(elevel, rest)
Definition: elog.h:141
#define NOTICE
Definition: elog.h:37
void WalSndInitStopping(void)
Definition: walsender.c:3087
void ShutdownCommitTs(void)
Definition: commit_ts.c:744
#define Assert(condition)
Definition: c.h:732
#define XLogArchivingActive()
Definition: xlog.h:135
int errmsg(const char *fmt,...)
Definition: elog.c:786
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:179
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:176

◆ StartupXLOG()

void StartupXLOG ( void  )

Definition at line 6367 of file xlog.c.

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

6368 {
6370  CheckPoint checkPoint;
6371  bool wasShutdown;
6372  bool reachedStopPoint = false;
6373  bool haveBackupLabel = false;
6374  bool haveTblspcMap = false;
6375  XLogRecPtr RecPtr,
6376  checkPointLoc,
6377  EndOfLog;
6378  TimeLineID EndOfLogTLI;
6379  TimeLineID PrevTimeLineID;
6380  XLogRecord *record;
6381  TransactionId oldestActiveXID;
6382  bool backupEndRequired = false;
6383  bool backupFromStandby = false;
6384  DBState dbstate_at_startup;
6385  XLogReaderState *xlogreader;
6386  XLogPageReadPrivate private;
6387  bool fast_promoted = false;
6388  struct stat st;
6389 
6390  /*
6391  * We should have an aux process resource owner to use, and we should not
6392  * be in a transaction that's installed some other resowner.
6393  */
6395  Assert(CurrentResourceOwner == NULL ||
6398 
6399  /*
6400  * Verify XLOG status looks valid.
6401  */
6402  if (ControlFile->state < DB_SHUTDOWNED ||
6405  ereport(FATAL,
6406  (errmsg("control file contains invalid data")));
6407 
6409  {
6410  /* This is the expected case, so don't be chatty in standalone mode */
6412  (errmsg("database system was shut down at %s",
6413  str_time(ControlFile->time))));
6414  }
6416  ereport(LOG,
6417  (errmsg("database system was shut down in recovery at %s",
6418  str_time(ControlFile->time))));
6419  else if (ControlFile->state == DB_SHUTDOWNING)
6420  ereport(LOG,
6421  (errmsg("database system shutdown was interrupted; last known up at %s",
6422  str_time(ControlFile->time))));
6423  else if (ControlFile->state == DB_IN_CRASH_RECOVERY)
6424  ereport(LOG,
6425  (errmsg("database system was interrupted while in recovery at %s",
6427  errhint("This probably means that some data is corrupted and"
6428  " you will have to use the last backup for recovery.")));
6430  ereport(LOG,
6431  (errmsg("database system was interrupted while in recovery at log time %s",
6433  errhint("If this has occurred more than once some data might be corrupted"
6434  " and you might need to choose an earlier recovery target.")));
6435  else if (ControlFile->state == DB_IN_PRODUCTION)
6436  ereport(LOG,
6437  (errmsg("database system was interrupted; last known up at %s",
6438  str_time(ControlFile->time))));
6439 
6440  /* This is just to allow attaching to startup process with a debugger */
6441 #ifdef XLOG_REPLAY_DELAY
6443  pg_usleep(60000000L);
6444 #endif
6445 
6446  /*
6447  * Verify that pg_wal and pg_wal/archive_status exist. In cases where
6448  * someone has performed a copy for PITR, these directories may have been
6449  * excluded and need to be re-created.
6450  */
6452 
6453  /*----------
6454  * If we previously crashed, perform a couple of actions:
6455  * - The pg_wal directory may still include some temporary WAL segments
6456  * used when creating a new segment, so perform some clean up to not
6457  * bloat this path. This is done first as there is no point to sync this
6458  * temporary data.
6459  * - There might be data which we had written, intending to fsync it,
6460  * but which we had not actually fsync'd yet. Therefore, a power failure
6461  * in the near future might cause earlier unflushed writes to be lost,
6462  * even though more recent data written to disk from here on would be
6463  * persisted. To avoid that, fsync the entire data directory.
6464  *---------
6465  */
6466  if (ControlFile->state != DB_SHUTDOWNED &&
6468  {
6471  }
6472 
6473  /*
6474  * Initialize on the assumption we want to recover to the latest timeline
6475  * that's active according to pg_control.
6476  */
6480  else
6482 
6483  /*
6484  * Check for recovery control file, and if so set up state for offline
6485  * recovery
6486  */
6488 
6489  /*
6490  * Save archive_cleanup_command in shared memory so that other processes
6491  * can see it.
6492  */
6495  sizeof(XLogCtl->archiveCleanupCommand));
6496 
6498  {
6500  ereport(LOG,
6501  (errmsg("entering standby mode")));
6502  else if (recoveryTarget == RECOVERY_TARGET_XID)
6503  ereport(LOG,
6504  (errmsg("starting point-in-time recovery to XID %u",
6505  recoveryTargetXid)));
6507  ereport(LOG,
6508  (errmsg("starting point-in-time recovery to %s",
6511  ereport(LOG,
6512  (errmsg("starting point-in-time recovery to \"%s\"",
6513  recoveryTargetName)));
6514  else if (recoveryTarget == RECOVERY_TARGET_LSN)
6515  ereport(LOG,
6516  (errmsg("starting point-in-time recovery to WAL location (LSN) \"%X/%X\"",
6517  (uint32) (recoveryTargetLSN >> 32),
6520  ereport(LOG,
6521  (errmsg("starting point-in-time recovery to earliest consistent point")));
6522  else
6523  ereport(LOG,
6524  (errmsg("starting archive recovery")));
6525  }
6526 
6527  /*
6528  * Take ownership of the wakeup latch if we're going to sleep during
6529  * recovery.
6530  */
6533 
6534  /* Set up XLOG reader facility */
6535  MemSet(&private, 0, sizeof(XLogPageReadPrivate));
6536  xlogreader = XLogReaderAllocate(wal_segment_size, &XLogPageRead, &private);
6537  if (!xlogreader)
6538  ereport(ERROR,
6539  (errcode(ERRCODE_OUT_OF_MEMORY),
6540  errmsg("out of memory"),
6541  errdetail("Failed while allocating a WAL reading processor.")));
6543 
6544  /*
6545  * Allocate two page buffers dedicated to WAL consistency checks. We do
6546  * it this way, rather than just making static arrays, for two reasons:
6547  * (1) no need to waste the storage in most instantiations of the backend;
6548  * (2) a static char array isn't guaranteed to have any particular
6549  * alignment, whereas palloc() will provide MAXALIGN'd storage.
6550  */
6551  replay_image_masked = (char *) palloc(BLCKSZ);
6552  master_image_masked = (char *) palloc(BLCKSZ);
6553 
6554  if (read_backup_label(&checkPointLoc, &backupEndRequired,
6555  &backupFromStandby))
6556  {
6557  List *tablespaces = NIL;
6558 
6559  /*
6560  * Archive recovery was requested, and thanks to the backup label
6561  * file, we know how far we need to replay to reach consistency. Enter
6562  * archive recovery directly.
6563  */
6564  InArchiveRecovery = true;
6566  StandbyMode = true;
6567 
6568  /*
6569  * When a backup_label file is present, we want to roll forward from
6570  * the checkpoint it identifies, rather than using pg_control.
6571  */
6572  record = ReadCheckpointRecord(xlogreader, checkPointLoc, 0, true);
6573  if (record != NULL)
6574  {
6575  memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
6576  wasShutdown = ((record->xl_info & ~XLR_INFO_MASK) == XLOG_CHECKPOINT_SHUTDOWN);
6577  ereport(DEBUG1,
6578  (errmsg("checkpoint record is at %X/%X",
6579  (uint32) (checkPointLoc >> 32), (uint32) checkPointLoc)));
6580  InRecovery = true; /* force recovery even if SHUTDOWNED */
6581 
6582  /*
6583  * Make sure that REDO location exists. This may not be the case
6584  * if there was a crash during an online backup, which left a
6585  * backup_label around that references a WAL segment that's
6586  * already been archived.
6587  */
6588  if (checkPoint.redo < checkPointLoc)
6589  {
6590  if (!ReadRecord(xlogreader, checkPoint.redo, LOG, false))
6591  ereport(FATAL,
6592  (errmsg("could not find redo location referenced by checkpoint record"),
6593  errhint("If you are not restoring from a backup, try removing the file \"%s/backup_label\".", DataDir)));
6594  }
6595  }
6596  else
6597  {
6598  ereport(FATAL,
6599  (errmsg("could not locate required checkpoint record"),
6600  errhint("If you are not restoring from a backup, try removing the file \"%s/backup_label\".", DataDir)));
6601  wasShutdown = false; /* keep compiler quiet */
6602  }
6603 
6604  /* read the tablespace_map file if present and create symlinks. */
6605  if (read_tablespace_map(&tablespaces))
6606  {
6607  ListCell *lc;
6608 
6609  foreach(lc, tablespaces)
6610  {
6611  tablespaceinfo *ti = lfirst(lc);
6612  char *linkloc;
6613 
6614  linkloc = psprintf("pg_tblspc/%s", ti->oid);
6615 
6616  /*
6617  * Remove the existing symlink if any and Create the symlink
6618  * under PGDATA.
6619  */
6620  remove_tablespace_symlink(linkloc);
6621 
6622  if (symlink(ti->path, linkloc) < 0)
6623  ereport(ERROR,
6625  errmsg("could not create symbolic link \"%s\": %m",
6626  linkloc)));
6627 
6628  pfree(ti->oid);
6629  pfree(ti->path);
6630  pfree(ti);
6631  }
6632 
6633  /* set flag to delete it later */
6634  haveTblspcMap = true;
6635  }
6636 
6637  /* set flag to delete it later */
6638  haveBackupLabel = true;
6639  }
6640  else
6641  {
6642  /*
6643  * If tablespace_map file is present without backup_label file, there
6644  * is no use of such file. There is no harm in retaining it, but it
6645  * is better to get rid of the map file so that we don't have any
6646  * redundant file in data directory and it will avoid any sort of
6647  * confusion. It seems prudent though to just rename the file out of
6648  * the way rather than delete it completely, also we ignore any error
6649  * that occurs in rename operation as even if map file is present
6650  * without backup_label file, it is harmless.
6651  */
6652  if (stat(TABLESPACE_MAP, &st) == 0)
6653  {
6654  unlink(TABLESPACE_MAP_OLD);
6656  ereport(LOG,
6657  (errmsg("ignoring file \"%s\" because no file \"%s\" exists",
6659  errdetail("File \"%s\" was renamed to \"%s\".",
6661  else
6662  ereport(LOG,
6663  (errmsg("ignoring file \"%s\" because no file \"%s\" exists",
6665  errdetail("Could not rename file \"%s\" to \"%s\": %m.",
6667  }
6668 
6669  /*
6670  * It's possible that archive recovery was requested, but we don't
6671  * know how far we need to replay the WAL before we reach consistency.
6672  * This can happen for example if a base backup is taken from a
6673  * running server using an atomic filesystem snapshot, without calling
6674  * pg_start/stop_backup. Or if you just kill a running master server
6675  * and put it into archive recovery by creating a recovery.conf file.
6676  *
6677  * Our strategy in that case is to perform crash recovery first,
6678  * replaying all the WAL present in pg_wal, and only enter archive
6679  * recovery after that.
6680  *
6681  * But usually we already know how far we need to replay the WAL (up
6682  * to minRecoveryPoint, up to backupEndPoint, or until we see an
6683  * end-of-backup record), and we can enter archive recovery directly.
6684  */
6690  {
6691  InArchiveRecovery = true;
6693  StandbyMode = true;
6694  }
6695 
6696  /* Get the last valid checkpoint record. */
6697  checkPointLoc = ControlFile->checkPoint;
6699  record = ReadCheckpointRecord(xlogreader, checkPointLoc, 1, true);
6700  if (record != NULL)
6701  {
6702  ereport(DEBUG1,
6703  (errmsg("checkpoint record is at %X/%X",
6704  (uint32) (checkPointLoc >> 32), (uint32) checkPointLoc)));
6705  }
6706  else
6707  {
6708  /*
6709  * We used to attempt to go back to a secondary checkpoint record
6710  * here, but only when not in standby_mode. We now just fail if we
6711  * can't read the last checkpoint because this allows us to
6712  * simplify processing around checkpoints.
6713  */
6714  ereport(PANIC,
6715  (errmsg("could not locate a valid checkpoint record")));
6716  }
6717  memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
6718  wasShutdown = ((record->xl_info & ~XLR_INFO_MASK) == XLOG_CHECKPOINT_SHUTDOWN);
6719  }
6720 
6721  /*
6722  * Clear out any old relcache cache files. This is *necessary* if we do
6723  * any WAL replay, since that would probably result in the cache files
6724  * being out of sync with database reality. In theory we could leave them
6725  * in place if the database had been cleanly shut down, but it seems
6726  * safest to just remove them always and let them be rebuilt during the
6727  * first backend startup. These files needs to be removed from all
6728  * directories including pg_tblspc, however the symlinks are created only
6729  * after reading tablespace_map file in case of archive recovery from
6730  * backup, so needs to clear old relcache files here after creating
6731  * symlinks.
6732  */
6734 
6735  /*
6736  * If the location of the checkpoint record is not on the expected
6737  * timeline in the history of the requested timeline, we cannot proceed:
6738  * the backup is not part of the history of the requested timeline.
6739  */
6740  Assert(expectedTLEs); /* was initialized by reading checkpoint
6741  * record */
6742  if (tliOfPointInHistory(checkPointLoc, expectedTLEs) !=
6743  checkPoint.ThisTimeLineID)
6744  {
6745  XLogRecPtr switchpoint;
6746 
6747  /*
6748  * tliSwitchPoint will throw an error if the checkpoint's timeline is
6749  * not in expectedTLEs at all.
6750  */
6752  ereport(FATAL,
6753  (errmsg("requested timeline %u is not a child of this server's history",
6755  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.",
6756  (uint32) (ControlFile->checkPoint >> 32),
6759  (uint32) (switchpoint >> 32),
6760  (uint32) switchpoint)));
6761  }
6762 
6763  /*
6764  * The min recovery point should be part of the requested timeline's
6765  * history, too.
6766  */
6770  ereport(FATAL,
6771  (errmsg("requested timeline %u does not contain minimum recovery point %X/%X on timeline %u",
6773  (uint32) (ControlFile->minRecoveryPoint >> 32),
6776 
6777  LastRec = RecPtr = checkPointLoc;
6778 
6779  ereport(DEBUG1,
6780  (errmsg_internal("redo record is at %X/%X; shutdown %s",
6781  (uint32) (checkPoint.redo >> 32), (uint32) checkPoint.redo,
6782  wasShutdown ? "true" : "false")));
6783  ereport(DEBUG1,
6784  (errmsg_internal("next transaction ID: %u:%u; next OID: %u",
6785  checkPoint.nextXidEpoch, checkPoint.nextXid,
6786  checkPoint.nextOid)));
6787  ereport(DEBUG1,
6788  (errmsg_internal("next MultiXactId: %u; next MultiXactOffset: %u",
6789  checkPoint.nextMulti, checkPoint.nextMultiOffset)));
6790  ereport(DEBUG1,
6791  (errmsg_internal("oldest unfrozen transaction ID: %u, in database %u",
6792  checkPoint.oldestXid, checkPoint.oldestXidDB)));
6793  ereport(DEBUG1,
6794  (errmsg_internal("oldest MultiXactId: %u, in database %u",
6795  checkPoint.oldestMulti, checkPoint.oldestMultiDB)));
6796  ereport(DEBUG1,
6797  (errmsg_internal("commit timestamp Xid oldest/newest: %u/%u",
6798  checkPoint.oldestCommitTsXid,
6799  checkPoint.newestCommitTsXid)));
6800  if (!TransactionIdIsNormal(checkPoint.nextXid))
6801  ereport(PANIC,
6802  (errmsg("invalid next transaction ID")));
6803 
6804  /* initialize shared memory variables from the checkpoint record */
6805  ShmemVariableCache->nextXid = checkPoint.nextXid;
6806  ShmemVariableCache->nextOid = checkPoint.nextOid;
6808  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
6809  AdvanceOldestClogXid(checkPoint.oldestXid);
6810  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
6811  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
6813  checkPoint.newestCommitTsXid);
6814  XLogCtl->ckptXidEpoch = checkPoint.nextXidEpoch;
6815  XLogCtl->ckptXid = checkPoint.nextXid;
6816 
6817  /*
6818  * Initialize replication slots, before there's a chance to remove
6819  * required resources.
6820  */
6822 
6823  /*
6824  * Startup logical state, needs to be setup now so we have proper data
6825  * during crash recovery.
6826  */
6828 
6829  /*
6830  * Startup MultiXact. We need to do this early to be able to replay
6831  * truncations.
6832  */
6833  StartupMultiXact();
6834 
6835  /*
6836  * Ditto for commit timestamps. Activate the facility if the setting is
6837  * enabled in the control file, as there should be no tracking of commit
6838  * timestamps done when the setting was disabled. This facility can be
6839  * started or stopped when replaying a XLOG_PARAMETER_CHANGE record.
6840  */
6842  StartupCommitTs();
6843 
6844  /*
6845  * Recover knowledge about replay progress of known replication partners.
6846  */
6848