tkhurana opened a new pull request, #2604:
URL: https://github.com/apache/phoenix/pull/2604

   When >=2 co-active RegionServers drive the shared HA-status znode to the 
same target state, each does an optimistic CAS whose expected version comes 
from the watch-lagged local cache. The first writer wins; the others were 
aborting the RegionServer even though the shared status was already at the 
target. This hits the peer-degrade path (ACTIVE_IN_SYNC -> ACTIVE_NOT_IN_SYNC) 
and, more commonly, the forwarders racing ACTIVE_NOT_IN_SYNC -> ACTIVE_IN_SYNC.
   
   The two convergent losers differ by whether the winner's write reached the 
loser's cache before it fired, and each is reconciled from a source that is 
authoritative for its path -- never the watch-lagged cache used as a 
false-success signal:
   
   Cache-stale loser (client, HAGroupStoreClient.setHAGroupStatusIfNeeded): the 
CAS is attempted and loses stale; the loop re-reads fresh from ZK and retries, 
bounded by SET_HA_GROUP_STATUS_MAX_ATTEMPTS. Move 'attempt > 1 && current == 
target' no-op ahead of validateTransitionAndGetWaitTime so a converged 
non-self-transitionable target (e.g. ACTIVE_IN_SYNC) returns a no-op success 
from the fresh re-read instead of throwing 
InvalidClusterRoleTransitionException on the X -> X self-transition. The first 
attempt never short-circuits, so the periodic STORE_AND_FORWARD heartbeat still
   writes its znode mtime bump that gates SYNC promotion.
   
   Watch-won loser (server, HAGroupStoreManager.setHAGroupStatusToSync): the 
winner's write already propagated to the cache, so validate rejects the 
ACTIVE_IN_SYNC -> ACTIVE_IN_SYNC self-transition before any CAS is attempted -- 
no stale-version exception is ever thrown, so the client cannot catch it. 
Swallow the InvalidClusterRoleTransitionException as a no-op success, guarded 
on isStateAlreadyUpdated(current == target) so a genuinely invalid transition 
still propagates. The ACTIVE_IN_SYNC local listener in ReplicationLogGroup 
already drives the loser to the correct end state (resume rotation, 
SYNC_AND_FORWARD -> SYNC), so the group-level goal is met and the loser need 
not retry its own write.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to