Thanks to visit codestin.com
Credit goes to doxygen.postgresql.org

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_FAST   0x0004 /* Do it without delays */
 
#define CHECKPOINT_FORCE   0x0008 /* Force even if no activity */
 
#define CHECKPOINT_FLUSH_UNLOGGED   0x0010 /* Flush unlogged tables */
 
#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)
 
bool GetDefaultCharSignedness (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)
 
bool 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)
 
TimeLineID GetWALInsertionTimeLineIfSet (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 bool * wal_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 303 of file xlog.h.

◆ BACKUP_LABEL_OLD

#define BACKUP_LABEL_OLD   "backup_label.old"

Definition at line 304 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_FAST

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

Definition at line 141 of file xlog.h.

◆ CHECKPOINT_FLUSH_UNLOGGED

#define CHECKPOINT_FLUSH_UNLOGGED   0x0010 /* Flush 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_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 310 of file xlog.h.

◆ RECOVERY_SIGNAL_FILE

#define RECOVERY_SIGNAL_FILE   "recovery.signal"

Definition at line 301 of file xlog.h.

◆ STANDBY_SIGNAL_FILE

#define STANDBY_SIGNAL_FILE   "standby.signal"

Definition at line 302 of file xlog.h.

◆ TABLESPACE_MAP

#define TABLESPACE_MAP   "tablespace_map"

Definition at line 306 of file xlog.h.

◆ TABLESPACE_MAP_OLD

#define TABLESPACE_MAP_OLD   "tablespace_map.old"

Definition at line 307 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) */
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 286 of file xlog.h.

288{
@ SESSION_BACKUP_RUNNING
Definition: xlog.h:289
@ SESSION_BACKUP_NONE
Definition: xlog.h:288

◆ WALAvailability

Enumerator
WALAVAIL_INVALID_LSN 
WALAVAIL_RESERVED 
WALAVAIL_EXTENDED 
WALAVAIL_UNRESERVED 
WALAVAIL_REMOVED 

Definition at line 187 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 */
195 WALAVAIL_REMOVED, /* WAL segment has been removed */
@ WALAVAIL_REMOVED
Definition: xlog.h:194
@ WALAVAIL_RESERVED
Definition: xlog.h:190
@ WALAVAIL_UNRESERVED
Definition: xlog.h:193
@ WALAVAIL_EXTENDED
Definition: xlog.h:191
@ WALAVAIL_INVALID_LSN
Definition: xlog.h:189

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

5073{
5074 CheckPoint checkPoint;
5075 char *buffer;
5076 XLogPageHeader page;
5077 XLogLongPageHeader longpage;
5078 XLogRecord *record;
5079 char *recptr;
5080 uint64 sysidentifier;
5081 struct timeval tv;
5082 pg_crc32c crc;
5083
5084 /* allow ordinary WAL segment creation, like StartupXLOG() would */
5086
5087 /*
5088 * Select a hopefully-unique system identifier code for this installation.
5089 * We use the result of gettimeofday(), including the fractional seconds
5090 * field, as being about as unique as we can easily get. (Think not to
5091 * use random(), since it hasn't been seeded and there's no portable way
5092 * to seed it other than the system clock value...) The upper half of the
5093 * uint64 value is just the tv_sec part, while the lower half contains the
5094 * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
5095 * PID for a little extra uniqueness. A person knowing this encoding can
5096 * determine the initialization time of the installation, which could
5097 * perhaps be useful sometimes.
5098 */
5099 gettimeofday(&tv, NULL);
5100 sysidentifier = ((uint64) tv.tv_sec) << 32;
5101 sysidentifier |= ((uint64) tv.tv_usec) << 12;
5102 sysidentifier |= getpid() & 0xFFF;
5103
5104 /* page buffer must be aligned suitably for O_DIRECT */
5105 buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
5106 page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
5107 memset(page, 0, XLOG_BLCKSZ);
5108
5109 /*
5110 * Set up information for the initial checkpoint record
5111 *
5112 * The initial checkpoint record is written to the beginning of the WAL
5113 * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5114 * used, so that we can use 0/0 to mean "before any valid WAL segment".
5115 */
5119 checkPoint.fullPageWrites = fullPageWrites;
5120 checkPoint.wal_level = wal_level;
5121 checkPoint.nextXid =
5123 checkPoint.nextOid = FirstGenbkiObjectId;
5124 checkPoint.nextMulti = FirstMultiXactId;
5125 checkPoint.nextMultiOffset = 0;
5127 checkPoint.oldestXidDB = Template1DbOid;
5128 checkPoint.oldestMulti = FirstMultiXactId;
5129 checkPoint.oldestMultiDB = Template1DbOid;
5132 checkPoint.time = (pg_time_t) time(NULL);
5134
5135 TransamVariables->nextXid = checkPoint.nextXid;
5136 TransamVariables->nextOid = checkPoint.nextOid;
5138 MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5139 AdvanceOldestClogXid(checkPoint.oldestXid);
5140 SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5141 SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5143
5144 /* Set up the XLOG page header */
5145 page->xlp_magic = XLOG_PAGE_MAGIC;
5146 page->xlp_info = XLP_LONG_HEADER;
5149 longpage = (XLogLongPageHeader) page;
5150 longpage->xlp_sysid = sysidentifier;
5151 longpage->xlp_seg_size = wal_segment_size;
5152 longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5153
5154 /* Insert the initial checkpoint record */
5155 recptr = ((char *) page + SizeOfXLogLongPHD);
5156 record = (XLogRecord *) recptr;
5157 record->xl_prev = 0;
5158 record->xl_xid = InvalidTransactionId;
5159 record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5161 record->xl_rmid = RM_XLOG_ID;
5162 recptr += SizeOfXLogRecord;
5163 /* fill the XLogRecordDataHeaderShort struct */
5164 *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5165 *(recptr++) = sizeof(checkPoint);
5166 memcpy(recptr, &checkPoint, sizeof(checkPoint));
5167 recptr += sizeof(checkPoint);
5168 Assert(recptr - (char *) record == record->xl_tot_len);
5169
5171 COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5172 COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5173 FIN_CRC32C(crc);
5174 record->xl_crc = crc;
5175
5176 /* Create first XLOG segment file */
5179
5180 /*
5181 * We needn't bother with Reserve/ReleaseExternalFD here, since we'll
5182 * close the file again in a moment.
5183 */
5184
5185 /* Write the first page with the initial record */
5186 errno = 0;
5187 pgstat_report_wait_start(WAIT_EVENT_WAL_BOOTSTRAP_WRITE);
5188 if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5189 {
5190 /* if write didn't set errno, assume problem is no disk space */
5191 if (errno == 0)
5192 errno = ENOSPC;
5193 ereport(PANIC,
5195 errmsg("could not write bootstrap write-ahead log file: %m")));
5196 }
5198
5199 pgstat_report_wait_start(WAIT_EVENT_WAL_BOOTSTRAP_SYNC);
5200 if (pg_fsync(openLogFile) != 0)
5201 ereport(PANIC,
5203 errmsg("could not fsync bootstrap write-ahead log file: %m")));
5205
5206 if (close(openLogFile) != 0)
5207 ereport(PANIC,
5209 errmsg("could not close bootstrap write-ahead log file: %m")));
5210
5211 openLogFile = -1;
5212
5213 /* Now create pg_control */
5214 InitControlFile(sysidentifier, data_checksum_version);
5215 ControlFile->time = checkPoint.time;
5216 ControlFile->checkPoint = checkPoint.redo;
5217 ControlFile->checkPointCopy = checkPoint;
5218
5219 /* some additional ControlFile fields are set in WriteControlFile() */
5221
5222 /* Bootstrap the commit log, too */
5223 BootStrapCLOG();
5227
5228 pfree(buffer);
5229
5230 /*
5231 * Force control file to be read - in contrast to normal processing we'd
5232 * otherwise never run the checks and GUC related initializations therein.
5233 */
5235}
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:804
uint64_t uint64
Definition: c.h:540
void BootStrapCLOG(void)
Definition: clog.c:831
void BootStrapCommitTs(void)
Definition: commit_ts.c:594
void SetCommitTsLimit(TransactionId oldestXact, TransactionId newestXact)
Definition: commit_ts.c:887
int errcode_for_file_access(void)
Definition: elog.c:877
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define PANIC
Definition: elog.h:42
#define ereport(elevel,...)
Definition: elog.h:150
int pg_fsync(int fd)
Definition: fd.c:386
Assert(PointerIsAligned(start, uint64))
#define close(a)
Definition: win32.h:12
#define write(a, b, c)
Definition: win32.h:14
void pfree(void *pointer)
Definition: mcxt.c:1594
void * palloc(Size size)
Definition: mcxt.c:1365
void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset)
Definition: multixact.c:2258
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
Definition: multixact.c:2292
void BootStrapMultiXact(void)
Definition: multixact.c:2025
#define FirstMultiXactId
Definition: multixact.h:26
#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:153
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:158
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:269
#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:69
static void pgstat_report_wait_end(void)
Definition: wait_event.h:85
int gettimeofday(struct timeval *tp, void *tzp)
int XLogFileInit(XLogSegNo logsegno, TimeLineID logtli)
Definition: xlog.c:3393
bool fullPageWrites
Definition: xlog.c:123
static void InitControlFile(uint64 sysidentifier, uint32 data_checksum_version)
Definition: xlog.c:4217
void SetInstallXLogFileSegmentActive(void)
Definition: xlog.c:9525
static int openLogFile
Definition: xlog.c:635
int wal_level
Definition: xlog.c:132
static void WriteControlFile(void)
Definition: xlog.c:4252
int wal_segment_size
Definition: xlog.c:144
static TimeLineID openLogTLI
Definition: xlog.c:637
static ControlFileData * ControlFile
Definition: xlog.c:574
#define BootstrapTimeLineID
Definition: xlog.c:112
static void ReadControlFile(void)
Definition: xlog.c:4361
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 3740 of file xlog.c.

3741{
3742 int save_errno = errno;
3743 XLogSegNo lastRemovedSegNo;
3744
3746 lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3748
3749 if (segno <= lastRemovedSegNo)
3750 {
3751 char filename[MAXFNAMELEN];
3752
3754 errno = save_errno;
3755 ereport(ERROR,
3757 errmsg("requested WAL segment %s has already been removed",
3758 filename)));
3759 }
3760 errno = save_errno;
3761}
#define ERROR
Definition: elog.h:39
static char * filename
Definition: pg_dumpall.c:120
#define SpinLockRelease(lock)
Definition: spin.h:61
#define SpinLockAcquire(lock)
Definition: spin.h:59
slock_t info_lck
Definition: xlog.c:553
XLogSegNo lastRemovedSegNo
Definition: xlog.c:461
static XLogCtlData * XLogCtl
Definition: xlog.c:566
#define MAXFNAMELEN
static void XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
uint64 XLogSegNo
Definition: xlogdefs.h:51

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()

bool CreateCheckPoint ( int  flags)

Definition at line 6938 of file xlog.c.

6939{
6940 bool shutdown;
6941 CheckPoint checkPoint;
6942 XLogRecPtr recptr;
6943 XLogSegNo _logSegNo;
6945 uint32 freespace;
6946 XLogRecPtr PriorRedoPtr;
6947 XLogRecPtr last_important_lsn;
6948 VirtualTransactionId *vxids;
6949 int nvxids;
6950 int oldXLogAllowed = 0;
6951
6952 /*
6953 * An end-of-recovery checkpoint is really a shutdown checkpoint, just
6954 * issued at a different time.
6955 */
6957 shutdown = true;
6958 else
6959 shutdown = false;
6960
6961 /* sanity check */
6962 if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
6963 elog(ERROR, "can't create a checkpoint during recovery");
6964
6965 /*
6966 * Prepare to accumulate statistics.
6967 *
6968 * Note: because it is possible for log_checkpoints to change while a
6969 * checkpoint proceeds, we always accumulate stats, even if
6970 * log_checkpoints is currently off.
6971 */
6974
6975 /*
6976 * Let smgr prepare for checkpoint; this has to happen outside the
6977 * critical section and before we determine the REDO pointer. Note that
6978 * smgr must not do anything that'd have to be undone if we decide no
6979 * checkpoint is needed.
6980 */
6982
6983 /*
6984 * Use a critical section to force system panic if we have trouble.
6985 */
6987
6988 if (shutdown)
6989 {
6990 LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6993 LWLockRelease(ControlFileLock);
6994 }
6995
6996 /* Begin filling in the checkpoint WAL record */
6997 MemSet(&checkPoint, 0, sizeof(checkPoint));
6998 checkPoint.time = (pg_time_t) time(NULL);
6999
7000 /*
7001 * For Hot Standby, derive the oldestActiveXid before we fix the redo
7002 * pointer. This allows us to begin accumulating changes to assemble our
7003 * starting snapshot of locks and transactions.
7004 */
7005 if (!shutdown && XLogStandbyInfoActive())
7006 checkPoint.oldestActiveXid = GetOldestActiveTransactionId(false, true);
7007 else
7009
7010 /*
7011 * Get location of last important record before acquiring insert locks (as
7012 * GetLastImportantRecPtr() also locks WAL locks).
7013 */
7014 last_important_lsn = GetLastImportantRecPtr();
7015
7016 /*
7017 * If this isn't a shutdown or forced checkpoint, and if there has been no
7018 * WAL activity requiring a checkpoint, skip it. The idea here is to
7019 * avoid inserting duplicate checkpoints when the system is idle.
7020 */
7022 CHECKPOINT_FORCE)) == 0)
7023 {
7024 if (last_important_lsn == ControlFile->checkPoint)
7025 {
7028 (errmsg_internal("checkpoint skipped because system is idle")));
7029 return false;
7030 }
7031 }
7032
7033 /*
7034 * An end-of-recovery checkpoint is created before anyone is allowed to
7035 * write WAL. To allow us to write the checkpoint record, temporarily
7036 * enable XLogInsertAllowed.
7037 */
7038 if (flags & CHECKPOINT_END_OF_RECOVERY)
7039 oldXLogAllowed = LocalSetXLogInsertAllowed();
7040
7042 if (flags & CHECKPOINT_END_OF_RECOVERY)
7044 else
7045 checkPoint.PrevTimeLineID = checkPoint.ThisTimeLineID;
7046
7047 /*
7048 * We must block concurrent insertions while examining insert state.
7049 */
7051
7052 checkPoint.fullPageWrites = Insert->fullPageWrites;
7053 checkPoint.wal_level = wal_level;
7054
7055 if (shutdown)
7056 {
7057 XLogRecPtr curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
7058
7059 /*
7060 * Compute new REDO record ptr = location of next XLOG record.
7061 *
7062 * Since this is a shutdown checkpoint, there can't be any concurrent
7063 * WAL insertion.
7064 */
7065 freespace = INSERT_FREESPACE(curInsert);
7066 if (freespace == 0)
7067 {
7068 if (XLogSegmentOffset(curInsert, wal_segment_size) == 0)
7069 curInsert += SizeOfXLogLongPHD;
7070 else
7071 curInsert += SizeOfXLogShortPHD;
7072 }
7073 checkPoint.redo = curInsert;
7074
7075 /*
7076 * Here we update the shared RedoRecPtr for future XLogInsert calls;
7077 * this must be done while holding all the insertion locks.
7078 *
7079 * Note: if we fail to complete the checkpoint, RedoRecPtr will be
7080 * left pointing past where it really needs to point. This is okay;
7081 * the only consequence is that XLogInsert might back up whole buffers
7082 * that it didn't really need to. We can't postpone advancing
7083 * RedoRecPtr because XLogInserts that happen while we are dumping
7084 * buffers must assume that their buffer changes are not included in
7085 * the checkpoint.
7086 */
7087 RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
7088 }
7089
7090 /*
7091 * Now we can release the WAL insertion locks, allowing other xacts to
7092 * proceed while we are flushing disk buffers.
7093 */
7095
7096 /*
7097 * If this is an online checkpoint, we have not yet determined the redo
7098 * point. We do so now by inserting the special XLOG_CHECKPOINT_REDO
7099 * record; the LSN at which it starts becomes the new redo pointer. We
7100 * don't do this for a shutdown checkpoint, because in that case no WAL
7101 * can be written between the redo point and the insertion of the
7102 * checkpoint record itself, so the checkpoint record itself serves to
7103 * mark the redo point.
7104 */
7105 if (!shutdown)
7106 {
7107 /* Include WAL level in record for WAL summarizer's benefit. */
7110 (void) XLogInsert(RM_XLOG_ID, XLOG_CHECKPOINT_REDO);
7111
7112 /*
7113 * XLogInsertRecord will have updated XLogCtl->Insert.RedoRecPtr in
7114 * shared memory and RedoRecPtr in backend-local memory, but we need
7115 * to copy that into the record that will be inserted when the
7116 * checkpoint is complete.
7117 */
7118 checkPoint.redo = RedoRecPtr;
7119 }
7120
7121 /* Update the info_lck-protected copy of RedoRecPtr as well */
7123 XLogCtl->RedoRecPtr = checkPoint.redo;
7125
7126 /*
7127 * If enabled, log checkpoint start. We postpone this until now so as not
7128 * to log anything if we decided to skip the checkpoint.
7129 */
7130 if (log_checkpoints)
7131 LogCheckpointStart(flags, false);
7132
7133 /* Update the process title */
7134 update_checkpoint_display(flags, false, false);
7135
7136 TRACE_POSTGRESQL_CHECKPOINT_START(flags);
7137
7138 /*
7139 * Get the other info we need for the checkpoint record.
7140 *
7141 * We don't need to save oldestClogXid in the checkpoint, it only matters
7142 * for the short period in which clog is being truncated, and if we crash
7143 * during that we'll redo the clog truncation and fix up oldestClogXid
7144 * there.
7145 */
7146 LWLockAcquire(XidGenLock, LW_SHARED);
7147 checkPoint.nextXid = TransamVariables->nextXid;
7148 checkPoint.oldestXid = TransamVariables->oldestXid;
7150 LWLockRelease(XidGenLock);
7151
7152 LWLockAcquire(CommitTsLock, LW_SHARED);
7155 LWLockRelease(CommitTsLock);
7156
7157 LWLockAcquire(OidGenLock, LW_SHARED);
7158 checkPoint.nextOid = TransamVariables->nextOid;
7159 if (!shutdown)
7160 checkPoint.nextOid += TransamVariables->oidCount;
7161 LWLockRelease(OidGenLock);
7162
7163 MultiXactGetCheckptMulti(shutdown,
7164 &checkPoint.nextMulti,
7165 &checkPoint.nextMultiOffset,
7166 &checkPoint.oldestMulti,
7167 &checkPoint.oldestMultiDB);
7168
7169 /*
7170 * Having constructed the checkpoint record, ensure all shmem disk buffers
7171 * and commit-log buffers are flushed to disk.
7172 *
7173 * This I/O could fail for various reasons. If so, we will fail to
7174 * complete the checkpoint, but there is no reason to force a system
7175 * panic. Accordingly, exit critical section while doing it.
7176 */
7178
7179 /*
7180 * In some cases there are groups of actions that must all occur on one
7181 * side or the other of a checkpoint record. Before flushing the
7182 * checkpoint record we must explicitly wait for any backend currently
7183 * performing those groups of actions.
7184 *
7185 * One example is end of transaction, so we must wait for any transactions
7186 * that are currently in commit critical sections. If an xact inserted
7187 * its commit record into XLOG just before the REDO point, then a crash
7188 * restart from the REDO point would not replay that record, which means
7189 * that our flushing had better include the xact's update of pg_xact. So
7190 * we wait till he's out of his commit critical section before proceeding.
7191 * See notes in RecordTransactionCommit().
7192 *
7193 * Because we've already released the insertion locks, this test is a bit
7194 * fuzzy: it is possible that we will wait for xacts we didn't really need
7195 * to wait for. But the delay should be short and it seems better to make
7196 * checkpoint take a bit longer than to hold off insertions longer than
7197 * necessary. (In fact, the whole reason we have this issue is that xact.c
7198 * does commit record XLOG insertion and clog update as two separate steps
7199 * protected by different locks, but again that seems best on grounds of
7200 * minimizing lock contention.)
7201 *
7202 * A transaction that has not yet set delayChkptFlags when we look cannot
7203 * be at risk, since it has not inserted its commit record yet; and one
7204 * that's already cleared it is not at risk either, since it's done fixing
7205 * clog and we will correctly flush the update below. So we cannot miss
7206 * any xacts we need to wait for.
7207 */
7209 if (nvxids > 0)
7210 {
7211 do
7212 {
7213 /*
7214 * Keep absorbing fsync requests while we wait. There could even
7215 * be a deadlock if we don't, if the process that prevents the
7216 * checkpoint is trying to add a request to the queue.
7217 */
7219
7220 pgstat_report_wait_start(WAIT_EVENT_CHECKPOINT_DELAY_START);
7221 pg_usleep(10000L); /* wait for 10 msec */
7223 } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids,
7225 }
7226 pfree(vxids);
7227
7228 CheckPointGuts(checkPoint.redo, flags);
7229
7231 if (nvxids > 0)
7232 {
7233 do
7234 {
7236
7237 pgstat_report_wait_start(WAIT_EVENT_CHECKPOINT_DELAY_COMPLETE);
7238 pg_usleep(10000L); /* wait for 10 msec */
7240 } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids,
7242 }
7243 pfree(vxids);
7244
7245 /*
7246 * Take a snapshot of running transactions and write this to WAL. This
7247 * allows us to reconstruct the state of running transactions during
7248 * archive recovery, if required. Skip, if this info disabled.
7249 *
7250 * If we are shutting down, or Startup process is completing crash
7251 * recovery we don't need to write running xact data.
7252 */
7253 if (!shutdown && XLogStandbyInfoActive())
7255
7257
7258 /*
7259 * Now insert the checkpoint record into XLOG.
7260 */
7262 XLogRegisterData(&checkPoint, sizeof(checkPoint));
7263 recptr = XLogInsert(RM_XLOG_ID,
7264 shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
7266
7267 XLogFlush(recptr);
7268
7269 /*
7270 * We mustn't write any new WAL after a shutdown checkpoint, or it will be
7271 * overwritten at next startup. No-one should even try, this just allows
7272 * sanity-checking. In the case of an end-of-recovery checkpoint, we want
7273 * to just temporarily disable writing until the system has exited
7274 * recovery.
7275 */
7276 if (shutdown)
7277 {
7278 if (flags & CHECKPOINT_END_OF_RECOVERY)
7279 LocalXLogInsertAllowed = oldXLogAllowed;
7280 else
7281 LocalXLogInsertAllowed = 0; /* never again write WAL */
7282 }
7283
7284 /*
7285 * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
7286 * = end of actual checkpoint record.
7287 */
7288 if (shutdown && checkPoint.redo != ProcLastRecPtr)
7289 ereport(PANIC,
7290 (errmsg("concurrent write-ahead log activity while database system is shutting down")));
7291
7292 /*
7293 * Remember the prior checkpoint's redo ptr for
7294 * UpdateCheckPointDistanceEstimate()
7295 */
7296 PriorRedoPtr = ControlFile->checkPointCopy.redo;
7297
7298 /*
7299 * Update the control file.
7300 */
7301 LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7302 if (shutdown)
7305 ControlFile->checkPointCopy = checkPoint;
7306 /* crash recovery should always recover to the end of WAL */
7309
7310 /*
7311 * Persist unloggedLSN value. It's reset on crash recovery, so this goes
7312 * unused on non-shutdown checkpoints, but seems useful to store it always
7313 * for debugging purposes.
7314 */
7316
7318 LWLockRelease(ControlFileLock);
7319
7320 /*
7321 * We are now done with critical updates; no need for system panic if we
7322 * have trouble while fooling with old log segments.
7323 */
7325
7326 /*
7327 * WAL summaries end when the next XLOG_CHECKPOINT_REDO or
7328 * XLOG_CHECKPOINT_SHUTDOWN record is reached. This is the first point
7329 * where (a) we're not inside of a critical section and (b) we can be
7330 * certain that the relevant record has been flushed to disk, which must
7331 * happen before it can be summarized.
7332 *
7333 * If this is a shutdown checkpoint, then this happens reasonably
7334 * promptly: we've only just inserted and flushed the
7335 * XLOG_CHECKPOINT_SHUTDOWN record. If this is not a shutdown checkpoint,
7336 * then this might not be very prompt at all: the XLOG_CHECKPOINT_REDO
7337 * record was written before we began flushing data to disk, and that
7338 * could be many minutes ago at this point. However, we don't XLogFlush()
7339 * after inserting that record, so we're not guaranteed that it's on disk
7340 * until after the above call that flushes the XLOG_CHECKPOINT_ONLINE
7341 * record.
7342 */
7344
7345 /*
7346 * Let smgr do post-checkpoint cleanup (eg, deleting old files).
7347 */
7349
7350 /*
7351 * Update the average distance between checkpoints if the prior checkpoint
7352 * exists.
7353 */
7354 if (PriorRedoPtr != InvalidXLogRecPtr)
7356
7357 INJECTION_POINT("checkpoint-before-old-wal-removal", NULL);
7358
7359 /*
7360 * Delete old log files, those no longer needed for last checkpoint to
7361 * prevent the disk holding the xlog from growing full.
7362 */
7364 KeepLogSeg(recptr, &_logSegNo);
7366 _logSegNo, InvalidOid,
7368 {
7369 /*
7370 * Some slots have been invalidated; recalculate the old-segment
7371 * horizon, starting again from RedoRecPtr.
7372 */
7374 KeepLogSeg(recptr, &_logSegNo);
7375 }
7376 _logSegNo--;
7377 RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr,
7378 checkPoint.ThisTimeLineID);
7379
7380 /*
7381 * Make more log segments if needed. (Do this after recycling old log
7382 * segments, since that may supply some of the needed files.)
7383 */
7384 if (!shutdown)
7385 PreallocXlogFiles(recptr, checkPoint.ThisTimeLineID);
7386
7387 /*
7388 * Truncate pg_subtrans if possible. We can throw away all data before
7389 * the oldest XMIN of any running transaction. No future transaction will
7390 * attempt to reference any pg_subtrans entry older than that (see Asserts
7391 * in subtrans.c). During recovery, though, we mustn't do this because
7392 * StartupSUBTRANS hasn't been called yet.
7393 */
7394 if (!RecoveryInProgress())
7396
7397 /* Real work is done; log and update stats. */
7398 LogCheckpointEnd(false);
7399
7400 /* Reset the process title */
7401 update_checkpoint_display(flags, false, true);
7402
7403 TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
7404 NBuffers,
7408
7409 return true;
7410}
static uint64 pg_atomic_read_membarrier_u64(volatile pg_atomic_uint64 *ptr)
Definition: atomics.h:474
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1645
uint32_t uint32
Definition: c.h:539
#define MemSet(start, val, len)
Definition: c.h:1020
void AbsorbSyncRequests(void)
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1161
#define DEBUG1
Definition: elog.h:30
#define elog(elevel,...)
Definition: elog.h:226
static void Insert(File file)
Definition: fd.c:1314
int NBuffers
Definition: globals.c:142
#define INJECTION_POINT(name, arg)
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1174
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1894
@ LW_SHARED
Definition: lwlock.h:113
@ LW_EXCLUSIVE
Definition: lwlock.h:112
#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:2212
#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:37
#define DELAY_CHKPT_START
Definition: proc.h:135
#define DELAY_CHKPT_COMPLETE
Definition: proc.h:136
TransactionId GetOldestTransactionIdConsideredRunning(void)
Definition: procarray.c:1982
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)
Definition: procarray.c:3051
TransactionId GetOldestActiveTransactionId(bool inCommitOnly, bool allDbs)
Definition: procarray.c:2833
VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
Definition: procarray.c:3005
void pg_usleep(long microsec)
Definition: signal.c:53
bool InvalidateObsoleteReplicationSlots(uint32 possible_causes, XLogSegNo oldestSegno, Oid dboid, TransactionId snapshotConflictHorizon)
Definition: slot.c:2055
@ RS_INVAL_WAL_REMOVED
Definition: slot.h:62
@ RS_INVAL_IDLE_TIMEOUT
Definition: slot.h:68
XLogRecPtr LogStandbySnapshot(void)
Definition: standby.c:1282
TimestampTz ckpt_start_t
Definition: xlog.h:161
int ckpt_segs_removed
Definition: xlog.h:171
int ckpt_segs_added
Definition: xlog.h:170
int ckpt_bufs_written
Definition: xlog.h:167
int ckpt_segs_recycled
Definition: xlog.h:172
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
TimeLineID InsertTimeLineID
Definition: xlog.c:509
XLogRecPtr RedoRecPtr
Definition: xlog.c:457
XLogCtlInsert Insert
Definition: xlog.c:453
TimeLineID PrevTimeLineID
Definition: xlog.c:510
pg_atomic_uint64 unloggedLSN
Definition: xlog.c:464
XLogRecPtr RedoRecPtr
Definition: xlog.c:431
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:385
void SyncPreCheckpoint(void)
Definition: sync.c:177
void SyncPostCheckpoint(void)
Definition: sync.c:202
void WakeupWalSummarizer(void)
XLogRecPtr ProcLastRecPtr
Definition: xlog.c:254
bool RecoveryInProgress(void)
Definition: xlog.c:6383
static void WALInsertLockRelease(void)
Definition: xlog.c:1448
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1861
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1419
static void UpdateControlFile(void)
Definition: xlog.c:4583
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr, TimeLineID insertTLI)
Definition: xlog.c:3878
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:6698
static XLogRecPtr RedoRecPtr
Definition: xlog.c:274
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:6730
static void PreallocXlogFiles(XLogRecPtr endptr, TimeLineID tli)
Definition: xlog.c:3703
bool log_checkpoints
Definition: xlog.c:130
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:7998
static int LocalSetXLogInsertAllowed(void)
Definition: xlog.c:6471
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:6605
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:6835
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:580
static int LocalXLogInsertAllowed
Definition: xlog.c:237
CheckpointStatsData CheckpointStats
Definition: xlog.c:210
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2780
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:7556
static void update_checkpoint_display(int flags, bool restartpoint, bool reset)
Definition: xlog.c:6873
#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
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:474
void XLogRegisterData(const void *data, uint32 len)
Definition: xloginsert.c:364
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, 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, INJECTION_POINT, 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_IDLE_TIMEOUT, RS_INVAL_WAL_REMOVED, 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(), WakeupWalSummarizer(), 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 7636 of file xlog.c.

