• 【osd】ceph中PGLog处理流程


    struct pg_log_entry_t {
        ObjectModDesc mod_desc;                 //用于保存本地回滚的一些信息,用于EC模式下的回滚操作
    
        bufferlist snaps;                       //克隆操作,用于记录当前对象的snap列表
        hobject_t  soid;                        //操作的对象
        osd_reqid_t reqid;                      //请求唯一标识(caller + tid)
    
    
        vector<pair<osd_reqid_t, version_t> > extra_reqids;
    
    
        eversion_t version;                     //本次操作的版本
        eversion_t prior_version;                //前一个操作的版本
        eversion_t reverting_to;                 //本次操作回退的版本(仅用于回滚操作)
    
        version_t user_version;                 //用户的版本号
        utime_t     mtime;                      //用户的本地时间
        
        __s32      op;                          //操作的类型
        bool invalid_hash;                      // only when decoding sobject_t based entries
        bool invalid_pool;                      // only when decoding pool-less hobject based entries
    
        ...
    };
    /**
     * pg_info_t - summary of PG statistics.
     *
     * some notes: 
     *  - last_complete implies we have all objects that existed as of that
     *    stamp, OR a newer object, OR have already applied a later delete.
     *  - if last_complete >= log.bottom, then we know pg contents thru log.head.
     *    otherwise, we have no idea what the pg is supposed to contain.
     */
    struct pg_info_t {
        spg_t pgid;                    //对应的PG ID
    
        //PG内最近一次更新的对象的版本,还没有在所有OSD上完成更新。在last_update和last_complete之间的操作表示
        //该操作已在部分OSD上完成,但是还没有全部完成。
        eversion_t last_update;        
        eversion_t last_complete;      //该指针之前的版本都已经在所有的OSD上完成更新(只表示内存更新完成)
    
        epoch_t last_epoch_started;    //本PG在启动时候的epoch值
        
        version_t last_user_version;   //最后更新的user object的版本号
        
        eversion_t log_tail;           //用于记录日志的尾部版本
        
        //上一次backfill操作的对象指针。如果该OSD的Backfill操作没有完成,那么[last_bakfill, last_complete)之间的对象可能
        //处于missing状态
        hobject_t last_backfill;      
    
    
        bool last_backfill_bitwise;            //true if last_backfill reflects a bitwise (vs nibblewise) sort
        
        interval_set<snapid_t> purged_snaps;   //PG要删除的snap集合
        
        pg_stat_t stats;                       //PG的统计信息
        
        pg_history_t history;                  //用于保存最近一次PG peering获取到的epoch等相关信息
        pg_hit_set_history_t hit_set;          //这是Cache Tier用的hit_set
    };

    下面简单画出三者之间的关系示意图:

    其中:

    • last_complete: 在该指针之前的版本都已经在所有的OSD上完成更新(只表示内存更新完成);

    • last_update: PG内最近一次更新的对象的版本,还没有在所有OSD上完成更新。在last_update与last_complete之间的操作表示该操作已在部分OSD上完成,但是还没有全部完成。

    • log_tail: 指向pg log最老的那条记录;

    • head: 最新的pg log记录

    • tail: 指向最老的pg log记录的前一个;

    • log: 存放实际的pglog记录的list

    从上面结构可以得知,PGLog里只有对象更新操作相关的内容,没有具体的数据以及偏移大小等,所以后续以PGLog来进行恢复时都是按照整个对象来进行恢复的(默认对象大小是4MB)。

    另外,这里再介绍两个概念:

    • epoch是一个单调递增序列,其序列由monitor负责维护,当集群中的配置及OSD状态(up、down、in、out)发生变更时,其数值加1。这一机制等同于时间轴,每次序列变化是时间轴上的点。这里说的epoch是针对OSD的,具体到PG时,即对于每个PG的版本eversion中的epoch的变化并不是跟随集群epoch变化的,而是当前PG所在OSD的状态变化,当前PG的epoch才会发生变化。

    如下图所示:

    ceph-chapter6-7

    • 根据epoch增长的概念,即引入第二个重要概念interval

    因为pg的epoch在其变化的时间轴上并非是完全连续的,所以在每两个变化的pg epoch所经历的时间段我们称之为intervals。

    3.1.3 Trim Log

    void PrimaryLogPG::execute_ctx(OpContext *ctx)
    {
        ......
          // trim log?
      if (hard_limit_pglog())
        calc_trim_to_aggressive();
      else
        calc_trim_to();
        ......
    }

    前面说到PGLog的记录数是有限制的,正常情况下默认是3000条(由参数osd_min_pg_log_entries控制),PG降级情况下默认增加到10000条(由参数osd_max_pg_log_entries)。当达到限制时,就会trim log进行截断。

    在ReplicatedPG::execute_ctx()里调用ReplicatedPG::calc_trim_to()来进行计算。计算的时候从log的tail(tail指向最老的记录的前一个)开始,需要trim的条数为log.head - log.tail - max_entries。但是trim的时候需要考虑到min_last_complete_ondisk(这个表示各个副本上last_complete的最小版本,是主OSD在收到3个副本都完成时再进行计算的,也就是计算last_complete_ondisk和其他副本OSD上的last_complete_ondisk,即peer_last_complete_ondisk的最小值得到min_last_complete_ondisk),也就是说trim的时候不能超过min_last_complete_ondisk,因为超过了也trim掉的话就会导致没有更新到磁盘上的pg log丢失。所以说可能存在某个时刻,pglog的记录数超过max_entries。例如:

    参考资料

    1. ceph中PGLog处理流程

  • 相关阅读:
    *Reverse Linked List II
    *Insertion Sort List
    Convert Sorted List to Binary Search Tree
    Reverse Integer
    read cache return null
    纳秒和随机数
    libthread_db
    gdb
    tls session resumption
    http://www.linux-commands-examples.com/xmllint
  • 原文地址:https://www.cnblogs.com/sunbines/p/15629079.html
Copyright © 2020-2023  润新知