summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/replsets/drop_collections_two_phase.js15
-rw-r--r--src/mongo/db/catalog/database_impl.cpp23
-rw-r--r--src/mongo/db/catalog/index_catalog_impl.cpp17
3 files changed, 40 insertions, 15 deletions
diff --git a/jstests/replsets/drop_collections_two_phase.js b/jstests/replsets/drop_collections_two_phase.js
index fb35984704d..18d63f12a24 100644
--- a/jstests/replsets/drop_collections_two_phase.js
+++ b/jstests/replsets/drop_collections_two_phase.js
@@ -60,6 +60,21 @@
primaryDB.createCollection(collToDrop);
replTest.awaitReplication();
+ // Two phase collection should handle long index names gracefully.
+ // MMAP imposes a hard limit on index namespaces so we have to drop indexes that are too long
+ // to store on disk after renaming the collection. See SERVER-29747.
+ // Other storage engines should allow the implicit index renames to proceed because these
+ // renamed indexes are internal and will not be visible to users (no risk of being exported to
+ // another storage engine).
+ // TODO: remove storage engine check when SERVER-29474 is completed.
+ var storageEngine = jsTest.options().storageEngine;
+ if (storageEngine !== 'mmapv1') {
+ var coll = primaryDB.getCollection(collToDrop);
+ var maxNsLength = 127;
+ var indexName = ''.pad(maxNsLength - (coll.getFullName() + '.$').length, true, 'a');
+ assert.commandWorked(coll.ensureIndex({a: 1}, {name: indexName}));
+ }
+
// Pause application on secondary so that commit point doesn't advance, meaning that a dropped
// collection on the primary will remain in 'drop-pending' state.
jsTestLog("Pausing oplog application on the secondary node.");
diff --git a/src/mongo/db/catalog/database_impl.cpp b/src/mongo/db/catalog/database_impl.cpp
index e96bd7325d6..1141dab3c72 100644
--- a/src/mongo/db/catalog/database_impl.cpp
+++ b/src/mongo/db/catalog/database_impl.cpp
@@ -511,16 +511,21 @@ Status DatabaseImpl::dropCollectionEvenIfSystem(OperationContext* opCtx,
}
}
- // Check if drop-pending namespace is too long for the index names in the collection.
auto dpns = fullns.makeDropPendingNamespace(dropOpTime);
- auto status =
- dpns.checkLengthForRename(collection->getIndexCatalog()->getLongestIndexNameLength(opCtx));
- if (!status.isOK()) {
- log() << "dropCollection: " << fullns
- << " - cannot proceed with collection rename for pending-drop: " << status
- << ". Dropping collection immediately.";
- fassertStatusOK(40463, _finishDropCollection(opCtx, fullns, collection));
- return Status::OK();
+
+ // MMAPv1 requires that index namespaces are subject to the same length constraints as indexes
+ // in collections that are not in a drop-pending state. Therefore, we check if the drop-pending
+ // namespace is too long for the index names in the collection.
+ if (opCtx->getServiceContext()->getGlobalStorageEngine()->isMmapV1()) {
+ auto status = dpns.checkLengthForRename(
+ collection->getIndexCatalog()->getLongestIndexNameLength(opCtx));
+ if (!status.isOK()) {
+ log() << "dropCollection: " << fullns
+ << " - cannot proceed with collection rename for pending-drop: " << status
+ << ". Dropping collection immediately.";
+ fassertStatusOK(40463, _finishDropCollection(opCtx, fullns, collection));
+ return Status::OK();
+ }
}
// Rename collection using drop-pending namespace generated from drop optime.
diff --git a/src/mongo/db/catalog/index_catalog_impl.cpp b/src/mongo/db/catalog/index_catalog_impl.cpp
index e9cfd3a4f0c..40f2ecb1c0d 100644
--- a/src/mongo/db/catalog/index_catalog_impl.cpp
+++ b/src/mongo/db/catalog/index_catalog_impl.cpp
@@ -590,12 +590,17 @@ Status IndexCatalogImpl::_isSpecOk(OperationContext* opCtx, const BSONObj& spec)
if (name.empty())
return Status(ErrorCodes::CannotCreateIndex, "index name cannot be empty");
- const std::string indexNamespace = IndexDescriptor::makeIndexNamespace(nss.ns(), name);
- if (indexNamespace.length() > NamespaceString::MaxNsLen)
- return Status(ErrorCodes::CannotCreateIndex,
- str::stream() << "namespace name generated from index name \""
- << indexNamespace
- << "\" is too long (127 byte max)");
+ // Drop pending collections are internal to the server and will not be exported to another
+ // storage engine. The indexes contained in these collections are not subject to the same
+ // namespace length constraints as the ones in created by users.
+ if (!nss.isDropPendingNamespace()) {
+ auto indexNamespace = IndexDescriptor::makeIndexNamespace(nss.ns(), name);
+ if (indexNamespace.length() > NamespaceString::MaxNsLen)
+ return Status(ErrorCodes::CannotCreateIndex,
+ str::stream() << "namespace name generated from index name \""
+ << indexNamespace
+ << "\" is too long (127 byte max)");
+ }
const BSONObj key = spec.getObjectField("key");
const Status keyStatus = index_key_validate::validateKeyPattern(key, indexVersion);