Coverage Report

Created: 2026-11-12 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/postgres/src/backend/access/transam/xlogrecovery.c
Line
Count
Source
1
/*-------------------------------------------------------------------------
2
 *
3
 * xlogrecovery.c
4
 *    Functions for WAL recovery, standby mode
5
 *
6
 * This source file contains functions controlling WAL recovery.
7
 * InitWalRecovery() initializes the system for crash or archive recovery,
8
 * or standby mode, depending on configuration options and the state of
9
 * the control file and possible backup label file.  PerformWalRecovery()
10
 * performs the actual WAL replay, calling the rmgr-specific redo routines.
11
 * FinishWalRecovery() performs end-of-recovery checks and cleanup actions,
12
 * and prepares information needed to initialize the WAL for writes.  In
13
 * addition to these three main functions, there are a bunch of functions
14
 * for interrogating recovery state and controlling the recovery process.
15
 *
16
 *
17
 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
18
 * Portions Copyright (c) 1994, Regents of the University of California
19
 *
20
 * src/backend/access/transam/xlogrecovery.c
21
 *
22
 *-------------------------------------------------------------------------
23
 */
24
25
#include "postgres.h"
26
27
#include <ctype.h>
28
#include <time.h>
29
#include <sys/stat.h>
30
#include <sys/time.h>
31
#include <unistd.h>
32
33
#include "access/timeline.h"
34
#include "access/transam.h"
35
#include "access/xact.h"
36
#include "access/xlog_internal.h"
37
#include "access/xlogarchive.h"
38
#include "access/xlogprefetcher.h"
39
#include "access/xlogreader.h"
40
#include "access/xlogrecovery.h"
41
#include "access/xlogutils.h"
42
#include "access/xlogwait.h"
43
#include "backup/basebackup.h"
44
#include "catalog/pg_control.h"
45
#include "commands/tablespace.h"
46
#include "common/file_utils.h"
47
#include "common/pg_parse_lsn.h"
48
#include "miscadmin.h"
49
#include "nodes/miscnodes.h"
50
#include "pgstat.h"
51
#include "postmaster/bgwriter.h"
52
#include "postmaster/startup.h"
53
#include "replication/slot.h"
54
#include "replication/slotsync.h"
55
#include "replication/walreceiver.h"
56
#include "storage/fd.h"
57
#include "storage/ipc.h"
58
#include "storage/latch.h"
59
#include "storage/pmsignal.h"
60
#include "storage/procarray.h"
61
#include "storage/spin.h"
62
#include "storage/subsystems.h"
63
#include "utils/datetime.h"
64
#include "utils/fmgrprotos.h"
65
#include "utils/guc.h"
66
#include "utils/guc_hooks.h"
67
#include "utils/pgstat_internal.h"
68
#include "utils/pg_lsn.h"
69
#include "utils/ps_status.h"
70
#include "utils/pg_rusage.h"
71
#include "utils/wait_event.h"
72
73
/* Unsupported old recovery command file names (relative to $PGDATA) */
74
0
#define RECOVERY_COMMAND_FILE "recovery.conf"
75
0
#define RECOVERY_COMMAND_DONE "recovery.done"
76
77
/*
78
 * GUC support
79
 */
80
const struct config_enum_entry recovery_target_action_options[] = {
81
  {"pause", RECOVERY_TARGET_ACTION_PAUSE, false},
82
  {"promote", RECOVERY_TARGET_ACTION_PROMOTE, false},
83
  {"shutdown", RECOVERY_TARGET_ACTION_SHUTDOWN, false},
84
  {NULL, 0, false}
85
};
86
87
/* options formerly taken from recovery.conf for archive recovery */
88
char     *recoveryRestoreCommand = NULL;
89
char     *recoveryEndCommand = NULL;
90
char     *archiveCleanupCommand = NULL;
91
RecoveryTargetType recoveryTarget = RECOVERY_TARGET_UNSET;
92
bool    recoveryTargetInclusive = true;
93
int     recoveryTargetAction = RECOVERY_TARGET_ACTION_PAUSE;
94
TransactionId recoveryTargetXid;
95
char     *recovery_target_time_string;
96
TimestampTz recoveryTargetTime;
97
char     *recoveryTargetName;
98
XLogRecPtr  recoveryTargetLSN;
99
int     recovery_min_apply_delay = 0;
100
101
/* options formerly taken from recovery.conf for XLOG streaming */
102
char     *PrimaryConnInfo = NULL;
103
char     *PrimarySlotName = NULL;
104
bool    wal_receiver_create_temp_slot = false;
105
106
/*
107
 * recoveryTargetTimeLineGoal: what the user requested, if any
108
 *
109
 * recoveryTargetTLIRequested: numeric value of requested timeline, if constant
110
 *
111
 * recoveryTargetTLI: the currently understood target timeline; changes
112
 *
113
 * expectedTLEs: a list of TimeLineHistoryEntries for recoveryTargetTLI and
114
 * the timelines of its known parents, newest first (so recoveryTargetTLI is
115
 * always the first list member).  Only these TLIs are expected to be seen in
116
 * the WAL segments we read, and indeed only these TLIs will be considered as
117
 * candidate WAL files to open at all.
118
 *
119
 * curFileTLI: the TLI appearing in the name of the current input WAL file.
120
 * (This is not necessarily the same as the timeline from which we are
121
 * replaying WAL, which StartupXLOG calls replayTLI, because we could be
122
 * scanning data that was copied from an ancestor timeline when the current
123
 * file was created.)  During a sequential scan we do not allow this value
124
 * to decrease.
125
 */
126
RecoveryTargetTimeLineGoal recoveryTargetTimeLineGoal = RECOVERY_TARGET_TIMELINE_LATEST;
127
TimeLineID  recoveryTargetTLIRequested = 0;
128
TimeLineID  recoveryTargetTLI = 0;
129
static List *expectedTLEs;
130
static TimeLineID curFileTLI;
131
132
/*
133
 * When ArchiveRecoveryRequested is set, archive recovery was requested,
134
 * ie. signal files were present.  When InArchiveRecovery is set, we are
135
 * currently recovering using offline XLOG archives.  These variables are only
136
 * valid in the startup process.
137
 *
138
 * When ArchiveRecoveryRequested is true, but InArchiveRecovery is false, we're
139
 * currently performing crash recovery using only XLOG files in pg_wal, but
140
 * will switch to using offline XLOG archives as soon as we reach the end of
141
 * WAL in pg_wal.
142
 */
143
bool    ArchiveRecoveryRequested = false;
144
bool    InArchiveRecovery = false;
145
146
/*
147
 * When StandbyModeRequested is set, standby mode was requested, i.e.
148
 * standby.signal file was present.  When StandbyMode is set, we are currently
149
 * in standby mode.  These variables are only valid in the startup process.
150
 * They work similarly to ArchiveRecoveryRequested and InArchiveRecovery.
151
 */
152
static bool StandbyModeRequested = false;
153
bool    StandbyMode = false;
154
155
/* was a signal file present at startup? */
156
static bool standby_signal_file_found = false;
157
static bool recovery_signal_file_found = false;
158
159
/*
160
 * CheckPointLoc is the position of the checkpoint record that determines
161
 * where to start the replay.  It comes from the backup label file or the
162
 * control file.
163
 *
164
 * RedoStartLSN is the checkpoint's REDO location, also from the backup label
165
 * file or the control file.  In standby mode, XLOG streaming usually starts
166
 * from the position where an invalid record was found.  But if we fail to
167
 * read even the initial checkpoint record, we use the REDO location instead
168
 * of the checkpoint location as the start position of XLOG streaming.
169
 * Otherwise we would have to jump backwards to the REDO location after
170
 * reading the checkpoint record, because the REDO record can precede the
171
 * checkpoint record.
172
 */
173
static XLogRecPtr CheckPointLoc = InvalidXLogRecPtr;
174
static TimeLineID CheckPointTLI = 0;
175
static XLogRecPtr RedoStartLSN = InvalidXLogRecPtr;
176
static TimeLineID RedoStartTLI = 0;
177
178
/*
179
 * Local copy of SharedHotStandbyActive variable. False actually means "not
180
 * known, need to check the shared state".
181
 */
182
static bool LocalHotStandbyActive = false;
183
184
/*
185
 * Local copy of SharedPromoteIsTriggered variable. False actually means "not
186
 * known, need to check the shared state".
187
 */
188
static bool LocalPromoteIsTriggered = false;
189
190
/* Has the recovery code requested a walreceiver wakeup? */
191
static bool doRequestWalReceiverReply;
192
193
/* XLogReader object used to parse the WAL records */
194
static XLogReaderState *xlogreader = NULL;
195
196
/* XLogPrefetcher object used to consume WAL records with read-ahead */
197
static XLogPrefetcher *xlogprefetcher = NULL;
198
199
/* Parameters passed down from ReadRecord to the XLogPageRead callback. */
200
typedef struct XLogPageReadPrivate
201
{
202
  int     emode;
203
  bool    fetching_ckpt;  /* are we fetching a checkpoint record? */
204
  bool    randAccess;
205
  TimeLineID  replayTLI;
206
} XLogPageReadPrivate;
207
208
/* flag to tell XLogPageRead that we have started replaying */
209
static bool InRedo = false;
210
211
/*
212
 * Codes indicating where we got a WAL file from during recovery, or where
213
 * to attempt to get one.
214
 */
215
typedef enum
216
{
217
  XLOG_FROM_ANY = 0,      /* request to read WAL from any source */
218
  XLOG_FROM_ARCHIVE,      /* restored using restore_command */
219
  XLOG_FROM_PG_WAL,     /* existing file in pg_wal */
220
  XLOG_FROM_STREAM,     /* streamed from primary */
221
} XLogSource;
222
223
/* human-readable names for XLogSources, for debugging output */
224
static const char *const xlogSourceNames[] = {"any", "archive", "pg_wal", "stream"};
225
226
/*
227
 * readFile is -1 or a kernel FD for the log file segment that's currently
228
 * open for reading.  readSegNo identifies the segment.  readOff is the offset
229
 * of the page just read, readLen indicates how much of it has been read into
230
 * readBuf, and readSource indicates where we got the currently open file from.
231
 *
232
 * Note: we could use Reserve/ReleaseExternalFD to track consumption of this
233
 * FD too (like for openLogFile in xlog.c); but it doesn't currently seem
234
 * worthwhile, since the XLOG is not read by general-purpose sessions.
235
 */
236
static int  readFile = -1;
237
static XLogSegNo readSegNo = 0;
238
static uint32 readOff = 0;
239
static uint32 readLen = 0;
240
static XLogSource readSource = XLOG_FROM_ANY;
241
242
/*
243
 * Keeps track of which source we're currently reading from. This is
244
 * different from readSource in that this is always set, even when we don't
245
 * currently have a WAL file open. If lastSourceFailed is set, our last
246
 * attempt to read from currentSource failed, and we should try another source
247
 * next.
248
 *
249
 * pendingWalRcvRestart is set when a config change occurs that requires a
250
 * walreceiver restart.  This is only valid in XLOG_FROM_STREAM state.
251
 */
252
static XLogSource currentSource = XLOG_FROM_ANY;
253
static bool lastSourceFailed = false;
254
static bool pendingWalRcvRestart = false;
255
256
/*
257
 * These variables track when we last obtained some WAL data to process,
258
 * and where we got it from.  (XLogReceiptSource is initially the same as
259
 * readSource, but readSource gets reset to zero when we don't have data
260
 * to process right now.  It is also different from currentSource, which
261
 * also changes when we try to read from a source and fail, while
262
 * XLogReceiptSource tracks where we last successfully read some WAL.)
263
 */
264
static TimestampTz XLogReceiptTime = 0;
265
static XLogSource XLogReceiptSource = XLOG_FROM_ANY;
266
267
/* Local copy of WalRcv->flushedUpto */
268
static XLogRecPtr flushedUpto = InvalidXLogRecPtr;
269
static TimeLineID receiveTLI = 0;
270
271
/*
272
 * Copy of minRecoveryPoint and backupEndPoint from the control file.
273
 *
274
 * In order to reach consistency, we must replay the WAL up to
275
 * minRecoveryPoint.  If backupEndRequired is true, we must also reach
276
 * backupEndPoint, or if it's invalid, an end-of-backup record corresponding
277
 * to backupStartPoint.
278
 *
279
 * Note: In archive recovery, after consistency has been reached, the
280
 * functions in xlog.c will start updating minRecoveryPoint in the control
281
 * file.  But this copy of minRecoveryPoint variable reflects the value at the
282
 * beginning of recovery, and is *not* updated after consistency is reached.
283
 */
284
static XLogRecPtr minRecoveryPoint;
285
static TimeLineID minRecoveryPointTLI;
286
287
static XLogRecPtr backupStartPoint;
288
static XLogRecPtr backupEndPoint;
289
static bool backupEndRequired = false;
290
291
/*
292
 * Have we reached a consistent database state?  In crash recovery, we have
293
 * to replay all the WAL, so reachedConsistency is never set.  During archive
294
 * recovery, the database is consistent once minRecoveryPoint is reached.
295
 *
296
 * Consistent state means that the system is internally consistent, all
297
 * the WAL has been replayed up to a certain point, and importantly, there
298
 * is no trace of later actions on disk.
299
 *
300
 * This flag is used only by the startup process and postmaster. When
301
 * minRecoveryPoint is reached, the startup process sets it to true and
302
 * sends a PMSIGNAL_RECOVERY_CONSISTENT signal to the postmaster,
303
 * which then sets it to true upon receiving the signal.
304
 */
305
bool    reachedConsistency = false;
306
307
/* Buffers dedicated to consistency checks of size BLCKSZ */
308
static char *replay_image_masked = NULL;
309
static char *primary_image_masked = NULL;
310
311
XLogRecoveryCtlData *XLogRecoveryCtl = NULL;
312
313
static void XLogRecoveryShmemRequest(void *arg);
314
static void XLogRecoveryShmemInit(void *arg);
315
316
const ShmemCallbacks XLogRecoveryShmemCallbacks = {
317
  .request_fn = XLogRecoveryShmemRequest,
318
  .init_fn = XLogRecoveryShmemInit,
319
};
320
321
/*
322
 * abortedRecPtr is the start pointer of a broken record at end of WAL when
323
 * recovery completes; missingContrecPtr is the location of the first
324
 * contrecord that went missing.  See CreateOverwriteContrecordRecord for
325
 * details.
326
 */
327
static XLogRecPtr abortedRecPtr;
328
static XLogRecPtr missingContrecPtr;
329
330
/*
331
 * if recoveryStopsBefore/After returns true, it saves information of the stop
332
 * point here
333
 */
334
static TransactionId recoveryStopXid;
335
static TimestampTz recoveryStopTime;
336
static XLogRecPtr recoveryStopLSN;
337
static char recoveryStopName[MAXFNAMELEN];
338
static bool recoveryStopAfter;
339
340
/* prototypes for local functions */
341
static void ApplyWalRecord(XLogReaderState *xlogreader, XLogRecord *record, TimeLineID *replayTLI);
342
343
static void EnableStandbyMode(void);
344
static void readRecoverySignalFile(void);
345
static void validateRecoveryParameters(void);
346
static bool read_backup_label(XLogRecPtr *checkPointLoc,
347
                TimeLineID *backupLabelTLI,
348
                bool *backupEndRequired, bool *backupFromStandby);
349
static bool read_tablespace_map(List **tablespaces);
350
351
static void xlogrecovery_redo(XLogReaderState *record, TimeLineID replayTLI);
352
static void CheckRecoveryConsistency(void);
353
static void rm_redo_error_callback(void *arg);
354
#ifdef WAL_DEBUG
355
static void xlog_outrec(StringInfo buf, XLogReaderState *record);
356
#endif
357
static void xlog_block_info(StringInfo buf, XLogReaderState *record);
358
static void checkTimeLineSwitch(XLogRecPtr lsn, TimeLineID newTLI,
359
                TimeLineID prevTLI, TimeLineID replayTLI);
360
static bool getRecordTimestamp(XLogReaderState *record, TimestampTz *recordXtime);
361
static void verifyBackupPageConsistency(XLogReaderState *record);
362
363
static bool recoveryStopsBefore(XLogReaderState *record);
364
static bool recoveryStopsAfter(XLogReaderState *record);
365
static char *getRecoveryStopReason(void);
366
static void recoveryPausesHere(bool endOfRecovery);
367
static bool recoveryApplyDelay(XLogReaderState *record);
368
static void ConfirmRecoveryPaused(void);
369
370
static XLogRecord *ReadRecord(XLogPrefetcher *xlogprefetcher,
371
                int emode, bool fetching_ckpt,
372
                TimeLineID replayTLI);
373
374
static int  XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr,
375
             int reqLen, XLogRecPtr targetRecPtr, char *readBuf);
376
static XLogPageReadResult WaitForWALToBecomeAvailable(XLogRecPtr RecPtr,
377
                            bool randAccess,
378
                            bool fetching_ckpt,
379
                            XLogRecPtr tliRecPtr,
380
                            TimeLineID replayTLI,
381
                            XLogRecPtr replayLSN,
382
                            bool nonblocking);
383
static int  emode_for_corrupt_record(int emode, XLogRecPtr RecPtr);
384
static XLogRecord *ReadCheckpointRecord(XLogPrefetcher *xlogprefetcher,
385
                    XLogRecPtr RecPtr, TimeLineID replayTLI);
386
static bool rescanLatestTimeLine(TimeLineID replayTLI, XLogRecPtr replayLSN);
387
static int  XLogFileRead(XLogSegNo segno, TimeLineID tli,
388
             XLogSource source, bool notfoundOk);
389
static int  XLogFileReadAnyTLI(XLogSegNo segno, XLogSource source);
390
391
static bool CheckForStandbyTrigger(void);
392
static void SetPromoteIsTriggered(void);
393
static bool HotStandbyActiveInReplay(void);
394
395
static void SetCurrentChunkStartTime(TimestampTz xtime);
396
static void SetLatestXTime(TimestampTz xtime);
397
static RecoveryTargetType DetermineRecoveryTargetType(void);
398
399
/*
400
 * Register shared memory for WAL recovery
401
 */
402
static void
403
XLogRecoveryShmemRequest(void *arg)
404
0
{
405
0
  ShmemRequestStruct(.name = "XLOG Recovery Ctl",
406
0
             .size = sizeof(XLogRecoveryCtlData),
407
0
             .ptr = (void **) &XLogRecoveryCtl,
408
0
    );
409
0
}
410
411
static void
412
XLogRecoveryShmemInit(void *arg)
413
0
{
414
0
  memset(XLogRecoveryCtl, 0, sizeof(XLogRecoveryCtlData));
415
416
0
  SpinLockInit(&XLogRecoveryCtl->info_lck);
417
0
  InitSharedLatch(&XLogRecoveryCtl->recoveryWakeupLatch);
418
0
  ConditionVariableInit(&XLogRecoveryCtl->recoveryNotPausedCV);
419
0
}
420
421
/*
422
 * A thin wrapper to enable StandbyMode and do other preparatory work as
423
 * needed.
424
 */
425
static void
426
EnableStandbyMode(void)
427
0
{
428
0
  StandbyMode = true;
429
430
  /*
431
   * To avoid server log bloat, we don't report recovery progress in a
432
   * standby as it will always be in recovery unless promoted. We disable
433
   * startup progress timeout in standby mode to avoid calling
434
   * startup_progress_timeout_handler() unnecessarily.
435
   */
436
0
  disable_startup_progress_timeout();
437
0
}
438
439
/*
440
 * Prepare the system for WAL recovery, if needed.
441
 *
442
 * This is called by StartupXLOG() which coordinates the server startup
443
 * sequence.  This function analyzes the control file and the backup label
444
 * file, if any, and figures out whether we need to perform crash recovery or
445
 * archive recovery, and how far we need to replay the WAL to reach a
446
 * consistent state.
447
 *
448
 * This doesn't yet change the on-disk state, except for creating the symlinks
449
 * from table space map file if any, and for fetching WAL files needed to find
450
 * the checkpoint record.  On entry, the caller has already read the control
451
 * file into memory, and passes it as argument.  This function updates it to
452
 * reflect the recovery state, and the caller is expected to write it back to
453
 * disk after initializing other subsystems, but before calling
454
 * PerformWalRecovery().
455
 *
456
 * This initializes some global variables like ArchiveRecoveryRequested, and
457
 * StandbyModeRequested and InRecovery.
458
 */
459
void
460
InitWalRecovery(ControlFileData *ControlFile, bool *wasShutdown_ptr,
461
        bool *haveBackupLabel_ptr, bool *haveTblspcMap_ptr)
