文档章节

Migrator类分析

linuxhunter
 linuxhunter
发布于 2016/07/26 10:48
字数 2533
阅读 129
收藏 0

Migrator类说明:

class Migrator {

     MDSRank *mds;          记录mds信息

     MDCache *cache;          记录MDCache信息

     struct export_state_t {

          int state;                    记录export的当前状态

          mds_rank_t peer;          记录export到对端mds rank信息

          uint64_t tid;                    记录export到对端的session id信息

          set<mds_rank_t> warning_ack_waiting;     等待warning ack的mds集合

          set<mds_rank_t> notify_ack_waiting;          等待notify ack的mds集合

          map<inodeno_t, map<client_t, Capability::Import>> peer_imported;     记录export对端信息

          list<MDSInternalContextBase*> waiting_for_finish;                              记录等待finish的集合

          MutationRef                     mut;      MutationImpl对象引用

          utime_t last_cum_auth_pins_change;

          int last_cum_auth_pins;

          int num_remote_waiters;              远程auth pin waiters

     };

     map<CDir*, export_state_t> export_state;          export的状态集合

     list<pair<dirfrag_t, mds_rank_t>> export_queue;     export队列

     struct import_state_t {

          int state;

          mds_rank_t peer;

          uint64_t tid;

          set<mds_rank_t> bystanders;

          list<dirfrag_t> bound_ls;

          list<ScatterLock*> updated_scatterlocks;

          map<client_t, entity_inst_t> client_map;

          map<CInode*, map<client_t, Capability::Export>> peer_exports;

          MutationRef mut;

     };

     map<dirfrag_t, import_state_t> import_state;

};

 

Migrator类方法:

Migrator::dispatch(m)                              核心分发处理函数

|__根据m的类型决定后续的处理过程

     |__类型是MSG_MDS_EXPORTDIRDISCOVER

          |__调用handle_export_discover(MExportDirDiscover* m)

     |__类型是MSG_MDS_EXPORTDIRPREP

          |__调用handle_export_prep(MExportDirPrep* m)

     |__类型是MSG_MDS_EXPORTDIR

          |__调用handle_export_dir(MExportDir* m)

     |__类型是MSG_MDS_EXPORTDIRFINISH

          |__调用handle_export_finsih(MExportDirFinish* m)

     |__类型是MSG_MDS_EXPORTDIRCANCEL

          |__调用handle_export_cancel(MExportDirCancel* m)

     |__类型是MSG_MDS_EXPORTDIRDISCOVERACK

          |__调用handle_export_discover_ack(MExportDirDiscoverAck* m)

     |__类型是MSG_MDS_EXPORTDIRPREACK

          |__调用handle_export_prep_ack(MExportDirPrepAck* m)

     |__类型是MSG_MDS_EXPORTDIRACK

          |__调用handle_export_ack(MExportDirAck* m)

     |__类型是MSG_MDS_EXPORTDIRNOTIFYACK

          |__调用handle_export_notify_ack(MExportDirNotifyAck* m)

     |__类型是MSG_MDS_EXPORTDIRNOTIFY

          |__调用handle_export_dir_notify(MExportDirNotify* m)

     |__类型是MSG_MDS_EXPORTCAPS

          |__调用handle_export_caps(MExportCaps* m)

     |__类型是MSG_MDS_GATHERCAPS     

          |__调用handle_gather_caps(MGatherCaps* m)

 

Migrator::export_empty_import(dir)

|__dir对应的inode节点是auth的

     |__直接返回

|__dir是auth的

     |__直接返回

|__dir是freezing或frozen

     |__直接返回

|__dir不是空目录

     |__直接返回

|__dir是root节点

     |__直接返回

|__得到export目的dir所在的mds节点,即:dir->inode->authority().first

|__调用export_dir(dir, dest)               执行实际的export操作

 

Migrator::export_dir(dir, dest)

|__检查MDCache是否是readonly(目前尚不支持read-only模式的export)

     |__直接返回

|__检查mdsmap是否是degraded(cluster处于degraded状态则不能export)

     |__直接返回

|__检查dir的inode是否是system(不能export system dir)

     |__直接返回

|__检查dir的inode是否是stray

     |__直接返回

|__检查dir是否处于freezing或frozen

     |__直接返回

|__检查dir是否处于EXPORTING状态

     |__直接返回

|__执行dir的auth_pin()

|__设置dir的当前状态为EXPORTING,即:dir->state_set(STATE_EXPORTING)

|__从MDCache中得到MDRequestRef类对象,即:mds->mdcache->request_start_internal(EXPORTDIR)

|__设置MDRequest类对象中的_more的export_dir为dir,即:保存待export的dir数据

