Add rocksdb.num-live-versions: number of live versions

Summary: Add a DB property about live versions. It can be helpful to figure out whether there are files not live but not yet deleted, in some use cases.

Test Plan: make all check

Reviewers: rven, yhchiang, igor

Reviewed By: igor

Subscribers: yoshinorim, dhruba, leveldb

Differential Revision: https://reviews.facebook.net/D33327
main
sdong 10 years ago
parent 11581b7415
commit d45a6a4002
  1. 4
      db/column_family.cc
  2. 2
      db/column_family.h
  3. 37
      db/db_test.cc
  4. 6
      db/internal_stats.cc
  5. 1
      db/internal_stats.h
  6. 8
      db/version_set.cc
  7. 2
      db/version_set.h
  8. 5
      include/rocksdb/db.h

@ -439,6 +439,10 @@ void ColumnFamilyData::SetCurrent(Version* current_version) {
current_ = current_version; current_ = current_version;
} }
uint64_t ColumnFamilyData::GetNumLiveVersions() const {
return VersionSet::GetNumLiveVersions(dummy_versions_);
}
MemTable* ColumnFamilyData::ConstructNewMemtable( MemTable* ColumnFamilyData::ConstructNewMemtable(
const MutableCFOptions& mutable_cf_options) { const MutableCFOptions& mutable_cf_options) {
assert(current_ != nullptr); assert(current_ != nullptr);

@ -207,6 +207,8 @@ class ColumnFamilyData {
Version* current() { return current_; } Version* current() { return current_; }
Version* dummy_versions() { return dummy_versions_; } Version* dummy_versions() { return dummy_versions_; }
void SetCurrent(Version* current); void SetCurrent(Version* current);
uint64_t GetNumLiveVersions() const; // REQUIRE: DB mutex held
MemTable* ConstructNewMemtable(const MutableCFOptions& mutable_cf_options); MemTable* ConstructNewMemtable(const MutableCFOptions& mutable_cf_options);
void SetMemtable(MemTable* new_mem) { mem_ = new_mem; } void SetMemtable(MemTable* new_mem) { mem_ = new_mem; }
void CreateNewMemtable(const MutableCFOptions& mutable_cf_options); void CreateNewMemtable(const MutableCFOptions& mutable_cf_options);

@ -3230,6 +3230,43 @@ TEST(DBTest, GetProperty) {
ASSERT_TRUE( ASSERT_TRUE(
dbfull()->GetIntProperty("rocksdb.estimate-table-readers-mem", &int_num)); dbfull()->GetIntProperty("rocksdb.estimate-table-readers-mem", &int_num));
ASSERT_GT(int_num, 0U); ASSERT_GT(int_num, 0U);
// Test rocksdb.num-live-versions
{
options.level0_file_num_compaction_trigger = 20;
Reopen(options);
ASSERT_TRUE(
dbfull()->GetIntProperty("rocksdb.num-live-versions", &int_num));
ASSERT_EQ(int_num, 1U);
// Use an iterator to hold current version
std::unique_ptr<Iterator> iter1(dbfull()->NewIterator(ReadOptions()));
ASSERT_OK(dbfull()->Put(writeOpt, "k6", big_value));
Flush();
ASSERT_TRUE(
dbfull()->GetIntProperty("rocksdb.num-live-versions", &int_num));
ASSERT_EQ(int_num, 2U);
// Use an iterator to hold current version
std::unique_ptr<Iterator> iter2(dbfull()->NewIterator(ReadOptions()));
ASSERT_OK(dbfull()->Put(writeOpt, "k7", big_value));
Flush();
ASSERT_TRUE(
dbfull()->GetIntProperty("rocksdb.num-live-versions", &int_num));
ASSERT_EQ(int_num, 3U);
iter2.reset();
ASSERT_TRUE(
dbfull()->GetIntProperty("rocksdb.num-live-versions", &int_num));
ASSERT_EQ(int_num, 2U);
iter1.reset();
ASSERT_TRUE(
dbfull()->GetIntProperty("rocksdb.num-live-versions", &int_num));
ASSERT_EQ(int_num, 1U);
}
} }
TEST(DBTest, FLUSH) { TEST(DBTest, FLUSH) {

@ -140,6 +140,8 @@ DBPropertyType GetPropertyType(const Slice& property, bool* is_int_property,
return kNumSnapshots; return kNumSnapshots;
} else if (in == "oldest-snapshot-time") { } else if (in == "oldest-snapshot-time") {
return kOldestSnapshotTime; return kOldestSnapshotTime;
} else if (in == "num-live-versions") {
return kNumLiveVersions;
} }
return kUnknown; return kUnknown;
} }
@ -224,6 +226,7 @@ bool InternalStats::GetStringProperty(DBPropertyType property_type,
bool InternalStats::GetIntProperty(DBPropertyType property_type, bool InternalStats::GetIntProperty(DBPropertyType property_type,
uint64_t* value, DBImpl* db) const { uint64_t* value, DBImpl* db) const {
db->mutex_.AssertHeld();
const auto* vstorage = cfd_->current()->storage_info(); const auto* vstorage = cfd_->current()->storage_info();
switch (property_type) { switch (property_type) {
@ -273,6 +276,9 @@ bool InternalStats::GetIntProperty(DBPropertyType property_type,
case kOldestSnapshotTime: case kOldestSnapshotTime:
*value = static_cast<uint64_t>(db->snapshots().GetOldestSnapshotTime()); *value = static_cast<uint64_t>(db->snapshots().GetOldestSnapshotTime());
return true; return true;
case kNumLiveVersions:
*value = cfd_->GetNumLiveVersions();
return true;
#ifndef ROCKSDB_LITE #ifndef ROCKSDB_LITE
case kIsFileDeletionEnabled: case kIsFileDeletionEnabled:
*value = db->IsFileDeletionsEnabled(); *value = db->IsFileDeletionsEnabled();

@ -50,6 +50,7 @@ enum DBPropertyType : uint32_t {
// 0 means file deletions enabled // 0 means file deletions enabled
kNumSnapshots, // Number of snapshots in the system kNumSnapshots, // Number of snapshots in the system
kOldestSnapshotTime, // Unix timestamp of the first snapshot kOldestSnapshotTime, // Unix timestamp of the first snapshot
kNumLiveVersions,
}; };
extern DBPropertyType GetPropertyType(const Slice& property, extern DBPropertyType GetPropertyType(const Slice& property,

@ -2807,4 +2807,12 @@ ColumnFamilyData* VersionSet::CreateColumnFamily(
return new_cfd; return new_cfd;
} }
uint64_t VersionSet::GetNumLiveVersions(Version* dummy_versions) {
uint64_t count = 0;
for (Version* v = dummy_versions->next_; v != dummy_versions; v = v->next_) {
count++;
}
return count;
}
} // namespace rocksdb } // namespace rocksdb

@ -596,6 +596,8 @@ class VersionSet {
ColumnFamilySet* GetColumnFamilySet() { return column_family_set_.get(); } ColumnFamilySet* GetColumnFamilySet() { return column_family_set_.get(); }
const EnvOptions& env_options() { return env_options_; } const EnvOptions& env_options() { return env_options_; }
static uint64_t GetNumLiveVersions(Version* dummy_versions);
private: private:
struct ManifestWriter; struct ManifestWriter;

@ -325,6 +325,10 @@ class DB {
// "rocksdb.is-file-deletions-enabled" // "rocksdb.is-file-deletions-enabled"
// "rocksdb.num-snapshots" // "rocksdb.num-snapshots"
// "rocksdb.oldest-snapshot-time" // "rocksdb.oldest-snapshot-time"
// "rocksdb.num-live-versions" - `version` is an internal data structure.
// See version_set.h for details. More live versions often mean more SST
// files are held from being deleted, by iterators or unfinished
// compactions.
virtual bool GetProperty(ColumnFamilyHandle* column_family, virtual bool GetProperty(ColumnFamilyHandle* column_family,
const Slice& property, std::string* value) = 0; const Slice& property, std::string* value) = 0;
virtual bool GetProperty(const Slice& property, std::string* value) { virtual bool GetProperty(const Slice& property, std::string* value) {
@ -347,6 +351,7 @@ class DB {
// "rocksdb.is-file-deletions-enabled" // "rocksdb.is-file-deletions-enabled"
// "rocksdb.num-snapshots" // "rocksdb.num-snapshots"
// "rocksdb.oldest-snapshot-time" // "rocksdb.oldest-snapshot-time"
// "rocksdb.num-live-versions"
virtual bool GetIntProperty(ColumnFamilyHandle* column_family, virtual bool GetIntProperty(ColumnFamilyHandle* column_family,
const Slice& property, uint64_t* value) = 0; const Slice& property, uint64_t* value) = 0;
virtual bool GetIntProperty(const Slice& property, uint64_t* value) { virtual bool GetIntProperty(const Slice& property, uint64_t* value) {

Loading…
Cancel
Save