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/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 notexistOk)
 
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)
 
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 84 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 714 of file xlog.c.

Referenced by CopyXLogRecordToWAL(), and CreateCheckPoint().

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

Definition at line 718 of file xlog.c.

Referenced by XLogWrite().

#define PROMOTE_SIGNAL_FILE   "promote"

Definition at line 83 of file xlog.c.

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

#define RECOVERY_COMMAND_DONE   "recovery.done"

Definition at line 82 of file xlog.c.

Referenced by exitArchiveRecovery().

#define RECOVERY_COMMAND_FILE   "recovery.conf"

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

Referenced by CheckRequiredParameterValues().

#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)

Definition at line 731 of file xlog.c.

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

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

Definition at line 732 of file xlog.c.

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

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

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

enum XLogSource
Enumerator
XLOG_FROM_ANY 
XLOG_FROM_ARCHIVE 
XLOG_FROM_PG_WAL 
XLOG_FROM_STREAM 

Definition at line 744 of file xlog.c.

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

Function Documentation

static void AdvanceXLInsertBuffer ( XLogRecPtr  upto,
bool  opportunistic 
)
static

Definition at line 2031 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().

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

Definition at line 2230 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

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

Definition at line 2223 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size, and newval.

2224 {
2225  max_wal_size = newval;
2227 }
int max_wal_size
Definition: xlog.c:88
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2200
#define newval
void assign_xlog_sync_method ( int  new_sync_method,
void *  extra 
)

Definition at line 9966 of file xlog.c.

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

9967 {
9968  if (sync_method != new_sync_method)
9969  {
9970  /*
9971  * To ensure that no blocks escape unsynced, force an fsync on the
9972  * currently open log segment (if any). Also, if the open flag is
9973  * changing, close the log file so it will be reopened (with new flag
9974  * bit) at next use.
9975  */
9976  if (openLogFile >= 0)
9977  {
9978  if (pg_fsync(openLogFile) != 0)
9979  ereport(PANIC,
9981  errmsg("could not fsync log segment %s: %m",
9983  if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
9984  XLogFileClose();
9985  }
9986  }
9987 }
static int get_sync_bit(int method)
Definition: xlog.c:9910
#define PANIC
Definition: elog.h:53
static XLogSegNo openLogSegNo
Definition: xlog.c:762
static void XLogFileClose(void)
Definition: xlog.c:3683
char * XLogFileNameP(TimeLineID tli, XLogSegNo segno)
Definition: xlog.c:10040
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
static int openLogFile
Definition: xlog.c:761
TimeLineID ThisTimeLineID
Definition: xlog.c:178
int sync_method
Definition: xlog.c:102
int errmsg(const char *fmt,...)
Definition: elog.c:797
int pg_fsync(int fd)
Definition: fd.c:333
bool BackupInProgress ( void  )

Definition at line 11240 of file xlog.c.

References BACKUP_LABEL_FILE.

Referenced by pg_is_in_backup(), and PostmasterStateMachine().

11241 {
11242  struct stat stat_buf;
11243 
11244  return (stat(BACKUP_LABEL_FILE, &stat_buf) == 0);
11245 }
struct stat stat_buf
Definition: pg_standby.c:101
#define BACKUP_LABEL_FILE
Definition: xlog.h:301
void BootStrapXLOG ( void  )

Definition at line 4907 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_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, 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_fsync(), 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, 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().

4908 {
4909  CheckPoint checkPoint;
4910  char *buffer;
4911  XLogPageHeader page;
4912  XLogLongPageHeader longpage;
4913  XLogRecord *record;
4914  char *recptr;
4915  bool use_existent;
4916  uint64 sysidentifier;
4917  struct timeval tv;
4918  pg_crc32c crc;
4919 
4920  /*
4921  * Select a hopefully-unique system identifier code for this installation.
4922  * We use the result of gettimeofday(), including the fractional seconds
4923  * field, as being about as unique as we can easily get. (Think not to
4924  * use random(), since it hasn't been seeded and there's no portable way
4925  * to seed it other than the system clock value...) The upper half of the
4926  * uint64 value is just the tv_sec part, while the lower half contains the
4927  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
4928  * PID for a little extra uniqueness. A person knowing this encoding can
4929  * determine the initialization time of the installation, which could
4930  * perhaps be useful sometimes.
4931  */
4932  gettimeofday(&tv, NULL);
4933  sysidentifier = ((uint64) tv.tv_sec) << 32;
4934  sysidentifier |= ((uint64) tv.tv_usec) << 12;
4935  sysidentifier |= getpid() & 0xFFF;
4936 
4937  /* First timeline ID is always 1 */
4938  ThisTimeLineID = 1;
4939 
4940  /* page buffer must be aligned suitably for O_DIRECT */
4941  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
4942  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
4943  memset(page, 0, XLOG_BLCKSZ);
4944 
4945  /*
4946  * Set up information for the initial checkpoint record
4947  *
4948  * The initial checkpoint record is written to the beginning of the WAL
4949  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
4950  * used, so that we can use 0/0 to mean "before any valid WAL segment".
4951  */
4952  checkPoint.redo = XLogSegSize + SizeOfXLogLongPHD;
4953  checkPoint.ThisTimeLineID = ThisTimeLineID;
4954  checkPoint.PrevTimeLineID = ThisTimeLineID;
4955  checkPoint.fullPageWrites = fullPageWrites;
4956  checkPoint.nextXidEpoch = 0;
4957  checkPoint.nextXid = FirstNormalTransactionId;
4958  checkPoint.nextOid = FirstBootstrapObjectId;
4959  checkPoint.nextMulti = FirstMultiXactId;
4960  checkPoint.nextMultiOffset = 0;
4961  checkPoint.oldestXid = FirstNormalTransactionId;
4962  checkPoint.oldestXidDB = TemplateDbOid;
4963  checkPoint.oldestMulti = FirstMultiXactId;
4964  checkPoint.oldestMultiDB = TemplateDbOid;
4967  checkPoint.time = (pg_time_t) time(NULL);
4969 
4970  ShmemVariableCache->nextXid = checkPoint.nextXid;
4971  ShmemVariableCache->nextOid = checkPoint.nextOid;
4973  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
4974  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
4975  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB);
4977 
4978  /* Set up the XLOG page header */
4979  page->xlp_magic = XLOG_PAGE_MAGIC;
4980  page->xlp_info = XLP_LONG_HEADER;
4981  page->xlp_tli = ThisTimeLineID;
4982  page->xlp_pageaddr = XLogSegSize;
4983  longpage = (XLogLongPageHeader) page;
4984  longpage->xlp_sysid = sysidentifier;
4985  longpage->xlp_seg_size = XLogSegSize;
4986  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
4987 
4988  /* Insert the initial checkpoint record */
4989  recptr = ((char *) page + SizeOfXLogLongPHD);
4990  record = (XLogRecord *) recptr;
4991  record->xl_prev = 0;
4992  record->xl_xid = InvalidTransactionId;
4993  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
4995  record->xl_rmid = RM_XLOG_ID;
4996  recptr += SizeOfXLogRecord;
4997  /* fill the XLogRecordDataHeaderShort struct */
4998  *(recptr++) = XLR_BLOCK_ID_DATA_SHORT;
4999  *(recptr++) = sizeof(checkPoint);
5000  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5001  recptr += sizeof(checkPoint);
5002  Assert(recptr - (char *) record == record->xl_tot_len);
5003 
5004  INIT_CRC32C(crc);
5005  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5006  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5007  FIN_CRC32C(crc);
5008  record->xl_crc = crc;
5009 
5010  /* Create first XLOG segment file */
5011  use_existent = false;
5012  openLogFile = XLogFileInit(1, &use_existent, false);
5013 
5014  /* Write the first page with the initial record */
5015  errno = 0;
5016  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5017  {
5018  /* if write didn't set errno, assume problem is no disk space */
5019  if (errno == 0)
5020  errno = ENOSPC;
5021  ereport(PANIC,
5023  errmsg("could not write bootstrap transaction log file: %m")));
5024  }
5025 
5026  if (pg_fsync(openLogFile) != 0)
5027  ereport(PANIC,
5029  errmsg("could not fsync bootstrap transaction log file: %m")));
5030 
5031  if (close(openLogFile))
5032  ereport(PANIC,
5034  errmsg("could not close bootstrap transaction log file: %m")));
5035 
5036  openLogFile = -1;
5037 
5038  /* Now create pg_control */
5039 
5040  memset(ControlFile, 0, sizeof(ControlFileData));
5041  /* Initialize pg_control status fields */
5042  ControlFile->system_identifier = sysidentifier;
5044  ControlFile->time = checkPoint.time;
5045  ControlFile->checkPoint = checkPoint.redo;
5046  ControlFile->checkPointCopy = checkPoint;
5047  ControlFile->unloggedLSN = 1;
5048 
5049  /* Set important parameter values for use when replaying WAL */
5058 
5059  /* some additional ControlFile fields are set in WriteControlFile() */
5060 
5061  WriteControlFile();
5062 
5063  /* Bootstrap the commit log, too */
5064  BootStrapCLOG();
5068 
5069  pfree(buffer);
5070 }
static void WriteControlFile(void)
Definition: xlog.c:4358
#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:183
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:105
int max_prepared_xacts
Definition: pg_control.h:182
int64 pg_time_t
Definition: pgtime.h:23
pg_time_t time
Definition: pg_control.h:129
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:181
uint32 pg_crc32c
Definition: pg_crc32c.h:38
TransactionId oldestActiveXid
Definition: pg_control.h:60
int wal_level
Definition: xlog.c:103
int XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
Definition: xlog.c:3141
void BootStrapMultiXact(void)
Definition: multixact.c:1866
MultiXactId oldestMulti
Definition: pg_control.h:46
TimeLineID PrevTimeLineID
Definition: pg_control.h:36
RmgrId xl_rmid
Definition: xlogrecord.h:47
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:57
CheckPoint checkPointCopy
Definition: pg_control.h:133
TransactionId oldestXid
Definition: pg_control.h:44
TransactionId nextXid
Definition: pg_control.h:40
pg_time_t time
Definition: pg_control.h:48
#define PANIC
Definition: elog.h:53
uint32 bootstrap_data_checksum_version
Definition: bootstrap.c:48
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid)
Definition: multixact.c:2191
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:74
bool fullPageWrites
Definition: xlog.c:96
void BootStrapSUBTRANS(void)
Definition: subtrans.c:200
MultiXactOffset nextMultiOffset
Definition: pg_control.h:43
TransactionId oldestCommitTsXid
Definition: pg_control.h:49
void pfree(void *pointer)
Definition: mcxt.c:992
#define FirstNormalTransactionId
Definition: transam.h:34
int max_prepared_xacts
Definition: twophase.c:99
uint64 system_identifier
Definition: pg_control.h:107
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:39
bool track_commit_timestamp
Definition: commit_ts.c:103
#define TemplateDbOid
Definition: pg_database.h:80
uint32 data_checksum_version
Definition: pg_control.h:223
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:64
XLogRecPtr unloggedLSN
Definition: pg_control.h:135
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
#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:51
int MaxConnections
Definition: globals.c:123
Oid oldestMultiDB
Definition: pg_control.h:47
static int openLogFile
Definition: xlog.c:761
static ControlFileData * ControlFile
Definition: xlog.c:708
TimeLineID ThisTimeLineID
Definition: xlog.c:178
Oid nextOid
Definition: pg_control.h:41
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:577
bool fullPageWrites
Definition: pg_control.h:38
bool wal_log_hints
Definition: xlog.c:97
void BootStrapCLOG(void)
Definition: clog.c:463
#define NULL
Definition: c.h:226
bool track_commit_timestamp
Definition: pg_control.h:184
#define Assert(condition)
Definition: c.h:671
#define XLP_LONG_HEADER
Definition: xlog_internal.h:79
Oid oldestXidDB
Definition: pg_control.h:45
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:42
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:35
void * palloc(Size size)
Definition: mcxt.c:891
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:130
XLogRecPtr redo
Definition: pg_control.h:33
#define offsetof(type, field)
Definition: c.h:551
#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 2200 of file xlog.c.

References CheckPointCompletionTarget, CheckPointSegments, and max_wal_size.

Referenced by assign_checkpoint_completion_target(), and assign_max_wal_size().

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

Definition at line 11260 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().

