Ensure shard is refreshed once it's inactive (#27559)

Once a shard goes inactive we want the shard to be refreshed if
the refresh interval is default since we might hold on to unnecessary
segments and in the inactive case we stopped indexing and can release
old segments.

Relates to #27500
This commit is contained in:
Simon Willnauer 2017-11-30 19:04:05 +01:00 committed by GitHub
parent c6b73239ae
commit b116221540
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 3 deletions

View File

@ -873,7 +873,7 @@ public class IndexShard extends AbstractIndexShardComponent implements IndicesCl
long numDeletedDocs = 0; long numDeletedDocs = 0;
long sizeInBytes = 0; long sizeInBytes = 0;
try (Engine.Searcher searcher = acquireSearcher("docStats", Engine.SearcherScope.INTERNAL)) { try (Engine.Searcher searcher = acquireSearcher("docStats", Engine.SearcherScope.INTERNAL)) {
// we don't wait for a pending refreshes here since it's a stats call instead we mark it as accesssed only which will cause // we don't wait for a pending refreshes here since it's a stats call instead we mark it as accessed only which will cause
// the next scheduled refresh to go through and refresh the stats as well // the next scheduled refresh to go through and refresh the stats as well
markSearcherAccessed(); markSearcherAccessed();
for (LeafReaderContext reader : searcher.reader().leaves()) { for (LeafReaderContext reader : searcher.reader().leaves()) {
@ -972,7 +972,7 @@ public class IndexShard extends AbstractIndexShardComponent implements IndicesCl
public CompletionStats completionStats(String... fields) { public CompletionStats completionStats(String... fields) {
CompletionStats completionStats = new CompletionStats(); CompletionStats completionStats = new CompletionStats();
try (Engine.Searcher currentSearcher = acquireSearcher("completion_stats")) { try (Engine.Searcher currentSearcher = acquireSearcher("completion_stats")) {
// we don't wait for a pending refreshes here since it's a stats call instead we mark it as accesssed only which will cause // we don't wait for a pending refreshes here since it's a stats call instead we mark it as accessed only which will cause
// the next scheduled refresh to go through and refresh the stats as well // the next scheduled refresh to go through and refresh the stats as well
markSearcherAccessed(); markSearcherAccessed();
completionStats.add(CompletionFieldStats.completionStats(currentSearcher.reader(), fields)); completionStats.add(CompletionFieldStats.completionStats(currentSearcher.reader(), fields));
@ -2457,7 +2457,9 @@ public class IndexShard extends AbstractIndexShardComponent implements IndicesCl
boolean listenerNeedsRefresh = refreshListeners.refreshNeeded(); boolean listenerNeedsRefresh = refreshListeners.refreshNeeded();
if (isReadAllowed() && (listenerNeedsRefresh || getEngine().refreshNeeded())) { if (isReadAllowed() && (listenerNeedsRefresh || getEngine().refreshNeeded())) {
if (listenerNeedsRefresh == false // if we have a listener that is waiting for a refresh we need to force it if (listenerNeedsRefresh == false // if we have a listener that is waiting for a refresh we need to force it
&& isSearchIdle() && indexSettings.isExplicitRefresh() == false) { && isSearchIdle()
&& indexSettings.isExplicitRefresh() == false
&& active.get()) { // it must be active otherwise we might not free up segment memory once the shard became inactive
// lets skip this refresh since we are search idle and // lets skip this refresh since we are search idle and
// don't necessarily need to refresh. the next searcher access will register a refreshListener and that will // don't necessarily need to refresh. the next searcher access will register a refreshListener and that will
// cause the next schedule to refresh. // cause the next schedule to refresh.

View File

@ -2685,6 +2685,15 @@ public class IndexShardTests extends IndexShardTestCase {
}); });
latch1.await(); latch1.await();
indexDoc(primary, "test", "2", "{\"foo\" : \"bar\"}");
assertFalse(primary.scheduledRefresh());
assertTrue(primary.isSearchIdle());
primary.checkIdle(0);
assertTrue(primary.scheduledRefresh()); // make sure we refresh once the shard is inactive
try (Engine.Searcher searcher = primary.acquireSearcher("test")) {
assertEquals(3, searcher.reader().numDocs());
}
closeShards(primary); closeShards(primary);
} }