PostgreSQL Source Code  git master
xlog.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <math.h>
#include <time.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include "access/clog.h"
#include "access/commit_ts.h"
#include "access/heaptoast.h"
#include "access/multixact.h"
#include "access/rewriteheap.h"
#include "access/subtrans.h"
#include "access/timeline.h"
#include "access/transam.h"
#include "access/twophase.h"
#include "access/xact.h"
#include "access/xlog_internal.h"
#include "access/xlogarchive.h"
#include "access/xloginsert.h"
#include "access/xlogprefetcher.h"
#include "access/xlogreader.h"
#include "access/xlogrecovery.h"
#include "access/xlogutils.h"
#include "backup/basebackup.h"
#include "catalog/catversion.h"
#include "catalog/pg_control.h"
#include "catalog/pg_database.h"
#include "common/controldata_utils.h"
#include "common/file_utils.h"
#include "executor/instrument.h"
#include "miscadmin.h"
#include "pg_trace.h"
#include "pgstat.h"
#include "port/atomics.h"
#include "port/pg_iovec.h"
#include "postmaster/bgwriter.h"
#include "postmaster/startup.h"
#include "postmaster/walsummarizer.h"
#include "postmaster/walwriter.h"
#include "replication/logical.h"
#include "replication/origin.h"
#include "replication/slot.h"
#include "replication/snapbuild.h"
#include "replication/walreceiver.h"
#include "replication/walsender.h"
#include "storage/bufmgr.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/large_object.h"
#include "storage/latch.h"
#include "storage/pmsignal.h"
#include "storage/predicate.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/reinit.h"
#include "storage/smgr.h"
#include "storage/spin.h"
#include "storage/sync.h"
#include "utils/guc_hooks.h"
#include "utils/guc_tables.h"
#include "utils/memutils.h"
#include "utils/ps_status.h"
#include "utils/relmapper.h"
#include "utils/pg_rusage.h"
#include "utils/snapmgr.h"
#include "utils/timeout.h"
#include "utils/timestamp.h"
#include "utils/varlena.h"
Include dependency graph for xlog.c:

Go to the source code of this file.

Data Structures

struct  XLogwrtRqst
 
struct  XLogwrtResult
 
struct  WALInsertLock
 
union  WALInsertLockPadded
 
struct  XLogCtlInsert
 
struct  XLogCtlData
 

Macros

#define BootstrapTimeLineID   1
 
#define NUM_XLOGINSERT_LOCKS   8
 
#define INSERT_FREESPACE(endptr)    (((endptr) % XLOG_BLCKSZ == 0) ? 0 : (XLOG_BLCKSZ - (endptr) % XLOG_BLCKSZ))
 
#define NextBufIdx(idx)    (((idx) == XLogCtl->XLogCacheBlck) ? 0 : ((idx) + 1))
 
#define XLogRecPtrToBufIdx(recptr)    (((recptr) / XLOG_BLCKSZ) % (XLogCtl->XLogCacheBlck + 1))
 
#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)
 
#define ConvertToXSegs(x, segsize)   XLogMBVarToSegs((x), (segsize))
 

Typedefs

typedef struct XLogwrtRqst XLogwrtRqst
 
typedef struct XLogwrtResult XLogwrtResult
 
typedef union WALInsertLockPadded WALInsertLockPadded
 
typedef struct XLogCtlInsert XLogCtlInsert
 
typedef struct XLogCtlData XLogCtlData
 

Enumerations

enum  WalInsertClass { WALINSERT_NORMAL , WALINSERT_SPECIAL_SWITCH , WALINSERT_SPECIAL_CHECKPOINT }
 

Functions

static void CleanupAfterArchiveRecovery (TimeLineID EndOfLogTLI, XLogRecPtr EndOfLog, TimeLineID newTLI)
 
static void CheckRequiredParameterValues (void)
 
static void XLogReportParameters (void)
 
static int LocalSetXLogInsertAllowed (void)
 
static void CreateEndOfRecoveryRecord (void)
 
static XLogRecPtr CreateOverwriteContrecordRecord (XLogRecPtr aborted_lsn, XLogRecPtr pagePtr, TimeLineID newTLI)
 
static void CheckPointGuts (XLogRecPtr checkPointRedo, int flags)
 
static void KeepLogSeg (XLogRecPtr recptr, XLogSegNo *logSegNo)
 
static XLogRecPtr XLogGetReplicationSlotMinimumLSN (void)
 
static void AdvanceXLInsertBuffer (XLogRecPtr upto, TimeLineID tli, bool opportunistic)
 
static void XLogWrite (XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
 
static bool InstallXLogFileSegment (XLogSegNo *segno, char *tmppath, bool find_free, XLogSegNo max_segno, TimeLineID tli)
 
static void XLogFileClose (void)
 
static void PreallocXlogFiles (XLogRecPtr endptr, TimeLineID tli)
 
static void RemoveTempXlogFiles (void)
 
static void RemoveOldXlogFiles (XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr, TimeLineID insertTLI)
 
static void RemoveXlogFile (const struct dirent *segment_de, XLogSegNo recycleSegNo, XLogSegNo *endlogSegNo, TimeLineID insertTLI)
 
static void UpdateLastRemovedPtr (char *filename)
 
static void ValidateXLOGDirectoryStructure (void)
 
static void CleanupBackupHistory (void)
 
static void UpdateMinRecoveryPoint (XLogRecPtr lsn, bool force)
 
static bool PerformRecoveryXLogAction (void)
 
static void InitControlFile (uint64 sysidentifier)
 
static void WriteControlFile (void)
 
static void ReadControlFile (void)
 
static void UpdateControlFile (void)
 
static char * str_time (pg_time_t tnow)
 
static int get_sync_bit (int method)
 
static void CopyXLogRecordToWAL (int write_len, bool isLogSwitch, XLogRecData *rdata, XLogRecPtr StartPos, XLogRecPtr EndPos, TimeLineID tli)
 
static void ReserveXLogInsertLocation (int size, XLogRecPtr *StartPos, XLogRecPtr *EndPos, XLogRecPtr *PrevPtr)
 
static bool ReserveXLogSwitch (XLogRecPtr *StartPos, XLogRecPtr *EndPos, XLogRecPtr *PrevPtr)
 
static XLogRecPtr WaitXLogInsertionsToFinish (XLogRecPtr upto)
 
static char * GetXLogBuffer (XLogRecPtr ptr, TimeLineID tli)
 
static XLogRecPtr XLogBytePosToRecPtr (uint64 bytepos)
 
static XLogRecPtr XLogBytePosToEndRecPtr (uint64 bytepos)
 
static uint64 XLogRecPtrToBytePos (XLogRecPtr ptr)
 
static void WALInsertLockAcquire (void)
 
static void WALInsertLockAcquireExclusive (void)
 
static void WALInsertLockRelease (void)
 
static void WALInsertLockUpdateInsertingAt (XLogRecPtr insertingAt)
 
XLogRecPtr XLogInsertRecord (XLogRecData *rdata, XLogRecPtr fpw_lsn, uint8 flags, int num_fpi, bool topxid_included)
 
Size WALReadFromBuffers (char *dstbuf, XLogRecPtr startptr, Size count, TimeLineID tli)
 
static void CalculateCheckpointSegments (void)
 
void assign_max_wal_size (int newval, void *extra)
 
void assign_checkpoint_completion_target (double newval, void *extra)
 
bool check_wal_segment_size (int *newval, void **extra, GucSource source)
 
bool check_max_slot_wal_keep_size (int *newval, void **extra, GucSource source)
 
static XLogSegNo XLOGfileslop (XLogRecPtr lastredoptr)
 
bool XLogCheckpointNeeded (XLogSegNo new_segno)
 
void XLogSetAsyncXactLSN (XLogRecPtr asyncXactLSN)
 
void XLogSetReplicationSlotMinimumLSN (XLogRecPtr lsn)
 
void XLogFlush (XLogRecPtr record)
 
bool XLogBackgroundFlush (void)
 
bool XLogNeedsFlush (XLogRecPtr record)
 
static int XLogFileInitInternal (XLogSegNo logsegno, TimeLineID logtli, bool *added, char *path)
 
int XLogFileInit (XLogSegNo logsegno, TimeLineID logtli)
 
static void XLogFileCopy (TimeLineID destTLI, XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno, int upto)
 
int XLogFileOpen (XLogSegNo segno, TimeLineID tli)
 
void CheckXLogRemoved (XLogSegNo segno, TimeLineID tli)
 
XLogSegNo XLogGetLastRemovedSegno (void)
 
XLogSegNo XLogGetOldestSegno (TimeLineID tli)
 
void RemoveNonParentXlogFiles (XLogRecPtr switchpoint, TimeLineID newTLI)
 
uint64 GetSystemIdentifier (void)
 
char * GetMockAuthenticationNonce (void)
 
bool DataChecksumsEnabled (void)
 
XLogRecPtr GetFakeLSNForUnloggedRel (void)
 
static int XLOGChooseNumBuffers (void)
 
bool check_wal_buffers (int *newval, void **extra, GucSource source)
 
bool check_wal_consistency_checking (char **newval, void **extra, GucSource source)
 
void assign_wal_consistency_checking (const char *newval, void *extra)
 
void InitializeWalConsistencyChecking (void)
 
const char * show_archive_command (void)
 
const char * show_in_hot_standby (void)
 
void LocalProcessControlFile (bool reset)
 
WalLevel GetActiveWalLevelOnStandby (void)
 
Size XLOGShmemSize (void)
 
void XLOGShmemInit (void)
 
void BootStrapXLOG (void)
 
static void XLogInitNewTimeline (TimeLineID endTLI, XLogRecPtr endOfLog, TimeLineID newTLI)
 
void StartupXLOG (void)
 
void SwitchIntoArchiveRecovery (XLogRecPtr EndRecPtr, TimeLineID replayTLI)
 
void ReachedEndOfBackup (XLogRecPtr EndRecPtr, TimeLineID tli)
 
bool RecoveryInProgress (void)
 
RecoveryState GetRecoveryState (void)
 
bool XLogInsertAllowed (void)
 
XLogRecPtr GetRedoRecPtr (void)
 
void GetFullPageWriteInfo (XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p)
 
XLogRecPtr GetInsertRecPtr (void)
 
XLogRecPtr GetFlushRecPtr (TimeLineID *insertTLI)
 
TimeLineID GetWALInsertionTimeLine (void)
 
XLogRecPtr GetLastImportantRecPtr (void)
 
pg_time_t GetLastSegSwitchData (XLogRecPtr *lastSwitchLSN)
 
void ShutdownXLOG (int code, Datum arg)
 
static void LogCheckpointStart (int flags, bool restartpoint)
 
static void LogCheckpointEnd (bool restartpoint)
 
static void UpdateCheckPointDistanceEstimate (uint64 nbytes)
 
static void update_checkpoint_display (int flags, bool restartpoint, bool reset)
 
void CreateCheckPoint (int flags)
 
static void RecoveryRestartPoint (const CheckPoint *checkPoint, XLogReaderState *record)
 
bool CreateRestartPoint (int flags)
 
WALAvailability GetWALAvailability (XLogRecPtr targetLSN)
 
void XLogPutNextOid (Oid nextOid)
 
XLogRecPtr RequestXLogSwitch (bool mark_unimportant)
 
XLogRecPtr XLogRestorePoint (const char *rpName)
 
void UpdateFullPageWrites (void)
 
void xlog_redo (XLogReaderState *record)
 
void assign_wal_sync_method (int new_wal_sync_method, void *extra)
 
void issue_xlog_fsync (int fd, XLogSegNo segno, TimeLineID tli)
 
void do_pg_backup_start (const char *backupidstr, bool fast, List **tablespaces, BackupState *state, StringInfo tblspcmapfile)
 
SessionBackupState get_backup_status (void)
 
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)
 
XLogRecPtr GetXLogInsertRecPtr (void)
 
XLogRecPtr GetXLogWriteRecPtr (void)
 
void GetOldestRestartPoint (XLogRecPtr *oldrecptr, TimeLineID *oldtli)
 
void XLogShutdownWalRcv (void)
 
void SetInstallXLogFileSegmentActive (void)
 
bool IsInstallXLogFileSegmentActive (void)
 
void SetWalWriterSleeping (bool sleeping)
 

Variables

uint32 bootstrap_data_checksum_version
 
int max_wal_size_mb = 1024
 
int min_wal_size_mb = 80
 
int wal_keep_size_mb = 0
 
int XLOGbuffers = -1
 
int XLogArchiveTimeout = 0
 
int XLogArchiveMode = ARCHIVE_MODE_OFF
 
char * XLogArchiveCommand = NULL
 
bool EnableHotStandby = false
 
bool fullPageWrites = true
 
bool wal_log_hints = false
 
int wal_compression = WAL_COMPRESSION_NONE
 
char * wal_consistency_checking_string = NULL
 
boolwal_consistency_checking = NULL
 
bool wal_init_zero = true
 
bool wal_recycle = true
 
bool log_checkpoints = true
 
int wal_sync_method = DEFAULT_WAL_SYNC_METHOD
 
int wal_level = WAL_LEVEL_REPLICA
 
int CommitDelay = 0
 
int CommitSiblings = 5
 
int wal_retrieve_retry_interval = 5000
 
int max_slot_wal_keep_size_mb = -1
 
int wal_decode_buffer_size = 512 * 1024
 
bool track_wal_io_timing = false
 
int wal_segment_size = DEFAULT_XLOG_SEG_SIZE
 
int CheckPointSegments
 
static double CheckPointDistanceEstimate = 0
 
static double PrevCheckPointDistance = 0
 
static bool check_wal_consistency_checking_deferred = false
 
const struct config_enum_entry wal_sync_method_options []
 
const struct config_enum_entry archive_mode_options []
 
CheckpointStatsData CheckpointStats
 
static bool lastFullPageWrites
 
static bool LocalRecoveryInProgress = true
 
static int LocalXLogInsertAllowed = -1
 
XLogRecPtr ProcLastRecPtr = InvalidXLogRecPtr
 
XLogRecPtr XactLastRecEnd = InvalidXLogRecPtr
 
XLogRecPtr XactLastCommitEnd = InvalidXLogRecPtr
 
static XLogRecPtr RedoRecPtr
 
static bool doPageWrites
 
static SessionBackupState sessionBackupState = SESSION_BACKUP_NONE
 
static XLogCtlDataXLogCtl = NULL
 
static WALInsertLockPaddedWALInsertLocks = NULL
 
static ControlFileDataControlFile = NULL
 
static int UsableBytesInSegment
 
static XLogwrtResult LogwrtResult = {0, 0}
 
static int openLogFile = -1
 
static XLogSegNo openLogSegNo = 0
 
static TimeLineID openLogTLI = 0
 
static XLogRecPtr LocalMinRecoveryPoint
 
static TimeLineID LocalMinRecoveryPointTLI
 
static bool updateMinRecoveryPoint = true
 
static int MyLockNo = 0
 
static bool holdingAllLocks = false
 

Macro Definition Documentation

◆ BootstrapTimeLineID

#define BootstrapTimeLineID   1

Definition at line 115 of file xlog.c.

◆ ConvertToXSegs

#define ConvertToXSegs (   x,
  segsize 
)    XLogMBVarToSegs((x), (segsize))

Definition at line 610 of file xlog.c.

◆ INSERT_FREESPACE

#define INSERT_FREESPACE (   endptr)     (((endptr) % XLOG_BLCKSZ == 0) ? 0 : (XLOG_BLCKSZ - (endptr) % XLOG_BLCKSZ))

Definition at line 587 of file xlog.c.

◆ NextBufIdx

#define NextBufIdx (   idx)     (((idx) == XLogCtl->XLogCacheBlck) ? 0 : ((idx) + 1))

Definition at line 591 of file xlog.c.

◆ NUM_XLOGINSERT_LOCKS

#define NUM_XLOGINSERT_LOCKS   8

Definition at line 154 of file xlog.c.

◆ UsableBytesInPage

#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)

Definition at line 604 of file xlog.c.

◆ XLogRecPtrToBufIdx

#define XLogRecPtrToBufIdx (   recptr)     (((recptr) / XLOG_BLCKSZ) % (XLogCtl->XLogCacheBlck + 1))

Definition at line 598 of file xlog.c.

Typedef Documentation

◆ WALInsertLockPadded

◆ XLogCtlData

typedef struct XLogCtlData XLogCtlData

◆ XLogCtlInsert

typedef struct XLogCtlInsert XLogCtlInsert

◆ XLogwrtResult

typedef struct XLogwrtResult XLogwrtResult

◆ XLogwrtRqst

typedef struct XLogwrtRqst XLogwrtRqst

Enumeration Type Documentation

◆ WalInsertClass

Enumerator
WALINSERT_NORMAL 
WALINSERT_SPECIAL_SWITCH 
WALINSERT_SPECIAL_CHECKPOINT 

Definition at line 566 of file xlog.c.

567 {
WalInsertClass
Definition: xlog.c:567
@ WALINSERT_SPECIAL_SWITCH
Definition: xlog.c:569
@ WALINSERT_NORMAL
Definition: xlog.c:568
@ WALINSERT_SPECIAL_CHECKPOINT
Definition: xlog.c:570

Function Documentation

◆ AdvanceXLInsertBuffer()

static void AdvanceXLInsertBuffer ( XLogRecPtr  upto,
TimeLineID  tli,
bool  opportunistic 
)
static

Definition at line 1949 of file xlog.c.

1950 {
1952  int nextidx;
1953  XLogRecPtr OldPageRqstPtr;
1954  XLogwrtRqst WriteRqst;
1955  XLogRecPtr NewPageEndPtr = InvalidXLogRecPtr;
1956  XLogRecPtr NewPageBeginPtr;
1957  XLogPageHeader NewPage;
1958  int npages pg_attribute_unused() = 0;
1959 
1960  LWLockAcquire(WALBufMappingLock, LW_EXCLUSIVE);
1961 
1962  /*
1963  * Now that we have the lock, check if someone initialized the page
1964  * already.
1965  */
1966  while (upto >= XLogCtl->InitializedUpTo || opportunistic)
1967  {
1969 
1970  /*
1971  * Get ending-offset of the buffer page we need to replace (this may
1972  * be zero if the buffer hasn't been used yet). Fall through if it's
1973  * already written out.
1974  */
1975  OldPageRqstPtr = pg_atomic_read_u64(&XLogCtl->xlblocks[nextidx]);
1976  if (LogwrtResult.Write < OldPageRqstPtr)
1977  {
1978  /*
1979  * Nope, got work to do. If we just want to pre-initialize as much
1980  * as we can without flushing, give up now.
1981  */
1982  if (opportunistic)
1983  break;
1984 
1985  /* Before waiting, get info_lck and update LogwrtResult */
1987  if (XLogCtl->LogwrtRqst.Write < OldPageRqstPtr)
1988  XLogCtl->LogwrtRqst.Write = OldPageRqstPtr;
1991 
1992  /*
1993  * Now that we have an up-to-date LogwrtResult value, see if we
1994  * still need to write it or if someone else already did.
1995  */
1996  if (LogwrtResult.Write < OldPageRqstPtr)
1997  {
1998  /*
1999  * Must acquire write lock. Release WALBufMappingLock first,
2000  * to make sure that all insertions that we need to wait for
2001  * can finish (up to this same position). Otherwise we risk
2002  * deadlock.
2003  */
2004  LWLockRelease(WALBufMappingLock);
2005 
2006  WaitXLogInsertionsToFinish(OldPageRqstPtr);
2007 
2008  LWLockAcquire(WALWriteLock, LW_EXCLUSIVE);
2009 
2011  if (LogwrtResult.Write >= OldPageRqstPtr)
2012  {
2013  /* OK, someone wrote it already */
2014  LWLockRelease(WALWriteLock);
2015  }
2016  else
2017  {
2018  /* Have to write it ourselves */
2019  TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_START();
2020  WriteRqst.Write = OldPageRqstPtr;
2021  WriteRqst.Flush = 0;
2022  XLogWrite(WriteRqst, tli, false);
2023  LWLockRelease(WALWriteLock);
2025  TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_DONE();
2026  }
2027  /* Re-acquire WALBufMappingLock and retry */
2028  LWLockAcquire(WALBufMappingLock, LW_EXCLUSIVE);
2029  continue;
2030  }
2031  }
2032 
2033  /*
2034  * Now the next buffer slot is free and we can set it up to be the
2035  * next output page.
2036  */
2037  NewPageBeginPtr = XLogCtl->InitializedUpTo;
2038  NewPageEndPtr = NewPageBeginPtr + XLOG_BLCKSZ;
2039 
2040  Assert(XLogRecPtrToBufIdx(NewPageBeginPtr) == nextidx);
2041 
2042  NewPage = (XLogPageHeader) (XLogCtl->pages + nextidx * (Size) XLOG_BLCKSZ);
2043 
2044  /*
2045  * Mark the xlblock with InvalidXLogRecPtr and issue a write barrier
2046  * before initializing. Otherwise, the old page may be partially
2047  * zeroed but look valid.
2048  */
2050  pg_write_barrier();
2051 
2052  /*
2053  * Be sure to re-zero the buffer so that bytes beyond what we've
2054  * written will look like zeroes and not valid XLOG records...
2055  */
2056  MemSet((char *) NewPage, 0, XLOG_BLCKSZ);
2057 
2058  /*
2059  * Fill the new page's header
2060  */
2061  NewPage->xlp_magic = XLOG_PAGE_MAGIC;
2062 
2063  /* NewPage->xlp_info = 0; */ /* done by memset */
2064  NewPage->xlp_tli = tli;
2065  NewPage->xlp_pageaddr = NewPageBeginPtr;
2066 
2067  /* NewPage->xlp_rem_len = 0; */ /* done by memset */
2068 
2069  /*
2070  * If online backup is not in progress, mark the header to indicate
2071  * that WAL records beginning in this page have removable backup
2072  * blocks. This allows the WAL archiver to know whether it is safe to
2073  * compress archived WAL data by transforming full-block records into
2074  * the non-full-block format. It is sufficient to record this at the
2075  * page level because we force a page switch (in fact a segment
2076  * switch) when starting a backup, so the flag will be off before any
2077  * records can be written during the backup. At the end of a backup,
2078  * the last page will be marked as all unsafe when perhaps only part
2079  * is unsafe, but at worst the archiver would miss the opportunity to
2080  * compress a few records.
2081  */
2082  if (Insert->runningBackups == 0)
2083  NewPage->xlp_info |= XLP_BKP_REMOVABLE;
2084 
2085  /*
2086  * If first page of an XLOG segment file, make it a long header.
2087  */
2088  if ((XLogSegmentOffset(NewPage->xlp_pageaddr, wal_segment_size)) == 0)
2089  {
2090  XLogLongPageHeader NewLongPage = (XLogLongPageHeader) NewPage;
2091 
2092  NewLongPage->xlp_sysid = ControlFile->system_identifier;
2093  NewLongPage->xlp_seg_size = wal_segment_size;
2094  NewLongPage->xlp_xlog_blcksz = XLOG_BLCKSZ;
2095  NewPage->xlp_info |= XLP_LONG_HEADER;
2096  }
2097 
2098  /*
2099  * Make sure the initialization of the page becomes visible to others
2100  * before the xlblocks update. GetXLogBuffer() reads xlblocks without
2101  * holding a lock.
2102  */
2103  pg_write_barrier();
2104 
2105  pg_atomic_write_u64(&XLogCtl->xlblocks[nextidx], NewPageEndPtr);
2106  XLogCtl->InitializedUpTo = NewPageEndPtr;
2107 
2108  npages++;
2109  }
2110  LWLockRelease(WALBufMappingLock);
2111 
2112 #ifdef WAL_DEBUG
2113  if (XLOG_DEBUG && npages > 0)
2114  {
2115  elog(DEBUG1, "initialized %d pages, up to %X/%X",
2116  npages, LSN_FORMAT_ARGS(NewPageEndPtr));
2117  }
2118 #endif
2119 }
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:433
#define pg_write_barrier()
Definition: atomics.h:154
static uint64 pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr)
Definition: atomics.h:424
#define pg_attribute_unused()
Definition: c.h:125
#define MemSet(start, val, len)
Definition: c.h:1009
size_t Size
Definition: c.h:594
#define DEBUG1
Definition: elog.h:30
static void Insert(File file)
Definition: fd.c:1313
Assert(fmt[strlen(fmt) - 1] !='\n')
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1168
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1781
@ LW_EXCLUSIVE
Definition: lwlock.h:116
PgStat_PendingWalStats PendingWalStats
Definition: pgstat_wal.c:24
#define SpinLockRelease(lock)
Definition: spin.h:64
#define SpinLockAcquire(lock)
Definition: spin.h:62
uint64 system_identifier
Definition: pg_control.h:109
PgStat_Counter wal_buffers_full
Definition: pgstat.h:452
XLogwrtRqst LogwrtRqst
Definition: xlog.c:465
slock_t info_lck
Definition: xlog.c:560
XLogRecPtr InitializedUpTo
Definition: xlog.c:497
char * pages
Definition: xlog.c:504
XLogwrtResult LogwrtResult
Definition: xlog.c:485
pg_atomic_uint64 * xlblocks
Definition: xlog.c:505
XLogCtlInsert Insert
Definition: xlog.c:462
TimeLineID xlp_tli
Definition: xlog_internal.h:40
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
XLogRecPtr Write
Definition: xlog.c:337
XLogRecPtr Flush
Definition: xlog.c:332
XLogRecPtr Write
Definition: xlog.c:331
static XLogCtlData * XLogCtl
Definition: xlog.c:573
static XLogRecPtr WaitXLogInsertionsToFinish(XLogRecPtr upto)
Definition: xlog.c:1497
int wal_segment_size
Definition: xlog.c:147
static XLogwrtResult LogwrtResult
Definition: xlog.c:619
#define XLogRecPtrToBufIdx(recptr)
Definition: xlog.c:598
static void XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
Definition: xlog.c:2278
static ControlFileData * ControlFile
Definition: xlog.c:581
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:71
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:54
#define XLP_LONG_HEADER
Definition: xlog_internal.h:76
#define XLP_BKP_REMOVABLE
Definition: xlog_internal.h:78
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
#define LSN_FORMAT_ARGS(lsn)
Definition: xlogdefs.h:43
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28

