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

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

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

References fb(), PROMOTE_SIGNAL_FILE, and stat.

Referenced by CheckForStandbyTrigger(), and process_pm_pmsignal().

◆ FinishWalRecovery()

EndOfWalRecoveryInfo * FinishWalRecovery ( void  )
extern

Definition at line 1417 of file xlogrecovery.c.

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

4633{
4635
4639
4640 return xtime;
4641}
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 4648 of file xlogrecovery.c.

4649{
4650 /*
4651 * This must be executed in the startup process, since we don't export the
4652 * relevant state to shared memory.
4653 */
4655
4658}
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 4508 of file xlogrecovery.c.

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

459{
460 XLogPageReadPrivate *private;
461 struct stat st;
462 bool wasShutdown;
463 XLogRecord *record;
465 bool haveTblspcMap = false;
466 bool haveBackupLabel = false;
467 CheckPoint checkPoint;
468 bool backupFromStandby = false;
469
471
472 /*
473 * Initialize on the assumption we want to recover to the latest timeline
474 * that's active according to pg_control.
475 */
479 else
481
482 /*
483 * Check for signal files, and if so set up state for offline recovery
484 */
487
488 /*
489 * Take ownership of the wakeup latch if we're going to sleep during
490 * recovery, if required.
491 */
494
495 /*
496 * Set the WAL reading processor now, as it will be needed when reading
497 * the checkpoint record required (backup_label or not).
498 */
500 xlogreader =
502 XL_ROUTINE(.page_read = &XLogPageRead,
503 .segment_open = NULL,
504 .segment_close = wal_segment_close),
505 private);
506 if (!xlogreader)
509 errmsg("out of memory"),
510 errdetail("Failed while allocating a WAL reading processor.")));
512
513 /*
514 * Set the WAL decode buffer size. This limits how far ahead we can read
515 * in the WAL.
516 */
518
519 /* Create a WAL prefetcher. */
521
522 /*
523 * Allocate two page buffers dedicated to WAL consistency checks. We do
524 * it this way, rather than just making static arrays, for two reasons:
525 * (1) no need to waste the storage in most instantiations of the backend;
526 * (2) a static char array isn't guaranteed to have any particular
527 * alignment, whereas palloc() will provide MAXALIGN'd storage.
528 */
531
532 /*
533 * Read the backup_label file. We want to run this part of the recovery
534 * process after checking for signal files and after performing validation
535 * of the recovery parameters.
536 */
539 {
540 List *tablespaces = NIL;
541
542 /*
543 * Archive recovery was requested, and thanks to the backup label
544 * file, we know how far we need to replay to reach consistency. Enter
545 * archive recovery directly.
546 */
547 InArchiveRecovery = true;
550
551 /*
552 * Omitting backup_label when creating a new replica, PITR node etc.
553 * unfortunately is a common cause of corruption. Logging that
554 * backup_label was used makes it a bit easier to exclude that as the
555 * cause of observed corruption.
556 *
557 * Do so before we try to read the checkpoint record (which can fail),
558 * as otherwise it can be hard to understand why a checkpoint other
559 * than ControlFile->checkPoint is used.
560 */
561 ereport(LOG,
562 errmsg("starting backup recovery with redo LSN %X/%08X, checkpoint LSN %X/%08X, on timeline ID %u",
566
567 /*
568 * When a backup_label file is present, we want to roll forward from
569 * the checkpoint it identifies, rather than using pg_control.
570 */
573 if (record != NULL)
574 {
575 memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
578 errmsg_internal("checkpoint record is at %X/%08X",
580 InRecovery = true; /* force recovery even if SHUTDOWNED */
581
582 /*
583 * Make sure that REDO location exists. This may not be the case
584 * if there was a crash during an online backup, which left a
585 * backup_label around that references a WAL segment that's
586 * already been archived.
587 */
588 if (checkPoint.redo < CheckPointLoc)
589 {
591 if (!ReadRecord(xlogprefetcher, LOG, false,
592 checkPoint.ThisTimeLineID))
594 errmsg("could not find redo location %X/%08X referenced by checkpoint record at %X/%08X",
596 errhint("If you are restoring from a backup, touch \"%s/recovery.signal\" or \"%s/standby.signal\" and add required recovery options.\n"
597 "If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n"
598 "Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup.",
600 }
601 }
602 else
603 {
605 errmsg("could not locate required checkpoint record at %X/%08X",
607 errhint("If you are restoring from a backup, touch \"%s/recovery.signal\" or \"%s/standby.signal\" and add required recovery options.\n"
608 "If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n"
609 "Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup.",
611 wasShutdown = false; /* keep compiler quiet */
612 }
613
614 /* Read the tablespace_map file if present and create symlinks. */
615 if (read_tablespace_map(&tablespaces))
616 {
617 ListCell *lc;
618
619 foreach(lc, tablespaces)
620 {
622 char *linkloc;
623
624 linkloc = psprintf("%s/%u", PG_TBLSPC_DIR, ti->oid);
625
626 /*
627 * Remove the existing symlink if any and Create the symlink
628 * under PGDATA.
629 */
631
632 if (symlink(ti->path, linkloc) < 0)
635 errmsg("could not create symbolic link \"%s\": %m",
636 linkloc)));
637
638 pfree(ti->path);
639 pfree(ti);
640 }
641
642 /* tell the caller to delete it later */
643 haveTblspcMap = true;
644 }
645
646 /* tell the caller to delete it later */
647 haveBackupLabel = true;
648 }
649 else
650 {
651 /* No backup_label file has been found if we are here. */
652
653 /*
654 * If tablespace_map file is present without backup_label file, there
655 * is no use of such file. There is no harm in retaining it, but it
656 * is better to get rid of the map file so that we don't have any
657 * redundant file in data directory and it will avoid any sort of
658 * confusion. It seems prudent though to just rename the file out of
659 * the way rather than delete it completely, also we ignore any error
660 * that occurs in rename operation as even if map file is present
661 * without backup_label file, it is harmless.
662 */
663 if (stat(TABLESPACE_MAP, &st) == 0)
664 {
667 ereport(LOG,
668 (errmsg("ignoring file \"%s\" because no file \"%s\" exists",
670 errdetail("File \"%s\" was renamed to \"%s\".",
672 else
673 ereport(LOG,
674 (errmsg("ignoring file \"%s\" because no file \"%s\" exists",
676 errdetail("Could not rename file \"%s\" to \"%s\": %m.",
678 }
679
680 /*
681 * It's possible that archive recovery was requested, but we don't
682 * know how far we need to replay the WAL before we reach consistency.
683 * This can happen for example if a base backup is taken from a
684 * running server using an atomic filesystem snapshot, without calling
685 * pg_backup_start/stop. Or if you just kill a running primary server
686 * and put it into archive recovery by creating a recovery signal
687 * file.
688 *
689 * Our strategy in that case is to perform crash recovery first,
690 * replaying all the WAL present in pg_wal, and only enter archive
691 * recovery after that.
692 *
693 * But usually we already know how far we need to replay the WAL (up
694 * to minRecoveryPoint, up to backupEndPoint, or until we see an
695 * end-of-backup record), and we can enter archive recovery directly.
696 */
702 {
703 InArchiveRecovery = true;
706 }
707
708 /*
709 * For the same reason as when starting up with backup_label present,
710 * emit a log message when we continue initializing from a base
711 * backup.
712 */
714 ereport(LOG,
715 errmsg("restarting backup recovery with redo LSN %X/%08X",
717
718 /* Get the last valid checkpoint record. */
725 if (record != NULL)
726 {
728 errmsg_internal("checkpoint record is at %X/%08X",
730 }
731 else
732 {
733 /*
734 * We used to attempt to go back to a secondary checkpoint record
735 * here, but only when not in standby mode. We now just fail if we
736 * can't read the last checkpoint because this allows us to
737 * simplify processing around checkpoints.
738 */
740 errmsg("could not locate a valid checkpoint record at %X/%08X",
742 }
743 memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
745
746 /* Make sure that REDO location exists. */
747 if (checkPoint.redo < CheckPointLoc)
748 {
750 if (!ReadRecord(xlogprefetcher, LOG, false, checkPoint.ThisTimeLineID))
752 errmsg("could not find redo location %X/%08X referenced by checkpoint record at %X/%08X",
754 }
755 }
756
758 {
760 ereport(LOG,
761 (errmsg("entering standby mode")));
763 ereport(LOG,
764 (errmsg("starting point-in-time recovery to XID %u",
767 ereport(LOG,
768 (errmsg("starting point-in-time recovery to %s",
771 ereport(LOG,
772 (errmsg("starting point-in-time recovery to \"%s\"",
775 ereport(LOG,
776 errmsg("starting point-in-time recovery to WAL location (LSN) \"%X/%08X\"",
779 ereport(LOG,
780 (errmsg("starting point-in-time recovery to earliest consistent point")));
781 else
782 ereport(LOG,
783 (errmsg("starting archive recovery")));
784 }
785
786 /*
787 * If the location of the checkpoint record is not on the expected
788 * timeline in the history of the requested timeline, we cannot proceed:
789 * the backup is not part of the history of the requested timeline.
790 */
791 Assert(expectedTLEs); /* was initialized by reading checkpoint
792 * record */
795 {
797
798 /*
799 * tliSwitchPoint will throw an error if the checkpoint's timeline is
800 * not in expectedTLEs at all.
801 */
804 (errmsg("requested timeline %u is not a child of this server's history",
806 /* translator: %s is a backup_label file or a pg_control file */
807 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.",
808 haveBackupLabel ? "backup_label" : "pg_control",
812 }
813
814 /*
815 * The min recovery point should be part of the requested timeline's
816 * history, too.
817 */
822 errmsg("requested timeline %u does not contain minimum recovery point %X/%08X on timeline %u",
826
828 errmsg_internal("redo record is at %X/%08X; shutdown %s",
829 LSN_FORMAT_ARGS(checkPoint.redo),
830 wasShutdown ? "true" : "false"));
832 (errmsg_internal("next transaction ID: " UINT64_FORMAT "; next OID: %u",
834 checkPoint.nextOid)));
836 (errmsg_internal("next MultiXactId: %u; next MultiXactOffset: %" PRIu64,
837 checkPoint.nextMulti, checkPoint.nextMultiOffset)));
839 (errmsg_internal("oldest unfrozen transaction ID: %u, in database %u",
840 checkPoint.oldestXid, checkPoint.oldestXidDB)));
842 (errmsg_internal("oldest MultiXactId: %u, in database %u",
843 checkPoint.oldestMulti, checkPoint.oldestMultiDB)));
845 (errmsg_internal("commit timestamp Xid oldest/newest: %u/%u",
846 checkPoint.oldestCommitTsXid,
847 checkPoint.newestCommitTsXid)));
850 (errmsg("invalid next transaction ID")));
851
852 /* sanity check */
853 if (checkPoint.redo > CheckPointLoc)
855 (errmsg("invalid redo in checkpoint record")));
856
857 /*
858 * Check whether we need to force recovery from WAL. If it appears to
859 * have been a clean shutdown and we did not have a recovery signal file,
860 * then assume no recovery needed.
861 */
862 if (checkPoint.redo < CheckPointLoc)
863 {
864 if (wasShutdown)
866 (errmsg("invalid redo record in shutdown checkpoint")));
867 InRecovery = true;
868 }
869 else if (ControlFile->state != DB_SHUTDOWNED)
870 InRecovery = true;
872 {
873 /* force recovery due to presence of recovery signal file */
874 InRecovery = true;
875 }
876
877 /*
878 * If recovery is needed, update our in-memory copy of pg_control to show
879 * that we are recovering and to show the selected checkpoint as the place
880 * we are starting from. We also mark pg_control with any minimum recovery
881 * stop point obtained from a backup history file.
882 *
883 * We don't write the changes to disk yet, though. Only do that after
884 * initializing various subsystems.
885 */
886 if (InRecovery)
887 {
889 {
891 }
892 else
893 {
894 ereport(LOG,
895 (errmsg("database system was not properly shut down; "
896 "automatic recovery in progress")));
898 ereport(LOG,
899 (errmsg("crash recovery starts in timeline %u "
900 "and has target timeline %u",
904 }
906 ControlFile->checkPointCopy = checkPoint;
908 {
909 /* initialize minRecoveryPoint if not set yet */
910 if (ControlFile->minRecoveryPoint < checkPoint.redo)
911 {
912 ControlFile->minRecoveryPoint = checkPoint.redo;
914 }
915 }
916
917 /*
918 * Set backupStartPoint if we're starting recovery from a base backup.
919 *
920 * Also set backupEndPoint and use minRecoveryPoint as the backup end
921 * location if we're starting recovery from a base backup which was
922 * taken from a standby. In this case, the database system status in
923 * pg_control must indicate that the database was already in recovery.
924 * Usually that will be DB_IN_ARCHIVE_RECOVERY but also can be
925 * DB_SHUTDOWNED_IN_RECOVERY if recovery previously was interrupted
926 * before reaching this point; e.g. because restore_command or
927 * primary_conninfo were faulty.
928 *
929 * Any other state indicates that the backup somehow became corrupted
930 * and we can't sensibly continue with recovery.
931 */
932 if (haveBackupLabel)
933 {
934 ControlFile->backupStartPoint = checkPoint.redo;
936
938 {
942 (errmsg("backup_label contains data inconsistent with control file"),
943 errhint("This means that the backup is corrupted and you will "
944 "have to use another backup for recovery.")));
946 }
947 }
948 }
949
950 /* remember these, so that we know when we have reached consistency */
955 {
958 }
959 else
960 {
963 }
964
965 /*
966 * Start recovery assuming that the final record isn't lost.
967 */
970
974}
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:891
const char * timestamptz_to_str(TimestampTz t)
Definition timestamp.c:1856
#define UINT64_FORMAT
Definition c.h:635
int errcode_for_file_access(void)
Definition elog.c:897
int errcode(int sqlerrcode)
Definition elog.c:874
#define LOG
Definition elog.h:32
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define FATAL
Definition elog.h:42
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define DEBUG1
Definition elog.h:31
#define ERROR
Definition elog.h:40
#define ereport(elevel,...)
Definition elog.h:152
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:73
void OwnLatch(Latch *latch)
Definition latch.c:126
void pfree(void *pointer)
Definition mcxt.c:1616
static char * errmsg
DBState
Definition pg_control.h:98
@ DB_IN_ARCHIVE_RECOVERY
Definition pg_control.h:104
@ DB_SHUTDOWNED_IN_RECOVERY
Definition pg_control.h:101
@ DB_SHUTDOWNED
Definition pg_control.h:100
@ DB_IN_CRASH_RECOVERY
Definition pg_control.h:103
#define XLOG_CHECKPOINT_SHUTDOWN
Definition pg_control.h:72
#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:178
CheckPoint checkPointCopy
Definition pg_control.h:143
XLogRecPtr backupEndPoint
Definition pg_control.h:179
XLogRecPtr minRecoveryPoint
Definition pg_control.h:176
XLogRecPtr checkPoint
Definition pg_control.h:141
uint64 system_identifier
Definition pg_control.h:118
TimeLineID minRecoveryPointTLI
Definition pg_control.h:177
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:143
static ControlFileData * ControlFile
Definition xlog.c:584
#define TABLESPACE_MAP_OLD
Definition xlog.h:336
#define TABLESPACE_MAP
Definition xlog.h:335
#define BACKUP_LABEL_FILE
Definition xlog.h:332
#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:415
#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, memcpy(), 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 1612 of file xlogrecovery.c.

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

4401{
4402 /*
4403 * We check shared state each time only until a standby promotion is
4404 * triggered. We can't trigger a promotion again, so there's no need to
4405 * keep checking after the shared variable has once been seen true.
4406 */
4408 return true;
4409
4413
4415}
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 4665 of file xlogrecovery.c.

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

4461{
4463}

References fb(), and PROMOTE_SIGNAL_FILE.

Referenced by CheckForStandbyTrigger(), and PostmasterMain().

◆ SetRecoveryPause()

◆ ShutdownWalRecovery()

void ShutdownWalRecovery ( void  )
extern

Definition at line 1567 of file xlogrecovery.c.

1568{
1569 char recoveryPath[MAXPGPATH];
1570
1571 /* Final update of pg_stat_recovery_prefetch. */
1573
1574 /* Shut down xlogreader */
1575 if (readFile >= 0)
1576 {
1577 close(readFile);
1578 readFile = -1;
1579 }
1583
1585 {
1586 /*
1587 * Since there might be a partial WAL segment named RECOVERYXLOG, get
1588 * rid of it.
1589 */
1590 snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYXLOG");
1591 unlink(recoveryPath); /* ignore any error */
1592
1593 /* Get rid of any remaining recovered timeline-history file, too */
1594 snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYHISTORY");
1595 unlink(recoveryPath); /* ignore any error */
1596 }
1597
1598 /*
1599 * We don't need the latch anymore. It's not strictly necessary to disown
1600 * it, but let's do it for the sake of tidiness.
1601 */
1604}
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 4381 of file xlogrecovery.c.

4382{
4384 {
4385 ereport(LOG,
4386 (errmsg("WAL receiver process shutdown requested")));
4387
4388 pendingWalRcvRestart = true;
4389 }
4390}
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 2271 of file xlogrecovery.c.

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

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

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

◆ XLogRequestWalReceiverReply()

void XLogRequestWalReceiverReply ( void  )
extern

Definition at line 4493 of file xlogrecovery.c.

4494{
4496}
static bool doRequestWalReceiverReply

References doRequestWalReceiverReply.

Referenced by xact_redo_commit().

Variable Documentation

◆ archiveCleanupCommand

PGDLLIMPORT char* archiveCleanupCommand
extern

Definition at line 88 of file xlogrecovery.c.

Referenced by CreateRestartPoint().

◆ PrimaryConnInfo

PGDLLIMPORT char* PrimaryConnInfo
extern

Definition at line 100 of file xlogrecovery.c.

◆ PrimarySlotName

PGDLLIMPORT char* PrimarySlotName
extern

Definition at line 101 of file xlogrecovery.c.

◆ reachedConsistency

◆ recovery_min_apply_delay

PGDLLIMPORT int recovery_min_apply_delay
extern

Definition at line 97 of file xlogrecovery.c.

Referenced by recoveryApplyDelay().

◆ recovery_target_time_string

PGDLLIMPORT char* recovery_target_time_string
extern

Definition at line 93 of file xlogrecovery.c.

Referenced by validateRecoveryParameters().

◆ recoveryEndCommand

PGDLLIMPORT char* recoveryEndCommand
extern

Definition at line 87 of file xlogrecovery.c.

Referenced by CleanupAfterArchiveRecovery().

◆ recoveryRestoreCommand

PGDLLIMPORT char* recoveryRestoreCommand
extern

Definition at line 86 of file xlogrecovery.c.

Referenced by RestoreArchivedFile(), and validateRecoveryParameters().

◆ recoveryTarget

◆ recoveryTargetAction

PGDLLIMPORT int recoveryTargetAction
extern

Definition at line 91 of file xlogrecovery.c.

Referenced by PerformWalRecovery(), and validateRecoveryParameters().

◆ recoveryTargetInclusive

PGDLLIMPORT bool recoveryTargetInclusive
extern

Definition at line 90 of file xlogrecovery.c.

Referenced by recoveryStopsAfter(), and recoveryStopsBefore().

◆ recoveryTargetLSN

PGDLLIMPORT XLogRecPtr recoveryTargetLSN
extern

◆ recoveryTargetName

PGDLLIMPORT const char* recoveryTargetName
extern

Definition at line 95 of file xlogrecovery.c.

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

◆ recoveryTargetTime

PGDLLIMPORT TimestampTz recoveryTargetTime
extern

Definition at line 94 of file xlogrecovery.c.

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

◆ recoveryTargetTimeLineGoal

◆ recoveryTargetTLI

◆ recoveryTargetTLIRequested

PGDLLIMPORT TimeLineID recoveryTargetTLIRequested
extern

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

Referenced by StartupRereadConfig(), and WaitForWALToBecomeAvailable().

◆ XLogRecoveryCtl