Examples of StreamLogScan


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

        long redoLWM     = LogCounter.INVALID_LOG_INSTANT;
        long undoLWM     = LogCounter.INVALID_LOG_INSTANT;
        long ttabInstant = LogCounter.INVALID_LOG_INSTANT;

        StreamLogScan redoScan = null;
        if (currentCheckpoint != null)
        { 
          Formatable transactionTable = null;

          // RESOLVE: sku
          // currentCheckpoint.getTransactionTable();

          // need to set the transaction table before the undo
          tf.useTransactionTable(transactionTable);

          redoLWM = currentCheckpoint.redoLWM();
          undoLWM = currentCheckpoint.undoLWM();

          if (transactionTable != null)
            ttabInstant = checkpointInstant;

          if (SanityManager.DEBUG)
          {
            if (SanityManager.DEBUG_ON(DBG_FLAG))
            {
              SanityManager.DEBUG(DBG_FLAG,
                                "Found checkpoint at " +
                                LogCounter.toDebugString(checkpointInstant) +
                                " " + currentCheckpoint.toString());
            }
          }

          firstLogFileNumber = LogCounter.getLogFileNumber(redoLWM);

          // figure out where the first interesting log file is.
          if (LogCounter.getLogFileNumber(undoLWM) <
                            firstLogFileNumber)
                    {
            firstLogFileNumber =
                            LogCounter.getLogFileNumber(undoLWM);
                    }


          // if the checkpoint record doesn't have a transaction
          // table, we need to rebuild it by scanning the log from
          // the undoLWM.  If it does have a transaction table, we
          // only need to scan the log from the redoLWM

          redoScan = (StreamLogScan)
                        openForwardsScan(undoLWM, (LogInstant)null);

        }
        else
        {
          // no checkpoint
          tf.useTransactionTable((Formatable)null);

          long start =
            LogCounter.makeLogInstantAsLong(
                            bootTimeLogFileNumber, LOG_FILE_HEADER_SIZE);

          // no checkpoint, start redo from the beginning of the
                    // file - assume this is the first log file
          firstLogFileNumber = bootTimeLogFileNumber;

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

        // open a transaction that is used for redo and rollback
        RawTransaction recoveryTransaction =
                    tf.startTransaction(
                        rawStoreFactory,
                        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;
       

                // Replication slave: When recovery has completed the
                // redo pass, the database is no longer in replication
                // slave mode and only the recover thread will access
                // this object until recover has complete. We
                // therefore do not need two versions of the log file
                // number anymore. From this point on, logFileNumber
                // is used for all references to the current log file
                // number; bootTimeLogFileNumber is no longer used.
                logFileNumber = bootTimeLogFileNumber;
       
        // 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);
            }
          }
          IOException accessException = null;
          try
          {
                        theLog =   privRandomAccessFile(logFile, "rw");
          }
          catch (IOException ioe)
          {
            theLog = null;
            accessException = ioe;
          }

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

            theLog = null;
            Monitor.logTextMessage(MessageId.LOG_CHANGED_DB_TO_READ_ONLY);
            if (accessException != null)
              Monitor.logThrowable(accessException);
            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 rwd mode.
            if(isWriteSynced)
            {
              //extend the file by wring zeros to it
              preAllocateNewLogFile(theLog);
              theLog.close();
              theLog = openLogFileInWriteMode(logFile);
              //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
            IOException accessException = null;
            try
            {
              if(isWriteSynced)
                theLog = openLogFileInWriteMode(logFile);
              else
                theLog = privRandomAccessFile(logFile, "rw");
            }
            catch (IOException ioe)
            {
              theLog = null;
                            accessException = ioe;
            }
                        if (theLog == null || !privCanWrite(logFile))
            {
              if (theLog != null)
                theLog.close();
              theLog = null;
              Monitor.logTextMessage(MessageId.LOG_CHANGED_DB_TO_READ_ONLY);
              if (accessException != null)
                Monitor.logThrowable(accessException)
              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,
View Full Code Here

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

    <P> MT- read only
  */
  private CheckpointOperation findCheckpoint(long checkpointInstant, FileLogger logger)
     throws IOException, StandardException, ClassNotFoundException
  {
    StreamLogScan scan = (StreamLogScan)
      openForwardsScan(checkpointInstant, (LogInstant)null);

    // estimated size of a checkpoint log record, which contains 3 longs
    // and assorted other log record overhead
    Loggable lop = logger.readLogRecord(scan, 100);
               
    scan.close();

    if (lop instanceof CheckpointOperation)
      return (CheckpointOperation)lop;
    else
      return null;
View Full Code Here

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

            long startInstant =
                LogCounter.makeLogInstantAsLong(logFileNumber,
                                                LOG_FILE_HEADER_SIZE);
            long logEndInstant = LOG_FILE_HEADER_SIZE;

            StreamLogScan scanOfHighestLogFile =
                (StreamLogScan) openForwardsScan(startInstant,
                                                 (LogInstant)null);
            ArrayInputStream scanInputStream = new ArrayInputStream();
            while(scanOfHighestLogFile.getNextRecord(scanInputStream, null, 0)
                  != null){
                logEndInstant = scanOfHighestLogFile.getLogRecordEnd();
            }

            endPosition = LogCounter.getLogFilePosition(logEndInstant);

            // endPosition and logFileNumber now point to the end of the
View Full Code Here

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

        long redoLWM     = LogCounter.INVALID_LOG_INSTANT;
        long undoLWM     = LogCounter.INVALID_LOG_INSTANT;
        long ttabInstant = LogCounter.INVALID_LOG_INSTANT;

        StreamLogScan redoScan = null;
        if (currentCheckpoint != null)
        { 
          Formatable transactionTable = null;

          // RESOLVE: sku
          // currentCheckpoint.getTransactionTable();

          // need to set the transaction table before the undo
          tf.useTransactionTable(transactionTable);

          redoLWM = currentCheckpoint.redoLWM();
          undoLWM = currentCheckpoint.undoLWM();

          if (transactionTable != null)
            ttabInstant = checkpointInstant;

          if (SanityManager.DEBUG)
          {
            if (SanityManager.DEBUG_ON(DBG_FLAG))
            {
              SanityManager.DEBUG(DBG_FLAG,
                                "Found checkpoint at " +
                                LogCounter.toDebugString(checkpointInstant) +
                                " " + currentCheckpoint.toString());
            }
          }

          firstLogFileNumber = LogCounter.getLogFileNumber(redoLWM);

          // figure out where the first interesting log file is.
          if (LogCounter.getLogFileNumber(undoLWM) <
                            firstLogFileNumber)
                    {
            firstLogFileNumber =
                            LogCounter.getLogFileNumber(undoLWM);
                    }


          // if the checkpoint record doesn't have a transaction
          // table, we need to rebuild it by scanning the log from
          // the undoLWM.  If it does have a transaction table, we
          // only need to scan the log from the redoLWM

          redoScan = (StreamLogScan)
                        openForwardsScan(undoLWM, (LogInstant)null);

        }
        else
        {
          // no checkpoint
          tf.useTransactionTable((Formatable)null);

          long start =
            LogCounter.makeLogInstantAsLong(
                            logFileNumber, LOG_FILE_HEADER_SIZE);

          // no checkpoint, start redo from the beginning of the
                    // file - assume this is the first log file
          firstLogFileNumber = logFileNumber;

          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 rwd mode.
            if(isWriteSynced)
            {
              //extend the file by wring zeros to it
              preAllocateNewLogFile(theLog);
              theLog.close();
              theLog = openLogFileInWriteMode(logFile);
              //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 = openLogFileInWriteMode(logFile);
              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,
View Full Code Here

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

    <P> MT- read only
  */
  private CheckpointOperation findCheckpoint(long checkpointInstant, FileLogger logger)
     throws IOException, StandardException, ClassNotFoundException
  {
    StreamLogScan scan = (StreamLogScan)
      openForwardsScan(checkpointInstant, (LogInstant)null);

    // estimated size of a checkpoint log record, which contains 3 longs
    // and assorted other log record overhead
    Loggable lop = logger.readLogRecord(scan, 100);
               
    scan.close();

    if (lop instanceof CheckpointOperation)
      return (CheckpointOperation)lop;
    else
      return null;
View Full Code Here

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

        long redoLWM     = LogCounter.INVALID_LOG_INSTANT;
        long undoLWM     = LogCounter.INVALID_LOG_INSTANT;
        long ttabInstant = LogCounter.INVALID_LOG_INSTANT;

        StreamLogScan redoScan = null;
        if (currentCheckpoint != null)
        { 
          Formatable transactionTable = null;

          // RESOLVE: sku
          // currentCheckpoint.getTransactionTable();

          // need to set the transaction table before the undo
          tf.useTransactionTable(transactionTable);

          redoLWM = currentCheckpoint.redoLWM();
          undoLWM = currentCheckpoint.undoLWM();

          if (transactionTable != null)
            ttabInstant = checkpointInstant;

          if (SanityManager.DEBUG)
          {
            if (SanityManager.DEBUG_ON(DBG_FLAG))
            {
              SanityManager.DEBUG(DBG_FLAG,
                                "Found checkpoint at " +
                                LogCounter.toDebugString(checkpointInstant) +
                                " " + currentCheckpoint.toString());
            }
          }

          firstLogFileNumber = LogCounter.getLogFileNumber(redoLWM);

          // figure out where the first interesting log file is.
          if (LogCounter.getLogFileNumber(undoLWM) <
                            firstLogFileNumber)
                    {
            firstLogFileNumber =
                            LogCounter.getLogFileNumber(undoLWM);
                    }


          // if the checkpoint record doesn't have a transaction
          // table, we need to rebuild it by scanning the log from
          // the undoLWM.  If it does have a transaction table, we
          // only need to scan the log from the redoLWM

          redoScan = (StreamLogScan)
                        openForwardsScan(undoLWM, (LogInstant)null);

        }
        else
        {
          // no checkpoint
          tf.useTransactionTable((Formatable)null);

          long start =
            LogCounter.makeLogInstantAsLong(
                            logFileNumber, LOG_FILE_HEADER_SIZE);

          // no checkpoint, start redo from the beginning of the
                    // file - assume this is the first log file
          firstLogFileNumber = logFileNumber;

          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 = openLogFileInWriteMode(logFile);
              //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 = openLogFileInWriteMode(logFile);
              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,
View Full Code Here

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

    <P> MT- read only
  */
  private CheckpointOperation findCheckpoint(long checkpointInstant, FileLogger logger)
     throws IOException, StandardException, ClassNotFoundException
  {
    StreamLogScan scan = (StreamLogScan)
      openForwardsScan(checkpointInstant, (LogInstant)null);

    // estimated size of a checkpoint log record, which contains 3 longs
    // and assorted other log record overhead
    Loggable lop = logger.readLogRecord(scan, 100);
               
    scan.close();

    if (lop instanceof CheckpointOperation)
      return (CheckpointOperation)lop;
    else
      return null;
View Full Code Here

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

    // to resize if the log record is larger than that.
    ArrayInputStream    rawInput    = null;

    try
    {
            StreamLogScan scanLog;

      if (prepareStartAt == null)
            {
                // don't know where to start, scan from end of log
        scanLog =
                    (StreamLogScan) logFactory.openBackwardsScan(prepareStopAt);
            }
      else
      {
        if (prepareStartAt.lessThan(prepareStopAt))
                {
                    // nothing to prepare!
          return;
                }

        scanLog = (StreamLogScan)
          logFactory.openBackwardsScan(
                        ((LogCounter) prepareStartAt).getValueAsLong(),
                        prepareStopAt);
      }

      if (SanityManager.DEBUG)
        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;
                }

        if (lop != null)
        {
                    // Reget locks based on log record.  reclaim all locks with
                    // a serializable locking policy, since we are only
                    // reclaiming write locks, isolation level does not matter
                    // much.

                    lop.reclaimPrepareLocks(
                        t,
                        t.newLockingPolicy(
                            LockingPolicy.MODE_RECORD,
                            TransactionController.ISOLATION_REPEATABLE_READ,
                            true));

          if (SanityManager.DEBUG)
                    {
                        if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
                        {
                            SanityManager.DEBUG(
                                LogToFile.DBG_FLAG,
                                "Reprepare log record at instant " +
                                scanLog.getInstant() + " : " + lop);
                        }
                    }

        }
      }
View Full Code Here

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

    // statistics
    int clrgenerated  = 0;
    int clrskipped    = 0;
    int logrecordseen = 0;

    StreamLogScan scanLog;
    Compensation  compensation = null;
    Undoable      lop          = null;

    // stream to read the log record - initial size 4096, scanLog needs
    // to resize if the log record is larget than that.
    ArrayInputStream    rawInput   = null;

    try
    {
      if (undoStartAt == null
            {
                // don't know where to start, rollback from end of log

        scanLog = (StreamLogScan)
          logFactory.openBackwardsScan(undoStopAt);
            }
      else
      {
        if (undoStartAt.lessThan(undoStopAt))
                {
                    // nothing to undo!
          return;
                }

        long undoStartInstant =
                    ((LogCounter) undoStartAt).getValueAsLong();

        scanLog = (StreamLogScan)
          logFactory.openBackwardsScan(undoStartInstant, undoStopAt);
      }

      if (SanityManager.DEBUG)
        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();
          rawInput.setLimit(savePosition, optionalDataLength);
 
          compensation = lop.generateUndo(t, rawInput);

          if (SanityManager.DEBUG)
                    {
                        if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
                        {
                            SanityManager.DEBUG(
                                LogToFile.DBG_FLAG,
                                "Rollback log record at instant " +
                                LogCounter.toDebugString(scanLog.getInstant()) +
                                " : " + lop);
                        }
                    }

          clrgenerated++;

          if (compensation != null)
          {
            // generateUndo may have read stuff off the
            // stream, reset it for the undo operation.
            rawInput.setLimit(savePosition, optionalDataLength);

            // log the compensation op that rolls back the
                        // operation at this instant
            t.logAndUndo(
                            compensation, new LogCounter(scanLog.getInstant()),
                            rawInput);

            compensation.releaseResource(t);
            compensation = null;
          }
View Full Code Here

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

    //////////////////////////////////////////////////////////////////////
    logIn.setData(logOutputBuffer.getByteArray());

    // use this scan to reconstitute operation to be undone
    // when we see a CLR in the redo scan
    StreamLogScan undoScan  = null;
    Loggable      op        = null;
    long          logEnd    = 0// we need to determine the log's true end

    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);
          }

          // at this point, logIn points to the optional
          // data of the loggable that is to be redone or to be
          // rolled back
         
          if (SanityManager.DEBUG)
                    {
                        if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
                        {
                            SanityManager.DEBUG(
                                LogToFile.DBG_FLAG,
                                "redoing " + op +
                                " instant = " +
                                LogCounter.toDebugString(instant));
                        }
                    }

          int dataLength = logIn.readInt();
          logIn.setLimit(logIn.getPosition(), dataLength);
                   
          // even though the log has already been written, we need to
          // tie the page to the log stream so that if redo failed
          // for some reasons, the log factory's corruption will stop
          // the corrupt page from flushing to disk.

          op.doMe(
                        recoveryTransaction,
                        new LogCounter(instant), logIn);

          op.releaseResource(recoveryTransaction);

          op = null;
        }

        // RESOLVE: to speed up undo, may want to update the
        // LastLogInstant in the transaction table. 
        // Right now, undo always start from the end of the log.

        // one last thing, if this is the last log record of the
        // transaction, then commit the transaction and clean up
        //
        // 'commit' even though the transaction maybe a rollback
        // because we already did all the rollback work when redoing
        // the CLRs.  Commit will only flush the log if this session
        // has written any transaction, so in this case, it is a noop.
        if (record.isComplete())
        {
          etranCount++;

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

          recoveryTransaction.commit();
        }
      } // while redoScan.getNextRecord() != null

            // If the scan ended in an empty file, update logEnd to reflect that
            // in order to avoid to continue logging to an older file
            long end = redoScan.getLogRecordEnd();
            if (end != LogCounter.INVALID_LOG_INSTANT
                && (LogCounter.getLogFileNumber(logEnd)
                    < LogCounter.getLogFileNumber(end))) {
                logEnd = end;
            }
    }
    catch (StandardException se)
    {
            throw StandardException.newException(
                    SQLState.LOG_REDO_FAILED, se, op);
    }
    finally
    {
      // close all the io streams
      redoScan.close();
      redoScan = null;

      if (undoScan != null)
      {
        undoScan.close();
        undoScan = null;
      }

      if (op != null)
        op.releaseResource(recoveryTransaction);
View Full Code Here
TOP
Copyright © 2018 www.massapi.com. 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.