Scrub的过程大致如下:通过比较对象各个OSD上副本的元数据和数据,来完成源数据和数据的校验。

1.1.1  数据结构

Scrub操作相关的主要数据结构有两个,一个是Scrub控制结构——相当于一次Scrub曹组的上下文,控制一次PG的操作过程。另外是ScrubMap保存需要比较对象的各个副本的元数据和数据的摘要信息。

1.1.1.1     Scrubber

Scrubber结构体用于控制一个PG的Scrub过程

// -- scrub --

struct Scrubber {

// metadata

set<pg_shard_t>reserved_peers; // 资源预约的shard

bool reserved,reserve_failed; //是否预约资源,预约是否失败

epoch_tepoch_start;//开始Scrub操作的epoch

// commonto both scrubs

bool active;//Scrub是否开始

//当PG有snap_trim操作时,如果检查Scrubber处于active状态,说明正在进行Scrub操作,那么snap_trim操作暂停,设置queue_snap_trim的值为true。当PG完成Scrub任务后,如果queue_snap_trim的值为true,就把PG添加到相应的工作队列里,继续完成snap_trim操作

bool queue_snap_trim;

int waiting_on;//等待的副本计数

set<pg_shard_t>waiting_on_whom;//得带的副本

int shallow_errors;//轻度扫描的错误数

int deep_errors;//深度扫描的错误数

int fixed;//已经修复的对象数

ScrubMapprimary_scrubmap;//主副本的ScrubMap

map<pg_shard_t,ScrubMap> received_maps;//接收到的从副本的ScrubMap

OpRequestRefactive_rep_scrub;

utime_tscrub_reg_stamp;  // stamp we registered for

// thisflag indicates whether we would like to do auto-repair of the PG or not

bool auto_repair;//是否自动恢复

// Mapsfrom objects with errors to missing/inconsistent peers

map<hobject_t, set<pg_shard_t>>missing; //扫描出的缺失对象

map<hobject_t, set<pg_shard_t>>inconsistent;//扫描出的不一致对象

// Map fromobject with errors to good peers

//如果所有副本对象中有不一致的对象,记录正确对象所在的osd

map<hobject_t, list<pair<ScrubMap::object,pg_shard_t> >> authoritative;

// Cleanedmap pending snap metadata scrub

ScrubMapcleaned_meta_map;

// digestupdates which we are waiting on

int num_digest_updates_pending;

// chunkyscrub

hobject_tstart, end;

eversion_tsubset_last_update;

// chunkyscrub state

enum State {

INACTIVE,

NEW_CHUNK,

WAIT_PUSHES,

WAIT_LAST_UPDATE,

BUILD_MAP,

WAIT_REPLICAS,

COMPARE_MAPS,

WAIT_DIGEST_UPDATES,

FINISH,

} state;

std::unique_ptr<Scrub::Store>store;

// deepscrub

bool deep;//是否为深度扫描

uint32_tseed;//计算CRC32校验码的种子

list<Context*>callbacks;

} scrubber;

1.1.1.2     ScrubMap

ScrubMap结构体保存准备校验的对象以及相应的校验信息

/*

* summarizepg contents for purposes of a scrub

*/

