Package org.apache.derby.impl.store.raw.log

Examples of org.apache.derby.impl.store.raw.log.LogRecord


        SanityManager.ASSERT(
                    scanLog != null, "cannot open log for prepare");

      rawInput    = new ArrayInputStream(new byte[4096]);

      LogRecord record;

      while ((record =
                    scanLog.getNextRecord(rawInput, prepareId, 0))
                       != null)
      {
        if (SanityManager.DEBUG)
        {
          SanityManager.ASSERT(
                        record.getTransactionId().equals(prepareId),
              "getNextRecord return unqualified log rec for prepare");
        }

        logrecordseen++;

        if (record.isCLR())
        {
          clrskipped++;

                    // the loggable is still in the input stream, get rid of it
          record.skipLoggable();

          // read the prepareInstant
          long prepareInstant = rawInput.readLong();

          if (SanityManager.DEBUG)
                    {
                        if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
                        {
                            SanityManager.DEBUG(
                                LogToFile.DBG_FLAG,
                                    "Skipping over CLRs, reset scan to " +
                                    LogCounter.toDebugString(prepareInstant));
                        }
          }

          scanLog.resetPosition(new LogCounter(prepareInstant));
          // scanLog now positioned at the beginning of the log
          // record that was rolled back by this CLR.
          // The scan is a backward one so getNextRecord will skip
          // over the record that was rolled back and go to the one
          // previous to it

          continue;
        }

                if (record.requiresPrepareLocks())
                {
                    lop = record.getRePreparable();
                }
                else
                {
                    continue;
                }
View Full Code Here


        SanityManager.ASSERT(
                    scanLog != null, "cannot open log for undo");

      rawInput   = new ArrayInputStream(new byte[4096]);

      LogRecord record;

      while ((record =
                    scanLog.getNextRecord(rawInput, undoId, 0))
                        != null)
      {
        if (SanityManager.DEBUG)
        {
          SanityManager.ASSERT(
                        record.getTransactionId().equals(undoId),
                        "getNextRecord return unqualified log record for undo");
        }

        logrecordseen++;

        if (record.isCLR())
        {
          clrskipped++;

                    // the loggable is still in the input stream, get rid of it
          record.skipLoggable();

          // read the undoInstant
          long undoInstant = rawInput.readLong();

          if (SanityManager.DEBUG)
                    {
                        if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
                        {
                            SanityManager.DEBUG(
                                LogToFile.DBG_FLAG,
                                "Skipping over CLRs, reset scan to " +
                                LogCounter.toDebugString(undoInstant));
                        }
                    }


          scanLog.resetPosition(new LogCounter(undoInstant));

          // scanLog now positioned at the beginning of the log
          // record that was rolled back by this CLR.
          // The scan is a backward one so getNextRecord will skip
          // over the record that was rolled back and go to the one
          // previous to it

          continue;
        }

        lop = record.getUndoable();

        if (lop != null)
        {
          int optionalDataLength = rawInput.readInt();
          int savePosition = rawInput.getPosition();
View Full Code Here

    try
        {

      // scan the log forward in redo pass and go to the end
      LogRecord record;
      while((record =
                    redoScan.getNextRecord(logIn, null, 0))
                        != null)
      {
        scanCount++;
        long undoInstant = 0;

        // last known good instant
        instant = redoScan.getInstant();

        // last known good log end
        logEnd = redoScan.getLogRecordEnd();


        // NOTE NOTE -- be very careful about the undoInstant, it is
        // read off the input stream in this debug section.
        // if we change the log format we will need to change the way
        // the undo instant is gotten.  Also, once it is read off, it
        // should not be read from the stream any more
        // NOTE NOTE
        if (SanityManager.DEBUG)
                {
                    if (SanityManager.DEBUG_ON(LogToFile.DUMP_LOG_ONLY) ||
                        SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))

                    {
                        if (SanityManager.DEBUG_ON(LogToFile.DUMP_LOG_ONLY))
                            SanityManager.DEBUG_SET(LogToFile.DBG_FLAG);

                        op = record.getLoggable();
                        tranId = record.getTransactionId();
                        if (record.isCLR()) 
                        {
                            // !!!!!!! this moves the file pointer
                            undoInstant = logIn.readLong();

                            SanityManager.DEBUG(
                                LogToFile.DBG_FLAG,
                                "scanned " + tranId + " : " + op +
                                " instant = " +
                                    LogCounter.toDebugString(instant) +
                                " undoInstant : " +
                                    LogCounter.toDebugString(undoInstant));
                        }
                        else
                        {
                            SanityManager.DEBUG(
                                LogToFile.DBG_FLAG,
                                "scanned " + tranId + " : " + op +
                                " instant = " +
                                    LogCounter.toDebugString(instant)
                                + " logEnd = " +
                                    LogCounter.toDebugString(logEnd)
                                + " logIn at " + logIn.getPosition()
                                + " available " + logIn.available());
                        }

                        // we only want to dump the log, don't touch it
                        if (SanityManager.DEBUG_ON(LogToFile.DUMP_LOG_ONLY))
                            continue;
                    }
                }

        // if the redo scan is between the undoLWM and redoLWM, we only
        // need to redo begin and end tran.  Everything else has
        // already been flushed by checkpoint
        if (redoLWM !=
                        LogCounter.INVALID_LOG_INSTANT && instant < redoLWM)
        {
          if (!(record.isFirst()      ||
                          record.isComplete()   ||
                          record.isPrepare()))
                    {
            continue;
                    }
        }

        // get the transaction
        tranId = record.getTransactionId();

        // if this transaction is known to the transaction factory, make
                // the recoveryTransaction assume its identitiy and properties
                // otherwise, make it known to the transaction factory
        if (!transFactory.findTransaction(tranId, recoveryTransaction))
        {
          // transaction not found

          if (redoLWM != LogCounter.INVALID_LOG_INSTANT &&
            instant < redoLWM &&
                        (record.isPrepare() || record.isComplete()))
          {
            // What is happening here is that a transaction that
            // started before the undoLWM has commited by the time
            // the checkpoint undoLWM was taken.  Hence, we only
            // see the tail end of its log record and its endXact
                        // record.
            //
            // NOTE:
            // Since we didn't see its beginXact, we cannot do the
            // endXact's doMe either.  Also if the endXact, is
                        // actually just a prepare, we don't need to do
                        // anything as the transaction will commit or abort
                        // prior to point we are recovering to.
            // If it is deemed necessary to do the endXact's doMe,
                        // then we should start the transaction right here.
                        // For now, just completely ignore this transaction
            //
            etranCount++;

            continue;
          }

          if ((ttabInstant == LogCounter.INVALID_LOG_INSTANT) &&
                        !record.isFirst())
                    {
            throw StandardException.newException(
                            SQLState.LOG_UNEXPECTED_RECOVERY_PROBLEM,
                            MessageService.getTextMessage(MessageId.LOG_RECORD_NOT_FIRST,tranId));

                    }

          if (SanityManager.DEBUG)
          {
            // if we dumped the transaction table but see a non
                        // BeginXact record after the transaction table dump
                        // instant, error.
            if (ttabInstant != LogCounter.INVALID_LOG_INSTANT)
            {
              if (instant > ttabInstant && !record.isFirst())
                            {
                SanityManager.THROWASSERT(
                "log record is Not first but transaction " +
                                "is not in transaction table (2) : " + tranId);
                            }

              // If we dump the transaction table and the table
              // does not have the transaction, and we see this
              // beginXact before the ttab instant, we could have
              // igored it because we "know" that we should see
              // the endXact before the ttab instant also.
              // Leave it in just in case.
            }
          }
          btranCount++;

          // the long transaction ID is embedded in the beginXact log
          // record.  The short ID is stored in the log record.
          recoveryTransaction.setTransactionId(
                        record.getLoggable(), tranId);

        }
        else       
        {
                    // recoveryTransaction found
                   
          if ((ttabInstant == LogCounter.INVALID_LOG_INSTANT) &&
                         record.isFirst())
                    {
            throw StandardException.newException(
                            SQLState.LOG_UNEXPECTED_RECOVERY_PROBLEM,
                            MessageService.getTextMessage(MessageId.LOG_RECORD_FIRST,
                                tranId));

                    }

          if (SanityManager.DEBUG)
          {
            if (ttabInstant != LogCounter.INVALID_LOG_INSTANT &&
              instant > ttabInstant &&
              record.isFirst())
                        {
              SanityManager.THROWASSERT(
                "log record is first but transaction is " +
                                "already in transaction table (3): " + tranId);
                        }

                        if (record.isPrepare())
                            prepareCount++;
          }

          // if we have a transaction table dumped with the
          // checkpoint log record, then during the redo scan we may
          // see the beginXact of a transaction which is already in
                    // the transaction table, just ignore it if it is after the
          // redoLWM but before the transaction table instant.  We
          // still need to redo any database changes but since the
          // transaction is already recorded in the transaction
          // table, ignore it.
          //
          if (record.isFirst())
          {
            btranCount++;
            continue;
          }
        }
       
        op = record.getLoggable();

        if (SanityManager.DEBUG)
                {
                    if (!record.isCLR())
                    {
                        if (logIn.available() < 4)
                        {
                            SanityManager.THROWASSERT(
                              "not enough bytes read in : " +
                                  logIn.available() +
                              " for " + op + " instant " +
                                  LogCounter.toDebugString(instant));
                        }
                    }
                }

        if (SanityManager.DEBUG)
                {
          SanityManager.ASSERT(
                        !recoveryTransaction.handlesPostTerminationWork(),
             "recovery transaction handles post termination work");
                }

        if (op.needsRedo(recoveryTransaction))
        {
          redoCount++;

          if (record.isCLR()) 
          {
            clrCount++;

            // the log operation is not complete, the operation to
            // undo is stashed away at the undoInstant.
            // Reconstitute that first.

            if (SanityManager.DEBUG)
              SanityManager.ASSERT(op instanceof Compensation);


                        // this value may be set by sanity xxxx
            if (undoInstant == 0)
              undoInstant = logIn.readLong();

            if (undoScan == null)
            {
              undoScan = (StreamLogScan)
                logFactory.openForwardsScan(
                                    undoInstant,(LogInstant)null);
            }
            else
            {
              undoScan.resetPosition(new LogCounter(undoInstant));
            }

            // undoScan now positioned at the beginning of the log
            // record was rolled back by this CLR. 
            // The scan is a forward one so getNextRecord will get
                        // the log record that needs to be rolled back.

            // reuse the buffer in logIn and logIn since CLR
                        // has no optional data and has no use for them anymore
            logIn.clearLimit();
            LogRecord undoRecord =
              undoScan.getNextRecord(logIn, null, 0);

            Undoable undoOp = undoRecord.getUndoable();

            if (SanityManager.DEBUG)
            {
              SanityManager.DEBUG(
                                LogToFile.DBG_FLAG,
                                "Redoing CLR: undoInstant = " +
                                    LogCounter.toDebugString(undoInstant) +
                                " clrinstant = " +
                                    LogCounter.toDebugString(instant));

              SanityManager.ASSERT(
                                undoRecord.getTransactionId().equals(tranId));

              SanityManager.ASSERT(undoOp != null);
            }

            ((Compensation)op).setUndoOp(undoOp);
View Full Code Here

    // Keep in mind the dynamic nature of the logOutputBuffer which means
    // it could switch buffer from underneath the logOutputBuffer on every
    // write.
    logIn = new ArrayInputStream();
    logRecord = new LogRecord();

  }
View Full Code Here

        SanityManager.ASSERT(
                    scanLog != null, "cannot open log for prepare");

      rawInput    = new ArrayInputStream(new byte[4096]);

      LogRecord record;

      while ((record =
                    scanLog.getNextRecord(rawInput, prepareId, 0))
                       != null)
      {
        if (SanityManager.DEBUG)
        {
          SanityManager.ASSERT(
                        record.getTransactionId().equals(prepareId),
              "getNextRecord return unqualified log rec for prepare");
        }

        logrecordseen++;

        if (record.isCLR())
        {
          clrskipped++;

                    // the loggable is still in the input stream, get rid of it
          record.skipLoggable();

          // read the prepareInstant
          long prepareInstant = rawInput.readLong();

          if (SanityManager.DEBUG)
                    {
                        if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
                        {
                            SanityManager.DEBUG(
                                LogToFile.DBG_FLAG,
                                    "Skipping over CLRs, reset scan to " +
                                    LogCounter.toDebugString(prepareInstant));
                        }
          }

          scanLog.resetPosition(new LogCounter(prepareInstant));
          // scanLog now positioned at the beginning of the log
          // record that was rolled back by this CLR.
          // The scan is a backward one so getNextRecord will skip
          // over the record that was rolled back and go to the one
          // previous to it

          continue;
        }

                if (record.requiresPrepareLocks())
                {
                    lop = record.getRePreparable();
                }
                else
                {
                    continue;
                }
View Full Code Here

        SanityManager.ASSERT(
                    scanLog != null, "cannot open log for undo");

      rawInput   = new ArrayInputStream(new byte[4096]);

      LogRecord record;

      while ((record =
                    scanLog.getNextRecord(rawInput, undoId, 0))
                        != null)
      {
        if (SanityManager.DEBUG)
        {
          SanityManager.ASSERT(
                        record.getTransactionId().equals(undoId),
                        "getNextRecord return unqualified log record for undo");
        }

        logrecordseen++;

        if (record.isCLR())
        {
          clrskipped++;

                    // the loggable is still in the input stream, get rid of it
          record.skipLoggable();

          // read the undoInstant
          long undoInstant = rawInput.readLong();

          if (SanityManager.DEBUG)
                    {
                        if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
                        {
                            SanityManager.DEBUG(
                                LogToFile.DBG_FLAG,
                                "Skipping over CLRs, reset scan to " +
                                LogCounter.toDebugString(undoInstant));
                        }
                    }


          scanLog.resetPosition(new LogCounter(undoInstant));

          // scanLog now positioned at the beginning of the log
          // record that was rolled back by this CLR.
          // The scan is a backward one so getNextRecord will skip
          // over the record that was rolled back and go to the one
          // previous to it

          continue;
        }

        lop = record.getUndoable();

        if (lop != null)
        {
          int optionalDataLength = rawInput.readInt();
          int savePosition = rawInput.getPosition();
View Full Code Here

    try
        {

      // scan the log forward in redo pass and go to the end
      LogRecord record;
      while((record =
                    redoScan.getNextRecord(logIn, null, 0))
                        != null)
      {
        scanCount++;
        long undoInstant = 0;

        // last known good instant
        instant = redoScan.getInstant();

        // last known good log end
        logEnd = redoScan.getLogRecordEnd();


        // NOTE NOTE -- be very careful about the undoInstant, it is
        // read off the input stream in this debug section.
        // if we change the log format we will need to change the way
        // the undo instant is gotten.  Also, once it is read off, it
        // should not be read from the stream any more
        // NOTE NOTE
        if (SanityManager.DEBUG)
                {
                    if (SanityManager.DEBUG_ON(LogToFile.DUMP_LOG_ONLY) ||
                        SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))

                    {
                        if (SanityManager.DEBUG_ON(LogToFile.DUMP_LOG_ONLY))
                            SanityManager.DEBUG_SET(LogToFile.DBG_FLAG);

                        op = record.getLoggable();
                        tranId = record.getTransactionId();
                        if (record.isCLR()) 
                        {
                            // !!!!!!! this moves the file pointer
                            undoInstant = logIn.readLong();

                            SanityManager.DEBUG(
                                LogToFile.DBG_FLAG,
                                "scanned " + tranId + " : " + op +
                                " instant = " +
                                    LogCounter.toDebugString(instant) +
                                " undoInstant : " +
                                    LogCounter.toDebugString(undoInstant));
                        }
                        else
                        {
                            SanityManager.DEBUG(
                                LogToFile.DBG_FLAG,
                                "scanned " + tranId + " : " + op +
                                " instant = " +
                                    LogCounter.toDebugString(instant)
                                + " logEnd = " +
                                    LogCounter.toDebugString(logEnd)
                                + " logIn at " + logIn.getPosition()
                                + " available " + logIn.available());
                        }

                        // we only want to dump the log, don't touch it
                        if (SanityManager.DEBUG_ON(LogToFile.DUMP_LOG_ONLY))
                            continue;
                    }
                }

        // if the redo scan is between the undoLWM and redoLWM, we only
        // need to redo begin and end tran.  Everything else has
        // already been flushed by checkpoint
        if (redoLWM !=
                        LogCounter.INVALID_LOG_INSTANT && instant < redoLWM)
        {
          if (!(record.isFirst()      ||
                          record.isComplete()   ||
                          record.isPrepare()))
                    {
            continue;
                    }
        }

        // get the transaction
        tranId = record.getTransactionId();

        // if this transaction is known to the transaction factory, make
                // the recoveryTransaction assume its identitiy and properties
                // otherwise, make it known to the transaction factory
        if (!transFactory.findTransaction(tranId, recoveryTransaction))
        {
          // transaction not found

          if (redoLWM != LogCounter.INVALID_LOG_INSTANT &&
            instant < redoLWM &&
                        (record.isPrepare() || record.isComplete()))
          {
            // What is happening here is that a transaction that
            // started before the undoLWM has commited by the time
            // the checkpoint undoLWM was taken.  Hence, we only
            // see the tail end of its log record and its endXact
                        // record.
            //
            // NOTE:
            // Since we didn't see its beginXact, we cannot do the
            // endXact's doMe either.  Also if the endXact, is
                        // actually just a prepare, we don't need to do
                        // anything as the transaction will commit or abort
                        // prior to point we are recovering to.
            // If it is deemed necessary to do the endXact's doMe,
                        // then we should start the transaction right here.
                        // For now, just completely ignore this transaction
            //
            etranCount++;

            continue;
          }

          if ((ttabInstant == LogCounter.INVALID_LOG_INSTANT) &&
                        !record.isFirst())
                    {
            throw StandardException.newException(
                            SQLState.LOG_UNEXPECTED_RECOVERY_PROBLEM,
                            MessageService.getTextMessage(MessageId.LOG_RECORD_NOT_FIRST,tranId));

                    }

          if (SanityManager.DEBUG)
          {
            // if we dumped the transaction table but see a non
                        // BeginXact record after the transaction table dump
                        // instant, error.
            if (ttabInstant != LogCounter.INVALID_LOG_INSTANT)
            {
              if (instant > ttabInstant && !record.isFirst())
                            {
                SanityManager.THROWASSERT(
                "log record is Not first but transaction " +
                                "is not in transaction table (2) : " + tranId);
                            }

              // If we dump the transaction table and the table
              // does not have the transaction, and we see this
              // beginXact before the ttab instant, we could have
              // igored it because we "know" that we should see
              // the endXact before the ttab instant also.
              // Leave it in just in case.
            }
          }
          btranCount++;

          // the long transaction ID is embedded in the beginXact log
          // record.  The short ID is stored in the log record.
          recoveryTransaction.setTransactionId(
                        record.getLoggable(), tranId);

        }
        else       
        {
                    // recoveryTransaction found
                   
          if ((ttabInstant == LogCounter.INVALID_LOG_INSTANT) &&
                         record.isFirst())
                    {
            throw StandardException.newException(
                            SQLState.LOG_UNEXPECTED_RECOVERY_PROBLEM,
                            MessageService.getTextMessage(MessageId.LOG_RECORD_FIRST,
                                tranId));

                    }

          if (SanityManager.DEBUG)
          {
            if (ttabInstant != LogCounter.INVALID_LOG_INSTANT &&
              instant > ttabInstant &&
              record.isFirst())
                        {
              SanityManager.THROWASSERT(
                "log record is first but transaction is " +
                                "already in transaction table (3): " + tranId);
                        }

                        if (record.isPrepare())
                            prepareCount++;
          }

          // if we have a transaction table dumped with the
          // checkpoint log record, then during the redo scan we may
          // see the beginXact of a transaction which is already in
                    // the transaction table, just ignore it if it is after the
          // redoLWM but before the transaction table instant.  We
          // still need to redo any database changes but since the
          // transaction is already recorded in the transaction
          // table, ignore it.
          //
          if (record.isFirst())
          {
            btranCount++;
            continue;
          }
        }
       
        op = record.getLoggable();

        if (SanityManager.DEBUG)
                {
                    if (!record.isCLR())
                    {
                        if (logIn.available() < 4)
                        {
                            SanityManager.THROWASSERT(
                              "not enough bytes read in : " +
                                  logIn.available() +
                              " for " + op + " instant " +
                                  LogCounter.toDebugString(instant));
                        }
                    }
                }

        if (SanityManager.DEBUG)
                {
          SanityManager.ASSERT(
                        !recoveryTransaction.handlesPostTerminationWork(),
             "recovery transaction handles post termination work");
                }

        if (op.needsRedo(recoveryTransaction))
        {
          redoCount++;

          if (record.isCLR()) 
          {
            clrCount++;

            // the log operation is not complete, the operation to
            // undo is stashed away at the undoInstant.
            // Reconstitute that first.

            if (SanityManager.DEBUG)
              SanityManager.ASSERT(op instanceof Compensation);


                        // this value may be set by sanity xxxx
            if (undoInstant == 0)
              undoInstant = logIn.readLong();

            if (undoScan == null)
            {
              undoScan = (StreamLogScan)
                logFactory.openForwardsScan(
                                    undoInstant,(LogInstant)null);
            }
            else
            {
              undoScan.resetPosition(new LogCounter(undoInstant));
            }

            // undoScan now positioned at the beginning of the log
            // record was rolled back by this CLR. 
            // The scan is a forward one so getNextRecord will get
                        // the log record that needs to be rolled back.

            // reuse the buffer in logIn and logIn since CLR
                        // has no optional data and has no use for them anymore
            logIn.clearLimit();
            LogRecord undoRecord =
              undoScan.getNextRecord(logIn, null, 0);

            Undoable undoOp = undoRecord.getUndoable();

            if (SanityManager.DEBUG)
            {
              SanityManager.DEBUG(
                                LogToFile.DBG_FLAG,
                                "Redoing CLR: undoInstant = " +
                                    LogCounter.toDebugString(undoInstant) +
                                " clrinstant = " +
                                    LogCounter.toDebugString(instant));

              SanityManager.ASSERT(
                                undoRecord.getTransactionId().equals(tranId));

              SanityManager.ASSERT(undoOp != null);
            }

            ((Compensation)op).setUndoOp(undoOp);
View Full Code Here

  {
    Loggable lop = null;

    ArrayInputStream logInputBuffer = new ArrayInputStream(new byte[size]);

    LogRecord record = scan.getNextRecord(logInputBuffer, null, 0);
    if (record != null)
      lop = record.getLoggable();
    return lop;
  }
View Full Code Here

      return null;

    if (SanityManager.DEBUG)
      SanityManager.ASSERT(scanDirection != 0, "scan has been secretly closed!");

    LogRecord lr = null;
    try
    {
      if (scanDirection == BACKWARD)
        lr = getNextRecordBackward(input, tranId, groupmask);
      else if (scanDirection == FORWARD)
View Full Code Here

    if (tranId != null)
      peekAmount += LogRecord.maxTransactionIdStoredSize(tranId);

    int readAmount;      // the number of bytes actually read

    LogRecord lr;
    long curpos = scan.getFilePointer();

    do
    {
      // this log record is a candidate unless proven otherwise
      candidate = true;
      lr = null;
      readAmount = -1;

      if (curpos == LogToFile.LOG_FILE_HEADER_SIZE)
      {
        // don't go thru the trouble of switching log file if we
        // will have gone past stopAt
        if (stopAt != LogCounter.INVALID_LOG_INSTANT &&
          LogCounter.getLogFileNumber(stopAt) == currentLogFileNumber)
        {
          if (SanityManager.DEBUG)
                    {
                        if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
                        {
                            SanityManager.DEBUG(LogToFile.DBG_FLAG,
                                "stopping at " + currentLogFileNumber);
                        }
                    }

          return null// no more log record
        }
       
        // figure out where the last log record is in the previous
        // log file
        scan.seek(LogToFile.LOG_FILE_HEADER_PREVIOUS_LOG_INSTANT_OFFSET);
        long previousLogInstant = scan.readLong();
        scan.close();

        if (SanityManager.DEBUG)
        {
          SanityManager.ASSERT(previousLogInstant != LogCounter.INVALID_LOG_INSTANT,
                   "scanning backward beyond the first log file");
          if (currentLogFileNumber !=
              LogCounter.getLogFileNumber(previousLogInstant) + 1)
            SanityManager.THROWASSERT(
            "scanning backward but get incorrect log file number " +
             "expected " + (currentLogFileNumber -1) +
             "get " +
             LogCounter.getLogFileNumber(previousLogInstant));

          SanityManager.ASSERT(LogCounter.getLogFilePosition(previousLogInstant) >
                   LogToFile.LOG_FILE_HEADER_SIZE,
                   "scanning backward encounter completely empty log file");

          SanityManager.DEBUG(LogToFile.DBG_FLAG,
                  "scanning backwards from log file " +
                  currentLogFileNumber + ", switch to (" +
                  LogCounter.getLogFileNumber(previousLogInstant) + "," +
                  LogCounter.getLogFilePosition(previousLogInstant) + ")"
                  );
        }

        // log file switch, set this.currentLogFileNumber
        currentLogFileNumber = LogCounter.getLogFileNumber(previousLogInstant);

        scan = logFactory.getLogFileAtPosition(previousLogInstant);

        // scan is located right past the last byte of the last log
        // record in the previous log file.  currentLogFileNumber is
        // set.  We asserted that the scan is not located right at the
        // end of the file header, in other words, there is at least
        // one log record in this log file.
        curpos = scan.getFilePointer();

        // if the log file happens to be empty skip and proceed.
        // ideally this case should never occur because log switch is
        // not suppose to happen on an empty log file.
        // But it is safer to put following check incase if it ever
        // happens to avoid any recovery issues.
        if (curpos == LogToFile.LOG_FILE_HEADER_SIZE)
          continue;
      }

      scan.seek(curpos - 4);
      int recordLength = scan.readInt(); // get the length after the log record

      // calculate where this log record started.
      // include the eight bytes for the long log instant at the front
      // the four bytes of length in the front and the four bytes we just read
      long recordStartPosition = curpos - recordLength -
        LogToFile.LOG_RECORD_OVERHEAD;

      if (SanityManager.DEBUG)
      {
        if (recordStartPosition < LogToFile.LOG_FILE_HEADER_SIZE)
          SanityManager.THROWASSERT(
                 "next position " + recordStartPosition +
                 " recordLength " + recordLength +
                 " current file position " + scan.getFilePointer());

        scan.seek(recordStartPosition);

        // read the length before the log record and check it against the
        // length after the log record
        int checkLength = scan.readInt();

        if (checkLength != recordLength)
        {
          long inst = LogCounter.makeLogInstantAsLong(currentLogFileNumber, recordStartPosition);

          throw logFactory.markCorrupt(
                        StandardException.newException(
                            SQLState.LOG_RECORD_CORRUPTED,
                            new Long(checkLength),
                            new Long(recordLength),
                            new Long(inst),
                            new Long(currentLogFileNumber)));
        }
      }
      else
      {
        // skip over the length in insane
        scan.seek(recordStartPosition+4);
      }

      // scan is positioned just before the log instant
      // read the current log instant - this is the currentInstant if we have not
      // exceeded the scan limit
      currentInstant = scan.readLong();

      if (SanityManager.DEBUG)
      {
        // sanity check the current instant against the scan position
        if (LogCounter.getLogFileNumber(currentInstant) !=
          currentLogFileNumber ||
          LogCounter.getLogFilePosition(currentInstant) !=
          recordStartPosition)
          SanityManager.THROWASSERT(
                 "Wrong LogInstant on log record " +
                LogCounter.toDebugString(currentInstant) +
                 " version real position (" +
                 currentLogFileNumber + "," +
                 recordStartPosition + ")");
      }


      // if stopAt == INVALID_LOG_INSTANT, no stop instant, read till
      // nothing more can be read.  Else check scan limit
      if (currentInstant < stopAt && stopAt != LogCounter.INVALID_LOG_INSTANT)
      {
        currentInstant = LogCounter.INVALID_LOG_INSTANT;
        return null// we went past the stopAt
      }


      byte[] data = input.getData();

      if (data.length < recordLength)
      {
        // make a new array of sufficient size and reset the arrary
        // in the input stream
        data = new byte[recordLength];
        input.setData(data);
      }

      // If the log is encrypted, we must do the filtering after reading
      // and decrypting the record.
      if (logFactory.databaseEncrypted())
      {
        scan.readFully(data, 0, recordLength);
        int len = logFactory.decrypt(data, 0, recordLength, data, 0);
        if (SanityManager.DEBUG)
          SanityManager.ASSERT(len == recordLength);
        input.setLimit(0, recordLength);
      }
      else // no need to decrypt, only get the group and tid if we filter
      {
        if (groupmask == 0 && tranId == null)
        {
          // no filter, get the whole thing
          scan.readFully(data, 0, recordLength);
          input.setLimit(0, recordLength);
        }
        else
        {
          // Read only enough so that group and the tran id is in
          // the data buffer.  Group is stored as compressed int
          // and tran id is stored as who knows what.  read min
          // of peekAmount or recordLength
          readAmount = (recordLength > peekAmount) ?
            peekAmount : recordLength;

          // in the data buffer, we now have enough to peek
          scan.readFully(data, 0, readAmount);
          input.setLimit(0, readAmount);
        }
      }

      lr = (LogRecord) input.readObject();
      if (groupmask != 0 || tranId != null)
      {
        if (groupmask != 0 && (groupmask & lr.group()) == 0)
          candidate = false; // no match, throw this log record out

        if (candidate && tranId != null)
        {
          TransactionId tid = lr.getTransactionId();
          if (!tid.equals(tranId)) // nomatch
            candidate = false; // throw this log record out
        }

        // if this log record is not filtered out, we need to read
View Full Code Here

TOP

Related Classes of org.apache.derby.impl.store.raw.log.LogRecord

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.