• 【osd】pg_info_t 字段解析


      last_epoch_started介绍

    Info中实际保存了两个last_epoch_started属 性,一个位于Info属性之下,另一个则位于Info的history属性之 下。

    1. info.last_epoch_started由每个副本收到Primary发送的Peering完成通知之后更新,并与Peering结果一并存盘。

    2. info.history.last_epoch_started则由Primary在收到所有副本 Peering完成通知应答之后更新和存盘。由于Primary更新完history 中的last_epoch_started属性之后会同步设置PG为Active状态(注意如果此时Acting中的副本数小于存储池最小副本数,PG将 进入Peered状态), 因此history中last_epoch_started也用于指示PG最近一次开始接受 客户端读写请求时的Epoch。

    last_epoch_started字段有两个地方出现,一个是pg_info_t结构里的last_epoch_started,代表最后一次Peering成功后的epoch值,是本地PG完成Peering后就设置的。另一个是pg_history_t结构体里的last_epoch_started,是PG里所有的OSD都完成Peering后设置的epoch值。如下图所示:

    info.last_epoch_started: 记录了PG在interval i完成Peering时的epoch值,在i(包括i)之前的interval提交的所有写操作均会反映到local info/log中,而对于i之后的interval所提交的写操作将不会在当前local info/log中得到体现。由于提交的写操作不可能出现分歧(注:peering已经完成),因此即使用一个更旧的info.last_epoch_started来获取权威log/info信息,也不可能会影响到当前的info.last_epoch_started。

    info.history.last_epoch_started: 记录了最近一个interval中,PG作为一个整体完成peering操作后设置的epoch值。由于提交的所有写操作都是由acting set中的OSD提交的,任何无歧义的write操作都会确保acting set中每一个OSD都记录了history.last_epoch_started。

    如下我们介绍一下last_epoch_started的更新操作:

    1) info.last_epoch_started: PG在本OSD上完成Peering操作,就会马上更新其对应的last_epoch_started的值。参看PG::activate()函数

    2) info.history.last_epoch_started: 对于本字段的更新操作,情况较为复杂。


     对于PG副本OSD上的info.history.last_epoch_started字段的更新会在Peering完成后马上进行,参看PG::activate();另外还会在Primary OSD向副本OSD发送pg_query_t::INFO时得到更新:

     1 boost::statechart::result PG::RecoveryState::Stray::react(const MQuery& query)
     2 {
     3   PG *pg = context<RecoveryMachine>().pg;
     4   pg->fulfill_query(query, context<RecoveryMachine>().get_recovery_ctx());
     5   return discard_event();
     6 }
     7 
     8 void PG::fulfill_query(const MQuery& query, RecoveryCtx *rctx)
     9 {
    10   if (query.query.type == pg_query_t::INFO) 
    11   {
    12     ...
    13     update_history(query.query.history);
    14     ...
    15   } 
    16 }
    17 
    18 void PG::update_history(const pg_history_t& new_history)
    19 {
    20   if (info.history.merge(new_history)) 
    21   {
    22       ...
    23   }
    24   on_info_history_change(); //scrub机制
    25 }
    26 
    27 bool merge(const pg_history_t &other) 
    28 {
    29     ...
    30     if (last_epoch_started < other.last_epoch_started) {
    31       last_epoch_started = other.last_epoch_started;
    32       modified = true;
    33     }
    34     ...
    35     return modified;
    36 }
     1 void PG::activate(ObjectStore::Transaction& t,
     2           epoch_t activation_epoch,
     3           list<Context*>& tfin,
     4           map<int, map<spg_t,pg_query_t> >& query_map,
     5           map<int,
     6               vector<
     7             pair<pg_notify_t,
     8                  pg_interval_map_t> > > *activator_map,
     9                   RecoveryCtx *ctx)
    10 {
    11     ...
    12 
    13     // find out when we commit
    14     t.register_on_complete(
    15         new C_PG_ActivateCommitted(
    16             this,
    17             get_osdmap()->get_epoch(),
    18             activation_epoch));
    19 
    20     ...
    21 }
    22 
    23 void PG::_activate_committed(epoch_t epoch, epoch_t activation_epoch)
    24 {
    25     if (pg_has_reset_since(epoch)) {
    26         ...
    27     } else if (is_primary()) {
    28         ...
    29         if (peer_activated.size() == actingbackfill.size())
    30             all_activated_and_committed();
    31     }
    32     ...
    33 }
    34 
    35 void PG::all_activated_and_committed()
    36 {
    37     ...
    38     queue_peering_event(
    39         CephPeeringEvtRef(
    40             std::make_shared<CephPeeringEvt>(
    41             get_osdmap()->get_epoch(),
    42             get_osdmap()->get_epoch(),
    43             AllReplicasActivated())));
    44 }
    45 
    46 boost::statechart::result PG::RecoveryState::Active::react(const AllReplicasActivated &evt){
    47     ...
    48 
    49     // info.last_epoch_started is set during activate()
    50     pg->info.history.last_epoch_started = pg->info.last_epoch_started;
    51 
    52     ...
    53 }
  • 相关阅读:
    开博客啦
    C语言 变长参数表的使用方法
    禅道程序员
    【转】函数式编程另类指南
    Servlet中JSP页面跳转的两种方法以及其区别
    《C程序设计语言》(学习笔记)——结构体
    C#保存wps和office表格.数据源为list<T>类型
    中国网建的短信接口实现
    C#保存wps和office表格.数据源为list<T>类型,
    MD5加密
  • 原文地址:https://www.cnblogs.com/sunbines/p/15724297.html
Copyright © 2020-2023  润新知