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 "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/basebackup.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.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 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 missingContrecPtr, 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 char *segname, 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 void pg_backup_start_callback (int code, Datum arg)
 
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)
 
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)
 
XLogRecPtr do_pg_backup_start (const char *backupidstr, bool fast, TimeLineID *starttli_p, StringInfo labelfile, List **tablespaces, StringInfo tblspcmapfile)
 
SessionBackupState get_backup_status (void)
 
XLogRecPtr do_pg_backup_stop (char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 
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_MINIMAL
 
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
 
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 112 of file xlog.c.

◆ ConvertToXSegs

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

Definition at line 595 of file xlog.c.

◆ INSERT_FREESPACE

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

Definition at line 572 of file xlog.c.

◆ NextBufIdx

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

Definition at line 576 of file xlog.c.

◆ NUM_XLOGINSERT_LOCKS

#define NUM_XLOGINSERT_LOCKS   8

Definition at line 151 of file xlog.c.

◆ UsableBytesInPage

#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)

Definition at line 589 of file xlog.c.

◆ XLogRecPtrToBufIdx

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

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

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

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

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

◆ assign_max_wal_size()

void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 1971 of file xlog.c.

1972 {
1975 }
int max_wal_size_mb
Definition: xlog.c:115

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

◆ assign_xlog_sync_method()

void assign_xlog_sync_method ( int  new_sync_method,
void *  extra 
)

Definition at line 7935 of file xlog.c.

7936 {
7937  if (sync_method != new_sync_method)
7938  {
7939  /*
7940  * To ensure that no blocks escape unsynced, force an fsync on the
7941  * currently open log segment (if any). Also, if the open flag is
7942  * changing, close the log file so it will be reopened (with new flag
7943  * bit) at next use.
7944  */
7945  if (openLogFile >= 0)
7946  {
7948  if (pg_fsync(openLogFile) != 0)
7949  {
7950  char xlogfname[MAXFNAMELEN];
7951  int save_errno;
7952 
7953  save_errno = errno;
7954  XLogFileName(xlogfname, openLogTLI, openLogSegNo,
7956  errno = save_errno;
7957  ereport(PANIC,
7959  errmsg("could not fsync file \"%s\": %m", xlogfname)));
7960  }
7961 
7963  if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
7964  XLogFileClose();
7965  }
7966  }
7967 }
int errcode_for_file_access(void)
Definition: elog.c:716
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define PANIC
Definition: elog.h:36
#define ereport(elevel,...)
Definition: elog.h:143
int pg_fsync(int fd)
Definition: fd.c:359
@ WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN
Definition: wait_event.h:231
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:266
static void pgstat_report_wait_end(void)
Definition: wait_event.h:282
static int openLogFile
Definition: xlog.c:614
static int get_sync_bit(int method)
Definition: xlog.c:7879
static TimeLineID openLogTLI
Definition: xlog.c:616
static void XLogFileClose(void)
Definition: xlog.c:3366
static XLogSegNo openLogSegNo
Definition: xlog.c:615
int sync_method
Definition: xlog.c:131
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
#define MAXFNAMELEN

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

4497 {
4498  CheckPoint checkPoint;
4499  char *buffer;
4500  XLogPageHeader page;
4501  XLogLongPageHeader longpage;
4502  XLogRecord *record;
4503  char *recptr;
4504  uint64 sysidentifier;
4505  struct timeval tv;
4506  pg_crc32c crc;
4507 
4508  /* allow ordinary WAL segment creation, like StartupXLOG() would */
4509  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
4511  LWLockRelease(ControlFileLock);
4512 
4513  /*
4514  * Select a hopefully-unique system identifier code for this installation.
4515  * We use the result of gettimeofday(), including the fractional seconds
4516  * field, as being about as unique as we can easily get. (Think not to
4517  * use random(), since it hasn't been seeded and there's no portable way
4518  * to seed it other than the system clock value...) The upper half of the
4519  * uint64 value is just the tv_sec part, while the lower half contains the
4520  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
4521  * PID for a little extra uniqueness. A person knowing this encoding can
4522  * determine the initialization time of the installation, which could
4523  * perhaps be useful sometimes.
4524  */
4525  gettimeofday(&tv, NULL);
4526  sysidentifier = ((uint64) tv.tv_sec) << 32;
4527  sysidentifier |= ((uint64) tv.tv_usec) << 12;
4528  sysidentifier |= getpid() & 0xFFF;
4529 
4530  /* page buffer must be aligned suitably for O_DIRECT */
4531  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
4532  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
4533  memset(page, 0, XLOG_BLCKSZ);
4534 
4535  /*
4536  * Set up information for the initial checkpoint record
4537  *
4538  * The initial checkpoint record is written to the beginning of the WAL
4539  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
4540  * used, so that we can use 0/0 to mean "before any valid WAL segment".
4541  */
4542  checkPoint.redo = wal_segment_size + SizeOfXLogLongPHD;
4543  checkPoint.ThisTimeLineID = BootstrapTimeLineID;
4544  checkPoint.PrevTimeLineID = BootstrapTimeLineID;
4545  checkPoint.fullPageWrites = fullPageWrites;
4546  checkPoint.nextXid =
4548  checkPoint.nextOid = FirstGenbkiObjectId;
4549  checkPoint.nextMulti = FirstMultiXactId;
4550  checkPoint.nextMultiOffset = 0;
4551  checkPoint.oldestXid = FirstNormalTransactionId;
4552  checkPoint.oldestXidDB = Template1DbOid;
4553  checkPoint.oldestMulti = FirstMultiXactId;
4554  checkPoint.oldestMultiDB = Template1DbOid;
4557  checkPoint.time = (pg_time_t) time(NULL);
4559 
4560  ShmemVariableCache->nextXid = checkPoint.nextXid;
4561  ShmemVariableCache->nextOid = checkPoint.nextOid;
4563  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
4564  AdvanceOldestClogXid(checkPoint.oldestXid);
4565  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
4566  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
4568 
4569  /* Set up the XLOG page header */
4570  page->xlp_magic = XLOG_PAGE_MAGIC;
4571  page->xlp_info = XLP_LONG_HEADER;
4572  page->xlp_tli = BootstrapTimeLineID;
4574  longpage = (XLogLongPageHeader) page;
4575  longpage->xlp_sysid = sysidentifier;
4576  longpage->xlp_seg_size = wal_segment_size;
4577  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
4578 
4579  /* Insert the initial checkpoint record */
4580  recptr = ((char *) page + SizeOfXLogLongPHD);
4581  record = (XLogRecord *) recptr;
4582  record->xl_prev = 0;
4583  record->xl_xid = InvalidTransactionId;
4584  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
4586  record->xl_rmid = RM_XLOG_ID;
4587  recptr += SizeOfXLogRecord;
4588  /* fill the XLogRecordDataHeaderShort struct */
4589  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
4590  *(recptr++) = sizeof(checkPoint);
4591  memcpy(recptr, &checkPoint, sizeof(checkPoint));
4592  recptr += sizeof(checkPoint);
4593  Assert(recptr - (char *) record == record->xl_tot_len);
4594 
4595  INIT_CRC32C(crc);
4596  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
4597  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
4598  FIN_CRC32C(crc);
4599  record->xl_crc = crc;
4600 
4601  /* Create first XLOG segment file */
4604 
4605  /*
4606  * We needn't bother with Reserve/ReleaseExternalFD here, since we'll
4607  * close the file again in a moment.
4608  */
4609 
4610  /* Write the first page with the initial record */
4611  errno = 0;
4613  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
4614  {
4615  /* if write didn't set errno, assume problem is no disk space */
4616  if (errno == 0)
4617  errno = ENOSPC;
4618  ereport(PANIC,
4620  errmsg("could not write bootstrap write-ahead log file: %m")));
4621  }
4623 
4625  if (pg_fsync(openLogFile) != 0)
4626  ereport(PANIC,
4628  errmsg("could not fsync bootstrap write-ahead log file: %m")));
4630 
4631  if (close(openLogFile) != 0)
4632  ereport(PANIC,
4634  errmsg("could not close bootstrap write-ahead log file: %m")));
4635 
4636  openLogFile = -1;
4637 
4638  /* Now create pg_control */
4639  InitControlFile(sysidentifier);
4640  ControlFile->time = checkPoint.time;
4641  ControlFile->checkPoint = checkPoint.redo;
4642  ControlFile->checkPointCopy = checkPoint;
4643 
4644  /* some additional ControlFile fields are set in WriteControlFile() */
4645  WriteControlFile();
4646 
4647  /* Bootstrap the commit log, too */
4648  BootStrapCLOG();
4652 
4653  pfree(buffer);
4654 
4655  /*
4656  * Force control file to be read - in contrast to normal processing we'd
4657  * otherwise never run the checks and GUC related initializations therein.
4658  */
4659  ReadControlFile();
4660 }
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:761
#define offsetof(type, field)
Definition: c.h:738
void BootStrapCLOG(void)
Definition: clog.c:713
void BootStrapCommitTs(void)
Definition: commit_ts.c:574
void SetCommitTsLimit(TransactionId oldestXact, TransactionId newestXact)
Definition: commit_ts.c:881
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:104
#define close(a)
Definition: win32.h:12
#define write(a, b, c)
Definition: win32.h:14
void pfree(void *pointer)
Definition: mcxt.c:1175
void * palloc(Size size)
Definition: mcxt.c:1068
void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset)
Definition: multixact.c:2179
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
Definition: multixact.c:2213
void BootStrapMultiXact(void)
Definition: multixact.c:1894
#define FirstMultiXactId
Definition: multixact.h:25
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
uint32 pg_crc32c
Definition: pg_crc32c.h:38
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:89
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:94
return crc
int64 pg_time_t
Definition: pgtime.h:23
Oid oldestMultiDB
Definition: pg_control.h:50
MultiXactId oldestMulti
Definition: pg_control.h:49
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
TransactionId newestCommitTsXid
Definition: pg_control.h:54
TransactionId oldestXid
Definition: pg_control.h:47
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
Oid nextOid
Definition: pg_control.h:44
TransactionId oldestActiveXid
Definition: pg_control.h:63
bool fullPageWrites
Definition: pg_control.h:42
MultiXactId nextMulti
Definition: pg_control.h:45
FullTransactionId nextXid
Definition: pg_control.h:43
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
pg_time_t time
Definition: pg_control.h:51
XLogRecPtr redo
Definition: pg_control.h:37
Oid oldestXidDB
Definition: pg_control.h:48
CheckPoint checkPointCopy
Definition: pg_control.h:133
pg_time_t time
Definition: pg_control.h:130
XLogRecPtr checkPoint
Definition: pg_control.h:131
FullTransactionId nextXid
Definition: transam.h:220
uint32 oidCount
Definition: transam.h:215
bool InstallXLogFileSegmentActive
Definition: xlog.c:528
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:222
@ WAIT_EVENT_WAL_BOOTSTRAP_WRITE
Definition: wait_event.h:223
int XLogFileInit(XLogSegNo logsegno, TimeLineID logtli)
Definition: xlog.c:3106
bool fullPageWrites
Definition: xlog.c:123
static void InitControlFile(uint64 sysidentifier)
Definition: xlog.c:3871
static void WriteControlFile(void)
Definition: xlog.c:3906
#define BootstrapTimeLineID
Definition: xlog.c:112
static void ReadControlFile(void)
Definition: xlog.c:3997
#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(), XLogCtlData::InstallXLogFileSegmentActive, InvalidTransactionId, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MultiXactSetNextMXact(), CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, VariableCacheData::nextOid, CheckPoint::nextOid, VariableCacheData::nextXid, CheckPoint::nextXid, offsetof, 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(), 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, XLogCtl, 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 1942 of file xlog.c.

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

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

4283 {
4284  /*
4285  * -1 indicates a request for auto-tune.
4286  */
4287  if (*newval == -1)
4288  {
4289  /*
4290  * If we haven't yet changed the boot_val default of -1, just let it
4291  * be. We'll fix it when XLOGShmemSize is called.
4292  */
4293  if (XLOGbuffers == -1)
4294  return true;
4295 
4296  /* Otherwise, substitute the auto-tune value */
4298  }
4299 
4300  /*
4301  * We clamp manually-set values to at least 4 blocks. Prior to PostgreSQL
4302  * 9.1, a minimum of 4 was enforced by guc.c, but since that is no longer
4303  * the case, we just silently treat such values as a request for the
4304  * minimum. (We could throw an error instead, but that doesn't seem very
4305  * helpful.)
4306  */
4307  if (*newval < 4)
4308  *newval = 4;
4309 
4310  return true;
4311 }
static int XLOGChooseNumBuffers(void)
Definition: xlog.c:4266
int XLOGbuffers
Definition: xlog.c:118

References newval, XLOGbuffers, and XLOGChooseNumBuffers().

◆ CheckPointGuts()

static void CheckPointGuts ( XLogRecPtr  checkPointRedo,
int  flags 
)
static

Definition at line 6839 of file xlog.c.

