diff --git a/src/main/java/org/elasticsearch/indices/IndicesLifecycle.java b/src/main/java/org/elasticsearch/indices/IndicesLifecycle.java index 7f7a990915c..5d9bf0ce9b2 100644 --- a/src/main/java/org/elasticsearch/indices/IndicesLifecycle.java +++ b/src/main/java/org/elasticsearch/indices/IndicesLifecycle.java @@ -146,6 +146,28 @@ public interface IndicesLifecycle { public void indexShardStateChanged(IndexShard indexShard, @Nullable IndexShardState previousState, IndexShardState currentState, @Nullable String reason) { } + + /** + * Called after the index has been deleted. + * This listener method is invoked after {@link #afterIndexClosed(org.elasticsearch.index.Index)} + * when an index is deleted + * + * @param index The index + */ + public void afterIndexDeleted(Index index) { + + } + + /** + * Called before the index gets deleted. + * This listener method is invoked after + * {@link #beforeIndexClosed(org.elasticsearch.index.service.IndexService)} when an index is deleted + * + * @param indexService The index service + */ + public void beforeIndexDeleted(IndexService indexService) { + + } } } diff --git a/src/main/java/org/elasticsearch/indices/IndicesService.java b/src/main/java/org/elasticsearch/indices/IndicesService.java index 8e633668563..d64b1481911 100644 --- a/src/main/java/org/elasticsearch/indices/IndicesService.java +++ b/src/main/java/org/elasticsearch/indices/IndicesService.java @@ -78,9 +78,24 @@ public interface IndicesService extends Iterable, LifecycleCompone IndexService createIndex(String index, Settings settings, String localNodeId) throws ElasticsearchException; + /** + * Removes the given index from this service and releases all associated resources. Persistent parts of the index + * like the shards files, state and transaction logs are kept around in the case of a disaster recovery. + * @param index the index to remove + * @param reason the high level reason causing this removal + */ void removeIndex(String index, String reason) throws ElasticsearchException; - void removeIndex(String index, String reason, @Nullable IndexCloseListener listener) throws ElasticsearchException; + /** + * Deletes the given index. Persistent parts of the index + * like the shards files, state and transaction logs are removed once all resources are released. + * + * Equivalent to {@link #removeIndex(String, String)} but fires + * different lifecycle events to ensure pending resources of this index are immediately removed. + * @param index the index to delete + * @param reason the high level reason causing this delete + */ + void deleteIndex(String index, String reason) throws ElasticsearchException; /** * A listener interface that can be used to get notification once a shard or all shards diff --git a/src/main/java/org/elasticsearch/indices/InternalIndicesLifecycle.java b/src/main/java/org/elasticsearch/indices/InternalIndicesLifecycle.java index 1711810a67a..7b255542718 100644 --- a/src/main/java/org/elasticsearch/indices/InternalIndicesLifecycle.java +++ b/src/main/java/org/elasticsearch/indices/InternalIndicesLifecycle.java @@ -132,6 +132,26 @@ public class InternalIndicesLifecycle extends AbstractComponent implements Indic } } + public void beforeIndexDeleted(IndexService indexService) { + for (Listener listener : listeners) { + try { + listener.beforeIndexDeleted(indexService); + } catch (Throwable t) { + logger.warn("[{}] failed to invoke before index deleted callback", t, indexService.index().name()); + } + } + } + + public void afterIndexDeleted(Index index) { + for (Listener listener : listeners) { + try { + listener.afterIndexDeleted(index); + } catch (Throwable t) { + logger.warn("[{}] failed to invoke after index deleted callback", t, index.name()); + } + } + } + public void afterIndexClosed(Index index) { for (Listener listener : listeners) { try { diff --git a/src/main/java/org/elasticsearch/indices/InternalIndicesService.java b/src/main/java/org/elasticsearch/indices/InternalIndicesService.java index 47a05f4c036..13421bef179 100644 --- a/src/main/java/org/elasticsearch/indices/InternalIndicesService.java +++ b/src/main/java/org/elasticsearch/indices/InternalIndicesService.java @@ -32,6 +32,7 @@ import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.inject.*; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.EsExecutors; +import org.elasticsearch.env.NodeEnvironment; import org.elasticsearch.gateway.Gateway; import org.elasticsearch.index.*; import org.elasticsearch.index.aliases.IndexAliasesServiceModule; @@ -71,6 +72,7 @@ import org.elasticsearch.indices.store.IndicesStore; import org.elasticsearch.plugins.IndexPluginsModule; import org.elasticsearch.plugins.PluginsService; +import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -100,6 +102,8 @@ public class InternalIndicesService extends AbstractLifecycleComponent indicesInjectors = new HashMap<>(); private volatile ImmutableMap indices = ImmutableMap.of(); @@ -107,7 +111,7 @@ public class InternalIndicesService extends AbstractLifecycleComponent failures) { latch.countDown(); @@ -328,11 +333,44 @@ public class InternalIndicesService extends AbstractLifecycleComponent failures) { + try { + nodeEnv.deleteIndexDirectorySafe(index); + logger.debug("deleted index [{}] from filesystem - failures {}", index, failures); + } catch (Exception e) { + for (Throwable t : failures) { + e.addSuppressed(t); + } + logger.debug("failed to deleted index [{}] from filesystem", e, index); + // ignore - still some shards locked here + } + } + + @Override + public void onShardClosed(ShardId shardId) { + try { + nodeEnv.deleteShardDirectorySafe(shardId); + logger.debug("deleted shard [{}] from filesystem", shardId); + } catch (IOException e) { + logger.warn("Can't delete shard {} ", e, shardId); + } + } + + @Override + public void onShardCloseFailed(ShardId shardId, Throwable t) { + } + }); + } + + private void removeIndex(String index, String reason, boolean delete, @Nullable IndexCloseListener listener) throws ElasticsearchException { final IndexService indexService; final Injector indexInjector; synchronized (this) { @@ -346,7 +384,11 @@ public class InternalIndicesService extends AbstractLifecycleComponent closeable : pluginsService.indexServices()) { indexInjector.getInstance(closeable).close(); @@ -378,6 +420,9 @@ public class InternalIndicesService extends AbstractLifecycleComponent failures) { - try { - nodeEnvironment.deleteIndexDirectorySafe(index); - logger.debug("deleted index [{}] from filesystem", index); - } catch (Exception e) { - logger.debug("failed to deleted index [{}] from filesystem", e, index); - // ignore - still some shards locked here - } - } - - @Override - public void onShardClosed(ShardId shardId) { - try { - nodeEnvironment.deleteShardDirectorySafe(shardId); - logger.debug("deleted shard [{}] from filesystem", shardId); - } catch (IOException e) { - logger.warn("Can't delete shard {} ", e, shardId); - } - } - - @Override - public void onShardCloseFailed(ShardId shardId, Throwable t) { - } - }); + deleteIndex(index, "index no longer part of the metadata"); } } } @@ -869,15 +843,16 @@ public class IndicesClusterStateService extends AbstractLifecycleComponent tuple : seenMappings.keySet()) { if (tuple.v1().equals(index)) { @@ -886,6 +861,16 @@ public class IndicesClusterStateService extends AbstractLifecycleComponent