diff --git a/database.cc b/database.cc index 7a4a1e1c41..e1c2ef118d 100644 --- a/database.cc +++ b/database.cc @@ -1691,7 +1691,18 @@ future<> column_family::snapshot(sstring name) { return parallel_for_each(tables, [name](sstables::shared_sstable sstable) { auto dir = sstable->get_dir() + "/snapshots/" + name; return recursive_touch_directory(dir).then([sstable, dir] { - return sstable->create_links(dir); + return sstable->create_links(dir).then_wrapped([] (future<> f) { + // If the SSTables are shared, one of the CPUs will fail here. + // That is completely fine, though. We only need one link. + try { + f.get(); + } catch (std::system_error& e) { + if (e.code() != std::error_code(EEXIST, std::system_category())) { + throw; + } + } + return make_ready_future<>(); + }); }); }).then([jsondir, &tables] { // This is not just an optimization. If we have no files, jsondir may not have been created, @@ -1701,7 +1712,7 @@ future<> column_family::snapshot(sstring name) { } else { return make_ready_future<>(); } - }).then([this, &tables, jsondir] { + }).finally([this, &tables, jsondir] { auto shard = std::hash()(jsondir) % smp::count; std::unordered_set table_names; for (auto& sst : tables) {