Siyao Meng created HDDS-17451:
---------------------------------

             Summary: SCM terminates when it applies a 
transitionDeletingOrDeletedToClosedState Raft log entry written by SCM 2.0 or 
2.1, and again on every restart
                 Key: HDDS-17451
                 URL: https://issues.apache.org/jira/browse/HDDS-17451
             Project: Apache Ozone
          Issue Type: Bug
          Components: SCM
    Affects Versions: 2.2.1, 2.3.0, 2.2.0
            Reporter: Siyao Meng


h3. Mechanism
SCM 2.0.x and 2.1.x write {{CONTAINER}} Raft log entries for 
{{ContainerStateManager.transitionDeletingOrDeletedToClosedState(ContainerID)}} 
(HDDS-11136, HDDS-12421) when the leader gets a non-empty replica report for a 
DELETING or DELETED container. HDDS-14684 (2.2.0) renamed the method to 
{{transitionDeletingOrDeletedToTargetState(ContainerID, LifeCycleState)}} and 
kept no method under the old name, so the generated 
{{ContainerStateManagerInvoker.invokeLocal}} has no case for it. Applying such 
an entry throws {{IllegalArgumentException("Method not found: 
transitionDeletingOrDeletedToClosedState in ContainerStateManager")}}. That is 
not an {{SCMException}}, so {{SCMStateMachine.applyTransaction}} calls 
{{ExitUtils.terminate}}. The entry is still unapplied, so the SCM replays it 
and terminates again on every start. The request encoding is unchanged 
(parameter class name plus proto bytes), only the method name lookup fails. 
HDDS-16169 fixed the same failure for the renamed 
{{ContainerStateManager.updateContainerState}}.

h3. Trigger
An SCM on 2.2.x or master has to apply such an entry, which happens when it did 
not apply it before the upgrade:
# An SCM that was down or behind when its ring wrote the entry on 2.0.x or 
2.1.x, and is then started on 2.2.x or later. It catches up by log append.
# An SCM stopped uncleanly (crash, kill) after the entry and before a 
transaction buffer flush or snapshot covered it, then started on 2.2.x or 
later. A graceful stop takes a snapshot first and is not affected.

h3. Impact
The affected SCM cannot start on 2.2.0, 2.2.1 or master. If all SCMs were 
stopped uncleanly right after such an entry, no SCM can start. No data loss. A 
workaround (argued, not run) is to start the stuck SCM on 2.1.x until it has 
applied the entry, then upgrade it again.

h3. Fix
As in HDDS-16169, {{ContainerStateManager}} declares 
{{transitionDeletingOrDeletedToClosedState(ContainerID)}} again as 
{{@Deprecated}} and {{@Replicate}}, {{ContainerStateManagerImpl}} delegates it 
to {{transitionDeletingOrDeletedToTargetState}} with CLOSED (the same checks 
and result as 2.1), and {{ContainerStateManagerInvoker}} is regenerated. 
Nothing on master calls it. No Raft log or proto change.

{{TestContainerStateManager#testApplyLegacyTransitionDeletingOrDeletedToClosedState}}
 encodes the entry as 2.1 does and applies it through the SCM Ratis server stub 
for a DELETING and a DELETED container. Without the fix it fails with the 
{{Method not found}} error above. With it the container ends CLOSED.

A comparison of the {{@Replicate}} methods in 2.0, 2.1 and 2.2.1 with the 
{{invokeLocal}} cases on master finds no other missing method besides the ones 
tracked in HDDS-17421 ({{FinalizationStateManager}}) and HDDS-17447 
({{DeletedBlockLogStateManager}}).

Found while reviewing the fix for HDDS-17447. Checked against HDDS issues and 
apache/ozone pull requests for duplicates before filing. Generated with Claude 
Code (Claude Opus 5.5).



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

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

Reply via email to