[MDEV-4556] Server crashes in SEL_ARG::rb_insert with index_merge+index_merge_sort_union, FORCE INDEX Created: 2013-05-21 Updated: 2014-02-19 Resolved: 2014-02-19 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | None |
| Affects Version/s: | 10.0.2, 5.5.30, 5.3.12 |
| Fix Version/s: | 10.0.4, 5.5.32, 5.3.13 |
| Type: | Bug | Priority: | Blocker |
| Reporter: | Elena Stepanova | Assignee: | Sergei Petrunia |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | optimizer | ||
| Attachments: |
|
||||
| Issue Links: |
|
||||
| Description |
|
Stack trace from:
Also reproducible on current 5.5, 10.0. Not reproducible on MySQL 5.6. Minimal optimizer_switch: index_merge=on,index_merge_sort_union=on
Test case:
EXPLAIN also crashes. |
| Comments |
| Comment by Patryk Pomykalski [ 2013-06-21 ] | ||||||||
|
Attached a possible fix. Not sure if it's the proper way, I got the idea after looking at a similar bug in mysql: http://bazaar.launchpad.net/~mysql/mysql-server/5.6/revision/4764 | ||||||||
| Comment by Sergei Petrunia [ 2013-07-11 ] | ||||||||
|
Analysis: The crash happens in SEL_ARG::rb_insert. The reason for the crash is that $node1->rb_insert($node2) when $node1 is not the root node of the RB tree. The rb_insert is called from SEL_ARG::insert(), which has the same restriction: | ||||||||
| Comment by Sergei Petrunia [ 2013-07-11 ] | ||||||||
|
Tracking it further, one can see that 10th call to key_or() made by the query receives non-root SEL_ARG as argument. Before that, the same SEL_ARG is passed as an argument to key_or() call #4. key_or() call #4 combines two SEL_ARG tree, and the passed tree ceases to be the root node (because of RB-tree rebalancing). Breakpoint 3, key_or (param=0x7fff38543a20, key1=0x7fff2c017030, key2=0x7fff2c0170a0) at /home/psergey/dev2/5.5/sql/opt_range.cc:8854 | ||||||||
| Comment by Sergei Petrunia [ 2013-07-11 ] | ||||||||
|
So, the problem is that merge_same_index_scans() does the following: given a SEL_ARG* pointer $selarg, it The idea in Patryk's patch: call key->clone() before passing it as an argument to key_or() seems to be correct. As for implementation, I don't get what these lines are for: + next_arg->next=0; // Fix last link | ||||||||
| Comment by Sergei Petrunia [ 2013-07-11 ] | ||||||||
|
Another question is, why do we need to call key->clone() in merge_same_index_scans() manually. There is SEL_ARG::use_count, which could be used to provide a kind of copy-on-write protection for SEL_ARG trees. | ||||||||
| Comment by Sergei Petrunia [ 2013-07-11 ] | ||||||||
|
Oracle's patch is for a similar, but different problem. mysql-5.5 (which doesn't have Oracle's fix) doesn't crash on the testcase from this bug. It seems, we don't have access to Oracle's testcase. | ||||||||
| Comment by Patryk Pomykalski [ 2013-07-11 ] | ||||||||
|
I don't get it too... | ||||||||
| Comment by Sergei Petrunia [ 2013-07-11 ] | ||||||||
|
Alternative fix: === modified file 'sql/opt_range.cc' | ||||||||
| Comment by Sergei Petrunia [ 2013-07-11 ] | ||||||||
|
Made a commit with the alternative diff. Will need a review discussion for it | ||||||||
| Comment by Sergei Petrunia [ 2013-07-11 ] | ||||||||
|
Pushed the "Alternative fix". Oracle's bugfix will be dealt with outside of the scope of this bug. Patryk, thanks for the ideas and pointers! | ||||||||
| Comment by Elena Stepanova [ 2014-02-01 ] | ||||||||
|
Although the 'Fix version(s)' field says that it was fixed in 5.3, it seems the patch only made it to 5.5, while 5.3 is still crashing. Maybe it makes sense to backport it. | ||||||||
| Comment by Elena Stepanova [ 2014-02-01 ] | ||||||||
|
Also, I have an apparently related test case which causes wrong results on 5.3. It used to fail on 5.5 too, but the failure was gone after this patch. The full test case is big-gish, so I will attach it as mdev4556-wrong_result.test. The problematic query is:
On the provided data it returns
It's supposed to be 2000. | ||||||||
| Comment by Sergei Petrunia [ 2014-02-19 ] | ||||||||
|
Backported the fix to 5.3 |