summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Mir <ali.mir@mongodb.com>2020-04-09 11:12:27 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-05-05 16:04:11 +0000
commit73a812bd10647977e7b2ad6f1614ab0cfbe2b007 (patch)
tree027300a7b3b766d34bb5f16030955a62797f6f81
parentd5377a49090be1cf17e78fe888b78b8634c537e9 (diff)
downloadmongo-73a812bd10647977e7b2ad6f1614ab0cfbe2b007.tar.gz
SERVER-32225 Only limit number of text indexes created by user connections
(cherry picked from commit 7ce7dc274c7c899855f14ac55b5344b32399598c)
-rw-r--r--src/mongo/db/catalog/index_catalog_impl.cpp8
-rw-r--r--src/mongo/db/repl/oplog_applier_impl_test.cpp20
2 files changed, 25 insertions, 3 deletions
diff --git a/src/mongo/db/catalog/index_catalog_impl.cpp b/src/mongo/db/catalog/index_catalog_impl.cpp
index d2cdcc85686..d38b3f010d8 100644
--- a/src/mongo/db/catalog/index_catalog_impl.cpp
+++ b/src/mongo/db/catalog/index_catalog_impl.cpp
@@ -866,10 +866,12 @@ Status IndexCatalogImpl::_doesSpecConflictWithExisting(OperationContext* opCtx,
return Status(ErrorCodes::CannotCreateIndex, s);
}
- // Refuse to build text index if another text index exists or is in progress.
- // Collections should only have one text index.
+ // Refuse to build text index for user connections if another text index exists or is in
+ // progress. This constraint is not based on technical limitations of the storage or execution
+ // layers, and thus we allow internal connections to temporarily build multiple text indexes for
+ // idempotency reasons.
string pluginName = IndexNames::findPluginName(key);
- if (pluginName == IndexNames::TEXT) {
+ if (pluginName == IndexNames::TEXT && opCtx->getClient()->isFromUserConnection()) {
vector<const IndexDescriptor*> textIndexes;
findIndexByType(opCtx, IndexNames::TEXT, textIndexes, includeUnfinishedIndexes);
if (textIndexes.size() > 0) {
diff --git a/src/mongo/db/repl/oplog_applier_impl_test.cpp b/src/mongo/db/repl/oplog_applier_impl_test.cpp
index 925b1ed9394..d8687bdb148 100644
--- a/src/mongo/db/repl/oplog_applier_impl_test.cpp
+++ b/src/mongo/db/repl/oplog_applier_impl_test.cpp
@@ -2960,6 +2960,26 @@ TEST_F(IdempotencyTest, ConvertToCappedNamespaceNotFound) {
ASSERT_FALSE(autoColl.getDb());
}
+TEST_F(IdempotencyTest, IgnoreMultipleTextIndexErrorFromSystemConnection) {
+ ASSERT_OK(
+ ReplicationCoordinator::get(_opCtx.get())->setFollowerMode(MemberState::RS_RECOVERING));
+ ASSERT_OK(runOpInitialSync(createCollection(kUuid)));
+ ASSERT_OK(runOpInitialSync(insert(fromjson("{_id: 1, a: '1', b: '2'}"))));
+ // Building multiple non-compound indexes on different field results in an IndexOptionsConflict
+ // error code, which is already explicitly ignored during oplog application. In order to test
+ // ignoring the correct multiple text index error, we use compound indexes.
+ auto addA = buildIndex(fromjson("{a: 'text', b: 1}"), BSONObj(), kUuid);
+ ASSERT_OK(runOpInitialSync(addA));
+ // Building a second text index should succeed as only users are limited to one
+ // text index per collection. Trying to build indexA a second time should fail, but the error
+ // will be ignored.
+ auto indexB = buildIndex(fromjson("{b: 'text', c: 1}"), BSONObj(), kUuid);
+ auto dropB = dropIndex("b_index", kUuid);
+ auto ops = {indexB, dropB, addA};
+ testOpsAreIdempotent(ops);
+ ASSERT_OK(runOpsInitialSync(ops));
+}
+
class IdempotencyTestTxns : public IdempotencyTest {};
// Document used by transaction idempotency tests.