/*
* If we can't get an exclusive lock, then there are other processes
* with the environment open read-only and we can't delete any files.
*/
final FileManager fileManager = env.getFileManager();
if (!fileManager.lockEnvironment(false, true)) {
LoggerUtils.traceAndLog(logger, env, Level.WARNING,
"Cleaner has " + safeToDeleteFiles.size() +
" files not deleted because of read-only" +
" processes.");
return;
}
/* Be sure to release the environment lock in the finally block. */
try {
/* Synchronize while deleting files to block DbBackup.start. */
synchronized (protectedFileRanges) {
/* Intersect the protected ranges for active DbBackups. */
if (!protectedFileRanges.isEmpty()) {
unprotectedFiles = unprotectedFiles.headSet
(Collections.min(protectedFileRanges));
}
/* Delete the unprotected files. */
for (final Iterator<Long> iter = unprotectedFiles.iterator();
iter.hasNext();) {
final Long fileNum = iter.next();
final boolean deleted;
try {
if (expunge) {
deleted = fileManager.deleteFile(fileNum);
} else {
deleted = fileManager.renameFile
(fileNum, FileManager.DEL_SUFFIX);
}
} catch (IOException e) {
throw new EnvironmentFailureException
(env, EnvironmentFailureReason.LOG_WRITE,
"Unable to delete or rename " + fileNum, e);
}
if (deleted) {
/*
* Deletion was successful. Log a trace message for
* debugging of log cleaning behavior.
*/
LoggerUtils.traceAndLog(logger, env, Level.FINE,
"Cleaner deleted file 0x" +
Long.toHexString(fileNum));
} else if (!fileManager.isFileValid(fileNum)) {
/*
* Somehow the file was previously deleted. This could
* indicate an internal state error, and therefore we
* output a trace message. But we should not
* repeatedly attempt to delete it, so we do remove it
* from the profile below.
*/
LoggerUtils.traceAndLog
(logger, env, Level.SEVERE,
"Cleaner deleteSafeToDeleteFiles Log file 0x" +
Long.toHexString(fileNum) + " was previously " +
(expunge ? "deleted" : "renamed") + ". State: " +
fileSelector);
} else {
/*
* We will retry the deletion later if file still
* exists. The deletion could have failed on Windows
* if the file was recently closed. Remove the file
* from unprotectedFiles. That way, we won't remove it
* from the FileSelector's safe-to-delete set or the UP
* below, and we will retry the file deletion later.
*/
iter.remove();
LoggerUtils.traceAndLog
(logger, env, Level.WARNING,
"Cleaner deleteSafeToDeleteFiles Log file 0x" +
Long.toHexString(fileNum) + " could not be " +
(expunge ? "deleted" : "renamed") + ". This " +
"operation will be retried at the next " +
"checkpoint. State: " + fileSelector);
}
}
}
} finally {
fileManager.releaseExclusiveLock();
}
/*
* Now unprotectedFiles contains only the files we deleted above. We
* can update the UP (and FileSelector) here outside of the