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/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
 

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)
 
static void CalculateCheckpointSegments (void)
 
void assign_max_wal_size (int newval, void *extra)
 
void assign_checkpoint_completion_target (double newval, void *extra)
 
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)
 
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)
 
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_xlog_sync_method (int new_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 sync_method = DEFAULT_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 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 114 of file xlog.c.

◆ ConvertToXSegs

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

Definition at line 599 of file xlog.c.

◆ INSERT_FREESPACE

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

Definition at line 576 of file xlog.c.

◆ NextBufIdx

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

Definition at line 580 of file xlog.c.

◆ NUM_XLOGINSERT_LOCKS

#define NUM_XLOGINSERT_LOCKS   8

Definition at line 153 of file xlog.c.

◆ UsableBytesInPage

#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)

Definition at line 593 of file xlog.c.

◆ XLogRecPtrToBufIdx

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

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

Function Documentation

◆ AdvanceXLInsertBuffer()

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

Definition at line 1775 of file xlog.c.

1776 {
1778  int nextidx;
1779  XLogRecPtr OldPageRqstPtr;
1780  XLogwrtRqst WriteRqst;
1781  XLogRecPtr NewPageEndPtr = InvalidXLogRecPtr;
1782  XLogRecPtr NewPageBeginPtr;
1783  XLogPageHeader NewPage;
1784  int npages pg_attribute_unused() = 0;
1785 
1786  LWLockAcquire(WALBufMappingLock, LW_EXCLUSIVE);
1787 
1788  /*
1789  * Now that we have the lock, check if someone initialized the page
1790  * already.
1791  */
1792  while (upto >= XLogCtl->InitializedUpTo || opportunistic)
1793  {
1795 
1796  /*
1797  * Get ending-offset of the buffer page we need to replace (this may
1798  * be zero if the buffer hasn't been used yet). Fall through if it's
1799  * already written out.
1800  */
1801  OldPageRqstPtr = XLogCtl->xlblocks[nextidx];
1802  if (LogwrtResult.Write < OldPageRqstPtr)
1803  {
1804  /*
1805  * Nope, got work to do. If we just want to pre-initialize as much
1806  * as we can without flushing, give up now.
1807  */
1808  if (opportunistic)
1809  break;
1810 
1811  /* Before waiting, get info_lck and update LogwrtResult */
1813  if (XLogCtl->LogwrtRqst.Write < OldPageRqstPtr)
1814  XLogCtl->LogwrtRqst.Write = OldPageRqstPtr;
1817 
1818  /*
1819  * Now that we have an up-to-date LogwrtResult value, see if we
1820  * still need to write it or if someone else already did.
1821  */
1822  if (LogwrtResult.Write < OldPageRqstPtr)
1823  {
1824  /*
1825  * Must acquire write lock. Release WALBufMappingLock first,
1826  * to make sure that all insertions that we need to wait for
1827  * can finish (up to this same position). Otherwise we risk
1828  * deadlock.
1829  */
1830  LWLockRelease(WALBufMappingLock);
1831 
1832  WaitXLogInsertionsToFinish(OldPageRqstPtr);
1833 
1834  LWLockAcquire(WALWriteLock, LW_EXCLUSIVE);
1835 
1837  if (LogwrtResult.Write >= OldPageRqstPtr)
1838  {
1839  /* OK, someone wrote it already */
1840  LWLockRelease(WALWriteLock);
1841  }
1842  else
1843  {
1844  /* Have to write it ourselves */
1845  TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_START();
1846  WriteRqst.Write = OldPageRqstPtr;
1847  WriteRqst.Flush = 0;
1848  XLogWrite(WriteRqst, tli, false);
1849  LWLockRelease(WALWriteLock);
1851  TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_DONE();
1852  }
1853  /* Re-acquire WALBufMappingLock and retry */
1854  LWLockAcquire(WALBufMappingLock, LW_EXCLUSIVE);
1855  continue;
1856  }
1857  }
1858 
1859  /*
1860  * Now the next buffer slot is free and we can set it up to be the
1861  * next output page.
1862  */
1863  NewPageBeginPtr = XLogCtl->InitializedUpTo;
1864  NewPageEndPtr = NewPageBeginPtr + XLOG_BLCKSZ;
1865 
1866  Assert(XLogRecPtrToBufIdx(NewPageBeginPtr) == nextidx);
1867 
1868  NewPage = (XLogPageHeader) (XLogCtl->pages + nextidx * (Size) XLOG_BLCKSZ);
1869 
1870  /*
1871  * Be sure to re-zero the buffer so that bytes beyond what we've
1872  * written will look like zeroes and not valid XLOG records...
1873  */
1874  MemSet((char *) NewPage, 0, XLOG_BLCKSZ);
1875 
1876  /*
1877  * Fill the new page's header
1878  */
1879  NewPage->xlp_magic = XLOG_PAGE_MAGIC;
1880 
1881  /* NewPage->xlp_info = 0; */ /* done by memset */
1882  NewPage->xlp_tli = tli;
1883  NewPage->xlp_pageaddr = NewPageBeginPtr;
1884 
1885  /* NewPage->xlp_rem_len = 0; */ /* done by memset */
1886 
1887  /*
1888  * If online backup is not in progress, mark the header to indicate
1889  * that WAL records beginning in this page have removable backup
1890  * blocks. This allows the WAL archiver to know whether it is safe to
1891  * compress archived WAL data by transforming full-block records into
1892  * the non-full-block format. It is sufficient to record this at the
1893  * page level because we force a page switch (in fact a segment
1894  * switch) when starting a backup, so the flag will be off before any
1895  * records can be written during the backup. At the end of a backup,
1896  * the last page will be marked as all unsafe when perhaps only part
1897  * is unsafe, but at worst the archiver would miss the opportunity to
1898  * compress a few records.
1899  */
1900  if (Insert->runningBackups == 0)
1901  NewPage->xlp_info |= XLP_BKP_REMOVABLE;
1902 
1903  /*
1904  * If first page of an XLOG segment file, make it a long header.
1905  */
1906  if ((XLogSegmentOffset(NewPage->xlp_pageaddr, wal_segment_size)) == 0)
1907  {
1908  XLogLongPageHeader NewLongPage = (XLogLongPageHeader) NewPage;
1909 
1910  NewLongPage->xlp_sysid = ControlFile->system_identifier;
1911  NewLongPage->xlp_seg_size = wal_segment_size;
1912  NewLongPage->xlp_xlog_blcksz = XLOG_BLCKSZ;
1913  NewPage->xlp_info |= XLP_LONG_HEADER;
1914  }
1915 
1916  /*
1917  * Make sure the initialization of the page becomes visible to others
1918  * before the xlblocks update. GetXLogBuffer() reads xlblocks without
1919  * holding a lock.
1920  */
1921  pg_write_barrier();
1922 
1923  *((volatile XLogRecPtr *) &XLogCtl->xlblocks[nextidx]) = NewPageEndPtr;
1924 
1925  XLogCtl->InitializedUpTo = NewPageEndPtr;
1926 
1927  npages++;
1928  }
1929  LWLockRelease(WALBufMappingLock);
1930 
1931 #ifdef WAL_DEBUG
1932  if (XLOG_DEBUG && npages > 0)
1933  {
1934  elog(DEBUG1, "initialized %d pages, up to %X/%X",
1935  npages, LSN_FORMAT_ARGS(NewPageEndPtr));
1936  }
1937 #endif
1938 }
#define pg_write_barrier()
Definition: atomics.h:154
#define pg_attribute_unused()
Definition: c.h:120
#define MemSet(start, val, len)
Definition: c.h:1004
size_t Size
Definition: c.h:589
#define DEBUG1
Definition: elog.h:30
static void Insert(File file)
Definition: fd.c:1219
Assert(fmt[strlen(fmt) - 1] !='\n')
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1195
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1803
@ LW_EXCLUSIVE
Definition: lwlock.h:115
PgStat_WalStats 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:108
PgStat_Counter wal_buffers_full
Definition: pgstat.h:428
XLogwrtRqst LogwrtRqst
Definition: xlog.c:464
slock_t info_lck
Definition: xlog.c:559
XLogRecPtr InitializedUpTo
Definition: xlog.c:496
char * pages
Definition: xlog.c:503
XLogwrtResult LogwrtResult
Definition: xlog.c:484
XLogCtlInsert Insert
Definition: xlog.c:461
XLogRecPtr * xlblocks
Definition: xlog.c:504
TimeLineID xlp_tli
Definition: xlog_internal.h:40
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
XLogRecPtr Write
Definition: xlog.c:336
XLogRecPtr Flush
Definition: xlog.c:331
XLogRecPtr Write
Definition: xlog.c:330
static XLogCtlData * XLogCtl
Definition: xlog.c:562
static XLogRecPtr WaitXLogInsertionsToFinish(XLogRecPtr upto)
Definition: xlog.c:1438
int wal_segment_size
Definition: xlog.c:146
static XLogwrtResult LogwrtResult
Definition: xlog.c:608
#define XLogRecPtrToBufIdx(recptr)
Definition: xlog.c:587
static void XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
Definition: xlog.c:2066
static ControlFileData * ControlFile
Definition: xlog.c:570
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_attribute_unused, pg_write_barrier, SpinLockAcquire, SpinLockRelease, ControlFileData::system_identifier, WaitXLogInsertionsToFinish(), PgStat_WalStats::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 1981 of file xlog.c.

1982 {
1985 }
double CheckPointCompletionTarget
Definition: checkpointer.c:146
#define newval
static void CalculateCheckpointSegments(void)
Definition: xlog.c:1945

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 1974 of file xlog.c.

1975 {
1978 }
int max_wal_size_mb
Definition: xlog.c:117

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

4374 {
4375  /*
4376  * If some checks were deferred, it's possible that the checks will fail
4377  * later during InitializeWalConsistencyChecking(). But in that case, the
4378  * postmaster will exit anyway, so it's safe to proceed with the
4379  * assignment.
4380  *
4381  * Any built-in resource managers specified are assigned immediately,
4382  * which affects WAL created before shared_preload_libraries are
4383  * processed. Any custom resource managers specified won't be assigned
4384  * until after shared_preload_libraries are processed, but that's OK
4385  * because WAL for a custom resource manager can't be written before the
4386  * module is loaded anyway.
4387  */
4388  wal_consistency_checking = extra;
4389 }
bool * wal_consistency_checking
Definition: xlog.c:129

References wal_consistency_checking.

◆ assign_xlog_sync_method()

void assign_xlog_sync_method ( int  new_sync_method,
void *  extra 
)

Definition at line 8093 of file xlog.c.

8094 {
8095  if (sync_method != new_sync_method)
8096  {
8097  /*
8098  * To ensure that no blocks escape unsynced, force an fsync on the
8099  * currently open log segment (if any). Also, if the open flag is
8100  * changing, close the log file so it will be reopened (with new flag
8101  * bit) at next use.
8102  */
8103  if (openLogFile >= 0)
8104  {
8106  if (pg_fsync(openLogFile) != 0)
8107  {
8108  char xlogfname[MAXFNAMELEN];
8109  int save_errno;
8110 
8111  save_errno = errno;
8112  XLogFileName(xlogfname, openLogTLI, openLogSegNo,
8114  errno = save_errno;
8115  ereport(PANIC,
8117  errmsg("could not fsync file \"%s\": %m", xlogfname)));
8118  }
8119 
8121  if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
8122  XLogFileClose();
8123  }
8124  }
8125 }
int errcode_for_file_access(void)
Definition: elog.c:881
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define PANIC
Definition: elog.h:42
#define ereport(elevel,...)
Definition: elog.h:149
int pg_fsync(int fd)
Definition: fd.c:356
@ WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN
Definition: wait_event.h:236
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:271
static void pgstat_report_wait_end(void)
Definition: wait_event.h:287
static int openLogFile
Definition: xlog.c:618
static int get_sync_bit(int method)
Definition: xlog.c:8037
static TimeLineID openLogTLI
Definition: xlog.c:620
static void XLogFileClose(void)
Definition: xlog.c:3347
static XLogSegNo openLogSegNo
Definition: xlog.c:619
int sync_method
Definition: xlog.c:133
#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(), sync_method, WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN, wal_segment_size, XLogFileClose(), and XLogFileName().

◆ BootStrapXLOG()

void BootStrapXLOG ( void  )

Definition at line 4633 of file xlog.c.

4634 {
4635  CheckPoint checkPoint;
4636  char *buffer;
4637  XLogPageHeader page;
4638  XLogLongPageHeader longpage;
4639  XLogRecord *record;
4640  char *recptr;
4641  uint64 sysidentifier;
4642  struct timeval tv;
4643  pg_crc32c crc;
4644 
4645  /* allow ordinary WAL segment creation, like StartupXLOG() would */
4647 
4648  /*
4649  * Select a hopefully-unique system identifier code for this installation.
4650  * We use the result of gettimeofday(), including the fractional seconds
4651  * field, as being about as unique as we can easily get. (Think not to
4652  * use random(), since it hasn't been seeded and there's no portable way
4653  * to seed it other than the system clock value...) The upper half of the
4654  * uint64 value is just the tv_sec part, while the lower half contains the
4655  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
4656  * PID for a little extra uniqueness. A person knowing this encoding can
4657  * determine the initialization time of the installation, which could
4658  * perhaps be useful sometimes.
4659  */
4660  gettimeofday(&tv, NULL);
4661  sysidentifier = ((uint64) tv.tv_sec) << 32;
4662  sysidentifier |= ((uint64) tv.tv_usec) << 12;
4663  sysidentifier |= getpid() & 0xFFF;
4664 
4665  /* page buffer must be aligned suitably for O_DIRECT */
4666  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
4667  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
4668  memset(page, 0, XLOG_BLCKSZ);
4669 
4670  /*
4671  * Set up information for the initial checkpoint record
4672  *
4673  * The initial checkpoint record is written to the beginning of the WAL
4674  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
4675  * used, so that we can use 0/0 to mean "before any valid WAL segment".
4676  */
4677  checkPoint.redo = wal_segment_size + SizeOfXLogLongPHD;
4678  checkPoint.ThisTimeLineID = BootstrapTimeLineID;
4679  checkPoint.PrevTimeLineID = BootstrapTimeLineID;
4680  checkPoint.fullPageWrites = fullPageWrites;
4681  checkPoint.nextXid =
4683  checkPoint.nextOid = FirstGenbkiObjectId;
4684  checkPoint.nextMulti = FirstMultiXactId;
4685  checkPoint.nextMultiOffset = 0;
4686  checkPoint.oldestXid = FirstNormalTransactionId;
4687  checkPoint.oldestXidDB = Template1DbOid;
4688  checkPoint.oldestMulti = FirstMultiXactId;
4689  checkPoint.oldestMultiDB = Template1DbOid;
4692  checkPoint.time = (pg_time_t) time(NULL);
4694 
4695  ShmemVariableCache->nextXid = checkPoint.nextXid;
4696  ShmemVariableCache->nextOid = checkPoint.nextOid;
4698  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
4699  AdvanceOldestClogXid(checkPoint.oldestXid);
4700  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
4701  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
4703 
4704  /* Set up the XLOG page header */
4705  page->xlp_magic = XLOG_PAGE_MAGIC;
4706  page->xlp_info = XLP_LONG_HEADER;
4707  page->xlp_tli = BootstrapTimeLineID;
4709  longpage = (XLogLongPageHeader) page;
4710  longpage->xlp_sysid = sysidentifier;
4711  longpage->xlp_seg_size = wal_segment_size;
4712  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
4713 
4714  /* Insert the initial checkpoint record */
4715  recptr = ((char *) page + SizeOfXLogLongPHD);
4716  record = (XLogRecord *) recptr;
4717  record->xl_prev = 0;
4718  record->xl_xid = InvalidTransactionId;
4719  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
4721  record->xl_rmid = RM_XLOG_ID;
4722  recptr += SizeOfXLogRecord;
4723  /* fill the XLogRecordDataHeaderShort struct */
4724  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
4725  *(recptr++) = sizeof(checkPoint);
4726  memcpy(recptr, &checkPoint, sizeof(checkPoint));
4727  recptr += sizeof(checkPoint);
4728  Assert(recptr - (char *) record == record->xl_tot_len);
4729 
4730  INIT_CRC32C(crc);
4731  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
4732  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
4733  FIN_CRC32C(crc);
4734  record->xl_crc = crc;
4735 
4736  /* Create first XLOG segment file */
4739 
4740  /*
4741  * We needn't bother with Reserve/ReleaseExternalFD here, since we'll
4742  * close the file again in a moment.
4743  */
4744 
4745  /* Write the first page with the initial record */
4746  errno = 0;
4748  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
4749  {
4750  /* if write didn't set errno, assume problem is no disk space */
4751  if (errno == 0)
4752  errno = ENOSPC;
4753  ereport(PANIC,
4755  errmsg("could not write bootstrap write-ahead log file: %m")));
4756  }
4758 
4760  if (pg_fsync(openLogFile) != 0)
4761  ereport(PANIC,
4763  errmsg("could not fsync bootstrap write-ahead log file: %m")));
4765 
4766  if (close(openLogFile) != 0)
4767  ereport(PANIC,
4769  errmsg("could not close bootstrap write-ahead log file: %m")));
4770 
4771  openLogFile = -1;
4772 
4773  /* Now create pg_control */
4774  InitControlFile(sysidentifier);
4775  ControlFile->time = checkPoint.time;
4776  ControlFile->checkPoint = checkPoint.redo;
4777  ControlFile->checkPointCopy = checkPoint;
4778 
4779  /* some additional ControlFile fields are set in WriteControlFile() */
4780  WriteControlFile();
4781 
4782  /* Bootstrap the commit log, too */
4783  BootStrapCLOG();
4787 
4788  pfree(buffer);
4789 
4790  /*
4791  * Force control file to be read - in contrast to normal processing we'd
4792  * otherwise never run the checks and GUC related initializations therein.
4793  */
4794  ReadControlFile();
4795 }
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:788
void BootStrapCLOG(void)
Definition: clog.c:711
void BootStrapCommitTs(void)
Definition: commit_ts.c:553
void SetCommitTsLimit(TransactionId oldestXact, TransactionId newestXact)
Definition: commit_ts.c:860
#define close(a)
Definition: win32.h:12
#define write(a, b, c)
Definition: win32.h:14
void pfree(void *pointer)
Definition: mcxt.c:1436
void * palloc(Size size)
Definition: mcxt.c:1210
void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset)
Definition: multixact.c:2179
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
Definition: multixact.c:2213
void BootStrapMultiXact(void)
Definition: multixact.c:1894
#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:89
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:94
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:133
pg_time_t time
Definition: pg_control.h:130
XLogRecPtr checkPoint
Definition: pg_control.h:131
FullTransactionId nextXid
Definition: transam.h:220
uint32 oidCount
Definition: transam.h:215
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:211
#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:345
void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid)
Definition: varsup.c:328
VariableCache ShmemVariableCache
Definition: varsup.c:34
@ WAIT_EVENT_WAL_BOOTSTRAP_SYNC
Definition: wait_event.h:227
@ WAIT_EVENT_WAL_BOOTSTRAP_WRITE
Definition: wait_event.h:228
int gettimeofday(struct timeval *tp, void *tzp)
int XLogFileInit(XLogSegNo logsegno, TimeLineID logtli)
Definition: xlog.c:3088
bool fullPageWrites
Definition: xlog.c:125
static void InitControlFile(uint64 sysidentifier)
Definition: xlog.c:3851
void SetInstallXLogFileSegmentActive(void)
Definition: xlog.c:8908
static void WriteControlFile(void)
Definition: xlog.c:3886
#define BootstrapTimeLineID
Definition: xlog.c:114
static void ReadControlFile(void)
Definition: xlog.c:3968
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:69
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:206
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:230
#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, VariableCacheData::nextOid, CheckPoint::nextOid, VariableCacheData::nextXid, CheckPoint::nextXid, VariableCacheData::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(), ShmemVariableCache, SizeOfXLogLongPHD, SizeOfXLogRecord, SizeOfXLogRecordDataHeaderShort, CheckPoint::ThisTimeLineID, CheckPoint::time, ControlFileData::time, TYPEALIGN, WAIT_EVENT_WAL_BOOTSTRAP_SYNC, WAIT_EVENT_WAL_BOOTSTRAP_WRITE, 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 1945 of file xlog.c.

