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

Go to the source code of this file.

Data Structures

struct  CheckpointStatsData
 

Macros

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

Typedefs

typedef enum ArchiveMode ArchiveMode
 
typedef enum WalLevel WalLevel
 
typedef struct CheckpointStatsData CheckpointStatsData
 
typedef enum SessionBackupState SessionBackupState
 

Enumerations

enum  HotStandbyState { STANDBY_DISABLED, STANDBY_INITIALIZED, STANDBY_SNAPSHOT_PENDING, STANDBY_SNAPSHOT_READY }
 
enum  RecoveryTargetType {
  RECOVERY_TARGET_UNSET, RECOVERY_TARGET_XID, RECOVERY_TARGET_TIME, RECOVERY_TARGET_NAME,
  RECOVERY_TARGET_LSN, RECOVERY_TARGET_IMMEDIATE
}
 
enum  ArchiveMode { ARCHIVE_MODE_OFF = 0, ARCHIVE_MODE_ON, ARCHIVE_MODE_ALWAYS }
 
enum  WalLevel { WAL_LEVEL_MINIMAL = 0, WAL_LEVEL_REPLICA, WAL_LEVEL_LOGICAL }
 
enum  SessionBackupState { SESSION_BACKUP_NONE, SESSION_BACKUP_EXCLUSIVE, SESSION_BACKUP_NON_EXCLUSIVE }
 

Functions

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

Variables

int sync_method
 
PGDLLIMPORT TimeLineID ThisTimeLineID
 
bool InRecovery
 
HotStandbyState standbyState
 
XLogRecPtr ProcLastRecPtr
 
XLogRecPtr XactLastRecEnd
 
PGDLLIMPORT XLogRecPtr XactLastCommitEnd
 
bool reachedConsistency
 
int wal_segment_size
 
int min_wal_size_mb
 
int max_wal_size_mb
 
int wal_keep_segments
 
int XLOGbuffers
 
int XLogArchiveTimeout
 
int wal_retrieve_retry_interval
 
char * XLogArchiveCommand
 
bool EnableHotStandby
 
bool fullPageWrites
 
bool wal_log_hints
 
bool wal_compression
 
boolwal_consistency_checking
 
char * wal_consistency_checking_string
 
bool log_checkpoints
 
int CheckPointSegments
 
int XLogArchiveMode
 
PGDLLIMPORT int wal_level
 
CheckpointStatsData CheckpointStats
 

Macro Definition Documentation

◆ BACKUP_LABEL_FILE

#define BACKUP_LABEL_FILE   "backup_label"

◆ BACKUP_LABEL_OLD

#define BACKUP_LABEL_OLD   "backup_label.old"

Definition at line 323 of file xlog.h.

Referenced by CancelBackup(), and StartupXLOG().

◆ CHECKPOINT_CAUSE_TIME

#define CHECKPOINT_CAUSE_TIME   0x0080 /* Elapsed time */

Definition at line 187 of file xlog.h.

Referenced by CheckpointerMain(), and LogCheckpointStart().

◆ CHECKPOINT_CAUSE_XLOG

#define CHECKPOINT_CAUSE_XLOG   0x0040 /* XLOG consumption */

Definition at line 186 of file xlog.h.

Referenced by CheckpointerMain(), LogCheckpointStart(), XLogPageRead(), and XLogWrite().

◆ CHECKPOINT_END_OF_RECOVERY

#define CHECKPOINT_END_OF_RECOVERY
Value:
0x0002 /* Like shutdown checkpoint, but
* issued at end of WAL recovery */

Definition at line 177 of file xlog.h.

Referenced by BufferSync(), CheckpointerMain(), CreateCheckPoint(), LogCheckpointStart(), and StartupXLOG().

◆ CHECKPOINT_FLUSH_ALL

#define CHECKPOINT_FLUSH_ALL
Value:
0x0010 /* Flush all pages, including those
* belonging to unlogged tables */

Definition at line 181 of file xlog.h.

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

◆ CHECKPOINT_FORCE

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

◆ CHECKPOINT_IMMEDIATE

◆ CHECKPOINT_IS_SHUTDOWN

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

◆ CHECKPOINT_WAIT

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

◆ InHotStandby

◆ SYNC_METHOD_FDATASYNC

