Skip to content

Commit fd9eeba

Browse files
committed
Only apply initial recovery filter to shrunk shard (#44054)
Today the `index.routing.allocation.initial_recovery._id` setting can only be set on indices that are the result of a shrink, but the filtered allocation decider also applies this filter to shards with a recovery source of `EMPTY_STORE`. The only way to have this setting set while the recovery source is `EMPTY_STORE` is to force-allocate an empty primary, but such a forced allocation ignores this allocation decider. This commit simplifies the allocation decider so that the `initial_recovery` setting only applies to shards with a recovery source of `LOCAL_SHARDS`.
1 parent 9eac5ce commit fd9eeba

File tree

2 files changed

+15
-42
lines changed

2 files changed

+15
-42
lines changed

server/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/FilterAllocationDecider.java

+4-17
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import org.elasticsearch.common.settings.Setting.Property;
3131
import org.elasticsearch.common.settings.Settings;
3232

33-
import java.util.EnumSet;
3433
import java.util.Map;
3534

3635
import static org.elasticsearch.cluster.node.DiscoveryNodeFilters.IP_VALIDATOR;
@@ -81,17 +80,6 @@ public class FilterAllocationDecider extends AllocationDecider {
8180
Setting.prefixKeySetting(CLUSTER_ROUTING_EXCLUDE_GROUP_PREFIX + ".", key ->
8281
Setting.simpleString(key, value -> IP_VALIDATOR.accept(key, value), Property.Dynamic, Property.NodeScope));
8382

84-
/**
85-
* The set of {@link RecoverySource.Type} values for which the
86-
* {@link IndexMetaData#INDEX_ROUTING_INITIAL_RECOVERY_GROUP_SETTING} should apply.
87-
* Note that we do not include the {@link RecoverySource.Type#SNAPSHOT} type here
88-
* because if the snapshot is restored to a different cluster that does not contain
89-
* the initial recovery node id, or to the same cluster where the initial recovery node
90-
* id has been decommissioned, then the primary shards will never be allocated.
91-
*/
92-
static EnumSet<RecoverySource.Type> INITIAL_RECOVERY_TYPES =
93-
EnumSet.of(RecoverySource.Type.EMPTY_STORE, RecoverySource.Type.LOCAL_SHARDS);
94-
9583
private volatile DiscoveryNodeFilters clusterRequireFilters;
9684
private volatile DiscoveryNodeFilters clusterIncludeFilters;
9785
private volatile DiscoveryNodeFilters clusterExcludeFilters;
@@ -108,17 +96,16 @@ public FilterAllocationDecider(Settings settings, ClusterSettings clusterSetting
10896
@Override
10997
public Decision canAllocate(ShardRouting shardRouting, RoutingNode node, RoutingAllocation allocation) {
11098
if (shardRouting.unassigned()) {
111-
// only for unassigned - we filter allocation right after the index creation ie. for shard shrinking etc. to ensure
99+
// only for unassigned - we filter allocation right after the index creation (for shard shrinking) to ensure
112100
// that once it has been allocated post API the replicas can be allocated elsewhere without user interaction
113101
// this is a setting that can only be set within the system!
114102
IndexMetaData indexMd = allocation.metaData().getIndexSafe(shardRouting.index());
115103
DiscoveryNodeFilters initialRecoveryFilters = indexMd.getInitialRecoveryFilters();
116104
if (initialRecoveryFilters != null &&
117-
INITIAL_RECOVERY_TYPES.contains(shardRouting.recoverySource().getType()) &&
105+
shardRouting.recoverySource().getType() == RecoverySource.Type.LOCAL_SHARDS &&
118106
initialRecoveryFilters.match(node.node()) == false) {
119-
String explanation = (shardRouting.recoverySource().getType() == RecoverySource.Type.LOCAL_SHARDS) ?
120-
"initial allocation of the shrunken index is only allowed on nodes [%s] that hold a copy of every shard in the index" :
121-
"initial allocation of the index is only allowed on nodes [%s]";
107+
String explanation =
108+
"initial allocation of the shrunken index is only allowed on nodes [%s] that hold a copy of every shard in the index";
122109
return allocation.decision(Decision.NO, NAME, explanation, initialRecoveryFilters);
123110
}
124111
}

server/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/FilterAllocationDeciderTests.java

+11-25
Original file line numberDiff line numberDiff line change
@@ -139,39 +139,25 @@ public void testFilterInitialRecovery() {
139139
}
140140

141141
private ClusterState createInitialClusterState(AllocationService service, Settings settings) {
142-
RecoverySource.Type recoveryType = randomFrom(FilterAllocationDecider.INITIAL_RECOVERY_TYPES);
143142
MetaData.Builder metaData = MetaData.builder();
144143
final Settings.Builder indexSettings = settings(Version.CURRENT).put(settings);
145144
final IndexMetaData sourceIndex;
146-
if (recoveryType == RecoverySource.Type.LOCAL_SHARDS) {
147-
//put a fake closed source index
148-
sourceIndex = IndexMetaData.builder("sourceIndex")
149-
.settings(settings(Version.CURRENT)).numberOfShards(2).numberOfReplicas(0)
150-
.putInSyncAllocationIds(0, Collections.singleton("aid0"))
151-
.putInSyncAllocationIds(1, Collections.singleton("aid1"))
152-
.build();
153-
metaData.put(sourceIndex, false);
154-
indexSettings.put(INDEX_RESIZE_SOURCE_UUID.getKey(), sourceIndex.getIndexUUID());
155-
indexSettings.put(INDEX_RESIZE_SOURCE_NAME.getKey(), sourceIndex.getIndex().getName());
156-
} else {
157-
sourceIndex = null;
158-
}
145+
//put a fake closed source index
146+
sourceIndex = IndexMetaData.builder("sourceIndex")
147+
.settings(settings(Version.CURRENT)).numberOfShards(2).numberOfReplicas(0)
148+
.putInSyncAllocationIds(0, Collections.singleton("aid0"))
149+
.putInSyncAllocationIds(1, Collections.singleton("aid1"))
150+
.build();
151+
metaData.put(sourceIndex, false);
152+
indexSettings.put(INDEX_RESIZE_SOURCE_UUID.getKey(), sourceIndex.getIndexUUID());
153+
indexSettings.put(INDEX_RESIZE_SOURCE_NAME.getKey(), sourceIndex.getIndex().getName());
159154
final IndexMetaData.Builder indexMetaDataBuilder = IndexMetaData.builder("idx").settings(indexSettings)
160155
.numberOfShards(1).numberOfReplicas(1);
161156
final IndexMetaData indexMetaData = indexMetaDataBuilder.build();
162157
metaData.put(indexMetaData, false);
163158
RoutingTable.Builder routingTableBuilder = RoutingTable.builder();
164-
switch (recoveryType) {
165-
case EMPTY_STORE:
166-
routingTableBuilder.addAsNew(indexMetaData);
167-
break;
168-
case LOCAL_SHARDS:
169-
routingTableBuilder.addAsFromCloseToOpen(sourceIndex);
170-
routingTableBuilder.addAsNew(indexMetaData);
171-
break;
172-
default:
173-
throw new UnsupportedOperationException(recoveryType + " is not supported");
174-
}
159+
routingTableBuilder.addAsFromCloseToOpen(sourceIndex);
160+
routingTableBuilder.addAsNew(indexMetaData);
175161

176162
RoutingTable routingTable = routingTableBuilder.build();
177163
ClusterState clusterState = ClusterState.builder(org.elasticsearch.cluster.ClusterName.CLUSTER_NAME_SETTING

0 commit comments

Comments
 (0)