PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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/multixact.h"
#include "access/rewriteheap.h"
#include "access/subtrans.h"
#include "access/timeline.h"
#include "access/transam.h"
#include "access/tuptoaster.h"
#include "access/twophase.h"
#include "access/xact.h"
#include "access/xlog_internal.h"
#include "access/xloginsert.h"
#include "access/xlogreader.h"
#include "access/xlogutils.h"
#include "catalog/catversion.h"
#include "catalog/pg_control.h"
#include "catalog/pg_database.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "port/atomics.h"
#include "postmaster/bgwriter.h"
#include "postmaster/walwriter.h"
#include "postmaster/startup.h"
#include "replication/basebackup.h"
#include "replication/logical.h"
#include "replication/slot.h"
#include "replication/origin.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 "utils/backend_random.h"
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/pg_lsn.h"
#include "utils/ps_status.h"
#include "utils/relmapper.h"
#include "utils/snapmgr.h"
#include "utils/timestamp.h"
#include "pg_trace.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
 
struct  XLogPageReadPrivate
 

Macros

#define RECOVERY_COMMAND_FILE   "recovery.conf"
 
#define RECOVERY_COMMAND_DONE   "recovery.done"
 
#define PROMOTE_SIGNAL_FILE   "promote"
 
#define FALLBACK_PROMOTE_SIGNAL_FILE   "fallback_promote"
 
#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 UsableBytesInSegment   ((XLOG_SEG_SIZE / XLOG_BLCKSZ) * UsableBytesInPage - (SizeOfXLogLongPHD - SizeOfXLogShortPHD))
 
#define RecoveryRequiresIntParameter(param_name, currValue, minValue)
 

Typedefs

typedef struct XLogwrtRqst XLogwrtRqst
 
typedef struct XLogwrtResult XLogwrtResult
 
typedef union WALInsertLockPadded WALInsertLockPadded
 
typedef enum ExclusiveBackupState ExclusiveBackupState
 
typedef struct XLogCtlInsert XLogCtlInsert
 
typedef struct XLogCtlData XLogCtlData
 
typedef struct XLogPageReadPrivate XLogPageReadPrivate
 

Enumerations

enum  ExclusiveBackupState { EXCLUSIVE_BACKUP_NONE = 0, EXCLUSIVE_BACKUP_STARTING, EXCLUSIVE_BACKUP_IN_PROGRESS, EXCLUSIVE_BACKUP_STOPPING }
 
enum  XLogSource { XLOG_FROM_ANY = 0, XLOG_FROM_ARCHIVE, XLOG_FROM_PG_WAL, XLOG_FROM_STREAM }
 

Functions

static void readRecoveryCommandFile (void)
 
static void exitArchiveRecovery (TimeLineID endTLI, XLogRecPtr endOfLog)
 
static bool recoveryStopsBefore (XLogReaderState *record)
 
static bool recoveryStopsAfter (XLogReaderState *record)
 
static void recoveryPausesHere (void)
 
static bool recoveryApplyDelay (XLogReaderState *record)
 
static void SetLatestXTime (TimestampTz xtime)
 
static void SetCurrentChunkStartTime (TimestampTz xtime)
 
static void CheckRequiredParameterValues (void)
 
static void XLogReportParameters (void)
 
static void checkTimeLineSwitch (XLogRecPtr lsn, TimeLineID newTLI, TimeLineID prevTLI)
 
static void LocalSetXLogInsertAllowed (void)
 
static void CreateEndOfRecoveryRecord (void)
 
static void CheckPointGuts (XLogRecPtr checkPointRedo, int flags)
 
static void KeepLogSeg (XLogRecPtr recptr, XLogSegNo *logSegNo)
 
static XLogRecPtr XLogGetReplicationSlotMinimumLSN (void)
 
static void AdvanceXLInsertBuffer (XLogRecPtr upto, bool opportunistic)
 
static bool XLogCheckpointNeeded (XLogSegNo new_segno)
 
static void XLogWrite (XLogwrtRqst WriteRqst, bool flexible)
 
static bool InstallXLogFileSegment (XLogSegNo *segno, char *tmppath, bool find_free, XLogSegNo max_segno, bool use_lock)
 
static int XLogFileRead (XLogSegNo segno, int emode, TimeLineID tli, int source, bool notfoundOk)
 
static int XLogFileReadAnyTLI (XLogSegNo segno, int emode, int source)
 
static int XLogPageRead (XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char *readBuf, TimeLineID *readTLI)
 
static bool WaitForWALToBecomeAvailable (XLogRecPtr RecPtr, bool randAccess, bool fetching_ckpt, XLogRecPtr tliRecPtr)
 
static int emode_for_corrupt_record (int emode, XLogRecPtr RecPtr)
 
static void XLogFileClose (void)
 
static void PreallocXlogFiles (XLogRecPtr endptr)
 
static void RemoveOldXlogFiles (XLogSegNo segno, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
 
static void RemoveXlogFile (const char *segname, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
 
static void UpdateLastRemovedPtr (char *filename)
 
static void ValidateXLOGDirectoryStructure (void)
 
static void CleanupBackupHistory (void)
 
static void UpdateMinRecoveryPoint (XLogRecPtr lsn, bool force)
 
static XLogRecordReadRecord (XLogReaderState *xlogreader, XLogRecPtr RecPtr, int emode, bool fetching_ckpt)
 
static void CheckRecoveryConsistency (void)
 
static XLogRecordReadCheckpointRecord (XLogReaderState *xlogreader, XLogRecPtr RecPtr, int whichChkpti, bool report)
 
static bool rescanLatestTimeLine (void)
 
static void WriteControlFile (void)
 
static void ReadControlFile (void)
 
static char * str_time (pg_time_t tnow)
 
static bool CheckForStandbyTrigger (void)
 
static void xlog_outdesc (StringInfo buf, XLogReaderState *record)
 
static void pg_start_backup_callback (int code, Datum arg)
 
static void pg_stop_backup_callback (int code, Datum arg)
 
static bool read_backup_label (XLogRecPtr *checkPointLoc, bool *backupEndRequired, bool *backupFromStandby)
 
static bool read_tablespace_map (List **tablespaces)
 
static void rm_redo_error_callback (void *arg)
 
static int get_sync_bit (int method)
 
static void CopyXLogRecordToWAL (int write_len, bool isLogSwitch, XLogRecData *rdata, XLogRecPtr StartPos, XLogRecPtr EndPos)
 
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)
 
static XLogRecPtr XLogBytePosToRecPtr (uint64 bytepos)
 
static XLogRecPtr XLogBytePosToEndRecPtr (uint64 bytepos)
 
static uint64 XLogRecPtrToBytePos (XLogRecPtr ptr)
 
static void checkXLogConsistency (XLogReaderState *record)
 
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)
 
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 PriorRedoPtr)
 
void XLogSetAsyncXactLSN (XLogRecPtr asyncXactLSN)
 
void XLogSetReplicationSlotMinimumLSN (XLogRecPtr lsn)
 
void XLogFlush (XLogRecPtr record)
 
bool XLogBackgroundFlush (void)
 
bool XLogNeedsFlush (XLogRecPtr record)
 
int XLogFileInit (XLogSegNo logsegno, bool *use_existent, bool use_lock)
 
static void XLogFileCopy (XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno, int upto)
 
int XLogFileOpen (XLogSegNo segno)
 
void CheckXLogRemoved (XLogSegNo segno, TimeLineID tli)
 
XLogSegNo XLogGetLastRemovedSegno (void)
 
static void RemoveNonParentXlogFiles (XLogRecPtr switchpoint, TimeLineID newTLI)
 
void UpdateControlFile (void)
 
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)
 
Size XLOGShmemSize (void)
 
void XLOGShmemInit (void)
 
void BootStrapXLOG (void)
 
static bool getRecordTimestamp (XLogReaderState *record, TimestampTz *recordXtime)
 
bool RecoveryIsPaused (void)
 
void SetRecoveryPause (bool recoveryPause)
 
TimestampTz GetLatestXTime (void)
 
TimestampTz GetCurrentChunkReplayStartTime (void)
 
void GetXLogReceiptTime (TimestampTz *rtime, bool *fromStream)
 
void StartupXLOG (void)
 
bool RecoveryInProgress (void)
 
bool HotStandbyActive (void)
 
bool HotStandbyActiveInReplay (void)
 
bool XLogInsertAllowed (void)
 
void InitXLOGAccess (void)
 
XLogRecPtr GetRedoRecPtr (void)
 
void GetFullPageWriteInfo (XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p)
 
XLogRecPtr GetInsertRecPtr (void)
 
XLogRecPtr GetFlushRecPtr (void)
 
XLogRecPtr GetLastImportantRecPtr (void)
 
pg_time_t GetLastSegSwitchData (XLogRecPtr *lastSwitchLSN)
 
void GetNextXidAndEpoch (TransactionId *xid, uint32 *epoch)
 
void ShutdownXLOG (int code, Datum arg)
 
static void LogCheckpointStart (int flags, bool restartpoint)
 
static void LogCheckpointEnd (bool restartpoint)
 
static void UpdateCheckPointDistanceEstimate (uint64 nbytes)
 
void CreateCheckPoint (int flags)
 
static void RecoveryRestartPoint (const CheckPoint *checkPoint)
 
bool CreateRestartPoint (int flags)
 
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)
 
char * XLogFileNameP (TimeLineID tli, XLogSegNo segno)
 
XLogRecPtr do_pg_start_backup (const char *backupidstr, bool fast, TimeLineID *starttli_p, StringInfo labelfile, DIR *tblspcdir, List **tablespaces, StringInfo tblspcmapfile, bool infotbssize, bool needtblspcmapfile)
 
XLogRecPtr do_pg_stop_backup (char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 
void do_pg_abort_backup (void)
 
XLogRecPtr GetXLogReplayRecPtr (TimeLineID *replayTLI)
 
XLogRecPtr GetXLogInsertRecPtr (void)
 
XLogRecPtr GetXLogWriteRecPtr (void)
 
void GetOldestRestartPoint (XLogRecPtr *oldrecptr, TimeLineID *oldtli)
 
bool BackupInProgress (void)
 
void CancelBackup (void)
 
void RemovePromoteSignalFiles (void)
 
bool CheckPromoteSignal (void)
 
void WakeupRecovery (void)
 
void SetWalWriterSleeping (bool sleeping)
 
void XLogRequestWalReceiverReply (void)
 

Variables

uint32 bootstrap_data_checksum_version
 
int max_wal_size = 64
 
int min_wal_size = 5
 
int wal_keep_segments = 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
 
bool wal_compression = false
 
char * wal_consistency_checking_string = NULL
 
boolwal_consistency_checking = NULL
 
bool log_checkpoints = false
 
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 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
 
TimeLineID ThisTimeLineID = 0
 
bool InRecovery = false
 
HotStandbyState standbyState = STANDBY_DISABLED
 
static XLogRecPtr LastRec
 
static XLogRecPtr receivedUpto = 0
 
static TimeLineID receiveTLI = 0
 
static bool lastFullPageWrites
 
static bool LocalRecoveryInProgress = true
 
static bool LocalHotStandbyActive = false
 
static int LocalXLogInsertAllowed = -1
 
bool ArchiveRecoveryRequested = false
 
bool InArchiveRecovery = false
 
static bool restoredFromArchive = false
 
static char * replay_image_masked = NULL
 
static char * master_image_masked = NULL
 
char * recoveryRestoreCommand = NULL
 
static char * recoveryEndCommand = NULL
 
static char * archiveCleanupCommand = NULL
 
static RecoveryTargetType recoveryTarget = RECOVERY_TARGET_UNSET
 
static bool recoveryTargetInclusive = true
 
static RecoveryTargetAction recoveryTargetAction = RECOVERY_TARGET_ACTION_PAUSE
 
static TransactionId recoveryTargetXid
 
static TimestampTz recoveryTargetTime
 
static char * recoveryTargetName
 
static XLogRecPtr recoveryTargetLSN
 
static int recovery_min_apply_delay = 0
 
static TimestampTz recoveryDelayUntilTime
 
static bool StandbyModeRequested = false
 
static char * PrimaryConnInfo = NULL
 
static char * PrimarySlotName = NULL
 
static char * TriggerFile = NULL
 
bool StandbyMode = false
 
static bool fast_promote = false
 
static TransactionId recoveryStopXid
 
static TimestampTz recoveryStopTime
 
static XLogRecPtr recoveryStopLSN
 
static char recoveryStopName [MAXFNAMELEN]
 
static bool recoveryStopAfter
 
static TimeLineID recoveryTargetTLI
 
static bool recoveryTargetIsLatest = false
 
static ListexpectedTLEs
 
static TimeLineID curFileTLI
 
XLogRecPtr ProcLastRecPtr = InvalidXLogRecPtr
 
XLogRecPtr XactLastRecEnd = InvalidXLogRecPtr
 
XLogRecPtr XactLastCommitEnd = InvalidXLogRecPtr
 
static XLogRecPtr RedoRecPtr
 
static bool doPageWrites
 
static bool doRequestWalReceiverReply
 
static XLogRecPtr RedoStartLSN = InvalidXLogRecPtr
 
static XLogCtlDataXLogCtl = NULL
 
static WALInsertLockPaddedWALInsertLocks = NULL
 
static ControlFileDataControlFile = NULL
 
static XLogwrtResult LogwrtResult = {0, 0}
 
static const char * xlogSourceNames [] = {"any", "archive", "pg_wal", "stream"}
 
static int openLogFile = -1
 
static XLogSegNo openLogSegNo = 0
 
static uint32 openLogOff = 0
 
static int readFile = -1
 
static XLogSegNo readSegNo = 0
 
static uint32 readOff = 0
 
static uint32 readLen = 0
 
static XLogSource readSource = 0
 
static XLogSource currentSource = 0
 
static bool lastSourceFailed = false
 
static TimestampTz XLogReceiptTime = 0
 
static XLogSource XLogReceiptSource = 0
 
static XLogRecPtr ReadRecPtr
 
static XLogRecPtr EndRecPtr
 
static XLogRecPtr minRecoveryPoint
 
static TimeLineID minRecoveryPointTLI
 
static bool updateMinRecoveryPoint = true
 
bool reachedConsistency = false
 
static bool InRedo = false
 
static bool bgwriterLaunched = false
 
static int MyLockNo = 0
 
static bool holdingAllLocks = false
 

Macro Definition Documentation

#define FALLBACK_PROMOTE_SIGNAL_FILE   "fallback_promote"

Definition at line 85 of file xlog.c.

Referenced by CheckForStandbyTrigger(), CheckPromoteSignal(), and RemovePromoteSignalFiles().

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

Definition at line 715 of file xlog.c.

Referenced by CopyXLogRecordToWAL(), and CreateCheckPoint().

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

Definition at line 719 of file xlog.c.

Referenced by XLogWrite().

#define PROMOTE_SIGNAL_FILE   "promote"

Definition at line 84 of file xlog.c.

Referenced by CheckForStandbyTrigger(), CheckPromoteSignal(), and RemovePromoteSignalFiles().

#define RECOVERY_COMMAND_DONE   "recovery.done"

Definition at line 83 of file xlog.c.

Referenced by exitArchiveRecovery().

#define RECOVERY_COMMAND_FILE   "recovery.conf"

Definition at line 82 of file xlog.c.

Referenced by exitArchiveRecovery(), and readRecoveryCommandFile().

#define RecoveryRequiresIntParameter (   param_name,
  currValue,
  minValue 
)
Value:
do { \
if ((currValue) < (minValue)) \
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), \
errmsg("hot standby is not possible because " \
"%s = %d is a lower setting than on the master server " \
"(its value was %d)", \
param_name, \
currValue, \
minValue))); \
} while(0)
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797

Definition at line 6116 of file xlog.c.

Referenced by CheckRequiredParameterValues().

#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)

Definition at line 732 of file xlog.c.

Referenced by XLogBytePosToEndRecPtr(), XLogBytePosToRecPtr(), and XLogRecPtrToBytePos().

#define UsableBytesInSegment   ((XLOG_SEG_SIZE / XLOG_BLCKSZ) * UsableBytesInPage - (SizeOfXLogLongPHD - SizeOfXLogShortPHD))

Definition at line 733 of file xlog.c.

Referenced by XLogBytePosToEndRecPtr(), XLogBytePosToRecPtr(), and XLogRecPtrToBytePos().

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

Definition at line 726 of file xlog.c.

Referenced by AdvanceXLInsertBuffer(), GetXLogBuffer(), StartupXLOG(), and XLogWrite().

Typedef Documentation

Enumeration Type Documentation

Enumerator
EXCLUSIVE_BACKUP_NONE 
EXCLUSIVE_BACKUP_STARTING 
EXCLUSIVE_BACKUP_IN_PROGRESS 
EXCLUSIVE_BACKUP_STOPPING 

Definition at line 498 of file xlog.c.

enum XLogSource
Enumerator
XLOG_FROM_ANY 
XLOG_FROM_ARCHIVE 
XLOG_FROM_PG_WAL 
XLOG_FROM_STREAM 

Definition at line 745 of file xlog.c.

746 {
747  XLOG_FROM_ANY = 0, /* request to read WAL from any source */
748  XLOG_FROM_ARCHIVE, /* restored using restore_command */
749  XLOG_FROM_PG_WAL, /* existing file in pg_wal */
750  XLOG_FROM_STREAM /* streamed from master */
751 } XLogSource;
XLogSource
Definition: xlog.c:745

Function Documentation

static void AdvanceXLInsertBuffer ( XLogRecPtr  upto,
bool  opportunistic 
)
static

Definition at line 2032 of file xlog.c.

References Assert, DEBUG1, elog, XLogwrtRqst::Flush, XLogCtlInsert::forcePageWrites, XLogCtlData::info_lck, XLogCtlData::InitializedUpTo, Insert(), XLogCtlData::Insert, InvalidXLogRecPtr, XLogCtlData::LogwrtResult, XLogCtlData::LogwrtRqst, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MemSet, XLogCtlData::pages, pg_write_barrier, SpinLockAcquire, SpinLockRelease, ControlFileData::system_identifier, ThisTimeLineID, WaitXLogInsertionsToFinish(), XLogwrtRqst::Write, XLogwrtResult::Write, XLogCtlData::xlblocks, XLOG_PAGE_MAGIC, XLogRecPtrToBufIdx, XLogSegSize, XLogWrite(), XLP_BKP_REMOVABLE, XLogPageHeaderData::xlp_info, XLP_LONG_HEADER, XLogPageHeaderData::xlp_magic, XLogPageHeaderData::xlp_pageaddr, XLogLongPageHeaderData::xlp_seg_size, XLogLongPageHeaderData::xlp_sysid, XLogPageHeaderData::xlp_tli, and XLogLongPageHeaderData::xlp_xlog_blcksz.

Referenced by CopyXLogRecordToWAL(), GetXLogBuffer(), and XLogBackgroundFlush().

