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, uint64 fpi_bytes, 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 ResetInstallXLogFileSegmentActive (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 305 of file xlog.h.

◆ BACKUP_LABEL_OLD

#define BACKUP_LABEL_OLD   "backup_label.old"

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

◆ RECOVERY_SIGNAL_FILE

#define RECOVERY_SIGNAL_FILE   "recovery.signal"

Definition at line 303 of file xlog.h.

◆ STANDBY_SIGNAL_FILE

#define STANDBY_SIGNAL_FILE   "standby.signal"

Definition at line 304 of file xlog.h.

◆ TABLESPACE_MAP

#define TABLESPACE_MAP   "tablespace_map"

Definition at line 308 of file xlog.h.

◆ TABLESPACE_MAP_OLD

#define TABLESPACE_MAP_OLD   "tablespace_map.old"

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

290{
@ SESSION_BACKUP_RUNNING
Definition: xlog.h:291
@ SESSION_BACKUP_NONE
Definition: xlog.h:290

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

5092{
5093 CheckPoint checkPoint;
5094 PGAlignedXLogBlock buffer;
5095 XLogPageHeader page;
5096 XLogLongPageHeader longpage;
5097 XLogRecord *record;
5098 char *recptr;
5099 uint64 sysidentifier;
5100 struct timeval tv;
5101 pg_crc32c crc;
5102
5103 /* allow ordinary WAL segment creation, like StartupXLOG() would */
5105
5106 /*
5107 * Select a hopefully-unique system identifier code for this installation.
5108 * We use the result of gettimeofday(), including the fractional seconds
5109 * field, as being about as unique as we can easily get. (Think not to
5110 * use random(), since it hasn't been seeded and there's no portable way
5111 * to seed it other than the system clock value...) The upper half of the
5112 * uint64 value is just the tv_sec part, while the lower half contains the
5113 * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
5114 * PID for a little extra uniqueness. A person knowing this encoding can
5115 * determine the initialization time of the installation, which could
5116 * perhaps be useful sometimes.
5117 */
5118 gettimeofday(&tv, NULL);
5119 sysidentifier = ((uint64) tv.tv_sec) << 32;
5120 sysidentifier |= ((uint64) tv.tv_usec) << 12;
5121 sysidentifier |= getpid() & 0xFFF;
5122
5123 memset(&buffer, 0, sizeof buffer);
5124 page = (XLogPageHeader) &buffer;
5125
5126 /*
5127 * Set up information for the initial checkpoint record
5128 *
5129 * The initial checkpoint record is written to the beginning of the WAL
5130 * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5131 * used, so that we can use 0/0 to mean "before any valid WAL segment".
5132 */
5136 checkPoint.fullPageWrites = fullPageWrites;
5137 checkPoint.wal_level = wal_level;
5138 checkPoint.nextXid =
5140 checkPoint.nextOid = FirstGenbkiObjectId;
5141 checkPoint.nextMulti = FirstMultiXactId;
5142 checkPoint.nextMultiOffset = 1;
5144 checkPoint.oldestXidDB = Template1DbOid;
5145 checkPoint.oldestMulti = FirstMultiXactId;
5146 checkPoint.oldestMultiDB = Template1DbOid;
5149 checkPoint.time = (pg_time_t) time(NULL);
5151
5152 TransamVariables->nextXid = checkPoint.nextXid;
5153 TransamVariables->nextOid = checkPoint.nextOid;
5155 MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5156 AdvanceOldestClogXid(checkPoint.oldestXid);
5157 SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5158 SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB);
5160
5161 /* Set up the XLOG page header */
5162 page->xlp_magic = XLOG_PAGE_MAGIC;
5163 page->xlp_info = XLP_LONG_HEADER;
5166 longpage = (XLogLongPageHeader) page;
5167 longpage->xlp_sysid = sysidentifier;
5168 longpage->xlp_seg_size = wal_segment_size;
5169 longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5170
5171 /* Insert the initial checkpoint record */
5172 recptr = ((char *) page + SizeOfXLogLongPHD);
5173 record = (XLogRecord *) recptr;
5174 record->xl_prev = 0;
5175 record->xl_xid = InvalidTransactionId;
5176 record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5178 record->xl_rmid = RM_XLOG_ID;
5179 recptr += SizeOfXLogRecord;
5180 /* fill the XLogRecordDataHeaderShort struct */
5181 *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5182 *(recptr++) = sizeof(checkPoint);
5183 memcpy(recptr, &checkPoint, sizeof(checkPoint));
5184 recptr += sizeof(checkPoint);
5185 Assert(recptr - (char *) record == record->xl_tot_len);
5186
5188 COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5189 COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5190 FIN_CRC32C(crc);
5191 record->xl_crc = crc;
5192
5193 /* Create first XLOG segment file */
5196
5197 /*
5198 * We needn't bother with Reserve/ReleaseExternalFD here, since we'll
5199 * close the file again in a moment.
5200 */
5201
5202 /* Write the first page with the initial record */
5203 errno = 0;
5204 pgstat_report_wait_start(WAIT_EVENT_WAL_BOOTSTRAP_WRITE);
5205 if (write(openLogFile, &buffer, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5206 {
5207 /* if write didn't set errno, assume problem is no disk space */
5208 if (errno == 0)
5209 errno = ENOSPC;
5210 ereport(PANIC,
5212 errmsg("could not write bootstrap write-ahead log file: %m")));
5213 }
5215
5216 pgstat_report_wait_start(WAIT_EVENT_WAL_BOOTSTRAP_SYNC);
5217 if (pg_fsync(openLogFile) != 0)
5218 ereport(PANIC,
5220 errmsg("could not fsync bootstrap write-ahead log file: %m")));
5222
5223 if (close(openLogFile) != 0)
5224 ereport(PANIC,
5226 errmsg("could not close bootstrap write-ahead log file: %m")));
5227
5228 openLogFile = -1;
5229
5230 /* Now create pg_control */
5231 InitControlFile(sysidentifier, data_checksum_version);
5232 ControlFile->time = checkPoint.time;
5233 ControlFile->checkPoint = checkPoint.redo;
5234 ControlFile->checkPointCopy = checkPoint;
5235
5236 /* some additional ControlFile fields are set in WriteControlFile() */
5238
5239 /* Bootstrap the commit log, too */
5240 BootStrapCLOG();
5244
5245 /*
5246 * Force control file to be read - in contrast to normal processing we'd
5247 * otherwise never run the checks and GUC related initializations therein.
5248 */
5250}
uint64_t uint64
Definition: c.h:553
void BootStrapCLOG(void)
Definition: clog.c:832
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:886
int errmsg(const char *fmt,...)
Definition: elog.c:1080
#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 MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset)
Definition: multixact.c:1989
void BootStrapMultiXact(void)
Definition: multixact.c:1790
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid)
Definition: multixact.c:2011
#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:3401
bool fullPageWrites
Definition: xlog.c:124
static void InitControlFile(uint64 sysidentifier, uint32 data_checksum_version)
Definition: xlog.c:4225
void SetInstallXLogFileSegmentActive(void)
Definition: xlog.c:9545
static int openLogFile
Definition: xlog.c:636
int wal_level
Definition: xlog.c:133
static void WriteControlFile(void)
Definition: xlog.c:4260
int wal_segment_size
Definition: xlog.c:145
static TimeLineID openLogTLI
Definition: xlog.c:638
static ControlFileData * ControlFile
Definition: xlog.c:575
#define BootstrapTimeLineID
Definition: xlog.c:113
static void ReadControlFile(void)
Definition: xlog.c:4370
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, PANIC, 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, 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 3748 of file xlog.c.

3749{
3750 int save_errno = errno;
3751 XLogSegNo lastRemovedSegNo;
3752
3754 lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3756
3757 if (segno <= lastRemovedSegNo)
3758 {
3759 char filename[MAXFNAMELEN];
3760
3762 errno = save_errno;
3763 ereport(ERROR,
3765 errmsg("requested WAL segment %s has already been removed",
3766 filename)));
3767 }
3768 errno = save_errno;
3769}
#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:554
XLogSegNo lastRemovedSegNo
Definition: xlog.c:462
static XLogCtlData * XLogCtl
Definition: xlog.c:567
#define MAXFNAMELEN
static void XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
uint64 XLogSegNo
Definition: xlogdefs.h:52

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

