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 6122 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:109
#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 10054 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().

10055 {
10056  if (sync_method != new_sync_method)
10057  {
10058  /*
10059  * To ensure that no blocks escape unsynced, force an fsync on the
10060  * currently open log segment (if any). Also, if the open flag is
10061  * changing, close the log file so it will be reopened (with new flag
10062  * bit) at next use.
10063  */
10064  if (openLogFile >= 0)
10065  {
10067  if (pg_fsync(openLogFile) != 0)
10068  ereport(PANIC,
10070  errmsg("could not fsync log segment %s: %m",
10073  if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
10074  XLogFileClose();
10075  }
10076  }
10077 }
static int get_sync_bit(int method)
Definition: xlog.c:9998
#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:10130
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 11344 of file xlog.c.

References BACKUP_LABEL_FILE.

Referenced by pg_is_in_backup(), and PostmasterStateMachine().

11345 {
11346  struct stat stat_buf;
11347 
11348  return (stat(BACKUP_LABEL_FILE, &stat_buf) == 0);
11349 }
struct stat stat_buf
Definition: pg_standby.c:101
#define BACKUP_LABEL_FILE
Definition: xlog.h:320
void BootStrapXLOG ( void  )

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

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

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

11365 {
11366  struct stat stat_buf;
11367 
11368  /* if the backup_label file is not there, return */
11369  if (stat(BACKUP_LABEL_FILE, &stat_buf) < 0)
11370  return;
11371 
11372  /* remove leftover file from previously canceled backup if it exists */
11374 
11376  {
11377  ereport(WARNING,
11379  errmsg("online backup mode was not canceled"),
11380  errdetail("File \"%s\" could not be renamed to \"%s\": %m.",
11382  return;
11383  }
11384 
11385  /* if the tablespace_map file is not there, return */
11386  if (stat(TABLESPACE_MAP, &stat_buf) < 0)
11387  {
11388  ereport(LOG,
11389  (errmsg("online backup mode canceled"),
11390  errdetail("File \"%s\" was renamed to \"%s\".",
11392  return;
11393  }
11394 
11395  /* remove leftover file from previously canceled backup if it exists */
11397 
11399  {
11400  ereport(LOG,
11401  (errmsg("online backup mode canceled"),
11402  errdetail("Files \"%s\" and \"%s\" were renamed to "
11403  "\"%s\" and \"%s\", respectively.",
11406  }
11407  else
11408  {
11409  ereport(WARNING,
11411  errmsg("online backup mode canceled"),
11412  errdetail("File \"%s\" was renamed to \"%s\", but "
11413  "file \"%s\" could not be renamed to \"%s\": %m.",
11416  }
11417 }
#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 4765 of file xlog.c.

References XLOGbuffers, and XLOGChooseNumBuffers().

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

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

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

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

Referenced by CreateCheckPoint(), and CreateRestartPoint().

9005 {
9006  CheckPointCLOG();
9015  CheckPointBuffers(flags); /* performs all required fsyncs */
9017  /* We deliberately delay 2PC checkpointing as long as possible */
9018  CheckPointTwoPhase(checkPointRedo);
9019 }
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:1040
void CheckPointTwoPhase(XLogRecPtr redo_horizon)
Definition: twophase.c:1651
void CheckPointReplicationSlots(void)
Definition: slot.c:994
bool CheckPromoteSignal ( void  )

Definition at line 12080 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, and PROMOTE_SIGNAL_FILE.

Referenced by sigusr1_handler().

12081 {
12082  struct stat stat_buf;
12083 
12084  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
12086  return true;
12087 
12088  return false;
12089 }
#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 7773 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().

7774 {
7775  XLogRecPtr lastReplayedEndRecPtr;
7776 
7777  /*
7778  * During crash recovery, we don't reach a consistent state until we've
7779  * replayed all the WAL.
7780  */
7782  return;
7783 
7784  /*
7785  * assume that we are called in the startup process, and hence don't need
7786  * a lock to read lastReplayedEndRecPtr
7787  */
7788  lastReplayedEndRecPtr = XLogCtl->lastReplayedEndRecPtr;
7789 
7790  /*
7791  * Have we reached the point where our base backup was completed?
7792  */
7794  ControlFile->backupEndPoint <= lastReplayedEndRecPtr)
7795  {
7796  /*
7797  * We have reached the end of base backup, as indicated by pg_control.
7798  * The data on disk is now consistent. Reset backupStartPoint and
7799  * backupEndPoint, and update minRecoveryPoint to make sure we don't
7800  * allow starting up at an earlier point even if recovery is stopped
7801  * and restarted soon after this.
7802  */
7803  elog(DEBUG1, "end of backup reached");
7804 
7805  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
7806 
7807  if (ControlFile->minRecoveryPoint < lastReplayedEndRecPtr)
7808  ControlFile->minRecoveryPoint = lastReplayedEndRecPtr;
7809 
7812  ControlFile->backupEndRequired = false;
7814 
7815  LWLockRelease(ControlFileLock);
7816  }
7817 
7818  /*
7819  * Have we passed our safe starting point? Note that minRecoveryPoint is
7820  * known to be incorrectly set if ControlFile->backupEndRequired, until
7821  * the XLOG_BACKUP_RECORD arrives to advise us of the correct
7822  * minRecoveryPoint. All we know prior to that is that we're not
7823  * consistent yet.
7824  */
7826  minRecoveryPoint <= lastReplayedEndRecPtr &&
7828  {
7829  /*
7830  * Check to see if the XLOG sequence contained any unresolved
7831  * references to uninitialized pages.
7832  */
7834 
7835  reachedConsistency = true;
7836  ereport(LOG,
7837  (errmsg("consistent recovery state reached at %X/%X",
7838  (uint32) (lastReplayedEndRecPtr >> 32),
7839  (uint32) lastReplayedEndRecPtr)));
7840  }
7841 
7842  /*
7843  * Have we got a valid starting snapshot that will allow queries to be
7844  * run? If so, we can tell postmaster that the database is consistent now,
7845  * enabling connections.
7846  */
7851  {
7855 
7856  LocalHotStandbyActive = true;
7857 
7859  }
7860 }
#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:174
#define SpinLockAcquire(lock)
Definition: spin.h:62
static bool LocalHotStandbyActive
Definition: xlog.c:221
void UpdateControlFile(void)
Definition: xlog.c:4640
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:173
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:172
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:170
static XLogRecPtr minRecoveryPoint
Definition: xlog.c:820
XLogRecPtr lastReplayedEndRecPtr
Definition: xlog.c:681
static void CheckRequiredParameterValues ( void  )
static

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

6145 {
6146  /*
6147  * For archive recovery, the WAL must be generated with at least 'replica'
6148  * wal_level.
6149  */
6151  {
6152  ereport(WARNING,
6153  (errmsg("WAL was generated with wal_level=minimal, data may be missing"),
6154  errhint("This happens if you temporarily set wal_level=minimal without taking a new base backup.")));
6155  }
6156 
6157  /*
6158  * For Hot Standby, the WAL must be generated with 'replica' mode, and we
6159  * must have at least as many backend slots as the primary.
6160  */
6162  {
6164  ereport(ERROR,
6165  (errmsg("hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server"),
6166  errhint("Either set wal_level to \"replica\" on the master, or turn off hot_standby here.")));
6167 
6168  /* We ignore autovacuum_max_workers when we make this test. */
6169  RecoveryRequiresIntParameter("max_connections",
6172  RecoveryRequiresIntParameter("max_worker_processes",
6175  RecoveryRequiresIntParameter("max_prepared_transactions",
6178  RecoveryRequiresIntParameter("max_locks_per_transaction",
6181  }
6182 }
bool ArchiveRecoveryRequested
Definition: xlog.c:246
int max_locks_per_xact
Definition: pg_control.h:185
int errhint(const char *fmt,...)
Definition: elog.c:987
int max_prepared_xacts
Definition: pg_control.h:184
int max_worker_processes
Definition: pg_control.h:183
#define ERROR
Definition: elog.h:43
int max_prepared_xacts
Definition: twophase.c: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:6122
static void checkTimeLineSwitch ( XLogRecPtr  lsn,
TimeLineID  newTLI,
TimeLineID  prevTLI 
)
static

Definition at line 9562 of file xlog.c.

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

Referenced by StartupXLOG().

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

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

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

8956 {
8957  xl_end_of_recovery xlrec;
8958  XLogRecPtr recptr;
8959 
8960  /* sanity check */
8961  if (!RecoveryInProgress())
8962  elog(ERROR, "can only be used to end recovery");
8963 
8964  xlrec.end_time = GetCurrentTimestamp();
8965 
8970 
8972 
8974 
8975  XLogBeginInsert();
8976  XLogRegisterData((char *) &xlrec, sizeof(xl_end_of_recovery));
8977  recptr = XLogInsert(RM_XLOG_ID, XLOG_END_OF_RECOVERY);
8978 
8979  XLogFlush(recptr);
8980 
8981  /*
8982  * Update the control file so that crash recovery can follow the timeline
8983  * changes to this point.
8984  */
8985  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8986  ControlFile->time = (pg_time_t) time(NULL);
8987  ControlFile->minRecoveryPoint = recptr;
8990  LWLockRelease(ControlFileLock);
8991 
8992  END_CRIT_SECTION();
8993 
8994  LocalXLogInsertAllowed = -1; /* return to "check" state */
8995 }
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:131
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:171
TimeLineID PrevTimeLineID
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1570
#define END_CRIT_SECTION()
Definition: miscadmin.h:135
TimeLineID PrevTimeLineID
Definition: xlog.c:629
#define START_CRIT_SECTION()
Definition: miscadmin.h:133
bool RecoveryInProgress(void)
Definition: xlog.c:7872
#define XLOG_END_OF_RECOVERY
Definition: pg_control.h:75
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2757
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
void UpdateControlFile(void)
Definition: xlog.c:4640
#define ERROR
Definition: elog.h:43
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:7998
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:170
bool CreateRestartPoint ( int  flags)

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

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

Definition at line 4709 of file xlog.c.

References Assert, ControlFileData::data_checksum_version, and NULL.

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

4710 {
4711  Assert(ControlFile != NULL);
4712  return (ControlFile->data_checksum_version > 0);
4713 }
uint32 data_checksum_version
Definition: pg_control.h:225
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 11068 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().

11069 {
11073 
11076  {
11077  XLogCtl->Insert.forcePageWrites = false;
11078  }
11080 }
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 10177 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().

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

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

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

Definition at line 11989 of file xlog.c.

References DEBUG1, LOG, readSource, and XLOG_FROM_PG_WAL.

Referenced by ReadRecord(), and XLogPageRead().

11990 {
11991  static XLogRecPtr lastComplaint = 0;
11992 
11993  if (readSource == XLOG_FROM_PG_WAL && emode == LOG)
11994  {
11995  if (RecPtr == lastComplaint)
11996  emode = DEBUG1;
11997  else
11998  lastComplaint = RecPtr;
11999  }
12000  return emode;
12001 }
#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 5464 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().

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