7637{
7638 XLogRecPtr lastCheckPointRecPtr;
7639 XLogRecPtr lastCheckPointEndPtr;
7640 CheckPoint lastCheckPoint;
7641 XLogRecPtr PriorRedoPtr;
7642 XLogRecPtr receivePtr;
7643 XLogRecPtr replayPtr;
7644 TimeLineID replayTLI;
7645 XLogRecPtr endptr;
7646 XLogSegNo _logSegNo;
7647 TimestampTz xtime;
7648
7649 /* Concurrent checkpoint/restartpoint cannot happen */
7651
7652 /* Get a local copy of the last safe checkpoint record. */
7654 lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
7655 lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
7656 lastCheckPoint = XLogCtl->lastCheckPoint;
7658
7659 /*
7660 * Check that we're still in recovery mode. It's ok if we exit recovery
7661 * mode after this check, the restart point is valid anyway.
7662 */
7663 if (!RecoveryInProgress())
7664 {
7666 (errmsg_internal("skipping restartpoint, recovery has already ended")));
7667 return false;
7668 }
7669
7670 /*
7671 * If the last checkpoint record we've replayed is already our last
7672 * restartpoint, we can't perform a new restart point. We still update
7673 * minRecoveryPoint in that case, so that if this is a shutdown restart
7674 * point, we won't start up earlier than before. That's not strictly
7675 * necessary, but when hot standby is enabled, it would be rather weird if
7676 * the database opened up for read-only connections at a point-in-time
7677 * before the last shutdown. Such time travel is still possible in case of
7678 * immediate shutdown, though.
7679 *
7680 * We don't explicitly advance minRecoveryPoint when we do create a
7681 * restartpoint. It's assumed that flushing the buffers will do that as a
7682 * side-effect.
7683 */
7684 if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
7685 lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
7686 {
7688 errmsg_internal("skipping restartpoint, already performed at %X/%08X",
7689 LSN_FORMAT_ARGS(lastCheckPoint.redo)));
7690
7692 if (flags & CHECKPOINT_IS_SHUTDOWN)
7693 {
7694 LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7697 LWLockRelease(ControlFileLock);
7698 }
7699 return false;
7700 }
7701
7702 /*
7703 * Update the shared RedoRecPtr so that the startup process can calculate
7704 * the number of segments replayed since last restartpoint, and request a
7705 * restartpoint if it exceeds CheckPointSegments.
7706 *
7707 * Like in CreateCheckPoint(), hold off insertions to update it, although
7708 * during recovery this is just pro forma, because no WAL insertions are
7709 * happening.
7710 */
7712 RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
7714
7715 /* Also update the info_lck-protected copy */
7717 XLogCtl->RedoRecPtr = lastCheckPoint.redo;
7719
7720 /*
7721 * Prepare to accumulate statistics.
7722 *
7723 * Note: because it is possible for log_checkpoints to change while a
7724 * checkpoint proceeds, we always accumulate stats, even if
7725 * log_checkpoints is currently off.
7726 */
7729
7730 if (log_checkpoints)
7731 LogCheckpointStart(flags, true);
7732
7733 /* Update the process title */
7734 update_checkpoint_display(flags, true, false);
7735
7736 CheckPointGuts(lastCheckPoint.redo, flags);
7737
7738 /*
7739 * This location needs to be after CheckPointGuts() to ensure that some
7740 * work has already happened during this checkpoint.
7741 */
7742 INJECTION_POINT("create-restart-point", NULL);
7743
7744 /*
7745 * Remember the prior checkpoint's redo ptr for
7746 * UpdateCheckPointDistanceEstimate()
7747 */
7748 PriorRedoPtr = ControlFile->checkPointCopy.redo;
7749
7750 /*
7751 * Update pg_control, using current time. Check that it still shows an
7752 * older checkpoint, else do nothing; this is a quick hack to make sure
7753 * nothing really bad happens if somehow we get here after the
7754 * end-of-recovery checkpoint.
7755 */
7756 LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7757 if (ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
7758 {
7759 /*
7760 * Update the checkpoint information. We do this even if the cluster
7761 * does not show DB_IN_ARCHIVE_RECOVERY to match with the set of WAL
7762 * segments recycled below.
7763 */
7764 ControlFile->checkPoint = lastCheckPointRecPtr;
7765 ControlFile->checkPointCopy = lastCheckPoint;
7766
7767 /*
7768 * Ensure minRecoveryPoint is past the checkpoint record and update it
7769 * if the control file still shows DB_IN_ARCHIVE_RECOVERY. Normally,
7770 * this will have happened already while writing out dirty buffers,
7771 * but not necessarily - e.g. because no buffers were dirtied. We do
7772 * this because a backup performed in recovery uses minRecoveryPoint
7773 * to determine which WAL files must be included in the backup, and
7774 * the file (or files) containing the checkpoint record must be
7775 * included, at a minimum. Note that for an ordinary restart of
7776 * recovery there's no value in having the minimum recovery point any
7777 * earlier than this anyway, because redo will begin just after the
7778 * checkpoint record.
7779 */
7781 {
7782 if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
7783 {
7784 ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
7786
7787 /* update local copy */
7790 }
7791 if (flags & CHECKPOINT_IS_SHUTDOWN)
7793 }
7795 }
7796 LWLockRelease(ControlFileLock);
7797
7798 /*
7799 * Update the average distance between checkpoints/restartpoints if the
7800 * prior checkpoint exists.
7801 */
7802 if (PriorRedoPtr != InvalidXLogRecPtr)
7804
7805 /*
7806 * Delete old log files, those no longer needed for last restartpoint to
7807 * prevent the disk holding the xlog from growing full.
7808 */
7810
7811 /*
7812 * Retreat _logSegNo using the current end of xlog replayed or received,
7813 * whichever is later.
7814 */
7815 receivePtr = GetWalRcvFlushRecPtr(NULL, NULL);
7816 replayPtr = GetXLogReplayRecPtr(&replayTLI);
7817 endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
7818 KeepLogSeg(endptr, &_logSegNo);
7820 _logSegNo, InvalidOid,
7822 {
7823 /*
7824 * Some slots have been invalidated; recalculate the old-segment
7825 * horizon, starting again from RedoRecPtr.
7826 */
7828 KeepLogSeg(endptr, &_logSegNo);
7829 }
7830 _logSegNo--;
7831
7832 /*
7833 * Try to recycle segments on a useful timeline. If we've been promoted
7834 * since the beginning of this restartpoint, use the new timeline chosen
7835 * at end of recovery. If we're still in recovery, use the timeline we're
7836 * currently replaying.
7837 *
7838 * There is no guarantee that the WAL segments will be useful on the
7839 * current timeline; if recovery proceeds to a new timeline right after
7840 * this, the pre-allocated WAL segments on this timeline will not be used,
7841 * and will go wasted until recycled on the next restartpoint. We'll live
7842 * with that.
7843 */
7844 if (!RecoveryInProgress())
7845 replayTLI = XLogCtl->InsertTimeLineID;
7846
7847 RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr, replayTLI);
7848
7849 /*
7850 * Make more log segments if needed. (Do this after recycling old log
7851 * segments, since that may supply some of the needed files.)
7852 */
7853 PreallocXlogFiles(endptr, replayTLI);
7854
7855 /*
7856 * Truncate pg_subtrans if possible. We can throw away all data before
7857 * the oldest XMIN of any running transaction. No future transaction will
7858 * attempt to reference any pg_subtrans entry older than that (see Asserts
7859 * in subtrans.c). When hot standby is disabled, though, we mustn't do
7860 * this because StartupSUBTRANS hasn't been called yet.
7861 */
7862 if (EnableHotStandby)
7864
7865 /* Real work is done; log and update stats. */
7866 LogCheckpointEnd(true);
7867
7868 /* Reset the process title */
7869 update_checkpoint_display(flags, true, true);
7870
7871 xtime = GetLatestXTime();
7873 errmsg("recovery restart point at %X/%08X",
7874 LSN_FORMAT_ARGS(lastCheckPoint.redo)),
7875 xtime ? errdetail("Last completed transaction was at log time %s.",
7876 timestamptz_to_str(xtime)) : 0);
7877
7878 /*
7879 * Finally, execute archive_cleanup_command, if any.
7880 */
7881 if (archiveCleanupCommand && strcmp(archiveCleanupCommand, "") != 0)
7883 "archive_cleanup_command",
7884 false,
7885 WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND);
7886
7887 return true;
7888}
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1862
int64 TimestampTz
Definition: timestamp.h:39
int errdetail(const char *fmt,...)
Definition: elog.c:1207
#define LOG
Definition: elog.h:31
#define DEBUG2
Definition: elog.h:29
bool IsUnderPostmaster
Definition: globals.c:120
@ B_CHECKPOINTER
Definition: miscadmin.h:362
BackendType MyBackendType
Definition: miscinit.c:64
@ DB_IN_ARCHIVE_RECOVERY
Definition: pg_control.h:96
@ DB_SHUTDOWNED_IN_RECOVERY
Definition: pg_control.h:93
CheckPoint lastCheckPoint
Definition: xlog.c:545
XLogRecPtr lastCheckPointRecPtr
Definition: xlog.c:543
XLogRecPtr lastCheckPointEndPtr
Definition: xlog.c:544
XLogRecPtr GetWalRcvFlushRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI)
bool EnableHotStandby
Definition: xlog.c:122
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition: xlog.c:2700
static XLogRecPtr LocalMinRecoveryPoint
Definition: xlog.c:646
static TimeLineID LocalMinRecoveryPointTLI
Definition: xlog.c:647
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:46
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
uint32 TimeLineID
Definition: xlogdefs.h:62
char * archiveCleanupCommand
Definition: xlogrecovery.c:86
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_IDLE_TIMEOUT, 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 9435 of file xlog.c.

9436{
9437 bool during_backup_start = DatumGetBool(arg);
9438
9439 /* If called during backup start, there shouldn't be one already running */
9440 Assert(!during_backup_start || sessionBackupState == SESSION_BACKUP_NONE);
9441
9442 if (during_backup_start || sessionBackupState != SESSION_BACKUP_NONE)
9443 {
9447
9450
9451 if (!during_backup_start)
9453 errmsg("aborting backup due to backend exiting before pg_backup_stop was called"));
9454 }
9455}
#define WARNING
Definition: elog.h:36
void * arg
static bool DatumGetBool(Datum X)
Definition: postgres.h:100
int runningBackups
Definition: xlog.c:439
static SessionBackupState sessionBackupState
Definition: xlog.c:392

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

8835{
8837
8838 Assert(state != NULL);
8840
8841 /*
8842 * During recovery, we don't need to check WAL level. Because, if WAL
8843 * level is not sufficient, it's impossible to get here during recovery.
8844 */
8846 ereport(ERROR,
8847 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8848 errmsg("WAL level not sufficient for making an online backup"),
8849 errhint("\"wal_level\" must be set to \"replica\" or \"logical\" at server start.")));
8850
8851 if (strlen(backupidstr) > MAXPGPATH)
8852 ereport(ERROR,
8853 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8854 errmsg("backup label too long (max %d bytes)",
8855 MAXPGPATH)));
8856
8857 strlcpy(state->name, backupidstr, sizeof(state->name));
8858
8859 /*
8860 * Mark backup active in shared memory. We must do full-page WAL writes
8861 * during an on-line backup even if not doing so at other times, because
8862 * it's quite possible for the backup dump to obtain a "torn" (partially
8863 * written) copy of a database page if it reads the page concurrently with
8864 * our write to the same page. This can be fixed as long as the first
8865 * write to the page in the WAL sequence is a full-page write. Hence, we
8866 * increment runningBackups then force a CHECKPOINT, to ensure there are
8867 * no dirty pages in shared memory that might get dumped while the backup
8868 * is in progress without having a corresponding WAL record. (Once the
8869 * backup is complete, we need not force full-page writes anymore, since
8870 * we expect that any pages not modified during the backup interval must
8871 * have been correctly captured by the backup.)
8872 *
8873 * Note that forcing full-page writes has no effect during an online
8874 * backup from the standby.
8875 *
8876 * We must hold all the insertion locks to change the value of
8877 * runningBackups, to ensure adequate interlocking against
8878 * XLogInsertRecord().
8879 */
8883
8884 /*
8885 * Ensure we decrement runningBackups if we fail below. NB -- for this to
8886 * work correctly, it is critical that sessionBackupState is only updated
8887 * after this block is over.
8888 */
8890 {
8891 bool gotUniqueStartpoint = false;
8892 DIR *tblspcdir;
8893 struct dirent *de;
8894 tablespaceinfo *ti;
8895 int datadirpathlen;
8896
8897 /*
8898 * Force an XLOG file switch before the checkpoint, to ensure that the
8899 * WAL segment the checkpoint is written to doesn't contain pages with
8900 * old timeline IDs. That would otherwise happen if you called
8901 * pg_backup_start() right after restoring from a PITR archive: the
8902 * first WAL segment containing the startup checkpoint has pages in
8903 * the beginning with the old timeline ID. That can cause trouble at
8904 * recovery: we won't have a history file covering the old timeline if
8905 * pg_wal directory was not included in the base backup and the WAL
8906 * archive was cleared too before starting the backup.
8907 *
8908 * This also ensures that we have emitted a WAL page header that has
8909 * XLP_BKP_REMOVABLE off before we emit the checkpoint record.
8910 * Therefore, if a WAL archiver (such as pglesslog) is trying to
8911 * compress out removable backup blocks, it won't remove any that
8912 * occur after this point.
8913 *
8914 * During recovery, we skip forcing XLOG file switch, which means that
8915 * the backup taken during recovery is not available for the special
8916 * recovery case described above.
8917 */
8919 RequestXLogSwitch(false);
8920
8921 do
8922 {
8923 bool checkpointfpw;
8924
8925 /*
8926 * Force a CHECKPOINT. Aside from being necessary to prevent torn
8927 * page problems, this guarantees that two successive backup runs
8928 * will have different checkpoint positions and hence different
8929 * history file names, even if nothing happened in between.
8930 *
8931 * During recovery, establish a restartpoint if possible. We use
8932 * the last restartpoint as the backup starting checkpoint. This
8933 * means that two successive backup runs can have same checkpoint
8934 * positions.
8935 *
8936 * Since the fact that we are executing do_pg_backup_start()
8937 * during recovery means that checkpointer is running, we can use
8938 * RequestCheckpoint() to establish a restartpoint.
8939 *
8940 * We use CHECKPOINT_FAST only if requested by user (via passing
8941 * fast = true). Otherwise this can take awhile.
8942 */
8944 (fast ? CHECKPOINT_FAST : 0));
8945
8946 /*
8947 * Now we need to fetch the checkpoint record location, and also
8948 * its REDO pointer. The oldest point in WAL that would be needed
8949 * to restore starting from the checkpoint is precisely the REDO
8950 * pointer.
8951 */
8952 LWLockAcquire(ControlFileLock, LW_SHARED);
8953 state->checkpointloc = ControlFile->checkPoint;
8954 state->startpoint = ControlFile->checkPointCopy.redo;
8956 checkpointfpw = ControlFile->checkPointCopy.fullPageWrites;
8957 LWLockRelease(ControlFileLock);
8958
8960 {
8961 XLogRecPtr recptr;
8962
8963 /*
8964 * Check to see if all WAL replayed during online backup
8965 * (i.e., since last restartpoint used as backup starting
8966 * checkpoint) contain full-page writes.
8967 */
8969 recptr = XLogCtl->lastFpwDisableRecPtr;
8971
8972 if (!checkpointfpw || state->startpoint <= recptr)
8973 ereport(ERROR,
8974 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8975 errmsg("WAL generated with \"full_page_writes=off\" was replayed "
8976 "since last restartpoint"),
8977 errhint("This means that the backup being taken on the standby "
8978 "is corrupt and should not be used. "
8979 "Enable \"full_page_writes\" and run CHECKPOINT on the primary, "
8980 "and then try an online backup again.")));
8981
8982 /*
8983 * During recovery, since we don't use the end-of-backup WAL
8984 * record and don't write the backup history file, the
8985 * starting WAL location doesn't need to be unique. This means
8986 * that two base backups started at the same time might use
8987 * the same checkpoint as starting locations.
8988 */
8989 gotUniqueStartpoint = true;
8990 }
8991
8992 /*
8993 * If two base backups are started at the same time (in WAL sender
8994 * processes), we need to make sure that they use different
8995 * checkpoints as starting locations, because we use the starting
8996 * WAL location as a unique identifier for the base backup in the
8997 * end-of-backup WAL record and when we write the backup history
8998 * file. Perhaps it would be better generate a separate unique ID
8999 * for each backup instead of forcing another checkpoint, but
9000 * taking a checkpoint right after another is not that expensive
9001 * either because only few buffers have been dirtied yet.
9002 */
9004 if (XLogCtl->Insert.lastBackupStart < state->startpoint)
9005 {
9006 XLogCtl->Insert.lastBackupStart = state->startpoint;
9007 gotUniqueStartpoint = true;
9008 }
9010 } while (!gotUniqueStartpoint);
9011
9012 /*
9013 * Construct tablespace_map file.
9014 */
9015 datadirpathlen = strlen(DataDir);
9016
9017 /* Collect information about all tablespaces */
9018 tblspcdir = AllocateDir(PG_TBLSPC_DIR);
9019 while ((de = ReadDir(tblspcdir, PG_TBLSPC_DIR)) != NULL)
9020 {
9021 char fullpath[MAXPGPATH + sizeof(PG_TBLSPC_DIR)];
9022 char linkpath[MAXPGPATH];
9023 char *relpath = NULL;
9024 char *s;
9025 PGFileType de_type;
9026 char *badp;
9027 Oid tsoid;
9028
9029 /*
9030 * Try to parse the directory name as an unsigned integer.
9031 *
9032 * Tablespace directories should be positive integers that can be
9033 * represented in 32 bits, with no leading zeroes or trailing
9034 * garbage. If we come across a name that doesn't meet those
9035 * criteria, skip it.
9036 */
9037 if (de->d_name[0] < '1' || de->d_name[1] > '9')
9038 continue;
9039 errno = 0;
9040 tsoid = strtoul(de->d_name, &badp, 10);
9041 if (*badp != '\0' || errno == EINVAL || errno == ERANGE)
9042 continue;
9043
9044 snprintf(fullpath, sizeof(fullpath), "%s/%s", PG_TBLSPC_DIR, de->d_name);
9045
9046 de_type = get_dirent_type(fullpath, de, false, ERROR);
9047
9048 if (de_type == PGFILETYPE_LNK)
9049 {
9050 StringInfoData escapedpath;
9051 int rllen;
9052
9053 rllen = readlink(fullpath, linkpath, sizeof(linkpath));
9054 if (rllen < 0)
9055 {
9057 (errmsg("could not read symbolic link \"%s\": %m",
9058 fullpath)));
9059 continue;
9060 }
9061 else if (rllen >= sizeof(linkpath))
9062 {
9064 (errmsg("symbolic link \"%s\" target is too long",
9065 fullpath)));
9066 continue;
9067 }
9068 linkpath[rllen] = '\0';
9069
9070 /*
9071 * Relpath holds the relative path of the tablespace directory
9072 * when it's located within PGDATA, or NULL if it's located
9073 * elsewhere.
9074 */
9075 if (rllen > datadirpathlen &&
9076 strncmp(linkpath, DataDir, datadirpathlen) == 0 &&
9077 IS_DIR_SEP(linkpath[datadirpathlen]))
9078 relpath = pstrdup(linkpath + datadirpathlen + 1);
9079
9080 /*
9081 * Add a backslash-escaped version of the link path to the
9082 * tablespace map file.
9083 */
9084 initStringInfo(&escapedpath);
9085 for (s = linkpath; *s; s++)
9086 {
9087 if (*s == '\n' || *s == '\r' || *s == '\\')
9088 appendStringInfoChar(&escapedpath, '\\');
9089 appendStringInfoChar(&escapedpath, *s);
9090 }
9091 appendStringInfo(tblspcmapfile, "%s %s\n",
9092 de->d_name, escapedpath.data);
9093 pfree(escapedpath.data);
9094 }
9095 else if (de_type == PGFILETYPE_DIR)
9096 {
9097 /*
9098 * It's possible to use allow_in_place_tablespaces to create
9099 * directories directly under pg_tblspc, for testing purposes
9100 * only.
9101 *
9102 * In this case, we store a relative path rather than an
9103 * absolute path into the tablespaceinfo.
9104 */
9105 snprintf(linkpath, sizeof(linkpath), "%s/%s",
9106 PG_TBLSPC_DIR, de->d_name);
9107 relpath = pstrdup(linkpath);
9108 }
9109 else
9110 {
9111 /* Skip any other file type that appears here. */
9112 continue;
9113 }
9114
9115 ti = palloc(sizeof(tablespaceinfo));
9116 ti->oid = tsoid;
9117 ti->path = pstrdup(linkpath);
9118 ti->rpath = relpath;
9119 ti->size = -1;
9120
9121 if (tablespaces)
9122 *tablespaces = lappend(*tablespaces, ti);
9123 }
9124 FreeDir(tblspcdir);
9125
9126 state->starttime = (pg_time_t) time(NULL);
9127 }
9129
9130 state->started_in_recovery = backup_started_in_recovery;
9131
9132 /*
9133 * Mark that the start phase has correctly finished for the backup.
9134 */
9136}
static bool backup_started_in_recovery
Definition: basebackup.c:123
void RequestCheckpoint(int flags)
int errhint(const char *fmt,...)
Definition: elog.c:1321
int errcode(int sqlerrcode)
Definition: elog.c:854
int FreeDir(DIR *dir)
Definition: fd.c:3022
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2904
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2970
PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
Definition: file_utils.c:547
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:71
#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:1759
#define MAXPGPATH
#define snprintf
Definition: port.h:239
#define IS_DIR_SEP(ch)
Definition: port.h:103
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
static Datum BoolGetDatum(bool X)
Definition: postgres.h:112
unsigned int Oid
Definition: postgres_ext.h:32
#define relpath(rlocator, forknum)
Definition: relpath.h:150
#define PG_TBLSPC_DIR
Definition: relpath.h:41
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:242
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
Definition: dirent.c:26
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:551
XLogRecPtr lastBackupStart
Definition: xlog.c:440
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:226
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:8107
void do_pg_abort_backup(int code, Datum arg)
Definition: xlog.c:9435
#define CHECKPOINT_WAIT
Definition: xlog.h:145
#define CHECKPOINT_FAST
Definition: xlog.h:141
#define XLogIsNeeded()
Definition: xlog.h:109

