summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/catalog/uuid_catalog.cpp15
-rw-r--r--src/mongo/db/catalog/uuid_catalog.h8
-rw-r--r--src/mongo/db/op_observer_impl.cpp11
-rw-r--r--src/mongo/db/op_observer_noop.cpp11
-rw-r--r--src/mongo/db/repl/storage_interface_impl.cpp3
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;