Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix issue #25, 在mvcc场景下,多事务执行删除会出错 #27

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/server/include/storage_engine/recorder/record_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "include/storage_engine/buffer/buffer_pool.h"
#include "include/storage_engine/recorder/record.h"
#include "include/storage_engine/recorder/condition_filter.h"
#include "include/query_engine/structor/expression/expression.h"
#include "common/lang/bitmap.h"

class ConditionFilter;
Expand Down Expand Up @@ -323,6 +324,7 @@ class RecordFileScanner
* @param condition_filter 做一些初步过滤操作
*/
RC open_scan(Table *table, FileBufferPool &buffer_pool, Trx *trx, bool readonly, ConditionFilter *condition_filter);
RC open_scan(Table *table, FileBufferPool &buffer_pool, Trx *trx, bool readonly, std::vector<std::unique_ptr<Expression>> predicate_exprs);

/**
* @brief 关闭一个文件扫描,释放相应的资源
Expand Down Expand Up @@ -367,4 +369,6 @@ class RecordFileScanner
RecordPageHandler record_page_handler_; // 处理文件某页面的记录
RecordPageIterator record_page_iterator_; // 遍历某个页面上的所有record
Record next_record_; // 获取的记录放在这里缓存起来
std::vector<std::unique_ptr<Expression>> predicates_; // 过滤的谓词

};
2 changes: 2 additions & 0 deletions src/server/include/storage_engine/recorder/table.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ class Table

RC get_record_scanner(RecordFileScanner &scanner, Trx *trx, bool readonly);

RC get_record_scanner(RecordFileScanner &scanner, Trx *trx, bool readonly, std::vector<std::unique_ptr<Expression>> predicate_exprs);

RecordFileHandler *record_handler() const
{
return record_handler_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ using namespace std;

RC TableScanPhysicalOperator::open(Trx *trx)
{
RC rc = table_->get_record_scanner(record_scanner_, trx, readonly_);
// 将predicates_传下去,让record_scanner_做过滤
RC rc = table_->get_record_scanner(record_scanner_, trx, readonly_,std::move(predicates_));
if (rc == RC::SUCCESS) {
tuple_.set_schema(table_, table_alias_, table_->table_meta().field_metas());
}
Expand Down
103 changes: 103 additions & 0 deletions src/server/storage_engine/recorder/record_manager.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include "include/storage_engine/recorder/record_manager.h"
#include "include/storage_engine/recorder/table.h"
#include "include/storage_engine/transaction/trx.h"
#include "include/query_engine/structor/expression/comparison_expression.h"
#include "include/query_engine/structor/expression/field_expression.h"
#include "include/query_engine/structor/expression/value_expression.h"


using namespace common;
Expand Down Expand Up @@ -473,6 +476,31 @@ RC RecordFileScanner::open_scan(
return rc;
}

RC RecordFileScanner::open_scan(
Table *table, FileBufferPool &buffer_pool, Trx *trx, bool readonly,
std::vector<std::unique_ptr<Expression>> predicate_exprs) {
close_scan();

table_ = table;
file_buffer_pool_ = &buffer_pool;
trx_ = trx;
readonly_ = readonly;

RC rc = bp_iterator_.init(buffer_pool);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to init bp iterator. rc=%d:%s", rc, strrc(rc));
return rc;
}

predicates_ = std::move(predicate_exprs);

rc = fetch_next_record();
if (rc == RC::RECORD_EOF) {
rc = RC::SUCCESS;
}
return rc;
}

/**
* @brief 从当前位置开始找到下一条有效的记录
*
Expand Down Expand Up @@ -538,6 +566,81 @@ RC RecordFileScanner::fetch_next_record_in_page()
continue;
}

bool pass = false;
if (!predicates_.empty()) {
ValueExpr *value_expression = nullptr;
for (auto &predicate : predicates_) {
if (predicate->type() == ExprType::COMPARISON) {
/**
* 例如 where id = 1
*/
auto comp_expr = dynamic_cast<ComparisonExpr *>(predicate.get());

Expression *left_expr = comp_expr->left().get(); // 即id
Expression *right_expr = comp_expr->right().get(); // 即1

Value right_value; // 1
rc = right_expr->try_get_value(right_value);
bool left_value_is_field = true; // 默认左边是字段
// 有可能是 1 = id 的情况
if (rc != RC::SUCCESS) {
left_value_is_field = false;
}

// 获取左边的字段
std::vector<Field *> query_fields;
if (left_value_is_field)
left_expr->getFields(query_fields);
else
right_expr->getFields(query_fields);

for (auto field : query_fields) {
const char *record = field->get_data(next_record_);
char *recordNonConst = const_cast<char *>(record);

Value left_value;
// id=1的情况
if (left_value_is_field) {
// 获取左边的值
left_value =
Value(field->attr_type(), recordNonConst, field->len());
}
// 1=id的情况
else {
left_expr->try_get_value(left_value);
right_value =
Value(field->attr_type(), recordNonConst, field->len());
}

// 比较左右两边的值
bool compare_result = false;
rc = comp_expr->compare_value(left_value, right_value,
compare_result);

if (rc != RC::SUCCESS) {
LOG_WARN("failed to compare value. rc=%s", strrc(rc));
return rc;
}

// 不相等则过滤掉
if (!compare_result) {
pass = true;
break;
}
}

if (pass) {
break;
}
}
}
}

// 不满足过滤条件,就继续找下一条记录,不需要进行事务探测
if (pass) {
continue;
}

// 如果是某个事务上遍历数据,还要看看事务访问是否有冲突
if (trx_ == nullptr) {
return rc;
Expand Down
14 changes: 14 additions & 0 deletions src/server/storage_engine/recorder/table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include "include/storage_engine/recorder/record_manager.h"
#include "include/storage_engine/schema/schema_util.h"
#include "include/storage_engine/index/bplus_tree_index.h"
#include "include/storage_engine/transaction/mvcc_trx.h"
#include "include/storage_engine/transaction/trx.h"
#include <random>


Expand Down Expand Up @@ -490,6 +492,18 @@ RC Table::get_record_scanner(RecordFileScanner &scanner, Trx *trx, bool readonly
return rc;
}

RC Table::get_record_scanner(
RecordFileScanner &scanner, Trx *trx, bool readonly,
std::vector<std::unique_ptr<Expression>> predicate_exprs) {

RC rc = scanner.open_scan(this, *data_buffer_pool_, trx, readonly,
std::move(predicate_exprs));
if (rc != RC::SUCCESS) {
LOG_WARN("failed to open scanner. rc=%s", strrc(rc));
}
return rc;
}


Index *Table::find_index(const char *index_name) const
{
Expand Down