PostgreSQL Source Code  git master
xlog.h File Reference
#include "access/xlogbackup.h"
#include "access/xlogdefs.h"
#include "datatype/timestamp.h"
#include "lib/stringinfo.h"
#include "nodes/pg_list.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 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 XLogIsNeeded()   (wal_level >= WAL_LEVEL_REPLICA)
 
#define XLogHintBitIsNeeded()   (DataChecksumsEnabled() || wal_log_hints)
 
#define XLogStandbyInfoActive()   (wal_level >= WAL_LEVEL_REPLICA)
 
#define XLogLogicalInfoActive()   (wal_level >= WAL_LEVEL_LOGICAL)
 
#define CHECKPOINT_IS_SHUTDOWN   0x0001 /* Checkpoint is for shutdown */
 
#define CHECKPOINT_END_OF_RECOVERY
 
#define CHECKPOINT_IMMEDIATE   0x0004 /* Do it without delays */
 
#define CHECKPOINT_FORCE   0x0008 /* Force even if no activity */
 
#define CHECKPOINT_FLUSH_ALL
 
#define CHECKPOINT_WAIT   0x0020 /* Wait for completion */
 
#define CHECKPOINT_REQUESTED   0x0040 /* Checkpoint request has been made */
 
#define CHECKPOINT_CAUSE_XLOG   0x0080 /* XLOG consumption */
 
#define CHECKPOINT_CAUSE_TIME   0x0100 /* Elapsed time */
 
#define XLOG_INCLUDE_ORIGIN   0x01 /* include the replication origin */
 
#define XLOG_MARK_UNIMPORTANT   0x02 /* record not important for durability */
 
#define RECOVERY_SIGNAL_FILE   "recovery.signal"
 
#define STANDBY_SIGNAL_FILE   "standby.signal"
 
#define BACKUP_LABEL_FILE   "backup_label"
 
#define BACKUP_LABEL_OLD   "backup_label.old"
 
#define TABLESPACE_MAP   "tablespace_map"
 
#define TABLESPACE_MAP_OLD   "tablespace_map.old"
 
#define PROMOTE_SIGNAL_FILE   "promote"
 

Typedefs

typedef enum ArchiveMode ArchiveMode
 
typedef enum WalLevel WalLevel
 
typedef enum WalCompression WalCompression
 
typedef enum RecoveryState RecoveryState
 
typedef struct CheckpointStatsData CheckpointStatsData
 
typedef enum WALAvailability WALAvailability
 
typedef enum SessionBackupState SessionBackupState
 

Enumerations

enum  WalSyncMethod {
  WAL_SYNC_METHOD_FSYNC = 0 , WAL_SYNC_METHOD_FDATASYNC , WAL_SYNC_METHOD_OPEN , WAL_SYNC_METHOD_FSYNC_WRITETHROUGH ,
  WAL_SYNC_METHOD_OPEN_DSYNC
}
 
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  WalCompression { WAL_COMPRESSION_NONE = 0 , WAL_COMPRESSION_PGLZ , WAL_COMPRESSION_LZ4 , WAL_COMPRESSION_ZSTD }
 
enum  RecoveryState { RECOVERY_STATE_CRASH = 0 , RECOVERY_STATE_ARCHIVE , RECOVERY_STATE_DONE }
 
enum  WALAvailability {
  WALAVAIL_INVALID_LSN , WALAVAIL_RESERVED , WALAVAIL_EXTENDED , WALAVAIL_UNRESERVED ,
  WALAVAIL_REMOVED
}
 
enum  SessionBackupState { SESSION_BACKUP_NONE , SESSION_BACKUP_RUNNING }
 

Functions

XLogRecPtr XLogInsertRecord (struct XLogRecData *rdata, XLogRecPtr fpw_lsn, uint8 flags, int num_fpi, bool topxid_included)
 
void XLogFlush (XLogRecPtr record)
 
bool XLogBackgroundFlush (void)
 
bool XLogNeedsFlush (XLogRecPtr record)
 
int XLogFileInit (XLogSegNo logsegno, TimeLineID logtli)
 
int XLogFileOpen (XLogSegNo segno, TimeLineID tli)
 
void CheckXLogRemoved (XLogSegNo segno, TimeLineID tli)
 
XLogSegNo XLogGetLastRemovedSegno (void)
 
XLogSegNo XLogGetOldestSegno (TimeLineID tli)
 
void XLogSetAsyncXactLSN (XLogRecPtr asyncXactLSN)
 
void XLogSetReplicationSlotMinimumLSN (XLogRecPtr lsn)
 
void xlog_redo (struct XLogReaderState *record)
 
void xlog_desc (StringInfo buf, struct XLogReaderState *record)
 
const char * xlog_identify (uint8 info)
 
void issue_xlog_fsync (int fd, XLogSegNo segno, TimeLineID tli)
 
bool RecoveryInProgress (void)
 
RecoveryState GetRecoveryState (void)
 
bool XLogInsertAllowed (void)
 
XLogRecPtr GetXLogInsertRecPtr (void)
 
XLogRecPtr GetXLogWriteRecPtr (void)
 
uint64 GetSystemIdentifier (void)
 
char * GetMockAuthenticationNonce (void)
 
bool DataChecksumsEnabled (void)
 
XLogRecPtr GetFakeLSNForUnloggedRel (void)
 
Size XLOGShmemSize (void)
 
void XLOGShmemInit (void)
 
void BootStrapXLOG (uint32 data_checksum_version)
 
void InitializeWalConsistencyChecking (void)
 
void LocalProcessControlFile (bool reset)
 
WalLevel GetActiveWalLevelOnStandby (void)
 
void StartupXLOG (void)
 
void ShutdownXLOG (int code, Datum arg)
 
void CreateCheckPoint (int flags)
 
bool CreateRestartPoint (int flags)
 
WALAvailability GetWALAvailability (XLogRecPtr targetLSN)
 
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 (TimeLineID *insertTLI)
 
TimeLineID GetWALInsertionTimeLine (void)
 
XLogRecPtr GetLastImportantRecPtr (void)
 
void SetWalWriterSleeping (bool sleeping)
 
Size WALReadFromBuffers (char *dstbuf, XLogRecPtr startptr, Size count, TimeLineID tli)
 
void RemoveNonParentXlogFiles (XLogRecPtr switchpoint, TimeLineID newTLI)
 
bool XLogCheckpointNeeded (XLogSegNo new_segno)
 
void SwitchIntoArchiveRecovery (XLogRecPtr EndRecPtr, TimeLineID replayTLI)
 
void ReachedEndOfBackup (XLogRecPtr EndRecPtr, TimeLineID tli)
 
void SetInstallXLogFileSegmentActive (void)
 
bool IsInstallXLogFileSegmentActive (void)
 
void XLogShutdownWalRcv (void)
 
void do_pg_backup_start (const char *backupidstr, bool fast, List **tablespaces, BackupState *state, StringInfo tblspcmapfile)
 
void do_pg_backup_stop (BackupState *state, bool waitforarchive)
 
void do_pg_abort_backup (int code, Datum arg)
 
void register_persistent_abort_backup_handler (void)
 
SessionBackupState get_backup_status (void)
 

Variables

PGDLLIMPORT int wal_sync_method
 
PGDLLIMPORT XLogRecPtr ProcLastRecPtr
 
PGDLLIMPORT XLogRecPtr XactLastRecEnd
 
PGDLLIMPORT XLogRecPtr XactLastCommitEnd
 
PGDLLIMPORT int wal_segment_size
 
PGDLLIMPORT int min_wal_size_mb
 
PGDLLIMPORT int max_wal_size_mb
 
PGDLLIMPORT int wal_keep_size_mb
 
PGDLLIMPORT int max_slot_wal_keep_size_mb
 
PGDLLIMPORT int XLOGbuffers
 
PGDLLIMPORT int XLogArchiveTimeout
 
PGDLLIMPORT int wal_retrieve_retry_interval
 
PGDLLIMPORT char * XLogArchiveCommand
 
PGDLLIMPORT bool EnableHotStandby
 
PGDLLIMPORT bool fullPageWrites
 
PGDLLIMPORT bool wal_log_hints
 
PGDLLIMPORT int wal_compression
 
PGDLLIMPORT bool wal_init_zero
 
PGDLLIMPORT bool wal_recycle
 
PGDLLIMPORT boolwal_consistency_checking
 
PGDLLIMPORT char * wal_consistency_checking_string
 
PGDLLIMPORT bool log_checkpoints
 
PGDLLIMPORT int CommitDelay
 
PGDLLIMPORT int CommitSiblings
 
PGDLLIMPORT bool track_wal_io_timing
 
PGDLLIMPORT int wal_decode_buffer_size
 
PGDLLIMPORT int CheckPointSegments
 
PGDLLIMPORT int XLogArchiveMode
 
PGDLLIMPORT int wal_level
 
PGDLLIMPORT CheckpointStatsData CheckpointStats
 

Macro Definition Documentation

◆ BACKUP_LABEL_FILE

#define BACKUP_LABEL_FILE   "backup_label"

Definition at line 300 of file xlog.h.

◆ BACKUP_LABEL_OLD

#define BACKUP_LABEL_OLD   "backup_label.old"

Definition at line 301 of file xlog.h.

◆ CHECKPOINT_CAUSE_TIME

#define CHECKPOINT_CAUSE_TIME   0x0100 /* Elapsed time */

Definition at line 149 of file xlog.h.

◆ CHECKPOINT_CAUSE_XLOG

#define CHECKPOINT_CAUSE_XLOG   0x0080 /* XLOG consumption */

Definition at line 148 of file xlog.h.

◆ CHECKPOINT_END_OF_RECOVERY

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

Definition at line 140 of file xlog.h.

◆ CHECKPOINT_FLUSH_ALL

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

Definition at line 143 of file xlog.h.

◆ CHECKPOINT_FORCE

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

Definition at line 142 of file xlog.h.

◆ CHECKPOINT_IMMEDIATE

#define CHECKPOINT_IMMEDIATE   0x0004 /* Do it without delays */

Definition at line 141 of file xlog.h.

◆ CHECKPOINT_IS_SHUTDOWN

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

Definition at line 139 of file xlog.h.

◆ CHECKPOINT_REQUESTED

#define CHECKPOINT_REQUESTED   0x0040 /* Checkpoint request has been made */

Definition at line 146 of file xlog.h.

◆ CHECKPOINT_WAIT

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

Definition at line 145 of file xlog.h.

◆ PROMOTE_SIGNAL_FILE

#define PROMOTE_SIGNAL_FILE   "promote"

Definition at line 307 of file xlog.h.

◆ RECOVERY_SIGNAL_FILE

#define RECOVERY_SIGNAL_FILE   "recovery.signal"

Definition at line 298 of file xlog.h.

◆ STANDBY_SIGNAL_FILE

#define STANDBY_SIGNAL_FILE   "standby.signal"

Definition at line 299 of file xlog.h.

◆ TABLESPACE_MAP

#define TABLESPACE_MAP   "tablespace_map"

Definition at line 303 of file xlog.h.

◆ TABLESPACE_MAP_OLD

#define TABLESPACE_MAP_OLD   "tablespace_map.old"

Definition at line 304 of file xlog.h.

◆ XLOG_INCLUDE_ORIGIN

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

Definition at line 154 of file xlog.h.

◆ XLOG_MARK_UNIMPORTANT

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

Definition at line 155 of file xlog.h.

◆ XLogArchivingActive

Definition at line 99 of file xlog.h.

◆ XLogArchivingAlways

Definition at line 102 of file xlog.h.

◆ XLogHintBitIsNeeded

#define XLogHintBitIsNeeded ( )    (DataChecksumsEnabled() || wal_log_hints)

Definition at line 120 of file xlog.h.

◆ XLogIsNeeded

#define XLogIsNeeded ( )    (wal_level >= WAL_LEVEL_REPLICA)

Definition at line 109 of file xlog.h.

◆ XLogLogicalInfoActive

#define XLogLogicalInfoActive ( )    (wal_level >= WAL_LEVEL_LOGICAL)

Definition at line 126 of file xlog.h.

◆ XLogStandbyInfoActive

#define XLogStandbyInfoActive ( )    (wal_level >= WAL_LEVEL_REPLICA)

Definition at line 123 of file xlog.h.

Typedef Documentation

◆ ArchiveMode

typedef enum ArchiveMode ArchiveMode

◆ CheckpointStatsData

◆ RecoveryState

◆ SessionBackupState

◆ WALAvailability

◆ WalCompression

◆ WalLevel

typedef enum WalLevel WalLevel

Enumeration Type Documentation

◆ ArchiveMode

Enumerator
ARCHIVE_MODE_OFF 
ARCHIVE_MODE_ON 
ARCHIVE_MODE_ALWAYS 

Definition at line 63 of file xlog.h.

64 {
65  ARCHIVE_MODE_OFF = 0, /* disabled */
66  ARCHIVE_MODE_ON, /* enabled while server is running normally */
67  ARCHIVE_MODE_ALWAYS, /* enabled always (even during recovery) */
68 } ArchiveMode;
ArchiveMode
Definition: xlog.h:64
@ ARCHIVE_MODE_ALWAYS
Definition: xlog.h:67
@ ARCHIVE_MODE_OFF
Definition: xlog.h:65
@ ARCHIVE_MODE_ON
Definition: xlog.h:66

◆ RecoveryState

Enumerator
RECOVERY_STATE_CRASH 
RECOVERY_STATE_ARCHIVE 
RECOVERY_STATE_DONE 

Definition at line 89 of file xlog.h.

90 {
91  RECOVERY_STATE_CRASH = 0, /* crash recovery */
92  RECOVERY_STATE_ARCHIVE, /* archive recovery */
93  RECOVERY_STATE_DONE, /* currently in production */
RecoveryState
Definition: xlog.h:90
@ RECOVERY_STATE_CRASH
Definition: xlog.h:91
@ RECOVERY_STATE_DONE
Definition: xlog.h:93
@ RECOVERY_STATE_ARCHIVE
Definition: xlog.h:92

◆ SessionBackupState

Enumerator
SESSION_BACKUP_NONE 
SESSION_BACKUP_RUNNING 

Definition at line 283 of file xlog.h.

286 {
@ SESSION_BACKUP_NONE
Definition: xlog.h:285

◆ WALAvailability

Enumerator
WALAVAIL_INVALID_LSN 
WALAVAIL_RESERVED 
WALAVAIL_EXTENDED 
WALAVAIL_UNRESERVED 
WALAVAIL_REMOVED 

Definition at line 186 of file xlog.h.

189 {
190  WALAVAIL_INVALID_LSN, /* parameter error */
191  WALAVAIL_RESERVED, /* WAL segment is within max_wal_size */
192  WALAVAIL_EXTENDED, /* WAL segment is reserved by a slot or
193  * wal_keep_size */
194  WALAVAIL_UNRESERVED, /* no longer reserved, but not removed yet */
@ WALAVAIL_RESERVED
Definition: xlog.h:189
@ WALAVAIL_UNRESERVED
Definition: xlog.h:192
@ WALAVAIL_EXTENDED
Definition: xlog.h:190
@ WALAVAIL_INVALID_LSN
Definition: xlog.h:188

◆ WalCompression

Enumerator
WAL_COMPRESSION_NONE 
WAL_COMPRESSION_PGLZ 
WAL_COMPRESSION_LZ4 
WAL_COMPRESSION_ZSTD 

Definition at line 80 of file xlog.h.

81 {
WalCompression
Definition: xlog.h:81
@ WAL_COMPRESSION_NONE
Definition: xlog.h:82
@ WAL_COMPRESSION_LZ4
Definition: xlog.h:84
@ WAL_COMPRESSION_PGLZ
Definition: xlog.h:83
@ WAL_COMPRESSION_ZSTD
Definition: xlog.h:85

◆ WalLevel

enum WalLevel
Enumerator
WAL_LEVEL_MINIMAL 
WAL_LEVEL_REPLICA 
WAL_LEVEL_LOGICAL 

Definition at line 72 of file xlog.h.

73 {
77 } WalLevel;
WalLevel
Definition: xlog.h:73
@ WAL_LEVEL_REPLICA
Definition: xlog.h:75
@ WAL_LEVEL_LOGICAL
Definition: xlog.h:76
@ WAL_LEVEL_MINIMAL
Definition: xlog.h:74

◆ WalSyncMethod

Enumerator
WAL_SYNC_METHOD_FSYNC 
WAL_SYNC_METHOD_FDATASYNC 
WAL_SYNC_METHOD_OPEN 
WAL_SYNC_METHOD_FSYNC_WRITETHROUGH 
WAL_SYNC_METHOD_OPEN_DSYNC 

Definition at line 22 of file xlog.h.

23 {
26  WAL_SYNC_METHOD_OPEN, /* for O_SYNC */
28  WAL_SYNC_METHOD_OPEN_DSYNC /* for O_DSYNC */
29 };
@ WAL_SYNC_METHOD_OPEN
Definition: xlog.h:26
@ WAL_SYNC_METHOD_FDATASYNC
Definition: xlog.h:25
@ WAL_SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:27
@ WAL_SYNC_METHOD_OPEN_DSYNC
Definition: xlog.h:28
@ WAL_SYNC_METHOD_FSYNC
Definition: xlog.h:24

Function Documentation

◆ BootStrapXLOG()

void BootStrapXLOG ( uint32  data_checksum_version)

Definition at line 4998 of file xlog.c.

4999 {
5000  CheckPoint checkPoint;
5001  char *buffer;
5002  XLogPageHeader page;
5003  XLogLongPageHeader longpage;
5004  XLogRecord *record;
5005  char *recptr;
5006  uint64 sysidentifier;
5007  struct timeval tv;
5008  pg_crc32c crc;
5009 
5010  /* allow ordinary WAL segment creation, like StartupXLOG() would */
5012 
5013  /*
5014  * Select a hopefully-unique system identifier code for this installation.
5015  * We use the result of gettimeofday(), including the fractional seconds
5016  * field, as being about as unique as we can easily get. (Think not to
5017  * use random(), since it hasn't been seeded and there's no portable way
5018  * to seed it other than the system clock value...) The upper half of the
5019  * uint64 value is just the tv_sec part, while the lower half contains the
5020  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
5021  * PID for a little extra uniqueness. A person knowing this encoding can
5022  * determine the initialization time of the installation, which could
5023  * perhaps be useful sometimes.
5024  */
5025  gettimeofday(&tv, NULL);
5026  sysidentifier = ((uint64) tv.tv_sec) << 32;
5027  sysidentifier |= ((uint64) tv.tv_usec) << 12;
5028  sysidentifier |= getpid() & 0xFFF;
5029 
5030  /* page buffer must be aligned suitably for O_DIRECT */
5031  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
5032  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
5033  memset(page, 0, XLOG_BLCKSZ);
5034 
5035  /*
5036  * Set up information for the initial checkpoint record
5037  *
5038  * The initial checkpoint record is written to the beginning of the WAL
5039  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5040  * used, so that we can use 0/0 to mean "before any valid WAL segment".
5041  */
5042  checkPoint.redo = wal_segment_size + SizeOfXLogLongPHD;
5043  checkPoint.ThisTimeLineID = BootstrapTimeLineID;
5044  checkPoint.PrevTimeLineID = BootstrapTimeLineID;
5045  checkPoint.fullPageWrites = fullPageWrites;
5046  checkPoint.wal_level = wal_level;
5047  checkPoint.nextXid =
5049  checkPoint.nextOid = FirstGenbkiObjectId;
5050  checkPoint.nextMulti = FirstMultiXactId;
5051  checkPoint.nextMultiOffset = 0;
5052  checkPoint.oldestXid = FirstNormalTransactionId;
5053  checkPoint.oldestXidDB = Template1DbOid;
5054  checkPoint.oldestMulti = FirstMultiXactId;
5055  checkPoint.oldestMultiDB = Template1DbOid;
5058  checkPoint.time = (pg_time_t) time(NULL);
5060 
5061  TransamVariables->nextXid = checkPoint.nextXid;
5062  TransamVariables->nextOid = checkPoint.nextOid;
5064  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5065  AdvanceOldestClogXid(checkPoint.oldestXid);
5066  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5067  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5069 
5070  /* Set up the XLOG page header */
5071  page->xlp_magic = XLOG_PAGE_MAGIC;
5072  page->xlp_info = XLP_LONG_HEADER;
5073  page->xlp_tli = BootstrapTimeLineID;
5075  longpage = (XLogLongPageHeader) page;
5076  longpage->xlp_sysid = sysidentifier;
5077  longpage->xlp_seg_size = wal_segment_size;
5078  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5079 
5080  /* Insert the initial checkpoint record */
5081  recptr = ((char *) page + SizeOfXLogLongPHD);
5082  record = (XLogRecord *) recptr;
5083  record->xl_prev = 0;
5084  record->xl_xid = InvalidTransactionId;
5085  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5087  record->xl_rmid = RM_XLOG_ID;
5088  recptr += SizeOfXLogRecord;
5089  /* fill the XLogRecordDataHeaderShort struct */
5090  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5091  *(recptr++) = sizeof(checkPoint);
5092  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5093  recptr += sizeof(checkPoint);
5094  Assert(recptr - (char *) record == record->xl_tot_len);
5095 
5096  INIT_CRC32C(crc);
5097  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5098  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5099  FIN_CRC32C(crc);
5100  record->xl_crc = crc;
5101 
5102  /* Create first XLOG segment file */
5105 
5106  /*
5107  * We needn't bother with Reserve/ReleaseExternalFD here, since we'll
5108  * close the file again in a moment.
5109  */
5110 
5111  /* Write the first page with the initial record */
5112  errno = 0;
5113  pgstat_report_wait_start(WAIT_EVENT_WAL_BOOTSTRAP_WRITE);
5114  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5115  {
5116  /* if write didn't set errno, assume problem is no disk space */
5117  if (errno == 0)
5118  errno = ENOSPC;
5119  ereport(PANIC,
5121  errmsg("could not write bootstrap write-ahead log file: %m")));
5122  }
5124 
5125  pgstat_report_wait_start(WAIT_EVENT_WAL_BOOTSTRAP_SYNC);
5126  if (pg_fsync(openLogFile) != 0)
5127  ereport(PANIC,
5129  errmsg("could not fsync bootstrap write-ahead log file: %m")));
5131 
5132  if (close(openLogFile) != 0)
5133  ereport(PANIC,
5135  errmsg("could not close bootstrap write-ahead log file: %m")));
5136 
5137  openLogFile = -1;
5138 
5139  /* Now create pg_control */
5140  InitControlFile(sysidentifier, data_checksum_version);
5141  ControlFile->time = checkPoint.time;
5142  ControlFile->checkPoint = checkPoint.redo;
5143  ControlFile->checkPointCopy = checkPoint;
5144 
5145  /* some additional ControlFile fields are set in WriteControlFile() */
5146  WriteControlFile();
5147 
5148  /* Bootstrap the commit log, too */
5149  BootStrapCLOG();
5153 
5154  pfree(buffer);
5155 
5156  /*
5157  * Force control file to be read - in contrast to normal processing we'd
5158  * otherwise never run the checks and GUC related initializations therein.
5159  */
5160  ReadControlFile();
5161 }
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:804
#define Assert(condition)
Definition: c.h:858
void BootStrapCLOG(void)
Definition: clog.c:833
void BootStrapCommitTs(void)
Definition: commit_ts.c:596
void SetCommitTsLimit(TransactionId oldestXact, TransactionId newestXact)
Definition: commit_ts.c:909
int errcode_for_file_access(void)
Definition: elog.c:876
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define PANIC
Definition: elog.h:42
#define ereport(elevel,...)
Definition: elog.h:149
int pg_fsync(int fd)
Definition: fd.c:386
#define close(a)
Definition: win32.h:12
#define write(a, b, c)
Definition: win32.h:14
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc(Size size)
Definition: mcxt.c:1317
void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset)
Definition: multixact.c:2320
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
Definition: multixact.c:2354
void BootStrapMultiXact(void)
Definition: multixact.c:2026
#define FirstMultiXactId
Definition: multixact.h:25
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:68
uint32 pg_crc32c
Definition: pg_crc32c.h:38
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:98
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:103
return crc
int64 pg_time_t
Definition: pgtime.h:23
Oid oldestMultiDB
Definition: pg_control.h:51
MultiXactId oldestMulti
Definition: pg_control.h:50
MultiXactOffset nextMultiOffset
Definition: pg_control.h:47
TransactionId newestCommitTsXid
Definition: pg_control.h:55
TransactionId oldestXid
Definition: pg_control.h:48
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
Oid nextOid
Definition: pg_control.h:45
TransactionId oldestActiveXid
Definition: pg_control.h:64
bool fullPageWrites
Definition: pg_control.h:42
MultiXactId nextMulti
Definition: pg_control.h:46
FullTransactionId nextXid
Definition: pg_control.h:44
TransactionId oldestCommitTsXid
Definition: pg_control.h:53
pg_time_t time
Definition: pg_control.h:52
int wal_level
Definition: pg_control.h:43
XLogRecPtr redo
Definition: pg_control.h:37
Oid oldestXidDB
Definition: pg_control.h:49
CheckPoint checkPointCopy
Definition: pg_control.h:135
pg_time_t time
Definition: pg_control.h:132
XLogRecPtr checkPoint
Definition: pg_control.h:133
FullTransactionId nextXid
Definition: transam.h:220
TimeLineID xlp_tli
Definition: xlog_internal.h:40
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
uint8 xl_info
Definition: xlogrecord.h:46
uint32 xl_tot_len
Definition: xlogrecord.h:43
TransactionId xl_xid
Definition: xlogrecord.h:44
RmgrId xl_rmid
Definition: xlogrecord.h:47
void BootStrapSUBTRANS(void)
Definition: subtrans.c:270
#define InvalidTransactionId
Definition: transam.h:31
#define FirstGenbkiObjectId
Definition: transam.h:195
#define FirstNormalTransactionId
Definition: transam.h:34
static FullTransactionId FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
Definition: transam.h:71
void SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid)
Definition: varsup.c:372
void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid)
Definition: varsup.c:355
TransamVariablesData * TransamVariables
Definition: varsup.c:34
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:85
static void pgstat_report_wait_end(void)
Definition: wait_event.h:101
int gettimeofday(struct timeval *tp, void *tzp)
int XLogFileInit(XLogSegNo logsegno, TimeLineID logtli)
Definition: xlog.c:3367
bool fullPageWrites
Definition: xlog.c:120
static void InitControlFile(uint64 sysidentifier, uint32 data_checksum_version)
Definition: xlog.c:4191
void SetInstallXLogFileSegmentActive(void)
Definition: xlog.c:9414
static int openLogFile
Definition: xlog.c:628
int wal_level
Definition: xlog.c:129
static void WriteControlFile(void)
Definition: xlog.c:4226
int wal_segment_size
Definition: xlog.c:141
static TimeLineID openLogTLI
Definition: xlog.c:630
static ControlFileData * ControlFile
Definition: xlog.c:567
#define BootstrapTimeLineID
Definition: xlog.c:109
static void ReadControlFile(void)
Definition: xlog.c:4308
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:71
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:54
#define XLP_LONG_HEADER
Definition: xlog_internal.h:76
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:69
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:217
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:241
#define SizeOfXLogRecord
Definition: xlogrecord.h:55

