All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sleepycat.je.util.DbVerifyLog Maven / Gradle / Ivy

The newest version!
/*-
 * Copyright (C) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
 *
 * This file was distributed by Oracle as part of a version of Oracle Berkeley
 * DB Java Edition made available at:
 *
 * http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
 *
 * Please see the LICENSE file included in the top-level directory of the
 * appropriate version of Oracle Berkeley DB Java Edition for a copy of the
 * license and additional information.
 */

package com.sleepycat.je.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;

import com.sleepycat.je.DbInternal;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.EnvironmentFailureException;
import com.sleepycat.je.JEVersion;
import com.sleepycat.je.ThreadInterruptedException;
import com.sleepycat.je.config.EnvironmentParams;
import com.sleepycat.je.dbi.EnvironmentFailureReason;
import com.sleepycat.je.dbi.EnvironmentImpl;
import com.sleepycat.je.log.FileManager;
import com.sleepycat.je.log.entry.RestoreRequired;
import com.sleepycat.je.util.verify.VerifierUtils;
import com.sleepycat.je.utilint.CmdUtil;
import com.sleepycat.je.utilint.LoggerUtils;
import com.sleepycat.je.utilint.PropUtil;

/**
 * Verifies the checksums in one or more log files.
 *
 * 

This class may be instantiated and used programmatically, or used as a * command line utility as described below.

* *
 * usage: java { com.sleepycat.je.util.DbVerifyLog |
 *               -jar je-<version>.jar DbVerifyLog }
 *  [-h <dir>]      # environment home directory
 *  [-s <file>]     # starting (minimum) file number
 *  [-e <file>]     # ending (one past the maximum) file number
 *  [-d <millis>]   # delay in ms between reads (default is zero)
 *  [-V]                  # print JE version number"
 * 
* *

All arguments are optional. The current directory is used if {@code -h} * is not specified. File numbers may be specified in hex (preceded by {@code * 0x}) or decimal format. For convenience when copy/pasting from other * output, LSN format (<file>/<offset>) is also allowed.

*/ public class DbVerifyLog { private static final String USAGE = "usage: " + CmdUtil.getJavaCommand(DbVerifyLog.class) + "\n" + " [-h
] # environment home directory\n" + " [-s ] # starting (minimum) file number\n" + " [-e ] # ending (one past the maximum) file number\n" + " [-d ] # delay in ms between reads (default is zero)\n" + " [-V] # print JE version number"; private final EnvironmentImpl envImpl; private final int readBufferSize; private volatile boolean stopVerify = false; private volatile int filesToVerify = 0; private volatile int filesVerified = 0; private volatile int filesDeleted = 0; private long delayMs = 0; /** * Creates a utility object for verifying the checksums in log files. * *

