Example #1
0
/**
 * @brief read tuple record from log file and add them tuples to recovery txn
 * @param recovery txn
 */
void AriesFrontendLogger::DeleteTuple(concurrency::Transaction *recovery_txn) {
  TupleRecord tuple_record(LOGRECORD_TYPE_ARIES_TUPLE_DELETE);

  // Check for torn log write
  if (ReadTupleRecordHeader(tuple_record, log_file, log_file_size) == false) {
    return;
  }

  auto txn_id = tuple_record.GetTransactionId();
  if (recovery_txn_table.find(txn_id) == recovery_txn_table.end()) {
    LOG_TRACE("Delete txd id %d not found in recovery txn table", (int)txn_id);
    return;
  }

  auto table = GetTable(tuple_record);

  ItemPointer delete_location = tuple_record.GetDeleteLocation();

  // Try to delete the tuple
  bool status = table->DeleteTuple(recovery_txn, delete_location);
  if (status == false) {
    // TODO: We need to abort on failure !
    recovery_txn->SetResult(Result::RESULT_FAILURE);
    return;
  }

  auto txn = recovery_txn_table.at(txn_id);
  txn->RecordDelete(delete_location);
}
Example #2
0
void SimpleCheckpoint::InsertTuple(cid_t commit_id) {
  TupleRecord tuple_record(LOGRECORD_TYPE_WAL_TUPLE_INSERT);

  // Check for torn log write
  if (LoggingUtil::ReadTupleRecordHeader(tuple_record, file_handle_) == false) {
    LOG_ERROR("Could not read tuple record header.");
    return;
  }

  auto table = LoggingUtil::GetTable(tuple_record);
  if (!table) {
    // the table was deleted
    LoggingUtil::SkipTupleRecordBody(file_handle_);
    return;
  }

  // Read off the tuple record body from the log
  std::unique_ptr<storage::Tuple> tuple(LoggingUtil::ReadTupleRecordBody(
      table->GetSchema(), pool.get(), file_handle_));
  // Check for torn log write
  if (tuple == nullptr) {
    LOG_ERROR("Torn checkpoint write.");
    return;
  }
  auto target_location = tuple_record.GetInsertLocation();
  auto tile_group_id = target_location.block;
  RecoverTuple(tuple.get(), table, target_location, commit_id);
  if (max_oid_ < target_location.block) {
    max_oid_ = tile_group_id;
  }
  LOG_TRACE("Inserted a tuple from checkpoint: (%u, %u)",
            target_location.block, target_location.offset);
}
Example #3
0
/**
 * @brief read tuple record from log file and add them tuples to recovery txn
 * @param recovery txn
 */
void AriesFrontendLogger::InsertTuple(concurrency::Transaction *recovery_txn) {
  TupleRecord tuple_record(LOGRECORD_TYPE_ARIES_TUPLE_INSERT);

  // Check for torn log write
  if (ReadTupleRecordHeader(tuple_record, log_file, log_file_size) == false) {
    LOG_ERROR("Could not read tuple record header.");
    return;
  }

  auto txn_id = tuple_record.GetTransactionId();
  if (recovery_txn_table.find(txn_id) == recovery_txn_table.end()) {
    LOG_ERROR("Insert txd id %d not found in recovery txn table", (int)txn_id);
    return;
  }

  auto table = GetTable(tuple_record);

  // Read off the tuple record body from the log
  auto tuple = ReadTupleRecordBody(table->GetSchema(), recovery_pool, log_file,
                                   log_file_size);

  // Check for torn log write
  if (tuple == nullptr) {
    return;
  }

  auto target_location = tuple_record.GetInsertLocation();
  auto tile_group_id = target_location.block;
  auto tuple_slot = target_location.offset;

  auto &manager = catalog::Manager::GetInstance();
  auto tile_group = manager.GetTileGroup(tile_group_id);

  auto txn = recovery_txn_table.at(txn_id);

  // Create new tile group if table doesn't already have that tile group
  if (tile_group == nullptr) {
    table->AddTileGroupWithOid(tile_group_id);
    tile_group = manager.GetTileGroup(tile_group_id);
    if (max_oid < tile_group_id) {
      max_oid = tile_group_id;
    }
  }

  // Do the insert !
  auto inserted_tuple_slot = tile_group->InsertTuple(
      recovery_txn->GetTransactionId(), tuple_slot, tuple);

  if (inserted_tuple_slot == INVALID_OID) {
    // TODO: We need to abort on failure !
    recovery_txn->SetResult(Result::RESULT_FAILURE);
  } else {
    txn->RecordInsert(target_location);
    table->IncreaseNumberOfTuplesBy(1);
  }

  delete tuple;
}
Example #4
0
/**
 * @brief read tuple record from log file and add them tuples to recovery txn
 * @param recovery txn
 */