References AdvanceOldestClogXid(), Assert, BootStrapCLOG(), BootStrapCommitTs(), BootStrapMultiXact(), BootStrapSUBTRANS(), BootstrapTimeLineID, ControlFileData::checkPoint, ControlFileData::checkPointCopy, close, COMP_CRC32C, ControlFile, crc, ereport, errcode_for_file_access(), errmsg(), FIN_CRC32C, FirstGenbkiObjectId, FirstMultiXactId, FirstNormalTransactionId, fullPageWrites, CheckPoint::fullPageWrites, FullTransactionIdFromEpochAndXid(), gettimeofday(), INIT_CRC32C, InitControlFile(), InvalidTransactionId, MultiXactSetNextMXact(), CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, TransamVariablesData::nextOid, CheckPoint::nextOid, TransamVariablesData::nextXid, CheckPoint::nextXid, TransamVariablesData::oidCount, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, openLogFile, openLogTLI, palloc(), PANIC, pfree(), pg_fsync(), pgstat_report_wait_end(), pgstat_report_wait_start(), CheckPoint::PrevTimeLineID, ReadControlFile(), CheckPoint::redo, SetCommitTsLimit(), SetInstallXLogFileSegmentActive(), SetMultiXactIdLimit(), SetTransactionIdLimit(), SizeOfXLogLongPHD, SizeOfXLogRecord, SizeOfXLogRecordDataHeaderShort, CheckPoint::ThisTimeLineID, CheckPoint::time, ControlFileData::time, TransamVariables, TYPEALIGN, wal_level, CheckPoint::wal_level, wal_segment_size, write, WriteControlFile(), XLogRecord::xl_crc, 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 BootstrapModeMain().

◆ CheckXLogRemoved()

void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)

Definition at line 3714 of file xlog.c.

3715 {
3716  int save_errno = errno;
3717  XLogSegNo lastRemovedSegNo;
3718 
3720  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3722 
3723  if (segno <= lastRemovedSegNo)
3724  {
3725  char filename[MAXFNAMELEN];
3726 
3727  XLogFileName(filename, tli, segno, wal_segment_size);
3728  errno = save_errno;
3729  ereport(ERROR,
3731  errmsg("requested WAL segment %s has already been removed",
3732  filename)));
3733  }
3734  errno = save_errno;
3735 }
#define ERROR
Definition: elog.h:39
static char * filename
Definition: pg_dumpall.c:119
#define SpinLockRelease(lock)
Definition: spin.h:64
#define SpinLockAcquire(lock)
Definition: spin.h:62
slock_t info_lck
Definition: xlog.c:546
XLogSegNo lastRemovedSegNo
Definition: xlog.c:459
static XLogCtlData * XLogCtl
Definition: xlog.c:559
#define MAXFNAMELEN
static void XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
uint64 XLogSegNo
Definition: xlogdefs.h:48

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

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

◆ CreateCheckPoint()

void CreateCheckPoint ( int  flags)

Definition at line 6821 of file xlog.c.

6822 {
6823  bool shutdown;
6824  CheckPoint checkPoint;
6825  XLogRecPtr recptr;
6826  XLogSegNo _logSegNo;
6828  uint32 freespace;
6829  XLogRecPtr PriorRedoPtr;
6830  XLogRecPtr last_important_lsn;
6831  VirtualTransactionId *vxids;
6832  int nvxids;
6833  int oldXLogAllowed = 0;
6834 
6835  /*
6836  * An end-of-recovery checkpoint is really a shutdown checkpoint, just
6837  * issued at a different time.
6838  */
6840  shutdown = true;
6841  else
6842  shutdown = false;
6843 
6844  /* sanity check */
6845  if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
6846  elog(ERROR, "can't create a checkpoint during recovery");
6847 
6848  /*
6849  * Prepare to accumulate statistics.
6850  *
6851  * Note: because it is possible for log_checkpoints to change while a
6852  * checkpoint proceeds, we always accumulate stats, even if
6853  * log_checkpoints is currently off.
6854  */
6855  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
6857 
6858  /*
6859  * Let smgr prepare for checkpoint; this has to happen outside the
6860  * critical section and before we determine the REDO pointer. Note that
6861  * smgr must not do anything that'd have to be undone if we decide no
6862  * checkpoint is needed.
6863  */
6865 
6866  /*
6867  * Use a critical section to force system panic if we have trouble.
6868  */
6870 
6871  if (shutdown)
6872  {
6873  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6876  LWLockRelease(ControlFileLock);
6877  }
6878 
6879  /* Begin filling in the checkpoint WAL record */
6880  MemSet(&checkPoint, 0, sizeof(checkPoint));
6881  checkPoint.time = (pg_time_t) time(NULL);
6882 
6883  /*
6884  * For Hot Standby, derive the oldestActiveXid before we fix the redo
6885  * pointer. This allows us to begin accumulating changes to assemble our
6886  * starting snapshot of locks and transactions.
6887  */
6888  if (!shutdown && XLogStandbyInfoActive())
6890  else
6892 
6893  /*
6894  * Get location of last important record before acquiring insert locks (as
6895  * GetLastImportantRecPtr() also locks WAL locks).
6896  */
6897  last_important_lsn = GetLastImportantRecPtr();
6898 
6899  /*
6900  * If this isn't a shutdown or forced checkpoint, and if there has been no
6901  * WAL activity requiring a checkpoint, skip it. The idea here is to
6902  * avoid inserting duplicate checkpoints when the system is idle.
6903  */
6905  CHECKPOINT_FORCE)) == 0)
6906  {
6907  if (last_important_lsn == ControlFile->checkPoint)
6908  {
6909  END_CRIT_SECTION();
6910  ereport(DEBUG1,
6911  (errmsg_internal("checkpoint skipped because system is idle")));
6912  return;
6913  }
6914  }
6915 
6916  /*
6917  * An end-of-recovery checkpoint is created before anyone is allowed to
6918  * write WAL. To allow us to write the checkpoint record, temporarily
6919  * enable XLogInsertAllowed.
6920  */
6921  if (flags & CHECKPOINT_END_OF_RECOVERY)
6922  oldXLogAllowed = LocalSetXLogInsertAllowed();
6923 
6924  checkPoint.ThisTimeLineID = XLogCtl->InsertTimeLineID;
6925  if (flags & CHECKPOINT_END_OF_RECOVERY)
6926  checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
6927  else
6928  checkPoint.PrevTimeLineID = checkPoint.ThisTimeLineID;
6929 
6930  /*
6931  * We must block concurrent insertions while examining insert state.
6932  */
6934 
6935  checkPoint.fullPageWrites = Insert->fullPageWrites;
6936  checkPoint.wal_level = wal_level;
6937 
6938  if (shutdown)
6939  {
6940  XLogRecPtr curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
6941 
6942  /*
6943  * Compute new REDO record ptr = location of next XLOG record.
6944  *
6945  * Since this is a shutdown checkpoint, there can't be any concurrent
6946  * WAL insertion.
6947  */
6948  freespace = INSERT_FREESPACE(curInsert);
6949  if (freespace == 0)
6950  {
6951  if (XLogSegmentOffset(curInsert, wal_segment_size) == 0)
6952  curInsert += SizeOfXLogLongPHD;
6953  else
6954  curInsert += SizeOfXLogShortPHD;
6955  }
6956  checkPoint.redo = curInsert;
6957 
6958  /*
6959  * Here we update the shared RedoRecPtr for future XLogInsert calls;
6960  * this must be done while holding all the insertion locks.
6961  *
6962  * Note: if we fail to complete the checkpoint, RedoRecPtr will be
6963  * left pointing past where it really needs to point. This is okay;
6964  * the only consequence is that XLogInsert might back up whole buffers
6965  * that it didn't really need to. We can't postpone advancing
6966  * RedoRecPtr because XLogInserts that happen while we are dumping
6967  * buffers must assume that their buffer changes are not included in
6968  * the checkpoint.
6969  */
6970  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
6971  }
6972 
6973  /*
6974  * Now we can release the WAL insertion locks, allowing other xacts to
6975  * proceed while we are flushing disk buffers.
6976  */
6978 
6979  /*
6980  * If this is an online checkpoint, we have not yet determined the redo
6981  * point. We do so now by inserting the special XLOG_CHECKPOINT_REDO
6982  * record; the LSN at which it starts becomes the new redo pointer. We
6983  * don't do this for a shutdown checkpoint, because in that case no WAL
6984  * can be written between the redo point and the insertion of the
6985  * checkpoint record itself, so the checkpoint record itself serves to
6986  * mark the redo point.
6987  */
6988  if (!shutdown)
6989  {
6990  /* Include WAL level in record for WAL summarizer's benefit. */
6991  XLogBeginInsert();
6992  XLogRegisterData((char *) &wal_level, sizeof(wal_level));
6993  (void) XLogInsert(RM_XLOG_ID, XLOG_CHECKPOINT_REDO);
6994 
6995  /*
6996  * XLogInsertRecord will have updated XLogCtl->Insert.RedoRecPtr in
6997  * shared memory and RedoRecPtr in backend-local memory, but we need
6998  * to copy that into the record that will be inserted when the
6999  * checkpoint is complete.
7000  */
7001  checkPoint.redo = RedoRecPtr;
7002  }
7003 
7004  /* Update the info_lck-protected copy of RedoRecPtr as well */
7006  XLogCtl->RedoRecPtr = checkPoint.redo;
7008 
7009  /*
7010  * If enabled, log checkpoint start. We postpone this until now so as not
7011  * to log anything if we decided to skip the checkpoint.
7012  */
7013  if (log_checkpoints)
7014  LogCheckpointStart(flags, false);
7015 
7016  /* Update the process title */
7017  update_checkpoint_display(flags, false, false);
7018 
7019  TRACE_POSTGRESQL_CHECKPOINT_START(flags);
7020 
7021  /*
7022  * Get the other info we need for the checkpoint record.
7023  *
7024  * We don't need to save oldestClogXid in the checkpoint, it only matters
7025  * for the short period in which clog is being truncated, and if we crash
7026  * during that we'll redo the clog truncation and fix up oldestClogXid
7027  * there.
7028  */
7029  LWLockAcquire(XidGenLock, LW_SHARED);
7030  checkPoint.nextXid = TransamVariables->nextXid;
7031  checkPoint.oldestXid = TransamVariables->oldestXid;
7033  LWLockRelease(XidGenLock);
7034 
7035  LWLockAcquire(CommitTsLock, LW_SHARED);
7038  LWLockRelease(CommitTsLock);
7039 
7040  LWLockAcquire(OidGenLock, LW_SHARED);
7041  checkPoint.nextOid = TransamVariables->nextOid;
7042  if (!shutdown)
7043  checkPoint.nextOid += TransamVariables->oidCount;
7044  LWLockRelease(OidGenLock);
7045 
7046  MultiXactGetCheckptMulti(shutdown,
7047  &checkPoint.nextMulti,
7048  &checkPoint.nextMultiOffset,
7049  &checkPoint.oldestMulti,
7050  &checkPoint.oldestMultiDB);
7051 
7052  /*
7053  * Having constructed the checkpoint record, ensure all shmem disk buffers
7054  * and commit-log buffers are flushed to disk.
7055  *
7056  * This I/O could fail for various reasons. If so, we will fail to
7057  * complete the checkpoint, but there is no reason to force a system
7058  * panic. Accordingly, exit critical section while doing it.
7059  */
7060  END_CRIT_SECTION();
7061 
7062  /*
7063  * In some cases there are groups of actions that must all occur on one
7064  * side or the other of a checkpoint record. Before flushing the
7065  * checkpoint record we must explicitly wait for any backend currently
7066  * performing those groups of actions.
7067  *
7068  * One example is end of transaction, so we must wait for any transactions
7069  * that are currently in commit critical sections. If an xact inserted
7070  * its commit record into XLOG just before the REDO point, then a crash
7071  * restart from the REDO point would not replay that record, which means
7072  * that our flushing had better include the xact's update of pg_xact. So
7073  * we wait till he's out of his commit critical section before proceeding.
7074  * See notes in RecordTransactionCommit().
7075  *
7076  * Because we've already released the insertion locks, this test is a bit
7077  * fuzzy: it is possible that we will wait for xacts we didn't really need
7078  * to wait for. But the delay should be short and it seems better to make
7079  * checkpoint take a bit longer than to hold off insertions longer than
7080  * necessary. (In fact, the whole reason we have this issue is that xact.c
7081  * does commit record XLOG insertion and clog update as two separate steps
7082  * protected by different locks, but again that seems best on grounds of
7083  * minimizing lock contention.)
7084  *
7085  * A transaction that has not yet set delayChkptFlags when we look cannot
7086  * be at risk, since it has not inserted its commit record yet; and one
7087  * that's already cleared it is not at risk either, since it's done fixing
7088  * clog and we will correctly flush the update below. So we cannot miss
7089  * any xacts we need to wait for.
7090  */
7092  if (nvxids > 0)
7093  {
7094  do
7095  {
7096  /*
7097  * Keep absorbing fsync requests while we wait. There could even
7098  * be a deadlock if we don't, if the process that prevents the
7099  * checkpoint is trying to add a request to the queue.
7100  */
7102 
7103  pgstat_report_wait_start(WAIT_EVENT_CHECKPOINT_DELAY_START);
7104  pg_usleep(10000L); /* wait for 10 msec */
7106  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids,
7108  }
7109  pfree(vxids);
7110 
7111  CheckPointGuts(checkPoint.redo, flags);
7112 
7114  if (nvxids > 0)
7115  {
7116  do
7117  {
7119 
7120  pgstat_report_wait_start(WAIT_EVENT_CHECKPOINT_DELAY_COMPLETE);
7121  pg_usleep(10000L); /* wait for 10 msec */
7123  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids,
7125  }
7126  pfree(vxids);
7127 
7128  /*
7129  * Take a snapshot of running transactions and write this to WAL. This
7130  * allows us to reconstruct the state of running transactions during
7131  * archive recovery, if required. Skip, if this info disabled.
7132  *
7133  * If we are shutting down, or Startup process is completing crash
7134  * recovery we don't need to write running xact data.
7135  */
7136  if (!shutdown && XLogStandbyInfoActive())
7138 
7140 
7141  /*
7142  * Now insert the checkpoint record into XLOG.
7143  */
7144  XLogBeginInsert();
7145  XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));
7146  recptr = XLogInsert(RM_XLOG_ID,
7147  shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
7149 
7150  XLogFlush(recptr);
7151 
7152  /*
7153  * We mustn't write any new WAL after a shutdown checkpoint, or it will be
7154  * overwritten at next startup. No-one should even try, this just allows
7155  * sanity-checking. In the case of an end-of-recovery checkpoint, we want
7156  * to just temporarily disable writing until the system has exited
7157  * recovery.
7158  */
7159  if (shutdown)
7160  {
7161  if (flags & CHECKPOINT_END_OF_RECOVERY)
7162  LocalXLogInsertAllowed = oldXLogAllowed;
7163  else
7164  LocalXLogInsertAllowed = 0; /* never again write WAL */
7165  }
7166 
7167  /*
7168  * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
7169  * = end of actual checkpoint record.
7170  */
7171  if (shutdown && checkPoint.redo != ProcLastRecPtr)
7172  ereport(PANIC,
7173  (errmsg("concurrent write-ahead log activity while database system is shutting down")));
7174 
7175  /*
7176  * Remember the prior checkpoint's redo ptr for
7177  * UpdateCheckPointDistanceEstimate()
7178  */
7179  PriorRedoPtr = ControlFile->checkPointCopy.redo;
7180 
7181  /*
7182  * Update the control file.
7183  */
7184  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7185  if (shutdown)
7188  ControlFile->checkPointCopy = checkPoint;
7189  /* crash recovery should always recover to the end of WAL */
7192 
7193  /*
7194  * Persist unloggedLSN value. It's reset on crash recovery, so this goes
7195  * unused on non-shutdown checkpoints, but seems useful to store it always
7196  * for debugging purposes.
7197  */
7199 
7201  LWLockRelease(ControlFileLock);
7202 
7203  /* Update shared-memory copy of checkpoint XID/epoch */
7205  XLogCtl->ckptFullXid = checkPoint.nextXid;
7207 
7208  /*
7209  * We are now done with critical updates; no need for system panic if we
7210  * have trouble while fooling with old log segments.
7211  */
7212  END_CRIT_SECTION();
7213 
7214  /*
7215  * WAL summaries end when the next XLOG_CHECKPOINT_REDO or
7216  * XLOG_CHECKPOINT_SHUTDOWN record is reached. This is the first point
7217  * where (a) we're not inside of a critical section and (b) we can be
7218  * certain that the relevant record has been flushed to disk, which must
7219  * happen before it can be summarized.
7220  *
7221  * If this is a shutdown checkpoint, then this happens reasonably
7222  * promptly: we've only just inserted and flushed the
7223  * XLOG_CHECKPOINT_SHUTDOWN record. If this is not a shutdown checkpoint,
7224  * then this might not be very prompt at all: the XLOG_CHECKPOINT_REDO
7225  * record was written before we began flushing data to disk, and that
7226  * could be many minutes ago at this point. However, we don't XLogFlush()
7227  * after inserting that record, so we're not guaranteed that it's on disk
7228  * until after the above call that flushes the XLOG_CHECKPOINT_ONLINE
7229  * record.
7230  */
7232 
7233  /*
7234  * Let smgr do post-checkpoint cleanup (eg, deleting old files).
7235  */
7237 
7238  /*
7239  * Update the average distance between checkpoints if the prior checkpoint
7240  * exists.
7241  */
7242  if (PriorRedoPtr != InvalidXLogRecPtr)
7244 
7245  /*
7246  * Delete old log files, those no longer needed for last checkpoint to
7247  * prevent the disk holding the xlog from growing full.
7248  */
7250  KeepLogSeg(recptr, &_logSegNo);
7252  _logSegNo, InvalidOid,
7254  {
7255  /*
7256  * Some slots have been invalidated; recalculate the old-segment
7257  * horizon, starting again from RedoRecPtr.
7258  */
7260  KeepLogSeg(recptr, &_logSegNo);
7261  }
7262  _logSegNo--;
7263  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr,
7264  checkPoint.ThisTimeLineID);
7265 
7266  /*
7267  * Make more log segments if needed. (Do this after recycling old log
7268  * segments, since that may supply some of the needed files.)
7269  */
7270  if (!shutdown)
7271  PreallocXlogFiles(recptr, checkPoint.ThisTimeLineID);
7272 
7273  /*
7274  * Truncate pg_subtrans if possible. We can throw away all data before
7275  * the oldest XMIN of any running transaction. No future transaction will
7276  * attempt to reference any pg_subtrans entry older than that (see Asserts
7277  * in subtrans.c). During recovery, though, we mustn't do this because
7278  * StartupSUBTRANS hasn't been called yet.
7279  */
7280  if (!RecoveryInProgress())
7282 
7283  /* Real work is done; log and update stats. */
7284  LogCheckpointEnd(false);
7285 
7286  /* Reset the process title */
7287  update_checkpoint_display(flags, false, true);
7288 
7289  TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
7290  NBuffers,
7294 }
static uint64 pg_atomic_read_membarrier_u64(volatile pg_atomic_uint64 *ptr)
Definition: atomics.h:469
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1655
unsigned int uint32
Definition: c.h:506
#define MemSet(start, val, len)
Definition: c.h:1020
void AbsorbSyncRequests(void)
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1157
#define DEBUG1
Definition: elog.h:30
#define elog(elevel,...)
Definition: elog.h:224
static void Insert(File file)
Definition: fd.c:1313
int NBuffers
Definition: globals.c:140
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1168
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1781
@ LW_SHARED
Definition: lwlock.h:115
@ LW_EXCLUSIVE
Definition: lwlock.h:114
#define START_CRIT_SECTION()
Definition: miscadmin.h:149
#define END_CRIT_SECTION()
Definition: miscadmin.h:151
void MultiXactGetCheckptMulti(bool is_shutdown, MultiXactId *nextMulti, MultiXactOffset *nextMultiOffset, MultiXactId *oldestMulti, Oid *oldestMultiDB)
Definition: multixact.c:2274
#define XLOG_CHECKPOINT_REDO
Definition: pg_control.h:82
@ DB_SHUTDOWNING
Definition: pg_control.h:94
@ DB_SHUTDOWNED
Definition: pg_control.h:92
#define XLOG_CHECKPOINT_ONLINE
Definition: pg_control.h:69
#define InvalidOid
Definition: postgres_ext.h:36
#define DELAY_CHKPT_START
Definition: proc.h:114
#define DELAY_CHKPT_COMPLETE
Definition: proc.h:115
VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
Definition: procarray.c:3047
TransactionId GetOldestActiveTransactionId(void)
Definition: procarray.c:2884
TransactionId GetOldestTransactionIdConsideredRunning(void)
Definition: procarray.c:2034
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)
Definition: procarray.c:3093
void pg_usleep(long microsec)
Definition: signal.c:53
bool InvalidateObsoleteReplicationSlots(ReplicationSlotInvalidationCause cause, XLogSegNo oldestSegno, Oid dboid, TransactionId snapshotConflictHorizon)
Definition: slot.c:1804
@ RS_INVAL_WAL_REMOVED
Definition: slot.h:51
XLogRecPtr LogStandbySnapshot(void)
Definition: standby.c:1285
TimestampTz ckpt_start_t
Definition: xlog.h:161
int ckpt_segs_removed
Definition: xlog.h:170
int ckpt_segs_added
Definition: xlog.h:169
int ckpt_bufs_written
Definition: xlog.h:167
int ckpt_segs_recycled
Definition: xlog.h:171
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:168
XLogRecPtr unloggedLSN
Definition: pg_control.h:137
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:169
TransactionId oldestCommitTsXid
Definition: transam.h:232
TransactionId newestCommitTsXid
Definition: transam.h:233
TransactionId oldestXid
Definition: transam.h:222
FullTransactionId ckptFullXid
Definition: xlog.c:455
TimeLineID InsertTimeLineID
Definition: xlog.c:502
XLogRecPtr RedoRecPtr
Definition: xlog.c:454
XLogCtlInsert Insert
Definition: xlog.c:450
TimeLineID PrevTimeLineID
Definition: xlog.c:503
pg_atomic_uint64 unloggedLSN
Definition: xlog.c:462
XLogRecPtr RedoRecPtr
Definition: xlog.c:428
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:411
void SyncPreCheckpoint(void)
Definition: sync.c:177
void SyncPostCheckpoint(void)
Definition: sync.c:202
void SetWalSummarizerLatch(void)
XLogRecPtr ProcLastRecPtr
Definition: xlog.c:251
bool RecoveryInProgress(void)
Definition: xlog.c:6290
static void WALInsertLockRelease(void)
Definition: xlog.c:1438
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1851
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1409
static void UpdateControlFile(void)
Definition: xlog.c:4524
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr, TimeLineID insertTLI)
Definition: xlog.c:3852
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:6586
static XLogRecPtr RedoRecPtr
Definition: xlog.c:271
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:6618
static void PreallocXlogFiles(XLogRecPtr endptr, TimeLineID tli)
Definition: xlog.c:3677
bool log_checkpoints
Definition: xlog.c:127
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:7883
static int LocalSetXLogInsertAllowed(void)
Definition: xlog.c:6378
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:6493
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:6721
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:573
static int LocalXLogInsertAllowed
Definition: xlog.c:234
CheckpointStatsData CheckpointStats
Definition: xlog.c:207
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2789
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:7440
static void update_checkpoint_display(int flags, bool restartpoint, bool reset)
Definition: xlog.c:6759
#define CHECKPOINT_END_OF_RECOVERY
Definition: xlog.h:140
#define CHECKPOINT_FORCE
Definition: xlog.h:142
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:139
#define XLogStandbyInfoActive()
Definition: xlog.h:123
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)
#define SizeOfXLogShortPHD
Definition: xlog_internal.h:52
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
void XLogRegisterData(char *data, uint32 len)
Definition: xloginsert.c:364
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:474
void XLogBeginInsert(void)
Definition: xloginsert.c:149

