diff options
author | William Schultz <william.schultz@mongodb.com> | 2019-03-25 15:40:18 -0400 |
---|---|---|
committer | William Schultz <william.schultz@mongodb.com> | 2019-03-25 15:40:18 -0400 |
commit | cdc1359a61de42673455c4f64eb9986da5ef0df4 (patch) | |
tree | 560c1c5bf6cdbd3383b64a4f38505c02460a50af /src/mongo/db/db_raii.cpp | |
parent | 04b7774c27587b5b66ac9171b962145ce00d5372 (diff) | |
download | mongo-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.cpp | 20 |
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); |