void AriesFrontendLogger::UpdateTuple(concurrency::Transaction *recovery_txn) {
  TupleRecord tuple_record(LOGRECORD_TYPE_ARIES_TUPLE_UPDATE);

  // Check for torn log write
  if (ReadTupleRecordHeader(tuple_record, log_file, log_file_size) == false) {
    return;
  }

  auto txn_id = tuple_record.GetTransactionId();
  if (recovery_txn_table.find(txn_id) == recovery_txn_table.end()) {
    LOG_TRACE("Update txd id %d not found in recovery txn table", (int)txn_id);
    return;
  }

  auto txn = recovery_txn_table.at(txn_id);

  auto table = GetTable(tuple_record);

  auto tuple = ReadTupleRecordBody(table->GetSchema(), recovery_pool, log_file,
                                   log_file_size);

  // Check for torn log write
  if (tuple == nullptr) {
    return;
  }

  // First, redo the delete
  ItemPointer delete_location = tuple_record.GetDeleteLocation();

  bool status = table->DeleteTuple(recovery_txn, delete_location);
  if (status == false) {
    recovery_txn->SetResult(Result::RESULT_FAILURE);
  } else {
    txn->RecordDelete(delete_location);

    auto target_location = tuple_record.GetInsertLocation();
    auto tile_group_id = target_location.block;
    auto tuple_slot = target_location.offset;
    auto &manager = catalog::Manager::GetInstance();
    auto tile_group = manager.GetTileGroup(tile_group_id);

    // Create new tile group if table doesn't already have that tile group
    if (tile_group == nullptr) {
      table->AddTileGroupWithOid(tile_group_id);
      tile_group = manager.GetTileGroup(tile_group_id);
      if (max_oid < tile_group_id) {
        max_oid = tile_group_id;
      }
    }

    // Do the insert !
    auto inserted_tuple_slot = tile_group->InsertTuple(
        recovery_txn->GetTransactionId(), tuple_slot, tuple);
    if (inserted_tuple_slot == INVALID_OID) {
      recovery_txn->SetResult(Result::RESULT_FAILURE);
    } else {
      txn->RecordInsert(target_location);
    }
  }

  delete tuple;
}
void BackendLoggingThread::ExecuteNext() {
  // Prepare data for operation
  logging_op_type op = schedule->operations[cur_seq].op;
  cid_t cid = schedule->operations[cur_seq].cid;

  cur_seq++;

  // Execute the operation
  switch (op) {
    case LOGGING_OP_PREPARE: {
      LOG_INFO("Execute Prepare");
      log_manager->PrepareLogging();
      break;
    }
    case LOGGING_OP_BEGIN: {
      LOG_INFO("Execute Begin txn %d", (int)cid);
      log_manager->LogBeginTransaction(cid);
      break;
    }
    case LOGGING_OP_INSERT: {
      LOG_INFO("Execute Insert txn %d", (int)cid);
      auto tuple = LoggingTestsUtil::BuildTuples(table, 1, false, false)[0];
      std::unique_ptr<logging::LogRecord> tuple_record(
          backend_logger->GetTupleRecord(LOGRECORD_TYPE_TUPLE_INSERT, cid, 1,
                                         DEFAULT_DB_ID, INVALID_ITEMPOINTER,
                                         INVALID_ITEMPOINTER, tuple.get()));
      backend_logger->Log(tuple_record.get());
      tuple.reset();
      break;
    }
    case LOGGING_OP_UPDATE: {
      LOG_INFO("Execute Update txn %d", (int)cid);
      auto tuple = LoggingTestsUtil::BuildTuples(table, 1, false, false)[0];
      std::unique_ptr<logging::LogRecord> tuple_record(
          backend_logger->GetTupleRecord(LOGRECORD_TYPE_TUPLE_UPDATE, cid, 1,
                                         DEFAULT_DB_ID, INVALID_ITEMPOINTER,
                                         INVALID_ITEMPOINTER, tuple.get()));
      backend_logger->Log(tuple_record.get());
      tuple.reset();
      break;
    }
    case LOGGING_OP_DELETE: {
      LOG_INFO("Execute Delete txn %d", (int)cid);
      auto tuple = LoggingTestsUtil::BuildTuples(table, 1, false, false)[0];
      std::unique_ptr<logging::LogRecord> tuple_record(
          backend_logger->GetTupleRecord(LOGRECORD_TYPE_TUPLE_DELETE, cid, 1,
                                         DEFAULT_DB_ID, INVALID_ITEMPOINTER,
                                         INVALID_ITEMPOINTER, tuple.get()));
      backend_logger->Log(tuple_record.get());
      tuple.reset();
      break;
    }
    case LOGGING_OP_DONE: {
      LOG_INFO("Execute Done txn %d", (int)cid);
      log_manager->DoneLogging();
      break;
    }
    case LOGGING_OP_COMMIT: {
      LOG_INFO("Execute Commit txn %d", (int)cid);
      std::unique_ptr<logging::LogRecord> record(new logging::TransactionRecord(
          LOGRECORD_TYPE_TRANSACTION_COMMIT, cid));
      PL_ASSERT(backend_logger);
      backend_logger->Log(record.get());
      break;
    }
    case LOGGING_OP_ABORT: {
      LOG_INFO("Execute Abort txn %d", (int)cid);
      std::unique_ptr<logging::LogRecord> record(new logging::TransactionRecord(
          LOGRECORD_TYPE_TRANSACTION_ABORT, cid));
      PL_ASSERT(backend_logger);
      backend_logger->Log(record.get());
      break;
    }
    default: {
      LOG_ERROR("Unsupported operation type!");
      break;
    }
  }
}