11261 {
11262  struct stat stat_buf;
11263 
11264  /* if the backup_label file is not there, return */
11265  if (stat(BACKUP_LABEL_FILE, &stat_buf) < 0)
11266  return;
11267 
11268  /* remove leftover file from previously canceled backup if it exists */
11270 
11272  {
11273  ereport(WARNING,
11275  errmsg("online backup mode was not canceled"),
11276  errdetail("File \"%s\" could not be renamed to \"%s\": %m.",
11278  return;
11279  }
11280 
11281  /* if the tablespace_map file is not there, return */
11282  if (stat(TABLESPACE_MAP, &stat_buf) < 0)
11283  {
11284  ereport(LOG,
11285  (errmsg("online backup mode canceled"),
11286  errdetail("File \"%s\" was renamed to \"%s\".",
11288  return;
11289  }
11290 
11291  /* remove leftover file from previously canceled backup if it exists */
11293 
11295  {
11296  ereport(LOG,
11297  (errmsg("online backup mode canceled"),
11298  errdetail("Files \"%s\" and \"%s\" were renamed to "
11299  "\"%s\" and \"%s\", respectively.",
11302  }
11303  else
11304  {
11305  ereport(WARNING,
11307  errmsg("online backup mode canceled"),
11308  errdetail("File \"%s\" was renamed to \"%s\", but "
11309  "file \"%s\" could not be renamed to \"%s\": %m.",
11312  }
11313 }
#define DEBUG1
Definition: elog.h:25
#define LOG
Definition: elog.h:26
#define BACKUP_LABEL_OLD
Definition: xlog.h:302
#define TABLESPACE_MAP
Definition: xlog.h:304
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:305
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define BACKUP_LABEL_FILE
Definition: xlog.h:301
bool check_wal_buffers ( int *  newval,
void **  extra,
GucSource  source 
)

Definition at line 4727 of file xlog.c.

References XLOGbuffers, and XLOGChooseNumBuffers().

4728 {
4729  /*
4730  * -1 indicates a request for auto-tune.
4731  */
4732  if (*newval == -1)
4733  {
4734  /*
4735  * If we haven't yet changed the boot_val default of -1, just let it
4736  * be. We'll fix it when XLOGShmemSize is called.
4737  */
4738  if (XLOGbuffers == -1)
4739  return true;
4740 
4741  /* Otherwise, substitute the auto-tune value */
4743  }
4744 
4745  /*
4746  * We clamp manually-set values to at least 4 blocks. Prior to PostgreSQL
4747  * 9.1, a minimum of 4 was enforced by guc.c, but since that is no longer
4748  * the case, we just silently treat such values as a request for the
4749  * minimum. (We could throw an error instead, but that doesn't seem very
4750  * helpful.)
4751  */
4752  if (*newval < 4)
4753  *newval = 4;
4754 
4755  return true;
4756 }
static int XLOGChooseNumBuffers(void)
Definition: xlog.c:4711
#define newval
int XLOGbuffers
Definition: xlog.c:91
static bool CheckForStandbyTrigger ( void  )
static

Definition at line 11887 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().

11888 {
11889  struct stat stat_buf;
11890  static bool triggered = false;
11891 
11892  if (triggered)
11893  return true;
11894 
11895  if (IsPromoteTriggered())
11896  {
11897  /*
11898  * In 9.1 and 9.2 the postmaster unlinked the promote file inside the
11899  * signal handler. It now leaves the file in place and lets the
11900  * Startup process do the unlink. This allows Startup to know whether
11901  * it should create a full checkpoint before starting up (fallback
11902  * mode). Fast promotion takes precedence.
11903  */
11904  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
11905  {
11908  fast_promote = true;
11909  }
11910  else if (stat(FALLBACK_PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
11911  {
11913  fast_promote = false;
11914  }
11915 
11916  ereport(LOG, (errmsg("received promote request")));
11917 
11919  triggered = true;
11920  return true;
11921  }
11922 
11923  if (TriggerFile == NULL)
11924  return false;
11925 
11926  if (stat(TriggerFile, &stat_buf) == 0)
11927  {
11928  ereport(LOG,
11929  (errmsg("trigger file found: %s", TriggerFile)));
11931  triggered = true;
11932  fast_promote = true;
11933  return true;
11934  }
11935  else if (errno != ENOENT)
11936  ereport(ERROR,
11938  errmsg("could not stat trigger file \"%s\": %m",
11939  TriggerFile)));
11940 
11941  return false;
11942 }
void ResetPromoteTriggered(void)
Definition: startup.c:252
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.c:84
#define LOG
Definition: elog.h:26
static char * TriggerFile
Definition: xlog.c:273
#define ERROR
Definition: elog.h:43
struct stat stat_buf
Definition: pg_standby.c:101
#define PROMOTE_SIGNAL_FILE
Definition: xlog.c:83
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:226
int errmsg(const char *fmt,...)
Definition: elog.c:797
static bool fast_promote
Definition: xlog.c:279
static void CheckPointGuts ( XLogRecPtr  checkPointRedo,
int  flags 
)
static

Definition at line 8921 of file xlog.c.

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

Referenced by CreateCheckPoint(), and CreateRestartPoint().

8922 {
8923  CheckPointCLOG();
8932  CheckPointBuffers(flags); /* performs all required fsyncs */
8934  /* We deliberately delay 2PC checkpointing as long as possible */
8935  CheckPointTwoPhase(checkPointRedo);
8936 }
void CheckPointBuffers(int flags)
Definition: bufmgr.c:2557
void CheckPointLogicalRewriteHeap(void)
Definition: rewriteheap.c:1191
void CheckPointReplicationOrigin(void)
Definition: origin.c:504
void CheckPointSnapBuild(void)
Definition: snapbuild.c:1835
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:288
void CheckPointRelationMap(void)
Definition: relmapper.c:523
void CheckPointPredicate(void)
Definition: predicate.c:1032
void CheckPointTwoPhase(XLogRecPtr redo_horizon)
Definition: twophase.c:1597
void CheckPointReplicationSlots(void)
Definition: slot.c:894
bool CheckPromoteSignal ( void  )

Definition at line 11959 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, and PROMOTE_SIGNAL_FILE.

Referenced by sigusr1_handler().

11960 {
11961  struct stat stat_buf;
11962 
11963  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
11965  return true;
11966 
11967  return false;
11968 }
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.c:84
struct stat stat_buf
Definition: pg_standby.c:101
#define PROMOTE_SIGNAL_FILE
Definition: xlog.c:83
static void CheckRecoveryConsistency ( void  )
static

Definition at line 7706 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().

7707 {
7708  XLogRecPtr lastReplayedEndRecPtr;
7709 
7710  /*
7711  * During crash recovery, we don't reach a consistent state until we've
7712  * replayed all the WAL.
7713  */
7715  return;
7716 
7717  /*
7718  * assume that we are called in the startup process, and hence don't need
7719  * a lock to read lastReplayedEndRecPtr
7720  */
7721  lastReplayedEndRecPtr = XLogCtl->lastReplayedEndRecPtr;
7722 
7723  /*
7724  * Have we reached the point where our base backup was completed?
7725  */
7727  ControlFile->backupEndPoint <= lastReplayedEndRecPtr)
7728  {
7729  /*
7730  * We have reached the end of base backup, as indicated by pg_control.
7731  * The data on disk is now consistent. Reset backupStartPoint and
7732  * backupEndPoint, and update minRecoveryPoint to make sure we don't
7733  * allow starting up at an earlier point even if recovery is stopped
7734  * and restarted soon after this.
7735  */
7736  elog(DEBUG1, "end of backup reached");
7737 
7738  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7739 
7740  if (ControlFile->minRecoveryPoint < lastReplayedEndRecPtr)
7741  ControlFile->minRecoveryPoint = lastReplayedEndRecPtr;
7742 
7745  ControlFile->backupEndRequired = false;
7747 
7748  LWLockRelease(ControlFileLock);
7749  }
7750 
7751  /*
7752  * Have we passed our safe starting point? Note that minRecoveryPoint is
7753  * known to be incorrectly set if ControlFile->backupEndRequired, until
7754  * the XLOG_BACKUP_RECORD arrives to advise us of the correct
7755  * minRecoveryPoint. All we know prior to that is that we're not
7756  * consistent yet.
7757  */
7759  minRecoveryPoint <= lastReplayedEndRecPtr &&
7761  {
7762  /*
7763  * Check to see if the XLOG sequence contained any unresolved
7764  * references to uninitialized pages.
7765  */
7767 
7768  reachedConsistency = true;
7769  ereport(LOG,
7770  (errmsg("consistent recovery state reached at %X/%X",
7771  (uint32) (lastReplayedEndRecPtr >> 32),
7772  (uint32) lastReplayedEndRecPtr)));
7773  }
7774 
7775  /*
7776  * Have we got a valid starting snapshot that will allow queries to be
7777  * run? If so, we can tell postmaster that the database is consistent now,
7778  * enabling connections.
7779  */
7784  {
7788 
7789  LocalHotStandbyActive = true;
7790 
7792  }
7793 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define DEBUG1
Definition: elog.h:25
void XLogCheckInvalidPages(void)
Definition: xlogutils.c:219
bool SharedHotStandbyActive
Definition: xlog.c:642
slock_t info_lck
Definition: xlog.c:697
#define LOG
Definition: elog.h:26
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1714
bool backupEndRequired
Definition: pg_control.h:172
#define SpinLockAcquire(lock)
Definition: spin.h:62
static bool LocalHotStandbyActive
Definition: xlog.c:220
void UpdateControlFile(void)
Definition: xlog.c:4616
bool IsUnderPostmaster
Definition: globals.c:100
unsigned int uint32
Definition: c.h:265
#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:708
XLogRecPtr backupEndPoint
Definition: pg_control.h:171
bool reachedConsistency
Definition: xlog.c:821
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:700
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1110
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:194
XLogRecPtr backupStartPoint
Definition: pg_control.h:170
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:168
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:811
XLogRecPtr lastReplayedEndRecPtr
Definition: xlog.c:676
static void CheckRequiredParameterValues ( void  )
static

Definition at line 6088 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().

6089 {
6090  /*
6091  * For archive recovery, the WAL must be generated with at least 'replica'
6092  * wal_level.
6093  */
6095  {
6096  ereport(WARNING,
6097  (errmsg("WAL was generated with wal_level=minimal, data may be missing"),
6098  errhint("This happens if you temporarily set wal_level=minimal without taking a new base backup.")));
6099  }
6100 
6101  /*
6102  * For Hot Standby, the WAL must be generated with 'replica' mode, and we
6103  * must have at least as many backend slots as the primary.
6104  */
6106  {
6108  ereport(ERROR,
6109  (errmsg("hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server"),
6110  errhint("Either set wal_level to \"replica\" on the master, or turn off hot_standby here.")));
6111 
6112  /* We ignore autovacuum_max_workers when we make this test. */
6113  RecoveryRequiresIntParameter("max_connections",
6116  RecoveryRequiresIntParameter("max_worker_processes",
6119  RecoveryRequiresIntParameter("max_prepared_transactions",
6122  RecoveryRequiresIntParameter("max_locks_per_transaction",
6125  }
6126 }
bool ArchiveRecoveryRequested
Definition: xlog.c:245
int max_locks_per_xact
Definition: pg_control.h:183
int errhint(const char *fmt,...)
Definition: elog.c:987
int max_prepared_xacts
Definition: pg_control.h:182
int max_worker_processes
Definition: pg_control.h:181
#define ERROR
Definition: elog.h:43
int max_prepared_xacts
Definition: twophase.c:99
#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:708
bool EnableHotStandby
Definition: xlog.c:95
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:6066
static void checkTimeLineSwitch ( XLogRecPtr  lsn,
TimeLineID  newTLI,
TimeLineID  prevTLI 
)
static

Definition at line 9479 of file xlog.c.

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

Referenced by StartupXLOG().

9480 {
9481  /* Check that the record agrees on what the current (old) timeline is */
9482  if (prevTLI != ThisTimeLineID)
9483  ereport(PANIC,
9484  (errmsg("unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record",
9485  prevTLI, ThisTimeLineID)));
9486 
9487  /*
9488  * The new timeline better be in the list of timelines we expect to see,
9489  * according to the timeline history. It should also not decrease.
9490  */
9491  if (newTLI < ThisTimeLineID || !tliInHistory(newTLI, expectedTLEs))
9492  ereport(PANIC,
9493  (errmsg("unexpected timeline ID %u (after %u) in checkpoint record",
9494  newTLI, ThisTimeLineID)));
9495 
9496  /*
9497  * If we have not yet reached min recovery point, and we're about to
9498  * switch to a timeline greater than the timeline of the min recovery
9499  * point: trouble. After switching to the new timeline, we could not
9500  * possibly visit the min recovery point on the correct timeline anymore.
9501  * This can happen if there is a newer timeline in the archive that
9502  * branched before the timeline the min recovery point is on, and you
9503  * attempt to do PITR to the new timeline.
9504  */
9506  lsn < minRecoveryPoint &&
9507  newTLI > minRecoveryPointTLI)
9508  ereport(PANIC,
9509  (errmsg("unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u",
9510  newTLI,
9511  (uint32) (minRecoveryPoint >> 32),
9514 
9515  /* Looks good */
9516 }
static List * expectedTLEs
Definition: xlog.c:317
#define PANIC
Definition: elog.h:53
unsigned int uint32
Definition: c.h:265
#define ereport(elevel, rest)
Definition: elog.h:122
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
static TimeLineID minRecoveryPointTLI
Definition: xlog.c:813
TimeLineID ThisTimeLineID
Definition: xlog.c:178
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool tliInHistory(TimeLineID tli, List *expectedTLEs)
Definition: timeline.c:507
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:811
static void checkXLogConsistency ( XLogReaderState record)
static

Definition at line 1334 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().

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

Definition at line 3743 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().

3744 {
3745  XLogSegNo lastRemovedSegNo;
3746 
3748  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3750 
3751  if (segno <= lastRemovedSegNo)
3752  {
3753  char filename[MAXFNAMELEN];
3754 
3755  XLogFileName(filename, tli, segno);
3756  ereport(ERROR,
3758  errmsg("requested WAL segment %s has already been removed",
3759  filename)));
3760  }
3761 }
slock_t info_lck
Definition: xlog.c:697
#define XLogFileName(fname, tli, logSegNo)
XLogSegNo lastRemovedSegNo
Definition: xlog.c:579
#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:700
static char * filename
Definition: pg_dumpall.c:84
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void CleanupBackupHistory ( void  )
static

Definition at line 4081 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().

4082 {
4083  DIR *xldir;
4084  struct dirent *xlde;
4085  char path[MAXPGPATH];
4086 
4087  xldir = AllocateDir(XLOGDIR);
4088  if (xldir == NULL)
4089  ereport(ERROR,
4091  errmsg("could not open transaction log directory \"%s\": %m",
4092  XLOGDIR)));
4093 
4094  while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
4095  {
4096  if (IsBackupHistoryFileName(xlde->d_name))
4097  {
4098  if (XLogArchiveCheckDone(xlde->d_name))
4099  {
4100  ereport(DEBUG2,
4101  (errmsg("removing transaction log backup history file \"%s\"",
4102  xlde->d_name)));
4103  snprintf(path, MAXPGPATH, XLOGDIR "/%s", xlde->d_name);
4104  unlink(path);
4105  XLogArchiveCleanup(xlde->d_name);
4106  }
4107  }
4108  }
4109 
4110  FreeDir(xldir);
4111 }
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:751
Definition: dirent.c:25
#define ERROR
Definition: elog.h:43
bool XLogArchiveCheckDone(const char *xlog)
Definition: xlogarchive.c:618
#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:2284
int unlink(const char *filename)
#define ereport(elevel, rest)
Definition: elog.h:122
#define IsBackupHistoryFileName(fname)
#define XLOGDIR
#define NULL
Definition: c.h:226
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2350
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:2393
static void CopyXLogRecordToWAL ( int  write_len,
bool  isLogSwitch,
XLogRecData rdata,
XLogRecPtr  StartPos,
XLogRecPtr  EndPos 
)
static

Definition at line 1437 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().

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

Definition at line 8449 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, 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().

8450 {
8451  bool shutdown;
8452  CheckPoint checkPoint;
8453  XLogRecPtr recptr;
8455  uint32 freespace;
8456  XLogRecPtr PriorRedoPtr;
8457  XLogRecPtr curInsert;
8458  XLogRecPtr last_important_lsn;
8459  VirtualTransactionId *vxids;
8460  int nvxids;
8461 
8462  /*
8463  * An end-of-recovery checkpoint is really a shutdown checkpoint, just
8464  * issued at a different time.
8465  */
8467  shutdown = true;
8468  else
8469  shutdown = false;
8470 
8471  /* sanity check */
8472  if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
8473  elog(ERROR, "can't create a checkpoint during recovery");
8474 
8475  /*
8476  * Initialize InitXLogInsert working areas before entering the critical
8477  * section. Normally, this is done by the first call to
8478  * RecoveryInProgress() or LocalSetXLogInsertAllowed(), but when creating
8479  * an end-of-recovery checkpoint, the LocalSetXLogInsertAllowed call is
8480  * done below in a critical section, and InitXLogInsert cannot be called
8481  * in a critical section.
8482  */
8483  InitXLogInsert();
8484 
8485  /*
8486  * Acquire CheckpointLock to ensure only one checkpoint happens at a time.
8487  * (This is just pro forma, since in the present system structure there is
8488  * only one process that is allowed to issue checkpoints at any given
8489  * time.)
8490  */
8491  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
8492 
8493  /*
8494  * Prepare to accumulate statistics.
8495  *
8496  * Note: because it is possible for log_checkpoints to change while a
8497  * checkpoint proceeds, we always accumulate stats, even if
8498  * log_checkpoints is currently off.
8499  */
8500  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
8502 
8503  /*
8504  * Use a critical section to force system panic if we have trouble.
8505  */
8507 
8508  if (shutdown)
8509  {
8510  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8512  ControlFile->time = (pg_time_t) time(NULL);
8514  LWLockRelease(ControlFileLock);
8515  }
8516 
8517  /*
8518  * Let smgr prepare for checkpoint; this has to happen before we determine
8519  * the REDO pointer. Note that smgr must not do anything that'd have to
8520  * be undone if we decide no checkpoint is needed.
8521  */
8522  smgrpreckpt();
8523 
8524  /* Begin filling in the checkpoint WAL record */
8525  MemSet(&checkPoint, 0, sizeof(checkPoint));
8526  checkPoint.time = (pg_time_t) time(NULL);
8527 
8528  /*
8529  * For Hot Standby, derive the oldestActiveXid before we fix the redo
8530  * pointer. This allows us to begin accumulating changes to assemble our
8531  * starting snapshot of locks and transactions.
8532  */
8533  if (!shutdown && XLogStandbyInfoActive())
8535  else
8537 
8538  /*
8539  * Get location of last important record before acquiring insert locks (as
8540  * GetLastImportantRecPtr() also locks WAL locks).
8541  */
8542  last_important_lsn = GetLastImportantRecPtr();
8543 
8544  /*
8545  * We must block concurrent insertions while examining insert state to
8546  * determine the checkpoint REDO pointer.
8547  */
8549  curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
8550 
8551  /*
8552  * If this isn't a shutdown or forced checkpoint, and if there has been no
8553  * WAL activity requiring a checkpoint, skip it. The idea here is to
8554  * avoid inserting duplicate checkpoints when the system is idle.
8555  */
8556  if ((flags & (CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_END_OF_RECOVERY |
8557  CHECKPOINT_FORCE)) == 0)
8558  {
8559  if (last_important_lsn == ControlFile->checkPoint)
8560  {
8562  LWLockRelease(CheckpointLock);
8563  END_CRIT_SECTION();
8564  ereport(DEBUG1,
8565  (errmsg("checkpoint skipped due to an idle system")));
8566  return;
8567  }
8568  }
8569 
8570  /*
8571  * An end-of-recovery checkpoint is created before anyone is allowed to
8572  * write WAL. To allow us to write the checkpoint record, temporarily
8573  * enable XLogInsertAllowed. (This also ensures ThisTimeLineID is
8574  * initialized, which we need here and in AdvanceXLInsertBuffer.)
8575  */
8576  if (flags & CHECKPOINT_END_OF_RECOVERY)
8578 
8579  checkPoint.ThisTimeLineID = ThisTimeLineID;
8580  if (flags & CHECKPOINT_END_OF_RECOVERY)
8581  checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
8582  else
8583  checkPoint.PrevTimeLineID = ThisTimeLineID;
8584 
8585  checkPoint.fullPageWrites = Insert->fullPageWrites;
8586 
8587  /*
8588  * Compute new REDO record ptr = location of next XLOG record.
8589  *
8590  * NB: this is NOT necessarily where the checkpoint record itself will be,
8591  * since other backends may insert more XLOG records while we're off doing
8592  * the buffer flush work. Those XLOG records are logically after the
8593  * checkpoint, even though physically before it. Got that?
8594  */
8595  freespace = INSERT_FREESPACE(curInsert);
8596  if (freespace == 0)
8597  {
8598  if (curInsert % XLogSegSize == 0)
8599  curInsert += SizeOfXLogLongPHD;
8600  else
8601  curInsert += SizeOfXLogShortPHD;
8602  }
8603  checkPoint.redo = curInsert;
8604 
8605  /*
8606  * Here we update the shared RedoRecPtr for future XLogInsert calls; this
8607  * must be done while holding all the insertion locks.
8608  *
8609  * Note: if we fail to complete the checkpoint, RedoRecPtr will be left
8610  * pointing past where it really needs to point. This is okay; the only
8611  * consequence is that XLogInsert might back up whole buffers that it
8612  * didn't really need to. We can't postpone advancing RedoRecPtr because
8613  * XLogInserts that happen while we are dumping buffers must assume that
8614  * their buffer changes are not included in the checkpoint.
8615  */
8616  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
8617 
8618  /*
8619  * Now we can release the WAL insertion locks, allowing other xacts to
8620  * proceed while we are flushing disk buffers.
8621  */
8623 
8624  /* Update the info_lck-protected copy of RedoRecPtr as well */
8626  XLogCtl->RedoRecPtr = checkPoint.redo;
8628 
8629  /*
8630  * If enabled, log checkpoint start. We postpone this until now so as not
8631  * to log anything if we decided to skip the checkpoint.
8632  */
8633  if (log_checkpoints)
8634  LogCheckpointStart(flags, false);
8635 
8636  TRACE_POSTGRESQL_CHECKPOINT_START(flags);
8637 
8638  /*
8639  * Get the other info we need for the checkpoint record.
8640  */
8641  LWLockAcquire(XidGenLock, LW_SHARED);
8642  checkPoint.nextXid = ShmemVariableCache->nextXid;
8643  checkPoint.oldestXid = ShmemVariableCache->oldestXid;
8645  LWLockRelease(XidGenLock);
8646 
8647  LWLockAcquire(CommitTsLock, LW_SHARED);
8650  LWLockRelease(CommitTsLock);
8651 
8652  /* Increase XID epoch if we've wrapped around since last checkpoint */
8654  if (checkPoint.nextXid < ControlFile->checkPointCopy.nextXid)
8655  checkPoint.nextXidEpoch++;
8656 
8657  LWLockAcquire(OidGenLock, LW_SHARED);
8658  checkPoint.nextOid = ShmemVariableCache->nextOid;
8659  if (!shutdown)
8660  checkPoint.nextOid += ShmemVariableCache->oidCount;
8661  LWLockRelease(OidGenLock);
8662 
8663  MultiXactGetCheckptMulti(shutdown,
8664  &checkPoint.nextMulti,
8665  &checkPoint.nextMultiOffset,
8666  &checkPoint.oldestMulti,
8667  &checkPoint.oldestMultiDB);
8668 
8669  /*
8670  * Having constructed the checkpoint record, ensure all shmem disk buffers
8671  * and commit-log buffers are flushed to disk.
8672  *
8673  * This I/O could fail for various reasons. If so, we will fail to
8674  * complete the checkpoint, but there is no reason to force a system
8675  * panic. Accordingly, exit critical section while doing it.
8676  */
8677  END_CRIT_SECTION();
8678 
8679  /*
8680  * In some cases there are groups of actions that must all occur on one
8681  * side or the other of a checkpoint record. Before flushing the
8682  * checkpoint record we must explicitly wait for any backend currently
8683  * performing those groups of actions.
8684  *
8685  * One example is end of transaction, so we must wait for any transactions
8686  * that are currently in commit critical sections. If an xact inserted
8687  * its commit record into XLOG just before the REDO point, then a crash
8688  * restart from the REDO point would not replay that record, which means
8689  * that our flushing had better include the xact's update of pg_clog. So
8690  * we wait till he's out of his commit critical section before proceeding.
8691  * See notes in RecordTransactionCommit().
8692  *
8693  * Because we've already released the insertion locks, this test is a bit
8694  * fuzzy: it is possible that we will wait for xacts we didn't really need
8695  * to wait for. But the delay should be short and it seems better to make
8696  * checkpoint take a bit longer than to hold off insertions longer than
8697  * necessary. (In fact, the whole reason we have this issue is that xact.c
8698  * does commit record XLOG insertion and clog update as two separate steps
8699  * protected by different locks, but again that seems best on grounds of
8700  * minimizing lock contention.)
8701  *
8702  * A transaction that has not yet set delayChkpt when we look cannot be at
8703  * risk, since he's not inserted his commit record yet; and one that's
8704  * already cleared it is not at risk either, since he's done fixing clog
8705  * and we will correctly flush the update below. So we cannot miss any
8706  * xacts we need to wait for.
8707  */
8708  vxids = GetVirtualXIDsDelayingChkpt(&nvxids);
8709  if (nvxids > 0)
8710  {
8711  do
8712  {
8713  pg_usleep(10000L); /* wait for 10 msec */
8714  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids));
8715  }
8716  pfree(vxids);
8717 
8718  CheckPointGuts(checkPoint.redo, flags);
8719 
8720  /*
8721  * Take a snapshot of running transactions and write this to WAL. This
8722  * allows us to reconstruct the state of running transactions during
8723  * archive recovery, if required. Skip, if this info disabled.
8724  *
8725  * If we are shutting down, or Startup process is completing crash
8726  * recovery we don't need to write running xact data.
8727  */
8728  if (!shutdown && XLogStandbyInfoActive())
8730 
8732 
8733  /*
8734  * Now insert the checkpoint record into XLOG.
8735  */
8736  XLogBeginInsert();
8737  XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));
8738  recptr = XLogInsert(RM_XLOG_ID,
8739  shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
8741 
8742  XLogFlush(recptr);
8743 
8744  /*
8745  * We mustn't write any new WAL after a shutdown checkpoint, or it will be
8746  * overwritten at next startup. No-one should even try, this just allows
8747  * sanity-checking. In the case of an end-of-recovery checkpoint, we want
8748  * to just temporarily disable writing until the system has exited
8749  * recovery.
8750  */
8751  if (shutdown)
8752  {
8753  if (flags & CHECKPOINT_END_OF_RECOVERY)
8754  LocalXLogInsertAllowed = -1; /* return to "check" state */
8755  else
8756  LocalXLogInsertAllowed = 0; /* never again write WAL */
8757  }
8758 
8759  /*
8760  * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
8761  * = end of actual checkpoint record.
8762  */
8763  if (shutdown && checkPoint.redo != ProcLastRecPtr)
8764  ereport(PANIC,
8765  (errmsg("concurrent transaction log activity while database system is shutting down")));
8766 
8767  /*
8768  * Remember the prior checkpoint's redo pointer, used later to determine
8769  * the point where the log can be truncated.
8770  */
8771  PriorRedoPtr = ControlFile->checkPointCopy.redo;
8772 
8773  /*
8774  * Update the control file.
8775  */
8776  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8777  if (shutdown)
8781  ControlFile->checkPointCopy = checkPoint;
8782  ControlFile->time = (pg_time_t) time(NULL);
8783  /* crash recovery should always recover to the end of WAL */
8786 
8787  /*
8788  * Persist unloggedLSN value. It's reset on crash recovery, so this goes
8789  * unused on non-shutdown checkpoints, but seems useful to store it always
8790  * for debugging purposes.
8791  */
8795 
8797  LWLockRelease(ControlFileLock);
8798 
8799  /* Update shared-memory copy of checkpoint XID/epoch */
8801  XLogCtl->ckptXidEpoch = checkPoint.nextXidEpoch;
8802  XLogCtl->ckptXid = checkPoint.nextXid;
8804 
8805  /*
8806  * We are now done with critical updates; no need for system panic if we
8807  * have trouble while fooling with old log segments.
8808  */
8809  END_CRIT_SECTION();
8810 
8811  /*
8812  * Let smgr do post-checkpoint cleanup (eg, deleting old files).
8813  */
8814  smgrpostckpt();
8815 
8816  /*
8817  * Delete old log files (those no longer needed even for previous
8818  * checkpoint or the standbys in XLOG streaming).
8819  */
8820  if (PriorRedoPtr != InvalidXLogRecPtr)
8821  {
8822  XLogSegNo _logSegNo;
8823 
8824  /* Update the average distance between checkpoints. */
8826 
8827  XLByteToSeg(PriorRedoPtr, _logSegNo);
8828  KeepLogSeg(recptr, &_logSegNo);
8829  _logSegNo--;
8830  RemoveOldXlogFiles(_logSegNo, PriorRedoPtr, recptr);
8831  }
8832 
8833  /*
8834  * Make more log segments if needed. (Do this after recycling old log
8835  * segments, since that may supply some of the needed files.)
8836  */
8837  if (!shutdown)
8838  PreallocXlogFiles(recptr);
8839 
8840  /*
8841  * Truncate pg_subtrans if possible. We can throw away all data before
8842  * the oldest XMIN of any running transaction. No future transaction will
8843  * attempt to reference any pg_subtrans entry older than that (see Asserts
8844  * in subtrans.c). During recovery, though, we mustn't do this because
8845  * StartupSUBTRANS hasn't been called yet.
8846  */
8847  if (!RecoveryInProgress())
8849 
8850  /* Real work is done, but log and update stats before releasing lock. */
8851  LogCheckpointEnd(false);
8852 
8853  TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
8854  NBuffers,
8858 
8859  LWLockRelease(CheckpointLock);
8860 }
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:8172
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8387
#define XLogSegSize
Definition: xlog_internal.h:92
static int LocalXLogInsertAllowed
Definition: xlog.c:232
bool log_checkpoints
Definition: xlog.c:101
#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:575
static void WALInsertLockRelease(void)
Definition: xlog.c:1635
pg_time_t time
Definition: pg_control.h:129
#define XLOG_CHECKPOINT_ONLINE
Definition: pg_control.h:65
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:169
uint32 oidCount
Definition: transam.h:112
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1569
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1904
XLogRecPtr unloggedLSN
Definition: xlog.c:583
XLogRecPtr ProcLastRecPtr
Definition: xlog.c:335
TransactionId oldestActiveXid
Definition: pg_control.h:60
void InitXLogInsert(void)
Definition: xloginsert.c:1029
TimestampTz ckpt_start_t
Definition: xlog.h:199
slock_t info_lck
Definition: xlog.c:697
#define END_CRIT_SECTION()
Definition: miscadmin.h:132
VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids)
Definition: procarray.c:2237
MultiXactId oldestMulti
Definition: pg_control.h:46
TimeLineID PrevTimeLineID
Definition: xlog.c:624
TimeLineID PrevTimeLineID
Definition: pg_control.h:36
#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:853
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
Definition: xlog.c:3808
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:8921
CheckPoint checkPointCopy
Definition: pg_control.h:133
XLogCtlInsert Insert
Definition: xlog.c:569
TransactionId oldestXid
Definition: pg_control.h:44
bool RecoveryInProgress(void)
Definition: xlog.c:7805
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:342
uint32 ckptXidEpoch
Definition: xlog.c:574
TransactionId nextXid
Definition: pg_control.h:40
pg_time_t time
Definition: pg_control.h:48
#define PANIC
Definition: elog.h:53
bool fullPageWrites
Definition: xlog.c:543
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2745
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1714
#define SpinLockAcquire(lock)
Definition: spin.h:62
void pg_usleep(long microsec)
Definition: signal.c:53
MultiXactOffset nextMultiOffset
Definition: pg_control.h:43
void UpdateControlFile(void)
Definition: xlog.c:4616
TransactionId oldestCommitTsXid
Definition: pg_control.h:49
void pfree(void *pointer)
Definition: mcxt.c:992
XLogRecPtr LogStandbySnapshot(void)
Definition: standby.c:913
#define ERROR
Definition: elog.h:43
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8302
TransactionId nextXid
Definition: transam.h:117
uint32 nextXidEpoch
Definition: pg_control.h:39
static XLogRecPtr RedoRecPtr
Definition: xlog.c:349
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:64
XLogRecPtr unloggedLSN
Definition: pg_control.h:135
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3717
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:519
unsigned int uint32
Definition: c.h:265
XLogRecPtr RedoRecPtr
Definition: xlog.c:573
int ckpt_segs_removed
Definition: xlog.h:208
#define CHECKPOINT_FORCE
Definition: xlog.h:180
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:714
#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:7931
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:51
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9245
Oid oldestMultiDB
Definition: pg_control.h:47
#define XLogStandbyInfoActive()
Definition: xlog.h:159
XLogRecPtr prevCheckPoint
Definition: pg_control.h:131
static ControlFileData * ControlFile
Definition: xlog.c:708
TimeLineID ThisTimeLineID
Definition: xlog.c:178
Oid nextOid
Definition: pg_control.h:41
bool fullPageWrites
Definition: pg_control.h:38
void smgrpreckpt(void)
Definition: smgr.c:744
TransactionId GetOldestXmin(Relation rel, bool ignoreVacuum)
Definition: procarray.c:1305
#define XLByteToSeg(xlrp, logSegNo)
#define NULL
Definition: c.h:226
uint64 XLogRecPtr
Definition: xlogdefs.h:21
Oid oldestXidDB
Definition: pg_control.h:45
TransactionId newestCommitTsXid
Definition: transam.h:130
CheckpointStatsData CheckpointStats
Definition: xlog.c:172
#define SizeOfXLogShortPHD
Definition: xlog_internal.h:55
MultiXactId nextMulti
Definition: pg_control.h:42
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1606
static XLogCtlData * XLogCtl
Definition: xlog.c:700
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1110
int ckpt_segs_added
Definition: xlog.h:207
slock_t ulsn_lck
Definition: xlog.c:584
TimeLineID ThisTimeLineID
Definition: pg_control.h:35
int errmsg(const char *fmt,...)
Definition: elog.c:797
TransactionId GetOldestActiveTransactionId(void)
Definition: procarray.c:2083
int NBuffers
Definition: globals.c:122
#define elog
Definition: elog.h:219
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids)
Definition: procarray.c:2282
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr RedoRecPtr
Definition: xlog.c:541
void smgrpostckpt(void)
Definition: smgr.c:774
XLogRecPtr checkPoint
Definition: pg_control.h:130
XLogRecPtr redo
Definition: pg_control.h:33
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8284
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:175
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:168
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
static void CreateEndOfRecoveryRecord ( void  )
static

Definition at line 8872 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().

8873 {
8874  xl_end_of_recovery xlrec;
8875  XLogRecPtr recptr;
8876 
8877  /* sanity check */
8878  if (!RecoveryInProgress())
8879  elog(ERROR, "can only be used to end recovery");
8880 
8881  xlrec.end_time = GetCurrentTimestamp();
8882 
8887 
8889 
8891 
8892  XLogBeginInsert();
8893  XLogRegisterData((char *) &xlrec, sizeof(xl_end_of_recovery));
8894  recptr = XLogInsert(RM_XLOG_ID, XLOG_END_OF_RECOVERY);
8895 
8896  XLogFlush(recptr);
8897 
8898  /*
8899  * Update the control file so that crash recovery can follow the timeline
8900  * changes to this point.
8901  */
8902  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8903  ControlFile->time = (pg_time_t) time(NULL);
8904  ControlFile->minRecoveryPoint = recptr;
8907  LWLockRelease(ControlFileLock);
8908 
8909  END_CRIT_SECTION();
8910 
8911  LocalXLogInsertAllowed = -1; /* return to "check" state */
8912 }
static int LocalXLogInsertAllowed
Definition: xlog.c:232
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1635
pg_time_t time
Definition: pg_control.h:129
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:169
TimeLineID PrevTimeLineID
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1569
#define END_CRIT_SECTION()
Definition: miscadmin.h:132
TimeLineID PrevTimeLineID
Definition: xlog.c:624
#define START_CRIT_SECTION()
Definition: miscadmin.h:130
bool RecoveryInProgress(void)
Definition: xlog.c:7805
#define XLOG_END_OF_RECOVERY
Definition: pg_control.h:73
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2745
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1714
void UpdateControlFile(void)
Definition: xlog.c:4616
#define ERROR
Definition: elog.h:43
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:7931
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:708
TimeLineID ThisTimeLineID
Definition: xlog.c:178
TimestampTz end_time
#define NULL
Definition: c.h:226
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1606
static XLogCtlData * XLogCtl
Definition: xlog.c:700
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1110
TimeLineID ThisTimeLineID
#define elog
Definition: elog.h:219
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:168
bool CreateRestartPoint ( int  flags)

Definition at line 8991 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, 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().

8992 {
8993  XLogRecPtr lastCheckPointRecPtr;
8994  XLogRecPtr lastCheckPointEndPtr;
8995  CheckPoint lastCheckPoint;
8996  XLogRecPtr PriorRedoPtr;
8997  TimestampTz xtime;
8998 
8999  /*
9000  * Acquire CheckpointLock to ensure only one restartpoint or checkpoint
9001  * happens at a time.
9002  */
9003  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
9004 
9005  /* Get a local copy of the last safe checkpoint record. */
9007  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
9008  lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
9009  lastCheckPoint = XLogCtl->lastCheckPoint;
9011 
9012  /*
9013  * Check that we're still in recovery mode. It's ok if we exit recovery
9014  * mode after this check, the restart point is valid anyway.
9015  */
9016  if (!RecoveryInProgress())
9017  {
9018  ereport(DEBUG2,
9019  (errmsg("skipping restartpoint, recovery has already ended")));
9020  LWLockRelease(CheckpointLock);
9021  return false;
9022  }
9023 
9024  /*
9025  * If the last checkpoint record we've replayed is already our last
9026  * restartpoint, we can't perform a new restart point. We still update
9027  * minRecoveryPoint in that case, so that if this is a shutdown restart
9028  * point, we won't start up earlier than before. That's not strictly
9029  * necessary, but when hot standby is enabled, it would be rather weird if
9030  * the database opened up for read-only connections at a point-in-time
9031  * before the last shutdown. Such time travel is still possible in case of
9032  * immediate shutdown, though.
9033  *
9034  * We don't explicitly advance minRecoveryPoint when we do create a
9035  * restartpoint. It's assumed that flushing the buffers will do that as a
9036  * side-effect.
9037  */
9038  if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
9039  lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
9040  {
9041  ereport(DEBUG2,
9042  (errmsg("skipping restartpoint, already performed at %X/%X",
9043  (uint32) (lastCheckPoint.redo >> 32),
9044  (uint32) lastCheckPoint.redo)));
9045 
9047  if (flags & CHECKPOINT_IS_SHUTDOWN)
9048  {
9049  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9051  ControlFile->time = (pg_time_t) time(NULL);
9053  LWLockRelease(ControlFileLock);
9054  }
9055  LWLockRelease(CheckpointLock);
9056  return false;
9057  }
9058 
9059  /*
9060  * Update the shared RedoRecPtr so that the startup process can calculate
9061  * the number of segments replayed since last restartpoint, and request a
9062  * restartpoint if it exceeds CheckPointSegments.
9063  *
9064  * Like in CreateCheckPoint(), hold off insertions to update it, although
9065  * during recovery this is just pro forma, because no WAL insertions are
9066  * happening.
9067  */
9069  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
9071 
9072  /* Also update the info_lck-protected copy */
9074  XLogCtl->RedoRecPtr = lastCheckPoint.redo;
9076 
9077  /*
9078  * Prepare to accumulate statistics.
9079  *
9080  * Note: because it is possible for log_checkpoints to change while a
9081  * checkpoint proceeds, we always accumulate stats, even if
9082  * log_checkpoints is currently off.
9083  */
9084  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
9086 
9087  if (log_checkpoints)
9088  LogCheckpointStart(flags, true);
9089 
9090  CheckPointGuts(lastCheckPoint.redo, flags);
9091 
9092  /*
9093  * Remember the prior checkpoint's redo pointer, used later to determine
9094  * the point at which we can truncate the log.
9095  */
9096  PriorRedoPtr = ControlFile->checkPointCopy.redo;
9097 
9098  /*
9099  * Update pg_control, using current time. Check that it still shows
9100  * IN_ARCHIVE_RECOVERY state and an older checkpoint, else do nothing;
9101  * this is a quick hack to make sure nothing really bad happens if somehow
9102  * we get here after the end-of-recovery checkpoint.
9103  */
9104  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9106  ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
9107  {
9109  ControlFile->checkPoint = lastCheckPointRecPtr;
9110  ControlFile->checkPointCopy = lastCheckPoint;
9111  ControlFile->time = (pg_time_t) time(NULL);
9112 
9113  /*
9114  * Ensure minRecoveryPoint is past the checkpoint record. Normally,
9115  * this will have happened already while writing out dirty buffers,
9116  * but not necessarily - e.g. because no buffers were dirtied. We do
9117  * this because a non-exclusive base backup uses minRecoveryPoint to
9118  * determine which WAL files must be included in the backup, and the
9119  * file (or files) containing the checkpoint record must be included,
9120  * at a minimum. Note that for an ordinary restart of recovery there's
9121  * no value in having the minimum recovery point any earlier than this
9122  * anyway, because redo will begin just after the checkpoint record.
9123  */
9124  if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
9125  {
9126  ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
9128 
9129  /* update local copy */
9132  }
9133  if (flags & CHECKPOINT_IS_SHUTDOWN)
9136  }
9137  LWLockRelease(ControlFileLock);
9138 
9139  /*
9140  * Delete old log files (those no longer needed even for previous
9141  * checkpoint/restartpoint) to prevent the disk holding the xlog from
9142  * growing full.
9143  */
9144  if (PriorRedoPtr != InvalidXLogRecPtr)
9145  {
9146  XLogRecPtr receivePtr;
9147  XLogRecPtr replayPtr;
9148  TimeLineID replayTLI;
9149  XLogRecPtr endptr;
9150  XLogSegNo _logSegNo;
9151 
9152  /* Update the average distance between checkpoints/restartpoints. */
9154 
9155  XLByteToSeg(PriorRedoPtr, _logSegNo);
9156 
9157  /*
9158  * Get the current end of xlog replayed or received, whichever is
9159  * later.
9160  */
9161  receivePtr = GetWalRcvWriteRecPtr(NULL, NULL);
9162  replayPtr = GetXLogReplayRecPtr(&replayTLI);
9163  endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
9164 
9165  KeepLogSeg(endptr, &_logSegNo);
9166  _logSegNo--;
9167 
9168  /*
9169  * Try to recycle segments on a useful timeline. If we've been
9170  * promoted since the beginning of this restartpoint, use the new
9171  * timeline chosen at end of recovery (RecoveryInProgress() sets
9172  * ThisTimeLineID in that case). If we're still in recovery, use the
9173  * timeline we're currently replaying.
9174  *
9175  * There is no guarantee that the WAL segments will be useful on the
9176  * current timeline; if recovery proceeds to a new timeline right
9177  * after this, the pre-allocated WAL segments on this timeline will
9178  * not be used, and will go wasted until recycled on the next
9179  * restartpoint. We'll live with that.
9180  */
9181  if (RecoveryInProgress())
9182  ThisTimeLineID = replayTLI;
9183 
9184  RemoveOldXlogFiles(_logSegNo, PriorRedoPtr, endptr);
9185 
9186  /*
9187  * Make more log segments if needed. (Do this after recycling old log
9188  * segments, since that may supply some of the needed files.)
9189  */
9190  PreallocXlogFiles(endptr);
9191 
9192  /*
9193  * ThisTimeLineID is normally not set when we're still in recovery.
9194  * However, recycling/preallocating segments above needed
9195  * ThisTimeLineID to determine which timeline to install the segments
9196  * on. Reset it now, to restore the normal state of affairs for
9197  * debugging purposes.
9198  */
9199  if (RecoveryInProgress())
9200  ThisTimeLineID = 0;
9201  }
9202 
9203  /*
9204  * Truncate pg_subtrans if possible. We can throw away all data before
9205  * the oldest XMIN of any running transaction. No future transaction will
9206  * attempt to reference any pg_subtrans entry older than that (see Asserts
9207  * in subtrans.c). When hot standby is disabled, though, we mustn't do
9208  * this because StartupSUBTRANS hasn't been called yet.
9209  */
9210  if (EnableHotStandby)
9212 
9213  /* Real work is done, but log and update before releasing lock. */
9214  LogCheckpointEnd(true);
9215 
9216  xtime = GetLatestXTime();
9218  (errmsg("recovery restart point at %X/%X",
9219  (uint32) (lastCheckPoint.redo >> 32), (uint32) lastCheckPoint.redo),
9220  xtime ? errdetail("last completed transaction was at log time %s",
9221  timestamptz_to_str(xtime)) : 0));
9222 
9223  LWLockRelease(CheckpointLock);
9224 
9225  /*
9226  * Finally, execute archive_cleanup_command, if any.
9227  */
9230  "archive_cleanup_command",
9231  false);
9232 
9233  return true;
9234 }
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8387
bool log_checkpoints
Definition: xlog.c:101
#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:1635
pg_time_t time
Definition: pg_control.h:129
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:169
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1569
int64 TimestampTz
Definition: timestamp.h:39
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition: xlog.c:2670
TimestampTz ckpt_start_t
Definition: xlog.h:199
slock_t info_lck
Definition: xlog.c:697
#define MemSet(start, val, len)
Definition: c.h:853
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
Definition: xlog.c:3808
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:8921
TimestampTz GetLatestXTime(void)
Definition: xlog.c:6004
CheckPoint checkPointCopy
Definition: pg_control.h:133
XLogCtlInsert Insert
Definition: xlog.c:569
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:7805
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:342
XLogRecPtr lastCheckPointRecPtr
Definition: xlog.c:666
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1714
#define SpinLockAcquire(lock)
Definition: spin.h:62
void UpdateControlFile(void)
Definition: xlog.c:4616
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8302
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
Definition: xlog.c:10984
#define DEBUG2
Definition: elog.h:24
static XLogRecPtr RedoRecPtr
Definition: xlog.c:349
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3717
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errdetail(const char *fmt,...)
Definition: elog.c:873
unsigned int uint32
Definition: c.h:265
XLogRecPtr RedoRecPtr
Definition: xlog.c:573
#define ereport(elevel, rest)
Definition: elog.h:122
CheckPoint lastCheckPoint
Definition: xlog.c:668
void ExecuteRecoveryCommand(char *command, char *commandName, bool failOnSignal)
Definition: xlogarchive.c:330
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
#define SpinLockRelease(lock)
Definition: spin.h:64
static TimeLineID minRecoveryPointTLI
Definition: xlog.c:813
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9245
XLogRecPtr prevCheckPoint
Definition: pg_control.h:131
static ControlFileData * ControlFile
Definition: xlog.c:708
TimeLineID ThisTimeLineID
Definition: xlog.c:178
TransactionId GetOldestXmin(Relation rel, bool ignoreVacuum)
Definition: procarray.c:1305
#define XLByteToSeg(xlrp, logSegNo)
#define NULL
Definition: c.h:226
uint64 XLogRecPtr
Definition: xlogdefs.h:21
CheckpointStatsData CheckpointStats
Definition: xlog.c:172
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1606
static XLogCtlData * XLogCtl
Definition: xlog.c:700
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1110
char archiveCleanupCommand[MAXPGPATH]
Definition: xlog.c:630
bool EnableHotStandby
Definition: xlog.c:95
TimeLineID ThisTimeLineID
Definition: pg_control.h:35
int errmsg(const char *fmt,...)
Definition: elog.c:797
XLogRecPtr RedoRecPtr
Definition: xlog.c:541
XLogRecPtr lastCheckPointEndPtr
Definition: xlog.c:667
XLogRecPtr checkPoint
Definition: pg_control.h:130
XLogRecPtr redo
Definition: pg_control.h:33
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8284
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:175
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:168
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:811
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1709
bool DataChecksumsEnabled ( void  )

Definition at line 4671 of file xlog.c.

References Assert, ControlFileData::data_checksum_version, and NULL.

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

4672 {
4673  Assert(ControlFile != NULL);
4674  return (ControlFile->data_checksum_version > 0);
4675 }
uint32 data_checksum_version
Definition: pg_control.h:223
static ControlFileData * ControlFile
Definition: xlog.c:708
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
void do_pg_abort_backup ( void  )

Definition at line 10964 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().

10965 {
10969 
10972  {
10973  XLogCtl->Insert.forcePageWrites = false;
10974  }
10976 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1635
XLogCtlInsert Insert
Definition: xlog.c:569
bool forcePageWrites
Definition: xlog.c:542
int nonExclusiveBackups
Definition: xlog.c:555
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:554
#define Assert(condition)
Definition: c.h:671
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1606
static XLogCtlData * XLogCtl
Definition: xlog.c:700
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 10087 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().

10091 {
10092  bool exclusive = (labelfile == NULL);
10093  bool backup_started_in_recovery = false;
10094  XLogRecPtr checkpointloc;
10095  XLogRecPtr startpoint;
10096  TimeLineID starttli;
10097  pg_time_t stamp_time;
10098  char strfbuf[128];
10099  char xlogfilename[MAXFNAMELEN];
10100  XLogSegNo _logSegNo;
10101  struct stat stat_buf;
10102  FILE *fp;
10103 
10104  backup_started_in_recovery = RecoveryInProgress();
10105 
10106  /*
10107  * Currently only non-exclusive backup can be taken during recovery.
10108  */
10109  if (backup_started_in_recovery && exclusive)
10110  ereport(ERROR,
10111  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10112  errmsg("recovery is in progress"),
10113  errhint("WAL control functions cannot be executed during recovery.")));
10114 
10115  /*
10116  * During recovery, we don't need to check WAL level. Because, if WAL
10117  * level is not sufficient, it's impossible to get here during recovery.
10118  */
10119  if (!backup_started_in_recovery && !XLogIsNeeded())
10120  ereport(ERROR,
10121  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10122  errmsg("WAL level not sufficient for making an online backup"),
10123  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
10124 
10125  if (strlen(backupidstr) > MAXPGPATH)
10126  ereport(ERROR,
10127  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
10128  errmsg("backup label too long (max %d bytes)",
10129  MAXPGPATH)));
10130 
10131  /*
10132  * Mark backup active in shared memory. We must do full-page WAL writes
10133  * during an on-line backup even if not doing so at other times, because
10134  * it's quite possible for the backup dump to obtain a "torn" (partially
10135  * written) copy of a database page if it reads the page concurrently with
10136  * our write to the same page. This can be fixed as long as the first
10137  * write to the page in the WAL sequence is a full-page write. Hence, we
10138  * turn on forcePageWrites and then force a CHECKPOINT, to ensure there
10139  * are no dirty pages in shared memory that might get dumped while the
10140  * backup is in progress without having a corresponding WAL record. (Once
10141  * the backup is complete, we need not force full-page writes anymore,
10142  * since we expect that any pages not modified during the backup interval
10143  * must have been correctly captured by the backup.)
10144  *
10145  * Note that forcePageWrites has no effect during an online backup from
10146  * the standby.
10147  *
10148  * We must hold all the insertion locks to change the value of
10149  * forcePageWrites, to ensure adequate interlocking against
10150  * XLogInsertRecord().
10151  */
10153  if (exclusive)
10154  {
10155  /*
10156  * At first, mark that we're now starting an exclusive backup,
10157  * to ensure that there are no other sessions currently running
10158  * pg_start_backup() or pg_stop_backup().
10159  */
10161  {
10163  ereport(ERROR,
10164  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10165  errmsg("a backup is already in progress"),
10166  errhint("Run pg_stop_backup() and try again.")));
10167  }
10169  }
10170  else
10172  XLogCtl->Insert.forcePageWrites = true;
10174 
10175  /* Ensure we release forcePageWrites if fail below */
10177  {
10178  bool gotUniqueStartpoint = false;
10179  struct dirent *de;
10180  tablespaceinfo *ti;
10181  int datadirpathlen;
10182 
10183  /*
10184  * Force an XLOG file switch before the checkpoint, to ensure that the
10185  * WAL segment the checkpoint is written to doesn't contain pages with
10186  * old timeline IDs. That would otherwise happen if you called
10187  * pg_start_backup() right after restoring from a PITR archive: the
10188  * first WAL segment containing the startup checkpoint has pages in
10189  * the beginning with the old timeline ID. That can cause trouble at
10190  * recovery: we won't have a history file covering the old timeline if
10191  * pg_wal directory was not included in the base backup and the WAL
10192  * archive was cleared too before starting the backup.
10193  *
10194  * This also ensures that we have emitted a WAL page header that has
10195  * XLP_BKP_REMOVABLE off before we emit the checkpoint record.
10196  * Therefore, if a WAL archiver (such as pglesslog) is trying to
10197  * compress out removable backup blocks, it won't remove any that
10198  * occur after this point.
10199  *
10200  * During recovery, we skip forcing XLOG file switch, which means that
10201  * the backup taken during recovery is not available for the special
10202  * recovery case described above.
10203  */
10204  if (!backup_started_in_recovery)
10205  RequestXLogSwitch(false);
10206 
10207  do
10208  {
10209  bool checkpointfpw;
10210 
10211  /*
10212  * Force a CHECKPOINT. Aside from being necessary to prevent torn
10213  * page problems, this guarantees that two successive backup runs
10214  * will have different checkpoint positions and hence different
10215  * history file names, even if nothing happened in between.
10216  *
10217  * During recovery, establish a restartpoint if possible. We use
10218  * the last restartpoint as the backup starting checkpoint. This
10219  * means that two successive backup runs can have same checkpoint
10220  * positions.
10221  *
10222  * Since the fact that we are executing do_pg_start_backup()
10223  * during recovery means that checkpointer is running, we can use
10224  * RequestCheckpoint() to establish a restartpoint.
10225  *
10226  * We use CHECKPOINT_IMMEDIATE only if requested by user (via
10227  * passing fast = true). Otherwise this can take awhile.
10228  */
10230  (fast ? CHECKPOINT_IMMEDIATE : 0));
10231 
10232  /*
10233  * Now we need to fetch the checkpoint record location, and also
10234  * its REDO pointer. The oldest point in WAL that would be needed
10235  * to restore starting from the checkpoint is precisely the REDO
10236  * pointer.
10237  */
10238  LWLockAcquire(ControlFileLock, LW_SHARED);
10239  checkpointloc = ControlFile->checkPoint;
10240  startpoint = ControlFile->checkPointCopy.redo;
10242  checkpointfpw = ControlFile->checkPointCopy.fullPageWrites;
10243  LWLockRelease(ControlFileLock);
10244 
10245  if (backup_started_in_recovery)
10246  {
10247  XLogRecPtr recptr;
10248 
10249  /*
10250  * Check to see if all WAL replayed during online backup
10251  * (i.e., since last restartpoint used as backup starting
10252  * checkpoint) contain full-page writes.
10253  */
10255  recptr = XLogCtl->lastFpwDisableRecPtr;
10257 
10258  if (!checkpointfpw || startpoint <= recptr)
10259  ereport(ERROR,
10260  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10261  errmsg("WAL generated with full_page_writes=off was replayed "
10262  "since last restartpoint"),
10263  errhint("This means that the backup being taken on the standby "
10264  "is corrupt and should not be used. "
10265  "Enable full_page_writes and run CHECKPOINT on the master, "
10266  "and then try an online backup again.")));
10267 
10268  /*
10269  * During recovery, since we don't use the end-of-backup WAL
10270  * record and don't write the backup history file, the
10271  * starting WAL location doesn't need to be unique. This means
10272  * that two base backups started at the same time might use
10273  * the same checkpoint as starting locations.
10274  */
10275  gotUniqueStartpoint = true;
10276  }
10277 
10278  /*
10279  * If two base backups are started at the same time (in WAL sender
10280  * processes), we need to make sure that they use different
10281  * checkpoints as starting locations, because we use the starting
10282  * WAL location as a unique identifier for the base backup in the
10283  * end-of-backup WAL record and when we write the backup history
10284  * file. Perhaps it would be better generate a separate unique ID
10285  * for each backup instead of forcing another checkpoint, but
10286  * taking a checkpoint right after another is not that expensive
10287  * either because only few buffers have been dirtied yet.
10288  */
10290  if (XLogCtl->Insert.lastBackupStart < startpoint)
10291  {
10292  XLogCtl->Insert.lastBackupStart = startpoint;
10293  gotUniqueStartpoint = true;
10294  }
10296  } while (!gotUniqueStartpoint);
10297 
10298  XLByteToSeg(startpoint, _logSegNo);
10299  XLogFileName(xlogfilename, starttli, _logSegNo);
10300 
10301  /*
10302  * Construct tablespace_map file
10303  */
10304  if (exclusive)
10305  tblspcmapfile = makeStringInfo();
10306 
10307  datadirpathlen = strlen(DataDir);
10308 
10309  /* Collect information about all tablespaces */
10310  while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL)
10311  {
10312  char fullpath[MAXPGPATH];
10313  char linkpath[MAXPGPATH];
10314  char *relpath = NULL;
10315  int rllen;
10316  StringInfoData buflinkpath;
10317  char *s = linkpath;
10318 
10319  /* Skip special stuff */
10320  if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
10321  continue;
10322 
10323  snprintf(fullpath, sizeof(fullpath), "pg_tblspc/%s", de->d_name);
10324 
10325 #if defined(HAVE_READLINK) || defined(WIN32)
10326  rllen = readlink(fullpath, linkpath, sizeof(linkpath));
10327  if (rllen < 0)
10328  {
10329  ereport(WARNING,
10330  (errmsg("could not read symbolic link \"%s\": %m",
10331  fullpath)));
10332  continue;
10333  }
10334  else if (rllen >= sizeof(linkpath))
10335  {
10336  ereport(WARNING,
10337  (errmsg("symbolic link \"%s\" target is too long",
10338  fullpath)));
10339  continue;
10340  }
10341  linkpath[rllen] = '\0';
10342 
10343  /*
10344  * Add the escape character '\\' before newline in a string to
10345  * ensure that we can distinguish between the newline in the
10346  * tablespace path and end of line while reading tablespace_map
10347  * file during archive recovery.
10348  */
10349  initStringInfo(&buflinkpath);
10350 
10351  while (*s)
10352  {
10353  if ((*s == '\n' || *s == '\r') && needtblspcmapfile)
10354  appendStringInfoChar(&buflinkpath, '\\');
10355  appendStringInfoChar(&buflinkpath, *s++);
10356  }
10357 
10358 
10359  /*
10360  * Relpath holds the relative path of the tablespace directory
10361  * when it's located within PGDATA, or NULL if it's located
10362  * elsewhere.
10363  */
10364  if (rllen > datadirpathlen &&
10365  strncmp(linkpath, DataDir, datadirpathlen) == 0 &&
10366  IS_DIR_SEP(linkpath[datadirpathlen]))
10367  relpath = linkpath + datadirpathlen + 1;
10368 
10369  ti = palloc(sizeof(tablespaceinfo));
10370  ti->oid = pstrdup(de->d_name);
10371  ti->path = pstrdup(buflinkpath.data);
10372  ti->rpath = relpath ? pstrdup(relpath) : NULL;
10373  ti->size = infotbssize ? sendTablespace(fullpath, true) : -1;
10374 
10375  if (tablespaces)
10376  *tablespaces = lappend(*tablespaces, ti);
10377 
10378  appendStringInfo(tblspcmapfile, "%s %s\n", ti->oid, ti->path);
10379 
10380  pfree(buflinkpath.data);
10381 #else
10382 
10383  /*
10384  * If the platform does not have symbolic links, it should not be
10385  * possible to have tablespaces - clearly somebody else created
10386  * them. Warn about it and ignore.
10387  */
10388  ereport(WARNING,
10389  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
10390  errmsg("tablespaces are not supported on this platform")));
10391 #endif
10392  }
10393 
10394  /*
10395  * Construct backup label file
10396  */
10397  if (exclusive)
10398  labelfile = makeStringInfo();
10399 
10400  /* Use the log timezone here, not the session timezone */
10401  stamp_time = (pg_time_t) time(NULL);
10402  pg_strftime(strfbuf, sizeof(strfbuf),
10403  "%Y-%m-%d %H:%M:%S %Z",
10404  pg_localtime(&stamp_time, log_timezone));
10405  appendStringInfo(labelfile, "START WAL LOCATION: %X/%X (file %s)\n",
10406  (uint32) (startpoint >> 32), (uint32) startpoint, xlogfilename);
10407  appendStringInfo(labelfile, "CHECKPOINT LOCATION: %X/%X\n",
10408  (uint32) (checkpointloc >> 32), (uint32) checkpointloc);
10409  appendStringInfo(labelfile, "BACKUP METHOD: %s\n",
10410  exclusive ? "pg_start_backup" : "streamed");
10411  appendStringInfo(labelfile, "BACKUP FROM: %s\n",
10412  backup_started_in_recovery ? "standby" : "master");
10413  appendStringInfo(labelfile, "START TIME: %s\n", strfbuf);
10414  appendStringInfo(labelfile, "LABEL: %s\n", backupidstr);
10415 
10416  /*
10417  * Okay, write the file, or return its contents to caller.
10418  */
10419  if (exclusive)
10420  {
10421  /*
10422  * Check for existing backup label --- implies a backup is already
10423  * running. (XXX given that we checked exclusiveBackupState above,
10424  * maybe it would be OK to just unlink any such label file?)
10425  */
10426  if (stat(BACKUP_LABEL_FILE, &stat_buf) != 0)
10427  {
10428  if (errno != ENOENT)
10429  ereport(ERROR,
10431  errmsg("could not stat file \"%s\": %m",
10432  BACKUP_LABEL_FILE)));
10433  }
10434  else
10435  ereport(ERROR,
10436  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10437  errmsg("a backup is already in progress"),
10438  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
10439  BACKUP_LABEL_FILE)));
10440 
10441  fp = AllocateFile(BACKUP_LABEL_FILE, "w");
10442 
10443  if (!fp)
10444  ereport(ERROR,
10446  errmsg("could not create file \"%s\": %m",
10447  BACKUP_LABEL_FILE)));
10448  if (fwrite(labelfile->data, labelfile->len, 1, fp) != 1 ||
10449  fflush(fp) != 0 ||
10450  pg_fsync(fileno(fp)) != 0 ||
10451  ferror(fp) ||
10452  FreeFile(fp))
10453  ereport(ERROR,
10455  errmsg("could not write file \"%s\": %m",
10456  BACKUP_LABEL_FILE)));
10457  /* Allocated locally for exclusive backups, so free separately */
10458  pfree(labelfile->data);
10459  pfree(labelfile);
10460 
10461  /* Write backup tablespace_map file. */
10462  if (tblspcmapfile->len > 0)
10463  {
10464  if (stat(TABLESPACE_MAP, &stat_buf) != 0)
10465  {
10466  if (errno != ENOENT)
10467  ereport(ERROR,
10469  errmsg("could not stat file \"%s\": %m",
10470  TABLESPACE_MAP)));
10471  }
10472  else
10473  ereport(ERROR,
10474  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10475  errmsg("a backup is already in progress"),
10476  errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
10477  TABLESPACE_MAP)));
10478 
10479  fp = AllocateFile(TABLESPACE_MAP, "w");
10480 
10481  if (!fp)
10482  ereport(ERROR,
10484  errmsg("could not create file \"%s\": %m",
10485  TABLESPACE_MAP)));
10486  if (fwrite(tblspcmapfile->data, tblspcmapfile->len, 1, fp) != 1 ||
10487  fflush(fp) != 0 ||
10488  pg_fsync(fileno(fp)) != 0 ||
10489  ferror(fp) ||
10490  FreeFile(fp))
10491  ereport(ERROR,
10493  errmsg("could not write file \"%s\": %m",
10494  TABLESPACE_MAP)));
10495  }
10496 
10497  /* Allocated locally for exclusive backups, so free separately */
10498  pfree(tblspcmapfile->data);
10499  pfree(tblspcmapfile);
10500  }
10501  }
10503 
10504  /*
10505  * Mark that start phase has correctly finished for an exclusive backup.
10506  */
10507  if (exclusive)
10508  {
10512  }
10513 
10514  /*
10515  * We're done. As a convenience, return the starting WAL location.
10516  */
10517  if (starttli_p)
10518  *starttli_p = starttli;
10519  return startpoint;
10520 }
size_t pg_strftime(char *s, size_t max, const char *format, const struct pg_tm *tm)
Definition: strftime.c:124
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9322
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:1635
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:695
XLogRecPtr lastBackupStart
Definition: xlog.c:556
char * pstrdup(const char *in)
Definition: mcxt.c:1165
#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:697
#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:133
XLogCtlInsert Insert
Definition: xlog.c:569
bool RecoveryInProgress(void)
Definition: xlog.c:7805
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:1714
#define TABLESPACE_MAP
Definition: xlog.h:304
#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:992
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
bool forcePageWrites
Definition: xlog.c:542
#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:2043
unsigned int uint32
Definition: c.h:265
int64 sendTablespace(char *path, bool sizeonly)
Definition: basebackup.c:903
#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:555
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
static void pg_start_backup_callback(int code, Datum arg)
Definition: xlog.c:10524
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:554
uintptr_t Datum
Definition: postgres.h:374
static ControlFileData * ControlFile
Definition: xlog.c:708
#define BoolGetDatum(X)
Definition: postgres.h:410
bool fullPageWrites
Definition: pg_control.h:38
#define CHECKPOINT_WAIT
Definition: xlog.h:184
#define XLByteToSeg(xlrp, logSegNo)
#define NULL
Definition: c.h:226
uint64 XLogRecPtr
Definition: xlogdefs.h:21
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2350
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1606
static XLogCtlData * XLogCtl
Definition: xlog.c:700
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1110
#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:2226
void * palloc(Size size)
Definition: mcxt.c:891
TimeLineID ThisTimeLineID
Definition: pg_control.h:35
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:301
int pg_fsync(int fd)
Definition: fd.c:333
char d_name[MAX_PATH]
Definition: dirent.h:14
XLogRecPtr checkPoint
Definition: pg_control.h:130
XLogRecPtr redo
Definition: pg_control.h:33
void RequestCheckpoint(int flags)
Definition: checkpointer.c:967
XLogRecPtr do_pg_stop_backup ( char *  labelfile,
bool  waitforarchive,
TimeLineID stoptli_p 
)

