diff options
author | Geert Bosch <geert@mongodb.com> | 2019-07-23 15:48:19 -0400 |
---|---|---|
committer | Geert Bosch <geert@mongodb.com> | 2019-07-26 00:23:40 -0400 |
commit | 911a2117e9b75d51dafa2d6dc5ba97bd8b85dc55 (patch) | |
tree | 3899544bf0b93ee68dd9ee273d361584233bf62e | |
parent | 27b4ffbccb9f9b7bc40c03c7824e0b8f0cc0a248 (diff) | |
download | mongo-911a2117e9b75d51dafa2d6dc5ba97bd8b85dc55.tar.gz |
SERVER-42300 Retry, not skip, renamed ns in forEachCollectionFromDb
(cherry picked from commit 917d338c4bf52dc8dce2c0e585a676385e81ed1c)
-rw-r--r-- | jstests/concurrency/fsm_workloads/rename_collection_chain.js | 26 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection_catalog_helper.cpp | 26 |
2 files changed, 38 insertions, 14 deletions
diff --git a/jstests/concurrency/fsm_workloads/rename_collection_chain.js b/jstests/concurrency/fsm_workloads/rename_collection_chain.js index cd6a541c170..cf2f6f49424 100644 --- a/jstests/concurrency/fsm_workloads/rename_collection_chain.js +++ b/jstests/concurrency/fsm_workloads/rename_collection_chain.js @@ -9,7 +9,6 @@ */ var $config = (function() { - var data = { // Use the workload name as a prefix for the collection name, // since the workload name is assumed to be unique. @@ -17,7 +16,6 @@ var $config = (function() { }; var states = (function() { - function uniqueCollectionName(prefix, tid, num) { return prefix + tid + '_' + num; } @@ -35,11 +33,30 @@ var $config = (function() { this.fromCollName = toCollName; } - return {init: init, rename: rename}; + function listCollections(db, collName) { + const collectionInfos = db.getCollectionInfos(); + if (!this.allCollectionsInitialized) { + if (collectionInfos.length === this.threadCount) { + this.allCollectionsInitialized = true; + jsTestLog(`All collections visible to thread ${this.tid}: ${ + tojsononeline(collectionInfos)}`); + } + } else { + const numColls = + collectionInfos.filter((collInfo) => collInfo.name.startsWith(this.prefix)) + .length; + assertAlways.eq(numColls, this.threadCount, () => tojson(collectionInfos)); + } + } + return {init: init, rename: rename, listCollections: listCollections}; })(); - var transitions = {init: {rename: 1}, rename: {rename: 1}}; + var transitions = { + init: {rename: 1}, + rename: {rename: 0.9, listCollections: 0.1}, + listCollections: {rename: 1}, + }; return { threadCount: 10, @@ -48,5 +65,4 @@ var $config = (function() { states: states, transitions: transitions, }; - })(); diff --git a/src/mongo/db/catalog/collection_catalog_helper.cpp b/src/mongo/db/catalog/collection_catalog_helper.cpp index 2cb11844d71..620a9a2a08a 100644 --- a/src/mongo/db/catalog/collection_catalog_helper.cpp +++ b/src/mongo/db/catalog/collection_catalog_helper.cpp @@ -51,18 +51,26 @@ void forEachCollectionFromDb(OperationContext* opCtx, continue; } - auto nss = catalog.lookupNSSByUUID(uuid); + boost::optional<Lock::CollectionLock> clk; + Collection* collection = nullptr; - // If the NamespaceString can't be resolved from the uuid, then the collection was dropped. - if (!nss) { - continue; - } + while (auto nss = catalog.lookupNSSByUUID(uuid)) { + // Get a fresh snapshot for each locked collection to see any catalog changes. + clk.emplace(opCtx, *nss, collLockMode); + opCtx->recoveryUnit()->abandonSnapshot(); - Lock::CollectionLock clk(opCtx, *nss, collLockMode); - opCtx->recoveryUnit()->abandonSnapshot(); + if (catalog.lookupNSSByUUID(uuid) == nss) { + // Success: locked the namespace and the UUID still maps to it. + collection = catalog.lookupCollectionByUUID(uuid); + invariant(collection); + break; + } + // Failed: collection got renamed before locking it, so unlock and try again. + clk.reset(); + } - auto collection = catalog.lookupCollectionByUUID(uuid); - if (!collection || collection->ns() != *nss) + // The NamespaceString couldn't be resolved from the uuid, so the collection was dropped. + if (!collection) continue; if (!callback(collection)) |