Exemple #1
0
/*
 * Run the redo phase of ARIES.
 * If the StorageEngine stops responding, return false.
 * Else when redo phase is complete, return true. 
 */
bool LogMgr::redo(vector <LogRecord*> log)
{
  TxType tType;
  int lsn, pageID, offset, nextLsn;
  string afterImage;

  for(auto it = log.begin(); it != log.end(); it++)
    {
      LogRecord *logPointer = *it;
      tType = logPointer->getType();
      lsn = logPointer->getLSN();

      if ( tType == UPDATE ) 
        {
          UpdateLogRecord * updateLogPointer = dynamic_cast<UpdateLogRecord *>(logPointer);
          pageID = updateLogPointer->getPageID();
          afterImage = updateLogPointer->getAfterImage();
          offset = updateLogPointer->getOffset();
        }
      else if ( tType == CLR )
        {
          CompensationLogRecord * compensationLogPointer = dynamic_cast<CompensationLogRecord *>(logPointer);
          pageID = compensationLogPointer->getPageID();
          afterImage = compensationLogPointer->getAfterImage();
          offset = compensationLogPointer->getOffset();
        }      
      
      if ( dirty_page_table.find(pageID) == dirty_page_table.end() )
        {
          continue;
        }
      if( dirty_page_table[pageID] <= lsn && se->getLSN(pageID) < lsn )
        {
          if( !(se->pageWrite(pageID, offset, afterImage, lsn)) )
            {
              return false;
            }
        }
    }

  vector <int> txToErase;
  for ( auto it = tx_table.begin(); it != tx_table.end(); it++ )
    {
      if( it->second.status == C && it->first != NULL_TX )
        {
	  nextLsn = se->nextLSN();
          logtail.push_back(new LogRecord(nextLsn, it->second.lastLSN, it->first, END));
	  txToErase.push_back(it->first);
        }
    }
  for ( int i = 0; i < txToErase.size(); i++ )
    {
      tx_table.erase(txToErase[i]);
    }

  return true;
}
Exemple #2
0
/* 
 * Run the analysis phase of ARIES.
 */
void LogMgr::analyze(vector <LogRecord*> log)
{
  auto it = log.end();  
  TxType tType;
  int lsn, txID, pageID;
  bool foundCheckpoint = false;

  tx_table.clear();
  dirty_page_table.clear();

  if ( log.size() > 0 )
    {
      it--;
    }
  else
    {
      return;
    }

  while( it >= log.begin() )
    {
      LogRecord *logPointer = *it;
      tType = logPointer->getType();      
      if ( tType == END_CKPT )
        {
          ChkptLogRecord *chkptLogPointer = dynamic_cast<ChkptLogRecord *>(logPointer);
          tx_table = chkptLogPointer->getTxTable();
          dirty_page_table = chkptLogPointer->getDirtyPageTable();
          foundCheckpoint = true;
          break;
        }
      it--;
    }

  if ( !foundCheckpoint )
    {
      it = log.begin();
    }

  while( it != log.end() )
    {
      LogRecord *logPointer = *it;
      tType = logPointer->getType();
      txID = logPointer->getTxID();
      lsn = logPointer->getLSN();
      tx_table[txID].lastLSN = lsn;

      if ( txID == NULL_TX )
	{
	  it++;
	  continue;
	}

      if ( tType ==  UPDATE)
          {
            UpdateLogRecord * updateLogPointer = dynamic_cast<UpdateLogRecord *>(logPointer);
            tx_table[txID].status = U;
            pageID = updateLogPointer->getPageID();
            if ( dirty_page_table.find(pageID) == dirty_page_table.end() )
              {
                // not found                                                                           
                dirty_page_table[pageID] = lsn; 
              }
          }
      else if( tType ==  COMMIT)
          {
            tx_table[txID].status = C;
          }
      else if( tType ==  CLR)
          {
            CompensationLogRecord * compensationLogPointer = dynamic_cast<CompensationLogRecord *>(logPointer);
            tx_table[txID].status = U;
            pageID = compensationLogPointer->getPageID();
            if ( dirty_page_table.find(pageID) == dirty_page_table.end() )
              {
                // not found
                dirty_page_table[pageID] = lsn;
              }
          }
      else if( tType ==  END)
          {
            tx_table.erase(txID);
          }
      it++;
    }
}
Exemple #3
0
/*
 * If no txnum is specified, run the undo phase of ARIES.
 * If a txnum is provided, abort that transaction.
 * Hint: the logic is very similar for these two tasks!
 */