6840 {
6846 
6847  /* Write out all dirty data in SLRUs and the main buffer pool */
6848  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_START(flags);
6850  CheckPointCLOG();
6855  CheckPointBuffers(flags);
6856 
6857  /* Perform all queued up fsyncs */
6858  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_SYNC_START();
6862  TRACE_POSTGRESQL_BUFFER_CHECKPOINT_DONE();
6863 
6864  /* We deliberately delay 2PC checkpointing as long as possible */
6865  CheckPointTwoPhase(checkPointRedo);
6866 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1574
void CheckPointBuffers(int flags)
Definition: bufmgr.c:2731
void CheckPointCLOG(void)
Definition: clog.c:819
void CheckPointCommitTs(void)
Definition: commit_ts.c:795
void CheckPointMultiXact(void)
Definition: multixact.c:2155
void CheckPointReplicationOrigin(void)
Definition: origin.c:557
void CheckPointPredicate(void)
Definition: predicate.c:1069
void CheckPointRelationMap(void)
Definition: relmapper.c:605
void CheckPointLogicalRewriteHeap(void)
Definition: rewriteheap.c:1192
void CheckPointReplicationSlots(void)
Definition: slot.c:1442
void CheckPointSnapBuild(void)
Definition: snapbuild.c:1921
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:1795
CheckpointStatsData CheckpointStats
Definition: xlog.c:206

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

4844 {
4845  /*
4846  * For archive recovery, the WAL must be generated with at least 'replica'
4847  * wal_level.
4848  */
4850  {
4851  ereport(FATAL,
4852  (errmsg("WAL was generated with wal_level=minimal, cannot continue recovering"),
4853  errdetail("This happens if you temporarily set wal_level=minimal on the server."),
4854  errhint("Use a backup taken after setting wal_level to higher than minimal.")));
4855  }
4856 
4857  /*
4858  * For Hot Standby, the WAL must be generated with 'replica' mode, and we
4859  * must have at least as many backend slots as the primary.
4860  */
4862  {
4863  /* We ignore autovacuum_max_workers when we make this test. */
4864  RecoveryRequiresIntParameter("max_connections",
4867  RecoveryRequiresIntParameter("max_worker_processes",
4870  RecoveryRequiresIntParameter("max_wal_senders",
4873  RecoveryRequiresIntParameter("max_prepared_transactions",
4876  RecoveryRequiresIntParameter("max_locks_per_transaction",
4879  }
4880 }
int errdetail(const char *fmt,...)
Definition: elog.c:1037
int errhint(const char *fmt,...)
Definition: elog.c:1151
#define FATAL
Definition: elog.h:35
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:122
@ WAL_LEVEL_MINIMAL
Definition: xlog.h:69
bool ArchiveRecoveryRequested
Definition: xlogrecovery.c:134
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 3454 of file xlog.c.

3455 {
3456  int save_errno = errno;
3457  XLogSegNo lastRemovedSegNo;
3458 
3460  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3462 
3463  if (segno <= lastRemovedSegNo)
3464  {
3465  char filename[MAXFNAMELEN];
3466 
3467  XLogFileName(filename, tli, segno, wal_segment_size);
3468  errno = save_errno;
3469  ereport(ERROR,
3471  errmsg("requested WAL segment %s has already been removed",
3472  filename)));
3473  }
3474  errno = save_errno;
3475 }
#define ERROR
Definition: elog.h:33
static char * filename
Definition: pg_dumpall.c:94
XLogSegNo lastRemovedSegNo
Definition: xlog.c:466
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 4754 of file xlog.c.

4756 {
4757  /*
4758  * Execute the recovery_end_command, if any.
4759  */
4760  if (recoveryEndCommand && strcmp(recoveryEndCommand, "") != 0)
4762  "recovery_end_command",
4763  true,
4765 
4766  /*
4767  * We switched to a new timeline. Clean up segments on the old timeline.
4768  *
4769  * If there are any higher-numbered segments on the old timeline, remove
4770  * them. They might contain valid WAL, but they might also be
4771  * pre-allocated files containing garbage. In any case, they are not part
4772  * of the new timeline's history so we don't need them.
4773  */
4774  RemoveNonParentXlogFiles(EndOfLog, newTLI);
4775 
4776  /*
4777  * If the switch happened in the middle of a segment, what to do with the
4778  * last, partial segment on the old timeline? If we don't archive it, and
4779  * the server that created the WAL never archives it either (e.g. because
4780  * it was hit by a meteor), it will never make it to the archive. That's
4781  * OK from our point of view, because the new segment that we created with
4782  * the new TLI contains all the WAL from the old timeline up to the switch
4783  * point. But if you later try to do PITR to the "missing" WAL on the old
4784  * timeline, recovery won't find it in the archive. It's physically
4785  * present in the new file with new TLI, but recovery won't look there
4786  * when it's recovering to the older timeline. On the other hand, if we
4787  * archive the partial segment, and the original server on that timeline
4788  * is still running and archives the completed version of the same segment
4789  * later, it will fail. (We used to do that in 9.4 and below, and it
4790  * caused such problems).
4791  *
4792  * As a compromise, we rename the last segment with the .partial suffix,
4793  * and archive it. Archive recovery will never try to read .partial
4794  * segments, so they will normally go unused. But in the odd PITR case,
4795  * the administrator can copy them manually to the pg_wal directory
4796  * (removing the suffix). They can be useful in debugging, too.
4797  *
4798  * If a .done or .ready file already exists for the old timeline, however,
4799  * we had already determined that the segment is complete, so we can let
4800  * it be archived normally. (In particular, if it was restored from the
4801  * archive to begin with, it's expected to have a .done file).
4802  */
4803  if (XLogSegmentOffset(EndOfLog, wal_segment_size) != 0 &&
4805  {
4806  char origfname[MAXFNAMELEN];
4807  XLogSegNo endLogSegNo;
4808 
4809  XLByteToPrevSeg(EndOfLog, endLogSegNo, wal_segment_size);
4810  XLogFileName(origfname, EndOfLogTLI, endLogSegNo, wal_segment_size);
4811 
4812  if (!XLogArchiveIsReadyOrDone(origfname))
4813  {
4814  char origpath[MAXPGPATH];
4815  char partialfname[MAXFNAMELEN];
4816  char partialpath[MAXPGPATH];
4817 
4818  XLogFilePath(origpath, EndOfLogTLI, endLogSegNo, wal_segment_size);
4819  snprintf(partialfname, MAXFNAMELEN, "%s.partial", origfname);
4820  snprintf(partialpath, MAXPGPATH, "%s.partial", origpath);
4821 
4822  /*
4823  * Make sure there's no .done or .ready file for the .partial
4824  * file.
4825  */
4826  XLogArchiveCleanup(partialfname);
4827 
4828  durable_rename(origpath, partialpath, ERROR);
4829  XLogArchiveNotify(partialfname);
4830  }
4831  }
4832 }
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:699
#define MAXPGPATH
#define snprintf
Definition: port.h:225
@ WAIT_EVENT_RECOVERY_END_COMMAND
Definition: wait_event.h:122
void RemoveNonParentXlogFiles(XLogRecPtr switchpoint, TimeLineID newTLI)
Definition: xlog.c:3630
#define XLogArchivingActive()
Definition: xlog.h:94
#define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes)
#define XLogFilePath(path, tli, logSegNo, wal_segsz_bytes)
bool XLogArchiveIsReadyOrDone(const char *xlog)
Definition: xlogarchive.c:694
void ExecuteRecoveryCommand(const char *command, const char *commandName, bool failOnSignal, uint32 wait_event_info)
Definition: xlogarchive.c:290
void XLogArchiveNotify(const char *xlog)
Definition: xlogarchive.c:474
void XLogArchiveCleanup(const char *xlog)
Definition: xlogarchive.c:742
char * recoveryEndCommand
Definition: xlogrecovery.c:79

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

3829 {
3830  DIR *xldir;
3831  struct dirent *xlde;
3832  char path[MAXPGPATH + sizeof(XLOGDIR)];
3833 
3834  xldir = AllocateDir(XLOGDIR);
3835 
3836  while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
3837  {
3838  if (IsBackupHistoryFileName(xlde->d_name))
3839  {
3840  if (XLogArchiveCheckDone(xlde->d_name))
3841  {
3842  elog(DEBUG2, "removing WAL backup history file \"%s\"",
3843  xlde->d_name);
3844  snprintf(path, sizeof(path), XLOGDIR "/%s", xlde->d_name);
3845  unlink(path);
3846  XLogArchiveCleanup(xlde->d_name);
3847  }
3848  }
3849  }
3850 
3851  FreeDir(xldir);
3852 }
#define DEBUG2
Definition: elog.h:23
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2788
int FreeDir(DIR *dir)
Definition: fd.c:2840
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2722
Definition: dirent.c:26
Definition: dirent.h:10
char d_name[MAX_PATH]
Definition: dirent.h:15
#define XLOGDIR
#define IsBackupHistoryFileName(fname)
bool XLogArchiveCheckDone(const char *xlog)
Definition: xlogarchive.c:595

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

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

6280 {
6281  bool shutdown;
6282  CheckPoint checkPoint;
6283  XLogRecPtr recptr;
6284  XLogSegNo _logSegNo;
6286  uint32 freespace;
6287  XLogRecPtr PriorRedoPtr;
6288  XLogRecPtr curInsert;
6289  XLogRecPtr last_important_lsn;
6290  VirtualTransactionId *vxids;
6291  int nvxids;
6292  int oldXLogAllowed = 0;
6293 
6294  /*
6295  * An end-of-recovery checkpoint is really a shutdown checkpoint, just
6296  * issued at a different time.
6297  */
6299  shutdown = true;
6300  else
6301  shutdown = false;
6302 
6303  /* sanity check */
6304  if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
6305  elog(ERROR, "can't create a checkpoint during recovery");
6306 
6307  /*
6308  * Prepare to accumulate statistics.
6309  *
6310  * Note: because it is possible for log_checkpoints to change while a
6311  * checkpoint proceeds, we always accumulate stats, even if
6312  * log_checkpoints is currently off.
6313  */
6314  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
6316 
6317  /*
6318  * Let smgr prepare for checkpoint; this has to happen outside the
6319  * critical section and before we determine the REDO pointer. Note that
6320  * smgr must not do anything that'd have to be undone if we decide no
6321  * checkpoint is needed.
6322  */
6324 
6325  /*
6326  * Use a critical section to force system panic if we have trouble.
6327  */
6329 
6330  if (shutdown)
6331  {
6332  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6335  LWLockRelease(ControlFileLock);
6336  }
6337 
6338  /* Begin filling in the checkpoint WAL record */
6339  MemSet(&checkPoint, 0, sizeof(checkPoint));
6340  checkPoint.time = (pg_time_t) time(NULL);
6341 
6342  /*
6343  * For Hot Standby, derive the oldestActiveXid before we fix the redo
6344  * pointer. This allows us to begin accumulating changes to assemble our
6345  * starting snapshot of locks and transactions.
6346  */
6347  if (!shutdown && XLogStandbyInfoActive())
6349  else
6351 
6352  /*
6353  * Get location of last important record before acquiring insert locks (as
6354  * GetLastImportantRecPtr() also locks WAL locks).
6355  */
6356  last_important_lsn = GetLastImportantRecPtr();
6357 
6358  /*
6359  * We must block concurrent insertions while examining insert state to
6360  * determine the checkpoint REDO pointer.
6361  */
6363  curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
6364 
6365  /*
6366  * If this isn't a shutdown or forced checkpoint, and if there has been no
6367  * WAL activity requiring a checkpoint, skip it. The idea here is to
6368  * avoid inserting duplicate checkpoints when the system is idle.
6369  */
6371  CHECKPOINT_FORCE)) == 0)
6372  {
6373  if (last_important_lsn == ControlFile->checkPoint)
6374  {
6376  END_CRIT_SECTION();
6377  ereport(DEBUG1,
6378  (errmsg_internal("checkpoint skipped because system is idle")));
6379  return;
6380  }
6381  }
6382 
6383  /*
6384  * An end-of-recovery checkpoint is created before anyone is allowed to
6385  * write WAL. To allow us to write the checkpoint record, temporarily
6386  * enable XLogInsertAllowed.
6387  */
6388  if (flags & CHECKPOINT_END_OF_RECOVERY)
6389  oldXLogAllowed = LocalSetXLogInsertAllowed();
6390 
6391  checkPoint.ThisTimeLineID = XLogCtl->InsertTimeLineID;
6392  if (flags & CHECKPOINT_END_OF_RECOVERY)
6393  checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
6394  else
6395  checkPoint.PrevTimeLineID = checkPoint.ThisTimeLineID;
6396 
6397  checkPoint.fullPageWrites = Insert->fullPageWrites;
6398 
6399  /*
6400  * Compute new REDO record ptr = location of next XLOG record.
6401  *
6402  * NB: this is NOT necessarily where the checkpoint record itself will be,
6403  * since other backends may insert more XLOG records while we're off doing
6404  * the buffer flush work. Those XLOG records are logically after the
6405  * checkpoint, even though physically before it. Got that?
6406  */
6407  freespace = INSERT_FREESPACE(curInsert);
6408  if (freespace == 0)
6409  {
6410  if (XLogSegmentOffset(curInsert, wal_segment_size) == 0)
6411  curInsert += SizeOfXLogLongPHD;
6412  else
6413  curInsert += SizeOfXLogShortPHD;
6414  }
6415  checkPoint.redo = curInsert;
6416 
6417  /*
6418  * Here we update the shared RedoRecPtr for future XLogInsert calls; this
6419  * must be done while holding all the insertion locks.
6420  *
6421  * Note: if we fail to complete the checkpoint, RedoRecPtr will be left
6422  * pointing past where it really needs to point. This is okay; the only
6423  * consequence is that XLogInsert might back up whole buffers that it
6424  * didn't really need to. We can't postpone advancing RedoRecPtr because
6425  * XLogInserts that happen while we are dumping buffers must assume that
6426  * their buffer changes are not included in the checkpoint.
6427  */
6428  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
6429 
6430  /*
6431  * Now we can release the WAL insertion locks, allowing other xacts to
6432  * proceed while we are flushing disk buffers.
6433  */
6435 
6436  /* Update the info_lck-protected copy of RedoRecPtr as well */
6438  XLogCtl->RedoRecPtr = checkPoint.redo;
6440 
6441  /*
6442  * If enabled, log checkpoint start. We postpone this until now so as not
6443  * to log anything if we decided to skip the checkpoint.
6444  */
6445  if (log_checkpoints)
6446  LogCheckpointStart(flags, false);
6447 
6448  /* Update the process title */
6449  update_checkpoint_display(flags, false, false);
6450 
6451  TRACE_POSTGRESQL_CHECKPOINT_START(flags);
6452 
6453  /*
6454  * Get the other info we need for the checkpoint record.
6455  *
6456  * We don't need to save oldestClogXid in the checkpoint, it only matters
6457  * for the short period in which clog is being truncated, and if we crash
6458  * during that we'll redo the clog truncation and fix up oldestClogXid
6459  * there.
6460  */
6461  LWLockAcquire(XidGenLock, LW_SHARED);
6462  checkPoint.nextXid = ShmemVariableCache->nextXid;
6463  checkPoint.oldestXid = ShmemVariableCache->oldestXid;
6465  LWLockRelease(XidGenLock);
6466 
6467  LWLockAcquire(CommitTsLock, LW_SHARED);
6470  LWLockRelease(CommitTsLock);
6471 
6472  LWLockAcquire(OidGenLock, LW_SHARED);
6473  checkPoint.nextOid = ShmemVariableCache->nextOid;
6474  if (!shutdown)
6475  checkPoint.nextOid += ShmemVariableCache->oidCount;
6476  LWLockRelease(OidGenLock);
6477 
6478  MultiXactGetCheckptMulti(shutdown,
6479  &checkPoint.nextMulti,
6480  &checkPoint.nextMultiOffset,
6481  &checkPoint.oldestMulti,
6482  &checkPoint.oldestMultiDB);
6483 
6484  /*
6485  * Having constructed the checkpoint record, ensure all shmem disk buffers
6486  * and commit-log buffers are flushed to disk.
6487  *
6488  * This I/O could fail for various reasons. If so, we will fail to
6489  * complete the checkpoint, but there is no reason to force a system
6490  * panic. Accordingly, exit critical section while doing it.
6491  */
6492  END_CRIT_SECTION();
6493 
6494  /*
6495  * In some cases there are groups of actions that must all occur on one
6496  * side or the other of a checkpoint record. Before flushing the
6497  * checkpoint record we must explicitly wait for any backend currently
6498  * performing those groups of actions.
6499  *
6500  * One example is end of transaction, so we must wait for any transactions
6501  * that are currently in commit critical sections. If an xact inserted
6502  * its commit record into XLOG just before the REDO point, then a crash
6503  * restart from the REDO point would not replay that record, which means
6504  * that our flushing had better include the xact's update of pg_xact. So
6505  * we wait till he's out of his commit critical section before proceeding.
6506  * See notes in RecordTransactionCommit().
6507  *
6508  * Because we've already released the insertion locks, this test is a bit
6509  * fuzzy: it is possible that we will wait for xacts we didn't really need
6510  * to wait for. But the delay should be short and it seems better to make
6511  * checkpoint take a bit longer than to hold off insertions longer than
6512  * necessary. (In fact, the whole reason we have this issue is that xact.c
6513  * does commit record XLOG insertion and clog update as two separate steps
6514  * protected by different locks, but again that seems best on grounds of
6515  * minimizing lock contention.)
6516  *
6517  * A transaction that has not yet set delayChkptFlags when we look cannot
6518  * be at risk, since it has not inserted its commit record yet; and one
6519  * that's already cleared it is not at risk either, since it's done fixing
6520  * clog and we will correctly flush the update below. So we cannot miss
6521  * any xacts we need to wait for.
6522  */
6524  if (nvxids > 0)
6525  {
6526  do
6527  {
6528  pg_usleep(10000L); /* wait for 10 msec */
6529  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids,
6531  }
6532  pfree(vxids);
6533 
6534  CheckPointGuts(checkPoint.redo, flags);
6535 
6537  if (nvxids > 0)
6538  {
6539  do
6540  {
6541  pg_usleep(10000L); /* wait for 10 msec */
6542  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids,
6544  }
6545  pfree(vxids);
6546 
6547  /*
6548  * Take a snapshot of running transactions and write this to WAL. This
6549  * allows us to reconstruct the state of running transactions during
6550  * archive recovery, if required. Skip, if this info disabled.
6551  *
6552  * If we are shutting down, or Startup process is completing crash
6553  * recovery we don't need to write running xact data.
6554  */
6555  if (!shutdown && XLogStandbyInfoActive())
6557 
6559 
6560  /*
6561  * Now insert the checkpoint record into XLOG.
6562  */
6563  XLogBeginInsert();
6564  XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));
6565  recptr = XLogInsert(RM_XLOG_ID,
6566  shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
6568 
6569  XLogFlush(recptr);
6570 
6571  /*
6572  * We mustn't write any new WAL after a shutdown checkpoint, or it will be
6573  * overwritten at next startup. No-one should even try, this just allows
6574  * sanity-checking. In the case of an end-of-recovery checkpoint, we want
6575  * to just temporarily disable writing until the system has exited
6576  * recovery.
6577  */
6578  if (shutdown)
6579  {
6580  if (flags & CHECKPOINT_END_OF_RECOVERY)
6581  LocalXLogInsertAllowed = oldXLogAllowed;
6582  else
6583  LocalXLogInsertAllowed = 0; /* never again write WAL */
6584  }
6585 
6586  /*
6587  * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
6588  * = end of actual checkpoint record.
6589  */
6590  if (shutdown && checkPoint.redo != ProcLastRecPtr)
6591  ereport(PANIC,
6592  (errmsg("concurrent write-ahead log activity while database system is shutting down")));
6593 
6594  /*
6595  * Remember the prior checkpoint's redo ptr for
6596  * UpdateCheckPointDistanceEstimate()
6597  */
6598  PriorRedoPtr = ControlFile->checkPointCopy.redo;
6599 
6600  /*
6601  * Update the control file.
6602  */
6603  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6604  if (shutdown)
6607  ControlFile->checkPointCopy = checkPoint;
6608  /* crash recovery should always recover to the end of WAL */
6611 
6612  /*
6613  * Persist unloggedLSN value. It's reset on crash recovery, so this goes
6614  * unused on non-shutdown checkpoints, but seems useful to store it always
6615  * for debugging purposes.
6616  */
6620 
6622  LWLockRelease(ControlFileLock);
6623 
6624  /* Update shared-memory copy of checkpoint XID/epoch */
6626  XLogCtl->ckptFullXid = checkPoint.nextXid;
6628 
6629  /*
6630  * We are now done with critical updates; no need for system panic if we
6631  * have trouble while fooling with old log segments.
6632  */
6633  END_CRIT_SECTION();
6634 
6635  /*
6636  * Let smgr do post-checkpoint cleanup (eg, deleting old files).
6637  */
6639 
6640  /*
6641  * Update the average distance between checkpoints if the prior checkpoint
6642  * exists.
6643  */
6644  if (PriorRedoPtr != InvalidXLogRecPtr)
6646 
6647  /*
6648  * Delete old log files, those no longer needed for last checkpoint to
6649  * prevent the disk holding the xlog from growing full.
6650  */
6652  KeepLogSeg(recptr, &_logSegNo);
6653  if (InvalidateObsoleteReplicationSlots(_logSegNo))
6654  {
6655  /*
6656  * Some slots have been invalidated; recalculate the old-segment
6657  * horizon, starting again from RedoRecPtr.
6658  */
6660  KeepLogSeg(recptr, &_logSegNo);
6661  }
6662  _logSegNo--;
6663  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr,
6664  checkPoint.ThisTimeLineID);
6665 
6666  /*
6667  * Make more log segments if needed. (Do this after recycling old log
6668  * segments, since that may supply some of the needed files.)
6669  */
6670  if (!shutdown)
6671  PreallocXlogFiles(recptr, checkPoint.ThisTimeLineID);
6672 
6673  /*
6674  * Truncate pg_subtrans if possible. We can throw away all data before
6675  * the oldest XMIN of any running transaction. No future transaction will
6676  * attempt to reference any pg_subtrans entry older than that (see Asserts
6677  * in subtrans.c). During recovery, though, we mustn't do this because
6678  * StartupSUBTRANS hasn't been called yet.
6679  */
6680  if (!RecoveryInProgress())
6682 
6683  /* Real work is done; log and update stats. */
6684  LogCheckpointEnd(false);
6685 
6686  /* Reset the process title */
6687  update_checkpoint_display(flags, false, true);
6688 
6689  TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
6690  NBuffers,
6694 }
int errmsg_internal(const char *fmt,...)
Definition: elog.c:991
int NBuffers
Definition: globals.c:136
@ LW_SHARED
Definition: lwlock.h:105
#define START_CRIT_SECTION()
Definition: miscadmin.h:148
#define END_CRIT_SECTION()
Definition: miscadmin.h:150
void MultiXactGetCheckptMulti(bool is_shutdown, MultiXactId *nextMulti, MultiXactOffset *nextMultiOffset, MultiXactId *oldestMulti, Oid *oldestMultiDB)
Definition: multixact.c:2133
@ DB_SHUTDOWNING
Definition: pg_control.h:92
@ DB_SHUTDOWNED
Definition: pg_control.h:90
#define XLOG_CHECKPOINT_ONLINE
Definition: pg_control.h:68
#define DELAY_CHKPT_START
Definition: proc.h:117
#define DELAY_CHKPT_COMPLETE
Definition: proc.h:118
VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
Definition: procarray.c:3060
TransactionId GetOldestActiveTransactionId(void)
Definition: procarray.c:2897
TransactionId GetOldestTransactionIdConsideredRunning(void)
Definition: procarray.c:2035
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)
Definition: procarray.c:3106
void pg_usleep(long microsec)
Definition: signal.c:53
bool InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno)
Definition: slot.c:1393
XLogRecPtr LogStandbySnapshot(void)
Definition: standby.c:1222
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:462
TimeLineID InsertTimeLineID
Definition: xlog.c:511
slock_t ulsn_lck
Definition: xlog.c:470
XLogRecPtr RedoRecPtr
Definition: xlog.c:461
XLogRecPtr unloggedLSN
Definition: xlog.c:469
TimeLineID PrevTimeLineID
Definition: xlog.c:512
XLogRecPtr RedoRecPtr
Definition: xlog.c:433
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:250
bool RecoveryInProgress(void)
Definition: xlog.c:5762
static void WALInsertLockRelease(void)
Definition: xlog.c:1376
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1645
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1347
static void UpdateControlFile(void)
Definition: xlog.c:4197
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr, TimeLineID insertTLI)
Definition: xlog.c:3555
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:6060
static XLogRecPtr RedoRecPtr
Definition: xlog.c:270
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:6092
static void PreallocXlogFiles(XLogRecPtr endptr, TimeLineID tli)
Definition: xlog.c:3417
bool log_checkpoints
Definition: xlog.c:130
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:7273
static int LocalSetXLogInsertAllowed(void)
Definition: xlog.c:5850
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:5967
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:6184
static int LocalXLogInsertAllowed
Definition: xlog.c:233
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2509
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:6839
static void update_checkpoint_display(int flags, bool restartpoint, bool reset)
Definition: xlog.c:6222
#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)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:443
void XLogBeginInsert(void)
Definition: xloginsert.c:150
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:351

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

6706 {
6707  xl_end_of_recovery xlrec;
6708  XLogRecPtr recptr;
6709 
6710  /* sanity check */
6711  if (!RecoveryInProgress())
6712  elog(ERROR, "can only be used to end recovery");
6713 
6714  xlrec.end_time = GetCurrentTimestamp();
6715 
6720 
6722 
6723  XLogBeginInsert();
6724  XLogRegisterData((char *) &xlrec, sizeof(xl_end_of_recovery));
6725  recptr = XLogInsert(RM_XLOG_ID, XLOG_END_OF_RECOVERY);
6726 
6727  XLogFlush(recptr);
6728 
6729  /*
6730  * Update the control file so that crash recovery can follow the timeline
6731  * changes to this point.
6732  */
6733  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6734  ControlFile->minRecoveryPoint = recptr;
6735  ControlFile->minRecoveryPointTLI = xlrec.ThisTimeLineID;
6737  LWLockRelease(ControlFileLock);
6738 
6739  END_CRIT_SECTION();
6740 }
#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  missingContrecPtr,
TimeLineID  newTLI 
)
static

Definition at line 6769 of file xlog.c.

6771 {
6773  XLogRecPtr recptr;
6774  XLogPageHeader pagehdr;
6775  XLogRecPtr startPos;
6776 
6777  /* sanity checks */
6778  if (!RecoveryInProgress())
6779  elog(ERROR, "can only be used at end of recovery");
6780  if (pagePtr % XLOG_BLCKSZ != 0)
6781  elog(ERROR, "invalid position for missing continuation record %X/%X",
6782  LSN_FORMAT_ARGS(pagePtr));
6783 
6784  /* The current WAL insert position should be right after the page header */
6785  startPos = pagePtr;
6786  if (XLogSegmentOffset(startPos, wal_segment_size) == 0)
6787  startPos += SizeOfXLogLongPHD;
6788  else
6789  startPos += SizeOfXLogShortPHD;
6790  recptr = GetXLogInsertRecPtr();
6791  if (recptr != startPos)
6792  elog(ERROR, "invalid WAL insert position %X/%X for OVERWRITE_CONTRECORD",
6793  LSN_FORMAT_ARGS(recptr));
6794 
6796 
6797  /*
6798  * Initialize the XLOG page header (by GetXLogBuffer), and set the
6799  * XLP_FIRST_IS_OVERWRITE_CONTRECORD flag.
6800  *
6801  * No other backend is allowed to write WAL yet, so acquiring the WAL
6802  * insertion lock is just pro forma.
6803  */
6805  pagehdr = (XLogPageHeader) GetXLogBuffer(pagePtr, newTLI);
6808 
6809  /*
6810  * Insert the XLOG_OVERWRITE_CONTRECORD record as the first record on the
6811  * page. We know it becomes the first record, because no other backend is
6812  * allowed to write WAL yet.
6813  */
6814  XLogBeginInsert();
6815  xlrec.overwritten_lsn = aborted_lsn;
6817  XLogRegisterData((char *) &xlrec, sizeof(xl_overwrite_contrecord));
6818  recptr = XLogInsert(RM_XLOG_ID, XLOG_OVERWRITE_CONTRECORD);
6819 
6820  /* check that the record was inserted to the right place */
6821  if (ProcLastRecPtr != startPos)
6822  elog(ERROR, "OVERWRITE_CONTRECORD was inserted to unexpected position %X/%X",
6824 
6825  XLogFlush(recptr);
6826 
6827  END_CRIT_SECTION();
6828 
6829  return recptr;
6830 }
#define XLOG_OVERWRITE_CONTRECORD
Definition: pg_control.h:80
static void WALInsertLockAcquire(void)
Definition: xlog.c:1302
XLogRecPtr GetXLogInsertRecPtr(void)
Definition: xlog.c:8812
#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 6920 of file xlog.c.

6921 {
6922  XLogRecPtr lastCheckPointRecPtr;
6923  XLogRecPtr lastCheckPointEndPtr;
6924  CheckPoint lastCheckPoint;
6925  XLogRecPtr PriorRedoPtr;
6926  XLogRecPtr receivePtr;
6927  XLogRecPtr replayPtr;
6928  TimeLineID replayTLI;
6929  XLogRecPtr endptr;
6930  XLogSegNo _logSegNo;
6931  TimestampTz xtime;
6932 
6933  /* Concurrent checkpoint/restartpoint cannot happen */
6935 
6936  /* Get a local copy of the last safe checkpoint record. */
6938  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
6939  lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
6940  lastCheckPoint = XLogCtl->lastCheckPoint;
6942 
6943  /*
6944  * Check that we're still in recovery mode. It's ok if we exit recovery
6945  * mode after this check, the restart point is valid anyway.
6946  */
6947  if (!RecoveryInProgress())
6948  {
6949  ereport(DEBUG2,
6950  (errmsg_internal("skipping restartpoint, recovery has already ended")));
6951  return false;
6952  }
6953 
6954  /*
6955  * If the last checkpoint record we've replayed is already our last
6956  * restartpoint, we can't perform a new restart point. We still update
6957  * minRecoveryPoint in that case, so that if this is a shutdown restart
6958  * point, we won't start up earlier than before. That's not strictly
6959  * necessary, but when hot standby is enabled, it would be rather weird if
6960  * the database opened up for read-only connections at a point-in-time
6961  * before the last shutdown. Such time travel is still possible in case of
6962  * immediate shutdown, though.
6963  *
6964  * We don't explicitly advance minRecoveryPoint when we do create a
6965  * restartpoint. It's assumed that flushing the buffers will do that as a
6966  * side-effect.
6967  */
6968  if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
6969  lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
6970  {
6971  ereport(DEBUG2,
6972  (errmsg_internal("skipping restartpoint, already performed at %X/%X",
6973  LSN_FORMAT_ARGS(lastCheckPoint.redo))));
6974 
6976  if (flags & CHECKPOINT_IS_SHUTDOWN)
6977  {
6978  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
6981  LWLockRelease(ControlFileLock);
6982  }
6983  return false;
6984  }
6985 
6986  /*
6987  * Update the shared RedoRecPtr so that the startup process can calculate
6988  * the number of segments replayed since last restartpoint, and request a
6989  * restartpoint if it exceeds CheckPointSegments.
6990  *
6991  * Like in CreateCheckPoint(), hold off insertions to update it, although
6992  * during recovery this is just pro forma, because no WAL insertions are
6993  * happening.
6994  */
6996  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
6998 
6999  /* Also update the info_lck-protected copy */
7001  XLogCtl->RedoRecPtr = lastCheckPoint.redo;
7003 
7004  /*
7005  * Prepare to accumulate statistics.
7006  *
7007  * Note: because it is possible for log_checkpoints to change while a
7008  * checkpoint proceeds, we always accumulate stats, even if
7009  * log_checkpoints is currently off.
7010  */
7011  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
7013 
7014  if (log_checkpoints)
7015  LogCheckpointStart(flags, true);
7016 
7017  /* Update the process title */
7018  update_checkpoint_display(flags, true, false);
7019 
7020  CheckPointGuts(lastCheckPoint.redo, flags);
7021 
7022  /*
7023  * Remember the prior checkpoint's redo ptr for
7024  * UpdateCheckPointDistanceEstimate()
7025  */
7026  PriorRedoPtr = ControlFile->checkPointCopy.redo;
7027 
7028  /*
7029  * Update pg_control, using current time. Check that it still shows an
7030  * older checkpoint, else do nothing; this is a quick hack to make sure
7031  * nothing really bad happens if somehow we get here after the
7032  * end-of-recovery checkpoint.
7033  */
7034  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7035  if (ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
7036  {
7037  /*
7038  * Update the checkpoint information. We do this even if the cluster
7039  * does not show DB_IN_ARCHIVE_RECOVERY to match with the set of WAL
7040  * segments recycled below.
7041  */
7042  ControlFile->checkPoint = lastCheckPointRecPtr;
7043  ControlFile->checkPointCopy = lastCheckPoint;
7044 
7045  /*
7046  * Ensure minRecoveryPoint is past the checkpoint record and update it
7047  * if the control file still shows DB_IN_ARCHIVE_RECOVERY. Normally,
7048  * this will have happened already while writing out dirty buffers,
7049  * but not necessarily - e.g. because no buffers were dirtied. We do
7050  * this because a backup performed in recovery uses minRecoveryPoint
7051  * to determine which WAL files must be included in the backup, and
7052  * the file (or files) containing the checkpoint record must be
7053  * included, at a minimum. Note that for an ordinary restart of
7054  * recovery there's no value in having the minimum recovery point any
7055  * earlier than this anyway, because redo will begin just after the
7056  * checkpoint record.
7057  */
7059  {
7060  if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
7061  {
7062  ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
7064 
7065  /* update local copy */
7068  }
7069  if (flags & CHECKPOINT_IS_SHUTDOWN)
7071  }
7073  }
7074  LWLockRelease(ControlFileLock);
7075 
7076  /*
7077  * Update the average distance between checkpoints/restartpoints if the
7078  * prior checkpoint exists.
7079  */
7080  if (PriorRedoPtr != InvalidXLogRecPtr)
7082 
7083  /*
7084  * Delete old log files, those no longer needed for last restartpoint to
7085  * prevent the disk holding the xlog from growing full.
7086  */
7088 
7089  /*
7090  * Retreat _logSegNo using the current end of xlog replayed or received,
7091  * whichever is later.
7092  */
7093  receivePtr = GetWalRcvFlushRecPtr(NULL, NULL);
7094  replayPtr = GetXLogReplayRecPtr(&replayTLI);
7095  endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
7096  KeepLogSeg(endptr, &_logSegNo);
7097  if (InvalidateObsoleteReplicationSlots(_logSegNo))
7098  {
7099  /*
7100  * Some slots have been invalidated; recalculate the old-segment
7101  * horizon, starting again from RedoRecPtr.
7102  */
7104  KeepLogSeg(endptr, &_logSegNo);
7105  }
7106  _logSegNo--;
7107 
7108  /*
7109  * Try to recycle segments on a useful timeline. If we've been promoted
7110  * since the beginning of this restartpoint, use the new timeline chosen
7111  * at end of recovery. If we're still in recovery, use the timeline we're
7112  * currently replaying.
7113  *
7114  * There is no guarantee that the WAL segments will be useful on the
7115  * current timeline; if recovery proceeds to a new timeline right after
7116  * this, the pre-allocated WAL segments on this timeline will not be used,
7117  * and will go wasted until recycled on the next restartpoint. We'll live
7118  * with that.
7119  */
7120  if (!RecoveryInProgress())
7121  replayTLI = XLogCtl->InsertTimeLineID;
7122 
7123  RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr, replayTLI);
7124 
7125  /*
7126  * Make more log segments if needed. (Do this after recycling old log
7127  * segments, since that may supply some of the needed files.)
7128  */
7129  PreallocXlogFiles(endptr, replayTLI);
7130 
7131  /*
7132  * Truncate pg_subtrans if possible. We can throw away all data before
7133  * the oldest XMIN of any running transaction. No future transaction will
7134  * attempt to reference any pg_subtrans entry older than that (see Asserts
7135  * in subtrans.c). When hot standby is disabled, though, we mustn't do
7136  * this because StartupSUBTRANS hasn't been called yet.
7137  */
7138  if (EnableHotStandby)
7140 
7141  /* Real work is done; log and update stats. */
7142  LogCheckpointEnd(true);
7143 
7144  /* Reset the process title */
7145  update_checkpoint_display(flags, true, true);
7146 
7147  xtime = GetLatestXTime();
7149  (errmsg("recovery restart point at %X/%X",
7150  LSN_FORMAT_ARGS(lastCheckPoint.redo)),
7151  xtime ? errdetail("Last completed transaction was at log time %s.",
7152  timestamptz_to_str(xtime)) : 0));
7153 
7154  /*
7155  * Finally, execute archive_cleanup_command, if any.
7156  */
7157  if (archiveCleanupCommand && strcmp(archiveCleanupCommand, "") != 0)
7159  "archive_cleanup_command",
7160  false,
7162 
7163  return true;
7164 }
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1768
int64 TimestampTz
Definition: timestamp.h:39
#define LOG
Definition: elog.h:25
bool IsUnderPostmaster
Definition: globals.c:113
@ B_CHECKPOINTER
Definition: miscadmin.h:332
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:547
XLogRecPtr lastCheckPointRecPtr
Definition: xlog.c:545
XLogRecPtr lastCheckPointEndPtr
Definition: xlog.c:546
@ 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:2429
static XLogRecPtr LocalMinRecoveryPoint
Definition: xlog.c:625
static TimeLineID LocalMinRecoveryPointTLI
Definition: xlog.c:626
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
uint32 TimeLineID
Definition: xlogdefs.h:59
char * archiveCleanupCommand
Definition: xlogrecovery.c:80
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 8768 of file xlog.c.

