PostgreSQL Source Code git master
Loading...
Searching...
No Matches
xlog.h File Reference
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 || XLogLogicalInfo)
 
#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)
 
XLogRecPtr XLogGetReplicationSlotMinimumLSN (void)
 
void xlog_redo (struct XLogReaderState *record)
 
void xlog_desc (StringInfo buf, struct XLogReaderState *record)
 
const charxlog_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)
 
charGetMockAuthenticationNonce (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)
 
void WakeupCheckpointer (void)
 
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 charXLogArchiveCommand
 
PGDLLIMPORT bool EnableHotStandby
 
PGDLLIMPORT bool fullPageWrites
 
PGDLLIMPORT bool wal_log_hints
 
PGDLLIMPORT int wal_compression
 
PGDLLIMPORT bool wal_init_zero
 
PGDLLIMPORT bool wal_recycle
 
PGDLLIMPORT boolwal_consistency_checking
 
PGDLLIMPORT charwal_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 bool XLogLogicalInfo
 
PGDLLIMPORT CheckpointStatsData CheckpointStats
 

Macro Definition Documentation

◆ BACKUP_LABEL_FILE

#define BACKUP_LABEL_FILE   "backup_label"

Definition at line 319 of file xlog.h.

◆ BACKUP_LABEL_OLD

#define BACKUP_LABEL_OLD   "backup_label.old"

Definition at line 320 of file xlog.h.

◆ CHECKPOINT_CAUSE_TIME

#define CHECKPOINT_CAUSE_TIME   0x0100 /* Elapsed time */

Definition at line 160 of file xlog.h.

◆ CHECKPOINT_CAUSE_XLOG

#define CHECKPOINT_CAUSE_XLOG   0x0080 /* XLOG consumption */

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

172{
173 TimestampTz ckpt_start_t; /* start of checkpoint */
174 TimestampTz ckpt_write_t; /* start of flushing buffers */
175 TimestampTz ckpt_sync_t; /* start of fsyncs */
176 TimestampTz ckpt_sync_end_t; /* end of fsyncs */
177 TimestampTz ckpt_end_t; /* end of checkpoint */
178
179 int ckpt_bufs_written; /* # of buffers written */
180 int ckpt_slru_written; /* # of SLRU buffers written */
181
182 int ckpt_segs_added; /* # of new xlog segments created */
183 int ckpt_segs_removed; /* # of xlog segments deleted */
184 int ckpt_segs_recycled; /* # of xlog segments recycled */
185
186 int ckpt_sync_rels; /* # of relations synced */
187 uint64 ckpt_longest_sync; /* Longest sync for one relation */
188 uint64 ckpt_agg_sync_time; /* The sum of all the individual sync
189 * times, which is not necessarily the
190 * same as the total elapsed time for the
191 * entire sync phase. */
193
195
196/*
197 * GetWALAvailability return codes
198 */
199typedef enum WALAvailability
200{
201 WALAVAIL_INVALID_LSN, /* parameter error */
202 WALAVAIL_RESERVED, /* WAL segment is within max_wal_size */
203 WALAVAIL_EXTENDED, /* WAL segment is reserved by a slot or
204 * wal_keep_size */
205 WALAVAIL_UNRESERVED, /* no longer reserved, but not removed yet */
206 WALAVAIL_REMOVED, /* WAL segment has been removed */
208
209struct XLogRecData;
210struct XLogReaderState;
211
214 uint8 flags,
215 int num_fpi,
217 bool topxid_included);
218extern void XLogFlush(XLogRecPtr record);
219extern bool XLogBackgroundFlush(void);
220extern bool XLogNeedsFlush(XLogRecPtr record);
222extern int XLogFileOpen(XLogSegNo segno, TimeLineID tli);
223
224extern void CheckXLogRemoved(XLogSegNo segno, TimeLineID tli);
227extern void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN);
230
231extern void xlog_redo(struct XLogReaderState *record);
232extern void xlog_desc(StringInfo buf, struct XLogReaderState *record);
233extern const char *xlog_identify(uint8 info);
234
235extern void issue_xlog_fsync(int fd, XLogSegNo segno, TimeLineID tli);
236
237extern bool RecoveryInProgress(void);
239extern bool XLogInsertAllowed(void);
241extern XLogRecPtr GetXLogWriteRecPtr(void);
242
243extern uint64 GetSystemIdentifier(void);
244extern char *GetMockAuthenticationNonce(void);
245extern bool DataChecksumsEnabled(void);
246extern bool GetDefaultCharSignedness(void);
248extern Size XLOGShmemSize(void);
249extern void XLOGShmemInit(void);
250extern void BootStrapXLOG(uint32 data_checksum_version);
251extern void InitializeWalConsistencyChecking(void);
252extern void LocalProcessControlFile(bool reset);
254extern void StartupXLOG(void);
255extern void ShutdownXLOG(int code, Datum arg);
256extern bool CreateCheckPoint(int flags);
257extern bool CreateRestartPoint(int flags);
259extern void XLogPutNextOid(Oid nextOid);
260extern XLogRecPtr XLogRestorePoint(const char *rpName);
261extern void UpdateFullPageWrites(void);
263extern XLogRecPtr GetRedoRecPtr(void);
264extern XLogRecPtr GetInsertRecPtr(void);
269
270extern void SetWalWriterSleeping(bool sleeping);
271
272extern void WakeupCheckpointer(void);
273
274extern Size WALReadFromBuffers(char *dstbuf, XLogRecPtr startptr, Size count,
275 TimeLineID tli);
276
277/*
278 * Routines used by xlogrecovery.c to call back into xlog.c during recovery.
279 */
284extern void SetInstallXLogFileSegmentActive(void);
285extern bool IsInstallXLogFileSegmentActive(void);
286extern void ResetInstallXLogFileSegmentActive(void);
287extern void XLogShutdownWalRcv(void);
288
289/*
290 * Routines to start, stop, and get status of a base backup.
291 */
292
293/*
294 * Session-level status of base backups
295 *
296 * This is used in parallel with the shared memory status to control parallel
297 * execution of base backup functions for a given session, be it a backend
298 * dedicated to replication or a normal backend connected to a database. The
299 * update of the session-level status happens at the same time as the shared
300 * memory counters to keep a consistent global and local state of the backups
301 * running.
302 */
303typedef enum SessionBackupState
304{
308
309extern void do_pg_backup_start(const char *backupidstr, bool fast,
310 List **tablespaces, BackupState *state,
313extern void do_pg_abort_backup(int code, Datum arg);
316
317/* File path names (all relative to $PGDATA) */
318#define RECOVERY_SIGNAL_FILE "recovery.signal"
319#define STANDBY_SIGNAL_FILE "standby.signal"
320#define BACKUP_LABEL_FILE "backup_label"
321#define BACKUP_LABEL_OLD "backup_label.old"
322
323#define TABLESPACE_MAP "tablespace_map"
324#define TABLESPACE_MAP_OLD "tablespace_map.old"
325
326/* files to signal promotion to primary */
327#define PROMOTE_SIGNAL_FILE "promote"
328
329#endif /* XLOG_H */
#define PGDLLIMPORT
Definition c.h:1393
uint8_t uint8
Definition c.h:586
uint64_t uint64
Definition c.h:589
uint32_t uint32
Definition c.h:588
size_t Size
Definition c.h:661
int64 TimestampTz
Definition timestamp.h:39
Datum arg
Definition elog.c:1322
static char buf[DEFAULT_XLOG_SEG_SIZE]
uint64_t Datum
Definition postgres.h:70
unsigned int Oid
static int fd(const char *x, int i)
static int fb(int x)
void reset(void)
Definition pg_list.h:54
DecodedXLogRecord * record
Definition xlogreader.h:235
XLogRecPtr EndRecPtr
Definition xlogreader.h:206
int XLogFileInit(XLogSegNo logsegno, TimeLineID logtli)
Definition xlog.c:3401
uint64 GetSystemIdentifier(void)
Definition xlog.c:4611
void UpdateFullPageWrites(void)
Definition xlog.c:8295
bool RecoveryInProgress(void)
Definition xlog.c:6444
void GetFullPageWriteInfo(XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p)
Definition xlog.c:6577
TimeLineID GetWALInsertionTimeLine(void)
Definition xlog.c:6630
void do_pg_abort_backup(int code, Datum arg)
Definition xlog.c:9545
XLogSegNo XLogGetLastRemovedSegno(void)
Definition xlog.c:3779
void xlog_desc(StringInfo buf, struct XLogReaderState *record)
Definition xlogdesc.c:58
Size WALReadFromBuffers(char *dstbuf, XLogRecPtr startptr, Size count, TimeLineID tli)
Definition xlog.c:1755
XLogRecPtr GetRedoRecPtr(void)
Definition xlog.c:6547
void SetInstallXLogFileSegmentActive(void)
Definition xlog.c:9634
void StartupXLOG(void)
Definition xlog.c:5501
bool IsInstallXLogFileSegmentActive(void)
Definition xlog.c:9651
void BootStrapXLOG(uint32 data_checksum_version)
Definition xlog.c:5110
bool CreateRestartPoint(int flags)
Definition xlog.c:7715
XLogRecPtr GetInsertRecPtr(void)
Definition xlog.c:6592
XLogRecPtr XLogGetReplicationSlotMinimumLSN(void)
Definition xlog.c:2666
SessionBackupState get_backup_status(void)
Definition xlog.c:9252
void CheckXLogRemoved(XLogSegNo segno, TimeLineID tli)
Definition xlog.c:3748
WALAvailability
Definition xlog.h:199
@ WALAVAIL_REMOVED
Definition xlog.h:205
@ WALAVAIL_RESERVED
Definition xlog.h:201
@ WALAVAIL_UNRESERVED
Definition xlog.h:204
@ WALAVAIL_EXTENDED
Definition xlog.h:202
@ WALAVAIL_INVALID_LSN
Definition xlog.h:200
PGDLLIMPORT CheckpointStatsData CheckpointStats
Definition xlog.c:213
WALAvailability GetWALAvailability(XLogRecPtr targetLSN)
Definition xlog.c:7996
void XLOGShmemInit(void)
Definition xlog.c:4995
void ShutdownXLOG(int code, Datum arg)
Definition xlog.c:6712
bool DataChecksumsEnabled(void)
Definition xlog.c:4631
RecoveryState GetRecoveryState(void)
Definition xlog.c:6480
const char * xlog_identify(uint8 info)
Definition xlogdesc.c:181
void XLogSetReplicationSlotMinimumLSN(XLogRecPtr lsn)
Definition xlog.c:2653
void SwitchIntoArchiveRecovery(XLogRecPtr EndRecPtr, TimeLineID replayTLI)
Definition xlog.c:6319
bool GetDefaultCharSignedness(void)
Definition xlog.c:4645
XLogRecPtr GetXLogInsertRecPtr(void)
Definition xlog.c:9586
Size XLOGShmemSize(void)
Definition xlog.c:4945
void SetWalWriterSleeping(bool sleeping)
Definition xlog.c:9666
void WakeupCheckpointer(void)
int XLogFileOpen(XLogSegNo segno, TimeLineID tli)
Definition xlog.c:3639
XLogRecPtr GetFlushRecPtr(TimeLineID *insertTLI)
Definition xlog.c:6609
WalLevel GetActiveWalLevelOnStandby(void)
Definition xlog.c:4936
void xlog_redo(struct XLogReaderState *record)
Definition xlog.c:8364
void InitializeWalConsistencyChecking(void)
Definition xlog.c:4842
void RemoveNonParentXlogFiles(XLogRecPtr switchpoint, TimeLineID newTLI)
Definition xlog.c:3961
XLogRecPtr GetLastImportantRecPtr(void)
Definition xlog.c:6666
SessionBackupState
Definition xlog.h:303
@ SESSION_BACKUP_RUNNING
Definition xlog.h:305
@ SESSION_BACKUP_NONE
Definition xlog.h:304
XLogRecPtr XLogInsertRecord(struct XLogRecData *rdata, XLogRecPtr fpw_lsn, uint8 flags, int num_fpi, uint64 fpi_bytes, bool topxid_included)
Definition xlog.c:750
bool XLogNeedsFlush(XLogRecPtr record)
Definition xlog.c:3129
void register_persistent_abort_backup_handler(void)
Definition xlog.c:9572
void ReachedEndOfBackup(XLogRecPtr EndRecPtr, TimeLineID tli)
Definition xlog.c:6357
void LocalProcessControlFile(bool reset)
Definition xlog.c:4923
XLogSegNo XLogGetOldestSegno(TimeLineID tli)
Definition xlog.c:3795
XLogRecPtr GetXLogWriteRecPtr(void)
Definition xlog.c:9602
void ResetInstallXLogFileSegmentActive(void)
Definition xlog.c:9643
bool XLogBackgroundFlush(void)
Definition xlog.c:2972
char * GetMockAuthenticationNonce(void)
Definition xlog.c:4621
bool XLogInsertAllowed(void)
Definition xlog.c:6499
void do_pg_backup_start(const char *backupidstr, bool fast, List **tablespaces, BackupState *state, StringInfo tblspcmapfile)
Definition xlog.c:8949
XLogRecPtr XLogRestorePoint(const char *rpName)
Definition xlog.c:8207
TimeLineID GetWALInsertionTimeLineIfSet(void)
Definition xlog.c:6646
void do_pg_backup_stop(BackupState *state, bool waitforarchive)
Definition xlog.c:9271
WalLevel
Definition xlog.h:74
bool CreateCheckPoint(int flags)
Definition xlog.c:7009
XLogRecPtr GetFakeLSNForUnloggedRel(void)
Definition xlog.c:4660
void XLogPutNextOid(Oid nextOid)
Definition xlog.c:8152
void XLogFlush(XLogRecPtr record)
Definition xlog.c:2767
RecoveryState
Definition xlog.h:91
void XLogShutdownWalRcv(void)
Definition xlog.c:9624
void issue_xlog_fsync(int fd, XLogSegNo segno, TimeLineID tli)
Definition xlog.c:8852
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
Definition xlog.c:2596
bool XLogCheckpointNeeded(XLogSegNo new_segno)
Definition xlog.c:2267
uint64 XLogRecPtr
Definition xlogdefs.h:21
uint32 TimeLineID
Definition xlogdefs.h:63
uint64 XLogSegNo
Definition xlogdefs.h:52

◆ CHECKPOINT_FAST

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

Definition at line 152 of file xlog.h.

◆ CHECKPOINT_FLUSH_UNLOGGED

#define CHECKPOINT_FLUSH_UNLOGGED   0x0010 /* Flush unlogged tables */

Definition at line 154 of file xlog.h.

◆ CHECKPOINT_FORCE

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

Definition at line 153 of file xlog.h.

◆ CHECKPOINT_IS_SHUTDOWN

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

Definition at line 150 of file xlog.h.

◆ CHECKPOINT_REQUESTED

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

Definition at line 157 of file xlog.h.

◆ CHECKPOINT_WAIT

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

Definition at line 156 of file xlog.h.

◆ PROMOTE_SIGNAL_FILE

#define PROMOTE_SIGNAL_FILE   "promote"

Definition at line 326 of file xlog.h.

◆ RECOVERY_SIGNAL_FILE

#define RECOVERY_SIGNAL_FILE   "recovery.signal"

Definition at line 317 of file xlog.h.

◆ STANDBY_SIGNAL_FILE

#define STANDBY_SIGNAL_FILE   "standby.signal"

Definition at line 318 of file xlog.h.

◆ TABLESPACE_MAP

#define TABLESPACE_MAP   "tablespace_map"

Definition at line 322 of file xlog.h.

◆ TABLESPACE_MAP_OLD

#define TABLESPACE_MAP_OLD   "tablespace_map.old"

Definition at line 323 of file xlog.h.

◆ XLOG_INCLUDE_ORIGIN

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

Definition at line 165 of file xlog.h.

◆ XLOG_MARK_UNIMPORTANT

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

Definition at line 166 of file xlog.h.

◆ XLogArchivingActive

Definition at line 101 of file xlog.h.

◆ XLogArchivingAlways

Definition at line 104 of file xlog.h.

◆ XLogHintBitIsNeeded

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

Definition at line 122 of file xlog.h.

◆ XLogIsNeeded

#define XLogIsNeeded ( )    (wal_level >= WAL_LEVEL_REPLICA)

Definition at line 111 of file xlog.h.

◆ XLogLogicalInfoActive

#define XLogLogicalInfoActive ( )     (wal_level >= WAL_LEVEL_LOGICAL || XLogLogicalInfo)

Definition at line 136 of file xlog.h.

◆ XLogStandbyInfoActive

#define XLogStandbyInfoActive ( )    (wal_level >= WAL_LEVEL_REPLICA)

Definition at line 125 of file xlog.h.

Typedef Documentation

◆ ArchiveMode

◆ CheckpointStatsData

◆ RecoveryState

◆ SessionBackupState

◆ WALAvailability

◆ WalCompression

◆ WalLevel

Enumeration Type Documentation

◆ ArchiveMode

Enumerator
ARCHIVE_MODE_OFF 
ARCHIVE_MODE_ON 
ARCHIVE_MODE_ALWAYS 

Definition at line 64 of file xlog.h.

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

◆ RecoveryState

Enumerator
RECOVERY_STATE_CRASH 
RECOVERY_STATE_ARCHIVE 
RECOVERY_STATE_DONE 

Definition at line 90 of file xlog.h.

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

◆ SessionBackupState

Enumerator
SESSION_BACKUP_NONE 
SESSION_BACKUP_RUNNING 

Definition at line 302 of file xlog.h.

◆ WALAvailability

Enumerator
WALAVAIL_INVALID_LSN 
WALAVAIL_RESERVED 
WALAVAIL_EXTENDED 
WALAVAIL_UNRESERVED 
WALAVAIL_REMOVED 

Definition at line 198 of file xlog.h.

200{
201 WALAVAIL_INVALID_LSN, /* parameter error */
202 WALAVAIL_RESERVED, /* WAL segment is within max_wal_size */
203 WALAVAIL_EXTENDED, /* WAL segment is reserved by a slot or
204 * wal_keep_size */
205 WALAVAIL_UNRESERVED, /* no longer reserved, but not removed yet */
206 WALAVAIL_REMOVED, /* WAL segment has been removed */

◆ WalCompression

Enumerator
WAL_COMPRESSION_NONE 
WAL_COMPRESSION_PGLZ 
WAL_COMPRESSION_LZ4 
WAL_COMPRESSION_ZSTD 

Definition at line 81 of file xlog.h.

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

◆ WalLevel

Enumerator
WAL_LEVEL_MINIMAL 
WAL_LEVEL_REPLICA 
WAL_LEVEL_LOGICAL 

Definition at line 73 of file xlog.h.

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

◆ 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 23 of file xlog.h.

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

Function Documentation

◆ BootStrapXLOG()

void BootStrapXLOG ( uint32  data_checksum_version)
extern

Definition at line 5110 of file xlog.c.

5111{
5112 CheckPoint checkPoint;
5113 PGAlignedXLogBlock buffer;
5114 XLogPageHeader page;
5116 XLogRecord *record;
5117 char *recptr;
5118 uint64 sysidentifier;
5119 struct timeval tv;
5120 pg_crc32c crc;
5121
5122 /* allow ordinary WAL segment creation, like StartupXLOG() would */
5124
5125 /*
5126 * Select a hopefully-unique system identifier code for this installation.
5127 * We use the result of gettimeofday(), including the fractional seconds
5128 * field, as being about as unique as we can easily get. (Think not to
5129 * use random(), since it hasn't been seeded and there's no portable way
5130 * to seed it other than the system clock value...) The upper half of the
5131 * uint64 value is just the tv_sec part, while the lower half contains the
5132 * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
5133 * PID for a little extra uniqueness. A person knowing this encoding can
5134 * determine the initialization time of the installation, which could
5135 * perhaps be useful sometimes.
5136 */
5137 gettimeofday(&tv, NULL);
5138 sysidentifier = ((uint64) tv.tv_sec) << 32;
5139 sysidentifier |= ((uint64) tv.tv_usec) << 12;
5140 sysidentifier |= getpid() & 0xFFF;
5141
5142 memset(&buffer, 0, sizeof buffer);
5143 page = (XLogPageHeader) &buffer;
5144
5145 /*
5146 * Set up information for the initial checkpoint record
5147 *
5148 * The initial checkpoint record is written to the beginning of the WAL
5149 * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5150 * used, so that we can use 0/0 to mean "before any valid WAL segment".
5151 */
5155 checkPoint.fullPageWrites = fullPageWrites;
5157 checkPoint.wal_level = wal_level;
5158 checkPoint.nextXid =
5160 checkPoint.nextOid = FirstGenbkiObjectId;
5161 checkPoint.nextMulti = FirstMultiXactId;
5162 checkPoint.nextMultiOffset = 1;
5164 checkPoint.oldestXidDB = Template1DbOid;
5165 checkPoint.oldestMulti = FirstMultiXactId;
5166 checkPoint.oldestMultiDB = Template1DbOid;
5169 checkPoint.time = (pg_time_t) time(NULL);
5171
5172 TransamVariables->nextXid = checkPoint.nextXid;
5173 TransamVariables->nextOid = checkPoint.nextOid;
5175 MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5176 AdvanceOldestClogXid(checkPoint.oldestXid);
5177 SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5178 SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB);
5180
5181 /* Set up the XLOG page header */
5182 page->xlp_magic = XLOG_PAGE_MAGIC;
5183 page->xlp_info = XLP_LONG_HEADER;
5187 longpage->xlp_sysid = sysidentifier;
5188 longpage->xlp_seg_size = wal_segment_size;
5189 longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5190
5191 /* Insert the initial checkpoint record */
5192 recptr = ((char *) page + SizeOfXLogLongPHD);
5193 record = (XLogRecord *) recptr;
5194 record->xl_prev = InvalidXLogRecPtr;
5195 record->xl_xid = InvalidTransactionId;
5196 record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5198 record->xl_rmid = RM_XLOG_ID;
5200 /* fill the XLogRecordDataHeaderShort struct */
5201 *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5202 *(recptr++) = sizeof(checkPoint);
5203 memcpy(recptr, &checkPoint, sizeof(checkPoint));
5204 recptr += sizeof(checkPoint);
5205 Assert(recptr - (char *) record == record->xl_tot_len);
5206
5208 COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5209 COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5210 FIN_CRC32C(crc);
5211 record->xl_crc = crc;
5212
5213 /* Create first XLOG segment file */
5216
5217 /*
5218 * We needn't bother with Reserve/ReleaseExternalFD here, since we'll
5219 * close the file again in a moment.
5220 */
5221
5222 /* Write the first page with the initial record */
5223 errno = 0;
5225 if (write(openLogFile, &buffer, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5226 {
5227 /* if write didn't set errno, assume problem is no disk space */
5228 if (errno == 0)
5229 errno = ENOSPC;
5230 ereport(PANIC,
5232 errmsg("could not write bootstrap write-ahead log file: %m")));
5233 }
5235
5237 if (pg_fsync(openLogFile) != 0)
5238 ereport(PANIC,
5240 errmsg("could not fsync bootstrap write-ahead log file: %m")));
5242
5243 if (close(openLogFile) != 0)
5244 ereport(PANIC,
5246 errmsg("could not close bootstrap write-ahead log file: %m")));
5247
5248 openLogFile = -1;
5249
5250 /* Now create pg_control */
5251 InitControlFile(sysidentifier, data_checksum_version);
5252 ControlFile->time = checkPoint.time;
5253 ControlFile->checkPoint = checkPoint.redo;
5254 ControlFile->checkPointCopy = checkPoint;
5255
5256 /* some additional ControlFile fields are set in WriteControlFile() */
5258
5259 /* Bootstrap the commit log, too */
5260 BootStrapCLOG();
5264
5265 /*
5266 * Force control file to be read - in contrast to normal processing we'd
5267 * otherwise never run the checks and GUC related initializations therein.
5268 */
5270}
#define Assert(condition)
Definition c.h:915
void BootStrapCLOG(void)
Definition clog.c:833
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:897
#define PANIC
Definition elog.h:42
#define ereport(elevel,...)
Definition elog.h:150
int pg_fsync(int fd)
Definition fd.c:390
#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:2041
void BootStrapMultiXact(void)
Definition multixact.c:1842
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid)
Definition multixact.c:2063
#define FirstMultiXactId
Definition multixact.h:26
static char * errmsg
#define XLOG_CHECKPOINT_SHUTDOWN
Definition pg_control.h:69
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:52
MultiXactId oldestMulti
Definition pg_control.h:51
MultiXactOffset nextMultiOffset
Definition pg_control.h:48
TransactionId newestCommitTsXid
Definition pg_control.h:56
TransactionId oldestXid
Definition pg_control.h:49
TimeLineID PrevTimeLineID
Definition pg_control.h:40
TimeLineID ThisTimeLineID
Definition pg_control.h:39
TransactionId oldestActiveXid
Definition pg_control.h:65
bool fullPageWrites
Definition pg_control.h:42
MultiXactId nextMulti
Definition pg_control.h:47
FullTransactionId nextXid
Definition pg_control.h:45
TransactionId oldestCommitTsXid
Definition pg_control.h:54
pg_time_t time
Definition pg_control.h:53
int wal_level
Definition pg_control.h:43
bool logicalDecodingEnabled
Definition pg_control.h:44
XLogRecPtr redo
Definition pg_control.h:37
Oid oldestXidDB
Definition pg_control.h:50
CheckPoint checkPointCopy
Definition pg_control.h:137
pg_time_t time
Definition pg_control.h:134
XLogRecPtr checkPoint
Definition pg_control.h:135
FullTransactionId nextXid
Definition transam.h:220
XLogRecPtr xlp_pageaddr
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:126
static void InitControlFile(uint64 sysidentifier, uint32 data_checksum_version)
Definition xlog.c:4225
void SetInstallXLogFileSegmentActive(void)
Definition xlog.c:9634
static int openLogFile
Definition xlog.c:638
int wal_level
Definition xlog.c:135
static void WriteControlFile(void)
Definition xlog.c:4260
int wal_segment_size
Definition xlog.c:147
static TimeLineID openLogTLI
Definition xlog.c:640
static ControlFileData * ControlFile
Definition xlog.c:577
#define BootstrapTimeLineID
Definition xlog.c:115
static void ReadControlFile(void)
Definition xlog.c:4370
XLogLongPageHeaderData * XLogLongPageHeader
XLogPageHeaderData * XLogPageHeader
#define XLP_LONG_HEADER
#define XLOG_PAGE_MAGIC
#define SizeOfXLogLongPHD
#define InvalidXLogRecPtr
Definition xlogdefs.h:28
#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, fb(), FIN_CRC32C, FirstGenbkiObjectId, FirstMultiXactId, FirstNormalTransactionId, fullPageWrites, CheckPoint::fullPageWrites, FullTransactionIdFromEpochAndXid(), gettimeofday(), INIT_CRC32C, InitControlFile(), InvalidTransactionId, InvalidXLogRecPtr, CheckPoint::logicalDecodingEnabled, 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_LEVEL_LOGICAL, 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, XLogPageHeaderData::xlp_tli, and XLR_BLOCK_ID_DATA_SHORT.

