summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaria van Keulen <maria.vankeulen@mongodb.com>2020-01-07 15:15:10 +0000
committerevergreen <evergreen@mongodb.com>2020-01-07 15:15:10 +0000
commitcb293d4de806e8089e4fb08926124ed18b2fa578 (patch)
treef073318c41619271ff050855b5b80fc1d6f957bb /src
parent47a810f853921657acb78db1110590c0c380091f (diff)
downloadmongo-cb293d4de806e8089e4fb08926124ed18b2fa578.tar.gz
SERVER-44139 Allow collection creation in multi-document transactions
This commit allows the feature for single-node replica sets only.
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/auth/SConscript1
-rw-r--r--src/mongo/db/auth/auth_op_observer.cpp4
-rw-r--r--src/mongo/db/catalog/create_collection.cpp4
-rw-r--r--src/mongo/db/catalog/index_build_block.cpp5
-rw-r--r--src/mongo/db/catalog/index_catalog_impl.cpp20
-rw-r--r--src/mongo/db/commands.cpp17
-rw-r--r--src/mongo/db/commands/create_indexes.cpp2
-rw-r--r--src/mongo/db/logical_clock.cpp8
-rw-r--r--src/mongo/db/logical_clock.h1
-rw-r--r--src/mongo/db/op_observer_impl.cpp20
-rw-r--r--src/mongo/db/op_observer_util.cpp24
-rw-r--r--src/mongo/db/op_observer_util.h5
-rw-r--r--src/mongo/db/repl/SConscript3
-rw-r--r--src/mongo/db/repl/oplog_entry.cpp38
-rw-r--r--src/mongo/db/repl/oplog_entry.h10
-rw-r--r--src/mongo/db/storage/biggie/biggie_kv_engine.cpp11
-rw-r--r--src/mongo/db/storage/biggie/biggie_kv_engine.h2
-rw-r--r--src/mongo/db/storage/biggie/biggie_record_store.cpp11
-rw-r--r--src/mongo/db/storage/biggie/biggie_record_store.h2
-rw-r--r--src/mongo/db/storage/biggie/biggie_sorted_impl.cpp7
-rw-r--r--src/mongo/db/storage/biggie/biggie_sorted_impl.h2
-rw-r--r--src/mongo/db/storage/devnull/devnull_kv_engine.h2
-rw-r--r--src/mongo/db/storage/durable_catalog_impl.cpp33
-rw-r--r--src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.cpp4
-rw-r--r--src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.h2
-rw-r--r--src/mongo/db/storage/kv/kv_drop_pending_ident_reaper.cpp2
-rw-r--r--src/mongo/db/storage/kv/kv_drop_pending_ident_reaper_test.cpp24
-rw-r--r--src/mongo/db/storage/kv/kv_engine.h10
-rw-r--r--src/mongo/db/storage/kv/kv_engine_test_harness.cpp2
-rw-r--r--src/mongo/db/storage/kv/storage_engine_test.cpp8
-rw-r--r--src/mongo/db/storage/kv/temporary_kv_record_store.cpp2
-rw-r--r--src/mongo/db/storage/mobile/mobile_kv_engine.cpp7
-rw-r--r--src/mongo/db/storage/mobile/mobile_kv_engine.h2
-rw-r--r--src/mongo/db/storage/storage_engine_impl.cpp8
-rw-r--r--src/mongo/db/storage/storage_engine_test_fixture.h6
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp6
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h2
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp4
-rw-r--r--src/mongo/dbtests/catalogtests.cpp8
39 files changed, 206 insertions, 123 deletions
diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript
index 580367c9016..6ffcf7467ba 100644
--- a/src/mongo/db/auth/SConscript
+++ b/src/mongo/db/auth/SConscript
@@ -58,6 +58,7 @@ env.Library(
'$BUILD_DIR/mongo/db/index/index_descriptor',
'$BUILD_DIR/mongo/db/op_observer',
'$BUILD_DIR/mongo/db/op_observer_util',
+ '$BUILD_DIR/mongo/db/repl/oplog_entry',
'$BUILD_DIR/mongo/db/s/sharding_api_d',
]
)
diff --git a/src/mongo/db/auth/auth_op_observer.cpp b/src/mongo/db/auth/auth_op_observer.cpp
index df979414ba6..60db0b23f77 100644
--- a/src/mongo/db/auth/auth_op_observer.cpp
+++ b/src/mongo/db/auth/auth_op_observer.cpp
@@ -35,6 +35,7 @@
#include "mongo/db/catalog/collection_options.h"
#include "mongo/db/op_observer_util.h"
#include "mongo/db/operation_context.h"
+#include "mongo/db/repl/oplog_entry.h"
namespace mongo {
@@ -101,7 +102,8 @@ void AuthOpObserver::onCreateCollection(OperationContext* opCtx,
const OplogSlot& createOpTime) {
const auto cmdNss = collectionName.getCommandNS();
- const auto cmdObj = makeCreateCollCmdObj(collectionName, options, idIndex);
+ const auto cmdObj =
+ repl::MutableOplogEntry::makeCreateCollCmdObj(collectionName, options, idIndex);
AuthorizationManager::get(opCtx->getServiceContext())
->logOp(opCtx, "c", cmdNss, cmdObj, nullptr);
diff --git a/src/mongo/db/catalog/create_collection.cpp b/src/mongo/db/catalog/create_collection.cpp
index dc841b95b2c..75754ad4da3 100644
--- a/src/mongo/db/catalog/create_collection.cpp
+++ b/src/mongo/db/catalog/create_collection.cpp
@@ -190,6 +190,10 @@ Status createCollection(OperationContext* opCtx,
}
if (collectionOptions.isView()) {
+ uassert(ErrorCodes::OperationNotSupportedInTransaction,
+ str::stream() << "Cannot create a view in a multi-document "
+ "transaction.",
+ !opCtx->inMultiDocumentTransaction());
return _createView(opCtx, nss, collectionOptions, idIndex);
} else {
return _createCollection(opCtx, nss, collectionOptions, idIndex);
diff --git a/src/mongo/db/catalog/index_build_block.cpp b/src/mongo/db/catalog/index_build_block.cpp
index 85e184b7036..148ccf20cfb 100644
--- a/src/mongo/db/catalog/index_build_block.cpp
+++ b/src/mongo/db/catalog/index_build_block.cpp
@@ -171,8 +171,9 @@ void IndexBuildBlock::success(OperationContext* opCtx, Collection* collection) {
log() << "index build: done building index " << _indexName << " on ns " << _nss;
collection->indexBuildSuccess(opCtx, _indexCatalogEntry);
+ auto svcCtx = opCtx->getClient()->getServiceContext();
- opCtx->recoveryUnit()->onCommit([opCtx, entry = _indexCatalogEntry, coll = collection](
+ opCtx->recoveryUnit()->onCommit([svcCtx, entry = _indexCatalogEntry, coll = collection](
boost::optional<Timestamp> commitTime) {
// Note: this runs after the WUOW commits but before we release our X lock on the
// collection. This means that any snapshot created after this must include the full
@@ -182,7 +183,7 @@ void IndexBuildBlock::success(OperationContext* opCtx, Collection* collection) {
// timestamp. We use the cluster time since it's guaranteed to be greater than the
// time of the index build. It is possible the cluster time could be in the future,
// and we will need to do another write to reach the minimum visible snapshot.
- commitTime = LogicalClock::getClusterTimeForReplicaSet(opCtx).asTimestamp();
+ commitTime = LogicalClock::getClusterTimeForReplicaSet(svcCtx).asTimestamp();
}
entry->setMinimumVisibleSnapshot(commitTime.get());
// We must also set the minimum visible snapshot on the collection like during init().
diff --git a/src/mongo/db/catalog/index_catalog_impl.cpp b/src/mongo/db/catalog/index_catalog_impl.cpp
index 8f50b465447..043161e9fb7 100644
--- a/src/mongo/db/catalog/index_catalog_impl.cpp
+++ b/src/mongo/db/catalog/index_catalog_impl.cpp
@@ -376,7 +376,8 @@ IndexCatalogEntry* IndexCatalogImpl::createIndexEntry(OperationContext* opCtx,
_buildingIndexes.add(std::move(entry));
}
- if (!initFromDisk) {
+ if (!initFromDisk &&
+ UncommittedCollections::getForTxn(opCtx, descriptorPtr->parentNS()) == nullptr) {
opCtx->recoveryUnit()->onRollback([this, opCtx, isReadyIndex, descriptor = descriptorPtr] {
// Need to preserve indexName as descriptor no longer exists after remove().
const std::string indexName = descriptor->indexName();
@@ -1607,14 +1608,17 @@ void IndexCatalogImpl::indexBuildSuccess(OperationContext* opCtx, IndexCatalogEn
index->setIndexBuildInterceptor(nullptr);
index->setIsReady(true);
- opCtx->recoveryUnit()->onRollback([this, index, interceptor]() {
- auto releasedEntry = _readyIndexes.release(index->descriptor());
- invariant(releasedEntry.get() == index);
- _buildingIndexes.add(std::move(releasedEntry));
+ // Only roll back index changes that are part of pre-existing collections.
+ if (UncommittedCollections::getForTxn(opCtx, index->descriptor()->parentNS()) == nullptr) {
+ opCtx->recoveryUnit()->onRollback([this, index, interceptor]() {
+ auto releasedEntry = _readyIndexes.release(index->descriptor());
+ invariant(releasedEntry.get() == index);
+ _buildingIndexes.add(std::move(releasedEntry));
- index->setIndexBuildInterceptor(interceptor);
- index->setIsReady(false);
- });
+ index->setIndexBuildInterceptor(interceptor);
+ index->setIsReady(false);
+ });
+ }
}
StatusWith<BSONObj> IndexCatalogImpl::_fixIndexSpec(OperationContext* opCtx,
diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp
index e67e02b8c85..0df24b22613 100644
--- a/src/mongo/db/commands.cpp
+++ b/src/mongo/db/commands.cpp
@@ -110,11 +110,12 @@ bool checkAuthorizationImplPreParse(OperationContext* opCtx,
}
// The command names that are allowed in a multi-document transaction.
+const StringMap<int> txnCmdWhitelistFCV44 = {
+ {"create", 1}, {"createIndexes", 1}, {"_configsvrCreateCollection", 1}};
const StringMap<int> txnCmdWhitelist = {{"abortTransaction", 1},
{"aggregate", 1},
{"commitTransaction", 1},
{"coordinateCommitTransaction", 1},
- {"createIndexes", 1},
{"delete", 1},
{"distinct", 1},
{"find", 1},
@@ -443,9 +444,21 @@ void CommandHelpers::canUseTransactions(const NamespaceString& nss,
"http://dochub.mongodb.org/core/transaction-count for a recommended alternative.",
cmdName != "count"_sd);
+ auto inTxnWhitelist = txnCmdWhitelist.find(cmdName) != txnCmdWhitelist.cend();
+ auto inTxnWhitelistFCV44 = txnCmdWhitelistFCV44.find(cmdName) != txnCmdWhitelistFCV44.cend();
+ auto isFullyUpgradedTo44 =
+ (serverGlobalParams.featureCompatibility.getVersion() ==
+ ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo44);
+
+ uassert(ErrorCodes::OperationNotSupportedInTransaction,
+ str::stream() << "Cannot run '" << cmdName
+ << "' in a multi-document transaction unless the "
+ "featureCompatibilityVersion is equal to 4.4.",
+ isFullyUpgradedTo44 || !inTxnWhitelistFCV44);
+
uassert(ErrorCodes::OperationNotSupportedInTransaction,
str::stream() << "Cannot run '" << cmdName << "' in a multi-document transaction.",
- txnCmdWhitelist.find(cmdName) != txnCmdWhitelist.cend());
+ inTxnWhitelist || inTxnWhitelistFCV44);
const auto dbName = nss.db();
diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp
index 6b2b702d38b..55b4857c1d7 100644
--- a/src/mongo/db/commands/create_indexes.cpp
+++ b/src/mongo/db/commands/create_indexes.cpp
@@ -471,7 +471,7 @@ BSONObj runCreateIndexesOnNewCollection(OperationContext* opCtx,
auto createStatus =
createCollection(opCtx, ns.db().toString(), builder.obj().getOwned(), idIndexSpec);
- if (!UncommittedCollections::get(opCtx).hasExclusiveAccessToCollection(opCtx, ns)) {
+ if (createStatus == ErrorCodes::NamespaceExists) {
// We should retry the createIndexes command so we can perform the checks for index
// and/or collection existence again.
throw WriteConflictException();
diff --git a/src/mongo/db/logical_clock.cpp b/src/mongo/db/logical_clock.cpp
index 5cc982465d9..6dea3e7acdc 100644
--- a/src/mongo/db/logical_clock.cpp
+++ b/src/mongo/db/logical_clock.cpp
@@ -52,14 +52,18 @@ bool lessThanOrEqualToMaxPossibleTime(LogicalTime time, uint64_t nTicks) {
}
} // namespace
-LogicalTime LogicalClock::getClusterTimeForReplicaSet(OperationContext* opCtx) {
+LogicalTime LogicalClock::getClusterTimeForReplicaSet(ServiceContext* svcCtx) {
if (getGlobalReplSettings().usingReplSets()) {
- return get(opCtx)->getClusterTime();
+ return get(svcCtx)->getClusterTime();
}
return {};
}
+LogicalTime LogicalClock::getClusterTimeForReplicaSet(OperationContext* opCtx) {
+ return getClusterTimeForReplicaSet(opCtx->getClient()->getServiceContext());
+}
+
LogicalClock* LogicalClock::get(ServiceContext* service) {
return getLogicalClock(service).get();
}
diff --git a/src/mongo/db/logical_clock.h b/src/mongo/db/logical_clock.h
index 28191be87f6..ec4bddc518a 100644
--- a/src/mongo/db/logical_clock.h
+++ b/src/mongo/db/logical_clock.h
@@ -53,6 +53,7 @@ public:
* Returns the current cluster time if this is a replica set node, otherwise returns a null
* logical time.
*/
+ static LogicalTime getClusterTimeForReplicaSet(ServiceContext* svcCtx);
static LogicalTime getClusterTimeForReplicaSet(OperationContext* opCtx);
/**
diff --git a/src/mongo/db/op_observer_impl.cpp b/src/mongo/db/op_observer_impl.cpp
index 1644ff3b582..4966ef4b333 100644
--- a/src/mongo/db/op_observer_impl.cpp
+++ b/src/mongo/db/op_observer_impl.cpp
@@ -608,13 +608,27 @@ void OpObserverImpl::onCreateCollection(OperationContext* opCtx,
const CollectionOptions& options,
const BSONObj& idIndex,
const OplogSlot& createOpTime) {
- if (!collectionName.isSystemDotProfile()) {
- // do not replicate system.profile modifications
+ // do not replicate system.profile modifications
+ if (collectionName.isSystemDotProfile()) {
+ return;
+ }
+
+ auto txnParticipant = TransactionParticipant::get(opCtx);
+ const bool inMultiDocumentTransaction =
+ txnParticipant && opCtx->writesAreReplicated() && txnParticipant.transactionIsOpen();
+
+ if (inMultiDocumentTransaction) {
+ invariant(serverGlobalParams.featureCompatibility.getVersion() ==
+ ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo44);
+ auto operation = MutableOplogEntry::makeCreateCommand(collectionName, options, idIndex);
+ txnParticipant.addTransactionOperation(opCtx, operation);
+ } else {
MutableOplogEntry oplogEntry;
oplogEntry.setOpType(repl::OpTypeEnum::kCommand);
oplogEntry.setNss(collectionName.getCommandNS());
oplogEntry.setUuid(options.uuid);
- oplogEntry.setObject(makeCreateCollCmdObj(collectionName, options, idIndex));
+ oplogEntry.setObject(
+ MutableOplogEntry::makeCreateCollCmdObj(collectionName, options, idIndex));
oplogEntry.setOpTime(createOpTime);
logOperation(opCtx, &oplogEntry);
}
diff --git a/src/mongo/db/op_observer_util.cpp b/src/mongo/db/op_observer_util.cpp
index b1bc7074915..9c03a37a3db 100644
--- a/src/mongo/db/op_observer_util.cpp
+++ b/src/mongo/db/op_observer_util.cpp
@@ -65,28 +65,4 @@ BSONObj makeCollModCmdObj(const BSONObj& collModCmd,
return cmdObjBuilder.obj();
}
-BSONObj makeCreateCollCmdObj(const NamespaceString& collectionName,
- const CollectionOptions& options,
- const BSONObj& idIndex) {
- BSONObjBuilder b;
- b.append("create", collectionName.coll().toString());
- {
- // Don't store the UUID as part of the options, but instead only at the top level
- CollectionOptions optionsToStore = options;
- optionsToStore.uuid.reset();
- b.appendElements(optionsToStore.toBSON());
- }
-
- // Include the full _id index spec in the oplog for index versions >= 2.
- if (!idIndex.isEmpty()) {
- auto versionElem = idIndex[IndexDescriptor::kIndexVersionFieldName];
- invariant(versionElem.isNumber());
- if (IndexDescriptor::IndexVersion::kV2 <=
- static_cast<IndexDescriptor::IndexVersion>(versionElem.numberInt())) {
- b.append("idIndex", idIndex);
- }
- }
-
- return b.obj();
-}
} // namespace mongo
diff --git a/src/mongo/db/op_observer_util.h b/src/mongo/db/op_observer_util.h
index 7e60c66cca8..800a1486d4d 100644
--- a/src/mongo/db/op_observer_util.h
+++ b/src/mongo/db/op_observer_util.h
@@ -34,11 +34,6 @@
#include "mongo/db/op_observer.h"
namespace mongo {
-
-BSONObj makeCreateCollCmdObj(const NamespaceString& collectionName,
- const CollectionOptions& options,
- const BSONObj& idIndex);
-
BSONObj makeCollModCmdObj(const BSONObj& collModCmd,
const CollectionOptions& oldCollOptions,
boost::optional<TTLCollModInfo> ttlInfo);
diff --git a/src/mongo/db/repl/SConscript b/src/mongo/db/repl/SConscript
index 4b672142624..391f09637df 100644
--- a/src/mongo/db/repl/SConscript
+++ b/src/mongo/db/repl/SConscript
@@ -179,11 +179,11 @@ env.Library(
LIBDEPS=[
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/idl/idl_parser',
- '$BUILD_DIR/mongo/db/catalog/collection_options',
'$BUILD_DIR/mongo/db/catalog/health_log',
'$BUILD_DIR/mongo/db/db_raii',
],
LIBDEPS_PRIVATE=[
+ '$BUILD_DIR/mongo/db/catalog/collection_options',
'$BUILD_DIR/mongo/db/query_exec',
'$BUILD_DIR/mongo/util/md5',
],
@@ -488,6 +488,7 @@ env.Library(
'optime_and_wall_time_base',
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/db/logical_session_id',
+ '$BUILD_DIR/mongo/db/catalog/collection_options',
'$BUILD_DIR/mongo/idl/idl_parser',
],
)
diff --git a/src/mongo/db/repl/oplog_entry.cpp b/src/mongo/db/repl/oplog_entry.cpp
index 4da5afdc4dc..787e54f0384 100644
--- a/src/mongo/db/repl/oplog_entry.cpp
+++ b/src/mongo/db/repl/oplog_entry.cpp
@@ -33,6 +33,7 @@
#include "mongo/db/repl/oplog_entry.h"
+#include "mongo/db/index/index_descriptor.h"
#include "mongo/db/namespace_string.h"
#include "mongo/util/log.h"
#include "mongo/util/time_support.h"
@@ -164,6 +165,31 @@ ReplOperation MutableOplogEntry::makeInsertOperation(const NamespaceString& nss,
return op;
}
+BSONObj MutableOplogEntry::makeCreateCollCmdObj(const NamespaceString& collectionName,
+ const CollectionOptions& options,
+ const BSONObj& idIndex) {
+ BSONObjBuilder b;
+ b.append("create", collectionName.coll().toString());
+ {
+ // Don't store the UUID as part of the options, but instead only at the top level
+ CollectionOptions optionsToStore = options;
+ optionsToStore.uuid.reset();
+ b.appendElements(optionsToStore.toBSON());
+ }
+
+ // Include the full _id index spec in the oplog for index versions >= 2.
+ if (!idIndex.isEmpty()) {
+ auto versionElem = idIndex[IndexDescriptor::kIndexVersionFieldName];
+ invariant(versionElem.isNumber());
+ if (IndexDescriptor::IndexVersion::kV2 <=
+ static_cast<IndexDescriptor::IndexVersion>(versionElem.numberInt())) {
+ b.append("idIndex", idIndex);
+ }
+ }
+
+ return b.obj();
+}
+
ReplOperation MutableOplogEntry::makeUpdateOperation(const NamespaceString nss,
boost::optional<UUID> uuid,
const BSONObj& update,
@@ -177,6 +203,18 @@ ReplOperation MutableOplogEntry::makeUpdateOperation(const NamespaceString nss,
return op;
}
+ReplOperation MutableOplogEntry::makeCreateCommand(const NamespaceString nss,
+ const CollectionOptions& options,
+ const BSONObj& idIndex) {
+
+ ReplOperation op;
+ op.setOpType(OpTypeEnum::kCommand);
+ op.setNss(nss.getCommandNS());
+ op.setUuid(options.uuid);
+ op.setObject(makeCreateCollCmdObj(nss, options, idIndex));
+ return op;
+}
+
ReplOperation MutableOplogEntry::makeDeleteOperation(const NamespaceString& nss,
boost::optional<UUID> uuid,
const BSONObj& docToDelete) {
diff --git a/src/mongo/db/repl/oplog_entry.h b/src/mongo/db/repl/oplog_entry.h
index c01b2766d1b..b1678b37267 100644
--- a/src/mongo/db/repl/oplog_entry.h
+++ b/src/mongo/db/repl/oplog_entry.h
@@ -31,6 +31,7 @@
#include "mongo/bson/bsonobj.h"
#include "mongo/bson/simple_bsonobj_comparator.h"
+#include "mongo/db/catalog/collection_options.h"
#include "mongo/db/logical_session_id.h"
#include "mongo/db/repl/apply_ops_gen.h"
#include "mongo/db/repl/oplog_entry_gen.h"
@@ -90,6 +91,14 @@ public:
boost::optional<UUID> uuid,
const BSONObj& docToDelete);
+ static ReplOperation makeCreateCommand(const NamespaceString nss,
+ const mongo::CollectionOptions& options,
+ const BSONObj& idIndex);
+
+ static BSONObj makeCreateCollCmdObj(const NamespaceString& collectionName,
+ const mongo::CollectionOptions& options,
+ const BSONObj& idIndex);
+
static StatusWith<MutableOplogEntry> parse(const BSONObj& object);
MutableOplogEntry() : OplogEntryBase() {}
@@ -213,6 +222,7 @@ public:
// Make helper functions accessible.
using MutableOplogEntry::getOpTime;
+ using MutableOplogEntry::makeCreateCommand;
using MutableOplogEntry::makeDeleteOperation;
using MutableOplogEntry::makeInsertOperation;
using MutableOplogEntry::makeUpdateOperation;
diff --git a/src/mongo/db/storage/biggie/biggie_kv_engine.cpp b/src/mongo/db/storage/biggie/biggie_kv_engine.cpp
index 370ececd244..2a43de99a32 100644
--- a/src/mongo/db/storage/biggie/biggie_kv_engine.cpp
+++ b/src/mongo/db/storage/biggie/biggie_kv_engine.cpp
@@ -118,21 +118,20 @@ std::unique_ptr<mongo::SortedDataInterface> KVEngine::getSortedDataInterface(
return std::make_unique<SortedDataInterface>(opCtx, ident, desc);
}
-Status KVEngine::dropIdent(OperationContext* opCtx, StringData ident) {
+Status KVEngine::dropIdent(OperationContext* opCtx, mongo::RecoveryUnit* ru, StringData ident) {
Status dropStatus = Status::OK();
if (_idents.count(ident.toString()) > 0) {
// Check if the ident is a RecordStore or a SortedDataInterface then call the corresponding
// truncate. A true value in the map means it is a RecordStore, false a SortedDataInterface.
if (_idents[ident.toString()] == true) { // ident is RecordStore.
CollectionOptions s;
- auto rs = getRecordStore(opCtx, ""_sd, ident, s);
- dropStatus = checked_cast<RecordStore*>(rs.get())
- ->truncateWithoutUpdatingCount(opCtx)
- .getStatus();
+ auto rs = getRecordStore(/*unused*/ opCtx, ""_sd, ident, s);
+ dropStatus =
+ checked_cast<RecordStore*>(rs.get())->truncateWithoutUpdatingCount(ru).getStatus();
} else { // ident is SortedDataInterface.
auto sdi =
std::make_unique<SortedDataInterface>(Ordering::make(BSONObj()), true, ident);
- dropStatus = sdi->truncate(opCtx);
+ dropStatus = sdi->truncate(ru);
}
_idents.erase(ident.toString());
}
diff --git a/src/mongo/db/storage/biggie/biggie_kv_engine.h b/src/mongo/db/storage/biggie/biggie_kv_engine.h
index a9a3582cfdd..2ce35d07cbf 100644
--- a/src/mongo/db/storage/biggie/biggie_kv_engine.h
+++ b/src/mongo/db/storage/biggie/biggie_kv_engine.h
@@ -80,7 +80,7 @@ public:
virtual void endBackup(OperationContext* opCtx) {}
- virtual Status dropIdent(OperationContext* opCtx, StringData ident);
+ virtual Status dropIdent(OperationContext* opCtx, mongo::RecoveryUnit* ru, StringData ident);
virtual bool supportsDocLocking() const {
return true;
diff --git a/src/mongo/db/storage/biggie/biggie_record_store.cpp b/src/mongo/db/storage/biggie/biggie_record_store.cpp
index c4c0c698456..05d325f7bb2 100644
--- a/src/mongo/db/storage/biggie/biggie_record_store.cpp
+++ b/src/mongo/db/storage/biggie/biggie_record_store.cpp
@@ -226,16 +226,17 @@ std::unique_ptr<SeekableRecordCursor> RecordStore::getCursor(OperationContext* o
Status RecordStore::truncate(OperationContext* opCtx) {
SizeAdjuster adjuster(opCtx, this);
- StatusWith<int64_t> s = truncateWithoutUpdatingCount(opCtx);
+ StatusWith<int64_t> s =
+ truncateWithoutUpdatingCount(checked_cast<biggie::RecoveryUnit*>(opCtx->recoveryUnit()));
if (!s.isOK())
return s.getStatus();
return Status::OK();
}
-StatusWith<int64_t> RecordStore::truncateWithoutUpdatingCount(OperationContext* opCtx) {
- auto ru = RecoveryUnit::get(opCtx);
- StringStore* workingCopy(ru->getHead());
+StatusWith<int64_t> RecordStore::truncateWithoutUpdatingCount(mongo::RecoveryUnit* ru) {
+ auto bRu = checked_cast<biggie::RecoveryUnit*>(ru);
+ StringStore* workingCopy(bRu->getHead());
StringStore::const_iterator end = workingCopy->upper_bound(_postfix);
std::vector<std::string> toDelete;
@@ -249,7 +250,7 @@ StatusWith<int64_t> RecordStore::truncateWithoutUpdatingCount(OperationContext*
for (const auto& key : toDelete)
workingCopy->erase(key);
- ru->makeDirty();
+ bRu->makeDirty();
return static_cast<int64_t>(toDelete.size());
}
diff --git a/src/mongo/db/storage/biggie/biggie_record_store.h b/src/mongo/db/storage/biggie/biggie_record_store.h
index d604ba51826..f4281ea528f 100644
--- a/src/mongo/db/storage/biggie/biggie_record_store.h
+++ b/src/mongo/db/storage/biggie/biggie_record_store.h
@@ -92,7 +92,7 @@ public:
bool forward) const final;
virtual Status truncate(OperationContext* opCtx);
- StatusWith<int64_t> truncateWithoutUpdatingCount(OperationContext* opCtx);
+ StatusWith<int64_t> truncateWithoutUpdatingCount(RecoveryUnit* ru);
virtual void cappedTruncateAfter(OperationContext* opCtx, RecordId end, bool inclusive);
diff --git a/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp b/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp
index d55ed2d1bf6..68bcb271f96 100644
--- a/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp
+++ b/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp
@@ -443,8 +443,9 @@ void SortedDataInterface::unindex(OperationContext* opCtx,
// This function is, as of now, not in the interface, but there exists a server ticket to add
// truncate to the list of commands able to be used.
-Status SortedDataInterface::truncate(OperationContext* opCtx) {
- StringStore* workingCopy(RecoveryUnit::get(opCtx)->getHead());
+Status SortedDataInterface::truncate(mongo::RecoveryUnit* ru) {
+ auto bRu = checked_cast<biggie::RecoveryUnit*>(ru);
+ StringStore* workingCopy(bRu->getHead());
std::vector<std::string> toDelete;
auto end = workingCopy->upper_bound(_KSForIdentEnd);
for (auto it = workingCopy->lower_bound(_KSForIdentStart); it != end; ++it) {
@@ -453,7 +454,7 @@ Status SortedDataInterface::truncate(OperationContext* opCtx) {
if (!toDelete.empty()) {
for (const auto& key : toDelete)
workingCopy->erase(key);
- RecoveryUnit::get(opCtx)->makeDirty();
+ bRu->makeDirty();
}
return Status::OK();
diff --git a/src/mongo/db/storage/biggie/biggie_sorted_impl.h b/src/mongo/db/storage/biggie/biggie_sorted_impl.h
index acf8414b9eb..559789df44e 100644
--- a/src/mongo/db/storage/biggie/biggie_sorted_impl.h
+++ b/src/mongo/db/storage/biggie/biggie_sorted_impl.h
@@ -75,7 +75,7 @@ class SortedDataInterface : public ::mongo::SortedDataInterface {
public:
// Truncate is not required at the time of writing but will be when the truncate command is
// created
- Status truncate(OperationContext* opCtx);
+ Status truncate(RecoveryUnit* ru);
SortedDataInterface(OperationContext* opCtx, StringData ident, const IndexDescriptor* desc);
SortedDataInterface(const Ordering& ordering, bool isUnique, StringData ident);
virtual SortedDataBuilderInterface* getBulkBuilder(OperationContext* opCtx,
diff --git a/src/mongo/db/storage/devnull/devnull_kv_engine.h b/src/mongo/db/storage/devnull/devnull_kv_engine.h
index 34d39f79919..f32af0d4235 100644
--- a/src/mongo/db/storage/devnull/devnull_kv_engine.h
+++ b/src/mongo/db/storage/devnull/devnull_kv_engine.h
@@ -74,7 +74,7 @@ public:
virtual std::unique_ptr<SortedDataInterface> getSortedDataInterface(
OperationContext* opCtx, StringData ident, const IndexDescriptor* desc);
- virtual Status dropIdent(OperationContext* opCtx, StringData ident) {
+ virtual Status dropIdent(OperationContext* opCtx, RecoveryUnit* ru, StringData ident) {
return Status::OK();
}
diff --git a/src/mongo/db/storage/durable_catalog_impl.cpp b/src/mongo/db/storage/durable_catalog_impl.cpp
index 38f9db61e58..e43f2013cd2 100644
--- a/src/mongo/db/storage/durable_catalog_impl.cpp
+++ b/src/mongo/db/storage/durable_catalog_impl.cpp
@@ -178,17 +178,22 @@ public:
class DurableCatalogImpl::AddIndexChange : public RecoveryUnit::Change {
public:
- AddIndexChange(OperationContext* opCtx, StorageEngineInterface* engine, StringData ident)
- : _opCtx(opCtx), _engine(engine), _ident(ident.toString()) {}
+ AddIndexChange(OperationContext* opCtx,
+ RecoveryUnit* ru,
+ StorageEngineInterface* engine,
+ StringData ident)
+ : _opCtx(opCtx), _recoveryUnit(ru), _engine(engine), _ident(ident.toString()) {}
virtual void commit(boost::optional<Timestamp>) {}
virtual void rollback() {
// Intentionally ignoring failure.
auto kvEngine = _engine->getEngine();
- MONGO_COMPILER_VARIABLE_UNUSED auto status = kvEngine->dropIdent(_opCtx, _ident);
+ MONGO_COMPILER_VARIABLE_UNUSED auto status =
+ kvEngine->dropIdent(_opCtx, _recoveryUnit, _ident);
}
OperationContext* const _opCtx;
+ RecoveryUnit* const _recoveryUnit;
StorageEngineInterface* _engine;
const std::string _ident;
};
@@ -202,6 +207,7 @@ public:
StringData indexName,
StringData ident)
: _opCtx(opCtx),
+ _recoveryUnit(opCtx->recoveryUnit()),
_engine(engine),
_uuid(uuid),
_indexNss(indexNss),
@@ -219,11 +225,13 @@ public:
_engine->addDropPendingIdent(*commitTimestamp, _indexNss, _ident);
} else {
auto kvEngine = _engine->getEngine();
- MONGO_COMPILER_VARIABLE_UNUSED auto status = kvEngine->dropIdent(_opCtx, _ident);
+ MONGO_COMPILER_VARIABLE_UNUSED auto status =
+ kvEngine->dropIdent(_opCtx, _recoveryUnit, _ident);
}
}
OperationContext* const _opCtx;
+ RecoveryUnit* const _recoveryUnit;
StorageEngineInterface* _engine;
OptionalCollectionUUID _uuid;
const NamespaceString _indexNss;
@@ -809,11 +817,13 @@ StatusWith<std::pair<RecordId, std::unique_ptr<RecordStore>>> DurableCatalogImpl
}
}
+ auto ru = opCtx->recoveryUnit();
CollectionUUID uuid = options.uuid.get();
- opCtx->recoveryUnit()->onRollback([opCtx, catalog = this, nss, ident = entry.ident, uuid]() {
- // Intentionally ignoring failure
- catalog->_engine->getEngine()->dropIdent(opCtx, ident).ignore();
- });
+ opCtx->recoveryUnit()->onRollback(
+ [opCtx, ru, catalog = this, nss, ident = entry.ident, uuid]() {
+ // Intentionally ignoring failure
+ catalog->_engine->getEngine()->dropIdent(opCtx, ru, ident).ignore();
+ });
auto rs =
_engine->getEngine()->getGroupedRecordStore(opCtx, nss.ns(), entry.ident, options, prefix);
@@ -854,9 +864,10 @@ Status DurableCatalogImpl::dropCollection(OperationContext* opCtx, RecordId cata
return status;
}
+ auto ru = opCtx->recoveryUnit();
// This will notify the storageEngine to drop the collection only on WUOW::commit().
opCtx->recoveryUnit()->onCommit(
- [opCtx, catalog = this, entry](boost::optional<Timestamp> commitTimestamp) {
+ [opCtx, ru, catalog = this, entry](boost::optional<Timestamp> commitTimestamp) {
StorageEngineInterface* engine = catalog->_engine;
auto storageEngine = engine->getStorageEngine();
if (storageEngine->supportsPendingDrops() && commitTimestamp) {
@@ -867,7 +878,7 @@ Status DurableCatalogImpl::dropCollection(OperationContext* opCtx, RecordId cata
// Intentionally ignoring failure here. Since we've removed the metadata pointing to
// the collection, we should never see it again anyway.
auto kvEngine = engine->getEngine();
- kvEngine->dropIdent(opCtx, entry.ident).ignore();
+ kvEngine->dropIdent(opCtx, ru, entry.ident).ignore();
}
});
@@ -982,7 +993,7 @@ Status DurableCatalogImpl::prepareForIndexBuild(OperationContext* opCtx,
opCtx, getCollectionOptions(opCtx, catalogId), ident, spec, prefix);
if (status.isOK()) {
opCtx->recoveryUnit()->registerChange(
- std::make_unique<AddIndexChange>(opCtx, _engine, ident));
+ std::make_unique<AddIndexChange>(opCtx, opCtx->recoveryUnit(), _engine, ident));
}
return status;
diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.cpp b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.cpp
index 597bc513d20..070d6cbf244 100644
--- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.cpp
+++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.cpp
@@ -104,7 +104,9 @@ std::unique_ptr<SortedDataInterface> EphemeralForTestEngine::getSortedDataInterf
&_dataMap[ident]);
}
-Status EphemeralForTestEngine::dropIdent(OperationContext* opCtx, StringData ident) {
+Status EphemeralForTestEngine::dropIdent(OperationContext* opCtx,
+ RecoveryUnit* ru,
+ StringData ident) {
stdx::lock_guard<Latch> lk(_mutex);
_dataMap.erase(ident);
return Status::OK();
diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.h b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.h
index 002d8468b80..a18079a860d 100644
--- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.h
+++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.h
@@ -71,7 +71,7 @@ public:
virtual void endBackup(OperationContext* opCtx) {}
- virtual Status dropIdent(OperationContext* opCtx, StringData ident);
+ virtual Status dropIdent(OperationContext* opCtx, RecoveryUnit* ru, StringData ident);
virtual bool supportsDocLocking() const {
return false;
diff --git a/src/mongo/db/storage/kv/kv_drop_pending_ident_reaper.cpp b/src/mongo/db/storage/kv/kv_drop_pending_ident_reaper.cpp
index 44337fffc49..a68cbfe58f1 100644
--- a/src/mongo/db/storage/kv/kv_drop_pending_ident_reaper.cpp
+++ b/src/mongo/db/storage/kv/kv_drop_pending_ident_reaper.cpp
@@ -112,7 +112,7 @@ void KVDropPendingIdentReaper::dropIdentsOlderThan(OperationContext* opCtx, cons
log() << "Completing drop for ident " << ident << " (ns: " << nss
<< ") with drop timestamp " << dropTimestamp;
WriteUnitOfWork wuow(opCtx);
- auto status = _engine->dropIdent(opCtx, ident);
+ auto status = _engine->dropIdent(opCtx, opCtx->recoveryUnit(), ident);
if (!status.isOK()) {
severe() << "Failed to remove drop-pending ident " << ident << "(ns: " << nss
<< ") with drop timestamp " << dropTimestamp << ": " << status;
diff --git a/src/mongo/db/storage/kv/kv_drop_pending_ident_reaper_test.cpp b/src/mongo/db/storage/kv/kv_drop_pending_ident_reaper_test.cpp
index f58c2abb0b4..7f187993d7a 100644
--- a/src/mongo/db/storage/kv/kv_drop_pending_ident_reaper_test.cpp
+++ b/src/mongo/db/storage/kv/kv_drop_pending_ident_reaper_test.cpp
@@ -59,7 +59,7 @@ public:
*/
class KVEngineMock : public KVEngine {
public:
- Status dropIdent(OperationContext* opCtx, StringData ident) override;
+ Status dropIdent(OperationContext* opCtx, RecoveryUnit* ru, StringData ident) override;
// Unused KVEngine functions below.
RecoveryUnit* newRecoveryUnit() override {
@@ -132,12 +132,14 @@ public:
std::vector<std::string> droppedIdents;
// Override to modify dropIdent() behavior.
- using DropIdentFn = std::function<Status(OperationContext*, StringData)>;
- DropIdentFn dropIdentFn = [](OperationContext*, StringData) { return Status::OK(); };
+ using DropIdentFn = std::function<Status(OperationContext*, RecoveryUnit*, StringData)>;
+ DropIdentFn dropIdentFn = [](OperationContext*, RecoveryUnit*, StringData) {
+ return Status::OK();
+ };
};
-Status KVEngineMock::dropIdent(OperationContext* opCtx, StringData ident) {
- auto status = dropIdentFn(opCtx, ident);
+Status KVEngineMock::dropIdent(OperationContext* opCtx, RecoveryUnit* ru, StringData ident) {
+ auto status = dropIdentFn(opCtx, ru, ident);
if (status.isOK()) {
droppedIdents.push_back(ident.toString());
}
@@ -320,11 +322,13 @@ DEATH_TEST_F(KVDropPendingIdentReaperTest,
ASSERT_EQUALS(dropTimestamp, *reaper.getEarliestDropTimestamp());
// Make KVEngineMock::dropIndent() fail.
- engine->dropIdentFn = [ident](OperationContext* opCtx, StringData identToDrop) {
- ASSERT(opCtx);
- ASSERT_EQUALS(ident, identToDrop);
- return Status(ErrorCodes::OperationFailed, "Mock KV engine dropIndent() failed.");
- };
+ engine->dropIdentFn =
+ [ident](OperationContext* opCtx, RecoveryUnit* ru, StringData identToDrop) {
+ ASSERT(opCtx);
+ ASSERT(ru);
+ ASSERT_EQUALS(ident, identToDrop);
+ return Status(ErrorCodes::OperationFailed, "Mock KV engine dropIndent() failed.");
+ };
auto opCtx = makeOpCtx();
reaper.dropIdentsOlderThan(opCtx.get(), makeTimestampWithNextInc(dropTimestamp));
diff --git a/src/mongo/db/storage/kv/kv_engine.h b/src/mongo/db/storage/kv/kv_engine.h
index 5b80e7a857d..fa7a095a6ac 100644
--- a/src/mongo/db/storage/kv/kv_engine.h
+++ b/src/mongo/db/storage/kv/kv_engine.h
@@ -182,7 +182,15 @@ public:
*/
virtual Status repairIdent(OperationContext* opCtx, StringData ident) = 0;
- virtual Status dropIdent(OperationContext* opCtx, StringData ident) = 0;
+ /**
+ * Takes both an OperationContext and a RecoveryUnit, since most storage engines except for
+ * mobile only need the RecoveryUnit. Obtaining the RecoveryUnit from the OperationContext is
+ * not necessarily possible, since as of SERVER-44139 dropIdent can be called as part of
+ * multi-document transactions, which use the same RecoveryUnit throughout but not the same
+ * OperationContext.
+ * TODO(SERVER-45371) Remove OperationContext argument.
+ */
+ virtual Status dropIdent(OperationContext* opCtx, RecoveryUnit* ru, StringData ident) = 0;
/**
* Attempts to locate and recover a file that is "orphaned" from the storage engine's metadata,
diff --git a/src/mongo/db/storage/kv/kv_engine_test_harness.cpp b/src/mongo/db/storage/kv/kv_engine_test_harness.cpp
index e9c07d7fdbd..0bce1df682d 100644
--- a/src/mongo/db/storage/kv/kv_engine_test_harness.cpp
+++ b/src/mongo/db/storage/kv/kv_engine_test_harness.cpp
@@ -256,7 +256,7 @@ TEST(KVEngineTestHarness, TemporaryRecordStoreSimple) {
ASSERT_EQUALS(ident, all[0]);
WriteUnitOfWork wuow(&opCtx);
- ASSERT_OK(engine->dropIdent(&opCtx, ident));
+ ASSERT_OK(engine->dropIdent(&opCtx, opCtx.recoveryUnit(), ident));
wuow.commit();
}
}
diff --git a/src/mongo/db/storage/kv/storage_engine_test.cpp b/src/mongo/db/storage/kv/storage_engine_test.cpp
index 5fb349a9a6b..1926a0f64ad 100644
--- a/src/mongo/db/storage/kv/storage_engine_test.cpp
+++ b/src/mongo/db/storage/kv/storage_engine_test.cpp
@@ -93,7 +93,7 @@ TEST_F(StorageEngineTest, ReconcileIdentsTest) {
ASSERT_EQUALS("_id", toRebuild.indexName);
// Now drop the `db.coll1` table, while leaving the DurableCatalog entry.
- ASSERT_OK(dropIdent(opCtx.get(), swCollInfo.getValue().ident));
+ ASSERT_OK(dropIdent(opCtx.get(), opCtx.get()->recoveryUnit(), swCollInfo.getValue().ident));
ASSERT_EQUALS(static_cast<const unsigned long>(1), getAllKVEngineIdents(opCtx.get()).size());
// Reconciling this should result in an error.
@@ -109,7 +109,7 @@ TEST_F(StorageEngineTest, LoadCatalogDropsOrphansAfterUncleanShutdown) {
auto swCollInfo = createCollection(opCtx.get(), collNs);
ASSERT_OK(swCollInfo.getStatus());
- ASSERT_OK(dropIdent(opCtx.get(), swCollInfo.getValue().ident));
+ ASSERT_OK(dropIdent(opCtx.get(), opCtx.get()->recoveryUnit(), swCollInfo.getValue().ident));
ASSERT(collectionExists(opCtx.get(), collNs));
// After the catalog is reloaded, we expect that the collection has been dropped because the
@@ -292,7 +292,7 @@ TEST_F(StorageEngineRepairTest, LoadCatalogRecoversOrphans) {
auto swCollInfo = createCollection(opCtx.get(), collNs);
ASSERT_OK(swCollInfo.getStatus());
- ASSERT_OK(dropIdent(opCtx.get(), swCollInfo.getValue().ident));
+ ASSERT_OK(dropIdent(opCtx.get(), opCtx.get()->recoveryUnit(), swCollInfo.getValue().ident));
ASSERT(collectionExists(opCtx.get(), collNs));
// After the catalog is reloaded, we expect that the ident has been recovered because the
@@ -316,7 +316,7 @@ TEST_F(StorageEngineRepairTest, ReconcileSucceeds) {
auto swCollInfo = createCollection(opCtx.get(), collNs);
ASSERT_OK(swCollInfo.getStatus());
- ASSERT_OK(dropIdent(opCtx.get(), swCollInfo.getValue().ident));
+ ASSERT_OK(dropIdent(opCtx.get(), opCtx.get()->recoveryUnit(), swCollInfo.getValue().ident));
ASSERT(collectionExists(opCtx.get(), collNs));
// Reconcile would normally return an error if a collection existed with a missing ident in the
diff --git a/src/mongo/db/storage/kv/temporary_kv_record_store.cpp b/src/mongo/db/storage/kv/temporary_kv_record_store.cpp
index 7625fe8630d..ee71e5d7091 100644
--- a/src/mongo/db/storage/kv/temporary_kv_record_store.cpp
+++ b/src/mongo/db/storage/kv/temporary_kv_record_store.cpp
@@ -49,7 +49,7 @@ void TemporaryKVRecordStore::deleteTemporaryTable(OperationContext* opCtx) {
// destructed while we're using it.
invariant(opCtx->lockState()->isReadLocked());
- auto status = _kvEngine->dropIdent(opCtx, _rs->getIdent());
+ auto status = _kvEngine->dropIdent(opCtx, opCtx->recoveryUnit(), _rs->getIdent());
fassert(
51032,
status.withContext(str::stream() << "failed to drop temporary ident: " << _rs->getIdent()));
diff --git a/src/mongo/db/storage/mobile/mobile_kv_engine.cpp b/src/mongo/db/storage/mobile/mobile_kv_engine.cpp
index 648ac3612ae..495dce80070 100644
--- a/src/mongo/db/storage/mobile/mobile_kv_engine.cpp
+++ b/src/mongo/db/storage/mobile/mobile_kv_engine.cpp
@@ -244,8 +244,9 @@ std::unique_ptr<SortedDataInterface> MobileKVEngine::getSortedDataInterface(
return std::make_unique<MobileIndexStandard>(opCtx, desc, ident.toString());
}
-Status MobileKVEngine::dropIdent(OperationContext* opCtx, StringData ident) {
- MobileSession* session = MobileRecoveryUnit::get(opCtx)->getSessionNoTxn(opCtx);
+Status MobileKVEngine::dropIdent(OperationContext* opCtx, RecoveryUnit* ru, StringData ident) {
+ auto mRu = checked_cast<MobileRecoveryUnit*>(ru);
+ MobileSession* session = mRu->getSessionNoTxn(opCtx);
std::string dropQuery = "DROP TABLE IF EXISTS \"" + ident + "\";";
try {
@@ -256,7 +257,7 @@ Status MobileKVEngine::dropIdent(OperationContext* opCtx, StringData ident) {
LOG(MOBILE_LOG_LEVEL_LOW)
<< "MobileSE: Caught WriteConflictException while dropping table, "
"queuing to retry later";
- MobileRecoveryUnit::get(opCtx)->enqueueFailedDrop(dropQuery);
+ mRu->enqueueFailedDrop(dropQuery);
}
return Status::OK();
}
diff --git a/src/mongo/db/storage/mobile/mobile_kv_engine.h b/src/mongo/db/storage/mobile/mobile_kv_engine.h
index 0e0b3ab17e3..662f2898b24 100644
--- a/src/mongo/db/storage/mobile/mobile_kv_engine.h
+++ b/src/mongo/db/storage/mobile/mobile_kv_engine.h
@@ -78,7 +78,7 @@ public:
void endBackup(OperationContext* opCtx) override {}
- Status dropIdent(OperationContext* opCtx, StringData ident) override;
+ Status dropIdent(OperationContext* opCtx, RecoveryUnit* ru, StringData ident) override;
bool supportsDocLocking() const override {
return false;
diff --git a/src/mongo/db/storage/storage_engine_impl.cpp b/src/mongo/db/storage/storage_engine_impl.cpp
index ff055222963..1cb0d8f7c9e 100644
--- a/src/mongo/db/storage/storage_engine_impl.cpp
+++ b/src/mongo/db/storage/storage_engine_impl.cpp
@@ -383,7 +383,7 @@ StatusWith<StorageEngine::ReconcileResult> StorageEngineImpl::reconcileCatalogAn
const auto& toRemove = it;
log() << "Dropping unknown ident: " << toRemove;
WriteUnitOfWork wuow(opCtx);
- fassert(40591, _engine->dropIdent(opCtx, toRemove));
+ fassert(40591, _engine->dropIdent(opCtx, opCtx->recoveryUnit(), toRemove));
wuow.commit();
}
@@ -479,7 +479,7 @@ StatusWith<StorageEngine::ReconcileResult> StorageEngineImpl::reconcileCatalogAn
log() << "Dropping an unfinished index because --noIndexBuildRetry is set. "
"Collection: "
<< coll << " Index: " << indexName;
- fassert(51197, _engine->dropIdent(opCtx, indexIdent));
+ fassert(51197, _engine->dropIdent(opCtx, opCtx->recoveryUnit(), indexIdent));
indexesToDrop.push_back(indexName);
continue;
}
@@ -501,7 +501,7 @@ StatusWith<StorageEngine::ReconcileResult> StorageEngineImpl::reconcileCatalogAn
log() << "Dropping unfinished index. Collection: " << coll
<< " Index: " << indexName;
// Ensure the `ident` is dropped while we have the `indexIdent` value.
- fassert(50713, _engine->dropIdent(opCtx, indexIdent));
+ fassert(50713, _engine->dropIdent(opCtx, opCtx->recoveryUnit(), indexIdent));
indexesToDrop.push_back(indexName);
continue;
}
@@ -522,7 +522,7 @@ StatusWith<StorageEngine::ReconcileResult> StorageEngineImpl::reconcileCatalogAn
for (auto&& temp : internalIdentsToDrop) {
log() << "Dropping internal ident: " << temp;
WriteUnitOfWork wuow(opCtx);
- fassert(51067, _engine->dropIdent(opCtx, temp));
+ fassert(51067, _engine->dropIdent(opCtx, opCtx->recoveryUnit(), temp));
wuow.commit();
}
diff --git a/src/mongo/db/storage/storage_engine_test_fixture.h b/src/mongo/db/storage/storage_engine_test_fixture.h
index 3495fd893e8..35254e71eb9 100644
--- a/src/mongo/db/storage/storage_engine_test_fixture.h
+++ b/src/mongo/db/storage/storage_engine_test_fixture.h
@@ -82,11 +82,11 @@ public:
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss)->getCatalogId();
std::string indexIdent =
_storageEngine->getCatalog()->getIndexIdent(opCtx, catalogId, indexName);
- return dropIdent(opCtx, indexIdent);
+ return dropIdent(opCtx, opCtx->recoveryUnit(), indexIdent);
}
- Status dropIdent(OperationContext* opCtx, StringData ident) {
- return _storageEngine->getEngine()->dropIdent(opCtx, ident);
+ Status dropIdent(OperationContext* opCtx, RecoveryUnit* ru, StringData ident) {
+ return _storageEngine->getEngine()->dropIdent(opCtx, ru, ident);
}
StatusWith<StorageEngine::ReconcileResult> reconcile(OperationContext* opCtx) {
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
index dd63aad920a..2d0cf8c6a16 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
@@ -1481,11 +1481,11 @@ std::unique_ptr<RecordStore> WiredTigerKVEngine::makeTemporaryRecordStore(Operat
return std::move(rs);
}
-Status WiredTigerKVEngine::dropIdent(OperationContext* opCtx, StringData ident) {
+Status WiredTigerKVEngine::dropIdent(OperationContext* opCtx, RecoveryUnit* ru, StringData ident) {
string uri = _uri(ident);
- WiredTigerRecoveryUnit* ru = WiredTigerRecoveryUnit::get(opCtx);
- ru->getSessionNoTxn()->closeAllCursors(uri);
+ WiredTigerRecoveryUnit* wtRu = checked_cast<WiredTigerRecoveryUnit*>(ru);
+ wtRu->getSessionNoTxn()->closeAllCursors(uri);
_sessionCache->closeAllCursors(uri);
WiredTigerSession session(_conn);
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
index ca4c51c1ccd..98ca038789a 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
@@ -165,7 +165,7 @@ public:
const IndexDescriptor* desc,
KVPrefix prefix) override;
- Status dropIdent(OperationContext* opCtx, StringData ident) override;
+ Status dropIdent(OperationContext* opCtx, RecoveryUnit* ru, StringData ident) override;
Status okToRename(OperationContext* opCtx,
StringData fromNS,
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp
index 76ab1239046..2f818dce98a 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp
@@ -166,7 +166,7 @@ TEST_F(WiredTigerKVEngineRepairTest, OrphanedDataFilesCanBeRecovered) {
boost::filesystem::rename(*dataFilePath, tmpFile, err);
ASSERT(!err) << err.message();
- ASSERT_OK(_engine->dropIdent(opCtxPtr.get(), ident));
+ ASSERT_OK(_engine->dropIdent(opCtxPtr.get(), opCtxPtr.get()->recoveryUnit(), ident));
// The data file is moved back in place so that it becomes an "orphan" of the storage
// engine and the restoration process can be tested.
@@ -209,7 +209,7 @@ TEST_F(WiredTigerKVEngineRepairTest, UnrecoverableOrphanedDataFilesAreRebuilt) {
ASSERT(boost::filesystem::exists(*dataFilePath));
- ASSERT_OK(_engine->dropIdent(opCtxPtr.get(), ident));
+ ASSERT_OK(_engine->dropIdent(opCtxPtr.get(), opCtxPtr.get()->recoveryUnit(), ident));
#ifdef _WIN32
auto status =
diff --git a/src/mongo/dbtests/catalogtests.cpp b/src/mongo/dbtests/catalogtests.cpp
index 56db54cc9f8..288ab67f19c 100644
--- a/src/mongo/dbtests/catalogtests.cpp
+++ b/src/mongo/dbtests/catalogtests.cpp
@@ -59,10 +59,6 @@ public:
return;
}
- // TODO SERVER-44138: The commented out lines can be reinstated when committing new
- // collections to the catalog are transactional (all succeed or fail).
-
- // NamespaceString op1UniqueNss("test.uniqueCollection");
NamespaceString competingNss("test.competingCollection");
auto client1 = serviceContext->makeClient("client1");
@@ -74,7 +70,6 @@ public:
Lock::DBLock dbLk1(op1.get(), competingNss.db(), LockMode::MODE_IX);
Lock::CollectionLock collLk1(op1.get(), competingNss, LockMode::MODE_IX);
- // Lock::CollectionLock uniqueNssLk(op1.get(), op1UniqueNss, LockMode::MODE_IX);
Lock::DBLock dbLk2(op2.get(), competingNss.db(), LockMode::MODE_IX);
Lock::CollectionLock collLk2(op2.get(), competingNss, LockMode::MODE_IX);
@@ -83,7 +78,6 @@ public:
{
WriteUnitOfWork wuow1(op1.get());
- // ASSERT_TRUE(db->createCollection(op1.get(), op1UniqueNss) != nullptr);
ASSERT_TRUE(db->createCollection(op1.get(), competingNss) != nullptr);
ASSERT_TRUE(collectionExists(op1.get(), competingNss));
ASSERT_FALSE(collectionExists(op2.get(), competingNss));
@@ -103,8 +97,6 @@ public:
ASSERT_TRUE(collectionExists(op1.get(), competingNss));
ASSERT_TRUE(collectionExists(op2.get(), competingNss));
- // ASSERT_FALSE(collectionExists(op1.get(), op1UniqueNss));
- // ASSERT_FALSE(collectionExists(op2.get(), op1UniqueNss));
}
};