[CORE] Free pending search contexts if index is closed

Today we hold on to search context reference if they are not cleaned
up for a while until a reaper thread trashes them if they timed out.
This commit removes all pending contexts once the index is closed to release
resources and filehandles immediatly once the index is closed.
This commit is contained in:
Simon Willnauer 2014-11-19 15:58:26 +01:00
parent fb81a3203b
commit edc48f39c5
2 changed files with 23 additions and 4 deletions

View File

@ -51,10 +51,7 @@ import org.elasticsearch.index.refresh.RefreshStats;
import org.elasticsearch.index.search.stats.SearchStats; import org.elasticsearch.index.search.stats.SearchStats;
import org.elasticsearch.index.search.stats.ShardSearchService; import org.elasticsearch.index.search.stats.ShardSearchService;
import org.elasticsearch.index.service.IndexService; import org.elasticsearch.index.service.IndexService;
import org.elasticsearch.index.shard.DocsStats; import org.elasticsearch.index.shard.*;
import org.elasticsearch.index.shard.IllegalIndexShardStateException;
import org.elasticsearch.index.shard.IndexShardComponent;
import org.elasticsearch.index.shard.IndexShardState;
import org.elasticsearch.index.store.StoreStats; import org.elasticsearch.index.store.StoreStats;
import org.elasticsearch.index.suggest.stats.ShardSuggestService; import org.elasticsearch.index.suggest.stats.ShardSuggestService;
import org.elasticsearch.index.suggest.stats.SuggestStats; import org.elasticsearch.index.suggest.stats.SuggestStats;
@ -183,6 +180,8 @@ public interface IndexShard extends IndexShardComponent {
void readAllowed(Mode mode) throws IllegalIndexShardStateException; void readAllowed(Mode mode) throws IllegalIndexShardStateException;
ShardId shardId();
public enum Mode { public enum Mode {
READ, READ,
WRITE WRITE

View File

@ -51,6 +51,7 @@ import org.elasticsearch.common.util.concurrent.FutureUtils;
import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.engine.Engine; import org.elasticsearch.index.engine.Engine;
import org.elasticsearch.index.fielddata.FieldDataType; import org.elasticsearch.index.fielddata.FieldDataType;
import org.elasticsearch.index.fielddata.IndexFieldData; import org.elasticsearch.index.fielddata.IndexFieldData;
@ -145,6 +146,15 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
this.threadPool = threadPool; this.threadPool = threadPool;
this.clusterService = clusterService; this.clusterService = clusterService;
this.indicesService = indicesService; this.indicesService = indicesService;
indicesService.indicesLifecycle().addListener(new IndicesLifecycle.Listener() {
@Override
public void afterIndexClosed(Index index) {
// once an index is closed we can just clean up all the pending search context information
// to release memory and let references to the filesystem go etc.
freeAllContextForIndex(index);
}
});
this.indicesWarmer = indicesWarmer; this.indicesWarmer = indicesWarmer;
this.scriptService = scriptService; this.scriptService = scriptService;
this.pageCacheRecycler = pageCacheRecycler; this.pageCacheRecycler = pageCacheRecycler;
@ -563,6 +573,16 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
return context; return context;
} }
private void freeAllContextForIndex(Index index) {
assert index != null;
for (SearchContext ctx : activeContexts.values()) {
if (index.equals(ctx.indexShard().shardId().index())) {
freeContext(ctx.id());
}
}
}
public boolean freeContext(long id) { public boolean freeContext(long id) {
final SearchContext context = activeContexts.remove(id); final SearchContext context = activeContexts.remove(id);
if (context != null) { if (context != null) {