Definition at line 10581 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().

10582 {
10583  bool exclusive = (labelfile == NULL);
10584  bool backup_started_in_recovery = false;
10585  XLogRecPtr startpoint;
10586  XLogRecPtr stoppoint;
10587  TimeLineID stoptli;
10588  pg_time_t stamp_time;
10589  char strfbuf[128];
10590  char histfilepath[MAXPGPATH];
10591  char startxlogfilename[MAXFNAMELEN];
10592  char stopxlogfilename[MAXFNAMELEN];
10593  char lastxlogfilename[MAXFNAMELEN];
10594  char histfilename[MAXFNAMELEN];
10595  char backupfrom[20];
10596  XLogSegNo _logSegNo;
10597  FILE *lfp;
10598  FILE *fp;
10599  char ch;
10600  int seconds_before_warning;
10601  int waits = 0;
10602  bool reported_waiting = false;
10603  char *remaining;
10604  char *ptr;
10605  uint32 hi,
10606  lo;
10607 
10608  backup_started_in_recovery = RecoveryInProgress();
10609 
10610  /*
10611  * Currently only non-exclusive backup can be taken during recovery.
10612  */
10613  if (backup_started_in_recovery && exclusive)
10614  ereport(ERROR,
10615  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10616  errmsg("recovery is in progress"),
10617  errhint("WAL control functions cannot be executed during recovery.")));
10618 
10619  /*
10620  * During recovery, we don't need to check WAL level. Because, if WAL
10621  * level is not sufficient, it's impossible to get here during recovery.
10622  */
10623  if (!backup_started_in_recovery && !XLogIsNeeded())
10624  ereport(ERROR,
10625  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10626  errmsg("WAL level not sufficient for making an online backup"),
10627  errhint("wal_level must be set to \"replica\" or \"logical\" at server start.")));
10628 
10629  if (exclusive)
10630  {
10631  /*
10632  * At first, mark that we're now stopping an exclusive backup,
10633  * to ensure that there are no other sessions currently running
10634  * pg_start_backup() or pg_stop_backup().
10635  */
10638  {
10640  ereport(ERROR,
10641  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10642  errmsg("exclusive backup not in progress")));
10643  }
10646 
10647  /*
10648  * Remove backup_label. In case of failure, the state for an exclusive
10649  * backup is switched back to in-progress.
10650  */
10652  {
10653  /*
10654  * Read the existing label file into memory.
10655  */
10656  struct stat statbuf;
10657  int r;
10658 
10659  if (stat(BACKUP_LABEL_FILE, &statbuf))
10660  {
10661  /* should not happen per the upper checks */
10662  if (errno != ENOENT)
10663  ereport(ERROR,
10665  errmsg("could not stat file \"%s\": %m",
10666  BACKUP_LABEL_FILE)));
10667  ereport(ERROR,
10668  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10669  errmsg("a backup is not in progress")));
10670  }
10671 
10672  lfp = AllocateFile(BACKUP_LABEL_FILE, "r");
10673  if (!lfp)
10674  {
10675  ereport(ERROR,
10677  errmsg("could not read file \"%s\": %m",
10678  BACKUP_LABEL_FILE)));
10679  }
10680  labelfile = palloc(statbuf.st_size + 1);
10681  r = fread(labelfile, statbuf.st_size, 1, lfp);
10682  labelfile[statbuf.st_size] = '\0';
10683 
10684  /*
10685  * Close and remove the backup label file
10686  */
10687  if (r != 1 || ferror(lfp) || FreeFile(lfp))
10688  ereport(ERROR,
10690  errmsg("could not read file \"%s\": %m",
10691  BACKUP_LABEL_FILE)));
10692  if (unlink(BACKUP_LABEL_FILE) != 0)
10693  ereport(ERROR,
10695  errmsg("could not remove file \"%s\": %m",
10696  BACKUP_LABEL_FILE)));
10697 
10698  /*
10699  * Remove tablespace_map file if present, it is created only if there
10700  * are tablespaces.
10701  */
10703  }
10705  }
10706 
10707  /*
10708  * OK to update backup counters and forcePageWrites
10709  */
10711  if (exclusive)
10712  {
10714  }
10715  else
10716  {
10717  /*
10718  * The user-visible pg_start/stop_backup() functions that operate on
10719  * exclusive backups can be called at any time, but for non-exclusive
10720  * backups, it is expected that each do_pg_start_backup() call is
10721  * matched by exactly one do_pg_stop_backup() call.
10722  */
10725  }
10726 
10729  {
10730  XLogCtl->Insert.forcePageWrites = false;
10731  }
10733 
10734  /*
10735  * Read and parse the START WAL LOCATION line (this code is pretty crude,
10736  * but we are not expecting any variability in the file format).
10737  */
10738  if (sscanf(labelfile, "START WAL LOCATION: %X/%X (file %24s)%c",
10739  &hi, &lo, startxlogfilename,
10740  &ch) != 4 || ch != '\n')
10741  ereport(ERROR,
10742  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10743  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
10744  startpoint = ((uint64) hi) << 32 | lo;
10745  remaining = strchr(labelfile, '\n') + 1; /* %n is not portable enough */
10746 
10747  /*
10748  * Parse the BACKUP FROM line. If we are taking an online backup from the
10749  * standby, we confirm that the standby has not been promoted during the
10750  * backup.
10751  */
10752  ptr = strstr(remaining, "BACKUP FROM:");
10753  if (!ptr || sscanf(ptr, "BACKUP FROM: %19s\n", backupfrom) != 1)
10754  ereport(ERROR,
10755  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10756  errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
10757  if (strcmp(backupfrom, "standby") == 0 && !backup_started_in_recovery)
10758  ereport(ERROR,
10759  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10760  errmsg("the standby was promoted during online backup"),
10761  errhint("This means that the backup being taken is corrupt "
10762  "and should not be used. "
10763  "Try taking another online backup.")));
10764 
10765  /*
10766  * During recovery, we don't write an end-of-backup record. We assume that
10767  * pg_control was backed up last and its minimum recovery point can be
10768  * available as the backup end location. Since we don't have an
10769  * end-of-backup record, we use the pg_control value to check whether
10770  * we've reached the end of backup when starting recovery from this
10771  * backup. We have no way of checking if pg_control wasn't backed up last
10772  * however.
10773  *
10774  * We don't force a switch to new WAL file and wait for all the required
10775  * files to be archived. This is okay if we use the backup to start the
10776  * standby. But, if it's for an archive recovery, to ensure all the
10777  * required files are available, a user should wait for them to be
10778  * archived, or include them into the backup.
10779  *
10780  * We return the current minimum recovery point as the backup end
10781  * location. Note that it can be greater than the exact backup end
10782  * location if the minimum recovery point is updated after the backup of
10783  * pg_control. This is harmless for current uses.
10784  *
10785  * XXX currently a backup history file is for informational and debug
10786  * purposes only. It's not essential for an online backup. Furthermore,
10787  * even if it's created, it will not be archived during recovery because
10788  * an archiver is not invoked. So it doesn't seem worthwhile to write a
10789  * backup history file during recovery.
10790  */
10791  if (backup_started_in_recovery)
10792  {
10793  XLogRecPtr recptr;
10794 
10795  /*
10796  * Check to see if all WAL replayed during online backup contain
10797  * full-page writes.
10798  */
10800  recptr = XLogCtl->lastFpwDisableRecPtr;
10802 
10803  if (startpoint <= recptr)
10804  ereport(ERROR,
10805  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
10806  errmsg("WAL generated with full_page_writes=off was replayed "
10807  "during online backup"),
10808  errhint("This means that the backup being taken on the standby "
10809  "is corrupt and should not be used. "
10810  "Enable full_page_writes and run CHECKPOINT on the master, "
10811  "and then try an online backup again.")));
10812 
10813 
10814  LWLockAcquire(ControlFileLock, LW_SHARED);
10815  stoppoint = ControlFile->minRecoveryPoint;
10816  stoptli = ControlFile->minRecoveryPointTLI;
10817  LWLockRelease(ControlFileLock);
10818 
10819  if (stoptli_p)
10820  *stoptli_p = stoptli;
10821  return stoppoint;
10822  }
10823 
10824  /*
10825  * Write the backup-end xlog record
10826  */
10827  XLogBeginInsert();
10828  XLogRegisterData((char *) (&startpoint), sizeof(startpoint));
10829  stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
10830  stoptli = ThisTimeLineID;
10831 
10832  /*
10833  * Force a switch to a new xlog segment file, so that the backup is valid
10834  * as soon as archiver moves out the current segment file.
10835  */
10836  RequestXLogSwitch(false);
10837 
10838  XLByteToPrevSeg(stoppoint, _logSegNo);
10839  XLogFileName(stopxlogfilename, ThisTimeLineID, _logSegNo);
10840 
10841  /* Use the log timezone here, not the session timezone */
10842  stamp_time = (pg_time_t) time(NULL);
10843  pg_strftime(strfbuf, sizeof(strfbuf),
10844  "%Y-%m-%d %H:%M:%S %Z",
10845  pg_localtime(&stamp_time, log_timezone));
10846 
10847  /*
10848  * Write the backup history file
10849  */
10850  XLByteToSeg(startpoint, _logSegNo);
10851  BackupHistoryFilePath(histfilepath, ThisTimeLineID, _logSegNo,
10852  (uint32) (startpoint % XLogSegSize));
10853  fp = AllocateFile(histfilepath, "w");
10854  if (!fp)
10855  ereport(ERROR,
10857  errmsg("could not create file \"%s\": %m",
10858  histfilepath)));
10859  fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n",
10860  (uint32) (startpoint >> 32), (uint32) startpoint, startxlogfilename);
10861  fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
10862  (uint32) (stoppoint >> 32), (uint32) stoppoint, stopxlogfilename);
10863  /* transfer remaining lines from label to history file */
10864  fprintf(fp, "%s", remaining);
10865  fprintf(fp, "STOP TIME: %s\n", strfbuf);
10866  if (fflush(fp) || ferror(fp) || FreeFile(fp))
10867  ereport(ERROR,
10869  errmsg("could not write file \"%s\": %m",
10870  histfilepath)));
10871 
10872  /*
10873  * Clean out any no-longer-needed history files. As a side effect, this
10874  * will post a .ready file for the newly created history file, notifying
10875  * the archiver that history file may be archived immediately.
10876  */
10878 
10879  /*
10880  * If archiving is enabled, wait for all the required WAL files to be
10881  * archived before returning. If archiving isn't enabled, the required WAL
10882  * needs to be transported via streaming replication (hopefully with
10883  * wal_keep_segments set high enough), or some more exotic mechanism like
10884  * polling and copying files from pg_wal with script. We have no
10885  * knowledge of those mechanisms, so it's up to the user to ensure that he
10886  * gets all the required WAL.
10887  *
10888  * We wait until both the last WAL file filled during backup and the
10889  * history file have been archived, and assume that the alphabetic sorting
10890  * property of the WAL files ensures any earlier WAL files are safely
10891  * archived as well.
10892  *
10893  * We wait forever, since archive_command is supposed to work and we
10894  * assume the admin wanted his backup to work completely. If you don't
10895  * wish to wait, you can set statement_timeout. Also, some notices are
10896  * issued to clue in anyone who might be doing this interactively.
10897  */
10898  if (waitforarchive && XLogArchivingActive())
10899  {
10900  XLByteToPrevSeg(stoppoint, _logSegNo);
10901  XLogFileName(lastxlogfilename, ThisTimeLineID, _logSegNo);
10902 
10903  XLByteToSeg(startpoint, _logSegNo);
10904  BackupHistoryFileName(histfilename, ThisTimeLineID, _logSegNo,
10905  (uint32) (startpoint % XLogSegSize));
10906 
10907  seconds_before_warning = 60;
10908  waits = 0;
10909 
10910  while (XLogArchiveIsBusy(lastxlogfilename) ||
10911  XLogArchiveIsBusy(histfilename))
10912  {
10914 
10915  if (!reported_waiting && waits > 5)
10916  {
10917  ereport(NOTICE,
10918  (errmsg("pg_stop_backup cleanup done, waiting for required WAL segments to be archived")));
10919  reported_waiting = true;
10920  }
10921 
10922  pg_usleep(1000000L);
10923 
10924  if (++waits >= seconds_before_warning)
10925  {
10926  seconds_before_warning *= 2; /* This wraps in >10 years... */
10927  ereport(WARNING,
10928  (errmsg("pg_stop_backup still waiting for all required WAL segments to be archived (%d seconds elapsed)",
10929  waits),
10930  errhint("Check that your archive_command is executing properly. "
10931  "pg_stop_backup can be canceled safely, "
10932  "but the database backup will not be usable without all the WAL segments.")));
10933  }
10934  }
10935 
10936  ereport(NOTICE,
10937  (errmsg("pg_stop_backup complete, all required WAL segments have been archived")));
10938  }
10939  else if (waitforarchive)
10940  ereport(NOTICE,
10941  (errmsg("WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup")));
10942 
10943  /*
10944  * We're done. As a convenience, return the ending WAL location.
10945  */
10946  if (stoptli_p)
10947  *stoptli_p = stoptli;
10948  return stoppoint;
10949 }
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:124
#define XLogSegSize
Definition: xlog_internal.h:92
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9322
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:1635
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:169
XLogRecPtr lastFpwDisableRecPtr
Definition: xlog.c:695
#define XLogIsNeeded()
Definition: xlog.h:145
slock_t info_lck
Definition: xlog.c:697
#define XLogFileName(fname, tli, logSegNo)
int errcode(int sqlerrcode)
Definition: elog.c:575
XLogCtlInsert Insert
Definition: xlog.c:569
bool RecoveryInProgress(void)
Definition: xlog.c:7805
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:1714
#define TABLESPACE_MAP
Definition: xlog.h:304
#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:542
#define ERROR
Definition: elog.h:43
static void CleanupBackupHistory(void)
Definition: xlog.c:4081
#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:2043
unsigned int uint32
Definition: c.h:265
#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:69
#define WARNING
Definition: elog.h:40
int nonExclusiveBackups
Definition: xlog.c:555
#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:554
uintptr_t Datum
Definition: postgres.h:374
static ControlFileData * ControlFile
Definition: xlog.c:708
#define BoolGetDatum(X)
Definition: postgres.h:410
TimeLineID ThisTimeLineID
Definition: xlog.c:178
#define NOTICE
Definition: elog.h:37
#define XLByteToSeg(xlrp, logSegNo)
bool XLogArchiveIsBusy(const char *xlog)
Definition: xlogarchive.c:658
#define NULL
Definition: c.h:226
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:671
#define XLogArchivingActive()
Definition: xlog.h:134
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1606
static XLogCtlData * XLogCtl
Definition: xlog.c:700
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1110
static void pg_stop_backup_callback(int code, Datum arg)
Definition: xlog.c:10553
#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:2226
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define BackupHistoryFilePath(path, tli, logSegNo, offset)
#define BACKUP_LABEL_FILE
Definition: xlog.h:301
#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:168
static int emode_for_corrupt_record ( int  emode,
XLogRecPtr  RecPtr 
)
static

