Siyao Meng created HDDS-17244:
---------------------------------

             Summary: Quota repair skips deleted snapshots that are not purged 
yet, so the pending deletes they still hold drop out of the bucket's 
snapshotUsedBytes
                 Key: HDDS-17244
                 URL: https://issues.apache.org/jira/browse/HDDS-17244
             Project: Apache Ozone
          Issue Type: Bug
            Reporter: Siyao Meng
         Attachments: 
CR-14-quota-repair-scans-deleted-snapshots-not-yet-purged.patch, 
TestBugCR14DeletedSnapshotSkipped.java

h3. Mechanism
{{QuotaRepairTask.recalculateSnapshotDbPendingDeleteQuota}} recomputes 
{{snapshotUsedBytes}} and {{snapshotUsedNamespace}} from the active DB 
checkpoint and from the snapshot DBs on the repaired buckets' snapshot chains, 
but it skips every snapshot whose status is not {{SNAPSHOT_ACTIVE}} 
({{loadActiveSnapshot}} on this commit; the patch of HDDS-17241, which lists 
the snapshots from the checkpoint's snapshot table instead of the live chain, 
keeps the same filter), so deleted snapshots are not scanned.

Deleting a snapshot ({{OMSnapshotDeleteRequest}}) only sets its status to 
{{SNAPSHOT_DELETED}}. Its deleted keys, deleted directories and renamed entries 
stay in its DB until {{SnapshotDeletingService}} moves them to the next active 
snapshot or to the active DB ({{OMSnapshotMoveTableKeysRequest}}, which also 
removes them from the deleted snapshot's DB) and then purges the snapshot. None 
of these requests changes the bucket's counters: an entry is charged to 
{{snapshotUsed*}} from the key delete until {{OMKeyPurgeRequest}} or 
{{OMDirectoriesPurgeRequestWithFSO}} purges it. So while a deleted snapshot 
still holds entries, they are pending and charged, and nothing else in the 
repair counts them. The deleted snapshot's DB is still available 
({{OmSnapshotManager.getSnapshot(UUID)}} does not require an active snapshot, 
and {{SnapshotDeletingService}} also opens deleted snapshots).

h3. Trigger
* A snapshot of the bucket that was deleted and still holds deleted keys or 
directories of the bucket. That lasts until {{SnapshotDeletingService}} has 
moved them out, at least one run of the service, longer for large snapshots 
(the moves are batched) and while the next snapshot in the chain is also 
deleted (the service then skips the snapshot).
* A quota repair of that bucket ({{ozone repair om quota start}}, admin only) 
in that window.

h3. Impact
* {{snapshotUsedBytes}} and {{snapshotUsedNamespace}} of the bucket end too low 
by what the deleted snapshot still holds (reproduced: 0 and 0 where 3000 and 1 
are correct). The value is written to RocksDB and stays until a repair runs 
outside the window.
* By the code, not run: when those entries are purged later, the purge 
subtracts them again, so the counters stay too low (negative if nothing else is 
pending), and the quota checks, which use used plus snapshotUsed, accept writes 
beyond the bucket's quota by that amount.

h3. Reproduction
[^TestBugCR14DeletedSnapshotSkipped.java] goes into 
{{hadoop-ozone/ozone-manager}} (target package and Maven command in the class 
comment) and passes on unmodified source while the bug is present. It deletes a 
key, takes a snapshot with the real {{OMSnapshotCreateRequest}} (which moves 
the deleted key's row from the active DB into the snapshot DB), deletes the 
snapshot with the real {{OMSnapshotDeleteRequest}}, then runs 
{{QuotaRepairTask}} and applies the request it submits: the bucket ends at 0 
and 0 although the row is still in the deleted snapshot's DB. A control with 
the snapshot left active ends at 3000 and 1.

h3. Patch
This patch should land together with or after the one of HDDS-17243. Without 
it, the newly scanned deleted snapshots are read in full, every bucket's copies 
included: that adds the overcount of HDDS-17243 for the deleted snapshots too, 
and a long scan of a snapshot that {{SnapshotDeletingService}} is about to 
purge can hold up that purge, which closes the snapshot DB and takes its lock 
while the repair still has it open, and with it the OM's double buffer flush 
until the scan ends (argued from the code, not run). With the prefix scan of 
HDDS-17243 the scan of an emptied deleted snapshot is near instant.

[^CR-14-quota-repair-scans-deleted-snapshots-not-yet-purged.patch] applies on 
top of the patch of HDDS-17241 (against 
20d95ed37fe35013b5320713665db03c06ee36fa plus that patch); the two also apply 
to master at 64d4a791502. It does not conflict with the patch for pending 
deletes of other buckets counted from snapshot DBs (filed separately): either 
applies on top of the patch of HDDS-17241 alone or together with the other, in 
either order.

The status check is removed, so the repair scans every snapshot of the bucket 
that is in the checkpoint's snapshot info table, active or deleted. A purged 
snapshot is gone from the table and is not scanned, as before; one purged after 
the checkpoint fails the run through the check HDDS-17241 adds, like any other 
snapshot change during the scan. This does not count an entry twice. A move 
takes the entries out of the deleted snapshot's DB when it writes them to the 
destination, so a move completed before the repair is counted once, at the 
destination. The two writes are separate RocksDB commits, but the move updates 
{{lastTransactionInfo}} of both snapshots in the snapshot info cache when it is 
applied, so a repair that overlaps a move fails through the check HDDS-17241 
adds.

Covered by {{testQuotaRepairCountsDeletedSnapshotsNotYetPurged}} in the 
existing {{TestQuotaRepairTask}}: three snapshots, the first two deleted. The 
first still holds its key (its next snapshot is deleted too), and the second 
has already moved its key to the third, active one with the real 
{{OMSnapshotMoveTableKeysRequest}}, so the test checks both the missing count 
and that a moved entry is counted once. On top of the HDDS-17241 patch it fails 
without the change ("expected: <3000> but was: <2000>"); with it, 
{{TestQuotaRepairTask}} and {{TestOMQuotaRepairRequest}} (22 tests) pass, 
{{TestOzoneRepairShell}} on a mini cluster passes with both snapshot scan 
patches applied, and checkstyle is clean. With the patch the reproduction's 
deleted snapshot test fails because the bucket is repaired to 3000 and 1, and 
its control passes.

Found during review of a fix for the OM quota repair, as part of the TLA+ 
verification effort under HDDS-15926, on commit 
20d95ed37fe35013b5320713665db03c06ee36fa. Related to HDDS-17241, whose fix 
changes the same loop. 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