@@ -67,6 +67,75 @@ void DB::BgSaveDB() {
6767 g_pika_server->BGSaveTaskSchedule (&DoBgSave, static_cast <void *>(bg_task_arg));
6868}
6969
70+ pstd::Status DB::CreateCheckpoint (const std::string& checkpoint_dir) {
71+ std::string checkpoint_sub_path = checkpoint_dir;
72+ if (!checkpoint_sub_path.empty () && checkpoint_sub_path.back () != ' /' ) {
73+ checkpoint_sub_path.push_back (' /' );
74+ }
75+ checkpoint_sub_path += db_name_;
76+
77+ if (!pstd::FileExists (checkpoint_sub_path)) {
78+ if (pstd::CreatePath (checkpoint_sub_path, 0755 ) != 0 ) {
79+ return Status::IOError (" Failed to create checkpoint path" , checkpoint_sub_path);
80+ }
81+ }
82+
83+ std::shared_lock guard (dbs_rw_);
84+ auto tasks = storage_->CreateCheckpoint (checkpoint_sub_path);
85+ for (auto & task : tasks) {
86+ auto status = task.get ();
87+ if (!status.ok ()) {
88+ return Status::Corruption (" Create checkpoint failed: " + status.ToString ());
89+ }
90+ }
91+ return Status::OK ();
92+ }
93+
94+ pstd::Status DB::LoadDBFromCheckpoint (const std::string& checkpoint_dir) {
95+ std::string checkpoint_sub_path = checkpoint_dir;
96+ if (!checkpoint_sub_path.empty () && checkpoint_sub_path.back () != ' /' ) {
97+ checkpoint_sub_path.push_back (' /' );
98+ }
99+ checkpoint_sub_path += db_name_;
100+
101+ if (!pstd::FileExists (checkpoint_sub_path)) {
102+ return Status::NotFound (" Checkpoint dir does not exist: " + checkpoint_sub_path);
103+ }
104+
105+ std::lock_guard<std::shared_mutex> guard (dbs_rw_);
106+ opened_ = false ;
107+
108+ auto old_storage = storage_;
109+ storage_.reset ();
110+ if (old_storage) {
111+ old_storage->Close ();
112+ }
113+
114+ storage_ = std::make_shared<storage::Storage>();
115+ auto checkpoint_tasks = storage_->LoadCheckpoint (checkpoint_sub_path, db_path_);
116+ for (auto & task : checkpoint_tasks) {
117+ auto status = task.get ();
118+ if (!status.ok ()) {
119+ storage_.reset ();
120+ return Status::Corruption (" Load checkpoint failed: " + status.ToString ());
121+ }
122+ }
123+
124+ storage::StorageOptions storage_options = g_pika_server->storage_options ();
125+ auto open_status = storage_->Open (storage_options, db_path_);
126+ if (!open_status.ok ()) {
127+ storage_.reset ();
128+ return Status::Corruption (" Storage open failed: " + open_status.ToString ());
129+ }
130+
131+ if (!g_pika_conf->raft_enabled ()) {
132+ storage_->DisableWal (false );
133+ }
134+
135+ opened_ = true ;
136+ return Status::OK ();
137+ }
138+
70139void DB::SetBinlogIoError () { return binlog_io_error_.store (true ); }
71140void DB::SetBinlogIoErrorrelieve () { return binlog_io_error_.store (false ); }
72141bool DB::IsBinlogIoError () { return binlog_io_error_.load (); }
0 commit comments