8769 {
8770  bool emit_warning = DatumGetBool(arg);
8771 
8772  /*
8773  * Quick exit if session does not have a running backup.
8774  */
8776  return;
8777 
8781 
8782  if (XLogCtl->Insert.runningBackups == 0)
8783  {
8784  XLogCtl->Insert.forcePageWrites = false;
8785  }
8787 
8788  if (emit_warning)
8789  ereport(WARNING,
8790  (errmsg("aborting backup due to backend exiting before pg_backup_stop was called")));
8791 }
#define WARNING
Definition: elog.h:30
void * arg
#define DatumGetBool(X)
Definition: postgres.h:437
bool forcePageWrites
Definition: xlog.c:434
int runningBackups
Definition: xlog.c:443
static SessionBackupState sessionBackupState
Definition: xlog.c:394
@ SESSION_BACKUP_RUNNING
Definition: xlog.h:277

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

Referenced by perform_base_backup(), and register_persistent_abort_backup_handler().

◆ do_pg_backup_start()

XLogRecPtr do_pg_backup_start ( const char *  backupidstr,
bool  fast,
TimeLineID starttli_p,
StringInfo  labelfile,
List **  tablespaces,
StringInfo  tblspcmapfile 
)

Definition at line 8086 of file xlog.c.

8089 {
8090  bool backup_started_in_recovery = false;
8091  XLogRecPtr checkpointloc;
8092  XLogRecPtr startpoint;
8093  TimeLineID starttli;
8094  pg_time_t stamp_time;
8095  char strfbuf[128];
8096  char xlogfilename[MAXFNAMELEN];
8097  XLogSegNo _logSegNo;
8098 
8100 
8101  /*
8102  * During recovery, we don't need to check WAL level. Because, if WAL
8103  * level is not sufficient, it's impossible to get here during recovery.
8104  */
8106  ereport(ERROR,
8107  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8108  errmsg("WAL level not sufficient for making an online backup"),
8109  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
8110 
8111  if (strlen(backupidstr) > MAXPGPATH)
8112  ereport(ERROR,
8113  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8114  errmsg("backup label too long (max %d bytes)",
8115  MAXPGPATH)));
8116 
8117  /*
8118  * Mark backup active in shared memory. We must do full-page WAL writes
8119  * during an on-line backup even if not doing so at other times, because
8120  * it's quite possible for the backup dump to obtain a "torn" (partially
8121  * written) copy of a database page if it reads the page concurrently with
8122  * our write to the same page. This can be fixed as long as the first
8123  * write to the page in the WAL sequence is a full-page write. Hence, we
8124  * turn on forcePageWrites and then force a CHECKPOINT, to ensure there
8125  * are no dirty pages in shared memory that might get dumped while the
8126  * backup is in progress without having a corresponding WAL record. (Once
8127  * the backup is complete, we need not force full-page writes anymore,
8128  * since we expect that any pages not modified during the backup interval
8129  * must have been correctly captured by the backup.)
8130  *
8131  * Note that forcePageWrites has no effect during an online backup from
8132  * the standby.
8133  *
8134  * We must hold all the insertion locks to change the value of
8135  * forcePageWrites, to ensure adequate interlocking against
8136  * XLogInsertRecord().
8137  */
8140  XLogCtl->Insert.forcePageWrites = true;
8142 
8143  /* Ensure we release forcePageWrites if fail below */
8145  {
8146  bool gotUniqueStartpoint = false;
8147  DIR *tblspcdir;
8148  struct dirent *de;
8149  tablespaceinfo *ti;
8150  int datadirpathlen;
8151 
8152  /*
8153  * Force an XLOG file switch before the checkpoint, to ensure that the
8154  * WAL segment the checkpoint is written to doesn't contain pages with
8155  * old timeline IDs. That would otherwise happen if you called
8156  * pg_backup_start() right after restoring from a PITR archive: the
8157  * first WAL segment containing the startup checkpoint has pages in
8158  * the beginning with the old timeline ID. That can cause trouble at
8159  * recovery: we won't have a history file covering the old timeline if
8160  * pg_wal directory was not included in the base backup and the WAL
8161  * archive was cleared too before starting the backup.
8162  *
8163  * This also ensures that we have emitted a WAL page header that has
8164  * XLP_BKP_REMOVABLE off before we emit the checkpoint record.
8165  * Therefore, if a WAL archiver (such as pglesslog) is trying to
8166  * compress out removable backup blocks, it won't remove any that
8167  * occur after this point.
8168  *
8169  * During recovery, we skip forcing XLOG file switch, which means that
8170  * the backup taken during recovery is not available for the special
8171  * recovery case described above.
8172  */
8174  RequestXLogSwitch(false);
8175 
8176  do
8177  {
8178  bool checkpointfpw;
8179 
8180  /*
8181  * Force a CHECKPOINT. Aside from being necessary to prevent torn
8182  * page problems, this guarantees that two successive backup runs
8183  * will have different checkpoint positions and hence different
8184  * history file names, even if nothing happened in between.
8185  *
8186  * During recovery, establish a restartpoint if possible. We use
8187  * the last restartpoint as the backup starting checkpoint. This
8188  * means that two successive backup runs can have same checkpoint
8189  * positions.
8190  *
8191  * Since the fact that we are executing do_pg_backup_start()
8192  * during recovery means that checkpointer is running, we can use
8193  * RequestCheckpoint() to establish a restartpoint.
8194  *
8195  * We use CHECKPOINT_IMMEDIATE only if requested by user (via
8196  * passing fast = true). Otherwise this can take awhile.
8197  */
8199  (fast ? CHECKPOINT_IMMEDIATE : 0));
8200 
8201  /*
8202  * Now we need to fetch the checkpoint record location, and also
8203  * its REDO pointer. The oldest point in WAL that would be needed
8204  * to restore starting from the checkpoint is precisely the REDO
8205  * pointer.
8206  */
8207  LWLockAcquire(ControlFileLock, LW_SHARED);
8208  checkpointloc = ControlFile->checkPoint;
8209  startpoint = ControlFile->checkPointCopy.redo;
8211  checkpointfpw = ControlFile->checkPointCopy.fullPageWrites;
8212  LWLockRelease(ControlFileLock);
8213 
8215  {
8216  XLogRecPtr recptr;
8217 
8218  /*
8219  * Check to see if all WAL replayed during online backup
8220  * (i.e., since last restartpoint used as backup starting
8221  * checkpoint) contain full-page writes.
8222  */
8224  recptr = XLogCtl->lastFpwDisableRecPtr;
8226 
8227  if (!checkpointfpw || startpoint <= recptr)
8228  ereport(ERROR,
8229  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8230  errmsg("WAL generated with full_page_writes=off was replayed "
8231  "since last restartpoint"),
8232  errhint("This means that the backup being taken on the standby "
8233  "is corrupt and should not be used. "
8234  "Enable full_page_writes and run CHECKPOINT on the primary, "
8235  "and then try an online backup again.")));
8236 
8237  /*
8238  * During recovery, since we don't use the end-of-backup WAL
8239  * record and don't write the backup history file, the
8240  * starting WAL location doesn't need to be unique. This means
8241  * that two base backups started at the same time might use
8242  * the same checkpoint as starting locations.
8243  */
8244  gotUniqueStartpoint = true;
8245  }
8246 
8247  /*
8248  * If two base backups are started at the same time (in WAL sender
8249  * processes), we need to make sure that they use different
8250  * checkpoints as starting locations, because we use the starting
8251  * WAL location as a unique identifier for the base backup in the
8252  * end-of-backup WAL record and when we write the backup history
8253  * file. Perhaps it would be better generate a separate unique ID
8254  * for each backup instead of forcing another checkpoint, but
8255  * taking a checkpoint right after another is not that expensive
8256  * either because only few buffers have been dirtied yet.
8257  */
8259  if (XLogCtl->Insert.lastBackupStart < startpoint)
8260  {
8261  XLogCtl->Insert.lastBackupStart = startpoint;
8262  gotUniqueStartpoint = true;
8263  }
8265  } while (!gotUniqueStartpoint);
8266 
8267  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
8268  XLogFileName(xlogfilename, starttli, _logSegNo, wal_segment_size);
8269 
8270  /*
8271  * Construct tablespace_map file.
8272  */
8273  datadirpathlen = strlen(DataDir);
8274 
8275  /* Collect information about all tablespaces */
8276  tblspcdir = AllocateDir("pg_tblspc");
8277  while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL)
8278  {
8279  char fullpath[MAXPGPATH + 10];
8280  char linkpath[MAXPGPATH];
8281  char *relpath = NULL;
8282  int rllen;
8283  StringInfoData escapedpath;
8284  char *s;
8285 
8286  /* Skip anything that doesn't look like a tablespace */
8287  if (strspn(de->d_name, "0123456789") != strlen(de->d_name))
8288  continue;
8289 
8290  snprintf(fullpath, sizeof(fullpath), "pg_tblspc/%s", de->d_name);
8291 
8292  /*
8293  * Skip anything that isn't a symlink/junction. For testing only,
8294  * we sometimes use allow_in_place_tablespaces to create
8295  * directories directly under pg_tblspc, which would fail below.
8296  */
8297 #ifdef WIN32
8298  if (!pgwin32_is_junction(fullpath))
8299  continue;
8300 #else
8301  if (get_dirent_type(fullpath, de, false, ERROR) != PGFILETYPE_LNK)
8302  continue;
8303 #endif
8304 
8305 #if defined(HAVE_READLINK) || defined(WIN32)
8306  rllen = readlink(fullpath, linkpath, sizeof(linkpath));
8307  if (rllen < 0)
8308  {
8309  ereport(WARNING,
8310  (errmsg("could not read symbolic link \"%s\": %m",
8311  fullpath)));
8312  continue;
8313  }
8314  else if (rllen >= sizeof(linkpath))
8315  {
8316  ereport(WARNING,
8317  (errmsg("symbolic link \"%s\" target is too long",
8318  fullpath)));
8319  continue;
8320  }
8321  linkpath[rllen] = '\0';
8322 
8323  /*
8324  * Build a backslash-escaped version of the link path to include
8325  * in the tablespace map file.
8326  */
8327  initStringInfo(&escapedpath);
8328  for (s = linkpath; *s; s++)
8329  {
8330  if (*s == '\n' || *s == '\r' || *s == '\\')
8331  appendStringInfoChar(&escapedpath, '\\');
8332  appendStringInfoChar(&escapedpath, *s);
8333  }
8334 
8335  /*
8336  * Relpath holds the relative path of the tablespace directory
8337  * when it's located within PGDATA, or NULL if it's located
8338  * elsewhere.
8339  */
8340  if (rllen > datadirpathlen &&
8341  strncmp(linkpath, DataDir, datadirpathlen) == 0 &&
8342  IS_DIR_SEP(linkpath[datadirpathlen]))
8343  relpath = linkpath + datadirpathlen + 1;
8344 
8345  ti = palloc(sizeof(tablespaceinfo));
8346  ti->oid = pstrdup(de->d_name);
8347  ti->path = pstrdup(linkpath);
8348  ti->rpath = relpath ? pstrdup(relpath) : NULL;
8349  ti->size = -1;
8350 
8351  if (tablespaces)
8352  *tablespaces = lappend(*tablespaces, ti);
8353 
8354  appendStringInfo(tblspcmapfile, "%s %s\n",
8355  ti->oid, escapedpath.data);
8356 
8357  pfree(escapedpath.data);
8358 #else
8359 
8360  /*
8361  * If the platform does not have symbolic links, it should not be
8362  * possible to have tablespaces - clearly somebody else created
8363  * them. Warn about it and ignore.
8364  */
8365  ereport(WARNING,
8366  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
8367  errmsg("tablespaces are not supported on this platform")));
8368 #endif
8369  }
8370  FreeDir(tblspcdir);
8371 
8372  /*
8373  * Construct backup label file.
8374  */
8375 
8376  /* Use the log timezone here, not the session timezone */
8377  stamp_time = (pg_time_t) time(NULL);
8378  pg_strftime(strfbuf, sizeof(strfbuf),
8379  "%Y-%m-%d %H:%M:%S %Z",
8380  pg_localtime(&stamp_time, log_timezone));
8381  appendStringInfo(labelfile, "START WAL LOCATION: %X/%X (file %s)\n",
8382  LSN_FORMAT_ARGS(startpoint), xlogfilename);
8383  appendStringInfo(labelfile, "CHECKPOINT LOCATION: %X/%X\n",
8384  LSN_FORMAT_ARGS(checkpointloc));
8385  appendStringInfo(labelfile, "BACKUP METHOD: streamed\n");
8386  appendStringInfo(labelfile, "BACKUP FROM: %s\n",
8387  backup_started_in_recovery ? "standby" : "primary");
8388  appendStringInfo(labelfile, "START TIME: %s\n", strfbuf);
8389  appendStringInfo(labelfile, "LABEL: %s\n", backupidstr);
8390  appendStringInfo(labelfile, "START TIMELINE: %u\n", starttli);
8391  }
8393 
8394  /*
8395  * Mark that the start phase has correctly finished for the backup.
8396  */
8398 
8399  /*
8400  * We're done. As a convenience, return the starting WAL location.
8401  */
8402  if (starttli_p)
8403  *starttli_p = starttli;
8404  return startpoint;
8405 }
static bool backup_started_in_recovery
Definition: basebackup.c:100
void RequestCheckpoint(int flags)
Definition: checkpointer.c:931
int errcode(int sqlerrcode)
Definition: elog.c:693
PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
Definition: file_utils.c:410
@ 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
char * pstrdup(const char *in)
Definition: mcxt.c:1305
size_t pg_strftime(char *s, size_t max, const char *format, const struct pg_tm *tm)
Definition: strftime.c:128
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1342
PGDLLIMPORT pg_tz * log_timezone
Definition: pgtz.c:31
#define IS_DIR_SEP(ch)
Definition: port.h:87
uintptr_t Datum
Definition: postgres.h:411
#define relpath(rnode, forknum)
Definition: relpath.h:87
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:553
XLogRecPtr lastBackupStart
Definition: xlog.c:444
char * rpath
Definition: basebackup.h:32
bool pgwin32_is_junction(const char *path)
#define readlink(path, buf, size)
Definition: win32_port.h:236
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:7366
static void pg_backup_start_callback(int code, Datum arg)
Definition: xlog.c:8409
#define CHECKPOINT_WAIT
Definition: xlog.h:140
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:136
#define XLogIsNeeded()
Definition: xlog.h:104

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

