diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/catalog/uuid_catalog.cpp | 15 | ||||
-rw-r--r-- | src/mongo/db/catalog/uuid_catalog.h | 8 | ||||
-rw-r--r-- | src/mongo/db/op_observer_impl.cpp | 11 | ||||
-rw-r--r-- | src/mongo/db/op_observer_noop.cpp | 11 | ||||
-rw-r--r-- | src/mongo/db/repl/storage_interface_impl.cpp | 3 |
5 files changed, 36 insertions, 12 deletions
diff --git a/src/mongo/db/catalog/uuid_catalog.cpp b/src/mongo/db/catalog/uuid_catalog.cpp index d6efb818d6d..07c4e3f70de 100644 --- a/src/mongo/db/catalog/uuid_catalog.cpp +++ b/src/mongo/db/catalog/uuid_catalog.cpp @@ -63,11 +63,22 @@ void UUIDCatalog::onDropCollection(OperationContext* opCtx, CollectionUUID uuid) } void UUIDCatalog::onRenameCollection(OperationContext* opCtx, - Collection* newColl, + GetNewCollectionFunction getNewCollection, CollectionUUID uuid) { Collection* oldColl = removeUUIDCatalogEntry(uuid); - registerUUIDCatalogEntry(uuid, newColl); + opCtx->recoveryUnit()->onCommit([this, getNewCollection, uuid] { + // Reset current UUID entry in case some other operation updates the UUID catalog before the + // WUOW is committed. registerUUIDCatalogEntry() is a no-op if there's an existing UUID + // entry. + removeUUIDCatalogEntry(uuid); + auto newColl = getNewCollection(); + invariant(newColl); + registerUUIDCatalogEntry(uuid, newColl); + }); opCtx->recoveryUnit()->onRollback([this, oldColl, uuid] { + // Reset current UUID entry in case some other operation updates the UUID catalog before the + // WUOW is rolled back. registerUUIDCatalogEntry() is a no-op if there's an existing UUID + // entry. removeUUIDCatalogEntry(uuid); registerUUIDCatalogEntry(uuid, oldColl); }); diff --git a/src/mongo/db/catalog/uuid_catalog.h b/src/mongo/db/catalog/uuid_catalog.h index 783affa6795..0dd1487fa2a 100644 --- a/src/mongo/db/catalog/uuid_catalog.h +++ b/src/mongo/db/catalog/uuid_catalog.h @@ -33,6 +33,7 @@ #include "mongo/base/disallow_copying.h" #include "mongo/db/catalog/collection.h" #include "mongo/db/service_context.h" +#include "mongo/stdx/functional.h" #include "mongo/util/uuid.h" namespace mongo { @@ -66,8 +67,13 @@ public: /** * Combination of onDropCollection and onCreateCollection. + * 'getNewCollection' is a function that returns collection to be registered when the current + * write unit of work is committed. */ - void onRenameCollection(OperationContext* opCtx, Collection* newColl, CollectionUUID uuid); + using GetNewCollectionFunction = stdx::function<Collection*()>; + void onRenameCollection(OperationContext* opCtx, + GetNewCollectionFunction getNewCollection, + CollectionUUID uuid); /** * Implies onDropCollection for all collections in db, but is not transactional. diff --git a/src/mongo/db/op_observer_impl.cpp b/src/mongo/db/op_observer_impl.cpp index 8c103798fd6..d03d9937e85 100644 --- a/src/mongo/db/op_observer_impl.cpp +++ b/src/mongo/db/op_observer_impl.cpp @@ -527,11 +527,14 @@ repl::OpTime OpObserverImpl::onRenameCollection(OperationContext* opCtx, // Finally update the UUID Catalog. if (uuid) { - auto db = dbHolder().get(opCtx, toCollection.db()); - auto newColl = db->getCollection(opCtx, toCollection); - invariant(newColl); + auto getNewCollection = [opCtx, toCollection] { + auto db = dbHolder().get(opCtx, toCollection.db()); + auto newColl = db->getCollection(opCtx, toCollection); + invariant(newColl); + return newColl; + }; UUIDCatalog& catalog = UUIDCatalog::get(opCtx); - catalog.onRenameCollection(opCtx, newColl, uuid.get()); + catalog.onRenameCollection(opCtx, getNewCollection, uuid.get()); } return renameOpTime; diff --git a/src/mongo/db/op_observer_noop.cpp b/src/mongo/db/op_observer_noop.cpp index a0ad429a6c0..06f5e8384a6 100644 --- a/src/mongo/db/op_observer_noop.cpp +++ b/src/mongo/db/op_observer_noop.cpp @@ -127,11 +127,14 @@ repl::OpTime OpObserverNoop::onRenameCollection(OperationContext* opCtx, // Finally update the UUID Catalog. if (uuid) { - auto db = dbHolder().get(opCtx, toCollection.db()); - auto newColl = db->getCollection(opCtx, toCollection); - invariant(newColl); + auto getNewCollection = [opCtx, toCollection] { + auto db = dbHolder().get(opCtx, toCollection.db()); + auto newColl = db->getCollection(opCtx, toCollection); + invariant(newColl); + return newColl; + }; UUIDCatalog& catalog = UUIDCatalog::get(opCtx); - catalog.onRenameCollection(opCtx, newColl, uuid.get()); + catalog.onRenameCollection(opCtx, getNewCollection, uuid.get()); } return {}; diff --git a/src/mongo/db/repl/storage_interface_impl.cpp b/src/mongo/db/repl/storage_interface_impl.cpp index d6c66ad51d9..a2dca57abdd 100644 --- a/src/mongo/db/repl/storage_interface_impl.cpp +++ b/src/mongo/db/repl/storage_interface_impl.cpp @@ -448,7 +448,8 @@ Status StorageInterfaceImpl::renameCollection(OperationContext* opCtx, auto newColl = autoDB.getDb()->getCollection(opCtx, toNS); if (newColl->uuid()) { - UUIDCatalog::get(opCtx).onRenameCollection(opCtx, newColl, newColl->uuid().get()); + UUIDCatalog::get(opCtx).onRenameCollection( + opCtx, [newColl] { return newColl; }, newColl->uuid().get()); } wunit.commit(); return status; |