Siyao Meng created HDDS-17747:
---------------------------------

             Summary: DAG snapshot diff misses the DELETE of a directory that 
is deleted and replaced at the same path within one flush
                 Key: HDDS-17747
                 URL: https://issues.apache.org/jira/browse/HDDS-17747
             Project: Apache Ozone
          Issue Type: Bug
            Reporter: Siyao Meng
         Attachments: CR-3-load-from-dir-row-for-every-delta-key.patch, 
TestBugCR3DirectoryReplacedAtSameKey.java

h3. Mechanism
{{DagDiffSequentialReader.scanFromDirectoryTable}} loads a from snapshot 
directory row into the old list only when its objectId was seen as a put in the 
directory delta, or when its table key had a tombstone in the delta. After {{rm 
-r d}} and {{mkdir d}} with no flush in between, both writes hit the same 
{{directoryTable}} key and RocksDB drops the tombstone at flush, so the delta 
holds only the put of the new objectId. The same happens when another directory 
is renamed onto the freed path ({{rm -r d}}, {{mv x d}}). The old objectId 
passes neither check and never reaches the old list. The merge join then emits 
CREATE d without DELETE d. The file path is not affected because it looks up 
every delta key in the from table.

h3. Trigger
FSO bucket, {{ozone.om.snapshot.diff.optimized.enabled=true}}, native library 
loaded (DAG path, the default):
# Create {{/a/d/f}}, take snapshot snap1.
# {{rm -r /a/d}}, {{mkdir /a/d}}, take snapshot snap2 (no flush in between; the 
snapshot flushes).
# Request the snapshot diff snap1 to snap2, ordered or unordered.

Replacing {{/a/d}} by renaming another directory onto it ({{rm -r /a/d}}, {{mv 
/a/x /a/d}}) in the same flush has the same effect: the report has RENAME a/x 
to a/d but no DELETE a/d (shown at unit level, see Patch). The same change with 
a snapshot (flush) between the delete and the second write is reported 
correctly.

h3. Impact
The report contains {{CREATE a/d}} only. Replaying it onto snap1 keeps the old 
subtree, including {{a/d/f}}, which is gone in snap2. The report is persisted 
and returned for every later read of the pair.

h3. Reproduction
[^TestBugCR3DirectoryReplacedAtSameKey.java] 
({{hadoop-ozone/integration-test}}, needs {{-Drocks_tools_native}}) runs the 
steps for {{a/d}} through the FileSystem and snapshot APIs on a mini cluster, 
plus a control {{b/d}} whose delete and mkdir are separated by a snapshot, in 
the same diff. On the unfixed code it fails with {{Expecting ArrayList: [- 
./b/d, + ./a/d, + ./b/d] ... could not find the following element(s): [- 
./a/d]}}; with the patch it passes.

h3. Patch
[^CR-3-load-from-dir-row-for-every-delta-key.patch], against 
d3b75c75bf9ad475551202477c3a21a3f4b968b7. It also applies to master at 
bbc8505e00d.

{{scanDirectoryDeltaEntries}} now records the table key of every directory 
delta entry, put or tombstone, in the key set it already keeps for tombstones 
(the {{SnapDiffJobStore}} Javadocs of that set are updated; the method names 
are kept). The from side row at a replaced key is then loaded into the old list 
and reported as DELETE. For a key whose objectId did not change the row was 
already loaded, so nothing else changes. The merge iterator cannot be the place 
for this, since the tombstone is no longer in any SST file.

Covered by {{testDirectoryReplacedAtSameKeyWithoutTombstone}} in the existing 
{{TestDagDiffSequentialReader}}, for both shapes: a delta with only the put of 
a new objectId at a key whose from row has another objectId, and a delta with 
the tombstone of a renamed directory plus its put at a key whose from row has 
another objectId. Without the change the replaced objectIds are missing from 
the old list (each shape checked separately). With it the snapshot diff unit 
suites and {{TestSnapshotDiffManager}} (192 tests) and 
{{TestOptimizedSnapshotDiff}} pass, and checkstyle is clean.

Found by code review of the OM optimized snapshot diff paths, as part of the 
TLA+ verification effort 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