summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJordi Serra Torrens <jordi.serra-torrens@mongodb.com>2021-05-17 07:49:00 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-05-18 13:52:44 +0000
commit5c9288ff2d32ef9b24625883e6f67d279f344356 (patch)
tree7c24acd43a3c4029881e873490c3d9569c9d8c4e /src
parentf62706daa8f17a2338b98860b35aac66c376bfb6 (diff)
downloadmongo-5c9288ff2d32ef9b24625883e6f67d279f344356.tar.gz
SERVER-56956 ScopedShardVersionCriticalSection can leave critical section held if filtering metadata refresh fails
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/s/shard_filtering_metadata_refresh.cpp27
-rw-r--r--src/mongo/db/s/shard_filtering_metadata_refresh.h2
2 files changed, 20 insertions, 9 deletions
diff --git a/src/mongo/db/s/shard_filtering_metadata_refresh.cpp b/src/mongo/db/s/shard_filtering_metadata_refresh.cpp
index 7f7541a4b79..6a04f9b916b 100644
--- a/src/mongo/db/s/shard_filtering_metadata_refresh.cpp
+++ b/src/mongo/db/s/shard_filtering_metadata_refresh.cpp
@@ -318,18 +318,16 @@ ScopedShardVersionCriticalSection::ScopedShardVersionCriticalSection(OperationCo
}
}
- forceShardFilteringMetadataRefresh(_opCtx, _nss);
+ try {
+ forceShardFilteringMetadataRefresh(_opCtx, _nss);
+ } catch (const DBException&) {
+ _cleanup();
+ throw;
+ }
}
ScopedShardVersionCriticalSection::~ScopedShardVersionCriticalSection() {
- UninterruptibleLockGuard noInterrupt(_opCtx->lockState());
- // DBLock and CollectionLock are used here to avoid throwing further recursive stale config
- // errors.
- Lock::DBLock dbLock(_opCtx, _nss.db(), MODE_IX);
- Lock::CollectionLock collLock(_opCtx, _nss, MODE_IX);
- auto* const csr = CollectionShardingRuntime::get(_opCtx, _nss);
- auto csrLock = CollectionShardingRuntime::CSRLock::lockExclusive(_opCtx, csr);
- csr->exitCriticalSection(csrLock, _reason);
+ _cleanup();
}
void ScopedShardVersionCriticalSection::enterCommitPhase() {
@@ -344,6 +342,17 @@ void ScopedShardVersionCriticalSection::enterCommitPhase() {
csr->enterCriticalSectionCommitPhase(csrLock, _reason);
}
+void ScopedShardVersionCriticalSection::_cleanup() {
+ UninterruptibleLockGuard noInterrupt(_opCtx->lockState());
+ // DBLock and CollectionLock are used here to avoid throwing further recursive stale config
+ // errors.
+ Lock::DBLock dbLock(_opCtx, _nss.db(), MODE_IX);
+ Lock::CollectionLock collLock(_opCtx, _nss, MODE_IX);
+ auto* const csr = CollectionShardingRuntime::get(_opCtx, _nss);
+ auto csrLock = CollectionShardingRuntime::CSRLock::lockExclusive(_opCtx, csr);
+ csr->exitCriticalSection(csrLock, _reason);
+}
+
Status onShardVersionMismatchNoExcept(OperationContext* opCtx,
const NamespaceString& nss,
boost::optional<ChunkVersion> shardVersionReceived) noexcept {
diff --git a/src/mongo/db/s/shard_filtering_metadata_refresh.h b/src/mongo/db/s/shard_filtering_metadata_refresh.h
index 3801654aace..8ebec832d75 100644
--- a/src/mongo/db/s/shard_filtering_metadata_refresh.h
+++ b/src/mongo/db/s/shard_filtering_metadata_refresh.h
@@ -119,6 +119,8 @@ public:
void enterCommitPhase();
private:
+ void _cleanup();
+
OperationContext* const _opCtx;
const NamespaceString _nss;
const BSONObj _reason;