📄 filelogger.java
字号:
SanityManager.DEBUG( LogToFile.DBG_FLAG, "Write log record: tranId=" + transactionId.toString() + " instant: " + logInstant.toString() + " length: " + completeLength + "\n" + operation + "\n"); } } return logInstant; } catch (IOException ioe) { // error writing to the log buffer if (inUserCode) { throw StandardException.newException( SQLState.LOG_WRITE_LOG_RECORD, ioe, operation); } else { throw StandardException.newException( SQLState.LOG_BUFFER_FULL, ioe, operation); } } } /** Writes out a compensation log record to the log stream, and call its doMe method to undo the change of a previous log operation. <P>MT - Not needed. A transaction must be single threaded thru undo, each RawTransaction has its own logger, therefore no need to synchronize. The RawTransaction must handle synchronizing with multiple threads during rollback. @param xact the transaction logging the change @param compensation the compensation log operation @param undoInstant the log instant of the operation that is to be rolled back @param in optional data input for the compenastion doMe method @return the instant in the log that can be used to identify the log record @exception StandardException Cloudscape Standard error policy */ public LogInstant logAndUndo(RawTransaction xact, Compensation compensation, LogInstant undoInstant, LimitObjectInput in) throws StandardException { boolean inUserCode = false; try { logOutputBuffer.reset(); TransactionId transactionId = xact.getId(); // write out the log header with the operation embedded logRecord.setValue(transactionId, compensation); inUserCode = true; logicalOut.writeObject(logRecord); inUserCode = false; // write out the undoInstant logicalOut.writeLong(((LogCounter)undoInstant).getValueAsLong()); // in this implemetaion, there is no optional data for the // compensation operation. Optional data for the rollback comes // from the undoable operation - and is passed into this call. int completeLength = logOutputBuffer.getPosition(); long instant = 0; if (logFactory.databaseEncrypted()) { // we must pad the encryption data to be multiple of block // size, which is logFactory.getEncryptionBlockSize() int encryptedLength = completeLength; if ((encryptedLength % logFactory.getEncryptionBlockSize()) != 0) encryptedLength = encryptedLength + logFactory.getEncryptionBlockSize() - (encryptedLength % logFactory.getEncryptionBlockSize()); if (encryptionBuffer == null || encryptionBuffer.length < encryptedLength) encryptionBuffer = new byte[encryptedLength]; System.arraycopy(logOutputBuffer.getByteArray(), 0, encryptionBuffer, 0, completeLength); // do not bother to clear out the padding area int len = logFactory.encrypt(encryptionBuffer, 0, encryptedLength, encryptionBuffer, 0); if (SanityManager.DEBUG) SanityManager.ASSERT(len == encryptedLength, "encrypted log buffer length != log buffer len"); instant = logFactory. appendLogRecord(encryptionBuffer, 0, encryptedLength, null, 0, 0); } else { instant = logFactory. appendLogRecord(logOutputBuffer.getByteArray(), 0, completeLength, null, 0, 0); } LogInstant logInstant = new LogCounter(instant); if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG)) { SanityManager.DEBUG( LogToFile.DBG_FLAG, "Write CLR: Xact: " + transactionId.toString() + "clrinstant: " + logInstant.toString() + " undoinstant " + undoInstant + "\n"); } } try { // in and dataLength contains optional data that was written // to the log during a previous call to logAndDo. compensation.doMe(xact, logInstant, in); } catch (StandardException se) { throw logFactory.markCorrupt( StandardException.newException( SQLState.LOG_DO_ME_FAIL, se, compensation)); } catch (IOException ioe) { throw logFactory.markCorrupt( StandardException.newException( SQLState.LOG_DO_ME_FAIL, ioe, compensation)); } return logInstant; } catch (IOException ioe) { if (inUserCode) { throw StandardException.newException( SQLState.LOG_WRITE_LOG_RECORD, ioe, compensation); } else { throw StandardException.newException( SQLState.LOG_BUFFER_FULL, ioe, compensation); } } } /** Flush the log up to the given log instant. <P>MT - not needed, wrapper method @exception StandardException cannot sync log file */ public void flush(LogInstant where) throws StandardException { if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG)) { SanityManager.DEBUG( LogToFile.DBG_FLAG, "Flush log to " + where.toString()); } } logFactory.flush(where); } /** Flush all outstanding log to disk. <P>MT - not needed, wrapper method @exception StandardException cannot sync log file */ public void flushAll () throws StandardException { logFactory.flushAll(); } /** * 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)); // 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); } } } } } 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 {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -