Author: mreutegg
Date: Tue Feb 2 14:16:03 2016
New Revision: 1728123
URL: http://svn.apache.org/viewvc?rev=1728123&view=rev
Log:
OAK-3071: Add a compound index for _modified + _id
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java?rev=1728123&r1=1728122&r2=1728123&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
Tue Feb 2 14:16:03 2016
@@ -102,6 +102,8 @@ import static com.google.common.collect.
import static com.google.common.collect.Maps.filterKeys;
import static com.google.common.collect.Maps.filterValues;
import static com.google.common.collect.Sets.difference;
+import static
org.apache.jackrabbit.oak.plugins.document.mongo.MongoUtils.createIndex;
+import static
org.apache.jackrabbit.oak.plugins.document.mongo.MongoUtils.hasIndex;
/**
* A document store that uses MongoDB as the backend.
@@ -192,6 +194,8 @@ public class MongoDocumentStore implemen
private DocumentStoreStatsCollector stats;
+ private boolean hasModifiedIdCompoundIndex = true;
+
public MongoDocumentStore(DB db, DocumentMK.Builder builder) {
String version = checkVersion(db);
metadata = ImmutableMap.<String,String>builder()
@@ -210,40 +214,31 @@ public class MongoDocumentStore implemen
// indexes:
// the _id field is the primary key, so we don't need to define it
- DBObject index = new BasicDBObject();
- // modification time (descending)
- index.put(NodeDocument.MODIFIED_IN_SECS, -1L);
- DBObject options = new BasicDBObject();
- options.put("unique", Boolean.FALSE);
- nodes.createIndex(index, options);
+
+ // compound index on _modified and _id
+ if (nodes.count() == 0) {
+ // this is an empty store, create a compound index
+ // on _modified and _id (OAK-3071)
+ createIndex(nodes, new String[]{NodeDocument.MODIFIED_IN_SECS,
Document.ID},
+ new boolean[]{true, true}, false, false);
+ } else if (!hasIndex(nodes, NodeDocument.MODIFIED_IN_SECS,
Document.ID)) {
+ hasModifiedIdCompoundIndex = false;
+ LOG.warn("Detected an upgrade from Oak version <= 1.2. For optimal
" +
+ "performance it is recommended to create a compound index
" +
+ "for the 'nodes' collection on {_modified:1, _id:1}.");
+ }
// index on the _bin flag to faster access nodes with binaries for GC
- index = new BasicDBObject();
- index.put(NodeDocument.HAS_BINARY_FLAG, 1);
- options = new BasicDBObject();
- options.put("unique", Boolean.FALSE);
- options.put("sparse", Boolean.TRUE);
- this.nodes.createIndex(index, options);
-
- index = new BasicDBObject();
- index.put(NodeDocument.DELETED_ONCE, 1);
- options = new BasicDBObject();
- options.put("unique", Boolean.FALSE);
- options.put("sparse", Boolean.TRUE);
- this.nodes.createIndex(index, options);
-
- index = new BasicDBObject();
- index.put(NodeDocument.SD_TYPE, 1);
- options = new BasicDBObject();
- options.put("unique", Boolean.FALSE);
- options.put("sparse", Boolean.TRUE);
- this.nodes.createIndex(index, options);
-
- index = new BasicDBObject();
- index.put(JournalEntry.MODIFIED, 1);
- options = new BasicDBObject();
- options.put("unique", Boolean.FALSE);
- this.journal.createIndex(index, options);
+ createIndex(nodes, NodeDocument.HAS_BINARY_FLAG, true, false, true);
+
+ // index on _deleted for fast lookup of potentially garbage
+ createIndex(nodes, NodeDocument.DELETED_ONCE, true, false, true);
+
+ // index on _sdType for fast lookup of split documents
+ createIndex(nodes, NodeDocument.SD_TYPE, true, false, true);
+
+ // index on _modified for journal entries
+ createIndex(journal, JournalEntry.MODIFIED, true, false, false);
this.nodeLocks = new TreeNodeDocumentLocks();
this.nodesCache = builder.buildNodeDocumentCache(this, nodeLocks);
@@ -595,7 +590,7 @@ public class MongoDocumentStore implemen
try {
lockTime = withLock ? watch.elapsed(TimeUnit.MILLISECONDS) : -1;
DBCursor cursor = dbCollection.find(query).sort(BY_ID_ASC);
- if (!disableIndexHint) {
+ if (!disableIndexHint && !hasModifiedIdCompoundIndex) {
cursor.hint(hint);
}
if (maxQueryTime > 0) {
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreTest.java?rev=1728123&r1=1728122&r2=1728123&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreTest.java
Tue Feb 2 14:16:03 2016
@@ -27,12 +27,15 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.document.Collection;
import org.apache.jackrabbit.oak.plugins.document.Document;
import org.apache.jackrabbit.oak.plugins.document.DocumentMK;
+import org.apache.jackrabbit.oak.plugins.document.JournalEntry;
import org.apache.jackrabbit.oak.plugins.document.MongoUtils;
import org.apache.jackrabbit.oak.plugins.document.NodeDocument;
import org.apache.jackrabbit.oak.plugins.document.util.Utils;
import org.junit.Test;
+import static
org.apache.jackrabbit.oak.plugins.document.mongo.MongoUtils.hasIndex;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -79,6 +82,17 @@ public class MongoDocumentStoreTest exte
fail("No query timeout triggered even after adding " + index + "
nodes");
}
+ @Test
+ public void defaultIndexes() {
+ assertTrue(hasIndex(store.getDBCollection(Collection.NODES),
Document.ID));
+ assertTrue(hasIndex(store.getDBCollection(Collection.NODES),
NodeDocument.SD_TYPE));
+ assertTrue(hasIndex(store.getDBCollection(Collection.NODES),
NodeDocument.DELETED_ONCE));
+ assertTrue(hasIndex(store.getDBCollection(Collection.NODES),
NodeDocument.HAS_BINARY_FLAG));
+ assertTrue(hasIndex(store.getDBCollection(Collection.NODES),
NodeDocument.MODIFIED_IN_SECS, Document.ID));
+ assertFalse(hasIndex(store.getDBCollection(Collection.NODES),
NodeDocument.MODIFIED_IN_SECS));
+ assertTrue(hasIndex(store.getDBCollection(Collection.JOURNAL),
JournalEntry.MODIFIED));
+ }
+
static final class TestStore extends MongoDocumentStore {
AtomicInteger queriesWithoutLock = new AtomicInteger();