462
0
{
463
0
  XLogPageReadPrivate *private;
464
0
  struct stat st;
465
0
  bool    wasShutdown;
466
0
  XLogRecord *record;
467
0
  DBState   dbstate_at_startup;
468
0
  bool    haveTblspcMap = false;
469
0
  bool    haveBackupLabel = false;
470
0
  CheckPoint  checkPoint;
471
0
  bool    backupFromStandby = false;
472
473
0
  dbstate_at_startup = ControlFile->state;
474
475
  /*
476
   * A startup process always starts with an inconsistent database. Set the
477
   * flag accordingly, even if it was inherited from a postmaster that had
478
   * already marked the database as consistent. This keeps the invariant
479
   * local to the startup process without requiring every fork path to clear
480
   * the flag.
481
   */
482
0
  reachedConsistency = false;
483
484
  /*
485
   * Initialize on the assumption we want to recover to the latest timeline
486
   * that's active according to pg_control.
487
   */
488
0
  if (ControlFile->minRecoveryPointTLI >
489
0
    ControlFile->checkPointCopy.ThisTimeLineID)
490
0
    recoveryTargetTLI = ControlFile->minRecoveryPointTLI;
491
0
  else
492
0
    recoveryTargetTLI = ControlFile->checkPointCopy.ThisTimeLineID;
493
494
  /*
495
   * Check for signal files, and if so set up state for offline recovery
496
   */
497
0
  readRecoverySignalFile();
498
0
  validateRecoveryParameters();
499
500
  /*
501
   * Take ownership of the wakeup latch if we're going to sleep during
502
   * recovery, if required.
503
   */
504
0
  if (ArchiveRecoveryRequested)
505
0
    OwnLatch(&XLogRecoveryCtl->recoveryWakeupLatch);
506
507
  /*
508
   * Set the WAL reading processor now, as it will be needed when reading
509
   * the checkpoint record required (backup_label or not).
510
   */
511
0
  private = palloc0_object(XLogPageReadPrivate);
512
0
  xlogreader =
513
0
    XLogReaderAllocate(wal_segment_size, NULL,
514
0
               XL_ROUTINE(.page_read = &XLogPageRead,
515
0
                    .segment_open = NULL,
516
0
                    .segment_close = wal_segment_close),
517
0
               private);
518
0
  if (!xlogreader)
519
0
    ereport(ERROR,
520
0
        (errcode(ERRCODE_OUT_OF_MEMORY),
521
0
         errmsg("out of memory"),
522
0
         errdetail("Failed while allocating a WAL reading processor.")));
523
0
  xlogreader->system_identifier = ControlFile->system_identifier;
524
525
  /*
526
   * Set the WAL decode buffer size.  This limits how far ahead we can read
527
   * in the WAL.
528
   */
529
0
  XLogReaderSetDecodeBuffer(xlogreader, NULL, wal_decode_buffer_size);
530
531
  /* Create a WAL prefetcher. */
532
0
  xlogprefetcher = XLogPrefetcherAllocate(xlogreader);
533
534
  /*
535
   * Allocate two page buffers dedicated to WAL consistency checks.  We do
536
   * it this way, rather than just making static arrays, for two reasons:
537
   * (1) no need to waste the storage in most instantiations of the backend;
538
   * (2) a static char array isn't guaranteed to have any particular
539
   * alignment, whereas palloc() will provide MAXALIGN'd storage.
540
   */
541
0
  replay_image_masked = (char *) palloc(BLCKSZ);
542
0
  primary_image_masked = (char *) palloc(BLCKSZ);
543
544
  /*
545
   * Read the backup_label file.  We want to run this part of the recovery
546
   * process after checking for signal files and after performing validation
547
   * of the recovery parameters.
548
   */
549
0
  if (read_backup_label(&CheckPointLoc, &CheckPointTLI, &backupEndRequired,
550
0
              &backupFromStandby))
551
0
  {
552
0
    List     *tablespaces = NIL;
553
554
    /*
555
     * Archive recovery was requested, and thanks to the backup label
556
     * file, we know how far we need to replay to reach consistency. Enter
557
     * archive recovery directly.
558
     */
559
0
    InArchiveRecovery = true;
560
0
    if (StandbyModeRequested)
561
0
      EnableStandbyMode();
562
563
    /*
564
     * Omitting backup_label when creating a new replica, PITR node etc.
565
     * unfortunately is a common cause of corruption.  Logging that
566
     * backup_label was used makes it a bit easier to exclude that as the
567
     * cause of observed corruption.
568
     *
569
     * Do so before we try to read the checkpoint record (which can fail),
570
     * as otherwise it can be hard to understand why a checkpoint other
571
     * than ControlFile->checkPoint is used.
572
     */
573
0
    ereport(LOG,
574
0
        errmsg("starting backup recovery with redo LSN %X/%08X, checkpoint LSN %X/%08X, on timeline ID %u",
575
0
             LSN_FORMAT_ARGS(RedoStartLSN),
576
0
             LSN_FORMAT_ARGS(CheckPointLoc),
577
0
             CheckPointTLI));
578
579
    /*
580
     * When a backup_label file is present, we want to roll forward from
581
     * the checkpoint it identifies, rather than using pg_control.
582
     */
583
0
    record = ReadCheckpointRecord(xlogprefetcher, CheckPointLoc,
584
0
                    CheckPointTLI);
585
0
    if (record != NULL)
586
0
    {
587
0
      memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
588
0
      wasShutdown = ((record->xl_info & ~XLR_INFO_MASK) == XLOG_CHECKPOINT_SHUTDOWN);
589
0
      ereport(DEBUG1,
590
0
          errmsg_internal("checkpoint record is at %X/%08X",
591
0
                  LSN_FORMAT_ARGS(CheckPointLoc)));
592
0
      InRecovery = true; /* force recovery even if SHUTDOWNED */
593
594
      /*
595
       * Make sure that REDO location exists. This may not be the case
596
       * if there was a crash during an online backup, which left a
597
       * backup_label around that references a WAL segment that's
598
       * already been archived.
599
       */
600
0
      if (checkPoint.redo < CheckPointLoc)
601
0
      {
602
0
        XLogPrefetcherBeginRead(xlogprefetcher, checkPoint.redo);
603
0
        if (!ReadRecord(xlogprefetcher, LOG, false,
604
0
                checkPoint.ThisTimeLineID))
605
0
          ereport(FATAL,
606
0
              errmsg("could not find redo location %X/%08X referenced by checkpoint record at %X/%08X",
607
0
                   LSN_FORMAT_ARGS(checkPoint.redo), LSN_FORMAT_ARGS(CheckPointLoc)),
608
0
              errhint("If you are restoring from a backup, touch \"%s/recovery.signal\" or \"%s/standby.signal\" and add required recovery options.\n"
609
0
                  "If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n"
610
0
                  "Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup.",
611
0
                  DataDir, DataDir, DataDir, DataDir));
612
0
      }
613
0
    }
614
0
    else
615
0
    {
616
0
      ereport(FATAL,
617
0
          errmsg("could not locate required checkpoint record at %X/%08X",
618
0
               LSN_FORMAT_ARGS(CheckPointLoc)),
619
0
          errhint("If you are restoring from a backup, touch \"%s/recovery.signal\" or \"%s/standby.signal\" and add required recovery options.\n"
620
0
              "If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n"
621
0
              "Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup.",
622
0
              DataDir, DataDir, DataDir, DataDir));
623
0
      wasShutdown = false;  /* keep compiler quiet */
624
0
    }
625
626
    /* Read the tablespace_map file if present and create symlinks. */
627
0
    if (read_tablespace_map(&tablespaces))
628
0
    {
629
0
      ListCell   *lc;
630
631
0
      foreach(lc, tablespaces)
632
0
      {
633
0
        tablespaceinfo *ti = lfirst(lc);
634
0
        char     *linkloc;
635
636
0
        linkloc = psprintf("%s/%u", PG_TBLSPC_DIR, ti->oid);
637
638
        /*
639
         * Remove the existing symlink if any and Create the symlink
640
         * under PGDATA.
641
         */
642
0
        remove_tablespace_symlink(linkloc);
643
644
0
        if (symlink(ti->path, linkloc) < 0)
645
0
          ereport(ERROR,
646
0
              (errcode_for_file_access(),
647
0
               errmsg("could not create symbolic link \"%s\": %m",
648
0
                  linkloc)));
649
650
0
        pfree(ti->path);
651
0
        pfree(ti);
652
0
      }
653
654
      /* tell the caller to delete it later */
655
0
      haveTblspcMap = true;
656
0
    }
657
658
    /* tell the caller to delete it later */
659
0
    haveBackupLabel = true;
660
0
  }
661
0
  else
662
0
  {
663
    /* No backup_label file has been found if we are here. */
664
665
    /*
666
     * If tablespace_map file is present without backup_label file, there
667
     * is no use of such file.  There is no harm in retaining it, but it
668
     * is better to get rid of the map file so that we don't have any
669
     * redundant file in data directory and it will avoid any sort of
670
     * confusion.  It seems prudent though to just rename the file out of
671
     * the way rather than delete it completely, also we ignore any error
672
     * that occurs in rename operation as even if map file is present
673
     * without backup_label file, it is harmless.
674
     */
675
0
    if (stat(TABLESPACE_MAP, &st) == 0)
676
0
    {
677
0
      unlink(TABLESPACE_MAP_OLD);
678
0
      if (durable_rename(TABLESPACE_MAP, TABLESPACE_MAP_OLD, DEBUG1) == 0)
679
0
        ereport(LOG,
680
0
            (errmsg("ignoring file \"%s\" because no file \"%s\" exists",
681
0
                TABLESPACE_MAP, BACKUP_LABEL_FILE),
682
0
             errdetail("File \"%s\" was renamed to \"%s\".",
683
0
                   TABLESPACE_MAP, TABLESPACE_MAP_OLD)));
684
0
      else
685
0
        ereport(LOG,
686
0
            (errmsg("ignoring file \"%s\" because no file \"%s\" exists",
687
0
                TABLESPACE_MAP, BACKUP_LABEL_FILE),
688
0
             errdetail("Could not rename file \"%s\" to \"%s\": %m.",
689
0
                   TABLESPACE_MAP, TABLESPACE_MAP_OLD)));
690
0
    }
691
692
    /*
693
     * It's possible that archive recovery was requested, but we don't
694
     * know how far we need to replay the WAL before we reach consistency.
695
     * This can happen for example if a base backup is taken from a
696
     * running server using an atomic filesystem snapshot, without calling
697
     * pg_backup_start/stop. Or if you just kill a running primary server
698
     * and put it into archive recovery by creating a recovery signal
699
     * file.
700
     *
701
     * Our strategy in that case is to perform crash recovery first,
702
     * replaying all the WAL present in pg_wal, and only enter archive
703
     * recovery after that.
704
     *
705
     * But usually we already know how far we need to replay the WAL (up
706
     * to minRecoveryPoint, up to backupEndPoint, or until we see an
707
     * end-of-backup record), and we can enter archive recovery directly.
708
     */
709
0
    if (ArchiveRecoveryRequested &&
710
0
      (XLogRecPtrIsValid(ControlFile->minRecoveryPoint) ||
711
0
       ControlFile->backupEndRequired ||
712
0
       XLogRecPtrIsValid(ControlFile->backupEndPoint) ||
713
0
       ControlFile->state == DB_SHUTDOWNED))
714
0
    {
715
0
      InArchiveRecovery = true;
716
0
      if (StandbyModeRequested)
717
0
        EnableStandbyMode();
718
0
    }
719
720
    /*
721
     * For the same reason as when starting up with backup_label present,
722
     * emit a log message when we continue initializing from a base
723
     * backup.
724
     */
725
0
    if (XLogRecPtrIsValid(ControlFile->backupStartPoint))
726
0
      ereport(LOG,
727
0
          errmsg("restarting backup recovery with redo LSN %X/%08X",
728
0
               LSN_FORMAT_ARGS(ControlFile->backupStartPoint)));
729
730
    /* Get the last valid checkpoint record. */
731
0
    CheckPointLoc = ControlFile->checkPoint;
732
0
    CheckPointTLI = ControlFile->checkPointCopy.ThisTimeLineID;
733
0
    RedoStartLSN = ControlFile->checkPointCopy.redo;
734
0
    RedoStartTLI = ControlFile->checkPointCopy.ThisTimeLineID;
735
0
    record = ReadCheckpointRecord(xlogprefetcher, CheckPointLoc,
736
0
                    CheckPointTLI);
737
0
    if (record != NULL)
738
0
    {
739
0
      ereport(DEBUG1,
740
0
          errmsg_internal("checkpoint record is at %X/%08X",
741
0
                  LSN_FORMAT_ARGS(CheckPointLoc)));
742
0
    }
743
0
    else
744
0
    {
745
      /*
746
       * We used to attempt to go back to a secondary checkpoint record
747
       * here, but only when not in standby mode. We now just fail if we
748
       * can't read the last checkpoint because this allows us to
749
       * simplify processing around checkpoints.
750
       */
751
0
      ereport(FATAL,
752
0
          errmsg("could not locate a valid checkpoint record at %X/%08X",
753
0
               LSN_FORMAT_ARGS(CheckPointLoc)));
754
0
    }
755
0
    memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
756
0
    wasShutdown = ((record->xl_info & ~XLR_INFO_MASK) == XLOG_CHECKPOINT_SHUTDOWN);
757
758
    /* Make sure that REDO location exists. */
759
0
    if (checkPoint.redo < CheckPointLoc)
760
0
    {
761
0
      XLogPrefetcherBeginRead(xlogprefetcher, checkPoint.redo);
762
0
      if (!ReadRecord(xlogprefetcher, LOG, false, checkPoint.ThisTimeLineID))
763
0
        ereport(FATAL,
764
0
            errmsg("could not find redo location %X/%08X referenced by checkpoint record at %X/%08X",
765
0
                 LSN_FORMAT_ARGS(checkPoint.redo), LSN_FORMAT_ARGS(CheckPointLoc)));
766
0
    }
767
0
  }
768
769
0
  if (ArchiveRecoveryRequested)
770
0
  {
771
0
    if (StandbyModeRequested)
772
0
      ereport(LOG,
773
0
          (errmsg("entering standby mode")));
774
0
    else if (recoveryTarget == RECOVERY_TARGET_XID)
775
0
      ereport(LOG,
776
0
          (errmsg("starting point-in-time recovery to XID %u",
777
0
              recoveryTargetXid)));
778
0
    else if (recoveryTarget == RECOVERY_TARGET_TIME)
779
0
      ereport(LOG,
780
0
          (errmsg("starting point-in-time recovery to %s",
781
0
              timestamptz_to_str(recoveryTargetTime))));
782
0
    else if (recoveryTarget == RECOVERY_TARGET_NAME)
783
0
      ereport(LOG,
784
0
          (errmsg("starting point-in-time recovery to \"%s\"",
785
0
              recoveryTargetName)));
786
0
    else if (recoveryTarget == RECOVERY_TARGET_LSN)
787
0
      ereport(LOG,
788
0
          errmsg("starting point-in-time recovery to WAL location (LSN) \"%X/%08X\"",
789
0
               LSN_FORMAT_ARGS(recoveryTargetLSN)));
790
0
    else if (recoveryTarget == RECOVERY_TARGET_IMMEDIATE)
791
0
      ereport(LOG,
792
0
          (errmsg("starting point-in-time recovery to earliest consistent point")));
793
0
    else
794
0
      ereport(LOG,
795
0
          (errmsg("starting archive recovery")));
796
0
  }
797
798
  /*
799
   * If the location of the checkpoint record is not on the expected
800
   * timeline in the history of the requested timeline, we cannot proceed:
801
   * the backup is not part of the history of the requested timeline.
802
   */
803
0
  Assert(expectedTLEs);   /* was initialized by reading checkpoint
804
                 * record */
805
0
  if (tliOfPointInHistory(CheckPointLoc, expectedTLEs) !=
806
0
    CheckPointTLI)
807
0
  {
808
0
    XLogRecPtr  switchpoint;
809
810
    /*
811
     * tliSwitchPoint will throw an error if the checkpoint's timeline is
812
     * not in expectedTLEs at all.
813
     */
814
0
    switchpoint = tliSwitchPoint(CheckPointTLI, expectedTLEs, NULL);
815
0
    ereport(FATAL,
816
0
        (errmsg("requested timeline %u is not a child of this server's history",
817
0
            recoveryTargetTLI),
818
    /* translator: %s is a backup_label file or a pg_control file */
819
0
         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.",
820
0
               haveBackupLabel ? "backup_label" : "pg_control",
821
0
               LSN_FORMAT_ARGS(CheckPointLoc),
822
0
               CheckPointTLI,
823
0
               LSN_FORMAT_ARGS(switchpoint))));
824
0
  }
825
826
  /*
827
   * The min recovery point should be part of the requested timeline's
828
   * history, too.
829
   */
830
0
  if (XLogRecPtrIsValid(ControlFile->minRecoveryPoint) &&
831
0
    tliOfPointInHistory(ControlFile->minRecoveryPoint - 1, expectedTLEs) !=
832
0
    ControlFile->minRecoveryPointTLI)
833
0
    ereport(FATAL,
834
0
        errmsg("requested timeline %u does not contain minimum recovery point %X/%08X on timeline %u",
835
0
             recoveryTargetTLI,
836
0
             LSN_FORMAT_ARGS(ControlFile->minRecoveryPoint),
837
0
             ControlFile->minRecoveryPointTLI));
838
839
0
  ereport(DEBUG1,
840
0
      errmsg_internal("redo record is at %X/%08X; shutdown %s",
841
0
              LSN_FORMAT_ARGS(checkPoint.redo),
842
0
              wasShutdown ? "true" : "false"));
843
0
  ereport(DEBUG1,
844
0
      (errmsg_internal("next transaction ID: " UINT64_FORMAT "; next OID: %" PRIu64,
845
0
               U64FromFullTransactionId(checkPoint.nextXid),
846
0
               checkPoint.nextOid)));
847
0
  ereport(DEBUG1,
848
0
      (errmsg_internal("next MultiXactId: %u; next MultiXactOffset: %" PRIu64,
849
0
               checkPoint.nextMulti, checkPoint.nextMultiOffset)));
850
0
  ereport(DEBUG1,
851
0
      (errmsg_internal("oldest unfrozen transaction ID: %u, in database %u",
852
0
               checkPoint.oldestXid, checkPoint.oldestXidDB)));
853
0
  ereport(DEBUG1,
854
0
      (errmsg_internal("oldest MultiXactId: %u, in database %u",
855
0
               checkPoint.oldestMulti, checkPoint.oldestMultiDB)));
856
0
  ereport(DEBUG1,
857
0
      (errmsg_internal("commit timestamp Xid oldest/newest: %u/%u",
858
0
               checkPoint.oldestCommitTsXid,
859
0
               checkPoint.newestCommitTsXid)));
860
0
  if (!TransactionIdIsNormal(XidFromFullTransactionId(checkPoint.nextXid)))
861
0
    ereport(PANIC,
862
0
        (errmsg("invalid next transaction ID")));
863
864
  /* sanity check */
865
0
  if (checkPoint.redo > CheckPointLoc)
866
0
    ereport(PANIC,
867
0
        (errmsg("invalid redo in checkpoint record")));
868
869
  /*
870
   * Check whether we need to force recovery from WAL.  If it appears to
871
   * have been a clean shutdown and we did not have a recovery signal file,
872
   * then assume no recovery needed.
873
   */
874
0
  if (checkPoint.redo < CheckPointLoc)
875
0
  {
876
0
    if (wasShutdown)
877
0
      ereport(PANIC,
878
0
          (errmsg("invalid redo record in shutdown checkpoint")));
879
0
    InRecovery = true;
880
0
  }
881
0
  else if (ControlFile->state != DB_SHUTDOWNED)
882
0
    InRecovery = true;
883
0
  else if (ArchiveRecoveryRequested)
884
0
  {
885
    /* force recovery due to presence of recovery signal file */
886
0
    InRecovery = true;
887
0
  }
888
889
  /*
890
   * If recovery is needed, update our in-memory copy of pg_control to show
891
   * that we are recovering and to show the selected checkpoint as the place
892
   * we are starting from. We also mark pg_control with any minimum recovery
893
   * stop point obtained from a backup history file.
894
   *
895
   * We don't write the changes to disk yet, though. Only do that after
896
   * initializing various subsystems.
897
   */
898
0
  if (InRecovery)
899
0
  {
900
0
    if (InArchiveRecovery)
901
0
    {
902
0
      ControlFile->state = DB_IN_ARCHIVE_RECOVERY;
903
0
    }
904
0
    else
905
0
    {
906
0
      ereport(LOG,
907
0
          (errmsg("database system was not properly shut down; "
908
0
              "automatic recovery in progress")));
909
0
      if (recoveryTargetTLI > ControlFile->checkPointCopy.ThisTimeLineID)
910
0
        ereport(LOG,
911
0
            (errmsg("crash recovery starts in timeline %u "
912
0
                "and has target timeline %u",
913
0
                ControlFile->checkPointCopy.ThisTimeLineID,
914
0
                recoveryTargetTLI)));
915
0
      ControlFile->state = DB_IN_CRASH_RECOVERY;
916
0
    }
917
0
    ControlFile->checkPoint = CheckPointLoc;
918
0
    ControlFile->checkPointCopy = checkPoint;
919
0
    if (InArchiveRecovery)
920
0
    {
921
      /* initialize minRecoveryPoint if not set yet */
922
0
      if (ControlFile->minRecoveryPoint < checkPoint.redo)
923
0
      {
924
0
        ControlFile->minRecoveryPoint = checkPoint.redo;
925
0
        ControlFile->minRecoveryPointTLI = checkPoint.ThisTimeLineID;
926
0
      }
927
0
    }
928
929
    /*
930
     * Set backupStartPoint if we're starting recovery from a base backup.
931
     *
932
     * Also set backupEndPoint and use minRecoveryPoint as the backup end
933
     * location if we're starting recovery from a base backup which was
934
     * taken from a standby. In this case, the database system status in
935
     * pg_control must indicate that the database was already in recovery.
936
     * Usually that will be DB_IN_ARCHIVE_RECOVERY but also can be
937
     * DB_SHUTDOWNED_IN_RECOVERY if recovery previously was interrupted
938
     * before reaching this point; e.g. because restore_command or
939
     * primary_conninfo were faulty.
940
     *
941
     * Any other state indicates that the backup somehow became corrupted
942
     * and we can't sensibly continue with recovery.
943
     */
944
0
    if (haveBackupLabel)
945
0
    {
946
0
      ControlFile->backupStartPoint = checkPoint.redo;
947
0
      ControlFile->backupEndRequired = backupEndRequired;
948
949
0
      if (backupFromStandby)
950
0
      {
951
0
        if (dbstate_at_startup != DB_IN_ARCHIVE_RECOVERY &&
952
0
          dbstate_at_startup != DB_SHUTDOWNED_IN_RECOVERY)
953
0
          ereport(FATAL,
954
0
              (errmsg("backup_label contains data inconsistent with control file"),
955
0
               errhint("This means that the backup is corrupted and you will "
956
0
                   "have to use another backup for recovery.")));
957
0
        ControlFile->backupEndPoint = ControlFile->minRecoveryPoint;
958
0
      }
959
0
    }
960
0
  }
961
962
  /* remember these, so that we know when we have reached consistency */
963
0
  backupStartPoint = ControlFile->backupStartPoint;
964
0
  backupEndRequired = ControlFile->backupEndRequired;
965
0
  backupEndPoint = ControlFile->backupEndPoint;
966
0
  if (InArchiveRecovery)
967
0
  {
968
0
    minRecoveryPoint = ControlFile->minRecoveryPoint;
969
0
    minRecoveryPointTLI = ControlFile->minRecoveryPointTLI;
970
0
  }
971
0
  else
972
0
  {
973
0
    minRecoveryPoint = InvalidXLogRecPtr;
974
0
    minRecoveryPointTLI = 0;
975
0
  }
976
977
  /*
978
   * Start recovery assuming that the final record isn't lost.
979
   */
980
0
  abortedRecPtr = InvalidXLogRecPtr;
981
0
  missingContrecPtr = InvalidXLogRecPtr;
982
983
0
  *wasShutdown_ptr = wasShutdown;
984
0
  *haveBackupLabel_ptr = haveBackupLabel;
985
0
  *haveTblspcMap_ptr = haveTblspcMap;
986
0
}
987
988
/*
989
 * See if there are any recovery signal files and if so, set state for
990
 * recovery.
991
 *
992
 * See if there is a recovery command file (recovery.conf), and if so
993
 * throw an ERROR since as of PG12 we no longer recognize that.
994
 */
995
static void
996
readRecoverySignalFile(void)
997
0
{
998
0
  struct stat stat_buf;
999
1000
0
  if (IsBootstrapProcessingMode())
1001
0
    return;
1002
1003
  /*
1004
   * Check for old recovery API file: recovery.conf
1005
   */
1006
0
  if (stat(RECOVERY_COMMAND_FILE, &stat_buf) == 0)
1007
0
    ereport(FATAL,
1008
0
        (errcode_for_file_access(),
1009
0
         errmsg("using recovery command file \"%s\" is not supported",
1010
0
            RECOVERY_COMMAND_FILE)));
1011
1012
  /*
1013
   * Remove unused .done file, if present. Ignore if absent.
1014
   */
1015
0
  unlink(RECOVERY_COMMAND_DONE);
1016
1017
  /*
1018
   * Check for recovery signal files and if found, fsync them since they
1019
   * represent server state information.  We don't sweat too much about the
1020
   * possibility of fsync failure, however.
1021
   */
1022
0
  if (stat(STANDBY_SIGNAL_FILE, &stat_buf) == 0)
1023
0
  {
1024
0
    int     fd;
1025
1026
0
    fd = BasicOpenFilePerm(STANDBY_SIGNAL_FILE, O_RDWR | PG_BINARY,
1027
0
                 S_IRUSR | S_IWUSR);
1028
0
    if (fd >= 0)
1029
0
    {
1030
0
      (void) pg_fsync(fd);
1031
0
      close(fd);
1032
0
    }
1033
0
    standby_signal_file_found = true;
1034
0
  }
1035
1036
0
  if (stat(RECOVERY_SIGNAL_FILE, &stat_buf) == 0)
1037
0
  {
1038
0
    int     fd;
1039
1040
0
    fd = BasicOpenFilePerm(RECOVERY_SIGNAL_FILE, O_RDWR | PG_BINARY,
1041
0
                 S_IRUSR | S_IWUSR);
1042
0
    if (fd >= 0)
1043
0
    {
1044
0
      (void) pg_fsync(fd);
1045
0
      close(fd);
1046
0
    }
1047
0
    recovery_signal_file_found = true;
1048
0
  }
1049
1050
  /*
1051
   * If both signal files are present, standby signal file takes precedence.
1052
   * If neither is present then we won't enter archive recovery.
1053
   */
1054
0
  StandbyModeRequested = false;
1055
0
  ArchiveRecoveryRequested = false;
1056
0
  if (standby_signal_file_found)
1057
0
  {
1058
0
    StandbyModeRequested = true;
1059
0
    ArchiveRecoveryRequested = true;
1060
0
  }
1061
0
  else if (recovery_signal_file_found)
1062
0
  {
1063
0
    StandbyModeRequested = false;
1064
0
    ArchiveRecoveryRequested = true;
1065
0
  }
1066
0
  else
1067
0
    return;
1068
1069
  /*
1070
   * We don't support standby mode in standalone backends; that requires
1071
   * other processes such as the WAL receiver to be alive.
1072
   */
1073
0
  if (StandbyModeRequested && !IsUnderPostmaster)
1074
0
    ereport(FATAL,
1075
0
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1076
0
         errmsg("standby mode is not supported by single-user servers")));
1077
0
}
1078
1079
static void
1080
validateRecoveryParameters(void)
1081
0
{
1082
  /* Reject conflicting targets even when recovery was not requested */
1083
0
  recoveryTarget = DetermineRecoveryTargetType();
1084
1085
0
  if (!ArchiveRecoveryRequested)
1086
0
    return;
1087
1088
  /*
1089
   * Check for compulsory parameters
1090
   */
1091
0
  if (StandbyModeRequested)
1092
0
  {
1093
0
    if ((PrimaryConnInfo == NULL || strcmp(PrimaryConnInfo, "") == 0) &&
1094
0
      (recoveryRestoreCommand == NULL || strcmp(recoveryRestoreCommand, "") == 0))
1095
0
      ereport(WARNING,
1096
0
          (errmsg("specified neither \"primary_conninfo\" nor \"restore_command\""),
1097
0
           errhint("The database server will regularly poll the pg_wal subdirectory to check for files placed there.")));
1098
0
  }
1099
0
  else
1100
0
  {
1101
0
    if (recoveryRestoreCommand == NULL ||
1102
0
      strcmp(recoveryRestoreCommand, "") == 0)
1103
0
      ereport(FATAL,
1104
0
          (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1105
0
           errmsg("must specify \"restore_command\" when standby mode is not enabled")));
1106
0
  }
1107
1108
  /*
1109
   * Override any inconsistent requests. Note that this is a change of
1110
   * behaviour in 9.5; prior to this we simply ignored a request to pause if
1111
   * hot_standby = off, which was surprising behaviour.
1112
   */
1113
0
  if (recoveryTargetAction == RECOVERY_TARGET_ACTION_PAUSE &&
1114
0
    !EnableHotStandby)
1115
0
    recoveryTargetAction = RECOVERY_TARGET_ACTION_SHUTDOWN;
1116
1117
  /*
1118
   * Final parsing of recovery_target_time string; see also
1119
   * check_recovery_target_time().
1120
   */
1121
0
  if (recoveryTarget == RECOVERY_TARGET_TIME)
1122
0
  {
1123
0
    recoveryTargetTime = DatumGetTimestampTz(DirectFunctionCall3(timestamptz_in,
1124
0
                                   CStringGetDatum(recovery_target_time_string),
1125
0
                                   ObjectIdGetDatum(InvalidOid),
1126
0
                                   Int32GetDatum(-1)));
1127
0
  }
1128
1129
  /*
1130
   * If user specified recovery_target_timeline, validate it or compute the
1131
   * "latest" value.  We can't do this until after we've gotten the restore
1132
   * command and set InArchiveRecovery, because we need to fetch timeline
1133
   * history files from the archive.
1134
   */
1135
0
  if (recoveryTargetTimeLineGoal == RECOVERY_TARGET_TIMELINE_NUMERIC)
1136
0
  {
1137
0
    TimeLineID  rtli = recoveryTargetTLIRequested;
1138
1139
    /* Timeline 1 does not have a history file, all else should */
1140
0
    if (rtli != 1 && !existsTimeLineHistory(rtli))
1141
0
      ereport(FATAL,
1142
0
          (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1143
0
           errmsg("recovery target timeline %u does not exist",
1144
0
              rtli)));
1145
0
    recoveryTargetTLI = rtli;
1146
0
  }
1147
0
  else if (recoveryTargetTimeLineGoal == RECOVERY_TARGET_TIMELINE_LATEST)
1148
0
  {
1149
    /* We start the "latest" search from pg_control's timeline */
1150
0
    recoveryTargetTLI = findNewestTimeLine(recoveryTargetTLI);
1151
0
  }
1152
0
  else
1153
0
  {
1154
    /*
1155
     * else we just use the recoveryTargetTLI as already read from
1156
     * ControlFile
1157
     */
1158
0
    Assert(recoveryTargetTimeLineGoal == RECOVERY_TARGET_TIMELINE_CONTROLFILE);
1159
0
  }
1160
0
}
1161
1162
/*
1163
 * read_backup_label: check to see if a backup_label file is present
1164
 *
1165
 * If we see a backup_label during recovery, we assume that we are recovering
1166
 * from a backup dump file, and we therefore roll forward from the checkpoint
1167
 * identified by the label file, NOT what pg_control says.  This avoids the
1168
 * problem that pg_control might have been archived one or more checkpoints
1169
 * later than the start of the dump, and so if we rely on it as the start
1170
 * point, we will fail to restore a consistent database state.
1171
 *
1172
 * Returns true if a backup_label was found (and fills the checkpoint
1173
 * location and TLI into *checkPointLoc and *backupLabelTLI, respectively);
1174
 * returns false if not. If this backup_label came from a streamed backup,
1175
 * *backupEndRequired is set to true. If this backup_label was created during
1176
 * recovery, *backupFromStandby is set to true.
1177
 *
1178
 * Also sets the global variables RedoStartLSN and RedoStartTLI with the LSN
1179
 * and TLI read from the backup file.
1180
 */
1181
static bool
1182
read_backup_label(XLogRecPtr *checkPointLoc, TimeLineID *backupLabelTLI,
1183
          bool *backupEndRequired, bool *backupFromStandby)