References Assert(), ControlFile, DEBUG1, elog(), XLogwrtRqst::Flush, XLogCtlData::info_lck, XLogCtlData::InitializedUpTo, XLogCtlData::Insert, Insert(), InvalidXLogRecPtr, XLogCtlData::LogwrtResult, LogwrtResult, XLogCtlData::LogwrtRqst, LSN_FORMAT_ARGS, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MemSet, XLogCtlData::pages, PendingWalStats, pg_atomic_read_u64(), pg_atomic_write_u64(), pg_attribute_unused, pg_write_barrier, SpinLockAcquire, SpinLockRelease, ControlFileData::system_identifier, WaitXLogInsertionsToFinish(), PgStat_PendingWalStats::wal_buffers_full, wal_segment_size, XLogwrtRqst::Write, XLogwrtResult::Write, XLogCtlData::xlblocks, XLOG_PAGE_MAGIC, XLogCtl, XLogRecPtrToBufIdx, XLogSegmentOffset, XLogWrite(), XLP_BKP_REMOVABLE, XLP_LONG_HEADER, XLogLongPageHeaderData::xlp_seg_size, XLogLongPageHeaderData::xlp_sysid, and XLogLongPageHeaderData::xlp_xlog_blcksz.

Referenced by GetXLogBuffer(), and XLogBackgroundFlush().

◆ assign_checkpoint_completion_target()

void assign_checkpoint_completion_target ( double  newval,
void *  extra 
)

Definition at line 2162 of file xlog.c.

2163 {
2166 }
double CheckPointCompletionTarget
Definition: checkpointer.c:137
#define newval
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2126

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2155 of file xlog.c.

2156 {
2159 }
int max_wal_size_mb
Definition: xlog.c:118

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

◆ assign_wal_consistency_checking()

void assign_wal_consistency_checking ( const char *  newval,
void *  extra 
)

Definition at line 4659 of file xlog.c.

4660 {
4661  /*
4662  * If some checks were deferred, it's possible that the checks will fail
4663  * later during InitializeWalConsistencyChecking(). But in that case, the
4664  * postmaster will exit anyway, so it's safe to proceed with the
4665  * assignment.
4666  *
4667  * Any built-in resource managers specified are assigned immediately,
4668  * which affects WAL created before shared_preload_libraries are
4669  * processed. Any custom resource managers specified won't be assigned
4670  * until after shared_preload_libraries are processed, but that's OK
4671  * because WAL for a custom resource manager can't be written before the
4672  * module is loaded anyway.
4673  */
4674  wal_consistency_checking = extra;
4675 }
bool * wal_consistency_checking
Definition: xlog.c:130

References wal_consistency_checking.

◆ assign_wal_sync_method()

void assign_wal_sync_method ( int  new_wal_sync_method,
void *  extra 
)

Definition at line 8480 of file xlog.c.

8481 {
8482  if (wal_sync_method != new_wal_sync_method)
8483  {
8484  /*
8485  * To ensure that no blocks escape unsynced, force an fsync on the
8486  * currently open log segment (if any). Also, if the open flag is
8487  * changing, close the log file so it will be reopened (with new flag
8488  * bit) at next use.
8489  */
8490  if (openLogFile >= 0)
8491  {
8492  pgstat_report_wait_start(WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN);
8493  if (pg_fsync(openLogFile) != 0)
8494  {
8495  char xlogfname[MAXFNAMELEN];
8496  int save_errno;
8497 
8498  save_errno = errno;
8499  XLogFileName(xlogfname, openLogTLI, openLogSegNo,
8501  errno = save_errno;
8502  ereport(PANIC,
8504  errmsg("could not fsync file \"%s\": %m", xlogfname)));
8505  }
8506 
8508  if (get_sync_bit(wal_sync_method) != get_sync_bit(new_wal_sync_method))
8509  XLogFileClose();
8510  }
8511  }
8512 }
int errcode_for_file_access(void)
Definition: elog.c:883
int errmsg(const char *fmt,...)
Definition: elog.c:1075
#define PANIC
Definition: elog.h:42
#define ereport(elevel,...)
Definition: elog.h:149
int pg_fsync(int fd)
Definition: fd.c:386
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:88
static void pgstat_report_wait_end(void)
Definition: wait_event.h:104
static int openLogFile
Definition: xlog.c:629
static int get_sync_bit(int method)
Definition: xlog.c:8432
int wal_sync_method
Definition: xlog.c:134
static TimeLineID openLogTLI
Definition: xlog.c:631
static void XLogFileClose(void)
Definition: xlog.c:3574
static XLogSegNo openLogSegNo
Definition: xlog.c:630
#define MAXFNAMELEN
static void XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)

References ereport, errcode_for_file_access(), errmsg(), get_sync_bit(), MAXFNAMELEN, openLogFile, openLogSegNo, openLogTLI, PANIC, pg_fsync(), pgstat_report_wait_end(), pgstat_report_wait_start(), wal_segment_size, wal_sync_method, XLogFileClose(), and XLogFileName().

◆ BootStrapXLOG()

void BootStrapXLOG ( void  )

Definition at line 4932 of file xlog.c.

4933 {
4934  CheckPoint checkPoint;
4935  char *buffer;
4936  XLogPageHeader page;
4937  XLogLongPageHeader longpage;
4938  XLogRecord *record;
4939  char *recptr;
4940  uint64 sysidentifier;
4941  struct timeval tv;
4942  pg_crc32c crc;
4943 
4944  /* allow ordinary WAL segment creation, like StartupXLOG() would */
4946 
4947  /*
4948  * Select a hopefully-unique system identifier code for this installation.
4949  * We use the result of gettimeofday(), including the fractional seconds
4950  * field, as being about as unique as we can easily get. (Think not to
4951  * use random(), since it hasn't been seeded and there's no portable way
4952  * to seed it other than the system clock value...) The upper half of the
4953  * uint64 value is just the tv_sec part, while the lower half contains the
4954  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
4955  * PID for a little extra uniqueness. A person knowing this encoding can
4956  * determine the initialization time of the installation, which could
4957  * perhaps be useful sometimes.
4958  */
4959  gettimeofday(&tv, NULL);
4960  sysidentifier = ((uint64) tv.tv_sec) << 32;
4961  sysidentifier |= ((uint64) tv.tv_usec) << 12;
4962  sysidentifier |= getpid() & 0xFFF;
4963 
4964  /* page buffer must be aligned suitably for O_DIRECT */
4965  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
4966  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
4967  memset(page, 0, XLOG_BLCKSZ);
4968 
4969  /*
4970  * Set up information for the initial checkpoint record
4971  *
4972  * The initial checkpoint record is written to the beginning of the WAL
4973  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
4974  * used, so that we can use 0/0 to mean "before any valid WAL segment".
4975  */
4976  checkPoint.redo = wal_segment_size + SizeOfXLogLongPHD;
4977  checkPoint.ThisTimeLineID = BootstrapTimeLineID;
4978  checkPoint.PrevTimeLineID = BootstrapTimeLineID;
4979  checkPoint.fullPageWrites = fullPageWrites;
4980  checkPoint.nextXid =
4982  checkPoint.nextOid = FirstGenbkiObjectId;
4983  checkPoint.nextMulti = FirstMultiXactId;
4984  checkPoint.nextMultiOffset = 0;
4985  checkPoint.oldestXid = FirstNormalTransactionId;
4986  checkPoint.oldestXidDB = Template1DbOid;
4987  checkPoint.oldestMulti = FirstMultiXactId;
4988  checkPoint.oldestMultiDB = Template1DbOid;
4991  checkPoint.time = (pg_time_t) time(NULL);
4993 
4994  TransamVariables->nextXid = checkPoint.nextXid;
4995  TransamVariables->nextOid = checkPoint.nextOid;
4997  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
4998  AdvanceOldestClogXid(checkPoint.oldestXid);
4999  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5000  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5002 
5003  /* Set up the XLOG page header */
5004  page->xlp_magic = XLOG_PAGE_MAGIC;
5005  page->xlp_info = XLP_LONG_HEADER;
5006  page->xlp_tli = BootstrapTimeLineID;
5008  longpage = (XLogLongPageHeader) page;
5009  longpage->xlp_sysid = sysidentifier;
5010  longpage->xlp_seg_size = wal_segment_size;
5011  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5012 
5013  /* Insert the initial checkpoint record */
5014  recptr = ((char *) page + SizeOfXLogLongPHD);
5015  record = (XLogRecord *) recptr;
5016  record->xl_prev = 0;
5017  record->xl_xid = InvalidTransactionId;
5018  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5020  record->xl_rmid = RM_XLOG_ID;
5021  recptr += SizeOfXLogRecord;
5022  /* fill the XLogRecordDataHeaderShort struct */
5023  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5024  *(recptr++) = sizeof(checkPoint);
5025  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5026  recptr += sizeof(checkPoint);
5027  Assert(recptr - (char *) record == record->xl_tot_len);
5028 
5029  INIT_CRC32C(crc);
5030  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5031  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5032  FIN_CRC32C(crc);
5033  record->xl_crc = crc;
5034 
5035  /* Create first XLOG segment file */
5038 
5039  /*
5040  * We needn't bother with Reserve/ReleaseExternalFD here, since we'll
5041  * close the file again in a moment.
5042  */
5043 
5044  /* Write the first page with the initial record */
5045  errno = 0;
5046  pgstat_report_wait_start(WAIT_EVENT_WAL_BOOTSTRAP_WRITE);
5047  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5048  {
5049  /* if write didn't set errno, assume problem is no disk space */
5050  if (errno == 0)
5051  errno = ENOSPC;
5052  ereport(PANIC,
5054  errmsg("could not write bootstrap write-ahead log file: %m")));
5055  }
5057 
5058  pgstat_report_wait_start(WAIT_EVENT_WAL_BOOTSTRAP_SYNC);
5059  if (pg_fsync(openLogFile) != 0)
5060  ereport(PANIC,
5062  errmsg("could not fsync bootstrap write-ahead log file: %m")));
5064 
5065  if (close(openLogFile) != 0)
5066  ereport(PANIC,
5068  errmsg("could not close bootstrap write-ahead log file: %m")));
5069 
5070  openLogFile = -1;
5071 
5072  /* Now create pg_control */
5073  InitControlFile(sysidentifier);
5074  ControlFile->time = checkPoint.time;
5075  ControlFile->checkPoint = checkPoint.redo;
5076  ControlFile->checkPointCopy = checkPoint;
5077 
5078  /* some additional ControlFile fields are set in WriteControlFile() */
5079  WriteControlFile();
5080 
5081  /* Bootstrap the commit log, too */
5082  BootStrapCLOG();
5086 
5087  pfree(buffer);
5088 
5089  /*
5090  * Force control file to be read - in contrast to normal processing we'd
5091  * otherwise never run the checks and GUC related initializations therein.
5092  */
5093  ReadControlFile();
5094 }
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:793
void BootStrapCLOG(void)
Definition: clog.c:722
void BootStrapCommitTs(void)
Definition: commit_ts.c:563
void SetCommitTsLimit(TransactionId oldestXact, TransactionId newestXact)
Definition: commit_ts.c:868
#define close(a)
Definition: win32.h:12
#define write(a, b, c)
Definition: win32.h:14
void pfree(void *pointer)
Definition: mcxt.c:1431
void * palloc(Size size)
Definition: mcxt.c:1201
void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset)
Definition: multixact.c:2186
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
Definition: multixact.c:2220
void BootStrapMultiXact(void)
Definition: multixact.c:1896
#define FirstMultiXactId
Definition: multixact.h:25
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
uint32 pg_crc32c
Definition: pg_crc32c.h:38
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:98
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:103
return crc
int64 pg_time_t
Definition: pgtime.h:23
Oid oldestMultiDB
Definition: pg_control.h:50
MultiXactId oldestMulti
Definition: pg_control.h:49
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
TransactionId newestCommitTsXid
Definition: pg_control.h:54
TransactionId oldestXid
Definition: pg_control.h:47
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
Oid nextOid
Definition: pg_control.h:44
TransactionId oldestActiveXid
Definition: pg_control.h:63
bool fullPageWrites
Definition: pg_control.h:42
MultiXactId nextMulti
Definition: pg_control.h:45
FullTransactionId nextXid
Definition: pg_control.h:43
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
pg_time_t time
Definition: pg_control.h:51
XLogRecPtr redo
Definition: pg_control.h:37
Oid oldestXidDB
Definition: pg_control.h:48
CheckPoint checkPointCopy
Definition: pg_control.h:134
pg_time_t time
Definition: pg_control.h:131
XLogRecPtr checkPoint
Definition: pg_control.h:132
FullTransactionId nextXid
Definition: transam.h:220
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:221
#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
int gettimeofday(struct timeval *tp, void *tzp)
int XLogFileInit(XLogSegNo logsegno, TimeLineID logtli)
Definition: xlog.c:3315
bool fullPageWrites
Definition: xlog.c:126
static void InitControlFile(uint64 sysidentifier)
Definition: xlog.c:4136
void SetInstallXLogFileSegmentActive(void)
Definition: xlog.c:9323
static void WriteControlFile(void)
Definition: xlog.c:4171
#define BootstrapTimeLineID
Definition: xlog.c:115
static void ReadControlFile(void)
Definition: xlog.c:4253
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:69
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:217
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:241
#define SizeOfXLogRecord
Definition: xlogrecord.h:55

References AdvanceOldestClogXid(), Assert(), BootStrapCLOG(), BootStrapCommitTs(), BootStrapMultiXact(), BootStrapSUBTRANS(), BootstrapTimeLineID, ControlFileData::checkPoint, ControlFileData::checkPointCopy, close, COMP_CRC32C, ControlFile, crc, ereport, errcode_for_file_access(), errmsg(), FIN_CRC32C, FirstGenbkiObjectId, FirstMultiXactId, FirstNormalTransactionId, fullPageWrites, CheckPoint::fullPageWrites, FullTransactionIdFromEpochAndXid(), gettimeofday(), INIT_CRC32C, InitControlFile(), InvalidTransactionId, MultiXactSetNextMXact(), CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, TransamVariablesData::nextOid, CheckPoint::nextOid, TransamVariablesData::nextXid, CheckPoint::nextXid, TransamVariablesData::oidCount, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, openLogFile, openLogTLI, palloc(), PANIC, pfree(), pg_fsync(), pgstat_report_wait_end(), pgstat_report_wait_start(), CheckPoint::PrevTimeLineID, ReadControlFile(), CheckPoint::redo, SetCommitTsLimit(), SetInstallXLogFileSegmentActive(), SetMultiXactIdLimit(), SetTransactionIdLimit(), SizeOfXLogLongPHD, SizeOfXLogRecord, SizeOfXLogRecordDataHeaderShort, CheckPoint::ThisTimeLineID, CheckPoint::time, ControlFileData::time, TransamVariables, TYPEALIGN, wal_segment_size, write, WriteControlFile(), XLogRecord::xl_crc, XLogRecord::xl_info, XLogRecord::xl_prev, XLogRecord::xl_rmid, XLogRecord::xl_tot_len, XLogRecord::xl_xid, XLOG_CHECKPOINT_SHUTDOWN, XLOG_PAGE_MAGIC, XLogFileInit(), XLogPageHeaderData::xlp_info, XLP_LONG_HEADER, XLogPageHeaderData::xlp_magic, XLogPageHeaderData::xlp_pageaddr, XLogLongPageHeaderData::xlp_seg_size, XLogLongPageHeaderData::xlp_sysid, XLogPageHeaderData::xlp_tli, XLogLongPageHeaderData::xlp_xlog_blcksz, and XLR_BLOCK_ID_DATA_SHORT.

Referenced by BootstrapModeMain().

◆ CalculateCheckpointSegments()

static void CalculateCheckpointSegments ( void  )
static

Definition at line 2126 of file xlog.c.

2127 {
2128  double target;
2129 
2130  /*-------
2131  * Calculate the distance at which to trigger a checkpoint, to avoid
2132  * exceeding max_wal_size_mb. This is based on two assumptions:
2133  *
2134  * a) we keep WAL for only one checkpoint cycle (prior to PG11 we kept
2135  * WAL for two checkpoint cycles to allow us to recover from the
2136  * secondary checkpoint if the first checkpoint failed, though we
2137  * only did this on the primary anyway, not on standby. Keeping just
2138  * one checkpoint simplifies processing and reduces disk space in
2139  * many smaller databases.)
2140  * b) during checkpoint, we consume checkpoint_completion_target *
2141  * number of segments consumed between checkpoints.
2142  *-------
2143  */
2144  target = (double) ConvertToXSegs(max_wal_size_mb, wal_segment_size) /
2146 
2147  /* round down */
2148  CheckPointSegments = (int) target;
2149 
2150  if (CheckPointSegments < 1)
2151  CheckPointSegments = 1;
2152 }
#define ConvertToXSegs(x, segsize)
Definition: xlog.c:610
int CheckPointSegments
Definition: xlog.c:160

References CheckPointCompletionTarget, CheckPointSegments, ConvertToXSegs, max_wal_size_mb, and wal_segment_size.

Referenced by assign_checkpoint_completion_target(), assign_max_wal_size(), and ReadControlFile().

◆ check_max_slot_wal_keep_size()

bool check_max_slot_wal_keep_size ( int *  newval,
void **  extra,
GucSource  source 
)

Definition at line 2187 of file xlog.c.