|__从export_state数组中得到dir为索引对应的export_state_t对象stat

|__设置stat的state为EXPORT_LOCKING

|__设置stat的peer为dest

|__设置stat的tid为mdr->reqid.tid

|__设置stat的mut为mdr

|__调用dispatch_export_dir(mdr)来发送export dir请求

 

Migrator::dispatch_export_dir(mdr)

|__从mdr的_more中得到待export的dir数据,即:mdr->more()->export_dir

|__从export_state数组中找到dir对应的export state项

|__设置export_state_t的当前状态是EXPORT_DISCOVERING

|__创建MExportDirDiscover类消息

|__将消息发送给目的MDS进程,即:mds->send_message_mds(discover, it->second.peer)

|__设置export_state_t中的last_cum_auth_pins_change为系统当前时间

|__freeze当前dir的tree,即:dir->freeze_tree()

|__添加dir等待WAIT_FROZEN的回调函数C_MDC_ExportFreeze(),即:调用export_frozen()函数

 

Migrator::handle_export_discover(MExportDirDiscover *m) (对端)

|__从消息中得到对端的mds_rank_t以及dirfrag_t结构,即:from=m->get_source_mds()/df = m->get_dirfrag()

|__遍历import_state数组

     |__若数组中没有找到对应的项且m->started==false

          |__设置m->started=true

          |__更新import_state数组中对应的项,即:state=IMPORT_DISCOVERING/peer=from/tid=m->get_tid()

|__从MDCache中得到export的dir的CInode信息,即:in=cache->get_inode(m->get_dirfrag().ino)

|__更新import_state数组中对应的项,即:state==IMPORT_DISCOVERED

|__创建MExportDirDiscoverAck类消息

|__将类消息发送回给mds进程,即:mds->send_message_mds()

 

Migrator::handle_export_discover_ack(MExportDirDiscoverAck* m)

|__从消息中得到dirfrag,之后从MDCache中得到dirfrag对应的CDir类对象,即:cache->get_dirfrag(m->get_dirfrag())

|__在export_state数组中查找dir对应的项

|__在export_state数组对应的dir项中设置其状态为EXPORT_FREEZING

 

Migrator::export_frozen(dir, tid)

|__从export_state数组中查找dir对应的项

|__得到该dir对应的CInode,即:dir->get_inode()

|__创建一个新的MutationImpl类对象且将其放入export_state_t的mut中

|__根据dirfrag和tid创建一个MExportDirPrep类消息

|__遍历dir的replicas数组

     |__将数组中的成员添加到MExportDirPrep类消息的bystander中

|__将basedir添加到MExportDirPrep类消息的basedir中

|__遍历bounds数组

     |__将bounds成员添加到MExportDirPrep类消息的bound中

     |__循环处理如下内容

          |__将bounds成员的inode添加到inodes_added数组中

          |__遍历bounds成员的parent目录

     |__将dirfrag以及start信息序列化到bufferlist中

     |__将bufferlist写入到MExportDirPrep类消息的trace中

|__设置export_state_t中的状态为EXPORT_PREPPING

|__将MExportDirPrep类消息发送给目的MDS,即:mds->send_message_mds()

 

Migrator::handle_export_prep(MExportDirPrep *m)     (对端)

|__从import_state数组中找到消息中对应的dirfrag项

|__从MDCache中得到dir和dir对应的CInode

|__遍历消息中的bounds数组

     |__将数组中的内容添加到import_bound_fragset数组中

|__若消息中的did_assim()==false

     |__设置当前import_state数组中对应项的state为IMPORT_PREPPING

     |__从消息中解析traces数组

          |__将traces数组中的内容添加到MDCache中

     |__遍历import_bound_fragset数组

          |__从数组成员的inodeno_t的到对应的CInode结构

          |__调用CInode对应的get_stickydirs()函数

|__遍历import_bound_fragset数组

     |__从数组成员的inodeno_t的到对应的CInode结构

     |__遍历数组成员中fragset_t下所有叶子节点

          |__根据叶子节点得到在MDCache中对应的CDir数据

          |__若CDir数据不在MDCache中

               |__执行MDCache中的open_remote_dirfrag()函数来创建这个CDir

          |__将叶子节点对应的CDir数据插入到import_bounds数组中

|__设置import_state数组指定成员的状态为IMPORT_PREPPED

|__创建MExportDirPreAck类消息

|__调用mds的send_message()方法将类消息发送给指定的MDS进程

 

Migrator::handle_export_prep_ack(MExportDirPrepAck *m)

|__根据消息的dirfrag得到对应的CDir类对象

|__在export_state数组中查找CDir类对象对应的项

