Search in sources :

Example 1 with SnapshotInProgressException

use of org.elasticsearch.snapshots.SnapshotInProgressException in project crate by crate.

the class TransportCloseTable method addCloseBlocks.

/**
 * Step 1 - Start closing indices by adding a write block
 *
 * This step builds the list of indices to close (the ones explicitly requested that are not in CLOSE state) and adds a unique cluster
 * block (or reuses an existing one) to every index to close in the cluster state. After the cluster state is published, the shards
 * should start to reject writing operations and we can proceed with step 2.
 */
private static ClusterState addCloseBlocks(ClusterState currentState, Index[] indices, Map<Index, ClusterBlock> blockedIndices) {
    Metadata.Builder metadata = Metadata.builder(currentState.metadata());
    ClusterBlocks.Builder blocks = ClusterBlocks.builder().blocks(currentState.blocks());
    Set<Index> indicesToClose = new HashSet<>();
    for (Index index : indices) {
        final IndexMetadata indexMetadata = metadata.getSafe(index);
        if (indexMetadata.getState() != IndexMetadata.State.CLOSE) {
            indicesToClose.add(index);
        } else {
            LOGGER.debug("index {} is already closed, ignoring", index);
            assert currentState.blocks().hasIndexBlock(index.getName(), IndexMetadata.INDEX_CLOSED_BLOCK);
        }
    }
    if (indicesToClose.isEmpty()) {
        return currentState;
    }
    Set<Index> restoringIndices = RestoreService.restoringIndices(currentState, indicesToClose);
    if (restoringIndices.isEmpty() == false) {
        throw new IllegalArgumentException("Cannot close indices that are being restored: " + restoringIndices);
    }
    Set<Index> snapshottingIndices = SnapshotsService.snapshottingIndices(currentState, indicesToClose);
    if (snapshottingIndices.isEmpty() == false) {
        throw new SnapshotInProgressException("Cannot close indices that are being snapshotted: " + snapshottingIndices + ". Try again after snapshot finishes or cancel the currently running snapshot.");
    }
    for (var index : indicesToClose) {
        ClusterBlock indexBlock = null;
        final Set<ClusterBlock> clusterBlocks = currentState.blocks().indices().get(index.getName());
        if (clusterBlocks != null) {
            for (ClusterBlock clusterBlock : clusterBlocks) {
                if (clusterBlock.id() == INDEX_CLOSED_BLOCK_ID) {
                    // Reuse the existing index closed block
                    indexBlock = clusterBlock;
                    break;
                }
            }
        }
        if (indexBlock == null) {
            indexBlock = new ClusterBlock(INDEX_CLOSED_BLOCK_ID, UUIDs.randomBase64UUID(), "Table or partition preparing to close. Reopen the table to allow " + "writes again or retry closing the table to fully close it.", false, false, false, RestStatus.FORBIDDEN, EnumSet.of(ClusterBlockLevel.WRITE));
        }
        assert Strings.hasLength(indexBlock.uuid()) : "Closing block should have a UUID";
        blocks.addIndexBlock(index.getName(), indexBlock);
        blockedIndices.put(index, indexBlock);
    }
    return ClusterState.builder(currentState).blocks(blocks).metadata(metadata).routingTable(currentState.routingTable()).build();
}
Also used : ClusterBlocks(org.elasticsearch.cluster.block.ClusterBlocks) IndexMetadata(org.elasticsearch.cluster.metadata.IndexMetadata) Metadata(org.elasticsearch.cluster.metadata.Metadata) IndexTemplateMetadata(org.elasticsearch.cluster.metadata.IndexTemplateMetadata) Index(org.elasticsearch.index.Index) ClusterBlock(org.elasticsearch.cluster.block.ClusterBlock) SnapshotInProgressException(org.elasticsearch.snapshots.SnapshotInProgressException) IndexMetadata(org.elasticsearch.cluster.metadata.IndexMetadata) HashSet(java.util.HashSet)

Example 2 with SnapshotInProgressException

use of org.elasticsearch.snapshots.SnapshotInProgressException in project crate by crate.

the class CloseTableClusterStateTaskExecutor method execute.

