Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 8771634

Browse files
committed
Don't set recoveryLastXTime when replaying a checkpoint --- that was a bogus
idea from the start since the variable is only meant to track commit/abort events. This patch reverts the logic around the variable to what it was in 8.4, except that the value is now kept in shared memory rather than a static variable, so that it can be reported correctly by CreateRestartPoint (which is executed in the bgwriter).
1 parent aceedd8 commit 8771634

File tree

1 file changed

+60
-55
lines changed
  • src/backend/access/transam

1 file changed

+60
-55
lines changed

src/backend/access/transam/xlog.c

Lines changed: 60 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.428 2010/07/03 20:43:57 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.429 2010/07/03 22:15:45 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -184,7 +184,6 @@ static RecoveryTargetType recoveryTarget = RECOVERY_TARGET_UNSET;
184184
static bool recoveryTargetInclusive = true;
185185
static TransactionId recoveryTargetXid;
186186
static TimestampTz recoveryTargetTime;
187-
static TimestampTz recoveryLastXTime = 0;
188187

189188
/* options taken from recovery.conf for XLOG streaming */
190189
static bool StandbyMode = false;
@@ -403,10 +402,10 @@ typedef struct XLogCtlData
403402

404403
/* end+1 of the last record replayed (or being replayed) */
405404
XLogRecPtr replayEndRecPtr;
406-
/* timestamp of last record replayed (or being replayed) */
407-
TimestampTz recoveryLastXTime;
408405
/* end+1 of the last record replayed */
409406
XLogRecPtr recoveryLastRecPtr;
407+
/* timestamp of last COMMIT/ABORT record replayed (or being replayed) */
408+
TimestampTz recoveryLastXTime;
410409

411410
slock_t info_lck; /* locks shared variables shown above */
412411
} XLogCtlData;
@@ -554,6 +553,8 @@ static void readRecoveryCommandFile(void);
554553
static void exitArchiveRecovery(TimeLineID endTLI,
555554
uint32 endLogId, uint32 endLogSeg);
556555
static bool recoveryStopsHere(XLogRecord *record, bool *includeThis);
556+
static void SetLatestXTime(TimestampTz xtime);
557+
static TimestampTz GetLatestXTime(void);
557558
static void CheckRequiredParameterValues(void);
558559
static void XLogReportParameters(void);
559560
static void LocalSetXLogInsertAllowed(void);
@@ -5440,7 +5441,7 @@ exitArchiveRecovery(TimeLineID endTLI, uint32 endLogId, uint32 endLogSeg)
54405441
* *includeThis is set TRUE if we should apply this record before stopping.
54415442
*
54425443
* We also track the timestamp of the latest applied COMMIT/ABORT record
5443-
* in recoveryLastXTime, for logging purposes.
5444+
* in XLogCtl->recoveryLastXTime, for logging purposes.
54445445
* Also, some information is saved in recoveryStopXid et al for use in
54455446
* annotating the new timeline's history file.
54465447
*/
@@ -5452,51 +5453,30 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
54525453
TimestampTz recordXtime;
54535454