1946 {
1947  double target;
1948 
1949  /*-------
1950  * Calculate the distance at which to trigger a checkpoint, to avoid
1951  * exceeding max_wal_size_mb. This is based on two assumptions:
1952  *
1953  * a) we keep WAL for only one checkpoint cycle (prior to PG11 we kept
1954  * WAL for two checkpoint cycles to allow us to recover from the
1955  * secondary checkpoint if the first checkpoint failed, though we
1956  * only did this on the primary anyway, not on standby. Keeping just
1957  * one checkpoint simplifies processing and reduces disk space in
1958  * many smaller databases.)
1959  * b) during checkpoint, we consume checkpoint_completion_target *
1960  * number of segments consumed between checkpoints.
1961  *-------
1962  */
1963  target = (double) ConvertToXSegs(max_wal_size_mb, wal_segment_size) /
1965 
1966  /* round down */
1967  CheckPointSegments = (int) target;
1968 
1969  if (CheckPointSegments < 1)
1970  CheckPointSegments = 1;
1971 }
#define ConvertToXSegs(x, segsize)
Definition: xlog.c:599
int CheckPointSegments
Definition: xlog.c:159

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

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

Definition at line 4253 of file xlog.c.

4254 {
4255  /*
4256  * -1 indicates a request for auto-tune.
4257  */
4258  if (*newval == -1)
4259  {
4260  /*
4261  * If we haven't yet changed the boot_val default of -1, just let it
4262  * be. We'll fix it when XLOGShmemSize is called.
4263  */
4264  if (XLOGbuffers == -1)
4265  return true;
4266 
4267  /* Otherwise, substitute the auto-tune value */
4269  }
4270 
4271  /*
4272  * We clamp manually-set values to at least 4 blocks. Prior to PostgreSQL
4273  * 9.1, a minimum of 4 was enforced by guc.c, but since that is no longer
4274  * the case, we just silently treat such values as a request for the
4275  * minimum. (We could throw an error instead, but that doesn't seem very
4276  * helpful.)
4277  */
4278  if (*newval < 4)
4279  *newval = 4;
4280 
4281  return true;
4282 }
static int XLOGChooseNumBuffers(void)
Definition: xlog.c:4237
int XLOGbuffers
Definition: xlog.c:120

References newval, XLOGbuffers, and XLOGChooseNumBuffers().

◆ check_wal_consistency_checking()

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

Definition at line 4288 of file xlog.c.

4289 {
4290  char *rawstring;
4291  List *elemlist;
4292  ListCell *l;
4293  bool newwalconsistency[RM_MAX_ID + 1];
4294 
4295  /* Initialize the array */
4296  MemSet(newwalconsistency, 0, (RM_MAX_ID + 1) * sizeof(bool));
4297 
4298  /* Need a modifiable copy of string */
4299  rawstring = pstrdup(*newval);
4300 
4301  /* Parse string into list of identifiers */
4302  if (!SplitIdentifierString(rawstring, ',', &elemlist))
4303  {
4304  /* syntax error in list */
4305  GUC_check_errdetail("List syntax is invalid.");
4306  pfree(rawstring);
4307  list_free(elemlist);
4308  return false;
4309  }
4310 
4311  foreach(l, elemlist)
4312  {
4313  char *tok = (char *) lfirst(l);
4314  int rmid;
4315 
4316  /* Check for 'all'. */
4317  if (pg_strcasecmp(tok, "all") == 0)
4318  {
4319  for (rmid = 0; rmid <= RM_MAX_ID; rmid++)
4320  if (RmgrIdExists(rmid) && GetRmgr(rmid).rm_mask != NULL)
4321  newwalconsistency[rmid] = true;
4322  }
4323  else
4324  {
4325  /* Check if the token matches any known resource manager. */
4326  bool found = false;
4327 
4328  for (rmid = 0; rmid <= RM_MAX_ID; rmid++)
4329  {
4330  if (RmgrIdExists(rmid) && GetRmgr(rmid).rm_mask != NULL &&
4331  pg_strcasecmp(tok, GetRmgr(rmid).rm_name) == 0)
4332  {
4333  newwalconsistency[rmid] = true;
4334  found = true;
4335  break;
4336  }
4337  }
4338  if (!found)
4339  {
4340  /*
4341  * During startup, it might be a not-yet-loaded custom
4342  * resource manager. Defer checking until
4343  * InitializeWalConsistencyChecking().
4344  */
4346  {
4348  }
4349  else
4350  {
4351  GUC_check_errdetail("Unrecognized key word: \"%s\".", tok);
4352  pfree(rawstring);
4353  list_free(elemlist);
4354  return false;
4355  }
4356  }
4357  }
4358  }
4359 
4360  pfree(rawstring);
4361  list_free(elemlist);
4362 
4363  /* assign new value */
4364  *extra = guc_malloc(ERROR, (RM_MAX_ID + 1) * sizeof(bool));
4365  memcpy(*extra, newwalconsistency, (RM_MAX_ID + 1) * sizeof(bool));
4366  return true;
4367 }
#define ERROR
Definition: elog.h:39
void * guc_malloc(int elevel, size_t size)
Definition: guc.c:631
#define GUC_check_errdetail
Definition: guc.h:437
void list_free(List *list)
Definition: list.c:1545
char * pstrdup(const char *in)
Definition: mcxt.c:1624
bool process_shared_preload_libraries_done
Definition: miscinit.c:1783
#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:3454
static bool check_wal_consistency_checking_deferred
Definition: xlog.c:169
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().

◆ CheckPointGuts()

static void CheckPointGuts ( XLogRecPtr  checkPointRedo,
int  flags 
)
static

Definition at line 6996 of file xlog.c.