References AbsorbSyncRequests(), ControlFileData::checkPoint, CHECKPOINT_END_OF_RECOVERY, CHECKPOINT_FORCE, CHECKPOINT_IS_SHUTDOWN, ControlFileData::checkPointCopy, CheckPointGuts(), CheckpointStats, CheckpointStatsData::ckpt_bufs_written, CheckpointStatsData::ckpt_segs_added, CheckpointStatsData::ckpt_segs_recycled, CheckpointStatsData::ckpt_segs_removed, CheckpointStatsData::ckpt_start_t, XLogCtlData::ckptFullXid, ControlFile, DB_SHUTDOWNED, DB_SHUTDOWNING, DEBUG1, DELAY_CHKPT_COMPLETE, DELAY_CHKPT_START, elog, END_CRIT_SECTION, ereport, errmsg(), errmsg_internal(), ERROR, CheckPoint::fullPageWrites, GetCurrentTimestamp(), GetLastImportantRecPtr(), GetOldestActiveTransactionId(), GetOldestTransactionIdConsideredRunning(), GetVirtualXIDsDelayingChkpt(), HaveVirtualXIDsDelayingChkpt(), XLogCtlData::info_lck, XLogCtlData::Insert, Insert(), INSERT_FREESPACE, XLogCtlData::InsertTimeLineID, InvalidateObsoleteReplicationSlots(), InvalidOid, InvalidTransactionId, InvalidXLogRecPtr, KeepLogSeg(), LocalSetXLogInsertAllowed(), LocalXLogInsertAllowed, log_checkpoints, LogCheckpointEnd(), LogCheckpointStart(), LogStandbySnapshot(), LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockRelease(), MemSet, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, MultiXactGetCheckptMulti(), NBuffers, TransamVariablesData::newestCommitTsXid, CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, TransamVariablesData::nextOid, CheckPoint::nextOid, TransamVariablesData::nextXid, CheckPoint::nextXid, TransamVariablesData::oidCount, CheckPoint::oldestActiveXid, TransamVariablesData::oldestCommitTsXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, TransamVariablesData::oldestXid, CheckPoint::oldestXid, TransamVariablesData::oldestXidDB, CheckPoint::oldestXidDB, PANIC, pfree(), pg_atomic_read_membarrier_u64(), pg_usleep(), pgstat_report_wait_end(), pgstat_report_wait_start(), PreallocXlogFiles(), XLogCtlData::PrevTimeLineID, CheckPoint::PrevTimeLineID, ProcLastRecPtr, RecoveryInProgress(), CheckPoint::redo, RedoRecPtr, XLogCtlInsert::RedoRecPtr, XLogCtlData::RedoRecPtr, RemoveOldXlogFiles(), RS_INVAL_WAL_REMOVED, SetWalSummarizerLatch(), SizeOfXLogLongPHD, SizeOfXLogShortPHD, SpinLockAcquire, SpinLockRelease, START_CRIT_SECTION, ControlFileData::state, SyncPostCheckpoint(), SyncPreCheckpoint(), CheckPoint::ThisTimeLineID, CheckPoint::time, TransamVariables, TruncateSUBTRANS(), XLogCtlData::unloggedLSN, ControlFileData::unloggedLSN, update_checkpoint_display(), UpdateCheckPointDistanceEstimate(), UpdateControlFile(), wal_level, CheckPoint::wal_level, wal_segment_size, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), XLByteToSeg, XLOG_CHECKPOINT_ONLINE, XLOG_CHECKPOINT_REDO, XLOG_CHECKPOINT_SHUTDOWN, XLogBeginInsert(), XLogBytePosToRecPtr(), XLogCtl, XLogFlush(), XLogInsert(), XLogRegisterData(), XLogSegmentOffset, and XLogStandbyInfoActive.

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

◆ CreateRestartPoint()

bool CreateRestartPoint ( int  flags)

Definition at line 7521 of file xlog.c.

7522 {
7523  XLogRecPtr lastCheckPointRecPtr;
7524  XLogRecPtr lastCheckPointEndPtr;
7525  CheckPoint lastCheckPoint;
7526  XLogRecPtr PriorRedoPtr;
7527  XLogRecPtr receivePtr;
7528  XLogRecPtr replayPtr;
7529  TimeLineID replayTLI;
7530  XLogRecPtr endptr;
7531  XLogSegNo _logSegNo;
7532  TimestampTz xtime;
7533 
7534  /* Concurrent checkpoint/restartpoint cannot happen */
7536 
7537  /* Get a local copy of the last safe checkpoint record. */
7539  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
7540  lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
7541  lastCheckPoint = XLogCtl->lastCheckPoint;
7543 
7544  /*
7545  * Check that we're still in recovery mode. It's ok if we exit recovery
7546  * mode after this check, the restart point is valid anyway.
7547  */
7548  if (!RecoveryInProgress())
7549  {
7550  ereport(DEBUG2,
7551  (errmsg_internal("skipping restartpoint, recovery has already ended")));
7552  return false;
7553  }
7554 
7555  /*
7556  * If the last checkpoint record we've replayed is already our last
7557  * restartpoint, we can't perform a new restart point. We still update
7558  * minRecoveryPoint in that case, so that if this is a shutdown restart
7559  * point, we won't start up earlier than before. That's not strictly
7560  * necessary, but when hot standby is enabled, it would be rather weird if
7561  * the database opened up for read-only connections at a point-in-time
7562  * before the last shutdown. Such time travel is still possible in case of
7563  * immediate shutdown, though.
7564  *
7565  * We don't explicitly advance minRecoveryPoint when we do create a
7566  * restartpoint. It's assumed that flushing the buffers will do that as a
7567  * side-effect.
7568  */
7569  if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
7570  lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
7571  {
7572  ereport(DEBUG2,
7573  (errmsg_internal("skipping restartpoint, already performed at %X/%X",
7574  LSN_FORMAT_ARGS(lastCheckPoint.redo))));
7575 
7577  if (flags & CHECKPOINT_IS_SHUTDOWN)
7578  {
7579  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7582  LWLockRelease(ControlFileLock);
7583  }
7584  return false;
7585  }
7586 
7587  /*
7588  * Update the shared RedoRecPtr so that the startup process can calculate
7589  * the number of segments replayed since last restartpoint, and request a
7590  * restartpoint if it exceeds CheckPointSegments.
7591  *
7592  * Like in CreateCheckPoint(), hold off insertions to update it, although
7593  * during recovery this is just pro forma, because no WAL insertions are
7594  * happening.
7595  */
7597  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
7599 
7600  /* Also update the info_lck-protected copy */
7602  XLogCtl->RedoRecPtr = lastCheckPoint.redo;
7604 
7605  /*
7606  * Prepare to accumulate statistics.
7607  *
7608  * Note: because it is possible for log_checkpoints to change while a
7609  * checkpoint proceeds, we always accumulate stats, even if
7610  * log_checkpoints is currently off.
7611  */
7612  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
7614 
7615  if (log_checkpoints)
7616  LogCheckpointStart(flags, true);
7617 
7618  /* Update the process title */
7619  update_checkpoint_display(flags, true, false);
7620 
7621  CheckPointGuts(lastCheckPoint.redo, flags);
7622 
7623  /*
7624  * This location needs to be after CheckPointGuts() to ensure that some
7625  * work has already happened during this checkpoint.
7626  */
7627  INJECTION_POINT("create-restart-point");
7628 
7629  /*
7630  * Remember the prior checkpoint's redo ptr for
7631  * UpdateCheckPointDistanceEstimate()
7632  */
7633  PriorRedoPtr = ControlFile->checkPointCopy.redo;
7634 
7635  /*
7636  * Update pg_control, using current time. Check that it still shows an
7637  * older checkpoint, else do nothing; this is a quick hack to make sure
7638  * nothing really bad happens if somehow we get here after the
7639  * end-of-recovery checkpoint.
7640  */
7641  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7642  if (ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
7643  {
7644  /*
7645  * Update the checkpoint information. We do this even if the cluster
7646  * does not show DB_IN_ARCHIVE_RECOVERY to match with the set of WAL
7647  * segments recycled below.
7648  */
7649  ControlFile->checkPoint = lastCheckPointRecPtr;
7650  ControlFile->checkPointCopy = lastCheckPoint;
7651 
7652  /*
7653  * Ensure minRecoveryPoint is past the checkpoint record and update it
7654  * if the control file still shows DB_IN_ARCHIVE_RECOVERY. Normally,
7655  * this will have happened already while writing out dirty buffers,
7656  * but not necessarily - e.g. because no buffers were dirtied. We do
7657  * this because a backup performed in recovery uses minRecoveryPoint
7658  * to determine which WAL files must be included in the backup, and
7659  * the file (or files) containing the checkpoint record must be
7660  * included, at a minimum. Note that for an ordinary restart of
7661  * recovery there's no value in having the minimum recovery point any
7662  * earlier than this anyway, because redo will begin just after the
7663  * checkpoint record.
7664  */
7666  {
7667  if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
7668  {
7669  ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
7671 
7672  /* update local copy */
7675  }
7676  if (flags & CHECKPOINT_IS_SHUTDOWN)
7678  }
7680  }
7681  LWLockRelease(ControlFileLock);
7682 
7683  /*
7684  * Update the average distance between checkpoints/restartpoints if the
7685  * prior checkpoint exists.
7686  */
7687  if (PriorRedoPtr != InvalidXLogRecPtr)
7689 
7690  /*
7691  * Delete old log files, those no longer needed for last restartpoint to
7692  * prevent the disk holding the xlog from growing full.
7693  */
7695 
7696  /*
7697  * Retreat _logSegNo using the current end of xlog replayed or received,
7698  * whichever is later.
7699  */
7700  receivePtr = GetWalRcvFlushRecPtr(NULL, NULL);
7701  replayPtr = GetXLogReplayRecPtr(&replayTLI);
7702  endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
7703  KeepLogSeg(endptr, &_logSegNo);
7705  _logSegNo, InvalidOid,
7707  {
7708  /*
7709  * Some slots have been invalidated; recalculate the old-segment
7710  * horizon, starting again from RedoRecPtr.
7711  */
7713  KeepLogSeg(endptr, &_logSegNo);
7714  }
7715  _logSegNo--;
7716 
7717  /*
7718  * Try to recycle segments on a useful timeline. If we've been promoted
7719  * since the beginning of this restartpoint, use the new timeline chosen
7720  * at end of recovery. If we're still in recovery, use the timeline we're
7721  * currently replaying.
7722  *
7723  * There is no guarantee that the WAL segments will be useful on the
7724  * current timeline; if recovery proceeds to a new timeline right after
7725  * this, the pre-allocated WAL segments on this timeline will not be used,
7726  * and will go wasted until recycled on the next restartpoint. We'll live
7727  * with that.
7728  */
7729  if (!RecoveryInProgress())
7730  replayTLI = XLogCtl->InsertTimeLineID;
7731 
7732  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr, replayTLI);
7733 
7734  /*
7735  * Make more log segments if needed. (Do this after recycling old log
7736  * segments, since that may supply some of the needed files.)
7737  */
7738  PreallocXlogFiles(endptr, replayTLI);
7739 
7740  /*
7741  * Truncate pg_subtrans if possible. We can throw away all data before
7742  * the oldest XMIN of any running transaction. No future transaction will
7743  * attempt to reference any pg_subtrans entry older than that (see Asserts
7744  * in subtrans.c). When hot standby is disabled, though, we mustn't do
7745  * this because StartupSUBTRANS hasn't been called yet.
7746  */
7747  if (EnableHotStandby)
7749 
7750  /* Real work is done; log and update stats. */
7751  LogCheckpointEnd(true);
7752 
7753  /* Reset the process title */
7754  update_checkpoint_display(flags, true, true);
7755 
7756  xtime = GetLatestXTime();
7758  (errmsg("recovery restart point at %X/%X",
7759  LSN_FORMAT_ARGS(lastCheckPoint.redo)),
7760  xtime ? errdetail("Last completed transaction was at log time %s.",
7761  timestamptz_to_str(xtime)) : 0));
7762 
7763  /*
7764  * Finally, execute archive_cleanup_command, if any.
7765  */
7766  if (archiveCleanupCommand && strcmp(archiveCleanupCommand, "") != 0)
7768  "archive_cleanup_command",
7769  false,
7770  WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND);
7771 
7772  return true;
7773 }
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1854
int64 TimestampTz
Definition: timestamp.h:39
int errdetail(const char *fmt,...)
Definition: elog.c:1203
#define LOG
Definition: elog.h:31
#define DEBUG2
Definition: elog.h:29
bool IsUnderPostmaster
Definition: globals.c:118
#define INJECTION_POINT(name)
@ B_CHECKPOINTER
Definition: miscadmin.h:357
BackendType MyBackendType
Definition: miscinit.c:63
@ DB_IN_ARCHIVE_RECOVERY
Definition: pg_control.h:96
@ DB_SHUTDOWNED_IN_RECOVERY
Definition: pg_control.h:93
CheckPoint lastCheckPoint
Definition: xlog.c:538
XLogRecPtr lastCheckPointRecPtr
Definition: xlog.c:536
XLogRecPtr lastCheckPointEndPtr
Definition: xlog.c:537
XLogRecPtr GetWalRcvFlushRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI)
bool EnableHotStandby
Definition: xlog.c:119
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition: xlog.c:2709
static XLogRecPtr LocalMinRecoveryPoint
Definition: xlog.c:639
static TimeLineID LocalMinRecoveryPointTLI
Definition: xlog.c:640
void ExecuteRecoveryCommand(const char *command, const char *commandName, bool failOnSignal, uint32 wait_event_info)
Definition: xlogarchive.c:295
#define LSN_FORMAT_ARGS(lsn)
Definition: xlogdefs.h:43
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
uint32 TimeLineID
Definition: xlogdefs.h:59
char * archiveCleanupCommand
Definition: xlogrecovery.c:84
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
TimestampTz GetLatestXTime(void)

References archiveCleanupCommand, Assert, B_CHECKPOINTER, ControlFileData::checkPoint, CHECKPOINT_IS_SHUTDOWN, ControlFileData::checkPointCopy, CheckPointGuts(), CheckpointStats, CheckpointStatsData::ckpt_start_t, ControlFile, DB_IN_ARCHIVE_RECOVERY, DB_SHUTDOWNED_IN_RECOVERY, DEBUG2, EnableHotStandby, ereport, errdetail(), errmsg(), errmsg_internal(), ExecuteRecoveryCommand(), GetCurrentTimestamp(), GetLatestXTime(), GetOldestTransactionIdConsideredRunning(), GetWalRcvFlushRecPtr(), GetXLogReplayRecPtr(), XLogCtlData::info_lck, INJECTION_POINT, XLogCtlData::Insert, XLogCtlData::InsertTimeLineID, InvalidateObsoleteReplicationSlots(), InvalidOid, InvalidTransactionId, InvalidXLogRecPtr, IsUnderPostmaster, KeepLogSeg(), XLogCtlData::lastCheckPoint, XLogCtlData::lastCheckPointEndPtr, XLogCtlData::lastCheckPointRecPtr, LocalMinRecoveryPoint, LocalMinRecoveryPointTLI, LOG, log_checkpoints, LogCheckpointEnd(), LogCheckpointStart(), LSN_FORMAT_ARGS, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MemSet, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, MyBackendType, PreallocXlogFiles(), RecoveryInProgress(), CheckPoint::redo, RedoRecPtr, XLogCtlInsert::RedoRecPtr, XLogCtlData::RedoRecPtr, RemoveOldXlogFiles(), RS_INVAL_WAL_REMOVED, SpinLockAcquire, SpinLockRelease, ControlFileData::state, CheckPoint::ThisTimeLineID, timestamptz_to_str(), TruncateSUBTRANS(), update_checkpoint_display(), UpdateCheckPointDistanceEstimate(), UpdateControlFile(), UpdateMinRecoveryPoint(), wal_segment_size, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), XLByteToSeg, XLogCtl, and XLogRecPtrIsInvalid.

Referenced by CheckpointerMain(), and ShutdownXLOG().

◆ DataChecksumsEnabled()

◆ do_pg_abort_backup()

void do_pg_abort_backup ( int  code,
Datum  arg 
)

Definition at line 9324 of file xlog.c.

9325 {
9326  bool during_backup_start = DatumGetBool(arg);
9327 
9328  /* If called during backup start, there shouldn't be one already running */
9329  Assert(!during_backup_start || sessionBackupState == SESSION_BACKUP_NONE);
9330 
9331  if (during_backup_start || sessionBackupState != SESSION_BACKUP_NONE)
9332  {
9336 
9339 
9340  if (!during_backup_start)
9341  ereport(WARNING,
9342  errmsg("aborting backup due to backend exiting before pg_backup_stop was called"));
9343  }
9344 }
#define WARNING
Definition: elog.h:36
void * arg
static bool DatumGetBool(Datum X)
Definition: postgres.h:90
int runningBackups
Definition: xlog.c:436
static SessionBackupState sessionBackupState
Definition: xlog.c:389

