From dc366fafec05064722bb475caa241571931c793b Mon Sep 17 00:00:00 2001 From: Xuehan Xu Date: Sun, 4 Aug 2024 18:59:05 +0800 Subject: [PATCH] crimson/osd: send empty transactions to backfill targets that haven't backfilled the objects yet Fixes: https://tracker.ceph.com/issues/67327 Signed-off-by: Xuehan Xu --- src/crimson/osd/pg.cc | 22 ++++++++++++++++++++++ src/crimson/osd/pg.h | 10 ++++++++++ src/crimson/osd/replicated_backend.cc | 9 ++++++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/crimson/osd/pg.cc b/src/crimson/osd/pg.cc index c195241cc5d8..a681705deee0 100644 --- a/src/crimson/osd/pg.cc +++ b/src/crimson/osd/pg.cc @@ -1698,6 +1698,28 @@ bool PG::is_degraded_or_backfilling_object(const hobject_t& soid) const { return false; } +bool PG::should_send_op( + pg_shard_t peer, + const hobject_t &hoid) const +{ + if (peer == get_primary()) + return true; + bool should_send = + (hoid.pool != (int64_t)get_info().pgid.pool() || + (has_backfill_state() && hoid <= get_last_backfill_started()) || + hoid <= peering_state.get_peer_info(peer).last_backfill); + if (!should_send) { + ceph_assert(is_backfill_target(peer)); + logger().debug("{} issue_repop shipping empty opt to osd." + "{}, object {} beyond std::max(last_backfill_started, " + "peer_info[peer].last_backfill {})", + peer, hoid, peering_state.get_peer_info(peer).last_backfill); + } + return should_send; + // TODO: should consider async recovery cases in the future which are not supported + // by crimson yet +} + PG::interruptible_future> PG::already_complete(const osd_reqid_t& reqid) { diff --git a/src/crimson/osd/pg.h b/src/crimson/osd/pg.h index 252709dea4dd..a9f45d329cb4 100644 --- a/src/crimson/osd/pg.h +++ b/src/crimson/osd/pg.h @@ -521,6 +521,7 @@ public: bool get_need_up_thru() const { return peering_state.get_need_up_thru(); } + bool should_send_op(pg_shard_t peer, const hobject_t &hoid) const; epoch_t get_same_interval_since() const { return get_info().history.same_interval_since; } @@ -740,6 +741,15 @@ public: PeeringState& get_peering_state() final { return peering_state; } + bool has_backfill_state() const { + return (bool)(recovery_handler->backfill_state); + } + const BackfillState& get_backfill_state() const { + return *recovery_handler->backfill_state; + } + hobject_t get_last_backfill_started() const { + return get_backfill_state().get_last_backfill_started(); + } bool has_reset_since(epoch_t epoch) const final { return peering_state.pg_has_reset_since(epoch); } diff --git a/src/crimson/osd/replicated_backend.cc b/src/crimson/osd/replicated_backend.cc index d01fd6468034..d227b9c89e97 100644 --- a/src/crimson/osd/replicated_backend.cc +++ b/src/crimson/osd/replicated_backend.cc @@ -65,7 +65,14 @@ ReplicatedBackend::_submit_transaction(std::set&& pg_shards, min_epoch, tid, osd_op_p.at_version); - m->set_data(encoded_txn); + if (pg.should_send_op(pg_shard, hoid)) { + m->set_data(encoded_txn); + } else { + ceph::os::Transaction t; + bufferlist bl; + encode(t, bl); + m->set_data(bl); + } pending_txn->second.acked_peers.push_back({pg_shard, eversion_t{}}); encode(log_entries, m->logbl); m->pg_trim_to = osd_op_p.pg_trim_to; -- 2.47.3