struct ScrubMap {

struct object {

map<string,bufferptr>attrs;//对象的属性

uint64_t size;//该对象的大小

__u32omap_digest;         ///< omapcrc32c

__u32digest;              ///< datacrc32c

bool negative:1;

bool digest_present:1;//是否计算了数据的校验码

bool omap_digest_present:1;//是否有omap的校验码标志

bool read_error:1;//读对象数据的错误标志

bool stat_error:1;//调用stat获取对象元数据时的出错标志

bool ec_hash_mismatch:1;//

bool ec_size_mismatch:1;

};

内部类object是用来保存对象需要的校验信息。

1.1.2  Scrub的控制流程的状态机

Scrub任务的由OSD的工作队列OpWq来完成,调用对应的处理函数pg->scrub(handle)来执行。最终调用PG::chunky_scrub函数控制scrub操作的状态转换和核心处理。

1. Scrubber的初始状态为INACTIVE。

(1) 设置scrubber的参数epoch_start

(2) 设置scrubber.active= true说明已经激活scrub

(3) 设置状态scrubber.status为NEW_CHUNK

(4) 设置scrubber.seed的类型,初始为-1

2. Scrubber的状态为NEW_CHUNK的处理。

(1) 通过函数objects_list_partial函数计算对象的边界,方便划界。

(2) 调用函数_range_available_for_scrub检查列表中的对象,是否存在被阻塞的对象,如果存在,则退出本次Scrub

(3) 根据pg_log计算start和end区间对象最大的更新版本号,更新至scrubber.subset_last_update

(4) 调用函数_request_scrub_map()向所有的副本发送消息,获取相应的ScrubMap的校验信息。

(5) 设置状态为WAIT_PUSHES

3. Scrubber的状态为WAIT_PUSHES的处理。

(1) 如果active_pushes的值为0,设置状态为WAIT_LAST_UPDATE进入下一个状态处理。

(2) 如果active_pushes的值不为0,说明该PG正在进行Recovery操作,设置done的值为true。在进入chunk_scrub时,PG应该处于CLEAN状态,不可能有Recovery操作(这里的Recovery应该是上次进行的chunky_scrub的修复操作)

4. Scrubber的状态为BUILD_MAP的处理。

(1) 调用函数build_scrub_map_chunk构造主OSD上对象的ScrubMap结构

(2) 如果构造成功,计数scrubber.waiting_on的值减1,并从队列中删除scrubber.waiting_on_whom,则相应的状态设置为WAIT_REPLICAS

4. Scrubber的状态为WAIT_REPLICAS的处理

(1) 若scrubber.waiting_on不为0,说明replica请求没有应答,设置done=true并退出等待;

(2) 否则,设置状态为COMPARE_MAPS

5. Scrubber的状态为COMPARE_MAPS的处理

(1) 调用函数scrub_compare_maps比较各副本的校验信息

(2) 将参数scrubber.start设置为srubber.end

(3) 调用参数requeue_ops,把由于Scrub而阻塞的读写操作重新加入操作队列里执行

(4) 设置状态为WAIT_DIGEST_UPDATES

6. Scrubber的状态为COMPARE_MAPS的处理

(1) 如果有scrubber.num_digest_updates_pending等待,等待更新数据的digest或者omap的digest

(2) 如果scrubber.end小于hobject_t::get_max(),本PG还存在没有完成Scrub操作的对象,设置状态scrubber.stat为NEW_CHUNK,继续把PG加入到osd->scrub_wq中

(3) 否则,设置状态为FINISH

6. Scrubber的状态为FINISH的处理

(1) 调用函数scrub_finish来设置相关的统计信息,并触发修复不一致的对象

(2) 设置状态为INACTIVE

调用函数build_scrub_map_chunk构造主OSD上对象的ScrubMap结构

(2) 如果构造成功,计数scrubber.waiting_on的值减1,并从队列中删除scrubber.waiting_on_whom,则相应的状态设置为WAIT_REPLICAS

1.1.3  构建ScrubMap

构建ScrubMap是由多个函数组成:

1. 调用函数build_scrub_map_chunk构建从start到end之间所有对象的校验信息并保存ScrubMap结构体中;

2. 调用函数_scan_snap扫描head对象保存的snap信息和snapset结构体中保存的该对象的snap信息是否一致,以前者保存的snap信息为准,修复snapset中保存的snap对象;

3. 调用函数be_scan_list构建ScrubMap结构体中对象的校验信息

4. 如果需要deep scrub,则调用be_deep_scrub进行深度扫描,获取omap和data的digest信息。

1.1.4  从副本处理

当从副本接收到主副本发送来的MOSDRepScrub类型消息时,用于获取对象的校验信息时,就调用函数replica_scrub来完成。

1.1.5  副本比较

当对象的主副本和从副本都完成了校验信息的构建,并保存在相应的结构体ScrubMap中,接下来,就是对比各个副本的校验信息来完成数据一致性检查。

首先通过对象自身的信息来选出一个权威的对象,然后用权威对象和其他对象来比较和检验。

1.1.6  结束Scrub

通过函数scrub_finish函数来结束scrub过程,处理流程如下:

1. 设置相关PG的状态和统计信息

2.修复scrubber中标记的missing和inconsistent对象;

3. 触发DoRecovery事件发送给PG的状态机。发起实际对象的修复操作。

2  参考文献

1. 百度百科——CAP原则

2. 摘自机械工业出版社《Ceph源码分析》

【分析】Ceph数据一致性检查 - Scrub的执行相关推荐

  1. 机械--NX2007(UG)--间隙分析(干涉检查)

    机械–NX2007(UG)–间隙分析(干涉检查) 原来的版本好像是叫干涉检查,现在叫间隙分析,也就是检查零件在装配时,有没有干涉(碰撞)冲突,以避免设计完成后却装配不了的情况. 装配体说明 左边垂直的 ...