1184
0
{
1185
0
  char    startxlogfilename[MAXFNAMELEN];
1186
0
  TimeLineID  tli_from_walseg,
1187
0
        tli_from_file;
1188
0
  FILE     *lfp;
1189
0
  char    ch;
1190
0
  char    backuptype[20];
1191
0
  char    backupfrom[20];
1192
0
  char    backuplabel[MAXPGPATH];
1193
0
  char    backuptime[128];
1194
0
  char    lsn[MAXPG_LSNLEN + 1];
1195
1196
  /* suppress possible uninitialized-variable warnings */
1197
0
  *checkPointLoc = InvalidXLogRecPtr;
1198
0
  *backupLabelTLI = 0;
1199
0
  *backupEndRequired = false;
1200
0
  *backupFromStandby = false;
1201
1202
  /*
1203
   * See if label file is present
1204
   */
1205
0
  lfp = AllocateFile(BACKUP_LABEL_FILE, "r");
1206
0
  if (!lfp)
1207
0
  {
1208
0
    if (errno != ENOENT)
1209
0
      ereport(FATAL,
1210
0
          (errcode_for_file_access(),
1211
0
           errmsg("could not read file \"%s\": %m",
1212
0
              BACKUP_LABEL_FILE)));
1213
0
    return false;     /* it's not there, all is fine */
1214
0
  }
1215
1216
  /*
1217
   * Read and parse the START WAL LOCATION and CHECKPOINT lines (this code
1218
   * is pretty crude, but we are not expecting any variability in the file
1219
   * format).
1220
   */
1221
0
  if (fscanf(lfp,
1222
0
         "START WAL LOCATION: %" CppAsString2(MAXPG_LSNLEN) "[0123456789ABCDEFabcdef/] (file %08X%16s)%c",
1223
0
         lsn, &tli_from_walseg, startxlogfilename, &ch) != 4 ||
1224
0
    ch != '\n' ||
1225
0
    !pg_parse_lsn(lsn, &RedoStartLSN))
1226
0
    ereport(FATAL,
1227
0
        (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1228
0
         errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
1229
0
  RedoStartTLI = tli_from_walseg;
1230
0
  if (fscanf(lfp,
1231
0
         "CHECKPOINT LOCATION: %" CppAsString2(MAXPG_LSNLEN) "[0123456789ABCDEFabcdef/]%c", lsn,
1232
0
         &ch) != 2 ||
1233
0
    ch != '\n' ||
1234
0
    !pg_parse_lsn(lsn, checkPointLoc))
1235
0
    ereport(FATAL,
1236
0
        (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1237
0
         errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
1238
0
  *backupLabelTLI = tli_from_walseg;
1239
1240
  /*
1241
   * BACKUP METHOD lets us know if this was a typical backup ("streamed",
1242
   * which could mean either pg_basebackup or the pg_backup_start/stop
1243
   * method was used) or if this label came from somewhere else (the only
1244
   * other option today being from pg_rewind).  If this was a streamed
1245
   * backup then we know that we need to play through until we get to the
1246
   * end of the WAL which was generated during the backup (at which point we
1247
   * will have reached consistency and backupEndRequired will be reset to be
1248
   * false).
1249
   */
1250
0
  if (fscanf(lfp, "BACKUP METHOD: %19s\n", backuptype) == 1)
1251
0
  {
1252
0
    if (strcmp(backuptype, "streamed") == 0)
1253
0
      *backupEndRequired = true;
1254
0
  }
1255
1256
  /*
1257
   * BACKUP FROM lets us know if this was from a primary or a standby.  If
1258
   * it was from a standby, we'll double-check that the control file state
1259
   * matches that of a standby.
1260
   */
1261
0
  if (fscanf(lfp, "BACKUP FROM: %19s\n", backupfrom) == 1)
1262
0
  {
1263
0
    if (strcmp(backupfrom, "standby") == 0)
1264
0
      *backupFromStandby = true;
1265
0
  }
1266
1267
  /*
1268
   * Parse START TIME and LABEL. Those are not mandatory fields for recovery
1269
   * but checking for their presence is useful for debugging and the next
1270
   * sanity checks. Cope also with the fact that the result buffers have a
1271
   * pre-allocated size, hence if the backup_label file has been generated
1272
   * with strings longer than the maximum assumed here an incorrect parsing
1273
   * happens. That's fine as only minor consistency checks are done
1274
   * afterwards.
1275
   */
1276
0
  if (fscanf(lfp, "START TIME: %127[^\n]\n", backuptime) == 1)
1277
0
    ereport(DEBUG1,
1278
0
        (errmsg_internal("backup time %s in file \"%s\"",
1279
0
                 backuptime, BACKUP_LABEL_FILE)));
1280
1281
0
  if (fscanf(lfp, "LABEL: %1023[^\n]\n", backuplabel) == 1)
1282
0
    ereport(DEBUG1,
1283
0
        (errmsg_internal("backup label %s in file \"%s\"",
1284
0
                 backuplabel, BACKUP_LABEL_FILE)));
1285
1286
  /*
1287
   * START TIMELINE is new as of 11. Its parsing is not mandatory, still use
1288
   * it as a sanity check if present.
1289
   */
1290
0
  if (fscanf(lfp, "START TIMELINE: %u\n", &tli_from_file) == 1)
1291
0
  {
1292
0
    if (tli_from_walseg != tli_from_file)
1293
0
      ereport(FATAL,
1294
0
          (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1295
0
           errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE),
1296
0
           errdetail("Timeline ID parsed is %u, but expected %u.",
1297
0
                 tli_from_file, tli_from_walseg)));
1298
1299
0
    ereport(DEBUG1,
1300
0
        (errmsg_internal("backup timeline %u in file \"%s\"",
1301
0
                 tli_from_file, BACKUP_LABEL_FILE)));
1302
0
  }
1303
1304
  /*
1305
   * INCREMENTAL FROM LSN indicates that this is an incremental backup.  The
1306
   * LSN itself need not be parsed, so reading its first character is
1307
   * sufficient.
1308
   */
1309
0
  if (fscanf(lfp, "INCREMENTAL FROM LSN: %c", &ch) == 1)
1310
0
    ereport(FATAL,
1311
0
        (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1312
0
         errmsg("this is an incremental backup, not a data directory"),
1313
0
         errhint("Use pg_combinebackup to reconstruct a valid data directory.")));
1314
1315
0
  if (ferror(lfp) || FreeFile(lfp))
1316
0
    ereport(FATAL,
1317
0
        (errcode_for_file_access(),
1318
0
         errmsg("could not read file \"%s\": %m",
1319
0
            BACKUP_LABEL_FILE)));
1320
1321
0
  return true;
1322
0
}
1323
1324
/*
1325
 * read_tablespace_map: check to see if a tablespace_map file is present
1326
 *
1327
 * If we see a tablespace_map file during recovery, we assume that we are
1328
 * recovering from a backup dump file, and we therefore need to create symlinks
1329
 * as per the information present in tablespace_map file.
1330
 *
1331
 * Returns true if a tablespace_map file was found (and fills *tablespaces
1332
 * with a tablespaceinfo struct for each tablespace listed in the file);
1333
 * returns false if not.
1334
 */
1335
static bool
1336
read_tablespace_map(List **tablespaces)
1337
0
{
1338
0
  tablespaceinfo *ti;
1339
0
  FILE     *lfp;
1340
0
  char    str[MAXPGPATH];
1341
0
  int     ch,
1342
0
        i,
1343
0
        n;
1344
0
  bool    was_backslash;
1345
1346
  /*
1347
   * See if tablespace_map file is present
1348
   */
1349
0
  lfp = AllocateFile(TABLESPACE_MAP, "r");
1350
0
  if (!lfp)
1351
0
  {
1352
0
    if (errno != ENOENT)
1353
0
      ereport(FATAL,
1354
0
          (errcode_for_file_access(),
1355
0
           errmsg("could not read file \"%s\": %m",
1356
0
              TABLESPACE_MAP)));
1357
0
    return false;     /* it's not there, all is fine */
1358
0
  }
1359
1360
  /*
1361
   * Read and parse the link name and path lines from tablespace_map file
1362
   * (this code is pretty crude, but we are not expecting any variability in
1363
   * the file format).  De-escape any backslashes that were inserted.
1364
   */
1365
0
  i = 0;
1366
0
  was_backslash = false;
1367
0
  while ((ch = fgetc(lfp)) != EOF)
1368
0
  {
1369
0
    if (!was_backslash && (ch == '\n' || ch == '\r'))
1370
0
    {
1371
0
      char     *endp;
1372
1373
0
      if (i == 0)
1374
0
        continue;   /* \r immediately followed by \n */
1375
1376
      /*
1377
       * The de-escaped line should contain an OID followed by exactly
1378
       * one space followed by a path.  The path might start with
1379
       * spaces, so don't be too liberal about parsing.
1380
       */
1381
0
      str[i] = '\0';
1382
0
      n = 0;
1383
0
      while (str[n] && str[n] != ' ')
1384
0
        n++;
1385
0
      if (n < 1 || n >= i - 1)
1386
0
        ereport(FATAL,
1387
0
            (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1388
0
             errmsg("invalid data in file \"%s\"", TABLESPACE_MAP)));
1389
0
      str[n++] = '\0';
1390
1391
0
      ti = palloc0_object(tablespaceinfo);
1392
0
      errno = 0;
1393
0
      ti->oid = strtoul(str, &endp, 10);
1394
0
      if (*endp != '\0' || errno == EINVAL || errno == ERANGE)
1395
0
        ereport(FATAL,
1396
0
            (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1397
0
             errmsg("invalid data in file \"%s\"", TABLESPACE_MAP)));
1398
0
      ti->path = pstrdup(str + n);
1399
0
      *tablespaces = lappend(*tablespaces, ti);
1400
1401
0
      i = 0;
1402
0
      continue;
1403
0
    }
1404
0
    else if (!was_backslash && ch == '\\')
1405
0
      was_backslash = true;
1406
0
    else
1407
0
    {
1408
0
      if (i < sizeof(str) - 1)
1409
0
        str[i++] = ch;
1410
0
      was_backslash = false;
1411
0
    }
1412
0
  }
1413
1414
0
  if (i != 0 || was_backslash) /* last line not terminated? */
1415
0
    ereport(FATAL,
1416
0
        (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1417
0
         errmsg("invalid data in file \"%s\"", TABLESPACE_MAP)));
1418
1419
0
  if (ferror(lfp) || FreeFile(lfp))
1420
0
    ereport(FATAL,
1421
0
        (errcode_for_file_access(),
1422
0
         errmsg("could not read file \"%s\": %m",
1423
0
            TABLESPACE_MAP)));
1424
1425
0
  return true;
1426
0
}
1427
1428
/*
1429
 * Finish WAL recovery.
1430
 *
1431
 * This does not close the 'xlogreader' yet, because in some cases the caller
1432
 * still wants to re-read the last checkpoint record by calling
1433
 * ReadCheckpointRecord().
1434
 *
1435
 * Returns the position of the last valid or applied record, after which new
1436
 * WAL should be appended, information about why recovery was ended, and some
1437
 * other things. See the EndOfWalRecoveryInfo struct for details.
1438
 */
1439
EndOfWalRecoveryInfo *
1440
FinishWalRecovery(void)
1441
0
{
1442
0
  EndOfWalRecoveryInfo *result = palloc_object(EndOfWalRecoveryInfo);
1443
0
  XLogRecPtr  lastRec;
1444
0
  TimeLineID  lastRecTLI;
1445
0
  XLogRecPtr  endOfLog;
1446
1447
  /*
1448
   * Kill WAL receiver, if it's still running, before we continue to write
1449
   * the startup checkpoint and aborted-contrecord records. It will trump
1450
   * over these records and subsequent ones if it's still alive when we
1451
   * start writing WAL.
1452
   */
1453
0
  XLogShutdownWalRcv();
1454
1455
  /*
1456
   * Shutdown the slot sync worker to drop any temporary slots acquired by
1457
   * it and to prevent it from keep trying to fetch the failover slots.
1458
   *
1459
   * We do not update the 'synced' column in 'pg_replication_slots' system
1460
   * view from true to false here, as any failed update could leave 'synced'
1461
   * column false for some slots. This could cause issues during slot sync
1462
   * after restarting the server as a standby. While updating the 'synced'
1463
   * column after switching to the new timeline is an option, it does not
1464
   * simplify the handling for the 'synced' column. Therefore, we retain the
1465
   * 'synced' column as true after promotion as it may provide useful
1466
   * information about the slot origin.
1467
   */
1468
0
  ShutDownSlotSync();
1469
1470
  /*
1471
   * We are now done reading the xlog from stream. Turn off streaming
1472
   * recovery to force fetching the files (which would be required at end of
1473
   * recovery, e.g., timeline history file) from archive or pg_wal.
1474
   *
1475
   * Note that standby mode must be turned off after killing WAL receiver,
1476
   * i.e., calling XLogShutdownWalRcv().
1477
   */
1478
0
  Assert(!WalRcvStreaming());
1479
0
  StandbyMode = false;
1480
1481
  /*
1482
   * Determine where to start writing WAL next.
1483
   *
1484
   * Re-fetch the last valid or last applied record, so we can identify the
1485
   * exact endpoint of what we consider the valid portion of WAL.  There may
1486
   * be an incomplete continuation record after that, in which case
1487
   * 'abortedRecPtr' and 'missingContrecPtr' are set and the caller will
1488
   * write a special OVERWRITE_CONTRECORD message to mark that the rest of
1489
   * it is intentionally missing.  See CreateOverwriteContrecordRecord().
1490
   *
1491
   * An important side-effect of this is to load the last page into
1492
   * xlogreader. The caller uses it to initialize the WAL for writing.
1493
   */
1494
0
  if (!InRecovery)
1495
0
  {
1496
0
    lastRec = CheckPointLoc;
1497
0
    lastRecTLI = CheckPointTLI;
1498
0
  }
1499
0
  else
1500
0
  {
1501
0
    lastRec = XLogRecoveryCtl->lastReplayedReadRecPtr;
1502
0
    lastRecTLI = XLogRecoveryCtl->lastReplayedTLI;
1503
0
  }
1504
0
  XLogPrefetcherBeginRead(xlogprefetcher, lastRec);
1505
0
  (void) ReadRecord(xlogprefetcher, PANIC, false, lastRecTLI);
1506
0
  endOfLog = xlogreader->EndRecPtr;
1507
1508
  /*
1509
   * Remember the TLI in the filename of the XLOG segment containing the
1510
   * end-of-log.  It could be different from the timeline that endOfLog
1511
   * nominally belongs to, if there was a timeline switch in that segment,
1512
   * and we were reading the old WAL from a segment belonging to a higher
1513
   * timeline.
1514
   */
1515
0
  result->endOfLogTLI = xlogreader->seg.ws_tli;
1516
1517
0
  if (ArchiveRecoveryRequested)
1518
0
  {
1519
    /*
1520
     * We are no longer in archive recovery state.
1521
     *
1522
     * We are now done reading the old WAL.  Turn off archive fetching if
1523
     * it was active.
1524
     */
1525
0
    Assert(InArchiveRecovery);
1526
0
    InArchiveRecovery = false;
1527
1528
    /*
1529
     * If the ending log segment is still open, close it (to avoid
1530
     * problems on Windows with trying to rename or delete an open file).
1531
     */
1532
0
    if (readFile >= 0)
1533
0
    {
1534
0
      close(readFile);
1535
0
      readFile = -1;
1536
0
    }
1537
0
  }
1538
1539
  /*
1540
   * Copy the last partial block to the caller, for initializing the WAL
1541
   * buffer for appending new WAL.
1542
   */
1543
0
  if (endOfLog % XLOG_BLCKSZ != 0)
1544
0
  {
1545
0
    char     *page;
1546
0
    int     len;
1547
0
    XLogRecPtr  pageBeginPtr;
1548
1549
0
    pageBeginPtr = endOfLog - (endOfLog % XLOG_BLCKSZ);
1550
0
    Assert(readOff == XLogSegmentOffset(pageBeginPtr, wal_segment_size));
1551
1552
    /* Copy the valid part of the last block */
1553
0
    len = endOfLog % XLOG_BLCKSZ;
1554
0
    page = palloc(len);
1555
0
    memcpy(page, xlogreader->readBuf, len);
1556
1557
0
    result->lastPageBeginPtr = pageBeginPtr;
1558
0
    result->lastPage = page;
1559
0
  }
1560
0
  else
1561
0
  {
1562
    /* There is no partial block to copy. */
1563
0
    result->lastPageBeginPtr = endOfLog;
1564
0
    result->lastPage = NULL;
1565
0
  }
1566
1567
  /*
1568
   * Create a comment for the history file to explain why and where timeline
1569
   * changed.
1570
   */
1571
0
  result->recoveryStopReason = getRecoveryStopReason();
1572
1573
0
  result->lastRec = lastRec;
1574
0
  result->lastRecTLI = lastRecTLI;
1575
0
  result->endOfLog = endOfLog;
1576
1577
0
  result->abortedRecPtr = abortedRecPtr;
1578
0
  result->missingContrecPtr = missingContrecPtr;
1579
1580
0
  result->standby_signal_file_found = standby_signal_file_found;
1581
0
  result->recovery_signal_file_found = recovery_signal_file_found;
1582
1583
0
  return result;
1584
0
}
1585
1586
/*
1587
 * Clean up the WAL reader and leftovers from restoring WAL from archive
1588
 */
1589
void
1590
ShutdownWalRecovery(void)
1591
0
{
1592
0
  char    recoveryPath[MAXPGPATH];
1593
1594
  /* Final update of pg_stat_recovery_prefetch. */
1595
0
  XLogPrefetcherComputeStats(xlogprefetcher);
1596
1597
  /* Shut down xlogreader */
1598
0
  if (readFile >= 0)
1599
0
  {
1600
0
    close(readFile);
1601
0
    readFile = -1;
1602
0
  }
1603
0
  pfree(xlogreader->private_data);
1604
0
  XLogReaderFree(xlogreader);
1605
0
  XLogPrefetcherFree(xlogprefetcher);
1606
1607
0
  if (ArchiveRecoveryRequested)
1608
0
  {
1609
    /*
1610
     * Since there might be a partial WAL segment named RECOVERYXLOG, get
1611
     * rid of it.
1612
     */
1613
0
    snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYXLOG");
1614
0
    unlink(recoveryPath); /* ignore any error */
1615
1616
    /* Get rid of any remaining recovered timeline-history file, too */
1617
0
    snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYHISTORY");
1618
0
    unlink(recoveryPath); /* ignore any error */
1619
0
  }
1620
1621
  /*
1622
   * We don't need the latch anymore. It's not strictly necessary to disown
1623
   * it, but let's do it for the sake of tidiness.
1624
   */
1625
0
  if (ArchiveRecoveryRequested)
1626
0
    DisownLatch(&XLogRecoveryCtl->recoveryWakeupLatch);
1627
0
}
1628
1629
/*
1630
 * Perform WAL recovery.
1631
 *
1632
 * If the system was shut down cleanly, this is never called.
1633
 */
1634
void
1635
PerformWalRecovery(void)
1636
0
{
1637
0
  XLogRecord *record;
1638
0
  bool    reachedRecoveryTarget = false;
1639
0
  TimeLineID  replayTLI;
1640
1641
  /*
1642
   * Initialize shared variables for tracking progress of WAL replay, as if
1643
   * we had just replayed the record before the REDO location (or the
1644
   * checkpoint record itself, if it's a shutdown checkpoint).
1645
   */
1646
0
  SpinLockAcquire(&XLogRecoveryCtl->info_lck);
1647
0
  if (RedoStartLSN < CheckPointLoc)
1648
0
  {
1649
0
    XLogRecoveryCtl->lastReplayedReadRecPtr = InvalidXLogRecPtr;
1650
0
    XLogRecoveryCtl->lastReplayedEndRecPtr = RedoStartLSN;
1651
0
    XLogRecoveryCtl->lastReplayedTLI = RedoStartTLI;
1652
0
  }
1653
0
  else
1654
0
  {
1655
0
    XLogRecoveryCtl->lastReplayedReadRecPtr = xlogreader->ReadRecPtr;
1656
0
    XLogRecoveryCtl->lastReplayedEndRecPtr = xlogreader->EndRecPtr;
1657
0
    XLogRecoveryCtl->lastReplayedTLI = CheckPointTLI;
1658
0
  }
1659
0
  XLogRecoveryCtl->replayEndRecPtr = XLogRecoveryCtl->lastReplayedEndRecPtr;
1660
0
  XLogRecoveryCtl->replayEndTLI = XLogRecoveryCtl->lastReplayedTLI;
1661
0
  XLogRecoveryCtl->recoveryLastXTime = 0;
1662
0
  XLogRecoveryCtl->currentChunkStartTime = 0;
1663
0
  XLogRecoveryCtl->recoveryPauseState = RECOVERY_NOT_PAUSED;
1664
0
  SpinLockRelease(&XLogRecoveryCtl->info_lck);
1665
1666
  /* Also ensure XLogReceiptTime has a sane value */
1667
0
  XLogReceiptTime = GetCurrentTimestamp();
1668
1669
  /*
1670
   * Let postmaster know we've started redo now, so that it can launch the
1671
   * archiver if necessary.
1672
   */
1673
0
  if (IsUnderPostmaster)
1674
0
    SendPostmasterSignal(PMSIGNAL_RECOVERY_STARTED);
1675
1676
  /*
1677
   * Allow read-only connections immediately if we're consistent already.
1678
   */
1679
0
  CheckRecoveryConsistency();
1680
1681
  /*
1682
   * Find the first record that logically follows the checkpoint --- it
1683
   * might physically precede it, though.
1684
   */
1685
0
  if (RedoStartLSN < CheckPointLoc)
1686
0
  {
1687
    /* back up to find the record */
1688
0
    replayTLI = RedoStartTLI;
1689
0
    XLogPrefetcherBeginRead(xlogprefetcher, RedoStartLSN);
1690
0
    record = ReadRecord(xlogprefetcher, PANIC, false, replayTLI);
1691
1692
    /*
1693
     * If a checkpoint record's redo pointer points back to an earlier
1694
     * LSN, the record at that LSN should be an XLOG_CHECKPOINT_REDO
1695
     * record.
1696
     */
1697
0
    if (record->xl_rmid != RM_XLOG_ID ||
1698
0
      (record->xl_info & ~XLR_INFO_MASK) != XLOG_CHECKPOINT_REDO)
1699
0
      ereport(FATAL,
1700
0
          errmsg("unexpected record type found at redo point %X/%08X",
1701
0
               LSN_FORMAT_ARGS(xlogreader->ReadRecPtr)));
1702
0
  }
1703
0
  else
1704
0
  {
1705
    /* just have to read next record after CheckPoint */
1706
0
    Assert(xlogreader->ReadRecPtr == CheckPointLoc);
1707
0
    replayTLI = CheckPointTLI;
1708
0
    record = ReadRecord(xlogprefetcher, LOG, false, replayTLI);
1709
0
  }
1710
1711
0
  if (record != NULL)
1712
0
  {
1713
0
    TimestampTz xtime;
1714
0
    PGRUsage  ru0;
1715
1716
0
    pg_rusage_init(&ru0);
1717
1718
0
    InRedo = true;
1719
1720
0
    RmgrStartup();
1721
1722
0
    ereport(LOG,
1723
0
        errmsg("redo starts at %X/%08X",
1724
0
             LSN_FORMAT_ARGS(xlogreader->ReadRecPtr)));
1725
1726
    /* Prepare to report progress of the redo phase. */
1727
0
    if (!StandbyMode)
1728
0
      begin_startup_progress_phase();
1729
1730
    /*
1731
     * main redo apply loop
1732
     */
1733
0
    do
1734
0
    {
1735
0
      if (!StandbyMode)
1736
0
        ereport_startup_progress("redo in progress, elapsed time: %ld.%02d s, current LSN: %X/%08X",
1737
0
                     LSN_FORMAT_ARGS(xlogreader->ReadRecPtr));
1738
1739
#ifdef WAL_DEBUG
1740
      if (XLOG_DEBUG)
1741
      {
1742
        StringInfoData buf;
1743
1744
        initStringInfo(&buf);
1745
        appendStringInfo(&buf, "REDO @ %X/%08X; LSN %X/%08X: ",
1746
                 LSN_FORMAT_ARGS(xlogreader->ReadRecPtr),
1747
                 LSN_FORMAT_ARGS(xlogreader->EndRecPtr));
1748
        xlog_outrec(&buf, xlogreader);
1749
        appendStringInfoString(&buf, " - ");
1750
        xlog_outdesc(&buf, xlogreader);
1751
        elog(LOG, "%s", buf.data);
1752
        pfree(buf.data);
1753
      }
1754
#endif
1755
1756
      /* Handle interrupt signals of startup process */
1757
0
      ProcessStartupProcInterrupts();
1758
1759
      /*
1760
       * Pause WAL replay, if requested by a hot-standby session via
1761
       * SetRecoveryPause().
1762
       *
1763
       * Note that we intentionally don't take the info_lck spinlock
1764
       * here.  We might therefore read a slightly stale value of the
1765
       * recoveryPause flag, but it can't be very stale (no worse than
1766
       * the last spinlock we did acquire).  Since a pause request is a
1767
       * pretty asynchronous thing anyway, possibly responding to it one
1768
       * WAL record later than we otherwise would is a minor issue, so
1769
       * it doesn't seem worth adding another spinlock cycle to prevent
1770
       * that.
1771
       */
1772
0
      if (((volatile XLogRecoveryCtlData *) XLogRecoveryCtl)->recoveryPauseState !=
1773
0
        RECOVERY_NOT_PAUSED)
1774
0
        recoveryPausesHere(false);
1775
1776
      /*
1777
       * Have we reached our recovery target?
1778
       */
1779
0
      if (recoveryStopsBefore(xlogreader))
1780
0
      {
1781
0
        reachedRecoveryTarget = true;
1782
0
        break;
1783
0
      }
1784
1785
      /*
1786
       * If we've been asked to lag the primary, wait on latch until
1787
       * enough time has passed.
1788
       */
1789
0
      if (recoveryApplyDelay(xlogreader))
1790
0
      {
1791
        /*
1792
         * We test for paused recovery again here. If user sets
1793
         * delayed apply, it may be because they expect to pause
1794
         * recovery in case of problems, so we must test again here
1795
         * otherwise pausing during the delay-wait wouldn't work.
1796
         */
1797
0
        if (((volatile XLogRecoveryCtlData *) XLogRecoveryCtl)->recoveryPauseState !=
1798
0
          RECOVERY_NOT_PAUSED)
1799
0
          recoveryPausesHere(false);
1800
0
      }
1801
1802
      /*
1803
       * Apply the record
1804
       */
1805
0
      ApplyWalRecord(xlogreader, record, &replayTLI);
1806
1807
      /*
1808
       * Wake up processes waiting for standby replay, write, or flush
1809
       * LSN to reach current replay position.  Replay implies that the
1810
       * WAL was already written and flushed to disk, so write and flush
1811
       * waiters can be woken at the replay position too.
1812
       */
1813
0
      WaitLSNWakeup(WAIT_LSN_TYPE_STANDBY_REPLAY,
1814
0
              XLogRecoveryCtl->lastReplayedEndRecPtr);
1815
0
      WaitLSNWakeup(WAIT_LSN_TYPE_STANDBY_WRITE,
1816
0
              XLogRecoveryCtl->lastReplayedEndRecPtr);
1817
0
      WaitLSNWakeup(WAIT_LSN_TYPE_STANDBY_FLUSH,
1818
0
              XLogRecoveryCtl->lastReplayedEndRecPtr);
1819
1820
      /* Exit loop if we reached inclusive recovery target */
1821
0
      if (recoveryStopsAfter(xlogreader))
1822
0
      {
1823
0
        reachedRecoveryTarget = true;
1824
0
        break;
1825
0
      }
1826
1827
      /* Else, try to fetch the next WAL record */
1828
0
      record = ReadRecord(xlogprefetcher, LOG, false, replayTLI);
1829
0
    } while (record != NULL);
1830
1831
    /*
1832
     * end of main redo apply loop
1833
     */
1834
1835
0
    if (reachedRecoveryTarget)
1836
0
    {
1837
0
      if (!reachedConsistency)
1838
0
        ereport(FATAL,
1839
0
            (errmsg("requested recovery stop point is before consistent recovery point")));
1840
1841
      /*
1842
       * This is the last point where we can restart recovery with a new
1843
       * recovery target, if we shutdown and begin again. After this,
1844
       * Resource Managers may choose to do permanent corrective actions
1845
       * at end of recovery.
1846
       */
1847
0
      switch (recoveryTargetAction)
1848
0
      {
1849
0
        case RECOVERY_TARGET_ACTION_SHUTDOWN:
1850
1851
          /*
1852
           * exit with special return code to request shutdown of
1853
           * postmaster.  Log messages issued from postmaster.
1854
           */
1855
0
          proc_exit(3);
1856
1857
0
        case RECOVERY_TARGET_ACTION_PAUSE:
1858
0
          SetRecoveryPause(true);
1859
0
          recoveryPausesHere(true);
1860
1861
          /* drop into promote */
1862
0
          pg_fallthrough;
1863
1864
0
        case RECOVERY_TARGET_ACTION_PROMOTE:
1865
0
          break;
1866
0
      }
1867
0
    }
1868
1869
0
    RmgrCleanup();
1870
1871
0
    ereport(LOG,
1872
0
        errmsg("redo done at %X/%08X system usage: %s",
1873
0
             LSN_FORMAT_ARGS(xlogreader->ReadRecPtr),
1874
0
             pg_rusage_show(&ru0)));
1875
0
    xtime = GetLatestXTime();
1876
0
    if (xtime)
1877
0
      ereport(LOG,
1878
0
          (errmsg("last completed transaction was at log time %s",
1879
0
              timestamptz_to_str(xtime))));
1880
1881
0
    InRedo = false;
1882
0
  }
1883
0
  else
1884
0
  {
1885
    /* there are no WAL records following the checkpoint */
1886
0
    ereport(LOG,
1887
0
        (errmsg("redo is not required")));
1888
0
  }
1889
1890
  /*
1891
   * This check is intentionally after the above log messages that indicate
1892
   * how far recovery went.
1893
   */
1894
0
  if (ArchiveRecoveryRequested &&
1895
0
    recoveryTarget != RECOVERY_TARGET_UNSET &&
1896
0
    !reachedRecoveryTarget)
1897
0
    ereport(FATAL,
1898
0
        (errcode(ERRCODE_CONFIG_FILE_ERROR),
1899
0
         errmsg("recovery ended before configured recovery target was reached")));
1900
0
}
1901
1902
/*
1903
 * Subroutine of PerformWalRecovery, to apply one WAL record.
1904
 */
1905
static void
1906
ApplyWalRecord(XLogReaderState *xlogreader, XLogRecord *record, TimeLineID *replayTLI)
1907
0
{
1908
0
  ErrorContextCallback errcallback;
1909
0
  bool    switchedTLI = false;
1910
1911
  /* Setup error traceback support for ereport() */
1912
0
  errcallback.callback = rm_redo_error_callback;
1913
0
  errcallback.arg = xlogreader;
1914
0
  errcallback.previous = error_context_stack;
1915
0
  error_context_stack = &errcallback;
1916
1917
  /*
1918
   * TransamVariables->nextXid must be beyond record's xid.
1919
   */
1920
0
  AdvanceNextFullTransactionIdPastXid(record->xl_xid);
1921
1922
  /*
1923
   * Before replaying this record, check if this record causes the current
1924
   * timeline to change. The record is already considered to be part of the
1925
   * new timeline, so we update replayTLI before replaying it. That's
1926
   * important so that replayEndTLI, which is recorded as the minimum
1927
   * recovery point's TLI if recovery stops after this record, is set
1928
   * correctly.
1929
   */
1930
0
  if (record->xl_rmid == RM_XLOG_ID)
1931
0
  {
1932
0
    TimeLineID  newReplayTLI = *replayTLI;
1933
0
    TimeLineID  prevReplayTLI = *replayTLI;
1934
0
    uint8   info = record->xl_info & ~XLR_INFO_MASK;
1935
1936
0
    if (info == XLOG_CHECKPOINT_SHUTDOWN)
1937
0
    {
1938
0
      CheckPoint  checkPoint;
1939
1940
0
      memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
1941
0
      newReplayTLI = checkPoint.ThisTimeLineID;
1942
0
      prevReplayTLI = checkPoint.PrevTimeLineID;
1943
0
    }
1944
0
    else if (info == XLOG_END_OF_RECOVERY)
1945
0
    {
1946
0
      xl_end_of_recovery xlrec;
1947
1948
0
      memcpy(&xlrec, XLogRecGetData(xlogreader), sizeof(xl_end_of_recovery));
1949
0
      newReplayTLI = xlrec.ThisTimeLineID;
1950
0
      prevReplayTLI = xlrec.PrevTimeLineID;
1951
0
    }
1952
1953
0
    if (newReplayTLI != *replayTLI)
1954
0
    {
1955
      /* Check that it's OK to switch to this TLI */
1956
0
      checkTimeLineSwitch(xlogreader->EndRecPtr,
1957
0
                newReplayTLI, prevReplayTLI, *replayTLI);
1958
1959
      /* Following WAL records should be run with new TLI */
1960
0
      *replayTLI = newReplayTLI;
1961
0
      switchedTLI = true;
1962
0
    }
1963
0
  }
1964
1965
  /*
1966
   * Update shared replayEndRecPtr before replaying this record, so that
1967
   * XLogFlush will update minRecoveryPoint correctly.
1968
   */
1969
0
  SpinLockAcquire(&XLogRecoveryCtl->info_lck);
1970
0
  XLogRecoveryCtl->replayEndRecPtr = xlogreader->EndRecPtr;
1971
0
  XLogRecoveryCtl->replayEndTLI = *replayTLI;
1972
0
  SpinLockRelease(&XLogRecoveryCtl->info_lck);
1973
1974
  /*
1975
   * If we are attempting to enter Hot Standby mode, process XIDs we see
1976
   */
1977
0
  if (standbyState >= STANDBY_INITIALIZED &&
1978
0
    TransactionIdIsValid(record->xl_xid))
1979
0
    RecordKnownAssignedTransactionIds(record->xl_xid);
1980
1981
  /*
1982
   * Some XLOG record types that are related to recovery are processed
1983
   * directly here, rather than in xlog_redo()
1984
   */
1985
0
  if (record->xl_rmid == RM_XLOG_ID)
1986
0
    xlogrecovery_redo(xlogreader, *replayTLI);
1987
1988
  /* Now apply the WAL record itself */
1989
0
  GetRmgr(record->xl_rmid).rm_redo(xlogreader);
1990
1991
  /*
1992
   * After redo, check whether the backup pages associated with the WAL
1993
   * record are consistent with the existing pages. This check is done only
1994
   * if consistency check is enabled for this record.
1995
   */
1996
0
  if ((record->xl_info & XLR_CHECK_CONSISTENCY) != 0)
1997
0
    verifyBackupPageConsistency(xlogreader);
1998
1999
  /* Pop the error context stack */
2000
0
  error_context_stack = errcallback.previous;
2001
2002
  /*
2003
   * Update lastReplayedEndRecPtr after this record has been successfully
2004
   * replayed.
2005
   */
2006
0
  SpinLockAcquire(&XLogRecoveryCtl->info_lck);
2007
0
  XLogRecoveryCtl->lastReplayedReadRecPtr = xlogreader->ReadRecPtr;
2008
0
  XLogRecoveryCtl->lastReplayedEndRecPtr = xlogreader->EndRecPtr;
2009
0
  XLogRecoveryCtl->lastReplayedTLI = *replayTLI;
2010
0
  SpinLockRelease(&XLogRecoveryCtl->info_lck);
2011
2012
  /* ------
2013
   * Wakeup walsenders:
2014
   *
2015
   * On the standby, the WAL is flushed first (which will only wake up
2016
   * physical walsenders) and then applied, which will only wake up logical
2017
   * walsenders.
2018
   *
2019
   * Indeed, logical walsenders on standby can't decode and send data until
2020
   * it's been applied.
2021
   *
2022
   * Physical walsenders don't need to be woken up during replay unless
2023
   * cascading replication is allowed and time line change occurred (so that
2024
   * they can notice that they are on a new time line).
2025
   *
2026
   * That's why the wake up conditions are for:
2027
   *
2028
   *  - physical walsenders in case of new time line and cascade
2029
   *    replication is allowed
2030
   *  - logical walsenders in case cascade replication is allowed (could not
2031
   *    be created otherwise)
2032
   * ------
2033
   */
2034
0
  if (AllowCascadeReplication())
2035
0
    WalSndWakeup(switchedTLI, true);
2036
2037
  /*
2038
   * If rm_redo called XLogRequestWalReceiverReply, then we wake up the
2039
   * receiver so that it notices the updated lastReplayedEndRecPtr and sends
2040
   * a reply to the primary.
2041
   */
2042
0
  if (doRequestWalReceiverReply)
2043
0
  {
2044
0
    doRequestWalReceiverReply = false;
2045
0
    WalRcvRequestApplyReply();
2046
0
  }
2047
2048
  /* Allow read-only connections if we're consistent now */
2049
0
  CheckRecoveryConsistency();
2050
2051
  /* Is this a timeline switch? */
2052
0
  if (switchedTLI)
2053
0
  {
2054
    /*
2055
     * Before we continue on the new timeline, clean up any (possibly
2056
     * bogus) future WAL segments on the old timeline.
2057
     */
2058
0
    RemoveNonParentXlogFiles(xlogreader->EndRecPtr, *replayTLI);
2059
2060
    /* Reset the prefetcher. */
2061
0
    XLogPrefetchReconfigure();
2062
0
  }
2063
0
}
2064
2065
/*
2066
 * Some XLOG RM record types that are directly related to WAL recovery are
2067
 * handled here rather than in the xlog_redo()
2068
 */
2069
static void
2070
xlogrecovery_redo(XLogReaderState *record, TimeLineID replayTLI)
2071
{
2072
  uint8   info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
2073
  XLogRecPtr  lsn = record->EndRecPtr;
2074
2075
  Assert(XLogRecGetRmid(record) == RM_XLOG_ID);
2076
2077
  if (info == XLOG_OVERWRITE_CONTRECORD)
2078
  {
2079
    /* Verify the payload of a XLOG_OVERWRITE_CONTRECORD record. */
2080
    xl_overwrite_contrecord xlrec;
2081
2082
    memcpy(&xlrec, XLogRecGetData(record), sizeof(xl_overwrite_contrecord));
2083
    if (xlrec.overwritten_lsn != record->overwrittenRecPtr)
2084
      elog(FATAL, "mismatching overwritten LSN %X/%08X -> %X/%08X",
2085
         LSN_FORMAT_ARGS(xlrec.overwritten_lsn),
2086
         LSN_FORMAT_ARGS(record->overwrittenRecPtr));
2087
2088
    /* We have safely skipped the aborted record */
2089
    abortedRecPtr = InvalidXLogRecPtr;
2090
    missingContrecPtr = InvalidXLogRecPtr;
2091
2092
    ereport(LOG,
2093
        errmsg("successfully skipped missing contrecord at %X/%08X, overwritten at %s",
2094
             LSN_FORMAT_ARGS(xlrec.overwritten_lsn),
2095
             timestamptz_to_str(xlrec.overwrite_time)));
2096
2097
    /* Verifying the record should only happen once */
2098
    record->overwrittenRecPtr = InvalidXLogRecPtr;
2099
  }
2100
  else if (info == XLOG_BACKUP_END)
2101
  {
2102
    XLogRecPtr  startpoint;
2103
2104
    memcpy(&startpoint, XLogRecGetData(record), sizeof(startpoint));
2105
2106
    if (backupStartPoint == startpoint)
2107
    {
2108
      /*
2109
       * We have reached the end of base backup, the point where
2110
       * pg_backup_stop() was done.  The data on disk is now consistent
2111
       * (assuming we have also reached minRecoveryPoint).  Set
2112
       * backupEndPoint to the current LSN, so that the next call to
2113
       * CheckRecoveryConsistency() will notice it and do the
2114
       * end-of-backup processing.
2115
       */
2116
      elog(DEBUG1, "end of backup record reached");
2117
2118
      backupEndPoint = lsn;
2119
    }
2120
    else
2121
      elog(DEBUG1, "saw end-of-backup record for backup starting at %X/%08X, waiting for %X/%08X",
2122
         LSN_FORMAT_ARGS(startpoint), LSN_FORMAT_ARGS(backupStartPoint));
2123
  }
2124
}
2125
2126
/*
2127
 * Verify that, in non-test mode, ./pg_tblspc doesn't contain any real
2128
 * directories.
2129
 *
2130
 * Replay of database creation XLOG records for databases that were later
2131
 * dropped can create fake directories in pg_tblspc.  By the time consistency
2132
 * is reached these directories should have been removed; here we verify
2133
 * that this did indeed happen.  This is to be called at the point where
2134
 * consistent state is reached.
2135
 *
2136
 * allow_in_place_tablespaces turns the PANIC into a WARNING, which is
2137
 * useful for testing purposes, and also allows for an escape hatch in case
2138
 * things go south.
2139
 */
2140
static void
2141
CheckTablespaceDirectory(void)
2142
0
{
2143
0
  DIR      *dir;
2144
0
  struct dirent *de;
2145
2146
0
  dir = AllocateDir(PG_TBLSPC_DIR);
2147
0
  while ((de = ReadDir(dir, PG_TBLSPC_DIR)) != NULL)
2148
0
  {
2149
0
    char    path[MAXPGPATH + sizeof(PG_TBLSPC_DIR)];
2150
2151
    /* Skip entries of non-oid names */
2152
0
    if (strspn(de->d_name, "0123456789") != strlen(de->d_name))
2153
0
      continue;
2154
2155
0
    snprintf(path, sizeof(path), "%s/%s", PG_TBLSPC_DIR, de->d_name);
2156
2157
0
    if (get_dirent_type(path, de, false, ERROR) != PGFILETYPE_LNK)
2158
0
      ereport(allow_in_place_tablespaces ? WARNING : PANIC,
2159
0
          (errcode(ERRCODE_DATA_CORRUPTED),
2160
0
           errmsg("unexpected directory entry \"%s\" found in %s",
2161
0
              de->d_name, PG_TBLSPC_DIR),
2162
0
           errdetail("All directory entries in %s/ should be symbolic links.",
2163
0
                 PG_TBLSPC_DIR),
2164
0
           errhint("Remove those directories, or set \"allow_in_place_tablespaces\" to ON transiently to let recovery complete.")));
2165
0
  }
2166
0
  FreeDir(dir);
2167
0
}
2168
2169
/*
2170
 * Checks if recovery has reached a consistent state. When consistency is
2171
 * reached and we have a valid starting standby snapshot, tell postmaster
2172
 * that it can start accepting read-only connections.
2173
 */
2174
static void
2175
CheckRecoveryConsistency(void)
2176
0
{
2177
0
  XLogRecPtr  lastReplayedEndRecPtr;
2178
0
  TimeLineID  lastReplayedTLI;
2179
2180
  /*
2181
   * During crash recovery, we don't reach a consistent state until we've
2182
   * replayed all the WAL.
2183
   */
2184
0
  if (!XLogRecPtrIsValid(minRecoveryPoint))
2185
0
    return;
2186
2187
0
  Assert(InArchiveRecovery);
2188
2189
  /*
2190
   * assume that we are called in the startup process, and hence don't need
2191
   * a lock to read lastReplayedEndRecPtr
2192
   */
2193
0
  lastReplayedEndRecPtr = XLogRecoveryCtl->lastReplayedEndRecPtr;
2194
0
  lastReplayedTLI = XLogRecoveryCtl->lastReplayedTLI;
2195
2196
  /*
2197
   * Have we reached the point where our base backup was completed?
2198
   */
2199
0
  if (XLogRecPtrIsValid(backupEndPoint) &&
2200
0
    backupEndPoint <= lastReplayedEndRecPtr)
2201
0
  {
2202
0
    XLogRecPtr  saveBackupStartPoint = backupStartPoint;
2203
0
    XLogRecPtr  saveBackupEndPoint = backupEndPoint;
2204
2205
0
    elog(DEBUG1, "end of backup reached");
2206
2207
    /*
2208
     * We have reached the end of base backup, as indicated by pg_control.
2209
     * Update the control file accordingly.
2210
     */
2211
0
    ReachedEndOfBackup(lastReplayedEndRecPtr, lastReplayedTLI);
2212
0
    backupStartPoint = InvalidXLogRecPtr;
2213
0
    backupEndPoint = InvalidXLogRecPtr;
2214
0
    backupEndRequired = false;
2215
2216
0
    ereport(LOG,
2217
0
        errmsg("completed backup recovery with redo LSN %X/%08X and end LSN %X/%08X",
2218
0
             LSN_FORMAT_ARGS(saveBackupStartPoint),
2219
0
             LSN_FORMAT_ARGS(saveBackupEndPoint)));
2220
0
  }
2221
2222
  /*
2223
   * Have we passed our safe starting point? Note that minRecoveryPoint is
2224
   * known to be incorrectly set if recovering from a backup, until the
2225
   * XLOG_BACKUP_END arrives to advise us of the correct minRecoveryPoint.
2226
   * All we know prior to that is that we're not consistent yet.
2227
   */
2228
0
  if (!reachedConsistency && !backupEndRequired &&
2229
0
    minRecoveryPoint <= lastReplayedEndRecPtr)
2230
0
  {
2231
    /*
2232
     * Check to see if the XLOG sequence contained any unresolved
2233
     * references to uninitialized pages.
2234
     */
2235
0
    XLogCheckInvalidPages();
2236
2237
    /*
2238
     * Check that pg_tblspc doesn't contain any real directories. Replay
2239
     * of Database/CREATE_* records may have created fictitious tablespace
2240
     * directories that should have been removed by the time consistency
2241
     * was reached.
2242
     */
2243
0
    CheckTablespaceDirectory();
2244
2245
0
    reachedConsistency = true;
2246
0
    SendPostmasterSignal(PMSIGNAL_RECOVERY_CONSISTENT);
2247
0
    ereport(LOG,
2248
0
        errmsg("consistent recovery state reached at %X/%08X",
2249
0
             LSN_FORMAT_ARGS(lastReplayedEndRecPtr)));
2250
0
  }
2251
2252
  /*
2253
   * Have we got a valid starting snapshot that will allow queries to be
2254
   * run? If so, we can tell postmaster that the database is consistent now,
2255
   * enabling connections.
2256
   */
2257
0
  if (standbyState == STANDBY_SNAPSHOT_READY &&
2258
0
    !LocalHotStandbyActive &&
2259
0
    reachedConsistency &&
2260
0
    IsUnderPostmaster)
2261
0
  {
2262
0
    SpinLockAcquire(&XLogRecoveryCtl->info_lck);
2263
0
    XLogRecoveryCtl->SharedHotStandbyActive = true;
2264
0
    SpinLockRelease(&XLogRecoveryCtl->info_lck);
2265
2266
0
    LocalHotStandbyActive = true;
2267
2268
0
    SendPostmasterSignal(PMSIGNAL_BEGIN_HOT_STANDBY);
2269
0
  }
2270
0
}
2271
2272
/*
2273
 * Error context callback for errors occurring during rm_redo().
2274
 */
2275
static void
2276
rm_redo_error_callback(void *arg)
2277
0
{
2278
0
  XLogReaderState *record = (XLogReaderState *) arg;
2279
0
  StringInfoData buf;
2280
2281
0
  initStringInfo(&buf);
2282
0
  xlog_outdesc(&buf, record);
2283
0
  xlog_block_info(&buf, record);
2284
2285
  /* translator: %s is a WAL record description */
2286
0
  errcontext("WAL redo at %X/%08X for %s",
2287
0
         LSN_FORMAT_ARGS(record->ReadRecPtr),
2288
0
         buf.data);
2289
2290
0
  pfree(buf.data);
2291
0
}
2292
2293
/*
2294
 * Returns a string describing an XLogRecord, consisting of its identity
2295
 * optionally followed by a colon, a space, and a further description.
2296
 */
2297
void
2298
xlog_outdesc(StringInfo buf, XLogReaderState *record)
2299
0
{
2300
0
  RmgrData  rmgr = GetRmgr(XLogRecGetRmid(record));
2301
0
  uint8   info = XLogRecGetInfo(record);
2302
0
  const char *id;
2303
2304
0
  appendStringInfoString(buf, rmgr.rm_name);
2305
0
  appendStringInfoChar(buf, '/');
2306
2307
0
  id = rmgr.rm_identify(info);
2308
0
  if (id == NULL)
2309
0
    appendStringInfo(buf, "UNKNOWN (%X): ", info & ~XLR_INFO_MASK);
2310
0
  else
2311
0
    appendStringInfo(buf, "%s: ", id);
2312
2313
0
  rmgr.rm_desc(buf, record);
2314
0
}
2315
2316
#ifdef WAL_DEBUG
2317
2318
static void
2319
xlog_outrec(StringInfo buf, XLogReaderState *record)
2320
{
2321
  appendStringInfo(buf, "prev %X/%08X; xid %u",
2322
           LSN_FORMAT_ARGS(XLogRecGetPrev(record)),
2323
           XLogRecGetXid(record));
2324
2325
  appendStringInfo(buf, "; len %u",
2326
           XLogRecGetDataLen(record));
2327
2328
  xlog_block_info(buf, record);
2329
}
2330
#endif              /* WAL_DEBUG */
2331
2332
/*
2333
 * Returns a string giving information about all the blocks in an
2334
 * XLogRecord.
2335
 */
2336
static void
2337
xlog_block_info(StringInfo buf, XLogReaderState *record)
2338
0
{
2339
0
  int     block_id;
2340
2341
  /* decode block references */
2342
0
  for (block_id = 0; block_id <= XLogRecMaxBlockId(record); block_id++)
2343
0
  {
2344
0
    RelFileLocator rlocator;
2345
0
    ForkNumber  forknum;
2346
0
    BlockNumber blk;
2347
2348
0
    if (!XLogRecGetBlockTagExtended(record, block_id,
2349
0
                    &rlocator, &forknum, &blk, NULL))
2350
0
      continue;
2351
2352
0
    if (forknum != MAIN_FORKNUM)
2353
0
      appendStringInfo(buf, "; blkref #%d: rel %u/%u/%u, fork %u, blk %u",
2354
0
               block_id,
2355
0
               rlocator.spcOid, rlocator.dbOid,
2356
0
               rlocator.relNumber,
2357
0
               forknum,
2358
0
               blk);
2359
0
    else
2360
0
      appendStringInfo(buf, "; blkref #%d: rel %u/%u/%u, blk %u",
2361
0
               block_id,
2362
0
               rlocator.spcOid, rlocator.dbOid,
2363
0
               rlocator.relNumber,
2364
0
               blk);
2365
0
    if (XLogRecHasBlockImage(record, block_id))
2366
0
      appendStringInfoString(buf, " FPW");
2367
0
  }
2368
0
}
2369
2370
2371
/*
2372
 * Check that it's OK to switch to new timeline during recovery.
2373
 *
2374
 * 'lsn' is the address of the shutdown checkpoint record we're about to
2375
 * replay. (Currently, timeline can only change at a shutdown checkpoint).
2376
 */
2377
static void
2378
checkTimeLineSwitch(XLogRecPtr lsn, TimeLineID newTLI, TimeLineID prevTLI,
2379
          TimeLineID replayTLI)
2380
0
{
2381
  /* Check that the record agrees on what the current (old) timeline is */
2382
0
  if (prevTLI != replayTLI)
2383
0
    ereport(PANIC,
2384
0
        (errmsg("unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record",
2385
0
            prevTLI, replayTLI)));
2386
2387
  /*
2388
   * The new timeline better be in the list of timelines we expect to see,
2389
   * according to the timeline history. It should also not decrease.
2390
   */
2391
0
  if (newTLI < replayTLI || !tliInHistory(newTLI, expectedTLEs))
2392
0
    ereport(PANIC,
2393
0
        (errmsg("unexpected timeline ID %u (after %u) in checkpoint record",
2394
0
            newTLI, replayTLI)));
2395
2396
  /*
2397
   * If we have not yet reached min recovery point, and we're about to
2398
   * switch to a timeline greater than the timeline of the min recovery
2399
   * point: trouble. After switching to the new timeline, we could not
2400
   * possibly visit the min recovery point on the correct timeline anymore.
2401
   * This can happen if there is a newer timeline in the archive that
2402
   * branched before the timeline the min recovery point is on, and you
2403
   * attempt to do PITR to the new timeline.
2404
   */
2405
0
  if (XLogRecPtrIsValid(minRecoveryPoint) &&
2406
0
    lsn < minRecoveryPoint &&
2407
0
    newTLI > minRecoveryPointTLI)
2408
0
    ereport(PANIC,
2409
0
        errmsg("unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%08X on timeline %u",
2410
0
             newTLI,
2411
0
             LSN_FORMAT_ARGS(minRecoveryPoint),
2412
0
             minRecoveryPointTLI));
2413
2414
  /* Looks good */
2415
0
}
2416
2417
2418
/*
2419
 * Extract timestamp from WAL record.
2420
 *
2421
 * If the record contains a timestamp, returns true, and saves the timestamp
2422
 * in *recordXtime. If the record type has no timestamp, returns false.
2423
 * Currently, only transaction commit/abort records and restore points contain
2424
 * timestamps.
2425
 */
2426
static bool
2427
getRecordTimestamp(XLogReaderState *record, TimestampTz *recordXtime)
2428
0
{
2429
0
  uint8   info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
2430
0
  uint8   xact_info = info & XLOG_XACT_OPMASK;
2431
0
  uint8   rmid = XLogRecGetRmid(record);
2432
2433
0
  if (rmid == RM_XLOG_ID && info == XLOG_RESTORE_POINT)
2434
0
  {
2435
0
    *recordXtime = ((xl_restore_point *) XLogRecGetData(record))->rp_time;
2436
0
    return true;
2437
0
  }
2438
0
  if (rmid == RM_XACT_ID && (xact_info == XLOG_XACT_COMMIT ||
2439
0
                 xact_info == XLOG_XACT_COMMIT_PREPARED))
2440
0
  {
2441
0
    *recordXtime = ((xl_xact_commit *) XLogRecGetData(record))->xact_time;
2442
0
    return true;
2443
0
  }
2444
0
  if (rmid == RM_XACT_ID && (xact_info == XLOG_XACT_ABORT ||
2445
0
                 xact_info == XLOG_XACT_ABORT_PREPARED))
2446
0
  {
2447
0
    *recordXtime = ((xl_xact_abort *) XLogRecGetData(record))->xact_time;
2448
0
    return true;
2449
0
  }
2450
0
  return false;
2451
0
}
2452
2453
/*
2454
 * Checks whether the current buffer page and backup page stored in the
2455
 * WAL record are consistent or not. Before comparing the two pages, a
2456
 * masking can be applied to the pages to ignore certain areas like hint bits,
2457
 * unused space between pd_lower and pd_upper among other things. This
2458
 * function should be called once WAL replay has been completed for a
2459
 * given record.
2460
 */
2461
static void
2462
verifyBackupPageConsistency(XLogReaderState *record)
2463
0
{
2464
0
  RmgrData  rmgr = GetRmgr(XLogRecGetRmid(record));
2465
0
  RelFileLocator rlocator;
2466
0
  ForkNumber  forknum;
2467
0
  BlockNumber blkno;
2468
0
  int     block_id;
2469
2470
  /* Records with no backup blocks have no need for consistency checks. */
2471
0
  if (!XLogRecHasAnyBlockRefs(record))
2472
0
    return;
2473
2474
0
  Assert((XLogRecGetInfo(record) & XLR_CHECK_CONSISTENCY) != 0);
2475
2476
0
  for (block_id = 0; block_id <= XLogRecMaxBlockId(record); block_id++)
2477
0
  {
2478
0
    Buffer    buf;
2479
0
    Page    page;
2480
2481
0
    if (!XLogRecGetBlockTagExtended(record, block_id,
2482
0
                    &rlocator, &forknum, &blkno, NULL))
2483
0
    {
2484
      /*
2485
       * WAL record doesn't contain a block reference with the given id.
2486
       * Do nothing.
2487
       */
2488
0
      continue;
2489
0
    }
2490
2491
    /*
2492
     * Blocks registered with REGBUF_NO_CHANGE may have no image, see
2493
     * XLogRecordAssemble().  Nothing to compare for these.
2494
     */
2495
0
    if (!XLogRecHasBlockImage(record, block_id))
2496
0
      continue;
2497
2498
0
    if (XLogRecBlockImageApply(record, block_id))
2499
0
    {
2500
      /*
2501
       * WAL record has already applied the page, so bypass the
2502
       * consistency check as that would result in comparing the full
2503
       * page stored in the record with itself.
2504
       */
2505
0
      continue;
2506
0
    }
2507
2508
    /*
2509
     * Read the contents from the current buffer and store it in a
2510
     * temporary page.
2511
     */
2512
0
    buf = XLogReadBufferExtended(rlocator, forknum, blkno,
2513
0
                   RBM_NORMAL_NO_LOG,
2514
0
                   InvalidBuffer);
2515
0
    if (!BufferIsValid(buf))
2516
0
      continue;
2517
2518
0
    LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
2519
0
    page = BufferGetPage(buf);
2520
2521
    /*
2522
     * Take a copy of the local page where WAL has been applied to have a
2523
     * comparison base before masking it...
2524
     */
2525
0
    memcpy(replay_image_masked, page, BLCKSZ);
2526
2527
    /* No need for this page anymore now that a copy is in. */
2528
0
    UnlockReleaseBuffer(buf);
2529
2530
    /*
2531
     * If the block LSN is already ahead of this WAL record, we can't
2532
     * expect contents to match.  This can happen if recovery is
2533
     * restarted.
2534
     */
2535
0
    if (PageGetLSN(replay_image_masked) > record->EndRecPtr)
2536
0
      continue;
2537
2538
    /*
2539
     * Read the contents from the backup copy, stored in WAL record and
2540
     * store it in a temporary page. There is no need to allocate a new
2541
     * page here, a local buffer is fine to hold its contents and a mask
2542
     * can be directly applied on it.
2543
     */
2544
0
    if (!RestoreBlockImage(record, block_id, primary_image_masked))
2545
0
      ereport(ERROR,
2546
0
          (errcode(ERRCODE_INTERNAL_ERROR),
2547
0
           errmsg_internal("%s", record->errormsg_buf)));
2548
2549
    /*
2550
     * If masking function is defined, mask both the primary and replay
2551
     * images
2552
     */
2553
0
    if (rmgr.rm_mask != NULL)
2554
0
    {
2555
0
      rmgr.rm_mask(replay_image_masked, blkno);
2556
0
      rmgr.rm_mask(primary_image_masked, blkno);
2557
0
    }
2558
2559
    /* Time to compare the primary and replay images. */
2560
0
    if (memcmp(replay_image_masked, primary_image_masked, BLCKSZ) != 0)
2561
0
    {
2562
0
      elog(FATAL,
2563
0
         "inconsistent page found, rel %u/%u/%u, forknum %u, blkno %u",
2564
0
         rlocator.spcOid, rlocator.dbOid, rlocator.relNumber,
2565
0
         forknum, blkno);
2566
0
    }
2567
0
  }
2568
0
}
2569
2570
/*
2571
 * For point-in-time recovery, this function decides whether we want to
2572
 * stop applying the XLOG before the current record.
2573
 *
2574
 * Returns true if we are stopping, false otherwise. If stopping, some
2575
 * information is saved in recoveryStopXid et al for use in annotating the
2576
 * new timeline's history file.
2577
 */
2578
static bool
2579
recoveryStopsBefore(XLogReaderState *record)
2580
{
2581
  bool    stopsHere = false;
2582
  uint8   xact_info;
2583
  bool    isCommit;
2584
  TimestampTz recordXtime = 0;
2585
  TransactionId recordXid;
2586
2587
  /*
2588
   * Ignore recovery target settings when not in archive recovery (meaning
2589
   * we are in crash recovery).
2590
   */
2591
  if (!ArchiveRecoveryRequested)
2592
    return false;
2593
2594
  /* Check if we should stop as soon as reaching consistency */
2595
  if (recoveryTarget == RECOVERY_TARGET_IMMEDIATE && reachedConsistency)
2596
  {
2597
    ereport(LOG,
2598
        (errmsg("recovery stopping after reaching consistency")));
2599
2600
    recoveryStopAfter = false;
2601
    recoveryStopXid = InvalidTransactionId;
2602
    recoveryStopLSN = InvalidXLogRecPtr;
2603
    recoveryStopTime = 0;
2604
    recoveryStopName[0] = '\0';
2605
    return true;
2606
  }
2607
2608
  /* Check if target LSN has been reached */
2609
  if (recoveryTarget == RECOVERY_TARGET_LSN &&
2610
    !recoveryTargetInclusive &&
2611
    record->ReadRecPtr >= recoveryTargetLSN)
2612
  {
2613
    recoveryStopAfter = false;
2614
    recoveryStopXid = InvalidTransactionId;
2615
    recoveryStopLSN = record->ReadRecPtr;
2616
    recoveryStopTime = 0;
2617
    recoveryStopName[0] = '\0';
2618
    ereport(LOG,
2619
        errmsg("recovery stopping before WAL location (LSN) \"%X/%08X\"",
2620
             LSN_FORMAT_ARGS(recoveryStopLSN)));
2621
    return true;
2622
  }
2623
2624
  /* Otherwise we only consider stopping before COMMIT or ABORT records. */
2625
  if (XLogRecGetRmid(record) != RM_XACT_ID)
2626
    return false;
2627
2628
  xact_info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
2629
2630
  if (xact_info == XLOG_XACT_COMMIT)
2631
  {
2632
    isCommit = true;
2633
    recordXid = XLogRecGetXid(record);
2634
  }
2635
  else if (xact_info == XLOG_XACT_COMMIT_PREPARED)
2636
  {
2637
    xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
2638
    xl_xact_parsed_commit parsed;
2639
2640
    isCommit = true;
2641
    ParseCommitRecord(XLogRecGetInfo(record),
2642
              xlrec,
2643
              &parsed);
2644
    recordXid = parsed.twophase_xid;
2645
  }
2646
  else if (xact_info == XLOG_XACT_ABORT)
2647
  {
2648
    isCommit = false;
2649
    recordXid = XLogRecGetXid(record);
2650
  }
2651
  else if (xact_info == XLOG_XACT_ABORT_PREPARED)
2652
  {
2653
    xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
2654
    xl_xact_parsed_abort parsed;
2655
2656
    isCommit = false;
2657
    ParseAbortRecord(XLogRecGetInfo(record),
2658
             xlrec,
2659
             &parsed);
2660
    recordXid = parsed.twophase_xid;
2661
  }
2662
  else
2663
    return false;
2664
2665
  if (recoveryTarget == RECOVERY_TARGET_XID && !recoveryTargetInclusive)
2666
  {
2667
    /*
2668
     * There can be only one transaction end record with this exact
2669
     * transactionid
2670
     *
2671
     * when testing for an xid, we MUST test for equality only, since
2672
     * transactions are numbered in the order they start, not the order
2673
     * they complete. A higher numbered xid will complete before you about
2674
     * 50% of the time...
2675
     */
2676
    stopsHere = (recordXid == recoveryTargetXid);
2677
  }
2678
2679
  /*
2680
   * Note: we must fetch recordXtime regardless of recoveryTarget setting.
2681
   * We don't expect getRecordTimestamp ever to fail, since we already know
2682
   * this is a commit or abort record; but test its result anyway.
2683
   */
2684
  if (getRecordTimestamp(record, &recordXtime) &&
2685
    recoveryTarget == RECOVERY_TARGET_TIME)
2686
  {
2687
    /*
2688
     * There can be many transactions that share the same commit time, so
2689
     * we stop after the last one, if we are inclusive, or stop at the
2690
     * first one if we are exclusive
2691
     */
2692
    if (recoveryTargetInclusive)
2693
      stopsHere = (recordXtime > recoveryTargetTime);
2694
    else
2695
      stopsHere = (recordXtime >= recoveryTargetTime);
2696
  }
2697
2698
  if (stopsHere)
2699
  {
2700
    recoveryStopAfter = false;
2701
    recoveryStopXid = recordXid;
2702
    recoveryStopTime = recordXtime;
2703
    recoveryStopLSN = InvalidXLogRecPtr;
2704
    recoveryStopName[0] = '\0';
2705
2706
    if (isCommit)
2707
    {
2708
      ereport(LOG,
2709
          (errmsg("recovery stopping before commit of transaction %u, time %s",
2710
              recoveryStopXid,
2711
              timestamptz_to_str(recoveryStopTime))));
2712
    }
2713
    else
2714
    {
2715
      ereport(LOG,
2716
          (errmsg("recovery stopping before abort of transaction %u, time %s",
2717
              recoveryStopXid,
2718
              timestamptz_to_str(recoveryStopTime))));
2719
    }
2720
  }
2721
2722
  return stopsHere;
2723
}
2724
2725
/*
2726
 * Same as recoveryStopsBefore, but called after applying the record.
2727
 *
2728
 * We also track the timestamp of the latest applied COMMIT/ABORT
2729
 * record in XLogRecoveryCtl->recoveryLastXTime.
2730
 */
2731
static bool
2732
recoveryStopsAfter(XLogReaderState *record)
2733
{
2734
  uint8   info;
2735
  uint8   xact_info;
2736
  uint8   rmid;
2737
  TimestampTz recordXtime = 0;
2738
2739
  /*
2740
   * Ignore recovery target settings when not in archive recovery (meaning
2741
   * we are in crash recovery).
2742
   */
2743
  if (!ArchiveRecoveryRequested)
2744
    return false;
2745
2746
  info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
2747
  rmid = XLogRecGetRmid(record);
2748
2749
  /*
2750
   * There can be many restore points that share the same name; we stop at
2751
   * the first one.
2752
   */
2753
  if (recoveryTarget == RECOVERY_TARGET_NAME &&
2754
    rmid == RM_XLOG_ID && info == XLOG_RESTORE_POINT)
2755
  {
2756
    xl_restore_point *recordRestorePointData;
2757
2758
    recordRestorePointData = (xl_restore_point *) XLogRecGetData(record);
2759
2760
    if (strcmp(recordRestorePointData->rp_name, recoveryTargetName) == 0)
2761
    {
2762
      recoveryStopAfter = true;
2763
      recoveryStopXid = InvalidTransactionId;
2764
      recoveryStopLSN = InvalidXLogRecPtr;
2765
      (void) getRecordTimestamp(record, &recoveryStopTime);
2766
      strlcpy(recoveryStopName, recordRestorePointData->rp_name, MAXFNAMELEN);
2767
2768
      ereport(LOG,
2769
          (errmsg("recovery stopping at restore point \"%s\", time %s",
2770
              recoveryStopName,
2771
              timestamptz_to_str(recoveryStopTime))));
2772
      return true;
2773
    }
2774
  }
2775
2776
  /* Check if the target LSN has been reached */
2777
  if (recoveryTarget == RECOVERY_TARGET_LSN &&
2778
    recoveryTargetInclusive &&
2779
    record->ReadRecPtr >= recoveryTargetLSN)
2780
  {
2781
    recoveryStopAfter = true;
2782
    recoveryStopXid = InvalidTransactionId;
2783
    recoveryStopLSN = record->ReadRecPtr;
2784
    recoveryStopTime = 0;
2785
    recoveryStopName[0] = '\0';
2786
    ereport(LOG,
2787
        errmsg("recovery stopping after WAL location (LSN) \"%X/%08X\"",
2788
             LSN_FORMAT_ARGS(recoveryStopLSN)));
2789
    return true;
2790
  }
2791
2792
  if (rmid != RM_XACT_ID)
2793
    return false;
2794
2795
  xact_info = info & XLOG_XACT_OPMASK;
2796
2797
  if (xact_info == XLOG_XACT_COMMIT ||
2798
    xact_info == XLOG_XACT_COMMIT_PREPARED ||
2799
    xact_info == XLOG_XACT_ABORT ||
2800
    xact_info == XLOG_XACT_ABORT_PREPARED)
2801
  {
2802
    TransactionId recordXid;
2803
2804
    /* Update the last applied transaction timestamp */
2805
    if (getRecordTimestamp(record, &recordXtime))
2806
      SetLatestXTime(recordXtime);
2807
2808
    /* Extract the XID of the committed/aborted transaction */
2809
    if (xact_info == XLOG_XACT_COMMIT_PREPARED)
2810
    {
2811
      xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
2812
      xl_xact_parsed_commit parsed;
2813
2814
      ParseCommitRecord(XLogRecGetInfo(record),
2815
                xlrec,
2816
                &parsed);
2817
      recordXid = parsed.twophase_xid;
2818
    }
2819
    else if (xact_info == XLOG_XACT_ABORT_PREPARED)
2820
    {
2821
      xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
2822
      xl_xact_parsed_abort parsed;
2823
2824
      ParseAbortRecord(XLogRecGetInfo(record),
2825
               xlrec,
2826
               &parsed);
2827
      recordXid = parsed.twophase_xid;
2828
    }
2829
    else
2830
      recordXid = XLogRecGetXid(record);
2831
2832
    /*
2833
     * There can be only one transaction end record with this exact
2834
     * transactionid
2835
     *
2836
     * when testing for an xid, we MUST test for equality only, since
2837
     * transactions are numbered in the order they start, not the order
2838
     * they complete. A higher numbered xid will complete before you about
2839
     * 50% of the time...
2840
     */
2841
    if (recoveryTarget == RECOVERY_TARGET_XID && recoveryTargetInclusive &&
2842
      recordXid == recoveryTargetXid)
2843
    {
2844
      recoveryStopAfter = true;
2845
      recoveryStopXid = recordXid;
2846
      recoveryStopTime = recordXtime;
2847
      recoveryStopLSN = InvalidXLogRecPtr;
2848
      recoveryStopName[0] = '\0';
2849
2850
      if (xact_info == XLOG_XACT_COMMIT ||
2851
        xact_info == XLOG_XACT_COMMIT_PREPARED)
2852
      {
2853
        ereport(LOG,
2854
            (errmsg("recovery stopping after commit of transaction %u, time %s",
2855
                recoveryStopXid,
2856
                timestamptz_to_str(recoveryStopTime))));
2857
      }
2858
      else if (xact_info == XLOG_XACT_ABORT ||
2859
           xact_info == XLOG_XACT_ABORT_PREPARED)
2860
      {
2861
        ereport(LOG,
2862
            (errmsg("recovery stopping after abort of transaction %u, time %s",
2863
                recoveryStopXid,
2864
                timestamptz_to_str(recoveryStopTime))));
2865
      }
2866
      return true;
2867
    }
2868
  }
2869
2870
  /* Check if we should stop as soon as reaching consistency */
2871
  if (recoveryTarget == RECOVERY_TARGET_IMMEDIATE && reachedConsistency)
2872
  {
2873
    ereport(LOG,
2874
        (errmsg("recovery stopping after reaching consistency")));
2875
2876
    recoveryStopAfter = true;
2877
    recoveryStopXid = InvalidTransactionId;
2878
    recoveryStopTime = 0;
2879
    recoveryStopLSN = InvalidXLogRecPtr;
2880
    recoveryStopName[0] = '\0';
2881
    return true;
2882
  }
2883
2884
  return false;
2885
}
2886
2887
/*
2888
 * Create a comment for the history file to explain why and where
2889
 * timeline changed.
2890
 */
2891
static char *
2892
getRecoveryStopReason(void)
2893
0
{
2894
0
  char    reason[200];
2895
2896
0
  if (recoveryTarget == RECOVERY_TARGET_XID)
2897
0
    snprintf(reason, sizeof(reason),
2898
0
         "%s transaction %u",
2899
0
         recoveryStopAfter ? "after" : "before",
2900
0
         recoveryStopXid);
2901
0
  else if (recoveryTarget == RECOVERY_TARGET_TIME)
2902
0
    snprintf(reason, sizeof(reason),
2903
0
         "%s %s\n",
2904
0
         recoveryStopAfter ? "after" : "before",
2905
0
         timestamptz_to_str(recoveryStopTime));
2906
0
  else if (recoveryTarget == RECOVERY_TARGET_LSN)
2907
0
    snprintf(reason, sizeof(reason),
2908
0
         "%s LSN %X/%08X\n",
2909
0
         recoveryStopAfter ? "after" : "before",
2910
0
         LSN_FORMAT_ARGS(recoveryStopLSN));
2911
0
  else if (recoveryTarget == RECOVERY_TARGET_NAME)
2912
0
    snprintf(reason, sizeof(reason),
2913
0
         "at restore point \"%s\"",
2914
0
         recoveryStopName);
2915
0
  else if (recoveryTarget == RECOVERY_TARGET_IMMEDIATE)
2916
0
    snprintf(reason, sizeof(reason), "reached consistency");
2917
0
  else
2918
0
    snprintf(reason, sizeof(reason), "no recovery target specified");
2919
2920
0
  return pstrdup(reason);
2921
0
}
2922
2923
/*
2924
 * Wait until shared recoveryPauseState is set to RECOVERY_NOT_PAUSED.
2925
 *
2926
 * endOfRecovery is true if the recovery target is reached and
2927
 * the paused state starts at the end of recovery because of
2928
 * recovery_target_action=pause, and false otherwise.
2929
 */
2930
static void
2931
recoveryPausesHere(bool endOfRecovery)
2932
0
{
2933
  /* Don't pause unless users can connect! */
2934
0
  if (!LocalHotStandbyActive)
2935
0
    return;
2936
2937
  /* Don't pause after standby promotion has been triggered */
2938
0
  if (LocalPromoteIsTriggered)
2939
0
    return;
2940
2941
0
  if (endOfRecovery)
2942
0
    ereport(LOG,
2943
0
        (errmsg("pausing at the end of recovery"),
2944
0
         errhint("Execute pg_wal_replay_resume() to promote.")));
2945
0
  else
2946
0
    ereport(LOG,
2947
0
        (errmsg("recovery has paused"),
2948
0
         errhint("Execute pg_wal_replay_resume() to continue.")));
2949
2950
  /* loop until recoveryPauseState is set to RECOVERY_NOT_PAUSED */
2951
0
  while (GetRecoveryPauseState() != RECOVERY_NOT_PAUSED)
2952
0
  {
2953
0
    ProcessStartupProcInterrupts();
2954
0
    if (CheckForStandbyTrigger())
2955
0
      return;
2956
2957
    /*
2958
     * If recovery pause is requested then set it paused.  While we are in
2959
     * the loop, user might resume and pause again so set this every time.
2960
     */
2961
0
    ConfirmRecoveryPaused();
2962
2963
    /*
2964
     * We wait on a condition variable that will wake us as soon as the
2965
     * pause ends, but we use a timeout so we can check the above exit
2966
     * condition periodically too.
2967
     */
2968
0
    ConditionVariableTimedSleep(&XLogRecoveryCtl->recoveryNotPausedCV, 1000,
2969
0
                  WAIT_EVENT_RECOVERY_PAUSE);
2970
0
  }
2971
0
  ConditionVariableCancelSleep();
2972
0
}
2973
2974
/*
2975
 * When recovery_min_apply_delay is set, we wait long enough to make sure
2976
 * certain record types are applied at least that interval behind the primary.
2977
 *
2978
 * Returns true if we waited.
2979
 *
2980
 * Note that the delay is calculated between the WAL record log time and
2981
 * the current time on standby. We would prefer to keep track of when this
2982
 * standby received each WAL record, which would allow a more consistent
2983
 * approach and one not affected by time synchronisation issues, but that
2984
 * is significantly more effort and complexity for little actual gain in
2985
 * usability.
2986
 */
2987
static bool
2988
recoveryApplyDelay(XLogReaderState *record)
2989
{
2990
  uint8   xact_info;
2991
  TimestampTz xtime;
2992
  TimestampTz delayUntil;
2993
  long    msecs;
2994
2995
  /* nothing to do if no delay configured */
2996
  if (recovery_min_apply_delay <= 0)
2997
    return false;
2998
2999
  /* no delay is applied on a database not yet consistent */
3000
  if (!reachedConsistency)
3001
    return false;
3002
3003
  /* nothing to do if crash recovery is requested */
3004
  if (!ArchiveRecoveryRequested)
3005
    return false;
3006
3007
  /*
3008
   * Is it a COMMIT record?
3009
   *
3010
   * We deliberately choose not to delay aborts since they have no effect on
3011
   * MVCC. We already allow replay of records that don't have a timestamp,
3012
   * so there is already opportunity for issues caused by early conflicts on
3013
   * standbys.
3014
   */
3015
  if (XLogRecGetRmid(record) != RM_XACT_ID)
3016
    return false;
3017
3018
  xact_info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
3019
3020
  if (xact_info != XLOG_XACT_COMMIT &&
3021
    xact_info != XLOG_XACT_COMMIT_PREPARED)
3022
    return false;
3023
3024
  if (!getRecordTimestamp(record, &xtime))
3025
    return false;
3026
3027
  delayUntil = TimestampTzPlusMilliseconds(xtime, recovery_min_apply_delay);
3028
3029
  /*
3030
   * Exit without arming the latch if it's already past time to apply this
3031
   * record
3032
   */
3033
  msecs = TimestampDifferenceMilliseconds(GetCurrentTimestamp(), delayUntil);
3034
  if (msecs <= 0)
3035
    return false;
3036
3037
  while (true)
3038
  {
3039
    ResetLatch(&XLogRecoveryCtl->recoveryWakeupLatch);
3040
3041
    /* This might change recovery_min_apply_delay. */
3042
    ProcessStartupProcInterrupts();
3043
3044
    if (CheckForStandbyTrigger())
3045
      break;
3046
3047
    /*
3048
     * Recalculate delayUntil as recovery_min_apply_delay could have
3049
     * changed while waiting in this loop.
3050
     */
3051
    delayUntil = TimestampTzPlusMilliseconds(xtime, recovery_min_apply_delay);
3052
3053
    /*
3054
     * Wait for difference between GetCurrentTimestamp() and delayUntil.
3055
     */
3056
    msecs = TimestampDifferenceMilliseconds(GetCurrentTimestamp(),
3057
                        delayUntil);
3058
3059
    if (msecs <= 0)
3060
      break;
3061
3062
    elog(DEBUG2, "recovery apply delay %ld milliseconds", msecs);
3063
3064
    (void) WaitLatch(&XLogRecoveryCtl->recoveryWakeupLatch,
3065
             WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
3066
             msecs,
3067
             WAIT_EVENT_RECOVERY_APPLY_DELAY);
3068
  }
3069
  return true;
3070
}
3071
3072
/*
3073
 * Get the current state of the recovery pause request.
3074
 */
3075
RecoveryPauseState
3076
GetRecoveryPauseState(void)
3077
0
{
3078
0
  RecoveryPauseState state;
3079
3080
0
  SpinLockAcquire(&XLogRecoveryCtl->info_lck);
3081
0
  state = XLogRecoveryCtl->recoveryPauseState;
3082
0
  SpinLockRelease(&XLogRecoveryCtl->info_lck);
3083
3084
0
  return state;
3085
0
}
3086
3087
/*
3088
 * Set the recovery pause state.
3089
 *
3090
 * If recovery pause is requested then sets the recovery pause state to
3091
 * 'pause requested' if it is not already 'paused'.  Otherwise, sets it
3092
 * to 'not paused' to resume the recovery.  The recovery pause will be
3093
 * confirmed by the ConfirmRecoveryPaused.
3094
 */
3095
void
3096
SetRecoveryPause(bool recoveryPause)
3097
0
{
3098
0
  SpinLockAcquire(&XLogRecoveryCtl->info_lck);
3099
3100
0
  if (!recoveryPause)
3101
0
    XLogRecoveryCtl->recoveryPauseState = RECOVERY_NOT_PAUSED;
3102
0
  else if (XLogRecoveryCtl->recoveryPauseState == RECOVERY_NOT_PAUSED)
3103
0
    XLogRecoveryCtl->recoveryPauseState = RECOVERY_PAUSE_REQUESTED;
3104
3105
0
  SpinLockRelease(&XLogRecoveryCtl->info_lck);
3106
3107
0
  if (!recoveryPause)
3108
0
    ConditionVariableBroadcast(&XLogRecoveryCtl->recoveryNotPausedCV);
3109
0
}
3110
3111
/*
3112
 * Confirm the recovery pause by setting the recovery pause state to
3113
 * RECOVERY_PAUSED.
3114
 */
3115
static void
3116
ConfirmRecoveryPaused(void)
3117
0
{
3118
  /* If recovery pause is requested then set it paused */
3119
0
  SpinLockAcquire(&XLogRecoveryCtl->info_lck);
3120
0
  if (XLogRecoveryCtl->recoveryPauseState == RECOVERY_PAUSE_REQUESTED)
3121
0
    XLogRecoveryCtl->recoveryPauseState = RECOVERY_PAUSED;
3122
0
  SpinLockRelease(&XLogRecoveryCtl->info_lck);
3123
0
}
3124
3125
3126
/*
3127
 * Attempt to read the next XLOG record.
3128
 *
3129
 * Before first call, the reader needs to be positioned to the first record
3130
 * by calling XLogPrefetcherBeginRead().
3131
 *
3132
 * If no valid record is available, returns NULL, or fails if emode is PANIC.
3133
 * (emode must be either PANIC, LOG). In standby mode, retries until a valid
3134
 * record is available.
3135
 */
3136
static XLogRecord *
3137
ReadRecord(XLogPrefetcher *xlogprefetcher, int emode,
3138
       bool fetching_ckpt, TimeLineID replayTLI)
3139
0
{
3140
0
  XLogRecord *record;
3141
0
  XLogReaderState *xlogreader = XLogPrefetcherGetReader(xlogprefetcher);
3142
0
  XLogPageReadPrivate *private = (XLogPageReadPrivate *) xlogreader->private_data;
3143
3144
0
  Assert(AmStartupProcess() || !IsUnderPostmaster);
3145
3146
  /* Pass through parameters to XLogPageRead */
3147
0
  private->fetching_ckpt = fetching_ckpt;
3148
0
  private->emode = emode;
3149
0
  private->randAccess = !XLogRecPtrIsValid(xlogreader->ReadRecPtr);
3150
0
  private->replayTLI = replayTLI;
3151
3152
  /* This is the first attempt to read this page. */
3153
0
  lastSourceFailed = false;
3154
3155
0
  for (;;)
3156
0
  {
3157
0
    char     *errormsg;
3158
3159
0
    record = XLogPrefetcherReadRecord(xlogprefetcher, &errormsg);
3160
0
    if (record == NULL)
3161
0
    {
3162
      /*
3163
       * When we find that WAL ends in an incomplete record, keep track
3164
       * of that record.  After recovery is done, we'll write a record
3165
       * to indicate to downstream WAL readers that that portion is to
3166
       * be ignored.
3167
       *
3168
       * However, when ArchiveRecoveryRequested = true, we're going to
3169
       * switch to a new timeline at the end of recovery. We will only
3170
       * copy WAL over to the new timeline up to the end of the last
3171
       * complete record, so if we did this, we would later create an
3172
       * overwrite contrecord in the wrong place, breaking everything.
3173
       */
3174
0
      if (!ArchiveRecoveryRequested &&
3175
0
        XLogRecPtrIsValid(xlogreader->abortedRecPtr))
3176
0
      {
3177
0
        abortedRecPtr = xlogreader->abortedRecPtr;
3178
0
        missingContrecPtr = xlogreader->missingContrecPtr;
3179
0
      }
3180
3181
0
      if (readFile >= 0)
3182
0
      {
3183
0
        close(readFile);
3184
0
        readFile = -1;
3185
0
      }
3186
3187
      /*
3188
       * We only end up here without a message when XLogPageRead()
3189
       * failed - in that case we already logged something. In
3190
       * StandbyMode that only happens if we have been triggered, so we
3191
       * shouldn't loop anymore in that case.
3192
       */
3193
0
      if (errormsg)
3194
0
        ereport(emode_for_corrupt_record(emode, xlogreader->EndRecPtr),
3195
0
            (errmsg_internal("%s", errormsg) /* already translated */ ));
3196
0
    }
3197
3198
    /*
3199
     * Check page TLI is one of the expected values.
3200
     */
3201
0
    else if (!tliInHistory(xlogreader->latestPageTLI, expectedTLEs))
3202
0
    {
3203
0
      char    fname[MAXFNAMELEN];
3204
0
      XLogSegNo segno;
3205
0
      int32   offset;
3206
3207
0
      XLByteToSeg(xlogreader->latestPagePtr, segno, wal_segment_size);
3208
0
      offset = XLogSegmentOffset(xlogreader->latestPagePtr,
3209
0
                     wal_segment_size);
3210
0
      XLogFileName(fname, xlogreader->seg.ws_tli, segno,
3211
0
             wal_segment_size);
3212
0
      ereport(emode_for_corrupt_record(emode, xlogreader->EndRecPtr),
3213
0
          errmsg("unexpected timeline ID %u in WAL segment %s, LSN %X/%08X, offset %u",
3214
0
               xlogreader->latestPageTLI,
3215
0
               fname,
3216
0
               LSN_FORMAT_ARGS(xlogreader->latestPagePtr),
3217
0
               offset));
3218
0
      record = NULL;
3219
0
    }
3220
3221
0
    if (record)
3222
0
    {
3223
      /* Great, got a record */
3224
0
      return record;
3225
0
    }
3226
0
    else
3227
0
    {
3228
      /* No valid record available from this source */
3229
0
      lastSourceFailed = true;
3230
3231
      /*
3232
       * If archive recovery was requested, but we were still doing
3233
       * crash recovery, switch to archive recovery and retry using the
3234
       * offline archive. We have now replayed all the valid WAL in
3235
       * pg_wal, so we are presumably now consistent.
3236
       *
3237
       * We require that there's at least some valid WAL present in
3238
       * pg_wal, however (!fetching_ckpt).  We could recover using the
3239
       * WAL from the archive, even if pg_wal is completely empty, but
3240
       * we'd have no idea how far we'd have to replay to reach
3241
       * consistency.  So err on the safe side and give up.
3242
       */
3243
0
      if (!InArchiveRecovery && ArchiveRecoveryRequested &&
3244
0
        !fetching_ckpt)
3245
0
      {
3246
0
        ereport(DEBUG1,
3247
0
            (errmsg_internal("reached end of WAL in pg_wal, entering archive recovery")));
3248
0
        InArchiveRecovery = true;
3249
0
        if (StandbyModeRequested)
3250
0
          EnableStandbyMode();
3251
3252
0
        SwitchIntoArchiveRecovery(xlogreader->EndRecPtr, replayTLI);
3253
0
        minRecoveryPoint = xlogreader->EndRecPtr;
3254
0
        minRecoveryPointTLI = replayTLI;
3255
3256
0
        CheckRecoveryConsistency();
3257
3258
        /*
3259
         * Before we retry, reset lastSourceFailed and currentSource
3260
         * so that we will check the archive next.
3261
         */
3262
0
        lastSourceFailed = false;
3263
0
        currentSource = XLOG_FROM_ANY;
3264
3265
0
        continue;
3266
0
      }
3267
3268
      /* In standby mode, loop back to retry. Otherwise, give up. */
3269
0
      if (StandbyMode && !CheckForStandbyTrigger())
3270
0
        continue;
3271
0
      else
3272
0
        return NULL;
3273
0
    }
3274
0
  }
3275
0
}
3276
3277
/*
3278
 * Read the XLOG page containing targetPagePtr into readBuf (if not read
3279
 * already).  Returns number of bytes read, if the page is read successfully,
3280
 * or XLREAD_FAIL in case of errors.  When errors occur, they are ereport'ed,
3281
 * but only if they have not been previously reported.
3282
 *
3283
 * See XLogReaderRoutine.page_read for more details.
3284
 *
3285
 * While prefetching, xlogreader->nonblocking may be set.  In that case,
3286
 * returns XLREAD_WOULDBLOCK if we'd otherwise have to wait for more WAL.
3287
 *
3288
 * This is responsible for restoring files from archive as needed, as well
3289
 * as for waiting for the requested WAL record to arrive in standby mode.
3290
 *
3291
 * xlogreader->private_data->emode specifies the log level used for reporting
3292
 * "file not found" or "end of WAL" situations in archive recovery, or in
3293
 * standby mode when promotion is triggered. If set to WARNING or below,
3294
 * XLogPageRead() returns XLREAD_FAIL in those situations, on higher log
3295
 * levels the ereport() won't return.
3296
 *
3297
 * In standby mode, if after a successful return of XLogPageRead() the
3298
 * caller finds the record it's interested in to be broken, it should
3299
 * ereport the error with the level determined by
3300
 * emode_for_corrupt_record(), and then set lastSourceFailed
3301
 * and call XLogPageRead() again with the same arguments. This lets
3302
 * XLogPageRead() to try fetching the record from another source, or to
3303
 * sleep and retry.
3304
 */
3305
static int
3306
XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen,
3307
       XLogRecPtr targetRecPtr, char *readBuf)
3308
0
{
3309
0
  XLogPageReadPrivate *private =
3310
0
    (XLogPageReadPrivate *) xlogreader->private_data;
3311
0
  int     emode = private->emode;
3312
0
  uint32    targetPageOff;
3313
0
  XLogSegNo targetSegNo PG_USED_FOR_ASSERTS_ONLY;
3314
0
  ssize_t   r;
3315
0
  instr_time  io_start;
3316
3317
0
  Assert(AmStartupProcess() || !IsUnderPostmaster);
3318
3319
0
  XLByteToSeg(targetPagePtr, targetSegNo, wal_segment_size);
3320
0
  targetPageOff = XLogSegmentOffset(targetPagePtr, wal_segment_size);
3321
3322
  /*
3323
   * See if we need to switch to a new segment because the requested record
3324
   * is not in the currently open one.
3325
   */
3326
0
  if (readFile >= 0 &&
3327
0
    !XLByteInSeg(targetPagePtr, readSegNo, wal_segment_size))
3328
0
  {
3329
    /*
3330
     * Request a restartpoint if we've replayed too much xlog since the
3331
     * last one.
3332
     */
3333
0
    if (ArchiveRecoveryRequested && IsUnderPostmaster)
3334
0
    {
3335
0
      if (XLogCheckpointNeeded(readSegNo))
3336
0
      {
3337
0
        (void) GetRedoRecPtr();
3338
0
        if (XLogCheckpointNeeded(readSegNo))
3339
0
          RequestCheckpoint(CHECKPOINT_CAUSE_XLOG);
3340
0
      }
3341
0
    }
3342
3343
0
    close(readFile);
3344
0
    readFile = -1;
3345
0
    readSource = XLOG_FROM_ANY;
3346
0
  }
3347
3348
0
  XLByteToSeg(targetPagePtr, readSegNo, wal_segment_size);
3349
3350
0
retry:
3351
  /* See if we need to retrieve more data */
3352
0
  if (readFile < 0 ||
3353
0
    (readSource == XLOG_FROM_STREAM &&
3354
0
     flushedUpto < targetPagePtr + reqLen))
3355
0
  {
3356
0
    if (readFile >= 0 &&
3357
0
      xlogreader->nonblocking &&
3358
0
      readSource == XLOG_FROM_STREAM &&
3359
0
      flushedUpto < targetPagePtr + reqLen)
3360
0
      return XLREAD_WOULDBLOCK;
3361
3362
0
    switch (WaitForWALToBecomeAvailable(targetPagePtr + reqLen,
3363
0
                      private->randAccess,
3364
0
                      private->fetching_ckpt,
3365
0
                      targetRecPtr,
3366
0
                      private->replayTLI,
3367
0
                      xlogreader->EndRecPtr,
3368
0
                      xlogreader->nonblocking))
3369
0
    {
3370
0
      case XLREAD_WOULDBLOCK:
3371
0
        return XLREAD_WOULDBLOCK;
3372
0
      case XLREAD_FAIL:
3373
0
        if (readFile >= 0)
3374
0
          close(readFile);
3375
0
        readFile = -1;
3376
0
        readLen = 0;
3377
0
        readSource = XLOG_FROM_ANY;
3378
0
        return XLREAD_FAIL;
3379
0
      case XLREAD_SUCCESS:
3380
0
        break;
3381
0
    }
3382
0
  }
3383
3384
  /*
3385
   * At this point, we have the right segment open and if we're streaming we
3386
   * know the requested record is in it.
3387
   */
3388
0
  Assert(readFile != -1);
3389
3390
  /*
3391
   * If the current segment is being streamed from the primary, calculate
3392
   * how much of the current page we have received already. We know the
3393
   * requested record has been received, but this is for the benefit of
3394
   * future calls, to allow quick exit at the top of this function.
3395
   */
3396
0
  if (readSource == XLOG_FROM_STREAM)
3397
0
  {
3398
0
    if (((targetPagePtr) / XLOG_BLCKSZ) != (flushedUpto / XLOG_BLCKSZ))
3399
0
      readLen = XLOG_BLCKSZ;
3400
0
    else
3401
0
      readLen = XLogSegmentOffset(flushedUpto, wal_segment_size) -
3402
0
        targetPageOff;
3403
0
  }
3404
0
  else
3405
0
    readLen = XLOG_BLCKSZ;
3406
3407
  /* Read the requested page */
3408
0
  readOff = targetPageOff;
3409
3410
  /* Measure I/O timing when reading segment */
3411
0
  io_start = pgstat_prepare_io_time(track_wal_io_timing);
3412
3413
0
  pgstat_report_wait_start(WAIT_EVENT_WAL_READ);
3414
0
  r = pg_pread(readFile, readBuf, XLOG_BLCKSZ, (pgoff_t) readOff);
3415
0
  if (r != XLOG_BLCKSZ)
3416
0
  {
3417
0
    char    fname[MAXFNAMELEN];
3418
0
    int     save_errno = errno;
3419
3420
0
    pgstat_report_wait_end();
3421
3422
    /* Count I/O stats only for successful short reads */
3423
0
    if (r > 0)
3424
0
      pgstat_count_io_op_time(IOOBJECT_WAL, IOCONTEXT_NORMAL, IOOP_READ,
3425
0
                  io_start, 1, r);
3426
3427
0
    XLogFileName(fname, curFileTLI, readSegNo, wal_segment_size);
3428
0
    if (r < 0)
3429
0
    {
3430
0
      errno = save_errno;
3431
0
      ereport(emode_for_corrupt_record(emode, targetPagePtr + reqLen),
3432
0
          (errcode_for_file_access(),
3433
0
           errmsg("could not read from WAL segment %s, LSN %X/%08X, offset %u: %m",
3434
0
              fname, LSN_FORMAT_ARGS(targetPagePtr),
3435
0
              readOff)));
3436
0
    }
3437
0
    else
3438
0
      ereport(emode_for_corrupt_record(emode, targetPagePtr + reqLen),
3439
0
          (errcode(ERRCODE_DATA_CORRUPTED),
3440
0
           errmsg("could not read from WAL segment %s, LSN %X/%08X, offset %u: read %zd of %zu",
3441
0
              fname, LSN_FORMAT_ARGS(targetPagePtr),
3442
0
              readOff, r, (Size) XLOG_BLCKSZ)));
3443
0
    goto next_record_is_invalid;
3444
0
  }
3445
0
  pgstat_report_wait_end();
3446
3447
0
  pgstat_count_io_op_time(IOOBJECT_WAL, IOCONTEXT_NORMAL, IOOP_READ,
3448
0
              io_start, 1, r);
3449
3450
0
  Assert(targetSegNo == readSegNo);
3451
0
  Assert(targetPageOff == readOff);
3452
0
  Assert(reqLen <= readLen);
3453
3454
0
  xlogreader->seg.ws_tli = curFileTLI;
3455
3456
  /*
3457
   * Check the page header immediately, so that we can retry immediately if
3458
   * it's not valid. This may seem unnecessary, because ReadPageInternal()
3459
   * validates the page header anyway, and would propagate the failure up to
3460
   * ReadRecord(), which would retry. However, there's a corner case with
3461
   * continuation records, if a record is split across two pages such that
3462
   * we would need to read the two pages from different sources across two
3463
   * WAL segments.
3464
   *
3465
   * The first page is only available locally, in pg_wal, because it's
3466
   * already been recycled on the primary. The second page, however, is not
3467
   * present in pg_wal, and we should stream it from the primary. There is a
3468
   * recycled WAL segment present in pg_wal, with garbage contents, however.
3469
   * We would read the first page from the local WAL segment, but when
3470
   * reading the second page, we would read the bogus, recycled, WAL
3471
   * segment. If we didn't catch that case here, we would never recover,
3472
   * because ReadRecord() would retry reading the whole record from the
3473
   * beginning.
3474
   *
3475
   * Of course, this only catches errors in the page header, which is what
3476
   * happens in the case of a recycled WAL segment. Other kinds of errors or
3477
   * corruption still has the same problem. But this at least fixes the
3478
   * common case, which can happen as part of normal operation.
3479
   *
3480
   * Validating the page header is cheap enough that doing it twice
3481
   * shouldn't be a big deal from a performance point of view.
3482
   *
3483
   * When not in standby mode, an invalid page header should cause recovery
3484
   * to end, not retry reading the page, so we don't need to validate the
3485
   * page header here for the retry. Instead, ReadPageInternal() is
3486
   * responsible for the validation.
3487
   */
3488
0
  if (StandbyMode &&
3489
0
    (targetPagePtr % wal_segment_size) == 0 &&
3490
0
    !XLogReaderValidatePageHeader(xlogreader, targetPagePtr, readBuf))
3491
0
  {
3492
    /*
3493
     * Emit this error right now then retry this page immediately. Use
3494
     * errmsg_internal() because the message was already translated.
3495
     */
3496
0
    if (xlogreader->errormsg_buf[0])
3497
0
      ereport(emode_for_corrupt_record(emode, xlogreader->EndRecPtr),
3498
0
          (errmsg_internal("%s", xlogreader->errormsg_buf)));
3499
3500
    /* reset any error XLogReaderValidatePageHeader() might have set */
3501
0
    XLogReaderResetError(xlogreader);
3502
0
    goto next_record_is_invalid;
3503
0
  }
3504
3505
0
  return readLen;
3506
3507
0
next_record_is_invalid:
3508
3509
  /*
3510
   * If we're reading ahead, give up fast.  Retries and error reporting will
3511
   * be handled by a later read when recovery catches up to this point.
3512
   */
3513
0
  if (xlogreader->nonblocking)
3514
0
    return XLREAD_WOULDBLOCK;
3515
3516
0
  lastSourceFailed = true;
3517
3518
0
  if (readFile >= 0)
3519
0
    close(readFile);
3520
0
  readFile = -1;
3521
0
  readLen = 0;
3522
0
  readSource = XLOG_FROM_ANY;
3523
3524
  /* In standby-mode, keep trying */
3525
0
  if (StandbyMode)
3526
0
    goto retry;
3527
0
  else
3528
0
    return XLREAD_FAIL;
3529
0
}
3530
3531
/*
3532
 * Open the WAL segment containing WAL location 'RecPtr'.
3533
 *
3534
 * The segment can be fetched via restore_command, or via walreceiver having
3535
 * streamed the record, or it can already be present in pg_wal. Checking
3536
 * pg_wal is mainly for crash recovery, but it will be polled in standby mode
3537
 * too, in case someone copies a new segment directly to pg_wal. That is not
3538
 * documented or recommended, though.
3539
 *
3540
 * If 'fetching_ckpt' is true, we're fetching a checkpoint record, and should
3541
 * prepare to read WAL starting from RedoStartLSN after this.
3542
 *
3543
 * 'RecPtr' might not point to the beginning of the record we're interested
3544
 * in, it might also point to the page or segment header. In that case,
3545
 * 'tliRecPtr' is the position of the WAL record we're interested in. It is
3546
 * used to decide which timeline to stream the requested WAL from.
3547
 *
3548
 * 'replayLSN' is the current replay LSN, so that if we scan for new
3549
 * timelines, we can reject a switch to a timeline that branched off before
3550
 * this point.
3551
 *
3552
 * If the record is not immediately available, the function returns XLREAD_FAIL
3553
 * if we're not in standby mode. In standby mode, the function waits for it to
3554
 * become available.
3555
 *
3556
 * When the requested record becomes available, the function opens the file
3557
 * containing it (if not open already), and returns XLREAD_SUCCESS. When end
3558
 * of standby mode is triggered by the user, and there is no more WAL
3559
 * available, returns XLREAD_FAIL.
3560
 *
3561
 * If nonblocking is true, then give up immediately if we can't satisfy the
3562
 * request, returning XLREAD_WOULDBLOCK instead of waiting.
3563
 */
3564
static XLogPageReadResult
3565
WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
3566
              bool fetching_ckpt, XLogRecPtr tliRecPtr,
3567
              TimeLineID replayTLI, XLogRecPtr replayLSN,
3568
              bool nonblocking)
3569
0
{
3570
0
  static TimestampTz last_fail_time = 0;
3571
0
  TimestampTz now;
3572
0
  bool    streaming_reply_sent = false;
3573
3574
  /*-------
3575
   * Standby mode is implemented by a state machine:
3576
   *
3577
   * 1. Read from either archive or pg_wal (XLOG_FROM_ARCHIVE), or just
3578
   *    pg_wal (XLOG_FROM_PG_WAL)
3579
   * 2. Check for promotion trigger request
3580
   * 3. Read from primary server via walreceiver (XLOG_FROM_STREAM)
3581
   * 4. Rescan timelines
3582
   * 5. Sleep wal_retrieve_retry_interval milliseconds, and loop back to 1.
3583
   *
3584
   * Failure to read from the current source advances the state machine to
3585
   * the next state.
3586
   *
3587
   * 'currentSource' indicates the current state. There are no currentSource
3588
   * values for "check trigger", "rescan timelines", and "sleep" states,
3589
   * those actions are taken when reading from the previous source fails, as
3590
   * part of advancing to the next state.
3591
   *
3592
   * If standby mode is turned off while reading WAL from stream, we move
3593
   * to XLOG_FROM_ARCHIVE and reset lastSourceFailed, to force fetching
3594
   * the files (which would be required at end of recovery, e.g., timeline
3595
   * history file) from archive or pg_wal. We don't need to kill WAL receiver
3596
   * here because it's already stopped when standby mode is turned off at
3597
   * the end of recovery.
3598
   *-------
3599
   */
3600
0
  if (!InArchiveRecovery)
3601
0
    currentSource = XLOG_FROM_PG_WAL;
3602
0
  else if (currentSource == XLOG_FROM_ANY ||
3603
0
       (!StandbyMode && currentSource == XLOG_FROM_STREAM))
3604
0
  {
3605
0
    lastSourceFailed = false;
3606
0
    currentSource = XLOG_FROM_ARCHIVE;
3607
0
  }
3608
3609
0
  for (;;)
3610
0
  {
3611
0
    XLogSource  oldSource = currentSource;
3612
0
    bool    startWalReceiver = false;
3613
3614
    /*
3615
     * First check if we failed to read from the current source, and
3616
     * advance the state machine if so. The failure to read might've
3617
     * happened outside this function, e.g when a CRC check fails on a
3618
     * record, or within this loop.
3619
     */
3620
0
    if (lastSourceFailed)
3621
0
    {
3622
      /*
3623
       * Don't allow any retry loops to occur during nonblocking
3624
       * readahead.  Let the caller process everything that has been
3625
       * decoded already first.
3626
       */
3627
0
      if (nonblocking)
3628
0
        return XLREAD_WOULDBLOCK;
3629
3630
0
      switch (currentSource)
3631
0
      {
3632
0
        case XLOG_FROM_ARCHIVE:
3633
0
        case XLOG_FROM_PG_WAL:
3634
3635
          /*
3636
           * Check to see if promotion is requested. Note that we do
3637
           * this only after failure, so when you promote, we still
3638
           * finish replaying as much as we can from archive and
3639
           * pg_wal before failover.
3640
           */
3641
0
          if (StandbyMode && CheckForStandbyTrigger())
3642
0
          {
3643
0
            XLogShutdownWalRcv();
3644
0
            return XLREAD_FAIL;
3645
0
          }
3646
3647
          /*
3648
           * Not in standby mode, and we've now tried the archive
3649
           * and pg_wal.
3650
           */
3651
0
          if (!StandbyMode)
3652
0
            return XLREAD_FAIL;
3653
3654
          /*
3655
           * Move to XLOG_FROM_STREAM state, and set to start a
3656
           * walreceiver if necessary.
3657
           */
3658
0
          currentSource = XLOG_FROM_STREAM;
3659
0
          startWalReceiver = true;
3660
0
          break;
3661
3662
0
        case XLOG_FROM_STREAM:
3663
3664
          /*
3665
           * Failure while streaming. Most likely, we got here
3666
           * because streaming replication was terminated, or
3667
           * promotion was triggered. But we also get here if we
3668
           * find an invalid record in the WAL streamed from the
3669
           * primary, in which case something is seriously wrong.
3670
           * There's little chance that the problem will just go
3671
           * away, but PANIC is not good for availability either,
3672
           * especially in hot standby mode. So, we treat that the
3673
           * same as disconnection, and retry from archive/pg_wal
3674
           * again. The WAL in the archive should be identical to
3675
           * what was streamed, so it's unlikely that it helps, but
3676
           * one can hope...
3677
           */
3678
3679
          /*
3680
           * We should be able to move to XLOG_FROM_STREAM only in
3681
           * standby mode.
3682
           */
3683
0
          Assert(StandbyMode);
3684
3685
          /*
3686
           * Before we leave XLOG_FROM_STREAM state, make sure that
3687
           * walreceiver is not active, so that it won't overwrite
3688
           * WAL that we restore from archive.
3689
           *
3690
           * If walreceiver is actively streaming (or attempting to
3691
           * connect), we must shut it down. However, if it's
3692
           * already in WAITING state (e.g., due to timeline
3693
           * divergence), we only need to reset the install flag to
3694
           * allow archive restoration.
3695
           */
3696
0
          if (WalRcvStreaming())
3697
0
            XLogShutdownWalRcv();
3698
0
          else
3699
0
          {
3700
            /*
3701
             * WALRCV_STOPPING state is a transient state while
3702
             * the startup process is in ShutdownWalRcv().  It
3703
             * should never appear here since we would be waiting
3704
             * for the walreceiver to reach WALRCV_STOPPED in that
3705
             * case.
3706
             */
3707
0
            Assert(WalRcvGetState() != WALRCV_STOPPING);
3708
0
            ResetInstallXLogFileSegmentActive();
3709
0
          }
3710
3711
          /*
3712
           * Before we sleep, re-scan for possible new timelines if
3713
           * we were requested to recover to the latest timeline.
3714
           */
3715
0
          if (recoveryTargetTimeLineGoal == RECOVERY_TARGET_TIMELINE_LATEST)
3716
0
          {
3717
0
            if (rescanLatestTimeLine(replayTLI, replayLSN))
3718
0
            {
3719
0
              currentSource = XLOG_FROM_ARCHIVE;
3720
0
              break;
3721
0
            }
3722
0
          }
3723
3724
          /*
3725
           * XLOG_FROM_STREAM is the last state in our state
3726
           * machine, so we've exhausted all the options for
3727
           * obtaining the requested WAL. We're going to loop back
3728
           * and retry from the archive, but if it hasn't been long
3729
           * since last attempt, sleep wal_retrieve_retry_interval
3730
           * milliseconds to avoid busy-waiting.
3731
           */
3732
0
          now = GetCurrentTimestamp();
3733
0
          if (!TimestampDifferenceExceeds(last_fail_time, now,
3734
0
                          wal_retrieve_retry_interval))
3735
0
          {
3736
0
            long    wait_time;
3737
3738
0
            wait_time = wal_retrieve_retry_interval -
3739
0
              TimestampDifferenceMilliseconds(last_fail_time, now);
3740
3741
0
            elog(LOG, "waiting for WAL to become available at %X/%08X",
3742
0
               LSN_FORMAT_ARGS(RecPtr));
3743
3744
            /* Do background tasks that might benefit us later. */
3745
0
            KnownAssignedTransactionIdsIdleMaintenance();
3746
3747
0
            (void) WaitLatch(&XLogRecoveryCtl->recoveryWakeupLatch,
3748
0
                     WL_LATCH_SET | WL_TIMEOUT |
3749
0
                     WL_EXIT_ON_PM_DEATH,
3750
0
                     wait_time,
3751
0
                     WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL);
3752
0
            ResetLatch(&XLogRecoveryCtl->recoveryWakeupLatch);
3753
0
            now = GetCurrentTimestamp();
3754
3755
            /* Handle interrupt signals of startup process */
3756
0
            ProcessStartupProcInterrupts();
3757
0
          }
3758
0
          last_fail_time = now;
3759
0
          currentSource = XLOG_FROM_ARCHIVE;
3760
0
          break;
3761
3762
0
        default:
3763
0
          elog(ERROR, "unexpected WAL source %d", currentSource);
3764
0
      }
3765
0
    }
3766
0
    else if (currentSource == XLOG_FROM_PG_WAL)
3767
0
    {
3768
      /*
3769
       * We just successfully read a file in pg_wal. We prefer files in
3770
       * the archive over ones in pg_wal, so try the next file again
3771
       * from the archive first.
3772
       */
3773
0
      if (InArchiveRecovery)
3774
0
        currentSource = XLOG_FROM_ARCHIVE;
3775
0
    }
3776
3777
0
    if (currentSource != oldSource)
3778
0
      elog(DEBUG2, "switched WAL source from %s to %s after %s",
3779
0
         xlogSourceNames[oldSource], xlogSourceNames[currentSource],
3780
0
         lastSourceFailed ? "failure" : "success");
3781
3782
    /*
3783
     * We've now handled possible failure. Try to read from the chosen
3784
     * source.
3785
     */
3786
0
    lastSourceFailed = false;
3787
3788
0
    switch (currentSource)
3789
0
    {
3790
0
      case XLOG_FROM_ARCHIVE:
3791
0
      case XLOG_FROM_PG_WAL:
3792
3793
        /*
3794
         * WAL receiver must not be running when reading WAL from
3795
         * archive or pg_wal.
3796
         */
3797
0
        Assert(!WalRcvStreaming());
3798
3799
        /* Close any old file we might have open. */
3800
0
        if (readFile >= 0)
3801
0
        {
3802
0
          close(readFile);
3803
0
          readFile = -1;
3804
0
        }
3805
        /* Reset curFileTLI if random fetch. */
3806
0
        if (randAccess)
3807
0
          curFileTLI = 0;
3808
3809
        /*
3810
         * Try to restore the file from archive, or read an existing
3811
         * file from pg_wal.
3812
         */
3813
0
        readFile = XLogFileReadAnyTLI(readSegNo,
3814
0
                        currentSource == XLOG_FROM_ARCHIVE ? XLOG_FROM_ANY :
3815
0
                        currentSource);
3816
0
        if (readFile >= 0)
3817
0
          return XLREAD_SUCCESS; /* success! */
3818
3819
        /*
3820
         * Nope, not found in archive or pg_wal.
3821
         */
3822
0
        lastSourceFailed = true;
3823
0
        break;
3824
3825
0
      case XLOG_FROM_STREAM:
3826
0
        {
3827
0
          bool    havedata;
3828
3829
          /*
3830
           * We should be able to move to XLOG_FROM_STREAM only in
3831
           * standby mode.
3832
           */
3833
0
          Assert(StandbyMode);
3834
3835
          /*
3836
           * First, shutdown walreceiver if its restart has been
3837
           * requested -- but no point if we're already slated for
3838
           * starting it.
3839
           */
3840
0
          if (pendingWalRcvRestart && !startWalReceiver)
3841
0
          {
3842
0
            XLogShutdownWalRcv();
3843
3844
            /*
3845
             * Re-scan for possible new timelines if we were
3846
             * requested to recover to the latest timeline.
3847
             */
3848
0
            if (recoveryTargetTimeLineGoal ==
3849
0
              RECOVERY_TARGET_TIMELINE_LATEST)
3850
0
              rescanLatestTimeLine(replayTLI, replayLSN);
3851
3852
0
            startWalReceiver = true;
3853
0
          }
3854
0
          pendingWalRcvRestart = false;
3855
3856
          /*
3857
           * Launch walreceiver if needed.
3858
           *
3859
           * If fetching_ckpt is true, RecPtr points to the initial
3860
           * checkpoint location. In that case, we use RedoStartLSN
3861
           * as the streaming start position instead of RecPtr, so
3862
           * that when we later jump backwards to start redo at
3863
           * RedoStartLSN, we will have the logs streamed already.
3864
           */
3865
0
          if (startWalReceiver &&
3866
0
            PrimaryConnInfo && strcmp(PrimaryConnInfo, "") != 0)
3867
0
          {
3868
0
            XLogRecPtr  ptr;
3869
0
            TimeLineID  tli;
3870
3871
0
            if (fetching_ckpt)
3872
0
            {
3873
0
              ptr = RedoStartLSN;
3874
0
              tli = RedoStartTLI;
3875
0
            }
3876
0
            else
3877
0
            {
3878
0
              ptr = RecPtr;
3879
3880
              /*
3881
               * Use the record begin position to determine the
3882
               * TLI, rather than the position we're reading.
3883
               */
3884
0
              tli = tliOfPointInHistory(tliRecPtr, expectedTLEs);
3885
3886
0
              if (curFileTLI > 0 && tli < curFileTLI)
3887
0
                elog(ERROR, "according to history file, WAL location %X/%08X belongs to timeline %u, but previous recovered WAL file came from timeline %u",
3888
0
                   LSN_FORMAT_ARGS(tliRecPtr),
3889
0
                   tli, curFileTLI);
3890
0
            }
3891
0
            curFileTLI = tli;
3892
0
            SetInstallXLogFileSegmentActive();
3893
0
            RequestXLogStreaming(tli, ptr, PrimaryConnInfo,
3894
0
                       PrimarySlotName,
3895
0
                       wal_receiver_create_temp_slot);
3896
0
            flushedUpto = InvalidXLogRecPtr;
3897
0
          }
3898
3899
          /*
3900
           * Check if WAL receiver is active or wait to start up.
3901
           */
3902
0
          if (!WalRcvStreaming())
3903
0
          {
3904
0
            lastSourceFailed = true;
3905
0
            break;
3906
0
          }
3907
3908
          /*
3909
           * Walreceiver is active, so see if new data has arrived.
3910
           *
3911
           * We only advance XLogReceiptTime when we obtain fresh
3912
           * WAL from walreceiver and observe that we had already
3913
           * processed everything before the most recent "chunk"
3914
           * that it flushed to disk.  In steady state where we are
3915
           * keeping up with the incoming data, XLogReceiptTime will
3916
           * be updated on each cycle. When we are behind,
3917
           * XLogReceiptTime will not advance, so the grace time
3918
           * allotted to conflicting queries will decrease.
3919
           */
3920
0
          if (RecPtr < flushedUpto)
3921
0
            havedata = true;
3922
0
          else
3923
0
          {
3924
0
            XLogRecPtr  latestChunkStart;
3925
3926
0
            flushedUpto = GetWalRcvFlushRecPtr(&latestChunkStart, &receiveTLI);
3927
0
            if (RecPtr < flushedUpto && receiveTLI == curFileTLI)
3928
0
            {
3929
0
              havedata = true;
3930
0
              if (latestChunkStart <= RecPtr)
3931
0
              {
3932
0
                XLogReceiptTime = GetCurrentTimestamp();
3933
0
                SetCurrentChunkStartTime(XLogReceiptTime);
3934
0
              }
3935
0
            }
3936
0
            else
3937
0
              havedata = false;
3938
0
          }
3939
0
          if (havedata)
3940
0
          {
3941
            /*
3942
             * Great, streamed far enough.  Open the file if it's
3943
             * not open already.  Also read the timeline history
3944
             * file if we haven't initialized timeline history
3945
             * yet; it should be streamed over and present in
3946
             * pg_wal by now.  Use XLOG_FROM_STREAM so that source
3947
             * info is set correctly and XLogReceiptTime isn't
3948
             * changed.
3949
             *
3950
             * NB: We must set readTimeLineHistory based on
3951
             * recoveryTargetTLI, not receiveTLI. Normally they'll
3952
             * be the same, but if recovery_target_timeline is
3953
             * 'latest' and archiving is configured, then it's
3954
             * possible that we managed to retrieve one or more
3955
             * new timeline history files from the archive,
3956
             * updating recoveryTargetTLI.
3957
             */
3958
0
            if (readFile < 0)
3959
0
            {
3960
0
              if (!expectedTLEs)
3961
0
                expectedTLEs = readTimeLineHistory(recoveryTargetTLI);
3962
0
              readFile = XLogFileRead(readSegNo, receiveTLI,
3963
0
                          XLOG_FROM_STREAM, false);
3964
0
              Assert(readFile >= 0);
3965
0
            }
3966
0
            else
3967
0
            {
3968
              /* just make sure source info is correct... */
3969
0
              readSource = XLOG_FROM_STREAM;
3970
0
              XLogReceiptSource = XLOG_FROM_STREAM;
3971
0
              return XLREAD_SUCCESS;
3972
0
            }
3973
0
            break;
3974
0
          }
3975
3976
          /* In nonblocking mode, return rather than sleeping. */
3977
0
          if (nonblocking)
3978
0
            return XLREAD_WOULDBLOCK;
3979
3980
          /*
3981
           * Data not here yet. Check for trigger, then wait for
3982
           * walreceiver to wake us up when new WAL arrives.
3983
           */
3984
0
          if (CheckForStandbyTrigger())
3985
0
          {
3986
            /*
3987
             * Note that we don't return XLREAD_FAIL immediately
3988
             * here. After being triggered, we still want to
3989
             * replay all the WAL that was already streamed. It's
3990
             * in pg_wal now, so we just treat this as a failure,
3991
             * and the state machine will move on to replay the
3992
             * streamed WAL from pg_wal, and then recheck the
3993
             * trigger and exit replay.
3994
             */
3995
0
            lastSourceFailed = true;
3996
0
            break;
3997
0
          }
3998
3999
          /*
4000
           * Since we have replayed everything we have received so
4001
           * far and are about to start waiting for more WAL, let's
4002
           * tell the upstream server our replay location now so
4003
           * that pg_stat_replication doesn't show stale
4004
           * information.
4005
           */
4006
0
          if (!streaming_reply_sent)
4007
0
          {
4008
0
            WalRcvRequestApplyReply();
4009
0
            streaming_reply_sent = true;
4010
0
          }
4011
4012
          /* Do any background tasks that might benefit us later. */
4013
0
          KnownAssignedTransactionIdsIdleMaintenance();
4014
4015
          /* Update pg_stat_recovery_prefetch before sleeping. */
4016
0
          XLogPrefetcherComputeStats(xlogprefetcher);
4017
4018
          /*
4019
           * Wait for more WAL to arrive, when we will be woken
4020
           * immediately by the WAL receiver.
4021
           */
4022
0
          (void) WaitLatch(&XLogRecoveryCtl->recoveryWakeupLatch,
4023
0
                   WL_LATCH_SET | WL_EXIT_ON_PM_DEATH,
4024
0
                   -1L,
4025
0
                   WAIT_EVENT_RECOVERY_WAL_STREAM);
4026
0
          ResetLatch(&XLogRecoveryCtl->recoveryWakeupLatch);
4027
0
          break;
4028
0
        }
4029
4030
0
      default:
4031
0
        elog(ERROR, "unexpected WAL source %d", currentSource);
4032
0
    }
4033
4034
    /*
4035
     * Check for recovery pause here so that we can confirm more quickly
4036
     * that a requested pause has actually taken effect.
4037
     */
4038
0
    if (((volatile XLogRecoveryCtlData *) XLogRecoveryCtl)->recoveryPauseState !=
4039
0
      RECOVERY_NOT_PAUSED)
4040
0
      recoveryPausesHere(false);
4041
4042
    /*
4043
     * This possibly-long loop needs to handle interrupts of startup
4044
     * process.
4045
     */
4046
0
    ProcessStartupProcInterrupts();
4047
0
  }
4048
4049
0
  return XLREAD_FAIL;     /* not reached */
4050
0
}
4051
4052
4053
/*
4054
 * Determine what log level should be used to report a corrupt WAL record
4055
 * in the current WAL page, previously read by XLogPageRead().
4056
 *
4057
 * 'emode' is the error mode that would be used to report a file-not-found
4058
 * or legitimate end-of-WAL situation.   Generally, we use it as-is, but if
4059
 * we're retrying the exact same record that we've tried previously, only
4060
 * complain the first time to keep the noise down.  However, we only do when
4061
 * reading from pg_wal, because we don't expect any invalid records in archive
4062
 * or in records streamed from the primary. Files in the archive should be complete,
4063
 * and we should never hit the end of WAL because we stop and wait for more WAL
4064
 * to arrive before replaying it.
4065
 *
4066
 * NOTE: This function remembers the RecPtr value it was last called with,
4067
 * to suppress repeated messages about the same record. Only call this when
4068
 * you are about to ereport(), or you might cause a later message to be
4069
 * erroneously suppressed.
4070
 */
4071
static int
4072
emode_for_corrupt_record(int emode, XLogRecPtr RecPtr)
4073
0
{
4074
0
  static XLogRecPtr lastComplaint = InvalidXLogRecPtr;
4075
4076
0
  if (readSource == XLOG_FROM_PG_WAL && emode == LOG)
4077
0
  {
4078
0
    if (RecPtr == lastComplaint)
4079
0
      emode = DEBUG1;
4080
0
    else
4081
0
      lastComplaint = RecPtr;
4082
0
  }
4083
0
  return emode;
4084
0
}
4085
4086
4087
/*
4088
 * Subroutine to try to fetch and validate a prior checkpoint record.
4089
 */
4090
static XLogRecord *
4091
ReadCheckpointRecord(XLogPrefetcher *xlogprefetcher, XLogRecPtr RecPtr,
4092
           TimeLineID replayTLI)
4093
{
4094
  XLogRecord *record;
4095
  uint8   info;
4096
4097
  Assert(xlogreader != NULL);
4098
4099
  if (!XRecOffIsValid(RecPtr))
4100
  {
4101
    ereport(LOG,
4102
        (errmsg("invalid checkpoint location")));
4103
    return NULL;
4104
  }
4105
4106
  XLogPrefetcherBeginRead(xlogprefetcher, RecPtr);
4107
  record = ReadRecord(xlogprefetcher, LOG, true, replayTLI);
4108
4109
  if (record == NULL)
4110
  {
4111
    ereport(LOG,
4112
        (errmsg("invalid checkpoint record")));
4113
    return NULL;
4114
  }
4115
  if (record->xl_rmid != RM_XLOG_ID)
4116
  {
4117
    ereport(LOG,
4118
        (errmsg("invalid resource manager ID in checkpoint record")));
4119
    return NULL;
4120
  }
4121
  info = record->xl_info & ~XLR_INFO_MASK;
4122
  if (info != XLOG_CHECKPOINT_SHUTDOWN &&
4123
    info != XLOG_CHECKPOINT_ONLINE)
4124
  {
4125
    ereport(LOG,
4126
        (errmsg("invalid xl_info in checkpoint record")));
4127
    return NULL;
4128
  }
4129
  if (record->xl_tot_len != SizeOfXLogRecord + SizeOfXLogRecordDataHeaderShort + sizeof(CheckPoint))
4130
  {
4131
    ereport(LOG,
4132
        (errmsg("invalid length of checkpoint record")));
4133
    return NULL;
4134
  }
4135
  return record;
4136
}
4137
4138
/*
4139
 * Scan for new timelines that might have appeared in the archive since we
4140
 * started recovery.
4141
 *
4142
 * If there are any, the function changes recovery target TLI to the latest
4143
 * one and returns 'true'.
4144
 */
4145
static bool
4146
rescanLatestTimeLine(TimeLineID replayTLI, XLogRecPtr replayLSN)
4147
{
4148
  List     *newExpectedTLEs;
4149
  bool    found;
4150
  ListCell   *cell;
4151
  TimeLineID  newtarget;
4152
  TimeLineID  oldtarget = recoveryTargetTLI;
4153
  TimeLineHistoryEntry *currentTle = NULL;
4154
4155
  newtarget = findNewestTimeLine(recoveryTargetTLI);
4156
  if (newtarget == recoveryTargetTLI)
4157
  {
4158
    /* No new timelines found */
4159
    return false;
4160
  }
4161
4162
  /*
4163
   * Determine the list of expected TLIs for the new TLI
4164
   */
4165
4166
  newExpectedTLEs = readTimeLineHistory(newtarget);
4167
4168
  /*
4169
   * If the current timeline is not part of the history of the new timeline,
4170
   * we cannot proceed to it.
4171
   */
4172
  found = false;
4173
  foreach(cell, newExpectedTLEs)
4174
  {
4175
    currentTle = (TimeLineHistoryEntry *) lfirst(cell);
4176
4177
    if (currentTle->tli == recoveryTargetTLI)
4178
    {
4179
      found = true;
4180
      break;
4181
    }
4182
  }
4183
  if (!found)
4184
  {
4185
    ereport(LOG,
4186
        (errmsg("new timeline %u is not a child of database system timeline %u",
4187
            newtarget,
4188
            replayTLI)));
4189
    return false;
4190
  }
4191
4192
  /*
4193
   * The current timeline was found in the history file, but check that the
4194
   * next timeline was forked off from it *after* the current recovery
4195
   * location.
4196
   */
4197
  if (currentTle->end < replayLSN)
4198
  {
4199
    ereport(LOG,
4200
        errmsg("new timeline %u forked off current database system timeline %u before current recovery point %X/%08X",
4201
             newtarget,
4202
             replayTLI,
4203
             LSN_FORMAT_ARGS(replayLSN)));
4204
    return false;
4205
  }
4206
4207
  /* The new timeline history seems valid. Switch target */
4208
  recoveryTargetTLI = newtarget;
4209
  list_free_deep(expectedTLEs);
4210
  expectedTLEs = newExpectedTLEs;
4211
4212
  /*
4213
   * As in StartupXLOG(), try to ensure we have all the history files
4214
   * between the old target and new target in pg_wal.
4215
   */
4216
  restoreTimeLineHistoryFiles(oldtarget + 1, newtarget);
4217
4218
  ereport(LOG,
4219
      (errmsg("new target timeline is %u",
4220
          recoveryTargetTLI)));
4221
4222
  return true;
4223
}
4224
4225
4226
/*
4227
 * Open a logfile segment for reading (during recovery).
4228
 *
4229
 * If source == XLOG_FROM_ARCHIVE, the segment is retrieved from archive.
4230
 * Otherwise, it's assumed to be already available in pg_wal.
4231
 */
4232
static int
4233
XLogFileRead(XLogSegNo segno, TimeLineID tli,
4234
       XLogSource source, bool notfoundOk)
4235
0
{
4236
0
  char    xlogfname[MAXFNAMELEN];
4237
0
  char    activitymsg[MAXFNAMELEN + 16];
4238
0
  char    path[MAXPGPATH];
4239
0
  int     fd;
4240
4241
0
  XLogFileName(xlogfname, tli, segno, wal_segment_size);
4242
4243
0
  switch (source)
4244
0
  {
4245
0
    case XLOG_FROM_ARCHIVE:
4246
      /* Report recovery progress in PS display */
4247
0
      snprintf(activitymsg, sizeof(activitymsg), "waiting for %s",
4248
0
           xlogfname);
4249
0
      set_ps_display(activitymsg);
4250
4251
0
      if (!RestoreArchivedFile(path, xlogfname,
4252
0
                   "RECOVERYXLOG",
4253
0
                   wal_segment_size,
4254
0
                   InRedo))
4255
0
        return -1;
4256
0
      break;
4257
4258
0
    case XLOG_FROM_PG_WAL:
4259
0
    case XLOG_FROM_STREAM:
4260
0
      XLogFilePath(path, tli, segno, wal_segment_size);
4261
0
      break;
4262
4263
0
    default:
4264
0
      elog(ERROR, "invalid XLogFileRead source %d", source);
4265
0
  }
4266
4267
  /*
4268
   * If the segment was fetched from archival storage, replace the existing
4269
   * xlog segment (if any) with the archival version.
4270
   */
4271
0
  if (source == XLOG_FROM_ARCHIVE)
4272
0
  {
4273
0
    Assert(!IsInstallXLogFileSegmentActive());
4274
0
    KeepFileRestoredFromArchive(path, xlogfname);
4275
4276
    /*
4277
     * Set path to point at the new file in pg_wal.
4278
     */
4279
0
    snprintf(path, MAXPGPATH, XLOGDIR "/%s", xlogfname);
4280
0
  }
4281
4282
0
  fd = BasicOpenFile(path, O_RDONLY | PG_BINARY);
4283
0
  if (fd >= 0)
4284
0
  {
4285
    /* Success! */
4286
0
    curFileTLI = tli;
4287
4288
    /* Report recovery progress in PS display */
4289
0
    snprintf(activitymsg, sizeof(activitymsg), "recovering %s",
4290
0
         xlogfname);
4291
0
    set_ps_display(activitymsg);
4292
4293
    /* Track source of data in assorted state variables */
4294
0
    readSource = source;
4295
0
    XLogReceiptSource = source;
4296
    /* In FROM_STREAM case, caller tracks receipt time, not me */
4297
0
    if (source != XLOG_FROM_STREAM)
4298
0
      XLogReceiptTime = GetCurrentTimestamp();
4299
4300
0
    return fd;
4301
0
  }
4302
0
  if (errno != ENOENT || !notfoundOk) /* unexpected failure? */
4303
0
    ereport(PANIC,
4304
0
        (errcode_for_file_access(),
4305
0
         errmsg("could not open file \"%s\": %m", path)));
4306
0
  return -1;
4307
0
}
4308
4309
/*
4310
 * Open a logfile segment for reading (during recovery).
4311
 *
4312
 * This version searches for the segment with any TLI listed in expectedTLEs.
4313
 */
4314
static int
4315
XLogFileReadAnyTLI(XLogSegNo segno, XLogSource source)
4316
{
4317
  char    path[MAXPGPATH];
4318
  ListCell   *cell;
4319
  int     fd;
4320
  List     *tles;
4321
4322
  /*
4323
   * Loop looking for a suitable timeline ID: we might need to read any of
4324
   * the timelines listed in expectedTLEs.
4325
   *
4326
   * We expect curFileTLI on entry to be the TLI of the preceding file in
4327
   * sequence, or 0 if there was no predecessor.  We do not allow curFileTLI
4328
   * to go backwards; this prevents us from picking up the wrong file when a
4329
   * parent timeline extends to higher segment numbers than the child we
4330
   * want to read.
4331
   *
4332
   * If we haven't read the timeline history file yet, read it now, so that
4333
   * we know which TLIs to scan.  We don't save the list in expectedTLEs,
4334
   * however, unless we actually find a valid segment.  That way if there is
4335
   * neither a timeline history file nor a WAL segment in the archive, and
4336
   * streaming replication is set up, we'll read the timeline history file
4337
   * streamed from the primary when we start streaming, instead of
4338
   * recovering with a dummy history generated here.
4339
   */
4340
  if (expectedTLEs)
4341
    tles = expectedTLEs;
4342
  else
4343
    tles = readTimeLineHistory(recoveryTargetTLI);
4344
4345
  foreach(cell, tles)
4346
  {
4347
    TimeLineHistoryEntry *hent = (TimeLineHistoryEntry *) lfirst(cell);
4348
    TimeLineID  tli = hent->tli;
4349
4350
    if (tli < curFileTLI)
4351
      break;        /* don't bother looking at too-old TLIs */
4352
4353
    /*
4354
     * Skip scanning the timeline ID that the logfile segment to read
4355
     * doesn't belong to
4356
     */
4357
    if (XLogRecPtrIsValid(hent->begin))
4358
    {
4359
      XLogSegNo beginseg = 0;
4360
4361
      XLByteToSeg(hent->begin, beginseg, wal_segment_size);
4362
4363
      /*
4364
       * The logfile segment that doesn't belong to the timeline is
4365
       * older or newer than the segment that the timeline started or
4366
       * ended at, respectively. It's sufficient to check only the
4367
       * starting segment of the timeline here. Since the timelines are
4368
       * scanned in descending order in this loop, any segments newer
4369
       * than the ending segment should belong to newer timeline and
4370
       * have already been read before. So it's not necessary to check
4371
       * the ending segment of the timeline here.
4372
       */
4373
      if (segno < beginseg)
4374
        continue;
4375
    }
4376
4377
    if (source == XLOG_FROM_ANY || source == XLOG_FROM_ARCHIVE)
4378
    {
4379
      fd = XLogFileRead(segno, tli, XLOG_FROM_ARCHIVE, true);
4380
      if (fd != -1)
4381
      {
4382
        elog(DEBUG1, "got WAL segment from archive");
4383
        if (!expectedTLEs)
4384
          expectedTLEs = tles;
4385
        return fd;
4386
      }
4387
    }
4388
4389
    if (source == XLOG_FROM_ANY || source == XLOG_FROM_PG_WAL)
4390
    {
4391
      fd = XLogFileRead(segno, tli, XLOG_FROM_PG_WAL, true);
4392
      if (fd != -1)
4393
      {
4394
        if (!expectedTLEs)
4395
          expectedTLEs = tles;
4396
        return fd;
4397
      }
4398
    }
4399
  }
4400
4401
  /* Couldn't find it.  For simplicity, complain about front timeline */
4402
  XLogFilePath(path, recoveryTargetTLI, segno, wal_segment_size);
4403
  errno = ENOENT;
4404
  ereport(DEBUG2,
4405
      (errcode_for_file_access(),
4406
       errmsg("could not open file \"%s\": %m", path)));
4407
  return -1;
4408
}
4409
4410
/*
4411
 * Set flag to signal the walreceiver to restart.  (The startup process calls
4412
 * this on noticing a relevant configuration change.)
4413
 */
4414
void
4415
StartupRequestWalReceiverRestart(void)
4416
{
4417
  if (currentSource == XLOG_FROM_STREAM && WalRcvRunning())
4418
  {
4419
    ereport(LOG,
4420
        (errmsg("WAL receiver process shutdown requested")));
4421
4422
    pendingWalRcvRestart = true;
4423
  }
4424
}
4425
4426
4427
/*
4428
 * Has a standby promotion already been triggered?
4429
 *
4430
 * Unlike CheckForStandbyTrigger(), this works in any process
4431
 * that's connected to shared memory.
4432
 */
4433
bool
4434
PromoteIsTriggered(void)
4435
0
{
4436
  /*
4437
   * We check shared state each time only until a standby promotion is
4438
   * triggered. We can't trigger a promotion again, so there's no need to
4439
   * keep checking after the shared variable has once been seen true.
4440
   */
4441
0
  if (LocalPromoteIsTriggered)
4442
0
    return true;
4443
4444
0
  SpinLockAcquire(&XLogRecoveryCtl->info_lck);
4445
0
  LocalPromoteIsTriggered = XLogRecoveryCtl->SharedPromoteIsTriggered;
4446
0
  SpinLockRelease(&XLogRecoveryCtl->info_lck);
4447
4448
0
  return LocalPromoteIsTriggered;
4449
0
}
4450
4451
static void
4452
SetPromoteIsTriggered(void)
4453
0
{
4454
0
  SpinLockAcquire(&XLogRecoveryCtl->info_lck);
4455
0
  XLogRecoveryCtl->SharedPromoteIsTriggered = true;
4456
0
  SpinLockRelease(&XLogRecoveryCtl->info_lck);
4457
4458
  /*
4459
   * Mark the recovery pause state as 'not paused' because the paused state
4460
   * ends and promotion continues if a promotion is triggered while recovery
4461
   * is paused. Otherwise pg_get_wal_replay_pause_state() can mistakenly
4462
   * return 'paused' while a promotion is ongoing.
4463
   */
4464
0
  SetRecoveryPause(false);
4465
4466
0
  LocalPromoteIsTriggered = true;
4467
0
}
4468
4469
/*
4470
 * Check whether a promote request has arrived.
4471
 */
4472
static bool
4473
CheckForStandbyTrigger(void)
4474
{
4475
  if (LocalPromoteIsTriggered)
4476
    return true;
4477
4478
  if (IsPromoteSignaled() && CheckPromoteSignal())
4479
  {
4480
    ereport(LOG, (errmsg("received promote request")));
4481
    RemovePromoteSignalFiles();
4482
    ResetPromoteSignaled();
4483
    SetPromoteIsTriggered();
4484
    return true;
4485
  }
4486
4487
  return false;
4488
}
4489
4490
/*
4491
 * Remove the files signaling a standby promotion request.
4492
 */
4493
void
4494
RemovePromoteSignalFiles(void)
4495
0
{
4496
0
  unlink(PROMOTE_SIGNAL_FILE);
4497
0
}
4498
4499
/*
4500
 * Check to see if a promote request has arrived.
4501
 */
4502
bool
4503
CheckPromoteSignal(void)
4504
0
{
4505
0
  struct stat stat_buf;
4506
4507
0
  if (stat(PROMOTE_SIGNAL_FILE, &stat_buf) == 0)
4508
0
    return true;
4509
4510
0
  return false;
4511
0
}
4512
4513
/*
4514
 * Has hot standby initialization started pg_subtrans?
4515
 */
4516
bool
4517
RecoverySubtransInitialized(void)
4518
0
{
4519
0
  bool    result;
4520
4521
0
  SpinLockAcquire(&XLogRecoveryCtl->info_lck);
4522
0
  result = XLogRecoveryCtl->SharedRecoverySubtransInitialized;
4523
0
  SpinLockRelease(&XLogRecoveryCtl->info_lck);
4524
4525
0
  return result;
4526
0
}
4527
4528
/*
4529
 * Remember that hot standby initialization has started pg_subtrans.
4530
 */
4531
void
4532
SetRecoverySubtransInitialized(void)
4533
0
{
4534
0
  SpinLockAcquire(&XLogRecoveryCtl->info_lck);
4535
0
  XLogRecoveryCtl->SharedRecoverySubtransInitialized = true;
4536
0
  SpinLockRelease(&XLogRecoveryCtl->info_lck);
4537
0
}
4538
4539
/*
4540
 * Wake up startup process to replay newly arrived WAL, or to notice that
4541
 * failover has been requested.
4542
 */
4543
void
4544
WakeupRecovery(void)
4545
0
{
4546
0
  SetLatch(&XLogRecoveryCtl->recoveryWakeupLatch);
4547
0
}
4548
4549
/*
4550
 * Schedule a walreceiver wakeup in the main recovery loop.
4551
 */
4552
void
4553
XLogRequestWalReceiverReply(void)
4554
0
{
4555
0
  doRequestWalReceiverReply = true;
4556
0
}
4557
4558
/*
4559
 * Is HotStandby active yet? This is only important in special backends
4560
 * since normal backends won't ever be able to connect until this returns
4561
 * true. Postmaster knows this by way of signal, not via shared memory.
4562
 *
4563
 * Unlike testing standbyState, this works in any process that's connected to
4564
 * shared memory.  (And note that standbyState alone doesn't tell the truth
4565
 * anyway.)
4566
 */
4567
bool
4568
HotStandbyActive(void)
4569
0
{
4570
  /*
4571
   * We check shared state each time only until Hot Standby is active. We
4572
   * can't de-activate Hot Standby, so there's no need to keep checking
4573
   * after the shared variable has once been seen true.
4574
   */
4575
0
  if (LocalHotStandbyActive)
4576
0
    return true;
4577
0
  else
4578
0
  {
4579
    /* spinlock is essential on machines with weak memory ordering! */
4580
0
    SpinLockAcquire(&XLogRecoveryCtl->info_lck);
4581
0
    LocalHotStandbyActive = XLogRecoveryCtl->SharedHotStandbyActive;
4582
0
    SpinLockRelease(&XLogRecoveryCtl->info_lck);
4583
4584
0
    return LocalHotStandbyActive;
4585
0
  }
4586
0
}
4587
4588
/*
4589
 * Like HotStandbyActive(), but to be used only in WAL replay code,
4590
 * where we don't need to ask any other process what the state is.
4591
 */
4592
static bool
4593
HotStandbyActiveInReplay(void)
4594
0
{
4595
0
  Assert(AmStartupProcess() || !IsPostmasterEnvironment);
4596
0
  return LocalHotStandbyActive;
4597
0
}
4598
4599
/*
4600
 * Get latest redo apply position.
4601
 *
4602
 * Exported to allow WALReceiver to read the pointer directly.
4603
 */
4604
XLogRecPtr
4605
GetXLogReplayRecPtr(TimeLineID *replayTLI)
4606
0
{
4607
0
  XLogRecPtr  recptr;
4608
0
  TimeLineID  tli;
4609
4610
0
  SpinLockAcquire(&XLogRecoveryCtl->info_lck);
4611
0
  recptr = XLogRecoveryCtl->lastReplayedEndRecPtr;
4612
0
  tli = XLogRecoveryCtl->lastReplayedTLI;
4613
0
  SpinLockRelease(&XLogRecoveryCtl->info_lck);
4614
4615
0
  if (replayTLI)
4616
0
    *replayTLI = tli;
4617
0
  return recptr;
4618
0
}
4619
4620
4621
/*
4622
 * Get position of last applied, or the record being applied.
4623
 *
4624
 * This is different from GetXLogReplayRecPtr() in that if a WAL
4625
 * record is currently being applied, this includes that record.
4626
 */
4627
XLogRecPtr
4628
GetCurrentReplayRecPtr(TimeLineID *replayEndTLI)
4629
0
{
4630
0
  XLogRecPtr  recptr;
4631
0
  TimeLineID  tli;
4632
4633
0
  SpinLockAcquire(&XLogRecoveryCtl->info_lck);
4634
0
  recptr = XLogRecoveryCtl->replayEndRecPtr;
4635
0
  tli = XLogRecoveryCtl->replayEndTLI;
4636
0
  SpinLockRelease(&XLogRecoveryCtl->info_lck);
4637
4638
0
  if (replayEndTLI)
4639
0
    *replayEndTLI = tli;
4640
0
  return recptr;
4641
0
}
4642
4643
/*
4644
 * Save timestamp of latest processed commit/abort record.
4645
 *
4646
 * We keep this in XLogRecoveryCtl, not a simple static variable, so that it can be
4647
 * seen by processes other than the startup process.  Note in particular
4648
 * that CreateRestartPoint is executed in the checkpointer.
4649
 */
4650
static void
4651
SetLatestXTime(TimestampTz xtime)
4652
0
{
4653
0
  SpinLockAcquire(&XLogRecoveryCtl->info_lck);
4654
0
  XLogRecoveryCtl->recoveryLastXTime = xtime;
4655
0
  SpinLockRelease(&XLogRecoveryCtl->info_lck);
4656
0
}
4657
4658
/*
4659
 * Fetch timestamp of latest processed commit/abort record.
4660
 */
4661
TimestampTz
4662
GetLatestXTime(void)
4663
0
{
4664
0
  TimestampTz xtime;
4665
4666
0
  SpinLockAcquire(&XLogRecoveryCtl->info_lck);
4667
0
  xtime = XLogRecoveryCtl->recoveryLastXTime;
4668
0
  SpinLockRelease(&XLogRecoveryCtl->info_lck);
4669
4670
0
  return xtime;
4671
0
}
4672
4673
/*
4674
 * Save timestamp of the next chunk of WAL records to apply.
4675
 *
4676
 * We keep this in XLogRecoveryCtl, not a simple static variable, so that it can be
4677
 * seen by all backends.
4678
 */
4679
static void
4680
SetCurrentChunkStartTime(TimestampTz xtime)
4681
0
{
4682
0
  SpinLockAcquire(&XLogRecoveryCtl->info_lck);
4683
0
  XLogRecoveryCtl->currentChunkStartTime = xtime;
4684
0
  SpinLockRelease(&XLogRecoveryCtl->info_lck);
4685
0
}
4686
4687
/*
4688
 * Fetch timestamp of latest processed commit/abort record.
4689
 * Startup process maintains an accurate local copy in XLogReceiptTime
4690
 */
4691
TimestampTz
4692
GetCurrentChunkReplayStartTime(void)
4693
0
{
4694
0
  TimestampTz xtime;
4695
4696
0
  SpinLockAcquire(&XLogRecoveryCtl->info_lck);
4697
0
  xtime = XLogRecoveryCtl->currentChunkStartTime;
4698
0
  SpinLockRelease(&XLogRecoveryCtl->info_lck);
4699
4700
0
  return xtime;
4701
0
}
4702
4703
/*
4704
 * Returns time of receipt of current chunk of XLOG data, as well as
4705
 * whether it was received from streaming replication or from archives.
4706
 */
4707
void
4708
GetXLogReceiptTime(TimestampTz *rtime, bool *fromStream)
4709
0
{
4710
  /*
4711
   * This must be executed in the startup process, since we don't export the
4712
   * relevant state to shared memory.
4713
   */
4714
0
  Assert(InRecovery);
4715
4716
0
  *rtime = XLogReceiptTime;
4717
0
  *fromStream = (XLogReceiptSource == XLOG_FROM_STREAM);
4718
0
}
4719
4720
/*
4721
 * Note that text field supplied is a parameter name and does not require
4722
 * translation
4723
 */
4724
void
4725
RecoveryRequiresIntParameter(const char *param_name, int currValue, int minValue)
4726
0
{
4727
0
  if (currValue < minValue)
4728
0
  {
4729
0
    if (HotStandbyActiveInReplay())
4730
0
    {
4731
0
      bool    warned_for_promote = false;
4732
4733
0
      ereport(WARNING,
4734
0
          (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4735
0
           errmsg("hot standby is not possible because of insufficient parameter settings"),
4736
0
           errdetail("%s = %d is a lower setting than on the primary server, where its value was %d.",
4737
0
                 param_name,
4738
0
                 currValue,
4739
0
                 minValue)));
4740
4741
0
      SetRecoveryPause(true);
4742
4743
0
      ereport(LOG,
4744
0
          (errmsg("recovery has paused"),
4745
0
           errdetail("If recovery is unpaused, the server will shut down."),
4746
0
           errhint("You can then restart the server after making the necessary configuration changes.")));
4747
4748
0
      while (GetRecoveryPauseState() != RECOVERY_NOT_PAUSED)
4749
0
      {
4750
0
        ProcessStartupProcInterrupts();
4751
4752
0
        if (CheckForStandbyTrigger())
4753
0
        {
4754
0
          if (!warned_for_promote)
4755
0
            ereport(WARNING,
4756
0
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4757
0
                 errmsg("promotion is not possible because of insufficient parameter settings"),
4758
4759
            /*
4760
             * Repeat the detail from above so it's easy to find
4761
             * in the log.
4762
             */
4763
0
                 errdetail("%s = %d is a lower setting than on the primary server, where its value was %d.",
4764
0
                       param_name,
4765
0
                       currValue,
4766
0
                       minValue),
4767
0
                 errhint("Restart the server after making the necessary configuration changes.")));
4768
0
          warned_for_promote = true;
4769
0
        }
4770
4771
        /*
4772
         * If recovery pause is requested then set it paused.  While
4773
         * we are in the loop, user might resume and pause again so
4774
         * set this every time.
4775
         */
4776
0
        ConfirmRecoveryPaused();
4777
4778
        /*
4779
         * We wait on a condition variable that will wake us as soon
4780
         * as the pause ends, but we use a timeout so we can check the
4781
         * above conditions periodically too.
4782
         */
4783
0
        ConditionVariableTimedSleep(&XLogRecoveryCtl->recoveryNotPausedCV, 1000,
4784
0
                      WAIT_EVENT_RECOVERY_PAUSE);
4785
0
      }
4786
0
      ConditionVariableCancelSleep();
4787
0
    }
4788
4789
0
    ereport(FATAL,
4790
0
        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4791
0
         errmsg("recovery aborted because of insufficient parameter settings"),
4792
    /* Repeat the detail from above so it's easy to find in the log. */
4793
0
         errdetail("%s = %d is a lower setting than on the primary server, where its value was %d.",
4794
0
               param_name,
4795
0
               currValue,
4796
0
               minValue),
4797
0
         errhint("You can restart the server after making the necessary configuration changes.")));
4798
0
  }
