Expose the amount of garbage in live blob files as a dedicated DB property (#9835)

Summary:
This information has been already available as part of the `rocksdb.blob-stats`
string property. The patch adds a dedicated integer property to make it easier
to surface this information in monitoring systems.

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

Test Plan: `make check`

Reviewed By: riversand963

Differential Revision: D35619495

Pulled By: ltamasi

fbshipit-source-id: 03fb0b228aa27d3859a1e3783bcb7eca095607f8
This commit is contained in:
Levi Tamasi 2022-04-13 13:36:30 -07:00 committed by Facebook GitHub Bot
parent dc1c90c4e3
commit 5645207758
5 changed files with 52 additions and 0 deletions

View File

@ -19,6 +19,7 @@
* Add new stat ASYNC_READ_BYTES that calculates number of bytes read during async read call and users can check if async code path is being called by RocksDB internal automatic prefetching for sequential reads. * Add new stat ASYNC_READ_BYTES that calculates number of bytes read during async read call and users can check if async code path is being called by RocksDB internal automatic prefetching for sequential reads.
* Enable async prefetching if ReadOptions.readahead_size is set along with ReadOptions.async_io in FilePrefetchBuffer. * Enable async prefetching if ReadOptions.readahead_size is set along with ReadOptions.async_io in FilePrefetchBuffer.
* Add event listener support on remote compaction compactor side. * Add event listener support on remote compaction compactor side.
* Added a dedicated integer DB property `rocksdb.live-blob-file-garbage-size` that exposes the total amount of garbage in the blob files in the current version.
### Behavior changes ### Behavior changes
* Disallow usage of commit-time-write-batch for write-prepared/write-unprepared transactions if TransactionOptions::use_only_the_last_commit_time_batch_for_recovery is false to prevent two (or more) uncommitted versions of the same key in the database. Otherwise, bottommost compaction may violate the internal key uniqueness invariant of SSTs if the sequence numbers of both internal keys are zeroed out (#9794). * Disallow usage of commit-time-write-batch for write-prepared/write-unprepared transactions if TransactionOptions::use_only_the_last_commit_time_batch_for_recovery is false to prevent two (or more) uncommitted versions of the same key in the database. Otherwise, bottommost compaction may violate the internal key uniqueness invariant of SSTs if the sequence numbers of both internal keys are zeroed out (#9794).

View File

@ -733,6 +733,14 @@ TEST_F(DBBlobBasicTest, Properties) {
&live_blob_file_size)); &live_blob_file_size));
ASSERT_EQ(live_blob_file_size, total_expected_size); ASSERT_EQ(live_blob_file_size, total_expected_size);
// Total amount of garbage in live blob files
{
uint64_t live_blob_file_garbage_size = 0;
ASSERT_TRUE(db_->GetIntProperty(DB::Properties::kLiveBlobFileGarbageSize,
&live_blob_file_garbage_size));
ASSERT_EQ(live_blob_file_garbage_size, 0);
}
// Total size of all blob files across all versions // Total size of all blob files across all versions
// Note: this should be the same as above since we only have one // Note: this should be the same as above since we only have one
// version at this point. // version at this point.
@ -768,6 +776,14 @@ TEST_F(DBBlobBasicTest, Properties) {
<< "\nBlob file space amplification: " << expected_space_amp << '\n'; << "\nBlob file space amplification: " << expected_space_amp << '\n';
ASSERT_EQ(blob_stats, oss.str()); ASSERT_EQ(blob_stats, oss.str());
// Total amount of garbage in live blob files
{
uint64_t live_blob_file_garbage_size = 0;
ASSERT_TRUE(db_->GetIntProperty(DB::Properties::kLiveBlobFileGarbageSize,
&live_blob_file_garbage_size));
ASSERT_EQ(live_blob_file_garbage_size, expected_garbage_size);
}
} }
TEST_F(DBBlobBasicTest, PropertiesMultiVersion) { TEST_F(DBBlobBasicTest, PropertiesMultiVersion) {

View File

@ -305,6 +305,8 @@ static const std::string num_blob_files = "num-blob-files";
static const std::string blob_stats = "blob-stats"; static const std::string blob_stats = "blob-stats";
static const std::string total_blob_file_size = "total-blob-file-size"; static const std::string total_blob_file_size = "total-blob-file-size";
static const std::string live_blob_file_size = "live-blob-file-size"; static const std::string live_blob_file_size = "live-blob-file-size";
static const std::string live_blob_file_garbage_size =
"live-blob-file-garbage-size";
const std::string DB::Properties::kNumFilesAtLevelPrefix = const std::string DB::Properties::kNumFilesAtLevelPrefix =
rocksdb_prefix + num_files_at_level_prefix; rocksdb_prefix + num_files_at_level_prefix;
@ -405,6 +407,8 @@ const std::string DB::Properties::kTotalBlobFileSize =
rocksdb_prefix + total_blob_file_size; rocksdb_prefix + total_blob_file_size;
const std::string DB::Properties::kLiveBlobFileSize = const std::string DB::Properties::kLiveBlobFileSize =
rocksdb_prefix + live_blob_file_size; rocksdb_prefix + live_blob_file_size;
const std::string DB::Properties::kLiveBlobFileGarbageSize =
rocksdb_prefix + live_blob_file_garbage_size;
const UnorderedMap<std::string, DBPropertyInfo> const UnorderedMap<std::string, DBPropertyInfo>
InternalStats::ppt_name_to_info = { InternalStats::ppt_name_to_info = {
@ -563,6 +567,9 @@ const UnorderedMap<std::string, DBPropertyInfo>
{DB::Properties::kLiveBlobFileSize, {DB::Properties::kLiveBlobFileSize,
{false, nullptr, &InternalStats::HandleLiveBlobFileSize, nullptr, {false, nullptr, &InternalStats::HandleLiveBlobFileSize, nullptr,
nullptr}}, nullptr}},
{DB::Properties::kLiveBlobFileGarbageSize,
{false, nullptr, &InternalStats::HandleLiveBlobFileGarbageSize,
nullptr, nullptr}},
}; };
InternalStats::InternalStats(int num_levels, SystemClock* clock, InternalStats::InternalStats(int num_levels, SystemClock* clock,
@ -758,6 +765,7 @@ bool InternalStats::HandleLiveSstFilesSizeAtTemperature(std::string* value,
bool InternalStats::HandleNumBlobFiles(uint64_t* value, DBImpl* /*db*/, bool InternalStats::HandleNumBlobFiles(uint64_t* value, DBImpl* /*db*/,
Version* /*version*/) { Version* /*version*/) {
assert(value);
assert(cfd_); assert(cfd_);
const auto* current = cfd_->current(); const auto* current = cfd_->current();
@ -774,6 +782,7 @@ bool InternalStats::HandleNumBlobFiles(uint64_t* value, DBImpl* /*db*/,
} }
bool InternalStats::HandleBlobStats(std::string* value, Slice /*suffix*/) { bool InternalStats::HandleBlobStats(std::string* value, Slice /*suffix*/) {
assert(value);
assert(cfd_); assert(cfd_);
const auto* current = cfd_->current(); const auto* current = cfd_->current();
@ -798,6 +807,7 @@ bool InternalStats::HandleBlobStats(std::string* value, Slice /*suffix*/) {
bool InternalStats::HandleTotalBlobFileSize(uint64_t* value, DBImpl* /*db*/, bool InternalStats::HandleTotalBlobFileSize(uint64_t* value, DBImpl* /*db*/,
Version* /*version*/) { Version* /*version*/) {
assert(value);
assert(cfd_); assert(cfd_);
*value = cfd_->GetTotalBlobFileSize(); *value = cfd_->GetTotalBlobFileSize();
@ -807,6 +817,7 @@ bool InternalStats::HandleTotalBlobFileSize(uint64_t* value, DBImpl* /*db*/,
bool InternalStats::HandleLiveBlobFileSize(uint64_t* value, DBImpl* /*db*/, bool InternalStats::HandleLiveBlobFileSize(uint64_t* value, DBImpl* /*db*/,
Version* /*version*/) { Version* /*version*/) {
assert(value);
assert(cfd_); assert(cfd_);
const auto* current = cfd_->current(); const auto* current = cfd_->current();
@ -820,6 +831,23 @@ bool InternalStats::HandleLiveBlobFileSize(uint64_t* value, DBImpl* /*db*/,
return true; return true;
} }
bool InternalStats::HandleLiveBlobFileGarbageSize(uint64_t* value,
DBImpl* /*db*/,
Version* /*version*/) {
assert(value);
assert(cfd_);
const auto* current = cfd_->current();
assert(current);
const auto* vstorage = current->storage_info();
assert(vstorage);
*value = vstorage->GetBlobStats().total_garbage_size;
return true;
}
const DBPropertyInfo* GetPropertyInfo(const Slice& property) { const DBPropertyInfo* GetPropertyInfo(const Slice& property) {
std::string ppt_name = GetPropertyNameAndArg(property).first.ToString(); std::string ppt_name = GetPropertyNameAndArg(property).first.ToString();
auto ppt_info_iter = InternalStats::ppt_name_to_info.find(ppt_name); auto ppt_info_iter = InternalStats::ppt_name_to_info.find(ppt_name);

View File

@ -691,6 +691,9 @@ class InternalStats {
bool HandleBlobStats(std::string* value, Slice suffix); bool HandleBlobStats(std::string* value, Slice suffix);
bool HandleTotalBlobFileSize(uint64_t* value, DBImpl* db, Version* version); bool HandleTotalBlobFileSize(uint64_t* value, DBImpl* db, Version* version);
bool HandleLiveBlobFileSize(uint64_t* value, DBImpl* db, Version* version); bool HandleLiveBlobFileSize(uint64_t* value, DBImpl* db, Version* version);
bool HandleLiveBlobFileGarbageSize(uint64_t* value, DBImpl* db,
Version* version);
// Total number of background errors encountered. Every time a flush task // Total number of background errors encountered. Every time a flush task
// or compaction task fails, this counter is incremented. The failure can // or compaction task fails, this counter is incremented. The failure can
// be caused by any possible reason, including file system errors, out of // be caused by any possible reason, including file system errors, out of

View File

@ -1066,6 +1066,10 @@ class DB {
// "rocksdb.live-blob-file-size" - returns the total size of all blob // "rocksdb.live-blob-file-size" - returns the total size of all blob
// files in the current version. // files in the current version.
static const std::string kLiveBlobFileSize; static const std::string kLiveBlobFileSize;
// "rocksdb.live-blob-file-garbage-size" - returns the total amount of
// garbage in the blob files in the current version.
static const std::string kLiveBlobFileGarbageSize;
}; };
#endif /* ROCKSDB_LITE */ #endif /* ROCKSDB_LITE */