|__遍历replicas数组

     |__将mds_rank_t信息插入到export_state_t结构中的warning_ack_waiting/notify_ack_waiting数组中

     |__创建MExportDirNotify类消息

     |__将MEXportDirNotify类消息发送给对端mds进程

|__设置export_state_t结构中的state为EXPORT_WARNING

 

Migrator::handle_export_notify(MExportDirNotify *m)     (对端)

|__从MDCache中得到消息中dirfrag对应的CDir类对象

|__创建MExportDirNotifyAck类消息

|__调用mds的send_message_mds()将类消息发送回给mds进程

 

Migrator::handle_export_notify_ack(MExportDirNotifyAck *m)

|__根据消息的dirfrag得到对应的CDir类对象

|__从消息中得到对端mds_rank_t信息

|__若在export_state数组中能够找到dir对应的项

     |__若export_state_t的state==EXPORT_WARNING

          |__调用export_go(dir)     执行实际的export操作

     |__若export_state_t的state==EXPORT_NOTIFYING

          |__调用export_finish(dir)

 

Migrator::export_go(dir)

|__调用哦mds中mdlog的wait_for_safe()函数来设置回调函数C_M_ExportGo(),最后执行export_go_synced(dir, tid)

|__flush mds的mdlog,即:|mds->mdlog->flush()

 

Migrator::export_go_synced(dir, tid)

|__在export_state数组中查找dir对应的项

|__设置其状态为EXPORT_EXPORTING

|__创建MExportDir类消息

|__调用encode_export_dir()得到export的map信息以及得到exported_inodes数量

|__将得到的export的map信息序列化到类消息的client_map中

|__遍历bounds数组

     |__将数组中的成员添加到类消息的export数组中

|__发送类消息到对端mds进程,即:mds->send_message_mds()

 

Migrator::handle_export_dir(MExportDir *m)     (对端)

|__从MDCache中得到消息中dirfrag对应的CDir类对象

|__从import_state数组中查到消息中dirfrag对象的项

|__创建C_MDS_ImportDirLoggedStart回调函数类

|__创建EImportStart日志入口

|__调用MDS的mlog的start_entry()来启动日志

|__将消息中的client_map信息解析道EImportStart中的imported_client_map中

|__从消息中得到export_data

|__调用decode_import_dir()函数,将export_data写入到mdlog对应的current segment里

|__遍历消息中的bounds数组

     |__将数组中dirfrag_t对应的CDir添加到LogSegment中

     |__将数组中dirfrag_t对应的CDir添加到import_bounds数组中

|__调用mds的balancer的add_import()函数来平衡查找树

|__设置import_state_t中的状态为IMPORT_LOGGINGSTART

|__启动mdlog,即:mds->mdlog->submit_entry()/mds->mdlog->flush()

 

Migrator::import_logged_start()     (对端)

|__在import_state数组中查找dirfrag对应的项

|__设置对应项的state为IMPORT_ACKING

|__创建MExportDirAck类对象

|__发送MExportDirAck类对象到mds进程

 

Migrator::handle_export_ack(MExportDirAck *m)

|__在export_state数组中查找dirfrag对应的项

|__将消息中的imported_caps解析到export_state_t中的peer_imported中

|__设置对应项的state为EXPORT_LOGGINGFINISH

|__创建EExport类对象

|__将bounds数组中的内容写入到EExport类对象的metablob中

|__创建C_MDS_ExportFinishLogged回调函数类

|__启动mdlog,即:mds->mdlog->submit_entry()/mds->mdlog->flush()

 

Migator::export_logged_finish(dir)

|__查找export_state数组中指定dir的export_state_t项

|__遍历export_state_t项中的notify_ack_waiting数组

     |__创建MExportDirNotify类消息

     |__发送MExportDirNotify类消息到mds进程

|__设置export_state_t中的状态为EXPORT_NOTIFYING

|__创建MExportDirFinish类消息

|__发送MExportDirFinish类消息到mds进程

 

Migrator::handle_export_finish(MExportDirFinish *m)     (对端)

|__在import_state数组中找到对应项

|__调用import_finish()函数

 

Migrator::import_finish(dir, notify, last)     (对端)

|__从import_state数组中得到指定dirfrag

|__若state==IMPORT_ACKING

     |__遍历import_state_t中的peer_exports数组

          |__更新MDCache中的内容

|__若last==false

     |__设置state=IMPORT_FINISHING

     |__直接返回

|__处理MDCache中的内容

 

=======================export client maps and client caps

Migrator::encode_export_inode_caps(in, auth_cap, bl, exported_client_map)     得到client map以及client caps map

|__调用in->export_client_caps()函数,得到in的client capability map信息

|__将client capability map信息序列化到bl中

