trx.cpp 7.2 KB
Newer Older
羽飞's avatar
羽飞 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */

//
// Created by Wangyunlai on 2021/5/24.
//

#include <atomic>

#include "storage/trx/trx.h"
#include "storage/common/table.h"
羽飞's avatar
羽飞 已提交
19
#include "storage/record/record_manager.h"
羽飞's avatar
羽飞 已提交
20 21 22 23 24 25
#include "storage/common/field_meta.h"
#include "common/log/log.h"

static const uint32_t DELETED_FLAG_BIT_MASK = 0x80000000;
static const uint32_t TRX_ID_BIT_MASK = 0x7FFFFFFF;

26 27
int32_t Trx::default_trx_id()
{
羽飞's avatar
羽飞 已提交
28 29 30
  return 0;
}

31 32
int32_t Trx::next_trx_id()
{
羽飞's avatar
羽飞 已提交
33 34 35 36
  static std::atomic<int32_t> trx_id;
  return ++trx_id;
}

37 38
const char *Trx::trx_field_name()
{
羽飞's avatar
羽飞 已提交
39 40 41
  return "__trx";
}

42 43
AttrType Trx::trx_field_type()
{
羽飞's avatar
羽飞 已提交
44 45 46
  return INTS;
}

47 48
int Trx::trx_field_len()
{
羽飞's avatar
羽飞 已提交
49 50 51
  return sizeof(int32_t);
}

52 53
Trx::Trx()
{}
羽飞's avatar
羽飞 已提交
54

55 56
Trx::~Trx()
{}
羽飞's avatar
羽飞 已提交
57

58 59
RC Trx::insert_record(Table *table, Record *record)
{
羽飞's avatar
羽飞 已提交
60
  RC rc = RC::SUCCESS;
61
  // 先校验是否以前是否存在过(应该不会存在)
羽飞's avatar
羽飞 已提交
62
  Operation *old_oper = find_operation(table, record->rid());
羽飞's avatar
羽飞 已提交
63
  if (old_oper != nullptr) {
64
    return RC::GENERIC_ERROR;  // error code
羽飞's avatar
羽飞 已提交
65 66 67 68 69 70 71
  }

  start_if_not_started();

  // 设置record中trx_field为当前的事务号
  // set_record_trx_id(table, record, trx_id_, false);
  // 记录到operations中
羽飞's avatar
羽飞 已提交
72
  insert_operation(table, Operation::Type::INSERT, record->rid());
羽飞's avatar
羽飞 已提交
73 74 75
  return rc;
}

76 77
RC Trx::delete_record(Table *table, Record *record)
{
羽飞's avatar
羽飞 已提交
78 79
  RC rc = RC::SUCCESS;
  start_if_not_started();
羽飞's avatar
羽飞 已提交
80
  Operation *old_oper = find_operation(table, record->rid());
羽飞's avatar
羽飞 已提交
81 82
  if (old_oper != nullptr) {
    if (old_oper->type() == Operation::Type::INSERT) {
羽飞's avatar
羽飞 已提交
83
      delete_operation(table, record->rid());
羽飞's avatar
羽飞 已提交
84 85 86 87 88 89
      return RC::SUCCESS;
    } else {
      return RC::GENERIC_ERROR;
    }
  }
  set_record_trx_id(table, *record, trx_id_, true);
羽飞's avatar
羽飞 已提交
90
  insert_operation(table, Operation::Type::DELETE, record->rid());
羽飞's avatar
羽飞 已提交
91 92 93
  return rc;
}

94 95
void Trx::set_record_trx_id(Table *table, Record &record, int32_t trx_id, bool deleted) const
{
羽飞's avatar
羽飞 已提交
96
  const FieldMeta *trx_field = table->table_meta().trx_field();
羽飞's avatar
羽飞 已提交
97
  int32_t *ptrx_id = (int32_t *)(record.data() + trx_field->offset());
羽飞's avatar
羽飞 已提交
98 99 100 101 102 103
  if (deleted) {
    trx_id |= DELETED_FLAG_BIT_MASK;
  }
  *ptrx_id = trx_id;
}

104 105
void Trx::get_record_trx_id(Table *table, const Record &record, int32_t &trx_id, bool &deleted)
{
羽飞's avatar
羽飞 已提交
106
  const FieldMeta *trx_field = table->table_meta().trx_field();
羽飞's avatar
羽飞 已提交
107
  int32_t trx = *(int32_t *)(record.data() + trx_field->offset());
羽飞's avatar
羽飞 已提交
108 109 110 111
  trx_id = trx & TRX_ID_BIT_MASK;
  deleted = (trx & DELETED_FLAG_BIT_MASK) != 0;
}

112 113
Operation *Trx::find_operation(Table *table, const RID &rid)
{
羽飞's avatar
羽飞 已提交
114 115 116 117 118
  std::unordered_map<Table *, OperationSet>::iterator table_operations_iter = operations_.find(table);
  if (table_operations_iter == operations_.end()) {
    return nullptr;
  }

119
  OperationSet &table_operations = table_operations_iter->second;
羽飞's avatar
羽飞 已提交
120 121 122 123 124 125 126 127
  Operation tmp(Operation::Type::UNDEFINED, rid);
  OperationSet::iterator operation_iter = table_operations.find(tmp);
  if (operation_iter == table_operations.end()) {
    return nullptr;
  }
  return const_cast<Operation *>(&(*operation_iter));
}

128 129 130
void Trx::insert_operation(Table *table, Operation::Type type, const RID &rid)
{
  OperationSet &table_operations = operations_[table];
羽飞's avatar
羽飞 已提交
131 132 133
  table_operations.emplace(type, rid);
}

