PostgreSQL Source Code git master
Loading...
Searching...
No Matches
xlogrecovery.h File Reference
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  XLogRecoveryCtlData
 
struct  EndOfWalRecoveryInfo
 

Typedefs

typedef enum RecoveryPauseState RecoveryPauseState
 
typedef struct XLogRecoveryCtlData XLogRecoveryCtlData
 

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  RecoveryTargetAction { RECOVERY_TARGET_ACTION_PAUSE , RECOVERY_TARGET_ACTION_PROMOTE , RECOVERY_TARGET_ACTION_SHUTDOWN }
 
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 XLogRecoveryCtlDataXLogRecoveryCtl
 
PGDLLIMPORT bool recoveryTargetInclusive
 
PGDLLIMPORT int recoveryTargetAction
 
PGDLLIMPORT int recovery_min_apply_delay
 
PGDLLIMPORT charPrimaryConnInfo
 
PGDLLIMPORT charPrimarySlotName
 
PGDLLIMPORT charrecoveryRestoreCommand
 
PGDLLIMPORT charrecoveryEndCommand
 
PGDLLIMPORT chararchiveCleanupCommand
 
PGDLLIMPORT TransactionId recoveryTargetXid
 
PGDLLIMPORT charrecovery_target_time_string
 
PGDLLIMPORT TimestampTz recoveryTargetTime
 
PGDLLIMPORT const charrecoveryTargetName
 
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

◆ XLogRecoveryCtlData

Enumeration Type Documentation

◆ RecoveryPauseState

Enumerator
RECOVERY_NOT_PAUSED 
RECOVERY_PAUSE_REQUESTED 
RECOVERY_PAUSED 

Definition at line 56 of file xlogrecovery.h.

57{
58 RECOVERY_NOT_PAUSED, /* pause not requested */
59 RECOVERY_PAUSE_REQUESTED, /* pause requested, but not yet paused */
60 RECOVERY_PAUSED, /* recovery is paused */
RecoveryPauseState
@ RECOVERY_PAUSED
@ RECOVERY_NOT_PAUSED
@ RECOVERY_PAUSE_REQUESTED

◆ RecoveryTargetAction

Enumerator
RECOVERY_TARGET_ACTION_PAUSE 
RECOVERY_TARGET_ACTION_PROMOTE 
RECOVERY_TARGET_ACTION_SHUTDOWN 

Definition at line 48 of file xlogrecovery.h.

◆ RecoveryTargetTimeLineGoal

Enumerator
RECOVERY_TARGET_TIMELINE_CONTROLFILE 
RECOVERY_TARGET_TIMELINE_LATEST 
RECOVERY_TARGET_TIMELINE_NUMERIC 

Definition at line 38 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 25 of file xlogrecovery.h.

26{
RecoveryTargetType
@ RECOVERY_TARGET_IMMEDIATE
@ RECOVERY_TARGET_TIME
@ RECOVERY_TARGET_UNSET
@ RECOVERY_TARGET_XID
@ RECOVERY_TARGET_LSN
@ RECOVERY_TARGET_NAME

Function Documentation

◆ CheckPromoteSignal()

bool CheckPromoteSignal ( void  )
extern

Definition at line 4468 of file xlogrecovery.c.

4469{
4470 struct stat stat_buf;
4471
4472 if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
4473 return true;
4474
4475 return false;
4476}
static int fb(int x)
#define stat
Definition win32_port.h:74
#define PROMOTE_SIGNAL_FILE
Definition xlog.h:328

References fb(), PROMOTE_SIGNAL_FILE, and stat.

Referenced by CheckForStandbyTrigger(), and process_pm_pmsignal().

◆ FinishWalRecovery()

EndOfWalRecoveryInfo * FinishWalRecovery ( void  )
extern

Definition at line 1416 of file xlogrecovery.c.

1417{
1419 XLogRecPtr lastRec;
1420 TimeLineID lastRecTLI;
1421 XLogRecPtr endOfLog;
1422
1423 /*
1424 * Kill WAL receiver, if it's still running, before we continue to write
1425 * the startup checkpoint and aborted-contrecord records. It will trump
1426 * over these records and subsequent ones if it's still alive when we
1427 * start writing WAL.
1428 */
1430
1431 /*
1432 * Shutdown the slot sync worker to drop any temporary slots acquired by
1433 * it and to prevent it from keep trying to fetch the failover slots.
1434 *
1435 * We do not update the 'synced' column in 'pg_replication_slots' system
1436 * view from true to false here, as any failed update could leave 'synced'
1437 * column false for some slots. This could cause issues during slot sync
1438 * after restarting the server as a standby. While updating the 'synced'
1439 * column after switching to the new timeline is an option, it does not
1440 * simplify the handling for the 'synced' column. Therefore, we retain the
1441 * 'synced' column as true after promotion as it may provide useful
1442 * information about the slot origin.
1443 */
1445
1446 /*
1447 * We are now done reading the xlog from stream. Turn off streaming
1448 * recovery to force fetching the files (which would be required at end of
1449 * recovery, e.g., timeline history file) from archive or pg_wal.
1450 *
1451 * Note that standby mode must be turned off after killing WAL receiver,
1452 * i.e., calling XLogShutdownWalRcv().
1453 */
1455 StandbyMode = false;
1456
1457 /*
1458 * Determine where to start writing WAL next.
1459 *
1460 * Re-fetch the last valid or last applied record, so we can identify the
1461 * exact endpoint of what we consider the valid portion of WAL. There may
1462 * be an incomplete continuation record after that, in which case
1463 * 'abortedRecPtr' and 'missingContrecPtr' are set and the caller will
1464 * write a special OVERWRITE_CONTRECORD message to mark that the rest of
1465 * it is intentionally missing. See CreateOverwriteContrecordRecord().
1466 *
1467 * An important side-effect of this is to load the last page into
1468 * xlogreader. The caller uses it to initialize the WAL for writing.
1469 */
1470 if (!InRecovery)
1471 {
1472 lastRec = CheckPointLoc;
1473 lastRecTLI = CheckPointTLI;
1474 }
1475 else
1476 {
1478 lastRecTLI = XLogRecoveryCtl->lastReplayedTLI;
1479 }
1481 (void) ReadRecord(xlogprefetcher, PANIC, false, lastRecTLI);
1482 endOfLog = xlogreader->EndRecPtr;
1483
1484 /*
1485 * Remember the TLI in the filename of the XLOG segment containing the
1486 * end-of-log. It could be different from the timeline that endOfLog
1487 * nominally belongs to, if there was a timeline switch in that segment,
1488 * and we were reading the old WAL from a segment belonging to a higher
1489 * timeline.
1490 */
1491 result->endOfLogTLI = xlogreader->seg.ws_tli;
1492
1494 {
1495 /*
1496 * We are no longer in archive recovery state.
1497 *
1498 * We are now done reading the old WAL. Turn off archive fetching if
1499 * it was active.
1500 */
1502 InArchiveRecovery = false;
1503
1504 /*
1505 * If the ending log segment is still open, close it (to avoid
1506 * problems on Windows with trying to rename or delete an open file).
1507 */
1508 if (readFile >= 0)
1509 {
1510 close(readFile);
1511 readFile = -1;
1512 }
1513 }
1514
1515 /*
1516 * Copy the last partial block to the caller, for initializing the WAL
1517 * buffer for appending new WAL.
1518 */
1519 if (endOfLog % XLOG_BLCKSZ != 0)
1520 {
1521 char *page;
1522 int len;
1524
1525 pageBeginPtr = endOfLog - (endOfLog % XLOG_BLCKSZ);
1527
1528 /* Copy the valid part of the last block */
1529 len = endOfLog % XLOG_BLCKSZ;
1530 page = palloc(len);
1531 memcpy(page, xlogreader->readBuf, len);
1532
1534 result->lastPage = page;
1535 }
1536 else
1537 {
1538 /* There is no partial block to copy. */
1539 result->lastPageBeginPtr = endOfLog;
1540 result->lastPage = NULL;
1541 }
1542
1543 /*
1544 * Create a comment for the history file to explain why and where timeline
1545 * changed.
1546 */
1548
1549 result->lastRec = lastRec;
1550 result->lastRecTLI = lastRecTLI;
1551 result->endOfLog = endOfLog;
1552
1553 result->abortedRecPtr = abortedRecPtr;
1555
1558
1559 return result;
1560}
#define Assert(condition)
Definition c.h:945
#define PANIC
Definition elog.h:42
#define palloc_object(type)
Definition fe_memutils.h:74
#define close(a)
Definition win32.h:12
void * palloc(Size size)
Definition mcxt.c:1387
const void size_t len
void ShutDownSlotSync(void)
Definition slotsync.c:1727
XLogRecPtr lastPageBeginPtr
XLogRecPtr missingContrecPtr
TimeLineID ws_tli
Definition xlogreader.h:49
XLogRecPtr EndRecPtr
Definition xlogreader.h:206
WALOpenSegment seg
Definition xlogreader.h:271
TimeLineID lastReplayedTLI
XLogRecPtr lastReplayedReadRecPtr
bool WalRcvStreaming(void)
int wal_segment_size
Definition xlog.c:147
void XLogShutdownWalRcv(void)
Definition xlog.c:9668
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
uint64 XLogRecPtr
Definition xlogdefs.h:21
uint32 TimeLineID
Definition xlogdefs.h:63
void XLogPrefetcherBeginRead(XLogPrefetcher *prefetcher, XLogRecPtr recPtr)
static char * getRecoveryStopReason(void)
bool ArchiveRecoveryRequested
bool InArchiveRecovery
static XLogRecPtr missingContrecPtr
XLogRecoveryCtlData * XLogRecoveryCtl
static uint32 readOff
static bool standby_signal_file_found
bool StandbyMode
static int readFile
static XLogRecPtr abortedRecPtr
static XLogRecord * ReadRecord(XLogPrefetcher *xlogprefetcher, int emode, bool fetching_ckpt, TimeLineID replayTLI)
static XLogRecPtr CheckPointLoc
static bool recovery_signal_file_found
static XLogPrefetcher * xlogprefetcher
static XLogReaderState * xlogreader
static TimeLineID CheckPointTLI
bool InRecovery
Definition xlogutils.c:50

References abortedRecPtr, EndOfWalRecoveryInfo::abortedRecPtr, ArchiveRecoveryRequested, Assert, CheckPointLoc, CheckPointTLI, close, EndOfWalRecoveryInfo::endOfLog, EndOfWalRecoveryInfo::endOfLogTLI, XLogReaderState::EndRecPtr, fb(), getRecoveryStopReason(), InArchiveRecovery, InRecovery, EndOfWalRecoveryInfo::lastPage, EndOfWalRecoveryInfo::lastPageBeginPtr, EndOfWalRecoveryInfo::lastRec, EndOfWalRecoveryInfo::lastRecTLI, XLogRecoveryCtlData::lastReplayedReadRecPtr, XLogRecoveryCtlData::lastReplayedTLI, len, missingContrecPtr, EndOfWalRecoveryInfo::missingContrecPtr, palloc(), palloc_object, 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  )
extern

Definition at line 4631 of file xlogrecovery.c.

4632{
4634
4638
4639 return xtime;
4640}
int64 TimestampTz
Definition timestamp.h:39
static void SpinLockRelease(volatile slock_t *lock)
Definition spin.h:62
static void SpinLockAcquire(volatile slock_t *lock)
Definition spin.h:56
TimestampTz currentChunkStartTime

References XLogRecoveryCtlData::currentChunkStartTime, fb(), XLogRecoveryCtlData::info_lck, SpinLockAcquire(), SpinLockRelease(), and XLogRecoveryCtl.

Referenced by GetReplicationApplyDelay().

◆ GetCurrentReplayRecPtr()

XLogRecPtr GetCurrentReplayRecPtr ( TimeLineID replayEndTLI)
extern

◆ GetLatestXTime()

◆ GetRecoveryPauseState()

◆ GetXLogReceiptTime()

void GetXLogReceiptTime ( TimestampTz rtime,
bool fromStream 
)
extern

Definition at line 4647 of file xlogrecovery.c.

4648{
4649 /*
4650 * This must be executed in the startup process, since we don't export the
4651 * relevant state to shared memory.
4652 */
4654
4657}
static XLogSource XLogReceiptSource
@ XLOG_FROM_STREAM
static TimestampTz XLogReceiptTime

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

Referenced by GetStandbyLimitTime().

◆ GetXLogReplayRecPtr()

◆ HotStandbyActive()

bool HotStandbyActive ( void  )
extern

Definition at line 4507 of file xlogrecovery.c.

4508{
4509 /*
4510 * We check shared state each time only until Hot Standby is active. We
4511 * can't de-activate Hot Standby, so there's no need to keep checking
4512 * after the shared variable has once been seen true.
4513 */
4515 return true;
4516 else
4517 {
4518 /* spinlock is essential on machines with weak memory ordering! */
4522
4523 return LocalHotStandbyActive;
4524 }
4525}
static bool LocalHotStandbyActive

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 
)
extern

