001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2002,2008 Oracle. All rights reserved.
005: *
006: * $Id: DbDump.java,v 1.48.2.2 2008/01/07 15:14:17 cwl Exp $
007: */
008:
009: package com.sleepycat.je.util;
010:
011: import java.io.File;
012: import java.io.FileOutputStream;
013: import java.io.IOException;
014: import java.io.PrintStream;
015: import java.util.Iterator;
016: import java.util.List;
017: import java.util.logging.Level;
018:
019: import com.sleepycat.je.Cursor;
020: import com.sleepycat.je.Database;
021: import com.sleepycat.je.DatabaseConfig;
022: import com.sleepycat.je.DatabaseEntry;
023: import com.sleepycat.je.DatabaseException;
024: import com.sleepycat.je.DbInternal;
025: import com.sleepycat.je.Environment;
026: import com.sleepycat.je.EnvironmentConfig;
027: import com.sleepycat.je.JEVersion;
028: import com.sleepycat.je.LockMode;
029: import com.sleepycat.je.OperationStatus;
030: import com.sleepycat.je.config.EnvironmentParams;
031: import com.sleepycat.je.utilint.CmdUtil;
032: import com.sleepycat.je.utilint.DbScavenger;
033: import com.sleepycat.je.utilint.Tracer;
034:
035: public class DbDump {
036: private static final int VERSION = 3;
037:
038: protected File envHome = null;
039: protected Environment env;
040: protected String dbName = null;
041: protected boolean formatUsingPrintable;
042: private boolean dupSort;
043: private String outputFileName = null;
044: protected String outputDirectory = null;
045: protected PrintStream outputFile = null;
046: protected boolean doScavengerRun = false;
047: protected boolean doAggressiveScavengerRun = false;
048: protected boolean verbose = false;
049:
050: private static final String usageString = "usage: "
051: + CmdUtil.getJavaCommand(DbDump.class)
052: + "\n"
053: + " -h <dir> # environment home directory\n"
054: + " [-f <fileName>] # output file, for non -rR dumps\n"
055: + " [-l] # list databases in the environment\n"
056: + " [-p] # output printable characters\n"
057: + " [-r] # salvage mode\n"
058: + " [-R] # aggressive salvage mode\n"
059: + " [-d] <directory> # directory for *.dump files (salvage mode)\n"
060: + " [-s <databaseName>] # database to dump\n"
061: + " [-v] # verbose in salvage mode\n"
062: + " [-V] # print JE version number\n";
063:
064: private DbDump() {
065: }
066:
067: public DbDump(Environment env, String dbName,
068: PrintStream outputFile, String outputDirectory,
069: boolean formatUsingPrintable) {
070: try {
071: this .envHome = env.getHome();
072: } catch (DatabaseException e) {
073: IllegalArgumentException iae = new IllegalArgumentException();
074: iae.initCause(e);
075: throw iae;
076: }
077: this .env = env;
078: this .dbName = dbName;
079: this .outputFile = outputFile;
080: this .outputDirectory = outputDirectory;
081: this .formatUsingPrintable = formatUsingPrintable;
082: }
083:
084: public static void main(String argv[]) throws DatabaseException,
085: IOException {
086:
087: DbDump dumper = new DbDump();
088: boolean listDbs = dumper.parseArgs(argv);
089: if (dumper.doScavengerRun) {
090: dumper.openEnv(false);
091: dumper = new DbScavenger(dumper.env, dumper.outputFile,
092: dumper.outputDirectory,
093: dumper.formatUsingPrintable,
094: dumper.doAggressiveScavengerRun, dumper.verbose);
095: ((DbScavenger) dumper).setDumpCorruptedBounds(true);
096: }
097:
098: if (listDbs) {
099: dumper.listDbs();
100: System.exit(0);
101: }
102:
103: try {
104: dumper.dump();
105: } catch (Throwable T) {
106: T.printStackTrace();
107: } finally {
108: dumper.env.close();
109: if (dumper.outputFile != null
110: && dumper.outputFile != System.out) {
111: dumper.outputFile.close();
112: }
113: }
114: }
115:
116: private void listDbs() throws DatabaseException {
117:
118: openEnv(true);
119:
120: List dbNames = env.getDatabaseNames();
121: Iterator iter = dbNames.iterator();
122: while (iter.hasNext()) {
123: String name = (String) iter.next();
124: System.out.println(name);
125: }
126: }
127:
128: protected void printUsage(String msg) {
129: System.err.println(msg);
130: System.err.println(usageString);
131: System.exit(-1);
132: }
133:
134: protected boolean parseArgs(String argv[]) throws IOException {
135:
136: int argc = 0;
137: int nArgs = argv.length;
138: boolean listDbs = false;
139: while (argc < nArgs) {
140: String this Arg = argv[argc++];
141: if (this Arg.equals("-p")) {
142: formatUsingPrintable = true;
143: } else if (this Arg.equals("-V")) {
144: System.out.println(JEVersion.CURRENT_VERSION);
145: System.exit(0);
146: } else if (this Arg.equals("-l")) {
147: listDbs = true;
148: } else if (this Arg.equals("-r")) {
149: doScavengerRun = true;
150: } else if (this Arg.equals("-R")) {
151: doScavengerRun = true;
152: doAggressiveScavengerRun = true;
153: } else if (this Arg.equals("-f")) {
154: if (argc < nArgs) {
155: outputFileName = argv[argc++];
156: } else {
157: printUsage("-f requires an argument");
158: }
159: } else if (this Arg.equals("-h")) {
160: if (argc < nArgs) {
161: String envDir = argv[argc++];
162: envHome = new File(envDir);
163: } else {
164: printUsage("-h requires an argument");
165: }
166: } else if (this Arg.equals("-d")) {
167: if (argc < nArgs) {
168: outputDirectory = argv[argc++];
169: } else {
170: printUsage("-d requires an argument");
171: }
172: } else if (this Arg.equals("-s")) {
173: if (argc < nArgs) {
174: dbName = argv[argc++];
175: } else {
176: printUsage("-s requires an argument");
177: }
178: } else if (this Arg.equals("-v")) {
179: verbose = true;
180: } else {
181: printUsage(this Arg + " is not a valid option.");
182: }
183: }
184:
185: if (envHome == null) {
186: printUsage("-h is a required argument");
187: }
188:
189: if (!listDbs && !doScavengerRun) {
190: if (dbName == null) {
191: printUsage("Must supply a database name if -l not supplied.");
192: }
193: }
194:
195: if (outputFileName == null) {
196: outputFile = System.out;
197: } else {
198: outputFile = new PrintStream(new FileOutputStream(
199: outputFileName));
200: }
201:
202: return listDbs;
203: }
204:
205: /*
206: * Begin DbDump API. From here on there should be no calls to printUsage,
207: * System.xxx.print, or System.exit.
208: */
209: protected void openEnv(boolean doRecovery) throws DatabaseException {
210:
211: if (env == null) {
212: EnvironmentConfig envConfiguration = new EnvironmentConfig();
213: envConfiguration.setReadOnly(true);
214: /* Don't run recovery. */
215: envConfiguration.setConfigParam(
216: EnvironmentParams.ENV_RECOVERY.getName(),
217: doRecovery ? "true" : "false");
218: env = new Environment(envHome, envConfiguration);
219: }
220: }
221:
222: public void dump() throws IOException, DatabaseException {
223:
224: openEnv(true);
225:
226: Tracer.trace(Level.INFO, DbInternal.envGetEnvironmentImpl(env),
227: "DbDump.dump of " + dbName + " starting");
228:
229: DatabaseEntry foundKey = new DatabaseEntry();
230: DatabaseEntry foundData = new DatabaseEntry();
231:
232: DatabaseConfig dbConfig = new DatabaseConfig();
233: dbConfig.setReadOnly(true);
234: DbInternal.setUseExistingConfig(dbConfig, true);
235: Database db = env.openDatabase(null, dbName, dbConfig);
236: dupSort = db.getConfig().getSortedDuplicates();
237:
238: printHeader(outputFile, dupSort, formatUsingPrintable);
239:
240: Cursor cursor = db.openCursor(null, null);
241: while (cursor.getNext(foundKey, foundData, LockMode.DEFAULT) == OperationStatus.SUCCESS) {
242: dumpOne(outputFile, foundKey.getData(),
243: formatUsingPrintable);
244: dumpOne(outputFile, foundData.getData(),
245: formatUsingPrintable);
246: }
247: cursor.close();
248: db.close();
249: outputFile.println("DATA=END");
250:
251: Tracer.trace(Level.INFO, DbInternal.envGetEnvironmentImpl(env),
252: "DbDump.dump of " + dbName + " ending");
253: }
254:
255: protected void printHeader(PrintStream o, boolean dupSort,
256: boolean formatUsingPrintable) {
257: o.println("VERSION=" + VERSION);
258: if (formatUsingPrintable) {
259: o.println("format=print");
260: } else {
261: o.println("format=bytevalue");
262: }
263: o.println("type=btree");
264: o.println("dupsort=" + (dupSort ? "1" : "0"));
265: o.println("HEADER=END");
266: }
267:
268: protected void dumpOne(PrintStream o, byte[] ba,
269: boolean formatUsingPrintable) {
270: StringBuffer sb = new StringBuffer();
271: sb.append(' ');
272: CmdUtil.formatEntry(sb, ba, formatUsingPrintable);
273: o.println(sb.toString());
274: }
275: }
|