References arg, Assert, DatumGetBool(), ereport, errmsg(), XLogCtlData::Insert, XLogCtlInsert::runningBackups, SESSION_BACKUP_NONE, sessionBackupState, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), WARNING, and XLogCtl.

Referenced by do_pg_backup_start(), perform_base_backup(), and register_persistent_abort_backup_handler().

◆ do_pg_backup_start()

void do_pg_backup_start ( const char *  backupidstr,
bool  fast,
List **  tablespaces,
BackupState state,
StringInfo  tblspcmapfile 
)

Definition at line 8722 of file xlog.c.

8724 {
8726 
8727  Assert(state != NULL);
8729 
8730  /*
8731  * During recovery, we don't need to check WAL level. Because, if WAL
8732  * level is not sufficient, it's impossible to get here during recovery.
8733  */
8735  ereport(ERROR,
8736  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8737  errmsg("WAL level not sufficient for making an online backup"),
8738  errhint("\"wal_level\" must be set to \"replica\" or \"logical\" at server start.")));
8739 
8740  if (strlen(backupidstr) > MAXPGPATH)
8741  ereport(ERROR,
8742  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8743  errmsg("backup label too long (max %d bytes)",
8744  MAXPGPATH)));
8745 
8746  strlcpy(state->name, backupidstr, sizeof(state->name));
8747 
8748  /*
8749  * Mark backup active in shared memory. We must do full-page WAL writes
8750  * during an on-line backup even if not doing so at other times, because
8751  * it's quite possible for the backup dump to obtain a "torn" (partially
8752  * written) copy of a database page if it reads the page concurrently with
8753  * our write to the same page. This can be fixed as long as the first
8754  * write to the page in the WAL sequence is a full-page write. Hence, we
8755  * increment runningBackups then force a CHECKPOINT, to ensure there are
8756  * no dirty pages in shared memory that might get dumped while the backup
8757  * is in progress without having a corresponding WAL record. (Once the
8758  * backup is complete, we need not force full-page writes anymore, since
8759  * we expect that any pages not modified during the backup interval must
8760  * have been correctly captured by the backup.)
8761  *
8762  * Note that forcing full-page writes has no effect during an online
8763  * backup from the standby.
8764  *
8765  * We must hold all the insertion locks to change the value of
8766  * runningBackups, to ensure adequate interlocking against
8767  * XLogInsertRecord().
8768  */
8772 
8773  /*
8774  * Ensure we decrement runningBackups if we fail below. NB -- for this to
8775  * work correctly, it is critical that sessionBackupState is only updated
8776  * after this block is over.
8777  */
8779  {
8780  bool gotUniqueStartpoint = false;
8781  DIR *tblspcdir;
8782  struct dirent *de;
8783  tablespaceinfo *ti;
8784  int datadirpathlen;
8785 
8786  /*
8787  * Force an XLOG file switch before the checkpoint, to ensure that the
8788  * WAL segment the checkpoint is written to doesn't contain pages with
8789  * old timeline IDs. That would otherwise happen if you called
8790  * pg_backup_start() right after restoring from a PITR archive: the
8791  * first WAL segment containing the startup checkpoint has pages in
8792  * the beginning with the old timeline ID. That can cause trouble at
8793  * recovery: we won't have a history file covering the old timeline if
8794  * pg_wal directory was not included in the base backup and the WAL
8795  * archive was cleared too before starting the backup.
8796  *
8797  * This also ensures that we have emitted a WAL page header that has
8798  * XLP_BKP_REMOVABLE off before we emit the checkpoint record.
8799  * Therefore, if a WAL archiver (such as pglesslog) is trying to
8800  * compress out removable backup blocks, it won't remove any that
8801  * occur after this point.
8802  *
8803  * During recovery, we skip forcing XLOG file switch, which means that
8804  * the backup taken during recovery is not available for the special
8805  * recovery case described above.
8806  */
8808  RequestXLogSwitch(false);
8809 
8810  do
8811  {
8812  bool checkpointfpw;
8813 
8814  /*
8815  * Force a CHECKPOINT. Aside from being necessary to prevent torn
8816  * page problems, this guarantees that two successive backup runs
8817  * will have different checkpoint positions and hence different
8818  * history file names, even if nothing happened in between.
8819  *
8820  * During recovery, establish a restartpoint if possible. We use
8821  * the last restartpoint as the backup starting checkpoint. This
8822  * means that two successive backup runs can have same checkpoint
8823  * positions.
8824  *
8825  * Since the fact that we are executing do_pg_backup_start()
8826  * during recovery means that checkpointer is running, we can use
8827  * RequestCheckpoint() to establish a restartpoint.
8828  *
8829  * We use CHECKPOINT_IMMEDIATE only if requested by user (via
8830  * passing fast = true). Otherwise this can take awhile.
8831  */
8833  (fast ? CHECKPOINT_IMMEDIATE : 0));
8834 
8835  /*
8836  * Now we need to fetch the checkpoint record location, and also
8837  * its REDO pointer. The oldest point in WAL that would be needed
8838  * to restore starting from the checkpoint is precisely the REDO
8839  * pointer.
8840  */
8841  LWLockAcquire(ControlFileLock, LW_SHARED);
8842  state->checkpointloc = ControlFile->checkPoint;
8843  state->startpoint = ControlFile->checkPointCopy.redo;
8845  checkpointfpw = ControlFile->checkPointCopy.fullPageWrites;
8846  LWLockRelease(ControlFileLock);
8847 
8849  {
8850  XLogRecPtr recptr;
8851 
8852  /*
8853  * Check to see if all WAL replayed during online backup
8854  * (i.e., since last restartpoint used as backup starting
8855  * checkpoint) contain full-page writes.
8856  */
8858  recptr = XLogCtl->lastFpwDisableRecPtr;
8860 
8861  if (!checkpointfpw || state->startpoint <= recptr)
8862  ereport(ERROR,
8863  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8864  errmsg("WAL generated with \"full_page_writes=off\" was replayed "
8865  "since last restartpoint"),
8866  errhint("This means that the backup being taken on the standby "
8867  "is corrupt and should not be used. "
8868  "Enable \"full_page_writes\" and run CHECKPOINT on the primary, "
8869  "and then try an online backup again.")));
8870 
8871  /*
8872  * During recovery, since we don't use the end-of-backup WAL
8873  * record and don't write the backup history file, the
8874  * starting WAL location doesn't need to be unique. This means
8875  * that two base backups started at the same time might use
8876  * the same checkpoint as starting locations.
8877  */
8878  gotUniqueStartpoint = true;
8879  }
8880 
8881  /*
8882  * If two base backups are started at the same time (in WAL sender
8883  * processes), we need to make sure that they use different
8884  * checkpoints as starting locations, because we use the starting
8885  * WAL location as a unique identifier for the base backup in the
8886  * end-of-backup WAL record and when we write the backup history
8887  * file. Perhaps it would be better generate a separate unique ID
8888  * for each backup instead of forcing another checkpoint, but
8889  * taking a checkpoint right after another is not that expensive
8890  * either because only few buffers have been dirtied yet.
8891  */
8893  if (XLogCtl->Insert.lastBackupStart < state->startpoint)
8894  {
8895  XLogCtl->Insert.lastBackupStart = state->startpoint;
8896  gotUniqueStartpoint = true;
8897  }
8899  } while (!gotUniqueStartpoint);
8900 
8901  /*
8902  * Construct tablespace_map file.
8903  */
8904  datadirpathlen = strlen(DataDir);
8905 
8906  /* Collect information about all tablespaces */
8907  tblspcdir = AllocateDir("pg_tblspc");
8908  while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL)
8909  {
8910  char fullpath[MAXPGPATH + 10];
8911  char linkpath[MAXPGPATH];
8912  char *relpath = NULL;
8913  char *s;
8914  PGFileType de_type;
8915  char *badp;
8916  Oid tsoid;
8917 
8918  /*
8919  * Try to parse the directory name as an unsigned integer.
8920  *
8921  * Tablespace directories should be positive integers that can be
8922  * represented in 32 bits, with no leading zeroes or trailing
8923  * garbage. If we come across a name that doesn't meet those
8924  * criteria, skip it.
8925  */
8926  if (de->d_name[0] < '1' || de->d_name[1] > '9')
8927  continue;
8928  errno = 0;
8929  tsoid = strtoul(de->d_name, &badp, 10);
8930  if (*badp != '\0' || errno == EINVAL || errno == ERANGE)
8931  continue;
8932 
8933  snprintf(fullpath, sizeof(fullpath), "pg_tblspc/%s", de->d_name);
8934 
8935  de_type = get_dirent_type(fullpath, de, false, ERROR);
8936 
8937  if (de_type == PGFILETYPE_LNK)
8938  {
8939  StringInfoData escapedpath;
8940  int rllen;
8941 
8942  rllen = readlink(fullpath, linkpath, sizeof(linkpath));
8943  if (rllen < 0)
8944  {
8945  ereport(WARNING,
8946  (errmsg("could not read symbolic link \"%s\": %m",
8947  fullpath)));
8948  continue;
8949  }
8950  else if (rllen >= sizeof(linkpath))
8951  {
8952  ereport(WARNING,
8953  (errmsg("symbolic link \"%s\" target is too long",
8954  fullpath)));
8955  continue;
8956  }
8957  linkpath[rllen] = '\0';
8958 
8959  /*
8960  * Relpath holds the relative path of the tablespace directory
8961  * when it's located within PGDATA, or NULL if it's located
8962  * elsewhere.
8963  */
8964  if (rllen > datadirpathlen &&
8965  strncmp(linkpath, DataDir, datadirpathlen) == 0 &&
8966  IS_DIR_SEP(linkpath[datadirpathlen]))
8967  relpath = pstrdup(linkpath + datadirpathlen + 1);
8968 
8969  /*
8970  * Add a backslash-escaped version of the link path to the
8971  * tablespace map file.
8972  */
8973  initStringInfo(&escapedpath);
8974  for (s = linkpath; *s; s++)
8975  {
8976  if (*s == '\n' || *s == '\r' || *s == '\\')
8977  appendStringInfoChar(&escapedpath, '\\');
8978  appendStringInfoChar(&escapedpath, *s);
8979  }
8980  appendStringInfo(tblspcmapfile, "%s %s\n",
8981  de->d_name, escapedpath.data);
8982  pfree(escapedpath.data);
8983  }
8984  else if (de_type == PGFILETYPE_DIR)
8985  {
8986  /*
8987  * It's possible to use allow_in_place_tablespaces to create
8988  * directories directly under pg_tblspc, for testing purposes
8989  * only.
8990  *
8991  * In this case, we store a relative path rather than an
8992  * absolute path into the tablespaceinfo.
8993  */
8994  snprintf(linkpath, sizeof(linkpath), "pg_tblspc/%s",
8995  de->d_name);
8996  relpath = pstrdup(linkpath);
8997  }
8998  else
8999  {
9000  /* Skip any other file type that appears here. */
9001  continue;
9002  }
9003 
9004  ti = palloc(sizeof(tablespaceinfo));
9005  ti->oid = tsoid;
9006  ti->path = pstrdup(linkpath);
9007  ti->rpath = relpath;
9008  ti->size = -1;
9009 
9010  if (tablespaces)
9011  *tablespaces = lappend(*tablespaces, ti);
9012  }
9013  FreeDir(tblspcdir);
9014 
9015  state->starttime = (pg_time_t) time(NULL);
9016  }
9018 
9019  state->started_in_recovery = backup_started_in_recovery;
9020 
9021  /*
9022  * Mark that the start phase has correctly finished for the backup.
9023  */
9025 }
static bool backup_started_in_recovery
Definition: basebackup.c:123
void RequestCheckpoint(int flags)
Definition: checkpointer.c:941
int errhint(const char *fmt,...)
Definition: elog.c:1317
int errcode(int sqlerrcode)
Definition: elog.c:853
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2909
int FreeDir(DIR *dir)
Definition: fd.c:2961
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2843
PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
Definition: file_utils.c:525
PGFileType
Definition: file_utils.h:19
@ PGFILETYPE_LNK
Definition: file_utils.h:24
@ PGFILETYPE_DIR
Definition: file_utils.h:23
char * DataDir
Definition: globals.c:69
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:47
#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:52
List * lappend(List *list, void *datum)
Definition: list.c:339
char * pstrdup(const char *in)
Definition: mcxt.c:1696
#define MAXPGPATH
#define snprintf
Definition: port.h:238
#define IS_DIR_SEP(ch)
Definition: port.h:102
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
unsigned int Oid
Definition: postgres_ext.h:31
#define relpath(rlocator, forknum)
Definition: relpath.h:94
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:194
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
Definition: dirent.c:26
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:544
XLogRecPtr lastBackupStart
Definition: xlog.c:437
Definition: dirent.h:10
char d_name[MAX_PATH]
Definition: dirent.h:15
Definition: regguts.h:323
char * rpath
Definition: basebackup.h:32
#define readlink(path, buf, size)
Definition: win32_port.h:236
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:7990
void do_pg_abort_backup(int code, Datum arg)
Definition: xlog.c:9324
@ SESSION_BACKUP_RUNNING
Definition: xlog.h:286
#define CHECKPOINT_WAIT
Definition: xlog.h:145
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:141
#define XLogIsNeeded()
Definition: xlog.h:109

References AllocateDir(), appendStringInfo(), appendStringInfoChar(), Assert, backup_started_in_recovery, ControlFileData::checkPoint, CHECKPOINT_FORCE, CHECKPOINT_IMMEDIATE, CHECKPOINT_WAIT, ControlFileData::checkPointCopy, ControlFile, dirent::d_name, StringInfoData::data, DataDir, DatumGetBool(), do_pg_abort_backup(), ereport, errcode(), errhint(), errmsg(), ERROR, FreeDir(), CheckPoint::fullPageWrites, get_dirent_type(), XLogCtlData::info_lck, initStringInfo(), XLogCtlData::Insert, IS_DIR_SEP, lappend(), XLogCtlInsert::lastBackupStart, XLogCtlData::lastFpwDisableRecPtr, LW_SHARED, LWLockAcquire(), LWLockRelease(), MAXPGPATH, tablespaceinfo::oid, palloc(), tablespaceinfo::path, pfree(), PG_END_ENSURE_ERROR_CLEANUP, PG_ENSURE_ERROR_CLEANUP, PGFILETYPE_DIR, PGFILETYPE_LNK, pstrdup(), ReadDir(), readlink, RecoveryInProgress(), CheckPoint::redo, relpath, RequestCheckpoint(), RequestXLogSwitch(), tablespaceinfo::rpath, XLogCtlInsert::runningBackups, SESSION_BACKUP_RUNNING, sessionBackupState, tablespaceinfo::size, snprintf, SpinLockAcquire, SpinLockRelease, strlcpy(), CheckPoint::ThisTimeLineID, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), WARNING, XLogCtl, and XLogIsNeeded.

Referenced by perform_base_backup(), and pg_backup_start().

◆ do_pg_backup_stop()

void do_pg_backup_stop ( BackupState state,
bool  waitforarchive 
)

Definition at line 9050 of file xlog.c.

9051 {
9052  bool backup_stopped_in_recovery = false;
9053  char histfilepath[MAXPGPATH];
9054  char lastxlogfilename[MAXFNAMELEN];
9055  char histfilename[MAXFNAMELEN];
9056  XLogSegNo _logSegNo;
9057  FILE *fp;
9058  int seconds_before_warning;
9059  int waits = 0;
9060  bool reported_waiting = false;
9061 
9062  Assert(state != NULL);
9063 
9064  backup_stopped_in_recovery = RecoveryInProgress();
9065 
9066  /*
9067  * During recovery, we don't need to check WAL level. Because, if WAL
9068  * level is not sufficient, it's impossible to get here during recovery.
9069  */
9070  if (!backup_stopped_in_recovery && !XLogIsNeeded())
9071  ereport(ERROR,
9072  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
9073  errmsg("WAL level not sufficient for making an online backup"),
9074  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
9075 
9076  /*
9077  * OK to update backup counter and session-level lock.
9078  *
9079  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating them,
9080  * otherwise they can be updated inconsistently, which might cause
9081  * do_pg_abort_backup() to fail.
9082  */
9084 
9085  /*
9086  * It is expected that each do_pg_backup_start() call is matched by
9087  * exactly one do_pg_backup_stop() call.
9088  */
9091 
9092  /*
9093  * Clean up session-level lock.
9094  *
9095  * You might think that WALInsertLockRelease() can be called before
9096  * cleaning up session-level lock because session-level lock doesn't need
9097  * to be protected with WAL insertion lock. But since
9098  * CHECK_FOR_INTERRUPTS() can occur in it, session-level lock must be
9099  * cleaned up before it.
9100  */
9102 
9104 
9105  /*
9106  * If we are taking an online backup from the standby, we confirm that the
9107  * standby has not been promoted during the backup.
9108  */
9109  if (state->started_in_recovery && !backup_stopped_in_recovery)
9110  ereport(ERROR,
9111  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
9112  errmsg("the standby was promoted during online backup"),
9113  errhint("This means that the backup being taken is corrupt "
9114  "and should not be used. "
9115  "Try taking another online backup.")));
9116 
9117  /*
9118  * During recovery, we don't write an end-of-backup record. We assume that
9119  * pg_control was backed up last and its minimum recovery point can be
9120  * available as the backup end location. Since we don't have an
9121  * end-of-backup record, we use the pg_control value to check whether
9122  * we've reached the end of backup when starting recovery from this
9123  * backup. We have no way of checking if pg_control wasn't backed up last
9124  * however.
9125  *
9126  * We don't force a switch to new WAL file but it is still possible to
9127  * wait for all the required files to be archived if waitforarchive is
9128  * true. This is okay if we use the backup to start a standby and fetch
9129  * the missing WAL using streaming replication. But in the case of an
9130  * archive recovery, a user should set waitforarchive to true and wait for
9131  * them to be archived to ensure that all the required files are
9132  * available.
9133  *
9134  * We return the current minimum recovery point as the backup end
9135  * location. Note that it can be greater than the exact backup end
9136  * location if the minimum recovery point is updated after the backup of
9137  * pg_control. This is harmless for current uses.
9138  *
9139  * XXX currently a backup history file is for informational and debug
9140  * purposes only. It's not essential for an online backup. Furthermore,
9141  * even if it's created, it will not be archived during recovery because
9142  * an archiver is not invoked. So it doesn't seem worthwhile to write a
9143  * backup history file during recovery.
9144  */
9145  if (backup_stopped_in_recovery)
9146  {
9147  XLogRecPtr recptr;
9148 
9149  /*
9150  * Check to see if all WAL replayed during online backup contain
9151  * full-page writes.
9152  */
9154  recptr = XLogCtl->lastFpwDisableRecPtr;
9156 
9157  if (state->startpoint <= recptr)
9158  ereport(ERROR,
9159  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
9160  errmsg("WAL generated with \"full_page_writes=off\" was replayed "
9161  "during online backup"),
9162  errhint("This means that the backup being taken on the standby "
9163  "is corrupt and should not be used. "
9164  "Enable \"full_page_writes\" and run CHECKPOINT on the primary, "
9165  "and then try an online backup again.")));
9166 
9167 
9168  LWLockAcquire(ControlFileLock, LW_SHARED);
9169  state->stoppoint = ControlFile->minRecoveryPoint;
9171  LWLockRelease(ControlFileLock);
9172  }
9173  else
9174  {
9175  char *history_file;
9176 
9177  /*
9178  * Write the backup-end xlog record
9179  */
9180  XLogBeginInsert();
9181  XLogRegisterData((char *) (&state->startpoint),
9182  sizeof(state->startpoint));
9183  state->stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
9184 
9185  /*
9186  * Given that we're not in recovery, InsertTimeLineID is set and can't
9187  * change, so we can read it without a lock.
9188  */
9189  state->stoptli = XLogCtl->InsertTimeLineID;
9190 
9191  /*
9192  * Force a switch to a new xlog segment file, so that the backup is
9193  * valid as soon as archiver moves out the current segment file.
9194  */
9195  RequestXLogSwitch(false);
9196 
9197  state->stoptime = (pg_time_t) time(NULL);
9198 
9199  /*
9200  * Write the backup history file
9201  */
9202  XLByteToSeg(state->startpoint, _logSegNo, wal_segment_size);
9203  BackupHistoryFilePath(histfilepath, state->stoptli, _logSegNo,
9204  state->startpoint, wal_segment_size);
9205  fp = AllocateFile(histfilepath, "w");
9206  if (!fp)
9207  ereport(ERROR,
9209  errmsg("could not create file \"%s\": %m",
9210  histfilepath)));
9211 
9212  /* Build and save the contents of the backup history file */
9213  history_file = build_backup_content(state, true);
9214  fprintf(fp, "%s", history_file);
9215  pfree(history_file);
9216 
9217  if (fflush(fp) || ferror(fp) || FreeFile(fp))
9218  ereport(ERROR,
9220  errmsg("could not write file \"%s\": %m",
9221  histfilepath)));
9222 
9223  /*
9224  * Clean out any no-longer-needed history files. As a side effect,
9225  * this will post a .ready file for the newly created history file,
9226  * notifying the archiver that history file may be archived
9227  * immediately.
9228  */
9230  }
9231 
9232  /*
9233  * If archiving is enabled, wait for all the required WAL files to be
9234  * archived before returning. If archiving isn't enabled, the required WAL
9235  * needs to be transported via streaming replication (hopefully with
9236  * wal_keep_size set high enough), or some more exotic mechanism like
9237  * polling and copying files from pg_wal with script. We have no knowledge
9238  * of those mechanisms, so it's up to the user to ensure that he gets all
9239  * the required WAL.
9240  *
9241  * We wait until both the last WAL file filled during backup and the
9242  * history file have been archived, and assume that the alphabetic sorting
9243  * property of the WAL files ensures any earlier WAL files are safely
9244  * archived as well.
9245  *
9246  * We wait forever, since archive_command is supposed to work and we
9247  * assume the admin wanted his backup to work completely. If you don't
9248  * wish to wait, then either waitforarchive should be passed in as false,
9249  * or you can set statement_timeout. Also, some notices are issued to
9250  * clue in anyone who might be doing this interactively.
9251  */
9252 
9253  if (waitforarchive &&
9254  ((!backup_stopped_in_recovery && XLogArchivingActive()) ||
9255  (backup_stopped_in_recovery && XLogArchivingAlways())))
9256  {
9257  XLByteToPrevSeg(state->stoppoint, _logSegNo, wal_segment_size);
9258  XLogFileName(lastxlogfilename, state->stoptli, _logSegNo,
9260 
9261  XLByteToSeg(state->startpoint, _logSegNo, wal_segment_size);
9262  BackupHistoryFileName(histfilename, state->stoptli, _logSegNo,
9263  state->startpoint, wal_segment_size);
9264 
9265  seconds_before_warning = 60;
9266  waits = 0;
9267 
9268  while (XLogArchiveIsBusy(lastxlogfilename) ||
9269  XLogArchiveIsBusy(histfilename))
9270  {
9272 
9273  if (!reported_waiting && waits > 5)
9274  {
9275  ereport(NOTICE,
9276  (errmsg("base backup done, waiting for required WAL segments to be archived")));
9277  reported_waiting = true;
9278  }
9279 
9280  (void) WaitLatch(MyLatch,
9282  1000L,
9283  WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE);
9285 
9286  if (++waits >= seconds_before_warning)
9287  {
9288  seconds_before_warning *= 2; /* This wraps in >10 years... */
9289  ereport(WARNING,
9290  (errmsg("still waiting for all required WAL segments to be archived (%d seconds elapsed)",
9291  waits),
9292  errhint("Check that your \"archive_command\" is executing properly. "
9293  "You can safely cancel this backup, "
9294  "but the database backup will not be usable without all the WAL segments.")));
9295  }
9296  }
9297 
9298  ereport(NOTICE,
9299  (errmsg("all required WAL segments have been archived")));
9300  }
9301  else if (waitforarchive)
9302  ereport(NOTICE,
9303  (errmsg("WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup")));
9304 }
#define NOTICE
Definition: elog.h:35
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2583
int FreeFile(FILE *file)
Definition: fd.c:2781
struct Latch * MyLatch
Definition: globals.c:61
void ResetLatch(Latch *latch)
Definition: latch.c:724
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:517
#define WL_TIMEOUT
Definition: latch.h:130
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:132
#define WL_LATCH_SET
Definition: latch.h:127
static void const char fflush(stdout)
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
#define XLOG_BACKUP_END
Definition: pg_control.h:73
#define fprintf
Definition: port.h:242
static void CleanupBackupHistory(void)
Definition: xlog.c:4148
#define XLogArchivingActive()
Definition: xlog.h:99
#define XLogArchivingAlways()
Definition: xlog.h:102
#define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes)
static void BackupHistoryFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr startpoint, int wal_segsz_bytes)
static void BackupHistoryFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr startpoint, int wal_segsz_bytes)
bool XLogArchiveIsBusy(const char *xlog)
Definition: xlogarchive.c:619
char * build_backup_content(BackupState *state, bool ishistoryfile)
Definition: xlogbackup.c:29

