Package org.apache.derby.iapi.store.raw.xact

Examples of org.apache.derby.iapi.store.raw.xact.RawTransaction


          redoScan = (StreamLogScan)
                        openForwardsScan(start, (LogInstant)null);
        }

        // open a transaction that is used for redo and rollback
        RawTransaction recoveryTransaction =
                    tf.startTransaction(
                        rsf,
                        ContextService.getFactory().getCurrentContextManager(),
                        AccessFactoryGlobals.USER_TRANS_NAME);

        // make this transaction aware that it is a recovery transaction
        // and don't spew forth post commit work while replaying the log
        recoveryTransaction.recoveryTransaction();

        /////////////////////////////////////////////////////////////
        //
        //  Redo loop - in FileLogger
        //
        /////////////////////////////////////////////////////////////

        //
        // set log factory state to inRedo so that if redo caused any
        // dirty page to be written from the cache, it won't flush the
        // log since the end of the log has not been determined and we
        // know the log record that caused the page to change has
        // already been written to the log.  We need the page write to
        // go thru the log factory because if the redo has a problem,
        // the log factory is corrupt and the only way we know not to
        // write out the page in a checkpoint is if it check with the
        // log factory, and that is done via a flush - we use the WAL
        // protocol to stop corrupt pages from writing to the disk.
        //
        inRedo = true

        long logEnd =
                    logger.redo(
                        recoveryTransaction, tf, redoScan, redoLWM,
                        ttabInstant);

        inRedo = false;
       

       
        // if we are only interested in dumping the log, don't alter
        // the database and prevent anyone from using the log
        if (SanityManager.DEBUG)
        {
          if (SanityManager.DEBUG_ON(LogToFile.DUMP_LOG_ONLY))
          {
            Monitor.logMessage("_____________________________________________________");
            Monitor.logMessage("\n\t\t Log dump finished");
            Monitor.logMessage("_____________________________________________________");
                        // just in case, it has not been set anyway
            logOut = null;

            return;
          }
        }


        /////////////////////////////////////////////////////////////
        //
        // determine where the log ends
        //
        /////////////////////////////////////////////////////////////
        StorageRandomAccessFile theLog = null;


        // if logend == LogCounter.INVALID_LOG_SCAN, that means there
                // is no log record in the log - most likely it is corrupted in
                // some way ...
        if (logEnd == LogCounter.INVALID_LOG_INSTANT)
        {
          Monitor.logTextMessage(MessageId.LOG_LOG_NOT_FOUND);

          StorageFile logFile = getLogFileName(logFileNumber);

                    if (privExists(logFile))
          {
            // if we can delete this strange corrupted file, do so,
            // otherwise, skip it
                        if (!privDelete(logFile))
            {
              logFile = getLogFileName(++logFileNumber);
            }
          }

          try
          {
                        theLog =   privRandomAccessFile(logFile, "rw");
          }
          catch (IOException ioe)
          {
            theLog = null;
          }

                    if (theLog == null || !privCanWrite(logFile))
          {
            if (theLog != null)
              theLog.close();

            theLog = null;

            ReadOnlyDB = true;
          }
          else
          {
            try
            {
              // no previous log file or previous log position
              if (!initLogFile(
                                    theLog, logFileNumber,
                                    LogCounter.INVALID_LOG_INSTANT))
                            {
                throw markCorrupt(
                                    StandardException.newException(
                                        SQLState.LOG_SEGMENT_NOT_EXIST,
                                        logFile.getPath()));
                            }
            }
            catch (IOException ioe)
            {
              throw markCorrupt(
                                StandardException.newException(
                                    SQLState.LOG_IO_ERROR, ioe));
            }

                        // successfully init'd the log file - set up markers,
                        // and position at the end of the log.
            endPosition = theLog.getFilePointer();
            lastFlush   = endPosition;
           
            //if write sync is true , prellocate the log file
            //and reopen the file in rws mode.
            if(isWriteSynced)
            {
              //extend the file by wring zeros to it
              preAllocateNewLogFile(theLog);
              theLog.close();
              theLog=  privRandomAccessFile(logFile, "rws");
              //postion the log at the current end postion
              theLog.seek(endPosition);
            }
           
            if (SanityManager.DEBUG)
            {
              SanityManager.ASSERT(
                                endPosition == LOG_FILE_HEADER_SIZE,
                                "empty log file has wrong size");
            }
           
            //because we already incrementing the log number
            //here, no special log switch required for
            //backup recoveries.
            logSwitchRequired = false;
          }
        }
        else
        {
          // logEnd is the instant of the next log record in the log
          // it is used to determine the last known good position of
          // the log
          logFileNumber = LogCounter.getLogFileNumber(logEnd);

          ReadOnlyDB = df.isReadOnly();

          StorageFile logFile = getLogFileName(logFileNumber);

          if (!ReadOnlyDB)
          {
            // if datafactory doesn't think it is readonly, we can
            // do some futher test of our own
            try
            {
              if(isWriteSynced)
                theLog = privRandomAccessFile(logFile, "rws");
              else
                theLog = privRandomAccessFile(logFile, "rw");
            }
            catch (IOException ioe)
            {
              theLog = null;
            }
                        if (theLog == null || !privCanWrite(logFile))
            {
              if (theLog != null)
                theLog.close();
              theLog = null;

              ReadOnlyDB = true;
            }
          }

          if (!ReadOnlyDB)
          {
            endPosition = LogCounter.getLogFilePosition(logEnd);

            //
            // The end of the log is at endPosition.  Which is where
            // the next log should be appending.
            //
            // if the last log record ends before the end of the
                        // log file, then this log file has a fuzzy end.
                        // Zap all the bytes to between endPosition to EOF to 0.
            //
            // the end log marker is 4 bytes (of zeros)
            //
            // if endPosition + 4 == logOut.length, we have a
                        // properly terminated log file
            //
            // if endPosition + 4 is > logOut.length, there are 0,
                        // 1, 2, or 3 bytes of 'fuzz' at the end of the log. We
                        // can ignore that because it is guaranteed to be
                        // overwritten by the next log record.
            //
            // if endPosition + 4 is < logOut.length, we have a
                        // partial log record at the end of the log.
            //
            // We need to overwrite all of the incomplete log
                        // record, because if we start logging but cannot
                        // 'consume' all the bad log, then the log will truly
                        // be corrupted if the next 4 bytes (the length of the
                        // log record) after that is small enough that the next
                        // time the database is recovered, it will be
                        // interpreted that the whole log record is in the log
                        // and will try to objectify, only to get classNotFound
                        // error or worse.
            //

            //find out if log had incomplete log records at the end.
            if (redoScan.isLogEndFuzzy())
            {
              theLog.seek(endPosition);
              long eof = theLog.length();

              Monitor.logTextMessage(MessageId.LOG_INCOMPLETE_LOG_RECORD,
                logFile, new Long(endPosition), new Long(eof));

              /* Write zeros from incomplete log record to end of file */
              long nWrites = (eof - endPosition)/logBufferSize;
              int rBytes = (int)((eof - endPosition) % logBufferSize);
              byte zeroBuf[]= new byte[logBufferSize];
             
              //write the zeros to file
              while(nWrites-- > 0)
                theLog.write(zeroBuf);
              if(rBytes !=0)
                theLog.write(zeroBuf, 0, rBytes);
             
              if(!isWriteSynced)
                syncFile(theLog);
            }

            if (SanityManager.DEBUG)
            {
              if (theLog.length() != endPosition)
              {
                SanityManager.ASSERT(
                                    theLog.length() > endPosition,
                                    "log end > log file length, bad scan");
              }
            }

            // set the log to the true end position,
                        // and not the end of the file

            lastFlush = endPosition;
            theLog.seek(endPosition);
          }
        }

        if (theLog != null)
          logOut = new LogAccessFile(this, theLog, logBufferSize);
       
        if(logSwitchRequired)
          switchLogFile();


        boolean noInFlightTransactions = tf.noActiveUpdateTransaction();

        if (ReadOnlyDB)
        {
          // in the unlikely event that someone detects we are
          // dealing with a read only db, check to make sure the
          // database is quiesce when it was copied with no unflushed
          // dirty buffer
          if (!noInFlightTransactions)
                    {
            throw StandardException.newException(
                                SQLState.LOG_READ_ONLY_DB_NEEDS_UNDO);
                    }
        }

        /////////////////////////////////////////////////////////////
        //
        // Undo loop - in transaction factory.  It just gets one
        // transaction at a time from the transaction table and calls
        // undo, no different from runtime.
        //
        /////////////////////////////////////////////////////////////

                if (SanityManager.DEBUG)
                {
                    if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
                        SanityManager.DEBUG(LogToFile.DBG_FLAG,
                            "About to call undo(), transaction table =" +
                            tf.getTransactionTable());
                }

        if (!noInFlightTransactions)
        {
          if (SanityManager.DEBUG)
          {
            if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
              SanityManager.DEBUG(LogToFile.DBG_FLAG,
                                "In recovery undo, rollback inflight transactions");
          }

          tf.rollbackAllTransactions(recoveryTransaction, rsf);

          if (SanityManager.DEBUG)
          {
            if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
              SanityManager.DEBUG(
                                LogToFile.DBG_FLAG, "finish recovery undo,");
          }
        }
        else
        {
          if (SanityManager.DEBUG)
          {
            if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
              SanityManager.DEBUG(LogToFile.DBG_FLAG,
                                "No in flight transaction, no recovery undo work");
          }
        }

        /////////////////////////////////////////////////////////////
        //
        // XA prepared xact loop - in transaction factory.  At this
                // point only prepared transactions should be left in the
                // transaction table, all others should have been aborted or
                // committed and removed from the transaction table.  It just
                // gets one transaction at a time from the transaction table,
                // creates a real context and transaction, reclaims locks,
                // and leaves the new xact in the transaction table.
        //
        /////////////////////////////////////////////////////////////

                if (SanityManager.DEBUG)
                {
                    if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
                        SanityManager.DEBUG(LogToFile.DBG_FLAG,
                            "About to call rePrepare(), transaction table =" +
                            tf.getTransactionTable());
                }

                tf.handlePreparedXacts(rsf);

                if (SanityManager.DEBUG)
                {
                    if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
                        SanityManager.DEBUG(LogToFile.DBG_FLAG,
                            "Finished rePrepare(), transaction table =" +
                            tf.getTransactionTable());
                }

        /////////////////////////////////////////////////////////////
        //
        // End of recovery.
        //
        /////////////////////////////////////////////////////////////

        // recovery is finished.  Close the transaction
        recoveryTransaction.close();


        // notify the dataFactory that recovery is completed,
        // but before the checkpoint is written.
        dataFactory.postRecovery();
