-
Notifications
You must be signed in to change notification settings - Fork 9.8k
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
Fix the data inconsistency issue by moving the SetConsistentIndex into the transaction lock #13854
Conversation
f72fbb0
to
c6dc71f
Compare
Codecov Report
@@ Coverage Diff @@
## main #13854 +/- ##
==========================================
- Coverage 72.45% 72.31% -0.15%
==========================================
Files 469 469
Lines 38275 38352 +77
==========================================
+ Hits 27733 27735 +2
- Misses 8771 8833 +62
- Partials 1771 1784 +13
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
Thank you @ahrtr. The fix logic seems to me to be good. @serathius is the problem reproducible with the fix ? What I'm afraid is that it is error prone maintain the correct calls going forward:
I'm think we need to have some method of verification that we don't forget or messed the calls. For example: If ETCD_VERIFY env variable ( Line 30 in 0e83f62
in Unlock & UnlockWithoutHooks we perform verification whether 'apply' method is/is-not (respectively) on the stack-trace. The mode is already enabled by default in both integrational & e2e tests. It would be slow... but it would catch most of the wrong calls... It might miss case when 'apply' is creating go-routine that performs a transaction... but I think it would be weird pattern we should be also aware off. Alternative is to use 'ctx' for such verification... (implicit ctx driving business logic is imho anti-pattern) but it would require us to pass ctx to all methods that performs transactions (that seems a good thing in general).
I reserved a ~full day for tomorrow to potentially try hands-on some of the ideas proposed above. |
It's really a good point. But I don't think it's a blocker for the release of 3.5.3, because this issue is urgent and important. |
Just added detailed comment to explain the difference between Lock and LockWithoutHook. @ptabor |
I still managed to reproduce inconsistencies due to downgrade/upgrade as described in #13514 (comment) with #13844 cherry-picked to v3.5.2. I didn't try this PR, as it's more complex to cherry-pick. |
With this PR, the test from #13838 no longer produces "found data inconsistency with peers" |
I have also run qualification and was not longer able to reproduce the issue on this PR. To give some data I have run qualification 4 times each taking 10 minutes and didn't find any issues. Compare this to reproduction on |
this is great news @serathius Nice hob @ahrtr ! |
Still looking into this. Added verification as described above and discovering subtle cases as expected:
And the other way around: Authenticate is being called outside of 'apply' from interceptors...
|
be02248
to
45e2ad0
Compare
Thanks @ptabor . In your first stack trace, we do need to call In your second stack trace coming from outside I just enhanced I rebased this PR, so all the three commits are submitted again, but you only need to take a look at the last one to check the latest change I made. |
a7ac307
to
d449fc6
Compare
d6d7c53
to
c698e13
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you so much !!!
Great work.
…ackage Removed the fields consistentIdx and consistentTerm from struct EtcdServer, and added applyingIndex and applyingTerm into struct consistentIndex in package cindex. We may remove the two fields completely if we decide to remove the OnPreCommitUnsafe, and it will depend on the performance test result.
// and raftpb.Entry.Term, and they are not ready to be persisted yet. They will be | ||
// saved to consistentIndex and term above in the txPostLockInsideApplyHook. | ||
// | ||
// TODO(ahrtr): try to remove the OnPreCommitUnsafe, and compare the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we do the performance check before merging this PR? I would prefer not to backport a PR with todo. Please let me know if you need help with measuring it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we are all good so far. I will investigate whether or not we should completely remove the OnPreCommitUnsafe
in the next step only in the main branch. The change (I mean possibly removing OnPreCommitUnsafe
) will not be cherry picked to 3.5.
We can use the tools/benchmark, correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to backport this change because it makes the code much simpler, which will be important for long term maintenance of release-3.5 branch. Just making sure that the decision not to fix it imminently is not rushed, let's not sacrifice the quality, however it you think it's not worth backporting that's also ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your comment is valid, but usually we only backport bug fixes to previous release, so does this PR. But completely possibly removing OnPreCommitUnsafe
is a refactor, and so I don't think we should backport it to 3.5. Please note that refactoring may also introduce regression, so we should only do it in main branch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this PR is good to go.
Can you squash the commits? |
I intentionally added multiple commits, each has a clear goal/comment. I can merge the first two commits. WDYT? |
@ahrtr can you handle backport to v3.5? |
Definitely yes, will do it today. Many thanks to @ptabor and @serathius for all the helps and valuable review comments. |
Also thanks to @deads2k @serathius and @michaljasionowski for the verification of issue based on this PR! |
FYI. In case anyone needs a simple summary |
Fix issues/13766 .
Previously the
SetConsistentIndex()
is called during the apply workflow, but it's outside the backend transaction. Obviously they do not belong to an atomic operation any more. If a periodic commit happens betweenSetConsistentIndex
and the left apply workflow, and etcd crashes for whatever reason right after the commit, then etcd runs into the data inconsistency issue. Please refer to discussion in pull/13844 and issues/13766.In this PR, I moved the
SetConsistentIndex
into atxPostLockHook
, which is executed each time right after thebatchTx.Lock()
being called.batchTx.Lock()
is called in many places, buttxPostLockHook
is only supposed to be executed in the apply workflow. So I added one more interface methodLockWithoutHook
intoBatchTx
; it doesn't execute thetxPostLockHook
at all.Only the operations in the apply workflow call the
BatchTx.Lock
, and all others should callBatchTx.LockWithoutHook
. If the operation doesn't have any impact on the apply workflow, such as theetcdutl
commands, then it doesn't matter which lock it calls.cc all related people @ptabor @serathius @spzala @wilsonwang371 @chaochn47 @tangcong @liuycsd @PaulFurtado @gyuho @hexfusion @jingyih @wpedrak Please take a look. Thanks.
@chaochn47 @serathius @liuycsd @moonovo @michaljasionowski could you please try this PR to check whether you can still reproduce the data inconsistency issue? Thanks.