Skip to content

options: expose direct-IO setters for the SST writer and reader - #856

Open
sanketkedia wants to merge 1 commit into
tikv:masterfrom
sanketkedia:sst-direct-io-setters
Open

options: expose direct-IO setters for the SST writer and reader#856
sanketkedia wants to merge 1 commit into
tikv:masterfrom
sanketkedia:sst-direct-io-setters

Conversation

@sanketkedia

@sanketkedia sanketkedia commented Jul 30, 2026

Copy link
Copy Markdown

What is changed and how it works?

See tikv/tikv#19917 for full context. Exposes two direct-IO setters that TiKV needs in order to stop its SST importer from polluting the OS page cache:

  • EnvOptions::set_use_direct_writes — lets SstFileWriter write an SST without
    populating the page cache. Adds the missing crocksdb_envoptions_set_use_direct_writes
    shim; RocksDB already supports the underlying EnvOptions::use_direct_writes, using
    O_DIRECT on Linux and fcntl(F_NOCACHE) on macOS.
  • ColumnFamilyOptions::set_use_direct_reads — lets a standalone SstFileReader read an
    SST the same way. Rust-only wrapper; it reuses the existing
    crocksdb_options_set_use_direct_reads FFI, so there is no new C code on this path.

Neither setter changes any default — both are false unless explicitly set, so existing
users are unaffected.

Check List

Tests

  • Unit test — test_sst_direct_io in tests/cases/test_ingest_external_file.rs: writes
    an SST with direct writes, reads it back with direct reads and verifies checksum +
    contents, then reads it once more buffered to confirm the alignment padding
    O_DIRECT requires does not leak into the file format.

Side effects

  • Performance regression
  • Breaking backward compatibility

No behaviour change unless a caller opts in.

Related changes

  • Consumed by a follow-up PR to tikv/tikv implementing the importer fix; that PR is blocked
    on this one landing, since TiKV pins rocksdb by git.

Summary by CodeRabbit

  • New Features

    • Added options to enable direct reads for column families.
    • Added options to enable direct writes for environment settings.
    • Direct I/O supports creating, verifying, and reading SST files normally.
  • Tests

    • Added coverage confirming direct I/O preserves expected SST contents and compatibility.

TiKV's SST importer writes ingested SSTs buffered and then reads each one
back in full, also buffered, to verify checksums. During a large ADD INDEX
ingest that streams the entire index through the OS page cache twice and
evicts the foreground read working set: reads that were page-cache hits
(~50us) become device reads (~400us), degrading foreground p99 by ~2x.
See tikv/tikv#19917 for the full analysis.

Fixing that in TiKV needs two knobs this crate does not currently expose:

- EnvOptions::set_use_direct_writes, so SstFileWriter can write without
  populating the page cache. RocksDB uses O_DIRECT on Linux and
  fcntl(F_NOCACHE) on macOS.
- ColumnFamilyOptions::set_use_direct_reads, so a standalone SstFileReader
  can read the same way. use_direct_reads is a DB-level RocksDB option and
  DBOptions already exposes it here, but SstFileReader::new only accepts
  ColumnFamilyOptions; in crocksdb both wrap the same underlying Options
  object, so the setter is added there as well.

Neither setter changes any default: both are false unless explicitly set.

The test writes an SST with direct writes, reads it back with direct reads,
and then reads it again buffered to confirm the alignment padding O_DIRECT
requires does not leak into the file format.

Ref: tikv/tikv#19917

Signed-off-by: Sanket Kedia <kediasanket11121993@gmail.com>
@ti-chi-bot ti-chi-bot Bot added dco-signoff: yes Indicates the PR's author has signed the dco. 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. labels Jul 30, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jul 30, 2026

Copy link
Copy Markdown

Hi @sanketkedia. Thanks for your PR.

I'm waiting for a tikv 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.

@ti-chi-bot ti-chi-bot Bot added the first-time-contributor Indicates that the PR was contributed by an external member and is a first-time contributor. label Jul 30, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jul 30, 2026

Copy link
Copy Markdown

Welcome @sanketkedia!

It looks like this is your first PR to tikv/rust-rocksdb 🎉.

I'm the bot to help you request reviewers, add labels and more, See available commands.

We want to make sure your contribution gets all the attention it needs!



Thank you, and welcome to tikv/rust-rocksdb. 😃

@ti-chi-bot ti-chi-bot Bot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Jul 30, 2026
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds direct read and write option setters to the Rust RocksDB API through new C and Rust FFI bindings. A test verifies direct-I/O SST creation, checksum validation, iteration, and compatibility with non-direct readers.

Changes

