PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
xlog.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <math.h>
#include <time.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include "access/clog.h"
#include "access/commit_ts.h"
#include "access/multixact.h"
#include "access/rewriteheap.h"
#include "access/subtrans.h"
#include "access/timeline.h"
#include "access/transam.h"
#include "access/tuptoaster.h"
#include "access/twophase.h"
#include "access/xact.h"
#include "access/xlog_internal.h"
#include "access/xloginsert.h"
#include "access/xlogreader.h"
#include "access/xlogutils.h"
#include "catalog/catversion.h"
#include "catalog/pg_control.h"
#include "catalog/pg_database.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "port/atomics.h"
#include "postmaster/bgwriter.h"
#include "postmaster/walwriter.h"
#include "postmaster/startup.h"
#include "replication/basebackup.h"
#include "replication/logical.h"
#include "replication/slot.h"
#include "replication/origin.h"
#include "replication/snapbuild.h"
#include "replication/walreceiver.h"
#include "replication/walsender.h"
#include "storage/bufmgr.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/large_object.h"
#include "storage/latch.h"
#include "storage/pmsignal.h"
#include "storage/predicate.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/reinit.h"
#include "storage/smgr.h"
#include "storage/spin.h"
#include "utils/backend_random.h"
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/pg_lsn.h"
#include "utils/ps_status.h"
#include "utils/relmapper.h"
#include "utils/snapmgr.h"
#include "utils/timestamp.h"
#include "pg_trace.h"
Include dependency graph for xlog.c:

Go to the source code of this file.

Data Structures

struct  XLogwrtRqst
 
struct  XLogwrtResult
 
struct  WALInsertLock
 
union  WALInsertLockPadded
 
struct  XLogCtlInsert
 
struct  XLogCtlData
 
struct  XLogPageReadPrivate
 

Macros

#define RECOVERY_COMMAND_FILE   "recovery.conf"
 
#define RECOVERY_COMMAND_DONE   "recovery.done"
 
#define PROMOTE_SIGNAL_FILE   "promote"
 
#define FALLBACK_PROMOTE_SIGNAL_FILE   "fallback_promote"
 
#define NUM_XLOGINSERT_LOCKS   8
 
#define INSERT_FREESPACE(endptr)   (((endptr) % XLOG_BLCKSZ == 0) ? 0 : (XLOG_BLCKSZ - (endptr) % XLOG_BLCKSZ))
 
#define NextBufIdx(idx)   (((idx) == XLogCtl->XLogCacheBlck) ? 0 : ((idx) + 1))
 
#define XLogRecPtrToBufIdx(recptr)   (((recptr) / XLOG_BLCKSZ) % (XLogCtl->XLogCacheBlck + 1))
 
#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)
 
#define UsableBytesInSegment   ((XLOG_SEG_SIZE / XLOG_BLCKSZ) * UsableBytesInPage - (SizeOfXLogLongPHD - SizeOfXLogShortPHD))
 
#define RecoveryRequiresIntParameter(param_name, currValue, minValue)
 

Typedefs

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

Enumerations

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

Functions

static void readRecoveryCommandFile (void)
 
static void exitArchiveRecovery (TimeLineID endTLI, XLogRecPtr endOfLog)
 
static bool recoveryStopsBefore (XLogReaderState *record)
 
static bool recoveryStopsAfter (XLogReaderState *record)
 
static void recoveryPausesHere (void)
 
static bool recoveryApplyDelay (XLogReaderState *record)
 
static void SetLatestXTime (TimestampTz xtime)
 
static void SetCurrentChunkStartTime (TimestampTz xtime)
 
static void CheckRequiredParameterValues (void)
 
static void XLogReportParameters (void)
 
static void checkTimeLineSwitch (XLogRecPtr lsn, TimeLineID newTLI, TimeLineID prevTLI)
 
static void LocalSetXLogInsertAllowed (void)
 
static void CreateEndOfRecoveryRecord (void)
 
static void CheckPointGuts (XLogRecPtr checkPointRedo, int flags)
 
static void KeepLogSeg (XLogRecPtr recptr, XLogSegNo *logSegNo)
 
static XLogRecPtr XLogGetReplicationSlotMinimumLSN (void)
 
static void AdvanceXLInsertBuffer (XLogRecPtr upto, bool opportunistic)
 
static bool XLogCheckpointNeeded (XLogSegNo new_segno)
 
static void XLogWrite (XLogwrtRqst WriteRqst, bool flexible)
 
static bool InstallXLogFileSegment (XLogSegNo *segno, char *tmppath, bool find_free, XLogSegNo max_segno, bool use_lock)
 
static int XLogFileRead (XLogSegNo segno, int emode, TimeLineID tli, int source, bool notfoundOk)
 
static int XLogFileReadAnyTLI (XLogSegNo segno, int emode, int source)
 
static int XLogPageRead (XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char *readBuf, TimeLineID *readTLI)
 
static bool WaitForWALToBecomeAvailable (XLogRecPtr RecPtr, bool randAccess, bool fetching_ckpt, XLogRecPtr tliRecPtr)
 
static int emode_for_corrupt_record (int emode, XLogRecPtr RecPtr)
 
static void XLogFileClose (void)
 
static void PreallocXlogFiles (XLogRecPtr endptr)
 
static void RemoveOldXlogFiles (XLogSegNo segno, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
 
static void RemoveXlogFile (const char *segname, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
 
static void UpdateLastRemovedPtr (char *filename)
 
static void ValidateXLOGDirectoryStructure (void)
 
static void CleanupBackupHistory (void)
 
static void UpdateMinRecoveryPoint (XLogRecPtr lsn, bool force)
 
static XLogRecordReadRecord (XLogReaderState *xlogreader, XLogRecPtr RecPtr, int emode, bool fetching_ckpt)
 
static void CheckRecoveryConsistency (void)
 
static XLogRecordReadCheckpointRecord (XLogReaderState *xlogreader, XLogRecPtr RecPtr, int whichChkpti, bool report)
 
static bool rescanLatestTimeLine (void)
 
static void WriteControlFile (void)
 
static void ReadControlFile (void)
 
static char * str_time (pg_time_t tnow)
 
static bool CheckForStandbyTrigger (void)
 
static void xlog_outdesc (StringInfo buf, XLogReaderState *record)
 
static void pg_start_backup_callback (int code, Datum arg)
 
static void pg_stop_backup_callback (int code, Datum arg)
 
static bool read_backup_label (XLogRecPtr *checkPointLoc, bool *backupEndRequired, bool *backupFromStandby)
 
static bool read_tablespace_map (List **tablespaces)
 
static void rm_redo_error_callback (void *arg)
 
static int get_sync_bit (int method)
 
static void CopyXLogRecordToWAL (int write_len, bool isLogSwitch, XLogRecData *rdata, XLogRecPtr StartPos, XLogRecPtr EndPos)
 
static void ReserveXLogInsertLocation (int size, XLogRecPtr *StartPos, XLogRecPtr *EndPos, XLogRecPtr *PrevPtr)
 
static bool ReserveXLogSwitch (XLogRecPtr *StartPos, XLogRecPtr *EndPos, XLogRecPtr *PrevPtr)
 
static XLogRecPtr WaitXLogInsertionsToFinish (XLogRecPtr upto)
 
static char * GetXLogBuffer (XLogRecPtr ptr)
 
static XLogRecPtr XLogBytePosToRecPtr (uint64 bytepos)
 
static XLogRecPtr XLogBytePosToEndRecPtr (uint64 bytepos)
 
static uint64 XLogRecPtrToBytePos (XLogRecPtr ptr)
 
static void checkXLogConsistency (XLogReaderState *record)
 
static void WALInsertLockAcquire (void)
 
static void WALInsertLockAcquireExclusive (void)
 
static void WALInsertLockRelease (void)
 
static void WALInsertLockUpdateInsertingAt (XLogRecPtr insertingAt)
 
XLogRecPtr XLogInsertRecord (XLogRecData *rdata, XLogRecPtr fpw_lsn, uint8 flags)
 
static void CalculateCheckpointSegments (void)
 
void assign_max_wal_size (int newval, void *extra)
 
void assign_checkpoint_completion_target (double newval, void *extra)
 
static XLogSegNo XLOGfileslop (XLogRecPtr PriorRedoPtr)
 
void XLogSetAsyncXactLSN (XLogRecPtr asyncXactLSN)
 
void XLogSetReplicationSlotMinimumLSN (XLogRecPtr lsn)
 
void XLogFlush (XLogRecPtr record)
 
bool XLogBackgroundFlush (void)
 
bool XLogNeedsFlush (XLogRecPtr record)
 
int XLogFileInit (XLogSegNo logsegno, bool *use_existent, bool use_lock)
 
static void XLogFileCopy (XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno, int upto)
 
int XLogFileOpen (XLogSegNo segno)
 
void CheckXLogRemoved (XLogSegNo segno, TimeLineID tli)
 
XLogSegNo XLogGetLastRemovedSegno (void)
 
static void RemoveNonParentXlogFiles (XLogRecPtr switchpoint, TimeLineID newTLI)
 
void UpdateControlFile (void)
 
uint64 GetSystemIdentifier (void)
 
char * GetMockAuthenticationNonce (void)
 
bool DataChecksumsEnabled (void)
 
XLogRecPtr GetFakeLSNForUnloggedRel (void)
 
static int XLOGChooseNumBuffers (void)
 
bool check_wal_buffers (int *newval, void **extra, GucSource source)
 
Size XLOGShmemSize (void)
 
void XLOGShmemInit (void)
 
void BootStrapXLOG (void)
 
static bool getRecordTimestamp (XLogReaderState *record, TimestampTz *recordXtime)
 
bool RecoveryIsPaused (void)
 
void SetRecoveryPause (bool recoveryPause)
 
TimestampTz GetLatestXTime (void)
 
TimestampTz GetCurrentChunkReplayStartTime (void)
 
void GetXLogReceiptTime (TimestampTz *rtime, bool *fromStream)
 
void StartupXLOG (void)
 
bool RecoveryInProgress (void)
 
bool HotStandbyActive (void)
 
bool HotStandbyActiveInReplay (void)
 
bool XLogInsertAllowed (void)
 
void InitXLOGAccess (void)
 
XLogRecPtr GetRedoRecPtr (void)
 
void GetFullPageWriteInfo (XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p)
 
XLogRecPtr GetInsertRecPtr (void)
 
XLogRecPtr GetFlushRecPtr (void)
 
XLogRecPtr GetLastImportantRecPtr (void)
 
pg_time_t GetLastSegSwitchData (XLogRecPtr *lastSwitchLSN)
 
void GetNextXidAndEpoch (TransactionId *xid, uint32 *epoch)
 
void ShutdownXLOG (int code, Datum arg)
 
static void LogCheckpointStart (int flags, bool restartpoint)
 
static void LogCheckpointEnd (bool restartpoint)
 
static void UpdateCheckPointDistanceEstimate (uint64 nbytes)
 
void CreateCheckPoint (int flags)
 
static void RecoveryRestartPoint (const CheckPoint *checkPoint)
 
bool CreateRestartPoint (int flags)
 
void XLogPutNextOid (Oid nextOid)
 
XLogRecPtr RequestXLogSwitch (bool mark_unimportant)
 
XLogRecPtr XLogRestorePoint (const char *rpName)
 
void UpdateFullPageWrites (void)
 
void xlog_redo (XLogReaderState *record)
 
void assign_xlog_sync_method (int new_sync_method, void *extra)
 
void issue_xlog_fsync (int fd, XLogSegNo segno)
 
char * XLogFileNameP (TimeLineID tli, XLogSegNo segno)
 
XLogRecPtr do_pg_start_backup (const char *backupidstr, bool fast, TimeLineID *starttli_p, StringInfo labelfile, DIR *tblspcdir, List **tablespaces, StringInfo tblspcmapfile, bool infotbssize, bool needtblspcmapfile)
 
SessionBackupState get_backup_status (void)
 
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 SessionBackupState sessionBackupState = SESSION_BACKUP_NONE
 
static XLogCtlDataXLogCtl = NULL
 
static WALInsertLockPaddedWALInsertLocks = NULL
 
static ControlFileDataControlFile = NULL
 
static XLogwrtResult LogwrtResult = {0, 0}
 
static const char * xlogSourceNames [] = {"any", "archive", "pg_wal", "stream"}
 
static int openLogFile = -1
 
static XLogSegNo openLogSegNo = 0
 
static uint32 openLogOff = 0
 
static int readFile = -1
 
static XLogSegNo readSegNo = 0
 
static uint32 readOff = 0
 
static uint32 readLen = 0
 
static XLogSource readSource = 0
 
static XLogSource currentSource = 0
 
static bool lastSourceFailed = false
 
static TimestampTz XLogReceiptTime = 0
 
static XLogSource XLogReceiptSource = 0
 
static XLogRecPtr ReadRecPtr
 
static XLogRecPtr EndRecPtr
 
static XLogRecPtr minRecoveryPoint
 
static TimeLineID minRecoveryPointTLI
 
static bool updateMinRecoveryPoint = true
 
bool reachedConsistency = false
 
static bool InRedo = false
 
static bool bgwriterLaunched = false
 
static int MyLockNo = 0
 
static bool holdingAllLocks = false
 

Macro Definition Documentation

#define FALLBACK_PROMOTE_SIGNAL_FILE   "fallback_promote"

Definition at line 85 of file xlog.c.

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

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

Definition at line 721 of file xlog.c.

Referenced by CopyXLogRecordToWAL(), and CreateCheckPoint().

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

Definition at line 725 of file xlog.c.

Referenced by XLogWrite().

#define PROMOTE_SIGNAL_FILE   "promote"

Definition at line 84 of file xlog.c.

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

#define RECOVERY_COMMAND_DONE   "recovery.done"

Definition at line 83 of file xlog.c.

Referenced by exitArchiveRecovery().

#define RECOVERY_COMMAND_FILE   "recovery.conf"

Definition at line 82 of file xlog.c.

Referenced by exitArchiveRecovery(), and readRecoveryCommandFile().

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

Definition at line 6123 of file xlog.c.

Referenced by CheckRequiredParameterValues().

#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)

Definition at line 738 of file xlog.c.

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

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

Definition at line 739 of file xlog.c.

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

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

Definition at line 732 of file xlog.c.

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

Typedef Documentation

Enumeration Type Documentation

Enumerator
EXCLUSIVE_BACKUP_NONE 
EXCLUSIVE_BACKUP_STARTING 
EXCLUSIVE_BACKUP_IN_PROGRESS 
EXCLUSIVE_BACKUP_STOPPING 

Definition at line 498 of file xlog.c.

enum XLogSource
Enumerator
XLOG_FROM_ANY 
XLOG_FROM_ARCHIVE 
XLOG_FROM_PG_WAL 
XLOG_FROM_STREAM 

Definition at line 751 of file xlog.c.

752 {
753  XLOG_FROM_ANY = 0, /* request to read WAL from any source */
754  XLOG_FROM_ARCHIVE, /* restored using restore_command */
755  XLOG_FROM_PG_WAL, /* existing file in pg_wal */
756  XLOG_FROM_STREAM /* streamed from master */
757 } XLogSource;
XLogSource
Definition: xlog.c:751

Function Documentation

static void AdvanceXLInsertBuffer ( XLogRecPtr  upto,
bool  opportunistic 
)
static

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

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

Definition at line 2237 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

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

Definition at line 2230 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size, and newval.

2231 {
2232  max_wal_size = newval;
2234 }
int max_wal_size
Definition: xlog.c:89
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2207
#define newval
void assign_xlog_sync_method ( int  new_sync_method,
void *  extra 
)

Definition at line 10033 of file xlog.c.

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

10034 {
10035  if (sync_method != new_sync_method)
10036  {
10037  /*
10038  * To ensure that no blocks escape unsynced, force an fsync on the
10039  * currently open log segment (if any). Also, if the open flag is
10040  * changing, close the log file so it will be reopened (with new flag
10041  * bit) at next use.
10042  */
10043  if (openLogFile >= 0)
10044  {
10046  if (pg_fsync(openLogFile) != 0)
10047  ereport(PANIC,
10049  errmsg("could not fsync log segment %s: %m",
10052  if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
10053  XLogFileClose();
10054  }
10055  }
10056 }
static int get_sync_bit(int method)
Definition: xlog.c:9977
#define PANIC
Definition: elog.h:53
static XLogSegNo openLogSegNo
Definition: xlog.c:769
static void XLogFileClose(void)
Definition: xlog.c:3702
char * XLogFileNameP(TimeLineID tli, XLogSegNo segno)
Definition: xlog.c:10109
int errcode_for_file_access(void)
Definition: elog.c:598
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1205
#define ereport(elevel, rest)
Definition: elog.h:122
static int openLogFile
Definition: xlog.c:768
TimeLineID ThisTimeLineID
Definition: xlog.c:179
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1181
int sync_method
Definition: xlog.c:103
int errmsg(const char *fmt,...)
Definition: elog.c:797
int pg_fsync(int fd)
Definition: fd.c:333
bool BackupInProgress ( void  )

Definition at line 11326 of file xlog.c.

References BACKUP_LABEL_FILE.

Referenced by pg_is_in_backup(), and PostmasterStateMachine().

11327 {
11328  struct stat stat_buf;
11329 
11330  return (stat(BACKUP_LABEL_FILE, &stat_buf) == 0);
11331 }
struct stat stat_buf
Definition: pg_standby.c:101
#define BACKUP_LABEL_FILE
Definition: xlog.h:321
void BootStrapXLOG ( void  )

Definition at line 4946 of file xlog.c.

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

Referenced by AuxiliaryProcessMain().

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

Definition at line 2207 of file xlog.c.

References CheckPointCompletionTarget, CheckPointSegments, and max_wal_size.

Referenced by assign_checkpoint_completion_target(), and assign_max_wal_size().

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

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

11347 {
11348  struct stat stat_buf;
11349 
11350  /* if the backup_label file is not there, return */
11351  if (stat(BACKUP_LABEL_FILE, &stat_buf) < 0)
11352  return;
11353 
11354  /* remove leftover file from previously canceled backup if it exists */
11356 
11358  {
11359  ereport(WARNING,
11361  errmsg("online backup mode was not canceled"),
11362  errdetail("File \"%s\" could not be renamed to \"%s\": %m.",
11364  return;
11365  }
11366 
11367  /* if the tablespace_map file is not there, return */
11368  if (stat(TABLESPACE_MAP, &stat_buf) < 0)
11369  {
11370  ereport(LOG,
11371  (errmsg("online backup mode canceled"),
11372  errdetail("File \"%s\" was renamed to \"%s\".",
11374  return;
11375  }
11376 
11377  /* remove leftover file from previously canceled backup if it exists */
11379 
11381  {
11382  ereport(LOG,
11383  (errmsg("online backup mode canceled"),
11384  errdetail("Files \"%s\" and \"%s\" were renamed to "
11385  "\"%s\" and \"%s\", respectively.",
11388  }
11389  else
11390  {
11391  ereport(WARNING,
11393  errmsg("online backup mode canceled"),
11394  errdetail("File \"%s\" was renamed to \"%s\", but "
11395  "file \"%s\" could not be renamed to \"%s\": %m.",
11398  }
11399 }
#define DEBUG1
Definition: elog.h:25
#define LOG
Definition: elog.h:26
#define BACKUP_LABEL_OLD
Definition: xlog.h:322
#define TABLESPACE_MAP
Definition: xlog.h:324
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:325
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define BACKUP_LABEL_FILE
Definition: xlog.h:321
bool check_wal_buffers ( int *  newval,
void **  extra,
GucSource  source 
)

Definition at line 4766 of file xlog.c.

References XLOGbuffers, and XLOGChooseNumBuffers().

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

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

11991 {
11992  struct stat stat_buf;
11993  static bool triggered = false;
11994 
11995  if (triggered)
11996  return true;
11997 
11998  if (IsPromoteTriggered())
11999  {
12000  /*
12001  * In 9.1 and 9.2 the postmaster unlinked the promote file inside the
12002  * signal handler. It now leaves the file in place and lets the
12003  * Startup process do the unlink. This allows Startup to know whether
12004  * it should create a full checkpoint before starting up (fallback
12005  * mode). Fast promotion takes precedence.
12006  */
12007  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
12008  {
12011  fast_promote = true;
12012  }
12013  else if (stat(FALLBACK_PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
12014  {
12016  fast_promote = false;
12017  }
12018 
12019  ereport(LOG, (errmsg("received promote request")));
12020 
12022  triggered = true;
12023  return true;
12024  }
12025 
12026  if (TriggerFile == NULL)
12027  return false;
12028 
12029  if (stat(TriggerFile, &stat_buf) == 0)
12030  {
12031  ereport(LOG,
12032  (errmsg("trigger file found: %s", TriggerFile)));
12034  triggered = true;
12035  fast_promote = true;
12036  return true;
12037  }
12038  else if (errno != ENOENT)
12039  ereport(ERROR,
12041  errmsg("could not stat trigger file \"%s\": %m",
12042  TriggerFile)));
12043 
12044  return false;
12045 }
void ResetPromoteTriggered(void)
Definition: startup.c:252
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.c:85
#define LOG
Definition: elog.h:26
static char * TriggerFile
Definition: xlog.c:274
#define ERROR
Definition: elog.h:43
struct stat stat_buf
Definition: pg_standby.c:101
#define PROMOTE_SIGNAL_FILE
Definition: xlog.c:84
int errcode_for_file_access(void)
Definition: elog.c:598
bool IsPromoteTriggered(void)
Definition: startup.c:246
int unlink(const char *filename)
#define ereport(elevel, rest)
Definition: elog.h:122
#define NULL
Definition: c.h:229
int errmsg(const char *fmt,...)
Definition: elog.c:797
static bool fast_promote
Definition: xlog.c:280
static void CheckPointGuts ( XLogRecPtr  checkPointRedo,
int  flags 
)
static

Definition at line 8984 of file xlog.c.

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

Referenced by CreateCheckPoint(), and CreateRestartPoint().

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

Definition at line 12062 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, and PROMOTE_SIGNAL_FILE.

Referenced by sigusr1_handler().

12063 {
12064  struct stat stat_buf;
12065 
12066  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
12068  return true;
12069 
12070  return false;
12071 }
#define FALLBACK_PROMOTE_SIGNAL_FILE
Definition: xlog.c:85
struct stat stat_buf
Definition: pg_standby.c:101
#define PROMOTE_SIGNAL_FILE
Definition: xlog.c:84
static void CheckRecoveryConsistency ( void  )
static

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

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

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

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

Definition at line 9542 of file xlog.c.

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

Referenced by StartupXLOG().

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

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

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

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

3763 {
3764  XLogSegNo lastRemovedSegNo;
3765 
3767  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3769 
3770  if (segno <= lastRemovedSegNo)
3771  {
3772  char filename[MAXFNAMELEN];
3773 
3774  XLogFileName(filename, tli, segno);
3775  ereport(ERROR,
3777  errmsg("requested WAL segment %s has already been removed",
3778  filename)));
3779  }
3780 }
slock_t info_lck
Definition: xlog.c:704
#define XLogFileName(fname, tli, logSegNo)
XLogSegNo lastRemovedSegNo
Definition: xlog.c:586
#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:707
static char * filename
Definition: pg_dumpall.c:87
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void CleanupBackupHistory ( void  )
static

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

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

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

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

Definition at line 8507 of file xlog.c.

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

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

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

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

8936 {
8937  xl_end_of_recovery xlrec;
8938  XLogRecPtr recptr;
8939 
8940  /* sanity check */
8941  if (!RecoveryInProgress())
8942  elog(ERROR, "can only be used to end recovery");
8943 
8944  xlrec.end_time = GetCurrentTimestamp();
8945 
8950 
8952 
8954 
8955  XLogBeginInsert();
8956  XLogRegisterData((char *) &xlrec, sizeof(xl_end_of_recovery));
8957  recptr = XLogInsert(RM_XLOG_ID, XLOG_END_OF_RECOVERY);
8958 
8959  XLogFlush(recptr);
8960 
8961  /*
8962  * Update the control file so that crash recovery can follow the timeline
8963  * changes to this point.
8964  */
8965  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8966  ControlFile->time = (pg_time_t) time(NULL);
8967  ControlFile->minRecoveryPoint = recptr;
8970  LWLockRelease(ControlFileLock);
8971 
8972  END_CRIT_SECTION();
8973 
8974  LocalXLogInsertAllowed = -1; /* return to "check" state */
8975 }
static int LocalXLogInsertAllowed
Definition: xlog.c:233
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1642
pg_time_t time
Definition: pg_control.h:131
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:171
TimeLineID PrevTimeLineID
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1569
#define END_CRIT_SECTION()
Definition: miscadmin.h:132
TimeLineID PrevTimeLineID
Definition: xlog.c:631
#define START_CRIT_SECTION()
Definition: miscadmin.h:130
bool RecoveryInProgress(void)
Definition: xlog.c:7863
#define XLOG_END_OF_RECOVERY
Definition: pg_control.h:75
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2754
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
void UpdateControlFile(void)
Definition: xlog.c:4641
#define ERROR
Definition: elog.h:43
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:7989
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:715
TimeLineID ThisTimeLineID
Definition: xlog.c:179
TimestampTz end_time
#define NULL
Definition: c.h:229
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1613
static XLogCtlData * XLogCtl
Definition: xlog.c:707
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
TimeLineID ThisTimeLineID
#define elog
Definition: elog.h:219
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:170
bool CreateRestartPoint ( int  flags)

Definition at line 9054 of file xlog.c.

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

Referenced by CheckpointerMain(), and ShutdownXLOG().

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

Definition at line 4710 of file xlog.c.

References Assert, ControlFileData::data_checksum_version, and NULL.

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

4711 {
4712  Assert(ControlFile != NULL);
4713  return (ControlFile->data_checksum_version > 0);
4714 }
uint32 data_checksum_version
Definition: pg_control.h:225
static ControlFileData * ControlFile
Definition: xlog.c:715
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
void do_pg_abort_backup ( void  )

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

11051 {
11055 
11058  {
11059  XLogCtl->Insert.forcePageWrites = false;
11060  }
11062 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1642
XLogCtlInsert Insert
Definition: xlog.c:576
bool forcePageWrites
Definition: xlog.c:549
int nonExclusiveBackups
Definition: xlog.c:562
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:561
#define Assert(condition)
Definition: c.h:675
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1613
static XLogCtlData * XLogCtl
Definition: xlog.c:707
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 10156 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(), SESSION_BACKUP_EXCLUSIVE, SESSION_BACKUP_NON_EXCLUSIVE, sessionBackupState, 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().

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

Definition at line 10663 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(), SESSION_BACKUP_NONE, sessionBackupState, 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().

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

Definition at line 11971 of file xlog.c.

References DEBUG1, LOG, readSource, and XLOG_FROM_PG_WAL.

Referenced by ReadRecord(), and XLogPageRead().

11972 {
11973  static XLogRecPtr lastComplaint = 0;
11974 
11975  if (readSource == XLOG_FROM_PG_WAL && emode == LOG)
11976  {
11977  if (RecPtr == lastComplaint)
11978  emode = DEBUG1;
11979  else
11980  lastComplaint = RecPtr;
11981  }
11982  return emode;
11983 }
#define DEBUG1
Definition: elog.h:25
static XLogSource readSource
Definition: xlog.c:784
#define LOG
Definition: elog.h:26
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static void exitArchiveRecovery ( TimeLineID  endTLI,
XLogRecPtr  endOfLog 
)
static

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

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