diff options
author | Yuhong Zhang <yuhong.zhang@mongodb.com> | 2022-04-01 13:43:55 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-04-19 22:54:55 +0000 |
commit | 221a44efc37f2f88812275b153e6c8b823310880 (patch) | |
tree | c2be61c7ba5662b277cee7dcaf05f499270d9b06 | |
parent | 250e543f214ee5c327a5b569f04f9f76278a3f82 (diff) | |
download | mongo-221a44efc37f2f88812275b153e6c8b823310880.tar.gz |
SERVER-65024 Fix the uniqueness constraint handling for foreground index builds
(cherry picked from commit 5985d757ddc2645fb1b5df88f78abf6b9a833452)
-rw-r--r-- | jstests/noPassthroughWithMongod/reindex_duplicate_keys.js | 46 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_catalog.h | 2 | ||||
-rw-r--r-- | src/mongo/db/catalog/multi_index_block.cpp | 7 | ||||
-rw-r--r-- | src/mongo/db/catalog/multi_index_block.h | 9 |
4 files changed, 55 insertions, 9 deletions
diff --git a/jstests/noPassthroughWithMongod/reindex_duplicate_keys.js b/jstests/noPassthroughWithMongod/reindex_duplicate_keys.js new file mode 100644 index 00000000000..aa4a363a72a --- /dev/null +++ b/jstests/noPassthroughWithMongod/reindex_duplicate_keys.js @@ -0,0 +1,46 @@ +/** + * Tests that reIndex command fails with duplicate key error when there are duplicates in the + * collection. + */ + +(function() { +"use strict"; + +const collNamePrefix = "reindex_duplicate_keys_"; +let count = 0; + +// Bypasses DuplicateKey insertion error for testing via failpoint. +let addDuplicateDocumentsToCol = function(db, coll, doc) { + jsTestLog("Inserts documents without index entries."); + assert.commandWorked( + db.adminCommand({configureFailPoint: "skipIndexNewRecords", mode: "alwaysOn"})); + + assert.commandWorked(coll.insert(doc)); + assert.commandWorked(coll.insert(doc)); + + assert.commandWorked(db.adminCommand({configureFailPoint: "skipIndexNewRecords", mode: "off"})); +}; + +let runTest = function(doc) { + const collName = collNamePrefix + count++; + const coll = db.getCollection(collName); + coll.drop(); + + // Makes sure to create the _id index. + assert.commandWorked(db.createCollection(collName)); + if (doc) { + assert.commandWorked(coll.createIndex(doc, {unique: true})); + } else { + doc = {_id: 1}; + } + + // Inserts two violating documents without indexing them. + addDuplicateDocumentsToCol(db, coll, doc); + + // Checks reIndex command fails with duplicate key error. + assert.commandFailedWithCode(coll.reIndex(), ErrorCodes.DuplicateKey); +}; + +runTest(); +runTest({a: 1}); +})();
\ No newline at end of file diff --git a/src/mongo/db/catalog/index_catalog.h b/src/mongo/db/catalog/index_catalog.h index c07d386fec9..9f5b431d990 100644 --- a/src/mongo/db/catalog/index_catalog.h +++ b/src/mongo/db/catalog/index_catalog.h @@ -67,7 +67,7 @@ enum class IndexBuildMethod { */ kHybrid, /** - * Perform a collection scan to dump all keys into the exteral sorter, then into the index. + * Perform a collection scan to dump all keys into the external sorter, then into the index. * During this process, callers guarantee that no writes will be accepted on this collection. */ kForeground, diff --git a/src/mongo/db/catalog/multi_index_block.cpp b/src/mongo/db/catalog/multi_index_block.cpp index 8cbfbe535d0..e389a181478 100644 --- a/src/mongo/db/catalog/multi_index_block.cpp +++ b/src/mongo/db/catalog/multi_index_block.cpp @@ -304,9 +304,12 @@ StatusWith<std::vector<BSONObj>> MultiIndexBlock::init( collection->getIndexCatalog()->prepareInsertDeleteOptions( opCtx, collection->ns(), descriptor, &index.options); - // Index builds always relax constraints and check for violations at commit-time. + // Foreground index builds have to check for duplicates. Other index builds can relax + // constraints and check for violations at commit-time. index.options.getKeysMode = IndexAccessMethod::GetKeysMode::kRelaxConstraints; - index.options.dupsAllowed = true; + index.options.dupsAllowed = _method == IndexBuildMethod::kForeground + ? !descriptor->unique() || _ignoreUnique + : true; index.options.fromIndexBuilder = true; LOGV2(20384, diff --git a/src/mongo/db/catalog/multi_index_block.h b/src/mongo/db/catalog/multi_index_block.h index 211cc52373d..471c8ae861f 100644 --- a/src/mongo/db/catalog/multi_index_block.h +++ b/src/mongo/db/catalog/multi_index_block.h @@ -82,12 +82,9 @@ public: ~MultiIndexBlock(); /** - * By default we enforce the 'unique' flag in specs when building an index by failing. - * If this is called before init(), we will ignore unique violations. This has no effect if - * no specs are unique. - * - * If this is called, any 'dupRecords' set passed to dumpInsertsFromBulk() will never be - * filled. + * When this is called: + * For hybrid index builds, the index interceptor will not track duplicates. + * For foreground index builds, the uniqueness constraint will be relaxed. */ void ignoreUniqueConstraint(); |