Search in sources :

Example 31 with StorageFile

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());
                        }
                    }
                }
            }
        }
    }
}
Also used : StandardException(org.apache.derby.shared.common.error.StandardException) StorageFile(org.apache.derby.io.StorageFile)

Example 32 with StorageFile

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;
}
Also used : MalformedURLException(java.net.MalformedURLException) StorageFile(org.apache.derby.io.StorageFile) IOException(java.io.IOException) URL(java.net.URL) ShutdownException(org.apache.derby.shared.common.error.ShutdownException) FileNotFoundException(java.io.FileNotFoundException) SyncFailedException(java.io.SyncFailedException) StandardException(org.apache.derby.shared.common.error.StandardException) PrivilegedActionException(java.security.PrivilegedActionException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException)

Example 33 with StorageFile

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
}
Also used : StorageRandomAccessFile(org.apache.derby.io.StorageRandomAccessFile) StorageFile(org.apache.derby.io.StorageFile) IOException(java.io.IOException)

Example 34 with StorageFile

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);
}
Also used : VirtualFile(org.apache.derby.impl.io.vfmem.VirtualFile) DataStore(org.apache.derby.impl.io.vfmem.DataStore) StorageFile(org.apache.derby.io.StorageFile)

Example 35 with StorageFile

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;
}
Also used : StorageFile(org.apache.derby.io.StorageFile)

Aggregations

StorageFile (org.apache.derby.io.StorageFile)53 IOException (java.io.IOException)21 StorageRandomAccessFile (org.apache.derby.io.StorageRandomAccessFile)13 File (java.io.File)12 PrivilegedActionException (java.security.PrivilegedActionException)9 StandardException (org.apache.derby.shared.common.error.StandardException)9 StorageFactory (org.apache.derby.io.StorageFactory)6 FileNotFoundException (java.io.FileNotFoundException)4 Properties (java.util.Properties)4 RawTransaction (org.apache.derby.iapi.store.raw.xact.RawTransaction)4 WritableStorageFactory (org.apache.derby.io.WritableStorageFactory)4 OutputStreamWriter (java.io.OutputStreamWriter)3 PrivilegedExceptionAction (java.security.PrivilegedExceptionAction)3 FileInputStream (java.io.FileInputStream)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 PreparedStatement (java.sql.PreparedStatement)2 ResultSet (java.sql.ResultSet)2 ContextManager (org.apache.derby.iapi.services.context.ContextManager)2 DataStore (org.apache.derby.impl.io.vfmem.DataStore)2 VirtualFile (org.apache.derby.impl.io.vfmem.VirtualFile)2