@Override
protected ClusterState execute(ClusterState currentState, OpenCloseTableOrPartitionRequest request) throws Exception {
    Context context = prepare(currentState, request);
    Set<Index> indicesToClose = context.indicesMetadata().stream().map(IndexMetadata::getIndex).collect(Collectors.toSet());
    IndexTemplateMetadata templateMetadata = context.templateMetadata();
    if (indicesToClose.isEmpty() && templateMetadata == null) {
        return currentState;
    }
    // Check if index closing conflicts with any running restores
    Set<Index> restoringIndices = RestoreService.restoringIndices(currentState, indicesToClose);
    if (restoringIndices.isEmpty() == false) {
        throw new IllegalArgumentException("Cannot close indices that are being restored: " + restoringIndices);
    }
    // Check if index closing conflicts with any running snapshots
    Set<Index> snapshottingIndices = SnapshotsService.snapshottingIndices(currentState, indicesToClose);
    if (snapshottingIndices.isEmpty() == false) {
        throw new SnapshotInProgressException("Cannot close indices that are being snapshotted: " + snapshottingIndices + ". Try again after snapshot finishes or cancel the currently running snapshot.");
    }
    Metadata.Builder mdBuilder = Metadata.builder(currentState.metadata());
    ClusterBlocks.Builder blocksBuilder = ClusterBlocks.builder().blocks(currentState.blocks());
    for (IndexMetadata openIndexMetadata : context.indicesMetadata()) {
        final String indexName = openIndexMetadata.getIndex().getName();
        mdBuilder.put(IndexMetadata.builder(openIndexMetadata).state(IndexMetadata.State.CLOSE));
        blocksBuilder.addIndexBlock(indexName, INDEX_CLOSED_BLOCK);
    }
    // mark closed at possible partitioned table template
    if (templateMetadata != null) {
        mdBuilder.put(updateOpenCloseOnPartitionTemplate(templateMetadata, false));
    }
    // The Metadata will always be overridden (and not merged!) when applying it on a cluster state builder.
    // So we must re-build the state with the latest modifications before we pass this state to possible modifiers.
    // Otherwise they would operate on the old Metadata and would just ignore any modifications.
    ClusterState updatedState = ClusterState.builder(currentState).metadata(mdBuilder).blocks(blocksBuilder).build();
    // call possible registered modifiers
    if (context.partitionName() != null) {
        updatedState = ddlClusterStateService.onCloseTablePartition(updatedState, context.partitionName());
    } else {
        updatedState = ddlClusterStateService.onCloseTable(updatedState, request.tableIdent());
    }
    RoutingTable.Builder rtBuilder = RoutingTable.builder(currentState.routingTable());
    for (Index index : indicesToClose) {
        rtBuilder.remove(index.getName());
    }
    // no explicit wait for other nodes needed as we use AckedClusterStateUpdateTask
    return allocationService.reroute(ClusterState.builder(updatedState).routingTable(rtBuilder.build()).build(), "indices closed " + indicesToClose);
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState) ClusterBlocks(org.elasticsearch.cluster.block.ClusterBlocks) IndexTemplateMetadata(org.elasticsearch.cluster.metadata.IndexTemplateMetadata) IndexMetadata(org.elasticsearch.cluster.metadata.IndexMetadata) IndexTemplateMetadata(org.elasticsearch.cluster.metadata.IndexTemplateMetadata) Metadata(org.elasticsearch.cluster.metadata.Metadata) Index(org.elasticsearch.index.Index) RoutingTable(org.elasticsearch.cluster.routing.RoutingTable) SnapshotInProgressException(org.elasticsearch.snapshots.SnapshotInProgressException) IndexMetadata(org.elasticsearch.cluster.metadata.IndexMetadata)

Example 3 with SnapshotInProgressException

use of org.elasticsearch.snapshots.SnapshotInProgressException in project crate by crate.

the class MetadataDeleteIndexService method deleteIndices.

/**
 * Delete some indices from the cluster state.
 */