Definition at line 11868 of file xlog.c.

References DEBUG1, LOG, readSource, and XLOG_FROM_PG_WAL.

Referenced by ReadRecord(), and XLogPageRead().

11869 {
11870  static XLogRecPtr lastComplaint = 0;
11871 
11872  if (readSource == XLOG_FROM_PG_WAL && emode == LOG)
11873  {
11874  if (RecPtr == lastComplaint)
11875  emode = DEBUG1;
11876  else
11877  lastComplaint = RecPtr;
11878  }
11879  return emode;
11880 }
#define DEBUG1
Definition: elog.h:25
static XLogSource readSource
Definition: xlog.c:777
#define LOG
Definition: elog.h:26
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static void exitArchiveRecovery ( TimeLineID  endTLI,
XLogRecPtr  endOfLog 
)
static

Definition at line 5408 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().

5409 {
5410  char recoveryPath[MAXPGPATH];
5411  char xlogfname[MAXFNAMELEN];
5412  XLogSegNo endLogSegNo;
5413  XLogSegNo startLogSegNo;
5414 
5415  /* we always switch to a new timeline after archive recovery */
5416  Assert(endTLI != ThisTimeLineID);
5417 
5418  /*
5419  * We are no longer in archive recovery state.
5420  */
5421  InArchiveRecovery = false;
5422 
5423  /*
5424  * Update min recovery point one last time.
5425  */
5427 
5428  /*
5429  * If the ending log segment is still open, close it (to avoid problems on
5430  * Windows with trying to rename or delete an open file).
5431  */
5432  if (readFile >= 0)
5433  {
5434  close(readFile);
5435  readFile = -1;
5436  }
5437 
5438  /*
5439  * Calculate the last segment on the old timeline, and the first segment
5440  * on the new timeline. If the switch happens in the middle of a segment,
5441  * they are the same, but if the switch happens exactly at a segment
5442  * boundary, startLogSegNo will be endLogSegNo + 1.
5443  */
5444  XLByteToPrevSeg(endOfLog, endLogSegNo);
5445  XLByteToSeg(endOfLog, startLogSegNo);
5446 
5447  /*
5448  * Initialize the starting WAL segment for the new timeline. If the switch
5449  * happens in the middle of a segment, copy data from the last WAL segment
5450  * of the old timeline up to the switch point, to the starting WAL segment
5451  * on the new timeline.
5452  */
5453  if (endLogSegNo == startLogSegNo)
5454  {
5455  /*
5456  * Make a copy of the file on the new timeline.
5457  *
5458  * Writing WAL isn't allowed yet, so there are no locking
5459  * considerations. But we should be just as tense as XLogFileInit to
5460  * avoid emplacing a bogus file.
5461  */
5462  XLogFileCopy(endLogSegNo, endTLI, endLogSegNo,
5463  endOfLog % XLOG_SEG_SIZE);
5464  }
5465  else
5466  {
5467  /*
5468  * The switch happened at a segment boundary, so just create the next
5469  * segment on the new timeline.
5470  */
5471  bool use_existent = true;
5472  int fd;
5473 
5474  fd = XLogFileInit(startLogSegNo, &use_existent, true);
5475 
5476  if (close(fd))
5477  ereport(ERROR,
5479  errmsg("could not close log file %s: %m",
5480  XLogFileNameP(ThisTimeLineID, startLogSegNo))));
5481  }
5482 
5483  /*
5484  * Let's just make real sure there are not .ready or .done flags posted
5485  * for the new segment.
5486  */
5487  XLogFileName(xlogfname, ThisTimeLineID, startLogSegNo);
5488  XLogArchiveCleanup(xlogfname);
5489 
5490  /*
5491  * Since there might be a partial WAL segment named RECOVERYXLOG, get rid
5492  * of it.
5493  */
5494  snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYXLOG");
5495  unlink(recoveryPath); /* ignore any error */
5496 
5497  /* Get rid of any remaining recovered timeline-history file, too */
5498  snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYHISTORY");
5499  unlink(recoveryPath); /* ignore any error */
5500 
5501  /*
5502  * Rename the config file out of the way, so that we don't accidentally
5503  * re-enter archive recovery mode in a subsequent crash.
5504  */
5507 
5508  ereport(LOG,
5509  (errmsg("archive recovery complete")));
5510 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition: xlog.c:2670
int XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
Definition: xlog.c:3141
#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:81
static void XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno, int upto)
Definition: xlog.c:3306
#define LOG
Definition: elog.h:26
#define RECOVERY_COMMAND_DONE
Definition: xlog.c:82
static int fd(const char *x, int i)
Definition: preproc-init.c:105
void XLogArchiveCleanup(const char *xlog)
Definition: xlogarchive.c:751
bool InArchiveRecovery
Definition: xlog.c:246
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
#define MAXPGPATH
char * XLogFileNameP(TimeLineID tli, XLogSegNo segno)
Definition: xlog.c:10040
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:178
#define XLByteToSeg(xlrp, logSegNo)
static int readFile
Definition: xlog.c:773
#define Assert(condition)
Definition: c.h:671
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 9910 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().

