up集合中的成员。所有的成员都是加入到acting_backfilling中,如果是incomplete状态的成员或者 日志衔接不上的成员(cur.last_update<auth.log_tail)则添加到backfill中,否则添加到want成员中。
acting集合中的成员,该组内的成员不会添加到backfill中,所以只需要判断 如果状态是complete并且 日志能够衔接的上,则添加到want和acting_backfilling中。
其他prior中的osd成员 处理同acting一致。
经过这一步可知,acting_backfilling的成员(可用日志恢复数据,或者帮助恢复数据的成员),backfill的成员(只能通过其他的osd上pg的数据进行全量拷贝恢复),want的成员(同样在acting_backfill中,但是不同于backfill的成员)。
calc_ec_acting。ceph有两种pool,一种是副本类型pool,一种是纠删码类型pool(类似RAID)。具体实现后续补充,今天太晚了,有空看代码补补。
2.2、如果计算出的authoritative log对应的pg是自身,直接post event到GotLog;否则,向其所在的osd发送Query Log请求;
context<RecoveryMachine>().send_query(
auth_log_shard,
pg_query_t(
pg_query_t::LOG,
auth_log_shard.shard, pg->pg_whoami.shard,
request_log_from, pg->info.history,
pg->get_osdmap()->get_epoch()));
2.3、接收请求的osd应答,并将获取的log merge到本地,状态机post event到GetMissing;如果收不到应答,状态将持续等待;
boost::statechart::result PG::RecoveryState::GetLog::react(const GotLog &)
{
dout(10) << "leaving GetLog" << dendl;
PG *pg = context< RecoveryMachine >().pg;
if (msg)
{
dout(10) << "processing master log" << dendl;
pg->proc_master_log(*context<RecoveryMachine>().get_cur_transaction(),
msg->info, msg->log, msg->missing,
auth_log_shard);//log处理函数
}
pg->start_flush(
context< RecoveryMachine >().get_cur_transaction(),
context< RecoveryMachine >().get_on_applied_context_list(),
context< RecoveryMachine >().get_on_safe_context_list());
return transit< GetMissing >();//跳转到GetMissing
}
void PG::proc_master_log(
ObjectStore::Transaction &t, pg_info_t &oinfo,
pg_log_t &olog, pg_missing_t &omissing, pg_shard_t from)
{
dout(10) << "proc_master_log for osd." << from << ": "
<< olog << " " << omissing << dendl;
assert(!is_peered() && is_primary());
// merge log into our own log to build master log. no need to
// make any adjustments to their missing map; we are taking their
// log to be authoritative (i.e., their entries are by definitely
// non-divergent).
merge_log(t, oinfo, olog, from);//该函数对log进行合并,形成一个权威顺序完整的一个log。包括日志前后的修补,而且最重要的是修补的过程中,统计了本地副本中需要恢复object的情况missing.add_next_event(ne)。这里已经开始统计missing结构了。
peer_info[from] = oinfo;//保存来自best_log的oinfo到本地的peer-info数组中。
dout(10) << " peer osd." << from << " now " << oinfo << " " << omissing << dendl;
might_have_unfound.insert(from);