  2. MySQL数据一致性检查的几个工具

    1.MySQL checksum命令 在执行checksum命令时,表会被加一个读锁(read lock),checksum table的原理是对表中的数据进行一行一行的较验和计算,因些对于大表,这是 ...

  3. Postgresql源码(85)查询执行——表达式解析器分析(select 1+1如何执行)

    相关 <Postgresql源码(61)查询执行--最外层Portal模块> <Postgresql源码(62)查询执行--子模块ProcessUtility> <Pos ...

  4. 一个操作系统的实现(1):分析linux下如何运行一个执行文件

    分类: 操作系统实现 本文只为整理思路,供自己日后参考.现在就从从一个执行文件a.out的运行开始,自上而下地分析linux是如何运行一个执行文件的. 1.首先,需要了解一下a.out这个目标文件.a ...

  5. java大神请出来_求java大神,请分析以下代码,写出执行结果,并解释每行结果输出的原因。...

    求java大神,请分析以下代码,写出执行结果,并解释每行结果输出的原因.classPlate{publicPlate(){System.out.println("inPlateconstru ...

  6. 分析oracle缓慢原因,Oracle SQL执行缓慢的原因分析

    以下的文章主要介绍的是Oracle SQL执行缓慢的分析,如果你是Oracle SQL执行方面的新手,你就可以通过以下的文章对Oracle SQL执行有一个更好的了解,以下就是文章的详细内容的介绍. ...

  7. 分析teamTNT团队Linux挖矿木马执行过程与防范

    分析teamTNT团队Linux挖矿木马执行过程与防范 公司需要扩展海外业务,需要有一台海外云服务器.当我们把应用部署上去时的第二天所有应用down掉了,然后发现ssh连接服务器特别慢.好不容易连接上 ...

  8. pprof搭配ceph tell命令分析ceph内存

    文章目录 安装 使用 使用`ceph tell`产生堆栈信息文 使用`pprof`工具分析内存及`ceph tell`释放内存 火焰图`FlameGraph`可视化进程堆栈信息 pprof是一个goo ...

  9. MySQL · 源码分析 · 一条insert语句的执行过程

    本文只分析了insert语句执行的主路径,和路径上部分关键函数,很多细节没有深入,留给读者继续分析 create table t1(id int); insert into t1 values(1) ...

  10. mysql insert执行过程_MySQL · 源码分析 · 一条insert语句的执行过程

    本文只分析了insert语句执行的主路径,和路径上部分关键函数,很多细节没有深入,留给读者继续分析 create table t1(id int); insert into t1 values(1) ...

最新文章

  1. java编程语言大全_JAVA编程语言的基础知识(一)
  2. Samba的配置与使用
  3. java关键词 英文原文解释,javadoc注释规范(国外英文资料).doc
  4. mysql编写触发器语法_mysql触发器语法
  5. LitJson使用范例
  6. 技术交底书(二)-----一种基于移动终端的安全防护系统
  7. html间超链接怎么做,超链接怎么做
  8. 机器学习实战(七):Ensemble Learning and Random Forests
  9. bnuoj 29065 鸣人的查克拉
  10. 广工数据结构课设——校园导游咨询(C语言)
  11. postman使用自定义函数
  12. encode() decode() 编码解码函数
  13. 很迷的SG??Berzerk - 787C
  14. satisfy with用法
  15. java集成微信发送模板消息
  16. 基于JavaEE的“三味”书屋网上售书系统
  17. 三相全桥整流 逆变 matlab,三相桥式有源逆变电路的MATLAB建模仿真
  18. Matlab实现 乘幂法反幂法
  19. Python爬虫入门,详细讲解爬虫过程
  20. 华大单片机低功耗注意事项

热门文章

  1. 苹果win7系统无线网络无法连接服务器,苹果电脑不能连接wifi怎么修复_苹果电脑wifi连不上解决步骤-win7之家...
  2. 自动驾驶技术越来越火,浅谈一些对百度Apollo开放平台8.0的看法和认知
  3. 观《蓝天铁翼-红旗军演》所想到的
  4. ME21N/ME22N/ME23N屏幕增强BADI ME_GUI_PO_CUST
  5. 32位与64位CPU字长
  6. 网络文件传输工具,秒杀各种网络文件传送工具的镭速云
  7. 【Winform】 Enum逆向解析
  8. 阿里云短信服务接口触发天级流控Permits:10
  9. 第五节:蜂鸣器的驱动程序
  10. quicktime安装不了