Skip to content

Commit 4fe4e7f

Browse files
committed
Fix handling of auto expand replicas for stateless indices
Auto expand replicas is meant to be entirely disabled for stateless indices. The only scenario where a change needs to be applied is when the number of replicas is initialized to 0, in which case 0 needs to be turned into 1. Otherwise, no changes should be applied in stateless indices despite auto expand replicas is used. The current handling for this was missing an early exit of the indices loop in the case where 0 shoudl be turned into 1, that leads to a potentially higher number of copies being allocated (effectively auto-expand gets applied by mistake).
1 parent e8bbf27 commit 4fe4e7f

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

server/src/main/java/org/elasticsearch/cluster/metadata/AutoExpandReplicas.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,8 @@ public static Map<Integer, List<String>> getAutoExpandReplicaChanges(
156156
)) {
157157
if (indexMetadata.getNumberOfReplicas() == 0) {
158158
nrReplicasChanged.computeIfAbsent(1, ArrayList::new).add(indexMetadata.getIndex().getName());
159-
} else {
160-
continue;
161159
}
160+
continue;
162161
}
163162
if (allocation == null) {
164163
allocation = allocationSupplier.get();

server/src/test/java/org/elasticsearch/cluster/metadata/AutoExpandReplicasTests.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
import org.elasticsearch.cluster.routing.IndexShardRoutingTable;
2121
import org.elasticsearch.cluster.routing.RoutingNodesHelper;
2222
import org.elasticsearch.cluster.routing.ShardRoutingState;
23+
import org.elasticsearch.cluster.routing.allocation.ExistingShardsAllocator;
2324
import org.elasticsearch.common.settings.Settings;
2425
import org.elasticsearch.core.Strings;
26+
import org.elasticsearch.index.IndexVersion;
2527
import org.elasticsearch.indices.cluster.ClusterStateChanges;
2628
import org.elasticsearch.test.ESTestCase;
2729
import org.elasticsearch.threadpool.TestThreadPool;
@@ -31,11 +33,14 @@
3133
import java.util.Collections;
3234
import java.util.HashSet;
3335
import java.util.List;
36+
import java.util.Map;
3437
import java.util.Set;
3538
import java.util.concurrent.atomic.AtomicInteger;
3639
import java.util.stream.Collectors;
3740

41+
import static org.elasticsearch.cluster.metadata.IndexMetadata.INDEX_AUTO_EXPAND_REPLICAS_SETTING;
3842
import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_AUTO_EXPAND_REPLICAS;
43+
import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_NUMBER_OF_REPLICAS;
3944
import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_NUMBER_OF_SHARDS;
4045
import static org.hamcrest.Matchers.equalTo;
4146
import static org.hamcrest.Matchers.everyItem;
@@ -221,4 +226,48 @@ public void testCalculateDesiredNumberOfReplicas() {
221226
assertThat(autoExpandReplicas.calculateDesiredNumberOfReplicas(matchingNodes), equalTo(Math.max(lowerBound, matchingNodes - 1)));
222227
assertThat(autoExpandReplicas.calculateDesiredNumberOfReplicas(max + 1), equalTo(max));
223228
}
229+
230+
public void testGetAutoExpandReplicaChangesStatelessIndices() {
231+
{
232+
// number of replicas is adjusted to 1 when it is initialized to 0
233+
Metadata metadata = Metadata.builder()
234+
.put(
235+
IndexMetadata.builder("test")
236+
.settings(
237+
Settings.builder()
238+
.put(ExistingShardsAllocator.EXISTING_SHARDS_ALLOCATOR_SETTING.getKey(), "stateless")
239+
.put("index.version.created", IndexVersion.current())
240+
.put(SETTING_NUMBER_OF_SHARDS, 1)
241+
.put(SETTING_NUMBER_OF_REPLICAS, 0)
242+
.put(INDEX_AUTO_EXPAND_REPLICAS_SETTING.getKey(), "0-all")
243+
)
244+
)
245+
.build();
246+
Map<Integer, List<String>> autoExpandReplicaChanges = AutoExpandReplicas.getAutoExpandReplicaChanges(metadata, null);
247+
assertEquals(1, autoExpandReplicaChanges.size());
248+
List<String> indices = autoExpandReplicaChanges.get(1);
249+
assertEquals(1, indices.size());
250+
assertEquals("test", indices.getFirst());
251+
}
252+
{
253+
// no changes when number of replicas is set to anything other than 0
254+
Metadata metadata = Metadata.builder()
255+
.put(
256+
IndexMetadata.builder("test")
257+
.settings(
258+
Settings.builder()
259+
.put(ExistingShardsAllocator.EXISTING_SHARDS_ALLOCATOR_SETTING.getKey(), "stateless")
260+
.put("index.version.created", IndexVersion.current())
261+
.put(SETTING_NUMBER_OF_SHARDS, 1)
262+
.put(SETTING_NUMBER_OF_REPLICAS, randomIntBetween(1, 10))
263+
.put(INDEX_AUTO_EXPAND_REPLICAS_SETTING.getKey(), "0-all")
264+
)
265+
)
266+
.build();
267+
Map<Integer, List<String>> autoExpandReplicaChanges = AutoExpandReplicas.getAutoExpandReplicaChanges(metadata, () -> {
268+
throw new UnsupportedOperationException();
269+
});
270+
assertEquals(0, autoExpandReplicaChanges.size());
271+
}
272+
}
224273
}

0 commit comments

Comments
 (0)