You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by mr...@apache.org on 2015/06/30 17:01:39 UTC
svn commit: r1688469 - in /jackrabbit/oak/branches/1.2: ./
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreTest.java
Author: mreutegg
Date: Tue Jun 30 15:01:39 2015
New Revision: 1688469
URL: http://svn.apache.org/r1688469
Log:
OAK-3023: Long running MongoDB query may block other threads
Merged revision 1688453 from trunk
Added:
jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreTest.java
- copied unchanged from r1688453, jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStoreTest.java
Modified:
jackrabbit/oak/branches/1.2/ (props changed)
jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
Propchange: jackrabbit/oak/branches/1.2/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Jun 30 15:01:39 2015
@@ -1,3 +1,3 @@
/jackrabbit/oak/branches/1.0:1665962
-/jackrabbit/oak/trunk:1672350,1672468,1672537,1672603,1672642,1672644,1672834-1672835,1673351,1673410,1673414-1673415,1673436,1673644,1673662-1673664,1673669,1673695,1673738,1673787,1673791,1674046,1674065,1674075,1674107,1674228,1674780,1674880,1675054-1675055,1675319,1675332,1675354,1675357,1675382,1675555,1675566,1675593,1676198,1676237,1676407,1676458,1676539,1676670,1676693,1676703,1676725,1677579,1677581,1677609,1677611,1677774,1677788,1677797,1677804,1677806,1677939,1677991,1678173,1678323,1678758,1678938,1678954,1679144,1679165,1679191,1679232,1679235,1679958,1679961,1680182,1680222,1680232,1680236,1680461,1680633,1680643,1680805-1680806,1680903,1681282,1681767,1681918,1682218,1682235,1682437,1682494,1682555,1682855,1682904,1683059,1683089,1683213,1683249,1683259,1683278,1683323,1683687,1683700,1684174-1684175,1684186,1684376,1684442,1684561,1684570,1684601,1684618,1684868,1685023,1685370,1685552,1685589,1685840,1685999,1686097,1686162,1686229,1686234,1686253,1686414,1686780
,1686854,1686857,1686971,1687053-1687055,1687198,1687220,1687239-1687240,1687301,1687441,1687553,1688089-1688090,1688349,1688421,1688436
+/jackrabbit/oak/trunk:1672350,1672468,1672537,1672603,1672642,1672644,1672834-1672835,1673351,1673410,1673414-1673415,1673436,1673644,1673662-1673664,1673669,1673695,1673738,1673787,1673791,1674046,1674065,1674075,1674107,1674228,1674780,1674880,1675054-1675055,1675319,1675332,1675354,1675357,1675382,1675555,1675566,1675593,1676198,1676237,1676407,1676458,1676539,1676670,1676693,1676703,1676725,1677579,1677581,1677609,1677611,1677774,1677788,1677797,1677804,1677806,1677939,1677991,1678173,1678323,1678758,1678938,1678954,1679144,1679165,1679191,1679232,1679235,1679958,1679961,1680182,1680222,1680232,1680236,1680461,1680633,1680643,1680805-1680806,1680903,1681282,1681767,1681918,1682218,1682235,1682437,1682494,1682555,1682855,1682904,1683059,1683089,1683213,1683249,1683259,1683278,1683323,1683687,1683700,1684174-1684175,1684186,1684376,1684442,1684561,1684570,1684601,1684618,1684868,1685023,1685370,1685552,1685589,1685840,1685999,1686097,1686162,1686229,1686234,1686253,1686414,1686780
,1686854,1686857,1686971,1687053-1687055,1687198,1687220,1687239-1687240,1687301,1687441,1687553,1688089-1688090,1688349,1688421,1688436,1688453
/jackrabbit/trunk:1345480
Modified: jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java?rev=1688469&r1=1688468&r2=1688469&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java (original)
+++ jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java Tue Jun 30 15:01:39 2015
@@ -43,6 +43,7 @@ import com.google.common.collect.Immutab
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.UncheckedExecutionException;
import com.mongodb.MongoClientURI;
+import com.mongodb.MongoExecutionTimeoutException;
import com.mongodb.QueryOperators;
import com.mongodb.ReadPreference;
@@ -173,6 +174,17 @@ public class MongoDocumentStore implemen
private final long maxQueryTimeMS =
Long.getLong("oak.mongo.maxQueryTimeMS", TimeUnit.MINUTES.toMillis(1));
+ /**
+ * Duration in milliseconds after a mongo query with an additional
+ * constraint (e.g. _modified) on the NODES collection times out and is
+ * executed again without holding a {@link TreeLock} and without updating
+ * the cache with data retrieved from MongoDB.
+ * <p>
+ * Default is 3000 (three seconds).
+ */
+ private long maxLockedQueryTimeMS =
+ Long.getLong("oak.mongo.maxLockedQueryTimeMS", TimeUnit.SECONDS.toMillis(3));
+
private String lastReadWriteMode;
private final Map<String, String> metadata;
@@ -489,6 +501,36 @@ public class MongoDocumentStore implemen
String indexedProperty,
long startValue,
int limit) {
+ boolean withLock = true;
+ if (collection == Collection.NODES && indexedProperty != null) {
+ long maxQueryTime;
+ if (maxQueryTimeMS > 0) {
+ maxQueryTime = Math.min(maxQueryTimeMS, maxLockedQueryTimeMS);
+ } else {
+ maxQueryTime = maxLockedQueryTimeMS;
+ }
+ try {
+ return queryInternal(collection, fromKey, toKey, indexedProperty,
+ startValue, limit, maxQueryTime, true);
+ } catch (MongoExecutionTimeoutException e) {
+ LOG.info("query timed out after {} milliseconds and will be retried without lock {}",
+ maxQueryTime, Lists.newArrayList(fromKey, toKey, indexedProperty, startValue, limit));
+ withLock = false;
+ }
+ }
+ return queryInternal(collection, fromKey, toKey, indexedProperty,
+ startValue, limit, maxQueryTimeMS, withLock);
+ }
+
+ @Nonnull
+ <T extends Document> List<T> queryInternal(Collection<T> collection,
+ String fromKey,
+ String toKey,
+ String indexedProperty,
+ long startValue,
+ int limit,
+ long maxQueryTime,
+ boolean withLock) {
log("query", fromKey, toKey, indexedProperty, startValue, limit);
DBCollection dbCollection = getDBCollection(collection);
QueryBuilder queryBuilder = QueryBuilder.start(Document.ID);
@@ -518,16 +560,16 @@ public class MongoDocumentStore implemen
}
DBObject query = queryBuilder.get();
String parentId = Utils.getParentIdFromLowerLimit(fromKey);
- TreeLock lock = acquireExclusive(parentId != null ? parentId : "");
final long start = PERFLOG.start();
+ TreeLock lock = withLock ? acquireExclusive(parentId != null ? parentId : "") : null;
try {
DBCursor cursor = dbCollection.find(query).sort(BY_ID_ASC);
if (!disableIndexHint) {
cursor.hint(hint);
}
- if (maxQueryTimeMS > 0) {
+ if (maxQueryTime > 0) {
// OAK-2614: set maxTime if maxQueryTimeMS > 0
- cursor.maxTime(maxQueryTimeMS, TimeUnit.MILLISECONDS);
+ cursor.maxTime(maxQueryTime, TimeUnit.MILLISECONDS);
}
ReadPreference readPreference =
getMongoReadPreference(collection, parentId, getDefaultReadPreference(collection));
@@ -544,7 +586,9 @@ public class MongoDocumentStore implemen
for (int i = 0; i < limit && cursor.hasNext(); i++) {
DBObject o = cursor.next();
T doc = convertFromDBObject(collection, o);
- if (collection == Collection.NODES && doc != null) {
+ if (collection == Collection.NODES
+ && doc != null
+ && lock != null) {
doc.seal();
String id = doc.getId();
CacheValue cacheKey = new StringValue(id);
@@ -573,7 +617,9 @@ public class MongoDocumentStore implemen
}
return list;
} finally {
- lock.unlock();
+ if (lock != null) {
+ lock.unlock();
+ }
PERFLOG.end(start, 1, "query for children from [{}] to [{}]", fromKey, toKey);
}
}
@@ -1303,6 +1349,10 @@ public class MongoDocumentStore implemen
this.clock = clock;
}
+ void setMaxLockedQueryTimeMS(long maxLockedQueryTimeMS) {
+ this.maxLockedQueryTimeMS = maxLockedQueryTimeMS;
+ }
+
private final static class TreeLock {
private final Lock parentLock;