References AllocateDir(), appendStringInfo(), appendStringInfoChar(), Assert(), backup_started_in_recovery, BoolGetDatum(), ControlFileData::checkPoint, CHECKPOINT_FAST, CHECKPOINT_FORCE, CHECKPOINT_WAIT, ControlFileData::checkPointCopy, ControlFile, dirent::d_name, StringInfoData::data, DataDir, 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, PG_TBLSPC_DIR, 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 9161 of file xlog.c.

9162{
9163 bool backup_stopped_in_recovery = false;
9164 char histfilepath[MAXPGPATH];
9165 char lastxlogfilename[MAXFNAMELEN];
9166 char histfilename[MAXFNAMELEN];
9167 XLogSegNo _logSegNo;
9168 FILE *fp;
9169 int seconds_before_warning;
9170 int waits = 0;
9171 bool reported_waiting = false;
9172
9173 Assert(state != NULL);
9174
9175 backup_stopped_in_recovery = RecoveryInProgress();
9176
9177 /*
9178 * During recovery, we don't need to check WAL level. Because, if WAL
9179 * level is not sufficient, it's impossible to get here during recovery.
9180 */
9181 if (!backup_stopped_in_recovery && !XLogIsNeeded())
9182 ereport(ERROR,
9183 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
9184 errmsg("WAL level not sufficient for making an online backup"),
9185 errhint("\"wal_level\" must be set to \"replica\" or \"logical\" at server start.")));
9186
9187 /*
9188 * OK to update backup counter and session-level lock.
9189 *
9190 * Note that CHECK_FOR_INTERRUPTS() must not occur while updating them,
9191 * otherwise they can be updated inconsistently, which might cause
9192 * do_pg_abort_backup() to fail.
9193 */
9195
9196 /*
9197 * It is expected that each do_pg_backup_start() call is matched by
9198 * exactly one do_pg_backup_stop() call.
9199 */
9202
9203 /*
9204 * Clean up session-level lock.
9205 *
9206 * You might think that WALInsertLockRelease() can be called before
9207 * cleaning up session-level lock because session-level lock doesn't need
9208 * to be protected with WAL insertion lock. But since
9209 * CHECK_FOR_INTERRUPTS() can occur in it, session-level lock must be
9210 * cleaned up before it.
9211 */
9213
9215
9216 /*
9217 * If we are taking an online backup from the standby, we confirm that the
9218 * standby has not been promoted during the backup.
9219 */
9220 if (state->started_in_recovery && !backup_stopped_in_recovery)
9221 ereport(ERROR,
9222 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
9223 errmsg("the standby was promoted during online backup"),
9224 errhint("This means that the backup being taken is corrupt "
9225 "and should not be used. "
9226 "Try taking another online backup.")));
9227
9228 /*
9229 * During recovery, we don't write an end-of-backup record. We assume that
9230 * pg_control was backed up last and its minimum recovery point can be
9231 * available as the backup end location. Since we don't have an
9232 * end-of-backup record, we use the pg_control value to check whether
9233 * we've reached the end of backup when starting recovery from this
9234 * backup. We have no way of checking if pg_control wasn't backed up last
9235 * however.
9236 *
9237 * We don't force a switch to new WAL file but it is still possible to
9238 * wait for all the required files to be archived if waitforarchive is
9239 * true. This is okay if we use the backup to start a standby and fetch
9240 * the missing WAL using streaming replication. But in the case of an
9241 * archive recovery, a user should set waitforarchive to true and wait for
9242 * them to be archived to ensure that all the required files are
9243 * available.
9244 *
9245 * We return the current minimum recovery point as the backup end
9246 * location. Note that it can be greater than the exact backup end
9247 * location if the minimum recovery point is updated after the backup of
9248 * pg_control. This is harmless for current uses.
9249 *
9250 * XXX currently a backup history file is for informational and debug
9251 * purposes only. It's not essential for an online backup. Furthermore,
9252 * even if it's created, it will not be archived during recovery because
9253 * an archiver is not invoked. So it doesn't seem worthwhile to write a
9254 * backup history file during recovery.
9255 */
9256 if (backup_stopped_in_recovery)
9257 {
9258 XLogRecPtr recptr;
9259
9260 /*
9261 * Check to see if all WAL replayed during online backup contain
9262 * full-page writes.
9263 */
9265 recptr = XLogCtl->lastFpwDisableRecPtr;
9267
9268 if (state->startpoint <= recptr)
9269 ereport(ERROR,
9270 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
9271 errmsg("WAL generated with \"full_page_writes=off\" was replayed "
9272 "during online backup"),
9273 errhint("This means that the backup being taken on the standby "
9274 "is corrupt and should not be used. "
9275 "Enable \"full_page_writes\" and run CHECKPOINT on the primary, "
9276 "and then try an online backup again.")));
9277
9278
9279 LWLockAcquire(ControlFileLock, LW_SHARED);
9280 state->stoppoint = ControlFile->minRecoveryPoint;
9282 LWLockRelease(ControlFileLock);
9283 }
9284 else
9285 {
9286 char *history_file;
9287
9288 /*
9289 * Write the backup-end xlog record
9290 */
9292 XLogRegisterData(&state->startpoint,
9293 sizeof(state->startpoint));
9294 state->stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
9295
9296 /*
9297 * Given that we're not in recovery, InsertTimeLineID is set and can't
9298 * change, so we can read it without a lock.
9299 */
9300 state->stoptli = XLogCtl->InsertTimeLineID;
9301
9302 /*
9303 * Force a switch to a new xlog segment file, so that the backup is
9304 * valid as soon as archiver moves out the current segment file.
9305 */
9306 RequestXLogSwitch(false);
9307
9308 state->stoptime = (pg_time_t) time(NULL);
9309
9310 /*
9311 * Write the backup history file
9312 */
9313 XLByteToSeg(state->startpoint, _logSegNo, wal_segment_size);
9314 BackupHistoryFilePath(histfilepath, state->stoptli, _logSegNo,
9315 state->startpoint, wal_segment_size);
9316 fp = AllocateFile(histfilepath, "w");
9317 if (!fp)
9318 ereport(ERROR,
9320 errmsg("could not create file \"%s\": %m",
9321 histfilepath)));
9322
9323 /* Build and save the contents of the backup history file */
9324 history_file = build_backup_content(state, true);
9325 fprintf(fp, "%s", history_file);
9326 pfree(history_file);
9327
9328 if (fflush(fp) || ferror(fp) || FreeFile(fp))
9329 ereport(ERROR,
9331 errmsg("could not write file \"%s\": %m",
9332 histfilepath)));
9333
9334 /*
9335 * Clean out any no-longer-needed history files. As a side effect,
9336 * this will post a .ready file for the newly created history file,
9337 * notifying the archiver that history file may be archived
9338 * immediately.
9339 */
9341 }
9342
9343 /*
9344 * If archiving is enabled, wait for all the required WAL files to be
9345 * archived before returning. If archiving isn't enabled, the required WAL
9346 * needs to be transported via streaming replication (hopefully with
9347 * wal_keep_size set high enough), or some more exotic mechanism like
9348 * polling and copying files from pg_wal with script. We have no knowledge
9349 * of those mechanisms, so it's up to the user to ensure that he gets all
9350 * the required WAL.
9351 *
9352 * We wait until both the last WAL file filled during backup and the
9353 * history file have been archived, and assume that the alphabetic sorting
9354 * property of the WAL files ensures any earlier WAL files are safely
9355 * archived as well.
9356 *
9357 * We wait forever, since archive_command is supposed to work and we
9358 * assume the admin wanted his backup to work completely. If you don't
9359 * wish to wait, then either waitforarchive should be passed in as false,
9360 * or you can set statement_timeout. Also, some notices are issued to
9361 * clue in anyone who might be doing this interactively.
9362 */
9363
9364 if (waitforarchive &&
9365 ((!backup_stopped_in_recovery && XLogArchivingActive()) ||
9366 (backup_stopped_in_recovery && XLogArchivingAlways())))
9367 {
9368 XLByteToPrevSeg(state->stoppoint, _logSegNo, wal_segment_size);
9369 XLogFileName(lastxlogfilename, state->stoptli, _logSegNo,
9371
9372 XLByteToSeg(state->startpoint, _logSegNo, wal_segment_size);
9373 BackupHistoryFileName(histfilename, state->stoptli, _logSegNo,
9374 state->startpoint, wal_segment_size);
9375
9376 seconds_before_warning = 60;
9377 waits = 0;
9378
9379 while (XLogArchiveIsBusy(lastxlogfilename) ||
9380 XLogArchiveIsBusy(histfilename))
9381 {
9383
9384 if (!reported_waiting && waits > 5)
9385 {
9387 (errmsg("base backup done, waiting for required WAL segments to be archived")));
9388 reported_waiting = true;
9389 }
9390
9391 (void) WaitLatch(MyLatch,
9393 1000L,
9394 WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE);
9396
9397 if (++waits >= seconds_before_warning)
9398 {
9399 seconds_before_warning *= 2; /* This wraps in >10 years... */
9401 (errmsg("still waiting for all required WAL segments to be archived (%d seconds elapsed)",
9402 waits),
9403 errhint("Check that your \"archive_command\" is executing properly. "
9404 "You can safely cancel this backup, "
9405 "but the database backup will not be usable without all the WAL segments.")));
9406 }
9407 }
9408
9410 (errmsg("all required WAL segments have been archived")));
9411 }
9412 else if (waitforarchive)
9414 (errmsg("WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup")));
9415}
#define fprintf(file, fmt, msg)
Definition: cubescan.l:21
#define NOTICE
Definition: elog.h:35
int FreeFile(FILE *file)
Definition: fd.c:2840
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2641
struct Latch * MyLatch
Definition: globals.c:63
void ResetLatch(Latch *latch)
Definition: latch.c:374
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:172
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
#define XLOG_BACKUP_END
Definition: pg_control.h:73
#define WL_TIMEOUT
Definition: waiteventset.h:37
#define WL_EXIT_ON_PM_DEATH
Definition: waiteventset.h:39
#define WL_LATCH_SET
Definition: waiteventset.h:34
static void CleanupBackupHistory(void)
Definition: xlog.c:4174
#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, 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 9142 of file xlog.c.

9143{
9144 return sessionBackupState;
9145}

References sessionBackupState.

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

◆ GetActiveWalLevelOnStandby()

WalLevel GetActiveWalLevelOnStandby ( void  )

Definition at line 4898 of file xlog.c.

4899{
4900 return ControlFile->wal_level;
4901}

References ControlFile, and ControlFileData::wal_level.

Referenced by CheckLogicalDecodingRequirements().

◆ GetDefaultCharSignedness()

bool GetDefaultCharSignedness ( void  )

Definition at line 4626 of file xlog.c.

4627{
4629}
bool default_char_signedness
Definition: pg_control.h:228

References ControlFile, and ControlFileData::default_char_signedness.

Referenced by CMPTRGM_CHOOSE().

◆ GetFakeLSNForUnloggedRel()

XLogRecPtr GetFakeLSNForUnloggedRel ( void  )

Definition at line 4641 of file xlog.c.

4642{
4644}
static uint64 pg_atomic_fetch_add_u64(volatile pg_atomic_uint64 *ptr, int64 add_)
Definition: atomics.h:520

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

Referenced by gistGetFakeLSN().

◆ GetFlushRecPtr()

XLogRecPtr GetFlushRecPtr ( TimeLineID insertTLI)

Definition at line 6548 of file xlog.c.

6549{
6551
6553
6554 /*
6555 * If we're writing and flushing WAL, the time line can't be changing, so
6556 * no lock is required.
6557 */
6558 if (insertTLI)
6559 *insertTLI = XLogCtl->InsertTimeLineID;
6560
6561 return LogwrtResult.Flush;
6562}
RecoveryState SharedRecoveryState
Definition: xlog.c:516
XLogRecPtr Flush
Definition: xlog.c:329
#define RefreshXLogWriteResult(_target)
Definition: xlog.c:620
static XLogwrtResult LogwrtResult
Definition: xlog.c:612

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

6517{
6518 *RedoRecPtr_p = RedoRecPtr;
6519 *doPageWrites_p = doPageWrites;
6520}
static bool doPageWrites
Definition: xlog.c:287

References doPageWrites, and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )

Definition at line 6531 of file xlog.c.

6532{
6533 XLogRecPtr recptr;
6534
6536 recptr = XLogCtl->LogwrtRqst.Write;
6538
6539 return recptr;
6540}
XLogwrtRqst LogwrtRqst
Definition: xlog.c:456
XLogRecPtr Write
Definition: xlog.c:322

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

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

◆ GetLastImportantRecPtr()

XLogRecPtr GetLastImportantRecPtr ( void  )

Definition at line 6605 of file xlog.c.

6606{
6608 int i;
6609
6610 for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
6611 {
6612 XLogRecPtr last_important;
6613
6614 /*
6615 * Need to take a lock to prevent torn reads of the LSN, which are
6616 * possible on some of the supported platforms. WAL insert locks only
6617 * support exclusive mode, so we have to use that.
6618 */
6620 last_important = WALInsertLocks[i].l.lastImportantAt;
6621 LWLockRelease(&WALInsertLocks[i].l.lock);
6622
6623 if (res < last_important)
6624 res = last_important;
6625 }
6626
6627 return res;
6628}
int i
Definition: isn.c:77
XLogRecPtr lastImportantAt
Definition: xlog.c:372
WALInsertLock l
Definition: xlog.c:384
static WALInsertLockPadded * WALInsertLocks
Definition: xlog.c:569
#define NUM_XLOGINSERT_LOCKS
Definition: xlog.c:151

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

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

◆ GetMockAuthenticationNonce()

char * GetMockAuthenticationNonce ( void  )

Definition at line 4602 of file xlog.c.

4603{
4604 Assert(ControlFile != NULL);
4606}
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition: pg_control.h:235

References Assert(), ControlFile, and ControlFileData::mock_authentication_nonce.

Referenced by scram_mock_salt().

◆ GetRecoveryState()

RecoveryState GetRecoveryState ( void  )

Definition at line 6419 of file xlog.c.

6420{
6421 RecoveryState retval;
6422
6424 retval = XLogCtl->SharedRecoveryState;
6426
6427 return retval;
6428}

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

Referenced by XLogArchiveCheckDone().

◆ GetRedoRecPtr()

XLogRecPtr GetRedoRecPtr ( void  )

Definition at line 6486 of file xlog.c.

6487{
6488 XLogRecPtr ptr;
6489
6490 /*
6491 * The possibly not up-to-date copy in XlogCtl is enough. Even if we
6492 * grabbed a WAL insertion lock to read the authoritative value in
6493 * Insert->RedoRecPtr, someone might update it just after we've released
6494 * the lock.
6495 */
6497 ptr = XLogCtl->RedoRecPtr;
6499
6500 if (RedoRecPtr < ptr)
6501 RedoRecPtr = ptr;
6502
6503 return RedoRecPtr;
6504}

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()

◆ GetWALAvailability()

WALAvailability GetWALAvailability ( XLogRecPtr  targetLSN)

Definition at line 7914 of file xlog.c.

7915{
7916 XLogRecPtr currpos; /* current write LSN */
7917 XLogSegNo currSeg; /* segid of currpos */
7918 XLogSegNo targetSeg; /* segid of targetLSN */
7919 XLogSegNo oldestSeg; /* actual oldest segid */
7920 XLogSegNo oldestSegMaxWalSize; /* oldest segid kept by max_wal_size */
7921 XLogSegNo oldestSlotSeg; /* oldest segid kept by slot */
7922 uint64 keepSegs;
7923
7924 /*
7925 * slot does not reserve WAL. Either deactivated, or has never been active
7926 */
7927 if (XLogRecPtrIsInvalid(targetLSN))
7928 return WALAVAIL_INVALID_LSN;
7929
7930 /*
7931 * Calculate the oldest segment currently reserved by all slots,
7932 * considering wal_keep_size and max_slot_wal_keep_size. Initialize
7933 * oldestSlotSeg to the current segment.
7934 */
7935 currpos = GetXLogWriteRecPtr();
7936 XLByteToSeg(currpos, oldestSlotSeg, wal_segment_size);
7937 KeepLogSeg(currpos, &oldestSlotSeg);
7938
7939 /*
7940 * Find the oldest extant segment file. We get 1 until checkpoint removes
7941 * the first WAL segment file since startup, which causes the status being
7942 * wrong under certain abnormal conditions but that doesn't actually harm.
7943 */
7944 oldestSeg = XLogGetLastRemovedSegno() + 1;
7945
7946 /* calculate oldest segment by max_wal_size */
7947 XLByteToSeg(currpos, currSeg, wal_segment_size);
7949
7950 if (currSeg > keepSegs)
7951 oldestSegMaxWalSize = currSeg - keepSegs;
7952 else
7953 oldestSegMaxWalSize = 1;
7954
7955 /* the segment we care about */
7956 XLByteToSeg(targetLSN, targetSeg, wal_segment_size);
7957
7958 /*
7959 * No point in returning reserved or extended status values if the
7960 * targetSeg is known to be lost.
7961 */
7962 if (targetSeg >= oldestSlotSeg)
7963 {
7964 /* show "reserved" when targetSeg is within max_wal_size */
7965 if (targetSeg >= oldestSegMaxWalSize)
7966 return WALAVAIL_RESERVED;
7967
7968 /* being retained by slots exceeding max_wal_size */
7969 return WALAVAIL_EXTENDED;
7970 }
7971
7972 /* WAL segments are no longer retained but haven't been removed yet */
7973 if (targetSeg >= oldestSeg)
7974 return WALAVAIL_UNRESERVED;
7975
7976 /* Definitely lost */
7977 return WALAVAIL_REMOVED;
7978}
XLogSegNo XLogGetLastRemovedSegno(void)
Definition: xlog.c:3771
int max_wal_size_mb
Definition: xlog.c:115
#define ConvertToXSegs(x, segsize)
Definition: xlog.c:603
XLogRecPtr GetXLogWriteRecPtr(void)
Definition: xlog.c:9492

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  )

◆ GetWALInsertionTimeLineIfSet()

TimeLineID GetWALInsertionTimeLineIfSet ( void  )

Definition at line 6585 of file xlog.c.

6586{
6587 TimeLineID insertTLI;
6588
6590 insertTLI = XLogCtl->InsertTimeLineID;
6592
6593 return insertTLI;
6594}

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

Referenced by GetLatestLSN().

◆ GetXLogInsertRecPtr()

XLogRecPtr GetXLogInsertRecPtr ( void  )

Definition at line 9476 of file xlog.c.

9477{
9479 uint64 current_bytepos;
9480
9481 SpinLockAcquire(&Insert->insertpos_lck);
9482 current_bytepos = Insert->CurrBytePos;
9483 SpinLockRelease(&Insert->insertpos_lck);
9484
9485 return XLogBytePosToRecPtr(current_bytepos);
9486}

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()

◆ InitializeWalConsistencyChecking()

void InitializeWalConsistencyChecking ( void  )

Definition at line 4823 of file xlog.c.

4824{
4826
4828 {
4829 struct config_generic *guc;
4830
4831 guc = find_option("wal_consistency_checking", false, false, ERROR);
4832
4834
4835 set_config_option_ext("wal_consistency_checking",
4837 guc->scontext, guc->source, guc->srole,
4838 GUC_ACTION_SET, true, ERROR, false);
4839
4840 /* checking should not be deferred again */
4842 }
4843}
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:3387
struct config_generic * find_option(const char *name, bool create_placeholders, bool skip_errors, int elevel)
Definition: guc.c:1236
@ GUC_ACTION_SET
Definition: guc.h:203
bool process_shared_preload_libraries_done
Definition: miscinit.c:1787
GucContext scontext
Definition: guc_tables.h:185
GucSource source
Definition: guc_tables.h:183
char * wal_consistency_checking_string
Definition: xlog.c:126
static bool check_wal_consistency_checking_deferred
Definition: xlog.c:167

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

9534{
9535 bool result;
9536
9537 LWLockAcquire(ControlFileLock, LW_SHARED);
9539 LWLockRelease(ControlFileLock);
9540
9541 return result;
9542}
bool InstallXLogFileSegmentActive
Definition: xlog.c:526

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

