BlueStore写流程事务实现梳理

Tag: ceph 12.2.4

BlueStore transaction相关结构

BlueStore事务状态转换

OSD层IO保序处理

ShardedOpWQ内部存在一组ShardData,每个ShardData包含队列pqueue、锁sdata_op_ordering_lock;

IO放入时根据pgid哈希映射到某一个shard(保证同一pg映射到同一shard),shard内部通过锁sdata_op_ordering_lock保序;


BlueStore层写操作处理

simple write: 新写 | 对齐写等(非WAL)场景;

deferred write: 需要写WAL场景;

  • simple write

1)数据写块设备(新block); 2)更新元数据(k/v);

事务状态转换

写新block:
STATE_PREPARE -> STATE_AIO_WAIT -> STATE_IO_DONE -> STATE_KV_QUEUED;

更新元数据(k/v):
STATE_KV_QUEUED -> STATE_KV_SUBMITTED -> STATE_KV_DONE -> STATE_FINISHING -> STATE_DONE;

线程情况

线程池osd_op_tp设置状态STATE_PREPARE、STATE_AIO_WAIT,提交IO待回调;

线程aio_thread回调处理,设置状态STATE_IO_DONE、STATE_KV_QUEUED;

线程kv_sync_thread提交k/v事务,设置状态STATE_KV_SUBMITTED;

线程kv_finalize_thread设置状态STATE_KV_DONE、STATE_FINISHING、STATE_DONE;

若步骤1完成后发生异常,原先数据未被破坏且元数据并未更新,本次更新数据不可见;

更新元数据,针对同一对象的操作需保序执行;

// 方法:void BlueStore::_txc_finish_io(TransContext *txc)

while (p != osr->q.begin()) {
    --p;
    // osr内部列表q中元素p(TransContext)之前是否都已完成IO
    if (p->state < TransContext::STATE_IO_DONE) {
      return;
    }
    if (p->state > TransContext::STATE_IO_DONE) {
      ++p;
      break;
    }
  }
  do {
    _txc_state_proc(&*p++);  // 放入kv_queue
  } while (p != osr->q.end() && p->state == TransContext::STATE_IO_DONE);

更新元数据完成,_txc_state_proc执行事务状态STATE_KV_SUBMITTED分支,调用_txc_committed_kv进入队列待回调,其后数据可读/已提交;

  • deferred write

数据和元数据写WAL(k/v, PREFIX_DEFERRED),其后数据可读/已提交,后续将数据写入块设备;

事务状态转换

写WAL:
STATE_PREPARE -> STATE_IO_DONE -> STATE_KV_QUEUED -> STATE_KV_SUBMITTED -> STATE_KV_DONE -> STATE_DEFERRED_QUEUED;

写数据:
STATE_DEFERRED_QUEUED -> STATE_DEFERRED_CLEANUP -> STATE_FINISHING -> STATE_DONE;

线程情况

线程池osd_op_tp设置状态STATE_PREPARE、STATE_IO_DONE和STATE_KVQUEUED,WAL写请求在k/v队列排队,待kv_sync_thread提交k/v日志,设置状态STATE_KV_SUBMITTED;

线程kv_finalize_thread设置状态STATE_KV_DONE和STATE_DEFERRED_QUEUED,生成写数据deferredbatch事务(dbh)并提交IO请求,待回调;

线程aio_thread回调处理,设置状态STATE_DEFERRED_CLEANUP ;

线程kv_sync_thread清理对应k/v日志;

线程kv_finalize_thread设置状态STATE_FINISHING、STATE_DONE;

异常情况,可通过WAL回放(_deferred_replay);

若数据未写入块设备前,读取该对象,等待pending aio下刷完成再读取;

数据写块设备时如何保序,IO事务OpSequencer进入队列deferred_queue,

_deferred_submit_unlock方法中将deferred_pending、deferred_running两者进行交换,准备aio结构,aio_submit一次性提交txc,完成后进行下一次提交。

另外,simple write和deferred write之间如何保序写kv,事务按序进入OpSequencer q_list_t(_txc_create),simple wirte完成数据写入后,_txc_finish_io将自身事务状态置为STATE_IO_DONE,deferred write调用_txc_finish_io状态直接从STATE_PREPARE转换为STATE_IO_DONE,OpSequencer内部列表本事务之前所有事务都已完成IO,事务按序放入kv_queue,待_kv_sync_thread处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值