Search in sources :

Example 1 with RePreparable

use of org.apache.derby.iapi.store.raw.RePreparable in project derby by apache.

the class FileLogger method reprepare.

/**
 * During recovery re-prepare a transaction.
 * <p>
 * After redo() and undo(), this routine is called on all outstanding
 * in-doubt (prepared) transactions.  This routine re-acquires all
 * logical write locks for operations in the xact, and then modifies
 * the transaction table entry to make the transaction look as if it
 * had just been prepared following startup after recovery.
 * <p>
 *
 * @param t                 is the transaction performing the re-prepare
 * @param prepareId         is the transaction ID to be re-prepared
 * @param prepareStopAt     is where the log instant (inclusive) where the
 *                          re-prepare should stop.
 * @param prepareStartAt    is the log instant (inclusive) where re-prepare
 *                          should begin, this is normally the log instant
 *                          of the last log record of the transaction that
 *                          is to be re-prepare.  If null, then re-prepare
 *                          starts from the end of the log.
 *
 * @exception  StandardException  Standard exception policy.
 */
public void reprepare(RawTransaction t, TransactionId prepareId, LogInstant prepareStopAt, LogInstant prepareStartAt) throws StandardException {
    if (SanityManager.DEBUG) {
        if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG)) {
            if (prepareStartAt != null) {
                SanityManager.DEBUG(LogToFile.DBG_FLAG, "----------------------------------------------------\n" + "\nBegin of RePrepare : " + prepareId.toString() + "start at " + prepareStartAt.toString() + " stop at " + prepareStopAt.toString() + "\n----------------------------------------------------\n");
            } else {
                SanityManager.DEBUG(LogToFile.DBG_FLAG, "----------------------------------------------------\n" + "\nBegin of Reprepare: " + prepareId.toString() + "start at end of log stop at " + prepareStopAt.toString() + "\n----------------------------------------------------\n");
            }
        }
    }
    // statistics
    int clrskipped = 0;
    int logrecordseen = 0;
    RePreparable lop = null;
    // stream to read the log record - initial size 4096, scanLog needs
    // 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));
                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);
                    }
                }
            }
        }
    } catch (ClassNotFoundException cnfe) {
        throw logFactory.markCorrupt(StandardException.newException(SQLState.LOG_CORRUPTED, cnfe));
    } catch (IOException ioe) {
        throw logFactory.markCorrupt(StandardException.newException(SQLState.LOG_READ_LOG_FOR_UNDO, ioe));
    } catch (StandardException se) {
        throw logFactory.markCorrupt(StandardException.newException(SQLState.LOG_UNDO_FAILED, se, prepareId, lop, (Object) null));
    } finally {
        if (rawInput != null) {
            try {
                rawInput.close();
            } catch (IOException ioe) {
                throw logFactory.markCorrupt(StandardException.newException(SQLState.LOG_READ_LOG_FOR_UNDO, ioe, prepareId));
            }
        }
    }
    if (SanityManager.DEBUG) {
        if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG)) {
            SanityManager.DEBUG(LogToFile.DBG_FLAG, "Finish prepare" + ", clr skipped = " + clrskipped + ", record seen = " + logrecordseen + "\n");
        }
    }
    if (SanityManager.DEBUG) {
        if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG)) {
            SanityManager.DEBUG(LogToFile.DBG_FLAG, "----------------------------------------------------\n" + "End of recovery rePrepare\n" + ", clr skipped = " + clrskipped + ", record seen = " + logrecordseen + "\n----------------------------------------------------\n");
        }
    }
}
Also used : StandardException(org.apache.derby.shared.common.error.StandardException) RePreparable(org.apache.derby.iapi.store.raw.RePreparable) LogRecord(org.apache.derby.impl.store.raw.log.LogRecord) ArrayInputStream(org.apache.derby.iapi.services.io.ArrayInputStream) LogCounter(org.apache.derby.impl.store.raw.log.LogCounter) IOException(java.io.IOException) StreamLogScan(org.apache.derby.impl.store.raw.log.StreamLogScan)

Aggregations

IOException (java.io.IOException)1 ArrayInputStream (org.apache.derby.iapi.services.io.ArrayInputStream)1 RePreparable (org.apache.derby.iapi.store.raw.RePreparable)1 LogCounter (org.apache.derby.impl.store.raw.log.LogCounter)1 LogRecord (org.apache.derby.impl.store.raw.log.LogRecord)1 StreamLogScan (org.apache.derby.impl.store.raw.log.StreamLogScan)1 StandardException (org.apache.derby.shared.common.error.StandardException)1