8737{
8738 char *msg = NULL;
8740
8741 Assert(tli != 0);
8742
8743 /*
8744 * Quick exit if fsync is disabled or write() has already synced the WAL
8745 * file.
8746 */
8747 if (!enableFsync ||
8750 return;
8751
8752 /*
8753 * Measure I/O timing to sync the WAL file for pg_stat_io.
8754 */
8756
8757 pgstat_report_wait_start(WAIT_EVENT_WAL_SYNC);
8758 switch (wal_sync_method)
8759 {
8761 if (pg_fsync_no_writethrough(fd) != 0)
8762 msg = _("could not fsync file \"%s\": %m");
8763 break;
8764#ifdef HAVE_FSYNC_WRITETHROUGH
8766 if (pg_fsync_writethrough(fd) != 0)
8767 msg = _("could not fsync write-through file \"%s\": %m");
8768 break;
8769#endif
8771 if (pg_fdatasync(fd) != 0)
8772 msg = _("could not fdatasync file \"%s\": %m");
8773 break;
8776 /* not reachable */
8777 Assert(false);
8778 break;
8779 default:
8780 ereport(PANIC,
8781 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8782 errmsg_internal("unrecognized \"wal_sync_method\": %d", wal_sync_method));
8783 break;
8784 }
8785
8786 /* PANIC if failed to fsync */
8787 if (msg)
8788 {
8789 char xlogfname[MAXFNAMELEN];
8790 int save_errno = errno;
8791
8792 XLogFileName(xlogfname, tli, segno, wal_segment_size);
8793 errno = save_errno;
8794 ereport(PANIC,
8796 errmsg(msg, xlogfname)));
8797 }
8798
8800
8802 start, 1, 0);
8803}
#define _(x)
Definition: elog.c:91
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:438
int pg_fdatasync(int fd)
Definition: fd.c:477
int pg_fsync_writethrough(int fd)
Definition: fd.c:458
bool enableFsync
Definition: globals.c:129
return str start
@ IOOBJECT_WAL
Definition: pgstat.h:277
@ IOCONTEXT_NORMAL
Definition: pgstat.h:287
@ IOOP_FSYNC
Definition: pgstat.h:306
instr_time pgstat_prepare_io_time(bool track_io_guc)
Definition: pgstat_io.c:91
void pgstat_count_io_op_time(IOObject io_object, IOContext io_context, IOOp io_op, instr_time start_time, uint32 cnt, uint64 bytes)
Definition: pgstat_io.c:122
static int fd(const char *x, int i)
Definition: preproc-init.c:105
int wal_sync_method
Definition: xlog.c:131
bool track_wal_io_timing
Definition: xlog.c:138

References _, Assert(), enableFsync, ereport, errcode(), errcode_for_file_access(), errmsg(), errmsg_internal(), fd(), IOCONTEXT_NORMAL, IOOBJECT_WAL, IOOP_FSYNC, MAXFNAMELEN, PANIC, pg_fdatasync(), pg_fsync_no_writethrough(), pg_fsync_writethrough(), pgstat_count_io_op_time(), pgstat_prepare_io_time(), pgstat_report_wait_end(), pgstat_report_wait_start(), start, track_wal_io_timing, wal_segment_size, 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, and XLogFileName().

Referenced by XLogWalRcvFlush(), and XLogWrite().

◆ LocalProcessControlFile()

void LocalProcessControlFile ( bool  reset)

Definition at line 4885 of file xlog.c.

4886{
4887 Assert(reset || ControlFile == NULL);
4890}
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 6296 of file xlog.c.

6297{
6298 /*
6299 * We have reached the end of base backup, as indicated by pg_control. The
6300 * data on disk is now consistent (unless minRecoveryPoint is further
6301 * ahead, which can happen if we crashed during previous recovery). Reset
6302 * backupStartPoint and backupEndPoint, and update minRecoveryPoint to
6303 * make sure we don't allow starting up at an earlier point even if
6304 * recovery is stopped and restarted soon after this.
6305 */
6306 LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6307
6308 if (ControlFile->minRecoveryPoint < EndRecPtr)
6309 {
6310 ControlFile->minRecoveryPoint = EndRecPtr;
6312 }
6313
6318
6319 LWLockRelease(ControlFileLock);
6320}
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 6383 of file xlog.c.

6384{
6385 /*
6386 * We check shared state each time only until we leave recovery mode. We
6387 * can't re-enter recovery, so there's no need to keep checking after the
6388 * shared variable has once been seen false.
6389 */
6391 return false;
6392 else
6393 {
6394 /*
6395 * use volatile pointer to make sure we make a fresh read of the
6396 * shared variable.
6397 */
6398 volatile XLogCtlData *xlogctl = XLogCtl;
6399
6401
6402 /*
6403 * Note: We don't need a memory barrier when we're still in recovery.
6404 * We might exit recovery immediately after return, so the caller
6405 * can't rely on 'true' meaning that we're still in recovery anyway.
6406 */
6407
6409 }
6410}
static bool LocalRecoveryInProgress
Definition: xlog.c:225

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

Referenced by amcheck_index_mainfork_expected(), attribute_statistics_update(), BackgroundWriterMain(), BeginReportingGUCOptions(), brin_desummarize_range(), brin_summarize_range(), CanInvalidateIdleSlot(), 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(), ExecCheckpoint(), 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(), InitWalSender(), IsCheckpointOnSchedule(), LockAcquireExtended(), logical_read_xlog_page(), MaintainLatestCompletedXid(), MarkBufferDirtyHint(), perform_base_backup(), pg_clear_attribute_stats(), pg_create_restore_point(), pg_current_wal_flush_lsn(), pg_current_wal_insert_lsn(), pg_current_wal_lsn(), pg_get_sequence_data(), 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(), PrepareRedoRemoveFull(), PreventCommandDuringRecovery(), ProcessStandbyPSRequestMessage(), ProcSleep(), read_local_xlog_page_guts(), ReadReplicationSlot(), recovery_create_dbdir(), relation_statistics_update(), ReplicationSlotAlter(), ReplicationSlotCreate(), ReplicationSlotDrop(), ReplicationSlotReserveWal(), replorigin_check_prerequisites(), ReportChangedGUCOptions(), sendDir(), SerialSetActiveSerXmin(), show_in_hot_standby(), ShutdownXLOG(), SnapBuildWaitSnapshot(), StandbySlotsHaveCaughtup(), StartLogicalReplication(), StartReplication(), StartTransaction(), TransactionIdIsInProgress(), TruncateMultiXact(), UpdateFullPageWrites(), verify_heapam(), WALReadFromBuffers(), WalReceiverMain(), WalSndWaitForWal(), xlog_decode(), XLogBackgroundFlush(), XLogFlush(), XLogInsertAllowed(), and XLogSendPhysical().

◆ register_persistent_abort_backup_handler()

void register_persistent_abort_backup_handler ( void  )

Definition at line 9462 of file xlog.c.

9463{
9464 static bool already_done = false;
9465
9466 if (already_done)
9467 return;
9469 already_done = true;
9470}
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:337

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

Referenced by pg_backup_start().

◆ RemoveNonParentXlogFiles()

void RemoveNonParentXlogFiles ( XLogRecPtr  switchpoint,
TimeLineID  newTLI 
)

Definition at line 3953 of file xlog.c.

3954{
3955 DIR *xldir;
3956 struct dirent *xlde;
3957 char switchseg[MAXFNAMELEN];
3958 XLogSegNo endLogSegNo;
3959 XLogSegNo switchLogSegNo;
3960 XLogSegNo recycleSegNo;
3961
3962 /*
3963 * Initialize info about where to begin the work. This will recycle,
3964 * somewhat arbitrarily, 10 future segments.
3965 */
3966 XLByteToPrevSeg(switchpoint, switchLogSegNo, wal_segment_size);
3967 XLByteToSeg(switchpoint, endLogSegNo, wal_segment_size);
3968 recycleSegNo = endLogSegNo + 10;
3969
3970 /*
3971 * Construct a filename of the last segment to be kept.
3972 */
3973 XLogFileName(switchseg, newTLI, switchLogSegNo, wal_segment_size);
3974
3975 elog(DEBUG2, "attempting to remove WAL segments newer than log file %s",
3976 switchseg);
3977
3978 xldir = AllocateDir(XLOGDIR);
3979
3980 while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
3981 {
3982 /* Ignore files that are not XLOG segments */
3983 if (!IsXLogFileName(xlde->d_name))
3984 continue;
3985
3986 /*
3987 * Remove files that are on a timeline older than the new one we're
3988 * switching to, but with a segment number >= the first segment on the
3989 * new timeline.
3990 */
3991 if (strncmp(xlde->d_name, switchseg, 8) < 0 &&
3992 strcmp(xlde->d_name + 8, switchseg + 8) > 0)
3993 {
3994 /*
3995 * If the file has already been marked as .ready, however, don't
3996 * remove it yet. It should be OK to remove it - files that are
3997 * not part of our timeline history are not required for recovery
3998 * - but seems safer to let them be archived and removed later.
3999 */
4000 if (!XLogArchiveIsReady(xlde->d_name))
4001 RemoveXlogFile(xlde, recycleSegNo, &endLogSegNo, newTLI);
4002 }
4003 }
4004
4005 FreeDir(xldir);
4006}
static void RemoveXlogFile(const struct dirent *segment_de, XLogSegNo recycleSegNo, XLogSegNo *endlogSegNo, TimeLineID insertTLI)
Definition: xlog.c:4022
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 9525 of file xlog.c.

9526{
9527 LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9529 LWLockRelease(ControlFileLock);
9530}

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

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

◆ SetWalWriterSleeping()

void SetWalWriterSleeping ( bool  sleeping)

Definition at line 9548 of file xlog.c.

9549{
9551 XLogCtl->WalWriterSleeping = sleeping;
9553}
bool WalWriterSleeping
Definition: xlog.c:533

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

Referenced by WalWriterMain().

◆ ShutdownXLOG()

void ShutdownXLOG ( int  code,
Datum  arg 
)

Definition at line 6651 of file xlog.c.

6652{
6653 /*
6654 * We should have an aux process resource owner to use, and we should not
6655 * be in a transaction that's installed some other resowner.
6656 */
6658 Assert(CurrentResourceOwner == NULL ||
6661
6662 /* Don't be chatty in standalone mode */
6664 (errmsg("shutting down")));
6665
6666 /*
6667 * Signal walsenders to move to stopping state.
6668 */
6670
6671 /*
6672 * Wait for WAL senders to be in stopping state. This prevents commands
6673 * from writing new WAL.
6674 */
6676
6677 if (RecoveryInProgress())
6679 else
6680 {
6681 /*
6682 * If archiving is enabled, rotate the last XLOG file so that all the
6683 * remaining records are archived (postmaster wakes up the archiver
6684 * process one more time at the end of shutdown). The checkpoint
6685 * record will go to the next XLOG file and won't be archived (yet).
6686 */
6687 if (XLogArchivingActive())
6688 RequestXLogSwitch(false);
6689
6691 }
6692}
bool IsPostmasterEnvironment
Definition: globals.c:119
ResourceOwner CurrentResourceOwner
Definition: resowner.c:173
ResourceOwner AuxProcessResourceOwner
Definition: resowner.c:176
void WalSndInitStopping(void)
Definition: walsender.c:3858
void WalSndWaitStopping(void)
Definition: walsender.c:3884
bool CreateRestartPoint(int flags)
Definition: xlog.c:7636
bool CreateCheckPoint(int flags)
Definition: xlog.c:6938

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

Referenced by CheckpointerMain(), and InitPostgres().

◆ StartupXLOG()

void StartupXLOG ( void  )

Definition at line 5466 of file xlog.c.

