[SERVER-1376] Yield in QueryPlanSet Created: 07/Jul/10 Updated: 12/Jul/16 Resolved: 08/Jul/10 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | 1.5.5 |
| Type: | Bug | Priority: | Critical - P2 |
| Reporter: | Eliot Horowitz (Inactive) | Assignee: | Aaron Staple |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||
| Operating System: | ALL | ||||
| Participants: | |||||
| Description |
|
if finding the first object is slow, update doesn't yield. Constructors should be instantanous only next() should iterate, (gdb) |
| Comments |
| Comment by Eliot Horowitz (Inactive) [ 07/Jul/10 ] |
|
Ok that's a bug Let's bite the bullet and move to that part to UserQueryOp |
| Comment by Aaron Staple [ 07/Jul/10 ] |
|
I might be missing something, but it looks like there may be an issue with UserQueryOp - multiple UserQueryOps are going to be alive at the same time, each with their own cursors. But not all of them are necessarily going to have client cursors when one of the UserQueryOps yields. If we fix this by making QueryPlanSet in charge of administering yielding, the same solution will work for Update and Delete. Will take more than an hour to do it. |
| Comment by Eliot Horowitz (Inactive) [ 07/Jul/10 ] |
|
Do queries work the same way or are those different? I added yielding in UserQueryOp itself, so perhaps different. |
| Comment by Eliot Horowitz (Inactive) [ 07/Jul/10 ] |
|
How hard is it to make QueryPLanSet yield? If its more than an hour, lets have remove and update use "best guess" |
| Comment by Eliot Horowitz (Inactive) [ 07/Jul/10 ] |
|
Ok - lets make an option to QueryPlanSet to yield. Want an option, because some things could have cached items so need be aware of it. |
| Comment by Aaron Staple [ 07/Jul/10 ] |
|
An alternative quick and dirty fix is to have update use a "best guess" plan. Let me know what you want me to do. |
| Comment by Aaron Staple [ 07/Jul/10 ] |
|
So, both before and after MultiCursor on an update we did the following: 1) find first match using all plans in parallel By the time the update implementation has a cursor, 1 has already happened. Making QueryPlanSet, etc yield is a relatively general solution. |
| Comment by Eliot Horowitz (Inactive) [ 07/Jul/10 ] |
|
Oh - is the issue that's its trying different plans? |
| Comment by Aaron Staple [ 07/Jul/10 ] |
|
Yielding in UpdateOp is tricky because we'll need to have all the different UpdateOps keep a temp client cursor. I can add an option to QueryPlanSet, etc, to allow yielding while the different plans are running. Will be a bit of work. |
| Comment by Eliot Horowitz (Inactive) [ 07/Jul/10 ] |
|
Why does the scan have to happen there? Shouldn't next be instaneous? Don't want to fix in UpdateOp as this similar logic in many places. |
| Comment by Aaron Staple [ 07/Jul/10 ] |
|
This behavior is the same as we had without the multi cursor. Before MultiCursor we did: QueryPlanSet qps( ns, patternOrig, BSONObj() ); That runOp found the first match, so it could take a while and there was no yielding happening. I could make the constructor for MultiCursor instantaneous, but then when you did init() or next() you would still do a long scan without yielding. I think we can fix this by adding a yield to UpdateOp. |