6997 {
7003 
7004  /* Write out all dirty data in SLRUs and the main buffer pool */
7005  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_START(flags);
7007  CheckPointCLOG();
7012  CheckPointBuffers(flags);
7013 
7014  /* Perform all queued up fsyncs */
7015  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_SYNC_START();
7019  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_DONE();
7020 
7021  /* We deliberately delay 2PC checkpointing as long as possible */
7022  CheckPointTwoPhase(checkPointRedo);
7023 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1582
void CheckPointBuffers(int flags)
Definition: bufmgr.c:2787
void CheckPointCLOG(void)
Definition: clog.c:817
void CheckPointCommitTs(void)
Definition: commit_ts.c:774
void CheckPointMultiXact(void)
Definition: multixact.c:2155
void CheckPointReplicationOrigin(void)
Definition: origin.c:573
void CheckPointPredicate(void)
Definition: predicate.c:1005
void CheckPointRelationMap(void)
Definition: relmapper.c:611
void CheckPointLogicalRewriteHeap(void)
Definition: rewriteheap.c:1189
void CheckPointReplicationSlots(void)
Definition: slot.c:1444
void CheckPointSnapBuild(void)
Definition: snapbuild.c:2046
TimestampTz ckpt_write_t
Definition: xlog.h:157
TimestampTz ckpt_sync_end_t
Definition: xlog.h:159
TimestampTz ckpt_sync_t
Definition: xlog.h:158
void CheckPointSUBTRANS(void)
Definition: subtrans.c:284
void ProcessSyncRequests(void)
Definition: sync.c:293
void CheckPointTwoPhase(XLogRecPtr redo_horizon)
Definition: twophase.c:1793
CheckpointStatsData CheckpointStats
Definition: xlog.c:212

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

4978 {
4979  /*
4980  * For archive recovery, the WAL must be generated with at least 'replica'
4981  * wal_level.
4982  */
4984  {
4985  ereport(FATAL,
4986  (errmsg("WAL was generated with wal_level=minimal, cannot continue recovering"),
4987  errdetail("This happens if you temporarily set wal_level=minimal on the server."),
4988  errhint("Use a backup taken after setting wal_level to higher than minimal.")));
4989  }
4990 
4991  /*
4992  * For Hot Standby, the WAL must be generated with 'replica' mode, and we
4993  * must have at least as many backend slots as the primary.
4994  */
4996  {
4997  /* We ignore autovacuum_max_workers when we make this test. */
4998  RecoveryRequiresIntParameter("max_connections",
5001  RecoveryRequiresIntParameter("max_worker_processes",
5004  RecoveryRequiresIntParameter("max_wal_senders",
5007  RecoveryRequiresIntParameter("max_prepared_transactions",
5010  RecoveryRequiresIntParameter("max_locks_per_transaction",
5013  }
5014 }
int errdetail(const char *fmt,...)
Definition: elog.c:1202
int errhint(const char *fmt,...)
Definition: elog.c:1316
#define FATAL
Definition: elog.h:41
int MaxConnections
Definition: globals.c:137
int max_worker_processes
Definition: globals.c:138
int max_locks_per_xact
Definition: lock.c:55
int max_worker_processes
Definition: pg_control.h:179
int max_locks_per_xact
Definition: pg_control.h:182
int max_prepared_xacts
Definition: pg_control.h:181
int max_prepared_xacts
Definition: twophase.c:117
int max_wal_senders
Definition: walsender.c:122
bool EnableHotStandby
Definition: xlog.c:124
@ WAL_LEVEL_MINIMAL
Definition: xlog.h:69
bool ArchiveRecoveryRequested
Definition: xlogrecovery.c:137
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 3435 of file xlog.c.

3436 {
3437  int save_errno = errno;
3438  XLogSegNo lastRemovedSegNo;
3439 
3441  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3443 
3444  if (segno <= lastRemovedSegNo)
3445  {
3446  char filename[MAXFNAMELEN];
3447 
3448  XLogFileName(filename, tli, segno, wal_segment_size);
3449  errno = save_errno;
3450  ereport(ERROR,
3452  errmsg("requested WAL segment %s has already been removed",
3453  filename)));
3454  }
3455  errno = save_errno;
3456 }
static char * filename
Definition: pg_dumpall.c:119
XLogSegNo lastRemovedSegNo
Definition: xlog.c:470
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 4888 of file xlog.c.

4890 {
4891  /*
4892  * Execute the recovery_end_command, if any.
4893  */
4894  if (recoveryEndCommand && strcmp(recoveryEndCommand, "") != 0)
4896  "recovery_end_command",
4897  true,
4899 
4900  /*
4901  * We switched to a new timeline. Clean up segments on the old timeline.
4902  *
4903  * If there are any higher-numbered segments on the old timeline, remove
4904  * them. They might contain valid WAL, but they might also be
4905  * pre-allocated files containing garbage. In any case, they are not part
4906  * of the new timeline's history so we don't need them.
4907  */
4908  RemoveNonParentXlogFiles(EndOfLog, newTLI);
4909 
4910  /*
4911  * If the switch happened in the middle of a segment, what to do with the
4912  * last, partial segment on the old timeline? If we don't archive it, and
4913  * the server that created the WAL never archives it either (e.g. because
4914  * it was hit by a meteor), it will never make it to the archive. That's
4915  * OK from our point of view, because the new segment that we created with
4916  * the new TLI contains all the WAL from the old timeline up to the switch
4917  * point. But if you later try to do PITR to the "missing" WAL on the old
4918  * timeline, recovery won't find it in the archive. It's physically
4919  * present in the new file with new TLI, but recovery won't look there
4920  * when it's recovering to the older timeline. On the other hand, if we
4921  * archive the partial segment, and the original server on that timeline
4922  * is still running and archives the completed version of the same segment
4923  * later, it will fail. (We used to do that in 9.4 and below, and it
4924  * caused such problems).
4925  *
4926  * As a compromise, we rename the last segment with the .partial suffix,
4927  * and archive it. Archive recovery will never try to read .partial
4928  * segments, so they will normally go unused. But in the odd PITR case,
4929  * the administrator can copy them manually to the pg_wal directory
4930  * (removing the suffix). They can be useful in debugging, too.
4931  *
4932  * If a .done or .ready file already exists for the old timeline, however,
4933  * we had already determined that the segment is complete, so we can let
4934  * it be archived normally. (In particular, if it was restored from the
4935  * archive to begin with, it's expected to have a .done file).
4936  */
4937  if (XLogSegmentOffset(EndOfLog, wal_segment_size) != 0 &&
4939  {
4940  char origfname[MAXFNAMELEN];
4941  XLogSegNo endLogSegNo;
4942 
4943  XLByteToPrevSeg(EndOfLog, endLogSegNo, wal_segment_size);
4944  XLogFileName(origfname, EndOfLogTLI, endLogSegNo, wal_segment_size);
4945 
4946  if (!XLogArchiveIsReadyOrDone(origfname))
4947  {
4948  char origpath[MAXPGPATH];
4949  char partialfname[MAXFNAMELEN];
4950  char partialpath[MAXPGPATH];
4951 
4952  XLogFilePath(origpath, EndOfLogTLI, endLogSegNo, wal_segment_size);
4953  snprintf(partialfname, MAXFNAMELEN, "%s.partial", origfname);
4954  snprintf(partialpath, MAXPGPATH, "%s.partial", origpath);
4955 
4956  /*
4957  * Make sure there's no .done or .ready file for the .partial
4958  * file.
4959  */
4960  XLogArchiveCleanup(partialfname);
4961 
4962  durable_rename(origpath, partialpath, ERROR);
4963  XLogArchiveNotify(partialfname);
4964  }
4965  }
4966 }
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:688
#define MAXPGPATH
#define snprintf
Definition: port.h:238
@ WAIT_EVENT_RECOVERY_END_COMMAND
Definition: wait_event.h:125
void RemoveNonParentXlogFiles(XLogRecPtr switchpoint, TimeLineID newTLI)
Definition: xlog.c:3610
#define XLogArchivingActive()
Definition: xlog.h:94
#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:658
void ExecuteRecoveryCommand(const char *command, const char *commandName, bool failOnSignal, uint32 wait_event_info)
Definition: xlogarchive.c:289
void XLogArchiveNotify(const char *xlog)
Definition: xlogarchive.c:438
void XLogArchiveCleanup(const char *xlog)
Definition: xlogarchive.c:706
char * recoveryEndCommand
Definition: xlogrecovery.c:83

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

Referenced by StartupXLOG().

◆ CleanupBackupHistory()

static void CleanupBackupHistory ( void  )
static

Definition at line 3808 of file xlog.c.

3809 {
3810  DIR *xldir;
3811  struct dirent *xlde;
3812  char path[MAXPGPATH + sizeof(XLOGDIR)];
3813 
3814  xldir = AllocateDir(XLOGDIR);
3815 
3816  while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
3817  {
3818  if (IsBackupHistoryFileName(xlde->d_name))
3819  {
3820  if (XLogArchiveCheckDone(xlde->d_name))
3821  {
3822  elog(DEBUG2, "removing WAL backup history file \"%s\"",
3823  xlde->d_name);
3824  snprintf(path, sizeof(path), XLOGDIR "/%s", xlde->d_name);
3825  unlink(path);
3826  XLogArchiveCleanup(xlde->d_name);
3827  }
3828  }
3829  }
3830 
3831  FreeDir(xldir);
3832 }
#define DEBUG2
Definition: elog.h:29
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2710
int FreeDir(DIR *dir)
Definition: fd.c:2762
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2644
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:559

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

1163 {
1164  char *currpos;
1165  int freespace;
1166  int written;
1167  XLogRecPtr CurrPos;
1168  XLogPageHeader pagehdr;
1169 
1170  /*
1171  * Get a pointer to the right place in the right WAL buffer to start
1172  * inserting to.
1173  */
1174  CurrPos = StartPos;
1175  currpos = GetXLogBuffer(CurrPos, tli);
1176  freespace = INSERT_FREESPACE(CurrPos);
1177 
1178  /*
1179  * there should be enough space for at least the first field (xl_tot_len)
1180  * on this page.
1181  */
1182  Assert(freespace >= sizeof(uint32));
1183 
1184  /* Copy record data */
1185  written = 0;
1186  while (rdata != NULL)
1187  {
1188  char *rdata_data = rdata->data;
1189  int rdata_len = rdata->len;
1190 
1191  while (rdata_len > freespace)
1192  {
1193  /*
1194  * Write what fits on this page, and continue on the next page.
1195  */
1196  Assert(CurrPos % XLOG_BLCKSZ >= SizeOfXLogShortPHD || freespace == 0);
1197  memcpy(currpos, rdata_data, freespace);
1198  rdata_data += freespace;
1199  rdata_len -= freespace;
1200  written += freespace;
1201  CurrPos += freespace;
1202 
1203  /*
1204  * Get pointer to beginning of next page, and set the xlp_rem_len
1205  * in the page header. Set XLP_FIRST_IS_CONTRECORD.
1206  *
1207  * It's safe to set the contrecord flag and xlp_rem_len without a
1208  * lock on the page. All the other flags were already set when the
1209  * page was initialized, in AdvanceXLInsertBuffer, and we're the
1210  * only backend that needs to set the contrecord flag.
1211  */
1212  currpos = GetXLogBuffer(CurrPos, tli);
1213  pagehdr = (XLogPageHeader) currpos;
1214  pagehdr->xlp_rem_len = write_len - written;
1215  pagehdr->xlp_info |= XLP_FIRST_IS_CONTRECORD;
1216 
1217  /* skip over the page header */
1218  if (XLogSegmentOffset(CurrPos, wal_segment_size) == 0)
1219  {
1220  CurrPos += SizeOfXLogLongPHD;
1221  currpos += SizeOfXLogLongPHD;
1222  }
1223  else
1224  {
1225  CurrPos += SizeOfXLogShortPHD;
1226  currpos += SizeOfXLogShortPHD;
1227  }
1228  freespace = INSERT_FREESPACE(CurrPos);
1229  }
1230 
1231  Assert(CurrPos % XLOG_BLCKSZ >= SizeOfXLogShortPHD || rdata_len == 0);
1232  memcpy(currpos, rdata_data, rdata_len);
1233  currpos += rdata_len;
1234  CurrPos += rdata_len;
1235  freespace -= rdata_len;
1236  written += rdata_len;
1237 
1238  rdata = rdata->next;
1239  }
1240  Assert(written == write_len);
1241 
1242  /*
1243  * If this was an xlog-switch, it's not enough to write the switch record,
1244  * we also have to consume all the remaining space in the WAL segment. We
1245  * have already reserved that space, but we need to actually fill it.
1246  */
1247  if (isLogSwitch && XLogSegmentOffset(CurrPos, wal_segment_size) != 0)
1248  {
1249  /* An xlog-switch record doesn't contain any data besides the header */
1250  Assert(write_len == SizeOfXLogRecord);
1251 
1252  /* Assert that we did reserve the right amount of space */
1253  Assert(XLogSegmentOffset(EndPos, wal_segment_size) == 0);
1254 
1255  /* Use up all the remaining space on the current page */
1256  CurrPos += freespace;
1257 
1258  /*
1259  * Cause all remaining pages in the segment to be flushed, leaving the
1260  * XLog position where it should be, at the start of the next segment.
1261  * We do this one page at a time, to make sure we don't deadlock
1262  * against ourselves if wal_buffers < wal_segment_size.
1263  */
1264  while (CurrPos < EndPos)
1265  {
1266  /*
1267  * The minimal action to flush the page would be to call
1268  * WALInsertLockUpdateInsertingAt(CurrPos) followed by
1269  * AdvanceXLInsertBuffer(...). The page would be left initialized
1270  * mostly to zeros, except for the page header (always the short
1271  * variant, as this is never a segment's first page).
1272  *
1273  * The large vistas of zeros are good for compressibility, but the
1274  * headers interrupting them every XLOG_BLCKSZ (with values that
1275  * differ from page to page) are not. The effect varies with
1276  * compression tool, but bzip2 for instance compresses about an
1277  * order of magnitude worse if those headers are left in place.
1278  *
1279  * Rather than complicating AdvanceXLInsertBuffer itself (which is
1280  * called in heavily-loaded circumstances as well as this lightly-
1281  * loaded one) with variant behavior, we just use GetXLogBuffer
1282  * (which itself calls the two methods we need) to get the pointer
1283  * and zero most of the page. Then we just zero the page header.
1284  */
1285  currpos = GetXLogBuffer(CurrPos, tli);
1286  MemSet(currpos, 0, SizeOfXLogShortPHD);
1287 
1288  CurrPos += XLOG_BLCKSZ;
1289  }
1290  }
1291  else
1292  {
1293  /* Align the end position, so that the next record starts aligned */
1294  CurrPos = MAXALIGN64(CurrPos);
1295  }
1296 
1297  if (CurrPos != EndPos)
1298  elog(PANIC, "space reserved for WAL record does not match what was written");
1299 }
unsigned int uint32
Definition: c.h:490
#define MAXALIGN64(LEN)
Definition: c.h:820
struct XLogRecData * next
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:576
static char * GetXLogBuffer(XLogRecPtr ptr, TimeLineID tli)
Definition: xlog.c:1537
#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 6436 of file xlog.c.

6437 {
6438  bool shutdown;
6439  CheckPoint checkPoint;
6440  XLogRecPtr recptr;
6441  XLogSegNo _logSegNo;
6443  uint32 freespace;
6444  XLogRecPtr PriorRedoPtr;
6445  XLogRecPtr curInsert;
6446  XLogRecPtr last_important_lsn;
6447  VirtualTransactionId *vxids;
6448  int nvxids;
6449  int oldXLogAllowed = 0;
6450 
6451  /*
6452  * An end-of-recovery checkpoint is really a shutdown checkpoint, just
6453  * issued at a different time.
6454  */
6456  shutdown = true;
6457  else
6458  shutdown = false;
6459 
6460  /* sanity check */
6461  if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
6462  elog(ERROR, "can't create a checkpoint during recovery");
6463 
6464  /*
6465  * Prepare to accumulate statistics.
6466  *
6467  * Note: because it is possible for log_checkpoints to change while a
6468  * checkpoint proceeds, we always accumulate stats, even if
6469  * log_checkpoints is currently off.
6470  */
6471  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
6473 
6474  /*
6475  * Let smgr prepare for checkpoint; this has to happen outside the
6476  * critical section and before we determine the REDO pointer. Note that
6477  * smgr must not do anything that'd have to be undone if we decide no
6478  * checkpoint is needed.
6479  */
6481 
6482  /*
6483  * Use a critical section to force system panic if we have trouble.
6484  */
6486 
6487  if (shutdown)
6488  {
6489  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6492  LWLockRelease(ControlFileLock);
6493  }
6494 
6495  /* Begin filling in the checkpoint WAL record */
6496  MemSet(&checkPoint, 0, sizeof(checkPoint));
6497  checkPoint.time = (pg_time_t) time(NULL);
6498 
6499  /*
6500  * For Hot Standby, derive the oldestActiveXid before we fix the redo
6501  * pointer. This allows us to begin accumulating changes to assemble our
6502  * starting snapshot of locks and transactions.
6503  */
6504  if (!shutdown && XLogStandbyInfoActive())
6506  else
6508 
6509  /*
6510  * Get location of last important record before acquiring insert locks (as
6511  * GetLastImportantRecPtr() also locks WAL locks).
6512  */
6513  last_important_lsn = GetLastImportantRecPtr();
6514 
6515  /*
6516  * We must block concurrent insertions while examining insert state to
6517  * determine the checkpoint REDO pointer.
6518  */
6520  curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
6521 
6522  /*
6523  * If this isn't a shutdown or forced checkpoint, and if there has been no
6524  * WAL activity requiring a checkpoint, skip it. The idea here is to
6525  * avoid inserting duplicate checkpoints when the system is idle.
6526  */
6528  CHECKPOINT_FORCE)) == 0)
6529  {
6530  if (last_important_lsn == ControlFile->checkPoint)
6531  {
6533  END_CRIT_SECTION();
6534  ereport(DEBUG1,
6535  (errmsg_internal("checkpoint skipped because system is idle")));
6536  return;
6537  }
6538  }
6539 
6540  /*
6541  * An end-of-recovery checkpoint is created before anyone is allowed to
6542  * write WAL. To allow us to write the checkpoint record, temporarily
6543  * enable XLogInsertAllowed.
6544  */
6545  if (flags & CHECKPOINT_END_OF_RECOVERY)
6546  oldXLogAllowed = LocalSetXLogInsertAllowed();
6547 
6548  checkPoint.ThisTimeLineID = XLogCtl->InsertTimeLineID;
6549  if (flags & CHECKPOINT_END_OF_RECOVERY)
6550  checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
6551  else
6552  checkPoint.PrevTimeLineID = checkPoint.ThisTimeLineID;
6553 
6554  checkPoint.fullPageWrites = Insert->fullPageWrites;
6555 
6556  /*
6557  * Compute new REDO record ptr = location of next XLOG record.
6558  *
6559  * NB: this is NOT necessarily where the checkpoint record itself will be,
6560  * since other backends may insert more XLOG records while we're off doing
6561  * the buffer flush work. Those XLOG records are logically after the
6562  * checkpoint, even though physically before it. Got that?
6563  */
6564  freespace = INSERT_FREESPACE(curInsert);
6565  if (freespace == 0)
6566  {
6567  if (XLogSegmentOffset(curInsert, wal_segment_size) == 0)
6568  curInsert += SizeOfXLogLongPHD;
6569  else
6570  curInsert += SizeOfXLogShortPHD;
6571  }
6572  checkPoint.redo = curInsert;
6573 
6574  /*
6575  * Here we update the shared RedoRecPtr for future XLogInsert calls; this
6576  * must be done while holding all the insertion locks.
6577  *
6578  * Note: if we fail to complete the checkpoint, RedoRecPtr will be left
6579  * pointing past where it really needs to point. This is okay; the only
6580  * consequence is that XLogInsert might back up whole buffers that it
6581  * didn't really need to. We can't postpone advancing RedoRecPtr because
6582  * XLogInserts that happen while we are dumping buffers must assume that
6583  * their buffer changes are not included in the checkpoint.
6584  */
6585  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
6586 
6587  /*
6588  * Now we can release the WAL insertion locks, allowing other xacts to
6589  * proceed while we are flushing disk buffers.
6590  */
6592 
6593  /* Update the info_lck-protected copy of RedoRecPtr as well */
6595  XLogCtl->RedoRecPtr = checkPoint.redo;
6597 
6598  /*
6599  * If enabled, log checkpoint start. We postpone this until now so as not
6600  * to log anything if we decided to skip the checkpoint.
6601  */
6602  if (log_checkpoints)
6603  LogCheckpointStart(flags, false);
6604 
6605  /* Update the process title */
6606  update_checkpoint_display(flags, false, false);
6607 
6608  TRACE_POSTGRESQL_CHECKPOINT_START(flags);
6609 
6610  /*
6611  * Get the other info we need for the checkpoint record.
6612  *
6613  * We don't need to save oldestClogXid in the checkpoint, it only matters
6614  * for the short period in which clog is being truncated, and if we crash
6615  * during that we'll redo the clog truncation and fix up oldestClogXid
6616  * there.
6617  */
6618  LWLockAcquire(XidGenLock, LW_SHARED);
6619  checkPoint.nextXid = ShmemVariableCache->nextXid;
6620  checkPoint.oldestXid = ShmemVariableCache->oldestXid;
6622  LWLockRelease(XidGenLock);
6623 
6624  LWLockAcquire(CommitTsLock, LW_SHARED);
6627  LWLockRelease(CommitTsLock);
6628 
6629  LWLockAcquire(OidGenLock, LW_SHARED);
6630  checkPoint.nextOid = ShmemVariableCache->nextOid;
6631  if (!shutdown)
6632  checkPoint.nextOid += ShmemVariableCache->oidCount;
6633  LWLockRelease(OidGenLock);
6634 
6635  MultiXactGetCheckptMulti(shutdown,
6636  &checkPoint.nextMulti,
6637  &checkPoint.nextMultiOffset,
6638  &checkPoint.oldestMulti,
6639  &checkPoint.oldestMultiDB);
6640 
6641  /*
6642  * Having constructed the checkpoint record, ensure all shmem disk buffers
6643  * and commit-log buffers are flushed to disk.
6644  *
6645  * This I/O could fail for various reasons. If so, we will fail to
6646  * complete the checkpoint, but there is no reason to force a system
6647  * panic. Accordingly, exit critical section while doing it.
6648  */
6649  END_CRIT_SECTION();
6650 
6651  /*
6652  * In some cases there are groups of actions that must all occur on one
6653  * side or the other of a checkpoint record. Before flushing the
6654  * checkpoint record we must explicitly wait for any backend currently
6655  * performing those groups of actions.
6656  *
6657  * One example is end of transaction, so we must wait for any transactions
6658  * that are currently in commit critical sections. If an xact inserted
6659  * its commit record into XLOG just before the REDO point, then a crash
6660  * restart from the REDO point would not replay that record, which means
6661  * that our flushing had better include the xact's update of pg_xact. So
6662  * we wait till he's out of his commit critical section before proceeding.
6663  * See notes in RecordTransactionCommit().
6664  *
6665  * Because we've already released the insertion locks, this test is a bit
6666  * fuzzy: it is possible that we will wait for xacts we didn't really need
6667  * to wait for. But the delay should be short and it seems better to make
6668  * checkpoint take a bit longer than to hold off insertions longer than
6669  * necessary. (In fact, the whole reason we have this issue is that xact.c
6670  * does commit record XLOG insertion and clog update as two separate steps
6671  * protected by different locks, but again that seems best on grounds of
6672  * minimizing lock contention.)
6673  *
6674  * A transaction that has not yet set delayChkptFlags when we look cannot
6675  * be at risk, since it has not inserted its commit record yet; and one
6676  * that's already cleared it is not at risk either, since it's done fixing
6677  * clog and we will correctly flush the update below. So we cannot miss
6678  * any xacts we need to wait for.
6679  */
6681  if (nvxids > 0)
6682  {
6683  do
6684  {
6685  pg_usleep(10000L); /* wait for 10 msec */
6686  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids,
6688  }
6689  pfree(vxids);
6690 
6691  CheckPointGuts(checkPoint.redo, flags);
6692 
6694  if (nvxids > 0)
6695  {
6696  do
6697  {
6698  pg_usleep(10000L); /* wait for 10 msec */
6699  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids,
6701  }
6702  pfree(vxids);
6703 
6704  /*
6705  * Take a snapshot of running transactions and write this to WAL. This
6706  * allows us to reconstruct the state of running transactions during
6707  * archive recovery, if required. Skip, if this info disabled.
6708  *
6709  * If we are shutting down, or Startup process is completing crash
6710  * recovery we don't need to write running xact data.
6711  */
6712  if (!shutdown && XLogStandbyInfoActive())
6714 
6716 
6717  /*
6718  * Now insert the checkpoint record into XLOG.
6719  */
6720  XLogBeginInsert();
6721  XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));
6722  recptr = XLogInsert(RM_XLOG_ID,
6723  shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
6725 
6726  XLogFlush(recptr);
6727 
6728  /*
6729  * We mustn't write any new WAL after a shutdown checkpoint, or it will be
6730  * overwritten at next startup. No-one should even try, this just allows
6731  * sanity-checking. In the case of an end-of-recovery checkpoint, we want
6732  * to just temporarily disable writing until the system has exited
6733  * recovery.
6734  */
6735  if (shutdown)
6736  {
6737  if (flags & CHECKPOINT_END_OF_RECOVERY)
6738  LocalXLogInsertAllowed = oldXLogAllowed;
6739  else
6740  LocalXLogInsertAllowed = 0; /* never again write WAL */
6741  }
6742 
6743  /*
6744  * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
6745  * = end of actual checkpoint record.
6746  */
6747  if (shutdown && checkPoint.redo != ProcLastRecPtr)
6748  ereport(PANIC,
6749  (errmsg("concurrent write-ahead log activity while database system is shutting down")));
6750 
6751  /*
6752  * Remember the prior checkpoint's redo ptr for
6753  * UpdateCheckPointDistanceEstimate()
6754  */
6755  PriorRedoPtr = ControlFile->checkPointCopy.redo;
6756 
6757  /*
6758  * Update the control file.
6759  */
6760  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6761  if (shutdown)
6764  ControlFile->checkPointCopy = checkPoint;
6765  /* crash recovery should always recover to the end of WAL */
6768 
6769  /*
6770  * Persist unloggedLSN value. It's reset on crash recovery, so this goes
6771  * unused on non-shutdown checkpoints, but seems useful to store it always
6772  * for debugging purposes.
6773  */
6777 
6779  LWLockRelease(ControlFileLock);
6780 
6781  /* Update shared-memory copy of checkpoint XID/epoch */
6783  XLogCtl->ckptFullXid = checkPoint.nextXid;
6785 
6786  /*
6787  * We are now done with critical updates; no need for system panic if we
6788  * have trouble while fooling with old log segments.
6789  */
6790  END_CRIT_SECTION();
6791 
6792  /*
6793  * Let smgr do post-checkpoint cleanup (eg, deleting old files).
6794  */
6796 
6797  /*
6798  * Update the average distance between checkpoints if the prior checkpoint
6799  * exists.
6800  */
6801  if (PriorRedoPtr != InvalidXLogRecPtr)
6803 
6804  /*
6805  * Delete old log files, those no longer needed for last checkpoint to
6806  * prevent the disk holding the xlog from growing full.
6807  */
6809  KeepLogSeg(recptr, &_logSegNo);
6810  if (InvalidateObsoleteReplicationSlots(_logSegNo))
6811  {
6812  /*
6813  * Some slots have been invalidated; recalculate the old-segment
6814  * horizon, starting again from RedoRecPtr.
6815  */
6817  KeepLogSeg(recptr, &_logSegNo);
6818  }
6819  _logSegNo--;
6820  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr,
6821  checkPoint.ThisTimeLineID);
6822 
6823  /*
6824  * Make more log segments if needed. (Do this after recycling old log
6825  * segments, since that may supply some of the needed files.)
6826  */
6827  if (!shutdown)
6828  PreallocXlogFiles(recptr, checkPoint.ThisTimeLineID);
6829 
6830  /*
6831  * Truncate pg_subtrans if possible. We can throw away all data before
6832  * the oldest XMIN of any running transaction. No future transaction will
6833  * attempt to reference any pg_subtrans entry older than that (see Asserts
6834  * in subtrans.c). During recovery, though, we mustn't do this because
6835  * StartupSUBTRANS hasn't been called yet.
6836  */
6837  if (!RecoveryInProgress())
6839 
6840  /* Real work is done; log and update stats. */
6841  LogCheckpointEnd(false);
6842 
6843  /* Reset the process title */
6844  update_checkpoint_display(flags, false, true);
6845 
6846  TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
6847  NBuffers,
6851 }
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1156
int NBuffers
Definition: globals.c:136
@ LW_SHARED
Definition: lwlock.h:116
#define START_CRIT_SECTION()
Definition: miscadmin.h:148
#define END_CRIT_SECTION()
Definition: miscadmin.h:150
void MultiXactGetCheckptMulti(bool is_shutdown, MultiXactId *nextMulti, MultiXactOffset *nextMultiOffset, MultiXactId *oldestMulti, Oid *oldestMultiDB)
Definition: multixact.c:2133
@ DB_SHUTDOWNING
Definition: pg_control.h:92
@ DB_SHUTDOWNED
Definition: pg_control.h:90
#define XLOG_CHECKPOINT_ONLINE
Definition: pg_control.h:68
#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:3090
TransactionId GetOldestActiveTransactionId(void)
Definition: procarray.c:2927
TransactionId GetOldestTransactionIdConsideredRunning(void)
Definition: procarray.c:2063
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)
Definition: procarray.c:3136
void pg_usleep(long microsec)
Definition: signal.c:53
bool InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno)
Definition: slot.c:1401
XLogRecPtr LogStandbySnapshot(void)
Definition: standby.c:1264
TimestampTz ckpt_start_t
Definition: xlog.h:156
int ckpt_segs_removed
Definition: xlog.h:165
int ckpt_segs_added
Definition: xlog.h:164
int ckpt_bufs_written
Definition: xlog.h:162
int ckpt_segs_recycled
Definition: xlog.h:166
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
XLogRecPtr unloggedLSN
Definition: pg_control.h:135
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
TransactionId newestCommitTsXid
Definition: transam.h:233
TransactionId oldestXid
Definition: transam.h:222
TransactionId oldestCommitTsXid
Definition: transam.h:232
FullTransactionId ckptFullXid
Definition: xlog.c:466
TimeLineID InsertTimeLineID
Definition: xlog.c:515
slock_t ulsn_lck
Definition: xlog.c:474
XLogRecPtr RedoRecPtr
Definition: xlog.c:465
XLogRecPtr unloggedLSN
Definition: xlog.c:473
TimeLineID PrevTimeLineID
Definition: xlog.c:516
XLogRecPtr RedoRecPtr
Definition: xlog.c:439
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:338
void SyncPreCheckpoint(void)
Definition: sync.c:184
void SyncPostCheckpoint(void)
Definition: sync.c:209
XLogRecPtr ProcLastRecPtr
Definition: xlog.c:256
bool RecoveryInProgress(void)
Definition: xlog.c:5908
static void WALInsertLockRelease(void)
Definition: xlog.c:1379
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1648
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1350
static void UpdateControlFile(void)
Definition: xlog.c:4168
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr, TimeLineID insertTLI)
Definition: xlog.c:3536
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:6206
static XLogRecPtr RedoRecPtr
Definition: xlog.c:276
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:6238
static void PreallocXlogFiles(XLogRecPtr endptr, TimeLineID tli)
Definition: xlog.c:3398
bool log_checkpoints
Definition: xlog.c:132
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:7431
static int LocalSetXLogInsertAllowed(void)
Definition: xlog.c:5996
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:6113
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:6341
static int LocalXLogInsertAllowed
Definition: xlog.c:239
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2514
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:6996
static void update_checkpoint_display(int flags, bool restartpoint, bool reset)
Definition: xlog.c:6379
#define CHECKPOINT_END_OF_RECOVERY
Definition: xlog.h:135
#define CHECKPOINT_FORCE
Definition: xlog.h:137
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:134
#define XLogStandbyInfoActive()
Definition: xlog.h:118
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)
void XLogRegisterData(char *data, uint32 len)
Definition: xloginsert.c:351
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:451
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(), InvalidTransactionId, InvalidXLogRecPtr, KeepLogSeg(), LocalSetXLogInsertAllowed(), LocalXLogInsertAllowed, log_checkpoints, LogCheckpointEnd(), LogCheckpointStart(), LogStandbySnapshot(), LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockRelease(), MemSet, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, MultiXactGetCheckptMulti(), NBuffers, VariableCacheData::newestCommitTsXid, CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, VariableCacheData::nextOid, CheckPoint::nextOid, VariableCacheData::nextXid, CheckPoint::nextXid, VariableCacheData::oidCount, CheckPoint::oldestActiveXid, VariableCacheData::oldestCommitTsXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, VariableCacheData::oldestXid, CheckPoint::oldestXid, VariableCacheData::oldestXidDB, CheckPoint::oldestXidDB, PANIC, pfree(), pg_usleep(), PreallocXlogFiles(), XLogCtlData::PrevTimeLineID, CheckPoint::PrevTimeLineID, ProcLastRecPtr, RecoveryInProgress(), CheckPoint::redo, RedoRecPtr, XLogCtlInsert::RedoRecPtr, XLogCtlData::RedoRecPtr, RemoveOldXlogFiles(), ShmemVariableCache, SizeOfXLogLongPHD, SizeOfXLogShortPHD, SpinLockAcquire, SpinLockRelease, START_CRIT_SECTION, ControlFileData::state, SyncPostCheckpoint(), SyncPreCheckpoint(), CheckPoint::ThisTimeLineID, CheckPoint::time, TruncateSUBTRANS(), XLogCtlData::ulsn_lck, XLogCtlData::unloggedLSN, ControlFileData::unloggedLSN, update_checkpoint_display(), UpdateCheckPointDistanceEstimate(), UpdateControlFile(), wal_segment_size, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), XLByteToSeg, XLOG_CHECKPOINT_ONLINE, 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 6862 of file xlog.c.

