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 ConvertToXSegs(x)   (x / (XLOG_SEG_SIZE / (1024 * 1024)))
 
#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_mb = 1024
 
int min_wal_size_mb = 80
 
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 ConvertToXSegs (   x)    (x / (XLOG_SEG_SIZE / (1024 * 1024)))

Definition at line 740 of file xlog.c.

Referenced by CalculateCheckpointSegments(), and XLOGfileslop().

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

Referenced by CopyXLogRecordToWAL(), and CreateCheckPoint().

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

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

Referenced by CheckRequiredParameterValues().

#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)

Definition at line 736 of file xlog.c.

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

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

Definition at line 737 of file xlog.c.

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

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

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

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

Function Documentation

static void AdvanceXLInsertBuffer ( XLogRecPtr  upto,
bool  opportunistic 
)
static

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

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

Definition at line 2240 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

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

Definition at line 2233 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

2234 {
2237 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2210
int max_wal_size_mb
Definition: xlog.c:89
#define newval
void assign_xlog_sync_method ( int  new_sync_method,
void *  extra 
)

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

10061 {
10062  if (sync_method != new_sync_method)
10063  {
10064  /*
10065  * To ensure that no blocks escape unsynced, force an fsync on the
10066  * currently open log segment (if any). Also, if the open flag is
10067  * changing, close the log file so it will be reopened (with new flag
10068  * bit) at next use.
10069  */
10070  if (openLogFile >= 0)
10071  {
10073  if (pg_fsync(openLogFile) != 0)
10074  ereport(PANIC,
10076  errmsg("could not fsync log segment %s: %m",
10079  if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
10080  XLogFileClose();
10081  }
10082  }
10083 }
static int get_sync_bit(int method)
Definition: xlog.c:10004
#define PANIC
Definition: elog.h:53
static XLogSegNo openLogSegNo
Definition: xlog.c:771
static void XLogFileClose(void)
Definition: xlog.c:3705
char * XLogFileNameP(TimeLineID tli, XLogSegNo segno)
Definition: xlog.c:10136
int errcode_for_file_access(void)
Definition: elog.c:598
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1232
#define ereport(elevel, rest)
Definition: elog.h:122
static int openLogFile
Definition: xlog.c:770
TimeLineID ThisTimeLineID
Definition: xlog.c:179
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1208
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 11350 of file xlog.c.

References BACKUP_LABEL_FILE.

Referenced by pg_is_in_backup(), and PostmasterStateMachine().

11351 {
11352  struct stat stat_buf;
11353 
11354  return (stat(BACKUP_LABEL_FILE, &stat_buf) == 0);
11355 }
struct stat stat_buf
Definition: pg_standby.c:101
#define BACKUP_LABEL_FILE
Definition: xlog.h:320
void BootStrapXLOG ( void  )

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

4952 {
4953  CheckPoint checkPoint;
4954  char *buffer;
4955  XLogPageHeader page;
4956  XLogLongPageHeader longpage;
4957  XLogRecord *record;
4958  char *recptr;
4959  bool use_existent;
4960  uint64 sysidentifier;
4961  char mock_auth_nonce[MOCK_AUTH_NONCE_LEN];
4962  struct timeval tv;
4963  pg_crc32c crc;
4964 
4965  /*
4966  * Select a hopefully-unique system identifier code for this installation.
4967  * We use the result of gettimeofday(), including the fractional seconds
4968  * field, as being about as unique as we can easily get. (Think not to
4969  * use random(), since it hasn't been seeded and there's no portable way
4970  * to seed it other than the system clock value...) The upper half of the
4971  * uint64 value is just the tv_sec part, while the lower half contains the
4972  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
4973  * PID for a little extra uniqueness. A person knowing this encoding can
4974  * determine the initialization time of the installation, which could
4975  * perhaps be useful sometimes.
4976  */
4977  gettimeofday(&tv, NULL);
4978  sysidentifier = ((uint64) tv.tv_sec) << 32;
4979  sysidentifier |= ((uint64) tv.tv_usec) << 12;
4980  sysidentifier |= getpid() & 0xFFF;
4981 
4982  /*
4983  * Generate a random nonce. This is used for authentication requests that
4984  * will fail because the user does not exist. The nonce is used to create
4985  * a genuine-looking password challenge for the non-existent user, in lieu
4986  * of an actual stored password.
4987  */
4988  if (!pg_backend_random(mock_auth_nonce, MOCK_AUTH_NONCE_LEN))
4989  ereport(PANIC,
4990  (errcode(ERRCODE_INTERNAL_ERROR),
4991  errmsg("could not generate secret authorization token")));
4992 
4993  /* First timeline ID is always 1 */
4994  ThisTimeLineID = 1;
4995 
4996  /* page buffer must be aligned suitably for O_DIRECT */
4997  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
4998  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
4999  memset(page, 0, XLOG_BLCKSZ);
5000 
5001  /*
5002  * Set up information for the initial checkpoint record
5003  *
5004  * The initial checkpoint record is written to the beginning of the WAL
5005  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5006  * used, so that we can use 0/0 to mean "before any valid WAL segment".
5007  */
5008  checkPoint.redo = XLogSegSize + SizeOfXLogLongPHD;
5009  checkPoint.ThisTimeLineID = ThisTimeLineID;
5010  checkPoint.PrevTimeLineID = ThisTimeLineID;
5011  checkPoint.fullPageWrites = fullPageWrites;
5012  checkPoint.nextXidEpoch = 0;
5013  checkPoint.nextXid = FirstNormalTransactionId;
5014  checkPoint.nextOid = FirstBootstrapObjectId;
5015  checkPoint.nextMulti = FirstMultiXactId;
5016  checkPoint.nextMultiOffset = 0;
5017  checkPoint.oldestXid = FirstNormalTransactionId;
5018  checkPoint.oldestXidDB = TemplateDbOid;
5019  checkPoint.oldestMulti = FirstMultiXactId;
5020  checkPoint.oldestMultiDB = TemplateDbOid;
5023  checkPoint.time = (pg_time_t) time(NULL);
5025 
5026  ShmemVariableCache->nextXid = checkPoint.nextXid;
5027  ShmemVariableCache->nextOid = checkPoint.nextOid;
5029  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5030  AdvanceOldestClogXid(checkPoint.oldestXid);
5031  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5032  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5034 
5035  /* Set up the XLOG page header */
5036  page->xlp_magic = XLOG_PAGE_MAGIC;
5037  page->xlp_info = XLP_LONG_HEADER;
5038  page->xlp_tli = ThisTimeLineID;
5039  page->xlp_pageaddr = XLogSegSize;
5040  longpage = (XLogLongPageHeader) page;
5041  longpage->xlp_sysid = sysidentifier;
5042  longpage->xlp_seg_size = XLogSegSize;
5043  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5044 
5045  /* Insert the initial checkpoint record */
5046  recptr = ((char *) page + SizeOfXLogLongPHD);
5047  record = (XLogRecord *) recptr;
5048  record->xl_prev = 0;
5049  record->xl_xid = InvalidTransactionId;
5050  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5052  record->xl_rmid = RM_XLOG_ID;
5053  recptr += SizeOfXLogRecord;
5054  /* fill the XLogRecordDataHeaderShort struct */
5055  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5056  *(recptr++) = sizeof(checkPoint);
5057  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5058  recptr += sizeof(checkPoint);
5059  Assert(recptr - (char *) record == record->xl_tot_len);
5060 
5061  INIT_CRC32C(crc);
5062  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5063  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5064  FIN_CRC32C(crc);
5065  record->xl_crc = crc;
5066 
5067  /* Create first XLOG segment file */
5068  use_existent = false;
5069  openLogFile = XLogFileInit(1, &use_existent, false);
5070 
5071  /* Write the first page with the initial record */
5072  errno = 0;
5074  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5075  {
5076  /* if write didn't set errno, assume problem is no disk space */
5077  if (errno == 0)
5078  errno = ENOSPC;
5079  ereport(PANIC,
5081  errmsg("could not write bootstrap write-ahead log file: %m")));
5082  }
5084 
5086  if (pg_fsync(openLogFile) != 0)
5087  ereport(PANIC,
5089  errmsg("could not fsync bootstrap write-ahead log file: %m")));
5091 
5092  if (close(openLogFile))
5093  ereport(PANIC,
5095  errmsg("could not close bootstrap write-ahead log file: %m")));
5096 
5097  openLogFile = -1;
5098 
5099  /* Now create pg_control */
5100 
5101  memset(ControlFile, 0, sizeof(ControlFileData));
5102  /* Initialize pg_control status fields */
5103  ControlFile->system_identifier = sysidentifier;
5104  memcpy(ControlFile->mock_authentication_nonce, mock_auth_nonce, MOCK_AUTH_NONCE_LEN);
5106  ControlFile->time = checkPoint.time;
5107  ControlFile->checkPoint = checkPoint.redo;
5108  ControlFile->checkPointCopy = checkPoint;
5109  ControlFile->unloggedLSN = 1;
5110 
5111  /* Set important parameter values for use when replaying WAL */
5120 
5121  /* some additional ControlFile fields are set in WriteControlFile() */
5122 
5123  WriteControlFile();
5124 
5125  /* Bootstrap the commit log, too */
5126  BootStrapCLOG();
5130 
5131  pfree(buffer);
5132 }
static void WriteControlFile(void)
Definition: xlog.c:4376
#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:182
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:105
int max_prepared_xacts
Definition: pg_control.h:181
int64 pg_time_t
Definition: pgtime.h:23
pg_time_t time
Definition: pg_control.h:128
void SetCommitTsLimit(TransactionId oldestXact, TransactionId newestXact)
Definition: commit_ts.c:849
uint32 oidCount
Definition: transam.h:112
#define write(a, b, c)
Definition: win32.h:14
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:201
int max_worker_processes
Definition: pg_control.h:180
uint32 pg_crc32c
Definition: pg_crc32c.h:38
TransactionId oldestActiveXid
Definition: pg_control.h:63
int wal_level
Definition: xlog.c:104
int XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
Definition: xlog.c:3153
void BootStrapMultiXact(void)
Definition: multixact.c:1866
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: pg_control.h:39
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:132
TransactionId oldestXid
Definition: pg_control.h:47
TransactionId nextXid
Definition: pg_control.h:43
pg_time_t time
Definition: pg_control.h:51
#define PANIC
Definition: elog.h:53
uint32 bootstrap_data_checksum_version
Definition: bootstrap.c:49
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:74
#define MOCK_AUTH_NONCE_LEN
Definition: pg_control.h:27
bool fullPageWrites
Definition: xlog.c:97
void BootStrapSUBTRANS(void)
Definition: subtrans.c:212
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid)
Definition: varsup.c:271
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
void pfree(void *pointer)
Definition: mcxt.c:950
#define FirstNormalTransactionId
Definition: transam.h:34
int max_prepared_xacts
Definition: twophase.c:117
uint64 system_identifier
Definition: pg_control.h:106
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:42
bool track_commit_timestamp
Definition: commit_ts.c:103
#define TemplateDbOid
Definition: pg_database.h:80
uint32 data_checksum_version
Definition: pg_control.h:222
bool pg_backend_random(char *dst, int len)
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
XLogRecPtr unloggedLSN
Definition: pg_control.h:134
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:1232
#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:54
char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]
Definition: pg_control.h:229
int MaxConnections
Definition: globals.c:124
Oid oldestMultiDB
Definition: pg_control.h:50
static int openLogFile
Definition: xlog.c:770
static ControlFileData * ControlFile
Definition: xlog.c:713
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:44
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:581
bool fullPageWrites
Definition: pg_control.h:41
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:183
#define Assert(condition)
Definition: c.h:675
#define XLP_LONG_HEADER
Definition: xlog_internal.h:79
Oid oldestXidDB
Definition: pg_control.h:48
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1208
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:45
pg_crc32c xl_crc
Definition: xlogrecord.h:49
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:224
TransactionId xl_xid
Definition: xlogrecord.h:44
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
void * palloc(Size size)
Definition: mcxt.c:849
int errmsg(const char *fmt,...)
Definition: elog.c:797
int max_worker_processes
Definition: globals.c:125
int pg_fsync(int fd)
Definition: fd.c:333
#define close(a)
Definition: win32.h:12
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:129
XLogRecPtr redo
Definition: pg_control.h:36
#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 2210 of file xlog.c.

References CheckPointCompletionTarget, CheckPointSegments, ConvertToXSegs, and max_wal_size_mb.

Referenced by assign_checkpoint_completion_target(), and assign_max_wal_size().

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

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

11371 {
11372  struct stat stat_buf;
11373 
11374  /* if the backup_label file is not there, return */
11375  if (stat(BACKUP_LABEL_FILE, &stat_buf) < 0)
11376  return;
11377 
11378  /* remove leftover file from previously canceled backup if it exists */
11380 
11382  {
11383  ereport(WARNING,
11385  errmsg("online backup mode was not canceled"),
11386  errdetail("File \"%s\" could not be renamed to \"%s\": %m.",
11388  return;
11389  }
11390 
11391  /* if the tablespace_map file is not there, return */
11392  if (stat(TABLESPACE_MAP, &stat_buf) < 0)
11393  {
11394  ereport(LOG,
11395  (errmsg("online backup mode canceled"),
11396  errdetail("File \"%s\" was renamed to \"%s\".",
11398  return;
11399  }
11400 
11401  /* remove leftover file from previously canceled backup if it exists */
11403 
11405  {
11406  ereport(LOG,
11407  (errmsg("online backup mode canceled"),
11408  errdetail("Files \"%s\" and \"%s\" were renamed to "
11409  "\"%s\" and \"%s\", respectively.",
11412  }
11413  else
11414  {
11415  ereport(WARNING,
11417  errmsg("online backup mode canceled"),
11418  errdetail("File \"%s\" was renamed to \"%s\", but "
11419  "file \"%s\" could not be renamed to \"%s\": %m.",
11422  }
11423 }
#define DEBUG1
Definition: elog.h:25
#define LOG
Definition: elog.h:26
#define BACKUP_LABEL_OLD
Definition: xlog.h:321
#define TABLESPACE_MAP
Definition: xlog.h:323
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:324
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define BACKUP_LABEL_FILE
Definition: xlog.h:320
bool check_wal_buffers ( int *  newval,
void **  extra,
GucSource  source 
)

Definition at line 4771 of file xlog.c.

References XLOGbuffers, and XLOGChooseNumBuffers().

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

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

12015 {
12016  struct stat stat_buf;
12017  static bool triggered = false;
12018 
12019  if (triggered)
12020  return true;
12021 
12022  if (IsPromoteTriggered())
12023  {
12024  /*
12025  * In 9.1 and 9.2 the postmaster unlinked the promote file inside the
12026  * signal handler. It now leaves the file in place and lets the
12027  * Startup process do the unlink. This allows Startup to know whether
12028  * it should create a full checkpoint before starting up (fallback
12029  * mode). Fast promotion takes precedence.
12030  */
12031  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
12032  {
12035  fast_promote = true;
12036  }
12037  else if (stat(FALLBACK_PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
12038  {
12040  fast_promote = false;
12041  }
12042 
12043  ereport(LOG, (errmsg("received promote request")));
12044 
12046  triggered = true;
12047  return true;
12048  }
12049 
12050  if (TriggerFile == NULL)
12051  return false;
12052 
12053  if (stat(TriggerFile, &stat_buf) == 0)
12054  {
12055  ereport(LOG,
12056  (errmsg("trigger file found: %s", TriggerFile)));
12058  triggered = true;
12059  fast_promote = true;
12060  return true;
12061  }
12062  else if (errno != ENOENT)
12063  ereport(ERROR,
12065  errmsg("could not stat trigger file \"%s\": %m",
12066  TriggerFile)));
12067 
12068  return false;
12069 }
void ResetPromoteTriggered(void)
Definition: startup.c:253
#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:247
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 9010 of file xlog.c.

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

Referenced by CreateCheckPoint(), and CreateRestartPoint().

9011 {
9012  CheckPointCLOG();
9021  CheckPointBuffers(flags); /* performs all required fsyncs */
9023  /* We deliberately delay 2PC checkpointing as long as possible */
9024  CheckPointTwoPhase(checkPointRedo);
9025 }
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:1862
void CheckPointCLOG(void)
Definition: clog.c:594
void CheckPointMultiXact(void)
Definition: multixact.c:2140
void CheckPointCommitTs(void)
Definition: commit_ts.c:761
void CheckPointSUBTRANS(void)
Definition: subtrans.c:300
void CheckPointRelationMap(void)
Definition: relmapper.c:524
void CheckPointPredicate(void)
Definition: predicate.c:1041
void CheckPointTwoPhase(XLogRecPtr redo_horizon)
Definition: twophase.c:1651
void CheckPointReplicationSlots(void)
Definition: slot.c:1054
bool CheckPromoteSignal ( void  )

Definition at line 12086 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, and PROMOTE_SIGNAL_FILE.

Referenced by sigusr1_handler().

12087 {
12088  struct stat stat_buf;
12089 
12090  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
12092  return true;
12093 
12094  return false;
12095 }
#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 7779 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().

7780 {
7781  XLogRecPtr lastReplayedEndRecPtr;
7782 
7783  /*
7784  * During crash recovery, we don't reach a consistent state until we've
7785  * replayed all the WAL.
7786  */
7788  return;
7789 
7790  /*
7791  * assume that we are called in the startup process, and hence don't need
7792  * a lock to read lastReplayedEndRecPtr
7793  */
7794  lastReplayedEndRecPtr = XLogCtl->lastReplayedEndRecPtr;
7795 
7796  /*
7797  * Have we reached the point where our base backup was completed?
7798  */
7800  ControlFile->backupEndPoint <= lastReplayedEndRecPtr)
7801  {
7802  /*
7803  * We have reached the end of base backup, as indicated by pg_control.
7804  * The data on disk is now consistent. Reset backupStartPoint and
7805  * backupEndPoint, and update minRecoveryPoint to make sure we don't
7806  * allow starting up at an earlier point even if recovery is stopped
7807  * and restarted soon after this.
7808  */
7809  elog(DEBUG1, "end of backup reached");
7810 
7811  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7812 
7813  if (ControlFile->minRecoveryPoint < lastReplayedEndRecPtr)
7814  ControlFile->minRecoveryPoint = lastReplayedEndRecPtr;
7815 
7818  ControlFile->backupEndRequired = false;
7820 
7821  LWLockRelease(ControlFileLock);
7822  }
7823 
7824  /*
7825  * Have we passed our safe starting point? Note that minRecoveryPoint is
7826  * known to be incorrectly set if ControlFile->backupEndRequired, until
7827  * the XLOG_BACKUP_RECORD arrives to advise us of the correct
7828  * minRecoveryPoint. All we know prior to that is that we're not
7829  * consistent yet.
7830  */
7832  minRecoveryPoint <= lastReplayedEndRecPtr &&
7834  {
7835  /*
7836  * Check to see if the XLOG sequence contained any unresolved
7837  * references to uninitialized pages.
7838  */
7840 
7841  reachedConsistency = true;
7842  ereport(LOG,
7843  (errmsg("consistent recovery state reached at %X/%X",
7844  (uint32) (lastReplayedEndRecPtr >> 32),
7845  (uint32) lastReplayedEndRecPtr)));
7846  }
7847 
7848  /*
7849  * Have we got a valid starting snapshot that will allow queries to be
7850  * run? If so, we can tell postmaster that the database is consistent now,
7851  * enabling connections.
7852  */
7857  {
7861 
7862  LocalHotStandbyActive = true;
7863 
7865  }
7866 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define DEBUG1
Definition: elog.h:25
void XLogCheckInvalidPages(void)
Definition: xlogutils.c:221
bool SharedHotStandbyActive
Definition: xlog.c:647
slock_t info_lck
Definition: xlog.c:702
#define LOG
Definition: elog.h:26
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
bool backupEndRequired
Definition: pg_control.h:171
#define SpinLockAcquire(lock)
Definition: spin.h:62
static bool LocalHotStandbyActive
Definition: xlog.c:221
void UpdateControlFile(void)
Definition: xlog.c:4646
bool IsUnderPostmaster
Definition: globals.c:101
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:713
XLogRecPtr backupEndPoint
Definition: pg_control.h:170
bool reachedConsistency
Definition: xlog.c:830
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static XLogCtlData * XLogCtl
Definition: xlog.c:705
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:169
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:167
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:820
XLogRecPtr lastReplayedEndRecPtr
Definition: xlog.c:681
static void CheckRequiredParameterValues ( void  )
static

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

6151 {
6152  /*
6153  * For archive recovery, the WAL must be generated with at least 'replica'
6154  * wal_level.
6155  */
6157  {
6158  ereport(WARNING,
6159  (errmsg("WAL was generated with wal_level=minimal, data may be missing"),
6160  errhint("This happens if you temporarily set wal_level=minimal without taking a new base backup.")));
6161  }
6162 
6163  /*
6164  * For Hot Standby, the WAL must be generated with 'replica' mode, and we
6165  * must have at least as many backend slots as the primary.
6166  */
6168  {
6170  ereport(ERROR,
6171  (errmsg("hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server"),
6172  errhint("Either set wal_level to \"replica\" on the master, or turn off hot_standby here.")));
6173 
6174  /* We ignore autovacuum_max_workers when we make this test. */
6175  RecoveryRequiresIntParameter("max_connections",
6178  RecoveryRequiresIntParameter("max_worker_processes",
6181  RecoveryRequiresIntParameter("max_prepared_transactions",
6184  RecoveryRequiresIntParameter("max_locks_per_transaction",
6187  }
6188 }
bool ArchiveRecoveryRequested
Definition: xlog.c:246
int max_locks_per_xact
Definition: pg_control.h:182
int errhint(const char *fmt,...)
Definition: elog.c:987
int max_prepared_xacts
Definition: pg_control.h:181
int max_worker_processes
Definition: pg_control.h:180
#define ERROR
Definition: elog.h:43
int max_prepared_xacts
Definition: twophase.c:117
#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:124
static ControlFileData * ControlFile
Definition: xlog.c:713
bool EnableHotStandby
Definition: xlog.c:96
int errmsg(const char *fmt,...)
Definition: elog.c:797
int max_worker_processes
Definition: globals.c:125
#define RecoveryRequiresIntParameter(param_name, currValue, minValue)
Definition: xlog.c:6128
static void checkTimeLineSwitch ( XLogRecPtr  lsn,
TimeLineID  newTLI,
TimeLineID  prevTLI 
)
static

Definition at line 9568 of file xlog.c.

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

Referenced by StartupXLOG().

9569 {
9570  /* Check that the record agrees on what the current (old) timeline is */
9571  if (prevTLI != ThisTimeLineID)
9572  ereport(PANIC,
9573  (errmsg("unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record",
9574  prevTLI, ThisTimeLineID)));
9575 
9576  /*
9577  * The new timeline better be in the list of timelines we expect to see,
9578  * according to the timeline history. It should also not decrease.
9579  */
9580  if (newTLI < ThisTimeLineID || !tliInHistory(newTLI, expectedTLEs))
9581  ereport(PANIC,
9582  (errmsg("unexpected timeline ID %u (after %u) in checkpoint record",
9583  newTLI, ThisTimeLineID)));
9584 
9585  /*
9586  * If we have not yet reached min recovery point, and we're about to
9587  * switch to a timeline greater than the timeline of the min recovery
9588  * point: trouble. After switching to the new timeline, we could not
9589  * possibly visit the min recovery point on the correct timeline anymore.
9590  * This can happen if there is a newer timeline in the archive that
9591  * branched before the timeline the min recovery point is on, and you
9592  * attempt to do PITR to the new timeline.
9593  */
9595  lsn < minRecoveryPoint &&
9596  newTLI > minRecoveryPointTLI)
9597  ereport(PANIC,
9598  (errmsg("unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u",
9599  newTLI,
9600  (uint32) (minRecoveryPoint >> 32),
9603 
9604  /* Looks good */
9605 }
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:822
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:820
static void checkXLogConsistency ( XLogReaderState record)
static

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

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

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

3766 {
3767  XLogSegNo lastRemovedSegNo;
3768 
3770  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3772 
3773  if (segno <= lastRemovedSegNo)
3774  {
3775  char filename[MAXFNAMELEN];
3776 
3777  XLogFileName(filename, tli, segno);
3778  ereport(ERROR,
3780  errmsg("requested WAL segment %s has already been removed",
3781  filename)));
3782  }
3783 }
slock_t info_lck
Definition: xlog.c:702
#define XLogFileName(fname, tli, logSegNo)
XLogSegNo lastRemovedSegNo
Definition: xlog.c:585
#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:705
static char * filename
Definition: pg_dumpall.c:89
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, elog, 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 + sizeof(XLOGDIR)];
4105 
4106  xldir = AllocateDir(XLOGDIR);
4107  if (xldir == NULL)
4108  ereport(ERROR,
4110  errmsg("could not open write-ahead 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  elog(DEBUG2, "removing WAL backup history file \"%s\"",
4120  xlde->d_name);
4121  snprintf(path, sizeof(path), XLOGDIR "/%s", xlde->d_name);
4122  unlink(path);
4123  XLogArchiveCleanup(xlde->d_name);
4124  }
4125  }
4126  }
4127 
4128  FreeDir(xldir);
4129 }
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:2335
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:2401
int errmsg(const char *fmt,...)
Definition: elog.c:797
char d_name[MAX_PATH]
Definition: dirent.h:14
#define elog
Definition: elog.h:219
int FreeDir(DIR *dir)
Definition: fd.c:2444
static void CopyXLogRecordToWAL ( int  write_len,
bool  isLogSwitch,
XLogRecData rdata,
XLogRecPtr  StartPos,
XLogRecPtr  EndPos 
)
static

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

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

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

8534 {
8535  bool shutdown;
8536  CheckPoint checkPoint;
8537  XLogRecPtr recptr;
8539  uint32 freespace;
8540  XLogRecPtr PriorRedoPtr;
8541  XLogRecPtr curInsert;
8542  XLogRecPtr last_important_lsn;
8543  VirtualTransactionId *vxids;
8544  int nvxids;
8545 
8546  /*
8547  * An end-of-recovery checkpoint is really a shutdown checkpoint, just
8548  * issued at a different time.
8549  */
8551  shutdown = true;
8552  else
8553  shutdown = false;
8554 
8555  /* sanity check */
8556  if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
8557  elog(ERROR, "can't create a checkpoint during recovery");
8558 
8559  /*
8560  * Initialize InitXLogInsert working areas before entering the critical
8561  * section. Normally, this is done by the first call to
8562  * RecoveryInProgress() or LocalSetXLogInsertAllowed(), but when creating
8563  * an end-of-recovery checkpoint, the LocalSetXLogInsertAllowed call is
8564  * done below in a critical section, and InitXLogInsert cannot be called
8565  * in a critical section.
8566  */
8567  InitXLogInsert();
8568 
8569  /*
8570  * Acquire CheckpointLock to ensure only one checkpoint happens at a time.
8571  * (This is just pro forma, since in the present system structure there is
8572  * only one process that is allowed to issue checkpoints at any given
8573  * time.)
8574  */
8575  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
8576 
8577  /*
8578  * Prepare to accumulate statistics.
8579  *
8580  * Note: because it is possible for log_checkpoints to change while a
8581  * checkpoint proceeds, we always accumulate stats, even if
8582  * log_checkpoints is currently off.
8583  */
8584  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
8586 
8587  /*
8588  * Use a critical section to force system panic if we have trouble.
8589  */
8591 
8592  if (shutdown)
8593  {
8594  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8596  ControlFile->time = (pg_time_t) time(NULL);
8598  LWLockRelease(ControlFileLock);
8599  }
8600 
8601  /*
8602  * Let smgr prepare for checkpoint; this has to happen before we determine
8603  * the REDO pointer. Note that smgr must not do anything that'd have to
8604  * be undone if we decide no checkpoint is needed.
8605  */
8606  smgrpreckpt();
8607 
8608  /* Begin filling in the checkpoint WAL record */
8609  MemSet(&checkPoint, 0, sizeof(checkPoint));
8610  checkPoint.time = (pg_time_t) time(NULL);
8611 
8612  /*
8613  * For Hot Standby, derive the oldestActiveXid before we fix the redo
8614  * pointer. This allows us to begin accumulating changes to assemble our
8615  * starting snapshot of locks and transactions.
8616  */
8617  if (!shutdown && XLogStandbyInfoActive())
8619  else
8621 
8622  /*
8623  * Get location of last important record before acquiring insert locks (as
8624  * GetLastImportantRecPtr() also locks WAL locks).
8625  */
8626  last_important_lsn = GetLastImportantRecPtr();
8627 
8628  /*
8629  * We must block concurrent insertions while examining insert state to
8630  * determine the checkpoint REDO pointer.
8631  */
8633  curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);
8634 
8635  /*
8636  * If this isn't a shutdown or forced checkpoint, and if there has been no
8637  * WAL activity requiring a checkpoint, skip it. The idea here is to
8638  * avoid inserting duplicate checkpoints when the system is idle.
8639  */
8640  if ((flags & (CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_END_OF_RECOVERY |
8641  CHECKPOINT_FORCE)) == 0)
8642  {
8643  if (last_important_lsn == ControlFile->checkPoint)
8644  {
8646  LWLockRelease(CheckpointLock);
8647  END_CRIT_SECTION();
8648  ereport(DEBUG1,
8649  (errmsg("checkpoint skipped due to an idle system")));
8650  return;
8651  }
8652  }
8653 
8654  /*
8655  * An end-of-recovery checkpoint is created before anyone is allowed to
8656  * write WAL. To allow us to write the checkpoint record, temporarily
8657  * enable XLogInsertAllowed. (This also ensures ThisTimeLineID is
8658  * initialized, which we need here and in AdvanceXLInsertBuffer.)
8659  */
8660  if (flags & CHECKPOINT_END_OF_RECOVERY)
8662 
8663  checkPoint.ThisTimeLineID = ThisTimeLineID;
8664  if (flags & CHECKPOINT_END_OF_RECOVERY)
8665  checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
8666  else
8667  checkPoint.PrevTimeLineID = ThisTimeLineID;
8668 
8669  checkPoint.fullPageWrites = Insert->fullPageWrites;
8670 
8671  /*
8672  * Compute new REDO record ptr = location of next XLOG record.
8673  *
8674  * NB: this is NOT necessarily where the checkpoint record itself will be,
8675  * since other backends may insert more XLOG records while we're off doing
8676  * the buffer flush work. Those XLOG records are logically after the
8677  * checkpoint, even though physically before it. Got that?
8678  */
8679  freespace = INSERT_FREESPACE(curInsert);
8680  if (freespace == 0)
8681  {
8682  if (curInsert % XLogSegSize == 0)
8683  curInsert += SizeOfXLogLongPHD;
8684  else
8685  curInsert += SizeOfXLogShortPHD;
8686  }
8687  checkPoint.redo = curInsert;
8688 
8689  /*
8690  * Here we update the shared RedoRecPtr for future XLogInsert calls; this
8691  * must be done while holding all the insertion locks.
8692  *
8693  * Note: if we fail to complete the checkpoint, RedoRecPtr will be left
8694  * pointing past where it really needs to point. This is okay; the only
8695  * consequence is that XLogInsert might back up whole buffers that it
8696  * didn't really need to. We can't postpone advancing RedoRecPtr because
8697  * XLogInserts that happen while we are dumping buffers must assume that
8698  * their buffer changes are not included in the checkpoint.
8699  */
8700  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
8701 
8702  /*
8703  * Now we can release the WAL insertion locks, allowing other xacts to
8704  * proceed while we are flushing disk buffers.
8705  */
8707 
8708  /* Update the info_lck-protected copy of RedoRecPtr as well */
8710  XLogCtl->RedoRecPtr = checkPoint.redo;
8712 
8713  /*
8714  * If enabled, log checkpoint start. We postpone this until now so as not
8715  * to log anything if we decided to skip the checkpoint.
8716  */
8717  if (log_checkpoints)
8718  LogCheckpointStart(flags, false);
8719 
8720  TRACE_POSTGRESQL_CHECKPOINT_START(flags);
8721 
8722  /*
8723  * Get the other info we need for the checkpoint record.
8724  *
8725  * We don't need to save oldestClogXid in the checkpoint, it only matters
8726  * for the short period in which clog is being truncated, and if we crash
8727  * during that we'll redo the clog truncation and fix up oldestClogXid
8728  * there.
8729  */
8730  LWLockAcquire(XidGenLock, LW_SHARED);
8731  checkPoint.nextXid = ShmemVariableCache->nextXid;
8732  checkPoint.oldestXid = ShmemVariableCache->oldestXid;
8734  LWLockRelease(XidGenLock);
8735 
8736  LWLockAcquire(CommitTsLock, LW_SHARED);
8739  LWLockRelease(CommitTsLock);
8740 
8741  /* Increase XID epoch if we've wrapped around since last checkpoint */
8743  if (checkPoint.nextXid < ControlFile->checkPointCopy.nextXid)
8744  checkPoint.nextXidEpoch++;
8745 
8746  LWLockAcquire(OidGenLock, LW_SHARED);
8747  checkPoint.nextOid = ShmemVariableCache->nextOid;
8748  if (!shutdown)
8749  checkPoint.nextOid += ShmemVariableCache->oidCount;
8750  LWLockRelease(OidGenLock);
8751 
8752  MultiXactGetCheckptMulti(shutdown,
8753  &checkPoint.nextMulti,
8754  &checkPoint.nextMultiOffset,
8755  &checkPoint.oldestMulti,
8756  &checkPoint.oldestMultiDB);
8757 
8758  /*
8759  * Having constructed the checkpoint record, ensure all shmem disk buffers
8760  * and commit-log buffers are flushed to disk.
8761  *
8762  * This I/O could fail for various reasons. If so, we will fail to
8763  * complete the checkpoint, but there is no reason to force a system
8764  * panic. Accordingly, exit critical section while doing it.
8765  */
8766  END_CRIT_SECTION();
8767 
8768  /*
8769  * In some cases there are groups of actions that must all occur on one
8770  * side or the other of a checkpoint record. Before flushing the
8771  * checkpoint record we must explicitly wait for any backend currently
8772  * performing those groups of actions.
8773  *
8774  * One example is end of transaction, so we must wait for any transactions
8775  * that are currently in commit critical sections. If an xact inserted
8776  * its commit record into XLOG just before the REDO point, then a crash
8777  * restart from the REDO point would not replay that record, which means
8778  * that our flushing had better include the xact's update of pg_xact. So
8779  * we wait till he's out of his commit critical section before proceeding.
8780  * See notes in RecordTransactionCommit().
8781  *
8782  * Because we've already released the insertion locks, this test is a bit
8783  * fuzzy: it is possible that we will wait for xacts we didn't really need
8784  * to wait for. But the delay should be short and it seems better to make
8785  * checkpoint take a bit longer than to hold off insertions longer than
8786  * necessary. (In fact, the whole reason we have this issue is that xact.c
8787  * does commit record XLOG insertion and clog update as two separate steps
8788  * protected by different locks, but again that seems best on grounds of
8789  * minimizing lock contention.)
8790  *
8791  * A transaction that has not yet set delayChkpt when we look cannot be at
8792  * risk, since he's not inserted his commit record yet; and one that's
8793  * already cleared it is not at risk either, since he's done fixing clog
8794  * and we will correctly flush the update below. So we cannot miss any
8795  * xacts we need to wait for.
8796  */
8797  vxids = GetVirtualXIDsDelayingChkpt(&nvxids);
8798  if (nvxids > 0)
8799  {
8800  do
8801  {
8802  pg_usleep(10000L); /* wait for 10 msec */
8803  } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids));
8804  }
8805  pfree(vxids);
8806 
8807  CheckPointGuts(checkPoint.redo, flags);
8808 
8809  /*
8810  * Take a snapshot of running transactions and write this to WAL. This
8811  * allows us to reconstruct the state of running transactions during
8812  * archive recovery, if required. Skip, if this info disabled.
8813  *
8814  * If we are shutting down, or Startup process is completing crash
8815  * recovery we don't need to write running xact data.
8816  */
8817  if (!shutdown && XLogStandbyInfoActive())
8819 
8821 
8822  /*
8823  * Now insert the checkpoint record into XLOG.
8824  */
8825  XLogBeginInsert();
8826  XLogRegisterData((char *) (&checkPoint), sizeof(checkPoint));
8827  recptr = XLogInsert(RM_XLOG_ID,
8828  shutdown ? XLOG_CHECKPOINT_SHUTDOWN :
8830 
8831  XLogFlush(recptr);
8832 
8833  /*
8834  * We mustn't write any new WAL after a shutdown checkpoint, or it will be
8835  * overwritten at next startup. No-one should even try, this just allows
8836  * sanity-checking. In the case of an end-of-recovery checkpoint, we want
8837  * to just temporarily disable writing until the system has exited
8838  * recovery.
8839  */
8840  if (shutdown)
8841  {
8842  if (flags & CHECKPOINT_END_OF_RECOVERY)
8843  LocalXLogInsertAllowed = -1; /* return to "check" state */
8844  else
8845  LocalXLogInsertAllowed = 0; /* never again write WAL */
8846  }
8847 
8848  /*
8849  * We now have ProcLastRecPtr = start of actual checkpoint record, recptr
8850  * = end of actual checkpoint record.
8851  */
8852  if (shutdown && checkPoint.redo != ProcLastRecPtr)
8853  ereport(PANIC,
8854  (errmsg("concurrent write-ahead log activity while database system is shutting down")));
8855 
8856  /*
8857  * Remember the prior checkpoint's redo pointer, used later to determine
8858  * the point where the log can be truncated.
8859  */
8860  PriorRedoPtr = ControlFile->checkPointCopy.redo;
8861 
8862  /*
8863  * Update the control file.
8864  */
8865  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8866  if (shutdown)
8870  ControlFile->checkPointCopy = checkPoint;
8871  ControlFile->time = (pg_time_t) time(NULL);
8872  /* crash recovery should always recover to the end of WAL */
8875 
8876  /*
8877  * Persist unloggedLSN value. It's reset on crash recovery, so this goes
8878  * unused on non-shutdown checkpoints, but seems useful to store it always
8879  * for debugging purposes.
8880  */
8884 
8886  LWLockRelease(ControlFileLock);
8887 
8888  /* Update shared-memory copy of checkpoint XID/epoch */
8890  XLogCtl->ckptXidEpoch = checkPoint.nextXidEpoch;
8891  XLogCtl->ckptXid = checkPoint.nextXid;
8893 
8894  /*
8895  * We are now done with critical updates; no need for system panic if we
8896  * have trouble while fooling with old log segments.
8897  */
8898  END_CRIT_SECTION();
8899 
8900  /*
8901  * Let smgr do post-checkpoint cleanup (eg, deleting old files).
8902  */
8903  smgrpostckpt();
8904 
8905  /*
8906  * Delete old log files (those no longer needed even for previous
8907  * checkpoint or the standbys in XLOG streaming).
8908  */
8909  if (PriorRedoPtr != InvalidXLogRecPtr)
8910  {
8911  XLogSegNo _logSegNo;
8912 
8913  /* Update the average distance between checkpoints. */
8915 
8916  XLByteToSeg(PriorRedoPtr, _logSegNo);
8917  KeepLogSeg(recptr, &_logSegNo);
8918  _logSegNo--;
8919  RemoveOldXlogFiles(_logSegNo, PriorRedoPtr, recptr);
8920  }
8921 
8922  /*
8923  * Make more log segments if needed. (Do this after recycling old log
8924  * segments, since that may supply some of the needed files.)
8925  */
8926  if (!shutdown)
8927  PreallocXlogFiles(recptr);
8928 
8929  /*
8930  * Truncate pg_subtrans if possible. We can throw away all data before
8931  * the oldest XMIN of any running transaction. No future transaction will
8932  * attempt to reference any pg_subtrans entry older than that (see Asserts
8933  * in subtrans.c). During recovery, though, we mustn't do this because
8934  * StartupSUBTRANS hasn't been called yet.
8935  */
8936  if (!RecoveryInProgress())
8938 
8939  /* Real work is done, but log and update stats before releasing lock. */
8940  LogCheckpointEnd(false);
8941 
8942  TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
8943  NBuffers,
8947 
8948  LWLockRelease(CheckpointLock);
8949 }
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:8245
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8471
#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:581
static void WALInsertLockRelease(void)
Definition: xlog.c:1645
pg_time_t time
Definition: pg_control.h:128
#define XLOG_CHECKPOINT_ONLINE
Definition: pg_control.h:68
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:168
uint32 oidCount
Definition: transam.h:112
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1570
static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos)
Definition: xlog.c:1914
XLogRecPtr unloggedLSN
Definition: xlog.c:588
XLogRecPtr ProcLastRecPtr
Definition: xlog.c:336
TransactionId oldestActiveXid
Definition: pg_control.h:63
void InitXLogInsert(void)
Definition: xloginsert.c:1028
TimestampTz ckpt_start_t
Definition: xlog.h:198
slock_t info_lck
Definition: xlog.c:702
#define END_CRIT_SECTION()
Definition: miscadmin.h:133
VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids)
Definition: procarray.c:2253
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: xlog.c:629
TimeLineID PrevTimeLineID
Definition: pg_control.h:39
#define START_CRIT_SECTION()
Definition: miscadmin.h:131
int ckpt_segs_recycled
Definition: xlog.h:208
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:3830
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:9010
CheckPoint checkPointCopy
Definition: pg_control.h:132
XLogCtlInsert Insert
Definition: xlog.c:575
TransactionId oldestXid
Definition: pg_control.h:47
bool RecoveryInProgress(void)
Definition: xlog.c:7878
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:354
uint32 ckptXidEpoch
Definition: xlog.c:580
TransactionId nextXid
Definition: pg_control.h:43
pg_time_t time
Definition: pg_control.h:51
#define PANIC
Definition: elog.h:53
bool fullPageWrites
Definition: xlog.c:550
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2757
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:46
void UpdateControlFile(void)
Definition: xlog.c:4646
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
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:8386
TransactionId nextXid
Definition: transam.h:117
uint32 nextXidEpoch
Definition: pg_control.h:42
static XLogRecPtr RedoRecPtr
Definition: xlog.c:350
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
XLogRecPtr unloggedLSN
Definition: pg_control.h:134
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3739
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:579
int ckpt_segs_removed
Definition: xlog.h:207
#define CHECKPOINT_FORCE
Definition: xlog.h:179
#define INSERT_FREESPACE(endptr)
Definition: xlog.c:719
#define ereport(elevel, rest)
Definition: elog.h:122
TransactionId oldestCommitTsXid
Definition: transam.h:129
static void Insert(File file)
Definition: fd.c:1044
int ckpt_bufs_written
Definition: xlog.h:204
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8004
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:54
#define PROCARRAY_FLAGS_DEFAULT
Definition: procarray.h:50
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9334
Oid oldestMultiDB
Definition: pg_control.h:50
#define XLogStandbyInfoActive()
Definition: xlog.h:159
XLogRecPtr prevCheckPoint
Definition: pg_control.h:130
static ControlFileData * ControlFile
Definition: xlog.c:713
TimeLineID ThisTimeLineID
Definition: xlog.c:179
Oid nextOid
Definition: pg_control.h:44
bool fullPageWrites
Definition: pg_control.h:41
TransactionId GetOldestXmin(Relation rel, int flags)
Definition: procarray.c:1314
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:48
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:45
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1616
static XLogCtlData * XLogCtl
Definition: xlog.c:705
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
int ckpt_segs_added
Definition: xlog.h:206
slock_t ulsn_lck
Definition: xlog.c:589
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
int errmsg(const char *fmt,...)
Definition: elog.c:797
TransactionId GetOldestActiveTransactionId(void)
Definition: procarray.c:2091
int NBuffers
Definition: globals.c:123
#define elog
Definition: elog.h:219
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids)
Definition: procarray.c:2298
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:129
XLogRecPtr redo
Definition: pg_control.h:36
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8368
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:175
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:167
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
static void CreateEndOfRecoveryRecord ( void  )
static

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

8962 {
8963  xl_end_of_recovery xlrec;
8964  XLogRecPtr recptr;
8965 
8966  /* sanity check */
8967  if (!RecoveryInProgress())
8968  elog(ERROR, "can only be used to end recovery");
8969 
8970  xlrec.end_time = GetCurrentTimestamp();
8971 
8976 
8978 
8980 
8981  XLogBeginInsert();
8982  XLogRegisterData((char *) &xlrec, sizeof(xl_end_of_recovery));
8983  recptr = XLogInsert(RM_XLOG_ID, XLOG_END_OF_RECOVERY);
8984 
8985  XLogFlush(recptr);
8986 
8987  /*
8988  * Update the control file so that crash recovery can follow the timeline
8989  * changes to this point.
8990  */
8991  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8992  ControlFile->time = (pg_time_t) time(NULL);
8993  ControlFile->minRecoveryPoint = recptr;
8996  LWLockRelease(ControlFileLock);
8997 
8998  END_CRIT_SECTION();
8999 
9000  LocalXLogInsertAllowed = -1; /* return to "check" state */
9001 }
static int LocalXLogInsertAllowed
Definition: xlog.c:233
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1645
pg_time_t time
Definition: pg_control.h:128
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:168
TimeLineID PrevTimeLineID
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1570
#define END_CRIT_SECTION()
Definition: miscadmin.h:133
TimeLineID PrevTimeLineID
Definition: xlog.c:629
#define START_CRIT_SECTION()
Definition: miscadmin.h:131
bool RecoveryInProgress(void)
Definition: xlog.c:7878
#define XLOG_END_OF_RECOVERY
Definition: pg_control.h:76
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2757
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
void UpdateControlFile(void)
Definition: xlog.c:4646
#define ERROR
Definition: elog.h:43
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8004
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:713
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:1616
static XLogCtlData * XLogCtl
Definition: xlog.c:705
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:167
bool CreateRestartPoint ( int  flags)

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

9081 {
9082  XLogRecPtr lastCheckPointRecPtr;
9083  XLogRecPtr lastCheckPointEndPtr;
9084  CheckPoint lastCheckPoint;
9085  XLogRecPtr PriorRedoPtr;
9086  TimestampTz xtime;
9087 
9088  /*
9089  * Acquire CheckpointLock to ensure only one restartpoint or checkpoint
9090  * happens at a time.
9091  */
9092  LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
9093 
9094  /* Get a local copy of the last safe checkpoint record. */
9096  lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
9097  lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
9098  lastCheckPoint = XLogCtl->lastCheckPoint;
9100 
9101  /*
9102  * Check that we're still in recovery mode. It's ok if we exit recovery
9103  * mode after this check, the restart point is valid anyway.
9104  */
9105  if (!RecoveryInProgress())
9106  {
9107  ereport(DEBUG2,
9108  (errmsg("skipping restartpoint, recovery has already ended")));
9109  LWLockRelease(CheckpointLock);
9110  return false;
9111  }
9112 
9113  /*
9114  * If the last checkpoint record we've replayed is already our last
9115  * restartpoint, we can't perform a new restart point. We still update
9116  * minRecoveryPoint in that case, so that if this is a shutdown restart
9117  * point, we won't start up earlier than before. That's not strictly
9118  * necessary, but when hot standby is enabled, it would be rather weird if
9119  * the database opened up for read-only connections at a point-in-time
9120  * before the last shutdown. Such time travel is still possible in case of
9121  * immediate shutdown, though.
9122  *
9123  * We don't explicitly advance minRecoveryPoint when we do create a
9124  * restartpoint. It's assumed that flushing the buffers will do that as a
9125  * side-effect.
9126  */
9127  if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
9128  lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
9129  {
9130  ereport(DEBUG2,
9131  (errmsg("skipping restartpoint, already performed at %X/%X",
9132  (uint32) (lastCheckPoint.redo >> 32),
9133  (uint32) lastCheckPoint.redo)));
9134 
9136  if (flags & CHECKPOINT_IS_SHUTDOWN)
9137  {
9138  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9140  ControlFile->time = (pg_time_t) time(NULL);
9142  LWLockRelease(ControlFileLock);
9143  }
9144  LWLockRelease(CheckpointLock);
9145  return false;
9146  }
9147 
9148  /*
9149  * Update the shared RedoRecPtr so that the startup process can calculate
9150  * the number of segments replayed since last restartpoint, and request a
9151  * restartpoint if it exceeds CheckPointSegments.
9152  *
9153  * Like in CreateCheckPoint(), hold off insertions to update it, although
9154  * during recovery this is just pro forma, because no WAL insertions are
9155  * happening.
9156  */
9158  RedoRecPtr = XLogCtl->Insert.RedoRecPtr = lastCheckPoint.redo;
9160 
9161  /* Also update the info_lck-protected copy */
9163  XLogCtl->RedoRecPtr = lastCheckPoint.redo;
9165 
9166  /*
9167  * Prepare to accumulate statistics.
9168  *
9169  * Note: because it is possible for log_checkpoints to change while a
9170  * checkpoint proceeds, we always accumulate stats, even if
9171  * log_checkpoints is currently off.
9172  */
9173  MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
9175 
9176  if (log_checkpoints)
9177  LogCheckpointStart(flags, true);
9178 
9179  CheckPointGuts(lastCheckPoint.redo, flags);
9180 
9181  /*
9182  * Remember the prior checkpoint's redo pointer, used later to determine
9183  * the point at which we can truncate the log.
9184  */
9185  PriorRedoPtr = ControlFile->checkPointCopy.redo;
9186 
9187  /*
9188  * Update pg_control, using current time. Check that it still shows
9189  * IN_ARCHIVE_RECOVERY state and an older checkpoint, else do nothing;
9190  * this is a quick hack to make sure nothing really bad happens if somehow
9191  * we get here after the end-of-recovery checkpoint.
9192  */
9193  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
9195  ControlFile->checkPointCopy.redo < lastCheckPoint.redo)
9196  {
9198  ControlFile->checkPoint = lastCheckPointRecPtr;
9199  ControlFile->checkPointCopy = lastCheckPoint;
9200  ControlFile->time = (pg_time_t) time(NULL);
9201 
9202  /*
9203  * Ensure minRecoveryPoint is past the checkpoint record. Normally,
9204  * this will have happened already while writing out dirty buffers,
9205  * but not necessarily - e.g. because no buffers were dirtied. We do
9206  * this because a non-exclusive base backup uses minRecoveryPoint to
9207  * determine which WAL files must be included in the backup, and the
9208  * file (or files) containing the checkpoint record must be included,
9209  * at a minimum. Note that for an ordinary restart of recovery there's
9210  * no value in having the minimum recovery point any earlier than this
9211  * anyway, because redo will begin just after the checkpoint record.
9212  */
9213  if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
9214  {
9215  ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
9217 
9218  /* update local copy */
9221  }
9222  if (flags & CHECKPOINT_IS_SHUTDOWN)
9225  }
9226  LWLockRelease(ControlFileLock);
9227 
9228  /*
9229  * Delete old log files (those no longer needed even for previous
9230  * checkpoint/restartpoint) to prevent the disk holding the xlog from
9231  * growing full.
9232  */
9233  if (PriorRedoPtr != InvalidXLogRecPtr)
9234  {
9235  XLogRecPtr receivePtr;
9236  XLogRecPtr replayPtr;
9237  TimeLineID replayTLI;
9238  XLogRecPtr endptr;
9239  XLogSegNo _logSegNo;
9240 
9241  /* Update the average distance between checkpoints/restartpoints. */
9243 
9244  XLByteToSeg(PriorRedoPtr, _logSegNo);
9245 
9246  /*
9247  * Get the current end of xlog replayed or received, whichever is
9248  * later.
9249  */
9250  receivePtr = GetWalRcvWriteRecPtr(NULL, NULL);
9251  replayPtr = GetXLogReplayRecPtr(&replayTLI);
9252  endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
9253 
9254  KeepLogSeg(endptr, &_logSegNo);
9255  _logSegNo--;
9256 
9257  /*
9258  * Try to recycle segments on a useful timeline. If we've been
9259  * promoted since the beginning of this restartpoint, use the new
9260  * timeline chosen at end of recovery (RecoveryInProgress() sets
9261  * ThisTimeLineID in that case). If we're still in recovery, use the
9262  * timeline we're currently replaying.
9263  *
9264  * There is no guarantee that the WAL segments will be useful on the
9265  * current timeline; if recovery proceeds to a new timeline right
9266  * after this, the pre-allocated WAL segments on this timeline will
9267  * not be used, and will go wasted until recycled on the next
9268  * restartpoint. We'll live with that.
9269  */
9270  if (RecoveryInProgress())
9271  ThisTimeLineID = replayTLI;
9272 
9273  RemoveOldXlogFiles(_logSegNo, PriorRedoPtr, endptr);
9274 
9275  /*
9276  * Make more log segments if needed. (Do this after recycling old log
9277  * segments, since that may supply some of the needed files.)
9278  */
9279  PreallocXlogFiles(endptr);
9280 
9281  /*
9282  * ThisTimeLineID is normally not set when we're still in recovery.
9283  * However, recycling/preallocating segments above needed
9284  * ThisTimeLineID to determine which timeline to install the segments
9285  * on. Reset it now, to restore the normal state of affairs for
9286  * debugging purposes.
9287  */
9288  if (RecoveryInProgress())
9289  ThisTimeLineID = 0;
9290  }
9291 
9292  /*
9293  * Truncate pg_subtrans if possible. We can throw away all data before
9294  * the oldest XMIN of any running transaction. No future transaction will
9295  * attempt to reference any pg_subtrans entry older than that (see Asserts
9296  * in subtrans.c). When hot standby is disabled, though, we mustn't do
9297  * this because StartupSUBTRANS hasn't been called yet.
9298  */
9299  if (EnableHotStandby)
9301 
9302  /* Real work is done, but log and update before releasing lock. */
9303  LogCheckpointEnd(true);
9304 
9305  xtime = GetLatestXTime();
9307  (errmsg("recovery restart point at %X/%X",
9308  (uint32) (lastCheckPoint.redo >> 32), (uint32) lastCheckPoint.redo),
9309  xtime ? errdetail("last completed transaction was at log time %s",
9310  timestamptz_to_str(xtime)) : 0));
9311 
9312  LWLockRelease(CheckpointLock);
9313 
9314  /*
9315  * Finally, execute archive_cleanup_command, if any.
9316  */
9319  "archive_cleanup_command",
9320  false);
9321 
9322  return true;
9323 }
static void UpdateCheckPointDistanceEstimate(uint64 nbytes)
Definition: xlog.c:8471
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:1645
pg_time_t time
Definition: pg_control.h:128
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:168
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1570
int64 TimestampTz
Definition: timestamp.h:39
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
Definition: xlog.c:2682
TimestampTz ckpt_start_t
Definition: xlog.h:198
slock_t info_lck
Definition: xlog.c:702
#define MemSet(start, val, len)
Definition: c.h:857
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
Definition: xlog.c:3830
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
Definition: xlog.c:9010
TimestampTz GetLatestXTime(void)
Definition: xlog.c:6066
CheckPoint checkPointCopy
Definition: pg_control.h:132
XLogCtlInsert Insert
Definition: xlog.c:575
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:7878
void TruncateSUBTRANS(TransactionId oldestXact)
Definition: subtrans.c:354
XLogRecPtr lastCheckPointRecPtr
Definition: xlog.c:671
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
#define SpinLockAcquire(lock)
Definition: spin.h:62
void UpdateControlFile(void)
Definition: xlog.c:4646
static void LogCheckpointEnd(bool restartpoint)
Definition: xlog.c:8386
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
Definition: xlog.c:11094
#define DEBUG2
Definition: elog.h:24
static XLogRecPtr RedoRecPtr
Definition: xlog.c:350
static void PreallocXlogFiles(XLogRecPtr endptr)
Definition: xlog.c:3739
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:579
#define ereport(elevel, rest)
Definition: elog.h:122
CheckPoint lastCheckPoint
Definition: xlog.c:673
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:822
#define PROCARRAY_FLAGS_DEFAULT
Definition: procarray.h:50
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
Definition: xlog.c:9334
XLogRecPtr prevCheckPoint
Definition: pg_control.h:130
static ControlFileData * ControlFile
Definition: xlog.c:713
TimeLineID ThisTimeLineID
Definition: xlog.c:179
TransactionId GetOldestXmin(Relation rel, int flags)
Definition: procarray.c:1314
#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:1616
static XLogCtlData * XLogCtl
Definition: xlog.c:705
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
char archiveCleanupCommand[MAXPGPATH]
Definition: xlog.c:635
bool EnableHotStandby
Definition: xlog.c:96
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
int errmsg(const char *fmt,...)
Definition: elog.c:797
XLogRecPtr RedoRecPtr
Definition: xlog.c:548
XLogRecPtr lastCheckPointEndPtr
Definition: xlog.c:672
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:36
static void LogCheckpointStart(int flags, bool restartpoint)
Definition: xlog.c:8368
#define CHECKPOINT_IS_SHUTDOWN
Definition: xlog.h:175
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:167
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:820
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1710
bool DataChecksumsEnabled ( void  )

Definition at line 4715 of file xlog.c.

References Assert, ControlFileData::data_checksum_version, and NULL.

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

4716 {
4717  Assert(ControlFile != NULL);
4718  return (ControlFile->data_checksum_version > 0);
4719 }
uint32 data_checksum_version
Definition: pg_control.h:222
static ControlFileData * ControlFile
Definition: xlog.c:713
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
void do_pg_abort_backup ( void  )

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

11075 {
11079 
11082  {
11083  XLogCtl->Insert.forcePageWrites = false;
11084  }
11086 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1645
XLogCtlInsert Insert
Definition: xlog.c:575
bool forcePageWrites
Definition: xlog.c:549
int nonExclusiveBackups
Definition: xlog.c:561
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:560
#define Assert(condition)
Definition: c.h:675
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1616
static XLogCtlData * XLogCtl
Definition: xlog.c:705
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 10183 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().

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

Definition at line 10691 of file xlog.c.

References AllocateFile(), Assert, BACKUP_LABEL_FILE, backup_started_in_recovery, BackupHistoryFileName, BackupHistoryFilePath, BoolGetDatum, CHECK_FOR_INTERRUPTS, CleanupBackupHistory(), DEBUG1, durable_unlink(), 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, 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().

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

Definition at line 11995 of file xlog.c.

References DEBUG1, LOG, readSource, and XLOG_FROM_PG_WAL.

Referenced by ReadRecord(), and XLogPageRead().

11996 {
11997  static XLogRecPtr lastComplaint = 0;
11998 
11999  if (readSource == XLOG_FROM_PG_WAL && emode == LOG)
12000  {
12001  if (RecPtr == lastComplaint)
12002  emode = DEBUG1;
12003  else
12004  lastComplaint = RecPtr;
12005  }
12006  return emode;
12007 }
#define DEBUG1
Definition: elog.h:25
static XLogSource readSource
Definition: xlog.c:786
#define LOG
Definition: elog.h:26
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static void exitArchiveRecovery ( TimeLineID  endTLI,
XLogRecPtr  endOfLog 
)
static

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

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