View Full Code Here


        // TODO (mikem) - should a global scratch variable be used?

    // this is an overflow page purge, no need to lock the head row (it
    // has already been locked, hopefully).  No need to check for long rows
    // (they have already been deleted, hopefully).
    RawTransaction  t           = owner.getTransaction();
    int[]           recordId    = new int[1];

    recordId[0]                 = getHeaderAtSlot(slot).getId();

    owner.getActionSet().actionPurge(t, this, slot, 1, recordId, needDataLogged);
View Full Code Here

  }

  protected void prepareForBulkLoad(BaseContainerHandle handle, int numPage)
  {
    clearPreallocThreshold();
    RawTransaction tran = handle.getTransaction();

    // find the last allocation page - do not invalidate the alloc cache,
    // we don't want to prevent other people from reading or writing
    // pages.
    AllocPage allocPage = findLastAllocPage(handle, tran);
View Full Code Here

    @exception StandardException  Standard Cloudscape error policy
  */
  public void compressContainer(BaseContainerHandle handle)
        throws StandardException
    {
    RawTransaction ntt = handle.getTransaction().startNestedTopTransaction();

    int mode = handle.getMode();

    if (SanityManager.DEBUG)
    {
      SanityManager.ASSERT((mode & ContainerHandle.MODE_FORUPDATE) ==
                 ContainerHandle.MODE_FORUPDATE,
                 "addPage handle not for update");
    }

    // if we are not in the same transaction as the one which created the
    // container and the container may have logged some operation already,
    // then we need to log allocation regardless of whether user changes
    // are logged.  Otherwise, the database will be corrupted if it
    // crashed.
    if ((mode & ContainerHandle.MODE_CREATE_UNLOGGED) == 0 &&
      (mode & ContainerHandle.MODE_UNLOGGED) ==
            ContainerHandle.MODE_UNLOGGED)
      mode &= ~ContainerHandle.MODE_UNLOGGED;

    // make a handle which is tied to the ntt, not to the user transaction
        // this handle is tied to.  The container is already locked by the
        // user transaction, open it nolock
    BaseContainerHandle allocHandle = (BaseContainerHandle)
            ntt.openContainer(identity, (LockingPolicy)null, mode);

    if (allocHandle == null)
        {
      throw StandardException.newException(
                    SQLState.DATA_ALLOC_NTT_CANT_OPEN,
                    new Long(getSegmentId()),
                    new Long(getContainerId()));
        }

    // Latch this container, the commit will release the latch
    ntt.getLockFactory().lockObject(
                ntt, ntt, this, null, C_LockFactory.WAIT_FOREVER);

    try
    {
            compressContainer(ntt, allocHandle);
    }
    finally
    {
            ntt.commit();

      ntt.close();
    }
    }
View Full Code Here

    @exception StandardException Standard Cloudscape error policy
  */
  public Page addPage(BaseContainerHandle handle, boolean isOverflow) throws StandardException {
   
    RawTransaction ntt = handle.getTransaction().startNestedTopTransaction();

    int mode = handle.getMode();

    if (SanityManager.DEBUG)
    {
      SanityManager.ASSERT((mode & ContainerHandle.MODE_FORUPDATE) ==
                 ContainerHandle.MODE_FORUPDATE,
                 "addPage handle not for update");
    }

    // if we are not in the same transaction as the one which created the
    // container and the container may have logged some operation already,
    // then we need to log allocation regardless of whether user changes
    // are logged.  Otherwise, the database will be corrupted if it
    // crashed.
    if ((mode & ContainerHandle.MODE_CREATE_UNLOGGED) == 0 &&
      (mode & ContainerHandle.MODE_UNLOGGED) ==
            ContainerHandle.MODE_UNLOGGED)
      mode &= ~ContainerHandle.MODE_UNLOGGED;

    // make a handle which is tied to the ntt, not to the user transaction this
    // handle is tied to.  The container is already locked by the user transaction,
    // open it nolock
    BaseContainerHandle allocHandle = (BaseContainerHandle)ntt.openContainer
      (identity, (LockingPolicy)null, mode);

    if (allocHandle == null)
        {
      throw StandardException.newException(
                    SQLState.DATA_ALLOC_NTT_CANT_OPEN,
                    new Long(getSegmentId()),
                    new Long(getContainerId()));
        }

    // Latch this container, the commit will release the latch
    ntt.getLockFactory().lockObject(
                ntt, ntt, this, null, C_LockFactory.WAIT_FOREVER);

    BasePage newPage = null;
    try
    {
      newPage = newPage(handle, ntt, allocHandle, isOverflow);
    }
    finally
    {
      if (newPage != null)
            {
                // it is ok to commit without syncing, as it is ok if this
                // transaction never makes it to the db, if no subsequent
                // log record makes it to the log.  If any subsequent log
                // record is sync'd then this transaction will be sync'd
                // as well.
        ntt.commitNoSync(Transaction.RELEASE_LOCKS);
            }
      else
            {     
        ntt.abort();
            }
      ntt.close();
    }

    if (SanityManager.DEBUG) {
      SanityManager.ASSERT(newPage.isLatched());
    }
View Full Code Here

                   boolean zeroDuration)
     throws StandardException
  {
    // get deallocate lock on page so that the GC won't attempt to
    // free and re-allocate it until the transaction commits
    RawTransaction tran = handle.getTransaction();

    LockingPolicy lp =
            tran.newLockingPolicy(
                LockingPolicy.MODE_RECORD,
                TransactionController.ISOLATION_REPEATABLE_READ,
                true); // striterOK
   
    PageKey pkey = new PageKey(identity, deallocLock.getPageNumber());
View Full Code Here

    lock may be held until the end of the transaction.

  */
  protected void letGo(BaseContainerHandle handle) {

    RawTransaction t = handle.getTransaction();

    handle.getLockingPolicy().unlockContainer(t, handle);
  }
View Full Code Here

        // that is being updated.
        Page firstPageOnColumnChain = getOverflowPage(overflowPage);
        PageTimeStamp ts = firstPageOnColumnChain.currentTimeStamp();
        firstPageOnColumnChain.unlatch();

        RawTransaction rxact = (RawTransaction)owner.getTransaction();

        ReclaimSpace work =
          new ReclaimSpace(ReclaimSpace.COLUMN_CHAIN,
                headRowHandle,
                fieldId, // long column about to be orphaned by update
                overflowPage, // page where the long column starts
                overflowId, // record Id of the beginning of the long column
                ts,
                rxact.getDataFactory(), true);

        rxact.addPostCommitWork(work);

        rawDataIn.setPosition(saveOffset); // Just to be safe, reset data stream
      }

View Full Code Here

    // Back to the head page.  Get rid of all reserved space in the entire
    // row post commit.
    if (rowHasReservedSpace)
    {
      RawTransaction rxact = (RawTransaction)owner.getTransaction();

      ReclaimSpace work =
        new ReclaimSpace(ReclaimSpace.ROW_RESERVE,
                 headRowHandle,
                 rxact.getDataFactory(), true);
      rxact.addPostCommitWork(work);
    }
  }
View Full Code Here

        // TODO (mikem) - should a global scratch variable be used?

    // this is an overflow page purge, no need to lock the head row (it
    // has already been locked, hopefully).  No need to check for long rows
    // (they have already been deleted, hopefully).
    RawTransaction  t           = owner.getTransaction();
    int[]           recordId    = new int[1];

    recordId[0]                 = getHeaderAtSlot(slot).getId();

    owner.getActionSet().actionPurge(t, this, slot, 1, recordId, needDataLogged);
View Full Code Here

TOP

Related Classes of org.apache.derby.iapi.store.raw.xact.RawTransaction

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.