2033 {
2035  int nextidx;
2036  XLogRecPtr OldPageRqstPtr;
2037  XLogwrtRqst WriteRqst;
2038  XLogRecPtr NewPageEndPtr = InvalidXLogRecPtr;
2039  XLogRecPtr NewPageBeginPtr;
2040  XLogPageHeader NewPage;
2041  int npages = 0;
2042 
2043  LWLockAcquire(WALBufMappingLock, LW_EXCLUSIVE);
2044 
2045  /*
2046  * Now that we have the lock, check if someone initialized the page
2047  * already.
2048  */
2049  while (upto >= XLogCtl->InitializedUpTo || opportunistic)
2050  {
2052 
2053  /*
2054  * Get ending-offset of the buffer page we need to replace (this may
2055  * be zero if the buffer hasn't been used yet). Fall through if it's
2056  * already written out.
2057  */
2058  OldPageRqstPtr = XLogCtl->xlblocks[nextidx];
2059  if (LogwrtResult.Write < OldPageRqstPtr)
2060  {
2061  /*
2062  * Nope, got work to do. If we just want to pre-initialize as much
2063  * as we can without flushing, give up now.
2064  */
2065  if (opportunistic)
2066  break;
2067 
2068  /* Before waiting, get info_lck and update LogwrtResult */
2070  if (XLogCtl->LogwrtRqst.Write < OldPageRqstPtr)
2071  XLogCtl->LogwrtRqst.Write = OldPageRqstPtr;
2074 
2075  /*
2076  * Now that we have an up-to-date LogwrtResult value, see if we
2077  * still need to write it or if someone else already did.
2078  */
2079  if (LogwrtResult.Write < OldPageRqstPtr)
2080  {
2081  /*
2082  * Must acquire write lock. Release WALBufMappingLock first,
2083  * to make sure that all insertions that we need to wait for
2084  * can finish (up to this same position). Otherwise we risk
2085  * deadlock.
2086  */
2087  LWLockRelease(WALBufMappingLock);
2088 
2089  WaitXLogInsertionsToFinish(OldPageRqstPtr);
2090 
2091  LWLockAcquire(WALWriteLock, LW_EXCLUSIVE);
2092 
2094  if (LogwrtResult.Write >= OldPageRqstPtr)
2095  {
2096  /* OK, someone wrote it already */
2097  LWLockRelease(WALWriteLock);
2098  }
2099  else
2100  {
2101  /* Have to write it ourselves */
2102  TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_START();
2103  WriteRqst.Write = OldPageRqstPtr;
2104  WriteRqst.Flush = 0;
2105  XLogWrite(WriteRqst, false);
2106  LWLockRelease(WALWriteLock);
2107  TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_DONE();
2108  }
2109  /* Re-acquire WALBufMappingLock and retry */
2110  LWLockAcquire(WALBufMappingLock, LW_EXCLUSIVE);
2111  continue;
2112  }
2113  }
2114 
2115  /*
2116  * Now the next buffer slot is free and we can set it up to be the
2117  * next output page.
2118  */
2119  NewPageBeginPtr = XLogCtl->InitializedUpTo;
2120  NewPageEndPtr = NewPageBeginPtr + XLOG_BLCKSZ;
2121 
2122  Assert(XLogRecPtrToBufIdx(NewPageBeginPtr) == nextidx);
2123 
2124  NewPage = (XLogPageHeader) (XLogCtl->pages + nextidx * (Size) XLOG_BLCKSZ);
2125 
2126  /*
2127  * Be sure to re-zero the buffer so that bytes beyond what we've
2128  * written will look like zeroes and not valid XLOG records...
2129  */
2130  MemSet((char *) NewPage, 0, XLOG_BLCKSZ);
2131 
2132  /*
2133  * Fill the new page's header
2134  */
2135  NewPage->xlp_magic = XLOG_PAGE_MAGIC;
2136 
2137  /* NewPage->xlp_info = 0; */ /* done by memset */
2138  NewPage->xlp_tli = ThisTimeLineID;
2139  NewPage->xlp_pageaddr = NewPageBeginPtr;
2140 
2141  /* NewPage->xlp_rem_len = 0; */ /* done by memset */
2142 
2143  /*
2144  * If online backup is not in progress, mark the header to indicate
2145  * that* WAL records beginning in this page have removable backup
2146  * blocks. This allows the WAL archiver to know whether it is safe to
2147  * compress archived WAL data by transforming full-block records into
2148  * the non-full-block format. It is sufficient to record this at the
2149  * page level because we force a page switch (in fact a segment
2150  * switch) when starting a backup, so the flag will be off before any
2151  * records can be written during the backup. At the end of a backup,
2152  * the last page will be marked as all unsafe when perhaps only part
2153  * is unsafe, but at worst the archiver would miss the opportunity to
2154  * compress a few records.
2155  */
2156  if (!Insert->forcePageWrites)
2157  NewPage->xlp_info |= XLP_BKP_REMOVABLE;
2158 
2159  /*
2160  * If first page of an XLOG segment file, make it a long header.
2161  */
2162  if ((NewPage->xlp_pageaddr % XLogSegSize) == 0)
2163  {
2164  XLogLongPageHeader NewLongPage = (XLogLongPageHeader) NewPage;
2165 
2166  NewLongPage->xlp_sysid = ControlFile->system_identifier;
2167  NewLongPage->xlp_seg_size = XLogSegSize;
2168  NewLongPage->xlp_xlog_blcksz = XLOG_BLCKSZ;
2169  NewPage->xlp_info |= XLP_LONG_HEADER;
2170  }
2171 
2172  /*
2173  * Make sure the initialization of the page becomes visible to others
2174  * before the xlblocks update. GetXLogBuffer() reads xlblocks without
2175  * holding a lock.
2176  */
2177  pg_write_barrier();
2178 
2179  *((volatile XLogRecPtr *) &XLogCtl->xlblocks[nextidx]) = NewPageEndPtr;
2180 
2181  XLogCtl->InitializedUpTo = NewPageEndPtr;
2182 
2183  npages++;
2184  }
2185  LWLockRelease(WALBufMappingLock);
2186 
2187 #ifdef WAL_DEBUG
2188  if (XLOG_DEBUG && npages > 0)
2189  {
2190  elog(DEBUG1, "initialized %d pages, up to %X/%X",
2191  npages, (uint32) (NewPageEndPtr >> 32), (uint32) NewPageEndPtr);
2192  }
2193 #endif
2194 }
#define XLogSegSize
Definition: xlog_internal.h:92
XLogRecPtr InitializedUpTo
Definition: xlog.c:607
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define DEBUG1
Definition: elog.h:25
XLogRecPtr * xlblocks
Definition: xlog.c:615
static XLogwrtResult LogwrtResult
Definition: xlog.c:739
slock_t info_lck
Definition: xlog.c:698
#define MemSet(start, val, len)
Definition: c.h:857
static XLogRecPtr WaitXLogInsertionsToFinish(XLogRecPtr upto)
Definition: xlog.c:1695
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:57
XLogCtlInsert Insert
Definition: xlog.c:570
XLogRecPtr Flush
Definition: xlog.c:418
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:74
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define XLP_BKP_REMOVABLE
Definition: xlog_internal.h:81
bool forcePageWrites
Definition: xlog.c:543
uint64 system_identifier
Definition: pg_control.h:109
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
XLogwrtResult LogwrtResult
Definition: xlog.c:595
unsigned int uint32
Definition: c.h:268
static void Insert(File file)
Definition: fd.c:1007
TimeLineID xlp_tli
Definition: xlog_internal.h:40
static void XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
Definition: xlog.c:2328
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
#define SpinLockRelease(lock)
Definition: spin.h:64
XLogRecPtr Write
Definition: xlog.c:417
static ControlFileData * ControlFile
Definition: xlog.c:709
XLogwrtRqst LogwrtRqst
Definition: xlog.c:573
TimeLineID ThisTimeLineID
Definition: xlog.c:179
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:675
#define XLP_LONG_HEADER
Definition: xlog_internal.h:79
size_t Size
Definition: c.h:356
static XLogCtlData * XLogCtl
Definition: xlog.c:701
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
#define XLogRecPtrToBufIdx(recptr)
Definition: xlog.c:726
XLogRecPtr Write
Definition: xlog.c:423
#define pg_write_barrier()
Definition: atomics.h:161
#define elog
Definition: elog.h:219
char * pages
Definition: xlog.c:614
void assign_checkpoint_completion_target ( double  newval,
void *  extra 
)

Definition at line 2231 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

2232 {
2235 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2201
#define newval
double CheckPointCompletionTarget
Definition: checkpointer.c:147
void assign_max_wal_size ( int  newval,
void *  extra 
)

Definition at line 2224 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size, and newval.

2225 {
2226  max_wal_size = newval;
2228 }
int max_wal_size
Definition: xlog.c:89
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2201
#define newval
void assign_xlog_sync_method ( int  new_sync_method,
void *  extra 
)

Definition at line 10016 of file xlog.c.

References ereport, errcode_for_file_access(), errmsg(), get_sync_bit(), openLogFile, openLogSegNo, PANIC, pg_fsync(), pgstat_report_wait_end(), pgstat_report_wait_start(), sync_method, ThisTimeLineID, WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN, XLogFileClose(), and XLogFileNameP().

10017 {
10018  if (sync_method != new_sync_method)
10019  {
10020  /*
10021  * To ensure that no blocks escape unsynced, force an fsync on the
10022  * currently open log segment (if any). Also, if the open flag is
10023  * changing, close the log file so it will be reopened (with new flag
10024  * bit) at next use.
10025  */
10026  if (openLogFile >= 0)
10027  {
10029  if (pg_fsync(openLogFile) != 0)
10030  ereport(PANIC,
10032  errmsg("could not fsync log segment %s: %m",
10035  if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
10036  XLogFileClose();
10037  }
10038  }
10039 }
static int get_sync_bit(int method)
Definition: xlog.c:9960
#define PANIC
Definition: elog.h:53
static XLogSegNo openLogSegNo
Definition: xlog.c:763
static void XLogFileClose(void)
Definition: xlog.c:3696
char * XLogFileNameP(TimeLineID tli, XLogSegNo segno)
Definition: xlog.c:10092
int errcode_for_file_access(void)
Definition: elog.c:598
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1203
#define ereport(elevel, rest)
Definition: elog.h:122
static int openLogFile
Definition: xlog.c:762
TimeLineID ThisTimeLineID
Definition: xlog.c:179
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1179
int sync_method
Definition: xlog.c:103
int errmsg(const char *fmt,...)
Definition: elog.c:797
int pg_fsync(int fd)
Definition: fd.c:333
bool BackupInProgress ( void  )

Definition at line 11293 of file xlog.c.

References BACKUP_LABEL_FILE.

Referenced by pg_is_in_backup(), and PostmasterStateMachine().

11294 {
11295  struct stat stat_buf;
11296 
11297  return (stat(BACKUP_LABEL_FILE, &stat_buf) == 0);
11298 }
struct stat stat_buf
Definition: pg_standby.c:101
#define BACKUP_LABEL_FILE
Definition: xlog.h:302
void BootStrapXLOG ( void  )

Definition at line 4940 of file xlog.c.

References Assert, bootstrap_data_checksum_version, BootStrapCLOG(), BootStrapCommitTs(), BootStrapMultiXact(), BootStrapSUBTRANS(), ControlFileData::checkPoint, ControlFileData::checkPointCopy, close, COMP_CRC32C, ControlFileData::data_checksum_version, DB_SHUTDOWNED, ereport, errcode(), errcode_for_file_access(), errmsg(), FIN_CRC32C, FirstBootstrapObjectId, FirstMultiXactId, FirstNormalTransactionId, CheckPoint::fullPageWrites, fullPageWrites, gettimeofday(), INIT_CRC32C, InvalidTransactionId, max_locks_per_xact, ControlFileData::max_locks_per_xact, max_prepared_xacts, ControlFileData::max_prepared_xacts, max_worker_processes, ControlFileData::max_worker_processes, MaxConnections, ControlFileData::MaxConnections, MOCK_AUTH_NONCE_LEN, ControlFileData::mock_authentication_nonce, MultiXactSetNextMXact(), CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, VariableCacheData::nextOid, CheckPoint::nextXid, VariableCacheData::nextXid, CheckPoint::nextXidEpoch, NULL, offsetof, VariableCacheData::oidCount, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, openLogFile, palloc(), PANIC, pfree(), pg_backend_random(), pg_fsync(), pgstat_report_wait_end(), pgstat_report_wait_start(), CheckPoint::PrevTimeLineID, CheckPoint::redo, SetCommitTsLimit(), SetMultiXactIdLimit(), SetTransactionIdLimit(), ShmemVariableCache, SizeOfXLogLongPHD, SizeOfXLogRecord, SizeOfXLogRecordDataHeaderShort, ControlFileData::state, ControlFileData::system_identifier, TemplateDbOid, CheckPoint::ThisTimeLineID, ThisTimeLineID, CheckPoint::time, ControlFileData::time, track_commit_timestamp, ControlFileData::track_commit_timestamp, TYPEALIGN, ControlFileData::unloggedLSN, WAIT_EVENT_WAL_BOOTSTRAP_SYNC, WAIT_EVENT_WAL_BOOTSTRAP_WRITE, wal_level, ControlFileData::wal_level, wal_log_hints, ControlFileData::wal_log_hints, write, WriteControlFile(), XLogRecord::xl_crc, XLogRecord::xl_info, XLogRecord::xl_prev, XLogRecord::xl_rmid, XLogRecord::xl_tot_len, XLogRecord::xl_xid, XLOG_CHECKPOINT_SHUTDOWN, XLOG_PAGE_MAGIC, XLogFileInit(), XLogSegSize, 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 AuxiliaryProcessMain().

4941 {
4942  CheckPoint checkPoint;
4943  char *buffer;
4944  XLogPageHeader page;
4945  XLogLongPageHeader longpage;
4946  XLogRecord *record;
4947  char *recptr;
4948  bool use_existent;
4949  uint64 sysidentifier;
4950  char mock_auth_nonce[MOCK_AUTH_NONCE_LEN];
4951  struct timeval tv;
4952  pg_crc32c crc;
4953 
4954  /*
4955  * Select a hopefully-unique system identifier code for this installation.
4956  * We use the result of gettimeofday(), including the fractional seconds
4957  * field, as being about as unique as we can easily get. (Think not to
4958  * use random(), since it hasn't been seeded and there's no portable way
4959  * to seed it other than the system clock value...) The upper half of the
4960  * uint64 value is just the tv_sec part, while the lower half contains the
4961  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
4962  * PID for a little extra uniqueness. A person knowing this encoding can
4963  * determine the initialization time of the installation, which could
4964  * perhaps be useful sometimes.
4965  */
4966  gettimeofday(&tv, NULL);
4967  sysidentifier = ((uint64) tv.tv_sec) << 32;
4968  sysidentifier |= ((uint64) tv.tv_usec) << 12;
4969  sysidentifier |= getpid() & 0xFFF;
4970 
4971  /*
4972  * Generate a random nonce. This is used for authentication requests
4973  * that will fail because the user does not exist. The nonce is used to
4974  * create a genuine-looking password challenge for the non-existent user,
4975  * in lieu of an actual stored password.
4976  */
4977  if (!pg_backend_random(mock_auth_nonce, MOCK_AUTH_NONCE_LEN))
4978  ereport(PANIC,
4979  (errcode(ERRCODE_INTERNAL_ERROR),
4980  errmsg("could not generation secret authorization token")));
4981 
4982  /* First timeline ID is always 1 */
4983  ThisTimeLineID = 1;
4984 
4985  /* page buffer must be aligned suitably for O_DIRECT */
4986  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
4987  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
4988  memset(page, 0, XLOG_BLCKSZ);
4989 
4990  /*
4991  * Set up information for the initial checkpoint record
4992  *
4993  * The initial checkpoint record is written to the beginning of the WAL
4994  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
4995  * used, so that we can use 0/0 to mean "before any valid WAL segment".
4996  */
4997  checkPoint.redo = XLogSegSize + SizeOfXLogLongPHD;
4998  checkPoint.ThisTimeLineID = ThisTimeLineID;
4999  checkPoint.PrevTimeLineID = ThisTimeLineID;
5000  checkPoint.fullPageWrites = fullPageWrites;
5001  checkPoint.nextXidEpoch = 0;
5002  checkPoint.nextXid = FirstNormalTransactionId;
5003  checkPoint.nextOid = FirstBootstrapObjectId;
5004  checkPoint.nextMulti = FirstMultiXactId;
5005  checkPoint.nextMultiOffset = 0;
5006  checkPoint.oldestXid = FirstNormalTransactionId;
5007  checkPoint.oldestXidDB = TemplateDbOid;
5008  checkPoint.oldestMulti = FirstMultiXactId;
5009  checkPoint.oldestMultiDB = TemplateDbOid;
5012  checkPoint.time = (pg_time_t) time(NULL);
5014 
5015  ShmemVariableCache->nextXid = checkPoint.nextXid;
5016  ShmemVariableCache->nextOid = checkPoint.nextOid;
5018  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5019  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5020  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5022 
5023  /* Set up the XLOG page header */
5024  page->xlp_magic = XLOG_PAGE_MAGIC;
5025  page->xlp_info = XLP_LONG_HEADER;
5026  page->xlp_tli = ThisTimeLineID;
5027  page->xlp_pageaddr = XLogSegSize;
5028  longpage = (XLogLongPageHeader) page;
5029  longpage->xlp_sysid = sysidentifier;
5030  longpage->xlp_seg_size = XLogSegSize;
5031  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5032 
5033  /* Insert the initial checkpoint record */
5034  recptr = ((char *) page + SizeOfXLogLongPHD);
5035  record = (XLogRecord *) recptr;
5036  record->xl_prev = 0;
5037  record->xl_xid = InvalidTransactionId;
5038  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5040  record->xl_rmid = RM_XLOG_ID;
5041  recptr += SizeOfXLogRecord;
5042  /* fill the XLogRecordDataHeaderShort struct */
5043  *(recptr++) = XLR_BLOCK_ID_DATA_SHORT;
5044  *(recptr++) = sizeof(checkPoint);
5045  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5046  recptr += sizeof(checkPoint);
5047  Assert(recptr - (char *) record == record->xl_tot_len);
5048 
5049  INIT_CRC32C(crc);
5050  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5051  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5052  FIN_CRC32C(crc);
5053  record->xl_crc = crc;
5054 
5055  /* Create first XLOG segment file */
5056  use_existent = false;
5057  openLogFile = XLogFileInit(1, &use_existent, false);
5058 
5059  /* Write the first page with the initial record */
5060  errno = 0;
5062  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5063  {
5064  /* if write didn't set errno, assume problem is no disk space */
5065  if (errno == 0)
5066  errno = ENOSPC;
5067  ereport(PANIC,
5069  errmsg("could not write bootstrap transaction log file: %m")));
5070  }
5072 
5074  if (pg_fsync(openLogFile) != 0)
5075  ereport(PANIC,
5077  errmsg("could not fsync bootstrap transaction log file: %m")));
5079 
5080  if (close(openLogFile))
5081  ereport(PANIC,
5083  errmsg("could not close bootstrap transaction log file: %m")));
5084 
5085  openLogFile = -1;
5086 
5087  /* Now create pg_control */
5088 
5089  memset(ControlFile, 0, sizeof(ControlFileData));
5090  /* Initialize pg_control status fields */
5091  ControlFile->system_identifier = sysidentifier;
5092  memcpy(ControlFile->mock_authentication_nonce, mock_auth_nonce, MOCK_AUTH_NONCE_LEN);
5094  ControlFile->time = checkPoint.time;
5095  ControlFile->checkPoint = checkPoint.redo;
5096  ControlFile->checkPointCopy = checkPoint;
5097  ControlFile->unloggedLSN = 1;
5098 
5099  /* Set important parameter values for use when replaying WAL */
5108 
5109  /* some additional ControlFile fields are set in WriteControlFile() */
5110 
5111  WriteControlFile();
5112 
5113  /* Bootstrap the commit log, too */
5114  BootStrapCLOG();
5118 
5119  pfree(buffer);
5120 }
static void WriteControlFile(void)
Definition: xlog.c:4371
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
#define XLogSegSize
Definition: xlog_internal.h:92
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
int max_locks_per_xact
Definition: pg_control.h:185
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:105
int max_prepared_xacts
Definition: pg_control.h:184
int64 pg_time_t
Definition: pgtime.h:23
pg_time_t time
Definition: pg_control.h:131
void SetCommitTsLimit(TransactionId oldestXact, TransactionId newestXact)
Definition: commit_ts.c:837
uint32 oidCount
Definition: transam.h:112
#define write(a, b, c)
Definition: win32.h:19
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:200
int max_worker_processes
Definition: pg_control.h:183
uint32 pg_crc32c
Definition: pg_crc32c.h:38
TransactionId oldestActiveXid
Definition: pg_control.h:62
int wal_level
Definition: xlog.c:104
int XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
Definition: xlog.c:3144
void BootStrapMultiXact(void)
Definition: multixact.c:1866
MultiXactId oldestMulti
Definition: pg_control.h:48
TimeLineID PrevTimeLineID
Definition: pg_control.h:38
int errcode(int sqlerrcode)
Definition: elog.c:575
RmgrId xl_rmid
Definition: xlogrecord.h:47
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:57
CheckPoint checkPointCopy
Definition: pg_control.h:135
TransactionId oldestXid
Definition: pg_control.h:46
TransactionId nextXid
Definition: pg_control.h:42
pg_time_t time
Definition: pg_control.h:50
#define PANIC
Definition: elog.h:53
uint32 bootstrap_data_checksum_version
Definition: bootstrap.c:48
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:74
#define MOCK_AUTH_NONCE_LEN
Definition: pg_control.h:23
bool fullPageWrites
Definition: xlog.c:97
void BootStrapSUBTRANS(void)
Definition: subtrans.c:199
MultiXactOffset nextMultiOffset
Definition: pg_control.h:45
TransactionId oldestCommitTsXid
Definition: pg_control.h:51
void pfree(void *pointer)
Definition: mcxt.c:950
#define FirstNormalTransactionId
Definition: transam.h:34
int max_prepared_xacts
Definition: twophase.c:98
uint64 system_identifier
Definition: pg_control.h:109
uint32 xl_tot_len
Definition: xlogrecord.h:43
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
TransactionId nextXid
Definition: transam.h:117
uint32 nextXidEpoch
Definition: pg_control.h:41
bool track_commit_timestamp
Definition: commit_ts.c:103
#define TemplateDbOid
Definition: pg_database.h:80
uint32 data_checksum_version
Definition: pg_control.h:225
bool pg_backend_random(char *dst, int len)
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:66
XLogRecPtr unloggedLSN
Definition: pg_control.h:137
int errcode_for_file_access(void)
Definition: elog.c:598
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define InvalidTransactionId
Definition: transam.h:31
#define FirstBootstrapObjectId
Definition: transam.h:93
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1203
#define FirstMultiXactId
Definition: multixact.h:24
#define ereport(elevel, rest)
Definition: elog.h:122
int max_locks_per_xact
Definition: lock.c:54
TimeLineID xlp_tli
Definition: xlog_internal.h:40
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
#define SizeOfXLogRecord
Definition: xlogrecord.h:55
TransactionId newestCommitTsXid
Definition: pg_control.h:53
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition: pg_control.h:232
int MaxConnections
Definition: globals.c:123
Oid oldestMultiDB
Definition: pg_control.h:49
static int openLogFile
Definition: xlog.c:762
static ControlFileData * ControlFile
Definition: xlog.c:709
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
Definition: multixact.c:2194
TimeLineID ThisTimeLineID
Definition: xlog.c:179
Oid nextOid
Definition: pg_control.h:43
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:581
bool fullPageWrites
Definition: pg_control.h:40
bool wal_log_hints
Definition: xlog.c:98
void BootStrapCLOG(void)
Definition: clog.c:463
#define NULL
Definition: c.h:229
bool track_commit_timestamp
Definition: pg_control.h:186
#define Assert(condition)
Definition: c.h:675
#define XLP_LONG_HEADER
Definition: xlog_internal.h:79
Oid oldestXidDB
Definition: pg_control.h:47
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1179
void SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid)
Definition: varsup.c:267
uint8 xl_info
Definition: xlogrecord.h:46
MultiXactId nextMulti
Definition: pg_control.h:44
pg_crc32c xl_crc
Definition: xlogrecord.h:49
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:223
TransactionId xl_xid
Definition: xlogrecord.h:44
TimeLineID ThisTimeLineID
Definition: pg_control.h:37
void * palloc(Size size)
Definition: mcxt.c:849
int errmsg(const char *fmt,...)
Definition: elog.c:797
int max_worker_processes
Definition: globals.c:124
int pg_fsync(int fd)
Definition: fd.c:333
#define close(a)
Definition: win32.h:17
void BootStrapCommitTs(void)
Definition: commit_ts.c:523
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:73
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:78
XLogRecPtr checkPoint
Definition: pg_control.h:132
XLogRecPtr redo
Definition: pg_control.h:35
#define offsetof(type, field)
Definition: c.h:555
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset)
Definition: multixact.c:2160
static void CalculateCheckpointSegments ( void  )
static

