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 742 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 721 of file xlog.c.

Referenced by CopyXLogRecordToWAL(), and CreateCheckPoint().

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

Definition at line 725 of file xlog.c.

Referenced by XLogWrite().

#define PROMOTE_SIGNAL_FILE   "promote"

Definition at line 84 of file xlog.c.

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

#define RECOVERY_COMMAND_DONE   "recovery.done"

Definition at line 83 of file xlog.c.

Referenced by exitArchiveRecovery().

#define RECOVERY_COMMAND_FILE   "recovery.conf"

Definition at line 82 of file xlog.c.

Referenced by exitArchiveRecovery(), and readRecoveryCommandFile().

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

Definition at line 6124 of file xlog.c.

Referenced by CheckRequiredParameterValues().

#define UsableBytesInPage   (XLOG_BLCKSZ - SizeOfXLogShortPHD)

Definition at line 738 of file xlog.c.

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

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

Definition at line 739 of file xlog.c.

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

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

Definition at line 732 of file xlog.c.

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

Typedef Documentation

Enumeration Type Documentation

Enumerator
EXCLUSIVE_BACKUP_NONE 
EXCLUSIVE_BACKUP_STARTING 
EXCLUSIVE_BACKUP_IN_PROGRESS 
EXCLUSIVE_BACKUP_STOPPING 

Definition at line 498 of file xlog.c.

enum XLogSource
Enumerator
XLOG_FROM_ANY 
XLOG_FROM_ARCHIVE 
XLOG_FROM_PG_WAL 
XLOG_FROM_STREAM 

Definition at line 755 of file xlog.c.

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

Function Documentation

static void AdvanceXLInsertBuffer ( XLogRecPtr  upto,
bool  opportunistic 
)
static

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

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

Definition at line 2241 of file xlog.c.

References CalculateCheckpointSegments(), CheckPointCompletionTarget, and newval.

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

Definition at line 2234 of file xlog.c.

References CalculateCheckpointSegments(), max_wal_size_mb, and newval.

2235 {
2238 }
static void CalculateCheckpointSegments(void)
Definition: xlog.c:2211
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 10044 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().

