Search in sources :

Example 6 with SnapshotDeletionsInProgress

use of org.elasticsearch.cluster.SnapshotDeletionsInProgress in project elasticsearch by elastic.

the class SnapshotsService method isRepositoryInUse.

/**
     * Checks if a repository is currently in use by one of the snapshots
     *
     * @param clusterState cluster state
     * @param repository   repository id
     * @return true if repository is currently in use by one of the running snapshots
     */
public static boolean isRepositoryInUse(ClusterState clusterState, String repository) {
    SnapshotsInProgress snapshots = clusterState.custom(SnapshotsInProgress.TYPE);
    if (snapshots != null) {
        for (SnapshotsInProgress.Entry snapshot : snapshots.entries()) {
            if (repository.equals(snapshot.snapshot().getRepository())) {
                return true;
            }
        }
    }
    SnapshotDeletionsInProgress deletionsInProgress = clusterState.custom(SnapshotDeletionsInProgress.TYPE);
    if (deletionsInProgress != null) {
        for (SnapshotDeletionsInProgress.Entry entry : deletionsInProgress.getEntries()) {
            if (entry.getSnapshot().getRepository().equals(repository)) {
                return true;
            }
        }
    }
    return false;
}
Also used : SnapshotsInProgress(org.elasticsearch.cluster.SnapshotsInProgress) SnapshotDeletionsInProgress(org.elasticsearch.cluster.SnapshotDeletionsInProgress)

Example 7 with SnapshotDeletionsInProgress

use of org.elasticsearch.cluster.SnapshotDeletionsInProgress in project elasticsearch by elastic.

the class SnapshotsService method finalizeSnapshotDeletionFromPreviousMaster.

/**
     * Finalizes a snapshot deletion in progress if the current node is the master but it
     * was not master in the previous cluster state and there is still a lingering snapshot
     * deletion in progress in the cluster state.  This means that the old master failed
     * before it could clean up an in-progress snapshot deletion.  We attempt to delete the
     * snapshot files and remove the deletion from the cluster state.  It is possible that the
     * old master was in a state of long GC and then it resumes and tries to delete the snapshot
     * that has already been deleted by the current master.  This is acceptable however, since
     * the old master's snapshot deletion will just respond with an error but in actuality, the
     * snapshot was deleted and a call to GET snapshots would reveal that the snapshot no longer exists.
     */
private void finalizeSnapshotDeletionFromPreviousMaster(ClusterChangedEvent event) {
    if (event.localNodeMaster() && event.previousState().nodes().isLocalNodeElectedMaster() == false) {
        SnapshotDeletionsInProgress deletionsInProgress = event.state().custom(SnapshotDeletionsInProgress.TYPE);
        if (deletionsInProgress != null && deletionsInProgress.hasDeletionsInProgress()) {
            assert deletionsInProgress.getEntries().size() == 1 : "only one in-progress deletion allowed per cluster";
            SnapshotDeletionsInProgress.Entry entry = deletionsInProgress.getEntries().get(0);
            deleteSnapshotFromRepository(entry.getSnapshot(), null, entry.getRepositoryStateId());
        }
    }
}
Also used : SnapshotDeletionsInProgress(org.elasticsearch.cluster.SnapshotDeletionsInProgress)

Example 8 with SnapshotDeletionsInProgress

use of org.elasticsearch.cluster.SnapshotDeletionsInProgress in project crate by crate.

the class SnapshotsService method createSnapshot.

/**
 * Initializes the snapshotting process.
 * <p>
 * This method is used by clients to start snapshot. It makes sure that there is no snapshots are currently running and
 * creates a snapshot record in cluster state metadata.
 *
 * @param request  snapshot request
 * @param listener snapshot creation listener
 */