Referenced by BootstrapModeMain().

◆ CheckXLogRemoved()

void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)
extern

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:133
static void SpinLockRelease(volatile slock_t *lock)
Definition spin.h:62
static void SpinLockAcquire(volatile slock_t *lock)
Definition spin.h:56
slock_t info_lck
Definition xlog.c:556
XLogSegNo lastRemovedSegNo
Definition xlog.c:464
static XLogCtlData * XLogCtl
Definition xlog.c:569
#define MAXFNAMELEN
static void XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)

References ereport, errcode_for_file_access(), errmsg, ERROR, fb(), 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)
extern

Definition at line 7009 of file xlog.c.

7010{
7011 bool shutdown;
7012 CheckPoint checkPoint;
7016 uint32 freespace;
7020 int nvxids;
7021 int oldXLogAllowed = 0;
7022
7023 /*
7024 * An end-of-recovery checkpoint is really a shutdown checkpoint, just
7025 * issued at a different time.
7026 */
7028 shutdown = true;
7029 else
7030 shutdown = false;
7031
7032 /* sanity check */
7033 if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
7034 elog(ERROR, "can't create a checkpoint during recovery");
7035
7036 /*
7037 * Prepare to accumulate statistics.
7038 *
7039 * Note: because it is possible for log_checkpoints to change while a
7040 * checkpoint proceeds, we always accumulate stats, even if
7041 * log_checkpoints is currently off.
7042 */
7045
7046 /*
7047 * Let smgr prepare for checkpoint; this has to happen outside the
7048 * critical section and before we determine the REDO pointer. Note that
7049 * smgr must not do anything that'd have to be undone if we decide no
7050 * checkpoint is needed.
7051 */
7053
7054 /* Run these points outside the critical section. */
7055 INJECTION_POINT("create-checkpoint-initial", NULL);
7056 INJECTION_POINT_LOAD("create-checkpoint-run");
7057
7058 /*
7059 * Use a critical section to force system panic if we have trouble.
7060 */
7062
7063 if (shutdown)
7064 {
7069 }
7070
7071 /* Begin filling in the checkpoint WAL record */
7072 MemSet(&checkPoint, 0, sizeof(checkPoint));
7073 checkPoint.time = (pg_time_t) time(NULL);
7074
7075 /*
7076 * For Hot Standby, derive the oldestActiveXid before we fix the redo
7077 * pointer. This allows us to begin accumulating changes to assemble our
7078 * starting snapshot of locks and transactions.
7079 */
7081 checkPoint.oldestActiveXid = GetOldestActiveTransactionId(false, true);
7082 else
7084
7085 /*
7086 * Get location of last important record before acquiring insert locks (as
7087 * GetLastImportantRecPtr() also locks WAL locks).
7088 */
7090
7091 /*
7092 * If this isn't a shutdown or forced checkpoint, and if there has been no
7093 * WAL activity requiring a checkpoint, skip it. The idea here is to
7094 * avoid inserting duplicate checkpoints when the system is idle.
7095 */
7097 CHECKPOINT_FORCE)) == 0)
7098 {
7100 {
7103 (errmsg_internal("checkpoint skipped because system is idle")));
7104 return false;
7105 }
7106 }
7107
7108 /*
7109 * An end-of-recovery checkpoint is created before anyone is allowed to
7110 * write WAL. To allow us to write the checkpoint record, temporarily
7111 * enable XLogInsertAllowed.
7112 */
7113 if (flags & CHECKPOINT_END_OF_RECOVERY)
7115
7117 if (flags & CHECKPOINT_END_OF_RECOVERY)
7119 else
7120 checkPoint.PrevTimeLineID = checkPoint.ThisTimeLineID;
7121
7122 /*
7123 * We must block concurrent insertions while examining insert state.
7124 */
7126
7127 checkPoint.fullPageWrites = Insert->fullPageWrites;
7128 checkPoint.wal_level = wal_level;
7129
7130 if (shutdown)
7131 {
7133
7134 /*
7135 * Compute new REDO record ptr = location of next XLOG record.
7136 *
7137 * Since this is a shutdown checkpoint, there can't be any concurrent
7138 * WAL insertion.
7139 */
7140 freespace = INSERT_FREESPACE(curInsert);
7141 if (freespace == 0)
7142 {
7145 else
7147 }
7148 checkPoint.redo = curInsert;
7149
7150 /*
7151 * Here we update the shared RedoRecPtr for future XLogInsert calls;
7152 * this must be done while holding all the insertion locks.
7153 *
7154 * Note: if we fail to complete the checkpoint, RedoRecPtr will be
7155 * left pointing past where it really needs to point. This is okay;
7156 * the only consequence is that XLogInsert might back up whole buffers
7157 * that it didn't really need to. We can't postpone advancing
7158 * RedoRecPtr because XLogInserts that happen while we are dumping
7159 * buffers must assume that their buffer changes are not included in
7160 * the checkpoint.
7161 */
7162 RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
7163 }
7164
7165 /*
7166 * Now we can release the WAL insertion locks, allowing other xacts to
7167 * proceed while we are flushing disk buffers.
7168 */
7170
7171 /*
7172 * If this is an online checkpoint, we have not yet determined the redo
7173 * point. We do so now by inserting the special XLOG_CHECKPOINT_REDO
7174 * record; the LSN at which it starts becomes the new redo pointer. We
7175 * don't do this for a shutdown checkpoint, because in that case no WAL
7176 * can be written between the redo point and the insertion of the
7177 * checkpoint record itself, so the checkpoint record itself serves to
7178 * mark the redo point.
7179 */
7180 if (!shutdown)
7181 {
7182 /* Include WAL level in record for WAL summarizer's benefit. */
7186
7187 /*
7188 * XLogInsertRecord will have updated XLogCtl->Insert.RedoRecPtr in
7189 * shared memory and RedoRecPtr in backend-local memory, but we need
7190 * to copy that into the record that will be inserted when the
7191 * checkpoint is complete.
7192 */
7193 checkPoint.redo = RedoRecPtr;
7194 }
7195
7196 /* Update the info_lck-protected copy of RedoRecPtr as well */
7198 XLogCtl->RedoRecPtr = checkPoint.redo;
7200
7201 /*
7202 * If enabled, log checkpoint start. We postpone this until now so as not
7203 * to log anything if we decided to skip the checkpoint.
7204 */
7205 if (log_checkpoints)
7206 LogCheckpointStart(flags, false);
7207
7208 INJECTION_POINT_CACHED("create-checkpoint-run", NULL);
7209
7210 /* Update the process title */
7211 update_checkpoint_display(flags, false, false);
7212
7214
7215 /*
7216 * Get the other info we need for the checkpoint record.
7217 *
7218 * We don't need to save oldestClogXid in the checkpoint, it only matters
7219 * for the short period in which clog is being truncated, and if we crash
7220 * during that we'll redo the clog truncation and fix up oldestClogXid
7221 * there.
7222 */
7224 checkPoint.nextXid = TransamVariables->nextXid;
7225 checkPoint.oldestXid = TransamVariables->oldestXid;
7228
7233
7235 checkPoint.nextOid = TransamVariables->nextOid;
7236 if (!shutdown)
7237 checkPoint.nextOid += TransamVariables->oidCount;
7239
7241
7243 &checkPoint.nextMulti,
7244 &checkPoint.nextMultiOffset,
7245 &checkPoint.oldestMulti,
7246 &checkPoint.oldestMultiDB);
7247
7248 /*
7249 * Having constructed the checkpoint record, ensure all shmem disk buffers
7250 * and commit-log buffers are flushed to disk.
7251 *
7252 * This I/O could fail for various reasons. If so, we will fail to
7253 * complete the checkpoint, but there is no reason to force a system
7254 * panic. Accordingly, exit critical section while doing it.
7255 */
7257
7258 /*
7259 * In some cases there are groups of actions that must all occur on one
7260 * side or the other of a checkpoint record. Before flushing the
7261 * checkpoint record we must explicitly wait for any backend currently
7262 * performing those groups of actions.
7263 *
7264 * One example is end of transaction, so we must wait for any transactions
7265 * that are currently in commit critical sections. If an xact inserted
7266 * its commit record into XLOG just before the REDO point, then a crash
7267 * restart from the REDO point would not replay that record, which means
7268 * that our flushing had better include the xact's update of pg_xact. So
7269 * we wait till he's out of his commit critical section before proceeding.
7270 * See notes in RecordTransactionCommit().
7271 *
7272 * Because we've already released the insertion locks, this test is a bit
7273 * fuzzy: it is possible that we will wait for xacts we didn't really need
7274 * to wait for. But the delay should be short and it seems better to make
7275 * checkpoint take a bit longer than to hold off insertions longer than
7276 * necessary. (In fact, the whole reason we have this issue is that xact.c
7277 * does commit record XLOG insertion and clog update as two separate steps
7278 * protected by different locks, but again that seems best on grounds of
7279 * minimizing lock contention.)
7280 *
7281 * A transaction that has not yet set delayChkptFlags when we look cannot
7282 * be at risk, since it has not inserted its commit record yet; and one
7283 * that's already cleared it is not at risk either, since it's done fixing
7284 * clog and we will correctly flush the update below. So we cannot miss
7285 * any xacts we need to wait for.
7286 */
7288 if (nvxids > 0)
7289 {
7290 do
7291 {
7292 /*
7293 * Keep absorbing fsync requests while we wait. There could even
7294 * be a deadlock if we don't, if the process that prevents the
7295 * checkpoint is trying to add a request to the queue.
7296 */
7298
7300 pg_usleep(10000L); /* wait for 10 msec */
7304 }
7305 pfree(vxids);
7306
7307 CheckPointGuts(checkPoint.redo, flags);
7308
7310 if (nvxids > 0)
7311 {
7312 do
7313 {
7315
7317 pg_usleep(10000L); /* wait for 10 msec */
7321 }
7322 pfree(vxids);
7323
7324 /*
7325 * Take a snapshot of running transactions and write this to WAL. This
7326 * allows us to reconstruct the state of running transactions during
7327 * archive recovery, if required. Skip, if this info disabled.
7328 *
7329 * If we are shutting down, or Startup process is completing crash
7330 * recovery we don't need to write running xact data.
7331 */
7334
7336
7337 /*
7338 * Now insert the checkpoint record into XLOG.
7339 */
7341 XLogRegisterData(&checkPoint, sizeof(checkPoint));
7345
7347
7348 /*
7349 * We mustn't write any new WAL after a shutdown checkpoint, or it will be
7350 * overwritten at next startup. No-one should even try, this just allows
7351 * sanity-checking. In the case of an end-of-recovery checkpoint, we want
7352 * to just temporarily disable writing until the system has exited
7353 * recovery.
7354 */
7355 if (shutdown)
7356 {
7357 if (flags & CHECKPOINT_END_OF_RECOVERY)
7359 else
7360 LocalXLogInsertAllowed = 0; /* never again write WAL */
7361 }
7362
7363 /*
7364 * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
7365 * = end of actual checkpoint record.
7366 */
7367 if (shutdown && checkPoint.redo != ProcLastRecPtr)
7368 ereport(PANIC,
7369 (errmsg("concurrent write-ahead log activity while database system is shutting down")));
7370
7371 /*
7372 * Remember the prior checkpoint's redo ptr for
7373 * UpdateCheckPointDistanceEstimate()
7374 */
7376
7377 /*
7378 * Update the control file.
7379 */
7381 if (shutdown)
7384 ControlFile->checkPointCopy = checkPoint;
7385 /* crash recovery should always recover to the end of WAL */
7388
7389 /*
7390 * Persist unloggedLSN value. It's reset on crash recovery, so this goes
7391 * unused on non-shutdown checkpoints, but seems useful to store it always
7392 * for debugging purposes.
7393 */
7395
7398
7399 /*
7400 * We are now done with critical updates; no need for system panic if we
7401 * have trouble while fooling with old log segments.
7402 */
7404
7405 /*
7406 * WAL summaries end when the next XLOG_CHECKPOINT_REDO or
7407 * XLOG_CHECKPOINT_SHUTDOWN record is reached. This is the first point
7408 * where (a) we're not inside of a critical section and (b) we can be
7409 * certain that the relevant record has been flushed to disk, which must
7410 * happen before it can be summarized.
7411 *
7412 * If this is a shutdown checkpoint, then this happens reasonably
7413 * promptly: we've only just inserted and flushed the
7414 * XLOG_CHECKPOINT_SHUTDOWN record. If this is not a shutdown checkpoint,
7415 * then this might not be very prompt at all: the XLOG_CHECKPOINT_REDO
7416 * record was written before we began flushing data to disk, and that
7417 * could be many minutes ago at this point. However, we don't XLogFlush()
7418 * after inserting that record, so we're not guaranteed that it's on disk
7419 * until after the above call that flushes the XLOG_CHECKPOINT_ONLINE
7420 * record.
7421 */
7423
7424 /*
7425 * Let smgr do post-checkpoint cleanup (eg, deleting old files).
7426 */
7428
7429 /*
7430 * Update the average distance between checkpoints if the prior checkpoint
7431 * exists.
7432 */
7435
7436 INJECTION_POINT("checkpoint-before-old-wal-removal", NULL);
7437
7438 /*
7439 * Delete old log files, those no longer needed for last checkpoint to
7440 * prevent the disk holding the xlog from growing full.
7441 */
7447 {
7448 /*
7449 * Some slots have been invalidated; recalculate the old-segment
7450 * horizon, starting again from RedoRecPtr.
7451 */
7454 }
7455 _logSegNo--;
7457 checkPoint.ThisTimeLineID);
7458
7459 /*
7460 * Make more log segments if needed. (Do this after recycling old log
7461 * segments, since that may supply some of the needed files.)
7462 */
7463 if (!shutdown)
7465
7466 /*
7467 * Truncate pg_subtrans if possible. We can throw away all data before
7468 * the oldest XMIN of any running transaction. No future transaction will
7469 * attempt to reference any pg_subtrans entry older than that (see Asserts
7470 * in subtrans.c). During recovery, though, we mustn't do this because
7471 * StartupSUBTRANS hasn't been called yet.
7472 */
7473 if (!RecoveryInProgress())
7475
7476 /* Real work is done; log and update stats. */
7477 LogCheckpointEnd(false, flags);
7478
7479 /* Reset the process title */
7480 update_checkpoint_display(flags, false, true);
7481
7483 NBuffers,
7487
7488 return true;
7489}
static uint64 pg_atomic_read_membarrier_u64(volatile pg_atomic_uint64 *ptr)
Definition atomics.h:476
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1643
#define MemSet(start, val, len)
Definition c.h:1079
void AbsorbSyncRequests(void)
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define DEBUG1
Definition elog.h:30
#define elog(elevel,...)
Definition elog.h:226
static void Insert(File file)
Definition fd.c:1301
int NBuffers
Definition globals.c:142
#define INJECTION_POINT(name, arg)
#define INJECTION_POINT_CACHED(name, arg)
#define INJECTION_POINT_LOAD(name)
bool IsLogicalDecodingEnabled(void)
Definition logicalctl.c:205
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1177
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1794
@ LW_SHARED
Definition lwlock.h:113
@ LW_EXCLUSIVE
Definition lwlock.h:112
void pfree(void *pointer)
Definition mcxt.c:1616
#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:1995
#define XLOG_CHECKPOINT_REDO
Definition pg_control.h:83
@ DB_SHUTDOWNING
Definition pg_control.h:96
@ DB_SHUTDOWNED
Definition pg_control.h:94
#define XLOG_CHECKPOINT_ONLINE
Definition pg_control.h:70
#define InvalidOid
#define DELAY_CHKPT_START
Definition proc.h:136
#define DELAY_CHKPT_COMPLETE
Definition proc.h:137
TransactionId GetOldestTransactionIdConsideredRunning(void)
Definition procarray.c:1981
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)
Definition procarray.c:3049
TransactionId GetOldestActiveTransactionId(bool inCommitOnly, bool allDbs)
Definition procarray.c:2832
VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
Definition procarray.c:3004
void pg_usleep(long microsec)
Definition signal.c:53
bool InvalidateObsoleteReplicationSlots(uint32 possible_causes, XLogSegNo oldestSegno, Oid dboid, TransactionId snapshotConflictHorizon)
Definition slot.c:2206
@ RS_INVAL_WAL_REMOVED
Definition slot.h:62
@ RS_INVAL_IDLE_TIMEOUT
Definition slot.h:68
XLogRecPtr LogStandbySnapshot(void)
Definition standby.c:1283
TimestampTz ckpt_start_t
Definition xlog.h:172
int ckpt_segs_removed
Definition xlog.h:182
int ckpt_bufs_written
Definition xlog.h:178
int ckpt_segs_recycled
Definition xlog.h:183
XLogRecPtr minRecoveryPoint
Definition pg_control.h:170
XLogRecPtr unloggedLSN
Definition pg_control.h:139
TimeLineID minRecoveryPointTLI
Definition pg_control.h:171
TransactionId oldestCommitTsXid
Definition transam.h:232
TransactionId newestCommitTsXid
Definition transam.h:233
TransactionId oldestXid
Definition transam.h:222
TimeLineID InsertTimeLineID
Definition xlog.c:512
XLogRecPtr RedoRecPtr
Definition xlog.c:460
XLogCtlInsert Insert
Definition xlog.c:456
TimeLineID PrevTimeLineID
Definition xlog.c:513
pg_atomic_uint64 unloggedLSN
Definition xlog.c:467
XLogRecPtr RedoRecPtr
Definition xlog.c:434
void TruncateSUBTRANS(TransactionId oldestXact)
Definition subtrans.c:385
void SyncPreCheckpoint(void)
Definition sync.c:178
void SyncPostCheckpoint(void)
Definition sync.c:203
void WakeupWalSummarizer(void)
XLogRecPtr ProcLastRecPtr
Definition xlog.c:257
bool RecoveryInProgress(void)
Definition xlog.c:6444
static void WALInsertLockRelease(void)
Definition xlog.c:1452
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition xlog.c:1865
static void WALInsertLockAcquireExclusive(void)
Definition xlog.c:1423
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:6781
static XLogRecPtr RedoRecPtr
Definition xlog.c:277
static void LogCheckpointEnd(bool restartpoint, int flags)
Definition xlog.c:6799
static void PreallocXlogFiles(XLogRecPtr endptr, TimeLineID tli)
Definition xlog.c:3711
bool log_checkpoints
Definition xlog.c:133
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition xlog.c:8080
static int LocalSetXLogInsertAllowed(void)
Definition xlog.c:6532
XLogRecPtr GetLastImportantRecPtr(void)
Definition xlog.c:6666
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition xlog.c:6906
#define INSERT_FREESPACE(endptr)
Definition xlog.c:583
static int LocalXLogInsertAllowed
Definition xlog.c:240
CheckpointStatsData CheckpointStats
Definition xlog.c:213
void XLogFlush(XLogRecPtr record)
Definition xlog.c:2767
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition xlog.c:7635
static void update_checkpoint_display(int flags, bool restartpoint, bool reset)
Definition xlog.c:6944
#define CHECKPOINT_END_OF_RECOVERY
Definition xlog.h:151
#define CHECKPOINT_FORCE
Definition xlog.h:153
#define CHECKPOINT_IS_SHUTDOWN
Definition xlog.h:150
#define XLogStandbyInfoActive()
Definition xlog.h:125
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)
#define SizeOfXLogShortPHD
#define XLogRecPtrIsValid(r)
Definition xlogdefs.h:29
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, fb(), CheckPoint::fullPageWrites, GetCurrentTimestamp(), GetLastImportantRecPtr(), GetOldestActiveTransactionId(), GetOldestTransactionIdConsideredRunning(), GetVirtualXIDsDelayingChkpt(), HaveVirtualXIDsDelayingChkpt(), XLogCtlData::info_lck, INJECTION_POINT, INJECTION_POINT_CACHED, INJECTION_POINT_LOAD, XLogCtlData::Insert, Insert(), INSERT_FREESPACE, XLogCtlData::InsertTimeLineID, InvalidateObsoleteReplicationSlots(), InvalidOid, InvalidTransactionId, InvalidXLogRecPtr, IsLogicalDecodingEnabled(), KeepLogSeg(), LocalSetXLogInsertAllowed(), LocalXLogInsertAllowed, log_checkpoints, LogCheckpointEnd(), LogCheckpointStart(), CheckPoint::logicalDecodingEnabled, 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)
extern

