@@ -35,6 +35,8 @@ void BackupableDBOptions::Dump(Logger* logger) const {
35
35
Log (logger, " Options.sync: %d" , static_cast <int >(sync ));
36
36
Log (logger, " Options.destroy_old_data: %d" ,
37
37
static_cast <int >(destroy_old_data));
38
+ Log (logger, " Options.backup_log_files: %d" ,
39
+ static_cast <int >(backup_log_files));
38
40
}
39
41
40
42
// -------- BackupEngineImpl class ---------
@@ -50,14 +52,21 @@ class BackupEngineImpl : public BackupEngine {
50
52
}
51
53
52
54
void GetBackupInfo (std::vector<BackupInfo>* backup_info);
53
- Status RestoreDBFromBackup (BackupID backup_id, const std::string &db_dir,
54
- const std::string &wal_dir);
55
- Status RestoreDBFromLatestBackup (const std::string &db_dir,
56
- const std::string &wal_dir) {
57
- return RestoreDBFromBackup (latest_backup_id_, db_dir, wal_dir);
55
+ Status RestoreDBFromBackup (BackupID backup_id, const std::string& db_dir,
56
+ const std::string& wal_dir,
57
+ const RestoreOptions& restore_options =
58
+ RestoreOptions ());
59
+ Status RestoreDBFromLatestBackup (const std::string& db_dir,
60
+ const std::string& wal_dir,
61
+ const RestoreOptions& restore_options =
62
+ RestoreOptions ()) {
63
+ return RestoreDBFromBackup (latest_backup_id_, db_dir, wal_dir,
64
+ restore_options);
58
65
}
59
66
60
67
private:
68
+ void DeleteChildren (const std::string& dir, uint32_t file_type_filter = 0 );
69
+
61
70
struct FileInfo {
62
71
FileInfo (const std::string& fname, uint64_t sz, uint32_t checksum)
63
72
: refs(0 ), filename(fname), size(sz), checksum_value(checksum) {}
@@ -314,7 +323,8 @@ Status BackupEngineImpl::CreateNewBackup(DB* db, bool flush_before_backup) {
314
323
// this will return live_files prefixed with "/"
315
324
s = db->GetLiveFiles (live_files, &manifest_file_size, flush_before_backup);
316
325
}
317
- if (s.ok ()) {
326
+ // if we didn't flush before backup, we need to also get WAL files
327
+ if (s.ok () && !flush_before_backup && options_.backup_log_files ) {
318
328
// returns file names prefixed with "/"
319
329
s = db->GetSortedWalFiles (live_wal_files);
320
330
}
@@ -468,9 +478,9 @@ void BackupEngineImpl::GetBackupInfo(std::vector<BackupInfo>* backup_info) {
468
478
}
469
479
}
470
480
471
- Status BackupEngineImpl::RestoreDBFromBackup (BackupID backup_id,
472
- const std::string& db_dir ,
473
- const std::string& wal_dir ) {
481
+ Status BackupEngineImpl::RestoreDBFromBackup (
482
+ BackupID backup_id, const std::string& db_dir, const std::string& wal_dir ,
483
+ const RestoreOptions& restore_options ) {
474
484
auto backup_itr = backups_.find (backup_id);
475
485
if (backup_itr == backups_.end ()) {
476
486
return Status::NotFound (" Backup not found" );
@@ -481,25 +491,40 @@ Status BackupEngineImpl::RestoreDBFromBackup(BackupID backup_id,
481
491
}
482
492
483
493
Log (options_.info_log , " Restoring backup id %u\n " , backup_id);
494
+ Log (options_.info_log , " keep_log_files: %d\n " ,
495
+ static_cast <int >(restore_options.keep_log_files ));
484
496
485
497
// just in case. Ignore errors
486
498
db_env_->CreateDirIfMissing (db_dir);
487
499
db_env_->CreateDirIfMissing (wal_dir);
488
500
489
- // delete log files that might have been already in wal_dir.
490
- // This is important since they might get replayed to the restored DB,
491
- // which will then differ from the backuped DB
492
- std::vector<std::string> delete_children;
493
- db_env_->GetChildren (wal_dir, &delete_children); // ignore errors
494
- for (auto f : delete_children) {
495
- db_env_->DeleteFile (wal_dir + " /" + f); // ignore errors
496
- }
497
- // Also delete all the db_dir children. This is not so important
498
- // because obsolete files will be deleted by DBImpl::PurgeObsoleteFiles()
499
- delete_children.clear ();
500
- db_env_->GetChildren (db_dir, &delete_children); // ignore errors
501
- for (auto f : delete_children) {
502
- db_env_->DeleteFile (db_dir + " /" + f); // ignore errors
501
+ if (restore_options.keep_log_files ) {
502
+ // delete files in db_dir, but keep all the log files
503
+ DeleteChildren (db_dir, 1 << kLogFile );
504
+ // move all the files from archive dir to wal_dir
505
+ std::string archive_dir = ArchivalDirectory (wal_dir);
506
+ std::vector<std::string> archive_files;
507
+ db_env_->GetChildren (archive_dir, &archive_files); // ignore errors
508
+ for (const auto & f : archive_files) {
509
+ uint64_t number;
510
+ FileType type;
511
+ bool ok = ParseFileName (f, &number, &type);
512
+ if (ok && type == kLogFile ) {
513
+ Log (options_.info_log , " Moving log file from archive/ to wal_dir: %s" ,
514
+ f.c_str ());
515
+ Status s =
516
+ db_env_->RenameFile (archive_dir + " /" + f, wal_dir + " /" + f);
517
+ if (!s.ok ()) {
518
+ // if we can't move log file from archive_dir to wal_dir,
519
+ // we should fail, since it might mean data loss
520
+ return s;
521
+ }
522
+ }
523
+ }
524
+ } else {
525
+ DeleteChildren (wal_dir);
526
+ DeleteChildren (ArchivalDirectory (wal_dir));
527
+ DeleteChildren (db_dir);
503
528
}
504
529
505
530
Status s;
@@ -760,6 +785,23 @@ Status BackupEngineImpl::CalculateChecksum(const std::string& src, Env* src_env,
760
785
return s;
761
786
}
762
787
788
+ void BackupEngineImpl::DeleteChildren (const std::string& dir,
789
+ uint32_t file_type_filter) {
790
+ std::vector<std::string> children;
791
+ db_env_->GetChildren (dir, &children); // ignore errors
792
+
793
+ for (const auto & f : children) {
794
+ uint64_t number;
795
+ FileType type;
796
+ bool ok = ParseFileName (f, &number, &type);
797
+ if (ok && (file_type_filter & (1 << type))) {
798
+ // don't delete this file
799
+ continue ;
800
+ }
801
+ db_env_->DeleteFile (dir + " /" + f); // ignore errors
802
+ }
803
+ }
804
+
763
805
void BackupEngineImpl::GarbageCollection (bool full_scan) {
764
806
Log (options_.info_log , " Starting garbage collection" );
765
807
std::vector<std::string> to_delete;
@@ -1042,16 +1084,18 @@ RestoreBackupableDB::GetBackupInfo(std::vector<BackupInfo>* backup_info) {
1042
1084
backup_engine_->GetBackupInfo (backup_info);
1043
1085
}
1044
1086
1045
- Status RestoreBackupableDB::RestoreDBFromBackup (BackupID backup_id,
1046
- const std::string& db_dir,
1047
- const std::string& wal_dir) {
1048
- return backup_engine_->RestoreDBFromBackup (backup_id, db_dir, wal_dir);
1087
+ Status RestoreBackupableDB::RestoreDBFromBackup (
1088
+ BackupID backup_id, const std::string& db_dir, const std::string& wal_dir,
1089
+ const RestoreOptions& restore_options) {
1090
+ return backup_engine_->RestoreDBFromBackup (backup_id, db_dir, wal_dir,
1091
+ restore_options);
1049
1092
}
1050
1093
1051
- Status
1052
- RestoreBackupableDB::RestoreDBFromLatestBackup (const std::string& db_dir,
1053
- const std::string& wal_dir) {
1054
- return backup_engine_->RestoreDBFromLatestBackup (db_dir, wal_dir);
1094
+ Status RestoreBackupableDB::RestoreDBFromLatestBackup (
1095
+ const std::string& db_dir, const std::string& wal_dir,
1096
+ const RestoreOptions& restore_options) {
1097
+ return backup_engine_->RestoreDBFromLatestBackup (db_dir, wal_dir,
1098
+ restore_options);
1055
1099
}
1056
1100
1057
1101
Status RestoreBackupableDB::PurgeOldBackups (uint32_t num_backups_to_keep) {
0 commit comments