PostgreSQL Source Code git master
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 4475 of file xlogrecovery.c.

4476{
4477 struct stat stat_buf;
4478
4479 if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
4480 return true;
4481
4482 return false;
4483}
#define stat
Definition: win32_port.h:274
#define PROMOTE_SIGNAL_FILE
Definition: xlog.h:309

References PROMOTE_SIGNAL_FILE, and stat.

Referenced by CheckForStandbyTrigger(), and process_pm_pmsignal().

◆ FinishWalRecovery()

EndOfWalRecoveryInfo * FinishWalRecovery ( void  )

Definition at line 1459 of file xlogrecovery.c.

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

4639{
4640 TimestampTz xtime;
4641
4645
4646 return xtime;
4647}
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:357

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

Referenced by GetReplicationApplyDelay().

◆ GetCurrentReplayRecPtr()

XLogRecPtr GetCurrentReplayRecPtr ( TimeLineID replayEndTLI)

Definition at line 4574 of file xlogrecovery.c.

4575{
4576 XLogRecPtr recptr;
4577 TimeLineID tli;
4578
4583
4584 if (replayEndTLI)
4585 *replayEndTLI = tli;
4586 return recptr;
4587}
TimeLineID replayEndTLI
Definition: xlogrecovery.c:349
XLogRecPtr replayEndRecPtr
Definition: xlogrecovery.c:348

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 4654 of file xlogrecovery.c.

4655{
4656 /*
4657 * This must be executed in the startup process, since we don't export the
4658 * relevant state to shared memory.
4659 */
4661
4662 *rtime = XLogReceiptTime;
4663 *fromStream = (XLogReceiptSource == XLOG_FROM_STREAM);
4664}
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 4514 of file xlogrecovery.c.

4515{
4516 /*
4517 * We check shared state each time only until Hot Standby is active. We
4518 * can't de-activate Hot Standby, so there's no need to keep checking
4519 * after the shared variable has once been seen true.
4520 */
4522 return true;
4523 else
4524 {
4525 /* spinlock is essential on machines with weak memory ordering! */
4529
4530 return LocalHotStandbyActive;
4531 }
4532}
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 513 of file xlogrecovery.c.

