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

Siyao Meng updated HDDS-16920:
------------------------------
    Attachment: MC-2-create-db-marker-before-moving-scm-db.patch

> SCM creates the DB inconsistent marker only after moving scm.db away, so a 
> stop in between restarts on an empty DB
> ------------------------------------------------------------------------------------------------------------------
>
>                 Key: HDDS-16920
>                 URL: https://issues.apache.org/jira/browse/HDDS-16920
>             Project: Apache Ozone
>          Issue Type: Bug
>            Reporter: Siyao Meng
>            Priority: Minor
>         Attachments: MC-2-create-db-marker-before-moving-scm-db.patch, 
> TestBugMC2CrashAfterDBMoveOpensEmptyDB.java
>
>
> h3. Mechanism
> {{HAUtils.replaceDBWithCheckpoint}} renames {{scm.db}} to 
> {{scm.db.backup.<index>_<time>}} and only then creates 
> {{dbInconsistentMarker}}. The marker is meant to stop SCM from starting on a 
> half installed DB ("this marker file will fail it from starting up"). If the 
> process stops between the rename and the marker, the directory has neither 
> {{scm.db}} nor the marker. On the next start {{SCMMetadataStoreImpl.start}} 
> checks only the marker, and {{DBStoreBuilder.createDBStore}} creates a new 
> empty DB because {{createIfMissing}} is true. The old DB stays in the backup 
> directory and nothing restores or deletes it.
> h3. Trigger
> # A follower SCM installs a checkpoint from the leader 
> ({{SCMHAManagerImpl.installCheckpoint}}).
> # The SCM process stops (kill, OOM) right after {{Files.move}} of {{scm.db}} 
> and before {{Files.createFile}} of the marker. The window is two consecutive 
> file system calls; in the reproduction the stop is injected.
> h3. Impact
> * The SCM starts on an empty {{scm.db}} without any error, against the marker 
> contract. Its old DB is left orphaned in {{scm.db.backup.*}}.
> * Committed state is not lost cluster wide (the other SCMs have it). The 
> window is entered only after Ratis acknowledged the install, so with the 
> current code the follower cannot catch up afterwards anyway, whether it 
> restarts on the empty DB or on the old one. As long as it stays a follower it 
> does not start its datanode server, so no datanode report is processed 
> against the empty DB (argued, not run).
> h3. Reproduction
> PASS on the unmodified source. [^TestBugMC2CrashAfterDBMoveOpensEmptyDB.java] 
> ({{hadoop-hdds/server-scm}}) writes a real SCM DB with a container and a 
> transaction info, runs {{HAUtils.replaceDBWithCheckpoint}} with a static 
> {{Files.move}} spy that does the real move and then throws an {{Error}} (the 
> stop), and opens a new {{SCMMetadataStoreImpl}} on the same directory. 
> Output: {{after the crash: scm.db exists=false, marker exists=false, 
> backups=1}}, then {{restart accepted, scm.db exists=true, 
> transactionInfo=null, container #1=null}}. A passing test means the defect is 
> present.
> h3. Patch
> [^MC-2-create-db-marker-before-moving-scm-db.patch], against 
> b0aa6475b7856d2c7f467dd3db12b9a1dd116f63. It also applies to master at 
> 52812559dad.
> The patch creates the marker before the move and deletes it again if the move 
> fails, so a failed backup leaves the directory unchanged. The rest of the 
> method is unchanged. A stop anywhere between the move and the end of the copy 
> now leaves the marker, and the existing check refuses to start ("Cannot load 
> SCM DB as it is in an inconsistent state"). With the patch the reproduction 
> fails because the marker exists after the stop.
> Covered by {{testReplaceDBWithCheckpointCreatesMarkerBeforeMovingDB}} and 
> {{testReplaceDBWithCheckpointRemovesMarkerIfMoveFails}} in a new 
> {{TestHAUtils}} (there is no existing unit test class for {{HAUtils}}). 
> Without the change the first fails with "Expecting AtomicBoolean(false) to 
> have value: true". With it {{TestHAUtils}}, {{TestRDBSnapshotProvider}} and 
> {{TestSCMHAUtils}} (5 tests) and the mini cluster suites 
> {{TestSCMInstallSnapshotWithHA}} and {{TestSCMInstallSnapshot}} (5 tests) 
> pass, and checkstyle is clean. The patch does not add an fsync of the marker 
> or the directory, so it covers a process stop; after a power loss the file 
> system may still persist the rename without the marker.
> {{OzoneManager.replaceOMDBWithCheckpoint}} still moves the {{om.db}} items to 
> the backup before {{moveCheckpointFiles}} creates the marker (by code 
> reading); HDDS-16026 changed its failure handling, not this order, and the OM 
> side is a separate follow up that this patch does not change.
> 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 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