Expose CacheEntryRole
and map keys for block cache stat collections (#9838)
Summary: This gives users the ability to examine the map populated by `GetMapProperty()` with property `kBlockCacheEntryStats`. It also sets us up for a possible future where cache reservations are configured according to `CacheEntryRole`s rather than flags coupled to roles. Pull Request resolved: https://github.com/facebook/rocksdb/pull/9838 Test Plan: - migrated test DBBlockCacheTest.CacheEntryRoleStats to use this API. That test verifies some of the contents are as expected - added a DBPropertiesTest to verify the public map keys are present, and nothing else Reviewed By: hx235 Differential Revision: D35629493 Pulled By: ajkr fbshipit-source-id: 5c4356b8560e85d1f881fd32c44c15960b02fc68
This commit is contained in:
parent
fefacd33e3
commit
d6e016be6d
@ -24,6 +24,9 @@
|
|||||||
### 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).
|
||||||
|
|
||||||
|
### Public API changes
|
||||||
|
* Exposed APIs to examine results of block cache stats collections in a structured way. In particular, users of `GetMapProperty()` with property `kBlockCacheEntryStats` can now use the functions in `BlockCacheEntryStatsMapKeys` to find stats in the map.
|
||||||
|
|
||||||
## 7.1.0 (03/23/2022)
|
## 7.1.0 (03/23/2022)
|
||||||
### New Features
|
### New Features
|
||||||
* Allow WriteBatchWithIndex to index a WriteBatch that includes keys with user-defined timestamps. The index itself does not have timestamp.
|
* Allow WriteBatchWithIndex to index a WriteBatch that includes keys with user-defined timestamps. The index itself does not have timestamp.
|
||||||
|
60
cache/cache_entry_roles.cc
vendored
60
cache/cache_entry_roles.cc
vendored
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
namespace ROCKSDB_NAMESPACE {
|
namespace ROCKSDB_NAMESPACE {
|
||||||
|
|
||||||
std::array<const char*, kNumCacheEntryRoles> kCacheEntryRoleToCamelString{{
|
std::array<std::string, kNumCacheEntryRoles> kCacheEntryRoleToCamelString{{
|
||||||
"DataBlock",
|
"DataBlock",
|
||||||
"FilterBlock",
|
"FilterBlock",
|
||||||
"FilterMetaBlock",
|
"FilterMetaBlock",
|
||||||
@ -25,7 +25,7 @@ std::array<const char*, kNumCacheEntryRoles> kCacheEntryRoleToCamelString{{
|
|||||||
"Misc",
|
"Misc",
|
||||||
}};
|
}};
|
||||||
|
|
||||||
std::array<const char*, kNumCacheEntryRoles> kCacheEntryRoleToHyphenString{{
|
std::array<std::string, kNumCacheEntryRoles> kCacheEntryRoleToHyphenString{{
|
||||||
"data-block",
|
"data-block",
|
||||||
"filter-block",
|
"filter-block",
|
||||||
"filter-meta-block",
|
"filter-meta-block",
|
||||||
@ -39,6 +39,62 @@ std::array<const char*, kNumCacheEntryRoles> kCacheEntryRoleToHyphenString{{
|
|||||||
"misc",
|
"misc",
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
const std::string& GetCacheEntryRoleName(CacheEntryRole role) {
|
||||||
|
return kCacheEntryRoleToHyphenString[static_cast<size_t>(role)];
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& BlockCacheEntryStatsMapKeys::CacheId() {
|
||||||
|
static const std::string kCacheId = "id";
|
||||||
|
return kCacheId;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& BlockCacheEntryStatsMapKeys::CacheCapacityBytes() {
|
||||||
|
static const std::string kCacheCapacityBytes = "capacity";
|
||||||
|
return kCacheCapacityBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string&
|
||||||
|
BlockCacheEntryStatsMapKeys::LastCollectionDurationSeconds() {
|
||||||
|
static const std::string kLastCollectionDurationSeconds =
|
||||||
|
"secs_for_last_collection";
|
||||||
|
return kLastCollectionDurationSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& BlockCacheEntryStatsMapKeys::LastCollectionAgeSeconds() {
|
||||||
|
static const std::string kLastCollectionAgeSeconds =
|
||||||
|
"secs_since_last_collection";
|
||||||
|
return kLastCollectionAgeSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
std::string GetPrefixedCacheEntryRoleName(const std::string& prefix,
|
||||||
|
CacheEntryRole role) {
|
||||||
|
const std::string& role_name = GetCacheEntryRoleName(role);
|
||||||
|
std::string prefixed_role_name;
|
||||||
|
prefixed_role_name.reserve(prefix.size() + role_name.size());
|
||||||
|
prefixed_role_name.append(prefix);
|
||||||
|
prefixed_role_name.append(role_name);
|
||||||
|
return prefixed_role_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
std::string BlockCacheEntryStatsMapKeys::EntryCount(CacheEntryRole role) {
|
||||||
|
const static std::string kPrefix = "count.";
|
||||||
|
return GetPrefixedCacheEntryRoleName(kPrefix, role);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string BlockCacheEntryStatsMapKeys::UsedBytes(CacheEntryRole role) {
|
||||||
|
const static std::string kPrefix = "bytes.";
|
||||||
|
return GetPrefixedCacheEntryRoleName(kPrefix, role);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string BlockCacheEntryStatsMapKeys::UsedPercent(CacheEntryRole role) {
|
||||||
|
const static std::string kPrefix = "percent.";
|
||||||
|
return GetPrefixedCacheEntryRoleName(kPrefix, role);
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct Registry {
|
struct Registry {
|
||||||
|
38
cache/cache_entry_roles.h
vendored
38
cache/cache_entry_roles.h
vendored
@ -15,43 +15,9 @@
|
|||||||
|
|
||||||
namespace ROCKSDB_NAMESPACE {
|
namespace ROCKSDB_NAMESPACE {
|
||||||
|
|
||||||
// Classifications of block cache entries, for reporting statistics
|
extern std::array<std::string, kNumCacheEntryRoles>
|
||||||
// Adding new enum to this class requires corresponding updates to
|
|
||||||
// kCacheEntryRoleToCamelString and kCacheEntryRoleToHyphenString
|
|
||||||
enum class CacheEntryRole {
|
|
||||||
// Block-based table data block
|
|
||||||
kDataBlock,
|
|
||||||
// Block-based table filter block (full or partitioned)
|
|
||||||
kFilterBlock,
|
|
||||||
// Block-based table metadata block for partitioned filter
|
|
||||||
kFilterMetaBlock,
|
|
||||||
// Block-based table deprecated filter block (old "block-based" filter)
|
|
||||||
kDeprecatedFilterBlock,
|
|
||||||
// Block-based table index block
|
|
||||||
kIndexBlock,
|
|
||||||
// Other kinds of block-based table block
|
|
||||||
kOtherBlock,
|
|
||||||
// WriteBufferManager reservations to account for memtable usage
|
|
||||||
kWriteBuffer,
|
|
||||||
// BlockBasedTableBuilder reservations to account for
|
|
||||||
// compression dictionary building buffer's memory usage
|
|
||||||
kCompressionDictionaryBuildingBuffer,
|
|
||||||
// Filter reservations to account for
|
|
||||||
// (new) bloom and ribbon filter construction's memory usage
|
|
||||||
kFilterConstruction,
|
|
||||||
// BlockBasedTableReader reservations to account for
|
|
||||||
// its memory usage
|
|
||||||
kBlockBasedTableReader,
|
|
||||||
// Default bucket, for miscellaneous cache entries. Do not use for
|
|
||||||
// entries that could potentially add up to large usage.
|
|
||||||
kMisc,
|
|
||||||
};
|
|
||||||
constexpr uint32_t kNumCacheEntryRoles =
|
|
||||||
static_cast<uint32_t>(CacheEntryRole::kMisc) + 1;
|
|
||||||
|
|
||||||
extern std::array<const char*, kNumCacheEntryRoles>
|
|
||||||
kCacheEntryRoleToCamelString;
|
kCacheEntryRoleToCamelString;
|
||||||
extern std::array<const char*, kNumCacheEntryRoles>
|
extern std::array<std::string, kNumCacheEntryRoles>
|
||||||
kCacheEntryRoleToHyphenString;
|
kCacheEntryRoleToHyphenString;
|
||||||
|
|
||||||
// To associate cache entries with their role, we use a hack on the
|
// To associate cache entries with their role, we use a hack on the
|
||||||
|
@ -1404,21 +1404,11 @@ TEST_F(DBBlockCacheTest, CacheEntryRoleStats) {
|
|||||||
ASSERT_TRUE(
|
ASSERT_TRUE(
|
||||||
db_->GetMapProperty(DB::Properties::kBlockCacheEntryStats, &values));
|
db_->GetMapProperty(DB::Properties::kBlockCacheEntryStats, &values));
|
||||||
|
|
||||||
EXPECT_EQ(
|
for (size_t i = 0; i < kNumCacheEntryRoles; ++i) {
|
||||||
ToString(expected[static_cast<size_t>(CacheEntryRole::kIndexBlock)]),
|
auto role = static_cast<CacheEntryRole>(i);
|
||||||
values["count.index-block"]);
|
EXPECT_EQ(ToString(expected[i]),
|
||||||
EXPECT_EQ(
|
values[BlockCacheEntryStatsMapKeys::EntryCount(role)]);
|
||||||
ToString(expected[static_cast<size_t>(CacheEntryRole::kDataBlock)]),
|
}
|
||||||
values["count.data-block"]);
|
|
||||||
EXPECT_EQ(
|
|
||||||
ToString(expected[static_cast<size_t>(CacheEntryRole::kFilterBlock)]),
|
|
||||||
values["count.filter-block"]);
|
|
||||||
EXPECT_EQ(
|
|
||||||
ToString(
|
|
||||||
prev_expected[static_cast<size_t>(CacheEntryRole::kWriteBuffer)]),
|
|
||||||
values["count.write-buffer"]);
|
|
||||||
EXPECT_EQ(ToString(expected[static_cast<size_t>(CacheEntryRole::kMisc)]),
|
|
||||||
values["count.misc"]);
|
|
||||||
|
|
||||||
// Add one for kWriteBuffer
|
// Add one for kWriteBuffer
|
||||||
{
|
{
|
||||||
@ -1431,7 +1421,8 @@ TEST_F(DBBlockCacheTest, CacheEntryRoleStats) {
|
|||||||
env_->MockSleepForSeconds(1);
|
env_->MockSleepForSeconds(1);
|
||||||
EXPECT_EQ(ToString(prev_expected[static_cast<size_t>(
|
EXPECT_EQ(ToString(prev_expected[static_cast<size_t>(
|
||||||
CacheEntryRole::kWriteBuffer)]),
|
CacheEntryRole::kWriteBuffer)]),
|
||||||
values["count.write-buffer"]);
|
values[BlockCacheEntryStatsMapKeys::EntryCount(
|
||||||
|
CacheEntryRole::kWriteBuffer)]);
|
||||||
// Not enough for a "background" miss but enough for a "foreground" miss
|
// Not enough for a "background" miss but enough for a "foreground" miss
|
||||||
env_->MockSleepForSeconds(45);
|
env_->MockSleepForSeconds(45);
|
||||||
|
|
||||||
@ -1440,7 +1431,8 @@ TEST_F(DBBlockCacheTest, CacheEntryRoleStats) {
|
|||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
ToString(
|
ToString(
|
||||||
expected[static_cast<size_t>(CacheEntryRole::kWriteBuffer)]),
|
expected[static_cast<size_t>(CacheEntryRole::kWriteBuffer)]),
|
||||||
values["count.write-buffer"]);
|
values[BlockCacheEntryStatsMapKeys::EntryCount(
|
||||||
|
CacheEntryRole::kWriteBuffer)]);
|
||||||
}
|
}
|
||||||
prev_expected = expected;
|
prev_expected = expected;
|
||||||
|
|
||||||
|
@ -1997,6 +1997,37 @@ TEST_F(DBPropertiesTest, GetMapPropertyDbStats) {
|
|||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(DBPropertiesTest, GetMapPropertyBlockCacheEntryStats) {
|
||||||
|
// Currently only verifies the expected properties are present
|
||||||
|
std::map<std::string, std::string> values;
|
||||||
|
ASSERT_TRUE(
|
||||||
|
db_->GetMapProperty(DB::Properties::kBlockCacheEntryStats, &values));
|
||||||
|
|
||||||
|
ASSERT_TRUE(values.find(BlockCacheEntryStatsMapKeys::CacheId()) !=
|
||||||
|
values.end());
|
||||||
|
ASSERT_TRUE(values.find(BlockCacheEntryStatsMapKeys::CacheCapacityBytes()) !=
|
||||||
|
values.end());
|
||||||
|
ASSERT_TRUE(
|
||||||
|
values.find(
|
||||||
|
BlockCacheEntryStatsMapKeys::LastCollectionDurationSeconds()) !=
|
||||||
|
values.end());
|
||||||
|
ASSERT_TRUE(
|
||||||
|
values.find(BlockCacheEntryStatsMapKeys::LastCollectionAgeSeconds()) !=
|
||||||
|
values.end());
|
||||||
|
for (size_t i = 0; i < kNumCacheEntryRoles; ++i) {
|
||||||
|
CacheEntryRole role = static_cast<CacheEntryRole>(i);
|
||||||
|
ASSERT_TRUE(values.find(BlockCacheEntryStatsMapKeys::EntryCount(role)) !=
|
||||||
|
values.end());
|
||||||
|
ASSERT_TRUE(values.find(BlockCacheEntryStatsMapKeys::UsedBytes(role)) !=
|
||||||
|
values.end());
|
||||||
|
ASSERT_TRUE(values.find(BlockCacheEntryStatsMapKeys::UsedPercent(role)) !=
|
||||||
|
values.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// There should be no extra values in the map.
|
||||||
|
ASSERT_EQ(3 * kNumCacheEntryRoles + 4, values.size());
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
std::string PopMetaIndexKey(InternalIterator* meta_iter) {
|
std::string PopMetaIndexKey(InternalIterator* meta_iter) {
|
||||||
Status s = meta_iter->status();
|
Status s = meta_iter->status();
|
||||||
|
@ -702,17 +702,21 @@ void InternalStats::CacheEntryRoleStats::ToMap(
|
|||||||
std::map<std::string, std::string>* values, SystemClock* clock) const {
|
std::map<std::string, std::string>* values, SystemClock* clock) const {
|
||||||
values->clear();
|
values->clear();
|
||||||
auto& v = *values;
|
auto& v = *values;
|
||||||
v["id"] = cache_id;
|
v[BlockCacheEntryStatsMapKeys::CacheId()] = cache_id;
|
||||||
v["capacity"] = ROCKSDB_NAMESPACE::ToString(cache_capacity);
|
v[BlockCacheEntryStatsMapKeys::CacheCapacityBytes()] =
|
||||||
v["secs_for_last_collection"] =
|
ROCKSDB_NAMESPACE::ToString(cache_capacity);
|
||||||
|
v[BlockCacheEntryStatsMapKeys::LastCollectionDurationSeconds()] =
|
||||||
ROCKSDB_NAMESPACE::ToString(GetLastDurationMicros() / 1000000.0);
|
ROCKSDB_NAMESPACE::ToString(GetLastDurationMicros() / 1000000.0);
|
||||||
v["secs_since_last_collection"] = ROCKSDB_NAMESPACE::ToString(
|
v[BlockCacheEntryStatsMapKeys::LastCollectionAgeSeconds()] =
|
||||||
(clock->NowMicros() - last_end_time_micros_) / 1000000U);
|
ROCKSDB_NAMESPACE::ToString((clock->NowMicros() - last_end_time_micros_) /
|
||||||
|
1000000U);
|
||||||
for (size_t i = 0; i < kNumCacheEntryRoles; ++i) {
|
for (size_t i = 0; i < kNumCacheEntryRoles; ++i) {
|
||||||
std::string role = kCacheEntryRoleToHyphenString[i];
|
auto role = static_cast<CacheEntryRole>(i);
|
||||||
v["count." + role] = ROCKSDB_NAMESPACE::ToString(entry_counts[i]);
|
v[BlockCacheEntryStatsMapKeys::EntryCount(role)] =
|
||||||
v["bytes." + role] = ROCKSDB_NAMESPACE::ToString(total_charges[i]);
|
ROCKSDB_NAMESPACE::ToString(entry_counts[i]);
|
||||||
v["percent." + role] =
|
v[BlockCacheEntryStatsMapKeys::UsedBytes(role)] =
|
||||||
|
ROCKSDB_NAMESPACE::ToString(total_charges[i]);
|
||||||
|
v[BlockCacheEntryStatsMapKeys::UsedPercent(role)] =
|
||||||
ROCKSDB_NAMESPACE::ToString(100.0 * total_charges[i] / cache_capacity);
|
ROCKSDB_NAMESPACE::ToString(100.0 * total_charges[i] / cache_capacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -540,4 +540,58 @@ class Cache {
|
|||||||
std::shared_ptr<MemoryAllocator> memory_allocator_;
|
std::shared_ptr<MemoryAllocator> memory_allocator_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Classifications of block cache entries.
|
||||||
|
//
|
||||||
|
// Developer notes: Adding a new enum to this class requires corresponding
|
||||||
|
// updates to `kCacheEntryRoleToCamelString` and
|
||||||
|
// `kCacheEntryRoleToHyphenString`. Do not add to this enum after `kMisc` since
|
||||||
|
// `kNumCacheEntryRoles` assumes `kMisc` comes last.
|
||||||
|
enum class CacheEntryRole {
|
||||||
|
// Block-based table data block
|
||||||
|
kDataBlock,
|
||||||
|
// Block-based table filter block (full or partitioned)
|
||||||
|
kFilterBlock,
|
||||||
|
// Block-based table metadata block for partitioned filter
|
||||||
|
kFilterMetaBlock,
|
||||||
|
// Block-based table deprecated filter block (old "block-based" filter)
|
||||||
|
kDeprecatedFilterBlock,
|
||||||
|
// Block-based table index block
|
||||||
|
kIndexBlock,
|
||||||
|
// Other kinds of block-based table block
|
||||||
|
kOtherBlock,
|
||||||
|
// WriteBufferManager reservations to account for memtable usage
|
||||||
|
kWriteBuffer,
|
||||||
|
// BlockBasedTableBuilder reservations to account for
|
||||||
|
// compression dictionary building buffer's memory usage
|
||||||
|
kCompressionDictionaryBuildingBuffer,
|
||||||
|
// Filter reservations to account for
|
||||||
|
// (new) bloom and ribbon filter construction's memory usage
|
||||||
|
kFilterConstruction,
|
||||||
|
// BlockBasedTableReader reservations to account for
|
||||||
|
// its memory usage
|
||||||
|
kBlockBasedTableReader,
|
||||||
|
// Default bucket, for miscellaneous cache entries. Do not use for
|
||||||
|
// entries that could potentially add up to large usage.
|
||||||
|
kMisc,
|
||||||
|
};
|
||||||
|
constexpr uint32_t kNumCacheEntryRoles =
|
||||||
|
static_cast<uint32_t>(CacheEntryRole::kMisc) + 1;
|
||||||
|
|
||||||
|
// Obtain a hyphen-separated, lowercase name of a `CacheEntryRole`.
|
||||||
|
const std::string& GetCacheEntryRoleName(CacheEntryRole);
|
||||||
|
|
||||||
|
// For use with `GetMapProperty()` for property
|
||||||
|
// `DB::Properties::kBlockCacheEntryStats`. On success, the map will
|
||||||
|
// be populated with all keys that can be obtained from these functions.
|
||||||
|
struct BlockCacheEntryStatsMapKeys {
|
||||||
|
static const std::string& CacheId();
|
||||||
|
static const std::string& CacheCapacityBytes();
|
||||||
|
static const std::string& LastCollectionDurationSeconds();
|
||||||
|
static const std::string& LastCollectionAgeSeconds();
|
||||||
|
|
||||||
|
static std::string EntryCount(CacheEntryRole);
|
||||||
|
static std::string UsedBytes(CacheEntryRole);
|
||||||
|
static std::string UsedPercent(CacheEntryRole);
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace ROCKSDB_NAMESPACE
|
} // namespace ROCKSDB_NAMESPACE
|
||||||
|
@ -876,7 +876,9 @@ class DB {
|
|||||||
static const std::string kLevelStats;
|
static const std::string kLevelStats;
|
||||||
|
|
||||||
// "rocksdb.block-cache-entry-stats" - returns a multi-line string or
|
// "rocksdb.block-cache-entry-stats" - returns a multi-line string or
|
||||||
// map with statistics on block cache usage.
|
// map with statistics on block cache usage. See
|
||||||
|
// `BlockCacheEntryStatsMapKeys` for structured representation of keys
|
||||||
|
// available in the map form.
|
||||||
static const std::string kBlockCacheEntryStats;
|
static const std::string kBlockCacheEntryStats;
|
||||||
|
|
||||||
// "rocksdb.num-immutable-mem-table" - returns number of immutable
|
// "rocksdb.num-immutable-mem-table" - returns number of immutable
|
||||||
|
Loading…
Reference in New Issue
Block a user