Definition at line 2201 of file xlog.c.

References CheckPointCompletionTarget, CheckPointSegments, and max_wal_size.

Referenced by assign_checkpoint_completion_target(), and assign_max_wal_size().

2202 {
2203  double target;
2204 
2205  /*-------
2206  * Calculate the distance at which to trigger a checkpoint, to avoid
2207  * exceeding max_wal_size. This is based on two assumptions:
2208  *
2209  * a) we keep WAL for two checkpoint cycles, back to the "prev" checkpoint.
2210  * b) during checkpoint, we consume checkpoint_completion_target *
2211  * number of segments consumed between checkpoints.
2212  *-------
2213  */
2214  target = (double) max_wal_size / (2.0 + CheckPointCompletionTarget);
2215 
2216  /* round down */
2217  CheckPointSegments = (int) target;
2218 
2219  if (CheckPointSegments < 1)
2220  CheckPointSegments = 1;
2221 }
int max_wal_size
Definition: xlog.c:89
int CheckPointSegments
Definition: xlog.c:124
double CheckPointCompletionTarget
Definition: checkpointer.c:147
void CancelBackup ( void  )

Definition at line 11313 of file xlog.c.

References BACKUP_LABEL_FILE, BACKUP_LABEL_OLD, DEBUG1, durable_rename(), ereport, errcode_for_file_access(), errdetail(), errmsg(), LOG, TABLESPACE_MAP, TABLESPACE_MAP_OLD, unlink(), and WARNING.

Referenced by PostmasterStateMachine().