6960{
6961 bool shutdown;
6962 CheckPoint checkPoint;
6963 XLogRecPtr recptr;
6964 XLogSegNo _logSegNo;
6966 uint32 freespace;
6967 XLogRecPtr PriorRedoPtr;
6968 XLogRecPtr last_important_lsn;
6969 VirtualTransactionId *vxids;
6970 int nvxids;
6971 int oldXLogAllowed = 0;
6972
6973 /*
6974 * An end-of-recovery checkpoint is really a shutdown checkpoint, just
6975 * issued at a different time.
6976 */
6978 shutdown = true;
6979 else
6980 shutdown = false;
6981
6982 /* sanity check */
6983 if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
6984 elog(ERROR, "can't create a checkpoint during recovery");
6985
6986 /*
6987 * Prepare to accumulate statistics.
6988 *
6989 * Note: because it is possible for log_checkpoints to change while a
6990 * checkpoint proceeds, we always accumulate stats, even if
6991 * log_checkpoints is currently off.
6992 */
6995
6996 /*
6997 * Let smgr prepare for checkpoint; this has to happen outside the
6998 * critical section and before we determine the REDO pointer. Note that
6999 * smgr must not do anything that'd have to be undone if we decide no
7000 * checkpoint is needed.
7001 */
7003
7004 /*
7005 * Use a critical section to force system panic if we have trouble.
7006 */
7008
7009 if (shutdown)
7010 {
7011 LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7014 LWLockRelease(ControlFileLock);
7015 }
7016
7017 /* Begin filling in the checkpoint WAL record */
7018 MemSet(&checkPoint, 0, sizeof(checkPoint));
7019 checkPoint.time = (pg_time_t) time(NULL);
7020
7021 /*
7022 * For Hot Standby, derive the oldestActiveXid before we fix the redo
7023 * pointer. This allows us to begin accumulating changes to assemble our
7024 * starting snapshot of locks and transactions.
7025 */
7026 if (!shutdown && XLogStandbyInfoActive())
7027 checkPoint.oldestActiveXid = GetOldestActiveTransactionId(false, true);
7028 else
7030
7031 /*
7032 * Get location of last important record before acquiring insert locks (as
7033 * GetLastImportantRecPtr() also locks WAL locks).
7034 */
7035 last_important_lsn = GetLastImportantRecPtr();
7036
7037 /*
7038 * If this isn't a shutdown or forced checkpoint, and if there has been no
7039 * WAL activity requiring a checkpoint, skip it. The idea here is to
7040 * avoid inserting duplicate checkpoints when the system is idle.
7041 */
7043 CHECKPOINT_FORCE)) == 0)
7044 {
7045 if (last_important_lsn == ControlFile->checkPoint)
7046 {
7049 (errmsg_internal("checkpoint skipped because system is idle")));
7050 return false;
7051 }
7052 }
7053
7054 /*
7055 * An end-of-recovery checkpoint is created before anyone is allowed to
7056 * write WAL. To allow us to write the checkpoint record, temporarily
7057 * enable XLogInsertAllowed.
7058 */
7059 if (flags & CHECKPOINT_END_OF_RECOVERY)
7060 oldXLogAllowed = LocalSetXLogInsertAllowed();
7061
7063 if (flags & CHECKPOINT_END_OF_RECOVERY)
7065 else
7066 checkPoint.PrevTimeLineID = checkPoint.ThisTimeLineID;
7067
7068 /*
7069 * We must block concurrent insertions while examining insert state.
7070 */
7072
7073 checkPoint.fullPageWrites = Insert->fullPageWrites;
7074 checkPoint.wal_level = wal_level;
7075
7076 if (shutdown)
7077 {
7078 XLogRecPtr curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
7079
7080 /*
7081 * Compute new REDO record ptr = location of next XLOG record.
7082 *
7083 * Since this is a shutdown checkpoint, there can't be any concurrent
7084 * WAL insertion.
7085 */
7086 freespace = INSERT_FREESPACE(curInsert);
7087 if (freespace == 0)
7088 {
7089 if (XLogSegmentOffset(curInsert, wal_segment_size) == 0)
7090 curInsert += SizeOfXLogLongPHD;
7091 else
7092 curInsert += SizeOfXLogShortPHD;
7093 }
7094 checkPoint.redo = curInsert;
7095
7096 /*
7097 * Here we update the shared RedoRecPtr for future XLogInsert calls;
7098 * this must be done while holding all the insertion locks.
7099 *
7100 * Note: if we fail to complete the checkpoint, RedoRecPtr will be
7101 * left pointing past where it really needs to point. This is okay;
7102 * the only consequence is that XLogInsert might back up whole buffers
7103 * that it didn't really need to. We can't postpone advancing
7104 * RedoRecPtr because XLogInserts that happen while we are dumping
7105 * buffers must assume that their buffer changes are not included in
7106 * the checkpoint.
7107 */
7108 RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
7109 }
7110
7111 /*
7112 * Now we can release the WAL insertion locks, allowing other xacts to
7113 * proceed while we are flushing disk buffers.
7114 */
7116
7117 /*
7118 * If this is an online checkpoint, we have not yet determined the redo
7119 * point. We do so now by inserting the special XLOG_CHECKPOINT_REDO
7120 * record; the LSN at which it starts becomes the new redo pointer. We
7121 * don't do this for a shutdown checkpoint, because in that case no WAL
7122 * can be written between the redo point and the insertion of the
7123 * checkpoint record itself, so the checkpoint record itself serves to
7124 * mark the redo point.
7125 */
7126 if (!shutdown)
7127 {
7128 /* Include WAL level in record for WAL summarizer's benefit. */
7131 (void) XLogInsert(RM_XLOG_ID, XLOG_CHECKPOINT_REDO);
7132
7133 /*
7134 * XLogInsertRecord will have updated XLogCtl->Insert.RedoRecPtr in
7135 * shared memory and RedoRecPtr in backend-local memory, but we need
7136 * to copy that into the record that will be inserted when the
7137 * checkpoint is complete.
7138 */
7139 checkPoint.redo = RedoRecPtr;
7140 }
7141
7142 /* Update the info_lck-protected copy of RedoRecPtr as well */
7144 XLogCtl->RedoRecPtr = checkPoint.redo;
7146
7147 /*
7148 * If enabled, log checkpoint start. We postpone this until now so as not
7149 * to log anything if we decided to skip the checkpoint.
7150 */
7151 if (log_checkpoints)
7152 LogCheckpointStart(flags, false);
7153
7154 /* Update the process title */
7155 update_checkpoint_display(flags, false, false);
7156
7157 TRACE_POSTGRESQL_CHECKPOINT_START(flags);
7158
7159 /*
7160 * Get the other info we need for the checkpoint record.
7161 *
7162 * We don't need to save oldestClogXid in the checkpoint, it only matters
7163 * for the short period in which clog is being truncated, and if we crash
7164 * during that we'll redo the clog truncation and fix up oldestClogXid
7165 * there.
7166 */
7167 LWLockAcquire(XidGenLock, LW_SHARED);
7168 checkPoint.nextXid = TransamVariables->nextXid;
7169 checkPoint.oldestXid = TransamVariables->oldestXid;
7171 LWLockRelease(XidGenLock);
7172
7173 LWLockAcquire(CommitTsLock, LW_SHARED);
7176 LWLockRelease(CommitTsLock);
7177
7178 LWLockAcquire(OidGenLock, LW_SHARED);
7179 checkPoint.nextOid = TransamVariables->nextOid;
7180 if (!shutdown)
7181 checkPoint.nextOid += TransamVariables->oidCount;
7182 LWLockRelease(OidGenLock);
7183
7184 MultiXactGetCheckptMulti(shutdown,
7185 &checkPoint.nextMulti,
7186 &checkPoint.nextMultiOffset,
7187 &checkPoint.oldestMulti,
7188 &checkPoint.oldestMultiDB);
7189
7190 /*
7191 * Having constructed the checkpoint record, ensure all shmem disk buffers
7192 * and commit-log buffers are flushed to disk.
7193 *
7194 * This I/O could fail for various reasons. If so, we will fail to
7195 * complete the checkpoint, but there is no reason to force a system
7196 * panic. Accordingly, exit critical section while doing it.
7197 */
7199
7200 /*
7201 * In some cases there are groups of actions that must all occur on one
7202 * side or the other of a checkpoint record. Before flushing the
7203 * checkpoint record we must explicitly wait for any backend currently
7204 * performing those groups of actions.
7205 *
7206 * One example is end of transaction, so we must wait for any transactions
7207 * that are currently in commit critical sections. If an xact inserted
7208 * its commit record into XLOG just before the REDO point, then a crash
7209 * restart from the REDO point would not replay that record, which means
7210 * that our flushing had better include the xact's update of pg_xact. So
7211 * we wait till he's out of his commit critical section before proceeding.
7212 * See notes in RecordTransactionCommit().
7213 *
7214 * Because we've already released the insertion locks, this test is a bit
7215 * fuzzy: it is possible that we will wait for xacts we didn't really need
7216 * to wait for. But the delay should be short and it seems better to make
7217 * checkpoint take a bit longer than to hold off insertions longer than
7218 * necessary. (In fact, the whole reason we have this issue is that xact.c
7219 * does commit record XLOG insertion and clog update as two separate steps
7220 * protected by different locks, but again that seems best on grounds of
7221 * minimizing lock contention.)
7222 *
7223 * A transaction that has not yet set delayChkptFlags when we look cannot
7224 * be at risk, since it has not inserted its commit record yet; and one
7225 * that's already cleared it is not at risk either, since it's done fixing
7226 * clog and we will correctly flush the update below. So we cannot miss
7227 * any xacts we need to wait for.
7228 */
7230 if (nvxids > 0)
7231 {
7232 do
7233 {
7234 /*
7235 * Keep absorbing fsync requests while we wait. There could even
7236 * be a deadlock if we don't, if the process that prevents the
7237 * checkpoint is trying to add a request to the queue.
7238 */
7240
7241 pgstat_report_wait_start(WAIT_EVENT_CHECKPOINT_DELAY_START);
7242 pg_usleep(10000L); /* wait for 10 msec */
7244 } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids,
7246 }
7247 pfree(vxids);
7248
7249 CheckPointGuts(checkPoint.redo, flags);
7250
7252 if (nvxids > 0)
7253 {
7254 do
7255 {
7257
7258 pgstat_report_wait_start(WAIT_EVENT_CHECKPOINT_DELAY_COMPLETE);
7259 pg_usleep(10000L); /* wait for 10 msec */
7261 } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids,
7263 }
7264 pfree(vxids);
7265
7266 /*
7267 * Take a snapshot of running transactions and write this to WAL. This
7268 * allows us to reconstruct the state of running transactions during
7269 * archive recovery, if required. Skip, if this info disabled.
7270 *
7271 * If we are shutting down, or Startup process is completing crash
7272 * recovery we don't need to write running xact data.
7273 */
7274 if (!shutdown && XLogStandbyInfoActive())
7276
7278
7279 /*
7280 * Now insert the checkpoint record into XLOG.
7281 */
7283 XLogRegisterData(&checkPoint, sizeof(checkPoint));
7284 recptr = XLogInsert(RM_XLOG_ID,
7285 shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
7287
7288 XLogFlush(recptr);
7289
7290 /*
7291 * We mustn't write any new WAL after a shutdown checkpoint, or it will be
7292 * overwritten at next startup. No-one should even try, this just allows
7293 * sanity-checking. In the case of an end-of-recovery checkpoint, we want
7294 * to just temporarily disable writing until the system has exited
7295 * recovery.
7296 */
7297 if (shutdown)
7298 {
7299 if (flags & CHECKPOINT_END_OF_RECOVERY)
7300 LocalXLogInsertAllowed = oldXLogAllowed;
7301 else
7302 LocalXLogInsertAllowed = 0; /* never again write WAL */
7303 }
7304
7305 /*
7306 * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
7307 * = end of actual checkpoint record.
7308 */
7309 if (shutdown && checkPoint.redo != ProcLastRecPtr)
7310 ereport(PANIC,
7311 (errmsg("concurrent write-ahead log activity while database system is shutting down")));
7312
7313 /*
7314 * Remember the prior checkpoint's redo ptr for
7315 * UpdateCheckPointDistanceEstimate()
7316 */
7317 PriorRedoPtr = ControlFile->checkPointCopy.redo;
7318
7319 /*
7320 * Update the control file.
7321 */
7322 LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7323 if (shutdown)
7326 ControlFile->checkPointCopy = checkPoint;
7327 /* crash recovery should always recover to the end of WAL */
7330
7331 /*
7332 * Persist unloggedLSN value. It's reset on crash recovery, so this goes
7333 * unused on non-shutdown checkpoints, but seems useful to store it always
7334 * for debugging purposes.
7335 */
7337
7339 LWLockRelease(ControlFileLock);
7340
7341 /*
7342 * We are now done with critical updates; no need for system panic if we
7343 * have trouble while fooling with old log segments.
7344 */
7346
7347 /*
7348 * WAL summaries end when the next XLOG_CHECKPOINT_REDO or
7349 * XLOG_CHECKPOINT_SHUTDOWN record is reached. This is the first point
7350 * where (a) we're not inside of a critical section and (b) we can be
7351 * certain that the relevant record has been flushed to disk, which must
7352 * happen before it can be summarized.
7353 *
7354 * If this is a shutdown checkpoint, then this happens reasonably
7355 * promptly: we've only just inserted and flushed the
7356 * XLOG_CHECKPOINT_SHUTDOWN record. If this is not a shutdown checkpoint,
7357 * then this might not be very prompt at all: the XLOG_CHECKPOINT_REDO
7358 * record was written before we began flushing data to disk, and that
7359 * could be many minutes ago at this point. However, we don't XLogFlush()
7360 * after inserting that record, so we're not guaranteed that it's on disk
7361 * until after the above call that flushes the XLOG_CHECKPOINT_ONLINE
7362 * record.
7363 */
7365
7366 /*
7367 * Let smgr do post-checkpoint cleanup (eg, deleting old files).
7368 */
7370
7371 /*
7372 * Update the average distance between checkpoints if the prior checkpoint
7373 * exists.
7374 */
7375 if (XLogRecPtrIsValid(PriorRedoPtr))
7377
7378 INJECTION_POINT("checkpoint-before-old-wal-removal", NULL);
7379
7380 /*
7381 * Delete old log files, those no longer needed for last checkpoint to
7382 * prevent the disk holding the xlog from growing full.
7383 */
7385 KeepLogSeg(recptr, &_logSegNo);
7387 _logSegNo, InvalidOid,
7389 {
7390 /*
7391 * Some slots have been invalidated; recalculate the old-segment
7392 * horizon, starting again from RedoRecPtr.
7393 */
7395 KeepLogSeg(recptr, &_logSegNo);
7396 }
7397 _logSegNo--;
7398 RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr,
7399 checkPoint.ThisTimeLineID);
7400
7401 /*
7402 * Make more log segments if needed. (Do this after recycling old log
7403 * segments, since that may supply some of the needed files.)
7404 */
7405 if (!shutdown)
7406 PreallocXlogFiles(recptr, checkPoint.ThisTimeLineID);
7407
7408 /*
7409 * Truncate pg_subtrans if possible. We can throw away all data before
7410 * the oldest XMIN of any running transaction. No future transaction will
7411 * attempt to reference any pg_subtrans entry older than that (see Asserts
7412 * in subtrans.c). During recovery, though, we mustn't do this because
7413 * StartupSUBTRANS hasn't been called yet.
7414 */
7415 if (!RecoveryInProgress())
7417
7418 /* Real work is done; log and update stats. */
7419 LogCheckpointEnd(false);
7420
7421 /* Reset the process title */
7422 update_checkpoint_display(flags, false, true);
7423
7424 TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
7425 NBuffers,
7429
7430 return true;
7431}
static uint64 pg_atomic_read_membarrier_u64(volatile pg_atomic_uint64 *ptr)
Definition: atomics.h:476
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1645
uint32_t uint32
Definition: c.h:552
#define MemSet(start, val, len)
Definition: c.h:1032
void AbsorbSyncRequests(void)
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1170
#define DEBUG1
Definition: elog.h:30
#define elog(elevel,...)
Definition: elog.h:226
static void Insert(File file)
Definition: fd.c:1297
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
void pfree(void *pointer)
Definition: mcxt.c:1594
#define START_CRIT_SECTION()
Definition: miscadmin.h:150
#define END_CRIT_SECTION()
Definition: miscadmin.h:152
void MultiXactGetCheckptMulti(bool is_shutdown, MultiXactId *nextMulti, MultiXactOffset *nextMultiOffset, MultiXactId *oldestMulti, Oid *oldestMultiDB)
Definition: multixact.c:1943
#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:3050
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:2068
@ 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:510
XLogRecPtr RedoRecPtr
Definition: xlog.c:458
XLogCtlInsert Insert
Definition: xlog.c:454
TimeLineID PrevTimeLineID
Definition: xlog.c:511
pg_atomic_uint64 unloggedLSN
Definition: xlog.c:465
XLogRecPtr RedoRecPtr
Definition: xlog.c:432
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:255
bool RecoveryInProgress(void)
Definition: xlog.c:6404
static void WALInsertLockRelease(void)
Definition: xlog.c:1451
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1864
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1422
static void UpdateControlFile(void)
Definition: xlog.c:4602
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr, TimeLineID insertTLI)
Definition: xlog.c:3886
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:6719
static XLogRecPtr RedoRecPtr
Definition: xlog.c:275
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:6751
static void PreallocXlogFiles(XLogRecPtr endptr, TimeLineID tli)
Definition: xlog.c:3711
bool log_checkpoints
Definition: xlog.c:131
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:8019
static int LocalSetXLogInsertAllowed(void)
Definition: xlog.c:6492
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:6626
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:6856
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:581
static int LocalXLogInsertAllowed
Definition: xlog.c:238
CheckpointStatsData CheckpointStats
Definition: xlog.c:211
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2783
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:7577
static void update_checkpoint_display(int flags, bool restartpoint, bool reset)
Definition: xlog.c:6894
#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
#define XLogRecPtrIsValid(r)
Definition: xlogdefs.h:29
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:478
void XLogRegisterData(const void *data, uint32 len)
Definition: xloginsert.c:368
void XLogBeginInsert(void)
Definition: xloginsert.c:152

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(), XLogRecPtrIsValid, XLogRegisterData(), XLogSegmentOffset, and XLogStandbyInfoActive.

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