2188 {
2189  if (IsBinaryUpgrade && *newval != -1)
2190  {
2191  GUC_check_errdetail("\"%s\" must be set to -1 during binary upgrade mode.",
2192  "max_slot_wal_keep_size");
2193  return false;
2194  }
2195 
2196  return true;
2197 }
bool IsBinaryUpgrade
Definition: globals.c:117
#define GUC_check_errdetail
Definition: guc.h:446

References GUC_check_errdetail, IsBinaryUpgrade, and newval.

◆ check_wal_buffers()

bool check_wal_buffers ( int *  newval,
void **  extra,
GucSource  source 
)

Definition at line 4539 of file xlog.c.

4540 {
4541  /*
4542  * -1 indicates a request for auto-tune.
4543  */
4544  if (*newval == -1)
4545  {
4546  /*
4547  * If we haven't yet changed the boot_val default of -1, just let it
4548  * be. We'll fix it when XLOGShmemSize is called.
4549  */
4550  if (XLOGbuffers == -1)
4551  return true;
4552 
4553  /* Otherwise, substitute the auto-tune value */
4555  }
4556 
4557  /*
4558  * We clamp manually-set values to at least 4 blocks. Prior to PostgreSQL
4559  * 9.1, a minimum of 4 was enforced by guc.c, but since that is no longer
4560  * the case, we just silently treat such values as a request for the
4561  * minimum. (We could throw an error instead, but that doesn't seem very
4562  * helpful.)
4563  */
4564  if (*newval < 4)
4565  *newval = 4;
4566 
4567  return true;
4568 }
static int XLOGChooseNumBuffers(void)
Definition: xlog.c:4523
int XLOGbuffers
Definition: xlog.c:121

References newval, XLOGbuffers, and XLOGChooseNumBuffers().

◆ check_wal_consistency_checking()

bool check_wal_consistency_checking ( char **  newval,
void **  extra,
GucSource  source 
)

Definition at line 4574 of file xlog.c.

4575 {
4576  char *rawstring;
4577  List *elemlist;
4578  ListCell *l;
4579  bool newwalconsistency[RM_MAX_ID + 1];
4580 
4581  /* Initialize the array */
4582  MemSet(newwalconsistency, 0, (RM_MAX_ID + 1) * sizeof(bool));
4583 
4584  /* Need a modifiable copy of string */
4585  rawstring = pstrdup(*newval);
4586 
4587  /* Parse string into list of identifiers */
4588  if (!SplitIdentifierString(rawstring, ',', &elemlist))
4589  {
4590  /* syntax error in list */
4591  GUC_check_errdetail("List syntax is invalid.");
4592  pfree(rawstring);
4593  list_free(elemlist);
4594  return false;
4595  }
4596 
4597  foreach(l, elemlist)
4598  {
4599  char *tok = (char *) lfirst(l);
4600  int rmid;
4601 
4602  /* Check for 'all'. */
4603  if (pg_strcasecmp(tok, "all") == 0)
4604  {
4605  for (rmid = 0; rmid <= RM_MAX_ID; rmid++)
4606  if (RmgrIdExists(rmid) && GetRmgr(rmid).rm_mask != NULL)
4607  newwalconsistency[rmid] = true;
4608  }
4609  else
4610  {
4611  /* Check if the token matches any known resource manager. */
4612  bool found = false;
4613 
4614  for (rmid = 0; rmid <= RM_MAX_ID; rmid++)
4615  {
4616  if (RmgrIdExists(rmid) && GetRmgr(rmid).rm_mask != NULL &&
4617  pg_strcasecmp(tok, GetRmgr(rmid).rm_name) == 0)
4618  {
4619  newwalconsistency[rmid] = true;
4620  found = true;
4621  break;
4622  }
4623  }
4624  if (!found)
4625  {
4626  /*
4627  * During startup, it might be a not-yet-loaded custom
4628  * resource manager. Defer checking until
4629  * InitializeWalConsistencyChecking().
4630  */
4632  {
4634  }
4635  else
4636  {
4637  GUC_check_errdetail("Unrecognized key word: \"%s\".", tok);
4638  pfree(rawstring);
4639  list_free(elemlist);
4640  return false;
4641  }
4642  }
4643  }
4644  }
4645 
4646  pfree(rawstring);
4647  list_free(elemlist);
4648 
4649  /* assign new value */
4650  *extra = guc_malloc(ERROR, (RM_MAX_ID + 1) * sizeof(bool));
4651  memcpy(*extra, newwalconsistency, (RM_MAX_ID + 1) * sizeof(bool));
4652  return true;
4653 }
#define ERROR
Definition: elog.h:39
void * guc_malloc(int elevel, size_t size)
Definition: guc.c:633
void list_free(List *list)
Definition: list.c:1546
char * pstrdup(const char *in)
Definition: mcxt.c:1619
bool process_shared_preload_libraries_done
Definition: miscinit.c:1780
#define lfirst(lc)
Definition: pg_list.h:172
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
#define RM_MAX_ID
Definition: rmgr.h:33
Definition: pg_list.h:54
void(* rm_mask)(char *pagedata, BlockNumber blkno)
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3456
static bool check_wal_consistency_checking_deferred
Definition: xlog.c:170
static RmgrData GetRmgr(RmgrId rmid)
static bool RmgrIdExists(RmgrId rmid)

References check_wal_consistency_checking_deferred, ERROR, GetRmgr(), GUC_check_errdetail, guc_malloc(), lfirst, list_free(), MemSet, newval, pfree(), pg_strcasecmp(), process_shared_preload_libraries_done, pstrdup(), RmgrData::rm_mask, RM_MAX_ID, RmgrIdExists(), and SplitIdentifierString().

◆ check_wal_segment_size()

bool check_wal_segment_size ( int *  newval,
void **  extra,
GucSource  source 
)

Definition at line 2169 of file xlog.c.

2170 {
2171  if (!IsValidWalSegSize(*newval))
2172  {
2173  GUC_check_errdetail("The WAL segment size must be a power of two between 1 MB and 1 GB.");
2174  return false;
2175  }
2176 
2177  return true;
2178 }
#define IsValidWalSegSize(size)
Definition: xlog_internal.h:96

References GUC_check_errdetail, IsValidWalSegSize, and newval.

◆ CheckPointGuts()

static void CheckPointGuts ( XLogRecPtr  checkPointRedo,
int  flags 
)
static

Definition at line 7356 of file xlog.c.

