Skip to content

HDDS-16755. Uncommitted block cleanup can delete a block that a snapshot of an hsync'ed key still references - #11437

Draft
smengcl wants to merge 1 commit into
apache:masterfrom
smengcl:HDDS-16755
Draft

smengcl wants to merge 1 commit into
apache:masterfrom
smengcl:HDDS-16755

Conversation

@smengcl

@smengcl smengcl commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Generated-by: Claude Code (Opus 5.5)

What changes were proposed in this pull request?

A block that an hsync committed and that a later hsync or the final commit leaves out is released as an uncommitted block when the key is closed. OMKeyRequest.wrapUncommittedBlocksAsPseudoKey wrapped it in a pseudo key with object ID OBJECT_ID_RECLAIM_BLOCKS (0) before putting it in deletedTable. ReclaimableKeyFilter treats an object ID mismatch with the previous snapshot's key as reclaimable, so KeyDeletingService deleted the block even when a snapshot taken after the hsync still listed it. Reads of the key through that snapshot then fail. The active key is not affected.

The pseudo key now keeps the object ID of the key. Together with the hsync metadata it already carries (callers wrap before they remove HSYNC_CLIENT_ID, which the helper now documents), SnapshotUtils.isBlockLocationInfoSame retains the row while the previous snapshot holds an hsync'ed version of the key. This also covers the case where the previous snapshot does not list the block itself: hsync [A, B], snapshot S1, hsync [A, C], snapshot S2, commit [A, C]. The row becomes reclaimable once no previous snapshot holds an hsync'ed version of the key.

The deletedTable row name is derived from the transaction index, not the object ID, so rows do not collide. The same helper serves OMKeyCommitRequestWithFSO and S3MultipartUploadCommitPartRequest.

Notes for reviewers:

  • While the previous snapshot holds an hsync'ed version of the key, the whole pseudo row is retained, including blocks that no snapshot references.
  • A retained pseudo row counts toward that snapshot's exclusive size.
  • OBJECT_ID_RECLAIM_BLOCKS and its exemption in WithObjectID.validate are now unused. They are left in place to keep this patch small and can be removed in a follow up.
  • The test drives OM directly. Whether an unmodified client can drop a block it has already hsync'ed is not established.

What is the link to the Apache JIRA

https://issues.apache.org/jira/browse/HDDS-16755

How was this patch tested?

  • New TestKeyDeletingService.testUncommittedBlockOfHsyncedKeyRetainedBySnapshot runs the two snapshot sequence above. The deletedTable row for B must stay while S2 is the previous snapshot and after S2 is deleted, and must be purged only after S1 is deleted. It fails without the fix, and also with the object ID kept but the hsync metadata removed from the pseudo key.
  • TestOMKeyCommitRequest.testValidateAndUpdateCacheOnOverwriteWithUncommittedBlocks now asserts that the pseudo key keeps a non zero object ID, for OBS and FSO. It fails without the fix.
  • Ran TestKeyDeletingService$Normal, TestOMKeyCommitRequest, TestOMKeyCommitRequestWithFSO, both TestS3MultipartUploadCommitPartRequest variants, TestOpenKeyCleanupService, TestReclaimableKeyFilter and TestSnapshotUtils locally, plus checkstyle on ozone-manager.

…hot of an hsync'ed key still references

A block committed by an hsync and left out of a later hsync or of the final commit is released as an uncommitted block when the key is closed. Its pseudo key in the deleted table had object ID 0, so ReclaimableKeyFilter never matched it with the key in the previous snapshot and KeyDeletingService deleted the block, even when a snapshot taken after the hsync still listed it.

The pseudo key now keeps the object ID of the key. Together with the hsync metadata it already carries, this retains it while the previous snapshot holds an hsync'ed version of the key. The deleted table row name is still derived from the transaction index, so rows do not collide.

Tested with TestKeyDeletingService (new testUncommittedBlockOfHsyncedKeyRetainedBySnapshot), TestOMKeyCommitRequest and TestOMKeyCommitRequestWithFSO. The new test fails without the fix, and also with the object ID kept but the hsync metadata removed from the pseudo key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 7, 2026 17:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused fix correctly preserves snapshot identity and includes appropriate regression coverage.

0 open findings

What changed in this PR

Prevents snapshot-referenced hsync blocks from being prematurely reclaimed.

Changes:

  • Preserve object IDs and hsync metadata on uncommitted-block pseudo keys.
  • Add regression and object-ID preservation tests.
File Description
OMKeyRequest.java Preserves pseudo-key identity and hsync metadata.
TestKeyDeletingService.java Tests snapshot-safe block retention and cleanup.
TestOMKeyCommitRequest.java Verifies pseudo keys retain object IDs.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@smengcl smengcl added bug Something isn't working AI-gen snapshot https://issues.apache.org/jira/browse/HDDS-6517 labels Oct 7, 2026
@github-actions github-actions Bot added the om label Oct 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI-gen bug Something isn't working om snapshot https://issues.apache.org/jira/browse/HDDS-6517

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants