-
Type: Bug
-
Resolution: Done
-
Priority: Major - P3
-
Affects Version/s: 3.2.1, 3.3.0
-
Component/s: WiredTiger
-
Fully Compatible
-
ALL
-
-
Integration F (02/01/16)
-
(copied to CRM)
ISSUE SUMMARY
Operations where the predicate is a rooted $or use a special execution path in the query optimizer in order to perform query plan selection. A rooted $or is a predicate which consists exclusively of a top-level $or statement (although the subexpressions may be arbitrarily complex). For example,
{$or: [{a: 1}, {b: 1}]}
is a rooted $or. By contrast,
{$or: [{a: 1}, {b: 1}], c: 1}
is not a rooted $or due to the implicit AND with the predicate on the c field.
A bug in the plan selection path for such predicates may cause the server to improperly save index cursor state in preparation for yielding locks or to improperly restore index cursor state when re-acquiring locks after a yield.
USER IMPACT
The following commands, if using a rooted $or predicate, are affected:
- aggregate
- count
- delete
- distinct
- find
- findAndModify
- group
- mapReduce
- update
For servers running the WiredTiger storage engine, this issue could cause poor performance due to suboptimal plan selection for a rooted $or query. The following log message is indicative of this issue:
WTIndex::updatePosition -- the new key (...) is less than the previous key (...), which is a bug
Servers running MMAPv1 may experience the following symptoms:
- Poor performance due to suboptimal plan selection for a rooted $or query.
- Failed rooted $or queries due to breaking internal invariants.
- In rare cases, reads from freed memory or other undefined behavior may cause the server to abort.
WORKAROUNDS
The special execution path for rooted $or queries can be disabled at startup or at runtime via the internalQueryPlanOrChildrenIndependently setParameter. You can disable this parameter from the shell as shown below:
db.adminCommand({setParameter: 1, internalQueryPlanOrChildrenIndependently: false});
This configuration option should be set with care, as all rooted $or queries will be diverted from their typical execution path, potentially leading to a loss in performance for such queries.
AFFECTED VERSIONS
MongoDB 3.2.0 and 3.2.1.
FIX VERSION
The fix is included in the 3.2.3 release.
Original description
This causes messages such as save, restore, and invalidate to fail to propagate to the subplans if a yield occurs while choosing a plan for subqueries. This can result in incorrect query execution.
This was introduced by https://github.com/mongodb/mongo/commit/c832bc75#diff-d16091f48e3ffb1cc4c4cc6fd6319c2bR326.
Original Title and Description:
WTIndex::updatePosition - the new key is less than the previous key
When I use a query using compund indexes, the following message is shown several times per second on log:
2016-01-22T15:21:16.865-0200 I STORAGE [conn2] WTIndex::updatePosition -- the new key ( 64558C7B28CCB061D504E068AB78800001523FD86A6C042087F1) is less than the previous key (64558C7B28CCB061D504E0692C78800001523FE4DFA40420EED9), which is a bug.
A dump to reproduce the bug is attached.
If I run the query without creating indexes, it works fine both on MMAPv1 and WiredTiger:
var userId = ObjectId('558c7b28ccb061d504e0692c'); var queryStart = ISODate('2016-01-14T09:00:00.000-0200'); var queryEnd = ISODate('2016-01-14T12:00:00.000-0200'); db.bug_test.count({ $or: [ { userId: userId, end: { $gte: queryStart, $lt: queryEnd } }, { userId: userId, start: { $gte: queryStart, $lt: queryEnd } }, { userId: userId, start: { $lt: queryStart }, end: { $gt: queryEnd } } ]});
If I create the following indexes, it works fine on MMAPv1 but triggers the bug on WiredTiger:
db.bug_test.createIndex({ userId: 1, start: 1 }); db.bug_test.createIndex({ userId: 1, end: 1 });
- is duplicated by
-
SERVER-22288 Performance degradation after upgrade to 3.2.1, MongoDB log is full of "the new key (...) is less than the previous key" messages
- Closed
-
SERVER-22482 Cache growing to 100% followed by crash
- Closed