diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetadata.java b/server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetadata.java index f88961071b4c8..59ee04414b3fc 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetadata.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetadata.java @@ -1998,34 +1998,31 @@ public Builder numberOfShards(int numberOfShards) { /** * Builder to create IndexMetadata that has an increased shard count (used for re-shard). - * The new shard count must be a multiple of the original shardcount. + * The new shard count must be a multiple of the original shardcount as well as a factor + * of routingNumShards. * We do not support shrinking the shard count. - * @param shardCount updated shardCount - * - * TODO: Check if this.version needs to be incremented + * @param targetShardCount target shard count after resharding */ - public Builder reshardAddShards(int shardCount) { - // Assert routingNumShards is null ? - // Assert numberOfShards > 0 - if (shardCount % numberOfShards() != 0) { + public Builder reshardAddShards(int targetShardCount) { + final int sourceNumShards = numberOfShards(); + if (targetShardCount % sourceNumShards != 0) { throw new IllegalArgumentException( "New shard count [" - + shardCount + + targetShardCount + "] should be a multiple" + " of current shard count [" - + numberOfShards() + + sourceNumShards + "] for [" + index + "]" ); } - IndexVersion indexVersionCreated = indexCreatedVersion(settings); - settings = Settings.builder().put(settings).put(SETTING_NUMBER_OF_SHARDS, shardCount).build(); - var newPrimaryTerms = new long[shardCount]; + settings = Settings.builder().put(settings).put(SETTING_NUMBER_OF_SHARDS, targetShardCount).build(); + var newPrimaryTerms = new long[targetShardCount]; Arrays.fill(newPrimaryTerms, this.primaryTerms.length, newPrimaryTerms.length, SequenceNumbers.UNASSIGNED_PRIMARY_TERM); System.arraycopy(primaryTerms, 0, newPrimaryTerms, 0, this.primaryTerms.length); primaryTerms = newPrimaryTerms; - routingNumShards = MetadataCreateIndexService.calculateNumRoutingShards(shardCount, indexVersionCreated); + routingNumShards = MetadataCreateIndexService.getIndexNumberOfRoutingShards(settings, sourceNumShards, this.routingNumShards); return this; } @@ -3034,7 +3031,7 @@ public static ShardId selectCloneShard(int shardId, IndexMetadata sourceIndexMet return new ShardId(sourceIndexMetadata.getIndex(), shardId); } - private static void assertSplitMetadata(int numSourceShards, int numTargetShards, IndexMetadata sourceIndexMetadata) { + public static void assertSplitMetadata(int numSourceShards, int numTargetShards, IndexMetadata sourceIndexMetadata) { if (numSourceShards > numTargetShards) { throw new IllegalArgumentException( "the number of source shards [" diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/MetadataCreateIndexService.java b/server/src/main/java/org/elasticsearch/cluster/metadata/MetadataCreateIndexService.java index 9b50872d8fa80..a131d49fd5269 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/MetadataCreateIndexService.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/MetadataCreateIndexService.java @@ -1282,10 +1282,23 @@ private static void validateSoftDeleteSettings(Settings indexSettings) { * it will return the value configured for that index. */ static int getIndexNumberOfRoutingShards(Settings indexSettings, @Nullable IndexMetadata sourceMetadata) { + final int routingNumShards = getIndexNumberOfRoutingShards( + indexSettings, + sourceMetadata == null ? 1 : sourceMetadata.getNumberOfShards(), + sourceMetadata == null ? 0 : sourceMetadata.getRoutingNumShards() + ); + return routingNumShards; + } + + /** + * Calculates the number of routing shards based on the configured value in indexSettings or if recovering from another index + * it will return the value configured for that index. + */ + static int getIndexNumberOfRoutingShards(Settings indexSettings, final int sourceNumShards, final int sourceRoutingNumShards) { final int numTargetShards = INDEX_NUMBER_OF_SHARDS_SETTING.get(indexSettings); final IndexVersion indexVersionCreated = IndexMetadata.SETTING_INDEX_VERSION_CREATED.get(indexSettings); final int routingNumShards; - if (sourceMetadata == null || sourceMetadata.getNumberOfShards() == 1) { + if (sourceNumShards == 1) { // in this case we either have no index to recover from or // we have a source index with 1 shard and without an explicit split factor // or one that is valid in that case we can split into whatever and auto-generate a new factor. @@ -1299,7 +1312,7 @@ static int getIndexNumberOfRoutingShards(Settings indexSettings, @Nullable Index } else { assert IndexMetadata.INDEX_NUMBER_OF_ROUTING_SHARDS_SETTING.exists(indexSettings) == false : "index.number_of_routing_shards should not be present on the target index on resize"; - routingNumShards = sourceMetadata.getRoutingNumShards(); + routingNumShards = sourceRoutingNumShards; } return routingNumShards; }