Ceph增量备份import diff export diff代码串讲

export-diff:
入口:
rbd.cc
Ceph增量备份import diff export diff代码串讲_第1张图片

Ceph增量备份import diff export diff代码串讲_第2张图片
所谓的context, 指明一些基本的模块, 记录image相关的信息,包括参数等。
调用image.diff_iterate返回两个快照前的变化数据,结果写入到fd中。

这里写图片描述
这里实际调用librbd::diff_iterate()
Ceph增量备份import diff export diff代码串讲_第3张图片

这里第一种情况,第一次比对有parent的情况。
Ceph增量备份import diff export diff代码串讲_第4张图片

开始循环,调用file_to_extents()
原本的offset是指在rbd内的偏移量(写入rbd的位置),经过file_to_extents后,转化成了一个或者多个object的内部的偏移量offset0。这样转化后处理一批这个object内的请求.
Ceph增量备份import diff export diff代码串讲_第5张图片
然后针对这个object,看两个快照之间有没有diff,如果diff 为空,说明这两个快照间没有数据变化
Ceph增量备份import diff export diff代码串讲_第6张图片

否则调calback函数,这儿是export_diff_cb,实际上最终是掉aio_read
测试发现librbd::diff_iterate()的bug, 和社区反馈,邮件讨论如下:
https://www.mail-archive.com/[email protected]/msg33923.html

确认了是一个bug,对于克隆出来的object,如果有快照的数据覆盖了parent对应的部分,diff居然没有包括这部分和parent的的不同:
http://tracker.ceph.com/issues/18068

给出的fix如下:
https://github.com/ceph/ceph/pull/12218

import-diff:
调用do_import_diff 以snap2 到snap3为例:
检查fromsnap是存在的,tosnap是不存在的。
然后开始把diff的object 写到header版本上去,最后写完了,打一个快照snap3。
注意, export-diff总是更新的header版本,完成后最后打快照。这就容易出现import-diff执行到一半,失败退出,header版本被写脏的问题。针对此,跟社区提交了一个问题:
http://tracker.ceph.com/issues/17928
而一个有效的workaround,就是,出现import-diff失败的时候,想header版本rollback到最近一次快照,保证引入的脏数据被回滚掉。

你可能感兴趣的:(ceph)