今天有人问了两个关于EC的问题,就在这里写篇博客解答,希望对大家理解Cepg的EC的实现机制有帮助。
1)EC 在 remove object的时候,考虑到回滚,不是马上删除,那么什么时刻真正删除?
2) 回滚机制如何触发?
问题1:什么时候真正删除对象?
1.字段 min_last_complete_ondisk 用来记录 该PG的所有 osd中最小提交的版本号,也就是小于该版本的rollback对象都可以删除了。因为所有osd都已经完成请求。他在函数calc_min_last_complete_ondisk里计算更新。
class PG{
...
eversion_t min_last_complete_ondisk
...
}
2.在下次写操作过程中,函数issue_repop会带上 min_last_complete_ondisk信息用于删除 rollback对象。
void ReplicatedPG::issue_repop(RepGather *repop, OpContext *ctx){
......
pgbackend->submit_transaction(
soid,
ctx->at_version,
std::move(ctx->op_t),
pg_trim_to,
min_last_complete_ondisk,
ctx->log,
ctx->updated_hset_history,
onapplied_sync,
on_all_applied,
on_all_commit,
repop->rep_tid,
ctx->reqid,
ctx->op);
......
}
3.在函数ECBackend::handle_sub_write处理EC写操作时,调用:
get_parent()->log_operation(
op.log_entries,
op.updated_hit_set_history,
op.trim_to,
op.trim_rollback_to,
!(op.t.empty()),
localt);
4.在ReplicatedPG的log_operation 函数里调用,最终调用PGLogEntryHandler的visit函数里,调用LogEntryTrimmer 实现删除对象。(这个实现用了 visit 设计模式,这里不详细分析)。
问题2:
什么时候rollback ? 当一个PG(EC M+N), 有多于N个osd失效时,不能恢复最新数据,只能rollback,来恢复旧数据。 这个过程在PG的peering过程中完成。