7357 {
7363 
7364  /* Write out all dirty data in SLRUs and the main buffer pool */
7365  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_START(flags);
7367  CheckPointCLOG();
7372  CheckPointBuffers(flags);
7373 
7374  /* Perform all queued up fsyncs */
7375  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_SYNC_START();
7379  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_DONE();
7380 
7381  /* We deliberately delay 2PC checkpointing as long as possible */
7382  CheckPointTwoPhase(checkPointRedo);
7383 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1655
void CheckPointBuffers(int flags)
Definition: bufmgr.c:3364
void CheckPointCLOG(void)
Definition: clog.c:824
void CheckPointCommitTs(void)
Definition: commit_ts.c:782
void CheckPointMultiXact(void)
Definition: multixact.c:2162
void CheckPointReplicationOrigin(void)
Definition: origin.c:574
void CheckPointPredicate(void)
Definition: predicate.c:1021
void CheckPointRelationMap(void)
Definition: relmapper.c:612
void CheckPointLogicalRewriteHeap(void)
Definition: rewriteheap.c:1157
void CheckPointReplicationSlots(bool is_shutdown)
Definition: slot.c:1779
void CheckPointSnapBuild(void)
Definition: snapbuild.c:2055
TimestampTz ckpt_write_t
Definition: xlog.h:160
TimestampTz ckpt_sync_end_t
Definition: xlog.h:162
TimestampTz ckpt_sync_t
Definition: xlog.h:161
void CheckPointSUBTRANS(void)
Definition: subtrans.c:294
void ProcessSyncRequests(void)
Definition: sync.c:291
void CheckPointTwoPhase(XLogRecPtr redo_horizon)
Definition: twophase.c:1831
CheckpointStatsData CheckpointStats
Definition: xlog.c:213
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:137

References CHECKPOINT_IS_SHUTDOWN, CheckPointBuffers(), CheckPointCLOG(), CheckPointCommitTs(), CheckPointLogicalRewriteHeap(), CheckPointMultiXact(), CheckPointPredicate(), CheckPointRelationMap(), CheckPointReplicationOrigin(), CheckPointReplicationSlots(), CheckPointSnapBuild(), CheckpointStats, CheckPointSUBTRANS(), CheckPointTwoPhase(), CheckpointStatsData::ckpt_sync_end_t, CheckpointStatsData::ckpt_sync_t, CheckpointStatsData::ckpt_write_t, GetCurrentTimestamp(), and ProcessSyncRequests().

Referenced by CreateCheckPoint(), and CreateRestartPoint().

◆ CheckRequiredParameterValues()

static void CheckRequiredParameterValues ( void  )
static

Definition at line 5276 of file xlog.c.

5277 {
5278  /*
5279  * For archive recovery, the WAL must be generated with at least 'replica'
5280  * wal_level.
5281  */
5283  {
5284  ereport(FATAL,
5285  (errmsg("WAL was generated with wal_level=minimal, cannot continue recovering"),
5286  errdetail("This happens if you temporarily set wal_level=minimal on the server."),
5287  errhint("Use a backup taken after setting wal_level to higher than minimal.")));
5288  }
5289 
5290  /*
5291  * For Hot Standby, the WAL must be generated with 'replica' mode, and we
5292  * must have at least as many backend slots as the primary.
5293  */
5295  {
5296  /* We ignore autovacuum_max_workers when we make this test. */
5297  RecoveryRequiresIntParameter("max_connections",
5300  RecoveryRequiresIntParameter("max_worker_processes",
5303  RecoveryRequiresIntParameter("max_wal_senders",
5306  RecoveryRequiresIntParameter("max_prepared_transactions",
5309  RecoveryRequiresIntParameter("max_locks_per_transaction",
5312  }
5313 }
int errdetail(const char *fmt,...)
Definition: elog.c:1208
int errhint(const char *fmt,...)
Definition: elog.c:1322
#define FATAL
Definition: elog.h:41
int MaxConnections
Definition: globals.c:140
int max_worker_processes
Definition: globals.c:141
int max_locks_per_xact
Definition: lock.c:55
int max_worker_processes
Definition: pg_control.h:180
int max_locks_per_xact
Definition: pg_control.h:183
int max_prepared_xacts
Definition: pg_control.h:182
int max_prepared_xacts
Definition: twophase.c:118
int max_wal_senders
Definition: walsender.c:124
bool EnableHotStandby
Definition: xlog.c:125
@ WAL_LEVEL_MINIMAL
Definition: xlog.h:72
bool ArchiveRecoveryRequested
Definition: xlogrecovery.c:138
void RecoveryRequiresIntParameter(const char *param_name, int currValue, int minValue)

References ArchiveRecoveryRequested, ControlFile, EnableHotStandby, ereport, errdetail(), errhint(), errmsg(), FATAL, max_locks_per_xact, ControlFileData::max_locks_per_xact, max_prepared_xacts, ControlFileData::max_prepared_xacts, max_wal_senders, ControlFileData::max_wal_senders, max_worker_processes, ControlFileData::max_worker_processes, MaxConnections, ControlFileData::MaxConnections, RecoveryRequiresIntParameter(), ControlFileData::wal_level, and WAL_LEVEL_MINIMAL.

Referenced by StartupXLOG(), and xlog_redo().

◆ CheckXLogRemoved()

void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)

Definition at line 3662 of file xlog.c.

3663 {
3664  int save_errno = errno;
3665  XLogSegNo lastRemovedSegNo;
3666 
3668  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3670 
3671  if (segno <= lastRemovedSegNo)
3672  {
3673  char filename[MAXFNAMELEN];
3674 
3675  XLogFileName(filename, tli, segno, wal_segment_size);
3676  errno = save_errno;
3677  ereport(ERROR,
3679  errmsg("requested WAL segment %s has already been removed",
3680  filename)));
3681  }
3682  errno = save_errno;
3683 }
static char * filename
Definition: pg_dumpall.c:121
XLogSegNo lastRemovedSegNo
Definition: xlog.c:471
uint64 XLogSegNo
Definition: xlogdefs.h:48

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

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

◆ CleanupAfterArchiveRecovery()

static void CleanupAfterArchiveRecovery ( TimeLineID  EndOfLogTLI,
XLogRecPtr  EndOfLog,
TimeLineID  newTLI 
)
static

Definition at line 5187 of file xlog.c.

5189 {
5190  /*
5191  * Execute the recovery_end_command, if any.
5192  */
5193  if (recoveryEndCommand && strcmp(recoveryEndCommand, "") != 0)
5195  "recovery_end_command",
5196  true,
5197  WAIT_EVENT_RECOVERY_END_COMMAND);
5198 
5199  /*
5200  * We switched to a new timeline. Clean up segments on the old timeline.
5201  *
5202  * If there are any higher-numbered segments on the old timeline, remove
5203  * them. They might contain valid WAL, but they might also be
5204  * pre-allocated files containing garbage. In any case, they are not part
5205  * of the new timeline's history so we don't need them.
5206  */
5207  RemoveNonParentXlogFiles(EndOfLog, newTLI);
5208 
5209  /*
5210  * If the switch happened in the middle of a segment, what to do with the
5211  * last, partial segment on the old timeline? If we don't archive it, and
5212  * the server that created the WAL never archives it either (e.g. because
5213  * it was hit by a meteor), it will never make it to the archive. That's
5214  * OK from our point of view, because the new segment that we created with
5215  * the new TLI contains all the WAL from the old timeline up to the switch
5216  * point. But if you later try to do PITR to the "missing" WAL on the old
5217  * timeline, recovery won't find it in the archive. It's physically
5218  * present in the new file with new TLI, but recovery won't look there
5219  * when it's recovering to the older timeline. On the other hand, if we
5220  * archive the partial segment, and the original server on that timeline
5221  * is still running and archives the completed version of the same segment
5222  * later, it will fail. (We used to do that in 9.4 and below, and it
5223  * caused such problems).
5224  *
5225  * As a compromise, we rename the last segment with the .partial suffix,
5226  * and archive it. Archive recovery will never try to read .partial
5227  * segments, so they will normally go unused. But in the odd PITR case,
5228  * the administrator can copy them manually to the pg_wal directory
5229  * (removing the suffix). They can be useful in debugging, too.
5230  *
5231  * If a .done or .ready file already exists for the old timeline, however,
5232  * we had already determined that the segment is complete, so we can let
5233  * it be archived normally. (In particular, if it was restored from the
5234  * archive to begin with, it's expected to have a .done file).
5235  */
5236  if (XLogSegmentOffset(EndOfLog, wal_segment_size) != 0 &&
5238  {
5239  char origfname[MAXFNAMELEN];
5240  XLogSegNo endLogSegNo;
5241 
5242  XLByteToPrevSeg(EndOfLog, endLogSegNo, wal_segment_size);
5243  XLogFileName(origfname, EndOfLogTLI, endLogSegNo, wal_segment_size);
5244 
5245  if (!XLogArchiveIsReadyOrDone(origfname))
5246  {
5247  char origpath[MAXPGPATH];
5248  char partialfname[MAXFNAMELEN];
5249  char partialpath[MAXPGPATH];
5250 
5251  XLogFilePath(origpath, EndOfLogTLI, endLogSegNo, wal_segment_size);
5252  snprintf(partialfname, MAXFNAMELEN, "%s.partial", origfname);
5253  snprintf(partialpath, MAXPGPATH, "%s.partial", origpath);
5254 
5255  /*
5256  * Make sure there's no .done or .ready file for the .partial
5257  * file.
5258  */
5259  XLogArchiveCleanup(partialfname);
5260 
5261  durable_rename(origpath, partialpath, ERROR);
5262  XLogArchiveNotify(partialfname);
5263  }
5264  }
5265 }
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:782
#define MAXPGPATH
#define snprintf
Definition: port.h:238
void RemoveNonParentXlogFiles(XLogRecPtr switchpoint, TimeLineID newTLI)
Definition: xlog.c:3875
#define XLogArchivingActive()
Definition: xlog.h:97
#define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes)
static void XLogFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
bool XLogArchiveIsReadyOrDone(const char *xlog)
Definition: xlogarchive.c:665
void ExecuteRecoveryCommand(const char *command, const char *commandName, bool failOnSignal, uint32 wait_event_info)
Definition: xlogarchive.c:296
void XLogArchiveNotify(const char *xlog)
Definition: xlogarchive.c:445
void XLogArchiveCleanup(const char *xlog)
Definition: xlogarchive.c:713
char * recoveryEndCommand
Definition: xlogrecovery.c:84

References durable_rename(), ERROR, ExecuteRecoveryCommand(), MAXFNAMELEN, MAXPGPATH, recoveryEndCommand, RemoveNonParentXlogFiles(), snprintf, wal_segment_size, XLByteToPrevSeg, XLogArchiveCleanup(), XLogArchiveIsReadyOrDone(), XLogArchiveNotify(), XLogArchivingActive, XLogFileName(), XLogFilePath(), and XLogSegmentOffset.

Referenced by StartupXLOG().

◆ CleanupBackupHistory()

static void CleanupBackupHistory ( void  )
static

Definition at line 4093 of file xlog.c.

4094 {
4095  DIR *xldir;
4096  struct dirent *xlde;
4097  char path[MAXPGPATH + sizeof(XLOGDIR)];
4098 
4099  xldir = AllocateDir(XLOGDIR);
4100 
4101  while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
4102  {
4103  if (IsBackupHistoryFileName(xlde->d_name))
4104  {
4105  if (XLogArchiveCheckDone(xlde->d_name))
4106  {
4107  elog(DEBUG2, "removing WAL backup history file \"%s\"",
4108  xlde->d_name);
4109  snprintf(path, sizeof(path), XLOGDIR "/%s", xlde->d_name);
4110  unlink(path);
4111  XLogArchiveCleanup(xlde->d_name);
4112  }
4113  }
4114  }
4115 
4116  FreeDir(xldir);
4117 }
#define DEBUG2
Definition: elog.h:29
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2909
int FreeDir(DIR *dir)
Definition: fd.c:2961
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2843
Definition: dirent.c:26
Definition: dirent.h:10
char d_name[MAX_PATH]
Definition: dirent.h:15
#define XLOGDIR
static bool IsBackupHistoryFileName(const char *fname)
bool XLogArchiveCheckDone(const char *xlog)
Definition: xlogarchive.c:566

References AllocateDir(), dirent::d_name, DEBUG2, elog(), FreeDir(), IsBackupHistoryFileName(), MAXPGPATH, ReadDir(), snprintf, XLogArchiveCheckDone(), XLogArchiveCleanup(), and XLOGDIR.

Referenced by do_pg_backup_stop().

◆ CopyXLogRecordToWAL()

static void CopyXLogRecordToWAL ( int  write_len,
bool  isLogSwitch,
XLogRecData rdata,
XLogRecPtr  StartPos,
XLogRecPtr  EndPos,
TimeLineID  tli 
)
static

Definition at line 1220 of file xlog.c.

1222 {
1223  char *currpos;
1224  int freespace;
1225  int written;
1226  XLogRecPtr CurrPos;
1227  XLogPageHeader pagehdr;
1228 
1229  /*
1230  * Get a pointer to the right place in the right WAL buffer to start
1231  * inserting to.
1232  */
1233  CurrPos = StartPos;
1234  currpos = GetXLogBuffer(CurrPos, tli);
1235  freespace = INSERT_FREESPACE(CurrPos);
1236 
1237  /*
1238  * there should be enough space for at least the first field (xl_tot_len)
1239  * on this page.
1240  */
1241  Assert(freespace >= sizeof(uint32));
1242 
1243  /* Copy record data */
1244  written = 0;
1245  while (rdata != NULL)
1246  {
1247  char *rdata_data = rdata->data;
1248  int rdata_len = rdata->len;
1249 
1250  while (rdata_len > freespace)
1251  {
1252  /*
1253  * Write what fits on this page, and continue on the next page.
1254  */
1255  Assert(CurrPos % XLOG_BLCKSZ >= SizeOfXLogShortPHD || freespace == 0);
1256  memcpy(currpos, rdata_data, freespace);
1257  rdata_data += freespace;
1258  rdata_len -= freespace;
1259  written += freespace;
1260  CurrPos += freespace;
1261 
1262  /*
1263  * Get pointer to beginning of next page, and set the xlp_rem_len
1264  * in the page header. Set XLP_FIRST_IS_CONTRECORD.
1265  *
1266  * It's safe to set the contrecord flag and xlp_rem_len without a
1267  * lock on the page. All the other flags were already set when the
1268  * page was initialized, in AdvanceXLInsertBuffer, and we're the
1269  * only backend that needs to set the contrecord flag.
1270  */
1271  currpos = GetXLogBuffer(CurrPos, tli);
1272  pagehdr = (XLogPageHeader) currpos;
1273  pagehdr->xlp_rem_len = write_len - written;
1274  pagehdr->xlp_info |= XLP_FIRST_IS_CONTRECORD;
1275 
1276  /* skip over the page header */
1277  if (XLogSegmentOffset(CurrPos, wal_segment_size) == 0)
1278  {
1279  CurrPos += SizeOfXLogLongPHD;
1280  currpos += SizeOfXLogLongPHD;
1281  }
1282  else
1283  {
1284  CurrPos += SizeOfXLogShortPHD;
1285  currpos += SizeOfXLogShortPHD;
1286  }
1287  freespace = INSERT_FREESPACE(CurrPos);
1288  }
1289 
1290  Assert(CurrPos % XLOG_BLCKSZ >= SizeOfXLogShortPHD || rdata_len == 0);
1291  memcpy(currpos, rdata_data, rdata_len);
1292  currpos += rdata_len;
1293  CurrPos += rdata_len;
1294  freespace -= rdata_len;
1295  written += rdata_len;
1296 
1297  rdata = rdata->next;
1298  }
1299  Assert(written == write_len);
1300 
1301  /*
1302  * If this was an xlog-switch, it's not enough to write the switch record,
1303  * we also have to consume all the remaining space in the WAL segment. We
1304  * have already reserved that space, but we need to actually fill it.
1305  */
1306  if (isLogSwitch && XLogSegmentOffset(CurrPos, wal_segment_size) != 0)
1307  {
1308  /* An xlog-switch record doesn't contain any data besides the header */
1309  Assert(write_len == SizeOfXLogRecord);
1310 
1311  /* Assert that we did reserve the right amount of space */
1312  Assert(XLogSegmentOffset(EndPos, wal_segment_size) == 0);
1313 
1314  /* Use up all the remaining space on the current page */
1315  CurrPos += freespace;
1316 
1317  /*
1318  * Cause all remaining pages in the segment to be flushed, leaving the
1319  * XLog position where it should be, at the start of the next segment.
1320  * We do this one page at a time, to make sure we don't deadlock
1321  * against ourselves if wal_buffers < wal_segment_size.
1322  */
1323  while (CurrPos < EndPos)
1324  {
1325  /*
1326  * The minimal action to flush the page would be to call
1327  * WALInsertLockUpdateInsertingAt(CurrPos) followed by
1328  * AdvanceXLInsertBuffer(...). The page would be left initialized
1329  * mostly to zeros, except for the page header (always the short
1330  * variant, as this is never a segment's first page).
1331  *
1332  * The large vistas of zeros are good for compressibility, but the
1333  * headers interrupting them every XLOG_BLCKSZ (with values that
1334  * differ from page to page) are not. The effect varies with
1335  * compression tool, but bzip2 for instance compresses about an
1336  * order of magnitude worse if those headers are left in place.
1337  *
1338  * Rather than complicating AdvanceXLInsertBuffer itself (which is
1339  * called in heavily-loaded circumstances as well as this lightly-
1340  * loaded one) with variant behavior, we just use GetXLogBuffer
1341  * (which itself calls the two methods we need) to get the pointer
1342  * and zero most of the page. Then we just zero the page header.
1343  */
1344  currpos = GetXLogBuffer(CurrPos, tli);
1345  MemSet(currpos, 0, SizeOfXLogShortPHD);
1346 
1347  CurrPos += XLOG_BLCKSZ;
1348  }
1349  }
1350  else
1351  {
1352  /* Align the end position, so that the next record starts aligned */
1353  CurrPos = MAXALIGN64(CurrPos);
1354  }
1355 
1356  if (CurrPos != EndPos)
1357  elog(PANIC, "space reserved for WAL record does not match what was written");
1358 }
unsigned int uint32
Definition: c.h:495
#define MAXALIGN64(LEN)
Definition: c.h:825
struct XLogRecData * next
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:587
static char * GetXLogBuffer(XLogRecPtr ptr, TimeLineID tli)
Definition: xlog.c:1607
#define XLP_FIRST_IS_CONTRECORD
Definition: xlog_internal.h:74
#define SizeOfXLogShortPHD
Definition: xlog_internal.h:52

References Assert(), XLogRecData::data, elog(), GetXLogBuffer(), INSERT_FREESPACE, XLogRecData::len, MAXALIGN64, MemSet, XLogRecData::next, PANIC, SizeOfXLogLongPHD, SizeOfXLogRecord, SizeOfXLogShortPHD, wal_segment_size, XLogSegmentOffset, XLP_FIRST_IS_CONTRECORD, XLogPageHeaderData::xlp_info, and XLogPageHeaderData::xlp_rem_len.

Referenced by XLogInsertRecord().

◆ CreateCheckPoint()

void CreateCheckPoint ( int  flags)

Definition at line 6744 of file xlog.c.

6745 {
6746  bool shutdown;
6747  CheckPoint checkPoint;
6748  XLogRecPtr recptr;
6749  XLogSegNo _logSegNo;
6751  uint32 freespace;
6752  XLogRecPtr PriorRedoPtr;
6753  XLogRecPtr last_important_lsn;
6754  VirtualTransactionId *vxids;
6755  int nvxids;
6756  int oldXLogAllowed = 0;
6757 
6758  /*
6759  * An end-of-recovery checkpoint is really a shutdown checkpoint, just
6760  * issued at a different time.
6761  */
6763  shutdown = true;
6764  else
6765  shutdown = false;
6766 
6767  /* sanity check */
6768  if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
6769  elog(ERROR, "can't create a checkpoint during recovery");
6770 
6771  /*
6772  * Prepare to accumulate statistics.
6773  *
6774  * Note: because it is possible for log_checkpoints to change while a
6775  * checkpoint proceeds, we always accumulate stats, even if
6776  * log_checkpoints is currently off.
6777  */
6778  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
6780 
6781  /*
6782  * Let smgr prepare for checkpoint; this has to happen outside the
6783  * critical section and before we determine the REDO pointer. Note that
6784  * smgr must not do anything that'd have to be undone if we decide no
6785  * checkpoint is needed.
6786  */
6788 
6789  /*
6790  * Use a critical section to force system panic if we have trouble.
6791  */
6793 
6794  if (shutdown)
6795  {
6796  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6799  LWLockRelease(ControlFileLock);
6800  }
6801 
6802  /* Begin filling in the checkpoint WAL record */
6803  MemSet(&checkPoint, 0, sizeof(checkPoint));
6804  checkPoint.time = (pg_time_t) time(NULL);
6805 
6806  /*
6807  * For Hot Standby, derive the oldestActiveXid before we fix the redo
6808  * pointer. This allows us to begin accumulating changes to assemble our
6809  * starting snapshot of locks and transactions.
6810  */
6811  if (!shutdown && XLogStandbyInfoActive())
6813  else
6815 
6816  /*
6817  * Get location of last important record before acquiring insert locks (as
6818  * GetLastImportantRecPtr() also locks WAL locks).
6819  */
6820  last_important_lsn = GetLastImportantRecPtr();
6821 
6822  /*
6823  * If this isn't a shutdown or forced checkpoint, and if there has been no
6824  * WAL activity requiring a checkpoint, skip it. The idea here is to
6825  * avoid inserting duplicate checkpoints when the system is idle.
6826  */
6828  CHECKPOINT_FORCE)) == 0)
6829  {
6830  if (last_important_lsn == ControlFile->checkPoint)
6831  {
6832  END_CRIT_SECTION();
6833  ereport(DEBUG1,
6834  (errmsg_internal("checkpoint skipped because system is idle")));
6835  return;
6836  }
6837  }
6838 
6839  /*
6840  * An end-of-recovery checkpoint is created before anyone is allowed to
6841  * write WAL. To allow us to write the checkpoint record, temporarily
6842  * enable XLogInsertAllowed.
6843  */
6844  if (flags & CHECKPOINT_END_OF_RECOVERY)
6845  oldXLogAllowed = LocalSetXLogInsertAllowed();
6846 
6847  checkPoint.ThisTimeLineID = XLogCtl->InsertTimeLineID;
6848  if (flags & CHECKPOINT_END_OF_RECOVERY)
6849  checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
6850  else
6851  checkPoint.PrevTimeLineID = checkPoint.ThisTimeLineID;
6852 
6853  /*
6854  * We must block concurrent insertions while examining insert state.
6855  */
6857 
6858  checkPoint.fullPageWrites = Insert->fullPageWrites;
6859 
6860  if (shutdown)
6861  {
6862  XLogRecPtr curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
6863 
6864  /*
6865  * Compute new REDO record ptr = location of next XLOG record.
6866  *
6867  * Since this is a shutdown checkpoint, there can't be any concurrent
6868  * WAL insertion.
6869  */
6870  freespace = INSERT_FREESPACE(curInsert);
6871  if (freespace == 0)
6872  {
6873  if (XLogSegmentOffset(curInsert, wal_segment_size) == 0)
6874  curInsert += SizeOfXLogLongPHD;
6875  else
6876  curInsert += SizeOfXLogShortPHD;
6877  }
6878  checkPoint.redo = curInsert;
6879 
6880  /*
6881  * Here we update the shared RedoRecPtr for future XLogInsert calls;
6882  * this must be done while holding all the insertion locks.
6883  *
6884  * Note: if we fail to complete the checkpoint, RedoRecPtr will be
6885  * left pointing past where it really needs to point. This is okay;
6886  * the only consequence is that XLogInsert might back up whole buffers
6887  * that it didn't really need to. We can't postpone advancing
6888  * RedoRecPtr because XLogInserts that happen while we are dumping
6889  * buffers must assume that their buffer changes are not included in
6890  * the checkpoint.
6891  */
6892  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
6893  }
6894 
6895  /*
6896  * Now we can release the WAL insertion locks, allowing other xacts to
6897  * proceed while we are flushing disk buffers.
6898  */
6900 
6901  /*
6902  * If this is an online checkpoint, we have not yet determined the redo
6903  * point. We do so now by inserting the special XLOG_CHECKPOINT_REDO
6904  * record; the LSN at which it starts becomes the new redo pointer. We
6905  * don't do this for a shutdown checkpoint, because in that case no WAL
6906  * can be written between the redo point and the insertion of the
6907  * checkpoint record itself, so the checkpoint record itself serves to
6908  * mark the redo point.
6909  */
6910  if (!shutdown)
6911  {
6912  int dummy = 0;
6913 
6914  /* Record must have payload to avoid assertion failure. */
6915  XLogBeginInsert();
6916  XLogRegisterData((char *) &dummy, sizeof(dummy));
6917  (void) XLogInsert(RM_XLOG_ID, XLOG_CHECKPOINT_REDO);
6918 
6919  /*
6920  * XLogInsertRecord will have updated XLogCtl->Insert.RedoRecPtr in
6921  * shared memory and RedoRecPtr in backend-local memory, but we need
6922  * to copy that into the record that will be inserted when the
6923  * checkpoint is complete.
6924  */
6925  checkPoint.redo = RedoRecPtr;
6926  }
6927 
6928  /* Update the info_lck-protected copy of RedoRecPtr as well */
6930  XLogCtl->RedoRecPtr = checkPoint.redo;
6932 
6933  /*
6934  * If enabled, log checkpoint start. We postpone this until now so as not
6935  * to log anything if we decided to skip the checkpoint.
6936  */
6937  if (log_checkpoints)
6938  LogCheckpointStart(flags, false);
6939 
6940  /* Update the process title */
6941  update_checkpoint_display(flags, false, false);
6942 
6943  TRACE_POSTGRESQL_CHECKPOINT_START(flags);
6944 
6945  /*
6946  * Get the other info we need for the checkpoint record.
6947  *
6948  * We don't need to save oldestClogXid in the checkpoint, it only matters
6949  * for the short period in which clog is being truncated, and if we crash
6950  * during that we'll redo the clog truncation and fix up oldestClogXid
6951  * there.
6952  */
6953  LWLockAcquire(XidGenLock, LW_SHARED);
6954  checkPoint.nextXid = TransamVariables->nextXid;
6955  checkPoint.oldestXid = TransamVariables->oldestXid;
6957  LWLockRelease(XidGenLock);
6958 
6959  LWLockAcquire(CommitTsLock, LW_SHARED);
6962  LWLockRelease(CommitTsLock);
6963 
6964  LWLockAcquire(OidGenLock, LW_SHARED);
6965  checkPoint.nextOid = TransamVariables->nextOid;
6966  if (!shutdown)
6967  checkPoint.nextOid += TransamVariables->oidCount;
6968  LWLockRelease(OidGenLock);
6969 
6970  MultiXactGetCheckptMulti(shutdown,
6971  &checkPoint.nextMulti,
6972  &checkPoint.nextMultiOffset,
6973  &checkPoint.oldestMulti,
6974  &checkPoint.oldestMultiDB);
6975 
6976  /*
6977  * Having constructed the checkpoint record, ensure all shmem disk buffers
6978  * and commit-log buffers are flushed to disk.
6979  *
6980  * This I/O could fail for various reasons. If so, we will fail to
6981  * complete the checkpoint, but there is no reason to force a system
6982  * panic. Accordingly, exit critical section while doing it.
6983  */
6984  END_CRIT_SECTION();
6985 
6986  /*
6987  * In some cases there are groups of actions that must all occur on one
6988  * side or the other of a checkpoint record. Before flushing the
6989  * checkpoint record we must explicitly wait for any backend currently
6990  * performing those groups of actions.
6991  *
6992  * One example is end of transaction, so we must wait for any transactions
6993  * that are currently in commit critical sections. If an xact inserted
6994  * its commit record into XLOG just before the REDO point, then a crash
6995  * restart from the REDO point would not replay that record, which means
6996  * that our flushing had better include the xact's update of pg_xact. So
6997  * we wait till he's out of his commit critical section before proceeding.
6998  * See notes in RecordTransactionCommit().
6999  *
7000  * Because we've already released the insertion locks, this test is a bit
7001  * fuzzy: it is possible that we will wait for xacts we didn't really need
7002  * to wait for. But the delay should be short and it seems better to make
7003  * checkpoint take a bit longer than to hold off insertions longer than
7004  * necessary. (In fact, the whole reason we have this issue is that xact.c
7005  * does commit record XLOG insertion and clog update as two separate steps
7006  * protected by different locks, but again that seems best on grounds of
7007  * minimizing lock contention.)
7008  *
7009  * A transaction that has not yet set delayChkptFlags when we look cannot
7010  * be at risk, since it has not inserted its commit record yet; and one
7011  * that's already cleared it is not at risk either, since it's done fixing
7012  * clog and we will correctly flush the update below. So we cannot miss
7013  * any xacts we need to wait for.
7014  */
7016  if (nvxids > 0)
7017  {
7018  do
7019  {
7020  pgstat_report_wait_start(WAIT_EVENT_CHECKPOINT_DELAY_START);
7021  pg_usleep(10000L); /* wait for 10 msec */
7023  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids,
7025  }
7026  pfree(vxids);
7027 
7028  CheckPointGuts(checkPoint.redo, flags);
7029 
7031  if (nvxids > 0)
7032  {
7033  do
7034  {
7035  pgstat_report_wait_start(WAIT_EVENT_CHECKPOINT_DELAY_COMPLETE);
7036  pg_usleep(10000L); /* wait for 10 msec */
7038  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids,
7040  }
7041  pfree(vxids);
7042 
7043  /*
7044  * Take a snapshot of running transactions and write this to WAL. This
7045  * allows us to reconstruct the state of running transactions during
7046  * archive recovery, if required. Skip, if this info disabled.
7047  *
7048  * If we are shutting down, or Startup process is completing crash
7049  * recovery we don't need to write running xact data.
7050  */
7051  if (!shutdown && XLogStandbyInfoActive())
7053 
7055 
7056  /*
7057  * Now insert the checkpoint record into XLOG.
7058  */
7059  XLogBeginInsert();
7060  XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));
7061  recptr = XLogInsert(RM_XLOG_ID,
7062  shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
7064 
7065  XLogFlush(recptr);
7066 
7067  /*
7068  * We mustn't write any new WAL after a shutdown checkpoint, or it will be
7069  * overwritten at next startup. No-one should even try, this just allows
7070  * sanity-checking. In the case of an end-of-recovery checkpoint, we want
7071  * to just temporarily disable writing until the system has exited
7072  * recovery.
7073  */
7074  if (shutdown)
7075  {
7076  if (flags & CHECKPOINT_END_OF_RECOVERY)
7077  LocalXLogInsertAllowed = oldXLogAllowed;
7078  else
7079  LocalXLogInsertAllowed = 0; /* never again write WAL */
7080  }
7081 
7082  /*
7083  * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
7084  * = end of actual checkpoint record.
7085  */
7086  if (shutdown && checkPoint.redo != ProcLastRecPtr)
7087  ereport(PANIC,
7088  (errmsg("concurrent write-ahead log activity while database system is shutting down")));
7089 
7090  /*
7091  * Remember the prior checkpoint's redo ptr for
7092  * UpdateCheckPointDistanceEstimate()
7093  */
7094  PriorRedoPtr = ControlFile->checkPointCopy.redo;
7095 
7096  /*
7097  * Update the control file.
7098  */
7099  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7100  if (shutdown)
7103  ControlFile->checkPointCopy = checkPoint;
7104  /* crash recovery should always recover to the end of WAL */
7107 
7108  /*
7109  * Persist unloggedLSN value. It's reset on crash recovery, so this goes
7110  * unused on non-shutdown checkpoints, but seems useful to store it always
7111  * for debugging purposes.
7112  */
7116 
7118  LWLockRelease(ControlFileLock);
7119 
7120  /* Update shared-memory copy of checkpoint XID/epoch */
7122  XLogCtl->ckptFullXid = checkPoint.nextXid;
7124 
7125  /*
7126  * We are now done with critical updates; no need for system panic if we
7127  * have trouble while fooling with old log segments.
7128  */
7129  END_CRIT_SECTION();
7130 
7131  /*
7132  * WAL summaries end when the next XLOG_CHECKPOINT_REDO or
7133  * XLOG_CHECKPOINT_SHUTDOWN record is reached. This is the first point
7134  * where (a) we're not inside of a critical section and (b) we can be
7135  * certain that the relevant record has been flushed to disk, which must
7136  * happen before it can be summarized.
7137  *
7138  * If this is a shutdown checkpoint, then this happens reasonably
7139  * promptly: we've only just inserted and flushed the
7140  * XLOG_CHECKPOINT_SHUTDOWN record. If this is not a shutdown checkpoint,
7141  * then this might not be very prompt at all: the XLOG_CHECKPOINT_REDO
7142  * record was written before we began flushing data to disk, and that
7143  * could be many minutes ago at this point. However, we don't XLogFlush()
7144  * after inserting that record, so we're not guaranteed that it's on disk
7145  * until after the above call that flushes the XLOG_CHECKPOINT_ONLINE
7146  * record.
7147  */
7149 
7150  /*
7151  * Let smgr do post-checkpoint cleanup (eg, deleting old files).
7152  */
7154 
7155  /*
7156  * Update the average distance between checkpoints if the prior checkpoint
7157  * exists.
7158  */
7159  if (PriorRedoPtr != InvalidXLogRecPtr)
7161 
7162  /*
7163  * Delete old log files, those no longer needed for last checkpoint to
7164  * prevent the disk holding the xlog from growing full.
7165  */
7167  KeepLogSeg(recptr, &_logSegNo);
7169  _logSegNo, InvalidOid,
7171  {
7172  /*
7173  * Some slots have been invalidated; recalculate the old-segment
7174  * horizon, starting again from RedoRecPtr.
7175  */
7177  KeepLogSeg(recptr, &_logSegNo);
7178  }
7179  _logSegNo--;
7180  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr,
7181  checkPoint.ThisTimeLineID);
7182 
7183  /*
7184  * Make more log segments if needed. (Do this after recycling old log
7185  * segments, since that may supply some of the needed files.)
7186  */
7187  if (!shutdown)
7188  PreallocXlogFiles(recptr, checkPoint.ThisTimeLineID);
7189 
7190  /*
7191  * Truncate pg_subtrans if possible. We can throw away all data before
7192  * the oldest XMIN of any running transaction. No future transaction will
7193  * attempt to reference any pg_subtrans entry older than that (see Asserts
7194  * in subtrans.c). During recovery, though, we mustn't do this because
7195  * StartupSUBTRANS hasn't been called yet.
7196  */
7197  if (!RecoveryInProgress())
7199 
7200  /* Real work is done; log and update stats. */
7201  LogCheckpointEnd(false);
7202 
7203  /* Reset the process title */
7204  update_checkpoint_display(flags, false, true);
7205 
7206  TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
7207  NBuffers,
7211 }
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1162
int NBuffers
Definition: globals.c:139
@ LW_SHARED
Definition: lwlock.h:117
#define START_CRIT_SECTION()
Definition: miscadmin.h:149
#define END_CRIT_SECTION()
Definition: miscadmin.h:151
void MultiXactGetCheckptMulti(bool is_shutdown, MultiXactId *nextMulti, MultiXactOffset *nextMultiOffset, MultiXactId *oldestMulti, Oid *oldestMultiDB)
Definition: multixact.c:2140
#define XLOG_CHECKPOINT_REDO
Definition: pg_control.h:81
@ DB_SHUTDOWNING
Definition: pg_control.h:93
@ DB_SHUTDOWNED
Definition: pg_control.h:91
#define XLOG_CHECKPOINT_ONLINE
Definition: pg_control.h:68
#define InvalidOid
Definition: postgres_ext.h:36
#define DELAY_CHKPT_START
Definition: proc.h:119
#define DELAY_CHKPT_COMPLETE
Definition: proc.h:120
VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
Definition: procarray.c:3015
TransactionId GetOldestActiveTransactionId(void)
Definition: procarray.c:2852
TransactionId GetOldestTransactionIdConsideredRunning(void)
Definition: procarray.c:2023
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)
Definition: procarray.c:3061
void pg_usleep(long microsec)
Definition: signal.c:53
bool InvalidateObsoleteReplicationSlots(ReplicationSlotInvalidationCause cause, XLogSegNo oldestSegno, Oid dboid, TransactionId snapshotConflictHorizon)
Definition: slot.c:1723
@ RS_INVAL_WAL_REMOVED
Definition: slot.h:51
XLogRecPtr LogStandbySnapshot(void)
Definition: standby.c:1286
TimestampTz ckpt_start_t
Definition: xlog.h:159
int ckpt_segs_removed
Definition: xlog.h:168
int ckpt_segs_added
Definition: xlog.h:167
int ckpt_bufs_written
Definition: xlog.h:165
int ckpt_segs_recycled
Definition: xlog.h:169
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:167
XLogRecPtr unloggedLSN
Definition: pg_control.h:136
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:168
TransactionId oldestCommitTsXid
Definition: transam.h:232
TransactionId newestCommitTsXid
Definition: transam.h:233
TransactionId oldestXid
Definition: transam.h:222
FullTransactionId ckptFullXid
Definition: xlog.c:467
TimeLineID InsertTimeLineID
Definition: xlog.c:516
slock_t ulsn_lck
Definition: xlog.c:475
XLogRecPtr RedoRecPtr
Definition: xlog.c:466
XLogRecPtr unloggedLSN
Definition: xlog.c:474
TimeLineID PrevTimeLineID
Definition: xlog.c:517
XLogRecPtr RedoRecPtr
Definition: xlog.c:440
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:348
void SyncPreCheckpoint(void)
Definition: sync.c:182
void SyncPostCheckpoint(void)
Definition: sync.c:207
void SetWalSummarizerLatch(void)
XLogRecPtr ProcLastRecPtr
Definition: xlog.c:257
bool RecoveryInProgress(void)
Definition: xlog.c:6211
static void WALInsertLockRelease(void)
Definition: xlog.c:1438
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1822
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1409
static void UpdateControlFile(void)
Definition: xlog.c:4454
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr, TimeLineID insertTLI)
Definition: xlog.c:3800
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:6509
static XLogRecPtr RedoRecPtr
Definition: xlog.c:277
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:6541
static void PreallocXlogFiles(XLogRecPtr endptr, TimeLineID tli)
Definition: xlog.c:3625
bool log_checkpoints
Definition: xlog.c:133
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:7793
static int LocalSetXLogInsertAllowed(void)
Definition: xlog.c:6299
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:6416
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:6644
static int LocalXLogInsertAllowed
Definition: xlog.c:240
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2733
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:7356
static void update_checkpoint_display(int flags, bool restartpoint, bool reset)
Definition: xlog.c:6682
#define CHECKPOINT_END_OF_RECOVERY
Definition: xlog.h:138
#define CHECKPOINT_FORCE
Definition: xlog.h:140
#define XLogStandbyInfoActive()
Definition: xlog.h:121
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)
void XLogRegisterData(char *data, uint32 len)
Definition: xloginsert.c:365
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:475
void XLogBeginInsert(void)
Definition: xloginsert.c:150

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

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