#define SYNC_METHOD_FDATASYNC   1

Definition at line 26 of file xlog.h.

Referenced by get_sync_bit(), and issue_xlog_fsync().

◆ SYNC_METHOD_FSYNC

#define SYNC_METHOD_FSYNC   0

Definition at line 25 of file xlog.h.

Referenced by get_sync_bit(), and issue_xlog_fsync().

◆ SYNC_METHOD_FSYNC_WRITETHROUGH

#define SYNC_METHOD_FSYNC_WRITETHROUGH   3

Definition at line 28 of file xlog.h.

Referenced by get_sync_bit(), issue_xlog_fsync(), and pg_fsync().

◆ SYNC_METHOD_OPEN

#define SYNC_METHOD_OPEN   2 /* for O_SYNC */

Definition at line 27 of file xlog.h.

Referenced by get_sync_bit(), issue_xlog_fsync(), and XLogWrite().

◆ SYNC_METHOD_OPEN_DSYNC

#define SYNC_METHOD_OPEN_DSYNC   4 /* for O_DSYNC */

Definition at line 29 of file xlog.h.

Referenced by get_sync_bit(), issue_xlog_fsync(), and XLogWrite().

◆ TABLESPACE_MAP

#define TABLESPACE_MAP   "tablespace_map"

◆ TABLESPACE_MAP_OLD

#define TABLESPACE_MAP_OLD   "tablespace_map.old"

Definition at line 326 of file xlog.h.

Referenced by CancelBackup(), and StartupXLOG().

◆ XLOG_INCLUDE_ORIGIN

#define XLOG_INCLUDE_ORIGIN   0x01 /* include the replication origin */

◆ XLOG_MARK_UNIMPORTANT

#define XLOG_MARK_UNIMPORTANT   0x02 /* record not important for durability */

◆ XLogArchiveCommandSet

#define XLogArchiveCommandSet ( )    (XLogArchiveCommand[0] != '\0')

Definition at line 140 of file xlog.h.

Referenced by pgarch_ArchiverCopyLoop(), and ShutdownXLOG().

◆ XLogArchivingActive

◆ XLogArchivingAlways

Definition at line 138 of file xlog.h.

Referenced by do_pg_stop_backup(), and sigusr1_handler().

◆ XLogHintBitIsNeeded

◆ XLogIsNeeded

◆ XLogLogicalInfoActive

#define XLogLogicalInfoActive ( )    (wal_level >= WAL_LEVEL_LOGICAL)

◆ 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 2279 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