void LogMgr::undo(vector <LogRecord*> log, int txnum)
{
  vector <int> loserTxID;
  priority_queue <int> ToUndo;
  int lsn, lastLsn, nextLsn, txID, pageID, offset, prevLsn, undoNextLsn;
  TxType tType;
  string beforeImage;

  // If a txnum is provided, abort that transaction.
  if ( txnum != NULL_TX )
    {
      lsn = se->nextLSN();
      lastLsn = getLastLSN(txnum);
      setLastLSN(txnum, lsn);
      logtail.push_back(new LogRecord(lsn, lastLsn, txnum, ABORT));
      log.push_back(new LogRecord(lsn, lastLsn, txnum, ABORT));
      tx_table[txnum].lastLSN = lsn;
      tx_table[txnum].status = U;
      loserTxID.push_back(txnum);
    }
  else
    {
      for (auto it = tx_table.begin(); it != tx_table.end(); it++)
        {
          if ( it->second.status != C )
            {
              loserTxID.push_back(it->first);
            }
        }
    }

  auto it = log.end();
  if ( log.size() > 0 )
    {
      it--;
    }
  else
    {
      return;
    }
      
  for ( int i = 0; i < loserTxID.size(); i++ )
    {
      ToUndo.push(tx_table[loserTxID[i]].lastLSN);
    }

  it = log.end();
  if ( log.size() > 0 )
    {
      it--;
    }
  else
    {
      return;
    }
  while ( it >= log.begin() && !(ToUndo.empty()) )
    {
      LogRecord *logPointer = *it;
      tType = logPointer->getType();
      lsn = logPointer->getLSN();
      if (lsn == ToUndo.top())
        {
          ToUndo.pop();
	  if ( tType == UPDATE )
	    {
	      UpdateLogRecord * updateLogPointer = dynamic_cast<UpdateLogRecord *>(logPointer);
	      txID = updateLogPointer->getTxID();
	      pageID = updateLogPointer->getPageID();
	      offset = updateLogPointer->getOffset();
	      beforeImage = updateLogPointer->getBeforeImage();
	      prevLsn = updateLogPointer->getprevLSN();
	      lastLsn = getLastLSN(txID);
	      nextLsn = se->nextLSN();
	      logtail.push_back(new CompensationLogRecord(nextLsn, lastLsn, txID, pageID, offset, beforeImage, prevLsn));
	      setLastLSN(txID, nextLsn);
	      tx_table[txID].status = U;
	      
	      if ( dirty_page_table.find(pageID) == dirty_page_table.end() )
		{
		  dirty_page_table[pageID] = nextLsn; 
		}
	      if( !(se->pageWrite(pageID, offset, beforeImage, nextLsn)) )
		{
		  return;
		}
	      if ( prevLsn == NULL_LSN )
		{
		  logtail.push_back( new LogRecord(se->nextLSN(), nextLsn, txID, END) );
		  tx_table.erase(txID);
		}
	      else
		{
		  ToUndo.push(prevLsn);
		}
	    }
	  else if ( tType == CLR )
	    {
	      CompensationLogRecord* compensationLogPointer = dynamic_cast<CompensationLogRecord*>(logPointer);
	      undoNextLsn = compensationLogPointer->getUndoNextLSN();
	      if(undoNextLsn != NULL_LSN)
		{
		  ToUndo.push(undoNextLsn);   
		} 
	      else 
		{
		  txID = compensationLogPointer->getTxID();
		  nextLsn = se->nextLSN();
		  logtail.push_back( new LogRecord(nextLsn, lsn, txID, END) );
		  tx_table.erase(txID);
		}
	    }

	  else if ( tType == ABORT )
	    {
	      if(prevLsn != NULL_LSN)
                {
		  prevLsn = logPointer->getprevLSN();
                  ToUndo.push(prevLsn);
                }
              else
                {
		  txID = logPointer->getTxID();
		  nextLsn = se->nextLSN();
                  logtail.push_back( new LogRecord(nextLsn, lsn, txID, END) );
                  tx_table.erase(txID);
                }
	    }
        }
      it--;
    }
}
Exemple #4
0
/* 
 * Run the analysis phase of ARIES.
 */
void LogMgr::analyze(vector <LogRecord*> log){
  // find the most recent check_begin if there is one
  int B_CKPT = NULL_LSN;
  int E_CKPT = NULL_LSN;
  
  for(int i = log.size() - 1;i >=0; i--){
    if(log[i]->getType() == BEGIN_CKPT){
      B_CKPT =i;
      break;
    }
    else if(log[i]->getType() == END_CKPT){
      E_CKPT = i;
    }
  }
  
  // if there is begin checkpoint
  if(B_CKPT != NULL_LSN){
    ChkptLogRecord * end_CKPT_Pointer = (ChkptLogRecord *)log[E_CKPT];
    tx_table = end_CKPT_Pointer->getTxTable();
    dirty_page_table = end_CKPT_Pointer->getDirtyPageTable();
  }


  // modifying the tx and dirty table from the begin check point
  for(int i = B_CKPT + 1; i< log.size() ; i++){
    int lsn = log[i]->getLSN();
    // skip the end LSN
    if(lsn != E_CKPT){
      int pre_lsn = log[i]->getprevLSN();
      int txid = log[i]->getTxID();
      TxType t = log[i]->getType();
      
      map<int,txTableEntry>::iterator it;
      map<int,int>::iterator dit;
      it = tx_table.find(txid);
      // end type
      if(t == END){
        if(it != tx_table.end()){
          tx_table.erase(it);
        }
      }
      //other than end
      else{
        
        if(it != tx_table.end()){
          tx_table[txid].lastLSN = lsn;
        }else{
          //adding new 
          txTableEntry t(lsn,TxStatus::U);
          tx_table[txid] = t;
        }

        if(t == COMMIT){
          tx_table[txid].status = TxStatus::C;
        }
        
        else if( t == ABORT){
          tx_table[txid].status = TxStatus::U;
        }

        else if( t == UPDATE ){
          tx_table[txid].status = TxStatus::U;
          UpdateLogRecord * updLog = (UpdateLogRecord * ) log[i];
          int pageID = updLog->getPageID();
          dit = dirty_page_table.find(pageID);
          // if not found in the dirty dtale
          if(dit == dirty_page_table.end()){
            dirty_page_table[pageID] = lsn;
          }
        }else if(t == CLR){
          tx_table[txid].status = TxStatus::U;
          CompensationLogRecord * clrLog = (CompensationLogRecord * ) log[i];
          int pageID = clrLog->getPageID();
          dit = dirty_page_table.find(pageID);
          // if not found in the dirty dtale
          if(dit == dirty_page_table.end()){
            dirty_page_table[pageID] = lsn;
          }
        }else{
          cout<<"Something Wrong in the analysis"<<endl;
        }

      }
    }
  }
}
Exemple #5
0
/*
 * Run the redo phase of ARIES.
 * If the StorageEngine stops responding, return false.
 * Else when redo phase is complete, return true. 
 */
bool LogMgr::redo(vector <LogRecord*> log){
  //first find the oldest update in the dirty-table
  int oldest_lsn = INT_MAX;
  map<int,int>::iterator it;
  for(it = dirty_page_table.begin(); it!=dirty_page_table.end(); it++){
    if(it->second < oldest_lsn){
      oldest_lsn = it->second;
    }
  }
  // iterate through the log 
  for(int i = oldest_lsn; i<log.size() ; i++){
    TxType t = log[i]->getType();
    if(t == UPDATE || t == CLR){
      if(t == UPDATE){
        // if this is update
        UpdateLogRecord * updLog = (UpdateLogRecord * ) log[i];
        int pageID = updLog->getPageID();
        //check the constraint 
        it = dirty_page_table.find(pageID);
        //if the pageID is int the dirty page
        if(it !=dirty_page_table.end()){
          // check if the reclsn is samller then the lsn
          int lsn = updLog->getLSN();
          int reclsn = dirty_page_table[pageID]; 
          if(reclsn <= lsn){
            //check the page lsn is samller than the lsn
            int pageLSN = se->getLSN(pageID);
            if(pageLSN < lsn){
              // redo things
              if(se->pageWrite(pageID,updLog->getOffset(),updLog->getAfterImage(),lsn)){

              }else{
                return false;
              }
            }
          }
        }
      }
      else{
        // if this is clr
        CompensationLogRecord * clrLog = (CompensationLogRecord *) log[i];
        int pageID = clrLog->getPageID();
        it = dirty_page_table.find(pageID);
        if(it != dirty_page_table.end()){
          int lsn = clrLog->getLSN();
          int reclsn = dirty_page_table[pageID]; 
          if(reclsn <= lsn){
            int pageLSN = se->getLSN(pageID);
            if(pageLSN < lsn){
              if(se->pageWrite(pageID,clrLog->getOffset(),clrLog->getAfterImage(),lsn)){

              }else{
                return false;
              }
            }
          }
        }
      }
    }
  }
  // write end type record for C type
  map<int ,txTableEntry>::iterator tit;
  for(tit = tx_table.begin(); tit != tx_table.end(); tit++){
    if(tit->second.status == C){
      LogRecord* eLR = new LogRecord(se->nextLSN(),tit->second.lastLSN,tit->first,TxType::END);
      logtail.push_back(eLR);
      tx_table.erase(tit);
    }
  }

  return false;
}