UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
{
	/* Quick check using our local copy of the variable */
	if (!updateMinRecoveryPoint || (!force && lsn <= minRecoveryPoint))
		return;

	LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);

	/* update local copy */
	minRecoveryPoint = ControlFile->minRecoveryPoint;
	minRecoveryPointTLI = ControlFile->minRecoveryPointTLI;

	/*
	 * An invalid minRecoveryPoint means that we need to recover all the WAL,
	 * i.e., we're doing crash recovery.  We never modify the control file's
	 * value in that case, so we can short-circuit future checks here too.
	 */
	if (minRecoveryPoint == 0)
		updateMinRecoveryPoint = false;
	else if (force || minRecoveryPoint < lsn)
	{
		/* use volatile pointer to prevent code rearrangement */
		volatile XLogCtlData *xlogctl = XLogCtl;
		XLogRecPtr	newMinRecoveryPoint;
		TimeLineID	newMinRecoveryPointTLI;

		/*
		 * To avoid having to update the control file too often, we update it
		 * all the way to the last record being replayed, even though 'lsn'
		 * would suffice for correctness.  This also allows the 'force' case
		 * to not need a valid 'lsn' value.
		 *
		 * Another important reason for doing it this way is that the passed
		 * 'lsn' value could be bogus, i.e., past the end of available WAL, if
		 * the caller got it from a corrupted heap page.  Accepting such a
		 * value as the min recovery point would prevent us from coming up at
		 * all.  Instead, we just log a warning and continue with recovery.
		 * (See also the comments about corrupt LSNs in XLogFlush.)
		 */
		SpinLockAcquire(&xlogctl->info_lck);
		newMinRecoveryPoint = xlogctl->replayEndRecPtr;
		newMinRecoveryPointTLI = xlogctl->replayEndTLI;
		SpinLockRelease(&xlogctl->info_lck);

		if (!force && newMinRecoveryPoint < lsn)
			elog(WARNING,
			   "xlog min recovery request %X/%X is past current point %X/%X",
				 (uint32) (lsn >> 32), (uint32) lsn,
				 (uint32) (newMinRecoveryPoint >> 32),
				 (uint32) newMinRecoveryPoint);

		/* update control file */
		if (ControlFile->minRecoveryPoint < newMinRecoveryPoint)
		{
			ControlFile->minRecoveryPoint = newMinRecoveryPoint;
			ControlFile->minRecoveryPointTLI = newMinRecoveryPointTLI;
			UpdateControlFile();
			minRecoveryPoint = newMinRecoveryPoint;
			minRecoveryPointTLI = newMinRecoveryPointTLI;

			ereport(DEBUG2,
				(errmsg("updated min recovery point to %X/%X on timeline %u",
						(uint32) (minRecoveryPoint >> 32),
						(uint32) minRecoveryPoint,
						newMinRecoveryPointTLI)));
		}
	}
	LWLockRelease(ControlFileLock);
}
UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
{
	 
	if (!updateMinRecoveryPoint || (!force && lsn <= minRecoveryPoint))
		return;

	LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);

	 
	minRecoveryPoint = ControlFile->minRecoveryPoint;
	minRecoveryPointTLI = ControlFile->minRecoveryPointTLI;

	 
	if (minRecoveryPoint == 0)
		updateMinRecoveryPoint = false;
	else if (force || minRecoveryPoint < lsn)
	{
		 
		volatile XLogCtlData *xlogctl = XLogCtl;
		XLogRecPtr	newMinRecoveryPoint;
		TimeLineID	newMinRecoveryPointTLI;

		 
		SpinLockAcquire(&xlogctl->info_lck);
		newMinRecoveryPoint = xlogctl->replayEndRecPtr;
		newMinRecoveryPointTLI = xlogctl->replayEndTLI;
		SpinLockRelease(&xlogctl->info_lck);

		if (!force && newMinRecoveryPoint < lsn)
			elog(WARNING,
			   "xlog min recovery request %X/%X is past current point %X/%X",
				 (uint32) (lsn >> 32), (uint32) lsn,
				 (uint32) (newMinRecoveryPoint >> 32),
				 (uint32) newMinRecoveryPoint);

		 
		if (ControlFile->minRecoveryPoint < newMinRecoveryPoint)
		{
			ControlFile->minRecoveryPoint = newMinRecoveryPoint;
			ControlFile->minRecoveryPointTLI = newMinRecoveryPointTLI;
			UpdateControlFile();
			minRecoveryPoint = newMinRecoveryPoint;
			minRecoveryPointTLI = newMinRecoveryPointTLI;

			ereport(DEBUG2,
				(errmsg("updated min recovery point to %X/%X on timeline %u",
						(uint32) (minRecoveryPoint >> 32),
						(uint32) minRecoveryPoint,
						newMinRecoveryPointTLI)));
		}
	}
	LWLockRelease(ControlFileLock);
}