Skip to content

Commit 859709c

Browse files
Closed index noop recovery during upgrade (#44072)
Test that closed indices do noop recovery during rolling upgrade.
1 parent fd9eeba commit 859709c

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

qa/rolling-upgrade/src/test/java/org/elasticsearch/upgrades/RecoveryIT.java

+69
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.elasticsearch.client.ResponseException;
2727
import org.elasticsearch.cluster.metadata.IndexMetaData;
2828
import org.elasticsearch.cluster.metadata.MetaDataIndexStateService;
29+
import org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider;
2930
import org.elasticsearch.common.Booleans;
3031
import org.elasticsearch.common.settings.Settings;
3132
import org.elasticsearch.common.util.concurrent.AbstractRunnable;
@@ -36,6 +37,7 @@
3637
import org.elasticsearch.rest.action.document.RestUpdateAction;
3738
import org.elasticsearch.test.rest.yaml.ObjectPath;
3839
import org.hamcrest.Matcher;
40+
import org.hamcrest.Matchers;
3941

4042
import java.io.IOException;
4143
import java.util.ArrayList;
@@ -448,6 +450,41 @@ public void testCloseIndexDuringRollingUpgrade() throws Exception {
448450
}
449451
}
450452

453+
/**
454+
* We test that a closed index makes no-op replica allocation/recovery only.
455+
*/
456+
public void testClosedIndexNoopRecovery() throws Exception {
457+
final String indexName = "closed_index_replica_allocation";
458+
if (CLUSTER_TYPE == ClusterType.OLD) {
459+
createIndex(indexName, Settings.builder()
460+
.put(IndexMetaData.INDEX_NUMBER_OF_SHARDS_SETTING.getKey(), 1)
461+
.put(IndexMetaData.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), 1)
462+
.put(EnableAllocationDecider.INDEX_ROUTING_REBALANCE_ENABLE_SETTING.getKey(), "none")
463+
.put(INDEX_DELAYED_NODE_LEFT_TIMEOUT_SETTING.getKey(), "120s")
464+
.put("index.routing.allocation.include._name", "node-0")
465+
.build());
466+
indexDocs(indexName, 0, randomInt(10));
467+
// allocate replica to node-2
468+
updateIndexSettings(indexName,
469+
Settings.builder().put("index.routing.allocation.include._name", "node-0,node-2,upgraded-node-*"));
470+
ensureGreen(indexName);
471+
closeIndex(indexName);
472+
}
473+
474+
final Version indexVersionCreated = indexVersionCreated(indexName);
475+
if (indexVersionCreated.onOrAfter(Version.V_7_2_0)) {
476+
// index was created on a version that supports the replication of closed indices,
477+
// so we expect the index to be closed and replicated
478+
ensureGreen(indexName);
479+
assertClosedIndex(indexName, true);
480+
if (CLUSTER_TYPE != ClusterType.OLD && minimumNodeVersion().onOrAfter(Version.V_7_2_0)) {
481+
assertNoFileBasedRecovery(indexName, s-> s.startsWith("upgraded"));
482+
}
483+
} else {
484+
assertClosedIndex(indexName, false);
485+
}
486+
487+
}
451488
/**
452489
* Returns the version in which the given index has been created
453490
*/
@@ -592,4 +629,36 @@ public void testUpdateDoc() throws Exception {
592629
client().performRequest(update);
593630
}
594631
}
632+
633+
private void assertNoFileBasedRecovery(String indexName, Predicate<String> targetNode) throws IOException {
634+
Map<String, Object> recoveries = entityAsMap(client()
635+
.performRequest(new Request("GET", indexName + "/_recovery?detailed=true")));
636+
637+
@SuppressWarnings("unchecked")
638+
List<Map<String, ?>> shards = (List<Map<String,?>>) XContentMapValues.extractValue(indexName + ".shards", recoveries);
639+
assertNotNull(shards);
640+
boolean foundReplica = false;
641+
for (Map<String, ?> shard : shards) {
642+
if (shard.get("primary") == Boolean.FALSE
643+
&& targetNode.test((String) XContentMapValues.extractValue("target.name", shard))) {
644+
List<?> details = (List<?>) XContentMapValues.extractValue("index.files.details", shard);
645+
// once detailed recoveries works, remove this if.
646+
if (details == null) {
647+
long totalFiles = ((Number) XContentMapValues.extractValue("index.files.total", shard)).longValue();
648+
long reusedFiles = ((Number) XContentMapValues.extractValue("index.files.reused", shard)).longValue();
649+
logger.info("total [{}] reused [{}]", totalFiles, reusedFiles);
650+
assertEquals("must reuse all files, recoveries [" + recoveries + "]", totalFiles, reusedFiles);
651+
} else {
652+
assertNotNull(details);
653+
assertThat(details, Matchers.empty());
654+
}
655+
656+
long translogRecovered = ((Number) XContentMapValues.extractValue("translog.recovered", shard)).longValue();
657+
assertEquals("must be noop, recoveries [" + recoveries + "]", 0, translogRecovered);
658+
foundReplica = true;
659+
}
660+
}
661+
662+
assertTrue("must find replica", foundReplica);
663+
}
595664
}

0 commit comments

Comments
 (0)