515{
516 XLogPageReadPrivate *private;
517 struct stat st;
518 bool wasShutdown;
519 XLogRecord *record;
520 DBState dbstate_at_startup;
521 bool haveTblspcMap = false;
522 bool haveBackupLabel = false;
523 CheckPoint checkPoint;
524 bool backupFromStandby = false;
525
526 dbstate_at_startup = ControlFile->state;
527
528 /*
529 * Initialize on the assumption we want to recover to the latest timeline
530 * that's active according to pg_control.
531 */
535 else
537
538 /*
539 * Check for signal files, and if so set up state for offline recovery
540 */
543
544 /*
545 * Take ownership of the wakeup latch if we're going to sleep during
546 * recovery, if required.
547 */
550
551 /*
552 * Set the WAL reading processor now, as it will be needed when reading
553 * the checkpoint record required (backup_label or not).
554 */
555 private = palloc0(sizeof(XLogPageReadPrivate));
556 xlogreader =
558 XL_ROUTINE(.page_read = &XLogPageRead,
559 .segment_open = NULL,
560 .segment_close = wal_segment_close),
561 private);
562 if (!xlogreader)
564 (errcode(ERRCODE_OUT_OF_MEMORY),
565 errmsg("out of memory"),
566 errdetail("Failed while allocating a WAL reading processor.")));
568
569 /*
570 * Set the WAL decode buffer size. This limits how far ahead we can read
571 * in the WAL.
572 */
574
575 /* Create a WAL prefetcher. */
577
578 /*
579 * Allocate two page buffers dedicated to WAL consistency checks. We do
580 * it this way, rather than just making static arrays, for two reasons:
581 * (1) no need to waste the storage in most instantiations of the backend;
582 * (2) a static char array isn't guaranteed to have any particular
583 * alignment, whereas palloc() will provide MAXALIGN'd storage.
584 */
585 replay_image_masked = (char *) palloc(BLCKSZ);
586 primary_image_masked = (char *) palloc(BLCKSZ);
587
588 /*
589 * Read the backup_label file. We want to run this part of the recovery
590 * process after checking for signal files and after performing validation
591 * of the recovery parameters.
592 */
594 &backupFromStandby))
595 {
596 List *tablespaces = NIL;
597
598 /*
599 * Archive recovery was requested, and thanks to the backup label
600 * file, we know how far we need to replay to reach consistency. Enter
601 * archive recovery directly.
602 */
603 InArchiveRecovery = true;
606
607 /*
608 * Omitting backup_label when creating a new replica, PITR node etc.
609 * unfortunately is a common cause of corruption. Logging that
610 * backup_label was used makes it a bit easier to exclude that as the
611 * cause of observed corruption.
612 *
613 * Do so before we try to read the checkpoint record (which can fail),
614 * as otherwise it can be hard to understand why a checkpoint other
615 * than ControlFile->checkPoint is used.
616 */
617 ereport(LOG,
618 (errmsg("starting backup recovery with redo LSN %X/%X, checkpoint LSN %X/%X, on timeline ID %u",
621 CheckPointTLI)));
622
623 /*
624 * When a backup_label file is present, we want to roll forward from
625 * the checkpoint it identifies, rather than using pg_control.
626 */
629 if (record != NULL)
630 {
631 memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
632 wasShutdown = ((record->xl_info & ~XLR_INFO_MASK) == XLOG_CHECKPOINT_SHUTDOWN);
634 (errmsg_internal("checkpoint record is at %X/%X",
636 InRecovery = true; /* force recovery even if SHUTDOWNED */
637
638 /*
639 * Make sure that REDO location exists. This may not be the case
640 * if there was a crash during an online backup, which left a
641 * backup_label around that references a WAL segment that's
642 * already been archived.
643 */
644 if (checkPoint.redo < CheckPointLoc)
645 {
647 if (!ReadRecord(xlogprefetcher, LOG, false,
648 checkPoint.ThisTimeLineID))
650 (errmsg("could not find redo location %X/%X referenced by checkpoint record at %X/%X",
652 errhint("If you are restoring from a backup, touch \"%s/recovery.signal\" or \"%s/standby.signal\" and add required recovery options.\n"
653 "If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n"
654 "Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup.",
656 }
657 }
658 else
659 {
661 (errmsg("could not locate required checkpoint record at %X/%X",
663 errhint("If you are restoring from a backup, touch \"%s/recovery.signal\" or \"%s/standby.signal\" and add required recovery options.\n"
664 "If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n"
665 "Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup.",
667 wasShutdown = false; /* keep compiler quiet */
668 }
669
670 /* Read the tablespace_map file if present and create symlinks. */
671 if (read_tablespace_map(&tablespaces))
672 {
673 ListCell *lc;
674
675 foreach(lc, tablespaces)
676 {
677 tablespaceinfo *ti = lfirst(lc);
678 char *linkloc;
679
680 linkloc = psprintf("%s/%u", PG_TBLSPC_DIR, ti->oid);
681
682 /*
683 * Remove the existing symlink if any and Create the symlink
684 * under PGDATA.
685 */
687
688 if (symlink(ti->path, linkloc) < 0)
691 errmsg("could not create symbolic link \"%s\": %m",
692 linkloc)));
693
694 pfree(ti->path);
695 pfree(ti);
696 }
697
698 /* tell the caller to delete it later */
699 haveTblspcMap = true;
700 }
701
702 /* tell the caller to delete it later */
703 haveBackupLabel = true;
704 }
705 else
706 {
707 /* No backup_label file has been found if we are here. */
708
709 /*
710 * If tablespace_map file is present without backup_label file, there
711 * is no use of such file. There is no harm in retaining it, but it
712 * is better to get rid of the map file so that we don't have any
713 * redundant file in data directory and it will avoid any sort of
714 * confusion. It seems prudent though to just rename the file out of
715 * the way rather than delete it completely, also we ignore any error
716 * that occurs in rename operation as even if map file is present
717 * without backup_label file, it is harmless.
718 */
719 if (stat(TABLESPACE_MAP, &st) == 0)
720 {
721 unlink(TABLESPACE_MAP_OLD);
723 ereport(LOG,
724 (errmsg("ignoring file \"%s\" because no file \"%s\" exists",
726 errdetail("File \"%s\" was renamed to \"%s\".",
728 else
729 ereport(LOG,
730 (errmsg("ignoring file \"%s\" because no file \"%s\" exists",
732 errdetail("Could not rename file \"%s\" to \"%s\": %m.",
734 }
735
736 /*
737 * It's possible that archive recovery was requested, but we don't
738 * know how far we need to replay the WAL before we reach consistency.
739 * This can happen for example if a base backup is taken from a
740 * running server using an atomic filesystem snapshot, without calling
741 * pg_backup_start/stop. Or if you just kill a running primary server
742 * and put it into archive recovery by creating a recovery signal
743 * file.
744 *
745 * Our strategy in that case is to perform crash recovery first,
746 * replaying all the WAL present in pg_wal, and only enter archive
747 * recovery after that.
748 *
749 * But usually we already know how far we need to replay the WAL (up
750 * to minRecoveryPoint, up to backupEndPoint, or until we see an
751 * end-of-backup record), and we can enter archive recovery directly.
752 */
758 {
759 InArchiveRecovery = true;
762 }
763
764 /*
765 * For the same reason as when starting up with backup_label present,
766 * emit a log message when we continue initializing from a base
767 * backup.
768 */
770 ereport(LOG,
771 (errmsg("restarting backup recovery with redo LSN %X/%X",
773
774 /* Get the last valid checkpoint record. */
781 if (record != NULL)
782 {
784 (errmsg_internal("checkpoint record is at %X/%X",
786 }
787 else
788 {
789 /*
790 * We used to attempt to go back to a secondary checkpoint record
791 * here, but only when not in standby mode. We now just fail if we
792 * can't read the last checkpoint because this allows us to
793 * simplify processing around checkpoints.
794 */
796 (errmsg("could not locate a valid checkpoint record at %X/%X",
798 }
799 memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
800 wasShutdown = ((record->xl_info & ~XLR_INFO_MASK) == XLOG_CHECKPOINT_SHUTDOWN);
801 }
802
804 {
806 ereport(LOG,
807 (errmsg("entering standby mode")));
809 ereport(LOG,
810 (errmsg("starting point-in-time recovery to XID %u",
813 ereport(LOG,
814 (errmsg("starting point-in-time recovery to %s",
817 ereport(LOG,
818 (errmsg("starting point-in-time recovery to \"%s\"",
821 ereport(LOG,
822 (errmsg("starting point-in-time recovery to WAL location (LSN) \"%X/%X\"",
825 ereport(LOG,
826 (errmsg("starting point-in-time recovery to earliest consistent point")));
827 else
828 ereport(LOG,
829 (errmsg("starting archive recovery")));
830 }
831
832 /*
833 * If the location of the checkpoint record is not on the expected
834 * timeline in the history of the requested timeline, we cannot proceed:
835 * the backup is not part of the history of the requested timeline.
836 */
837 Assert(expectedTLEs); /* was initialized by reading checkpoint
838 * record */
841 {
842 XLogRecPtr switchpoint;
843
844 /*
845 * tliSwitchPoint will throw an error if the checkpoint's timeline is
846 * not in expectedTLEs at all.
847 */
850 (errmsg("requested timeline %u is not a child of this server's history",
852 errdetail("Latest checkpoint 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.",
855 LSN_FORMAT_ARGS(switchpoint))));
856 }
857
858 /*
859 * The min recovery point should be part of the requested timeline's
860 * history, too.
861 */
866 (errmsg("requested timeline %u does not contain minimum recovery point %X/%X on timeline %u",
870
872 (errmsg_internal("redo record is at %X/%X; shutdown %s",
873 LSN_FORMAT_ARGS(checkPoint.redo),
874 wasShutdown ? "true" : "false")));
876 (errmsg_internal("next transaction ID: " UINT64_FORMAT "; next OID: %u",
878 checkPoint.nextOid)));
880 (errmsg_internal("next MultiXactId: %u; next MultiXactOffset: %u",
881 checkPoint.nextMulti, checkPoint.nextMultiOffset)));
883 (errmsg_internal("oldest unfrozen transaction ID: %u, in database %u",
884 checkPoint.oldestXid, checkPoint.oldestXidDB)));
886 (errmsg_internal("oldest MultiXactId: %u, in database %u",
887 checkPoint.oldestMulti, checkPoint.oldestMultiDB)));
889 (errmsg_internal("commit timestamp Xid oldest/newest: %u/%u",
890 checkPoint.oldestCommitTsXid,
891 checkPoint.newestCommitTsXid)));
894 (errmsg("invalid next transaction ID")));
895
896 /* sanity check */
897 if (checkPoint.redo > CheckPointLoc)
899 (errmsg("invalid redo in checkpoint record")));
900
901 /*
902 * Check whether we need to force recovery from WAL. If it appears to
903 * have been a clean shutdown and we did not have a recovery signal file,
904 * then assume no recovery needed.
905 */
906 if (checkPoint.redo < CheckPointLoc)
907 {
908 if (wasShutdown)
910 (errmsg("invalid redo record in shutdown checkpoint")));
911 InRecovery = true;
912 }
913 else if (ControlFile->state != DB_SHUTDOWNED)
914 InRecovery = true;
916 {
917 /* force recovery due to presence of recovery signal file */
918 InRecovery = true;
919 }
920
921 /*
922 * If recovery is needed, update our in-memory copy of pg_control to show
923 * that we are recovering and to show the selected checkpoint as the place
924 * we are starting from. We also mark pg_control with any minimum recovery
925 * stop point obtained from a backup history file.
926 *
927 * We don't write the changes to disk yet, though. Only do that after
928 * initializing various subsystems.
929 */
930 if (InRecovery)
931 {
933 {
935 }
936 else
937 {
938 ereport(LOG,
939 (errmsg("database system was not properly shut down; "
940 "automatic recovery in progress")));
942 ereport(LOG,
943 (errmsg("crash recovery starts in timeline %u "
944 "and has target timeline %u",
948 }
950 ControlFile->checkPointCopy = checkPoint;
952 {
953 /* initialize minRecoveryPoint if not set yet */
954 if (ControlFile->minRecoveryPoint < checkPoint.redo)
955 {
956 ControlFile->minRecoveryPoint = checkPoint.redo;
958 }
959 }
960
961 /*
962 * Set backupStartPoint if we're starting recovery from a base backup.
963 *
964 * Also set backupEndPoint and use minRecoveryPoint as the backup end
965 * location if we're starting recovery from a base backup which was
966 * taken from a standby. In this case, the database system status in
967 * pg_control must indicate that the database was already in recovery.
968 * Usually that will be DB_IN_ARCHIVE_RECOVERY but also can be
969 * DB_SHUTDOWNED_IN_RECOVERY if recovery previously was interrupted
970 * before reaching this point; e.g. because restore_command or
971 * primary_conninfo were faulty.
972 *
973 * Any other state indicates that the backup somehow became corrupted
974 * and we can't sensibly continue with recovery.
975 */
976 if (haveBackupLabel)
977 {
978 ControlFile->backupStartPoint = checkPoint.redo;
980
981 if (backupFromStandby)
982 {
983 if (dbstate_at_startup != DB_IN_ARCHIVE_RECOVERY &&
984 dbstate_at_startup != DB_SHUTDOWNED_IN_RECOVERY)
986 (errmsg("backup_label contains data inconsistent with control file"),
987 errhint("This means that the backup is corrupted and you will "
988 "have to use another backup for recovery.")));
990 }
991 }
992 }
993
994 /* remember these, so that we know when we have reached consistency */
999 {
1002 }
1003 else
1004 {
1007 }
1008
1009 /*
1010 * Start recovery assuming that the final record isn't lost.
1011 */
1014
1015 *wasShutdown_ptr = wasShutdown;
1016 *haveBackupLabel_ptr = haveBackupLabel;
1017 *haveTblspcMap_ptr = haveTblspcMap;
1018}
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:1843
#define UINT64_FORMAT
Definition: c.h:507
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1157
int errcode_for_file_access(void)
Definition: elog.c:876
int errdetail(const char *fmt,...)
Definition: elog.c:1203
int errhint(const char *fmt,...)
Definition: elog.c:1317
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#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:781
char * DataDir
Definition: globals.c:70
void OwnLatch(Latch *latch)
Definition: latch.c:463
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc0(Size size)
Definition: mcxt.c:1347
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:574
#define TABLESPACE_MAP_OLD
Definition: xlog.h:306
#define TABLESPACE_MAP
Definition: xlog.h:305
#define BACKUP_LABEL_FILE
Definition: xlog.h:302
#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:299
static TimeLineID minRecoveryPointTLI
Definition: xlogrecovery.c:280
TransactionId recoveryTargetXid
Definition: xlogrecovery.c:89
static char * replay_image_masked
Definition: xlogrecovery.c:298
TimeLineID recoveryTargetTLI
Definition: xlogrecovery.c:123
static XLogRecPtr RedoStartLSN
Definition: xlogrecovery.c:170
static void EnableStandbyMode(void)
Definition: xlogrecovery.c:479
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:842

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 1653 of file xlogrecovery.c.

1654{
1655 XLogRecord *record;
1656 bool reachedRecoveryTarget = false;
1657 TimeLineID replayTLI;
1658
1659 /*
1660 * Initialize shared variables for tracking progress of WAL replay, as if
1661 * we had just replayed the record before the REDO location (or the
1662 * checkpoint record itself, if it's a shutdown checkpoint).
1663 */
1666 {
1670 }
1671 else
1672 {
1676 }
1683
1684 /* Also ensure XLogReceiptTime has a sane value */
1686
1687 /*
1688 * Let postmaster know we've started redo now, so that it can launch the
1689 * archiver if necessary.
1690 */
1693
1694 /*
1695 * Allow read-only connections immediately if we're consistent already.
1696 */
1698
1699 /*
1700 * Find the first record that logically follows the checkpoint --- it
1701 * might physically precede it, though.
1702 */
1704 {
1705 /* back up to find the record */
1706 replayTLI = RedoStartTLI;
1708 record = ReadRecord(xlogprefetcher, PANIC, false, replayTLI);
1709
1710 /*
1711 * If a checkpoint record's redo pointer points back to an earlier
1712 * LSN, the record at that LSN should be an XLOG_CHECKPOINT_REDO
1713 * record.
1714 */
1715 if (record->xl_rmid != RM_XLOG_ID ||
1717 ereport(FATAL,
1718 (errmsg("unexpected record type found at redo point %X/%X",
1720 }
1721 else
1722 {
1723 /* just have to read next record after CheckPoint */
1725 replayTLI = CheckPointTLI;
1726 record = ReadRecord(xlogprefetcher, LOG, false, replayTLI);
1727 }
1728
1729 if (record != NULL)
1730 {
1731 TimestampTz xtime;
1732 PGRUsage ru0;
1733
1734 pg_rusage_init(&ru0);
1735
1736 InRedo = true;
1737
1738 RmgrStartup();
1739
1740 ereport(LOG,
1741 (errmsg("redo starts at %X/%X",
1743
1744 /* Prepare to report progress of the redo phase. */
1745 if (!StandbyMode)
1747
1748 /*
1749 * main redo apply loop
1750 */
1751 do
1752 {
1753 if (!StandbyMode)
1754 ereport_startup_progress("redo in progress, elapsed time: %ld.%02d s, current LSN: %X/%X",
1756
1757#ifdef WAL_DEBUG
1758 if (XLOG_DEBUG)
1759 {
1761
1763 appendStringInfo(&buf, "REDO @ %X/%X; LSN %X/%X: ",
1766 xlog_outrec(&buf, xlogreader);
1767 appendStringInfoString(&buf, " - ");
1769 elog(LOG, "%s", buf.data);
1770 pfree(buf.data);
1771 }
1772#endif
1773
1774 /* Handle interrupt signals of startup process */
1776
1777 /*
1778 * Pause WAL replay, if requested by a hot-standby session via
1779 * SetRecoveryPause().
1780 *
1781 * Note that we intentionally don't take the info_lck spinlock
1782 * here. We might therefore read a slightly stale value of the
1783 * recoveryPause flag, but it can't be very stale (no worse than
1784 * the last spinlock we did acquire). Since a pause request is a
1785 * pretty asynchronous thing anyway, possibly responding to it one
1786 * WAL record later than we otherwise would is a minor issue, so
1787 * it doesn't seem worth adding another spinlock cycle to prevent
1788 * that.
1789 */
1790 if (((volatile XLogRecoveryCtlData *) XLogRecoveryCtl)->recoveryPauseState !=
1792 recoveryPausesHere(false);
1793
1794 /*
1795 * Have we reached our recovery target?
1796 */
1798 {
1799 reachedRecoveryTarget = true;
1800 break;
1801 }
1802
1803 /*
1804 * If we've been asked to lag the primary, wait on latch until
1805 * enough time has passed.
1806 */
1808 {
1809 /*
1810 * We test for paused recovery again here. If user sets
1811 * delayed apply, it may be because they expect to pause
1812 * recovery in case of problems, so we must test again here
1813 * otherwise pausing during the delay-wait wouldn't work.
1814 */
1815 if (((volatile XLogRecoveryCtlData *) XLogRecoveryCtl)->recoveryPauseState !=
1817 recoveryPausesHere(false);
1818 }
1819
1820 /*
1821 * Apply the record
1822 */
1823 ApplyWalRecord(xlogreader, record, &replayTLI);
1824
1825 /* Exit loop if we reached inclusive recovery target */
1827 {
1828 reachedRecoveryTarget = true;
1829 break;
1830 }
1831
1832 /* Else, try to fetch the next WAL record */
1833 record = ReadRecord(xlogprefetcher, LOG, false, replayTLI);
1834 } while (record != NULL);
1835
1836 /*
1837 * end of main redo apply loop
1838 */
1839
1840 if (reachedRecoveryTarget)
1841 {
1842 if (!reachedConsistency)
1843 ereport(FATAL,
1844 (errmsg("requested recovery stop point is before consistent recovery point")));
1845
1846 /*
1847 * This is the last point where we can restart recovery with a new
1848 * recovery target, if we shutdown and begin again. After this,
1849 * Resource Managers may choose to do permanent corrective actions
1850 * at end of recovery.
1851 */
1852 switch (recoveryTargetAction)
1853 {
1855
1856 /*
1857 * exit with special return code to request shutdown of
1858 * postmaster. Log messages issued from postmaster.
1859 */
1860 proc_exit(3);
1861
1863 SetRecoveryPause(true);
1864 recoveryPausesHere(true);
1865
1866 /* drop into promote */
1867
1869 break;
1870 }
1871 }
1872
1873 RmgrCleanup();
1874
1875 ereport(LOG,
1876 (errmsg("redo done at %X/%X system usage: %s",
1878 pg_rusage_show(&ru0))));
1879 xtime = GetLatestXTime();
1880 if (xtime)
1881 ereport(LOG,
1882 (errmsg("last completed transaction was at log time %s",
1883 timestamptz_to_str(xtime))));
1884
1885 InRedo = false;
1886 }
1887 else
1888 {
1889 /* there are no WAL records following the checkpoint */
1890 ereport(LOG,
1891 (errmsg("redo is not required")));
1892 }
1893
1894 /*
1895 * This check is intentionally after the above log messages that indicate
1896 * how far recovery went.
1897 */
1900 !reachedRecoveryTarget)
1901 ereport(FATAL,
1902 (errcode(ERRCODE_CONFIG_FILE_ERROR),
1903 errmsg("recovery ended before configured recovery target was reached")));
1904}
void HandleStartupProcInterrupts(void)
Definition: startup.c:154
void begin_startup_progress_phase(void)
Definition: startup.c:343
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1644
#define elog(elevel,...)
Definition: elog.h:225
bool IsUnderPostmaster
Definition: globals.c:119
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:295
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(), HandleStartupProcInterrupts(), 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(), 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 4406 of file xlogrecovery.c.

4407{
4408 /*
4409 * We check shared state each time only until a standby promotion is
4410 * triggered. We can't trigger a promotion again, so there's no need to
4411 * keep checking after the shared variable has once been seen true.
4412 */
4414 return true;
4415
4419
4421}
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 4671 of file xlogrecovery.c.

4672{
4673 if (currValue < minValue)
4674 {
4676 {
4677 bool warned_for_promote = false;
4678
4680 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4681 errmsg("hot standby is not possible because of insufficient parameter settings"),
4682 errdetail("%s = %d is a lower setting than on the primary server, where its value was %d.",
4683 param_name,
4684 currValue,
4685 minValue)));
4686
4687 SetRecoveryPause(true);
4688
4689 ereport(LOG,
4690 (errmsg("recovery has paused"),
4691 errdetail("If recovery is unpaused, the server will shut down."),
4692 errhint("You can then restart the server after making the necessary configuration changes.")));
4693
4695 {
4697
4699 {
4700 if (!warned_for_promote)
4702 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4703 errmsg("promotion is not possible because of insufficient parameter settings"),
4704
4705 /*
4706 * Repeat the detail from above so it's easy to find
4707 * in the log.
4708 */
4709 errdetail("%s = %d is a lower setting than on the primary server, where its value was %d.",
4710 param_name,
4711 currValue,
4712 minValue),
4713 errhint("Restart the server after making the necessary configuration changes.")));
4714 warned_for_promote = true;
4715 }
4716
4717 /*
4718 * If recovery pause is requested then set it paused. While
4719 * we are in the loop, user might resume and pause again so
4720 * set this every time.
4721 */
4723
4724 /*
4725 * We wait on a condition variable that will wake us as soon
4726 * as the pause ends, but we use a timeout so we can check the
4727 * above conditions periodically too.
4728 */
4730 WAIT_EVENT_RECOVERY_PAUSE);
4731 }
4733 }
4734
4735 ereport(FATAL,
4736 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4737 errmsg("recovery aborted because of insufficient parameter settings"),
4738 /* Repeat the detail from above so it's easy to find in the log. */
4739 errdetail("%s = %d is a lower setting than on the primary server, where its value was %d.",
4740 param_name,
4741 currValue,
4742 minValue),
4743 errhint("You can restart the server after making the necessary configuration changes.")));
4744 }
4745}
bool ConditionVariableCancelSleep(void)
bool ConditionVariableTimedSleep(ConditionVariable *cv, long timeout, uint32 wait_event_info)
#define WARNING
Definition: elog.h:36
ConditionVariable recoveryNotPausedCV
Definition: xlogrecovery.c:360
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(), HandleStartupProcInterrupts(), HotStandbyActiveInReplay(), LOG, RECOVERY_NOT_PAUSED, XLogRecoveryCtlData::recoveryNotPausedCV, SetRecoveryPause(), WARNING, and XLogRecoveryCtl.

Referenced by CheckRequiredParameterValues().

◆ RemovePromoteSignalFiles()

void RemovePromoteSignalFiles ( void  )

Definition at line 4466 of file xlogrecovery.c.

4467{
4468 unlink(PROMOTE_SIGNAL_FILE);
4469}

References PROMOTE_SIGNAL_FILE.

Referenced by CheckForStandbyTrigger(), and PostmasterMain().

◆ SetRecoveryPause()

◆ ShutdownWalRecovery()

void ShutdownWalRecovery ( void  )

Definition at line 1609 of file xlogrecovery.c.

1610{
1611 char recoveryPath[MAXPGPATH];
1612
1613 /* Final update of pg_stat_recovery_prefetch. */
1615
1616 /* Shut down xlogreader */
1617 if (readFile >= 0)
1618 {
1619 close(readFile);
1620 readFile = -1;
1621 }
1624
1626 {
1627 /*
1628 * Since there might be a partial WAL segment named RECOVERYXLOG, get
1629 * rid of it.
1630 */
1631 snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYXLOG");
1632 unlink(recoveryPath); /* ignore any error */
1633
1634 /* Get rid of any remaining recovered timeline-history file, too */
1635 snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYHISTORY");
1636 unlink(recoveryPath); /* ignore any error */
1637 }
1638
1639 /*
1640 * We don't need the latch anymore. It's not strictly necessary to disown
1641 * it, but let's do it for the sake of tidiness.
1642 */
1645}
void DisownLatch(Latch *latch)
Definition: latch.c:489
#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 4387 of file xlogrecovery.c.

4388{
4390 {
4391 ereport(LOG,
4392 (errmsg("WAL receiver process shutdown requested")));
4393
4394 pendingWalRcvRestart = true;
4395 }
4396}
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 2300 of file xlogrecovery.c.

2301{
2302 RmgrData rmgr = GetRmgr(XLogRecGetRmid(record));
2303 uint8 info = XLogRecGetInfo(record);
2304 const char *id;
2305
2308
2309 id = rmgr.rm_identify(info);
2310 if (id == NULL)
2311 appendStringInfo(buf, "UNKNOWN (%X): ", info & ~XLR_INFO_MASK);
2312 else
2313 appendStringInfo(buf, "%s: ", id);
2314
2315 rmgr.rm_desc(buf, record);
2316}
uint8_t uint8
Definition: c.h:486
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 459 of file xlogrecovery.c.

460{
461 bool found;
462
464 ShmemInitStruct("XLOG Recovery Ctl", XLogRecoveryShmemSize(), &found);
465 if (found)
466 return;
467 memset(XLogRecoveryCtl, 0, sizeof(XLogRecoveryCtlData));
468
472}
void ConditionVariableInit(ConditionVariable *cv)
void InitSharedLatch(Latch *latch)
Definition: latch.c:430
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:382
#define SpinLockInit(lock)
Definition: spin.h:57
Size XLogRecoveryShmemSize(void)
Definition: xlogrecovery.c:448

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 448 of file xlogrecovery.c.

449{
450 Size size;
451
452 /* XLogRecoveryCtl */
453 size = sizeof(XLogRecoveryCtlData);
454
455 return size;
456}
size_t Size
Definition: c.h:562
static pg_noinline void Size size
Definition: slab.c:607
struct XLogRecoveryCtlData XLogRecoveryCtlData

References size.

Referenced by CalculateShmemSize(), and XLogRecoveryShmemInit().

◆ XLogRequestWalReceiverReply()

void XLogRequestWalReceiverReply ( void  )

Definition at line 4499 of file xlogrecovery.c.

4500{
4502}
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().