public void createSnapshot(final CreateSnapshotRequest request, final ActionListener<Snapshot> listener) {
    final String repositoryName = request.repository();
    final String snapshotName = request.snapshot();
    validate(repositoryName, snapshotName);
    // new UUID for the snapshot
    final SnapshotId snapshotId = new SnapshotId(snapshotName, UUIDs.randomBase64UUID());
    final StepListener<RepositoryData> repositoryDataListener = new StepListener<>();
    repositoriesService.repository(repositoryName).getRepositoryData(repositoryDataListener);
    repositoryDataListener.whenComplete(repositoryData -> {
        clusterService.submitStateUpdateTask("create_snapshot [" + snapshotName + ']', new ClusterStateUpdateTask() {

            private SnapshotsInProgress.Entry newSnapshot = null;

            @Override
            public ClusterState execute(ClusterState currentState) {
                validate(repositoryName, snapshotName, currentState);
                SnapshotDeletionsInProgress deletionsInProgress = currentState.custom(SnapshotDeletionsInProgress.TYPE);
                if (deletionsInProgress != null && deletionsInProgress.hasDeletionsInProgress()) {
                    throw new ConcurrentSnapshotExecutionException(repositoryName, snapshotName, "cannot snapshot while a snapshot deletion is in-progress in [" + deletionsInProgress + "]");
                }
                SnapshotsInProgress snapshots = currentState.custom(SnapshotsInProgress.TYPE);
                if (snapshots == null || snapshots.entries().isEmpty()) {
                    // Store newSnapshot here to be processed in clusterStateProcessed
                    List<String> indices = Arrays.asList(indexNameExpressionResolver.concreteIndexNames(currentState, request.indicesOptions(), request.indices()));
                    LOGGER.trace("[{}][{}] creating snapshot for indices [{}]", repositoryName, snapshotName, indices);
                    List<IndexId> snapshotIndices = repositoryData.resolveNewIndices(indices);
                    newSnapshot = new SnapshotsInProgress.Entry(new Snapshot(repositoryName, snapshotId), request.includeGlobalState(), request.partial(), State.INIT, snapshotIndices, List.of(request.templates()), threadPool.absoluteTimeInMillis(), repositoryData.getGenId(), null, clusterService.state().nodes().getMinNodeVersion().onOrAfter(SHARD_GEN_IN_REPO_DATA_VERSION));
                    initializingSnapshots.add(newSnapshot.snapshot());
                    snapshots = new SnapshotsInProgress(newSnapshot);
                } else {
                    throw new ConcurrentSnapshotExecutionException(repositoryName, snapshotName, " a snapshot is already running");
                }
                return ClusterState.builder(currentState).putCustom(SnapshotsInProgress.TYPE, snapshots).build();
            }

            @Override
            public void onFailure(String source, Exception e) {
                LOGGER.warn(() -> new ParameterizedMessage("[{}][{}] failed to create snapshot", repositoryName, snapshotName), e);
                if (newSnapshot != null) {
                    initializingSnapshots.remove(newSnapshot.snapshot());
                }
                newSnapshot = null;
                listener.onFailure(e);
            }

            @Override
            public void clusterStateProcessed(String source, ClusterState oldState, final ClusterState newState) {
                if (newSnapshot != null) {
                    final Snapshot current = newSnapshot.snapshot();
                    assert initializingSnapshots.contains(current);
                    beginSnapshot(newState, newSnapshot, request.partial(), new ActionListener<>() {

                        @Override
                        public void onResponse(final Snapshot snapshot) {
                            initializingSnapshots.remove(snapshot);
                            listener.onResponse(snapshot);
                        }

                        @Override
                        public void onFailure(final Exception e) {
                            initializingSnapshots.remove(current);
                            listener.onFailure(e);
                        }
                    });
                }
            }

            @Override
            public TimeValue timeout() {
                return request.masterNodeTimeout();
            }
        });
    }, listener::onFailure);
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState) ClusterStateUpdateTask(org.elasticsearch.cluster.ClusterStateUpdateTask) FailedToCommitClusterStateException(org.elasticsearch.cluster.coordination.FailedToCommitClusterStateException) RepositoryException(org.elasticsearch.repositories.RepositoryException) RepositoryMissingException(org.elasticsearch.repositories.RepositoryMissingException) NotMasterException(org.elasticsearch.cluster.NotMasterException) RepositoryData(org.elasticsearch.repositories.RepositoryData) SnapshotDeletionsInProgress(org.elasticsearch.cluster.SnapshotDeletionsInProgress) GroupedActionListener(org.elasticsearch.action.support.GroupedActionListener) ActionListener(org.elasticsearch.action.ActionListener) SnapshotsInProgress(org.elasticsearch.cluster.SnapshotsInProgress) StepListener(org.elasticsearch.action.StepListener) Collections.unmodifiableList(java.util.Collections.unmodifiableList) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) TimeValue(io.crate.common.unit.TimeValue)

Example 9 with SnapshotDeletionsInProgress

use of org.elasticsearch.cluster.SnapshotDeletionsInProgress in project crate by crate.