Definition at line 7715 of file xlog.c.

7716{
7717 XLogRecPtr lastCheckPointRecPtr;
7718 XLogRecPtr lastCheckPointEndPtr;
7719 CheckPoint lastCheckPoint;
7723 TimeLineID replayTLI;
7724 XLogRecPtr endptr;
7727
7728 /* Concurrent checkpoint/restartpoint cannot happen */
7730
7731 /* Get a local copy of the last safe checkpoint record. */
7733 lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
7734 lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
7735 lastCheckPoint = XLogCtl->lastCheckPoint;
7737
7738 /*
7739 * Check that we're still in recovery mode. It's ok if we exit recovery
7740 * mode after this check, the restart point is valid anyway.
7741 */
7742 if (!RecoveryInProgress())
7743 {
7745 (errmsg_internal("skipping restartpoint, recovery has already ended")));
7746 return false;
7747 }
7748
7749 /*
7750 * If the last checkpoint record we've replayed is already our last
7751 * restartpoint, we can't perform a new restart point. We still update
7752 * minRecoveryPoint in that case, so that if this is a shutdown restart
7753 * point, we won't start up earlier than before. That's not strictly
7754 * necessary, but when hot standby is enabled, it would be rather weird if
7755 * the database opened up for read-only connections at a point-in-time
7756 * before the last shutdown. Such time travel is still possible in case of
7757 * immediate shutdown, though.
7758 *
7759 * We don't explicitly advance minRecoveryPoint when we do create a
7760 * restartpoint. It's assumed that flushing the buffers will do that as a
7761 * side-effect.
7762 */
7763 if (!XLogRecPtrIsValid(lastCheckPointRecPtr) ||
7764 lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
7765 {
7767 errmsg_internal("skipping restartpoint, already performed at %X/%08X",
7768 LSN_FORMAT_ARGS(lastCheckPoint.redo)));
7769
7771 if (flags & CHECKPOINT_IS_SHUTDOWN)
7772 {
7777 }
7778 return false;
7779 }
7780
7781 /*
7782 * Update the shared RedoRecPtr so that the startup process can calculate
7783 * the number of segments replayed since last restartpoint, and request a
7784 * restartpoint if it exceeds CheckPointSegments.
7785 *
7786 * Like in CreateCheckPoint(), hold off insertions to update it, although
7787 * during recovery this is just pro forma, because no WAL insertions are
7788 * happening.
7789 */
7791 RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
7793
7794 /* Also update the info_lck-protected copy */
7796 XLogCtl->RedoRecPtr = lastCheckPoint.redo;
7798
7799 /*
7800 * Prepare to accumulate statistics.
7801 *
7802 * Note: because it is possible for log_checkpoints to change while a
7803 * checkpoint proceeds, we always accumulate stats, even if
7804 * log_checkpoints is currently off.
7805 */
7808
7809 if (log_checkpoints)
7810 LogCheckpointStart(flags, true);
7811
7812 /* Update the process title */
7813 update_checkpoint_display(flags, true, false);
7814
7815 CheckPointGuts(lastCheckPoint.redo, flags);
7816
7817 /*
7818 * This location needs to be after CheckPointGuts() to ensure that some
7819 * work has already happened during this checkpoint.
7820 */
7821 INJECTION_POINT("create-restart-point", NULL);
7822
7823 /*
7824 * Remember the prior checkpoint's redo ptr for
7825 * UpdateCheckPointDistanceEstimate()
7826 */
7828
7829 /*
7830 * Update pg_control, using current time. Check that it still shows an
7831 * older checkpoint, else do nothing; this is a quick hack to make sure
7832 * nothing really bad happens if somehow we get here after the
7833 * end-of-recovery checkpoint.
7834 */
7836 if (ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
7837 {
7838 /*
7839 * Update the checkpoint information. We do this even if the cluster
7840 * does not show DB_IN_ARCHIVE_RECOVERY to match with the set of WAL
7841 * segments recycled below.
7842 */
7843 ControlFile->checkPoint = lastCheckPointRecPtr;
7844 ControlFile->checkPointCopy = lastCheckPoint;
7845
7846 /*
7847 * Ensure minRecoveryPoint is past the checkpoint record and update it
7848 * if the control file still shows DB_IN_ARCHIVE_RECOVERY. Normally,
7849 * this will have happened already while writing out dirty buffers,
7850 * but not necessarily - e.g. because no buffers were dirtied. We do
7851 * this because a backup performed in recovery uses minRecoveryPoint
7852 * to determine which WAL files must be included in the backup, and
7853 * the file (or files) containing the checkpoint record must be
7854 * included, at a minimum. Note that for an ordinary restart of
7855 * recovery there's no value in having the minimum recovery point any
7856 * earlier than this anyway, because redo will begin just after the
7857 * checkpoint record.
7858 */
7860 {
7861 if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
7862 {
7863 ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
7865
7866 /* update local copy */
7869 }
7870 if (flags & CHECKPOINT_IS_SHUTDOWN)
7872 }
7874 }
7876
7877 /*
7878 * Update the average distance between checkpoints/restartpoints if the
7879 * prior checkpoint exists.
7880 */
7883
7884 /*
7885 * Delete old log files, those no longer needed for last restartpoint to
7886 * prevent the disk holding the xlog from growing full.
7887 */
7889
7890 /*
7891 * Retreat _logSegNo using the current end of xlog replayed or received,
7892 * whichever is later.
7893 */
7895 replayPtr = GetXLogReplayRecPtr(&replayTLI);
7896 endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
7897 KeepLogSeg(endptr, &_logSegNo);
7898
7899 INJECTION_POINT("restartpoint-before-slot-invalidation", NULL);
7900
7904 {
7905 /*
7906 * Some slots have been invalidated; recalculate the old-segment
7907 * horizon, starting again from RedoRecPtr.
7908 */
7910 KeepLogSeg(endptr, &_logSegNo);
7911 }
7912 _logSegNo--;
7913
7914 /*
7915 * Try to recycle segments on a useful timeline. If we've been promoted
7916 * since the beginning of this restartpoint, use the new timeline chosen
7917 * at end of recovery. If we're still in recovery, use the timeline we're
7918 * currently replaying.
7919 *
7920 * There is no guarantee that the WAL segments will be useful on the
7921 * current timeline; if recovery proceeds to a new timeline right after
7922 * this, the pre-allocated WAL segments on this timeline will not be used,
7923 * and will go wasted until recycled on the next restartpoint. We'll live
7924 * with that.
7925 */
7926 if (!RecoveryInProgress())
7927 replayTLI = XLogCtl->InsertTimeLineID;
7928
7929 RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr, replayTLI);
7930
7931 /*
7932 * Make more log segments if needed. (Do this after recycling old log
7933 * segments, since that may supply some of the needed files.)
7934 */
7935 PreallocXlogFiles(endptr, replayTLI);
7936
7937 /*
7938 * Truncate pg_subtrans if possible. We can throw away all data before
7939 * the oldest XMIN of any running transaction. No future transaction will
7940 * attempt to reference any pg_subtrans entry older than that (see Asserts
7941 * in subtrans.c). When hot standby is disabled, though, we mustn't do
7942 * this because StartupSUBTRANS hasn't been called yet.
7943 */
7944 if (EnableHotStandby)
7946
7947 /* Real work is done; log and update stats. */
7948 LogCheckpointEnd(true, flags);
7949
7950 /* Reset the process title */
7951 update_checkpoint_display(flags, true, true);
7952
7955 errmsg("recovery restart point at %X/%08X",
7956 LSN_FORMAT_ARGS(lastCheckPoint.redo)),
7957 xtime ? errdetail("Last completed transaction was at log time %s.",
7959
7960 /*
7961 * Finally, execute archive_cleanup_command, if any.
7962 */
7965 "archive_cleanup_command",
7966 false,
7968
7969 return true;
7970}
const char * timestamptz_to_str(TimestampTz t)
Definition timestamp.c:1860
#define LOG
Definition elog.h:31
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define DEBUG2
Definition elog.h:29
bool IsUnderPostmaster
Definition globals.c:120
@ B_CHECKPOINTER
Definition miscadmin.h:363
BackendType MyBackendType
Definition miscinit.c:65
@ DB_IN_ARCHIVE_RECOVERY
Definition pg_control.h:98
@ DB_SHUTDOWNED_IN_RECOVERY
Definition pg_control.h:95
CheckPoint lastCheckPoint
Definition xlog.c:548
XLogRecPtr lastCheckPointRecPtr
Definition xlog.c:546
XLogRecPtr lastCheckPointEndPtr
Definition xlog.c:547
XLogRecPtr GetWalRcvFlushRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI)
bool EnableHotStandby
Definition xlog.c:125
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition xlog.c:2687
static XLogRecPtr LocalMinRecoveryPoint
Definition xlog.c:649
static TimeLineID LocalMinRecoveryPointTLI
Definition xlog.c:650
void ExecuteRecoveryCommand(const char *command, const char *commandName, bool failOnSignal, uint32 wait_event_info)
#define LSN_FORMAT_ARGS(lsn)
Definition xlogdefs.h:47
char * archiveCleanupCommand
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(), fb(), 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 
)
extern

Definition at line 9545 of file xlog.c.

9546{
9548
9549 /* If called during backup start, there shouldn't be one already running */
9551
9553 {
9557
9560
9563 errmsg("aborting backup due to backend exiting before pg_backup_stop was called"));
9564 }
9565}
#define WARNING
Definition elog.h:36
static bool DatumGetBool(Datum X)
Definition postgres.h:100
int runningBackups
Definition xlog.c:442
static SessionBackupState sessionBackupState
Definition xlog.c:395

References arg, Assert, DatumGetBool(), ereport, errmsg, fb(), 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 
)
extern

Definition at line 8949 of file xlog.c.

8951{
8953
8954 Assert(state != NULL);
8956
8957 /*
8958 * During recovery, we don't need to check WAL level. Because, if WAL
8959 * level is not sufficient, it's impossible to get here during recovery.
8960 */
8962 ereport(ERROR,
8964 errmsg("WAL level not sufficient for making an online backup"),
8965 errhint("\"wal_level\" must be set to \"replica\" or \"logical\" at server start.")));
8966
8968 ereport(ERROR,
8970 errmsg("backup label too long (max %d bytes)",
8971 MAXPGPATH)));
8972
8973 strlcpy(state->name, backupidstr, sizeof(state->name));
8974
8975 /*
8976 * Mark backup active in shared memory. We must do full-page WAL writes
8977 * during an on-line backup even if not doing so at other times, because
8978 * it's quite possible for the backup dump to obtain a "torn" (partially
8979 * written) copy of a database page if it reads the page concurrently with
8980 * our write to the same page. This can be fixed as long as the first
8981 * write to the page in the WAL sequence is a full-page write. Hence, we
8982 * increment runningBackups then force a CHECKPOINT, to ensure there are
8983 * no dirty pages in shared memory that might get dumped while the backup
8984 * is in progress without having a corresponding WAL record. (Once the
8985 * backup is complete, we need not force full-page writes anymore, since
8986 * we expect that any pages not modified during the backup interval must
8987 * have been correctly captured by the backup.)
8988 *
8989 * Note that forcing full-page writes has no effect during an online
8990 * backup from the standby.
8991 *
8992 * We must hold all the insertion locks to change the value of
8993 * runningBackups, to ensure adequate interlocking against
8994 * XLogInsertRecord().
8995 */
8999
9000 /*
9001 * Ensure we decrement runningBackups if we fail below. NB -- for this to
9002 * work correctly, it is critical that sessionBackupState is only updated
9003 * after this block is over.
9004 */
9006 {
9007 bool gotUniqueStartpoint = false;
9008 DIR *tblspcdir;
9009 struct dirent *de;
9011 int datadirpathlen;
9012
9013 /*
9014 * Force an XLOG file switch before the checkpoint, to ensure that the
9015 * WAL segment the checkpoint is written to doesn't contain pages with
9016 * old timeline IDs. That would otherwise happen if you called
9017 * pg_backup_start() right after restoring from a PITR archive: the
9018 * first WAL segment containing the startup checkpoint has pages in
9019 * the beginning with the old timeline ID. That can cause trouble at
9020 * recovery: we won't have a history file covering the old timeline if
9021 * pg_wal directory was not included in the base backup and the WAL
9022 * archive was cleared too before starting the backup.
9023 *
9024 * During recovery, we skip forcing XLOG file switch, which means that
9025 * the backup taken during recovery is not available for the special
9026 * recovery case described above.
9027 */
9029 RequestXLogSwitch(false);
9030
9031 do
9032 {
9033 bool checkpointfpw;
9034
9035 /*
9036 * Force a CHECKPOINT. Aside from being necessary to prevent torn
9037 * page problems, this guarantees that two successive backup runs
9038 * will have different checkpoint positions and hence different
9039 * history file names, even if nothing happened in between.
9040 *
9041 * During recovery, establish a restartpoint if possible. We use
9042 * the last restartpoint as the backup starting checkpoint. This
9043 * means that two successive backup runs can have same checkpoint
9044 * positions.
9045 *
9046 * Since the fact that we are executing do_pg_backup_start()
9047 * during recovery means that checkpointer is running, we can use
9048 * RequestCheckpoint() to establish a restartpoint.
9049 *
9050 * We use CHECKPOINT_FAST only if requested by user (via passing
9051 * fast = true). Otherwise this can take awhile.
9052 */
9054 (fast ? CHECKPOINT_FAST : 0));
9055
9056 /*
9057 * Now we need to fetch the checkpoint record location, and also
9058 * its REDO pointer. The oldest point in WAL that would be needed
9059 * to restore starting from the checkpoint is precisely the REDO
9060 * pointer.
9061 */
9063 state->checkpointloc = ControlFile->checkPoint;
9064 state->startpoint = ControlFile->checkPointCopy.redo;
9068
9070 {
9072
9073 /*
9074 * Check to see if all WAL replayed during online backup
9075 * (i.e., since last restartpoint used as backup starting
9076 * checkpoint) contain full-page writes.
9077 */
9081
9082 if (!checkpointfpw || state->startpoint <= recptr)
9083 ereport(ERROR,
9085 errmsg("WAL generated with \"full_page_writes=off\" was replayed "
9086 "since last restartpoint"),
9087 errhint("This means that the backup being taken on the standby "
9088 "is corrupt and should not be used. "
9089 "Enable \"full_page_writes\" and run CHECKPOINT on the primary, "
9090 "and then try an online backup again.")));
9091
9092 /*
9093 * During recovery, since we don't use the end-of-backup WAL
9094 * record and don't write the backup history file, the
9095 * starting WAL location doesn't need to be unique. This means
9096 * that two base backups started at the same time might use
9097 * the same checkpoint as starting locations.
9098 */
9099 gotUniqueStartpoint = true;
9100 }
9101
9102 /*
9103 * If two base backups are started at the same time (in WAL sender
9104 * processes), we need to make sure that they use different
9105 * checkpoints as starting locations, because we use the starting
9106 * WAL location as a unique identifier for the base backup in the
9107 * end-of-backup WAL record and when we write the backup history
9108 * file. Perhaps it would be better generate a separate unique ID
9109 * for each backup instead of forcing another checkpoint, but
9110 * taking a checkpoint right after another is not that expensive
9111 * either because only few buffers have been dirtied yet.
9112 */
9114 if (XLogCtl->Insert.lastBackupStart < state->startpoint)
9115 {
9116 XLogCtl->Insert.lastBackupStart = state->startpoint;
9117 gotUniqueStartpoint = true;
9118 }
9120 } while (!gotUniqueStartpoint);
9121
9122 /*
9123 * Construct tablespace_map file.
9124 */
9126
9127 /* Collect information about all tablespaces */
9129 while ((de = ReadDir(tblspcdir, PG_TBLSPC_DIR)) != NULL)
9130 {
9131 char fullpath[MAXPGPATH + sizeof(PG_TBLSPC_DIR)];
9132 char linkpath[MAXPGPATH];
9133 char *relpath = NULL;
9134 char *s;
9136 char *badp;
9137 Oid tsoid;
9138
9139 /*
9140 * Try to parse the directory name as an unsigned integer.
9141 *
9142 * Tablespace directories should be positive integers that can be
9143 * represented in 32 bits, with no leading zeroes or trailing
9144 * garbage. If we come across a name that doesn't meet those
9145 * criteria, skip it.
9146 */
9147 if (de->d_name[0] < '1' || de->d_name[1] > '9')
9148 continue;
9149 errno = 0;
9150 tsoid = strtoul(de->d_name, &badp, 10);
9151 if (*badp != '\0' || errno == EINVAL || errno == ERANGE)
9152 continue;
9153
9154 snprintf(fullpath, sizeof(fullpath), "%s/%s", PG_TBLSPC_DIR, de->d_name);
9155
9156 de_type = get_dirent_type(fullpath, de, false, ERROR);
9157
9158 if (de_type == PGFILETYPE_LNK)
9159 {
9161 int rllen;
9162
9163 rllen = readlink(fullpath, linkpath, sizeof(linkpath));
9164 if (rllen < 0)
9165 {
9167 (errmsg("could not read symbolic link \"%s\": %m",
9168 fullpath)));
9169 continue;
9170 }
9171 else if (rllen >= sizeof(linkpath))
9172 {
9174 (errmsg("symbolic link \"%s\" target is too long",
9175 fullpath)));
9176 continue;
9177 }
9178 linkpath[rllen] = '\0';
9179
9180 /*
9181 * Relpath holds the relative path of the tablespace directory
9182 * when it's located within PGDATA, or NULL if it's located
9183 * elsewhere.
9184 */
9185 if (rllen > datadirpathlen &&
9189
9190 /*
9191 * Add a backslash-escaped version of the link path to the
9192 * tablespace map file.
9193 */
9195 for (s = linkpath; *s; s++)
9196 {
9197 if (*s == '\n' || *s == '\r' || *s == '\\')
9200 }
9202 de->d_name, escapedpath.data);
9203 pfree(escapedpath.data);
9204 }
9205 else if (de_type == PGFILETYPE_DIR)
9206 {
9207 /*
9208 * It's possible to use allow_in_place_tablespaces to create
9209 * directories directly under pg_tblspc, for testing purposes
9210 * only.
9211 *
9212 * In this case, we store a relative path rather than an
9213 * absolute path into the tablespaceinfo.
9214 */
9215 snprintf(linkpath, sizeof(linkpath), "%s/%s",
9216 PG_TBLSPC_DIR, de->d_name);
9218 }
9219 else
9220 {
9221 /* Skip any other file type that appears here. */
9222 continue;
9223 }
9224
9226 ti->oid = tsoid;
9227 ti->path = pstrdup(linkpath);
9228 ti->rpath = relpath;
9229 ti->size = -1;
9230
9231 if (tablespaces)
9232 *tablespaces = lappend(*tablespaces, ti);
9233 }
9235
9236 state->starttime = (pg_time_t) time(NULL);
9237 }
9239
9240 state->started_in_recovery = backup_started_in_recovery;
9241
9242 /*
9243 * Mark that the start phase has correctly finished for the backup.
9244 */
9246}
static bool backup_started_in_recovery
Definition basebackup.c:129
void RequestCheckpoint(int flags)
int errcode(int sqlerrcode)
Definition elog.c:874
int errhint(const char *fmt,...) pg_attribute_printf(1
int FreeDir(DIR *dir)
Definition fd.c:3009
DIR * AllocateDir(const char *dirname)
Definition fd.c:2891
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition fd.c:2957
#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:1781
#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
#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:554
XLogRecPtr lastBackupStart
Definition xlog.c:443
#define readlink(path, buf, size)
Definition win32_port.h:226
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition xlog.c:8189
void do_pg_abort_backup(int code, Datum arg)
Definition xlog.c:9545
#define CHECKPOINT_WAIT
Definition xlog.h:156
#define CHECKPOINT_FAST
Definition xlog.h:152
#define XLogIsNeeded()
Definition xlog.h:111

References AllocateDir(), appendStringInfo(), appendStringInfoChar(), Assert, backup_started_in_recovery, BoolGetDatum(), ControlFileData::checkPoint, CHECKPOINT_FAST, CHECKPOINT_FORCE, CHECKPOINT_WAIT, ControlFileData::checkPointCopy, ControlFile, DataDir, do_pg_abort_backup(), ereport, errcode(), errhint(), errmsg, ERROR, fb(), 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, palloc_object, 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(), XLogCtlInsert::runningBackups, SESSION_BACKUP_RUNNING, sessionBackupState, 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 
)
extern

