PGLog写流程梳理

文章目录

      • PG_log 简介
        • log内容
        • 存储结构分析
        • 查看方法
        • 追踪单个op的pglog
        • 相关数据结构
          • pg_log_t
          • pg_log_info
          • pg_history_t
          • pg_log_entry_t
      • PG状态机
        • PGlog参与数据恢复过程
          • 对于故障OSD所拥有的Primary PG
          • 对于故障OSD所拥有的Replicate PG

参考文档:
https://blog.csdn.net/changtao381/article/details/49125817

https://blog.csdn.net/skdkjzz/article/details/51579432

https://blog.csdn.net/skdkjzz/article/details/52852076

https://blog.csdn.net/liu3612162/article/details/79389088

PG_log 简介

相关配置说明:

osd_min_pg_log_entries 正常情况下PGLog的记录的条数,

osd_max_pg_log_entries 异常情况下pglog记录的条数,达到该限制会进行trim操作

log内容

主要存储内容为pg_log_entry_t,主要包括如下内容

  • op:对象操作 (modify,delete,clone,promote,clean,error…)

  • object:对象名称

  • eversion:当前操作的pg epoch以及对应的版本

PGLog写流程梳理_第1张图片

简单介绍两个概念:

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

    如下图:

    [外链图片转存失败(img-O1W2XRrL-1566639053871)(C:\Users\zhanghuigui\AppData\Roaming\Typora\typora-user-images\1566626293968.png)]

    PGLog写流程梳理_第2张图片

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

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

存储结构分析

pglog相关的主要数据结构如上:pg_info_t ,pg_log_t,pg_log_entry_t,存储在rocksdb中

如上图中关于pglog中的各个参数含义如下:

  • 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内容可以使用如下工具查看:

  • 停掉运行中的osd,获取改osd的挂载路径,使用如下命令获取pg列表

    ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-9/ --type bluestore --op list-pgs

  • 获取具体的pg_log_t信息

    ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-9/ --type bluestore --pgid 19.39s2 --op log

    PGLog写流程梳理_第3张图片

  • 获取具体的pg_info_t信息

    ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-9/ --type bluestore --pgid 19.39s2 --op info

    PGLog写流程梳理_第4张图片

追踪单个op的pglog

  • ceph osd map pool_name obj_name_id

    输出如下:

    osdmap e2074 pool ‘tc_malloc_p1’ (19) object ‘obj1’ -> pg 19.6cf8deff (19.3f) -> up ([7,NONE,8], p7) acting ([7,NONE,8], p7)

    其中可以看到obj1映射到了19.3f的pg上,能够看到改pg的up set和actiong set

  • 确认pg所在osd

    ceph pg dump pgs_brief |grep ^19|grep 19.3f

    [外链图片转存失败(img-iCHoXGjS-1566639053873)(C:\Users\zhanghuigui\AppData\Roaming\Typora\typora-user-images\1566627769824.png)]

    可以看到改pg的承载osd,再确认该osd所在的资源池

  • 通过以上两步找到会落入到指定pg的对象,以该对象为名将指定文件put到资源池中

    rados -p tc_malloc_p1 put obj1 test.file

  • 从该pg所在的osd集合中任意选择一个down掉,查看写入的关于obj1的log信息

    ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-9/ --type bluestore --pgid 19.3fs1 --op log|less

    PGLog写流程梳理_第5张图片

相关数据结构

pg_log_t
struct pg_log_t {
  /*
   *   head - newest entry (update|delete)
   *   tail - entry previous to oldest (update|delete) for which we have
   *          complete negative information.  
   * i.e. we can infer pg contents for any store whose last_update >= tail.
   */
  eversion_t head;    // newest entry 同样通过我们以上使用工具追踪单个的pglog方式看到head指向最新的一条信息
  eversion_t tail;    // version prior to oldest 指向最老的pglog

protected:
  // We can rollback rollback-able entries > can_rollback_to
  eversion_t can_rollback_to;

  // always <= can_rollback_to, indicates how far stashed rollback
  // data can be found
  eversion_t rollback_info_trimmed_to;
  public:
  // the actual log,实际的pglog entry,用链表形式进行存储
  mempool::osd_pglog::list<pg_log_entry_t> log; 
  ...
pg_log_info
struct pg_info_t {
  spg_t pgid;
  eversion_t last_update;      ///< last object version applied to store.
  eversion_t last_complete;    ///< last version pg was complete through.
  epoch_t last_epoch_started;  ///< last epoch at which this pg started on this osd
  epoch_t last_interval_started; ///< first epoch of last_epoch_started interval
  
  version_t last_user_version; ///< last user object version applied to store