5467{
5469 CheckPoint checkPoint;
5470 bool wasShutdown;
5471 bool didCrash;
5472 bool haveTblspcMap;
5473 bool haveBackupLabel;
5474 XLogRecPtr EndOfLog;
5475 TimeLineID EndOfLogTLI;
5476 TimeLineID newTLI;
5477 bool performedWalRecovery;
5478 EndOfWalRecoveryInfo *endOfRecoveryInfo;
5481 TransactionId oldestActiveXID;
5482 bool promoted = false;
5483 char timebuf[128];
5484
5485 /*
5486 * We should have an aux process resource owner to use, and we should not
5487 * be in a transaction that's installed some other resowner.
5488 */
5490 Assert(CurrentResourceOwner == NULL ||
5493
5494 /*
5495 * Check that contents look valid.
5496 */
5498 ereport(FATAL,
5500 errmsg("control file contains invalid checkpoint location")));
5501
5502 switch (ControlFile->state)
5503 {
5504 case DB_SHUTDOWNED:
5505
5506 /*
5507 * This is the expected case, so don't be chatty in standalone
5508 * mode
5509 */
5511 (errmsg("database system was shut down at %s",
5513 timebuf, sizeof(timebuf)))));
5514 break;
5515
5517 ereport(LOG,
5518 (errmsg("database system was shut down in recovery at %s",
5520 timebuf, sizeof(timebuf)))));
5521 break;
5522
5523 case DB_SHUTDOWNING:
5524 ereport(LOG,
5525 (errmsg("database system shutdown was interrupted; last known up at %s",
5527 timebuf, sizeof(timebuf)))));
5528 break;
5529
5531 ereport(LOG,
5532 (errmsg("database system was interrupted while in recovery at %s",
5534 timebuf, sizeof(timebuf))),
5535 errhint("This probably means that some data is corrupted and"
5536 " you will have to use the last backup for recovery.")));
5537 break;
5538
5540 ereport(LOG,
5541 (errmsg("database system was interrupted while in recovery at log time %s",
5543 timebuf, sizeof(timebuf))),
5544 errhint("If this has occurred more than once some data might be corrupted"
5545 " and you might need to choose an earlier recovery target.")));
5546 break;
5547
5548 case DB_IN_PRODUCTION:
5549 ereport(LOG,
5550 (errmsg("database system was interrupted; last known up at %s",
5552 timebuf, sizeof(timebuf)))));
5553 break;
5554
5555 default:
5556 ereport(FATAL,
5558 errmsg("control file contains invalid database cluster state")));
5559 }
5560
5561 /* This is just to allow attaching to startup process with a debugger */
5562#ifdef XLOG_REPLAY_DELAY
5564 pg_usleep(60000000L);
5565#endif
5566
5567 /*
5568 * Verify that pg_wal, pg_wal/archive_status, and pg_wal/summaries exist.
5569 * In cases where someone has performed a copy for PITR, these directories
5570 * may have been excluded and need to be re-created.
5571 */
5573
5574 /* Set up timeout handler needed to report startup progress. */
5578
5579 /*----------
5580 * If we previously crashed, perform a couple of actions:
5581 *
5582 * - The pg_wal directory may still include some temporary WAL segments
5583 * used when creating a new segment, so perform some clean up to not
5584 * bloat this path. This is done first as there is no point to sync
5585 * this temporary data.
5586 *
5587 * - There might be data which we had written, intending to fsync it, but
5588 * which we had not actually fsync'd yet. Therefore, a power failure in
5589 * the near future might cause earlier unflushed writes to be lost, even
5590 * though more recent data written to disk from here on would be
5591 * persisted. To avoid that, fsync the entire data directory.
5592 */
5595 {
5598 didCrash = true;
5599 }
5600 else
5601 didCrash = false;
5602
5603 /*
5604 * Prepare for WAL recovery if needed.
5605 *
5606 * InitWalRecovery analyzes the control file and the backup label file, if
5607 * any. It updates the in-memory ControlFile buffer according to the
5608 * starting checkpoint, and sets InRecovery and ArchiveRecoveryRequested.
5609 * It also applies the tablespace map file, if any.
5610 */
5611 InitWalRecovery(ControlFile, &wasShutdown,
5612 &haveBackupLabel, &haveTblspcMap);
5613 checkPoint = ControlFile->checkPointCopy;
5614
5615 /* initialize shared memory variables from the checkpoint record */
5616 TransamVariables->nextXid = checkPoint.nextXid;
5617 TransamVariables->nextOid = checkPoint.nextOid;
5619 MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5620 AdvanceOldestClogXid(checkPoint.oldestXid);
5621 SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5622 SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5624 checkPoint.newestCommitTsXid);
5625
5626 /*
5627 * Clear out any old relcache cache files. This is *necessary* if we do
5628 * any WAL replay, since that would probably result in the cache files
5629 * being out of sync with database reality. In theory we could leave them
5630 * in place if the database had been cleanly shut down, but it seems
5631 * safest to just remove them always and let them be rebuilt during the
5632 * first backend startup. These files needs to be removed from all
5633 * directories including pg_tblspc, however the symlinks are created only
5634 * after reading tablespace_map file in case of archive recovery from
5635 * backup, so needs to clear old relcache files here after creating
5636 * symlinks.
5637 */
5639
5640 /*
5641 * Initialize replication slots, before there's a chance to remove
5642 * required resources.
5643 */
5645
5646 /*
5647 * Startup logical state, needs to be setup now so we have proper data
5648 * during crash recovery.
5649 */
5651
5652 /*
5653 * Startup CLOG. This must be done after TransamVariables->nextXid has
5654 * been initialized and before we accept connections or begin WAL replay.
5655 */
5656 StartupCLOG();
5657
5658 /*
5659 * Startup MultiXact. We need to do this early to be able to replay
5660 * truncations.
5661 */
5663
5664 /*
5665 * Ditto for commit timestamps. Activate the facility if the setting is
5666 * enabled in the control file, as there should be no tracking of commit
5667 * timestamps done when the setting was disabled. This facility can be
5668 * started or stopped when replaying a XLOG_PARAMETER_CHANGE record.
5669 */
5672
5673 /*
5674 * Recover knowledge about replay progress of known replication partners.
5675 */
5677
5678 /*
5679 * Initialize unlogged LSN. On a clean shutdown, it's restored from the
5680 * control file. On recovery, all unlogged relations are blown away, so
5681 * the unlogged LSN counter can be reset too.
5682 */
5686 else
5689
5690 /*
5691 * Copy any missing timeline history files between 'now' and the recovery
5692 * target timeline from archive to pg_wal. While we don't need those files
5693 * ourselves - the history file of the recovery target timeline covers all
5694 * the previous timelines in the history too - a cascading standby server
5695 * might be interested in them. Or, if you archive the WAL from this
5696 * server to a different archive than the primary, it'd be good for all
5697 * the history files to get archived there after failover, so that you can
5698 * use one of the old timelines as a PITR target. Timeline history files
5699 * are small, so it's better to copy them unnecessarily than not copy them
5700 * and regret later.
5701 */
5703
5704 /*
5705 * Before running in recovery, scan pg_twophase and fill in its status to
5706 * be able to work on entries generated by redo. Doing a scan before
5707 * taking any recovery action has the merit to discard any 2PC files that
5708 * are newer than the first record to replay, saving from any conflicts at
5709 * replay. This avoids as well any subsequent scans when doing recovery
5710 * of the on-disk two-phase data.
5711 */
5713
5714 /*
5715 * When starting with crash recovery, reset pgstat data - it might not be
5716 * valid. Otherwise restore pgstat data. It's safe to do this here,
5717 * because postmaster will not yet have started any other processes.
5718 *
5719 * NB: Restoring replication slot stats relies on slot state to have
5720 * already been restored from disk.
5721 *
5722 * TODO: With a bit of extra work we could just start with a pgstat file
5723 * associated with the checkpoint redo location we're starting from.
5724 */
5725 if (didCrash)
5727 else
5729
5731
5734
5735 /* REDO */
5736 if (InRecovery)
5737 {
5738 /* Initialize state for RecoveryInProgress() */
5742 else
5745
5746 /*
5747 * Update pg_control to show that we are recovering and to show the
5748 * selected checkpoint as the place we are starting from. We also mark
5749 * pg_control with any minimum recovery stop point obtained from a
5750 * backup history file.
5751 *
5752 * No need to hold ControlFileLock yet, we aren't up far enough.
5753 */
5755
5756 /*
5757 * If there was a backup label file, it's done its job and the info
5758 * has now been propagated into pg_control. We must get rid of the
5759 * label file so that if we crash during recovery, we'll pick up at
5760 * the latest recovery restartpoint instead of going all the way back
5761 * to the backup start point. It seems prudent though to just rename
5762 * the file out of the way rather than delete it completely.
5763 */
5764 if (haveBackupLabel)
5765 {
5766 unlink(BACKUP_LABEL_OLD);
5768 }
5769
5770 /*
5771 * If there was a tablespace_map file, it's done its job and the
5772 * symlinks have been created. We must get rid of the map file so
5773 * that if we crash during recovery, we don't create symlinks again.
5774 * It seems prudent though to just rename the file out of the way
5775 * rather than delete it completely.
5776 */
5777 if (haveTblspcMap)
5778 {
5779 unlink(TABLESPACE_MAP_OLD);
5781 }
5782
5783 /*
5784 * Initialize our local copy of minRecoveryPoint. When doing crash
5785 * recovery we want to replay up to the end of WAL. Particularly, in
5786 * the case of a promoted standby minRecoveryPoint value in the
5787 * control file is only updated after the first checkpoint. However,
5788 * if the instance crashes before the first post-recovery checkpoint
5789 * is completed then recovery will use a stale location causing the
5790 * startup process to think that there are still invalid page
5791 * references when checking for data consistency.
5792 */
5794 {
5797 }
5798 else
5799 {
5802 }
5803
5804 /* Check that the GUCs used to generate the WAL allow recovery */
5806
5807 /*
5808 * We're in recovery, so unlogged relations may be trashed and must be
5809 * reset. This should be done BEFORE allowing Hot Standby
5810 * connections, so that read-only backends don't try to read whatever
5811 * garbage is left over from before.
5812 */
5814
5815 /*
5816 * Likewise, delete any saved transaction snapshot files that got left
5817 * behind by crashed backends.
5818 */
5820
5821 /*
5822 * Initialize for Hot Standby, if enabled. We won't let backends in
5823 * yet, not until we've reached the min recovery point specified in
5824 * control file and we've established a recovery snapshot from a
5825 * running-xacts WAL record.
5826 */
5828 {
5829 TransactionId *xids;
5830 int nxids;
5831
5833 (errmsg_internal("initializing for hot standby")));
5834
5836
5837 if (wasShutdown)
5838 oldestActiveXID = PrescanPreparedTransactions(&xids, &nxids);
5839 else
5840 oldestActiveXID = checkPoint.oldestActiveXid;
5841 Assert(TransactionIdIsValid(oldestActiveXID));
5842
5843 /* Tell procarray about the range of xids it has to deal with */
5845
5846 /*
5847 * Startup subtrans only. CLOG, MultiXact and commit timestamp
5848 * have already been started up and other SLRUs are not maintained
5849 * during recovery and need not be started yet.
5850 */
5851 StartupSUBTRANS(oldestActiveXID);
5852
5853 /*
5854 * If we're beginning at a shutdown checkpoint, we know that
5855 * nothing was running on the primary at this point. So fake-up an
5856 * empty running-xacts record and use that here and now. Recover
5857 * additional standby state for prepared transactions.
5858 */
5859 if (wasShutdown)
5860 {
5862 TransactionId latestCompletedXid;
5863
5864 /* Update pg_subtrans entries for any prepared transactions */
5866
5867 /*
5868 * Construct a RunningTransactions snapshot representing a
5869 * shut down server, with only prepared transactions still
5870 * alive. We're never overflowed at this point because all
5871 * subxids are listed with their parent prepared transactions.
5872 */
5873 running.xcnt = nxids;
5874 running.subxcnt = 0;
5876 running.nextXid = XidFromFullTransactionId(checkPoint.nextXid);
5877 running.oldestRunningXid = oldestActiveXID;
5878 latestCompletedXid = XidFromFullTransactionId(checkPoint.nextXid);
5879 TransactionIdRetreat(latestCompletedXid);
5880 Assert(TransactionIdIsNormal(latestCompletedXid));
5881 running.latestCompletedXid = latestCompletedXid;
5882 running.xids = xids;
5883
5885 }
5886 }
5887
5888 /*
5889 * We're all set for replaying the WAL now. Do it.
5890 */
5892 performedWalRecovery = true;
5893 }
5894 else
5895 performedWalRecovery = false;
5896
5897 /*
5898 * Finish WAL recovery.
5899 */
5900 endOfRecoveryInfo = FinishWalRecovery();
5901 EndOfLog = endOfRecoveryInfo->endOfLog;
5902 EndOfLogTLI = endOfRecoveryInfo->endOfLogTLI;
5903 abortedRecPtr = endOfRecoveryInfo->abortedRecPtr;
5904 missingContrecPtr = endOfRecoveryInfo->missingContrecPtr;
5905
5906 /*
5907 * Reset ps status display, so as no information related to recovery shows
5908 * up.
5909 */
5910 set_ps_display("");
5911
5912 /*
5913 * When recovering from a backup (we are in recovery, and archive recovery
5914 * was requested), complain if we did not roll forward far enough to reach
5915 * the point where the database is consistent. For regular online
5916 * backup-from-primary, that means reaching the end-of-backup WAL record
5917 * (at which point we reset backupStartPoint to be Invalid), for
5918 * backup-from-replica (which can't inject records into the WAL stream),
5919 * that point is when we reach the minRecoveryPoint in pg_control (which
5920 * we purposefully copy last when backing up from a replica). For
5921 * pg_rewind (which creates a backup_label with a method of "pg_rewind")
5922 * or snapshot-style backups (which don't), backupEndRequired will be set
5923 * to false.
5924 *
5925 * Note: it is indeed okay to look at the local variable
5926 * LocalMinRecoveryPoint here, even though ControlFile->minRecoveryPoint
5927 * might be further ahead --- ControlFile->minRecoveryPoint cannot have
5928 * been advanced beyond the WAL we processed.
5929 */
5930 if (InRecovery &&
5931 (EndOfLog < LocalMinRecoveryPoint ||
5933 {
5934 /*
5935 * Ran off end of WAL before reaching end-of-backup WAL record, or
5936 * minRecoveryPoint. That's a bad sign, indicating that you tried to
5937 * recover from an online backup but never called pg_backup_stop(), or
5938 * you didn't archive all the WAL needed.
5939 */
5941 {
5943 ereport(FATAL,
5944 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
5945 errmsg("WAL ends before end of online backup"),
5946 errhint("All WAL generated while online backup was taken must be available at recovery.")));
5947 else
5948 ereport(FATAL,
5949 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
5950 errmsg("WAL ends before consistent recovery point")));
5951 }
5952 }
5953
5954 /*
5955 * Reset unlogged relations to the contents of their INIT fork. This is
5956 * done AFTER recovery is complete so as to include any unlogged relations
5957 * created during recovery, but BEFORE recovery is marked as having
5958 * completed successfully. Otherwise we'd not retry if any of the post
5959 * end-of-recovery steps fail.
5960 */
5961 if (InRecovery)
5963
5964 /*
5965 * Pre-scan prepared transactions to find out the range of XIDs present.
5966 * This information is not quite needed yet, but it is positioned here so
5967 * as potential problems are detected before any on-disk change is done.
5968 */
5969 oldestActiveXID = PrescanPreparedTransactions(NULL, NULL);
5970
5971 /*
5972 * Allow ordinary WAL segment creation before possibly switching to a new
5973 * timeline, which creates a new segment, and after the last ReadRecord().
5974 */
5976
5977 /*
5978 * Consider whether we need to assign a new timeline ID.
5979 *
5980 * If we did archive recovery, we always assign a new ID. This handles a
5981 * couple of issues. If we stopped short of the end of WAL during
5982 * recovery, then we are clearly generating a new timeline and must assign
5983 * it a unique new ID. Even if we ran to the end, modifying the current
5984 * last segment is problematic because it may result in trying to
5985 * overwrite an already-archived copy of that segment, and we encourage
5986 * DBAs to make their archive_commands reject that. We can dodge the
5987 * problem by making the new active segment have a new timeline ID.
5988 *
5989 * In a normal crash recovery, we can just extend the timeline we were in.
5990 */
5991 newTLI = endOfRecoveryInfo->lastRecTLI;
5993 {
5995 ereport(LOG,
5996 (errmsg("selected new timeline ID: %u", newTLI)));
5997
5998 /*
5999 * Make a writable copy of the last WAL segment. (Note that we also
6000 * have a copy of the last block of the old WAL in
6001 * endOfRecovery->lastPage; we will use that below.)
6002 */
6003 XLogInitNewTimeline(EndOfLogTLI, EndOfLog, newTLI);
6004
6005 /*
6006 * Remove the signal files out of the way, so that we don't
6007 * accidentally re-enter archive recovery mode in a subsequent crash.
6008 */
6009 if (endOfRecoveryInfo->standby_signal_file_found)
6011
6012 if (endOfRecoveryInfo->recovery_signal_file_found)
6014
6015 /*
6016 * Write the timeline history file, and have it archived. After this
6017 * point (or rather, as soon as the file is archived), the timeline
6018 * will appear as "taken" in the WAL archive and to any standby
6019 * servers. If we crash before actually switching to the new
6020 * timeline, standby servers will nevertheless think that we switched
6021 * to the new timeline, and will try to connect to the new timeline.
6022 * To minimize the window for that, try to do as little as possible
6023 * between here and writing the end-of-recovery record.
6024 */
6026 EndOfLog, endOfRecoveryInfo->recoveryStopReason);
6027
6028 ereport(LOG,
6029 (errmsg("archive recovery complete")));
6030 }
6031
6032 /* Save the selected TimeLineID in shared memory, too */
6034 XLogCtl->InsertTimeLineID = newTLI;
6035 XLogCtl->PrevTimeLineID = endOfRecoveryInfo->lastRecTLI;
6037
6038 /*
6039 * Actually, if WAL ended in an incomplete record, skip the parts that
6040 * made it through and start writing after the portion that persisted.
6041 * (It's critical to first write an OVERWRITE_CONTRECORD message, which
6042 * we'll do as soon as we're open for writing new WAL.)
6043 */
6045 {
6046 /*
6047 * We should only have a missingContrecPtr if we're not switching to a
6048 * new timeline. When a timeline switch occurs, WAL is copied from the
6049 * old timeline to the new only up to the end of the last complete
6050 * record, so there can't be an incomplete WAL record that we need to
6051 * disregard.
6052 */
6053 Assert(newTLI == endOfRecoveryInfo->lastRecTLI);
6055 EndOfLog = missingContrecPtr;
6056 }
6057
6058 /*
6059 * Prepare to write WAL starting at EndOfLog location, and init xlog
6060 * buffer cache using the block containing the last record from the
6061 * previous incarnation.
6062 */
6063 Insert = &XLogCtl->Insert;
6064 Insert->PrevBytePos = XLogRecPtrToBytePos(endOfRecoveryInfo->lastRec);
6065 Insert->CurrBytePos = XLogRecPtrToBytePos(EndOfLog);
6066
6067 /*
6068 * Tricky point here: lastPage contains the *last* block that the LastRec
6069 * record spans, not the one it starts in. The last block is indeed the
6070 * one we want to use.
6071 */
6072 if (EndOfLog % XLOG_BLCKSZ != 0)
6073 {
6074 char *page;
6075 int len;
6076 int firstIdx;
6077
6078 firstIdx = XLogRecPtrToBufIdx(EndOfLog);
6079 len = EndOfLog - endOfRecoveryInfo->lastPageBeginPtr;
6080 Assert(len < XLOG_BLCKSZ);
6081
6082 /* Copy the valid part of the last block, and zero the rest */
6083 page = &XLogCtl->pages[firstIdx * XLOG_BLCKSZ];
6084 memcpy(page, endOfRecoveryInfo->lastPage, len);
6085 memset(page + len, 0, XLOG_BLCKSZ - len);
6086
6087 pg_atomic_write_u64(&XLogCtl->xlblocks[firstIdx], endOfRecoveryInfo->lastPageBeginPtr + XLOG_BLCKSZ);
6088 XLogCtl->InitializedUpTo = endOfRecoveryInfo->lastPageBeginPtr + XLOG_BLCKSZ;
6089 }
6090 else
6091 {
6092 /*
6093 * There is no partial block to copy. Just set InitializedUpTo, and
6094 * let the first attempt to insert a log record to initialize the next
6095 * buffer.
6096 */
6097 XLogCtl->InitializedUpTo = EndOfLog;
6098 }
6099
6100 /*
6101 * Update local and shared status. This is OK to do without any locks
6102 * because no other process can be reading or writing WAL yet.
6103 */
6104 LogwrtResult.Write = LogwrtResult.Flush = EndOfLog;
6108 XLogCtl->LogwrtRqst.Write = EndOfLog;
6109 XLogCtl->LogwrtRqst.Flush = EndOfLog;
6110
6111 /*
6112 * Preallocate additional log files, if wanted.
6113 */
6114 PreallocXlogFiles(EndOfLog, newTLI);
6115
6116 /*
6117 * Okay, we're officially UP.
6118 */
6119 InRecovery = false;
6120
6121 /* start the archive_timeout timer and LSN running */
6122 XLogCtl->lastSegSwitchTime = (pg_time_t) time(NULL);
6123 XLogCtl->lastSegSwitchLSN = EndOfLog;
6124
6125 /* also initialize latestCompletedXid, to nextXid - 1 */
6126 LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
6129 LWLockRelease(ProcArrayLock);
6130
6131 /*
6132 * Start up subtrans, if not already done for hot standby. (commit
6133 * timestamps are started below, if necessary.)
6134 */
6136 StartupSUBTRANS(oldestActiveXID);
6137
6138 /*
6139 * Perform end of recovery actions for any SLRUs that need it.
6140 */
6141 TrimCLOG();
6142 TrimMultiXact();
6143
6144 /*
6145 * Reload shared-memory state for prepared transactions. This needs to
6146 * happen before renaming the last partial segment of the old timeline as
6147 * it may be possible that we have to recover some transactions from it.
6148 */
6150
6151 /* Shut down xlogreader */
6153
6154 /* Enable WAL writes for this backend only. */
6156
6157 /* If necessary, write overwrite-contrecord before doing anything else */
6159 {
6162 }
6163
6164 /*
6165 * Update full_page_writes in shared memory and write an XLOG_FPW_CHANGE
6166 * record before resource manager writes cleanup WAL records or checkpoint
6167 * record is written.
6168 */
6169 Insert->fullPageWrites = lastFullPageWrites;
6171
6172 /*
6173 * Emit checkpoint or end-of-recovery record in XLOG, if required.
6174 */
6175 if (performedWalRecovery)
6176 promoted = PerformRecoveryXLogAction();
6177
6178 /*
6179 * If any of the critical GUCs have changed, log them before we allow
6180 * backends to write WAL.
6181 */
6183
6184 /* If this is archive recovery, perform post-recovery cleanup actions. */
6186 CleanupAfterArchiveRecovery(EndOfLogTLI, EndOfLog, newTLI);
6187
6188 /*
6189 * Local WAL inserts enabled, so it's time to finish initialization of
6190 * commit timestamp.
6191 */
6193
6194 /* Clean up EndOfWalRecoveryInfo data to appease Valgrind leak checking */
6195 if (endOfRecoveryInfo->lastPage)
6196 pfree(endOfRecoveryInfo->lastPage);
6197 pfree(endOfRecoveryInfo->recoveryStopReason);
6198 pfree(endOfRecoveryInfo);
6199
6200 /*
6201 * All done with end-of-recovery actions.
6202 *
6203 * Now allow backends to write WAL and update the control file status in
6204 * consequence. SharedRecoveryState, that controls if backends can write
6205 * WAL, is updated while holding ControlFileLock to prevent other backends
6206 * to look at an inconsistent state of the control file in shared memory.
6207 * There is still a small window during which backends can write WAL and
6208 * the control file is still referring to a system not in DB_IN_PRODUCTION
6209 * state while looking at the on-disk control file.
6210 *
6211 * Also, we use info_lck to update SharedRecoveryState to ensure that
6212 * there are no race conditions concerning visibility of other recent
6213 * updates to shared memory.
6214 */
6215 LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6217
6221
6223 LWLockRelease(ControlFileLock);
6224
6225 /*
6226 * Shutdown the recovery environment. This must occur after
6227 * RecoverPreparedTransactions() (see notes in lock_twophase_recover())
6228 * and after switching SharedRecoveryState to RECOVERY_STATE_DONE so as
6229 * any session building a snapshot will not rely on KnownAssignedXids as
6230 * RecoveryInProgress() would return false at this stage. This is
6231 * particularly critical for prepared 2PC transactions, that would still
6232 * need to be included in snapshots once recovery has ended.
6233 */
6236
6237 /*
6238 * If there were cascading standby servers connected to us, nudge any wal
6239 * sender processes to notice that we've been promoted.
6240 */
6241 WalSndWakeup(true, true);
6242
6243 /*
6244 * If this was a promotion, request an (online) checkpoint now. This isn't
6245 * required for consistency, but the last restartpoint might be far back,
6246 * and in case of a crash, recovering from it might take a longer than is
6247 * appropriate now that we're not in standby mode anymore.
6248 */
6249 if (promoted)
6251}
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:483
static void pg_atomic_write_membarrier_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:492
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:658
void StartupCLOG(void)
Definition: clog.c:842
void TrimCLOG(void)
Definition: clog.c:857
void StartupCommitTs(void)
Definition: commit_ts.c:608
void CompleteCommitTsInitialization(void)
Definition: commit_ts.c:618
#define FATAL
Definition: elog.h:41
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:779
int durable_unlink(const char *fname, int elevel)
Definition: fd.c:869
void SyncDataDirectory(void)
Definition: fd.c:3606
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:476
void TrimMultiXact(void)
Definition: multixact.c:2108
void StartupMultiXact(void)
Definition: multixact.c:2083
void StartupReplicationOrigin(void)
Definition: origin.c:722
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:42
@ 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:505
void pgstat_discard_stats(void)
Definition: pgstat.c:517
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:6900
void StartupReorderBuffer(void)
void StartupReplicationSlots(void)
Definition: slot.c:2187
void DeleteAllExportedSnapshotFiles(void)
Definition: snapmgr.c:1585
void InitRecoveryTransactionEnvironment(void)
Definition: standby.c:95
void ShutdownRecoveryTransactionEnvironment(void)
Definition: standby.c:161
@ SUBXIDS_IN_SUBTRANS
Definition: standby.h:82
bool track_commit_timestamp
Definition: pg_control.h:185
XLogRecPtr lastPageBeginPtr
Definition: xlogrecovery.h:121
XLogRecPtr abortedRecPtr
Definition: xlogrecovery.h:130
XLogRecPtr missingContrecPtr
Definition: xlogrecovery.h:131
TimeLineID endOfLogTLI
Definition: xlogrecovery.h:119
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:485
char * pages
Definition: xlog.c:492
pg_time_t lastSegSwitchTime
Definition: xlog.c:467
XLogRecPtr lastSegSwitchLSN
Definition: xlog.c:468
pg_atomic_uint64 * xlblocks
Definition: xlog.c:493
pg_atomic_uint64 logWriteResult
Definition: xlog.c:472
pg_atomic_uint64 logFlushResult
Definition: xlog.c:473
pg_atomic_uint64 logInsertResult
Definition: xlog.c:471
XLogRecPtr Flush
Definition: xlog.c:323
void StartupSUBTRANS(TransactionId oldestActiveXID)
Definition: subtrans.c:283
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:1904
TransactionId PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p)
Definition: twophase.c:1966
void StandbyRecoverPreparedTransactions(void)
Definition: twophase.c:2045
void WalSndWakeup(bool physical, bool logical)
Definition: walsender.c:3779
void UpdateFullPageWrites(void)
Definition: xlog.c:8213
static void ValidateXLOGDirectoryStructure(void)
Definition: xlog.c:4112
static XLogRecPtr CreateOverwriteContrecordRecord(XLogRecPtr aborted_lsn, XLogRecPtr pagePtr, TimeLineID newTLI)
Definition: xlog.c:7486
static void XLogReportParameters(void)
Definition: xlog.c:8150
static bool PerformRecoveryXLogAction(void)
Definition: xlog.c:6333
static void CleanupAfterArchiveRecovery(TimeLineID EndOfLogTLI, XLogRecPtr EndOfLog, TimeLineID newTLI)
Definition: xlog.c:5326
static bool lastFullPageWrites
Definition: xlog.c:218
static uint64 XLogRecPtrToBytePos(XLogRecPtr ptr)
Definition: xlog.c:1944
static void XLogInitNewTimeline(TimeLineID endTLI, XLogRecPtr endOfLog, TimeLineID newTLI)
Definition: xlog.c:5251
static void CheckRequiredParameterValues(void)
Definition: xlog.c:5422
#define XLogRecPtrToBufIdx(recptr)
Definition: xlog.c:591
static void RemoveTempXlogFiles(void)
Definition: xlog.c:3845
static char * str_time(pg_time_t tnow, char *buf, size_t bufsize)
Definition: xlog.c:5238
#define TABLESPACE_MAP_OLD
Definition: xlog.h:307
#define TABLESPACE_MAP
Definition: xlog.h:306
#define STANDBY_SIGNAL_FILE
Definition: xlog.h:302
#define BACKUP_LABEL_OLD
Definition: xlog.h:304
#define BACKUP_LABEL_FILE
Definition: xlog.h:303
#define RECOVERY_SIGNAL_FILE
Definition: xlog.h:301
#define XRecOffIsValid(xlrp)
#define FirstNormalUnloggedLSN
Definition: xlogdefs.h:36
void ShutdownWalRecovery(void)
bool ArchiveRecoveryRequested
Definition: xlogrecovery.c:139
bool InArchiveRecovery
Definition: xlogrecovery.c:140
void PerformWalRecovery(void)
static XLogRecPtr missingContrecPtr
Definition: xlogrecovery.c:380
static XLogRecPtr abortedRecPtr
Definition: xlogrecovery.c:379
EndOfWalRecoveryInfo * FinishWalRecovery(void)
void InitWalRecovery(ControlFileData *ControlFile, bool *wasShutdown_ptr, bool *haveBackupLabel_ptr, bool *haveTblspcMap_ptr)
Definition: xlogrecovery.c:519
TimeLineID recoveryTargetTLI
Definition: xlogrecovery.c:124
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(), 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(), pfree(), 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 6258 of file xlog.c.

6259{
6260 /* initialize minRecoveryPoint to this record */
6261 LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6263 if (ControlFile->minRecoveryPoint < EndRecPtr)
6264 {
6265 ControlFile->minRecoveryPoint = EndRecPtr;
6266 ControlFile->minRecoveryPointTLI = replayTLI;
6267 }
6268 /* update local copy */
6271
6272 /*
6273 * The startup process can update its local copy of minRecoveryPoint from
6274 * this point.
6275 */
6277
6279
6280 /*
6281 * We update SharedRecoveryState while holding the lock on ControlFileLock
6282 * so both states are consistent in shared memory.
6283 */
6287
6288 LWLockRelease(ControlFileLock);
6289}
static bool updateMinRecoveryPoint
Definition: xlog.c:648

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