Definition at line 9271 of file xlog.c.

9272{
9273 bool backup_stopped_in_recovery = false;
9274 char histfilepath[MAXPGPATH];
9278 FILE *fp;
9280 int waits = 0;
9281 bool reported_waiting = false;
9282
9283 Assert(state != NULL);
9284
9286
9287 /*
9288 * During recovery, we don't need to check WAL level. Because, if WAL
9289 * level is not sufficient, it's impossible to get here during recovery.
9290 */
9292 ereport(ERROR,
9294 errmsg("WAL level not sufficient for making an online backup"),
9295 errhint("\"wal_level\" must be set to \"replica\" or \"logical\" at server start.")));
9296
9297 /*
9298 * OK to update backup counter and session-level lock.
9299 *
9300 * Note that CHECK_FOR_INTERRUPTS() must not occur while updating them,
9301 * otherwise they can be updated inconsistently, which might cause
9302 * do_pg_abort_backup() to fail.
9303 */
9305
9306 /*
9307 * It is expected that each do_pg_backup_start() call is matched by
9308 * exactly one do_pg_backup_stop() call.
9309 */
9312
9313 /*
9314 * Clean up session-level lock.
9315 *
9316 * You might think that WALInsertLockRelease() can be called before
9317 * cleaning up session-level lock because session-level lock doesn't need
9318 * to be protected with WAL insertion lock. But since
9319 * CHECK_FOR_INTERRUPTS() can occur in it, session-level lock must be
9320 * cleaned up before it.
9321 */
9323
9325
9326 /*
9327 * If we are taking an online backup from the standby, we confirm that the
9328 * standby has not been promoted during the backup.
9329 */
9330 if (state->started_in_recovery && !backup_stopped_in_recovery)
9331 ereport(ERROR,
9333 errmsg("the standby was promoted during online backup"),
9334 errhint("This means that the backup being taken is corrupt "
9335 "and should not be used. "
9336 "Try taking another online backup.")));
9337
9338 /*
9339 * During recovery, we don't write an end-of-backup record. We assume that
9340 * pg_control was backed up last and its minimum recovery point can be
9341 * available as the backup end location. Since we don't have an
9342 * end-of-backup record, we use the pg_control value to check whether
9343 * we've reached the end of backup when starting recovery from this
9344 * backup. We have no way of checking if pg_control wasn't backed up last
9345 * however.
9346 *
9347 * We don't force a switch to new WAL file but it is still possible to
9348 * wait for all the required files to be archived if waitforarchive is
9349 * true. This is okay if we use the backup to start a standby and fetch
9350 * the missing WAL using streaming replication. But in the case of an
9351 * archive recovery, a user should set waitforarchive to true and wait for
9352 * them to be archived to ensure that all the required files are
9353 * available.
9354 *
9355 * We return the current minimum recovery point as the backup end
9356 * location. Note that it can be greater than the exact backup end
9357 * location if the minimum recovery point is updated after the backup of
9358 * pg_control. This is harmless for current uses.
9359 *
9360 * XXX currently a backup history file is for informational and debug
9361 * purposes only. It's not essential for an online backup. Furthermore,
9362 * even if it's created, it will not be archived during recovery because
9363 * an archiver is not invoked. So it doesn't seem worthwhile to write a
9364 * backup history file during recovery.
9365 */
9367 {
9369
9370 /*
9371 * Check to see if all WAL replayed during online backup contain
9372 * full-page writes.
9373 */
9377
9378 if (state->startpoint <= recptr)
9379 ereport(ERROR,
9381 errmsg("WAL generated with \"full_page_writes=off\" was replayed "
9382 "during online backup"),
9383 errhint("This means that the backup being taken on the standby "
9384 "is corrupt and should not be used. "
9385 "Enable \"full_page_writes\" and run CHECKPOINT on the primary, "
9386 "and then try an online backup again.")));
9387
9388
9390 state->stoppoint = ControlFile->minRecoveryPoint;
9393 }
9394 else
9395 {
9396 char *history_file;
9397
9398 /*
9399 * Write the backup-end xlog record
9400 */
9402 XLogRegisterData(&state->startpoint,
9403 sizeof(state->startpoint));
9405
9406 /*
9407 * Given that we're not in recovery, InsertTimeLineID is set and can't
9408 * change, so we can read it without a lock.
9409 */
9410 state->stoptli = XLogCtl->InsertTimeLineID;
9411
9412 /*
9413 * Force a switch to a new xlog segment file, so that the backup is
9414 * valid as soon as archiver moves out the current segment file.
9415 */
9416 RequestXLogSwitch(false);
9417
9418 state->stoptime = (pg_time_t) time(NULL);
9419
9420 /*
9421 * Write the backup history file
9422 */
9425 state->startpoint, wal_segment_size);
9426 fp = AllocateFile(histfilepath, "w");
9427 if (!fp)
9428 ereport(ERROR,
9430 errmsg("could not create file \"%s\": %m",
9431 histfilepath)));
9432
9433 /* Build and save the contents of the backup history file */
9435 fprintf(fp, "%s", history_file);
9437
9438 if (fflush(fp) || ferror(fp) || FreeFile(fp))
9439 ereport(ERROR,
9441 errmsg("could not write file \"%s\": %m",
9442 histfilepath)));
9443
9444 /*
9445 * Clean out any no-longer-needed history files. As a side effect,
9446 * this will post a .ready file for the newly created history file,
9447 * notifying the archiver that history file may be archived
9448 * immediately.
9449 */
9451 }
9452
9453 /*
9454 * If archiving is enabled, wait for all the required WAL files to be
9455 * archived before returning. If archiving isn't enabled, the required WAL
9456 * needs to be transported via streaming replication (hopefully with
9457 * wal_keep_size set high enough), or some more exotic mechanism like
9458 * polling and copying files from pg_wal with script. We have no knowledge
9459 * of those mechanisms, so it's up to the user to ensure that he gets all
9460 * the required WAL.
9461 *
9462 * We wait until both the last WAL file filled during backup and the
9463 * history file have been archived, and assume that the alphabetic sorting
9464 * property of the WAL files ensures any earlier WAL files are safely
9465 * archived as well.
9466 *
9467 * We wait forever, since archive_command is supposed to work and we
9468 * assume the admin wanted his backup to work completely. If you don't
9469 * wish to wait, then either waitforarchive should be passed in as false,
9470 * or you can set statement_timeout. Also, some notices are issued to
9471 * clue in anyone who might be doing this interactively.
9472 */
9473
9474 if (waitforarchive &&
9477 {
9481
9484 state->startpoint, wal_segment_size);
9485
9487 waits = 0;
9488
9491 {
9493
9494 if (!reported_waiting && waits > 5)
9495 {
9497 (errmsg("base backup done, waiting for required WAL segments to be archived")));
9498 reported_waiting = true;
9499 }
9500
9503 1000L,
9506
9508 {
9509 seconds_before_warning *= 2; /* This wraps in >10 years... */
9511 (errmsg("still waiting for all required WAL segments to be archived (%d seconds elapsed)",
9512 waits),
9513 errhint("Check that your \"archive_command\" is executing properly. "
9514 "You can safely cancel this backup, "
9515 "but the database backup will not be usable without all the WAL segments.")));
9516 }
9517 }
9518
9520 (errmsg("all required WAL segments have been archived")));
9521 }
9522 else if (waitforarchive)
9524 (errmsg("WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup")));
9525}
#define fprintf(file, fmt, msg)
Definition cubescan.l:21
#define NOTICE
Definition elog.h:35
int FreeFile(FILE *file)
Definition fd.c:2827
FILE * AllocateFile(const char *name, const char *mode)
Definition fd.c:2628
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:74
#define WL_TIMEOUT
#define WL_EXIT_ON_PM_DEATH
#define WL_LATCH_SET
static void CleanupBackupHistory(void)
Definition xlog.c:4182
#define XLogArchivingActive()
Definition xlog.h:101
#define XLogArchivingAlways()
Definition xlog.h:104
#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)
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, fb(), 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  )
extern

Definition at line 9252 of file xlog.c.

9253{
9254 return sessionBackupState;
9255}

References sessionBackupState.

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

◆ GetActiveWalLevelOnStandby()

WalLevel GetActiveWalLevelOnStandby ( void  )
extern

Definition at line 4936 of file xlog.c.

4937{
4938 return ControlFile->wal_level;
4939}

References ControlFile, and ControlFileData::wal_level.

◆ GetDefaultCharSignedness()

bool GetDefaultCharSignedness ( void  )
extern

Definition at line 4645 of file xlog.c.

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

References ControlFile, and ControlFileData::default_char_signedness.

Referenced by CMPTRGM_CHOOSE().

◆ GetFakeLSNForUnloggedRel()

XLogRecPtr GetFakeLSNForUnloggedRel ( void  )
extern

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

◆ GetFullPageWriteInfo()

void GetFullPageWriteInfo ( XLogRecPtr RedoRecPtr_p,
bool doPageWrites_p 
)
extern

Definition at line 6577 of file xlog.c.

6578{
6581}
static bool doPageWrites
Definition xlog.c:290

References doPageWrites, fb(), and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )
extern

◆ GetLastImportantRecPtr()

XLogRecPtr GetLastImportantRecPtr ( void  )
extern

Definition at line 6666 of file xlog.c.

6667{
6669 int i;
6670
6671 for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
6672 {
6674
6675 /*
6676 * Need to take a lock to prevent torn reads of the LSN, which are
6677 * possible on some of the supported platforms. WAL insert locks only
6678 * support exclusive mode, so we have to use that.
6679 */
6682 LWLockRelease(&WALInsertLocks[i].l.lock);
6683
6684 if (res < last_important)
6685 res = last_important;
6686 }
6687
6688 return res;
6689}
int i
Definition isn.c:77
XLogRecPtr lastImportantAt
Definition xlog.c:375
WALInsertLock l
Definition xlog.c:387
static WALInsertLockPadded * WALInsertLocks
Definition xlog.c:572
#define NUM_XLOGINSERT_LOCKS
Definition xlog.c:154

References fb(), 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  )
extern

Definition at line 4621 of file xlog.c.

4622{
4625}
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition pg_control.h:239

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

Referenced by scram_mock_salt().

◆ GetRecoveryState()

RecoveryState GetRecoveryState ( void  )
extern

Definition at line 6480 of file xlog.c.

6481{
6482 RecoveryState retval;
6483
6485 retval = XLogCtl->SharedRecoveryState;
6487
6488 return retval;
6489}

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

Referenced by XLogArchiveCheckDone().

◆ GetRedoRecPtr()

XLogRecPtr GetRedoRecPtr ( void  )
extern

Definition at line 6547 of file xlog.c.

6548{
6549 XLogRecPtr ptr;
6550
6551 /*
6552 * The possibly not up-to-date copy in XlogCtl is enough. Even if we
6553 * grabbed a WAL insertion lock to read the authoritative value in
6554 * Insert->RedoRecPtr, someone might update it just after we've released
6555 * the lock.
6556 */
6558 ptr = XLogCtl->RedoRecPtr;
6560
6561 if (RedoRecPtr < ptr)
6562 RedoRecPtr = ptr;
6563
6564 return RedoRecPtr;
6565}

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

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

◆ GetSystemIdentifier()

◆ GetWALAvailability()

WALAvailability GetWALAvailability ( XLogRecPtr  targetLSN)
extern

Definition at line 7996 of file xlog.c.

7997{
7998 XLogRecPtr currpos; /* current write LSN */
7999 XLogSegNo currSeg; /* segid of currpos */
8000 XLogSegNo targetSeg; /* segid of targetLSN */
8001 XLogSegNo oldestSeg; /* actual oldest segid */
8002 XLogSegNo oldestSegMaxWalSize; /* oldest segid kept by max_wal_size */
8003 XLogSegNo oldestSlotSeg; /* oldest segid kept by slot */
8005
8006 /*
8007 * slot does not reserve WAL. Either deactivated, or has never been active
8008 */
8010 return WALAVAIL_INVALID_LSN;
8011
8012 /*
8013 * Calculate the oldest segment currently reserved by all slots,
8014 * considering wal_keep_size and max_slot_wal_keep_size. Initialize
8015 * oldestSlotSeg to the current segment.
8016 */
8017 currpos = GetXLogWriteRecPtr();
8019 KeepLogSeg(currpos, &oldestSlotSeg);
8020
8021 /*
8022 * Find the oldest extant segment file. We get 1 until checkpoint removes
8023 * the first WAL segment file since startup, which causes the status being
8024 * wrong under certain abnormal conditions but that doesn't actually harm.
8025 */
8027
8028 /* calculate oldest segment by max_wal_size */
8031
8032 if (currSeg > keepSegs)
8034 else
8036
8037 /* the segment we care about */
8039
8040 /*
8041 * No point in returning reserved or extended status values if the
8042 * targetSeg is known to be lost.
8043 */
8044 if (targetSeg >= oldestSlotSeg)
8045 {
8046 /* show "reserved" when targetSeg is within max_wal_size */
8048 return WALAVAIL_RESERVED;
8049
8050 /* being retained by slots exceeding max_wal_size */
8051 return WALAVAIL_EXTENDED;
8052 }
8053
8054 /* WAL segments are no longer retained but haven't been removed yet */
8055 if (targetSeg >= oldestSeg)
8056 return WALAVAIL_UNRESERVED;
8057
8058 /* Definitely lost */
8059 return WALAVAIL_REMOVED;
8060}
XLogSegNo XLogGetLastRemovedSegno(void)
Definition xlog.c:3779
int max_wal_size_mb
Definition xlog.c:118
#define ConvertToXSegs(x, segsize)
Definition xlog.c:606
XLogRecPtr GetXLogWriteRecPtr(void)
Definition xlog.c:9602

References ConvertToXSegs, fb(), 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  )
extern

Definition at line 6630 of file xlog.c.

6631{
6633
6634 /* Since the value can't be changing, no lock is required. */
6635 return XLogCtl->InsertTimeLineID;
6636}

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

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

◆ GetWALInsertionTimeLineIfSet()

TimeLineID GetWALInsertionTimeLineIfSet ( void  )
extern

◆ GetXLogInsertRecPtr()

◆ GetXLogWriteRecPtr()

◆ InitializeWalConsistencyChecking()

void InitializeWalConsistencyChecking ( void  )
extern

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:1788
char * wal_consistency_checking_string
Definition xlog.c:129
static bool check_wal_consistency_checking_deferred
Definition xlog.c:170

References Assert, check_wal_consistency_checking_deferred, ERROR, fb(), find_option(), GUC_ACTION_SET, process_shared_preload_libraries_done, set_config_option_ext(), and wal_consistency_checking_string.

Referenced by PostgresSingleUserMain(), and PostmasterMain().

◆ IsInstallXLogFileSegmentActive()

bool IsInstallXLogFileSegmentActive ( void  )
extern

Definition at line 9651 of file xlog.c.

9652{
9653 bool result;
9654
9658
9659 return result;
9660}
bool InstallXLogFileSegmentActive
Definition xlog.c:529

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

Referenced by XLogFileRead().

◆ issue_xlog_fsync()

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

Definition at line 8852 of file xlog.c.

8853{
8854 char *msg = NULL;
8856
8857 Assert(tli != 0);
8858
8859 /*
8860 * Quick exit if fsync is disabled or write() has already synced the WAL
8861 * file.
8862 */
8863 if (!enableFsync ||
8866 return;
8867
8868 /*
8869 * Measure I/O timing to sync the WAL file for pg_stat_io.
8870 */
8872
8874 switch (wal_sync_method)
8875 {
8877 if (pg_fsync_no_writethrough(fd) != 0)
8878 msg = _("could not fsync file \"%s\": %m");
8879 break;
8880#ifdef HAVE_FSYNC_WRITETHROUGH
8882 if (pg_fsync_writethrough(fd) != 0)
8883 msg = _("could not fsync write-through file \"%s\": %m");
8884 break;
8885#endif
8887 if (pg_fdatasync(fd) != 0)
8888 msg = _("could not fdatasync file \"%s\": %m");
8889 break;
8892 /* not reachable */
8893 Assert(false);
8894 break;
8895 default:
8896 ereport(PANIC,
8898 errmsg_internal("unrecognized \"wal_sync_method\": %d", wal_sync_method));
8899 break;
8900 }
8901
8902 /* PANIC if failed to fsync */
8903 if (msg)
8904 {
8905 char xlogfname[MAXFNAMELEN];
8906 int save_errno = errno;
8907
8909 errno = save_errno;
8910 ereport(PANIC,
8912 errmsg(msg, xlogfname)));
8913 }
8914
8916
8918 start, 1, 0);
8919}
#define _(x)
Definition elog.c:95
int pg_fsync_no_writethrough(int fd)
Definition fd.c:442
int pg_fdatasync(int fd)
Definition fd.c:481
int pg_fsync_writethrough(int fd)
Definition fd.c:462
bool enableFsync
Definition globals.c:129
return str start
@ IOOBJECT_WAL
Definition pgstat.h:282
@ IOCONTEXT_NORMAL
Definition pgstat.h:292
@ IOOP_FSYNC
Definition pgstat.h:311
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
int wal_sync_method
Definition xlog.c:134
bool track_wal_io_timing
Definition xlog.c:141

