Skip to content

[fix](cloud) recycler decrement_delete_bitmap_packed_file_ref_counts method should read delete bitmaps as blobs - #66728

Open
mymeiyi wants to merge 1 commit into
apache:masterfrom
mymeiyi:fix-delete-bitmap-recycler
Open

[fix](cloud) recycler decrement_delete_bitmap_packed_file_ref_counts method should read delete bitmaps as blobs#66728
mymeiyi wants to merge 1 commit into
apache:masterfrom
mymeiyi:fix-delete-bitmap-recycler

Conversation

@mymeiyi

@mymeiyi mymeiyi commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

v2 delete bitmaps are written with blob_put, which appends a suffix to every physical key.
The recycler read the unsuffixed logical key with Transaction::get, treated existing delete bitmap metadata as missing, and skipped standalone-file deletion or packed-file reference-count updates.

### What problem does this PR solve?

Issue Number: close #xxx

Related PR: #xxx

Problem Summary: Versioned delete bitmaps are written with blob_put, which appends a suffix to every physical key. The recycler read the unsuffixed logical key with Transaction::get, treated existing delete bitmap metadata as missing, and skipped standalone-file deletion or packed-file reference-count updates. Read the logical value with blob_get and deserialize it from ValueBuf. Update the recycler test fixture to use the production blob encoding so existing rowset recycling tests cover the failure.

### Release note

None

### Check List (For Author)

- Test: Unit Test added; not run as requested. C++ format check passed.
- Behavior changed: Yes, recycler now reclaims external versioned delete bitmap storage.
- Does this need documentation: No
@mymeiyi
mymeiyi requested a review from liaoxin01 as a code owner August 13, 2026 08:29
Copilot AI lite review requested due to automatic review settings August 13, 2026 08:29
@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@mymeiyi

mymeiyi commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

/review

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.

Pull request overview

Fixes Apache Doris Cloud recycler’s handling of v2 delete-bitmap storage metadata by reading versioned delete-bitmap keys as blob values (which include a physical-key suffix due to blob_put), preventing false “missing delete bitmap” behavior during recycling.

Changes:

  • Update InstanceRecycler::decrement_delete_bitmap_packed_file_ref_counts to use cloud::blob_get + ValueBuf::to_pb instead of Transaction::get + ParseFromString.
  • Update recycler unit test helper to write v2 delete-bitmap storage metadata using cloud::blob_put to match production behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
cloud/test/recycler_test.cpp Aligns v2 delete-bitmap metadata setup with blob-based writes (blob_put) so tests exercise the real storage format.
cloud/src/recycler/recycler.cpp Reads delete-bitmap storage metadata via blob APIs to correctly find suffixed physical keys and parse protobuf from merged blob fragments.

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

@github-actions github-actions Bot 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.

Requesting changes: the blob read fixes the production key-layout mismatch for the ordinary path-v0 case, but cleanup is still incomplete in three supported lifecycle/address variants. Each can report success and then discard the only DBM location while leaving a physical object or packed-file reference live; the inline comments identify clone ownership, legacy dropped-tablet cleanup, and path-version-1 standalone deletion.

Critical checkpoint conclusions:

  • Goal and proof: blob_get plus ValueBuf::to_pb is the right logical read for a single legacy value or normal suffix/split blob, and the updated fixture matches the production blob encoding. It proves only standalone path-v0 cleanup; the three attached variants remain uncovered.
  • Scope and reuse: the code change is small and uses the existing blob abstraction. Transaction/read/parse failures still propagate with identifiers, and no new allocation, hot-loop, memory-safety, or performance issue was found.
  • Concurrency and lifecycle: normal packed cleanup retains transaction-conflict retries, per-slice idempotency, and object-before-KV two-phase deletion. The blocking gaps occur where clone provenance, the legacy tablet path, or path reconstruction skips physical cleanup before metadata destruction.
  • Compatibility and persistence: no new config, protocol, symbol, or storage format is introduced. Legacy unsuffixed and ordinary split values remain readable; existing clone ownership, multi-version mode, and storage-vault path-version fences expose the incomplete behavior.
  • Testing and observability: tests cover the corrected blob encoding only for standalone path v0. They do not cover clone-last ownership, a packed DBM in legacy dropped-tablet recycling, or a path-v1 direct-write DBM. Existing logs also cannot reveal successful deletion of the wrong/missing object key or a corrected packed reference left live.
  • User focus: no additional review focus was supplied, so the full PR and its parallel cleanup paths were reviewed.

No local build or test was run because the authoritative review-runner instructions prohibit builds. git diff --check is clean; the live style/license/title checks and macOS BE UT reported passing at submission time.

std::string dbm_val;
err = txn->get(dbm_key, &dbm_val);
ValueBuf dbm_val;
err = cloud::blob_get(txn.get(), dbm_key, &dbm_val);

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.

[P1] Read clone-shared DBM metadata from its owning instance. Classification and phase-3 cleanup deliberately key a clone rowset through RowsetMetaCloudPB::reference_instance_id, but this helper builds both the DBM key and packed-file key from the clone recycler's instance_id_. If the source recycler decrements the shared refcount first, the clone can be the last owner: this read returns NOT_FOUND, skips standalone/packed cleanup, and cleanup then removes the source DBM range, permanently losing the physical location. Thread the canonical/reference instance into this helper and use it for both keys; please cover clone-last standalone and packed DBMs.

std::string dbm_val;
err = txn->get(dbm_key, &dbm_val);
ValueBuf dbm_val;
err = cloud::blob_get(txn.get(), dbm_key, &dbm_val);

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.

[P1] Apply blob-backed DBM cleanup to the legacy dropped-tablet path too. When should_recycle_versioned_keys() is false, recycle_tablet() decrements only RowsetMetaCloudPB::packed_slice_locations, deletes data/<tablet>/, and then range-removes every v2 DBM KV. A packed DBM lives under data/packed_file and its exact slice location exists only in that DBM value, so a previously corrected packed record remains live permanently after the range removal. Process each visible/restore rowset's DBM before deleting that range, and add a non-versioned dropped-tablet case with a packed DBM.

std::string dbm_val;
err = txn->get(dbm_key, &dbm_val);
ValueBuf dbm_val;
err = cloud::blob_get(txn.get(), dbm_key, &dbm_val);

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.

[P1] Preserve the vault path format when deleting standalone DBMs. BE writes a path-version-1 HDFS-vault DBM as data/<shard>/<tablet>/<rowset>_delete_bitmap.db, but after this read returns STANDALONE_FILE both callers enqueue the fixed path-version-0 delete_bitmap_path. The accessors do not add the shard; deleting the nonexistent v0 object succeeds, and later metadata cleanup discards the only locator while the real v1 object remains. Retain the vault PathFormat or persist the exact standalone path, and cover a path-v1 direct-write DBM.

@mymeiyi

mymeiyi commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants