| java.lang.Object org.apache.derby.impl.store.raw.log.LogToFile
LogToFile | final public class LogToFile implements LogFactory,ModuleControl,ModuleSupportable,Serviceable,java.security.PrivilegedExceptionAction(Code) | | This is an implementation of the log using a non-circular file system file.
No support for incremental log backup or media recovery.
Only crash recovery is supported.
The 'log' is a stream of log records. The 'log' is implemented as
a series of numbered log files. These numbered log files are logically
continuous so a transaction can have log records that span multiple log files.
A single log record cannot span more then one log file. The log file number
is monotonically increasing.
The log belongs to a log factory of a RawStore. In the current implementation,
each RawStore only has one log factory, so each RawStore only has one log
(which composed of multiple log files).
At any given time, a log factory only writes new log records to one log file,
this log file is called the 'current log file'.
A log file is named loglogNumber.dat
Everytime a checkpoint is taken, a new log file is created and all subsequent
log records will go to the new log file. After a checkpoint is taken, old
and useless log files will be deleted.
RawStore exposes a checkpoint method which clients can call, or a checkpoint is
taken automatically by the RawStore when
- the log file grows beyond a certain size (configurable, default 100K bytes)
- RawStore is shutdown and a checkpoint hasn't been done "for a while"
- RawStore is recovered and a checkpoint hasn't been done "for a while"
This LogFactory is responsible for the formats of 2 kinds of file: the log
file and the log control file. And it is responsible for the format of the
log record wrapper.
Format of log control file
|
Method Summary | |
public void | abortLogBackup() | protected long | appendLogRecord(byte[] data, int offset, int length, byte[] optionalData, int optionalDataOffset, int optionalDataLength) Append length bytes of data to the log prepended by a long log instant
and followed by 4 bytes of length information.
This method is synchronized to ensure log records are added sequentially
to the end of the log.
MT- single threaded through this log factory. | public void | boot(boolean create, Properties startParams) Boot up the log factory. | public boolean | canSupport(Properties startParams) | boolean | checkVersion(int requiredMajorVersion, int requiredMinorVersion) Check to see if a database has been upgraded to the required
level in order to use a store feature. | public boolean | checkVersion(int requiredMajorVersion, int requiredMinorVersion, String feature) Check to see if a database has been upgraded to the required
level in order to use a store feature.
Parameters: requiredMajorVersion - required database Engine major version Parameters: requiredMinorVersion - required database Engine minor version Parameters: feature - Non-null to throw an exception, null to return the state of the version match. | public boolean | checkpoint(RawStoreFactory rsf, DataFactory df, TransactionFactory tf, boolean wait) Checkpoint the rawStore.
MT- Only one checkpoint is to be taking place at any given time.
The steps of a checkpoint are
- switch to a new log file if possible
freeze the log (for the transition to a new log file)
flush current log file
create and flush the new log file (with file number 1 higher
than the previous log file). | public void | checkpointInRFR(LogInstant cinstant, long redoLWM, DataFactory df) | protected boolean | checkpointWithTran(RawTransaction cptran, RawStoreFactory rsf, DataFactory df, TransactionFactory tf) | protected synchronized long | currentInstant() Get the current log instant - this is the log instant of the Next log
record to be written out
MT - This method is synchronized to ensure that it always points to
the end of a log record, not the middle of one. | final public boolean | databaseEncrypted() | public int | decrypt(byte[] ciphertext, int offset, int length, byte[] cleartext, int outputOffset) | public void | deleteLogFileAfterCheckpointLogFile() | public void | deleteOnlineArchivedLogFiles() | public void | disableLogArchiveMode() | public void | enableLogArchiveMode() | public int | encrypt(byte[] cleartext, int offset, int length, byte[] ciphertext, int outputOffset) | public void | endLogBackup(File toDir) | protected synchronized long | endPosition() | public void | flush(LogInstant where) Flush all unwritten log record up to the log instance indicated to disk
and sync. | protected void | flush(long fileNumber, long wherePosition) Flush the log such that the log record written with the instant
wherePosition is guaranteed to be on disk. | public void | flushAll() Flush all unwritten log record to disk and sync. | public void | freezePersistentStore() | public String | getCanonicalLogPath() | public int | getEncryptedDataLength(int length) returns the length that will make the data to be multiple of encryption
block size based on the given length. | public int | getEncryptionBlockSize() | public synchronized LogInstant | getFirstUnflushedInstant() Get the instant of the first record which was not
flushed. | public StorageFile | getLogDirectory() | public void | getLogFactoryProperties(PersistentSet set) | protected StorageRandomAccessFile | getLogFileAtBeginning(long filenumber) Open a log file and position the file at the beginning. | protected StorageRandomAccessFile | getLogFileAtPosition(long logInstant) | public StorageRandomAccessFile | getLogFileToSimulateCorruption(long filenum) | public Logger | getLogger() | public int | getTypeFormatId() Return my format identifier. | public boolean | inRFR() | public boolean | isCheckpointInLastLogFile() | public boolean | logArchived() | protected void | logErrMsg(String msg) | protected void | logErrMsg(Throwable t) | public StandardException | markCorrupt(StandardException originalError) | protected LogScan | openBackwardsScan(long startAt, LogInstant stopAt) Scan backward from start position. | protected LogScan | openBackwardsScan(LogInstant stopAt) Scan backward from end of log. | public ScanHandle | openFlushedScan(DatabaseInstant start, int groupsIWant) | public LogScan | openForwardsFlushedScan(LogInstant startAt) Open a forward scan of the transaction log. | protected LogScan | openForwardsScan(long startAt, LogInstant stopAt) Scan Forward from start position.
MT- read only
Parameters: startAt - - if startAt == INVALID_LOG_INSTANT,start from the beginning of the log. | public LogScan | openForwardsScan(LogInstant startAt, LogInstant stopAt) | public int | performWork(ContextManager context) | protected boolean | privCanWrite(StorageFile file) | protected boolean | privDelete(StorageFile file) | protected boolean | privExists(StorageFile file) | protected boolean | privMkdirs(StorageFile file) | public void | recover(RawStoreFactory rsf, DataFactory df, TransactionFactory tf) Recover the rawStore to a consistent state using the log.
In this implementation, the log is a stream of log records stored in
one or more flat files. | final public Object | run() | public boolean | serviceASAP() | public boolean | serviceImmediately() | public void | setDatabaseEncrypted(boolean flushLog) | public void | startLogBackup(File toDir) | public void | startNewLogFile() | public void | stop() | protected void | testLogFull() Simulate a log full condition
if TEST_LOG_FULL is set to true, then the property
TEST_RECORD_TO_FILL_LOG indicates the number of times this function is
call before an IOException simulating a log full condition is raised. | public void | unfreezePersistentStore() | boolean | writeControlFile(StorageFile logControlFileName, long value) Carefully write out this value to the control file. |
DUMP_LOG_FROM_LOG_FILE | final public static String DUMP_LOG_FROM_LOG_FILE(Code) | | |
LOG_FILE_HEADER_PREVIOUS_LOG_INSTANT_OFFSET | final protected static int LOG_FILE_HEADER_PREVIOUS_LOG_INSTANT_OFFSET(Code) | | |
LOG_FILE_HEADER_SIZE | final public static int LOG_FILE_HEADER_SIZE(Code) | | |
LOG_RECORD_OVERHEAD | final public static int LOG_RECORD_OVERHEAD(Code) | | |
LOG_SYNC_STATISTICS | final protected static String LOG_SYNC_STATISTICS(Code) | | |
ReadOnlyDB | protected boolean ReadOnlyDB(Code) | | |
TEST_LOG_FULL | final public static String TEST_LOG_FULL(Code) | | Set to true if we want to simulate a log full condition
|
TEST_LOG_INCOMPLETE_LOG_WRITE | final public static String TEST_LOG_INCOMPLETE_LOG_WRITE(Code) | | Set to true if we want the up comming log record to be only partially
written. The database is corrupted if not immediately shutdown.
Set TEST_LOG_PARTIAL_LOG_WRITE_NUM_BYTES to the number of bytes to write
out, default is 1 byte.
|
TEST_LOG_PARTIAL_LOG_WRITE_NUM_BYTES | final public static String TEST_LOG_PARTIAL_LOG_WRITE_NUM_BYTES(Code) | | Set to the number of bytes we want the next log record to actually write
out, only used when TEST_LOG_INCOMPLETE_LOG_WRITE is on. Default is 1
byte.
|
TEST_LOG_SWITCH_LOG | final public static String TEST_LOG_SWITCH_LOG(Code) | | Set to true if we want the checkpoint to only switch the log but not
actually do the checkpoint
|
TEST_MAX_LOGFILE_NUMBER | final public static String TEST_MAX_LOGFILE_NUMBER(Code) | | Set to true if we want to simulate max possible log file number is
being used.
|
TEST_RECORD_TO_FILL_LOG | final public static String TEST_RECORD_TO_FILL_LOG(Code) | | Set to the number of log record we want to write before the log is
simulated to be full.
|
TEST_SWITCH_LOG_FAIL1 | final public static String TEST_SWITCH_LOG_FAIL1(Code) | | Set to true if we want to simulate a log full condition while switching log
|
TEST_SWITCH_LOG_FAIL2 | final public static String TEST_SWITCH_LOG_FAIL2(Code) | | |
checkpointInstant | long checkpointInstant(Code) | | |
corrupt | protected volatile StandardException corrupt(Code) | | If not null then something is corrupt in the raw store and this represents the original error.
|
endPosition | protected long endPosition(Code) | | |
firstLogFileNumber | long firstLogFileNumber(Code) | | |
lastFlush | long lastFlush(Code) | | |
logFileNumber | long logFileNumber(Code) | | |
test_logWritten | int test_logWritten(Code) | | DEBUG test only
|
test_numRecordToFillLog | int test_numRecordToFillLog(Code) | | |
LogToFile | public LogToFile()(Code) | | MT- not needed for constructor
|
abortLogBackup | public void abortLogBackup()(Code) | | |
appendLogRecord | protected long appendLogRecord(byte[] data, int offset, int length, byte[] optionalData, int optionalDataOffset, int optionalDataLength) throws StandardException(Code) | | Append length bytes of data to the log prepended by a long log instant
and followed by 4 bytes of length information.
This method is synchronized to ensure log records are added sequentially
to the end of the log.
MT- single threaded through this log factory. Log records are
appended one at a time.
exception: StandardException - Log Full. |
checkVersion | boolean checkVersion(int requiredMajorVersion, int requiredMinorVersion)(Code) | | Check to see if a database has been upgraded to the required
level in order to use a store feature.
Parameters: requiredMajorVersion - required database Engine major version Parameters: requiredMinorVersion - required database Engine minor version True if the database has been upgraded to the required level, false otherwise. |
checkVersion | public boolean checkVersion(int requiredMajorVersion, int requiredMinorVersion, String feature) throws StandardException(Code) | | Check to see if a database has been upgraded to the required
level in order to use a store feature.
Parameters: requiredMajorVersion - required database Engine major version Parameters: requiredMinorVersion - required database Engine minor version Parameters: feature - Non-null to throw an exception, null to return the state of the version match. true if the database has been upgraded to the required level, false otherwise. exception: StandardException - if the database is not at the require version when feature feature is not null . |
checkpoint | public boolean checkpoint(RawStoreFactory rsf, DataFactory df, TransactionFactory tf, boolean wait) throws StandardException(Code) | | Checkpoint the rawStore.
MT- Only one checkpoint is to be taking place at any given time.
The steps of a checkpoint are
- switch to a new log file if possible
freeze the log (for the transition to a new log file)
flush current log file
create and flush the new log file (with file number 1 higher
than the previous log file). The new log file becomes the
current log file.
unfreeze the log
- start checkpoint transaction
- gather interesting information about the rawStore:
the current log instant (redoLWM)
the earliest active transaction begin tran log record
instant (undoLWM), all the truncation LWM set by clients
of raw store (replication)
- clean the buffer cache
- log the next checkpoint log record, which contains
(repPoint, undoLWM, redoLWM) and commit checkpoint transaction.
- synchronously write the control file containing the next checkpoint
log record log instant
- the new checkpoint becomes the current checkpoint.
Somewhere near the beginning of each log file should be a
checkpoint log record (not guarenteed to be there)
- see if the log can be truncated
The earliest useful log record is determined by the repPoint and the
undoLWM, whichever is earlier.
Every log file whose log file number is smaller than the earliest
useful log record's log file number can be deleted.
Transactions can be at the following states w/r to a checkpoint -
consider the log as a continous stream and not as series of log
files for the sake of clarity.
|(BT)-------(ET)| marks the begin and end of a transaction.
. checkpoint started
. |__undoLWM |
. V |___redoLWM
. |___TruncationLWM
. |
. V
1 |-----------------|
2 |--------------------------------|
3 |-------|
4 |--------------------------------------(end of log)
5 |-^-|
. Checkpoint Log Record
---A--->|<-------B--------->|<-------------C-----------
There are only 3 periods of interest :
A) before undoLWM, B) between undo and redo LWM, C) after redoLWM.
Transaction 1 started in A and terminates in B.
During redo, we should only see log records and endXact from this
transaction in the first phase (between undoLWM and redoLWM). No
beginXact log record for this transaction will be seen.
Transaction 2 started in B (right on the undoLWM) and terminated in C.
Any transaction that terminates in C must have a beginXact at or
after undoLWM. In other words, no transaction can span A, B and C.
During redo, we will see beginXact, other log records and endXact
for this transaction.
Transaction 3 started in B and ended in B.
During redo, we will see beginXact, other log records and endXact
for this transaction.
Transaction 4 begins in B and never ends.
During redo, we will see beginXact, other log records.
In undo, this loser transaction will be rolled back.
Transaction 5 is the transaction taking the checkpoint.
The checkpoint action started way back in time but the checkpoint
log record is only written after the buffer cache has been flushed.
Note that if any time elapse between taking the undoLWM and the
redoLWM, then it will create a 4th period of interest.
exception: StandardException - - encounter exception while doing checkpoint. |
currentInstant | protected synchronized long currentInstant()(Code) | | Get the current log instant - this is the log instant of the Next log
record to be written out
MT - This method is synchronized to ensure that it always points to
the end of a log record, not the middle of one.
|
databaseEncrypted | final public boolean databaseEncrypted()(Code) | | |
deleteLogFileAfterCheckpointLogFile | public void deleteLogFileAfterCheckpointLogFile() throws StandardException(Code) | | |
deleteOnlineArchivedLogFiles | public void deleteOnlineArchivedLogFiles()(Code) | | |
endPosition | protected synchronized long endPosition()(Code) | | |
flush | public void flush(LogInstant where) throws StandardException(Code) | | Flush all unwritten log record up to the log instance indicated to disk
and sync.
Also check to see if database is frozen or corrupt.
MT - not needed, wrapper method
Parameters: where - flush log up to here exception: StandardException - Standard Cloudscape error policy |
flush | protected void flush(long fileNumber, long wherePosition) throws StandardException(Code) | | Flush the log such that the log record written with the instant
wherePosition is guaranteed to be on disk.
MT - only one flush is allowed to be taking place at any given time
(RESOLVE: right now it single thread thru the log factory while the log
is frozen)
exception: StandardException - cannot sync log file |
flushAll | public void flushAll() throws StandardException(Code) | | Flush all unwritten log record to disk and sync.
Also check to see if database is frozen or corrupt.
MT - not needed, wrapper method
exception: StandardException - Standard Cloudscape error policy |
freezePersistentStore | public void freezePersistentStore() throws StandardException(Code) | | Backup restore - stop sending log record to the log stream
exception: StandardException - Standard Cloudscape error policy |
getCanonicalLogPath | public String getCanonicalLogPath()(Code) | | |
getEncryptedDataLength | public int getEncryptedDataLength(int length)(Code) | | returns the length that will make the data to be multiple of encryption
block size based on the given length. Block cipher algorithms like DES
and Blowfish ..etc require their input to be an exact multiple of the block size.
|
getEncryptionBlockSize | public int getEncryptionBlockSize()(Code) | | return the encryption block size used during encrypted db creation
|
getFirstUnflushedInstant | public synchronized LogInstant getFirstUnflushedInstant()(Code) | | Get the instant of the first record which was not
flushed.
This only works after running recovery the first time.
MT - RESOLVE:
|
getTypeFormatId | public int getTypeFormatId()(Code) | | Return my format identifier.
|
inRFR | public boolean inRFR()(Code) | | |
logArchived | public boolean logArchived()(Code) | | Backup restore - is the log being archived to some directory?
if log archive mode is enabled return true else false
|
logErrMsg | protected void logErrMsg(String msg)(Code) | | Print error message to user about the log
MT - not needed, informational only
|
logErrMsg | protected void logErrMsg(Throwable t)(Code) | | Print error message to user about the log
MT - not needed, informational only
|
openForwardsScan | protected LogScan openForwardsScan(long startAt, LogInstant stopAt) throws IOException, StandardException(Code) | | Scan Forward from start position.
MT- read only
Parameters: startAt - - if startAt == INVALID_LOG_INSTANT,start from the beginning of the log. Otherwise, start scan from startAt. Parameters: stopAt - - if not null, stop at this log instant (inclusive).Otherwise, stop at the end of the log exception: IOException - cannot access the log exception: StandardException - Standard Cloudscape error policy |
recover | public void recover(RawStoreFactory rsf, DataFactory df, TransactionFactory tf) throws StandardException(Code) | | Recover the rawStore to a consistent state using the log.
In this implementation, the log is a stream of log records stored in
one or more flat files. Recovery is done in 2 passes: redo and undo.
Redo pass
In the redo pass, reconstruct the state of the rawstore by
repeating exactly what happened before as recorded in the log.
Undo pass
In the undo pass, all incomplete transactions are rolled back in
the order from the most recently started to the oldest.
MT - synchronization provided by caller - RawStore boot.
This method is guaranteed to be the only method being called and can
assume single thread access on all fields.
See Also: Loggable.needsRedo See Also: FileLogger.redo exception: StandardException - Standard Cloudscape error policy |
serviceASAP | public boolean serviceASAP()(Code) | | |
serviceImmediately | public boolean serviceImmediately()(Code) | | |
stop | public void stop()(Code) | | Stop the log factory
MT- caller provide synchronization
(RESOLVE: this should be called AFTER dataFactory and transFactory are
stopped)
|
testLogFull | protected void testLogFull() throws IOException(Code) | | Simulate a log full condition
if TEST_LOG_FULL is set to true, then the property
TEST_RECORD_TO_FILL_LOG indicates the number of times this function is
call before an IOException simulating a log full condition is raised.
If TEST_RECORD_TO_FILL_LOG is not set, it defaults to 100 log record
|
unfreezePersistentStore | public void unfreezePersistentStore() throws StandardException(Code) | | Backup restore - start sending log record to the log stream
exception: StandardException - Standard Cloudscape error policy |
writeControlFile | boolean writeControlFile(StorageFile logControlFileName, long value) throws IOException, StandardException(Code) | | Carefully write out this value to the control file.
We do safe write of this data by writing the data
into two files every time we write the control data.
we write checksum at the end of the file, so if by
chance system crashes while writing into the file,
using the checksum we find that the control file
is hosed then we use the mirror file, which will have
the condrol data written at last check point.
see comment at beginning of file for log control file format.
MT- synchronized by caller
|
|
|