Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor RecoveryTarget state management #8092

Closed
wants to merge 11 commits into from

Conversation

bleskes
Copy link
Contributor

@bleskes bleskes commented Oct 15, 2014

The PR rewrites the state controls in the RecoveryTarget family classes to make it easier to guarantee that:

  • recovery resources are only cleared once there are no ongoing requests
  • recovery is automatically canceled when the target shard is closed/removed
  • canceled recoveries do not leave temp files behind when canceled.

Highlights of the change:

  1. All temporary files are cleared upon failure/cancel (see Recovery files left behind when replica building fails #7315 )
  2. All newly created files are always temporary
  3. Doesn't list local files on the cluster state update thread (which throw unwanted exception)
  4. Recoveries are canceled by a listener to IndicesLifecycle.beforeIndexShardClosed, so we don't need to explicitly call it.
  5. Simplifies RecoveryListener to only notify when a recovery is done or failed. Removed subtleties like ignore and retry (they are dealt with internally)

Relates to #7893

At the moment, we leave around temporary files if a peer (replica) recovery is canceled. Those files will normally be cleaned up once the shard is started else but in case of errors this can lead to trouble. If recovery are started and canceled often, we may cause nodes to run out of disk space.

Closes #7893
@bleskes bleskes changed the title Recovery: refactor RecoveryTarget state managemnt Recovery: refactor RecoveryTarget state management Oct 15, 2014
…ere cleaned

These are now background processes..
@s1monw s1monw self-assigned this Oct 15, 2014
import org.elasticsearch.index.shard.service.InternalIndexShard;

import java.util.Map;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we get a javadoc string what this class does?

private void closeInternal() {
try {
// clean open index outputs
Iterator<Entry<String, IndexOutput>> iterator = openIndexOutputs.entrySet().iterator();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can just do:

IOUtils.closeWhileHandlingException(openIndexOutputs.values());
openIndexOutputs.clear();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's strictly speaking thread unsafe. I think we can do this here in practice, but part of the refactoring was not to have to worry about these kind of things. I think we should keep it as is?

@s1monw
Copy link
Contributor

s1monw commented Oct 16, 2014

I left a bunch of comments - I really like that change btw :) 👍

@s1monw s1monw removed the review label Oct 16, 2014
@bleskes bleskes added the review label Oct 19, 2014
@bleskes
Copy link
Contributor Author

bleskes commented Oct 19, 2014

@s1monw I pushed some commits to address your comments. Can we do another round?

@s1monw
Copy link
Contributor

s1monw commented Oct 21, 2014

LGTM

recoveryState.setSourceNode(sourceNode);
recoveryState.setTargetNode(clusterService.localNode());
recoveryState.setPrimary(indexShard.routingEntry().primary());
final long recoveryId = onGoingRecoveries.startRecovery(indexShard, sourceNode, recoveryState, listener);
threadPool.generic().execute(new Runnable() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually think we should use AbstractRunnable here

     threadPool.generic().execute(new AbstractRunnable() {
            @Override
            public void onFailure(Throwable t) {
              // call listener
            }

            @Override
            protected void doRun() throws Exception {
 RecoveriesCollection.StatusRef statusRef = onGoingRecoveries.getStatus(recoveryId);
                if (statusRef == null) {
                    return;
                }
                try {
                    doRecovery(statusRef.status());
                } finally {
                    // make sure we never interrupt the thread after we have released it back to the pool
                    statusRef.status().clearWaitingRecoveryThread(Thread.currentThread());
                    statusRef.close();
                }
            }

WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

++

@bleskes
Copy link
Contributor Author

bleskes commented Oct 23, 2014

@s1monw I pushed another commit based on the latest feedback. I'm giving CI an hour or two to chew this and will then merge.

bleskes added a commit that referenced this pull request Oct 23, 2014
This commit rewrites the state controls in the RecoveryTarget family classes to make it easier to guarantee that:
- recovery resources are only cleared once there are no ongoing requests
- recovery is automatically canceled when the target shard is closed/removed
- canceled recoveries do not leave temp files behind when canceled.

Highlights of the change:
1) All temporary files are cleared upon failure/cancel (see #7315 )
2) All newly created files are always temporary
3) Doesn't list local files on the cluster state update thread (which throw unwanted exception)
4) Recoveries are canceled by a listener to IndicesLifecycle.beforeIndexShardClosed, so we don't need to explicitly call it.
5) Simplifies RecoveryListener to only notify when a recovery is done or failed. Removed subtleties like ignore and retry (they are dealt with internally)

Closes #8092 , Closes #7315
@bleskes bleskes closed this in 24bc8d3 Oct 23, 2014
@bleskes bleskes deleted the enhancement/recovery_target_rewrite branch October 23, 2014 13:14
@bleskes
Copy link
Contributor Author

bleskes commented Oct 23, 2014

merged. Thx @s1monw !

bleskes added a commit that referenced this pull request Oct 29, 2014
we current check that the recovery is not finished when people access the status local variables. This is wrong and we should check for the refcount being > 0 as it is OK to use the status after it has marked as finished but there are still on going, in-flight reference to it.

Relates to #8092

Closes #8271
bleskes added a commit that referenced this pull request Oct 29, 2014
we current check that the recovery is not finished when people access the status local variables. This is wrong and we should check for the refcount being > 0 as it is OK to use the status after it has marked as finished but there are still on going, in-flight reference to it.

Relates to #8092

Closes #8271
@clintongormley clintongormley added :Distributed/Recovery Anything around constructing a new shard, either from a local or a remote source. and removed review labels Mar 19, 2015
@clintongormley clintongormley changed the title Recovery: refactor RecoveryTarget state management Refactor RecoveryTarget state management Jun 7, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Distributed/Recovery Anything around constructing a new shard, either from a local or a remote source. >enhancement resiliency v1.5.0 v2.0.0-beta1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants