【分析】Ceph数据一致性检查 - Scrub的执行
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的执行相关推荐
- 机械--NX2007(UG)--间隙分析(干涉检查)
机械–NX2007(UG)–间隙分析(干涉检查) 原来的版本好像是叫干涉检查,现在叫间隙分析,也就是检查零件在装配时,有没有干涉(碰撞)冲突,以避免设计完成后却装配不了的情况. 装配体说明 左边垂直的 ...
- MySQL数据一致性检查的几个工具
1.MySQL checksum命令 在执行checksum命令时,表会被加一个读锁(read lock),checksum table的原理是对表中的数据进行一行一行的较验和计算,因些对于大表,这是 ...
- Postgresql源码(85)查询执行——表达式解析器分析(select 1+1如何执行)
相关 <Postgresql源码(61)查询执行--最外层Portal模块> <Postgresql源码(62)查询执行--子模块ProcessUtility> <Pos ...
- 一个操作系统的实现(1):分析linux下如何运行一个执行文件
分类: 操作系统实现 本文只为整理思路,供自己日后参考.现在就从从一个执行文件a.out的运行开始,自上而下地分析linux是如何运行一个执行文件的. 1.首先,需要了解一下a.out这个目标文件.a ...
- java大神请出来_求java大神,请分析以下代码,写出执行结果,并解释每行结果输出的原因。...
求java大神,请分析以下代码,写出执行结果,并解释每行结果输出的原因.classPlate{publicPlate(){System.out.println("inPlateconstru ...
- 分析oracle缓慢原因,Oracle SQL执行缓慢的原因分析
以下的文章主要介绍的是Oracle SQL执行缓慢的分析,如果你是Oracle SQL执行方面的新手,你就可以通过以下的文章对Oracle SQL执行有一个更好的了解,以下就是文章的详细内容的介绍. ...
- 分析teamTNT团队Linux挖矿木马执行过程与防范
分析teamTNT团队Linux挖矿木马执行过程与防范 公司需要扩展海外业务,需要有一台海外云服务器.当我们把应用部署上去时的第二天所有应用down掉了,然后发现ssh连接服务器特别慢.好不容易连接上 ...
- pprof搭配ceph tell命令分析ceph内存
文章目录 安装 使用 使用`ceph tell`产生堆栈信息文 使用`pprof`工具分析内存及`ceph tell`释放内存 火焰图`FlameGraph`可视化进程堆栈信息 pprof是一个goo ...
- MySQL · 源码分析 · 一条insert语句的执行过程
本文只分析了insert语句执行的主路径,和路径上部分关键函数,很多细节没有深入,留给读者继续分析 create table t1(id int); insert into t1 values(1) ...
- mysql insert执行过程_MySQL · 源码分析 · 一条insert语句的执行过程
本文只分析了insert语句执行的主路径,和路径上部分关键函数,很多细节没有深入,留给读者继续分析 create table t1(id int); insert into t1 values(1) ...
最新文章
- java编程语言大全_JAVA编程语言的基础知识(一)
- Samba的配置与使用
- java关键词 英文原文解释,javadoc注释规范(国外英文资料).doc
- mysql编写触发器语法_mysql触发器语法
- LitJson使用范例
- 技术交底书(二)-----一种基于移动终端的安全防护系统
- html间超链接怎么做,超链接怎么做
- 机器学习实战(七):Ensemble Learning and Random Forests
- bnuoj 29065 鸣人的查克拉
- 广工数据结构课设——校园导游咨询(C语言)
- postman使用自定义函数
- encode() decode() 编码解码函数
- 很迷的SG??Berzerk - 787C
- satisfy with用法
- java集成微信发送模板消息
- 基于JavaEE的“三味”书屋网上售书系统
- 三相全桥整流 逆变 matlab,三相桥式有源逆变电路的MATLAB建模仿真
- Matlab实现 乘幂法反幂法
- Python爬虫入门,详细讲解爬虫过程
- 华大单片机低功耗注意事项
热门文章
- 苹果win7系统无线网络无法连接服务器,苹果电脑不能连接wifi怎么修复_苹果电脑wifi连不上解决步骤-win7之家...
- 自动驾驶技术越来越火,浅谈一些对百度Apollo开放平台8.0的看法和认知
- 观《蓝天铁翼-红旗军演》所想到的
- ME21N/ME22N/ME23N屏幕增强BADI ME_GUI_PO_CUST
- 32位与64位CPU字长
- 网络文件传输工具,秒杀各种网络文件传送工具的镭速云
- 【Winform】 Enum逆向解析
- 阿里云短信服务接口触发天级流控Permits:10
- 第五节:蜂鸣器的驱动程序
- quicktime安装不了