References _, Assert, enableFsync, ereport, errcode(), errcode_for_file_access(), errmsg, errmsg_internal(), fb(), 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)
extern

◆ ReachedEndOfBackup()

void ReachedEndOfBackup ( XLogRecPtr  EndRecPtr,
TimeLineID  tli 
)
extern

Definition at line 6357 of file xlog.c.

6358{
6359 /*
6360 * We have reached the end of base backup, as indicated by pg_control. The
6361 * data on disk is now consistent (unless minRecoveryPoint is further
6362 * ahead, which can happen if we crashed during previous recovery). Reset
6363 * backupStartPoint and backupEndPoint, and update minRecoveryPoint to
6364 * make sure we don't allow starting up at an earlier point even if
6365 * recovery is stopped and restarted soon after this.
6366 */
6368
6369 if (ControlFile->minRecoveryPoint < EndRecPtr)
6370 {
6371 ControlFile->minRecoveryPoint = EndRecPtr;
6373 }
6374
6379
6381}
XLogRecPtr backupStartPoint
Definition pg_control.h:172
XLogRecPtr backupEndPoint
Definition pg_control.h:173

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

Referenced by CheckRecoveryConsistency().

◆ RecoveryInProgress()

bool RecoveryInProgress ( void  )
extern

Definition at line 6444 of file xlog.c.

6445{
6446 /*
6447 * We check shared state each time only until we leave recovery mode. We
6448 * can't re-enter recovery, so there's no need to keep checking after the
6449 * shared variable has once been seen false.
6450 */
6452 return false;
6453 else
6454 {
6455 /*
6456 * use volatile pointer to make sure we make a fresh read of the
6457 * shared variable.
6458 */
6459 volatile XLogCtlData *xlogctl = XLogCtl;
6460
6461 LocalRecoveryInProgress = (xlogctl->SharedRecoveryState != RECOVERY_STATE_DONE);
6462
6463 /*
6464 * Note: We don't need a memory barrier when we're still in recovery.
6465 * We might exit recovery immediately after return, so the caller
6466 * can't rely on 'true' meaning that we're still in recovery anyway.
6467 */
6468
6470 }
6471}
static bool LocalRecoveryInProgress
Definition xlog.c:228

References fb(), LocalRecoveryInProgress, RECOVERY_STATE_DONE, 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(), DisableLogicalDecoding(), DisableLogicalDecodingIfNecessary(), do_pg_backup_start(), do_pg_backup_stop(), EnableLogicalDecoding(), EnsureLogicalDecodingEnabled(), error_commit_ts_disabled(), ExecCheckpoint(), ExecWaitStmt(), extended_statistics_update(), 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(), MarkSharedBufferDirtyHint(), perform_base_backup(), pg_clear_attribute_stats(), pg_clear_extended_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_stat_get_recovery(), 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_effective_wal_level(), show_in_hot_standby(), ShutdownXLOG(), SnapBuildWaitSnapshot(), StandbySlotsHaveCaughtup(), StartLogicalReplication(), StartReplication(), StartTransaction(), TransactionIdIsInProgress(), TruncateMultiXact(), UpdateFullPageWrites(), UpdateLogicalDecodingStatusEndOfRecovery(), verify_heapam(), WaitForLSN(), WALReadFromBuffers(), WalReceiverMain(), WalSndWaitForWal(), XLogBackgroundFlush(), XLogFlush(), XLogInsertAllowed(), and XLogSendPhysical().

◆ register_persistent_abort_backup_handler()

void register_persistent_abort_backup_handler ( void  )
extern

Definition at line 9572 of file xlog.c.

9573{
9574 static bool already_done = false;
9575
9576 if (already_done)
9577 return;
9579 already_done = true;
9580}
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition ipc.c:344

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

Referenced by pg_backup_start().

◆ RemoveNonParentXlogFiles()

void RemoveNonParentXlogFiles ( XLogRecPtr  switchpoint,
TimeLineID  newTLI 
)
extern

Definition at line 3961 of file xlog.c.

3962{
3963 DIR *xldir;
3964 struct dirent *xlde;
3965 char switchseg[MAXFNAMELEN];
3969
3970 /*
3971 * Initialize info about where to begin the work. This will recycle,
3972 * somewhat arbitrarily, 10 future segments.
3973 */
3977
3978 /*
3979 * Construct a filename of the last segment to be kept.
3980 */
3982
3983 elog(DEBUG2, "attempting to remove WAL segments newer than log file %s",
3984 switchseg);
3985
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))
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)

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

Referenced by ApplyWalRecord(), and CleanupAfterArchiveRecovery().

◆ ResetInstallXLogFileSegmentActive()

void ResetInstallXLogFileSegmentActive ( void  )
extern

◆ SetInstallXLogFileSegmentActive()

◆ SetWalWriterSleeping()

void SetWalWriterSleeping ( bool  sleeping)
extern

◆ ShutdownXLOG()

void ShutdownXLOG ( int  code,
Datum  arg 
)
extern

Definition at line 6712 of file xlog.c.

6713{
6714 /*
6715 * We should have an aux process resource owner to use, and we should not
6716 * be in a transaction that's installed some other resowner.
6717 */
6722
6723 /* Don't be chatty in standalone mode */
6725 (errmsg("shutting down")));
6726
6727 /*
6728 * Signal walsenders to move to stopping state.
6729 */
6731
6732 /*
6733 * Wait for WAL senders to be in stopping state. This prevents commands
6734 * from writing new WAL.
6735 */
6737
6738 if (RecoveryInProgress())
6740 else
6741 {
6742 /*
6743 * If archiving is enabled, rotate the last XLOG file so that all the
6744 * remaining records are archived (postmaster wakes up the archiver
6745 * process one more time at the end of shutdown). The checkpoint
6746 * record will go to the next XLOG file and won't be archived (yet).
6747 */
6748 if (XLogArchivingActive())
6749 RequestXLogSwitch(false);
6750
6752 }
6753}
bool IsPostmasterEnvironment
Definition globals.c:119
ResourceOwner CurrentResourceOwner
Definition resowner.c:173
ResourceOwner AuxProcessResourceOwner
Definition resowner.c:176
void WalSndInitStopping(void)
Definition walsender.c:3890
void WalSndWaitStopping(void)
Definition walsender.c:3916
bool CreateRestartPoint(int flags)
Definition xlog.c:7715
bool CreateCheckPoint(int flags)
Definition xlog.c:7009

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

Referenced by CheckpointerMain(), and InitPostgres().

◆ StartupXLOG()

void StartupXLOG ( void  )
extern

Definition at line 5501 of file xlog.c.

