HDDS-16118. Release snapshot DB handles before KeyDeletingService submits OM requests - #10987
HDDS-16118. Release snapshot DB handles before KeyDeletingService submits OM requests#10987smengcl wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR addresses a potential circular-wait/deadlock involving KeyDeletingService holding snapshot DB read locks while submitting synchronous OM (Ratis) requests, which can block double-buffer flushing that needs a colliding snapshot DB write lock. The change ensures snapshot DB handles (and their associated SNAPSHOT_DB_LOCK read locks) are released before synchronous OM requests are submitted, while keeping snapshot GC locks held until request completion for correctness.
Changes:
- Close snapshot DB handles (current + previous-snapshot handles opened by reclaimable filters) after the metadata scan and before submitting synchronous OM requests.
- Add
ReclaimableFilter.closeSnapshotDbHandles()to allow early closure of snapshot DB handles without releasing snapshot GC locks. - Add a regression test asserting the snapshot DB handle is closed before
KeyDeletingServicesubmits an OM request.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/service/TestKeyDeletingService.java | Adds a regression test that asserts the snapshot DB handle is closed before OM request submission. |
| hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/filter/ReclaimableFilter.java | Introduces closeSnapshotDbHandles() to close previous snapshot DB handles while retaining snapshot GC locks. |
| hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/service/KeyDeletingService.java | Closes reclaimable-filter snapshot handles and the active snapshot handle before submitting synchronous OM requests. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
if step 2 is synchronous call, is it possible to check if the thread has a read lock before obtaining write lock and upgrade read to write lock instead of waiting for write lock? |
@yandrey321 Thanks for the suggestion. Yes the purge call is synchronous on
|
…haustion deadlock Adds a deterministic KeyDeletingService test that reproduces the circular wait fixed in this change: a deep-clean worker holds a snapshot DB read lock while it submits a synchronous OM request, an OMDoubleBuffer flush thread applies a snapshot purge needing the colliding snapshot DB write lock, and the single double-buffer permit is never released. The scenario is forced with one double-buffer permit (ozone.om.unflushed.transaction.max.count=1) and one snapshot DB lock stripe (ozone.om.lock.stripes.snapshot_db_lock=1) so any snapshot read lock collides with any snapshot write lock. The test hangs and fails without the fix and passes with it.
jojochuang
left a comment
There was a problem hiding this comment.
lgtm.
I can't help but wonder: does DirectoryDeletingService has the same kind of bug?
| } | ||
| submitSetSnapshotRequests(setSnapshotPropertyRequests); | ||
| } | ||
| } |
There was a problem hiding this comment.
the reclaimableKeyFilter is cleaned up here at the end of try-with-resources scope, releasing the snapshot lock.
What changes were proposed in this pull request?
KeyDeletingServiceopens the current snapshot database and may open previous snapshot databases while determining which deleted keys and rename entries are reclaimable. Each open snapshot DB handle retains a stripedSNAPSHOT_DB_LOCKread lock.Previously, these handles remained open while
KeyDeletingServicesubmitted synchronous OM requests. This could form the following circular wait:KeyDeletingServiceworker retains a snapshot DB read lock while synchronously submitting an OM request.OMDoubleBufferFlushThreadapplies an earlier snapshot-purge response that needs a colliding write lock. The KDS and purge snapshots may have different UUIDs mapped to the same lock stripe.ozone.om.unflushed.transaction.max.count.This change releases all snapshot DB handles after the metadata scan and before synchronous OM requests are submitted:
No snapshot database is accessed after the handles are released; subsequent processing uses metadata already materialized in memory.
Regression tests cover the change:
KeyDeletingServicesubmits an OM request.ozone.om.unflushed.transaction.max.count=1) and a single snapshot DB lock stripe (ozone.om.lock.stripes.snapshot_db_lock=1) so a snapshot read lock collides with a snapshot purge's write lock. It hangs without the fix and passes with it.What is the link to the Apache JIRA
https://issues.apache.org/jira/browse/HDDS-16118
How was this patch tested?
TestKeyDeletingServiceregression tests, including one that reproduces the permit-exhaustion deadlock (times out without the fix, passes with it).TestKeyDeletingServiceclass and checkstyle locally; all green.Generated-by: Codex (GPT-5)