box: rework clear_synchro_queue to commit everything
It is possible that a new leader (elected either via raft or manually or
via some user-written election algorithm) loses the data that the old
leader has successfully committed and confirmed.
Imagine such a situation: there are N nodes in a replicaset, the old
leader, denoted A, tries to apply some synchronous transaction. It is
written on the leader itself and N/2 other nodes, one of which is B.
The transaction has thus gathered quorum, N/2 + 1 acks.
Now A writes CONFIRM and commits the transaction, but dies before the
confirmation reaches any of its followers. B is elected the new leader and it
sees that the last A's transaction is present on N/2 nodes, so it doesn't have a
quorum (A was one of the N/2 + 1).
Current `clear_synchro_queue()` implementation makes B roll the transaction
back, leading to rollback after commit, which is unacceptable.
To fix the problem, make `clear_synchro_queue()` wait until all the rows from
the previous leader gather `replication_synchro_quorum` acks.
In case the quorum wasn't achieved during replication_synchro_timeout, rollback
nothing and wait for user's intervention.
Closes #5435
Co-developed-by:
Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
Showing
- src/box/box.cc 138 additions, 28 deletionssrc/box/box.cc
- src/box/errcode.h 1 addition, 0 deletionssrc/box/errcode.h
- src/box/raft.c 11 additions, 2 deletionssrc/box/raft.c
- test/replication/election_replica.lua 4 additions, 1 deletiontest/replication/election_replica.lua
- test/replication/gh-5435-qsync-clear-synchro-queue-commit-all.result 144 additions, 0 deletions...ation/gh-5435-qsync-clear-synchro-queue-commit-all.result
- test/replication/gh-5435-qsync-clear-synchro-queue-commit-all.test.lua 65 additions, 0 deletions...ion/gh-5435-qsync-clear-synchro-queue-commit-all.test.lua
- test/replication/suite.cfg 1 addition, 0 deletionstest/replication/suite.cfg
Loading
Please register or sign in to comment