);
}).then([this](OSDSuperblock&& sb) {
superblock = std::move(sb);
+ if (!superblock.cluster_osdmap_trim_lower_bound) {
+ superblock.cluster_osdmap_trim_lower_bound = superblock.get_oldest_map();
+ }
pg_shard_manager.set_superblock(superblock);
return pg_shard_manager.get_local_map(superblock.current_epoch);
}).then([this](OSDMapService::local_cached_map_t&& map) {
logger().info("handle_osd_map epochs [{}..{}], i have {}, src has [{}..{}]",
first, last, superblock.get_newest_map(),
m->cluster_osdmap_trim_lower_bound, m->newest_map);
+
+ if (superblock.cluster_osdmap_trim_lower_bound <
+ m->cluster_osdmap_trim_lower_bound) {
+ superblock.cluster_osdmap_trim_lower_bound =
+ m->cluster_osdmap_trim_lower_bound;
+ logger().debug("{} superblock cluster_osdmap_trim_lower_bound new epoch is: {}",
+ __func__, superblock.cluster_osdmap_trim_lower_bound);
+ ceph_assert(
+ superblock.cluster_osdmap_trim_lower_bound >= superblock.get_oldest_map());
+ }
// make sure there is something new, here, before we bother flushing
// the queues and such
if (last <= superblock.get_newest_map()) {
monc->sub_got("osdmap", last);
if (!superblock.maps.empty()) {
- // TODO: support osdmap trimming
- // See: <tracker>
+ pg_shard_manager.trim_maps(t, superblock);
}
superblock.insert_osdmap_epochs(first, last);
});
}
+// Note: store/set_superblock is called in later OSD::handle_osd_map
+// so we use the OSD's superblock reference meanwhile.
+void OSDSingletonState::trim_maps(ceph::os::Transaction& t,
+ OSDSuperblock& superblock)
+{
+ epoch_t min =
+ std::min(superblock.cluster_osdmap_trim_lower_bound,
+ osdmaps.cached_key_lower_bound());
+
+ if (min <= superblock.get_oldest_map()) {
+ return;
+ }
+ logger().debug("{}: min={} oldest_map={}", __func__, min, superblock.get_oldest_map());
+
+ // Trim from the superblock's oldest_map up to `min`.
+ // Break if we have exceeded the txn target size.
+ while (superblock.get_oldest_map() < min &&
+ t.get_num_ops() < crimson::common::local_conf()->osd_target_transaction_size) {
+ logger().debug("{}: removing old osdmap epoch {}", __func__, superblock.get_oldest_map());
+ meta_coll->remove_map(t, superblock.get_oldest_map());
+ superblock.maps.erase(superblock.get_oldest_map());
+ }
+
+ // we should not trim past osdmaps.cached_key_lower_bound()
+ // as there may still be PGs with those map epochs recorded.
+ ceph_assert(min <= osdmaps.cached_key_lower_bound());
+}
+
seastar::future<Ref<PG>> ShardServices::make_pg(
OSDMapService::cached_map_t create_map,
spg_t pgid,
"superblock's oldest map: {}",
__func__, first, superblock.get_oldest_map());
if (first >= superblock.get_oldest_map()) {
+ if (first < superblock.cluster_osdmap_trim_lower_bound) {
+ logger().info("{}: cluster osdmap lower bound: {} "
+ " > first {}, starting with full map",
+ __func__, superblock.cluster_osdmap_trim_lower_bound, first);
+ // we don't have the next map the target wants,
+ // so start with a full map.
+ first = superblock.cluster_osdmap_trim_lower_bound;
+ }
return load_map_bls(
first, superblock.get_newest_map()
- ).then([this, &conn, first](auto&& bls) {
+ ).then([this, &conn](auto&& bls) {
auto m = crimson::make_message<MOSDMap>(
monc.get_fsid(),
osdmap->get_encoding_features());
- m->cluster_osdmap_trim_lower_bound = first;
+ m->cluster_osdmap_trim_lower_bound = superblock.cluster_osdmap_trim_lower_bound;
m->newest_map = superblock.get_newest_map();
m->maps = std::move(bls);
return conn.send(std::move(m));
});
} else {
+ // See OSDService::send_incremental_map
+ // just send latest full map
return load_map_bl(osdmap->get_epoch()
).then([this, &conn](auto&& bl) mutable {
auto m = crimson::make_message<MOSDMap>(
monc.get_fsid(),
osdmap->get_encoding_features());
- /* TODO: once we support the tracking of superblock's
- * cluster_osdmap_trim_lower_bound, the MOSDMap should
- * be populated with this value instead of the oldest_map.
- * See: OSD::handle_osd_map for how classic updates the
- * cluster's trim lower bound.
- */
- m->cluster_osdmap_trim_lower_bound = superblock.get_oldest_map();
+ m->cluster_osdmap_trim_lower_bound = superblock.cluster_osdmap_trim_lower_bound;
m->newest_map = superblock.get_newest_map();
m->maps.emplace(osdmap->get_epoch(), std::move(bl));
return conn.send(std::move(m));