PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
xlogrecovery.h File Reference
#include "access/xlogreader.h"
#include "catalog/pg_control.h"
#include "lib/stringinfo.h"
#include "utils/timestamp.h"
Include dependency graph for xlogrecovery.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  EndOfWalRecoveryInfo
 

Typedefs

typedef enum RecoveryPauseState RecoveryPauseState
 

Enumerations

enum  RecoveryTargetType {
  RECOVERY_TARGET_UNSET , RECOVERY_TARGET_XID , RECOVERY_TARGET_TIME , RECOVERY_TARGET_NAME ,
  RECOVERY_TARGET_LSN , RECOVERY_TARGET_IMMEDIATE
}
 
enum  RecoveryTargetTimeLineGoal { RECOVERY_TARGET_TIMELINE_CONTROLFILE , RECOVERY_TARGET_TIMELINE_LATEST , RECOVERY_TARGET_TIMELINE_NUMERIC }
 
enum  RecoveryPauseState { RECOVERY_NOT_PAUSED , RECOVERY_PAUSE_REQUESTED , RECOVERY_PAUSED }
 

Functions

Size XLogRecoveryShmemSize (void)
 
void XLogRecoveryShmemInit (void)
 
void InitWalRecovery (ControlFileData *ControlFile, bool *wasShutdown_ptr, bool *haveBackupLabel_ptr, bool *haveTblspcMap_ptr)
 
void PerformWalRecovery (void)
 
EndOfWalRecoveryInfoFinishWalRecovery (void)
 
void ShutdownWalRecovery (void)
 
void RemovePromoteSignalFiles (void)
 
bool HotStandbyActive (void)
 
XLogRecPtr GetXLogReplayRecPtr (TimeLineID *replayTLI)
 
RecoveryPauseState GetRecoveryPauseState (void)
 
void SetRecoveryPause (bool recoveryPause)
 
void GetXLogReceiptTime (TimestampTz *rtime, bool *fromStream)
 
TimestampTz GetLatestXTime (void)
 
TimestampTz GetCurrentChunkReplayStartTime (void)
 
XLogRecPtr GetCurrentReplayRecPtr (TimeLineID *replayEndTLI)
 
bool PromoteIsTriggered (void)
 
bool CheckPromoteSignal (void)
 
void WakeupRecovery (void)
 
void StartupRequestWalReceiverRestart (void)
 
void XLogRequestWalReceiverReply (void)
 
void RecoveryRequiresIntParameter (const char *param_name, int currValue, int minValue)
 
void xlog_outdesc (StringInfo buf, XLogReaderState *record)
 

Variables

PGDLLIMPORT bool recoveryTargetInclusive
 
PGDLLIMPORT int recoveryTargetAction
 
PGDLLIMPORT int recovery_min_apply_delay
 
PGDLLIMPORT char * PrimaryConnInfo
 
PGDLLIMPORT char * PrimarySlotName
 
PGDLLIMPORT char * recoveryRestoreCommand
 
PGDLLIMPORT char * recoveryEndCommand
 
PGDLLIMPORT char * archiveCleanupCommand
 
PGDLLIMPORT TransactionId recoveryTargetXid
 
PGDLLIMPORT char * recovery_target_time_string
 
PGDLLIMPORT TimestampTz recoveryTargetTime
 
PGDLLIMPORT const char * recoveryTargetName
 
PGDLLIMPORT XLogRecPtr recoveryTargetLSN
 
PGDLLIMPORT RecoveryTargetType recoveryTarget
 
PGDLLIMPORT bool wal_receiver_create_temp_slot
 
PGDLLIMPORT RecoveryTargetTimeLineGoal recoveryTargetTimeLineGoal
 
PGDLLIMPORT TimeLineID recoveryTargetTLIRequested
 
PGDLLIMPORT TimeLineID recoveryTargetTLI
 
PGDLLIMPORT bool reachedConsistency
 
PGDLLIMPORT bool StandbyMode
 

Typedef Documentation

◆ RecoveryPauseState

Enumeration Type Documentation

◆ RecoveryPauseState

Enumerator
RECOVERY_NOT_PAUSED 
RECOVERY_PAUSE_REQUESTED 
RECOVERY_PAUSED 

Definition at line 44 of file xlogrecovery.h.

