[
https://issues.apache.org/jira/browse/HDDS-16832?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Siyao Meng updated HDDS-16832:
------------------------------
Attachment: TestBugCR6OldOMCannotInstallCheckpointFromFirstNewOM.java
> OM that started as a single node fails every checkpoint install from the
> first OM bootstrapped onto it with a NullPointerException
> ----------------------------------------------------------------------------------------------------------------------------------
>
> Key: HDDS-16832
> URL: https://issues.apache.org/jira/browse/HDDS-16832
> Project: Apache Ozone
> Issue Type: Bug
> Reporter: Siyao Meng
> Priority: Major
> Attachments:
> CR-6-add-first-bootstrapped-om-to-snapshot-provider.patch,
> TestBugCR6OldOMCannotInstallCheckpointFromFirstNewOM.java
>
>
> h3. Mechanism
> An OM that starts with no peers has no {{OmRatisSnapshotProvider}}.
> {{OzoneManager.addOMNodeToPeers}} creates it when the first OM is
> bootstrapped, from {{peerNodesMap}} as it is before the new node is put in,
> and only the {{else}} branch (the provider already exists) calls
> {{addNewPeerNode}}. The provider keeps its own copy of the map, so the first
> bootstrapped OM is never in it. OMs bootstrapped later are added.
> {{OmRatisSnapshotProvider.downloadSnapshot}} uses the result of
> {{peerNodesMap.get(leaderNodeID)}} without a null check. When the first
> bootstrapped OM is leader and notifies the original OM to install a snapshot,
> the lookup returns null and a {{NullPointerException}} leaves
> {{OzoneManager.installSnapshotFromLeader}}, which catches only
> {{IOException}}. Ratis logs "Failed to notify StateMachine to
> InstallSnapshot" and the leader sends the notification again. Nothing adds
> the missing peer later, because {{OzoneManager.updatePeerList}} only adds
> nodes that the Ratis server's peer list does not have yet.
> The {{addOMNodeToPeers}} block is the same in the release tags from 1.2.0 to
> 2.2.1 (read from the tagged source, not run there). It came in with HDDS-4330.
> h3. Trigger
> # One OM runs with a service ID as a single node ring.
> # Two more OMs are bootstrapped. The existing OM is not restarted, which the
> OM HA documentation says is not needed.
> # The first bootstrapped OM becomes leader.
> # The original OM falls behind the leader's purged log while its process
> stays up (a partition or a long pause), so the leader notifies it to install
> a snapshot.
> h3. Impact
> The original OM cannot catch up while the first bootstrapped OM leads. It
> stays a member of the ring but no longer counts towards the commit majority,
> so the ring cannot tolerate the loss of the other follower. Nothing reports
> this except the ERROR lines in the original OM's log. There is no data loss.
> Restarting the original OM is a workaround, because the provider is then
> built from the configuration.
> Run on a mini cluster with a short Raft log (purge gap and snapshot threshold
> of 50): the original OM stayed at applied index 8 while the leader was at
> 102, with 100 to 200 failed install attempts per second (2138 in 20 seconds
> in one run, 3994 in 21 seconds in another), each one an ERROR line on the
> original OM. A write with all three OMs up succeeded. With the second
> bootstrapped OM stopped, a write did not complete within 20 seconds. After
> the original OM was stopped and started again as a new {{OzoneManager}} from
> its configuration and storage directory, it installed a checkpoint from the
> same leader and a write succeeded.
> Not exercised: default log settings (snapshot every 400,000 transactions, so
> the OM has to miss far more), a real network partition, a secure cluster, and
> the conversion of an OM that had no service ID.
> h3. Reproduction
> PASS in 2 of 2 runs on unmodified source.
> [^TestBugCR6OldOMCannotInstallCheckpointFromFirstNewOM.java]
> ({{hadoop-ozone/integration-test}}) starts a mini cluster with one OM,
> bootstraps two OMs, transfers leadership to the first and writes through the
> client. The original OM is made to miss the transactions without a restart by
> rejecting the {{appendEntries}} and {{installSnapshot}} calls it receives,
> through the Ratis {{CodeInjectionForTesting}} hooks at the start of these
> handlers. This stands for a partition and changes no state. The hooks are
> then removed and the test observes the failed attempts, the two writes and
> the restart. A passing test means the defect is present.
> h3. Suggested fix
> The attached patch removes the cause. A null check in
> {{OmRatisSnapshotProvider.downloadSnapshot}} that throws an {{IOException}}
> naming the unknown leader would in addition send any future missing peer
> through the handled error path. It is not in the patch, since it makes no
> install succeed.
> h3. Patch
> [^CR-6-add-first-bootstrapped-om-to-snapshot-provider.patch], against
> 7fcf31294859d5d31163e016b5a9a63f21c6edd2. It also applies to master at
> 1cc6423590f (not built there).
> {{OzoneManager.addOMNodeToPeers}} now calls {{addNewPeerNode}} for the new OM
> whether the provider already existed or was just created. For an OM that
> starts with peers nothing changes.
> Covered by an addition to the existing
> {{TestAddRemoveOzoneManager.testBootstrap}}: after the two OMs are
> bootstrapped, leadership moves to the first new OM, the old OM downloads a
> checkpoint from it through its snapshot provider, and leadership moves back.
> Without the change it fails with the {{NullPointerException}} above. With it
> {{TestAddRemoveOzoneManager}}, {{TestOMInstallSnapshotDuringBootstrapping}}
> and {{TestOzoneManagerSnapshotProvider}} pass (10 tests), as do
> {{TestOzoneManagerStateMachine}}, {{TestOmRatisSnapshotProvider}} and
> {{TestOzoneManagerRatisServer}} (74 tests), and checkstyle is clean. With the
> patch the reproduction class fails at the assertion that expects the original
> OM to stay behind, with 0 failed install attempts.
> Found by code review of the OM HA membership change paths (bootstrap,
> decommission and leader transfer), as part of the TLA+ verification effort
> under HDDS-15926, on commit 7fcf31294859d5d31163e016b5a9a63f21c6edd2. 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]