2280 {
2283 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2243
#define newval
double CheckPointCompletionTarget
Definition: checkpointer.c:147

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2272 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

2273 {
2276 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2243
int max_wal_size_mb
Definition: xlog.c:89
#define newval

◆ BootStrapXLOG()

void BootStrapXLOG ( void  )

Definition at line 5085 of file xlog.c.

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

5086 {
5087  CheckPoint checkPoint;
5088  char *buffer;
5089  XLogPageHeader page;
5090  XLogLongPageHeader longpage;
5091  XLogRecord *record;
5092  char *recptr;
5093  bool use_existent;
5094  uint64 sysidentifier;
5095  char mock_auth_nonce[MOCK_AUTH_NONCE_LEN];
5096  struct timeval tv;
5097  pg_crc32c crc;
5098 
5099  /*
5100  * Select a hopefully-unique system identifier code for this installation.
5101  * We use the result of gettimeofday(), including the fractional seconds
5102  * field, as being about as unique as we can easily get. (Think not to
5103  * use random(), since it hasn't been seeded and there's no portable way
5104  * to seed it other than the system clock value...) The upper half of the
5105  * uint64 value is just the tv_sec part, while the lower half contains the
5106  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
5107  * PID for a little extra uniqueness. A person knowing this encoding can
5108  * determine the initialization time of the installation, which could
5109  * perhaps be useful sometimes.
5110  */
5111  gettimeofday(&tv, NULL);
5112  sysidentifier = ((uint64) tv.tv_sec) << 32;
5113  sysidentifier |= ((uint64) tv.tv_usec) << 12;
5114  sysidentifier |= getpid() & 0xFFF;
5115 
5116  /*
5117  * Generate a random nonce. This is used for authentication requests that
5118  * will fail because the user does not exist. The nonce is used to create
5119  * a genuine-looking password challenge for the non-existent user, in lieu
5120  * of an actual stored password.
5121  */
5122  if (!pg_backend_random(mock_auth_nonce, MOCK_AUTH_NONCE_LEN))
5123  ereport(PANIC,
5124  (errcode(ERRCODE_INTERNAL_ERROR),
5125  errmsg("could not generate secret authorization token")));
5126 
5127  /* First timeline ID is always 1 */
5128  ThisTimeLineID = 1;
5129 
5130  /* page buffer must be aligned suitably for O_DIRECT */
5131  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
5132  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
5133  memset(page, 0, XLOG_BLCKSZ);
5134 
5135  /*
5136  * Set up information for the initial checkpoint record
5137  *
5138  * The initial checkpoint record is written to the beginning of the WAL
5139  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5140  * used, so that we can use 0/0 to mean "before any valid WAL segment".
5141  */
5142  checkPoint.redo = wal_segment_size + SizeOfXLogLongPHD;
5143  checkPoint.ThisTimeLineID = ThisTimeLineID;
5144  checkPoint.PrevTimeLineID = ThisTimeLineID;
5145  checkPoint.fullPageWrites = fullPageWrites;
5146  checkPoint.nextXidEpoch = 0;
5147  checkPoint.nextXid = FirstNormalTransactionId;
5148  checkPoint.nextOid = FirstBootstrapObjectId;
5149  checkPoint.nextMulti = FirstMultiXactId;
5150  checkPoint.nextMultiOffset = 0;
5151  checkPoint.oldestXid = FirstNormalTransactionId;
5152  checkPoint.oldestXidDB = TemplateDbOid;
5153  checkPoint.oldestMulti = FirstMultiXactId;
5154  checkPoint.oldestMultiDB = TemplateDbOid;
5157  checkPoint.time = (pg_time_t) time(NULL);
5159 
5160  ShmemVariableCache->nextXid = checkPoint.nextXid;
5161  ShmemVariableCache->nextOid = checkPoint.nextOid;
5163  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5164  AdvanceOldestClogXid(checkPoint.oldestXid);
5165  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5166  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5168 
5169  /* Set up the XLOG page header */
5170  page->xlp_magic = XLOG_PAGE_MAGIC;
5171  page->xlp_info = XLP_LONG_HEADER;
5172  page->xlp_tli = ThisTimeLineID;
5174  longpage = (XLogLongPageHeader) page;
5175  longpage->xlp_sysid = sysidentifier;
5176  longpage->xlp_seg_size = wal_segment_size;
5177  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5178 
5179  /* Insert the initial checkpoint record */
5180  recptr = ((char *) page + SizeOfXLogLongPHD);
5181  record = (XLogRecord *) recptr;
5182  record->xl_prev = 0;
5183  record->xl_xid = InvalidTransactionId;
5184  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5186  record->xl_rmid = RM_XLOG_ID;
5187  recptr += SizeOfXLogRecord;
5188  /* fill the XLogRecordDataHeaderShort struct */
5189  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5190  *(recptr++) = sizeof(checkPoint);
5191  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5192  recptr += sizeof(checkPoint);
5193  Assert(recptr - (char *) record == record->xl_tot_len);
5194 
5195  INIT_CRC32C(crc);
5196  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5197  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5198  FIN_CRC32C(crc);
5199  record->xl_crc = crc;
5200 
5201  /* Create first XLOG segment file */
5202  use_existent = false;
5203  openLogFile = XLogFileInit(1, &use_existent, false);
5204 
5205  /* Write the first page with the initial record */
5206  errno = 0;
5208  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5209  {
5210  /* if write didn't set errno, assume problem is no disk space */
5211  if (errno == 0)
5212  errno = ENOSPC;
5213  ereport(PANIC,
5215  errmsg("could not write bootstrap write-ahead log file: %m")));
5216  }
5218 
5220  if (pg_fsync(openLogFile) != 0)
5221  ereport(PANIC,
5223  errmsg("could not fsync bootstrap write-ahead log file: %m")));
5225 
5226  if (close(openLogFile))
5227  ereport(PANIC,
5229  errmsg("could not close bootstrap write-ahead log file: %m")));
5230 
5231  openLogFile = -1;
5232 
5233  /* Now create pg_control */
5234 
5235  memset(ControlFile, 0, sizeof(ControlFileData));
5236  /* Initialize pg_control status fields */
5237  ControlFile->system_identifier = sysidentifier;
5238  memcpy(ControlFile->mock_authentication_nonce, mock_auth_nonce, MOCK_AUTH_NONCE_LEN);
5240  ControlFile->time = checkPoint.time;
5241  ControlFile->checkPoint = checkPoint.redo;
5242  ControlFile->checkPointCopy = checkPoint;
5243  ControlFile->unloggedLSN = 1;
5244 
5245  /* Set important parameter values for use when replaying WAL */
5254 
5255  /* some additional ControlFile fields are set in WriteControlFile() */
5256 
5257  WriteControlFile();
5258 
5259  /* Bootstrap the commit log, too */
5260  BootStrapCLOG();
5264 
5265  pfree(buffer);
5266 
5267  /*
5268  * Force control file to be read - in contrast to normal processing we'd
5269  * otherwise never run the checks and GUC related initializations therein.
5270  */
5271  ReadControlFile();
5272 }
static void WriteControlFile(void)
Definition: xlog.c:4446
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
int max_locks_per_xact
Definition: pg_control.h:181
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:105
int max_prepared_xacts
Definition: pg_control.h:180
int64 pg_time_t
Definition: pgtime.h:23
int wal_segment_size
Definition: xlog.c:113
pg_time_t time
Definition: pg_control.h:128
void SetCommitTsLimit(TransactionId oldestXact, TransactionId newestXact)
Definition: commit_ts.c:849
uint32 oidCount
Definition: transam.h:112
#define write(a, b, c)
Definition: win32.h:14
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:201
int max_worker_processes
Definition: pg_control.h:179
uint32 pg_crc32c
Definition: pg_crc32c.h:38
TransactionId oldestActiveXid
Definition: pg_control.h:63
int wal_level
Definition: xlog.c:104
int XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
Definition: xlog.c:3190
void BootStrapMultiXact(void)
Definition: multixact.c:1866
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: pg_control.h:39
int errcode(int sqlerrcode)
Definition: elog.c:575
RmgrId xl_rmid
Definition: xlogrecord.h:47
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:57
CheckPoint checkPointCopy
Definition: pg_control.h:131
TransactionId oldestXid
Definition: pg_control.h:47
TransactionId nextXid
Definition: pg_control.h:43
pg_time_t time
Definition: pg_control.h:51
#define PANIC
Definition: elog.h:53
uint32 bootstrap_data_checksum_version
Definition: bootstrap.c:50
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:74
#define MOCK_AUTH_NONCE_LEN
Definition: pg_control.h:27
bool fullPageWrites
Definition: xlog.c:97
void BootStrapSUBTRANS(void)
Definition: subtrans.c:212
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid)
Definition: varsup.c:271
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
void pfree(void *pointer)
Definition: mcxt.c: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:4538
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:598
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define InvalidTransactionId
Definition: transam.h:31
#define FirstBootstrapObjectId
Definition: transam.h:93
static void pgstat_report_wait_end(void)
Definition: pgstat.h: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:645
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:699
#define XLP_LONG_HEADER
Definition: xlog_internal.h:79
Oid oldestXidDB
Definition: pg_control.h:48
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h: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:797
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:622
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset)
Definition: multixact.c:2160