public ClusterState deleteIndices(ClusterState currentState, Set<Index> indices) {
    final Metadata meta = currentState.metadata();
    final Set<Index> indicesToDelete = indices.stream().map(i -> meta.getIndexSafe(i).getIndex()).collect(toSet());
    // Check if index deletion conflicts with any running snapshots
    Set<Index> snapshottingIndices = SnapshotsService.snapshottingIndices(currentState, indicesToDelete);
    if (snapshottingIndices.isEmpty() == false) {
        throw new SnapshotInProgressException("Cannot delete indices that are being snapshotted: " + snapshottingIndices + ". Try again after snapshot finishes or cancel the currently running snapshot.");
    }
    RoutingTable.Builder routingTableBuilder = RoutingTable.builder(currentState.routingTable());
    Metadata.Builder metadataBuilder = Metadata.builder(meta);
    ClusterBlocks.Builder clusterBlocksBuilder = ClusterBlocks.builder().blocks(currentState.blocks());
    final IndexGraveyard.Builder graveyardBuilder = IndexGraveyard.builder(metadataBuilder.indexGraveyard());
    final int previousGraveyardSize = graveyardBuilder.tombstones().size();
    for (final Index index : indices) {
        String indexName = index.getName();
        LOGGER.info("{} deleting index", index);
        routingTableBuilder.remove(indexName);
        clusterBlocksBuilder.removeIndexBlocks(indexName);
        metadataBuilder.remove(indexName);
    }
    // add tombstones to the cluster state for each deleted index
    final IndexGraveyard currentGraveyard = graveyardBuilder.addTombstones(indices).build(settings);
    // the new graveyard set on the metadata
    metadataBuilder.indexGraveyard(currentGraveyard);
    LOGGER.trace("{} tombstones purged from the cluster state. Previous tombstone size: {}. Current tombstone size: {}.", graveyardBuilder.getNumPurged(), previousGraveyardSize, currentGraveyard.getTombstones().size());
    Metadata newMetadata = metadataBuilder.build();
    ClusterBlocks blocks = clusterBlocksBuilder.build();
    // update snapshot restore entries
    ImmutableOpenMap<String, ClusterState.Custom> customs = currentState.getCustoms();
    final RestoreInProgress restoreInProgress = currentState.custom(RestoreInProgress.TYPE);
    if (restoreInProgress != null) {
        RestoreInProgress updatedRestoreInProgress = RestoreService.updateRestoreStateWithDeletedIndices(restoreInProgress, indices);
        if (updatedRestoreInProgress != restoreInProgress) {
            ImmutableOpenMap.Builder<String, ClusterState.Custom> builder = ImmutableOpenMap.builder(customs);
            builder.put(RestoreInProgress.TYPE, updatedRestoreInProgress);
            customs = builder.build();
        }
    }
    return allocationService.reroute(ClusterState.builder(currentState).routingTable(routingTableBuilder.build()).metadata(newMetadata).blocks(blocks).customs(customs).build(), "deleted indices [" + indices + "]");
}
Also used : Arrays(java.util.Arrays) AckedClusterStateUpdateTask(org.elasticsearch.cluster.AckedClusterStateUpdateTask) Priority(org.elasticsearch.common.Priority) SnapshotsService(org.elasticsearch.snapshots.SnapshotsService) ImmutableOpenMap(org.elasticsearch.common.collect.ImmutableOpenMap) ClusterService(org.elasticsearch.cluster.service.ClusterService) AllocationService(org.elasticsearch.cluster.routing.allocation.AllocationService) Set(java.util.Set) ClusterBlocks(org.elasticsearch.cluster.block.ClusterBlocks) Index(org.elasticsearch.index.Index) RestoreService(org.elasticsearch.snapshots.RestoreService) Inject(org.elasticsearch.common.inject.Inject) DeleteIndexClusterStateUpdateRequest(org.elasticsearch.action.admin.indices.delete.DeleteIndexClusterStateUpdateRequest) ClusterState(org.elasticsearch.cluster.ClusterState) Logger(org.apache.logging.log4j.Logger) Settings(org.elasticsearch.common.settings.Settings) RestoreInProgress(org.elasticsearch.cluster.RestoreInProgress) RoutingTable(org.elasticsearch.cluster.routing.RoutingTable) ClusterStateUpdateResponse(org.elasticsearch.cluster.ack.ClusterStateUpdateResponse) LogManager(org.apache.logging.log4j.LogManager) ActionListener(org.elasticsearch.action.ActionListener) Collectors.toSet(java.util.stream.Collectors.toSet) SnapshotInProgressException(org.elasticsearch.snapshots.SnapshotInProgressException) ClusterBlocks(org.elasticsearch.cluster.block.ClusterBlocks) Index(org.elasticsearch.index.Index) ImmutableOpenMap(org.elasticsearch.common.collect.ImmutableOpenMap) RestoreInProgress(org.elasticsearch.cluster.RestoreInProgress) RoutingTable(org.elasticsearch.cluster.routing.RoutingTable) SnapshotInProgressException(org.elasticsearch.snapshots.SnapshotInProgressException)

Aggregations

ClusterBlocks (org.elasticsearch.cluster.block.ClusterBlocks)3 Index (org.elasticsearch.index.Index)3 SnapshotInProgressException (org.elasticsearch.snapshots.SnapshotInProgressException)3 ClusterState (org.elasticsearch.cluster.ClusterState)2 IndexMetadata (org.elasticsearch.cluster.metadata.IndexMetadata)2 IndexTemplateMetadata (org.elasticsearch.cluster.metadata.IndexTemplateMetadata)2 Metadata (org.elasticsearch.cluster.metadata.Metadata)2 RoutingTable (org.elasticsearch.cluster.routing.RoutingTable)2 Arrays (java.util.Arrays)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1 Collectors.toSet (java.util.stream.Collectors.toSet)1 LogManager (org.apache.logging.log4j.LogManager)1 Logger (org.apache.logging.log4j.Logger)1 ActionListener (org.elasticsearch.action.ActionListener)1 DeleteIndexClusterStateUpdateRequest (org.elasticsearch.action.admin.indices.delete.DeleteIndexClusterStateUpdateRequest)1 AckedClusterStateUpdateTask (org.elasticsearch.cluster.AckedClusterStateUpdateTask)1 RestoreInProgress (org.elasticsearch.cluster.RestoreInProgress)1 ClusterStateUpdateResponse (org.elasticsearch.cluster.ack.ClusterStateUpdateResponse)1 ClusterBlock (org.elasticsearch.cluster.block.ClusterBlock)1