◆ CreateEndOfRecoveryRecord()

static void CreateEndOfRecoveryRecord ( void  )
static

Definition at line 7222 of file xlog.c.

7223 {
7224  xl_end_of_recovery xlrec;
7225  XLogRecPtr recptr;
7226 
7227  /* sanity check */
7228  if (!RecoveryInProgress())
7229  elog(ERROR, "can only be used to end recovery");
7230 
7231  xlrec.end_time = GetCurrentTimestamp();
7232 
7237 
7239 
7240  XLogBeginInsert();
7241  XLogRegisterData((char *) &xlrec, sizeof(xl_end_of_recovery));
7242  recptr = XLogInsert(RM_XLOG_ID, XLOG_END_OF_RECOVERY);
7243 
7244  XLogFlush(recptr);
7245 
7246  /*
7247  * Update the control file so that crash recovery can follow the timeline
7248  * changes to this point.
7249  */
7250  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7251  ControlFile->minRecoveryPoint = recptr;
7252  ControlFile->minRecoveryPointTLI = xlrec.ThisTimeLineID;
7254  LWLockRelease(ControlFileLock);
7255 
7256  END_CRIT_SECTION();
7257 }
#define XLOG_END_OF_RECOVERY
Definition: pg_control.h:76
TimeLineID PrevTimeLineID
TimestampTz end_time
TimeLineID ThisTimeLineID

References ControlFile, elog(), END_CRIT_SECTION, xl_end_of_recovery::end_time, ERROR, GetCurrentTimestamp(), XLogCtlData::InsertTimeLineID, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, XLogCtlData::PrevTimeLineID, xl_end_of_recovery::PrevTimeLineID, RecoveryInProgress(), START_CRIT_SECTION, xl_end_of_recovery::ThisTimeLineID, UpdateControlFile(), WALInsertLockAcquireExclusive(), WALInsertLockRelease(), XLOG_END_OF_RECOVERY, XLogBeginInsert(), XLogCtl, XLogFlush(), XLogInsert(), and XLogRegisterData().

Referenced by PerformRecoveryXLogAction().

◆ CreateOverwriteContrecordRecord()

static XLogRecPtr CreateOverwriteContrecordRecord ( XLogRecPtr  aborted_lsn,
XLogRecPtr  pagePtr,
TimeLineID  newTLI 
)
static

Definition at line 7286 of file xlog.c.

7288 {
7290  XLogRecPtr recptr;
7291  XLogPageHeader pagehdr;
7292  XLogRecPtr startPos;
7293 
7294  /* sanity checks */
7295  if (!RecoveryInProgress())
7296  elog(ERROR, "can only be used at end of recovery");
7297  if (pagePtr % XLOG_BLCKSZ != 0)
7298  elog(ERROR, "invalid position for missing continuation record %X/%X",
7299  LSN_FORMAT_ARGS(pagePtr));
7300 
7301  /* The current WAL insert position should be right after the page header */
7302  startPos = pagePtr;
7303  if (XLogSegmentOffset(startPos, wal_segment_size) == 0)
7304  startPos += SizeOfXLogLongPHD;
7305  else
7306  startPos += SizeOfXLogShortPHD;
7307  recptr = GetXLogInsertRecPtr();
7308  if (recptr != startPos)
7309  elog(ERROR, "invalid WAL insert position %X/%X for OVERWRITE_CONTRECORD",
7310  LSN_FORMAT_ARGS(recptr));
7311 
7313 
7314  /*
7315  * Initialize the XLOG page header (by GetXLogBuffer), and set the
7316  * XLP_FIRST_IS_OVERWRITE_CONTRECORD flag.
7317  *
7318  * No other backend is allowed to write WAL yet, so acquiring the WAL
7319  * insertion lock is just pro forma.
7320  */
7322  pagehdr = (XLogPageHeader) GetXLogBuffer(pagePtr, newTLI);
7325 
7326  /*
7327  * Insert the XLOG_OVERWRITE_CONTRECORD record as the first record on the
7328  * page. We know it becomes the first record, because no other backend is
7329  * allowed to write WAL yet.
7330  */
7331  XLogBeginInsert();
7332  xlrec.overwritten_lsn = aborted_lsn;
7334  XLogRegisterData((char *) &xlrec, sizeof(xl_overwrite_contrecord));
7335  recptr = XLogInsert(RM_XLOG_ID, XLOG_OVERWRITE_CONTRECORD);
7336 
7337  /* check that the record was inserted to the right place */
7338  if (ProcLastRecPtr != startPos)
7339  elog(ERROR, "OVERWRITE_CONTRECORD was inserted to unexpected position %X/%X",
7341 
7342  XLogFlush(recptr);
7343 
7344  END_CRIT_SECTION();
7345 
7346  return recptr;
7347 }
#define XLOG_OVERWRITE_CONTRECORD
Definition: pg_control.h:80
static void WALInsertLockAcquire(void)
Definition: xlog.c:1364
XLogRecPtr GetXLogInsertRecPtr(void)
Definition: xlog.c:9272
#define XLP_FIRST_IS_OVERWRITE_CONTRECORD
Definition: xlog_internal.h:80

References elog(), END_CRIT_SECTION, ERROR, GetCurrentTimestamp(), GetXLogBuffer(), GetXLogInsertRecPtr(), LSN_FORMAT_ARGS, xl_overwrite_contrecord::overwrite_time, xl_overwrite_contrecord::overwritten_lsn, ProcLastRecPtr, RecoveryInProgress(), SizeOfXLogLongPHD, SizeOfXLogShortPHD, START_CRIT_SECTION, wal_segment_size, WALInsertLockAcquire(), WALInsertLockRelease(), XLOG_OVERWRITE_CONTRECORD, XLogBeginInsert(), XLogFlush(), XLogInsert(), XLogRegisterData(), XLogSegmentOffset, XLP_FIRST_IS_OVERWRITE_CONTRECORD, and XLogPageHeaderData::xlp_info.

Referenced by StartupXLOG().

◆ CreateRestartPoint()

bool CreateRestartPoint ( int  flags)

Definition at line 7437 of file xlog.c.

7438 {
7439  XLogRecPtr lastCheckPointRecPtr;
7440  XLogRecPtr lastCheckPointEndPtr;
7441  CheckPoint lastCheckPoint;
7442  XLogRecPtr PriorRedoPtr;
7443  XLogRecPtr receivePtr;
7444  XLogRecPtr replayPtr;
7445  TimeLineID replayTLI;
7446  XLogRecPtr endptr;
7447  XLogSegNo _logSegNo;
7448  TimestampTz xtime;
7449 
7450  /* Concurrent checkpoint/restartpoint cannot happen */
7452 
7453  /* Get a local copy of the last safe checkpoint record. */
7455  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
7456  lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
7457  lastCheckPoint = XLogCtl->lastCheckPoint;
7459 
7460  /*
7461  * Check that we're still in recovery mode. It's ok if we exit recovery
7462  * mode after this check, the restart point is valid anyway.
7463  */
7464  if (!RecoveryInProgress())
7465  {
7466  ereport(DEBUG2,
7467  (errmsg_internal("skipping restartpoint, recovery has already ended")));
7468  return false;
7469  }
7470 
7471  /*
7472  * If the last checkpoint record we've replayed is already our last
7473  * restartpoint, we can't perform a new restart point. We still update
7474  * minRecoveryPoint in that case, so that if this is a shutdown restart
7475  * point, we won't start up earlier than before. That's not strictly
7476  * necessary, but when hot standby is enabled, it would be rather weird if
7477  * the database opened up for read-only connections at a point-in-time
7478  * before the last shutdown. Such time travel is still possible in case of
7479  * immediate shutdown, though.
7480  *
7481  * We don't explicitly advance minRecoveryPoint when we do create a
7482  * restartpoint. It's assumed that flushing the buffers will do that as a
7483  * side-effect.
7484  */
7485  if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
7486  lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
7487  {
7488  ereport(DEBUG2,
7489  (errmsg_internal("skipping restartpoint, already performed at %X/%X",
7490  LSN_FORMAT_ARGS(lastCheckPoint.redo))));
7491 
7493  if (flags & CHECKPOINT_IS_SHUTDOWN)
7494  {
7495  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7498  LWLockRelease(ControlFileLock);
7499  }
7500  return false;
7501  }
7502 
7503  /*
7504  * Update the shared RedoRecPtr so that the startup process can calculate
7505  * the number of segments replayed since last restartpoint, and request a
7506  * restartpoint if it exceeds CheckPointSegments.
7507  *
7508  * Like in CreateCheckPoint(), hold off insertions to update it, although
7509  * during recovery this is just pro forma, because no WAL insertions are
7510  * happening.
7511  */
7513  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
7515 
7516  /* Also update the info_lck-protected copy */
7518  XLogCtl->RedoRecPtr = lastCheckPoint.redo;
7520 
7521  /*
7522  * Prepare to accumulate statistics.
7523  *
7524  * Note: because it is possible for log_checkpoints to change while a
7525  * checkpoint proceeds, we always accumulate stats, even if
7526  * log_checkpoints is currently off.
7527  */
7528  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
7530 
7531  if (log_checkpoints)
7532  LogCheckpointStart(flags, true);
7533 
7534  /* Update the process title */
7535  update_checkpoint_display(flags, true, false);
7536 
7537  CheckPointGuts(lastCheckPoint.redo, flags);
7538 
7539  /*
7540  * Remember the prior checkpoint's redo ptr for
7541  * UpdateCheckPointDistanceEstimate()
7542  */
7543  PriorRedoPtr = ControlFile->checkPointCopy.redo;
7544 
7545  /*
7546  * Update pg_control, using current time. Check that it still shows an
7547  * older checkpoint, else do nothing; this is a quick hack to make sure
7548  * nothing really bad happens if somehow we get here after the
7549  * end-of-recovery checkpoint.
7550  */
7551  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7552  if (ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
7553  {
7554  /*
7555  * Update the checkpoint information. We do this even if the cluster
7556  * does not show DB_IN_ARCHIVE_RECOVERY to match with the set of WAL
7557  * segments recycled below.
7558  */
7559  ControlFile->checkPoint = lastCheckPointRecPtr;
7560  ControlFile->checkPointCopy = lastCheckPoint;
7561 
7562  /*
7563  * Ensure minRecoveryPoint is past the checkpoint record and update it
7564  * if the control file still shows DB_IN_ARCHIVE_RECOVERY. Normally,
7565  * this will have happened already while writing out dirty buffers,
7566  * but not necessarily - e.g. because no buffers were dirtied. We do
7567  * this because a backup performed in recovery uses minRecoveryPoint
7568  * to determine which WAL files must be included in the backup, and
7569  * the file (or files) containing the checkpoint record must be
7570  * included, at a minimum. Note that for an ordinary restart of
7571  * recovery there's no value in having the minimum recovery point any
7572  * earlier than this anyway, because redo will begin just after the
7573  * checkpoint record.
7574  */
7576  {
7577  if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
7578  {
7579  ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
7581 
7582  /* update local copy */
7585  }
7586  if (flags & CHECKPOINT_IS_SHUTDOWN)
7588  }
7590  }
7591  LWLockRelease(ControlFileLock);
7592 
7593  /*
7594  * Update the average distance between checkpoints/restartpoints if the
7595  * prior checkpoint exists.
7596  */
7597  if (PriorRedoPtr != InvalidXLogRecPtr)
7599 
7600  /*
7601  * Delete old log files, those no longer needed for last restartpoint to
7602  * prevent the disk holding the xlog from growing full.
7603  */
7605 
7606  /*
7607  * Retreat _logSegNo using the current end of xlog replayed or received,
7608  * whichever is later.
7609  */
7610  receivePtr = GetWalRcvFlushRecPtr(NULL, NULL);
7611  replayPtr = GetXLogReplayRecPtr(&replayTLI);
7612  endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
7613  KeepLogSeg(endptr, &_logSegNo);
7615  _logSegNo, InvalidOid,
7617  {
7618  /*
7619  * Some slots have been invalidated; recalculate the old-segment
7620  * horizon, starting again from RedoRecPtr.
7621  */
7623  KeepLogSeg(endptr, &_logSegNo);
7624  }
7625  _logSegNo--;
7626 
7627  /*
7628  * Try to recycle segments on a useful timeline. If we've been promoted
7629  * since the beginning of this restartpoint, use the new timeline chosen
7630  * at end of recovery. If we're still in recovery, use the timeline we're
7631  * currently replaying.
7632  *
7633  * There is no guarantee that the WAL segments will be useful on the
7634  * current timeline; if recovery proceeds to a new timeline right after
7635  * this, the pre-allocated WAL segments on this timeline will not be used,
7636  * and will go wasted until recycled on the next restartpoint. We'll live
7637  * with that.
7638  */
7639  if (!RecoveryInProgress())
7640  replayTLI = XLogCtl->InsertTimeLineID;
7641 
7642  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr, replayTLI);
7643 
7644  /*
7645  * Make more log segments if needed. (Do this after recycling old log
7646  * segments, since that may supply some of the needed files.)
7647  */
7648  PreallocXlogFiles(endptr, replayTLI);
7649 
7650  /*
7651  * Truncate pg_subtrans if possible. We can throw away all data before
7652  * the oldest XMIN of any running transaction. No future transaction will
7653  * attempt to reference any pg_subtrans entry older than that (see Asserts
7654  * in subtrans.c). When hot standby is disabled, though, we mustn't do
7655  * this because StartupSUBTRANS hasn't been called yet.
7656  */
7657  if (EnableHotStandby)
7659 
7660  /* Real work is done; log and update stats. */
7661  LogCheckpointEnd(true);
7662 
7663  /* Reset the process title */
7664  update_checkpoint_display(flags, true, true);
7665 
7666  xtime = GetLatestXTime();
7668  (errmsg("recovery restart point at %X/%X",
7669  LSN_FORMAT_ARGS(lastCheckPoint.redo)),
7670  xtime ? errdetail("Last completed transaction was at log time %s.",
7671  timestamptz_to_str(xtime)) : 0));
7672 
7673  /*
7674  * Finally, execute archive_cleanup_command, if any.
7675  */
7676  if (archiveCleanupCommand && strcmp(archiveCleanupCommand, "") != 0)
7678  "archive_cleanup_command",
7679  false,
7680  WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND);
7681 
7682  return true;
7683 }
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1854
int64 TimestampTz
Definition: timestamp.h:39
#define LOG
Definition: elog.h:31
bool IsUnderPostmaster
Definition: globals.c:116
@ B_CHECKPOINTER
Definition: miscadmin.h:334
BackendType MyBackendType
Definition: miscinit.c:64
@ DB_IN_ARCHIVE_RECOVERY
Definition: pg_control.h:95
@ DB_SHUTDOWNED_IN_RECOVERY
Definition: pg_control.h:92
CheckPoint lastCheckPoint
Definition: xlog.c:552
XLogRecPtr lastCheckPointRecPtr
Definition: xlog.c:550
XLogRecPtr lastCheckPointEndPtr
Definition: xlog.c:551
XLogRecPtr GetWalRcvFlushRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI)
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition: xlog.c:2653
static XLogRecPtr LocalMinRecoveryPoint
Definition: xlog.c:640
static TimeLineID LocalMinRecoveryPointTLI
Definition: xlog.c:641
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
uint32 TimeLineID
Definition: xlogdefs.h:59
char * archiveCleanupCommand
Definition: xlogrecovery.c:85
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
TimestampTz GetLatestXTime(void)

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

Referenced by CheckpointerMain(), and ShutdownXLOG().

◆ DataChecksumsEnabled()

◆ do_pg_abort_backup()

void do_pg_abort_backup ( int  code,
Datum  arg 
)

Definition at line 9231 of file xlog.c.

9232 {
9233  bool during_backup_start = DatumGetBool(arg);
9234 
9235  /* If called during backup start, there shouldn't be one already running */
9236  Assert(!during_backup_start || sessionBackupState == SESSION_BACKUP_NONE);
9237 
9238  if (during_backup_start || sessionBackupState != SESSION_BACKUP_NONE)
9239  {
9243 
9246 
9247  if (!during_backup_start)
9248  ereport(WARNING,
9249  errmsg("aborting backup due to backend exiting before pg_backup_stop was called"));
9250  }
9251 }
#define WARNING
Definition: elog.h:36
void * arg
static bool DatumGetBool(Datum X)
Definition: postgres.h:90
int runningBackups
Definition: xlog.c:448
static SessionBackupState sessionBackupState
Definition: xlog.c:401
@ SESSION_BACKUP_NONE
Definition: xlog.h:283

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

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

◆ do_pg_backup_start()

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

Definition at line 8629 of file xlog.c.

