src/backend/concurrency/ssi_txn_manager.cpp
// Clean obsolete txn record
// Current implementation might be very expensive, consider using dependency
// count
Clean obsolete txn record
Current implementation might be very expensive, consider using dependency
count
Clean obsolete txn record Current implementation might be very expensive consider using dependency count
void SsiTxnManager::CleanUp() {
  std::lock_guard<std::mutex> lock(clean_mutex_);
  std::unordered_set<SsiTxnContext *> garbage_ctx;
  {
    txn_manager_mutex_.ReadLock();
    cid_t min_begin = std::numeric_limits<cid_t>::max();
    for (auto &item : txn_table_) {
      auto &ctx = item.second;
      if (ctx->transaction_->GetEndCommitId() == INVALID_TXN_ID) {
        min_begin = ctx->transaction_->GetBeginCommitId();
        break;
      }
    }
    for (auto itr = txn_table_.begin(); itr != txn_table_.end(); itr++) {
      auto &ctx = itr->second;
      auto end_cid = ctx->transaction_->GetEndCommitId();
      if (end_cid == INVALID_TXN_ID) {
        break;
      }
      if (end_cid < min_begin && ctx->is_finish_) {
        LOG_INFO("remove %ld in table", ctx->transaction_->GetTransactionId());
        garbage_ctx.insert(ctx);
      }
    }
    txn_manager_mutex_.Unlock();
  }
  {
    txn_manager_mutex_.WriteLock();
    for (auto ctx : garbage_ctx) {
      txn_table_.erase(ctx->transaction_->GetTransactionId());
    }
    txn_manager_mutex_.Unlock();
  }
  for (auto ctx : garbage_ctx) {
    RemoveReader(ctx->transaction_);
    delete ctx->transaction_;
    delete ctx;
  }
}
void SsiTxnManager :: CleanUp ( ) { std :: lock_guard < std :: mutex > lock ( clean_mutex_ ) ; std :: unordered_set < SsiTxnContext * > garbage_ctx ; { txn_manager_mutex_ . ReadLock ( ) ; cid_t min_begin = std :: numeric_limits < cid_t > :: max ( ) ; for ( auto & item : txn_table_ ) { auto & ctx = item . second ; if ( ctx -> transaction_ -> GetEndCommitId ( ) == INVALID_TXN_ID ) { min_begin = ctx -> transaction_ -> GetBeginCommitId ( ) ; break ; } } for ( auto itr = txn_table_ . begin ( ) ; itr != txn_table_ . end ( ) ; itr ++ ) { auto & ctx = itr -> second ; auto end_cid = ctx -> transaction_ -> GetEndCommitId ( ) ; if ( end_cid == INVALID_TXN_ID ) { break ; } if ( end_cid < min_begin && ctx -> is_finish_ ) { LOG_INFO ( " " , ctx -> transaction_ -> GetTransactionId ( ) ) ; garbage_ctx . insert ( ctx ) ; } } txn_manager_mutex_ . Unlock ( ) ; } { txn_manager_mutex_ . WriteLock ( ) ; for ( auto ctx : garbage_ctx ) { txn_table_ . erase ( ctx -> transaction_ -> GetTransactionId ( ) ) ; } txn_manager_mutex_ . Unlock ( ) ; } for ( auto ctx : garbage_ctx ) { RemoveReader ( ctx -> transaction_ ) ; delete ctx -> transaction_ ; delete ctx ; } }
Clean obsolete txn record
Current implementation might be very expensive, consider using dependency
count
Clean obsolete txn record Current implementation might be very expensive consider using dependency count
// init it as max() for the case that all transactions are committed // find smallest begin cid of the running transaction // txn_id_a > txn_id_b --> begin_cid_a > begin_cid_b // so the first running transaction's begin_cid must be the smallest // see BeginTransaction() // remove committed transactions, whose end_cid < min_begin // running transaction // then we know that the subsequent txn's end_cid > min_begin // so just break // record garbage // we can safely remove it from table // remove garbage from table // remove txn's reader list firstly