Referenced by perform_base_backup(), and pg_backup_start().

◆ do_pg_backup_stop()

XLogRecPtr do_pg_backup_stop ( char *  labelfile,
bool  waitforarchive,
TimeLineID stoptli_p 
)

Definition at line 8446 of file xlog.c.

8447 {
8448  bool backup_started_in_recovery = false;
8449  XLogRecPtr startpoint;
8450  XLogRecPtr stoppoint;
8451  TimeLineID stoptli;
8452  pg_time_t stamp_time;
8453  char strfbuf[128];
8454  char histfilepath[MAXPGPATH];
8455  char startxlogfilename[MAXFNAMELEN];
8456  char stopxlogfilename[MAXFNAMELEN];
8457  char lastxlogfilename[MAXFNAMELEN];
8458  char histfilename[MAXFNAMELEN];
8459  char backupfrom[20];
8460  XLogSegNo _logSegNo;
8461  FILE *fp;
8462  char ch;
8463  int seconds_before_warning;
8464  int waits = 0;
8465  bool reported_waiting = false;
8466  char *remaining;
8467  char *ptr;
8468  uint32 hi,
8469  lo;
8470 
8472 
8473  /*
8474  * During recovery, we don't need to check WAL level. Because, if WAL
8475  * level is not sufficient, it's impossible to get here during recovery.
8476  */
8478  ereport(ERROR,
8479  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8480  errmsg("WAL level not sufficient for making an online backup"),
8481  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
8482 
8483  /*
8484  * OK to update backup counters, forcePageWrites, and session-level lock.
8485  *
8486  * Note that CHECK_FOR_INTERRUPTS() must not occur while updating them.
8487  * Otherwise they can be updated inconsistently, and which might cause
8488  * do_pg_abort_backup() to fail.
8489  */
8491 
8492  /*
8493  * It is expected that each do_pg_backup_start() call is matched by
8494  * exactly one do_pg_backup_stop() call.
8495  */
8498 
8499  if (XLogCtl->Insert.runningBackups == 0)
8500  {
8501  XLogCtl->Insert.forcePageWrites = false;
8502  }
8503 
8504  /*
8505  * Clean up session-level lock.
8506  *
8507  * You might think that WALInsertLockRelease() can be called before
8508  * cleaning up session-level lock because session-level lock doesn't need
8509  * to be protected with WAL insertion lock. But since
8510  * CHECK_FOR_INTERRUPTS() can occur in it, session-level lock must be
8511  * cleaned up before it.
8512  */
8514 
8516 
8517  /*
8518  * Read and parse the START WAL LOCATION line (this code is pretty crude,
8519  * but we are not expecting any variability in the file format).
8520  */
8521  if (sscanf(labelfile, "START WAL LOCATION: %X/%X (file %24s)%c",
8522  &hi, &lo, startxlogfilename,
8523  &ch) != 4 || ch != '\n')
8524  ereport(ERROR,
8525  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8526  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
8527  startpoint = ((uint64) hi) << 32 | lo;
8528  remaining = strchr(labelfile, '\n') + 1; /* %n is not portable enough */
8529 
8530  /*
8531  * Parse the BACKUP FROM line. If we are taking an online backup from the
8532  * standby, we confirm that the standby has not been promoted during the
8533  * backup.
8534  */
8535  ptr = strstr(remaining, "BACKUP FROM:");
8536  if (!ptr || sscanf(ptr, "BACKUP FROM: %19s\n", backupfrom) != 1)
8537  ereport(ERROR,
8538  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8539  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
8540  if (strcmp(backupfrom, "standby") == 0 && !backup_started_in_recovery)
8541  ereport(ERROR,
8542  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8543  errmsg("the standby was promoted during online backup"),
8544  errhint("This means that the backup being taken is corrupt "
8545  "and should not be used. "
8546  "Try taking another online backup.")));
8547 
8548  /*
8549  * During recovery, we don't write an end-of-backup record. We assume that
8550  * pg_control was backed up last and its minimum recovery point can be
8551  * available as the backup end location. Since we don't have an
8552  * end-of-backup record, we use the pg_control value to check whether
8553  * we've reached the end of backup when starting recovery from this
8554  * backup. We have no way of checking if pg_control wasn't backed up last
8555  * however.
8556  *
8557  * We don't force a switch to new WAL file but it is still possible to
8558  * wait for all the required files to be archived if waitforarchive is
8559  * true. This is okay if we use the backup to start a standby and fetch
8560  * the missing WAL using streaming replication. But in the case of an
8561  * archive recovery, a user should set waitforarchive to true and wait for
8562  * them to be archived to ensure that all the required files are
8563  * available.
8564  *
8565  * We return the current minimum recovery point as the backup end
8566  * location. Note that it can be greater than the exact backup end
8567  * location if the minimum recovery point is updated after the backup of
8568  * pg_control. This is harmless for current uses.
8569  *
8570  * XXX currently a backup history file is for informational and debug
8571  * purposes only. It's not essential for an online backup. Furthermore,
8572  * even if it's created, it will not be archived during recovery because
8573  * an archiver is not invoked. So it doesn't seem worthwhile to write a
8574  * backup history file during recovery.
8575  */
8577  {
8578  XLogRecPtr recptr;
8579 
8580  /*
8581  * Check to see if all WAL replayed during online backup contain
8582  * full-page writes.
8583  */
8585  recptr = XLogCtl->lastFpwDisableRecPtr;
8587 
8588  if (startpoint <= recptr)
8589  ereport(ERROR,
8590  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
8591  errmsg("WAL generated with full_page_writes=off was replayed "
8592  "during online backup"),
8593  errhint("This means that the backup being taken on the standby "
8594  "is corrupt and should not be used. "
8595  "Enable full_page_writes and run CHECKPOINT on the primary, "
8596  "and then try an online backup again.")));
8597 
8598 
8599  LWLockAcquire(ControlFileLock, LW_SHARED);
8600  stoppoint = ControlFile->minRecoveryPoint;
8601  stoptli = ControlFile->minRecoveryPointTLI;
8602  LWLockRelease(ControlFileLock);
8603  }
8604  else
8605  {
8606  /*
8607  * Write the backup-end xlog record
8608  */
8609  XLogBeginInsert();
8610  XLogRegisterData((char *) (&startpoint), sizeof(startpoint));
8611  stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
8612 
8613  /*
8614  * Given that we're not in recovery, InsertTimeLineID is set and can't
8615  * change, so we can read it without a lock.
8616  */
8617  stoptli = XLogCtl->InsertTimeLineID;
8618 
8619  /*
8620  * Force a switch to a new xlog segment file, so that the backup is
8621  * valid as soon as archiver moves out the current segment file.
8622  */
8623  RequestXLogSwitch(false);
8624 
8625  XLByteToPrevSeg(stoppoint, _logSegNo, wal_segment_size);
8626  XLogFileName(stopxlogfilename, stoptli, _logSegNo, wal_segment_size);
8627 
8628  /* Use the log timezone here, not the session timezone */
8629  stamp_time = (pg_time_t) time(NULL);
8630  pg_strftime(strfbuf, sizeof(strfbuf),
8631  "%Y-%m-%d %H:%M:%S %Z",
8632  pg_localtime(&stamp_time, log_timezone));
8633 
8634  /*
8635  * Write the backup history file
8636  */
8637  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
8638  BackupHistoryFilePath(histfilepath, stoptli, _logSegNo,
8639  startpoint, wal_segment_size);
8640  fp = AllocateFile(histfilepath, "w");
8641  if (!fp)
8642  ereport(ERROR,
8644  errmsg("could not create file \"%s\": %m",
8645  histfilepath)));
8646  fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n",
8647  LSN_FORMAT_ARGS(startpoint), startxlogfilename);
8648  fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
8649  LSN_FORMAT_ARGS(stoppoint), stopxlogfilename);
8650 
8651  /*
8652  * Transfer remaining lines including label and start timeline to
8653  * history file.
8654  */
8655  fprintf(fp, "%s", remaining);
8656  fprintf(fp, "STOP TIME: %s\n", strfbuf);
8657  fprintf(fp, "STOP TIMELINE: %u\n", stoptli);
8658  if (fflush(fp) || ferror(fp) || FreeFile(fp))
8659  ereport(ERROR,
8661  errmsg("could not write file \"%s\": %m",
8662  histfilepath)));
8663 
8664  /*
8665  * Clean out any no-longer-needed history files. As a side effect,
8666  * this will post a .ready file for the newly created history file,
8667  * notifying the archiver that history file may be archived
8668  * immediately.
8669  */
8671  }
8672 
8673  /*
8674  * If archiving is enabled, wait for all the required WAL files to be
8675  * archived before returning. If archiving isn't enabled, the required WAL
8676  * needs to be transported via streaming replication (hopefully with
8677  * wal_keep_size set high enough), or some more exotic mechanism like
8678  * polling and copying files from pg_wal with script. We have no knowledge
8679  * of those mechanisms, so it's up to the user to ensure that he gets all
8680  * the required WAL.
8681  *
8682  * We wait until both the last WAL file filled during backup and the
8683  * history file have been archived, and assume that the alphabetic sorting
8684  * property of the WAL files ensures any earlier WAL files are safely
8685  * archived as well.
8686  *
8687  * We wait forever, since archive_command is supposed to work and we
8688  * assume the admin wanted his backup to work completely. If you don't
8689  * wish to wait, then either waitforarchive should be passed in as false,
8690  * or you can set statement_timeout. Also, some notices are issued to
8691  * clue in anyone who might be doing this interactively.
8692  */
8693 
8694  if (waitforarchive &&
8697  {
8698  XLByteToPrevSeg(stoppoint, _logSegNo, wal_segment_size);
8699  XLogFileName(lastxlogfilename, stoptli, _logSegNo, wal_segment_size);
8700 
8701  XLByteToSeg(startpoint, _logSegNo, wal_segment_size);
8702  BackupHistoryFileName(histfilename, stoptli, _logSegNo,
8703  startpoint, wal_segment_size);
8704 
8705  seconds_before_warning = 60;
8706  waits = 0;
8707 
8708  while (XLogArchiveIsBusy(lastxlogfilename) ||
8709  XLogArchiveIsBusy(histfilename))
8710  {
8712 
8713  if (!reported_waiting && waits > 5)
8714  {
8715  ereport(NOTICE,
8716  (errmsg("base backup done, waiting for required WAL segments to be archived")));
8717  reported_waiting = true;
8718  }
8719 
8720  (void) WaitLatch(MyLatch,
8722  1000L,
8725 
8726  if (++waits >= seconds_before_warning)
8727  {
8728  seconds_before_warning *= 2; /* This wraps in >10 years... */
8729  ereport(WARNING,
8730  (errmsg("still waiting for all required WAL segments to be archived (%d seconds elapsed)",
8731  waits),
8732  errhint("Check that your archive_command is executing properly. "
8733  "You can safely cancel this backup, "
8734  "but the database backup will not be usable without all the WAL segments.")));
8735  }
8736  }
8737 
8738  ereport(NOTICE,
8739  (errmsg("all required WAL segments have been archived")));
8740  }
8741  else if (waitforarchive)
8742  ereport(NOTICE,
8743  (errmsg("WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup")));
8744 
8745  /*
8746  * We're done. As a convenience, return the ending WAL location.
8747  */
8748  if (stoptli_p)
8749  *stoptli_p = stoptli;
8750  return stoppoint;
8751 }
#define NOTICE
Definition: elog.h:29
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2461
int FreeFile(FILE *file)
Definition: fd.c:2660
struct Latch * MyLatch
Definition: globals.c:58
int remaining
Definition: informix.c:667
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:229
@ WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE
Definition: wait_event.h:85
static void CleanupBackupHistory(void)
Definition: xlog.c:3828
#define BACKUP_LABEL_FILE
Definition: xlog.h:292
@ SESSION_BACKUP_NONE
Definition: xlog.h:276
#define XLogArchivingAlways()
Definition: xlog.h:97
#define BackupHistoryFileName(fname, tli, logSegNo, startpoint, wal_segsz_bytes)
#define BackupHistoryFilePath(path, tli, logSegNo, startpoint, wal_segsz_bytes)
bool XLogArchiveIsBusy(const char *xlog)
Definition: xlogarchive.c:649

References AllocateFile(), Assert(), BACKUP_LABEL_FILE, backup_started_in_recovery, BackupHistoryFileName, BackupHistoryFilePath, CHECK_FOR_INTERRUPTS, CleanupBackupHistory(), ControlFile, ereport, errcode(), errcode_for_file_access(), errhint(), errmsg(), ERROR, fflush(), XLogCtlInsert::forcePageWrites, fprintf, FreeFile(), XLogCtlData::info_lck, XLogCtlData::Insert, XLogCtlData::InsertTimeLineID, XLogCtlData::lastFpwDisableRecPtr, log_timezone, LSN_FORMAT_ARGS, LW_SHARED, LWLockAcquire(), LWLockRelease(), MAXFNAMELEN, MAXPGPATH, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, MyLatch, NOTICE, pg_localtime(), pg_strftime(), RecoveryInProgress(), remaining, 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 8428 of file xlog.c.

8429 {
8430  return sessionBackupState;
8431 }

References sessionBackupState.

Referenced by pg_backup_start(), and pg_backup_stop().

◆ get_sync_bit()

static int get_sync_bit ( int  method)
static

Definition at line 7879 of file xlog.c.

7880 {
7881  int o_direct_flag = 0;
7882 
7883  /* If fsync is disabled, never open in sync mode */
7884  if (!enableFsync)
7885  return 0;
7886 
7887  /*
7888  * Optimize writes by bypassing kernel cache with O_DIRECT when using
7889  * O_SYNC/O_FSYNC and O_DSYNC. But only if archiving and streaming are
7890  * disabled, otherwise the archive command or walsender process will read
7891  * the WAL soon after writing it, which is guaranteed to cause a physical
7892  * read if we bypassed the kernel cache. We also skip the
7893  * posix_fadvise(POSIX_FADV_DONTNEED) call in XLogFileClose() for the same
7894  * reason.
7895  *
7896  * Never use O_DIRECT in walreceiver process for similar reasons; the WAL
7897  * written by walreceiver is normally read by the startup process soon
7898  * after it's written. Also, walreceiver performs unaligned writes, which
7899  * don't work with O_DIRECT, so it is required for correctness too.
7900  */
7901  if (!XLogIsNeeded() && !AmWalReceiverProcess())
7902  o_direct_flag = PG_O_DIRECT;
7903 
7904  switch (method)
7905  {
7906  /*
7907  * enum values for all sync options are defined even if they are
7908  * not supported on the current platform. But if not, they are
7909  * not included in the enum option array, and therefore will never
7910  * be seen here.
7911  */
7912  case SYNC_METHOD_FSYNC:
7914  case SYNC_METHOD_FDATASYNC:
7915  return 0;
7916 #ifdef OPEN_SYNC_FLAG
7917  case SYNC_METHOD_OPEN:
7918  return OPEN_SYNC_FLAG | o_direct_flag;
7919 #endif
7920 #ifdef OPEN_DATASYNC_FLAG
7922  return OPEN_DATASYNC_FLAG | o_direct_flag;
7923 #endif
7924  default:
7925  /* can't happen (unless we are out of sync with option array) */
7926  elog(ERROR, "unrecognized wal_sync_method: %d", method);
7927  return 0; /* silence warning */
7928  }
7929 }
#define PG_O_DIRECT
Definition: fd.h:95
bool enableFsync
Definition: globals.c:123
#define AmWalReceiverProcess()
Definition: miscadmin.h:449
#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, 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 4242 of file xlog.c.

4243 {
4244  XLogRecPtr nextUnloggedLSN;
4245 
4246  /* increment the unloggedLSN counter, need SpinLock */
4248  nextUnloggedLSN = XLogCtl->unloggedLSN++;
4250 
4251  return nextUnloggedLSN;
4252 }

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

Referenced by gistGetFakeLSN().

◆ GetFlushRecPtr()

XLogRecPtr GetFlushRecPtr ( TimeLineID insertTLI)

Definition at line 5927 of file xlog.c.

5928 {
5930 
5934 
5935  /*
5936  * If we're writing and flushing WAL, the time line can't be changing, so
5937  * no lock is required.
5938  */
5939  if (insertTLI)
5940  *insertTLI = XLogCtl->InsertTimeLineID;
5941 
5942  return LogwrtResult.Flush;
5943 }
RecoveryState SharedRecoveryState
Definition: xlog.c:518
XLogRecPtr Flush
Definition: xlog.c:331
@ 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 5895 of file xlog.c.

5896 {
5897  *RedoRecPtr_p = RedoRecPtr;
5898  *doPageWrites_p = doPageWrites;
5899 }
static bool doPageWrites
Definition: xlog.c:283

References doPageWrites, and RedoRecPtr.

Referenced by XLogCheckBufferNeedsBackup(), and XLogInsert().

◆ GetInsertRecPtr()

XLogRecPtr GetInsertRecPtr ( void  )

Definition at line 5910 of file xlog.c.

5911 {
5912  XLogRecPtr recptr;
5913 
5915  recptr = XLogCtl->LogwrtRqst.Write;
5917 
5918  return recptr;
5919 }

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

5968 {
5970  int i;
5971 
5972  for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
5973  {
5974  XLogRecPtr last_important;
5975 
5976  /*
5977  * Need to take a lock to prevent torn reads of the LSN, which are
5978  * possible on some of the supported platforms. WAL insert locks only
5979  * support exclusive mode, so we have to use that.
5980  */
5982  last_important = WALInsertLocks[i].l.lastImportantAt;
5983  LWLockRelease(&WALInsertLocks[i].l.lock);
5984 
5985  if (res < last_important)
5986  res = last_important;
5987  }
5988 
5989  return res;
5990 }
int i
Definition: isn.c:73
XLogRecPtr lastImportantAt
Definition: xlog.c:374
WALInsertLock l
Definition: xlog.c:386
static WALInsertLockPadded * WALInsertLocks
Definition: xlog.c:561
#define NUM_XLOGINSERT_LOCKS
Definition: xlog.c:151

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

5997 {
5998  pg_time_t result;
5999 
6000  /* Need WALWriteLock, but shared lock is sufficient */
6001  LWLockAcquire(WALWriteLock, LW_SHARED);
6002  result = XLogCtl->lastSegSwitchTime;
6003  *lastSwitchLSN = XLogCtl->lastSegSwitchLSN;
6004  LWLockRelease(WALWriteLock);
6005 
6006  return result;
6007 }
pg_time_t lastSegSwitchTime
Definition: xlog.c:473
XLogRecPtr lastSegSwitchLSN
Definition: xlog.c:474

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

Referenced by CheckArchiveTimeout().

◆ GetMockAuthenticationNonce()

char* GetMockAuthenticationNonce ( void  )

Definition at line 4216 of file xlog.c.

4217 {
4218  Assert(ControlFile != NULL);
4220 }
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 8842 of file xlog.c.

8843 {
8844  LWLockAcquire(ControlFileLock, LW_SHARED);
8845  *oldrecptr = ControlFile->checkPointCopy.redo;
8847  LWLockRelease(ControlFileLock);
8848 }

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

5799 {
5800  RecoveryState retval;
5801 
5803  retval = XLogCtl->SharedRecoveryState;
5805 
5806  return retval;
5807 }
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 5865 of file xlog.c.

5866 {
5867  XLogRecPtr ptr;
5868 
5869  /*
5870  * The possibly not up-to-date copy in XlogCtl is enough. Even if we
5871  * grabbed a WAL insertion lock to read the authoritative value in
5872  * Insert->RedoRecPtr, someone might update it just after we've released
5873  * the lock.
5874  */
5876  ptr = XLogCtl->RedoRecPtr;
5878 
5879  if (RedoRecPtr < ptr)
5880  RedoRecPtr = ptr;
5881 
5882  return RedoRecPtr;
5883 }

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

4207 {
4208  Assert(ControlFile != NULL);
4210 }

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

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

◆ GetWALAvailability()

WALAvailability GetWALAvailability ( XLogRecPtr  targetLSN)

Definition at line 7189 of file xlog.c.

7190 {
7191  XLogRecPtr currpos; /* current write LSN */
7192  XLogSegNo currSeg; /* segid of currpos */
7193  XLogSegNo targetSeg; /* segid of targetLSN */
7194  XLogSegNo oldestSeg; /* actual oldest segid */
7195  XLogSegNo oldestSegMaxWalSize; /* oldest segid kept by max_wal_size */
7196  XLogSegNo oldestSlotSeg; /* oldest segid kept by slot */
7197  uint64 keepSegs;
7198 
7199  /*
7200  * slot does not reserve WAL. Either deactivated, or has never been active
7201  */
7202  if (XLogRecPtrIsInvalid(targetLSN))
7203  return WALAVAIL_INVALID_LSN;
7204 
7205  /*
7206  * Calculate the oldest segment currently reserved by all slots,
7207  * considering wal_keep_size and max_slot_wal_keep_size. Initialize
7208  * oldestSlotSeg to the current segment.
7209  */
7210  currpos = GetXLogWriteRecPtr();
7211  XLByteToSeg(currpos, oldestSlotSeg, wal_segment_size);
7212  KeepLogSeg(currpos, &oldestSlotSeg);
7213 
7214  /*
7215  * Find the oldest extant segment file. We get 1 until checkpoint removes
7216  * the first WAL segment file since startup, which causes the status being
7217  * wrong under certain abnormal conditions but that doesn't actually harm.
7218  */
7219  oldestSeg = XLogGetLastRemovedSegno() + 1;
7220 
7221  /* calculate oldest segment by max_wal_size */
7222  XLByteToSeg(currpos, currSeg, wal_segment_size);
7224 
7225  if (currSeg > keepSegs)
7226  oldestSegMaxWalSize = currSeg - keepSegs;
7227  else
7228  oldestSegMaxWalSize = 1;
7229 
7230  /* the segment we care about */
7231  XLByteToSeg(targetLSN, targetSeg, wal_segment_size);
7232 
7233  /*
7234  * No point in returning reserved or extended status values if the
7235  * targetSeg is known to be lost.
7236  */
7237  if (targetSeg >= oldestSlotSeg)
7238  {
7239  /* show "reserved" when targetSeg is within max_wal_size */
7240  if (targetSeg >= oldestSegMaxWalSize)
7241  return WALAVAIL_RESERVED;
7242 
7243  /* being retained by slots exceeding max_wal_size */
7244  return WALAVAIL_EXTENDED;
7245  }
7246 
7247  /* WAL segments are no longer retained but haven't been removed yet */
7248  if (targetSeg >= oldestSeg)
7249  return WALAVAIL_UNRESERVED;
7250 
7251  /* Definitely lost */
7252  return WALAVAIL_REMOVED;
7253 }
XLogSegNo XLogGetLastRemovedSegno(void)
Definition: xlog.c:3485
XLogRecPtr GetXLogWriteRecPtr(void)
Definition: xlog.c:8828
@ 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 5950 of file xlog.c.

5951 {
5953 
5954  /* Since the value can't be changing, no lock is required. */
5955  return XLogCtl->InsertTimeLineID;
5956 }

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

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

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

8813 {
8815  uint64 current_bytepos;
8816 
8817  SpinLockAcquire(&Insert->insertpos_lck);
8818  current_bytepos = Insert->CurrBytePos;
8819  SpinLockRelease(&Insert->insertpos_lck);
8820 
8821  return XLogBytePosToRecPtr(current_bytepos);
8822 }

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

3872 {
3873  char mock_auth_nonce[MOCK_AUTH_NONCE_LEN];
3874 
3875  /*
3876  * Generate a random nonce. This is used for authentication requests that
3877  * will fail because the user does not exist. The nonce is used to create
3878  * a genuine-looking password challenge for the non-existent user, in lieu
3879  * of an actual stored password.
3880  */
3881  if (!pg_strong_random(mock_auth_nonce, MOCK_AUTH_NONCE_LEN))
3882  ereport(PANIC,
3883  (errcode(ERRCODE_INTERNAL_ERROR),
3884  errmsg("could not generate secret authorization token")));
3885 
3886  memset(ControlFile, 0, sizeof(ControlFileData));
3887  /* Initialize pg_control status fields */
3888  ControlFile->system_identifier = sysidentifier;
3889  memcpy(ControlFile->mock_authentication_nonce, mock_auth_nonce, MOCK_AUTH_NONCE_LEN);
3892 
3893  /* Set important parameter values for use when replaying WAL */
3903 }
bool track_commit_timestamp
Definition: commit_ts.c:105
#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:132
bool wal_log_hints
Definition: xlog.c:124
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().

◆ InstallXLogFileSegment()

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

Definition at line 3288 of file xlog.c.

3290 {
3291  char path[MAXPGPATH];
3292  struct stat stat_buf;
3293 
3294  Assert(tli != 0);
3295 
3296  XLogFilePath(path, tli, *segno, wal_segment_size);
3297 
3298  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
3300  {
3301  LWLockRelease(ControlFileLock);
3302  return false;
3303  }
3304 
3305  if (!find_free)
3306  {
3307  /* Force installation: get rid of any pre-existing segment file */
3308  durable_unlink(path, DEBUG1);
3309  }
3310  else
3311  {
3312  /* Find a free slot to put it in */
3313  while (stat(path, &stat_buf) == 0)
3314  {
3315  if ((*segno) >= max_segno)
3316  {
3317  /* Failed to find a free slot within specified range */
3318  LWLockRelease(ControlFileLock);
3319  return false;
3320  }
3321  (*segno)++;
3322  XLogFilePath(path, tli, *segno, wal_segment_size);
3323  }
3324  }
3325 
3326  /*
3327  * Perform the rename using link if available, paranoidly trying to avoid
3328  * overwriting an existing file (there shouldn't be one).
3329  */
3330  if (durable_rename_excl(tmppath, path, LOG) != 0)
3331  {
3332  LWLockRelease(ControlFileLock);
3333  /* durable_rename_excl already emitted log message */
3334  return false;
3335  }
3336 
3337  LWLockRelease(ControlFileLock);
3338 
3339  return true;
3340 }
int durable_rename_excl(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:829
int durable_unlink(const char *fname, int elevel)
Definition: fd.c:789
#define stat
Definition: win32_port.h:283

References Assert(), DEBUG1, durable_rename_excl(), 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 8871 of file xlog.c.

8872 {
8873  bool result;
8874 
8875  LWLockAcquire(ControlFileLock, LW_SHARED);
8877  LWLockRelease(ControlFileLock);
8878 
8879  return result;
8880 }

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

7978 {
7979  char *msg = NULL;
7980  instr_time start;
7981 
7982  Assert(tli != 0);
7983 
7984  /*
7985  * Quick exit if fsync is disabled or write() has already synced the WAL
7986  * file.
7987  */
7988  if (!enableFsync ||
7991  return;
7992 
7993  /* Measure I/O timing to sync the WAL file */
7994  if (track_wal_io_timing)
7995  INSTR_TIME_SET_CURRENT(start);
7996 
7998  switch (sync_method)
7999  {
8000  case SYNC_METHOD_FSYNC:
8001  if (pg_fsync_no_writethrough(fd) != 0)
8002  msg = _("could not fsync file \"%s\": %m");
8003  break;
8004 #ifdef HAVE_FSYNC_WRITETHROUGH
8006  if (pg_fsync_writethrough(fd) != 0)
8007  msg = _("could not fsync write-through file \"%s\": %m");
8008  break;
8009 #endif
8010 #ifdef HAVE_FDATASYNC
8011  case SYNC_METHOD_FDATASYNC:
8012  if (pg_fdatasync(fd) != 0)
8013  msg = _("could not fdatasync file \"%s\": %m");
8014  break;
8015 #endif
8016  case SYNC_METHOD_OPEN:
8018  /* not reachable */
8019  Assert(false);
8020  break;
8021  default:
8022  elog(PANIC, "unrecognized wal_sync_method: %d", sync_method);
8023  break;
8024  }
8025 
8026  /* PANIC if failed to fsync */
8027  if (msg)
8028  {
8029  char xlogfname[MAXFNAMELEN];
8030  int save_errno = errno;
8031 
8032  XLogFileName(xlogfname, tli, segno, wal_segment_size);
8033  errno = save_errno;
8034  ereport(PANIC,
8036  errmsg(msg, xlogfname)));
8037  }
8038 
8040 
8041  /*
8042  * Increment the I/O timing and the number of times WAL files were synced.
8043  */
8044  if (track_wal_io_timing)
8045  {
8047 
8049  INSTR_TIME_SUBTRACT(duration, start);
8051  }
8052 
8054 }
#define _(x)
Definition: elog.c:89
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:414
int pg_fdatasync(int fd)
Definition: fd.c:449
int pg_fsync_writethrough(int fd)
Definition: fd.c:426
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:156
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:170
struct timeval instr_time
Definition: instr_time.h:150
#define INSTR_TIME_GET_MICROSEC(t)
Definition: instr_time.h:205
int duration
Definition: pgbench.c:187
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:230
bool track_wal_io_timing
Definition: xlog.c:138

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

7274 {
7275  XLogSegNo currSegNo;
7276  XLogSegNo segno;
7277  XLogRecPtr keep;
7278 
7279  XLByteToSeg(recptr, currSegNo, wal_segment_size);
7280  segno = currSegNo;
7281 
7282  /*
7283  * Calculate how many segments are kept by slots first, adjusting for
7284  * max_slot_wal_keep_size.
7285  */
7287  if (keep != InvalidXLogRecPtr)
7288  {
7289  XLByteToSeg(keep, segno, wal_segment_size);
7290 
7291  /* Cap by max_slot_wal_keep_size ... */
7292  if (max_slot_wal_keep_size_mb >= 0)
7293  {
7294  uint64 slot_keep_segs;
7295 
7296  slot_keep_segs =
7298 
7299  if (currSegNo - segno > slot_keep_segs)
7300  segno = currSegNo - slot_keep_segs;
7301  }
7302  }
7303 
7304  /* but, keep at least wal_keep_size if that's set */
7305  if (wal_keep_size_mb > 0)
7306  {
7307  uint64 keep_segs;
7308 
7310  if (currSegNo - segno < keep_segs)
7311  {
7312  /* avoid underflow, don't go below 1 */
7313  if (currSegNo <= keep_segs)
7314  segno = 1;
7315  else
7316  segno = currSegNo - keep_segs;
7317  }
7318  }
7319 
7320  /* don't delete WAL segments newer than the calculated segment */
7321  if (segno < *logSegNo)
7322  *logSegNo = segno;
7323 }
int wal_keep_size_mb
Definition: xlog.c:117
static XLogRecPtr XLogGetReplicationSlotMinimumLSN(void)
Definition: xlog.c:2408
int max_slot_wal_keep_size_mb
Definition: xlog.c:136

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

4327 {
4328  Assert(reset || ControlFile == NULL);
4329  ControlFile = palloc(sizeof(ControlFileData));
4330  ReadControlFile();
4331 }
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 5850 of file xlog.c.

5851 {
5852  int oldXLogAllowed = LocalXLogInsertAllowed;
5853 
5855 
5856  return oldXLogAllowed;
5857 }

References LocalXLogInsertAllowed.

Referenced by CreateCheckPoint(), and StartupXLOG().

◆ LogCheckpointEnd()

static void LogCheckpointEnd ( bool  restartpoint)
static

Definition at line 6092 of file xlog.c.

6093 {
6094  long write_msecs,
6095  sync_msecs,
6096  total_msecs,
6097  longest_msecs,
6098  average_msecs;
6099  uint64 average_sync_time;
6100 
6102 
6105 
6108 
6109  /* Accumulate checkpoint timing summary data, in milliseconds. */
6112 
6113  /*
6114  * All of the published timing statistics are accounted for. Only
6115  * continue if a log message is to be written.
6116  */
6117  if (!log_checkpoints)
6118  return;
6119 
6122 
6123  /*
6124  * Timing values returned from CheckpointStats are in microseconds.
6125  * Convert to milliseconds for consistent printing.
6126  */
6127  longest_msecs = (long) ((CheckpointStats.ckpt_longest_sync + 999) / 1000);
6128 
6129  average_sync_time = 0;
6131  average_sync_time = CheckpointStats.ckpt_agg_sync_time /
6133  average_msecs = (long) ((average_sync_time + 999) / 1000);
6134 
6135  if (restartpoint)
6136  ereport(LOG,
6137  (errmsg("restartpoint complete: wrote %d buffers (%.1f%%); "
6138  "%d WAL file(s) added, %d removed, %d recycled; "
6139  "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; "
6140  "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; "
6141  "distance=%d kB, estimate=%d kB",
6143  (double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
6147  write_msecs / 1000, (int) (write_msecs % 1000),
6148  sync_msecs / 1000, (int) (sync_msecs % 1000),
6149  total_msecs / 1000, (int) (total_msecs % 1000),
6151  longest_msecs / 1000, (int) (longest_msecs % 1000),
6152  average_msecs / 1000, (int) (average_msecs % 1000),
6153  (int) (PrevCheckPointDistance / 1024.0),
6154  (int) (CheckPointDistanceEstimate / 1024.0))));
6155  else
6156  ereport(LOG,
6157  (errmsg("checkpoint complete: wrote %d buffers (%.1f%%); "
6158  "%d WAL file(s) added, %d removed, %d recycled; "
6159  "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; "
6160  "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; "
6161  "distance=%d kB, estimate=%d kB",
6163  (double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
6167  write_msecs / 1000, (int) (write_msecs % 1000),
6168  sync_msecs / 1000, (int) (sync_msecs % 1000),
6169  total_msecs / 1000, (int) (total_msecs % 1000),
6171  longest_msecs / 1000, (int) (longest_msecs % 1000),
6172  average_msecs / 1000, (int) (average_msecs % 1000),
6173  (int) (PrevCheckPointDistance / 1024.0),
6174  (int) (CheckPointDistanceEstimate / 1024.0))));
6175 }
long TimestampDifferenceMilliseconds(TimestampTz start_time, TimestampTz stop_time)
Definition: timestamp.c:1687
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:160
static double PrevCheckPointDistance
Definition: xlog.c:161

References PgStat_CheckpointerStats::checkpoint_sync_time, PgStat_CheckpointerStats::checkpoint_write_time, 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, ereport, errmsg(), GetCurrentTimestamp(), LOG, log_checkpoints, NBuffers, PendingCheckpointerStats, PrevCheckPointDistance, and TimestampDifferenceMilliseconds().

Referenced by CreateCheckPoint(), and CreateRestartPoint().

◆ LogCheckpointStart()

static void LogCheckpointStart ( int  flags,
bool  restartpoint 
)
static

Definition at line 6060 of file xlog.c.

6061 {
6062  if (restartpoint)
6063  ereport(LOG,
6064  /* translator: the placeholders show checkpoint options */
6065  (errmsg("restartpoint starting:%s%s%s%s%s%s%s%s",
6066  (flags & CHECKPOINT_IS_SHUTDOWN) ? " shutdown" : "",
6067  (flags & CHECKPOINT_END_OF_RECOVERY) ? " end-of-recovery" : "",
6068  (flags & CHECKPOINT_IMMEDIATE) ? " immediate" : "",
6069  (flags & CHECKPOINT_FORCE) ? " force" : "",
6070  (flags & CHECKPOINT_WAIT) ? " wait" : "",
6071  (flags & CHECKPOINT_CAUSE_XLOG) ? " wal" : "",
6072  (flags & CHECKPOINT_CAUSE_TIME) ? " time" : "",
6073  (flags & CHECKPOINT_FLUSH_ALL) ? " flush-all" : "")));
6074  else
6075  ereport(LOG,
6076  /* translator: the placeholders show checkpoint options */
6077  (errmsg("checkpoint starting:%s%s%s%s%s%s%s%s",
6078  (flags & CHECKPOINT_IS_SHUTDOWN) ? " shutdown" : "",
6079  (flags & CHECKPOINT_END_OF_RECOVERY) ? " end-of-recovery" : "",
6080  (flags & CHECKPOINT_IMMEDIATE) ? " immediate" : "",
6081  (flags & CHECKPOINT_FORCE) ? " force" : "",
6082  (flags & CHECKPOINT_WAIT) ? " wait" : "",
6083  (flags & CHECKPOINT_CAUSE_XLOG) ? " wal" : "",
6084  (flags & CHECKPOINT_CAUSE_TIME) ? " time" : "",
6085  (flags & CHECKPOINT_FLUSH_ALL) ? " flush-all" : "")));
6086 }
#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 5712 of file xlog.c.

5713 {
5714  bool promoted = false;
5715 
5716  /*
5717  * Perform a checkpoint to update all our recovery activity to disk.
5718  *
5719  * Note that we write a shutdown checkpoint rather than an on-line one.
5720  * This is not particularly critical, but since we may be assigning a new
5721  * TLI, using a shutdown checkpoint allows us to have the rule that TLI
5722  * only changes in shutdown checkpoints, which allows some extra error
5723  * checking in xlog_redo.
5724  *
5725  * In promotion, only create a lightweight end-of-recovery record instead
5726  * of a full checkpoint. A checkpoint is requested later, after we're
5727  * fully out of recovery mode and already accepting queries.
5728  */
5731  {
5732  promoted = true;
5733 
5734  /*
5735  * Insert a special WAL record to mark the end of recovery, since we
5736  * aren't doing a checkpoint. That means that the checkpointer process
5737  * may likely be in the middle of a time-smoothed restartpoint and
5738  * could continue to be for minutes after this. That sounds strange,
5739  * but the effect is roughly the same and it would be stranger to try
5740  * to come out of the restartpoint and then checkpoint. We request a
5741  * checkpoint later anyway, just for safety.
5742  */
5744  }
5745  else
5746  {
5749  CHECKPOINT_WAIT);
5750  }
5751 
5752  return promoted;
5753 }
static void CreateEndOfRecoveryRecord(void)
Definition: xlog.c:6705
bool PromoteIsTriggered(void)

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

Referenced by StartupXLOG().

◆ pg_backup_start_callback()

static void pg_backup_start_callback ( int  code,
Datum  arg 
)
static

Definition at line 8409 of file xlog.c.

8410 {
8411  /* Update backup counters and forcePageWrites on failure */
8413 
8416 
8417  if (XLogCtl->Insert.runningBackups == 0)
8418  {
8419  XLogCtl->Insert.forcePageWrites = false;
8420  }
8422 }

References Assert(), XLogCtlInsert::forcePageWrites, XLogCtlData::Insert, XLogCtlInsert::runningBackups, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), and XLogCtl.

Referenced by do_pg_backup_start().

◆ PreallocXlogFiles()

static void PreallocXlogFiles ( XLogRecPtr  endptr,
TimeLineID  tli 
)
static

Definition at line 3417 of file xlog.c.

3418 {
3419  XLogSegNo _logSegNo;
3420  int lf;
3421  bool added;
3422  char path[MAXPGPATH];
3423  uint64 offset;
3424 
3426  return; /* unlocked check says no */
3427 
3428  XLByteToPrevSeg(endptr, _logSegNo, wal_segment_size);
3429  offset = XLogSegmentOffset(endptr - 1, wal_segment_size);
3430  if (offset >= (uint32) (0.75 * wal_segment_size))
3431  {
3432  _logSegNo++;
3433  lf = XLogFileInitInternal(_logSegNo, tli, &added, path);
3434  if (lf >= 0)
3435  close(lf);
3436  if (added)
3438  }
3439 }
static int XLogFileInitInternal(XLogSegNo logsegno, TimeLineID logtli, bool *added, char *path)
Definition: xlog.c:2917

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

5676 {
5677  /*
5678  * We have reached the end of base backup, as indicated by pg_control. The
5679  * data on disk is now consistent (unless minRecovery point is further
5680  * ahead, which can happen if we crashed during previous recovery). Reset
5681  * backupStartPoint and backupEndPoint, and update minRecoveryPoint to
5682  * make sure we don't allow starting up at an earlier point even if
5683  * recovery is stopped and restarted soon after this.
5684  */
5685  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
5686 
5687  if (ControlFile->minRecoveryPoint < EndRecPtr)
5688  {
5689  ControlFile->minRecoveryPoint = EndRecPtr;
5691  }
5692 
5695  ControlFile->backupEndRequired = false;
5697 
5698  LWLockRelease(ControlFileLock);
5699 }
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 3997 of file xlog.c.

3998 {
3999  pg_crc32c crc;
4000  int fd;
4001  static char wal_segsz_str[20];
4002  int r;
4003 
4004  /*
4005  * Read data...
4006  */
4008  O_RDWR | PG_BINARY);
4009  if (fd < 0)
4010  ereport(PANIC,
4012  errmsg("could not open file \"%s\": %m",
4013  XLOG_CONTROL_FILE)));
4014 
4016  r = read(fd, ControlFile, sizeof(ControlFileData));
4017  if (r != sizeof(ControlFileData))
4018  {
4019  if (r < 0)
4020  ereport(PANIC,
4022  errmsg("could not read file \"%s\": %m",
4023  XLOG_CONTROL_FILE)));
4024  else
4025  ereport(PANIC,
4027  errmsg("could not read file \"%s\": read %d of %zu",
4028  XLOG_CONTROL_FILE, r, sizeof(ControlFileData))));
4029  }
4031 
4032  close(fd);
4033 
4034  /*
4035  * Check for expected pg_control format version. If this is wrong, the
4036  * CRC check will likely fail because we'll be checking the wrong number
4037  * of bytes. Complaining about wrong version will probably be more
4038  * enlightening than complaining about wrong CRC.
4039  */
4040 
4042  ereport(FATAL,
4043  (errmsg("database files are incompatible with server"),
4044  errdetail("The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x),"
4045  " but the server was compiled with PG_CONTROL_VERSION %d (0x%08x).",
4048  errhint("This could be a problem of mismatched byte ordering. It looks like you need to initdb.")));
4049 
4051  ereport(FATAL,
4052  (errmsg("database files are incompatible with server"),
4053  errdetail("The database cluster was initialized with PG_CONTROL_VERSION %d,"
4054  " but the server was compiled with PG_CONTROL_VERSION %d.",
4056  errhint("It looks like you need to initdb.")));
4057 
4058  /* Now check the CRC. */
4059  INIT_CRC32C(crc);
4060  COMP_CRC32C(crc,
4061  (char *) ControlFile,
4063  FIN_CRC32C(crc);
4064 
4065  if (!EQ_CRC32C(crc, ControlFile->crc))
4066  ereport(FATAL,
4067  (errmsg("incorrect checksum in control file")));
4068 
4069  /*
4070  * Do compatibility checking immediately. If the database isn't
4071  * compatible with the backend executable, we want to abort before we can
4072  * possibly do any damage.
4073  */
4075  ereport(FATAL,
4076  (errmsg("database files are incompatible with server"),
4077  errdetail("The database cluster was initialized with CATALOG_VERSION_NO %d,"
4078  " but the server was compiled with CATALOG_VERSION_NO %d.",
4080  errhint("It looks like you need to initdb.")));
4081  if (ControlFile->maxAlign != MAXIMUM_ALIGNOF)
4082  ereport(FATAL,
4083  (errmsg("database files are incompatible with server"),
4084  errdetail("The database cluster was initialized with MAXALIGN %d,"
4085  " but the server was compiled with MAXALIGN %d.",
4086  ControlFile->maxAlign, MAXIMUM_ALIGNOF),
4087  errhint("It looks like you need to initdb.")));
4089  ereport(FATAL,
4090  (errmsg("database files are incompatible with server"),
4091  errdetail("The database cluster appears to use a different floating-point number format than the server executable."),
4092  errhint("It looks like you need to initdb.")));
4093  if (ControlFile->blcksz != BLCKSZ)
4094  ereport(FATAL,
4095  (errmsg("database files are incompatible with server"),
4096  errdetail("The database cluster was initialized with BLCKSZ %d,"
4097  " but the server was compiled with BLCKSZ %d.",
4098  ControlFile->blcksz, BLCKSZ),
4099  errhint("It looks like you need to recompile or initdb.")));
4100  if (ControlFile->relseg_size != RELSEG_SIZE)
4101  ereport(FATAL,
4102  (errmsg("database files are incompatible with server"),
4103  errdetail("The database cluster was initialized with RELSEG_SIZE %d,"
4104  " but the server was compiled with RELSEG_SIZE %d.",
4105  ControlFile->relseg_size, RELSEG_SIZE),
4106  errhint("It looks like you need to recompile or initdb.")));
4107  if (ControlFile->xlog_blcksz != XLOG_BLCKSZ)
4108  ereport(FATAL,
4109  (errmsg("database files are incompatible with server"),
4110  errdetail("The database cluster was initialized with XLOG_BLCKSZ %d,"
4111  " but the server was compiled with XLOG_BLCKSZ %d.",
4112  ControlFile->xlog_blcksz, XLOG_BLCKSZ),
4113  errhint("It looks like you need to recompile or initdb.")));
4115  ereport(FATAL,
4116  (errmsg("database files are incompatible with server"),
4117  errdetail("The database cluster was initialized with NAMEDATALEN %d,"
4118  " but the server was compiled with NAMEDATALEN %d.",
4120  errhint("It looks like you need to recompile or initdb.")));
4122  ereport(FATAL,
4123  (errmsg("database files are incompatible with server"),
4124  errdetail("The database cluster was initialized with INDEX_MAX_KEYS %d,"
4125  " but the server was compiled with INDEX_MAX_KEYS %d.",
4127  errhint("It looks like you need to recompile or initdb.")));
4129  ereport(FATAL,
4130  (errmsg("database files are incompatible with server"),
4131  errdetail("The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d,"
4132  " but the server was compiled with TOAST_MAX_CHUNK_SIZE %d.",
4134  errhint("It looks like you need to recompile or initdb.")));
4136  ereport(FATAL,
4137  (errmsg("database files are incompatible with server"),
4138  errdetail("The database cluster was initialized with LOBLKSIZE %d,"
4139  " but the server was compiled with LOBLKSIZE %d.",
4140  ControlFile->loblksize, (int) LOBLKSIZE),
4141  errhint("It looks like you need to recompile or initdb.")));
4142 
4143 #ifdef USE_FLOAT8_BYVAL
4144  if (ControlFile->float8ByVal != true)
4145  ereport(FATAL,
4146  (errmsg("database files are incompatible with server"),
4147  errdetail("The database cluster was initialized without USE_FLOAT8_BYVAL"
4148  " but the server was compiled with USE_FLOAT8_BYVAL."),
4149  errhint("It looks like you need to recompile or initdb.")));
4150 #else
4151  if (ControlFile->float8ByVal != false)
4152  ereport(FATAL,
4153  (errmsg("database files are incompatible with server"),
4154  errdetail("The database cluster was initialized with USE_FLOAT8_BYVAL"
4155  " but the server was compiled without USE_FLOAT8_BYVAL."),
4156  errhint("It looks like you need to recompile or initdb.")));
4157 #endif
4158 
4160 
4162  ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4163  errmsg_plural("WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte",
4164  "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes",
4166  wal_segment_size)));
4167 
4168  snprintf(wal_segsz_str, sizeof(wal_segsz_str), "%d", wal_segment_size);
4169  SetConfigOption("wal_segment_size", wal_segsz_str, PGC_INTERNAL,
4171 
4172  /* check and update variables dependent on wal_segment_size */
4174  ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4175  errmsg("\"min_wal_size\" must be at least twice \"wal_segment_size\"")));
4176 
4178  ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4179  errmsg("\"max_wal_size\" must be at least twice \"wal_segment_size\"")));
4180 
4182  (wal_segment_size / XLOG_BLCKSZ * UsableBytesInPage) -
4184 
4186 
4187  /* Make the initdb settings visible as GUC variables, too */
4188  SetConfigOption("data_checksums", DataChecksumsEnabled() ? "yes" : "no",
4190 }
#define PG_BINARY
Definition: c.h:1279
#define CATALOG_VERSION_NO
Definition: catversion.h:56
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1014
int BasicOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1071
void SetConfigOption(const char *name, const char *value, GucContext context, GucSource source)
Definition: guc.c:8373
@ PGC_S_DYNAMIC_DEFAULT
Definition: guc.h:111
@ PGC_INTERNAL
Definition: guc.h:70
#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:43
#define INDEX_MAX_KEYS
#define NAMEDATALEN
#define FLOATFORMAT_VALUE
Definition: pg_control.h:199
#define PG_CONTROL_VERSION
Definition: pg_control.h:25
#define EQ_CRC32C(c1, c2)
Definition: pg_crc32c.h:42
uint32 pg_control_version
Definition: pg_control.h:123
uint32 xlog_seg_size
Definition: pg_control.h:209
uint32 nameDataLen
Definition: pg_control.h:211
uint32 indexMaxKeys
Definition: pg_control.h:212
uint32 relseg_size
Definition: pg_control.h:206
uint32 catalog_version_no
Definition: pg_control.h:124
double floatFormat
Definition: pg_control.h:198
uint32 xlog_blcksz
Definition: pg_control.h:208
uint32 loblksize
Definition: pg_control.h:215
pg_crc32c crc
Definition: pg_control.h:230
uint32 toast_max_chunk_size
Definition: pg_control.h:214
@ WAIT_EVENT_CONTROL_FILE_READ
Definition: wait_event.h:166
#define UsableBytesInPage
Definition: xlog.c:589
bool DataChecksumsEnabled(void)
Definition: xlog.c:4226
static int UsableBytesInSegment
Definition: xlog.c:598
int min_wal_size_mb
Definition: xlog.c:116
#define IsValidWalSegSize(size)
Definition: xlog_internal.h:96
#define XLOG_CONTROL_FILE

References BasicOpenFile(), ControlFileData::blcksz, CalculateCheckpointSegments(), CATALOG_VERSION_NO, ControlFileData::catalog_version_no, close, COMP_CRC32C, ControlFile, ConvertToXSegs, ControlFileData::crc, crc, DataChecksumsEnabled(), EQ_CRC32C, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errcode_for_file_access(), errdetail(), errhint(), errmsg(), errmsg_plural(), ERROR, FATAL, fd(), FIN_CRC32C, ControlFileData::float8ByVal, ControlFileData::floatFormat, FLOATFORMAT_VALUE, INDEX_MAX_KEYS, ControlFileData::indexMaxKeys, INIT_CRC32C, IsValidWalSegSize, ControlFileData::loblksize, LOBLKSIZE, max_wal_size_mb, ControlFileData::maxAlign, min_wal_size_mb, ControlFileData::nameDataLen, NAMEDATALEN, offsetof, PANIC,