8631 {
8633 
8634  Assert(state != NULL);
8636 
8637  /*
8638  * During recovery, we don't need to check WAL level. Because, if WAL
8639  * level is not sufficient, it's impossible to get here during recovery.
8640  */
8642  ereport(ERROR,
8643  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8644  errmsg("WAL level not sufficient for making an online backup"),
8645  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
8646 
8647  if (strlen(backupidstr) > MAXPGPATH)
8648  ereport(ERROR,
8649  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8650  errmsg("backup label too long (max %d bytes)",
8651  MAXPGPATH)));
8652 
8653  memcpy(state->name, backupidstr, strlen(backupidstr));
8654 
8655  /*
8656  * Mark backup active in shared memory. We must do full-page WAL writes
8657  * during an on-line backup even if not doing so at other times, because
8658  * it's quite possible for the backup dump to obtain a "torn" (partially
8659  * written) copy of a database page if it reads the page concurrently with
8660  * our write to the same page. This can be fixed as long as the first
8661  * write to the page in the WAL sequence is a full-page write. Hence, we
8662  * increment runningBackups then force a CHECKPOINT, to ensure there are
8663  * no dirty pages in shared memory that might get dumped while the backup
8664  * is in progress without having a corresponding WAL record. (Once the
8665  * backup is complete, we need not force full-page writes anymore, since
8666  * we expect that any pages not modified during the backup interval must
8667  * have been correctly captured by the backup.)
8668  *
8669  * Note that forcing full-page writes has no effect during an online
8670  * backup from the standby.
8671  *
8672  * We must hold all the insertion locks to change the value of
8673  * runningBackups, to ensure adequate interlocking against
8674  * XLogInsertRecord().
8675  */
8679 
8680  /*
8681  * Ensure we decrement runningBackups if we fail below. NB -- for this to
8682  * work correctly, it is critical that sessionBackupState is only updated
8683  * after this block is over.
8684  */
8686  {
8687  bool gotUniqueStartpoint = false;
8688  DIR *tblspcdir;
8689  struct dirent *de;
8690  tablespaceinfo *ti;
8691  int datadirpathlen;
8692 
8693  /*
8694  * Force an XLOG file switch before the checkpoint, to ensure that the
8695  * WAL segment the checkpoint is written to doesn't contain pages with
8696  * old timeline IDs. That would otherwise happen if you called
8697  * pg_backup_start() right after restoring from a PITR archive: the
8698  * first WAL segment containing the startup checkpoint has pages in
8699  * the beginning with the old timeline ID. That can cause trouble at
8700  * recovery: we won't have a history file covering the old timeline if
8701  * pg_wal directory was not included in the base backup and the WAL
8702  * archive was cleared too before starting the backup.
8703  *
8704  * This also ensures that we have emitted a WAL page header that has
8705  * XLP_BKP_REMOVABLE off before we emit the checkpoint record.
8706  * Therefore, if a WAL archiver (such as pglesslog) is trying to
8707  * compress out removable backup blocks, it won't remove any that
8708  * occur after this point.
8709  *
8710  * During recovery, we skip forcing XLOG file switch, which means that
8711  * the backup taken during recovery is not available for the special
8712  * recovery case described above.
8713  */
8715  RequestXLogSwitch(false);
8716 
8717  do
8718  {
8719  bool checkpointfpw;
8720 
8721  /*
8722  * Force a CHECKPOINT. Aside from being necessary to prevent torn
8723  * page problems, this guarantees that two successive backup runs
8724  * will have different checkpoint positions and hence different
8725  * history file names, even if nothing happened in between.
8726  *
8727  * During recovery, establish a restartpoint if possible. We use
8728  * the last restartpoint as the backup starting checkpoint. This
8729  * means that two successive backup runs can have same checkpoint
8730  * positions.
8731  *
8732  * Since the fact that we are executing do_pg_backup_start()
8733  * during recovery means that checkpointer is running, we can use
8734  * RequestCheckpoint() to establish a restartpoint.
8735  *
8736  * We use CHECKPOINT_IMMEDIATE only if requested by user (via
8737  * passing fast = true). Otherwise this can take awhile.
8738  */
8740  (fast ? CHECKPOINT_IMMEDIATE : 0));
8741 
8742  /*
8743  * Now we need to fetch the checkpoint record location, and also
8744  * its REDO pointer. The oldest point in WAL that would be needed
8745  * to restore starting from the checkpoint is precisely the REDO
8746  * pointer.
8747  */
8748  LWLockAcquire(ControlFileLock, LW_SHARED);
8749  state->checkpointloc = ControlFile->checkPoint;
8750  state->startpoint = ControlFile->checkPointCopy.redo;
8752  checkpointfpw = ControlFile->checkPointCopy.fullPageWrites;
8753  LWLockRelease(ControlFileLock);
8754 
8756  {
8757  XLogRecPtr recptr;
8758 
8759  /*
8760  * Check to see if all WAL replayed during online backup
8761  * (i.e., since last restartpoint used as backup starting
8762  * checkpoint) contain full-page writes.
8763  */
8765  recptr = XLogCtl->lastFpwDisableRecPtr;
8767 
8768  if (!checkpointfpw || state->startpoint <= recptr)
8769  ereport(ERROR,
8770  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8771  errmsg("WAL generated with full_page_writes=off was replayed "
8772  "since last restartpoint"),
8773  errhint("This means that the backup being taken on the standby "
8774  "is corrupt and should not be used. "
8775  "Enable full_page_writes and run CHECKPOINT on the primary, "
8776  "and then try an online backup again.")));
8777 
8778  /*
8779  * During recovery, since we don't use the end-of-backup WAL
8780  * record and don't write the backup history file, the
8781  * starting WAL location doesn't need to be unique. This means
8782  * that two base backups started at the same time might use
8783  * the same checkpoint as starting locations.
8784  */
8785  gotUniqueStartpoint = true;
8786  }
8787 
8788  /*
8789  * If two base backups are started at the same time (in WAL sender
8790  * processes), we need to make sure that they use different
8791  * checkpoints as starting locations, because we use the starting
8792  * WAL location as a unique identifier for the base backup in the
8793  * end-of-backup WAL record and when we write the backup history
8794  * file. Perhaps it would be better generate a separate unique ID
8795  * for each backup instead of forcing another checkpoint, but
8796  * taking a checkpoint right after another is not that expensive
8797  * either because only few buffers have been dirtied yet.
8798  */
8800  if (XLogCtl->Insert.lastBackupStart < state->startpoint)
8801  {
8802  XLogCtl->Insert.lastBackupStart = state->startpoint;
8803  gotUniqueStartpoint = true;
8804  }
8806  } while (!gotUniqueStartpoint);
8807 
8808  /*
8809  * Construct tablespace_map file.
8810  */
8811  datadirpathlen = strlen(DataDir);
8812 
8813  /* Collect information about all tablespaces */
8814  tblspcdir = AllocateDir("pg_tblspc");
8815  while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL)
8816  {
8817  char fullpath[MAXPGPATH + 10];
8818  char linkpath[MAXPGPATH];
8819  char *relpath = NULL;
8820  char *s;
8821  PGFileType de_type;
8822  char *badp;
8823  Oid tsoid;
8824 
8825  /*
8826  * Try to parse the directory name as an unsigned integer.
8827  *
8828  * Tablespace directories should be positive integers that can be
8829  * represented in 32 bits, with no leading zeroes or trailing
8830  * garbage. If we come across a name that doesn't meet those
8831  * criteria, skip it.
8832  */
8833  if (de->d_name[0] < '1' || de->d_name[1] > '9')
8834  continue;
8835  errno = 0;
8836  tsoid = strtoul(de->d_name, &badp, 10);
8837  if (*badp != '\0' || errno == EINVAL || errno == ERANGE)
8838  continue;
8839 
8840  snprintf(fullpath, sizeof(fullpath), "pg_tblspc/%s", de->d_name);
8841 
8842  de_type = get_dirent_type(fullpath, de, false, ERROR);
8843 
8844  if (de_type == PGFILETYPE_LNK)
8845  {
8846  StringInfoData escapedpath;
8847  int rllen;
8848 
8849  rllen = readlink(fullpath, linkpath, sizeof(linkpath));
8850  if (rllen < 0)
8851  {
8852  ereport(WARNING,
8853  (errmsg("could not read symbolic link \"%s\": %m",
8854  fullpath)));
8855  continue;
8856  }
8857  else if (rllen >= sizeof(linkpath))
8858  {
8859  ereport(WARNING,
8860  (errmsg("symbolic link \"%s\" target is too long",
8861  fullpath)));
8862  continue;
8863  }
8864  linkpath[rllen] = '\0';
8865 
8866  /*
8867  * Relpath holds the relative path of the tablespace directory
8868  * when it's located within PGDATA, or NULL if it's located
8869  * elsewhere.
8870  */
8871  if (rllen > datadirpathlen &&
8872  strncmp(linkpath, DataDir, datadirpathlen) == 0 &&
8873  IS_DIR_SEP(linkpath[datadirpathlen]))
8874  relpath = pstrdup(linkpath + datadirpathlen + 1);
8875 
8876  /*
8877  * Add a backslash-escaped version of the link path to the
8878  * tablespace map file.
8879  */
8880  initStringInfo(&escapedpath);
8881  for (s = linkpath; *s; s++)
8882  {
8883  if (*s == '\n' || *s == '\r' || *s == '\\')
8884  appendStringInfoChar(&escapedpath, '\\');
8885  appendStringInfoChar(&escapedpath, *s);
8886  }
8887  appendStringInfo(tblspcmapfile, "%s %s\n",
8888  de->d_name, escapedpath.data);
8889  pfree(escapedpath.data);
8890  }
8891  else if (de_type == PGFILETYPE_DIR)
8892  {
8893  /*
8894  * It's possible to use allow_in_place_tablespaces to create
8895  * directories directly under pg_tblspc, for testing purposes
8896  * only.
8897  *
8898  * In this case, we store a relative path rather than an
8899  * absolute path into the tablespaceinfo.
8900  */
8901  snprintf(linkpath, sizeof(linkpath), "pg_tblspc/%s",
8902  de->d_name);
8903  relpath = pstrdup(linkpath);
8904  }
8905  else
8906  {
8907  /* Skip any other file type that appears here. */
8908  continue;
8909  }
8910 
8911  ti = palloc(sizeof(tablespaceinfo));
8912  ti->oid = tsoid;
8913  ti->path = pstrdup(linkpath);
8914  ti->rpath = relpath;
8915  ti->size = -1;
8916 
8917  if (tablespaces)
8918  *tablespaces = lappend(*tablespaces, ti);
8919  }
8920  FreeDir(tblspcdir);
8921 
8922  state->starttime = (pg_time_t) time(NULL);
8923  }
8925 
8926  state->started_in_recovery = backup_started_in_recovery;
8927 
8928  /*
8929  * Mark that the start phase has correctly finished for the backup.
8930  */
8932 }
static bool backup_started_in_recovery
Definition: basebackup.c:124
void RequestCheckpoint(int flags)
Definition: checkpointer.c:935
int errcode(int sqlerrcode)
Definition: elog.c:860
PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
Definition: file_utils.c:525
PGFileType
Definition: file_utils.h:19
@ PGFILETYPE_LNK
Definition: file_utils.h:24
@ PGFILETYPE_DIR
Definition: file_utils.h:23
char * DataDir
Definition: globals.c:67
#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
#define IS_DIR_SEP(ch)
Definition: port.h:102
unsigned int Oid
Definition: postgres_ext.h:31
#define relpath(rlocator, forknum)
Definition: relpath.h:94
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:194
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:558
XLogRecPtr lastBackupStart
Definition: xlog.c:449
Definition: regguts.h:323
char * rpath
Definition: basebackup.h:32
#define readlink(path, buf, size)
Definition: win32_port.h:236
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:7900
void do_pg_abort_backup(int code, Datum arg)
Definition: xlog.c:9231
@ SESSION_BACKUP_RUNNING
Definition: xlog.h:284
#define CHECKPOINT_WAIT
Definition: xlog.h:143
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:139
#define XLogIsNeeded()
Definition: xlog.h:107

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

Referenced by perform_base_backup(), and pg_backup_start().

◆ do_pg_backup_stop()

void do_pg_backup_stop ( BackupState state,
bool  waitforarchive 
)

Definition at line 8957 of file xlog.c.

8958 {
8959  bool backup_stopped_in_recovery = false;
8960  char histfilepath[MAXPGPATH];
8961  char lastxlogfilename[MAXFNAMELEN];
8962  char histfilename[MAXFNAMELEN];
8963  XLogSegNo _logSegNo;
8964  FILE *fp;
8965  int seconds_before_warning;
8966  int waits = 0;
8967  bool reported_waiting = false;
8968 
8969  Assert(state != NULL);
8970 
8971  backup_stopped_in_recovery = RecoveryInProgress();
8972 
8973  /*
8974  * During recovery, we don't need to check WAL level. Because, if WAL
8975  * level is not sufficient, it's impossible to get here during recovery.
8976  */
8977  if (!backup_stopped_in_recovery && !XLogIsNeeded())
8978  ereport(ERROR,
8979  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8980  errmsg("WAL level not sufficient for making an online backup"),
8981  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
8982 
8983  /*
8984  * OK to update backup counter and session-level lock.
8985  *
8986  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating them,
8987  * otherwise they can be updated inconsistently, which might cause
8988  * do_pg_abort_backup() to fail.
8989  */
8991 
8992  /*
8993  * It is expected that each do_pg_backup_start() call is matched by
8994  * exactly one do_pg_backup_stop() call.
8995  */
8998 
8999  /*
9000  * Clean up session-level lock.
9001  *
9002  * You might think that WALInsertLockRelease() can be called before
9003  * cleaning up session-level lock because session-level lock doesn't need
9004  * to be protected with WAL insertion lock. But since
9005  * CHECK_FOR_INTERRUPTS() can occur in it, session-level lock must be
9006  * cleaned up before it.
9007  */
9009 
9011 
9012  /*
9013  * If we are taking an online backup from the standby, we confirm that the
9014  * standby has not been promoted during the backup.
9015  */
9016  if (state->started_in_recovery && !backup_stopped_in_recovery)
9017  ereport(ERROR,
9018  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
9019  errmsg("the standby was promoted during online backup"),
9020  errhint("This means that the backup being taken is corrupt "
9021  "and should not be used. "
9022  "Try taking another online backup.")));
9023 
9024  /*
9025  * During recovery, we don't write an end-of-backup record. We assume that
9026  * pg_control was backed up last and its minimum recovery point can be
9027  * available as the backup end location. Since we don't have an
9028  * end-of-backup record, we use the pg_control value to check whether
9029  * we've reached the end of backup when starting recovery from this
9030  * backup. We have no way of checking if pg_control wasn't backed up last
9031  * however.
9032  *
9033  * We don't force a switch to new WAL file but it is still possible to
9034  * wait for all the required files to be archived if waitforarchive is
9035  * true. This is okay if we use the backup to start a standby and fetch
9036  * the missing WAL using streaming replication. But in the case of an
9037  * archive recovery, a user should set waitforarchive to true and wait for
9038  * them to be archived to ensure that all the required files are
9039  * available.
9040  *
9041  * We return the current minimum recovery point as the backup end
9042  * location. Note that it can be greater than the exact backup end
9043  * location if the minimum recovery point is updated after the backup of
9044  * pg_control. This is harmless for current uses.
9045  *
9046  * XXX currently a backup history file is for informational and debug
9047  * purposes only. It's not essential for an online backup. Furthermore,
9048  * even if it's created, it will not be archived during recovery because
9049  * an archiver is not invoked. So it doesn't seem worthwhile to write a
9050  * backup history file during recovery.
9051  */
9052  if (backup_stopped_in_recovery)
9053  {
9054  XLogRecPtr recptr;
9055 
9056  /*
9057  * Check to see if all WAL replayed during online backup contain
9058  * full-page writes.
9059  */
9061  recptr = XLogCtl->lastFpwDisableRecPtr;
9063 
9064  if (state->startpoint <= recptr)
9065  ereport(ERROR,
9066  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
9067  errmsg("WAL generated with full_page_writes=off was replayed "
9068  "during online backup"),
9069  errhint("This means that the backup being taken on the standby "
9070  "is corrupt and should not be used. "
9071  "Enable full_page_writes and run CHECKPOINT on the primary, "
9072  "and then try an online backup again.")));
9073 
9074 
9075  LWLockAcquire(ControlFileLock, LW_SHARED);
9076  state->stoppoint = ControlFile->minRecoveryPoint;
9078  LWLockRelease(ControlFileLock);
9079  }
9080  else
9081  {
9082  char *history_file;
9083 
9084  /*
9085  * Write the backup-end xlog record
9086  */
9087  XLogBeginInsert();
9088  XLogRegisterData((char *) (&state->startpoint),
9089  sizeof(state->startpoint));
9090  state->stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
9091 
9092  /*
9093  * Given that we're not in recovery, InsertTimeLineID is set and can't
9094  * change, so we can read it without a lock.
9095  */
9096  state->stoptli = XLogCtl->InsertTimeLineID;
9097 
9098  /*
9099  * Force a switch to a new xlog segment file, so that the backup is
9100  * valid as soon as archiver moves out the current segment file.
9101  */
9102  RequestXLogSwitch(false);
9103 
9104  state->stoptime = (pg_time_t) time(NULL);
9105 
9106  /*
9107  * Write the backup history file
9108  */
9109  XLByteToSeg(state->startpoint, _logSegNo, wal_segment_size);
9110  BackupHistoryFilePath(histfilepath, state->stoptli, _logSegNo,
9111  state->startpoint, wal_segment_size);
9112  fp = AllocateFile(histfilepath, "w");
9113  if (!fp)
9114  ereport(ERROR,
9116  errmsg("could not create file \"%s\": %m",
9117  histfilepath)));
9118 
9119  /* Build and save the contents of the backup history file */
9120  history_file = build_backup_content(state, true);
9121  fprintf(fp, "%s", history_file);
9122  pfree(history_file);
9123 
9124  if (fflush(fp) || ferror(fp) || FreeFile(fp))
9125  ereport(ERROR,
9127  errmsg("could not write file \"%s\": %m",
9128  histfilepath)));
9129 
9130  /*
9131  * Clean out any no-longer-needed history files. As a side effect,
9132  * this will post a .ready file for the newly created history file,
9133  * notifying the archiver that history file may be archived
9134  * immediately.
9135  */
9137  }
9138 
9139  /*
9140  * If archiving is enabled, wait for all the required WAL files to be
9141  * archived before returning. If archiving isn't enabled, the required WAL
9142  * needs to be transported via streaming replication (hopefully with
9143  * wal_keep_size set high enough), or some more exotic mechanism like
9144  * polling and copying files from pg_wal with script. We have no knowledge
9145  * of those mechanisms, so it's up to the user to ensure that he gets all
9146  * the required WAL.
9147  *
9148  * We wait until both the last WAL file filled during backup and the
9149  * history file have been archived, and assume that the alphabetic sorting
9150  * property of the WAL files ensures any earlier WAL files are safely
9151  * archived as well.
9152  *
9153  * We wait forever, since archive_command is supposed to work and we
9154  * assume the admin wanted his backup to work completely. If you don't
9155  * wish to wait, then either waitforarchive should be passed in as false,
9156  * or you can set statement_timeout. Also, some notices are issued to
9157  * clue in anyone who might be doing this interactively.
9158  */
9159 
9160  if (waitforarchive &&
9161  ((!backup_stopped_in_recovery && XLogArchivingActive()) ||
9162  (backup_stopped_in_recovery && XLogArchivingAlways())))
9163  {
9164  XLByteToPrevSeg(state->stoppoint, _logSegNo, wal_segment_size);
9165  XLogFileName(lastxlogfilename, state->stoptli, _logSegNo,
9167 
9168  XLByteToSeg(state->startpoint, _logSegNo, wal_segment_size);
9169  BackupHistoryFileName(histfilename, state->stoptli, _logSegNo,
9170  state->startpoint, wal_segment_size);
9171 
9172  seconds_before_warning = 60;
9173  waits = 0;
9174 
9175  while (XLogArchiveIsBusy(lastxlogfilename) ||
9176  XLogArchiveIsBusy(histfilename))
9177  {
9179 
9180  if (!reported_waiting && waits > 5)
9181  {
9182  ereport(NOTICE,
9183  (errmsg("base backup done, waiting for required WAL segments to be archived")));
9184  reported_waiting = true;
9185  }
9186 
9187  (void) WaitLatch(MyLatch,
9189  1000L,
9190  WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE);
9192 
9193  if (++waits >= seconds_before_warning)
9194  {
9195  seconds_before_warning *= 2; /* This wraps in >10 years... */
9196  ereport(WARNING,
9197  (errmsg("still waiting for all required WAL segments to be archived (%d seconds elapsed)",
9198  waits),
9199  errhint("Check that your archive_command is executing properly. "
9200  "You can safely cancel this backup, "
9201  "but the database backup will not be usable without all the WAL segments.")));
9202  }
9203  }
9204 
9205  ereport(NOTICE,
9206  (errmsg("all required WAL segments have been archived")));
9207  }
9208  else if (waitforarchive)
9209  ereport(NOTICE,
9210  (errmsg("WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup")));
9211 }
#define NOTICE
Definition: elog.h:35
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2583
int FreeFile(FILE *file)
Definition: fd.c:2781
struct Latch * MyLatch
Definition: globals.c:59
void ResetLatch(Latch *latch)
Definition: latch.c:725
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:518
#define WL_TIMEOUT
Definition: latch.h:130
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:132
#define WL_LATCH_SET
Definition: latch.h:127
static void const char fflush(stdout)
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
#define XLOG_BACKUP_END
Definition: pg_control.h:72
#define fprintf
Definition: port.h:242
static void CleanupBackupHistory(void)
Definition: xlog.c:4093
#define XLogArchivingAlways()
Definition: xlog.h:100
static void BackupHistoryFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr startpoint, int wal_segsz_bytes)
static void BackupHistoryFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr startpoint, int wal_segsz_bytes)
bool XLogArchiveIsBusy(const char *xlog)
Definition: xlogarchive.c:620
char * build_backup_content(BackupState *state, bool ishistoryfile)
Definition: xlogbackup.c:29

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

Referenced by perform_base_backup(), and pg_backup_stop().

◆ get_backup_status()

SessionBackupState get_backup_status ( void  )

Definition at line 8938 of file xlog.c.

8939 {
8940  return sessionBackupState;
8941 }

References sessionBackupState.

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

◆ get_sync_bit()

static int get_sync_bit ( int  method)
static

Definition at line 8432 of file xlog.c.

8433 {
8434  int o_direct_flag = 0;
8435 
8436  /*
8437  * Use O_DIRECT if requested, except in walreceiver process. The WAL
8438  * written by walreceiver is normally read by the startup process soon
8439  * after it's written. Also, walreceiver performs unaligned writes, which
8440  * don't work with O_DIRECT, so it is required for correctness too.
8441  */
8443  o_direct_flag = PG_O_DIRECT;
8444 
8445  /* If fsync is disabled, never open in sync mode */
8446  if (!enableFsync)
8447  return o_direct_flag;
8448 
8449  switch (method)
8450  {
8451  /*
8452  * enum values for all sync options are defined even if they are
8453  * not supported on the current platform. But if not, they are
8454  * not included in the enum option array, and therefore will never
8455  * be seen here.
8456  */
8457  case WAL_SYNC_METHOD_FSYNC:
8460  return o_direct_flag;
8461 #ifdef O_SYNC
8462  case WAL_SYNC_METHOD_OPEN:
8463  return O_SYNC | o_direct_flag;
8464 #endif
8465 #ifdef O_DSYNC
8467  return O_DSYNC | o_direct_flag;
8468 #endif
8469  default:
8470  /* can't happen (unless we are out of sync with option array) */
8471  elog(ERROR, "unrecognized wal_sync_method: %d", method);
8472  return 0; /* silence warning */
8473  }
8474 }
int io_direct_flags
Definition: fd.c:168
#define IO_DIRECT_WAL
Definition: fd.h:55
#define PG_O_DIRECT
Definition: fd.h:97
bool enableFsync
Definition: globals.c:126
#define AmWalReceiverProcess()
Definition: miscadmin.h:460
#define O_DSYNC
Definition: win32_port.h:352
@ WAL_SYNC_METHOD_OPEN
Definition: xlog.h:26
@ WAL_SYNC_METHOD_FDATASYNC
Definition: xlog.h:25
@ WAL_SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:27
@ WAL_SYNC_METHOD_OPEN_DSYNC
Definition: xlog.h:28
@ WAL_SYNC_METHOD_FSYNC
Definition: xlog.h:24

References AmWalReceiverProcess, elog(), enableFsync, ERROR, io_direct_flags, IO_DIRECT_WAL, O_DSYNC, PG_O_DIRECT, WAL_SYNC_METHOD_FDATASYNC, WAL_SYNC_METHOD_FSYNC, WAL_SYNC_METHOD_FSYNC_WRITETHROUGH, WAL_SYNC_METHOD_OPEN, and WAL_SYNC_METHOD_OPEN_DSYNC.