◆ CheckPromoteSignal()

bool CheckPromoteSignal ( void  )

Definition at line 12403 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, PROMOTE_SIGNAL_FILE, and stat.

Referenced by sigusr1_handler().

12404 {
12405  struct stat stat_buf;
12406 
12407  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
12409  return true;
12410 
12411  return false;
12412 }
#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 3810 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().

3811 {
3812  int save_errno = errno;
3813  XLogSegNo lastRemovedSegNo;
3814 
3816  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3818 
3819  if (segno <= lastRemovedSegNo)
3820  {
3821  char filename[MAXFNAMELEN];
3822 
3823  XLogFileName(filename, tli, segno, wal_segment_size);
3824  errno = save_errno;
3825  ereport(ERROR,
3827  errmsg("requested WAL segment %s has already been removed",
3828  filename)));
3829  }
3830  errno = save_errno;
3831 }
int wal_segment_size
Definition: xlog.c:113
slock_t info_lck
Definition: xlog.c:704
XLogSegNo lastRemovedSegNo
Definition: xlog.c:587
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define ERROR
Definition: elog.h:43
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h: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:797

◆ CreateCheckPoint()

void CreateCheckPoint ( int  flags)

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

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

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

◆ DataChecksumsEnabled()

bool DataChecksumsEnabled ( void  )

