Skip to content

Optimize blobstore read syscalls#10975

Open
yy782 wants to merge 5 commits into
pingcap:masterfrom
yy782:optimize-blobstore-read-syscalls
Open

Optimize blobstore read syscalls#10975
yy782 wants to merge 5 commits into
pingcap:masterfrom
yy782:optimize-blobstore-read-syscalls

Conversation

@yy782

@yy782 yy782 commented Jul 9, 2026

Copy link
Copy Markdown

What problem does this PR solve?

Issue Number: close #5078

Problem Summary: Optimize field-level read in BlobStore by merging continuous fields into single system call to reduce IOPS and improve read performance.

What is changed and how it works?

storage/v3: merge continuous field reads into single system call (#5078)

Check List

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)
  • No code

Side effects

  • Performance regression: Consumes more CPU
  • Performance regression: Consumes more Memory
  • Breaking backward compatibility

Documentation

  • Affects user behaviors
  • Contains syntax changes
  • Contains variable changes
  • Contains experimental features
  • Changes MySQL compatibility

Release note

None

Summary by CodeRabbit

  • Bug Fixes

    • Improved how selected fields are read from blobs, ensuring correct results for continuous, hole (skipped), and scattered field selections.
    • Reduced redundant blob reads by batching adjacent field bytes into fewer read operations.
  • Tests

    • Added coverage for continuous, hole, and scattered field-selection patterns.
    • Added test-only instrumentation to confirm the underlying blob read count matches the expected batching behavior.

@ti-chi-bot ti-chi-bot Bot added the release-note-none Denotes a PR that doesn't merit a release note. label Jul 9, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign mengxin9014 for approval. For more information see the Code Review Process.
Please ensure that each of them provides their approval before proceeding.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ti-chi-bot ti-chi-bot Bot added contribution This PR is from a community contributor. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. needs-ok-to-test Indicates a PR created by contributors and need ORG member send '/ok-to-test' to start testing. labels Jul 9, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Hi @yy782. Thanks for your PR.

I'm waiting for a pingcap member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

BlobStore field reads now merge consecutive field indices into contiguous ranges, issuing one read per range while preserving per-field offset and checksum handling. GTest-only read-count instrumentation and coverage validate continuous, hole-containing, and scattered selections.

Changes

Batch Contiguous Field Read

Layer / File(s) Summary
Contiguous field-range read implementation
dbms/src/Storages/Page/V3/BlobStore.cpp
The field-reading loop groups consecutive indices, reads each contiguous byte span once, and processes per-field offsets and checksums within the span.
Read-count instrumentation and selection tests
dbms/src/Storages/Page/V3/BlobStore.h, dbms/src/Storages/Page/V3/tests/gtest_blob_store.cpp
GTest-only counter accessors and storage support the new test, which checks field sizes and read-call counts for continuous, hole-containing, and scattered selections.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant BlobStoreRead as BlobStore::read
  participant BlobStorage
  Caller->>BlobStoreRead: read(FieldReadInfos)
  BlobStoreRead->>BlobStoreRead: group consecutive field indices
  loop for each contiguous range
    BlobStoreRead->>BlobStorage: read(range byte span)
    BlobStorage-->>BlobStoreRead: range buffer
    BlobStoreRead->>BlobStoreRead: process offsets and checksums
  end
  BlobStoreRead-->>Caller: page_map
Loading

Poem

A rabbit hops through blobs of bytes,
Merging fields into fewer flights 🐇
One read where once there were five,
Checksums checked, fields arrive!
Hop, hop, IOPS take flight~

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR implements #5078 by coalescing continuous field reads into one BlobStore read and adding tests that verify the behavior.
Out of Scope Changes check ✅ Passed The added GTest-only counter and debug instrumentation are directly tied to verifying the read optimization and do not appear unrelated.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title is concise and accurately summarizes the main change: optimizing BlobStore read syscalls.
Description check ✅ Passed The description covers the required problem, change summary, tests, side effects, documentation, and release note sections.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
dbms/src/Storages/Page/V3/tests/gtest_blob_store.cpp (2)

1956-1956: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove debug std::cout statements from committed test.