6863 {
6864  xl_end_of_recovery xlrec;
6865  XLogRecPtr recptr;
6866 
6867  /* sanity check */
6868  if (!RecoveryInProgress())
6869  elog(ERROR, "can only be used to end recovery");
6870 
6871  xlrec.end_time = GetCurrentTimestamp();
6872 
6877 
6879 
6880  XLogBeginInsert();
6881  XLogRegisterData((char *) &xlrec, sizeof(xl_end_of_recovery));
6882  recptr = XLogInsert(RM_XLOG_ID, XLOG_END_OF_RECOVERY);
6883 
6884  XLogFlush(recptr);
6885 
6886  /*
6887  * Update the control file so that crash recovery can follow the timeline
6888  * changes to this point.
6889  */
6890  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6891  ControlFile->minRecoveryPoint = recptr;
6892  ControlFile->minRecoveryPointTLI = xlrec.ThisTimeLineID;
6894  LWLockRelease(ControlFileLock);
6895 
6896  END_CRIT_SECTION();
6897 }
#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 6926 of file xlog.c.

6928 {
6930  XLogRecPtr recptr;
6931  XLogPageHeader pagehdr;
6932  XLogRecPtr startPos;
6933 
6934  /* sanity checks */
6935  if (!RecoveryInProgress())
6936  elog(ERROR, "can only be used at end of recovery");
6937  if (pagePtr % XLOG_BLCKSZ != 0)
6938  elog(ERROR, "invalid position for missing continuation record %X/%X",
6939  LSN_FORMAT_ARGS(pagePtr));
6940 
6941  /* The current WAL insert position should be right after the page header */
6942  startPos = pagePtr;
6943  if (XLogSegmentOffset(startPos, wal_segment_size) == 0)
6944  startPos += SizeOfXLogLongPHD;
6945  else
6946  startPos += SizeOfXLogShortPHD;
6947  recptr = GetXLogInsertRecPtr();
6948  if (recptr != startPos)
6949  elog(ERROR, "invalid WAL insert position %X/%X for OVERWRITE_CONTRECORD",
6950  LSN_FORMAT_ARGS(recptr));
6951 
6953 
6954  /*
6955  * Initialize the XLOG page header (by GetXLogBuffer), and set the
6956  * XLP_FIRST_IS_OVERWRITE_CONTRECORD flag.
6957  *
6958  * No other backend is allowed to write WAL yet, so acquiring the WAL
6959  * insertion lock is just pro forma.
6960  */
6962  pagehdr = (XLogPageHeader) GetXLogBuffer(pagePtr, newTLI);
6965 
6966  /*
6967  * Insert the XLOG_OVERWRITE_CONTRECORD record as the first record on the
6968  * page. We know it becomes the first record, because no other backend is
6969  * allowed to write WAL yet.
6970  */
6971  XLogBeginInsert();
6972  xlrec.overwritten_lsn = aborted_lsn;
6974  XLogRegisterData((char *) &xlrec, sizeof(xl_overwrite_contrecord));
6975  recptr = XLogInsert(RM_XLOG_ID, XLOG_OVERWRITE_CONTRECORD);
6976 
6977  /* check that the record was inserted to the right place */
6978  if (ProcLastRecPtr != startPos)
6979  elog(ERROR, "OVERWRITE_CONTRECORD was inserted to unexpected position %X/%X",
6981 
6982  XLogFlush(recptr);
6983 
6984  END_CRIT_SECTION();
6985 
6986  return recptr;
6987 }
#define XLOG_OVERWRITE_CONTRECORD
Definition: pg_control.h:80
static void WALInsertLockAcquire(void)
Definition: xlog.c:1305
XLogRecPtr GetXLogInsertRecPtr(void)
Definition: xlog.c:8857
#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 7077 of file xlog.c.

7078 {
7079  XLogRecPtr lastCheckPointRecPtr;
7080  XLogRecPtr lastCheckPointEndPtr;
7081  CheckPoint lastCheckPoint;
7082  XLogRecPtr PriorRedoPtr;
7083  XLogRecPtr receivePtr;
7084  XLogRecPtr replayPtr;
7085  TimeLineID replayTLI;
7086  XLogRecPtr endptr;
7087  XLogSegNo _logSegNo;
7088  TimestampTz xtime;
7089 
7090  /* Concurrent checkpoint/restartpoint cannot happen */
7092 
7093  /* Get a local copy of the last safe checkpoint record. */
7095  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
7096  lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
7097  lastCheckPoint = XLogCtl->lastCheckPoint;
7099 
7100  /*
7101  * Check that we're still in recovery mode. It's ok if we exit recovery
7102  * mode after this check, the restart point is valid anyway.
7103  */
7104  if (!RecoveryInProgress())
7105  {
7106  ereport(DEBUG2,
7107  (errmsg_internal("skipping restartpoint, recovery has already ended")));
7108  return false;
7109  }
7110 
7111  /*
7112  * If the last checkpoint record we've replayed is already our last
7113  * restartpoint, we can't perform a new restart point. We still update
7114  * minRecoveryPoint in that case, so that if this is a shutdown restart
7115  * point, we won't start up earlier than before. That's not strictly
7116  * necessary, but when hot standby is enabled, it would be rather weird if
7117  * the database opened up for read-only connections at a point-in-time
7118  * before the last shutdown. Such time travel is still possible in case of
7119  * immediate shutdown, though.
7120  *
7121  * We don't explicitly advance minRecoveryPoint when we do create a
7122  * restartpoint. It's assumed that flushing the buffers will do that as a
7123  * side-effect.
7124  */
7125  if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
7126  lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
7127  {
7128  ereport(DEBUG2,
7129  (errmsg_internal("skipping restartpoint, already performed at %X/%X",
7130  LSN_FORMAT_ARGS(lastCheckPoint.redo))));
7131 
7133  if (flags & CHECKPOINT_IS_SHUTDOWN)
7134  {
7135  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7138  LWLockRelease(ControlFileLock);
7139  }
7140  return false;
7141  }
7142 
7143  /*
7144  * Update the shared RedoRecPtr so that the startup process can calculate
7145  * the number of segments replayed since last restartpoint, and request a
7146  * restartpoint if it exceeds CheckPointSegments.
7147  *
7148  * Like in CreateCheckPoint(), hold off insertions to update it, although
7149  * during recovery this is just pro forma, because no WAL insertions are
7150  * happening.
7151  */
7153  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
7155 
7156  /* Also update the info_lck-protected copy */
7158  XLogCtl->RedoRecPtr = lastCheckPoint.redo;
7160 
7161  /*
7162  * Prepare to accumulate statistics.
7163  *
7164  * Note: because it is possible for log_checkpoints to change while a
7165  * checkpoint proceeds, we always accumulate stats, even if
7166  * log_checkpoints is currently off.
7167  */
7168  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
7170 
7171  if (log_checkpoints)
7172  LogCheckpointStart(flags, true);
7173 
7174  /* Update the process title */
7175  update_checkpoint_display(flags, true, false);
7176 
7177  CheckPointGuts(lastCheckPoint.redo, flags);
7178 
7179  /*
7180  * Remember the prior checkpoint's redo ptr for
7181  * UpdateCheckPointDistanceEstimate()
7182  */
7183  PriorRedoPtr = ControlFile->checkPointCopy.redo;
7184 
7185  /*
7186  * Update pg_control, using current time. Check that it still shows an
7187  * older checkpoint, else do nothing; this is a quick hack to make sure
7188  * nothing really bad happens if somehow we get here after the
7189  * end-of-recovery checkpoint.
7190  */
7191  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7192  if (ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
7193  {
7194  /*
7195  * Update the checkpoint information. We do this even if the cluster
7196  * does not show DB_IN_ARCHIVE_RECOVERY to match with the set of WAL
7197  * segments recycled below.
7198  */
7199  ControlFile->checkPoint = lastCheckPointRecPtr;
7200  ControlFile->checkPointCopy = lastCheckPoint;
7201 
7202  /*
7203  * Ensure minRecoveryPoint is past the checkpoint record and update it
7204  * if the control file still shows DB_IN_ARCHIVE_RECOVERY. Normally,
7205  * this will have happened already while writing out dirty buffers,
7206  * but not necessarily - e.g. because no buffers were dirtied. We do
7207  * this because a backup performed in recovery uses minRecoveryPoint
7208  * to determine which WAL files must be included in the backup, and
7209  * the file (or files) containing the checkpoint record must be
7210  * included, at a minimum. Note that for an ordinary restart of
7211  * recovery there's no value in having the minimum recovery point any
7212  * earlier than this anyway, because redo will begin just after the
7213  * checkpoint record.
7214  */
7216  {
7217  if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
7218  {
7219  ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
7221 
7222  /* update local copy */
7225  }
7226  if (flags & CHECKPOINT_IS_SHUTDOWN)
7228  }
7230  }
7231  LWLockRelease(ControlFileLock);
7232 
7233  /*
7234  * Update the average distance between checkpoints/restartpoints if the
7235  * prior checkpoint exists.
7236  */
7237  if (PriorRedoPtr != InvalidXLogRecPtr)
7239 
7240  /*
7241  * Delete old log files, those no longer needed for last restartpoint to
7242  * prevent the disk holding the xlog from growing full.
7243  */
7245 
7246  /*
7247  * Retreat _logSegNo using the current end of xlog replayed or received,
7248  * whichever is later.
7249  */
7250  receivePtr = GetWalRcvFlushRecPtr(NULL, NULL);
7251  replayPtr = GetXLogReplayRecPtr(&replayTLI);
7252  endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
7253  KeepLogSeg(endptr, &_logSegNo);
7254  if (InvalidateObsoleteReplicationSlots(_logSegNo))
7255  {
7256  /*
7257  * Some slots have been invalidated; recalculate the old-segment
7258  * horizon, starting again from RedoRecPtr.
7259  */
7261  KeepLogSeg(endptr, &_logSegNo);
7262  }
7263  _logSegNo--;
7264 
7265  /*
7266  * Try to recycle segments on a useful timeline. If we've been promoted
7267  * since the beginning of this restartpoint, use the new timeline chosen
7268  * at end of recovery. If we're still in recovery, use the timeline we're
7269  * currently replaying.
7270  *
7271  * There is no guarantee that the WAL segments will be useful on the
7272  * current timeline; if recovery proceeds to a new timeline right after
7273  * this, the pre-allocated WAL segments on this timeline will not be used,
7274  * and will go wasted until recycled on the next restartpoint. We'll live
7275  * with that.
7276  */
7277  if (!RecoveryInProgress())
7278  replayTLI = XLogCtl->InsertTimeLineID;
7279 
7280  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr, replayTLI);
7281 
7282  /*
7283  * Make more log segments if needed. (Do this after recycling old log
7284  * segments, since that may supply some of the needed files.)
7285  */
7286  PreallocXlogFiles(endptr, replayTLI);
7287 
7288  /*
7289  * Truncate pg_subtrans if possible. We can throw away all data before
7290  * the oldest XMIN of any running transaction. No future transaction will
7291  * attempt to reference any pg_subtrans entry older than that (see Asserts
7292  * in subtrans.c). When hot standby is disabled, though, we mustn't do
7293  * this because StartupSUBTRANS hasn't been called yet.
7294  */
7295  if (EnableHotStandby)
7297 
7298  /* Real work is done; log and update stats. */
7299  LogCheckpointEnd(true);
7300 
7301  /* Reset the process title */
7302  update_checkpoint_display(flags, true, true);
7303 
7304  xtime = GetLatestXTime();
7306  (errmsg("recovery restart point at %X/%X",
7307  LSN_FORMAT_ARGS(lastCheckPoint.redo)),
7308  xtime ? errdetail("Last completed transaction was at log time %s.",
7309  timestamptz_to_str(xtime)) : 0));
7310 
7311  /*
7312  * Finally, execute archive_cleanup_command, if any.
7313  */
7314  if (archiveCleanupCommand && strcmp(archiveCleanupCommand, "") != 0)
7316  "archive_cleanup_command",
7317  false,
7319 
7320  return true;
7321 }
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1790
int64 TimestampTz
Definition: timestamp.h:39
#define LOG
Definition: elog.h:31
bool IsUnderPostmaster
Definition: globals.c:113
@ B_CHECKPOINTER
Definition: miscadmin.h:326
BackendType MyBackendType
Definition: miscinit.c:63
@ DB_IN_ARCHIVE_RECOVERY
Definition: pg_control.h:94
@ DB_SHUTDOWNED_IN_RECOVERY
Definition: pg_control.h:91
CheckPoint lastCheckPoint
Definition: xlog.c:551
XLogRecPtr lastCheckPointRecPtr
Definition: xlog.c:549
XLogRecPtr lastCheckPointEndPtr
Definition: xlog.c:550
@ WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND
Definition: wait_event.h:83
XLogRecPtr GetWalRcvFlushRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI)
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition: xlog.c:2434
static XLogRecPtr LocalMinRecoveryPoint
Definition: xlog.c:629
static TimeLineID LocalMinRecoveryPointTLI
Definition: xlog.c:630
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
uint32 TimeLineID
Definition: xlogdefs.h:59
char * archiveCleanupCommand
Definition: xlogrecovery.c:84
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
TimestampTz GetLatestXTime(void)

