From 116d4ae02bbc231a5beb2e8fb5c0d6a69906bcb5 Mon Sep 17 00:00:00 2001 From: Tomasz Grabiec Date: Thu, 31 Aug 2017 12:39:30 +0200 Subject: [PATCH] database: Make add_sstable() have strong exception guarantees If insert() fails, we left the database with stats updated, but sstable not being attached. --- database.cc | 7 ++++--- database.hh | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/database.cc b/database.cc index a67a22d5fc..7b48376344 100644 --- a/database.cc +++ b/database.cc @@ -785,7 +785,7 @@ void column_family::load_sstable(sstables::shared_sstable& sst, bool reset_level add_sstable(sst, std::move(shards)); } -void column_family::update_stats_for_new_sstable(uint64_t disk_space_used_by_sstable, std::vector&& shards_for_the_sstable) { +void column_family::update_stats_for_new_sstable(uint64_t disk_space_used_by_sstable, std::vector&& shards_for_the_sstable) noexcept { assert(!shards_for_the_sstable.empty()); if (*boost::min_element(shards_for_the_sstable) == engine().cpu_id()) { _stats.live_disk_space_used += disk_space_used_by_sstable; @@ -796,9 +796,10 @@ void column_family::update_stats_for_new_sstable(uint64_t disk_space_used_by_sst void column_family::add_sstable(lw_shared_ptr sstable, std::vector&& shards_for_the_sstable) { // allow in-progress reads to continue using old list - _sstables = make_lw_shared(*_sstables); + auto new_sstables = make_lw_shared(*_sstables); + new_sstables->insert(sstable); + _sstables = std::move(new_sstables); update_stats_for_new_sstable(sstable->bytes_on_disk(), std::move(shards_for_the_sstable)); - _sstables->insert(std::move(sstable)); } future<> diff --git a/database.hh b/database.hh index 3c35015326..f6ed1b012e 100644 --- a/database.hh +++ b/database.hh @@ -438,12 +438,13 @@ private: // have to get. It will be closed by stop(). seastar::gate _async_gate; private: - void update_stats_for_new_sstable(uint64_t disk_space_used_by_sstable, std::vector&& shards_for_the_sstable); + void update_stats_for_new_sstable(uint64_t disk_space_used_by_sstable, std::vector&& shards_for_the_sstable) noexcept; // Adds new sstable to the set of sstables // Doesn't update the cache. The cache must be synchronized in order for reads to see // the writes contained in this sstable. // Cache must be synchronized atomically with this, otherwise write atomicity may not be respected. // Doesn't trigger compaction. + // Strong exception guarantees. void add_sstable(lw_shared_ptr sstable, std::vector&& shards_for_the_sstable); // returns an empty pointer if sstable doesn't belong to current shard. future> open_sstable(sstables::foreign_sstable_open_info info, sstring dir,