Definition at line 4820 of file xlog.c.

References Assert, and ControlFileData::data_checksum_version.

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

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

◆ do_pg_abort_backup()

void do_pg_abort_backup ( void  )

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

11288 {
11289  /*
11290  * Quick exit if session is not keeping around a non-exclusive backup
11291  * already started.
11292  */
11294  return;
11295 
11300 
11303  {
11304  XLogCtl->Insert.forcePageWrites = false;
11305  }
11307 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1678
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:699
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1649
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 10365 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().

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

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

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

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

◆ get_backup_status()

SessionBackupState get_backup_status ( void  )

Definition at line 10863 of file xlog.c.

References sessionBackupState.

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

10864 {
10865  return sessionBackupState;
10866 }
static SessionBackupState sessionBackupState
Definition: xlog.c:512

◆ GetCurrentChunkReplayStartTime()

TimestampTz GetCurrentChunkReplayStartTime ( void  )

Definition at line 6248 of file xlog.c.

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

Referenced by GetReplicationApplyDelay().

6249 {
6250  TimestampTz xtime;
6251 
6253  xtime = XLogCtl->currentChunkStartTime;
6255 
6256  return xtime;
6257 }
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 4836 of file xlog.c.

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

Referenced by gistGetFakeLSN().

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

8390 {
8394 
8395  return LogwrtResult.Flush;
8396 }
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 8358 of file xlog.c.

References doPageWrites, and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

8359 {
8360  *RedoRecPtr_p = RedoRecPtr;
8361  *doPageWrites_p = doPageWrites;
8362 }
static bool doPageWrites
Definition: xlog.c:359
static XLogRecPtr RedoRecPtr
Definition: xlog.c:352

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )

Definition at line 8373 of file xlog.c.

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

Referenced by CheckpointerMain(), and IsCheckpointOnSchedule().

8374 {
8375  XLogRecPtr recptr;
8376 
8378  recptr = XLogCtl->LogwrtRqst.Write;
8380 
8381  return recptr;
8382 }
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 8407 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().

8408 {
8410  int i;
8411 
8412  for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
8413  {
8414  XLogRecPtr last_important;
8415 
8416  /*
8417  * Need to take a lock to prevent torn reads of the LSN, which are
8418  * possible on some of the supported platforms. WAL insert locks only
8419  * support exclusive mode, so we have to use that.
8420  */
8422  last_important = WALInsertLocks[i].l.lastImportantAt;
8423  LWLockRelease(&WALInsertLocks[i].l.lock);
8424 
8425  if (res < last_important)
8426  res = last_important;
8427  }
8428 
8429  return res;
8430 }
#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 6218 of file xlog.c.

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

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

6219 {
6220  TimestampTz xtime;
6221 
6223  xtime = XLogCtl->recoveryLastXTime;
6225 
6226  return xtime;
6227 }
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 4810 of file xlog.c.

References Assert, and ControlFileData::mock_authentication_nonce.

Referenced by scram_mock_salt().

4811 {
4812  Assert(ControlFile != NULL);
4814 }
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:699

◆ GetNextXidAndEpoch()

void GetNextXidAndEpoch ( TransactionId xid,
uint32 epoch 
)

Definition at line 8458 of file xlog.c.

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

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

8459 {
8460  uint32 ckptXidEpoch;
8461  TransactionId ckptXid;
8462  TransactionId nextXid;
8463 
8464  /* Must read checkpoint info first, else have race condition */
8466  ckptXidEpoch = XLogCtl->ckptXidEpoch;
8467  ckptXid = XLogCtl->ckptXid;
8469 
8470  /* Now fetch current nextXid */
8471  nextXid = ReadNewTransactionId();
8472 
8473  /*
8474  * nextXid is certainly logically later than ckptXid. So if it's
8475  * numerically less, it must have wrapped into the next epoch.
8476  */
8477  if (nextXid < ckptXid)
8478  ckptXidEpoch++;
8479 
8480  *xid = nextXid;
8481  *epoch = ckptXidEpoch;
8482 }
TransactionId ckptXid
Definition: xlog.c:583
uint32 TransactionId
Definition: c.h:474
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:325
#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 8330 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().