4799
0
}
4800
4801
4802
/*
4803
 * GUC check_hook for primary_slot_name
4804
 */
4805
bool
4806
check_primary_slot_name(char **newval, void **extra, GucSource source)
4807
2
{
4808
2
  int     err_code;
4809
2
  char     *err_msg = NULL;
4810
2
  char     *err_hint = NULL;
4811
4812
2
  if (*newval && strcmp(*newval, "") != 0 &&
4813
0
    !ReplicationSlotValidateNameInternal(*newval, false, &err_code,
4814
0
                       &err_msg, &err_hint))
4815
0
  {
4816
0
    GUC_check_errcode(err_code);
4817
0
    GUC_check_errdetail("%s", err_msg);
4818
0
    if (err_hint != NULL)
4819
0
      GUC_check_errhint("%s", err_hint);
4820
0
    return false;
4821
0
  }
4822
4823
2
  return true;
4824
2
}
4825
4826
/*
4827
 * Return the recovery target derived from the recovery_target* settings,
4828
 * raising an error if more than one of them is set.
4829
 */
4830
static RecoveryTargetType
4831
DetermineRecoveryTargetType(void)
4832
0
{
4833
0
  int     ntargets = 0;
4834
0
  RecoveryTargetType target = RECOVERY_TARGET_UNSET;
4835
0
  const char *val;
4836
0
  StringInfoData buf;
4837
4838
0
  initStringInfo(&buf);
4839
4840
0
#define ADD_TARGET_IF_SET(gucname, kind) \
4841
0
  do { \
4842
0
    val = GetConfigOption(gucname, false, false); \
4843
0
    if (val[0] != '\0') \
4844
0
    { \
4845
0
      ntargets++; \
4846
0
      target = (kind); \
4847
0
      if (buf.len == 0) \
4848
0
        appendStringInfo(&buf, _("\"%s\""), gucname); \
4849
0
      else \
4850
0
        appendStringInfo(&buf, _(", \"%s\""), gucname); \
4851
0
    } \
4852
0
  } while (0)
4853
4854
0
  ADD_TARGET_IF_SET("recovery_target", RECOVERY_TARGET_IMMEDIATE);
4855
0
  ADD_TARGET_IF_SET("recovery_target_lsn", RECOVERY_TARGET_LSN);
4856
0
  ADD_TARGET_IF_SET("recovery_target_name", RECOVERY_TARGET_NAME);
4857
0
  ADD_TARGET_IF_SET("recovery_target_time", RECOVERY_TARGET_TIME);
4858
0
  ADD_TARGET_IF_SET("recovery_target_xid", RECOVERY_TARGET_XID);
4859
0
#undef ADD_TARGET_IF_SET
4860
4861
0
  if (ntargets > 1)
4862
0
    ereport(FATAL,
4863
0
        errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4864
0
        errmsg("cannot specify more than one recovery target"),
4865
0
        errdetail("Parameters set are: %s.",
4866
0
              buf.data));
4867
4868
0
  pfree(buf.data);
4869
4870
0
  return target;
4871
0
}
4872
4873
/*
4874
 * GUC check_hook for recovery_target
4875
 */