the class SnapshotsService method isRepositoryInUse.

/**
 * Checks if a repository is currently in use by one of the snapshots
 *
 * @param clusterState cluster state
 * @param repository   repository id
 * @return true if repository is currently in use by one of the running snapshots
 */
public static boolean isRepositoryInUse(ClusterState clusterState, String repository) {
    SnapshotsInProgress snapshots = clusterState.custom(SnapshotsInProgress.TYPE);
    if (snapshots != null) {
        for (SnapshotsInProgress.Entry snapshot : snapshots.entries()) {
            if (repository.equals(snapshot.snapshot().getRepository())) {
                return true;
            }
        }
    }
    SnapshotDeletionsInProgress deletionsInProgress = clusterState.custom(SnapshotDeletionsInProgress.TYPE);
    if (deletionsInProgress != null) {
        for (SnapshotDeletionsInProgress.Entry entry : deletionsInProgress.getEntries()) {
            if (entry.getSnapshot().getRepository().equals(repository)) {
                return true;
            }
        }
    }
    return false;
}
Also used : SnapshotsInProgress(org.elasticsearch.cluster.SnapshotsInProgress) SnapshotDeletionsInProgress(org.elasticsearch.cluster.SnapshotDeletionsInProgress)

Example 10 with SnapshotDeletionsInProgress

use of org.elasticsearch.cluster.SnapshotDeletionsInProgress in project crate by crate.

the class SnapshotsService method finalizeSnapshotDeletionFromPreviousMaster.

/**
 * Finalizes a snapshot deletion in progress if the current node is the master but it
 * was not master in the previous cluster state and there is still a lingering snapshot
 * deletion in progress in the cluster state.  This means that the old master failed
 * before it could clean up an in-progress snapshot deletion.  We attempt to delete the
 * snapshot files and remove the deletion from the cluster state.  It is possible that the
 * old master was in a state of long GC and then it resumes and tries to delete the snapshot
 * that has already been deleted by the current master.  This is acceptable however, since
 * the old master's snapshot deletion will just respond with an error but in actuality, the
 * snapshot was deleted and a call to GET snapshots would reveal that the snapshot no longer exists.
 */
private void finalizeSnapshotDeletionFromPreviousMaster(ClusterState state) {
    SnapshotDeletionsInProgress deletionsInProgress = state.custom(SnapshotDeletionsInProgress.TYPE);
    if (deletionsInProgress != null && deletionsInProgress.hasDeletionsInProgress()) {
        assert deletionsInProgress.getEntries().size() == 1 : "only one in-progress deletion allowed per cluster";
        SnapshotDeletionsInProgress.Entry entry = deletionsInProgress.getEntries().get(0);
        deleteSnapshotFromRepository(entry.getSnapshot(), null, entry.repositoryStateId(), state.nodes().getMinNodeVersion());
    }
}
Also used : SnapshotDeletionsInProgress(org.elasticsearch.cluster.SnapshotDeletionsInProgress)

Aggregations

SnapshotDeletionsInProgress (org.elasticsearch.cluster.SnapshotDeletionsInProgress)11 SnapshotsInProgress (org.elasticsearch.cluster.SnapshotsInProgress)7 ClusterState (org.elasticsearch.cluster.ClusterState)6 ClusterStateUpdateTask (org.elasticsearch.cluster.ClusterStateUpdateTask)6 ParameterizedMessage (org.apache.logging.log4j.message.ParameterizedMessage)5 ArrayList (java.util.ArrayList)4 List (java.util.List)4 RepositoryData (org.elasticsearch.repositories.RepositoryData)4 ObjectObjectCursor (com.carrotsearch.hppc.cursors.ObjectObjectCursor)3 ActionListener (org.elasticsearch.action.ActionListener)3 RestoreInProgress (org.elasticsearch.cluster.RestoreInProgress)3 Priority (org.elasticsearch.common.Priority)3 ImmutableOpenMap (org.elasticsearch.common.collect.ImmutableOpenMap)3 RepositoryMissingException (org.elasticsearch.repositories.RepositoryMissingException)3 IntHashSet (com.carrotsearch.hppc.IntHashSet)2 IntSet (com.carrotsearch.hppc.IntSet)2 ObjectCursor (com.carrotsearch.hppc.cursors.ObjectCursor)2 TimeValue (io.crate.common.unit.TimeValue)2 IOException (java.io.IOException)2 Collections (java.util.Collections)2