◆ CreateRestartPoint()

bool CreateRestartPoint ( int  flags)

Definition at line 7657 of file xlog.c.

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

Referenced by CheckpointerMain(), and ShutdownXLOG().

◆ DataChecksumsEnabled()

◆ do_pg_abort_backup()

void do_pg_abort_backup ( int  code,
Datum  arg 
)

Definition at line 9456 of file xlog.c.

9457{
9458 bool during_backup_start = DatumGetBool(arg);
9459
9460 /* If called during backup start, there shouldn't be one already running */
9461 Assert(!during_backup_start || sessionBackupState == SESSION_BACKUP_NONE);
9462
9463 if (during_backup_start || sessionBackupState != SESSION_BACKUP_NONE)
9464 {
9468
9471
9472 if (!during_backup_start)
9474 errmsg("aborting backup due to backend exiting before pg_backup_stop was called"));
9475 }
9476}
#define WARNING
Definition: elog.h:36
void * arg
static bool DatumGetBool(Datum X)
Definition: postgres.h:100
int runningBackups
Definition: xlog.c:440
static SessionBackupState sessionBackupState
Definition: xlog.c:393

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

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

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

9164{
9165 return sessionBackupState;
9166}

References sessionBackupState.

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

◆ GetActiveWalLevelOnStandby()