8214{
8216 bool recoveryInProgress;
8217
8218 /*
8219 * Do nothing if full_page_writes has not been changed.
8220 *
8221 * It's safe to check the shared full_page_writes without the lock,
8222 * because we assume that there is no concurrently running process which
8223 * can update it.
8224 */
8225 if (fullPageWrites == Insert->fullPageWrites)
8226 return;
8227
8228 /*
8229 * Perform this outside critical section so that the WAL insert
8230 * initialization done by RecoveryInProgress() doesn't trigger an
8231 * assertion failure.
8232 */
8233 recoveryInProgress = RecoveryInProgress();
8234
8236
8237 /*
8238 * It's always safe to take full page images, even when not strictly
8239 * required, but not the other round. So if we're setting full_page_writes
8240 * to true, first set it true and then write the WAL record. If we're
8241 * setting it to false, first write the WAL record and then set the global
8242 * flag.
8243 */
8244 if (fullPageWrites)
8245 {
8247 Insert->fullPageWrites = true;
8249 }
8250
8251 /*
8252 * Write an XLOG_FPW_CHANGE record. This allows us to keep track of
8253 * full_page_writes during archive recovery, if required.
8254 */
8255 if (XLogStandbyInfoActive() && !recoveryInProgress)
8256 {
8258 XLogRegisterData(&fullPageWrites, sizeof(bool));
8259
8260 XLogInsert(RM_XLOG_ID, XLOG_FPW_CHANGE);
8261 }
8262
8263 if (!fullPageWrites)
8264 {
8266 Insert->fullPageWrites = false;
8268 }
8270}
#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 1751 of file xlog.c.

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

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 ||
65 {
66 CheckPoint *checkpoint = (CheckPoint *) rec;
67
68 appendStringInfo(buf, "redo %X/%08X; "
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",
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/%08X", LSN_FORMAT_ARGS(startpoint));
115 }
116 else if (info == XLOG_PARAMETER_CHANGE)
117 {
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,
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/%08X; 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)
uint8_t uint8
Definition: c.h:537
#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:72
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
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

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, and XLogRecGetInfo.

◆ 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;
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;
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
#define XLR_INFO_MASK
Definition: xlogrecord.h:62

References 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_NOOP, XLOG_OVERWRITE_CONTRECORD, XLOG_PARAMETER_CHANGE, XLOG_RESTORE_POINT, XLOG_SWITCH, and XLR_INFO_MASK.

◆ xlog_redo()

void xlog_redo ( struct XLogReaderState record)

Definition at line 8282 of file xlog.c.

8283{
8284 uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
8285 XLogRecPtr lsn = record->EndRecPtr;
8286
8287 /*
8288 * In XLOG rmgr, backup blocks are only used by XLOG_FPI and
8289 * XLOG_FPI_FOR_HINT records.
8290 */
8291 Assert(info == XLOG_FPI || info == XLOG_FPI_FOR_HINT ||
8292 !XLogRecHasAnyBlockRefs(record));
8293
8294 if (info == XLOG_NEXTOID)
8295 {
8296 Oid nextOid;
8297
8298 /*
8299 * We used to try to take the maximum of TransamVariables->nextOid and
8300 * the recorded nextOid, but that fails if the OID counter wraps
8301 * around. Since no OID allocation should be happening during replay
8302 * anyway, better to just believe the record exactly. We still take
8303 * OidGenLock while setting the variable, just in case.
8304 */
8305 memcpy(&nextOid, XLogRecGetData(record), sizeof(Oid));
8306 LWLockAcquire(OidGenLock, LW_EXCLUSIVE);
8307 TransamVariables->nextOid = nextOid;
8309 LWLockRelease(OidGenLock);
8310 }
8311 else if (info == XLOG_CHECKPOINT_SHUTDOWN)
8312 {
8313 CheckPoint checkPoint;
8314 TimeLineID replayTLI;
8315
8316 memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
8317 /* In a SHUTDOWN checkpoint, believe the counters exactly */
8318 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
8319 TransamVariables->nextXid = checkPoint.nextXid;
8320 LWLockRelease(XidGenLock);
8321 LWLockAcquire(OidGenLock, LW_EXCLUSIVE);
8322 TransamVariables->nextOid = checkPoint.nextOid;
8324 LWLockRelease(OidGenLock);
8326 checkPoint.nextMultiOffset);
8327
8329 checkPoint.oldestMultiDB);
8330
8331 /*
8332 * No need to set oldestClogXid here as well; it'll be set when we
8333 * redo an xl_clog_truncate if it changed since initialization.
8334 */
8335 SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
8336
8337 /*
8338 * If we see a shutdown checkpoint while waiting for an end-of-backup
8339 * record, the backup was canceled and the end-of-backup record will
8340 * never arrive.
8341 */
8345 ereport(PANIC,
8346 (errmsg("online backup was canceled, recovery cannot continue")));
8347
8348 /*
8349 * If we see a shutdown checkpoint, we know that nothing was running
8350 * on the primary at this point. So fake-up an empty running-xacts
8351 * record and use that here and now. Recover additional standby state
8352 * for prepared transactions.
8353 */
8355 {
8356 TransactionId *xids;
8357 int nxids;
8358 TransactionId oldestActiveXID;
8359 TransactionId latestCompletedXid;
8361
8362 oldestActiveXID = PrescanPreparedTransactions(&xids, &nxids);
8363
8364 /* Update pg_subtrans entries for any prepared transactions */
8366
8367 /*
8368 * Construct a RunningTransactions snapshot representing a shut
8369 * down server, with only prepared transactions still alive. We're
8370 * never overflowed at this point because all subxids are listed
8371 * with their parent prepared transactions.
8372 */
8373 running.xcnt = nxids;
8374 running.subxcnt = 0;
8376 running.nextXid = XidFromFullTransactionId(checkPoint.nextXid);
8377 running.oldestRunningXid = oldestActiveXID;
8378 latestCompletedXid = XidFromFullTransactionId(checkPoint.nextXid);
8379 TransactionIdRetreat(latestCompletedXid);
8380 Assert(TransactionIdIsNormal(latestCompletedXid));
8381 running.latestCompletedXid = latestCompletedXid;
8382 running.xids = xids;
8383
8385 }
8386
8387 /* ControlFile->checkPointCopy always tracks the latest ckpt XID */
8388 LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8390 LWLockRelease(ControlFileLock);
8391
8392 /*
8393 * We should've already switched to the new TLI before replaying this
8394 * record.
8395 */
8396 (void) GetCurrentReplayRecPtr(&replayTLI);
8397 if (checkPoint.ThisTimeLineID != replayTLI)
8398 ereport(PANIC,
8399 (errmsg("unexpected timeline ID %u (should be %u) in shutdown checkpoint record",
8400 checkPoint.ThisTimeLineID, replayTLI)));
8401
8402 RecoveryRestartPoint(&checkPoint, record);
8403
8404 /*
8405 * After replaying a checkpoint record, free all smgr objects.
8406 * Otherwise we would never do so for dropped relations, as the
8407 * startup does not process shared invalidation messages or call
8408 * AtEOXact_SMgr().
8409 */
8411 }
8412 else if (info == XLOG_CHECKPOINT_ONLINE)
8413 {
8414 CheckPoint checkPoint;
8415 TimeLineID replayTLI;
8416
8417 memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
8418 /* In an ONLINE checkpoint, treat the XID counter as a minimum */
8419 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
8421 checkPoint.nextXid))
8422 TransamVariables->nextXid = checkPoint.nextXid;
8423 LWLockRelease(XidGenLock);
8424
8425 /*
8426 * We ignore the nextOid counter in an ONLINE checkpoint, preferring
8427 * to track OID assignment through XLOG_NEXTOID records. The nextOid
8428 * counter is from the start of the checkpoint and might well be stale
8429 * compared to later XLOG_NEXTOID records. We could try to take the
8430 * maximum of the nextOid counter and our latest value, but since
8431 * there's no particular guarantee about the speed with which the OID
8432 * counter wraps around, that's a risky thing to do. In any case,
8433 * users of the nextOid counter are required to avoid assignment of
8434 * duplicates, so that a somewhat out-of-date value should be safe.
8435 */
8436
8437 /* Handle multixact */
8439 checkPoint.nextMultiOffset);
8440
8441 /*
8442 * NB: This may perform multixact truncation when replaying WAL
8443 * generated by an older primary.
8444 */
8446 checkPoint.oldestMultiDB);
8448 checkPoint.oldestXid))
8450 checkPoint.oldestXidDB);
8451 /* ControlFile->checkPointCopy always tracks the latest ckpt XID */
8452 LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8454 LWLockRelease(ControlFileLock);
8455
8456 /* TLI should not change in an on-line checkpoint */
8457 (void) GetCurrentReplayRecPtr(&replayTLI);
8458 if (checkPoint.ThisTimeLineID != replayTLI)
8459 ereport(PANIC,
8460 (errmsg("unexpected timeline ID %u (should be %u) in online checkpoint record",
8461 checkPoint.ThisTimeLineID, replayTLI)));
8462
8463 RecoveryRestartPoint(&checkPoint, record);
8464
8465 /*
8466 * After replaying a checkpoint record, free all smgr objects.
8467 * Otherwise we would never do so for dropped relations, as the
8468 * startup does not process shared invalidation messages or call
8469 * AtEOXact_SMgr().
8470 */
8472 }
8473 else if (info == XLOG_OVERWRITE_CONTRECORD)
8474 {
8475 /* nothing to do here, handled in xlogrecovery_redo() */
8476 }
8477 else if (info == XLOG_END_OF_RECOVERY)
8478 {
8479 xl_end_of_recovery xlrec;
8480 TimeLineID replayTLI;
8481
8482 memcpy(&xlrec, XLogRecGetData(record), sizeof(xl_end_of_recovery));
8483
8484 /*
8485 * For Hot Standby, we could treat this like a Shutdown Checkpoint,
8486 * but this case is rarer and harder to test, so the benefit doesn't
8487 * outweigh the potential extra cost of maintenance.
8488 */
8489
8490 /*
8491 * We should've already switched to the new TLI before replaying this
8492 * record.
8493 */
8494 (void) GetCurrentReplayRecPtr(&replayTLI);
8495 if (xlrec.ThisTimeLineID != replayTLI)
8496 ereport(PANIC,
8497 (errmsg("unexpected timeline ID %u (should be %u) in end-of-recovery record",
8498 xlrec.ThisTimeLineID, replayTLI)));
8499 }
8500 else if (info == XLOG_NOOP)
8501 {
8502 /* nothing to do here */
8503 }
8504 else if (info == XLOG_SWITCH)
8505 {
8506 /* nothing to do here */
8507 }
8508 else if (info == XLOG_RESTORE_POINT)
8509 {
8510 /* nothing to do here, handled in xlogrecovery.c */
8511 }
8512 else if (info == XLOG_FPI || info == XLOG_FPI_FOR_HINT)
8513 {
8514 /*
8515 * XLOG_FPI records contain nothing else but one or more block
8516 * references. Every block reference must include a full-page image
8517 * even if full_page_writes was disabled when the record was generated
8518 * - otherwise there would be no point in this record.
8519 *
8520 * XLOG_FPI_FOR_HINT records are generated when a page needs to be
8521 * WAL-logged because of a hint bit update. They are only generated
8522 * when checksums and/or wal_log_hints are enabled. They may include
8523 * no full-page images if full_page_writes was disabled when they were
8524 * generated. In this case there is nothing to do here.
8525 *
8526 * No recovery conflicts are generated by these generic records - if a
8527 * resource manager needs to generate conflicts, it has to define a
8528 * separate WAL record type and redo routine.
8529 */
8530 for (uint8 block_id = 0; block_id <= XLogRecMaxBlockId(record); block_id++)
8531 {
8532 Buffer buffer;
8533
8534 if (!XLogRecHasBlockImage(record, block_id))
8535 {
8536 if (info == XLOG_FPI)
8537 elog(ERROR, "XLOG_FPI record did not contain a full-page image");
8538 continue;
8539 }
8540
8541 if (XLogReadBufferForRedo(record, block_id, &buffer) != BLK_RESTORED)
8542 elog(ERROR, "unexpected XLogReadBufferForRedo result when restoring backup block");
8543 UnlockReleaseBuffer(buffer);
8544 }
8545 }
8546 else if (info == XLOG_BACKUP_END)
8547 {
8548 /* nothing to do here, handled in xlogrecovery_redo() */
8549 }
8550 else if (info == XLOG_PARAMETER_CHANGE)
8551 {
8552 xl_parameter_change xlrec;
8553
8554 /* Update our copy of the parameters in pg_control */
8555 memcpy(&xlrec, XLogRecGetData(record), sizeof(xl_parameter_change));
8556
8557 /*
8558 * Invalidate logical slots if we are in hot standby and the primary
8559 * does not have a WAL level sufficient for logical decoding. No need
8560 * to search for potentially conflicting logically slots if standby is
8561 * running with wal_level lower than logical, because in that case, we
8562 * would have either disallowed creation of logical slots or
8563 * invalidated existing ones.
8564 */
8565 if (InRecovery && InHotStandby &&
8566 xlrec.wal_level < WAL_LEVEL_LOGICAL &&
8569 0, InvalidOid,
8571
8572 LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8580
8581 /*
8582 * Update minRecoveryPoint to ensure that if recovery is aborted, we
8583 * recover back up to this point before allowing hot standby again.
8584 * This is important if the max_* settings are decreased, to ensure
8585 * you don't run queries against the WAL preceding the change. The
8586 * local copies cannot be updated as long as crash recovery is
8587 * happening and we expect all the WAL to be replayed.
8588 */
8590 {
8593 }
8595 {
8596 TimeLineID replayTLI;
8597
8598 (void) GetCurrentReplayRecPtr(&replayTLI);
8600 ControlFile->minRecoveryPointTLI = replayTLI;
8601 }
8602
8606
8608 LWLockRelease(ControlFileLock);
8609
8610 /* Check to see if any parameter change gives a problem on recovery */
8612 }
8613 else if (info == XLOG_FPW_CHANGE)
8614 {
8615 bool fpw;
8616
8617 memcpy(&fpw, XLogRecGetData(record), sizeof(bool));
8618
8619 /*
8620 * Update the LSN of the last replayed XLOG_FPW_CHANGE record so that
8621 * do_pg_backup_start() and do_pg_backup_stop() can check whether
8622 * full_page_writes has been disabled during online backup.
8623 */
8624 if (!fpw)
8625 {
8630 }
8631
8632 /* Keep track of full_page_writes */
8633 lastFullPageWrites = fpw;
8634 }
8635 else if (info == XLOG_CHECKPOINT_REDO)
8636 {
8637 /* nothing to do here, just for informational purposes */
8638 }
8639}
int Buffer
Definition: buf.h:23
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:5355
void CommitTsParameterChange(bool newvalue, bool oldvalue)
Definition: commit_ts.c:640
void MultiXactAdvanceOldest(MultiXactId oldestMulti, Oid oldestMultiDB)
Definition: multixact.c:2466
void MultiXactAdvanceNextMXact(MultiXactId minMulti, MultiXactOffset minMultiOffset)
Definition: multixact.c:2441
@ RS_INVAL_WAL_LEVEL
Definition: slot.h:66
void smgrdestroyall(void)
Definition: smgr.c:386
int max_worker_processes
Definition: pg_control.h:181
int max_locks_per_xact
Definition: pg_control.h:184
int max_prepared_xacts
Definition: pg_control.h:183
XLogRecPtr EndRecPtr
Definition: xlogreader.h:207
XLogRecPtr ReadRecPtr
Definition: xlogreader.h:206
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:280
#define FullTransactionIdPrecedes(a, b)
Definition: transam.h:51
static void RecoveryRestartPoint(const CheckPoint *checkPoint, XLogReaderState *record)
Definition: xlog.c:7596
#define XLogRecMaxBlockId(decoder)
Definition: xlogreader.h:418
#define XLogRecHasBlockImage(decoder, block_id)
Definition: xlogreader.h:423
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:417
XLogRecPtr GetCurrentReplayRecPtr(TimeLineID *replayEndTLI)
XLogRedoAction XLogReadBufferForRedo(XLogReaderState *record, uint8 block_id, Buffer *buf)
Definition: xlogutils.c:303
@ STANDBY_INITIALIZED
Definition: xlogutils.h:53
#define InHotStandby
Definition: xlogutils.h:60
@ BLK_RESTORED
Definition: xlogutils.h:76

References ArchiveRecoveryRequested, Assert(), ControlFileData::backupEndPoint, ControlFileData::backupStartPoint, BLK_RESTORED, ControlFileData::checkPointCopy, CheckRequiredParameterValues(), CommitTsParameterChange(), ControlFile, elog, XLogReaderState::EndRecPtr, ereport, errmsg(), ERROR, FullTransactionIdPrecedes, GetCurrentReplayRecPtr(), InArchiveRecovery, XLogCtlData::info_lck, InHotStandby, InRecovery, InvalidateObsoleteReplicationSlots(), InvalidOid, InvalidTransactionId, InvalidXLogRecPtr, XLogCtlData::lastFpwDisableRecPtr, lastFullPageWrites, RunningTransactionsData::latestCompletedXid, LocalMinRecoveryPoint, LocalMinRecoveryPointTLI, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), xl_parameter_change::max_locks_per_xact, ControlFileData::max_locks_per_xact, xl_parameter_change::max_prepared_xacts, ControlFileData::max_prepared_xacts, xl_parameter_change::max_wal_senders, ControlFileData::max_wal_senders, xl_parameter_change::max_worker_processes, ControlFileData::max_worker_processes, xl_parameter_change::MaxConnections, ControlFileData::MaxConnections, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, MultiXactAdvanceNextMXact(), MultiXactAdvanceOldest(), MultiXactSetNextMXact(), CheckPoint::nextMulti, CheckPoint::nextMultiOffset, TransamVariablesData::nextOid, CheckPoint::nextOid, TransamVariablesData::nextXid, CheckPoint::nextXid, RunningTransactionsData::nextXid, TransamVariablesData::oidCount, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, RunningTransactionsData::oldestRunningXid, TransamVariablesData::oldestXid, CheckPoint::oldestXid, CheckPoint::oldestXidDB, PANIC, PrescanPreparedTransactions(), ProcArrayApplyRecoveryInfo(), XLogReaderState::ReadRecPtr, RecoveryRestartPoint(), RS_INVAL_WAL_LEVEL, SetTransactionIdLimit(), smgrdestroyall(), SpinLockAcquire, SpinLockRelease, STANDBY_INITIALIZED, StandbyRecoverPreparedTransactions(), standbyState, RunningTransactionsData::subxcnt, RunningTransactionsData::subxid_status, SUBXIDS_IN_SUBTRANS, xl_end_of_recovery::ThisTimeLineID, CheckPoint::ThisTimeLineID, xl_parameter_change::track_commit_timestamp, ControlFileData::track_commit_timestamp, TransactionIdIsNormal, TransactionIdPrecedes(), TransactionIdRetreat, TransamVariables, UnlockReleaseBuffer(), UpdateControlFile(), wal_level, xl_parameter_change::wal_level, ControlFileData::wal_level, WAL_LEVEL_LOGICAL, xl_parameter_change::wal_log_hints, ControlFileData::wal_log_hints, RunningTransactionsData::xcnt, XidFromFullTransactionId, RunningTransactionsData::xids, 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_NOOP, XLOG_OVERWRITE_CONTRECORD, XLOG_PARAMETER_CHANGE, XLOG_RESTORE_POINT, XLOG_SWITCH, XLogCtl, XLogReadBufferForRedo(), XLogRecGetData, XLogRecGetInfo, XLogRecHasAnyBlockRefs, XLogRecHasBlockImage, XLogRecMaxBlockId, and XLogRecPtrIsInvalid.

◆ XLogBackgroundFlush()

bool XLogBackgroundFlush ( void  )

Definition at line 2975 of file xlog.c.

2976{
2977 XLogwrtRqst WriteRqst;
2978 bool flexible = true;
2979 static TimestampTz lastflush;
2981 int flushblocks;
2982 TimeLineID insertTLI;
2983
2984 /* XLOG doesn't need flushing during recovery */
2985 if (RecoveryInProgress())
2986 return false;
2987
2988 /*
2989 * Since we're not in recovery, InsertTimeLineID is set and can't change,
2990 * so we can read it without a lock.
2991 */
2992 insertTLI = XLogCtl->InsertTimeLineID;
2993
2994 /* read updated LogwrtRqst */
2996 WriteRqst = XLogCtl->LogwrtRqst;
2998
2999 /* back off to last completed page boundary */
3000 WriteRqst.Write -= WriteRqst.Write % XLOG_BLCKSZ;
3001
3002 /* if we have already flushed that far, consider async commit records */
3004 if (WriteRqst.Write <= LogwrtResult.Flush)
3005 {
3007 WriteRqst.Write = XLogCtl->asyncXactLSN;
3009 flexible = false; /* ensure it all gets written */
3010 }
3011
3012 /*
3013 * If already known flushed, we're done. Just need to check if we are
3014 * holding an open file handle to a logfile that's no longer in use,
3015 * preventing the file from being deleted.
3016 */
3017 if (WriteRqst.Write <= LogwrtResult.Flush)
3018 {
3019 if (openLogFile >= 0)
3020 {
3023 {
3024 XLogFileClose();
3025 }
3026 }
3027 return false;
3028 }
3029
3030 /*
3031 * Determine how far to flush WAL, based on the wal_writer_delay and
3032 * wal_writer_flush_after GUCs.
3033 *
3034 * Note that XLogSetAsyncXactLSN() performs similar calculation based on
3035 * wal_writer_flush_after, to decide when to wake us up. Make sure the
3036 * logic is the same in both places if you change this.
3037 */
3039 flushblocks =
3040 WriteRqst.Write / XLOG_BLCKSZ - LogwrtResult.Flush / XLOG_BLCKSZ;
3041
3042 if (WalWriterFlushAfter == 0 || lastflush == 0)
3043 {
3044 /* first call, or block based limits disabled */
3045 WriteRqst.Flush = WriteRqst.Write;
3046 lastflush = now;
3047 }
3048 else if (TimestampDifferenceExceeds(lastflush, now, WalWriterDelay))
3049 {
3050 /*
3051 * Flush the writes at least every WalWriterDelay ms. This is
3052 * important to bound the amount of time it takes for an asynchronous
3053 * commit to hit disk.
3054 */
3055 WriteRqst.Flush = WriteRqst.Write;
3056 lastflush = now;
3057 }
3058 else if (flushblocks >= WalWriterFlushAfter)
3059 {
3060 /* exceeded wal_writer_flush_after blocks, flush */
3061 WriteRqst.Flush = WriteRqst.Write;
3062 lastflush = now;
3063 }
3064 else
3065 {
3066 /* no flushing, this time round */
3067 WriteRqst.Flush = 0;
3068 }
3069
3070#ifdef WAL_DEBUG
3071 if (XLOG_DEBUG)
3072 elog(LOG, "xlog bg flush request write %X/%08X; flush: %X/%08X, current is write %X/%08X; flush %X/%08X",
3073 LSN_FORMAT_ARGS(WriteRqst.Write),
3074 LSN_FORMAT_ARGS(WriteRqst.Flush),
3077#endif
3078
3080
3081 /* now wait for any in-progress insertions to finish and get write lock */
3083 LWLockAcquire(WALWriteLock, LW_EXCLUSIVE);
3085 if (WriteRqst.Write > LogwrtResult.Write ||
3086 WriteRqst.Flush > LogwrtResult.Flush)
3087 {
3088 XLogWrite(WriteRqst, insertTLI, flexible);
3089 }
3090 LWLockRelease(WALWriteLock);
3091
3093
3094 /* wake up walsenders now that we've released heavily contended locks */
3096
3097 /*
3098 * Great, done. To take some work off the critical path, try to initialize
3099 * as many of the no-longer-needed WAL buffers for future use as we can.
3100 */
3101 AdvanceXLInsertBuffer(InvalidXLogRecPtr, insertTLI, true);
3102
3103 /*
3104 * If we determined that we need to write data, but somebody else
3105 * wrote/flushed already, it should be considered as being active, to
3106 * avoid hibernating too early.
3107 */
3108 return true;
3109}
bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec)
Definition: timestamp.c:1781
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1609
XLogRecPtr asyncXactLSN
Definition: xlog.c:458
static void WalSndWakeupProcessRequests(bool physical, bool logical)
Definition: walsender.h:65
int WalWriterFlushAfter
Definition: walwriter.c:71
int WalWriterDelay
Definition: walwriter.c:70
static XLogRecPtr WaitXLogInsertionsToFinish(XLogRecPtr upto)
Definition: xlog.c:1507
static void AdvanceXLInsertBuffer(XLogRecPtr upto, TimeLineID tli, bool opportunistic)
Definition: xlog.c:1988
static void XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
Definition: xlog.c:2304
static void XLogFileClose(void)
Definition: xlog.c:3652
static XLogSegNo openLogSegNo
Definition: xlog.c:636
#define XLByteInPrevSeg(xlrp, logSegNo, wal_segsz_bytes)

References AdvanceXLInsertBuffer(), XLogCtlData::asyncXactLSN, elog, END_CRIT_SECTION, XLogwrtRqst::Flush, XLogwrtResult::Flush, GetCurrentTimestamp(), XLogCtlData::info_lck, XLogCtlData::InsertTimeLineID, InvalidXLogRecPtr, LOG, LogwrtResult, XLogCtlData::LogwrtRqst, LSN_FORMAT_ARGS, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), now(), openLogFile, openLogSegNo, RecoveryInProgress(), RefreshXLogWriteResult, SpinLockAcquire, SpinLockRelease, START_CRIT_SECTION, TimestampDifferenceExceeds(), WaitXLogInsertionsToFinish(), wal_segment_size, WalSndWakeupProcessRequests(), WalWriterDelay, WalWriterFlushAfter, XLogwrtRqst::Write, XLogwrtResult::Write, XLByteInPrevSeg, XLogCtl, XLogFileClose(), and XLogWrite().

Referenced by WalSndWaitForWal(), and WalWriterMain().

◆ XLogCheckpointNeeded()

bool XLogCheckpointNeeded ( XLogSegNo  new_segno)

Definition at line 2280 of file xlog.c.

2281{
2282 XLogSegNo old_segno;
2283
2285
2286 if (new_segno >= old_segno + (uint64) (CheckPointSegments - 1))
2287 return true;
2288 return false;
2289}
int CheckPointSegments
Definition: xlog.c:157

References CheckPointSegments, RedoRecPtr, wal_segment_size, and XLByteToSeg.

Referenced by XLogPageRead(), and XLogWrite().

◆ XLogFileInit()

int XLogFileInit ( XLogSegNo  logsegno,
TimeLineID  logtli 
)

Definition at line 3393 of file xlog.c.

3394{
3395 bool ignore_added;
3396 char path[MAXPGPATH];
3397 int fd;
3398
3399 Assert(logtli != 0);
3400
3401 fd = XLogFileInitInternal(logsegno, logtli, &ignore_added, path);
3402 if (fd >= 0)
3403 return fd;
3404
3405 /* Now open original target segment (might not be file I just made) */
3406 fd = BasicOpenFile(path, O_RDWR | PG_BINARY | O_CLOEXEC |
3408 if (fd < 0)
3409 ereport(ERROR,
3411 errmsg("could not open file \"%s\": %m", path)));
3412 return fd;
3413}
#define PG_BINARY
Definition: c.h:1273
int BasicOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1086
#define O_CLOEXEC
Definition: win32_port.h:349
static int get_sync_bit(int method)
Definition: xlog.c:8646
static int XLogFileInitInternal(XLogSegNo logsegno, TimeLineID logtli, bool *added, char *path)
Definition: xlog.c:3205

References Assert(), BasicOpenFile(), ereport, errcode_for_file_access(), errmsg(), ERROR, fd(), get_sync_bit(), MAXPGPATH, O_CLOEXEC, PG_BINARY, wal_sync_method, and XLogFileInitInternal().

Referenced by BootStrapXLOG(), XLogInitNewTimeline(), XLogWalRcvWrite(), and XLogWrite().

◆ XLogFileOpen()

int XLogFileOpen ( XLogSegNo  segno,
TimeLineID  tli 
)

Definition at line 3631 of file xlog.c.

3632{
3633 char path[MAXPGPATH];
3634 int fd;
3635
3636 XLogFilePath(path, tli, segno, wal_segment_size);
3637
3638 fd = BasicOpenFile(path, O_RDWR | PG_BINARY | O_CLOEXEC |
3640 if (fd < 0)
3641 ereport(PANIC,
3643 errmsg("could not open file \"%s\": %m", path)));
3644
3645 return fd;
3646}
static void XLogFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)

References BasicOpenFile(), ereport, errcode_for_file_access(), errmsg(), fd(), get_sync_bit(), MAXPGPATH, O_CLOEXEC, PANIC, PG_BINARY, wal_segment_size, wal_sync_method, and XLogFilePath().

Referenced by XLogWrite().

◆ XLogFlush()

void XLogFlush ( XLogRecPtr  record)

Definition at line 2780 of file xlog.c.

