Class ReplicationLogScan


  • class ReplicationLogScan
    extends java.lang.Object

    Scan a chunk of log received from the master. The log chunk (byte[] logToScan) is assumed to always contain (an unknown) number of complete log records. If the last log record is incomplete, something is wrong. This will raise a StandardException, and will probably mean that replication has to be aborted. That decision is not made here, though.

    When a new chunk of log records is to be scanned, ReplicationLogScan is initialized by calling init(...). Every time next() is called after that, ReplicationLogScan reads a new log record from logToScan. If next() returns true, the next log record was successfully read. The information in this last read log record either indicates that a log file switch has taken place on the master (isLogSwitch() = true) or it is a normal log record which information can be retrieved by using the get-methods (if isLogRecord() = true).

    Threads: The class does not provide thread synchronization since it is assumed that only one thread will be receiving and applying log per replicated database when in slave mode. Since a ReplicationLogScan object belongs to only one slave database, this means that only one thread will access the object.

    The format of the log chunk byte[] is defined in org.apache.derby.impl.store.raw.log.LogAccessFile

    See Also:
    LogAccessFile
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private byte[] currentData  
      private int currentDataOffset  
      private long currentInstant  
      private int currentPosition  
      private boolean hasInfo
      hasInfo = true when the scan will return meaningful information, either in the form of a log record (in which case the above variables will be set), or when it has found a log record indicating that a log file switch has taken place on the master (isLogSwitch = true). hasInfo = false before next() is called for the first time, after next() has reached the end of logToScan and if an error occured when parsing logToScan (i.e.
      private boolean isLogSwitch
      true if the last read log record indicates a log switch, false if it is a normal log record private boolean isLogSwitch;
      private byte[] logToScan  
    • Constructor Summary

      Constructors 
      Modifier Constructor Description
      protected ReplicationLogScan()  
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      protected byte[] getData()
      Method to get the data byte[] read by the last call to next().
      protected int getDataLength()  
      protected long getInstant()  
      protected boolean hasValidInformation()
      Used to determine whether or not the last call to next() was successful.
      protected void init​(byte[] logToScan)
      Set all variables to default values, and makes logToScan the byte[] that will be scanned for log records.
      protected boolean isLogFileSwitch()
      Used to determine whether the last call to next() found a log file switch
      protected boolean isLogRecord()
      Used to determine whether the last call to next() read a log record
      protected boolean next()
      Read the next log record in logToScan.
      private void retrieveBytes​(byte[] readInto, int length)
      Copy length number of bytes from logToScan into readInto.
      private int retrieveInt()
      Read an int from logToScan.
      private long retrieveLong()
      Read a long from logToScan.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • logToScan

        private byte[] logToScan
      • currentPosition

        private int currentPosition
      • currentInstant

        private long currentInstant
      • currentDataOffset

        private int currentDataOffset
      • currentData

        private byte[] currentData
      • hasInfo

        private boolean hasInfo
        hasInfo = true when the scan will return meaningful information, either in the form of a log record (in which case the above variables will be set), or when it has found a log record indicating that a log file switch has taken place on the master (isLogSwitch = true). hasInfo = false before next() is called for the first time, after next() has reached the end of logToScan and if an error occured when parsing logToScan (i.e. when next() has thrown a StandardException)
      • isLogSwitch

        private boolean isLogSwitch
        true if the last read log record indicates a log switch, false if it is a normal log record private boolean isLogSwitch;
    • Constructor Detail

      • ReplicationLogScan

        protected ReplicationLogScan()
    • Method Detail

      • init

        protected void init​(byte[] logToScan)
        Set all variables to default values, and makes logToScan the byte[] that will be scanned for log records.
        Parameters:
        logToScan - A chunk of log records received from the master
      • next

        protected boolean next()
                        throws StandardException

        Read the next log record in logToScan. The information in this log record can be read by using the getXXX methods.

        Side effects:

        On a successful read (return true): either...

        ... the scan read a log record indicating that a log file switch has taken place on the master, in which case isLogFileSwitch() returns true. In this case, getXXX will not contain valid data. Asserts handle calls to these methods when in sane mode. currentPosition is updated to point to the byte immediately following this log file switch log record.

        ... or the scan read a normal log record, in which case isLogRecord() returns true. Also sets currentInstant and currentData, and updates currentPosition to point to the byte immediatly following the log record. In this case, getXXX will return meaningful information about the log record.

        If there are no more log records in logToScan (returns false) or a problem occurs (throws StandardException): setting hasInfo = false

        Returns:
        true if a log record was successfully read, false if end of logToScan has been reached.
        Throws:
        StandardException - if logToScan is found to be corrupted.
      • getInstant

        protected long getInstant()
                           throws java.util.NoSuchElementException
        Returns:
        The instant of the log record read by the last call to next(). Only returns meaningful information if isLogRecord() returns true.
        Throws:
        java.util.NoSuchElementException - if next() has not been called or if there are no more log records in this chunk of log. Should never be thrown unless ReplicationLogScan is used in a wrong way.
      • getDataLength

        protected int getDataLength()
                             throws java.util.NoSuchElementException
        Returns:
        The number of bytes in the byte[] returned by getData() for the log record read by the last call to next(). Only returns meaningful information if isLogRecord() returns true.
        Throws:
        java.util.NoSuchElementException - if next() has not been called or if there are no more log records in this chunk of log. Should never be thrown unless ReplicationLogScan is used in a wrong way.
      • getData

        protected byte[] getData()
                          throws java.util.NoSuchElementException
        Method to get the data byte[] read by the last call to next(). Note that this byte[] contains both byte[] data and byte[] optional_data from LogAccessFile. To split this byte[] into data and optional_data, we would need to create a Loggable object from it because the log does not provide information on where to split. There is no need to split since this byte[] will only be written to the slave log anyway. If it was split, LogAccessFile would simply merge them when writing to file.
        Returns:
        The byte[] containing data+optional_data of the log record read by the last call to next(). Only returns meaningful information if isLogRecord() returns true.
        Throws:
        java.util.NoSuchElementException - if next() has not been called or if there are no more log records in this chunk of log. Should never be thrown unless ReplicationLogScan is used in a wrong way.
      • hasValidInformation

        protected boolean hasValidInformation()
        Used to determine whether or not the last call to next() was successful.
        Returns:
        true if next() has been called and the end of the log chunk has not yet been reached. Returns the same answer as the last call to next() did. Use isLogFileSwitch() and isLogRecord() to find out if the current log record indicates a log file switch or is a normal log record.
      • isLogRecord

        protected boolean isLogRecord()
                               throws java.util.NoSuchElementException
        Used to determine whether the last call to next() read a log record
        Returns:
        true if the last call to next() found a normal log record.
        Throws:
        java.util.NoSuchElementException - if next() has not been called or if there are no more log records in this chunk of log. Should never be thrown unless ReplicationLogScan is used in a wrong way.
      • isLogFileSwitch

        protected boolean isLogFileSwitch()
                                   throws java.util.NoSuchElementException
        Used to determine whether the last call to next() found a log file switch
        Returns:
        true if the last call to next() found a log record indicating a log file switch has taken place on the master.
        Throws:
        java.util.NoSuchElementException - if next() has not been called or if there are no more log records in this chunk of log. Should never be thrown unless ReplicationLogScan is used in a wrong way.
      • retrieveBytes

        private void retrieveBytes​(byte[] readInto,
                                   int length)
                            throws StandardException
        Copy length number of bytes from logToScan into readInto. Starts to copy from currentPosition. Also increments currentPosition by length.
        Parameters:
        readInto - The byte[] copied to
        length - The number of bytes copied from logToScan to readInto
        Throws:
        StandardException - if there are less then length bytes left to read in logToScan, meaning that the chunk of log is corrupt.
      • retrieveInt

        private int retrieveInt()
                         throws StandardException
        Read an int from logToScan. Also increments currentPosition by 4 (the number of bytes in an int).
        Returns:
        an int read from logToScan
        Throws:
        StandardException - if there are less then 4 bytes left to read in logToScan, meaning that the chunk of log is corrupt.
      • retrieveLong

        private long retrieveLong()
                           throws StandardException
        Read a long from logToScan. Also increments currentPosition by 8 (the number of bytes in a long).
        Returns:
        a long read from logToScan
        Throws:
        StandardException - if there are less then 8 bytes left to read in logToScan, meaning that the chunk of log is corrupt.