Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add the ability to checkpoint an existing server, and spawn a read-only server on that view. #2548

Open
wants to merge 25 commits into
base: unstable
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e8fd991
Add checkpoints
Sep 20, 2024
b2ce62b
Move global variables to Config
nathanlo-hrt Sep 24, 2024
770ce93
Merge branch 'unstable' into unstable
nathanlo99 Sep 24, 2024
b3e93fe
Fix lint error, rename checkpoint -> snapshot, deduplicate error mess…
nathanlo99 Sep 30, 2024
60b0860
Merge branch 'unstable' into unstable
nathanlo99 Sep 30, 2024
810a86c
Trigger tests
nathanlo-hrt Oct 3, 2024
b866c5f
Merge branch 'unstable' into unstable
git-hulk Oct 5, 2024
5a43069
Merge branch 'unstable' into unstable
nathanlo99 Oct 14, 2024
916ce73
Merge branch 'unstable' into unstable
aleksraiden Oct 15, 2024
2edb82b
Merge branch 'unstable' into unstable
nathanlo99 Oct 18, 2024
50a32d1
Merge branch 'unstable' into unstable
nathanlo99 Oct 21, 2024
d27c1bc
Move functionality out of main.cc
nathanlo-hrt Oct 21, 2024
e46818a
Format
nathanlo-hrt Oct 24, 2024
e86e115
Merge branch 'unstable' into unstable
nathanlo99 Oct 24, 2024
6f76141
Merge branch 'unstable' into unstable
nathanlo99 Nov 5, 2024
53b0ed7
Move creating snapshot from constructor to Open()
nathanlo-hrt Nov 5, 2024
7f6d0a2
Make snapshot-dir read-only
nathanlo-hrt Nov 5, 2024
694f839
Remove trailing whitespace
nathanlo-hrt Nov 6, 2024
19f25b9
Fix 'const prevents move' issue
nathanlo-hrt Nov 6, 2024
786908f
Revert changes in main.cc
nathanlo-hrt Nov 7, 2024
838a4ab
Merge branch 'unstable' into unstable
nathanlo99 Nov 7, 2024
9e6865b
Merge branch 'unstable' into unstable
nathanlo99 Nov 11, 2024
15776e5
Merge branch 'unstable' into unstable
nathanlo99 Nov 13, 2024
79309ff
Merge branch 'unstable' into unstable
nathanlo99 Nov 14, 2024
6a6ca87
Merge branch 'unstable' into unstable
nathanlo99 Nov 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion src/cli/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@
#include <event2/thread.h>
#include <glog/logging.h>

#include <filesystem>
#include <iomanip>
#include <ostream>

#include "daemon_util.h"
#include "io_util.h"
#include "pid_util.h"
#include "rocksdb/utilities/checkpoint.h"
#include "scope_exit.h"
#include "server/server.h"
#include "signal_util.h"
Expand Down Expand Up @@ -113,6 +115,31 @@ static void InitGoogleLog(const Config *config) {
}
}

static Status CreateSnapshot(Config &config, const std::string &snapshot_location) {
// The Storage destructor deletes anything at the checkpoint_dir, so we need to make sure it's empty in case the user
// happens to use a snapshot name which matches the default (checkpoint/)
const std::string old_checkpoint_dir = std::exchange(config.checkpoint_dir, "");
const auto checkpoint_dir_guard =
MakeScopeExit([&config, &old_checkpoint_dir] { config.checkpoint_dir = old_checkpoint_dir; });

engine::Storage storage(&config);
if (const auto s = storage.Open(kDBOpenModeForReadOnly); !s.IsOK()) {
nathanlo99 marked this conversation as resolved.
Show resolved Hide resolved
return {Status::NotOK, fmt::format("failed to open DB in read-only mode: {}", s.Msg())};
}

rocksdb::Checkpoint *snapshot = nullptr;
if (const auto s = rocksdb::Checkpoint::Create(storage.GetDB(), &snapshot); !s.ok()) {
return {Status::NotOK, s.ToString()};
}

std::unique_ptr<rocksdb::Checkpoint> snapshot_guard(snapshot);
if (const auto s = snapshot->CreateCheckpoint(snapshot_location + "/db"); !s.ok()) {
return {Status::NotOK, s.ToString()};
}

return Status::OK();
}

int main(int argc, char *argv[]) {
srand(static_cast<unsigned>(util::GetTimeStamp()));

Expand Down Expand Up @@ -170,8 +197,27 @@ int main(int argc, char *argv[]) {
}
#endif

const bool use_snapshot = config.snapshot_dir != "";
if (use_snapshot) {
if (const auto s = CreateSnapshot(config, config.snapshot_dir); !s.IsOK()) {
LOG(ERROR) << "Failed to create snapshot: " << s.Msg();
return 1;
}
LOG(INFO) << "Starting server in read-only mode with snapshot dir: " << config.snapshot_dir;
config.db_dir = config.snapshot_dir + "/db";
}
const auto snapshot_exit = MakeScopeExit([use_snapshot, &config]() {
if (use_snapshot && !config.keep_snapshot) {
LOG(INFO) << "Removing snapshot dir: " << config.snapshot_dir;
std::filesystem::remove_all(config.snapshot_dir);
}
});

engine::Storage storage(&config);
s = storage.Open();
const bool read_only = use_snapshot;
const DBOpenMode open_mode = read_only ? kDBOpenModeForReadOnly : kDBOpenModeDefault;
s = storage.Open(open_mode);
nathanlo99 marked this conversation as resolved.
Show resolved Hide resolved

if (!s.IsOK()) {
LOG(ERROR) << "Failed to open: " << s.Msg();
return 1;
Expand Down
2 changes: 2 additions & 0 deletions src/config/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ Config::Config() {
new IntField(&force_compact_file_min_deleted_percentage, 10, 1, 100)},
{"db-name", true, new StringField(&db_name, "change.me.db")},
{"dir", true, new StringField(&dir, kDefaultDir)},
{"snapshot-dir", false, new StringField(&snapshot_dir, "")},
nathanlo99 marked this conversation as resolved.
Show resolved Hide resolved
{"keep-snapshot", false, new YesNoField(&keep_snapshot, false)},
nathanlo99 marked this conversation as resolved.
Show resolved Hide resolved
{"backup-dir", false, new StringField(&backup_dir, kDefaultBackupDir)},
{"log-dir", true, new StringField(&log_dir, "")},
{"log-level", false, new EnumField<int>(&log_level, log_levels, google::INFO)},
Expand Down
5 changes: 5 additions & 0 deletions src/config/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ struct Config {
std::string replica_announce_ip;
uint32_t replica_announce_port = 0;

// The following options exist so users can spawn a read-only server from a snapshot
// of a running server.
std::string snapshot_dir;
bool keep_snapshot = false;

bool persist_cluster_nodes_enabled = true;
bool slot_id_encoded = false;
bool cluster_enabled = false;
Expand Down