8331 {
8332  XLogRecPtr ptr;
8333 
8334  /*
8335  * The possibly not up-to-date copy in XlogCtl is enough. Even if we
8336  * grabbed a WAL insertion lock to read the master copy, someone might
8337  * update it just after we've released the lock.
8338  */
8340  ptr = XLogCtl->RedoRecPtr;
8342 
8343  if (RedoRecPtr < ptr)
8344  RedoRecPtr = ptr;
8345 
8346  return RedoRecPtr;
8347 }
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 4800 of file xlog.c.

References Assert, and ControlFileData::system_identifier.

Referenced by IdentifySystem(), and WalReceiverMain().

4801 {
4802  Assert(ControlFile != NULL);
4804 }
uint64 system_identifier
Definition: pg_control.h:106
static ControlFileData * ControlFile
Definition: xlog.c:715
#define Assert(condition)
Definition: c.h:699

◆ GetXLogInsertRecPtr()

XLogRecPtr GetXLogInsertRecPtr ( void  )

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

11335 {
11337  uint64 current_bytepos;
11338 
11339  SpinLockAcquire(&Insert->insertpos_lck);
11340  current_bytepos = Insert->CurrBytePos;
11341  SpinLockRelease(&Insert->insertpos_lck);
11342 
11343  return XLogBytePosToRecPtr(current_bytepos);
11344 }
slock_t insertpos_lck
Definition: xlog.c:519
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1947
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 6264 of file xlog.c.

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

Referenced by GetStandbyLimitTime().

6265 {
6266  /*
6267  * This must be executed in the startup process, since we don't export the
6268  * relevant state to shared memory.
6269  */
6270  Assert(InRecovery);
6271 
6272  *rtime = XLogReceiptTime;
6273  *fromStream = (XLogReceiptSource == XLOG_FROM_STREAM);
6274 }
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:699

◆ GetXLogReplayRecPtr()

XLogRecPtr GetXLogReplayRecPtr ( TimeLineID replayTLI)

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

11316 {
11317  XLogRecPtr recptr;
11318  TimeLineID tli;
11319 
11321  recptr = XLogCtl->lastReplayedEndRecPtr;
11322  tli = XLogCtl->lastReplayedTLI;
11324 
11325  if (replayTLI)
11326  *replayTLI = tli;
11327  return recptr;
11328 }
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 11350 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().

11351 {
11355 
11356  return LogwrtResult.Write;
11357 }
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 8113 of file xlog.c.

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

Referenced by XLogWalRcvSendHSFeedback().

8114 {
8115  /*
8116  * We check shared state each time only until Hot Standby is active. We
8117  * can't de-activate Hot Standby, so there's no need to keep checking
8118  * after the shared variable has once been seen true.
8119  */
8121  return true;
8122  else
8123  {
8124  /* spinlock is essential on machines with weak memory ordering! */
8128 
8129  return LocalHotStandbyActive;
8130  }
8131 }
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 8138 of file xlog.c.

References AmStartupProcess, Assert, IsPostmasterEnvironment, and LocalHotStandbyActive.

Referenced by btree_xlog_vacuum().

8139 {
8141  return LocalHotStandbyActive;
8142 }
#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:699

◆ InitXLOGAccess()

void InitXLOGAccess ( void  )

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

8305 {
8307 
8308  /* ThisTimeLineID doesn't change so we need no lock to copy it */
8311 
8312  /* set wal_segment_size */
8314 
8315  /* Use GetRedoRecPtr to copy the RedoRecPtr safely */
8316  (void) GetRedoRecPtr();
8317  /* Also update our copy of doPageWrites. */
8318  doPageWrites = (Insert->fullPageWrites || Insert->forcePageWrites);
8319 
8320  /* Also initialize the working areas for constructing WAL records */
8321  InitXLogInsert();
8322 }
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:699
static XLogCtlData * XLogCtl
Definition: xlog.c:707
XLogRecPtr GetRedoRecPtr(void)
Definition: xlog.c:8330
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:372

