You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@ozone.apache.org by "Siyao Meng (Jira)" <ji...@apache.org> on 2026/10/21 13:43:00 UTC
[jira] [Created] (HDDS-17244) Quota repair skips deleted snapshots that are not purged yet, so the pending deletes they still hold drop out of the bucket's snapshotUsedBytes
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: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org