[SERVER-52678] [SBE] multi-planner candidate plan may yield before being attached to the OperationContext Created: 06/Nov/20  Updated: 29/Oct/23  Resolved: 25/Nov/20

Status: Closed
Project: Core Server
Component/s: Querying
Affects Version/s: None
Fix Version/s: 4.9.0

Type: Bug Priority: Major - P3
Reporter: David Storch Assignee: David Storch
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
Duplicate
is duplicated by SERVER-52959 Fix invariant failure in IndexScanSta... Closed
Related
is related to SERVER-48555 SBE runtime planners should be able t... Closed
Backwards Compatibility: Fully Compatible
Operating System: ALL
Steps To Reproduce:

Start a server with test commands enabled:

./mongod --setParameter enableTestCommands=true

Run the following script against the server:

(function() {
"use strict";
 
// Turn on SBE.
assert.commandWorked(
    db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: true}));
 
// Make yielding happen frequently.
assert.commandWorked(db.adminCommand({setParameter: 1, internalQueryExecYieldIterations: 1}));
 
db.c.drop();
assert.commandWorked(db.c.createIndex({a: 1}));
assert.commandWorked(db.c.createIndex({b: 1}));
 
assert.commandWorked(db.c.insert([{a: 1, b: 1}, {a: 1, b: 2}, {a: 1, b: 3}]));
 
// This query provokes the crash.
assert.eq(3, db.c.find({a: 1, b: {$gt: 0}}).sort({b: 1}).itcount());
}());

Sprint: Query 2020-11-30, Query 2020-12-14
Participants:
Linked BF Score: 9

 Description   

This is a bug in the implementation of yielding during SBE runtime planning. Yielding during SBE runtime planning was implemented under related ticket SERVER-48555. See "Steps To Reproduce" for a reliable way to provoke the bug.

The problem is as follows. When any of the candidate QuerySolutionNode trees is converted into a corresponding SBE execution plan, that plan is registered for yielding with the PlanYieldPolicySBE. At this point, however, the SBE tree has not yet been attached the OperationContext with a call to attachFromOperationContext().

Once all the SBE plans are actually constructed, we call sbe::MultiPlanner::plan() in order to choose the winning plan. This involves executing the candidate plans, and of course the first step in doing so is to prepare and open the plans. Each candidate is prepared and opened one-by-one.

The trouble is that we only attach the OperationContext to the plan immediately before opening it. Let's say that there are two candidate plans. We have attached the first to the OperationContext and are in the process of opening it. The second plan remains unattached and unopened. If a yield occurs during the open of the first candidate plan, then we attempt to save and restore each of the two candidate plans since both are registered for yielding. However, this invariant fails for the second (unattached) candidate plan because it expects the index scan stage to be attached to the OperationContext prior to yielding.



 Comments   
Comment by Githook User [ 25/Nov/20 ]

Author:

{'name': 'David Storch', 'email': 'david.storch@mongodb.com', 'username': 'dstorch'}

Message: SERVER-52678 Ensure SBE plan trees are attached to the OperationContext prior to yielding
Branch: master
https://github.com/mongodb/mongo/commit/484e365d40fc6b3d34c6a1a91c06528295fab3f8

Generated at Thu Feb 08 05:28:42 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.