References AllocateFile(), Assert, BackupHistoryFileName(), BackupHistoryFilePath(), build_backup_content(), CHECK_FOR_INTERRUPTS, CleanupBackupHistory(), ControlFile, ereport, errcode(), errcode_for_file_access(), errhint(), errmsg(), ERROR, fflush(), fprintf, FreeFile(), XLogCtlData::info_lck, XLogCtlData::Insert, XLogCtlData::InsertTimeLineID, XLogCtlData::lastFpwDisableRecPtr, LW_SHARED, LWLockAcquire(), LWLockRelease(), MAXFNAMELEN, MAXPGPATH, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, MyLatch, NOTICE, pfree(), RecoveryInProgress(), RequestXLogSwitch(), ResetLatch(), XLogCtlInsert::runningBackups, SESSION_BACKUP_NONE, sessionBackupState, SpinLockAcquire, SpinLockRelease, WaitLatch(), wal_segment_size, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), WARNING, WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, WL_TIMEOUT, XLByteToPrevSeg, XLByteToSeg, XLOG_BACKUP_END, XLogArchiveIsBusy(), XLogArchivingActive, XLogArchivingAlways, XLogBeginInsert(), XLogCtl, XLogFileName(), XLogInsert(), XLogIsNeeded, and XLogRegisterData().

Referenced by perform_base_backup(), and pg_backup_stop().

◆ get_backup_status()

SessionBackupState get_backup_status ( void  )

Definition at line 9031 of file xlog.c.

9032 {
9033  return sessionBackupState;
9034 }

References sessionBackupState.

Referenced by pg_backup_start(), pg_backup_stop(), and SendBaseBackup().

◆ GetActiveWalLevelOnStandby()

WalLevel GetActiveWalLevelOnStandby ( void  )

Definition at line 4824 of file xlog.c.

4825 {
4826  return ControlFile->wal_level;
4827 }

References ControlFile, and ControlFileData::wal_level.

Referenced by CheckLogicalDecodingRequirements().

◆ GetFakeLSNForUnloggedRel()

XLogRecPtr GetFakeLSNForUnloggedRel ( void  )

Definition at line 4569 of file xlog.c.

4570 {
4572 }
static uint64 pg_atomic_fetch_add_u64(volatile pg_atomic_uint64 *ptr, int64 add_)
Definition: atomics.h:515

References pg_atomic_fetch_add_u64(), XLogCtlData::unloggedLSN, and XLogCtl.

Referenced by gistGetFakeLSN().

◆ GetFlushRecPtr()

XLogRecPtr GetFlushRecPtr ( TimeLineID insertTLI)

Definition at line 6455 of file xlog.c.

6456 {
6458 
6460 
6461  /*
6462  * If we're writing and flushing WAL, the time line can't be changing, so
6463  * no lock is required.
6464  */
6465  if (insertTLI)
6466  *insertTLI = XLogCtl->InsertTimeLineID;
6467 
6468  return LogwrtResult.Flush;
6469 }
RecoveryState SharedRecoveryState
Definition: xlog.c:509
XLogRecPtr Flush
Definition: xlog.c:326
#define RefreshXLogWriteResult(_target)
Definition: xlog.c:613
static XLogwrtResult LogwrtResult
Definition: xlog.c:605

References Assert, XLogwrtResult::Flush, XLogCtlData::InsertTimeLineID, LogwrtResult, RECOVERY_STATE_DONE, RefreshXLogWriteResult, XLogCtlData::SharedRecoveryState, and XLogCtl.

Referenced by binary_upgrade_logical_slot_has_caught_up(), get_flush_position(), GetCurrentLSN(), GetLatestLSN(), IdentifySystem(), pg_current_wal_flush_lsn(), pg_logical_slot_get_changes_guts(), pg_replication_slot_advance(), read_local_xlog_page_guts(), StartReplication(), WalSndWaitForWal(), XLogSendLogical(), and XLogSendPhysical().

◆ GetFullPageWriteInfo()

void GetFullPageWriteInfo ( XLogRecPtr RedoRecPtr_p,
bool doPageWrites_p 
)

Definition at line 6423 of file xlog.c.

6424 {
6425  *RedoRecPtr_p = RedoRecPtr;
6426  *doPageWrites_p = doPageWrites;
6427 }
static bool doPageWrites
Definition: xlog.c:284

References doPageWrites, and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )

Definition at line 6438 of file xlog.c.

6439 {
6440  XLogRecPtr recptr;
6441 
6443  recptr = XLogCtl->LogwrtRqst.Write;
6445 
6446  return recptr;
6447 }
XLogwrtRqst LogwrtRqst
Definition: xlog.c:453
XLogRecPtr Write
Definition: xlog.c:319

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

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

◆ GetLastImportantRecPtr()

XLogRecPtr GetLastImportantRecPtr ( void  )

Definition at line 6493 of file xlog.c.

6494 {
6496  int i;
6497 
6498  for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
6499  {
6500  XLogRecPtr last_important;
6501 
6502  /*
6503  * Need to take a lock to prevent torn reads of the LSN, which are
6504  * possible on some of the supported platforms. WAL insert locks only
6505  * support exclusive mode, so we have to use that.
6506  */
6508  last_important = WALInsertLocks[i].l.lastImportantAt;
6509  LWLockRelease(&WALInsertLocks[i].l.lock);
6510 
6511  if (res < last_important)
6512  res = last_important;
6513  }
6514 
6515  return res;
6516 }
int i
Definition: isn.c:73
XLogRecPtr lastImportantAt
Definition: xlog.c:369
WALInsertLock l
Definition: xlog.c:381
static WALInsertLockPadded * WALInsertLocks
Definition: xlog.c:562
#define NUM_XLOGINSERT_LOCKS
Definition: xlog.c:148

References i, InvalidXLogRecPtr, WALInsertLockPadded::l, WALInsertLock::lastImportantAt, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), NUM_XLOGINSERT_LOCKS, res, and WALInsertLocks.

Referenced by BackgroundWriterMain(), CheckArchiveTimeout(), and CreateCheckPoint().

◆ GetMockAuthenticationNonce()

char* GetMockAuthenticationNonce ( void  )

Definition at line 4543 of file xlog.c.

4544 {
4545  Assert(ControlFile != NULL);
4547 }
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition: pg_control.h:229

References Assert, ControlFile, and ControlFileData::mock_authentication_nonce.

Referenced by scram_mock_salt().

◆ GetRecoveryState()

RecoveryState GetRecoveryState ( void  )

Definition at line 6326 of file xlog.c.

6327 {
6328  RecoveryState retval;
6329 
6331  retval = XLogCtl->SharedRecoveryState;
6333 
6334  return retval;
6335 }

References XLogCtlData::info_lck, XLogCtlData::SharedRecoveryState, SpinLockAcquire, SpinLockRelease, and XLogCtl.

Referenced by XLogArchiveCheckDone().

◆ GetRedoRecPtr()

XLogRecPtr GetRedoRecPtr ( void  )

Definition at line 6393 of file xlog.c.

6394 {
6395  XLogRecPtr ptr;
6396 
6397  /*
6398  * The possibly not up-to-date copy in XlogCtl is enough. Even if we
6399  * grabbed a WAL insertion lock to read the authoritative value in
6400  * Insert->RedoRecPtr, someone might update it just after we've released
6401  * the lock.
6402  */
6404  ptr = XLogCtl->RedoRecPtr;
6406 
6407  if (RedoRecPtr < ptr)
6408  RedoRecPtr = ptr;
6409 
6410  return RedoRecPtr;
6411 }

References XLogCtlData::info_lck, RedoRecPtr, XLogCtlData::RedoRecPtr, SpinLockAcquire, SpinLockRelease, and XLogCtl.

Referenced by CheckPointLogicalRewriteHeap(), CheckPointSnapBuild(), MaybeRemoveOldWalSummaries(), nextval_internal(), ReplicationSlotReserveWal(), smgr_bulk_finish(), smgr_bulk_start_smgr(), XLogPageRead(), XLogSaveBufferForHint(), and XLogWrite().

◆ GetSystemIdentifier()

uint64 GetSystemIdentifier ( void  )

◆ GetWALAvailability()

WALAvailability GetWALAvailability ( XLogRecPtr  targetLSN)

Definition at line 7799 of file xlog.c.

7800 {
7801  XLogRecPtr currpos; /* current write LSN */
7802  XLogSegNo currSeg; /* segid of currpos */
7803  XLogSegNo targetSeg; /* segid of targetLSN */
7804  XLogSegNo oldestSeg; /* actual oldest segid */
7805  XLogSegNo oldestSegMaxWalSize; /* oldest segid kept by max_wal_size */
7806  XLogSegNo oldestSlotSeg; /* oldest segid kept by slot */
7807  uint64 keepSegs;
7808 
7809  /*
7810  * slot does not reserve WAL. Either deactivated, or has never been active
7811  */
7812  if (XLogRecPtrIsInvalid(targetLSN))
7813  return WALAVAIL_INVALID_LSN;
7814 
7815  /*
7816  * Calculate the oldest segment currently reserved by all slots,
7817  * considering wal_keep_size and max_slot_wal_keep_size. Initialize
7818  * oldestSlotSeg to the current segment.
7819  */
7820  currpos = GetXLogWriteRecPtr();
7821  XLByteToSeg(currpos, oldestSlotSeg, wal_segment_size);
7822  KeepLogSeg(currpos, &oldestSlotSeg);
7823 
7824  /*
7825  * Find the oldest extant segment file. We get 1 until checkpoint removes
7826  * the first WAL segment file since startup, which causes the status being
7827  * wrong under certain abnormal conditions but that doesn't actually harm.
7828  */
7829  oldestSeg = XLogGetLastRemovedSegno() + 1;
7830 
7831  /* calculate oldest segment by max_wal_size */
7832  XLByteToSeg(currpos, currSeg, wal_segment_size);
7834 
7835  if (currSeg > keepSegs)
7836  oldestSegMaxWalSize = currSeg - keepSegs;
7837  else
7838  oldestSegMaxWalSize = 1;
7839 
7840  /* the segment we care about */
7841  XLByteToSeg(targetLSN, targetSeg, wal_segment_size);
7842 
7843  /*
7844  * No point in returning reserved or extended status values if the
7845  * targetSeg is known to be lost.
7846  */
7847  if (targetSeg >= oldestSlotSeg)
7848  {
7849  /* show "reserved" when targetSeg is within max_wal_size */
7850  if (targetSeg >= oldestSegMaxWalSize)
7851  return WALAVAIL_RESERVED;
7852 
7853  /* being retained by slots exceeding max_wal_size */
7854  return WALAVAIL_EXTENDED;
7855  }
7856 
7857  /* WAL segments are no longer retained but haven't been removed yet */
7858  if (targetSeg >= oldestSeg)
7859  return WALAVAIL_UNRESERVED;
7860 
7861  /* Definitely lost */
7862  return WALAVAIL_REMOVED;
7863 }
XLogSegNo XLogGetLastRemovedSegno(void)
Definition: xlog.c:3745
int max_wal_size_mb
Definition: xlog.c:112
#define ConvertToXSegs(x, segsize)
Definition: xlog.c:596
XLogRecPtr GetXLogWriteRecPtr(void)
Definition: xlog.c:9381
@ WALAVAIL_REMOVED
Definition: xlog.h:193

References ConvertToXSegs, GetXLogWriteRecPtr(), KeepLogSeg(), max_wal_size_mb, wal_segment_size, WALAVAIL_EXTENDED, WALAVAIL_INVALID_LSN, WALAVAIL_REMOVED, WALAVAIL_RESERVED, WALAVAIL_UNRESERVED, XLByteToSeg, XLogGetLastRemovedSegno(), and XLogRecPtrIsInvalid.

Referenced by pg_get_replication_slots().

◆ GetWALInsertionTimeLine()

TimeLineID GetWALInsertionTimeLine ( void  )

Definition at line 6476 of file xlog.c.

6477 {
6479 
6480  /* Since the value can't be changing, no lock is required. */
6481  return XLogCtl->InsertTimeLineID;
6482 }

References Assert, XLogCtlData::InsertTimeLineID, RECOVERY_STATE_DONE, XLogCtlData::SharedRecoveryState, and XLogCtl.

Referenced by logical_read_xlog_page(), pg_walfile_name(), pg_walfile_name_offset(), ReadReplicationSlot(), WALReadFromBuffers(), and XLogSendPhysical().

◆ GetXLogInsertRecPtr()

XLogRecPtr GetXLogInsertRecPtr ( void  )

Definition at line 9365 of file xlog.c.

9366 {
9368  uint64 current_bytepos;
9369 
9370  SpinLockAcquire(&Insert->insertpos_lck);
9371  current_bytepos = Insert->CurrBytePos;
9372  SpinLockRelease(&Insert->insertpos_lck);
9373 
9374  return XLogBytePosToRecPtr(current_bytepos);
9375 }

References XLogCtlData::Insert, Insert(), SpinLockAcquire, SpinLockRelease, XLogBytePosToRecPtr(), and XLogCtl.

Referenced by CreateOverwriteContrecordRecord(), gistGetFakeLSN(), logical_begin_heap_rewrite(), pg_current_wal_insert_lsn(), and ReplicationSlotReserveWal().

◆ GetXLogWriteRecPtr()

XLogRecPtr GetXLogWriteRecPtr ( void  )

Definition at line 9381 of file xlog.c.

9382 {
9384 
9385  return LogwrtResult.Write;
9386 }
XLogRecPtr Write
Definition: xlog.c:325

References LogwrtResult, RefreshXLogWriteResult, and XLogwrtResult::Write.

Referenced by GetWALAvailability(), pg_attribute_noreturn(), pg_current_wal_lsn(), and pg_get_replication_slots().

◆ InitializeWalConsistencyChecking()

void InitializeWalConsistencyChecking ( void  )

Definition at line 4749 of file xlog.c.

4750 {
4752 
4754  {
4755  struct config_generic *guc;
4756 
4757  guc = find_option("wal_consistency_checking", false, false, ERROR);
4758 
4760 
4761  set_config_option_ext("wal_consistency_checking",
4763  guc->scontext, guc->source, guc->srole,
4764  GUC_ACTION_SET, true, ERROR, false);
4765 
4766  /* checking should not be deferred again */
4768  }
4769 }
struct config_generic * find_option(const char *name, bool create_placeholders, bool skip_errors, int elevel)
Definition: guc.c:1234
int set_config_option_ext(const char *name, const char *value, GucContext context, GucSource source, Oid srole, GucAction action, bool changeVal, int elevel, bool is_reload)
Definition: guc.c:3380
@ GUC_ACTION_SET
Definition: guc.h:199
bool process_shared_preload_libraries_done
Definition: miscinit.c:1779
GucContext scontext
Definition: guc_tables.h:167
GucSource source
Definition: guc_tables.h:165
char * wal_consistency_checking_string
Definition: xlog.c:123
static bool check_wal_consistency_checking_deferred
Definition: xlog.c:164

References Assert, check_wal_consistency_checking_deferred, ERROR, find_option(), GUC_ACTION_SET, process_shared_preload_libraries_done, config_generic::scontext, set_config_option_ext(), config_generic::source, config_generic::srole, and wal_consistency_checking_string.

Referenced by PostgresSingleUserMain(), and PostmasterMain().

◆ IsInstallXLogFileSegmentActive()

bool IsInstallXLogFileSegmentActive ( void  )

Definition at line 9422 of file xlog.c.

9423 {
9424  bool result;
9425 
9426  LWLockAcquire(ControlFileLock, LW_SHARED);
9428  LWLockRelease(ControlFileLock);
9429 
9430  return result;
9431 }
bool InstallXLogFileSegmentActive
Definition: xlog.c:519

References XLogCtlData::InstallXLogFileSegmentActive, LW_SHARED, LWLockAcquire(), LWLockRelease(), and XLogCtl.

Referenced by XLogFileRead().

◆ issue_xlog_fsync()

void issue_xlog_fsync ( int  fd,
XLogSegNo  segno,
TimeLineID  tli 
)

Definition at line 8613 of file xlog.c.

8614 {
8615  char *msg = NULL;
8616  instr_time start;
8617 
8618  Assert(tli != 0);
8619 
8620  /*
8621  * Quick exit if fsync is disabled or write() has already synced the WAL
8622  * file.
8623  */
8624  if (!enableFsync ||
8627  return;
8628 
8629  /* Measure I/O timing to sync the WAL file */
8630  if (track_wal_io_timing)
8632  else
8634 
8635  pgstat_report_wait_start(WAIT_EVENT_WAL_SYNC);
8636  switch (wal_sync_method)
8637  {
8638  case WAL_SYNC_METHOD_FSYNC:
8639  if (pg_fsync_no_writethrough(fd) != 0)
8640  msg = _("could not fsync file \"%s\": %m");
8641  break;
8642 #ifdef HAVE_FSYNC_WRITETHROUGH
8644  if (pg_fsync_writethrough(fd) != 0)
8645  msg = _("could not fsync write-through file \"%s\": %m");
8646  break;
8647 #endif
8649  if (pg_fdatasync(fd) != 0)
8650  msg = _("could not fdatasync file \"%s\": %m");
8651  break;
8652  case WAL_SYNC_METHOD_OPEN:
8654  /* not reachable */
8655  Assert(false);
8656  break;
8657  default:
8658  ereport(PANIC,
8659  errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8660  errmsg_internal("unrecognized \"wal_sync_method\": %d", wal_sync_method));
8661  break;
8662  }
8663 
8664  /* PANIC if failed to fsync */
8665  if (msg)
8666  {
8667  char xlogfname[MAXFNAMELEN];
8668  int save_errno = errno;
8669 
8670  XLogFileName(xlogfname, tli, segno, wal_segment_size);
8671  errno = save_errno;
8672  ereport(PANIC,
8674  errmsg(msg, xlogfname)));
8675  }
8676 
8678 
8679  /*
8680  * Increment the I/O timing and the number of times WAL files were synced.
8681  */
8682  if (track_wal_io_timing)
8683  {
8684  instr_time end;
8685 
8688  }
8689 
8691 }
#define _(x)
Definition: elog.c:90
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:441
int pg_fdatasync(int fd)
Definition: fd.c:480
int pg_fsync_writethrough(int fd)
Definition: fd.c:461
bool enableFsync
Definition: globals.c:127
return str start
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:122
#define INSTR_TIME_SET_ZERO(t)
Definition: instr_time.h:172
#define INSTR_TIME_ACCUM_DIFF(x, y, z)
Definition: instr_time.h:184
PgStat_PendingWalStats PendingWalStats
Definition: pgstat_wal.c:24
static int fd(const char *x, int i)
Definition: preproc-init.c:105
instr_time wal_sync_time
Definition: pgstat.h:456
PgStat_Counter wal_sync
Definition: pgstat.h:454
int wal_sync_method
Definition: xlog.c:128
bool track_wal_io_timing
Definition: xlog.c:135

References _, Assert, enableFsync, ereport, errcode(), errcode_for_file_access(), errmsg(), errmsg_internal(), fd(), INSTR_TIME_ACCUM_DIFF, INSTR_TIME_SET_CURRENT, INSTR_TIME_SET_ZERO, MAXFNAMELEN, PANIC, PendingWalStats, pg_fdatasync(), pg_fsync_no_writethrough(), pg_fsync_writethrough(), pgstat_report_wait_end(), pgstat_report_wait_start(), start, track_wal_io_timing, wal_segment_size, PgStat_PendingWalStats::wal_sync, wal_sync_method, WAL_SYNC_METHOD_FDATASYNC, WAL_SYNC_METHOD_FSYNC, WAL_SYNC_METHOD_FSYNC_WRITETHROUGH, WAL_SYNC_METHOD_OPEN, WAL_SYNC_METHOD_OPEN_DSYNC, PgStat_PendingWalStats::wal_sync_time, and XLogFileName().

Referenced by XLogWalRcvFlush(), and XLogWrite().

◆ LocalProcessControlFile()

void LocalProcessControlFile ( bool  reset)

Definition at line 4811 of file xlog.c.

4812 {
4813  Assert(reset || ControlFile == NULL);
4814  ControlFile = palloc(sizeof(ControlFileData));
4815  ReadControlFile();
4816 }
void reset(void)
Definition: sql-declare.c:600

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

Referenced by PostgresSingleUserMain(), PostmasterMain(), and PostmasterStateMachine().

◆ ReachedEndOfBackup()

