Fix shard size of initializing restored shard#126783
Conversation
For shards being restored from a snapshot we use `SnapshotShardSizeInfo` to track their sizes while they're unassigned, and then use `ShardRouting#expectedShardSize` when they start to recover. However we were incorrectly ignoring the `ShardRouting#expectedShardSize` value when accounting for the movements of shards in the `ClusterInfoSimulator`, which would sometimes cause us to assign more shards to a node than its disk space should have allowed. Closes elastic#105331
|
Pinging @elastic/es-distributed-coordination (Team:Distributed Coordination) |
|
Hi @DaveCTurner, I've created a changelog YAML for you. |
| assertBusyWithDiskUsageRefresh(dataNode0Id, indexName, contains(in(shardSizes.getShardIdsWithSizeSmallerOrEqual(usableSpace)))); | ||
| } | ||
|
|
||
| public void testRestoreSnapshotAllocationDoesNotExceedWatermarkWithMultipleRestores() { |
There was a problem hiding this comment.
testRestoreSnapshotAllocationDoesNotExceedWatermarkWithMultipleShards was flaky because of this bug, but only failing once every few hundred iterations. This test fails more reliably for the same reason, although still not all that reliably (after around 20-30 iterations on my laptop). I could make it exercise the exact path that hits the bug every time, but it'd be very specific to this one bug and I'd rather have something a little more general to look out for related bugs too.
There was a problem hiding this comment.
So testRestoreSnapshotAllocationDoesNotExceedWatermarkWithMultipleShards does a little more disk usage checking as well as the shard assignment. This new test checks that shards are assigned correctly, not so much disk usage.
They feel a little redundant: might we add a couple more touches to the new one and delete the old?
There was a problem hiding this comment.
Yeah I was sort of inclined to keep them both but you're right, we're not really testing anything different in the old test.
There was a problem hiding this comment.
Great, thanks for updating
| var size = getExpectedShardSize( | ||
| shard, | ||
| UNAVAILABLE_EXPECTED_SHARD_SIZE, | ||
| shard.getExpectedShardSize(), |
There was a problem hiding this comment.
One-line fix \o/
…tRestoreSnapshotAllocationDoesNotExceedWatermarkWithMultipleShards
...erTest/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDeciderIT.java
Outdated
Show resolved
Hide resolved
...erTest/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDeciderIT.java
Show resolved
Hide resolved
…routing/allocation/decider/DiskThresholdDeciderIT.java Co-authored-by: Jeremy Dahlgren <jeremy.dahlgren@elastic.co>
…tRestoreSnapshotAllocationDoesNotExceedWatermarkWithMultipleShards
DiannaHohensee
left a comment
There was a problem hiding this comment.
I think the changes look good, I'm good with shipping it as is. Though I do wonder if we could delete the old test in favor of the new -- per comment.
| // set up a listener that explicitly forbids more than one shard to be assigned to the tiny node | ||
| final String dataNodeId = internalCluster().getInstance(NodeEnvironment.class, dataNodeName).nodeId(); | ||
| final var allShardsActiveListener = ClusterServiceUtils.addTemporaryStateListener(cs -> { | ||
| assertThat(cs.getRoutingNodes().toString(), cs.getRoutingNodes().node(dataNodeId).size(), lessThanOrEqualTo(1)); |
There was a problem hiding this comment.
Oooph, RoutingNode#size() is an unhelpful method name 😓
There was a problem hiding this comment.
Naming things is hard, but yeah this is not good. At least it has Javadocs :)
| clusterAdmin().prepareRestoreSnapshot(TEST_REQUEST_TIMEOUT, "repo", "snap") | ||
| .setWaitForCompletion(true) | ||
| .setRenamePattern(indexName) | ||
| .setRenameReplacement(indexName + "-copy") |
There was a problem hiding this comment.
Huh, is this purely a test-only feature? Doesn't look like it's used anyplace else.
(not actionable, I'm just surprised)
There was a problem hiding this comment.
We use the feature in production, see here:
We just don't use the RestoreSnapshotRequestBuilder to build a RestoreSnapshotRequest anywhere, instead building the request directly since it's all mutable anyway. Not a pattern I like, but one that is going to take a long time to completely eliminate.
| assertBusyWithDiskUsageRefresh(dataNode0Id, indexName, contains(in(shardSizes.getShardIdsWithSizeSmallerOrEqual(usableSpace)))); | ||
| } | ||
|
|
||
| public void testRestoreSnapshotAllocationDoesNotExceedWatermarkWithMultipleRestores() { |
There was a problem hiding this comment.
So testRestoreSnapshotAllocationDoesNotExceedWatermarkWithMultipleShards does a little more disk usage checking as well as the shard assignment. This new test checks that shards are assigned correctly, not so much disk usage.
They feel a little redundant: might we add a couple more touches to the new one and delete the old?
…tRestoreSnapshotAllocationDoesNotExceedWatermarkWithMultipleShards
…tRestoreSnapshotAllocationDoesNotExceedWatermarkWithMultipleShards
…tRestoreSnapshotAllocationDoesNotExceedWatermarkWithMultipleShards
For shards being restored from a snapshot we use `SnapshotShardSizeInfo` to track their sizes while they're unassigned, and then use `ShardRouting#expectedShardSize` when they start to recover. However we were incorrectly ignoring the `ShardRouting#expectedShardSize` value when accounting for the movements of shards in the `ClusterInfoSimulator`, which would sometimes cause us to assign more shards to a node than its disk space should have allowed. Closes elastic#105331
For shards being restored from a snapshot we use `SnapshotShardSizeInfo` to track their sizes while they're unassigned, and then use `ShardRouting#expectedShardSize` when they start to recover. However we were incorrectly ignoring the `ShardRouting#expectedShardSize` value when accounting for the movements of shards in the `ClusterInfoSimulator`, which would sometimes cause us to assign more shards to a node than its disk space should have allowed. Closes elastic#105331
For shards being restored from a snapshot we use `SnapshotShardSizeInfo` to track their sizes while they're unassigned, and then use `ShardRouting#expectedShardSize` when they start to recover. However we were incorrectly ignoring the `ShardRouting#expectedShardSize` value when accounting for the movements of shards in the `ClusterInfoSimulator`, which would sometimes cause us to assign more shards to a node than its disk space should have allowed. Closes elastic#105331
* Fix shard size of initializing restored shard (#126783) For shards being restored from a snapshot we use `SnapshotShardSizeInfo` to track their sizes while they're unassigned, and then use `ShardRouting#expectedShardSize` when they start to recover. However we were incorrectly ignoring the `ShardRouting#expectedShardSize` value when accounting for the movements of shards in the `ClusterInfoSimulator`, which would sometimes cause us to assign more shards to a node than its disk space should have allowed. Closes #105331 * Backport utils from 4009599
* Fix shard size of initializing restored shard (#126783) For shards being restored from a snapshot we use `SnapshotShardSizeInfo` to track their sizes while they're unassigned, and then use `ShardRouting#expectedShardSize` when they start to recover. However we were incorrectly ignoring the `ShardRouting#expectedShardSize` value when accounting for the movements of shards in the `ClusterInfoSimulator`, which would sometimes cause us to assign more shards to a node than its disk space should have allowed. Closes #105331 * Missing throws
* Fix shard size of initializing restored shard (#126783) For shards being restored from a snapshot we use `SnapshotShardSizeInfo` to track their sizes while they're unassigned, and then use `ShardRouting#expectedShardSize` when they start to recover. However we were incorrectly ignoring the `ShardRouting#expectedShardSize` value when accounting for the movements of shards in the `ClusterInfoSimulator`, which would sometimes cause us to assign more shards to a node than its disk space should have allowed. Closes #105331 * Backport utils from 4009599 * Missing throws
For shards being restored from a snapshot we use
SnapshotShardSizeInfoto track their sizes while they're unassigned, and then use
ShardRouting#expectedShardSizewhen they start to recover. However wewere incorrectly ignoring the
ShardRouting#expectedShardSizevaluewhen accounting for the movements of shards in the
ClusterInfoSimulator, which would sometimes cause us to assign moreshards to a node than its disk space should have allowed.
Closes #105331