The read buffer size is {@link * EnvironmentConfig#LOG_ITERATOR_READ_SIZE}.

* * @param env the {@code Environment} associated with the log. * * @throws EnvironmentFailureException if an unexpected, internal or * environment-wide failure occurs. */ public DbVerifyLog(final Environment env) { this(env, 0); } /** * Creates a utility object for verifying log files. * * @param env the {@code Environment} associated with the log. * * @param readBufferSize is the buffer size to use. If a value less than * or equal to zero is specified, {@link * EnvironmentConfig#LOG_ITERATOR_READ_SIZE} is used. * * @throws EnvironmentFailureException if an unexpected, internal or * environment-wide failure occurs. */ public DbVerifyLog(final Environment env, final int readBufferSize) { this(DbInternal.getNonNullEnvImpl(env), readBufferSize); } /** * @hidden */ public DbVerifyLog(final EnvironmentImpl envImpl, final int readBufferSize) { this.readBufferSize = (readBufferSize > 0) ? readBufferSize : envImpl.getConfigManager().getInt (EnvironmentParams.LOG_ITERATOR_READ_SIZE); this.envImpl = envImpl; } /** * Verifies all log files in the environment. * * @throws LogVerificationException if a checksum cannot be verified or a * log entry is determined to be invalid by examining its contents. * * @throws IOException if an IOException occurs while reading a log file. * * @throws EnvironmentFailureException if an unexpected, internal or * environment-wide failure occurs. */ public void verifyAll() throws LogVerificationException, IOException { /* The same reason with BtreeVerifier.verifyAll. */ if (stopVerify) { return; } LoggerUtils.envLogMsg( Level.INFO, envImpl, "Start verify of data files"); verify(0, Long.MAX_VALUE); LoggerUtils.envLogMsg( Level.INFO, envImpl, "End verify of data files"); } /** * Verifies the given range of log files in the environment. * * @param startFile is the lowest numbered log file to be verified. * * @param endFile is one greater than the highest numbered log file to be * verified. * * @throws LogVerificationException if a checksum cannot be verified or a * log entry is determined to be invalid by examining its contents. * * @throws IOException if an IOException occurs while reading a log file. * * @throws EnvironmentFailureException if an unexpected, internal or * environment-wide failure occurs. */ public void verify(final long startFile, final long endFile) throws LogVerificationException, IOException { try { final FileManager fileManager = envImpl.getFileManager(); final File homeDir = envImpl.getEnvironmentHome(); final String[] fileNames = fileManager.listFileNames(startFile, endFile - 1); filesToVerify = fileNames.length; final ByteBuffer buf = ByteBuffer.allocateDirect(readBufferSize); for (final String fileName : fileNames) { /* * When env is closed, the current executing dataVerifier task * should be canceled asap. So when env is closed, * setStopVerifyFlag() is called in DataVerifier.shutdown(). * Here stopVerify is checked to determine whether dataVerifier * task continues. */ if (stopVerify) { return; } final File file = new File(homeDir, fileName); /* * If JE enables Cleaner, then it is possible that Cleaner * deletes one or more files, whose fileNum is between * startFile and endFile, during the for-loop. So for each * loop, the current 'file' may be deleted by the Cleaner, then * 'new FileInputStream' will throw FileNotFoundException. * * In addition, now JE has a daemon thread to detect the * unexpected log file deletion. So if FileNotFoundException is * caused by unexpected log deletion, then that daemon thread * will catch this abnormal situation. Here, we just ignore * this exception. */ FileInputStream fis; try { fis = new FileInputStream(file); } catch (FileNotFoundException fne) { filesDeleted += 1; continue; } final FileChannel fic = fis.getChannel(); final LogVerificationReadableByteChannel vic = new LogVerificationReadableByteChannel( envImpl, fic, fileName); IOException ioe = null; try { while (vic.read(buf) != -1) { buf.clear(); /* Return as soon as possible if shutdown. */ if (stopVerify) { return; } if (delayMs > 0) { try { Thread.sleep(delayMs); } catch (InterruptedException e) { throw new ThreadInterruptedException( envImpl, e); } } } filesVerified += 1; } catch (IOException e) { ioe = e; throw ioe; } finally { try { /* * vic.close aims to close associated channel fic, but * it may be redundant because fis.close also closes * fic. */ fis.close(); vic.close(); } catch (IOException e) { if (ioe == null) { throw e; } } } } } catch (LogVerificationException lve) { VerifierUtils.createMarkerFileFromException( RestoreRequired.FailureType.LOG_CHECKSUM, lve, envImpl, EnvironmentFailureReason.LOG_CHECKSUM); throw lve; } } /** * Returns the number of files to be verified. Returns zero when called * prior to calling {@link #verifyAll} or {@link #verify}. */ public int getNFilesToVerify() { return filesToVerify; } /** * Returns the number of files verified so far. */ public int getNFilesVerified() { return filesVerified; } /** * Returns the number of files deleted so far. This can happen when a * file to be verified is deleted by the cleaner. */ public int getNFilesDeleted() { return filesDeleted; } public static void main(String[] argv) { try { File envHome = new File("."); long startFile = 0; long endFile = Long.MAX_VALUE; long delayMs = 0; for (int whichArg = 0; whichArg < argv.length; whichArg += 1) { final String nextArg = argv[whichArg]; if (nextArg.equals("-h")) { whichArg++; envHome = new File(CmdUtil.getArg(argv, whichArg)); } else if (nextArg.equals("-s")) { whichArg++; String arg = CmdUtil.getArg(argv, whichArg); final int slashOff = arg.indexOf("/"); if (slashOff >= 0) { arg = arg.substring(0, slashOff); } startFile = CmdUtil.readLongNumber(arg); } else if (nextArg.equals("-e")) { whichArg++; String arg = CmdUtil.getArg(argv, whichArg); final int slashOff = arg.indexOf("/"); if (slashOff >= 0) { arg = arg.substring(0, slashOff); } endFile = CmdUtil.readLongNumber(arg); } else if (nextArg.equals("-d")) { whichArg++; delayMs = CmdUtil.readLongNumber(CmdUtil.getArg(argv, whichArg)); } else if (nextArg.equals("-V")) { System.out.println(JEVersion.CURRENT_VERSION); System.exit(0); } else { printUsageAndExit("Unknown argument: " + nextArg); } } final EnvironmentImpl envImpl = CmdUtil.makeUtilityEnvironment(envHome, true /*readOnly*/); final DbVerifyLog verifier = new DbVerifyLog(envImpl, 0); /* Set the delay time specified by -d flag. */ verifier.setReadDelay(delayMs, TimeUnit.MILLISECONDS); verifier.verify(startFile, endFile); System.exit(0); } catch (Throwable e) { e.printStackTrace(); printUsageAndExit(e.toString()); } } private static void printUsageAndExit(String msg) { if (msg != null) { System.err.println(msg); } System.err.println(USAGE); System.exit(1); } /** * Configures the delay between file reads during verification. A delay * between reads is needed to allow other JE components, such as HA, to * make timely progress. * *

By default there is no read delay (it is zero).

* *

Note that when using the {@link EnvironmentConfig#ENV_RUN_VERIFIER * background data verifier}, the delay between reads is * {@link EnvironmentConfig#VERIFY_LOG_READ_DELAY}.

* * @param delay the delay between reads or zero for no delay. * * @param unit the {@code TimeUnit} of the delay value. May be * null only if delay is zero. */ public void setReadDelay(long delay, TimeUnit unit) { delayMs = PropUtil.durationToMillis(delay, unit); } /** * @hidden * For internal use only. */ public void setStopVerifyFlag(boolean val) { stopVerify = val; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy