{
// The redo LWM is the current log instant. We are going to
// clean the cache shortly, any log record before this point
// will not ever need to be redone.
redoLWM_long = currentInstant();
redoLWM = new LogCounter(redoLWM_long);
// The undo LWM is what we need to rollback all transactions.
// Synchronize this with the starting of a new transaction so
// that the transaction factory can have a consistent view
// See FileLogger.logAndDo
LogCounter undoLWM = (LogCounter)(tf.firstUpdateInstant());
if (undoLWM == null)
undoLWM_long = redoLWM_long; // no active transaction
else
undoLWM_long = undoLWM.getValueAsLong();
}
/////////////////////////////////////////////////////
// clean the buffer cache
/////////////////////////////////////////////////////
df.checkpoint();
/////////////////////////////////////////////////////
// write out the checkpoint log record
/////////////////////////////////////////////////////
// send the checkpoint record to the log
Formatable transactionTable = tf.getTransactionTable();
CheckpointOperation nextCheckpoint =
new CheckpointOperation(
redoLWM_long, undoLWM_long, transactionTable);
cptran.logAndDo(nextCheckpoint);
LogCounter checkpointInstant =
(LogCounter)(cptran.getLastLogInstant());
if (checkpointInstant != null)
{
// since checkpoint is an internal transaction, I need to
// flush it to make sure it actually goes to the log
flush(checkpointInstant);
}
else
{
throw StandardException.newException(
SQLState.LOG_CANNOT_LOG_CHECKPOINT);
}
cptran.commit();
if (needCPTran)
{
cptran.close(); // if we started it, we will close it
cptran = null;
}
/////////////////////////////////////////////////////
// write out the log control file which contains the last
// successful checkpoint log record
/////////////////////////////////////////////////////
if (!writeControlFile(getControlFileName(),
checkpointInstant.getValueAsLong()))
{
throw StandardException.newException(
SQLState.LOG_CONTROL_FILE, getControlFileName());
}