10045 {
10046  if (sync_method != new_sync_method)
10047  {
10048  /*
10049  * To ensure that no blocks escape unsynced, force an fsync on the
10050  * currently open log segment (if any). Also, if the open flag is
10051  * changing, close the log file so it will be reopened (with new flag
10052  * bit) at next use.
10053  */
10054  if (openLogFile >= 0)
10055  {
10057  if (pg_fsync(openLogFile) != 0)
10058  ereport(PANIC,
10060  errmsg("could not fsync log segment %s: %m",
10063  if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
10064  XLogFileClose();
10065  }
10066  }
10067 }
static int get_sync_bit(int method)
Definition: xlog.c:9988
#define PANIC
Definition: elog.h:53
static XLogSegNo openLogSegNo
Definition: xlog.c:773
static void XLogFileClose(void)
Definition: xlog.c:3706
char * XLogFileNameP(TimeLineID tli, XLogSegNo segno)
Definition: xlog.c:10120
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:772
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 11333 of file xlog.c.

References BACKUP_LABEL_FILE.

Referenced by pg_is_in_backup(), and PostmasterStateMachine().

11334 {
11335  struct stat stat_buf;
11336 
11337  return (stat(BACKUP_LABEL_FILE, &stat_buf) == 0);
11338 }
struct stat stat_buf
Definition: pg_standby.c:101
#define BACKUP_LABEL_FILE
Definition: xlog.h:321
void BootStrapXLOG ( void  )

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

4948 {
4949  CheckPoint checkPoint;
4950  char *buffer;
4951  XLogPageHeader page;
4952  XLogLongPageHeader longpage;
4953  XLogRecord *record;
4954  char *recptr;
4955  bool use_existent;
4956  uint64 sysidentifier;
4957  char mock_auth_nonce[MOCK_AUTH_NONCE_LEN];
4958  struct timeval tv;
4959  pg_crc32c crc;
4960 
4961  /*
4962  * Select a hopefully-unique system identifier code for this installation.
4963  * We use the result of gettimeofday(), including the fractional seconds
4964  * field, as being about as unique as we can easily get. (Think not to
4965  * use random(), since it hasn't been seeded and there's no portable way
4966  * to seed it other than the system clock value...) The upper half of the
4967  * uint64 value is just the tv_sec part, while the lower half contains the
4968  * tv_usec part (which must fit in 20 bits), plus 12 bits from our current
4969  * PID for a little extra uniqueness. A person knowing this encoding can
4970  * determine the initialization time of the installation, which could
4971  * perhaps be useful sometimes.
4972  */
4973  gettimeofday(&tv, NULL);
4974  sysidentifier = ((uint64) tv.tv_sec) << 32;
4975  sysidentifier |= ((uint64) tv.tv_usec) << 12;
4976  sysidentifier |= getpid() & 0xFFF;
4977 
4978  /*
4979  * Generate a random nonce. This is used for authentication requests
4980  * that will fail because the user does not exist. The nonce is used to
4981  * create a genuine-looking password challenge for the non-existent user,
4982  * in lieu of an actual stored password.
4983  */
4984  if (!pg_backend_random(mock_auth_nonce, MOCK_AUTH_NONCE_LEN))
4985  ereport(PANIC,
4986  (errcode(ERRCODE_INTERNAL_ERROR),
4987  errmsg("could not generate secret authorization token")));
4988 
4989  /* First timeline ID is always 1 */
4990  ThisTimeLineID = 1;
4991 
4992  /* page buffer must be aligned suitably for O_DIRECT */
4993  buffer = (char *) palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
4994  page = (XLogPageHeader) TYPEALIGN(XLOG_BLCKSZ, buffer);
4995  memset(page, 0, XLOG_BLCKSZ);
4996 
4997  /*
4998  * Set up information for the initial checkpoint record
4999  *
5000  * The initial checkpoint record is written to the beginning of the WAL
5001  * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not
5002  * used, so that we can use 0/0 to mean "before any valid WAL segment".
5003  */
5004  checkPoint.redo = XLogSegSize + SizeOfXLogLongPHD;
5005  checkPoint.ThisTimeLineID = ThisTimeLineID;
5006  checkPoint.PrevTimeLineID = ThisTimeLineID;
5007  checkPoint.fullPageWrites = fullPageWrites;
5008  checkPoint.nextXidEpoch = 0;
5009  checkPoint.nextXid = FirstNormalTransactionId;
5010  checkPoint.nextOid = FirstBootstrapObjectId;
5011  checkPoint.nextMulti = FirstMultiXactId;
5012  checkPoint.nextMultiOffset = 0;
5013  checkPoint.oldestXid = FirstNormalTransactionId;
5014  checkPoint.oldestXidDB = TemplateDbOid;
5015  checkPoint.oldestMulti = FirstMultiXactId;
5016  checkPoint.oldestMultiDB = TemplateDbOid;
5019  checkPoint.time = (pg_time_t) time(NULL);
5021 
5022  ShmemVariableCache->nextXid = checkPoint.nextXid;
5023  ShmemVariableCache->nextOid = checkPoint.nextOid;
5025  MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
5026  AdvanceOldestClogXid(checkPoint.oldestXid);
5027  SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
5028  SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true);
5030 
5031  /* Set up the XLOG page header */
5032  page->xlp_magic = XLOG_PAGE_MAGIC;
5033  page->xlp_info = XLP_LONG_HEADER;
5034  page->xlp_tli = ThisTimeLineID;
5035  page->xlp_pageaddr = XLogSegSize;
5036  longpage = (XLogLongPageHeader) page;
5037  longpage->xlp_sysid = sysidentifier;
5038  longpage->xlp_seg_size = XLogSegSize;
5039  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
5040 
5041  /* Insert the initial checkpoint record */
5042  recptr = ((char *) page + SizeOfXLogLongPHD);
5043  record = (XLogRecord *) recptr;
5044  record->xl_prev = 0;
5045  record->xl_xid = InvalidTransactionId;
5046  record->xl_tot_len = SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(checkPoint);
5048  record->xl_rmid = RM_XLOG_ID;
5049  recptr += SizeOfXLogRecord;
5050  /* fill the XLogRecordDataHeaderShort struct */
5051  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
5052  *(recptr++) = sizeof(checkPoint);
5053  memcpy(recptr, &checkPoint, sizeof(checkPoint));
5054  recptr += sizeof(checkPoint);
5055  Assert(recptr - (char *) record == record->xl_tot_len);
5056 
5057  INIT_CRC32C(crc);
5058  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
5059  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
5060  FIN_CRC32C(crc);
5061  record->xl_crc = crc;
5062 
5063  /* Create first XLOG segment file */
5064  use_existent = false;
5065  openLogFile = XLogFileInit(1, &use_existent, false);
5066 
5067  /* Write the first page with the initial record */
5068  errno = 0;
5070  if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
5071  {
5072  /* if write didn't set errno, assume problem is no disk space */
5073  if (errno == 0)
5074  errno = ENOSPC;
5075  ereport(PANIC,
5077  errmsg("could not write bootstrap transaction log file: %m")));
5078  }
5080 
5082  if (pg_fsync(openLogFile) != 0)
5083  ereport(PANIC,
5085  errmsg("could not fsync bootstrap transaction log file: %m")));
5087 
5088  if (close(openLogFile))
5089  ereport(PANIC,
5091  errmsg("could not close bootstrap transaction log file: %m")));
5092 
5093  openLogFile = -1;
5094 
5095  /* Now create pg_control */
5096 
5097  memset(ControlFile, 0, sizeof(ControlFileData));
5098  /* Initialize pg_control status fields */
5099  ControlFile->system_identifier = sysidentifier;
5100  memcpy(ControlFile->mock_authentication_nonce, mock_auth_nonce, MOCK_AUTH_NONCE_LEN);
5102  ControlFile->time = checkPoint.time;
5103  ControlFile->checkPoint = checkPoint.redo;
5104  ControlFile->checkPointCopy = checkPoint;
5105  ControlFile->unloggedLSN = 1;
5106 
5107  /* Set important parameter values for use when replaying WAL */
5116 
5117  /* some additional ControlFile fields are set in WriteControlFile() */
5118 
5119  WriteControlFile();
5120 
5121  /* Bootstrap the commit log, too */
5122  BootStrapCLOG();
5126 
5127  pfree(buffer);
5128 }
static void WriteControlFile(void)
Definition: xlog.c:4378
#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:200
int max_worker_processes
Definition: pg_control.h:183
uint32 pg_crc32c
Definition: pg_crc32c.h:38
TransactionId oldestActiveXid
Definition: pg_control.h:62
int wal_level
Definition: xlog.c:104
int XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
Definition: xlog.c:3154
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:211
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:123
Oid oldestMultiDB
Definition: pg_control.h:49
static int openLogFile
Definition: xlog.c:772
static ControlFileData * ControlFile
Definition: xlog.c:715
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
Definition: multixact.c:2194
TimeLineID ThisTimeLineID
Definition: xlog.c:179
Oid nextOid
Definition: pg_control.h:43
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:581
bool fullPageWrites
Definition: pg_control.h:40
bool wal_log_hints
Definition: xlog.c:98
void BootStrapCLOG(void)
Definition: clog.c:464
#define NULL
Definition: c.h:229
bool track_commit_timestamp
Definition: pg_control.h:186
#define Assert(condition)
Definition: c.h:675
#define XLP_LONG_HEADER
Definition: xlog_internal.h:79
Oid oldestXidDB
Definition: pg_control.h:47
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:207
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h: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:223
TransactionId xl_xid
Definition: xlogrecord.h:44
TimeLineID ThisTimeLineID
Definition: pg_control.h:37
void * palloc(Size size)
Definition: mcxt.c:849
int errmsg(const char *fmt,...)
Definition: elog.c:797
int max_worker_processes
Definition: globals.c:124
int pg_fsync(int fd)
Definition: fd.c:333
#define close(a)
Definition: win32.h: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 2211 of file xlog.c.

References CheckPointCompletionTarget, CheckPointSegments, ConvertToXSegs, and max_wal_size_mb.

Referenced by assign_checkpoint_completion_target(), and assign_max_wal_size().

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

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

11354 {
11355  struct stat stat_buf;
11356 
11357  /* if the backup_label file is not there, return */
11358  if (stat(BACKUP_LABEL_FILE, &stat_buf) < 0)
11359  return;
11360 
11361  /* remove leftover file from previously canceled backup if it exists */
11363 
11365  {
11366  ereport(WARNING,
11368  errmsg("online backup mode was not canceled"),
11369  errdetail("File \"%s\" could not be renamed to \"%s\": %m.",
11371  return;
11372  }
11373 
11374  /* if the tablespace_map file is not there, return */
11375  if (stat(TABLESPACE_MAP, &stat_buf) < 0)
11376  {
11377  ereport(LOG,
11378  (errmsg("online backup mode canceled"),
11379  errdetail("File \"%s\" was renamed to \"%s\".",
11381  return;
11382  }
11383 
11384  /* remove leftover file from previously canceled backup if it exists */
11386 
11388  {
11389  ereport(LOG,
11390  (errmsg("online backup mode canceled"),
11391  errdetail("Files \"%s\" and \"%s\" were renamed to "
11392  "\"%s\" and \"%s\", respectively.",
11395  }
11396  else
11397  {
11398  ereport(WARNING,
11400  errmsg("online backup mode canceled"),
11401  errdetail("File \"%s\" was renamed to \"%s\", but "
11402  "file \"%s\" could not be renamed to \"%s\": %m.",
11405  }
11406 }
#define DEBUG1
Definition: elog.h:25
#define LOG
Definition: elog.h:26
#define BACKUP_LABEL_OLD
Definition: xlog.h:322
#define TABLESPACE_MAP
Definition: xlog.h:324
struct stat stat_buf
Definition: pg_standby.c:101
int errdetail(const char *fmt,...)
Definition: elog.c:873
int errcode_for_file_access(void)
Definition: elog.c:598
int unlink(const char *filename)
#define ereport(elevel, rest)
Definition: elog.h:122
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:593
#define WARNING
Definition: elog.h:40
#define TABLESPACE_MAP_OLD
Definition: xlog.h:325
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define BACKUP_LABEL_FILE
Definition: xlog.h:321
bool check_wal_buffers ( int *  newval,
void **  extra,
GucSource  source 
)

Definition at line 4767 of file xlog.c.

References XLOGbuffers, and XLOGChooseNumBuffers().

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

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

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

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

Referenced by CreateCheckPoint(), and CreateRestartPoint().

8996 {
8997  CheckPointCLOG();
9006  CheckPointBuffers(flags); /* performs all required fsyncs */
9008  /* We deliberately delay 2PC checkpointing as long as possible */
9009  CheckPointTwoPhase(checkPointRedo);
9010 }
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:1886
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:299
void CheckPointRelationMap(void)
Definition: relmapper.c:524
void CheckPointPredicate(void)
Definition: predicate.c:1039
void CheckPointTwoPhase(XLogRecPtr redo_horizon)
Definition: twophase.c:1649
void CheckPointReplicationSlots(void)
Definition: slot.c:996
bool CheckPromoteSignal ( void  )

Definition at line 12069 of file xlog.c.

References FALLBACK_PROMOTE_SIGNAL_FILE, and PROMOTE_SIGNAL_FILE.

Referenced by sigusr1_handler().

12070 {
12071  struct stat stat_buf;
12072 
12073  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0 ||
12075  return true;
12076 
12077  return false;
12078 }
#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 7775 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().

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

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

6147 {
6148  /*
6149  * For archive recovery, the WAL must be generated with at least 'replica'
6150  * wal_level.
6151  */
6153  {
6154  ereport(WARNING,
6155  (errmsg("WAL was generated with wal_level=minimal, data may be missing"),
6156  errhint("This happens if you temporarily set wal_level=minimal without taking a new base backup.")));
6157  }
6158 
6159  /*
6160  * For Hot Standby, the WAL must be generated with 'replica' mode, and we
6161  * must have at least as many backend slots as the primary.
6162  */
6164  {
6166  ereport(ERROR,
6167  (errmsg("hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server"),
6168  errhint("Either set wal_level to \"replica\" on the master, or turn off hot_standby here.")));
6169 
6170  /* We ignore autovacuum_max_workers when we make this test. */
6171  RecoveryRequiresIntParameter("max_connections",
6174  RecoveryRequiresIntParameter("max_worker_processes",
6177  RecoveryRequiresIntParameter("max_prepared_transactions",
6180  RecoveryRequiresIntParameter("max_locks_per_transaction",
6183  }
6184 }
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:123
static ControlFileData * ControlFile
Definition: xlog.c:715
bool EnableHotStandby
Definition: xlog.c:96
int errmsg(const char *fmt,...)
Definition: elog.c:797
int max_worker_processes
Definition: globals.c:124
#define RecoveryRequiresIntParameter(param_name, currValue, minValue)
Definition: xlog.c:6124
static void checkTimeLineSwitch ( XLogRecPtr  lsn,
TimeLineID  newTLI,
TimeLineID  prevTLI 
)
static

Definition at line 9553 of file xlog.c.

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

Referenced by StartupXLOG().

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

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

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

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

3767 {
3768  XLogSegNo lastRemovedSegNo;
3769 
3771  lastRemovedSegNo = XLogCtl->lastRemovedSegNo;
3773 
3774  if (segno <= lastRemovedSegNo)
3775  {
3776  char filename[MAXFNAMELEN];
3777 
3778  XLogFileName(filename, tli, segno);
3779  ereport(ERROR,
3781  errmsg("requested WAL segment %s has already been removed",
3782  filename)));
3783  }
3784 }
slock_t info_lck
Definition: xlog.c:704
#define XLogFileName(fname, tli, logSegNo)
XLogSegNo lastRemovedSegNo
Definition: xlog.c:586
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define ERROR
Definition: elog.h:43
uint64 XLogSegNo
Definition: xlogdefs.h:34
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
#define MAXFNAMELEN
#define SpinLockRelease(lock)
Definition: spin.h:64
static XLogCtlData * XLogCtl
Definition: xlog.c:707
static char * filename
Definition: pg_dumpall.c:87
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void CleanupBackupHistory ( void  )
static

Definition at line 4101 of file xlog.c.

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

Referenced by do_pg_stop_backup().

4102 {
4103  DIR *xldir;
4104  struct dirent *xlde;
4105  char path[MAXPGPATH + sizeof(XLOGDIR)];
4106 
4107  xldir = AllocateDir(XLOGDIR);
4108  if (xldir == NULL)
4109  ereport(ERROR,
4111  errmsg("could not open transaction log directory \"%s\": %m",
4112  XLOGDIR)));
4113 
4114  while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL)
4115  {
4116  if (IsBackupHistoryFileName(xlde->d_name))
4117  {
4118  if (XLogArchiveCheckDone(xlde->d_name))
4119  {
4120  ereport(DEBUG2,
4121  (errmsg("removing transaction log backup history file \"%s\"",
4122  xlde->d_name)));
4123  snprintf(path, sizeof(path), XLOGDIR "/%s", xlde->d_name);
4124  unlink(path);
4125  XLogArchiveCleanup(xlde->d_name);
4126  }
4127  }
4128  }
4129 
4130  FreeDir(xldir);
4131 }
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
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 1448 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().

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

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

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

8947 {
8948  xl_end_of_recovery xlrec;
8949  XLogRecPtr recptr;
8950 
8951  /* sanity check */
8952  if (!RecoveryInProgress())
8953  elog(ERROR, "can only be used to end recovery");
8954 
8955  xlrec.end_time = GetCurrentTimestamp();
8956 
8961 
8963 
8965 
8966  XLogBeginInsert();
8967  XLogRegisterData((char *) &xlrec, sizeof(xl_end_of_recovery));
8968  recptr = XLogInsert(RM_XLOG_ID, XLOG_END_OF_RECOVERY);
8969 
8970  XLogFlush(recptr);
8971 
8972  /*
8973  * Update the control file so that crash recovery can follow the timeline
8974  * changes to this point.
8975  */
8976  LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
8977  ControlFile->time = (pg_time_t) time(NULL);
8978  ControlFile->minRecoveryPoint = recptr;
8981  LWLockRelease(ControlFileLock);
8982 
8983  END_CRIT_SECTION();
8984 
8985  LocalXLogInsertAllowed = -1; /* return to "check" state */
8986 }
static int LocalXLogInsertAllowed
Definition: xlog.c:233
int64 pg_time_t
Definition: pgtime.h:23
static void WALInsertLockRelease(void)
Definition: xlog.c:1646
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:132
TimeLineID PrevTimeLineID
Definition: xlog.c:631
#define START_CRIT_SECTION()
Definition: miscadmin.h:130
bool RecoveryInProgress(void)
Definition: xlog.c:7874
#define XLOG_END_OF_RECOVERY
Definition: pg_control.h:75
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2758
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
void UpdateControlFile(void)
Definition: xlog.c:4642
#define ERROR
Definition: elog.h:43
static void LocalSetXLogInsertAllowed(void)
Definition: xlog.c:8000
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
static ControlFileData * ControlFile
Definition: xlog.c:715
TimeLineID ThisTimeLineID
Definition: xlog.c:179
TimestampTz end_time
#define NULL
Definition: c.h:229
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1617
static XLogCtlData * XLogCtl
Definition: xlog.c:707
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
TimeLineID ThisTimeLineID
#define elog
Definition: elog.h:219
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:170
bool CreateRestartPoint ( int  flags)

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

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

Definition at line 4711 of file xlog.c.

References Assert, ControlFileData::data_checksum_version, and NULL.

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

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

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

11058 {
11062 
11065  {
11066  XLogCtl->Insert.forcePageWrites = false;
11067  }
11069 }
static void WALInsertLockRelease(void)
Definition: xlog.c:1646
XLogCtlInsert Insert
Definition: xlog.c:576
bool forcePageWrites
Definition: xlog.c:549
int nonExclusiveBackups
Definition: xlog.c:562
ExclusiveBackupState exclusiveBackupState
Definition: xlog.c:561
#define Assert(condition)
Definition: c.h:675
static void WALInsertLockAcquireExclusive(void)
Definition: xlog.c:1617
static XLogCtlData * XLogCtl
Definition: xlog.c:707
XLogRecPtr do_pg_start_backup ( const char *  backupidstr,
bool  fast,
TimeLineID starttli_p,
StringInfo  labelfile,
DIR tblspcdir,
List **  tablespaces,
StringInfo  tblspcmapfile,
bool  infotbssize,
bool  needtblspcmapfile 
)

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

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

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

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

Definition at line 11978 of file xlog.c.

References DEBUG1, LOG, readSource, and XLOG_FROM_PG_WAL.

Referenced by ReadRecord(), and XLogPageRead().

11979 {
11980  static XLogRecPtr lastComplaint = 0;
11981 
11982  if (readSource == XLOG_FROM_PG_WAL && emode == LOG)
11983  {
11984  if (RecPtr == lastComplaint)
11985  emode = DEBUG1;
11986  else
11987  lastComplaint = RecPtr;
11988  }
11989  return emode;
11990 }
#define DEBUG1
Definition: elog.h:25
static XLogSource readSource
Definition: xlog.c:788
#define LOG
Definition: elog.h:26
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static void exitArchiveRecovery ( TimeLineID  endTLI,
XLogRecPtr  endOfLog 
)
static

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

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