11314 {
11315  struct stat stat_buf;
11316 
11317  /* if the backup_label file is not there, return */
11318  if (stat(BACKUP_LABEL_FILE, &stat_buf) < 0)
11319  return;
11320 
11321  /* remove leftover file from previously canceled backup if it exists */
11323 
11325  {
11326  ereport(WARNING,
11328  errmsg("online backup mode was not canceled"),
11329  errdetail("File \"%s\" could not be renamed to \"%s\": %m.",
11331  return;
11332  }
11333 
11334  /* if the tablespace_map file is not there, return */
11335  if (stat(TABLESPACE_MAP, &stat_buf) < 0)
11336  {
11337  ereport(LOG,
11338  (errmsg("online backup mode canceled"),
11339  errdetail("File \"%s\" was renamed to \"%s\".",
11341  return;
11342  }
11343 
11344  /* remove leftover file from previously canceled backup if it exists */
11346 
11348  {
11349  ereport(LOG,
11350  (errmsg("online backup mode canceled"),
11351  errdetail("Files \"%s\" and \"%s\" were renamed to "
11352  "\"%s\" and \"%s\", respectively.",
11355  }
11356  else
11357  {
11358  ereport(WARNING,
11360  errmsg("online backup mode canceled"),
11361  errdetail("File \"%s\" was renamed to \"%s\", but "
11362  "file \"%s\" could not be renamed to \"%s\": %m.",
11365  }
11366 }
#define DEBUG1
Definition: elog.h:25
#define LOG
Definition: elog.h:26
#define BACKUP_LABEL_OLD
Definition: xlog.h:303
#define TABLESPACE_MAP
Definition: xlog.h:305
struct stat stat_buf
Definition: pg_standby.c:101
int errdetail(const char *fmt,...)
Definition: elog.c:873
int errcode_for_file_access(void)
Definition: elog.c:598
int unlink(const char *filename)
#define ereport(elevel, rest)
Definition: elog.h:122
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:593
#define WARNING
Definition: elog.h:40
#define TABLESPACE_MAP_OLD
Definition: xlog.h:306
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define BACKUP_LABEL_FILE
Definition: xlog.h:302
bool check_wal_buffers ( int *  newval,
void **  extra,
GucSource  source 
)

Definition at line 4760 of file xlog.c.

References XLOGbuffers, and XLOGChooseNumBuffers().

4761 {
4762  /*
4763  * -1 indicates a request for auto-tune.
4764  */
4765  if (*newval == -1)
4766  {
4767  /*
4768  * If we haven't yet changed the boot_val default of -1, just let it
4769  * be. We'll fix it when XLOGShmemSize is called.
4770  */
4771  if (XLOGbuffers == -1)
4772  return true;
4773 
4774  /* Otherwise, substitute the auto-tune value */
4776  }
4777 
4778  /*
4779  * We clamp manually-set values to at least 4 blocks. Prior to PostgreSQL
4780  * 9.1, a minimum of 4 was enforced by guc.c, but since that is no longer
4781  * the case, we just silently treat such values as a request for the
4782  * minimum. (We could throw an error instead, but that doesn't seem very
4783  * helpful.)
4784  */
4785  if (*newval < 4)
4786  *newval = 4;
4787 
4788  return true;
4789 }
static int XLOGChooseNumBuffers(void)
Definition: xlog.c:4744
#define newval
int XLOGbuffers
Definition: xlog.c:92
static bool CheckForStandbyTrigger ( void  )
static

Definition at line 11943 of file xlog.c.

References ereport, errcode_for_file_access(), errmsg(), ERROR, FALLBACK_PROMOTE_SIGNAL_FILE, fast_promote, IsPromoteTriggered(), LOG, NULL, PROMOTE_SIGNAL_FILE, ResetPromoteTriggered(), TriggerFile, and unlink().

Referenced by ReadRecord(), recoveryApplyDelay(), and WaitForWALToBecomeAvailable().

11944 {
11945  struct stat stat_buf;
11946  static bool triggered = false;
11947 
11948  if (triggered)
11949  return true;
11950 
11951  if (IsPromoteTriggered())
11952  {
11953  /*
11954  * In 9.1 and 9.2 the postmaster unlinked the promote file inside the
11955  * signal handler. It now leaves the file in place and lets the
11956  * Startup process do the unlink. This allows Startup to know whether
11957  * it should create a full checkpoint before starting up (fallback
11958  * mode). Fast promotion takes precedence.
11959  */
11960  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
11961  {
11964  fast_promote = true;
11965  }
11966  else if (stat(FALLBACK_PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
11967  {
11969  fast_promote = false;
11970  }
11971 
11972  ereport(LOG, (errmsg("received promote request")));
11973 
11975  triggered = true;
11976  return true;
11977  }
11978 
11979  if (TriggerFile == NULL)
11980  return false;
11981 
11982  if (stat(TriggerFile, &stat_buf) == 0)
11983  {
11984  ereport(LOG,
11985  (errmsg("trigger file found: %s", TriggerFile)));
11987  triggered = true;
11988  fast_promote = true;
11989  return true;
11990  }
11991  else if (errno != ENOENT)
11992  ereport(ERROR,
11994  errmsg("could not stat trigger file \"%s\": %m",
11995  TriggerFile)));
11996 
11997  return false;
11998 }
void ResetPromoteTriggered(void)
Definition: startup.c:252
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.c:85
#define LOG
Definition: elog.h:26
static char * TriggerFile
Definition: xlog.c:274
#define ERROR
Definition: elog.h:43
struct stat stat_buf
Definition: pg_standby.c:101
#define PROMOTE_SIGNAL_FILE
Definition: xlog.c:84
int errcode_for_file_access(void)
Definition: elog.c:598
bool IsPromoteTriggered(void)
Definition: startup.c:246
int unlink(const char *filename)
#define ereport(elevel, rest)
Definition: elog.h:122
#define NULL
Definition: c.h:229
int errmsg(const char *fmt,...)
Definition: elog.c:797
static bool fast_promote
Definition: xlog.c:280
static void CheckPointGuts ( XLogRecPtr  checkPointRedo,
int  flags 
)
static

Definition at line 8971 of file xlog.c.

References CheckPointBuffers(), CheckPointCLOG(), CheckPointCommitTs(), CheckPointLogicalRewriteHeap(), CheckPointMultiXact(), CheckPointPredicate(), CheckPointRelationMap(), CheckPointReplicationOrigin(), CheckPointReplicationSlots(), CheckPointSnapBuild(), CheckPointSUBTRANS(), and CheckPointTwoPhase().

Referenced by CreateCheckPoint(), and CreateRestartPoint().

8972 {
8973  CheckPointCLOG();
8982  CheckPointBuffers(flags); /* performs all required fsyncs */
8984  /* We deliberately delay 2PC checkpointing as long as possible */
8985  CheckPointTwoPhase(checkPointRedo);
8986 }
void CheckPointBuffers(int flags)
Definition: bufmgr.c:2574
void CheckPointLogicalRewriteHeap(void)
Definition: rewriteheap.c:1200
void CheckPointReplicationOrigin(void)
Definition: origin.c:504
void CheckPointSnapBuild(void)
Definition: snapbuild.c:1848
void CheckPointCLOG(void)
Definition: clog.c:586
void CheckPointMultiXact(void)
Definition: multixact.c:2140
void CheckPointCommitTs(void)
Definition: commit_ts.c:755
void CheckPointSUBTRANS(void)
Definition: subtrans.c:287
void CheckPointRelationMap(void)
Definition: relmapper.c:524
void CheckPointPredicate(void)
Definition: predicate.c:1032
void CheckPointTwoPhase(XLogRecPtr redo_horizon)
Definition: twophase.c:1605
void CheckPointReplicationSlots(void)
Definition: slot.c:895
bool CheckPromoteSignal ( void  )

Definition at line 12015 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, and PROMOTE_SIGNAL_FILE.

Referenced by sigusr1_handler().

12016 {
12017  struct stat stat_buf;
12018 
12019  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
12021  return true;
12022 
12023  return false;
12024 }
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.c:85
struct stat stat_buf
Definition: pg_standby.c:101
#define PROMOTE_SIGNAL_FILE
Definition: xlog.c:84
static void CheckRecoveryConsistency ( void  )
static

Definition at line 7756 of file xlog.c.

References ControlFileData::backupEndPoint, ControlFileData::backupEndRequired, ControlFileData::backupStartPoint, DEBUG1, elog, ereport, errmsg(), XLogCtlData::info_lck, InvalidXLogRecPtr, IsUnderPostmaster, XLogCtlData::lastReplayedEndRecPtr, LocalHotStandbyActive, LOG, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), ControlFileData::minRecoveryPoint, minRecoveryPoint, PMSIGNAL_BEGIN_HOT_STANDBY, reachedConsistency, SendPostmasterSignal(), XLogCtlData::SharedHotStandbyActive, SpinLockAcquire, SpinLockRelease, STANDBY_SNAPSHOT_READY, standbyState, UpdateControlFile(), XLogCheckInvalidPages(), and XLogRecPtrIsInvalid.

Referenced by ReadRecord(), and StartupXLOG().

7757 {
7758  XLogRecPtr lastReplayedEndRecPtr;
7759 
7760  /*
7761  * During crash recovery, we don't reach a consistent state until we've
7762  * replayed all the WAL.
7763  */
7765  return;
7766 
7767  /*
7768  * assume that we are called in the startup process, and hence don't need
7769  * a lock to read lastReplayedEndRecPtr
7770  */
7771  lastReplayedEndRecPtr = XLogCtl->lastReplayedEndRecPtr;
7772 
7773  /*
7774  * Have we reached the point where our base backup was completed?
7775  */
7777  ControlFile->backupEndPoint <= lastReplayedEndRecPtr)
7778  {
7779  /*
7780  * We have reached the end of base backup, as indicated by pg_control.
7781  * The data on disk is now consistent. Reset backupStartPoint and
7782  * backupEndPoint, and update minRecoveryPoint to make sure we don't
7783  * allow starting up at an earlier point even if recovery is stopped
7784  * and restarted soon after this.
7785  */
7786  elog(DEBUG1, "end of backup reached");
7787 
7788  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7789 
7790  if (ControlFile->minRecoveryPoint < lastReplayedEndRecPtr)
7791  ControlFile->minRecoveryPoint = lastReplayedEndRecPtr;
7792 
7795  ControlFile->backupEndRequired = false;
7797 
7798  LWLockRelease(ControlFileLock);
7799  }
7800 
7801  /*
7802  * Have we passed our safe starting point? Note that minRecoveryPoint is
7803  * known to be incorrectly set if ControlFile->backupEndRequired, until
7804  * the XLOG_BACKUP_RECORD arrives to advise us of the correct
7805  * minRecoveryPoint. All we know prior to that is that we're not
7806  * consistent yet.
7807  */
7809  minRecoveryPoint <= lastReplayedEndRecPtr &&
7811  {
7812  /*
7813  * Check to see if the XLOG sequence contained any unresolved
7814  * references to uninitialized pages.
7815  */
7817 
7818  reachedConsistency = true;
7819  ereport(LOG,
7820  (errmsg("consistent recovery state reached at %X/%X",
7821  (uint32) (lastReplayedEndRecPtr >> 32),
7822  (uint32) lastReplayedEndRecPtr)));
7823  }
7824 
7825  /*
7826  * Have we got a valid starting snapshot that will allow queries to be
7827  * run? If so, we can tell postmaster that the database is consistent now,
7828  * enabling connections.
7829  */
7834  {
7838 
7839  LocalHotStandbyActive = true;
7840 
7842  }
7843 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define DEBUG1
Definition: elog.h:25
void XLogCheckInvalidPages(void)
Definition: xlogutils.c:221
bool SharedHotStandbyActive
Definition: xlog.c:643
slock_t info_lck
Definition: xlog.c:698
#define LOG
Definition: elog.h:26
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
bool backupEndRequired
Definition: pg_control.h:174
#define SpinLockAcquire(lock)
Definition: spin.h:62
static bool LocalHotStandbyActive
Definition: xlog.c:221
void UpdateControlFile(void)
Definition: xlog.c:4635
bool IsUnderPostmaster
Definition: globals.c:100
unsigned int uint32
Definition: c.h:268
#define ereport(elevel, rest)
Definition: elog.h:122
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
#define SpinLockRelease(lock)
Definition: spin.h:64
static ControlFileData * ControlFile
Definition: xlog.c:709
XLogRecPtr backupEndPoint
Definition: pg_control.h:173
bool reachedConsistency
Definition: xlog.c:822
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:701
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
int errmsg(const char *fmt,...)
Definition: elog.c:797
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:113
#define elog
Definition: elog.h:219
HotStandbyState standbyState
Definition: xlog.c:195
XLogRecPtr backupStartPoint
Definition: pg_control.h:172
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:170
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:812
XLogRecPtr lastReplayedEndRecPtr
Definition: xlog.c:677
static void CheckRequiredParameterValues ( void  )
static

Definition at line 6138 of file xlog.c.

References ArchiveRecoveryRequested, EnableHotStandby, ereport, errhint(), errmsg(), ERROR, max_locks_per_xact, ControlFileData::max_locks_per_xact, max_prepared_xacts, ControlFileData::max_prepared_xacts, max_worker_processes, ControlFileData::max_worker_processes, MaxConnections, ControlFileData::MaxConnections, RecoveryRequiresIntParameter, ControlFileData::wal_level, WAL_LEVEL_MINIMAL, WAL_LEVEL_REPLICA, and WARNING.

Referenced by StartupXLOG(), and xlog_redo().

6139 {
6140  /*
6141  * For archive recovery, the WAL must be generated with at least 'replica'
6142  * wal_level.
6143  */
6145  {
6146  ereport(WARNING,
6147  (errmsg("WAL was generated with wal_level=minimal, data may be missing"),
6148  errhint("This happens if you temporarily set wal_level=minimal without taking a new base backup.")));
6149  }
6150 
6151  /*
6152  * For Hot Standby, the WAL must be generated with 'replica' mode, and we
6153  * must have at least as many backend slots as the primary.
6154  */
6156  {
6158  ereport(ERROR,
6159  (errmsg("hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server"),
6160  errhint("Either set wal_level to \"replica\" on the master, or turn off hot_standby here.")));
6161 
6162  /* We ignore autovacuum_max_workers when we make this test. */
6163  RecoveryRequiresIntParameter("max_connections",
6166  RecoveryRequiresIntParameter("max_worker_processes",
6169  RecoveryRequiresIntParameter("max_prepared_transactions",
6172  RecoveryRequiresIntParameter("max_locks_per_transaction",
6175  }
6176 }
bool ArchiveRecoveryRequested
Definition: xlog.c:246
int max_locks_per_xact
Definition: pg_control.h:185
int errhint(const char *fmt,...)
Definition: elog.c:987
int max_prepared_xacts
Definition: pg_control.h:184
int max_worker_processes
Definition: pg_control.h:183
#define ERROR
Definition: elog.h:43
int max_prepared_xacts
Definition: twophase.c:98
#define ereport(elevel, rest)
Definition: elog.h:122
int max_locks_per_xact
Definition: lock.c:54
#define WARNING
Definition: elog.h:40
int MaxConnections
Definition: globals.c:123
static ControlFileData * ControlFile
Definition: xlog.c:709
bool EnableHotStandby
Definition: xlog.c:96
int errmsg(const char *fmt,...)
Definition: elog.c:797
int max_worker_processes
Definition: globals.c:124
#define RecoveryRequiresIntParameter(param_name, currValue, minValue)
Definition: xlog.c:6116
static void checkTimeLineSwitch ( XLogRecPtr  lsn,
TimeLineID  newTLI,
TimeLineID  prevTLI 
)
static

Definition at line 9529 of file xlog.c.

References ereport, errmsg(), minRecoveryPoint, minRecoveryPointTLI, PANIC, ThisTimeLineID, tliInHistory(), and XLogRecPtrIsInvalid.

Referenced by StartupXLOG().

9530 {
9531  /* Check that the record agrees on what the current (old) timeline is */
9532  if (prevTLI != ThisTimeLineID)
9533  ereport(PANIC,
9534  (errmsg("unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record",
9535  prevTLI, ThisTimeLineID)));
9536 
9537  /*
9538  * The new timeline better be in the list of timelines we expect to see,
9539  * according to the timeline history. It should also not decrease.
9540  */
9541  if (newTLI < ThisTimeLineID || !tliInHistory(newTLI, expectedTLEs))
9542  ereport(PANIC,
9543  (errmsg("unexpected timeline ID %u (after %u) in checkpoint record",
9544  newTLI, ThisTimeLineID)));
9545 
9546  /*
9547  * If we have not yet reached min recovery point, and we're about to
9548  * switch to a timeline greater than the timeline of the min recovery
9549  * point: trouble. After switching to the new timeline, we could not
9550  * possibly visit the min recovery point on the correct timeline anymore.
9551  * This can happen if there is a newer timeline in the archive that
9552  * branched before the timeline the min recovery point is on, and you
9553  * attempt to do PITR to the new timeline.
9554  */
9556  lsn < minRecoveryPoint &&
9557  newTLI > minRecoveryPointTLI)
9558  ereport(PANIC,
9559  (errmsg("unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u",
9560  newTLI,
9561  (uint32) (minRecoveryPoint >> 32),
9564 
9565  /* Looks good */
9566 }
static List * expectedTLEs
Definition: xlog.c:318
#define PANIC
Definition: elog.h:53
unsigned int uint32
Definition: c.h:268
#define ereport(elevel, rest)
Definition: elog.h:122
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
static TimeLineID minRecoveryPointTLI
Definition: xlog.c:814
TimeLineID ThisTimeLineID
Definition: xlog.c:179
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool tliInHistory(TimeLineID tli, List *expectedTLEs)
Definition: timeline.c:517
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:812
static void checkXLogConsistency ( XLogReaderState record)
static

Definition at line 1335 of file xlog.c.

References Assert, buf, BUFFER_LOCK_EXCLUSIVE, BufferGetPage, BufferIsValid, RelFileNode::dbNode, elog, XLogReaderState::EndRecPtr, ERROR, FATAL, LockBuffer(), master_image_masked, XLogReaderState::max_block_id, NULL, PageGetLSN, RBM_NORMAL_NO_LOG, RelFileNode::relNode, replay_image_masked, RestoreBlockImage(), RmgrData::rm_mask, RmgrTable, RelFileNode::spcNode, UnlockReleaseBuffer(), XLogReadBufferExtended(), XLogRecBlockImageApply, XLogRecGetBlockTag(), XLogRecGetInfo, XLogRecGetRmid, XLogRecHasAnyBlockRefs, XLogRecHasBlockImage, and XLR_CHECK_CONSISTENCY.

Referenced by StartupXLOG().

1336 {
1337  RmgrId rmid = XLogRecGetRmid(record);
1338  RelFileNode rnode;
1339  ForkNumber forknum;
1340  BlockNumber blkno;
1341  int block_id;
1342 
1343  /* Records with no backup blocks have no need for consistency checks. */
1344  if (!XLogRecHasAnyBlockRefs(record))
1345  return;
1346 
1347  Assert((XLogRecGetInfo(record) & XLR_CHECK_CONSISTENCY) != 0);
1348 
1349  for (block_id = 0; block_id <= record->max_block_id; block_id++)
1350  {
1351  Buffer buf;
1352  Page page;
1353 
1354  if (!XLogRecGetBlockTag(record, block_id, &rnode, &forknum, &blkno))
1355  {
1356  /*
1357  * WAL record doesn't contain a block reference with the given id.
1358  * Do nothing.
1359  */
1360  continue;
1361  }
1362 
1363  Assert(XLogRecHasBlockImage(record, block_id));
1364 
1365  if (XLogRecBlockImageApply(record, block_id))
1366  {
1367  /*
1368  * WAL record has already applied the page, so bypass the
1369  * consistency check as that would result in comparing the full
1370  * page stored in the record with itself.
1371  */
1372  continue;
1373  }
1374 
1375  /*
1376  * Read the contents from the current buffer and store it in a
1377  * temporary page.
1378  */
1379  buf = XLogReadBufferExtended(rnode, forknum, blkno,
1381  if (!BufferIsValid(buf))
1382  continue;
1383 
1385  page = BufferGetPage(buf);
1386 
1387  /*
1388  * Take a copy of the local page where WAL has been applied to have a
1389  * comparison base before masking it...
1390  */
1391  memcpy(replay_image_masked, page, BLCKSZ);
1392 
1393  /* No need for this page anymore now that a copy is in. */
1394  UnlockReleaseBuffer(buf);
1395 
1396  /*
1397  * If the block LSN is already ahead of this WAL record, we can't
1398  * expect contents to match. This can happen if recovery is restarted.
1399  */
1400  if (PageGetLSN(replay_image_masked) > record->EndRecPtr)
1401  continue;
1402 
1403  /*
1404  * Read the contents from the backup copy, stored in WAL record and
1405  * store it in a temporary page. There is no need to allocate a new
1406  * page here, a local buffer is fine to hold its contents and a mask
1407  * can be directly applied on it.
1408  */
1409  if (!RestoreBlockImage(record, block_id, master_image_masked))
1410  elog(ERROR, "failed to restore block image");
1411 
1412  /*
1413  * If masking function is defined, mask both the master and replay
1414  * images
1415  */
1416  if (RmgrTable[rmid].rm_mask != NULL)
1417  {
1418  RmgrTable[rmid].rm_mask(replay_image_masked, blkno);
1419  RmgrTable[rmid].rm_mask(master_image_masked, blkno);
1420  }
1421 
1422  /* Time to compare the master and replay images. */
1423  if (memcmp(replay_image_masked, master_image_masked, BLCKSZ) != 0)
1424  {
1425  elog(FATAL,
1426  "inconsistent page found, rel %u/%u/%u, forknum %u, blkno %u",
1427  rnode.spcNode, rnode.dbNode, rnode.relNode,
1428  forknum, blkno);
1429  }
1430  }
1431 }
void(* rm_mask)(char *pagedata, BlockNumber blkno)
#define XLogRecHasBlockImage(decoder, block_id)
Definition: xlogreader.h:223
Buffer XLogReadBufferExtended(RelFileNode rnode, ForkNumber forknum, BlockNumber blkno, ReadBufferMode mode)
Definition: xlogutils.c:438
const RmgrData RmgrTable[RM_MAX_ID+1]
Definition: rmgr.c:36
uint32 BlockNumber
Definition: block.h:31
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:89
#define XLR_CHECK_CONSISTENCY
Definition: xlogrecord.h:80
XLogRecPtr EndRecPtr
Definition: xlogreader.h:115
static char * replay_image_masked
Definition: xlog.c:253
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
static char * buf
Definition: pg_test_fsync.c:65
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:214
ForkNumber
Definition: relpath.h:24
bool XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id, RelFileNode *rnode, ForkNumber *forknum, BlockNumber *blknum)
Definition: xlogreader.c:1307
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
uint8 RmgrId
Definition: rmgr.h:11
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
bool RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page)
Definition: xlogreader.c:1360
#define PageGetLSN(page)
Definition: bufpage.h:363
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:220
#define elog
Definition: elog.h:219
#define XLogRecBlockImageApply(decoder, block_id)
Definition: xlogreader.h:225
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
#define XLogRecGetRmid(decoder)
Definition: xlogreader.h:215
static char * master_image_masked
Definition: xlog.c:254
void CheckXLogRemoved ( XLogSegNo  segno,
TimeLineID  tli 
)

Definition at line 3756 of file xlog.c.

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

Referenced by perform_base_backup(), and XLogRead().

3757 {
3758  XLogSegNo lastRemovedSegNo;
3759 
3761  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3763 
3764  if (segno <= lastRemovedSegNo)
3765  {
3766  char filename[MAXFNAMELEN];
3767 
3768  XLogFileName(filename, tli, segno);
3769  ereport(ERROR,
3771  errmsg("requested WAL segment %s has already been removed",
3772  filename)));
3773  }
3774 }
slock_t info_lck
Definition: xlog.c:698
#define XLogFileName(fname, tli, logSegNo)
XLogSegNo lastRemovedSegNo
Definition: xlog.c:580
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define ERROR
Definition: elog.h:43
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:701
static char * filename
Definition: pg_dumpall.c:87
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void CleanupBackupHistory ( void  )
static

Definition at line 4094 of file xlog.c.

References AllocateDir(), dirent::d_name, DEBUG2, ereport, errcode_for_file_access(), errmsg(), ERROR, FreeDir(), IsBackupHistoryFileName, MAXPGPATH, NULL, ReadDir(), snprintf(), unlink(), XLogArchiveCheckDone(), XLogArchiveCleanup(), and XLOGDIR.

Referenced by do_pg_stop_backup().

4095 {
4096  DIR *xldir;
4097  struct dirent *xlde;
4098  char path[MAXPGPATH];
4099 
4100  xldir = AllocateDir(XLOGDIR);
4101  if (xldir == NULL)
4102  ereport(ERROR,
4104  errmsg("could not open transaction log directory \"%s\": %m",
4105  XLOGDIR)));
4106 
4107  while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
4108  {
4109  if (IsBackupHistoryFileName(xlde->d_name))
4110  {
4111  if (XLogArchiveCheckDone(xlde->d_name))
4112  {
4113  ereport(DEBUG2,
4114  (errmsg("removing transaction log backup history file \"%s\"",
4115  xlde->d_name)));
4116  snprintf(path, MAXPGPATH, XLOGDIR "/%s", xlde->d_name);
4117  unlink(path);
4118  XLogArchiveCleanup(xlde->d_name);
4119  }
4120  }
4121  }
4122 
4123  FreeDir(xldir);
4124 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
Definition: dirent.h:9
void XLogArchiveCleanup(const char *xlog)
Definition: xlogarchive.c:750
Definition: dirent.c:25
#define ERROR
Definition: elog.h:43
bool XLogArchiveCheckDone(const char *xlog)
Definition: xlogarchive.c:617
#define MAXPGPATH
#define DEBUG2
Definition: elog.h:24
int errcode_for_file_access(void)
Definition: elog.c:598
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2298
int unlink(const char *filename)
#define ereport(elevel, rest)
Definition: elog.h:122
#define IsBackupHistoryFileName(fname)
#define XLOGDIR
#define NULL
Definition: c.h:229
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2364
int errmsg(const char *fmt,...)
Definition: elog.c:797
char d_name[MAX_PATH]
Definition: dirent.h:14
int FreeDir(DIR *dir)
Definition: fd.c:2407
static void CopyXLogRecordToWAL ( int  write_len,
bool  isLogSwitch,
XLogRecData rdata,
XLogRecPtr  StartPos,
XLogRecPtr  EndPos 
)
static

Definition at line 1438 of file xlog.c.

References AdvanceXLInsertBuffer(), Assert, XLogRecData::data, elog, GetXLogBuffer(), INSERT_FREESPACE, XLogRecData::len, MAXALIGN64, XLogRecData::next, NULL, PANIC, SizeOfXLogLongPHD, SizeOfXLogRecord, SizeOfXLogShortPHD, WALInsertLockUpdateInsertingAt(), XLogSegSize, XLP_FIRST_IS_CONTRECORD, XLogPageHeaderData::xlp_info, and XLogPageHeaderData::xlp_rem_len.

Referenced by XLogInsertRecord().

1440 {
1441  char *currpos;
1442  int freespace;
1443  int written;
1444  XLogRecPtr CurrPos;
1445  XLogPageHeader pagehdr;
1446 
1447  /*
1448  * Get a pointer to the right place in the right WAL buffer to start
1449  * inserting to.
1450  */
1451  CurrPos = StartPos;
1452  currpos = GetXLogBuffer(CurrPos);
1453  freespace = INSERT_FREESPACE(CurrPos);
1454 
1455  /*
1456  * there should be enough space for at least the first field (xl_tot_len)
1457  * on this page.
1458  */
1459  Assert(freespace >= sizeof(uint32));
1460 
1461  /* Copy record data */
1462  written = 0;
1463  while (rdata != NULL)
1464  {
1465  char *rdata_data = rdata->data;
1466  int rdata_len = rdata->len;
1467 
1468  while (rdata_len > freespace)
1469  {
1470  /*
1471  * Write what fits on this page, and continue on the next page.
1472  */
1473  Assert(CurrPos % XLOG_BLCKSZ >= SizeOfXLogShortPHD || freespace == 0);
1474  memcpy(currpos, rdata_data, freespace);
1475  rdata_data += freespace;
1476  rdata_len -= freespace;
1477  written += freespace;
1478  CurrPos += freespace;
1479 
1480  /*
1481  * Get pointer to beginning of next page, and set the xlp_rem_len
1482  * in the page header. Set XLP_FIRST_IS_CONTRECORD.
1483  *
1484  * It's safe to set the contrecord flag and xlp_rem_len without a
1485  * lock on the page. All the other flags were already set when the
1486  * page was initialized, in AdvanceXLInsertBuffer, and we're the
1487  * only backend that needs to set the contrecord flag.
1488  */
1489  currpos = GetXLogBuffer(CurrPos);
1490  pagehdr = (XLogPageHeader) currpos;
1491  pagehdr->xlp_rem_len = write_len - written;
1492  pagehdr->xlp_info |= XLP_FIRST_IS_CONTRECORD;
1493 
1494  /* skip over the page header */
1495  if (CurrPos % XLogSegSize == 0)
1496  {
1497  CurrPos += SizeOfXLogLongPHD;
1498  currpos += SizeOfXLogLongPHD;
1499  }
1500  else
1501  {
1502  CurrPos += SizeOfXLogShortPHD;
1503  currpos += SizeOfXLogShortPHD;
1504  }
1505  freespace = INSERT_FREESPACE(CurrPos);
1506  }
1507 
1508  Assert(CurrPos % XLOG_BLCKSZ >= SizeOfXLogShortPHD || rdata_len == 0);
1509  memcpy(currpos, rdata_data, rdata_len);
1510  currpos += rdata_len;
1511  CurrPos += rdata_len;
1512  freespace -= rdata_len;
1513  written += rdata_len;
1514 
1515  rdata = rdata->next;
1516  }
1517  Assert(written == write_len);
1518 
1519  /*
1520  * If this was an xlog-switch, it's not enough to write the switch record,
1521  * we also have to consume all the remaining space in the WAL segment. We
1522  * have already reserved it for us, but we still need to make sure it's
1523  * allocated and zeroed in the WAL buffers so that when the caller (or
1524  * someone else) does XLogWrite(), it can really write out all the zeros.
1525  */
1526  if (isLogSwitch && CurrPos % XLOG_SEG_SIZE != 0)
1527  {
1528  /* An xlog-switch record doesn't contain any data besides the header */
1529  Assert(write_len == SizeOfXLogRecord);
1530 
1531  /*
1532  * We do this one page at a time, to make sure we don't deadlock
1533  * against ourselves if wal_buffers < XLOG_SEG_SIZE.
1534  */
1535  Assert(EndPos % XLogSegSize == 0);
1536 
1537  /* Use up all the remaining space on the first page */
1538  CurrPos += freespace;
1539 
1540  while (CurrPos < EndPos)
1541  {
1542  /* initialize the next page (if not initialized already) */
1544  AdvanceXLInsertBuffer(CurrPos, false);
1545  CurrPos += XLOG_BLCKSZ;
1546  }
1547  }
1548  else
1549  {
1550  /* Align the end position, so that the next record starts aligned */
1551  CurrPos = MAXALIGN64(CurrPos);
1552  }
1553 
1554  if (CurrPos != EndPos)
1555  elog(PANIC, "space reserved for WAL record does not match what was written");
1556 }
#define XLogSegSize
Definition: xlog_internal.h:92
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:57
#define PANIC
Definition: elog.h:53
static char * GetXLogBuffer(XLogRecPtr ptr)
Definition: xlog.c:1794
#define MAXALIGN64(LEN)
Definition: c.h:612
static void WALInsertLockUpdateInsertingAt(XLogRecPtr insertingAt)
Definition: xlog.c:1662
unsigned int uint32
Definition: c.h:268
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:715
#define SizeOfXLogRecord
Definition: xlogrecord.h:55
#define NULL
Definition: c.h:229
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:675
#define SizeOfXLogShortPHD
Definition: xlog_internal.h:55
#define XLP_FIRST_IS_CONTRECORD
Definition: xlog_internal.h:77
struct XLogRecData * next
#define elog
Definition: elog.h:219
static void AdvanceXLInsertBuffer(XLogRecPtr upto, bool opportunistic)
Definition: xlog.c:2032
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
void CreateCheckPoint ( int  flags)

Definition at line 8499 of file xlog.c.

References ControlFileData::checkPoint, CHECKPOINT_END_OF_RECOVERY, CHECKPOINT_FORCE, CHECKPOINT_IS_SHUTDOWN, ControlFileData::checkPointCopy, CheckPointGuts(), CheckpointStatsData::ckpt_bufs_written, CheckpointStatsData::ckpt_segs_added, CheckpointStatsData::ckpt_segs_recycled, CheckpointStatsData::ckpt_segs_removed, CheckpointStatsData::ckpt_start_t, XLogCtlData::ckptXid, XLogCtlData::ckptXidEpoch, XLogCtlInsert::CurrBytePos, DB_SHUTDOWNED, DB_SHUTDOWNING, DEBUG1, elog, END_CRIT_SECTION, ereport, errmsg(), ERROR, CheckPoint::fullPageWrites, XLogCtlInsert::fullPageWrites, GetCurrentTimestamp(), GetLastImportantRecPtr(), GetOldestActiveTransactionId(), GetOldestXmin(), GetVirtualXIDsDelayingChkpt(), HaveVirtualXIDsDelayingChkpt(), XLogCtlData::info_lck, InitXLogInsert(), Insert(), XLogCtlData::Insert, INSERT_FREESPACE, InvalidTransactionId, InvalidXLogRecPtr, KeepLogSeg(), LocalSetXLogInsertAllowed(), LocalXLogInsertAllowed, log_checkpoints, LogCheckpointEnd(), LogCheckpointStart(), LogStandbySnapshot(), LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockRelease(), MemSet, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, MultiXactGetCheckptMulti(), NBuffers, CheckPoint::newestCommitTsXid, VariableCacheData::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, VariableCacheData::nextOid, CheckPoint::nextXid, VariableCacheData::nextXid, CheckPoint::nextXidEpoch, NULL, VariableCacheData::oidCount, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, VariableCacheData::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, VariableCacheData::oldestXid, CheckPoint::oldestXidDB, VariableCacheData::oldestXidDB, PANIC, pfree(), pg_usleep(), PreallocXlogFiles(), ControlFileData::prevCheckPoint, CheckPoint::PrevTimeLineID, XLogCtlData::PrevTimeLineID, PROCARRAY_FLAGS_DEFAULT, ProcLastRecPtr, RecoveryInProgress(), CheckPoint::redo, RedoRecPtr, XLogCtlInsert::RedoRecPtr, XLogCtlData::RedoRecPtr, RemoveOldXlogFiles(), ShmemVariableCache, SizeOfXLogLongPHD, SizeOfXLogShortPHD, smgrpostckpt(), smgrpreckpt(), SpinLockAcquire, SpinLockRelease, START_CRIT_SECTION, ControlFileData::state, CheckPoint::ThisTimeLineID, ThisTimeLineID, CheckPoint::time, ControlFileData::time, TruncateSUBTRANS(), XLogCtlData::ulsn_lck, ControlFileData::unloggedLSN, XLogCtlData::unloggedLSN, UpdateCheckPointDistanceEstimate(), UpdateControlFile(), WALInsertLockAcquireExclusive(), WALInsertLockRelease(), XLByteToSeg, XLOG_CHECKPOINT_ONLINE, XLOG_CHECKPOINT_SHUTDOWN, XLogBeginInsert(), XLogBytePosToRecPtr(), XLogFlush(), XLogInsert(), XLogRegisterData(), XLogSegSize, and XLogStandbyInfoActive.

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

8500 {
8501  bool shutdown;
8502  CheckPoint checkPoint;
8503  XLogRecPtr recptr;
8505  uint32 freespace;
8506  XLogRecPtr PriorRedoPtr;
8507  XLogRecPtr curInsert;
8508  XLogRecPtr last_important_lsn;
8509  VirtualTransactionId *vxids;
8510  int nvxids;
8511 
8512  /*
8513  * An end-of-recovery checkpoint is really a shutdown checkpoint, just
8514  * issued at a different time.
8515  */
8517  shutdown = true;
8518  else
8519  shutdown = false;
8520 
8521  /* sanity check */
8522  if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
8523  elog(ERROR, "can't create a checkpoint during recovery");
8524 
8525  /*
8526  * Initialize InitXLogInsert working areas before entering the critical
8527  * section. Normally, this is done by the first call to
8528  * RecoveryInProgress() or LocalSetXLogInsertAllowed(), but when creating
8529  * an end-of-recovery checkpoint, the LocalSetXLogInsertAllowed call is
8530  * done below in a critical section, and InitXLogInsert cannot be called
8531  * in a critical section.
8532  */
8533  InitXLogInsert();
8534 
8535  /*
8536  * Acquire CheckpointLock to ensure only one checkpoint happens at a time.
8537  * (This is just pro forma, since in the present system structure there is
8538  * only one process that is allowed to issue checkpoints at any given
8539  * time.)
8540  */
8541  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
8542 
8543  /*
8544  * Prepare to accumulate statistics.
8545  *
8546  * Note: because it is possible for log_checkpoints to change while a
8547  * checkpoint proceeds, we always accumulate stats, even if
8548  * log_checkpoints is currently off.
8549  */
8550  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
8552 
8553  /*
8554  * Use a critical section to force system panic if we have trouble.
8555  */
8557 
8558  if (shutdown)
8559  {
8560  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8562  ControlFile->time = (pg_time_t) time(NULL);
8564  LWLockRelease(ControlFileLock);
8565  }
8566 
8567  /*
8568  * Let smgr prepare for checkpoint; this has to happen before we determine
8569  * the REDO pointer. Note that smgr must not do anything that'd have to
8570  * be undone if we decide no checkpoint is needed.
8571  */
8572  smgrpreckpt();
8573 
8574  /* Begin filling in the checkpoint WAL record */
8575  MemSet(&checkPoint, 0, sizeof(checkPoint));
8576  checkPoint.time = (pg_time_t) time(NULL);
8577 
8578  /*
8579  * For Hot Standby, derive the oldestActiveXid before we fix the redo
8580  * pointer. This allows us to begin accumulating changes to assemble our
8581  * starting snapshot of locks and transactions.
8582  */
8583  if (!shutdown && XLogStandbyInfoActive())
8585  else
8587 
8588  /*
8589  * Get location of last important record before acquiring insert locks (as
8590  * GetLastImportantRecPtr() also locks WAL locks).
8591  */
8592  last_important_lsn = GetLastImportantRecPtr();
8593 
8594  /*
8595  * We must block concurrent insertions while examining insert state to
8596  * determine the checkpoint REDO pointer.
8597  */
8599  curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
8600 
8601  /*
8602  * If this isn't a shutdown or forced checkpoint, and if there has been no
8603  * WAL activity requiring a checkpoint, skip it. The idea here is to
8604  * avoid inserting duplicate checkpoints when the system is idle.
8605  */
8606  if ((flags & (CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_END_OF_RECOVERY |
8607  CHECKPOINT_FORCE)) == 0)
8608  {
8609  if (last_important_lsn == ControlFile->checkPoint)
8610  {
8612  LWLockRelease(CheckpointLock);
8613  END_CRIT_SECTION();
8614  ereport(DEBUG1,
8615  (errmsg("checkpoint skipped due to an idle system")));
8616  return;
8617  }
8618  }
8619 
8620  /*
8621  * An end-of-recovery checkpoint is created before anyone is allowed to
8622  * write WAL. To allow us to write the checkpoint record, temporarily
8623  * enable XLogInsertAllowed. (This also ensures ThisTimeLineID is
8624  * initialized, which we need here and in AdvanceXLInsertBuffer.)
8625  */
8626  if (flags & CHECKPOINT_END_OF_RECOVERY)
8628 
8629  checkPoint.ThisTimeLineID = ThisTimeLineID;
8630  if (flags & CHECKPOINT_END_OF_RECOVERY)
8631  checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
8632  else
8633  checkPoint.PrevTimeLineID = ThisTimeLineID;
8634 
8635  checkPoint.fullPageWrites = Insert->fullPageWrites;
8636 
8637  /*
8638  * Compute new REDO record ptr = location of next XLOG record.
8639  *
8640  * NB: this is NOT necessarily where the checkpoint record itself will be,
8641  * since other backends may insert more XLOG records while we're off doing
8642  * the buffer flush work. Those XLOG records are logically after the
8643  * checkpoint, even though physically before it. Got that?
8644  */
8645  freespace = INSERT_FREESPACE(curInsert);
8646  if (freespace == 0)
8647  {
8648  if (curInsert % XLogSegSize == 0)
8649  curInsert += SizeOfXLogLongPHD;
8650  else
8651  curInsert += SizeOfXLogShortPHD;
8652  }
8653  checkPoint.redo = curInsert;
8654 
8655  /*
8656  * Here we update the shared RedoRecPtr for future XLogInsert calls; this
8657  * must be done while holding all the insertion locks.
8658  *
8659  * Note: if we fail to complete the checkpoint, RedoRecPtr will be left
8660  * pointing past where it really needs to point. This is okay; the only
8661  * consequence is that XLogInsert might back up whole buffers that it
8662  * didn't really need to. We can't postpone advancing RedoRecPtr because
8663  * XLogInserts that happen while we are dumping buffers must assume that
8664  * their buffer changes are not included in the checkpoint.
8665  */
8666  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
8667 
8668  /*
8669  * Now we can release the WAL insertion locks, allowing other xacts to
8670  * proceed while we are flushing disk buffers.
8671  */
8673 
8674  /* Update the info_lck-protected copy of RedoRecPtr as well */
8676  XLogCtl->RedoRecPtr = checkPoint.redo;
8678 
8679  /*
8680  * If enabled, log checkpoint start. We postpone this until now so as not
8681  * to log anything if we decided to skip the checkpoint.
8682  */
8683  if (log_checkpoints)
8684  LogCheckpointStart(flags, false);
8685 
8686  TRACE_POSTGRESQL_CHECKPOINT_START(flags);
8687 
8688  /*
8689  * Get the other info we need for the checkpoint record.
8690  */
8691  LWLockAcquire(XidGenLock, LW_SHARED);
8692  checkPoint.nextXid = ShmemVariableCache->nextXid;
8693  checkPoint.oldestXid = ShmemVariableCache->oldestXid;
8695  LWLockRelease(XidGenLock);
8696 
8697  LWLockAcquire(CommitTsLock, LW_SHARED);
8700  LWLockRelease(CommitTsLock);
8701 
8702  /* Increase XID epoch if we've wrapped around since last checkpoint */
8704  if (checkPoint.nextXid < ControlFile->checkPointCopy.nextXid)
8705  checkPoint.nextXidEpoch++;
8706 
8707  LWLockAcquire(OidGenLock, LW_SHARED);
8708  checkPoint.nextOid = ShmemVariableCache->nextOid;
8709  if (!shutdown)
8710  checkPoint.nextOid += ShmemVariableCache->oidCount;
8711  LWLockRelease(OidGenLock);
8712 
8713  MultiXactGetCheckptMulti(shutdown,
8714  &checkPoint.nextMulti,
8715  &checkPoint.nextMultiOffset,
8716  &checkPoint.oldestMulti,
8717  &checkPoint.oldestMultiDB);
8718 
8719  /*
8720  * Having constructed the checkpoint record, ensure all shmem disk buffers
8721  * and commit-log buffers are flushed to disk.
8722  *
8723  * This I/O could fail for various reasons. If so, we will fail to
8724  * complete the checkpoint, but there is no reason to force a system
8725  * panic. Accordingly, exit critical section while doing it.
8726  */
8727  END_CRIT_SECTION();
8728 
8729  /*
8730  * In some cases there are groups of actions that must all occur on one
8731  * side or the other of a checkpoint record. Before flushing the
8732  * checkpoint record we must explicitly wait for any backend currently
8733  * performing those groups of actions.
8734  *
8735  * One example is end of transaction, so we must wait for any transactions
8736  * that are currently in commit critical sections. If an xact inserted
8737  * its commit record into XLOG just before the REDO point, then a crash
8738  * restart from the REDO point would not replay that record, which means
8739  * that our flushing had better include the xact's update of pg_xact. So
8740  * we wait till he's out of his commit critical section before proceeding.
8741  * See notes in RecordTransactionCommit().
8742  *
8743  * Because we've already released the insertion locks, this test is a bit
8744  * fuzzy: it is possible that we will wait for xacts we didn't really need
8745  * to wait for. But the delay should be short and it seems better to make
8746  * checkpoint take a bit longer than to hold off insertions longer than
8747  * necessary. (In fact, the whole reason we have this issue is that xact.c
8748  * does commit record XLOG insertion and clog update as two separate steps
8749  * protected by different locks, but again that seems best on grounds of
8750  * minimizing lock contention.)
8751  *
8752  * A transaction that has not yet set delayChkpt when we look cannot be at
8753  * risk, since he's not inserted his commit record yet; and one that's
8754  * already cleared it is not at risk either, since he's done fixing clog
8755  * and we will correctly flush the update below. So we cannot miss any
8756  * xacts we need to wait for.
8757  */
8758  vxids = GetVirtualXIDsDelayingChkpt(&nvxids);
8759  if (nvxids > 0)
8760  {
8761  do
8762  {
8763  pg_usleep(10000L); /* wait for 10 msec */
8764  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids));
8765  }
8766  pfree(vxids);
8767 
8768  CheckPointGuts(checkPoint.redo, flags);
8769 
8770  /*
8771  * Take a snapshot of running transactions and write this to WAL. This
8772  * allows us to reconstruct the state of running transactions during
8773  * archive recovery, if required. Skip, if this info disabled.
8774  *
8775  * If we are shutting down, or Startup process is completing crash
8776  * recovery we don't need to write running xact data.
8777  */
8778  if (!shutdown && XLogStandbyInfoActive())
8780 
8782 
8783  /*
8784  * Now insert the checkpoint record into XLOG.
8785  */
8786  XLogBeginInsert();
8787  XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));
8788  recptr = XLogInsert(RM_XLOG_ID,
8789  shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
8791 
8792  XLogFlush(recptr);
8793 
8794  /*
8795  * We mustn't write any new WAL after a shutdown checkpoint, or it will be
8796  * overwritten at next startup. No-one should even try, this just allows
8797  * sanity-checking. In the case of an end-of-recovery checkpoint, we want
8798  * to just temporarily disable writing until the system has exited
8799  * recovery.
8800  */
8801  if (shutdown)
8802  {
8803  if (flags & CHECKPOINT_END_OF_RECOVERY)
8804  LocalXLogInsertAllowed = -1; /* return to "check" state */
8805  else
8806  LocalXLogInsertAllowed = 0; /* never again write WAL */
8807  }
8808 
8809  /*
8810  * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
8811  * = end of actual checkpoint record.
8812  */
8813  if (shutdown && checkPoint.redo != ProcLastRecPtr)
8814  ereport(PANIC,
8815  (errmsg("concurrent transaction log activity while database system is shutting down")));
8816 
8817  /*
8818  * Remember the prior checkpoint's redo pointer, used later to determine
8819  * the point where the log can be truncated.
8820  */
8821  PriorRedoPtr = ControlFile->checkPointCopy.redo;
8822 
8823  /*
8824  * Update the control file.
8825  */
8826  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8827  if (shutdown)
8831  ControlFile->checkPointCopy = checkPoint;
8832  ControlFile->time = (pg_time_t) time(NULL);
8833  /* crash recovery should always recover to the end of WAL */
8836 
8837  /*
8838  * Persist unloggedLSN value. It's reset on crash recovery, so this goes
8839  * unused on non-shutdown checkpoints, but seems useful to store it always
8840  * for debugging purposes.
8841  */
8845 
8847  LWLockRelease(ControlFileLock);
8848 
8849  /* Update shared-memory copy of checkpoint XID/epoch */
8851  XLogCtl->ckptXidEpoch = checkPoint.nextXidEpoch;
8852  XLogCtl->ckptXid = checkPoint.nextXid;
8854 
8855  /*
8856  * We are now done with critical updates; no need for system panic if we
8857  * have trouble while fooling with old log segments.
8858  */
8859  END_CRIT_SECTION();
8860 
8861  /*
8862  * Let smgr do post-checkpoint cleanup (eg, deleting old files).
8863  */
8864  smgrpostckpt();
8865 
8866  /*
8867  * Delete old log files (those no longer needed even for previous
8868  * checkpoint or the standbys in XLOG streaming).
8869  */
8870  if (PriorRedoPtr != InvalidXLogRecPtr)
8871  {
8872  XLogSegNo _logSegNo;
8873 
8874  /* Update the average distance between checkpoints. */
8876 
8877  XLByteToSeg(PriorRedoPtr, _logSegNo);
8878  KeepLogSeg(recptr, &_logSegNo);
8879  _logSegNo--;
8880  RemoveOldXlogFiles(_logSegNo, PriorRedoPtr, recptr);
8881  }
8882 
8883  /*
8884  * Make more log segments if needed. (Do this after recycling old log
8885  * segments, since that may supply some of the needed files.)
8886  */
8887  if (!shutdown)
8888  PreallocXlogFiles(recptr);
8889 
8890  /*
8891  * Truncate pg_subtrans if possible. We can throw away all data before
8892  * the oldest XMIN of any running transaction. No future transaction will
8893  * attempt to reference any pg_subtrans entry older than that (see Asserts
8894  * in subtrans.c). During recovery, though, we mustn't do this because
8895  * StartupSUBTRANS hasn't been called yet.
8896  */
8897  if (!RecoveryInProgress())
8899 
8900  /* Real work is done, but log and update stats before releasing lock. */
8901  LogCheckpointEnd(false);
8902 
8903  TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
8904  NBuffers,
8908 
8909  LWLockRelease(CheckpointLock);
8910 }
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:8222
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8437
#define XLogSegSize
Definition: xlog_internal.h:92
static int LocalXLogInsertAllowed
Definition: xlog.c:233
bool log_checkpoints
Definition: xlog.c:102
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define DEBUG1
Definition: elog.h:25
int64 pg_time_t
Definition: pgtime.h:23
TransactionId ckptXid
Definition: xlog.c:576
static void WALInsertLockRelease(void)
Definition: xlog.c:1636
pg_time_t time
Definition: pg_control.h:131
#define XLOG_CHECKPOINT_ONLINE
Definition: pg_control.h:67
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:171
uint32 oidCount
Definition: transam.h:112
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1569
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1905
XLogRecPtr unloggedLSN
Definition: xlog.c:584
XLogRecPtr ProcLastRecPtr
Definition: xlog.c:336
TransactionId oldestActiveXid
Definition: pg_control.h:62
void InitXLogInsert(void)
Definition: xloginsert.c:1029
TimestampTz ckpt_start_t
Definition: xlog.h:199
slock_t info_lck
Definition: xlog.c:698
#define END_CRIT_SECTION()
Definition: miscadmin.h:132
VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids)
Definition: procarray.c:2232
MultiXactId oldestMulti
Definition: pg_control.h:48
TimeLineID PrevTimeLineID
Definition: xlog.c:625
TimeLineID PrevTimeLineID
Definition: pg_control.h:38
#define START_CRIT_SECTION()
Definition: miscadmin.h:130
int ckpt_segs_recycled
Definition: xlog.h:209
TransactionId oldestXid
Definition: transam.h:119
#define MemSet(start, val, len)
Definition: c.h:857
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
Definition: xlog.c:3821
void MultiXactGetCheckptMulti(bool is_shutdown, MultiXactId *nextMulti, MultiXactOffset *nextMultiOffset, MultiXactId *oldestMulti, Oid *oldestMultiDB)
Definition: multixact.c:2118
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:8971
CheckPoint checkPointCopy
Definition: pg_control.h:135
XLogCtlInsert Insert
Definition: xlog.c:570
TransactionId oldestXid
Definition: pg_control.h:46
bool RecoveryInProgress(void)
Definition: xlog.c:7855
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:341
uint32 ckptXidEpoch
Definition: xlog.c:575
TransactionId nextXid
Definition: pg_control.h:42
pg_time_t time
Definition: pg_control.h:50
#define PANIC
Definition: elog.h:53
bool fullPageWrites
Definition: xlog.c:544
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2748
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
#define SpinLockAcquire(lock)
Definition: spin.h:62
void pg_usleep(long microsec)
Definition: signal.c:53
MultiXactOffset nextMultiOffset
Definition: pg_control.h:45
void UpdateControlFile(void)
Definition: xlog.c:4635
TransactionId oldestCommitTsXid
Definition: pg_control.h:51
void pfree(void *pointer)
Definition: mcxt.c:950
XLogRecPtr LogStandbySnapshot(void)
Definition: standby.c:909
#define ERROR
Definition: elog.h:43
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8352
TransactionId nextXid
Definition: transam.h:117
uint32 nextXidEpoch
Definition: pg_control.h:41
static XLogRecPtr RedoRecPtr
Definition: xlog.c:350
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:66
XLogRecPtr unloggedLSN
Definition: pg_control.h:137
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3730
uint64 XLogSegNo
Definition: xlogdefs.h:34
#define CHECKPOINT_END_OF_RECOVERY
Definition: xlog.h:176
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define InvalidTransactionId
Definition: transam.h:31
uint64 CurrBytePos
Definition: xlog.c:520
unsigned int uint32
Definition: c.h:268
XLogRecPtr RedoRecPtr
Definition: xlog.c:574
int ckpt_segs_removed
Definition: xlog.h:208
#define CHECKPOINT_FORCE
Definition: xlog.h:180
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:715
#define ereport(elevel, rest)
Definition: elog.h:122
TransactionId oldestCommitTsXid
Definition: transam.h:129
static void Insert(File file)
Definition: fd.c:1007
int ckpt_bufs_written
Definition: xlog.h:205
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:7981
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
#define SpinLockRelease(lock)
Definition: spin.h:64
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
TransactionId newestCommitTsXid
Definition: pg_control.h:53
#define PROCARRAY_FLAGS_DEFAULT
Definition: procarray.h:37
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9295
Oid oldestMultiDB
Definition: pg_control.h:49
#define XLogStandbyInfoActive()
Definition: xlog.h:159
XLogRecPtr prevCheckPoint
Definition: pg_control.h:133
static ControlFileData * ControlFile
Definition: xlog.c:709
TimeLineID ThisTimeLineID
Definition: xlog.c:179
Oid nextOid
Definition: pg_control.h:43
bool fullPageWrites
Definition: pg_control.h:40
TransactionId GetOldestXmin(Relation rel, int flags)
Definition: procarray.c:1307
void smgrpreckpt(void)
Definition: smgr.c:744
#define XLByteToSeg(xlrp, logSegNo)
#define NULL
Definition: c.h:229
uint64 XLogRecPtr
Definition: xlogdefs.h:21
Oid oldestXidDB
Definition: pg_control.h:47
TransactionId newestCommitTsXid
Definition: transam.h:130
CheckpointStatsData CheckpointStats
Definition: xlog.c:173
#define SizeOfXLogShortPHD
Definition: xlog_internal.h:55
MultiXactId nextMulti
Definition: pg_control.h:44
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1607
static XLogCtlData * XLogCtl
Definition: xlog.c:701
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
int ckpt_segs_added
Definition: xlog.h:207
slock_t ulsn_lck
Definition: xlog.c:585
TimeLineID ThisTimeLineID
Definition: pg_control.h:37
int errmsg(const char *fmt,...)
Definition: elog.c:797
TransactionId GetOldestActiveTransactionId(void)
Definition: procarray.c:2078
int NBuffers
Definition: globals.c:122
#define elog
Definition: elog.h:219
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids)
Definition: procarray.c:2277
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr RedoRecPtr
Definition: xlog.c:542
void smgrpostckpt(void)
Definition: smgr.c:774
XLogRecPtr checkPoint
Definition: pg_control.h:132
XLogRecPtr redo
Definition: pg_control.h:35
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8334
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:175
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:170
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
static void CreateEndOfRecoveryRecord ( void  )
static

Definition at line 8922 of file xlog.c.

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

Referenced by StartupXLOG().

8923 {
8924  xl_end_of_recovery xlrec;
8925  XLogRecPtr recptr;
8926 
8927  /* sanity check */
8928  if (!RecoveryInProgress())
8929  elog(ERROR, "can only be used to end recovery");
8930 
8931  xlrec.end_time = GetCurrentTimestamp();
8932 
8937 
8939 
8941 
8942  XLogBeginInsert();
8943  XLogRegisterData((char *) &xlrec, sizeof(xl_end_of_recovery));
8944  recptr = XLogInsert(RM_XLOG_ID, XLOG_END_OF_RECOVERY);
8945 
8946  XLogFlush(recptr);
8947 
8948  /*
8949  * Update the control file so that crash recovery can follow the timeline
8950  * changes to this point.
8951  */
8952  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8953  ControlFile->time = (pg_time_t) time(NULL);
8954  ControlFile->minRecoveryPoint = recptr;
8957  LWLockRelease(ControlFileLock);
8958 
8959  END_CRIT_SECTION();
8960 
8961  LocalXLogInsertAllowed = -1; /* return to "check" state */
8962 }
static int LocalXLogInsertAllowed
Definition: xlog.c:233
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1636
pg_time_t time
Definition: pg_control.h:131
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:171
TimeLineID PrevTimeLineID
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1569
#define END_CRIT_SECTION()
Definition: miscadmin.h:132
TimeLineID PrevTimeLineID
Definition: xlog.c:625
#define START_CRIT_SECTION()
Definition: miscadmin.h:130
bool RecoveryInProgress(void)
Definition: xlog.c:7855
#define XLOG_END_OF_RECOVERY
Definition: pg_control.h:75
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2748
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
void UpdateControlFile(void)
Definition: xlog.c:4635
#define ERROR
Definition: elog.h:43
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:7981
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
static ControlFileData * ControlFile
Definition: xlog.c:709
TimeLineID ThisTimeLineID
Definition: xlog.c:179
TimestampTz end_time
#define NULL
Definition: c.h:229
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1607
static XLogCtlData * XLogCtl
Definition: xlog.c:701
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
TimeLineID ThisTimeLineID
#define elog
Definition: elog.h:219
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:170
bool CreateRestartPoint ( int  flags)

Definition at line 9041 of file xlog.c.

References XLogCtlData::archiveCleanupCommand, ControlFileData::checkPoint, CHECKPOINT_IS_SHUTDOWN, ControlFileData::checkPointCopy, CheckPointGuts(), CheckpointStatsData::ckpt_start_t, DB_IN_ARCHIVE_RECOVERY, DB_SHUTDOWNED_IN_RECOVERY, DEBUG2, EnableHotStandby, ereport, errdetail(), errmsg(), ExecuteRecoveryCommand(), GetCurrentTimestamp(), GetLatestXTime(), GetOldestXmin(), GetWalRcvWriteRecPtr(), GetXLogReplayRecPtr(), XLogCtlData::info_lck, XLogCtlData::Insert, InvalidXLogRecPtr, KeepLogSeg(), XLogCtlData::lastCheckPoint, XLogCtlData::lastCheckPointEndPtr, XLogCtlData::lastCheckPointRecPtr, LOG, log_checkpoints, LogCheckpointEnd(), LogCheckpointStart(), LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MemSet, ControlFileData::minRecoveryPoint, minRecoveryPoint, ControlFileData::minRecoveryPointTLI, minRecoveryPointTLI, NULL, PreallocXlogFiles(), ControlFileData::prevCheckPoint, PROCARRAY_FLAGS_DEFAULT, RecoveryInProgress(), CheckPoint::redo, RedoRecPtr, XLogCtlInsert::RedoRecPtr, XLogCtlData::RedoRecPtr, RemoveOldXlogFiles(), SpinLockAcquire, SpinLockRelease, ControlFileData::state, CheckPoint::ThisTimeLineID, ThisTimeLineID, ControlFileData::time, timestamptz_to_str(), TruncateSUBTRANS(), UpdateCheckPointDistanceEstimate(), UpdateControlFile(), UpdateMinRecoveryPoint(), WALInsertLockAcquireExclusive(), WALInsertLockRelease(), XLByteToSeg, and XLogRecPtrIsInvalid.

Referenced by CheckpointerMain(), and ShutdownXLOG().

9042 {
9043  XLogRecPtr lastCheckPointRecPtr;
9044  XLogRecPtr lastCheckPointEndPtr;
9045  CheckPoint lastCheckPoint;
9046  XLogRecPtr PriorRedoPtr;
9047  TimestampTz xtime;
9048 
9049  /*
9050  * Acquire CheckpointLock to ensure only one restartpoint or checkpoint
9051  * happens at a time.
9052  */
9053  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
9054 
9055  /* Get a local copy of the last safe checkpoint record. */
9057  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
9058  lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
9059  lastCheckPoint = XLogCtl->lastCheckPoint;
9061 
9062  /*
9063  * Check that we're still in recovery mode. It's ok if we exit recovery
9064  * mode after this check, the restart point is valid anyway.
9065  */
9066  if (!RecoveryInProgress())
9067  {
9068  ereport(DEBUG2,
9069  (errmsg("skipping restartpoint, recovery has already ended")));
9070  LWLockRelease(CheckpointLock);
9071  return false;
9072  }
9073 
9074  /*
9075  * If the last checkpoint record we've replayed is already our last
9076  * restartpoint, we can't perform a new restart point. We still update
9077  * minRecoveryPoint in that case, so that if this is a shutdown restart
9078  * point, we won't start up earlier than before. That's not strictly
9079  * necessary, but when hot standby is enabled, it would be rather weird if
9080  * the database opened up for read-only connections at a point-in-time
9081  * before the last shutdown. Such time travel is still possible in case of
9082  * immediate shutdown, though.
9083  *
9084  * We don't explicitly advance minRecoveryPoint when we do create a
9085  * restartpoint. It's assumed that flushing the buffers will do that as a
9086  * side-effect.
9087  */
9088  if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
9089  lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
9090  {
9091  ereport(DEBUG2,
9092  (errmsg("skipping restartpoint, already performed at %X/%X",
9093  (uint32) (lastCheckPoint.redo >> 32),
9094  (uint32) lastCheckPoint.redo)));
9095 
9097  if (flags & CHECKPOINT_IS_SHUTDOWN)
9098  {
9099  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9101  ControlFile->time = (pg_time_t) time(NULL);
9103  LWLockRelease(ControlFileLock);
9104  }
9105  LWLockRelease(CheckpointLock);
9106  return false;
9107  }
9108 
9109  /*
9110  * Update the shared RedoRecPtr so that the startup process can calculate
9111  * the number of segments replayed since last restartpoint, and request a
9112  * restartpoint if it exceeds CheckPointSegments.
9113  *
9114  * Like in CreateCheckPoint(), hold off insertions to update it, although
9115  * during recovery this is just pro forma, because no WAL insertions are
9116  * happening.
9117  */
9119  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
9121 
9122  /* Also update the info_lck-protected copy */
9124  XLogCtl->RedoRecPtr = lastCheckPoint.redo;
9126 
9127  /*
9128  * Prepare to accumulate statistics.
9129  *
9130  * Note: because it is possible for log_checkpoints to change while a
9131  * checkpoint proceeds, we always accumulate stats, even if
9132  * log_checkpoints is currently off.
9133  */
9134  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
9136 
9137  if (log_checkpoints)
9138  LogCheckpointStart(flags, true);
9139 
9140  CheckPointGuts(lastCheckPoint.redo, flags);
9141 
9142  /*
9143  * Remember the prior checkpoint's redo pointer, used later to determine
9144  * the point at which we can truncate the log.
9145  */
9146  PriorRedoPtr = ControlFile->checkPointCopy.redo;
9147 
9148  /*
9149  * Update pg_control, using current time. Check that it still shows
9150  * IN_ARCHIVE_RECOVERY state and an older checkpoint, else do nothing;
9151  * this is a quick hack to make sure nothing really bad happens if somehow
9152  * we get here after the end-of-recovery checkpoint.
9153  */
9154  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9156  ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
9157  {
9159  ControlFile->checkPoint = lastCheckPointRecPtr;
9160  ControlFile->checkPointCopy = lastCheckPoint;
9161  ControlFile->time = (pg_time_t) time(NULL);
9162 
9163  /*
9164  * Ensure minRecoveryPoint is past the checkpoint record. Normally,
9165  * this will have happened already while writing out dirty buffers,
9166  * but not necessarily - e.g. because no buffers were dirtied. We do
9167  * this because a non-exclusive base backup uses minRecoveryPoint to
9168  * determine which WAL files must be included in the backup, and the
9169  * file (or files) containing the checkpoint record must be included,
9170  * at a minimum. Note that for an ordinary restart of recovery there's
9171  * no value in having the minimum recovery point any earlier than this
9172  * anyway, because redo will begin just after the checkpoint record.
9173  */
9174  if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
9175  {
9176  ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
9178 
9179  /* update local copy */
9182  }
9183  if (flags & CHECKPOINT_IS_SHUTDOWN)
9186  }
9187  LWLockRelease(ControlFileLock);
9188 
9189  /*
9190  * Delete old log files (those no longer needed even for previous
9191  * checkpoint/restartpoint) to prevent the disk holding the xlog from
9192  * growing full.
9193  */
9194  if (PriorRedoPtr != InvalidXLogRecPtr)
9195  {
9196  XLogRecPtr receivePtr;
9197  XLogRecPtr replayPtr;
9198  TimeLineID replayTLI;
9199  XLogRecPtr endptr;
9200  XLogSegNo _logSegNo;
9201 
9202  /* Update the average distance between checkpoints/restartpoints. */
9204 
9205  XLByteToSeg(PriorRedoPtr, _logSegNo);
9206 
9207  /*
9208  * Get the current end of xlog replayed or received, whichever is
9209  * later.
9210  */
9211  receivePtr = GetWalRcvWriteRecPtr(NULL, NULL);
9212  replayPtr = GetXLogReplayRecPtr(&replayTLI);
9213  endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
9214 
9215  KeepLogSeg(endptr, &_logSegNo);
9216  _logSegNo--;
9217 
9218  /*
9219  * Try to recycle segments on a useful timeline. If we've been
9220  * promoted since the beginning of this restartpoint, use the new
9221  * timeline chosen at end of recovery (RecoveryInProgress() sets
9222  * ThisTimeLineID in that case). If we're still in recovery, use the
9223  * timeline we're currently replaying.
9224  *
9225  * There is no guarantee that the WAL segments will be useful on the
9226  * current timeline; if recovery proceeds to a new timeline right
9227  * after this, the pre-allocated WAL segments on this timeline will
9228  * not be used, and will go wasted until recycled on the next
9229  * restartpoint. We'll live with that.
9230  */
9231  if (RecoveryInProgress())
9232  ThisTimeLineID = replayTLI;
9233 
9234  RemoveOldXlogFiles(_logSegNo, PriorRedoPtr, endptr);
9235 
9236  /*
9237  * Make more log segments if needed. (Do this after recycling old log
9238  * segments, since that may supply some of the needed files.)
9239  */
9240  PreallocXlogFiles(endptr);
9241 
9242  /*
9243  * ThisTimeLineID is normally not set when we're still in recovery.
9244  * However, recycling/preallocating segments above needed
9245  * ThisTimeLineID to determine which timeline to install the segments
9246  * on. Reset it now, to restore the normal state of affairs for
9247  * debugging purposes.
9248  */
9249  if (RecoveryInProgress())
9250  ThisTimeLineID = 0;
9251  }
9252 
9253  /*
9254  * Truncate pg_subtrans if possible. We can throw away all data before
9255  * the oldest XMIN of any running transaction. No future transaction will
9256  * attempt to reference any pg_subtrans entry older than that (see Asserts
9257  * in subtrans.c). When hot standby is disabled, though, we mustn't do
9258  * this because StartupSUBTRANS hasn't been called yet.
9259  */
9260  if (EnableHotStandby)
9262 
9263  /* Real work is done, but log and update before releasing lock. */
9264  LogCheckpointEnd(true);
9265 
9266  xtime = GetLatestXTime();
9268  (errmsg("recovery restart point at %X/%X",
9269  (uint32) (lastCheckPoint.redo >> 32), (uint32) lastCheckPoint.redo),
9270  xtime ? errdetail("last completed transaction was at log time %s",
9271  timestamptz_to_str(xtime)) : 0));
9272 
9273  LWLockRelease(CheckpointLock);
9274 
9275  /*
9276  * Finally, execute archive_cleanup_command, if any.
9277  */
9280  "archive_cleanup_command",
9281  false);
9282 
9283  return true;
9284 }
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8437
bool log_checkpoints
Definition: xlog.c:102
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
uint32 TimeLineID
Definition: xlogdefs.h:45
int64 pg_time_t
Definition: pgtime.h:23
XLogRecPtr GetWalRcvWriteRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI)
static void WALInsertLockRelease(void)
Definition: xlog.c:1636
pg_time_t time
Definition: pg_control.h:131
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:171
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1569
int64 TimestampTz
Definition: timestamp.h:39
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition: xlog.c:2673
TimestampTz ckpt_start_t
Definition: xlog.h:199
slock_t info_lck
Definition: xlog.c:698
#define MemSet(start, val, len)
Definition: c.h:857
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
Definition: xlog.c:3821
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:8971
TimestampTz GetLatestXTime(void)
Definition: xlog.c:6054
CheckPoint checkPointCopy
Definition: pg_control.h:135
XLogCtlInsert Insert
Definition: xlog.c:570
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:7855
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:341
XLogRecPtr lastCheckPointRecPtr
Definition: xlog.c:667
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
#define SpinLockAcquire(lock)
Definition: spin.h:62
void UpdateControlFile(void)
Definition: xlog.c:4635
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8352
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
Definition: xlog.c:11037
#define DEBUG2
Definition: elog.h:24
static XLogRecPtr RedoRecPtr
Definition: xlog.c:350
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3730
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errdetail(const char *fmt,...)
Definition: elog.c:873
unsigned int uint32
Definition: c.h:268
XLogRecPtr RedoRecPtr
Definition: xlog.c:574
#define ereport(elevel, rest)
Definition: elog.h:122
CheckPoint lastCheckPoint
Definition: xlog.c:669
void ExecuteRecoveryCommand(char *command, char *commandName, bool failOnSignal)
Definition: xlogarchive.c:329
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
#define SpinLockRelease(lock)
Definition: spin.h:64
static TimeLineID minRecoveryPointTLI
Definition: xlog.c:814
#define PROCARRAY_FLAGS_DEFAULT
Definition: procarray.h:37
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9295
XLogRecPtr prevCheckPoint
Definition: pg_control.h:133
static ControlFileData * ControlFile
Definition: xlog.c:709
TimeLineID ThisTimeLineID
Definition: xlog.c:179
TransactionId GetOldestXmin(Relation rel, int flags)
Definition: procarray.c:1307
#define XLByteToSeg(xlrp, logSegNo)
#define NULL
Definition: c.h:229
uint64 XLogRecPtr
Definition: xlogdefs.h:21
CheckpointStatsData CheckpointStats
Definition: xlog.c:173
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1607
static XLogCtlData * XLogCtl
Definition: xlog.c:701
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
char archiveCleanupCommand[MAXPGPATH]
Definition: xlog.c:631
bool EnableHotStandby
Definition: xlog.c:96
TimeLineID ThisTimeLineID
Definition: pg_control.h:37
int errmsg(const char *fmt,...)
Definition: elog.c:797
XLogRecPtr RedoRecPtr
Definition: xlog.c:542
XLogRecPtr lastCheckPointEndPtr
Definition: xlog.c:668
XLogRecPtr checkPoint
Definition: pg_control.h:132
XLogRecPtr redo
Definition: pg_control.h:35
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8334
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:175
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:170
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:812
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1709
bool DataChecksumsEnabled ( void  )

Definition at line 4704 of file xlog.c.

References Assert, ControlFileData::data_checksum_version, and NULL.

Referenced by PageIsVerified(), PageSetChecksumCopy(), PageSetChecksumInplace(), and ReadControlFile().

4705 {
4706  Assert(ControlFile != NULL);
4707  return (ControlFile->data_checksum_version > 0);
4708 }
uint32 data_checksum_version
Definition: pg_control.h:225
static ControlFileData * ControlFile
Definition: xlog.c:709
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
void do_pg_abort_backup ( void  )

Definition at line 11017 of file xlog.c.

References Assert, EXCLUSIVE_BACKUP_NONE, XLogCtlInsert::exclusiveBackupState, XLogCtlInsert::forcePageWrites, XLogCtlData::Insert, XLogCtlInsert::nonExclusiveBackups, WALInsertLockAcquireExclusive(), and WALInsertLockRelease().

Referenced by base_backup_cleanup(), and nonexclusive_base_backup_cleanup().

11018 {
11022 
11025  {
11026  XLogCtl->Insert.forcePageWrites = false;
11027  }
11029 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1636
XLogCtlInsert Insert
Definition: xlog.c:570
bool forcePageWrites
Definition: xlog.c:543
int nonExclusiveBackups
Definition: xlog.c:556
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:555
#define Assert(condition)
Definition: c.h:675
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1607
static XLogCtlData * XLogCtl
Definition: xlog.c:701
XLogRecPtr do_pg_start_backup ( const char *  backupidstr,
bool  fast,
TimeLineID starttli_p,
StringInfo  labelfile,
DIR tblspcdir,
List **  tablespaces,
StringInfo  tblspcmapfile,
bool  infotbssize,
bool  needtblspcmapfile 
)

Definition at line 10139 of file xlog.c.

References AllocateFile(), appendStringInfo(), appendStringInfoChar(), BACKUP_LABEL_FILE, backup_started_in_recovery, BoolGetDatum, ControlFileData::checkPoint, CHECKPOINT_FORCE, CHECKPOINT_IMMEDIATE, CHECKPOINT_WAIT, ControlFileData::checkPointCopy, dirent::d_name, StringInfoData::data, DataDir, ereport, errcode(), errcode_for_file_access(), errhint(), errmsg(), ERROR, EXCLUSIVE_BACKUP_IN_PROGRESS, EXCLUSIVE_BACKUP_NONE, EXCLUSIVE_BACKUP_STARTING, XLogCtlInsert::exclusiveBackupState, XLogCtlInsert::forcePageWrites, FreeFile(), CheckPoint::fullPageWrites, XLogCtlData::info_lck, initStringInfo(), XLogCtlData::Insert, IS_DIR_SEP, lappend(), XLogCtlInsert::lastBackupStart, XLogCtlData::lastFpwDisableRecPtr, StringInfoData::len, log_timezone, LW_SHARED, LWLockAcquire(), LWLockRelease(), makeStringInfo(), MAXFNAMELEN, MAXPGPATH, XLogCtlInsert::nonExclusiveBackups, NULL, tablespaceinfo::oid, palloc(), tablespaceinfo::path, pfree(), PG_END_ENSURE_ERROR_CLEANUP, PG_ENSURE_ERROR_CLEANUP, pg_fsync(), pg_localtime(), pg_start_backup_callback(), pg_strftime(), pstrdup(), ReadDir(), RecoveryInProgress(), CheckPoint::redo, relpath, RequestCheckpoint(), RequestXLogSwitch(), tablespaceinfo::rpath, sendTablespace(), tablespaceinfo::size, snprintf(), SpinLockAcquire, SpinLockRelease, TABLESPACE_MAP, CheckPoint::ThisTimeLineID, WALInsertLockAcquireExclusive(), WALInsertLockRelease(), WARNING, XLByteToSeg, XLogFileName, and XLogIsNeeded.

Referenced by perform_base_backup(), and pg_start_backup().

10143 {
10144  bool exclusive = (labelfile == NULL);
10145  bool backup_started_in_recovery = false;
10146  XLogRecPtr checkpointloc;
10147  XLogRecPtr startpoint;
10148  TimeLineID starttli;
10149  pg_time_t stamp_time;
10150  char strfbuf[128];
10151  char xlogfilename[MAXFNAMELEN];
10152  XLogSegNo _logSegNo;
10153  struct stat stat_buf;
10154  FILE *fp;
10155 
10156  backup_started_in_recovery = RecoveryInProgress();
10157 
10158  /*
10159  * Currently only non-exclusive backup can be taken during recovery.
10160  */
10161  if (backup_started_in_recovery && exclusive)
10162  ereport(ERROR,
10163  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10164  errmsg("recovery is in progress"),
10165  errhint("WAL control functions cannot be executed during recovery.")));
10166 
10167  /*
10168  * During recovery, we don't need to check WAL level. Because, if WAL
10169  * level is not sufficient, it's impossible to get here during recovery.
10170  */
10171  if (!backup_started_in_recovery && !XLogIsNeeded())
10172  ereport(ERROR,
10173  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10174  errmsg("WAL level not sufficient for making an online backup"),
10175  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
10176 
10177  if (strlen(backupidstr) > MAXPGPATH)
10178  ereport(ERROR,
10179  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
10180  errmsg("backup label too long (max %d bytes)",
10181  MAXPGPATH)));
10182 
10183  /*
10184  * Mark backup active in shared memory. We must do full-page WAL writes
10185  * during an on-line backup even if not doing so at other times, because
10186  * it's quite possible for the backup dump to obtain a "torn" (partially
10187  * written) copy of a database page if it reads the page concurrently with
10188  * our write to the same page. This can be fixed as long as the first
10189  * write to the page in the WAL sequence is a full-page write. Hence, we
10190  * turn on forcePageWrites and then force a CHECKPOINT, to ensure there
10191  * are no dirty pages in shared memory that might get dumped while the
10192  * backup is in progress without having a corresponding WAL record. (Once
10193  * the backup is complete, we need not force full-page writes anymore,
10194  * since we expect that any pages not modified during the backup interval
10195  * must have been correctly captured by the backup.)
10196  *
10197  * Note that forcePageWrites has no effect during an online backup from
10198  * the standby.
10199  *
10200  * We must hold all the insertion locks to change the value of
10201  * forcePageWrites, to ensure adequate interlocking against
10202  * XLogInsertRecord().
10203  */
10205  if (exclusive)
10206  {
10207  /*
10208  * At first, mark that we're now starting an exclusive backup,
10209  * to ensure that there are no other sessions currently running
10210  * pg_start_backup() or pg_stop_backup().
10211  */
10213  {
10215  ereport(ERROR,
10216  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10217  errmsg("a backup is already in progress"),
10218  errhint("Run pg_stop_backup() and try again.")));
10219  }
10221  }
10222  else
10224  XLogCtl->Insert.forcePageWrites = true;
10226 
10227  /* Ensure we release forcePageWrites if fail below */
10229  {
10230  bool gotUniqueStartpoint = false;
10231  struct dirent *de;
10232  tablespaceinfo *ti;
10233  int datadirpathlen;
10234 
10235  /*
10236  * Force an XLOG file switch before the checkpoint, to ensure that the
10237  * WAL segment the checkpoint is written to doesn't contain pages with
10238  * old timeline IDs. That would otherwise happen if you called
10239  * pg_start_backup() right after restoring from a PITR archive: the
10240  * first WAL segment containing the startup checkpoint has pages in
10241  * the beginning with the old timeline ID. That can cause trouble at
10242  * recovery: we won't have a history file covering the old timeline if
10243  * pg_wal directory was not included in the base backup and the WAL
10244  * archive was cleared too before starting the backup.
10245  *
10246  * This also ensures that we have emitted a WAL page header that has
10247  * XLP_BKP_REMOVABLE off before we emit the checkpoint record.
10248  * Therefore, if a WAL archiver (such as pglesslog) is trying to
10249  * compress out removable backup blocks, it won't remove any that
10250  * occur after this point.
10251  *
10252  * During recovery, we skip forcing XLOG file switch, which means that
10253  * the backup taken during recovery is not available for the special
10254  * recovery case described above.
10255  */
10256  if (!backup_started_in_recovery)
10257  RequestXLogSwitch(false);
10258 
10259  do
10260  {
10261  bool checkpointfpw;
10262 
10263  /*
10264  * Force a CHECKPOINT. Aside from being necessary to prevent torn
10265  * page problems, this guarantees that two successive backup runs
10266  * will have different checkpoint positions and hence different
10267  * history file names, even if nothing happened in between.
10268  *
10269  * During recovery, establish a restartpoint if possible. We use
10270  * the last restartpoint as the backup starting checkpoint. This
10271  * means that two successive backup runs can have same checkpoint
10272  * positions.
10273  *
10274  * Since the fact that we are executing do_pg_start_backup()
10275  * during recovery means that checkpointer is running, we can use
10276  * RequestCheckpoint() to establish a restartpoint.
10277  *
10278  * We use CHECKPOINT_IMMEDIATE only if requested by user (via
10279  * passing fast = true). Otherwise this can take awhile.
10280  */
10282  (fast ? CHECKPOINT_IMMEDIATE : 0));
10283 
10284  /*
10285  * Now we need to fetch the checkpoint record location, and also
10286  * its REDO pointer. The oldest point in WAL that would be needed
10287  * to restore starting from the checkpoint is precisely the REDO
10288  * pointer.
10289  */
10290  LWLockAcquire(ControlFileLock, LW_SHARED);
10291  checkpointloc = ControlFile->checkPoint;
10292  startpoint = ControlFile->checkPointCopy.redo;
10294  checkpointfpw = ControlFile->checkPointCopy.fullPageWrites;
10295  LWLockRelease(ControlFileLock);
10296 
10297  if (backup_started_in_recovery)
10298  {
10299  XLogRecPtr recptr;
10300 
10301  /*
10302  * Check to see if all WAL replayed during online backup
10303  * (i.e., since last restartpoint used as backup starting
10304  * checkpoint) contain full-page writes.
10305  */
10307  recptr = XLogCtl->lastFpwDisableRecPtr;
10309 
10310  if (!checkpointfpw || startpoint <= recptr)
10311  ereport(ERROR,
10312  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10313  errmsg("WAL generated with full_page_writes=off was replayed "
10314  "since last restartpoint"),
10315  errhint("This means that the backup being taken on the standby "
10316  "is corrupt and should not be used. "
10317  "Enable full_page_writes and run CHECKPOINT on the master, "
10318  "and then try an online backup again.")));
10319 
10320  /*
10321  * During recovery, since we don't use the end-of-backup WAL
10322  * record and don't write the backup history file, the
10323  * starting WAL location doesn't need to be unique. This means
10324  * that two base backups started at the same time might use
10325  * the same checkpoint as starting locations.
10326  */
10327  gotUniqueStartpoint = true;
10328  }
10329 
10330  /*
10331  * If two base backups are started at the same time (in WAL sender
10332  * processes), we need to make sure that they use different
10333  * checkpoints as starting locations, because we use the starting
10334  * WAL location as a unique identifier for the base backup in the
10335  * end-of-backup WAL record and when we write the backup history
10336  * file. Perhaps it would be better generate a separate unique ID
10337  * for each backup instead of forcing another checkpoint, but
10338  * taking a checkpoint right after another is not that expensive
10339  * either because only few buffers have been dirtied yet.
10340  */
10342  if (XLogCtl->Insert.lastBackupStart < startpoint)
10343  {
10344  XLogCtl->Insert.lastBackupStart = startpoint;
10345  gotUniqueStartpoint = true;
10346  }
10348  } while (!gotUniqueStartpoint);
10349 
10350  XLByteToSeg(startpoint, _logSegNo);
10351  XLogFileName(xlogfilename, starttli, _logSegNo);
10352 
10353  /*
10354  * Construct tablespace_map file
10355  */
10356  if (exclusive)
10357  tblspcmapfile = makeStringInfo();
10358 
10359  datadirpathlen = strlen(DataDir);
10360 
10361  /* Collect information about all tablespaces */
10362  while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL)
10363  {
10364  char fullpath[MAXPGPATH];
10365  char linkpath[MAXPGPATH];
10366  char *relpath = NULL;
10367  int rllen;
10368  StringInfoData buflinkpath;
10369  char *s = linkpath;
10370 
10371  /* Skip special stuff */
10372  if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
10373  continue;
10374 
10375  snprintf(fullpath, sizeof(fullpath), "pg_tblspc/%s", de->d_name);
10376 
10377 #if defined(HAVE_READLINK) || defined(WIN32)
10378  rllen = readlink(fullpath, linkpath, sizeof(linkpath));
10379  if (rllen < 0)
10380  {
10381  ereport(WARNING,
10382  (errmsg("could not read symbolic link \"%s\": %m",
10383  fullpath)));
10384  continue;
10385  }
10386  else if (rllen >= sizeof(linkpath))
10387  {
10388  ereport(WARNING,
10389  (errmsg("symbolic link \"%s\" target is too long",
10390  fullpath)));
10391  continue;
10392  }
10393  linkpath[rllen] = '\0';
10394 
10395  /*
10396  * Add the escape character '\\' before newline in a string to
10397  * ensure that we can distinguish between the newline in the
10398  * tablespace path and end of line while reading tablespace_map
10399  * file during archive recovery.
10400  */
10401  initStringInfo(&buflinkpath);
10402 
10403  while (*s)
10404  {
10405  if ((*s == '\n' || *s == '\r') && needtblspcmapfile)
10406  appendStringInfoChar(&buflinkpath, '\\');
10407  appendStringInfoChar(&buflinkpath, *s++);
10408  }
10409 
10410 
10411  /*
10412  * Relpath holds the relative path of the tablespace directory
10413  * when it's located within PGDATA, or NULL if it's located
10414  * elsewhere.
10415  */
10416  if (rllen > datadirpathlen &&
10417  strncmp(linkpath, DataDir, datadirpathlen) == 0 &&
10418  IS_DIR_SEP(linkpath[datadirpathlen]))
10419  relpath = linkpath + datadirpathlen + 1;
10420 
10421  ti = palloc(sizeof(tablespaceinfo));
10422  ti->oid = pstrdup(de->d_name);
10423  ti->path = pstrdup(buflinkpath.data);
10424  ti->rpath = relpath ? pstrdup(relpath) : NULL;
10425  ti->size = infotbssize ? sendTablespace(fullpath, true) : -1;
10426 
10427  if (tablespaces)
10428  *tablespaces = lappend(*tablespaces, ti);
10429 
10430  appendStringInfo(tblspcmapfile, "%s %s\n", ti->oid, ti->path);
10431 
10432  pfree(buflinkpath.data);
10433 #else
10434 
10435  /*
10436  * If the platform does not have symbolic links, it should not be
10437  * possible to have tablespaces - clearly somebody else created
10438  * them. Warn about it and ignore.
10439  */
10440  ereport(WARNING,
10441  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
10442  errmsg("tablespaces are not supported on this platform")));
10443 #endif
10444  }
10445 
10446  /*
10447  * Construct backup label file
10448  */
10449  if (exclusive)
10450  labelfile = makeStringInfo();
10451 
10452  /* Use the log timezone here, not the session timezone */
10453  stamp_time = (pg_time_t) time(NULL);
10454  pg_strftime(strfbuf, sizeof(strfbuf),
10455  "%Y-%m-%d %H:%M:%S %Z",
10456  pg_localtime(&stamp_time, log_timezone));
10457  appendStringInfo(labelfile, "START WAL LOCATION: %X/%X (file %s)\n",
10458  (uint32) (startpoint >> 32), (uint32) startpoint, xlogfilename);
10459  appendStringInfo(labelfile, "CHECKPOINT LOCATION: %X/%X\n",
10460  (uint32) (checkpointloc >> 32), (uint32) checkpointloc);
10461  appendStringInfo(labelfile, "BACKUP METHOD: %s\n",
10462  exclusive ? "pg_start_backup" : "streamed");
10463  appendStringInfo(labelfile, "BACKUP FROM: %s\n",
10464  backup_started_in_recovery ? "standby" : "master");
10465  appendStringInfo(labelfile, "START TIME: %s\n", strfbuf);
10466  appendStringInfo(labelfile, "LABEL: %s\n", backupidstr);
10467 
10468  /*
10469  * Okay, write the file, or return its contents to caller.
10470  */
10471  if (exclusive)
10472  {
10473  /*
10474  * Check for existing backup label --- implies a backup is already
10475  * running. (XXX given that we checked exclusiveBackupState above,
10476  * maybe it would be OK to just unlink any such label file?)
10477  */
10478  if (stat(BACKUP_LABEL_FILE, &stat_buf) != 0)
10479  {
10480  if (errno != ENOENT)
10481  ereport(ERROR,
10483  errmsg("could not stat file \"%s\": %m",
10484  BACKUP_LABEL_FILE)));
10485  }
10486  else
10487  ereport(ERROR,
10488  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10489  errmsg("a backup is already in progress"),
10490  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
10491  BACKUP_LABEL_FILE)));
10492 
10493  fp = AllocateFile(BACKUP_LABEL_FILE, "w");
10494 
10495  if (!fp)
10496  ereport(ERROR,
10498  errmsg("could not create file \"%s\": %m",
10499  BACKUP_LABEL_FILE)));
10500  if (fwrite(labelfile->data, labelfile->len, 1, fp) != 1 ||
10501  fflush(fp) != 0 ||
10502  pg_fsync(fileno(fp)) != 0 ||
10503  ferror(fp) ||
10504  FreeFile(fp))
10505  ereport(ERROR,
10507  errmsg("could not write file \"%s\": %m",
10508  BACKUP_LABEL_FILE)));
10509  /* Allocated locally for exclusive backups, so free separately */
10510  pfree(labelfile->data);
10511  pfree(labelfile);
10512 
10513  /* Write backup tablespace_map file. */
10514  if (tblspcmapfile->len > 0)
10515  {
10516  if (stat(TABLESPACE_MAP, &stat_buf) != 0)
10517  {
10518  if (errno != ENOENT)
10519  ereport(ERROR,
10521  errmsg("could not stat file \"%s\": %m",
10522  TABLESPACE_MAP)));
10523  }
10524  else
10525  ereport(ERROR,
10526  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10527  errmsg("a backup is already in progress"),
10528  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
10529  TABLESPACE_MAP)));
10530 
10531  fp = AllocateFile(TABLESPACE_MAP, "w");
10532 
10533  if (!fp)
10534  ereport(ERROR,
10536  errmsg("could not create file \"%s\": %m",
10537  TABLESPACE_MAP)));
10538  if (fwrite(tblspcmapfile->data, tblspcmapfile->len, 1, fp) != 1 ||
10539  fflush(fp) != 0 ||
10540  pg_fsync(fileno(fp)) != 0 ||
10541  ferror(fp) ||
10542  FreeFile(fp))
10543  ereport(ERROR,
10545  errmsg("could not write file \"%s\": %m",
10546  TABLESPACE_MAP)));
10547  }
10548 
10549  /* Allocated locally for exclusive backups, so free separately */
10550  pfree(tblspcmapfile->data);
10551  pfree(tblspcmapfile);
10552  }
10553  }
10555 
10556  /*
10557  * Mark that start phase has correctly finished for an exclusive backup.
10558  */
10559  if (exclusive)
10560  {
10564  }
10565 
10566  /*
10567  * We're done. As a convenience, return the starting WAL location.
10568  */
10569  if (starttli_p)
10570  *starttli_p = starttli;
10571  return startpoint;
10572 }
size_t pg_strftime(char *s, size_t max, const char *format, const struct pg_tm *tm)
Definition: strftime.c:123
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9372
int errhint(const char *fmt,...)
Definition: elog.c:987
uint32 TimeLineID
Definition: xlogdefs.h:45
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1636
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:696
XLogRecPtr lastBackupStart
Definition: xlog.c:557
char * pstrdup(const char *in)
Definition: mcxt.c:1077
#define XLogIsNeeded()
Definition: xlog.h:145
char * rpath
Definition: basebackup.h:28
StringInfo makeStringInfo(void)
Definition: stringinfo.c:29
slock_t info_lck
Definition: xlog.c:698
#define XLogFileName(fname, tli, logSegNo)
int errcode(int sqlerrcode)
Definition: elog.c:575
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
CheckPoint checkPointCopy
Definition: pg_control.h:135
XLogCtlInsert Insert
Definition: xlog.c:570
bool RecoveryInProgress(void)
Definition: xlog.c:7855
static bool backup_started_in_recovery
Definition: basebackup.c:73
Definition: dirent.h:9
#define IS_DIR_SEP(ch)
Definition: port.h:75
pg_tz * log_timezone
Definition: pgtz.c:30
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
#define TABLESPACE_MAP
Definition: xlog.h:305
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:47
void pfree(void *pointer)
Definition: mcxt.c:950
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
bool forcePageWrites
Definition: xlog.c:543
#define ERROR
Definition: elog.h:43
struct stat stat_buf
Definition: pg_standby.c:101
#define MAXPGPATH
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errcode_for_file_access(void)
Definition: elog.c:598
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2057
unsigned int uint32
Definition: c.h:268
int64 sendTablespace(char *path, bool sizeonly)
Definition: basebackup.c:906
#define CHECKPOINT_FORCE
Definition: xlog.h:180
#define ereport(elevel, rest)
Definition: elog.h:122
List * lappend(List *list, void *datum)
Definition: list.c:128
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:201
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#define WARNING
Definition: elog.h:40
int nonExclusiveBackups
Definition: xlog.c:556
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
static void pg_start_backup_callback(int code, Datum arg)
Definition: xlog.c:10576
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:555
uintptr_t Datum
Definition: postgres.h:372
static ControlFileData * ControlFile
Definition: xlog.c:709
#define BoolGetDatum(X)
Definition: postgres.h:408
bool fullPageWrites
Definition: pg_control.h:40
#define CHECKPOINT_WAIT
Definition: xlog.h:184
#define XLByteToSeg(xlrp, logSegNo)
#define NULL
Definition: c.h:229
uint64 XLogRecPtr
Definition: xlogdefs.h:21
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2364
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1607
static XLogCtlData * XLogCtl
Definition: xlog.c:701
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:52
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1254
int FreeFile(FILE *file)
Definition: fd.c:2240
void * palloc(Size size)
Definition: mcxt.c:849
TimeLineID ThisTimeLineID
Definition: pg_control.h:37
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:179
#define relpath(rnode, forknum)
Definition: relpath.h:71
char * DataDir
Definition: globals.c:59
#define BACKUP_LABEL_FILE
Definition: xlog.h:302
int pg_fsync(int fd)
Definition: fd.c:333
char d_name[MAX_PATH]
Definition: dirent.h:14
XLogRecPtr checkPoint
Definition: pg_control.h:132
XLogRecPtr redo
Definition: pg_control.h:35
void RequestCheckpoint(int flags)
Definition: checkpointer.c:967
XLogRecPtr do_pg_stop_backup ( char *  labelfile,
bool  waitforarchive,
TimeLineID stoptli_p 
)

