[ 
https://issues.apache.org/jira/browse/HDDS-16905?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Siyao Meng updated HDDS-16905:
------------------------------
    Attachment: MC-6-remove-stale-node-pipelines-on-scm-reinitialize.patch

> SCM keeps deleted pipelines in its datanode to pipeline map after a Ratis 
> snapshot install, so decommission and maintenance stall while it is leader
> ----------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: HDDS-16905
>                 URL: https://issues.apache.org/jira/browse/HDDS-16905
>             Project: Apache Ozone
>          Issue Type: Bug
>            Reporter: Siyao Meng
>            Priority: Minor
>         Attachments: 
> MC-6-remove-stale-node-pipelines-on-scm-reinitialize.patch, 
> TestBugMC6StaleNode2PipelineAfterSnapshotInstall.java
>
>
> h3. Mechanism
> When a follower SCM installs a snapshot from the leader, 
> {{SCMHAManagerImpl.startServices}} calls 
> {{PipelineStateManagerImpl.reinitialize}}. It replaces the 
> {{PipelineStateMap}} with an empty one and {{initialize}} adds every pipeline 
> of the new pipeline table to the state map and to the NodeManager 
> ({{nodeManager.addPipeline}}). The pipelines of the old map are never removed 
> from the NodeManager. The datanode to pipeline map ({{Node2PipelineMap}}) is 
> only updated by {{PipelineStateManagerImpl}}, and its only removal path, 
> {{PipelineStateManagerImpl.removePipeline}}, needs the pipeline to be in the 
> state map. So a pipeline that was closed and deleted while the follower was 
> behind stays listed for its datanodes until that SCM process restarts.
> {{DatanodeAdminMonitorImpl.checkPipelinesClosedOnNode}}, the first gate for 
> decommission and for entering maintenance, waits until 
> {{nodeManager.getPipelines(dn)}} is empty, and decommission has no expiry. 
> {{StartDatanodeAdminHandler}} cannot close the stale pipeline either, because 
> the pipeline manager does not know it.
> h3. Trigger
> # {{ozone.scm.ha.ratis.log.purge.enabled=true}} (default false). Without log 
> purge the leader keeps its whole log and sends a lagging follower entries 
> instead of a snapshot (read from code).
> # A follower SCM knows pipeline P. It is stopped (or falls behind) while the 
> leader closes and deletes P and purges its Raft log past the follower's last 
> index.
> # The follower catches up by installing a snapshot 
> ({{SCMStateMachine.reinitialize}}). Its NodeManager still lists P for P's 
> datanodes.
> # That SCM becomes leader and an operator decommissions a datanode of P.
> Only the restart variant of step 2 was run. A live follower that is sent a 
> snapshot takes the same path (argued from code).
> h3. Impact
> * The decommission of every datanode that was in such a pipeline stays in 
> DECOMMISSIONING without an error while that SCM is leader. The monitor logs 
> "Waiting for pipelines to close ... There are 1 pipelines" on every run. 
> Restarting that SCM clears the stale entries (read from code, not run). 
> Moving leadership to another SCM should also let the decommission continue, 
> since the other SCMs have a correct map (argued, not run).
> * A datanode entering maintenance waits on the stale entry the same way, 
> until its maintenance end time passes, or forever if no end time was given 
> (argued, not run).
> * {{NodeManager.getPipelinesCount}} and the pipeline count in datanode usage 
> info include the stale entries (argued, not run). Pipeline placement is not 
> affected, because it ignores pipeline IDs the state manager does not know.
> h3. Reproduction
> PASS, unmodified source. 
> [^TestBugMC6StaleNode2PipelineAfterSnapshotInstall.java] 
> ({{hadoop-ozone/integration-test}}) starts 3 SCMs, 1 OM and 3 datanodes with 
> log purge enabled and the small purge gap and snapshot threshold that 
> {{TestSCMInstallSnapshotWithHA}} uses. It stops a follower, closes an open 
> RATIS/THREE pipeline with the admin close pipeline RPC and lets the leader's 
> scrubber delete it, advances the Raft log by 200 entries with in process 
> {{ContainerManager.allocateContainer}} calls on the leader, restarts the 
> follower, which installs a snapshot, transfers leadership to it and 
> decommissions one datanode of the deleted pipeline. Output on the pin: after 
> the snapshot install the restarted SCM does not know the pipeline but lists 
> it for the datanode, and after 8 monitor runs the datanode is still 
> DECOMMISSIONING with exactly that pipeline left. A passing test means the 
> defect is present. With the patch it fails at the first check after the 
> snapshot install, because the datanode then lists only its live pipelines.
> h3. Patch
> [^MC-6-remove-stale-node-pipelines-on-scm-reinitialize.patch], against 
> b0aa6475b7856d2c7f467dd3db12b9a1dd116f63. It also applies to master at 
> b9b33851b20.
> {{PipelineStateManagerImpl.reinitialize}} removes the pipelines of the old 
> state map from the NodeManager before it rebuilds the map; {{initialize}} 
> adds the pipelines of the new table back as before. The NodeManager then 
> lists exactly the pipelines of the new state map. Recon's SCM DB snapshot 
> sync ({{ReconStorageContainerManagerFacade.initializeNewRdbStore}}) calls the 
> same {{reinitialize}} and gets the same fix (read from code, not run). 
> Covered by {{testReinitializeRemovesPipelinesMissingFromNewStore}} in the 
> existing {{TestPipelineStateManagerImpl}} (two pipelines on one datanode, 
> reinitialize with a table that keeps one), which fails without the change. 
> With it the pipeline and node unit suites touched by this path (132 tests) 
> and {{TestSCMInstallSnapshotWithHA}} and {{TestSCMInstallSnapshot}} pass, 
> checkstyle is clean. Entries left on an SCM that already installed a snapshot 
> are only cleared by a restart.
> Found by TLA+ model checking and code review of the SCM pipeline lifecycle 
> paths under HDDS-15926, on commit b0aa6475b7856d2c7f467dd3db12b9a1dd116f63. 
> Checked against HDDS issues and apache/ozone pull requests for duplicates 
> before filing. The attached patch is a proposal for review. 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