45{
46 RECOVERY_NOT_PAUSED, /* pause not requested */
47 RECOVERY_PAUSE_REQUESTED, /* pause requested, but not yet paused */
48 RECOVERY_PAUSED, /* recovery is paused */
RecoveryPauseState
Definition: xlogrecovery.h:45
@ RECOVERY_PAUSED
Definition: xlogrecovery.h:48
@ RECOVERY_NOT_PAUSED
Definition: xlogrecovery.h:46
@ RECOVERY_PAUSE_REQUESTED
Definition: xlogrecovery.h:47

◆ RecoveryTargetTimeLineGoal

Enumerator
RECOVERY_TARGET_TIMELINE_CONTROLFILE 
RECOVERY_TARGET_TIMELINE_LATEST 
RECOVERY_TARGET_TIMELINE_NUMERIC 

Definition at line 36 of file xlogrecovery.h.

◆ RecoveryTargetType

Enumerator
RECOVERY_TARGET_UNSET 
RECOVERY_TARGET_XID 
RECOVERY_TARGET_TIME 
RECOVERY_TARGET_NAME 
RECOVERY_TARGET_LSN 
RECOVERY_TARGET_IMMEDIATE 

Definition at line 23 of file xlogrecovery.h.

24{
RecoveryTargetType
Definition: xlogrecovery.h:24
@ RECOVERY_TARGET_IMMEDIATE
Definition: xlogrecovery.h:30
@ RECOVERY_TARGET_TIME
Definition: xlogrecovery.h:27
@ RECOVERY_TARGET_UNSET
Definition: xlogrecovery.h:25
@ RECOVERY_TARGET_XID
Definition: xlogrecovery.h:26
@ RECOVERY_TARGET_LSN
Definition: xlogrecovery.h:29
@ RECOVERY_TARGET_NAME
Definition: xlogrecovery.h:28

Function Documentation

◆ CheckPromoteSignal()

bool CheckPromoteSignal ( void  )

Definition at line 4483 of file xlogrecovery.c.

4484{
4485 struct stat stat_buf;
4486
4487 if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
4488 return true;
4489
4490 return false;
4491}
#define stat
Definition: win32_port.h:274
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:310

References PROMOTE_SIGNAL_FILE, and stat.

Referenced by CheckForStandbyTrigger(), and process_pm_pmsignal().

◆ FinishWalRecovery()

EndOfWalRecoveryInfo * FinishWalRecovery ( void  )

Definition at line 1466 of file xlogrecovery.c.

1467{
1469 XLogRecPtr lastRec;
1470 TimeLineID lastRecTLI;
1471 XLogRecPtr endOfLog;
1472
1473 /*
1474 * Kill WAL receiver, if it's still running, before we continue to write
1475 * the startup checkpoint and aborted-contrecord records. It will trump
1476 * over these records and subsequent ones if it's still alive when we
1477 * start writing WAL.
1478 */
1480
1481 /*
1482 * Shutdown the slot sync worker to drop any temporary slots acquired by
1483 * it and to prevent it from keep trying to fetch the failover slots.
1484 *
1485 * We do not update the 'synced' column in 'pg_replication_slots' system
1486 * view from true to false here, as any failed update could leave 'synced'
1487 * column false for some slots. This could cause issues during slot sync
1488 * after restarting the server as a standby. While updating the 'synced'
1489 * column after switching to the new timeline is an option, it does not
1490 * simplify the handling for the 'synced' column. Therefore, we retain the
1491 * 'synced' column as true after promotion as it may provide useful
1492 * information about the slot origin.
1493 */
1495
1496 /*
1497 * We are now done reading the xlog from stream. Turn off streaming
1498 * recovery to force fetching the files (which would be required at end of
1499 * recovery, e.g., timeline history file) from archive or pg_wal.
1500 *
1501 * Note that standby mode must be turned off after killing WAL receiver,
1502 * i.e., calling XLogShutdownWalRcv().
1503 */
1505 StandbyMode = false;
1506
1507 /*
1508 * Determine where to start writing WAL next.
1509 *
1510 * Re-fetch the last valid or last applied record, so we can identify the
1511 * exact endpoint of what we consider the valid portion of WAL. There may
1512 * be an incomplete continuation record after that, in which case
1513 * 'abortedRecPtr' and 'missingContrecPtr' are set and the caller will
1514 * write a special OVERWRITE_CONTRECORD message to mark that the rest of
1515 * it is intentionally missing. See CreateOverwriteContrecordRecord().
1516 *
1517 * An important side-effect of this is to load the last page into
1518 * xlogreader. The caller uses it to initialize the WAL for writing.
1519 */
1520 if (!InRecovery)
1521 {
1522 lastRec = CheckPointLoc;
1523 lastRecTLI = CheckPointTLI;
1524 }
1525 else
1526 {
1528 lastRecTLI = XLogRecoveryCtl->lastReplayedTLI;
1529 }
1531 (void) ReadRecord(xlogprefetcher, PANIC, false, lastRecTLI);
1532 endOfLog = xlogreader->EndRecPtr;
1533
1534 /*
1535 * Remember the TLI in the filename of the XLOG segment containing the
1536 * end-of-log. It could be different from the timeline that endOfLog
1537 * nominally belongs to, if there was a timeline switch in that segment,
1538 * and we were reading the old WAL from a segment belonging to a higher
1539 * timeline.
1540 */
1541 result->endOfLogTLI = xlogreader->seg.ws_tli;
1542
1544 {
1545 /*
1546 * We are no longer in archive recovery state.
1547 *
1548 * We are now done reading the old WAL. Turn off archive fetching if
1549 * it was active.
1550 */
1552 InArchiveRecovery = false;
1553
1554 /*
1555 * If the ending log segment is still open, close it (to avoid
1556 * problems on Windows with trying to rename or delete an open file).
1557 */
1558 if (readFile >= 0)
1559 {
1560 close(readFile);
1561 readFile = -1;
1562 }
1563 }
1564
1565 /*
1566 * Copy the last partial block to the caller, for initializing the WAL
1567 * buffer for appending new WAL.
1568 */
1569 if (endOfLog % XLOG_BLCKSZ != 0)
1570 {
1571 char *page;
1572 int len;
1573 XLogRecPtr pageBeginPtr;
1574
1575 pageBeginPtr = endOfLog - (endOfLog % XLOG_BLCKSZ);
1577
1578 /* Copy the valid part of the last block */
1579 len = endOfLog % XLOG_BLCKSZ;
1580 page = palloc(len);
1581 memcpy(page, xlogreader->readBuf, len);
1582
1583 result->lastPageBeginPtr = pageBeginPtr;
1584 result->lastPage = page;
1585 }
1586 else
1587 {
1588 /* There is no partial block to copy. */
1589 result->lastPageBeginPtr = endOfLog;
1590 result->lastPage = NULL;
1591 }
1592
1593 /*
1594 * Create a comment for the history file to explain why and where timeline
1595 * changed.
1596 */
1598
1599 result->lastRec = lastRec;
1600 result->lastRecTLI = lastRecTLI;
1601 result->endOfLog = endOfLog;
1602
1603 result->abortedRecPtr = abortedRecPtr;
1605
1608
1609 return result;
1610}
#define PANIC
Definition: elog.h:42
Assert(PointerIsAligned(start, uint64))
#define close(a)
Definition: win32.h:12
void * palloc(Size size)
Definition: mcxt.c:1939
const void size_t len
void ShutDownSlotSync(void)
Definition: slotsync.c:1565
XLogRecPtr lastPageBeginPtr
Definition: xlogrecovery.h:111
XLogRecPtr abortedRecPtr
Definition: xlogrecovery.h:120
XLogRecPtr missingContrecPtr
Definition: xlogrecovery.h:121
TimeLineID endOfLogTLI
Definition: xlogrecovery.h:109
TimeLineID ws_tli
Definition: xlogreader.h:49
XLogRecPtr EndRecPtr
Definition: xlogreader.h:207
WALOpenSegment seg
Definition: xlogreader.h:272
TimeLineID lastReplayedTLI
Definition: xlogrecovery.c:346
XLogRecPtr lastReplayedReadRecPtr
Definition: xlogrecovery.c:344
bool WalRcvStreaming(void)
int wal_segment_size
Definition: xlog.c:143
void XLogShutdownWalRcv(void)
Definition: xlog.c:9650
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
uint64 XLogRecPtr
Definition: xlogdefs.h:21
uint32 TimeLineID
Definition: xlogdefs.h:59
void XLogPrefetcherBeginRead(XLogPrefetcher *prefetcher, XLogRecPtr recPtr)
static char * getRecoveryStopReason(void)
bool ArchiveRecoveryRequested
Definition: xlogrecovery.c:138
bool InArchiveRecovery
Definition: xlogrecovery.c:139
static XLogRecPtr missingContrecPtr
Definition: xlogrecovery.c:379
static XLogRecoveryCtlData * XLogRecoveryCtl
Definition: xlogrecovery.c:370
static uint32 readOff
Definition: xlogrecovery.c:233
static bool standby_signal_file_found
Definition: xlogrecovery.c:151
bool StandbyMode
Definition: xlogrecovery.c:148
static int readFile
Definition: xlogrecovery.c:231
static XLogRecPtr abortedRecPtr
Definition: xlogrecovery.c:378
static XLogRecord * ReadRecord(XLogPrefetcher *xlogprefetcher, int emode, bool fetching_ckpt, TimeLineID replayTLI)
static XLogRecPtr CheckPointLoc
Definition: xlogrecovery.c:168
static bool recovery_signal_file_found
Definition: xlogrecovery.c:152
static XLogPrefetcher * xlogprefetcher
Definition: xlogrecovery.c:192
static XLogReaderState * xlogreader
Definition: xlogrecovery.c:189
static TimeLineID CheckPointTLI
Definition: xlogrecovery.c:169
bool InRecovery
Definition: xlogutils.c:50

References abortedRecPtr, EndOfWalRecoveryInfo::abortedRecPtr, ArchiveRecoveryRequested, Assert(), CheckPointLoc, CheckPointTLI, close, EndOfWalRecoveryInfo::endOfLog, EndOfWalRecoveryInfo::endOfLogTLI, XLogReaderState::EndRecPtr, getRecoveryStopReason(), InArchiveRecovery, InRecovery, EndOfWalRecoveryInfo::lastPage, EndOfWalRecoveryInfo::lastPageBeginPtr, EndOfWalRecoveryInfo::lastRec, EndOfWalRecoveryInfo::lastRecTLI, XLogRecoveryCtlData::lastReplayedReadRecPtr, XLogRecoveryCtlData::lastReplayedTLI, len, missingContrecPtr, EndOfWalRecoveryInfo::missingContrecPtr, palloc(), PANIC, XLogReaderState::readBuf, readFile, readOff, ReadRecord(), recovery_signal_file_found, EndOfWalRecoveryInfo::recovery_signal_file_found, EndOfWalRecoveryInfo::recoveryStopReason, XLogReaderState::seg, ShutDownSlotSync(), standby_signal_file_found, EndOfWalRecoveryInfo::standby_signal_file_found, StandbyMode, wal_segment_size, WalRcvStreaming(), WALOpenSegment::ws_tli, xlogprefetcher, XLogPrefetcherBeginRead(), xlogreader, XLogRecoveryCtl, XLogSegmentOffset, and XLogShutdownWalRcv().

Referenced by StartupXLOG().

◆ GetCurrentChunkReplayStartTime()

TimestampTz GetCurrentChunkReplayStartTime ( void  )

Definition at line 4646 of file xlogrecovery.c.

4647{
4648 TimestampTz xtime;
4649
4653
4654 return xtime;
4655}
int64 TimestampTz
Definition: timestamp.h:39
#define SpinLockRelease(lock)
Definition: spin.h:61
#define SpinLockAcquire(lock)
Definition: spin.h:59
TimestampTz currentChunkStartTime
Definition: xlogrecovery.c:362

References XLogRecoveryCtlData::currentChunkStartTime, XLogRecoveryCtlData::info_lck, SpinLockAcquire, SpinLockRelease, and XLogRecoveryCtl.

Referenced by GetReplicationApplyDelay().

◆ GetCurrentReplayRecPtr()

XLogRecPtr GetCurrentReplayRecPtr ( TimeLineID replayEndTLI)

Definition at line 4582 of file xlogrecovery.c.

4583{
4584 XLogRecPtr recptr;
4585 TimeLineID tli;
4586
4591
4592 if (replayEndTLI)
4593 *replayEndTLI = tli;
4594 return recptr;
4595}
TimeLineID replayEndTLI
Definition: xlogrecovery.c:354
XLogRecPtr replayEndRecPtr
Definition: xlogrecovery.c:353

References XLogRecoveryCtlData::info_lck, XLogRecoveryCtlData::replayEndRecPtr, XLogRecoveryCtlData::replayEndTLI, SpinLockAcquire, SpinLockRelease, and XLogRecoveryCtl.

Referenced by UpdateMinRecoveryPoint(), and xlog_redo().

◆ GetLatestXTime()

◆ GetRecoveryPauseState()

◆ GetXLogReceiptTime()

void GetXLogReceiptTime ( TimestampTz rtime,
bool *  fromStream 
)

Definition at line 4662 of file xlogrecovery.c.

4663{
4664 /*
4665 * This must be executed in the startup process, since we don't export the
4666 * relevant state to shared memory.
4667 */
4669
4670 *rtime = XLogReceiptTime;
4671 *fromStream = (XLogReceiptSource == XLOG_FROM_STREAM);
4672}
static XLogSource XLogReceiptSource
Definition: xlogrecovery.c:260
@ XLOG_FROM_STREAM
Definition: xlogrecovery.c:215
static TimestampTz XLogReceiptTime
Definition: xlogrecovery.c:259

References Assert(), InRecovery, XLOG_FROM_STREAM, XLogReceiptSource, and XLogReceiptTime.

Referenced by GetStandbyLimitTime().

◆ GetXLogReplayRecPtr()

◆ HotStandbyActive()

bool HotStandbyActive ( void  )

Definition at line 4522 of file xlogrecovery.c.

4523{
4524 /*
4525 * We check shared state each time only until Hot Standby is active. We
4526 * can't de-activate Hot Standby, so there's no need to keep checking
4527 * after the shared variable has once been seen true.
4528 */
4530 return true;
4531 else
4532 {
4533 /* spinlock is essential on machines with weak memory ordering! */
4537
4538 return LocalHotStandbyActive;
4539 }
4540}
static bool LocalHotStandbyActive
Definition: xlogrecovery.c:177

References XLogRecoveryCtlData::info_lck, LocalHotStandbyActive, XLogRecoveryCtlData::SharedHotStandbyActive, SpinLockAcquire, SpinLockRelease, and XLogRecoveryCtl.

Referenced by XLogWalRcvSendHSFeedback().

◆ InitWalRecovery()

void InitWalRecovery ( ControlFileData ControlFile,
bool *  wasShutdown_ptr,
bool *  haveBackupLabel_ptr,
bool *  haveTblspcMap_ptr 
)

Definition at line 518 of file xlogrecovery.c.

520{
521 XLogPageReadPrivate *private;
522 struct stat st;
523 bool wasShutdown;
524 XLogRecord *record;
525 DBState dbstate_at_startup;
526 bool haveTblspcMap = false;
527 bool haveBackupLabel = false;
528 CheckPoint checkPoint;
529 bool backupFromStandby = false;
530
531 dbstate_at_startup = ControlFile->state;
532
533 /*
534 * Initialize on the assumption we want to recover to the latest timeline
535 * that's active according to pg_control.
536 */
540 else
542
543 /*
544 * Check for signal files, and if so set up state for offline recovery
545 */
548
549 /*
550 * Take ownership of the wakeup latch if we're going to sleep during
551 * recovery, if required.
552 */
555
556 /*
557 * Set the WAL reading processor now, as it will be needed when reading
558 * the checkpoint record required (backup_label or not).
559 */
560 private = palloc0(sizeof(XLogPageReadPrivate));
561 xlogreader =
563 XL_ROUTINE(.page_read = &XLogPageRead,
564 .segment_open = NULL,
565 .segment_close = wal_segment_close),
566 private);
567 if (!xlogreader)
569 (errcode(ERRCODE_OUT_OF_MEMORY),
570 errmsg("out of memory"),
571 errdetail("Failed while allocating a WAL reading processor.")));
573
574 /*
575 * Set the WAL decode buffer size. This limits how far ahead we can read
576 * in the WAL.
577 */
579
580 /* Create a WAL prefetcher. */
582
583 /*
584 * Allocate two page buffers dedicated to WAL consistency checks. We do
585 * it this way, rather than just making static arrays, for two reasons:
586 * (1) no need to waste the storage in most instantiations of the backend;
587 * (2) a static char array isn't guaranteed to have any particular
588 * alignment, whereas palloc() will provide MAXALIGN'd storage.
589 */
590 replay_image_masked = (char *) palloc(BLCKSZ);
591 primary_image_masked = (char *) palloc(BLCKSZ);
592
593 /*
594 * Read the backup_label file. We want to run this part of the recovery
595 * process after checking for signal files and after performing validation
596 * of the recovery parameters.
597 */
599 &backupFromStandby))
600 {
601 List *tablespaces = NIL;
602
603 /*
604 * Archive recovery was requested, and thanks to the backup label
605 * file, we know how far we need to replay to reach consistency. Enter
606 * archive recovery directly.
607 */
608 InArchiveRecovery = true;
611
612 /*
613 * Omitting backup_label when creating a new replica, PITR node etc.
614 * unfortunately is a common cause of corruption. Logging that
615 * backup_label was used makes it a bit easier to exclude that as the
616 * cause of observed corruption.
617 *
618 * Do so before we try to read the checkpoint record (which can fail),
619 * as otherwise it can be hard to understand why a checkpoint other
620 * than ControlFile->checkPoint is used.
621 */
622 ereport(LOG,
623 (errmsg("starting backup recovery with redo LSN %X/%X, checkpoint LSN %X/%X, on timeline ID %u",
626 CheckPointTLI)));
627
628 /*
629 * When a backup_label file is present, we want to roll forward from
630 * the checkpoint it identifies, rather than using pg_control.
631 */
634 if (record != NULL)
635 {
636 memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
637 wasShutdown = ((record->xl_info & ~XLR_INFO_MASK) == XLOG_CHECKPOINT_SHUTDOWN);
639 (errmsg_internal("checkpoint record is at %X/%X",
641 InRecovery = true; /* force recovery even if SHUTDOWNED */
642
643 /*
644 * Make sure that REDO location exists. This may not be the case
645 * if there was a crash during an online backup, which left a
646 * backup_label around that references a WAL segment that's
647 * already been archived.
648 */
649 if (checkPoint.redo < CheckPointLoc)
650 {
652 if (!ReadRecord(xlogprefetcher, LOG, false,
653 checkPoint.ThisTimeLineID))
655 (errmsg("could not find redo location %X/%X referenced by checkpoint record at %X/%X",
657 errhint("If you are restoring from a backup, touch \"%s/recovery.signal\" or \"%s/standby.signal\" and add required recovery options.\n"
658 "If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n"
659 "Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup.",
661 }
662 }
663 else
664 {
666 (errmsg("could not locate required checkpoint record at %X/%X",
668 errhint("If you are restoring from a backup, touch \"%s/recovery.signal\" or \"%s/standby.signal\" and add required recovery options.\n"
669 "If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n"
670 "Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup.",
672 wasShutdown = false; /* keep compiler quiet */
673 }
674
675 /* Read the tablespace_map file if present and create symlinks. */
676 if (read_tablespace_map(&tablespaces))
677 {
678 ListCell *lc;
679
680 foreach(lc, tablespaces)
681 {
682 tablespaceinfo *ti = lfirst(lc);
683 char *linkloc;
684
685 linkloc = psprintf("%s/%u", PG_TBLSPC_DIR, ti->oid);
686
687 /*
688 * Remove the existing symlink if any and Create the symlink
689 * under PGDATA.
690 */
692
693 if (symlink(ti->path, linkloc) < 0)
696 errmsg("could not create symbolic link \"%s\": %m",
697 linkloc)));
698
699 pfree(ti->path);
700 pfree(ti);
701 }
702
703 /* tell the caller to delete it later */
704 haveTblspcMap = true;
705 }
706
707 /* tell the caller to delete it later */
708 haveBackupLabel = true;
709 }
710 else
711 {
712 /* No backup_label file has been found if we are here. */
713
714 /*
715 * If tablespace_map file is present without backup_label file, there
716 * is no use of such file. There is no harm in retaining it, but it
717 * is better to get rid of the map file so that we don't have any
718 * redundant file in data directory and it will avoid any sort of
719 * confusion. It seems prudent though to just rename the file out of
720 * the way rather than delete it completely, also we ignore any error
721 * that occurs in rename operation as even if map file is present
722 * without backup_label file, it is harmless.
723 */
724 if (stat(TABLESPACE_MAP, &st) == 0)
725 {
726 unlink(TABLESPACE_MAP_OLD);
728 ereport(LOG,
729 (errmsg("ignoring file \"%s\" because no file \"%s\" exists",
731 errdetail("File \"%s\" was renamed to \"%s\".",
733 else
734 ereport(LOG,
735 (errmsg("ignoring file \"%s\" because no file \"%s\" exists",
737 errdetail("Could not rename file \"%s\" to \"%s\": %m.",
739 }
740
741 /*
742 * It's possible that archive recovery was requested, but we don't
743 * know how far we need to replay the WAL before we reach consistency.
744 * This can happen for example if a base backup is taken from a
745 * running server using an atomic filesystem snapshot, without calling
746 * pg_backup_start/stop. Or if you just kill a running primary server
747 * and put it into archive recovery by creating a recovery signal
748 * file.
749 *
750 * Our strategy in that case is to perform crash recovery first,
751 * replaying all the WAL present in pg_wal, and only enter archive
752 * recovery after that.
753 *
754 * But usually we already know how far we need to replay the WAL (up
755 * to minRecoveryPoint, up to backupEndPoint, or until we see an
756 * end-of-backup record), and we can enter archive recovery directly.
757 */
763 {
764 InArchiveRecovery = true;
767 }
768
769 /*
770 * For the same reason as when starting up with backup_label present,
771 * emit a log message when we continue initializing from a base
772 * backup.
773 */
775 ereport(LOG,
776 (errmsg("restarting backup recovery with redo LSN %X/%X",
778
779 /* Get the last valid checkpoint record. */
786 if (record != NULL)
787 {
789 (errmsg_internal("checkpoint record is at %X/%X",
791 }
792 else
793 {
794 /*
795 * We used to attempt to go back to a secondary checkpoint record
796 * here, but only when not in standby mode. We now just fail if we
797 * can't read the last checkpoint because this allows us to
798 * simplify processing around checkpoints.
799 */
801 (errmsg("could not locate a valid checkpoint record at %X/%X",
803 }
804 memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
805 wasShutdown = ((record->xl_info & ~XLR_INFO_MASK) == XLOG_CHECKPOINT_SHUTDOWN);
806 }
807
809 {
811 ereport(LOG,
812 (errmsg("entering standby mode")));
814 ereport(LOG,
815 (errmsg("starting point-in-time recovery to XID %u",
818 ereport(LOG,
819 (errmsg("starting point-in-time recovery to %s",
822 ereport(LOG,
823 (errmsg("starting point-in-time recovery to \"%s\"",
826 ereport(LOG,
827 (errmsg("starting point-in-time recovery to WAL location (LSN) \"%X/%X\"",
830 ereport(LOG,
831 (errmsg("starting point-in-time recovery to earliest consistent point")));
832 else
833 ereport(LOG,
834 (errmsg("starting archive recovery")));
835 }
836
837 /*
838 * If the location of the checkpoint record is not on the expected
839 * timeline in the history of the requested timeline, we cannot proceed:
840 * the backup is not part of the history of the requested timeline.
841 */
842 Assert(expectedTLEs); /* was initialized by reading checkpoint
843 * record */
846 {
847 XLogRecPtr switchpoint;
848
849 /*
850 * tliSwitchPoint will throw an error if the checkpoint's timeline is
851 * not in expectedTLEs at all.
852 */
853 switchpoint = tliSwitchPoint(CheckPointTLI, expectedTLEs, NULL);
855 (errmsg("requested timeline %u is not a child of this server's history",
857 /* translator: %s is a backup_label file or a pg_control file */
858 errdetail("Latest checkpoint in file \"%s\" is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X.",
859 haveBackupLabel ? "backup_label" : "pg_control",
862 LSN_FORMAT_ARGS(switchpoint))));
863 }
864
865 /*
866 * The min recovery point should be part of the requested timeline's
867 * history, too.
868 */
873 (errmsg("requested timeline %u does not contain minimum recovery point %X/%X on timeline %u",
877
879 (errmsg_internal("redo record is at %X/%X; shutdown %s",
880 LSN_FORMAT_ARGS(checkPoint.redo),
881 wasShutdown ? "true" : "false")));
883 (errmsg_internal("next transaction ID: " UINT64_FORMAT "; next OID: %u",
885 checkPoint.nextOid)));
887 (errmsg_internal("next MultiXactId: %u; next MultiXactOffset: %u",
888 checkPoint.nextMulti, checkPoint.nextMultiOffset)));
890 (errmsg_internal("oldest unfrozen transaction ID: %u, in database %u",
891 checkPoint.oldestXid, checkPoint.oldestXidDB)));
893 (errmsg_internal("oldest MultiXactId: %u, in database %u",
894 checkPoint.oldestMulti, checkPoint.oldestMultiDB)));
896 (errmsg_internal("commit timestamp Xid oldest/newest: %u/%u",
897 checkPoint.oldestCommitTsXid,
898 checkPoint.newestCommitTsXid)));
901 (errmsg("invalid next transaction ID")));
902
903 /* sanity check */
904 if (checkPoint.redo > CheckPointLoc)
906 (errmsg("invalid redo in checkpoint record")));
907
908 /*
909 * Check whether we need to force recovery from WAL. If it appears to
910 * have been a clean shutdown and we did not have a recovery signal file,
911 * then assume no recovery needed.
912 */
913 if (checkPoint.redo < CheckPointLoc)
914 {
915 if (wasShutdown)
917 (errmsg("invalid redo record in shutdown checkpoint")));
918 InRecovery = true;
919 }
920 else if (ControlFile->state != DB_SHUTDOWNED)
921 InRecovery = true;
923 {
924 /* force recovery due to presence of recovery signal file */
925 InRecovery = true;
926 }
927
928 /*
929 * If recovery is needed, update our in-memory copy of pg_control to show
930 * that we are recovering and to show the selected checkpoint as the place
931 * we are starting from. We also mark pg_control with any minimum recovery
932 * stop point obtained from a backup history file.
933 *
934 * We don't write the changes to disk yet, though. Only do that after
935 * initializing various subsystems.
936 */
937 if (InRecovery)
938 {
940 {
942 }
943 else
944 {
945 ereport(LOG,
946 (errmsg("database system was not properly shut down; "
947 "automatic recovery in progress")));
949 ereport(LOG,
950 (errmsg("crash recovery starts in timeline %u "
951 "and has target timeline %u",
955 }
957 ControlFile->checkPointCopy = checkPoint;
959 {
960 /* initialize minRecoveryPoint if not set yet */
961 if (ControlFile->minRecoveryPoint < checkPoint.redo)
962 {
963 ControlFile->minRecoveryPoint = checkPoint.redo;
965 }
966 }
967
968 /*
969 * Set backupStartPoint if we're starting recovery from a base backup.
970 *
971 * Also set backupEndPoint and use minRecoveryPoint as the backup end
972 * location if we're starting recovery from a base backup which was
973 * taken from a standby. In this case, the database system status in
974 * pg_control must indicate that the database was already in recovery.
975 * Usually that will be DB_IN_ARCHIVE_RECOVERY but also can be
976 * DB_SHUTDOWNED_IN_RECOVERY if recovery previously was interrupted
977 * before reaching this point; e.g. because restore_command or
978 * primary_conninfo were faulty.
979 *
980 * Any other state indicates that the backup somehow became corrupted
981 * and we can't sensibly continue with recovery.
982 */
983 if (haveBackupLabel)
984 {
985 ControlFile->backupStartPoint = checkPoint.redo;
987
988 if (backupFromStandby)
989 {
990 if (dbstate_at_startup != DB_IN_ARCHIVE_RECOVERY &&
991 dbstate_at_startup != DB_SHUTDOWNED_IN_RECOVERY)
993 (errmsg("backup_label contains data inconsistent with control file"),
994 errhint("This means that the backup is corrupted and you will "
995 "have to use another backup for recovery.")));
997 }
998 }
999 }
1000
1001 /* remember these, so that we know when we have reached consistency */
1006 {
1009 }
1010 else
1011 {
1014 }
1015
1016 /*
1017 * Start recovery assuming that the final record isn't lost.
1018 */
1021
1022 *wasShutdown_ptr = wasShutdown;
1023 *haveBackupLabel_ptr = haveBackupLabel;
1024 *haveTblspcMap_ptr = haveTblspcMap;
1025}
TimeLineID tliOfPointInHistory(XLogRecPtr ptr, List *history)
Definition: timeline.c:544
XLogRecPtr tliSwitchPoint(TimeLineID tli, List *history, TimeLineID *nextTLI)
Definition: timeline.c:572
void remove_tablespace_symlink(const char *linkloc)
Definition: tablespace.c:883
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1862
#define UINT64_FORMAT
Definition: c.h:521
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1158
int errcode_for_file_access(void)
Definition: elog.c:877
int errdetail(const char *fmt,...)
Definition: elog.c:1204
int errhint(const char *fmt,...)
Definition: elog.c:1318
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define LOG
Definition: elog.h:31
#define FATAL
Definition: elog.h:41
#define DEBUG1
Definition: elog.h:30
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:782
char * DataDir
Definition: globals.c:72
void OwnLatch(Latch *latch)
Definition: latch.c:126
void pfree(void *pointer)
Definition: mcxt.c:2146
void * palloc0(Size size)
Definition: mcxt.c:1969
DBState
Definition: pg_control.h:90
@ DB_IN_ARCHIVE_RECOVERY
Definition: pg_control.h:96
@ DB_SHUTDOWNED_IN_RECOVERY
Definition: pg_control.h:93
@ DB_SHUTDOWNED
Definition: pg_control.h:92
@ DB_IN_CRASH_RECOVERY
Definition: pg_control.h:95
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:68
#define lfirst(lc)
Definition: pg_list.h:172
#define NIL
Definition: pg_list.h:68
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43
#define PG_TBLSPC_DIR
Definition: relpath.h:41
Oid oldestMultiDB
Definition: pg_control.h:51
MultiXactId oldestMulti
Definition: pg_control.h:50
MultiXactOffset nextMultiOffset
Definition: pg_control.h:47
TransactionId newestCommitTsXid
Definition: pg_control.h:55
TransactionId oldestXid
Definition: pg_control.h:48
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
Oid nextOid
Definition: pg_control.h:45
MultiXactId nextMulti
Definition: pg_control.h:46
FullTransactionId nextXid
Definition: pg_control.h:44
TransactionId oldestCommitTsXid
Definition: pg_control.h:53
XLogRecPtr redo
Definition: pg_control.h:37
Oid oldestXidDB
Definition: pg_control.h:49
XLogRecPtr backupStartPoint
Definition: pg_control.h:170
bool backupEndRequired
Definition: pg_control.h:172
CheckPoint checkPointCopy
Definition: pg_control.h:135
XLogRecPtr backupEndPoint
Definition: pg_control.h:171
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:168
XLogRecPtr checkPoint
Definition: pg_control.h:133
uint64 system_identifier
Definition: pg_control.h:110
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:169
Definition: pg_list.h:54
uint64 system_identifier
Definition: xlogreader.h:191
uint8 xl_info
Definition: xlogrecord.h:46
#define U64FromFullTransactionId(x)
Definition: transam.h:49
#define XidFromFullTransactionId(x)
Definition: transam.h:48
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
#define symlink(oldpath, newpath)
Definition: win32_port.h:225
int wal_decode_buffer_size
Definition: xlog.c:136
static ControlFileData * ControlFile
Definition: xlog.c:585
#define TABLESPACE_MAP_OLD
Definition: xlog.h:307
#define TABLESPACE_MAP
Definition: xlog.h:306
#define BACKUP_LABEL_FILE
Definition: xlog.h:303
#define LSN_FORMAT_ARGS(lsn)
Definition: xlogdefs.h:43
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
XLogPrefetcher * XLogPrefetcherAllocate(XLogReaderState *reader)
XLogReaderState * XLogReaderAllocate(int wal_segment_size, const char *waldir, XLogReaderRoutine *routine, void *private_data)
Definition: xlogreader.c:107
void XLogReaderSetDecodeBuffer(XLogReaderState *state, void *buffer, size_t size)
Definition: xlogreader.c:91
#define XLogRecGetData(decoder)
Definition: xlogreader.h:415
#define XL_ROUTINE(...)
Definition: xlogreader.h:117
static bool backupEndRequired
Definition: xlogrecovery.c:284
const char * recoveryTargetName
Definition: xlogrecovery.c:92
static XLogRecPtr minRecoveryPoint
Definition: xlogrecovery.c:279
static int XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char *readBuf)
static XLogRecPtr backupEndPoint
Definition: xlogrecovery.c:283
static void validateRecoveryParameters(void)
static XLogRecord * ReadCheckpointRecord(XLogPrefetcher *xlogprefetcher, XLogRecPtr RecPtr, TimeLineID replayTLI)
static TimeLineID RedoStartTLI
Definition: xlogrecovery.c:171
static void readRecoverySignalFile(void)
XLogRecPtr recoveryTargetLSN
Definition: xlogrecovery.c:93
RecoveryTargetType recoveryTarget
Definition: xlogrecovery.c:86
static bool read_tablespace_map(List **tablespaces)
static bool read_backup_label(XLogRecPtr *checkPointLoc, TimeLineID *backupLabelTLI, bool *backupEndRequired, bool *backupFromStandby)
static List * expectedTLEs
Definition: xlogrecovery.c:124
static char * primary_image_masked
Definition: xlogrecovery.c:304
static TimeLineID minRecoveryPointTLI
Definition: xlogrecovery.c:280
TransactionId recoveryTargetXid
Definition: xlogrecovery.c:89
static char * replay_image_masked
Definition: xlogrecovery.c:303
TimeLineID recoveryTargetTLI
Definition: xlogrecovery.c:123
static XLogRecPtr RedoStartLSN
Definition: xlogrecovery.c:170
static void EnableStandbyMode(void)
Definition: xlogrecovery.c:484
TimestampTz recoveryTargetTime
Definition: xlogrecovery.c:91
static bool StandbyModeRequested
Definition: xlogrecovery.c:147
static XLogRecPtr backupStartPoint
Definition: xlogrecovery.c:282
void wal_segment_close(XLogReaderState *state)
Definition: xlogutils.c:831

References abortedRecPtr, ArchiveRecoveryRequested, Assert(), BACKUP_LABEL_FILE, backupEndPoint, ControlFileData::backupEndPoint, backupEndRequired, ControlFileData::backupEndRequired, backupStartPoint, ControlFileData::backupStartPoint, ControlFileData::checkPoint, ControlFileData::checkPointCopy, CheckPointLoc, CheckPointTLI, ControlFile, DataDir, DB_IN_ARCHIVE_RECOVERY, DB_IN_CRASH_RECOVERY, DB_SHUTDOWNED, DB_SHUTDOWNED_IN_RECOVERY, DEBUG1, durable_rename(), EnableStandbyMode(), ereport, errcode(), errcode_for_file_access(), errdetail(), errhint(), errmsg(), errmsg_internal(), ERROR, expectedTLEs, FATAL, InArchiveRecovery, InRecovery, InvalidXLogRecPtr, lfirst, LOG, LSN_FORMAT_ARGS, minRecoveryPoint, ControlFileData::minRecoveryPoint, minRecoveryPointTLI, ControlFileData::minRecoveryPointTLI, missingContrecPtr, CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::nextXid, NIL, tablespaceinfo::oid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, OwnLatch(), palloc(), palloc0(), PANIC, tablespaceinfo::path, pfree(), PG_TBLSPC_DIR, primary_image_masked, psprintf(), read_backup_label(), read_tablespace_map(), ReadCheckpointRecord(), ReadRecord(), readRecoverySignalFile(), RECOVERY_TARGET_IMMEDIATE, RECOVERY_TARGET_LSN, RECOVERY_TARGET_NAME, RECOVERY_TARGET_TIME, RECOVERY_TARGET_XID, recoveryTarget, recoveryTargetLSN, recoveryTargetName, recoveryTargetTime, recoveryTargetTLI, recoveryTargetXid, XLogRecoveryCtlData::recoveryWakeupLatch, CheckPoint::redo, RedoStartLSN, RedoStartTLI, remove_tablespace_symlink(), replay_image_masked, StandbyModeRequested, stat, ControlFileData::state, symlink, XLogReaderState::system_identifier, ControlFileData::system_identifier, TABLESPACE_MAP, TABLESPACE_MAP_OLD, CheckPoint::ThisTimeLineID, timestamptz_to_str(), tliOfPointInHistory(), tliSwitchPoint(), TransactionIdIsNormal, U64FromFullTransactionId, UINT64_FORMAT, validateRecoveryParameters(), wal_decode_buffer_size, wal_segment_close(), wal_segment_size, XidFromFullTransactionId, XLogRecord::xl_info, XL_ROUTINE, XLOG_CHECKPOINT_SHUTDOWN, XLogPageRead(), xlogprefetcher, XLogPrefetcherAllocate(), XLogPrefetcherBeginRead(), xlogreader, XLogReaderAllocate(), XLogReaderSetDecodeBuffer(), XLogRecGetData, XLogRecoveryCtl, and XLogRecPtrIsInvalid.

Referenced by StartupXLOG().

◆ PerformWalRecovery()

void PerformWalRecovery ( void  )

Definition at line 1660 of file xlogrecovery.c.

1661{
1662 XLogRecord *record;
1663 bool reachedRecoveryTarget = false;
1664 TimeLineID replayTLI;
1665
1666 /*
1667 * Initialize shared variables for tracking progress of WAL replay, as if
1668 * we had just replayed the record before the REDO location (or the
1669 * checkpoint record itself, if it's a shutdown checkpoint).
1670 */
1673 {
1677 }
1678 else
1679 {
1683 }
1690
1691 /* Also ensure XLogReceiptTime has a sane value */
1693
1694 /*
1695 * Let postmaster know we've started redo now, so that it can launch the
1696 * archiver if necessary.
1697 */
1700
1701 /*
1702 * Allow read-only connections immediately if we're consistent already.
1703 */
1705
1706 /*
1707 * Find the first record that logically follows the checkpoint --- it
1708 * might physically precede it, though.
1709 */
1711 {
1712 /* back up to find the record */
1713 replayTLI = RedoStartTLI;
1715 record = ReadRecord(xlogprefetcher, PANIC, false, replayTLI);
1716
1717 /*
1718 * If a checkpoint record's redo pointer points back to an earlier
1719 * LSN, the record at that LSN should be an XLOG_CHECKPOINT_REDO
1720 * record.
1721 */
1722 if (record->xl_rmid != RM_XLOG_ID ||
1724 ereport(FATAL,
1725 (errmsg("unexpected record type found at redo point %X/%X",
1727 }
1728 else
1729 {
1730 /* just have to read next record after CheckPoint */
1732 replayTLI = CheckPointTLI;
1733 record = ReadRecord(xlogprefetcher, LOG, false, replayTLI);
1734 }
1735
1736 if (record != NULL)
1737 {
1738 TimestampTz xtime;
1739 PGRUsage ru0;
1740
1741 pg_rusage_init(&ru0);
1742
1743 InRedo = true;
1744
1745 RmgrStartup();
1746
1747 ereport(LOG,
1748 (errmsg("redo starts at %X/%X",
1750
1751 /* Prepare to report progress of the redo phase. */
1752 if (!StandbyMode)
1754
1755 /*
1756 * main redo apply loop
1757 */
1758 do
1759 {
1760 if (!StandbyMode)
1761 ereport_startup_progress("redo in progress, elapsed time: %ld.%02d s, current LSN: %X/%X",
1763
1764#ifdef WAL_DEBUG
1765 if (XLOG_DEBUG)
1766 {
1768
1770 appendStringInfo(&buf, "REDO @ %X/%X; LSN %X/%X: ",
1773 xlog_outrec(&buf, xlogreader);
1774 appendStringInfoString(&buf, " - ");
1776 elog(LOG, "%s", buf.data);
1777 pfree(buf.data);
1778 }
1779#endif
1780
1781 /* Handle interrupt signals of startup process */
1783
1784 /*
1785 * Pause WAL replay, if requested by a hot-standby session via
1786 * SetRecoveryPause().
1787 *
1788 * Note that we intentionally don't take the info_lck spinlock
1789 * here. We might therefore read a slightly stale value of the
1790 * recoveryPause flag, but it can't be very stale (no worse than
1791 * the last spinlock we did acquire). Since a pause request is a
1792 * pretty asynchronous thing anyway, possibly responding to it one
1793 * WAL record later than we otherwise would is a minor issue, so
1794 * it doesn't seem worth adding another spinlock cycle to prevent
1795 * that.
1796 */
1797 if (((volatile XLogRecoveryCtlData *) XLogRecoveryCtl)->recoveryPauseState !=
1799 recoveryPausesHere(false);
1800
1801 /*
1802 * Have we reached our recovery target?
1803 */
1805 {
1806 reachedRecoveryTarget = true;
1807 break;
1808 }
1809
1810 /*
1811 * If we've been asked to lag the primary, wait on latch until
1812 * enough time has passed.
1813 */
1815 {
1816 /*
1817 * We test for paused recovery again here. If user sets
1818 * delayed apply, it may be because they expect to pause
1819 * recovery in case of problems, so we must test again here
1820 * otherwise pausing during the delay-wait wouldn't work.
1821 */
1822 if (((volatile XLogRecoveryCtlData *) XLogRecoveryCtl)->recoveryPauseState !=
1824 recoveryPausesHere(false);
1825 }
1826
1827 /*
1828 * Apply the record
1829 */
1830 ApplyWalRecord(xlogreader, record, &replayTLI);
1831
1832 /* Exit loop if we reached inclusive recovery target */
1834 {
1835 reachedRecoveryTarget = true;
1836 break;
1837 }
1838
1839 /* Else, try to fetch the next WAL record */
1840 record = ReadRecord(xlogprefetcher, LOG, false, replayTLI);
1841 } while (record != NULL);
1842
1843 /*
1844 * end of main redo apply loop
1845 */
1846
1847 if (reachedRecoveryTarget)
1848 {
1849 if (!reachedConsistency)
1850 ereport(FATAL,
1851 (errmsg("requested recovery stop point is before consistent recovery point")));
1852
1853 /*
1854 * This is the last point where we can restart recovery with a new
1855 * recovery target, if we shutdown and begin again. After this,
1856 * Resource Managers may choose to do permanent corrective actions
1857 * at end of recovery.
1858 */
1859 switch (recoveryTargetAction)
1860 {
1862
1863 /*
1864 * exit with special return code to request shutdown of
1865 * postmaster. Log messages issued from postmaster.
1866 */
1867 proc_exit(3);
1868
1870 SetRecoveryPause(true);
1871 recoveryPausesHere(true);
1872
1873 /* drop into promote */
1874
1876 break;
1877 }
1878 }
1879
1880 RmgrCleanup();
1881
1882 ereport(LOG,
1883 (errmsg("redo done at %X/%X system usage: %s",
1885 pg_rusage_show(&ru0))));
1886 xtime = GetLatestXTime();
1887 if (xtime)
1888 ereport(LOG,
1889 (errmsg("last completed transaction was at log time %s",
1890 timestamptz_to_str(xtime))));
1891
1892 InRedo = false;
1893 }
1894 else
1895 {
1896 /* there are no WAL records following the checkpoint */
1897 ereport(LOG,
1898 (errmsg("redo is not required")));
1899 }
1900
1901 /*
1902 * This check is intentionally after the above log messages that indicate
1903 * how far recovery went.
1904 */
1907 !reachedRecoveryTarget)
1908 ereport(FATAL,
1909 (errcode(ERRCODE_CONFIG_FILE_ERROR),
1910 errmsg("recovery ended before configured recovery target was reached")));
1911}
void begin_startup_progress_phase(void)
Definition: startup.c:347
void ProcessStartupProcInterrupts(void)
Definition: startup.c:154
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1645
#define elog(elevel,...)
Definition: elog.h:226
bool IsUnderPostmaster
Definition: globals.c:121
void proc_exit(int code)
Definition: ipc.c:104
#define XLOG_CHECKPOINT_REDO
Definition: pg_control.h:82
const char * pg_rusage_show(const PGRUsage *ru0)
Definition: pg_rusage.c:40
void pg_rusage_init(PGRUsage *ru0)
Definition: pg_rusage.c:27
static char * buf
Definition: pg_test_fsync.c:72
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:165
@ PMSIGNAL_RECOVERY_STARTED
Definition: pmsignal.h:35
void RmgrStartup(void)
Definition: rmgr.c:58
void RmgrCleanup(void)
Definition: rmgr.c:74
#define ereport_startup_progress(msg,...)
Definition: startup.h:18
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
XLogRecPtr ReadRecPtr
Definition: xlogreader.h:206
RmgrId xl_rmid
Definition: xlogrecord.h:47
@ RECOVERY_TARGET_ACTION_PAUSE
@ RECOVERY_TARGET_ACTION_PROMOTE
@ RECOVERY_TARGET_ACTION_SHUTDOWN
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
bool reachedConsistency
Definition: xlogrecovery.c:300
static bool recoveryStopsBefore(XLogReaderState *record)
int recoveryTargetAction
Definition: xlogrecovery.c:88
static bool recoveryApplyDelay(XLogReaderState *record)
static bool recoveryStopsAfter(XLogReaderState *record)
static void CheckRecoveryConsistency(void)
void SetRecoveryPause(bool recoveryPause)
void xlog_outdesc(StringInfo buf, XLogReaderState *record)
static bool InRedo
Definition: xlogrecovery.c:204
static void ApplyWalRecord(XLogReaderState *xlogreader, XLogRecord *record, TimeLineID *replayTLI)
static void recoveryPausesHere(bool endOfRecovery)
TimestampTz GetLatestXTime(void)

References appendStringInfo(), appendStringInfoString(), ApplyWalRecord(), ArchiveRecoveryRequested, Assert(), begin_startup_progress_phase(), buf, CheckPointLoc, CheckPointTLI, CheckRecoveryConsistency(), XLogRecoveryCtlData::currentChunkStartTime, elog, XLogReaderState::EndRecPtr, ereport, ereport_startup_progress, errcode(), errmsg(), FATAL, GetCurrentTimestamp(), GetLatestXTime(), XLogRecoveryCtlData::info_lck, initStringInfo(), InRedo, InvalidXLogRecPtr, IsUnderPostmaster, XLogRecoveryCtlData::lastReplayedEndRecPtr, XLogRecoveryCtlData::lastReplayedReadRecPtr, XLogRecoveryCtlData::lastReplayedTLI, LOG, LSN_FORMAT_ARGS, PANIC, pfree(), pg_rusage_init(), pg_rusage_show(), PMSIGNAL_RECOVERY_STARTED, proc_exit(), ProcessStartupProcInterrupts(), reachedConsistency, ReadRecord(), XLogReaderState::ReadRecPtr, RECOVERY_NOT_PAUSED, RECOVERY_TARGET_ACTION_PAUSE, RECOVERY_TARGET_ACTION_PROMOTE, RECOVERY_TARGET_ACTION_SHUTDOWN, RECOVERY_TARGET_UNSET, recoveryApplyDelay(), XLogRecoveryCtlData::recoveryLastXTime, recoveryPausesHere(), XLogRecoveryCtlData::recoveryPauseState, recoveryStopsAfter(), recoveryStopsBefore(), recoveryTarget, recoveryTargetAction, RedoStartLSN, RedoStartTLI, XLogRecoveryCtlData::replayEndRecPtr, XLogRecoveryCtlData::replayEndTLI, RmgrCleanup(), RmgrStartup(), SendPostmasterSignal(), SetRecoveryPause(), SpinLockAcquire, SpinLockRelease, StandbyMode, timestamptz_to_str(), XLogRecord::xl_info, XLogRecord::xl_rmid, XLOG_CHECKPOINT_REDO, xlog_outdesc(), xlogprefetcher, XLogPrefetcherBeginRead(), xlogreader, XLogReceiptTime, XLogRecoveryCtl, and XLR_INFO_MASK.

Referenced by StartupXLOG().

◆ PromoteIsTriggered()

bool PromoteIsTriggered ( void  )

Definition at line 4414 of file xlogrecovery.c.

4415{
4416 /*
4417 * We check shared state each time only until a standby promotion is
4418 * triggered. We can't trigger a promotion again, so there's no need to
4419 * keep checking after the shared variable has once been seen true.
4420 */
4422 return true;
4423
4427
4429}
static bool LocalPromoteIsTriggered
Definition: xlogrecovery.c:183

References XLogRecoveryCtlData::info_lck, LocalPromoteIsTriggered, XLogRecoveryCtlData::SharedPromoteIsTriggered, SpinLockAcquire, SpinLockRelease, and XLogRecoveryCtl.

Referenced by PerformRecoveryXLogAction(), pg_wal_replay_pause(), and pg_wal_replay_resume().

◆ RecoveryRequiresIntParameter()

void RecoveryRequiresIntParameter ( const char *  param_name,
int  currValue,
int  minValue 
)

Definition at line 4679 of file xlogrecovery.c.

4680{
4681 if (currValue < minValue)
4682 {
4684 {
4685 bool warned_for_promote = false;
4686
4688 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4689 errmsg("hot standby is not possible because of insufficient parameter settings"),
4690 errdetail("%s = %d is a lower setting than on the primary server, where its value was %d.",
4691 param_name,
4692 currValue,
4693 minValue)));
4694
4695 SetRecoveryPause(true);
4696
4697 ereport(LOG,
4698 (errmsg("recovery has paused"),
4699 errdetail("If recovery is unpaused, the server will shut down."),
4700 errhint("You can then restart the server after making the necessary configuration changes.")));
4701
4703 {
4705
4707 {
4708 if (!warned_for_promote)
4710 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4711 errmsg("promotion is not possible because of insufficient parameter settings"),
4712
4713 /*
4714 * Repeat the detail from above so it's easy to find
4715 * in the log.
4716 */
4717 errdetail("%s = %d is a lower setting than on the primary server, where its value was %d.",
4718 param_name,
4719 currValue,
4720 minValue),
4721 errhint("Restart the server after making the necessary configuration changes.")));
4722 warned_for_promote = true;
4723 }
4724
4725 /*
4726 * If recovery pause is requested then set it paused. While
4727 * we are in the loop, user might resume and pause again so
4728 * set this every time.
4729 */
4731
4732 /*
4733 * We wait on a condition variable that will wake us as soon
4734 * as the pause ends, but we use a timeout so we can check the
4735 * above conditions periodically too.
4736 */
4738 WAIT_EVENT_RECOVERY_PAUSE);
4739 }
4741 }
4742
4743 ereport(FATAL,
4744 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4745 errmsg("recovery aborted because of insufficient parameter settings"),
4746 /* Repeat the detail from above so it's easy to find in the log. */
4747 errdetail("%s = %d is a lower setting than on the primary server, where its value was %d.",
4748 param_name,
4749 currValue,
4750 minValue),
4751 errhint("You can restart the server after making the necessary configuration changes.")));
4752 }
4753}
bool ConditionVariableCancelSleep(void)
bool ConditionVariableTimedSleep(ConditionVariable *cv, long timeout, uint32 wait_event_info)
#define WARNING
Definition: elog.h:36
ConditionVariable recoveryNotPausedCV
Definition: xlogrecovery.c:365
static bool CheckForStandbyTrigger(void)
static void ConfirmRecoveryPaused(void)
static bool HotStandbyActiveInReplay(void)
RecoveryPauseState GetRecoveryPauseState(void)

References CheckForStandbyTrigger(), ConditionVariableCancelSleep(), ConditionVariableTimedSleep(), ConfirmRecoveryPaused(), ereport, errcode(), errdetail(), errhint(), errmsg(), FATAL, GetRecoveryPauseState(), HotStandbyActiveInReplay(), LOG, ProcessStartupProcInterrupts(), RECOVERY_NOT_PAUSED, XLogRecoveryCtlData::recoveryNotPausedCV, SetRecoveryPause(), WARNING, and XLogRecoveryCtl.

Referenced by CheckRequiredParameterValues().

◆ RemovePromoteSignalFiles()

void RemovePromoteSignalFiles ( void  )

Definition at line 4474 of file xlogrecovery.c.

4475{
4476 unlink(PROMOTE_SIGNAL_FILE);
4477}

References PROMOTE_SIGNAL_FILE.

Referenced by CheckForStandbyTrigger(), and PostmasterMain().

◆ SetRecoveryPause()

◆ ShutdownWalRecovery()

void ShutdownWalRecovery ( void  )

Definition at line 1616 of file xlogrecovery.c.

1617{
1618 char recoveryPath[MAXPGPATH];
1619
1620 /* Final update of pg_stat_recovery_prefetch. */
1622
1623 /* Shut down xlogreader */
1624 if (readFile >= 0)
1625 {
1626 close(readFile);
1627 readFile = -1;
1628 }
1631
1633 {
1634 /*
1635 * Since there might be a partial WAL segment named RECOVERYXLOG, get
1636 * rid of it.
1637 */
1638 snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYXLOG");
1639 unlink(recoveryPath); /* ignore any error */
1640
1641 /* Get rid of any remaining recovered timeline-history file, too */
1642 snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYHISTORY");
1643 unlink(recoveryPath); /* ignore any error */
1644 }
1645
1646 /*
1647 * We don't need the latch anymore. It's not strictly necessary to disown
1648 * it, but let's do it for the sake of tidiness.
1649 */
1652}
void DisownLatch(Latch *latch)
Definition: latch.c:144
#define MAXPGPATH
#define snprintf
Definition: port.h:239
#define XLOGDIR
void XLogPrefetcherComputeStats(XLogPrefetcher *prefetcher)
void XLogPrefetcherFree(XLogPrefetcher *prefetcher)
void XLogReaderFree(XLogReaderState *state)
Definition: xlogreader.c:162

References ArchiveRecoveryRequested, close, DisownLatch(), MAXPGPATH, readFile, XLogRecoveryCtlData::recoveryWakeupLatch, snprintf, XLOGDIR, xlogprefetcher, XLogPrefetcherComputeStats(), XLogPrefetcherFree(), xlogreader, XLogReaderFree(), and XLogRecoveryCtl.

Referenced by StartupXLOG().

◆ StartupRequestWalReceiverRestart()

void StartupRequestWalReceiverRestart ( void  )

Definition at line 4395 of file xlogrecovery.c.

4396{
4398 {
4399 ereport(LOG,
4400 (errmsg("WAL receiver process shutdown requested")));
4401
4402 pendingWalRcvRestart = true;
4403 }
4404}
bool WalRcvRunning(void)
static bool pendingWalRcvRestart
Definition: xlogrecovery.c:249
static XLogSource currentSource
Definition: xlogrecovery.c:247

References currentSource, ereport, errmsg(), LOG, pendingWalRcvRestart, WalRcvRunning(), and XLOG_FROM_STREAM.

Referenced by StartupRereadConfig().

◆ WakeupRecovery()

◆ xlog_outdesc()

void xlog_outdesc ( StringInfo  buf,
XLogReaderState record 
)

Definition at line 2308 of file xlogrecovery.c.

2309{
2310 RmgrData rmgr = GetRmgr(XLogRecGetRmid(record));
2311 uint8 info = XLogRecGetInfo(record);
2312 const char *id;
2313
2316
2317 id = rmgr.rm_identify(info);
2318 if (id == NULL)
2319 appendStringInfo(buf, "UNKNOWN (%X): ", info & ~XLR_INFO_MASK);
2320 else
2321 appendStringInfo(buf, "%s: ", id);
2322
2323 rmgr.rm_desc(buf, record);
2324}
uint8_t uint8
Definition: c.h:500
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:242
const char *(* rm_identify)(uint8 info)
const char * rm_name
void(* rm_desc)(StringInfo buf, XLogReaderState *record)
static RmgrData GetRmgr(RmgrId rmid)
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:410
#define XLogRecGetRmid(decoder)
Definition: xlogreader.h:411

References appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), buf, GetRmgr(), RmgrData::rm_desc, RmgrData::rm_identify, RmgrData::rm_name, XLogRecGetInfo, XLogRecGetRmid, and XLR_INFO_MASK.

Referenced by PerformWalRecovery(), rm_redo_error_callback(), and XLogInsertRecord().

◆ XLogRecoveryShmemInit()

void XLogRecoveryShmemInit ( void  )

Definition at line 464 of file xlogrecovery.c.

465{
466 bool found;
467
469 ShmemInitStruct("XLOG Recovery Ctl", XLogRecoveryShmemSize(), &found);
470 if (found)
471 return;
472 memset(XLogRecoveryCtl, 0, sizeof(XLogRecoveryCtlData));
473
477}
void ConditionVariableInit(ConditionVariable *cv)
void InitSharedLatch(Latch *latch)
Definition: latch.c:93
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:387
#define SpinLockInit(lock)
Definition: spin.h:57
Size XLogRecoveryShmemSize(void)
Definition: xlogrecovery.c:453

References ConditionVariableInit(), XLogRecoveryCtlData::info_lck, InitSharedLatch(), XLogRecoveryCtlData::recoveryNotPausedCV, XLogRecoveryCtlData::recoveryWakeupLatch, ShmemInitStruct(), SpinLockInit, XLogRecoveryCtl, and XLogRecoveryShmemSize().

Referenced by CreateOrAttachShmemStructs().

◆ XLogRecoveryShmemSize()

Size XLogRecoveryShmemSize ( void  )

Definition at line 453 of file xlogrecovery.c.

454{
455 Size size;
456
457 /* XLogRecoveryCtl */
458 size = sizeof(XLogRecoveryCtlData);
459
460 return size;
461}
size_t Size
Definition: c.h:576
struct XLogRecoveryCtlData XLogRecoveryCtlData

Referenced by CalculateShmemSize(), and XLogRecoveryShmemInit().

◆ XLogRequestWalReceiverReply()

void XLogRequestWalReceiverReply ( void  )

Definition at line 4507 of file xlogrecovery.c.

4508{
4510}
static bool doRequestWalReceiverReply
Definition: xlogrecovery.c:186

References doRequestWalReceiverReply.

Referenced by xact_redo_commit().

Variable Documentation

◆ archiveCleanupCommand

PGDLLIMPORT char* archiveCleanupCommand
extern

Definition at line 85 of file xlogrecovery.c.

Referenced by CreateRestartPoint().

◆ PrimaryConnInfo

PGDLLIMPORT char* PrimaryConnInfo
extern

Definition at line 97 of file xlogrecovery.c.

◆ PrimarySlotName

PGDLLIMPORT char* PrimarySlotName
extern

Definition at line 98 of file xlogrecovery.c.

◆ reachedConsistency

◆ recovery_min_apply_delay

PGDLLIMPORT int recovery_min_apply_delay
extern

Definition at line 94 of file xlogrecovery.c.

Referenced by recoveryApplyDelay().

◆ recovery_target_time_string

PGDLLIMPORT char* recovery_target_time_string
extern

Definition at line 90 of file xlogrecovery.c.

Referenced by validateRecoveryParameters().

◆ recoveryEndCommand

PGDLLIMPORT char* recoveryEndCommand
extern

Definition at line 84 of file xlogrecovery.c.

Referenced by CleanupAfterArchiveRecovery().

◆ recoveryRestoreCommand

PGDLLIMPORT char* recoveryRestoreCommand
extern

Definition at line 83 of file xlogrecovery.c.

Referenced by RestoreArchivedFile(), and validateRecoveryParameters().

◆ recoveryTarget

◆ recoveryTargetAction

PGDLLIMPORT int recoveryTargetAction
extern

Definition at line 88 of file xlogrecovery.c.

Referenced by PerformWalRecovery(), and validateRecoveryParameters().

◆ recoveryTargetInclusive

PGDLLIMPORT bool recoveryTargetInclusive
extern

Definition at line 87 of file xlogrecovery.c.

Referenced by recoveryStopsAfter(), and recoveryStopsBefore().

◆ recoveryTargetLSN

PGDLLIMPORT XLogRecPtr recoveryTargetLSN
extern

◆ recoveryTargetName

PGDLLIMPORT const char* recoveryTargetName
extern

Definition at line 92 of file xlogrecovery.c.

Referenced by assign_recovery_target_name(), InitWalRecovery(), and recoveryStopsAfter().

◆ recoveryTargetTime

PGDLLIMPORT TimestampTz recoveryTargetTime
extern

Definition at line 91 of file xlogrecovery.c.

Referenced by InitWalRecovery(), recoveryStopsBefore(), and validateRecoveryParameters().

◆ recoveryTargetTimeLineGoal

◆ recoveryTargetTLI

◆ recoveryTargetTLIRequested

PGDLLIMPORT TimeLineID recoveryTargetTLIRequested
extern

Definition at line 122 of file xlogrecovery.c.

Referenced by assign_recovery_target_timeline(), and validateRecoveryParameters().

◆ recoveryTargetXid

PGDLLIMPORT TransactionId recoveryTargetXid
extern

◆ StandbyMode

◆ wal_receiver_create_temp_slot

PGDLLIMPORT bool wal_receiver_create_temp_slot
extern

Definition at line 99 of file xlogrecovery.c.

Referenced by StartupRereadConfig(), and WaitForWALToBecomeAvailable().