0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

SERVER-56877 add js test for validating multikey index after restarting

This test checks that the multikey state of an index is updated correctly in the durable
catalog despite some earlier writes failing due to a hashed index constraint. Upon restarting,
we perform a full validation to ensure that the multikey information in the catalog is
consistent with the contents of the collection.

This initial version of the test characterizes an defect in tracking the multikey information
that leads to validation errors after the server restarts.
This commit is contained in:
Benety Goh 2021-05-18 21:14:38 -04:00 committed by Evergreen Agent
parent 64e63f9f0a
commit aefb1ac444

View File

@ -0,0 +1,71 @@
/**
* Validates multikey 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 another document with an array in the
* indexed field for the non-hashed index, we fail to save the index state as multikey.
* @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_restart');
assert.commandWorked(testColl.getDB().createCollection(testColl.getName()));
assert.commandWorked(testColl.createIndex({a: 1}));
assert.commandWorked(testColl.createIndex({b: 'hashed'}));
// 16766 is the error code returned by ExpressionKeysPrivate::getHashKeys() for
// "hashed indexes do not currently support array values".
assert.commandFailedWithCode(testColl.insert({_id: 0, a: [1, 2, 3], b: ['a', 'b', 'c']}), 16766);
assert.commandWorked(testColl.insert({_id: 1, a: [4, 5, 6], b: 'def'}));
jsTestLog('Checking documents in collection before restart');
let docs = testColl.find().sort({_id: 1}).toArray();
assert.eq(1, docs.length, 'too many docs in collection: ' + tojson(docs));
assert.eq(1, docs[0]._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');
docs = testColl.find().sort({_id: 1}).toArray();
assert.eq(1, docs.length, 'too many docs in collection: ' + tojson(docs));
assert.eq(1, docs[0]._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(1, result.nrecords, tojson(result));
assert.eq(3, result.nIndexes, tojson(result));
// Check non-multikey indexes.
assert.eq(1, result.keysPerIndex._id_, tojson(result));
assert.eq(1, result.keysPerIndex.b_hashed, tojson(result));
assert(result.indexDetails._id_.valid, tojson(result));
assert(result.indexDetails.b_hashed.valid, tojson(result));
// Check multikey index.
assert.eq(3, result.keysPerIndex.a_1, tojson(result));
assert(!result.indexDetails.a_1.valid, tojson(result));
assert(!result.valid, tojson(result));
rst.stopSet(/*signal=*/undefined, /*forRestart=*/undefined, {skipValidation: true});
})();