/** * @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); }
/** * @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; }
/** * @brief Delete the table tuples using the position list in the logical tile. * * If truncate is on, then it will truncate the table itself. * @return true on success, false otherwise. */ bool DeleteExecutor::DExecute() { assert(target_table_); // Retrieve next tile. const bool success = children_[0]->Execute(); if (!success) { return false; } std::unique_ptr<LogicalTile> source_tile(children_[0]->GetOutput()); storage::Tile *tile = source_tile->GetBaseTile(0); storage::TileGroup *tile_group = tile->GetTileGroup(); auto &pos_lists = source_tile.get()->GetPositionLists(); auto tile_group_id = tile_group->GetTileGroupId(); auto transaction_ = executor_context_->GetTransaction(); LOG_INFO("Source tile : %p Tuples : %lu \n", source_tile.get(), source_tile->GetTupleCount()); LOG_INFO("Transaction ID: %lu\n", transaction_->GetTransactionId()); // Delete each tuple for (oid_t visible_tuple_id : *source_tile) { oid_t physical_tuple_id = pos_lists[0][visible_tuple_id]; LOG_INFO("Visible Tuple id : %lu, Physical Tuple id : %lu \n", visible_tuple_id, physical_tuple_id); peloton::ItemPointer delete_location(tile_group_id, physical_tuple_id); // Logging { auto &log_manager = logging::LogManager::GetInstance(); if (log_manager.IsInLoggingMode()) { auto logger = log_manager.GetBackendLogger(); auto record = logger->GetTupleRecord( LOGRECORD_TYPE_TUPLE_DELETE, transaction_->GetTransactionId(), target_table_->GetOid(), INVALID_ITEMPOINTER, delete_location); logger->Log(record); } } // try to delete the tuple // this might fail due to a concurrent operation that has latched the tuple bool status = target_table_->DeleteTuple(transaction_, delete_location); if (status == false) { LOG_INFO("Fail to delete. Set txn failure"); transaction_->SetResult(peloton::Result::RESULT_FAILURE); return false; } executor_context_->num_processed += 1; // deleted one transaction_->RecordDelete(delete_location); } return true; }