WalLevel GetActiveWalLevelOnStandby ( void  )

Definition at line 4917 of file xlog.c.

4918{
4919 return ControlFile->wal_level;
4920}

References ControlFile, and ControlFileData::wal_level.

Referenced by CheckLogicalDecodingRequirements().

◆ GetDefaultCharSignedness()

bool GetDefaultCharSignedness ( void  )

Definition at line 4645 of file xlog.c.

4646{
4648}
bool default_char_signedness
Definition: pg_control.h:230

References ControlFile, and ControlFileData::default_char_signedness.

Referenced by CMPTRGM_CHOOSE().

◆ GetFakeLSNForUnloggedRel()

XLogRecPtr GetFakeLSNForUnloggedRel ( void  )

Definition at line 4660 of file xlog.c.

4661{
4663}
static uint64 pg_atomic_fetch_add_u64(volatile pg_atomic_uint64 *ptr, int64 add_)
Definition: atomics.h:532

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

Referenced by gistGetFakeLSN().

◆ GetFlushRecPtr()

XLogRecPtr GetFlushRecPtr ( TimeLineID insertTLI)

Definition at line 6569 of file xlog.c.

6570{
6572
6574
6575 /*
6576 * If we're writing and flushing WAL, the time line can't be changing, so
6577 * no lock is required.
6578 */
6579 if (insertTLI)
6580 *insertTLI = XLogCtl->InsertTimeLineID;
6581
6582 return LogwrtResult.Flush;
6583}
RecoveryState SharedRecoveryState
Definition: xlog.c:517
XLogRecPtr Flush
Definition: xlog.c:330
#define RefreshXLogWriteResult(_target)
Definition: xlog.c:621
static XLogwrtResult LogwrtResult
Definition: xlog.c:613

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(), WaitForLSN(), WalSndWaitForWal(), XLogSendLogical(), and XLogSendPhysical().

◆ GetFullPageWriteInfo()

void GetFullPageWriteInfo ( XLogRecPtr RedoRecPtr_p,
bool *  doPageWrites_p 
)

Definition at line 6537 of file xlog.c.

6538{
6539 *RedoRecPtr_p = RedoRecPtr;
6540 *doPageWrites_p = doPageWrites;
6541}
static bool doPageWrites
Definition: xlog.c:288

References doPageWrites, and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )

Definition at line 6552 of file xlog.c.

6553{
6554 XLogRecPtr recptr;
6555
6557 recptr = XLogCtl->LogwrtRqst.Write;
6559
6560 return recptr;
6561}
XLogwrtRqst LogwrtRqst
Definition: xlog.c:457
XLogRecPtr Write
Definition: xlog.c:323

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

6627{
6629 int i;
6630
6631 for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
6632 {
6633 XLogRecPtr last_important;
6634
6635 /*
6636 * Need to take a lock to prevent torn reads of the LSN, which are
6637 * possible on some of the supported platforms. WAL insert locks only
6638 * support exclusive mode, so we have to use that.
6639 */
6641 last_important = WALInsertLocks[i].l.lastImportantAt;
6642 LWLockRelease(&WALInsertLocks[i].l.lock);
6643
6644 if (res < last_important)
6645 res = last_important;
6646 }
6647
6648 return res;
6649}
int i
Definition: isn.c:77
XLogRecPtr lastImportantAt
Definition: xlog.c:373
WALInsertLock l
Definition: xlog.c:385
static WALInsertLockPadded * WALInsertLocks
Definition: xlog.c:570
#define NUM_XLOGINSERT_LOCKS
Definition: xlog.c:152

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

4622{
4623 Assert(ControlFile != NULL);
4625}
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition: pg_control.h:237

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

Referenced by scram_mock_salt().

◆ GetRecoveryState()

RecoveryState GetRecoveryState ( void  )

Definition at line 6440 of file xlog.c.

6441{
6442 RecoveryState retval;
6443
6445 retval = XLogCtl->SharedRecoveryState;
6447
6448 return retval;
6449}

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

Referenced by XLogArchiveCheckDone().

◆ GetRedoRecPtr()

XLogRecPtr GetRedoRecPtr ( void  )

Definition at line 6507 of file xlog.c.

6508{
6509 XLogRecPtr ptr;
6510
6511 /*
6512 * The possibly not up-to-date copy in XlogCtl is enough. Even if we
6513 * grabbed a WAL insertion lock to read the authoritative value in
6514 * Insert->RedoRecPtr, someone might update it just after we've released
6515 * the lock.
6516 */
6518 ptr = XLogCtl->RedoRecPtr;
6520
6521 if (RedoRecPtr < ptr)
6522 RedoRecPtr = ptr;
6523
6524 return RedoRecPtr;
6525}

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

