summaryrefslogtreecommitdiff
path: root/src/mongo/db/db_raii.cpp
diff options
context:
space:
mode:
authorWilliam Schultz <william.schultz@mongodb.com>2019-03-25 15:40:18 -0400
committerWilliam Schultz <william.schultz@mongodb.com>2019-03-25 15:40:18 -0400
commitcdc1359a61de42673455c4f64eb9986da5ef0df4 (patch)
tree560c1c5bf6cdbd3383b64a4f38505c02460a50af /src/mongo/db/db_raii.cpp
parent04b7774c27587b5b66ac9171b962145ce00d5372 (diff)
downloadmongo-cdc1359a61de42673455c4f64eb9986da5ef0df4.tar.gz
SERVER-39660 Return SnapshotUnavailable error when trying to read behind pending catalog changes in AutoGetCollectionForRead using a provided timestamp read source
Diffstat (limited to 'src/mongo/db/db_raii.cpp')
-rw-r--r--src/mongo/db/db_raii.cpp20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/mongo/db/db_raii.cpp b/src/mongo/db/db_raii.cpp
index dd48bc7c36e..7aa79365197 100644
--- a/src/mongo/db/db_raii.cpp
+++ b/src/mongo/db/db_raii.cpp
@@ -110,6 +110,23 @@ AutoGetCollectionForRead::AutoGetCollectionForRead(OperationContext* opCtx,
// need to check for pending catalog changes.
while (auto coll = _autoColl->getCollection()) {
+ auto readSource = opCtx->recoveryUnit()->getTimestampReadSource();
+ auto minSnapshot = coll->getMinimumVisibleSnapshot();
+ auto mySnapshot = opCtx->recoveryUnit()->getPointInTimeReadTimestamp();
+
+ // If we are reading at a provided timestamp earlier than the latest catalog changes, then
+ // we must return an error.
+ if (readSource == RecoveryUnit::ReadSource::kProvided && minSnapshot &&
+ (*mySnapshot < *minSnapshot)) {
+ uasserted(ErrorCodes::SnapshotUnavailable,
+ str::stream()
+ << "Unable to read from a snapshot due to pending collection catalog "
+ "changes; please retry the operation. Snapshot timestamp is "
+ << mySnapshot->toString()
+ << ". Collection minimum is "
+ << minSnapshot->toString());
+ }
+
// During batch application on secondaries, there is a potential to read inconsistent states
// that would normally be protected by the PBWM lock. In order to serve secondary reads
// during this period, we default to not acquiring the lock (by setting
@@ -139,12 +156,11 @@ AutoGetCollectionForRead::AutoGetCollectionForRead(OperationContext* opCtx,
? boost::optional<Timestamp>(replCoord->getMyLastAppliedOpTime().getTimestamp())
: boost::none;
- auto minSnapshot = coll->getMinimumVisibleSnapshot();
if (!_conflictingCatalogChanges(opCtx, minSnapshot, lastAppliedTimestamp)) {
return;
}
- auto readSource = opCtx->recoveryUnit()->getTimestampReadSource();
+ readSource = opCtx->recoveryUnit()->getTimestampReadSource();
invariant(lastAppliedTimestamp ||
readSource == RecoveryUnit::ReadSource::kMajorityCommitted);
invariant(readConcernLevel != repl::ReadConcernLevel::kSnapshotReadConcern);