/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2002-2005
* Sleepycat Software. All rights reserved.
*
* $Id: RunAction.java,v 1.19 2005/08/11 03:35:27 linda Exp $
*/
package com.sleepycat.je.util;
import java.io.File;
import java.text.DecimalFormat;
import com.sleepycat.je.CheckpointConfig;
import com.sleepycat.je.Cursor;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.DbInternal;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.EnvironmentMutableConfig;
import com.sleepycat.je.LockMode;
import com.sleepycat.je.OperationStatus;
import com.sleepycat.je.StatsConfig;
import com.sleepycat.je.config.EnvironmentParams;
import com.sleepycat.je.dbi.EnvironmentImpl;
import com.sleepycat.je.utilint.CmdUtil;
/**
* RunAction is a debugging aid that runs one of the background activities
* (cleaning, compressing, evicting, checkpointing).
*/
public class RunAction {
private static final int CLEAN = 1;
private static final int COMPRESS = 2;
private static final int EVICT = 3;
private static final int CHECKPOINT = 4;
private static final int REMOVEDB = 5;
private static final int DBSTATS = 6;
public static void main(String [] argv) {
long recoveryStart = 0;
long actionStart = 0;
long actionEnd = 0;
try {
int whichArg = 0;
if (argv.length == 0) {
usage();
System.exit(1);
}
/*
* Usage: -h <envHomeDir> (optional)
* -a <clean|compress|evict|checkpoint|removedb>
* -ro (read only)
*/
String dbName = null;
int doAction = 0;
String envHome = "."; // default to current directory
boolean readOnly = false;
while (whichArg < argv.length) {
String nextArg = argv[whichArg];
if (nextArg.equals("-h")) {
whichArg++;
envHome = CmdUtil.getArg(argv, whichArg);
} else if (nextArg.equals("-a")) {
whichArg++;
String action = CmdUtil.getArg(argv, whichArg);
if (action.equalsIgnoreCase("clean")) {
doAction = CLEAN;
} else if (action.equalsIgnoreCase("compress")) {
doAction = COMPRESS;
} else if (action.equalsIgnoreCase("checkpoint")) {
doAction = CHECKPOINT;
} else if (action.equalsIgnoreCase("evict")) {
doAction = EVICT;
} else if (action.equalsIgnoreCase("removedb")) {
doAction = REMOVEDB;
} else if (action.equalsIgnoreCase("dbstats")) {
doAction = DBSTATS;
} else {
usage();
System.exit(1);
}
} else if (nextArg.equals("-ro")) {
readOnly = true;
} else if (nextArg.equals("-s")) {
dbName = argv[++whichArg];
} else {
throw new IllegalArgumentException
(nextArg + " is not a supported option.");
}
whichArg++;
}
/* Make an environment */
EnvironmentConfig envConfig = TestUtils.initEnvConfig();
/* Do debug log to the console.*/
envConfig.setConfigParam
(EnvironmentParams.JE_LOGGING_CONSOLE.getName(), "true");
/* Don't debug log to the database log. */
if (readOnly) {
envConfig.setConfigParam
(EnvironmentParams.JE_LOGGING_DBLOG.getName(), "false");
envConfig.setReadOnly(true);
}
/*
* If evicting, scan the given database first and don't run the
* background evictor.
*/
if (doAction == EVICT) {
envConfig.setConfigParam(
EnvironmentParams.ENV_RUN_EVICTOR.getName(), "false");
envConfig.setConfigParam(
EnvironmentParams.EVICTOR_CRITICAL_PERCENTAGE.getName(),
"1000");
}
recoveryStart = System.currentTimeMillis();
Environment env =
new Environment(new File(envHome), envConfig);
CheckpointConfig forceConfig = new CheckpointConfig();
forceConfig.setForce(true);
actionStart = System.currentTimeMillis();
switch(doAction) {
case CLEAN:
/* Since this is batch cleaning, repeat until no progress. */
while (true) {
int nFiles = env.cleanLog();
System.out.println("Files cleaned: " + nFiles);
if (nFiles == 0) {
break;
}
}
env.checkpoint(forceConfig);
break;
case COMPRESS:
env.compress();
break;
case EVICT:
preload(env, dbName);
break;
case CHECKPOINT:
env.checkpoint(forceConfig);
break;
case REMOVEDB:
env.removeDatabase(null, dbName);
break;
case DBSTATS:
DatabaseConfig dbConfig = new DatabaseConfig();
dbConfig.setReadOnly(true);
DbInternal.setUseExistingConfig(dbConfig, true);
Database db = env.openDatabase(null, dbName, dbConfig);
try {
System.out.println(db.getStats(new StatsConfig()));
} finally {
db.close();
}
break;
}
actionEnd = System.currentTimeMillis();
env.close();
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
usage();
System.exit(1);
} finally {
DecimalFormat f = new DecimalFormat();
f.setMaximumFractionDigits(2);
long recoveryDuration = actionStart - recoveryStart;
System.out.println("\nrecovery time = " +
f.format(recoveryDuration) +
" millis " +
f.format((double)recoveryDuration/60000) +
" minutes");
long actionDuration = actionEnd - actionStart;
System.out.println("action time = " +
f.format(actionDuration) +
" millis " +
f.format(actionDuration/60000) +
" minutes");
}
}
private static void preload(Environment env, String dbName)
throws DatabaseException {
System.out.println("Preload starting");
Database db = env.openDatabase(null, dbName, null);
Cursor cursor = db.openCursor(null, null);
try {
DatabaseEntry key = new DatabaseEntry();
DatabaseEntry data = new DatabaseEntry();
int count = 0;
while (cursor.getNext(key, data, LockMode.DEFAULT) ==
OperationStatus.SUCCESS) {
count++;
if ((count % 50000) == 0) {
System.out.println(count + "...");
}
}
System.out.println("Preloaded " + count + " records");
} finally {
cursor.close();
db.close();
}
}
private static void doEvict(Environment env)
throws DatabaseException {
/* push the cache size down by half to force eviction. */
EnvironmentImpl envImpl = DbInternal.envGetEnvironmentImpl(env);
long cacheUsage = envImpl.getMemoryBudget().getCacheMemoryUsage();
EnvironmentMutableConfig c = new EnvironmentMutableConfig();
c.setCacheSize(cacheUsage/2);
env.setMutableConfig(c);
long start = System.currentTimeMillis();
env.evictMemory();
long end = System.currentTimeMillis();
DecimalFormat f = new DecimalFormat();
f.setMaximumFractionDigits(2);
System.out.println("evict time=" + f.format(end-start));
}
private static void usage() {
System.out.println("Usage: RunAction");
System.out.println(" -h <environment home> ");
System.out.println(" -a <clean|compress|evict|checkpoint|removedb>");
System.out.println(" -ro (read-only - defaults to read-write)");
System.out.println(" -s <dbName> (for preloading of evict or db remove)");
}
}