Skip to content

Commit dc277f0

Browse files
committed
[CF] Adaptation of GetLiveFiles for CF
Summary: Even if user flushes the memtables before getting live files, we still can't guarantee that new data didn't come in (to already-flushed memtables). If we want backups to provide consistent view of the database, we still need to get WAL files. Test Plan: backupable_db_test Reviewers: dhruba CC: leveldb Differential Revision: https://reviews.facebook.net/D16299
1 parent 5a91746 commit dc277f0

File tree

3 files changed

+28
-8
lines changed

3 files changed

+28
-8
lines changed

db/db_filesnapshot.cc

+21-3
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,35 @@ Status DBImpl::GetLiveFiles(std::vector<std::string>& ret,
6060

6161
*manifest_file_size = 0;
6262

63+
mutex_.Lock();
64+
6365
if (flush_memtable) {
6466
// flush all dirty data to disk.
65-
Status status = Flush(FlushOptions());
67+
autovector<ColumnFamilyData*> to_delete;
68+
Status status;
69+
for (auto cfd : *versions_->GetColumnFamilySet()) {
70+
cfd->Ref();
71+
mutex_.Unlock();
72+
status = FlushMemTable(cfd, FlushOptions());
73+
mutex_.Lock();
74+
if (cfd->Unref()) {
75+
to_delete.push_back(cfd);
76+
}
77+
if (!status.ok()) {
78+
break;
79+
}
80+
}
81+
for (auto cfd : to_delete) {
82+
delete cfd;
83+
}
6684
if (!status.ok()) {
85+
mutex_.Unlock();
6786
Log(options_.info_log, "Cannot Flush data %s\n",
6887
status.ToString().c_str());
6988
return status;
7089
}
7190
}
7291

73-
MutexLock l(&mutex_);
74-
7592
// Make a set of all of the live *.sst files
7693
std::set<uint64_t> live;
7794
for (auto cfd : *versions_->GetColumnFamilySet()) {
@@ -93,6 +110,7 @@ Status DBImpl::GetLiveFiles(std::vector<std::string>& ret,
93110
// find length of manifest file while holding the mutex lock
94111
*manifest_file_size = versions_->ManifestFileSize();
95112

113+
mutex_.Unlock();
96114
return Status::OK();
97115
}
98116

include/rocksdb/db.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -394,9 +394,12 @@ class DB {
394394
// Setting flush_memtable to true does Flush before recording the live files.
395395
// Setting flush_memtable to false is useful when we don't want to wait for
396396
// flush which may have to wait for compaction to complete taking an
397-
// indeterminate time. But this will have to use GetSortedWalFiles after
398-
// GetLiveFiles to compensate for memtables missed in this snapshot due to the
399-
// absence of Flush, by WAL files to recover the database consistently later
397+
// indeterminate time.
398+
//
399+
// In case you have multiple column families, even if flush_memtable is true,
400+
// you still need to call GetSortedWalFiles after GetLiveFiles to compensate
401+
// for new data that arrived to already-flushed column families while other
402+
// column families were flushing
400403
virtual Status GetLiveFiles(std::vector<std::string>&,
401404
uint64_t* manifest_file_size,
402405
bool flush_memtable = true) = 0;

utilities/backupable/backupable_db.cc

+1-2
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,7 @@ Status BackupEngineImpl::CreateNewBackup(DB* db, bool flush_before_backup) {
311311
// this will return live_files prefixed with "/"
312312
s = db->GetLiveFiles(live_files, &manifest_file_size, flush_before_backup);
313313
}
314-
// if we didn't flush before backup, we need to also get WAL files
315-
if (s.ok() && !flush_before_backup) {
314+
if (s.ok()) {
316315
// returns file names prefixed with "/"
317316
s = db->GetSortedWalFiles(live_wal_files);
318317
}

0 commit comments

Comments
 (0)