diff --git a/scylla-gdb.py b/scylla-gdb.py index 4bc6327ccb..a4e9c1f5bf 100644 --- a/scylla-gdb.py +++ b/scylla-gdb.py @@ -50,6 +50,8 @@ class intrusive_list: # Some boost versions have this instead self.root = rps['m_header'] member_hook = get_template_arg_with_prefix(list_type, "boost::intrusive::member_hook") + if not member_hook: + member_hook = get_template_arg_with_prefix(list_type, "struct boost::intrusive::member_hook") if member_hook: self.link_offset = member_hook.template_argument(2).cast(self.size_t) else: @@ -2280,16 +2282,8 @@ class scylla_cache(gdb.Command): def find_sstables(): """A generator which yields pointers to all live sstable objects on current shard.""" - visited = set() - # FIXME: Add support for other sstable sets. Also, we should change Scylla to make this easier - for sst_set in find_instances('sstables::bag_sstable_set'): - sstables = std_vector(sst_set['_sstables']) - for sst_ptr in sstables: - sst = seastar_lw_shared_ptr(sst_ptr).get() - if not int(sst) in visited: - visited.add(int(sst)) - yield sst - + for sst in intrusive_list(gdb.parse_and_eval('sstables::tracker._sstables')): + yield sst.address class scylla_sstables(gdb.Command): """Lists all sstable objects on currents shard together with useful information like on-disk and in-memory size.""" @@ -2305,6 +2299,8 @@ class scylla_sstables(gdb.Command): count = 0 for sst in find_sstables(): + if not sst['_open']: + continue count += 1 size = 0 diff --git a/sstables/sstables.cc b/sstables/sstables.cc index 9485a27ed9..afae6ed887 100644 --- a/sstables/sstables.cc +++ b/sstables/sstables.cc @@ -84,6 +84,20 @@ namespace sstables { logging::logger sstlog("sstable"); +namespace bi = boost::intrusive; + +class sstable_tracker { + bi::list, + bi::constant_time_size> _sstables; +public: + void add(sstable& sst) { + _sstables.push_back(sst); + } +}; + +static thread_local sstable_tracker tracker; + // Because this is a noop and won't hold any state, it is better to use a global than a // thread_local. It will be faster, specially on non-x86. static noop_write_monitor default_noop_write_monitor; @@ -1277,6 +1291,7 @@ future<> sstable::open_data() { } auto* sm = _components->scylla_metadata->data.get(); if (!sm) { + _open = true; return make_ready_future<>(); } auto c = &sm->token_ranges.elements; @@ -1286,6 +1301,7 @@ future<> sstable::open_data() { return make_ready_future<>(); }).then([this, c] () mutable { c = {}; + _open = true; return make_ready_future<>(); }); }); @@ -3349,6 +3365,29 @@ mutation_source sstable::as_mutation_source() { }); } +sstable::sstable(schema_ptr schema, + sstring dir, + int64_t generation, + version_types v, + format_types f, + db::large_data_handler& large_data_handler, + gc_clock::time_point now, + io_error_handler_gen error_handler_gen, + size_t buffer_size) + : sstable_buffer_size(buffer_size) + , _schema(std::move(schema)) + , _dir(std::move(dir)) + , _generation(generation) + , _version(v) + , _format(f) + , _now(now) + , _read_error_handler(error_handler_gen(sstable_read_error)) + , _write_error_handler(error_handler_gen(sstable_write_error)) + , _large_data_handler(large_data_handler) +{ + tracker.add(*this); +} + bool supports_correct_non_compound_range_tombstones() { return service::get_local_storage_service().cluster_supports_reading_correctly_serialized_range_tombstones(); } diff --git a/sstables/sstables.hh b/sstables/sstables.hh index e1a9f1dd33..7cc254ea68 100644 --- a/sstables/sstables.hh +++ b/sstables/sstables.hh @@ -64,6 +64,7 @@ #include "sstables/shareable_components.hh" #include +#include class sstable_assertions; @@ -123,11 +124,15 @@ struct sstable_writer_config { utils::UUID run_identifier = utils::make_random_uuid(); }; +class sstable_tracker; + class sstable : public enable_lw_shared_from_this { friend ::sstable_assertions; + friend sstable_tracker; public: using version_types = sstable_version_types; using format_types = sstable_format_types; + using tracker_link_type = bi::list_member_hook>; public: sstable(schema_ptr schema, sstring dir, @@ -137,21 +142,10 @@ public: db::large_data_handler& large_data_handler, gc_clock::time_point now, io_error_handler_gen error_handler_gen, - size_t buffer_size) - : sstable_buffer_size(buffer_size) - , _schema(std::move(schema)) - , _dir(std::move(dir)) - , _generation(generation) - , _version(v) - , _format(f) - , _now(now) - , _read_error_handler(error_handler_gen(sstable_read_error)) - , _write_error_handler(error_handler_gen(sstable_write_error)) - , _large_data_handler(large_data_handler) - { } + size_t buffer_size); sstable& operator=(const sstable&) = delete; sstable(const sstable&) = delete; - sstable(sstable&&) = default; + sstable(sstable&&) = delete; ~sstable(); @@ -472,6 +466,7 @@ private: foreign_ptr> _components = make_foreign(make_lw_shared()); column_translation _column_translation; bool _shared = true; // across shards; safe default + bool _open = false; // NOTE: _collector and _c_stats are used to generation of statistics file // when writing a new sstable. metadata_collector _collector; @@ -546,6 +541,7 @@ private: db::large_data_handler& _large_data_handler; sstables_stats _stats; + tracker_link_type _tracker_link; public: const bool has_component(component_type f) const;