Definition at line 10633 of file xlog.c.

References AllocateFile(), Assert, BACKUP_LABEL_FILE, backup_started_in_recovery, BackupHistoryFileName, BackupHistoryFilePath, BoolGetDatum, CHECK_FOR_INTERRUPTS, CleanupBackupHistory(), ereport, errcode(), errcode_for_file_access(), errhint(), errmsg(), ERROR, EXCLUSIVE_BACKUP_IN_PROGRESS, EXCLUSIVE_BACKUP_NONE, EXCLUSIVE_BACKUP_STOPPING, XLogCtlInsert::exclusiveBackupState, XLogCtlInsert::forcePageWrites, FreeFile(), XLogCtlData::info_lck, XLogCtlData::Insert, XLogCtlData::lastFpwDisableRecPtr, log_timezone, LW_SHARED, LWLockAcquire(), LWLockRelease(), MAXFNAMELEN, MAXPGPATH, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, XLogCtlInsert::nonExclusiveBackups, NOTICE, NULL, palloc(), PG_END_ENSURE_ERROR_CLEANUP, PG_ENSURE_ERROR_CLEANUP, pg_localtime(), pg_stop_backup_callback(), pg_strftime(), pg_usleep(), RecoveryInProgress(), remaining, RequestXLogSwitch(), SpinLockAcquire, SpinLockRelease, TABLESPACE_MAP, ThisTimeLineID, unlink(), WALInsertLockAcquireExclusive(), WALInsertLockRelease(), WARNING, XLByteToPrevSeg, XLByteToSeg, XLOG_BACKUP_END, XLogArchiveIsBusy(), XLogArchivingActive, XLogBeginInsert(), XLogFileName, XLogInsert(), XLogIsNeeded, XLogRegisterData(), and XLogSegSize.