4876
bool
4877
check_recovery_target(char **newval, void **extra, GucSource source)
4878
2
{
4879
2
  if (strcmp(*newval, "immediate") != 0 && strcmp(*newval, "") != 0)
4880
0
  {
4881
0
    GUC_check_errdetail("The only allowed value is \"immediate\".");
4882
0
    return false;
4883
0
  }
4884
2
  return true;
4885
2
}
4886
4887
/*
4888
 * GUC check_hook for recovery_target_lsn
4889
 */
4890
bool
4891
check_recovery_target_lsn(char **newval, void **extra, GucSource source)
4892
2
{
4893
2
  if (strcmp(*newval, "") != 0)
4894
0
  {
4895
0
    XLogRecPtr  lsn;
4896
0
    XLogRecPtr *myextra;
4897
0
    ErrorSaveContext escontext = {T_ErrorSaveContext};
4898
4899
0
    lsn = pg_lsn_in_safe(*newval, (Node *) &escontext);
4900
0
    if (escontext.error_occurred)
4901
0
      return false;
4902
4903
0
    myextra = (XLogRecPtr *) guc_malloc(LOG, sizeof(XLogRecPtr));
4904
0
    if (!myextra)
4905
0
      return false;
4906
0
    *myextra = lsn;
4907
0
    *extra = myextra;
4908
0
  }
4909
2
  return true;
4910
2
}
4911
4912
/*
4913
 * GUC assign_hook for recovery_target_lsn
4914
 */
