Siyao Meng created HDDS-16932:
---------------------------------

             Summary: SCM follower rejects every append from a new leader when 
leadership moves while it downloads a checkpoint that then succeeds
                 Key: HDDS-16932
                 URL: https://issues.apache.org/jira/browse/HDDS-16932
             Project: Apache Ozone
          Issue Type: Bug
            Reporter: Siyao Meng


h3. Mechanism
When the leader notifies a follower SCM to install a snapshot, 
{{SCMStateMachine.notifyInstallSnapshotFromLeader}} downloads the leader's 
checkpoint and completes its future with the checkpoint TermIndex. Ratis 
(3.3.1) {{SnapshotInstallationHandler}} then keeps its install in progress 
index set; the install is applied and the index cleared only when the next 
install notification arrives. While the index is set, 
{{RaftServerImpl.checkInconsistentAppendEntries}} rejects every append ("Failed 
appendEntries as snapshot (...) installation is in progress"). Ratis never 
clears or applies a pending install on a leader change. A new leader sends an 
install notification to a follower that is already a voting member only when 
the follower's next index is below the start of its own log 
({{LogAppender.shouldInstallSnapshot}}). So if leadership moves during the 
download to an SCM whose log still contains the follower's next entry, and the 
download then succeeds, the follower rejects all of the new leader's appends 
indefinitely.

HDDS-16899 reports the case where the download fails and the future completes 
with null; its patch fails the future instead, which makes Ratis clear the 
index at once. It does not cover a successful download. The null results of 
{{SCMHAManagerImpl.verifyCheckpointFromLeader}} (a checkpoint that is not ahead 
of the follower, or an error while reading it) leave the index set the same way 
and are not covered either (the second is listed under "Not covered" in 
HDDS-16899).

h3. Trigger
# {{ozone.scm.ha.ratis.log.purge.enabled=true}} (default false). Follower F is 
behind; leader L1 has purged its log past F's next index, while another SCM L2 
has not (for example after a snapshot request to L1 only, or different snapshot 
timing).
# F gets an install notification from L1 and downloads the checkpoint. With a 
large DB this takes minutes.
# L1 stays up but loses leadership to L2 during the download: an admin 
leadership transfer, or an election after a GC pause of L1 or a partition 
between L1 and L2. The leader side of the download 
({{InterSCMGrpcService.download}}) does not check leadership, so the download 
succeeds.

h3. Impact
* F stays at its old applied index and rejects every append from L2. It 
recovers on a restart, or (argued) when a leader whose log is purged past F's 
next index takes over or L2 purges past it.
* With L1 up, L1 and L2 form a majority, so the SCM service stays available. 
The ring has no failure margin left: if L1 or L2 then fails, the remaining two 
SCMs cannot commit (argued).

h3. Reproduction
The reproduction is not attached. It is a mini cluster test with three SCMs, 
purge enabled with gap 5 and automatic snapshots off. F stops, containers are 
allocated, and only L1 takes a snapshot, so L1's log starts after F's next 
index and L2's does not. F's download is routed through a proxy that holds the 
connection; while it is held, leadership is transferred from L1 to L2 with 
{{StorageContainerLocationClient.transferLeadership}}; then the proxy is 
released and the download succeeds (F logs "StateMachine successfully installed 
snapshot index 352" after L2 became leader at term 3). Results 30 s after the 
transfer:
* On b0aa6475b7856d2c7f467dd3db12b9a1dd116f63 (PASS, the defect is present, 
92.7 s): L2 leader and ready, L1 running, leader applied index 395, F applied 
index 42, 3258 rejected appends logged on F when the download ended and 3275 30 
s later, 1 install notification to F.
* With the patch attached to HDDS-16899 applied (PASS, 96.2 s): the same, 
leader applied index 396, F applied index 42, 2358 and 2374 rejected appends, 1 
install notification.

h3. Suggested fix
In SCM: after the download, fail the future instead of completing it when the 
leader changed while the download ran (the leader in the notification's role 
info is no longer the current leader). Ratis then clears the index at once, F 
accepts L2's appends from its next index, and L2 notifies F if its log no 
longer covers that index. This also needs the {{verifyCheckpointFromLeader}} 
null results to fail the future. Because Ratis never clears or applies a 
pending install on a leader change, a Ratis change that does so would close the 
case fully, for SCM and for OM, which uses the same notification mechanism 
(argued, not run for OM).

No patch is attached. The code involved is unchanged on master at 52812559dad.

Found by TLA+ model checking and code review of the SCM Ratis snapshot and 
checkpoint install paths under HDDS-15926, on commit 
b0aa6475b7856d2c7f467dd3db12b9a1dd116f63. Checked against HDDS and RATIS issues 
and apache/ozone pull requests for duplicates before filing. Generated with 
Specula (Claude Opus 5.5).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to