7936{
7937 XLogRecPtr currpos; /* current write LSN */
7938 XLogSegNo currSeg; /* segid of currpos */
7939 XLogSegNo targetSeg; /* segid of targetLSN */
7940 XLogSegNo oldestSeg; /* actual oldest segid */
7941 XLogSegNo oldestSegMaxWalSize; /* oldest segid kept by max_wal_size */
7942 XLogSegNo oldestSlotSeg; /* oldest segid kept by slot */
7943 uint64 keepSegs;
7944
7945 /*
7946 * slot does not reserve WAL. Either deactivated, or has never been active
7947 */
7948 if (!XLogRecPtrIsValid(targetLSN))
7949 return WALAVAIL_INVALID_LSN;
7950
7951 /*
7952 * Calculate the oldest segment currently reserved by all slots,
7953 * considering wal_keep_size and max_slot_wal_keep_size. Initialize
7954 * oldestSlotSeg to the current segment.
7955 */
7956 currpos = GetXLogWriteRecPtr();
7957 XLByteToSeg(currpos, oldestSlotSeg, wal_segment_size);
7958 KeepLogSeg(currpos, &oldestSlotSeg);
7959
7960 /*
7961 * Find the oldest extant segment file. We get 1 until checkpoint removes
7962 * the first WAL segment file since startup, which causes the status being
7963 * wrong under certain abnormal conditions but that doesn't actually harm.
7964 */
7965 oldestSeg = XLogGetLastRemovedSegno() + 1;
7966
7967 /* calculate oldest segment by max_wal_size */
7968 XLByteToSeg(currpos, currSeg, wal_segment_size);
7970
7971 if (currSeg > keepSegs)
7972 oldestSegMaxWalSize = currSeg - keepSegs;
7973 else
7974 oldestSegMaxWalSize = 1;
7975
7976 /* the segment we care about */
7977 XLByteToSeg(targetLSN, targetSeg, wal_segment_size);
7978
7979 /*
7980 * No point in returning reserved or extended status values if the
7981 * targetSeg is known to be lost.
7982 */
7983 if (targetSeg >= oldestSlotSeg)
7984 {
7985 /* show "reserved" when targetSeg is within max_wal_size */
7986 if (targetSeg >= oldestSegMaxWalSize)
7987 return WALAVAIL_RESERVED;
7988
7989 /* being retained by slots exceeding max_wal_size */
7990 return WALAVAIL_EXTENDED;
7991 }
7992
7993 /* WAL segments are no longer retained but haven't been removed yet */
7994 if (targetSeg >= oldestSeg)
7995 return WALAVAIL_UNRESERVED;
7996
7997 /* Definitely lost */
7998 return WALAVAIL_REMOVED;
7999}
XLogSegNo XLogGetLastRemovedSegno(void)
Definition: xlog.c:3779
int max_wal_size_mb
Definition: xlog.c:116
#define ConvertToXSegs(x, segsize)
Definition: xlog.c:604
XLogRecPtr GetXLogWriteRecPtr(void)
Definition: xlog.c:9513

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 XLogRecPtrIsValid.

Referenced by pg_get_replication_slots().

◆ GetWALInsertionTimeLine()

TimeLineID GetWALInsertionTimeLine ( void  )

◆ GetWALInsertionTimeLineIfSet()

TimeLineID GetWALInsertionTimeLineIfSet ( void  )

Definition at line 6606 of file xlog.c.

6607{
6608 TimeLineID insertTLI;
6609
6611 insertTLI = XLogCtl->InsertTimeLineID;
6613
6614 return insertTLI;
6615}

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

Referenced by GetLatestLSN().

◆ GetXLogInsertRecPtr()

XLogRecPtr GetXLogInsertRecPtr ( void  )

Definition at line 9497 of file xlog.c.

9498{
9500 uint64 current_bytepos;
9501
9502 SpinLockAcquire(&Insert->insertpos_lck);
9503 current_bytepos = Insert->CurrBytePos;
9504 SpinLockRelease(&Insert->insertpos_lck);
9505
9506 return XLogBytePosToRecPtr(current_bytepos);
9507}

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

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

◆ GetXLogWriteRecPtr()

XLogRecPtr GetXLogWriteRecPtr ( void  )

◆ InitializeWalConsistencyChecking()

void InitializeWalConsistencyChecking ( void  )

Definition at line 4842 of file xlog.c.

4843{
4845
4847 {
4848 struct config_generic *guc;
4849
4850 guc = find_option("wal_consistency_checking", false, false, ERROR);
4851
4853
4854 set_config_option_ext("wal_consistency_checking",
4856 guc->scontext, guc->source, guc->srole,
4857 GUC_ACTION_SET, true, ERROR, false);
4858
4859 /* checking should not be deferred again */
4861 }
4862}
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:3256
struct config_generic * find_option(const char *name, bool create_placeholders, bool skip_errors, int elevel)
Definition: guc.c:1113
@ GUC_ACTION_SET
Definition: guc.h:203
bool process_shared_preload_libraries_done
Definition: miscinit.c:1787
GucContext scontext
Definition: guc_tables.h:263
GucSource source
Definition: guc_tables.h:261
char * wal_consistency_checking_string
Definition: xlog.c:127
static bool check_wal_consistency_checking_deferred
Definition: xlog.c:168

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

9563{
9564 bool result;
9565
9566 LWLockAcquire(ControlFileLock, LW_SHARED);
9568 LWLockRelease(ControlFileLock);
9569
9570 return result;
9571}
bool InstallXLogFileSegmentActive
Definition: xlog.c:527

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

8758{
8759 char *msg = NULL;
8761
8762 Assert(tli != 0);
8763
8764 /*
8765 * Quick exit if fsync is disabled or write() has already synced the WAL
8766 * file.
8767 */
8768 if (!enableFsync ||
8771 return;
8772
8773 /*
8774 * Measure I/O timing to sync the WAL file for pg_stat_io.
8775 */
8777
8778 pgstat_report_wait_start(WAIT_EVENT_WAL_SYNC);
8779 switch (wal_sync_method)
8780 {
8782 if (pg_fsync_no_writethrough(fd) != 0)
8783 msg = _("could not fsync file \"%s\": %m");
8784 break;
8785#ifdef HAVE_FSYNC_WRITETHROUGH
8787 if (pg_fsync_writethrough(fd) != 0)
8788 msg = _("could not fsync write-through file \"%s\": %m");
8789 break;
8790#endif
8792 if (pg_fdatasync(fd) != 0)
8793 msg = _("could not fdatasync file \"%s\": %m");
8794 break;
8797 /* not reachable */
8798 Assert(false);
8799 break;
8800 default:
8801 ereport(PANIC,
8802 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8803 errmsg_internal("unrecognized \"wal_sync_method\": %d", wal_sync_method));
8804 break;
8805 }
8806
8807 /* PANIC if failed to fsync */
8808 if (msg)
8809 {
8810 char xlogfname[MAXFNAMELEN];
8811 int save_errno = errno;
8812
8813 XLogFileName(xlogfname, tli, segno, wal_segment_size);
8814 errno = save_errno;
8815 ereport(PANIC,
8817 errmsg(msg, xlogfname)));
8818 }
8819
8821
8823 start, 1, 0);
8824}
#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:279
@ IOCONTEXT_NORMAL
Definition: pgstat.h:289
@ IOOP_FSYNC
Definition: pgstat.h:308
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:132
bool track_wal_io_timing
Definition: xlog.c:139

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

4905{
4906 Assert(reset || ControlFile == NULL);
4909}
void reset(void)
Definition: sql-declare.c:600

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

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

◆ ReachedEndOfBackup()

void ReachedEndOfBackup ( XLogRecPtr  EndRecPtr,
TimeLineID  tli 
)

Definition at line 6317 of file xlog.c.

6318{
6319 /*
6320 * We have reached the end of base backup, as indicated by pg_control. The
6321 * data on disk is now consistent (unless minRecoveryPoint is further
6322 * ahead, which can happen if we crashed during previous recovery). Reset
6323 * backupStartPoint and backupEndPoint, and update minRecoveryPoint to
6324 * make sure we don't allow starting up at an earlier point even if
6325 * recovery is stopped and restarted soon after this.
6326 */
6327 LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6328
6329 if (ControlFile->minRecoveryPoint < EndRecPtr)
6330 {
6331 ControlFile->minRecoveryPoint = EndRecPtr;
6333 }
6334
6339
6340 LWLockRelease(ControlFileLock);
6341}
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 6404 of file xlog.c.