4915
void
4916
assign_recovery_target_lsn(const char *newval, void *extra)
4917
2
{
4918
2
  if (newval && strcmp(newval, "") != 0)
4919
0
    recoveryTargetLSN = *((XLogRecPtr *) extra);
4920
2
}
4921
4922
/*
4923
 * GUC check_hook for recovery_target_name
4924
 */
4925
bool
4926
check_recovery_target_name(char **newval, void **extra, GucSource source)
4927
2
{
4928
  /* Use the value of newval directly */
4929
2
  if (strlen(*newval) >= MAXFNAMELEN)
4930
0
  {
4931
0
    GUC_check_errdetail("\"%s\" is too long (maximum %d characters).",
4932
0
              "recovery_target_name", MAXFNAMELEN - 1);
4933
0
    return false;
4934
0
  }
4935
2
  return true;
4936
2
}
4937
4938
/*
4939
 * GUC check_hook for recovery_target_time
4940
 *
4941
 * The interpretation of the recovery_target_time string can depend on the
4942
 * time zone setting, so we need to wait until after all GUC processing is
4943
 * done before we can do the final parsing of the string.  This check function
4944
 * only does a parsing pass to catch syntax errors, but we store the string
4945
 * and parse it again when we need to use it.
4946
 */
4947
bool
4948
check_recovery_target_time(char **newval, void **extra, GucSource source)
4949
2
{
4950
2
  if (strcmp(*newval, "") != 0)
4951
0
  {
4952
    /* reject some special values */
4953
0
    if (strcmp(*newval, "now") == 0 ||
4954
0
      strcmp(*newval, "today") == 0 ||
4955
0
      strcmp(*newval, "tomorrow") == 0 ||
4956
0
      strcmp(*newval, "yesterday") == 0)
4957
0
    {
4958
0
      return false;
4959
0
    }
4960
4961
    /*
4962
     * parse timestamp value (see also timestamptz_in())
4963
     */
4964
0
    {
4965
0
      char     *str = *newval;
4966
0
      fsec_t    fsec;
4967
0
      struct pg_tm tt,
4968
0
             *tm = &tt;
4969
0
      int     tz;
4970
0
      int     dtype;
4971
0
      int     nf;
4972
0
      int     dterr;
4973
0
      char     *field[MAXDATEFIELDS];
4974
0
      int     ftype[MAXDATEFIELDS];
4975
0
      char    workbuf[MAXDATELEN + MAXDATEFIELDS];
4976
0
      DateTimeErrorExtra dtextra;
4977
0
      TimestampTz timestamp;
4978
4979
0
      dterr = ParseDateTime(str, workbuf, sizeof(workbuf),
4980
0
                  field, ftype, MAXDATEFIELDS, &nf);
4981
0
      if (dterr == 0)
4982
0
        dterr = DecodeDateTime(field, ftype, nf,
4983
0
                     &dtype, tm, &fsec, &tz, &dtextra);
4984
0
      if (dterr != 0)
4985
0
        return false;
4986
0
      if (dtype != DTK_DATE)
4987
0
        return false;
4988
4989
0
      if (tm2timestamp(tm, fsec, &tz, &timestamp) != 0)
4990
0
      {
4991
0
        GUC_check_errdetail("Timestamp out of range: \"%s\".", str);
4992
0
        return false;
4993
0
      }
4994
0
    }
4995
0
  }
4996
2
  return true;
4997
2
}
4998
4999
/*
5000
 * GUC check_hook for recovery_target_timeline
5001
 */
