|
@@ -18,16 +18,20 @@
|
|
|
*/
|
|
|
package org.elasticsearch.indices;
|
|
|
|
|
|
+import org.apache.lucene.index.DirectoryReader;
|
|
|
+import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeResponse;
|
|
|
import org.elasticsearch.common.settings.Settings;
|
|
|
import org.elasticsearch.common.unit.ByteSizeUnit;
|
|
|
import org.elasticsearch.common.unit.ByteSizeValue;
|
|
|
import org.elasticsearch.common.unit.TimeValue;
|
|
|
import org.elasticsearch.index.IndexService;
|
|
|
+import org.elasticsearch.index.engine.Engine;
|
|
|
import org.elasticsearch.index.shard.IndexShard;
|
|
|
import org.elasticsearch.test.ESSingleNodeTestCase;
|
|
|
import org.elasticsearch.threadpool.ThreadPool;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
+import java.util.Collections;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.HashSet;
|
|
|
import java.util.List;
|
|
@@ -37,88 +41,114 @@ import java.util.concurrent.ScheduledFuture;
|
|
|
|
|
|
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_REPLICAS;
|
|
|
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_SHARDS;
|
|
|
+import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
|
|
|
import static org.hamcrest.Matchers.equalTo;
|
|
|
|
|
|
public class IndexingMemoryControllerTests extends ESSingleNodeTestCase {
|
|
|
|
|
|
static class MockController extends IndexingMemoryController {
|
|
|
|
|
|
- final static ByteSizeValue INACTIVE = new ByteSizeValue(-1);
|
|
|
+ // Size of each shard's indexing buffer
|
|
|
+ final Map<IndexShard, Long> indexBufferRAMBytesUsed = new HashMap<>();
|
|
|
|
|
|
- final Map<IndexShard, ByteSizeValue> indexingBuffers = new HashMap<>();
|
|
|
+ // How many bytes this shard is currently moving to disk
|
|
|
+ final Map<IndexShard, Long> writingBytes = new HashMap<>();
|
|
|
|
|
|
- final Map<IndexShard, Long> lastIndexTimeNanos = new HashMap<>();
|
|
|
- final Set<IndexShard> activeShards = new HashSet<>();
|
|
|
-
|
|
|
- long currentTimeSec = TimeValue.timeValueNanos(System.nanoTime()).seconds();
|
|
|
+ // Shards that are currently throttled
|
|
|
+ final Set<IndexShard> throttled = new HashSet<>();
|
|
|
|
|
|
public MockController(Settings settings) {
|
|
|
super(Settings.builder()
|
|
|
- .put(SHARD_INACTIVE_INTERVAL_TIME_SETTING, "200h") // disable it
|
|
|
- .put(IndexShard.INDEX_SHARD_INACTIVE_TIME_SETTING, "1ms") // nearly immediate
|
|
|
- .put(settings)
|
|
|
- .build(),
|
|
|
- null, null, 100 * 1024 * 1024); // fix jvm mem size to 100mb
|
|
|
+ .put(SHARD_MEMORY_INTERVAL_TIME_SETTING, "200h") // disable it
|
|
|
+ .put(settings)
|
|
|
+ .build(),
|
|
|
+ null, null, 100 * 1024 * 1024); // fix jvm mem size to 100mb
|
|
|
}
|
|
|
|
|
|
- public void deleteShard(IndexShard id) {
|
|
|
- indexingBuffers.remove(id);
|
|
|
+ public void deleteShard(IndexShard shard) {
|
|
|
+ indexBufferRAMBytesUsed.remove(shard);
|
|
|
+ writingBytes.remove(shard);
|
|
|
}
|
|
|
|
|
|
- public void assertBuffers(IndexShard id, ByteSizeValue indexing) {
|
|
|
- assertThat(indexingBuffers.get(id), equalTo(indexing));
|
|
|
+ @Override
|
|
|
+ protected List<IndexShard> availableShards() {
|
|
|
+ return new ArrayList<>(indexBufferRAMBytesUsed.keySet());
|
|
|
}
|
|
|
|
|
|
- public void assertInactive(IndexShard id) {
|
|
|
- assertThat(indexingBuffers.get(id), equalTo(INACTIVE));
|
|
|
+ @Override
|
|
|
+ protected long getIndexBufferRAMBytesUsed(IndexShard shard) {
|
|
|
+ return indexBufferRAMBytesUsed.get(shard) + writingBytes.get(shard);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- protected long currentTimeInNanos() {
|
|
|
- return TimeValue.timeValueSeconds(currentTimeSec).nanos();
|
|
|
+ protected long getShardWritingBytes(IndexShard shard) {
|
|
|
+ Long bytes = writingBytes.get(shard);
|
|
|
+ if (bytes == null) {
|
|
|
+ return 0;
|
|
|
+ } else {
|
|
|
+ return bytes;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- protected List<IndexShard> availableShards() {
|
|
|
- return new ArrayList<>(indexingBuffers.keySet());
|
|
|
+ protected void checkIdle(IndexShard shard, long inactiveTimeNS) {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- protected boolean shardAvailable(IndexShard shard) {
|
|
|
- return indexingBuffers.containsKey(shard);
|
|
|
+ public void writeIndexingBufferAsync(IndexShard shard) {
|
|
|
+ long bytes = indexBufferRAMBytesUsed.put(shard, 0L);
|
|
|
+ writingBytes.put(shard, writingBytes.get(shard) + bytes);
|
|
|
+ indexBufferRAMBytesUsed.put(shard, 0L);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- protected void updateShardBuffers(IndexShard shard, ByteSizeValue shardIndexingBufferSize) {
|
|
|
- indexingBuffers.put(shard, shardIndexingBufferSize);
|
|
|
+ public void activateThrottling(IndexShard shard) {
|
|
|
+ assertTrue(throttled.add(shard));
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- protected boolean checkIdle(IndexShard shard) {
|
|
|
- final TimeValue inactiveTime = settings.getAsTime(IndexShard.INDEX_SHARD_INACTIVE_TIME_SETTING, TimeValue.timeValueMinutes(5));
|
|
|
- Long ns = lastIndexTimeNanos.get(shard);
|
|
|
- if (ns == null) {
|
|
|
- return true;
|
|
|
- } else if (currentTimeInNanos() - ns >= inactiveTime.nanos()) {
|
|
|
- indexingBuffers.put(shard, INACTIVE);
|
|
|
- activeShards.remove(shard);
|
|
|
- return true;
|
|
|
- } else {
|
|
|
- return false;
|
|
|
+ public void deactivateThrottling(IndexShard shard) {
|
|
|
+ assertTrue(throttled.remove(shard));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void doneWriting(IndexShard shard) {
|
|
|
+ writingBytes.put(shard, 0L);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void assertBuffer(IndexShard shard, int expectedMB) {
|
|
|
+ Long actual = indexBufferRAMBytesUsed.get(shard);
|
|
|
+ if (actual == null) {
|
|
|
+ actual = 0L;
|
|
|
}
|
|
|
+ assertEquals(expectedMB * 1024 * 1024, actual.longValue());
|
|
|
}
|
|
|
|
|
|
- public void incrementTimeSec(int sec) {
|
|
|
- currentTimeSec += sec;
|
|
|
+ public void assertThrottled(IndexShard shard) {
|
|
|
+ assertTrue(throttled.contains(shard));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void assertNotThrottled(IndexShard shard) {
|
|
|
+ assertFalse(throttled.contains(shard));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void assertWriting(IndexShard shard, int expectedMB) {
|
|
|
+ Long actual = writingBytes.get(shard);
|
|
|
+ if (actual == null) {
|
|
|
+ actual = 0L;
|
|
|
+ }
|
|
|
+ assertEquals(expectedMB * 1024 * 1024, actual.longValue());
|
|
|
}
|
|
|
|
|
|
public void simulateIndexing(IndexShard shard) {
|
|
|
- lastIndexTimeNanos.put(shard, currentTimeInNanos());
|
|
|
- if (indexingBuffers.containsKey(shard) == false) {
|
|
|
- // First time we are seeing this shard; start it off with inactive buffers as IndexShard does:
|
|
|
- indexingBuffers.put(shard, IndexingMemoryController.INACTIVE_SHARD_INDEXING_BUFFER);
|
|
|
+ Long bytes = indexBufferRAMBytesUsed.get(shard);
|
|
|
+ if (bytes == null) {
|
|
|
+ bytes = 0L;
|
|
|
+ // First time we are seeing this shard:
|
|
|
+ writingBytes.put(shard, 0L);
|
|
|
}
|
|
|
- activeShards.add(shard);
|
|
|
+ // Each doc we index takes up a megabyte!
|
|
|
+ bytes += 1024*1024;
|
|
|
+ indexBufferRAMBytesUsed.put(shard, bytes);
|
|
|
forceCheck();
|
|
|
}
|
|
|
|
|
@@ -134,21 +164,21 @@ public class IndexingMemoryControllerTests extends ESSingleNodeTestCase {
|
|
|
IndexService test = indicesService.indexService("test");
|
|
|
|
|
|
MockController controller = new MockController(Settings.builder()
|
|
|
- .put(IndexingMemoryController.INDEX_BUFFER_SIZE_SETTING, "10mb").build());
|
|
|
+ .put(IndexingMemoryController.INDEX_BUFFER_SIZE_SETTING, "4mb").build());
|
|
|
IndexShard shard0 = test.getShard(0);
|
|
|
controller.simulateIndexing(shard0);
|
|
|
- controller.assertBuffers(shard0, new ByteSizeValue(10, ByteSizeUnit.MB)); // translog is maxed at 64K
|
|
|
+ controller.assertBuffer(shard0, 1);
|
|
|
|
|
|
// add another shard
|
|
|
IndexShard shard1 = test.getShard(1);
|
|
|
controller.simulateIndexing(shard1);
|
|
|
- controller.assertBuffers(shard0, new ByteSizeValue(5, ByteSizeUnit.MB));
|
|
|
- controller.assertBuffers(shard1, new ByteSizeValue(5, ByteSizeUnit.MB));
|
|
|
+ controller.assertBuffer(shard0, 1);
|
|
|
+ controller.assertBuffer(shard1, 1);
|
|
|
|
|
|
// remove first shard
|
|
|
controller.deleteShard(shard0);
|
|
|
controller.forceCheck();
|
|
|
- controller.assertBuffers(shard1, new ByteSizeValue(10, ByteSizeUnit.MB)); // translog is maxed at 64K
|
|
|
+ controller.assertBuffer(shard1, 1);
|
|
|
|
|
|
// remove second shard
|
|
|
controller.deleteShard(shard1);
|
|
@@ -157,85 +187,48 @@ public class IndexingMemoryControllerTests extends ESSingleNodeTestCase {
|
|
|
// add a new one
|
|
|
IndexShard shard2 = test.getShard(2);
|
|
|
controller.simulateIndexing(shard2);
|
|
|
- controller.assertBuffers(shard2, new ByteSizeValue(10, ByteSizeUnit.MB)); // translog is maxed at 64K
|
|
|
+ controller.assertBuffer(shard2, 1);
|
|
|
}
|
|
|
|
|
|
public void testActiveInactive() {
|
|
|
+
|
|
|
createIndex("test", Settings.builder().put(SETTING_NUMBER_OF_SHARDS, 2).put(SETTING_NUMBER_OF_REPLICAS, 0).build());
|
|
|
IndicesService indicesService = getInstanceFromNode(IndicesService.class);
|
|
|
IndexService test = indicesService.indexService("test");
|
|
|
|
|
|
MockController controller = new MockController(Settings.builder()
|
|
|
- .put(IndexingMemoryController.INDEX_BUFFER_SIZE_SETTING, "10mb")
|
|
|
- .put(IndexShard.INDEX_SHARD_INACTIVE_TIME_SETTING, "5s")
|
|
|
- .build());
|
|
|
+ .put(IndexingMemoryController.INDEX_BUFFER_SIZE_SETTING, "5mb")
|
|
|
+ .build());
|
|
|
|
|
|
IndexShard shard0 = test.getShard(0);
|
|
|
controller.simulateIndexing(shard0);
|
|
|
IndexShard shard1 = test.getShard(1);
|
|
|
controller.simulateIndexing(shard1);
|
|
|
- controller.assertBuffers(shard0, new ByteSizeValue(5, ByteSizeUnit.MB));
|
|
|
- controller.assertBuffers(shard1, new ByteSizeValue(5, ByteSizeUnit.MB));
|
|
|
|
|
|
- // index into both shards, move the clock and see that they are still active
|
|
|
+ controller.assertBuffer(shard0, 1);
|
|
|
+ controller.assertBuffer(shard1, 1);
|
|
|
+
|
|
|
controller.simulateIndexing(shard0);
|
|
|
controller.simulateIndexing(shard1);
|
|
|
|
|
|
- controller.incrementTimeSec(10);
|
|
|
- controller.forceCheck();
|
|
|
-
|
|
|
- // both shards now inactive
|
|
|
- controller.assertInactive(shard0);
|
|
|
- controller.assertInactive(shard1);
|
|
|
+ controller.assertBuffer(shard0, 2);
|
|
|
+ controller.assertBuffer(shard1, 2);
|
|
|
|
|
|
- // index into one shard only, see it becomes active
|
|
|
+ // index into one shard only, crosses the 5mb limit, so shard1 is refreshed
|
|
|
controller.simulateIndexing(shard0);
|
|
|
- controller.assertBuffers(shard0, new ByteSizeValue(10, ByteSizeUnit.MB));
|
|
|
- controller.assertInactive(shard1);
|
|
|
-
|
|
|
- controller.incrementTimeSec(3); // increment but not enough to become inactive
|
|
|
- controller.forceCheck();
|
|
|
- controller.assertBuffers(shard0, new ByteSizeValue(10, ByteSizeUnit.MB));
|
|
|
- controller.assertInactive(shard1);
|
|
|
-
|
|
|
- controller.incrementTimeSec(3); // increment some more
|
|
|
- controller.forceCheck();
|
|
|
- controller.assertInactive(shard0);
|
|
|
- controller.assertInactive(shard1);
|
|
|
+ controller.simulateIndexing(shard0);
|
|
|
+ controller.assertBuffer(shard0, 0);
|
|
|
+ controller.assertBuffer(shard1, 2);
|
|
|
|
|
|
- // index some and shard becomes immediately active
|
|
|
controller.simulateIndexing(shard1);
|
|
|
- controller.assertInactive(shard0);
|
|
|
- controller.assertBuffers(shard1, new ByteSizeValue(10, ByteSizeUnit.MB));
|
|
|
- }
|
|
|
-
|
|
|
- public void testMinShardBufferSizes() {
|
|
|
- MockController controller = new MockController(Settings.builder()
|
|
|
- .put(IndexingMemoryController.INDEX_BUFFER_SIZE_SETTING, "10mb")
|
|
|
- .put(IndexingMemoryController.MIN_SHARD_INDEX_BUFFER_SIZE_SETTING, "6mb")
|
|
|
- .put(IndexingMemoryController.MIN_SHARD_TRANSLOG_BUFFER_SIZE_SETTING, "40kb").build());
|
|
|
-
|
|
|
- assertTwoActiveShards(controller, new ByteSizeValue(6, ByteSizeUnit.MB), new ByteSizeValue(40, ByteSizeUnit.KB));
|
|
|
- }
|
|
|
-
|
|
|
- public void testMaxShardBufferSizes() {
|
|
|
- MockController controller = new MockController(Settings.builder()
|
|
|
- .put(IndexingMemoryController.INDEX_BUFFER_SIZE_SETTING, "10mb")
|
|
|
- .put(IndexingMemoryController.MAX_SHARD_INDEX_BUFFER_SIZE_SETTING, "3mb")
|
|
|
- .put(IndexingMemoryController.MAX_SHARD_TRANSLOG_BUFFER_SIZE_SETTING, "10kb").build());
|
|
|
-
|
|
|
- assertTwoActiveShards(controller, new ByteSizeValue(3, ByteSizeUnit.MB), new ByteSizeValue(10, ByteSizeUnit.KB));
|
|
|
- }
|
|
|
-
|
|
|
- public void testRelativeBufferSizes() {
|
|
|
- MockController controller = new MockController(Settings.builder()
|
|
|
- .put(IndexingMemoryController.INDEX_BUFFER_SIZE_SETTING, "50%")
|
|
|
- .build());
|
|
|
-
|
|
|
- assertThat(controller.indexingBufferSize(), equalTo(new ByteSizeValue(50, ByteSizeUnit.MB)));
|
|
|
+ controller.simulateIndexing(shard1);
|
|
|
+ controller.assertBuffer(shard1, 4);
|
|
|
+ controller.simulateIndexing(shard1);
|
|
|
+ controller.simulateIndexing(shard1);
|
|
|
+ // shard1 crossed 5 mb and is now cleared:
|
|
|
+ controller.assertBuffer(shard1, 0);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
public void testMinBufferSizes() {
|
|
|
MockController controller = new MockController(Settings.builder()
|
|
|
.put(IndexingMemoryController.INDEX_BUFFER_SIZE_SETTING, "0.001%")
|
|
@@ -246,21 +239,142 @@ public class IndexingMemoryControllerTests extends ESSingleNodeTestCase {
|
|
|
|
|
|
public void testMaxBufferSizes() {
|
|
|
MockController controller = new MockController(Settings.builder()
|
|
|
- .put(IndexingMemoryController.INDEX_BUFFER_SIZE_SETTING, "90%")
|
|
|
- .put(IndexingMemoryController.MAX_INDEX_BUFFER_SIZE_SETTING, "6mb").build());
|
|
|
+ .put(IndexingMemoryController.INDEX_BUFFER_SIZE_SETTING, "90%")
|
|
|
+ .put(IndexingMemoryController.MAX_INDEX_BUFFER_SIZE_SETTING, "6mb").build());
|
|
|
|
|
|
assertThat(controller.indexingBufferSize(), equalTo(new ByteSizeValue(6, ByteSizeUnit.MB)));
|
|
|
}
|
|
|
|
|
|
- protected void assertTwoActiveShards(MockController controller, ByteSizeValue indexBufferSize, ByteSizeValue translogBufferSize) {
|
|
|
- createIndex("test", Settings.builder().put(SETTING_NUMBER_OF_SHARDS, 2).put(SETTING_NUMBER_OF_REPLICAS, 0).build());
|
|
|
+ public void testThrottling() throws Exception {
|
|
|
+ createIndex("test", Settings.builder().put(SETTING_NUMBER_OF_SHARDS, 3).put(SETTING_NUMBER_OF_REPLICAS, 0).build());
|
|
|
IndicesService indicesService = getInstanceFromNode(IndicesService.class);
|
|
|
IndexService test = indicesService.indexService("test");
|
|
|
+
|
|
|
+ MockController controller = new MockController(Settings.builder()
|
|
|
+ .put(IndexingMemoryController.INDEX_BUFFER_SIZE_SETTING, "4mb").build());
|
|
|
IndexShard shard0 = test.getShard(0);
|
|
|
- controller.simulateIndexing(shard0);
|
|
|
IndexShard shard1 = test.getShard(1);
|
|
|
+ IndexShard shard2 = test.getShard(2);
|
|
|
+ controller.simulateIndexing(shard0);
|
|
|
+ controller.simulateIndexing(shard0);
|
|
|
+ controller.simulateIndexing(shard0);
|
|
|
+ controller.assertBuffer(shard0, 3);
|
|
|
+ controller.simulateIndexing(shard1);
|
|
|
+ controller.simulateIndexing(shard1);
|
|
|
+
|
|
|
+ // We are now using 5 MB, so we should be writing shard0 since it's using the most heap:
|
|
|
+ controller.assertWriting(shard0, 3);
|
|
|
+ controller.assertWriting(shard1, 0);
|
|
|
+ controller.assertBuffer(shard0, 0);
|
|
|
+ controller.assertBuffer(shard1, 2);
|
|
|
+
|
|
|
+ controller.simulateIndexing(shard0);
|
|
|
+ controller.simulateIndexing(shard1);
|
|
|
controller.simulateIndexing(shard1);
|
|
|
- controller.assertBuffers(shard0, indexBufferSize);
|
|
|
- controller.assertBuffers(shard1, indexBufferSize);
|
|
|
+
|
|
|
+ // Now we are still writing 3 MB (shard0), and using 5 MB index buffers, so we should now 1) be writing shard1, and 2) be throttling shard1:
|
|
|
+ controller.assertWriting(shard0, 3);
|
|
|
+ controller.assertWriting(shard1, 4);
|
|
|
+ controller.assertBuffer(shard0, 1);
|
|
|
+ controller.assertBuffer(shard1, 0);
|
|
|
+
|
|
|
+ controller.assertNotThrottled(shard0);
|
|
|
+ controller.assertThrottled(shard1);
|
|
|
+
|
|
|
+ System.out.println("TEST: now index more");
|
|
|
+
|
|
|
+ // More indexing to shard0
|
|
|
+ controller.simulateIndexing(shard0);
|
|
|
+ controller.simulateIndexing(shard0);
|
|
|
+ controller.simulateIndexing(shard0);
|
|
|
+ controller.simulateIndexing(shard0);
|
|
|
+
|
|
|
+ // Now we are using 5 MB again, so shard0 should also be writing and now also be throttled:
|
|
|
+ controller.assertWriting(shard0, 8);
|
|
|
+ controller.assertWriting(shard1, 4);
|
|
|
+ controller.assertBuffer(shard0, 0);
|
|
|
+ controller.assertBuffer(shard1, 0);
|
|
|
+
|
|
|
+ controller.assertThrottled(shard0);
|
|
|
+ controller.assertThrottled(shard1);
|
|
|
+
|
|
|
+ // Both shards finally finish writing, and throttling should stop:
|
|
|
+ controller.doneWriting(shard0);
|
|
|
+ controller.doneWriting(shard1);
|
|
|
+ controller.forceCheck();
|
|
|
+ controller.assertNotThrottled(shard0);
|
|
|
+ controller.assertNotThrottled(shard1);
|
|
|
+ }
|
|
|
+
|
|
|
+ // #10312
|
|
|
+ public void testDeletesAloneCanTriggerRefresh() throws Exception {
|
|
|
+ createIndex("index",
|
|
|
+ Settings.builder().put(SETTING_NUMBER_OF_SHARDS, 1)
|
|
|
+ .put(SETTING_NUMBER_OF_REPLICAS, 0)
|
|
|
+ .put("index.refresh_interval", -1)
|
|
|
+ .build());
|
|
|
+ ensureGreen();
|
|
|
+
|
|
|
+ IndicesService indicesService = getInstanceFromNode(IndicesService.class);
|
|
|
+ IndexService indexService = indicesService.indexService("index");
|
|
|
+ IndexShard shard = indexService.getShardOrNull(0);
|
|
|
+ assertNotNull(shard);
|
|
|
+
|
|
|
+ for (int i = 0; i < 100; i++) {
|
|
|
+ String id = Integer.toString(i);
|
|
|
+ client().prepareIndex("index", "type", id).setSource("field", "value").get();
|
|
|
+ }
|
|
|
+
|
|
|
+ // Force merge so we know all merges are done before we start deleting:
|
|
|
+ ForceMergeResponse r = client().admin().indices().prepareForceMerge().setMaxNumSegments(1).execute().actionGet();
|
|
|
+ assertNoFailures(r);
|
|
|
+
|
|
|
+ // Make a shell of an IMC to check up on indexing buffer usage:
|
|
|
+ Settings settings = Settings.builder().put(IndexingMemoryController.INDEX_BUFFER_SIZE_SETTING, "1kb").build();
|
|
|
+
|
|
|
+ // TODO: would be cleaner if I could pass this 1kb setting to the single node this test created....
|
|
|
+ IndexingMemoryController imc = new IndexingMemoryController(settings, null, null) {
|
|
|
+ @Override
|
|
|
+ protected List<IndexShard> availableShards() {
|
|
|
+ return Collections.singletonList(shard);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected long getIndexBufferRAMBytesUsed(IndexShard shard) {
|
|
|
+ return shard.getIndexBufferRAMBytesUsed();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void writeIndexingBufferAsync(IndexShard shard) {
|
|
|
+ // just do it sync'd for this test
|
|
|
+ shard.writeIndexingBuffer();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected ScheduledFuture<?> scheduleTask(ThreadPool threadPool) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ for (int i = 0; i < 100; i++) {
|
|
|
+ String id = Integer.toString(i);
|
|
|
+ client().prepareDelete("index", "type", id).get();
|
|
|
+ }
|
|
|
+
|
|
|
+ final long indexingBufferBytes1 = shard.getIndexBufferRAMBytesUsed();
|
|
|
+
|
|
|
+ imc.forceCheck();
|
|
|
+
|
|
|
+ // We must assertBusy because the writeIndexingBufferAsync is done in background (REFRESH) thread pool:
|
|
|
+ assertBusy(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ try (Engine.Searcher s2 = shard.acquireSearcher("index")) {
|
|
|
+ // 100 buffered deletes will easily exceed our 1 KB indexing buffer so it should trigger a write:
|
|
|
+ final long indexingBufferBytes2 = shard.getIndexBufferRAMBytesUsed();
|
|
|
+ assertTrue(indexingBufferBytes2 < indexingBufferBytes1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
}
|