54545455
/* We only consider stopping at COMMIT or ABORT records */
5455-
if (record->xl_rmid == RM_XACT_ID)
5456+
if (record->xl_rmid != RM_XACT_ID)
5457+
return false;
5458+
record_info = record->xl_info & ~XLR_INFO_MASK;
5459+
if (record_info == XLOG_XACT_COMMIT)
54565460
{
5457-
record_info = record->xl_info & ~XLR_INFO_MASK;
5458-
if (record_info == XLOG_XACT_COMMIT)
5459-
{
5460-
xl_xact_commit *recordXactCommitData;
5461+
xl_xact_commit *recordXactCommitData;
54615462

5462-
recordXactCommitData = (xl_xact_commit *) XLogRecGetData(record);
5463-
recordXtime = recordXactCommitData->xact_time;
5464-
}
5465-
else if (record_info == XLOG_XACT_ABORT)
5466-
{
5467-
xl_xact_abort *recordXactAbortData;
5468-
5469-
recordXactAbortData = (xl_xact_abort *) XLogRecGetData(record);
5470-
recordXtime = recordXactAbortData->xact_time;
5471-
}
5472-
else
5473-
return false;
5463+
recordXactCommitData = (xl_xact_commit *) XLogRecGetData(record);
5464+
recordXtime = recordXactCommitData->xact_time;
54745465
}
5475-
else if (record->xl_rmid == RM_XLOG_ID)
5466+
else if (record_info == XLOG_XACT_ABORT)
54765467
{
5477-
record_info = record->xl_info & ~XLR_INFO_MASK;
5478-
if (record_info == XLOG_CHECKPOINT_SHUTDOWN ||
5479-
record_info == XLOG_CHECKPOINT_ONLINE)
5480-
{
5481-
CheckPoint checkPoint;
5468+
xl_xact_abort *recordXactAbortData;
54825469

5483-
memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
5484-
recoveryLastXTime = time_t_to_timestamptz(checkPoint.time);
5485-
}
5486-
5487-
/*
5488-
* We don't want to stop recovery on a checkpoint record, but we do
5489-
* want to update recoveryLastXTime. So return is unconditional.
5490-
*/
5491-
return false;
5470+
recordXactAbortData = (xl_xact_abort *) XLogRecGetData(record);
5471+
recordXtime = recordXactAbortData->xact_time;
54925472
}
54935473
else
54945474
return false;
54955475

54965476
/* Do we have a PITR target at all? */
54975477
if (recoveryTarget == RECOVERY_TARGET_UNSET)
54985478
{
5499-
recoveryLastXTime = recordXtime;
5479+
SetLatestXTime(recordXtime);
55005480
return false;
55015481
}
55025482

@@ -5564,37 +5544,56 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
55645544
}
55655545

55665546
if (recoveryStopAfter)
5567-
recoveryLastXTime = recordXtime;
5547+
SetLatestXTime(recordXtime);
55685548
}
55695549
else
5570-
recoveryLastXTime = recordXtime;
5550+
SetLatestXTime(recordXtime);
55715551

55725552
return stopsHere;
55735553
}
55745554

55755555
/*
5576-
* Returns bool with current recovery mode, a global state.
5556+
* Save timestamp of latest processed commit/abort record.
5557+
*
5558+
* We keep this in XLogCtl, not a simple static variable, so that it can be
5559+
* seen by processes other than the startup process. Note in particular
5560+
* that CreateRestartPoint is executed in the bgwriter.
55775561
*/
5578-
Datum
5579-
pg_is_in_recovery(PG_FUNCTION_ARGS)
5562+
static void
5563+
SetLatestXTime(TimestampTz xtime)
55805564
{
5581-
PG_RETURN_BOOL(RecoveryInProgress());
5565+
/* use volatile pointer to prevent code rearrangement */
5566+
volatile XLogCtlData *xlogctl = XLogCtl;
5567+
5568+
SpinLockAcquire(&xlogctl->info_lck);
5569+
xlogctl->recoveryLastXTime = xtime;
5570+
SpinLockRelease(&xlogctl->info_lck);
55825571
}
55835572

55845573
/*
5585-
* Returns timestamp of last recovered commit/abort record.
5574+
* Fetch timestamp of latest processed commit/abort record.
55865575
*/
55875576
static TimestampTz
5588-
GetLatestXLogTime(void)
5577+
GetLatestXTime(void)
55895578
{
55905579
/* use volatile pointer to prevent code rearrangement */
55915580
volatile XLogCtlData *xlogctl = XLogCtl;
5581+
TimestampTz xtime;
55925582

55935583
SpinLockAcquire(&xlogctl->info_lck);
5594-
recoveryLastXTime = xlogctl->recoveryLastXTime;
5584+
xtime = xlogctl->recoveryLastXTime;
55955585
SpinLockRelease(&xlogctl->info_lck);
55965586

5597-
return recoveryLastXTime;
5587+
return xtime;
5588+
}
5589+
5590+
/*
5591+
* Returns bool with current recovery mode, a global state.
5592+
*/
5593+
Datum
5594+
pg_is_in_recovery(PG_FUNCTION_ARGS)
5595+
{
5596+
PG_RETURN_BOOL(RecoveryInProgress());
55985597
}
55995598

