Merge lp:~pbeaman/akiban-persistit/display-volume-header-info into lp:akiban-persistit

Proposed by Peter Beaman
Status: Merged
Approved by: Nathan Williams
Approved revision: 422
Merged at revision: 420
Proposed branch: lp:~pbeaman/akiban-persistit/display-volume-header-info
Merge into: lp:akiban-persistit
Diff against target: 149 lines (+97/-2)
3 files modified
src/main/java/com/persistit/CLI.java (+1/-1)
src/main/java/com/persistit/CheckpointManager.java (+0/-1)
src/main/java/com/persistit/VolumeHeader.java (+96/-0)
To merge this branch: bzr merge lp:~pbeaman/akiban-persistit/display-volume-header-info
Reviewer Review Type Date Requested Status
Nathan Williams Approve
Review via email: mp+146693@code.launchpad.net

Description of the change

Add volumeinfo CLI command. Pretty-prints all the dates and other information in the volume header. Useful for diagnosing problems on client machines.

To post a comment you must log in.
Revision history for this message
Nathan Williams (nwilliams) wrote :

Looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/main/java/com/persistit/CLI.java'
2--- src/main/java/com/persistit/CLI.java 2013-01-19 17:52:20 +0000
3+++ src/main/java/com/persistit/CLI.java 2013-02-05 18:08:28 +0000
4@@ -156,7 +156,7 @@
5 private final static Map<String, Command> COMMANDS = new TreeMap<String, Command>();
6
7 private final static Class<?>[] CLASSES = { CLI.class, BackupTask.class, IntegrityCheck.class, StreamSaver.class,
8- StreamLoader.class, StatisticsTask.class, TaskCheck.class };
9+ StreamLoader.class, StatisticsTask.class, TaskCheck.class, VolumeHeader.class };
10
11 static {
12 for (final Class<?> clazz : CLASSES) {
13
14=== modified file 'src/main/java/com/persistit/CheckpointManager.java'
15--- src/main/java/com/persistit/CheckpointManager.java 2013-02-01 12:09:51 +0000
16+++ src/main/java/com/persistit/CheckpointManager.java 2013-02-05 18:08:28 +0000
17@@ -26,7 +26,6 @@
18 import java.util.concurrent.atomic.AtomicBoolean;
19
20 import com.persistit.Transaction.CommitPolicy;
21-import com.persistit.exception.MissingThreadException;
22 import com.persistit.exception.PersistitException;
23 import com.persistit.exception.PersistitInterruptedException;
24 import com.persistit.mxbeans.CheckpointManagerMXBean;
25
26=== modified file 'src/main/java/com/persistit/VolumeHeader.java'
27--- src/main/java/com/persistit/VolumeHeader.java 2012-10-05 19:37:58 +0000
28+++ src/main/java/com/persistit/VolumeHeader.java 2013-02-05 18:08:28 +0000
29@@ -18,11 +18,17 @@
30 import java.io.File;
31 import java.io.FileInputStream;
32 import java.io.IOException;
33+import java.io.PrintWriter;
34+import java.text.SimpleDateFormat;
35+import java.util.Date;
36
37+import com.persistit.CLI.Arg;
38+import com.persistit.CLI.Cmd;
39 import com.persistit.exception.CorruptVolumeException;
40 import com.persistit.exception.InvalidVolumeSpecificationException;
41 import com.persistit.exception.PersistitException;
42 import com.persistit.exception.PersistitIOException;
43+import com.persistit.util.ArgParser;
44 import com.persistit.util.Util;
45
46 /**
47@@ -30,7 +36,13 @@
48 * volume file.
49 */
50 class VolumeHeader {
51+
52+ private final static String[] ARGS_TEMPLATE = { "path|string:|Volume file name" };
53+
54+ private final static SimpleDateFormat SDF = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
55+
56 /**
57+ *
58 * Signature value - human and machine readable confirmation that this file
59 * resulted from Persistit.
60 */
61@@ -355,4 +367,88 @@
62 return CURRENT_VERSION;
63 }
64
65+ @Cmd("volumeinfo")
66+ static VolumeInfoTask createTask(@Arg("file|string:|Volume file") final String file) throws Exception {
67+ return new VolumeInfoTask(file);
68+ }
69+
70+ private static class VolumeInfoTask extends Task {
71+ String _volumeFileName;
72+
73+ private VolumeInfoTask(final String fileName) {
74+ _volumeFileName = fileName;
75+ }
76+
77+ @Override
78+ protected void runTask() throws Exception {
79+ final File file = new File(_volumeFileName);
80+ final FileInputStream stream = new FileInputStream(file);
81+ final byte[] bytes = new byte[SIZE];
82+ final int readSize = stream.read(bytes);
83+ stream.close();
84+ if (readSize < SIZE) {
85+ throw new CorruptVolumeException(String.format(
86+ "File %s of size %,d is too short to be a Volume file\n", file, readSize));
87+ }
88+ /*
89+ * Check out the fixed Volume file and learn the buffer size.
90+ */
91+ if (!verifySignature(bytes)) {
92+ throw new CorruptVolumeException(String.format("File %s is not a Volume file: Invalid signature", file));
93+ }
94+ postMessage(String.format("%30s: %s", "File", file), Task.LOG_NORMAL);
95+ outn("ID", getId(bytes));
96+ outn("Page size", getPageSize(bytes));
97+ outd("Creation time", getCreateTime(bytes));
98+ outd("Last open time", getOpenTime(bytes));
99+ outd("Last extension time", getLastExtensionTime(bytes));
100+ outd("Last read time", getLastReadTime(bytes));
101+ outd("Last write time", getLastWriteTime(bytes));
102+ outn("Global timestamp", getGlobalTimestamp(bytes));
103+ outn("Timestamp", getTimestamp(bytes));
104+ outn("Version", getVersion(bytes));
105+
106+ outn("Directory root", getDirectoryRoot(bytes));
107+ outn("Garbage root", getGarbageRoot(bytes));
108+ outn("Initial pages", getInitialPages(bytes));
109+ outn("Next available page", getNextAvailablePage(bytes));
110+ outn("Extended page count", getExtendedPageCount(bytes));
111+ outn("Pages per extension", getExtensionPages(bytes));
112+ outn("Maximum pages", getMaximumPages(bytes));
113+
114+ outn("Fetch counter", getfetchCounter(bytes));
115+ outn("Get counter", getGetCounter(bytes));
116+ outn("Read counter", getReadCounter(bytes));
117+ outn("Remove counter", getRemoveCounter(bytes));
118+ outn("Store counter", getStoreCounter(bytes));
119+ outn("Traverse counter", getTraverseCounter(bytes));
120+ outn("Write counter", getWriteCounter(bytes));
121+
122+ }
123+
124+ private void outd(final String legend, final long value) {
125+ postMessage(String.format("%30s: %s", legend, SDF.format(new Date(value))), Task.LOG_NORMAL);
126+ }
127+
128+ private void outn(final String legend, final long value) {
129+ postMessage(String.format("%30s: %,12d", legend, value), Task.LOG_NORMAL);
130+ }
131+
132+ @Override
133+ public String getStatus() {
134+ return "";
135+ }
136+
137+ }
138+
139+ public static void main(final String[] args) throws Exception {
140+ final ArgParser ap = new ArgParser("VolumeHeader", args, ARGS_TEMPLATE).strict();
141+ if (ap.isUsageOnly()) {
142+ return;
143+ }
144+ final Task task = new VolumeInfoTask(ap.getStringValue("path"));
145+ task.setMessageWriter(new PrintWriter(System.out));
146+ task.runTask();
147+ }
148+
149 }

Subscribers

People subscribed via source and target branches