[SERVER-41011] Server may crash when running $where on non-existent collection Created: 03/May/19 Updated: 15/Jul/19 Resolved: 29/May/19 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Querying |
| Affects Version/s: | 4.1.10 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Ian Boros | Assignee: | Xiangyu Yao (Inactive) |
| Resolution: | Duplicate | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||||||||||||||
| Operating System: | ALL | ||||||||||||||||||||
| Sprint: | Execution Team 2019-06-03 | ||||||||||||||||||||
| Participants: | |||||||||||||||||||||
| Linked BF Score: | 6 | ||||||||||||||||||||
| Description |
|
As discovered by gregory.wlodarek, this will crash the server with an invariant when run on a secondary:
Here is the sequence of events that cause the find() command to trigger an invariant: 1a) The construction of the AutoGetCollection causes a view catalog lookup and thus, refresh because of the recently created view. 1b) The refresh causes us to read from system.views, which "activates" the recovery unit when the WiredTigerCursor is created. Note that this refresh only happens when the collection does not exist. 1c) After the AutoGetCollection is constructed This entire block of AutoGetCollectionForRead() is skipped because the collection does not exist. 2) We initialize the WhereMatchExpression which creates a JS scope. As part of creating the JS scope, we create a DBDirectClient for reading from system.js. 3) We run a find() query using the DBDirectClient, and enter FindCmd::Invocation::run() again. We create an AutoGetCollectionForReadCommand, but this time, on system.js. 3a) Inside of AutoGetCollectionForRead() we decide that since we're on a secondary and the readConcern is "local", we should read from the last applied timestamp. 3b) We try to set the recovery unit's timestamp read source to kLastApplied here, which triggers this invariant, because the recovery unit was made "active" during the view catalog lookup:
I could not repro this on 4.0 because in that branch, the invariant allows for _timestampReadSource to be kUnset. See here
|
| Comments |
| Comment by Gregory Wlodarek [ 15/Jul/19 ] |
|
Verified by hand that |
| Comment by Xiangyu Yao (Inactive) [ 29/May/19 ] |
|
Discussed with milkie and we decided not to change the findCmd behavior. Marking this as a dup of |
| Comment by Xiangyu Yao (Inactive) [ 28/May/19 ] |
|
Seems the current behavior is that we continue findCmd even if the collection does not exist. code |
| Comment by Xiangyu Yao (Inactive) [ 21/May/19 ] |
|
I think the problem can be solved by |