[
https://issues.apache.org/jira/browse/IGNITE-23587?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17894673#comment-17894673
]
Mikhail Efremov commented on IGNITE-23587:
------------------------------------------
This ticket is required to fix possible livelocks on rebalance through primary
replica
> Make PlacementDriver able to choose lease candidate from pendings
> -----------------------------------------------------------------
>
> Key: IGNITE-23587
> URL: https://issues.apache.org/jira/browse/IGNITE-23587
> Project: Ignite
> Issue Type: Improvement
> Reporter: Mikhail Efremov
> Assignee: Mikhail Efremov
> Priority: Blocker
> Labels: ignite-3, lease
>
> *Description*
> While working under IGNITE-22036 there was found 2 exceptional scenarios:
> _Recovery case_
> {code:java}
> nodes = [A, B]
> parts = 1
> replicas = 1
> | starting nodes
> v
> 13_part_0 stable = [B]
> B hosts replicaGrpId=13_part_0
> B becomes PR
> |
> v
> A starts
> | <nothing happens>
> v
> B is shutdowned
> | <do reset on pending = [A]>
> v
> A::TableManager::handlePending fails (A not a primary)
> A starts voting and became a leader term=2
> | ReplicaStateManager fails (A not a primary)
> v
> LeaseUpdater#updateBatchLeaseInternal
> <---------------------------------------\
> | iterate over assignments == [B]
> |
> v
> |
> topologyTracker#nodeByConsistentId
> |
> | returns null
> |
> v
> |
> leaseUpdateStatistics#onLeaseWithoutCandidate();
> |
> | continue
> |
> v
> |
> LOG.debug("No leases to update found.") // don't see in log because debug lvl
> |
> |
> |
> \-----------------------------------------------------------------------------/
> {code}
> _Stable dies, change peers wasn't done_
> {code:java}
> nodes = [A, B]
> parts = 1
> replicas = 1
> | starting nodes
> v
> 13_part_0 stable = [B]
> B hosts replicaGrpId=13_part_0
> B becomes PR
> |
> v
> A starts
> | <filter={A}>
> v
> A::TM#handleChangePendingsAssignmentsEvent
> A::ReplicaManager#startReplica
> A::RaftGroupService#updatePeersAndLearners
> | <ready for catch up>
> v
> B::TM#handleChangePendingsAssignmentsEvent
> B::TM#sendChangePeersAndLearnersReplicaRequest
> B::ReplicaPartitionListener#processChangePeersAndLearnersReplicaRequest
> B::RaftGroupService#changePeersAndLearnersAsync
> | <B dies>
> v
> <No primary => no one would process failover>
> <All TM#handleChangePendingsAssignmentsEvent are finished previously =>
> => no one would send ChangePeersAndLearnersReplicaRequest>
> |
> v
> LeaseUpdater#updateBatchLeaseInternal
> <---------------------------------------\
> | iterate over assignments == [B]
> |
> v
> |
> topologyTracker#nodeByConsistentId
> |
> | returns null
> |
> v
> |
> leaseUpdateStatistics#onLeaseWithoutCandidate();
> |
> | continue
> |
> v
> |
> LOG.debug("No leases to update found.") // don't see in log because debug lvl
> |
> |
> |
> \-----------------------------------------------------------------------------/
> {code}
> As we can see, in both cases we have a situation where we can't re-grant
> lease and then neither send {{ChangePeersAndLearnersReplicaRequest}} nor
> trigger {{onLeaderElected}} callback that was hooked after
> {{PRIMARY_REPLICA_ELECTED}}. And if in the first scenario there is possible
> workaround through sending the replica request with ignoring of primary
> replica nod colocation, but in the second scenario all possible pending
> handlers are already finished and wouldn't be called further.
> This situation leads us to an idea that we may take a closer look on lease
> granting process. For now we're checking only stable assignments for a new
> lease holder candidate. So, while we didn't finished assignments stable
> switch (call of {{onNewPeersConfigurationApplied}} after full RAFT rebalabce
> is done), we will nave {{null}} candidate and stucks in live lock.
> A possible solution is to check pendings assignments too in case if on stable
> assignments we haven't got any possibe lease candidate. But there we have an
> assumption that granting lease for a candidate from pending assignments won't
> be a problem, because we may accept lease only if candidate replica can
> retrieve replication group leader (see
> {{ReplicaImpl#processLeaseGrantedMessage}}, mostly the first action is to get
> the leader), then we're almost able to process requests: at least we will
> propose leader-colocated replica or (see the 2nd case) will waiting if leader
> will be elected.
> There should be a note about about the 2nd case: if B node dies before catch
> up is done and before RAFT group de-facto changed a configuration and then A
> didn't and unable to elect itself as a leader, we have a situation as now
> when partition is broken because the only replica is unavailable.
> *Motivation*
> The main motivation there is to make IGNITE-22036 and a whole epic
> IGNITE-22313 be able to handle rebalance even if we have no any active node
> in stable assignments because assignments stable switch unable to be called.
> *Definition of done*
> # {{AssignmentsTracker}} is able to track both stable and pending assignments.
> # While {{LeaseUpdater#Updater#updateLeaseBatchInternal}} if on lease
> expiration {{LeaseUpdater#nextLeaseHolder}} returns {{null}}, then it now
> should gets pending assignments from {{AssignmentsTracker}} and choose a
> lease candidate among them.
> # Before IGNITE-22036 is done this changes shouldn't breaks any tests.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)