Referenced by perform_base_backup(), pg_stop_backup(), and pg_stop_backup_v2().

10634 {
10635  bool exclusive = (labelfile == NULL);
10636  bool backup_started_in_recovery = false;
10637  XLogRecPtr startpoint;
10638  XLogRecPtr stoppoint;
10639  TimeLineID stoptli;
10640  pg_time_t stamp_time;
10641  char strfbuf[128];
10642  char histfilepath[MAXPGPATH];
10643  char startxlogfilename[MAXFNAMELEN];
10644  char stopxlogfilename[MAXFNAMELEN];
10645  char lastxlogfilename[MAXFNAMELEN];
10646  char histfilename[MAXFNAMELEN];
10647  char backupfrom[20];
10648  XLogSegNo _logSegNo;
10649  FILE *lfp;
10650  FILE *fp;
10651  char ch;
10652  int seconds_before_warning;
10653  int waits = 0;
10654  bool reported_waiting = false;
10655  char *remaining;
10656  char *ptr;
10657  uint32 hi,
10658  lo;
10659 
10660  backup_started_in_recovery = RecoveryInProgress();
10661 
10662  /*
10663  * Currently only non-exclusive backup can be taken during recovery.
10664  */
10665  if (backup_started_in_recovery && exclusive)
10666  ereport(ERROR,
10667  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10668  errmsg("recovery is in progress"),
10669  errhint("WAL control functions cannot be executed during recovery.")));
10670 
10671  /*
10672  * During recovery, we don't need to check WAL level. Because, if WAL
10673  * level is not sufficient, it's impossible to get here during recovery.
10674  */
10675  if (!backup_started_in_recovery && !XLogIsNeeded())
10676  ereport(ERROR,
10677  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10678  errmsg("WAL level not sufficient for making an online backup"),
10679  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
10680 
10681  if (exclusive)
10682  {
10683  /*
10684  * At first, mark that we're now stopping an exclusive backup,
10685  * to ensure that there are no other sessions currently running
10686  * pg_start_backup() or pg_stop_backup().
10687  */
10690  {
10692  ereport(ERROR,
10693  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10694  errmsg("exclusive backup not in progress")));
10695  }
10698 
10699  /*
10700  * Remove backup_label. In case of failure, the state for an exclusive
10701  * backup is switched back to in-progress.
10702  */
10704  {
10705  /*
10706  * Read the existing label file into memory.
10707  */
10708  struct stat statbuf;
10709  int r;
10710 
10711  if (stat(BACKUP_LABEL_FILE, &statbuf))
10712  {
10713  /* should not happen per the upper checks */
10714  if (errno != ENOENT)
10715  ereport(ERROR,
10717  errmsg("could not stat file \"%s\": %m",
10718  BACKUP_LABEL_FILE)));
10719  ereport(ERROR,
10720  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10721  errmsg("a backup is not in progress")));
10722  }
10723 
10724  lfp = AllocateFile(BACKUP_LABEL_FILE, "r");
10725  if (!lfp)
10726  {
10727  ereport(ERROR,
10729  errmsg("could not read file \"%s\": %m",
10730  BACKUP_LABEL_FILE)));
10731  }
10732  labelfile = palloc(statbuf.st_size + 1);
10733  r = fread(labelfile, statbuf.st_size, 1, lfp);
10734  labelfile[statbuf.st_size] = '\0';
10735 
10736  /*
10737  * Close and remove the backup label file
10738  */
10739  if (r != 1 || ferror(lfp) || FreeFile(lfp))
10740  ereport(ERROR,
10742  errmsg("could not read file \"%s\": %m",
10743  BACKUP_LABEL_FILE)));
10744  if (unlink(BACKUP_LABEL_FILE) != 0)
10745  ereport(ERROR,
10747  errmsg("could not remove file \"%s\": %m",
10748  BACKUP_LABEL_FILE)));
10749 
10750  /*
10751  * Remove tablespace_map file if present, it is created only if there
10752  * are tablespaces.
10753  */
10755  }
10757  }
10758 
10759  /*
10760  * OK to update backup counters and forcePageWrites
10761  */
10763  if (exclusive)
10764  {
10766  }
10767  else
10768  {
10769  /*
10770  * The user-visible pg_start/stop_backup() functions that operate on
10771  * exclusive backups can be called at any time, but for non-exclusive
10772  * backups, it is expected that each do_pg_start_backup() call is
10773  * matched by exactly one do_pg_stop_backup() call.
10774  */
10777  }
10778 
10781  {
10782  XLogCtl->Insert.forcePageWrites = false;
10783  }
10785 
10786  /*
10787  * Read and parse the START WAL LOCATION line (this code is pretty crude,
10788  * but we are not expecting any variability in the file format).
10789  */
10790  if (sscanf(labelfile, "START WAL LOCATION: %X/%X (file %24s)%c",
10791  &hi, &lo, startxlogfilename,
10792  &ch) != 4 || ch != '\n')
10793  ereport(ERROR,
10794  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10795  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
10796  startpoint = ((uint64) hi) << 32 | lo;
10797  remaining = strchr(labelfile, '\n') + 1; /* %n is not portable enough */
10798 
10799  /*
10800  * Parse the BACKUP FROM line. If we are taking an online backup from the
10801  * standby, we confirm that the standby has not been promoted during the
10802  * backup.
10803  */
10804  ptr = strstr(remaining, "BACKUP FROM:");
10805  if (!ptr || sscanf(ptr, "BACKUP FROM: %19s\n", backupfrom) != 1)
10806  ereport(ERROR,
10807  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10808  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
10809  if (strcmp(backupfrom, "standby") == 0 && !backup_started_in_recovery)
10810  ereport(ERROR,
10811  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10812  errmsg("the standby was promoted during online backup"),
10813  errhint("This means that the backup being taken is corrupt "
10814  "and should not be used. "
10815  "Try taking another online backup.")));
10816 
10817  /*
10818  * During recovery, we don't write an end-of-backup record. We assume that
10819  * pg_control was backed up last and its minimum recovery point can be
10820  * available as the backup end location. Since we don't have an
10821  * end-of-backup record, we use the pg_control value to check whether
10822  * we've reached the end of backup when starting recovery from this
10823  * backup. We have no way of checking if pg_control wasn't backed up last
10824  * however.
10825  *
10826  * We don't force a switch to new WAL file and wait for all the required
10827  * files to be archived. This is okay if we use the backup to start the
10828  * standby. But, if it's for an archive recovery, to ensure all the
10829  * required files are available, a user should wait for them to be
10830  * archived, or include them into the backup.
10831  *
10832  * We return the current minimum recovery point as the backup end
10833  * location. Note that it can be greater than the exact backup end
10834  * location if the minimum recovery point is updated after the backup of
10835  * pg_control. This is harmless for current uses.
10836  *
10837  * XXX currently a backup history file is for informational and debug
10838  * purposes only. It's not essential for an online backup. Furthermore,
10839  * even if it's created, it will not be archived during recovery because
10840  * an archiver is not invoked. So it doesn't seem worthwhile to write a
10841  * backup history file during recovery.
10842  */
10843  if (backup_started_in_recovery)
10844  {
10845  XLogRecPtr recptr;
10846 
10847  /*
10848  * Check to see if all WAL replayed during online backup contain
10849  * full-page writes.
10850  */
10852  recptr = XLogCtl->lastFpwDisableRecPtr;
10854 
10855  if (startpoint <= recptr)
10856  ereport(ERROR,
10857  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10858  errmsg("WAL generated with full_page_writes=off was replayed "
10859  "during online backup"),
10860  errhint("This means that the backup being taken on the standby "
10861  "is corrupt and should not be used. "
10862  "Enable full_page_writes and run CHECKPOINT on the master, "
10863  "and then try an online backup again.")));
10864 
10865 
10866  LWLockAcquire(ControlFileLock, LW_SHARED);
10867  stoppoint = ControlFile->minRecoveryPoint;
10868  stoptli = ControlFile->minRecoveryPointTLI;
10869  LWLockRelease(ControlFileLock);
10870 
10871  if (stoptli_p)
10872  *stoptli_p = stoptli;
10873  return stoppoint;
10874  }
10875 
10876  /*
10877  * Write the backup-end xlog record
10878  */
10879  XLogBeginInsert();
10880  XLogRegisterData((char *) (&startpoint), sizeof(startpoint));
10881  stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
10882  stoptli = ThisTimeLineID;
10883 
10884  /*
10885  * Force a switch to a new xlog segment file, so that the backup is valid
10886  * as soon as archiver moves out the current segment file.
10887  */
10888  RequestXLogSwitch(false);
10889 
10890  XLByteToPrevSeg(stoppoint, _logSegNo);
10891  XLogFileName(stopxlogfilename, ThisTimeLineID, _logSegNo);
10892 
10893  /* Use the log timezone here, not the session timezone */
10894  stamp_time = (pg_time_t) time(NULL);
10895  pg_strftime(strfbuf, sizeof(strfbuf),
10896  "%Y-%m-%d %H:%M:%S %Z",
10897  pg_localtime(&stamp_time, log_timezone));
10898 
10899  /*
10900  * Write the backup history file
10901  */
10902  XLByteToSeg(startpoint, _logSegNo);
10903  BackupHistoryFilePath(histfilepath, ThisTimeLineID, _logSegNo,
10904  (uint32) (startpoint % XLogSegSize));
10905  fp = AllocateFile(histfilepath, "w");
10906  if (!fp)
10907  ereport(ERROR,
10909  errmsg("could not create file \"%s\": %m",
10910  histfilepath)));
10911  fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n",
10912  (uint32) (startpoint >> 32), (uint32) startpoint, startxlogfilename);
10913  fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
10914  (uint32) (stoppoint >> 32), (uint32) stoppoint, stopxlogfilename);
10915  /* transfer remaining lines from label to history file */
10916  fprintf(fp, "%s", remaining);
10917  fprintf(fp, "STOP TIME: %s\n", strfbuf);
10918  if (fflush(fp) || ferror(fp) || FreeFile(fp))
10919  ereport(ERROR,
10921  errmsg("could not write file \"%s\": %m",
10922  histfilepath)));
10923 
10924  /*
10925  * Clean out any no-longer-needed history files. As a side effect, this
10926  * will post a .ready file for the newly created history file, notifying
10927  * the archiver that history file may be archived immediately.
10928  */
10930 
10931  /*
10932  * If archiving is enabled, wait for all the required WAL files to be
10933  * archived before returning. If archiving isn't enabled, the required WAL
10934  * needs to be transported via streaming replication (hopefully with
10935  * wal_keep_segments set high enough), or some more exotic mechanism like
10936  * polling and copying files from pg_wal with script. We have no
10937  * knowledge of those mechanisms, so it's up to the user to ensure that he
10938  * gets all the required WAL.
10939  *
10940  * We wait until both the last WAL file filled during backup and the
10941  * history file have been archived, and assume that the alphabetic sorting
10942  * property of the WAL files ensures any earlier WAL files are safely
10943  * archived as well.
10944  *
10945  * We wait forever, since archive_command is supposed to work and we
10946  * assume the admin wanted his backup to work completely. If you don't
10947  * wish to wait, then either waitforarchive should be passed in as false,
10948  * or you can set statement_timeout. Also, some notices are
10949  * issued to clue in anyone who might be doing this interactively.
10950  */
10951  if (waitforarchive && XLogArchivingActive())
10952  {
10953  XLByteToPrevSeg(stoppoint, _logSegNo);
10954  XLogFileName(lastxlogfilename, ThisTimeLineID, _logSegNo);
10955 
10956  XLByteToSeg(startpoint, _logSegNo);
10957  BackupHistoryFileName(histfilename, ThisTimeLineID, _logSegNo,
10958  (uint32) (startpoint % XLogSegSize));
10959 
10960  seconds_before_warning = 60;
10961  waits = 0;
10962 
10963  while (XLogArchiveIsBusy(lastxlogfilename) ||
10964  XLogArchiveIsBusy(histfilename))
10965  {
10967 
10968  if (!reported_waiting && waits > 5)
10969  {
10970  ereport(NOTICE,
10971  (errmsg("pg_stop_backup cleanup done, waiting for required WAL segments to be archived")));
10972  reported_waiting = true;
10973  }
10974 
10975  pg_usleep(1000000L);
10976 
10977  if (++waits >= seconds_before_warning)
10978  {
10979  seconds_before_warning *= 2; /* This wraps in >10 years... */
10980  ereport(WARNING,
10981  (errmsg("pg_stop_backup still waiting for all required WAL segments to be archived (%d seconds elapsed)",
10982  waits),
10983  errhint("Check that your archive_command is executing properly. "
10984  "pg_stop_backup can be canceled safely, "
10985  "but the database backup will not be usable without all the WAL segments.")));
10986  }
10987  }
10988 
10989  ereport(NOTICE,
10990  (errmsg("pg_stop_backup complete, all required WAL segments have been archived")));
10991  }
10992  else if (waitforarchive)
10993  ereport(NOTICE,
10994  (errmsg("WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup")));
10995 
10996  /*
10997  * We're done. As a convenience, return the ending WAL location.
10998  */
10999  if (stoptli_p)
11000  *stoptli_p = stoptli;
11001  return stoppoint;
11002 }
int remaining
Definition: informix.c:692
size_t pg_strftime(char *s, size_t max, const char *format, const struct pg_tm *tm)
Definition: strftime.c:123
#define XLogSegSize
Definition: xlog_internal.h:92
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9372
int errhint(const char *fmt,...)
Definition: elog.c:987
uint32 TimeLineID
Definition: xlogdefs.h:45
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1636
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:171
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:696
#define XLogIsNeeded()
Definition: xlog.h:145
slock_t info_lck
Definition: xlog.c:698
#define XLogFileName(fname, tli, logSegNo)
int errcode(int sqlerrcode)
Definition: elog.c:575
XLogCtlInsert Insert
Definition: xlog.c:570
bool RecoveryInProgress(void)
Definition: xlog.c:7855
static bool backup_started_in_recovery
Definition: basebackup.c:73
pg_tz * log_timezone
Definition: pgtz.c:30
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
#define TABLESPACE_MAP
Definition: xlog.h:305
#define SpinLockAcquire(lock)
Definition: spin.h:62
void pg_usleep(long microsec)
Definition: signal.c:53
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:47
bool forcePageWrites
Definition: xlog.c:543
#define ERROR
Definition: elog.h:43
static void CleanupBackupHistory(void)
Definition: xlog.c:4094
#define MAXPGPATH
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errcode_for_file_access(void)
Definition: elog.c:598
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2057
unsigned int uint32
Definition: c.h:268
#define XLByteToPrevSeg(xlrp, logSegNo)
int unlink(const char *filename)
#define ereport(elevel, rest)
Definition: elog.h:122
#define XLOG_BACKUP_END
Definition: pg_control.h:71
#define WARNING
Definition: elog.h:40
int nonExclusiveBackups
Definition: xlog.c:556
#define MAXFNAMELEN
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
#define SpinLockRelease(lock)
Definition: spin.h:64
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:555
uintptr_t Datum
Definition: postgres.h:372
static ControlFileData * ControlFile
Definition: xlog.c:709
#define BoolGetDatum(X)
Definition: postgres.h:408
TimeLineID ThisTimeLineID
Definition: xlog.c:179
#define NOTICE
Definition: elog.h:37
#define XLByteToSeg(xlrp, logSegNo)
bool XLogArchiveIsBusy(const char *xlog)
Definition: xlogarchive.c:657
#define NULL
Definition: c.h:229
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:675
#define XLogArchivingActive()
Definition: xlog.h:134
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1607
static XLogCtlData * XLogCtl
Definition: xlog.c:701
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
static void pg_stop_backup_callback(int code, Datum arg)
Definition: xlog.c:10605
#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:52
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1254
int FreeFile(FILE *file)
Definition: fd.c:2240
void * palloc(Size size)
Definition: mcxt.c:849
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define BackupHistoryFilePath(path, tli, logSegNo, offset)
#define BACKUP_LABEL_FILE
Definition: xlog.h:302
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:97
void XLogBeginInsert(void)
Definition: xloginsert.c:120
#define BackupHistoryFileName(fname, tli, logSegNo, offset)
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:170
static int emode_for_corrupt_record ( int  emode,
XLogRecPtr  RecPtr 
)
static