Referenced by assign_wal_sync_method(), XLogFileInit(), XLogFileInitInternal(), and XLogFileOpen().

◆ GetActiveWalLevelOnStandby()

WalLevel GetActiveWalLevelOnStandby ( void  )

Definition at line 4761 of file xlog.c.

4762 {
4763  return ControlFile->wal_level;
4764 }

References ControlFile, and ControlFileData::wal_level.

Referenced by CheckLogicalDecodingRequirements().

◆ GetFakeLSNForUnloggedRel()

XLogRecPtr GetFakeLSNForUnloggedRel ( void  )

Definition at line 4499 of file xlog.c.

4500 {
4501  XLogRecPtr nextUnloggedLSN;
4502 
4503  /* increment the unloggedLSN counter, need SpinLock */
4505  nextUnloggedLSN = XLogCtl->unloggedLSN++;
4507 
4508  return nextUnloggedLSN;
4509 }

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

Referenced by gistGetFakeLSN().

◆ GetFlushRecPtr()

XLogRecPtr GetFlushRecPtr ( TimeLineID insertTLI)

◆ GetFullPageWriteInfo()

void GetFullPageWriteInfo ( XLogRecPtr RedoRecPtr_p,
bool doPageWrites_p 
)

Definition at line 6344 of file xlog.c.

6345 {
6346  *RedoRecPtr_p = RedoRecPtr;
6347  *doPageWrites_p = doPageWrites;
6348 }
static bool doPageWrites
Definition: xlog.c:290

References doPageWrites, and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )

Definition at line 6359 of file xlog.c.

6360 {
6361  XLogRecPtr recptr;
6362 
6364  recptr = XLogCtl->LogwrtRqst.Write;
6366 
6367  return recptr;
6368 }

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

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

◆ GetLastImportantRecPtr()

XLogRecPtr GetLastImportantRecPtr ( void  )

Definition at line 6416 of file xlog.c.

6417 {
6419  int i;
6420 
6421  for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
6422  {
6423  XLogRecPtr last_important;
6424 
6425  /*
6426  * Need to take a lock to prevent torn reads of the LSN, which are
6427  * possible on some of the supported platforms. WAL insert locks only
6428  * support exclusive mode, so we have to use that.
6429  */
6431  last_important = WALInsertLocks[i].l.lastImportantAt;
6432  LWLockRelease(&WALInsertLocks[i].l.lock);
6433 
6434  if (res < last_important)
6435  res = last_important;
6436  }
6437 
6438  return res;
6439 }
int i
Definition: isn.c:73
XLogRecPtr lastImportantAt
Definition: xlog.c:381
WALInsertLock l
Definition: xlog.c:393
static WALInsertLockPadded * WALInsertLocks
Definition: xlog.c:576
#define NUM_XLOGINSERT_LOCKS
Definition: xlog.c:154

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

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

◆ GetLastSegSwitchData()

pg_time_t GetLastSegSwitchData ( XLogRecPtr lastSwitchLSN)

Definition at line 6445 of file xlog.c.

6446 {
6447  pg_time_t result;
6448 
6449  /* Need WALWriteLock, but shared lock is sufficient */
6450  LWLockAcquire(WALWriteLock, LW_SHARED);
6451  result = XLogCtl->lastSegSwitchTime;
6452  *lastSwitchLSN = XLogCtl->lastSegSwitchLSN;
6453  LWLockRelease(WALWriteLock);
6454 
6455  return result;
6456 }
pg_time_t lastSegSwitchTime
Definition: xlog.c:478
XLogRecPtr lastSegSwitchLSN
Definition: xlog.c:479

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

Referenced by CheckArchiveTimeout().

◆ GetMockAuthenticationNonce()

char* GetMockAuthenticationNonce ( void  )

Definition at line 4473 of file xlog.c.

4474 {
4475  Assert(ControlFile != NULL);
4477 }
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition: pg_control.h:228

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

Referenced by scram_mock_salt().

◆ GetOldestRestartPoint()

void GetOldestRestartPoint ( XLogRecPtr oldrecptr,
TimeLineID oldtli 
)

Definition at line 9302 of file xlog.c.

9303 {
9304  LWLockAcquire(ControlFileLock, LW_SHARED);
9305  *oldrecptr = ControlFile->checkPointCopy.redo;
9307  LWLockRelease(ControlFileLock);
9308 }

References ControlFileData::checkPointCopy, ControlFile, LW_SHARED, LWLockAcquire(), LWLockRelease(), CheckPoint::redo, and CheckPoint::ThisTimeLineID.

Referenced by ExecuteRecoveryCommand(), and RestoreArchivedFile().

◆ GetRecoveryState()

RecoveryState GetRecoveryState ( void  )

Definition at line 6247 of file xlog.c.

6248 {
6249  RecoveryState retval;
6250 
6252  retval = XLogCtl->SharedRecoveryState;
6254 
6255  return retval;
6256 }
RecoveryState
Definition: xlog.h:88

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

Referenced by XLogArchiveCheckDone().

◆ GetRedoRecPtr()

XLogRecPtr GetRedoRecPtr ( void  )

Definition at line 6314 of file xlog.c.

6315 {
6316  XLogRecPtr ptr;
6317 
6318  /*
6319  * The possibly not up-to-date copy in XlogCtl is enough. Even if we
6320  * grabbed a WAL insertion lock to read the authoritative value in
6321  * Insert->RedoRecPtr, someone might update it just after we've released
6322  * the lock.
6323  */
6325  ptr = XLogCtl->RedoRecPtr;
6327 
6328  if (RedoRecPtr < ptr)
6329  RedoRecPtr = ptr;
6330 
6331  return RedoRecPtr;
6332 }

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

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

◆ GetSystemIdentifier()

uint64 GetSystemIdentifier ( void  )

Definition at line 4463 of file xlog.c.

4464 {
4465  Assert(ControlFile != NULL);
4467 }

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

Referenced by IdentifySystem(), ReplicationSlotNameForTablesync(), and WalReceiverMain().

◆ GetWALAvailability()

WALAvailability GetWALAvailability ( XLogRecPtr  targetLSN)

Definition at line 7709 of file xlog.c.

7710 {
7711  XLogRecPtr currpos; /* current write LSN */
7712  XLogSegNo currSeg; /* segid of currpos */
7713  XLogSegNo targetSeg; /* segid of targetLSN */
7714  XLogSegNo oldestSeg; /* actual oldest segid */
7715  XLogSegNo oldestSegMaxWalSize; /* oldest segid kept by max_wal_size */
7716  XLogSegNo oldestSlotSeg; /* oldest segid kept by slot */
7717  uint64 keepSegs;
7718 
7719  /*
7720  * slot does not reserve WAL. Either deactivated, or has never been active
7721  */
7722  if (XLogRecPtrIsInvalid(targetLSN))
7723  return WALAVAIL_INVALID_LSN;
7724 
7725  /*
7726  * Calculate the oldest segment currently reserved by all slots,
7727  * considering wal_keep_size and max_slot_wal_keep_size. Initialize
7728  * oldestSlotSeg to the current segment.
7729  */
7730  currpos = GetXLogWriteRecPtr();
7731  XLByteToSeg(currpos, oldestSlotSeg, wal_segment_size);
7732  KeepLogSeg(currpos, &oldestSlotSeg);
7733 
7734  /*
7735  * Find the oldest extant segment file. We get 1 until checkpoint removes
7736  * the first WAL segment file since startup, which causes the status being
7737  * wrong under certain abnormal conditions but that doesn't actually harm.
7738  */
7739  oldestSeg = XLogGetLastRemovedSegno() + 1;
7740 
7741  /* calculate oldest segment by max_wal_size */
7742  XLByteToSeg(currpos, currSeg, wal_segment_size);
7744 
7745  if (currSeg > keepSegs)
7746  oldestSegMaxWalSize = currSeg - keepSegs;
7747  else
7748  oldestSegMaxWalSize = 1;
7749 
7750  /* the segment we care about */
7751  XLByteToSeg(targetLSN, targetSeg, wal_segment_size);
7752 
7753  /*
7754  * No point in returning reserved or extended status values if the
7755  * targetSeg is known to be lost.
7756  */
7757  if (targetSeg >= oldestSlotSeg)
7758  {
7759  /* show "reserved" when targetSeg is within max_wal_size */
7760  if (targetSeg >= oldestSegMaxWalSize)
7761  return WALAVAIL_RESERVED;
7762 
7763  /* being retained by slots exceeding max_wal_size */
7764  return WALAVAIL_EXTENDED;
7765  }
7766 
7767  /* WAL segments are no longer retained but haven't been removed yet */
7768  if (targetSeg >= oldestSeg)
7769  return WALAVAIL_UNRESERVED;
7770 
7771  /* Definitely lost */
7772  return WALAVAIL_REMOVED;
7773 }
XLogSegNo XLogGetLastRemovedSegno(void)
Definition: xlog.c:3693
XLogRecPtr GetXLogWriteRecPtr(void)
Definition: xlog.c:9288
@ WALAVAIL_REMOVED
Definition: xlog.h:191
@ WALAVAIL_RESERVED
Definition: xlog.h:187
@ WALAVAIL_UNRESERVED
Definition: xlog.h:190
@ WALAVAIL_EXTENDED
Definition: xlog.h:188
@ WALAVAIL_INVALID_LSN
Definition: xlog.h:186

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

Referenced by pg_get_replication_slots().

◆ GetWALInsertionTimeLine()

TimeLineID GetWALInsertionTimeLine ( void  )

Definition at line 6399 of file xlog.c.

6400 {
6402 
6403  /* Since the value can't be changing, no lock is required. */
6404  return XLogCtl->InsertTimeLineID;
6405 }

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

◆ GetXLogBuffer()

static char * GetXLogBuffer ( XLogRecPtr  ptr,
TimeLineID  tli 
)
static

Definition at line 1607 of file xlog.c.

1608 {
1609  int idx;
1610  XLogRecPtr endptr;
1611  static uint64 cachedPage = 0;
1612  static char *cachedPos = NULL;
1613  XLogRecPtr expectedEndPtr;
1614 
1615  /*
1616  * Fast path for the common case that we need to access again the same
1617  * page as last time.
1618  */
1619  if (ptr / XLOG_BLCKSZ == cachedPage)
1620  {
1621  Assert(((XLogPageHeader) cachedPos)->xlp_magic == XLOG_PAGE_MAGIC);
1622  Assert(((XLogPageHeader) cachedPos)->xlp_pageaddr == ptr - (ptr % XLOG_BLCKSZ));
1623  return cachedPos + ptr % XLOG_BLCKSZ;
1624  }
1625 
1626  /*
1627  * The XLog buffer cache is organized so that a page is always loaded to a
1628  * particular buffer. That way we can easily calculate the buffer a given
1629  * page must be loaded into, from the XLogRecPtr alone.
1630  */
1631  idx = XLogRecPtrToBufIdx(ptr);
1632 
1633  /*
1634  * See what page is loaded in the buffer at the moment. It could be the
1635  * page we're looking for, or something older. It can't be anything newer
1636  * - that would imply the page we're looking for has already been written
1637  * out to disk and evicted, and the caller is responsible for making sure
1638  * that doesn't happen.
1639  *
1640  * We don't hold a lock while we read the value. If someone is just about
1641  * to initialize or has just initialized the page, it's possible that we
1642  * get InvalidXLogRecPtr. That's ok, we'll grab the mapping lock (in
1643  * AdvanceXLInsertBuffer) and retry if we see anything other than the page
1644  * we're looking for.
1645  */
1646  expectedEndPtr = ptr;
1647  expectedEndPtr += XLOG_BLCKSZ - ptr % XLOG_BLCKSZ;
1648 
1649  endptr = pg_atomic_read_u64(&XLogCtl->xlblocks[idx]);
1650  if (expectedEndPtr != endptr)
1651  {
1652  XLogRecPtr initializedUpto;
1653 
1654  /*
1655  * Before calling AdvanceXLInsertBuffer(), which can block, let others
1656  * know how far we're finished with inserting the record.
1657  *
1658  * NB: If 'ptr' points to just after the page header, advertise a
1659  * position at the beginning of the page rather than 'ptr' itself. If
1660  * there are no other insertions running, someone might try to flush
1661  * up to our advertised location. If we advertised a position after
1662  * the page header, someone might try to flush the page header, even
1663  * though page might actually not be initialized yet. As the first
1664  * inserter on the page, we are effectively responsible for making
1665  * sure that it's initialized, before we let insertingAt to move past
1666  * the page header.
1667  */
1668  if (ptr % XLOG_BLCKSZ == SizeOfXLogShortPHD &&
1669  XLogSegmentOffset(ptr, wal_segment_size) > XLOG_BLCKSZ)
1670  initializedUpto = ptr - SizeOfXLogShortPHD;
1671  else if (ptr % XLOG_BLCKSZ == SizeOfXLogLongPHD &&
1672  XLogSegmentOffset(ptr, wal_segment_size) < XLOG_BLCKSZ)
1673  initializedUpto = ptr - SizeOfXLogLongPHD;
1674  else
1675  initializedUpto = ptr;
1676 
1677  WALInsertLockUpdateInsertingAt(initializedUpto);
1678 
1679  AdvanceXLInsertBuffer(ptr, tli, false);
1680  endptr = pg_atomic_read_u64(&XLogCtl->xlblocks[idx]);
1681 
1682  if (expectedEndPtr != endptr)
1683  elog(PANIC, "could not find WAL buffer for %X/%X",
1684  LSN_FORMAT_ARGS(ptr));
1685  }
1686  else
1687  {
1688  /*
1689  * Make sure the initialization of the page is visible to us, and
1690  * won't arrive later to overwrite the WAL data we write on the page.
1691  */
1693  }
1694 
1695  /*
1696  * Found the buffer holding this page. Return a pointer to the right
1697  * offset within the page.
1698  */
1699  cachedPage = ptr / XLOG_BLCKSZ;
1700  cachedPos = XLogCtl->pages + idx * (Size) XLOG_BLCKSZ;
1701 
1702  Assert(((XLogPageHeader) cachedPos)->xlp_magic == XLOG_PAGE_MAGIC);
1703  Assert(((XLogPageHeader) cachedPos)->xlp_pageaddr == ptr - (ptr % XLOG_BLCKSZ));
1704 
1705  return cachedPos + ptr % XLOG_BLCKSZ;
1706 }
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
#define pg_memory_barrier()
Definition: atomics.h:140
static void WALInsertLockUpdateInsertingAt(XLogRecPtr insertingAt)
Definition: xlog.c:1464
static void AdvanceXLInsertBuffer(XLogRecPtr upto, TimeLineID tli, bool opportunistic)
Definition: xlog.c:1949

References AdvanceXLInsertBuffer(), Assert(), elog(), idx(), LSN_FORMAT_ARGS, XLogCtlData::pages, PANIC, pg_atomic_read_u64(), pg_memory_barrier, SizeOfXLogLongPHD, SizeOfXLogShortPHD, wal_segment_size, WALInsertLockUpdateInsertingAt(), XLogCtlData::xlblocks, XLOG_PAGE_MAGIC, XLogCtl, XLogRecPtrToBufIdx, and XLogSegmentOffset.

Referenced by CopyXLogRecordToWAL(), and CreateOverwriteContrecordRecord().

◆ GetXLogInsertRecPtr()

XLogRecPtr GetXLogInsertRecPtr ( void  )

Definition at line 9272 of file xlog.c.

9273 {
9275  uint64 current_bytepos;
9276 
9277  SpinLockAcquire(&Insert->insertpos_lck);
9278  current_bytepos = Insert->CurrBytePos;
9279  SpinLockRelease(&Insert->insertpos_lck);
9280 
9281  return XLogBytePosToRecPtr(current_bytepos);
9282 }

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

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

◆ GetXLogWriteRecPtr()

◆ InitControlFile()

static void InitControlFile ( uint64  sysidentifier)
static

Definition at line 4136 of file xlog.c.

4137 {
4138  char mock_auth_nonce[MOCK_AUTH_NONCE_LEN];
4139 
4140  /*
4141  * Generate a random nonce. This is used for authentication requests that
4142  * will fail because the user does not exist. The nonce is used to create
4143  * a genuine-looking password challenge for the non-existent user, in lieu
4144  * of an actual stored password.
4145  */
4146  if (!pg_strong_random(mock_auth_nonce, MOCK_AUTH_NONCE_LEN))
4147  ereport(PANIC,
4148  (errcode(ERRCODE_INTERNAL_ERROR),
4149  errmsg("could not generate secret authorization token")));
4150 
4151  memset(ControlFile, 0, sizeof(ControlFileData));
4152  /* Initialize pg_control status fields */
4153  ControlFile->system_identifier = sysidentifier;
4154  memcpy(ControlFile->mock_authentication_nonce, mock_auth_nonce, MOCK_AUTH_NONCE_LEN);
4157 
4158  /* Set important parameter values for use when replaying WAL */
4168 }
bool track_commit_timestamp
Definition: commit_ts.c:111
#define MOCK_AUTH_NONCE_LEN
Definition: pg_control.h:28
bool pg_strong_random(void *buf, size_t len)
bool track_commit_timestamp
Definition: pg_control.h:184
int wal_level
Definition: xlog.c:135
bool wal_log_hints
Definition: xlog.c:127
uint32 bootstrap_data_checksum_version
Definition: bootstrap.c:48
#define FirstNormalUnloggedLSN
Definition: xlogdefs.h:36

References bootstrap_data_checksum_version, ControlFile, ControlFileData::data_checksum_version, DB_SHUTDOWNED, ereport, errcode(), errmsg(), FirstNormalUnloggedLSN, max_locks_per_xact, ControlFileData::max_locks_per_xact, max_prepared_xacts, ControlFileData::max_prepared_xacts, max_wal_senders, ControlFileData::max_wal_senders, max_worker_processes, ControlFileData::max_worker_processes, MaxConnections, ControlFileData::MaxConnections, MOCK_AUTH_NONCE_LEN, ControlFileData::mock_authentication_nonce, PANIC, pg_strong_random(), ControlFileData::state, ControlFileData::system_identifier, track_commit_timestamp, ControlFileData::track_commit_timestamp, ControlFileData::unloggedLSN, wal_level, ControlFileData::wal_level, wal_log_hints, and ControlFileData::wal_log_hints.

Referenced by BootStrapXLOG().

◆ InitializeWalConsistencyChecking()

void InitializeWalConsistencyChecking ( void  )

Definition at line 4686 of file xlog.c.

4687 {
4689 
4691  {
4692  struct config_generic *guc;
4693 
4694  guc = find_option("wal_consistency_checking", false, false, ERROR);
4695 
4697 
4698  set_config_option_ext("wal_consistency_checking",
4700  guc->scontext, guc->source, guc->srole,
4701  GUC_ACTION_SET, true, ERROR, false);
4702 
4703  /* checking should not be deferred again */
4705  }
4706 }
struct config_generic * find_option(const char *name, bool create_placeholders, bool skip_errors, int elevel)
Definition: guc.c:1230
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:3354
@ GUC_ACTION_SET
Definition: guc.h:199
GucContext scontext
Definition: guc_tables.h:167
GucSource source
Definition: guc_tables.h:165
char * wal_consistency_checking_string
Definition: xlog.c:129

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

Referenced by PostgresSingleUserMain(), and PostmasterMain().

◆ InstallXLogFileSegment()

static bool InstallXLogFileSegment ( XLogSegNo segno,
char *  tmppath,
bool  find_free,
XLogSegNo  max_segno,
TimeLineID  tli 
)
static

Definition at line 3498 of file xlog.c.

3500 {
3501  char path[MAXPGPATH];
3502  struct stat stat_buf;
3503 
3504  Assert(tli != 0);
3505 
3506  XLogFilePath(path, tli, *segno, wal_segment_size);
3507 
3508  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
3510  {
3511  LWLockRelease(ControlFileLock);
3512  return false;
3513  }
3514 
3515  if (!find_free)
3516  {
3517  /* Force installation: get rid of any pre-existing segment file */
3518  durable_unlink(path, DEBUG1);
3519  }
3520  else
3521  {
3522  /* Find a free slot to put it in */
3523  while (stat(path, &stat_buf) == 0)
3524  {
3525  if ((*segno) >= max_segno)
3526  {
3527  /* Failed to find a free slot within specified range */
3528  LWLockRelease(ControlFileLock);
3529  return false;
3530  }
3531  (*segno)++;
3532  XLogFilePath(path, tli, *segno, wal_segment_size);
3533  }
3534  }
3535 
3536  Assert(access(path, F_OK) != 0 && errno == ENOENT);
3537  if (durable_rename(tmppath, path, LOG) != 0)
3538  {
3539  LWLockRelease(ControlFileLock);
3540  /* durable_rename already emitted log message */
3541  return false;
3542  }
3543 
3544  LWLockRelease(ControlFileLock);
3545 
3546  return true;
3547 }
int durable_unlink(const char *fname, int elevel)
Definition: fd.c:872
short access
Definition: preproc-type.c:36
bool InstallXLogFileSegmentActive
Definition: xlog.c:533
#define stat
Definition: win32_port.h:284

References Assert(), DEBUG1, durable_rename(), durable_unlink(), XLogCtlData::InstallXLogFileSegmentActive, LOG, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MAXPGPATH, stat, wal_segment_size, XLogCtl, and XLogFilePath().

Referenced by RemoveXlogFile(), XLogFileCopy(), and XLogFileInitInternal().

◆ IsInstallXLogFileSegmentActive()

bool IsInstallXLogFileSegmentActive ( void  )

Definition at line 9331 of file xlog.c.

