use of org.elasticsearch.indices.cluster.IndicesClusterStateService.AllocatedIndices.IndexRemovalReason.NO_LONGER_ASSIGNED in project elasticsearch by elastic.
the class MetaDataMappingService method executeRefresh.
/**
* Batch method to apply all the queued refresh operations. The idea is to try and batch as much
* as possible so we won't create the same index all the time for example for the updates on the same mapping
* and generate a single cluster change event out of all of those.
*/
ClusterState executeRefresh(final ClusterState currentState, final List<RefreshTask> allTasks) throws Exception {
// break down to tasks per index, so we can optimize the on demand index service creation
// to only happen for the duration of a single index processing of its respective events
Map<String, List<RefreshTask>> tasksPerIndex = new HashMap<>();
for (RefreshTask task : allTasks) {
if (task.index == null) {
logger.debug("ignoring a mapping task of type [{}] with a null index.", task);
}
tasksPerIndex.computeIfAbsent(task.index, k -> new ArrayList<>()).add(task);
}
boolean dirty = false;
MetaData.Builder mdBuilder = MetaData.builder(currentState.metaData());
for (Map.Entry<String, List<RefreshTask>> entry : tasksPerIndex.entrySet()) {
IndexMetaData indexMetaData = mdBuilder.get(entry.getKey());
if (indexMetaData == null) {
// index got deleted on us, ignore...
logger.debug("[{}] ignoring tasks - index meta data doesn't exist", entry.getKey());
continue;
}
final Index index = indexMetaData.getIndex();
// the tasks lists to iterate over, filled with the list of mapping tasks, trying to keep
// the latest (based on order) update mapping one per node
List<RefreshTask> allIndexTasks = entry.getValue();
boolean hasTaskWithRightUUID = false;
for (RefreshTask task : allIndexTasks) {
if (indexMetaData.isSameUUID(task.indexUUID)) {
hasTaskWithRightUUID = true;
} else {
logger.debug("{} ignoring task [{}] - index meta data doesn't match task uuid", index, task);
}
}
if (hasTaskWithRightUUID == false) {
continue;
}
// construct the actual index if needed, and make sure the relevant mappings are there
boolean removeIndex = false;
IndexService indexService = indicesService.indexService(indexMetaData.getIndex());
if (indexService == null) {
// we need to create the index here, and add the current mapping to it, so we can merge
indexService = indicesService.createIndex(indexMetaData, Collections.emptyList(), shardId -> {
});
removeIndex = true;
indexService.mapperService().merge(indexMetaData, MergeReason.MAPPING_RECOVERY, true);
}
IndexMetaData.Builder builder = IndexMetaData.builder(indexMetaData);
try {
boolean indexDirty = refreshIndexMapping(indexService, builder);
if (indexDirty) {
mdBuilder.put(builder);
dirty = true;
}
} finally {
if (removeIndex) {
indicesService.removeIndex(index, NO_LONGER_ASSIGNED, "created for mapping processing");
}
}
}
if (!dirty) {
return currentState;
}
return ClusterState.builder(currentState).metaData(mdBuilder).build();
}
use of org.elasticsearch.indices.cluster.IndicesClusterStateService.AllocatedIndices.IndexRemovalReason.NO_LONGER_ASSIGNED in project crate by crate.
the class MetadataMappingService method executeRefresh.
/**
* Batch method to apply all the queued refresh operations. The idea is to try and batch as much
* as possible so we won't create the same index all the time for example for the updates on the same mapping
* and generate a single cluster change event out of all of those.
*/
ClusterState executeRefresh(final ClusterState currentState, final List<RefreshTask> allTasks) throws Exception {
// break down to tasks per index, so we can optimize the on demand index service creation
// to only happen for the duration of a single index processing of its respective events
Map<String, List<RefreshTask>> tasksPerIndex = new HashMap<>();
for (RefreshTask task : allTasks) {
if (task.index == null) {
LOGGER.debug("ignoring a mapping task of type [{}] with a null index.", task);
}
tasksPerIndex.computeIfAbsent(task.index, k -> new ArrayList<>()).add(task);
}
boolean dirty = false;
Metadata.Builder mdBuilder = Metadata.builder(currentState.metadata());
for (Map.Entry<String, List<RefreshTask>> entry : tasksPerIndex.entrySet()) {
IndexMetadata indexMetadata = mdBuilder.get(entry.getKey());
if (indexMetadata == null) {
// index got deleted on us, ignore...
LOGGER.debug("[{}] ignoring tasks - index meta data doesn't exist", entry.getKey());
continue;
}
final Index index = indexMetadata.getIndex();
// the tasks lists to iterate over, filled with the list of mapping tasks, trying to keep
// the latest (based on order) update mapping one per node
List<RefreshTask> allIndexTasks = entry.getValue();
boolean hasTaskWithRightUUID = false;
for (RefreshTask task : allIndexTasks) {
if (indexMetadata.isSameUUID(task.indexUUID)) {
hasTaskWithRightUUID = true;
} else {
LOGGER.debug("{} ignoring task [{}] - index meta data doesn't match task uuid", index, task);
}
}
if (hasTaskWithRightUUID == false) {
continue;
}
// construct the actual index if needed, and make sure the relevant mappings are there
boolean removeIndex = false;
IndexService indexService = indicesService.indexService(indexMetadata.getIndex());
if (indexService == null) {
// we need to create the index here, and add the current mapping to it, so we can merge
indexService = indicesService.createIndex(indexMetadata, Collections.emptyList(), false);
removeIndex = true;
indexService.mapperService().merge(indexMetadata, MergeReason.MAPPING_RECOVERY);
}
IndexMetadata.Builder builder = IndexMetadata.builder(indexMetadata);
try {
boolean indexDirty = refreshIndexMapping(indexService, builder);
if (indexDirty) {
mdBuilder.put(builder);
dirty = true;
}
} finally {
if (removeIndex) {
indicesService.removeIndex(index, NO_LONGER_ASSIGNED, "created for mapping processing");
}
}
}
if (!dirty) {
return currentState;
}
return ClusterState.builder(currentState).metadata(mdBuilder).build();
}
use of org.elasticsearch.indices.cluster.IndicesClusterStateService.AllocatedIndices.IndexRemovalReason.NO_LONGER_ASSIGNED in project elasticsearch by elastic.
the class MetaDataIndexAliasesService method innerExecute.
ClusterState innerExecute(ClusterState currentState, Iterable<AliasAction> actions) {
List<Index> indicesToClose = new ArrayList<>();
Map<String, IndexService> indices = new HashMap<>();
try {
boolean changed = false;
// Gather all the indexes that must be removed first so:
// 1. We don't cause error when attempting to replace an index with a alias of the same name.
// 2. We don't allow removal of aliases from indexes that we're just going to delete anyway. That'd be silly.
Set<Index> indicesToDelete = new HashSet<>();
for (AliasAction action : actions) {
if (action.removeIndex()) {
IndexMetaData index = currentState.metaData().getIndices().get(action.getIndex());
if (index == null) {
throw new IndexNotFoundException(action.getIndex());
}
indicesToDelete.add(index.getIndex());
changed = true;
}
}
// Remove the indexes if there are any to remove
if (changed) {
currentState = deleteIndexService.deleteIndices(currentState, indicesToDelete);
}
MetaData.Builder metadata = MetaData.builder(currentState.metaData());
// Run the remaining alias actions
for (AliasAction action : actions) {
if (action.removeIndex()) {
// Handled above
continue;
}
IndexMetaData index = metadata.get(action.getIndex());
if (index == null) {
throw new IndexNotFoundException(action.getIndex());
}
NewAliasValidator newAliasValidator = (alias, indexRouting, filter) -> {
/* It is important that we look up the index using the metadata builder we are modifying so we can remove an
* index and replace it with an alias. */
Function<String, IndexMetaData> indexLookup = name -> metadata.get(name);
aliasValidator.validateAlias(alias, action.getIndex(), indexRouting, indexLookup);
if (Strings.hasLength(filter)) {
IndexService indexService = indices.get(index.getIndex());
if (indexService == null) {
indexService = indicesService.indexService(index.getIndex());
if (indexService == null) {
// temporarily create the index and add mappings so we can parse the filter
try {
indexService = indicesService.createIndex(index, emptyList(), shardId -> {
});
indicesToClose.add(index.getIndex());
} catch (IOException e) {
throw new ElasticsearchException("Failed to create temporary index for parsing the alias", e);
}
indexService.mapperService().merge(index, MapperService.MergeReason.MAPPING_RECOVERY, false);
}
indices.put(action.getIndex(), indexService);
}
// the context is only used for validation so it's fine to pass fake values for the shard id and the current
// timestamp
aliasValidator.validateAliasFilter(alias, filter, indexService.newQueryShardContext(0, null, () -> 0L), xContentRegistry);
}
};
changed |= action.apply(newAliasValidator, metadata, index);
}
if (changed) {
ClusterState updatedState = ClusterState.builder(currentState).metaData(metadata).build();
// i.e. remove and add the same alias to the same index
if (!updatedState.metaData().equalsAliases(currentState.metaData())) {
return updatedState;
}
}
return currentState;
} finally {
for (Index index : indicesToClose) {
indicesService.removeIndex(index, NO_LONGER_ASSIGNED, "created for alias processing");
}
}
}
Aggregations