: public MessageInstance<MOSDPGReadyToMerge, PaxosServiceMessage> {
public:
pg_t pgid;
+ epoch_t last_epoch_started = 0;
epoch_t last_epoch_clean = 0;
bool ready = true;
MOSDPGReadyToMerge()
: MessageInstance(MSG_OSD_PG_READY_TO_MERGE, 0)
{}
- MOSDPGReadyToMerge(pg_t p, epoch_t lec, bool r, epoch_t v)
+ MOSDPGReadyToMerge(pg_t p, epoch_t les, epoch_t lec, bool r, epoch_t v)
: MessageInstance(MSG_OSD_PG_READY_TO_MERGE, v),
pgid(p),
+ last_epoch_started(les),
last_epoch_clean(lec),
ready(r)
{}
using ceph::encode;
paxos_encode();
encode(pgid, payload);
+ encode(last_epoch_started, payload);
encode(last_epoch_clean, payload);
encode(ready, payload);
}
bufferlist::const_iterator p = payload.begin();
paxos_decode(p);
decode(pgid, p);
+ decode(last_epoch_started, p);
decode(last_epoch_clean, p);
decode(ready, p);
}
const char *get_type_name() const override { return "osd_pg_ready_to_merge"; }
void print(ostream &out) const {
out << get_type_name()
- << "(" << pgid << " lec " << last_epoch_clean
+ << "(" << pgid
+ << " les/c " << last_epoch_started << "/" << last_epoch_clean
<< (ready ? " ready" : " NOT READY")
<< " v" << version << ")";
}
}
if (m->ready) {
- p.dec_pg_num(m->last_epoch_clean);
+ p.dec_pg_num(m->last_epoch_started, m->last_epoch_clean);
p.last_change = pending_inc.epoch;
} else {
// back off the merge attempt!
_send_ready_to_merge();
}
-void OSDService::set_ready_to_merge_target(PG *pg, epoch_t last_epoch_clean)
+void OSDService::set_ready_to_merge_target(PG *pg,
+ epoch_t last_epoch_started,
+ epoch_t last_epoch_clean)
{
Mutex::Locker l(merge_lock);
dout(10) << __func__ << " " << pg->pg_id << dendl;
- ready_to_merge_target.insert(make_pair(pg->pg_id.pgid, last_epoch_clean));
+ ready_to_merge_target.insert(make_pair(pg->pg_id.pgid,
+ make_pair(last_epoch_started,
+ last_epoch_clean)));
assert(not_ready_to_merge_target.count(pg->pg_id.pgid) == 0);
_send_ready_to_merge();
}
monc->send_mon_message(new MOSDPGReadyToMerge(
src,
0,
+ 0,
false,
osdmap->get_epoch()));
sent_ready_to_merge_source.insert(src);
monc->send_mon_message(new MOSDPGReadyToMerge(
p.second,
0,
+ 0,
false,
osdmap->get_epoch()));
sent_ready_to_merge_source.insert(p.second);
sent_ready_to_merge_source.count(src) == 0) {
monc->send_mon_message(new MOSDPGReadyToMerge(
src,
- p->second, // PG's last_epoch_clean
+ p->second.first, // PG's last_epoch_started
+ p->second.second, // PG's last_epoch_clean
true,
osdmap->get_epoch()));
sent_ready_to_merge_source.insert(src);
dout(1) << __func__ << " merging " << pg->pg_id << dendl;
pg->merge_from(
sources, rctx, split_bits,
+ nextmap->get_pg_pool(
+ pg->pg_id.pool())->get_pg_num_dec_last_epoch_started(),
nextmap->get_pg_pool(
pg->pg_id.pool())->get_pg_num_dec_last_epoch_clean());
pg->pg_slot->waiting_for_merge_epoch = 0;
// -- pg merge --
Mutex merge_lock = {"OSD::merge_lock"};
set<pg_t> ready_to_merge_source;
- map<pg_t,epoch_t> ready_to_merge_target; // pg -> last_epoch_clean
+ map<pg_t,pair<epoch_t,epoch_t>> ready_to_merge_target; // pg -> (les,lec)
set<pg_t> not_ready_to_merge_source;
map<pg_t,pg_t> not_ready_to_merge_target;
set<pg_t> sent_ready_to_merge_source;
void set_ready_to_merge_source(PG *pg);
- void set_ready_to_merge_target(PG *pg, epoch_t last_epoch_clean);
+ void set_ready_to_merge_target(PG *pg,
+ epoch_t last_epoch_started,
+ epoch_t last_epoch_clean);
void set_not_ready_to_merge_source(pg_t source);
void set_not_ready_to_merge_target(pg_t target, pg_t source);
void clear_ready_to_merge(PG *pg);
if (pool.info.is_pending_merge(info.pgid.pgid, &target)) {
if (target) {
ldout(cct, 10) << "ready to merge (target)" << dendl;
- osd->set_ready_to_merge_target(this, info.history.last_epoch_clean);
+ osd->set_ready_to_merge_target(this,
+ info.history.last_epoch_started,
+ info.history.last_epoch_clean);
} else {
ldout(cct, 10) << "ready to merge (source)" << dendl;
osd->set_ready_to_merge_source(this);
void PG::merge_from(map<spg_t,PGRef>& sources, RecoveryCtx *rctx,
unsigned split_bits,
+ epoch_t dec_last_epoch_started,
epoch_t dec_last_epoch_clean)
{
dout(10) << __func__ << " from " << sources << " split_bits " << split_bits
// use last_epoch_clean value for last_epoch_started, though--we must be
// conservative here to avoid breaking peering, calc_acting, etc.
- info.history.last_epoch_started = dec_last_epoch_clean;
- info.last_epoch_started = dec_last_epoch_clean;
+ info.history.last_epoch_started = dec_last_epoch_started;
+ info.last_epoch_started = dec_last_epoch_started;
dout(10) << __func__
- << " set last_epoch_{started,clean} to " << dec_last_epoch_clean
- << " from pg_num_dec_last_epoch_clean, source pg history was "
+ << " set les/c to " << dec_last_epoch_started << "/"
+ << dec_last_epoch_clean
+ << " from pool last_dec_*, source pg history was "
<< sources.begin()->second->info.history
<< dendl;
}
void split_into(pg_t child_pgid, PG *child, unsigned split_bits);
void merge_from(map<spg_t,PGRef>& sources, RecoveryCtx *rctx,
unsigned split_bits,
+ epoch_t dec_last_epoch_started,
epoch_t dec_last_epoch_clean);
void finish_split_stats(const object_stat_sum_t& stats, ObjectStore::Transaction *t);
f->dump_unsigned("pg_placement_num_target", get_pgp_num_target());
f->dump_unsigned("pg_num_target", get_pg_num_target());
f->dump_unsigned("pg_num_pending", get_pg_num_pending());
+ f->dump_unsigned("pg_num_dec_last_epoch_started",
+ get_pg_num_dec_last_epoch_started());
f->dump_unsigned("pg_num_dec_last_epoch_clean",
get_pg_num_dec_last_epoch_clean());
f->dump_stream("last_change") << get_last_change();
encode(pg_num_target, bl);
encode(pgp_num_target, bl);
encode(pg_num_pending, bl);
+ encode(pg_num_dec_last_epoch_started, bl);
encode(pg_num_dec_last_epoch_clean, bl);
encode(last_force_op_resend, bl);
}
decode(pg_num_target, bl);
decode(pgp_num_target, bl);
decode(pg_num_pending, bl);
+ decode(pg_num_dec_last_epoch_started, bl);
decode(pg_num_dec_last_epoch_clean, bl);
decode(last_force_op_resend, bl);
} else {
a.pgp_num_target = 4;
a.pg_num_target = 5;
a.pg_num_pending = 5;
- a.pg_num_dec_last_epoch_clean = 2;
+ a.pg_num_dec_last_epoch_started = 2;
+ a.pg_num_dec_last_epoch_clean = 3;
a.last_change = 9;
a.last_force_op_resend = 123823;
a.last_force_op_resend_preluminous = 123824;
}
if (p.get_pg_num_pending() != p.get_pg_num()) {
out << " pg_num_pending " << p.get_pg_num_pending();
- if (p.get_pg_num_dec_last_epoch_clean())
- out << " dlec " << p.get_pg_num_dec_last_epoch_clean();
+ if (p.get_pg_num_dec_last_epoch_started() ||
+ p.get_pg_num_dec_last_epoch_clean())
+ out << " dles/c " << p.get_pg_num_dec_last_epoch_started()
+ << "/" << p.get_pg_num_dec_last_epoch_clean();
}
out << " last_change " << p.get_last_change();
if (p.get_last_force_op_resend() ||
/// last epoch that forced clients to resend (pre-luminous clients only)
epoch_t last_force_op_resend_preluminous = 0;
+ ///< last_epoch_started preceding pg_num decrement request
+ epoch_t pg_num_dec_last_epoch_started = 0;
///< last_epoch_clean preceding pg_num decrement request
epoch_t pg_num_dec_last_epoch_clean = 0;
snapid_t snap_seq; ///< seq for per-pool snapshot
// pool size that it represents.
unsigned get_pg_num_divisor(pg_t pgid) const;
+ epoch_t get_pg_num_dec_last_epoch_started() const {
+ return pg_num_dec_last_epoch_started;
+ }
epoch_t get_pg_num_dec_last_epoch_clean() const {
return pg_num_dec_last_epoch_clean;
}
void set_pgp_num_target(int p) {
pgp_num_target = p;
}
- void dec_pg_num(epoch_t last_epoch_clean) {
+ void dec_pg_num(epoch_t last_epoch_started,
+ epoch_t last_epoch_clean) {
--pg_num;
+ pg_num_dec_last_epoch_started = last_epoch_started;
pg_num_dec_last_epoch_clean = last_epoch_clean;
calc_pg_masks();
}