diff options
author | Benety Goh <benety@mongodb.com> | 2021-05-19 12:34:02 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-08-10 16:26:58 +0000 |
commit | b8ec200c830d8a79217195af175b023f40a60943 (patch) | |
tree | 315f55a6b634d7e0dbf66230ba83660108db14a6 | |
parent | 59183f9335c9deede96f016951e8ef0fb3aa6052 (diff) | |
download | mongo-b8ec200c830d8a79217195af175b023f40a60943.tar.gz |
SERVER-56877 add js test for validating multikey compound index after restarting
This test checks that the multikey paths for a compound index remain consistent
despite some failed writes. The test uses a compound index with two indexed fields
that are updated separately by different write operations. A hashed index provides
an easy way to fail a write operation due to a constraint on field values in a hashed
index.
This initial version of the test characterizes a defect in multikey tracking that shows
up as validation errors after the server restarts.
(cherry picked from commit 54f015ab1bc386b61c8011d5d8e3267bb4e181bf)
-rw-r--r-- | jstests/noPassthrough/validate_multikey_compound.js | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/jstests/noPassthrough/validate_multikey_compound.js b/jstests/noPassthrough/validate_multikey_compound.js new file mode 100644 index 00000000000..e354b9af3de --- /dev/null +++ b/jstests/noPassthrough/validate_multikey_compound.js @@ -0,0 +1,79 @@ +/** + * Validates multikey compound index in a collection that also contains a hashed index. + * The scenario tested here involves restarting the node after a failed insert due + * to contraints imposed by the hashed index. The validation behavior observed after + * restarting is that, even though we inserted documents that contain arrays in every + * indexed field in the compound index, we fail to save all the multikey path information + * in the catalog. + * @tags: [ + * requires_replication, + * requires_persistence, + * ] + */ +(function() { +'use strict'; + +const rst = new ReplSetTest({nodes: 1}); +rst.startSet(); +rst.initiate(); + +let primary = rst.getPrimary(); +let testColl = primary.getCollection('test.validate_multikey_compound'); + +assert.commandWorked(testColl.getDB().createCollection(testColl.getName())); + +assert.commandWorked(testColl.createIndex({a: 1, b: 1})); +assert.commandWorked(testColl.createIndex({c: 'hashed'})); + +// Insert 3 documents. Only the first and last documents are valid. +assert.commandWorked(testColl.insert({_id: 0, a: [1, 2, 3], b: 'abc', c: 'valid_hash_0'})); + +// 16766 is the error code returned by ExpressionKeysPrivate::getHashKeys() for +// "hashed indexes do not currently support array values". +assert.commandFailedWithCode( + testColl.insert({_id: 1, a: 456, b: ['d', 'e', 'f'], c: ['invalid', 'hash']}), 16766); + +assert.commandWorked(testColl.insert({_id: 2, a: 789, b: ['g', 'h', ' i'], c: 'valid_hash_2'})); + +jsTestLog('Checking documents in collection before restart'); +let docs = testColl.find().sort({_id: 1}).toArray(); +assert.eq(2, docs.length, 'too many docs in collection: ' + tojson(docs)); +assert.eq(0, docs[0]._id, 'unexpected document content in collection: ' + tojson(docs)); +assert.eq(2, docs[1]._id, 'unexpected document content in collection: ' + tojson(docs)); + +// For the purpose of reproducing the validation error in a_1, it is important to skip validation +// when restarting the primary node. Enabling validation here has an effect on the validate +// command's behavior after restarting. +primary = rst.restart(primary, {skipValidation: true}, /*signal=*/undefined, /*wait=*/true); +testColl = primary.getCollection(testColl.getFullName()); + +jsTestLog('Checking documents in collection after restart'); +rst.awaitReplication(); +docs = testColl.find().sort({_id: 1}).toArray(); +assert.eq(2, docs.length, 'too many docs in collection: ' + tojson(docs)); +assert.eq(0, docs[0]._id, 'unexpected document content in collection: ' + tojson(docs)); +assert.eq(2, docs[1]._id, 'unexpected document content in collection: ' + tojson(docs)); + +jsTestLog('Validating collection after restart'); +const result = assert.commandWorked(testColl.validate({full: true})); + +jsTestLog('Validation result: ' + tojson(result)); +assert.eq(testColl.getFullName(), result.ns, tojson(result)); +assert.eq(0, result.nInvalidDocuments, tojson(result)); +assert.eq(2, result.nrecords, tojson(result)); +assert.eq(3, result.nIndexes, tojson(result)); + +// Check non-multikey indexes. +assert.eq(2, result.keysPerIndex._id_, tojson(result)); +assert.eq(2, result.keysPerIndex.c_hashed, tojson(result)); +assert(result.indexDetails._id_.valid, tojson(result)); +assert(result.indexDetails.c_hashed.valid, tojson(result)); + +// Check multikey index. +assert.eq(6, result.keysPerIndex.a_1_b_1, tojson(result)); +assert(!result.indexDetails.a_1_b_1.valid, tojson(result)); + +assert(!result.valid, tojson(result)); + +rst.stopSet(/*signal=*/undefined, /*forRestart=*/undefined, {skipValidation: true}); +})(); |