Skip to content

Commit

Permalink
Add a DB Session ID (facebook#6959)
Browse files Browse the repository at this point in the history
Summary:
Added DB::GetDbSessionId by using the same format and machinery as DB::GetDbIdentity.
The DB Session ID is generated (and therefore, updated) each time a DB object is opened. It is written to the LOG file right after the line of “DB SUMMARY”.
A test for the uniqueness, for different openings and during the same opening, is also added.
Pull Request resolved: facebook#6959

Test Plan: Passed make check

Reviewed By: zhichao-cao

Differential Revision: D21951721

Pulled By: gg814

fbshipit-source-id: 958a48a612db49a39998ea703cded45987d3fa8b
  • Loading branch information
gg814 authored and facebook-github-bot committed Jun 15, 2020
1 parent 9c24a5c commit 88db97b
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 3 deletions.
1 change: 1 addition & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
* `pin_l0_filter_and_index_blocks_in_cache` no longer applies to L0 files larger than `1.5 * write_buffer_size` to give more predictable memory usage. Such L0 files may exist due to intra-L0 compaction, external file ingestion, or user dynamically changing `write_buffer_size` (note, however, that files that are already pinned will continue being pinned, even after such a dynamic change).
* In point-in-time wal recovery mode, fail database recovery in case of IOError while reading the WAL to avoid data loss.
* A new method `Env::LowerThreadPoolCPUPriority(Priority, CpuPriority)` is added to `Env` to be able to lower to a specific priority such as `CpuPriority::kIdle`.
* `DB::GetDbSessionId(std::string& session_id)` is added. `session_id` stores a unique identifier that gets reset every time the DB is opened. This DB session ID should be unique among all open DB instances on all hosts, and should be unique among re-openings of the same or other DBs. This identifier is recorded in the `LOG` file on the line starting with `DB Session ID:`.

### New Features
* sst_dump to add a new --readahead_size argument. Users can specify read size when scanning the data. Sst_dump also tries to prefetch tail part of the SST files so usually some number of I/Os are saved there too.
Expand Down
50 changes: 50 additions & 0 deletions db/db_basic_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,56 @@ TEST_F(DBBasicTest, OpenWhenOpen) {
delete db2;
}

TEST_F(DBBasicTest, UniqueSession) {
Options options = CurrentOptions();
std::string sid1, sid2, sid3, sid4;

db_->GetDbSessionId(sid1);
Reopen(options);
db_->GetDbSessionId(sid2);
ASSERT_OK(Put("foo", "v1"));
db_->GetDbSessionId(sid4);
Reopen(options);
db_->GetDbSessionId(sid3);

ASSERT_NE(sid1, sid2);
ASSERT_NE(sid1, sid3);
ASSERT_NE(sid2, sid3);

ASSERT_EQ(sid2, sid4);

#ifndef ROCKSDB_LITE
Close();
ASSERT_OK(ReadOnlyReopen(options));
db_->GetDbSessionId(sid1);
// Test uniqueness between readonly open (sid1) and regular open (sid3)
ASSERT_NE(sid1, sid3);
Close();
ASSERT_OK(ReadOnlyReopen(options));
db_->GetDbSessionId(sid2);
ASSERT_EQ("v1", Get("foo"));
db_->GetDbSessionId(sid3);

ASSERT_NE(sid1, sid2);

ASSERT_EQ(sid2, sid3);
#endif // ROCKSDB_LITE

CreateAndReopenWithCF({"goku"}, options);
db_->GetDbSessionId(sid1);
ASSERT_OK(Put("bar", "e1"));
db_->GetDbSessionId(sid2);
ASSERT_EQ("e1", Get("bar"));
db_->GetDbSessionId(sid3);
ReopenWithColumnFamilies({"default", "goku"}, options);
db_->GetDbSessionId(sid4);

ASSERT_EQ(sid1, sid2);
ASSERT_EQ(sid2, sid3);

ASSERT_NE(sid1, sid4);
}

#ifndef ROCKSDB_LITE
TEST_F(DBBasicTest, ReadOnlyDB) {
ASSERT_OK(Put("foo", "v1"));
Expand Down
18 changes: 17 additions & 1 deletion db/db_impl/db_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,8 @@ DBImpl::DBImpl(const DBOptions& options, const std::string& dbname,
new ColumnFamilyMemTablesImpl(versions_->GetColumnFamilySet()));

DumpRocksDBBuildVersion(immutable_db_options_.info_log.get());
DumpDBFileSummary(immutable_db_options_, dbname_);
SetDbSessionId();
DumpDBFileSummary(immutable_db_options_, dbname_, db_session_id_);
immutable_db_options_.Dump(immutable_db_options_.info_log.get());
mutable_db_options_.Dump(immutable_db_options_.info_log.get());
DumpSupportInfo(immutable_db_options_.info_log.get());
Expand Down Expand Up @@ -3601,6 +3602,21 @@ Status DBImpl::GetDbIdentityFromIdentityFile(std::string* identity) const {
return s;
}

Status DBImpl::GetDbSessionId(std::string& session_id) const {
session_id.assign(db_session_id_);
return Status::OK();
}

void DBImpl::SetDbSessionId() {
// GenerateUniqueId() generates an identifier
// that has a negligible probability of being duplicated
db_session_id_ = env_->GenerateUniqueId();
// Remove the extra '\n' at the end if there is one
if (!db_session_id_.empty() && db_session_id_.back() == '\n') {
db_session_id_.pop_back();
}
}

// Default implementation -- returns not supported status
Status DB::CreateColumnFamily(const ColumnFamilyOptions& /*cf_options*/,
const std::string& /*column_family_name*/,
Expand Down
9 changes: 9 additions & 0 deletions db/db_impl/db_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@ class DBImpl : public DB {

virtual Status GetDbIdentityFromIdentityFile(std::string* identity) const;

virtual Status GetDbSessionId(std::string& session_id) const override;

ColumnFamilyHandle* DefaultColumnFamily() const override;

ColumnFamilyHandle* PersistentStatsColumnFamily() const;
Expand Down Expand Up @@ -980,6 +982,9 @@ class DBImpl : public DB {
protected:
const std::string dbname_;
std::string db_id_;
// db_session_id_ is an identifier that gets reset
// every time the DB is opened
std::string db_session_id_;
std::unique_ptr<VersionSet> versions_;
// Flag to check whether we allocated and own the info log file
bool own_info_log_;
Expand Down Expand Up @@ -1161,6 +1166,10 @@ class DBImpl : public DB {
// bump up the version set's next_file_number_ to be 1 + largest_file_number.
Status FinishBestEffortsRecovery();

// SetDbSessionId() should be called in the constuctor DBImpl()
// to ensure that db_session_id_ gets updated every time the DB is opened
void SetDbSessionId();

private:
friend class DB;
friend class ErrorHandler;
Expand Down
5 changes: 4 additions & 1 deletion db/db_info_dumper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
namespace ROCKSDB_NAMESPACE {

void DumpDBFileSummary(const ImmutableDBOptions& options,
const std::string& dbname) {
const std::string& dbname,
const std::string& session_id) {
if (options.info_log == nullptr) {
return;
}
Expand All @@ -32,6 +33,8 @@ void DumpDBFileSummary(const ImmutableDBOptions& options,
std::string file_info, wal_info;

Header(options.info_log, "DB SUMMARY\n");
Header(options.info_log, "DB Session ID: %s\n", session_id.c_str());

// Get files in dbname dir
if (!env->GetChildren(dbname, &files).ok()) {
Error(options.info_log,
Expand Down
3 changes: 2 additions & 1 deletion db/db_info_dumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@

namespace ROCKSDB_NAMESPACE {
void DumpDBFileSummary(const ImmutableDBOptions& options,
const std::string& dbname);
const std::string& dbname,
const std::string& session_id = "");
} // namespace ROCKSDB_NAMESPACE
4 changes: 4 additions & 0 deletions db/db_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3031,6 +3031,10 @@ class ModelDB : public DB {
return Status::OK();
}

Status GetDbSessionId(std::string& /*session_id*/) const override {
return Status::OK();
}

SequenceNumber GetLatestSequenceNumber() const override { return 0; }

bool SetPreserveDeletesSequenceNumber(SequenceNumber /*seqnum*/) override {
Expand Down
7 changes: 7 additions & 0 deletions include/rocksdb/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -1544,6 +1544,13 @@ class DB {
// Returns Status::OK if identity could be set properly
virtual Status GetDbIdentity(std::string& identity) const = 0;

// Return a unique identifier for each DB object that is opened
// This DB session ID should be unique among all open DB instances on all
// hosts, and should be unique among re-openings of the same or other DBs.
// (Two open DBs have the same identity from other function GetDbIdentity when
// one is physically copied from the other.)
virtual Status GetDbSessionId(std::string& session_id) const = 0;

// Returns default column family handle
virtual ColumnFamilyHandle* DefaultColumnFamily() const = 0;

Expand Down
4 changes: 4 additions & 0 deletions include/rocksdb/utilities/stackable_db.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,10 @@ class StackableDB : public DB {
return db_->GetDbIdentity(identity);
}

virtual Status GetDbSessionId(std::string& session_id) const override {
return db_->GetDbSessionId(session_id);
}

using DB::SetOptions;
virtual Status SetOptions(ColumnFamilyHandle* column_family_handle,
const std::unordered_map<std::string, std::string>&
Expand Down

0 comments on commit 88db97b

Please sign in to comment.