Search in sources :

Example 1 with RecordReadStatus

use of org.apache.asterix.common.transactions.ILogRecord.RecordReadStatus in project asterixdb by apache.

the class LogReader method read.

//for random reading
@Override
public ILogRecord read(long LSN) throws ACIDException {
    readLSN = LSN;
    //wait for the log to be flushed if needed before trying to read it.
    synchronized (flushLSN) {
        while (readLSN >= flushLSN.get()) {
            try {
                flushLSN.wait();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
    try {
        if (logFile == null) {
            //get the log file which contains readLSN
            getLogFile();
            fillLogReadBuffer();
        } else if (readLSN < fileBeginLSN || readLSN >= fileBeginLSN + logFile.size()) {
            //log is not in the current log file
            logFile.close();
            getLogFile();
            fillLogReadBuffer();
        } else if (readLSN < bufferBeginLSN || readLSN >= bufferBeginLSN + readBuffer.limit()) {
            //log is not in the current read buffer
            fillLogReadBuffer();
        } else {
            //log is either completely in the current read buffer or truncated
            readBuffer.position((int) (readLSN - bufferBeginLSN));
        }
    } catch (IOException e) {
        throw new ACIDException(e);
    }
    ByteBuffer readBuffer = this.readBuffer;
    while (true) {
        RecordReadStatus status = logRecord.readLogRecord(readBuffer);
        switch(status) {
            case LARGE_RECORD:
                {
                    readBuffer = ByteBuffer.allocate(logRecord.getLogSize());
                    fillLogReadBuffer(logRecord.getLogSize(), readBuffer);
                    //now see what we have in the refilled buffer
                    continue;
                }
            case TRUNCATED:
                {
                    if (!fillLogReadBuffer()) {
                        throw new IllegalStateException("Could not read LSN(" + LSN + ") from log file id " + logFile.getLogFileId());
                    }
                    //now read the complete log record
                    continue;
                }
            case BAD_CHKSUM:
                {
                    throw new ACIDException("Log record has incorrect checksum");
                }
            case OK:
                break;
            default:
                throw new IllegalStateException("Unexpected log read status: " + status);
        }
        break;
    }
    logRecord.setLSN(readLSN);
    readLSN += logRecord.getLogSize();
    return logRecord;
}
Also used : RecordReadStatus(org.apache.asterix.common.transactions.ILogRecord.RecordReadStatus) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) ACIDException(org.apache.asterix.common.exceptions.ACIDException)

Example 2 with RecordReadStatus

use of org.apache.asterix.common.transactions.ILogRecord.RecordReadStatus in project asterixdb by apache.

the class LogReader method next.

/**
     * Get the next log record from the log file.
     *
     * @return A deserialized log record, or null if we have reached the end of the file.
     * @throws ACIDException
     */
@Override
public ILogRecord next() throws ACIDException {
    if (waitForFlushOrReturnIfEOF() == ReturnState.EOF) {
        return null;
    }
    if (readBuffer.position() == readBuffer.limit()) {
        boolean hasRemaining = refillLogReadBuffer();
        if (!hasRemaining && isRecoveryMode && readLSN < flushLSN.get()) {
            LOGGER.severe("Transaction log ends before expected. Log files may be missing.");
            return null;
        }
    }
    ByteBuffer readBuffer = this.readBuffer;
    boolean refilled = false;
    while (true) {
        RecordReadStatus status = logRecord.readLogRecord(readBuffer);
        switch(status) {
            case TRUNCATED:
                {
                    if (!refilled) {
                        //we may have just read off the end of the buffer, so try refiling it
                        if (!refillLogReadBuffer()) {
                            return null;
                        }
                        refilled = true;
                        //now see what we have in the refilled buffer
                        continue;
                    } else {
                        LOGGER.info("Log file has truncated log records.");
                        return null;
                    }
                }
            case LARGE_RECORD:
                {
                    readBuffer = ByteBuffer.allocate(logRecord.getLogSize());
                    fillLogReadBuffer(logRecord.getLogSize(), readBuffer);
                    //now see what we have in the expanded buffer
                    continue;
                }
            case BAD_CHKSUM:
                {
                    LOGGER.severe("Transaction log contains corrupt log records (perhaps due to medium error). Stopping recovery early.");
                    return null;
                }
            case OK:
                break;
            default:
                throw new IllegalStateException("Unexpected log read status: " + status);
        }
        // break the loop by default
        break;
    }
    logRecord.setLSN(readLSN);
    readLSN += logRecord.getLogSize();
    return logRecord;
}
Also used : RecordReadStatus(org.apache.asterix.common.transactions.ILogRecord.RecordReadStatus) ByteBuffer(java.nio.ByteBuffer)

Aggregations

ByteBuffer (java.nio.ByteBuffer)2 RecordReadStatus (org.apache.asterix.common.transactions.ILogRecord.RecordReadStatus)2 IOException (java.io.IOException)1 ACIDException (org.apache.asterix.common.exceptions.ACIDException)1