5502{
5504 CheckPoint checkPoint;
5505 bool wasShutdown;
5506 bool didCrash;
5507 bool haveTblspcMap;
5508 bool haveBackupLabel;
5517 bool promoted = false;
5518 char timebuf[128];
5519
5520 /*
5521 * We should have an aux process resource owner to use, and we should not
5522 * be in a transaction that's installed some other resowner.
5523 */
5528
5529 /*
5530 * Check that contents look valid.
5531 */
5533 ereport(FATAL,
5535 errmsg("control file contains invalid checkpoint location")));
5536
5537 switch (ControlFile->state)
5538 {
5539 case DB_SHUTDOWNED:
5540
5541 /*
5542 * This is the expected case, so don't be chatty in standalone
5543 * mode
5544 */
5546 (errmsg("database system was shut down at %s",
5547 str_time(ControlFile->time,
5548 timebuf, sizeof(timebuf)))));
5549 break;
5550
5552 ereport(LOG,
5553 (errmsg("database system was shut down in recovery at %s",
5555 timebuf, sizeof(timebuf)))));
5556 break;
5557
5558 case DB_SHUTDOWNING:
5559 ereport(LOG,
5560 (errmsg("database system shutdown was interrupted; last known up at %s",
5562 timebuf, sizeof(timebuf)))));
5563 break;
5564
5566 ereport(LOG,
5567 (errmsg("database system was interrupted while in recovery at %s",
5569 timebuf, sizeof(timebuf))),
5570 errhint("This probably means that some data is corrupted and"
5571 " you will have to use the last backup for recovery.")));
5572 break;
5573
5575 ereport(LOG,
5576 (errmsg("database system was interrupted while in recovery at log time %s",
5578 timebuf, sizeof(timebuf))),
5579 errhint("If this has occurred more than once some data might be corrupted"
5580 " and you might need to choose an earlier recovery target.")));
5581 break;
5582
5583 case DB_IN_PRODUCTION:
5584 ereport(LOG,
5585 (errmsg("database system was interrupted; last known up at %s",
5587 timebuf, sizeof(timebuf)))));
5588 break;
5589
5590 default:
5591 ereport(FATAL,
5593 errmsg("control file contains invalid database cluster state")));
5594 }
5595
5596 /* This is just to allow attaching to startup process with a debugger */
5597#ifdef XLOG_REPLAY_DELAY
5599 pg_usleep(60000000L);
5600#endif
5601
5602 /*
5603 * Verify that pg_wal, pg_wal/archive_status, and pg_wal/summaries exist.
5604 * In cases where someone has performed a copy for PITR, these directories
5605 * may have been excluded and need to be re-created.
5606 */
5608
5609 /* Set up timeout handler needed to report startup progress. */
5613
5614 /*----------
5615 * If we previously crashed, perform a couple of actions:
5616 *
5617 * - The pg_wal directory may still include some temporary WAL segments
5618 * used when creating a new segment, so perform some clean up to not
5619 * bloat this path. This is done first as there is no point to sync
5620 * this temporary data.
5621 *
5622 * - There might be data which we had written, intending to fsync it, but
5623 * which we had not actually fsync'd yet. Therefore, a power failure in
5624 * the near future might cause earlier unflushed writes to be lost, even
5625 * though more recent data written to disk from here on would be
5626 * persisted. To avoid that, fsync the entire data directory.
5627 */
5630 {
5633 didCrash = true;
5634 }
5635 else
5636 didCrash = false;
5637
5638 /*
5639 * Prepare for WAL recovery if needed.
5640 *
5641 * InitWalRecovery analyzes the control file and the backup label file, if
5642 * any. It updates the in-memory ControlFile buffer according to the
5643 * starting checkpoint, and sets InRecovery and ArchiveRecoveryRequested.
5644 * It also applies the tablespace map file, if any.
5645 */
5648 checkPoint = ControlFile->checkPointCopy;
5649
5650 /* initialize shared memory variables from the checkpoint record */
5651 TransamVariables->nextXid = checkPoint.nextXid;
5652 TransamVariables->nextOid = checkPoint.nextOid;
5654 MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5655 AdvanceOldestClogXid(checkPoint.oldestXid);
5656 SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5657 SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB);
5659 checkPoint.newestCommitTsXid);
5660
5661 /*
5662 * Clear out any old relcache cache files. This is *necessary* if we do
5663 * any WAL replay, since that would probably result in the cache files
5664 * being out of sync with database reality. In theory we could leave them
5665 * in place if the database had been cleanly shut down, but it seems
5666 * safest to just remove them always and let them be rebuilt during the
5667 * first backend startup. These files needs to be removed from all
5668 * directories including pg_tblspc, however the symlinks are created only
5669 * after reading tablespace_map file in case of archive recovery from
5670 * backup, so needs to clear old relcache files here after creating
5671 * symlinks.
5672 */
5674
5675 /*
5676 * Initialize replication slots, before there's a chance to remove
5677 * required resources.
5678 */
5680
5681 /*
5682 * Startup the logical decoding status with the last status stored in the
5683 * checkpoint record.
5684 */
5686
5687 /*
5688 * Startup logical state, needs to be setup now so we have proper data
5689 * during crash recovery.
5690 */
5692
5693 /*
5694 * Startup CLOG. This must be done after TransamVariables->nextXid has
5695 * been initialized and before we accept connections or begin WAL replay.
5696 */
5697 StartupCLOG();
5698
5699 /*
5700 * Startup MultiXact. We need to do this early to be able to replay
5701 * truncations.
5702 */
5704
5705 /*
5706 * Ditto for commit timestamps. Activate the facility if the setting is
5707 * enabled in the control file, as there should be no tracking of commit
5708 * timestamps done when the setting was disabled. This facility can be
5709 * started or stopped when replaying a XLOG_PARAMETER_CHANGE record.
5710 */
5713
5714 /*
5715 * Recover knowledge about replay progress of known replication partners.
5716 */
5718
5719 /*
5720 * Initialize unlogged LSN. On a clean shutdown, it's restored from the
5721 * control file. On recovery, all unlogged relations are blown away, so
5722 * the unlogged LSN counter can be reset too.
5723 */
5727 else
5730
5731 /*
5732 * Copy any missing timeline history files between 'now' and the recovery
5733 * target timeline from archive to pg_wal. While we don't need those files
5734 * ourselves - the history file of the recovery target timeline covers all
5735 * the previous timelines in the history too - a cascading standby server
5736 * might be interested in them. Or, if you archive the WAL from this
5737 * server to a different archive than the primary, it'd be good for all
5738 * the history files to get archived there after failover, so that you can
5739 * use one of the old timelines as a PITR target. Timeline history files
5740 * are small, so it's better to copy them unnecessarily than not copy them
5741 * and regret later.
5742 */
5744
5745 /*
5746 * Before running in recovery, scan pg_twophase and fill in its status to
5747 * be able to work on entries generated by redo. Doing a scan before
5748 * taking any recovery action has the merit to discard any 2PC files that
5749 * are newer than the first record to replay, saving from any conflicts at
5750 * replay. This avoids as well any subsequent scans when doing recovery
5751 * of the on-disk two-phase data.
5752 */
5754
5755 /*
5756 * When starting with crash recovery, reset pgstat data - it might not be
5757 * valid. Otherwise restore pgstat data. It's safe to do this here,
5758 * because postmaster will not yet have started any other processes.
5759 *
5760 * NB: Restoring replication slot stats relies on slot state to have
5761 * already been restored from disk.
5762 *
5763 * TODO: With a bit of extra work we could just start with a pgstat file
5764 * associated with the checkpoint redo location we're starting from.
5765 */
5766 if (didCrash)
5768 else
5770
5772
5775
5776 /* REDO */
5777 if (InRecovery)
5778 {
5779 /* Initialize state for RecoveryInProgress() */
5783 else
5786
5787 /*
5788 * Update pg_control to show that we are recovering and to show the
5789 * selected checkpoint as the place we are starting from. We also mark
5790 * pg_control with any minimum recovery stop point obtained from a
5791 * backup history file.
5792 *
5793 * No need to hold ControlFileLock yet, we aren't up far enough.
5794 */
5796
5797 /*
5798 * If there was a backup label file, it's done its job and the info
5799 * has now been propagated into pg_control. We must get rid of the
5800 * label file so that if we crash during recovery, we'll pick up at
5801 * the latest recovery restartpoint instead of going all the way back
5802 * to the backup start point. It seems prudent though to just rename
5803 * the file out of the way rather than delete it completely.
5804 */
5805 if (haveBackupLabel)
5806 {
5809 }
5810
5811 /*
5812 * If there was a tablespace_map file, it's done its job and the
5813 * symlinks have been created. We must get rid of the map file so
5814 * that if we crash during recovery, we don't create symlinks again.
5815 * It seems prudent though to just rename the file out of the way
5816 * rather than delete it completely.
5817 */
5818 if (haveTblspcMap)
5819 {
5822 }
5823
5824 /*
5825 * Initialize our local copy of minRecoveryPoint. When doing crash
5826 * recovery we want to replay up to the end of WAL. Particularly, in
5827 * the case of a promoted standby minRecoveryPoint value in the
5828 * control file is only updated after the first checkpoint. However,
5829 * if the instance crashes before the first post-recovery checkpoint
5830 * is completed then recovery will use a stale location causing the
5831 * startup process to think that there are still invalid page
5832 * references when checking for data consistency.
5833 */
5835 {
5838 }
5839 else
5840 {
5843 }
5844
5845 /* Check that the GUCs used to generate the WAL allow recovery */
5847
5848 /*
5849 * We're in recovery, so unlogged relations may be trashed and must be
5850 * reset. This should be done BEFORE allowing Hot Standby
5851 * connections, so that read-only backends don't try to read whatever
5852 * garbage is left over from before.
5853 */
5855
5856 /*
5857 * Likewise, delete any saved transaction snapshot files that got left
5858 * behind by crashed backends.
5859 */
5861
5862 /*
5863 * Initialize for Hot Standby, if enabled. We won't let backends in
5864 * yet, not until we've reached the min recovery point specified in
5865 * control file and we've established a recovery snapshot from a
5866 * running-xacts WAL record.
5867 */
5869 {
5870 TransactionId *xids;
5871 int nxids;
5872
5874 (errmsg_internal("initializing for hot standby")));
5875
5877
5878 if (wasShutdown)
5880 else
5881 oldestActiveXID = checkPoint.oldestActiveXid;
5883
5884 /* Tell procarray about the range of xids it has to deal with */
5886
5887 /*
5888 * Startup subtrans only. CLOG, MultiXact and commit timestamp
5889 * have already been started up and other SLRUs are not maintained
5890 * during recovery and need not be started yet.
5891 */
5893
5894 /*
5895 * If we're beginning at a shutdown checkpoint, we know that
5896 * nothing was running on the primary at this point. So fake-up an
5897 * empty running-xacts record and use that here and now. Recover
5898 * additional standby state for prepared transactions.
5899 */
5900 if (wasShutdown)
5901 {
5903 TransactionId latestCompletedXid;
5904
5905 /* Update pg_subtrans entries for any prepared transactions */
5907
5908 /*
5909 * Construct a RunningTransactions snapshot representing a
5910 * shut down server, with only prepared transactions still
5911 * alive. We're never overflowed at this point because all
5912 * subxids are listed with their parent prepared transactions.
5913 */
5914 running.xcnt = nxids;
5915 running.subxcnt = 0;
5917 running.nextXid = XidFromFullTransactionId(checkPoint.nextXid);
5919 latestCompletedXid = XidFromFullTransactionId(checkPoint.nextXid);
5920 TransactionIdRetreat(latestCompletedXid);
5921 Assert(TransactionIdIsNormal(latestCompletedXid));
5922 running.latestCompletedXid = latestCompletedXid;
5923 running.xids = xids;
5924
5926 }
5927 }
5928
5929 /*
5930 * We're all set for replaying the WAL now. Do it.
5931 */
5933 performedWalRecovery = true;
5934 }
5935 else
5936 performedWalRecovery = false;
5937
5938 /*
5939 * Finish WAL recovery.
5940 */
5942 EndOfLog = endOfRecoveryInfo->endOfLog;
5943 EndOfLogTLI = endOfRecoveryInfo->endOfLogTLI;
5944 abortedRecPtr = endOfRecoveryInfo->abortedRecPtr;
5945 missingContrecPtr = endOfRecoveryInfo->missingContrecPtr;
5946
5947 /*
5948 * Reset ps status display, so as no information related to recovery shows
5949 * up.
5950 */
5951 set_ps_display("");
5952
5953 /*
5954 * When recovering from a backup (we are in recovery, and archive recovery
5955 * was requested), complain if we did not roll forward far enough to reach
5956 * the point where the database is consistent. For regular online
5957 * backup-from-primary, that means reaching the end-of-backup WAL record
5958 * (at which point we reset backupStartPoint to be Invalid), for
5959 * backup-from-replica (which can't inject records into the WAL stream),
5960 * that point is when we reach the minRecoveryPoint in pg_control (which
5961 * we purposefully copy last when backing up from a replica). For
5962 * pg_rewind (which creates a backup_label with a method of "pg_rewind")
5963 * or snapshot-style backups (which don't), backupEndRequired will be set
5964 * to false.
5965 *
5966 * Note: it is indeed okay to look at the local variable
5967 * LocalMinRecoveryPoint here, even though ControlFile->minRecoveryPoint
5968 * might be further ahead --- ControlFile->minRecoveryPoint cannot have
5969 * been advanced beyond the WAL we processed.
5970 */
5971 if (InRecovery &&
5974 {
5975 /*
5976 * Ran off end of WAL before reaching end-of-backup WAL record, or
5977 * minRecoveryPoint. That's a bad sign, indicating that you tried to
5978 * recover from an online backup but never called pg_backup_stop(), or
5979 * you didn't archive all the WAL needed.
5980 */
5982 {
5984 ereport(FATAL,
5986 errmsg("WAL ends before end of online backup"),
5987 errhint("All WAL generated while online backup was taken must be available at recovery.")));
5988 else
5989 ereport(FATAL,
5991 errmsg("WAL ends before consistent recovery point")));
5992 }
5993 }
5994
5995 /*
5996 * Reset unlogged relations to the contents of their INIT fork. This is
5997 * done AFTER recovery is complete so as to include any unlogged relations
5998 * created during recovery, but BEFORE recovery is marked as having
5999 * completed successfully. Otherwise we'd not retry if any of the post
6000 * end-of-recovery steps fail.
6001 */
6002 if (InRecovery)
6004
6005 /*
6006 * Pre-scan prepared transactions to find out the range of XIDs present.
6007 * This information is not quite needed yet, but it is positioned here so
6008 * as potential problems are detected before any on-disk change is done.
6009 */
6011
6012 /*
6013 * Allow ordinary WAL segment creation before possibly switching to a new
6014 * timeline, which creates a new segment, and after the last ReadRecord().
6015 */
6017
6018 /*
6019 * Consider whether we need to assign a new timeline ID.
6020 *
6021 * If we did archive recovery, we always assign a new ID. This handles a
6022 * couple of issues. If we stopped short of the end of WAL during
6023 * recovery, then we are clearly generating a new timeline and must assign
6024 * it a unique new ID. Even if we ran to the end, modifying the current
6025 * last segment is problematic because it may result in trying to
6026 * overwrite an already-archived copy of that segment, and we encourage
6027 * DBAs to make their archive_commands reject that. We can dodge the
6028 * problem by making the new active segment have a new timeline ID.
6029 *
6030 * In a normal crash recovery, we can just extend the timeline we were in.
6031 */
6032 newTLI = endOfRecoveryInfo->lastRecTLI;
6034 {
6036 ereport(LOG,
6037 (errmsg("selected new timeline ID: %u", newTLI)));
6038
6039 /*
6040 * Make a writable copy of the last WAL segment. (Note that we also
6041 * have a copy of the last block of the old WAL in
6042 * endOfRecovery->lastPage; we will use that below.)
6043 */
6045
6046 /*
6047 * Remove the signal files out of the way, so that we don't
6048 * accidentally re-enter archive recovery mode in a subsequent crash.
6049 */
6050 if (endOfRecoveryInfo->standby_signal_file_found)
6052
6053 if (endOfRecoveryInfo->recovery_signal_file_found)
6055
6056 /*
6057 * Write the timeline history file, and have it archived. After this
6058 * point (or rather, as soon as the file is archived), the timeline
6059 * will appear as "taken" in the WAL archive and to any standby
6060 * servers. If we crash before actually switching to the new
6061 * timeline, standby servers will nevertheless think that we switched
6062 * to the new timeline, and will try to connect to the new timeline.
6063 * To minimize the window for that, try to do as little as possible
6064 * between here and writing the end-of-recovery record.
6065 */
6067 EndOfLog, endOfRecoveryInfo->recoveryStopReason);
6068
6069 ereport(LOG,
6070 (errmsg("archive recovery complete")));
6071 }
6072
6073 /* Save the selected TimeLineID in shared memory, too */
6078
6079 /*
6080 * Actually, if WAL ended in an incomplete record, skip the parts that
6081 * made it through and start writing after the portion that persisted.
6082 * (It's critical to first write an OVERWRITE_CONTRECORD message, which
6083 * we'll do as soon as we're open for writing new WAL.)
6084 */
6086 {
6087 /*
6088 * We should only have a missingContrecPtr if we're not switching to a
6089 * new timeline. When a timeline switch occurs, WAL is copied from the
6090 * old timeline to the new only up to the end of the last complete
6091 * record, so there can't be an incomplete WAL record that we need to
6092 * disregard.
6093 */
6094 Assert(newTLI == endOfRecoveryInfo->lastRecTLI);
6097 }
6098
6099 /*
6100 * Prepare to write WAL starting at EndOfLog location, and init xlog
6101 * buffer cache using the block containing the last record from the
6102 * previous incarnation.
6103 */
6104 Insert = &XLogCtl->Insert;
6106 Insert->CurrBytePos = XLogRecPtrToBytePos(EndOfLog);
6107
6108 /*
6109 * Tricky point here: lastPage contains the *last* block that the LastRec
6110 * record spans, not the one it starts in. The last block is indeed the
6111 * one we want to use.
6112 */
6113 if (EndOfLog % XLOG_BLCKSZ != 0)
6114 {
6115 char *page;
6116 int len;
6117 int firstIdx;
6118
6120 len = EndOfLog - endOfRecoveryInfo->lastPageBeginPtr;
6122
6123 /* Copy the valid part of the last block, and zero the rest */
6124 page = &XLogCtl->pages[firstIdx * XLOG_BLCKSZ];
6125 memcpy(page, endOfRecoveryInfo->lastPage, len);
6126 memset(page + len, 0, XLOG_BLCKSZ - len);
6127
6130 }
6131 else
6132 {
6133 /*
6134 * There is no partial block to copy. Just set InitializedUpTo, and
6135 * let the first attempt to insert a log record to initialize the next
6136 * buffer.
6137 */
6139 }
6140
6141 /*
6142 * Update local and shared status. This is OK to do without any locks
6143 * because no other process can be reading or writing WAL yet.
6144 */
6151
6152 /*
6153 * Preallocate additional log files, if wanted.
6154 */
6156
6157 /*
6158 * Okay, we're officially UP.
6159 */
6160 InRecovery = false;
6161
6162 /* start the archive_timeout timer and LSN running */
6165
6166 /* also initialize latestCompletedXid, to nextXid - 1 */
6171
6172 /*
6173 * Start up subtrans, if not already done for hot standby. (commit
6174 * timestamps are started below, if necessary.)
6175 */
6178
6179 /*
6180 * Perform end of recovery actions for any SLRUs that need it.
6181 */
6182 TrimCLOG();
6183 TrimMultiXact();
6184
6185 /*
6186 * Reload shared-memory state for prepared transactions. This needs to
6187 * happen before renaming the last partial segment of the old timeline as
6188 * it may be possible that we have to recover some transactions from it.
6189 */
6191
6192 /* Shut down xlogreader */
6194
6195 /* Enable WAL writes for this backend only. */
6197
6198 /* If necessary, write overwrite-contrecord before doing anything else */
6200 {
6203 }
6204
6205 /*
6206 * Update full_page_writes in shared memory and write an XLOG_FPW_CHANGE
6207 * record before resource manager writes cleanup WAL records or checkpoint
6208 * record is written.
6209 */
6210 Insert->fullPageWrites = lastFullPageWrites;
6212
6213 /*
6214 * Emit checkpoint or end-of-recovery record in XLOG, if required.
6215 */
6218
6219 /*
6220 * If any of the critical GUCs have changed, log them before we allow
6221 * backends to write WAL.
6222 */
6224
6225 /* If this is archive recovery, perform post-recovery cleanup actions. */
6228
6229 /*
6230 * Local WAL inserts enabled, so it's time to finish initialization of
6231 * commit timestamp.
6232 */
6234
6235 /*
6236 * Update logical decoding status in shared memory and write an
6237 * XLOG_LOGICAL_DECODING_STATUS_CHANGE, if necessary.
6238 */
6240
6241 /* Clean up EndOfWalRecoveryInfo data to appease Valgrind leak checking */
6242 if (endOfRecoveryInfo->lastPage)
6243 pfree(endOfRecoveryInfo->lastPage);
6244 pfree(endOfRecoveryInfo->recoveryStopReason);
6246
6247 /*
6248 * All done with end-of-recovery actions.
6249 *
6250 * Now allow backends to write WAL and update the control file status in
6251 * consequence. SharedRecoveryState, that controls if backends can write
6252 * WAL, is updated while holding ControlFileLock to prevent other backends
6253 * to look at an inconsistent state of the control file in shared memory.
6254 * There is still a small window during which backends can write WAL and
6255 * the control file is still referring to a system not in DB_IN_PRODUCTION
6256 * state while looking at the on-disk control file.
6257 *
6258 * Also, we use info_lck to update SharedRecoveryState to ensure that
6259 * there are no race conditions concerning visibility of other recent
6260 * updates to shared memory.
6261 */
6264
6268
6271
6272 /*
6273 * Wake up the checkpointer process as there might be a request to disable
6274 * logical decoding by concurrent slot drop.
6275 */
6277
6278 /*
6279 * Wake up all waiters. They need to report an error that recovery was
6280 * ended before reaching the target LSN.
6281 */
6285
6286 /*
6287 * Shutdown the recovery environment. This must occur after
6288 * RecoverPreparedTransactions() (see notes in lock_twophase_recover())
6289 * and after switching SharedRecoveryState to RECOVERY_STATE_DONE so as
6290 * any session building a snapshot will not rely on KnownAssignedXids as
6291 * RecoveryInProgress() would return false at this stage. This is
6292 * particularly critical for prepared 2PC transactions, that would still
6293 * need to be included in snapshots once recovery has ended.
6294 */
6297
6298 /*
6299 * If there were cascading standby servers connected to us, nudge any wal
6300 * sender processes to notice that we've been promoted.
6301 */
6302 WalSndWakeup(true, true);
6303
6304 /*
6305 * If this was a promotion, request an (online) checkpoint now. This isn't
6306 * required for consistency, but the last restartpoint might be far back,
6307 * and in case of a crash, recovering from it might take a longer than is
6308 * appropriate now that we're not in standby mode anymore.
6309 */
6310 if (promoted)
6312}
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:265
void restoreTimeLineHistoryFiles(TimeLineID begin, TimeLineID end)
Definition timeline.c:51
void writeTimeLineHistory(TimeLineID newTLI, TimeLineID parentTLI, XLogRecPtr switchpoint, char *reason)
Definition timeline.c:305
void startup_progress_timeout_handler(void)
Definition startup.c:302
uint32 TransactionId
Definition c.h:708
void WakeupCheckpointer(void)
void StartupCLOG(void)
Definition clog.c:844
void TrimCLOG(void)
Definition clog.c:859
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:783
int durable_unlink(const char *fname, int elevel)
Definition fd.c:873
void SyncDataDirectory(void)
Definition fd.c:3594
void UpdateLogicalDecodingStatusEndOfRecovery(void)
Definition logicalctl.c:554
void StartupLogicalDecodingStatus(bool last_status)
Definition logicalctl.c:147
#define IsBootstrapProcessingMode()
Definition miscadmin.h:477
void TrimMultiXact(void)
Definition multixact.c:1883
void StartupMultiXact(void)
Definition multixact.c:1858
void StartupReplicationOrigin(void)
Definition origin.c:731
#define ERRCODE_DATA_CORRUPTED
@ DB_IN_PRODUCTION
Definition pg_control.h:99
@ DB_IN_CRASH_RECOVERY
Definition pg_control.h:97
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:1053
void ProcArrayInitRecovery(TransactionId initializedUptoXID)
Definition procarray.c:1022
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:6918
void StartupReorderBuffer(void)
void StartupReplicationSlots(void)
Definition slot.c:2388
void DeleteAllExportedSnapshotFiles(void)
Definition snapmgr.c:1587
void InitRecoveryTransactionEnvironment(void)
Definition standby.c:96
void ShutdownRecoveryTransactionEnvironment(void)
Definition standby.c:162
@ SUBXIDS_IN_SUBTRANS
Definition standby.h:120
bool track_commit_timestamp
Definition pg_control.h:187
TransactionId oldestRunningXid
Definition standby.h:130
TransactionId nextXid
Definition standby.h:129
TransactionId latestCompletedXid
Definition standby.h:133
subxids_array_status subxid_status
Definition standby.h:128
TransactionId * xids
Definition standby.h:135
FullTransactionId latestCompletedXid
Definition transam.h:238
XLogRecPtr InitializedUpTo
Definition xlog.c:488
char * pages
Definition xlog.c:495
pg_time_t lastSegSwitchTime
Definition xlog.c:470
XLogRecPtr lastSegSwitchLSN
Definition xlog.c:471
pg_atomic_uint64 * xlblocks
Definition xlog.c:496
pg_atomic_uint64 logWriteResult
Definition xlog.c:475
pg_atomic_uint64 logFlushResult
Definition xlog.c:476
pg_atomic_uint64 logInsertResult
Definition xlog.c:474
uint64 PrevBytePos
Definition xlog.c:412
XLogRecPtr Flush
Definition xlog.c:326
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:2085
void restoreTwoPhaseData(void)
Definition twophase.c:1906
TransactionId PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p)
Definition twophase.c:1968
void StandbyRecoverPreparedTransactions(void)
Definition twophase.c:2047
void WalSndWakeup(bool physical, bool logical)
Definition walsender.c:3811
void UpdateFullPageWrites(void)
Definition xlog.c:8295
static void ValidateXLOGDirectoryStructure(void)
Definition xlog.c:4120
static XLogRecPtr CreateOverwriteContrecordRecord(XLogRecPtr aborted_lsn, XLogRecPtr pagePtr, TimeLineID newTLI)
Definition xlog.c:7565
static void XLogReportParameters(void)
Definition xlog.c:8232
static bool PerformRecoveryXLogAction(void)
Definition xlog.c:6394
static void CleanupAfterArchiveRecovery(TimeLineID EndOfLogTLI, XLogRecPtr EndOfLog, TimeLineID newTLI)
Definition xlog.c:5361
static bool lastFullPageWrites
Definition xlog.c:221
static uint64 XLogRecPtrToBytePos(XLogRecPtr ptr)
Definition xlog.c:1948
static void XLogInitNewTimeline(TimeLineID endTLI, XLogRecPtr endOfLog, TimeLineID newTLI)
Definition xlog.c:5286
static void CheckRequiredParameterValues(void)
Definition xlog.c:5457
#define XLogRecPtrToBufIdx(recptr)
Definition xlog.c:594
static void RemoveTempXlogFiles(void)
Definition xlog.c:3853
static char * str_time(pg_time_t tnow, char *buf, size_t bufsize)
Definition xlog.c:5273
#define TABLESPACE_MAP_OLD
Definition xlog.h:323
#define TABLESPACE_MAP
Definition xlog.h:322
#define STANDBY_SIGNAL_FILE
Definition xlog.h:318
#define BACKUP_LABEL_OLD
Definition xlog.h:320
#define BACKUP_LABEL_FILE
Definition xlog.h:319
#define RECOVERY_SIGNAL_FILE
Definition xlog.h:317
#define XRecOffIsValid(xlrp)
#define FirstNormalUnloggedLSN
Definition xlogdefs.h:37
void ShutdownWalRecovery(void)
bool ArchiveRecoveryRequested
bool InArchiveRecovery
void PerformWalRecovery(void)
static XLogRecPtr missingContrecPtr
static XLogRecPtr abortedRecPtr
EndOfWalRecoveryInfo * FinishWalRecovery(void)
void InitWalRecovery(ControlFileData *ControlFile, bool *wasShutdown_ptr, bool *haveBackupLabel_ptr, bool *haveTblspcMap_ptr)
TimeLineID recoveryTargetTLI
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:318
@ WAIT_LSN_TYPE_STANDBY_REPLAY
Definition xlogwait.h:39
@ WAIT_LSN_TYPE_STANDBY_FLUSH
Definition xlogwait.h:41
@ WAIT_LSN_TYPE_STANDBY_WRITE
Definition xlogwait.h:40

References 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, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errhint(), errmsg, errmsg_internal(), FATAL, fb(), 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, XLogCtlData::lastSegSwitchLSN, XLogCtlData::lastSegSwitchTime, TransamVariablesData::latestCompletedXid, RunningTransactionsData::latestCompletedXid, len, LocalMinRecoveryPoint, LocalMinRecoveryPointTLI, LocalSetXLogInsertAllowed(), LOG, XLogCtlData::logFlushResult, CheckPoint::logicalDecodingEnabled, XLogCtlData::logInsertResult, XLogCtlData::logWriteResult, LogwrtResult, XLogCtlData::LogwrtRqst, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, 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(), XLogCtlInsert::PrevBytePos, XLogCtlData::PrevTimeLineID, ProcArrayApplyRecoveryInfo(), ProcArrayInitRecovery(), RecoverPreparedTransactions(), RECOVERY_SIGNAL_FILE, RECOVERY_STATE_ARCHIVE, RECOVERY_STATE_CRASH, RECOVERY_STATE_DONE, 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, StandbyRecoverPreparedTransactions(), standbyState, STARTUP_PROGRESS_TIMEOUT, startup_progress_timeout_handler(), StartupCLOG(), StartupCommitTs(), StartupLogicalDecodingStatus(), 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(), UpdateLogicalDecodingStatusEndOfRecovery(), ValidateXLOGDirectoryStructure(), WAIT_LSN_TYPE_STANDBY_FLUSH, WAIT_LSN_TYPE_STANDBY_REPLAY, WAIT_LSN_TYPE_STANDBY_WRITE, WaitLSNWakeup(), WakeupCheckpointer(), 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 
)
extern

Definition at line 6319 of file xlog.c.

6320{
6321 /* initialize minRecoveryPoint to this record */
6324 if (ControlFile->minRecoveryPoint < EndRecPtr)
6325 {
6326 ControlFile->minRecoveryPoint = EndRecPtr;
6327 ControlFile->minRecoveryPointTLI = replayTLI;
6328 }
6329 /* update local copy */
6332
6333 /*
6334 * The startup process can update its local copy of minRecoveryPoint from
6335 * this point.
6336 */
6338
6340
6341 /*
6342 * We update SharedRecoveryState while holding the lock on ControlFileLock
6343 * so both states are consistent in shared memory.
6344 */
6348
6350}
static bool updateMinRecoveryPoint
Definition xlog.c:651

References ControlFile, DB_IN_ARCHIVE_RECOVERY, fb(), 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  )
extern

Definition at line 8295 of file xlog.c.

8296{
8298 bool recoveryInProgress;
8299
8300 /*
8301 * Do nothing if full_page_writes has not been changed.
8302 *
8303 * It's safe to check the shared full_page_writes without the lock,
8304 * because we assume that there is no concurrently running process which
8305 * can update it.
8306 */
8307 if (fullPageWrites == Insert->fullPageWrites)
8308 return;
8309
8310 /*
8311 * Perform this outside critical section so that the WAL insert
8312 * initialization done by RecoveryInProgress() doesn't trigger an
8313 * assertion failure.
8314 */
8316
8318
8319 /*
8320 * It's always safe to take full page images, even when not strictly
8321 * required, but not the other round. So if we're setting full_page_writes
8322 * to true, first set it true and then write the WAL record. If we're
8323 * setting it to false, first write the WAL record and then set the global
8324 * flag.
8325 */
8326 if (fullPageWrites)
8327 {
8329 Insert->fullPageWrites = true;
8331 }
8332
8333 /*
8334 * Write an XLOG_FPW_CHANGE record. This allows us to keep track of
8335 * full_page_writes during archive recovery, if required.
8336 */
8338 {
8340 XLogRegisterData(&fullPageWrites, sizeof(bool));
8341
8343 }
8344
8345 if (!fullPageWrites)
8346 {
8348 Insert->fullPageWrites = false;
8350 }
8352}
#define XLOG_FPW_CHANGE
Definition pg_control.h:77

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

Referenced by StartupXLOG(), and UpdateSharedMemoryConfig().

◆ WakeupCheckpointer()

void WakeupCheckpointer ( void  )
extern

Definition at line 1549 of file checkpointer.c.

1550{
1551 volatile PROC_HDR *procglobal = ProcGlobal;
1552 ProcNumber checkpointerProc = procglobal->checkpointerProc;
1553
1554 if (checkpointerProc != INVALID_PROC_NUMBER)
1555 SetLatch(&GetPGProcByNumber(checkpointerProc)->procLatch);
1556}
void SetLatch(Latch *latch)
Definition latch.c:290
#define GetPGProcByNumber(n)
Definition proc.h:504
#define INVALID_PROC_NUMBER
Definition procnumber.h:26
int ProcNumber
Definition procnumber.h:24
PROC_HDR * ProcGlobal
Definition proc.c:71
ProcNumber checkpointerProc
Definition proc.h:489

References PROC_HDR::checkpointerProc, fb(), GetPGProcByNumber, INVALID_PROC_NUMBER, ProcGlobal, and SetLatch().

Referenced by RequestDisableLogicalDecoding(), and StartupXLOG().

◆ WALReadFromBuffers()

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

Definition at line 1755 of file xlog.c.

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

