Author: mduerig
Date: Mon Mar 2 17:04:59 2015
New Revision: 1663362
URL: http://svn.apache.org/r1663362
Log:
OAK-2561: Add option to oak-run check runmode to check consistency of binary
properties
--bin n option to check the first n bytes of binary properties.
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/tooling/ConsistencyChecker.java
jackrabbit/oak/trunk/oak-run/README.md
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/tooling/ConsistencyChecker.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/tooling/ConsistencyChecker.java?rev=1663362&r1=1663361&r2=1663362&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/tooling/ConsistencyChecker.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/tooling/ConsistencyChecker.java
Mon Mar 2 17:04:59 2015
@@ -20,6 +20,9 @@
package org.apache.jackrabbit.oak.plugins.segment.file.tooling;
import static com.google.common.collect.Sets.newHashSet;
+import static java.lang.Math.min;
+import static org.apache.jackrabbit.oak.api.Type.BINARIES;
+import static org.apache.jackrabbit.oak.api.Type.BINARY;
import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
import static org.apache.jackrabbit.oak.commons.PathUtils.denotesRoot;
import static org.apache.jackrabbit.oak.commons.PathUtils.getName;
@@ -28,9 +31,12 @@ import static org.apache.jackrabbit.oak.
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.util.Set;
+import org.apache.jackrabbit.oak.api.Blob;
import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore;
import org.apache.jackrabbit.oak.plugins.segment.file.FileStore.ReadOnlyStore;
import org.apache.jackrabbit.oak.plugins.segment.file.JournalReader;
@@ -59,11 +65,12 @@ public class ConsistencyChecker {
* to access the root node otherwise.
* @param debugInterval number of seconds between printing progress
information to
* the console during the full traversal phase.
+ * @param binLen number of bytes to read from binary properties.
-1 for all.
* @return the latest consistent revision out of the revisions listed in
the journal.
* @throws IOException
*/
public static String checkConsistency(File directory, String
journalFileName,
- boolean fullTraversal, long debugInterval) throws IOException {
+ boolean fullTraversal, long debugInterval, long binLen) throws
IOException {
print("Searching for last good revision in {}", journalFileName);
JournalReader journal = new JournalReader(new File(directory,
journalFileName));
Set<String> badPaths = newHashSet();
@@ -73,9 +80,9 @@ public class ConsistencyChecker {
for (String revision : journal) {
print("Checking revision {}", revision);
revisionCount++;
- String badPath = checker.check(revision, badPaths);
+ String badPath = checker.check(revision, badPaths, binLen);
if (badPath == null && fullTraversal) {
- badPath = checker.traverse(revision);
+ badPath = checker.traverse(revision, binLen);
}
if (badPath == null) {
print("Found latest good revision {}", revision);
@@ -115,12 +122,13 @@ public class ConsistencyChecker {
*
* @param revision revision to check
* @param paths paths to check
+ * @param binLen number of bytes to read from binary properties. -1 for
all.
* @return Path of the first inconsistency detected or {@code null} if
none.
*/
- public String check(String revision, Set<String> paths) {
+ public String check(String revision, Set<String> paths, long binLen) {
store.setRevision(revision);
for (String path : paths) {
- String err = checkPath(path);
+ String err = checkPath(path, binLen);
if (err != null) {
return err;
}
@@ -128,7 +136,7 @@ public class ConsistencyChecker {
return null;
}
- private String checkPath(String path) {
+ private String checkPath(String path, long binLen) {
try {
print("Checking {}", path);
NodeState root = new SegmentNodeStore(store).getRoot();
@@ -136,9 +144,9 @@ public class ConsistencyChecker {
String name = getName(path);
NodeState parent = getNode(root, parentPath);
if (!denotesRoot(path) && parent.hasChildNode(name)) {
- return traverse(parent.getChildNode(name), path, false);
+ return traverse(parent.getChildNode(name), path, false,
binLen);
} else {
- return traverse(parent, parentPath, false);
+ return traverse(parent, parentPath, false, binLen);
}
} catch (RuntimeException e) {
print("Error while checking {}: {}", path, e.getMessage());
@@ -152,13 +160,14 @@ public class ConsistencyChecker {
/**
* Travers the given {@code revision}
* @param revision revision to travers
+ * @param binLen number of bytes to read from binary properties. -1 for
all.
*/
- public String traverse(String revision) {
+ public String traverse(String revision, long binLen) {
try {
store.setRevision(revision);
nodeCount = 0;
propertyCount = 0;
- String result = traverse(new SegmentNodeStore(store).getRoot(),
"/", true);
+ String result = traverse(new SegmentNodeStore(store).getRoot(),
"/", true, binLen);
print("Traversed {} nodes and {} properties", nodeCount,
propertyCount);
return result;
} catch (RuntimeException e) {
@@ -167,20 +176,29 @@ public class ConsistencyChecker {
}
}
- private String traverse(NodeState node, String path, boolean deep) {
+ private String traverse(NodeState node, String path, boolean deep, long
binLen) {
try {
debug("Traversing {}", path);
nodeCount++;
for (PropertyState propertyState : node.getProperties()) {
debug("Checking {}/{}", path, propertyState);
- propertyState.getValue(propertyState.getType());
+ Type<?> type = propertyState.getType();
+ if (type == BINARY) {
+ traverse(propertyState.getValue(BINARY), binLen);
+ } else if (type == BINARIES) {
+ for (Blob blob : propertyState.getValue(BINARIES)) {
+ traverse(blob, binLen);
+ }
+ } else {
+ propertyState.getValue(type);
+ }
propertyCount++;
}
for (ChildNodeEntry cne : node.getChildNodeEntries()) {
String childName = cne.getName();
NodeState child = cne.getNodeState();
if (deep) {
- String result = traverse(child, concat(path, childName),
deep);
+ String result = traverse(child, concat(path, childName),
true, binLen);
if (result != null) {
return result;
}
@@ -190,6 +208,24 @@ public class ConsistencyChecker {
} catch (RuntimeException e) {
print("Error while traversing {}: {}", path, e.getMessage());
return path;
+ } catch (IOException e) {
+ print("Error while traversing {}: {}", path, e.getMessage());
+ return path;
+ }
+ }
+
+ private static void traverse(Blob blob, long length) throws IOException {
+ InputStream s = blob.getNewStream();
+ if (length > 0) {
+ try {
+ byte[] buffer = new byte[8192];
+ int l = s.read(buffer, 0, (int) min(buffer.length, length));
+ while (l >= 0 && (length -= l) > 0) {
+ l = s.read(buffer, 0, (int) min(buffer.length, length));
+ }
+ } finally {
+ s.close();
+ }
}
}
Modified: jackrabbit/oak/trunk/oak-run/README.md
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/README.md?rev=1663362&r1=1663361&r2=1663362&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/README.md (original)
+++ jackrabbit/oak/trunk/oak-run/README.md Mon Mar 2 17:04:59 2015
@@ -100,6 +100,9 @@ The 'check' mode checks the storage of t
$ java -jar oak-run-*.jar check <options>
+ --bin [Long] read the n first bytes from binary
+ properties. -1 for all bytes.
+ (default: 0)
--deep [Long] enable deep consistency checking. An
optional long specifies the number
of seconds between progress
Modified:
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java?rev=1663362&r1=1663361&r2=1663362&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java
(original)
+++
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java
Mon Mar 2 17:04:59 2015
@@ -709,6 +709,9 @@ public class Main {
"deep", "enable deep consistency checking. An optional long " +
"specifies the number of seconds between progress
notifications")
.withOptionalArg().ofType(Long.class).defaultsTo(Long.MAX_VALUE);
+ ArgumentAcceptingOptionSpec<Long> bin = parser.accepts(
+ "bin", "read the n first bytes from binary properties. -1 for
all bytes.")
+ .withOptionalArg().ofType(Long.class).defaultsTo(0L);
OptionSet options = parser.parse(args);
@@ -727,8 +730,12 @@ public class Main {
String journalFileName = journal.value(options);
boolean fullTraversal = options.has(deep);
long debugLevel = deep.value(options);
+ long binLen = bin.value(options);
+ if (binLen < 0) {
+ binLen = Long.MAX_VALUE;
+ }
- checkConsistency(dir, journalFileName, fullTraversal, debugLevel);
+ checkConsistency(dir, journalFileName, fullTraversal, debugLevel,
binLen);
}
private static void debugTarFile(FileStore store, String[] args) {