void ReachedEndOfBackup ( XLogRecPtr  EndRecPtr,
TimeLineID  tli 
)

Definition at line 6203 of file xlog.c.

6204 {
6205  /*
6206  * We have reached the end of base backup, as indicated by pg_control. The
6207  * data on disk is now consistent (unless minRecoveryPoint is further
6208  * ahead, which can happen if we crashed during previous recovery). Reset
6209  * backupStartPoint and backupEndPoint, and update minRecoveryPoint to
6210  * make sure we don't allow starting up at an earlier point even if
6211  * recovery is stopped and restarted soon after this.
6212  */
6213  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6214 
6215  if (ControlFile->minRecoveryPoint < EndRecPtr)
6216  {
6217  ControlFile->minRecoveryPoint = EndRecPtr;
6219  }
6220 
6223  ControlFile->backupEndRequired = false;
6225 
6226  LWLockRelease(ControlFileLock);
6227 }
XLogRecPtr backupStartPoint
Definition: pg_control.h:170
bool backupEndRequired
Definition: pg_control.h:172
XLogRecPtr backupEndPoint
Definition: pg_control.h:171

References ControlFileData::backupEndPoint, ControlFileData::backupEndRequired, ControlFileData::backupStartPoint, ControlFile, InvalidXLogRecPtr, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, and UpdateControlFile().

Referenced by CheckRecoveryConsistency().

◆ RecoveryInProgress()

bool RecoveryInProgress ( void  )

Definition at line 6290 of file xlog.c.

6291 {
6292  /*
6293  * We check shared state each time only until we leave recovery mode. We
6294  * can't re-enter recovery, so there's no need to keep checking after the
6295  * shared variable has once been seen false.
6296  */
6298  return false;
6299  else
6300  {
6301  /*
6302  * use volatile pointer to make sure we make a fresh read of the
6303  * shared variable.
6304  */
6305  volatile XLogCtlData *xlogctl = XLogCtl;
6306 
6308 
6309  /*
6310  * Note: We don't need a memory barrier when we're still in recovery.
6311  * We might exit recovery immediately after return, so the caller
6312  * can't rely on 'true' meaning that we're still in recovery anyway.
6313  */
6314 
6315  return LocalRecoveryInProgress;
6316  }
6317 }
static bool LocalRecoveryInProgress
Definition: xlog.c:222

References LocalRecoveryInProgress, RECOVERY_STATE_DONE, XLogCtlData::SharedRecoveryState, and XLogCtl.

Referenced by BackgroundWriterMain(), BeginReportingGUCOptions(), brin_desummarize_range(), brin_summarize_range(), btree_index_mainfork_expected(), check_transaction_isolation(), check_transaction_read_only(), CheckArchiveTimeout(), CheckLogicalDecodingRequirements(), CheckpointerMain(), ComputeXidHorizons(), CreateCheckPoint(), CreateDecodingContext(), CreateEndOfRecoveryRecord(), CreateOverwriteContrecordRecord(), CreateRestartPoint(), do_pg_backup_start(), do_pg_backup_stop(), error_commit_ts_disabled(), get_relation_info(), GetCurrentLSN(), GetLatestLSN(), GetNewMultiXactId(), GetNewObjectId(), GetNewTransactionId(), GetOldestActiveTransactionId(), GetOldestSafeDecodingTransactionId(), GetRunningTransactionData(), GetSerializableTransactionSnapshot(), GetSerializableTransactionSnapshotInt(), GetSnapshotData(), GetStrictOldestNonRemovableTransactionId(), gin_clean_pending_list(), GlobalVisHorizonKindForRel(), heap_force_common(), heap_page_prune_opt(), IdentifySystem(), InitTempTableNamespace(), IsCheckpointOnSchedule(), LockAcquireExtended(), logical_read_xlog_page(), MaintainLatestCompletedXid(), MarkBufferDirtyHint(), perform_base_backup(), pg_create_restore_point(), pg_current_wal_flush_lsn(), pg_current_wal_insert_lsn(), pg_current_wal_lsn(), pg_get_wal_replay_pause_state(), pg_is_in_recovery(), pg_is_wal_replay_paused(), pg_log_standby_snapshot(), pg_logical_slot_get_changes_guts(), pg_promote(), pg_replication_slot_advance(), pg_sequence_last_value(), pg_switch_wal(), pg_sync_replication_slots(), pg_wal_replay_pause(), pg_wal_replay_resume(), pg_walfile_name(), pg_walfile_name_offset(), PhysicalWakeupLogicalWalSnd(), PrepareRedoAdd(), PrepareRedoRemove(), PreventCommandDuringRecovery(), ProcSleep(), read_local_xlog_page_guts(), ReadReplicationSlot(), recovery_create_dbdir(), ReplicationSlotAlter(), ReplicationSlotCreate(), ReplicationSlotDrop(), ReplicationSlotReserveWal(), replorigin_check_prerequisites(), ReportChangedGUCOptions(), sendDir(), SerialSetActiveSerXmin(), show_in_hot_standby(), ShutdownXLOG(), SnapBuildWaitSnapshot(), standard_ProcessUtility(), StandbySlotsHaveCaughtup(), StartLogicalReplication(), StartReplication(), StartTransaction(), TransactionIdIsInProgress(), TruncateMultiXact(), UpdateFullPageWrites(), verify_heapam(), WALReadFromBuffers(), WalReceiverMain(), WalSndWaitForWal(), xlog_decode(), XLogBackgroundFlush(), XLogFlush(), XLogInsertAllowed(), XLogNeedsFlush(), and XLogSendPhysical().

◆ register_persistent_abort_backup_handler()

void register_persistent_abort_backup_handler ( void  )

Definition at line 9351 of file xlog.c.

9352 {
9353  static bool already_done = false;
9354 
9355  if (already_done)
9356  return;
9358  already_done = true;
9359 }
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:337

References before_shmem_exit(), DatumGetBool(), and do_pg_abort_backup().

Referenced by pg_backup_start().

◆ RemoveNonParentXlogFiles()

void RemoveNonParentXlogFiles ( XLogRecPtr  switchpoint,
TimeLineID  newTLI 
)

Definition at line 3927 of file xlog.c.

3928 {
3929  DIR *xldir;
3930  struct dirent *xlde;
3931  char switchseg[MAXFNAMELEN];
3932  XLogSegNo endLogSegNo;
3933  XLogSegNo switchLogSegNo;
3934  XLogSegNo recycleSegNo;
3935 
3936  /*
3937  * Initialize info about where to begin the work. This will recycle,
3938  * somewhat arbitrarily, 10 future segments.
3939  */
3940  XLByteToPrevSeg(switchpoint, switchLogSegNo, wal_segment_size);
3941  XLByteToSeg(switchpoint, endLogSegNo, wal_segment_size);
3942  recycleSegNo = endLogSegNo + 10;
3943 
3944  /*
3945  * Construct a filename of the last segment to be kept.
3946  */
3947  XLogFileName(switchseg, newTLI, switchLogSegNo, wal_segment_size);
3948 
3949  elog(DEBUG2, "attempting to remove WAL segments newer than log file %s",
3950  switchseg);
3951 
3952  xldir = AllocateDir(XLOGDIR);
3953 
3954  while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
3955  {
3956  /* Ignore files that are not XLOG segments */
3957  if (!IsXLogFileName(xlde->d_name))
3958  continue;
3959 
3960  /*
3961  * Remove files that are on a timeline older than the new one we're
3962  * switching to, but with a segment number >= the first segment on the
3963  * new timeline.
3964  */
3965  if (strncmp(xlde->d_name, switchseg, 8) < 0 &&
3966  strcmp(xlde->d_name + 8, switchseg + 8) > 0)
3967  {
3968  /*
3969  * If the file has already been marked as .ready, however, don't
3970  * remove it yet. It should be OK to remove it - files that are
3971  * not part of our timeline history are not required for recovery
3972  * - but seems safer to let them be archived and removed later.
3973  */
3974  if (!XLogArchiveIsReady(xlde->d_name))
3975  RemoveXlogFile(xlde, recycleSegNo, &endLogSegNo, newTLI);
3976  }
3977  }
3978 
3979  FreeDir(xldir);
3980 }
static void RemoveXlogFile(const struct dirent *segment_de, XLogSegNo recycleSegNo, XLogSegNo *endlogSegNo, TimeLineID insertTLI)
Definition: xlog.c:3996
static bool IsXLogFileName(const char *fname)
#define XLOGDIR
bool XLogArchiveIsReady(const char *xlog)
Definition: xlogarchive.c:694

References AllocateDir(), dirent::d_name, DEBUG2, elog, FreeDir(), IsXLogFileName(), MAXFNAMELEN, ReadDir(), RemoveXlogFile(), wal_segment_size, XLByteToPrevSeg, XLByteToSeg, XLogArchiveIsReady(), XLOGDIR, and XLogFileName().

Referenced by ApplyWalRecord(), and CleanupAfterArchiveRecovery().

◆ SetInstallXLogFileSegmentActive()

void SetInstallXLogFileSegmentActive ( void  )

Definition at line 9414 of file xlog.c.

9415 {
9416  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9418  LWLockRelease(ControlFileLock);
9419 }

References XLogCtlData::InstallXLogFileSegmentActive, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), and XLogCtl.

Referenced by BootStrapXLOG(), StartupXLOG(), and WaitForWALToBecomeAvailable().

◆ SetWalWriterSleeping()

void SetWalWriterSleeping ( bool  sleeping)

Definition at line 9437 of file xlog.c.

9438 {
9440  XLogCtl->WalWriterSleeping = sleeping;
9442 }
bool WalWriterSleeping
Definition: xlog.c:526

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

Referenced by WalWriterMain().

◆ ShutdownXLOG()

void ShutdownXLOG ( int  code,
Datum  arg 
)

Definition at line 6539 of file xlog.c.

6540 {
6541  /*
6542  * We should have an aux process resource owner to use, and we should not
6543  * be in a transaction that's installed some other resowner.
6544  */
6546  Assert(CurrentResourceOwner == NULL ||
6549 
6550  /* Don't be chatty in standalone mode */
6552  (errmsg("shutting down")));
6553 
6554  /*
6555  * Signal walsenders to move to stopping state.
6556  */
6558 
6559  /*
6560  * Wait for WAL senders to be in stopping state. This prevents commands
6561  * from writing new WAL.
6562  */
6564 
6565  if (RecoveryInProgress())
6567  else
6568  {
6569  /*
6570  * If archiving is enabled, rotate the last XLOG file so that all the
6571  * remaining records are archived (postmaster wakes up the archiver
6572  * process one more time at the end of shutdown). The checkpoint
6573  * record will go to the next XLOG file and won't be archived (yet).
6574  */
6575  if (XLogArchivingActive())
6576  RequestXLogSwitch(false);
6577 
6579  }
6580 }
bool IsPostmasterEnvironment
Definition: globals.c:117
ResourceOwner CurrentResourceOwner
Definition: resowner.c:165
ResourceOwner AuxProcessResourceOwner
Definition: resowner.c:168
void WalSndInitStopping(void)
Definition: walsender.c:3748
void WalSndWaitStopping(void)
Definition: walsender.c:3774
bool CreateRestartPoint(int flags)
Definition: xlog.c:7521
void CreateCheckPoint(int flags)
Definition: xlog.c:6821

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

Referenced by HandleCheckpointerInterrupts(), and InitPostgres().

◆ StartupXLOG()

void StartupXLOG ( void  )

Definition at line 5387 of file xlog.c.

