Skip to content
This repository has been archived by the owner on Sep 27, 2019. It is now read-only.

Read-Only TxnContext Interface; Read-Only (single-statement select, txn) optimizations #1402

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 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
38 changes: 23 additions & 15 deletions src/concurrency/timestamp_ordering_transaction_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,9 @@ void TimestampOrderingTransactionManager::YieldOwnership(
tile_group_header->SetTransactionId(tuple_id, INITIAL_TXN_ID);
}

bool TimestampOrderingTransactionManager::PerformRead(TransactionContext *const current_txn,
const ItemPointer &read_location,
storage::TileGroupHeader *tile_group_header,
bool acquire_ownership) {
bool TimestampOrderingTransactionManager::PerformRead(
TransactionContext *const current_txn, const ItemPointer &read_location,
storage::TileGroupHeader *tile_group_header, bool acquire_ownership) {
ItemPointer location = read_location;

//////////////////////////////////////////////////////////
Expand Down Expand Up @@ -374,7 +373,8 @@ void TimestampOrderingTransactionManager::PerformInsert(
oid_t tuple_id = location.offset;

auto storage_manager = storage::StorageManager::GetInstance();
auto tile_group_header = storage_manager->GetTileGroup(tile_group_id)->GetHeader();
auto tile_group_header =
storage_manager->GetTileGroup(tile_group_id)->GetHeader();
auto transaction_id = current_txn->GetTransactionId();

// check MVCC info
Expand Down Expand Up @@ -420,9 +420,8 @@ void TimestampOrderingTransactionManager::PerformUpdate(
// version.
PELOTON_ASSERT(tile_group_header->GetTransactionId(old_location.offset) ==
transaction_id);
PELOTON_ASSERT(
tile_group_header->GetPrevItemPointer(old_location.offset).IsNull() ==
true);
PELOTON_ASSERT(tile_group_header->GetPrevItemPointer(old_location.offset)
.IsNull() == true);

// check whether the new version is empty.
PELOTON_ASSERT(new_tile_group_header->GetTransactionId(new_location.offset) ==
Expand Down Expand Up @@ -529,9 +528,8 @@ void TimestampOrderingTransactionManager::PerformDelete(
PELOTON_ASSERT(tile_group_header->GetTransactionId(old_location.offset) ==
transaction_id);
// we must be deleting the latest version.
PELOTON_ASSERT(
tile_group_header->GetPrevItemPointer(old_location.offset).IsNull() ==
true);
PELOTON_ASSERT(tile_group_header->GetPrevItemPointer(old_location.offset)
.IsNull() == true);

// check whether the new version is empty.
PELOTON_ASSERT(new_tile_group_header->GetTransactionId(new_location.offset) ==
Expand Down Expand Up @@ -588,7 +586,8 @@ void TimestampOrderingTransactionManager::PerformDelete(
oid_t tuple_id = location.offset;

auto storage_manager = storage::StorageManager::GetInstance();
auto tile_group_header = storage_manager->GetTileGroup(tile_group_id)->GetHeader();
auto tile_group_header =
storage_manager->GetTileGroup(tile_group_id)->GetHeader();

PELOTON_ASSERT(tile_group_header->GetTransactionId(tuple_id) ==
current_txn->GetTransactionId());
Expand Down Expand Up @@ -624,6 +623,14 @@ ResultType TimestampOrderingTransactionManager::CommitTransaction(
//// handle other isolation levels
//////////////////////////////////////////////////////////

auto &rw_set = current_txn->GetReadWriteSet();

// if no modifying queries, treat as read-only
if (rw_set.empty()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the implementation of the is_written_ flag in #1401 could we also check the is_written_ flag here? That would tell us if the RWSet is just reads.

Copy link
Contributor Author

@lmwnshn lmwnshn Jun 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mbutrovich I've tried changing it to use is_written_ instead of empty(), but I keep breaking on multi_granularity_access_test. Did you and/or @pervazea say something about SCAN being broken earlier?

In particular, I added an IsWritten() getter and the check became if (!current_txn->IsWritten()). Haven't been able to find the bug, for now, I'm leaving it as empty().

EndTransaction(current_txn);
Copy link
Member

@apavlo apavlo Jun 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just add a LOG_TRACE statement here to record what is happening.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

return ResultType::SUCCESS;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if the transaction just drops an object, like an index? IsWritten will still return false since that doesn't touch the RWSet yet we'll directly commit the transaction without adding the objects to the gc_object_set. I'm not sure we support drop index yet, but I foresee problems with this.


auto storage_manager = storage::StorageManager::GetInstance();
auto &log_manager = logging::LogManager::GetInstance();

Expand All @@ -632,7 +639,6 @@ ResultType TimestampOrderingTransactionManager::CommitTransaction(
// generate transaction id.
cid_t end_commit_id = current_txn->GetCommitId();

auto &rw_set = current_txn->GetReadWriteSet();
auto &rw_object_set = current_txn->GetCreateDropSet();

auto gc_set = current_txn->GetGCSetPtr();
Expand Down Expand Up @@ -660,7 +666,8 @@ ResultType TimestampOrderingTransactionManager::CommitTransaction(
oid_t tile_group_id = item_ptr.block;
oid_t tuple_slot = item_ptr.offset;

auto tile_group_header = storage_manager->GetTileGroup(tile_group_id)->GetHeader();
auto tile_group_header =
storage_manager->GetTileGroup(tile_group_id)->GetHeader();

if (tuple_entry.second == RWType::READ_OWN) {
// A read operation has acquired ownership but hasn't done any further
Expand Down Expand Up @@ -811,7 +818,8 @@ ResultType TimestampOrderingTransactionManager::AbortTransaction(
ItemPointer item_ptr = tuple_entry.first;
oid_t tile_group_id = item_ptr.block;
oid_t tuple_slot = item_ptr.offset;
auto tile_group_header = storage_manager->GetTileGroup(tile_group_id)->GetHeader();
auto tile_group_header =
storage_manager->GetTileGroup(tile_group_id)->GetHeader();

if (tuple_entry.second == RWType::READ_OWN) {
// A read operation has acquired ownership but hasn't done any further
Expand Down
13 changes: 7 additions & 6 deletions src/concurrency/transaction_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,26 @@ namespace concurrency {
* i : insert
*/

TransactionContext::TransactionContext(const size_t thread_id,
TransactionContext::TransactionContext(bool read_only, const size_t thread_id,
const IsolationLevelType isolation,
const cid_t &read_id) {
Init(thread_id, isolation, read_id);
Init(read_only, thread_id, isolation, read_id);
}

TransactionContext::TransactionContext(const size_t thread_id,
TransactionContext::TransactionContext(bool read_only, const size_t thread_id,
const IsolationLevelType isolation,
const cid_t &read_id,
const cid_t &commit_id) {
Init(thread_id, isolation, read_id, commit_id);
Init(read_only, thread_id, isolation, read_id, commit_id);
}

TransactionContext::~TransactionContext() {}

void TransactionContext::Init(const size_t thread_id,
void TransactionContext::Init(bool read_only, const size_t thread_id,
const IsolationLevelType isolation,
const cid_t &read_id, const cid_t &commit_id) {
read_only_ = read_only;

read_id_ = read_id;

// commit id can be set at a transaction's commit phase.
Expand Down Expand Up @@ -101,7 +103,6 @@ RWType TransactionContext::GetRWType(const ItemPointer &location) {
}

void TransactionContext::RecordRead(const ItemPointer &location) {

auto rw_set_it = rw_set_.find(location);
if (rw_set_it != rw_set_.end()) {
UNUSED_ATTRIBUTE RWType rw_type = rw_set_it->second;
Expand Down
18 changes: 8 additions & 10 deletions src/concurrency/transaction_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ ConflictAvoidanceType TransactionManager::conflict_avoidance_ =
ConflictAvoidanceType::ABORT;

TransactionContext *TransactionManager::BeginTransaction(
const size_t thread_id, const IsolationLevelType type, bool read_only) {
bool read_only, const size_t thread_id, const IsolationLevelType type) {
TransactionContext *txn = nullptr;

if (type == IsolationLevelType::SNAPSHOT) {
Expand All @@ -45,9 +45,10 @@ TransactionContext *TransactionManager::BeginTransaction(
cid_t commit_id = EpochManagerFactory::GetInstance().EnterEpoch(
thread_id, TimestampType::COMMIT);

txn = new TransactionContext(thread_id, type, read_id, commit_id);
txn = new TransactionContext(read_only, thread_id, type, read_id,
commit_id);
} else {
txn = new TransactionContext(thread_id, type, read_id);
txn = new TransactionContext(read_only, thread_id, type, read_id);
}

} else {
Expand All @@ -58,11 +59,7 @@ TransactionContext *TransactionManager::BeginTransaction(
// transaction processing with decentralized epoch manager
cid_t read_id = EpochManagerFactory::GetInstance().EnterEpoch(
thread_id, TimestampType::READ);
txn = new TransactionContext(thread_id, type, read_id);
}

if (read_only) {
txn->SetReadOnly();
txn = new TransactionContext(read_only, thread_id, type, read_id);
}

txn->SetTimestamp(function::DateFunctions::Now());
Expand Down Expand Up @@ -102,8 +99,9 @@ bool TransactionManager::IsOccupied(TransactionContext *const current_txn,
const void *position_ptr) {
ItemPointer &position = *((ItemPointer *)position_ptr);

auto tile_group_header =
storage::StorageManager::GetInstance()->GetTileGroup(position.block)->GetHeader();
auto tile_group_header = storage::StorageManager::GetInstance()
->GetTileGroup(position.block)
->GetHeader();
auto tuple_id = position.offset;

txn_id_t tuple_txn_id = tile_group_header->GetTransactionId(tuple_id);
Expand Down
56 changes: 25 additions & 31 deletions src/include/concurrency/transaction_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,25 +44,27 @@ class TransactionContext : public Printable {
TransactionContext(TransactionContext const &) = delete;

public:
TransactionContext(const size_t thread_id, const IsolationLevelType isolation,
const cid_t &read_id);
TransactionContext(bool read_only, const size_t thread_id,
const IsolationLevelType isolation, const cid_t &read_id);

TransactionContext(const size_t thread_id, const IsolationLevelType isolation,
const cid_t &read_id, const cid_t &commit_id);
TransactionContext(bool read_only, const size_t thread_id,
const IsolationLevelType isolation, const cid_t &read_id,
const cid_t &commit_id);

/**
* @brief Destroys the object.
*/
~TransactionContext();

private:
void Init(const size_t thread_id, const IsolationLevelType isolation,
const cid_t &read_id) {
Init(thread_id, isolation, read_id, read_id);
void Init(bool read_only, const size_t thread_id,
const IsolationLevelType isolation, const cid_t &read_id) {
Init(read_only, thread_id, isolation, read_id, read_id);
}

void Init(const size_t thread_id, const IsolationLevelType isolation,
const cid_t &read_id, const cid_t &commit_id);
void Init(bool read_only, const size_t thread_id,
const IsolationLevelType isolation, const cid_t &read_id,
const cid_t &commit_id);

public:
//===--------------------------------------------------------------------===//
Expand Down Expand Up @@ -116,8 +118,9 @@ class TransactionContext : public Printable {
*
* @return The query strings.
*/
inline const std::vector<std::string>& GetQueryStrings() const {
return query_strings_; }
inline const std::vector<std::string> &GetQueryStrings() const {
return query_strings_;
}

/**
* @brief Sets the commit identifier.
Expand All @@ -132,7 +135,7 @@ class TransactionContext : public Printable {
* @param[in] epoch_id The epoch identifier
*/
inline void SetEpochId(const eid_t epoch_id) { epoch_id_ = epoch_id; }

/**
* @brief Sets the timestamp.
*
Expand All @@ -145,18 +148,18 @@ class TransactionContext : public Printable {
*
* @param[in] query_string The query string
*/
inline void AddQueryString(const char* query_string) {
inline void AddQueryString(const char *query_string) {
query_strings_.push_back(std::string(query_string));
}

void RecordCreate(oid_t database_oid, oid_t table_oid, oid_t index_oid) {
rw_object_set_.push_back(std::make_tuple(database_oid, table_oid,
index_oid, DDLType::CREATE));
rw_object_set_.push_back(
std::make_tuple(database_oid, table_oid, index_oid, DDLType::CREATE));
}

void RecordDrop(oid_t database_oid, oid_t table_oid, oid_t index_oid) {
rw_object_set_.push_back(std::make_tuple(database_oid, table_oid,
index_oid, DDLType::DROP));
rw_object_set_.push_back(
std::make_tuple(database_oid, table_oid, index_oid, DDLType::DROP));
}

void RecordRead(const ItemPointer &);
Expand Down Expand Up @@ -262,17 +265,7 @@ class TransactionContext : public Printable {
*
* @return True if read only, False otherwise.
*/
bool IsReadOnly() const {
return read_only_;
}

/**
* @brief mark this context as read only
*
*/
void SetReadOnly() {
read_only_ = true;
}
bool IsReadOnly() const { return read_only_; }

/**
* @brief Gets the isolation level.
Expand Down Expand Up @@ -328,8 +321,8 @@ class TransactionContext : public Printable {
ReadWriteSet rw_set_;
CreateDropSet rw_object_set_;

/**
* this set contains data location that needs to be gc'd in the transaction.
/**
* this set contains data location that needs to be gc'd in the transaction.
*/
std::shared_ptr<GCSet> gc_set_;
std::shared_ptr<GCObjectSet> gc_object_set_;
Expand All @@ -344,7 +337,8 @@ class TransactionContext : public Printable {

std::unique_ptr<trigger::TriggerSet> on_commit_triggers_;

/** one default transaction is NOT 'read only' unless it is marked 'read only' explicitly*/
/** one default transaction is NOT 'read only' unless it is marked 'read only'
* explicitly*/
bool read_only_ = false;
};

Expand Down
Loading