5002
bool
5003
check_recovery_target_timeline(char **newval, void **extra, GucSource source)
5004
2
{
5005
2
  RecoveryTargetTimeLineGoal rttg;
5006
2
  RecoveryTargetTimeLineGoal *myextra;
5007
5008
2
  if (strcmp(*newval, "current") == 0)
5009
0
    rttg = RECOVERY_TARGET_TIMELINE_CONTROLFILE;
5010
2
  else if (strcmp(*newval, "latest") == 0)
5011
2
    rttg = RECOVERY_TARGET_TIMELINE_LATEST;
5012
0
  else
5013
0
  {
5014
0
    char     *endp;
5015
0
    uint64    timeline;
5016
5017
0
    rttg = RECOVERY_TARGET_TIMELINE_NUMERIC;
5018
5019
0
    errno = 0;
5020
0
    timeline = strtou64(*newval, &endp, 0);
5021
5022
0
    if (*endp != '\0' || errno == EINVAL || errno == ERANGE)
5023
0
    {
5024
0
      GUC_check_errdetail("\"%s\" is not a valid number.",
5025
0
                "recovery_target_timeline");
5026
0
      return false;
5027
0
    }
5028
5029
0
    if (timeline < 1 || timeline > PG_UINT32_MAX)
5030
0
    {
5031
0
      GUC_check_errdetail("\"%s\" must be between %u and %u.",
5032
0
                "recovery_target_timeline", 1, PG_UINT32_MAX);
5033
0
      return false;
5034
0
    }
5035
0
  }
5036
5037
2
  myextra = (RecoveryTargetTimeLineGoal *) guc_malloc(LOG, sizeof(RecoveryTargetTimeLineGoal));
5038
2
  if (!myextra)
5039
0
    return false;
5040
2
  *myextra = rttg;
5041
2
  *extra = myextra;
5042
5043
2
  return true;
5044
2
}
5045
5046
/*
5047
 * GUC assign_hook for recovery_target_timeline
5048
 */