References Assert, ereport, errmsg, ERROR, fb(), 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 
)
extern

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 {
67
68 appendStringInfo(buf, "redo %X/%08X; "
69 "tli %u; prev tli %u; fpw %s; wal_level %s; logical decoding %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",
74 checkpoint->ThisTimeLineID,
75 checkpoint->PrevTimeLineID,
76 checkpoint->fullPageWrites ? "true" : "false",
78 checkpoint->logicalDecodingEnabled ? "true" : "false",
81 checkpoint->nextOid,
82 checkpoint->nextMulti,
83 checkpoint->nextMultiOffset,
84 checkpoint->oldestXid,
85 checkpoint->oldestXidDB,
86 checkpoint->oldestMulti,
87 checkpoint->oldestMultiDB,
88 checkpoint->oldestCommitTsXid,
89 checkpoint->newestCommitTsXid,
90 checkpoint->oldestActiveXid,
91 (info == XLOG_CHECKPOINT_SHUTDOWN) ? "shutdown" : "online");
92 }
93 else if (info == XLOG_NEXTOID)
94 {
95 Oid nextOid;
96
97 memcpy(&nextOid, rec, sizeof(Oid));
98 appendStringInfo(buf, "%u", nextOid);
99 }
100 else if (info == XLOG_RESTORE_POINT)
101 {
103
105 }
106 else if (info == XLOG_FPI || info == XLOG_FPI_FOR_HINT)
107 {
108 /* no further information to print */
109 }
110 else if (info == XLOG_BACKUP_END)
111 {
112 XLogRecPtr startpoint;
113
114 memcpy(&startpoint, rec, sizeof(XLogRecPtr));
115 appendStringInfo(buf, "%X/%08X", LSN_FORMAT_ARGS(startpoint));
116 }
117 else if (info == XLOG_PARAMETER_CHANGE)
118 {
120 const char *wal_level_str;
121
122 memcpy(&xlrec, rec, sizeof(xl_parameter_change));
124
125 appendStringInfo(buf, "max_connections=%d max_worker_processes=%d "
126 "max_wal_senders=%d max_prepared_xacts=%d "
127 "max_locks_per_xact=%d wal_level=%s "
128 "wal_log_hints=%s track_commit_timestamp=%s",
129 xlrec.MaxConnections,
130 xlrec.max_worker_processes,
131 xlrec.max_wal_senders,
132 xlrec.max_prepared_xacts,
133 xlrec.max_locks_per_xact,
135 xlrec.wal_log_hints ? "on" : "off",
136 xlrec.track_commit_timestamp ? "on" : "off");
137 }
138 else if (info == XLOG_FPW_CHANGE)
139 {
140 bool fpw;
141
142 memcpy(&fpw, rec, sizeof(bool));
143 appendStringInfoString(buf, fpw ? "true" : "false");
144 }
145 else if (info == XLOG_END_OF_RECOVERY)
146 {
148
149 memcpy(&xlrec, rec, sizeof(xl_end_of_recovery));
150 appendStringInfo(buf, "tli %u; prev tli %u; time %s; wal_level %s",
151 xlrec.ThisTimeLineID, xlrec.PrevTimeLineID,
152 timestamptz_to_str(xlrec.end_time),
153 get_wal_level_string(xlrec.wal_level));
154 }
155 else if (info == XLOG_OVERWRITE_CONTRECORD)
156 {
158
159 memcpy(&xlrec, rec, sizeof(xl_overwrite_contrecord));
160 appendStringInfo(buf, "lsn %X/%08X; time %s",
161 LSN_FORMAT_ARGS(xlrec.overwritten_lsn),
162 timestamptz_to_str(xlrec.overwrite_time));
163 }
164 else if (info == XLOG_CHECKPOINT_REDO)
165 {
166 int wal_level;
167
168 memcpy(&wal_level, rec, sizeof(int));
170 }
172 {
173 bool enabled;
174
175 memcpy(&enabled, rec, sizeof(bool));
176 appendStringInfoString(buf, enabled ? "true" : "false");
177 }
178}
static const char * wal_level_str(WalLevel wal_level)
bool track_commit_timestamp
Definition commit_ts.c:109
#define XLOG_RESTORE_POINT
Definition pg_control.h:76
#define XLOG_OVERWRITE_CONTRECORD
Definition pg_control.h:82
#define XLOG_FPI
Definition pg_control.h:80
#define XLOG_FPI_FOR_HINT
Definition pg_control.h:79
#define XLOG_NEXTOID
Definition pg_control.h:72
#define XLOG_PARAMETER_CHANGE
Definition pg_control.h:75
#define XLOG_LOGICAL_DECODING_STATUS_CHANGE
Definition pg_control.h:84
#define XLOG_END_OF_RECOVERY
Definition pg_control.h:78
void appendStringInfoString(StringInfo str, const char *s)
Definition stringinfo.c:230
#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, EpochFromFullTransactionId, fb(), get_wal_level_string(), LSN_FORMAT_ARGS, timestamptz_to_str(), wal_level, wal_level_str(), 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_LOGICAL_DECODING_STATUS_CHANGE, XLOG_NEXTOID, XLOG_OVERWRITE_CONTRECORD, XLOG_PARAMETER_CHANGE, XLOG_RESTORE_POINT, XLogRecGetData, and XLogRecGetInfo.

◆ xlog_identify()

const char * xlog_identify ( uint8  info)
extern

Definition at line 181 of file xlogdesc.c.

182{
183 const char *id = NULL;
184
185 switch (info & ~XLR_INFO_MASK)
186 {
188 id = "CHECKPOINT_SHUTDOWN";
189 break;
191 id = "CHECKPOINT_ONLINE";
192 break;
193 case XLOG_NOOP:
194 id = "NOOP";
195 break;
196 case XLOG_NEXTOID:
197 id = "NEXTOID";
198 break;
199 case XLOG_SWITCH:
200 id = "SWITCH";
201 break;
202 case XLOG_BACKUP_END:
203 id = "BACKUP_END";
204 break;
206 id = "PARAMETER_CHANGE";
207 break;
209 id = "RESTORE_POINT";
210 break;
211 case XLOG_FPW_CHANGE:
212 id = "FPW_CHANGE";
213 break;
215 id = "END_OF_RECOVERY";
216 break;
218 id = "OVERWRITE_CONTRECORD";
219 break;
220 case XLOG_FPI:
221 id = "FPI";
222 break;
224 id = "FPI_FOR_HINT";
225 break;
227 id = "CHECKPOINT_REDO";
228 break;
230 id = "LOGICAL_DECODING_STATUS_CHANGE";
231 break;
232 }
233
234 return id;
235}
#define XLOG_NOOP
Definition pg_control.h:71
#define XLOG_SWITCH
Definition pg_control.h:73
#define XLR_INFO_MASK
Definition xlogrecord.h:62

References fb(), 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_LOGICAL_DECODING_STATUS_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)
extern

Definition at line 8364 of file xlog.c.

8365{
8366 uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
8367 XLogRecPtr lsn = record->EndRecPtr;
8368
8369 /*
8370 * In XLOG rmgr, backup blocks are only used by XLOG_FPI and
8371 * XLOG_FPI_FOR_HINT records.
8372 */
8373 Assert(info == XLOG_FPI || info == XLOG_FPI_FOR_HINT ||
8374 !XLogRecHasAnyBlockRefs(record));
8375
8376 if (info == XLOG_NEXTOID)
8377 {
8378 Oid nextOid;
8379
8380 /*
8381 * We used to try to take the maximum of TransamVariables->nextOid and
8382 * the recorded nextOid, but that fails if the OID counter wraps
8383 * around. Since no OID allocation should be happening during replay
8384 * anyway, better to just believe the record exactly. We still take
8385 * OidGenLock while setting the variable, just in case.
8386 */
8387 memcpy(&nextOid, XLogRecGetData(record), sizeof(Oid));
8389 TransamVariables->nextOid = nextOid;
8392 }
8393 else if (info == XLOG_CHECKPOINT_SHUTDOWN)
8394 {
8395 CheckPoint checkPoint;
8396 TimeLineID replayTLI;
8397
8398 memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
8399 /* In a SHUTDOWN checkpoint, believe the counters exactly */
8401 TransamVariables->nextXid = checkPoint.nextXid;
8404 TransamVariables->nextOid = checkPoint.nextOid;
8408 checkPoint.nextMultiOffset);
8409
8411 checkPoint.oldestMultiDB);
8412
8413 /*
8414 * No need to set oldestClogXid here as well; it'll be set when we
8415 * redo an xl_clog_truncate if it changed since initialization.
8416 */
8417 SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
8418
8419 /*
8420 * If we see a shutdown checkpoint while waiting for an end-of-backup
8421 * record, the backup was canceled and the end-of-backup record will
8422 * never arrive.
8423 */
8427 ereport(PANIC,
8428 (errmsg("online backup was canceled, recovery cannot continue")));
8429
8430 /*
8431 * If we see a shutdown checkpoint, we know that nothing was running
8432 * on the primary at this point. So fake-up an empty running-xacts
8433 * record and use that here and now. Recover additional standby state
8434 * for prepared transactions.
8435 */
8437 {
8438 TransactionId *xids;
8439 int nxids;
8441 TransactionId latestCompletedXid;
8443
8445
8446 /* Update pg_subtrans entries for any prepared transactions */
8448
8449 /*
8450 * Construct a RunningTransactions snapshot representing a shut
8451 * down server, with only prepared transactions still alive. We're
8452 * never overflowed at this point because all subxids are listed
8453 * with their parent prepared transactions.
8454 */
8455 running.xcnt = nxids;
8456 running.subxcnt = 0;
8458 running.nextXid = XidFromFullTransactionId(checkPoint.nextXid);
8460 latestCompletedXid = XidFromFullTransactionId(checkPoint.nextXid);
8461 TransactionIdRetreat(latestCompletedXid);
8462 Assert(TransactionIdIsNormal(latestCompletedXid));
8463 running.latestCompletedXid = latestCompletedXid;
8464 running.xids = xids;
8465
8467 }
8468
8469 /* ControlFile->checkPointCopy always tracks the latest ckpt XID */
8473
8474 /*
8475 * We should've already switched to the new TLI before replaying this
8476 * record.
8477 */
8478 (void) GetCurrentReplayRecPtr(&replayTLI);
8479 if (checkPoint.ThisTimeLineID != replayTLI)
8480 ereport(PANIC,
8481 (errmsg("unexpected timeline ID %u (should be %u) in shutdown 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_CHECKPOINT_ONLINE)
8495 {
8496 CheckPoint checkPoint;
8497 TimeLineID replayTLI;
8498
8499 memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
8500 /* In an ONLINE checkpoint, treat the XID counter as a minimum */
8503 checkPoint.nextXid))
8504 TransamVariables->nextXid = checkPoint.nextXid;
8506
8507 /*
8508 * We ignore the nextOid counter in an ONLINE checkpoint, preferring
8509 * to track OID assignment through XLOG_NEXTOID records. The nextOid
8510 * counter is from the start of the checkpoint and might well be stale
8511 * compared to later XLOG_NEXTOID records. We could try to take the
8512 * maximum of the nextOid counter and our latest value, but since
8513 * there's no particular guarantee about the speed with which the OID
8514 * counter wraps around, that's a risky thing to do. In any case,
8515 * users of the nextOid counter are required to avoid assignment of
8516 * duplicates, so that a somewhat out-of-date value should be safe.
8517 */
8518
8519 /* Handle multixact */
8521 checkPoint.nextMultiOffset);
8522
8523 /*
8524 * NB: This may perform multixact truncation when replaying WAL
8525 * generated by an older primary.
8526 */
8528 checkPoint.oldestMultiDB);
8530 checkPoint.oldestXid))
8532 checkPoint.oldestXidDB);
8533 /* ControlFile->checkPointCopy always tracks the latest ckpt XID */
8537
8538 /* TLI should not change in an on-line checkpoint */
8539 (void) GetCurrentReplayRecPtr(&replayTLI);
8540 if (checkPoint.ThisTimeLineID != replayTLI)
8541 ereport(PANIC,
8542 (errmsg("unexpected timeline ID %u (should be %u) in online checkpoint record",
8543 checkPoint.ThisTimeLineID, replayTLI)));
8544
8545 RecoveryRestartPoint(&checkPoint, record);
8546
8547 /*
8548 * After replaying a checkpoint record, free all smgr objects.
8549 * Otherwise we would never do so for dropped relations, as the
8550 * startup does not process shared invalidation messages or call
8551 * AtEOXact_SMgr().
8552 */
8554 }
8555 else if (info == XLOG_OVERWRITE_CONTRECORD)
8556 {
8557 /* nothing to do here, handled in xlogrecovery_redo() */
8558 }
8559 else if (info == XLOG_END_OF_RECOVERY)
8560 {
8562 TimeLineID replayTLI;
8563
8564 memcpy(&xlrec, XLogRecGetData(record), sizeof(xl_end_of_recovery));
8565
8566 /*
8567 * For Hot Standby, we could treat this like a Shutdown Checkpoint,
8568 * but this case is rarer and harder to test, so the benefit doesn't
8569 * outweigh the potential extra cost of maintenance.
8570 */
8571
8572 /*
8573 * We should've already switched to the new TLI before replaying this
8574 * record.
8575 */
8576 (void) GetCurrentReplayRecPtr(&replayTLI);
8577 if (xlrec.ThisTimeLineID != replayTLI)
8578 ereport(PANIC,
8579 (errmsg("unexpected timeline ID %u (should be %u) in end-of-recovery record",
8580 xlrec.ThisTimeLineID, replayTLI)));
8581 }
8582 else if (info == XLOG_NOOP)
8583 {
8584 /* nothing to do here */
8585 }
8586 else if (info == XLOG_SWITCH)
8587 {
8588 /* nothing to do here */
8589 }
8590 else if (info == XLOG_RESTORE_POINT)
8591 {
8592 /* nothing to do here, handled in xlogrecovery.c */
8593 }
8594 else if (info == XLOG_FPI || info == XLOG_FPI_FOR_HINT)
8595 {
8596 /*
8597 * XLOG_FPI records contain nothing else but one or more block
8598 * references. Every block reference must include a full-page image
8599 * even if full_page_writes was disabled when the record was generated
8600 * - otherwise there would be no point in this record.
8601 *
8602 * XLOG_FPI_FOR_HINT records are generated when a page needs to be
8603 * WAL-logged because of a hint bit update. They are only generated
8604 * when checksums and/or wal_log_hints are enabled. They may include
8605 * no full-page images if full_page_writes was disabled when they were
8606 * generated. In this case there is nothing to do here.
8607 *
8608 * No recovery conflicts are generated by these generic records - if a
8609 * resource manager needs to generate conflicts, it has to define a
8610 * separate WAL record type and redo routine.
8611 */
8612 for (uint8 block_id = 0; block_id <= XLogRecMaxBlockId(record); block_id++)
8613 {
8614 Buffer buffer;
8615
8616 if (!XLogRecHasBlockImage(record, block_id))
8617 {
8618 if (info == XLOG_FPI)
8619 elog(ERROR, "XLOG_FPI record did not contain a full-page image");
8620 continue;
8621 }
8622
8623 if (XLogReadBufferForRedo(record, block_id, &buffer) != BLK_RESTORED)
8624 elog(ERROR, "unexpected XLogReadBufferForRedo result when restoring backup block");
8625 UnlockReleaseBuffer(buffer);
8626 }
8627 }
8628 else if (info == XLOG_BACKUP_END)
8629 {
8630 /* nothing to do here, handled in xlogrecovery_redo() */
8631 }
8632 else if (info == XLOG_PARAMETER_CHANGE)
8633 {
8635
8636 /* Update our copy of the parameters in pg_control */
8637 memcpy(&xlrec, XLogRecGetData(record), sizeof(xl_parameter_change));
8638
8640 ControlFile->MaxConnections = xlrec.MaxConnections;
8641 ControlFile->max_worker_processes = xlrec.max_worker_processes;
8642 ControlFile->max_wal_senders = xlrec.max_wal_senders;
8643 ControlFile->max_prepared_xacts = xlrec.max_prepared_xacts;
8644 ControlFile->max_locks_per_xact = xlrec.max_locks_per_xact;
8645 ControlFile->wal_level = xlrec.wal_level;
8646 ControlFile->wal_log_hints = xlrec.wal_log_hints;
8647
8648 /*
8649 * Update minRecoveryPoint to ensure that if recovery is aborted, we
8650 * recover back up to this point before allowing hot standby again.
8651 * This is important if the max_* settings are decreased, to ensure
8652 * you don't run queries against the WAL preceding the change. The
8653 * local copies cannot be updated as long as crash recovery is
8654 * happening and we expect all the WAL to be replayed.
8655 */
8657 {
8660 }
8662 {
8663 TimeLineID replayTLI;
8664
8665 (void) GetCurrentReplayRecPtr(&replayTLI);
8667 ControlFile->minRecoveryPointTLI = replayTLI;
8668 }
8669
8670 CommitTsParameterChange(xlrec.track_commit_timestamp,
8672 ControlFile->track_commit_timestamp = xlrec.track_commit_timestamp;
8673
8676
8677 /* Check to see if any parameter change gives a problem on recovery */
8679 }
8680 else if (info == XLOG_FPW_CHANGE)
8681 {
8682 bool fpw;
8683
8684 memcpy(&fpw, XLogRecGetData(record), sizeof(bool));
8685
8686 /*
8687 * Update the LSN of the last replayed XLOG_FPW_CHANGE record so that
8688 * do_pg_backup_start() and do_pg_backup_stop() can check whether
8689 * full_page_writes has been disabled during online backup.
8690 */
8691 if (!fpw)
8692 {
8697 }
8698
8699 /* Keep track of full_page_writes */
8701 }
8702 else if (info == XLOG_CHECKPOINT_REDO)
8703 {
8704 /* nothing to do here, just for informational purposes */
8705 }
8706 else if (info == XLOG_LOGICAL_DECODING_STATUS_CHANGE)
8707 {
8708 bool status;
8709
8710 memcpy(&status, XLogRecGetData(record), sizeof(bool));
8711
8712 /*
8713 * We need to toggle the logical decoding status and update the
8714 * XLogLogicalInfo cache of processes synchronously because
8715 * XLogLogicalInfoActive() is used even during read-only queries
8716 * (e.g., via RelationIsAccessibleInLogicalDecoding()). In the
8717 * 'disable' case, it is safe to invalidate existing slots after
8718 * disabling logical decoding because logical decoding cannot process
8719 * subsequent WAL records, which may not contain logical information.
8720 */
8721 if (status)
8723 else
8725
8726 elog(DEBUG1, "update logical decoding status to %d during recovery",
8727 status);
8728
8729 if (InRecovery && InHotStandby)
8730 {
8731 if (!status)
8732 {
8733 /*
8734 * Invalidate logical slots if we are in hot standby and the
8735 * primary disabled logical decoding.
8736 */
8738 0, InvalidOid,
8740 }
8741 else if (sync_replication_slots)
8742 {
8743 /*
8744 * Signal the postmaster to launch the slotsync worker.
8745 *
8746 * XXX: For simplicity, we keep the slotsync worker running
8747 * even after logical decoding is disabled. A future
8748 * improvement can consider starting and stopping the worker
8749 * based on logical decoding status change.
8750 */
8752 }
8753 }
8754 }
8755}
int Buffer
Definition buf.h:23
void UnlockReleaseBuffer(Buffer buffer)
Definition bufmgr.c:5522
void CommitTsParameterChange(bool newvalue, bool oldvalue)
Definition commit_ts.c:640
pid_t PostmasterPid
Definition globals.c:106
void DisableLogicalDecoding(void)
Definition logicalctl.c:492
void EnableLogicalDecoding(void)
Definition logicalctl.c:341
void MultiXactAdvanceOldest(MultiXactId oldestMulti, Oid oldestMultiDB)
Definition multixact.c:2240
void MultiXactAdvanceNextMXact(MultiXactId minMulti, MultiXactOffset minMultiOffset)
Definition multixact.c:2213
@ RS_INVAL_WAL_LEVEL
Definition slot.h:66
bool sync_replication_slots
Definition slotsync.c:122
void smgrdestroyall(void)
Definition smgr.c:386
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
#define kill(pid, sig)
Definition win32_port.h:490
#define SIGUSR1
Definition win32_port.h:170
static void RecoveryRestartPoint(const CheckPoint *checkPoint, XLogReaderState *record)
Definition xlog.c:7675
#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, DEBUG1, DisableLogicalDecoding(), elog, EnableLogicalDecoding(), XLogReaderState::EndRecPtr, ereport, errmsg, ERROR, fb(), FullTransactionIdPrecedes, GetCurrentReplayRecPtr(), InArchiveRecovery, XLogCtlData::info_lck, InHotStandby, InRecovery, InvalidateObsoleteReplicationSlots(), InvalidOid, InvalidTransactionId, kill, XLogCtlData::lastFpwDisableRecPtr, lastFullPageWrites, RunningTransactionsData::latestCompletedXid, LocalMinRecoveryPoint, LocalMinRecoveryPointTLI, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), ControlFileData::max_locks_per_xact, ControlFileData::max_prepared_xacts, ControlFileData::max_wal_senders, ControlFileData::max_worker_processes, 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, PostmasterPid, PrescanPreparedTransactions(), ProcArrayApplyRecoveryInfo(), XLogReaderState::ReadRecPtr, RecoveryRestartPoint(), RS_INVAL_WAL_LEVEL, SetTransactionIdLimit(), SIGUSR1, smgrdestroyall(), SpinLockAcquire(), SpinLockRelease(), STANDBY_INITIALIZED, StandbyRecoverPreparedTransactions(), standbyState, RunningTransactionsData::subxcnt, RunningTransactionsData::subxid_status, SUBXIDS_IN_SUBTRANS, sync_replication_slots, CheckPoint::ThisTimeLineID, ControlFileData::track_commit_timestamp, TransactionIdIsNormal, TransactionIdPrecedes(), TransactionIdRetreat, TransamVariables, UnlockReleaseBuffer(), UpdateControlFile(), ControlFileData::wal_level, 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_LOGICAL_DECODING_STATUS_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  )
extern

Definition at line 2972 of file xlog.c.