9332 {
9333  bool result;
9334 
9335  LWLockAcquire(ControlFileLock, LW_SHARED);
9337  LWLockRelease(ControlFileLock);
9338 
9339  return result;
9340 }

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

Referenced by XLogFileRead().

◆ issue_xlog_fsync()

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

Definition at line 8522 of file xlog.c.

8523 {
8524  char *msg = NULL;
8525  instr_time start;
8526 
8527  Assert(tli != 0);
8528 
8529  /*
8530  * Quick exit if fsync is disabled or write() has already synced the WAL
8531  * file.
8532  */
8533  if (!enableFsync ||
8536  return;
8537 
8538  /* Measure I/O timing to sync the WAL file */
8539  if (track_wal_io_timing)
8540  INSTR_TIME_SET_CURRENT(start);
8541  else
8542  INSTR_TIME_SET_ZERO(start);
8543 
8544  pgstat_report_wait_start(WAIT_EVENT_WAL_SYNC);
8545  switch (wal_sync_method)
8546  {
8547  case WAL_SYNC_METHOD_FSYNC:
8548  if (pg_fsync_no_writethrough(fd) != 0)
8549  msg = _("could not fsync file \"%s\": %m");
8550  break;
8551 #ifdef HAVE_FSYNC_WRITETHROUGH
8553  if (pg_fsync_writethrough(fd) != 0)
8554  msg = _("could not fsync write-through file \"%s\": %m");
8555  break;
8556 #endif
8558  if (pg_fdatasync(fd) != 0)
8559  msg = _("could not fdatasync file \"%s\": %m");
8560  break;
8561  case WAL_SYNC_METHOD_OPEN:
8563  /* not reachable */
8564  Assert(false);
8565  break;
8566  default:
8567  elog(PANIC, "unrecognized wal_sync_method: %d", wal_sync_method);
8568  break;
8569  }
8570 
8571  /* PANIC if failed to fsync */
8572  if (msg)
8573  {
8574  char xlogfname[MAXFNAMELEN];
8575  int save_errno = errno;
8576 
8577  XLogFileName(xlogfname, tli, segno, wal_segment_size);
8578  errno = save_errno;
8579  ereport(PANIC,
8581  errmsg(msg, xlogfname)));
8582  }
8583 
8585 
8586  /*
8587  * Increment the I/O timing and the number of times WAL files were synced.
8588  */
8589  if (track_wal_io_timing)
8590  {
8591  instr_time end;
8592 
8595  }
8596 
8598 }
#define _(x)
Definition: elog.c:91
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:441
int pg_fdatasync(int fd)
Definition: fd.c:480
int pg_fsync_writethrough(int fd)
Definition: fd.c:461
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:122
#define INSTR_TIME_SET_ZERO(t)
Definition: instr_time.h:172
#define INSTR_TIME_ACCUM_DIFF(x, y, z)
Definition: instr_time.h:184
static int fd(const char *x, int i)
Definition: preproc-init.c:105
instr_time wal_sync_time
Definition: pgstat.h:456
PgStat_Counter wal_sync
Definition: pgstat.h:454
bool track_wal_io_timing
Definition: xlog.c:141

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

Referenced by XLogWalRcvFlush(), and XLogWrite().

◆ KeepLogSeg()

static void KeepLogSeg ( XLogRecPtr  recptr,
XLogSegNo logSegNo 
)
static

Definition at line 7793 of file xlog.c.

7794 {
7795  XLogSegNo currSegNo;
7796  XLogSegNo segno;
7797  XLogRecPtr keep;
7798 
7799  XLByteToSeg(recptr, currSegNo, wal_segment_size);
7800  segno = currSegNo;
7801 
7802  /*
7803  * Calculate how many segments are kept by slots first, adjusting for
7804  * max_slot_wal_keep_size.
7805  */
7807  if (keep != InvalidXLogRecPtr && keep < recptr)
7808  {
7809  XLByteToSeg(keep, segno, wal_segment_size);
7810 
7811  /* Cap by max_slot_wal_keep_size ... */
7812  if (max_slot_wal_keep_size_mb >= 0)
7813  {
7814  uint64 slot_keep_segs;
7815 
7816  slot_keep_segs =
7818 
7819  if (currSegNo - segno > slot_keep_segs)
7820  segno = currSegNo - slot_keep_segs;
7821  }
7822  }
7823 
7824  /*
7825  * If WAL summarization is in use, don't remove WAL that has yet to be
7826  * summarized.
7827  */
7828  keep = GetOldestUnsummarizedLSN(NULL, NULL, false);
7829  if (keep != InvalidXLogRecPtr)
7830  {
7831  XLogSegNo unsummarized_segno;
7832 
7833  XLByteToSeg(keep, unsummarized_segno, wal_segment_size);
7834  if (unsummarized_segno < segno)
7835  segno = unsummarized_segno;
7836  }
7837 
7838  /* but, keep at least wal_keep_size if that's set */
7839  if (wal_keep_size_mb > 0)
7840  {
7841  uint64 keep_segs;
7842 
7844  if (currSegNo - segno < keep_segs)
7845  {
7846  /* avoid underflow, don't go below 1 */
7847  if (currSegNo <= keep_segs)
7848  segno = 1;
7849  else
7850  segno = currSegNo - keep_segs;
7851  }
7852  }
7853 
7854  /* don't delete WAL segments newer than the calculated segment */
7855  if (segno < *logSegNo)
7856  *logSegNo = segno;
7857 }
XLogRecPtr GetOldestUnsummarizedLSN(TimeLineID *tli, bool *lsn_is_exact, bool reset_pending_lsn)
int wal_keep_size_mb
Definition: xlog.c:120
static XLogRecPtr XLogGetReplicationSlotMinimumLSN(void)
Definition: xlog.c:2632
int max_slot_wal_keep_size_mb
Definition: xlog.c:139

References ConvertToXSegs, GetOldestUnsummarizedLSN(), InvalidXLogRecPtr, max_slot_wal_keep_size_mb, wal_keep_size_mb, wal_segment_size, XLByteToSeg, and XLogGetReplicationSlotMinimumLSN().

Referenced by CreateCheckPoint(), CreateRestartPoint(), and GetWALAvailability().

◆ LocalProcessControlFile()

void LocalProcessControlFile ( bool  reset)

Definition at line 4748 of file xlog.c.

4749 {
4750  Assert(reset || ControlFile == NULL);
4751  ControlFile = palloc(sizeof(ControlFileData));
4752  ReadControlFile();
4753 }
void reset(void)
Definition: sql-declare.c:600

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

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

◆ LocalSetXLogInsertAllowed()

static int LocalSetXLogInsertAllowed ( void  )
static

Definition at line 6299 of file xlog.c.

6300 {
6301  int oldXLogAllowed = LocalXLogInsertAllowed;
6302 
6304 
6305  return oldXLogAllowed;
6306 }

References LocalXLogInsertAllowed.

Referenced by CreateCheckPoint(), and StartupXLOG().

◆ LogCheckpointEnd()

static void LogCheckpointEnd ( bool  restartpoint)
static

Definition at line 6541 of file xlog.c.

6542 {
6543  long write_msecs,
6544  sync_msecs,
6545  total_msecs,
6546  longest_msecs,
6547  average_msecs;
6548  uint64 average_sync_time;
6549 
6551 
6554 
6557 
6558  /* Accumulate checkpoint timing summary data, in milliseconds. */
6559  PendingCheckpointerStats.write_time += write_msecs;
6560  PendingCheckpointerStats.sync_time += sync_msecs;
6561 
6562  /*
6563  * All of the published timing statistics are accounted for. Only
6564  * continue if a log message is to be written.
6565  */
6566  if (!log_checkpoints)
6567  return;
6568 
6571 
6572  /*
6573  * Timing values returned from CheckpointStats are in microseconds.
6574  * Convert to milliseconds for consistent printing.
6575  */
6576  longest_msecs = (long) ((CheckpointStats.ckpt_longest_sync + 999) / 1000);
6577 
6578  average_sync_time = 0;
6580  average_sync_time = CheckpointStats.ckpt_agg_sync_time /
6582  average_msecs = (long) ((average_sync_time + 999) / 1000);
6583 
6584  /*
6585  * ControlFileLock is not required to see ControlFile->checkPoint and
6586  * ->checkPointCopy here as we are the only updator of those variables at
6587  * this moment.
6588  */
6589  if (restartpoint)
6590  ereport(LOG,
6591  (errmsg("restartpoint complete: wrote %d buffers (%.1f%%); "
6592  "%d WAL file(s) added, %d removed, %d recycled; "
6593  "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; "
6594  "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; "
6595  "distance=%d kB, estimate=%d kB; "
6596  "lsn=%X/%X, redo lsn=%X/%X",
6598  (double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
6602  write_msecs / 1000, (int) (write_msecs % 1000),
6603  sync_msecs / 1000, (int) (sync_msecs % 1000),
6604  total_msecs / 1000, (int) (total_msecs % 1000),
6606  longest_msecs / 1000, (int) (longest_msecs % 1000),
6607  average_msecs / 1000, (int) (average_msecs % 1000),
6608  (int) (PrevCheckPointDistance / 1024.0),
6609  (int) (CheckPointDistanceEstimate / 1024.0),
6612  else
6613  ereport(LOG,
6614  (errmsg("checkpoint complete: wrote %d buffers (%.1f%%); "
6615  "%d WAL file(s) added, %d removed, %d recycled; "
6616  "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; "
6617  "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; "
6618  "distance=%d kB, estimate=%d kB; "
6619  "lsn=%X/%X, redo lsn=%X/%X",
6621  (double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
6625  write_msecs / 1000, (int) (write_msecs % 1000),
6626  sync_msecs / 1000, (int) (sync_msecs % 1000),
6627  total_msecs / 1000, (int) (total_msecs % 1000),
6629  longest_msecs / 1000, (int) (longest_msecs % 1000),
6630  average_msecs / 1000, (int) (average_msecs % 1000),
6631  (int) (PrevCheckPointDistance / 1024.0),
6632  (int) (CheckPointDistanceEstimate / 1024.0),
6635 }
long TimestampDifferenceMilliseconds(TimestampTz start_time, TimestampTz stop_time)
Definition: timestamp.c:1767
PgStat_CheckpointerStats PendingCheckpointerStats
uint64 ckpt_agg_sync_time
Definition: xlog.h:173
uint64 ckpt_longest_sync
Definition: xlog.h:172
TimestampTz ckpt_end_t
Definition: xlog.h:163
int ckpt_sync_rels
Definition: xlog.h:171
PgStat_Counter sync_time
Definition: pgstat.h:269
PgStat_Counter write_time
Definition: pgstat.h:268
static double CheckPointDistanceEstimate
Definition: xlog.c:163
static double PrevCheckPointDistance
Definition: xlog.c:164

References ControlFileData::checkPoint, ControlFileData::checkPointCopy, CheckPointDistanceEstimate, CheckpointStats, CheckpointStatsData::ckpt_agg_sync_time, CheckpointStatsData::ckpt_bufs_written, CheckpointStatsData::ckpt_end_t, CheckpointStatsData::ckpt_longest_sync, CheckpointStatsData::ckpt_segs_added, CheckpointStatsData::ckpt_segs_recycled, CheckpointStatsData::ckpt_segs_removed, CheckpointStatsData::ckpt_start_t, CheckpointStatsData::ckpt_sync_end_t, CheckpointStatsData::ckpt_sync_rels, CheckpointStatsData::ckpt_sync_t, CheckpointStatsData::ckpt_write_t, ControlFile, ereport, errmsg(), GetCurrentTimestamp(), LOG, log_checkpoints, LSN_FORMAT_ARGS, NBuffers, PendingCheckpointerStats, PrevCheckPointDistance, CheckPoint::redo, PgStat_CheckpointerStats::sync_time, TimestampDifferenceMilliseconds(), and PgStat_CheckpointerStats::write_time.

Referenced by CreateCheckPoint(), and CreateRestartPoint().

◆ LogCheckpointStart()

static void LogCheckpointStart ( int  flags,
bool  restartpoint 
)
static

Definition at line 6509 of file xlog.c.

6510 {
6511  if (restartpoint)
6512  ereport(LOG,
6513  /* translator: the placeholders show checkpoint options */
6514  (errmsg("restartpoint starting:%s%s%s%s%s%s%s%s",
6515  (flags & CHECKPOINT_IS_SHUTDOWN) ? " shutdown" : "",
6516  (flags & CHECKPOINT_END_OF_RECOVERY) ? " end-of-recovery" : "",
6517  (flags & CHECKPOINT_IMMEDIATE) ? " immediate" : "",
6518  (flags & CHECKPOINT_FORCE) ? " force" : "",
6519  (flags & CHECKPOINT_WAIT) ? " wait" : "",
6520  (flags & CHECKPOINT_CAUSE_XLOG) ? " wal" : "",
6521  (flags & CHECKPOINT_CAUSE_TIME) ? " time" : "",
6522  (flags & CHECKPOINT_FLUSH_ALL) ? " flush-all" : "")));
6523  else
6524  ereport(LOG,
6525  /* translator: the placeholders show checkpoint options */
6526  (errmsg("checkpoint starting:%s%s%s%s%s%s%s%s",
6527  (flags & CHECKPOINT_IS_SHUTDOWN) ? " shutdown" : "",
6528  (flags & CHECKPOINT_END_OF_RECOVERY) ? " end-of-recovery" : "",
6529  (flags & CHECKPOINT_IMMEDIATE) ? " immediate" : "",
6530  (flags & CHECKPOINT_FORCE) ? " force" : "",
6531  (flags & CHECKPOINT_WAIT) ? " wait" : "",
6532  (flags & CHECKPOINT_CAUSE_XLOG) ? " wal" : "",
6533  (flags & CHECKPOINT_CAUSE_TIME) ? " time" : "",
6534  (flags & CHECKPOINT_FLUSH_ALL) ? " flush-all" : "")));
6535 }
#define CHECKPOINT_CAUSE_XLOG
Definition: xlog.h:146
#define CHECKPOINT_FLUSH_ALL
Definition: xlog.h:141
#define CHECKPOINT_CAUSE_TIME
Definition: xlog.h:147

References CHECKPOINT_CAUSE_TIME, CHECKPOINT_CAUSE_XLOG, CHECKPOINT_END_OF_RECOVERY, CHECKPOINT_FLUSH_ALL, CHECKPOINT_FORCE, CHECKPOINT_IMMEDIATE, CHECKPOINT_IS_SHUTDOWN, CHECKPOINT_WAIT, ereport, errmsg(), and LOG.

Referenced by CreateCheckPoint(), and CreateRestartPoint().

◆ PerformRecoveryXLogAction()

static bool PerformRecoveryXLogAction ( void  )
static

Definition at line 6161 of file xlog.c.

6162 {
6163  bool promoted = false;
6164 
6165  /*
6166  * Perform a checkpoint to update all our recovery activity to disk.
6167  *
6168  * Note that we write a shutdown checkpoint rather than an on-line one.
6169  * This is not particularly critical, but since we may be assigning a new
6170  * TLI, using a shutdown checkpoint allows us to have the rule that TLI
6171  * only changes in shutdown checkpoints, which allows some extra error
6172  * checking in xlog_redo.
6173  *
6174  * In promotion, only create a lightweight end-of-recovery record instead
6175  * of a full checkpoint. A checkpoint is requested later, after we're
6176  * fully out of recovery mode and already accepting queries.
6177  */
6180  {
6181  promoted = true;
6182 
6183  /*
6184  * Insert a special WAL record to mark the end of recovery, since we
6185  * aren't doing a checkpoint. That means that the checkpointer process
6186  * may likely be in the middle of a time-smoothed restartpoint and
6187  * could continue to be for minutes after this. That sounds strange,
6188  * but the effect is roughly the same and it would be stranger to try
6189  * to come out of the restartpoint and then checkpoint. We request a
6190  * checkpoint later anyway, just for safety.
6191  */
6193  }
6194  else
6195  {
6198  CHECKPOINT_WAIT);
6199  }
6200 
6201  return promoted;
6202 }
static void CreateEndOfRecoveryRecord(void)
Definition: xlog.c:7222
bool PromoteIsTriggered(void)

References ArchiveRecoveryRequested, CHECKPOINT_END_OF_RECOVERY, CHECKPOINT_IMMEDIATE, CHECKPOINT_WAIT, CreateEndOfRecoveryRecord(), IsUnderPostmaster, PromoteIsTriggered(), and RequestCheckpoint().

Referenced by StartupXLOG().

◆ PreallocXlogFiles()

static void PreallocXlogFiles ( XLogRecPtr  endptr,
TimeLineID  tli 
)
static

Definition at line 3625 of file xlog.c.

3626 {
3627  XLogSegNo _logSegNo;
3628  int lf;
3629  bool added;
3630  char path[MAXPGPATH];
3631  uint64 offset;
3632 
3634  return; /* unlocked check says no */
3635 
3636  XLByteToPrevSeg(endptr, _logSegNo, wal_segment_size);
3637  offset = XLogSegmentOffset(endptr - 1, wal_segment_size);
3638  if (offset >= (uint32) (0.75 * wal_segment_size))
3639  {
3640  _logSegNo++;
3641  lf = XLogFileInitInternal(_logSegNo, tli, &added, path);
3642  if (lf >= 0)
3643  close(lf);
3644  if (added)
3646  }
3647 }
static int XLogFileInitInternal(XLogSegNo logsegno, TimeLineID logtli, bool *added, char *path)
Definition: xlog.c:3145

References CheckpointStats, CheckpointStatsData::ckpt_segs_added, close, XLogCtlData::InstallXLogFileSegmentActive, MAXPGPATH, wal_segment_size, XLByteToPrevSeg, XLogCtl, XLogFileInitInternal(), and XLogSegmentOffset.

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

◆ ReachedEndOfBackup()

void ReachedEndOfBackup ( XLogRecPtr  EndRecPtr,
TimeLineID  tli 
)

Definition at line 6124 of file xlog.c.

6125 {
6126  /*
6127  * We have reached the end of base backup, as indicated by pg_control. The
6128  * data on disk is now consistent (unless minRecoveryPoint is further
6129  * ahead, which can happen if we crashed during previous recovery). Reset
6130  * backupStartPoint and backupEndPoint, and update minRecoveryPoint to
6131  * make sure we don't allow starting up at an earlier point even if
6132  * recovery is stopped and restarted soon after this.
6133  */
6134  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6135 
6136  if (ControlFile->minRecoveryPoint < EndRecPtr)
6137  {
6138  ControlFile->minRecoveryPoint = EndRecPtr;
6140  }
6141 
6144  ControlFile->backupEndRequired = false;
6146 
6147  LWLockRelease(ControlFileLock);
6148 }
XLogRecPtr backupStartPoint
Definition: pg_control.h:169
bool backupEndRequired
Definition: pg_control.h:171
XLogRecPtr backupEndPoint
Definition: pg_control.h:170

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

Referenced by CheckRecoveryConsistency().

◆ ReadControlFile()

static void ReadControlFile ( void  )
static

Definition at line 4253 of file xlog.c.

4254 {
4255  pg_crc32c crc;
4256  int fd;
4257  static char wal_segsz_str[20];
4258  int r;
4259 
4260  /*
4261  * Read data...
4262  */
4264  O_RDWR | PG_BINARY);
4265  if (fd < 0)
4266  ereport(PANIC,
4268  errmsg("could not open file \"%s\": %m",
4269  XLOG_CONTROL_FILE)));
4270 
4271  pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_READ);
4272  r = read(fd, ControlFile, sizeof(ControlFileData));
4273  if (r != sizeof(ControlFileData))
4274  {
4275  if (r < 0)
4276  ereport(PANIC,
4278  errmsg("could not read file \"%s\": %m",
4279  XLOG_CONTROL_FILE)));
4280  else
4281  ereport(PANIC,
4283  errmsg("could not read file \"%s\": read %d of %zu",
4284  XLOG_CONTROL_FILE, r, sizeof(ControlFileData))));
4285  }
4287 
4288  close(fd);
4289 
4290  /*
4291  * Check for expected pg_control format version. If this is wrong, the
4292  * CRC check will likely fail because we'll be checking the wrong number
4293  * of bytes. Complaining about wrong version will probably be more
4294  * enlightening than complaining about wrong CRC.
4295  */
4296 
4298  ereport(FATAL,
4299  (errmsg("database files are incompatible with server"),
4300  errdetail("The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x),"
4301  " but the server was compiled with PG_CONTROL_VERSION %d (0x%08x).",
4304  errhint("This could be a problem of mismatched byte ordering. It looks like you need to initdb.")));
4305 
4307  ereport(FATAL,
4308  (errmsg("database files are incompatible with server"),
4309  errdetail("The database cluster was initialized with PG_CONTROL_VERSION %d,"
4310  " but the server was compiled with PG_CONTROL_VERSION %d.",
4312  errhint("It looks like you need to initdb.")));
4313 
4314  /* Now check the CRC. */
4315  INIT_CRC32C(crc);
4316  COMP_CRC32C(crc,
4317  (char *) ControlFile,
4318  offsetof(ControlFileData, crc));
4319  FIN_CRC32C(crc);
4320 
4321  if (!EQ_CRC32C(crc, ControlFile->crc))
4322  ereport(FATAL,
4323  (errmsg("incorrect checksum in control file")));
4324 
4325  /*
4326  * Do compatibility checking immediately. If the database isn't
4327  * compatible with the backend executable, we want to abort before we can
4328  * possibly do any damage.
4329  */
4331  ereport(FATAL,
4332  (errmsg("database files are incompatible with server"),
4333  errdetail("The database cluster was initialized with CATALOG_VERSION_NO %d,"
4334  " but the server was compiled with CATALOG_VERSION_NO %d.",
4336  errhint("It looks like you need to initdb.")));
4337  if (ControlFile->maxAlign != MAXIMUM_ALIGNOF)
4338  ereport(FATAL,
4339  (