Skip to content

Commit ec2fa4a

Browse files
committed
Export BackupEngine
Summary: Lots of clients have problems with using StackableDB interface. It's nice to have BackupableDB as a layer on top of DB, but not necessary. This diff exports BackupEngine, which can be used to create backups without forcing clients to use StackableDB interface. Test Plan: backupable_db_test Reviewers: dhruba, ljin, swk Reviewed By: ljin CC: leveldb, benj Differential Revision: https://reviews.facebook.net/D15477
1 parent 9dc2941 commit ec2fa4a

File tree

2 files changed

+66
-45
lines changed

2 files changed

+66
-45
lines changed

include/utilities/backupable_db.h

+23-2
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@ struct BackupableDBOptions {
6868
destroy_old_data(_destroy_old_data) { }
6969
};
7070

71-
class BackupEngine;
72-
7371
typedef uint32_t BackupID;
7472

7573
struct BackupInfo {
@@ -82,6 +80,29 @@ struct BackupInfo {
8280
: backup_id(_backup_id), timestamp(_timestamp), size(_size) {}
8381
};
8482

83+
// Please see the documentation in BackupableDB and RestoreBackupableDB
84+
class BackupEngine {
85+
public:
86+
virtual ~BackupEngine() {}
87+
88+
virtual Status CreateNewBackup(DB* db, bool flush_before_backup = false) = 0;
89+
virtual Status PurgeOldBackups(uint32_t num_backups_to_keep) = 0;
90+
virtual Status DeleteBackup(BackupID backup_id) = 0;
91+
virtual void StopBackup() = 0;
92+
93+
virtual void GetBackupInfo(std::vector<BackupInfo>* backup_info) = 0;
94+
virtual Status RestoreDBFromBackup(BackupID backup_id,
95+
const std::string& db_dir,
96+
const std::string& wal_dir) = 0;
97+
virtual Status RestoreDBFromLatestBackup(const std::string& db_dir,
98+
const std::string& wal_dir) = 0;
99+
100+
virtual void DeleteBackupsNewerThan(uint64_t sequence_number) = 0;
101+
};
102+
103+
extern BackupEngine* CreateNewBackupEngine(Env* db_env,
104+
const BackupableDBOptions& options);
105+
85106
// Stack your DB with BackupableDB to be able to backup the DB
86107
class BackupableDB : public StackableDB {
87108
public:

utilities/backupable/backupable_db.cc

+43-43
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@
2626

2727
namespace rocksdb {
2828

29-
// -------- BackupEngine class ---------
30-
class BackupEngine {
29+
// -------- BackupEngineImpl class ---------
30+
class BackupEngineImpl : public BackupEngine {
3131
public:
32-
BackupEngine(Env* db_env, const BackupableDBOptions& options);
33-
~BackupEngine();
32+
BackupEngineImpl(Env* db_env, const BackupableDBOptions& options);
33+
~BackupEngineImpl();
3434
Status CreateNewBackup(DB* db, bool flush_before_backup = false);
3535
Status PurgeOldBackups(uint32_t num_backups_to_keep);
3636
Status DeleteBackup(BackupID backup_id);
@@ -188,7 +188,13 @@ class BackupEngine {
188188
static const size_t copy_file_buffer_size_ = 5 * 1024 * 1024LL; // 5MB
189189
};
190190

191-
BackupEngine::BackupEngine(Env* db_env, const BackupableDBOptions& options)
191+
BackupEngine* CreateNewBackupEngine(Env* db_env,
192+
const BackupableDBOptions& options) {
193+
return new BackupEngineImpl(db_env, options);
194+
}
195+
196+
BackupEngineImpl::BackupEngineImpl(Env* db_env,
197+
const BackupableDBOptions& options)
192198
: stop_backup_(false),
193199
options_(options),
194200
db_env_(db_env),
@@ -271,11 +277,9 @@ BackupEngine::BackupEngine(Env* db_env, const BackupableDBOptions& options)
271277
latest_backup_id_);
272278
}
273279

274-
BackupEngine::~BackupEngine() {
275-
LogFlush(options_.info_log);
276-
}
280+
BackupEngineImpl::~BackupEngineImpl() { LogFlush(options_.info_log); }
277281

278-
void BackupEngine::DeleteBackupsNewerThan(uint64_t sequence_number) {
282+
void BackupEngineImpl::DeleteBackupsNewerThan(uint64_t sequence_number) {
279283
for (auto backup : backups_) {
280284
if (backup.second.GetSequenceNumber() > sequence_number) {
281285
Log(options_.info_log,
@@ -295,7 +299,7 @@ void BackupEngine::DeleteBackupsNewerThan(uint64_t sequence_number) {
295299
GarbageCollection(false);
296300
}
297301

298-
Status BackupEngine::CreateNewBackup(DB* db, bool flush_before_backup) {
302+
Status BackupEngineImpl::CreateNewBackup(DB* db, bool flush_before_backup) {
299303
Status s;
300304
std::vector<std::string> live_files;
301305
VectorLogPtr live_wal_files;
@@ -405,7 +409,7 @@ Status BackupEngine::CreateNewBackup(DB* db, bool flush_before_backup) {
405409
return s;
406410
}
407411

408-
Status BackupEngine::PurgeOldBackups(uint32_t num_backups_to_keep) {
412+
Status BackupEngineImpl::PurgeOldBackups(uint32_t num_backups_to_keep) {
409413
Log(options_.info_log, "Purging old backups, keeping %u",
410414
num_backups_to_keep);
411415
while (num_backups_to_keep < backups_.size()) {
@@ -418,7 +422,7 @@ Status BackupEngine::PurgeOldBackups(uint32_t num_backups_to_keep) {
418422
return Status::OK();
419423
}
420424

421-
Status BackupEngine::DeleteBackup(BackupID backup_id) {
425+
Status BackupEngineImpl::DeleteBackup(BackupID backup_id) {
422426
Log(options_.info_log, "Deleting backup %u", backup_id);
423427
auto backup = backups_.find(backup_id);
424428
if (backup == backups_.end()) {
@@ -431,7 +435,7 @@ Status BackupEngine::DeleteBackup(BackupID backup_id) {
431435
return Status::OK();
432436
}
433437

434-
void BackupEngine::GetBackupInfo(std::vector<BackupInfo>* backup_info) {
438+
void BackupEngineImpl::GetBackupInfo(std::vector<BackupInfo>* backup_info) {
435439
backup_info->reserve(backups_.size());
436440
for (auto& backup : backups_) {
437441
if (!backup.second.Empty()) {
@@ -441,9 +445,9 @@ void BackupEngine::GetBackupInfo(std::vector<BackupInfo>* backup_info) {
441445
}
442446
}
443447

444-
Status BackupEngine::RestoreDBFromBackup(BackupID backup_id,
445-
const std::string &db_dir,
446-
const std::string &wal_dir) {
448+
Status BackupEngineImpl::RestoreDBFromBackup(BackupID backup_id,
449+
const std::string& db_dir,
450+
const std::string& wal_dir) {
447451
auto backup_itr = backups_.find(backup_id);
448452
if (backup_itr == backups_.end()) {
449453
return Status::NotFound("Backup not found");
@@ -517,7 +521,7 @@ Status BackupEngine::RestoreDBFromBackup(BackupID backup_id,
517521
}
518522

519523
// latest backup id is an ASCII representation of latest backup id
520-
Status BackupEngine::GetLatestBackupFileContents(uint32_t* latest_backup) {
524+
Status BackupEngineImpl::GetLatestBackupFileContents(uint32_t* latest_backup) {
521525
Status s;
522526
unique_ptr<SequentialFile> file;
523527
s = backup_env_->NewSequentialFile(GetLatestBackupFile(),
@@ -547,7 +551,7 @@ Status BackupEngine::GetLatestBackupFileContents(uint32_t* latest_backup) {
547551
// writing 4 bytes to the file is atomic alright, but we should *never*
548552
// do something like 1. delete file, 2. write new file
549553
// We write to a tmp file and then atomically rename
550-
Status BackupEngine::PutLatestBackupFileContents(uint32_t latest_backup) {
554+
Status BackupEngineImpl::PutLatestBackupFileContents(uint32_t latest_backup) {
551555
Status s;
552556
unique_ptr<WritableFile> file;
553557
EnvOptions env_options;
@@ -577,14 +581,11 @@ Status BackupEngine::PutLatestBackupFileContents(uint32_t latest_backup) {
577581
return s;
578582
}
579583

580-
Status BackupEngine::CopyFile(const std::string& src,
581-
const std::string& dst,
582-
Env* src_env,
583-
Env* dst_env,
584-
bool sync,
585-
uint64_t* size,
586-
uint32_t* checksum_value,
587-
uint64_t size_limit) {
584+
Status BackupEngineImpl::CopyFile(const std::string& src,
585+
const std::string& dst, Env* src_env,
586+
Env* dst_env, bool sync, uint64_t* size,
587+
uint32_t* checksum_value,
588+
uint64_t size_limit) {
588589
Status s;
589590
unique_ptr<WritableFile> dst_file;
590591
unique_ptr<SequentialFile> src_file;
@@ -644,12 +645,10 @@ Status BackupEngine::CopyFile(const std::string& src,
644645
}
645646

646647
// src_fname will always start with "/"
647-
Status BackupEngine::BackupFile(BackupID backup_id,
648-
BackupMeta* backup,
649-
bool shared,
650-
const std::string& src_dir,
651-
const std::string& src_fname,
652-
uint64_t size_limit) {
648+
Status BackupEngineImpl::BackupFile(BackupID backup_id, BackupMeta* backup,
649+
bool shared, const std::string& src_dir,
650+
const std::string& src_fname,
651+
uint64_t size_limit) {
653652

654653
assert(src_fname.size() > 0 && src_fname[0] == '/');
655654
std::string dst_relative = src_fname.substr(1);
@@ -697,10 +696,9 @@ Status BackupEngine::BackupFile(BackupID backup_id,
697696
return s;
698697
}
699698

700-
Status BackupEngine::CalculateChecksum(const std::string& src,
701-
Env* src_env,
702-
uint64_t size_limit,
703-
uint32_t* checksum_value) {
699+
Status BackupEngineImpl::CalculateChecksum(const std::string& src, Env* src_env,
700+
uint64_t size_limit,
701+
uint32_t* checksum_value) {
704702
*checksum_value = 0;
705703
if (size_limit == 0) {
706704
size_limit = std::numeric_limits<uint64_t>::max();
@@ -737,7 +735,7 @@ Status BackupEngine::CalculateChecksum(const std::string& src,
737735
return s;
738736
}
739737

740-
void BackupEngine::GarbageCollection(bool full_scan) {
738+
void BackupEngineImpl::GarbageCollection(bool full_scan) {
741739
Log(options_.info_log, "Starting garbage collection");
742740
std::vector<std::string> to_delete;
743741
for (auto& itr : backuped_file_infos_) {
@@ -817,7 +815,7 @@ void BackupEngine::GarbageCollection(bool full_scan) {
817815

818816
// ------- BackupMeta class --------
819817

820-
Status BackupEngine::BackupMeta::AddFile(const FileInfo& file_info) {
818+
Status BackupEngineImpl::BackupMeta::AddFile(const FileInfo& file_info) {
821819
size_ += file_info.size;
822820
files_.push_back(file_info.filename);
823821

@@ -840,7 +838,7 @@ Status BackupEngine::BackupMeta::AddFile(const FileInfo& file_info) {
840838
return Status::OK();
841839
}
842840

843-
void BackupEngine::BackupMeta::Delete() {
841+
void BackupEngineImpl::BackupMeta::Delete() {
844842
for (const auto& file : files_) {
845843
auto itr = file_infos_->find(file);
846844
assert(itr != file_infos_->end());
@@ -860,7 +858,8 @@ void BackupEngine::BackupMeta::Delete() {
860858
// <file2> <crc32(literal string)> <crc32_value>
861859
// ...
862860
// TODO: maybe add checksum?
863-
Status BackupEngine::BackupMeta::LoadFromFile(const std::string& backup_dir) {
861+
Status BackupEngineImpl::BackupMeta::LoadFromFile(
862+
const std::string& backup_dir) {
864863
assert(Empty());
865864
Status s;
866865
unique_ptr<SequentialFile> backup_meta_file;
@@ -927,7 +926,7 @@ Status BackupEngine::BackupMeta::LoadFromFile(const std::string& backup_dir) {
927926
return s;
928927
}
929928

930-
Status BackupEngine::BackupMeta::StoreToFile(bool sync) {
929+
Status BackupEngineImpl::BackupMeta::StoreToFile(bool sync) {
931930
Status s;
932931
unique_ptr<WritableFile> backup_meta_file;
933932
EnvOptions env_options;
@@ -969,7 +968,8 @@ Status BackupEngine::BackupMeta::StoreToFile(bool sync) {
969968
// --- BackupableDB methods --------
970969

971970
BackupableDB::BackupableDB(DB* db, const BackupableDBOptions& options)
972-
: StackableDB(db), backup_engine_(new BackupEngine(db->GetEnv(), options)) {
971+
: StackableDB(db),
972+
backup_engine_(new BackupEngineImpl(db->GetEnv(), options)) {
973973
if (options.share_table_files) {
974974
backup_engine_->DeleteBackupsNewerThan(GetLatestSequenceNumber());
975975
}
@@ -1003,7 +1003,7 @@ void BackupableDB::StopBackup() {
10031003

10041004
RestoreBackupableDB::RestoreBackupableDB(Env* db_env,
10051005
const BackupableDBOptions& options)
1006-
: backup_engine_(new BackupEngine(db_env, options)) {}
1006+
: backup_engine_(new BackupEngineImpl(db_env, options)) {}
10071007

10081008
RestoreBackupableDB::~RestoreBackupableDB() {
10091009
delete backup_engine_;

0 commit comments

Comments
 (0)