|__遍历in的client_caps数组

     |__从mds的sessionmap中得到client_caps数组成员对应的信息并写入到exported_client_map中

 

Migrator::export_caps(CInode *in)

|__从in中得到授权的mds_rank_t信息,即:in->authority().first

|__创建MExportCaps类消息

|__设置类消息的ino为in->ino()

|__调用encode_export_inode_caps()

|__调用mds的send_message_mds()函数将MExportCaps消息发送给指定的MDS进程

 

Migrator::handle_export_caps(MExportCaps *ex)

|__从MDCache中得到类消息中的CInode信息,即:in=cache->get_inode(ex->ino)

|__若in处于frozen状态

     |__直接返回

|__创建C_M_LoggedImportCaps回调函数类

|__将类消息中的client_map信息写入到回调函数类的client_map中

|__调用decode_import_inode_caps()函数将类消息中的client caps信息反序列化并保存到peer_exports数组中

|__创建ESession类型的LogEvent类消息(client_map)

|__写mdlog日志,即:mds->mdlog->start_submit_entry()

|__调用mds->mdlog->flush()     刷mdlog日志

 

Migrator::handle_gather_caps(MGatherCaps *m)

|__从MDCache中得到类消息对应的CInode信息,即:cache->get_inode(m->ino)

|__若in存在caps并且in不存在auth并且in没有EXPORTINGCAPS

     |__调用export_caps(in)          将in对应的client maps和client caps map export出去

 

Migrator导入导出状态机处理过程如下图所示:

© 著作权归作者所有

上一篇: MDCache类分析
linuxhunter
粉丝 72
博文 144
码字总数 93264
作品 0
沈阳
高级程序员
私信 提问
FmPro Migrator 6.35 发布,数据库迁移工具

FmPro Migrator 6.35 发布,该版本更新如下: This release adds creation of Script to Layout Object Report.txt and Script to Layout Usage Report.txt files for PHP conversion projec......

小卒过河
2011/10/02
384
0
Entityframework Migrations

  EF相关的内容园子里已经有很多很好的文章了,这篇只是把自己之前的一些整理搬运到这里,抛砖引玉,温故知新。 Migrations确实是个好东西,至少就升级维护Database方面,帮助笔者脱离苦海...

DogTwo
2018/12/29
0
0
Marko v4.14.8 发布,快速友好的 UI 库

Marko v4.14.8 已发布,Marko 是一个快速、友好的 UI 库,由 eBay 开源,旨在让构建 web 应用更有趣。 特性 简单 —— 只要了解 HTML、CSS 和 Javascript,你就会用 Marko ; 快速 —— 通过...

王练
2018/12/28
1K
1
Ghost Blog 开发环境搭建

Ghost Blog 开发环境搭建 标签(空格分隔): Ghost Blog Dev ![image_1b4sjrjrv14v1dqc1kiqts6vv09.png-478.4kB][1] Ghost 官方截图 Glost Blog Ghost Blog 源于WordPress两位大拿的灵感。 ......

superduper
2016/12/26
128
0
Harbor升级和数据库迁移手册

Harbor升级和数据库迁移手册 当升级一个已经存在的Harbor实例到新版本时,需要迁移数据库数据。参考What's New in Harbor Database Schema查看数据库发生了哪些变化,如果有的话,就需要进行...

党志强
2018/07/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

CQRS与AXON

CQRS 看了蛮多文章,只会CRUD,却不懂CQRS,CQRS是遵循DDD思想而产生的一种模式,Command and Query Responsibility Segregation 命令与查询隔离。查询就直接通过正常的模式service调dao层。...

无极之岚
36分钟前
4
0
OSChina 周三乱弹 —— 欢迎你来做产品经理

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @巴拉迪维 :10多次劲歌金曲获奖,更多叱咤歌坛排名,黎明才应该是四大天王之首,只可惜拍的电影太少。单曲循环一个多月的歌,力荐 《无名份的...

小小编辑
51分钟前
118
8
500行代码,教你用python写个微信飞机大战

这几天在重温微信小游戏的飞机大战,玩着玩着就在思考人生了,这飞机大战怎么就可以做的那么好,操作简单,简单上手。 帮助蹲厕族、YP族、饭圈女孩在无聊之余可以有一样东西让他们振作起来!...

上海小胖
今天
8
0
关于AsyncTask的onPostExcute方法是否会在Activity重建过程中调用的问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/XG1057415595/article/details/86774575 假设下面一种情况...

shzwork
今天
7
0
object 类中有哪些方法?

getClass(): 获取运行时类的对象 equals():判断其他对象是否与此对象相等 hashcode():返回该对象的哈希码值 toString():返回该对象的字符串表示 clone(): 创建并返此对象的一个副本 wait...

happywe
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部