2781{
2782 XLogRecPtr WriteRqstPtr;
2783 XLogwrtRqst WriteRqst;
2784 TimeLineID insertTLI = XLogCtl->InsertTimeLineID;
2785
2786 /*
2787 * During REDO, we are reading not writing WAL. Therefore, instead of
2788 * trying to flush the WAL, we should update minRecoveryPoint instead. We
2789 * test XLogInsertAllowed(), not InRecovery, because we need checkpointer
2790 * to act this way too, and because when it tries to write the
2791 * end-of-recovery checkpoint, it should indeed flush.
2792 */
2793 if (!XLogInsertAllowed())
2794 {
2795 UpdateMinRecoveryPoint(record, false);
2796 return;
2797 }
2798
2799 /* Quick exit if already known flushed */
2800 if (record <= LogwrtResult.Flush)
2801 return;
2802
2803#ifdef WAL_DEBUG
2804 if (XLOG_DEBUG)
2805 elog(LOG, "xlog flush request %X/%08X; write %X/%08X; flush %X/%08X",
2806 LSN_FORMAT_ARGS(record),
2809#endif
2810
2812
2813 /*
2814 * Since fsync is usually a horribly expensive operation, we try to
2815 * piggyback as much data as we can on each fsync: if we see any more data
2816 * entered into the xlog buffer, we'll write and fsync that too, so that
2817 * the final value of LogwrtResult.Flush is as large as possible. This
2818 * gives us some chance of avoiding another fsync immediately after.
2819 */
2820
2821 /* initialize to given target; may increase below */
2822 WriteRqstPtr = record;
2823
2824 /*
2825 * Now wait until we get the write lock, or someone else does the flush
2826 * for us.
2827 */
2828 for (;;)
2829 {
2830 XLogRecPtr insertpos;
2831
2832 /* done already? */
2834 if (record <= LogwrtResult.Flush)
2835 break;
2836
2837 /*
2838 * Before actually performing the write, wait for all in-flight
2839 * insertions to the pages we're about to write to finish.
2840 */
2842 if (WriteRqstPtr < XLogCtl->LogwrtRqst.Write)
2843 WriteRqstPtr = XLogCtl->LogwrtRqst.Write;
2845 insertpos = WaitXLogInsertionsToFinish(WriteRqstPtr);
2846
2847 /*
2848 * Try to get the write lock. If we can't get it immediately, wait
2849 * until it's released, and recheck if we still need to do the flush
2850 * or if the backend that held the lock did it for us already. This
2851 * helps to maintain a good rate of group committing when the system
2852 * is bottlenecked by the speed of fsyncing.
2853 */
2854 if (!LWLockAcquireOrWait(WALWriteLock, LW_EXCLUSIVE))
2855 {
2856 /*
2857 * The lock is now free, but we didn't acquire it yet. Before we
2858 * do, loop back to check if someone else flushed the record for
2859 * us already.
2860 */
2861 continue;
2862 }
2863
2864 /* Got the lock; recheck whether request is satisfied */
2866 if (record <= LogwrtResult.Flush)
2867 {
2868 LWLockRelease(WALWriteLock);
2869 break;
2870 }
2871
2872 /*
2873 * Sleep before flush! By adding a delay here, we may give further
2874 * backends the opportunity to join the backlog of group commit
2875 * followers; this can significantly improve transaction throughput,
2876 * at the risk of increasing transaction latency.
2877 *
2878 * We do not sleep if enableFsync is not turned on, nor if there are
2879 * fewer than CommitSiblings other backends with active transactions.
2880 */
2881 if (CommitDelay > 0 && enableFsync &&
2883 {
2885
2886 /*
2887 * Re-check how far we can now flush the WAL. It's generally not
2888 * safe to call WaitXLogInsertionsToFinish while holding
2889 * WALWriteLock, because an in-progress insertion might need to
2890 * also grab WALWriteLock to make progress. But we know that all
2891 * the insertions up to insertpos have already finished, because
2892 * that's what the earlier WaitXLogInsertionsToFinish() returned.
2893 * We're only calling it again to allow insertpos to be moved
2894 * further forward, not to actually wait for anyone.
2895 */
2896 insertpos = WaitXLogInsertionsToFinish(insertpos);
2897 }
2898
2899 /* try to write/flush later additions to XLOG as well */
2900 WriteRqst.Write = insertpos;
2901 WriteRqst.Flush = insertpos;
2902
2903 XLogWrite(WriteRqst, insertTLI, false);
2904
2905 LWLockRelease(WALWriteLock);
2906 /* done */
2907 break;
2908 }
2909
2911
2912 /* wake up walsenders now that we've released heavily contended locks */
2914
2915 /*
2916 * If we still haven't flushed to the request point then we have a
2917 * problem; most likely, the requested flush point is past end of XLOG.
2918 * This has been seen to occur when a disk page has a corrupted LSN.
2919 *
2920 * Formerly we treated this as a PANIC condition, but that hurts the
2921 * system's robustness rather than helping it: we do not want to take down
2922 * the whole system due to corruption on one data page. In particular, if
2923 * the bad page is encountered again during recovery then we would be
2924 * unable to restart the database at all! (This scenario actually
2925 * happened in the field several times with 7.1 releases.) As of 8.4, bad
2926 * LSNs encountered during recovery are UpdateMinRecoveryPoint's problem;
2927 * the only time we can reach here during recovery is while flushing the
2928 * end-of-recovery checkpoint record, and we don't expect that to have a
2929 * bad LSN.
2930 *
2931 * Note that for calls from xact.c, the ERROR will be promoted to PANIC
2932 * since xact.c calls this routine inside a critical section. However,
2933 * calls from bufmgr.c are not within critical sections and so we will not
2934 * force a restart for a bad LSN on a data page.
2935 */
2936 if (LogwrtResult.Flush < record)
2937 elog(ERROR,
2938 "xlog flush request %X/%08X is not satisfied --- flushed only to %X/%08X",
2939 LSN_FORMAT_ARGS(record),
2941
2942 /*
2943 * Cross-check XLogNeedsFlush(). Some of the checks of XLogFlush() and
2944 * XLogNeedsFlush() are duplicated, and this assertion ensures that these
2945 * remain consistent.
2946 */
2947 Assert(!XLogNeedsFlush(record));
2948}
bool LWLockAcquireOrWait(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1402
bool MinimumActiveBackends(int min)
Definition: procarray.c:3508
int CommitDelay
Definition: xlog.c:133
int CommitSiblings
Definition: xlog.c:134
bool XLogNeedsFlush(XLogRecPtr record)
Definition: xlog.c:3124
bool XLogInsertAllowed(void)
Definition: xlog.c:6438

References Assert(), CommitDelay, CommitSiblings, elog, enableFsync, END_CRIT_SECTION, ERROR, XLogwrtRqst::Flush, XLogwrtResult::Flush, XLogCtlData::info_lck, XLogCtlData::InsertTimeLineID, LOG, LogwrtResult, XLogCtlData::LogwrtRqst, LSN_FORMAT_ARGS, LW_EXCLUSIVE, LWLockAcquireOrWait(), LWLockRelease(), MinimumActiveBackends(), pg_usleep(), RecoveryInProgress(), RefreshXLogWriteResult, SpinLockAcquire, SpinLockRelease, START_CRIT_SECTION, UpdateMinRecoveryPoint(), WaitXLogInsertionsToFinish(), WalSndWakeupProcessRequests(), XLogwrtRqst::Write, XLogwrtResult::Write, XLogCtl, XLogInsertAllowed(), XLogNeedsFlush(), and XLogWrite().

Referenced by CheckPointReplicationOrigin(), CreateCheckPoint(), CreateEndOfRecoveryRecord(), CreateOverwriteContrecordRecord(), dropdb(), EndPrepare(), finish_sync_worker(), FlushBuffer(), LogLogicalMessage(), pg_truncate_visibility_map(), RecordTransactionAbortPrepared(), RecordTransactionCommit(), RecordTransactionCommitPrepared(), RelationTruncate(), ReplicationSlotReserveWal(), replorigin_get_progress(), replorigin_session_get_progress(), SlruPhysicalWritePage(), smgr_redo(), write_relmap_file(), WriteMTruncateXlogRec(), WriteTruncateXlogRec(), xact_redo_abort(), xact_redo_commit(), XLogInsertRecord(), and XLogReportParameters().

◆ XLogGetLastRemovedSegno()

XLogSegNo XLogGetLastRemovedSegno ( void  )

Definition at line 3771 of file xlog.c.

3772{
3773 XLogSegNo lastRemovedSegNo;
3774
3776 lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3778
3779 return lastRemovedSegNo;
3780}

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

Referenced by copy_replication_slot(), GetWALAvailability(), ReplicationSlotReserveWal(), and reserve_wal_for_local_slot().

◆ XLogGetOldestSegno()

XLogSegNo XLogGetOldestSegno ( TimeLineID  tli)

Definition at line 3787 of file xlog.c.

3788{
3789 DIR *xldir;
3790 struct dirent *xlde;
3791 XLogSegNo oldest_segno = 0;
3792
3793 xldir = AllocateDir(XLOGDIR);
3794 while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
3795 {
3796 TimeLineID file_tli;
3797 XLogSegNo file_segno;
3798
3799 /* Ignore files that are not XLOG segments. */
3800 if (!IsXLogFileName(xlde->d_name))
3801 continue;
3802
3803 /* Parse filename to get TLI and segno. */
3804 XLogFromFileName(xlde->d_name, &file_tli, &file_segno,
3806
3807 /* Ignore anything that's not from the TLI of interest. */
3808 if (tli != file_tli)
3809 continue;
3810
3811 /* If it's the oldest so far, update oldest_segno. */
3812 if (oldest_segno == 0 || file_segno < oldest_segno)
3813 oldest_segno = file_segno;
3814 }
3815
3816 FreeDir(xldir);
3817 return oldest_segno;
3818}
static void XLogFromFileName(const char *fname, TimeLineID *tli, XLogSegNo *logSegNo, int wal_segsz_bytes)

References AllocateDir(), dirent::d_name, FreeDir(), IsXLogFileName(), ReadDir(), wal_segment_size, XLOGDIR, and XLogFromFileName().

Referenced by GetOldestUnsummarizedLSN(), MaybeRemoveOldWalSummaries(), and reserve_wal_for_local_slot().

◆ XLogInsertAllowed()

bool XLogInsertAllowed ( void  )

Definition at line 6438 of file xlog.c.

6439{
6440 /*
6441 * If value is "unconditionally true" or "unconditionally false", just
6442 * return it. This provides the normal fast path once recovery is known
6443 * done.
6444 */
6445 if (LocalXLogInsertAllowed >= 0)
6446 return (bool) LocalXLogInsertAllowed;
6447
6448 /*
6449 * Else, must check to see if we're still in recovery.
6450 */
6451 if (RecoveryInProgress())
6452 return false;
6453
6454 /*
6455 * On exit from recovery, reset to "unconditionally true", since there is
6456 * no need to keep checking.
6457 */
6459 return true;
6460}

References LocalXLogInsertAllowed, and RecoveryInProgress().

Referenced by XLogBeginInsert(), XLogFlush(), XLogInsertRecord(), and XLogNeedsFlush().

◆ XLogInsertRecord()

XLogRecPtr XLogInsertRecord ( struct XLogRecData rdata,
XLogRecPtr  fpw_lsn,
uint8  flags,
int  num_fpi,
bool  topxid_included 
)

Definition at line 748 of file xlog.c.

753{
755 pg_crc32c rdata_crc;
756 bool inserted;
757 XLogRecord *rechdr = (XLogRecord *) rdata->data;
758 uint8 info = rechdr->xl_info & ~XLR_INFO_MASK;
760 XLogRecPtr StartPos;
761 XLogRecPtr EndPos;
762 bool prevDoPageWrites = doPageWrites;
763 TimeLineID insertTLI;
764
765 /* Does this record type require special handling? */
766 if (unlikely(rechdr->xl_rmid == RM_XLOG_ID))
767 {
768 if (info == XLOG_SWITCH)
770 else if (info == XLOG_CHECKPOINT_REDO)
772 }
773
774 /* we assume that all of the record header is in the first chunk */
775 Assert(rdata->len >= SizeOfXLogRecord);
776
777 /* cross-check on whether we should be here or not */
778 if (!XLogInsertAllowed())
779 elog(ERROR, "cannot make new WAL entries during recovery");
780
781 /*
782 * Given that we're not in recovery, InsertTimeLineID is set and can't
783 * change, so we can read it without a lock.
784 */
785 insertTLI = XLogCtl->InsertTimeLineID;
786
787 /*----------
788 *
789 * We have now done all the preparatory work we can without holding a
790 * lock or modifying shared state. From here on, inserting the new WAL
791 * record to the shared WAL buffer cache is a two-step process:
792 *
793 * 1. Reserve the right amount of space from the WAL. The current head of
794 * reserved space is kept in Insert->CurrBytePos, and is protected by
795 * insertpos_lck.
796 *
797 * 2. Copy the record to the reserved WAL space. This involves finding the
798 * correct WAL buffer containing the reserved space, and copying the
799 * record in place. This can be done concurrently in multiple processes.
800 *
801 * To keep track of which insertions are still in-progress, each concurrent
802 * inserter acquires an insertion lock. In addition to just indicating that
803 * an insertion is in progress, the lock tells others how far the inserter
804 * has progressed. There is a small fixed number of insertion locks,
805 * determined by NUM_XLOGINSERT_LOCKS. When an inserter crosses a page
806 * boundary, it updates the value stored in the lock to the how far it has
807 * inserted, to allow the previous buffer to be flushed.
808 *
809 * Holding onto an insertion lock also protects RedoRecPtr and
810 * fullPageWrites from changing until the insertion is finished.
811 *
812 * Step 2 can usually be done completely in parallel. If the required WAL
813 * page is not initialized yet, you have to grab WALBufMappingLock to
814 * initialize it, but the WAL writer tries to do that ahead of insertions
815 * to avoid that from happening in the critical path.
816 *
817 *----------
818 */
820
821 if (likely(class == WALINSERT_NORMAL))
822 {
824
825 /*
826 * Check to see if my copy of RedoRecPtr is out of date. If so, may
827 * have to go back and have the caller recompute everything. This can
828 * only happen just after a checkpoint, so it's better to be slow in
829 * this case and fast otherwise.
830 *
831 * Also check to see if fullPageWrites was just turned on or there's a
832 * running backup (which forces full-page writes); if we weren't
833 * already doing full-page writes then go back and recompute.
834 *
835 * If we aren't doing full-page writes then RedoRecPtr doesn't
836 * actually affect the contents of the XLOG record, so we'll update
837 * our local copy but not force a recomputation. (If doPageWrites was
838 * just turned off, we could recompute the record without full pages,
839 * but we choose not to bother.)
840 */
841 if (RedoRecPtr != Insert->RedoRecPtr)
842 {
843 Assert(RedoRecPtr < Insert->RedoRecPtr);
844 RedoRecPtr = Insert->RedoRecPtr;
845 }
846 doPageWrites = (Insert->fullPageWrites || Insert->runningBackups > 0);
847
848 if (doPageWrites &&
849 (!prevDoPageWrites ||
850 (fpw_lsn != InvalidXLogRecPtr && fpw_lsn <= RedoRecPtr)))
851 {
852 /*
853 * Oops, some buffer now needs to be backed up that the caller
854 * didn't back up. Start over.
855 */
858 return InvalidXLogRecPtr;
859 }
860
861 /*
862 * Reserve space for the record in the WAL. This also sets the xl_prev
863 * pointer.
864 */
865 ReserveXLogInsertLocation(rechdr->xl_tot_len, &StartPos, &EndPos,
866 &rechdr->xl_prev);
867
868 /* Normal records are always inserted. */
869 inserted = true;
870 }
871 else if (class == WALINSERT_SPECIAL_SWITCH)
872 {
873 /*
874 * In order to insert an XLOG_SWITCH record, we need to hold all of
875 * the WAL insertion locks, not just one, so that no one else can
876 * begin inserting a record until we've figured out how much space
877 * remains in the current WAL segment and claimed all of it.
878 *
879 * Nonetheless, this case is simpler than the normal cases handled
880 * below, which must check for changes in doPageWrites and RedoRecPtr.
881 * Those checks are only needed for records that can contain buffer
882 * references, and an XLOG_SWITCH record never does.
883 */
884 Assert(fpw_lsn == InvalidXLogRecPtr);
886 inserted = ReserveXLogSwitch(&StartPos, &EndPos, &rechdr->xl_prev);
887 }
888 else
889 {
891
892 /*
893 * We need to update both the local and shared copies of RedoRecPtr,
894 * which means that we need to hold all the WAL insertion locks.
895 * However, there can't be any buffer references, so as above, we need
896 * not check RedoRecPtr before inserting the record; we just need to
897 * update it afterwards.
898 */
899 Assert(fpw_lsn == InvalidXLogRecPtr);
901 ReserveXLogInsertLocation(rechdr->xl_tot_len, &StartPos, &EndPos,
902 &rechdr->xl_prev);
903 RedoRecPtr = Insert->RedoRecPtr = StartPos;
904 inserted = true;
905 }
906
907 if (inserted)
908 {
909 /*
910 * Now that xl_prev has been filled in, calculate CRC of the record
911 * header.
912 */
913 rdata_crc = rechdr->xl_crc;
914 COMP_CRC32C(rdata_crc, rechdr, offsetof(XLogRecord, xl_crc));
915 FIN_CRC32C(rdata_crc);
916 rechdr->xl_crc = rdata_crc;
917
918 /*
919 * All the record data, including the header, is now ready to be
920 * inserted. Copy the record in the space reserved.
921 */
923 class == WALINSERT_SPECIAL_SWITCH, rdata,
924 StartPos, EndPos, insertTLI);
925
926 /*
927 * Unless record is flagged as not important, update LSN of last
928 * important record in the current slot. When holding all locks, just
929 * update the first one.
930 */
931 if ((flags & XLOG_MARK_UNIMPORTANT) == 0)
932 {
933 int lockno = holdingAllLocks ? 0 : MyLockNo;
934
935 WALInsertLocks[lockno].l.lastImportantAt = StartPos;
936 }
937 }
938 else
939 {
940 /*
941 * This was an xlog-switch record, but the current insert location was
942 * already exactly at the beginning of a segment, so there was no need
943 * to do anything.
944 */
945 }
946
947 /*
948 * Done! Let others know that we're finished.
949 */
951
953
955
956 /*
957 * Mark top transaction id is logged (if needed) so that we should not try
958 * to log it again with the next WAL record in the current subtransaction.
959 */
960 if (topxid_included)
962
963 /*
964 * Update shared LogwrtRqst.Write, if we crossed page boundary.
965 */
966 if (StartPos / XLOG_BLCKSZ != EndPos / XLOG_BLCKSZ)
967 {
969 /* advance global request to include new block(s) */
970 if (XLogCtl->LogwrtRqst.Write < EndPos)
971 XLogCtl->LogwrtRqst.Write = EndPos;
974 }
975
976 /*
977 * If this was an XLOG_SWITCH record, flush the record and the empty
978 * padding space that fills the rest of the segment, and perform
979 * end-of-segment actions (eg, notifying archiver).
980 */
981 if (class == WALINSERT_SPECIAL_SWITCH)
982 {
983 TRACE_POSTGRESQL_WAL_SWITCH();
984 XLogFlush(EndPos);
985
986 /*
987 * Even though we reserved the rest of the segment for us, which is
988 * reflected in EndPos, we return a pointer to just the end of the
989 * xlog-switch record.
990 */
991 if (inserted)
992 {
993 EndPos = StartPos + SizeOfXLogRecord;
994 if (StartPos / XLOG_BLCKSZ != EndPos / XLOG_BLCKSZ)
995 {
996 uint64 offset = XLogSegmentOffset(EndPos, wal_segment_size);
997
998 if (offset == EndPos % XLOG_BLCKSZ)
999 EndPos += SizeOfXLogLongPHD;
1000 else
1001 EndPos += SizeOfXLogShortPHD;
1002 }
1003 }
1004 }
1005
1006#ifdef WAL_DEBUG
1007 if (XLOG_DEBUG)
1008 {
1009 static XLogReaderState *debug_reader = NULL;
1010 XLogRecord *record;
1011 DecodedXLogRecord *decoded;
1013 StringInfoData recordBuf;
1014 char *errormsg = NULL;
1015 MemoryContext oldCxt;
1016
1017 oldCxt = MemoryContextSwitchTo(walDebugCxt);
1018
1020 appendStringInfo(&buf, "INSERT @ %X/%08X: ", LSN_FORMAT_ARGS(EndPos));
1021
1022 /*
1023 * We have to piece together the WAL record data from the XLogRecData
1024 * entries, so that we can pass it to the rm_desc function as one
1025 * contiguous chunk.
1026 */
1027 initStringInfo(&recordBuf);
1028 for (; rdata != NULL; rdata = rdata->next)
1029 appendBinaryStringInfo(&recordBuf, rdata->data, rdata->len);
1030
1031 /* We also need temporary space to decode the record. */
1032 record = (XLogRecord *) recordBuf.data;
1033 decoded = (DecodedXLogRecord *)
1035
1036 if (!debug_reader)
1037 debug_reader = XLogReaderAllocate(wal_segment_size, NULL,
1038 XL_ROUTINE(.page_read = NULL,
1039 .segment_open = NULL,
1040 .segment_close = NULL),
1041 NULL);
1042 if (!debug_reader)
1043 {
1044 appendStringInfoString(&buf, "error decoding record: out of memory while allocating a WAL reading processor");
1045 }
1046 else if (!DecodeXLogRecord(debug_reader,
1047 decoded,
1048 record,
1049 EndPos,
1050 &errormsg))
1051 {
1052 appendStringInfo(&buf, "error decoding record: %s",
1053 errormsg ? errormsg : "no error message");
1054 }
1055 else
1056 {
1057 appendStringInfoString(&buf, " - ");
1058
1059 debug_reader->record = decoded;
1060 xlog_outdesc(&buf, debug_reader);
1061 debug_reader->record = NULL;
1062 }
1063 elog(LOG, "%s", buf.data);
1064
1065 pfree(decoded);
1066 pfree(buf.data);
1067 pfree(recordBuf.data);
1068 MemoryContextSwitchTo(oldCxt);
1069 }
1070#endif
1071
1072 /*
1073 * Update our global variables
1074 */
1075 ProcLastRecPtr = StartPos;
1076 XactLastRecEnd = EndPos;
1077
1078 /* Report WAL traffic to the instrumentation. */
1079 if (inserted)
1080 {
1081 pgWalUsage.wal_bytes += rechdr->xl_tot_len;
1083 pgWalUsage.wal_fpi += num_fpi;
1084
1085 /* Required for the flush of pending stats WAL data */
1086 pgstat_report_fixed = true;
1087 }
1088
1089 return EndPos;
1090}
#define likely(x)
Definition: c.h:402
#define unlikely(x)
Definition: c.h:403
WalUsage pgWalUsage
Definition: instrument.c:22
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
bool pgstat_report_fixed
Definition: pgstat.c:218
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:281
uint64 wal_bytes
Definition: instrument.h:55
int64 wal_fpi
Definition: instrument.h:54
int64 wal_records
Definition: instrument.h:53
DecodedXLogRecord * record
Definition: xlogreader.h:236
const void * data
struct XLogRecData * next
pg_crc32c xl_crc
Definition: xlogrecord.h:49
void MarkSubxactTopXidLogged(void)
Definition: xact.c:591
void MarkCurrentTransactionIdLoggedIfAny(void)
Definition: xact.c:541
XLogRecPtr XactLastRecEnd
Definition: xlog.c:255
static void WALInsertLockAcquire(void)
Definition: xlog.c:1374
static void CopyXLogRecordToWAL(int write_len, bool isLogSwitch, XLogRecData *rdata, XLogRecPtr StartPos, XLogRecPtr EndPos, TimeLineID tli)
Definition: xlog.c:1228
static bool holdingAllLocks
Definition: xlog.c:652
static int MyLockNo
Definition: xlog.c:651
WalInsertClass
Definition: xlog.c:560
@ WALINSERT_SPECIAL_SWITCH
Definition: xlog.c:562
@ WALINSERT_NORMAL
Definition: xlog.c:561
@ WALINSERT_SPECIAL_CHECKPOINT
Definition: xlog.c:563
static void ReserveXLogInsertLocation(int size, XLogRecPtr *StartPos, XLogRecPtr *EndPos, XLogRecPtr *PrevPtr)
Definition: xlog.c:1111
static bool ReserveXLogSwitch(XLogRecPtr *StartPos, XLogRecPtr *EndPos, XLogRecPtr *PrevPtr)
Definition: xlog.c:1167
#define XLOG_MARK_UNIMPORTANT
Definition: xlog.h:155
XLogReaderState * XLogReaderAllocate(int wal_segment_size, const char *waldir, XLogReaderRoutine *routine, void *private_data)
Definition: xlogreader.c:107
bool DecodeXLogRecord(XLogReaderState *state, DecodedXLogRecord *decoded, XLogRecord *record, XLogRecPtr lsn, char **errormsg)
Definition: xlogreader.c:1682
size_t DecodeXLogRecordRequiredSpace(size_t xl_tot_len)
Definition: xlogreader.c:1649
#define XL_ROUTINE(...)
Definition: xlogreader.h:117
void xlog_outdesc(StringInfo buf, XLogReaderState *record)

References appendBinaryStringInfo(), appendStringInfo(), appendStringInfoString(), Assert(), buf, COMP_CRC32C, CopyXLogRecordToWAL(), XLogRecData::data, StringInfoData::data, DecodeXLogRecord(), DecodeXLogRecordRequiredSpace(), doPageWrites, elog, END_CRIT_SECTION, ERROR, FIN_CRC32C, holdingAllLocks, if(), XLogCtlData::info_lck, initStringInfo(), XLogCtlData::Insert, Insert(), XLogCtlData::InsertTimeLineID, InvalidXLogRecPtr, WALInsertLockPadded::l, WALInsertLock::lastImportantAt, XLogRecData::len, likely, LOG, LogwrtResult, XLogCtlData::LogwrtRqst, LSN_FORMAT_ARGS, MarkCurrentTransactionIdLoggedIfAny(), MarkSubxactTopXidLogged(), MemoryContextSwitchTo(), MyLockNo, XLogRecData::next, palloc(), pfree(), pgstat_report_fixed, pgWalUsage, ProcLastRecPtr, XLogReaderState::record, RedoRecPtr, RefreshXLogWriteResult, ReserveXLogInsertLocation(), ReserveXLogSwitch(), SizeOfXLogLongPHD, SizeOfXLogRecord, SizeOfXLogShortPHD, SpinLockAcquire, SpinLockRelease, START_CRIT_SECTION, unlikely, WalUsage::wal_bytes, WalUsage::wal_fpi, WalUsage::wal_records, wal_segment_size, WALINSERT_NORMAL, WALINSERT_SPECIAL_CHECKPOINT, WALINSERT_SPECIAL_SWITCH, WALInsertLockAcquire(), WALInsertLockAcquireExclusive(), WALInsertLockRelease(), WALInsertLocks, XLogwrtRqst::Write, XactLastRecEnd, XLogRecord::xl_crc, XLogRecord::xl_info, XLogRecord::xl_prev, XLogRecord::xl_rmid, XL_ROUTINE, XLogRecord::xl_tot_len, XLOG_CHECKPOINT_REDO, XLOG_MARK_UNIMPORTANT, xlog_outdesc(), XLOG_SWITCH, XLogCtl, XLogFlush(), XLogInsertAllowed(), XLogReaderAllocate(), XLogSegmentOffset, and XLR_INFO_MASK.

Referenced by XLogInsert().

◆ XLogNeedsFlush()

bool XLogNeedsFlush ( XLogRecPtr  record)

Definition at line 3124 of file xlog.c.

3125{
3126 /*
3127 * During recovery, we don't flush WAL but update minRecoveryPoint
3128 * instead. So "needs flush" is taken to mean whether minRecoveryPoint
3129 * would need to be updated.
3130 *
3131 * Using XLogInsertAllowed() rather than RecoveryInProgress() matters for
3132 * the case of an end-of-recovery checkpoint, where WAL data is flushed.
3133 * This check should be consistent with the one in XLogFlush().
3134 */
3135 if (!XLogInsertAllowed())
3136 {
3137 /*
3138 * An invalid minRecoveryPoint means that we need to recover all the
3139 * WAL, i.e., we're doing crash recovery. We never modify the control
3140 * file's value in that case, so we can short-circuit future checks
3141 * here too. This triggers a quick exit path for the startup process,
3142 * which cannot update its local copy of minRecoveryPoint as long as
3143 * it has not replayed all WAL available when doing crash recovery.
3144 */
3146 updateMinRecoveryPoint = false;
3147
3148 /* Quick exit if already known to be updated or cannot be updated */
3150 return false;
3151
3152 /*
3153 * Update local copy of minRecoveryPoint. But if the lock is busy,
3154 * just return a conservative guess.
3155 */
3156 if (!LWLockConditionalAcquire(ControlFileLock, LW_SHARED))
3157 return true;
3160 LWLockRelease(ControlFileLock);
3161
3162 /*
3163 * Check minRecoveryPoint for any other process than the startup
3164 * process doing crash recovery, which should not update the control
3165 * file value if crash recovery is still running.
3166 */
3168 updateMinRecoveryPoint = false;
3169
3170 /* check again */
3172 return false;
3173 else
3174 return true;
3175 }
3176
3177 /* Quick exit if already known flushed */
3178 if (record <= LogwrtResult.Flush)
3179 return false;
3180
3181 /* read LogwrtResult and update local state */
3183
3184 /* check again */
3185 if (record <= LogwrtResult.Flush)
3186 return false;
3187
3188 return true;
3189}
bool LWLockConditionalAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1345

References ControlFile, XLogwrtResult::Flush, InRecovery, LocalMinRecoveryPoint, LocalMinRecoveryPointTLI, LogwrtResult, LW_SHARED, LWLockConditionalAcquire(), LWLockRelease(), ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, RefreshXLogWriteResult, updateMinRecoveryPoint, XLogInsertAllowed(), and XLogRecPtrIsInvalid.

Referenced by GetVictimBuffer(), SetHintBits(), and XLogFlush().

◆ XLogPutNextOid()

void XLogPutNextOid ( Oid  nextOid)

Definition at line 8070 of file xlog.c.

8071{
8073 XLogRegisterData(&nextOid, sizeof(Oid));
8074 (void) XLogInsert(RM_XLOG_ID, XLOG_NEXTOID);
8075
8076 /*
8077 * We need not flush the NEXTOID record immediately, because any of the
8078 * just-allocated OIDs could only reach disk as part of a tuple insert or
8079 * update that would have its own XLOG record that must follow the NEXTOID
8080 * record. Therefore, the standard buffer LSN interlock applied to those
8081 * records will ensure no such OID reaches disk before the NEXTOID record
8082 * does.
8083 *
8084 * Note, however, that the above statement only covers state "within" the
8085 * database. When we use a generated OID as a file or directory name, we
8086 * are in a sense violating the basic WAL rule, because that filesystem
8087 * change may reach disk before the NEXTOID WAL record does. The impact
8088 * of this is that if a database crash occurs immediately afterward, we
8089 * might after restart re-generate the same OID and find that it conflicts
8090 * with the leftover file or directory. But since for safety's sake we
8091 * always loop until finding a nonconflicting filename, this poses no real
8092 * problem in practice. See pgsql-hackers discussion 27-Sep-2006.
8093 */
8094}

References XLOG_NEXTOID, XLogBeginInsert(), XLogInsert(), and XLogRegisterData().

Referenced by GetNewObjectId().

◆ XLogRestorePoint()

XLogRecPtr XLogRestorePoint ( const char *  rpName)

Definition at line 8125 of file xlog.c.

8126{
8127 XLogRecPtr RecPtr;
8128 xl_restore_point xlrec;
8129
8130 xlrec.rp_time = GetCurrentTimestamp();
8131 strlcpy(xlrec.rp_name, rpName, MAXFNAMELEN);
8132
8134 XLogRegisterData(&xlrec, sizeof(xl_restore_point));
8135
8136 RecPtr = XLogInsert(RM_XLOG_ID, XLOG_RESTORE_POINT);
8137
8138 ereport(LOG,
8139 errmsg("restore point \"%s\" created at %X/%08X",
8140 rpName, LSN_FORMAT_ARGS(RecPtr)));
8141
8142 return RecPtr;
8143}
TimestampTz rp_time

References ereport, errmsg(), GetCurrentTimestamp(), LOG, LSN_FORMAT_ARGS, MAXFNAMELEN, xl_restore_point::rp_name, xl_restore_point::rp_time, strlcpy(), XLOG_RESTORE_POINT, XLogBeginInsert(), XLogInsert(), and XLogRegisterData().

Referenced by pg_create_restore_point().

◆ XLogSetAsyncXactLSN()

void XLogSetAsyncXactLSN ( XLogRecPtr  asyncXactLSN)

Definition at line 2609 of file xlog.c.

2610{
2611 XLogRecPtr WriteRqstPtr = asyncXactLSN;
2612 bool sleeping;
2613 bool wakeup = false;
2614 XLogRecPtr prevAsyncXactLSN;
2615
2617 sleeping = XLogCtl->WalWriterSleeping;
2618 prevAsyncXactLSN = XLogCtl->asyncXactLSN;
2619 if (XLogCtl->asyncXactLSN < asyncXactLSN)
2620 XLogCtl->asyncXactLSN = asyncXactLSN;
2622
2623 /*
2624 * If somebody else already called this function with a more aggressive
2625 * LSN, they will have done what we needed (and perhaps more).
2626 */
2627 if (asyncXactLSN <= prevAsyncXactLSN)
2628 return;
2629
2630 /*
2631 * If the WALWriter is sleeping, kick it to make it come out of low-power
2632 * mode, so that this async commit will reach disk within the expected
2633 * amount of time. Otherwise, determine whether it has enough WAL
2634 * available to flush, the same way that XLogBackgroundFlush() does.
2635 */
2636 if (sleeping)
2637 wakeup = true;
2638 else
2639 {
2640 int flushblocks;
2641
2643
2644 flushblocks =
2645 WriteRqstPtr / XLOG_BLCKSZ - LogwrtResult.Flush / XLOG_BLCKSZ;
2646
2647 if (WalWriterFlushAfter == 0 || flushblocks >= WalWriterFlushAfter)
2648 wakeup = true;
2649 }
2650
2651 if (wakeup)
2652 {
2653 volatile PROC_HDR *procglobal = ProcGlobal;
2654 ProcNumber walwriterProc = procglobal->walwriterProc;
2655
2656 if (walwriterProc != INVALID_PROC_NUMBER)
2657 SetLatch(&GetPGProcByNumber(walwriterProc)->procLatch);
2658 }
2659}
void SetLatch(Latch *latch)
Definition: latch.c:290
#define GetPGProcByNumber(n)
Definition: proc.h:440
#define INVALID_PROC_NUMBER
Definition: procnumber.h:26
int ProcNumber
Definition: procnumber.h:24
PROC_HDR * ProcGlobal
Definition: proc.c:78
Definition: proc.h:386
ProcNumber walwriterProc
Definition: proc.h:424
static TimestampTz wakeup[NUM_WALRCV_WAKEUPS]
Definition: walreceiver.c:130

References XLogCtlData::asyncXactLSN, XLogwrtResult::Flush, GetPGProcByNumber, XLogCtlData::info_lck, INVALID_PROC_NUMBER, LogwrtResult, ProcGlobal, RefreshXLogWriteResult, SetLatch(), SpinLockAcquire, SpinLockRelease, wakeup, WalWriterFlushAfter, PROC_HDR::walwriterProc, XLogCtlData::WalWriterSleeping, and XLogCtl.

Referenced by AbortTransaction(), LogCurrentRunningXacts(), RecordTransactionAbort(), and RecordTransactionCommit().

◆ XLogSetReplicationSlotMinimumLSN()

void XLogSetReplicationSlotMinimumLSN ( XLogRecPtr  lsn)

◆ XLOGShmemInit()

void XLOGShmemInit ( void  )

Definition at line 4957 of file xlog.c.

4958{
4959 bool foundCFile,
4960 foundXLog;
4961 char *allocptr;
4962 int i;
4963 ControlFileData *localControlFile;
4964
4965#ifdef WAL_DEBUG
4966
4967 /*
4968 * Create a memory context for WAL debugging that's exempt from the normal
4969 * "no pallocs in critical section" rule. Yes, that can lead to a PANIC if
4970 * an allocation fails, but wal_debug is not for production use anyway.
4971 */
4972 if (walDebugCxt == NULL)
4973 {
4975 "WAL Debug",
4977 MemoryContextAllowInCriticalSection(walDebugCxt, true);
4978 }
4979#endif
4980
4981
4982 XLogCtl = (XLogCtlData *)
4983 ShmemInitStruct("XLOG Ctl", XLOGShmemSize(), &foundXLog);
4984
4985 localControlFile = ControlFile;
4987 ShmemInitStruct("Control File", sizeof(ControlFileData), &foundCFile);
4988
4989 if (foundCFile || foundXLog)
4990 {
4991 /* both should be present or neither */
4992 Assert(foundCFile && foundXLog);
4993
4994 /* Initialize local copy of WALInsertLocks */
4996
4997 if (localControlFile)
4998 pfree(localControlFile);
4999 return;
5000 }
5001 memset(XLogCtl, 0, sizeof(XLogCtlData));
5002
5003 /*
5004 * Already have read control file locally, unless in bootstrap mode. Move
5005 * contents into shared memory.
5006 */
5007 if (localControlFile)
5008 {
5009 memcpy(ControlFile, localControlFile, sizeof(ControlFileData));
5010 pfree(localControlFile);
5011 }
5012
5013 /*
5014 * Since XLogCtlData contains XLogRecPtr fields, its sizeof should be a
5015 * multiple of the alignment for same, so no extra alignment padding is
5016 * needed here.
5017 */
5018 allocptr = ((char *) XLogCtl) + sizeof(XLogCtlData);
5019 XLogCtl->xlblocks = (pg_atomic_uint64 *) allocptr;
5020 allocptr += sizeof(pg_atomic_uint64) * XLOGbuffers;
5021
5022 for (i = 0; i < XLOGbuffers; i++)
5023 {
5025 }
5026
5027 /* WAL insertion locks. Ensure they're aligned to the full padded size */
5028 allocptr += sizeof(WALInsertLockPadded) -
5029 ((uintptr_t) allocptr) % sizeof(WALInsertLockPadded);
5031 (WALInsertLockPadded *) allocptr;
5032 allocptr += sizeof(WALInsertLockPadded) * NUM_XLOGINSERT_LOCKS;
5033
5034 for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
5035 {
5036 LWLockInitialize(&WALInsertLocks[i].l.lock, LWTRANCHE_WAL_INSERT);
5039 }
5040
5041 /*
5042 * Align the start of the page buffers to a full xlog block size boundary.
5043 * This simplifies some calculations in XLOG insertion. It is also
5044 * required for O_DIRECT.
5045 */
5046 allocptr = (char *) TYPEALIGN(XLOG_BLCKSZ, allocptr);
5047 XLogCtl->pages = allocptr;
5048 memset(XLogCtl->pages, 0, (Size) XLOG_BLCKSZ * XLOGbuffers);
5049
5050 /*
5051 * Do basic initialization of XLogCtl shared data. (StartupXLOG will fill
5052 * in additional info.)
5053 */
5057 XLogCtl->WalWriterSleeping = false;
5058
5065}
static void pg_atomic_init_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:451
struct pg_atomic_uint64 pg_atomic_uint64
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition: lwlock.c:698
MemoryContext TopMemoryContext
Definition: mcxt.c:166
void MemoryContextAllowInCriticalSection(MemoryContext context, bool allow)
Definition: mcxt.c:740
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:387
#define SpinLockInit(lock)
Definition: spin.h:57
int XLogCacheBlck
Definition: xlog.c:494
WALInsertLockPadded * WALInsertLocks
Definition: xlog.c:445
slock_t insertpos_lck
Definition: xlog.c:399
union WALInsertLockPadded WALInsertLockPadded
Size XLOGShmemSize(void)
Definition: xlog.c:4907
int XLOGbuffers
Definition: xlog.c:118
struct XLogCtlData XLogCtlData

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert(), ControlFile, i, XLogCtlData::info_lck, XLogCtlData::Insert, XLogCtlInsert::insertpos_lck, XLogCtlData::InstallXLogFileSegmentActive, InvalidXLogRecPtr, WALInsertLockPadded::l, WALInsertLock::lastImportantAt, XLogCtlData::logFlushResult, XLogCtlData::logInsertResult, XLogCtlData::logWriteResult, LWLockInitialize(), MemoryContextAllowInCriticalSection(), NUM_XLOGINSERT_LOCKS, XLogCtlData::pages, pfree(), pg_atomic_init_u64(), RECOVERY_STATE_CRASH, XLogCtlData::SharedRecoveryState, ShmemInitStruct(), SpinLockInit, TopMemoryContext, TYPEALIGN, XLogCtlData::unloggedLSN, XLogCtlInsert::WALInsertLocks, WALInsertLocks, XLogCtlData::WalWriterSleeping, XLogCtlData::xlblocks, XLOGbuffers, XLogCtlData::XLogCacheBlck, XLogCtl, and XLOGShmemSize().

Referenced by CreateOrAttachShmemStructs().

◆ XLOGShmemSize()

Size XLOGShmemSize ( void  )

Definition at line 4907 of file xlog.c.

4908{
4909 Size size;
4910
4911 /*
4912 * If the value of wal_buffers is -1, use the preferred auto-tune value.
4913 * This isn't an amazingly clean place to do this, but we must wait till
4914 * NBuffers has received its final value, and must do it before using the
4915 * value of XLOGbuffers to do anything important.
4916 *
4917 * We prefer to report this value's source as PGC_S_DYNAMIC_DEFAULT.
4918 * However, if the DBA explicitly set wal_buffers = -1 in the config file,
4919 * then PGC_S_DYNAMIC_DEFAULT will fail to override that and we must force
4920 * the matter with PGC_S_OVERRIDE.
4921 */
4922 if (XLOGbuffers == -1)
4923 {
4924 char buf[32];
4925
4926 snprintf(buf, sizeof(buf), "%d", XLOGChooseNumBuffers());
4927 SetConfigOption("wal_buffers", buf, PGC_POSTMASTER,
4929 if (XLOGbuffers == -1) /* failed to apply it? */
4930 SetConfigOption("wal_buffers", buf, PGC_POSTMASTER,
4932 }
4933 Assert(XLOGbuffers > 0);
4934
4935 /* XLogCtl */
4936 size = sizeof(XLogCtlData);
4937
4938 /* WAL insertion locks, plus alignment */
4939 size = add_size(size, mul_size(sizeof(WALInsertLockPadded), NUM_XLOGINSERT_LOCKS + 1));
4940 /* xlblocks array */
4941 size = add_size(size, mul_size(sizeof(pg_atomic_uint64), XLOGbuffers));
4942 /* extra alignment padding for XLOG I/O buffers */
4943 size = add_size(size, Max(XLOG_BLCKSZ, PG_IO_ALIGN_SIZE));
4944 /* and the buffers themselves */
4945 size = add_size(size, mul_size(XLOG_BLCKSZ, XLOGbuffers));
4946
4947 /*
4948 * Note: we don't count ControlFileData, it comes out of the "slop factor"
4949 * added by CreateSharedMemoryAndSemaphores. This lets us use this
4950 * routine again below to compute the actual allocation size.
4951 */
4952
4953 return size;
4954}
#define Max(x, y)
Definition: c.h:998
void SetConfigOption(const char *name, const char *value, GucContext context, GucSource source)
Definition: guc.c:4337
@ PGC_S_DYNAMIC_DEFAULT
Definition: guc.h:114
@ PGC_S_OVERRIDE
Definition: guc.h:123
@ PGC_POSTMASTER
Definition: guc.h:74
#define PG_IO_ALIGN_SIZE
Size add_size(Size s1, Size s2)
Definition: shmem.c:493
Size mul_size(Size s1, Size s2)
Definition: shmem.c:510
static int XLOGChooseNumBuffers(void)
Definition: xlog.c:4658

References add_size(), Assert(), buf, Max, mul_size(), NUM_XLOGINSERT_LOCKS, PG_IO_ALIGN_SIZE, PGC_POSTMASTER, PGC_S_DYNAMIC_DEFAULT, PGC_S_OVERRIDE, SetConfigOption(), snprintf, XLOGbuffers, and XLOGChooseNumBuffers().

Referenced by CalculateShmemSize(), and XLOGShmemInit().

◆ XLogShutdownWalRcv()

void XLogShutdownWalRcv ( void  )

Definition at line 9514 of file xlog.c.

9515{
9517
9518 LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9520 LWLockRelease(ControlFileLock);
9521}
void ShutdownWalRcv(void)

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

Referenced by FinishWalRecovery(), and WaitForWALToBecomeAvailable().

Variable Documentation

◆ CheckPointSegments

PGDLLIMPORT int CheckPointSegments
extern

◆ CheckpointStats

◆ CommitDelay

PGDLLIMPORT int CommitDelay
extern

Definition at line 133 of file xlog.c.

Referenced by XLogFlush().

◆ CommitSiblings

PGDLLIMPORT int CommitSiblings
extern

Definition at line 134 of file xlog.c.

Referenced by XLogFlush().

◆ EnableHotStandby

◆ fullPageWrites

PGDLLIMPORT bool fullPageWrites
extern

Definition at line 123 of file xlog.c.

Referenced by BootStrapXLOG(), and UpdateFullPageWrites().

◆ log_checkpoints

PGDLLIMPORT bool log_checkpoints
extern

◆ max_slot_wal_keep_size_mb

PGDLLIMPORT int max_slot_wal_keep_size_mb
extern

Definition at line 136 of file xlog.c.

Referenced by KeepLogSeg(), and pg_get_replication_slots().

◆ max_wal_size_mb

PGDLLIMPORT int max_wal_size_mb
extern

◆ min_wal_size_mb

PGDLLIMPORT int min_wal_size_mb
extern

Definition at line 116 of file xlog.c.

Referenced by ReadControlFile(), and XLOGfileslop().

◆ ProcLastRecPtr

PGDLLIMPORT XLogRecPtr ProcLastRecPtr
extern

◆ track_wal_io_timing

PGDLLIMPORT bool track_wal_io_timing
extern

◆ wal_compression

PGDLLIMPORT int wal_compression
extern

Definition at line 125 of file xlog.c.

Referenced by XLogCompressBackupBlock(), and XLogRecordAssemble().

◆ wal_consistency_checking

PGDLLIMPORT bool* wal_consistency_checking
extern

Definition at line 127 of file xlog.c.

Referenced by assign_wal_consistency_checking(), and XLogRecordAssemble().

◆ wal_consistency_checking_string

PGDLLIMPORT char* wal_consistency_checking_string
extern

Definition at line 126 of file xlog.c.

Referenced by InitializeWalConsistencyChecking().

◆ wal_decode_buffer_size

PGDLLIMPORT int wal_decode_buffer_size
extern

Definition at line 137 of file xlog.c.

Referenced by InitWalRecovery().

◆ wal_init_zero

PGDLLIMPORT bool wal_init_zero
extern

Definition at line 128 of file xlog.c.

Referenced by XLogFileInitInternal().

◆ wal_keep_size_mb

PGDLLIMPORT int wal_keep_size_mb
extern

Definition at line 117 of file xlog.c.

Referenced by KeepLogSeg(), and pg_get_replication_slots().

◆ wal_level

◆ wal_log_hints

PGDLLIMPORT bool wal_log_hints
extern

Definition at line 124 of file xlog.c.

Referenced by InitControlFile(), and XLogReportParameters().

◆ wal_recycle

PGDLLIMPORT bool wal_recycle
extern

Definition at line 129 of file xlog.c.

Referenced by RemoveXlogFile().

◆ wal_retrieve_retry_interval

PGDLLIMPORT int wal_retrieve_retry_interval
extern

◆ wal_segment_size

PGDLLIMPORT int wal_segment_size
extern

Definition at line 144 of file xlog.c.

Referenced by AdvanceXLInsertBuffer(), assign_wal_sync_method(), BootStrapXLOG(), build_backup_content(), CalculateCheckpointSegments(), CheckArchiveTimeout(), CheckXLogRemoved(), CleanupAfterArchiveRecovery(), copy_replication_slot(), CopyXLogRecordToWAL(), CreateCheckPoint(), CreateOverwriteContrecordRecord(), CreateRestartPoint(), do_pg_backup_stop(), ExecuteRecoveryCommand(), FinishWalRecovery(), GetOldestUnsummarizedLSN(), GetWALAvailability(), GetXLogBuffer(), InitWalRecovery(), InitXLogReaderState(), InstallXLogFileSegment(), InvalidateObsoleteReplicationSlots(), IsCheckpointOnSchedule(), issue_xlog_fsync(), KeepLogSeg(), LogicalConfirmReceivedLocation(), MaybeRemoveOldWalSummaries(), perform_base_backup(), pg_control_checkpoint(), pg_get_replication_slots(), pg_split_walfile_name(), pg_walfile_name(), pg_walfile_name_offset(), PreallocXlogFiles(), ReadControlFile(), ReadRecord(), RemoveNonParentXlogFiles(), RemoveOldXlogFiles(), ReorderBufferRestoreChanges(), ReorderBufferRestoreCleanup(), ReorderBufferSerializedPath(), ReorderBufferSerializeTXN(), ReplicationSlotReserveWal(), RequestXLogStreaming(), reserve_wal_for_local_slot(), ReserveXLogSwitch(), RestoreArchivedFile(), StartReplication(), StartupDecodingContext(), SummarizeWAL(), UpdateLastRemovedPtr(), WALReadRaiseError(), WalReceiverMain(), WalSndSegmentOpen(), WriteControlFile(), XLogArchiveNotifySeg(), XLogBackgroundFlush(), XLogBytePosToEndRecPtr(), XLogBytePosToRecPtr(), XLogCheckpointNeeded(), XLOGChooseNumBuffers(), XLogFileClose(), XLogFileCopy(), XLogFileInitInternal(), XLogFileOpen(), XLogFileRead(), XLogFileReadAnyTLI(), XLOGfileslop(), XLogGetOldestSegno(), XLogInitNewTimeline(), XLogInsertRecord(), XLogPageRead(), XLogReaderAllocate(), XlogReadTwoPhaseData(), XLogRecPtrToBytePos(), XLogWalRcvClose(), XLogWalRcvWrite(), and XLogWrite().

◆ wal_sync_method

PGDLLIMPORT int wal_sync_method
extern

◆ XactLastCommitEnd

◆ XactLastRecEnd

◆ XLogArchiveCommand

PGDLLIMPORT char* XLogArchiveCommand
extern

◆ XLogArchiveMode

◆ XLogArchiveTimeout

PGDLLIMPORT int XLogArchiveTimeout
extern

Definition at line 119 of file xlog.c.

Referenced by CheckArchiveTimeout(), and CheckpointerMain().

◆ XLOGbuffers

PGDLLIMPORT int XLOGbuffers
extern

Definition at line 118 of file xlog.c.

Referenced by check_wal_buffers(), XLOGShmemInit(), and XLOGShmemSize().