◆ issue_xlog_fsync()

void issue_xlog_fsync ( int  fd,
XLogSegNo  segno 
)

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

10274 {
10276  switch (sync_method)
10277  {
10278  case SYNC_METHOD_FSYNC:
10279  if (pg_fsync_no_writethrough(fd) != 0)
10280  ereport(PANIC,
10282  errmsg("could not fsync file \"%s\": %m",
10283  XLogFileNameP(ThisTimeLineID, segno))));
10284  break;
10285 #ifdef HAVE_FSYNC_WRITETHROUGH
10287  if (pg_fsync_writethrough(fd) != 0)
10288  ereport(PANIC,
10290  errmsg("could not fsync write-through file \"%s\": %m",
10291  XLogFileNameP(ThisTimeLineID, segno))));
10292  break;
10293 #endif
10294 #ifdef HAVE_FDATASYNC
10295  case SYNC_METHOD_FDATASYNC:
10296  if (pg_fdatasync(fd) != 0)
10297  ereport(PANIC,
10299  errmsg("could not fdatasync file \"%s\": %m",
10300  XLogFileNameP(ThisTimeLineID, segno))));
10301  break;
10302 #endif
10303  case SYNC_METHOD_OPEN:
10305  /* write synced it already */
10306  break;
10307  default:
10308  elog(PANIC, "unrecognized wal_sync_method: %d", sync_method);
10309  break;
10310  }
10312 }
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:10318
int errcode_for_file_access(void)
Definition: elog.c:598
#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:797
#define elog
Definition: elog.h:240

◆ LocalProcessControlFile()

void LocalProcessControlFile ( bool  reset)

Definition at line 4920 of file xlog.c.

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

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

4921 {
4922  Assert(reset || ControlFile == NULL);
4923  ControlFile = palloc(sizeof(ControlFileData));
4924  ReadControlFile();
4925 }
static void ReadControlFile(void)
Definition: xlog.c:4538
static ControlFileData * ControlFile
Definition: xlog.c:715
#define Assert(condition)
Definition: c.h:699
void * palloc(Size size)
Definition: mcxt.c:924

◆ RecoveryInProgress()

bool RecoveryInProgress ( void  )

Definition at line 8057 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(), XLogBackgroundFlush(), XLogInsertAllowed(), XLogNeedsFlush(), and XLogSendPhysical().

8058 {
8059  /*
8060  * We check shared state each time only until we leave recovery mode. We
8061  * can't re-enter recovery, so there's no need to keep checking after the
8062  * shared variable has once been seen false.
8063  */
8065  return false;
8066  else
8067  {
8068  /*
8069  * use volatile pointer to make sure we make a fresh read of the
8070  * shared variable.
8071  */
8072  volatile XLogCtlData *xlogctl = XLogCtl;
8073 
8075 
8076  /*
8077  * Initialize TimeLineID and RedoRecPtr when we discover that recovery
8078  * is finished. InitPostgres() relies upon this behaviour to ensure
8079  * that InitXLOGAccess() is called at backend startup. (If you change
8080  * this, see also LocalSetXLogInsertAllowed.)
8081  */
8083  {
8084  /*
8085  * If we just exited recovery, make sure we read TimeLineID and
8086  * RedoRecPtr after SharedRecoveryInProgress (for machines with
8087  * weak memory ordering).
8088  */
8090  InitXLOGAccess();
8091  }
8092 
8093  /*
8094  * Note: We don't need a memory barrier when we're still in recovery.
8095  * We might exit recovery immediately after return, so the caller
8096  * can't rely on 'true' meaning that we're still in recovery anyway.
8097  */
8098 
8099  return LocalRecoveryInProgress;
8100  }
8101 }
void InitXLOGAccess(void)
Definition: xlog.c:8304
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 6087 of file xlog.c.

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

Referenced by pg_is_wal_replay_paused(), and recoveryPausesHere().

6088 {
6089  bool recoveryPause;
6090 
6092  recoveryPause = XLogCtl->recoveryPause;
6094 
6095  return recoveryPause;
6096 }
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 12392 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, and PROMOTE_SIGNAL_FILE.

