-
Type: Task
-
Resolution: Fixed
-
Priority: Major - P3
-
Affects Version/s: None
-
Component/s: Index Maintenance, Sharding
-
Labels:
-
Fully Compatible
-
Sharding 2019-07-15
This only affects debug builds, since the assertion is a dassert. In a sharded cluster, I have an existing sharded collection sharded on {"shardKey": "hashed"}:
mongos> sh.shardCollection("test.sharded", {shardKey: "hashed"}) { "collectionsharded" : "test.sharded", "collectionUUID" : UUID("872244a4-4045-444c-b014-61170c3bc6da"), "ok" : 1, "operationTime" : Timestamp(1533326578, 10), "$clusterTime" : { "clusterTime" : Timestamp(1533326578, 10), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } }
This index creation trips the invariant failure:
mongos> db.sharded.createIndex({shardKey: "hashed", x: 1, y: 1}, {unique: true}) { "raw" : { "shardingtest-rs0/kimchi:20000" : { "ok" : 0, "errmsg" : "Connection was closed", "code" : 6, "codeName" : "HostUnreachable" }, "shardingtest-rs1/kimchi:20001" : { "ok" : 0, "errmsg" : "Connection was closed", "code" : 6, "codeName" : "HostUnreachable" } }, "code" : 6, "codeName" : "HostUnreachable", "ok" : 0, "errmsg" : "{ shardingtest-rs0/kimchi:20000: \"Connection was closed\", shardingtest-rs1/kimchi:20001: \"Connection was closed\" }", "operationTime" : Timestamp(1533326580, 1), "$clusterTime" : { "clusterTime" : Timestamp(1533326580, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } }
The invariant failure in question is
d20001| 2018-08-03T16:03:00.733-0400 F - [conn21] Invariant failure !KeyPattern::isHashedKeyPattern(uniqueIndexPattern) src/mongo/s/shard_key_pattern.cpp 351
The failing assertion is here. It seems like we should be doing more validation beforehand before hitting the invariant, though.
shard_key_pattern.cpp
bool ShardKeyPattern::isUniqueIndexCompatible(const BSONObj& uniqueIndexPattern) const { dassert(!KeyPattern::isHashedKeyPattern(uniqueIndexPattern)); if (!uniqueIndexPattern.isEmpty() && uniqueIndexPattern.firstElementFieldName() == kIdField) { return true; } return _keyPattern.toBSON().isFieldNamePrefixOf(uniqueIndexPattern); }