5388 {
5390  CheckPoint checkPoint;
5391  bool wasShutdown;
5392  bool didCrash;
5393  bool haveTblspcMap;
5394  bool haveBackupLabel;
5395  XLogRecPtr EndOfLog;
5396  TimeLineID EndOfLogTLI;
5397  TimeLineID newTLI;
5398  bool performedWalRecovery;
5399  EndOfWalRecoveryInfo *endOfRecoveryInfo;
5402  TransactionId oldestActiveXID;
5403  bool promoted = false;
5404 
5405  /*
5406  * We should have an aux process resource owner to use, and we should not
5407  * be in a transaction that's installed some other resowner.
5408  */
5410  Assert(CurrentResourceOwner == NULL ||
5413 
5414  /*
5415  * Check that contents look valid.
5416  */
5418  ereport(FATAL,
5420  errmsg("control file contains invalid checkpoint location")));
5421 
5422  switch (ControlFile->state)
5423  {
5424  case DB_SHUTDOWNED:
5425 
5426  /*
5427  * This is the expected case, so don't be chatty in standalone
5428  * mode
5429  */
5431  (errmsg("database system was shut down at %s",
5432  str_time(ControlFile->time))));
5433  break;
5434 
5436  ereport(LOG,
5437  (errmsg("database system was shut down in recovery at %s",
5438  str_time(ControlFile->time))));
5439  break;
5440 
5441  case DB_SHUTDOWNING:
5442  ereport(LOG,
5443  (errmsg("database system shutdown was interrupted; last known up at %s",
5444  str_time(ControlFile->time))));
5445  break;
5446 
5447  case DB_IN_CRASH_RECOVERY:
5448  ereport(LOG,
5449  (errmsg("database system was interrupted while in recovery at %s",
5451  errhint("This probably means that some data is corrupted and"
5452  " you will have to use the last backup for recovery.")));
5453  break;
5454 
5456  ereport(LOG,
5457  (errmsg("database system was interrupted while in recovery at log time %s",
5459  errhint("If this has occurred more than once some data might be corrupted"
5460  " and you might need to choose an earlier recovery target.")));
5461  break;
5462 
5463  case DB_IN_PRODUCTION:
5464  ereport(LOG,
5465  (errmsg("database system was interrupted; last known up at %s",
5466  str_time(ControlFile->time))));
5467  break;
5468 
5469  default:
5470  ereport(FATAL,
5472  errmsg("control file contains invalid database cluster state")));
5473  }
5474 
5475  /* This is just to allow attaching to startup process with a debugger */
5476 #ifdef XLOG_REPLAY_DELAY
5478  pg_usleep(60000000L);
5479 #endif
5480 
5481  /*
5482  * Verify that pg_wal, pg_wal/archive_status, and pg_wal/summaries exist.
5483  * In cases where someone has performed a copy for PITR, these directories
5484  * may have been excluded and need to be re-created.
5485  */
5487 
5488  /* Set up timeout handler needed to report startup progress. */
5492 
5493  /*----------
5494  * If we previously crashed, perform a couple of actions:
5495  *
5496  * - The pg_wal directory may still include some temporary WAL segments
5497  * used when creating a new segment, so perform some clean up to not
5498  * bloat this path. This is done first as there is no point to sync
5499  * this temporary data.
5500  *
5501  * - There might be data which we had written, intending to fsync it, but
5502  * which we had not actually fsync'd yet. Therefore, a power failure in
5503  * the near future might cause earlier unflushed writes to be lost, even
5504  * though more recent data written to disk from here on would be
5505  * persisted. To avoid that, fsync the entire data directory.
5506  */
5507  if (ControlFile->state != DB_SHUTDOWNED &&
5509  {
5512  didCrash = true;
5513  }
5514  else
5515  didCrash = false;
5516 
5517  /*
5518  * Prepare for WAL recovery if needed.
5519  *
5520  * InitWalRecovery analyzes the control file and the backup label file, if
5521  * any. It updates the in-memory ControlFile buffer according to the
5522  * starting checkpoint, and sets InRecovery and ArchiveRecoveryRequested.
5523  * It also applies the tablespace map file, if any.
5524  */
5525  InitWalRecovery(ControlFile, &wasShutdown,
5526  &haveBackupLabel, &haveTblspcMap);
5527  checkPoint = ControlFile->checkPointCopy;
5528 
5529  /* initialize shared memory variables from the checkpoint record */
5530  TransamVariables->nextXid = checkPoint.nextXid;
5531  TransamVariables->nextOid = checkPoint.nextOid;
5533  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5534  AdvanceOldestClogXid(checkPoint.oldestXid);
5535  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5536  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5538  checkPoint.newestCommitTsXid);
5539  XLogCtl->ckptFullXid = checkPoint.nextXid;
5540 
5541  /*
5542  * Clear out any old relcache cache files. This is *necessary* if we do
5543  * any WAL replay, since that would probably result in the cache files
5544  * being out of sync with database reality. In theory we could leave them
5545  * in place if the database had been cleanly shut down, but it seems
5546  * safest to just remove them always and let them be rebuilt during the
5547  * first backend startup. These files needs to be removed from all
5548  * directories including pg_tblspc, however the symlinks are created only
5549  * after reading tablespace_map file in case of archive recovery from
5550  * backup, so needs to clear old relcache files here after creating
5551  * symlinks.
5552  */
5554 
5555  /*
5556  * Initialize replication slots, before there's a chance to remove
5557  * required resources.
5558  */
5560 
5561  /*
5562  * Startup logical state, needs to be setup now so we have proper data
5563  * during crash recovery.
5564  */
5566 
5567  /*
5568  * Startup CLOG. This must be done after TransamVariables->nextXid has
5569  * been initialized and before we accept connections or begin WAL replay.
5570  */
5571  StartupCLOG();
5572 
5573  /*
5574  * Startup MultiXact. We need to do this early to be able to replay
5575  * truncations.
5576  */
5577  StartupMultiXact();
5578 
5579  /*
5580  * Ditto for commit timestamps. Activate the facility if the setting is
5581  * enabled in the control file, as there should be no tracking of commit
5582  * timestamps done when the setting was disabled. This facility can be
5583  * started or stopped when replaying a XLOG_PARAMETER_CHANGE record.
5584  */
5586  StartupCommitTs();
5587 
5588  /*
5589  * Recover knowledge about replay progress of known replication partners.
5590  */
5592 
5593  /*
5594  * Initialize unlogged LSN. On a clean shutdown, it's restored from the
5595  * control file. On recovery, all unlogged relations are blown away, so
5596  * the unlogged LSN counter can be reset too.
5597  */
5601  else
5604 
5605  /*
5606  * Copy any missing timeline history files between 'now' and the recovery
5607  * target timeline from archive to pg_wal. While we don't need those files
5608  * ourselves - the history file of the recovery target timeline covers all
5609  * the previous timelines in the history too - a cascading standby server
5610  * might be interested in them. Or, if you archive the WAL from this
5611  * server to a different archive than the primary, it'd be good for all
5612  * the history files to get archived there after failover, so that you can
5613  * use one of the old timelines as a PITR target. Timeline history files
5614  * are small, so it's better to copy them unnecessarily than not copy them
5615  * and regret later.
5616  */
5618 
5619  /*
5620  * Before running in recovery, scan pg_twophase and fill in its status to
5621  * be able to work on entries generated by redo. Doing a scan before
5622  * taking any recovery action has the merit to discard any 2PC files that
5623  * are newer than the first record to replay, saving from any conflicts at
5624  * replay. This avoids as well any subsequent scans when doing recovery
5625  * of the on-disk two-phase data.
5626  */
5628 
5629  /*
5630  * When starting with crash recovery, reset pgstat data - it might not be
5631  * valid. Otherwise restore pgstat data. It's safe to do this here,
5632  * because postmaster will not yet have started any other processes.
5633  *
5634  * NB: Restoring replication slot stats relies on slot state to have
5635  * already been restored from disk.
5636  *
5637  * TODO: With a bit of extra work we could just start with a pgstat file
5638  * associated with the checkpoint redo location we're starting from.
5639  */
5640  if (didCrash)
5642  else
5644 
5645  lastFullPageWrites = checkPoint.fullPageWrites;
5646 
5649 
5650  /* REDO */
5651  if (InRecovery)
5652  {
5653  /* Initialize state for RecoveryInProgress() */
5655  if (InArchiveRecovery)
5657  else
5660 
5661  /*
5662  * Update pg_control to show that we are recovering and to show the
5663  * selected checkpoint as the place we are starting from. We also mark
5664  * pg_control with any minimum recovery stop point obtained from a
5665  * backup history file.
5666  *
5667  * No need to hold ControlFileLock yet, we aren't up far enough.
5668  */
5670 
5671  /*
5672  * If there was a backup label file, it's done its job and the info
5673  * has now been propagated into pg_control. We must get rid of the
5674  * label file so that if we crash during recovery, we'll pick up at
5675  * the latest recovery restartpoint instead of going all the way back
5676  * to the backup start point. It seems prudent though to just rename
5677  * the file out of the way rather than delete it completely.
5678  */
5679  if (haveBackupLabel)
5680  {
5681  unlink(BACKUP_LABEL_OLD);
5683  }
5684 
5685  /*
5686  * If there was a tablespace_map file, it's done its job and the
5687  * symlinks have been created. We must get rid of the map file so
5688  * that if we crash during recovery, we don't create symlinks again.
5689  * It seems prudent though to just rename the file out of the way
5690  * rather than delete it completely.
5691  */
5692  if (haveTblspcMap)
5693  {
5694  unlink(TABLESPACE_MAP_OLD);
5696  }
5697 
5698  /*
5699  * Initialize our local copy of minRecoveryPoint. When doing crash
5700  * recovery we want to replay up to the end of WAL. Particularly, in
5701  * the case of a promoted standby minRecoveryPoint value in the
5702  * control file is only updated after the first checkpoint. However,
5703  * if the instance crashes before the first post-recovery checkpoint
5704  * is completed then recovery will use a stale location causing the
5705  * startup process to think that there are still invalid page
5706  * references when checking for data consistency.
5707  */
5708  if (InArchiveRecovery)
5709  {
5712  }
5713  else
5714  {
5717  }
5718 
5719  /* Check that the GUCs used to generate the WAL allow recovery */
5721 
5722  /*
5723  * We're in recovery, so unlogged relations may be trashed and must be
5724  * reset. This should be done BEFORE allowing Hot Standby
5725  * connections, so that read-only backends don't try to read whatever
5726  * garbage is left over from before.
5727  */
5729 
5730  /*
5731  * Likewise, delete any saved transaction snapshot files that got left
5732  * behind by crashed backends.
5733  */
5735 
5736  /*
5737  * Initialize for Hot Standby, if enabled. We won't let backends in
5738  * yet, not until we've reached the min recovery point specified in
5739  * control file and we've established a recovery snapshot from a
5740  * running-xacts WAL record.
5741  */
5743  {
5744  TransactionId *xids;
5745  int nxids;
5746 
5747  ereport(DEBUG1,
5748  (errmsg_internal("initializing for hot standby")));
5749 
5751 
5752  if (wasShutdown)
5753  oldestActiveXID = PrescanPreparedTransactions(&xids, &nxids);
5754  else
5755  oldestActiveXID = checkPoint.oldestActiveXid;
5756  Assert(TransactionIdIsValid(oldestActiveXID));
5757 
5758  /* Tell procarray about the range of xids it has to deal with */
5760 
5761  /*
5762  * Startup subtrans only. CLOG, MultiXact and commit timestamp
5763  * have already been started up and other SLRUs are not maintained
5764  * during recovery and need not be started yet.
5765  */
5766  StartupSUBTRANS(oldestActiveXID);
5767 
5768  /*
5769  * If we're beginning at a shutdown checkpoint, we know that
5770  * nothing was running on the primary at this point. So fake-up an
5771  * empty running-xacts record and use that here and now. Recover
5772  * additional standby state for prepared transactions.
5773  */
5774  if (wasShutdown)
5775  {
5776  RunningTransactionsData running;
5777  TransactionId latestCompletedXid;
5778 
5779  /* Update pg_subtrans entries for any prepared transactions */
5781 
5782  /*
5783  * Construct a RunningTransactions snapshot representing a
5784  * shut down server, with only prepared transactions still
5785  * alive. We're never overflowed at this point because all
5786  * subxids are listed with their parent prepared transactions.
5787  */
5788  running.xcnt = nxids;
5789  running.subxcnt = 0;
5791  running.nextXid = XidFromFullTransactionId(checkPoint.nextXid);
5792  running.oldestRunningXid = oldestActiveXID;
5793  latestCompletedXid = XidFromFullTransactionId(checkPoint.nextXid);
5794  TransactionIdRetreat(latestCompletedXid);
5795  Assert(TransactionIdIsNormal(latestCompletedXid));
5796  running.latestCompletedXid = latestCompletedXid;
5797  running.xids = xids;
5798 
5799  ProcArrayApplyRecoveryInfo(&running);
5800  }
5801  }
5802 
5803  /*
5804  * We're all set for replaying the WAL now. Do it.
5805  */
5807  performedWalRecovery = true;
5808  }
5809  else
5810  performedWalRecovery = false;
5811 
5812  /*
5813  * Finish WAL recovery.
5814  */
5815  endOfRecoveryInfo = FinishWalRecovery();
5816  EndOfLog = endOfRecoveryInfo->endOfLog;
5817  EndOfLogTLI = endOfRecoveryInfo->endOfLogTLI;
5818  abortedRecPtr = endOfRecoveryInfo->abortedRecPtr;
5819  missingContrecPtr = endOfRecoveryInfo->missingContrecPtr;
5820 
5821  /*
5822  * Reset ps status display, so as no information related to recovery shows
5823  * up.
5824  */
5825  set_ps_display("");
5826 
5827  /*
5828  * When recovering from a backup (we are in recovery, and archive recovery
5829  * was requested), complain if we did not roll forward far enough to reach
5830  * the point where the database is consistent. For regular online
5831  * backup-from-primary, that means reaching the end-of-backup WAL record
5832  * (at which point we reset backupStartPoint to be Invalid), for
5833  * backup-from-replica (which can't inject records into the WAL stream),
5834  * that point is when we reach the minRecoveryPoint in pg_control (which
5835  * we purposefully copy last when backing up from a replica). For
5836  * pg_rewind (which creates a backup_label with a method of "pg_rewind")
5837  * or snapshot-style backups (which don't), backupEndRequired will be set
5838  * to false.
5839  *
5840  * Note: it is indeed okay to look at the local variable
5841  * LocalMinRecoveryPoint here, even though ControlFile->minRecoveryPoint
5842  * might be further ahead --- ControlFile->minRecoveryPoint cannot have
5843  * been advanced beyond the WAL we processed.
5844  */
5845  if (InRecovery &&
5846  (EndOfLog < LocalMinRecoveryPoint ||
5848  {
5849  /*
5850  * Ran off end of WAL before reaching end-of-backup WAL record, or
5851  * minRecoveryPoint. That's a bad sign, indicating that you tried to
5852  * recover from an online backup but never called pg_backup_stop(), or
5853  * you didn't archive all the WAL needed.
5854  */
5856  {
5858  ereport(FATAL,
5859  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
5860  errmsg("WAL ends before end of online backup"),
5861  errhint("All WAL generated while online backup was taken must be available at recovery.")));
5862  else
5863  ereport(FATAL,
5864  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
5865  errmsg("WAL ends before consistent recovery point")));
5866  }
5867  }
5868 
5869  /*
5870  * Reset unlogged relations to the contents of their INIT fork. This is
5871  * done AFTER recovery is complete so as to include any unlogged relations
5872  * created during recovery, but BEFORE recovery is marked as having
5873  * completed successfully. Otherwise we'd not retry if any of the post
5874  * end-of-recovery steps fail.
5875  */
5876  if (InRecovery)
5878 
5879  /*
5880  * Pre-scan prepared transactions to find out the range of XIDs present.
5881  * This information is not quite needed yet, but it is positioned here so
5882  * as potential problems are detected before any on-disk change is done.
5883  */
5884  oldestActiveXID = PrescanPreparedTransactions(NULL, NULL);
5885 
5886  /*
5887  * Allow ordinary WAL segment creation before possibly switching to a new
5888  * timeline, which creates a new segment, and after the last ReadRecord().
5889  */
5891 
5892  /*
5893  * Consider whether we need to assign a new timeline ID.
5894  *
5895  * If we did archive recovery, we always assign a new ID. This handles a
5896  * couple of issues. If we stopped short of the end of WAL during
5897  * recovery, then we are clearly generating a new timeline and must assign
5898  * it a unique new ID. Even if we ran to the end, modifying the current
5899  * last segment is problematic because it may result in trying to
5900  * overwrite an already-archived copy of that segment, and we encourage
5901  * DBAs to make their archive_commands reject that. We can dodge the
5902  * problem by making the new active segment have a new timeline ID.
5903  *
5904  * In a normal crash recovery, we can just extend the timeline we were in.
5905  */
5906  newTLI = endOfRecoveryInfo->lastRecTLI;
5908  {
5909  newTLI = findNewestTimeLine(recoveryTargetTLI) + 1;
5910  ereport(LOG,
5911  (errmsg("selected new timeline ID: %u", newTLI)));
5912 
5913  /*
5914  * Make a writable copy of the last WAL segment. (Note that we also
5915  * have a copy of the last block of the old WAL in
5916  * endOfRecovery->lastPage; we will use that below.)
5917  */
5918  XLogInitNewTimeline(EndOfLogTLI, EndOfLog, newTLI);
5919 
5920  /*
5921  * Remove the signal files out of the way, so that we don't
5922  * accidentally re-enter archive recovery mode in a subsequent crash.
5923  */
5924  if (endOfRecoveryInfo->standby_signal_file_found)
5926 
5927  if (endOfRecoveryInfo->recovery_signal_file_found)
5929 
5930  /*
5931  * Write the timeline history file, and have it archived. After this
5932  * point (or rather, as soon as the file is archived), the timeline
5933  * will appear as "taken" in the WAL archive and to any standby
5934  * servers. If we crash before actually switching to the new
5935  * timeline, standby servers will nevertheless think that we switched
5936  * to the new timeline, and will try to connect to the new timeline.
5937  * To minimize the window for that, try to do as little as possible
5938  * between here and writing the end-of-recovery record.
5939  */
5941  EndOfLog, endOfRecoveryInfo->recoveryStopReason);
5942 
5943  ereport(LOG,
5944  (errmsg("archive recovery complete")));
5945  }
5946 
5947  /* Save the selected TimeLineID in shared memory, too */
5948  XLogCtl->InsertTimeLineID = newTLI;
5949  XLogCtl->PrevTimeLineID = endOfRecoveryInfo->lastRecTLI;
5950 
5951  /*
5952  * Actually, if WAL ended in an incomplete record, skip the parts that
5953  * made it through and start writing after the portion that persisted.
5954  * (It's critical to first write an OVERWRITE_CONTRECORD message, which
5955  * we'll do as soon as we're open for writing new WAL.)
5956  */
5958  {
5959  /*
5960  * We should only have a missingContrecPtr if we're not switching to a
5961  * new timeline. When a timeline switch occurs, WAL is copied from the
5962  * old timeline to the new only up to the end of the last complete
5963  * record, so there can't be an incomplete WAL record that we need to
5964  * disregard.
5965  */
5966  Assert(newTLI == endOfRecoveryInfo->lastRecTLI);
5968  EndOfLog = missingContrecPtr;
5969  }
5970 
5971  /*
5972  * Prepare to write WAL starting at EndOfLog location, and init xlog
5973  * buffer cache using the block containing the last record from the
5974  * previous incarnation.
5975  */
5976  Insert = &XLogCtl->Insert;
5977  Insert->PrevBytePos = XLogRecPtrToBytePos(endOfRecoveryInfo->lastRec);
5978  Insert->CurrBytePos = XLogRecPtrToBytePos(EndOfLog);
5979 
5980  /*
5981  * Tricky point here: lastPage contains the *last* block that the LastRec
5982  * record spans, not the one it starts in. The last block is indeed the
5983  * one we want to use.
5984  */
5985  if (EndOfLog % XLOG_BLCKSZ != 0)
5986  {
5987  char *page;
5988  int len;
5989  int firstIdx;
5990 
5991  firstIdx = XLogRecPtrToBufIdx(EndOfLog);
5992  len = EndOfLog - endOfRecoveryInfo->lastPageBeginPtr;
5993  Assert(len < XLOG_BLCKSZ);
5994 
5995  /* Copy the valid part of the last block, and zero the rest */
5996  page = &XLogCtl->pages[firstIdx * XLOG_BLCKSZ];
5997  memcpy(page, endOfRecoveryInfo->lastPage, len);
5998  memset(page + len, 0, XLOG_BLCKSZ - len);
5999 
6000  pg_atomic_write_u64(&XLogCtl->xlblocks[firstIdx], endOfRecoveryInfo->lastPageBeginPtr + XLOG_BLCKSZ);
6001  XLogCtl->InitializedUpTo = endOfRecoveryInfo->lastPageBeginPtr + XLOG_BLCKSZ;
6002  }
6003  else
6004  {
6005  /*
6006  * There is no partial block to copy. Just set InitializedUpTo, and
6007  * let the first attempt to insert a log record to initialize the next
6008  * buffer.
6009  */
6010  XLogCtl->InitializedUpTo = EndOfLog;
6011  }
6012 
6013  /*
6014  * Update local and shared status. This is OK to do without any locks
6015  * because no other process can be reading or writing WAL yet.
6016  */
6017  LogwrtResult.Write = LogwrtResult.Flush = EndOfLog;
6021  XLogCtl->LogwrtRqst.Write = EndOfLog;
6022  XLogCtl->LogwrtRqst.Flush = EndOfLog;
6023 
6024  /*
6025  * Preallocate additional log files, if wanted.
6026  */
6027  PreallocXlogFiles(EndOfLog, newTLI);
6028 
6029  /*
6030  * Okay, we're officially UP.
6031  */
6032  InRecovery = false;
6033 
6034  /* start the archive_timeout timer and LSN running */
6035  XLogCtl->lastSegSwitchTime = (pg_time_t) time(NULL);
6036  XLogCtl->lastSegSwitchLSN = EndOfLog;
6037 
6038  /* also initialize latestCompletedXid, to nextXid - 1 */
6039  LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
6042  LWLockRelease(ProcArrayLock);
6043 
6044  /*
6045  * Start up subtrans, if not already done for hot standby. (commit
6046  * timestamps are started below, if necessary.)
6047  */
6049  StartupSUBTRANS(oldestActiveXID);
6050 
6051  /*
6052  * Perform end of recovery actions for any SLRUs that need it.
6053  */
6054  TrimCLOG();
6055  TrimMultiXact();
6056 
6057  /*
6058  * Reload shared-memory state for prepared transactions. This needs to
6059  * happen before renaming the last partial segment of the old timeline as
6060  * it may be possible that we have to recovery some transactions from it.
6061  */
6063 
6064  /* Shut down xlogreader */
6066 
6067  /* Enable WAL writes for this backend only. */
6069 
6070  /* If necessary, write overwrite-contrecord before doing anything else */
6072  {
6075  }
6076 
6077  /*
6078  * Update full_page_writes in shared memory and write an XLOG_FPW_CHANGE
6079  * record before resource manager writes cleanup WAL records or checkpoint
6080  * record is written.
6081  */
6082  Insert->fullPageWrites = lastFullPageWrites;
6084 
6085  /*
6086  * Emit checkpoint or end-of-recovery record in XLOG, if required.
6087  */
6088  if (performedWalRecovery)
6089  promoted = PerformRecoveryXLogAction();
6090 
6091  /*
6092  * If any of the critical GUCs have changed, log them before we allow
6093  * backends to write WAL.
6094  */
6096 
6097  /* If this is archive recovery, perform post-recovery cleanup actions. */
6099  CleanupAfterArchiveRecovery(EndOfLogTLI, EndOfLog, newTLI);
6100 
6101  /*
6102  * Local WAL inserts enabled, so it's time to finish initialization of
6103  * commit timestamp.
6104  */
6106 
6107  /*
6108  * All done with end-of-recovery actions.
6109  *
6110  * Now allow backends to write WAL and update the control file status in
6111  * consequence. SharedRecoveryState, that controls if backends can write
6112  * WAL, is updated while holding ControlFileLock to prevent other backends
6113  * to look at an inconsistent state of the control file in shared memory.
6114  * There is still a small window during which backends can write WAL and
6115  * the control file is still referring to a system not in DB_IN_PRODUCTION
6116  * state while looking at the on-disk control file.
6117  *
6118  * Also, we use info_lck to update SharedRecoveryState to ensure that
6119  * there are no race conditions concerning visibility of other recent
6120  * updates to shared memory.
6121  */
6122  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6124 
6128 
6130  LWLockRelease(ControlFileLock);
6131 
6132  /*
6133  * Shutdown the recovery environment. This must occur after
6134  * RecoverPreparedTransactions() (see notes in lock_twophase_recover())
6135  * and after switching SharedRecoveryState to RECOVERY_STATE_DONE so as
6136  * any session building a snapshot will not rely on KnownAssignedXids as
6137  * RecoveryInProgress() would return false at this stage. This is
6138  * particularly critical for prepared 2PC transactions, that would still
6139  * need to be included in snapshots once recovery has ended.
6140  */
6143 
6144  /*
6145  * If there were cascading standby servers connected to us, nudge any wal
6146  * sender processes to notice that we've been promoted.
6147  */
6148  WalSndWakeup(true, true);
6149 
6150  /*
6151  * If this was a promotion, request an (online) checkpoint now. This isn't
6152  * required for consistency, but the last restartpoint might be far back,
6153  * and in case of a crash, recovering from it might take a longer than is
6154  * appropriate now that we're not in standby mode anymore.
6155  */
6156  if (promoted)
6158 }
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:478
static void pg_atomic_write_membarrier_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:487
TimeLineID findNewestTimeLine(TimeLineID startTLI)
Definition: timeline.c:264
void restoreTimeLineHistoryFiles(TimeLineID begin, TimeLineID end)
Definition: timeline.c:50
void writeTimeLineHistory(TimeLineID newTLI, TimeLineID parentTLI, XLogRecPtr switchpoint, char *reason)
Definition: timeline.c:304
void startup_progress_timeout_handler(void)
Definition: startup.c:303
uint32 TransactionId
Definition: c.h:652
void StartupCLOG(void)
Definition: clog.c:877
void TrimCLOG(void)
Definition: clog.c:892
void StartupCommitTs(void)
Definition: commit_ts.c:632
void CompleteCommitTsInitialization(void)
Definition: commit_ts.c:642
#define FATAL
Definition: elog.h:41
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:782
int durable_unlink(const char *fname, int elevel)
Definition: fd.c:872
void SyncDataDirectory(void)
Definition: fd.c:3544
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:454
void TrimMultiXact(void)
Definition: multixact.c:2170
void StartupMultiXact(void)
Definition: multixact.c:2145
void StartupReplicationOrigin(void)
Definition: origin.c:699
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:41
@ DB_IN_PRODUCTION
Definition: pg_control.h:97
@ DB_IN_CRASH_RECOVERY
Definition: pg_control.h:95
const void size_t len
void pgstat_restore_stats(void)
Definition: pgstat.c:450
void pgstat_discard_stats(void)
Definition: pgstat.c:462
void ProcArrayApplyRecoveryInfo(RunningTransactions running)
Definition: procarray.c:1054
void ProcArrayInitRecovery(TransactionId initializedUptoXID)
Definition: procarray.c:1023
static void set_ps_display(const char *activity)
Definition: ps_status.h:40
void ResetUnloggedRelations(int op)
Definition: reinit.c:47
#define UNLOGGED_RELATION_INIT
Definition: reinit.h:28
#define UNLOGGED_RELATION_CLEANUP
Definition: reinit.h:27
void RelationCacheInitFileRemove(void)
Definition: relcache.c:6801
void StartupReorderBuffer(void)
void StartupReplicationSlots(void)
Definition: slot.c:1917
void DeleteAllExportedSnapshotFiles(void)
Definition: snapmgr.c:1567
void InitRecoveryTransactionEnvironment(void)
Definition: standby.c:94
void ShutdownRecoveryTransactionEnvironment(void)
Definition: standby.c:160
@ SUBXIDS_IN_SUBTRANS
Definition: standby.h:82
bool track_commit_timestamp
Definition: pg_control.h:185
XLogRecPtr lastPageBeginPtr
Definition: xlogrecovery.h:111
XLogRecPtr abortedRecPtr
Definition: xlogrecovery.h:120
XLogRecPtr missingContrecPtr
Definition: xlogrecovery.h:121
TimeLineID endOfLogTLI
Definition: xlogrecovery.h:109
TransactionId oldestRunningXid
Definition: standby.h:92
TransactionId nextXid
Definition: standby.h:91
TransactionId latestCompletedXid
Definition: standby.h:95
subxids_array_status subxid_status
Definition: standby.h:90
TransactionId * xids
Definition: standby.h:97
FullTransactionId latestCompletedXid
Definition: transam.h:238
XLogRecPtr InitializedUpTo
Definition: xlog.c:483
char * pages
Definition: xlog.c:490
pg_time_t lastSegSwitchTime
Definition: xlog.c:465
XLogRecPtr lastSegSwitchLSN
Definition: xlog.c:466
pg_atomic_uint64 * xlblocks
Definition: xlog.c:491
pg_atomic_uint64 logWriteResult
Definition: xlog.c:470
pg_atomic_uint64 logFlushResult
Definition: xlog.c:471
pg_atomic_uint64 logInsertResult
Definition: xlog.c:469
XLogRecPtr Flush
Definition: xlog.c:320
void StartupSUBTRANS(TransactionId oldestActiveXID)
Definition: subtrans.c:309
TimeoutId RegisterTimeout(TimeoutId id, timeout_handler_proc handler)
Definition: timeout.c:505
@ STARTUP_PROGRESS_TIMEOUT
Definition: timeout.h:38
#define TransactionIdRetreat(dest)
Definition: transam.h:141
static void FullTransactionIdRetreat(FullTransactionId *dest)
Definition: transam.h:103
#define XidFromFullTransactionId(x)
Definition: transam.h:48
#define TransactionIdIsValid(xid)
Definition: transam.h:41
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
void RecoverPreparedTransactions(void)
Definition: twophase.c:2083
void restoreTwoPhaseData(void)
Definition: twophase.c:1898
TransactionId PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p)
Definition: twophase.c:1962
void StandbyRecoverPreparedTransactions(void)
Definition: twophase.c:2042
void WalSndWakeup(bool physical, bool logical)
Definition: walsender.c:3669
void UpdateFullPageWrites(void)
Definition: xlog.c:8096
static char * str_time(pg_time_t tnow)
Definition: xlog.c:5164
static void ValidateXLOGDirectoryStructure(void)
Definition: xlog.c:4086
static XLogRecPtr CreateOverwriteContrecordRecord(XLogRecPtr aborted_lsn, XLogRecPtr pagePtr, TimeLineID newTLI)
Definition: xlog.c:7370
static void XLogReportParameters(void)
Definition: xlog.c:8033
static bool PerformRecoveryXLogAction(void)
Definition: xlog.c:6240
static void CleanupAfterArchiveRecovery(TimeLineID EndOfLogTLI, XLogRecPtr EndOfLog, TimeLineID newTLI)
Definition: xlog.c:5254
static bool lastFullPageWrites
Definition: xlog.c:215
static uint64 XLogRecPtrToBytePos(XLogRecPtr ptr)
Definition: xlog.c:1934
static void XLogInitNewTimeline(TimeLineID endTLI, XLogRecPtr endOfLog, TimeLineID newTLI)
Definition: xlog.c:5179
static void CheckRequiredParameterValues(void)
Definition: xlog.c:5343
#define XLogRecPtrToBufIdx(recptr)
Definition: xlog.c:584
static void RemoveTempXlogFiles(void)
Definition: xlog.c:3819
#define TABLESPACE_MAP_OLD
Definition: xlog.h:304
#define TABLESPACE_MAP
Definition: xlog.h:303
#define STANDBY_SIGNAL_FILE
Definition: xlog.h:299
#define BACKUP_LABEL_OLD
Definition: xlog.h:301
#define BACKUP_LABEL_FILE
Definition: xlog.h:300
#define RECOVERY_SIGNAL_FILE
Definition: xlog.h:298
#define XRecOffIsValid(xlrp)
#define FirstNormalUnloggedLSN
Definition: xlogdefs.h:36
void ShutdownWalRecovery(void)
bool ArchiveRecoveryRequested
Definition: xlogrecovery.c:137
bool InArchiveRecovery
Definition: xlogrecovery.c:138
void PerformWalRecovery(void)
EndOfWalRecoveryInfo * FinishWalRecovery(void)
static XLogRecPtr missingContrecPtr
Definition: xlogrecovery.c:373
static XLogRecPtr abortedRecPtr
Definition: xlogrecovery.c:372
void InitWalRecovery(ControlFileData *ControlFile, bool *wasShutdown_ptr, bool *haveBackupLabel_ptr, bool *haveTblspcMap_ptr)
Definition: xlogrecovery.c:512
TimeLineID recoveryTargetTLI
Definition: xlogrecovery.c:122
HotStandbyState standbyState
Definition: xlogutils.c:53
bool InRecovery
Definition: xlogutils.c:50
@ STANDBY_DISABLED
Definition: xlogutils.h:52

