From ec7321a9a3c48981a36a95d15e61ac9ec6cb561c Mon Sep 17 00:00:00 2001 From: kevinyao0901 Date: Sun, 22 Dec 2024 14:29:54 +0800 Subject: [PATCH] fix bugs for rollback policy --- db/db_impl.cc | 71 ++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/db/db_impl.cc b/db/db_impl.cc index 370792d..9719c4d 100644 --- a/db/db_impl.cc +++ b/db/db_impl.cc @@ -1309,7 +1309,8 @@ Status DBImpl::Put(const WriteOptions& o, const Slice& key, const Slice& val) { Status DBImpl::Delete(const WriteOptions& options, const Slice& key) { //ToDo - WriteBatch batch; // 创建事务 + WriteBatch batch; // 创建主数据库的事务 + WriteBatch indexBatch; // 创建二级索引数据库的事务 Status s; // 在主数据库删除数据 @@ -1317,38 +1318,52 @@ Status DBImpl::Delete(const WriteOptions& options, const Slice& key) { // 如果不是在 indexDb_ 上调用 Delete,则需要处理索引删除 if (indexDb_ != nullptr) { - // 遍历fieldWithIndex_,检查是否需要删除索引 - for (const auto& field : fieldWithIndex_) { - size_t field_pos = key.ToString().find(field + ":"); - if (field_pos != std::string::npos) { - size_t value_start = field_pos + field.size() + 1; - size_t value_end = key.ToString().find("|", value_start); - if (value_end == std::string::npos) { - value_end = key.ToString().size(); - } - std::string fieldValue = key.ToString().substr(value_start, value_end - value_start); + // 遍历 fieldWithIndex_,检查是否需要删除索引 + for (const auto& field : fieldWithIndex_) { + size_t field_pos = key.ToString().find(field + ":"); + if (field_pos != std::string::npos) { + size_t value_start = field_pos + field.size() + 1; + size_t value_end = key.ToString().find("|", value_start); + if (value_end == std::string::npos) { + value_end = key.ToString().size(); + } + std::string fieldValue = key.ToString().substr(value_start, value_end - value_start); - if (!fieldValue.empty()) { - std::string indexKey = field + ":" + fieldValue; + if (!fieldValue.empty()) { + std::string indexKey = field + ":" + fieldValue; - // 将索引删除操作加入事务 - batch.Delete(Slice(indexKey)); - } - } + // 将索引删除操作加入二级索引数据库的事务 + indexBatch.Delete(Slice(indexKey)); + } } - } + } - // 如果是 indexDb_ 调用,则仅提交该数据库的删除操作 - if (this == indexDb_) { - s = indexDb_->Write(options, &batch); // 删除操作直接提交给 indexDb_ - } else { - // 使用 `this->Write` 提交事务 - s = this->Write(options, &batch); // 提交给主数据库和索引数据库的事务 - } + // 提交主数据库的 WriteBatch + s = this->Write(options, &batch); + if (!s.ok()) { + return s; // 如果主数据库删除失败,则直接返回错误 + } - if (!s.ok()) { - // 如果操作失败,则返回错误状态 - return s; + // 提交二级索引数据库的 WriteBatch + s = indexDb_->Write(options, &indexBatch); + if (!s.ok()) { + // 如果二级索引数据库删除失败,回滚主数据库的删除操作 + // 回滚操作:重新插入已删除的主数据库的键 + WriteBatch rollbackBatch; + rollbackBatch.Put(key, ""); // 将原始数据重新插入主数据库 + Status rollbackStatus = this->Write(options, &rollbackBatch); + if (!rollbackStatus.ok()) { + return rollbackStatus; // 如果回滚操作失败,返回回滚错误 + } + + return s; // 返回二级索引数据库删除失败的状态 + } + } else { + // 如果是 indexDb_ 调用,则仅提交该数据库的删除操作 + s = this->Write(options, &batch); // 删除操作直接提交给 indexDb_ + if (!s.ok()) { + return s; // 如果操作失败,则返回错误状态 + } } return Status::OK();