Definition at line 11924 of file xlog.c.

References DEBUG1, LOG, readSource, and XLOG_FROM_PG_WAL.

Referenced by ReadRecord(), and XLogPageRead().

11925 {
11926  static XLogRecPtr lastComplaint = 0;
11927 
11928  if (readSource == XLOG_FROM_PG_WAL && emode == LOG)
11929  {
11930  if (RecPtr == lastComplaint)
11931  emode = DEBUG1;
11932  else
11933  lastComplaint = RecPtr;
11934  }
11935  return emode;
11936 }
#define DEBUG1
Definition: elog.h:25
static XLogSource readSource
Definition: xlog.c:778
#define LOG
Definition: elog.h:26
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static void exitArchiveRecovery ( TimeLineID  endTLI,
XLogRecPtr  endOfLog 
)
static

Definition at line 5458 of file xlog.c.

References Assert, close, durable_rename(), ereport, errcode_for_file_access(), errmsg(), ERROR, FATAL, fd(), InArchiveRecovery, InvalidXLogRecPtr, LOG, MAXFNAMELEN, MAXPGPATH, readFile, RECOVERY_COMMAND_DONE, RECOVERY_COMMAND_FILE, snprintf(), ThisTimeLineID, unlink(), UpdateMinRecoveryPoint(), XLByteToPrevSeg, XLByteToSeg, XLogArchiveCleanup(), XLOGDIR, XLogFileCopy(), XLogFileInit(), XLogFileName, and XLogFileNameP().

