|
23 | 23 | import com.carrotsearch.hppc.procedures.IntProcedure; |
24 | 24 | import org.apache.lucene.index.IndexFileNames; |
25 | 25 | import org.apache.lucene.util.English; |
| 26 | +import org.elasticsearch.action.ActionFuture; |
26 | 27 | import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; |
| 28 | +import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteResponse; |
27 | 29 | import org.elasticsearch.action.index.IndexRequestBuilder; |
28 | 30 | import org.elasticsearch.action.search.SearchResponse; |
| 31 | +import org.elasticsearch.action.support.WriteRequest; |
29 | 32 | import org.elasticsearch.client.Client; |
30 | 33 | import org.elasticsearch.cluster.ClusterState; |
31 | 34 | import org.elasticsearch.cluster.metadata.IndexMetaData; |
@@ -506,6 +509,97 @@ public void testIndexAndRelocateConcurrently() throws ExecutionException, Interr |
506 | 509 |
|
507 | 510 | } |
508 | 511 |
|
| 512 | + public void testRelocateWhileWaitingForRefresh() { |
| 513 | + logger.info("--> starting [node1] ..."); |
| 514 | + final String node1 = internalCluster().startNode(); |
| 515 | + |
| 516 | + logger.info("--> creating test index ..."); |
| 517 | + prepareCreate("test", Settings.builder() |
| 518 | + .put("index.number_of_shards", 1) |
| 519 | + .put("index.number_of_replicas", 0) |
| 520 | + .put("index.refresh_interval", -1) // we want to control refreshes |
| 521 | + ).get(); |
| 522 | + |
| 523 | + logger.info("--> index 10 docs"); |
| 524 | + for (int i = 0; i < 10; i++) { |
| 525 | + client().prepareIndex("test", "type", Integer.toString(i)).setSource("field", "value" + i).execute().actionGet(); |
| 526 | + } |
| 527 | + logger.info("--> flush so we have an actual index"); |
| 528 | + client().admin().indices().prepareFlush().execute().actionGet(); |
| 529 | + logger.info("--> index more docs so we have something in the translog"); |
| 530 | + for (int i = 10; i < 20; i++) { |
| 531 | + client().prepareIndex("test", "type", Integer.toString(i)).setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL) |
| 532 | + .setSource("field", "value" + i).execute(); |
| 533 | + } |
| 534 | + |
| 535 | + logger.info("--> start another node"); |
| 536 | + final String node2 = internalCluster().startNode(); |
| 537 | + ClusterHealthResponse clusterHealthResponse = client().admin().cluster().prepareHealth().setWaitForEvents(Priority.LANGUID) |
| 538 | + .setWaitForNodes("2").execute().actionGet(); |
| 539 | + assertThat(clusterHealthResponse.isTimedOut(), equalTo(false)); |
| 540 | + |
| 541 | + logger.info("--> relocate the shard from node1 to node2"); |
| 542 | + client().admin().cluster().prepareReroute() |
| 543 | + .add(new MoveAllocationCommand("test", 0, node1, node2)) |
| 544 | + .execute().actionGet(); |
| 545 | + |
| 546 | + clusterHealthResponse = client().admin().cluster().prepareHealth().setWaitForEvents(Priority.LANGUID) |
| 547 | + .setWaitForNoRelocatingShards(true).setTimeout(ACCEPTABLE_RELOCATION_TIME).execute().actionGet(); |
| 548 | + assertThat(clusterHealthResponse.isTimedOut(), equalTo(false)); |
| 549 | + |
| 550 | + logger.info("--> verifying count"); |
| 551 | + client().admin().indices().prepareRefresh().execute().actionGet(); |
| 552 | + assertThat(client().prepareSearch("test").setSize(0).execute().actionGet().getHits().getTotalHits().value, equalTo(20L)); |
| 553 | + } |
| 554 | + |
| 555 | + public void testRelocateWhileContinuouslyIndexingAndWaitingForRefresh() { |
| 556 | + logger.info("--> starting [node1] ..."); |
| 557 | + final String node1 = internalCluster().startNode(); |
| 558 | + |
| 559 | + logger.info("--> creating test index ..."); |
| 560 | + prepareCreate("test", Settings.builder() |
| 561 | + .put("index.number_of_shards", 1) |
| 562 | + .put("index.number_of_replicas", 0) |
| 563 | + .put("index.refresh_interval", -1) // we want to control refreshes |
| 564 | + ).get(); |
| 565 | + |
| 566 | + logger.info("--> index 10 docs"); |
| 567 | + for (int i = 0; i < 10; i++) { |
| 568 | + client().prepareIndex("test", "type", Integer.toString(i)).setSource("field", "value" + i).execute().actionGet(); |
| 569 | + } |
| 570 | + logger.info("--> flush so we have an actual index"); |
| 571 | + client().admin().indices().prepareFlush().execute().actionGet(); |
| 572 | + logger.info("--> index more docs so we have something in the translog"); |
| 573 | + for (int i = 10; i < 20; i++) { |
| 574 | + client().prepareIndex("test", "type", Integer.toString(i)).setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL) |
| 575 | + .setSource("field", "value" + i).execute(); |
| 576 | + } |
| 577 | + |
| 578 | + logger.info("--> start another node"); |
| 579 | + final String node2 = internalCluster().startNode(); |
| 580 | + ClusterHealthResponse clusterHealthResponse = client().admin().cluster().prepareHealth().setWaitForEvents(Priority.LANGUID) |
| 581 | + .setWaitForNodes("2").execute().actionGet(); |
| 582 | + assertThat(clusterHealthResponse.isTimedOut(), equalTo(false)); |
| 583 | + |
| 584 | + logger.info("--> relocate the shard from node1 to node2"); |
| 585 | + ActionFuture<ClusterRerouteResponse> relocationListener = client().admin().cluster().prepareReroute() |
| 586 | + .add(new MoveAllocationCommand("test", 0, node1, node2)) |
| 587 | + .execute(); |
| 588 | + logger.info("--> index 100 docs while relocating"); |
| 589 | + for (int i = 20; i < 120; i++) { |
| 590 | + client().prepareIndex("test", "type", Integer.toString(i)).setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL) |
| 591 | + .setSource("field", "value" + i).execute(); |
| 592 | + } |
| 593 | + relocationListener.actionGet(); |
| 594 | + clusterHealthResponse = client().admin().cluster().prepareHealth().setWaitForEvents(Priority.LANGUID) |
| 595 | + .setWaitForNoRelocatingShards(true).setTimeout(ACCEPTABLE_RELOCATION_TIME).execute().actionGet(); |
| 596 | + assertThat(clusterHealthResponse.isTimedOut(), equalTo(false)); |
| 597 | + |
| 598 | + logger.info("--> verifying count"); |
| 599 | + client().admin().indices().prepareRefresh().execute().actionGet(); |
| 600 | + assertThat(client().prepareSearch("test").setSize(0).execute().actionGet().getHits().getTotalHits().value, equalTo(120L)); |
| 601 | + } |
| 602 | + |
509 | 603 | class RecoveryCorruption implements StubbableTransport.SendRequestBehavior { |
510 | 604 |
|
511 | 605 | private final CountDownLatch corruptionCount; |
|
0 commit comments