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

Siyao Meng updated HDDS-17741:
------------------------------
    Attachment: MC-7-replace-job-and-queue-old-report-in-one-write.patch

> OM crash during an ordered snapshot diff resubmit can leave a DONE job whose 
> report the cleanup then deletes
> ------------------------------------------------------------------------------------------------------------
>
>                 Key: HDDS-17741
>                 URL: https://issues.apache.org/jira/browse/HDDS-17741
>             Project: Apache Ozone
>          Issue Type: Bug
>    Affects Versions: 2.3.0
>            Reporter: Siyao Meng
>            Priority: Minor
>         Attachments: 
> MC-7-replace-job-and-queue-old-report-in-one-write.patch, 
> TestBugMC7CrashDuringResubmitLosesDoneReport.java
>
>
> h3. Mechanism
> With {{ozone.om.snapshot.diff.optimized.enabled}} = true (default false), on 
> an FSO bucket, an ordered request for a pair whose job is DONE (or QUEUED) 
> with an unordered report replaces that job. 
> {{SnapshotDiffManager.createSnapDiffJob}} does this with two separate RocksDB 
> writes: {{enqueueSnapshotDiffReportCleanup}} puts the old job ID into the 
> purged job table, then the new job is put into the job table. If the OM 
> process dies between the two writes, or the second write fails without a 
> crash (the case the regression test simulates), the old job is still the DONE 
> job of its key while its report is queued for deletion. The next 
> {{SnapshotDiffCleanupService}} run deletes the report rows of every queued 
> job ID without looking at the job table, and {{loadJobsOnStartUp}} only 
> handles IN_PROGRESS jobs.
> h3. Trigger
> # An unordered snapshot diff of a pair finishes DONE.
> # The same pair is submitted with an ordered report.
> # The OM process dies after the first write of the resubmit and before the 
> second.
> # After the restart, a cleanup run happens before the job expires.
> h3. Impact
> The job stays DONE but its report is gone. Every read of it fails, at the 
> moment with the NullPointerException of HDDS-16442 in 
> {{checkReportsIntegrity}}, until the job expires (default 7 days) or someone 
> submits an ordered request again. With HDDS-16442 fixed, the first read would 
> mark the job FAILED and return an error, and the next submit of the pair 
> would recompute it (argued from the code, not run). Only the snapshot diff 
> report is affected.
> h3. Reproduction
> PASS, deterministic, unmodified source. 
> [^TestBugMC7CrashDuringResubmitLosesDoneReport.java] 
> ({{hadoop-ozone/ozone-manager}}) runs the real {{SnapshotDiffManager}} and 
> {{SnapshotDiffCleanupService}} on a real RocksDB with the rest of the OM 
> mocked. A stand in for the report generation task writes three report rows 
> and publishes DONE through the real {{updateJobStatusToDone}}. The crash is 
> modelled by failing the serialization of the new job, which happens after the 
> first write and before the second; the restart is a new 
> {{SnapshotDiffManager}} on the same DB. A real process kill was not run. 
> Output on d3b75c75bf9ad475551202477c3a21a3f4b968b7: the old job is queued for 
> purge after the crash, and after the restart and one cleanup run the job is 
> still DONE with 0 of 3 report rows, and reading it throws. A passing test 
> means the defect is present.
> h3. Patch
> [^MC-7-replace-job-and-queue-old-report-in-one-write.patch], against 
> d3b75c75bf9ad475551202477c3a21a3f4b968b7. It also applies to master at 
> bbc8505e00d.
> When a previous job exists, {{createSnapDiffJob}} now writes the purged table 
> entry of the old job and the new job in one {{ManagedWriteBatch}} 
> ({{replaceSnapDiffJob}}), so either both are durable or neither is. A first 
> submission still uses a plain put. A failed write now fails the resubmit and 
> leaves the old job as it was, where it used to be logged while the resubmit 
> went on.
> Covered by {{testResubmitQueuesReplacedJobForCleanupOnlyWithItsReplacement}} 
> in the existing {{TestSnapshotDiffManager}}: with the write of the new job 
> failing, the ordered resubmit must leave the DONE job and no purged entry; 
> without the failure it must replace the job and queue the old one. Without 
> the change the first part fails because the old job is queued. With it 
> {{TestSnapshotDiffManager}}, {{TestSnapshotDiffCleanupService}} and 
> {{TestSnapshotDiffManagerMXBean}} (88 tests) pass, checkstyle is clean, and 
> the reproduction fails because all three rows remain and the read succeeds.
> Found by TLA+ model checking and code review of the OM optimized snapshot 
> diff paths under HDDS-15926, on commit 
> d3b75c75bf9ad475551202477c3a21a3f4b968b7. 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
(v10.3.26#10030026)

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

Reply via email to