Referenced by StartupXLOG().

5459 {
5460  char recoveryPath[MAXPGPATH];
5461  char xlogfname[MAXFNAMELEN];
5462  XLogSegNo endLogSegNo;
5463  XLogSegNo startLogSegNo;
5464 
5465  /* we always switch to a new timeline after archive recovery */
5466  Assert(endTLI != ThisTimeLineID);
5467 
5468  /*
5469  * We are no longer in archive recovery state.
5470  */
5471  InArchiveRecovery = false;
5472 
5473  /*
5474  * Update min recovery point one last time.
5475  */
5477 
5478  /*
5479  * If the ending log segment is still open, close it (to avoid problems on
5480  * Windows with trying to rename or delete an open file).
5481  */
5482  if (readFile >= 0)
5483  {
5484  close(readFile);
5485  readFile = -1;
5486  }
5487 
5488  /*
5489  * Calculate the last segment on the old timeline, and the first segment
5490  * on the new timeline. If the switch happens in the middle of a segment,
5491  * they are the same, but if the switch happens exactly at a segment
5492  * boundary, startLogSegNo will be endLogSegNo + 1.
5493  */
5494  XLByteToPrevSeg(endOfLog, endLogSegNo);
5495  XLByteToSeg(endOfLog, startLogSegNo);
5496 
5497  /*
5498  * Initialize the starting WAL segment for the new timeline. If the switch
5499  * happens in the middle of a segment, copy data from the last WAL segment
5500  * of the old timeline up to the switch point, to the starting WAL segment
5501  * on the new timeline.
5502  */
5503  if (endLogSegNo == startLogSegNo)
5504  {
5505  /*
5506  * Make a copy of the file on the new timeline.
5507  *
5508  * Writing WAL isn't allowed yet, so there are no locking
5509  * considerations. But we should be just as tense as XLogFileInit to
5510  * avoid emplacing a bogus file.
5511  */
5512  XLogFileCopy(endLogSegNo, endTLI, endLogSegNo,
5513  endOfLog % XLOG_SEG_SIZE);
5514  }
5515  else
5516  {
5517  /*
5518  * The switch happened at a segment boundary, so just create the next
5519  * segment on the new timeline.
5520  */
5521  bool use_existent = true;
5522  int fd;
5523 
5524  fd = XLogFileInit(startLogSegNo, &use_existent, true);
5525 
5526  if (close(fd))
5527  ereport(ERROR,
5529  errmsg("could not close log file %s: %m",
5530  XLogFileNameP(ThisTimeLineID, startLogSegNo))));
5531  }
5532 
5533  /*
5534  * Let's just make real sure there are not .ready or .done flags posted
5535  * for the new segment.
5536  */
5537  XLogFileName(xlogfname, ThisTimeLineID, startLogSegNo);
5538  XLogArchiveCleanup(xlogfname);
5539 
5540  /*
5541  * Since there might be a partial WAL segment named RECOVERYXLOG, get rid
5542  * of it.
5543  */
5544  snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYXLOG");
5545  unlink(recoveryPath); /* ignore any error */
5546 
5547  /* Get rid of any remaining recovered timeline-history file, too */
5548  snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYHISTORY");
5549  unlink(recoveryPath); /* ignore any error */
5550 
5551  /*
5552  * Rename the config file out of the way, so that we don't accidentally
5553  * re-enter archive recovery mode in a subsequent crash.
5554  */
5557 
5558  ereport(LOG,
5559  (errmsg("archive recovery complete")));
5560 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition: xlog.c:2673
int XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
Definition: xlog.c:3144
#define XLogFileName(fname, tli, logSegNo)
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define RECOVERY_COMMAND_FILE
Definition: xlog.c:82
static void XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno, int upto)
Definition: xlog.c:3313
#define LOG
Definition: elog.h:26
#define RECOVERY_COMMAND_DONE
Definition: xlog.c:83
static int fd(const char *x, int i)
Definition: preproc-init.c:105
void XLogArchiveCleanup(const char *xlog)
Definition: xlogarchive.c:750
bool InArchiveRecovery
Definition: xlog.c:247
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
#define MAXPGPATH
char * XLogFileNameP(TimeLineID tli, XLogSegNo segno)
Definition: xlog.c:10092
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errcode_for_file_access(void)
Definition: elog.c:598
#define XLByteToPrevSeg(xlrp, logSegNo)
int unlink(const char *filename)
#define ereport(elevel, rest)
Definition: elog.h:122
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:593
#define MAXFNAMELEN
#define XLOGDIR
TimeLineID ThisTimeLineID
Definition: xlog.c:179
#define XLByteToSeg(xlrp, logSegNo)
static int readFile
Definition: xlog.c:774
#define Assert(condition)
Definition: c.h:675
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define close(a)
Definition: win32.h:17
static int get_sync_bit ( int  method)
static

Definition at line 9960 of file xlog.c.

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

9961 {
9962  int o_direct_flag = 0;
9963 
9964  /* If fsync is disabled, never open in sync mode */
9965  if (!enableFsync)
9966  return 0;
9967 
9968  /*
9969  * Optimize writes by bypassing kernel cache with O_DIRECT when using
9970  * O_SYNC/O_FSYNC and O_DSYNC. But only if archiving and streaming are
9971  * disabled, otherwise the archive command or walsender process will read
9972  * the WAL soon after writing it, which is guaranteed to cause a physical
9973  * read if we bypassed the kernel cache. We also skip the
9974  * posix_fadvise(POSIX_FADV_DONTNEED) call in XLogFileClose() for the same
9975  * reason.
9976