These print statements appear to be leftover debugging output (matching the PR's manual verification screenshots) rather than part of the automated test assertions. They add noise to CI test output on every run.

🧹 Proposed cleanup
-    std::cout << "=== Test 1: Continuous fields {0,1,2,3,4} ===" << std::endl;
     {
         BlobStore::FieldReadInfos read_infos;
         read_infos.emplace_back(BlobStore::FieldReadInfo(buildV3Id(TEST_NAMESPACE_ID, page_id), entry, {0, 1, 2, 3, 4}));
         auto page_map = blob_store.read(read_infos);
         Page page = page_map.at(page_id);
         ASSERT_EQ(page.fieldSize(), 5);
     }

-    std::cout << "=== Test 2: Fields with hole {0,1,3,4} ===" << std::endl;
     {
         ...
     }

-    std::cout << "=== Test 3: Scattered fields {0,2,4} ===" << std::endl;
     {
         ...
     }

Also applies to: 1965-1965, 1974-1974

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@dbms/src/Storages/Page/V3/tests/gtest_blob_store.cpp` at line 1956, Remove
the leftover debug std::cout prints from the gtest_blob_store test so the
committed automated test no longer emits manual-verification noise in CI. Update
the relevant test cases in gtest_blob_store by deleting the test banner output
statements while keeping the actual assertions and behavior intact; use the
surrounding test blocks for the continuous-fields scenarios to locate and clean
all matching debug prints.

1927-1983: 🎯 Functional Correctness | 🔵 Trivial | 🏗️ Heavy lift

Test validates correctness but not the actual optimization (syscall reduction).

The new test only asserts page.fieldSize(), which would pass identically with the old per-field-read implementation. It doesn't verify that contiguous fields are actually merged into fewer read() calls — the core claim of issue #5078 and this PR. The PR description mentions manually counting read() calls via debug output (matching the std::cout lines here), but that verification isn't captured as an automated assertion.

Consider adding a way to count actual read syscalls per test case (e.g., via a mock/counting FileProvider or BlobFile) and asserting on it, so a regression back to per-field reads would be caught automatically.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@dbms/src/Storages/Page/V3/tests/gtest_blob_store.cpp` around lines 1927 -
1983, The new BlobStoreTest::ReadByFieldReadInfosContinuousFields only checks
page.fieldSize(), so it does not prove the optimization in BlobStore::read
actually reduces underlying read calls. Add an automated syscall/read-count
assertion for each FieldReadInfos case by using a counting/mock FileProvider or
BlobFile around the existing BlobStore setup, and verify the contiguous-field
case triggers fewer reads than the scattered/hole cases. Keep the current data
setup and page assertions, but make the test fail if read() reverts to per-field
behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@dbms/src/Storages/Page/V3/tests/gtest_blob_store.cpp`:
- Line 1956: Remove the leftover debug std::cout prints from the
gtest_blob_store test so the committed automated test no longer emits
manual-verification noise in CI. Update the relevant test cases in
gtest_blob_store by deleting the test banner output statements while keeping the
actual assertions and behavior intact; use the surrounding test blocks for the
continuous-fields scenarios to locate and clean all matching debug prints.
- Around line 1927-1983: The new
BlobStoreTest::ReadByFieldReadInfosContinuousFields only checks
page.fieldSize(), so it does not prove the optimization in BlobStore::read
actually reduces underlying read calls. Add an automated syscall/read-count
assertion for each FieldReadInfos case by using a counting/mock FileProvider or
BlobFile around the existing BlobStore setup, and verify the contiguous-field
case triggers fewer reads than the scattered/hole cases. Keep the current data
setup and page assertions, but make the test fail if read() reverts to per-field
behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 5bb46e4a-6d65-4316-a1f6-24bde4ca9b93

📥 Commits

Reviewing files that changed from the base of the PR and between b5093dd and f1d7d13.

📒 Files selected for processing (2)
  • dbms/src/Storages/Page/V3/BlobStore.cpp
  • dbms/src/Storages/Page/V3/tests/gtest_blob_store.cpp

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
dbms/src/Storages/Page/V3/BlobStore.cpp (1)

946-980: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Dead variable field_offset_in_buffer.

It is initialized and incremented but never read; read_size_this_entry and field_offset_in_entry already cover the offset bookkeeping. Consider removing it.

♻️ Proposed cleanup
-            size_t field_offset_in_buffer = 0;
             for (size_t i = start_field_index; i <= end_field_index; ++i)
             {
@@
                 read_size_this_entry += field_size;
-                field_offset_in_buffer += field_size;
             }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@dbms/src/Storages/Page/V3/BlobStore.cpp` around lines 946 - 980, Remove the
unused field_offset_in_buffer variable and its increment from the field
iteration in the relevant BlobStore read logic; retain read_size_this_entry and
field_offset_in_entry, which provide the required offset bookkeeping.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@dbms/src/Storages/Page/V3/BlobStore.h`:
- Around line 183-185: Initialize the DBMS_PUBLIC_GTEST-only member
field_read_call_count at its declaration with a zero default value, ensuring
BlobStore::read(FieldReadInfos&) can safely increment it before
resetFieldReadCallCount() is called.

---

Nitpick comments:
In `@dbms/src/Storages/Page/V3/BlobStore.cpp`:
- Around line 946-980: Remove the unused field_offset_in_buffer variable and its
increment from the field iteration in the relevant BlobStore read logic; retain
read_size_this_entry and field_offset_in_entry, which provide the required
offset bookkeeping.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f09b393d-d300-4dcd-9b70-2122525478bd

📥 Commits

Reviewing files that changed from the base of the PR and between f1d7d13 and 4d57c44.

📒 Files selected for processing (3)
  • dbms/src/Storages/Page/V3/BlobStore.cpp
  • dbms/src/Storages/Page/V3/BlobStore.h
  • dbms/src/Storages/Page/V3/tests/gtest_blob_store.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • dbms/src/Storages/Page/V3/tests/gtest_blob_store.cpp

Comment thread dbms/src/Storages/Page/V3/BlobStore.h
… field_offset_in_buffer

Signed-off-by: yy <736262857@qq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contribution This PR is from a community contributor. needs-ok-to-test Indicates a PR created by contributors and need ORG member send '/ok-to-test' to start testing. release-note-none Denotes a PR that doesn't merit a release note. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Continuously fields can read by one system call in BlobStore::read

1 participant