From 3b9386c75c661686e73ba0e3a6a53799c1bfc28d Mon Sep 17 00:00:00 2001 From: Yingxin Cheng Date: Fri, 29 Jul 2022 14:06:47 +0800 Subject: [PATCH] crimson/os/seastore: collect stats during replay Signed-off-by: Yingxin Cheng --- src/crimson/os/seastore/cache.cc | 15 +++--- src/crimson/os/seastore/cache.h | 6 ++- src/crimson/os/seastore/journal.h | 11 ++-- .../journal/circular_bounded_journal.cc | 2 +- .../os/seastore/journal/segmented_journal.cc | 52 ++++++++++++++----- .../os/seastore/journal/segmented_journal.h | 10 +++- .../os/seastore/transaction_manager.cc | 2 +- src/test/crimson/seastore/test_cbjournal.cc | 5 +- .../crimson/seastore/test_seastore_journal.cc | 2 +- 9 files changed, 71 insertions(+), 34 deletions(-) diff --git a/src/crimson/os/seastore/cache.cc b/src/crimson/os/seastore/cache.cc index 4b5572d2ad8..95342940747 100644 --- a/src/crimson/os/seastore/cache.cc +++ b/src/crimson/os/seastore/cache.cc @@ -1633,7 +1633,7 @@ Cache::replay_delta( const delta_info_t &delta, const journal_seq_t &dirty_tail, const journal_seq_t &alloc_tail, - sea_time_point &modify_time) + sea_time_point modify_time) { LOG_PREFIX(Cache::replay_delta); assert(dirty_tail != JOURNAL_SEQ_NULL); @@ -1642,7 +1642,7 @@ Cache::replay_delta( if (delta.type == extent_types_t::JOURNAL_TAIL) { // this delta should have been dealt with during segment cleaner mounting - return replay_delta_ertr::now(); + return replay_delta_ertr::make_ready_future(false); } // replay alloc @@ -1650,7 +1650,7 @@ Cache::replay_delta( if (journal_seq < alloc_tail) { DEBUG("journal_seq {} < alloc_tail {}, don't replay {}", journal_seq, alloc_tail, delta); - return replay_delta_ertr::now(); + return replay_delta_ertr::make_ready_future(false); } alloc_delta_t alloc_delta; @@ -1674,14 +1674,14 @@ Cache::replay_delta( if (!backref_list.empty()) { backref_batch_update(std::move(backref_list), journal_seq); } - return replay_delta_ertr::now(); + return replay_delta_ertr::make_ready_future(true); } // replay dirty if (journal_seq < dirty_tail) { DEBUG("journal_seq {} < dirty_tail {}, don't replay {}", journal_seq, dirty_tail, delta); - return replay_delta_ertr::now(); + return replay_delta_ertr::make_ready_future(false); } if (delta.type == extent_types_t::ROOT) { @@ -1695,7 +1695,7 @@ Cache::replay_delta( journal_seq, record_base, delta, *root); root->set_modify_time(modify_time); add_extent(root); - return replay_delta_ertr::now(); + return replay_delta_ertr::make_ready_future(true); } else { auto _get_extent_if_cached = [this](paddr_t addr) -> get_extent_ertr::future { @@ -1735,7 +1735,7 @@ Cache::replay_delta( DEBUG("replay extent is not present, so delta is obsolete at {} {} -- {}", journal_seq, record_base, delta); assert(delta.pversion > 0); - return; + return replay_delta_ertr::make_ready_future(true); } DEBUG("replay extent delta at {} {} ... -- {}, prv_extent={}", @@ -1758,6 +1758,7 @@ Cache::replay_delta( journal_seq, record_base, delta, *extent); } mark_dirty(extent); + return replay_delta_ertr::make_ready_future(true); }); } } diff --git a/src/crimson/os/seastore/cache.h b/src/crimson/os/seastore/cache.h index 1ece53e9a75..d4e58346537 100644 --- a/src/crimson/os/seastore/cache.h +++ b/src/crimson/os/seastore/cache.h @@ -762,17 +762,19 @@ public: * Intended for use in Journal::delta. For each delta, should decode delta, * read relevant block from disk or cache (using correct type), and call * CachedExtent::apply_delta marking the extent dirty. + * + * Returns whether the delta is applied. */ using replay_delta_ertr = crimson::errorator< crimson::ct_error::input_output_error>; - using replay_delta_ret = replay_delta_ertr::future<>; + using replay_delta_ret = replay_delta_ertr::future; replay_delta_ret replay_delta( journal_seq_t seq, paddr_t record_block_base, const delta_info_t &delta, const journal_seq_t &dirty_tail, const journal_seq_t &alloc_tail, - sea_time_point &modify_time); + sea_time_point modify_time); /** * init_cached_extents diff --git a/src/crimson/os/seastore/journal.h b/src/crimson/os/seastore/journal.h index 34f407d3929..c2e537008f2 100644 --- a/src/crimson/os/seastore/journal.h +++ b/src/crimson/os/seastore/journal.h @@ -91,11 +91,12 @@ public: crimson::ct_error::erange>; using replay_ret = replay_ertr::future<>; using delta_handler_t = std::function< - replay_ret(const record_locator_t&, - const delta_info_t&, - const journal_seq_t&, // dirty_tail - const journal_seq_t&, // alloc_tail - sea_time_point modify_time)>; + replay_ertr::future( + const record_locator_t&, + const delta_info_t&, + const journal_seq_t&, // dirty_tail + const journal_seq_t&, // alloc_tail + sea_time_point modify_time)>; virtual replay_ret replay( delta_handler_t &&delta_handler) = 0; diff --git a/src/crimson/os/seastore/journal/circular_bounded_journal.cc b/src/crimson/os/seastore/journal/circular_bounded_journal.cc index 6e4b3aee269..d7ff795f007 100644 --- a/src/crimson/os/seastore/journal/circular_bounded_journal.cc +++ b/src/crimson/os/seastore/journal/circular_bounded_journal.cc @@ -397,7 +397,7 @@ Journal::replay_ret CircularBoundedJournal::replay( delta, locator.write_result.start_seq, locator.write_result.start_seq, - modify_time); + modify_time).discard_result(); }); }).safe_then([]() { return replay_ertr::make_ready_future< diff --git a/src/crimson/os/seastore/journal/segmented_journal.cc b/src/crimson/os/seastore/journal/segmented_journal.cc index e7d0559648d..1465479d547 100644 --- a/src/crimson/os/seastore/journal/segmented_journal.cc +++ b/src/crimson/os/seastore/journal/segmented_journal.cc @@ -224,20 +224,22 @@ SegmentedJournal::replay_ertr::future<> SegmentedJournal::replay_segment( journal_seq_t seq, segment_header_t header, - delta_handler_t &handler) + delta_handler_t &handler, + replay_stats_t &stats) { LOG_PREFIX(Journal::replay_segment); INFO("starting at {} -- {}", seq, header); return seastar::do_with( scan_valid_records_cursor(seq), SegmentManagerGroup::found_record_handler_t( - [s_type=header.type, &handler, this]( + [s_type=header.type, &handler, this, &stats]( record_locator_t locator, const record_group_header_t& header, const bufferlist& mdbuf) -> SegmentManagerGroup::scan_valid_records_ertr::future<> { LOG_PREFIX(Journal::replay_segment); + ++stats.num_record_groups; auto maybe_record_deltas_list = try_decode_deltas( header, mdbuf, locator.record_block_base); if (!maybe_record_deltas_list) { @@ -253,7 +255,8 @@ SegmentedJournal::replay_segment( s_type, this, FNAME, - &handler](auto& record_deltas_list) + &handler, + &stats](auto& record_deltas_list) { return crimson::do_for_each( record_deltas_list, @@ -261,8 +264,10 @@ SegmentedJournal::replay_segment( s_type, this, FNAME, - &handler](record_deltas_t& record_deltas) + &handler, + &stats](record_deltas_t& record_deltas) { + ++stats.num_records; auto locator = record_locator_t{ record_deltas.record_block_base, write_result @@ -276,7 +281,8 @@ SegmentedJournal::replay_segment( s_type, this, FNAME, - &handler](auto &p) + &handler, + &stats](auto &p) { auto& modify_time = p.first; auto& delta = p.second; @@ -309,7 +315,18 @@ SegmentedJournal::replay_segment( delta, segment_provider.get_dirty_tail(), segment_provider.get_alloc_tail(), - modify_time); + modify_time + ).safe_then([&stats, delta_type=delta.type](bool is_applied) { + if (is_applied) { + // see Cache::replay_delta() + assert(delta_type != extent_types_t::JOURNAL_TAIL); + if (delta_type == extent_types_t::ALLOC_INFO) { + ++stats.num_alloc_deltas; + } else { + ++stats.num_dirty_deltas; + } + } + }); }); }); }); @@ -339,16 +356,25 @@ SegmentedJournal::replay_ret SegmentedJournal::replay( (auto &&segment_headers) mutable -> replay_ret { INFO("got {} segments", segment_headers.size()); return seastar::do_with( - std::move(delta_handler), replay_segments_t(), - [this, segment_headers=std::move(segment_headers)] - (auto &handler, auto &segments) mutable -> replay_ret { + std::move(delta_handler), + replay_segments_t(), + replay_stats_t(), + [this, segment_headers=std::move(segment_headers), FNAME] + (auto &handler, auto &segments, auto &stats) mutable -> replay_ret { return prep_replay_segments(std::move(segment_headers) - ).safe_then([this, &handler, &segments](auto replay_segs) mutable { + ).safe_then([this, &handler, &segments, &stats](auto replay_segs) mutable { segments = std::move(replay_segs); - return crimson::do_for_each(segments, [this, &handler](auto i) mutable { - return replay_segment(i.first, i.second, handler); + return crimson::do_for_each(segments,[this, &handler, &stats](auto i) mutable { + return replay_segment(i.first, i.second, handler, stats); }); - }); + }).safe_then([&stats, FNAME] { + INFO("replay done, record_groups={}, records={}, " + "alloc_deltas={}, dirty_deltas={}", + stats.num_record_groups, + stats.num_records, + stats.num_alloc_deltas, + stats.num_dirty_deltas); + }); }); }); } diff --git a/src/crimson/os/seastore/journal/segmented_journal.h b/src/crimson/os/seastore/journal/segmented_journal.h index 3cf935382b6..cc5e489393d 100644 --- a/src/crimson/os/seastore/journal/segmented_journal.h +++ b/src/crimson/os/seastore/journal/segmented_journal.h @@ -75,12 +75,20 @@ private: scan_last_segment_ertr::future<> scan_last_segment( const segment_id_t&, const segment_header_t&); + struct replay_stats_t { + std::size_t num_record_groups = 0; + std::size_t num_records = 0; + std::size_t num_alloc_deltas = 0; + std::size_t num_dirty_deltas = 0; + }; + /// replays records starting at start through end of segment replay_ertr::future<> replay_segment( journal_seq_t start, ///< [in] starting addr, seq segment_header_t header, ///< [in] segment header - delta_handler_t &delta_handler ///< [in] processes deltas in order + delta_handler_t &delta_handler, ///< [in] processes deltas in order + replay_stats_t &stats ///< [out] replay stats ); }; diff --git a/src/crimson/os/seastore/transaction_manager.cc b/src/crimson/os/seastore/transaction_manager.cc index 2f62431ddaa..91cd17d0e62 100644 --- a/src/crimson/os/seastore/transaction_manager.cc +++ b/src/crimson/os/seastore/transaction_manager.cc @@ -95,7 +95,7 @@ TransactionManager::mount_ertr::future<> TransactionManager::mount() const auto &e, const journal_seq_t &dirty_tail, const journal_seq_t &alloc_tail, - auto modify_time) + sea_time_point modify_time) { auto start_seq = offsets.write_result.start_seq; return cache->replay_delta( diff --git a/src/test/crimson/seastore/test_cbjournal.cc b/src/test/crimson/seastore/test_cbjournal.cc index 49e121e693b..beba8dd0ef1 100644 --- a/src/test/crimson/seastore/test_cbjournal.cc +++ b/src/test/crimson/seastore/test_cbjournal.cc @@ -216,8 +216,7 @@ struct cbjournal_test_t : public seastar_test_suite_t const auto &e, auto &dirty_seq, auto &alloc_seq, - auto last_modified) - -> Journal::replay_ret { + auto last_modified) { bool found = false; for (auto &i : entries) { paddr_t base = offsets.write_result.start_seq.offset; @@ -229,7 +228,7 @@ struct cbjournal_test_t : public seastar_test_suite_t } } assert(found == true); - return Journal::replay_ertr::now(); + return Journal::replay_ertr::make_ready_future(true); }).unsafe_get0(); } diff --git a/src/test/crimson/seastore/test_seastore_journal.cc b/src/test/crimson/seastore/test_seastore_journal.cc index 6df8e08337b..28af6a4506f 100644 --- a/src/test/crimson/seastore/test_seastore_journal.cc +++ b/src/test/crimson/seastore/test_seastore_journal.cc @@ -209,7 +209,7 @@ struct journal_test_t : seastar_test_suite_t, SegmentProvider { delta_checker = std::nullopt; advance(); } - return Journal::replay_ertr::now(); + return Journal::replay_ertr::make_ready_future(true); }).unsafe_get0(); ASSERT_EQ(record_iter, records.end()); for (auto &i : records) { -- 2.39.5