References archiveCleanupCommand, Assert(), B_CHECKPOINTER, ControlFileData::checkPoint, CHECKPOINT_IS_SHUTDOWN, ControlFileData::checkPointCopy, CheckPointGuts(), CheckpointStats, CheckpointStatsData::ckpt_start_t, ControlFile, DB_IN_ARCHIVE_RECOVERY, DB_SHUTDOWNED_IN_RECOVERY, DEBUG2, EnableHotStandby, ereport, errdetail(), errmsg(), errmsg_internal(), ExecuteRecoveryCommand(), GetCurrentTimestamp(), GetLatestXTime(), GetOldestTransactionIdConsideredRunning(), GetWalRcvFlushRecPtr(), GetXLogReplayRecPtr(), XLogCtlData::info_lck, XLogCtlData::Insert, XLogCtlData::InsertTimeLineID, InvalidateObsoleteReplicationSlots(), 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(), SpinLockAcquire, SpinLockRelease, ControlFileData::state, CheckPoint::ThisTimeLineID, timestamptz_to_str(), TruncateSUBTRANS(), update_checkpoint_display(), UpdateCheckPointDistanceEstimate(), UpdateControlFile(), UpdateMinRecoveryPoint(), WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND, 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 8816 of file xlog.c.

8817 {
8818  bool during_backup_start = DatumGetBool(arg);
8819 
8820  /* If called during backup start, there shouldn't be one already running */
8821  Assert(!during_backup_start || sessionBackupState == SESSION_BACKUP_NONE);
8822 
8823  if (during_backup_start || sessionBackupState != SESSION_BACKUP_NONE)
8824  {
8828 
8831 
8832  if (!during_backup_start)
8833  ereport(WARNING,
8834  errmsg("aborting backup due to backend exiting before pg_backup_stop was called"));
8835  }
8836 }
#define WARNING
Definition: elog.h:36
void * arg
static bool DatumGetBool(Datum X)
Definition: postgres.h:90
int runningBackups
Definition: xlog.c:447
static SessionBackupState sessionBackupState
Definition: xlog.c:400
@ SESSION_BACKUP_NONE
Definition: xlog.h:275

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

8245 {
8247 
8248  Assert(state != NULL);
8250 
8251  /*
8252  * During recovery, we don't need to check WAL level. Because, if WAL
8253  * level is not sufficient, it's impossible to get here during recovery.
8254  */
8256  ereport(ERROR,
8257  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8258  errmsg("WAL level not sufficient for making an online backup"),
8259  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
8260 
8261  if (strlen(backupidstr) > MAXPGPATH)
8262  ereport(ERROR,
8263  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8264  errmsg("backup label too long (max %d bytes)",
8265  MAXPGPATH)));
8266 
8267  memcpy(state->name, backupidstr, strlen(backupidstr));
8268 
8269  /*
8270  * Mark backup active in shared memory. We must do full-page WAL writes
8271  * during an on-line backup even if not doing so at other times, because
8272  * it's quite possible for the backup dump to obtain a "torn" (partially
8273  * written) copy of a database page if it reads the page concurrently with
8274  * our write to the same page. This can be fixed as long as the first
8275  * write to the page in the WAL sequence is a full-page write. Hence, we
8276  * increment runningBackups then force a CHECKPOINT, to ensure there are
8277  * no dirty pages in shared memory that might get dumped while the backup
8278  * is in progress without having a corresponding WAL record. (Once the
8279  * backup is complete, we need not force full-page writes anymore, since
8280  * we expect that any pages not modified during the backup interval must
8281  * have been correctly captured by the backup.)
8282  *
8283  * Note that forcing full-page writes has no effect during an online
8284  * backup from the standby.
8285  *
8286  * We must hold all the insertion locks to change the value of
8287  * runningBackups, to ensure adequate interlocking against
8288  * XLogInsertRecord().
8289  */
8293 
8294  /*
8295  * Ensure we decrement runningBackups if we fail below. NB -- for this to
8296  * work correctly, it is critical that sessionBackupState is only updated
8297  * after this block is over.
8298  */
8300  {
8301  bool gotUniqueStartpoint = false;
8302  DIR *tblspcdir;
8303  struct dirent *de;
8304  tablespaceinfo *ti;
8305  int datadirpathlen;
8306 
8307  /*
8308  * Force an XLOG file switch before the checkpoint, to ensure that the
8309  * WAL segment the checkpoint is written to doesn't contain pages with
8310  * old timeline IDs. That would otherwise happen if you called
8311  * pg_backup_start() right after restoring from a PITR archive: the
8312  * first WAL segment containing the startup checkpoint has pages in
8313  * the beginning with the old timeline ID. That can cause trouble at
8314  * recovery: we won't have a history file covering the old timeline if
8315  * pg_wal directory was not included in the base backup and the WAL
8316  * archive was cleared too before starting the backup.
8317  *
8318  * This also ensures that we have emitted a WAL page header that has
8319  * XLP_BKP_REMOVABLE off before we emit the checkpoint record.
8320  * Therefore, if a WAL archiver (such as pglesslog) is trying to
8321  * compress out removable backup blocks, it won't remove any that
8322  * occur after this point.
8323  *
8324  * During recovery, we skip forcing XLOG file switch, which means that
8325  * the backup taken during recovery is not available for the special
8326  * recovery case described above.
8327  */
8329  RequestXLogSwitch(false);
8330 
8331  do
8332  {
8333  bool checkpointfpw;
8334 
8335  /*
8336  * Force a CHECKPOINT. Aside from being necessary to prevent torn
8337  * page problems, this guarantees that two successive backup runs
8338  * will have different checkpoint positions and hence different
8339  * history file names, even if nothing happened in between.
8340  *
8341  * During recovery, establish a restartpoint if possible. We use
8342  * the last restartpoint as the backup starting checkpoint. This
8343  * means that two successive backup runs can have same checkpoint
8344  * positions.
8345  *
8346  * Since the fact that we are executing do_pg_backup_start()
8347  * during recovery means that checkpointer is running, we can use
8348  * RequestCheckpoint() to establish a restartpoint.
8349  *
8350  * We use CHECKPOINT_IMMEDIATE only if requested by user (via
8351  * passing fast = true). Otherwise this can take awhile.
8352  */
8354  (fast ? CHECKPOINT_IMMEDIATE : 0));
8355 
8356  /*
8357  * Now we need to fetch the checkpoint record location, and also
8358  * its REDO pointer. The oldest point in WAL that would be needed
8359  * to restore starting from the checkpoint is precisely the REDO
8360  * pointer.
8361  */
8362  LWLockAcquire(ControlFileLock, LW_SHARED);
8363  state->checkpointloc = ControlFile->checkPoint;
8364  state->startpoint = ControlFile->checkPointCopy.redo;
8366  checkpointfpw = ControlFile->checkPointCopy.fullPageWrites;
8367  LWLockRelease(ControlFileLock);
8368 
8370  {
8371  XLogRecPtr recptr;
8372 
8373  /*
8374  * Check to see if all WAL replayed during online backup
8375  * (i.e., since last restartpoint used as backup starting
8376  * checkpoint) contain full-page writes.
8377  */
8379  recptr = XLogCtl->lastFpwDisableRecPtr;
8381 
8382  if (!checkpointfpw || state->startpoint <= recptr)
8383  ereport(ERROR,
8384  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8385  errmsg("WAL generated with full_page_writes=off was replayed "
8386  "since last restartpoint"),
8387  errhint("This means that the backup being taken on the standby "
8388  "is corrupt and should not be used. "
8389  "Enable full_page_writes and run CHECKPOINT on the primary, "
8390  "and then try an online backup again.")));
8391 
8392  /*
8393  * During recovery, since we don't use the end-of-backup WAL
8394  * record and don't write the backup history file, the
8395  * starting WAL location doesn't need to be unique. This means
8396  * that two base backups started at the same time might use
8397  * the same checkpoint as starting locations.
8398  */
8399  gotUniqueStartpoint = true;
8400  }
8401 
8402  /*
8403  * If two base backups are started at the same time (in WAL sender
8404  * processes), we need to make sure that they use different
8405  * checkpoints as starting locations, because we use the starting
8406  * WAL location as a unique identifier for the base backup in the
8407  * end-of-backup WAL record and when we write the backup history
8408  * file. Perhaps it would be better generate a separate unique ID
8409  * for each backup instead of forcing another checkpoint, but
8410  * taking a checkpoint right after another is not that expensive
8411  * either because only few buffers have been dirtied yet.
8412  */
8414  if (XLogCtl->Insert.lastBackupStart < state->startpoint)
8415  {
8416  XLogCtl->Insert.lastBackupStart = state->startpoint;
8417  gotUniqueStartpoint = true;
8418  }
8420  } while (!gotUniqueStartpoint);
8421 
8422  /*
8423  * Construct tablespace_map file.
8424  */
8425  datadirpathlen = strlen(DataDir);
8426 
8427  /* Collect information about all tablespaces */
8428  tblspcdir = AllocateDir("pg_tblspc");
8429  while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL)
8430  {
8431  char fullpath[MAXPGPATH + 10];
8432  char linkpath[MAXPGPATH];
8433  char *relpath = NULL;
8434  int rllen;
8435  StringInfoData escapedpath;
8436  char *s;
8437 
8438  /* Skip anything that doesn't look like a tablespace */
8439  if (strspn(de->d_name, "0123456789") != strlen(de->d_name))
8440  continue;
8441 
8442  snprintf(fullpath, sizeof(fullpath), "pg_tblspc/%s", de->d_name);
8443 
8444  /*
8445  * Skip anything that isn't a symlink/junction. For testing only,
8446  * we sometimes use allow_in_place_tablespaces to create
8447  * directories directly under pg_tblspc, which would fail below.
8448  */
8449  if (get_dirent_type(fullpath, de, false, ERROR) != PGFILETYPE_LNK)
8450  continue;
8451 
8452  rllen = readlink(fullpath, linkpath, sizeof(linkpath));
8453  if (rllen < 0)
8454  {
8455  ereport(WARNING,
8456  (errmsg("could not read symbolic link \"%s\": %m",
8457  fullpath)));
8458  continue;
8459  }
8460  else if (rllen >= sizeof(linkpath))
8461  {
8462  ereport(WARNING,
8463  (errmsg("symbolic link \"%s\" target is too long",
8464  fullpath)));
8465  continue;
8466  }
8467  linkpath[rllen] = '\0';
8468 
8469  /*
8470  * Build a backslash-escaped version of the link path to include
8471  * in the tablespace map file.
8472  */
8473  initStringInfo(&escapedpath);
8474  for (s = linkpath; *s; s++)
8475  {
8476  if (*s == '\n' || *s == '\r' || *s == '\\')
8477  appendStringInfoChar(&escapedpath, '\\');
8478  appendStringInfoChar(&escapedpath, *s);
8479  }
8480 
8481  /*
8482  * Relpath holds the relative path of the tablespace directory
8483  * when it's located within PGDATA, or NULL if it's located
8484  * elsewhere.
8485  */
8486  if (rllen > datadirpathlen &&
8487  strncmp(linkpath, DataDir, datadirpathlen) == 0 &&
8488  IS_DIR_SEP(linkpath[datadirpathlen]))
8489  relpath = linkpath + datadirpathlen + 1;
8490 
8491  ti = palloc(sizeof(tablespaceinfo));
8492  ti->oid = pstrdup(de->d_name);
8493  ti->path = pstrdup(linkpath);
8494  ti->rpath = relpath ? pstrdup(relpath) : NULL;
8495  ti->size = -1;
8496 
8497  if (tablespaces)
8498  *tablespaces = lappend(*tablespaces, ti);
8499 
8500  appendStringInfo(tblspcmapfile, "%s %s\n",
8501  ti->oid, escapedpath.data);
8502 
8503  pfree(escapedpath.data);
8504  }
8505  FreeDir(tblspcdir);
8506 
8507  state->starttime = (pg_time_t) time(NULL);
8508  }
8510 
8511  state->started_in_recovery = backup_started_in_recovery;
8512 
8513  /*
8514  * Mark that the start phase has correctly finished for the backup.
8515  */
8517 }
static bool backup_started_in_recovery
Definition: basebackup.c:102
void RequestCheckpoint(int flags)
Definition: checkpointer.c:931
int errcode(int sqlerrcode)
Definition: elog.c:858
PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
Definition: file_utils.c:406
@ PGFILETYPE_LNK
Definition: file_utils.h:24
char * DataDir
Definition: globals.c:66
#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:338
#define IS_DIR_SEP(ch)
Definition: port.h:102
#define relpath(rlocator, forknum)
Definition: relpath.h:94
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:557
XLogRecPtr lastBackupStart
Definition: xlog.c:448
Definition: regguts.h:318
char * rpath
Definition: basebackup.h:32
#define readlink(path, buf, size)
Definition: win32_port.h:238
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:7524
void do_pg_abort_backup(int code, Datum arg)
Definition: xlog.c:8816
@ SESSION_BACKUP_RUNNING
Definition: xlog.h:276
#define CHECKPOINT_WAIT
Definition: xlog.h:140
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:136
#define XLogIsNeeded()
Definition: xlog.h:104

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

8543 {
8544  bool backup_stopped_in_recovery = false;
8545  char histfilepath[MAXPGPATH];
8546  char lastxlogfilename[MAXFNAMELEN];
8547  char histfilename[MAXFNAMELEN];
8548  XLogSegNo _logSegNo;
8549  FILE *fp;
8550  int seconds_before_warning;
8551  int waits = 0;
8552  bool reported_waiting = false;
8553 
8554  Assert(state != NULL);
8555 
8556  backup_stopped_in_recovery = RecoveryInProgress();
8557 
8558  /*
8559  * During recovery, we don't need to check WAL level. Because, if WAL
8560  * level is not sufficient, it's impossible to get here during recovery.
8561  */
8562  if (!backup_stopped_in_recovery && !XLogIsNeeded())
8563  ereport(ERROR,
8564  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8565  errmsg("WAL level not sufficient for making an online backup"),
8566  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
8567 
8568  /*
8569  * OK to update backup counter and session-level lock.
8570  *
8571  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating them,
8572  * otherwise they can be updated inconsistently, which might cause
8573  * do_pg_abort_backup() to fail.
8574  */
8576 
8577  /*
8578  * It is expected that each do_pg_backup_start() call is matched by
8579  * exactly one do_pg_backup_stop() call.
8580  */
8583 
8584  /*
8585  * Clean up session-level lock.
8586  *
8587  * You might think that WALInsertLockRelease() can be called before
8588  * cleaning up session-level lock because session-level lock doesn't need
8589  * to be protected with WAL insertion lock. But since
8590  * CHECK_FOR_INTERRUPTS() can occur in it, session-level lock must be
8591  * cleaned up before it.
8592  */
8594 
8596 
8597  /*
8598  * If we are taking an online backup from the standby, we confirm that the
8599  * standby has not been promoted during the backup.
8600  */
8601  if (state->started_in_recovery && !backup_stopped_in_recovery)
8602  ereport(ERROR,
8603  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8604  errmsg("the standby was promoted during online backup"),
8605  errhint("This means that the backup being taken is corrupt "
8606  "and should not be used. "
8607  "Try taking another online backup.")));
8608 
8609  /*
8610  * During recovery, we don't write an end-of-backup record. We assume that
8611  * pg_control was backed up last and its minimum recovery point can be
8612  * available as the backup end location. Since we don't have an
8613  * end-of-backup record, we use the pg_control value to check whether
8614  * we've reached the end of backup when starting recovery from this
8615  * backup. We have no way of checking if pg_control wasn't backed up last
8616  * however.
8617  *
8618  * We don't force a switch to new WAL file but it is still possible to
8619  * wait for all the required files to be archived if waitforarchive is
8620  * true. This is okay if we use the backup to start a standby and fetch
8621  * the missing WAL using streaming replication. But in the case of an
8622  * archive recovery, a user should set waitforarchive to true and wait for
8623  * them to be archived to ensure that all the required files are
8624  * available.
8625  *
8626  * We return the current minimum recovery point as the backup end
8627  * location. Note that it can be greater than the exact backup end
8628  * location if the minimum recovery point is updated after the backup of
8629  * pg_control. This is harmless for current uses.
8630  *
8631  * XXX currently a backup history file is for informational and debug
8632  * purposes only. It's not essential for an online backup. Furthermore,
8633  * even if it's created, it will not be archived during recovery because
8634  * an archiver is not invoked. So it doesn't seem worthwhile to write a
8635  * backup history file during recovery.
8636  */
8637  if (backup_stopped_in_recovery)
8638  {
8639  XLogRecPtr recptr;
8640 
8641  /*
8642  * Check to see if all WAL replayed during online backup contain
8643  * full-page writes.
8644  */
8646  recptr = XLogCtl->lastFpwDisableRecPtr;
8648 
8649  if (state->startpoint <= recptr)
8650  ereport(ERROR,
8651  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8652  errmsg("WAL generated with full_page_writes=off was replayed "
8653  "during online backup"),
8654  errhint("This means that the backup being taken on the standby "
8655  "is corrupt and should not be used. "
8656  "Enable full_page_writes and run CHECKPOINT on the primary, "
8657  "and then try an online backup again.")));
8658 
8659 
8660  LWLockAcquire(ControlFileLock, LW_SHARED);
8661  state->stoppoint = ControlFile->minRecoveryPoint;
8663  LWLockRelease(ControlFileLock);
8664  }
8665  else
8666  {
8667  char *history_file;
8668 
8669  /*
8670  * Write the backup-end xlog record
8671  */
8672  XLogBeginInsert();
8673  XLogRegisterData((char *) (&state->startpoint),
8674  sizeof(state->startpoint));
8675  state->stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
8676 
8677  /*
8678  * Given that we're not in recovery, InsertTimeLineID is set and can't
8679  * change, so we can read it without a lock.
8680  */
8681  state->stoptli = XLogCtl->InsertTimeLineID;
8682 
8683  /*
8684  * Force a switch to a new xlog segment file, so that the backup is
8685  * valid as soon as archiver moves out the current segment file.
8686  */
8687  RequestXLogSwitch(false);
8688 
8689  state->stoptime = (pg_time_t) time(NULL);
8690 
8691  /*
8692  * Write the backup history file
8693  */
8694  XLByteToSeg(state->startpoint, _logSegNo, wal_segment_size);
8695  BackupHistoryFilePath(histfilepath, state->stoptli, _logSegNo,
8696  state->startpoint, wal_segment_size);
8697  fp = AllocateFile(histfilepath, "w");
8698  if (!fp)
8699  ereport(ERROR,
8701  errmsg("could not create file \"%s\": %m",
8702  histfilepath)));
8703 
8704  /* Build and save the contents of the backup history file */
8705  history_file = build_backup_content(state, true);
8706  fprintf(fp, "%s", history_file);
8707  pfree(history_file);
8708 
8709  if (fflush(fp) || ferror(fp) || FreeFile(fp))
8710  ereport(ERROR,
8712  errmsg("could not write file \"%s\": %m",
8713  histfilepath)));
8714 
8715  /*
8716  * Clean out any no-longer-needed history files. As a side effect,
8717  * this will post a .ready file for the newly created history file,
8718  * notifying the archiver that history file may be archived
8719  * immediately.
8720  */
8722  }
8723 
8724  /*
8725  * If archiving is enabled, wait for all the required WAL files to be
8726  * archived before returning. If archiving isn't enabled, the required WAL
8727  * needs to be transported via streaming replication (hopefully with
8728  * wal_keep_size set high enough), or some more exotic mechanism like
8729  * polling and copying files from pg_wal with script. We have no knowledge
8730  * of those mechanisms, so it's up to the user to ensure that he gets all
8731  * the required WAL.
8732  *
8733  * We wait until both the last WAL file filled during backup and the
8734  * history file have been archived, and assume that the alphabetic sorting
8735  * property of the WAL files ensures any earlier WAL files are safely
8736  * archived as well.
8737  *
8738  * We wait forever, since archive_command is supposed to work and we
8739  * assume the admin wanted his backup to work completely. If you don't
8740  * wish to wait, then either waitforarchive should be passed in as false,
8741  * or you can set statement_timeout. Also, some notices are issued to
8742  * clue in anyone who might be doing this interactively.
8743  */
8744 
8745  if (waitforarchive &&
8746  ((!backup_stopped_in_recovery && XLogArchivingActive()) ||
8747  (backup_stopped_in_recovery && XLogArchivingAlways())))
8748  {
8749  XLByteToPrevSeg(state->stoppoint, _logSegNo, wal_segment_size);
8750  XLogFileName(lastxlogfilename, state->stoptli, _logSegNo,
8752 
8753  XLByteToSeg(state->startpoint, _logSegNo, wal_segment_size);
8754  BackupHistoryFileName(histfilename, state->stoptli, _logSegNo,
8755  state->startpoint, wal_segment_size);
8756 
8757  seconds_before_warning = 60;
8758  waits = 0;
8759 
8760  while (XLogArchiveIsBusy(lastxlogfilename) ||
8761  XLogArchiveIsBusy(histfilename))
8762  {
8764 
8765  if (!reported_waiting && waits > 5)
8766  {
8767  ereport(NOTICE,
8768  (errmsg("base backup done, waiting for required WAL segments to be archived")));
8769  reported_waiting = true;
8770  }
8771 
8772  (void) WaitLatch(MyLatch,
8774  1000L,
8777 
8778  if (++waits >= seconds_before_warning)
8779  {
8780  seconds_before_warning *= 2; /* This wraps in >10 years... */
8781  ereport(WARNING,
8782  (errmsg("still waiting for all required WAL segments to be archived (%d seconds elapsed)",
8783  waits),
8784  errhint("Check that your archive_command is executing properly. "
8785  "You can safely cancel this backup, "
8786  "but the database backup will not be usable without all the WAL segments.")));
8787  }
8788  }
8789 
8790  ereport(NOTICE,
8791  (errmsg("all required WAL segments have been archived")));
8792  }
8793  else if (waitforarchive)
8794  ereport(NOTICE,
8795  (errmsg("WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup")));
8796 }
#define NOTICE
Definition: elog.h:35
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2384
int FreeFile(FILE *file)
Definition: fd.c:2582
struct Latch * MyLatch
Definition: globals.c:58
void ResetLatch(Latch *latch)
Definition: latch.c:699
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:492
#define WL_TIMEOUT
Definition: latch.h:128
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:130
#define WL_LATCH_SET
Definition: latch.h:125
static void const char fflush(stdout)
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:121
#define XLOG_BACKUP_END
Definition: pg_control.h:72
#define fprintf
Definition: port.h:242
@ WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE
Definition: wait_event.h:86
static void CleanupBackupHistory(void)
Definition: xlog.c:3808
#define XLogArchivingAlways()
Definition: xlog.h:97
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:613
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, WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE, 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 8523 of file xlog.c.

8524 {
8525  return sessionBackupState;
8526 }

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

8038 {
8039  int o_direct_flag = 0;
8040 
8041  /* If fsync is disabled, never open in sync mode */
8042  if (!enableFsync)
8043  return 0;
8044 
8045  /*
8046  * Optimize writes by bypassing kernel cache with O_DIRECT when using
8047  * O_SYNC and O_DSYNC. But only if archiving and streaming are disabled,
8048  * otherwise the archive command or walsender process will read the WAL
8049  * soon after writing it, which is guaranteed to cause a physical read if
8050  * we bypassed the kernel cache. We also skip the
8051  * posix_fadvise(POSIX_FADV_DONTNEED) call in XLogFileClose() for the same
8052  * reason.
8053  *
8054  * Never use O_DIRECT in walreceiver process for similar reasons; the WAL
8055  * written by walreceiver is normally read by the startup process soon
8056  * after it's written. Also, walreceiver performs unaligned writes, which
8057  * don't work with O_DIRECT, so it is required for correctness too.
8058  */
8059  if (!XLogIsNeeded() && !AmWalReceiverProcess())
8060  o_direct_flag = PG_O_DIRECT;
8061 
8062  switch (method)
8063  {
8064  /*
8065  * enum values for all sync options are defined even if they are
8066  * not supported on the current platform. But if not, they are
8067  * not included in the enum option array, and therefore will never
8068  * be seen here.
8069  */
8070  case SYNC_METHOD_FSYNC:
8072  case SYNC_METHOD_FDATASYNC:
8073  return 0;
8074 #ifdef O_SYNC
8075  case SYNC_METHOD_OPEN:
8076  return O_SYNC | o_direct_flag;
8077 #endif
8078 #ifdef O_DSYNC
8080  return O_DSYNC | o_direct_flag;
8081 #endif
8082  default:
8083  /* can't happen (unless we are out of sync with option array) */
8084  elog(ERROR, "unrecognized wal_sync_method: %d", method);
8085  return 0; /* silence warning */
8086  }
8087 }
#define PG_O_DIRECT
Definition: fd.h:93
bool enableFsync
Definition: globals.c:123
#define AmWalReceiverProcess()
Definition: miscadmin.h:448
#define O_DSYNC
Definition: win32_port.h:354
#define SYNC_METHOD_FSYNC
Definition: xlog.h:22
#define SYNC_METHOD_OPEN
Definition: xlog.h:24
#define SYNC_METHOD_FDATASYNC
Definition: xlog.h:23
#define SYNC_METHOD_OPEN_DSYNC
Definition: xlog.h:26
#define SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:25

References AmWalReceiverProcess, elog(), enableFsync, ERROR, O_DSYNC, PG_O_DIRECT, SYNC_METHOD_FDATASYNC, SYNC_METHOD_FSYNC, SYNC_METHOD_FSYNC_WRITETHROUGH, SYNC_METHOD_OPEN, SYNC_METHOD_OPEN_DSYNC, and XLogIsNeeded.

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

◆ GetFakeLSNForUnloggedRel()

XLogRecPtr GetFakeLSNForUnloggedRel ( void  )

Definition at line 4213 of file xlog.c.

4214 {
4215  XLogRecPtr nextUnloggedLSN;
4216 
4217  /* increment the unloggedLSN counter, need SpinLock */
4219  nextUnloggedLSN = XLogCtl->unloggedLSN++;
4221 
4222  return nextUnloggedLSN;
4223 }

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

Referenced by gistGetFakeLSN().

◆ GetFlushRecPtr()

XLogRecPtr GetFlushRecPtr ( TimeLineID insertTLI)

Definition at line 6073 of file xlog.c.

6074 {
6076 
6080 
6081  /*
6082  * If we're writing and flushing WAL, the time line can't be changing, so
6083  * no lock is required.
6084  */
6085  if (insertTLI)
6086  *insertTLI = XLogCtl->InsertTimeLineID;
6087 
6088  return LogwrtResult.Flush;
6089 }
RecoveryState SharedRecoveryState
Definition: xlog.c:522
XLogRecPtr Flush
Definition: xlog.c:337
@ RECOVERY_STATE_DONE
Definition: xlog.h:88

References Assert(), XLogwrtResult::Flush, XLogCtlData::info_lck, XLogCtlData::InsertTimeLineID, XLogCtlData::LogwrtResult, LogwrtResult, RECOVERY_STATE_DONE, XLogCtlData::SharedRecoveryState, SpinLockAcquire, SpinLockRelease, and XLogCtl.

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

◆ GetFullPageWriteInfo()

void GetFullPageWriteInfo ( XLogRecPtr RedoRecPtr_p,
bool doPageWrites_p 
)

Definition at line 6041 of file xlog.c.

6042 {
6043  *RedoRecPtr_p = RedoRecPtr;
6044  *doPageWrites_p = doPageWrites;
6045 }
static bool doPageWrites
Definition: xlog.c:289

References doPageWrites, and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )

Definition at line 6056 of file xlog.c.

6057 {
6058  XLogRecPtr recptr;
6059 
6061  recptr = XLogCtl->LogwrtRqst.Write;
6063 
6064  return recptr;
6065 }

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

6114 {
6116  int i;
6117 
6118  for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
6119  {
6120  XLogRecPtr last_important;
6121 
6122  /*
6123  * Need to take a lock to prevent torn reads of the LSN, which are
6124  * possible on some of the supported platforms. WAL insert locks only
6125  * support exclusive mode, so we have to use that.
6126  */
6128  last_important = WALInsertLocks[i].l.lastImportantAt;
6129  LWLockRelease(&WALInsertLocks[i].l.lock);
6130 
6131  if (res < last_important)
6132  res = last_important;
6133  }
6134 
6135  return res;
6136 }
int i
Definition: isn.c:73
XLogRecPtr lastImportantAt
Definition: xlog.c:380
WALInsertLock l
Definition: xlog.c:392
static WALInsertLockPadded * WALInsertLocks
Definition: xlog.c:565
#define NUM_XLOGINSERT_LOCKS
Definition: xlog.c:153

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

6143 {
6144  pg_time_t result;
6145 
6146  /* Need WALWriteLock, but shared lock is sufficient */
6147  LWLockAcquire(WALWriteLock, LW_SHARED);
6148  result = XLogCtl->lastSegSwitchTime;
6149  *lastSwitchLSN = XLogCtl->lastSegSwitchLSN;
6150  LWLockRelease(WALWriteLock);
6151 
6152  return result;
6153 }
pg_time_t lastSegSwitchTime
Definition: xlog.c:477
XLogRecPtr lastSegSwitchLSN
Definition: xlog.c:478

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

Referenced by CheckArchiveTimeout().

◆ GetMockAuthenticationNonce()

char* GetMockAuthenticationNonce ( void  )

Definition at line 4187 of file xlog.c.

4188 {
4189  Assert(ControlFile != NULL);
4191 }
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition: pg_control.h:227

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

Referenced by scram_mock_salt().

◆ GetOldestRestartPoint()

void GetOldestRestartPoint ( XLogRecPtr oldrecptr,
TimeLineID oldtli 
)

Definition at line 8887 of file xlog.c.

8888 {
8889  LWLockAcquire(ControlFileLock, LW_SHARED);
8890  *oldrecptr = ControlFile->checkPointCopy.redo;
8892  LWLockRelease(ControlFileLock);
8893 }

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

5945 {
5946  RecoveryState retval;
5947 
5949  retval = XLogCtl->SharedRecoveryState;
5951 
5952  return retval;
5953 }
RecoveryState
Definition: xlog.h:85

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

Referenced by XLogArchiveCheckDone().

◆ GetRedoRecPtr()

XLogRecPtr GetRedoRecPtr ( void  )

Definition at line 6011 of file xlog.c.

6012 {
6013  XLogRecPtr ptr;
6014 
6015  /*
6016  * The possibly not up-to-date copy in XlogCtl is enough. Even if we
6017  * grabbed a WAL insertion lock to read the authoritative value in
6018  * Insert->RedoRecPtr, someone might update it just after we've released
6019  * the lock.
6020  */
6022  ptr = XLogCtl->RedoRecPtr;
6024 
6025  if (RedoRecPtr < ptr)
6026  RedoRecPtr = ptr;
6027 
6028  return RedoRecPtr;
6029 }

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

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

◆ GetSystemIdentifier()

uint64 GetSystemIdentifier ( void  )

Definition at line 4177 of file xlog.c.

4178 {
4179  Assert(ControlFile != NULL);
4181 }

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

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

◆ GetWALAvailability()

WALAvailability GetWALAvailability ( XLogRecPtr  targetLSN)

Definition at line 7347 of file xlog.c.

7348 {
7349  XLogRecPtr currpos; /* current write LSN */
7350  XLogSegNo currSeg; /* segid of currpos */
7351  XLogSegNo targetSeg; /* segid of targetLSN */
7352  XLogSegNo oldestSeg; /* actual oldest segid */
7353  XLogSegNo oldestSegMaxWalSize; /* oldest segid kept by max_wal_size */
7354  XLogSegNo oldestSlotSeg; /* oldest segid kept by slot */
7355  uint64 keepSegs;
7356 
7357  /*
7358  * slot does not reserve WAL. Either deactivated, or has never been active
7359  */
7360  if (XLogRecPtrIsInvalid(targetLSN))
7361  return WALAVAIL_INVALID_LSN;
7362 
7363  /*
7364  * Calculate the oldest segment currently reserved by all slots,
7365  * considering wal_keep_size and max_slot_wal_keep_size. Initialize
7366  * oldestSlotSeg to the current segment.
7367  */
7368  currpos = GetXLogWriteRecPtr();
7369  XLByteToSeg(currpos, oldestSlotSeg, wal_segment_size);
7370  KeepLogSeg(currpos, &oldestSlotSeg);
7371 
7372  /*
7373  * Find the oldest extant segment file. We get 1 until checkpoint removes
7374  * the first WAL segment file since startup, which causes the status being
7375  * wrong under certain abnormal conditions but that doesn't actually harm.
7376  */
7377  oldestSeg = XLogGetLastRemovedSegno() + 1;
7378 
7379  /* calculate oldest segment by max_wal_size */
7380  XLByteToSeg(currpos, currSeg, wal_segment_size);
7382 
7383  if (currSeg > keepSegs)
7384  oldestSegMaxWalSize = currSeg - keepSegs;
7385  else
7386  oldestSegMaxWalSize = 1;
7387 
7388  /* the segment we care about */
7389  XLByteToSeg(targetLSN, targetSeg, wal_segment_size);
7390 
7391  /*
7392  * No point in returning reserved or extended status values if the
7393  * targetSeg is known to be lost.
7394  */
7395  if (targetSeg >= oldestSlotSeg)
7396  {
7397  /* show "reserved" when targetSeg is within max_wal_size */
7398  if (targetSeg >= oldestSegMaxWalSize)
7399  return WALAVAIL_RESERVED;
7400 
7401  /* being retained by slots exceeding max_wal_size */
7402  return WALAVAIL_EXTENDED;
7403  }
7404 
7405  /* WAL segments are no longer retained but haven't been removed yet */
7406  if (targetSeg >= oldestSeg)
7407  return WALAVAIL_UNRESERVED;
7408 
7409  /* Definitely lost */
7410  return WALAVAIL_REMOVED;
7411 }
XLogSegNo XLogGetLastRemovedSegno(void)
Definition: xlog.c:3466
XLogRecPtr GetXLogWriteRecPtr(void)
Definition: xlog.c:8873
@ WALAVAIL_REMOVED
Definition: xlog.h:188
@ WALAVAIL_RESERVED
Definition: xlog.h:184
@ WALAVAIL_UNRESERVED
Definition: xlog.h:187
@ WALAVAIL_EXTENDED
Definition: xlog.h:185
@ WALAVAIL_INVALID_LSN
Definition: xlog.h:183

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

6097 {
6099 
6100  /* Since the value can't be changing, no lock is required. */
6101  return XLogCtl->InsertTimeLineID;
6102 }

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

◆ GetXLogBuffer()

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

Definition at line 1537 of file xlog.c.

1538 {
1539  int idx;
1540  XLogRecPtr endptr;
1541  static uint64 cachedPage = 0;
1542  static char *cachedPos = NULL;
1543  XLogRecPtr expectedEndPtr;
1544 
1545  /*
1546  * Fast path for the common case that we need to access again the same
1547  * page as last time.
1548  */
1549  if (ptr / XLOG_BLCKSZ == cachedPage)
1550  {
1551  Assert(((XLogPageHeader) cachedPos)->xlp_magic == XLOG_PAGE_MAGIC);
1552  Assert(((XLogPageHeader) cachedPos)->xlp_pageaddr == ptr - (ptr % XLOG_BLCKSZ));
1553  return cachedPos + ptr % XLOG_BLCKSZ;
1554  }
1555 
1556  /*
1557  * The XLog buffer cache is organized so that a page is always loaded to a
1558  * particular buffer. That way we can easily calculate the buffer a given
1559  * page must be loaded into, from the XLogRecPtr alone.
1560  */
1561  idx = XLogRecPtrToBufIdx(ptr);
1562 
1563  /*
1564  * See what page is loaded in the buffer at the moment. It could be the
1565  * page we're looking for, or something older. It can't be anything newer
1566  * - that would imply the page we're looking for has already been written
1567  * out to disk and evicted, and the caller is responsible for making sure
1568  * that doesn't happen.
1569  *
1570  * However, we don't hold a lock while we read the value. If someone has
1571  * just initialized the page, it's possible that we get a "torn read" of
1572  * the XLogRecPtr if 64-bit fetches are not atomic on this platform. In
1573  * that case we will see a bogus value. That's ok, we'll grab the mapping
1574  * lock (in AdvanceXLInsertBuffer) and retry if we see anything else than
1575  * the page we're looking for. But it means that when we do this unlocked
1576  * read, we might see a value that appears to be ahead of the page we're
1577  * looking for. Don't PANIC on that, until we've verified the value while
1578  * holding the lock.
1579  */
1580  expectedEndPtr = ptr;
1581  expectedEndPtr += XLOG_BLCKSZ - ptr % XLOG_BLCKSZ;
1582 
1583  endptr = XLogCtl->xlblocks[idx];
1584  if (expectedEndPtr != endptr)
1585  {
1586  XLogRecPtr initializedUpto;
1587 
1588  /*
1589  * Before calling AdvanceXLInsertBuffer(), which can block, let others
1590  * know how far we're finished with inserting the record.
1591  *
1592  * NB: If 'ptr' points to just after the page header, advertise a
1593  * position at the beginning of the page rather than 'ptr' itself. If
1594  * there are no other insertions running, someone might try to flush
1595  * up to our advertised location. If we advertised a position after
1596  * the page header, someone might try to flush the page header, even
1597  * though page might actually not be initialized yet. As the first
1598  * inserter on the page, we are effectively responsible for making
1599  * sure that it's initialized, before we let insertingAt to move past
1600  * the page header.
1601  */
1602  if (ptr % XLOG_BLCKSZ == SizeOfXLogShortPHD &&
1603  XLogSegmentOffset(ptr, wal_segment_size) > XLOG_BLCKSZ)
1604  initializedUpto = ptr - SizeOfXLogShortPHD;
1605  else if (ptr % XLOG_BLCKSZ == SizeOfXLogLongPHD &&
1606  XLogSegmentOffset(ptr, wal_segment_size) < XLOG_BLCKSZ)
1607  initializedUpto = ptr - SizeOfXLogLongPHD;
1608  else
1609  initializedUpto = ptr;
1610 
1611  WALInsertLockUpdateInsertingAt(initializedUpto);
1612 
1613  AdvanceXLInsertBuffer(ptr, tli, false);
1614  endptr = XLogCtl->xlblocks[idx];
1615 
1616  if (expectedEndPtr != endptr)
1617  elog(PANIC, "could not find WAL buffer for %X/%X",
1618  LSN_FORMAT_ARGS(ptr));
1619  }
1620  else
1621  {
1622  /*
1623  * Make sure the initialization of the page is visible to us, and
1624  * won't arrive later to overwrite the WAL data we write on the page.
1625  */
1627  }
1628 
1629  /*
1630  * Found the buffer holding this page. Return a pointer to the right
1631  * offset within the page.
1632  */
1633  cachedPage = ptr / XLOG_BLCKSZ;
1634  cachedPos = XLogCtl->pages + idx * (Size) XLOG_BLCKSZ;
1635 
1636  Assert(((XLogPageHeader) cachedPos)->xlp_magic == XLOG_PAGE_MAGIC);
1637  Assert(((XLogPageHeader) cachedPos)->xlp_pageaddr == ptr - (ptr % XLOG_BLCKSZ));
1638 
1639  return cachedPos + ptr % XLOG_BLCKSZ;
1640 }
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:1405
static void AdvanceXLInsertBuffer(XLogRecPtr upto, TimeLineID tli, bool opportunistic)
Definition: xlog.c:1775

References AdvanceXLInsertBuffer(), Assert(), elog(), idx(), LSN_FORMAT_ARGS, XLogCtlData::pages, PANIC, 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 8857 of file xlog.c.

8858 {
8860  uint64 current_bytepos;
8861 
8862  SpinLockAcquire(&Insert->insertpos_lck);
8863  current_bytepos = Insert->CurrBytePos;
8864  SpinLockRelease(&Insert->insertpos_lck);
8865 
8866  return XLogBytePosToRecPtr(current_bytepos);
8867 }

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

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

◆ GetXLogWriteRecPtr()

◆ InitControlFile()

static void InitControlFile ( uint64  sysidentifier)
static

Definition at line 3851 of file xlog.c.

3852 {
3853  char mock_auth_nonce[MOCK_AUTH_NONCE_LEN];
3854 
3855  /*
3856  * Generate a random nonce. This is used for authentication requests that
3857  * will fail because the user does not exist. The nonce is used to create
3858  * a genuine-looking password challenge for the non-existent user, in lieu
3859  * of an actual stored password.
3860  */
3861  if (!pg_strong_random(mock_auth_nonce, MOCK_AUTH_NONCE_LEN))
3862  ereport(PANIC,
3863  (errcode(ERRCODE_INTERNAL_ERROR),
3864  errmsg("could not generate secret authorization token")));
3865 
3866  memset(ControlFile, 0, sizeof(ControlFileData));
3867  /* Initialize pg_control status fields */
3868  ControlFile->system_identifier = sysidentifier;
3869  memcpy(ControlFile->mock_authentication_nonce, mock_auth_nonce, MOCK_AUTH_NONCE_LEN);
3872 
3873  /* Set important parameter values for use when replaying WAL */
3883 }
bool track_commit_timestamp
Definition: commit_ts.c:102
#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:183
int wal_level
Definition: xlog.c:134
bool wal_log_hints
Definition: xlog.c:126
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 4400 of file xlog.c.

4401 {
4403 
4405  {
4406  struct config_generic *guc;
4407 
4408  guc = find_option("wal_consistency_checking", false, false, ERROR);
4409 
4411 
4412  set_config_option_ext("wal_consistency_checking",
4414  guc->scontext, guc->source, guc->srole,
4415  GUC_ACTION_SET, true, ERROR, false);
4416 
4417  /* checking should not be deferred again */
4419  }
4420 }
struct config_generic * find_option(const char *name, bool create_placeholders, bool skip_errors, int elevel)
Definition: guc.c:1163
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:3324
@ GUC_ACTION_SET
Definition: guc.h:197
GucContext scontext
Definition: guc_tables.h:166
GucSource source
Definition: guc_tables.h:164
char * wal_consistency_checking_string
Definition: xlog.c:128

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

3273 {
3274  char path[MAXPGPATH];
3275  struct stat stat_buf;
3276 
3277  Assert(tli != 0);
3278 
3279  XLogFilePath(path, tli, *segno, wal_segment_size);
3280 
3281  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
3283  {
3284  LWLockRelease(ControlFileLock);
3285  return false;
3286  }
3287 
3288  if (!find_free)
3289  {
3290  /* Force installation: get rid of any pre-existing segment file */
3291  durable_unlink(path, DEBUG1);
3292  }
3293  else
3294  {
3295  /* Find a free slot to put it in */
3296  while (stat(path, &stat_buf) == 0)
3297  {
3298  if ((*segno) >= max_segno)
3299  {
3300  /* Failed to find a free slot within specified range */
3301  LWLockRelease(ControlFileLock);
3302  return false;
3303  }
3304  (*segno)++;
3305  XLogFilePath(path, tli, *segno, wal_segment_size);
3306  }
3307  }
3308 
3309  Assert(access(path, F_OK) != 0 && errno == ENOENT);
3310  if (durable_rename(tmppath, path, LOG) != 0)
3311  {
3312  LWLockRelease(ControlFileLock);
3313  /* durable_rename already emitted log message */
3314  return false;
3315  }
3316 
3317  LWLockRelease(ControlFileLock);
3318 
3319  return true;
3320 }
int durable_unlink(const char *fname, int elevel)
Definition: fd.c:778
short access
Definition: preproc-type.c:36
bool InstallXLogFileSegmentActive
Definition: xlog.c:532
#define stat
Definition: win32_port.h:286

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

8917 {
8918  bool result;
8919 
8920  LWLockAcquire(ControlFileLock, LW_SHARED);
8922  LWLockRelease(ControlFileLock);
8923 
8924  return result;
8925 }

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

8136 {
8137  char *msg = NULL;
8138  instr_time start;
8139 
8140  Assert(tli != 0);
8141 
8142  /*
8143  * Quick exit if fsync is disabled or write() has already synced the WAL
8144  * file.
8145  */
8146  if (!enableFsync ||
8149  return;
8150 
8151  /* Measure I/O timing to sync the WAL file */
8152  if (track_wal_io_timing)
8153  INSTR_TIME_SET_CURRENT(start);
8154  else
8155  INSTR_TIME_SET_ZERO(start);
8156 
8158  switch (sync_method)
8159  {
8160  case SYNC_METHOD_FSYNC:
8161  if (pg_fsync_no_writethrough(fd) != 0)
8162  msg = _("could not fsync file \"%s\": %m");
8163  break;
8164 #ifdef HAVE_FSYNC_WRITETHROUGH
8166  if (pg_fsync_writethrough(fd) != 0)
8167  msg = _("could not fsync write-through file \"%s\": %m");
8168  break;
8169 #endif
8170  case SYNC_METHOD_FDATASYNC:
8171  if (pg_fdatasync(fd) != 0)
8172  msg = _("could not fdatasync file \"%s\": %m");
8173  break;
8174  case SYNC_METHOD_OPEN:
8176  /* not reachable */
8177  Assert(false);
8178  break;
8179  default:
8180  elog(PANIC, "unrecognized wal_sync_method: %d", sync_method);
8181  break;
8182  }
8183 
8184  /* PANIC if failed to fsync */
8185  if (msg)
8186  {
8187  char xlogfname[MAXFNAMELEN];
8188  int save_errno = errno;
8189 
8190  XLogFileName(xlogfname, tli, segno, wal_segment_size);
8191  errno = save_errno;
8192  ereport(PANIC,
8194  errmsg(msg, xlogfname)));
8195  }
8196 
8198 
8199  /*
8200  * Increment the I/O timing and the number of times WAL files were synced.
8201  */
8202  if (track_wal_io_timing)
8203  {
8205 
8207  INSTR_TIME_SUBTRACT(duration, start);
8209  }
8210 
8212 }
#define _(x)
Definition: elog.c:91
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:411
int pg_fdatasync(int fd)
Definition: fd.c:444
int pg_fsync_writethrough(int fd)
Definition: fd.c:423
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:122
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:181
#define INSTR_TIME_GET_MICROSEC(t)
Definition: instr_time.h:194
#define INSTR_TIME_SET_ZERO(t)
Definition: instr_time.h:172
int duration
Definition: pgbench.c:184
static int fd(const char *x, int i)
Definition: preproc-init.c:105
PgStat_Counter wal_sync_time
Definition: pgstat.h:432
PgStat_Counter wal_sync
Definition: pgstat.h:430
@ WAIT_EVENT_WAL_SYNC
Definition: wait_event.h:235
bool track_wal_io_timing
Definition: xlog.c:140

References _, Assert(), duration, elog(), enableFsync, ereport, errcode_for_file_access(), errmsg(), fd(), INSTR_TIME_GET_MICROSEC, INSTR_TIME_SET_CURRENT, INSTR_TIME_SET_ZERO, INSTR_TIME_SUBTRACT, MAXFNAMELEN, PANIC, PendingWalStats, pg_fdatasync(), pg_fsync_no_writethrough(), pg_fsync_writethrough(), pgstat_report_wait_end(), pgstat_report_wait_start(), sync_method, SYNC_METHOD_FDATASYNC, SYNC_METHOD_FSYNC, SYNC_METHOD_FSYNC_WRITETHROUGH, SYNC_METHOD_OPEN, SYNC_METHOD_OPEN_DSYNC, track_wal_io_timing, WAIT_EVENT_WAL_SYNC, wal_segment_size, PgStat_WalStats::wal_sync, PgStat_WalStats::wal_sync_time, and XLogFileName().

Referenced by XLogWalRcvFlush(), and XLogWrite().

◆ KeepLogSeg()

static void KeepLogSeg ( XLogRecPtr  recptr,
XLogSegNo logSegNo 
)
static

Definition at line 7431 of file xlog.c.

7432 {
7433  XLogSegNo currSegNo;
7434  XLogSegNo segno;
7435  XLogRecPtr keep;
7436 
7437  XLByteToSeg(recptr, currSegNo, wal_segment_size);
7438  segno = currSegNo;
7439 
7440  /*
7441  * Calculate how many segments are kept by slots first, adjusting for
7442  * max_slot_wal_keep_size.
7443  */
7445  if (keep != InvalidXLogRecPtr)
7446  {
7447  XLByteToSeg(keep, segno, wal_segment_size);
7448 
7449  /* Cap by max_slot_wal_keep_size ... */
7450  if (max_slot_wal_keep_size_mb >= 0)
7451  {
7452  uint64 slot_keep_segs;
7453 
7454  slot_keep_segs =
7456 
7457  if (currSegNo - segno > slot_keep_segs)
7458  segno = currSegNo - slot_keep_segs;
7459  }
7460  }
7461 
7462  /* but, keep at least wal_keep_size if that's set */
7463  if (wal_keep_size_mb > 0)
7464  {
7465  uint64 keep_segs;
7466 
7468  if (currSegNo - segno < keep_segs)
7469  {
7470  /* avoid underflow, don't go below 1 */
7471  if (currSegNo <= keep_segs)
7472  segno = 1;
7473  else
7474  segno = currSegNo - keep_segs;
7475  }
7476  }
7477 
7478  /* don't delete WAL segments newer than the calculated segment */
7479  if (segno < *logSegNo)
7480  *logSegNo = segno;
7481 }
int wal_keep_size_mb
Definition: xlog.c:119
static XLogRecPtr XLogGetReplicationSlotMinimumLSN(void)
Definition: xlog.c:2413
int max_slot_wal_keep_size_mb
Definition: xlog.c:138

References ConvertToXSegs, 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 4463 of file xlog.c.

4464 {
4465  Assert(reset || ControlFile == NULL);
4466  ControlFile = palloc(sizeof(ControlFileData));
4467  ReadControlFile();
4468 }
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 5996 of file xlog.c.

5997 {
5998  int oldXLogAllowed = LocalXLogInsertAllowed;
5999 
6001 
6002  return oldXLogAllowed;
6003 }

References LocalXLogInsertAllowed.

Referenced by CreateCheckPoint(), and StartupXLOG().