6405{
6406 /*
6407 * We check shared state each time only until we leave recovery mode. We
6408 * can't re-enter recovery, so there's no need to keep checking after the
6409 * shared variable has once been seen false.
6410 */
6412 return false;
6413 else
6414 {
6415 /*
6416 * use volatile pointer to make sure we make a fresh read of the
6417 * shared variable.
6418 */
6419 volatile XLogCtlData *xlogctl = XLogCtl;
6420
6422
6423 /*
6424 * Note: We don't need a memory barrier when we're still in recovery.
6425 * We might exit recovery immediately after return, so the caller
6426 * can't rely on 'true' meaning that we're still in recovery anyway.
6427 */
6428
6430 }
6431}
static bool LocalRecoveryInProgress
Definition: xlog.c:226

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(), pgstat_report_replslotsync(), 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(), WaitForLSN(), 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 9483 of file xlog.c.

9484{
9485 static bool already_done = false;
9486
9487 if (already_done)
9488 return;
9490 already_done = true;
9491}
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 3961 of file xlog.c.

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

◆ ResetInstallXLogFileSegmentActive()

void ResetInstallXLogFileSegmentActive ( void  )

Definition at line 9554 of file xlog.c.

9555{
9556 LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9558 LWLockRelease(ControlFileLock);
9559}

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

Referenced by WaitForWALToBecomeAvailable(), and XLogShutdownWalRcv().

◆ SetInstallXLogFileSegmentActive()

void SetInstallXLogFileSegmentActive ( void  )

Definition at line 9545 of file xlog.c.

9546{
9547 LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9549 LWLockRelease(ControlFileLock);
9550}

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

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

◆ SetWalWriterSleeping()

void SetWalWriterSleeping ( bool  sleeping)

Definition at line 9577 of file xlog.c.

9578{
9580 XLogCtl->WalWriterSleeping = sleeping;
9582}
bool WalWriterSleeping
Definition: xlog.c:534

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

Referenced by WalWriterMain().

◆ ShutdownXLOG()

void ShutdownXLOG ( int  code,
Datum  arg 
)

Definition at line 6672 of file xlog.c.

6673{
6674 /*
6675 * We should have an aux process resource owner to use, and we should not
6676 * be in a transaction that's installed some other resowner.
6677 */
6679 Assert(CurrentResourceOwner == NULL ||
6682
6683 /* Don't be chatty in standalone mode */
6685 (errmsg("shutting down")));
6686
6687 /*
6688 * Signal walsenders to move to stopping state.
6689 */
6691
6692 /*
6693 * Wait for WAL senders to be in stopping state. This prevents commands
6694 * from writing new WAL.
6695 */
6697
6698 if (RecoveryInProgress())
6700 else
6701 {
6702 /*
6703 * If archiving is enabled, rotate the last XLOG file so that all the
6704 * remaining records are archived (postmaster wakes up the archiver
6705 * process one more time at the end of shutdown). The checkpoint
6706 * record will go to the next XLOG file and won't be archived (yet).
6707 */
6708 if (XLogArchivingActive())
6709 RequestXLogSwitch(false);
6710
6712 }
6713}
bool IsPostmasterEnvironment
Definition: globals.c:119
ResourceOwner CurrentResourceOwner
Definition: resowner.c:173
ResourceOwner AuxProcessResourceOwner
Definition: resowner.c:176
void WalSndInitStopping(void)
Definition: walsender.c:3872
void WalSndWaitStopping(void)
Definition: walsender.c:3898
bool CreateRestartPoint(int flags)
Definition: xlog.c:7657
bool CreateCheckPoint(int flags)
Definition: xlog.c:6959

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

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

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(), WAIT_LSN_TYPE_REPLAY, WaitLSNWakeup(), WalSndWakeup(), XLogwrtRqst::Write, XLogwrtResult::Write, writeTimeLineHistory(), RunningTransactionsData::xcnt, XidFromFullTransactionId, RunningTransactionsData::xids, XLogCtlData::xlblocks, XLogCtl, XLogInitNewTimeline(), XLogRecPtrIsValid, XLogRecPtrToBufIdx, XLogRecPtrToBytePos(), XLogReportParameters(), and XRecOffIsValid.

Referenced by InitPostgres(), and StartupProcessMain().

◆ SwitchIntoArchiveRecovery()

void SwitchIntoArchiveRecovery ( XLogRecPtr  EndRecPtr,
TimeLineID  replayTLI 
)

Definition at line 6279 of file xlog.c.

6280{
6281 /* initialize minRecoveryPoint to this record */
6282 LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6284 if (ControlFile->minRecoveryPoint < EndRecPtr)
6285 {
6286 ControlFile->minRecoveryPoint = EndRecPtr;
6287 ControlFile->minRecoveryPointTLI = replayTLI;
6288 }
6289 /* update local copy */
6292
6293 /*
6294 * The startup process can update its local copy of minRecoveryPoint from
6295 * this point.
6296 */
6298
6300
6301 /*
6302 * We update SharedRecoveryState while holding the lock on ControlFileLock
6303 * so both states are consistent in shared memory.
6304 */
6308
6309 LWLockRelease(ControlFileLock);
6310}
static bool updateMinRecoveryPoint
Definition: xlog.c:649

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

8235{
8237 bool recoveryInProgress;
8238
8239 /*
8240 * Do nothing if full_page_writes has not been changed.
8241 *
8242 * It's safe to check the shared full_page_writes without the lock,
8243 * because we assume that there is no concurrently running process which
8244 * can update it.
8245 */
8246 if (fullPageWrites == Insert->fullPageWrites)
8247 return;
8248
8249 /*
8250 * Perform this outside critical section so that the WAL insert
8251 * initialization done by RecoveryInProgress() doesn't trigger an
8252 * assertion failure.
8253 */
8254 recoveryInProgress = RecoveryInProgress();
8255
8257
8258 /*
8259 * It's always safe to take full page images, even when not strictly
8260 * required, but not the other round. So if we're setting full_page_writes
8261 * to true, first set it true and then write the WAL record. If we're
8262 * setting it to false, first write the WAL record and then set the global
8263 * flag.
8264 */
8265 if (fullPageWrites)
8266 {
8268 Insert->fullPageWrites = true;
8270 }
8271
8272 /*
8273 * Write an XLOG_FPW_CHANGE record. This allows us to keep track of
8274 * full_page_writes during archive recovery, if required.
8275 */
8276 if (XLogStandbyInfoActive() && !recoveryInProgress)
8277 {
8279 XLogRegisterData(&fullPageWrites, sizeof(bool));
8280
8281 XLogInsert(RM_XLOG_ID, XLOG_FPW_CHANGE);
8282 }
8283
8284 if (!fullPageWrites)
8285 {
8287 Insert->fullPageWrites = false;
8289 }
8291}
#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 1754 of file xlog.c.

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

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, XLogRecPtrIsValid, 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 %" PRIu64 "; "
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:550
#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[DEFAULT_XLOG_SEG_SIZE]
Definition: pg_test_fsync.c:71
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:409
#define XLogRecGetData(decoder)
Definition: xlogreader.h:414

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

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

◆ XLogBackgroundFlush()

bool XLogBackgroundFlush ( void  )

Definition at line 2980 of file xlog.c.

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

2284{
2285 XLogSegNo old_segno;
2286
2288
2289 if (new_segno >= old_segno + (uint64) (CheckPointSegments - 1))
2290 return true;
2291 return false;
2292}
int CheckPointSegments
Definition: xlog.c:158

References CheckPointSegments, RedoRecPtr, wal_segment_size, and XLByteToSeg.

Referenced by XLogPageRead(), and XLogWrite().

◆ XLogFileInit()

int XLogFileInit ( XLogSegNo  logsegno,
TimeLineID  logtli 
)

Definition at line 3401 of file xlog.c.

