Compare commits

...

20 Commits

Author SHA1 Message Date
Changyu Bi 2732f11849 Update version.h to 8.11.5 and update HISTORY.md 2025-11-26 10:41:15 -08:00
Changyu Bi 71f9e62906 Backport new value types to 8.11.fb (#14145)
* Backport new value types
2025-11-26 10:31:09 -08:00
Andrew Kryczka 5c2be544f5 update HISTORY.md and version.h for 8.11.4 2024-04-09 12:40:06 -07:00
Andrew Kryczka 4db41ec2ff 12404 history entry 2024-04-09 12:39:22 -07:00
Andrew Kryczka aac648c1b6 12474 history entry 2024-04-09 12:38:56 -07:00
Radek Hubner e5907aa96a Fix exception on RocksDB.getColumnFamilyMetaData() (#12474)
Summary:
https://github.com/facebook/rocksdb/issues/12466 reported a bug when `RocksDB.getColumnFamilyMetaData()` is called on an existing database(With files stored on disk). As neilramaswamy mentioned, this was caused by https://github.com/facebook/rocksdb/issues/11770 where the signature of `SstFileMetaData` constructor was changed, but JNI code wasn't updated.

This PR fix JNI code, and also properly populate `fileChecksum` on `SstFileMetaData`.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/12474

Reviewed By: jowlyzhang

Differential Revision: D55811808

Pulled By: ajkr

fbshipit-source-id: 2ab156f41eaf4a4f30c49e6df421b61e8451230e
2024-04-09 12:28:27 -07:00
Radek Hubner 388e9f3564 Fix regression for Javadoc jar build (#12404)
Summary:
https://github.com/facebook/rocksdb/issues/12371 Introduced regression not defining dependency between `create_javadoc`  and `rocksdb_javadocs_jar` build targets.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/12404

Reviewed By: pdillinger

Differential Revision: D54516862

Pulled By: ajkr

fbshipit-source-id: 785a99b2caf979395ae0de60e40e7d1b93059adb
2024-03-15 08:12:44 -07:00
Peter Dillinger f6d4775ed3 Fix windows build and CI (#12426)
Summary:
Issue https://github.com/facebook/rocksdb/issues/12421 describes a regression in the migration from CircleCI to GitHub Actions in which failing build steps no longer fail Windows CI jobs. In GHA with pwsh (new preferred powershell command), only the last non-builtin command (or something like that) affects the overall success/failure result, and failures in external commands do not exit the script, even with `$ErrorActionPreference = 'Stop'` and `$PSNativeCommandErrorActionPreference = $true`. Switching to `powershell` causes some obscure failure (not seen in CircleCI) about the `-Lo` option to `curl`.

Here we work around this using the only reasonable-but-ugly way known: explicitly check the result after every non-trivial build step. This leaves us highly susceptible to future regressions with unchecked build steps in the future, but a clean solution is not known.

This change also fixes the build errors that were allowed to creep in because of the CI regression. Also decreased the unnecessarily long running time of DBWriteTest.WriteThreadWaitNanosCounter.

For background, this problem explicitly contradicts GitHub's documentation, and GitHub has known about the problem for more than a year, with no evidence of caring or intending to fix. https://github.com/actions/runner-images/issues/6668 Somehow CircleCI doesn't have this problem. And even though cmd.exe and powershell have been perpetuating DOS-isms for decades, they still seem to be a somewhat active "hot mess" when it comes to sensible, consistent, and documented behavior.

Fixes https://github.com/facebook/rocksdb/issues/12421

A history of some things I tried in development is here: https://github.com/facebook/rocksdb/compare/main...pdillinger:rocksdb:debug_windows_ci_orig

Pull Request resolved: https://github.com/facebook/rocksdb/pull/12426

Test Plan: CI, including https://github.com/facebook/rocksdb/issues/12434 where I have temporarily enabled other Windows builds on PR with this change

Reviewed By: cbi42

Differential Revision: D54903698

Pulled By: pdillinger

fbshipit-source-id: 116bcbebbbf98f347c7cf7dfdeebeaaed7f76827
2024-03-14 15:04:47 -07:00
Peter Dillinger c2467b141e Update version.h and HISTORY for 8.11.3 2024-02-27 16:24:11 -08:00
Adam Retter ef0cadd38f Correct CMake Javadoc and source jar builds (#12371)
Summary:
Fix some issues introduced in https://github.com/facebook/rocksdb/pull/12199 (CC rhubner)
1. Previous `jar -v -c -f` was not valid command syntax.
2. Javadoc and source Jar files were prefixed `rocksdb-`, now corrected to `rocksdbjni-`

pdillinger This needs to be merged to `main` and also `8.11.fb` (to fix the Windows build for the RocksJava release of 8.11.2) please.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/12371

Reviewed By: pdillinger, jowlyzhang

Differential Revision: D54136834

Pulled By: hx235

fbshipit-source-id: f356f2401042af359ada607e5f0be627418ccd6c
2024-02-27 16:18:13 -08:00
Peter Dillinger 9d9014d4d0 Update HISTORY and version for 8.11.2 2024-02-16 12:12:49 -08:00
Adam Retter 412b7fd2bd Update ZLib to 1.3.1 (#12358)
Summary:
pdillinger This fixes the RocksJava build, is also needed in the 8.10.fb and 8.11.fb branches please?

Pull Request resolved: https://github.com/facebook/rocksdb/pull/12358

Reviewed By: jaykorean

Differential Revision: D53859743

Pulled By: pdillinger

fbshipit-source-id: b8417fccfee931591805f9aecdfae7c086fee708
2024-02-16 12:11:25 -08:00
Sanket Sanjeev Karnik 8a201ce68a Mark destructors as overridden (#12324)
Summary:
Pull Request resolved: https://github.com/facebook/rocksdb/pull/12324

We are trying to use rocksdb inside Hedwig. This is causing some builds to fail D53033764. Hence fixing -Wsuggest-destructor-override warning.

Reviewed By: jowlyzhang

Differential Revision: D53328538

fbshipit-source-id: d5b9865442de049b18f9ed086df5fa58fb8880d5
2024-02-02 09:49:05 -08:00
Peter Dillinger a53094983b Version bump and HISTORY for 8.11.1 patch 2024-01-26 08:38:54 -08:00
Hui Xiao cc20520d5f Pass rate_limiter_priority from SequentialFileReader to FS (#12296)
Summary:
**Context/Summary:**
The rate_limiter_priority passed to SequentialFileReader is now passed down to underlying file system. This allows the priority associated with backup/restore SST reads to be exposed to FS.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/12296

Test Plan: - Modified existing UT

Reviewed By: pdillinger

Differential Revision: D53100368

Pulled By: hx235

fbshipit-source-id: b4a28917efbb1b0d16f9d1c2b38769bffcff0f34
2024-01-25 18:58:47 -08:00
Hui Xiao 36797a43fe Rate-limit un-ratelimited flush/compaction code paths (#12290)
Summary:
**Context/Summary:**

We recently found out some code paths in flush and compaction aren't rate-limited when they should.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/12290

Test Plan: existing UT**

Reviewed By: anand1976

Differential Revision: D53066103

Pulled By: hx235

fbshipit-source-id: 9dc4cab5f841230d18e5504dc480ac523e9d3950
2024-01-25 13:29:13 -08:00
Hui Xiao 7c06a1e503 Fix bug of newer ingested data assigned with an older seqno (#12257)
Summary:
**Context:**
We found an edge case where newer ingested data is assigned with an older seqno. This causes older data of that key to be returned for read.

Consider the following lsm shape:
![image](https://github.com/facebook/rocksdb/assets/83968999/973fd160-5065-49cd-8b7b-b6ab4badae23)
Then ingest a file to L5 containing new data of key_overlap. Because of [this](https://l.facebook.com/l.php?u=https%3A%2F%2Fgithub.com%2Ffacebook%2Frocksdb%2Fblob%2F5a26f392ca640818da0b8590be6119699e852b07%2Fdb%2Fexternal_sst_file_ingestion_job.cc%3Ffbclid%3DIwAR10clXxpUSrt6sYg12sUMeHfShS7XigFrsJHvZoUDroQpbj_Sb3dG_JZFc%23L951-L956&h=AT0m56P7O0ZML7jk1sdjgnZZyGPMXg9HkKvBEb8mE9ZM3fpJjPrArAMsaHWZQPt9Ki-Pn7lv7x-RT9NEd_202Y6D2juIVHOIt3EjCZptDKBLRBMG49F8iBUSM9ypiKe8XCfM-FNW2Hl4KbVq2e3nZRbMvUM), the file is assigned with seqno 2, older than the old data's seqno 4. After just another compaction, we will drop the new_v for key_overlap because of the seqno and cause older data to be returned.
![image](https://github.com/facebook/rocksdb/assets/83968999/a3ef95e4-e7ae-4c30-8d03-955cd4b5ed42)

**Summary:**
This PR removes the incorrect seqno assignment

Pull Request resolved: https://github.com/facebook/rocksdb/pull/12257

Test Plan:
- New unit test failed before the fix but passes after
- python3 tools/db_crashtest.py --compaction_style=1 --ingest_external_file_one_in=10 --preclude_last_level_data_seconds=36000 --compact_files_one_in=10 --enable_blob_files=0 blackbox`
- Rehearsal stress test

Reviewed By: cbi42

Differential Revision: D52926092

Pulled By: hx235

fbshipit-source-id: 9e4dade0f6cc44e548db8fca27ccbc81a621cd6f
2024-01-25 13:28:39 -08:00
Peter Dillinger d9e7f6a3b9 Fix UB/crash in new SeqnoToTimeMapping::CopyFromSeqnoRange (#12293)
Summary:
After https://github.com/facebook/rocksdb/issues/12253 this function has crashed in the crash test, in its call to `std::copy`. I haven't reproduced the crash directly, but `std::copy` probably has undefined behavior if the starting iterator is after the ending iterator, which was possible. I've fixed the logic to deal with that case and to add an assertion to check that precondition of `std::copy` (which appears can be unchecked by `std::copy` itself even with UBSAN+ASAN).

Also added some unit tests etc. that were unfinished for https://github.com/facebook/rocksdb/issues/12253, and slightly tweak SeqnoToTimeMapping::EnforceMaxTimeSpan handling of zero time span case.

This is intended for patching 8.11.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/12293

Test Plan: tests added. Will trigger ~20 runs of the crash test job that saw the crash. https://fburl.com/ci/5iiizvfa

Reviewed By: jowlyzhang

Differential Revision: D53090422

Pulled By: pdillinger

fbshipit-source-id: 69d60b1847d9c7e4ae62b153011c2040405db461
2024-01-25 13:26:31 -08:00
Peter Dillinger bf61a59a5b Add 8.11 release note for FileOperationType enum addition (#12263)
Summary:
Adding a this new possibility caused an assertion failure in our own RocksDB extensions (switch now incomplete), so we should warn others about it as well.

Will pick this into 8.11.fb branch

Pull Request resolved: https://github.com/facebook/rocksdb/pull/12263

Test Plan: no code change

Reviewed By: jaykorean

Differential Revision: D52966124

Pulled By: pdillinger

fbshipit-source-id: 4998293a9480909e4888871850a012b7354c3e81
2024-01-22 13:18:21 -08:00
Peter Dillinger ec2c2921e6 Release notes for 8.11.0 2024-01-20 07:17:15 -08:00
40 changed files with 514 additions and 86 deletions
@@ -15,30 +15,40 @@ runs:
SNAPPY_INCLUDE: ${{ github.workspace }}/thirdparty/snappy-1.1.8;${{ github.workspace }}/thirdparty/snappy-1.1.8/build
SNAPPY_LIB_DEBUG: ${{ github.workspace }}/thirdparty/snappy-1.1.8/build/Debug/snappy.lib
run: |-
# NOTE: if ... Exit $LASTEXITCODE lines needed to exit and report failure
echo ===================== Install Dependencies =====================
choco install liberica8jdk -y
if(!$?) { Exit $LASTEXITCODE }
mkdir $Env:THIRDPARTY_HOME
cd $Env:THIRDPARTY_HOME
echo "Building Snappy dependency..."
curl -Lo snappy-1.1.8.zip https://github.com/google/snappy/archive/refs/tags/1.1.8.zip
if(!$?) { Exit $LASTEXITCODE }
unzip -q snappy-1.1.8.zip
if(!$?) { Exit $LASTEXITCODE }
cd snappy-1.1.8
mkdir build
cd build
& cmake -G "$Env:CMAKE_GENERATOR" ..
if(!$?) { Exit $LASTEXITCODE }
msbuild Snappy.sln -maxCpuCount -property:Configuration=Debug -property:Platform=x64
if(!$?) { Exit $LASTEXITCODE }
echo ======================== Build RocksDB =========================
cd ${{ github.workspace }}
$env:Path = $env:JAVA_HOME + ";" + $env:Path
mkdir build
cd build
& cmake -G "$Env:CMAKE_GENERATOR" -DCMAKE_BUILD_TYPE=Debug -DOPTDBG=1 -DPORTABLE="$Env:CMAKE_PORTABLE" -DSNAPPY=1 -DJNI=1 ..
if(!$?) { Exit $LASTEXITCODE }
cd ..
echo "Building with VS version: $Env:CMAKE_GENERATOR"
msbuild build/rocksdb.sln -maxCpuCount -property:Configuration=Debug -property:Platform=x64
if(!$?) { Exit $LASTEXITCODE }
echo ========================= Test RocksDB =========================
build_tools\run_ci_db_test.ps1 -SuiteRun arena_test,db_basic_test,db_test,db_test2,db_merge_operand_test,bloom_test,c_test,coding_test,crc32c_test,dynamic_bloom_test,env_basic_test,env_test,hash_test,random_test -Concurrency 16
if(!$?) { Exit $LASTEXITCODE }
echo ======================== Test RocksJava ========================
cd build\java
& ctest -C Debug -j 16
if(!$?) { Exit $LASTEXITCODE }
shell: pwsh
+45
View File
@@ -1,6 +1,51 @@
# Rocksdb Change Log
> NOTE: Entries for next release do not go here. Follow instructions in `unreleased_history/README.txt`
## 8.11.5 (11/26/2025)
### Behavior Changes
* Backport new value types `kTypeValuePreferredSeqno` and `kTypeColumnFamilyValuePreferredSeqno` introduced in RocksDB 9.1. This fixes a forward compatibility issue to allow reading MANIFEST with entries containing kTypeMaxValid written by RocksDB 9.1+.
## 8.11.4 (04/09/2024)
### Bug Fixes
* Fixed CMake Javadoc build
* Fixed Java `SstFileMetaData` to prevent throwing `java.lang.NoSuchMethodError`
## 8.11.3 (02/27/2024)
* Correct CMake Javadoc and source jar builds
## 8.11.2 (02/16/2024)
* Update zlib to 1.3.1 for Java builds
## 8.11.1 (01/25/2024)
### Bug Fixes
* Fix a bug where older data of an ingested key can be returned for read when universal compaction is used
* Apply appropriate rate limiting and priorities in more places.
## 8.11.0 (01/19/2024)
### New Features
* Add new statistics: `rocksdb.sst.write.micros` measures time of each write to SST file; `rocksdb.file.write.{flush|compaction|db.open}.micros` measure time of each write to SST table (currently only block-based table format) and blob file for flush, compaction and db open.
### Public API Changes
* Added another enumerator `kVerify` to enum class `FileOperationType` in listener.h. Update your `switch` statements as needed.
* Add CompressionOptions to the CompressedSecondaryCacheOptions structure to allow users to specify library specific options when creating the compressed secondary cache.
* Deprecated several options: `level_compaction_dynamic_file_size`, `ignore_max_compaction_bytes_for_input`, `check_flush_compaction_key_order`, `flush_verify_memtable_count`, `compaction_verify_record_count`, `fail_if_options_file_error`, and `enforce_single_del_contracts`
* Exposed options ttl via c api.
### Behavior Changes
* `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.
* 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.
### Bug Fixes
* Fix bug in auto_readahead_size that combined with IndexType::kBinarySearchWithFirstKey + fails or iterator lands at a wrong key
* Fixed some cases in which DB file corruption was detected but ignored on creating a backup with BackupEngine.
* Fix bugs where `rocksdb.blobdb.blob.file.synced` includes blob files failed to get synced and `rocksdb.blobdb.blob.file.bytes.written` includes blob bytes failed to get written.
* Fixed a possible memory leak or crash on a failure (such as I/O error) in automatic atomic flush of multiple column families.
* Fixed some cases of in-memory data corruption using mmap reads with `BackupEngine`, `sst_dump`, or `ldb`.
* Fixed issues with experimental `preclude_last_level_data_seconds` option that could interfere with expected data tiering.
* Fixed the handling of the edge case when all existing blob files become unreferenced. Such files are now correctly deleted.
## 8.10.0 (12/15/2023)
### New Features
* Provide support for async_io to trim readahead_size by doing block cache lookup
+2 -2
View File
@@ -2097,8 +2097,8 @@ ROCKSDB_JAVADOCS_JAR = rocksdbjni-$(ROCKSDB_JAVA_VERSION)-javadoc.jar
ROCKSDB_SOURCES_JAR = rocksdbjni-$(ROCKSDB_JAVA_VERSION)-sources.jar
SHA256_CMD = sha256sum
ZLIB_VER ?= 1.3
ZLIB_SHA256 ?= ff0ba4c292013dbc27530b3a81e1f9a813cd39de01ca5e0f8bf355702efa593e
ZLIB_VER ?= 1.3.1
ZLIB_SHA256 ?= 9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23
ZLIB_DOWNLOAD_BASE ?= http://zlib.net
BZIP2_VER ?= 1.0.8
BZIP2_SHA256 ?= ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269
+5 -3
View File
@@ -484,7 +484,8 @@ void CompactionJob::GenSubcompactionBoundaries() {
// overlap with N-1 other ranges. Since we requested a relatively large number
// (128) of ranges from each input files, even N range overlapping would
// cause relatively small inaccuracy.
const ReadOptions read_options(Env::IOActivity::kCompaction);
ReadOptions read_options(Env::IOActivity::kCompaction);
read_options.rate_limiter_priority = GetRateLimiterPriority();
auto* c = compact_->compaction;
if (c->max_subcompactions() <= 1 &&
!(c->immutable_options()->compaction_pri == kRoundRobin &&
@@ -736,8 +737,9 @@ Status CompactionJob::Run() {
// use_direct_io_for_flush_and_compaction is true, we will regard this
// verification as user reads since the goal is to cache it here for
// further user reads
const ReadOptions verify_table_read_options(
Env::IOActivity::kCompaction);
ReadOptions verify_table_read_options(Env::IOActivity::kCompaction);
verify_table_read_options.rate_limiter_priority =
GetRateLimiterPriority();
InternalIterator* iter = cfd->table_cache()->NewIterator(
verify_table_read_options, file_options_,
cfd->internal_comparator(), files_output[file_idx]->meta,
+19 -3
View File
@@ -3947,6 +3947,15 @@ TEST_F(DBTest2, RateLimitedCompactionReads) {
options.table_factory.reset(NewBlockBasedTableFactory(bbto));
DestroyAndReopen(options);
// To precisely control when to start bg compaction for excluding previous
// rate-limited bytes of flush read for table verification
std::shared_ptr<test::SleepingBackgroundTask> sleeping_task(
new test::SleepingBackgroundTask());
env_->SetBackgroundThreads(1, Env::LOW);
env_->Schedule(&test::SleepingBackgroundTask::DoSleepTask,
sleeping_task.get(), Env::Priority::LOW);
sleeping_task->WaitUntilSleeping();
for (int i = 0; i < kNumL0Files; ++i) {
for (int j = 0; j <= kNumKeysPerFile; ++j) {
ASSERT_OK(Put(Key(j), DummyString(kBytesPerKey)));
@@ -3956,13 +3965,20 @@ TEST_F(DBTest2, RateLimitedCompactionReads) {
ASSERT_EQ(i + 1, NumTableFilesAtLevel(0));
}
}
size_t rate_limited_bytes_start_bytes =
options.rate_limiter->GetTotalBytesThrough(Env::IO_TOTAL);
sleeping_task->WakeUp();
sleeping_task->WaitUntilDone();
ASSERT_OK(dbfull()->TEST_WaitForCompact());
ASSERT_EQ(0, NumTableFilesAtLevel(0));
// should be slightly above 512KB due to non-data blocks read. Arbitrarily
// chose 1MB as the upper bound on the total bytes read.
size_t rate_limited_bytes = static_cast<size_t>(
options.rate_limiter->GetTotalBytesThrough(Env::IO_TOTAL));
size_t rate_limited_bytes =
static_cast<size_t>(
options.rate_limiter->GetTotalBytesThrough(Env::IO_TOTAL)) -
rate_limited_bytes_start_bytes;
// The charges can exist for `IO_LOW` and `IO_USER` priorities.
size_t rate_limited_bytes_by_pri =
options.rate_limiter->GetTotalBytesThrough(Env::IO_LOW) +
+5 -2
View File
@@ -67,7 +67,9 @@ enum ValueType : unsigned char {
kTypeDeletionWithTimestamp = 0x14,
kTypeCommitXIDAndTimestamp = 0x15, // WAL only
kTypeWideColumnEntity = 0x16,
kTypeColumnFamilyWideColumnEntity = 0x17, // WAL only
kTypeColumnFamilyWideColumnEntity = 0x17, // WAL only
kTypeValuePreferredSeqno = 0x18, // Value with a unix write time
kTypeColumnFamilyValuePreferredSeqno = 0x19, // WAL only
kTypeMaxValid, // Should be after the last valid type, only used for
// validation
kMaxValue = 0x7F // Not used for storing records.
@@ -81,7 +83,8 @@ extern const ValueType kValueTypeForSeekForPrev;
// (i.e. a type used in memtable skiplist and sst file datablock).
inline bool IsValueType(ValueType t) {
return t <= kTypeMerge || kTypeSingleDeletion == t || kTypeBlobIndex == t ||
kTypeDeletionWithTimestamp == t || kTypeWideColumnEntity == t;
kTypeDeletionWithTimestamp == t || kTypeWideColumnEntity == t ||
kTypeValuePreferredSeqno == t;
}
// Checks whether a type is from user operation
+76
View File
@@ -9,6 +9,8 @@
#include "db/version_edit.h"
#include "port/port.h"
#include "port/stack_trace.h"
#include "rocksdb/advanced_options.h"
#include "rocksdb/options.h"
#include "rocksdb/sst_file_writer.h"
#include "test_util/testharness.h"
#include "test_util/testutil.h"
@@ -1292,6 +1294,80 @@ TEST_F(ExternalSSTFileBasicTest, VerifyChecksumReadahead) {
Destroy(options);
}
TEST_F(ExternalSSTFileBasicTest, ReadOldValueOfIngestedKeyBug) {
Options options = CurrentOptions();
options.compaction_style = kCompactionStyleUniversal;
options.disable_auto_compactions = true;
options.num_levels = 3;
options.preserve_internal_time_seconds = 36000;
DestroyAndReopen(options);
// To create the following LSM tree to trigger the bug:
// L0
// L1 with seqno [1, 2]
// L2 with seqno [3, 4]
// To create L1 shape
ASSERT_OK(
db_->Put(WriteOptions(), db_->DefaultColumnFamily(), "k1", "seqno1"));
ASSERT_OK(db_->Flush(FlushOptions()));
ASSERT_OK(
db_->Put(WriteOptions(), db_->DefaultColumnFamily(), "k1", "seqno2"));
ASSERT_OK(db_->Flush(FlushOptions()));
ColumnFamilyMetaData meta_1;
db_->GetColumnFamilyMetaData(&meta_1);
auto& files_1 = meta_1.levels[0].files;
ASSERT_EQ(files_1.size(), 2);
std::string file1 = files_1[0].db_path + files_1[0].name;
std::string file2 = files_1[1].db_path + files_1[1].name;
ASSERT_OK(db_->CompactFiles(CompactionOptions(), {file1, file2}, 1));
// To confirm L1 shape
ColumnFamilyMetaData meta_2;
db_->GetColumnFamilyMetaData(&meta_2);
ASSERT_EQ(meta_2.levels[0].files.size(), 0);
ASSERT_EQ(meta_2.levels[1].files.size(), 1);
// Seqno starts from non-zero due to seqno reservation for
// preserve_internal_time_seconds greater than 0;
ASSERT_EQ(meta_2.levels[1].files[0].largest_seqno, 102);
ASSERT_EQ(meta_2.levels[2].files.size(), 0);
// To create L2 shape
ASSERT_OK(db_->Put(WriteOptions(), db_->DefaultColumnFamily(), "k2overlap",
"old_value"));
ASSERT_OK(db_->Flush(FlushOptions()));
ASSERT_OK(db_->Put(WriteOptions(), db_->DefaultColumnFamily(), "k2overlap",
"old_value"));
ASSERT_OK(db_->Flush(FlushOptions()));
ColumnFamilyMetaData meta_3;
db_->GetColumnFamilyMetaData(&meta_3);
auto& files_3 = meta_3.levels[0].files;
std::string file3 = files_3[0].db_path + files_3[0].name;
std::string file4 = files_3[1].db_path + files_3[1].name;
ASSERT_OK(db_->CompactFiles(CompactionOptions(), {file3, file4}, 2));
// To confirm L2 shape
ColumnFamilyMetaData meta_4;
db_->GetColumnFamilyMetaData(&meta_4);
ASSERT_EQ(meta_4.levels[0].files.size(), 0);
ASSERT_EQ(meta_4.levels[1].files.size(), 1);
ASSERT_EQ(meta_4.levels[2].files.size(), 1);
ASSERT_EQ(meta_4.levels[2].files[0].largest_seqno, 104);
// Ingest a file with new value of the key "k2overlap"
SstFileWriter sst_file_writer(EnvOptions(), options);
std::string f = sst_files_dir_ + "f.sst";
ASSERT_OK(sst_file_writer.Open(f));
ASSERT_OK(sst_file_writer.Put("k2overlap", "new_value"));
ExternalSstFileInfo f_info;
ASSERT_OK(sst_file_writer.Finish(&f_info));
ASSERT_OK(db_->IngestExternalFile({f}, IngestExternalFileOptions()));
// To verify new value of the key "k2overlap" is correctly returned
ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
std::string value;
ASSERT_OK(db_->Get(ReadOptions(), "k2overlap", &value));
// Before the fix, the value would be "old_value" and assertion failed
ASSERT_EQ(value, "new_value");
}
TEST_F(ExternalSSTFileBasicTest, IngestRangeDeletionTombstoneWithGlobalSeqno) {
for (int i = 5; i < 25; i++) {
ASSERT_OK(db_->Put(WriteOptions(), db_->DefaultColumnFamily(), Key(i),
-20
View File
@@ -937,26 +937,6 @@ Status ExternalSstFileIngestionJob::AssignLevelAndSeqnoForIngestedFile(
overlap_with_db = true;
break;
}
if (compaction_style == kCompactionStyleUniversal && lvl != 0) {
const std::vector<FileMetaData*>& level_files =
vstorage->LevelFiles(lvl);
const SequenceNumber level_largest_seqno =
(*std::max_element(level_files.begin(), level_files.end(),
[](FileMetaData* f1, FileMetaData* f2) {
return f1->fd.largest_seqno <
f2->fd.largest_seqno;
}))
->fd.largest_seqno;
// should only assign seqno to current level's largest seqno when
// the file fits
if (level_largest_seqno != 0 &&
IngestedFileFitInLevel(file_to_ingest, lvl)) {
*assigned_seqno = level_largest_seqno;
} else {
continue;
}
}
} else if (compaction_style == kCompactionStyleUniversal) {
continue;
}
+4 -3
View File
@@ -861,7 +861,7 @@ Status FlushJob::WriteLevel0Table() {
{
auto write_hint = cfd_->CalculateSSTWriteHint(0);
Env::IOPriority io_priority = GetRateLimiterPriorityForWrite();
Env::IOPriority io_priority = GetRateLimiterPriority();
db_mutex_->Unlock();
if (log_buffer_) {
log_buffer_->FlushBufferToLog();
@@ -960,7 +960,8 @@ Status FlushJob::WriteLevel0Table() {
const std::string* const full_history_ts_low =
(full_history_ts_low_.empty()) ? nullptr : &full_history_ts_low_;
const ReadOptions read_options(Env::IOActivity::kFlush);
ReadOptions read_options(Env::IOActivity::kFlush);
read_options.rate_limiter_priority = io_priority;
const WriteOptions write_options(io_priority, Env::IOActivity::kFlush);
TableBuilderOptions tboptions(
*cfd_->ioptions(), mutable_cf_options_, read_options, write_options,
@@ -1087,7 +1088,7 @@ Status FlushJob::WriteLevel0Table() {
return s;
}
Env::IOPriority FlushJob::GetRateLimiterPriorityForWrite() {
Env::IOPriority FlushJob::GetRateLimiterPriority() {
if (versions_ && versions_->GetColumnFamilySet() &&
versions_->GetColumnFamilySet()->write_controller()) {
WriteController* write_controller =
+1 -1
View File
@@ -129,7 +129,7 @@ class FlushJob {
Status MemPurge();
bool MemPurgeDecider(double threshold);
// The rate limiter priority (io_priority) is determined dynamically here.
Env::IOPriority GetRateLimiterPriorityForWrite();
Env::IOPriority GetRateLimiterPriority();
std::unique_ptr<FlushJobInfo> GetFlushJobInfo() const;
// Require db_mutex held.
+3 -3
View File
@@ -588,7 +588,7 @@ TEST_F(FlushJobTest, GetRateLimiterPriorityForWrite) {
Env::Priority::USER, nullptr /*IOTracer*/, empty_seqno_to_time_mapping_);
// When the state from WriteController is normal.
ASSERT_EQ(flush_job.GetRateLimiterPriorityForWrite(), Env::IO_HIGH);
ASSERT_EQ(flush_job.GetRateLimiterPriority(), Env::IO_HIGH);
WriteController* write_controller =
flush_job.versions_->GetColumnFamilySet()->write_controller();
@@ -597,14 +597,14 @@ TEST_F(FlushJobTest, GetRateLimiterPriorityForWrite) {
// When the state from WriteController is Delayed.
std::unique_ptr<WriteControllerToken> delay_token =
write_controller->GetDelayToken(1000000);
ASSERT_EQ(flush_job.GetRateLimiterPriorityForWrite(), Env::IO_USER);
ASSERT_EQ(flush_job.GetRateLimiterPriority(), Env::IO_USER);
}
{
// When the state from WriteController is Stopped.
std::unique_ptr<WriteControllerToken> stop_token =
write_controller->GetStopToken();
ASSERT_EQ(flush_job.GetRateLimiterPriorityForWrite(), Env::IO_USER);
ASSERT_EQ(flush_job.GetRateLimiterPriority(), Env::IO_USER);
}
}
+195
View File
@@ -1052,6 +1052,114 @@ TEST_F(SeqnoTimeTest, MappingAppend) {
ASSERT_EQ(test.TEST_GetLastEntry(), P({11, 250}));
}
TEST_F(SeqnoTimeTest, CapacityLimits) {
using P = SeqnoToTimeMapping::SeqnoTimePair;
SeqnoToTimeMapping test;
test.SetCapacity(3);
EXPECT_TRUE(test.Append(10, 300));
EXPECT_TRUE(test.Append(20, 400));
EXPECT_TRUE(test.Append(30, 500));
EXPECT_TRUE(test.Append(40, 600));
// Capacity 3 is small enough that the non-strict limit is
// equal to the strict limit.
EXPECT_EQ(3U, test.Size());
EXPECT_EQ(test.TEST_GetLastEntry(), P({40, 600}));
// Same for Capacity 2
test.SetCapacity(2);
EXPECT_EQ(2U, test.Size());
EXPECT_EQ(test.TEST_GetLastEntry(), P({40, 600}));
EXPECT_TRUE(test.Append(50, 700));
EXPECT_EQ(2U, test.Size());
EXPECT_EQ(test.TEST_GetLastEntry(), P({50, 700}));
// Capacity 1 is difficult to work with internally, so is
// coerced to 2.
test.SetCapacity(1);
EXPECT_EQ(2U, test.Size());
EXPECT_EQ(test.TEST_GetLastEntry(), P({50, 700}));
EXPECT_TRUE(test.Append(60, 800));
EXPECT_EQ(2U, test.Size());
EXPECT_EQ(test.TEST_GetLastEntry(), P({60, 800}));
// Capacity 0 means throw everything away
test.SetCapacity(0);
EXPECT_EQ(0U, test.Size());
EXPECT_FALSE(test.Append(70, 900));
EXPECT_EQ(0U, test.Size());
// Unlimited capacity
test.SetCapacity(UINT64_MAX);
for (unsigned i = 1; i <= 10101U; i++) {
EXPECT_TRUE(test.Append(i, 11U * i));
}
EXPECT_EQ(10101U, test.Size());
}
TEST_F(SeqnoTimeTest, TimeSpanLimits) {
SeqnoToTimeMapping test;
// Default: no limit
for (unsigned i = 1; i <= 63U; i++) {
EXPECT_TRUE(test.Append(1000 + i, uint64_t{1} << i));
}
// None dropped.
EXPECT_EQ(63U, test.Size());
test.Clear();
// Explicit no limit
test.SetMaxTimeSpan(UINT64_MAX);
for (unsigned i = 1; i <= 63U; i++) {
EXPECT_TRUE(test.Append(1000 + i, uint64_t{1} << i));
}
// None dropped.
EXPECT_EQ(63U, test.Size());
// We generally keep 2 entries as long as the configured max time span
// is non-zero
test.SetMaxTimeSpan(10);
EXPECT_EQ(2U, test.Size());
test.SetMaxTimeSpan(1);
EXPECT_EQ(2U, test.Size());
// But go down to 1 entry if the max time span is zero
test.SetMaxTimeSpan(0);
EXPECT_EQ(1U, test.Size());
EXPECT_TRUE(test.Append(2000, (uint64_t{1} << 63) + 42U));
EXPECT_EQ(1U, test.Size());
test.Clear();
// Test more typical behavior. Note that one entry at or beyond the max span
// is kept.
test.SetMaxTimeSpan(100);
EXPECT_TRUE(test.Append(1001, 123));
EXPECT_TRUE(test.Append(1002, 134));
EXPECT_TRUE(test.Append(1003, 150));
EXPECT_TRUE(test.Append(1004, 189));
EXPECT_TRUE(test.Append(1005, 220));
EXPECT_EQ(5U, test.Size());
EXPECT_TRUE(test.Append(1006, 233));
EXPECT_EQ(6U, test.Size());
EXPECT_TRUE(test.Append(1007, 234));
EXPECT_EQ(6U, test.Size());
EXPECT_TRUE(test.Append(1008, 235));
EXPECT_EQ(7U, test.Size());
EXPECT_TRUE(test.Append(1009, 300));
EXPECT_EQ(6U, test.Size());
EXPECT_TRUE(test.Append(1010, 350));
EXPECT_EQ(3U, test.Size());
EXPECT_TRUE(test.Append(1011, 470));
EXPECT_EQ(2U, test.Size());
}
TEST_F(SeqnoTimeTest, ProximalFunctions) {
SeqnoToTimeMapping test;
test.SetCapacity(10);
@@ -1201,6 +1309,93 @@ TEST_F(SeqnoTimeTest, PrePopulate) {
}
}
TEST_F(SeqnoTimeTest, CopyFromSeqnoRange) {
SeqnoToTimeMapping test_from;
SeqnoToTimeMapping test_to;
// With zero to draw from
test_to.Clear();
test_to.CopyFromSeqnoRange(test_from, 0, 1000000);
EXPECT_EQ(test_to.Size(), 0U);
test_to.Clear();
test_to.CopyFromSeqnoRange(test_from, 100, 100);
EXPECT_EQ(test_to.Size(), 0U);
test_to.Clear();
test_to.CopyFromSeqnoRange(test_from, kMaxSequenceNumber, 0);
EXPECT_EQ(test_to.Size(), 0U);
// With one to draw from
EXPECT_TRUE(test_from.Append(10, 500));
test_to.Clear();
test_to.CopyFromSeqnoRange(test_from, 0, 1000000);
EXPECT_EQ(test_to.Size(), 1U);
// Includes one entry before range
test_to.Clear();
test_to.CopyFromSeqnoRange(test_from, 100, 100);
EXPECT_EQ(test_to.Size(), 1U);
// Includes one entry before range (even if somewhat nonsensical)
test_to.Clear();
test_to.CopyFromSeqnoRange(test_from, kMaxSequenceNumber, 0);
EXPECT_EQ(test_to.Size(), 1U);
test_to.Clear();
test_to.CopyFromSeqnoRange(test_from, 0, 9);
EXPECT_EQ(test_to.Size(), 0U);
test_to.Clear();
test_to.CopyFromSeqnoRange(test_from, 0, 10);
EXPECT_EQ(test_to.Size(), 1U);
// With more to draw from
EXPECT_TRUE(test_from.Append(20, 600));
EXPECT_TRUE(test_from.Append(30, 700));
EXPECT_TRUE(test_from.Append(40, 800));
EXPECT_TRUE(test_from.Append(50, 900));
test_to.Clear();
test_to.CopyFromSeqnoRange(test_from, 0, 1000000);
EXPECT_EQ(test_to.Size(), 5U);
// Includes one entry before range
test_to.Clear();
test_to.CopyFromSeqnoRange(test_from, 100, 100);
EXPECT_EQ(test_to.Size(), 1U);
test_to.Clear();
test_to.CopyFromSeqnoRange(test_from, 19, 19);
EXPECT_EQ(test_to.Size(), 1U);
// Includes one entry before range (even if somewhat nonsensical)
test_to.Clear();
test_to.CopyFromSeqnoRange(test_from, kMaxSequenceNumber, 0);
EXPECT_EQ(test_to.Size(), 1U);
test_to.Clear();
test_to.CopyFromSeqnoRange(test_from, 0, 9);
EXPECT_EQ(test_to.Size(), 0U);
test_to.Clear();
test_to.CopyFromSeqnoRange(test_from, 0, 10);
EXPECT_EQ(test_to.Size(), 1U);
test_to.Clear();
test_to.CopyFromSeqnoRange(test_from, 20, 20);
EXPECT_EQ(test_to.Size(), 2U);
test_to.Clear();
test_to.CopyFromSeqnoRange(test_from, 20, 29);
EXPECT_EQ(test_to.Size(), 2U);
test_to.Clear();
test_to.CopyFromSeqnoRange(test_from, 20, 30);
EXPECT_EQ(test_to.Size(), 3U);
}
TEST_F(SeqnoTimeTest, EnforceWithNow) {
constexpr uint64_t kMaxTimeSpan = 420;
SeqnoToTimeMapping test;
+9 -9
View File
@@ -72,20 +72,16 @@ SequenceNumber SeqnoToTimeMapping::GetProximalSeqnoBeforeTime(
void SeqnoToTimeMapping::EnforceMaxTimeSpan(uint64_t now) {
assert(enforced_); // at least sorted
uint64_t cutoff_time;
if (pairs_.size() <= 1) {
return;
}
if (now > 0) {
if (pairs_.size() <= 1) {
return;
}
if (now < max_time_span_) {
// Nothing eligible to prune / avoid underflow
return;
}
cutoff_time = now - max_time_span_;
} else {
if (pairs_.size() <= 2) {
// Need to keep at least two if we don't know the current time
return;
}
const auto& last = pairs_.back();
if (last.time < max_time_span_) {
// Nothing eligible to prune / avoid underflow
@@ -108,7 +104,6 @@ void SeqnoToTimeMapping::EnforceCapacity(bool strict) {
return;
}
// Treat cap of 1 as 2 to work with the below algorithm (etc.)
// TODO: unit test
if (strict_cap == 1) {
strict_cap = 2;
}
@@ -400,12 +395,16 @@ void SeqnoToTimeMapping::CopyFromSeqnoRange(const SeqnoToTimeMapping& src,
SequenceNumber to_seqno) {
bool orig_empty = Empty();
auto src_it = src.FindGreaterEqSeqno(from_seqno);
// Allow nonsensical ranges like [1000, 0] which might show up e.g. for
// an SST file with no entries.
auto src_it_end =
to_seqno < from_seqno ? src_it : src.FindGreaterSeqno(to_seqno);
// To best answer GetProximalTimeBeforeSeqno(from_seqno) we need an entry
// with a seqno before that (if available)
if (src_it != src.pairs_.begin()) {
--src_it;
}
auto src_it_end = src.FindGreaterSeqno(to_seqno);
assert(src_it <= src_it_end);
std::copy(src_it, src_it_end, std::back_inserter(pairs_));
if (!orig_empty || max_time_span_ < UINT64_MAX || capacity_ < UINT64_MAX) {
@@ -420,6 +419,7 @@ bool SeqnoToTimeMapping::Append(SequenceNumber seqno, uint64_t time) {
bool added = false;
if (seqno == 0) {
// skip seq number 0, which may have special meaning, like zeroed out data
// TODO: consider changing?
} else if (pairs_.empty()) {
enforced_ = true;
pairs_.push_back({seqno, time});
+11 -2
View File
@@ -125,12 +125,13 @@ class SeqnoToTimeMapping {
// under enforcement mode, the structure will maintian only one entry older
// than the newest entry time minus max_time_span, so that
// GetProximalSeqnoBeforeTime queries back to that time return a good result.
// UINT64_MAX == unlimited. Returns *this.
// UINT64_MAX == unlimited. 0 == retain just one latest entry. Returns *this.
SeqnoToTimeMapping& SetMaxTimeSpan(uint64_t max_time_span);
// Set the nominal capacity under enforcement mode. The structure is allowed
// to grow some reasonable fraction larger but will automatically compact
// down to this size. UINT64_MAX == unlimited. Returns *this.
// down to this size. UINT64_MAX == unlimited. 0 == retain nothing.
// Returns *this.
SeqnoToTimeMapping& SetCapacity(uint64_t capacity);
// ==== Modifiers, enforced ==== //
@@ -243,6 +244,14 @@ class SeqnoToTimeMapping {
std::deque<SeqnoTimePair> pairs_;
// Whether this object is in the "enforced" state. Between calls to public
// functions, enforced_==true means that
// * `pairs_` is sorted
// * The capacity limit (non-strict) is met
// * The time span limit is met
// However, some places within the implementation (Append()) will temporarily
// violate those last two conditions while enforced_==true. See also the
// Enforce*() and Sort*() private functions below.
bool enforced_ = true;
void EnforceMaxTimeSpan(uint64_t now = 0);
+5 -2
View File
@@ -16,6 +16,7 @@
#include "monitoring/histogram.h"
#include "monitoring/iostats_context_imp.h"
#include "port/port.h"
#include "rocksdb/file_system.h"
#include "test_util/sync_point.h"
#include "util/aligned_buffer.h"
#include "util/random.h"
@@ -38,6 +39,8 @@ IOStatus SequentialFileReader::Create(
IOStatus SequentialFileReader::Read(size_t n, Slice* result, char* scratch,
Env::IOPriority rate_limiter_priority) {
IOStatus io_s;
IOOptions io_opts;
io_opts.rate_limiter_priority = rate_limiter_priority;
if (use_direct_io()) {
//
// |-offset_advance-|---bytes returned--|
@@ -76,7 +79,7 @@ IOStatus SequentialFileReader::Read(size_t n, Slice* result, char* scratch,
start_ts = FileOperationInfo::StartNow();
}
io_s = file_->PositionedRead(aligned_offset + buf.CurrentSize(), allowed,
IOOptions(), &tmp, buf.Destination(),
io_opts, &tmp, buf.Destination(),
nullptr /* dbg */);
if (ShouldNotifyListeners()) {
auto finish_ts = FileOperationInfo::FinishNow();
@@ -119,7 +122,7 @@ IOStatus SequentialFileReader::Read(size_t n, Slice* result, char* scratch,
start_ts = FileOperationInfo::StartNow();
}
Slice tmp;
io_s = file_->Read(allowed, IOOptions(), &tmp, scratch + read,
io_s = file_->Read(allowed, io_opts, &tmp, scratch + read,
nullptr /* dbg */);
if (ShouldNotifyListeners()) {
auto finish_ts = FileOperationInfo::FinishNow();
@@ -102,7 +102,7 @@ class OptimisticTransactionDB : public StackableDB {
std::vector<ColumnFamilyHandle*>* handles,
OptimisticTransactionDB** dbptr);
virtual ~OptimisticTransactionDB() {}
~OptimisticTransactionDB() override {}
// Starts a new Transaction.
//
+1 -1
View File
@@ -27,7 +27,7 @@ class StackableDB : public DB {
explicit StackableDB(std::shared_ptr<DB> db)
: db_(db.get()), shared_db_ptr_(db) {}
~StackableDB() {
~StackableDB() override {
if (shared_db_ptr_ == nullptr) {
delete db_;
} else {
+1 -2
View File
@@ -135,7 +135,7 @@ class RangeLockManagerHandle : public LockManagerHandle {
virtual std::vector<RangeDeadlockPath> GetRangeDeadlockInfoBuffer() = 0;
virtual void SetRangeDeadlockInfoBufferSize(uint32_t target_size) = 0;
virtual ~RangeLockManagerHandle() {}
~RangeLockManagerHandle() override {}
};
// A factory function to create a Range Lock Manager. The created object should
@@ -503,4 +503,3 @@ class TransactionDB : public StackableDB {
};
} // namespace ROCKSDB_NAMESPACE
+1 -1
View File
@@ -13,7 +13,7 @@
// minor or major version number planned for release.
#define ROCKSDB_MAJOR 8
#define ROCKSDB_MINOR 11
#define ROCKSDB_PATCH 0
#define ROCKSDB_PATCH 5
// Do not use these. We made the mistake of declaring macros starting with
// double underscore. Now we have to live with our choice. We'll deprecate these
+20 -10
View File
@@ -795,20 +795,30 @@ if(NOT MINGW)
)
endif()
set(ROCKSDB_JAVADOC_JAR rocksdb-${CMAKE_PROJECT_VERSION}-javadoc.jar)
add_custom_target(rocksdbjava_javadocs_jar ALL
COMMAND ${Java_JAVADOC_EXECUTABLE} -d ${CMAKE_CURRENT_BINARY_DIR}/javadoc -sourcepath ${PROJECT_SOURCE_DIR}/java/src/main/java/ -subpackages org
COMMAND ${Java_JAR_EXECUTABLE} -v -c -f ${CMAKE_CURRENT_BINARY_DIR}/${ROCKSDB_JAVADOC_JAR} -C ${CMAKE_CURRENT_BINARY_DIR}/javadoc .
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/${ROCKSDB_JAVADOC_JAR}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
# Javadoc Jar
set(ROCKSDB_JAVADOC_JAR rocksdbjni-${CMAKE_PROJECT_VERSION}-javadoc.jar)
create_javadoc(rocksdb
PACKAGES org.rocksdb org.rocksdb.util
SOURCEPATH "${PROJECT_SOURCE_DIR}/java/src/main/java"
WINDOWTITLE "RocksDB Java API JavaDoc"
AUTHOR FALSE
USE FALSE
VERSION TRUE
)
add_custom_target(rocksdb_javadocs_jar ALL
COMMAND ${Java_JAR_EXECUTABLE} cvf ${CMAKE_CURRENT_BINARY_DIR}/${ROCKSDB_JAVADOC_JAR} -C ${CMAKE_CURRENT_BINARY_DIR}/javadoc/rocksdb .
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/${ROCKSDB_JAVADOC_JAR}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS rocksdb_javadoc
)
set(ROCKSDB_SOURCES_JAR rocksdb-${CMAKE_PROJECT_VERSION}-sources.jar)
add_custom_target(rocksdbjava_sources_jar
${Java_JAR_EXECUTABLE} -v -c -f ${CMAKE_CURRENT_BINARY_DIR}/${ROCKSDB_SOURCES_JAR} -C ${PROJECT_SOURCE_DIR}/java/src/main/java/ .
# Sources Jar
set(ROCKSDB_SOURCES_JAR rocksdbjni-${CMAKE_PROJECT_VERSION}-sources.jar)
add_custom_target(rocksdb_sources_jar ALL
${Java_JAR_EXECUTABLE} cvf ${CMAKE_CURRENT_BINARY_DIR}/${ROCKSDB_SOURCES_JAR} -C ${PROJECT_SOURCE_DIR}/java/src/main/java/ .
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/${ROCKSDB_SOURCES_JAR}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
)
+16 -2
View File
@@ -7584,7 +7584,8 @@ class SstFileMetaDataJni : public JavaClass {
}
jmethodID mid = env->GetMethodID(
jclazz, "<init>", "(Ljava/lang/String;Ljava/lang/String;JJJ[B[BJZJJ)V");
jclazz, "<init>",
"(Ljava/lang/String;Ljava/lang/String;JJJ[B[BJZJJ[B)V");
if (mid == nullptr) {
// exception thrown: NoSuchMethodException or OutOfMemoryError
return nullptr;
@@ -7624,6 +7625,17 @@ class SstFileMetaDataJni : public JavaClass {
return nullptr;
}
jbyteArray jfile_checksum = ROCKSDB_NAMESPACE::JniUtil::copyBytes(
env, sst_file_meta_data->file_checksum);
if (env->ExceptionCheck()) {
// exception occurred creating java string
env->DeleteLocalRef(jfile_name);
env->DeleteLocalRef(jpath);
env->DeleteLocalRef(jsmallest_key);
env->DeleteLocalRef(jlargest_key);
return nullptr;
}
jobject jsst_file_meta_data = env->NewObject(
jclazz, mid, jfile_name, jpath,
static_cast<jlong>(sst_file_meta_data->size),
@@ -7632,13 +7644,14 @@ class SstFileMetaDataJni : public JavaClass {
jlargest_key, static_cast<jlong>(sst_file_meta_data->num_reads_sampled),
static_cast<jboolean>(sst_file_meta_data->being_compacted),
static_cast<jlong>(sst_file_meta_data->num_entries),
static_cast<jlong>(sst_file_meta_data->num_deletions));
static_cast<jlong>(sst_file_meta_data->num_deletions), jfile_checksum);
if (env->ExceptionCheck()) {
env->DeleteLocalRef(jfile_name);
env->DeleteLocalRef(jpath);
env->DeleteLocalRef(jsmallest_key);
env->DeleteLocalRef(jlargest_key);
env->DeleteLocalRef(jfile_checksum);
return nullptr;
}
@@ -7647,6 +7660,7 @@ class SstFileMetaDataJni : public JavaClass {
env->DeleteLocalRef(jpath);
env->DeleteLocalRef(jsmallest_key);
env->DeleteLocalRef(jlargest_key);
env->DeleteLocalRef(jfile_checksum);
return jsst_file_meta_data;
}
@@ -1375,6 +1375,33 @@ public class RocksDBTest {
}
}
@Test
public void getColumnFamilyMetadataWithChecksum() throws RocksDBException {
final Properties props = new Properties();
props.put("file_checksum_gen_factory", "FileChecksumGenCrc32cFactory");
final String dbPath = dbFolder.getRoot().getAbsolutePath();
try (final DBOptions dbOptions = DBOptions.getDBOptionsFromProps(props);
final ColumnFamilyOptions cfOptions = new ColumnFamilyOptions();
final Options options = new Options(dbOptions, cfOptions).setCreateIfMissing(true)) {
try (final RocksDB db = RocksDB.open(options, dbPath);
final WriteOptions writeOptions = new WriteOptions().setDisableWAL(true)) {
db.put("key".getBytes(UTF_8), "value".getBytes(UTF_8));
}
try (final RocksDB db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath())) {
ColumnFamilyMetaData metadata = db.getColumnFamilyMetaData(); // Exception here
List<LevelMetaData> levels = metadata.levels();
assertThat(levels).isNotEmpty();
List<SstFileMetaData> filesMetadata = levels.get(0).files();
assertThat(filesMetadata).isNotEmpty();
assertThat(filesMetadata.get(0).fileChecksum()).isNotNull();
assertThat(filesMetadata.get(0).fileChecksum()).hasSize(4);
assertThat(filesMetadata.get(0).fileChecksum()).isNotEqualTo(new byte[] {0, 0, 0, 0});
}
}
}
@Ignore("TODO(AR) re-enable when ready!")
@Test
public void compactFiles() throws RocksDBException {
@@ -1 +0,0 @@
`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.
@@ -1 +0,0 @@
Files will be compacted to the next level if the data age exceeds periodic_compaction_seconds except for the last level.
@@ -1 +0,0 @@
Reduced the compaction debt ratio trigger for scheduling parallel compactions
@@ -1 +0,0 @@
* 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.
@@ -1 +0,0 @@
Fix bug in auto_readahead_size that combined with IndexType::kBinarySearchWithFirstKey + fails or iterator lands at a wrong key
@@ -1 +0,0 @@
Fixed some cases in which DB file corruption was detected but ignored on creating a backup with BackupEngine.
@@ -1 +0,0 @@
Fix bugs where `rocksdb.blobdb.blob.file.synced` includes blob files failed to get synced and `rocksdb.blobdb.blob.file.bytes.written` includes blob bytes failed to get written.
-1
View File
@@ -1 +0,0 @@
Fixed a possible memory leak or crash on a failure (such as I/O error) in automatic atomic flush of multiple column families.
@@ -1 +0,0 @@
Fixed some cases of in-memory data corruption using mmap reads with `BackupEngine`, `sst_dump`, or `ldb`.
@@ -1 +0,0 @@
Fixed issues with experimental `preclude_last_level_data_seconds` option that could interfere with expected data tiering.
@@ -1 +0,0 @@
Fixed the handling of the edge case when all existing blob files become unreferenced. Such files are now correctly deleted.
@@ -1 +0,0 @@
Add new statistics: `rocksdb.sst.write.micros` measures time of each write to SST file; `rocksdb.file.write.{flush|compaction|db.open}.micros` measure time of each write to SST table (currently only block-based table format) and blob file for flush, compaction and db open.
@@ -1 +0,0 @@
Add CompressionOptions to the CompressedSecondaryCacheOptions structure to allow users to specify library specific options when creating the compressed secondary cache.
@@ -1 +0,0 @@
Deprecated several options: `level_compaction_dynamic_file_size`, `ignore_max_compaction_bytes_for_input`, `check_flush_compaction_key_order`, `flush_verify_memtable_count`, `compaction_verify_record_count`, `fail_if_options_file_error`, and `enforce_single_del_contracts`
@@ -1 +0,0 @@
Exposed options ttl via c api.
+52 -1
View File
@@ -181,6 +181,40 @@ class TestFs : public FileSystemWrapper {
bool fail_reads_;
};
class CheckIOOptsSequentialFile : public FSSequentialFileOwnerWrapper {
public:
CheckIOOptsSequentialFile(std::unique_ptr<FSSequentialFile>&& f,
const std::string& file_name)
: FSSequentialFileOwnerWrapper(std::move(f)) {
is_sst_file_ = file_name.find(".sst") != std::string::npos;
}
IOStatus Read(size_t n, const IOOptions& options, Slice* result,
char* scratch, IODebugContext* dbg) override {
// Backup currently associates only SST read with rate limiter priority
assert(!is_sst_file_ || options.rate_limiter_priority ==
kExpectedBackupReadRateLimiterPri);
IOStatus rv = target()->Read(n, options, result, scratch, dbg);
return rv;
}
IOStatus PositionedRead(uint64_t offset, size_t n, const IOOptions& options,
Slice* result, char* scratch,
IODebugContext* dbg) override {
// Backup currently associates only SST read with rate limiter priority
assert(!is_sst_file_ || options.rate_limiter_priority ==
kExpectedBackupReadRateLimiterPri);
IOStatus rv =
target()->PositionedRead(offset, n, options, result, scratch, dbg);
return rv;
}
private:
static const Env::IOPriority kExpectedBackupReadRateLimiterPri =
Env::IO_LOW;
bool is_sst_file_;
};
IOStatus NewSequentialFile(const std::string& f, const FileOptions& file_opts,
std::unique_ptr<FSSequentialFile>* r,
IODebugContext* dbg) override {
@@ -189,6 +223,14 @@ class TestFs : public FileSystemWrapper {
r->reset(
new TestFs::DummySequentialFile(dummy_sequential_file_fail_reads_));
return IOStatus::OK();
} else if (check_iooptions_sequential_file_) {
std::unique_ptr<FSSequentialFile> file;
IOStatus s =
FileSystemWrapper::NewSequentialFile(f, file_opts, &file, dbg);
if (s.ok()) {
r->reset(new TestFs::CheckIOOptsSequentialFile(std::move(file), f));
}
return s;
} else {
IOStatus s = FileSystemWrapper::NewSequentialFile(f, file_opts, r, dbg);
if (s.ok()) {
@@ -292,6 +334,11 @@ class TestFs : public FileSystemWrapper {
dummy_sequential_file_fail_reads_ = dummy_sequential_file_fail_reads;
}
void SetCheckIOOptionsSequentialFile(bool check_iooptions_sequential_file) {
MutexLock l(&mutex_);
check_iooptions_sequential_file_ = check_iooptions_sequential_file;
}
void SetGetChildrenFailure(bool fail) { get_children_failure_ = fail; }
IOStatus GetChildren(const std::string& dir, const IOOptions& io_opts,
std::vector<std::string>* r,
@@ -387,6 +434,7 @@ class TestFs : public FileSystemWrapper {
port::Mutex mutex_;
bool dummy_sequential_file_ = false;
bool dummy_sequential_file_fail_reads_ = false;
bool check_iooptions_sequential_file_ = false;
std::vector<std::string> written_files_;
std::vector<std::string> filenames_for_mocked_attrs_;
uint64_t limit_written_files_ = 1000000;
@@ -1184,7 +1232,8 @@ TEST_P(BackupEngineTestWithParam, OnlineIntegrationTest) {
// restore)
// options_.db_paths.emplace_back(dbname_, 500 * 1024);
// options_.db_paths.emplace_back(dbname_ + "_2", 1024 * 1024 * 1024);
test_db_fs_->SetCheckIOOptionsSequentialFile(true);
test_backup_fs_->SetCheckIOOptionsSequentialFile(true);
OpenDBAndBackupEngine(true);
// write some data, backup, repeat
for (int i = 0; i < 5; ++i) {
@@ -1241,6 +1290,8 @@ TEST_P(BackupEngineTestWithParam, OnlineIntegrationTest) {
AssertBackupConsistency(0, 0, 3 * keys_iteration, max_key);
CloseBackupEngine();
test_db_fs_->SetCheckIOOptionsSequentialFile(false);
test_backup_fs_->SetCheckIOOptionsSequentialFile(false);
}
#endif // !defined(ROCKSDB_VALGRIND_RUN) || defined(ROCKSDB_FULL_VALGRIND_RUN)
+1 -1
View File
@@ -250,7 +250,7 @@ class BlobDB : public StackableDB {
virtual Status SyncBlobFiles(const WriteOptions& write_options) = 0;
virtual ~BlobDB() {}
~BlobDB() override {}
protected:
explicit BlobDB();
+4 -2
View File
@@ -38,7 +38,10 @@ static std::unordered_map<std::string, ValueType> value_type_string_map = {
{"TypeCommitXIDAndTimestamp", ValueType::kTypeCommitXIDAndTimestamp},
{"TypeWideColumnEntity", ValueType::kTypeWideColumnEntity},
{"TypeColumnFamilyWideColumnEntity",
ValueType::kTypeColumnFamilyWideColumnEntity}};
ValueType::kTypeColumnFamilyWideColumnEntity},
{"TypeValuePreferredSeqno", ValueType::kTypeValuePreferredSeqno},
{"TypeColumnFamilyValuePreferredSeqno",
ValueType::kTypeColumnFamilyValuePreferredSeqno}};
std::string KeyVersion::GetTypeName() const {
std::string type_name;
@@ -115,4 +118,3 @@ Status GetAllKeyVersions(DB* db, ColumnFamilyHandle* cfh, Slice begin_key,
}
} // namespace ROCKSDB_NAMESPACE