diff --git a/src/mongo/db/s/shard_filtering_metadata_refresh.cpp b/src/mongo/db/s/shard_filtering_metadata_refresh.cpp index 0895d38bd84..55bd6297888 100644 --- a/src/mongo/db/s/shard_filtering_metadata_refresh.cpp +++ b/src/mongo/db/s/shard_filtering_metadata_refresh.cpp @@ -58,6 +58,25 @@ MONGO_FAIL_POINT_DEFINE(skipDatabaseVersionMetadataRefresh); MONGO_FAIL_POINT_DEFINE(skipShardFilteringMetadataRefresh); MONGO_FAIL_POINT_DEFINE(hangInRecoverRefreshThread); +SharedSemiFuture asyncDbVersionRefresh(OperationContext* opCtx, StringData dbName) { + return ExecutorFuture{Grid::get(opCtx)->getExecutorPool()->getFixedExecutor()} + .then([serviceCtx{opCtx->getServiceContext()}, dbName] { + ThreadClient tc{"RefreshDbVersionThread", serviceCtx}; + { + stdx::lock_guard lk{*tc.get()}; + tc->setSystemOperationKillableByStepdown(lk); + } + + const auto uniqueOpCtx{tc->makeOperationContext()}; + auto opCtx{uniqueOpCtx.get()}; + opCtx->setAlwaysInterruptAtStepDownOrUp_UNSAFE(); + + forceDatabaseRefresh(opCtx, dbName); + }) + .semi() + .share(); +} + void onDbVersionMismatch(OperationContext* opCtx, const StringData dbName, boost::optional clientDbVersion) { @@ -91,7 +110,15 @@ void onDbVersionMismatch(OperationContext* opCtx, return; } - forceDatabaseRefresh(opCtx, dbName); + logd("DEBUG-0 Refreshing... db={}", dbName); + auto future = asyncDbVersionRefresh(opCtx, dbName); + try { + future.get(opCtx); + } catch (const DBException& e) { + logd("DEBUG-0 EXCEPTION db={} e={}", dbName, e); + throw; + } + logd("DEBUG-1 Refreshed db={}", dbName); } // Return true if joins a shard version update/recover/refresh (in that case, all locks are dropped) @@ -526,7 +553,9 @@ void forceDatabaseRefresh(OperationContext* opCtx, const StringData dbName) { // The cached version is older than the refreshed version; update the cached version. // TODO SERVER-67440 Use dbName directly + logd("DEBUG-1 Locking... db={}", dbName); Lock::DBLock dbLock(opCtx, DatabaseName(boost::none, dbName), MODE_X); + logd("DEBUG-1 Locked db={}", dbName); DatabaseHolder::get(opCtx)->openDb(opCtx, dbName); DatabaseHolder::get(opCtx)->setDbInfo(opCtx, dbName, *refreshedDbInfo); }