Blob DB: fix crash when DB full but no candidate file to evict
Summary: When blob_files is empty, std::min_element will return blobfiles.end(), which cannot be dereference. Fixing it. Closes https://github.com/facebook/rocksdb/pull/3387 Differential Revision: D6764927 Pulled By: yiwu-arbug fbshipit-source-id: 86f78700132be95760d35ac63480dfd3a8bbe17a
This commit is contained in:
parent
5568aec421
commit
f2f034ef3b
@ -859,6 +859,9 @@ std::shared_ptr<BlobFile> BlobDBImpl::GetOldestBlobFile() {
|
||||
CopyBlobFiles(&blob_files, [](const std::shared_ptr<BlobFile>& f) {
|
||||
return !f->Obsolete() && f->Immutable();
|
||||
});
|
||||
if (blob_files.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
blobf_compare_ttl compare;
|
||||
return *std::min_element(blob_files.begin(), blob_files.end(), compare);
|
||||
}
|
||||
@ -889,6 +892,7 @@ bool BlobDBImpl::EvictOldestBlobFile() {
|
||||
oldest_file->BlobCount());
|
||||
RecordTick(statistics_, BLOB_DB_FIFO_BYTES_EVICTED,
|
||||
oldest_file->GetFileSize());
|
||||
TEST_SYNC_POINT("BlobDBImpl::EvictOldestBlobFile:Evicted");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1061,15 +1061,19 @@ TEST_F(BlobDBTest, OutOfSpace) {
|
||||
}
|
||||
|
||||
TEST_F(BlobDBTest, EvictOldestFileWhenCloseToSpaceLimit) {
|
||||
// Use mock env to stop wall clock.
|
||||
Options options;
|
||||
BlobDBOptions bdb_options;
|
||||
bdb_options.blob_dir_size = 270;
|
||||
bdb_options.blob_file_size = 100;
|
||||
bdb_options.disable_background_tasks = true;
|
||||
bdb_options.is_fifo = true;
|
||||
bdb_options.disable_background_tasks = true;
|
||||
Open(bdb_options);
|
||||
|
||||
std::atomic<int> evict_count{0};
|
||||
SyncPoint::GetInstance()->SetCallBack(
|
||||
"BlobDBImpl::EvictOldestBlobFile:Evicted",
|
||||
[&](void *) { evict_count++; });
|
||||
SyncPoint::GetInstance()->EnableProcessing();
|
||||
|
||||
// Each stored blob has an overhead of 32 bytes currently.
|
||||
// So a 100 byte blob should take up 132 bytes.
|
||||
std::string value(100, 'v');
|
||||
@ -1093,6 +1097,28 @@ TEST_F(BlobDBTest, EvictOldestFileWhenCloseToSpaceLimit) {
|
||||
bdb_impl->TEST_DeleteObsoleteFiles();
|
||||
obsolete_files = bdb_impl->TEST_GetObsoleteFiles();
|
||||
ASSERT_TRUE(obsolete_files.empty());
|
||||
ASSERT_EQ(1, evict_count);
|
||||
}
|
||||
|
||||
TEST_F(BlobDBTest, NoOldestFileToEvict) {
|
||||
Options options;
|
||||
BlobDBOptions bdb_options;
|
||||
bdb_options.blob_dir_size = 1000;
|
||||
bdb_options.blob_file_size = 5000;
|
||||
bdb_options.is_fifo = true;
|
||||
bdb_options.disable_background_tasks = true;
|
||||
Open(bdb_options);
|
||||
|
||||
std::atomic<int> evict_count{0};
|
||||
SyncPoint::GetInstance()->SetCallBack(
|
||||
"BlobDBImpl::EvictOldestBlobFile:Evicted",
|
||||
[&](void *) { evict_count++; });
|
||||
SyncPoint::GetInstance()->EnableProcessing();
|
||||
|
||||
std::string value(2000, 'v');
|
||||
ASSERT_OK(Put("foo", std::string(2000, 'v')));
|
||||
ASSERT_OK(Put("bar", std::string(2000, 'v')));
|
||||
ASSERT_EQ(0, evict_count);
|
||||
}
|
||||
|
||||
TEST_F(BlobDBTest, InlineSmallValues) {
|
||||
|
Loading…
Reference in New Issue
Block a user