/** * Tests the aggregation that collects index consistency metrics for serverStatus retries on stale * version errors. * @tags: [ * requires_sharding, * ] */ (function() { "use strict"; load("jstests/noPassthrough/libs/sharded_index_consistency_metrics_helpers.js"); load("jstests/sharding/libs/shard_versioning_util.js"); load("jstests/libs/fail_point_util.js"); // This test creates inconsistent indexes. TestData.skipCheckingIndexesConsistentAcrossCluster = true; const intervalMS = 10000; const st = new ShardingTest({ shards: 2, config: 1, configOptions: {setParameter: {"shardedIndexConsistencyCheckIntervalMS": intervalMS}} }); const dbName = "testDb"; const ns0 = dbName + ".testColl0"; const ns1 = dbName + ".testColl1"; const ns2 = dbName + ".testColl2"; // Create 3 sharded collections, two hashed and another with 3 chunks, 1 on shard1 and 2 on shard0. assert.commandWorked(st.s.adminCommand({enableSharding: dbName})); st.ensurePrimaryShard(dbName, st.shard0.shardName); assert.commandWorked(st.s.adminCommand({shardCollection: ns0, key: {_id: "hashed"}})); assert.commandWorked(st.s.adminCommand({shardCollection: ns1, key: {_id: "hashed"}})); assert.commandWorked(st.s.adminCommand({shardCollection: ns2, key: {_id: 1}})); assert.commandWorked(st.s.adminCommand({split: ns2, middle: {_id: 0}})); assert.commandWorked(st.s.adminCommand({split: ns2, middle: {_id: 10}})); assert.commandWorked(st.s.adminCommand({moveChunk: ns2, find: {_id: 10}, to: st.shard1.shardName})); // Wait for the periodic index check to run by creating an inconsistency and waiting for the new // counter value to be reported. assert.commandWorked(st.shard0.getCollection(ns0).createIndex({x: 1})); checkServerStatusNumCollsWithInconsistentIndexes(st.configRS.getPrimary(), 1); // Clear the config server's log before the check below so an earlier failure to load inconsistent // indexes won't trigger a failure when the logs are checked below. assert.commandWorked(st.configRS.getPrimary().adminCommand({clearLog: "global"})); // Create an index inconsistency on ns1 and then begin repeatedly moving a chunk between both shards // for ns2 without refreshing the recipient so at least one shard should typically be stale when the // periodic index check runs. The check should retry on stale config errors and be able to // eventually return the correct counter. assert.commandWorked(st.shard0.getCollection(ns1).createIndex({x: 1})); assert.soon( () => { ShardVersioningUtil.moveChunkNotRefreshRecipient(st.s, ns2, st.shard0, st.shard1, {_id: 0}); sleep(2000); ShardVersioningUtil.moveChunkNotRefreshRecipient(st.s, ns2, st.shard1, st.shard0, {_id: 0}); sleep(2000); const latestCount = getServerStatusNumCollsWithInconsistentIndexes(st.configRS.getPrimary()); jsTestLog( "Waiting for periodic index check to discover inconsistent indexes. Latest count: " + latestCount); return latestCount == 2; }, "periodic index check couldn't discover inconsistent indexes with stale shards", undefined, undefined, {runHangAnalyzer: false}); // As an extra sanity check, verify the index check didn't log a failure. checkLog.containsWithCount(st.configRS.getPrimary(), "Failed to check index consistency", 0); st.stop(); }());