Skip to content

Conversation

@dnhatn
Copy link
Member

@dnhatn dnhatn commented Sep 22, 2018

We start tracking max seq_no_of_updates on the primary in #33842. This commit replicates that value from a primary to its replicas in replication requests or the translog phase of peer-recovery.

With this change, we guarantee that the value of max seq_no_of_updates on a replica when any index/delete operation is performed at least the max_seq_no_of_updates on the primary when that operation was executed.

Relates #33656

We start tracking max seq_no_of_updates on the primary in elastic#33842. This
commit replicates that value from a primary to its replicas in
replication requests or the translog phase of peer-recovery.

With this change, we guarantee that the value of max seq_no_of_updates
on a replica when any index/delete operation is performed at least the
max_seq_no_of_updates on the primary when that operation was executed.

Relates elastic#33656
@dnhatn dnhatn added >enhancement :Distributed Indexing/Recovery Anything around constructing a new shard, either from a local or a remote source. v7.0.0 v6.5.0 labels Sep 22, 2018
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-distributed

Copy link
Contributor

@bleskes bleskes left a comment

Choose a reason for hiding this comment

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

Looks great. I left some comments

private boolean assertMaxSeqNoOfUpdatesIsPropagated(Index index, IndexingStrategy plan) {
final long maxSeqNoOfUpdates = getMaxSeqNoOfUpdatesOrDeletes();
final Version indexVersion = config().getIndexSettings().getIndexVersionCreated();
assert plan.useLuceneUpdateDocument == false
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure what this buys us? it just validates the logic in plan as non primary and has nothing to do with the replication code? what am I missing?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, but with our classic example: index-1, delete-2, and index-3 on the primary; and the order on a replica is index-1(msu=-1), index-3(msu=2), and delete-2(msu=2). An index-3 on replica is an update on a replica but its msu is only 2.

Copy link
Contributor

Choose a reason for hiding this comment

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

sorry, I don't follow. I'll reach out monday to discuss.

// If the old primary was on an old version, this promoting primary (was replica before)
// does not have max_seq_no_of_updates. We need to bootstrap it manually from its local history.
assert indexSettings.getIndexVersionCreated().before(Version.V_7_0_0_alpha1);
engine.initializeMaxSeqNoOfUpdatesOrDeletes();
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 we need maxSeq no here? maybe the translog wasn't fsynced? (if people disable the per request fsync)

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, initializeMaxSeqNoOfUpdatesOrDeletes uses the max_seq_no from the local tracker and translog.

// assert indexSettings.getIndexVersionCreated().before(Version.V_7_0_0_alpha1) : indexSettings.getIndexVersionCreated();
// If the old primary was on an old version, this promoting primary (was replica before)
// does not have max_seq_no_of_updates. We need to bootstrap it manually from its local history.
assert indexSettings.getIndexVersionCreated().before(Version.V_7_0_0_alpha1);
Copy link
Contributor

Choose a reason for hiding this comment

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

same comment

opPrimaryTerm, currentGlobalCheckpoint, maxSeqNo);
if (currentGlobalCheckpoint < maxSeqNo) {
resetEngineToGlobalCheckpoint();
resetEngineToGlobalCheckpoint(maxSeqNoOfUpdatesOrDeletes);
Copy link
Contributor

Choose a reason for hiding this comment

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

why do we need to set the maxSeqNoUpdatesOrDeletes here? can't we let it be what engine does it self? I think it's also risky because we recovery from the translog (and need make the optimization doesn't create duplicates in thas process)

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, we can let an engine take care itself. The reason I use the max_seq_no_of_updates from the primary, so at the end of a test, all replicas and its primary have the same max_seq_no_of_updates. I will update this.

});
}
final IndexResult result = super.index(index);
if (index.seqNo() == SequenceNumbers.UNASSIGNED_SEQ_NO && result.getFailure() == null && result.isCreated() == false) {
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 we can inline this into internal engine as a standard assertion no?

advanceMaxSeqNoOfUpdatesOrDeletes(maxSeqNo);
}
final DeleteResult result = super.delete(delete);
if (delete.seqNo() == SequenceNumbers.UNASSIGNED_SEQ_NO && result.getFailure() == null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

same comment this can be in the engine it self?

* An alternative of {@link InternalEngine} that allows tweaking internals to reduce noise in engine tests.
*/
class InternalTestEngine extends InternalEngine {
private volatile boolean autoAdjustMaxSeqNoOfUpdatesOrDeletes = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

doesn't like anyone is change this - is this a follow up?

@dnhatn
Copy link
Member Author

dnhatn commented Sep 22, 2018

@bleskes Could you please have another look? Thank you!

@dnhatn dnhatn requested a review from bleskes September 22, 2018 22:18
@dnhatn dnhatn added the review label Sep 22, 2018
Copy link
Contributor

@bleskes bleskes left a comment

Choose a reason for hiding this comment

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

Looks good. I left some nits. I'm waiting with LGTM for our discussion

// If the old primary was on an old version, this promoting primary (was replica before)
// does not have max_seq_no_of_updates. We need to bootstrap it manually from its local history.
assert indexSettings.getIndexVersionCreated().before(Version.V_7_0_0_alpha1);
engine.advanceMaxSeqNoOfUpdatesOrDeletes(seqNoStats().getMaxSeqNo());
Copy link
Contributor

Choose a reason for hiding this comment

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

reads better thanks. I think this comment will be more intuitive if you change old primary was on an old version to old primary was on an old version that didn't yet replicate the MSU, we need to bootstrap it...

newEngine = createNewEngine(newEngineConfig());
active.set(true);
}
newEngine.advanceMaxSeqNoOfUpdatesOrDeletes(seqNoStats.getMaxSeqNo());
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 it will be easier to understand if we use seqNoStats.getGlobalCheckpoint() which is the upper bound for the local recovery. The rest we don't care about here, right?

} else if (plan.indexIntoLucene || plan.addStaleOpToLucene) {
indexResult = indexIntoLucene(index, plan);
assert (index.seqNo() != SequenceNumbers.UNASSIGNED_SEQ_NO || indexResult.isCreated() || indexResult.getFailure() != null)
|| indexResult.getSeqNo() <= getMaxSeqNoOfUpdatesOrDeletes() : indexResult.getSeqNo() + " > " + getMaxSeqNoOfUpdatesOrDeletes();
Copy link
Contributor

Choose a reason for hiding this comment

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

we need to allow for the msu to be unset here, no?

@dnhatn
Copy link
Member Author

dnhatn commented Sep 25, 2018

@bleskes I've updated the assertion as we discussed. Would you please give it another look? Thank you.

@dnhatn dnhatn requested a review from bleskes September 25, 2018 01:08
Copy link
Contributor

@bleskes bleskes left a comment

Choose a reason for hiding this comment

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

Lgtm

Copy link
Contributor

@s1monw s1monw left a comment

Choose a reason for hiding this comment

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

LGTM 2 thanks @dnhatn

@dnhatn
Copy link
Member Author

dnhatn commented Sep 25, 2018

Thanks @bleskes and @s1monw.

@dnhatn dnhatn merged commit 5166dd0 into elastic:master Sep 25, 2018
@dnhatn dnhatn deleted the replica-msu branch September 25, 2018 12:08
dnhatn added a commit that referenced this pull request Sep 27, 2018
We start tracking max seq_no_of_updates on the primary in #33842. This
commit replicates that value from a primary to its replicas in replication
requests or the translog phase of peer-recovery.

With this change, we guarantee that the value of max seq_no_of_updates
on a replica when any index/delete operation is performed at least the
max_seq_no_of_updates on the primary when that operation was executed.

Relates #33656
dnhatn added a commit that referenced this pull request Sep 27, 2018
dnhatn added a commit that referenced this pull request Sep 27, 2018
This commit adds "engine is closed" as an expected failure message.
This change is due to #33967 in which we might access a closed engine on
promotion.

Relates #33967
dnhatn added a commit that referenced this pull request Sep 27, 2018
This commit adds "engine is closed" as an expected failure message.
This change is due to #33967 in which we might access a closed engine on
promotion.

Relates #33967
kcm pushed a commit that referenced this pull request Oct 30, 2018
We start tracking max seq_no_of_updates on the primary in #33842. This
commit replicates that value from a primary to its replicas in replication 
requests or the translog phase of peer-recovery.

With this change, we guarantee that the value of max seq_no_of_updates
on a replica when any index/delete operation is performed at least the
max_seq_no_of_updates on the primary when that operation was executed.

Relates #33656
kcm pushed a commit that referenced this pull request Oct 30, 2018
kcm pushed a commit that referenced this pull request Oct 30, 2018
This commit adds "engine is closed" as an expected failure message.
This change is due to #33967 in which we might access a closed engine on
promotion.

Relates #33967
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

:Distributed Indexing/Recovery Anything around constructing a new shard, either from a local or a remote source. >enhancement >non-issue v6.5.0 v7.0.0-beta1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants