use of org.apache.derby.io.StorageFile in project derby by apache.
the class LogToFile method deleteObsoleteLogfiles.
/* delete the log files, that might have been left around if we crashed
* immediately after the checkpoint before truncations of logs completed.
* see bug no: 3519 , for more details.
*/
private void deleteObsoleteLogfiles() {
StorageFile logDir;
// find the first log file number that is useful
long firstLogNeeded = getFirstLogNeeded(currentCheckpoint);
if (firstLogNeeded == -1)
return;
// if they are not required for crash recovery.
if (backupInProgress) {
long logFileNeededForBackup = logFileToBackup;
// that is yet to be copied to the backup.
if (logFileNeededForBackup < firstLogNeeded)
firstLogNeeded = logFileNeededForBackup;
}
try {
logDir = getLogDirectory();
} catch (StandardException se) {
if (SanityManager.DEBUG)
if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
SanityManager.DEBUG(DBG_FLAG, "error opening log segment dir");
return;
}
String[] logfiles = privList(logDir);
if (logfiles != null) {
StorageFile uselessLogFile = null;
long fileNumber;
for (int i = 0; i < logfiles.length; i++) {
// delete the log files that are not needed any more
if (logfiles[i].startsWith("log") && logfiles[i].endsWith(".dat")) {
fileNumber = Long.parseLong(logfiles[i].substring(3, (logfiles[i].length() - 4)));
if (fileNumber < firstLogNeeded) {
uselessLogFile = logStorageFactory.newStorageFile(logDir, logfiles[i]);
if (privDelete(uselessLogFile)) {
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
SanityManager.DEBUG(DBG_FLAG, "truncating obsolete log file " + uselessLogFile.getPath());
}
} else {
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
SanityManager.DEBUG(DBG_FLAG, "Fail to truncate obsolete log file " + uselessLogFile.getPath());
}
}
}
}
}
}
}
use of org.apache.derby.io.StorageFile in project derby by apache.
the class LogToFile method boot.
/**
* Boot up the log factory.
* <P> MT- caller provide synchronization
*
* @exception StandardException log factory cannot start up
*/
public void boot(boolean create, Properties startParams) throws StandardException {
// Is the database booted in replication slave mode?
String mode = startParams.getProperty(SlaveFactory.REPLICATION_MODE);
if (mode != null && mode.equals(SlaveFactory.SLAVE_MODE)) {
inReplicationSlaveMode = true;
slaveRecoveryMonitor = new Object();
} else if (mode != null && mode.equals(SlaveFactory.SLAVE_PRE_MODE)) {
inReplicationSlavePreMode = true;
}
dataDirectory = startParams.getProperty(PersistentService.ROOT);
logDevice = startParams.getProperty(Attribute.LOG_DEVICE);
if (logDevice != null) {
// in case the user specifies logDevice in URL form
String logDeviceURL = null;
try {
URL url = new URL(logDevice);
logDeviceURL = url.getFile();
} catch (MalformedURLException ex) {
}
if (logDeviceURL != null)
logDevice = logDeviceURL;
}
if (create) {
getLogStorageFactory();
createLogDirectory();
} else {
// if it is then restore the logs.
if (!restoreLogs(startParams)) {
// set the log storage factory.
getLogStorageFactory();
if (logDevice != null) {
// Make sure we find the log, do not assume
// it is OK that the log is not there because
// it could be a user typo(like when users edit
// service.properties to change the log device
// while restoring from backups using OS copy.
StorageFile checklogDir = logStorageFactory.newStorageFile(LogFactory.LOG_DIRECTORY_NAME);
if (!privExists(checklogDir)) {
throw StandardException.newException(SQLState.LOG_FILE_NOT_FOUND, checklogDir.getPath());
}
}
}
}
// if user does not set the right value for the log buffer size,
// default value is used instead.
logBufferSize = PropertyUtil.getSystemInt(org.apache.derby.shared.common.reference.Property.LOG_BUFFER_SIZE, LOG_BUFFER_SIZE_MIN, LOG_BUFFER_SIZE_MAX, DEFAULT_LOG_BUFFER_SIZE);
jbmsVersion = getMonitor().getEngineVersion();
String logArchiveMode = startParams.getProperty(Property.LOG_ARCHIVE_MODE);
logArchived = Boolean.valueOf(logArchiveMode).booleanValue();
// get log factorty properties if any set in derby.properties
getLogFactoryProperties(null);
if (logStorageFactory.supportsWriteSync()) {
// write sync can be used in the jvm that database is running on.
// disable write sync if derby.storage.fileSyncTransactionLog is true
isWriteSynced = !(PropertyUtil.getSystemBoolean(Property.FILESYNC_TRANSACTION_LOG));
} else {
isWriteSynced = false;
}
// data page makes it to disk
if (Property.DURABILITY_TESTMODE_NO_SYNC.equalsIgnoreCase(PropertyUtil.getSystemProperty(Property.DURABILITY_PROPERTY))) {
// disable syncing of log.
logNotSynced = true;
// if log not being synced;files shouldn't be open in write sync mode
isWriteSynced = false;
} else if (Performance.MEASURE) {
// development build only feature, must by hand set the
// Performance.MEASURE variable and rebuild. Useful during
// development to compare/contrast effect of syncing, release
// users can use the above relaxed durability option to disable
// all syncing.
logNotSynced = PropertyUtil.getSystemBoolean(Property.STORAGE_LOG_NOT_SYNCED);
if (logNotSynced) {
isWriteSynced = false;
Monitor.logMessage("Performance.logNotSynced = true");
}
}
// try to access the log
// if it doesn't exist, create it.
// if it does exist, run recovery
boolean createNewLog = create;
if (SanityManager.DEBUG)
SanityManager.ASSERT(fid != -1, "invalid log format Id");
checkpointInstant = LogCounter.INVALID_LOG_INSTANT;
try {
StorageFile logControlFileName = getControlFileName();
StorageFile logFile;
if (!createNewLog) {
if (privExists(logControlFileName)) {
checkpointInstant = readControlFile(logControlFileName, startParams);
// to the derby log
if (wasDBInDurabilityTestModeNoSync) {
// print message stating that the database was
// previously atleast at one time running with
// derby.system.durability=test mode
Monitor.logMessage(MessageService.getTextMessage(MessageId.LOG_WAS_IN_DURABILITY_TESTMODE_NO_SYNC, Property.DURABILITY_PROPERTY, Property.DURABILITY_TESTMODE_NO_SYNC));
}
if (checkpointInstant == LogCounter.INVALID_LOG_INSTANT && privExists(getMirrorControlFileName())) {
checkpointInstant = readControlFile(getMirrorControlFileName(), startParams);
}
} else if (logDevice != null) {
// logDevice property is set, then it should be there.
throw StandardException.newException(SQLState.LOG_FILE_NOT_FOUND, logControlFileName.getPath());
}
if (checkpointInstant != LogCounter.INVALID_LOG_INSTANT)
logFileNumber = LogCounter.getLogFileNumber(checkpointInstant);
else
logFileNumber = 1;
logFile = getLogFileName(logFileNumber);
if (!privExists(logFile)) {
if (logDevice != null) {
throw StandardException.newException(SQLState.LOG_FILE_NOT_FOUND, logControlFileName.getPath());
}
logErrMsg(MessageService.getTextMessage(MessageId.LOG_MAYBE_INCONSISTENT, logFile.getPath()));
createNewLog = true;
} else if (!verifyLogFormat(logFile, logFileNumber)) {
Monitor.logTextMessage(MessageId.LOG_DELETE_INCOMPATIBLE_FILE, logFile);
// blow away the log file if possible
if (!privDelete(logFile) && logFileNumber == 1) {
logErrMsgForDurabilityTestModeNoSync();
throw StandardException.newException(SQLState.LOG_INCOMPATIBLE_FORMAT, dataDirectory);
}
// If logFileNumber > 1, we are not going to write that
// file just yet. Just leave it be and carry on. Maybe
// when we get there it can be deleted.
createNewLog = true;
}
}
if (createNewLog) {
// checkpoint instant since there is no checkpoint yet
if (writeControlFile(logControlFileName, LogCounter.INVALID_LOG_INSTANT)) {
firstLogFileNumber = 1;
logFileNumber = 1;
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON(TEST_MAX_LOGFILE_NUMBER)) {
// set the value to be two less than max possible
// log number, test case will perform some ops to
// hit the max number case.
firstLogFileNumber = LogCounter.MAX_LOGFILE_NUMBER - 2;
logFileNumber = LogCounter.MAX_LOGFILE_NUMBER - 2;
}
}
logFile = getLogFileName(logFileNumber);
if (privExists(logFile)) {
// this log file maybe there because the system may have
// crashed right after a log switch but did not write
// out any log record
Monitor.logTextMessage(MessageId.LOG_DELETE_OLD_FILE, logFile);
if (!privDelete(logFile)) {
logErrMsgForDurabilityTestModeNoSync();
throw StandardException.newException(SQLState.LOG_INCOMPATIBLE_FORMAT, dataDirectory);
}
}
// don't need to try to delete it, we know it isn't there
firstLog = privRandomAccessFile(logFile, "rw");
if (!initLogFile(firstLog, logFileNumber, LogCounter.INVALID_LOG_INSTANT)) {
throw StandardException.newException(SQLState.LOG_SEGMENT_NOT_EXIST, logFile.getPath());
}
setEndPosition(firstLog.getFilePointer());
lastFlush = firstLog.getFilePointer();
// and reopen the file in rwd mode.
if (isWriteSynced) {
// extend the file by wring zeros to it
preAllocateNewLogFile(firstLog);
firstLog.close();
firstLog = openLogFileInWriteMode(logFile);
// postion the log at the current log end postion
firstLog.seek(endPosition);
}
if (SanityManager.DEBUG) {
SanityManager.ASSERT(endPosition == LOG_FILE_HEADER_SIZE, "empty log file has wrong size");
}
} else {
Monitor.logTextMessage(MessageId.LOG_CHANGED_DB_TO_READ_ONLY);
Monitor.logThrowable(new Exception("Error writing control file"));
// read only database
ReadOnlyDB = true;
logOut = null;
firstLog = null;
}
recoveryNeeded = false;
} else {
// log file exist, need to run recovery
recoveryNeeded = true;
}
} catch (IOException ioe) {
throw Monitor.exceptionStartingModule(ioe);
}
// fully upgraded to or created in version 10.1 or above.
if (!checkVersion(RawStoreFactory.DERBY_STORE_MAJOR_VERSION_10, RawStoreFactory.DERBY_STORE_MINOR_VERSION_1))
maxLogFileNumber = LogCounter.DERBY_10_0_MAX_LOGFILE_NUMBER;
bootTimeLogFileNumber = logFileNumber;
}
use of org.apache.derby.io.StorageFile in project derby by apache.
the class LogToFile method switchLogFile.
/**
* Switch to the next log file if possible.
*
* <P>MT - log factory is single threaded thru a log file switch, the log
* is frozen for the duration of the switch
*/
public void switchLogFile() throws StandardException {
boolean switchedOver = false;
// ///////////////////////////////////////////////////
synchronized (this) {
// the log is not frozen for backup. Track (2985).
while (logBeingFlushed | isFrozen) {
try {
wait();
} catch (InterruptedException ie) {
InterruptStatus.setInterrupted();
}
}
// we have an empty log file here, refuse to switch.
if (endPosition == LOG_FILE_HEADER_SIZE) {
if (SanityManager.DEBUG) {
Monitor.logMessage("not switching from an empty log file (" + logFileNumber + ")");
}
return;
}
// log file isn't being flushed right now and logOut is not being
// used.
StorageFile newLogFile = getLogFileName(logFileNumber + 1);
if (logFileNumber + 1 >= maxLogFileNumber) {
throw StandardException.newException(SQLState.LOG_EXCEED_MAX_LOG_FILE_NUMBER, maxLogFileNumber);
}
// the new log file
StorageRandomAccessFile newLog = null;
try {
// switch log right now
if (privExists(newLogFile) && !privDelete(newLogFile)) {
logErrMsg(MessageService.getTextMessage(MessageId.LOG_NEW_LOGFILE_EXIST, newLogFile.getPath()));
return;
}
try {
newLog = privRandomAccessFile(newLogFile, "rw");
} catch (IOException ioe) {
newLog = null;
}
if (newLog == null || !privCanWrite(newLogFile)) {
if (newLog != null)
newLog.close();
newLog = null;
return;
}
if (initLogFile(newLog, logFileNumber + 1, LogCounter.makeLogInstantAsLong(logFileNumber, endPosition))) {
// New log file init ok, close the old one and
// switch over, after this point, need to shutdown the
// database if any error crops up
switchedOver = true;
// write out an extra 0 at the end to mark the end of the log
// file.
logOut.writeEndMarker(0);
setEndPosition(endPosition + INT_LENGTH);
// set that we are in log switch to prevent flusher
// not requesting to switch log again
inLogSwitch = true;
// flush everything including the int we just wrote
flush(logFileNumber, endPosition);
// simulate out of log error after the switch over
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON(TEST_SWITCH_LOG_FAIL2))
throw new IOException("TestLogSwitchFail2");
}
// close the old log file
logOut.close();
logWrittenFromLastCheckPoint += endPosition;
setEndPosition(newLog.getFilePointer());
lastFlush = endPosition;
if (isWriteSynced) {
// extend the file by wring zeros to it
preAllocateNewLogFile(newLog);
newLog.close();
newLog = openLogFileInWriteMode(newLogFile);
newLog.seek(endPosition);
}
logOut = new LogAccessFile(this, newLog, logBufferSize);
newLog = null;
if (SanityManager.DEBUG) {
if (endPosition != LOG_FILE_HEADER_SIZE)
SanityManager.THROWASSERT("new log file has unexpected size" + +endPosition);
}
logFileNumber++;
if (SanityManager.DEBUG) {
SanityManager.ASSERT(endPosition == LOG_FILE_HEADER_SIZE, "empty log file has wrong size");
}
} else // something went wrong, delete the half baked file
{
newLog.close();
newLog = null;
if (privExists(newLogFile))
privDelete(newLogFile);
logErrMsg(MessageService.getTextMessage(MessageId.LOG_CANNOT_CREATE_NEW, newLogFile.getPath()));
newLogFile = null;
}
} catch (IOException ioe) {
inLogSwitch = false;
// switching log file is an optional operation and there is no direct user
// control. Just sends a warning message to whomever, if any,
// system adminstrator there may be
logErrMsg(MessageService.getTextMessage(MessageId.LOG_CANNOT_CREATE_NEW_DUETO, newLogFile.getPath(), ioe.toString()));
try {
if (newLog != null) {
newLog.close();
newLog = null;
}
} catch (IOException ioe2) {
}
if (newLogFile != null && privExists(newLogFile)) {
privDelete(newLogFile);
newLogFile = null;
}
if (// error occur after old log file has been closed!
switchedOver) {
// limit any damage
logOut = null;
throw markCorrupt(StandardException.newException(SQLState.LOG_IO_ERROR, ioe));
}
}
// read the previous log file
if (inReplicationSlaveMode) {
allowedToReadFileNumber = logFileNumber - 1;
synchronized (slaveRecoveryMonitor) {
slaveRecoveryMonitor.notify();
}
}
inLogSwitch = false;
}
// unfreezes the log
}
use of org.apache.derby.io.StorageFile in project derby by apache.
the class VirtualFileTest method testGetParentRelative.
public void testGetParentRelative() {
DataStore store = getStore();
VirtualFile vFile = new VirtualFile(PathUtilTest.join(NON_EXISTING_DIRS), store);
int count = 0;
StorageFile parent = vFile.getParentDir();
while (parent != null) {
count++;
parent = parent.getParentDir();
}
assertEquals(4, count);
}
use of org.apache.derby.io.StorageFile in project derby by apache.
the class LogToFile method isCheckpointInLastLogFile.
/*
* find if the checkpoint is in the last log file.
*
* <P>MT - synchronization provided by caller - RawStore boot,
* This method is called only if a crash occured while
* re-encrypting the database at boot time.
* @return <code> true </code> if if the checkpoint is
* in the last log file, otherwise
* <code> false </code>.
*/
public boolean isCheckpointInLastLogFile() throws StandardException {
// check if the checkpoint is done in the last log file.
long logFileNumberAfterCheckpoint = LogCounter.getLogFileNumber(checkpointInstant) + 1;
// check if there is a log file after
// the log file that has the last
// checkpoint record.
StorageFile logFileAfterCheckpoint = getLogFileName(logFileNumberAfterCheckpoint);
// System.out.println("checking " + logFileAfterCheckpoint);
if (privExists(logFileAfterCheckpoint))
return false;
else
return true;
}
Aggregations