Referenced by PostmasterMain().

12393 {
12394  unlink(PROMOTE_SIGNAL_FILE);
12396 }
#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 6099 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().

6100 {
6102  XLogCtl->recoveryPause = recoveryPause;
6104 }
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 12428 of file xlog.c.

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

Referenced by WalWriterMain().

12429 {
12431  XLogCtl->WalWriterSleeping = sleeping;
12433 }
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 8488 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().

8489 {
8490  /*
8491  * We should have an aux process resource owner to use, and we should not
8492  * be in a transaction that's installed some other resowner.
8493  */
8495  Assert(CurrentResourceOwner == NULL ||
8498 
8499  /* Don't be chatty in standalone mode */
8501  (errmsg("shutting down")));
8502 
8503  /*
8504  * Signal walsenders to move to stopping state.
8505  */
8507 
8508  /*
8509  * Wait for WAL senders to be in stopping state. This prevents commands
8510  * from writing new WAL.
8511  */
8513 
8514  if (RecoveryInProgress())
8516  else
8517  {
8518  /*
8519  * If archiving is enabled, rotate the last XLOG file so that all the
8520  * remaining records are archived (postmaster wakes up the archiver
8521  * process one more time at the end of shutdown). The checkpoint
8522  * record will go to the next XLOG file and won't be archived (yet).
8523  */
8525  RequestXLogSwitch(false);
8526 
8528  }
8529  ShutdownCLOG();
8530  ShutdownCommitTs();
8531  ShutdownSUBTRANS();
8533 }
bool IsPostmasterEnvironment
Definition: globals.c:107
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9577
void ShutdownSUBTRANS(void)
Definition: subtrans.c:283
void CreateCheckPoint(int flags)
Definition: xlog.c:8704
ResourceOwner CurrentResourceOwner
Definition: resowner.c:141
void ShutdownCLOG(void)
Definition: clog.c:823
bool CreateRestartPoint(int flags)
Definition: xlog.c:9250
#define XLogArchiveCommandSet()
Definition: xlog.h:140
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:8057
ResourceOwner AuxProcessResourceOwner
Definition: resowner.c:144
void WalSndWaitStopping(void)
Definition: walsender.c:3103
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:3077
void ShutdownCommitTs(void)
Definition: commit_ts.c:745
#define Assert(condition)
Definition: c.h:699
#define XLogArchivingActive()
Definition: xlog.h:135
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:179
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:176

◆ StartupXLOG()

void StartupXLOG ( void  )

Definition at line 6346 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, track_commit_timestamp, ControlFileData::track_commit_timestamp, TransactionIdAdvance, TransactionIdFollowsOrEquals(), TransactionIdIsNormal, TransactionIdIsValid, TransactionIdRetreat, TrimCLOG(), TrimMultiXact(), UNLOGGED_RELATION_CLEANUP, UNLOGGED_RELATION_INIT, ControlFileData::unloggedLSN, XLogCtlData::unloggedLSN, UpdateControlFile(), UpdateFullPageWrites(), ValidateXLOGDirectoryStructure(), wal_segment_size, WalRcvForceReply(), WalSndWakeup(), XLogwrtRqst::Write, XLogwrtResult::Write, writeTimeLineHistory(), RunningTransactionsData::xcnt, RunningTransactionsData::xids, XLogRecord::xl_info, XLogRecord::xl_rmid, XLogRecord::xl_xid, XLogCtlData::xlblocks, XLByteToPrevSeg, XLOG_CHECKPOINT_SHUTDOWN, XLOG_END_OF_RECOVERY, xlog_outdesc(), XLogArchiveCleanup(), XLogArchiveIsReadyOrDone(), XLogArchiveNotify(), XLogArchivingActive, XLogFileName, XLogFilePath, XLogPageRead(), XLogReaderAllocate(), XLogReaderFree(), XLogReceiptTime, XLogRecGetData, XLogRecPtrIsInvalid, XLogRecPtrToBufIdx, XLogRecPtrToBytePos(), XLogReportParameters(), XLogSegmentOffset, XLR_CHECK_CONSISTENCY, XLR_INFO_MASK, and XRecOffIsValid.

Referenced by InitPostgres(), and StartupProcessMain().

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