56005599
/*
@@ -6078,7 +6077,8 @@ StartupXLOG(void)
60786077
}
60796078

60806079
/*
6081-
* Initialize shared replayEndRecPtr and recoveryLastRecPtr.
6080+
* Initialize shared replayEndRecPtr, recoveryLastRecPtr, and
6081+
* recoveryLastXTime.
60826082
*
60836083
* This is slightly confusing if we're starting from an online
60846084
* checkpoint; we've just read and replayed the chekpoint record,
@@ -6091,6 +6091,7 @@ StartupXLOG(void)
60916091
SpinLockAcquire(&xlogctl->info_lck);
60926092
xlogctl->replayEndRecPtr = ReadRecPtr;
60936093
xlogctl->recoveryLastRecPtr = ReadRecPtr;
6094+
xlogctl->recoveryLastXTime = 0;
60946095
SpinLockRelease(&xlogctl->info_lck);
60956096

60966097
/* Also ensure XLogReceiptTime has a sane value */
@@ -6140,6 +6141,7 @@ StartupXLOG(void)
61406141
bool recoveryContinue = true;
61416142
bool recoveryApply = true;
61426143
ErrorContextCallback errcontext;
6144+
TimestampTz xtime;
61436145

61446146
InRedo = true;
61456147

@@ -6210,7 +6212,6 @@ StartupXLOG(void)
62106212
*/
62116213
SpinLockAcquire(&xlogctl->info_lck);
62126214
xlogctl->replayEndRecPtr = EndRecPtr;
6213-
xlogctl->recoveryLastXTime = recoveryLastXTime;
62146215
SpinLockRelease(&xlogctl->info_lck);
62156216

62166217
/* If we are attempting to enter Hot Standby mode, process XIDs we see */
@@ -6243,10 +6244,11 @@ StartupXLOG(void)
62436244
ereport(LOG,
62446245
(errmsg("redo done at %X/%X",
62456246
ReadRecPtr.xlogid, ReadRecPtr.xrecoff)));
6246-
if (recoveryLastXTime)
6247+
xtime = GetLatestXTime();
6248+
if (xtime)
62476249
ereport(LOG,
62486250
(errmsg("last completed transaction was at log time %s",
6249-
timestamptz_to_str(recoveryLastXTime))));
6251+
timestamptz_to_str(xtime))));
62506252
InRedo = false;
62516253
}
62526254
else
@@ -7553,6 +7555,7 @@ CreateRestartPoint(int flags)
75537555
CheckPoint lastCheckPoint;
75547556
uint32 _logId;
75557557
uint32 _logSeg;
7558+
TimestampTz xtime;
75567559

75577560
/* use volatile pointer to prevent code rearrangement */
75587561
volatile XLogCtlData *xlogctl = XLogCtl;
@@ -7705,10 +7708,12 @@ CreateRestartPoint(int flags)
77057708
if (log_checkpoints)
77067709
LogCheckpointEnd(true);
77077710

7711+
xtime = GetLatestXTime();
77087712
ereport((log_checkpoints ? LOG : DEBUG2),
7709-
(errmsg("recovery restart point at %X/%X with latest known log time %s",
7710-
lastCheckPoint.redo.xlogid, lastCheckPoint.redo.xrecoff,
7711-
timestamptz_to_str(GetLatestXLogTime()))));
7713+
(errmsg("recovery restart point at %X/%X",
7714+
lastCheckPoint.redo.xlogid, lastCheckPoint.redo.xrecoff),
7715+
xtime ? errdetail("last completed transaction was at log time %s",
7716+
timestamptz_to_str(xtime)) : 0));
77127717

77137718
LWLockRelease(CheckpointLock);
77147719

0 commit comments

Comments
 (0)