Summary:
These will be useful for qualifying non-tiered workloads for tiered storage.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14243
Test Plan:
unit test included
I'm not concerned about performance because this fits pretty nicely into some existing code and only adds overhead when (expensive) IOs are done.
Reviewed By: jaykorean
Differential Revision: D90870348
Pulled By: pdillinger
fbshipit-source-id: 984411123bcd54c249a949da813ff04fedacc6a4
Summary:
To move away from OLD_CompressData / OLD_UncompressData. Also improved some error/warning messages.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14241
Test Plan: manual tests showing similar performance, runs with ASAN/UBSAN to check for issues
Reviewed By: hx235
Differential Revision: D90793708
Pulled By: pdillinger
fbshipit-source-id: e0655f7bed8d85e5ea110167dca73c6664f7465b
Summary:
Trying to get rid of uses of OLD_CompressData / OLD_UncompressData. Some performance optimizations and corrections for better accounting also.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14230
Test Plan:
* exanded unit test to be more complete / rigorous
* manual before-and-after db_bench runs with the option, seeing table properties as expected
Reviewed By: hx235
Differential Revision: D90545476
Pulled By: pdillinger
fbshipit-source-id: 2f7c577574bcc4b2acafa002761ec1cad7fdb093
Summary:
as part of the effort to get rid of OLD_CompressData and OLD_UncompressData and the old implementations in compression.h.
It's unfortunate the the existing blob file schema doesn't allow storing blobs uncompressed when the compressed version is larger, so we have to work around that.
Note that use of GrowableBuffer in place of std::string is intended to avoid the potential performance overhead of zeroing out memory before overwriting it.
Also includes some cleanup of includes
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14234
Test Plan:
some unit test updates as needed. Crash test covers integrated blob support.
I'm not too concerned about performance, as until a future schema change, this code is committing the grave performance error of storing compressed data larger than uncompressed.
Reviewed By: mszeszko-meta, hx235
Differential Revision: D90544049
Pulled By: pdillinger
fbshipit-source-id: 2f2ed16de63990b797cc06c8dad36b5869dac302
Summary:
Deadlock or timeout is possible in TestPut, when TestMultiGet was executed at the same time, because it executes MaybeAddKeyToTxnForRYW, which writes to the same key space but does not acquire stress test level mutex. Therefore, RocksDB could return deadlock error.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14235
Test Plan: Stress test
Reviewed By: hx235
Differential Revision: D90621772
Pulled By: xingbowang
fbshipit-source-id: eb808193ded06b69a8161320f88d5ba4e20b4901
Summary:
Folly download dependencies directly from external source. Sometimes, this could fail due to external website instability. To solve this, we added github cache to cache the dependencies. We also added a python script to try different sources during download to reduce the chance of failure.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14226
Test Plan: github CI
Reviewed By: krhancoc, archang19
Differential Revision: D90343051
Pulled By: xingbowang
fbshipit-source-id: 3faad6aaa6c1bfd361b9e405c298856cd64bf457
Summary:
Currently to set options for multiple CFs, the caller must repeatedly call SetOptions() for each CF. This in turn serializes the entire options file each time. This PR exposes a new API that allows SetOptions to be called on multiple CFs at once, thus only paying the OPTIONS file serialization once.
Also added a new unit test for SetOptions.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14201
Reviewed By: pdillinger
Differential Revision: D89735181
Pulled By: joshkang97
fbshipit-source-id: 9b7a721b7e8769b653243b1581678ffd05d038e8
Summary:
This diff introduces the IO Dispatcher, which will be used to simplify the code path for MultiScan, while further providing a centralized place to enact policy on how MultiScan is done (i.e., limit memory usage and pinned buffers for example). Right now this diff only encapsulates the functionality done during the Prepare of MultiScan.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14135
Reviewed By: anand1976
Differential Revision: D87837261
Pulled By: krhancoc
fbshipit-source-id: 2698910ade02bc3d182413ae07ce69fe7abb7ec5
Summary:
As compaction scheduling is not deterministic, the existing check is too strict sometimes, causing test to be flaky.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14220
Test Plan: Unit test
Reviewed By: pdillinger
Differential Revision: D90143556
Pulled By: xingbowang
fbshipit-source-id: 6780423c63324a4b20fc8b8ccac2051a094c9f4a
Summary:
My PR https://github.com/facebook/rocksdb/issues/14195 regressed a case in which db_crashtest.py calling db_stress with --destroy_db_initially=1 could lead to dbname directory being nonexistant for subsequent calls to gen_cmd -> finalize_and_sanitize -> is_direct_io_supported which would fail in creating a temporary file. Fix this (and clean up existing related code) using os.makedirs.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14219
Test Plan: I don't have a good reproducer for the error but some manual testing indicates this change is at least safe
Reviewed By: virajthakur
Differential Revision: D90138248
Pulled By: pdillinger
fbshipit-source-id: 0ed6524cd50f8632346a8583f26bf1f4941817ce
Summary:
* Some existing commentary and motivation around my atomic wrappers in atomic.h was based on a misreading of documentation. seq_cst *is* a safe substitute for acq_rel in all cases. I still like having a distinct type for RelaxedAtomic (as folly does) and a wrapper also for other cases to avoid readability traps like implicit conversion and implicit memory order. This PR is only comment changes and renaming.
* Create a blog post about bit fields API to help with lock-free (and low-lock) programming.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14213
Test Plan: esiting tests
Reviewed By: xingbowang
Differential Revision: D89971581
Pulled By: pdillinger
fbshipit-source-id: 9bd1181d692258d668189c2da8bd0e5d98fd6230
Summary:
This change builds on https://github.com/facebook/rocksdb/issues/14027 and https://github.com/facebook/rocksdb/issues/13965 to complete migration
of the HyperClockCache implementation to using the hygienic BitFields API.
No semantic change in the implementation details is intended, just
greatly improving readability and safety of the code while maintaining
the same performance.
In more detail,
* Refactor the main metadata atomic for each slot in an HCC table into
SlotMeta using BitFields.
* Extended BitFields APIs with some additional features, and renamed
BlahTransform classes to BlahTransformer to resolve potential naming
conflicts with member functions to create them.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14154
Test Plan:
for correctness, mostly existing tests. but also added tests
for new BitFields features. I especially ran local TSAN whitebox crash
test extensively which caught a couple of refactoring errors.
For performance, I verified with release builds of cache_bench, using
default options, that there was no noticeable/consistent difference
after all these HCC migrations vs. backing them out. That test was with
GCC 11 and -O2, which is a reasonable baseline for expected compiler
optimizations.
Reviewed By: xingbowang
Differential Revision: D87960540
Pulled By: pdillinger
fbshipit-source-id: e0257b7fea8a5c7709daef18911959201ce4e0f3
Summary:
This bug caused seqno to be incorrectly zeroed when UDT is enabled. This is one of the contributing factor that caused tombstones to be accumulated at bottommost level, causing high space amp.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14207
Test Plan: Unit test
Reviewed By: pdillinger
Differential Revision: D89826564
Pulled By: xingbowang
fbshipit-source-id: 62ab1e37c36ae1ed95f26213c97a591a17e962a6
Summary:
## Context
1. OpenAndCompact required CompactionServiceOptionsOverride
2. Currently there are no C APIs to create CompactionServiceOptionsOverride
## Changes
1. Create C API for compactionServiceOptionsOverride
2. Create helper function to create compactionServiceOptionsOverride from Options. This was added in because The C API lacks getter methods for non-serializable options (comparator, table_factory, etc.). Without this, users would need to maintain separate references to all these options just to pass them to the override. If the user need to create a new comparator or table factory then C API for compactionServiceOptionsOverride already as the setters for the same.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14183
Reviewed By: hx235
Differential Revision: D89690005
Pulled By: jaykorean
fbshipit-source-id: efe8211feec9d144b32be0f5e66c8cf8bde8dac0
Summary:
Let db_crashtest.py work with TEST_TMPDIR on remote filesystem, by infering whether it's remote from the env_uri argument. Note that some other paths passed to db_stress are local paths and we can't reuse TEST_TMPDIR for those cases when it's remote.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14195
Test Plan: public and private CI
Reviewed By: archang19
Differential Revision: D89590246
Pulled By: pdillinger
fbshipit-source-id: db6eb9c16d4e76617183780747353c798cc9bef6
Summary:
Causing failures and not yet supported. Also putting a note in db.h about the combination being unsupported.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14189
Test Plan: started up blackbox_crash_test_with_ts many times and checked command line to be confident it's excluded.
Reviewed By: hx235
Differential Revision: D89297971
Pulled By: pdillinger
fbshipit-source-id: c5134351d9ecb37879c7e3319c17dd9228d7f12a
Summary:
`PosixRandomAccessFile::MultiRead` was introduced in Dec 2019 in https://github.com/facebook/rocksdb/pull/5881. Subsequently, 2 years after, we introduced the `PosixRandomAccessFile::ReadAsync` API in https://github.com/facebook/rocksdb/pull/9578, which was reusing the same `PosixFileSystem` IO ring as `MultiRead` API, consequently writing to the very same ring's submission queue (without waiting!). This 'shared ring' design is problematic, since sequentially interleaving `ReadAsync` and `MultiRead` API calls on the very same thread might result in reading 'unknown' events in `MultiRead` leading to `Bad cqe data` errors (and therefore falsely perceived as a corruption) - which, for some services (running on local flash), in itself is a hard blocker for adopting RocksDB async prefetching ('async IO') that heavily relies on the `ReadAsync` API. This change aims to solve this problem by maintaining separate thread local IO rings for `async reads` and `multi reads` assuring correct execution. In addition, we're adding more robust error handling in form of retries for kernel interrupts and draining the queue when process is experiencing terse memory condition. Separately, we're enhancing the performance aspect by explicitly marking the rings to be written to / read from by a single thread (`IORING_SETUP_SINGLE_ISSUER` [if available]) and defer the task just before the application intends to process completions (`IORING_SETUP_DEFER_TASKRUN` [if available]). See https://man7.org/linux/man-pages/man2/io_uring_setup.2.html for reference.
## Benchmark
**TLDR**
There's no evident advantage of using `io_uring_submit` (relative to proposed `io_uring_submit_and_wait`) across batches of size 10, 250 and 1000 simulating significantly-less, close-to and 4x-above `kIoUringDepth` batch size. `io_uring_submit` might be more appealing if (at least) one of the IOs is slow (which was NOT the case during the benchmark). More notably, with this PR switching from `io_uring_submit_and_wait` -> `io_uring_submit` can be done with a single line change due to implemented guardrails (we can followup with adding optional config for true ring semantics [if needed]).
**Compilation**
```
DEBUG_LEVEL=0 make db_bench
```
**Create DB**
```
./db_bench \
--db=/db/testdb_2.5m_k100_v6144_16kB_LZ4 \
--benchmarks=fillseq \
--num=2500000 \
--key_size=100 \
--value_size=6144 \
--compression_type=LZ4 \
--block_size=16384 \
--seed=1723056275
```
**LSM**
* L0: 2 files, L1: 5, L2: 49, L3: 79
* Each file is roughly ~35M in size
### MultiReadRandom (with caching disabled)
Each run was preceded by OS page cache cleanup with `echo 1 | sudo tee /proc/sys/vm/drop_caches`.
```
./db_bench \
--use_existing_db=true \
--db=/db/testdb_2.5m_k100_v6144_16kB_LZ4 \
--compression_type=LZ4 \
--benchmarks=multireadrandom \
--num= **<N>** \
--batch_size= **<B>** \
--io_uring_enabled=true \
--async_io=false \
--optimize_multiget_for_io=false \
--threads=4 \
--cache_size=0 \
--use_direct_reads=true \
--use_direct_io_for_flush_and_compaction=true \
--cache_index_and_filter_blocks=false \
--pin_l0_filter_and_index_blocks_in_cache=false \
--pin_top_level_index_and_filter=false \
--prepopulate_block_cache=0 \
--row_cache_size=0 \
--use_blob_cache=false \
--use_compressed_secondary_cache=false
```
| B=10; N=100,000 | B = 250; N=80,000 | B = 1,000; N=20,000
-- | -- | -- | --
baseline | 31.5 (± 0.4) us/op | 17.5 (± 0.5) us/op | 13.5 (± 0.4) us/op
io_uring_submit_and_wait | 31.5 (± 0.6) us/op | 17.7 (± 0.4) us/op | 13.6 (± 0.4) us/op
io_uring_submit | 31.5 (± 0.6) us/op | 17.5 (± 0.5) us/op | 13.4 (± 0.45) us/op
### Specs
| Property | Value
-- | --
RocksDB | version 10.9.0
Date | Tue Dec 9 15:57:03 2025
CPU | 56 * Intel Sapphire Rapids (T10 SPR)
Kernel version | 6.9.0-0_fbk12_0_g28f2d09ad102
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14158
Reviewed By: anand1976
Differential Revision: D88172809
Pulled By: mszeszko-meta
fbshipit-source-id: 5198de3d2f18f76fee661a2ec5f447e79ba06fbd
Summary:
**Context/Summary:**
Truncated range deletion in input files can be output by CompactionIterator with type kMaxValid instead of kTypeRangeDeletion, to satisfy ordering requirement between the truncated range deletion start key and a file's point keys. There was a plan to skip such key in https://github.com/facebook/rocksdb/pull/14122 but blockers remain to fulfill the plan.
Resumable compaction is not able to handle resumption from range deletion well at this point and should consider kMaxValid type same as kTypeRangeDeletion for resumption. Previously, it didn't and mistakenly allow resumption from a delete range. That led to an assertion failure, complaining about lacking information to update file boundaries in the presence of range deletion needed during cutting an output file, after the compaction resumes from that delete range and happens to cut the output file shortly after without any point keys in between.
```
frame https://github.com/facebook/rocksdb/issues/9: 0x00007f4f4743bc93 libc.so.6`__GI___assert_fail(assertion="meta.smallest.size() > 0", file="db/compaction/compaction_outputs.cc", line=530, function="rocksdb::Status rocksdb::CompactionOutputs::AddRangeDels(rocksdb::CompactionRangeDelAggregator&, const rocksdb::Slice*, const rocksdb::Slice*, rocksdb::CompactionIterationStats&, bool, const rocksdb::InternalKeyComparator&, rocksdb::SequenceNumber, std::pair<long unsigned int, long unsigned int>, const rocksdb::Slice&, const string&)") at assert.c:101:3
frame https://github.com/facebook/rocksdb/issues/10: 0x00007f4f4808c68c librocksdb.so.10.9`rocksdb::CompactionOutputs::AddRangeDels(this=0x00007f4f0c27e1a0, range_del_agg=0x00007f4f0c21ecc0, comp_start_user_key=0x0000000000000000, comp_end_user_key=0x0000000000000000, range_del_out_stats=0x00007f4f0dffa140, bottommost_level=false, icmp=0x00007f4ef4c93040, earliest_snapshot=13108729, keep_seqno_range=<unavailable>, next_table_min_key=0x00007f4ef4c8f540, full_history_ts_low="") at compaction_outputs.cc:530:7
frame https://github.com/facebook/rocksdb/issues/11: 0x00007f4f480480dd librocksdb.so.10.9`rocksdb::CompactionJob::FinishCompactionOutputFile(this=0x00007f4f0dffb890, input_status=<unavailable>, prev_table_last_internal_key=0x00007f4f0dffa650, next_table_min_key=0x00007f4ef4c8f540, comp_start_user_key=0x0000000000000000, comp_end_user_key=0x0000000000000000, c_iter=0x00007f4ef4c8f400, sub_compact=0x00007f4f0c27e000, outputs=0x00007f4f0c27e1a0) at compaction_job.cc:1917:31
```
This PR simply prevents MaxValid from being a resumption point like regular range deletion - see commit 842d66eb18ea67e965d6acb1fce12c18eeb778d2
Besides that, the PR also improves the testing, variable naming, logging in resumable compaction codes that were needed to debug this assertion failure - see commit https://github.com/facebook/rocksdb/pull/14184/commits/aecd4e7f971f6dd4df672d9e5f1409fe4747c561. These improvements are covered by existing tests.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14184
Test Plan:
- The stress initially surfaced the error. Using the exact same LSM shapes and files that were used in stress test but in a unit test, I'm able to get a deterministic repro and confirmed the fix resolves the error. This is the repro test https://github.com/hx235/rocksdb/commit/1075936e693c68c960761855900c53f5b894f57a
```
./compaction_service_test --gtest_filter=ResumableCompactionServiceTest.CompactSpecificFilesFromExistingDBWithCancelAndResume
# Before fix
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from ResumableCompactionServiceTest
[ RUN ] ResumableCompactionServiceTest.CompactSpecificFilesFromExistingDBWithCancelAndResume
compaction_service_test: db/compaction/compaction_outputs.cc:530: rocksdb::Status rocksdb::CompactionOutputs::AddRangeDels(rocksdb::CompactionRangeDelAggregator&, const rocksdb::Slice*, const rocksdb::Slice*, rocksdb::CompactionIterationStats&, bool, const rocksdb::InternalKeyComparator&, rocksdb::SequenceNumber, std::pair<long unsigned int, long unsigned int>, const rocksdb::Slice&, const string&): Assertion `meta.smallest.size() > 0' failed.
Received signal 6 (Aborted)
Invoking GDB for stack trace...
[New LWP 2621610]
[New LWP 2621611]
[New LWP 2621612]
[New LWP 2621613]
[New LWP 2621614]
[New LWP 2621630]
[New LWP 2621631]
# After fix
Note: Google Test filter = ResumableCompactionServiceTest.CompactSpecificFilesFromExistingDBWithCancelAndResume
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from ResumableCompactionServiceTest
[ RUN ] ResumableCompactionServiceTest.CompactSpecificFilesFromExistingDBWithCancelAndResume
[ OK ] ResumableCompactionServiceTest.CompactSpecificFilesFromExistingDBWithCancelAndResume (4722 ms)
[----------] 1 test from ResumableCompactionServiceTest (4722 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (4722 ms total)
[ PASSED ] 1 test.
```
- Follow-up: I tried a couple time to coerce the truncated range delete from scratch in the unit test but failed doing so. Considering kMaxValid may not be outputted by compaction iterator anymore after https://github.com/facebook/rocksdb/pull/14122/files gets landed again (and obsolete the bug) ADN the simple nature of this fix 842d66eb18ea67e965d6acb1fce12c18eeb778d2 AND the worst case of such fix going wrong is just less resumption, I decided to leave writing a unit test to coerce truncated ranged deletion from scratch a follow-up. Maybe I will draw inspiration from https://github.com/facebook/rocksdb/pull/14122/files.
Reviewed By: jaykorean
Differential Revision: D88912663
Pulled By: hx235
fbshipit-source-id: 80a01135684c8fea659650faaa00c2dc452c482a
Summary:
**Context/Summary:**
Stress test flag printed by db_crashtest.py like `./db_stres ....-secondary_cache_uri=compressed_secondary_cache://capacity=8388608;enable_custom_split_merge=true --otherflags=xxxx` is not copy-paste-run friendly. Directly running this command will cause parsing hiccups due to special characters like // or ;. This PR made the db_crashtest.py print a single-quoted value so at least the copy-paste-run works for unix-like shell (the most common case).
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14180
Test Plan:
`python3 tools/db_crashtest.py --simple blackbox ...` display the following
Before fix, no single-quoted
```
Use random seed for iteration 9698536012932546857
Running db_stress with pid=1280640:./db_stress --secondary_cache_uri=compressed_secondary_cache://capacity=8388608;enable_custom_split_merge=true ...
// Directly copy, paste and run the ./db_stress command will encounter
Error: Read(-readpercent=0)+Prefix(-prefixpercent=0)+Write(-writepercent=45)+Delete(-delpercent=0)+DeleteRange(-delrangepercent=30)+Iterate(-iterpercent=40)+CustomOps(-customopspercent=0) percents != 100!
bash: --set_options_one_in=0: command not found
```
After fix, has single-quoted
```
se random seed for iteration 6017815530972723112
Running db_stress with pid=1234632: ./db_stress --secondary_cache_uri='compressed_secondary_cache://capacity=8388608;enable_custom_split_merge=true' ....
// Directly copy, paste and run the ./db_stress command is fine
```
Reviewed By: archang19
Differential Revision: D88688584
Pulled By: hx235
fbshipit-source-id: 88b8b2de7c2c5619b6e19900f4144dcd8e032f7b
Summary:
r? cbi42
Exposes RocksDB's remote compaction functionality through the C API, enabling C/FFI clients (Go, Rust, Python, etc.) to offload compaction work to remote workers.
## API Components
### Compaction Service
Create service with schedule, wait, cancel, and on_installation callbacks
Ownership transfers to options object (auto-destroyed, no manual cleanup)
### Job Info (13 getters)
DB/CF metadata and compaction details (priority, reason, levels, flags)
### Schedule Response
Create with job ID and status (validated with errptr)
Status: success, failure, aborted, use_local
### OpenAndCompact (for remote workers)
Execute compaction on worker node with environment/comparator overrides
Cancellation support via atomic flags
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14136
Reviewed By: hx235
Differential Revision: D88316558
Pulled By: jaykorean
fbshipit-source-id: 60a0fee69ff1e650dd785d96ec656649263214f8
Summary:
Crash tests have been failing of late with this assertion failure - db_stress: `./table/block_based/block_based_table_iterator.h:656: void rocksdb::BlockBasedTableIterator::PrepareReadAsyncCallBack(rocksdb::FSReadRequest &, void *): Assertion `async_state->status.IsAborted()' failed.` Instead of asserting, surface the failure status so we can troubleshoot.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14171
Reviewed By: xingbowang
Differential Revision: D88396654
Pulled By: anand1976
fbshipit-source-id: 8d59d7ace0c522c17b7af17c50e16af876911bad
Summary:
To help find potential issues not showing up in ARM unit tests. I'm running it with and without TransactionDB (write-committed) for better coverage. The job expands the size of /dev/shm for adequate space on maximum performance storage, and adds swap space to reduce risk of OOM in case we fill that up.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14172
Test Plan: earlier drafts of this PR added the job to PR jobs, and the last before putting in "nightly" can be seen here: https://github.com/facebook/rocksdb/actions/runs/19945493840/job/57193797390?pr=14172
Reviewed By: archang19
Differential Revision: D88429479
Pulled By: pdillinger
fbshipit-source-id: bd4d9cda9256950c3c6c126c299a44dbbbc30c7e
Summary:
Fix missing const for arg of OptionChangeMigration
We switched from std::string to std::string & for API OptionChangeMigration, which caused const qualifier to be lost at call site, which causes compilation failure.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14173
Test Plan: Unit test
Reviewed By: pdillinger
Differential Revision: D88431457
Pulled By: xingbowang
fbshipit-source-id: a705f3b80cc5ff56dab73aa6a31c940798d8df45
Summary:
Revert "Fix a bug where compaction with range deletion can persist kTypeMaxValid in file metadata (https://github.com/facebook/rocksdb/issues/14122)"
Add a new unit test to capture the situation found by stress test
This reverts commit 8c7c8b8dab.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14170
Test Plan: Unit Test
Reviewed By: anand1976
Differential Revision: D88395956
Pulled By: xingbowang
fbshipit-source-id: 226649dc79a86010ad326ffb2eae35109dc96bc4
Summary:
Continuing work from https://github.com/facebook/rocksdb/issues/13965. Here I'm migrating the "next with shift" kind of bit field and for that I've added an API for atomic additive transformations that can be combined into a single atomic update for multiple fields. (I implemented more features than needed, just in case they are needed someday and to demonstrate what is possible.)
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14027
Test Plan: BitFields unit test updated/added, existing HCC tests
Reviewed By: xingbowang
Differential Revision: D83895094
Pulled By: pdillinger
fbshipit-source-id: e4487f34f5607b20f94b85a645ca654e6401e35d
Summary:
I want to reduce the time from when we call `StopBackup` to `CreateNewBackup` returning `BackupStopped`. We already check for the `stop_backup_` inside `CopyOrCreateFile` and `ReadFileAndComputeChecksum`, but we should add a check at the top of these methods to abort immediately. This could help save some latency from the file system metadata operations, like creating the sequential file and writable file.
We also want to update the API documentation for `StopBackup` which currently does not indicate that once it is called, all subsequent requests to create backups will fail.
In a follow up PR, we should also add coverage of `StopBackup` to the crash tests.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14129
Test Plan:
We were missing unit test coverage for `StopBackup`. I added test cases which cancel backups at different points in time.
Once this change is rolled out to production, we can monitor the DB close latencies, which depend on first cancelling ongoing backups
Reviewed By: pdillinger
Differential Revision: D87356536
Pulled By: archang19
fbshipit-source-id: 687094a41f096f6a156be65b2cce0b5054fb26f2
Summary:
Support ccache in make file
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14123
Test Plan: local build
Reviewed By: cbi42
Differential Revision: D87332892
Pulled By: xingbowang
fbshipit-source-id: 2088bd19bdab1bd7070734c886200be80f1a65af
Summary:
... from https://github.com/facebook/rocksdb/issues/14140. The assertion in the default implementation of CompressorWrapper::MaybeCloneSpecialized() could fail because this wrapper wasn't overriding it when it should. (See the NOTE on that implementation.)
Because this release already has a breaking modification to the Compressor API (adding Clone()), I took this opportunity to add 'const' to MaybeCloneSpecialized(). Also marked some compression classes as 'final' that could be marked as such.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14150
Test Plan: unit test expanded to cover this case (verified failing before). Audited the rest of our CompressorWrappers.
Reviewed By: archang19
Differential Revision: D87793987
Pulled By: pdillinger
fbshipit-source-id: 61c4469b84e4a47451a9942df09277faeeccfe63
Summary:
This change enables a custom CompressionManager / Compressor to adopt custom handling for data and index blocks. In particular, index blocks for format_version >= 4 use a distinct variant of the block format. Thus, a potentially format-aware compression algorithm such as OpenZL should be told which kind of block we are compressing. (And previously I avoided passing block type in CompressBlock for efficient handling of things like dictionaries but also avoiding checks on every CompressBlock call.)
Most of the change is in BlockBasedTableBuilder to call MaybeCloneSpecialized for both kDataBlock and for kIndexBlock. But I also needed some small tweaks/additions to the public API also:
* Require a Clone() function from Compressors, to support proper implementations of MaybeCloneSpecialized() in wrapper Compressors.
* Assert that the default implementation of CompressorWrapper::MaybeCloneSpecialized() is only used in allowable cases.
* Convenience function Compressor::CloneMaybeSpecialized()
This also fixes a serious bug/oversight in ManagedPtr for (ManagedWorkingArea) that somehow wasn't showing up before. It probably doesn't need a release note because CompressionManager stuff is still considered experimental.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14140
Test Plan: Greatly expanded DBCompressionTest.CompressionManagerWrapper to make sure the distinction between data blocks and index blocks is properly communicated to a custom CompressionManager/Compressor. The test includes processing the expected structure of data and index blocks, to serve as a tested example for structure-aware compressors.
Reviewed By: hx235
Differential Revision: D87600019
Pulled By: pdillinger
fbshipit-source-id: 252ef78910073a0e45f2c81dd45ac87ff8a41fc6
Summary:
Range deletion start keys are considered during compaction for cutting output files. Due to some ordering requirement (see comment above InsertNextValidRangeTombstoneAtLevel()) between truncated range deletion start key and a file's point keys, there was logic in https://github.com/facebook/rocksdb/blob/f6c9c3bf1cf05096e8ff8c03ded60c1e199edbb7/db/range_del_aggregator.cc#L39 that changes the value type to be kTypeMaxValid. However, kTypeMaxValid is not supposed to be persisted per https://github.com/facebook/rocksdb/blob/f6c9c3bf1cf05096e8ff8c03ded60c1e199edbb7/db/dbformat.h#L75-L76. This can cause forward compatibility issues reported in https://github.com/facebook/rocksdb/issues/14101. This PR fixes this issue by removing the logic that sets kTypeMaxValid and always skip truncated range deletion start key in CompactionMergingIterator.
For existing SST files, we want to avoid using this kTypeMaxValid, so this PR also introduces a new placeholder value type. This allows us to re-strengthen the relevant value type checks (IsExtendedValueType()) that was loosen for kTypeMaxValid.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14122
Test Plan:
- a unit test that persists kTypeMaxValid before this fix
- crash test with frequent range deletion: `python3 ./tools/db_crashtest.py blackbox --delrangepercent=11 --readpercent=35`
- Generate SST files with 0x1A as value type (kTypeMaxValid before this change) in file metadata. Run ldb with the strengthened check in IsExtendedValueType() to dump the MANIFEST. It failed to parse MANIFEST as expected before this PR and succeeds after this PR.
```
Error in processing file /tmp/rocksdbtest-543376/db_range_del_test_2549357_6547198162080866792/MANIFEST-000005 Corruption: VersionEdit: new-file4 entry The file /tmp/rocksdbtest-543376/db_range_del_test_2549357_6547198162080866792/MANIFEST-000005 may be corrupted.
```
Reviewed By: pdillinger
Differential Revision: D87016541
Pulled By: cbi42
fbshipit-source-id: 9957a095db2cd9947463b403f352bd9a1fd70a76
Summary:
Fixing internal validator failure
```
Every project specific source file must contain a doc block with an appropriate copyright header. Unrelated files must be listed as exceptions in the Copyright Headers Exceptions page in the repo dashboard.
A copyright header clearly indicates that the code is owned by Meta. Every open source file must start with a comment containing "Meta Platforms, Inc. and affiliates"
https://github.com/facebook/rocksdb/blob/main/buckifier/targets_cfg.py:
The first 16 lines of 'buckifier/targets_cfg.py' do not contain the patterns:
(Meta Platforms, Inc. and affiliates)|(Facebook, Inc(\.|,)? and its affiliates)|([0-9]{4}-present(\.|,)? Facebook)|([0-9]{4}(\.|,)? Facebook)
```
While fixing the text to pass the linter, I took the opportunity to modify `format-diff.sh` script to add the copyright header automatically if missing in new files.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14143
Test Plan:
```
$> make format
```
**new python file**
```
build_tools/format-diff.sh
Checking format of uncommitted changes...
Checking for copyright headers in new files...
Added copyright header to build_tools/test.py
Copyright headers were added to new files.
Nothing needs to be reformatted!
```
**new header file**
```
build_tools/format-diff.sh
Checking format of uncommitted changes...
Checking for copyright headers in new files...
Added copyright header to db/db_impl/db_impl_jewoongh.h
Copyright headers were added to new files.
Nothing needs to be reformatted!
```
Reviewed By: hx235
Differential Revision: D87653124
Pulled By: jaykorean
fbshipit-source-id: 164322cfcd2c162bb3b41bb8f3bafefa3f20b695
Summary:
**Context/Summary:**
.. because verify_output_flags contains information of usage of paranoid_file_check that is currently not yet compatible with resumable remote compaction
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14139
Test Plan: Existing tests
Reviewed By: jaykorean
Differential Revision: D87582635
Pulled By: hx235
fbshipit-source-id: ef21223da53a0696fa3ca9b1617c2c1ee2e19878
Summary:
**Context/Summary:**
Due to double's 53-bit mantissa limitation, large uint64_t values lose precision when converted to double. Value equals to or smaller than UINT64_MAX (but greater than 2^64 - 1024) round up to 2^64 since rounding up results in less error than rounding down, which exceeds UINT64_MAX. `std::numeric_limits<uint64_t>::max() / op1 < op2` won't catch those cases. Casting such out-of-range doubles back to uint64_t causes undefined behavior. T
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14132
UndefinedBehaviorSanitizer: undefined-behavior options/cf_options.cc:1087:32 in
```
before the fix but not after.
Test Plan:
```
COMPILE_WITH_ASAN=1 COMPILE_WITH_UBSAN=1 CC=clang-18 CXX=clang++-18 ROCKSDB_DISABLE_ALIGNED_NEW=1 USE_CLANG=1 make V=1 -j55 db_stress
python3 tools/db_crashtest.py --simple blackbox --compact_range_one_in=5 --target_file_size_base=9223372036854775807 // Half of std::numeric_limits<uint64_t>::max()
```
It fails with
```
stderr:
options/cf_options.cc:1087:32: runtime error: 1.84467e+19 is outside the range of representable values of type 'unsigned long'
Reviewed By: pdillinger
Differential Revision: D87434936
Pulled By: hx235
fbshipit-source-id: 65563edf9faf732410bdba8b9e4b7fd61b958169
Summary:
I have been using sst_dump --command=recompress for some ad hoc automation for compression engineering and these new options help with that.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14133
Test Plan: manual
Reviewed By: hx235
Differential Revision: D87453635
Pulled By: pdillinger
fbshipit-source-id: 2ae54e13a9221ec27c6637fea16623465a9163ae
Summary:
Saw a mysterious failure of assertion
`assert(rep_->props.num_data_blocks == 0)` in
DBCompressionTest/CompressionFailuresTest.CompressionFailures/45. This seems to be caused by a parallel compression failure arriving after the emit thread has started Finish() but before the Flush() at the start of Finish(). We can fix this by relaxing the assertion to allow for the !ok() case. Testing revealed more ok() assertions that needed to be relaxed/moved.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14130
Test Plan: Added a sync point to inject a failure status in the right place and added to unit test to be sure the case is essentially covered. It would arguably be a more realistic test to force a particular thread interleaving but I believe simple is good here.
Reviewed By: hx235
Differential Revision: D87377709
Pulled By: pdillinger
fbshipit-source-id: 4bd465673b084afcc235688503d1c2f464eed32d
Summary:
**Context/Summary:**
This PR adds multi-cf support to option migration. The original implementation sets options, opens db, compacts files and reopens the db in almost all the three branches below. Such design makes expanding to multi-cf difficult as it needs to change all these places within each of the branch causing code redundancy.
```
Status OptionChangeMigration(std::string dbname, const Options& old_opts,
const Options& new_opts) {
if (old_opts.compaction_style == CompactionStyle::kCompactionStyleFIFO) {
// LSM generated by FIFO compaction can be opened by any compaction.
return Status::OK();
} else if (new_opts.compaction_style ==
CompactionStyle::kCompactionStyleUniversal) {
return MigrateToUniversal(dbname, old_opts, new_opts);
} else if (new_opts.compaction_style ==
CompactionStyle::kCompactionStyleLevel) {
return MigrateToLevelBase(dbname, old_opts, new_opts);
} else if (new_opts.compaction_style ==
CompactionStyle::kCompactionStyleFIFO) {
return CompactToLevel(old_opts, dbname, 0, 0 /* l0_file_size */, true);
} else {
return Status::NotSupported(
"Do not how to migrate to this compaction style");
}
}
```
Therefore this PR
- Refactor the option migration implementation by moving the common parts into the high-level `OptionChangeMigration()` through `PrepareNoCompactionCFDescriptors()` and `OpenDBWithCFs()` so `MigrateAllCFs()` can focus on compaction only.
- Treat the original OptionChangeMigration() API as a special case of the multi-cf version option migration
- Add multiple-cf support
A few notes:
- CompactToLevel() originally modifies the compaction-related options conditionally before doing compaction. This is moved into earlier steps through `ApplySpecialSingleLevelSettings()` in `PrepareNoCompactionCFDescriptors()`
- MigrateToUniversal() originally opens the db twice with essentially the same option. This PR reduces that to one open
- Option migration does not always use the old option to compact the db and reopen the db after migration, see ` return CompactToLevel(new_opts, dbname, new_opts.num_levels - 1,/*l0_file_size=*/0, false);`. `PrepareNoCompactionCFDescriptors()` is where we handle those decisions.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14059
Test Plan:
- Existing UTs
- New UTs
Reviewed By: cbi42
Differential Revision: D84852970
Pulled By: hx235
fbshipit-source-id: 936b456cf9fb4c3ccb687e5d1387f2d67a1448be
Summary:
This diff introduces the async prepare of all iterators within a MultiScan. The current state has each iterator be prepared as its needed, and with this diff, we prepare all iterators during the prepare phase of the Level Iterator, this will allow more time for each IO to be dispatched and serviced, increasing the odds that a block is ready as the scan seeks to it.
Benchmark is prefilled using
```
KEYSIZE=64
VALUESIZE=512
NUMKEYS=5000000
SCAN_SIZE=100
DISTANCE=25000
NUM_SCANS=15
THREADS=1
./db_bench --db=$DB \
--benchmarks="fillseq" \
--write_buffer_size=5242880 \
--max_write_buffer_number=4 \
--target_file_size_base=5242880 \
--disable_wal=1 --key_size=$KEYSIZE \
--value_size=$VALUESIZE --num=$NUMKEYS --threads=32
}
```
And benchmark ran is
```
run() {
echo 1 | sudo tee /proc/sys/vm/drop_caches
./db_bench --db=$DB --use_existing_db=1 \
--benchmarks=multiscan \
--disable_auto_compactions=1 --seek_nexts=$SCAN_SIZE \
--multiscan-use-async-io=1 \
--multiscan-size=$NUM_SCANS --multiscan-stride=$DISTANCE \
--key_size=$KEYSIZE --value_size=$VALUESIZE \
--num=$NUMKEYS --threads=$THREADS --duration=60 --statistics
}
```
The benchmark uses large stride sides to ensure that two scans would touch separate files. We reduce the size of the block cache to increase likelyhood of reads (and simulate larger data sets)
**Branch:**
```
Integrated BlobDB: blob cache disabled
RocksDB: version 10.8.0
Date: Tue Nov 11 13:26:29 2025
CPU: 166 * AMD EPYC-Milan Processor
CPUCache: 512 KB
Keys: 64 bytes each (+ 0 bytes user-defined timestamp)
Values: 512 bytes each (256 bytes after compression)
Entries: 5000000
Prefix: 0 bytes
Keys per prefix: 0
RawSize: 2746.6 MB (estimated)
FileSize: 1525.9 MB (estimated)
Write rate: 0 bytes/second
Read rate: 0 ops/second
Compression: Snappy
Compression sampling rate: 0
Memtablerep: SkipListFactory
Perf Level: 1
------------------------------------------------
multiscan_stride = 25000
multiscan_size = 15
seek_nexts = 100
DB path: [/data/rocksdb/mydb]
multiscan : 837.941 micros/op 1193 ops/sec 60.001 seconds 71605 operations; (multscans:71605)
```
**Baseline:**
```
Set seed to 1762898809121995 because --seed was 0
Initializing RocksDB Options from the specified file
Initializing RocksDB Options from command-line flags
Integrated BlobDB: blob cache disabled
RocksDB: version 10.9.0
Date: Tue Nov 11 14:06:49 2025
CPU: 166 * AMD EPYC-Milan Processor
CPUCache: 512 KB
Keys: 64 bytes each (+ 0 bytes user-defined timestamp)
Values: 512 bytes each (256 bytes after compression)
Entries: 5000000
Prefix: 0 bytes
Keys per prefix: 0
RawSize: 2746.6 MB (estimated)
FileSize: 1525.9 MB (estimated)
Write rate: 0 bytes/second
Read rate: 0 ops/second
Compression: Snappy
Compression sampling rate: 0
Memtablerep: SkipListFactory
Perf Level: 1
------------------------------------------------
multiscan_stride = 25000
multiscan_size = 15
seek_nexts = 100
DB path: [/data/rocksdb/mydb]
multiscan : 1129.916 micros/op 885 ops/sec 60.001 seconds 53102 operations; (multscans:53102)
```
Repeated for confirmation.
This introduces a ~20% improvement in latency and op/s.
Note: Benchmarks are single threaded as, when increasing thread count, we start seeing large amounts of overhead being induced by block cache contention, finally resulting in both baseline and branch becoming equal.
Further on network attached storage with high latency, the level iterator, preparing all iterators so a 20% improvement even at high thread counts.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14100
Reviewed By: anand1976
Differential Revision: D86913584
Pulled By: krhancoc
fbshipit-source-id: da9d0c890e25e392a33389ce6b80f9bfb84d3f85
Summary:
Oversight in https://github.com/facebook/rocksdb/issues/13964. More detail:
* Applies to cache_bench and db_bench (db_stress already using it)
* Make sure those along with db_stress treat "hyper_clock_cache" as "auto_hyper_clock_cache" because this is now the blessed implementation.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14120
Test Plan: manual runs of the tools
Reviewed By: krhancoc
Differential Revision: D86913202
Pulled By: pdillinger
fbshipit-source-id: 07b425d3522103417f4b034735376b9d759af5fb
Summary:
Right now, in Java's Get() calls, the way Get() is treated is inefficient. Status.NotFound is turned into an exception in the JNI layer, and is caught in the same function to turn into not found return. This causes significant overhead in the scenario where most of the queries ending up with not found. For example, in Spark's deduplication query, this exception creation overhead is higher than Get() itself. With the proposed change, if return status is NotFound, we directly return, rather than going through the exception path
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14095
Test Plan: Existing tests should cover all Get() cases, and they are passing.
Reviewed By: jaykorean
Differential Revision: D86797594
Pulled By: cbi42
fbshipit-source-id: 1202d24e46a2358976bb7c8ff38a2fd4783d0f99
Summary:
There are instances where an application might be interested in knowing the distribution in SST files for a key range in a particular level.
This implementation creates an overloaded GetColumnFamilyMetaData api where (startKey, EndKey) can be passed along with level information to filter the necessary sst files along with the keyranges for each sst file
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14009
Reviewed By: anand1976
Differential Revision: D83389707
fbshipit-source-id: 6df1dc1f9233efe9000b03cc1831b3c618cbcef3
Summary:
Support trivial move in CompactFiles API, which is not supported previously.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14112
Test Plan: Unit test
Reviewed By: cbi42
Differential Revision: D86546150
Pulled By: xingbowang
fbshipit-source-id: 08a3ae9a055f3d3d41711403b1695f44977e6ea8
Summary:
**Summary:**
Merge the BuiltinFilterBitsBuilder into FilterBitsBuilder. This enables using
CalculateSpace() for accurate filter size estimation instead of hardcoded
bits-per-key which could result in incorrect estimations for different filter types.
The previous hardcoded estimate of 15 bits per key was in the filter block builders UpdateFilterSizeEstimate().
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14111
Test Plan: - Existing filter tests pass (bloom_test, full_filter_block_test, filter_bench, db_bloom_filter_test)
Reviewed By: pdillinger
Differential Revision: D86473287
Pulled By: nmk70
fbshipit-source-id: cd4a47351e67444e944d5b1b375b3b13274dd6e3
Summary:
For all compactions, RocksDB performs a lightweight sanity check on output SST files before installation (in `CompactionJob::VerifyOutputFiles()`). However, this lightweight check may not catch corruption that is small enough to allow the SST files to still be opened.
There is an existing feature, `paranoid_file_check`, which opens the SST file, iterates through all keys, and checks the hash of each key. While this provides the ultimate level of data integrity checking, it comes at a high computational cost.
In this PR, we introduce a new mutable CF option, `verify_output_flags`. The `verify_output_flags` is a bitmask enum that allows users to select various verification types, including block checksum verification, full key iteration, and file checksum verification (to be added in subsequent PRs). Note that the existing `paranoid_file_check` option is equivalent to a full key iteration check. Block-level checksum verification is much lighter than the full key iteration check.
Please note that the previously deprecated `verify_checksums_in_compaction` option (removed in version 5.3.0) was for verifying the checksum of **input SST files**. RocksDB continues to perform this verification for both local and remote compactions, and this behavior remains unchanged. In contrast, this PR focuses on verifying the **output SST files**.
## To follow up
- File-level Checksum verification for output SST files
- Deprecate `paranoid_file_checks` option in favor of the new option
- Add to stress test / db_bench
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14103
Test Plan:
New Unit Test added. The corruption is both detected by `paranoid_file_check` and various types of verification set by this new option, `verify_output_flags`
```
./compaction_service_test --gtest_filter="*CompactionServiceTest.CorruptedOutput*"
```
Reviewed By: pdillinger
Differential Revision: D86357924
Pulled By: jaykorean
fbshipit-source-id: a9e04798f249c7e977231e179622a0830d6675fe
Summary:
MultiScanUnexpectedSeekTarget() currently uses user key comparison to decide on the next data block for multiscan. This can cause a multiscan to move backward in the following scenario:
data block 1: ..., k@7, k@6
data block 2: k@5, ...
DB iter scan through k@7, k@6 and k@5 and decides to seek to k@0 due to option [`max_sequential_skip_in_iterations`](https://github.com/facebook/rocksdb/blob/d56da8c112b4e6968fd79ce2bf15e6435df40656/include/rocksdb/advanced_options.h#L621-L629). Multiscan was on data block 2, but moves to data block 1 after the seek.
This can cause assertion failure in debug mode and seg fault in prod since older data blocks are unpinned and freed as we advanced a multiscan. This PR fixes the issue by forcing a multiscan to never go backward.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14106
Test Plan: - added a new unit test that reproduces the scenario: `./db_iterator_test --gtest_filter="*ReseekAcrossBlocksSameUserKey*"`
Reviewed By: xingbowang
Differential Revision: D86428845
Pulled By: cbi42
fbshipit-source-id: ab623f93e73298a60857fb2ff268366f289092a0
Summary:
This test is now taking > 6 hours, timing out, and has low signal, so creating a weekly job for it, with an explicit timeout of 12 hours.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14110
Test Plan: watch CI
Reviewed By: virajthakur
Differential Revision: D86428262
Pulled By: pdillinger
fbshipit-source-id: 44103518064ca378f3fd2ff8d21967ede698c8ea
Summary:
Adds auto-tuning of manifest file size to avoid the need to scale `max_manifest_file_size` in proportion to things like number of SST files to properly balance (a) manifest file write amp and new file creation, vs. (b) manifest file space amp and replay time, including non-incremental space usage in backups. (Manifest file write amp comes from re-writing a "live" record when the manifest file is re-created, or "compacted"; space amp is usage beyond what would be used by a compacted manifest file.) In more detail,
* Add new option `max_manifest_space_amp_pct` with default value of 500, which defaults to 0.2 write amp and up to roughly 5.0 space amp, except `max_manifest_file_size` is treated as the "minimum" size before re-creating ("compacting") the manifest file.
* `max_manifest_file_size` in a way means the same thing, with the same default of 1GB, but in a way has taken on a new role. What is the same is that we do not re-create the manifest file before reaching this size (except for DB re-open), and so users are very unlikely to see a change in default behavior (auto-tuning only kicking in if auto-tuning would exceed 1GB for effective max size for the current manifest file). The new role is as a file size lower bound before auto-tuning kicks in, to minimize churn in files considered "negligibly small." We recommend a new setting of around 1MB or even smaller like 64KB, and expect something like this to become the default soon.
* These two options along with `manifest_preallocation_size` are now mutable with SetDBOptions. The effect is nearly immediate, affecting the next write to the current manifest file.
Also in this PR:
* Refactoring of VersionSet to allow it to get (more) settings from MutableDBOptions. This touches a number of files in not very interesting ways, but notably we have to be careful about thread-safe access to MutableDBOptions fields, and even fields within VersionSet. I have decided to save copies of relevant fields from MutableDBOptions to simplify testing, etc. by not saving a reference to MutableDBOptions but getting notified of updates.
* Updated some logging in VersionSet to provide some basic data about final and compacted manifest sizes (effects of auto-tuning), making sure to avoid I/O while holding DB mutex.
* Added db_etc3_test.cc which is intended as a successor to db_test and db_test2, but having "test.cc" in its name for easier exclusion of test files when using `git grep`. Intended follow-up: rename db_test2 to db_etc2_test
* Moved+updated `ManifestRollOver` test to the new file to be closer to other manifest file rollover testing.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14076
Test Plan:
As for correctness, new unit test AutoTuneManifestSize is pretty thorough. Some other unit tests updated appropriately. Manual tests in the performance section were also audited for expected behavior based on the new logging in the DB LOG. Example LOG data with -max_manifest_file_size=2048 -max_manifest_space_amp_pct=500:
```
2025/10/24-11:12:48.979472 2150678 [/version_set.cc:5927] Created manifest 5, compacted+appended from 52 to 116
2025/10/24-11:12:49.626441 2150682 [/version_set.cc:5927] Created manifest 24, compacted+appended from 2169 to 1801
2025/10/24-11:12:52.194592 2150682 [/version_set.cc:5927] Created manifest 91, compacted+appended from 10913 to 8707
2025/10/24-11:13:02.969944 2150682 [/version_set.cc:5927] Created manifest 362, compacted+appended from 52259 to 13321
2025/10/24-11:13:18.815120 2150681 [/version_set.cc:5927] Created manifest 765, compacted+appended from 80064 to 13304
2025/10/24-11:13:35.590905 2150681 [/version_set.cc:5927] Created manifest 1167, compacted+appended from 79863 to 13304
```
As you can see, it only took a few iterations of ramp-up to settle on the auto-tuned max manifest size for tracking ~122 live SST files, around 80KB and compacting down to about 13KB. (13KB * (500 + 100) / 100 = 78KB). With the default large setting for max_manifest_file_size, we end up with a 232KB manifest, which is more than 90% wasted space. (A long-running DB would be much worse.)
As for performance, we don't expect a difference, even with TransactionDB because actual writing of the manifest is done without holding the DB mutex. I was not able to see a performance regression using db_bench with FIFO compaction and >1000 ~10MB SST files, including settings of -max_manifest_file_size=2048 -max_manifest_space_amp_pct={500,10,0}. No "hiccups" visible with -histogram either.
I also tried seeding a 1 second delay in writing new manifest files (other than the first). This had no significant effect at -max_manifest_space_amp_pct=500 but at 100 started causing write stalls in my test. In many ways this is kind of a worst case scenario and out-of-proportion test, but gives me more confidence that a higher number like 500 is probably the best balance in general.
Reviewed By: xingbowang
Differential Revision: D85445178
Pulled By: pdillinger
fbshipit-source-id: 1e6e07e89c586762dd65c65bb7cb2b8b719513f9
Summary:
**Summary:**
This change introduces tail size estimation during SST construction to improve compaction file cutting accuracy to prevent oversized files. The BlockBasedTableBuilder now estimates the SST tail size (index and filter blocks) and uses this estimate, in addition to the data size, to determine when to cut files during compaction.
**Problem:**
Currently, file cutting logic only considers data size when determining where to cut a file, failing to reserve space for index and filter blocks that are added when the file is finalized. This often leads to SST files that exceed target file size limits.
**Behavior Change:**
Implement size estimation methods for index and filter builders, and integrate these estimates into BlockBasedTableBuilder via a new EstimatedTailSize() method. This method aggregates estimates from all tail components and is used for file cutting decisions during compaction.
**Performance Considerations:**
To minimize CPU overhead, size estimates are updated when data blocks are finalized rather than on every key add. For index builders, estimates are updated when index entries are added (one per data block). For filter builders, the OnDataBlockFinalized() hook triggers estimate updates when data blocks are cut/finalized.
This approach provides:
* Minimal impact to compaction hot path (key additions)
* Near real-time estimates for file cutting decisions
* Meaningful estimate changes only when data blocks are finalized
**Usage:**
* Set true mutable cf option `compaction_use_tail_size_estimation`
to use tail size estimation for compaction file cutting decisions.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14051
Test Plan:
* Assert tail size estimate is an overestimate in BlockBasedTableBuilder::Finish
* Add new test to verify compaction output file is below target file size
**Next steps:**
* Enable tail size estimation for compaction file cutting by default (and other improvements)
Reviewed By: pdillinger, cbi42
Differential Revision: D84852285
Pulled By: nmk70
fbshipit-source-id: c43cf5dbd2cb2f623a0622591ef24eee30ce0c87
Summary:
* Fix nightly build-linux-cmake-with-folly-lite-no-test for real this time
with correct include directory. (CMakeLists.txt)
* Add test runs to that build (and rename)
* Improve folly build caching with a folly.mk file with most of the relevant
parts of Makefile that contribute to the checkout_folly and
build_folly builds. This reduces the risk of false passing of CI job with
cache folly build. This caching is still only for folly debug builds, (which
is probably OK with just a single nightly build relying on release folly
build, which also serves as a rough canary against false passing
because of caching).
* Use `make VERBOSE=1` after cmake calls for detailed output
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14099
Test Plan:
temporary CI change to put the relevant parts in pr-jobs,
then back to homes including in nightly
Reviewed By: mszeszko-meta
Differential Revision: D86243363
Pulled By: pdillinger
fbshipit-source-id: f7975fa190ef45195c6d0b74417f7886e551516a
Summary:
... caused by public headers depending on build parameters (macro definitions). This change also adds a check under 'make check-headers' (already in CI) looking for potential future violations.
I've audited the uses of '#if' in public headers and either
* Eliminated them
* Systematically excluded them because they are intentional or similar (details in comments in check-public-header.sh
* Manually excluded them as being ODR-SAFE
In the case of ROCKSDB_USING_THREAD_STATUS, there was no good reason for this to appear in public headers so I've replaced it with a static bool ThreadStatus::kEnabled. I considered getting rid of the ability to disable this code but some relatively recent PRs have been submitted for fixing that case. I've added a release note and updated one of the CI jobs to use this build configuration. (I didn't want to combine with some jobs like no_compression and status_checked because the interaction might limit what is checked.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14096
Test Plan: manual 'make check-headers' + manual cmake as in new CI config + CI
Reviewed By: jaykorean
Differential Revision: D86241864
Pulled By: pdillinger
fbshipit-source-id: d16addc9e3480706b174a006720a4def0740bf2e
Summary:
Following up on https://github.com/facebook/rocksdb/pull/14071, updating folly to
https://github.com/facebook/folly/commit/8a9fc1e80a18cafadbec85e33d5042ce13a7c634 or beyond was failing an F14Table assertion for a very subtle reason: ODR violation between the folly build and RocksDB build because folly build was release mode and RocksDB build was debug mode. What was happening was that folly change introduced a dependence on kDebug (whether build is debug) in a hashing implementation in a .h file, and the inconsistency between the inlined implementation during RocksDB build and the linked-to implementation from the folly build was leading to inconsistencies in the data structure.
The primary fix is to ensure we build folly in debug mode for debug mode RocksDB builds. Also,
* Needed to use the `patchelf` tool in `build_folly` to ensure the glog dependency shared library can always find its own gflags dependency. I explored many options for working around this, and this is what would work without reworking folly's own build.
* Updated folly to latest commit.
* Thrown in an ad hoc folly patch to use ftp.gnu.org mirrors (the canonical is super slow)
* Moved the placement of GETDEPS_USE_WGET=1 to apply to local builds also, to avoid the issue of a large download almost reaching completion and then stalling indefinitely.
* Fix failing nightly build-linux-cmake-with-folly-lite-no-test with fmt includes in cmake build (as was done with make build)
* Add a release mode folly+RocksDB to nightly CI, including both cmake and make. This also serves as a non-cached folly build to detect potential problems with PR jobs working from cached folly build.
* Move build-linux-cmake-with-folly to nightly because it's mostly covered by build-linux-cmake-with-folly-coroutines
Intended follow-up:
* folly-lite build with tests
* Make the folly build caching more friendly+accurate by hashing the relevant Makefile parts and tagging whether debug or release. Not in this PR because then you wouldn't be able to see what changed in the folly build steps themselves.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14094
Test Plan: manual + CI
Reviewed By: mszeszko-meta
Differential Revision: D85864871
Pulled By: pdillinger
fbshipit-source-id: 50009b33422d5781074fcbbdf18089be9e36800d
Summary:
Resolving this folly upgrade required fixing the FOLLY_LITE build with header include from the 'fmt' library.
I was close to timing out on fixing USE_FOLLY_LITE and removing it altogether - it could be considered obsolete and/or not worth the maintenance cost.
Follow-up: make the folly build caching more friendly by hashing the relevant makefile parts. Not in this PR because then you wouldn't be able to see what changed in the folly build steps themselves.
UPDATE/NOTE: I wasn't able to fully update to latest due to a failure seen in F14, using the next folly commit or later. The source of the bug is likely outside of F14 but investigation is in progress.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14071
Test Plan: CI
Reviewed By: jaykorean
Differential Revision: D85268833
Pulled By: pdillinger
fbshipit-source-id: 1d0a2d61f095524a20e6ec796ef46c02d0696f4e
Summary:
Change PosixWritableFile's Truncate to the new end offset. This ensures that future appends are written with no holes or overwrites. RocksDB doesn't guarantee this in the FileSystem contract, and its left up to the specific implementation.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14088
Reviewed By: cbi42
Differential Revision: D85786398
Pulled By: anand1976
fbshipit-source-id: 3520d9d6336362f5128a17bbf396297d821a5da3
Summary:
Comprehensive performance optimizations for the RocksDB C API that eliminate unnecessary memory allocations and copies.
## Key Changes
### 1. PinnableSlice for Get Operations (50% reduction in copies)
- Changed all `rocksdb_get*` functions to use `PinnableSlice` internally instead of `std::string`
- **Before:** RocksDB → std::string → malloc'd buffer (2 copies)
- **After:** RocksDB → malloc'd buffer (1 copy)
- Affects: Get, Transaction Get, TransactionDB Get, WriteBatch Get variants
### 2. Array-Based MultiGet with PinnableSlice (30% allocation reduction)
- Switched MultiGet operations to use optimized array-based RocksDB API with `PinnableSlice`
- Eliminates vector overhead and string allocations
- Affects: MultiGet, Transaction MultiGet, TransactionDB MultiGet variants
### New Zero-Copy APIs
Added high-performance zero-copy functions for applications that can use them:
- `rocksdb_iter_key_slice()` / `value_slice()` / `timestamp_slice()` - Return slices by value (eliminates output param overhead)
- `rocksdb_batched_multi_get_cf_slice()` - Batched get with slice array input
- `rocksdb_slice_t` - ABI-compatible slice type
Note that this pr builds on top of https://github.com/facebook/rocksdb/pull/13911
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14036
Reviewed By: pdillinger
Differential Revision: D85604919
Pulled By: jaykorean
fbshipit-source-id: 7f04b935eea79af1d45b3125a79b90e4706666f6
Summary:
Stress test can fail with assertion inside MultiScan in some reseek scenario. E.g., data block 1 ends with k@9, data block 2 starts with k@8, when a DB iter seeks to k@0 (see option `max_sequential_skip_in_iterations`), MultiScan will land in data block 1 due to https://github.com/facebook/rocksdb/blob/fd0b4e0cf08315f6a644d54d585fe70ca958d4ba/table/block_based/block_based_table_iterator.cc#L1258-L1263.
We can't just use internal key as separator since index block might not use it. I plan to follow up with a fix that never moves `cur_data_block_idx` backward within a MultiScan.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14087
Test Plan: CI and internal crash tests
Reviewed By: anand1976
Differential Revision: D85701668
Pulled By: cbi42
fbshipit-source-id: d3f1aaff40a12be4e3d1b4b7160bf2547f43b849
Summary:
All remote compaction test failures had `mmap_read=1` in common. Unfortunately, the failure hasn't been very reproducible. Try disabling `mmap_read` to see if that shed some light.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14083
Test Plan: CI
Reviewed By: hx235
Differential Revision: D85622229
Pulled By: jaykorean
fbshipit-source-id: bbe9e08efc369813f0fec388c910446089e43650
Summary:
As titled, this fixes some internal crash test failures when UDT is enabled.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14085
Test Plan: monitor crash tests.
Reviewed By: anand1976
Differential Revision: D85617949
Pulled By: cbi42
fbshipit-source-id: da6fb21c0ca5803ea24e8daf7de8558321babcf4
Summary:
Due to some internal requirements, what's being used for`$SSH` and `$SCP` has changed and it broke the regression test. (e.g. tarball streaming to remote host no longer works)
Minor behavior changes to the script to make the internal workflow work.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14079
Test Plan:
```
./tools/regression_test.sh
```
Meta Internal automation
Reviewed By: pdillinger
Differential Revision: D85502798
Pulled By: jaykorean
fbshipit-source-id: d294c2ee47661fbe368ccc318062e891f3ac7c81
Summary:
The TTL-based WAL archive cleanup logic could incorrectly delete an archived WAL if the system clock moved backwards between the last write to that WAL and `WALManager::PurgeObsoleteWALFiles()`. This happened due to unsigned underflow in subtraction of two wall clock based timestamps: `now_seconds - file_m_time`.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14016
Test Plan: unit test repro
Reviewed By: pdillinger
Differential Revision: D83879806
Pulled By: hx235
fbshipit-source-id: 643e7f623c6b5c31711565854314cfd6cbbcf3a7
Summary:
Fixed a missing CV signal when `FindObsoleteFiles()` decides there is nothing to purge and then decrements `pending_purge_obsolete_files_` to zero. This bug could cause `DB::GetSortedWalFiles()` to hang, at least.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14069
Test Plan: unit test repro
Reviewed By: hx235
Differential Revision: D85453534
Pulled By: cbi42
fbshipit-source-id: cf5cfe7f5087459ca1f1f28ce81ea6afc84178f0
Summary:
* Address feedback from https://github.com/facebook/rocksdb/issues/14040
* Add additional test for MultiScan
* Fix a bug when del range and data are in same file for multi-scan
* Rewrite the cases need to be handled in SeekMultiScan
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14055
Test Plan: Unit test
Reviewed By: cbi42, anand1976
Differential Revision: D84851788
Pulled By: xingbowang
fbshipit-source-id: 0f69632733afb99685f6341badbf239681010c38
Summary:
Linter complains like this
```
void foo(Arg parameter_name) {}
void bar() {
Arg a;
foo(/*some_other_name=*/ a); // Wrong! Comment/parameter name mismatch
foo(/*parameter_name=*/ a); // This is OK; the names match.
}
```
```
Argument name in comment (`read_only`) does not match parameter name (`unchanging`).
```
This used to be warning, but now treated as an error :(
Fixing a few other linter warnings before they become errors in the future.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14074
Test Plan: CI
Reviewed By: archang19
Differential Revision: D85370353
Pulled By: jaykorean
fbshipit-source-id: 20e96aad740d516a29c0424282674e655f99c0a2
Summary:
When a standalone range deletion file is ingested in L0, currently it is compacted with any overlapping L0 files. This is not desirable when we ingest new data on top of the range deletion file. This PR fixes the compaction picking logic to only consider L0 files older than the standalone range deletion file.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14061
Test Plan: added a new unit test and updated an existing one.
Reviewed By: xingbowang
Differential Revision: D84930780
Pulled By: cbi42
fbshipit-source-id: 65f4403ccb40ba964b9e65b09e2f7f7efebe81df
Summary:
**Context/Summary:**
- Add resumable compaction to stress test with adaptive progress cancellation
- Add fault injection to remote compaction
- Fix a real minor bug in a couple testing framework bugs with remote compaction
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14041
Test Plan: - Rehearsal stress test, finding bugs for https://github.com/facebook/rocksdb/pull/13984 effectively and did not create new failures.
Reviewed By: jaykorean
Differential Revision: D84524194
Pulled By: hx235
fbshipit-source-id: 42b4264e428c6739631ed9aa5eb02723367510bc
Summary:
With cache hit and compiler option optimization, the compilation time build time is reduced from 40 min to 2 min. Overall build time is reduced from 60 min to less 20 minutes on cache hit on majority of the source file. On 100% cache miss, it would be around 40 minutes.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14064
Test Plan: Github CI
Reviewed By: mszeszko-meta
Differential Revision: D85023882
Pulled By: xingbowang
fbshipit-source-id: 98551880c98f14d36133ff43e6af8c3be94ab465
Summary:
Fixing a nullptr access in multiscan, under following situation.
```
Block Based Table: blk1:[k1,k2], blk2:[k3, k8], blk3:[k9]
Scan ranges: [k1, k4), [k5,k6), [k7, k10)
Prepared block ranges: [0,2], [2,2], [1,3]
```
1. Seek key k1 on the first range, read key k1, k2.
2. Seek key k4 on the 2nd range, blocks 0,1 would be unpinned.
3. Seek key k9, block 1 would be accessed, but it is unpinned, which trigger assert failure in debug mode and nullptr access on release build.
This fix changes how blocks are unpinned. It is now only unpinning the block, when the cur_data_block_idx has passed it.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14062
Test Plan:
Unit Test
rand_seed 304010984 on UserDefinedIndexStressTest
Reviewed By: cbi42
Differential Revision: D84976410
Pulled By: xingbowang
fbshipit-source-id: 6b99bf85fc9d4108c5267ae77be77ccfe08923cd
Summary:
**Problem:** RocksDB was making unnecessary prefetch system calls on file systems that don't support prefetch operations, potentially leading to wasted CPU cycles.
**Fix:** Add kFSPrefetch to FSSupportedOps enum to allow file systems to indicate prefetch support capability. File systems can now opt out of prefetch calls by not setting this field.
**Backwards compatibility:** File systems that don't override SupportedOps() continue to receive prefetch calls exactly as before. Only file systems that explicitly opt out by not setting kFSPrefetch will avoid the calls.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13917
Test Plan:
- Added a new test in block_based_table_reader.
- Run existing tests: ```make prefetch_test && ./prefetch_test```
Reviewed By: anand1976
Differential Revision: D81607145
Pulled By: nmk70
fbshipit-source-id: 3bbefa05919034e8776ea4e4540cdc695cdc6d3f
Summary:
Currently we return `File is too large for PlainTableReader!` when the file size exceeds our pre-defined constant. There was a request to have the file size information logged when this error is returned.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14056
Reviewed By: nmk70
Differential Revision: D84834869
Pulled By: archang19
fbshipit-source-id: 8f332b6a31d51f320c7e2db06ad49f50798ff70e
Summary:
* Reduce build time of folly from 45m~1hr down to 25m. This is achieved by caching folly build artifact from previous build.
* Reduce windows build time of folly from 1hr 15m down to 50m. This is done by increase windows build machine size.
* Fix build on macos on other macos target.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14057
Test Plan: github CI
Reviewed By: archang19, nmk70
Differential Revision: D84848041
Pulled By: xingbowang
fbshipit-source-id: 00306750737070e7e446ee436d607ed6ecae79ae
Summary:
We simulate remote compaction in our stress test by running a separate set of worker threads to run compactions. In reality, these remote compactions run on a different host or (at least in a different process) where we cannot share the TableFactory and BlockCache with the main DB process.
To make this simulated remote compaction closer to reality, create a new TableFactory for each remote compaction in stress test.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14050
Test Plan:
```
python3 -u tools/db_crashtest.py --cleanup_cmd='' --simple blackbox --remote_compaction_worker_threads=8 --interval=10
```
Reviewed By: hx235
Differential Revision: D84775656
Pulled By: jaykorean
fbshipit-source-id: d6203fcbe0eca3539e008a19fd47b742553537ed
Summary:
We are adding more and more tests, so we need to increase the number of shards in macos build to reduce overall CI time.
macos-15-xlarge image is ARM, which has 5 vCPU cores, but is still 50% faster than the intel x86 12 vCPU.
Test time reduced from 1h 37m to 14m.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14048
Reviewed By: archang19
Differential Revision: D84741917
Pulled By: xingbowang
fbshipit-source-id: 9ba9bd696d3b2152f11dec2fb4280572b98233d5
Summary:
Currently in BlockBasedTableIterator's Prepare(), the index lookup for a MultiScan range is expected to return atleast 1 data block (unless UDI is in use). This is because there's an implicit assumption that only ranges intersecting with the keys in the file will be prepared. This assumption, however, doesn't hold if there are range deletions and the smallest and/or largest keys in the file extend beyond the keys in the file. The LevelIterator prunes the MultiScan ranges based on the smallest/largest key, so its possible for a range to only overlap the range deletion portion of the file and not overlap any of the data blocks. Furthermore, the BlockBasedTableIterator is now much more forgiving of Seek to targets outside of prepared ranges after https://github.com/facebook/rocksdb/issues/14040 .
Keeping the above in mind, this PR removes the check in BlockBasedTableIterator for non-empty index result. It adds assertions in LevelIterator to verify that ranges are being properly pruned. Another side effect is we can no longer rely solely on a scan range having 0 data blocks (i.e cur_scan_start_idx >= cur_scan_end_idx) to decide if the iterator is out of bound. We can only do so for all but the last range prepared range.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14046
Test Plan:
1. Add unit test in db_iterator_test
2. Run crash test
Reviewed By: xingbowang
Differential Revision: D84623871
Pulled By: anand1976
fbshipit-source-id: 2418e629f92b1c46c555ddea3761140f700819e4
Summary:
The current seek key validation is too strict. This change relaxes it at block iterator level, and add additional check at DB iterator level. The new contract is that when MultiScan is used, after prepared is called, each following seek must seek the start key of the prepared scan range in order. Otherwise, the iterator is set with error status.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14040
Test Plan: Unit test
Reviewed By: anand1976
Differential Revision: D84292297
Pulled By: xingbowang
fbshipit-source-id: 7b31f727e67e7c0bfc53c2f9a6552e0c3d324869
Summary:
Multi scan crash/stress tests are failing when skip_stats_update_on_db_open is true, because LevelIterator::Prepare relies on these stats in FileMetaData to make decisions. Disable it in crash tests until the proper fix is ready.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14039
Reviewed By: archang19
Differential Revision: D84280059
Pulled By: anand1976
fbshipit-source-id: f9f58b94c24d1f455432b05f3bf97f25c7233e3c
Summary:
**Context/Summary:**
There is no way to tag or rate-limit write IO occurs during FlushWAL() with priority. Under `Options::manual_wal_flush=true`, it is the major source of write IO during user writes so we decide to add that support. A new option struct `FlushWALOptions` is introduced to avoid making the API ugly for future new fields.
Also, we can't use the WriteOptions (https://github.com/facebook/rocksdb/blob/main/include/rocksdb/options.h#L2293-L2302 i) since is associated with that particular Put/Merge/.. associated with that option but FlushWAL() can happen after that write. There is no way to carry that write option over in RocksDB. I also avoided using the WriteOptions since it's mostly for live write.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14037
Test Plan: New UTs `TEST_P(DBRateLimiterOnManualWALFlushTest, ManualWALFlush)`
Reviewed By: archang19
Differential Revision: D84193522
Pulled By: hx235
fbshipit-source-id: 18feb5235672010d19a101ce52c8abdcc4a789f2
Summary:
- Include Status in RemoteCompactionResultMap in SharedState so that we can directly check the status of the remote compaction in `DbStressCompactionService::Wait()`
- If result is empty, populate the result with the status that was returned from `GetRemoteCompactionResult()` so that the status can be bubbled up to the primary (main db thread)
- Get rid of Timeout in `Wait()`
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14022
Test Plan:
With fall-back
```
python3 -u tools/db_crashtest.py blackbox --remote_compaction_worker_threads=8 --remote_compaction_failure_fall_back_to_local=1
```
Without fall-back
```
python3 -u tools/db_crashtest.py blackbox --remote_compaction_worker_threads=8 --remote_compaction_failure_fall_back_to_local=0
```
Reviewed By: hx235
Differential Revision: D83789172
Pulled By: jaykorean
fbshipit-source-id: 08f710c4ece5fcc1d4b95b3f9c353831882851b7
Summary:
Fix the binutils truncated download issue by switching to wget in the folly build scripts for downloading dependencies.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14030
Test Plan: make build_folly
Reviewed By: jaykorean
Differential Revision: D84033126
Pulled By: anand1976
fbshipit-source-id: bc6706d7e57c97d6edff149a965aa12c7959825f
Summary:
MultiScan currently doesn't handle delete range properly. In this specific case, a file with only delete range will have an empty index resulting in BlockBasedTableIterator wrongly thinking that a scan doesn't intersect the file due to empty result.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14026
Test Plan: Run crash test
Reviewed By: xingbowang
Differential Revision: D83881266
Pulled By: anand1976
fbshipit-source-id: dc1faa494ea23f36391b700dd1ee0430a1f20ac5
Summary:
When there is an ingested SST file that only contains delete range operations, MultiScan may return error "Scan does not intersect with file". This is due to file selection during Prepare uses the file smallest and largest key without considering whether there is any key in the file. This is only a temporary fix.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14028
Test Plan: Unit test
Reviewed By: anand1976
Differential Revision: D83986964
Pulled By: xingbowang
fbshipit-source-id: e0961ca854e2062c2457be4324817ba073ae785d
Summary:
Implicit reseek in the middle of an iteration is not supported with MultiScan. Avoid this for now in crash tests by setting max_sequential_skip_in_iterations to an absurdly high value.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14015
Reviewed By: xingbowang
Differential Revision: D83761612
Pulled By: anand1976
fbshipit-source-id: 16f4e856374b79170c0a79c11c275cbb0fc83a70
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14024
Fix some typo found along the codebase
Reviewed By: pdillinger
Differential Revision: D83789182
fbshipit-source-id: feb24d7d47a6faaf735fcfd50dd3ecce4a6c8cd5
Summary:
When inplace_update_support and memtable_veirfy_per_key_checksum_on_seek are enabled at the same time, it would cause data race in memtable.
inplace_update_support allows key/value pair in place update in memtable.
memtable_veirfy_per_key_checksum_on_seek performs key checksum verification during seek. It is possible that one thread is updating the key/value pair in place, while another thread is reading the key/value pair for checksum verification during seek.
Therefore, there these 2 configurations could not be enabled at the same time
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14023
Test Plan: local stress test run stops reporting race condition
Reviewed By: anand1976
Differential Revision: D83812322
Pulled By: xingbowang
fbshipit-source-id: 6cb9f0f3faa8deba97305bfe87266f2fe78e0501
Summary:
In RocksDB 10.6 with https://github.com/facebook/rocksdb/issues/13805, due to inaccurate testing of an async system, it went undetected at the time that LZ4 compression was using more CPU despite making a change to reuse stream objects which dramatically improved LZ4HC compression efficiency.
This change switches to using a basic LZ4 compress API which appears to be faster than all of these:
* Legacy behavior of creating LZ4_stream_t for each compression
* 10.6-10.7 behavior of re-using streams between compressions for the same file (with stream-as-WorkingArea)
* using LZ4's extState APIs without streams (with extState-as-WorkingArea) (data not shown in below results)
Also in this PR: more improvements to sst_dump --recompress, which is arguably the best SST construction benchmark right now since db_bench seems to be so noisy due to backgroun flush+compaction, even with no compaction (FIFO). Streamlined some output and added a SST read time test, mostly for decompression performance.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14017
Test Plan:
Performance test using sst_dump --recompress with newer sst_dump back-ported to 10.5:
```
./sst_dump --command=recompress --compression_types=kLZ4Compression
test5.sst --compression_level_from=-6 --compression_level_to=-1
```
and with default compression level.
10.5:
```
Cx level: -6 Cx size: 61608137 Write usec: 880404
Cx level: -5 Cx size: 60793749 Write usec: 840903
Cx level: -4 Cx size: 58134030 Write usec: 836365
Cx level: -3 Cx size: 55193773 Write usec: 857113
Cx level: -2 Cx size: 54013891 Write usec: 855642
Cx level: -1 Cx size: 50400393 Write usec: 865194
Cx level: 32767 Cx size: 50400393 Write usec: 886310
```
Before this change (showing the regression, more time, from 10.6:
```
Cx level: -6 Cx size: 61608137 Write usec: 933448
Cx level: -5 Cx size: 60793749 Write usec: 893826
Cx level: -4 Cx size: 58134030 Write usec: 891138
Cx level: -3 Cx size: 55193773 Write usec: 898461
Cx level: -2 Cx size: 54013891 Write usec: 897485
Cx level: -1 Cx size: 50400393 Write usec: 936970
Cx level: 32767 Cx size: 50400393 Write usec: 958764
```
After this change (faster than both the above):
```
Cx level: -6 Cx size: 63641883 Write usec: 874190
Cx level: -5 Cx size: 58860032 Write usec: 834662
Cx level: -4 Cx size: 57150188 Write usec: 832707
Cx level: -3 Cx size: 58791894 Write usec: 850305
Cx level: -2 Cx size: 53145885 Write usec: 839574
Cx level: -1 Cx size: 49809139 Write usec: 845639
Cx level: 32767 Cx size: 49809139 Write usec: 875199
```
Similar tests with dictionary compression show essentially no difference (need to use stream APIs and reuse doesn't seem to matter). LZ4HC also unaffected (still improved vs. 10.5)
Reviewed By: hx235
Differential Revision: D83722880
Pulled By: pdillinger
fbshipit-source-id: 30149dd187686d5dd98321e6aa7d74bd7653a905
Summary:
Pad block based table based on super block alignment
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13909
Test Plan:
Unit Test
No impact on perf observed due to change in the inner loop of flush.
upstream/main branch 202.15 MB/s
```
for i in `seq 1 10`; do ./db_bench --benchmarks=fillseq -num=10000000 -compaction_style=2 -fifo_compaction_max_table_files_size_mb=1000 -fifo_compaction_allow_compaction=0 -disable_wal -write_buffer_size=12000000 -format_version=7 >> /tmp/x1 2>&1; grep fillseq /tmp/x1 | grep -Po "\d+\.\d+ MB/s" | grep -Po "\d+\.\d+" | awk '{sum+=$1} END {print sum/NR}'
```
After the change without super block alignment 203.44 MB/s
```
for i in `seq 1 10`; do ./db_bench --benchmarks=fillseq -num=10000000 -compaction_style=2 -fifo_compaction_max_table_files_size_mb=1000 -fifo_compaction_allow_compaction=0 -disable_wal -write_buffer_size=12000000 -format_version=7 >> /tmp/x1 2>&1
```
After the change with super block alignment 204.47 MB/s
```
for i in `seq 1 10`; do ./db_bench --benchmarks=fillseq -num=10000000 -compaction_style=2 -fifo_compaction_max_table_files_size_mb=1000 -fifo_compaction_allow_compaction=0 -disable_wal -write_buffer_size=12000000 -format_version=7 --super_block_alignment_size=131072 --super_block_alignment_max_padding_size=4096 >> /tmp/x1 2>&1;
```
Reviewed By: pdillinger
Differential Revision: D83068913
Pulled By: xingbowang
fbshipit-source-id: eecd65088ab3e9dbc7902aab8c2580f1bc8575df
Summary:
### Context/Summary:
Flow of resuming: DB::OpenAndCompact() -> Compaction progress file -> SubcompactionProgress -> CompactionJob
Flow of persistence: CompactionJob -> SubcompactionProgress -> Compaction progress file -> DB that is called with OpenAndCompact()
This PR focuses on SubcompactionProgress -> CompactionJob and CompactionJob -> SubcompactionProgress -> Compaction progress file. For now only single subcompaction is supported as OpenAndCompact() does not partition compaction anyway.
The actual triggering of progress persistence and resuming (i.e, integration) is through DB::OpenAndCompact() in the upcoming PR.
**Resume Flow**
1. input_iter->Seek(next_internal_key_to_compact) // Position iterator
2. ReadTableProperties() // Validate existing outputs
3. RestoreCompactionOutputs() in CompactionOutputs // Rebuild output file metadata
4. Restore critical statistics about processed input and output records count for verification later
5. AdvanceFileNumbers() // Prevent file number conflicts
6. Continue normal compaction from positioned iterator or fallback to not resuming compaction in limited case or fail the compaction entirely
**Persistence Strategy**
1. When: At each SST file completion (FinishCompactionOutputFile()). This is the simplest but most expensive frequency. See below for benchmarking and potential follow-up items
2. What: Serialize, write and sync the in-memory SubcompactionProgress to a dedicated manifest-like file
3. For simplicity: Only persist at "clean" boundaries (no overlapping user keys, no range deletions, no timestamp for now)
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13983
Test Plan:
- New unit test in CompactionJob level to cover basic compaction progress resumption
- Existing UTs and stress/crash test to test no correctness regression to existing compaction code
- Run benchmark to ensure no performance regression to existing compaction code
```
./db_bench --benchmarks=fillseq[-X10] --db=$db --disable_auto_compactions=true --num=100000 --value_size=25000 --compression_type=none --target_file_size_base=268435456 --write_buffer_size=268435456
```
Pre-PR:
fillseq [AVG 10 runs] : 45127 (± 799) ops/sec; 1076.6 (± 19.1) MB/sec
fillseq [MEDIAN 10 runs] : 45375 ops/sec; 1082.5 MB/sec
Post-PR (regressed 0.057%, ignorable)
fillseq [AVG 10 runs] : 45101 (± 920) ops/sec; 1076.0 (± 22.0) MB/sec
fillseq [MEDIAN 10 runs] : 45385 ops/sec; 1082.8 MB/sec
Reviewed By: jaykorean
Differential Revision: D82889188
Pulled By: hx235
fbshipit-source-id: 8553fd478f134969d331af2c5a125b94bd747268
Summary:
This method will be used to improve the compaction logic by accounting for the tail size, in addition to the data size, when determining when to cut a file.
Problem: Currently the file cutting logic only considers data size when determining where to cut a file, failing to reserve space for index and filter blocks that are added when the file is finalized.
Key changes:
- Add EstimateCurrentIndexSize() to IndexBuilder interface
- Implement in ShortenedIndexBuilder with buffer that accounts for the next index entry. The buffer addresses under-estimation where the current index size doesn't account for the next index entry associated with the data block currently being built. The 2x multiplier bounds the estimate in the right direction and handles outlier cases with large keys.
- Add num_index_entries_ member to track added index entries (== data blocks emitted). This is thread-safe since it's updated/read in the serialized emit step.
Next steps:
- Partitioned index size estimation implementation
- Update compaction file cutting logic to consider index size estimation
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14010
Test Plan: Added a new test class with unit tests for new builder size estimation across all IndexBuilder implementations.
Reviewed By: pdillinger
Differential Revision: D83501741
Pulled By: nmk70
fbshipit-source-id: d58fc2a9e92e12a162f6244d4abd707a9c9e1885
Summary:
This PR fixes a bug in how MultiScan handled a scan range limit falling in the key range between files. The bug was in LevelIterator, where Prepare() relied on FindFile to determine the lower bound file for the range limit. FindFile returns the smallest file index with `range.limit < file.largest_key`. However, that doesn't guarantee that the range overlaps the file, as the `range.limit` could be smaller than `file.smallest_key`.
This also fixes a bug in BlockBasedTableIterator of Valid() returning true even if status() returned error. This was exposed by the previous bug.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14011
Test Plan: Add unit tests in db_iterator_test and table_test
Reviewed By: cbi42
Differential Revision: D83496439
Pulled By: anand1976
fbshipit-source-id: a9d2d138d69d0c816d9f4160a984b273d00d683f
Summary:
Pretty self-explanatory from the changes, including re-arranging the "COOL" entries for easier tracking of which values are used.
I'm not touching the TICKER_ENUM_MAX issue because IIRC we've gotten in trouble in the past for changing any Java ticker values.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14012
Test Plan: CI, sufficient prompts to get AI to discover the known issues relayed by hx235, to help ensure we found any other outstanding issues.
Reviewed By: hx235
Differential Revision: D83497503
Pulled By: pdillinger
fbshipit-source-id: ec0bd7e28188e0430fb03fc5bd79c2ed7b28f3ad
Summary:
Pass the comparator to UDI interface for both reader and builder.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/14001
Test Plan: Unit test
Reviewed By: anand1976
Differential Revision: D83339943
Pulled By: xingbowang
fbshipit-source-id: 7f6541776b0995260e28224329f0cca37f13b3d4
Summary:
currently BlockBasedTableIterator::Prepare() fails the iterator with non-ok status if an out-of-range scan option is detected. This is due to the interaction between LevelIterator and BlockBasedTableIterator, see added comment above BlockBasedTableIterator::Prepare(). This can fail stress test for L0 files since it doesn't use LevelIterator and scan options are not pruned. This PR fixes this by adding an internal option to MultiScanArgs that enables this check.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13995
Test Plan:
- new unit test
- stress test that fails before this pr: `python3 -u ./tools/db_crashtest.py whitebox --iterpercent=60 --prefix_size=-1 --prefixpercent=0 --readpercent=0 --test_batches_snapshots=0 --use_multiscan=1 --read_fault_one_in=0 --kill_random_test=88888 --interval=60 --multiscan_use_async_io=0 --mmap_read=0 --level0_file_num_compaction_trigger=20`
Reviewed By: anand1976
Differential Revision: D83166088
Pulled By: cbi42
fbshipit-source-id: 241a7d43c8c00d9a98eea0cabb03d2174d51aae5
Summary:
There can be concurrent reads/writes to fields in `IODebugContext`. One example we have seen is for the `cost_info` field which is of type `std::any`. In fact, in RocksDB's async MultiRead implementation, the same `IODebugContext` is re-used across separate async read requests.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13993
Test Plan: Update code which reads/writes to `cost_data` to first acquire shared/exclusive lock on the `mutex` field. There should not be any race conditions when async MultiRead is used.
Reviewed By: pdillinger
Differential Revision: D83091423
Pulled By: archang19
fbshipit-source-id: 4db86d33cf162ed39114b1cd115fcd8964c8ff9b
Summary:
Remove the restriction of only using BytewiseComparator(). In a follow on PR, the UDI interface will be updated to take the Comparator as a parameter.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13999
Test Plan: Add a unit test in table_test.cc
Reviewed By: cbi42
Differential Revision: D83179747
Pulled By: anand1976
fbshipit-source-id: 60222533c71022aa0701ac61c39268d36ca86338
Summary:
In https://github.com/facebook/rocksdb/issues/13964 I changed an expensive DEBUG check in ~AutoHyperClockTable to only run in ASAN builds. It's still expensive so I'm modifying it to scan only about one page beyond what we expect to have written to the anonymous mmap, rather than scanning the whole thing.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13998
Test Plan: manually checked that lru_cache_test running time went from 5.0s to 4.0s after the change. Verified that existing unit test ClockCacheTest.Limits uses the full anonymous mmap to be sure it is sized as expected, by temporarily breaking AutoHyperClockTable::Grow() to allow slightly exceeding the anonymous mmap size.
Reviewed By: cbi42
Differential Revision: D83178493
Pulled By: pdillinger
fbshipit-source-id: a2bf093e98bf68b540c073800be7e193021f2692
Summary:
This combination causes MultiScan iteration to fail due to internal reseek by the iterator.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13992
Reviewed By: cbi42
Differential Revision: D83094631
Pulled By: anand1976
fbshipit-source-id: 96410747d88de391e6d65857d39063d4fb113d65
Summary:
Fix the bug in Improve random seed override support in stress test.
The Bug:
`parser.parse_known_args()` is used to parse command line argument. When it is called without any argument, it uses sys.argv as input parameter. In sys.argv, the first argument is the command itself, so parser.parse_known_args skip the first argument. Meantime, the return value `remain_argv` of `parser.parse_known_args()` does not contain the command itself. When `remain_arg` replaces `sys.argv`, the first argument is treated as the command itself, which is skipped by `parser.parse_known_args()`. In the internal stress test tool, the first argument is `--stress_cmd`, therefore, it is skipped. Instead, the default value `./stress_db` is used. This is why `./stress_db` showed up in the error message. This is also why it works in local, as stress_db is located in the local folder.
The Fix:
When `parser.parse_known_args()` is called first time, the remain_argv is saved as a global variable. It is used in the second call of the `parser.parse_known_args(remain_argv)`. When argument is passed to `parser.parse_known_args` directly, the first argument will not be skipped.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13991
Test Plan:
The the value of first argument `--stress_cmd` is parsed correctly, and shown up in the error message.
```
/usr/local/bin/python3 -u tools/db_crashtest.py --stress_cmd=/data/sandcastle/boxes/trunk-hg-full-fbsource/buck-out/v2/gen/fbcode/d7db8b24dd42e2db/internal_repo_rocksdb/repo/__db_stress__/db_stress --cleanup_cmd='' --simple blackbox --print_stderr_separately
Start with random seed 11107847853133580500
Running blackbox-crash-test with
interval_between_crash=120
total-duration=6000
Use random seed for iteration 8577470137673434540
Traceback (most recent call last):
File "/home/xbw/workspace/ws1/rocksdb/tools/db_crashtest.py", line 1650, in <module>
main()
File "/home/xbw/workspace/ws1/rocksdb/tools/db_crashtest.py", line 1639, in main
blackbox_crash_main(args, unknown_args)
File "/home/xbw/workspace/ws1/rocksdb/tools/db_crashtest.py", line 1358, in blackbox_crash_main
hit_timeout, retcode, outs, errs = execute_cmd(cmd, cmd_params["interval"])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/xbw/workspace/ws1/rocksdb/tools/db_crashtest.py", line 1294, in execute_cmd
child = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/fbcode/platform010/lib/python3.12/subprocess.py", line 1028, in __init__
self._execute_child(args, executable, preexec_fn, close_fds,
File "/usr/local/fbcode/platform010/lib/python3.12/subprocess.py", line 1957, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: '/data/sandcastle/boxes/trunk-hg-full-fbsource/buck-out/v2/gen/fbcode/d7db8b24dd42e2db/internal_repo_rocksdb/repo/__db_stress__/db_stress'
```
Reviewed By: hx235
Differential Revision: D83068960
Pulled By: xingbowang
fbshipit-source-id: 28334d38a444c6f8525444e15f460ec6b257ef38
Summary:
Return a failure status for multi scan if Prepare fails, or if the scan options are unsupported, instead of falling back on a regular scan. This PR also fixes a bug in LevelIterator that caused max_prefetch_size to be ignored.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13974
Test Plan: Add new test in db_iterator_test and table_test
Reviewed By: xingbowang
Differential Revision: D82843944
Pulled By: anand1976
fbshipit-source-id: f12756c40ebd38d8d4e4425e97438b6e766a4663
Summary:
**Context/Summary**
This reverts commit 73432a3f36. This is due to it mysteriously fails our internal CI running with this change to db_crashtest.py. The root-cause is unknown but the error only reproed with this commit frequently but not the one before it. The error message appears to be the command parsing leading to the db_stress binary can't be found
```
Traceback (most recent call last):
File "/data/sandcastle/boxes/trunk-hg-full-fbsource/fbcode/internal_repo_rocksdb/repo/tools/db_crashtest.py", line 1638, in <module>
main()
File "/data/sandcastle/boxes/trunk-hg-full-fbsource/fbcode/internal_repo_rocksdb/repo/tools/db_crashtest.py", line 1627, in main
blackbox_crash_main(args, unknown_args)
File "/data/sandcastle/boxes/trunk-hg-full-fbsource/fbcode/internal_repo_rocksdb/repo/tools/db_crashtest.py", line 1347, in blackbox_crash_main
hit_timeout, retcode, outs, errs = execute_cmd(cmd, cmd_params["interval"])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/sandcastle/boxes/trunk-hg-full-fbsource/fbcode/internal_repo_rocksdb/repo/tools/db_crashtest.py", line 1283, in execute_cmd
child = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/fbcode/platform010/lib/python3.12/subprocess.py", line 1028, in __init__
self._execute_child(args, executable, preexec_fn, close_fds,
File "/usr/local/fbcode/platform010/lib/python3.12/subprocess.py", line 1957, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: './db_stress'
```
**Test plan**
- Rehearsal crash test
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13989
Reviewed By: xingbowang
Differential Revision: D83010751
Pulled By: hx235
fbshipit-source-id: d8cfc70564074065b6bb8a3986d6c1011064dd5e
Summary:
This is causing some internal failure, we decide to revert this for now until we have a proper fix.
This reverts commit 961880b458.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13987
Reviewed By: anand1976
Differential Revision: D82990294
Pulled By: cbi42
fbshipit-source-id: 5f5b4d18d0afe47599738d27e11e3eb2d08d88a0
Summary:
**Context**
Resuming compaction is designed to periodically record the progress of an ongoing compaction and can resume from that saved progress after interruptions such as cancellation, database shutdown, or crashes.
This PR introduces the data structures needed to store subcompaction progress in memory, along with serialization and deserialization support to persist and parse this progress to/from "a manifest-like compaction progress file" (the actual creation of such file is in upcoming PRs).
Flow of resuming: DB::OpenAndCompact() -> Compaction progress file -> SubcompactionProgress -> CompactionJob
Flow of persistence: CompactionJob -> SubcompactionProgress -> Compaction progress file -> DB that is called with OpenAndCompact()
**Summary**
Progress represented by `SubcompactionProgress` will be tracked at the scope of a subcompaction, which is the smallest independent unit of compaction work.
The frequency of recording this progress is once every N compaction output files (to be detailed in future PRs).
When recording, all fields, except for the output files metadata in `SubcompactionProgress`, will directly overwrite the corresponding fields from the last saved progress (See `SubcompactionProgress` and `SubcompactionProgressBuilder` for more).
As a bonus, this PR refactors the file metadata encoding and decoding utilities into two static helper functions, EncodeToNewFile4() and DecodeNewFile4From(), to support subcompaction progress usage.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13928
Test Plan:
- Added various `SubcompactionProgressTest` unit tests in version_edit_test.cc to verify basic serialization/deserialization and forward compatibility handling
- Existing UTs and stress/crash test
**Follow up:**
- Move output entry number and file verification to after each file creation so we can remove kNumProcessedOutputRecords persistence support and make resuming compaction work with `paranoid_file_checks=true` (by default false). Output verification will be done before persistence of progress. As long as this follow-up is done before the landing of the integration PR to create the progress file, we can change the manifest-like compaction progress file format freely.
Reviewed By: jaykorean
Differential Revision: D81986583
Pulled By: hx235
fbshipit-source-id: b42766da7d9c2e2f596c892d050c753238d1039f
Summary:
for MultiScan and UDI we start to use bound check from index iterator, so removing this assert here.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13988
Test Plan: existing test
Reviewed By: hx235
Differential Revision: D82993180
Pulled By: cbi42
fbshipit-source-id: 442b2e83cb3aef96fc1a825bf733af9ce59c21c1
Summary:
It is useful to be able to specify output temperatures in the CompactFiles API. For example it may be useful to store small L0 files produced by flushes locally, while larger intra-L0 compactions can store the compacted L0 file remotely.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13955
Test Plan: New unit tests
Reviewed By: jaykorean
Differential Revision: D82492503
Pulled By: joshkang97
fbshipit-source-id: e1225fe572a15d7c5c30a265762b048a4a9e7f0b
Summary:
- updated release note
- updated version to 10.8 in version.h
- added 10.7 to check_format_compatible.sh
- did not updated folly commit hash due to some build failure.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13980
Reviewed By: xingbowang
Differential Revision: D82882035
Pulled By: cbi42
fbshipit-source-id: b5e0e78570fdd492d592ee77bd3901e4b39c25fb
Summary:
the test did not consider the ingestion_option settings that can result in different error message. This PR fixes the relevant check and ensure we have enough randomness in this test.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13979
Test Plan: `gtest-parallel --repeat=20 --workers=20 ./external_sst_file_test --gtest_filter="*VaryingOptions/IngestDBGeneratedFileTest2.NonZeroSeqno/*"`
Reviewed By: hx235
Differential Revision: D82873439
Pulled By: cbi42
fbshipit-source-id: b0d74bf26a502ca3db59b4a0ea9717bf7d027400
Summary:
Start the process of migrating the HCC implementation over to my new system of "bit field atomics" to clean up the code. Here I took on the simplest of the three "bit field atomic" formats in HCC, but ended up moving some things around to end up with less plumbing of definitions and values overall.
In the process, updated BitFields to use the CRTP pattern to simplify some things (see updated example, etc.)
https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13965
Test Plan: existing tests. ClockCacheTest.ClockEvictionEffortCapTest caught a regression during my development, and the crash test has a history of finding subtle HCC bugs.
Reviewed By: xingbowang
Differential Revision: D82669582
Pulled By: pdillinger
fbshipit-source-id: b73dd47361cbe9fbd334413dd4ce01b3c667159e
Summary:
longtime wanted e.g. for easy tab-completion, now implemented
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13978
Test Plan: pretty good unit test updates, manual testing
Reviewed By: cbi42
Differential Revision: D82857671
Pulled By: pdillinger
fbshipit-source-id: d2b63b7d15e61ebf22c58a6ecd3003311e2d03cb
Summary:
* There was a bug where the compression manager would actually not be used for recompress because the options passed to SstFileDumper were not respected. That is now fixed by respecting the Options.
* Refactored SstFileDumper not to take explicit options that could naturally be embedded in Options.
* Report compressed and uncompressed data block sizes (and ratio) instead of total file size (without a useful ratio). Needed to add a new table property to support that.
* Allow --block_size instead of --set_block_size to be consistent with other tools
* Allow --compression_level as shorthand for both _from and _to options, for simplicity and consistency with other tools
* Support --compression_parallel_threads option
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13977
Test Plan:
* sst_dump manual testing
* TableProperties unit tests updated
* Made it much easier to detect when a functional change requires an update to ParseTablePropertiesString() (rather than causing cryptic downstream failures)
Reviewed By: cbi42
Differential Revision: D82841412
Pulled By: pdillinger
fbshipit-source-id: 8d3421be4d2a3e25b7590cd59d204a3779c2a928
Summary:
Currently in MultiScan we only unpins a block after we scan through it. This PR adds unpinning during Seek to release all blocks pinned by the previous scan range. This is useful when users do not scan through the entire scan range. I plan to follow up with support for aborting async IOs from the previous scan.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13972
Test Plan: new test MultiScanUnpinPreviousBlocks validates unpinning behavior
Reviewed By: xingbowang
Differential Revision: D82779504
Pulled By: cbi42
fbshipit-source-id: 17ba7d1e5a6d8ff09ceea57b79c18febfba75584
Summary:
This change adds FFI support for exporting column family checkpoints, basic access to the export/import files metadata, and creating column families by import.
I've been able to successfully use this to [add checkpoint export and import support to `rust-rocksdb`](https://github.com/pcholakov/rust-rocksdb/pull/2), a forked version of which has been successfully used in production for some time.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13874
Reviewed By: hx235
Differential Revision: D82343565
Pulled By: jaykorean
fbshipit-source-id: fb4182bdfd5cce10743c021a1ac636fd6ac48df3
Summary:
If there's a static initialization of Options() this could now instantiate an AutoHyperClockTable before kPageSize is initialized. Break the dependency because it's a very minor optimization.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13973
Test Plan: internal CI (not able to reproduce locally)
Reviewed By: hx235
Differential Revision: D82789849
Pulled By: pdillinger
fbshipit-source-id: 3f32b5779a4f56d2071be5aadacda2bf0f4b895d
Summary:
Add a new CF immutable option `paranoid_memory_check_key_checksum_on_seek` that allows additional data integrity validations during seek on SkipList Memtable. When this option is enabled and memtable_protection_bytes_per_key is non zero, skiplist-based memtable will validate the checksum of each key visited during seek operation. The option is opt-in due to performance overhead. This is an enhancement on top of paranoid_memory_checks option.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13902
Test Plan:
* new unit test added for paranoid_memory_check_key_checksum_on_seek=true.
* existing unit test for paranoid_memory_check_key_checksum_on_seek=false.
* enable in stress test.
Performance Benchmark: we check for performance regression in read path where data is in memtable only. For each benchmark, the script was run at the same time for main and this PR:
### Memtable-only randomread ops/sec:
* Value size = 100 Bytes
```
for B in 0 1 2 4 8; do (for I in $(seq 1 50);do ./db_bench --benchmarks=fillseq,readrandom --write_buffer_size=268435456 --writes=250000 --value_size=100 --num=250000 --reads=500000 --seed=1723056275 --paranoid_memory_check_key_checksum_on_seek=true --memtable_protection_bytes_per_key=$B 2>&1 | grep "readrandom"; done;) | awk '{ t += $5; c++; print } END { print 1.0 * t / c }'; done;
```
1. Main: 928999
2. PR with paranoid_memory_check_key_checksum_on_seek=false: 930993 (+0.2%)
3. PR with paranoid_memory_check_key_checksum_on_seek=true:
3.1 memtable_protection_bytes_per_key=1: 464577 (-50%)
3.2 memtable_protection_bytes_per_key=2: 470319 (-49%)
3.3 memtable_protection_bytes_per_key=4: 468457 (-50%)
3.4 memtable_protection_bytes_per_key=8: 465061 (-50%)
* Value size = 1000 Bytes
```
for B in 0 1 2 4 8; do (for I in $(seq 1 50);do ./db_bench --benchmarks=fillseq,readrandom --write_buffer_size=268435456 --writes=250000 --value_size=1000 --num=250000 --reads=500000 --seed=1723056275 --paranoid_memory_check_key_checksum_on_seek=true --memtable_protection_bytes_per_key=$B 2>&1 | grep "readrandom"; done;) | awk '{ t += $5; c++; print } END { print 1.0 * t / c }'; done;
```
1. Main: 601321
2. PR with paranoid_memory_check_key_checksum_on_seek=false: 607885 (+1.1%)
3. PR with paranoid_memory_check_key_checksum_on_seek=true:
3.1 memtable_protection_bytes_per_key=1: 185742 (-69%)
3.2 memtable_protection_bytes_per_key=2: 177167 (-71%)
3.3 memtable_protection_bytes_per_key=4: 185908 (-69%)
3.4 memtable_protection_bytes_per_key=8: 183639 (-69%)
Reviewed By: pdillinger
Differential Revision: D81199245
Pulled By: xingbowang
fbshipit-source-id: e3c29552ab92f2c5f360361366a293fa26934913
Summary:
Force caller of MultiScanArgs to pass comparator. Pass comparator from CF handle to MultiScanArgs in NewMultiScan.
Expand MultiScanArgs unit test with different comparator.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13970
Test Plan: unit test
Reviewed By: cbi42
Differential Revision: D82739270
Pulled By: xingbowang
fbshipit-source-id: e709f4a333ad547c0ba6d24d8fb2b22e50e8a12f
Summary:
**Context/Summary:**
`Status::state` can be nullptr when created with no specific error message. std::strstr on nullptr caused some segfault in our stress test.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13968
Test Plan: Monitor stress test
Reviewed By: jaykorean
Differential Revision: D82695541
Pulled By: hx235
fbshipit-source-id: cf08f70163a9ee6c911cdc3a3d79acd3429f0d15
Summary:
After seeing more people hit issues with thrashing small LRUCache shards and AutoHCC running fully in production for a while on a very large service, here I make these updates:
* In the public API, mark the case of `estimated_entry_charge = 0` (which is how you select AutoHCC) as production-ready and generally preferred. That means devoting a lot less space to how to tune FixedHCC (`estimated_entry_charge > 0`) because it is not generally recommended anymore even though in theory it is the fastest (conditional on a fragile configuration).
* In the public API, add more detail about potential problems with LRUCache and explicitly endorse HCC.
* When a default block cache is created, use AutoHCC instead of LRUCache. It's still a 32MB cache but that's just one cache shard for AutoHCC so the risk of issues with small cache shards is dramatically reduced. And a single AutoHCC shard is still essentially wait-free.
* Improve the handling of the hypothetical scenario of a failed anonymous mmap. This is hardly a concern for 64-bit Linux and likely most other OSes. It would in theory be possible to fall back on LRUCache in that case but the code structure makes that annoying/challenging. Instead we crash with an appropriate message.
* Cleaned up some includes
* Fixed some previously unreported leaks (better assertions on HCC perhaps, some subtle behavior changes)
* Added a new mode to cache_bench (detailed below)
* Avoid a particularly costly sanity check in `~AutoHyperClockTable()` even in debug builds so that unit testing, etc., isn't bogged down, except keep it in ASAN build.
Planned follow-up:
* Update HCC implementation to use my new "bit field atomics" API introduced in https://github.com/facebook/rocksdb/issues/13910 to make it easier to read and maintain
Possible follow-up:
* Re-engineer table cache to use AutoHCC also, instead of LRUCache and a single mutex to ensure no duplication across threads. (a) Pad table cache key to 128 bits for AutoHCC. (b) Stripe/shard the no-duplication mutex. (HCC's consistency model is too weak for concurrent threads to use its API to agree on a winner, even if entries could be inserted in an "open in progress" state.)
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13964
Test Plan:
existing tests. ClockCacheTest.ClockEvictionEffortCapTest caught a regression during my development, and the crash test has a history of finding subtle HCC bugs.
## Performance
Although we've validated AutoHCC performance under high load, etc., before we haven't really considered whether there will be unacceptable overheads for small DBs and CFs, e.g. in unit tests. For this, I have added a new mode to cache_bench: with the -stress_cache_instances=n parameter, it will create and destroy n empty cache instances several times. In the debug build, this found that a particular check in `~AutoHyperClockTable()` was extremely costly for short-lived caches (fixed). Beyond that, we can answer the question of whether it is feasible for a single process to host 1000 DBs each with 1000 CFs with default block cache instances, after moving LRUCache -> AutoHCC, for example:
```
/usr/bin/time ./cache_bench -stress_
cache_instances=1000000 -cache_type=auto_hyper_clock_cache -cache_size=33554432
```
Release build:
Average 9.8 us per 32MB LRUCache creation, 2.9 us per destruction, 24.6GB max RSS (~25KB each)
->
Average 4.3 us per 32MB AutoHCC creation, 4.9 us per destruction, 4.8GB max RSS (~5KB each)
Debug build:
Average 10.9 us per 32MB LRUCache creation, 3.5 us per destruction, 28.7GB max RSS (~29KB each)
->
Average 4.5 us per 32MB AutoHCC creation, 4.9 us per destruction, 4.7GB max RSS (~5KB each)
Despite the anonymous mmaps, it's apparently more efficient for default/small/empty structures. This is likely due to the dramatically low number of cache shards at this size. If we switch to `-stress_cache_instances=10000 -cache_size=1073741824`:
Release build:
Average 10.6 us per 1GB LRUCache, 2.8 us per destruction, 2.3 GB max RSS (~230KB each)
->
Average 130 us per 1GB AutoHCC creation, 153 us per destruction, 1.5 GB max RSS (~150KB each)
Debug build:
Average 11.2 us per 1GB LRUCache, 3.6 us per destruction, 2.4 GB max RSS (~240KB each)
->
Average 130 us per 1GB AutoHCC creation, 150 us per destruction, 1.6 GB max RSS (~160KB each)
Here it's clear that we are paying a price in time for setting up all those mmaps for the good number of cache shards and potential table growth, even though the RSS is well under control. However, I am not concerned about this at all, as it's unlikely to slow down anything notably such as unit tests. Before and after full testsuite runs confirm:
3327.73user 5188.71system 3:38.88elapsed -> 3312.07user 5704.77system 3:41.61elapsed
There is increased kernel time but acceptable. With ASAN+UBSAN:
11618.70user 15671.30system 5:54.68elapsed -> 12595.81user 16159.67system 6:32.77elapsed
Acceptable given that our ASAN+UBSAN builds are not the slowest in CI
Reviewed By: hx235
Differential Revision: D82661067
Pulled By: pdillinger
fbshipit-source-id: ab25c766ca70f2b8664849c2a838b9e1b4e72d3b
Summary:
when ingesting DB generated file with non-zero sequence number, we need smallest seqno of each file for file meta data. To avoid full table scan, we record this information in table property and use it during file ingestion.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13942
Test Plan: new unit test and updated existing unit test.
Reviewed By: hx235
Differential Revision: D82331802
Pulled By: cbi42
fbshipit-source-id: 3009a6801ca7092cd0fde33692db1a13567068a9
Summary:
This PR fixes a bug in BlockBasedTableIterator::Prepare in conjunction with a user defined index (UDI). If the UDI determines a scan range to be empty and thus returns the kOutOfBound iteration result during Seek, the iteration result is not propagated up and Prepare() assumes end of file and aborts the remaining scans. This results in incorrect behavior and unpredictable multi scan results.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13960
Test Plan: Add unit test to table_test.cc
Reviewed By: xingbowang
Differential Revision: D82590892
Pulled By: anand1976
fbshipit-source-id: 8cfaaae2bb1a9509ddf8ec967cb8a8801748413d
Summary:
* Fix compaction/flush CPU usage stats to include CPU usage by parallel compression workers. (Validated with manual db_bench testing.)
* Disable the parallel compression framework when compression is disabled. See new code comment for details, because in theory it could be useful to hide SST write latency, but manual testing with db_bench and -rate_limiter_bytes_per_sec or -simulate_hdd options shows no useful increase in throughput, just more CPU usage.
* Fix some minor clean-up items in the implementation
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13959
Test Plan: Also ran some tests like in https://github.com/facebook/rocksdb/issues/13910 to ensure the new CPU usage tracking did not regress performance, all good.
Reviewed By: xingbowang
Differential Revision: D82556686
Pulled By: pdillinger
fbshipit-source-id: 77c522159a7e6ab0ab6f7fb1d662070a46661557
Summary:
The stress test runs concurrent transactions through many threads at the same time on a shared key space. It is possible that a dead lock or a timeout is detected from the transactiondb layer. When this happens, simply return from the function and continue the test, instead of fail the test.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13950
Test Plan: Stress test pass locally with the same random seed from stress test 14723229280871643749.
Reviewed By: hx235
Differential Revision: D82373959
Pulled By: xingbowang
fbshipit-source-id: 5d72e89998171c5844fb22f13d8f061f81014c7d
Summary:
... reporting false positive double-lock on some of the new parallel compression code. Switching from std::condition_variable to condition_variable_any simply changes the FP from double-lock to lock inversion. In addition, leaking ParallelCompressionRep instances to avoid memory location reuse fails to fix the FP reports. Thus, I've decided to disable the watchdog with GCC+TSAN.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13958
Test Plan: local crash test runs could reproduce, now don't reproduce. CLANG TSAN doesn't seem to be reporting the same supposed issues
Reviewed By: xingbowang
Differential Revision: D82555968
Pulled By: pdillinger
fbshipit-source-id: 537fbc3a787f917915a6faf0bdedd1449a7f378a
Summary:
Complete redo of parallel compression in block_based_table_builder.cc to greatly reduce cross-thread hand-off and blocking. A ring buffer of blocks-in-progress is used to essentially bound working memory while enabling high throughput. Unlike before, all threads can participate in compression work, for a kind of work-stealing algorithm that reduces the need for threads to block. This builds on improvements in https://github.com/facebook/rocksdb/pull/13850
Previously, there was either
* parallel_threads==1, the *emit thread* (caller from flush/compaction) doing all the work
* parallel_threads > 1, the emit thread generates uncompressed blocks, `parallel_threads` worker threads compress blocks, and a writer thread writes to the SST file. Total of `parallel_threads + 2` threads participating. (Other bookkeeping in emit and write steps omitted from description for simplicity.)
Now we have either
* parallel_threads==1 (same), the emit thread doing all the work
* parallel_threads > 1, the emit thread generates uncompressed blocks and can take up compression work when the ring buffer is full; `parallel_threads` worker threads have as their top priority to write compressed blocks to the SST file but also take up compression work in priority order of next-to-write. Total of `parallel_threads + 1` threads participating. In some cases, this could result in less throughput than before, but arguably the previous implementation was using more threads than explicitly allowed.
## Future/alternate considerations
Although we could likely have used some framework for micro-work sharing across threads, that could be difficult with the asymmetry of work loads and thread affinity. Specifically, (a) it would be quite challenging to allow emit work in other threads, because it happens in the caller of BlockBasedTableBuilder, (b) async programming is unlikely to pay off until we have an async interface for writing SST files, and (c) this implementation will nevertheless serve as a benchmark for what we lose or gain in such a framework vs. a hand-tuned system.
This implementation still creates and destroys threads for each SST file created. We hope in the future to have more governance and/or pooling of worker threads across various flushes and compactions, but that is not available currently and would require significant design and implementation work.
## More details
* This implementation makes use of semaphores for idling and re-waking threads. `std::counting_semaphore` and `binary_semaphore` offer the best performance (see benchmark results below) but some implementations are known to have correctness bugs. Also, my attempt at upgrading CI for C++20 support (required for these) in https://github.com/facebook/rocksdb/pull/13904 is actually incomplete. Therefore, using these structures is opt-in with `-DROCKSDB_USE_STD_SEMAPHORES` at compile time, and a naive semaphore implementation based on mutex and condvar is used by default. A folly alternative (folly::fibers::Semaphore) was dropped in during development and found to be less efficient than the naive implementation. One CI job is upgraded to test with the new opt-in.
* One of the biggest concerns about correctness/reliability for this implementation is the possibility of hitting a deadlock, in part because that is not well checked in the DB crash test (a challenging problem!). Note also that with the parallel compression improvements in this release, I am calling the feature production-ready, so there is an extra level of confidence needed in the reliability of the feature. Thus, for DEBUG builds including crash test, I have added a watchdog thread to each parallel SST construction that heuristically checks for the most likely kinds of deadlock that could happen, including for the case of buggy semaphore implementations. It periodically verifies that some thread is outside of its "idle" state, and if the watchdog wakes up repeatedly to see all live threads stuck in their idle state (even if wake-up was attempted) then it declares a deadlock. This feature was manually verified for several seeded deadlock bugs. (More details in code comments.)
* For CPU efficiency, this implementation greatly simplifies the logic to estimate the outstanding or "inflight" size not yet written to the SST file. I expect this size to generally be insignificant relative to the full SST file size so is not worth careful engineering. And based on Meta's current needs, landing under-size for an SST file is better than over-size. See comments on `estimated_inflight_size` for details.
* Some other existing atomics in block_based_table_builder.cc modified to use safe atomic wrappers.
* Status handling in BlockBasedTableBuilder was streamlined to get rid of essentially redundant `status`+`io_status` fields and associated code. Made small optimizations to reduce unnecessary IOStatus copies (with StatusOk()) and mark status conditional branches as LIKELY or UNLIKELY.
* Prefer inline field initialization to initialization in constructor.
* Minimize references to the `parallel_threads` configuration parameter for better separation of concerns / sanitization / etc. For example, use non-nullity of `pc_rep` to indicate that parallel compression is enabled (and active).
* Some other refactoring to aid the new implementation.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13910
Test Plan:
## Correctness
Already integrated into unit tests and crash test. CI updated for opt-in semaphore implementation. Basic semaphore unit tests added/updated.
As for the tremendous simplification of logic relating to hitting target SST file size, as expected, the new behavior could under-shoot the single-threaded behavior by a small number of blocks, which will typically affect the file size by ~1/1000th or less. I think that's a good trade-off for cutting out unnecessarily complex code with non-trivial CPU cost (FileSizeEstimator).
```
./db_bench -db=/dev/shm/dbbench_filesize_after8 -benchmarks=fillseq,compact -num=10000000 -compression_type=zstd -compression_level=8 -compression_parallel_threads=8
```
Before, PT=8 & PT=1, and After PT=1 the same or very similar
```
-rw-r--r-- 1 peterd users 67474097 Sep 12 15:32 000052.sst
-rw-r--r-- 1 peterd users 67474214 Sep 12 15:32 000053.sst
-rw-r--r-- 1 peterd users 67473834 Sep 12 15:32 000054.sst
-rw-r--r-- 1 peterd users 67473437 Sep 12 15:32 000055.sst
-rw-r--r-- 1 peterd users 67473835 Sep 12 15:32 000056.sst
-rw-r--r-- 1 peterd users 67473204 Sep 12 15:33 000057.sst
-rw-r--r-- 1 peterd users 67473294 Sep 12 15:33 000058.sst
-rw-r--r-- 1 peterd users 67473839 Sep 12 15:33 000059.sst
```
After, PT=8 (worst case here ~0.05% smaller)
```
-rw-r--r-- 1 peterd users 67463189 Sep 12 14:55 000052.sst
-rw-r--r-- 1 peterd users 67465233 Sep 12 14:55 000053.sst
-rw-r--r-- 1 peterd users 67466822 Sep 12 14:55 000054.sst
-rw-r--r-- 1 peterd users 67466221 Sep 12 14:55 000055.sst
-rw-r--r-- 1 peterd users 67441675 Sep 12 14:55 000056.sst
-rw-r--r-- 1 peterd users 67467855 Sep 12 14:55 000057.sst
-rw-r--r-- 1 peterd users 67455132 Sep 12 14:55 000058.sst
-rw-r--r-- 1 peterd users 67458334 Sep 12 14:55 000059.sst
```
## Performance, modest load
We are primarily interested in balancing throughput in building SST files and CPU usage in doing so. (For example, we could maximize throughput by having worker threads only spin waiting for work, but that would likely be extra CPU usage we want to avoid to allow other productive CPU work to be scheduled.) No read path code has been touched.
A benchmark script running "before" and "after" configurations at the same time to minimize random machine load effects:
```
$ SUFFIX=`tty | sed 's|/|_|g'`; for CT in none lz4 zstd; do for PT in 1 2 3 4 6 8; do echo -n "$CT pt=$PT -> "; (for I in `seq 1 10`; do BIN=/tmp/dbbench${SUFFIX}.bin; rm -f $BIN; cp db_bench $BIN; /usr/bin/time $BIN -db=/dev/shm/dbbench$SUFFIX --benchmarks=fillseq -num=10000000 -compaction_style=2 -fifo_compaction_max_table_files_size_mb=1000 -fifo_compaction_allow_compaction=0 -disable_wal -write_buffer_size=12000000 -format_version=7 -compression_type=$CT -compression_parallel_threads=$PT 2>&1; done) | awk '/micros.op/ {n++; sum += $5;} /system / { cpu += $1 + $2; } END { print "ops/s: " int(sum/n) " cpu*s: " cpu; }'; done; done
```
Before this change:
```
none pt=1 -> ops/s: 1999603 cpu*s: 72.08
none pt=2 -> ops/s: 1871094 cpu*s: 148.3
none pt=3 -> ops/s: 1882907 cpu*s: 147.7
lz4 pt=1 -> ops/s: 1987858 cpu*s: 94.74
lz4 pt=2 -> ops/s: 1590192 cpu*s: 182.65
lz4 pt=3 -> ops/s: 1896294 cpu*s: 174.7
lz4 pt=4 -> ops/s: 1949174 cpu*s: 172.26
lz4 pt=6 -> ops/s: 1912517 cpu*s: 175.91
lz4 pt=8 -> ops/s: 1930585 cpu*s: 176.71
zstd pt=1 -> ops/s: 1239379 cpu*s: 129.85
zstd pt=2 -> ops/s: 1171742 cpu*s: 226.12
zstd pt=3 -> ops/s: 1832574 cpu*s: 214.21
zstd pt=4 -> ops/s: 1887124 cpu*s: 212.51
zstd pt=6 -> ops/s: 1920936 cpu*s: 211.7
zstd pt=8 -> ops/s: 1885544 cpu*s: 214.87
```
After this change:
```
none pt=1 -> ops/s: 1964361 cpu*s: 72.66
none pt=2 -> ops/s: 1914033 cpu*s: 104.95
none pt=3 -> ops/s: 1978567 cpu*s: 100.24
lz4 pt=1 -> ops/s: 2041703 cpu*s: 92.88
lz4 pt=2 -> ops/s: 1903210 cpu*s: 121.64
lz4 pt=3 -> ops/s: 1973906 cpu*s: 122.22
lz4 pt=4 -> ops/s: 1952605 cpu*s: 123.05
lz4 pt=6 -> ops/s: 1957524 cpu*s: 124.31
lz4 pt=8 -> ops/s: 1986274 cpu*s: 129.06
zstd pt=1 -> ops/s: 1233748 cpu*s: 130.43
zstd pt=2 -> ops/s: 1675226 cpu*s: 158.41
zstd pt=3 -> ops/s: 1929878 cpu*s: 159.77
zstd pt=4 -> ops/s: 1916403 cpu*s: 160.99
zstd pt=6 -> ops/s: 1942526 cpu*s: 166.21
zstd pt=8 -> ops/s: 1966704 cpu*s: 171.56
```
For parallel_threads=1, results are very similar, as expected.
For parallel_threads>1, throughput is usually improved a bit, but cpu consumption is dramatically reduced. For zstd, maximum throughput is essentially achieved with pt=3 rather than the previous roughly pt=4 to 6. And the old used about 30% more CPU.
We can also compare with more expensive compression by raising the compression level.
```
SUFFIX=`tty | sed 's|/|_|g'`; CT=zstd; for CL in 4 6 8; do for PT in 1 4 8; do echo -n "$CT@$CL pt=$PT -> "; (for I in `seq 1 10`; do BIN=/tmp/dbbench${SUFFIX}.bin; rm -f $BIN; cp db_bench $BIN; /usr/bin/time $BIN -db=/dev/shm/dbbench$SUFFIX --benchmarks=fillseq -num=10000000 -compaction_style=2 -fifo_compaction_max_table_files_size_mb=1000 -fifo_compaction_allow_compaction=0 -disable_wal -write_buffer_size=12000000 -format_version=7 -compression_type=$CT -compression_parallel_threads=$PT -compression_level=$CL 2>&1; done) | awk '/micros.op/ {n++; sum += $5;} /system / { cpu += $1 + $2; } END { print "ops/s: " int(sum/n) " cpu*s: " cpu; }'; done; done
```
Before:
```
zstd@4 pt=1 -> ops/s: 883630 cpu*s: 161.12
zstd@4 pt=4 -> ops/s: 1878206 cpu*s: 243.25
zstd@4 pt=8 -> ops/s: 1885002 cpu*s: 245.89
zstd@6 pt=1 -> ops/s: 710767 cpu*s: 189.44
zstd@6 pt=4 -> ops/s: 1706377 cpu*s: 277.29
zstd@6 pt=8 -> ops/s: 1866736 cpu*s: 275.07
zstd@8 pt=1 -> ops/s: 529047 cpu*s: 237.87
zstd@8 pt=4 -> ops/s: 1401379 cpu*s: 330.61
zstd@8 pt=8 -> ops/s: 1895601 cpu*s: 321.59
```
After:
```
zstd@4 pt=1 -> ops/s: 889905 cpu*s: 161.03
zstd@4 pt=4 -> ops/s: 1942240 cpu*s: 193.18
zstd@4 pt=8 -> ops/s: 1922367 cpu*s: 205.21
zstd@6 pt=1 -> ops/s: 713870 cpu*s: 188.91
zstd@6 pt=4 -> ops/s: 1832314 cpu*s: 219.66
zstd@6 pt=8 -> ops/s: 1949631 cpu*s: 229.34
zstd@8 pt=1 -> ops/s: 530324 cpu*s: 238.02
zstd@8 pt=4 -> ops/s: 1479767 cpu*s: 271.65
zstd@8 pt=8 -> ops/s: 1949631 cpu*s: 275.6
```
And we can also look at the cumulative effect of this change and https://github.com/facebook/rocksdb/pull/13850 that will combine for the parallel compression improvements in the upcoming 10.7 release:
Before both:
```
lz4 pt=1 -> ops/s: 1954445 cpu*s: 95.14
lz4 pt=3 -> ops/s: 1687043 cpu*s: 186.62
lz4 pt=5 -> ops/s: 1708196 cpu*s: 188.33
zstd pt=1 -> ops/s: 1220649 cpu*s: 131.2
zstd pt=3 -> ops/s: 1658100 cpu*s: 227.08
zstd pt=5 -> ops/s: 1685074 cpu*s: 226.08
```
After:
```
lz4 pt=1 -> ops/s: 2048214 cpu*s: 93.24
lz4 pt=3 -> ops/s: 1922049 cpu*s: 122.9
lz4 pt=5 -> ops/s: 1980165 cpu*s: 122.49
zstd pt=1 -> ops/s: 1245165 cpu*s: 128.84
zstd pt=3 -> ops/s: 1956961 cpu*s: 158.73
zstd pt=5 -> ops/s: 1970458 cpu*s: 161.02
```
In summary, before with zstd default level, you could see only
* about 38% increase in throughput for about 73% increase in CPU usage
Now you can get
* about 58% increase in throughput for about 25% increase in CPU usage
## Performance, high load
To validate this for usage on remote compaction workers, we also need to test whether it falls over at high load or anything concerning like that. For this I did a lot of testing with concurrent db_bench and zstd compression_level=8 and parallel_thread (PT) in {1,8} trying to observe "bad" behaviors such as stalls due to preempted threads and such. On a 166 core machine where a "job" is a db_bench process running a fillseq benchmark similar to above in parallel with others, I could summarize the results like this:
10 jobs PT=8 vs. PT=1 -> 12% more CPU usage, 75% reduction in wall time, 1.9 jobs/sec (vs. 0.5)
50 jobs PT=8 vs. PT=1 -> 89% more CPU usage, 27% reduction in wall time, 3.1 jobs/sec (vs. 2.3)
100 jobs PT=8 vs. PT=1 -> 24% more CPU usage, 5% reduction in wall time, 3.25 jobs/sec (vs. 3.1)
150 jobs PT=8 vs. PT=1 -> 4% more CPU usage, 2% increase in wall time, 3.3 jobs/sec (vs. 3.4)
500 jobs PT=8 vs. PT=1 -> 1% more CPU usage, insignificant difference in wall time, 3.3 jobs/sec
Even when there are 4000 threads potentially competing for 166 cores, the throughput (3.3 jobs / sec) is still very close to maximum (3.4). Enabling parallel compression didn't result in notably less throughput (based on wall clock time for all jobs to complete) in any case tested above, and much higher throughput for many cases. If parallel compression causes us to tip from comfortably under-saturating to over-saturating the cores (as in the 50 jobs case), the overall CPU usage can be much higher, presumably due to lower CPU cache hit rates and maybe clock throttling, but parallel compression still has the throughput advantage in those cases.
In other words, what would we stand to gain from being able to intelligently share worker threads between compaction jobs? It doesn't seem that much.
Reviewed By: xingbowang
Differential Revision: D81365623
Pulled By: pdillinger
fbshipit-source-id: 5db5151a959b5d25b84dbe185bc208bd188f2d1c
Summary:
we saw some crash test failure at https://github.com/facebook/rocksdb/blob/f46242cef631351a5c8f4a7b0fb0935ec7fa61c8/table/block_based/block_based_table_iterator.cc#L964-L965. This is likely due to timestamp not being considered properly in some places in MultiScan code paths. This PR fixes the issue.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13938
Test Plan: crash test with timestamp and multiscan: `python3 -u ./tools/db_crashtest.py whitebox --enable_ts --iterpercent=60 --prefix_size=-1 --prefixpercent=0 --readpercent=0 --test_batches_snapshots=0 --use_multiscan=1 --read_fault_one_in=0 --kill_random_test=88888 --interval=60`
Reviewed By: anand1976
Differential Revision: D82175263
Pulled By: cbi42
fbshipit-source-id: 5d40ede1aec15f8faeaa7fd041b939e68611ff73
Summary:
This PR enables Stress Test to fall back to local compaction when a remote compaction fails, allowing the compaction to be retried on the main thread.
If the local compaction succeeds, the stress test will continue without failing. The main thread will log that the remote compaction failed and was retried locally, while detailed failure logs from the remote compaction attempt will still be printed by the worker thread for further investigation.
This approach allows us to keep collecting useful logs for diagnosing remote compaction failures in Stress Test, while ensuring the test continues to run with remote compaction enabled.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13945
Test Plan:
```
python3 -u tools/db_crashtest.py --cleanup_cmd='' --simple blackbox --remote_compaction_worker_threads=8 --interval=10
```
# Internal Only
https://www.internalfb.com/sandcastle/workflow/1315051091202224133https://www.internalfb.com/sandcastle/workflow/3382203320165521367https://www.internalfb.com/sandcastle/workflow/2616591383512372892https://www.internalfb.com/sandcastle/workflow/4607182418810099066
Reviewed By: hx235
Differential Revision: D82279337
Pulled By: jaykorean
fbshipit-source-id: 6f663ec2eeb642fd4ad885a90efb344432a32f89
Summary:
We should add error logging to be able to pinpoint why RocksDB is returning status `NotSupported` for `ReadAsync`.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13936
Test Plan: Look at logs (and client logs of error status)
Reviewed By: anand1976
Differential Revision: D82141529
Pulled By: archang19
fbshipit-source-id: c71b70967457be35ef5168321d449f96b2b9441d
Summary:
Fix uninitialized value complaint in valgrind due to gtest print padded struct.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13934
Test Plan: CI. Verified that valgrind no longer complains about it.
Reviewed By: pdillinger
Differential Revision: D82124983
Pulled By: xingbowang
fbshipit-source-id: 99eb7bab99726c45affe0a231777e5951844d73b
Summary:
... and associated statistics, etc. Someone needs it, so here it is.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13927
Test Plan: Updated / extended / added some unit tests
Reviewed By: cbi42
Differential Revision: D81981469
Pulled By: pdillinger
fbshipit-source-id: 52558c08741890b781310906acbc18d9eb479363
Summary:
There are some internal use cases that do not map cleanly onto the existing `IOActivity` enums. This PR creates new custom IOActivity types that internal users can use as they see fit.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13924
Test Plan: Wrote a simple unit test
Reviewed By: pdillinger
Differential Revision: D82029992
Pulled By: archang19
fbshipit-source-id: a3e23c360baa96cd2e9adf570e71c6e43947bfc8
Summary:
PointLockManager manages point lock per key. The old implementation partition the per key lock into 16 stripes. Each stripe handles the point lock for a subset of keys. Each stripe have only one conditional variable. This conditional variable is used by all the transactions that are waiting for its turn to acquire a lock of a key that belongs to this stripe.
In production, we notified that when there are multiple transactions trying to write to the same key, all of them will wait on the same conditional variables. When the previous lock holder released the key, all of the transactions are woken up, but only one of them could proceed, and the rest goes back to sleep. This wasted a lot of CPU cycles. In addition, when there are other keys being locked/unlocked on the same lock stripe, the problem becomes even worse.
In order to solve this issue, we implemented a new PerKeyPointLockManager that keeps a transaction waiter queue at per key level. When a transaction could not acquire a lock immediately, it joins the waiter queue of the key and waits on a dedicated conditional variable. When previous lock holder released the lock, it wakes up the next set of transactions that are eligible to acquire the lock from the waiting queue. The queue respect FIFO order, except it prioritizes lock upgrade/downgrade operation.
However, this waiter queue change increases the deadlock detection cost, because the transaction waiting in the queue also needs to be considered during deadlock detection. To resolve this issue, a new deadlock_timeout_us (microseconds) configuration is introduced in transaction option. Essentially, when a transaction is waiting on a lock, it will join the wait queue and wait for the duration configured by deadlock_timeout_us without perform deadlock detection. If the transaction didn't get the lock after the deadlock_timeout_us timeout is reached, it will then perform deadlock detection and wait until lock_timeout is reached. This optimization takes the heuristic where majority of the transaction would be able to get the lock without perform deadlock detection.
The deadlock_timeout_us configuration needs to be tuned for different workload, if the likelihood of deadlock is very low, the deadlock_timeout_us could be configured close to a big higher than the average transaction execution time, so that majority of the transaction would be able to acquire the lock without performing deadlock detection. If the likelihood of deadlock is high, deadlock_timeout_us could be configured with lower value, so that deadlock would get detected faster.
The new PerKeyPointLockManager is disabled by default. It can be enabled by TransactionDBOptions.use_per_key_point_lock_mgr. The deadlock_timeout_us is only effective when PerKeyPointLockManager is used. When deadlock_timeout_us is set to 0, transaction will perform deadlock detection immediately before wait.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13731
Test Plan:
Unit test.
Stress unit test that validates deadlock detection and exclusive, shared lock guarantee.
A new point_lock_bench binary is created to help perform performance test.
Reviewed By: pdillinger
Differential Revision: D77353607
Pulled By: xingbowang
fbshipit-source-id: 21cf93354f9a367a78c8666596ed14013ac7240b
Summary:
A follow-up to https://github.com/facebook/rocksdb/issues/13904 which was incomplete in updating CI jobs to support C++20 because the C++20 usage was only in tests. Here we add subtle C++20 usage in the public API ("using enum" feature in db.h) to force the issue.
A lot of the work for this PR was in updating the Ubuntu22 docker image, for earlier compiler/runtime versions supporting C++20, and generating a new Ubuntu24 docker image, for later compiler/runtime versions. The Ubuntu22 image needed to be updated because there are incompatibilities with clang-13 + c++20 + libstdc++ for gcc 11, seen on these examples
```
#include <chrono>
int main(int argc, char *argv[]) {
std::chrono::microseconds d = {}; return 0;
}
```
and
```
#include <coroutine>
int main() { return 0; }
```
The second was causing recurring failures in build-linux-clang-13-asan-ubsan-with-folly, now fixed.
So we have to install clang's libc++ to compile with clang-13. I haven't been able to get this to work with some of the libraries like benchmark, glog, and/or gflags, but I'm able to compile core RocksDB with clang-13. On this docker image, an extra compiler parameter is needed to compile with gcc and glog because it's built from source perhaps not perfectly, because the ubuntu package transitively conflicts with libc++.
The Ubuntu24 image seems to be low-drama and generally work for testing out newer compiler versions. The mingw build uses Ubuntu24 because the mingw package on Ubuntu22 uses a gcc version that is too old.
And the mass of other code changes are trying to work around new warnings, mostly from clang-analyze, which I upgraded to clang-18 in CI.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13915
Test Plan: CI, including temporarily including the nightly jobs in the PR jobs in earlier revisions to test and stabilize
Reviewed By: archang19
Differential Revision: D81933067
Pulled By: pdillinger
fbshipit-source-id: 7e33823006a79d5f3cf5bc1d625f0a3c08a7d74c
Summary:
After running stress test over a week, we've identified more failures to fix. While we work on the fix, disable the remote compaction temporarily to reduce noise and avoid these failures hiding other failures.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13925
Test Plan: CI
Reviewed By: anand1976
Differential Revision: D81934248
Pulled By: jaykorean
fbshipit-source-id: 9ac11926429eebe1aebf7b520a548dc5987b7d76
Summary:
This diff adds logging in various places in the external file ingestion code where we check for non-OK status codes.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13905
Test Plan: Debugging external file ingestion should be easier with additional logging.
Differential Revision: D81814033
Pulled By: archang19
fbshipit-source-id: 77f8b342cbad892acedc4603c02865c38886f2f4
Summary:
If user_defined_index_factory in BlockBasedTableOptions is configured and we try to open an SST file without the corresponding UDI (either during DB open or file ingestion), ignore a failure to load the UDI by default. If fail_if_no_udi_on_open in BlockBasedTableOptions is true, then treat it as a fatal error.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13921
Test Plan: Update unit tests
Reviewed By: xingbowang
Differential Revision: D81826054
Pulled By: anand1976
fbshipit-source-id: f4fe0b13ccb02b9448622af487680131e349c52b
Summary:
Add a new option `MultiScanArgs::max_prefetch_size` that limits the memory usage of per file pinning of prefetched blocks. Note that this only accounts for compressed block size. This is intended to be a stopgap until we implement some kind of global prefetch manager that limits the global multiscan memory usage.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13920
Test Plan: new unit test `./block_based_table_reader_test --gtest_filter="*MultiScanPrefetchSizeLimit/*"`
Reviewed By: xingbowang
Differential Revision: D81630629
Pulled By: cbi42
fbshipit-source-id: 9f66678915242fe1220620531a4b9fd22747cdea
Summary:
# Summary
Until we get WAL + Remote Compaction in Stress Test working, temporarily disable this
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13919
Test Plan: Meta Internal CI run
Reviewed By: anand1976
Differential Revision: D81605621
Pulled By: jaykorean
fbshipit-source-id: 6e1f9a0a7a0f27e7465512689b51364b63ef3e2b
Summary:
Re-enabling Remote Compaction Stress Test with some changes to stress test feature combo sanitization changes
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13913
Test Plan:
Ran Meta Internal Tests for a few days
# Follow up
- Skip recovering from WAL in remote worker and re-enable WAL
- Investigate and fix races with Integrated BlobDB
Reviewed By: hx235
Differential Revision: D81509225
Pulled By: jaykorean
fbshipit-source-id: 949762c48ece0a25e3d0281e3510f1e7d3fe3667
Summary:
**Context/Summary:**
A small change as titled.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13891
Test Plan: - Existing UT and rehearsal stress test
Reviewed By: jaykorean
Differential Revision: D80588011
Pulled By: hx235
fbshipit-source-id: 6987e08a4855782305ad742eef6c0196da0d67ca
Summary:
I am wanting to use std::counting_semaphore for something and the timing seems good to require C++20 support. The internets suggest:
* GCC >= 10 is adequate, >= 11 preferred
* Clang >= 10 is needed
* Visual Studio >= 2019 is adquate
And popular linux distributions look like this:
* CentOS Stream 9 -> GCC 11.2 (CentOS 8 is EOL)
* Ubuntu 22.04 LTS -> GCC 11.x (Ubuntu 20 just ended standard support)
* Debian 12 (oldstable) -> GCC 12.2
* (Debian 11 has ended security updates, uses GCC 10.2)
This required generating a new docker image based on Ubuntu 22 for CI using gcc. The existing Ubuntu 20 image works for covering appropriate clang versions (though we should maybe add a much later version as well, in the next increment of our Ubuntu 22 image; however the minimum available clang build from apt.llvm.org for Ubuntu 22 is clang 13).
Update to SetDumpFilter is to quiet a mysterious gcc-13 warning-as-error.
Removed --compile-no-warning-as-error from a cmake command line because cmake in the new docker image is too old for this option.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13904
Test Plan: CI, one minor unit test added to verify std::counting_semaphor works
Reviewed By: xingbowang
Differential Revision: D81266435
Pulled By: pdillinger
fbshipit-source-id: 26040eeccca7004416e29a6ff4f6ea93f2052684
Summary:
**Context/Summary:**
`ProcessKeyValueCompaction()` has grown too long to resonate or add any logic to resume from some key and save progress for resumable compaction. This PR breaks this function into smaller functions. Almost all of them are cosmetic changes, except for one thing pointed out in below PR conversation.
Specially, this PR did the following:
- Added `SubcompactionInternalIterators`, `SubcompactionKeyBoundaries` and `BlobFileResources` to manage the lifetime of the local variables of the original functions to be used across smaller functions
- Moved AutoThreadOperationStageUpdater, some IO stats measurement to a different place that makes more sense
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13879
Test Plan: Existing UT
Reviewed By: jaykorean
Differential Revision: D80216092
Pulled By: hx235
fbshipit-source-id: 515615906e5e5fd5ec191bcdd4126f17d282cac2
Summary:
The implementation of parallel compression has historically scaled rather poorly, or perhaps modestly with heavy compression, topping out around 3x throughput vs. serial and incurring big overheads in CPU consumption relative to the throughput.
This change addresses one source of that extra CPU consumption: stashing all the keys of a block for later processing into building index and filter blocks. Historically with parallel compression, the index and filter block updates were handled in the last stage of processing along with writing each data block to the file writer. This was because the index blocks needed to know the BlockHandle of the new data block, which could only be known after every preceeding data block was compressed, to know the starting location for the BlockHandle. And because index and filter partitions were historically coupled (see decouple_partitioned_filters), filter updates had to happen at the same time.
Here we get rid of stashing the keys for later processing and the extra CPU associated with it, by
* Creating a two stage process of adding to index blocks ("prepare" and "finish" each entry; one entry per data block). The two stages must be executable in parallel for separate index entries. NOTE: not yet supported by UserDefinedIndex
* Requiring decouple_partitioned_filters=true for parallel compression, because we now add to filters in the first stage of processing when each key is readily available and we cannot couple that with finalizing index entries in the last stage of processing.
It might seem like adding to filters is something that is expensive (hashing etc.) and should be kept out of the bottle-neck first stage of processing (which includes walking the compaction iterator) but it's probably similar cost to simply stashing the keys away for later processing. (We might be able to reduce a bottle-neck by stashing hashes, but we're not to a point where that is worth the effort.)
And it makes sense to make two more simple public API updates in conjunction with this:
* Set decouple_partitioned_filters=true by default. No signs of problems in production.
* Mark parallel compression as production-ready. It's being thoroughly tested in the crash test, successfully, and in limited production uses.
Follow-up:
* Improve the threading/sychronization model of parallel compression for the next major efficiency improvement
* Consider supporting the parallel-compatible index building APIs with UserDefinedIndex, unless it's considered too dangerous to expect users to safely handle the multi-threading.
* (In a subsequent release) remove all the code associated with coupling filter and index partitions and mark the option as ignored.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13850
Test Plan:
for correctness, existing tests
## Performance Data
The "before" data here includes revert of https://github.com/facebook/rocksdb/issues/13828 for combined performance measurement of this change and that one.
```
SUFFIX=`tty | sed 's|/|_|g'`; for CT in lz4 zstd lz4; do for PT in 1 2 3 4 6 8; do echo "$CT pt=$PT"; (for I in `seq 1 1`; do BIN=/dev/shm/dbbench${SUFFIX}.bin; rm -f $BIN; cp db_bench $BIN; /usr/bin/time $BIN -db=/dev/shm/dbbench$SUFFIX --benchmarks=fillseq -num=30000000 -compaction_style=2 -fifo_compaction_max_table_files_size_mb=1000 -fifo_compaction_allow_compaction=0 -disable_wal -write_buffer_size=12000000 -format_version=7 -compression_type=$CT -compression_parallel_threads=$PT 2>&1 | tail -n 3 | head -n 2; done); done; done
```
To get a sense of the overall performance relative to number of parallel threads, we vary that with popular fast compression and popular heavier weight compression (some noise in this data, don't interpret each data point too strongly)
lz4 pt=1
2107431 -> 2112941 ops/sec (+0.3% - improvement)
(26.51 + 0.75) = 27.26 CPU sec -> (26.63 + 0.79) = 27.42 CPU sec (+0.6% - regression)
lz4 pt=2
1606660 -> 1580333 ops/sec (-1.6% - regression)
(47.10 + 8.37) = 55.47 CPU sec -> (45.05 + 9.23) = 54.28 CPU sec (-2.2% - improvement)
lz4 pt=3
1701353 -> 1889283 ops/sec (+11.1% - improvement)
(47.23 + 8.29) = 55.52 CPU sec -> (43.89 + 8.33) = 52.22 CPU sec (-6.0% - improvement)
lz4 pt=4
1651504 -> 1817890 ops/sec (+10.1% - improvement)
(48.07 + 8.31) = 56.38 CPU sec -> (44.77 + 8.45) = 53.22 CPU sec (-5.6% - improvement)
lz4 pt=6
1716099 -> 1888523 ops/sec (+10.1% - improvement)
(47.50 + 8.45) = 55.95 CPU sec -> (44.25 + 8.73) = 52.98 CPU sec (-5.3% - improvement)
lz4 pt=8
1696840 -> 1797256 ops/sec (+5.9% - improvement)
(48.09 + 8.61) = 56.70 CPU sec -> (45.90 + 8.68) = 54.58 CPU sec (-3.8% - improvement)
Clearly parallel threads do not help with fast compression like LZ4, but it's not as bad as it was before.
zstd pt=1
1214258 -> 1202863 ops/sec (-0.9% - regression)
(38.26 + 0.66) = 38.92 CPU sec -> (39.37 + 0.69) = 40.06 CPU sec (+2.9% - regression)
zstd pt=2
1194673 -> 1152746 ops/sec (-3.5% - regression)
(61.01 + 9.85) = 70.86 CPU sec -> (58.28 + 9.99) = 68.27 CPU sec (-3.7% - improvement)
zstd pt=3
1653661 -> 1825618 ops/sec (+10.4% - improvement)
(60.07 + 8.45) = 68.52 CPU sec -> (56.03 + 8.43) = 64.46 CPU sec (-5.9% - improvement)
zstd pt=4
1691723 -> 1890976 ops/sec (+11.8% - improvement)
(59.72 + 8.46) = 68.18 CPU sec -> (55.96 + 8.27) = 64.23 CPU sec (-5.7% - improvement)
zstd pt=6
1684982 -> 1900002 ops/sec (+12.8% - improvement)
(58.89 + 8.26) = 67.15 CPU sec -> (55.98 + 8.48) = 64.46 CPU sec (-4.0% - improvement)
zstd pt=8
1648282 -> 1892531 ops/sec (+14.8% - improvement)
(59.43 + 8.63) = 68.06 CPU sec -> (56.49 + 8.32) = 64.81 CPU sec (-4.8% - improvement)
The throughput is now able to increase by *more than half* with lots of parallelism, rather than only *about a third*.
Scalability is a bit better with higher compression level, and we still see a benefit from this change. (We've also enabled partitioned indexes and filters here, which sees essentially the same benefits):
zstd pt=1 compression_level=7
595720 -> 597359 ops/sec (+0.3% - improvement)
(63.45 + 0.73) = 64.18 CPU sec -> (63.25 + 0.71) = 63.96 CPU sec (-0.3% - improvement)
zstd pt=4 compression_level=7
1527116 -> 1501779 ops/sec (-1.7% - regression)
(85.00 + 8.14) = 93.14 CPU sec -> (81.85 + 9.02) = 90.87 CPU sec (-2.5% - improvement)
zstd pt=6 compression_level=7
1678239 -> 1956070 ops/sec (+16.5% - improvement)
(83.77 + 8.11) = 91.88 CPU sec -> (79.87 + 7.78) = 87.65 CPU sec (-4.6% - improvement)
zstd pt=8 compression_level=7
1696132 -> 1953041 ops/sec (+15.1% - improvement)
(83.97 + 8.14) = 92.11 CPU sec -> (80.61 + 7.78) = 88.39 CPU sec (-4.1% - improvement)
With more tests, not really seeing any consistent differences with no parallelism (despite some micro-optimizations thrown in)
Reviewed By: hx235
Differential Revision: D79853111
Pulled By: pdillinger
fbshipit-source-id: 7a34fd7811217fb74fa6d3efaea7ffcce72beec7
Summary:
**Context/Summary:**
RocksDB stress test verifies IOActivity is set correctly through reusing the pass-in Read/Write options through assertion. This is too strict for API that does not take or do not need to take Read/WriteOptions yet hence assertion failure.
```
stderr:
db_stress: ... db_stress_tool/db_stress_env_wrapper.h:24: void rocksdb::(anonymous namespace)::CheckIOActivity(const IOOptions &): Assertion `io_activity == Env::IOActivity::kUnknown || io_activity == options.io_activity' failed.
Received signal 6 (Aborted)
```
An example is ManagedSnapshot snapshot_guard(db_); in TestMultiScan().
This PR ignores such check.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13898
Test Plan: The same command repro-ed this assertion failure passes after this fix
Reviewed By: archang19
Differential Revision: D80983214
Pulled By: hx235
fbshipit-source-id: d8b660f8c8771198bc7fa0e805c3e86d2584f03e
Summary:
**Context/Summary:**
Clear statistics reference from options_ to intentionally shorten the statistics object lifetime to be same as the db object (which is the common case in practice) and detect if RocksDB access the statistics beyond its lifetime.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13899
Test Plan: - [Ongoing] Stress test rehearsal
Reviewed By: pdillinger
Differential Revision: D80985435
Pulled By: hx235
fbshipit-source-id: ab238231cd81f47fa451aea12a0c85fa11d9ac81
Summary:
`IngestExternalFileOptions::allow_db_generated_files` requires SST files to have zero sequence number. This PR opens it up for any DB generated SST files. Currently we don't do global sequence number assignment when `allow_db_generated_files` is true, so we require that files do not overlap with any key in the CF. One behavior difference is that now we allow ingesting overlapping files when `allow_db_generated_files` is true. Users need to ensure that files are ordered such that later files have more recent updates.
Intended follow ups:
- Record smallest seqno in table property, so that we don't need to scan the file for it.
- Cover allow_db_generated_files in crash test. We may create a new DB and ingest all files from a CF for verification.
- Add APIs that uses allow_db_generated_files. For example, an API for ingesting SST files from a source CF, so that we take care of ingestion file ordering for user. If we are already getting metadata from the source CF, we may be use it as a hint for level placement instead of dividing input files into batches again (`ExternalSstFileIngestionJob::DivideInputFilesIntoBatches`).
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13878
Test Plan: two new unit tests.
Reviewed By: hx235, xingbowang
Differential Revision: D80233727
Pulled By: cbi42
fbshipit-source-id: 74209386d8426c434bff2d9a734f06db537eb50c
Summary:
RocksDB currently aborts whenever `io_uring_wait_cqe` returns an error code. It also does not log what error code was returned.
While experimenting with `IO_URING`, my application crashed because of this.
I asked the Linux Kernel user group the best way to handle unsuccessful `io_uring_wait_cqe`.
It was recommended to retry on `EINTR`, `EAGAIN`, and `ETIME`. `ETIME` only happens when waiting with a timeout, so I am not handling it.
I also write to `stderr` so that we have some debugging information if we abort.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13890
Test Plan: Unfortunately this is hard to cover through unit/stress tests. We have to see what sort of errors get encountered in production.
Reviewed By: anand1976
Differential Revision: D80639955
Pulled By: archang19
fbshipit-source-id: e3a230bd37552ec0f36be34e6a4e53cfd2a254f1
Summary:
When fill_cache is ReadOptions is false, multi scan Prepare crashes with the following assertion failure. In this case, CreateAndPibBlockInCache needs to directly create a block with full ownership.
https://github.com/facebook/rocksdb/issues/9 0x00007f2fc003bc93 in __GI___assert_fail (assertion=0x7f2fc2147361 "pinned_data_blocks_guard[block_idx].GetValue()", file=0x7f2fc2146e08 "table/block_based/block_based_table_iterator.cc", line=1178, function=0x7f2fc2147262 "virtual void rocksdb::BlockBasedTableIterator::Prepare(const rocksdb::MultiScanArgs *)") at assert.c:101
101 in assert.c
https://github.com/facebook/rocksdb/issues/10 0x00007f2fc1d73088 in rocksdb::BlockBasedTableIterator::Prepare(rocksdb::MultiScanArgs const*) () from /data/users/anand76/rocksdb_anand76/librocksdb.so.10.6
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13889
Test Plan: Parameterize the DBMultiScanIteratorTest tests with fill_cache
Reviewed By: cbi42
Differential Revision: D80552069
Pulled By: anand1976
fbshipit-source-id: 1a0b64af1e14c63d826add1f994a832ebff12757
Summary:
I ran multiple runs of crash test jobs internally, so far I've seen one iterator mismatch and one assertion failure. I've added relevant logging improvements to help debugging them. use_multiscan will be stable within a crash test run to make it easier to triage.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13888
Test Plan: `python3 tools/db_crashtest.py whitebox --prefix_size=-1 --test_batches_snapshots=0 --use_multiscan=1 --read_fault_one_in=0 --kill_random_test=88888`
Reviewed By: anand1976
Differential Revision: D80627399
Pulled By: cbi42
fbshipit-source-id: 2fa3f77e730f5bc7d1d200dc122cf84e3558c588
Summary:
The assert occasionally throws off the stress test runs. We already have sufficient logging in place to collect the signal about secondary cache capacity exceeding primary cache reservation for further investigation.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13885
Reviewed By: anand1976
Differential Revision: D80355513
Pulled By: mszeszko-meta
fbshipit-source-id: b36926f0493a3aca19818a1980ef79277db9fe7e
Summary:
Add the --list_meta_blocks option to sst_dump. This PR also refactors some of the test code in sst_dump_test.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13838
Reviewed By: cbi42
Differential Revision: D80320812
Pulled By: anand1976
fbshipit-source-id: 921b6560fbd756f5f8b364893700d240d3b7ad00
Summary:
Two instances of change that are not just cosmetic:
* InlineSkipList<>::Node::CASNext() was implicitly using memory_order_seq_cst to access `next_` while it's intended to be accessed with acquire/release. This is probably not a correctness issue for compare_exchange_strong but potentially a previously missed optimization.
* Similar for `max_height_` in Insert which is otherwise accessed with relaxed memory order.
* One non-relaxed access to `is_range_del_table_empty_` in a function only used in assertions. Access to this atomic is otherwise relaxed (and should be - comment added)
Didn't do all of memtable.h because some of them are more complicated changes and I should probably add FetchMin and FetchMax functions to simplify and take advantage of C++27 functions where available (intended follow-up).
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13844
Test Plan: existing tests
Reviewed By: xingbowang
Differential Revision: D79742552
Pulled By: pdillinger
fbshipit-source-id: d97ce72ba9af6c105694b7d40622db9e994720cd
Summary:
This is an important feature for avoiding (reducing) unfair block cache treatment for a lot of blocks. It should also unlock some parallel optimizations (https://github.com/facebook/rocksdb/issues/13850) and code simplification.
Consider for follow-up:
* Feature to avoid majorly under0sized data blocks and filter and index partition blocks
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13881
Test Plan: existing tests, been looking good in production
Reviewed By: hx235
Differential Revision: D80288192
Pulled By: pdillinger
fbshipit-source-id: 5e274ffffb044713278d2a286db6bceaab2dadec
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13882
The `expect_valid_internal_key` parameter was always passed as true, with false only used in one unit test. This change removes the parameter and always fail compaction when encountering corrupted internal keys, which is the expected production behavior.
Reviewed By: mszeszko-meta
Differential Revision: D80287672
fbshipit-source-id: e30a282ac30d7fded677504cec11173de8d15167
Summary:
Allow a user defined index to be configured from a string
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13880
Test Plan: Add a unit test in table_test.cc
Reviewed By: bikash-c
Differential Revision: D80237701
Pulled By: anand1976
fbshipit-source-id: 8b3d0bcdfbb4bb76803916ea1b1f940a4d985dfd
Summary:
The original intention of the User Defined Index interface was to use the user key. However, the implementation mixed user and internal key usage. This PR makes it consistent. It also clarifies the UDI contract.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13865
Test Plan: Update tests in table_test.cc
Reviewed By: pdillinger
Differential Revision: D80050344
Pulled By: anand1976
fbshipit-source-id: ace47737d21684ec19709640a09e198cee2d98bd
Summary:
... as we see some issues that rehearsal stress test didn't surface.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13869
Reviewed By: cbi42
Differential Revision: D80103341
Pulled By: hx235
fbshipit-source-id: 8b2c1d76d4c3099727ba3a69de44de67afd64369
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13846
This diff addresses few issues that was identified during testing of the user defined index.
1. During the finishing of the index blocks, we run into an infinite loop because the user defined index wrapper returns
early on incomplete status. This happens because the wrapper blindly returns the status if it not OK. But, the status
could legitimately be `Incomplete()` for some indices like Partitioned Index (serving as the internal index for the UDI
wrapper). Fix is to exclude `Incomplete()` check from the status check early in the UDI wrapper's finish.
2. Once we fixed (1), we noticed that the meta blocks for the UDI-based index writer were not written out to the final
SST file. This is because the UDI's meta blocks are created after the internal index's meta blocks and the block-based
index builder didn't account for this. The fix is to finish the UDI wrapper first which will create the necessary meta blocks
and then finish the internal index. If the internal index is incomplete, the block-based index builder should still continue
to write out the meta blocks.
3. OnKeyAdded when delegating to the user-defined index should only pass the user key. The UDI builder doesn't
understand RocksDB's internal key format and while that poses interesting challenges when the UDI is used for non
last level SST files, our plan is to restrict the usage of the UDI to last level files only (for now).
Reviewed By: pdillinger
Differential Revision: D79781453
fbshipit-source-id: 2239c8fc016da55df5c24be6aacc8f6357cab029
Summary:
fix the following error showing up in continuous tests:
```
Makefile:186: Warning: Compiling in debug mode. Don't use the resulting binary in production
port/mmap.cc:46:15: error: first argument in call to 'memcpy' is a pointer to non-trivially copyable type 'rocksdb::MemMapping' [-Werror,-Wnontrivial-memcall]
46 | std::memcpy(this, &other, sizeof(*this));
| ^
port/mmap.cc:46:15: note: explicitly cast the pointer to silence this warning
46 | std::memcpy(this, &other, sizeof(*this));
| ^
| (void*)
1 error generated.
make: *** [Makefile:2580: port/mmap.o] Error 1
make: *** Waiting for unfinished jobs....
```
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13864
Test Plan: `make USE_CLANG=1 j=150 check` with https://github.com/facebook/rocksdb/blob/13f054febb26100184eeefaac11877d735d45ac2/build_tools/build_detect_platform#L61-L70 commented out.
Reviewed By: mszeszko-meta
Differential Revision: D80033441
Pulled By: cbi42
fbshipit-source-id: b2330eea71fe28243236b75128ec6f3f1e971873
Summary:
while debugging stress test failure, I noticed that sst_dump and ldb do not work if custom db_stress compression manager is used. This PR adds support for it.
```
./sst_dump --command=raw --show_properties --file=/tmp/rocksdb_crashtest_whitebox4ny5mass/000589.sst
options.env is 0x7f2b1f4b9000
Process /tmp/rocksdb_crashtest_whitebox4ny5mass/000589.sst
Sst file format: block-based
/tmp/rocksdb_crashtest_whitebox4ny5mass/000589.sst: Not implemented: Could not load CompressionManager: DbStressCustom1
/tmp/rocksdb_crashtest_whitebox4ny5mass/000589.sst is not a valid SST file
./ldb idump --db=/tmp/rocksdb_crashtest_whiteboxy_emah11 --ignore_unknown_options --hex >> /tmp/i_dump
Failed: Not implemented: Could not load CompressionManager: DbStressCustom1
```
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13827
Test Plan: manually tested that ldb and sst_dump work with DbStressCustomCompressionManager after this PR
Reviewed By: pdillinger
Differential Revision: D79461175
Pulled By: cbi42
fbshipit-source-id: c8c092b10b4fde3a295b00751057749e8f0cf095
Summary:
To better support future options, and changes, we need to convert the std::vector<ScanOptions> to something more malleable.
This diff introduces the MultiScanOptions structure and pipes it through the various points in the code in the Prepare path.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13837
Test Plan:
Ensure all associated tests pass
```
make check all
```
Reviewed By: cbi42
Differential Revision: D79655229
Pulled By: krhancoc
fbshipit-source-id: 3a90fb7420e9655021de85ed0158b866f8bfba05
Summary:
**Context/Summary:**
This update, which should have been part of a previous refactoring [PR](https://github.com/facebook/rocksdb/commit/d2ac955881e856fc69d5b15427d742fc635aaead), involves simple renaming for clarity and ensures output table properties are only set when compaction succeeds. Output properties are not meaningful if compaction fails, so this change prevents their population in such cases. Additionally, subsequent statistics updates already do not rely on output file table properties, maintaining correctness regardless of compaction success.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13851
Test Plan: Existing unit tests
Reviewed By: jaykorean
Differential Revision: D79862244
Pulled By: hx235
fbshipit-source-id: 1db16b8dc7b820fab3ec1d5c8a4b757466590e2c
Summary:
**Context/Summary:**
The `CompactionJob::Run()` method has grown too large and complex, making it difficult to implement moderate changes or reason about the code flow (e.g., determining where to save compaction progress for resuming). This PR refactors the method into smaller, more focused functions to improve readability and maintainability.
The refactoring consists mostly of cosmetic changes that extract logical sections into separate methods, with two notable functional improvements:
1. **Relocated output processing logic**: Moved code under `RemoveEmptyOutputs()` and `HasNewBlobFiles()` to where it's actually needed, rather than piggy-backing on the subcompaction state loop. While this introduces 2 additional loops over subcompactions, the performance impact should be negligible given the improved code clarity.
2. **Repositioned statistics updates**: Moved `UpdateCompactionJobInputStats()` and `UpdateCompactionJobOutputStats()` from the record verification section to the end `FinalizeCompactionRun()` methods. This change is safe since record verification is a read-only operation that doesn't modify any statistics.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13849
Test Plan: Existing unit tests
Reviewed By: jaykorean
Differential Revision: D79824429
Pulled By: hx235
fbshipit-source-id: 6b73136f32ecc6842a04a77502b7dbb0bbf507f7
Summary:
We temporarily disabled WAL when Remote Compaction is enabled in Stress Test (https://github.com/facebook/rocksdb/pull/13843). There are few others to incompatible features when WAL is disabled. Due to the sanitization order, WAL was disabled at the end of the sanitization and these incompatible features weren't set properly. Stress Test failed with an error like the following.
e.g. `reopen` stress test is not compatible with `disable_wal` - `Error: Db cannot reopen safely with disable_wal set!`
This PR changes the order of sanitization so that `disable_wal` is set earlier when `remote_compaction_worker_threads > 0`
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13845
Test Plan:
```
python3 -u tools/db_crashtest.py blackbox --remote_compaction_worker_threads=8 --interval=5 --duration=6000 --continuous_verification_interval=10 --disable_wal=1 --use_txn=1 --txn_write_policy=2 --enable_pipelined_write=0 --checkpoint_one_in=0 --use_timed_put_one_in=0
```
Reviewed By: cbi42
Differential Revision: D79758670
Pulled By: jaykorean
fbshipit-source-id: aa6f4a74cc86c23f442928c301187b06e8137f53
Summary:
https://github.com/facebook/rocksdb/issues/13676 unfortunately treated some IOErrors as corruption, which is not appropriate when remote storage is involved. To help enforce this, our crash test injects errors that are expected to be propagated back to the user rather than causing some other failure.
Saw crash test failures like this:
```
TestMultiGetEntity (AttributeGroup) error: Corruption: Failed to get file size: Not implemented: GetFileSize Not Supported for file ...
```
So fixing this handling by not injecting a false Corruption failure and allowing smooth fallback from FSRandomAccessFile::GetFileSize to FileSystem::GetFileSize
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13842
Test Plan: unit test added
Reviewed By: xingbowang
Differential Revision: D79728861
Pulled By: pdillinger
fbshipit-source-id: 33f7dfc85d86d88cb4ab24a8defd26618c95c954
Summary:
To reduce the noise, disable the incompatible ones for now when `remote_compaction_worker_threads > 0`. We will investigate each, fix as needed and re-enable them as follow up.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13843
Test Plan:
```
python3 -u tools/db_crashtest.py blackbox --remote_compaction_worker_threads=8 --interval=5 --duration=6000 --continuous_verification_interval=10 --disable_wal=1 --use_txn=1 --enable_pipelined_write=0 --checkpoint_one_in=0 --use_timed_put_one_in=0
```
Reviewed By: cbi42
Differential Revision: D79735166
Pulled By: jaykorean
fbshipit-source-id: ae3be38a21073fd3282d6e8cd7d71f0363df3590
Summary:
**Summary:**
This test verifies that compaction respects the min_file_size parameter when triggered by deletions, preventing the compaction of files with deletions smaller than the threshold. The test logic includes two scenarios:
1. Verify that a large L0 file with deletions exceeding the minimum file size threshold triggers deletion-triggered compaction (DTC) and compacts to L1.
2. Verify that a small L0 file with deletions, but below the minimum file size threshold, does not trigger DTC and remains at L0.
Added the DeletionTriggeredCompactionWithMinFileSizeTestListener, which verifies that files selected for compaction based on deletion triggers meet the minimum file size threshold. The listener validates in OnCompactionBegin that all input files have sizes greater than or equal to the configured min_file_size parameter.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13825
Test Plan:
Tested this feature on our devserver using the following commands:
```
DEBUG_LEVEL=2 make -j64 db_compaction_test && KEEP_DB=1 ./db_compaction_test --gtest_filter="*DBCompactionTest.CompactionWith*"
```
Test output confirms the expected behavior:
```
2025/07/31-11:24:49.473181 1431671 [/compaction/compaction_job.cc:2291] [default] [JOB 6] Compacting 2@0 files to L1, score 0.04
2025/07/31-11:24:49.473240 1431671 [/compaction/compaction_job.cc:2297] [default]: Compaction start summary: Base version 6 Base level 0, inputs: [15(52KB) 9(103KB)]
2025/07/31-11:24:49.473304 1431671 EVENT_LOG_v1 {"time_micros": 1753986289473273, "job": 6, "event": "compaction_started", "cf_name": "default", "compaction_reason": "FilesMarkedForCompaction", "files_L0": [15, 9], "score": 0.04, "input_data_size": 159848, "oldest_snapshot_seqno": -1}
```
**Tasks:**
T228156639
Reviewed By: cbi42
Differential Revision: D79395851
Pulled By: nmk70
fbshipit-source-id: 4c2a80a95521b40543981dd81b347f3984cd2a8b
Summary:
Remote Compaction in the stress test previously failed with the following error, so we temporarily disabled it in PR https://github.com/facebook/rocksdb/issues/13815 :
```
reference std::vector<rocksdb::ThreadState *>::operator[](size_type) [_Tp = rocksdb::ThreadState *, _Alloc = std::allocator<rocksdb::ThreadState *>]: Assertion '__n < this->size()' failed.
```
The error was from accessing `remote_compaction_worker_threads[i]` when `i < remote_compaction_worker_threads.size()` which leads to an undefined behavior. This PR fixes the issue by properly setting the worker thread pointers in `remote_compaction_worker_threads`.
Note: We are still encountering errors when both BlobDB and Remote Compaction are enabled. It appears to be a race condition. For now, BlobDB is temporarily disabled if remote compaction is enabled. We will fix the race condition and re-enable BlobDB as a follow-up.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13835
Test Plan:
```
python3 -u tools/db_crashtest.py blackbox --remote_compaction_worker_threads=16 --interval=2 --duration=180
```
Reviewed By: hx235
Differential Revision: D79684447
Pulled By: jaykorean
fbshipit-source-id: 65f5809f651865c3df76c2cf3b9e7b8d654bb90a
Summary:
this option has the same functionality as DBOptions::allow_ingest_behind but allows the feature at per CF level. `DBOptions::allow_ingest_behind` is deprecated after this PR and users should use `cf_allow_ingest_behind` instead.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13810
Test Plan: updated some existing tests to use the new option.
Reviewed By: xingbowang
Differential Revision: D79191969
Pulled By: cbi42
fbshipit-source-id: 0da45f6be472ace6754ad15df93d45ac86313837
Summary:
**Context/Summary:**
The `RoundRobinSubcompactionsAgainstResources` test, specifically the `SubcompactionsUsingResources` case, is now disabled. This decision was made because the test's reliability depends on the absence of any concurrent compactions other than the round-robin compaction. Addressing this issue while maintaining the test's focus on resource reservation requires a deeper investigation, which is currently beyond my available bandwidth. Given the increased frequency of test failures, it has been temporarily disabled to prevent further disruptions.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13839
Test Plan: - Should be no test failure from RoundRobinSubcompactionsAgainstResources.SubcompactionsUsingResources anymore.
Reviewed By: cbi42
Differential Revision: D79686366
Pulled By: hx235
fbshipit-source-id: 3a226cfd2b67cabc6c585ea567e2b0c25aa5f345
Summary:
#Summary
Quick follow-up from https://github.com/facebook/rocksdb/pull/13816: `CompactFiles()` and `CompactRange()` in CompactionPickers do not run compaction as their names might suggest. What they actually do is create the Compaction object that will be passed to `CompactionJob` to run the compaction.
Renaming these two functions to better represent their purposes.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13831
Test Plan: No functional change. Existing CI should be sufficient.
Reviewed By: hx235
Differential Revision: D79660196
Pulled By: jaykorean
fbshipit-source-id: ca831dbef5120e7115b52fd07b0059ca16c8f1e8
Summary:
... by ensuring that files in dropped column family are not returned to the caller upon successful, offline MANIFEST iteration.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13832
Test Plan: `DBTest2, GetFileChecksumsFromCurrentManifest_CRC32`
Reviewed By: pdillinger
Differential Revision: D79607298
Pulled By: mszeszko-meta
fbshipit-source-id: e7948e086ba6e6fb953a3959fdcc81300613d73e
Summary:
Introduce `CompactionJob::VerifyOutputRecordCount()` and make it align with `VerifyInputRecordCount()`.
Functionality-wise, it should be the same except when `db_options_.compaction_verify_record_count` is false. RocksDB will only print WARN message upon verification failure and not return `Status::Corruption()`.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13830
Test Plan:
Existing tests cover both
```
./compaction_service_test --gtest_filter="*CompactionServiceTest.VerifyInputRecordCount*"
```
```
./compaction_service_test --gtest_filter="*CompactionServiceTest.CorruptedOutput*"
```
Reviewed By: hx235
Differential Revision: D79584795
Pulled By: jaykorean
fbshipit-source-id: 5851328999005601b28504085b688b80880bca7c
Summary:
In anticipation of an enhancement related to parallel compression
* Rename confusing state variables `seperator_is_key_plus_seq_` -> `must_use_separator_with_seq_`
* Eliminate copy-paste code in `PartitionedIndexBuilder::AddIndexEntry`
* Optimize/simplify `PartitionedIndexBuilder::flush_policy_` by allowing a single policy to be re-targetted to different block builders. Added some additional internal APIs to make this work, and it only works because the FlushBlockBySizePolicy is otherwise stateless (after creation).
* Improve some comments, including another proposed optimization especially for the common case of no live snapshots affecting a large compaction
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13828
Test Plan:
existing tests are pretty exhaustive, especially with crash test
Planning to validate performance in combination with next change. (This change is saving some extra allocate/deallocate with partitioned index.)
Reviewed By: cbi42
Differential Revision: D79570576
Pulled By: pdillinger
fbshipit-source-id: f7a16f0e6e6ad2023a3d1a2ebaa3cc22aac717af
Summary:
This diff introduces the IntervalSet data structure, which will be used to help create sets of non overlapping sets of intervals for MultiScan scan options. Specifically, we add specializations for Slices to assist in this.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13787
Test Plan: Added test to catch various cases within adding intervals.
Reviewed By: anand1976
Differential Revision: D78624970
Pulled By: krhancoc
fbshipit-source-id: 9a3e4a28738ab8428788467540fc05ab5c1a1b67
Summary:
One of the parameters for constructing a Compaction object is `earliest_snapshot`, which is required for Standalone Range Deletion Optimization (introduced in [https://github.com/facebook/rocksdb/pull/13078](https://github.com/facebook/rocksdb/pull/13078)). Remote Compaction has been using the `CompactionPicker::CompactFiles()` API to create the Compaction object, but this API never sets the `earliest_snapshot` parameter. To address this, update `CompactionPicker::CompactFiles()` to optionally accept `earliest_snapshot` and pass it during the call in `DBImplSecondary::CompactWithoutInstallation()`.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13816
Test Plan:
```
./compaction_service_test --gtest_filter="*CompactionServiceTest.StandaloneDeleteRangeTombstoneOptimization*"
```
\+ Tested in Meta's internal offload infra.
Reviewed By: hx235
Differential Revision: D79284769
Pulled By: jaykorean
fbshipit-source-id: 164834ef6972d5e0ddfc2970bb9234ef166d6e52
Summary:
Fix a bug in MultiScan where BlockBasedTableIterator should not return out-of-bound when the all blocks of the last scan are exhausted. This prevented LevelIterator from entering the next file so iterator is returning less keys than expected.
Also fixed stress testing to specify iterate_upper_bound correctly.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13822
Test Plan:
- the following fails quickly before this PR and finishes after this PR
```python3 tools/db_crashtest.py whitebox --iterpercent=60 --prefix_size=-1 --prefixpercent=0 --readpercent=0 --test_batches_snapshots=0 --use_multiscan=1 --seed=1 --fill_cache=1 --read_fault_one_in=0 --column_families=1 --allow_unprepared_value=0 --kill_random_test=88888```
- new unit test that fails before this PR
Reviewed By: krhancoc
Differential Revision: D79308957
Pulled By: cbi42
fbshipit-source-id: c9eafd1c8750b959b0185d7c63199b503493cbd2
Summary:
The main motivation for this change is to more flexibly and efficiently support compressing data without extra copies when we do not want to support saving compressed data that is LARGER than the uncompressed. We believe pretty strongly that for the various workloads served by RocksDB, it is well worth a single byte compression marker so that we have the flexibility to save compressed or uncompressed data when compression is attempted. Why? Compression algorithms can add tens of bytes in fixed overheads and percents of bytes in relative overheads. It is also an advantage for the reader when they can bypass decompression, including at least a buffer copy in most cases, after reading just one byte.
The block-based table format in RocksDB follows this model with a single-byte compression marker, and at least after https://github.com/facebook/rocksdb/pull/13797 so does CompressedSecondaryCache. (Notably, the blob file format DOES NOT. This is left to follow-up work.)
In particular, Compressor::CompressBlock now takes in a fixed size buffer for output rather than a `std::string*`. CompressBlock itself rejects the compression if the output would not fit in the provided buffer. This also works well with `max_compressed_bytes_per_kb` option to reject compression even sooner if its ratio is insufficient (implemented in this change). In the future we might use this functionality to reduce a buffer copy (in many cases) into the WritableFileWriter buffer of the block based table builder.
This is a large change because we needed to (or were compelled to)
* Update all the existing callers of CompressBlock, sometimes with substantial changes. This includes introducing GrowableBuffer to reuse between calls rather than std::string, which (at least in C++17) requires zeroing out data when allocating/growing a buffer.
* Re-implement built-in Compressors (V2; V1 is obsolete) to efficiently implement the new version of the API, no longer wrapping the `OLD_CompressData()` function. The new compressors appropriately leverage the CompressBlock virtual call required for the customization interface and no rely on `switch` on compression type for each block. The implementations are largely adaptations of the old implementations, except
* LZ4 and LZ4HC are notably upgraded to take advantage of WorkingArea (see performance tests). And for simplicity in the new implementation, we are dropping support for some super old versions of the library.
* Getting snappy to work with limited-size output buffer required using the Sink/Source interfaces, which appear to be well supported for a long time and efficient (see performance tests).
* Replace awkward old CompressionManager::GetDecompressorForCompressor with Compressor::GetOptimizedDecompressor (which is optional to implement)
* Small behavior change where we treat lack of support for compression closer to not configuring compression, such as incompatibility with block_align. This is motivated by giving CompressionManager the freedom of determining when compression can be excluded for an entire file despite the configured "compression" type, and thus only surfacing actual incompatibilities not hypothetical ones that might be irrelevant to the CompressionManager (or build configuration). Unit tests in `table_test` and `compact_files_test` required update.
* Some lingering clean up of CompressedSecondaryCache and a re-optimization made possible by compressing into an existing buffer.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13805
Test Plan:
for correctness, existing tests
## Performance Test
As I generally only modified compression paths, I'm using a db_bench write benchmark, with before & after configurations running at the same time. vc=1 means verify_compression=1
```
USE_CLANG=1 DEBUG_LEVEL=0 LIB_MODE=static make -j100 db_bench
SUFFIX=`tty | sed 's|/|_|g'`; for CT in zlib bzip2 none snappy zstd lz4 lz4hc none snappy zstd lz4 bzip2; do for VC in 0 1; do echo "$CT vc=$VC"; (for I in `seq 1 20`; do BIN=/dev/shm/dbbench${SUFFIX}.bin; rm -f $BIN; cp db_bench $BIN; $BIN -db=/dev/shm/dbbench$SUFFIX --benchmarks=fillseq -num=10000000 -compaction_style=2 -fifo_compaction_max_table_files_size_mb=1000 -fifo_compaction_allow_compaction=0 -disable_wal -write_buffer_size=12000000 -format_version=7 -compression_type=$CT -verify_compression=$VC 2>&1 | grep micros/op; done) | awk '{n++; sum += $5;} END { print int(sum / n); }'; done; done
```
zlib vc=0 524198 -> 524904 (+0.1%)
zlib vc=1 430521 -> 430699 (+0.0%)
bzip2 vc=0 61841 -> 60835 (-1.6%)
bzip2 vc=1 49232 -> 48734 (-1.0%)
none vc=0 1802375 -> 1906227 (+5.8%)
none vc=1 1837181 -> 1950308 (+6.2%)
snappy vc=0 1783266 -> 1901461 (+6.6%)
snappy vc=1 1799703 -> 1879660 (+4.4%)
zstd vc=0 1216779 -> 1230507 (+1.1%)
zstd vc=1 996370 -> 1015415 (+1.9%)
lz4 vc=0 1801473 -> 1943095 (+7.9%)
lz4 vc=1 1799155 -> 1935242 (+7.6%)
lz4hc vc=0 349719 -> 1126909 (+222.2%)
lz4hc vc=1 348099 -> 1108933 (+218.6%)
(Repeating the most important ones)
none vc=0 1816878 -> 1952221 (+7.4%)
none vc=1 1813736 -> 1904622 (+5.0%)
snappy vc=0 1794816 -> 1875062 (+4.5%)
snappy vc=1 1789363 -> 1873771 (+4.7%)
zstd vc=0 1202592 -> 1225164 (+1.9%)
zstd vc=1 994322 -> 1016688 (+2.2%)
lz4 vc=0 1786959 -> 1971518 (+10.3%)
lz4 vc=1 1829483 -> 1935871 (+5.8%)
I confirmed manually that the new WorkingArea for LZ4HC makes the huge difference on that one, but not as much difference for LZ4, presumably because LZ4HC uses much larger buffers/structures/whatever for better compression ratios.
Reviewed By: hx235
Differential Revision: D79111736
Pulled By: pdillinger
fbshipit-source-id: 1ce1b14af9f15365f1b6da49906b5073a8cecc14
Summary:
Unit Test for a repro for the fix that was reported by https://github.com/facebook/rocksdb/pull/13743
There's potential dataloss when Remote Compaction entries are all removed due to various reasons (CompactionFilter, DeleteRange covering all keys of the SST file, etc)
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13812
Test Plan:
```
./compaction_service_test --gtest_filter="*CompactionServiceTest.EmptyResult*"
```
Failed before merging https://github.com/facebook/rocksdb/pull/13743, now passing
Reviewed By: cbi42
Differential Revision: D79192829
Pulled By: jaykorean
fbshipit-source-id: e200300c4a7993de21c63cd92bda65b692921b89
Summary:
We were seeing some internal builds apparently failing the `-d /mnt/gvfs/third-party` check. Although third-party2 is likely a better check (see dependencies_platform010.sh), that would create a big headache with check_format_compatible.sh which has to work across codebase versions.
* Report a WARNING when we detect on a Meta machine but the `-d /mnt/gvfs/third-party` check fails
* Let USE_CLANG influence default compiler choice so that things might still work in that case (e.g. `USE_CLANG=1 make -j24 check`)
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13820
Test Plan: manual, CI
Reviewed By: jaykorean
Differential Revision: D79277197
Pulled By: pdillinger
fbshipit-source-id: 19b2d45ed794f64bbf838f4414568d77ae9ca6f1
Summary:
Preserve tombstone when allow_ingest_behind` is enabled so that they can be applied to ingested files. This can be useful when users use ingest_behind to buffer updates where Deletion needs to be preserved. This fixes https://github.com/facebook/rocksdb/issues/13571.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13807
Test Plan: updated a unit test to verify that tombstones are not dropped during compaction.
Reviewed By: hx235
Differential Revision: D79016109
Pulled By: cbi42
fbshipit-source-id: c4d31ef32c88468ababcc1ea5af5db6de42a3b0d
Summary:
As title. We will re-enable it once fixed
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13815
Test Plan: N/A - Disabling the test.
Reviewed By: archang19
Differential Revision: D79172697
Pulled By: jaykorean
fbshipit-source-id: 936de3743816049cda811bde48b3b2207ed256ee
Summary:
**Issue**:
When running remote compaction, if all entries in the input files are expired, RocksDB incorrectly deletes an active file from the primary DB, leading to data loss and corruption.
**Root Cause**:
The current logic mistakenly mixed up the input and output file paths during the cleanup phase when no keys survive the compaction (all expired). This results in deleting the input files (which belong to the primary DB) instead of the output files (which belong to the SecondaryDB).
**Fix**:
Use `GetTableFileName` (virtual function) instead of `TableFileName`
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13743
Reviewed By: hx235
Differential Revision: D79108650
Pulled By: jaykorean
fbshipit-source-id: 1c9ba971a0e9a62c15ebc014436cb8fc961af95c
Summary:
Building db_bench with clang and DEBUG_LEVEL=0 was failing with unused variable. This was not caught by CI so I have added this to the build-linux-clang-13-no_test_run job.
Also, while I was touching CI:
* Fold build-linux-release-rtti into build-linux-release by reducing the number of combinations tested between static/dynamic lib and rtti/not. I don't expect these to interact meaningfully with an extremely mature compiler.
* Combine build-linux-clang10-asan and build-linux-clang10-ubsan because clang is extremely reliable running both together
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13813
Test Plan: manual builds, CI
Reviewed By: krhancoc
Differential Revision: D79112643
Pulled By: pdillinger
fbshipit-source-id: 4ffc672718c05fa4597d637aacbc5a179ad8a0cf
Summary:
• Guard on __cpp_lib_atomic_shared_ptr to use std::atomic<std::shared_ptr<T>>::load()/store()
• Fallback to std::atomic_load_explicit()/store_explicit() under C++17
When attempting to build with CXX 20 using clang in a Linux environment, the build fails due to deprecation of atomic_load_explicit.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13744
Reviewed By: xingbowang
Differential Revision: D78997919
Pulled By: cbi42
fbshipit-source-id: f829c282cba878f072d4b0ad44192a87f73b8a90
Summary:
Simulate Remote Compaction in Stress Test by running a separate set of threads that runs remote compaction.
Queue and ResultMap for the remote compactions are stored in memory as part of the `SharedState`. They are shared across main worker threads and remote compaction worker threads.
`enable_remote_compaction` is replaced by `remote_compaction_worker_threads`.
If `remote_compaction_worker_threads` is set to 0, remote compaction is not enabled in Stress Test.
**To Follow up**
This PR covers happy path only. Failure injection in the remote worker thread will be added as a follow up.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13800
Test Plan:
```
./db_stress --remote_compaction_worker_threads=4 --flush_one_in=1000 --writepercent=40 --readpercent=40 --iterpercent=10 --prefixpercent=0 --delpercent=10 --destroy_db_initially=0 --clear_column_family_one_in=0 --reopen=0
```
```
python3 -u tools/db_crashtest.py blackbox --remote_compaction_worker_threads=8
```
Reviewed By: hx235
Differential Revision: D78862084
Pulled By: jaykorean
fbshipit-source-id: b262058c92d7fecc5e014cef5df9cca4a209921b
Summary:
To be compatible with some upcoming compression change/refactoring where we supply a fixed size buffer to CompressBlock, we need to support CompressedSecondaryCache storing uncompressed values when the compression ratio is not suitable. It seems crazy that CompressedSecondaryCache currently stores compressed values that are *larger* than the uncompressed value, and even explicitly exercises that case (almost exclusively) in the existing unit tests. But it's true.
This change fixes that with some other nearby refactoring/improvement:
* Update the in-memory representation of these cache entries to support uncompressed entries even when compression is enabled. AFAIK this also allows us to safely get rid of "don't support custom split/merge for the tiered case".
* Use more efficient in-memory representation for non-split entries
* For CompressionType and CacheTier, which are defined as single-byte data types, use a single byte instead of varint32. (I don't know if varint32 was an attempt at future-proofing for a memory-only schema or what.) Now using lossless_cast will raise a compiler error if either of these types is made too large for a single byte.
* Don't wrap entries in a CacheAllocationPtr object; it's not necessary. We can rely on the same allocator being provided at delete time.
* Restructure serialization/deserialization logic, hopefully simpler or easier to read/understand.
* Use a RelaxedAtomic for disable_cache_ to avoid race.
Suggested follow-up on CompressedSecondaryCache:
* Refine the exact strategy for rejecting compressions
* Still have a lot of buffer copies; try to reduce
* Revisit the split-merge logic and try to make it more efficient overall, more unified with non-split case
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13797
Test Plan:
Unit tests updated to use actually compressible strings in many places and more testing around non-compressible string.
## Performance Test
There was some pre-existing issue causing decompression failures in compressed secondary cache with cache_bench that is somehow fixed in this change. This decompression failures were present before the new compression API, but since then cause assertion failures rather than being quietly ignored. For the "before" test here, they are back to quietly ignored. And the cache_bench changes here were back-ported to the "before" configuration.
### No compressed secondary (setting expectations)
```
./cache_bench --cache_type=auto_hyper_clock_cache -cache_size=8000000000 -populate_cache
```
Max key : 3906250
Before:
Complete in 12.784 s; Rough parallel ops/sec = 2503123
Thread ops/sec = 160329; Lookup hit ratio: 0.686771
After:
Complete in 12.745 s; Rough parallel ops/sec = 2510717 (in the noise)
Thread ops/sec = 159498; Lookup hit ratio: 0.68686
### Compressed secondary, no split/merge
Same max key and approximate total memory size
```
/usr/bin/time ./cache_bench --cache_type=auto_hyper_clock_cache -cache_size=4000000000 -populate_cache -resident_ratio=0.125 -compressible_to_ratio=0.4 --secondary_cache_uri=compressed_secondary_cache://capacity=4000000000
```
Before:
Complete in 18.690 s; Rough parallel ops/sec = 1712144
Thread ops/sec = 108683; Lookup hit ratio: 0.776683
Latency: P50: 4205.19 P75: 15281.76 P99: 43810.98 P99.9: 71487.41 P99.99: 165453.32
max RSS (according to /usr/bin/time): 9341856
After:
Complete in 17.878 s; Rough parallel ops/sec = 1789951 (+4.5%)
Thread ops/sec = 114957; Lookup hit ratio: 0.792998 (+0.016)
Latency: P50: 4012.70 P75: 14477.63 P99: 40039.70 P99.9: 62521.04 P99.99: 167049.18
max RSS (according to /usr/bin/time): 9235688
The improved hit ratio is probably from fixing the failed decompressions (somehow). And my modifications could have improved CPU efficiency, or it could be the small penalty the benchmark naturally imposes on most misses (generate another value and insert it).
### Compressed secondary, with split/merge
```
/usr/bin/time ./cache_bench --cache_type=auto_hyper_clock_cache -cache_size=4000000000 -populate_cache -resident_ratio=0.125 -compressible_to_ratio=0.4 --secondary_cache_uri='compressed_secondary_cache://capacity=4000000000;enable_custom_split_merge=true'
```
Before:
Complete in 20.062 s; Rough parallel ops/sec = 1595075
Thread ops/sec = 101759; Lookup hit ratio: 0.787129
Latency: P50: 5338.53 P75: 16073.46 P99: 46752.65 P99.9: 73459.11 P99.99: 201318.75
max RSS (according to /usr/bin/time): 9049852
After:
Complete in 18.564 s; Rough parallel ops/sec = 1723771 (+8.1%)
Thread ops/sec = 110724; Lookup hit ratio: 0.813414 (+0.026)
Latency: P50: 5234.75 P75: 14590.43 P99: 41401.03 P99.9: 65606.50 P99.99: 157248.04
max RSS (according to /usr/bin/time): 8917592
Looks like an improvement
Reviewed By: anand1976
Differential Revision: D78842120
Pulled By: pdillinger
fbshipit-source-id: 5f754b160c37ebee789279178ebb5e862071bdb2
Summary:
Create a new API FileSystem::SyncFile for file sync, so that we could use file sync directly in places where we need to sync file content to file system without any modification. This is mostly used combined with link file. In some file system link file does not guarantee the file content is synced to file system.
https://github.com/facebook/rocksdb/issues/13741
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13762
Test Plan:
Unit test
T229418750
Reviewed By: pdillinger
Differential Revision: D78121137
Pulled By: xingbowang
fbshipit-source-id: 0ea8a5a3b486e0b61636700400613fed6bbd3faa
Summary:
The yield is actually of not much use because waitFor should already be doing that.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13796
Reviewed By: pdillinger
Differential Revision: D78823656
Pulled By: jainpr
fbshipit-source-id: 040eaf596938ce8db535bc810ad77a9e50b2d551
Summary:
This diff fixes up a miss in which the property_bag was not pushed down to the BlockBasedIterator.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13795
Reviewed By: anand1976
Differential Revision: D78762294
Pulled By: krhancoc
fbshipit-source-id: 8970b0a87e35d07d5a0dd16f360ec96859f66550
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13794
LLVM has a warning `-Wdeprecated-redundant-constexpr-static-def` which raises the warning:
> warning: out-of-line definition of constexpr static data member is redundant in C++17 and is deprecated
Since we are now on C++20, we can remove the out-of-line definition of constexpr static data members. This diff does so.
- If you approve of this diff, please use the "Accept & Ship" button :-)
Reviewed By: meyering
Differential Revision: D78635037
fbshipit-source-id: a90c68469947705c65f36588b2d575237689dbe8
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13793
LLVM has a warning `-Wdeprecated-redundant-constexpr-static-def` which raises the warning:
> warning: out-of-line definition of constexpr static data member is redundant in C++17 and is deprecated
Since we are now on C++20, we can remove the out-of-line definition of constexpr static data members. This diff does so.
- If you approve of this diff, please use the "Accept & Ship" button :-)
Reviewed By: meyering
Differential Revision: D78635005
fbshipit-source-id: bd7cbfff0580b9579e78237ec4371615d3609536
Summary:
This patch reverted "NewRandomRWFile" back to "ReopenWritableFile" in external sst file ingestion job when file is linked instead of copied. The reason is that some of the file systems do not support "NewRandomRWFile". A long term fix is being worked in progress.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13791
Test Plan: Unit test
Reviewed By: pdillinger
Differential Revision: D78697825
Pulled By: xingbowang
fbshipit-source-id: d3651223ab1f2369aac34b772bba8049c6c2c628
Summary:
This diff introduces the ScanOption Pruning, previously the intent was to do prefetching for each sub-iterator of the level iterator, however since BlockBasedIterator does not prefetch asynchronously, this optimization does not make sense just yet.
For now we will prune the ScanOptions to the overlapping ranges and make sure they are properly piped to the underlying layers (during Prepare, and Seek).
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13780
Reviewed By: cbi42
Differential Revision: D78436869
Pulled By: krhancoc
fbshipit-source-id: 681fe7f7f88b04b5c2d60cb3a5de01e03f6f8431
Summary:
So that we can use --command=recompress with a custom CompressionManager. (It's not required for reading files using a custom CompressionManager because those can already use ObjectLibrary for dependency injection.)
Suggested follow-up:
* These tests should not be using C arrays, snprintf, manual delete, etc. except for thin compatibility with argc/argv.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13783
Test Plan: unit test added, some manual testing
Reviewed By: archang19
Differential Revision: D78574434
Pulled By: pdillinger
fbshipit-source-id: 609e6c6439090e6b7e9b63fbd4c2d3f04b104fcf
Summary:
initial support for Prepare() to optimize the performance of MultiScan when using block-based tables. In Prepare(), we do the following:
1. Load all data blocks that will be read in multiscan to block cache
2. Pin the data blocks during the scan
3. if I/O is needed, coalesce I/Os when they are adjacent.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13778
Test Plan:
Added a new unit test.
Benchmark:
1. Set up the DB, I use FIFO here so that files will be in L0 and iterator will use BlockBasedTableIterator directly instead of LevelIterator, where Prepare() call is not implemented yet.
```
./db_bench --benchmarks="fillseq,compact" --disable_wal=1 --threads=1 --num_levels=1 --compaction_style=2 --fifo_compaction_max_table_files_size_mb=1000 --write_buffer_size=268435456
```
2. Multi-scan: based on https://github.com/facebook/rocksdb/issues/13765
```
./db_bench --db="/tmp/rocksdbtest-543376/dbbench" --use_existing_db=1 --benchmarks=multiscan --disable_auto_compactions=1 --seek_nexts=100 --threads=32 --duration=10 --statistics=1
multiscan_stride = 100
multiscan_size = 10
seek_nexts = 100
Main:
multiscan : 449.386 micros/op 70562 ops/sec 10.359 seconds 730968 operations; (multscans:22999)
multiscan : 453.606 micros/op 69433 ops/sec 10.369 seconds 719968 operations; (multscans:22999)
rocksdb.non.last.level.read.bytes COUNT : 47763519421
rocksdb.non.last.level.read.count COUNT : 21573878
Branch:
multiscan : 332.670 micros/op 94698 ops/sec 10.285 seconds 973968 operations; (multscans:29999)
rocksdb.non.last.level.read.bytes COUNT : 111791308336
rocksdb.non.last.level.read.count COUNT : 1062942
With direct-IO:
./db_bench --db="/tmp/rocksdbtest-543376/dbbench" --use_existing_db=1 --benchmarks=multiscan --disable_auto_compactions=1 --seek_nexts=100 --threads=32 --duration=10 --statistics=1 --use_direct_reads=1
Main:
multiscan : 586.045 micros/op 53825 ops/sec 10.366 seconds 557968 operations; (multscans:14999)
rocksdb.non.last.level.read.bytes COUNT : 69107458693
rocksdb.non.last.level.read.count COUNT : 6724651
Branch:
multiscan : 386.679 micros/op 81282 ops/sec 10.359 seconds 841968 operations; (multscans:25999)
rocksdb.non.last.level.read.bytes COUNT : 96605800558
rocksdb.non.last.level.read.count COUNT : 918973
```
Throughput is 36% higher with non-direct IO and 50% higher with direct IO. The improvement is likely from doing less number of I/Os due to I/O coalescing during Prepare(), as shown in `rocksdb.non.last.level.read.count`. The total bytes read is more with this PR for the same reason.
3. Regular iterator:
```
./db_bench --use_existing_db=1 --db="/tmp/rocksdbtest-543376/dbbench" --benchmarks=seekrandom --disable_auto_compactions=1 --seek_nexts=10 --threads=32 --duration=10
Main:
seekrandom : 13.014 micros/op 2456735 ops/sec 10.014 seconds 24602968 operations; 2717.8 MB/s (773999 of 773999 found)
Branch:
seekrandom : 13.048 micros/op 2450554 ops/sec 10.013 seconds 24537968 operations; 2710.9 MB/s (772999 of 772999 found)
```
The result fluctuates but without noticeable regression.
Reviewed By: anand1976
Differential Revision: D78440807
Pulled By: cbi42
fbshipit-source-id: 80ac6fd222696fa65ac0b4b5441748be5ee0b979
Summary:
When max_table_files_size was accidentally configured with 0 value, engine could crash on divide by 0 operation. Although RocksDB do configuration validation during bootstrap, it typically does not do this for runtime dynamic parameter validation. Therefore, there is a chance where max_table_files_size could be set to 0. This PR only focuses on fixing a code path where max_table_files_size ack as divisor.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13767
Test Plan: Unit test.
Reviewed By: cbi42
Differential Revision: D78420516
Pulled By: xingbowang
fbshipit-source-id: 6fdcc85b28a2c6319066665262b981e513719703
Summary:
This diff introduces the ability to override behavior of exits, allow for users to catch exits in a try catch for example as opposed to fully exiting the process.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13772
Reviewed By: hx235
Differential Revision: D78244499
Pulled By: krhancoc
fbshipit-source-id: b403327ed5b494a22b6beeaad4083945a1def0c7
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13728
The Prepare interface allows the user defined index iterator to prefetch index entries, as well as take custom scan termination criteria specified in the property_bag into account.
Reviewed By: pdillinger
Differential Revision: D76165546
fbshipit-source-id: 83d628598924aa7a60dff7ed62a16ae575b2c8ec
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13727
Add UserDefinedIndexReader and UserDefinedIndexIterator. The BlockBasedTable reads the user defined index meta block during open, verifies the checksum, pins in cache or heap depending on configuration, and allocates a UserDefinedIndexReader object with the contents. Similar to the builder, an IndexReader wrapper is allocated. The wrapper forwards the calls to the native reader and/or user defined index reader as appropriate.
A new option, table_index_name, in ReadOptions specifies the index to use when creating a new Iterator.
Reviewed By: pdillinger
Differential Revision: D76165694
fbshipit-source-id: c30bde4c5ce91ea3dc9ad302e73fe4963c1ed457
Summary:
In SstFileWriter::Finish, the call to DeleteFile to delete the output file in case of an error may fail. The current behavior is to ignore the error. In stress tests, there may be expected failures due to error injection. Not acting on the return status will cause the ASSERT_STATUS_CHECKED test to fail, so silence it.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13776
Reviewed By: mszeszko-meta
Differential Revision: D78307124
Pulled By: anand1976
fbshipit-source-id: d27d9397c15cac5cb33b27094c9123a3fde7fa24
Summary:
* A number of comments clarifying contracts, etc.
* Make ReleaseWorkingArea public instead of protected because there are some limited cases where a wrapper implementation might want to call it directly
* Check non-empty dictionary precondition on MaybeCloneForDict
* Expand testing of wrapped WorkingAreas
* Random documentation improvement in block_builder.cc
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13775
Test Plan: existing and expanded tests and assertions
Reviewed By: hx235
Differential Revision: D78304550
Pulled By: pdillinger
fbshipit-source-id: e5f064e8405a5a49be123ee13145cb3626bbbfbf
Summary:
The Stress test was broken due to a change in switching from ReopenWritableFile to FSRandomRWFile for sync linked file in external Sst ingestion job. The Stress test is using FaultInjectionFs, which tracks the opening of ReopenWritableFile properly, but does not track FSRandomRWFile properly. This change fixes the tracking of FSRandomRWFile in FaultInjectionFs.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13771
Test Plan: unit test, stress test
Reviewed By: mszeszko-meta
Differential Revision: D78282719
Pulled By: xingbowang
fbshipit-source-id: f8f2ed8a5b28a76836f75effbdfa2c3bb172dc51
Summary:
in log_reader.cc.
* `for (;;)` (with no matching break inside) should be more structurally recognizable to compilers as unreachable after compared to `while (true)` which compilers can treat as conditional for warning/error purposes because `true` might have come from a macro, etc.
* Comment the `break` statements to indicate they are for the `switch` (not the `for`)
* No code or annotation is apparently needed for the unreachable end of the non-void function, so just a comment
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13764
Test Plan: CI
Reviewed By: archang19
Differential Revision: D78135493
Pulled By: pdillinger
fbshipit-source-id: e313435a846a6e15346acf40404f755be98ab09a
Summary:
This diff reverts D77424529
Unland reason: This diff broke our Windows 2022 build for Open Source CI (T230460952).
Depends on D77424529
Reviewed By: pdillinger
Differential Revision: D78107313
fbshipit-source-id: 6177448e1015c239abcebb0e68470dfd841b6fa0
Summary:
I was going to use this in some code I was working on but ended up not needing it. But it's useful nonetheless and I'm using it in a few places to replace reinterpret_cast.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13648
Test Plan: existing tests, manually see compilation fail when pointed-to types are not same size integral types
Reviewed By: cbi42
Differential Revision: D75576195
Pulled By: pdillinger
fbshipit-source-id: e10c7a4959340f6f2b536de8088072a90e871fcf
Summary:
LLVM has a warning `-Wdeprecated-redundant-constexpr-static-def` which raises the warning:
> warning: out-of-line definition of constexpr static data member is redundant in C++17 and is deprecated
Since we are now on C++20, we can remove the out-of-line definition of constexpr static data members. This diff does so.
- If you approve of this diff, please use the "Accept & Ship" button :-)
Differential Revision: D77423205
fbshipit-source-id: 4ee4a390431a5d25e7733311f3fa40395dfd4bc0
Summary:
LLVM has a warning `-Wunreachable-code-return` which identifies return statements that cannot be reached.
In innocuous situations such statements are often present:
* to satisfy a compiler warning that existed before `[[noreturn]]` was introduced. Now that we have `[[noreturn]]`, this use is not necessary.
* to specify a return type. But there are clearer ways to do this.
* in place of the more legible `__builtin_unreachable()` (which will soon become `std::unreachable()`). In this case, we should use the more legible alternative.
* because the programmer was afraid of the function unexpectedly returning. But we check for this condition with `-Wreturn-type`.
In dangerous situations such statements can obscure the intended execution of the program or even hide an erroneous early return.
In this diff, we remove one or more unreachable returns.
- If you approve of this diff, please use the "Accept & Ship" button :-)
Differential Revision: D77424529
fbshipit-source-id: fe41b5a640264d0a299d5ad330c645f94b147323
Summary:
Add file size validation in ReadFooterFromFile function.
Deprecate skip_checking_sst_file_sizes_on_db_open option.
This change is used to address this issue
https://github.com/facebook/rocksdb/issues/13619
It supports file size validation in ReadFooterFromFile. In favor of this
change, CheckConsistency function and
skip_checking_sst_file_sizes_on_db_open flag are deprecated.
The CheckConsistency function checks each file size matches what was
recorded in manifest during DB open. Meantime, ReadFooterFromFile was
called for each file in LoadTables function. Since ReadFooterFromFile
always validates file size, the CheckConsistency is redundant.
In addtion, CheckConsistency is executed in a single thread. This could
slow down DB open when a network file system is used. Therefore, the
flag skip_checking_sst_file_sizes_on_db_open was added to skip this
check. After this change, ReadFooterFromFile was executed in parallel
through multiple threads. Therefore, the concern of DB open slowness is
eliminated, and the flag could be deprecated.
When paranoid check flag is set to true, corrupted file will fail to open the DB.
When paranoid check flag is set to false, DB will still be able to open, the
healthy ones can be accessed, while the corrupted ones not.
There is 2 slight concerns of this change.
*If max_open_files is set with smaller value, engine will not open all
the files during DB open. This means if there is a corruption on file
size, it will not be detected during DB open, but rather at a later
time. Since the default is -1, which means open all the files, and it is
rarely overridden and a lot of new features rely on it to be -1, the
risk is very low.
*If FIFO compaction is used, engine could fail to open DB unnecessarily
on the corrupted files that would never be used again. However, this is
a very rare case as well. The error could still be ignored by setting
paranoid_checks operationally. The risk is very low.
To remain backward compatibility. The public facing flag was kept and
marked as no-op internally. Another change is required to fully remove
the flag.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13676
Test Plan:
make check
A new unit test was added to validate file size check API works as
expected.
Reviewed By: pdillinger
Differential Revision: D76168033
Pulled By: xingbowang
fbshipit-source-id: 8ceacf39bcfe02ff7aa289868c341366ee9f3a8e
Summary:
`SstFileManager` is supposed to be thread-safe for all of its public methods, but `SetStatisticsPtr` leads to a race condition because the access to `stat_` is not synchronized. We don't use `stat_` internally so we can get rid of it.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13757
Test Plan: Existing unit tests.
Reviewed By: mszeszko-meta
Differential Revision: D77962592
Pulled By: archang19
fbshipit-source-id: e8e56194dda034935ddef44e479243770a73d065
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13726
Add UserDefinedIndexFactory and UserDefinedIndexBuilder interfaces to allow users to plugin custom index implementation into block based table. The factory is specified in BlockBasedTableOptions. If non-null, BlockBasedTableBuilder allocates a wrapper index builder encapsulating the native index and the custom index. The custom index is exposed to BlockBasedTableBuilder as a meta_block of type kUserDefinedIndex. This block type is not compressed.
The IndexBuilder OnKeyAdded interface is enhanced to accept the value in addition to the key. Only full values are supported, and parallel compression is not supported since we cannot obtain the value when calling OnKeyAdded.
Reviewed By: pdillinger
Differential Revision: D76165614
fbshipit-source-id: dfad9cbd6d0359987b7f4abe64cae58c472836f9
Summary:
While a transaction is waiting on a lock, we can use GetWaitingTxns() to determine the transactionID of the blocking transaction and the contended key. However, this gets cleared when the lock times out, so if a client has widespread timeout errors, you need to catch a transaction 'in the act' before they actually hit the timeout in order to understand the contention pattern. This diff adds a new TransactionOptions variable enable_get_waiting_txn_after_timeout, which persists the lock contention information after timeout so it can be accessed by the client after they have received the timeout error.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13754
Test Plan:
- updated TransactionTest.WaitingTxn to test the changed behavior
- ran production shadow tests on traffic with frequent timeouts
Reviewed By: cbi42
Differential Revision: D77703598
Pulled By: akabcenell
fbshipit-source-id: b4448ca1b6a3694d51bfe1ce801b09eb376ff3e9
Summary:
See `Makefile` for actual changes:
* ZLIB remains the same
* BZIP2 remains the same
* SNAPPY is a minor update
* LZ4 is a significant update with multithreaded/multicore compression https://github.com/lz4/lz4/releases/tag/v1.10.0
* ZSTD is a significant update RocksDB is called out as benefiting in particular from the performance improvements herein https://github.com/facebook/zstd/releases/tag/v1.5.7
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13609
Reviewed By: archang19
Differential Revision: D77877295
Pulled By: mszeszko-meta
fbshipit-source-id: bf9a257e8f68dec3d02743b339aa2df65df4ab2c
Summary:
Was reading sec_cache_res_ratio_ outside of mutex and using the result for computation that needs to be synchronized
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13747
Test Plan: existing tests. Has been showing up in crash test, and there's no interesting concurrency here that would warrant a regression test based on sync points.
Reviewed By: cbi42
Differential Revision: D77607660
Pulled By: pdillinger
fbshipit-source-id: 12a71936b3558c7528d229a11c7d2e43982ad06b
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13752
... to github repo. This include changes from D77323287, D77473923 and the release note change in patch release: D77611483.
Reviewed By: archang19
Differential Revision: D77670619
fbshipit-source-id: 37d877f3317c71de190128fa4da6b18f6dfcf3c5
Summary:
address an existing limitation on compaction triggering mechanism that relies on events like flush/compaction/SetOptions. This is important for periodic compactions where files can become eligible without any of these events. The periodic task now runs every 12 hours and check CFs that enables `periodic_compaction_second` (TBD if we want to expand to all CFs) for eligible compactions.
Some of the periodic tasks probably don't need to run immediately after Register(). I'm keeping the existing behavior for now for patch release and to makes tests happy.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13736
Test Plan:
- new unit test that fails before this change.
- ran crash test for hours with the periodic task running every 5 seconds: `python3 ./tools/db_crashtest.py blackbox --test_batches_snapshot=0 --periodic_compaction_seconds=10`
Reviewed By: pdillinger
Differential Revision: D77460715
Pulled By: cbi42
fbshipit-source-id: 00f61502753185e76830c9ed44c5ccc4f4f16bfa
Summary:
CostAwareCompressor simply ignores the preferred compression type as compression manager setting takes precedence over the compression type setting. Thus, I am removing the assert statement as it itself is unnecessary for this case.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13739
Test Plan:
Run nightly build test
```bash
make V=1 J=4 -j4 check
```
Reviewed By: hx235
Differential Revision: D77470932
Pulled By: shubhajeet
fbshipit-source-id: ebb69367d2ffb9bd72432fd04b0cd12ce2d6240a
Summary:
improve assertions, one apparently a previous typo in https://github.com/facebook/rocksdb/issues/13606 and one a suspected possible area of logic error
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13737
Test Plan: watch crash test
Reviewed By: anand1976
Differential Revision: D77453102
Pulled By: pdillinger
fbshipit-source-id: d4196910a9e8d59ef814130a52ff4ebf188a976d
Summary:
I am seeing crashes during backups. The stack trace points back to `WritableFileWriter` creation inside `BackupEngineImpl::CopyOrCreateFile`. I believe the issue is that we are calling `writable_file_->GetRequiredBufferAlignment()` with a `null` `writable_file`.
https://github.com/facebook/rocksdb/blob/v10.2.1/utilities/backup/backup_engine.cc#L2396-L2397https://github.com/facebook/rocksdb/blob/v10.2.1/file/writable_file_writer.h#L210
Here's how I think the flow is:
```cpp
io_s = dst_env->GetFileSystem()->NewWritableFile(dst, dst_file_options,
&dst_file, nullptr);
// say there was some issue and dst_file is nullptr
// evaluates to false
if (io_s.ok() && !src.empty()) {
// we don't go down this branch
auto src_file_options = FileOptions(src_env_options);
src_file_options.temperature = *src_temperature;
io_s = src_env->GetFileSystem()->NewSequentialFile(src, src_file_options,
&src_file, nullptr);
}
// say this evaluates to true
if (io_s.IsPathNotFound() && *src_temperature != Temperature::kUnknown) {
// Retry without temperature hint in case the FileSystem is strict with
// non-kUnknown temperature option
io_s = src_env->GetFileSystem()->NewSequentialFile(
src, FileOptions(src_env_options), &src_file, nullptr);
}
// this is now from the NewSequentialFile call, not NewWritableFile
if (!io_s.ok()) {
return io_s;
}
// dst_file is still nullptr
```
If the first `NewWritableFile` fails and `IsPathNotFound
Tests: existing unit tests
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13734
Reviewed By: pdillinger
Differential Revision: D77390694
Pulled By: archang19
fbshipit-source-id: 865a3a646079ae2349a3b6f25e53ae85df8e4985
Summary:
`data_` and `size_` fields are duplicated in `Block` class, as `contents_` field already have a `data` member variable, which contains `data` and `size` already. This reduces memory consumption by 16 bytes per block.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13733
Test Plan: Unit test
Reviewed By: pdillinger
Differential Revision: D77389791
Pulled By: xingbowang
fbshipit-source-id: 50a56bc5fae494ed5bc39bdfde7303ca06ce87c6
Summary:
Corrected misspelling of "Compression". Changed "Compresssion" to "Compression".
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13735
Test Plan:
All the test case for compression is still working properly.
```bash
./compression_test
```
Reviewed By: hx235
Differential Revision: D77390273
Pulled By: shubhajeet
fbshipit-source-id: f5310e393e23f5d6c8310154cb929db4b6c60a77
Summary:
Respect the scan upper bound/limit, if specified, in `MultiScan`. This applies to block based table and other native RocksDB SSTs. In order to properly support it, the `MultiScan` object caches the `ReadOptions` passed by the user and sets the `iterate_upper_bound` as appropriate. We optimize for the case of either all scans specifying the upper bound, or none of them. In case of mixed scans, we reallocate the DB iterator anytime `ReadOptions` has to be updated.
Tests:
New unit tests in `db_iterator_test`
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13723
Reviewed By: cbi42
Differential Revision: D77385049
Pulled By: anand1976
fbshipit-source-id: 9c02d125770cbedbe6e8c10767ba537e7f7540e1
Summary:
Large txn commit optimization requires all updates are added to a transaction's WriteBatchWithIndex. However, some usage of transactions may add updates directly to the WBWI's underlying write batch. In these cases, we should not attempt to ingest the WBWI since it will drop these updates. This PR adds sanity checking for this.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13722
Test Plan:
- added checks in unit test and stress test
- manually check LOG files for the new unit test
Reviewed By: hx235
Differential Revision: D77247688
Pulled By: cbi42
fbshipit-source-id: 3d1c0c6e64d6d7dfd5578bc4d77abe44cac1e419
Summary:
The nightly build was failing because we were using the AutoSkipCompressionManager with kNoCompression. The test cases should not be running with NoCompression.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13716
Test Plan:
Run the test code being run on the nightly build.
```bash
make V=1 J=4 -j4 check
```
Reviewed By: hx235
Differential Revision: D77042874
Pulled By: shubhajeet
fbshipit-source-id: 821643b30ca53b1855fc24e3bc0a319e4fec2876
Summary:
Port changes made directly in fbcode in order to facilitate the 10.4 release.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13714
Test Plan: Existing tests
Reviewed By: mszeszko-meta
Differential Revision: D77038668
Pulled By: anand1976
fbshipit-source-id: 6b9b16d62bccf75923b525c1c24597a59920a948
Summary:
* Make new format_version=7 a supported setting.
* Fix a bug in compressed_secondary_cache.cc that is newly exercised by custom compression types and showing up in crash test with tiered secondary cache
* Small change to handling of disabled compression in fv=7: use empty compression manager compatibility name.
* Get rid of GetDefaultBuiltinCompressionManager() in public API because it could cause unexpected+unsafe schema change on a user's CompressionManager if built upon the default built-in manager and we add a new built-in schema. Now must be referenced by explicit compression schema version in the public API. (That notion was already exposed in compressed secondary cache API, for better or worse.)
* Improve some error messages for compression misconfiguration
* Improve testing with ObjectLibrary and CompressionManagers
* Improve testing of compression_name table property in BlockBasedTableTest.BlockBasedTableProperties2
* Improve some comments
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13713
Test Plan: existing and updated tests. Notably, the crash test has already been running with (unpublished) format_version=7
Reviewed By: mszeszko-meta, hx235
Differential Revision: D77035482
Pulled By: pdillinger
fbshipit-source-id: 95278de8734a79706a22361bff2184b1edb230ca
Summary:
Auto skip compression manager code is currently running only in context of test / db bench. Disable failing test to unblock monthly minor release.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13715
Test Plan: Disable test.
Reviewed By: hx235
Differential Revision: D77039218
Pulled By: mszeszko-meta
fbshipit-source-id: f9eeec8d5ca4efeaf1f490c5f091b3aff7861a4a
Summary:
Some pieces of follow-up to https://github.com/facebook/rocksdb/issues/13659.
_Recommend hiding whitespace for review_
* Add support for instantiating CompressionManagers through CreateFromString/ObjectLibrary.
* Pull CompressorCustomAlg and DecompressorCustomAlg out of db_test2, refactor/improvement them a bit, and put them in testutil.h for sharing with db_stress. Switched it from being built on snappy to being built on lz4 so that it can properly test dictionary compression.
* Add a custom compression manager for db_stress that uses these, and add to crash test. This depends on the ObjectLibrary stuff because some invocations of db_stress will not be configured with the custom compression manager but will need to access it to read some existing SST files.
* Remove some pieces where the concern of setting compression=kZSTD for compatibility purposes had leaked into configuring some tests and compression managers. After https://github.com/facebook/rocksdb/issues/13659 this compatibility concern is contained in the SST building code.
* Fix BuiltinDecompressorV2SnappyOnly hiding the (ignored) compression dictionary. SST read logic expects the serialized dictionary to be returned by the decompressor even if it's effectively ignored. Updated DBBlockCacheTest.CacheCompressionDict to cover this case.
For follow-up:
* Combine custom compression and mixed compression types in a file (not clean/easy without duplicating or majorly refactoring the mixed/random compressor)
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13710
Test Plan: unit tests updated
Reviewed By: hx235
Differential Revision: D76928974
Pulled By: pdillinger
fbshipit-source-id: 772cf9cb048d737699b0e2887c624fb64a68aa8c
Summary:
add the `min_file_size` parameter to CompactOnDeletionCollector. A file must be at least this size for it to qualify for DTC. This is useful when a user wants to specific a min file size requirement that is larger than the size constraint imposed by the sliding window's `deletion_trigger` requirement.
Added some comment explaining that the file_size provided to table property collector only includes data blocks and may not be up-to-date. This PR also updates DTC to consider SingleDelete and DeletionWithTimestamp as tombstones.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13707
Test Plan:
- new unit test for when min_file_size is specified.
- existing unit test for when min_file_size is not specified.
Reviewed By: hx235, pdillinger
Differential Revision: D76837231
Pulled By: cbi42
fbshipit-source-id: 0782144e75aef9961bf03da2a2c4b3c613ce5db3
Summary:
Some usage of vector memtable is bottlenecked in the memtable insertion path when using multiple writers. This PR adds support for concurrent writes for the vector memtable. The updates from each concurrent writer are buffered in a thread local vector. When a writer is done, MemTable::BatchPostProcess() is called to flush the thread local updates to the main vector. TSAN test and function comment suggest that ApproximateMemoryUsage() needs to be thread-safe, so its implementation is updated to provide thread-safe access.
Together with unordered_write, benchmark shows much improved insertion throughput.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13675
Test Plan:
- new unit test
- enabled some coverage of vector memtable in stress test
- Performance benchmark: benchmarked memtable insertion performance with by running fillrandom 20 times
- Compare branch and main performance with one thread and write batch size 100:
- main: 4896888.950 ops/sec
- branch: 4923366.350 ops/sec
- Benchmark this branch by configuring different threads, allow_concurrent_memtable_write, and unordered_write. Performance ratio is computed as current ops/sec divided by ops/sec at 1 thread with the same options.
allow_concurrent | unordered_write | Threads | ops/sec | Performance Ratio
-- | -- | -- | -- | --
0 | 0 | 1 | 4923367 | 1.0
0 | 0 | 2 | 5215640 | 1.1
0 | 0 | 4 | 5588510 | 1.1
0 | 0 | 8 | 6077525 | 1.2
1 | 0 | 1 | 4919060 | 1.0
1 | 0 | 2 | 5821922 | 1.2
1 | 0 | 4 | 7850395 | 1.6
1 | 0 | 8 | 10516600 | 2.1
1 | 1 | 1 | 5050004 | 1.0
1 | 1 | 2 | 8489834 | 1.7
1 | 1 | 4 | 14439513 | 2.9
1 | 1 | 8 | 21538098 | 4.3
```
mkdir -p /tmp/bench_$1
export TEST_TMPDIR=/tmp/bench_$1
memtablerep_value=${6:-vector}
(for I in $(seq 1 $2)
do
/data/users/changyubi/vscode-root/rocksdb/$1 --benchmarks=fillrandom --seed=1722808058 --write_buffer_size=67108864 --min_write_buffer_number_to_merge=1000 --max_write_buffer_number=1000 --enable_pipelined_write=0 --memtablerep=$memtablerep_value --disable_auto_compactions=1 --disable_wal=1 --avoid_flush_during_shutdown=1 --allow_concurrent_memtable_write=${5:-0} --unordered_write=$4 --batch_size=1 --threads=$3 2>&1 | grep "fillrandom"
done;) | awk '{ t += $5; c++; print } END { printf ("%9.3f\n", 1.0 * t / c) }';
```
Reviewed By: pdillinger
Differential Revision: D76641755
Pulled By: cbi42
fbshipit-source-id: c107ba42749855ad4fd1f52491eb93900757542e
Summary:
* Improve debugability with better error messages (including the returned status, not just log messages)
* Tolerate user providing file checksums recognized by the factory but not the same function as currently, generally provided by the factory. This makes it practical to transition from one type of checksum to another without major hiccups in ingestion workflows.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13708
Test Plan: updated unit test, manually inspect LOG file from the unit test
Reviewed By: cbi42
Differential Revision: D76837804
Pulled By: pdillinger
fbshipit-source-id: 45b744829b3a125e9d0ee6874bd37ce534c2e13c
Summary:
**Summary:**
We need to move the Predictor to WorkingArea so that it is local to each thread and thus is thread safe.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13706
Test Plan: It should pass the test case written in ./compression_test.
Reviewed By: pdillinger
Differential Revision: D76836846
Pulled By: shubhajeet
fbshipit-source-id: 0d0170baf65f4bb95ba107fec77151e66b8a4449
Summary:
**Summary**:
Clang tidy was throwing error that the gtest assertion EXPECT_EQ was being carried out variables that was not initialized.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13703
Test Plan:
Ran the clang-tidy operations to make sure the same error does not appear.
```bash
CC=clang-10 CXX=clang++-10 ROCKSDB_DISABLE_ALIGNED_NEW=1 CLANG_ANALYZER="/usr/bin/clang++-10" CLANG_SCAN_BUILD=scan-build-10 USE_CLANG=1 make V=1 -j32 analyze
```
Reviewed By: hx235, pdillinger
Differential Revision: D76777988
Pulled By: shubhajeet
fbshipit-source-id: b9bfe26a2264d4c21224ab53a0b0307596d7f49d
Summary:
The Object registry requires object to be allocated as std::unique_ptr. Hence we provide a new API for external table plugins to allocate and return a unique_ptr ExternalTableFactory wrapper.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13694
Reviewed By: jaykorean
Differential Revision: D76767974
Pulled By: anand1976
fbshipit-source-id: ac59c523a11679ca7c9f0b280325c7873c6b4c07
Summary:
This change builds on https://github.com/facebook/rocksdb/issues/13540 and https://github.com/facebook/rocksdb/issues/13626 in allowing a CompressionManager / Compressor / Decompressor to use a custom compression algorithm, with a distinct CompressionType. For background, review the API comments on CompressionManager and its CompatibilityName() function.
Highlights:
* Reserve and name 127 new CompressionTypes that can be used for custom compression algorithms / schemas. In many or most cases I expect the enumerators such as `kCustomCompression8F` to be used in user code rather than casting between integers and CompressionTypes, as I expect the supported custom compression algorithms to be identifiable / enumerable at compile time.
* When using these custom compression types, a CompressionManager must use a CompatibilityName() other than the built-in one AND new format_version=7 (see below).
* When building new SST files, track the full set of CompressionTypes actually used (usually just one aside from kNoCompression), using our efficient bitset SmallEnumSet, which supports fast iteration over the bits set to 1. Ideally, to support mixed or non-mixed compression algorithms in a file as efficiently as possible, we would know the set of CompressionTypes as SST file open time.
* New schema for `TableProperties::compression_name` in format_version=7 to represent the CompressionManager's CompatibilityName(), the set of CompressionTypes used, and potentially more in the future, while keeping the data relatively human-readable.
* It would be possible to do this without a new format_version, but then the only way to ensure incompatible versions fail is with an unsupported CompressionType tag, not with a compression_name property. Therefore, (a) I prefer not to put something misleading in the `compression_name` property (a built-in compression name) when there is nuance because of a CompressionManager, and (b) I prefer better, more consistent error messages that refer to either format_version or the CompressionManager's CompatibilityName(), rather than an unrecognized custom CompressionType value (which could have come from various CompressionManagers).
* The current configured CompressionManager is passed in to TableReaders so that it (or one it knows about) can be used if it matches the CompatibilityName() used for compression in the SST file. Until the connection with ObjectRegistry is implemented, the only way to read files generated with a particular CompressionManager using custom compression algorithms is to configure it (or a known relative; see FindCompatibleCompressionManager()) in the ColumnFamilyOptions.
* Optimized snappy compression with BuiltinDecompressorV2SnappyOnly, to offset some small added overheads with the new tracking. This is essentially an early part of the planned refactoring that will get rid of the old internal compression APIs.
* Another small optimization in eliminating an unnecessary key copy in flush (builder.cc).
* Fix some handling of named CompressionManagers in CompressionManager::CreateFromString() (problem seen in https://github.com/facebook/rocksdb/issues/13647)
Smaller things:
* Adds Name() and GetId() functions to Compressor for debugging/logging purposes. (Compressor and Decompressor are not expected to be Customizable because they are only instantiated by a CompressionManager.)
* When using an explicit compression_manager, the GetId() of the CompressionManager and the Compressor used to build the file are stored as bonus entries in the compression_options table property. This table property is not parsed anywhere, so it is currently for human reading, but still could be parsed with the new underscore-prefixed bonus entries. IMHO, this is preferable to additional table properties, which would increase memory fragmentation in the TableProperties objects and likely take slightly more CPU on SST open and slightly more storage.
* ReleaseWorkingArea() function from protected to public to make wrappers work, because of a quirk in C++ (vs. Java) in which you cannot access protected members of another instance of the same class (sigh)
* Added `CompressionManager:: SupportsCompressionType()` for early options sanity checking.
Follow-up before release:
* Make format_version=7 official / supported
* Stress test coverage
Sooner than later:
* Update tests for RoundRobinManager and SimpleMixedCompressionManager to take advantage of e.g. set of compression types in compression_name property
* ObjectRegistry stuff
* Refactor away old internal compression APIs
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13659
Test Plan:
Basic unit test added.
## Performance
### SST write performance
```
SUFFIX=`tty | sed 's|/|_|g'`; for ARGS in "-compression_type=none" "-compression_type=snappy" "-compression_type=zstd" "-compression_type=snappy -verify_compression=1" "-compression_type=zstd -verify_compression=1" "-compression_type=zstd -compression_max_dict_bytes=8180"; do echo $ARGS; (for I in `seq 1 20`; do BIN=/dev/shm/dbbench${SUFFIX}.bin; rm -f $BIN; cp db_bench $BIN; $BIN -db=/dev/shm/dbbench$SUFFIX --benchmarks=fillseq -num=10000000 -compaction_style=2 -fifo_compaction_max_table_files_size_mb=1000 -fifo_compaction_allow_compaction=0 -disable_wal -write_buffer_size=12000000 -format_version=7 $ARGS 2>&1 | grep micros/op; done) | awk '{n++; sum += $5;} END { print int(sum / n); }'; done
```
Ops/sec, Before -> After, both fv=6:
-compression_type=none
1894386 -> 1858403 (-2.0%)
-compression_type=snappy
1859131 -> 1807469 (-2.8%)
-compression_type=zstd
1191428 -> 1214374 (+1.9%)
-compression_type=snappy -verify_compression=1
1861819 -> 1858342 (+0.2%)
-compression_type=zstd -verify_compression=1
979435 -> 995870 (+1.6%)
-compression_type=zstd -compression_max_dict_bytes=8180
905349 -> 940563 (+3.9%)
Ops/sec, Before fv=6 -> After fv=7:
-compression_type=none
1879365 -> 1836159 (-2.3%)
-compression_type=snappy
1865460 -> 1830916 (-1.9%)
-compression_type=zstd
1191428 -> 1210260 (+1.6%)
-compression_type=snappy -verify_compression=1
1866756 -> 1818989 (-2.6%)
-compression_type=zstd -verify_compression=1
982640 -> 997129 (+1.5%)
-compression_type=zstd -compression_max_dict_bytes=8180
912608 -> 937248 (+2.7%)
### SST read performance
Create DBs
```
for COMP in none snappy zstd; do echo $ARGS; ./db_bench -db=/dev/shm/dbbench-7-$COMP --benchmarks=fillseq,flush -num=10000000 -compaction_style=2 -fifo_compaction_max_table_files_size_mb=1000 -fifo_compaction_allow_compaction=0 -disable_wal -write_buffer_size=12000000 -compression_type=$COMP -format_version=7; done
```
And test
```
for COMP in none
snappy zstd none; do echo $COMP; (for I in `seq 1 8`; do ./db_bench -readonly -db=/dev/shm/dbbench
-7-$COMP --benchmarks=readrandom -num=10000000 -duration=20 -threads=8 2>&1 | grep micros/op; done
) | awk '{n++; sum += $5;} END { print int(sum / n); }'; done
```
Ops/sec, Before -> After (both fv=6)
none
1491732 -> 1500209 (+0.6%)
snappy
1157216 -> 1169202 (+1.0%)
zstd
695414 -> 703719 (+1.2%)
none (again)
1491787 -> 1528789 (+2.4%)
Ops/sec, Before fv=6 -> After fv=7:
none
1492278 -> 1508668 (+1.1%)
snappy
1140769 -> 1152613 (+1.0%)
zstd
696437 -> 696511 (+0.0%)
none (again)
1500585 -> 1512037 (+0.7%)
Overall, I think we can take the read CPU improvement in exchange for the hit (in some cases) on background write CPU
Reviewed By: hx235
Differential Revision: D76520739
Pulled By: pdillinger
fbshipit-source-id: e73bd72502ff85c8779cba313f26f7d1fd50be3a
Summary:
Add an atomic bool to CompactionOptions to cancel an ongoing CompactFiles() operation, in the same fashion we do for CompactRange().
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13687
Test Plan: ./db_test2 --gtest_filter=DBTest2.TestCancelCompactFiles
Reviewed By: jaykorean
Differential Revision: D76538529
Pulled By: virajthakur
fbshipit-source-id: 77db5b4fb4cbd5280584834df28e51a72b084dab
Summary:
**Summary:**
This pull request configures RocksDB to optionally utilize this customized compressor (RandomCompressor) in the db stress test. It randomly selects the compression algorithm among the blocks.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13691
Test Plan: Testing was performed by verifying the stdout output from both RandomCompressor.
Reviewed By: hx235
Differential Revision: D76624220
Pulled By: shubhajeet
fbshipit-source-id: d9c458eeee930b25e8a87a77dc29f0647836310e
Summary:
**Context:**
RocksDB's current compression approach rejects blocks if the compressed size exceeds a predefined threshold. To optimize performance, we aim to develop an algorithm that dynamically stops and resumes block compression attempts based on past rejection data.
**Summary:**
The goal of this milestone is to design, implement, and evaluate an algorithm that intelligently skips and resumes block compression attempts in RocksDB. The algorithm tracks whether randomly selected blocks was rejected, compressed or bypassed and using data of window size to determine the current rejection rate. The calculate rejection rate is used to decide whether to pause and resume compression attempts. We measure the effectiveness of skipping and resuming compression using DB bench and identify any concerning regressions in correctness and performance.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13674
Test Plan:
1. Test case to see if it can automatically start compression on compression friendly workload and see if it can automatically stop compression on non-compression friendly workload (auto_skip_compresor_test.cc)
3. Regression analysis to prove that no significant performance attempt
```bash
SUFFIX=`tty | sed 's|/|_|g'`; for ARGS in "-compression_parallel_threads=1 -compression_type=zstd -compression_manager=none" "-compression_parallel_threads=4 -compression_type=zstd -compression_manager=none" "-compression_parallel_threads=1 -compression_type=zstd -compression_manager=autoskip" "-compression_parallel_threads=4 -compression_type=zstd -compression_manager=autoskip" ; do echo $ARGS; (for I in `seq 1 20`; do ./db_bench -db=/dev/shm/dbbench$SUFFIX --benchmarks=fillseq -num=10000000 -compaction_style=2 -fifo_compaction_max_table_files_size_mb=1000 -fifo_compaction_allow_compaction=0 -disable_wal -write_buffer_size=12000000 $ARGS 2>&1 | grep micros/op; done) | awk '{n++; sum += $5;} END { print int(sum / n); }'; done
```
Measurement experiment | throughput (% change from main branch) |
|---------------|--------------------------------|
compression manager = none (main branch) | 1106890.35 ops/s
compression manager = none (auto skip) | 1097574.55 ops/s (-0.84%)
compression manager = auto skip (auto skip branch) | 1133432.9 ops/s (+2.4%)
Reviewed By: hx235
Differential Revision: D76220795
Pulled By: shubhajeet
fbshipit-source-id: 0f46ab34da1b451f8907306afba221503e6e22a5
Summary:
Since `request_id` is a raw pointer to a string, copying `IODebugContext` becomes a little bit more complicated. We need to ensure that `request_id` gets its memory freed, but by we don't have ownership of the memory by default. The `request_id` inside `IODebugContext` is meant to point to a string allocated outside of the RocksDB read request. To get around this issue without refactoring `request_id`'s type entirely, we can store a private member variable and have `request_id` point to it, so the memory deallocation happens automatically for us.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13690
Test Plan:
I updated the `RequestIdPlumbingTest` unit test from https://github.com/facebook/rocksdb/issues/13616
```
./db_test --gtest_filter=DBTest.RequestIdPlumbingTest
```
Reviewed By: anand1976
Differential Revision: D76613051
Pulled By: archang19
fbshipit-source-id: 053a5b9c4cde20606ec7854ada29904bdf11d40c
Summary:
This field will be used internally to feed Warm Storage cost information back through the Sally IO stack. This is needed for cost accounting / reporting.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13666
Test Plan: I made the additional changes needed to set/record the new cost info field, and confirmed that this information could be fed through.
Reviewed By: anand1976
Differential Revision: D76070434
Pulled By: archang19
fbshipit-source-id: 2fab975f14fd8f7c20b5d0d85c31686ccf682068
Summary:
**Context:**
RocksDB currently selects files for long-running compaction outputs to the bottommost level, preventing these selected files files from being selected, but does not execute the compaction immediately like other compactions. Instead, this compaction is forwarded to another Env::Priority::bottom thread pool, where it waits (potentially for a long time) until its thread is ready to execute. This extended L0 lock time in universal compaction caused our users write stall and read performance regression.
**Summary:**
This PR is to eliminate L0 lock time during bottom priority compaction waiting to execute by the following
- Create and forward an intended compaction only consists of last input file (or sorted run if non-L0) instead of all the input files. This eliminate the locking for non-bottommost level input files while waiting for bottom priority thread is up to run.
- Re-pick compaction that outputs to max output level when bottom priority thread is up to run
- Refactor universal compaction picking logic to make it cleaner and easier to force picking compaction with max output level when bottom priority thread is up to run
- Guard feature behind a temporary option as requested
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13633
Test Plan:
- New unit test to cover the case that's not covered by existing tests - bottom priority thread re-picks compaction ends up picking nothing due to LSM shape changes
- Adapted existing unit tests to verify various bottom priority compaction behavior with this new option
- Stress test `python3 tools/db_crashtest.py --simple blackbox --compaction_style=1 --target_file_size_base=1000 --write_buffer_size=1000 --compact_range_one_in=10000 --compact_files_one_in=10000 `
Reviewed By: cbi42
Differential Revision: D76005505
Pulled By: hx235
fbshipit-source-id: 9688f22d4a84f619452820f12f15b765c17301fd
Summary:
**Context/Summary:**
Since LDB manifest dump including printing the LSM shape does not open the db and manifest itself does not have info about Options.num_levels, LDB tool (the only caller of `DumpManifestHandler` has to set a "hopefully-large-enough" level number (i.e,64) to print info of every level for the LSM shape in the manifest. This can mislead whoever that's reading the manifest to believe there are actually 64 levels configured with the CF. This PR clarifies that.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13681
Test Plan:
Manual test
`./ldb manifest_dump --hex --verbose --json --path=<some manifest file path>`
```
--------------- Column family "9" (ID 9) --------------
log number: 115873
comparator: leveldb.BytewiseComparator
--- level 0 --- version# 19 ---
--- level 1 --- version# 19 --- compact_cursor: '000000000000000900000000000000DF78787878787878' seq:3418519, type:2 ---
--- level 2 --- version# 19 --- compact_cursor: '000000000000000900000000000000D8' seq:3446619, type:2 ---
--- level 3 --- version# 19 --- compact_cursor: '000000000000000900000000000000DF78787878787878' seq:3418519, type:2 ---
--- level 4 --- version# 19 --- compact_cursor: '000000000000000900000000000000DF78787878787878' seq:3418519, type:2 ---
--- level 5 --- version# 19 --- compact_cursor: '0000000000000009000000000000012B0000000000000065' seq:3447830, type:2 ---
--- level 6 --- version# 19 ---
115931:376281[0 .. 0]['0000000000000000' seq:0, type:1 .. '00000000000003E7000000000000012B00000000000002B1' seq:0, type:1]
--- level 7 --- version# 19 ---
--- level 8 --- version# 19 ---
--- level 9 --- version# 19 ---
--- level 10 --- version# 19 ---
--- level 11 --- version# 19 ---
....
--- level 61 --- version# 19 ---
--- level 62 --- version# 19 ---
--- level 63 --- version# 19 ---
By default, manifest file dump prints LSM trees as if 64 levels were configured, which is not necessarily true for the column family (CF) this manifest is associated with. Please consult other DB files, such as the OPTIONS file, to confirm.
```
Reviewed By: jaykorean
Differential Revision: D76391064
Pulled By: hx235
fbshipit-source-id: 3e1c58e0eeb39a5fa020040201b07b181f8977a6
Summary:
In the function WritableFileWriter::WriteBufferedWithChecksum, since the alignment parameter passed to RequestToken defaults to 4096, when data_size is less than 4096, subtracting a larger value from data_size (which is of type unsigned long) will cause an underflow. This results in an infinite loop. Since WriteBuffered does not require alignment, it is sufficient to pass alignment == 0.
issue:https://github.com/facebook/rocksdb/issues/13640
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13641
Reviewed By: jaykorean
Differential Revision: D76341973
Pulled By: hx235
fbshipit-source-id: 8912f2b6598bb5a48b6b813c53146d9ecfd31d30
Summary:
**Context/Summary:**
`RoundRobinSubcompactionsAgainstResources.SubcompactionsUsingResources` has been flaky and difficult to de-flake. One of the reasons is the complicated usage of sync points and unnecessarily strict verification.
- The sync points don't seem necessary to verify the number of extra reserved threads for sub-compactions so are removed.
- The full reservation after compaction to verify extra reserved threads were release is indirect and hard to get right. So it's replaced with simpler sync-point callback check.
- Since we already have tests (see https://github.com/facebook/rocksdb/blob/7d80ea45442e84c25669db61cb7376ba0cd10ba5/env/env_test.cc#L841 and )for testing pure functionality of reserve/release does reserve/release the threads, verifying the relevant code paths are called should be enough to verify extra reserved threads were released after compaction
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13672
Test Plan: Monitor future flakiness.
Reviewed By: cbi42
Differential Revision: D76108242
Pulled By: hx235
fbshipit-source-id: 30113f16455688f113f296bda0098a66a7a198a3
Summary:
**Summary**
This pull request fixes the issue of having a single file simple_mixed_compressor.h containing both implementation and declaration. To improve code organization and follow best practices, I have separated the implementation into a new file simple_mixed_compressor.cc and updated the original file to only contain the necessary declarations.
**Testing**
Testing was performed by verifying the stdout output from both RoundRobinCompressor and BuiltInCompressorV2.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13665
Reviewed By: pdillinger
Differential Revision: D76060831
Pulled By: shubhajeet
fbshipit-source-id: c034868be51ea7b89c1a8dd12082b0159f49f588
Summary:
Iterator seek returns "SeekAndValidate() not implemented" error if the disallow_memtable_writes CF option is set along with paranoid_memory_checks. The fix is to sanitize the paranoid_memory_checks option to false, which should be safe since the memtable is guaranteed to be empty.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13663
Test Plan: Update unit test in db_basic_test.cc
Reviewed By: pdillinger
Differential Revision: D75973515
Pulled By: anand1976
fbshipit-source-id: 3f381f19dcda72e3b78ee375f755fb4809c6b99c
Summary:
Some tests were failing due to apparent missing include of iomanip. I suspect this was from a gtest upgrade, because in open source, the include iomanip comes from gtest.h. To ensure we maintain compatibility with older gtest as well as the newer one, I pulled the include iomanip out of the in-repo gtest.h. Note that other places in gtest code only instantiate floating-point related templates with `float` and `double` types.
Also, to avoid `make format` being insanely slow on gtest.h, I've excluded third-party from the formatting check.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13661
Test Plan: make check, internal CI, manually ensure formatting check works outside of third-party/
Reviewed By: jaykorean
Differential Revision: D75963897
Pulled By: pdillinger
fbshipit-source-id: ed5737dd456e74068185f1ac5d57046d7509df7a
Summary:
**Summary**
This pull request introduces a mixed compressor, RoundRobinManager and RoundRobinCompressor, which selects algorithms in a loop. This implementation replaces the current hacky approach to round-robin compression in BuiltInCompressorV2. Additionally, it configures RocksDB to optionally utilize this customized compressor in the db stress test.
**Testing**
Testing was performed by verifying the stdout output from both RoundRobinCompressor and BuiltInCompressorV2.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13647
Reviewed By: pdillinger
Differential Revision: D75921997
Pulled By: shubhajeet
fbshipit-source-id: 8f42ac46f08ba982b2cd70241bd7dc13ff5a1225
Summary:
... to support SmallEnumSet over CompressionType with allowed custom compression types using most of the available byte. This is accomplished using an std::array<uint64_t> in place of just uint64_t. Also adds an std::bitset-like count() operation.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13657
Test Plan: unit tests included
Reviewed By: hx235
Differential Revision: D75827601
Pulled By: pdillinger
fbshipit-source-id: 519ae97ac671fd9885d6485976abbd969d1392d3
Summary:
**Summary**
This pull request aims to populate num_input_files and total_input_bytes in the CompactionJobStats object, which is accessible through EventListener::OnCompactionBegin(DB*, const CompactionJobInfo&). This change will enable RocksDB users to access accurate compaction input information.
**Context/Goals**
Provide accurate compaction input statistics to RocksDB users
Populate num_input_files and total_input_bytes in CompactionJobStats
Ensure correct population of these fields before EventListener::OnCompactionBegin() is called
**Test Plan**
Added test code to capture num_input_file and total_num_bytes when EventHandler is triggered
Asserted that these values are populated correctly
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13637
Reviewed By: cbi42
Differential Revision: D75690774
Pulled By: shubhajeet
fbshipit-source-id: 8236546f8ce7743f46048b302b376b7ef6429887
Summary:
Somehow this was previously not being tested in our Windows CI jobs so was accidentally broken in https://github.com/facebook/rocksdb/pull/13540 This fix will need to be backported to 10.3.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13649
Test Plan: CI
Reviewed By: hx235
Differential Revision: D75655418
Pulled By: pdillinger
fbshipit-source-id: a56bb213270904a1b7a13b905c2cc1919116df1c
Summary:
Also revamping test
GeneralTableTest::ApproximateOffsetOfCompressed so that it's not sensitive to adding new metadata to SST files
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13646
Test Plan: manually inspect new table property, which is not parsed anywhere, just for information to human reader
Reviewed By: hx235
Differential Revision: D75561241
Pulled By: pdillinger
fbshipit-source-id: c076c01a8b540bc4cb771964d48fa919c4c48ae4
Summary:
to make it easier to use 0 for disabled. And deprecate the use of txn db option `txn_commit_bypass_memtable_threshold`.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13636
Test Plan: updated unit tests.
Reviewed By: jowlyzhang
Differential Revision: D75262136
Pulled By: cbi42
fbshipit-source-id: 9040e5a9c918c1d0906a2db4600cc012d2436b22
Summary:
Larger key/values can cause memtable write to take longer time. Add new option `TransactionOptions::large_txn_commit_optimize_byte_threshold` that enables the optimization by transaction write batch size.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13634
Test Plan:
- new unit test
- added option to stress test and ran stress test for some time: `python3 ./tools/db_crashtest.py --txn blackbox --txn_write_policy=0 --commit_bypass_memtable_one_in=50 --test_batches_snapshots=0`
Reviewed By: jowlyzhang
Differential Revision: D75248126
Pulled By: cbi42
fbshipit-source-id: 9522db93457729ba60e4176f7d47f7c2c7778567
Summary:
This exposes CompressionManager and related classes to the public API and adds `ColumnFamilyOptions::compression_manager` for tying a custom compression strategy to a column family. At the moment, this does not support custom/pluggable compression algorithms, just custom strategies around the built-in algorithms, e.g. which compression to use when and where.
A large part of the change is moving code from internal compression.h to a new public header advanced_compression.h, with some minor changes:
* `Decompressor::ExtractUncompressedSize()` is out-of-lined
* CompressionManager inherits Customizable and some related changes to members of CompressionManager are made. (Core functionality of CompressionManager is unchanged.)
This depends on a smart pointer I'm calling `ManagedPtr` which I'm adding to data_structure.h.
Additionally, advanced_compression.h gets CompressorWrapper and CompressionManagerWrapper as building blocks for overriding aspects of compression strategy while leveraging existing compression algorithms / schemas.
Some pieces needed to support the `compression_manager` option and rudimentary Customizable implementation are included. More work will be needed to make this general and well-behaved (see e.g. https://github.com/facebook/rocksdb/issues/8641; I still hit inscrutible problems every time I touch Customizable).
I'll add a release note for the experimental feature once pluggable compression algorithms and more of the Customizable things are working.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13626
Test Plan:
Added a unit test demonstrating how a custom compressor can "bypass" or "reject" compressions.
Expected next follow-up (probably someone else): use a custom CompressionManager/Compressor to replace the internal hack for testing mixed compressions.
Reviewed By: hx235
Differential Revision: D75028850
Pulled By: pdillinger
fbshipit-source-id: 8565bb8ba4b5fa923b1e29e76b4f7bb4faa42381
Summary:
Some specific old versions around RocksDB 2.5 would compress the metaindex and properties blocks. This hasn't been done since, probably because it interferes with the properties block indicating how to set up for decompression (so the reader can read those blocks before doing any decompression).
To fix backward compatibility, we establish a decompressor early if format_version indicates the file could come from a sufficiently old version.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13628
Test Plan: local and CI runs of tools/check_format_compatible.sh. (I don't believe we need special code to set up a unit test for this case.)
Reviewed By: jowlyzhang
Differential Revision: D75107623
Pulled By: pdillinger
fbshipit-source-id: 97132b8c5e0602e8e27254a11386d866b23cb4f5
Summary:
This PR introduces a new CF option, `memtable_avg_op_scan_flush_trigger`, to support triggering a memtable flush when an iterator skips too many invisible keys from the active memtable. This is a follow up to https://github.com/facebook/rocksdb/pull/13523#discussion_r2038261975, which introduced the option `memtable_op_scan_flush_trigger` for a single expensive iterator step. This PR focus on an expensive stretch of iterator steps, between Seeks and until iterator destruction. To avoid triggering a memtable flush for a stretch that is too small, this option only takes effect when the total number of entries skipped from the active memtable in a stretch of iterator steps exceeds `memtable_op_scan_flush_trigger`.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13593
Test Plan:
* New unit tests covering the new option
* Add the option to the crash test.
Reviewed By: hx235
Differential Revision: D74434263
Pulled By: cbi42
fbshipit-source-id: 64f1101efb79c7498e2038eff630713ead8f6f41
Summary:
Instead of using FileSystem::GetFileSize() for each CompactionOutputFile, use the file size that is being tracked internally as part of the output file's metadata. FileSize is now part of `CompactionServiceOutputFile` and serialized in the `CompactionServiceResult`
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13620
Test Plan:
Tested with logging Meta's internal offload Infra
```
./compaction_job_test
```
Reviewed By: jowlyzhang
Differential Revision: D75006961
Pulled By: jaykorean
fbshipit-source-id: 008f9dc22bd672746ac180380ada4188713a6b85
Summary:
Usual release steps
* Release notes from 10.3 branch
* Update version.h
* Add 10.3.fb to check_format_compatible.sh
* Update folly commit hash. Added a few hacks to fix build errors.
Bonus:
* Add a check_format_compatible.sh sanity check to the per-PR GitHub actions jobs. It should be quick enough and catch typos in release diffs as we've seen in the past.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13622
Test Plan: CI
Reviewed By: jowlyzhang
Differential Revision: D74943843
Pulled By: pdillinger
fbshipit-source-id: 4ff1db9a635e111f8830cadff2d3ee51cf2de512
Summary:
showing up in the crash test after https://github.com/facebook/rocksdb/issues/13540
* For an assertion `dict_samples.sample_data.size() <= opts_.max_dict_bytes` we needed to ensure that `zstd_max_train_bytes` only takes effect with kZSTD compression.
* For an assertion with `r->table_options.verify_compression == (verify_decomp != nullptr)` we needed to ensure that `data_block_verify_decompressor` is set even when dictionary compression is attempted but not used.
* Noticed along the way: finish an optimization in `CompressAndVerifyBlock` that was incomplete.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13621
Test Plan:
Both failures were reproducible with hard-coding of some crash test params, and now not getting a failure.
```
--compression_type=zstd --compression_max_dict_bytes=16384 --compression_zstd_max_train_bytes=65536 --compression_max_dict_buffer_bytes=131071 --compression_use_zstd_dict_trainer=1
```
Write performance test like in https://github.com/facebook/rocksdb/issues/13540 shows essentially no change, maybe slightly faster (+0.4%) with verify_compression.
Reviewed By: virajthakur
Differential Revision: D74939103
Pulled By: pdillinger
fbshipit-source-id: 8bac8891bc08e1356eff52cc524e5bb409b0f86f
Summary:
[internal use] Allow the application to pass a request_id per read request to RocksDB and pass it down to the FileSystem (via IODebugContext)
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13616
Test Plan:
./db_test --gtest_filter=DBTest.RequestIdPlumbingTest
Validates that RocksDB Api calls with request_id set result in request_id being passed to the filesystem through IODebugContext
Reviewed By: pdillinger
Differential Revision: D74912824
Pulled By: virajthakur
fbshipit-source-id: 4f15fef3ff7b5d700563f993f9b211c991020fb6
Summary:
Remove the dependency on `allow_db_generated_files` option in `IngestExternalFile` to be set for ingesting external tables. The files are created by SstFileWriter, and we should be able to ingest them. We could make it work by having the external table implementation provide the version and global sequence number related properties, but its safer to have RocksDB generate the table properties block and store it as is in the file.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13608
Test Plan: Add unit test to test basic ingestion and ingestion with atomic_replace_range
Reviewed By: pdillinger
Differential Revision: D74830707
Pulled By: anand1976
fbshipit-source-id: 4a9bea4a4f38f7c24c584262095c5c98cd771ddc
Summary:
Add stats to monitor the large transaction optimization. A stat is added for how many times wbwi ingestion is used. A histogram is added to track transaction size. We could also just track write batch size for all writes but I don't want to add the overhead to all writes yet.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13611
Test Plan:
ran `python3 ./tools/db_crashtest.py --txn blackbox --txn_write_policy=0 --commit_bypass_memtable_one_in=50 --test_batches_snapshots=0 --stats_dump_period_sec=2 --dump_malloc_stats=0 --statistics=1` and manually check LOG files
```
rocksdb.number.wbwi.ingest COUNT : 57
...
rocksdb.num.op.per.transaction P50 : 1.000000 P95 : 1.000000 P99 : 1.000000 P100 : 1.000000 COUNT : 2265 SUM : 2265
```
Reviewed By: jowlyzhang
Differential Revision: D74829087
Pulled By: cbi42
fbshipit-source-id: 5a9c3ab2d4cb6071cedfc47201ce2cf65a77d3c6
Summary:
Similar to https://github.com/facebook/rocksdb/pull/13555, add more info, ColumnFamily Id and name, to `CompactionServiceJobInfo`.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13615
Test Plan:
Updated Unit Test
```
./compaction_service_test
```
Reviewed By: archang19
Differential Revision: D74845661
Pulled By: jaykorean
fbshipit-source-id: e2fc61006092b9febec1c6637b92cb00fb6cb73e
Summary:
Adds new classes etc. in internal compression.h that are intended to become public APIs for supporting custom/pluggable compression. Some steps remain to allow for pluggable compression and to remove a lot of legacy code (e.g. now called `OLD_CompressData` and `OLD_UncompressData`), but this change refactors the key integration points of SST building and reading and compressed secondary cache over to the new APIs.
Compared with the proposed https://github.com/facebook/rocksdb/issues/7650, this fixes a number of issues including
* Making a clean divide between public and internal APIs (currently just indicated with comments)
* Enough generality that built-in compressions generally fit into the framework rather than needing special treatment
* Avoid exposing obnoxious idioms like `compress_format_version` to the user.
* Enough generality that a compressor mixing algorithms/strategies from other compressors is pretty well supported without an extra schema layer
* Explicit thread-safety contracts (carefully considered)
* Contract details around schema compatibility and extension with code changes (more detail in next PR)
* Customizable "working areas" (e.g. for ZSTD "context")
* Decompression into an arbitrary memory location (rather than involving the decompressor in memory allocation; should facilitate reducing number of objects in block cache)
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13540
Test Plan:
This is currently an internal refactor. More testing will come when the new API is migrated to the public API. A test in db_block_cache_test is updated to meaningfully cover a case (cache warming compression dictionary block) that was previously only covered in the crash test.
SST write performance test, like https://github.com/facebook/rocksdb/issues/13583. Compile with CLANG, run before & after simultaneously:
```
SUFFIX=`tty | sed 's|/|_|g'`; for ARGS in "-compression_parallel_threads=1 -compression_type=none" "-compression_parallel_threads=1 -compression_type=snappy" "-compression_parallel_threads=1 -compression_type=zstd" "-compression_parallel_threads=1 -compression_type=zstd -verify_compression=1" "-compression_parallel_threads=1 -compression_type=zstd -compression_max_dict_bytes=8180" "-compression_parallel_threads=4 -compression_type=snappy"; do echo $ARGS; (for I in `seq 1 20`; do ./db_bench -db=/dev/shm/dbbench$SUFFIX --benchmarks=fillseq -num=10000000 -compaction_style=2 -fifo_compaction_max_table_files_size_mb=1000 -fifo_compaction_allow_compaction=0 -disable_wal -write_buffer_size=12000000 $ARGS 2>&1 | grep micros/op; done) | awk '{n++; sum += $5;} END { print int(sum / n); }'; done
```
Before (this PR and with https://github.com/facebook/rocksdb/issues/13583 reverted):
-compression_parallel_threads=1 -compression_type=none
1908372
-compression_parallel_threads=1 -compression_type=snappy
1926093
-compression_parallel_threads=1 -compression_type=zstd
1208259
-compression_parallel_threads=1 -compression_type=zstd -verify_compression=1
997583
-compression_parallel_threads=1 -compression_type=zstd -compression_max_dict_bytes=8180
934246
-compression_parallel_threads=4 -compression_type=snappy
1644849
After:
-compression_parallel_threads=1 -compression_type=none
1956054 (+2.5%)
-compression_parallel_threads=1 -compression_type=snappy
1911433 (-0.8%)
-compression_parallel_threads=1 -compression_type=zstd
1205668 (-0.3%)
-compression_parallel_threads=1 -compression_type=zstd -verify_compression=1
999263 (+0.2%)
-compression_parallel_threads=1 -compression_type=zstd -compression_max_dict_bytes=8180
934322 (+0.0%)
-compression_parallel_threads=4 -compression_type=snappy
1642519 (-0.2%)
Pretty neutral change(s) overall.
SST read performance test (related to https://github.com/facebook/rocksdb/issues/13583). Set up:
```
for COMP in none snappy zstd; do echo $ARGS; ./db_bench -db=/dev/shm/dbbench-$COMP --benchmarks=fillseq,flush -num=10000000 -compaction_style=2 -fifo_compaction_max_table_files_size_mb=1000 -fifo_compaction_allow_compaction=0 -disable_wal -write_buffer_size=12000000 -compression_type=$COMP; done
```
Test (compile with CLANG, run before & after simultaneously):
```
for COMP in none snappy zstd; do echo $COMP; (for I in `seq 1 5`; do ./db_bench -readonly -db=/dev/shm/dbbench-$COMP --benchmarks=readrandom -num=10000000 -duration=20 -threads=8 2>&1 | grep micros/op; done) | awk '{n++; sum += $5;} END { print int(sum / n); }'; done
```
Before (this PR and with https://github.com/facebook/rocksdb/issues/13583 reverted):
none
1495646
snappy
1172443
zstd
706036
zstd (after constructing with -compression_max_dict_bytes=8180)
656182
After:
none
1494981 (-0.0%)
snappy
1171846 (-0.1%)
zstd
696363 (-1.4%)
zstd (after constructing with -compression_max_dict_bytes=8180)
667585 (+1.7%)
Pretty neutral.
Reviewed By: hx235
Differential Revision: D74626863
Pulled By: pdillinger
fbshipit-source-id: dc8ff3178da9b4eaa7c16aa1bb910c872afaf14a
Summary:
Addresses https://github.com/facebook/rocksdb/issues/13587.
This PR exposes the optimized implementation of batched reads through a `Transaction` object to Java clients.
The latency improvement of transactional multiget on production workload achieved by switching the implementation is roughly:
```
quantile=0.2: 21%
quantile=0.5: 28%
quantile=0.8: 46%
quantile=1.0: 239%
```
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13589
Reviewed By: jaykorean
Differential Revision: D74660169
Pulled By: cbi42
fbshipit-source-id: d01780173e0500c96e5e431ff6645008cbf6e8b5
Summary:
Expose pinned WriteBatchWithIndex::GetFromBatchAndDB through C bindings so that one can read data from the `WriteBatchWithIndex` and db w/o copying the data.
This fixes https://github.com/facebook/rocksdb/issues/12969.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/12970
Reviewed By: cbi42
Differential Revision: D74586418
Pulled By: jaykorean
fbshipit-source-id: a5a4d2e8ce3ddf4c2371fdfdb4e9c3309966a05d
Summary:
As titled.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13605
Test Plan: This is removing a test
Reviewed By: mszeszko-meta
Differential Revision: D74660230
Pulled By: jowlyzhang
fbshipit-source-id: 9c1d46b56d2f9ee43eba645563d4f954645d1ace
Summary:
We saw some crash test failure for secondary db. It happens during crash recovery verification. This PR logs the manifest number when such failure happens. This PR also includes a small fix in `TryCatchUpWithPrimary()` that could incorrectly check WAL not found case.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13594
Test Plan: monitor further secondary DB crash test failure.
Reviewed By: archang19
Differential Revision: D74488769
Pulled By: cbi42
fbshipit-source-id: 226e55b2f99a739e93abda3ee91c05b80f59bf6a
Summary:
This PR fixes a bug where the file checksum for an external table file was not being calculated by SstFileWriter. The checksum is calculated in WritableFileWriter, so we need to pass that the the external table builder rather than the FSWritableFile pointer directly. However, WritableFileWriter is private to RocksDB, so wrap it in an FSWritableFile and pass it.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13591
Test Plan: Add a new test in table_test.cc
Reviewed By: jaykorean
Differential Revision: D74410563
Pulled By: anand1976
fbshipit-source-id: c7fa8142e20da8836589dee5fa50919951cf4046
Summary:
Prior to this PR, for FIFO kChangeTemperature compaction was done by iterating and reading thru the input sst and generate the output sst. This was wasteful since for FIFO we could apply the "trivial" move by copying the input sst to the out sst without need decompress/compress and reading thru the input sst content at all. This PR added "allow_trivial_copy_when_change_temperature" to the CompactionOptionsFIFO.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13562
Reviewed By: cbi42
Differential Revision: D73295404
Pulled By: mikechuangmeta
fbshipit-source-id: 02241c7389797730ecd4a3b636837cb5f912b424
Summary:
Allow specifying ReadOptions for WBWI iterator when creating it through the C bindings. This allows to specify upper and lower bounds for the created iterator.
This fixes https://github.com/facebook/rocksdb/issues/12963.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/12968
Reviewed By: pdillinger
Differential Revision: D74188049
Pulled By: jaykorean
fbshipit-source-id: 970d9910472dfedaa29a800c6d52bec14c656f3c
Summary:
clarify in comments and fix one implementation under NewIterator where option `memtable_op_scan_flush_trigger` does not work correctly with tailing iterator yet. This is because tailing iterator can rebuild iterator internally which reads from a newer memtable, and DBIter's reference to active memtable needs to be refreshed. This PR clarifies that `memtable_op_scan_flush_trigger` will have no effect on tailing iterator. We can add the support in the future if needed.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13586
Test Plan: existing tests.
Reviewed By: jaykorean
Differential Revision: D74108099
Pulled By: cbi42
fbshipit-source-id: 7c6608485d57755abc44f3be0b3c5d82a7bc5ca9
Summary:
While working on some compression refactoring, I noticed that `NotifyCollectTableCollectorsOnBlockAdd()` was being called from multiple threads (with `parallel_threads` > 1), meaning we were violating the promise that TablePropertiesCollectors need not be thread safe (and typically will not be, for efficiency).
Fixing this is a bit awkward or intrusive. Even though it seems weird to expose `block_compressed_bytes_fast` and `block_compressed_bytes_fast` in the public `BlockAdd()` function, and NOT the actual compressed block size used, there are some Meta-internal uses that would at least require negotiation / coordination to deprecate and remove. So it's probably easiest to just keep the awkward functionality and do the necessary modifications to call from a single thread.
The simplest solution that preserves the functionality with `parallel_threads` > 1 (provide the sampling data, expected ordering between `BlockAdd()` and `AddUserKey()`, no races) is to do the compression sampling in the thread building uncompressed blocks. Specifically, moving `NotifyCollectTableCollectorsOnBlockAdd()` and the compression sampling from `CompressAndVerifyBlock()`, which is called in parallel, to table builder `Flush()`, which is only called serially (per file). Even though this adds some compression to that single thread when sampling is enabled, that should be tolerable without complicating the code or regressing performance. Some related or nearby optimizations are included to ensure this.
* Got rid of a lot of unnecessary indirection and unnecessary fields in BlockRep, which should be a step in improving parallel compression performance (still bad IMHO).
* Restructured some `if`s etc. to streamline some logic
This satisfies my original refactoring need to moving the sampling code higher up the stack from `CompressBlock()`, to set up some other upcoming refactorings. The other caller of `CompressBlock()` (legacy BlobDB) doesn't need it, and in fact is better off calling `CompressData()` directly because it does not appear to be dealing with the various "no compression" outcomes introduced by `CompressBlock()`.
Eventual follow-up:
* Performance data below shows how the overhead of parallel compression can make it slower, with available CPUs, compared to serial compression. This infrastructure should be re-designed/re-engineered to reduce thread creation, context switches, etc. Also, more of the processing such as checksumming could be parallelized. (Things dependent on the block location in the file, such as ChecksumModifierForContext and cache warming, cannot be parallelized.)
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13583
ThreadSanitizer: data race /data/users/peterd/rocksdb/./db_stress_tool/db_stress_table_properties_collector.h:36:5 in rocksdb::DbStressTablePropertiesCollector::BlockAdd(unsigned long, unsigned long, unsigned long)
```
Performance:
```
SUFFIX=`tty | sed 's|/|_|g'`; for ARGS in "-compression_parallel_threads=1 -compression_type=none" "-compression_parallel_threads=1 -compression_type=snappy" "-compression_parallel_threads=4 -compression_type=snappy"; do echo $ARGS; (for I in `seq 1 100`; do ./db_bench -db=/dev/shm/dbbench$SUFFIX --benchmarks=fillseq -num=10000000 -compaction_style=2 -fifo_compaction_max_table_files_size_mb=1000 -fifo_compaction_allow_compaction=0 -disable_wal -write_buffer_size=12000000 $ARGS 2>&1 | grep micros/op; done) | awk '{n++; sum += $5;} END { print int(sum / n); }'; done
```
Average ops/s of 100 runs, running before & after at the same time, using clang DEBUG_LEVEL=0:
-compression_parallel_threads=1 -compression_type=none
Before: 1976319
After: 1983840 (+0.3%)
-compression_parallel_threads=1 -compression_type=snappy
Before: 1945576
After: 1953473 (+0.4%)
-compression_parallel_threads=4 -compression_type=snappy
Before: 1573190
After: 1611881 (+2.4%)
-compression_parallel_threads=4 -sample_for_compression=100 (pretty high sample rate)
Before: 1577167
After: 1589704 (+0.8%)
-compression_parallel_threads=4 -sample_for_compression=10 (crazy high sample rate)
Before: 1581276
After: 1393453 (-11.9%)
As seen, you need a very very high compression sample rate to see a regression. I would expect a setting like 1000 to be more typical.
Test Plan:
Along with existing unit tests + CI, expanded crash test to make its TablePropertiesCollector non-trivial, to exercise the bug (and other potential bugs), which was confirmed with local run of whitebox_crash_test with TSAN:
```
Reviewed By: hx235
Differential Revision: D73944593
Pulled By: pdillinger
fbshipit-source-id: f1dcba4ebdc01e735251037395003945c9b34e62
Summary:
I added `TransactionDBOptions::txn_commit_bypass_memtable_threshold` previously but per DB option is not dynamically changeable. Adding it as a per transaction option to make it easier to use. The option naming is updated to make it easier for customer to understand `large_txn_commit_optimize_threshold`. The transaction DB option `TransactionDBOptions::txn_commit_bypass_memtable_threshold` is marked as deprecated.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13582
Test Plan:
- new unit test
- updated stress test to use this new transaction option
Reviewed By: jowlyzhang
Differential Revision: D73960981
Pulled By: cbi42
fbshipit-source-id: 406f6e0f5f4eb6b336976f9a93b0bc08e61a9662
Summary:
AcquireLocked() returns transaction ids that currently hold the lock for deadlock detection purpose. We should not include the id of the transaction that is trying to acquire the lock, since this would lead to a false-positive deadlock detection where the deadlock is a self-loop. Note that since `wait_ids` is never cleared, there is another bug where if AcquireLocked() fails with kLockLimit, we could do deadlock detection based on `wait_ids` from a previous lock acquire attempt. This PR fixes both bugs.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13575
Test Plan: added a unit test repro that shows deadlock status can be incorrectly returned.
Reviewed By: jaykorean
Differential Revision: D73617887
Pulled By: cbi42
fbshipit-source-id: a6388b3ec53db13e2c502d60199378ea95885841
Summary:
**Context/Summary:**
Similar to https://github.com/facebook/rocksdb/commit/0a43d8a261b9c633c0a4e369b1ef33aa5ee32810, this is to verify flush output file contains the exact number of keys (represented by its `TableProperties::num_entries`) as added to table builder for block-based and plain table format. The implementation reuses a temporary compaction stats to record output record and existing input record (with some refactoring)
**Bonus:**
following https://github.com/facebook/rocksdb/commit/0a43d8a261b9c633c0a4e369b1ef33aa5ee32810#r154313564, limit compaction output record count check within block based table and plain table format as well as removing extra test setting; fix some typo
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13556
Test Plan: New test
Reviewed By: jaykorean
Differential Revision: D73229644
Pulled By: hx235
fbshipit-source-id: 2a7796450048b3bcb2d5c38f2b5fc6b53e4aae37
Summary:
we want to limit the maximum disk space used by RocksDB in one of our Go services, as it runs on a highly disk-constrained network switch.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13404
Reviewed By: cbi42
Differential Revision: D73517940
Pulled By: jaykorean
fbshipit-source-id: ae91fc7a4992399e20f06cc67dad8130cf19049e
Summary:
This test was failing sporadically for me, like
```
db/db_properties_test.cc:247: Failure
Expected: (static_cast<double>(dbl_a - dbl_b) / (dbl_a + dbl_b)) <
(bias), actual: 0.113964 vs 0.1
```
I tried waiting for compaction in the test, but that made it fail consistently. Based on inspection of the test and the related test AggregatedTablePropertiesAtLevel already using `disable_auto_compactions = true`, I'm applying that to this test.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13568
Test Plan: Parallel runs of the unit test, before and after
Reviewed By: jaykorean
Differential Revision: D73463685
Pulled By: pdillinger
fbshipit-source-id: 84df7cc9bdcd1caa108a7be254ffbebbe9a77de7
Summary:
* Mostly, remove `sample_for_compression` from CompressionInfo because it's not used by the core function it serves, `CompressData()`. Confusing (and inefficient), especially in db_bench where it appears to use `FLAGS_sample_for_compression` in places where it is actually ignored.
* Various clarifying comments, clean-ups, and tiny optimizations
* Prepare some structures like `CompressionDict` for more usage
* Some TODOs and FIXMEs about some things I've noticed are amiss, confusing, or excessive
* A notable optimization opportunity that might become a "pay as you go" improvement for the potential indirection costs of customizable compression: use C++23's resize_and_overwrite() in compress functions to avoid zeroing the string buffer contents before populating it.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13539
Test Plan: existing tests / CI
Reviewed By: hx235
Differential Revision: D73451273
Pulled By: pdillinger
fbshipit-source-id: 0373627466d695043d21146ce34d52f189ae9432
Summary:
Updated version, HISTORY and compatibility script for 10.3 release (no folly hash update in this release).
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13566
Test Plan: CI
Reviewed By: anand1976
Differential Revision: D73391839
Pulled By: jaykorean
fbshipit-source-id: 075bb1f9f25caf96c4fcca7f4a315666acd5a288
Summary:
Adding an arbitrary options map so that any additional overridable options can be added without RocksDB change. Unknown options will be ignored
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13552
Test Plan:
Unit Test added
```
./db_secondary_test -- --gtest_filter="*OptionsOverrideTest*"
```
Reviewed By: hx235
Differential Revision: D73203789
Pulled By: jaykorean
fbshipit-source-id: 176bd9849d2bc60e78657c119e10a1a2a0988cd1
Summary:
This PR adds a DB::GetNewestUserDefinedTimestamp API to get the newest timestamp of the column family. This is only for when the column family enables user defined timestamp.
It checks the mutable memtable, the immutable memtable and the SST files, and returns the first newest user defined timestamp found. When user defined timestamp is not persisted in SST files, there is metadata in MANIFEST tracking upperbound of flushed timestamps, so the newest timestamp in SST files can be found. If user defined timestamps are
persisted in SST files, currently no timestamp metadata info is persisted. A NotSupported status will be returned if SST files need to be checked in that case.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13547
Test Plan: Added tests
Reviewed By: cbi42
Differential Revision: D73123575
Pulled By: jowlyzhang
fbshipit-source-id: 460ac4f9c96926d3c8fcf7944edab8dc0feae1dd
Summary:
add support for ingesting a WriteBatchWithIndex into the DB with the new API `IngestWriteBatchWithIndex()`. This ingestion works similarly as `TransactionOptions::commit_bypass_memtable` where the WBWI will be ingested as an immutable memtable. Since this skips memtable writes, it improves the write performance when writing a large write batch into the DB. Currently this API only supports `disableWAL=true`. Support for WAL write will be in a follow up if needed.
For a WBWI to be ingestable, we needed to call `SetTrackPerCFStat()` at WBWI creation. This PR removes this step for simpler usage and per CF stats will always be tracked in WBWI. `WBWIIteratorImpl::TestOutOfBound()` is optimized to offset the performance impact.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13550
Test Plan:
- new unit test
- stress test option ingest_wbwi_one_in and ran a few runs of `python3 ./tools/db_crashtest.py blackbox --enable_pipelined_write=0 --use_timed_put_one_in=0 --use_put_entity_one_in=0 --ingest_wbwi_one_in=10 --test_batches_snapshots=0 --enable_blob_files=0 --preserve_unverified_changes=1 --avoid_flush_during_recovery=1 --disable_wal=1 --inplace_update_support=0 --interval=40`
Reviewed By: jowlyzhang
Differential Revision: D73152223
Pulled By: cbi42
fbshipit-source-id: 339f8ed26ac5a798238870df3ba857ba1add759b
Summary:
A reopened writable file's size is not correctly tracked in the `WritableFile`'s internal state. This PR adds a querying to the file system to get the initial file size in the reopen case and use it to populate posix `WritableFile`'s internal state.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13534
Reviewed By: anand1976
Differential Revision: D72756628
Pulled By: jowlyzhang
fbshipit-source-id: 6f02b5c5da069fe49055d7b75bec9e7e47d5cd71
Summary:
Add a test to cover an internal user's expected behavior of using atomic_replace_range feature to atomically ingest a version key and a data file.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13549
Test Plan: This is a test
Reviewed By: cbi42
Differential Revision: D73142626
Pulled By: jowlyzhang
fbshipit-source-id: a5bdc24b762cbe91dd4d94242b9e1539c9feaf61
Summary:
add support for atomic_flush when using WBWI ingestion [feature](https://github.com/facebook/rocksdb/blob/29c6610617ddc1b486f12b99c16e7c9851e80430/include/rocksdb/utilities/transaction_db.h#L387). Transaction DB usually uses WAL so atomic_flush is not as helpful. This is to prepare for a follow up PR that enables ingesting WBWI without using transaction DB.
This PR also removes a redundant parameter `prep_log` for the WBWI ingestion feature.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13545
Test Plan:
- unti test added
- stress test will be added as we add support to ingest WBWI without using transaction DB.
Reviewed By: jowlyzhang
Differential Revision: D73062342
Pulled By: cbi42
fbshipit-source-id: e05da55dfabb8241a042214b9d50b1b49d42613e
Summary:
**Context/Summary:**
This PR adds new stats to measure compaction readahead size for rocksdb managed prefetching (not FS prefetching). It can be used to verify compaction read-ahead is doing what's configured. This PR also excludes compaction readahead stats from user scan readahead stats measured in existing stats so there is a cleaner separating between these two.
Bonus: this PR also included some typo fixing about "io activities"
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13520
Test Plan: Modified existing test to verify stats
Reviewed By: archang19
Differential Revision: D72892850
Pulled By: hx235
fbshipit-source-id: 1a73182061baa044c9c9193a2b0fd967ffe75c4a
Summary:
* Clarify in API comments which `log_` options in DBOptions relate to WALs, info log, and/or manifest files.
* Rename a bunch of "log" things to "wal" for clarity, especially in DBImpl. (More to go, especially some more challenging cases like `DBImpl::logs_`, but a step in the right direction IMHO)
* Simplify DBImpl ctor by moving constant initializers to field definitions.
* Use RelaxedAtomic for (renamed) `wals_total_size_`
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13490
Test Plan: existing tests
Reviewed By: cbi42
Differential Revision: D71939382
Pulled By: pdillinger
fbshipit-source-id: 852f4737eca83e6ad653010cc197ad1b6e6bae13
Summary:
Introduce a mutable CF option `memtable_op_scan_flush_trigger`. When a DB iterator scans this number of hidden entries (tombstones, overwritten puts) from the active memtable in a Seek() or Next() operation, it marks the memtable to be eligible for flush. Subsequent write operations will schedule the marked memtable for flush.
The main change is small and is in db_iter.cc. Some refactoring is done to consolidate and simplify creation of `ArenaWrappedDBIter` and `DBIter`.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13523
Test Plan:
- new unit tests added.
- added `memtable_op_scan_flush_trigger` in crash test
- benchmark:
The following benchmark was done with a previous version of the PR where the option was `memtable_tombstone_scan_limit` and it concerns tombstone only. The results should still be applicable for the case when there's no overwritten puts.
Tests that when memtable has many tombstones, the option helps to improve scan performance:
```
TEST_TMPDIR=/dev/shm ./db_bench --benchmarks=seekrandomwhilewriting --expand_range_tombstones=true --writes_per_range_tombstone=1 --max_num_range_tombstones=10000000 --perf_level=2 --range_tombstone_width=100 --memtable_tombstone_scan_limit=
memtable_tombstone_scan_limit = 10000
seekrandomwhilewriting : 18.527 micros/op 53973 ops/sec 18.527 seconds 1000000 operations; (7348 of 1000000 found)
next_on_memtable_count = 122305248
grep "flush_started" /dev/shm/dbbench/LOG | wc
8 200 2417
memtable_tombstone_scan_limit=200
seekrandomwhilewriting : 4.918 micros/op 203315 ops/sec 4.918 seconds 1000000 operations; (4510 of 1000000 found)
next_on_memtable_count = 1853167
grep "flush_started" /dev/shm/dbbench/LOG | wc
184 4600 54121
When memtable_tombstone_scan_limit=200, more flush is trigged to drop tombstones sooner and improve scan performance.
```
Tests that the new option does not introduce noticeable regression:
```
TEST_TMPDIR=/dev/shm ./db_bench --benchmarks=seekrandomwhilewriting[-X5] --expand_range_tombstones=true --writes_per_range_tombstone=1 --max_num_range_tombstones=10000000 --perf_level=2 --range_tombstone_width=100 --seed=123
Main:
seekrandomwhilewriting [AVG 5 runs] : 46049 (± 4512) ops/sec
PR:
seekrandomwhilewriting [AVG 5 runs] : 46100 (± 4470) ops/sec
The results are noisy with this PR performing better and worse in different runs, with no noticeable regression.
```
Reviewed By: pdillinger
Differential Revision: D72596434
Pulled By: cbi42
fbshipit-source-id: 2d51a0221dc20dac844aeba2ad3999d075a4cf91
Summary:
When ReadOptions.allow_unprepared_value is true, a `Iterator::PrepareValue()` call is needed to prepare the value after an entry is pinpointed, to only load the blob when it's actually needed. And it uses the `saved_key_.GetUserKey()` to prepare value.
https://github.com/facebook/rocksdb/blob/6d802639f7dc35bf765dbe1ed6b3942e4d76375d/db/db_iter.cc#L319
In the reverse iteration case, when the `FindValueForCurrentKeyUsingSeek()` path is used, `saved_key_` is only updated when `ReadOptions.iter_start_ts` is specified. This PR fixes it by updating `saved_key_` for the other case too.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13531
Test Plan: The FIXME test that reproduce the bug is updated
Reviewed By: pdillinger
Differential Revision: D72681397
Pulled By: jowlyzhang
fbshipit-source-id: 6c239da53c9beed1560d30013474f2ba542b245c
Summary:
Fix a reported data race, accessing `manifest_reader_` without locking `mutex_` could race with another `DBImpl::Secondary::TryCatchUpWithPrimary` thread that is updating to a new manifest in `ReactiveVersionSet::MaybeSwitchManifest`.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13529
Test Plan: Existing tests
Reviewed By: hx235
Differential Revision: D72655645
Pulled By: jowlyzhang
fbshipit-source-id: 08599862346bb39a6872c3adfd7f0097fc633849
Summary:
As titled. This option has been marked deprecated since introduction of a better option `max_write_buffer_size_to_maintain` and acts as its fallback since RocksDB 6.5.0 The internal user we know these options were created for migrated to `max_write_buffer_size_to_maintain` for a long time too.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13491
Test Plan: existing tests
Reviewed By: cbi42
Differential Revision: D71984601
Pulled By: jowlyzhang
fbshipit-source-id: c264d4809e311f60fdbad817ebfade256db549b6
Summary:
**Context/Summary:**
Rebased on https://github.com/facebook/rocksdb/pull/13522/files, this is to use the refactored function to calculate tail size from table property "tail_start_offset"
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13524
Test Plan: CI
Reviewed By: anand1976
Differential Revision: D72576262
Pulled By: hx235
fbshipit-source-id: 78c126bc64024c2341d183d6871e06d55fd27501
Summary:
**Context/Summary:**
This is to fix a bug that tail size of remote compaction output SST file is not persisted to manifest in primary instance. This prevent us from using direct tail prefetch optimization each time opening this SST file.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13522
Test Plan: Modify existing UT that failed before the fix
Reviewed By: anand1976
Differential Revision: D72479612
Pulled By: hx235
fbshipit-source-id: 1ba8aa66fac71b9196589f60076229c29a103706
Summary:
Public APIs like `DB::GetFullHistoryTsLow` and `DB::IncreaseFullHistoryTsLow` have such safeguarding, allowing them to only be invoked when user defined timestamp is enabled. This PR adds safeguarding into related internal APIs in `ColumnFamilyData` to properly handle the case when the UDT feature are toggled.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13521
Test Plan: ./db_with_timestamp_basic_test --gtest_filter="*EnableDisableUDT*"
Reviewed By: cbi42
Differential Revision: D72475234
Pulled By: jowlyzhang
fbshipit-source-id: 194c07287e3100da95450b04c76552c9d4a86c2d
Summary:
A multi scan API for users to pass a set of scan ranges and have the table readers determine the optimal strategy for performing the scans. This might include coalescing of IOs across scans, for example. The requested scans should be in increasing key order. The scan start keys and other info is passed to NewMultiScanIterator, which in turn uses the newly added Prepare() interface in Iterator to update the iterator. The Prepare() takes a vector of ScanOptions, which contain the start keys and optional upper bounds, as well as user defined parameters in the property_bag taht are passed through as is to external table readers.
The initial implementation plumbs this through to the ExternalTableReader. This PR also fixes an issue of premature destruction of the external table iterator after the first scan of the multi-scan. The `LevelIterator` treats an invalid iterator as a potential end of file and destroys the table iterator in order to move to the next file. To prevent that, this PR defines the `NextAndGetResult` interface that the external table iterator must implement. The result returned by `NextAndGetResult` differentiates between iterator invalidation due to out of bound vs end of file.
Eventually, I envision the `MultiScanIterator` to be built on top of a producer-consumer queue like container, with RocksDB (producer) enqueueing keys and values into the container and the application (consumer) dequeueing them. Unlike a traditional producer consumer queue, there is no concurrency here. The results will be buffered in the container, and when the buffer is empty a new batch will be read from the child iterators. This will allow the virtual function call overhead to be amortized over many entries.
TODO (in future PRs):
1. Update the internal implementation of Prepare to trim the ScanOptions range based on the intersection with the table key range, taking into consideration unbounded scans and opaque user defined bounds.
2. Long term, take advantage of Prepare in BlockBasedTableIterator, atleast for the upper bound case.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13473
Reviewed By: pdillinger
Differential Revision: D71447559
Pulled By: anand1976
fbshipit-source-id: 31668abb0c529aa1ac1738ae46c36cbddf9148f1
Summary:
**Context/Summary:**
- This is an attempt to fix our [build-window-vs2022 failure](https://github.com/facebook/rocksdb/actions/runs/14215681026/job/39831770554?fbclid=IwZXh0bgNhZW0CMTAAAR2BQLjp8kC1u1yyvN1_S5qwmrHEZOfzxJdcbj2vq7mvwwq83n1cbkmiBCA_aem_ygYxQA5EUmxh2y4EjMlTfg) below. snappy-1.1.8's cmake_minimum_required being less than 3.5 seems to trigger the complaint. Hopefully downloading the 1.2.2 which is the [first version starting to use higher cmake_minimum_required version](https://github.com/google/snappy/releases/tag/1.2.2) solves the failure.
```
Directory: D:\a\rocksdb\rocksdb\thirdparty\snappy-1.1.8
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 4/2/2025 9:02 AM build
CMake Error at CMakeLists.txt:29 (cmake_minimum_required):
Compatibility with CMake < 3.5 has been removed from CMake.
Update the VERSION argument <min> value. Or, use the <min>...<max> syntax
to tell CMake that the project requires at least <min> but has been updated
to work with policies introduced by <max> or earlier.
Or, add -DCMAKE_POLICY_VERSION_MINIMUM=3.5 to try configuring anyway.
```
- The downloaded snappy do not include the content under nested repos Google Test and Google Benchmark. But snappy cmake by default will attempt to build them. Since we don't change snappy, we don't need building such development suit. This PR also disabled snappy cmake's attempt to build them.
- By running above changes, the same build [complained](https://github.com/facebook/rocksdb/actions/runs/14228883966/job/39874927730?pr=13514) about java cmakelists requiring too low cmake_minimum_required as well. So this PR also upgraded its cmake_minimum_required to be 3.11 aligning with its warning message
```
if(${CMAKE_VERSION} VERSION_LESS "3.11.4")
message("Please consider switching to CMake 3.11.4 or newer")
endif()
```
**Test plan**
Monitor build-window-vs2022 for this PR
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13514
Reviewed By: pdillinger
Differential Revision: D72333581
Pulled By: hx235
fbshipit-source-id: 1a9096738d39c8b1d270fe17fbd78c1ea4c4c45e
Summary:
Essentially fix https://github.com/facebook/rocksdb/issues/13429 by
* Avoiding publishing to readers a partial write batch written to memtable. Also clarify in DB::Write that WriteBatch is applied atomically, and improve some logging.
* When we know we have written a bad write batch to WAL due to memtable insert failure, make a good effort to roll it back to make the DB recoverable. (Not compatible with all options.)
Fixes https://github.com/facebook/rocksdb/issues/13429
Follow-up items:
* More rigorously test and fix the code paths and option combinations where these features could be useful.
* Allow default CF with disallow_memtable_writes (with caveat that violation stops writes on your open DB)
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13489
Test Plan: Updated existing test, manually verified the DB went into a "stopped" state at least in this example.
Reviewed By: jaykorean
Differential Revision: D71917670
Pulled By: pdillinger
fbshipit-source-id: c9b9dfc102817fc4c160a6c7170c04011c228aaf
Summary:
We are seeing some occasional failures with WRITE_(UN)PREPARED crash test runs, and it's alarming when these are grouped in with WRITE_COMMITTED, which AFAIK is the only one considered mature and mission-critical at this point.
* Mark WRITE_(UN)PREPARED as EXPERIMENTAL in the public APIs
* Separate out the `_with_txn` crash test jobs by write policy, now `_with_wc_txn`, `_with_wp_txn` and `_with_wup_txn` so that the major functional and maturity differences are better grouped.
* Add `_with_multiops_wup_txn` which was apparently missing
* Clean up db_crashtest.py for better consistency
* Get rid of awkard "write_policy" parameter that could conflict with authoritative "txn_write_policy" parameter.
* Similarly, move some multiops logic from different parameter sets to finalize_and_sanitize logic.
Immediate internal follow-up:
* Migrate from `_with_txn` which are now deprecated aliases of `_with_wc_txn` to more jobs with the new variants. And likely also add new multiops job.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13499
Test Plan: manual runs of modified jobs, at least long enough to spot check things like txn_write_policy
Reviewed By: hx235
Differential Revision: D72015307
Pulled By: pdillinger
fbshipit-source-id: 06b99b2d1f15ac76fe7b8e22c93a51aaa2a42ecf
Summary:
**Context/Summary:**
MaxMemCompactionLevel() developed 10 years ago simply returns the level a memtable flushed to, which has historically been L0 and have no plan to change to something different for future. It is also not used in test or internally.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13503
Test Plan: CI + fake release
Reviewed By: cbi42
Differential Revision: D72066092
Pulled By: hx235
fbshipit-source-id: 5ff5b16a6664ef3efabd3a6fbd8a2d0529b62460
Summary:
based on the option comment, `ignore_range_deletions` was added due to the overhead of range deletions in read path when a DB does not use DeleteRange(). The current implementation should not have a noticeable performance difference in this case.
`experimental::PromoteL0()` can be replaced by doing a manual compaction with proper CompactRangeOptions.
There are some internal use of these option and API so we will remove them later after the usages are updated.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13500
Test Plan:
comment change only.
Performance: benchmark the performance difference with `ignore_range_deletions` and without (borrowed flag `universal_incremental` for this purpose), ran at the same time on the same machine.
- random point get:
- ignore_range_deletions=false: 343078 ops/sec
- ignore_range_deletions=true: 340219 ops/sec (0.8% slower)
```
(for I in $(seq 1 1); do TEST_TMPDIR=/dev/shm/t1 /data/users/changyubi/vscode-root/rocksdb/db_bench --benchmarks=fillseq,waitforcompaction,readrandom --write_buffer_size=67108864 --writes=1000000 --num=2000000 --reads=1000000 --seed=1723056275 --universal_incremental=false 2>&1 | grep "readrandom"; done;) | awk '{ t += $5; c++; print } END { print 1.0 * t / c }';
```
- sequential scan:
- ignore_range_deletions=false: 5378104 ops/sec
- ignore_range_deletions=true: 5393809 ops/sec (0.3% faster)
```
(for I in $(seq 1 10); do TEST_TMPDIR=/dev/shm/t1 /data/users/changyubi/vscode-root/rocksdb/db_bench --benchmarks=fillseq,waitforcompaction,readseq[-X10] --write_buffer_size=67108864 --writes=1000000 --num=2000000 --universal_incremental=true --seed=1723056275 2>1 | grep "\[AVG 10 runs\]"; done;) | awk '{ t += $6; c++; print; } END { printf "%.0f\n", 1.0 * t / c }';
```
The difference in ops/sec for the two benchmarks is likely noise.
Reviewed By: hx235
Differential Revision: D72069223
Pulled By: cbi42
fbshipit-source-id: ad82a051aa4682790d2178cd4fb2d1467397fbb5
Summary:
Acquiring a lock here can take a long time and cause a user mode scheduler to hold up, as it relies on explicit yielding. Hence, forcing a check here but ignoring any abort requests. Would rely on upstream to take action on aborts.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13498
Reviewed By: pdillinger
Differential Revision: D71987173
Pulled By: jainpr
fbshipit-source-id: 4aec40bdf0bc657e29f72c306c576b3117f97a25
Summary:
Based on passing address of uninit variable in ReadOnlyMemTable::Get() in memtable.h. The contract and other implementations suggest it is a pure out parameter that is always overwritten, so we initialize it in the function before checking its value in a loop
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13486
Test Plan: watch build-linux-valgrind in CI
Reviewed By: cbi42
Differential Revision: D71819843
Pulled By: pdillinger
fbshipit-source-id: 1e06f3ee6998099791af27de5b2872eb476ceb7c
Summary:
The new API in https://github.com/facebook/rocksdb/issues/13453 is awkward and precarious because of using RangePtr, which encodes optional keys using raw pointers to Slice. We could use `std::optional<Slice>` instead but that is unsatisfyingly a larger object with an inefficient size (typically 17 bytes).
Here I introduce a custom optional Slice type, `OptSlice`, that is the same size as a Slice, and use it in a number of places to clean up code and make some public APIs easier to work with. This includes
* `atomic_replace_range` (not yet released, OK to change)
* `GetAllKeyVersions()` which gets a behavior change because of its unusual handling of empty keys.
* `DeleteFilesInRanges()`
* TODO in follow-up: `CompactRange()`
Most of the diff is associated updates and refactorings. Also
* Move some relevant things out of db.h to keep it as tidy as possible.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13481
Test Plan: tests updated
Reviewed By: hx235
Differential Revision: D71747774
Pulled By: pdillinger
fbshipit-source-id: b4c8519608d119b8bceca9bb0fd778608f62a141
Summary:
As titled. This API returns the table properties of files per level. It can be handy for use cases that needed file's leveling info while retrieving TableProperties. We will use this API to later aggregate per level data write time info.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13469
Test Plan: Added unit tests
Reviewed By: pdillinger
Differential Revision: D71353096
Pulled By: jowlyzhang
fbshipit-source-id: dc1fbb2c97e4365fc8d7241f9a59c65fbf4fb766
Summary:
This PR adds a new field `CompactionJobStats.num_input_files_trivially_moved` representing the number of files this compaction trivially moved. It should either equal to the total number of input files, or being 0.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13479
Test Plan: Added tests
Reviewed By: hx235
Differential Revision: D71638796
Pulled By: jowlyzhang
fbshipit-source-id: 794c085408a0dc95f11874ca60fca3e6b5b92cba
Summary:
Adding a new option (argument) for file ingestion `atomic_replace_range` which is intended to support a couple forms of "atomic replacement of a key range":
* (Experimental implementation here) With snapshot_consistency=false, the feature acts like an atomic DeleteFilesInRange prior to the ingestion, though requires no existing files to partially overlap the range. (Consider using SstPartitioner.) This is especially useful for "always compacted" workloads, perhaps along with CF option `disallow_memtable_writes` and ingestion option `fail_if_not_bottommost_level`. If both bounds are nullptr, the whole CF is replaced.
* (To implement in follow-up) With snapshot_consistency=true (and perhaps in some fallback cases from above such as partial overlap), a "giant tombstone file" as in https://github.com/facebook/rocksdb/issues/13078 is generated and ingested at the beginning of the list.
Because I see this as a more elaborate DeleteRange, I would naturally expect the upper bound/limit key to be exclusive, but it has been challenging getting that to work. The inclusive/exclusive handling is currently a documented bug for the experimental feature to sort out in follow-up work. (I would love to take advantage of proposed SliceBound, but that would be ambitious to adapt to DeleteRange. Even getting the "replace whole CF" variant of the functionality might be difficult to get worthing with DeleteRange underneath. Nevertheless, I feel it's best to consolidate these two forms of "atomic replacement" under variants of the same API.)
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13453
Test Plan:
Unit tests added / updated.
db_stress integration left as follow-up work (experimental feature, will be challenging)
Reviewed By: anand1976
Differential Revision: D71584295
Pulled By: pdillinger
fbshipit-source-id: 307abff426e4b7d0a340008918ebcddc896ef747
Summary:
This PR is a followup to https://github.com/facebook/rocksdb/pull/13461. We're introducing an experimental option / killswitch to control SST write lifetime hint calculation based on the selected compaction style. By default (and mostly for backwards compatibility reasons), we'll calculate the SST hints only for level compactions. With this change users have an option to configure SST lifetime hint policy in their environments to enable the calculations in the universal compaction mode as well. It's important to underline that as currently implemented, SST write lifetime hints are calculated in a static way and solely based on the level, which might not be suitable for non-uniform workloads with dynamic / high-variance lifespan of data within the same level. In those cases (or when the performance is not satisfactory), it's recommended to disable the hints by setting the set to empty. Please see the comment in `options.h` for more.
**NOTE:** We deliberately decided to introduce a new option to ensure no impact to external users running their RocksDB instances on local flash with the default `PosixWritableFile` file implementation.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13472
Reviewed By: pdillinger, anand1976
Differential Revision: D71445488
Pulled By: mszeszko-meta
fbshipit-source-id: 57dc5e56662fa0b0fd686e183c0ec7090ff12d66
Summary:
## Issue
Thanks to PRs https://github.com/facebook/rocksdb/issues/13455 and https://github.com/facebook/rocksdb/issues/13464 , we were able to find another issue with compaction stats.
When there are multiple sub-compactions and they are processed remotely, some compaction stats are not collected correctly.
Here's an example of how `num_input_records` can be double-counted during a compaction with multiple sub-compactions executed remotely. Please note that this problem is not limited to `num_input_records`.
Input File: 1 SST file with 100 keys.
- Key 1~50 are in one sub compaction
- Key 51~100 in another sub compaction
`UpdateOutputLevelCompactionStats()` currently retrieves the total number of entries from the input files and sets `num_input_records` in the internal_stats to 100. In `CompactionJob::Run()`, this method is called once after all sub-compactions have finished. However, during remote compaction, `UpdateOutputLevelCompactionStats()` is called for each offloaded sub-compaction on the remote side and then aggregated on the primary host. The internal_stats for the first sub-compaction will have 100 `num_input_records`, and the second sub-compaction will have another 100 `num_input_records`. We end up having 200 `num_input_records` in the aggregated internal_stats.
There was another issue that `num_input_record` was not properly excluding `num_input_range_del` in `UpdateCompactionJobStats()`. `job_stats_->num_input_record` originally has correct value set by compaction iterator, but then later overwritten in `UpdateCompactionJobStats()`. `UpdateCompactionJobStats()` was called during `CompactionJob::Install()`, so not caught by `VerifyInputRecordCount()`.
## Refactor and other changes before the fixes
* Renamed `UpdateOutputLevelCompactionStats()` to `BuildStatsFromInputTableProperties()` to make the function more descriptive. `BuildStatsFromInputTableProperties()` builds input stats by scanning through entries from TableProperties in the Input Files and it's at the top compaction level, not at the sub-compaction level. (It also updates a couple of non-input stats, `bytes_read_blob` and `num_dropped_records`, but will be refactored in a later PR.)
* `UpdateCompactionJobStats()` was moved from `CompactionJob::Install()` to `CompactionJob::Run()` and separated into `UpdateCompactionJobInputStats()` and `UpdateCompactionJobOutputStats()`.
## Fixes
* Remote Compaction no longer updates the subcompaction-job-level input stats from InputTableProperties to avoid double-counted stats in case of multiple sub-compactions. Subcompaction-job-level input stats are aggregated to the compaction-job-level input stats in the primary host after all sub-compactions are finished.
* Remote Compaction now only calls `UpdateCompactionJobOutputStats()` to update the job-level output stats by copying from internal stats.
* `UpdateCompactionJobInputStats()` now takes `num_input_range_del` and properly subtracts it from the input record count. `VerifyInputRecordCount()` expected `job_stats.num_input_records` to be equal to `internal_stats_.output_level_stats.num_input_records - num_input_range_del`. However, when updating the job-level stats, we were taking the entire `internal_stats_.output_level_stats.num_input_records` after verification.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13470
Test Plan:
Local Compaction
```
./db_compaction_test -- --gtest_filter="*DBCompactionTest.VerifyRecordCount*"
```
Remote Compaction
```
./compaction_service_test --gtest_filter="*CompactionServiceTest.VerifyInputRecordCount*"
```
Reviewed By: pdillinger
Differential Revision: D71566149
Pulled By: jaykorean
fbshipit-source-id: c8aafcde701dec8901fd5e5a9ec186e26b896c19
Summary:
Continuing cbi42 's work in 602cc0f9a4be89020fb870dba2816f11dd515d16.
In this PR, we are adding record count verification for each compaction by comparing number of entries summed from Table Properties with the number of output records from the compaction stats.
If the count does not match, `Status::Corruption(msg)` is returned with detailed message including the actual number (from table property) and the expected number (from compaction stats)
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13455
Test Plan:
New UT added
```
./db_compaction_test -- --gtest_filter="*Verify*"
```
The check had to be disabled for some of the existing tests using MockTable/MockTableFactory, because TableProperties aren't populated properly for the MockTables.
Reviewed By: hx235
Differential Revision: D71235790
Pulled By: jaykorean
fbshipit-source-id: 3a86a878d13e79d948409d6a9843d1c992d2c98e
Summary:
## Background
Compaction statistics are collected at various levels across different classes and structs.
* `InternalStats::CompactionStats`: Per-level Compaction Stats within a job (can be at subcompaction level which later get aggregated to the compaction level)
* `InternalStats::CompactionStatsFull`: Contains two per-level compaction stats - `output_level_stats` for primary output level stats and `proximal_level_stats` for proximal level stats. Proximal level statistics are only relevant when using Tiered Storage with the per-key placement feature enabled.
* `InternalStats::CompactionOutputsStats`: Simplified version of `InternalStats::CompactionStats`. Only has a subset of fields from `InternalStats::CompactionStats`
* `CompactionJobStats`: Job-level Compaction Stats. (can be at subcompaction level which later get aggregated to the compaction level)
Please note that some fields in Job-level stats are not in Per-level stats and they don't map 1-to-1 today.
## Issues
* In non-remote compactions, proximal level compaction statistics were not being aggregated into job-level statistics. Job level statistics were missing stats for proximal level for tiered storage compactions with per-key-replacement feature enabled.
* During remote compactions, proximal level compaction statistics were pre-aggregated into job-level statistics on the remote side. However, per-level compaction statistics were not part of the serialized compaction result, so that primary host lost that information and weren't able to populate `per_key_placement_comp_stats_` and `internal_stats_.proximal_level_stats` properly during the installation.
* `TieredCompactionTest` was only checking if (expected stats > 0 && actual stats > 0) instead actual value comparison
## Fixes
* Renamed `compaction_stats_` to `internal_stats_` for `InternalStats::CompactionStatsFull` in `CompactionJob` for better readability
* Removed the usage of `InternalStats::CompactionOutputsStats` and consolidated them to `InternalStats::CompactionStats`.
* Remote Compactions now include the internal stats in the serialized `CompactionServiceResult`. `output_level_stats` and `proximal_level_stats` get later propagated in sub_compact output stats accordingly.
* `CompactionJob::UpdateCompactionJobStats()` now takes `CompactionStatsFull` and aggregates the `proximal_level_stats` as well
* `TieredCompactionTest` is now doing the actual value comparisons for input/output file counts and record counts. Follow up is needed to do the same for the bytes read / written.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13464
Test Plan:
Unit Tests updated to verify stats
```
./compaction_service_test
```
```
./tiered_compaction_test
```
Reviewed By: pdillinger
Differential Revision: D71220393
Pulled By: jaykorean
fbshipit-source-id: ad70bffd9614ced683f90c7570a17def9b5c8f3f
Summary:
This PR adds a check for an invariant of sequence number during recovery, that it should not be set backward. This is inspired by a recent SEV that is caused by a software bug. It is a relatively cheap and straightforward check that RocksDB can do to avoid silently opening the DB in a corrupted state.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13465
Test Plan:
Existing tests should cover the case when the invariant is met
The corrupted state is manually tested using aforementioned bug.
Reviewed By: hx235
Differential Revision: D71226513
Pulled By: jowlyzhang
fbshipit-source-id: cd8056fa6653d44ceeb9ba9b4693ab0660a53b4e
Summary:
**Context/Summary:**
For users who are interested in knowing how efficient their compaction in reducing L0 files or how bad their long-running compaction in "locking" L0 files, they now have a reference point "L0 files in the CF pre compaction" for their input compaction files.
- Compared to the existing stats or exposing in some other way, exposing this info in CompactionJobInfo allows users to compare it with other compaction data (e.g, compaction input num, compaction reason) of within **one** compaction (of per-compaction granularity).
- If this number is high while their "short-running" compaction has little L0 files input, then those compaction may have a room for improvement. Similar for those long-running compaction. This PR is to add a new field `CompactionJobInfo::num_l0_files_pre_compaction` for that.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13462
Test Plan: - Piggyback on an existing test
Reviewed By: jaykorean
Differential Revision: D71124938
Pulled By: hx235
fbshipit-source-id: aa47c9c86c62d9425771b320f5636e50671fd289
Summary:
The original implementation of NVMe write lifetime hints (https://github.com/facebook/rocksdb/pull/3095) assumed a flexible interface which decouples file creation from the explicit act of setting write lifetime hint (see `PosixWritableFile` for more context). However, there are existing file systems implementations (ex. Warm Storage) that require all the options (including file write lifetime hints) to be specified once at the time of the actual `FSWritableFile` object instantiation. We're extending the `FileOptions` with `Env::WriteLifeTimeHint` and patch existing callsites accordingly to enable one-shot metadata setup for those more constraint implementations.
NOTE: Today `CalculateSSTWriteHint` only sets write lifetime hint for Level compactions. We'll fill that gap in following PRs and add calculation for Universal Compactions which would unblock Zippy's use case.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13461
Reviewed By: anand1976
Differential Revision: D71144645
Pulled By: mszeszko-meta
fbshipit-source-id: 6c09b62a360d48bd6e4fb08a1265bce2a49f3f4a
Summary:
In hopes of eventually removing some ugly and awkard code for compress_format_version < 2, users can no longer write files in that format and its read support is marked deprecated. For continuing to test that read support, there is a back door to writing the files in unit tests.
If format_version < 2 is specified, it is quietly sanitized to 2. (This is similar to other BlockBasedTableOptions.)
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13463
Test Plan: unit tests updated.
Reviewed By: hx235
Differential Revision: D71152916
Pulled By: pdillinger
fbshipit-source-id: 95be55e86f93f09fd898223578b9381385c3ccd8
Summary:
With generalized age-based tiering (work-in-progress), the "warm tier" data will no longer necessarily be placed in the second-to-last level (also known as the "penultimate level").
Also, the cold tier may no longer necessarily be at the last level, so we need to rename options like `preclude_last_level_seconds` to `preclude_cold_tier_seconds`, but renaming options is trickier because it can be a breaking change for consuming applications. We will do this later as a follow up.
**Minor fix included**: Fixed one `use-after-move` in CompactionPicker
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13460
Test Plan: CI
Reviewed By: pdillinger
Differential Revision: D71059486
Pulled By: jaykorean
fbshipit-source-id: fd360cdf719e015bf9f9e3f6f1663438226566a4
Summary:
This PR adds support for PerKeyPlacement in Remote Compaction.
The `seqno_to_time_mapping` is already available from the table properties of the input files. `preserve_internal_time_seconds` and `preclude_last_level_data_seconds` are directly read from the OPTIONS file upon db open in the remote worker. The necessary changes include:
- Add `is_penultimate_level_output` and `file_temperature` to the `CompactionServiceOutputFile`
- When building the output for the remote compaction, get the outputs for penultimate level and last level separately, serialize them with the two additional information added in this PR.
- When deserializing the result from the primary, SubcompactionState's `GetOutputs()` now takes `is_penultimate_level`. This allows us to determine which level to place the output file.
- Include stats from `compaction_stats.penultimate_level_stats` in the remote compaction result
# To Follow up
- Stats to be fixed. Stats are not being populated correctly for PerKeyPlacement even for non-remote compactions.
- Clean up / Reconcile the "penultimate" naming by replacing with "proximal"
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13459
Test Plan:
Updated the unit test
```
./compaction_service_test
```
Reviewed By: pdillinger
Differential Revision: D71007211
Pulled By: jaykorean
fbshipit-source-id: f926e56df17239875d849d46b8b940f8cd5f1825
Summary:
[Experiment]
This PR is a followup to https://github.com/facebook/rocksdb/pull/13408. Thick bandaid of ignoring all injected read errors in context of periodic iterator auto refreshes in db stress proved to be effective. We confirmed our theory that errors are not a really a consequence / defect related to this new feature but rather due to subtle ways in which downstream code paths handle their respective IO failures. In this change we're replacing a thick 'ignore all IO read errors' bandaid in `no_batched_ops_stress` with a much smaller, targeted patches in obsolete files purge / delete codepaths, table block cache reader, table cache lookup to make sure we don't miss signal and ensure there's a single mechanism for ignoring error injection in db stress tests.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13447
Reviewed By: hx235
Differential Revision: D70794787
Pulled By: mszeszko-meta
fbshipit-source-id: c5fcd4780d82357c407f53bf0bb22fc38f7bd277
Summary:
Add debug logging when the Wait() does not return `kSuccess` so that we can compare the version state that was printed by the logging added in https://github.com/facebook/rocksdb/issues/13427 upon InputFileCheck failure.
# Test Plan
CI + Tested with Temporary Change in Meta Internal Infra
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13452
Reviewed By: hx235
Differential Revision: D70898963
Pulled By: jaykorean
fbshipit-source-id: d591b82f2df173b5e01f6552230844ce95155256
Summary:
`nullptr` is preferable to `0` or `NULL`. Let's use it everywhere so we can enable `-Wzero-as-null-pointer-constant`.
- If you approve of this diff, please use the "Accept & Ship" button :-)
Reviewed By: dtolnay
Differential Revision: D70818166
fbshipit-source-id: 4658fb004676fe2686249fdd8ecb322dec8aa63d
Summary:
Primarily, fix an issue from https://github.com/facebook/rocksdb/issues/13316 with opening secondary DB with preserve/preclude option (crash test disable in https://github.com/facebook/rocksdb/issues/13439). The issue comes down to mixed-up interpretations of "read_only" which should now be resolved. I've introduced the stronger notion of "unchanging" which means the VersionSet never sees any changes to the LSM tree, and the weaker notion of "read_only" which means LSM tree changes are not written through this VersionSet/etc. but can pick up externally written changes. In particular, ManifestTailer should use read_only=true (along with unchanging=false) for proper handling of preserve/preclude options.
A new assertion in VersionSet::CreateColumnFamily to help ensure sane usage of the two boolean flags is incompatible with the known wart of allowing CreateColumnFamily on a read-only DB. So to keep that assertion, I have fixed that issue by disallowing it. And this in turn required downstream clean-up in ldb, where I cleaned up some call sites as well.
Also, rename SanitizeOptions for ColumnFamilyOptions to SanitizeCfOptions, for ease of search etc.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13441
Test Plan:
* Added preserve option to a test in db_secondary_test, which reproduced the failure seen in the crash test.
* Revert https://github.com/facebook/rocksdb/issues/13439 to re-enable crash test functionality
* Update some tests to deal with disallowing CF creation on read-only DB
* Add some testing around read-only DBs and CreateColumnFamily(ies)
* Resurrect a nearby test for read-only DB to be sure it doesn't write to the DB dir. New EnforcedReadOnlyReopen should probably be used in more places but didn't want to attempt a big migration here and now. (Suggested follow-up.)
Reviewed By: jowlyzhang
Differential Revision: D70808033
Pulled By: pdillinger
fbshipit-source-id: 486b4e9f9c9045150a0ebb9cb302753d03932a3f
Summary:
In case the primary host has a new option added which isn't available in the remote worker yet, the remote compaction currently fails. In most cases, these new options are not relevant to the remote compaction and the worker should be able to move on by ignoring it.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13443
Test Plan: Verified internally in Meta Infra.
Reviewed By: anand1976
Differential Revision: D70744359
Pulled By: jaykorean
fbshipit-source-id: eb6a388c2358a7f8089f2e35a378b7017b9e03f3
Summary:
If compaction job needs to be aborted inside `Schedule()` or `Wait()` today (e.g. Primary host is shutting down), the only two options are the following
- Handle it as failure by returning `CompactionServiceJobStatus::kFailure`
- Return `CompactionServiceJobStatus::kUseLocal` and let the compaction move on locally and eventually succeed or fail depending on the timing
In this PR, we are introducing a new status, `CompactionServiceJobStatus::kAborted`, so that the implementation of `Schedule()` and `Wait()` can return it. Just like how `CompactionServiceJobStatus::kFailure` is handled, compaction will not move on and fail, but the status will be returned as `Status::Aborted()` instead of `Status::Incomplete()`
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13438
Test Plan:
Unit Test added
```
./compaction_service_test --gtest_filter="*CompactionServiceTest.AbortedWhileWait*"
```
Reviewed By: anand1976, hx235
Differential Revision: D70655355
Pulled By: jaykorean
fbshipit-source-id: 22614ce9c7455cda649b15465625edc93978fe11
Summary:
I have a place I want to use this helper method inside the Sally codebase. I have this functionality in my Sally diff right now, but I think it is generic enough to warrant putting alongside `Env::PriorityToString`.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13440
Test Plan: Just the compiler and CI checks are sufficient IMO.
Reviewed By: hx235
Differential Revision: D70664597
Pulled By: archang19
fbshipit-source-id: 341de6c6e311a3f421ad093c2c216e5caa5034dd
Summary:
This PR adds the ability to use an ExternalTableBuilder through the SstFileWriter to create external tables. This is a counterpart to https://github.com/facebook/rocksdb/issues/13401 , which adds the ExternalTableReader. The support for external tables is confined to ingestion only DBs, with external table files ingested into the bottommost level only. https://github.com/facebook/rocksdb/issues/13431 enforces ingestion only DBs by adding a disallow_memtable_writes column family option.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13434
Test Plan: New unit tests in table_test.cc
Reviewed By: pdillinger
Differential Revision: D70532054
Pulled By: anand1976
fbshipit-source-id: a837487eadfabed9627a0eceb403bfc5fc2c427c
Summary:
Add an unordered_map of name/value pairs in ReadOptions::property_bag, similar to IOOptions::property_bag. It allows users to pass through some custom options to an external table.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13436
Reviewed By: jaykorean
Differential Revision: D70649609
Pulled By: anand1976
fbshipit-source-id: 9b14806a9f3599b861827bd4ae6e948861edc51a
Summary:
PR https://github.com/facebook/rocksdb/issues/13316 broke some crash test cases in DBImplSecondary, from combining test_secondary=1 and preserve_internal_time_seconds>0. Disabling that while investigating the fix.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13439
Test Plan: manual blackbox_crash_test runs with forced test_secondary=1
Reviewed By: anand1976
Differential Revision: D70656373
Pulled By: pdillinger
fbshipit-source-id: fa2139e90bbe64ec8ebb062877d9337894ea3b43
Summary:
... to better support "ingestion only" column families such as those using an external file reader as in https://github.com/facebook/rocksdb/issues/13401.
It would be possible to implement this by getting rid of the memtable for that CF, but it quickly because clear that such an approach would need to update a lot of places to deal with such a possibility. And we already have logic to optimize reads when a memtable is empty. We put a vector memtable in place to minimize overheads of an empty memtable.
There are three layers of defense against writes to the memtable:
* WriteBatch ops to a disallowed CF will fail immediately, without waiting for Write(). For this check to work, we need a ColumnFamilyHandle and because of that, we don't support disallow_memtable_writes on the default column family.
* MemtableInserter will reject writes to disallowed CFs. This is needed to protect re-open with disallow when there are existing writes in a WAL.
* The placeholder memtable is marked immutable. This will cause an assertion failure on attempt to write, such as in case of bug or regression.
Suggested follow-up:
* Remove the limitation on using the option with the default column family, perhaps by solving https://github.com/facebook/rocksdb/issues/13429 more generally or perhaps with some specific check before the first memtable write of the batch (but potential CPU overhead for such a check - there's likely optimization opportunities around ColumnFamilyMemTables).
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13431
Test Plan:
unit tests added
Performance: A db_bench call designed to realistically focus on the CPU cost of writes:
```
./db_bench -db=/dev/shm/dbbench1 --benchmarks=fillrandom -num=10000000 -compaction_style=2 -fifo_compaction_max_table_files_size_mb=1000 -fifo_compaction_allow_compaction=0 -num_column_families=20 -disable_wal -write_buffer_size=1234000
```
Running before & after tests at the same time on the same machine, 40 iterations each, average ops/s, DEBUG_LEVEL=0, remove slowest run of each:
Before: 772466
After: 773785 (0.2% faster)
Likely within the noise, as if there was any change, we would expect a slight regression.
Reviewed By: anand1976
Differential Revision: D70495936
Pulled By: pdillinger
fbshipit-source-id: 306f7e737f87c1fbb52c5805f3cadb6e8ced9b40
Summary:
This is an unexpectedly complex follow-up to https://github.com/facebook/rocksdb/issues/13269.
This change solves (and detects regressed) inconsistencies between whether a CF's SuperVersion is configured with a preserve/preclude option and whether it gets a usable SeqnoToTimeMapping. Operating with preserve/preclude and no usable mapping is degraded functionality we need to avoid. And no mapping is useful for actually disabling the feature (except with respect to existing SST files, but that's less of a concern for now).
The challenge is that how we maintain the DB's SeqnoToTimeMapping can depend on all the column families, and we don't want to iterate over all column families *for each column family* (e.g. on initially creating each). The existing code was a bit relaxed:
* On initially creating or re-configuring a CF, we might install an empty mapping, but soon thereafter (after releasing and re-acquiring the DB mutex) re-install another SuperVersion with a useful mapping.
The solution here is to refactor the logic so that there's a distinct but related workflow for (a) ensuring a quality set of mappings when we might only be considering a single CF (`EnsureSeqnoToTimeMapping()`), and (b) massaging that set of mappings to account for all CFs (`RegisterRecordSeqnoTimeWorker`) which doesn't need to re-install new SuperVersions because each CF already has good mappings and will get updated SuperVersions when the periodic task adds new mappings. This should eliminate the extra SuperVersion installs associated with preserve/preclude on CF creation or re-configure, making it the same as any other CF.
Some more details:
* Some refactorings such as removing new_seqno_to_time_mapping from SuperVersionContext. (Now use parameter instead of being stateful.)
* Propagate `read_only` aspect of DB to more places so that we can pro-actively disable preserve/preclude on read-only DBs, so that we don't run afoul of the assertion expecting SeqnoToTime entries.
* Introduce a utility struct `MinAndMaxPreserveSeconds` for aggregating preserve/preclude settings in a useful way, sometimes on one CF and sometimes across multiple CFs. Much cleaner! (IMHO)
* Introduce a function `InstallSuperVersionForConfigChange` that is a superset of `InstallSuperVersionAndScheduleWork` for when a CF is new or might have had a change to its mutable options.
* Eliminate redundant re-install SuperVersions of created "missing" CFs in DBImpl::Open.
Intended follow-up:
* Ensure each flush has an "upper bound" SeqnoToTime entry, which would resolve a FIXME in tiered_compaction_test, but causes enough test churn to deserve its own PR + investigation.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13316
Test Plan:
This change is primarily validated by a new assertion in SuperVersion::Init to ensure consistency between (a) presence of any SeqnoToTime mappings in the SuperVersion and (b) preserve/preclude option being currently set.
One unit test update was needed because we now ensure at least one SeqnoToTime entry is created on any DB::Open with preserve/preclude, so that there is a lower bound time on all the future data writes. This required a small hack in associating the time with Seqno 1 instead of 0, which is reserved for "unspecified old."
Reviewed By: cbi42
Differential Revision: D70540638
Pulled By: pdillinger
fbshipit-source-id: bb419fdbeb5a1f115fc429c211f9b8efaf2f56d7
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13435
We've noticed the default CRC32c function gets executed when running on aarch64 cpus within our servers
Issue is that ROCKSDB_AUXV_GETAUXVAL_PRESENT evaluates to false
This fix enables the flag internally and reverts the previous fix, landed with D70423483
Reviewed By: pdillinger
Differential Revision: D70584250
fbshipit-source-id: 28e41316187c474fdfaf854f301ad14b6721fcad
Summary:
when reading with ReadOptions::read_tier = kPersistedTier and with a snapshot, MultiGet allows the case where some CF is read before a flush and some CF is read after the flush. This is not desirable, especially when atomic_flush is enabled and users use MultiGet to do some consistency checks on the data in SST files. This PR updates the code path for SuperVersion acquisition to get a consistent view across when kPersistedTier is used.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13433
Test Plan: a new unit test that could be flaky without this change.
Reviewed By: jaykorean
Differential Revision: D70509688
Pulled By: cbi42
fbshipit-source-id: 80de96f94407af9bb2062b6a185c61f65827c092
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13432
We've noticed the default CRC32c function gets executed when running on aarch64 cpus within our servers
Issue is that ROCKSDB_AUXV_GETAUXVAL_PRESENT evaluates to false
This fix allows the usage of hardware-accelerated crc32 within our fleet
Reviewed By: jaykorean
Differential Revision: D70423483
fbshipit-source-id: 601da3fbf156e3e40695eb76ee5d37f67f83d427
Summary:
This adds a test that attempts DeleteRange() with PlainTable (not supported) and shows that it not only puts the DB in failed write mode, it (a) breaks WriteBatch atomicity for readers, because they can see just part of a failed WriteBatch, and (b) makes the DB not recoverable (without manual intervention) if using WAL.
Note: WriteBatch atomicity is not clearly documented but indicated at the top of write_batch.h and the wiki page for Transactions, even without Transactions.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13428
Test Plan: this is the test
Reviewed By: anand1976
Differential Revision: D70332226
Pulled By: pdillinger
fbshipit-source-id: 67bc4de68833a80578e48baa9d3a4f23f1600f3c
Summary:
The existing format compatibility test had limited coverage of compression options, particularly newer algorithms with and without dictionary compression. There are some subtleties that need to remain consistent, such as index blocks potentially being compressed but *not* using the file's dictionary if they are. This involves detecting (with a rough approximation) builds with the appropriate capabilities.
The other motivation for this change is testing some potentially useful reader-side functionality that has been in place for a long time but has not been exercised until now: mixing compressions in a single SST file. The block-based SST schema puts a compression marker on each block; arguably this is for distinguishing blocks compressed using the algorithm stored in compression_name table property from blocks left uncompressed, e.g. because they did not reach the threshold of useful compression ratio, but the marker can also distinguish compression algorithms / decompressors.
As we work toward customizable compression, it seems worth unlocking the capability to leverage the existing schema and SST reader-side support for mixing compression algorithms among the blocks of a file. Yes, a custom compression could implement its own dynamic algorithm chooser with its own tag on the compressed data (e.g. first byte), but that is slightly less storage efficient and doesn't support "vanilla" RocksDB builds reading files using a mix of built-in algorithms. As a hypothetical example, we might want to switch to lz4 on a machine that is under heavy CPU load and back to zstd when load is more normal. I dug up some data indicating ~30 seconds per output file in compaction, suggesting that file-level responsiveness might be too slow. This agility is perhaps more useful with disaggregated storage, where there is more flexibility in DB storage footprint and potentially more payoff in optimizing the *average* footprint.
In support of this direction, I have added a backdoor capability for debug builds of `ldb` to generate files with a mix of compression algorithms and incorporated this into the format compatibility test. All of the existing "forward compatible" versions (currently back to 8.6) are able to read the files generated with "mixed" compression. (NOTE: there's no easy way to patch a bunch of old versions to have them support generating mixed compression files, but going forward we can auto-detect builds with this "mixed" capability.) A subtle aspect of this support that is that for proper handling of decompression contexts and digested dictionaries, we need to set the `compression_name` table property to `zstd` if any blocks are zstd compressed. I'm expecting to add better info to SST files in follow-up, but this approach here gives us forward compatibility back to 8.6.
However, in the spirit of opening things up with what makes sense under the existing schema, we only support one compression dictionary per file. It will be used by any/all algorithms that support dictionary compression. This is not outrageous because it seems standard that a dictionary is *or can be* arbitrary data representative of what will be compressed. This means we would need a schema change to add dictionary compression support to an existing built-in compression algorithm (because otherwise old versions and new versions would disagree on whether the data dictionary is needed with that algorithm; this could take the form of a new built-in compression type, e.g. `kSnappyCompressionWithDict`; only snappy, bzip2, and windows-only xpress compression lack dictionary support currently).
Looking ahead to supporting custom compression, exposing a sizeable set of CompressionTypes to the user for custom handling essentially guarantees a path for the user to put *versioning* on their compression even if they neglect that initially, and without resorting to managing a bunch of distinct named entities. (I'm envisioning perhaps 64 or 127 CompressionTypes open to customization, enough for ~weekly new releases with more than a year of horizon on recycling.)
More details:
* Reduce the running time (CI cost) of the default format compatibility test by randomly sampling versions that aren't the oldest in a category. AFAIK, pretty much all regressions can be caught with the even more stripped-down SHORT_TEST.
* Configurable make parallelism with J environment variable
* Generate data files in a way that makes them much more eligible for index compression, e.g. bigger keys with less entropy
* Generate enough data files
* Remove 2.7.fb.branch from list because it shows an assertion violation when involving compression.
* Randomly choose a contiguous subset of the compression algorithms X {dictionary, no dictionary} configuration space when generating files, with a number of files > number of algorithms. This covers all the algorithms and both dictionary/no dictionary for each release (but not in all combinations).
* Have `ldb` fail if the specified compression type is not supported by the build.
Other future work needed:
* Blob files in format compatibility test, and support for mixed compression. NOTE: the blob file schema should naturally support mixing compression algorithms but the reader code does not because of an assertion that the block CompressionType (if not no compression) matches the whole file CompressionType. We might introduce a "various" CompressionType for this whole file marker in blob files.
* Do more to ensure certain features and code paths e.g. in the scripts are actually used in the compatibility test, so that they aren't accidentally neutralized.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13414
Test Plan: Manual runs with some temporary instrumentation, also a recent revision of this change included a GitHub Actions run of the updated format compatible test: https://github.com/facebook/rocksdb/actions/runs/13463551149/job/37624205915?pr=13414
Reviewed By: hx235
Differential Revision: D70012056
Pulled By: pdillinger
fbshipit-source-id: 9ea5db76ba01a95338ed1a86b0edd71a469c4061
Summary:
added merge support for WBWIMemTable. Most of the preparation work is done in https://github.com/facebook/rocksdb/issues/13387 and https://github.com/facebook/rocksdb/issues/13400. The main code change to support merge is in wbwi_memtable.cc to support reading the Merge value type. The rest of the changes are mostly comment change and tests.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13410
Test Plan:
- new unit test
- ran `python3 ./tools/db_crashtest.py --txn blackbox --txn_write_policy=0 --commit_bypass_memtable_one_in=100 --test_batches_snapshots=0 --use_merge=1` for several runs.
Reviewed By: jowlyzhang
Differential Revision: D69885868
Pulled By: cbi42
fbshipit-source-id: b127d95a3027dc35910f6e5d65f3409ba27e2b6b
Summary:
... to ensure proper cache charging. However, this is a somewhat hazardous combination if there are many CFs and could be the target of future work.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13398
Test Plan: this is the test
Reviewed By: hx235
Differential Revision: D69619977
Pulled By: pdillinger
fbshipit-source-id: 9841768584e4688d8fdd0258f3ba9608b67408e5
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13411
We should intialize statuses with OK rather than IOError to correctly handle cases
like NotFound due to bloom filter. In case of IOError status would be updated
appropriately by the reader
Reviewed By: anand1976
Differential Revision: D69886976
fbshipit-source-id: 92b130168f23633224ff4153bfe46a7d86482b90
Summary:
This is a preparation for supporting merge in `WBWIMemTable`. This PR updates the sequence number assignment method so that it allows efficient and simple assignment when there are multiple entries with the same user key. This can happen when the WBWI contains Merge operations. This assignment relies on tracking the number of updates issued for each key in each WBWI entry (`WriteBatchIndexEntry::update_count`). Some refactoring is done in WBWI to remove `last_entry_offset` as part of the WBWI state which I find it harder to use correctly.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13400
Test Plan: updated unit tests to check that update count is tracked correctly and WBWIMemTable is assigning sequence number as expected.
Reviewed By: pdillinger
Differential Revision: D69666462
Pulled By: cbi42
fbshipit-source-id: 9b18291825017a67c4da3318e8a556aa2971326b
Summary:
This PR introduces an interface to plug in an external table file reader into RocksDB. The external table reader may support custom file formats that might work better for a specific use case compared to RocksDB native formats. This initial version allows the external table file to be loaded and queried using an `SstFileReader`. In the near future, we will allow it to be used with a limited RocksDB instance that allows bulkload but not live writes.
The model of a DB using an external table reader is a read only database allowing bulkload and atomic replace in the bottommost level only. Live writes, if supported in the future, are expected to use block based table files in higher levels. Tombstones, merge operands, and non-zero sequence numbers are expected to be present only in non-bottommost levels. External table files are assumed to have only Puts, and all keys implicitly have sequence number 0.
TODO (in future PRs) -
1. Add support for external file ingestion, with safety mechanisms to prevent accidental writes
2. Add support for atomic column family replace
3. Allow custom table file extensions
4. Add a TableBuilder interface for use with `SstFileWriter`
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13401
Reviewed By: pdillinger
Differential Revision: D69689351
Pulled By: anand1976
fbshipit-source-id: c5d5b92d56fd4d0fc43a77c4ceb0463d4f479bda
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13403
Add MultiGet support in SstReader. Today we only have iteration support and this change
also adds MultiGet support to SstFileReader if some application wants to use it.
Reviewed By: anand1976
Differential Revision: D69514499
fbshipit-source-id: 20e85a4bd13a3a9f45dacb223c1a4541fb87f561
Summary:
Noticed that the `do_merge` parameter is not properly set while working on memtable code.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13396
Test Plan: updated unit test for the read-only db case.
Reviewed By: jaykorean
Differential Revision: D69505015
Pulled By: cbi42
fbshipit-source-id: d4c64ca7bba31fe26aa41a29cbc55835d9f1f116
Summary:
**Context/Summary:**
https://github.com/facebook/rocksdb/pull/13263 and https://github.com/facebook/rocksdb/pull/13360 disabled `track_and_verify_wals` with some injection under TXN temporarily but recent stress tests has found more issues this feature surfaced even with the previous disabling. Disabling the feature **completely** now for stabilizing CI while debugging.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13405
Test Plan: Monitor CI
Reviewed By: cbi42
Differential Revision: D69759276
Pulled By: hx235
fbshipit-source-id: 501a3561acb9daa834f874095f9a66ae6ae5aa42
Summary:
**Context/Summary:**
It's [documented (https://github.com/facebook/rocksdb/blob/affcad0cc997958e93bc560202ed107c80d00395/db/job_context.h#L230) that `// For non-empty JobContext Clean() has to be called at least once before before destruction`. This is violated in a UT accidentally so causing the assertion failure `assert(logs_to_free.size() == 0);` in` ~JobContext`. This PR is to fix it.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13406
Test Plan: Monitor for future UT assertion failure in `TEST_F(DBWALTest, FullPurgePreservesRecycledLog) `
Reviewed By: cbi42
Differential Revision: D69759725
Pulled By: hx235
fbshipit-source-id: dd1617b370a2c69daba657287dcf258542f92ef5
Summary:
**Context/Summary:**
https://github.com/facebook/rocksdb/commit/02b4197544f758bdf84d80fe9319238611848c48 recently added the ability to detect WAL hole presents in the predecessor WAL. It forgot to update the corrupted wal number to point to the predecessor WAL in that corruption case. This PR fixed it.
As a bonus, this PR also (1) fixed the `FragmentBufferedReader()` constructor API to expose less parameters as they are never explicitly passed in in the codebase (2) a INFO log wording (3) a parameter naming typo (4) the reporter naming
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13359
Test Plan:
1. Manual printing to ensure the corrupted wal number is set to the right number
2. Existing UTs
Reviewed By: jowlyzhang
Differential Revision: D69068089
Pulled By: hx235
fbshipit-source-id: f7f8a887cded2d3a26cf9982f5d1d1ab6a78e9e1
Summary:
**Context/Summary:**
Secondary DB relies on open file descriptor of the shared SST file in primary DB to continue being able to read the file even if that file is deleted in the primary DB. However, this won't work if the file is truncated instead of deleted, which triggers an "truncated block read" corruption in stress test on secondary db reads. Truncation can happen if RocksDB implementation of SSTFileManager and `bytes_max_delete_chunk>0` are used. This PR is to disable such testing combination in stress test and clarify the related API.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13395
Test Plan:
- Manually repro-ed with below UT. I'm in favor of not including this UT in the codebase as it should be self-evident from the API comment now about the incompatiblity. Secondary DB is in a direction of being replaced by Follower so we should minimize edge-case tests for code with no functional change for a to-be-replaced functionality.
```
TEST_F(DBSecondaryTest, IncompatibleWithPrimarySSTTruncation) {
Options options;
options.env = env_;
options.disable_auto_compactions = true;
options.sst_file_manager.reset(NewSstFileManager(
env_, nullptr /*fs*/, "" /*trash_dir*/, 2024000 /*rate_bytes_per_sec*/,
true /*delete_existing_trash*/, nullptr /*status*/,
0.25 /*max_trash_db_ratio*/, 1129 /*bytes_max_delete_chunk*/));
Reopen(options);
ASSERT_OK(Put("key1", "old_value"));
ASSERT_OK(Put("key2", "old_value"));
ASSERT_OK(Flush());
ASSERT_OK(Put("key1", "new_value"));
ASSERT_OK(Put("key3", "new_value"));
ASSERT_OK(Flush());
Options options1;
options1.env = env_;
options1.max_open_files = -1;
Reopen(options);
OpenSecondary(options1);
ASSERT_OK(db_secondary_->TryCatchUpWithPrimary());
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
"DeleteScheduler::DeleteTrashFile:Fsync", [&](void*) {
std::string value;
Status s = db_secondary_->Get(ReadOptions(), "key2", &value);
assert(s.IsCorruption());
assert(s.ToString().find("truncated block read") !=
std::string::npos);
});
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing();
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->ClearAllCallBacks();
}
```
- Monitor future stress test
Reviewed By: jowlyzhang
Differential Revision: D69499694
Pulled By: hx235
fbshipit-source-id: 57525b9841897f42aecb758a4d3dd3589367dcd9
Summary:
# Problem
Once opened, iterator will preserve its' respective RocksDB snapshot for read consistency. Unless explicitly `Refresh'ed`, the iterator will hold on to the `Init`-time assigned `SuperVersion` throughout its lifetime. As time goes by, this might result in artificially long holdup of the obsolete memtables (_potentially_ referenced by that superversion alone) consequently limiting the supply of the reclaimable memory on the DB instance. This behavior proved to be especially problematic in case of _logical_ backups (outside of RocksDB `BackupEngine`).
# Solution
Building on top of the `Refresh(const Snapshot* snapshot)` API introduced in https://github.com/facebook/rocksdb/pull/10594, we're adding a new `ReadOptions` opt-in knob that (when enabled) will instruct the iterator to automatically refresh itself to the latest superversion - all that while retaining the originally assigned, explicit snapshot (supplied in `read_options.snapshot` at the time of iterator creation) for consistency. To ensure minimal performance overhead we're leveraging relaxed atomic for superversion freshness lookups.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13354
Test Plan:
**Correctness:** New test to demonstrate the auto refresh behavior in contrast to legacy iterator: `./db_iterator_test --gtest_filter=*AutoRefreshIterator*`.
**Stress testing:** We're adding command line parameter controlling the feature and hooking it up to as many iterator use cases in `db_stress` as we reasonably can with random feature on/off configuration in db_crashtest.py.
# Benchmarking
The goal of this benchmark is to validate that throughput did not regress substantially. Benchmark was run on optimized build, 3-5 times for each respective category or till convergence. In addition, we configured aggressive threshold of 1 second for new `Superversion` creation. Experiments have been run 'in parallel' (at the same time) on separate db instances within a single host to evenly spread the potential adverse impact of noisy neighbor activities. Host specs [1].
**TLDR;** Baseline & new solution are practically indistinguishable from performance standpoint. Difference (positive or negative) in throughput relative to the baseline, if any, is no more than 1-2%.
**Snapshot initialization approach:**
This feature is only effective on iterators with well-defined `snapshot` passed via `ReadOptions` config. We modified the existing `db_bench` program to reflect that constraint. However, it quickly turned out that the actual `Snapshot*` initialization is quite expensive. Especially in case of 'tiny scans' (100 rows) contributing as much as 25-35 microseconds, which is ~20-30% of the average per/op latency unintentionally masking _potentially_ adverse performance impact of this change. As a result, we ended up creating a single, explicit 'global' `Snapshot*` for all the future scans _before_ running multiple experiments en masse. This is also a valuable data point for us to keep in mind in case of any future discussions about taking implicit snapshots - now we know what the lower bound cost could be.
## "DB in memory" benchmark
**DB Setup**
1. Allow a single memtable to grow large enough (~572MB) to fit in all the rows. Upon shutdown all the rows will be flushed to the WAL file (inspected `000004.log` file is 541MB in size).
```
./db_bench -db=/tmp/testdb_in_mem -benchmarks="fillseq" -key_size=32 -value_size=512 -num=1000000 -write_buffer_size=600000000 max_write_buffer_number=2 -compression_type=none
```
2. As a part of recovery in subsequent DB open, WAL will be processed to one or more SST files during the recovery. We're selecting a large block cache (`cache_size` parameter in `db_bench` script) suitable for holding the entire DB to test the “hot path” CPU overhead.
```
./db_bench -use_existing_db=true -db=/tmp/testdb_in_mem -statistics=false -cache_index_and_filter_blocks=true -benchmarks=seekrandom -preserve_internal_time_seconds=1 max_write_buffer_number=2 -explicit_snapshot=1 -use_direct_reads=1 -async_io=1 -num=? -seek_nexts=? -cache_size=? -write_buffer_size=? -auto_refresh_iterator_with_snapshot={0|1}
```
| seek_nexts=100; num=2,000,000 | seek_nexts = 20,000; num=50000 | seek_nexts = 400,000; num=2000
-- | -- | -- | --
baseline | 36362 (± 300) ops/sec, 928.8 (± 23) MB/s, 99.11% block cache hit | 52.5 (± 0.5) ops/sec, 1402.05 (± 11.85) MB/s, 99.99% block cache hit | 156.2 (± 6.3) ms / op, 1330.45 (± 54) MB/s, 99.95% block cache hit
auto refresh | 35775.5 (± 537) ops/sec, 926.65 (± 13.75) MB/s, 99.11% block cache hit | 53.5 (± 0.5) ops/sec, 1367.9 (± 9.5) MB/s, 99.99% block cache hit | 162 (± 4.14) ms / op, 1281.35 (± 32.75) MB/s, 99.95% block cache hit
_-cache_size=5000000000 -write_buffer_size=3200000000 -max_write_buffer_number=2_
| seek_nexts=3,500,000; num=100
-- | --
baseline | 1447.5 (± 34.5) ms / op, 1255.1 (± 30) MB/s, 98.98% block cache hit
auto refresh | 1473.5 (± 26.5) ms / op, 1232.6 (± 22.2) MB/s, 98.98% block cache hit
_-cache_size=17680000000 -write_buffer_size=14500000000 -max_write_buffer_number=2_
| seek_nexts=17,500,000; num=10
-- | --
baseline | 9.11 (± 0.185) s/op, 997 (± 20) MB/s
auto refresh | 9.22 (± 0.1) s/op, 984 (± 11.4) MB/s
[1]
### Specs
| Property | Value
-- | --
RocksDB | version 10.0.0
Date | Mon Feb 3 23:21:03 2025
CPU | 32 * Intel Xeon Processor (Skylake)
CPUCache | 16384 KB
Keys | 16 bytes each (+ 0 bytes user-defined timestamp)
Values | 100 bytes each (50 bytes after compression)
Prefix | 0 bytes
RawSize | 5.5 MB (estimated)
FileSize | 3.1 MB (estimated)
Compression | Snappy
Compression sampling rate | 0
Memtablerep | SkipListFactory
Perf Level | 1
Reviewed By: pdillinger
Differential Revision: D69122091
Pulled By: mszeszko-meta
fbshipit-source-id: 147ef7c4fe9507b6fb77f6de03415bf3bec337a8
Summary:
Options File Number to be read by remote worker is part of the `CompactionServiceInput`. We've been setting this in `ProcessKeyValueCompactionWithCompactionService()` while the db_mutex is not held. This needs to be accessed while the mutex is held. The value can change as part of `SetOptions() -> RenameTempFileToOptionsFile()` as in following.
https://github.com/facebook/rocksdb/blob/e6972196bca115e841a6b88d361ba945b49e1e5d/db/db_impl/db_impl.cc#L5595-L5596
Keep this value in memory during `CompactionJob::Prepare()` which is called while the mutex is held, so that we can easily access this later without mutex when building the CompactionInput for the remote compaction.
Thanks to the crash test. This was surfaced after https://github.com/facebook/rocksdb/issues/13378 merged.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13394
Test Plan:
Unit Test
```
./compaction_service_test
```
Crash Test
```
COERCE_CONTEXT_SWITCH=1 COMPILE_WITH_TSAN=1 CC=clang-13 CXX=clang++-13 ROCKSDB_DISABLE_ALIGNED_NEW=1 USE_CLANG=1 make V=1 -j100 dbg
```
```
python3 -u tools/db_crashtest.py blackbox --enable_remote_compaction=1
```
Reviewed By: jowlyzhang
Differential Revision: D69496313
Pulled By: jaykorean
fbshipit-source-id: 7e38e3cb75d5a7708beb4883e1a138e2b09ff837
Summary:
as a preparation to support merge in [WBWIMemtable](https://github.com/facebook/rocksdb/blob/d48af213860054a7696e7ea2764f266c88a3263e/memtable/wbwi_memtable.h#L31), this PR updates how we [order updates to the same key](https://github.com/facebook/rocksdb/blob/d48af213860054a7696e7ea2764f266c88a3263e/utilities/write_batch_with_index/write_batch_with_index_internal.cc#L694-L697) in WriteBatchWithIndex. Specifically, the order is now reversed such that more recent update is ordered first. This will make iterating from WriteBatchWithIndex much easier since the key ordering in WBWI now matches internal key order where keys with larger sequence number are ordered first. The ordering is now explicitly documented above the declaration for `WriteBatchWithIndex` class.
Places that use `WBWIIteratorImpl` and assume key ordering are updated. The rest is test and comments update.
This will affect users who use WBWIIterator directly, the output of GetFromBatch, GetFromBatchAndDB or NewIteratorWithBase are not affected. Users are only affected if they may issue multiple updates to the same key. If WriteBatchWithIndex is created with `overwrite_key=true`, one the the updates needs to be Merge.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13387
Test Plan: we have some good coverage of WBWI, I updated some existing tests and added a test for `WBWIIteratorImpl`.
Reviewed By: pdillinger
Differential Revision: D69421268
Pulled By: cbi42
fbshipit-source-id: d97eec4ee74aeac3937c9758041c7713f07f9676
Summary:
Motivated by code review issue in https://github.com/facebook/rocksdb/issues/13316, we don't want to release the DB mutex in SetOptions between updating the cfd latest options and installing the new Version and SuperVersion. SetOptions uses LogAndApply to install a new Version but this currently incurs an unnecessary manifest write. (This is not a big performance concern because SetOptions dumps a new OPTIONS file, which is much larger than the redundant manifest update.) Since we don't want IO while holding the DB mutex, we need to get rid of the manifest write, and that's what this change does. We introduce a kind of dummy VersionEdit that allows the existing code paths of LogAndApply to install a new Version (with the updated mutable options), recompute resulting compaction scores etc., but without the manifest write.
Part of the validation for this is new assertions in SetOptions verifying the consistency of the various copies of MutableCFOptions. (I'm not convinced we need it in SuperVersion in addition to Version, but that's not for here and now.) These checks depend on defaulted `operator==` so depend on C++20.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13384
Test Plan:
New unit test in addition to new assertions. SetOptions already tested heavily in crash test. Used
`ROCKSDB_CXX_STANDARD=c++20 make -j100 check` to ensure the new assertions are verified
Reviewed By: cbi42
Differential Revision: D69408829
Pulled By: pdillinger
fbshipit-source-id: 4cf026010c6bb381e0ea27567cce2708d4678e7d
Summary:
I found a failed crash test with this error message:
```
Verification failed: Failed to flush primary's WAL before secondary verification
```
`manual_wal_flush_one_in` does not make sense / is not applicable when we are disabling the WAL.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13382
Test Plan: Monitor future crash test runs
Reviewed By: jowlyzhang, anand1976
Differential Revision: D69314053
Pulled By: archang19
fbshipit-source-id: b69d2e1e2869943c0df8cdc4f0623906f4ec7a7a
Summary:
There was a stress test that failed at the assertion check for `IsDataBlockInBuffer`.
`IsDataBlockInBuffer` is too strict of a condition if we are trying to read past the end of the file.
This seems to be a bug from the original 2019 commit https://github.com/siying/rocksdb/commit/3737d06adc01a59e7eb29710a2a4ec64adfaa528: https://github.com/siying/rocksdb/blob/4eb51130917c260f5637731cd77baaa45dfdc5ec/file/file_prefetch_buffer.cc#L130
If the caller tries requesting more bytes than are available, then we still return `n` bytes, even if the buffer really only contains `m < n` bytes.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13376
Test Plan: I added a unit test which caused the original `IsDataBlockInBuffer ` assertion to fail. I also updated the unit test to check for the result size, which triggered the bug (without this fix) where we return a size of `n` even if less than `n` bytes exist.
Reviewed By: anand1976
Differential Revision: D69269608
Pulled By: archang19
fbshipit-source-id: 1dc0d5930e2b73089850f6e996afbd6192cd5ac8
Summary:
First step to add (simulated) Remote Compaction in Stress Test. More PRs to come. Just first PR to add the FLAG to enable it. `DbStressCompactionService` will return `kUseLocal` for all compactions.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13378
Test Plan:
```
python3 -u tools/db_crashtest.py whitebox --enable_remote_compaction=1
```
```
python3 -u tools/db_crashtest.py blackbox --enable_remote_compaction=1
```
Reviewed By: hx235
Differential Revision: D69269568
Pulled By: jaykorean
fbshipit-source-id: 5119bb6afd4d52f66923fb095150d3132226f7ba
Summary:
**This PR adds a new statistic to track the total number of sorted runs for running compactions.**
Context: I am currently working on a separate project, where I am trying to tune the read request sizes made by `FilePrefetchBuffer` to the storage backend. In this particular case, `FilePrefetchBuffer` will issue larger reads and have to buffer larger read responses. This means we expect to see higher memory utilization. At least for the initial rollout, we only want to enable this optimization for compaction reads.
**I want some way to get a sense of what the memory usage _impact_ will be if the prefetch read request size is increased from (for instance) 8MB to 64MB.**
**If I know the number of files that compactions are actively reading from (i.e. the number of sorted runs / "input iterators"), I can determine how much the memory usage will increase if I bump up the readahead size inside `FilePrefetchBuffer`.** For instance, if there are 16 sorted runs at any given point in time and I bump up the readahead size by 64MB, I can project an increase of 16 * 64 MB.
In most cases, the number of sorted runs processed per compaction is the number of L0 files plus the number of non-L0 levels. However, we need to be aware of exceptions like trivial compactions, deletion compactions, and subcompactions. This is a major reason why this PR chooses to implement the stats counting inside `CompactionMergingIterator`, since by the time we get down to that part of the stack, we know the "true" values for the number of input iterators / sorted runs.
Alternatives considered:
- https://github.com/facebook/rocksdb/issues/13299 gives you a histogram for the number of sorted runs ("input iterators") for a _single compaction_. While this statistic is interested and in the direction of what we want, we are going to be assessing the memory impact across _all_ compactions that are currently running. Thus, this statistic does not give us all the information we need.
- https://github.com/facebook/rocksdb/issues/13302 gives you the total prefetch buffer memory usage, but it doesn't tell you what happens when the readahead size is increased. Furthermore, the code change is error prone and very "invasive" -- look at how many places in the code had to be updated. This would be useful in the future for general memory accounting purposes, but it does not serve our immediate needs.
- https://github.com/facebook/rocksdb/issues/13320 aimed to track the same metric, but did this inside `DbImpl:: BackgroundCallCompaction`. It turns out that this does not handle the case where a compaction is divided into multiple subcompactions (in which case, there would be _more_ sorted runs being processed at the same time than you would otherwise predict.) The current PR handles subcompactions automatically, and I think it is cleaner overall.
Note: When I attempted to put this statistic as part of the `cf_stats_value_` array, even after updating the array to use `std::atomic<uint64_t>`, I still was able to get assertions to _fail_ inside the crash tests. These assertions checked that the unsigned integer would not underflow below zero during compaction. I experimented for many hours but could not figure out a solution, even though it would seem like things "should" work with `fetch_add` and `fetch_sub`. One possibility is that the values in `cf_stats_value_` are being cleared to 0, but I added a `fprintf` to that portion of the code and didn't see it getting printed out before my assertions failed. Regardless, I think that this statistic is different enough from the CF-specific and the other DB-wide stats that the best solution is to just have it defined as a separate `std::atomic<uint64_t>`. I also do not want to spend more hours trying to debug why the crash test assertions break, when the solution in the current version of the PR can get the assertions to consistently pass.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13325
Test Plan:
- I updated one unit test to confirm that `num_running_compaction_sorted_runs` starts and ends at 0. This checks that all the additions and subtractions cancel out. I also made sure the statistic got incremented at least once.
- When I added `fprintf` manually, I confirmed that my statistics updating code was being exercised numerous times inside `db_compaction_test`. I printed out the results before and after the increments/decrements, and the numbers looked good.
- We will monitor the generated statistics after this PR is merged.
- There are assertion checks after each increment and before each decrement. If there are bugs, the crash test will almost certainly find them, since they quickly found issues with my initial implementation for this PR which tried using the `cf_stats_value_` array (modified to use `std::atomic`).
Reviewed By: anand1976, hx235
Differential Revision: D68527895
Pulled By: archang19
fbshipit-source-id: 135cf210e0ff1550ea28ae4384d429ae620b1784
Summary:
This test is flaky likely due to synchronization of the file ingestion thread and the live write thread with test sync points are not working as expected sometimes. Very occasionally, the live write thread can enter the write queue after file ingestion job already dequeued. Or it entered and waited for a very short period of time and quickly returned in the fast path: https://github.com/facebook/rocksdb/blob/833a2266a394fe5f140d2a22f406c82bb605c726/db/write_thread.cc#L83-L86
To fix the flakiness, I moved the test sync points to make sure the write thread is already linked into the write queue before the file ingestion writer get dequeued, so it definitely would need to wait some time in order to do its write.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13374
Test Plan:
I'm able to reproduce the flakiness with this command before the fix with every two or three runs:
./gtest-parallel external_sst_file_basic_test --gtest_filter=ExternalSSTFileBasicTest.Basic --repeat=10000 --workers=100
After the fix, I have tried the command for 10 runs, and there is no failure detected.
Reviewed By: cbi42
Differential Revision: D69258712
Pulled By: jowlyzhang
fbshipit-source-id: adcbad4dd53ccddab5c137d3f9d740b9f9623207
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13370
We have a class called `DefaultSecondaryIndex` in `TransactionTest.SecondaryIndexPutDelete` that contains generally useful functionality. The patch generalizes it a bit to make the column name configurable, renames it to `SimpleSecondaryIndex`, and moves it to the public API so applications can use it.
Reviewed By: jowlyzhang
Differential Revision: D69147890
fbshipit-source-id: 0d2d1cc5adcde01f3978a450ec841c9e990d2170
Summary:
There was a failed TSAN crash test run that involved BlobDB and secondary instances. ltamasi said that BlobDB is not compatible with secondary instances, so I have updated the crash test script accordingly.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13371
Test Plan:
I confirmed there were no blob-related parameters after running
```
python3 tools/db_crashtest.py --simple blackbox --test_secondary=1
```
Reviewed By: jowlyzhang
Differential Revision: D69193105
Pulled By: archang19
fbshipit-source-id: b545d7765928a385a792fc070c1d432d1c002b3d
Summary:
As titled. unreleased_history directory now only contain release notes for the next 10.0 release.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13373
Reviewed By: ltamasi
Differential Revision: D69196468
Pulled By: jowlyzhang
fbshipit-source-id: 849193c7901c5938d3d7c938e3b6c805532d7de4
Summary:
We want to disable WAL for RoWS stress tests (anand1976 made a config change to explicitly do this), but it turns out that is not compatible with `reopen` > 0.
I found this error in the logs:
```
Error: Db cannot reopen safely with disable_wal set!
```
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13372
Test Plan: We should not get this error message in the RoWS stress tests.
Reviewed By: jowlyzhang
Differential Revision: D69193849
Pulled By: archang19
fbshipit-source-id: 933252926a906183c9abdef0b47f641073c5de37
Summary:
`DynamicLevelCompressionPerLevel` test started _somewhat occasionally_ failing post refactoring in https://github.com/facebook/rocksdb/pull/13322. In order for `DeleteFilesInRange`-replacement to behave according to our expectations (that is delete exactly that very single file given its' key range), we must first ensure that input `keys` are NOT randomly shuffled, but rather preserved in their natural, sequential order. That change was originally a part of the PR, but got somehow deleted due to human error and since tests passed locally and in CI, spilled unnoticed. We're removing random keys reshuffling (as intended originally) and, in addition, asserting that all such constructed files are 1) non-overlapping and 2) contain full range of keys BEFORE we actually get to test the on table deletion callbacks.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13349
Test Plan: Confirmed that key range overlap is an issue by volume testing: `./db_test --gtest_filter=*DynamicLevelCompressionPerLevel --gtest_repeat=1000 --gtest_break_on_failure` (2-3 times is enough). Could not longer repro after the fix.
Reviewed By: jaykorean
Differential Revision: D68857018
Pulled By: mszeszko-meta
fbshipit-source-id: 873b1ba44f32d40192da4265aeeb39702c22a1d0
Summary:
**Context/Summary:**
archang19 found the place in code where no injected error status is returned on effectively injected error (empty result or corrupted bytes). I can't find a good argument for doing so. In these cases where such empty result and corrupted result is not expected, the file system should return error (< 0). Our fault injection framework should align with that to simulate fault returned by file system.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13369
Test Plan: Monitor stress test
Reviewed By: archang19
Differential Revision: D69136015
Pulled By: hx235
fbshipit-source-id: 6ee7a7bd5e0aa19837e4dfd73817d4a9d5af76f9
Summary:
The crash tests are failing during secondary database verification due to a "truncated block read" error.
https://github.com/facebook/rocksdb/issues/13366 attempted to resolve the issue by checking for injected errors. However, that did not work.
It turns out that sometimes faults are injected yet the return status is still "OK."
See https://github.com/facebook/rocksdb/blob/main/utilities/fault_injection_fs.cc#L1407-L1414 for an example:
```cpp
} else if (Random::GetTLSInstance()->OneIn(8)) {
assert(result);
// For a small chance, set the failure to status but turn the
// result to be empty, which is supposed to be caught for a check.
*result = Slice();
msg << "empty result";
ctx->message = msg.str();
ret_fault_injected = true;
```
My hypothesis is that this particular fault injection is the root cause of the "truncated block read" error.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13368
Test Plan: Hopefully the recurring crash tests start passing consistently for secondary db verification
Reviewed By: hx235
Differential Revision: D69132024
Pulled By: archang19
fbshipit-source-id: 941406165a2fd306f10048614457261cda99d762
Summary:
Leading up to some compression code refactoring, we have a bit of an ifdef nightmare in compression.h relating to zstd support. With the major release RocksDB 10.0.0 coming up, it is a good time to clean up much of this tech debt by requiring zstd >= 1.4.0 (April 2019) if building RocksDB with ZSTD support. For example, Ubuntu 20, the first LTS version to properly support C++17 in its built-in gcc, comes with zstd version 1.4.4. This should not be a significant limitation.
* Almost all of the `ZSTD_VERSION_NUMBER` checks are simplified to just `ZSTD`, though
* `ROCKSDB_ZSTD_DDICT` still needs to be separate because of dependency on `ZSTD_STATIC_LINKING_ONLY` (added to fbcode_config_platform010.sh by the way)
* Similar for ZDICT_finalizeDictionary, which is only generally available in >= 1.4.5
* Eliminate deprecated `kZSTDNotFinalCompression`
* Reduce some cases of unnecessary copying definitions across `#if` branches (e.g. `ZSTDUncompressCachedData`)
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13362
Test Plan:
minor unit test updates. `make check` on several build variants with/without zstd and with/without `ZSTD_STATIC_LINKING_ONLY`
Also deflaked DBTest.DynamicLevelCompressionPerLevel which was flaky before this change but failed once in CI
Reviewed By: cbi42
Differential Revision: D69129453
Pulled By: pdillinger
fbshipit-source-id: ef0cbf9f0fea4e7684fa0999320aa170cfbec233
Summary:
**Context/Summary:**
https://github.com/facebook/rocksdb/pull/13263 temporally disable `track_and_verify_wals=1` with write fault injection in all cases to mitigate a WAL hole not fully debugged. Fully debugging shows the WAL hole only happens under pessimistic TXN when two-phase-commit (2pc) was used.
The bug essentially is about 2pc won't be able to discard the corrupted WAL as it would in non-2pc case as part of the WAL write error recovery. So the corrupted WAL will still present in the next DB open and caught by `track_and_verify_wals=1`.
This fix is going to take a while. So for now, let's reduce the scope of disabling the testing.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13360
Test Plan: Monitor stress test for WAL recovery error/corruption
Reviewed By: jaykorean
Differential Revision: D68973022
Pulled By: hx235
fbshipit-source-id: ea8db6fa11ba25ace896da7cdb1dc1cd757742f6
Summary:
https://github.com/facebook/rocksdb/issues/13281 added secondary database verification to the crash tests.
I am seeing failures in the crash test that trace back to these two code sections:
1. https://github.com/facebook/rocksdb/blob/main/db_stress_tool/no_batched_ops_stress.cc#L2969-L2975
```cpp
VerificationAbort(
shared,
msg_prefix + "Non-OK status" + read_u64ts.str() + s.ToString(), cf,
key, "", Slice(expected_value_data, expected_value_data_size));
```
2. https://github.com/facebook/rocksdb/blob/main/table/block_fetcher.cc#L327-L331
```cpp
io_status_ = IOStatus::Corruption(
"truncated block read from " + file_->file_name() + " offset " +
std::to_string(handle_.offset()) + ", expected " +
std::to_string(block_size_with_trailer_) + " bytes, got " +
std::to_string(slice_.size()));
```
The error messages look like
```
Secondary get verificationNon-OK statusCorruption: truncated block read from /dev/shm/rocksdb_test/rocksdb_crashtest_blackbox/011887.sst offset 11780096, expected 16274 bytes, got 0
```
As you can see, the issue is not that the values of the secondary DB differ from what we expect. Rather, the `get` request itself is returning a non-OK status. I looked at the test configurations for the failed test runs, and I saw that both of them enabled fault injections (e.g. `read_fault_one_in`).
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13366
Test Plan:
Before merging: `python3 tools/db_crashtest.py --simple blackbox --test_secondary=1`
After merging: monitor for crash test failures
Reviewed By: jaykorean
Differential Revision: D69059138
Pulled By: archang19
fbshipit-source-id: a9c07d80381f52bdff220b0db3302748ebccd96c
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13361
After https://github.com/facebook/rocksdb/pull/13346 and https://github.com/facebook/rocksdb/pull/13348, K-nearest-neighbors queries no longer have to be exposed via an iterator API. The patch makes the interface for KNN search more natural by replacing `KNNIterator` in `FaissIVFIndex` with a new method `FindKNearestNeighbors`. This simplifies both the use and the implementation of `FaissIVFIndex`.
Reviewed By: jowlyzhang
Differential Revision: D68973541
fbshipit-source-id: cd6fec44c202e7cfa7219af482d1ca800e2d672d
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13353
The patch changes `SecondaryIndexIterator` to a standalone concrete class that mimics most of `Iterator`'s interface but no longer derives from `Iterator`. This eliminates the need to implement `Iterator` methods which are not applicable in the context of secondary indices (namely `SeekToFirst`, `SeekToLast`, and `SeekForPrev`). The class is also moved to the public interface; with this move, the earlier factory method doesn't really add much value anymore and is thus removed.
Reviewed By: jowlyzhang
Differential Revision: D68923662
fbshipit-source-id: 9e1af250bb392535537d6c867f36d23dae5b01b9
Summary:
This bug was spotted by cbi42 and should be the root cause for the crash test data races 🤞 .
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13351
Test Plan: Monitor recurring crash tests.
Reviewed By: hx235
Differential Revision: D68909000
Pulled By: archang19
fbshipit-source-id: e0bdfda9f92eacd2513fc8894f8cde35da88da68
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13348
This eliminates the need to shoehorn all index queries into a single method signature. With this change, `SecondaryIndex` implementations can expose the queries they support via the most natural interface. For `FaissIVFIndex`, this means that KNN search need not be modeled using an iterator anymore; however, for now, the class still has a (non-virtual) `NewIterator` method that takes a read options structure `FaissIVFIndexReadOptions`.
Reviewed By: jowlyzhang
Differential Revision: D68852927
fbshipit-source-id: b4f63bfea9cd73a6c99a547de2a0676e1e8dee0d
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13346
As the first step of revising the secondary index query API, the patch moves `FaissIVFIndex` to the public header. This will enable querying the index without having a `NewIterator` virtual in the `SecondaryIndex` interface (which will be removed in the next step of this cleanup).
Reviewed By: jowlyzhang
Differential Revision: D68846678
fbshipit-source-id: 37617d7da87a5c31b1ec7d82ef9694f8519d78d6
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13326
This diff introduces ToolHooks, a class which allows for users to interpose their own set of logic for various functionality with db_bench_tool (i.e., various OpenDB implementations).
Reviewed By: anand1976
Differential Revision: D67868126
fbshipit-source-id: df433b0c8a064a86735b92a8ef5f38527dbc9112
Summary:
Fixing the GetMergeOperands() in ReadOnlyDB and SecondaryDB as reported in https://github.com/facebook/rocksdb/issues/13243. Refactor in https://github.com/facebook/rocksdb/issues/11799 introduced this regression.
Follow ups to come
- Large Result Optimization (done in https://github.com/facebook/rocksdb/issues/10458 ) for ReadOnlyDB and SecondaryDB
- Stress Test / Crash Test coverage
- Consider removing some duplicate logic between ReadOnlyDB's GetImpl() and SecondaryDB's `GetImpl()`. The only difference is between acquiring/referencing Superversion.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13340
Test Plan:
`DBMergeOperandTest` and `DBSecondaryTest` updated
```
./db_merge_operand_test --gtest_filter="*GetMergeOperandsBasic*"
```
```
./db_secondary_test -- --gtest_filter="*GetMergeOperands*"
```
Reviewed By: ltamasi
Differential Revision: D68791652
Pulled By: jaykorean
fbshipit-source-id: 760925e257ab10993c207094718dc0659822ae64
Summary:
This is a continuation of https://github.com/facebook/rocksdb/pull/13338, which aims to address crash test failures caused by https://github.com/facebook/rocksdb/pull/13281.
This PR attempts to address the TSAN failures.
I searched for wherever we call `column_families_.clear()` and made sure that we also clear the secondary column families as well. I made a helper method since it is easy to forget to clear both sets of column families.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13343
Test Plan: Monitor recurring crash test results.
Reviewed By: cbi42
Differential Revision: D68790580
Pulled By: archang19
fbshipit-source-id: 96ed758a21545dd20181b8db71b81dd660546e18
Summary:
https://github.com/facebook/rocksdb/issues/13281 added support for verifying secondaries in the crash tests. We are trying to check that the values returned by the secondary in `Get` requests fall within an expected range of values. We do reads from the shared expected state before and after we read from the secondary.
There are some rare verification failures where `VerifyValueRange` fails with `Unexpected value found outside of the value base range`.
I have some ideas on what the root cause could be. The secondary can read the WAL, MANIFEST, and SST files, but in some scenarios some of these pieces may not be present.
I noticed that the failures had `manual_wal_flush_one_in=1000`, which means that `options.manual_wal_flush` is set to `true`. With this setting, RocksDB has its own internal buffers that need to be manually flushed for the WAL to be persisted.
Although the test failures I looked at did not disable the WAL, I realized that, when the WAL is disabled, we should flush the primary's memtables, since the secondary needs to be able to find SST files to fully catch up.
Injected faults further complicate matters, so I have a check to skip secondary verification whenever the WAL or memtable flushes fail due to fault injection.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13338
Test Plan:
Locally:
```
python3 tools/db_crashtest.py --simple blackbox --test_secondary=1
python3 tools/db_crashtest.py --simple whitebox --test_secondary=1
python3 tools/db_crashtest.py --simple blackbox --test_secondary=1 --disable_wal=1
python3 tools/db_crashtest.py --simple blackbox --test_secondary=1 --disable_wal=0 --manual_wal_flush_one_in=1000
```
I will monitor the recurring crash tests after this gets merged.
Reviewed By: anand1976
Differential Revision: D68741287
Pulled By: archang19
fbshipit-source-id: 86f474c41a68b7b06f2ed80a851c6cb52a47ebe7
Summary:
https://github.com/facebook/rocksdb/issues/13281 added support to the crash tests for secondary DB verification.
I looked at our recurring crash tests to see what impact https://github.com/facebook/rocksdb/issues/13281 had. The actual secondary verification looks okay to me (no `assert` failures), but I noticed memory leaks were detected.
The problematic areas were tracked down to the call to `DB::OpenAsSecondary` from `rocksdb::StressTest::Open`.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13337
Test Plan:
Monitor recurring crash tests. It is likely hard to reproduce the ASAN failures locally if they are rare enough.
```
make -j100 db_stress COMPILE_WITH_ASAN=1
python3 tools/db_crashtest.py --simple blackbox --test_secondary=1
```
Reviewed By: cbi42
Differential Revision: D68721624
Pulled By: archang19
fbshipit-source-id: 9c3044884c505c43c1819a3e98ce99b2d171f3ca
Summary:
Cleanup post https://github.com/facebook/rocksdb/pull/13284.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13322
Test Plan:
1. We did not find any evidence of breakage in internal pre-release integration pipeline runs after renaming the deprecated API in `9.10`.
2. _To the extent possible_, we manually validated partner use cases of file deletion and confirmed deprecated API is no longer in use.
Reviewed By: jaykorean
Differential Revision: D68476852
Pulled By: mszeszko-meta
fbshipit-source-id: fbe1f873e16ae7c60d7706a3c44ecc695ab86a4b
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13329
The patch adds two convenience methods `ConvertFloatsToSlice` and `ConvertSliceToFloats` that can be used to convert embeddings from a contiguous range of floats to a RocksDB `Slice` or vice versa. The methods are added to the public API so they can be utilized by applications as well.
Reviewed By: jowlyzhang
Differential Revision: D68581494
fbshipit-source-id: 2207fa3e668a6546b7de6d8ab78be2ba9f2ffd8c
Summary:
TLDR: This PR enables secondary DB verification inside the "simple" crash tests (`NonBatchedOpsStressTest`). Essentially, we want to be able to verify that the secondary is a valid "prefix" of the primary. This PR allows us to do this by piggybacking on the existing verification of the primary through `Get()` requests.
I originally proposed replaying the trace file to recreate the `ExpectedState` as of a specific sequence number. This could be used to run verifications against the secondary database. I did some experimenting in https://github.com/facebook/rocksdb/issues/13266 and got a "mostly working" implementation of this approach. I could sometimes get through entire key space verifications but eventually one of the keys would fail verification. I have not figured out the root cause yet, but I assume that something caused the sequence number to trace record alignment to break.
The approach in this PR is considerably simpler. We can just check that the secondary database's value is in the correct "range," which we already have functionality for checking that. Compared to the approach in https://github.com/facebook/rocksdb/issues/13266, this approach is _much, much simpler_ since we do not have to go through the whole headache of replaying the trace and creating an entire new `ExpectedState`. (Look at https://github.com/facebook/rocksdb/issues/13266 to see how much of a mess that creates.) I think this approach is better than my original approach in almost most aspects: it's faster, uses less space, and has less room for implementation errors.
Other nice aspects of this approach:
1. We don't need to block the primary. (Another approach you could imagine would be to block writes to the primary, have the secondary catch up, do the whole verification, and then re-enable writes to the primary.)
2. We don't need to block the secondary or do any special coordination (locks, sync points, etc). (If we insist on one "golden" expected value to be read from the secondary, then we need to make sure that another thread does not call `TryCatchUpWithPrimary` while we are trying to perform a `Get()`)
3. More "realistic" usage of the secondary. For instance, writes to the primary and secondary would continue on in production while we try to read from the secondary.
The main drawback of course is that we verify against a range of expected values, rather than one particular expected value. However, I think this is acceptable and "good enough" especially with all of other the aforementioned benefits.
Historical context: There is some very old code that attempted to verify secondaries, but is not enabled. This code has not been touched or executed in an extremely long time, and the crash tests started failing when I tried enabling it, most likely because the code is not compatible with certain other crash test options. This code is for the "continuous verification" and involves long iterator scans over the secondary database. Some of the code involved the cross CF consistency test type. I don't think the old checks are what we really want for our purposes of verifying the secondary functionality. Since I don't think we will get much value out of this old "continuous verification" code, I integrated my secondary verification with the "regular" database verification. This also makes the rollout simpler on my end, since I can control whether my secondary verifications are enabled through one `test_secondary` configuration. To make sure the old code does not execute for our recurring crash test runs, I had to enforce that `continuous_verification_interval` is 0 whenever `test_secondary` is set.
Monitoring: I will want to monitor the Sandcastle "simple" runs for failures where `test_secondary` is set. All of my error messages are prefixed with "Secondary" so it should be easy to tell if this PR causes any crash test issues.
Future work:
1. Extend this to followers. I think the same verification method should work, so most of the code from this PR should be reusable
2. Add additional checks to make sure the sequence number of the follower/secondary is actually increasing. For instance, if the primary's sequence number has advanced, and in that period the secondary has not (even after calling `TryCatchUpWithPrimary`), then we know there is a problem
3. Potentially checking things other than `Get()` for the secondary (i.e. iterators). I think the focus here should be testing replication-specific logic, and since we will already have separate unit tests, we do not need to repeat all of tests against both the primary and the secondary.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13281
Test Plan:
The primary crash test commands I ran were:
```
python3 tools/db_crashtest.py --simple blackbox --test_secondary=1
python3 tools/db_crashtest.py --simple whitebox --test_secondary=1
```
As a sanity check, I added an `assert(false)` right after my secondary verification code to make sure that my code was actually being run.
Reviewed By: anand1976
Differential Revision: D67953821
Pulled By: archang19
fbshipit-source-id: 0bd853580ea53566be41639f5499eb9b5e0e9376
Summary:
The patch adds a unit test that reproduces an issue we have been seeing in our stress tests that affects reverse iteration when BlobDB and user-defined timestamps are both enabled. If in addition to the above, lazy loading of blobs (`allow_unprepared_value`) is enabled and `max_sequential_skip_in_iterations` is exceeded during the reverse scan, calling `PrepareValue` can result in an error status (`Corruption: Key mismatch when reading blob`). We plan to fix the issue in a follow-up patch.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13332
Reviewed By: jowlyzhang
Differential Revision: D68642615
fbshipit-source-id: a09b24e2dda6b5fa97ae576708ab278f540251bf
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13327
The patch adds a public API method `NewSecondaryIndexIterator` that can be leveraged by users providing their own `SecondaryIndex` implementations.
Reviewed By: jaykorean
Differential Revision: D68569198
fbshipit-source-id: 07f77837c3ce7ab8ea2d9bac172df3d64ce4f745
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13324
There are actually some use cases which would benefit from the ability to use the primary key when forming the secondary key prefix or value. One such use case, which is demonstrated using a unit test, is building a secondary index on non-initial part(s) of the primary key. The patch adds back this ability, which was was removed in https://github.com/facebook/rocksdb/pull/13207, with a twist: the earlier `GetSecondaryKeyPrefix` is essentially split into two parts, with `GetSecondaryKeyPrefix` now being responsible only for computing whatever the secondary index is built on (let's call this "index function result") and a new `FinalizeSecondaryKeyPrefix` method having the responsibility of dealing with serialization concerns like adding a length indicator for disambiguation. This also means a slight change for the `SecondaryIndexIterator` class: it now treats its `Seek` argument as an "index function result" and thus only calls the new `FinalizeSecondaryKeyPrefix` on it (but not `GetSecondaryKeyPrefix`).
Reviewed By: jaykorean
Differential Revision: D68514201
fbshipit-source-id: d3750d049b0aee37e6c20edc19f5e4a0d3fce91e
Summary:
Today, backup verification is serial, which could pose a challenge in rare, high urgency recovery scenarios where we want to timely assess whether candidate backup is not corrupted and eligible for the restore. The _timely_ part will become increasingly more important in case of disaggregated storage.
### Semantics
Given the very simple thread pool implementation in `backup_engine` today, we do not really have a control over initialized threads and consequently do not have an option to unschedule / cancel in-progress tasks. As a result, `VerifyBackup` won't bail out on a very first mismatch (as it was the case for serial implementation) and instead will iterate over all the files logging success / degree_of_failure for each. We _could_, in theory, not `.wait()` on remaining `std::future<WorkItem>`s (upon previously detected failure) and therefore decrease the observed API latency, but that _could_ cause more confusion down the road as verification threads would still be occupied with inflight/scheduled work and would not be reclaimed by the pool for a while. It's a tradeoff where we choose a solution with clear and intuitive semantics.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13292
Test Plan:
Kudos to pdillinger who pointed out that we should already have appropriate fuzzing for max_background_operations and verify_checksum=true parameters in scope of ::VerifyBackup calls in existing backup restore stress test collateral.
[1]
https://github.com/facebook/rocksdb/blob/main/db_stress_tool/db_stress_test_base.cc#L1296
Reviewed By: pdillinger
Differential Revision: D68046714
Pulled By: mszeszko-meta
fbshipit-source-id: 980253174aa9dfd3064866a51c53345277e3a032
Summary:
... to makes it easier to use the new transaction feature `commit_bypass_memtable`. Instead of needing to specify the option when creating a transaction, this option allows users to specify a threshold on the number of updates in a transaction to determine when to skip memtables writes for a transaction.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13304
Test Plan: a new unit test for the new option
Reviewed By: pdillinger
Differential Revision: D68288579
Pulled By: cbi42
fbshipit-source-id: d3076629891d8b1d427878d20f0ac40dc0dadd35
Summary:
With this change we are adding native library support for incremental restores. When designing the solution we decided to follow 'tiered' approach where users can pick one of the three predefined, and for now, mutually exclusive restore modes (`kKeepLatestDbSessionIdFiles`, `kVerifyChecksum` and `kPurgeAllFiles` [default]) - trading write IO / CPU for the degree of certainty that the existing destination db files match selected backup files contents. New mode option is exposed via existing `RestoreOptions` configuration, which by this time has been already well-baked into our APIs. Restore engine will consume this configuration and infer which of the existing destination db files are 'in policy' to be retained during restore.
### Motivation
This work is motivated by internal customer who is running write-heavy, 1M+ QPS service and is using RocksDB restore functionality to scale up their fleet. Given already high QPS on their end, additional write IO from restores as-is today is contributing to prolonged spikes which lead the service to hit BLOB storage write quotas, which finally results in slowing down the pace of their scaling. See [T206217267](https://www.internalfb.com/intern/tasks/?t=206217267) for more.
### Impact
Enable faster service scaling by reducing write IO footprint on BLOB storage (coming from restore) to the absolute minimum.
### Key technical nuances
1. According to prior investigations, the risk of collisions on [file #, db session id, file size] metadata triplets is low enough to the point that we can confidently use it to uniquely describe the file and its' *perceived* contents, which is the rationale behind the `kKeepLatestDbSessionIdFiles` mode. To find more about the risks / tradeoffs for using this mode, please check the related comment in `backup_engine.cc`. This mode is only supported for SSTs where we persist the `db_session_id` information in the metadata footer.
2. `kVerifyChecksum` mode requires a full blob / SST file scan (assuming backup file has its' `checksum_hex` metadata set appropriately, if not additional file scan for backup file). While it saves us on write IOs (if checksums match), it's still fairly complex and _potentially_ CPU intensive operation.
3. We're extending the `WorkItemType` enum introduced in https://github.com/facebook/rocksdb/pull/13228 to accommodate a new simple request to `ComputeChecksum`, which will enable us to run 2) in parallel. This will become increasingly more important as we're moving towards disaggregated storage and holding up the sequence of checksum evaluations on a single lagging remote file scan would not be acceptable.
4. Note that it's necessary to compute the checksum on the restored file if corresponding backup file and existing destination db file checksums didn't match.
### Test plan ✅
1. Manual testing using debugger: ✅
2. Automated tests:
* `./backup_engine_test --gtest_filter=*IncrementalRestore*` covering the following scenarios: ✅
* Full clean restore
* Integration with `exclude files` feature (with proper writes counting)
* User workflow simulation: happy path with mix of added new files and deleted original backup files,
* Existing db files corruptions and the difference in handling between `kVerifyChecksum` and `kKeepLatestDbSessionIdFiles` modes.
* `./backup_engine_test --gtest_filter=*ExcludedFiles*` ✅
* Integrate existing test collateral with newly introduced restore modes
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13239
Reviewed By: pdillinger
Differential Revision: D67513875
Pulled By: mszeszko-meta
fbshipit-source-id: 273642accd7c97ea52e42f9dc1cc1479f86cf30e
Summary:
Offer new DB::Open and variants that use `std::unique_ptr<DB>*` output parameters and deprecate the old versions that use `DB**` output parameters.
This shouldn't have weird downstream effects because these are just static functions. (And a constructor for StackableDB)
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13311
Test Plan: existing tests
Reviewed By: anand1976
Differential Revision: D68340779
Pulled By: pdillinger
fbshipit-source-id: 30f4448398b479b5abecfc2406447f200a5fe073
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13312
The patch moves the `AsSlice` and `AsString` methods to a new `SecondaryIndexHelper` class to facilitate reuse and eliminate some code duplication.
Reviewed By: jaykorean
Differential Revision: D68342378
fbshipit-source-id: 9cb55bfd64a7db810898739dde01b128e15c81f4
Summary:
FlushReason enum in C++ has members up to 15, but in Java, the mirroring FlushReason only supports reason codes up to 12. This causes exceptions when adding a flush listener.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13246
Reviewed By: pdillinger
Differential Revision: D68241620
Pulled By: jaykorean
fbshipit-source-id: 1e2856dad28dff0cbb1772f5a8ea03cc1e224088
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13305
The patch adds a public factory method `NewFaissIVFIndex` that can be used to create a FAISS inverted file based secondary index object. (Note that at the moment, FAISS secondary indices require using the Meta-internal BUCK build; this will be addressed in a follow-up patch.) As a small code organization improvement, the patch also moves `SecondaryIndexReadOptions` to its own header file.
Reviewed By: jaykorean
Differential Revision: D68284544
fbshipit-source-id: b46351c110589ec05606710452016deaa5028626
Summary:
As follow-up to https://github.com/facebook/rocksdb/issues/13239, this change is primarily motivated by simplifying the calling conventions of LogAndApply. Since it must be called while holding the DB mutex, it can read safely read cfd->GetLatestMutableCFOptions(), until it releases the mutex within ProcessManifestWrites. Before it releases the mutex, it makes a copy of the mutable options in a new, unpublished Version object, which can be used when not holding the DB mutex. This eliminates the need for callers of LogAndApply to copy mutable options for its sake, or even specify mutable options at all. And it eliminates the need for *another* copy to be saved in ManifestWriter.
Other functions that don't need the mutable options parameter:
* ColumnFamilyData::CreateNewMemtable()
* CompactionJob::Install() / InstallCompactionResults()
* MemTableList::*InstallMemtable*()
* Version::PrepareAppend()
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13301
Test Plan: existing tests, CI with sanitizers
Reviewed By: mszeszko-meta
Differential Revision: D68234865
Pulled By: pdillinger
fbshipit-source-id: 6ce95f9cc479834e09ffc8ce93cbae7b664329e5
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13300
The patch adds a new unit test for `FaissIVFIndex` that compares its results with a regular in-memory FAISS index. Specifically, it trains two identical IVF indices using the same training vectors, passes the ownership of one to `FaissIVFIndex`, adds the same set of database vectors to both, and then queries them using the same query vectors (with a variety of values for number of neighbors and number of probes).
Reviewed By: jaykorean
Differential Revision: D68233815
fbshipit-source-id: 7577a65c03c7b811707a4dbcd81e69ed85202a51
Summary:
To start, I wanted to remove the unnecessary new_options parameter of `InstallSuperVersionAndScheduleWork()`. Passing it something other than the latest mutable options would be inconsistent/outdated. There was even a comment "Use latest MutableCFOptions" on a place that was using the saved options in effect for the compaction.
On investigation, this fixes an undiagnosed but longstanding serious bug in SetOptions() where the new settings can be reverted if a flush or compaction started before the SetOptions() finishes after. Fix confirmed with new unit test in db_test.cc.
I also got tired of seeing the cumbersome usage of pointer rather than const reference for related options accesses, so there's kind of a large (but trivial) refactoring tied in here as well. (Sorry for combining them; wasn't planning a major bug fix)
Intended follow-up: Clarify/simplify the crazy calling conventions of LogAndApply, and remove some unnecessary copying of MutableCFOptions (see new FIXMEs)
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13294
Test Plan: test for bug fix, confirmed fails on main and at least as far back as version 8.10. Plus existing tests and CI
Reviewed By: mszeszko-meta
Differential Revision: D68141563
Pulled By: pdillinger
fbshipit-source-id: f6c3290145afa06cc2fe8b485a5de17560a5deea
Summary:
Currently, when the primary instance shuts down, remote compaction continues to run and `CompactionService::Wait()` does not get aborted. This slows down `DB::Close()` as it waits for the completion of `CompactionService::Wait()`. Moreover, since shutdown has already begun, the compaction is unnecessary and will be wasted.
This PR introduces `CancelAwaitingJobs()` to the CompactionService interface. This allows users to implement cancellation of running remote compactions from the primary instance. When `CancelAllBackgroundWork()` is called on the primary instance, `CancelAwaitingJobs()` will be invoked, enabling a more efficient shutdown process.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13286
Test Plan:
Unit Test added
```
./compaction_service_test --gtest_filter="*CancelCompactionOnPrimarySide*"
```
Reviewed By: anand1976, cbi42
Differential Revision: D68035191
Pulled By: jaykorean
fbshipit-source-id: 47da641f7cbed1267f0a1f16924f57efde46216d
Summary:
The patch implements support for `Delete` and `SingleDelete` with secondary indices, leveraging the earlier pieces built for `Put` / `PutEntity`. As expected, deleting an entry using these APIs also deletes any associated secondary index entries.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13291
Reviewed By: jaykorean
Differential Revision: D68041422
fbshipit-source-id: c8afc9ff69dea834f89ae855a72c1d76e7db0e35
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13289
The patch adds support for `Put` / `PutUntracked` to the secondary indexing logic. Similarly to `PutEntity` (see https://github.com/facebook/rocksdb/pull/13180), calling these APIs automatically add or remove secondary index entries as needed in an atomic and transparent fashion.
Reviewed By: jaykorean
Differential Revision: D68035089
fbshipit-source-id: db37bce62151ae1909b46b1020592c8348156653
Summary:
We added a removal warning for public `DB::DeleteFile` API ~4 years ago in https://github.com/facebook/rocksdb/pull/7337. This API seems to sit at wrong layer of abstraction, where instead of exposing a clear interface to delete specific range of keys, callers rely on their own discovery / interpretation of where their data / log possibly resides 'as-of-now'. For example, in case of data, the physical location of the keys might very well change after user obtained their mapping from key(s) to specific SST file. This will lead to `InvalidArgument` response, which if repeated, would put a user in a race condition spinning wheel - the behavior that's inefficient, fairly indeterministic and therefore one that should be strongly discouraged. We're employing a graceful approach to prefixing the public API with `DEPRECATED_` first for better discoverability and ease of self service for product teams should they still use that legacy API. If everything goes smoothly, we intend to remove all the deprecated API references in the next release.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13284
Reviewed By: pdillinger
Differential Revision: D67981502
Pulled By: mszeszko-meta
fbshipit-source-id: adc7fe5cf4e2180bcfd21878b8f78f3fb6ead355
Summary:
The warm storage crash test sometimes fails due to the cleanup command failing if the db_stress exited successfully and we already cleaned up. This results in false alarms. Don't treat a cleanup command failure as crash test failure.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13287
Reviewed By: archang19
Differential Revision: D68023398
Pulled By: anand1976
fbshipit-source-id: f95fff030a5ea8eb7d2dfb248d08d7876e2de2b2
Summary:
As advertised and recommended by original authors comment, we're removing the now-outdated special handling logic for bloom filters perf regression (timing ~release 7.0.X). I decided to keep the `CompatibilityName` as-is since 1) it's publicly exposed API and 2) it's generally useful to have a dedicated name used for identifying whether a filter on disk is readable by the FilterPolicy.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13277
Test Plan:
'Dead code' / tech debt. As a smoke test, I manually run a similar benchmark to the one in https://github.com/facebook/rocksdb/pull/9736, with ./db_bench built pre and post change.
**Generate DB:**
```hcl
./db_bench -db=/dev/shm/rocksdb.9.11 -bloom_bits=10 -cache_index_and_filter_blocks=1 -benchmarks=fillrandom -num=10000000 -compaction_style=2 -fifo_compaction_max_table_files_size_mb=10000 -fifo_compaction_allow_compaction=0
```
**Before removing the 'if' block:**
```hcl
./db_bench -db=/dev/shm/rocksdb.9.11 -use_existing_db -readonly -bloom_bits=10 -benchmarks=readrandom -num=10000000 -compaction_style=2 -fifo_compaction_max_table_files_size_mb=10000 -fifo_compaction_allow_compaction=0 -duration=10 2>&1 | grep micros/op
readrandom : 17.216 micros/op 58085 ops/sec 10.002 seconds 580999 operations; 4.1 MB/s (367256 of 580999 found)
```
**After removing the 'if' block:**
```hcl
./db_bench -db=/dev/shm/rocksdb.9.11 -use_existing_db -readonly -bloom_bits=10 -benchmarks=readrandom -num=10000000 -compaction_style=2 -fifo_compaction_max_table_files_size_mb=10000 -fifo_compaction_allow_compaction=0 -duration=10 2>&1 | grep micros/op
readrandom : 16.776 micros/op 59607 ops/sec 10.015 seconds 596999 operations; 4.2 MB/s (377846 of 596999 found)
```
Reviewed By: jaykorean, pdillinger
Differential Revision: D67908020
Pulled By: mszeszko-meta
fbshipit-source-id: b904b8eaf9d106f0b47e4ff175242795ac1c5e73
Summary:
In https://github.com/facebook/rocksdb/pull/13177, I discussed an unsigned integer overflow issue that affects compaction reads inside `FilePrefetchBuffer` when we attempt to enable the file system buffer reuse optimization. In that PR, I disabled the optimization whenever `for_compaction` was `true` to eliminate the source of the bug.
**This PR safely re-enables the optimization when `for_compaction` is `true`.** We need to properly set the overlap buffer through `PrefetchInternal` rather than simply calling `Prefetch`. `Prefetch` assumes `num_buffers_` is 1 (i.e. async IO is disabled), so historically it did not have any overlap buffer logic. What ends up happening (with the old bug) is that, when we try to reuse the file system provided buffer, inside the `Prefetch` method, we read the remaining missing data. However, since we do not do any `RefitTail` method when `use_fs_buffer` is true, normally we would rely on copying the partial relevant data into an overlap buffer. That overlap buffer logic was missing, so the final main buffer ends up storing data from an offset that is greater than the requested offset, and we effectively end up "throwing away" part of the requested data.
**This PR also unifies the prefetching logic for compaction and non-compaction reads:**
- The same readahead size is used. Previously, we read only `std::max(n, readahead_size_)` bytes for compaction reads, rather than `n + readahead_size_` bytes
- The stats for `PREFETCH_HITS` and `PREFETCH_BYTES_USEFUL` are tracked for both. Previously, they were only tracked for non-compaction reads.
These two small changes should help reduce some of the cognitive load required to understand the codebase. The test suite also became easier to maintain. We could not come up with good reasons why the logic for the readahead size and stats should be different for compaction reads.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13187
Test Plan:
I removed the temporary test case from https://github.com/facebook/rocksdb/issues/13200 and incorporated the same test cases into my updated parameterized test case, which tests the valid combinations between `use_async_prefetch` and `for_compaction`.
I went further and added a randomized test case that will simply try to hit `assert`ion failures and catch any missing areas in the logic.
I also added a test case for compaction reads _without_ the file system buffer reuse optimization. I am thinking that it may be valuable to make a future PR that unifies a lot of these prefetch tests and parametrizes as much of them as possible. This way we can avoid writing duplicate tests and just look over different parameters for async IO, direct IO, file system buffer reuse, and `for_compaction`.
Reviewed By: anand1976
Differential Revision: D66903373
Pulled By: archang19
fbshipit-source-id: 351b56abea2f0ec146b83e3d8065ccc69d40405d
Summary:
This option has been officially deprecated in 5.4.0. We're removing all the references to `random_access_max_buffer_size`, related rules and all the clients wrappers. As a part of this refactoring, we're also getting rid of the `options-1-false` (and consequently its' `multiple-conds-all-false` corresponding rule), as condition would not make much sense anymore without the bounding RA max buffer size limit. Motivated by ongoing tech debt reduction effort.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13278
Test Plan: Validated that internal users do not rely on this long-gone option in their workflows.
Reviewed By: jaykorean
Differential Revision: D67909674
Pulled By: mszeszko-meta
fbshipit-source-id: 8f4b59a4a92b0b32b8b91b71ac318aafc17f1da2
Summary:
The crash test with COERCE_CONTEXT_SWITCH=1 is showing a failure:
```
db_stress: db/seqno_to_time_mapping.cc:480: bool rocksdb::SeqnoToTimeMapping::Append(rocksdb::SequenceNumber, uint64_t): Assertion `false' failed.
```
with `DBImpl::SetOptions()` in the call stack. This assertion and those around it are mostly there for catching systematic problems with recording the mappings, as small imprecisions here and there are not a problem in production. Nevertheless, we need to fix this to maintain the assertions for catching possible future systematic problems.
Because the seqno and time are acquired before holding the DB mutex, there could be a race where T1 acquires latest seqno, T1 acquires latest seqno, T2 acquires unix time, T1 acquires unix time, and entries are not just saved out-of-order, but would represent an inconsistent (time traveling) mapping if they were saved.
We can fix this by getting the seqno and unix times while under the mutex. (Hopefully this is not caused by non-monotonic clock adjustments.)
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13279
Test Plan: local run blackbox_crash_test with COERCE_CONTEXT_SWITCH=1. This is not really a production concern, and the conditions are not really reproducible in a unit test after the fix.
Reviewed By: cbi42
Differential Revision: D67923314
Pulled By: pdillinger
fbshipit-source-id: 6bfb6b05d6d449154fbaeb9196eedcfa21fe5ae1
Summary:
Reflect RocksDB DailyOffpeakTimeUTC option in Java API. As is standard for options, there are a number of different places where this option needs to be added: it is an option, a DB option, and it is mutable (can be changed while running).
The new option is a string value. This requires an extension to the internal MutableDBOptions parse code, which received the entire options string from C++ and parses it on the Java side.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13148
Reviewed By: cbi42
Differential Revision: D67870402
Pulled By: jaykorean
fbshipit-source-id: 975af69773206da936d230cbadb5f69a002d92a3
Summary:
The patch is the read-side counterpart of https://github.com/facebook/rocksdb/pull/13197 . It adds support for K-nearest-neighbor vector similarity searches to `FaissIVFIndex`. There are two main pieces to this:
1) `KNNIterator` is an `Iterator` implementation that is returned by `FaissIVFIndex` upon a call to `NewIterator`. `KNNIterator` treats its `Seek` target as a vector embedding and passes it to FAISS along with the number of neighbors requested `k` as well as the number of probes to use (i.e. the number of inverted lists to check). Applications can then use `Next` (and `Prev`) to iterate over the the vectors in the result set. `KNNIterator` exposes the primary keys associated with the result vectors (see below how this is done), while `value` and `columns` are empty. The iterator also supports a property `rocksdb.faiss.ivf.index.distance` that can be used to retrieve the distance/similarity metric for the current result vector.
2) `IteratorAdapter` takes a RocksDB secondary index iterator (see https://github.com/facebook/rocksdb/pull/13257) and adapts it to the interface required by FAISS (`faiss::InvertedListsIterator`), enabling FAISS to read the inverted lists stored in RocksDB. Since FAISS only supports numerical vector ids of type `faiss::idx_t`, `IteratorAdapter` uses `KNNIterator` to assign ephemeral (per-query) ids to the inverted list items read during iteration, which are later mapped back to the original primary keys by `KNNIterator`.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13258
Reviewed By: jaykorean
Differential Revision: D67684898
fbshipit-source-id: 5b5c4c438deb86b35d5d45262ce290caee083bca
Summary:
To resolve a crash test failure in
`FlushJob::GetPrecludeLastLevelMinSeqno()`
To fix this properly, I will work on ensuring that (a) FlushJob is created with a consistent view on mutable options and seqno_to_time_mapping (from a single SuperVersion) and (b) SuperVersions always have a non-null seqno_to_time_mapping when a relevant option is set.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13269
Test Plan: watch crash test
Reviewed By: ltamasi
Differential Revision: D67843008
Pulled By: pdillinger
fbshipit-source-id: cedbac4b2255398eefade46240c5481b57a98b1e
Summary:
The primary goal of this change was to support full dynamic mutability of options `preclude_last_level_data_seconds` and `preserve_internal_time_seconds`, which was challenging because of subtle design holes referenced from https://github.com/facebook/rocksdb/issues/13124.
The fix is, in a sense, "doubling down" on the idea of write-time-based tiering, by simplifying the output level decision with a single sequence number threshold. This approach has some advantages:
* Allows option mutability in presence of long snapshots (or UDT)
* Simpler to believe correct because there's no special treatment for range tombstones, and output level assignment does not affect sequence number assignment to the entries (which takes some care to avoid circular dependency; see CompactionIterator stuff below).
* Avoids extra key comparisons, in `WithinPenultimateLevelOutputRange()`, in relevant compactions (more CPU efficient, though untested).
There are two big pieces/changes to enable this simplification to a single `penultimate_after_seqno_` threshold:
* Allow range tombstones to be sent to either output level, based on sequence number.
* Use sequence numbers instead of range checks to avoid data in the last level from moving to penultimate level outside of the permissable range on that level (due to compaction selecting wider range in the later input level, which is the normal output level). With this change, data can only move "back up the LSM" when entire sorted runs are selected for comapction.
Possible disadvantages:
* Extra CPU to iterate over range tombstones in relevant compactions *twice* instead of once. However, work loads with lots of range tombstones relative to other entries should be rare.
* Data might not migrate back up the LSM tree on option changes as aggressively or consistently. This should a a rare concern, however, especially for universal compaction where selecting full sorted runs is normal compaction.
* This approach is arguably "further away from" a design that allows for other kinds of output level placement decisions, such as range-based input data hotness. However, properly handling range tombstones with such policies will likely require flexible placement into outputs, as this change introduces.
Additional details:
* For good code abstraction, separate CompactionIterator from the concern of where to place compaction outputs. CompactionIterator is supposed to provide a stream of entries, including the "best" sequence number we can assign to those entries. If it's safe and proper to zero out a sequence number, the placement of entries to outputs should deal with that safely rather than having complex inter-dependency between sequence number assignment and placement. To achieve this, we migrate all the compaction output placement logic that was in CompactionIterator to CompactionJob and similar. This unfortunately renders some unit tests (PerKeyPlacementCompIteratorTest) depending on the bad abstraction as obsolete, but tiered_compaction_test has pretty good coverage overall, catching many issues during this development.
Intended follow-up:
* See FIXME items in tiered_compaction_test
* More testing / validation / support for tiering + UDT
* Consider generalizing this work to split results at other levels as appropriate based on stats (auto-tuning essentially). Allowing only the last level to be cold is limiting.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13256
Test Plan: tests were added in previous changes (https://github.com/facebook/rocksdb/issues/13244#13124), and updated here to reflect correct operation (with some known problems for leveled compaction)
Reviewed By: cbi42
Differential Revision: D67683210
Pulled By: pdillinger
fbshipit-source-id: ca3f2bbc2fcc6891516a2a4220f1b0da09af5ade
Summary:
The RocksDB backup engine code currently derives the IO buffer size based on the following criteria:
1. If specified, use the rate limiter burst size
2. Otherwise, use the default size (5 MiB)
We want to be able to explicitly choose the IO size based on the storage backend. We want the new criteria to be:
1. If specified, use the size in `BackupEngineOptions`
2. If specified, use the rate limiter burst size
3. Otherwise, use the default size (5 MiB)
This PR adds a new option called `io_buffer_size` to `BackupEngineOptions` and updates the logic used to set the buffer size.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13236
Test Plan:
I added a separate unit test and verified that we can either use the `io_buffer_size`, rate limiter burst size, or the default size.
I decided to use a `TEST_SYNC_POINT_CALLBACK`. I considered the alternative of updating the `Read` implementation of `DummySequentialFile` / `CheckIOOptsSequentialFile` to check the value of `n`. However, that would have considerably complicated the whole test code, and we also do not need to be checking for this in every single test case. I think the `TEST_SYNC_POINT_CALLBACK` turned out to be quite elegant.
Reviewed By: sushilpa
Differential Revision: D67765000
Pulled By: archang19
fbshipit-source-id: 2122fab7379335de44ba4423af47aa0563635688
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13257
The patch adds a new API `NewIterator` to `SecondaryIndex`, which should return an iterator that can be used by applications to query the index. This method takes a `ReadOptions` structure, which can be used by applications to provide (implementation-specific) query parameters to the index, and an underlying iterator, which should be an iterator over the index's secondary column family, and is expected to be leveraged by the returned iterator to read the actual secondary index entries. (Providing the underlying iterator this way enables querying the index as of a specific point in time for example.)
Querying the index can be performed by calling the returned iterator's `Seek` API with a search target, and then using `Next` (and potentially `Prev`) to iterate through the matching index entries. `SeekToFirst`, `SeekToLast`, and `SeekForPrev` are not expected to be supported by the iterator. The iterator should expose primary keys, that is, the secondary key prefix should be stripped from the index entries.
The exact semantics of the returned iterator depend on the index and are implementation-specific. For simple indices, the search target might be a primary column value, and the iterator might return all primary keys that have the given column value. (This behavior can be achieved using the new class `SecondaryIndexIterator`.) However, other semantics are also possible: for vector indices, the search target might be a vector, and the iterator might return similar vectors from the index. (This will be implemented for `FaissIVFIndex` in a subsequent patch.)
Reviewed By: jaykorean
Differential Revision: D67684777
fbshipit-source-id: 59bc33919405a3e9e316a1fa4790c1708788eb85
Summary:
**Context/Summary:**
After https://github.com/facebook/rocksdb/pull/13226, our crash test appears to find a WAL hole caused by mishandling of an injected error during writing the buffer in writable file writer into the underlying log file. It will take some time for me to fully root-cause and fix it. Before then, let's disable this combination.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13263
Test Plan: Monitor crash test
Reviewed By: ltamasi
Differential Revision: D67755485
Pulled By: hx235
fbshipit-source-id: 5f7bb422f7722c2696872232b1fed8ffa5c0f4c3
Summary:
we saw this [assertion](https://github.com/facebook/rocksdb/blob/02b4197544f758bdf84d80fe9319238611848c48/db/error_handler.cc#L576) failing in crash test. The LOG shows that there's a call to SetOptions() concurrent to ResumeImpl(). It's possible that while waiting for error recovery flush (with mutex released), SetOptions() failed to write to MANIFEST and added a file to be quarantined. This triggered the assertion failure when ResumeImpl() calls ClearBGError().
This PR fixes the issue by setting background error when SetOptions() fails to write to MANIFEST.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13251
Test Plan: monitor future crash test failures.
Reviewed By: hx235
Differential Revision: D67660106
Pulled By: cbi42
fbshipit-source-id: 1b52bb23005c4b544f8f9bceefd3b9dcbaf0edfa
Summary:
The patch tweaks the new `SecondaryIndex` interface a bit by removing the `primary_key` parameter of `GetSecondaryKeyPrefix` and `GetSecondaryValue`. This parameter is currently unused by existing implementations and it actually does not make sense to have the secondary index prefix depend on the primary key since it would lead to potential chicken-and-egg problems at query time.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13207
Reviewed By: jaykorean
Differential Revision: D67184936
fbshipit-source-id: 5707a35225a0160132e5e87e9fe6c36bee5eada1
Summary:
**Context/Summary:**
This PR provides a new Options `track_and_verify_wals` to detect and handle WAL hole where new WAL data presents while some old WAL data is missing as well as db opened with no WAL. It's for https://github.com/facebook/rocksdb/issues/12488.
It's intended to be a future replacement to `track_and_verify_wals_in_manifest` for its simplicity, better handling of WAL hole in `WALRecoveryMode::kPointInTimeRecovery` and potentials to cover more scenarios for `WALRecoveryMode::kTolerateCorruptedTailRecords/kAbsoluteConsistency`(in future PRs).
The verification is done in `LogReader::MaybeVerifyPredecessorWALInfo()` and tracking is done in `log::Writer::MaybeAddPredecessorWALInfo()`. This PR also groups common utilities in `log::Writer` into functions `MaybeHandleSeenFileWriterError()`, `MaybeSwitchToNewBlock()` to avoid adding redundant code
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13226
Test Plan:
- New UT
- Integrate into existing UT
- Intense rehearsal stress/crash test
- db bench
- The only potential performance implication it has is to the write path since now we keep track of the last seqno recorded in the WAL in `log::Writer`. Below benchmark show no regression.
```
./db_bench --benchmarks=fillrandom[-X3] --num=2500000 --db=/dev/shm/db_bench_new --disable_auto_compactions=1 --threads=1 --enable_pipelined_write=0 --disable_wal=0 --track_and_verify_wals=1
Pre
fillrandom [AVG 3 runs] : 310517 (± 5641) ops/sec; 34.4 (± 0.6) MB/sec
fillrandom [MEDIAN 3 runs] : 308848 ops/sec; 34.2 MB/sec
Post
fillrandom [AVG 3 runs] : 311469 (± 4096) ops/sec; 34.5 (± 0.5) MB/sec
fillrandom [MEDIAN 3 runs] : 311961 ops/sec; 34.5 MB/sec
```
Reviewed By: pdillinger
Differential Revision: D67550260
Pulled By: hx235
fbshipit-source-id: 623e29bbe293ef03a45c20c348f84c8cb5bdaf91
Summary:
**Context/Summary:**
This is to solve https://github.com/facebook/rocksdb/issues/12152. We persist the largest flushed seqno before crash just like how we persist the ExpectedState. And we verify the db lates seqno after recovery is no smaller than this flushed seqno.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/12787
Test Plan:
- Manually observe that the persisted sequence after flush completion is used to verify db's latest sequence
- python3 tools/db_crashtest.py --simple blackbox --interval=30
- CI
Reviewed By: archang19
Differential Revision: D58860150
Pulled By: hx235
fbshipit-source-id: 99cb4403964d0737908855f92af7327867079e3e
Summary:
* Expand RangeTombstoneSnapshotMigrateFromLast in tiered_compaction_test (originally from https://github.com/facebook/rocksdb/issues/13124) to reproduce a failure in universal compaciton (as well as leveled), when a specific part of the test is uncommented.
* Small refactoring to eliminate unnecessary fields in SubcompactionState. Adding a bool parameter to SubcompactionState::AddToOutput here will make more sense in the next PR (which I'm trying to keep
from getting too big).
* Improve debuggability and performance of some other tests
* Remove accidentally committed test "BlahPrecludeLastLevel" which was a temporary copy of CompactionServiceTest.PrecludeLastLevel
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13244
Test Plan: existing tests, updated/expanded tests
Reviewed By: cbi42
Differential Revision: D67605076
Pulled By: pdillinger
fbshipit-source-id: 9be83c2173f77545b5fe17ff9dc67db497c7afc9
Summary:
Followup to https://github.com/facebook/rocksdb/pull/13228. This fix is not a critical one in a sense that `else`-branch is only supposed to act as a guard just in case when new work item type is being introduced, scheduled but not handled. However, we're in control of the work item types and currently we only support a single one (which has appropriate handling logic to it).
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13238
Reviewed By: pdillinger
Differential Revision: D67512001
Pulled By: mszeszko-meta
fbshipit-source-id: 71e74b3dac388882dd3757871f500c334667fbd1
Summary:
This test assertion was added in https://github.com/facebook/rocksdb/issues/13219. It checks the concurrent write thread's wait time is not longer than the file ingestion thread's write blocking time since the former entered the write thread after the blocking already started in the test. This test runs into flakiness like this:
```db/external_sst_file_basic_test.cc:300: Failure
Expected: (perf_context.file_ingestion_blocking_live_writes_nanos) > (write_thread_perf_context->write_thread_wait_nanos), actual: 166210 vs 279681
```
In reality the write thread is yielding starting with a 1 micro period and then every 100 micros: https://github.com/facebook/rocksdb/blob/54b614de5bd3e26d332b85557d44bde86b2a2e87/db/write_thread.cc#L68-L70
So this 113 micros errors is within this margin
This fix the test with just removing this assertion. The other assertion `ASSERT_GT(write_thread_perf_context->write_thread_wait_nanos, 0)` should be sufficient for the test's purpose.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13241
Reviewed By: hx235
Differential Revision: D67526804
Pulled By: jowlyzhang
fbshipit-source-id: 23ee9771247e4c13444054a1e86ad9293902cb56
Summary:
* Simplify some testing callbacks for tiered_compaction_test ahead of some significant functional updates.
* Refactor CompactionJob::Prepare() for sharing with CompactionServiceCompactionJob. This is a minor functional change in computing preserve/preclude sequence numbers for remote compaction, but it is a start toward support for tiered storage with remote compaction. A test is added that is only partly working but does check that outputs are being split (just not to the correct levels).
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13230
Test Plan: mostly test changes and additions. Arguably makes tiered storage + remote compaction MORE broken as a step toward supporting it.
Reviewed By: jaykorean
Differential Revision: D67493682
Pulled By: pdillinger
fbshipit-source-id: fd6db74e08ef0e4fc7fdd599ff8555aab0c8ddc4
Summary:
`DBErrorHandlingFSTest.AtomicFlushNoSpaceError` is flaky due to seg fault during error recovery:
```
...
frame https://github.com/facebook/rocksdb/issues/5: 0x00007f0b3ea0a9d6 librocksdb.so.9.10`rocksdb::VersionSet::GetObsoleteFiles(std::vector<rocksdb::ObsoleteFileInfo, std::allocator<rocksdb::ObsoleteFileInfo>>*, std::vector<rocksdb::ObsoleteBlobFileInfo, std::allocator<rocksdb::ObsoleteBlobFileInfo>>*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>*, unsigned long) [inlined] std::vector<rocksdb::ObsoleteFileInfo, std::allocator<rocksdb::ObsoleteFileInfo>>::begin(this=<unavailable>) at stl_vector.h:812:16
frame https://github.com/facebook/rocksdb/issues/6: 0x00007f0b3ea0a9d6 librocksdb.so.9.10`rocksdb::VersionSet::GetObsoleteFiles(this=0x0000000000000000, files=size=0, blob_files=size=0, manifest_filenames=size=0, min_pending_output=18446744073709551615) at version_set.cc:7258:18
frame https://github.com/facebook/rocksdb/issues/7: 0x00007f0b3e8ccbc0 librocksdb.so.9.10`rocksdb::DBImpl::FindObsoleteFiles(this=<unavailable>, job_context=<unavailable>, force=<unavailable>, no_full_scan=<unavailable>) at db_impl_files.cc:162:30
frame https://github.com/facebook/rocksdb/issues/8: 0x00007f0b3e85e698 librocksdb.so.9.10`rocksdb::DBImpl::ResumeImpl(this=<unavailable>, context=<unavailable>) at db_impl.cc:434:20
frame https://github.com/facebook/rocksdb/issues/9: 0x00007f0b3e921516 librocksdb.so.9.10`rocksdb::ErrorHandler::RecoverFromBGError(this=<unavailable>, is_manual=<unavailable>) at error_handler.cc:632:46
```
I suspect this is due to DB being destructed and reopened during recovery. Specifically, the [ClearBGError() call](https://github.com/facebook/rocksdb/blob/c72e79a262bf696faf5f8becabf92374fc14b464/db/db_impl/db_impl.cc#L425) can release and reacquire mutex, and DB can be closed during this time. So it's not safe to access DB state after ClearBGError(). There was a similar story in https://github.com/facebook/rocksdb/issues/9496. [Moving the obsolete files logic after ClearBGError()](https://github.com/facebook/rocksdb/pull/11955) probably makes the seg fault more easily triggered.
This PR updates `ClearBGError()` to guarantee that db close cannot finish until the method is returned and the mutex is released. So that we can safely access DB state after calling it.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13234
Test Plan: I could not trigger the seg fault locally, will just monitor future test failures.
Reviewed By: jowlyzhang
Differential Revision: D67476836
Pulled By: cbi42
fbshipit-source-id: dfb3e9ccd4eb3d43fc596ec10e4052861eeec002
Summary:
This change refactors existing `CopyOrCreateWorkItem` async task definition to a more generic one (`WorkItem`) with an assigned `type` indicative of intended action. This would allow us to reuse existing, battle-tested async tasks initialization code to handle wider range of incoming use cases in B/R space.
### Motivation
Historically, the two main use cases for `BackupEngineImpl`'s async work items were either creating a file in backup workflow or copying files in restore workflow. However, as we're now exploring opportunities in incremental restore (and potentially speeding up backup verification), we need the work item abstraction to be capable of processing different workflow types concurrently (computing checksum comes to mind).
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13228
Test Plan: Since this is purely cosmetic change where behavior remains intact, existing test collateral will suffice.
Reviewed By: pdillinger
Differential Revision: D67441210
Pulled By: mszeszko-meta
fbshipit-source-id: 78803e8cf3cf40b9d81831fac3a99193e1a30ef0
Summary:
As titled. And also added some documentation for an approach to name perf context metrics that can help identify the starting `PerfLevel` that enables collecting it.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13219
Test Plan: Unit test
Reviewed By: hx235
Differential Revision: D67362022
Pulled By: jowlyzhang
fbshipit-source-id: 7ed1bb475b5497961612d4e331600609da42074b
Summary:
To set up for splitting range deletes between penultimate and last level with per-key-placement compaction. This will solve some issues in combining RangeDelete+snapshot+mutable preclude_last, and probably also RangeDelete+UDT+preclude_last
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13231
Test Plan: existing tests
Reviewed By: cbi42
Differential Revision: D67481038
Pulled By: pdillinger
fbshipit-source-id: 597f0c991e4d7eae73b36b36aad493c2d2a15f24
Summary:
Originally I was trying to update `build-linux-clang10-mini-tsan` to actually use `clang10` (as the name implied). https://github.com/facebook/rocksdb/issues/13220 was supposed to also update this configuration, but I did not see that we had a definition for `build-linux-clang10-mini-tsan` in both `config.yml` and `pr-jobs.yml`. I was wondering why I could not see my changes reflected in the CI checks after merging. After I updated `pr-jobs.yml` for this PR, I found that the CI check started failing https://github.com/facebook/rocksdb/actions/runs/12417441052/job/34668411263?pr=13232. I don't think it makes sense for me to tackle looking into all the TSAN warnings being reported in `clang10` (at least in this PR), so for now I have updated the name of the PR job to accurately reflect the command that is being run.
This PR also gets rid of the entire `.circleci` folder, which I think is the more significant change.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13232
Test Plan: Existing CI check is unchanged
Reviewed By: pdillinger
Differential Revision: D67462454
Pulled By: archang19
fbshipit-source-id: f1aabfe4c8793616d6cbaae36fdf007319bf7ab2
Summary:
... which is the default for CentOS 9 and Ubuntu 24, the latter of which is now available in GitHub Actions. Relevant CI job updated.
Re-formatted all cc|c|h files except in third-party/, using
```
clang-format -i `git ls-files | grep -E '[.](cc|c|h)$' | grep -v third-party/`
```
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13233
Test Plan: CI
Reviewed By: jaykorean, archang19
Differential Revision: D67461638
Pulled By: pdillinger
fbshipit-source-id: 0c9ac21a3f5eea6f5ade68bb6af7b6ba16c8b301
Summary:
I found this mismatch between the CI job title and the actual command ran incidentally while trying to work on https://github.com/facebook/rocksdb/issues/13213.
`build-linux-clang10-mini-tsan` was added in https://github.com/facebook/rocksdb/issues/7122 with `clang-10`.
In https://github.com/facebook/rocksdb/issues/10496 it was changed to use `clang-13` but the name was not also updated. I do not know what the author's intent was, but given that `build-linux-clang10-mini-tsan` is right next to`build-linux-clang10-ubsan` and `build-linux-clang10-asan`, I think it is more likely we originally intended to use `clang-10`.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13220
Test Plan: I think we need to wait for the next set of CI checks after this PR is merged, since I don't see my changes incorporated into this PR's `build-linux-clang10-mini-tsan` check.
Reviewed By: hx235
Differential Revision: D67407034
Pulled By: archang19
fbshipit-source-id: 9c22b6c6c330a367920eb3d4a387f37b760d722c
Summary:
This is a follow up to https://github.com/facebook/rocksdb/issues/13189. As mentioned in the description in the previous PR, to guard against similar bugs in the future, we should update our test implementations to reflect the real-world assumptions that we can make about `fs_scratch` when we issue reads with the filesystem buffer reuse optimization. The current test implementations reinforce the misconception that `fs_scratch` points to the same place as `result.data()` (i.e. to the start of the valid data buffer for the read result). `fs_scratch` can point to any arbitrary data structure, but for our purposes, I think we achieve what we want if we just have it point to a `Slice` which wraps the underlying result buffer inside one of its class variables.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13195
Test Plan: Existing unit tests test the same functionality but in an improved way with this change.
Reviewed By: hx235
Differential Revision: D66896380
Pulled By: archang19
fbshipit-source-id: 377e67ec70427716f2b7b7388d99b78003c01eb0
Summary:
In https://github.com/facebook/rocksdb/pull/13118#discussion_r1842848359, we decided to make a separate follow-up PR that refactors `FilePrefetchBuffer` to determine `use_fs_buffer` once at construction time.
The change would have involved passing in the `RandomAccessFileReader*` directly to the constructor, and using that to determine `use_fs_buffer`. This would avoid repeatedly calling `UseFSBuffer(RandomAccessFileReader* reader)` during the actual prefetch requests.
I started working on this refactoring change but ran into issues with these 2 files, which used `GetOrCreatePrefetchBuffer`
- https://github.com/facebook/rocksdb/blob/main/db/compaction/compaction_iterator.cc
- https://github.com/facebook/rocksdb/blob/main/db/merge_helper.cc
As I explained in the added code comments, sometimes the `RandomAccessFileReader*` is not available when we construct the `FilePrefetchBuffer`, so although it is not the most elegant, I think right now it makes sense to pass in the `reader` into the `Prefetch` / `PrefetchAsync` / `TryReadFromCache` calls. Maybe there is a workaround but I don't think the refactor would be worth it.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13159
Test Plan: N/A (comments)
Reviewed By: anand1976
Differential Revision: D66473731
Pulled By: archang19
fbshipit-source-id: ce3473694c2cd82513da1a76ad5995afa5bc9cfa
Summary:
I saw these compiler warnings while preparing for the 9.10 release:
```cpp
'~CompactOnDeletionCollectorFactory' overrides a destructor but is not marked 'override' [-Werror,-Wsuggest-destructor-override]
'~CompactForTieringCollectorFactory' overrides a destructor but is not marked 'override' [-Werror,-Wsuggest-destructor-override]
```
This code is from a while ago so I assume that this CI check has been failing for quite some time. We should still clean this up to avoid confusion in the future.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13212
Test Plan: Existing CI checks should pass, and we should not see this CI check failure the next time we try to make a release/patch.
Reviewed By: jaykorean
Differential Revision: D67287794
Pulled By: archang19
fbshipit-source-id: a11230a919c0b7ef21a7219bf05f567d3d44b2d1
Summary:
I had an extra comma after `9.9.fb` when I updated `tools/check_format_compatible.sh` in https://github.com/facebook/rocksdb/issues/13210. This caused the nightly builds to start failing https://github.com/facebook/rocksdb/actions/workflows/nightly.yml on the `build-format-compatible` step. The error message is
```
2024-12-14T11:55:23.3413129Z == Building 9.9.fb, debug
2024-12-14T11:55:23.3427208Z fatal: ambiguous argument '_tmp_origin/9.9.fb,': unknown revision or path not in the working tree.
```
Notice the extra comma after `9.9.fb`.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13211
Test Plan: The nightly builds should start passing again.
Reviewed By: jowlyzhang
Differential Revision: D67286484
Pulled By: archang19
fbshipit-source-id: 57a754c88af004ee879d9c9f82819b3c410a66a9
Summary:
**Context/Summary:**
`DBImpl::RecoverLogFiles()` has ~500 lines of code with nested loops and various return/continue/break statements. This becomes too difficult to understand and make change for the upcoming wal hole detection.
This PR broke it into multiple smaller functions and left a couple FIXME where the EXISTING ugly code is too complicated to clean up right now. Most of them are copy-and-paste excepts for `ProcessLogRecord()` that needs some thoughts into how to translate existing behaviors of `break`, `continue`, `return non-ok status`
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13184
Test Plan: Pass existing test
Reviewed By: jowlyzhang
Differential Revision: D66799568
Pulled By: hx235
fbshipit-source-id: d15617a47ee2d1c02652f1fd8336e82a2c5434b1
Summary:
I followed the release instructions and referenced https://github.com/facebook/rocksdb/pull/13146
1. HISOTRY update
2. version.h
3. Format compatability test
4. Folly Git hash
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13210
Test Plan: CI
Reviewed By: pdillinger
Differential Revision: D67210980
Pulled By: archang19
fbshipit-source-id: cfbc02c643aeae19453c8c36d03d93478ea81c4e
Summary:
expand the test coverage to the more comprehensive no_batched_ops_stress. Small refactoring in db_crashtest.py.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13203
Test Plan: ran a couple stress test jobs internally: https://fburl.com/sandcastle/nohosh7i
Reviewed By: jowlyzhang
Differential Revision: D67057497
Pulled By: cbi42
fbshipit-source-id: eccc033f3ae3dbd20729cd8f1f8f8d8b7c2cd057
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13197
The patch adds initial support for backing FAISS's inverted file based indices with data stored in RocksDB. It introduces a `SecondaryIndex` implementation called `FaissIVFIndex` which takes ownership of a `faiss::IndexIVF` object. During indexing, `FaissIVFIndex` treats the original value of the specified primary column as an embedding vector, and passes it to the provided FAISS index object to perform quantization. It replaces the original embedding vector with the result of the coarse quantizer (i.e. the inverted list id), and puts the result of the fine quantizer (if any) into the secondary index value. Note that this patch is only one half of the equation; it provides a way of storing FAISS inverted lists in RocksDB but there is currently no retrieval/search support (this will be a follow-up change). Also, the integration currently works only with our internal Buck build. I plan to add support for `cmake` / `make` based builds similarly to how we handle Folly.
Reviewed By: jowlyzhang
Differential Revision: D66907065
fbshipit-source-id: 63fdf29895d5feeffc230254a7ddfb0aac050967
Summary:
This is a follow up to https://github.com/facebook/rocksdb/issues/13177, which was supposed to disable the file system buffer optimization for compaction reads. However, it did not work as expected because I did not pass through `use_fs_buffer` to the `Read` method, which also calls `UseFSBuffer`.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13200
Test Plan:
I added simple tests to verify we do not hit the overflow issue when we are doing compaction prefetches.
```
./prefetch_test --gtest_filter="*FSBufferPrefetchForCompaction*"
```
Of course I will be looking through the warm storage crash test logs as well once the change is merged.
Reviewed By: anand1976
Differential Revision: D66996079
Pulled By: archang19
fbshipit-source-id: b4d9254f1354ccfc53a307174de5f2388b7e5474
Summary:
https://github.com/facebook/rocksdb/issues/13182 successfully fixed the heap `use-after-free` issue.
However, there was one additional error I found while looking through the warm storage crash test logs. There are repeated (though infrequent) unsigned pointer arithmetic overflow errors that look like this:
```cpp
file_prefetch_buffer.cc:860:46: runtime error: addition of unsigned offset to 0x7f282001880f overflowed to 0x7f2820017667
```
It took me a while to figure it out, but I was finally able to reproduce the issue locally. It turns out the issue is when we call `TryReadFromCache` with `for_compaction` set to `true`. The default value for `for_compaction` is `false`, and this was not covered in the unit tests written for https://github.com/facebook/rocksdb/issues/13118.
When I run the same unit tests with `for_compaction` set to `true`, I am able to break this assertion that I added at the end of `TryReadFromCacheUntracked`:
```cpp
assert(buf->offset_ <= offset);
```
If `buf->offset_` is greater than `offset`, then that explains the overflow we get in the following lines:
```cpp
uint64_t offset_in_buffer = offset - buf->offset_;
*result = Slice(buf->buffer_.BufferStart() + offset_in_buffer, n);
```
I will have another PR out that fixes the issue and enables the optimization when `for_compaction` is set to `true`. I will need to add some overlap buffer logic, similar to what I have inside `PrefetchInternal`. For now, since I have confirmed that there is indeed a bug, we should disable the optimization where needed. It will take me some time to implement the fix and write new test cases.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13177
Test Plan: I kept the existing unit tests which test the file system buffer reuse code when `for_compaction` is `false`. I expect that the warm storage crash test logs will no longer show the integer overflow issue once we merge this PR.
Reviewed By: anand1976
Differential Revision: D66721857
Pulled By: archang19
fbshipit-source-id: 22d523646f969a7a0ccbbea73f63c32601f1179a
Summary:
This is a followup to https://github.com/facebook/rocksdb/issues/13190. We're patching the targets generating script to construct `BUCK` file instead of deprecated `TARGETS` file + adding safety checks to ensure that `BUCK` file does not go missing (either as a direct renaming / removal OR as a modification to buckfier's script(s)).
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13196
Test Plan:
1. Manually verify 'Compare buckify output' step produces expected results (vs previously soft-failed one [here](https://github.com/facebook/rocksdb/actions/runs/12202756083/job/34044173548?pr=13178)).
2. Manually test following scenarios (for both of which we expect the buckifier script to fail):
-> Simulate removing `BUCK` file via commit
-> Simulate buckifier script removing the `BUCK` file
Reviewed By: pdillinger
Differential Revision: D66903948
Pulled By: mszeszko-meta
fbshipit-source-id: 0f83fd2f87b600981f640ccdbc3a4640974a63d4
Summary:
After https://github.com/facebook/rocksdb/pull/13118 was merged, I did some investigation to see whether the file system buffer reuse code was actually being used.
The good news is that I was able to see from the CPU profiling results that my code is getting invoked through the warm storage stress tests.
The bad news is that most of the time, the optimization is not being used, so we end up going through the regular old `RandomAccessFileReader::Read` path.
Here is the entire function call chain up to `FilePrefetchBuffer::Read`
1. rocksdb::DB::MultiGet
2. rocksdb::DBImpl::MultiGet
3. rocksdb::DBImpl::MultiGetCommon
4. rocksdb::DBImpl::MultiGetImpl
5. rocksdb::Version::MultiGet
6. rocksdb::Version::MultiGetFromSST
7. rocksdb::TableCache::MultiGet
8. rocksdb::TableCache::FindTable
9. rocksdb::TableCache::GetTableReader
10. rocksdb::BlockBasedTableFactory::NewTableReader
11. rocksdb::BlockBasedTable::Open
12. rocksdb::BlockBasedTable::PrefetchTail
13. rocksdb::FilePrefetchBuffer::Prefetch
14. rocksdb::FilePrefetchBuffer::Read
At this point, we split into `rocksdb::RandomAccessFileReader::Read` and
`rocksdb::FilePrefetchBuffer::FSBufferDirectRead`. `FSBufferDirectRead` gets called <3% of the time.
I think the root cause is that the `FileSystem* fs` parameter is not getting passed into the `FilePrefetchBuffer` constructor. When `fs` is `nullptr`, `UseFSBuffer()` will always return `false` and we do not end up calling `FSBufferDirectRead`.
Luckily, it does not seem like there are too many places I need to change. `BlockBasedTable` resets its `prefetch_buffer` in 3 separate places. When it disables the prefetch buffer (2/3 of the instances), we don't care about whether the `fs` parameter is there. This PR is addressing the third instance, where it is not trying to disable the buffer.
Note that there is another method, `PrefetchBufferCollection::GetOrCreatePrefetchBuffer` that creates new `FilePrefetchBuffer`s without the `fs` parameter. This method gets called by `compaction_iterator` and `merge_helper`. I think we can address this in a subsequent PR:
1. Each of these changes effectively "unlocks" the buffer reuse feature. Separating the changes would be helpful when I look at the profiling results again, since I can isolate what impact this PR had on the percentage of time that `rocksdb::FilePrefetchBuffer::FSBufferDirectRead` was invoked.
2. I still need to look into what exactly I would need to changes I need to make to `PrefetchBufferCollection`
3. This code seems to be for blob prefetching in particular, and I don't think it has the biggest ROI anyways.
```cpp
const Status s = blob_fetcher_->FetchBlob(
user_key(), blob_index, prefetch_buffer, &blob_value_, &bytes_read);
```
4. I am not sure if the current benchmark I am using for warm storage exercises this blob prefetching code, so I may need to find another way to assess the performance impact.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13157
Test Plan: The existing unit test coverage guards against obvious bugs. I ran another set of performance tests to confirm there were no regressions in CPU utilization.
Reviewed By: anand1976
Differential Revision: D66464704
Pulled By: archang19
fbshipit-source-id: 260145cfcc05ac46cf2dd77a53a85e8808031dea
Summary:
This change introduces a new, lightweight _experimental_ API that reconstructs the [file # -> file checksum -> file checksum function] 1-1-1 mapping directly from the `MANIFEST` file considered `CURRENT` in scope of specific DB instance at the time. The goal is to provide a cheap alternative to `DB::GetLiveFilesMetaData` that doesn't require opening the database, reconstructing version sets and/or accessing files that are _potentially_ in disaggregated storage.
### Housekeeping:
1. Moved the `GetCurrentManifestPath` out of `version_set` to a new `manifest_ops` file(s) dedicated to manifest related operations.
2. Introduced new `Env::IOActivity::kReadManifest` to better reflect the IO intent in offline file checksum retrieving function.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13178
Test Plan:
Added a unit test comparing the outcome of newly introduced API against the established `GetLiveFilesMetaData`:
```hcl
./db_test2 --gtest_filter="*GetFileChecksumsFromCurrentManifest_CRC32*"
```
Reviewed By: pdillinger
Differential Revision: D66711910
Pulled By: mszeszko-meta
fbshipit-source-id: 57091c550a14ac2e832bf7eea136dab5450e71bc
Summary:
https://github.com/facebook/rocksdb/pull/13182 seems to have resolved the `heap-use-after-free` / `heap-buffer-overflow` issues, but not for the reasons we had in mind.
I believe I have figured out the root cause after doing more thinking / reading into the warm storage code.
**`fs_scratch` cannot be assumed to point to the start of the data buffer. It must be treated as a pointer to any arbitrary object / data structure. As such, we must rely only on result.data().**
I think that part of the reason for the bug was that the comment for `fs_scratch` was
> fs_scratch is a data buffer allocated and provided by underlying FileSystem
which is _extremely misleading_.
To avoid confusion in the future, I have updated the comments related to `FsReadRequest` with some of my learnings and included `WARNING`s in all caps to hopefully steer future engineers aware from the same issue.
In another PR, I will update some of our mock file system test classes that support `FSSupportedOps::kFSBuffer`. The test class implementation also contributed to my confusion, since `fs_scratch` did point to the start of the valid data in those implementations. This cannot and should not be assumed to be true in general, and we should try to guard against potential future bugs by updating those mock implementations.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13189
Test Plan: These are just comments.
Reviewed By: anand1976, hx235
Differential Revision: D66849436
Pulled By: archang19
fbshipit-source-id: c264007647af9cc2a4dfd58dbe7287af86fa2261
The internal and external repositories are out of sync. This Pull Request attempts to brings them back in sync by patching the GitHub repository. Please carefully review this patch. You must disable ShipIt for your project in order to merge this pull request. DO NOT IMPORT this pull request. Instead, merge it directly on GitHub using the MERGE BUTTON. Re-enable ShipIt after merging.
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13180
The patch adds initial support for secondary indices using write-committed transactions. Currently, only the `PutEntity` API is supported; other APIs like `Put` and `Delete` will be added separately. Applications can set up secondary indices using the new configuration option `TransactionDBOptions::secondary_indices`. When secondary indices are enabled, calling `PutEntity` via a (n explicit or implicit) transaction performs the following steps:
1) It retrieves the current value (if any) of the primary key using `GetEntityForUpdate`.
2) If there is an existing primary key-value, it removes any existing secondary index entries using `SingleDelete`. (Note: as a later optimization, we can avoid removing and recreating secondary index entries when neither the secondary key nor the value changes during an update.)
3) It invokes `UpdatePrimaryColumnValue` for all applicable `SecondaryIndex` objects, that is, those for which the primary column family matches the column family from the `PutEntity` call and for which the primary column appears in the new wide-column structure.
4) It writes the new primary key-value. Note that the values of the indexing columns might have been changed in step 3 above.
5) It builds the secondary key-value for each applicable secondary index using `GetSecondaryKeyPrefix` and `GetSecondaryValue`, and writes it to the appropriate secondary column family.
All the above operations are performed as part of the same transaction. The logic uses `SavePoint`s to roll back any earlier operations related to a primary key if a subsequent step fails.
Implementation-wise, the code uses a mixin template `SecondaryIndexMixin` that can inherit from any kind of transaction and use the write APIs and concurrency control mechanisms of the base class to implement the index maintenance logic. The mixin will enable us to later extend secondary indices to optimistic or write-prepared/write-unprepared pessimistic transactions as well.
Reviewed By: jowlyzhang
Differential Revision: D66672931
fbshipit-source-id: cdf6ef9c40dec46d928156bad0a3cc546aa8b887
Summary:
`StartV2()` and `WaitForCompleteV2()` were deprecated and replaced by`Schedule()` and `Wait()` in 9.1.0. This PR removes them from the codebase completely.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13188
Test Plan: CI
Reviewed By: archang19
Differential Revision: D66843687
Pulled By: jaykorean
fbshipit-source-id: f13d05845bf5ac4ae736c105035ca1a4d5a96047
Summary:
add a new transaction option `TransactionOptions::commit_bypass_memtable` that will ingest the transaction into a DB as an immutable memtables, skipping memtable writes during transaction commit. This helps to reduce the blocking time of committing a large transaction, which is mostly spent on memtable writes. The ingestion is done by creating WBWIMemTable using transaction's underlying WBWI, and ingest it as the latest immutable memtable. The feature will be experimental.
Major changes are:
1. write path change to ingest the transaction, mostly in WriteImpl() and IngestWBWI() in db_impl_write.cc.
2. WBWI changes to track some per CF stats like entry count and overwritten single deletion count, and track which keys have overwritten single deletions (see 3.). Per CF stat is used to precompute the number of entries in each WBWIMemTable.
3. WBWIMemTable Iterator changes to emit overwritten single deletions. The motivation is explained in the comment above class WBWIMemTable definition. The rest of the changes in WBWIMemTable are moving the iterator definition around.
Some intended follow ups:
1. support for merge operations
2. stats/logging around this option
3. tests improvement, including stress test support for the more comprehensive no_batched_op_stress.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13144
Test Plan:
* added new unit tests
* enabled in multi_ops_txns_stress test
* Benchmark: applying the change in 8222c0cafc4c6eb3a0d05807f7014b44998acb7a, I tested txn size of 10k and check perf context for write_memtable_time, write_wal_time and key_lock_wait_time(repurposed for transaction unlock time). Though the benchmark result number can be flaky, this shows memtable write time improved a lot (more than 100 times). The benchmark also shows that the remaining commit latency is from transaction unlock.
```
./db_bench --benchmarks=fillrandom --seed=1727376962 --threads=1 --disable_auto_compactions=1 --max_write_buffer_number=100 --min_write_buffer_number_to_merge=100 --writes=100000 --batch_size=10000 --transaction_db=1 --perf_level=4 --enable_pipelined_write=false --commit_bypass_memtable=1
commit_bypass_memtable = false
fillrandom : 3.982 micros/op 251119 ops/sec 0.398 seconds 100000 operations; 27.8 MB/s PERF_CONTEXT:
write_memtable_time = 116950422
write_wal_time = 8535565
txn unlock time = 32979883
commit_bypass_memtable = true
fillrandom : 2.627 micros/op 380559 ops/sec 0.263 seconds 100000 operations; 42.1 MB/s PERF_CONTEXT:
write_memtable_time = 740784
write_wal_time = 11993119
txn unlock time = 21735685
```
Reviewed By: jowlyzhang
Differential Revision: D66307632
Pulled By: cbi42
fbshipit-source-id: 6619af58c4c537aed1f76c4a7e869fb3f5098999
Summary:
[Venice](https://venicedb.org/) is a derived data platform using RocksDB as its storage engine. It is LinkedIn's ML feature store, powering thousands of recommender use cases, including the Feed, Video recommendations, and People You May Know.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13179
Reviewed By: hx235
Differential Revision: D66724729
Pulled By: cbi42
fbshipit-source-id: a027d6664f2924473884a3d5d129748ea1e5fe37
Summary:
This PR is an attempt to address https://github.com/facebook/rocksdb/issues/13118. The warm storage crash tests show use-after-free errors. They do not occur in every single crash test run, but with enough attempts, they are repeatable.
Theory 1:
I am wondering if the `fs_buffer` is being prematurely freed before we take ownership of it. In `SetBuffer`, I was passing in `FSAllocationPtr&& new_buf` rather than `FSAllocationPtr new_buf`. When I pass the parameter as `FSAllocationPtr&& new_buf`, only after the `buf_ = std::move(new_buf);` line is run is ownership transferred from the original `FSAllocationPtr`. But before that I had a line `bufstart_ = reinterpret_cast<char*>(buf_.get());`. So I am hypothesizing that it is possible, under certain race conditions, that between the first `buf_.get()` and the `buf_ = std::move(new_buf);`, the `fs_buffer` was altered, leaving `bufstart_` pointing to some freed memory area.
Theory 2 (from anand1976):
Perhaps we need to set the `bufstart_` based on the `Slice` rather than the `FSAllocationPtr`. This would be more consistent with what we do here https://github.com/facebook/rocksdb/blob/main/table/block_fetcher.cc#L275.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13182
Test Plan: The existing unit tests and CI ensures I am not making anything worse, but I will want to wait and see if the daily crash tests runs still have the same `heap-use-after-free` errors with this change. Alternatively, if we fail the `assert` I just added, then I can make a follow-up PR to return `false` from `TryReadFromCache` whenever we get handed back a `nullptr`.
Reviewed By: anand1976
Differential Revision: D66771852
Pulled By: archang19
fbshipit-source-id: 5b585d86d657ec050a04e892d3b1cf4383f377f9
Summary:
During `FinishCompactionOutputFile()` if there's an IOError, we may end up having the output in memory, but table properties are not populated, because `outputs.UpdateTableProperties();` is called only when `s.ok()` is true.
However, during remote compaction result serialization, we always try to access the `table_properties` which may be null. This was causing a segfault.
We can skip building the output files in the result completely if the status is not ok.
# Unit Test
New test added
```
./compaction_service_test --gtest_filter="*CompactionOutputFileIOError*"
```
Before the fix
```
Received signal 11 (Segmentation fault)
Invoking GDB for stack trace...
https://github.com/facebook/rocksdb/issues/4 0x00000000004708ed in rocksdb::TableProperties::TableProperties (this=0x7fae070fb4e8) at ./include/rocksdb/table_properties.h:212
212 struct TableProperties {
https://github.com/facebook/rocksdb/issues/5 0x00007fae0b195b9e in rocksdb::CompactionServiceOutputFile::CompactionServiceOutputFile (this=0x7fae070fb400, name=..., smallest=0, largest=0, _smallest_internal_key=..., _largest_internal_key=..., _oldest_ancester_time=1733335023, _file_creation_time=1733335026, _epoch_number=1, _file_checksum=..., _file_checksum_func_name=..., _paranoid_hash=0, _marked_for_compaction=false, _unique_id=..., _table_properties=...) at ./db/compaction/compaction_job.h:450
450 table_properties(_table_properties) {}
```
After the fix
```
[ RUN ] CompactionServiceTest.CompactionOutputFileIOError
[ OK ] CompactionServiceTest.CompactionOutputFileIOError (4499 ms)
[----------] 1 test from CompactionServiceTest (4499 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (4499 ms total)
[ PASSED ] 1 test.
```
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13183
Reviewed By: anand1976
Differential Revision: D66770876
Pulled By: jaykorean
fbshipit-source-id: 63df7c2786ce0353f38a93e493ae4e7b591f4ed9
Summary:
* Test tiered storage FIFO setting `file_temperature_age_thresholds` in crash test, with dynamic mutability.
* Re-organize db_crashtest.py slightly to better handle tiered storage parameters and their interaction with compaction_style and num_levels. I have put most of this logic in the python script so that `db_stress` command lines reflect settings in effect as best as possible.
* Tweak crash test settings for preclude_last_level_data_seconds. This seems to have amplified the possibility of hitting "Corruption: Unsafe to store Seq later" even with universal compaction, which I am working on a fix for. We should also be able to enable tiered+leveled when this is fixed. (TODO / follow-up items)
* Code formatting / small simplifications in db_crashtest.py
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13176
Test Plan:
no production code changes
Kicked off about 24 CI jobs (temporary internal link https://fburl.com/sandcastle/s61rzusr)
Reviewed By: cbi42
Differential Revision: D66674123
Pulled By: pdillinger
fbshipit-source-id: 33dd7f9d291ec4a9516665b4adb998fd9a2b9266
Summary: I missed in the previous diff that this is generated. Let's fix that codegen script
Reviewed By: dtolnay
Differential Revision: D66725403
fbshipit-source-id: ec9fa773c8309040da98677a128c4cb0309542a8
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13165
This diff migrates TARGETS file to BUCK files that are synced for an open source project.
Reviewed By: dtolnay
Differential Revision: D66561335
fbshipit-source-id: 9c91a19ef59a81adc31b763a63134aeef1eb00ed
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13175
The patch is the first step in adding support for secondary indices via the transaction layer. It introduces a new `SecondaryIndex` interface, which enables creating secondary indices over a set of (plain or wide-column) primary key-values to facilitate queries by (column) value instead of key. This interface will be automagically invoked by the transaction logic to add and remove secondary index entries as needed when the application issues write operations for the primary data. Classes deriving from `SecondaryIndex` can implement the methods `GetPrimaryColumn{Family,Name}` and `GetSecondaryColumnFamily` to respectively define the primary column family and wide column to index and the column family to use for the secondary index entries. The format of the secondary index entries can be defined by implementing `GetSecondaryKeyPrefix` and `GetSecondaryValue`. In addition, `UpdatePrimaryColumnValue` can be used to optionally update the value of the indexing column in the primary key-value before it is added to the transaction.
Reviewed By: jowlyzhang
Differential Revision: D66672758
fbshipit-source-id: 0b7441ffff626c13956220e6efc98215303ef57e
Summary:
In buffered IO mode, without checksum calculation for buffered data enabled, try to align writes to the file system on a power of two. This can improve performance, especially on a distributed file system like Warm Storage that does erasure coding and benefits from full stripe writes. We do this by filling up the writable buffer, with a partial append if necessary, before flushing. When checksum calculation for buffered data is enabled, we don't do this since its preferable to not split the data, especially if the caller provides the checksum. We don't guarantee alignment if the caller manually flushes before finishing the file.
Tests:
Add unit tests in file_reader_writer_test and external_sst_file_basic_test.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13158
Reviewed By: pdillinger
Differential Revision: D66669367
Pulled By: anand1976
fbshipit-source-id: 6df1b4538bda696e2170515420ee4c3766c83bb8
Summary:
This PR adds the definition for the public APIs for surfacing data write time info. It only contains minimum implementation. The implementations will be in follow ups. I need to sync with customers if these public APIs meet their requirements and are easy to use. And make modifications accordingly before proceeding with implementations.
- `struct DataCollectionUnixWriteTimeInfo` is a struct for the unix write time info for a collection of data
- `DB::GetPropertiesOfTablesForLevels` returns table properties collection per level
- `GetDataCollectionUnixWriteTimeInfoForFile` returns the data write time info for a file.
- `GetDataCollectionUnixWriteTimeInfoForLevels` returns the data write time info for levels.
- The user property names for recording write time stats in the user collected properties are defined.
Follow ups:
Implement collecting the write time related user table properties
Use the data write time info recorded in the table properties to implement these APIs
Test Plan:
No functional change, also follow ups should have tests covering the minimum implementation added in this PR.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13138
No functional change, also follow ups should have tests covering the minimum implementation added in this PR.
Reviewed By: pdillinger
Differential Revision: D65952586
Pulled By: jowlyzhang
fbshipit-source-id: b1ebf61a35005e9ca6b4ecc28c864beb6fb4bc59
Summary:
The compaction will incorrectly drop a key under the following conditions:
1. Open an empty database.
2. Use the `IngestExternalFile` API to ingest an SST file (the global sequence number will be 0).
3. Create a snapshot (the snapshot sequence number will be 0).
4. Trigger compaction; the key in the above SST file will be dropped.
The drop condition is found here: https://github.com/facebook/rocksdb/blob/f20d12adc85ece3e75fb238872959c702c0e5535/db/compaction/compaction_iterator.cc#L875-L878
The condition does not explicitly check if a previous key exists.
Fix: Add a check of `last_sequence != kMaxSequenceNumber` to verify if there is a previous key
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13155
Reviewed By: jowlyzhang
Differential Revision: D66473015
Pulled By: cbi42
fbshipit-source-id: 93a3ec5c103f95e9bb97e3944ba6e752a5394421
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13168
The patch moves `WideColumnSerialization::Find` to `WideColumnsHelper` to facilitate reuse in non-serialization-related contexts. It also generalizes the method to take a range of iterators, and templatizes it on the iterator type to enable using it with both `const` and non-`const` iterators. Finally, it adds an assertion to ensure the method is called with a properly sorted range, which is a precondition for binary search.
Reviewed By: jaykorean
Differential Revision: D66602558
fbshipit-source-id: 841a885af31e183edeb7e3314167c55f8ed53ff1
Summary:
Adding ability to kill mysql queries traversing long lists of tombstones. Outside of mysql where RocksDbThreadYieldAndCheckAbort is not implemented all of this should still be optimized out by the compiler.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13164
Reviewed By: cbi42
Differential Revision: D66556004
Pulled By: george-reynya
fbshipit-source-id: 727875569209cd6d2f29c07f89ecfa641d5ee36f
Summary:
This change aims at increasing general memory safety in scope of selected `/db` files (`db_impl/db_impl.cc`, `dbformat.cc`, `log_reader.cc` and `transaction_log_impl.cc`).
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13154
Test Plan:
Verify logging structure & formatting parity by manually running the `/db` related tests exercising respective code paths pre and post change.
Note: As per request, we'll address the `internal_stats.cc` in the followup PR.
Reviewed By: pdillinger
Differential Revision: D66392729
Pulled By: mszeszko-meta
fbshipit-source-id: 107fd11221554721d9c1669a24031be3049afd01
Summary:
`OptionTypeInfo::ParseStruct()` was not honoring `config_options.ignore_unknown_options` when unknown properties are found in the serialized string. This caused a compatibility issue in Remote Compaction. When the worker was updated with RocksDB 9.9, the remote worker started including a new table property, `newest_key_time` (added in PR https://github.com/facebook/rocksdb/issues/13083), in the compaction output files. However, parsing that table property in the serialized compaction result from the primary (running with `9.8`) was returning a non-ok status, even though `config_options.ignore_unknown_options` was `true`.
In this fix, we will ignore unused properties if `config_options.ignore_unknown_options` is set to true.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13152
Test Plan: Unit Test Added
Reviewed By: archang19
Differential Revision: D66374541
Pulled By: jaykorean
fbshipit-source-id: 78fd8309909279390438c247c4d390bbee4fa914
Summary:
This PR adds support for reusing the file system provided buffer to avoid an extra `memcpy` into RockDB's buffer. This optimization has already been implemented for point lookups, as well as compaction and scan reads _when prefetching is disabled_.
This PR extends this optimization to work with synchronous prefetching (`num_buffers == 1`). Asynchronous prefetching can be addressed in a future PR (and probably should be to keep this PR from growing too large).
Remarks
- To handle the case where the main buffer only has part of the requested data, I used the existing `overlap_buf_` (currently used in the async prefetching case) instead of defining a separate buffer. This was discussed in https://github.com/facebook/rocksdb/pull/13118#discussion_r1842839360.
- We use `MultiRead` with a single request to take advantage of the file system buffer. This is consistent with previous work (e.g. https://github.com/facebook/rocksdb/pull/12266).
- Even without the tests I added, there was some code coverage inside in at least `DBIOCorruptionTest.IterReadCorruptionRetry`, since those tests were failing before I addressed a bug in my code for this PR. [Run with failed test](https://github.com/facebook/rocksdb/actions/runs/11708830448/job/32611508818?pr=13118).
- This prefetching code is not too easy to follow, so I added quite a bit of comments to both the code and test case to try to make it easier to understand the exact internal state of the prefetch buffer at every point in time.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13118
Test Plan:
I wrote pretty thorough unit tests that cover synchronous prefetching with file system buffer reuse. The flows for partial hits, complete hits, and complete misses are tested. I also parametrized the test to make sure the async prefetching (without file system buffer reuse) still work as expected.
Once we agree on the changes, I will run a long stress test before merging.
Reviewed By: anand1976
Differential Revision: D65559101
Pulled By: archang19
fbshipit-source-id: 1a56d846e918c20a009b83f1371c1791f69849ae
Summary:
**Context/Summary:**
https://github.com/facebook/rocksdb/pull/13117 added check for obsolete SST files that are not cleaned up timely. It caused a infrequent stress test failure `assertion="live_and_quar_files.find(file_number) != live_and_quar_files.end()"` that I haven't repro-ed yet.
This PR prints the file number so we can find out what happens to that file through info logs when encountering the same failure.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13145
Test Plan:
Manually fail the assertion and observe the stderr printing
```
[ RUN ] DBBasicTest.UniqueSession
File 12 is not live nor quarantined
db_basic_test: db/db_impl/db_impl_debug.cc:384: rocksdb::DBImpl::TEST_VerifyNoObsoleteFilesCached(bool) const::<lambda(const rocksdb::Slice&, rocksdb::Cache::ObjectPtr, size_t, const rocksdb::Cache::CacheItemHelper*)>: Assertion `false' failed.
```
Reviewed By: pdillinger
Differential Revision: D66134154
Pulled By: hx235
fbshipit-source-id: 353164c373d3d674cee676b24468dfc79a1d4563
Summary:
Pull in HISTORY for 9.9.0, update version.h for next version, update check_format_compatible.sh, update git hash for folly
Pull Request resolved: https://github.com/facebook/rocksdb/pull/13146
Test Plan: CI
Reviewed By: ltamasi
Differential Revision: D66142259
Pulled By: jowlyzhang
fbshipit-source-id: 90216b2d7cff2e0befb4f56567e3bd074f97c484
2024-11-18 21:49:47 -08:00
746 changed files with 72133 additions and 19083 deletions
# The image configuration is build_tools/ubuntu20_image/Dockerfile
# To update and build the image:
# $ cd build_tools/ubuntu20_image
# $ docker build -t zjay437/rocksdb:0.5 .
# $ docker push zjay437/rocksdb:0.5
# `zjay437` is the account name for zjay@meta.com which readwrite token is shared internally. To login:
# $ docker login --username zjay437
# Or please feel free to change it to your docker hub account for hosting the image, meta employee should already have the account and able to login with SSO.
# To avoid impacting the existing CI runs, please bump the version every time creating a new image
# to run the CI image environment locally:
# $ docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -it zjay437/rocksdb:0.5 bash
# option `--cap-add=SYS_PTRACE --security-opt seccomp=unconfined` is used to enable gdb to attach an existing process
- image:zjay437/rocksdb:0.6
linux-java-docker:
docker:
# This is the Docker Image used for building RocksJava releases, see: https://github.com/evolvedbinary/docker-rocksjava
- image:evolvedbinary/rocksjava:centos6_x64-be
jobs:
build-macos:
macos:
xcode:14.3.1
resource_class:macos.m1.medium.gen1
environment:
ROCKSDB_DISABLE_JEMALLOC:1# jemalloc cause env_test hang, disable it for now
steps:
- increase-max-open-files-on-macos
- install-gflags-on-macos
- pre-steps-macos
- run:ulimit -S -n `ulimit -H -n` && make V=1 J=16 -j16 all
- post-steps
build-macos-cmake:
macos:
xcode:14.3.1
resource_class:macos.m1.medium.gen1
parameters:
run_even_tests:
description:run even or odd tests, used to split tests to 2 groups
- run:ASSERT_STATUS_CHECKED=1 TEST_UINT128_COMPAT=1 ROCKSDB_MODIFY_NPHASH=1 LIB_MODE=static OPT="-DROCKSDB_NAMESPACE=alternative_rocksdb_ns" make V=1 -j24 check
- post-steps
build-linux-release:
executor:linux-docker
resource_class:2xlarge
steps:
- checkout# check out the code in the project directory
- run:make V=1 -j32 LIB_MODE=shared release
- run:ls librocksdb.so# ensure shared lib built
- run:./db_stress --version# ensure with gflags
- run:make clean
- run:make V=1 -j32 release
- run:ls librocksdb.a# ensure static lib built
- run:./db_stress --version# ensure with gflags
- run:make clean
- run:apt-get remove -y libgflags-dev
- run:make V=1 -j32 LIB_MODE=shared release
- run:ls librocksdb.so# ensure shared lib built
- run:if ./db_stress --version; then false; else true; fi# ensure without gflags
- run:make clean
- run:make V=1 -j32 release
- run:ls librocksdb.a# ensure static lib built
- run:if ./db_stress --version; then false; else true; fi# ensure without gflags
- post-steps
build-linux-release-rtti:
executor:linux-docker
resource_class:xlarge
steps:
- checkout# check out the code in the project directory
- run:USE_RTTI=1 DEBUG_LEVEL=0 make V=1 -j16 static_lib tools db_bench
- run:./db_stress --version# ensure with gflags
- run:make clean
- run:apt-get remove -y libgflags-dev
- run:USE_RTTI=1 DEBUG_LEVEL=0 make V=1 -j16 static_lib tools db_bench
- run:if ./db_stress --version; then false; else true; fi# ensure without gflags
build-linux-clang-no_test_run:
executor:linux-docker
resource_class:xlarge
steps:
- checkout# check out the code in the project directory
- run:CC=clang CXX=clang++ USE_CLANG=1 PORTABLE=1 make V=1 -j16 all
- post-steps
build-linux-clang10-asan:
executor:linux-docker
resource_class:2xlarge
steps:
- pre-steps
- run:COMPILE_WITH_ASAN=1 CC=clang-10 CXX=clang++-10 ROCKSDB_DISABLE_ALIGNED_NEW=1 USE_CLANG=1 make V=1 -j32 check# aligned new doesn't work for reason we haven't figured out
- post-steps
build-linux-clang10-mini-tsan:
executor:linux-docker
resource_class:2xlarge+
steps:
- pre-steps
- run:COMPILE_WITH_TSAN=1 CC=clang-13 CXX=clang++-13 ROCKSDB_DISABLE_ALIGNED_NEW=1 USE_CLANG=1 make V=1 -j32 check
- post-steps
build-linux-clang10-ubsan:
executor:linux-docker
resource_class:2xlarge
steps:
- pre-steps
- run:COMPILE_WITH_UBSAN=1 OPT="-fsanitize-blacklist=.circleci/ubsan_suppression_list.txt" CC=clang-10 CXX=clang++-10 ROCKSDB_DISABLE_ALIGNED_NEW=1 USE_CLANG=1 make V=1 -j32 ubsan_check# aligned new doesn't work for reason we haven't figured out
- post-steps
build-linux-valgrind:
executor:linux-docker
resource_class:2xlarge
steps:
- pre-steps
- run:PORTABLE=1 make V=1 -j32 valgrind_test
- post-steps
build-linux-clang10-clang-analyze:
executor:linux-docker
resource_class:2xlarge
steps:
- pre-steps
- run:CC=clang-10 CXX=clang++-10 ROCKSDB_DISABLE_ALIGNED_NEW=1 CLANG_ANALYZER="/usr/bin/clang++-10" CLANG_SCAN_BUILD=scan-build-10 USE_CLANG=1 make V=1 -j32 analyze# aligned new doesn't work for reason we haven't figured out. For unknown, reason passing "clang++-10" as CLANG_ANALYZER doesn't work, and we need a full path.
- run:make V=1 -j8 -k check-headers# could be moved to a different build
- post-steps
build-linux-gcc-7-with-folly:
executor:linux-docker
resource_class:2xlarge
steps:
- pre-steps
- setup-folly
- build-folly
- run: USE_FOLLY=1 LIB_MODE=static CC=gcc-7 CXX=g++-7 V=1 make -j32 check # TODO:LIB_MODE only to work around unresolved linker failures
- post-steps
build-linux-gcc-7-with-folly-lite-no-test:
executor:linux-docker
resource_class:2xlarge
steps:
- pre-steps
- setup-folly
- run:USE_FOLLY_LITE=1 CC=gcc-7 CXX=g++-7 V=1 make -j32 all
- post-steps
build-linux-gcc-8-no_test_run:
executor:linux-docker
resource_class:2xlarge
steps:
- pre-steps
- run:CC=gcc-8 CXX=g++-8 V=1 make -j32 all
- post-steps
build-linux-cmake-with-folly-coroutines:
executor:linux-docker
resource_class:2xlarge
environment:
CC:gcc-10
CXX:g++-10
steps:
- pre-steps
- setup-folly
- build-folly
- run:(mkdir build && cd build && cmake -DUSE_COROUTINES=1 -DWITH_GFLAGS=1 -DROCKSDB_BUILD_SHARED=0 .. && make V=1 -j20 && ctest -j20)
- post-steps
build-linux-gcc-10-cxx20-no_test_run:
executor:linux-docker
resource_class:2xlarge
steps:
- pre-steps
- run:CC=gcc-10 CXX=g++-10 V=1 ROCKSDB_CXX_STANDARD=c++20 make -j32 all
- post-steps
build-linux-gcc-11-no_test_run:
executor:linux-docker
resource_class:2xlarge
steps:
- pre-steps
- run: LIB_MODE=static CC=gcc-11 CXX=g++-11 V=1 make -j32 all microbench # TODO:LIB_MODE only to work around unresolved linker failures
- post-steps
build-linux-clang-13-no_test_run:
executor:linux-docker
resource_class:2xlarge
steps:
- pre-steps
- run:CC=clang-13 CXX=clang++-13 USE_CLANG=1 make -j32 all microbench
- post-steps
# Ensure ASAN+UBSAN with folly, and full testsuite with clang 13
build-linux-clang-13-asan-ubsan-with-folly:
executor:linux-docker
resource_class:2xlarge
steps:
- pre-steps
- setup-folly
- build-folly
- run: CC=clang-13 CXX=clang++-13 LIB_MODE=static USE_CLANG=1 USE_FOLLY=1 COMPILE_WITH_UBSAN=1 COMPILE_WITH_ASAN=1 make -j32 check # TODO:LIB_MODE only to work around unresolved linker failures
- post-steps
# This job is only to make sure the microbench tests are able to run, the benchmark result is not meaningful as the CI host is changing.
> NOTE: Entries for next release do not go here. Follow instructions in `unreleased_history/README.txt`
## 10.10.0 (12/16/2025)
### Bug Fixes
* Fixed a bug in best-efforts recovery that causes use-after-free crashes when accessing SST files that were cached during the recovery.
* Fix resumable compaction incorrectly allowing resumption from a truncated range deletion that is not well handled currently.
* Fixed a bug in `PosixRandomFileAccess` IO uring submission queue ownership & management. Fix eliminates the false positive 'Bad cqe data' IO errors in `PosixRandomFileAccess::MultiRead` when interleaved with `PosixRandomFileAccess::ReadAsync` on the same thread.
## 10.9.0 (11/21/2025)
### New Features
* Added an auto-tuning feature for DB manifest file size that also (by default) improves the safety of existing configurations in case `max_manifest_file_size` is repeatedly exceeded. The new recommendation is to set `max_manifest_file_size` to something small like 1MB and tune `max_manifest_space_amp_pct` as needed to balance write amp and space amp in the manifest. Refer to comments on those options in `DBOptions` for details. Both options are (now) mutable.
* Added a new API to support option migration for multiple column families
* Added new option target_file_size_is_upper_bound that makes most compaction output SST files come close to the target file size without exceeding it, rather than commonly exceeding it by some fraction (current behavior). For now the new behavior is off by default, but we expect to enable it by default in the future.
* Add a new option allow_trivial_move in CompactionOptions to allow CompactFiles to perform trivial move if possible. By default the flag of allow_trivial_move is false, so it preserve the original behavior.
### Public API Changes
* To reduce risk of ODR violations or similar, `ROCKSDB_USING_THREAD_STATUS` has been removed from public headers and replaced with static `const bool ThreadStatus::kEnabled`. Some other uses of conditional compilation have been removed from public API headers to reduce risk of ODR violations or other issues.
### Behavior Changes
* PosixWritableFile now repositions the seek pointer to the new end of file after a call to Truncate.
* Updated standalone range deletion L0 file compaction behavior to avoid compacting with any newer L0 files (which is expensive and not useful).
### Bug Fixes
* Fix a bug where compaction with range deletion can persist kTypeMaxValid in MANIFEST as file metadata. kTypeMaxValid is not supposed to be persisted and can change as new value types are introduced. This can cause a forward compatibility issue where older versions of RocksDB don't recognize kTypeMaxValid from newer versions. A new placeholder value type kTypeTruncatedRangeDeletionSentinel is also introduced to replace kTypeMaxValid when reading existing SST files' metadata from MANIFEST. This allows us to strengthen some checks to avoid using kTypeMaxValid in the future.
* Fixed a bug where `DB::GetSortedWalFiles()` could hang when waiting for a purge operation that found nothing to do (potentially triggered by iterator release, flush, compaction, etc.).
* Fixed a bug in MultiScan where `max_sequential_skip_in_iterations` could cause the iterator to seek backward to already-unpinned blocks when the same user key spans multiple data blocks, leading to assertion failures or seg fault.
* Fixed a bug for `WAL_ttl_seconds > 0` use cases where the newest archived WAL files could be incorrectly deleted when the system clock moved backwards.
### Performance Improvements
* Added optimization that allowed for the asynchronous prefetching of all data outlined in a multiscan iterator. This optimization was applied to the level iterator, which prefetches all data through each of the block-based iterators.
## 10.8.0 (10/21/2025)
### New Features
* Add kFSPrefetch to FSSupportedOps enum to allow file systems to indicate prefetch support capability, avoiding unnecessary prefetch system calls on file systems that don't support them.
* Added experimental support `OpenAndCompactOptions::allow_resumption` for resumable compaction that persists progress during `OpenAndCompact()`, allowing interrupted compactions to resume from the last progress persitence. The default behavior is to not persist progress.
### Public API Changes
* Allow specifying output temperature in CompactionOptions
* Added `DB::FlushWAL(const FlushWALOptions&)` as an alternative to `DB::FlushWAL(bool sync)`, where `FlushWALOptions` includes a new `rate_limiter_priority` field (default `Env::IO_TOTAL`) that allows rate limiting and priority passing of manual WAL flush's IO operations.
* The MultiScan API contract is updated. After a multi scan range got prepared with Prepare API call, the following seeks must seek the start of each prepared scan range in order. In addition, when limit is set, upper bound must be set to the same value of limit before each seek
### Behavior Changes
* `kChangeTemperature` FIFO compaction will now honor `compaction_target_temp` to all levels regardless of `cf_options::last_level_temperature`
* Allow UDIs with a non BytewiseComparator
### Bug Fixes
* Fix incorrect MultiScan seek error status due to bugs in handling range limit falling between adjacent SST files key range.
* Fix a bug in Page unpinning in MultiScan
### Performance Improvements
* Fixed a performance regression in LZ4 compression that started in version 10.6.0
## 10.7.0 (09/19/2025)
### New Features
* Add the fail_if_no_udi_on_open flag in BlockBasedTableOption to control whether a missing user defined index block in a SST is a hard error or not.
* A new flag memtable_verify_per_key_checksum_on_seek is added to AdvancedColumnFamilyOptions. When it is enabled, it will validate key checksum along the binary search path on skiplist based memtable during seek operation.
* Introduce option MultiScanArgs::use_async_io to enable asynchronous I/O during MultiScan, instead of waiting for I/O to be done in Prepare().
* Add new option `MultiScanArgs::max_prefetch_size` that limits the memory usage of per file pinning of prefetched blocks.
* Improved `sst_dump` by allowing standalone file and directory arguments without `--file=`. Also added new options and better output for `sst_dump --command=recompress`. See `sst_dump --help`
### Public API Changes
* HyperClockCache with no `estimated_entry_charge` is now production-ready and is the preferred block cache implementation vs. LRUCache. Please consider updating your code to minimize the risk of hitting performance bottlenecks or anomalies from LRUCache. See cache.h for more detail.
* RocksDB now requires a C++20 compatible compiler (GCC >= 11, Clang >= 10, Visual Studio >= 2019), including for any code using RocksDB headers.
* MultiScanArgs used to have a default constructor with default parameter of BytewiseComparator. Now it always requires Comparator in its constructor.
### Behavior Changes
* The default provided block cache implementation is now HyperClockCache instead of LRUCache, when `block_cache` is nullptr (default) and `no_block_cache==false` (default). We recommend explicitly creating a HyperClockCache block cache based on memory budget and sharing it across all column families and even DB instances. This change could expose previously hidden memory or resource leaks.
### Bug Fixes
* Reported numbers for compaction and flush CPU usage now include time spent by parallel compression worker threads. This now means compaction/flush CPU usage could exceed the wall clock time.
* Fix a race condition in FIFO size-based compaction where concurrent threads could select the same non-L0 file, causing assertion failures in debug builds or "Cannot delete table file from LSM tree" errors in release builds.
* Fix a bug in RocksDB MultiScan with UDI when one of the scan ranges is determined to be empty by the UDI, which causes incorrect results.
### Performance Improvements
* Add a new table property "rocksdb.key.smallest.seqno" which records the smallest sequence number of all keys in file. It makes ingesting DB generated files faster by
avoiding scanning the whole file to find the smallest sequence number.
* Add a new experimental PerKeyPointLockManager to improve efficiency under high lock contention. PointLockManager was not efficient when there is high write contention on same key, as it uses a single conditional variable per lock stripe. PerKeyPointLockManager uses per thread conditional variable supporting fifo order. Although this is an experimental feature. By default, it is disabled. A new boolean flag TransactionDBOptions::use_per_key_point_lock_mgr is added to optionally enable it. Search the flag in code for more info.
Together, a new configuration TransactionOptions::deadlock_timeout_us is added, which allows the transaction to wait for a short period before perform deadlock detection. When the workload has low lock contention, the deadlock_timeout_us can be configured to be slightly higher than average transaction execution time, so that transaction would likely be able to take the lock before deadlock detection is performed when it is waiting for a lock. This allows transaction to reduce CPU cost on performing deadlock detection, which could be expensive in CPU time. When the workload has high lock contention, the deadlock_timeout_us can be configured to 0, so that transaction would perform deadlock detection immediately. By default the value is 0 to keep the behavior same as before.
* Majorly improved CPU efficiency and scalability of parallel compression (`CompressionOptions::parallel_threads` > 1), though this efficiency improvement makes parallel compression currently incompatible with UserDefinedIndex and with old setting of `decouple_partitioned_filters=false`. Parallel compression is now considered a production-ready feature. Maximum performance is available with `-DROCKSDB_USE_STD_SEMAPHORES` at compile time, but this is not currently recommended because of reported bugs in implementations of `std::counting_semaphore`/`binary_semaphore`.
## 10.6.0 (08/22/2025)
### New Features
* Introduce column family option `cf_allow_ingest_behind`. This option aims to replace `DBOptions::allow_ingest_behind` to enable ingest behind at the per-CF level. `DBOptions::allow_ingest_behind` is deprecated.
* Introduce `MultiScanArgs::io_coalesce_threshold` to allow a configurable IO coalescing threshold.
### Public API Changes
* `IngestExternalFileOptions::allow_db_generated_files` now allows files ingestion of any DB generated SST file, instead of only the ones with all keys having sequence number 0.
* `decouple_partitioned_filters = true` is now the default in BlockBasedTableOptions.
* GetTtl() API is now available in TTL DB
* Minimum supported version of LZ4 library is now 1.7.0 (r129 from 2015)
* Some changes to experimental Compressor and CompressionManager APIs
* A new Filesystem::SyncFile function is added for syncing a file that was already written, such as on file ingestion. The default implementation matches previous RocksDB behavior: re-open the file for read-write, sync it, and close it. We recommend overriding for FileSystems that do not require syncing for crash recovery or do not handle (well) re-opening for writes.
### Behavior Changes
* When `allow_ingest_behind` is enabled, compaction will no longer drop tombstones based on the absence of underlying data. Tombstones will be preserved to apply to ingested files.
### Bug Fixes
* Files in dropped column family won't be returned to the caller upon successful, offline MANIFEST iteration in `GetFileChecksumsFromCurrentManifest`.
* Fix a bug in MultiScan that causes it to fall back to a normal scan when dictionary compression is enabled.
* Fix a crash in iterator Prepare() when fill_cache=false
* Fix a bug in MultiScan where incorrect results can be returned when a Scan's range is across multiple files.
* Fixed a bug in remote compaction that may mistakenly delete live SST file(s) during the cleanup phase when no keys survive the compaction (all expired)
* Allow a user defined index to be configured from a string.
* Make the User Defined Index interface consistently use the user key format, fixing the previous mixed usage of internal and user key.
### Performance Improvements
* Small improvement to CPU efficiency of compression using built-in algorithms, and a dramatic efficiency improvement for LZ4HC, based on reusing data structures between invocations.
## 10.5.0 (07/18/2025)
### Public API Changes
* DB option skip_checking_sst_file_sizes_on_db_open is deprecated, in favor of validating file size in parallel in a thread pool, when db is opened. When DB is opened, with paranoid check enabled, a file with the wrong size would fail the DB open. With paranoid check disabled, the DB open would succeed, the column family with the corrupted file would not be read or write, while the other healthy column families could be read and write normally. When max_open_files option is not set to -1, only a subset of the files will be opened and checked. The rest of the files will be opened and checked when they are accessed.
### Behavior Changes
* PessimisticTransaction::GetWaitingTxns now returns waiting transaction information even if the current transaction has timed out. This allows the information to be surfaced to users for debugging purposes once it is known that the timeout has occurred.
* A new API GetFileSize is added to FSRandomAccessFile interface class. It uses fstat vs stat on the posix implementation which is more efficient. Caller could use it to get file size faster. This function might be required in the future for FileSystem implementation outside of the RocksDB code base.
* RocksDB now triggers eligible compactions every 12 hours when periodic compaction is configured. This solves a limitation of the compaction trigger mechanism, which would only trigger compaction after specific events like flush, compaction, or SetOptions.
### Bug Fixes
* Fix a bug in BackupEngine that can crash backup due to a null FSWritableFile passed to WritableFileWriter.
* Fix DB::NewMultiScan iterator to respect the scan upper bound specified in ScanOptions
### Performance Improvements
* Optimized MultiScan using BlockBasedTable to coalesce I/Os and prefetch all data blocks.
## 10.4.0 (06/20/2025)
### New Features
* Add a new CF option `memtable_avg_op_scan_flush_trigger` that supports triggering memtable flush when an iterator scans through an expensive range of keys, with the average number of skipped keys from the active memtable exceeding the threshold.
* Vector based memtable now supports concurrent writers (DBOptions::allow_concurrent_memtable_write) #13675.
* Add new experimental `TransactionOptions::large_txn_commit_optimize_byte_threshold` to enable optimizations for large transaction commit by transaction batch data size.
* Add a new option `CompactionOptionsUniversal::reduce_file_locking` and if it's true, auto universal compaction picking will adjust to minimize locking of input files when bottom priority compactions are waiting to run. This can increase the likelihood of existing L0s being selected for compaction, thereby improving write stall and reducing read regression.
* Add new `format_version=7` to aid experimental support of custom compression algorithms with CompressionManager and block-based table. This format version includes changing the format of `TableProperties::compression_name`.
### Public API Changes
* Change NewExternalTableFactory to return a unique_ptr instead of shared_ptr.
* Add an optional min file size requirement for deletion triggered compaction. It can be specified when creating `CompactOnDeletionCollectorFactory`.
### Behavior Changes
* `TransactionOptions::large_txn_commit_optimize_threshold` now has default value 0 for disabled. `TransactionDBOptions::txn_commit_bypass_memtable_threshold` now has no effect on transactions.
### Bug Fixes
* Fix a bug where CreateColumnFamilyWithImport() could miss the SST file for the memtable flush it triggered. The exported CF then may not contain the updates in the memtable when CreateColumnFamilyWithImport() is called.
* Fix iterator operations returning NotImplemented status if disallow_memtable_writes and paranoid_memory_checks CF options are both set.
* Fixed handling of file checksums in IngestExternalFile() to allow providing checksums using recognized but not necessarily the DB's preferred checksum function, to ease migration between checksum functions.
## 10.3.0 (05/17/2025)
### New Features
* Add new experimental `CompactionOptionsFIFO::allow_trivial_copy_when_change_temperature` along with `CompactionOptionsFIFO::trivial_copy_buffer_size` to allow optimizing FIFO compactions with tiering when kChangeTemperature to move files from source tier FileSystem to another tier FileSystem via trivial and direct copying raw sst file instead of reading thru the content of the SST file then rebuilding the table files.
* Add a new field to Compaction Stats in LOG files for the pre-compression size written to each level.
* Add new experimental `TransactionOptions::large_txn_commit_optimize_threshold` to enable optimizations for large transaction commit with per transaction threshold. `TransactionDBOptions::txn_commit_bypass_memtable_threshold` is deprecated in favor of this transaction option.
* [internal team use only] Allow an application-defined `request_id` to be passed to RocksDB and propagated to the filesystem via IODebugContext
### Bug Fixes
* Fix a bug where transaction lock upgrade can incorrectly fail with a Deadlock status. This happens when a transaction has a non-zero timeout and tries to upgrade a shared lock that is also held by another transaction.
* Pass wrapped WritableFileWriter pointer to ExternalTableBuilder so that the file checksum can be correctly calculated and returned by SstFileWriter for external table files.
* Fix an infinite-loop bug in transaction locking. This can happen if a transaction reaches lock limit and its time out expires before it attempts to wait for it.
* Fixed a potential data race with `CompressionOptions::parallel_threads > 1` and a `TablePropertiesCollector` overriding `BlockAdd()`.
## 10.2.0 (04/21/2025)
### New Features
* Provide histogram stats `COMPACTION_PREFETCH_BYTES` to measure number of bytes for RocksDB's prefetching (as opposed to file
system's prefetch) on SST file during compaction read
* A new API DB::GetNewestUserDefinedTimestamp is added to return the newest user defined timestamp seen in a column family
* Introduce API `IngestWriteBatchWithIndex()` for ingesting updates into DB while bypassing memtable writes. This improves performance when writing a large write batch to the DB.
* Add a new CF option `memtable_op_scan_flush_trigger` that triggers a flush of the memtable if an iterator's Seek()/Next() scans over a certain number of invisible entries from the memtable.
### Public API Changes
* AdvancedColumnFamilyOptions.max_write_buffer_number_to_maintain is deleted. It's deprecated since introduction of a better option max_write_buffer_size_to_maintain since RocksDB 6.5.0.
* Added arbitrary string map for additional options to be overridden for remote compactions
* The fail_if_options_file_error option in DBOptions has been removed. The behavior now is to always return failure in any API that fails to persist the OPTIONS file.
### Behavior Changes
* Make stats `PREFETCH_BYTES_USEFUL`, `PREFETCH_HITS`, `PREFETCH_BYTES` only account for prefetching during user initiated scan
### Bug Fixes
* Fix a bug in Posix file system that the FSWritableFile created via `FileSystem::ReopenWritableFile` internally does not track the correct file size.
* Fix a bug where tail size of remote compaction output is not persisted in primary db's manifest
## 10.1.0 (03/24/2025)
### New Features
* Added a new `DBOptions.calculate_sst_write_lifetime_hint_set` setting that allows to customize which compaction styles SST write lifetime hint calculation is allowed on. Today RocksDB supports only two modes `kCompactionStyleLevel` and `kCompactionStyleUniversal`.
* Add a new field `num_l0_files` in `CompactionJobInfo` about the number of L0 files in the CF right before and after the compaction
* Added per-key-placement feature in Remote Compaction
* Implemented API DB::GetPropertiesOfTablesByLevel that retrieves table properties for files in each LSM tree level
### Public API Changes
* `GetAllKeyVersions()` now interprets empty slices literally, as valid keys, and uses new `OptSlice` type default value for extreme upper and lower range limits.
* `DeleteFilesInRanges()` now takes `RangeOpt` which is based on `OptSlice`. The overload taking `RangePtr` is deprecated.
* Add an unordered map of name/value pairs, ReadOptions::property_bag, to pass opaque options through to an external table when creating an Iterator.
* Introduced CompactionServiceJobStatus::kAborted to allow handling aborted scenario in Schedule(), Wait() or OnInstallation() APIs in Remote Compactions.
* format\_version < 2 in BlockBasedTableOptions is no longer supported for writing new files. Support for reading such files is deprecated and might be removed in the future. `CompressedSecondaryCacheOptions::compress_format_version == 1` is also deprecated.
### Behavior Changes
* `ldb` now returns an error if the specified `--compression_type` is not supported in the build.
* MultiGet with snapshot and ReadOptions::read_tier = kPersistedTier will now read a consistent view across CFs (instead of potentially reading some CF before and some CF after a flush).
* CreateColumnFamily() is no longer allowed on a read-only DB (OpenForReadOnly())
### Bug Fixes
* Fixed stats for Tiered Storage with preclude_last_level feature
## 10.0.0 (02/21/2025)
### New Features
* Introduced new `auto_refresh_iterator_with_snapshot` opt-in knob that (when enabled) will periodically release obsolete memory and storage resources for as long as the iterator is making progress and its supplied `read_options.snapshot` was initialized with non-nullptr value.
* Added the ability to plug-in a custom table reader implementation. See include/rocksdb/external_table_reader.h for more details.
* Experimental feature: RocksDB now supports FAISS inverted file based indices via the secondary indexing framework. Applications can use FAISS secondary indices to automatically quantize embeddings and perform K-nearest-neighbors similarity searches. See `FaissIVFIndex` and `SecondaryIndex` for more details. Note: the FAISS integration currently requires using the BUCK build.
* Add new DB property `num_running_compaction_sorted_runs` that tracks the number of sorted runs being processed by currently running compactions
* Experimental feature: added support for simple secondary indices that index the specified column as-is. See `SimpleSecondaryIndex` and `SecondaryIndex` for more details.
* Added new `TransactionDBOptions::txn_commit_bypass_memtable_threshold`, which enables optimized transaction commit (see `TransactionOptions::commit_bypass_memtable`) when the transaction size exceeds a configured threshold.
### Public API Changes
* Updated the query API of the experimental secondary indexing feature by removing the earlier `SecondaryIndex::NewIterator` virtual and adding a `SecondaryIndexIterator` class that can be utilized by applications to find the primary keys for a given search target.
* Added back the ability to leverage the primary key when building secondary index entries. This involved changes to the signatures of `SecondaryIndex::GetSecondary{KeyPrefix,Value}` as well as the addition of a new method `SecondaryIndex::FinalizeSecondaryKeyPrefix`. See the API comments for more details.
* Minimum supported version of ZSTD is now 1.4.0, for code simplification. Obsolete `CompressionType``kZSTDNotFinalCompression` is also removed.
### Behavior Changes
* `VerifyBackup` in `verify_with_checksum`=`true` mode will now evaluate checksums in parallel. As a result, unlike in case of original implementation, the API won't bail out on a very first corruption / mismatch and instead will iterate over all the backup files logging success / _degree_of_failure_ for each.
* Reversed the order of updates to the same key in WriteBatchWithIndex. This means if there are multiple updates to the same key, the most recent update is ordered first. This affects the output of WBWIIterator. When WriteBatchWithIndex is created with `overwrite_key=true`, this affects the output only if Merge is used (#13387).
* Added support for Merge operations in transactions using option `TransactionOptions::commit_bypass_memtable`.
### Bug Fixes
* Fixed GetMergeOperands() API in ReadOnlyDB and SecondaryDB
* Fix a bug in `GetMergeOperands()` that can return incorrect status (MergeInProgress) and incorrect number of merge operands. This can happen when `GetMergeOperandsOptions::continue_cb` is set, both active and immutable memtables have merge operands and the callback stops the look up at the immutable memtable.
## 9.11.0 (01/17/2025)
### New Features
* Introduce CancelAwaitingJobs() in CompactionService interface which will allow users to implement cancellation of running remote compactions from the primary instance
* Experimental feature: RocksDB now supports defining secondary indices, which are automatically maintained by the storage engine. Secondary indices provide a new customization point: applications can provide their own by implementing the new `SecondaryIndex` interface. See the `SecondaryIndex` API comments for more details. Note: this feature is currently only available in conjunction with write-committed pessimistic transactions, and `Merge` is not yet supported.
* Provide a new option `track_and_verify_wals` to track and verify various information about WAL during WAL recovery. This is intended to be a better replacement to `track_and_verify_wals_in_manifest`.
### Public API Changes
* Add `io_buffer_size` to BackupEngineOptions to enable optimal configuration of IO size
* Clean up all the references to `random_access_max_buffer_size`, related rules and all the clients wrappers. This option has been officially deprecated in 5.4.0.
* Add `file_ingestion_nanos` and `file_ingestion_blocking_live_writes_nanos` in PerfContext to observe file ingestions
* Offer new DB::Open and variants that use `std::unique_ptr<DB>*` output parameters and deprecate the old versions that use `DB**` output parameters.
* The DB::DeleteFile API is officially deprecated.
### Behavior Changes
* For leveled compaction, manual compaction (CompactRange()) will be more strict about keeping compaction size under `max_compaction_bytes`. This prevents overly large compactions in some cases (#13306).
* Experimental tiering options `preclude_last_level_data_seconds` and `preserve_internal_time_seconds` are now mutable with `SetOptions()`. Some changes to handling of these features along with long-lived snapshots and range deletes made this possible.
### Bug Fixes
* Fix a longstanding major bug with SetOptions() in which setting changes can be quietly reverted.
## 9.10.0 (12/12/2024)
### New Features
* Introduce `TransactionOptions::commit_bypass_memtable` to enable transaction commit to bypass memtable insertions. This can be beneficial for transactions with many operations, as it reduces commit time that is mostly spent on memtable insertion.
### Public API Changes
* Deprecated Remote Compaction APIs (StartV2, WaitForCompleteV2) are completely removed from the codebase
### Behavior Changes
* DB::KeyMayExist() now follows its function comment, which means `value` parameter can be null, and it will be set only if `value_found` is passed in.
### Bug Fixes
* Fix the issue where compaction incorrectly drops a key when there is a snapshot with a sequence number of zero.
* Honor ConfigOptions.ignore_unknown_options in ParseStruct()
### Performance Improvements
* Enable reuse of file system allocated buffer for synchronous prefetching.
* In buffered IO mode, try to align writes on power of 2 if checksum handoff is not enabled for the file type being written.
## 9.9.0 (11/18/2024)
### New Features
* Multi-Column-Family-Iterator (CoalescingIterator/AttributeGroupIterator) is no longer marked as experimental
* Adds a new table property "rocksdb.newest.key.time" which records the unix timestamp of the newest key. Uses this table property for FIFO TTL and temperature change compaction.
### Public API Changes
* Added a new API `Transaction::GetAttributeGroupIterator` that can be used to create a multi-column-family attribute group iterator over the specified column families, including the data from both the transaction and the underlying database. This API is currently supported for optimistic and write-committed pessimistic transactions.
* Added a new API `Transaction::GetCoalescingIterator` that can be used to create a multi-column-family coalescing iterator over the specified column families, including the data from both the transaction and the underlying database. This API is currently supported for optimistic and write-committed pessimistic transactions.
### Behavior Changes
* `BaseDeltaIterator` now honors the read option `allow_unprepared_value`.
### Bug Fixes
* `BaseDeltaIterator` now calls `PrepareValue` on the base iterator in case it has been created with the `allow_unprepared_value` read option set. Earlier, such base iterators could lead to incorrect values being exposed from `BaseDeltaIterator`.
* Fix a leak of obsolete blob files left open until DB::Close(). This bug was introduced in version 9.4.0.
* Fix missing cases of corruption retry during DB open and read API processing.
* Fix a bug for transaction db with 2pc where an old WAL may be retained longer than needed (#13127).
* Fix leaks of some open SST files (until `DB::Close()`) that are written but never become live due to various failures. (We now have a check for such leaks with no outstanding issues.)
* Fix a bug for replaying WALs for WriteCommitted transaction DB when its user-defined timestamps setting is toggled on/off between DB sessions.
### Performance Improvements
* Fix regression in issue #12038 due to `Options::compaction_readahead_size` greater than `max_sectors_kb` (i.e, largest I/O size that the OS issues to a block device defined in linux)
## 9.8.0 (10/25/2024)
### New Features
* All non-`block_cache` options in `BlockBasedTableOptions` are now mutable with `DB::SetOptions()`. See also Bug Fixes below.
@@ -35,7 +319,7 @@
* In FIFO compaction, compactions for changing file temperature (configured by option `file_temperature_age_thresholds`) will compact one file at a time, instead of merging multiple eligible file together (#13018).
* Support ingesting db generated files using hard link, i.e. IngestExternalFileOptions::move_files/link_files and IngestExternalFileOptions::allow_db_generated_files.
* Add a new file ingestion option `IngestExternalFileOptions::link_files` to hard link input files and preserve original files links after ingestion.
* DB::Close now untracks files in SstFileManager, making avaialble any space used
* DB::Close now untracks files in SstFileManager, making available any space used
by them. Prior to this change they would be orphaned until the DB is re-opened.
* Remove the default `WritableFile::GetFileSize` and `FSWritableFile::GetFileSize` implementation that returns 0 and make it pure virtual, so that subclasses are enforced to explicitly provide an implementation.
* `sst_dump --command=check` now compares the number of records in a table with `num_entries` in table property, and reports corruption if there is a mismatch. API `SstFileDumper::ReadSequential()` is updated to optionally do this verification. (#12322)
* `rocksdb.blobdb.blob.file.write.micros` expands to also measure time writing the header and footer. Therefore the COUNT may be higher and values may be smaller than before. For stacked BlobDB, it no longer measures the time of explictly flushing blob file.
* `rocksdb.blobdb.blob.file.write.micros` expands to also measure time writing the header and footer. Therefore the COUNT may be higher and values may be smaller than before. For stacked BlobDB, it no longer measures the time of explicitly flushing blob file.
* Files will be compacted to the next level if the data age exceeds periodic_compaction_seconds except for the last level.
* Reduced the compaction debt ratio trigger for scheduling parallel compactions
* For leveled compaction with default compaction pri (kMinOverlappingRatio), files marked for compaction will be prioritized over files not marked when picking a file from a level for compaction.
@@ -323,7 +607,7 @@ want to continue to use force enabling, they need to explicitly pass a `true` to
### Behavior Changes
* During off-peak hours defined by `daily_offpeak_time_utc`, the compaction picker will select a larger number of files for periodic compaction. This selection will include files that are projected to expire by the next off-peak start time, ensuring that these files are not chosen for periodic compaction outside of off-peak hours.
* If an error occurs when writing to a trace file after `DB::StartTrace()`, the subsequent trace writes are skipped to avoid writing to a file that has previously seen error. In this case, `DB::EndTrace()` will also return a non-ok status with info about the error occured previously in its status message.
* If an error occurs when writing to a trace file after `DB::StartTrace()`, the subsequent trace writes are skipped to avoid writing to a file that has previously seen error. In this case, `DB::EndTrace()` will also return a non-ok status with info about the error occurred previously in its status message.
* Deleting stale files upon recovery are delegated to SstFileManger if available so they can be rate limited.
* Make RocksDB only call `TablePropertiesCollector::Finish()` once.
* When `WAL_ttl_seconds > 0`, we now process archived WALs for deletion at least every `WAL_ttl_seconds / 2` seconds. Previously it could be less frequent in case of small `WAL_ttl_seconds` values when size-based expiration (`WAL_size_limit_MB > 0 `) was simultaneously enabled.
@@ -1111,7 +1395,7 @@ Note: The next release will be major release 7.0. See https://github.com/faceboo
### Public API change
* Extend WriteBatch::AssignTimestamp and AssignTimestamps API so that both functions can accept an optional `checker` argument that performs additional checking on timestamp sizes.
* Introduce a new EventListener callback that will be called upon the end of automatic error recovery.
* Add IncreaseFullHistoryTsLow API so users can advance each column family's full_history_ts_low seperately.
* Add IncreaseFullHistoryTsLow API so users can advance each column family's full_history_ts_low separately.
* Add GetFullHistoryTsLow API so users can query current full_history_low value of specified column family.
The Bing search engine from Microsoft uses RocksDB as the storage engine for its web data platform: https://blogs.bing.com/Engineering-Blog/october-2021/RocksDB-in-Microsoft-Bing
## LinkedIn
Two different use cases at Linkedin are using RocksDB as a storage engine:
1. [Venice](https://venicedb.org/) is a derived data platform using RocksDB as its storage engine. It is LinkedIn's ML feature store, powering thousands of recommender use cases, including the Feed, Video recommendations, and People You May Know.
2. LinkedIn's follow feed for storing user's activities. Check out the blog post: https://engineering.linkedin.com/blog/2016/03/followfeed--linkedin-s-feed-made-faster-and-smarter
3. Apache Samza, open source framework for stream processing.
1. LinkedIn's follow feed for storing user's activities. Check out the blog post: https://engineering.linkedin.com/blog/2016/03/followfeed--linkedin-s-feed-made-faster-and-smarter
2. Apache Samza, open source framework for stream processing
Learn more about those use cases in a Tech Talk by Ankit Gupta and Naveen Somasundaram: http://www.youtube.com/watch?v=plqVp_OnSzg
Learn more about LinkedIn's follow feed and Apache Samza in a Tech Talk by Ankit Gupta and Naveen Somasundaram: http://www.youtube.com/watch?v=plqVp_OnSzg
## Yahoo
Yahoo is using RocksDB as a storage engine for their biggest distributed data store Sherpa. Learn more about it here: http://yahooeng.tumblr.com/post/120730204806/sherpa-scales-new-heights
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.