Definition at line 456 of file xlogrecovery.c.

458{
459 XLogPageReadPrivate *private;
460 struct stat st;
461 bool wasShutdown;
462 XLogRecord *record;
464 bool haveTblspcMap = false;
465 bool haveBackupLabel = false;
466 CheckPoint checkPoint;
467 bool backupFromStandby = false;
468
470
471 /*
472 * Initialize on the assumption we want to recover to the latest timeline
473 * that's active according to pg_control.
474 */
478 else
480
481 /*
482 * Check for signal files, and if so set up state for offline recovery
483 */
486
487 /*
488 * Take ownership of the wakeup latch if we're going to sleep during
489 * recovery, if required.
490 */
493
494 /*
495 * Set the WAL reading processor now, as it will be needed when reading
496 * the checkpoint record required (backup_label or not).
497 */
499 xlogreader =
501 XL_ROUTINE(.page_read = &XLogPageRead,
502 .segment_open = NULL,
503 .segment_close = wal_segment_close),
504 private);
505 if (!xlogreader)
508 errmsg("out of memory"),
509 errdetail("Failed while allocating a WAL reading processor.")));
511
512 /*
513 * Set the WAL decode buffer size. This limits how far ahead we can read
514 * in the WAL.
515 */
517
518 /* Create a WAL prefetcher. */
520
521 /*
522 * Allocate two page buffers dedicated to WAL consistency checks. We do
523 * it this way, rather than just making static arrays, for two reasons:
524 * (1) no need to waste the storage in most instantiations of the backend;
525 * (2) a static char array isn't guaranteed to have any particular
526 * alignment, whereas palloc() will provide MAXALIGN'd storage.
527 */
530
531 /*
532 * Read the backup_label file. We want to run this part of the recovery
533 * process after checking for signal files and after performing validation
534 * of the recovery parameters.
535 */
538 {
539 List *tablespaces = NIL;
540
541 /*
542 * Archive recovery was requested, and thanks to the backup label
543 * file, we know how far we need to replay to reach consistency. Enter
544 * archive recovery directly.
545 */
546 InArchiveRecovery = true;
549
550 /*
551 * Omitting backup_label when creating a new replica, PITR node etc.
552 * unfortunately is a common cause of corruption. Logging that
553 * backup_label was used makes it a bit easier to exclude that as the
554 * cause of observed corruption.
555 *
556 * Do so before we try to read the checkpoint record (which can fail),
557 * as otherwise it can be hard to understand why a checkpoint other
558 * than ControlFile->checkPoint is used.
559 */
560 ereport(LOG,
561 errmsg("starting backup recovery with redo LSN %X/%08X, checkpoint LSN %X/%08X, on timeline ID %u",
565
566 /*
567 * When a backup_label file is present, we want to roll forward from
568 * the checkpoint it identifies, rather than using pg_control.
569 */
572 if (record != NULL)
573 {
574 memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
577 errmsg_internal("checkpoint record is at %X/%08X",
579 InRecovery = true; /* force recovery even if SHUTDOWNED */
580
581 /*
582 * Make sure that REDO location exists. This may not be the case
583 * if there was a crash during an online backup, which left a
584 * backup_label around that references a WAL segment that's
585 * already been archived.
586 */
587 if (checkPoint.redo < CheckPointLoc)
588 {
590 if (!ReadRecord(xlogprefetcher, LOG, false,
591 checkPoint.ThisTimeLineID))
593 errmsg("could not find redo location %X/%08X referenced by checkpoint record at %X/%08X",
595 errhint("If you are restoring from a backup, touch \"%s/recovery.signal\" or \"%s/standby.signal\" and add required recovery options.\n"
596 "If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n"
597 "Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup.",
599 }
600 }
601 else
602 {
604 errmsg("could not locate required checkpoint record at %X/%08X",
606 errhint("If you are restoring from a backup, touch \"%s/recovery.signal\" or \"%s/standby.signal\" and add required recovery options.\n"
607 "If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n"
608 "Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup.",
610 wasShutdown = false; /* keep compiler quiet */
611 }
612
613 /* Read the tablespace_map file if present and create symlinks. */
614 if (read_tablespace_map(&tablespaces))
615 {
616 ListCell *lc;
617
618 foreach(lc, tablespaces)
619 {
621 char *linkloc;
622
623 linkloc = psprintf("%s/%u", PG_TBLSPC_DIR, ti->oid);
624
625 /*
626 * Remove the existing symlink if any and Create the symlink
627 * under PGDATA.
628 */
630
631 if (symlink(ti->path, linkloc) < 0)
634 errmsg("could not create symbolic link \"%s\": %m",
635 linkloc)));
636
637 pfree(ti->path);
638 pfree(ti);
639 }
640
641 /* tell the caller to delete it later */
642 haveTblspcMap = true;
643 }
644
645 /* tell the caller to delete it later */
646 haveBackupLabel = true;
647 }
648 else
649 {
650 /* No backup_label file has been found if we are here. */
651
652 /*
653 * If tablespace_map file is present without backup_label file, there
654 * is no use of such file. There is no harm in retaining it, but it
655 * is better to get rid of the map file so that we don't have any
656 * redundant file in data directory and it will avoid any sort of
657 * confusion. It seems prudent though to just rename the file out of
658 * the way rather than delete it completely, also we ignore any error
659 * that occurs in rename operation as even if map file is present
660 * without backup_label file, it is harmless.
661 */
662 if (stat(TABLESPACE_MAP, &st) == 0)
663 {
666 ereport(LOG,
667 (errmsg("ignoring file \"%s\" because no file \"%s\" exists",
669 errdetail("File \"%s\" was renamed to \"%s\".",
671 else
672 ereport(LOG,
673 (errmsg("ignoring file \"%s\" because no file \"%s\" exists",
675 errdetail("Could not rename file \"%s\" to \"%s\": %m.",
677 }
678
679 /*
680 * It's possible that archive recovery was requested, but we don't
681 * know how far we need to replay the WAL before we reach consistency.
682 * This can happen for example if a base backup is taken from a
683 * running server using an atomic filesystem snapshot, without calling
684 * pg_backup_start/stop. Or if you just kill a running primary server
685 * and put it into archive recovery by creating a recovery signal
686 * file.
687 *
688 * Our strategy in that case is to perform crash recovery first,
689 * replaying all the WAL present in pg_wal, and only enter archive
690 * recovery after that.
691 *
692 * But usually we already know how far we need to replay the WAL (up
693 * to minRecoveryPoint, up to backupEndPoint, or until we see an
694 * end-of-backup record), and we can enter archive recovery directly.
695 */
701 {
702 InArchiveRecovery = true;
705 }
706
707 /*
708 * For the same reason as when starting up with backup_label present,
709 * emit a log message when we continue initializing from a base
710 * backup.
711 */
713 ereport(LOG,
714 errmsg("restarting backup recovery with redo LSN %X/%08X",
716
717 /* Get the last valid checkpoint record. */
724 if (record != NULL)
725 {
727 errmsg_internal("checkpoint record is at %X/%08X",
729 }
730 else
731 {
732 /*
733 * We used to attempt to go back to a secondary checkpoint record
734 * here, but only when not in standby mode. We now just fail if we
735 * can't read the last checkpoint because this allows us to
736 * simplify processing around checkpoints.
737 */
739 errmsg("could not locate a valid checkpoint record at %X/%08X",
741 }
742 memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
744
745 /* Make sure that REDO location exists. */
746 if (checkPoint.redo < CheckPointLoc)
747 {
749 if (!ReadRecord(xlogprefetcher, LOG, false, checkPoint.ThisTimeLineID))
751 errmsg("could not find redo location %X/%08X referenced by checkpoint record at %X/%08X",
753 }
754 }
755
757 {
759 ereport(LOG,
760 (errmsg("entering standby mode")));
762 ereport(LOG,
763 (errmsg("starting point-in-time recovery to XID %u",
766 ereport(LOG,
767 (errmsg("starting point-in-time recovery to %s",
770 ereport(LOG,
771 (errmsg("starting point-in-time recovery to \"%s\"",
774 ereport(LOG,
775 errmsg("starting point-in-time recovery to WAL location (LSN) \"%X/%08X\"",
778 ereport(LOG,
779 (errmsg("starting point-in-time recovery to earliest consistent point")));
780 else
781 ereport(LOG,
782 (errmsg("starting archive recovery")));
783 }
784
785 /*
786 * If the location of the checkpoint record is not on the expected
787 * timeline in the history of the requested timeline, we cannot proceed:
788 * the backup is not part of the history of the requested timeline.
789 */
790 Assert(expectedTLEs); /* was initialized by reading checkpoint
791 * record */
794 {
796
797 /*
798 * tliSwitchPoint will throw an error if the checkpoint's timeline is
799 * not in expectedTLEs at all.
800 */
803 (errmsg("requested timeline %u is not a child of this server's history",
805 /* translator: %s is a backup_label file or a pg_control file */
806 errdetail("Latest checkpoint in file \"%s\" is at %X/%08X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%08X.",
807 haveBackupLabel ? "backup_label" : "pg_control",
811 }
812
813 /*
814 * The min recovery point should be part of the requested timeline's
815 * history, too.
816 */
821 errmsg("requested timeline %u does not contain minimum recovery point %X/%08X on timeline %u",
825
827 errmsg_internal("redo record is at %X/%08X; shutdown %s",
828 LSN_FORMAT_ARGS(checkPoint.redo),
829 wasShutdown ? "true" : "false"));
831 (errmsg_internal("next transaction ID: " UINT64_FORMAT "; next OID: %u",
833 checkPoint.nextOid)));
835 (errmsg_internal("next MultiXactId: %u; next MultiXactOffset: %" PRIu64,
836 checkPoint.nextMulti, checkPoint.nextMultiOffset)));
838 (errmsg_internal("oldest unfrozen transaction ID: %u, in database %u",
839 checkPoint.oldestXid, checkPoint.oldestXidDB)));
841 (errmsg_internal("oldest MultiXactId: %u, in database %u",
842 checkPoint.oldestMulti, checkPoint.oldestMultiDB)));
844 (errmsg_internal("commit timestamp Xid oldest/newest: %u/%u",
845 checkPoint.oldestCommitTsXid,
846 checkPoint.newestCommitTsXid)));
849 (errmsg("invalid next transaction ID")));
850
851 /* sanity check */
852 if (checkPoint.redo > CheckPointLoc)
854 (errmsg("invalid redo in checkpoint record")));
855
856 /*
857 * Check whether we need to force recovery from WAL. If it appears to
858 * have been a clean shutdown and we did not have a recovery signal file,
859 * then assume no recovery needed.
860 */
861 if (checkPoint.redo < CheckPointLoc)
862 {
863 if (wasShutdown)
865 (errmsg("invalid redo record in shutdown checkpoint")));
866 InRecovery = true;
867 }
868 else if (ControlFile->state != DB_SHUTDOWNED)
869 InRecovery = true;
871 {
872 /* force recovery due to presence of recovery signal file */
873 InRecovery = true;
874 }
875
876 /*
877 * If recovery is needed, update our in-memory copy of pg_control to show
878 * that we are recovering and to show the selected checkpoint as the place
879 * we are starting from. We also mark pg_control with any minimum recovery
880 * stop point obtained from a backup history file.
881 *
882 * We don't write the changes to disk yet, though. Only do that after
883 * initializing various subsystems.
884 */
885 if (InRecovery)
886 {
888 {
890 }
891 else
892 {
893 ereport(LOG,
894 (errmsg("database system was not properly shut down; "
895 "automatic recovery in progress")));
897 ereport(LOG,
898 (errmsg("crash recovery starts in timeline %u "
899 "and has target timeline %u",
903 }
905 ControlFile->checkPointCopy = checkPoint;
907 {
908 /* initialize minRecoveryPoint if not set yet */
909 if (ControlFile->minRecoveryPoint < checkPoint.redo)
910 {
911 ControlFile->minRecoveryPoint = checkPoint.redo;
913 }
914 }
915
916 /*
917 * Set backupStartPoint if we're starting recovery from a base backup.
918 *
919 * Also set backupEndPoint and use minRecoveryPoint as the backup end
920 * location if we're starting recovery from a base backup which was
921 * taken from a standby. In this case, the database system status in
922 * pg_control must indicate that the database was already in recovery.
923 * Usually that will be DB_IN_ARCHIVE_RECOVERY but also can be
924 * DB_SHUTDOWNED_IN_RECOVERY if recovery previously was interrupted
925 * before reaching this point; e.g. because restore_command or
926 * primary_conninfo were faulty.
927 *
928 * Any other state indicates that the backup somehow became corrupted
929 * and we can't sensibly continue with recovery.
930 */
931 if (haveBackupLabel)
932 {
933 ControlFile->backupStartPoint = checkPoint.redo;
935
937 {
941 (errmsg("backup_label contains data inconsistent with control file"),
942 errhint("This means that the backup is corrupted and you will "
943 "have to use another backup for recovery.")));
945 }
946 }
947 }
948
949 /* remember these, so that we know when we have reached consistency */
954 {
957 }
958 else
959 {
962 }
963
964 /*
965 * Start recovery assuming that the final record isn't lost.
966 */
969
973}
TimeLineID tliOfPointInHistory(XLogRecPtr ptr, List *history)
Definition timeline.c:545
XLogRecPtr tliSwitchPoint(TimeLineID tli, List *history, TimeLineID *nextTLI)
Definition timeline.c:573
void remove_tablespace_symlink(const char *linkloc)
Definition tablespace.c:890
const char * timestamptz_to_str(TimestampTz t)
Definition timestamp.c:1853
#define UINT64_FORMAT
Definition c.h:637
int errcode_for_file_access(void)
Definition elog.c:897
int errcode(int sqlerrcode)
Definition elog.c:874
#define LOG
Definition elog.h:31
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define FATAL
Definition elog.h:41
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define DEBUG1
Definition elog.h:30
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition fd.c:783
#define palloc0_object(type)
Definition fe_memutils.h:75
char * DataDir
Definition globals.c:71
void OwnLatch(Latch *latch)
Definition latch.c:126
void pfree(void *pointer)
Definition mcxt.c:1616
static char * errmsg
DBState
Definition pg_control.h:92
@ DB_IN_ARCHIVE_RECOVERY
Definition pg_control.h:98
@ DB_SHUTDOWNED_IN_RECOVERY
Definition pg_control.h:95
@ DB_SHUTDOWNED
Definition pg_control.h:94
@ DB_IN_CRASH_RECOVERY
Definition pg_control.h:97
#define XLOG_CHECKPOINT_SHUTDOWN
Definition pg_control.h:69
#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:52
MultiXactId oldestMulti
Definition pg_control.h:51
MultiXactOffset nextMultiOffset
Definition pg_control.h:48
TransactionId newestCommitTsXid
Definition pg_control.h:56
TransactionId oldestXid
Definition pg_control.h:49
TimeLineID ThisTimeLineID
Definition pg_control.h:39
MultiXactId nextMulti
Definition pg_control.h:47
FullTransactionId nextXid
Definition pg_control.h:45
TransactionId oldestCommitTsXid
Definition pg_control.h:54
XLogRecPtr redo
Definition pg_control.h:37
Oid oldestXidDB
Definition pg_control.h:50
XLogRecPtr backupStartPoint
Definition pg_control.h:172
CheckPoint checkPointCopy
Definition pg_control.h:137
XLogRecPtr backupEndPoint
Definition pg_control.h:173
XLogRecPtr minRecoveryPoint
Definition pg_control.h:170
XLogRecPtr checkPoint
Definition pg_control.h:135
uint64 system_identifier
Definition pg_control.h:112
TimeLineID minRecoveryPointTLI
Definition pg_control.h:171
Definition pg_list.h:54
uint64 system_identifier
Definition xlogreader.h:190
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:140
static ControlFileData * ControlFile
Definition xlog.c:577
#define TABLESPACE_MAP_OLD
Definition xlog.h:325
#define TABLESPACE_MAP
Definition xlog.h:324
#define BACKUP_LABEL_FILE
Definition xlog.h:321
#define XLogRecPtrIsValid(r)
Definition xlogdefs.h:29
#define LSN_FORMAT_ARGS(lsn)
Definition xlogdefs.h:47
#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:108
void XLogReaderSetDecodeBuffer(XLogReaderState *state, void *buffer, size_t size)
Definition xlogreader.c:92
#define XLogRecGetData(decoder)
Definition xlogreader.h:414
#define XL_ROUTINE(...)
Definition xlogreader.h:117
static bool backupEndRequired
const char * recoveryTargetName
static XLogRecPtr minRecoveryPoint
static int XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char *readBuf)
static XLogRecPtr backupEndPoint
static void validateRecoveryParameters(void)
static XLogRecord * ReadCheckpointRecord(XLogPrefetcher *xlogprefetcher, XLogRecPtr RecPtr, TimeLineID replayTLI)
static TimeLineID RedoStartTLI
static void readRecoverySignalFile(void)
XLogRecPtr recoveryTargetLSN
RecoveryTargetType recoveryTarget
static bool read_tablespace_map(List **tablespaces)
static bool read_backup_label(XLogRecPtr *checkPointLoc, TimeLineID *backupLabelTLI, bool *backupEndRequired, bool *backupFromStandby)
static List * expectedTLEs
static char * primary_image_masked
static TimeLineID minRecoveryPointTLI
TransactionId recoveryTargetXid
static char * replay_image_masked
TimeLineID recoveryTargetTLI
static XLogRecPtr RedoStartLSN
static void EnableStandbyMode(void)
TimestampTz recoveryTargetTime
static bool StandbyModeRequested
static XLogRecPtr backupStartPoint
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, fb(), 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, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, OwnLatch(), palloc(), palloc0_object, PANIC, 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 XLogRecPtrIsValid.

Referenced by StartupXLOG().

◆ PerformWalRecovery()

void PerformWalRecovery ( void  )
extern

Definition at line 1611 of file xlogrecovery.c.

1612{
1613 XLogRecord *record;
1614 bool reachedRecoveryTarget = false;
1615 TimeLineID replayTLI;
1616
1617 /*
1618 * Initialize shared variables for tracking progress of WAL replay, as if
1619 * we had just replayed the record before the REDO location (or the
1620 * checkpoint record itself, if it's a shutdown checkpoint).
1621 */
1624 {
1628 }
1629 else
1630 {
1634 }
1641
1642 /* Also ensure XLogReceiptTime has a sane value */
1644
1645 /*
1646 * Let postmaster know we've started redo now, so that it can launch the
1647 * archiver if necessary.
1648 */
1651
1652 /*
1653 * Allow read-only connections immediately if we're consistent already.
1654 */
1656
1657 /*
1658 * Find the first record that logically follows the checkpoint --- it
1659 * might physically precede it, though.
1660 */
1662 {
1663 /* back up to find the record */
1664 replayTLI = RedoStartTLI;
1666 record = ReadRecord(xlogprefetcher, PANIC, false, replayTLI);
1667
1668 /*
1669 * If a checkpoint record's redo pointer points back to an earlier
1670 * LSN, the record at that LSN should be an XLOG_CHECKPOINT_REDO
1671 * record.
1672 */
1673 if (record->xl_rmid != RM_XLOG_ID ||
1675 ereport(FATAL,
1676 errmsg("unexpected record type found at redo point %X/%08X",
1678 }
1679 else
1680 {
1681 /* just have to read next record after CheckPoint */
1683 replayTLI = CheckPointTLI;
1684 record = ReadRecord(xlogprefetcher, LOG, false, replayTLI);
1685 }
1686
1687 if (record != NULL)
1688 {
1690 PGRUsage ru0;
1691
1693
1694 InRedo = true;
1695
1696 RmgrStartup();
1697
1698 ereport(LOG,
1699 errmsg("redo starts at %X/%08X",
1701
1702 /* Prepare to report progress of the redo phase. */
1703 if (!StandbyMode)
1705
1706 /*
1707 * main redo apply loop
1708 */
1709 do
1710 {
1711 if (!StandbyMode)
1712 ereport_startup_progress("redo in progress, elapsed time: %ld.%02d s, current LSN: %X/%08X",
1714
1715#ifdef WAL_DEBUG
1716 if (XLOG_DEBUG)
1717 {
1719
1721 appendStringInfo(&buf, "REDO @ %X/%08X; LSN %X/%08X: ",
1725 appendStringInfoString(&buf, " - ");
1727 elog(LOG, "%s", buf.data);
1728 pfree(buf.data);
1729 }
1730#endif
1731
1732 /* Handle interrupt signals of startup process */
1734
1735 /*
1736 * Pause WAL replay, if requested by a hot-standby session via
1737 * SetRecoveryPause().
1738 *
1739 * Note that we intentionally don't take the info_lck spinlock
1740 * here. We might therefore read a slightly stale value of the
1741 * recoveryPause flag, but it can't be very stale (no worse than
1742 * the last spinlock we did acquire). Since a pause request is a
1743 * pretty asynchronous thing anyway, possibly responding to it one
1744 * WAL record later than we otherwise would is a minor issue, so
1745 * it doesn't seem worth adding another spinlock cycle to prevent
1746 * that.
1747 */
1748 if (((volatile XLogRecoveryCtlData *) XLogRecoveryCtl)->recoveryPauseState !=
1750 recoveryPausesHere(false);
1751
1752 /*
1753 * Have we reached our recovery target?
1754 */
1756 {
1757 reachedRecoveryTarget = true;
1758 break;
1759 }
1760
1761 /*
1762 * If we've been asked to lag the primary, wait on latch until
1763 * enough time has passed.
1764 */
1766 {
1767 /*
1768 * We test for paused recovery again here. If user sets
1769 * delayed apply, it may be because they expect to pause
1770 * recovery in case of problems, so we must test again here
1771 * otherwise pausing during the delay-wait wouldn't work.
1772 */
1773 if (((volatile XLogRecoveryCtlData *) XLogRecoveryCtl)->recoveryPauseState !=
1775 recoveryPausesHere(false);
1776 }
1777
1778 /*
1779 * Apply the record
1780 */
1781 ApplyWalRecord(xlogreader, record, &replayTLI);
1782
1783 /*
1784 * If we replayed an LSN that someone was waiting for then walk
1785 * over the shared memory array and set latches to notify the
1786 * waiters.
1787 */
1788 if (waitLSNState &&
1792
1793 /* Exit loop if we reached inclusive recovery target */
1795 {
1796 reachedRecoveryTarget = true;
1797 break;
1798 }
1799
1800 /* Else, try to fetch the next WAL record */
1801 record = ReadRecord(xlogprefetcher, LOG, false, replayTLI);
1802 } while (record != NULL);
1803
1804 /*
1805 * end of main redo apply loop
1806 */
1807
1809 {
1810 if (!reachedConsistency)
1811 ereport(FATAL,
1812 (errmsg("requested recovery stop point is before consistent recovery point")));
1813
1814 /*
1815 * This is the last point where we can restart recovery with a new
1816 * recovery target, if we shutdown and begin again. After this,
1817 * Resource Managers may choose to do permanent corrective actions
1818 * at end of recovery.
1819 */
1820 switch (recoveryTargetAction)
1821 {
1823
1824 /*
1825 * exit with special return code to request shutdown of
1826 * postmaster. Log messages issued from postmaster.
1827 */
1828 proc_exit(3);
1829
1831 SetRecoveryPause(true);
1832 recoveryPausesHere(true);
1833
1834 /* drop into promote */
1836
1838 break;
1839 }
1840 }
1841
1842 RmgrCleanup();
1843
1844 ereport(LOG,
1845 errmsg("redo done at %X/%08X system usage: %s",
1847 pg_rusage_show(&ru0)));
1849 if (xtime)
1850 ereport(LOG,
1851 (errmsg("last completed transaction was at log time %s",
1853
1854 InRedo = false;
1855 }
1856 else
1857 {
1858 /* there are no WAL records following the checkpoint */
1859 ereport(LOG,
1860 (errmsg("redo is not required")));
1861 }
1862
1863 /*
1864 * This check is intentionally after the above log messages that indicate
1865 * how far recovery went.
1866 */
1870 ereport(FATAL,
1872 errmsg("recovery ended before configured recovery target was reached")));
1873}
static uint64 pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr)
Definition atomics.h:467
void begin_startup_progress_phase(void)
Definition startup.c:342
void ProcessStartupProcInterrupts(void)
Definition startup.c:154
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1636
#define pg_fallthrough
Definition c.h:152
#define elog(elevel,...)
Definition elog.h:226
bool IsUnderPostmaster
Definition globals.c:120
void proc_exit(int code)
Definition ipc.c:105
#define XLOG_CHECKPOINT_REDO
Definition pg_control.h:83
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[DEFAULT_XLOG_SEG_SIZE]
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
pg_atomic_uint64 minWaitedLSN[WAIT_LSN_TYPE_COUNT]
Definition xlogwait.h:85
XLogRecPtr ReadRecPtr
Definition xlogreader.h:205
RmgrId xl_rmid
Definition xlogrecord.h:47
#define XLR_INFO_MASK
Definition xlogrecord.h:62
bool reachedConsistency
static bool recoveryStopsBefore(XLogReaderState *record)
int recoveryTargetAction
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
static void ApplyWalRecord(XLogReaderState *xlogreader, XLogRecord *record, TimeLineID *replayTLI)
static void recoveryPausesHere(bool endOfRecovery)
TimestampTz GetLatestXTime(void)
struct WaitLSNState * waitLSNState
Definition xlogwait.c:69
void WaitLSNWakeup(WaitLSNType lsnType, XLogRecPtr currentLSN)
Definition xlogwait.c:318
@ WAIT_LSN_TYPE_STANDBY_REPLAY
Definition xlogwait.h:39

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, fb(), GetCurrentTimestamp(), GetLatestXTime(), XLogRecoveryCtlData::info_lck, initStringInfo(), InRedo, InvalidXLogRecPtr, IsUnderPostmaster, XLogRecoveryCtlData::lastReplayedEndRecPtr, XLogRecoveryCtlData::lastReplayedReadRecPtr, XLogRecoveryCtlData::lastReplayedTLI, LOG, LSN_FORMAT_ARGS, WaitLSNState::minWaitedLSN, PANIC, pfree(), pg_atomic_read_u64(), pg_fallthrough, 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(), WAIT_LSN_TYPE_STANDBY_REPLAY, waitLSNState, WaitLSNWakeup(), 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  )
extern

Definition at line 4399 of file xlogrecovery.c.

4400{
4401 /*
4402 * We check shared state each time only until a standby promotion is
4403 * triggered. We can't trigger a promotion again, so there's no need to
4404 * keep checking after the shared variable has once been seen true.
4405 */
4407 return true;
4408
4412
4414}
static bool LocalPromoteIsTriggered

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

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

◆ RecoveryRequiresIntParameter()

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

Definition at line 4664 of file xlogrecovery.c.

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

Referenced by CheckRequiredParameterValues().

◆ RemovePromoteSignalFiles()

void RemovePromoteSignalFiles ( void  )
extern

Definition at line 4459 of file xlogrecovery.c.

4460{
4462}

References fb(), and PROMOTE_SIGNAL_FILE.

Referenced by CheckForStandbyTrigger(), and PostmasterMain().

◆ SetRecoveryPause()

◆ ShutdownWalRecovery()

void ShutdownWalRecovery ( void  )
extern

Definition at line 1566 of file xlogrecovery.c.

1567{
1568 char recoveryPath[MAXPGPATH];
1569
1570 /* Final update of pg_stat_recovery_prefetch. */
1572
1573 /* Shut down xlogreader */
1574 if (readFile >= 0)
1575 {
1576 close(readFile);
1577 readFile = -1;
1578 }
1582
1584 {
1585 /*
1586 * Since there might be a partial WAL segment named RECOVERYXLOG, get
1587 * rid of it.
1588 */
1589 snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYXLOG");
1590 unlink(recoveryPath); /* ignore any error */
1591
1592 /* Get rid of any remaining recovered timeline-history file, too */
1593 snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYHISTORY");
1594 unlink(recoveryPath); /* ignore any error */
1595 }
1596
1597 /*
1598 * We don't need the latch anymore. It's not strictly necessary to disown
1599 * it, but let's do it for the sake of tidiness.
1600 */
1603}
void DisownLatch(Latch *latch)
Definition latch.c:144
#define MAXPGPATH
#define snprintf
Definition port.h:260
void * private_data
Definition xlogreader.h:195
#define XLOGDIR
void XLogPrefetcherComputeStats(XLogPrefetcher *prefetcher)
void XLogPrefetcherFree(XLogPrefetcher *prefetcher)
void XLogReaderFree(XLogReaderState *state)
Definition xlogreader.c:163

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

Referenced by StartupXLOG().

◆ StartupRequestWalReceiverRestart()

void StartupRequestWalReceiverRestart ( void  )
extern

Definition at line 4380 of file xlogrecovery.c.

4381{
4383 {
4384 ereport(LOG,
4385 (errmsg("WAL receiver process shutdown requested")));
4386
4387 pendingWalRcvRestart = true;
4388 }
4389}
bool WalRcvRunning(void)
static bool pendingWalRcvRestart
static XLogSource currentSource

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

Referenced by StartupRereadConfig().

◆ WakeupRecovery()

◆ xlog_outdesc()

void xlog_outdesc ( StringInfo  buf,
XLogReaderState record 
)
extern

Definition at line 2270 of file xlogrecovery.c.

2271{
2273 uint8 info = XLogRecGetInfo(record);
2274 const char *id;
2275
2278
2279 id = rmgr.rm_identify(info);
2280 if (id == NULL)
2281 appendStringInfo(buf, "UNKNOWN (%X): ", info & ~XLR_INFO_MASK);
2282 else
2283 appendStringInfo(buf, "%s: ", id);
2284
2285 rmgr.rm_desc(buf, record);
2286}
uint8_t uint8
Definition c.h:616
void appendStringInfoChar(StringInfo str, char ch)
Definition stringinfo.c:242
static RmgrData GetRmgr(RmgrId rmid)
#define XLogRecGetInfo(decoder)
Definition xlogreader.h:409
#define XLogRecGetRmid(decoder)
Definition xlogreader.h:410

References appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), buf, fb(), GetRmgr(), XLogRecGetInfo, XLogRecGetRmid, and XLR_INFO_MASK.

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

◆ XLogRecoveryShmemInit()

void XLogRecoveryShmemInit ( void  )
extern

Definition at line 402 of file xlogrecovery.c.

403{
404 bool found;
405
407 ShmemInitStruct("XLOG Recovery Ctl", XLogRecoveryShmemSize(), &found);
408 if (found)
409 return;
411
415}
void ConditionVariableInit(ConditionVariable *cv)
void InitSharedLatch(Latch *latch)
Definition latch.c:93
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition shmem.c:381
static void SpinLockInit(volatile slock_t *lock)
Definition spin.h:50
Size XLogRecoveryShmemSize(void)

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

Referenced by CreateOrAttachShmemStructs().

◆ XLogRecoveryShmemSize()

Size XLogRecoveryShmemSize ( void  )
extern

Definition at line 391 of file xlogrecovery.c.

392{
393 Size size;
394
395 /* XLogRecoveryCtl */
396 size = sizeof(XLogRecoveryCtlData);
397
398 return size;
399}
size_t Size
Definition c.h:691

Referenced by CalculateShmemSize(), and XLogRecoveryShmemInit().

◆ XLogRequestWalReceiverReply()

void XLogRequestWalReceiverReply ( void  )
extern

Definition at line 4492 of file xlogrecovery.c.

4493{
4495}
static bool doRequestWalReceiverReply

References doRequestWalReceiverReply.

Referenced by xact_redo_commit().

Variable Documentation

◆ archiveCleanupCommand

PGDLLIMPORT char* archiveCleanupCommand
extern

Definition at line 87 of file xlogrecovery.c.

Referenced by CreateRestartPoint().

◆ PrimaryConnInfo

PGDLLIMPORT char* PrimaryConnInfo
extern

Definition at line 99 of file xlogrecovery.c.

◆ PrimarySlotName

PGDLLIMPORT char* PrimarySlotName
extern

Definition at line 100 of file xlogrecovery.c.

◆ reachedConsistency

◆ recovery_min_apply_delay

PGDLLIMPORT int recovery_min_apply_delay
extern

Definition at line 96 of file xlogrecovery.c.

Referenced by recoveryApplyDelay().

◆ recovery_target_time_string

PGDLLIMPORT char* recovery_target_time_string
extern

Definition at line 92 of file xlogrecovery.c.

Referenced by validateRecoveryParameters().

◆ recoveryEndCommand

PGDLLIMPORT char* recoveryEndCommand
extern

Definition at line 86 of file xlogrecovery.c.

Referenced by CleanupAfterArchiveRecovery().

◆ recoveryRestoreCommand

PGDLLIMPORT char* recoveryRestoreCommand
extern

Definition at line 85 of file xlogrecovery.c.

Referenced by RestoreArchivedFile(), and validateRecoveryParameters().

◆ recoveryTarget

◆ recoveryTargetAction

PGDLLIMPORT int recoveryTargetAction
extern

Definition at line 90 of file xlogrecovery.c.

Referenced by PerformWalRecovery(), and validateRecoveryParameters().

◆ recoveryTargetInclusive

PGDLLIMPORT bool recoveryTargetInclusive
extern

Definition at line 89 of file xlogrecovery.c.

Referenced by recoveryStopsAfter(), and recoveryStopsBefore().

◆ recoveryTargetLSN

PGDLLIMPORT XLogRecPtr recoveryTargetLSN
extern

◆ recoveryTargetName

PGDLLIMPORT const char* recoveryTargetName
extern

Definition at line 94 of file xlogrecovery.c.

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

◆ recoveryTargetTime

PGDLLIMPORT TimestampTz recoveryTargetTime
extern

Definition at line 93 of file xlogrecovery.c.

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

◆ recoveryTargetTimeLineGoal

◆ recoveryTargetTLI

◆ recoveryTargetTLIRequested

PGDLLIMPORT TimeLineID recoveryTargetTLIRequested
extern

Definition at line 124 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 101 of file xlogrecovery.c.

Referenced by StartupRereadConfig(), and WaitForWALToBecomeAvailable().

◆ XLogRecoveryCtl