3402{
3403 bool ignore_added;
3404 char path[MAXPGPATH];
3405 int fd;
3406
3407 Assert(logtli != 0);
3408
3409 fd = XLogFileInitInternal(logsegno, logtli, &ignore_added, path);
3410 if (fd >= 0)
3411 return fd;
3412
3413 /* Now open original target segment (might not be file I just made) */
3414 fd = BasicOpenFile(path, O_RDWR | PG_BINARY | O_CLOEXEC |
3416 if (fd < 0)
3417 ereport(ERROR,
3419 errmsg("could not open file \"%s\": %m", path)));
3420 return fd;
3421}
#define PG_BINARY
Definition: c.h:1271
int BasicOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1086
#define O_CLOEXEC
Definition: win32_port.h:344
static int get_sync_bit(int method)
Definition: xlog.c:8667
static int XLogFileInitInternal(XLogSegNo logsegno, TimeLineID logtli, bool *added, char *path)
Definition: xlog.c:3213

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

3640{
3641 char path[MAXPGPATH];
3642 int fd;
3643
3644 XLogFilePath(path, tli, segno, wal_segment_size);
3645
3646 fd = BasicOpenFile(path, O_RDWR | PG_BINARY | O_CLOEXEC |
3648 if (fd < 0)
3649 ereport(PANIC,
3651 errmsg("could not open file \"%s\": %m", path)));
3652
3653 return fd;
3654}
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 2783 of file xlog.c.

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

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(), pgstat_report_wait_end(), pgstat_report_wait_start(), 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(), FinishSyncWorker(), 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 3779 of file xlog.c.

3780{
3781 XLogSegNo lastRemovedSegNo;
3782
3784 lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3786
3787 return lastRemovedSegNo;
3788}

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

3796{
3797 DIR *xldir;
3798 struct dirent *xlde;
3799 XLogSegNo oldest_segno = 0;
3800
3801 xldir = AllocateDir(XLOGDIR);
3802 while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
3803 {
3804 TimeLineID file_tli;
3805 XLogSegNo file_segno;
3806
3807 /* Ignore files that are not XLOG segments. */
3808 if (!IsXLogFileName(xlde->d_name))
3809 continue;
3810
3811 /* Parse filename to get TLI and segno. */
3812 XLogFromFileName(xlde->d_name, &file_tli, &file_segno,
3814
3815 /* Ignore anything that's not from the TLI of interest. */
3816 if (tli != file_tli)
3817 continue;
3818
3819 /* If it's the oldest so far, update oldest_segno. */
3820 if (oldest_segno == 0 || file_segno < oldest_segno)
3821 oldest_segno = file_segno;
3822 }
3823
3824 FreeDir(xldir);
3825 return oldest_segno;
3826}
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 6459 of file xlog.c.

6460{
6461 /*
6462 * If value is "unconditionally true" or "unconditionally false", just
6463 * return it. This provides the normal fast path once recovery is known
6464 * done.
6465 */
6466 if (LocalXLogInsertAllowed >= 0)
6467 return (bool) LocalXLogInsertAllowed;
6468
6469 /*
6470 * Else, must check to see if we're still in recovery.
6471 */
6472 if (RecoveryInProgress())
6473 return false;
6474
6475 /*
6476 * On exit from recovery, reset to "unconditionally true", since there is
6477 * no need to keep checking.
6478 */
6480 return true;
6481}

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,
uint64  fpi_bytes,
bool  topxid_included 
)

Definition at line 749 of file xlog.c.

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

Referenced by XLogInsert().

◆ XLogNeedsFlush()

bool XLogNeedsFlush ( XLogRecPtr  record)

Definition at line 3129 of file xlog.c.

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

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

◆ XLogPutNextOid()

void XLogPutNextOid ( Oid  nextOid)

Definition at line 8091 of file xlog.c.

8092{
8094 XLogRegisterData(&nextOid, sizeof(Oid));
8095 (void) XLogInsert(RM_XLOG_ID, XLOG_NEXTOID);
8096
8097 /*
8098 * We need not flush the NEXTOID record immediately, because any of the
8099 * just-allocated OIDs could only reach disk as part of a tuple insert or
8100 * update that would have its own XLOG record that must follow the NEXTOID
8101 * record. Therefore, the standard buffer LSN interlock applied to those
8102 * records will ensure no such OID reaches disk before the NEXTOID record
8103 * does.
8104 *
8105 * Note, however, that the above statement only covers state "within" the
8106 * database. When we use a generated OID as a file or directory name, we
8107 * are in a sense violating the basic WAL rule, because that filesystem
8108 * change may reach disk before the NEXTOID WAL record does. The impact
8109 * of this is that if a database crash occurs immediately afterward, we
8110 * might after restart re-generate the same OID and find that it conflicts
8111 * with the leftover file or directory. But since for safety's sake we
8112 * always loop until finding a nonconflicting filename, this poses no real
8113 * problem in practice. See pgsql-hackers discussion 27-Sep-2006.
8114 */
8115}

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

Referenced by GetNewObjectId().

◆ XLogRestorePoint()

XLogRecPtr XLogRestorePoint ( const char *  rpName)

Definition at line 8146 of file xlog.c.

8147{
8148 XLogRecPtr RecPtr;
8149 xl_restore_point xlrec;
8150
8151 xlrec.rp_time = GetCurrentTimestamp();
8152 strlcpy(xlrec.rp_name, rpName, MAXFNAMELEN);
8153
8155 XLogRegisterData(&xlrec, sizeof(xl_restore_point));
8156
8157 RecPtr = XLogInsert(RM_XLOG_ID, XLOG_RESTORE_POINT);
8158
8159 ereport(LOG,
8160 errmsg("restore point \"%s\" created at %X/%08X",
8161 rpName, LSN_FORMAT_ARGS(RecPtr)));
8162
8163 return RecPtr;
8164}
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 2612 of file xlog.c.

2613{
2614 XLogRecPtr WriteRqstPtr = asyncXactLSN;
2615 bool sleeping;
2616 bool wakeup = false;
2617 XLogRecPtr prevAsyncXactLSN;
2618
2620 sleeping = XLogCtl->WalWriterSleeping;
2621 prevAsyncXactLSN = XLogCtl->asyncXactLSN;
2622 if (XLogCtl->asyncXactLSN < asyncXactLSN)
2623 XLogCtl->asyncXactLSN = asyncXactLSN;
2625
2626 /*
2627 * If somebody else already called this function with a more aggressive
2628 * LSN, they will have done what we needed (and perhaps more).
2629 */
2630 if (asyncXactLSN <= prevAsyncXactLSN)
2631 return;
2632
2633 /*
2634 * If the WALWriter is sleeping, kick it to make it come out of low-power
2635 * mode, so that this async commit will reach disk within the expected
2636 * amount of time. Otherwise, determine whether it has enough WAL
2637 * available to flush, the same way that XLogBackgroundFlush() does.
2638 */
2639 if (sleeping)
2640 wakeup = true;
2641 else
2642 {
2643 int flushblocks;
2644
2646
2647 flushblocks =
2648 WriteRqstPtr / XLOG_BLCKSZ - LogwrtResult.Flush / XLOG_BLCKSZ;
2649
2650 if (WalWriterFlushAfter == 0 || flushblocks >= WalWriterFlushAfter)
2651 wakeup = true;
2652 }
2653
2654 if (wakeup)
2655 {
2656 volatile PROC_HDR *procglobal = ProcGlobal;
2657 ProcNumber walwriterProc = procglobal->walwriterProc;
2658
2659 if (walwriterProc != INVALID_PROC_NUMBER)
2660 SetLatch(&GetPGProcByNumber(walwriterProc)->procLatch);
2661 }
2662}
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:79
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 4976 of file xlog.c.