Direct I/O option support

Layer / File(s) Summary
Direct I/O options API
librocksdb_sys/crocksdb/c.cc, librocksdb_sys/crocksdb/crocksdb/c.h, librocksdb_sys/src/lib.rs, src/rocksdb_options.rs
Adds the C export, Rust FFI binding, and public setters for direct writes and reads.
Direct-I/O SST validation
tests/cases/test_ingest_external_file.rs
Creates and reads an SST with direct I/O, then verifies it remains readable with default options.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: exposing direct-I/O setters for SST write and read paths.
✨ 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.

Actionable comments posted: 1

🤖 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 `@src/rocksdb_options.rs`:
- Around line 1492-1501: Update the public documentation for
set_use_direct_reads and the corresponding DBOptions setter to replace
platform-specific “O_DIRECT” wording with “direct I/O,” while preserving the
existing explanation of bypassing the OS page cache.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9b84651c-38cf-40e3-8bac-60966ef818dc

📥 Commits

Reviewing files that changed from the base of the PR and between cdb577c and f5efbde.

📒 Files selected for processing (5)
  • librocksdb_sys/crocksdb/c.cc
  • librocksdb_sys/crocksdb/crocksdb/c.h
  • librocksdb_sys/src/lib.rs
  • src/rocksdb_options.rs
  • tests/cases/test_ingest_external_file.rs

Comment thread src/rocksdb_options.rs
Comment on lines +1492 to +1501
/// Read this options' files with O_DIRECT, bypassing the OS page cache.
/// Useful for a standalone SstFileReader (e.g. ingest checksum verification)
/// so a one-shot read does not populate the page cache. `DBOptions` exposes
/// the same setter; both write to the shared underlying options object.
pub fn set_use_direct_reads(&mut self, v: bool) {
unsafe {
crocksdb_ffi::crocksdb_options_set_use_direct_reads(self.inner, v);
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use platform-neutral direct-I/O wording in the public docs.

The implementation uses O_DIRECT on Linux but F_NOCACHE on macOS. Replace the literal O_DIRECT references with “direct I/O” so the API documentation remains accurate across supported platforms.

Also applies to: 2379-2386

🤖 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 `@src/rocksdb_options.rs` around lines 1492 - 1501, Update the public
documentation for set_use_direct_reads and the corresponding DBOptions setter to
replace platform-specific “O_DIRECT” wording with “direct I/O,” while preserving
the existing explanation of bypassing the OS page cache.

@AndreMouche AndreMouche left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM @Connor1996 Please take a look

@ti-chi-bot ti-chi-bot Bot added the lgtm label Aug 19, 2026
@ti-chi-bot

ti-chi-bot Bot commented Aug 19, 2026

Copy link
Copy Markdown

[LGTM Timeline notifier]

Timeline:

  • 2026-08-19 17:54:12.211858005 +0000 UTC m=+92287.382952118: ☑️ agreed by AndreMouche.

@ti-chi-bot

ti-chi-bot Bot commented Aug 19, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: AndreMouche

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

The pull request process is described 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 the approved label Aug 19, 2026
@LykxSassinator

Copy link
Copy Markdown

Although the internal RocksDB read/write APIs are designed to guarantee forward and backward compatibility when writes use Direct I/O and reads use buffered I/O, I still have some concerns. To be safe, I'd suggest adding more test cases to explicitly validate compatibility for the following scenario:

1. Buffered write -> Direct I/O read

The current test covers "direct-write" -> "buffered-read", which is the important “disable Direct I/O after writing” compatibility case.
Could we also add the reverse case: create an SST with default buffered I/O, then reopen it with set_use_direct_reads(true) and verify its checksum and entries?

Direct I/O is an I/O mode rather than an SST format attribute, so this should work without any format metadata or migration. Adding this case would make the compatibility matrix explicit and protect both directions when users toggle the option.

2. Direct I/O write -> ingest -> normal DB read

Could we also extend the test to ingest a directly-written SST into a DB and read the ingested keys through the normal buffered DB read path?

Reopening the external SST with a buffered SstFileReader already validates its table format, but an ingest test would cover the complete TiKV lifecycle: create with Direct I/O, ingest into RocksDB, disable/not use Direct I/O, and serve normal reads. This would provide stronger regression coverage for the compatibility concern.

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

Labels

approved contribution This PR is from a community contributor. dco-signoff: yes Indicates the PR's author has signed the dco. first-time-contributor Indicates that the PR was contributed by an external member and is a first-time contributor. lgtm needs-ok-to-test Indicates a PR created by contributors and need ORG member send '/ok-to-test' to start testing. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants