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 MemSet(start, val, len)
Definition: c.h:953
size_t Size
Definition: c.h:541
#define DEBUG1
Definition: elog.h:26
static void Insert(File file)
Definition: fd.c:1226
pg_attribute_unused() static bool check_table(const char *(*TABLE)[2]
Assert(fmt[strlen(fmt) - 1] !='\n')
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1194
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1802
@ LW_EXCLUSIVE
Definition: lwlock.h:112
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:390
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 4377 of file xlog.c.

4378 {
4379  /*
4380  * If some checks were deferred, it's possible that the checks will fail
4381  * later during InitializeWalConsistencyChecking(). But in that case, the
4382  * postmaster will exit anyway, so it's safe to proceed with the
4383  * assignment.
4384  *
4385  * Any built-in resource managers specified are assigned immediately,
4386  * which affects WAL created before shared_preload_libraries are
4387  * processed. Any custom resource managers specified won't be assigned
4388  * until after shared_preload_libraries are processed, but that's OK
4389  * because WAL for a custom resource manager can't be written before the
4390  * module is loaded anyway.
4391  */
4392  wal_consistency_checking = extra;
4393 }
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 8096 of file xlog.c.

8097 {
8098  if (sync_method != new_sync_method)
8099  {
8100  /*
8101  * To ensure that no blocks escape unsynced, force an fsync on the
8102  * currently open log segment (if any). Also, if the open flag is
8103  * changing, close the log file so it will be reopened (with new flag
8104  * bit) at next use.
8105  */
8106  if (openLogFile >= 0)
8107  {
8109  if (pg_fsync(openLogFile) != 0)
8110  {
8111  char xlogfname[MAXFNAMELEN];
8112  int save_errno;
8113 
8114  save_errno = errno;
8115  XLogFileName(xlogfname, openLogTLI, openLogSegNo,
8117  errno = save_errno;
8118  ereport(PANIC,
8120  errmsg("could not fsync file \"%s\": %m", xlogfname)));
8121  }
8122 
8124  if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
8125  XLogFileClose();
8126  }
8127  }
8128 }
int errcode_for_file_access(void)
Definition: elog.c:718
int errmsg(const char *fmt,...)
Definition: elog.c:906
#define PANIC
Definition: elog.h:38
#define ereport(elevel,...)
Definition: elog.h:145
int pg_fsync(int fd)
Definition: fd.c:356
@ WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN
Definition: wait_event.h:233
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:268
static void pgstat_report_wait_end(void)
Definition: wait_event.h:284
static int openLogFile
Definition: xlog.c:618
static int get_sync_bit(int method)
Definition: xlog.c:8040
static TimeLineID openLogTLI
Definition: xlog.c:620
static void XLogFileClose(void)
Definition: xlog.c:3342
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 4637 of file xlog.c.

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

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

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

7001 {
7007 
7008  /* Write out all dirty data in SLRUs and the main buffer pool */
7009  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_START(flags);
7011  CheckPointCLOG();
7016  CheckPointBuffers(flags);
7017 
7018  /* Perform all queued up fsyncs */
7019  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_SYNC_START();
7023  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_DONE();
7024 
7025  /* We deliberately delay 2PC checkpointing as long as possible */
7026  CheckPointTwoPhase(checkPointRedo);
7027 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1573
void CheckPointBuffers(int flags)
Definition: bufmgr.c:2739
void CheckPointCLOG(void)
Definition: clog.c:817
void CheckPointCommitTs(void)
Definition: commit_ts.c:792
void CheckPointMultiXact(void)
Definition: multixact.c:2153
void CheckPointReplicationOrigin(void)
Definition: origin.c:569
void CheckPointPredicate(void)
Definition: predicate.c:1069
void CheckPointRelationMap(void)
Definition: relmapper.c:611
void CheckPointLogicalRewriteHeap(void)
Definition: rewriteheap.c:1189
void CheckPointReplicationSlots(void)
Definition: slot.c:1442
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 4981 of file xlog.c.

4982 {
4983  /*
4984  * For archive recovery, the WAL must be generated with at least 'replica'
4985  * wal_level.
4986  */
4988  {
4989  ereport(FATAL,
4990  (errmsg("WAL was generated with wal_level=minimal, cannot continue recovering"),
4991  errdetail("This happens if you temporarily set wal_level=minimal on the server."),
4992  errhint("Use a backup taken after setting wal_level to higher than minimal.")));
4993  }
4994 
4995  /*
4996  * For Hot Standby, the WAL must be generated with 'replica' mode, and we
4997  * must have at least as many backend slots as the primary.
4998  */
5000  {
5001  /* We ignore autovacuum_max_workers when we make this test. */
5002  RecoveryRequiresIntParameter("max_connections",
5005  RecoveryRequiresIntParameter("max_worker_processes",
5008  RecoveryRequiresIntParameter("max_wal_senders",
5011  RecoveryRequiresIntParameter("max_prepared_transactions",
5014  RecoveryRequiresIntParameter("max_locks_per_transaction",
5017  }
5018 }
int errdetail(const char *fmt,...)
Definition: elog.c:1039
int errhint(const char *fmt,...)
Definition: elog.c:1153
#define FATAL
Definition: elog.h:37
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 3430 of file xlog.c.

3431 {
3432  int save_errno = errno;
3433  XLogSegNo lastRemovedSegNo;
3434 
3436  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3438 
3439  if (segno <= lastRemovedSegNo)
3440  {
3441  char filename[MAXFNAMELEN];
3442 
3443  XLogFileName(filename, tli, segno, wal_segment_size);
3444  errno = save_errno;
3445  ereport(ERROR,
3447  errmsg("requested WAL segment %s has already been removed",
3448  filename)));
3449  }
3450  errno = save_errno;
3451 }
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 4892 of file xlog.c.

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

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

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:442
#define MAXALIGN64(LEN)
Definition: c.h:772
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 6440 of file xlog.c.

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

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

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

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

8818 {
8819  bool during_backup_start = DatumGetBool(arg);
8820 
8821  /* If called during backup start, there shouldn't be one already running */
8822  Assert(!during_backup_start || sessionBackupState == SESSION_BACKUP_NONE);
8823 
8824  if (during_backup_start || sessionBackupState != SESSION_BACKUP_NONE)
8825  {
8829 
8832 
8833  if (!during_backup_start)
8834  ereport(WARNING,
8835  errmsg("aborting backup due to backend exiting before pg_backup_stop was called"));
8836  }
8837 }
#define WARNING
Definition: elog.h:32
void * arg
static bool DatumGetBool(Datum X)
Definition: postgres.h:438
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 8244 of file xlog.c.

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

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

8525 {
8526  return sessionBackupState;
8527 }

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

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

4218 {
4219  XLogRecPtr nextUnloggedLSN;
4220 
4221  /* increment the unloggedLSN counter, need SpinLock */
4223  nextUnloggedLSN = XLogCtl->unloggedLSN++;
4225 
4226  return nextUnloggedLSN;
4227 }

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

Referenced by gistGetFakeLSN().

◆ GetFlushRecPtr()

XLogRecPtr GetFlushRecPtr ( TimeLineID insertTLI)

Definition at line 6077 of file xlog.c.

6078 {
6080 
6084 
6085  /*
6086  * If we're writing and flushing WAL, the time line can't be changing, so
6087  * no lock is required.
6088  */
6089  if (insertTLI)
6090  *insertTLI = XLogCtl->InsertTimeLineID;
6091 
6092  return LogwrtResult.Flush;
6093 }
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(), IdentifySystem(), IsFutureLSN(), 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 6045 of file xlog.c.

6046 {
6047  *RedoRecPtr_p = RedoRecPtr;
6048  *doPageWrites_p = doPageWrites;
6049 }
static bool doPageWrites
Definition: xlog.c:289

References doPageWrites, and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )

Definition at line 6060 of file xlog.c.

6061 {
6062  XLogRecPtr recptr;
6063 
6065  recptr = XLogCtl->LogwrtRqst.Write;
6067 
6068  return recptr;
6069 }

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

6118 {
6120  int i;
6121 
6122  for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
6123  {
6124  XLogRecPtr last_important;
6125 
6126  /*
6127  * Need to take a lock to prevent torn reads of the LSN, which are
6128  * possible on some of the supported platforms. WAL insert locks only
6129  * support exclusive mode, so we have to use that.
6130  */
6132  last_important = WALInsertLocks[i].l.lastImportantAt;
6133  LWLockRelease(&WALInsertLocks[i].l.lock);
6134 
6135  if (res < last_important)
6136  res = last_important;
6137  }
6138 
6139  return res;
6140 }
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 6146 of file xlog.c.

6147 {
6148  pg_time_t result;
6149 
6150  /* Need WALWriteLock, but shared lock is sufficient */
6151  LWLockAcquire(WALWriteLock, LW_SHARED);
6152  result = XLogCtl->lastSegSwitchTime;
6153  *lastSwitchLSN = XLogCtl->lastSegSwitchLSN;
6154  LWLockRelease(WALWriteLock);
6155 
6156  return result;
6157 }
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 4191 of file xlog.c.

4192 {
4193  Assert(ControlFile != NULL);
4195 }
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 8888 of file xlog.c.

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

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

5949 {
5950  RecoveryState retval;
5951 
5953  retval = XLogCtl->SharedRecoveryState;
5955 
5956  return retval;
5957 }
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 6015 of file xlog.c.

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

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

4182 {
4183  Assert(ControlFile != NULL);
4185 }

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

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

◆ GetWALAvailability()

WALAvailability GetWALAvailability ( XLogRecPtr  targetLSN)

Definition at line 7350 of file xlog.c.

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

6101 {
6103 
6104  /* Since the value can't be changing, no lock is required. */
6105  return XLogCtl->InsertTimeLineID;
6106 }

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

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

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

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

4405 {
4407 
4409  {
4410  struct config_generic *guc;
4411 
4412  guc = find_option("wal_consistency_checking", false, false, ERROR);
4413 
4415 
4416  set_config_option_ext("wal_consistency_checking",
4418  guc->scontext, guc->source, guc->srole,
4419  GUC_ACTION_SET, true, ERROR, false);
4420 
4421  /* checking should not be deferred again */
4423  }
4424 }
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:3306
@ 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 3267 of file xlog.c.

3269 {
3270  char path[MAXPGPATH];
3271  struct stat stat_buf;
3272 
3273  Assert(tli != 0);
3274 
3275  XLogFilePath(path, tli, *segno, wal_segment_size);
3276 
3277  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
3279  {
3280  LWLockRelease(ControlFileLock);
3281  return false;
3282  }
3283 
3284  if (!find_free)
3285  {
3286  /* Force installation: get rid of any pre-existing segment file */
3287  durable_unlink(path, DEBUG1);
3288  }
3289  else
3290  {
3291  /* Find a free slot to put it in */
3292  while (stat(path, &stat_buf) == 0)
3293  {
3294  if ((*segno) >= max_segno)
3295  {
3296  /* Failed to find a free slot within specified range */
3297  LWLockRelease(ControlFileLock);
3298  return false;
3299  }
3300  (*segno)++;
3301  XLogFilePath(path, tli, *segno, wal_segment_size);
3302  }
3303  }
3304 
3305  Assert(access(path, F_OK) != 0 && errno == ENOENT);
3306  if (durable_rename(tmppath, path, LOG) != 0)
3307  {
3308  LWLockRelease(ControlFileLock);
3309  /* durable_rename already emitted log message */
3310  return false;
3311  }
3312 
3313  LWLockRelease(ControlFileLock);
3314 
3315  return true;
3316 }
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 8917 of file xlog.c.

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

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

8139 {
8140  char *msg = NULL;
8141  instr_time start;
8142 
8143  Assert(tli != 0);
8144 
8145  /*
8146  * Quick exit if fsync is disabled or write() has already synced the WAL
8147  * file.
8148  */
8149  if (!enableFsync ||
8152  return;
8153 
8154  /* Measure I/O timing to sync the WAL file */
8155  if (track_wal_io_timing)
8156  INSTR_TIME_SET_CURRENT(start);
8157 
8159  switch (sync_method)
8160  {
8161  case SYNC_METHOD_FSYNC:
8162  if (pg_fsync_no_writethrough(fd) != 0)
8163  msg = _("could not fsync file \"%s\": %m");
8164  break;
8165 #ifdef HAVE_FSYNC_WRITETHROUGH
8167  if (pg_fsync_writethrough(fd) != 0)
8168  msg = _("could not fsync write-through file \"%s\": %m");
8169  break;
8170 #endif
8171  case SYNC_METHOD_FDATASYNC:
8172  if (pg_fdatasync(fd) != 0)
8173  msg = _("could not fdatasync file \"%s\": %m");
8174  break;
8175  case SYNC_METHOD_OPEN:
8177  /* not reachable */
8178  Assert(false);
8179  break;
8180  default:
8181  elog(PANIC, "unrecognized wal_sync_method: %d", sync_method);
8182  break;
8183  }
8184 
8185  /* PANIC if failed to fsync */
8186  if (msg)
8187  {
8188  char xlogfname[MAXFNAMELEN];
8189  int save_errno = errno;
8190 
8191  XLogFileName(xlogfname, tli, segno, wal_segment_size);
8192  errno = save_errno;
8193  ereport(PANIC,
8195  errmsg(msg, xlogfname)));
8196  }
8197 
8199 
8200  /*
8201  * Increment the I/O timing and the number of times WAL files were synced.
8202  */
8203  if (track_wal_io_timing)
8204  {
8206 
8208  INSTR_TIME_SUBTRACT(duration, start);
8210  }
8211 
8213 }
#define _(x)
Definition: elog.c:90
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:89
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:103
#define INSTR_TIME_GET_MICROSEC(t)
Definition: instr_time.h:138
struct timespec instr_time
Definition: instr_time.h:83
int duration
Definition: pgbench.c:183
static int fd(const char *x, int i)
Definition: preproc-init.c:105
PgStat_Counter wal_sync_time
Definition: pgstat.h:394
PgStat_Counter wal_sync
Definition: pgstat.h:392
@ WAIT_EVENT_WAL_SYNC
Definition: wait_event.h:232
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_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 7434 of file xlog.c.

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

4468 {
4469  Assert(reset || ControlFile == NULL);
4470  ControlFile = palloc(sizeof(ControlFileData));
4471  ReadControlFile();
4472 }
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 6000 of file xlog.c.

6001 {
6002  int oldXLogAllowed = LocalXLogInsertAllowed;
6003 
6005 
6006  return oldXLogAllowed;
6007 }

References LocalXLogInsertAllowed.

Referenced by CreateCheckPoint(), and StartupXLOG().

◆ LogCheckpointEnd()

static void LogCheckpointEnd ( bool  restartpoint)
static

Definition at line 6242 of file xlog.c.

6243 {
6244  long write_msecs,
6245  sync_msecs,
6246  total_msecs,
6247  longest_msecs,
6248  average_msecs;
6249  uint64 average_sync_time;
6250 
6252 
6255 
6258 
6259  /* Accumulate checkpoint timing summary data, in milliseconds. */
6262 
6263  /*
6264  * All of the published timing statistics are accounted for. Only
6265  * continue if a log message is to be written.
6266  */
6267  if (!log_checkpoints)
6268  return;
6269 
6272 
6273  /*
6274  * Timing values returned from CheckpointStats are in microseconds.
6275  * Convert to milliseconds for consistent printing.
6276  */
6277  longest_msecs = (long) ((CheckpointStats.ckpt_longest_sync + 999) / 1000);
6278 
6279  average_sync_time = 0;
6281  average_sync_time = CheckpointStats.ckpt_agg_sync_time /
6283  average_msecs = (long) ((average_sync_time + 999) / 1000);
6284 
6285  /*
6286  * ControlFileLock is not required to see ControlFile->checkPoint and
6287  * ->checkPointCopy here as we are the only updator of those variables at
6288  * this moment.
6289  */
6290  if (restartpoint)
6291  ereport(LOG,
6292  (errmsg("restartpoint complete: wrote %d buffers (%.1f%%); "
6293  "%d WAL file(s) added, %d removed, %d recycled; "
6294  "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; "
6295  "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; "
6296  "distance=%d kB, estimate=%d kB; "
6297  "lsn=%X/%X, redo lsn=%X/%X",
6299  (double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
6303  write_msecs / 1000, (int) (write_msecs % 1000),
6304  sync_msecs / 1000, (int) (sync_msecs % 1000),
6305  total_msecs / 1000, (int) (total_msecs % 1000),
6307  longest_msecs / 1000, (int) (longest_msecs % 1000),
6308  average_msecs / 1000, (int) (average_msecs % 1000),
6309  (int) (PrevCheckPointDistance / 1024.0),
6310  (int) (CheckPointDistanceEstimate / 1024.0),
6313  else
6314  ereport(LOG,
6315  (errmsg("checkpoint complete: wrote %d buffers (%.1f%%); "
6316  "%d WAL file(s) added, %d removed, %d recycled; "
6317  "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; "
6318  "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; "
6319  "distance=%d kB, estimate=%d kB; "
6320  "lsn=%X/%X, redo lsn=%X/%X",
6322  (double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
6326  write_msecs / 1000, (int) (write_msecs % 1000),
6327  sync_msecs / 1000, (int) (sync_msecs % 1000),
6328  total_msecs / 1000, (int) (total_msecs % 1000),
6330  longest_msecs / 1000, (int) (longest_msecs % 1000),
6331  average_msecs / 1000, (int) (average_msecs % 1000),
6332  (int) (PrevCheckPointDistance / 1024.0),
6333  (int) (CheckPointDistanceEstimate / 1024.0),
6336 }
long TimestampDifferenceMilliseconds(TimestampTz start_time, TimestampTz stop_time)
Definition: timestamp.c:1701
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:273
PgStat_Counter checkpoint_write_time
Definition: pgstat.h:272
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 6210 of file xlog.c.

6211 {
6212  if (restartpoint)
6213  ereport(LOG,
6214  /* translator: the placeholders show checkpoint options */
6215  (errmsg("restartpoint starting:%s%s%s%s%s%s%s%s",
6216  (flags & CHECKPOINT_IS_SHUTDOWN) ? " shutdown" : "",
6217  (flags & CHECKPOINT_END_OF_RECOVERY) ? " end-of-recovery" : "",
6218  (flags & CHECKPOINT_IMMEDIATE) ? " immediate" : "",
6219  (flags & CHECKPOINT_FORCE) ? " force" : "",
6220  (flags & CHECKPOINT_WAIT) ? " wait" : "",
6221  (flags & CHECKPOINT_CAUSE_XLOG) ? " wal" : "",
6222  (flags & CHECKPOINT_CAUSE_TIME) ? " time" : "",
6223  (flags & CHECKPOINT_FLUSH_ALL) ? " flush-all" : "")));
6224  else
6225  ereport(LOG,
6226  /* translator: the placeholders show checkpoint options */
6227  (errmsg("checkpoint starting:%s%s%s%s%s%s%s%s",
6228  (flags & CHECKPOINT_IS_SHUTDOWN) ? " shutdown" : "",
6229  (flags & CHECKPOINT_END_OF_RECOVERY) ? " end-of-recovery" : "",
6230  (flags & CHECKPOINT_IMMEDIATE) ? " immediate" : "",
6231  (flags & CHECKPOINT_FORCE) ? " force" : "",
6232  (flags & CHECKPOINT_WAIT) ? " wait" : "",
6233  (flags & CHECKPOINT_CAUSE_XLOG) ? " wal" : "",
6234  (flags & CHECKPOINT_CAUSE_TIME) ? " time" : "",
6235  (flags & CHECKPOINT_FLUSH_ALL) ? " flush-all" : "")));
6236 }
#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 5862 of file xlog.c.

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

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

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

5826 {
5827  /*
5828  * We have reached the end of base backup, as indicated by pg_control. The
5829  * data on disk is now consistent (unless minRecovery point is further
5830  * ahead, which can happen if we crashed during previous recovery). Reset
5831  * backupStartPoint and backupEndPoint, and update minRecoveryPoint to
5832  * make sure we don't allow starting up at an earlier point even if
5833  * recovery is stopped and restarted soon after this.
5834  */
5835  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
5836 
5837  if (ControlFile->minRecoveryPoint < EndRecPtr)
5838  {
5839  ControlFile->minRecoveryPoint = EndRecPtr;
5841  }
5842 
5845  ControlFile->backupEndRequired = false;
5847 
5848  LWLockRelease(ControlFileLock);
5849 }
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 3972 of file xlog.c.

3973 {
3974  pg_crc32c crc;
3975  int fd;
3976  static char wal_segsz_str[20];
3977  int r;
3978 
3979  /*
3980  * Read data...
3981  */
3983  O_RDWR | PG_BINARY);
3984  if (fd < 0)
3985  ereport(PANIC,
3987  errmsg("could not open file \"%s\": %m",
3988  XLOG_CONTROL_FILE)));
3989 
3991  r = read(fd, ControlFile, sizeof(ControlFileData));
3992  if (r != sizeof(ControlFileData))
3993  {
3994  if (r < 0)
3995  ereport(PANIC,
3997  errmsg("could not read file \"%s\": %m",
3998  XLOG_CONTROL_FILE)));
3999  else
4000  ereport(PANIC,
4002  errmsg("could not read file \"%s\": read %d of %zu",
4003  XLOG_CONTROL_FILE, r, sizeof(ControlFileData))));
4004  }
4006 
4007  close(fd);
4008 
4009  /*
4010  * Check for expected pg_control format version. If this is wrong, the
4011  * CRC check will likely fail because we'll be checking the wrong number
4012  * of bytes. Complaining about wrong version will probably be more
4013  * enlightening than complaining about wrong CRC.
4014  */
4015 
4017  ereport(FATAL,
4018  (errmsg("database files are incompatible with server"),
4019  errdetail("The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x),"
4020  " but the server was compiled with PG_CONTROL_VERSION %d (0x%08x).",
4023  errhint("This could be a problem of mismatched byte ordering. It looks like you need to initdb.")));
4024 
4026  ereport(FATAL,
4027  (errmsg("database files are incompatible with server"),
4028  errdetail("The database cluster was initialized with PG_CONTROL_VERSION %d,"
4029  " but the server was compiled with PG_CONTROL_VERSION %d.",
4031  errhint("It looks like you need to initdb.")));
4032 
4033  /* Now check the CRC. */
4034  INIT_CRC32C(crc);
4035  COMP_CRC32C(crc,
4036  (char *) ControlFile,
4037  offsetof(ControlFileData, crc));
4038  FIN_CRC32C(crc);
4039 
4040  if (!EQ_CRC32C(crc, ControlFile->crc))
4041  ereport(FATAL,
4042  (errmsg("incorrect checksum in control file")));
4043 
4044  /*
4045  * Do compatibility checking immediately. If the database isn't
4046  * compatible with the backend executable, we want to abort before we can
4047  * possibly do any damage.
4048  */
4050  ereport(FATAL,
4051  (errmsg("database files are incompatible with server"),
4052  errdetail("The database cluster was initialized with CATALOG_VERSION_NO %d,"
4053  " but the server was compiled with CATALOG_VERSION_NO %d.",
4055  errhint("It looks like you need to initdb.")));
4056  if (ControlFile->maxAlign != MAXIMUM_ALIGNOF)
4057  ereport(FATAL,
4058  (errmsg("database files are incompatible with server"),
4059  errdetail("The database cluster was initialized with MAXALIGN %d,"
4060  " but the server was compiled with MAXALIGN %d.",
4061  ControlFile->maxAlign, MAXIMUM_ALIGNOF),
4062  errhint("It looks like you need to initdb.")));
4064  ereport(FATAL,
4065  (errmsg("database files are incompatible with server"),
4066  errdetail("The database cluster appears to use a different floating-point number format than the server executable."),
4067  errhint("It looks like you need to initdb.")));
4068  if (ControlFile->blcksz != BLCKSZ)
4069  ereport(FATAL,
4070  (errmsg("database files are incompatible with server"),
4071  errdetail("The database cluster was initialized with BLCKSZ %d,"
4072  " but the server was compiled with BLCKSZ %d.",
4073  ControlFile->blcksz, BLCKSZ),
4074  errhint("It looks like you need to recompile or initdb.")));
4075  if (ControlFile->relseg_size != RELSEG_SIZE)
4076  ereport(FATAL,
4077  (errmsg("database files are incompatible with server"),
4078  errdetail("The database cluster was initialized with RELSEG_SIZE %d,"
4079  " but the server was compiled with RELSEG_SIZE %d.",
4080  ControlFile->relseg_size, RELSEG_SIZE),
4081  errhint("It looks like you need to recompile or initdb.")));
4082  if (ControlFile->xlog_blcksz != XLOG_BLCKSZ)
4083  ereport(FATAL,
4084  (errmsg("database files are incompatible with server"),
4085  errdetail("The database cluster was initialized with XLOG_BLCKSZ %d,"
4086  " but the server was compiled with XLOG_BLCKSZ %d.",
4087  ControlFile->xlog_blcksz, XLOG_BLCKSZ),
4088  errhint("It looks like you need to recompile or initdb.")));
4090  ereport(FATAL,
4091  (errmsg("database files are incompatible with server"),
4092  errdetail("The database cluster was initialized with NAMEDATALEN %d,"
4093  " but the server was compiled with NAMEDATALEN %d.",
4095  errhint("It looks like you need to recompile or initdb.")));
4097  ereport(FATAL,
4098  (errmsg("database files are incompatible with server"),
4099  errdetail("The database cluster was initialized with INDEX_MAX_KEYS %d,"
4100  " but the server was compiled with INDEX_MAX_KEYS %d.",
4102  errhint("It looks like you need to recompile or initdb.")));
4104  ereport(FATAL,
4105  (errmsg("database files are incompatible with server"),
4106  errdetail("The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d,"
4107  " but the server was compiled with TOAST_MAX_CHUNK_SIZE %d.",
4109  errhint("It looks like you need to recompile or initdb.")));
4111  ereport(FATAL,
4112  (errmsg("database files are incompatible with server"),
4113  errdetail("The database cluster was initialized with LOBLKSIZE %d,"
4114  " but the server was compiled with LOBLKSIZE %d.",
4115  ControlFile->loblksize, (int) LOBLKSIZE),
4116  errhint("It looks like you need to recompile or initdb.")));
4117 
4118 #ifdef USE_FLOAT8_BYVAL
4119  if (ControlFile->float8ByVal != true)
4120  ereport(FATAL,
4121  (errmsg("database files are incompatible with server"),
4122  errdetail("The database cluster was initialized without USE_FLOAT8_BYVAL"
4123  " but the server was compiled with USE_FLOAT8_BYVAL."),
4124  errhint("It looks like you need to recompile or initdb.")));
4125 #else
4126  if (ControlFile->float8ByVal != false)
4127  ereport(FATAL,
4128  (errmsg("database files are incompatible with server"),
4129  errdetail("The database cluster was initialized with USE_FLOAT8_BYVAL"
4130  " but the server was compiled without USE_FLOAT8_BYVAL."),
4131  errhint("It looks like you need to recompile or initdb.")));
4132 #endif
4133 
4135 
4137  ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4138  errmsg_plural("WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte",
4139  "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes",
4141  wal_segment_size)));
4142 
4143  snprintf(wal_segsz_str, sizeof(wal_segsz_str), "%d", wal_segment_size);
4144  SetConfigOption("wal_segment_size", wal_segsz_str, PGC_INTERNAL,
4146 
4147  /* check and update variables dependent on wal_segment_size */
4149  ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4150  errmsg("\"min_wal_size\" must be at least twice \"wal_segment_size\"")));
4151 
4153  ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4154  errmsg("\"max_wal_size\" must be at least twice \"wal_segment_size\"")));
4155 
4157  (wal_segment_size / XLOG_BLCKSZ * UsableBytesInPage) -
4159 
4161 
4162  /* Make the initdb settings visible as GUC variables, too */
4163  SetConfigOption("data_checksums", DataChecksumsEnabled() ? "yes" : "no",
4165 }
#define PG_BINARY
Definition: c.h:1209
#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:1016
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:4158
@ 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
#define FLOATFORMAT_VALUE
Definition: pg_control.h:199
#define PG_CONTROL_VERSION
Definition: pg_control.h:25