一般文件系统采用的fsck命令来维护文件系统一致性,但是fsck对cephfs的难度是非常大的,主要原因在于其机制存在根本的区别:
1. cephfs修复的是一个rados集群数据而非一块磁盘设备;
2. 需要精确的识别数据的所有数据片,及这些数据片所属的inode
3. 大量的元数据不可能全部保存到内存中
4. 数据丢失原因可能在于(1)系统bug导致;(2)由于RADOS同步的灾难性故障——可能到时大量数据丢失;(3)bit位翻转(bitrot)
作者:Younger Liu,
本作品采用知识共享署名-非商业性使用-相同方式共享 3.0 未本地化版本许可协议进行许可。
因此,Cephfs提供专门的工具ceph-data-scan来检查和维护文件系统的一致性。
1 cephfs-data-scan
cephfs-data-scan根据数据存储池中的内容重新生成丢失文件和目录的元数据对象。这要分三步完成,首先,初始化;其次,扫描所有对象以计算索引节点的尺寸和 mtime 元数据;最后,从每个文件的第一个对象扫描出元数据并注入元数据存储池。
cephfs-data-scan init
cephfs-data-scan scan_extents <datapool>
cephfs-data-scan scan_inodes <datapool>
如果数据存储池内的文件很多、或者有很大的文件,这个命令就要花费很长时间。要加快处理,可以让这个工具多跑几个例程。先确定例程数量、再传递给每个例程一个数字 N ,此数字应大于 0 且小于 (N - 1) ,像这样:
# Worker 0
cephfs-data-scan scan_extents <data pool> 0 1
# Worker 1
cephfs-data-scan scan_extents <data pool> 1 1
# Worker 0
cephfs-data-scan scan_inodes <data pool> 0 1
# Worker 1
cephfs-data-scan scan_inodes <data pool> 1 1
1.1 main分析
Cephfs-data-scan命令保存在src\tools\cephfs\cephfs-data-scan.cc中,其主要流程如下:
1. 调用初始化函数global_init进行参数初始化;
2. 调用函数common_init_finish初始化g_ceph_context,并启动服务线程;
3. 调用函数data_scan.init()初始化DataScan结构体——与MDS建立通信连接,获得MDS map等信息
4. 调用函数data_scan.main(args)执行用户命令。
1.2 dataScan结构体分析
DataScan结构体的父类与成员如下图:
1.3 函数DataScan init分析
函数init定义在父类MDSUtility中,其中init,其调用者与被调用者关系图,如下:很明显,datascan结构体主要用户Dumper、JournalTool、cephfs-data-scan、cephfs-table-tool及cephfs-journal-tool,而这些都需要cephfs修复机制相关。
Init的功能是利用网络通信创建message实例获取集群的OSD map、MDS map,流程如下:
1.4 函数DataScan main分析
函数主要是执行用户命令,其UML图如下
作者:Younger Liu,
本作品采用知识共享署名-非商业性使用-相同方式共享 3.0 未本地化版本许可协议进行许可。