4977{
4978 bool foundCFile,
4979 foundXLog;
4980 char *allocptr;
4981 int i;
4982 ControlFileData *localControlFile;
4983
4984#ifdef WAL_DEBUG
4985
4986 /*
4987 * Create a memory context for WAL debugging that's exempt from the normal
4988 * "no pallocs in critical section" rule. Yes, that can lead to a PANIC if
4989 * an allocation fails, but wal_debug is not for production use anyway.
4990 */
4991 if (walDebugCxt == NULL)
4992 {
4994 "WAL Debug",
4996 MemoryContextAllowInCriticalSection(walDebugCxt, true);
4997 }
4998#endif
4999
5000
5001 XLogCtl = (XLogCtlData *)
5002 ShmemInitStruct("XLOG Ctl", XLOGShmemSize(), &foundXLog);
5003
5004 localControlFile = ControlFile;
5006 ShmemInitStruct("Control File", sizeof(ControlFileData), &foundCFile);
5007
5008 if (foundCFile || foundXLog)
5009 {
5010 /* both should be present or neither */
5011 Assert(foundCFile && foundXLog);
5012
5013 /* Initialize local copy of WALInsertLocks */
5015
5016 if (localControlFile)
5017 pfree(localControlFile);
5018 return;
5019 }
5020 memset(XLogCtl, 0, sizeof(XLogCtlData));
5021
5022 /*
5023 * Already have read control file locally, unless in bootstrap mode. Move
5024 * contents into shared memory.
5025 */
5026 if (localControlFile)
5027 {
5028 memcpy(ControlFile, localControlFile, sizeof(ControlFileData));
5029 pfree(localControlFile);
5030 }
5031
5032 /*
5033 * Since XLogCtlData contains XLogRecPtr fields, its sizeof should be a
5034 * multiple of the alignment for same, so no extra alignment padding is
5035 * needed here.
5036 */
5037 allocptr = ((char *) XLogCtl) + sizeof(XLogCtlData);
5038 XLogCtl->xlblocks = (pg_atomic_uint64 *) allocptr;
5039 allocptr += sizeof(pg_atomic_uint64) * XLOGbuffers;
5040
5041 for (i = 0; i < XLOGbuffers; i++)
5042 {
5044 }
5045
5046 /* WAL insertion locks. Ensure they're aligned to the full padded size */
5047 allocptr += sizeof(WALInsertLockPadded) -
5048 ((uintptr_t) allocptr) % sizeof(WALInsertLockPadded);
5050 (WALInsertLockPadded *) allocptr;
5051 allocptr += sizeof(WALInsertLockPadded) * NUM_XLOGINSERT_LOCKS;
5052
5053 for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
5054 {
5055 LWLockInitialize(&WALInsertLocks[i].l.lock, LWTRANCHE_WAL_INSERT);
5058 }
5059
5060 /*
5061 * Align the start of the page buffers to a full xlog block size boundary.
5062 * This simplifies some calculations in XLOG insertion. It is also
5063 * required for O_DIRECT.
5064 */
5065 allocptr = (char *) TYPEALIGN(XLOG_BLCKSZ, allocptr);
5066 XLogCtl->pages = allocptr;
5067 memset(XLogCtl->pages, 0, (Size) XLOG_BLCKSZ * XLOGbuffers);
5068
5069 /*
5070 * Do basic initialization of XLogCtl shared data. (StartupXLOG will fill
5071 * in additional info.)
5072 */
5076 XLogCtl->WalWriterSleeping = false;
5077
5084}
static void pg_atomic_init_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:453
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:817
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:389
#define SpinLockInit(lock)
Definition: spin.h:57
int XLogCacheBlck
Definition: xlog.c:495
WALInsertLockPadded * WALInsertLocks
Definition: xlog.c:446
slock_t insertpos_lck
Definition: xlog.c:400
union WALInsertLockPadded WALInsertLockPadded
Size XLOGShmemSize(void)
Definition: xlog.c:4926
int XLOGbuffers
Definition: xlog.c:119
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 4926 of file xlog.c.

4927{
4928 Size size;
4929
4930 /*
4931 * If the value of wal_buffers is -1, use the preferred auto-tune value.
4932 * This isn't an amazingly clean place to do this, but we must wait till
4933 * NBuffers has received its final value, and must do it before using the
4934 * value of XLOGbuffers to do anything important.
4935 *
4936 * We prefer to report this value's source as PGC_S_DYNAMIC_DEFAULT.
4937 * However, if the DBA explicitly set wal_buffers = -1 in the config file,
4938 * then PGC_S_DYNAMIC_DEFAULT will fail to override that and we must force
4939 * the matter with PGC_S_OVERRIDE.
4940 */
4941 if (XLOGbuffers == -1)
4942 {
4943 char buf[32];
4944
4945 snprintf(buf, sizeof(buf), "%d", XLOGChooseNumBuffers());
4946 SetConfigOption("wal_buffers", buf, PGC_POSTMASTER,
4948 if (XLOGbuffers == -1) /* failed to apply it? */
4949 SetConfigOption("wal_buffers", buf, PGC_POSTMASTER,
4951 }
4952 Assert(XLOGbuffers > 0);
4953
4954 /* XLogCtl */
4955 size = sizeof(XLogCtlData);
4956
4957 /* WAL insertion locks, plus alignment */
4958 size = add_size(size, mul_size(sizeof(WALInsertLockPadded), NUM_XLOGINSERT_LOCKS + 1));
4959 /* xlblocks array */
4960 size = add_size(size, mul_size(sizeof(pg_atomic_uint64), XLOGbuffers));
4961 /* extra alignment padding for XLOG I/O buffers */
4962 size = add_size(size, Max(XLOG_BLCKSZ, PG_IO_ALIGN_SIZE));
4963 /* and the buffers themselves */
4964 size = add_size(size, mul_size(XLOG_BLCKSZ, XLOGbuffers));
4965
4966 /*
4967 * Note: we don't count ControlFileData, it comes out of the "slop factor"
4968 * added by CreateSharedMemoryAndSemaphores. This lets us use this
4969 * routine again below to compute the actual allocation size.
4970 */
4971
4972 return size;
4973}
#define Max(x, y)
Definition: c.h:1010
void SetConfigOption(const char *name, const char *value, GucContext context, GucSource source)
Definition: guc.c:4196
@ 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:495
Size mul_size(Size s1, Size s2)
Definition: shmem.c:510
static int XLOGChooseNumBuffers(void)
Definition: xlog.c:4677

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

9536{
9538
9541}
#define AmStartupProcess()
Definition: miscadmin.h:390
void ShutdownWalRcv(void)
void ResetInstallXLogFileSegmentActive(void)
Definition: xlog.c:9554

References AmStartupProcess, Assert(), IsUnderPostmaster, ResetInstallXLogFileSegmentActive(), and ShutdownWalRcv().

Referenced by FinishWalRecovery(), and WaitForWALToBecomeAvailable().

Variable Documentation

◆ CheckPointSegments

PGDLLIMPORT int CheckPointSegments
extern

◆ CheckpointStats

◆ CommitDelay

PGDLLIMPORT int CommitDelay
extern

Definition at line 134 of file xlog.c.

Referenced by XLogFlush().

◆ CommitSiblings

PGDLLIMPORT int CommitSiblings
extern

Definition at line 135 of file xlog.c.

Referenced by XLogFlush().

◆ EnableHotStandby

◆ fullPageWrites

PGDLLIMPORT bool fullPageWrites
extern

Definition at line 124 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 137 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 117 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 126 of file xlog.c.

Referenced by XLogCompressBackupBlock(), and XLogRecordAssemble().

◆ wal_consistency_checking

PGDLLIMPORT bool* wal_consistency_checking
extern

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

Referenced by InitializeWalConsistencyChecking().

◆ wal_decode_buffer_size

PGDLLIMPORT int wal_decode_buffer_size
extern

Definition at line 138 of file xlog.c.

Referenced by InitWalRecovery().

◆ wal_init_zero

PGDLLIMPORT bool wal_init_zero
extern

Definition at line 129 of file xlog.c.

Referenced by XLogFileInitInternal().

◆ wal_keep_size_mb

PGDLLIMPORT int wal_keep_size_mb
extern

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

Referenced by InitControlFile(), and XLogReportParameters().

◆ wal_recycle

PGDLLIMPORT bool wal_recycle
extern

Definition at line 130 of file xlog.c.

Referenced by RemoveXlogFile().

◆ wal_retrieve_retry_interval

PGDLLIMPORT int wal_retrieve_retry_interval
extern

Definition at line 136 of file xlog.c.

Referenced by ApplyLauncherMain(), launch_sync_worker(), and WaitForWALToBecomeAvailable().

◆ wal_segment_size

PGDLLIMPORT int wal_segment_size
extern

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

Referenced by CheckArchiveTimeout(), and CheckpointerMain().

◆ XLOGbuffers

PGDLLIMPORT int XLOGbuffers
extern

Definition at line 119 of file xlog.c.

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