[
https://issues.apache.org/jira/browse/HDDS-17243?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Siyao Meng updated HDDS-17243:
------------------------------
Attachment:
CR-13-quota-repair-scans-only-own-bucket-rows-of-snapshot-db.patch
> Quota repair counts pending deletes of a bucket again for every snapshot of
> another bucket that holds a copy of them
> --------------------------------------------------------------------------------------------------------------------
>
> Key: HDDS-17243
> URL: https://issues.apache.org/jira/browse/HDDS-17243
> Project: Apache Ozone
> Issue Type: Bug
> Affects Versions: 2.3.0
> Reporter: Siyao Meng
> Priority: Major
> Attachments:
> CR-13-quota-repair-scans-only-own-bucket-rows-of-snapshot-db.patch,
> TestBugCR13SnapshotDbCrossBucketCount.java
>
>
> h3. Mechanism
> {{QuotaRepairTask.recalculateSnapshotDbPendingDeleteQuota}} recomputes
> {{snapshotUsedBytes}} and {{snapshotUsedNamespace}} from the active DB
> checkpoint and from every snapshot DB on the repaired buckets' snapshot
> chains. For a snapshot DB it scans the whole {{deletedTable}} and
> {{deletedDirTable}} ({{recalculateDeletedKeyUsages}},
> {{recalculateDeletedDirNamespace}}) and credits each row to the bucket it
> belongs to.
> A snapshot DB is a checkpoint of the whole OM DB.
> {{OmSnapshotManager.createOmSnapshotCheckpoint}} removes only the snapshot's
> own bucket prefix from the active {{deletedTable}}, {{deletedDirTable}} and
> {{snapshotRenamedTable}}, so the pending deletes of every other bucket stay
> in the active DB and are also copied into the snapshot DB. The repair counts
> them once from the active DB checkpoint and once more from every snapshot DB
> of another bucket that holds a copy. The code that reads or changes a
> snapshot's deleted tables ({{SnapshotDeletingService}} through
> {{KeyManagerImpl.getDeletedKeyEntries}} and {{getDeletedDirEntries}},
> {{OMSnapshotMoveTableKeysRequest}}) always restricts itself to the snapshot's
> bucket prefix, so the copies are never removed from the snapshot DB, and the
> repair keeps counting them even after the real entries have been purged from
> the active DB.
> h3. Trigger
> * A snapshot of bucket A taken while bucket B (any other bucket in the
> cluster) had pending deletes in the active {{deletedTable}} or
> {{deletedDirTable}}.
> * A quota repair that includes both buckets ({{ozone repair om quota start}},
> admin only; a repair without {{--buckets}} includes every bucket). The repair
> scans only the snapshots of the buckets it repairs, so a repair of bucket B
> alone is not affected.
> h3. Impact
> * {{snapshotUsedBytes}} and {{snapshotUsedNamespace}} of bucket B end too
> high by one copy of its rows per snapshot DB of another bucket that holds
> them (reproduced: 6000 bytes and 2 entries where 3000 and 1 are correct, with
> one snapshot of another bucket; 3000 bytes where 1000 is correct, with two).
> The value is written to RocksDB, and every later repair computes the same
> excess again while those snapshots exist.
> * By the code, not run: the quota checks use used plus snapshotUsed, so
> bucket B can reject writes with {{QUOTA_EXCEEDED}} before it reaches its
> quota. On a real cluster the excess can be smaller than one full copy per
> snapshot, because {{SstFilteringService}} drops the SST files of a snapshot
> DB that hold no key of the snapshot's own bucket, and with them some of the
> copies.
> h3. Reproduction
> [^TestBugCR13SnapshotDbCrossBucketCount.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
> one key of bucket B, takes a snapshot of bucket A with the real
> {{OMSnapshotCreateRequest}}, then runs {{QuotaRepairTask}} and applies the
> request it submits: bucket B ends at 6000 bytes and 2 entries. A control
> without the snapshot ends at 3000 and 1.
> h3. Patch
> [^CR-13-quota-repair-scans-only-own-bucket-rows-of-snapshot-db.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 deleted
> snapshots that are not purged yet (filed separately): either applies on top
> of the patch of HDDS-17241 alone or together with the other, in either order.
> The snapshot DB scan now iterates only the snapshot's own bucket prefix,
> {{/volume/bucket/}} in {{deletedTable}} and {{/volumeId/bucketId/}} in
> {{deletedDirTable}}: the same rows that snapshot create removes from the
> active DB and that {{SnapshotDeletingService}} moves. Each pending entry is
> then counted once, from the active DB or from the one snapshot DB that holds
> it, also for a bucket with several snapshots. The scan of the active DB
> checkpoint is unchanged, and a snapshot DB scan now reads only its own
> bucket's rows instead of every deleted row in the cluster. This also takes
> {{SstFilteringService}} out of the picture: it deletes SST files of a
> snapshot DB that hold only other buckets' rows without updating the
> snapshot's {{lastTransactionInfo}}, so before this change a filter run during
> the repair could change what was counted without the check of HDDS-17241
> noticing.
> Covered by {{testQuotaRepairCountsOnlyOwnBucketRowsOfSnapshotDb}} in the
> existing {{TestQuotaRepairTask}}: two FSO buckets with deleted keys and
> directories, and two snapshots of one of them. The first bucket's name and ID
> are string prefixes of the other bucket's, so the test also shows that the
> scan stops at the path separator. On top of the HDDS-17241 patch it fails
> without the change ("expected: <1000> but was: <3000>"); 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
> snapshot test fails because bucket B 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]