2973{
2975 bool flexible = true;
2976 static TimestampTz lastflush;
2978 int flushblocks;
2980
2981 /* XLOG doesn't need flushing during recovery */
2982 if (RecoveryInProgress())
2983 return false;
2984
2985 /*
2986 * Since we're not in recovery, InsertTimeLineID is set and can't change,
2987 * so we can read it without a lock.
2988 */
2990
2991 /* read updated LogwrtRqst */
2995
2996 /* back off to last completed page boundary */
2997 WriteRqst.Write -= WriteRqst.Write % XLOG_BLCKSZ;
2998
2999 /* if we have already flushed that far, consider async commit records */
3001 if (WriteRqst.Write <= LogwrtResult.Flush)
3002 {
3006 flexible = false; /* ensure it all gets written */
3007 }
3008
3009 /*
3010 * If already known flushed, we're done. Just need to check if we are
3011 * holding an open file handle to a logfile that's no longer in use,
3012 * preventing the file from being deleted.
3013 */
3014 if (WriteRqst.Write <= LogwrtResult.Flush)
3015 {
3016 if (openLogFile >= 0)
3017 {
3020 {
3021 XLogFileClose();
3022 }
3023 }
3024 return false;
3025 }
3026
3027 /*
3028 * Determine how far to flush WAL, based on the wal_writer_delay and
3029 * wal_writer_flush_after GUCs.
3030 *
3031 * Note that XLogSetAsyncXactLSN() performs similar calculation based on
3032 * wal_writer_flush_after, to decide when to wake us up. Make sure the
3033 * logic is the same in both places if you change this.
3034 */
3036 flushblocks =
3038
3039 if (WalWriterFlushAfter == 0 || lastflush == 0)
3040 {
3041 /* first call, or block based limits disabled */
3042 WriteRqst.Flush = WriteRqst.Write;
3043 lastflush = now;
3044 }
3046 {
3047 /*
3048 * Flush the writes at least every WalWriterDelay ms. This is
3049 * important to bound the amount of time it takes for an asynchronous
3050 * commit to hit disk.
3051 */
3052 WriteRqst.Flush = WriteRqst.Write;
3053 lastflush = now;
3054 }
3055 else if (flushblocks >= WalWriterFlushAfter)
3056 {
3057 /* exceeded wal_writer_flush_after blocks, flush */
3058 WriteRqst.Flush = WriteRqst.Write;
3059 lastflush = now;
3060 }
3061 else
3062 {
3063 /* no flushing, this time round */
3065 }
3066
3067#ifdef WAL_DEBUG
3068 if (XLOG_DEBUG)
3069 elog(LOG, "xlog bg flush request write %X/%08X; flush: %X/%08X, current is write %X/%08X; flush %X/%08X",
3074#endif
3075
3077
3078 /* now wait for any in-progress insertions to finish and get write lock */
3082 if (WriteRqst.Write > LogwrtResult.Write ||
3084 {
3086 }
3088
3090
3091 /* wake up walsenders now that we've released heavily contended locks */
3093
3094 /*
3095 * If we flushed an LSN that someone was waiting for, notify the waiters.
3096 */
3097 if (waitLSNState &&
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 */
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:1779
Datum now(PG_FUNCTION_ARGS)
Definition timestamp.c:1607
pg_atomic_uint64 minWaitedLSN[WAIT_LSN_TYPE_COUNT]
Definition xlogwait.h:85
XLogRecPtr asyncXactLSN
Definition xlog.c:461
static void WalSndWakeupProcessRequests(bool physical, bool logical)
Definition walsender.h:65
int WalWriterFlushAfter
Definition walwriter.c:72
int WalWriterDelay
Definition walwriter.c:71
static XLogRecPtr WaitXLogInsertionsToFinish(XLogRecPtr upto)
Definition xlog.c:1511
static void AdvanceXLInsertBuffer(XLogRecPtr upto, TimeLineID tli, bool opportunistic)
Definition xlog.c:1992
static void XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
Definition xlog.c:2291
static void XLogFileClose(void)
Definition xlog.c:3660
static XLogSegNo openLogSegNo
Definition xlog.c:639
#define XLByteInPrevSeg(xlrp, logSegNo, wal_segsz_bytes)
struct WaitLSNState * waitLSNState
Definition xlogwait.c:69
@ WAIT_LSN_TYPE_PRIMARY_FLUSH
Definition xlogwait.h:44

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

Referenced by WalWriterMain().

◆ XLogCheckpointNeeded()

bool XLogCheckpointNeeded ( XLogSegNo  new_segno)
extern

Definition at line 2267 of file xlog.c.

2268{
2270
2272
2274 return true;
2275 return false;
2276}
int CheckPointSegments
Definition xlog.c:160

References CheckPointSegments, fb(), RedoRecPtr, wal_segment_size, and XLByteToSeg.

Referenced by XLogPageRead(), and XLogWrite().

◆ XLogFileInit()

int XLogFileInit ( XLogSegNo  logsegno,
TimeLineID  logtli 
)
extern

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
3410 if (fd >= 0)
3411 return fd;
3412
3413 /* Now open original target segment (might not be file I just made) */
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:1346
int BasicOpenFile(const char *fileName, int fileFlags)
Definition fd.c:1090
#define O_CLOEXEC
Definition win32_port.h:344
static int get_sync_bit(int method)
Definition xlog.c:8762
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, fb(), 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 
)
extern

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
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, fb(), 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)
extern

Definition at line 2767 of file xlog.c.

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

References Assert, CommitDelay, CommitSiblings, elog, enableFsync, END_CRIT_SECTION, ERROR, fb(), XLogwrtResult::Flush, XLogCtlData::info_lck, XLogCtlData::InsertTimeLineID, LOG, LogwrtResult, XLogCtlData::LogwrtRqst, LSN_FORMAT_ARGS, LW_EXCLUSIVE, LWLockAcquireOrWait(), LWLockRelease(), MinimumActiveBackends(), WaitLSNState::minWaitedLSN, pg_atomic_read_u64(), pg_usleep(), pgstat_report_wait_end(), pgstat_report_wait_start(), RecoveryInProgress(), RefreshXLogWriteResult, SpinLockAcquire(), SpinLockRelease(), START_CRIT_SECTION, UpdateMinRecoveryPoint(), WAIT_LSN_TYPE_PRIMARY_FLUSH, waitLSNState, WaitLSNWakeup(), 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(), WalSndWaitForWal(), write_logical_decoding_status_update_record(), write_relmap_file(), WriteMTruncateXlogRec(), WriteTruncateXlogRec(), xact_redo_abort(), xact_redo_commit(), XLogInsertRecord(), and XLogReportParameters().

◆ XLogGetLastRemovedSegno()

XLogSegNo XLogGetLastRemovedSegno ( void  )
extern

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

Definition at line 3795 of file xlog.c.

3796{
3797 DIR *xldir;
3798 struct dirent *xlde;
3800
3802 while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
3803 {
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. */
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)
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(), fb(), FreeDir(), IsXLogFileName(), ReadDir(), wal_segment_size, XLOGDIR, and XLogFromFileName().

Referenced by GetOldestUnsummarizedLSN(), and MaybeRemoveOldWalSummaries().

◆ XLogGetReplicationSlotMinimumLSN()

XLogRecPtr XLogGetReplicationSlotMinimumLSN ( void  )
extern

Definition at line 2666 of file xlog.c.

2667{
2668 XLogRecPtr retval;
2669
2673
2674 return retval;
2675}
XLogRecPtr replicationSlotMinLSN
Definition xlog.c:462

References XLogCtlData::info_lck, XLogCtlData::replicationSlotMinLSN, SpinLockAcquire(), SpinLockRelease(), and XLogCtl.

Referenced by KeepLogSeg(), and reserve_wal_for_local_slot().

◆ XLogInsertAllowed()

bool XLogInsertAllowed ( void  )
extern

Definition at line 6499 of file xlog.c.

6500{
6501 /*
6502 * If value is "unconditionally true" or "unconditionally false", just
6503 * return it. This provides the normal fast path once recovery is known
6504 * done.
6505 */
6506 if (LocalXLogInsertAllowed >= 0)
6507 return (bool) LocalXLogInsertAllowed;
6508
6509 /*
6510 * Else, must check to see if we're still in recovery.
6511 */
6512 if (RecoveryInProgress())
6513 return false;
6514
6515 /*
6516 * On exit from recovery, reset to "unconditionally true", since there is
6517 * no need to keep checking.
6518 */
6520 return true;
6521}

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

Definition at line 750 of file xlog.c.

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

References appendBinaryStringInfo(), appendStringInfo(), appendStringInfoString(), Assert, buf, COMP_CRC32C, CopyXLogRecordToWAL(), DecodeXLogRecord(), DecodeXLogRecordRequiredSpace(), doPageWrites, elog, END_CRIT_SECTION, ERROR, fb(), FIN_CRC32C, holdingAllLocks, XLogCtlData::info_lck, initStringInfo(), XLogCtlData::Insert, Insert(), XLogCtlData::InsertTimeLineID, InvalidXLogRecPtr, WALInsertLockPadded::l, WALInsertLock::lastImportantAt, likely, LOG, LogwrtResult, XLogCtlData::LogwrtRqst, LSN_FORMAT_ARGS, MarkCurrentTransactionIdLoggedIfAny(), MarkSubxactTopXidLogged(), MemoryContextSwitchTo(), MyLockNo, palloc(), pfree(), pgstat_report_fixed, pgWalUsage, ProcLastRecPtr, 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, XL_ROUTINE, XLogRecord::xl_tot_len, XLOG_CHECKPOINT_REDO, XLOG_MARK_UNIMPORTANT, xlog_outdesc(), XLOG_SWITCH, XLogCtl, XLogFlush(), XLogInsertAllowed(), XLogReaderAllocate(), XLogRecPtrIsValid, and XLogSegmentOffset.

Referenced by XLogInsert().

◆ XLogNeedsFlush()

bool XLogNeedsFlush ( XLogRecPtr  record)
extern

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 */
3165 return true;
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:1348

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

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

◆ XLogPutNextOid()

void XLogPutNextOid ( Oid  nextOid)
extern

Definition at line 8152 of file xlog.c.

8153{
8155 XLogRegisterData(&nextOid, sizeof(Oid));
8157
8158 /*
8159 * We need not flush the NEXTOID record immediately, because any of the
8160 * just-allocated OIDs could only reach disk as part of a tuple insert or
8161 * update that would have its own XLOG record that must follow the NEXTOID
8162 * record. Therefore, the standard buffer LSN interlock applied to those
8163 * records will ensure no such OID reaches disk before the NEXTOID record
8164 * does.
8165 *
8166 * Note, however, that the above statement only covers state "within" the
8167 * database. When we use a generated OID as a file or directory name, we
8168 * are in a sense violating the basic WAL rule, because that filesystem
8169 * change may reach disk before the NEXTOID WAL record does. The impact
8170 * of this is that if a database crash occurs immediately afterward, we
8171 * might after restart re-generate the same OID and find that it conflicts
8172 * with the leftover file or directory. But since for safety's sake we
8173 * always loop until finding a nonconflicting filename, this poses no real
8174 * problem in practice. See pgsql-hackers discussion 27-Sep-2006.
8175 */
8176}

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

Referenced by GetNewObjectId().

◆ XLogRestorePoint()

XLogRecPtr XLogRestorePoint ( const char rpName)
extern

Definition at line 8207 of file xlog.c.

8208{
8211
8213 strlcpy(xlrec.rp_name, rpName, MAXFNAMELEN);
8214
8217
8219
8220 ereport(LOG,
8221 errmsg("restore point \"%s\" created at %X/%08X",
8223
8224 return RecPtr;
8225}
TimestampTz rp_time

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

Referenced by pg_create_restore_point().

◆ XLogSetAsyncXactLSN()

void XLogSetAsyncXactLSN ( XLogRecPtr  asyncXactLSN)
extern

Definition at line 2596 of file xlog.c.

2597{
2598 XLogRecPtr WriteRqstPtr = asyncXactLSN;
2599 bool sleeping;
2600 bool wakeup = false;
2602
2606 if (XLogCtl->asyncXactLSN < asyncXactLSN)
2607 XLogCtl->asyncXactLSN = asyncXactLSN;
2609
2610 /*
2611 * If somebody else already called this function with a more aggressive
2612 * LSN, they will have done what we needed (and perhaps more).
2613 */
2614 if (asyncXactLSN <= prevAsyncXactLSN)
2615 return;
2616
2617 /*
2618 * If the WALWriter is sleeping, kick it to make it come out of low-power
2619 * mode, so that this async commit will reach disk within the expected
2620 * amount of time. Otherwise, determine whether it has enough WAL
2621 * available to flush, the same way that XLogBackgroundFlush() does.
2622 */
2623 if (sleeping)
2624 wakeup = true;
2625 else
2626 {
2627 int flushblocks;
2628
2630
2631 flushblocks =
2633
2635 wakeup = true;
2636 }
2637
2638 if (wakeup)
2639 {
2640 volatile PROC_HDR *procglobal = ProcGlobal;
2641 ProcNumber walwriterProc = procglobal->walwriterProc;
2642
2643 if (walwriterProc != INVALID_PROC_NUMBER)
2644 SetLatch(&GetPGProcByNumber(walwriterProc)->procLatch);
2645 }
2646}
ProcNumber walwriterProc
Definition proc.h:488
static TimestampTz wakeup[NUM_WALRCV_WAKEUPS]

References XLogCtlData::asyncXactLSN, fb(), 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)
extern

◆ XLOGShmemInit()

void XLOGShmemInit ( void  )
extern

Definition at line 4995 of file xlog.c.

4996{
4997 bool foundCFile,
4998 foundXLog;
4999 char *allocptr;
5000 int i;
5002
5003#ifdef WAL_DEBUG
5004
5005 /*
5006 * Create a memory context for WAL debugging that's exempt from the normal
5007 * "no pallocs in critical section" rule. Yes, that can lead to a PANIC if
5008 * an allocation fails, but wal_debug is not for production use anyway.
5009 */
5010 if (walDebugCxt == NULL)
5011 {
5013 "WAL Debug",
5016 }
5017#endif
5018
5019
5020 XLogCtl = (XLogCtlData *)
5021 ShmemInitStruct("XLOG Ctl", XLOGShmemSize(), &foundXLog);
5022
5025 ShmemInitStruct("Control File", sizeof(ControlFileData), &foundCFile);
5026
5027 if (foundCFile || foundXLog)
5028 {
5029 /* both should be present or neither */
5031
5032 /* Initialize local copy of WALInsertLocks */
5034
5035 if (localControlFile)
5037 return;
5038 }
5039 memset(XLogCtl, 0, sizeof(XLogCtlData));
5040
5041 /*
5042 * Already have read control file locally, unless in bootstrap mode. Move
5043 * contents into shared memory.
5044 */
5045 if (localControlFile)
5046 {
5049 }
5050
5051 /*
5052 * Since XLogCtlData contains XLogRecPtr fields, its sizeof should be a
5053 * multiple of the alignment for same, so no extra alignment padding is
5054 * needed here.
5055 */
5056 allocptr = ((char *) XLogCtl) + sizeof(XLogCtlData);
5059
5060 for (i = 0; i < XLOGbuffers; i++)
5061 {
5063 }
5064
5065 /* WAL insertion locks. Ensure they're aligned to the full padded size */
5066 allocptr += sizeof(WALInsertLockPadded) -
5071
5072 for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
5073 {
5077 }
5078
5079 /*
5080 * Align the start of the page buffers to a full xlog block size boundary.
5081 * This simplifies some calculations in XLOG insertion. It is also
5082 * required for O_DIRECT.
5083 */
5087
5088 /*
5089 * Do basic initialization of XLogCtl shared data. (StartupXLOG will fill
5090 * in additional info.)
5091 */
5095 XLogCtl->WalWriterSleeping = false;
5096
5103}
static void pg_atomic_init_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition atomics.h:453
#define TYPEALIGN(ALIGNVAL, LEN)
Definition c.h:861
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition lwlock.c:699
MemoryContext TopMemoryContext
Definition mcxt.c:166
void MemoryContextAllowInCriticalSection(MemoryContext context, bool allow)
Definition mcxt.c:743
#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:378
static void SpinLockInit(volatile slock_t *lock)
Definition spin.h:50
int XLogCacheBlck
Definition xlog.c:497
WALInsertLockPadded * WALInsertLocks
Definition xlog.c:448
slock_t insertpos_lck
Definition xlog.c:402
Size XLOGShmemSize(void)
Definition xlog.c:4945
int XLOGbuffers
Definition xlog.c:121

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, ControlFile, fb(), 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  )
extern

Definition at line 4945 of file xlog.c.

4946{
4947 Size size;
4948
4949 /*
4950 * If the value of wal_buffers is -1, use the preferred auto-tune value.
4951 * This isn't an amazingly clean place to do this, but we must wait till
4952 * NBuffers has received its final value, and must do it before using the
4953 * value of XLOGbuffers to do anything important.
4954 *
4955 * We prefer to report this value's source as PGC_S_DYNAMIC_DEFAULT.
4956 * However, if the DBA explicitly set wal_buffers = -1 in the config file,
4957 * then PGC_S_DYNAMIC_DEFAULT will fail to override that and we must force
4958 * the matter with PGC_S_OVERRIDE.
4959 */
4960 if (XLOGbuffers == -1)
4961 {
4962 char buf[32];
4963
4964 snprintf(buf, sizeof(buf), "%d", XLOGChooseNumBuffers());
4965 SetConfigOption("wal_buffers", buf, PGC_POSTMASTER,
4967 if (XLOGbuffers == -1) /* failed to apply it? */
4968 SetConfigOption("wal_buffers", buf, PGC_POSTMASTER,
4970 }
4971 Assert(XLOGbuffers > 0);
4972
4973 /* XLogCtl */
4974 size = sizeof(XLogCtlData);
4975
4976 /* WAL insertion locks, plus alignment */
4977 size = add_size(size, mul_size(sizeof(WALInsertLockPadded), NUM_XLOGINSERT_LOCKS + 1));
4978 /* xlblocks array */
4979 size = add_size(size, mul_size(sizeof(pg_atomic_uint64), XLOGbuffers));
4980 /* extra alignment padding for XLOG I/O buffers */
4981 size = add_size(size, Max(XLOG_BLCKSZ, PG_IO_ALIGN_SIZE));
4982 /* and the buffers themselves */
4983 size = add_size(size, mul_size(XLOG_BLCKSZ, XLOGbuffers));
4984
4985 /*
4986 * Note: we don't count ControlFileData, it comes out of the "slop factor"
4987 * added by CreateSharedMemoryAndSemaphores. This lets us use this
4988 * routine again below to compute the actual allocation size.
4989 */
4990
4991 return size;
4992}
#define Max(x, y)
Definition c.h:1057
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:482
Size mul_size(Size s1, Size s2)
Definition shmem.c:497
static int XLOGChooseNumBuffers(void)
Definition xlog.c:4677

References add_size(), Assert, buf, fb(), 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  )
extern

Definition at line 9624 of file xlog.c.

9625{
9627
9630}
#define AmStartupProcess()
Definition miscadmin.h:390
void ShutdownWalRcv(void)
void ResetInstallXLogFileSegmentActive(void)
Definition xlog.c:9643

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

Referenced by XLogFlush().

◆ CommitSiblings

PGDLLIMPORT int CommitSiblings
extern

Definition at line 137 of file xlog.c.

Referenced by XLogFlush().

◆ EnableHotStandby

◆ fullPageWrites

PGDLLIMPORT bool fullPageWrites
extern

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

Referenced by ReadControlFile(), and XLOGfileslop().

◆ ProcLastRecPtr

PGDLLIMPORT XLogRecPtr ProcLastRecPtr
extern

◆ track_wal_io_timing

◆ wal_compression

PGDLLIMPORT int wal_compression
extern

Definition at line 128 of file xlog.c.

Referenced by XLogCompressBackupBlock(), and XLogRecordAssemble().

◆ wal_consistency_checking

PGDLLIMPORT bool* wal_consistency_checking
extern

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

Referenced by InitializeWalConsistencyChecking().

◆ wal_decode_buffer_size

PGDLLIMPORT int wal_decode_buffer_size
extern

Definition at line 140 of file xlog.c.

Referenced by InitWalRecovery().

◆ wal_init_zero

PGDLLIMPORT bool wal_init_zero
extern

Definition at line 131 of file xlog.c.

Referenced by XLogFileInitInternal().

◆ wal_keep_size_mb

PGDLLIMPORT int wal_keep_size_mb
extern

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

Referenced by InitControlFile(), and XLogReportParameters().

◆ wal_recycle

PGDLLIMPORT bool wal_recycle
extern

Definition at line 132 of file xlog.c.

Referenced by RemoveXlogFile().

◆ wal_retrieve_retry_interval

PGDLLIMPORT int wal_retrieve_retry_interval
extern

Definition at line 138 of file xlog.c.

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

◆ wal_segment_size

PGDLLIMPORT int wal_segment_size
extern

Definition at line 147 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

◆ XactLastCommitEnd

◆ XactLastRecEnd

◆ XLogArchiveCommand

◆ XLogArchiveMode

◆ XLogArchiveTimeout

PGDLLIMPORT int XLogArchiveTimeout
extern

Definition at line 122 of file xlog.c.

Referenced by CheckArchiveTimeout(), and CheckpointerMain().

◆ XLOGbuffers

PGDLLIMPORT int XLOGbuffers
extern

Definition at line 121 of file xlog.c.

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

◆ XLogLogicalInfo

PGDLLIMPORT bool XLogLogicalInfo
extern

Definition at line 108 of file logicalctl.c.

Referenced by update_xlog_logical_info().