关于glusterfs-3.0.4中AFR修复的一个bug

    夜深了,困扰了我好几天的bug今天终于让我揪出来了,有点如释重负的感觉。

问题描述:

在AFR冗余度为2的glusterfs3.0.4系统上,创建虚拟机(img文件),然后启动虚拟机,然后宕掉AFR一个子节点,在虚拟机用dd开始一直写数据,然后再启动刚才宕掉的AFR子节点进程,触发修复。带修复完毕后,把虚拟机关掉。计算AFR两个子节点img文件的md5值不一样(AFR为镜像冗余,两子节点上的文件应该是一样的才对)。

是边写边修复的加锁原因么?

模拟测试:

用dd在glusterfs上一直进行写操作,然后宕掉AFR一个子节点进程,然后再启动宕掉的子节点进程,触发修复。修复完毕后,kill掉dd进程,查看AFR后端的文件,md5值是一样的,排除了边写边修复的问题。

是多线程写导致的么?

通过打印log也排除了此种可能性。

再看修复后两个子节点上的img文件,ls -l 显示的size是一样的,用stat查看block数是不一样的,难道是空洞文件导致的?

找到afr修复部分的代码,呵呵,在进行差量修复时,若在源文件上需要修复的数据块为全0时,不再去写入目标文件(估计愿意是在目标文件上产生空洞文件)。这样就有问题了,因为在目标文件宕掉的时候,源文件一直再更新(虚拟机运行着且进行各种操作),有可能会将原来非全0的数据块更新为全0数据块,而宕掉的文件对应的区域仍为非全0数据块,此种情况下不去更新目标文件,必然导致修复后文件不一致。

所以,在修复时对空洞(全0)数据块的处理是错误的,在此应该去掉,而且代码中对全0的判断是一个大while循环,去掉后反而会提升一些代码的性能,呵呵,原来大牛们是咋想的呢?

夜深了,睡吧~

你可能感兴趣的:(bug,gluster,修复,gluterfs,selfheal)