use of org.elasticsearch.cluster.block.ClusterBlocks 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.cluster.block.ClusterBlocks in project crate by crate.
the class ClusterState method readFrom.
public static ClusterState readFrom(StreamInput in, DiscoveryNode localNode) throws IOException {
ClusterName clusterName = new ClusterName(in);
Builder builder = new Builder(clusterName);
builder.version = in.readLong();
builder.uuid = in.readString();
builder.metadata = Metadata.readFrom(in);
builder.routingTable = RoutingTable.readFrom(in);
builder.nodes = DiscoveryNodes.readFrom(in, localNode);
builder.blocks = new ClusterBlocks(in);
int customSize = in.readVInt();
for (int i = 0; i < customSize; i++) {
Custom customIndexMetadata = in.readNamedWriteable(Custom.class);
builder.putCustom(customIndexMetadata.getWriteableName(), customIndexMetadata);
}
return builder.build();
}
use of org.elasticsearch.cluster.block.ClusterBlocks in project crate by crate.
the class Coordinator method clusterStateWithNoMasterBlock.
private ClusterState clusterStateWithNoMasterBlock(ClusterState clusterState) {
if (clusterState.nodes().getMasterNodeId() != null) {
// remove block if it already exists before adding new one
assert clusterState.blocks().hasGlobalBlockWithId(NO_MASTER_BLOCK_ID) == false : "NO_MASTER_BLOCK should only be added by Coordinator";
final ClusterBlocks clusterBlocks = ClusterBlocks.builder().blocks(clusterState.blocks()).addGlobalBlock(noMasterBlockService.getNoMasterBlock()).build();
final DiscoveryNodes discoveryNodes = new DiscoveryNodes.Builder(clusterState.nodes()).masterNodeId(null).build();
return ClusterState.builder(clusterState).blocks(clusterBlocks).nodes(discoveryNodes).build();
} else {
return clusterState;
}
}
use of org.elasticsearch.cluster.block.ClusterBlocks in project elasticsearch by elastic.
the class ClusterState method readFrom.
public static ClusterState readFrom(StreamInput in, DiscoveryNode localNode) throws IOException {
ClusterName clusterName = new ClusterName(in);
Builder builder = new Builder(clusterName);
builder.version = in.readLong();
builder.uuid = in.readString();
builder.metaData = MetaData.readFrom(in);
builder.routingTable = RoutingTable.readFrom(in);
builder.nodes = DiscoveryNodes.readFrom(in, localNode);
builder.blocks = new ClusterBlocks(in);
int customSize = in.readVInt();
for (int i = 0; i < customSize; i++) {
Custom customIndexMetaData = in.readNamedWriteable(Custom.class);
builder.putCustom(customIndexMetaData.getWriteableName(), customIndexMetaData);
}
return builder.build();
}
use of org.elasticsearch.cluster.block.ClusterBlocks in project crate by crate.
the class TransportVerifyShardBeforeCloseAction method executeShardOperation.
private void executeShardOperation(final ShardRequest request, final IndexShard indexShard) throws IOException {
final ShardId shardId = indexShard.shardId();
if (indexShard.getActiveOperationsCount() != IndexShard.OPERATIONS_BLOCKED) {
throw new IllegalStateException("Index shard " + shardId + " is not blocking all operations during closing");
}
final ClusterBlocks clusterBlocks = clusterService.state().blocks();
if (clusterBlocks.hasIndexBlock(shardId.getIndexName(), request.clusterBlock()) == false) {
throw new IllegalStateException("Index shard " + shardId + " must be blocked by " + request.clusterBlock() + " before closing");
}
if (request.isPhase1()) {
// in order to advance the global checkpoint to the maximum sequence number, the (persisted) local checkpoint needs to be
// advanced first, which, when using async translog syncing, does not automatically hold at the time where we have acquired
// all operation permits. Instead, this requires and explicit sync, which communicates the updated (persisted) local checkpoint
// to the primary (we call this phase1), and phase2 can then use the fact that the global checkpoint has moved to the maximum
// sequence number to pass the verifyShardBeforeIndexClosing check and create a safe commit where the maximum sequence number
// is equal to the global checkpoint.
indexShard.sync();
} else {
indexShard.verifyShardBeforeIndexClosing();
indexShard.flush(new FlushRequest().force(true).waitIfOngoing(true));
logger.trace("{} shard is ready for closing", shardId);
}
}
Aggregations