  eversion_t log_tail;         ///< oldest log entry.

  hobject_t last_backfill;     ///指出需要进行backfill的位置 < objects >= this and < last_complete may be missing
  bool last_backfill_bitwise;  //一种对象间比对的方法,采用bitwise方式还是nibblewise方式进行比对 < true if last_backfill reflects a bitwise (vs nibblewise) sort

  interval_set<snapid_t> purged_snaps;

  pg_stat_t stats;//pg 状态信息

  pg_history_t history;//集群状态历史
  pg_hit_set_history_t hit_set;
pg_history_t
//当前数据结构主要存储pg在进行peering/mapping过程的历史信息,包括一些状态机事件的时间点

struct pg_history_t {

  epoch_t epoch_created;    //pg被创建的时间点

   epoch_t last_epoch_started;   //集群最后一次进入start的时间,不一定和本地相等。

 

 

  epoch_t last_epoch_clean;  //集群中最后一次进入clean状态的时间

  epoch_t last_epoch_split; // 集群中最后一次分裂的时间

  epoch_t last_epoch_marked_full;  // 标记为满,暂未分析
     /**
   * In the event of a map discontinuity, same_*_since may reflect the first
   * map the osd has seen in the new map sequence rather than the actual start
   * of the interval.  This is ok since a discontinuity at epoch e means there
   * must have been a clean interval between e and now and that we cannot be
   * in the active set during the interval containing e.
   */
  epoch_t same_up_since;       // same acting set since 用来标识PG最近一个interval的起点
  epoch_t same_interval_since;   // same acting AND up set since 标识自该epoch开始,pg当前的up没有发生变化
  epoch_t same_primary_since;  // same primary at least back through this epoch.标识自该epoch开始,PG当前的primary没有发生过变化
pg_log_entry_t
//描述单个pglog 条目/事件的内容  
struct pg_log_entry_t {
  // describes state for a locally-rollbackable entry
  ObjectModDesc mod_desc; //pglog当前条目的操作描述(mod、delete、)
  bufferlist snaps;   // only for clone entries 当快照克隆时使用
  hobject_t  soid; //标记一个对象
  osd_reqid_t reqid;  // caller+tid to uniquely identify request 标记一个唯一的请求
  mempool::osd_pglog::vector<pair<osd_reqid_t, version_t> > extra_reqids;
  eversion_t version, prior_version, reverting_to; //本操作版本,本操作的前一版本,回退版本
  version_t user_version; // the user version for this entry 用户为此对象安排的版本
  utime_t     mtime;  // this is the _user_ mtime, mind you 用户定义的时间
  int32_t return_code; // only stored for ERRORs for dup detection针用于失败时的返回值,此值用于重复请求检测

  __s32      op; //操作类型(见类枚举) modify,promote,clone,delete
  bool invalid_hash; // only when decoding sobject_t based entries
  bool invalid_pool; // only when decoding pool-less hobject based entries

PG状态机

主要是pg 从reset -> activte过程中的状态转换,其中包括pg从peering到activate 以及epoch变化时pg 状态恢复的处理流程

PGLog写流程梳理_第6张图片

PGlog参与数据恢复过程

根据pg状态机我们可以看到pg状态恢复为active的过程需要区分PrimaryReplicated两种,因为不论是pg还是osd的消息处理都是由primary主导,再分发给从组件。

同时PGLog参与恢复主要体现在ceph进行peering的时候建立missing列表来标记过时数据,以便于进行对这些数据进行修复。故障的OSD重新上线后,PG就会标记为peering状态并暂停处理请求

对于故障OSD所拥有的Primary PG
  • 它作为这部分数据”权责”主体,需要发送查询PG元数据请求给所有属于该PG的Replicate角色节点;
  • 该 PG 的 Replicate角色节点实际上在故障OSD下线时期间成为了Primary角色并维护了“权威”的PGLog,该PG在得到故障OSD的Primary PG的查询请求后会发送回应;
  • Primary PG 通过对比 Replicate PG 发送的元数据和PG版本信息后发现处于落后状态,因此它会合并得到的PGLog并建立“权威” PGLog,同时会建立missing列表来标记过时数据;
  • Primary PG 在完成“权威” PGLog的建立后就可以标志自己处于Active状态;
对于故障OSD所拥有的Replicate PG
  • 这时上线后故障 OSD 的 Replicate PG会得到Primary PG的查询请求,发送自己这份“过时”的元数据和PGLog;
  • Primary PG 对比数据后发现该 PG 落后并且过时,比通过PGLog建立了missing列表;
  • Primary PG 标记自己处于 Active 状态;

你可能感兴趣的:(ceph技能树,ceph源码分析)