◆ LogCheckpointEnd()

static void LogCheckpointEnd ( bool  restartpoint)
static

Definition at line 6238 of file xlog.c.

6239 {
6240  long write_msecs,
6241  sync_msecs,
6242  total_msecs,
6243  longest_msecs,
6244  average_msecs;
6245  uint64 average_sync_time;
6246 
6248 
6251 
6254 
6255  /* Accumulate checkpoint timing summary data, in milliseconds. */
6258 
6259  /*
6260  * All of the published timing statistics are accounted for. Only
6261  * continue if a log message is to be written.
6262  */
6263  if (!log_checkpoints)
6264  return;
6265 
6268 
6269  /*
6270  * Timing values returned from CheckpointStats are in microseconds.
6271  * Convert to milliseconds for consistent printing.
6272  */
6273  longest_msecs = (long) ((CheckpointStats.ckpt_longest_sync + 999) / 1000);
6274 
6275  average_sync_time = 0;
6277  average_sync_time = CheckpointStats.ckpt_agg_sync_time /
6279  average_msecs = (long) ((average_sync_time + 999) / 1000);
6280 
6281  /*
6282  * ControlFileLock is not required to see ControlFile->checkPoint and
6283  * ->checkPointCopy here as we are the only updator of those variables at
6284  * this moment.
6285  */
6286  if (restartpoint)
6287  ereport(LOG,
6288  (errmsg("restartpoint complete: wrote %d buffers (%.1f%%); "
6289  "%d WAL file(s) added, %d removed, %d recycled; "
6290  "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; "
6291  "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; "
6292  "distance=%d kB, estimate=%d kB; "
6293  "lsn=%X/%X, redo lsn=%X/%X",
6295  (double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
6299  write_msecs / 1000, (int) (write_msecs % 1000),
6300  sync_msecs / 1000, (int) (sync_msecs % 1000),
6301  total_msecs / 1000, (int) (total_msecs % 1000),
6303  longest_msecs / 1000, (int) (longest_msecs % 1000),
6304  average_msecs / 1000, (int) (average_msecs % 1000),
6305  (int) (PrevCheckPointDistance / 1024.0),
6306  (int) (CheckPointDistanceEstimate / 1024.0),
6309  else
6310  ereport(LOG,
6311  (errmsg("checkpoint complete: wrote %d buffers (%.1f%%); "
6312  "%d WAL file(s) added, %d removed, %d recycled; "
6313  "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; "
6314  "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; "
6315  "distance=%d kB, estimate=%d kB; "
6316  "lsn=%X/%X, redo lsn=%X/%X",
6318  (double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
6322  write_msecs / 1000, (int) (write_msecs % 1000),
6323  sync_msecs / 1000, (int) (sync_msecs % 1000),
6324  total_msecs / 1000, (int) (total_msecs % 1000),
6326  longest_msecs / 1000, (int) (longest_msecs % 1000),
6327  average_msecs / 1000, (int) (average_msecs % 1000),
6328  (int) (PrevCheckPointDistance / 1024.0),
6329  (int) (CheckPointDistanceEstimate / 1024.0),
6332 }
long TimestampDifferenceMilliseconds(TimestampTz start_time, TimestampTz stop_time)
Definition: timestamp.c:1703
PgStat_CheckpointerStats PendingCheckpointerStats
uint64 ckpt_agg_sync_time
Definition: xlog.h:170
uint64 ckpt_longest_sync
Definition: xlog.h:169
TimestampTz ckpt_end_t
Definition: xlog.h:160
int ckpt_sync_rels
Definition: xlog.h:168
PgStat_Counter checkpoint_sync_time
Definition: pgstat.h:265
PgStat_Counter checkpoint_write_time
Definition: pgstat.h:264
static double CheckPointDistanceEstimate
Definition: xlog.c:162
static double PrevCheckPointDistance
Definition: xlog.c:163

References ControlFileData::checkPoint, PgStat_CheckpointerStats::checkpoint_sync_time, PgStat_CheckpointerStats::checkpoint_write_time, 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, and TimestampDifferenceMilliseconds().

Referenced by CreateCheckPoint(), and CreateRestartPoint().

◆ LogCheckpointStart()

static void LogCheckpointStart ( int  flags,
bool  restartpoint 
)
static

Definition at line 6206 of file xlog.c.

6207 {
6208  if (restartpoint)
6209  ereport(LOG,
6210  /* translator: the placeholders show checkpoint options */
6211  (errmsg("restartpoint starting:%s%s%s%s%s%s%s%s",
6212  (flags & CHECKPOINT_IS_SHUTDOWN) ? " shutdown" : "",
6213  (flags & CHECKPOINT_END_OF_RECOVERY) ? " end-of-recovery" : "",
6214  (flags & CHECKPOINT_IMMEDIATE) ? " immediate" : "",
6215  (flags & CHECKPOINT_FORCE) ? " force" : "",
6216  (flags & CHECKPOINT_WAIT) ? " wait" : "",
6217  (flags & CHECKPOINT_CAUSE_XLOG) ? " wal" : "",
6218  (flags & CHECKPOINT_CAUSE_TIME) ? " time" : "",
6219  (flags & CHECKPOINT_FLUSH_ALL) ? " flush-all" : "")));
6220  else
6221  ereport(LOG,
6222  /* translator: the placeholders show checkpoint options */
6223  (errmsg("checkpoint starting:%s%s%s%s%s%s%s%s",
6224  (flags & CHECKPOINT_IS_SHUTDOWN) ? " shutdown" : "",
6225  (flags & CHECKPOINT_END_OF_RECOVERY) ? " end-of-recovery" : "",
6226  (flags & CHECKPOINT_IMMEDIATE) ? " immediate" : "",
6227  (flags & CHECKPOINT_FORCE) ? " force" : "",
6228  (flags & CHECKPOINT_WAIT) ? " wait" : "",
6229  (flags & CHECKPOINT_CAUSE_XLOG) ? " wal" : "",
6230  (flags & CHECKPOINT_CAUSE_TIME) ? " time" : "",
6231  (flags & CHECKPOINT_FLUSH_ALL) ? " flush-all" : "")));
6232 }
#define CHECKPOINT_CAUSE_XLOG
Definition: xlog.h:143
#define CHECKPOINT_FLUSH_ALL
Definition: xlog.h:138
#define CHECKPOINT_CAUSE_TIME
Definition: xlog.h:144

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

5859 {
5860  bool promoted = false;
5861 
5862  /*
5863  * Perform a checkpoint to update all our recovery activity to disk.
5864  *
5865  * Note that we write a shutdown checkpoint rather than an on-line one.
5866  * This is not particularly critical, but since we may be assigning a new
5867  * TLI, using a shutdown checkpoint allows us to have the rule that TLI
5868  * only changes in shutdown checkpoints, which allows some extra error
5869  * checking in xlog_redo.
5870  *
5871  * In promotion, only create a lightweight end-of-recovery record instead
5872  * of a full checkpoint. A checkpoint is requested later, after we're
5873  * fully out of recovery mode and already accepting queries.
5874  */
5877  {
5878  promoted = true;
5879 
5880  /*
5881  * Insert a special WAL record to mark the end of recovery, since we
5882  * aren't doing a checkpoint. That means that the checkpointer process
5883  * may likely be in the middle of a time-smoothed restartpoint and
5884  * could continue to be for minutes after this. That sounds strange,
5885  * but the effect is roughly the same and it would be stranger to try
5886  * to come out of the restartpoint and then checkpoint. We request a
5887  * checkpoint later anyway, just for safety.
5888  */
5890  }
5891  else
5892  {
5895  CHECKPOINT_WAIT);
5896  }
5897 
5898  return promoted;
5899 }
static void CreateEndOfRecoveryRecord(void)
Definition: xlog.c:6862
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 3398 of file xlog.c.

3399 {
3400  XLogSegNo _logSegNo;
3401  int lf;
3402  bool added;
3403  char path[MAXPGPATH];
3404  uint64 offset;
3405 
3407  return; /* unlocked check says no */
3408 
3409  XLByteToPrevSeg(endptr, _logSegNo, wal_segment_size);
3410  offset = XLogSegmentOffset(endptr - 1, wal_segment_size);
3411  if (offset >= (uint32) (0.75 * wal_segment_size))
3412  {
3413  _logSegNo++;
3414  lf = XLogFileInitInternal(_logSegNo, tli, &added, path);
3415  if (lf >= 0)
3416  close(lf);
3417  if (added)
3419  }
3420 }
static int XLogFileInitInternal(XLogSegNo logsegno, TimeLineID logtli, bool *added, char *path)
Definition: xlog.c:2922

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

5822 {
5823  /*
5824  * We have reached the end of base backup, as indicated by pg_control. The
5825  * data on disk is now consistent (unless minRecovery point is further
5826  * ahead, which can happen if we crashed during previous recovery). Reset
5827  * backupStartPoint and backupEndPoint, and update minRecoveryPoint to
5828  * make sure we don't allow starting up at an earlier point even if
5829  * recovery is stopped and restarted soon after this.
5830  */
5831  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
5832 
5833  if (ControlFile->minRecoveryPoint < EndRecPtr)
5834  {
5835  ControlFile->minRecoveryPoint = EndRecPtr;
5837  }
5838 
5841  ControlFile->backupEndRequired = false;
5843 
5844  LWLockRelease(ControlFileLock);
5845 }
XLogRecPtr backupStartPoint
Definition: pg_control.h:168
bool backupEndRequired
Definition: pg_control.h:170
XLogRecPtr backupEndPoint
Definition: pg_control.h:169

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

3969 {
3970  pg_crc32c crc;
3971  int fd;
3972  static char wal_segsz_str[20];
3973  int r;
3974 
3975  /*
3976  * Read data...
3977  */
3979  O_RDWR | PG_BINARY);
3980  if (fd < 0)
3981  ereport(PANIC,
3983  errmsg("could not open file \"%s\": %m",
3984  XLOG_CONTROL_FILE)));
3985 
3987  r = read(fd, ControlFile, sizeof(ControlFileData));
3988  if (r != sizeof(ControlFileData))
3989  {
3990  if (r < 0)
3991  ereport(PANIC,
3993  errmsg("could not read file \"%s\": %m",
3994  XLOG_CONTROL_FILE)));
3995  else
3996  ereport(PANIC,
3998  errmsg("could not read file \"%s\": read %d of %zu",
3999  XLOG_CONTROL_FILE, r, sizeof(ControlFileData))));
4000  }
4002 
4003  close(fd);
4004 
4005  /*
4006  * Check for expected pg_control format version. If this is wrong, the
4007  * CRC check will likely fail because we'll be checking the wrong number
4008  * of bytes. Complaining about wrong version will probably be more
4009  * enlightening than complaining about wrong CRC.
4010  */
4011 
4013  ereport(FATAL,
4014  (errmsg("database files are incompatible with server"),
4015  errdetail("The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x),"
4016  " but the server was compiled with PG_CONTROL_VERSION %d (0x%08x).",
4019  errhint("This could be a problem of mismatched byte ordering. It looks like you need to initdb.")));
4020 
4022  ereport(FATAL,
4023  (errmsg("database files are incompatible with server"),
4024  errdetail("The database cluster was initialized with PG_CONTROL_VERSION %d,"
4025  " but the server was compiled with PG_CONTROL_VERSION %d.",
4027  errhint("It looks like you need to initdb.")));
4028 
4029  /* Now check the CRC. */
4030  INIT_CRC32C(crc);
4031  COMP_CRC32C(crc,
4032  (char *) ControlFile,
4033  offsetof(ControlFileData, crc));
4034  FIN_CRC32C(crc);
4035 
4036  if (!EQ_CRC32C(crc, ControlFile->crc))
4037  ereport(FATAL,
4038  (errmsg("incorrect checksum in control file")));
4039 
4040  /*
4041  * Do compatibility checking immediately. If the database isn't
4042  * compatible with the backend executable, we want to abort before we can
4043  * possibly do any damage.
4044  */
4046  ereport(FATAL,
4047  (errmsg("database files are incompatible with server"),
4048  errdetail("The database cluster was initialized with CATALOG_VERSION_NO %d,"
4049  " but the server was compiled with CATALOG_VERSION_NO %d.",
4051  errhint("It looks like you need to initdb.")));
4052  if (ControlFile->maxAlign != MAXIMUM_ALIGNOF)
4053  ereport(FATAL,
4054  (errmsg("database files are incompatible with server"),
4055  errdetail("The database cluster was initialized with MAXALIGN %d,"
4056  " but the server was compiled with MAXALIGN %d.",
4057  ControlFile->maxAlign, MAXIMUM_ALIGNOF),
4058  errhint("It looks like you need to initdb.")));
4060  ereport(FATAL,
4061  (errmsg("database files are incompatible with server"),
4062  errdetail("The database cluster appears to use a different floating-point number format than the server executable."),
4063  errhint("It looks like you need to initdb.")));
4064  if (ControlFile->blcksz != BLCKSZ)
4065  ereport(FATAL,
4066  (errmsg("database files are incompatible with server"),
4067  errdetail("The database cluster was initialized with BLCKSZ %d,"
4068  " but the server was compiled with BLCKSZ %d.",
4069  ControlFile->blcksz, BLCKSZ),
4070  errhint("It looks like you need to recompile or initdb.")));
4071  if (ControlFile->relseg_size != RELSEG_SIZE)
4072  ereport(FATAL,
4073  (errmsg("database files are incompatible with server"),
4074  errdetail("The database cluster was initialized with RELSEG_SIZE %d,"
4075  " but the server was compiled with RELSEG_SIZE %d.",
4076  ControlFile->relseg_size, RELSEG_SIZE),
4077  errhint("It looks like you need to recompile or initdb.")));
4078  if (ControlFile->xlog_blcksz != XLOG_BLCKSZ)
4079  ereport(FATAL,
4080  (errmsg("database files are incompatible with server"),
4081  errdetail("The database cluster was initialized with XLOG_BLCKSZ %d,"
4082  " but the server was compiled with XLOG_BLCKSZ %d.",
4083  ControlFile->xlog_blcksz, XLOG_BLCKSZ),
4084  errhint("It looks like you need to recompile or initdb.")));
4086  ereport(FATAL,
4087  (errmsg("database files are incompatible with server"),
4088  errdetail("The database cluster was initialized with NAMEDATALEN %d,"
4089  " but the server was compiled with NAMEDATALEN %d.",
4091  errhint("It looks like you need to recompile or initdb.")));
4093  ereport(FATAL,
4094  (errmsg("database files are incompatible with server"),
4095  errdetail("The database cluster was initialized with INDEX_MAX_KEYS %d,"
4096  " but the server was compiled with INDEX_MAX_KEYS %d.",
4098  errhint("It looks like you need to recompile or initdb.")));
4100  ereport(FATAL,
4101  (errmsg("database files are incompatible with server"),
4102  errdetail("The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d,"
4103  " but the server was compiled with TOAST_MAX_CHUNK_SIZE %d.",
4105  errhint("It looks like you need to recompile or initdb.")));
4107  ereport(FATAL,
4108  (errmsg("database files are incompatible with server"),
4109  errdetail("The database cluster was initialized with LOBLKSIZE %d,"
4110  " but the server was compiled with LOBLKSIZE %d.",
4111  ControlFile->loblksize, (int) LOBLKSIZE),
4112  errhint("It looks like you need to recompile or initdb.")));
4113 
4114 #ifdef USE_FLOAT8_BYVAL
4115  if (ControlFile->float8ByVal != true)
4116  ereport(FATAL,
4117  (errmsg("database files are incompatible with server"),
4118  errdetail("The database cluster was initialized without USE_FLOAT8_BYVAL"
4119  " but the server was compiled with USE_FLOAT8_BYVAL."),
4120  errhint("It looks like you need to recompile or initdb.")));
4121 #else
4122  if (ControlFile->float8ByVal != false)
4123  ereport(FATAL,
4124  (errmsg("database files are incompatible with server"),
4125  errdetail("The database cluster was initialized with USE_FLOAT8_BYVAL"
4126  " but the server was compiled without USE_FLOAT8_BYVAL."),
4127  errhint("It looks like you need to recompile or initdb.")));
4128 #endif
4129 
4131 
4133  ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4134  errmsg_plural("WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte",
4135  "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes",
4137  wal_segment_size)));
4138 
4139  snprintf(wal_segsz_str, sizeof(wal_segsz_str), "%d", wal_segment_size);
4140  SetConfigOption("wal_segment_size", wal_segsz_str, PGC_INTERNAL,
4142 
4143  /* check and update variables dependent on wal_segment_size */
4145  ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4146  errmsg("\"min_wal_size\" must be at least twice \"wal_segment_size\"")));
4147 
4149  ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4150  errmsg("\"max_wal_size\" must be at least twice \"wal_segment_size\"")));
4151 
4153  (wal_segment_size / XLOG_BLCKSZ * UsableBytesInPage) -
4155 
4157 
4158  /* Make the initdb settings visible as GUC variables, too */
4159  SetConfigOption("data_checksums", DataChecksumsEnabled() ? "yes" : "no",
4161 }
#define PG_BINARY
Definition: c.h:1260
#define CATALOG_VERSION_NO
Definition: catversion.h:60
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1179
int BasicOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:993
void SetConfigOption(const char *name, const char *value, GucContext context, GucSource source)
Definition: guc.c:4176
@ PGC_S_DYNAMIC_DEFAULT
Definition: guc.h:110
@ PGC_INTERNAL
Definition: guc.h:69
#define TOAST_MAX_CHUNK_SIZE
Definition: heaptoast.h:84
#define read(a, b, c)
Definition: win32.h:13
#define LOBLKSIZE
Definition: large_object.h:70
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:41
#define INDEX_MAX_KEYS
#define NAMEDATALEN