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();
}
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);
}
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 + "]");
}
Aggregations