]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/os/seastore: collect stats during replay
authorYingxin Cheng <yingxin.cheng@intel.com>
Fri, 29 Jul 2022 06:06:47 +0000 (14:06 +0800)
committerYingxin Cheng <yingxin.cheng@intel.com>
Fri, 29 Jul 2022 07:56:04 +0000 (15:56 +0800)
Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
src/crimson/os/seastore/cache.cc
src/crimson/os/seastore/cache.h
src/crimson/os/seastore/journal.h
src/crimson/os/seastore/journal/circular_bounded_journal.cc
src/crimson/os/seastore/journal/segmented_journal.cc
src/crimson/os/seastore/journal/segmented_journal.h
src/crimson/os/seastore/transaction_manager.cc
src/test/crimson/seastore/test_cbjournal.cc
src/test/crimson/seastore/test_seastore_journal.cc

index 4b5572d2ad89809dd96fd30ea1dee13198079804..953429407476b5e533b39c47208f0d92719c92c9 100644 (file)
@@ -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<bool>(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<bool>(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<bool>(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<bool>(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<bool>(true);
   } else {
     auto _get_extent_if_cached = [this](paddr_t addr)
       -> get_extent_ertr::future<CachedExtentRef> {
@@ -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<bool>(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<bool>(true);
     });
   }
 }
index 1ece53e9a754e41e7ccaab65f7dc82afb4d26e39..d4e583465376ee6327f37b3892fbc2879f2c88fa 100644 (file)
@@ -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<bool>;
   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
index 34f407d392937929dcc2b65c429f173d1198a98f..c2e537008f273475bdcd6fe0e44b5f11d2b7c143 100644 (file)
@@ -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<bool>(
+      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;
 
index 6e4b3aee2690d3ecebdc93d1d84d5cbfc019d931..d7ff795f0076ae8e0f57f4ea563214cf8274d15f 100644 (file)
@@ -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<
index e7d0559648d4c8d0ae3b565ff5f2484b202c6abd..1465479d547f3218a6e98fdd01e540b170327d50 100644 (file)
@@ -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);
+        });
       });
   });
 }
index 3cf935382b612387b64faf02d72493a897a09063..cc5e489393dfcedb0ac0d9fb506b2d5e98cb30d0 100644 (file)
@@ -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
   );
 };
 
index 2f62431ddaa9f66b7551719d01f2c236d8c2d205..91cd17d0e623142eccb3d6bc8dd1bee5be882f01 100644 (file)
@@ -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(
index 49e121e693bf9e18a7c76dbe775b48f21e3e6070..beba8dd0ef1326afded52ac841363a82257bad1c 100644 (file)
@@ -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<bool>(true);
     }).unsafe_get0();
   }
 
index 6df8e08337bfba782348c7bbaeb1e2e1041fb2a5..28af6a4506f60df3e3b229bc44537c7c783101c3 100644 (file)
@@ -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<bool>(true);
       }).unsafe_get0();
     ASSERT_EQ(record_iter, records.end());
     for (auto &i : records) {