9911 {
9912  int o_direct_flag = 0;
9913 
9914  /* If fsync is disabled, never open in sync mode */
9915  if (!enableFsync)
9916  return 0;
9917 
9918  /*
9919  * Optimize writes by bypassing kernel cache with O_DIRECT when using
9920  * O_SYNC/O_FSYNC and O_DSYNC. But only if archiving and streaming are
9921  * disabled, otherwise the archive command or walsender process will read
9922  * the WAL soon after writing it, which is guaranteed to cause a physical
9923  * read if we bypassed the kernel cache. We also skip the
9924  * posix_fadvise(POSIX_FADV_DONTNEED) call in XLogFileClose() for the same
9925  * reason.
9926  *
9927  * Never use O_DIRECT in walreceiver process for similar reasons; the WAL
9928  * written by walreceiver is normally read by the startup process soon
9929  * after its written. Also, walreceiver performs unaligned writes, which
9930  * don't work with O_DIRECT, so it is required for correctness too.
9931  */
9932  if (!XLogIsNeeded() && !AmWalReceiverProcess())
9933  o_direct_flag = PG_O_DIRECT;
9934 
9935  switch (method)
9936  {
9937  /*
9938  * enum values for all sync options are defined even if they are
9939  * not supported on the current platform. But if not, they are
9940  * not included in the enum option array, and therefore will never
9941  * be seen here.
9942  */
9943  case SYNC_METHOD_FSYNC:
9945  case SYNC_METHOD_FDATASYNC:
9946  return 0;
9947 #ifdef OPEN_SYNC_FLAG
9948  case SYNC_METHOD_OPEN:
9949  return OPEN_SYNC_FLAG | o_direct_flag;
9950 #endif
9951 #ifdef OPEN_DATASYNC_FLAG
9953  return OPEN_DATASYNC_FLAG | o_direct_flag;
9954 #endif
9955  default:
9956  /* can't happen (unless we are out of sync with option array) */
9957  elog(ERROR, "unrecognized wal_sync_method: %d", method);
9958  return 0; /* silence warning */
9959  }
9960 }
#define PG_O_DIRECT
Definition: xlogdefs.h:65
#define SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:28
#define XLogIsNeeded()
Definition: xlog.h:145
#define SYNC_METHOD_OPEN_DSYNC
Definition: xlog.h:29
#define ERROR
Definition: elog.h:43
#define SYNC_METHOD_FSYNC
Definition: xlog.h:25
#define SYNC_METHOD_OPEN
Definition: xlog.h:27
#define AmWalReceiverProcess()
Definition: miscadmin.h:407
bool enableFsync
Definition: globals.c:110
#define SYNC_METHOD_FDATASYNC
Definition: xlog.h:26
#define elog
Definition: elog.h:219
TimestampTz GetCurrentChunkReplayStartTime ( void  )

Definition at line 6034 of file xlog.c.

References XLogCtlData::currentChunkStartTime, XLogCtlData::info_lck, SpinLockAcquire, and SpinLockRelease.

Referenced by GetReplicationApplyDelay().

6035 {
6036  TimestampTz xtime;
6037 
6038