sstables: Add delete func to rename TOC ensuring table is marked dead

Note: "normal" remove_by_toc_name must now be prepared for and check
if the TOC of the sstable is already moved to temp file when we
get to the juicy delete parts.
Message-Id: <1458575440-505-1-git-send-email-calle@scylladb.com>
This commit is contained in:
Calle Wilund
2016-03-21 15:50:39 +00:00
committed by Pekka Enberg
parent 6fd6e57e80
commit 4e52b41a46
Notes: Avi Kivity 2016-03-26 22:06:40 +03:00
backport: 1.0
2 changed files with 48 additions and 6 deletions

View File

@@ -1800,16 +1800,23 @@ fsync_directory(sstring fname) {
future<>
remove_by_toc_name(sstring sstable_toc_name) {
return seastar::async([sstable_toc_name] {
auto dir = dirname(sstable_toc_name);
auto toc_file = open_checked_file_dma(sstable_read_error, sstable_toc_name, open_flags::ro).get0();
sstring prefix = sstable_toc_name.substr(0, sstable_toc_name.size() - TOC_SUFFIX.size());
auto new_toc_name = prefix + TEMPORARY_TOC_SUFFIX;
sstring dir;
if (sstable_write_io_check(file_exists, sstable_toc_name).get0()) {
dir = dirname(sstable_toc_name);
sstable_write_io_check(rename_file, sstable_toc_name, new_toc_name).get();
sstable_write_io_check(fsync_directory, dir).get();
} else {
dir = dirname(new_toc_name);
}
auto toc_file = open_checked_file_dma(sstable_read_error, new_toc_name, open_flags::ro).get0();
auto in = make_file_input_stream(toc_file);
auto size = toc_file.size().get0();
auto text = in.read_exactly(size).get0();
in.close().get();
sstring prefix = sstable_toc_name.substr(0, sstable_toc_name.size() - TOC_SUFFIX.size());
auto new_toc_name = prefix + TEMPORARY_TOC_SUFFIX;
sstable_write_io_check(rename_file, sstable_toc_name, new_toc_name).get();
sstable_write_io_check(fsync_directory, dir).get();
std::vector<sstring> components;
sstring all(text.begin(), text.end());
boost::split(components, all, boost::is_any_of("\n"));
@@ -1829,6 +1836,39 @@ remove_by_toc_name(sstring sstable_toc_name) {
});
}
future<>
sstable::mark_for_deletion_on_disk() {
mark_for_deletion();
auto toc_name = filename(component_type::TOC);
auto shard = std::hash<sstring>()(toc_name) % smp::count;
return smp::submit_to(shard, [toc_name] {
static thread_local std::unordered_set<sstring> renaming;
if (renaming.count(toc_name) > 0) {
return make_ready_future<>();
}
renaming.emplace(toc_name);
return seastar::async([toc_name] {
if (!sstable_write_io_check(file_exists, toc_name).get0()) {
return; // already gone
}
auto dir = dirname(toc_name);
auto toc_file = open_checked_file_dma(sstable_read_error, toc_name, open_flags::ro).get0();
sstring prefix = toc_name.substr(0, toc_name.size() - TOC_SUFFIX.size());
auto new_toc_name = prefix + TEMPORARY_TOC_SUFFIX;
sstable_write_io_check(rename_file, toc_name, new_toc_name).get();
sstable_write_io_check(fsync_directory, dir).get();
}).finally([toc_name] {
renaming.erase(toc_name);
});
});
}
future<>
sstable::remove_sstable_with_temp_toc(sstring ks, sstring cf, sstring dir, int64_t generation, version_types v, format_types f) {
return seastar::async([ks, cf, dir, generation, v, f] {

View File

@@ -245,6 +245,8 @@ public:
_marked_for_deletion = true;
}
future<> mark_for_deletion_on_disk();
bool marked_for_deletion() const {
return _marked_for_deletion;
}