References abortedRecPtr, EndOfWalRecoveryInfo::abortedRecPtr, AdvanceOldestClogXid(), ArchiveRecoveryRequested, Assert, AuxProcessResourceOwner, BACKUP_LABEL_FILE, BACKUP_LABEL_OLD, ControlFileData::backupEndRequired, ControlFileData::backupStartPoint, ControlFileData::checkPoint, CHECKPOINT_FORCE, ControlFileData::checkPointCopy, CheckRequiredParameterValues(), XLogCtlData::ckptFullXid, CleanupAfterArchiveRecovery(), CompleteCommitTsInitialization(), ControlFile, CreateOverwriteContrecordRecord(), CurrentResourceOwner, DB_IN_ARCHIVE_RECOVERY, DB_IN_CRASH_RECOVERY, DB_IN_PRODUCTION, DB_SHUTDOWNED, DB_SHUTDOWNED_IN_RECOVERY, DB_SHUTDOWNING, DEBUG1, DeleteAllExportedSnapshotFiles(), doPageWrites, durable_rename(), durable_unlink(), EnableHotStandby, EndOfWalRecoveryInfo::endOfLog, EndOfWalRecoveryInfo::endOfLogTLI, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errhint(), errmsg(), errmsg_internal(), FATAL, findNewestTimeLine(), FinishWalRecovery(), FirstNormalUnloggedLSN, XLogwrtRqst::Flush, XLogwrtResult::Flush, CheckPoint::fullPageWrites, FullTransactionIdRetreat(), InArchiveRecovery, XLogCtlData::info_lck, XLogCtlData::InitializedUpTo, InitRecoveryTransactionEnvironment(), InitWalRecovery(), InRecovery, XLogCtlData::Insert, Insert(), XLogCtlData::InsertTimeLineID, InvalidXLogRecPtr, IsBootstrapProcessingMode, IsPostmasterEnvironment, lastFullPageWrites, EndOfWalRecoveryInfo::lastPage, EndOfWalRecoveryInfo::lastPageBeginPtr, EndOfWalRecoveryInfo::lastRec, EndOfWalRecoveryInfo::lastRecTLI, XLogCtlData::lastSegSwitchLSN, XLogCtlData::lastSegSwitchTime, TransamVariablesData::latestCompletedXid, RunningTransactionsData::latestCompletedXid, len, LocalMinRecoveryPoint, LocalMinRecoveryPointTLI, LocalSetXLogInsertAllowed(), LOG, XLogCtlData::logFlushResult, XLogCtlData::logInsertResult, XLogCtlData::logWriteResult, LogwrtResult, XLogCtlData::LogwrtRqst, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, missingContrecPtr, EndOfWalRecoveryInfo::missingContrecPtr, MultiXactSetNextMXact(), CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, TransamVariablesData::nextOid, CheckPoint::nextOid, TransamVariablesData::nextXid, CheckPoint::nextXid, RunningTransactionsData::nextXid, NOTICE, TransamVariablesData::oidCount, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, RunningTransactionsData::oldestRunningXid, CheckPoint::oldestXid, CheckPoint::oldestXidDB, XLogCtlData::pages, PerformRecoveryXLogAction(), PerformWalRecovery(), pg_atomic_write_membarrier_u64(), pg_atomic_write_u64(), pg_usleep(), pgstat_discard_stats(), pgstat_restore_stats(), PreallocXlogFiles(), PrescanPreparedTransactions(), XLogCtlData::PrevTimeLineID, ProcArrayApplyRecoveryInfo(), ProcArrayInitRecovery(), RecoverPreparedTransactions(), RECOVERY_SIGNAL_FILE, EndOfWalRecoveryInfo::recovery_signal_file_found, RECOVERY_STATE_ARCHIVE, RECOVERY_STATE_CRASH, RECOVERY_STATE_DONE, EndOfWalRecoveryInfo::recoveryStopReason, recoveryTargetTLI, CheckPoint::redo, RedoRecPtr, XLogCtlInsert::RedoRecPtr, XLogCtlData::RedoRecPtr, RegisterTimeout(), RelationCacheInitFileRemove(), RemoveTempXlogFiles(), RequestCheckpoint(), ResetUnloggedRelations(), restoreTimeLineHistoryFiles(), restoreTwoPhaseData(), set_ps_display(), SetCommitTsLimit(), SetInstallXLogFileSegmentActive(), SetMultiXactIdLimit(), SetTransactionIdLimit(), XLogCtlData::SharedRecoveryState, ShutdownRecoveryTransactionEnvironment(), ShutdownWalRecovery(), SpinLockAcquire, SpinLockRelease, STANDBY_DISABLED, STANDBY_SIGNAL_FILE, EndOfWalRecoveryInfo::standby_signal_file_found, StandbyRecoverPreparedTransactions(), standbyState, STARTUP_PROGRESS_TIMEOUT, startup_progress_timeout_handler(), StartupCLOG(), StartupCommitTs(), StartupMultiXact(), StartupReorderBuffer(), StartupReplicationOrigin(), StartupReplicationSlots(), StartupSUBTRANS(), ControlFileData::state, str_time(), RunningTransactionsData::subxcnt, RunningTransactionsData::subxid_status, SUBXIDS_IN_SUBTRANS, SyncDataDirectory(), TABLESPACE_MAP, TABLESPACE_MAP_OLD, CheckPoint::ThisTimeLineID, CheckPoint::time, ControlFileData::time, ControlFileData::track_commit_timestamp, TransactionIdIsNormal, TransactionIdIsValid, TransactionIdRetreat, TransamVariables, TrimCLOG(), TrimMultiXact(), UNLOGGED_RELATION_CLEANUP, UNLOGGED_RELATION_INIT, XLogCtlData::unloggedLSN, ControlFileData::unloggedLSN, UpdateControlFile(), UpdateFullPageWrites(), ValidateXLOGDirectoryStructure(), WalSndWakeup(), XLogwrtRqst::Write, XLogwrtResult::Write, writeTimeLineHistory(), RunningTransactionsData::xcnt, XidFromFullTransactionId, RunningTransactionsData::xids, XLogCtlData::xlblocks, XLogCtl, XLogInitNewTimeline(), XLogRecPtrIsInvalid, XLogRecPtrToBufIdx, XLogRecPtrToBytePos(), XLogReportParameters(), and XRecOffIsValid.

Referenced by InitPostgres(), and StartupProcessMain().

◆ SwitchIntoArchiveRecovery()

void SwitchIntoArchiveRecovery ( XLogRecPtr  EndRecPtr,
TimeLineID  replayTLI 
)

Definition at line 6165 of file xlog.c.

6166 {
6167  /* initialize minRecoveryPoint to this record */
6168  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6170  if (ControlFile->minRecoveryPoint < EndRecPtr)
6171  {
6172  ControlFile->minRecoveryPoint = EndRecPtr;
6173  ControlFile->minRecoveryPointTLI = replayTLI;
6174  }
6175  /* update local copy */
6178 
6179  /*
6180  * The startup process can update its local copy of minRecoveryPoint from
6181  * this point.
6182  */
6183  updateMinRecoveryPoint = true;
6184 
6186 
6187  /*
6188  * We update SharedRecoveryState while holding the lock on ControlFileLock
6189  * so both states are consistent in shared memory.
6190  */
6194 
6195  LWLockRelease(ControlFileLock);
6196 }
static bool updateMinRecoveryPoint
Definition: xlog.c:641

References ControlFile, DB_IN_ARCHIVE_RECOVERY, XLogCtlData::info_lck, LocalMinRecoveryPoint, LocalMinRecoveryPointTLI, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, RECOVERY_STATE_ARCHIVE, XLogCtlData::SharedRecoveryState, SpinLockAcquire, SpinLockRelease, ControlFileData::state, UpdateControlFile(), updateMinRecoveryPoint, and XLogCtl.

Referenced by ReadRecord().

◆ UpdateFullPageWrites()

void UpdateFullPageWrites ( void  )

Definition at line 8096 of file xlog.c.

8097 {
8099  bool recoveryInProgress;
8100 
8101  /*
8102  * Do nothing if full_page_writes has not been changed.
8103  *
8104  * It's safe to check the shared full_page_writes without the lock,
8105  * because we assume that there is no concurrently running process which
8106  * can update it.
8107  */
8108  if (fullPageWrites == Insert->fullPageWrites)
8109  return;
8110 
8111  /*
8112  * Perform this outside critical section so that the WAL insert
8113  * initialization done by RecoveryInProgress() doesn't trigger an
8114  * assertion failure.
8115  */
8116  recoveryInProgress = RecoveryInProgress();
8117 
8119 
8120  /*
8121  * It's always safe to take full page images, even when not strictly
8122  * required, but not the other round. So if we're setting full_page_writes
8123  * to true, first set it true and then write the WAL record. If we're
8124  * setting it to false, first write the WAL record and then set the global
8125  * flag.
8126  */
8127  if (fullPageWrites)
8128  {
8130  Insert->fullPageWrites = true;
8132  }
8133 
8134  /*
8135  * Write an XLOG_FPW_CHANGE record. This allows us to keep track of
8136  * full_page_writes during archive recovery, if required.
8137  */
8138  if (XLogStandbyInfoActive() && !recoveryInProgress)
8139  {
8140  XLogBeginInsert();
8141  XLogRegisterData((char *) (&fullPageWrites), sizeof(bool));
8142 
8143  XLogInsert(RM_XLOG_ID, XLOG_FPW_CHANGE);
8144  }
8145 
8146  if (!fullPageWrites)
8147  {
8149  Insert->fullPageWrites = false;
8151  }
8152  END_CRIT_SECTION();
8153 }
#define XLOG_FPW_CHANGE
Definition: pg_control.h:76

References END_CRIT_SECTION, fullPageWrites, XLogCtlData::Insert, Insert(), RecoveryInProgress(), START_CRIT_SECTION, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), XLOG_FPW_CHANGE, XLogBeginInsert(), XLogCtl, XLogInsert(), XLogRegisterData(), and XLogStandbyInfoActive.

Referenced by StartupXLOG(), and UpdateSharedMemoryConfig().

◆ WALReadFromBuffers()

Size WALReadFromBuffers ( char *  dstbuf,
XLogRecPtr  startptr,
Size  count,
TimeLineID  tli 
)

Definition at line 1741 of file xlog.c.

1743 {
1744  char *pdst = dstbuf;
1745  XLogRecPtr recptr = startptr;
1746  XLogRecPtr inserted;
1747  Size nbytes = count;
1748 
1749  if (RecoveryInProgress() || tli != GetWALInsertionTimeLine())
1750  return 0;
1751 
1752  Assert(!XLogRecPtrIsInvalid(startptr));
1753 
1754  /*
1755  * Caller should ensure that the requested data has been inserted into WAL
1756  * buffers before we try to read it.
1757  */
1759  if (startptr + count > inserted)
1760  ereport(ERROR,
1761  errmsg("cannot read past end of generated WAL: requested %X/%X, current position %X/%X",
1762  LSN_FORMAT_ARGS(startptr + count),
1763  LSN_FORMAT_ARGS(inserted)));
1764 
1765  /*
1766  * Loop through the buffers without a lock. For each buffer, atomically
1767  * read and verify the end pointer, then copy the data out, and finally
1768  * re-read and re-verify the end pointer.
1769  *
1770  * Once a page is evicted, it never returns to the WAL buffers, so if the
1771  * end pointer matches the expected end pointer before and after we copy
1772  * the data, then the right page must have been present during the data
1773  * copy. Read barriers are necessary to ensure that the data copy actually
1774  * happens between the two verification steps.
1775  *
1776  * If either verification fails, we simply terminate the loop and return
1777  * with the data that had been already copied out successfully.
1778  */
1779  while (nbytes > 0)
1780  {
1781  uint32 offset = recptr % XLOG_BLCKSZ;
1782  int idx = XLogRecPtrToBufIdx(recptr);
1783  XLogRecPtr expectedEndPtr;
1784  XLogRecPtr endptr;
1785  const char *page;
1786  const char *psrc;
1787  Size npagebytes;
1788 
1789  /*
1790  * Calculate the end pointer we expect in the xlblocks array if the
1791  * correct page is present.
1792  */
1793  expectedEndPtr = recptr + (XLOG_BLCKSZ - offset);
1794 
1795  /*
1796  * First verification step: check that the correct page is present in
1797  * the WAL buffers.
1798  */
1799  endptr = pg_atomic_read_u64(&XLogCtl->xlblocks[idx]);
1800  if (expectedEndPtr != endptr)
1801  break;
1802 
1803  /*
1804  * The correct page is present (or was at the time the endptr was
1805  * read; must re-verify later). Calculate pointer to source data and
1806  * determine how much data to read from this page.
1807  */
1808  page = XLogCtl->pages + idx * (Size) XLOG_BLCKSZ;
1809  psrc = page + offset;
1810  npagebytes = Min(nbytes, XLOG_BLCKSZ - offset);
1811 
1812  /*
1813  * Ensure that the data copy and the first verification step are not
1814  * reordered.
1815  */
1816  pg_read_barrier();
1817 
1818  /* data copy */
1819  memcpy(pdst, psrc, npagebytes);
1820 
1821  /*
1822  * Ensure that the data copy and the second verification step are not
1823  * reordered.
1824  */
1825  pg_read_barrier();
1826 
1827  /*
1828  * Second verification step: check that the page we read from wasn't
1829  * evicted while we were copying the data.
1830  */
1831  endptr = pg_atomic_read_u64(&XLogCtl->xlblocks[idx]);
1832  if (expectedEndPtr != endptr)
1833  break;
1834 
1835  pdst += npagebytes;
1836  recptr += npagebytes;
1837  nbytes -= npagebytes;
1838  }
1839 
1840  Assert(pdst - dstbuf <= count);
1841 
1842  return pdst - dstbuf;
1843 }
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
#define pg_read_barrier()
Definition: atomics.h:149
static uint64 pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr)
Definition: atomics.h:460
#define Min(x, y)
Definition: c.h:1004
size_t Size
Definition: c.h:605
TimeLineID GetWALInsertionTimeLine(void)
Definition: xlog.c:6476

References Assert, ereport, errmsg(), ERROR, GetWALInsertionTimeLine(), idx(), XLogCtlData::logInsertResult, LSN_FORMAT_ARGS, Min, XLogCtlData::pages, pg_atomic_read_u64(), pg_read_barrier, RecoveryInProgress(), XLogCtlData::xlblocks, XLogCtl, XLogRecPtrIsInvalid, and XLogRecPtrToBufIdx.

Referenced by XLogSendPhysical().

◆ xlog_desc()

void xlog_desc ( StringInfo  buf,
struct XLogReaderState record 
)

Definition at line 58 of file xlogdesc.c.

59 {
60  char *rec = XLogRecGetData(record);
61  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
62 
63  if (info == XLOG_CHECKPOINT_SHUTDOWN ||
64  info == XLOG_CHECKPOINT_ONLINE)
65  {
66  CheckPoint *checkpoint = (CheckPoint *) rec;
67 
68  appendStringInfo(buf, "redo %X/%X; "
69  "tli %u; prev tli %u; fpw %s; wal_level %s; xid %u:%u; oid %u; multi %u; offset %u; "
70  "oldest xid %u in DB %u; oldest multi %u in DB %u; "
71  "oldest/newest commit timestamp xid: %u/%u; "
72  "oldest running xid %u; %s",
73  LSN_FORMAT_ARGS(checkpoint->redo),
74  checkpoint->ThisTimeLineID,
75  checkpoint->PrevTimeLineID,
76  checkpoint->fullPageWrites ? "true" : "false",
77  get_wal_level_string(checkpoint->wal_level),
79  XidFromFullTransactionId(checkpoint->nextXid),
80  checkpoint->nextOid,
81  checkpoint->nextMulti,
82  checkpoint->nextMultiOffset,
83  checkpoint->oldestXid,
84  checkpoint->oldestXidDB,
85  checkpoint->oldestMulti,
86  checkpoint->oldestMultiDB,
87  checkpoint->oldestCommitTsXid,
88  checkpoint->newestCommitTsXid,
89  checkpoint->oldestActiveXid,
90  (info == XLOG_CHECKPOINT_SHUTDOWN) ? "shutdown" : "online");
91  }
92  else if (info == XLOG_NEXTOID)
93  {
94  Oid nextOid;
95 
96  memcpy(&nextOid, rec, sizeof(Oid));
97  appendStringInfo(buf, "%u", nextOid);
98  }
99  else if (info == XLOG_RESTORE_POINT)
100  {
101  xl_restore_point *xlrec = (xl_restore_point *) rec;
102 
104  }
105  else if (info == XLOG_FPI || info == XLOG_FPI_FOR_HINT)
106  {
107  /* no further information to print */
108  }
109  else if (info == XLOG_BACKUP_END)
110  {
111  XLogRecPtr startpoint;
112 
113  memcpy(&startpoint, rec, sizeof(XLogRecPtr));
114  appendStringInfo(buf, "%X/%X", LSN_FORMAT_ARGS(startpoint));
115  }
116  else if (info == XLOG_PARAMETER_CHANGE)
117  {
118  xl_parameter_change xlrec;
119  const char *wal_level_str;
120 
121  memcpy(&xlrec, rec, sizeof(xl_parameter_change));
123 
124  appendStringInfo(buf, "max_connections=%d max_worker_processes=%d "
125  "max_wal_senders=%d max_prepared_xacts=%d "
126  "max_locks_per_xact=%d wal_level=%s "
127  "wal_log_hints=%s track_commit_timestamp=%s",
128  xlrec.MaxConnections,
129  xlrec.max_worker_processes,
130  xlrec.max_wal_senders,
131  xlrec.max_prepared_xacts,
132  xlrec.max_locks_per_xact,
134  xlrec.wal_log_hints ? "on" : "off",
135  xlrec.track_commit_timestamp ? "on" : "off");
136  }
137  else if (info == XLOG_FPW_CHANGE)
138  {
139  bool fpw;
140 
141  memcpy(&fpw, rec, sizeof(bool));
142  appendStringInfoString(buf, fpw ? "true" : "false");
143  }
144  else if (info == XLOG_END_OF_RECOVERY)
145  {
146  xl_end_of_recovery xlrec;
147 
148  memcpy(&xlrec, rec, sizeof(xl_end_of_recovery));
149  appendStringInfo(buf, "tli %u; prev tli %u; time %s; wal_level %s",
150  xlrec.ThisTimeLineID, xlrec.PrevTimeLineID,
153  }
154  else if (info == XLOG_OVERWRITE_CONTRECORD)
155  {
157 
158  memcpy(&xlrec, rec, sizeof(xl_overwrite_contrecord));
159  appendStringInfo(buf, "lsn %X/%X; time %s",
162  }
163  else if (info == XLOG_CHECKPOINT_REDO)
164  {
165  int wal_level;
166 
167  memcpy(&wal_level, rec, sizeof(int));
169  }
170 }
static const char * wal_level_str(WalLevel wal_level)
unsigned char uint8
Definition: c.h:504
#define XLOG_RESTORE_POINT
Definition: pg_control.h:75
#define XLOG_OVERWRITE_CONTRECORD
Definition: pg_control.h:81
#define XLOG_FPI
Definition: pg_control.h:79
#define XLOG_FPI_FOR_HINT
Definition: pg_control.h:78
#define XLOG_NEXTOID
Definition: pg_control.h:71
#define XLOG_PARAMETER_CHANGE
Definition: pg_control.h:74
#define XLOG_END_OF_RECOVERY
Definition: pg_control.h:77
static char * buf
Definition: pg_test_fsync.c:73
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:182
TimeLineID PrevTimeLineID
TimestampTz end_time
TimeLineID ThisTimeLineID
char rp_name[MAXFNAMELEN]
#define EpochFromFullTransactionId(x)
Definition: transam.h:47
static const char * get_wal_level_string(int wal_level)
Definition: xlogdesc.c:40
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:410
#define XLogRecGetData(decoder)
Definition: xlogreader.h:415
#define XLR_INFO_MASK
Definition: xlogrecord.h:62

References appendStringInfo(), appendStringInfoString(), buf, xl_end_of_recovery::end_time, EpochFromFullTransactionId, CheckPoint::fullPageWrites, get_wal_level_string(), LSN_FORMAT_ARGS, xl_parameter_change::max_locks_per_xact, xl_parameter_change::max_prepared_xacts, xl_parameter_change::max_wal_senders, xl_parameter_change::max_worker_processes, xl_parameter_change::MaxConnections, CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::nextXid, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, xl_overwrite_contrecord::overwrite_time, xl_overwrite_contrecord::overwritten_lsn, xl_end_of_recovery::PrevTimeLineID, CheckPoint::PrevTimeLineID, CheckPoint::redo, xl_restore_point::rp_name, xl_end_of_recovery::ThisTimeLineID, CheckPoint::ThisTimeLineID, timestamptz_to_str(), xl_parameter_change::track_commit_timestamp, wal_level, xl_parameter_change::wal_level, xl_end_of_recovery::wal_level, CheckPoint::wal_level, wal_level_str(), xl_parameter_change::wal_log_hints, XidFromFullTransactionId, XLOG_BACKUP_END, XLOG_CHECKPOINT_ONLINE, XLOG_CHECKPOINT_REDO, XLOG_CHECKPOINT_SHUTDOWN, XLOG_END_OF_RECOVERY, XLOG_FPI, XLOG_FPI_FOR_HINT, XLOG_FPW_CHANGE, XLOG_NEXTOID, XLOG_OVERWRITE_CONTRECORD, XLOG_PARAMETER_CHANGE, XLOG_RESTORE_POINT, XLogRecGetData, XLogRecGetInfo, and XLR_INFO_MASK.

◆ xlog_identify()

const char* xlog_identify ( uint8  info)

Definition at line 173 of file xlogdesc.c.

174 {
175  const char *id = NULL;
176 
177  switch (info & ~XLR_INFO_MASK)
178  {
180  id = "CHECKPOINT_SHUTDOWN";
181  break;
183  id = "CHECKPOINT_ONLINE";
184  break;
185  case XLOG_NOOP:
186  id = "NOOP";
187  break;
188  case XLOG_NEXTOID:
189  id = "NEXTOID";
190  break;
191  case XLOG_SWITCH:
192  id = "SWITCH";
193  break;
194  case XLOG_BACKUP_END:
195  id = "BACKUP_END";
196  break;
198  id = "PARAMETER_CHANGE";
199  break;
200  case XLOG_RESTORE_POINT:
201  id = "RESTORE_POINT";
202  break;
203  case XLOG_FPW_CHANGE:
204  id = "FPW_CHANGE";
205  break;
207  id = "END_OF_RECOVERY";
208  break;
210  id = "OVERWRITE_CONTRECORD";
211  break;
212  case XLOG_FPI:
213  id = "FPI";
214  break;
215  case XLOG_FPI_FOR_HINT:
216  id = "FPI_FOR_HINT";
217  break;
219  id = "CHECKPOINT_REDO";
220  break;
221  }
222 
223  return id;
224 }
#define XLOG_NOOP
Definition: pg_control.h:70
#define XLOG_SWITCH
Definition: pg_control.h:72

References XLOG_BACKUP_END, XLOG_CHECKPOINT_ONLINE, XLOG_CHECKPOINT_REDO, XLOG_CHECKPOINT_SHUTDOWN, XLOG_END_OF_RECOVERY, XLOG_FPI, XLOG_FPI_FOR_HINT,