5049
void
5050
assign_recovery_target_timeline(const char *newval, void *extra)
5051
2
{
5052
2
  recoveryTargetTimeLineGoal = *((RecoveryTargetTimeLineGoal *) extra);
5053
2
  if (recoveryTargetTimeLineGoal == RECOVERY_TARGET_TIMELINE_NUMERIC)
5054
0
    recoveryTargetTLIRequested = (TimeLineID) strtoul(newval, NULL, 0);
5055
2
  else
5056
2
    recoveryTargetTLIRequested = 0;
5057
2
}
5058
5059
/*
5060
 * GUC check_hook for recovery_target_xid
5061
 */
5062
bool
5063
check_recovery_target_xid(char **newval, void **extra, GucSource source)
5064
2
{
5065
2
  if (strcmp(*newval, "") != 0)
5066
0
  {
5067
0
    TransactionId xid;
5068
0
    TransactionId *myextra;
5069
0
    char     *endp;
5070
0
    char     *val;
5071
5072
0
    errno = 0;
5073
5074
    /*
5075
     * Consume leading whitespace to determine if number is negative
5076
     */
5077
0
    val = *newval;
5078
5079
0
    while (isspace((unsigned char) *val))
5080
0
      val++;
5081
5082
    /*
5083
     * This cast will remove the epoch, if any
5084
     */
5085
0
    xid = (TransactionId) strtou64(val, &endp, 0);
5086
5087
0
    if (*endp != '\0' || errno == EINVAL || errno == ERANGE || *val == '-')
5088
0
    {
5089
0
      GUC_check_errdetail("\"%s\" is not a valid number.",
5090
0
                "recovery_target_xid");
5091
0
      return false;
5092
0
    }
5093
5094
0
    if (xid < FirstNormalTransactionId)
5095
0
    {
5096
0
      GUC_check_errdetail("\"%s\" without epoch must be greater than or equal to %u.",
5097
0
                "recovery_target_xid",
5098
0
                FirstNormalTransactionId);
5099
0
      return false;
5100
0
    }
5101
5102
0
    myextra = (TransactionId *) guc_malloc(LOG, sizeof(TransactionId));
5103
0
    if (!myextra)
5104
0
      return false;
5105
0
    *myextra = xid;
5106
0
    *extra = myextra;
5107
0
  }
5108
2
  return true;
5109
2
}
5110
5111
/*
5112
 * GUC assign_hook for recovery_target_xid
5113
 */
5114
void
5115
assign_recovery_target_xid(const char *newval, void *extra)
5116
2
{
5117
2
  if (newval && strcmp(newval, "") != 0)
5118
0
    recoveryTargetXid = *((TransactionId *) extra);
5119
2
}