134 135
void Trx::delete_operation(Table *table, const RID &rid)
{
羽飞's avatar
羽飞 已提交
136 137 138

  std::unordered_map<Table *, OperationSet>::iterator table_operations_iter = operations_.find(table);
  if (table_operations_iter == operations_.end()) {
139
    return;
羽飞's avatar
羽飞 已提交
140 141 142 143 144 145
  }

  Operation tmp(Operation::Type::UNDEFINED, rid);
  table_operations_iter->second.erase(tmp);
}

146 147
RC Trx::commit()
{
羽飞's avatar
羽飞 已提交
148
  RC rc = RC::SUCCESS;
149
  for (const auto &table_operations : operations_) {
羽飞's avatar
羽飞 已提交
150 151
    Table *table = table_operations.first;
    const OperationSet &operation_set = table_operations.second;
152
    for (const Operation &operation : operation_set) {
羽飞's avatar
羽飞 已提交
153 154 155 156 157 158 159 160 161 162

      RID rid;
      rid.page_num = operation.page_num();
      rid.slot_num = operation.slot_num();

      switch (operation.type()) {
        case Operation::Type::INSERT: {
          rc = table->commit_insert(this, rid);
          if (rc != RC::SUCCESS) {
            // handle rc
163 164
            LOG_ERROR(
                "Failed to commit insert operation. rid=%d.%d, rc=%d:%s", rid.page_num, rid.slot_num, rc, strrc(rc));
羽飞's avatar
羽飞 已提交
165
          }
166
        } break;
羽飞's avatar
羽飞 已提交
167 168 169 170
        case Operation::Type::DELETE: {
          rc = table->commit_delete(this, rid);
          if (rc != RC::SUCCESS) {
            // handle rc
171 172
            LOG_ERROR(
                "Failed to commit delete operation. rid=%d.%d, rc=%d:%s", rid.page_num, rid.slot_num, rc, strrc(rc));
羽飞's avatar
羽飞 已提交
173
          }
174
        } break;
羽飞's avatar
羽飞 已提交
175 176
        default: {
          LOG_PANIC("Unknown operation. type=%d", (int)operation.type());
177
        } break;
羽飞's avatar
羽飞 已提交
178 179 180 181 182 183 184 185 186
      }
    }
  }

  operations_.clear();
  trx_id_ = 0;
  return rc;
}

187 188
RC Trx::rollback()
{
羽飞's avatar
羽飞 已提交
189
  RC rc = RC::SUCCESS;
190
  for (const auto &table_operations : operations_) {
羽飞's avatar
羽飞 已提交
191 192
    Table *table = table_operations.first;
    const OperationSet &operation_set = table_operations.second;
193
    for (const Operation &operation : operation_set) {
羽飞's avatar
羽飞 已提交
194 195 196 197 198 199 200 201 202 203

      RID rid;
      rid.page_num = operation.page_num();
      rid.slot_num = operation.slot_num();

      switch (operation.type()) {
        case Operation::Type::INSERT: {
          rc = table->rollback_insert(this, rid);
          if (rc != RC::SUCCESS) {
            // handle rc
204 205
            LOG_ERROR(
                "Failed to rollback insert operation. rid=%d.%d, rc=%d:%s", rid.page_num, rid.slot_num, rc, strrc(rc));
羽飞's avatar
羽飞 已提交
206
          }
207
        } break;
羽飞's avatar
羽飞 已提交
208 209 210 211
        case Operation::Type::DELETE: {
          rc = table->rollback_delete(this, rid);
          if (rc != RC::SUCCESS) {
            // handle rc
212 213
            LOG_ERROR(
                "Failed to rollback delete operation. rid=%d.%d, rc=%d:%s", rid.page_num, rid.slot_num, rc, strrc(rc));
羽飞's avatar
羽飞 已提交
214
          }
215
        } break;
羽飞's avatar
羽飞 已提交
216 217
        default: {
          LOG_PANIC("Unknown operation. type=%d", (int)operation.type());
218
        } break;
羽飞's avatar
羽飞 已提交
219 220 221 222 223 224 225 226 227
      }
    }
  }

  operations_.clear();
  trx_id_ = 0;
  return rc;
}

228 229
RC Trx::commit_insert(Table *table, Record &record)
{
羽飞's avatar
羽飞 已提交
230 231 232 233
  set_record_trx_id(table, record, 0, false);
  return RC::SUCCESS;
}

234 235
RC Trx::rollback_delete(Table *table, Record &record)
{
羽飞's avatar
羽飞 已提交
236 237 238 239
  set_record_trx_id(table, record, 0, false);
  return RC::SUCCESS;
}

240 241
bool Trx::is_visible(Table *table, const Record *record)
{
羽飞's avatar
羽飞 已提交
242 243 244 245 246 247 248 249 250
  int32_t record_trx_id;
  bool record_deleted;
  get_record_trx_id(table, *record, record_trx_id, record_deleted);

  // 0 表示这条数据已经提交
  if (0 == record_trx_id || record_trx_id == trx_id_) {
    return !record_deleted;
  }

251
  return record_deleted;  // 当前记录上面有事务号,说明是未提交数据,那么如果有删除标记的话,就表示是未提交的删除
羽飞's avatar
羽飞 已提交
252 253
}

254 255
void Trx::init_trx_info(Table *table, Record &record)
{
羽飞's avatar
羽飞 已提交
256 257 258
  set_record_trx_id(table, record, trx_id_, false);
}

259 260
void Trx::start_if_not_started()
{
羽飞's avatar
羽飞 已提交
261 262 263
  if (trx_id_ == 0) {
    trx_id_ = next_trx_id();
  }
羽飞's avatar
羽飞 已提交
264
}