Bug #47123 | Endless 100% CPU loop with STRAIGHT_JOIN | ||
---|---|---|---|
Submitted: | 4 Sep 2009 7:13 | Modified: | 12 Mar 2010 17:32 |
Reporter: | Philip Stoev | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S2 (Serious) |
Version: | 5.0, 5.1, 5.4 | OS: | Any |
Assigned to: | Alexey Kopytov | CPU Architecture: | Any |
Tags: | join_cache_level |
[4 Sep 2009 7:13]
Philip Stoev
[4 Sep 2009 8:14]
Sveta Smirnova
Thank you for the report. Verified as described.
[13 Oct 2009 8:52]
Alexey Kopytov
A shorter testcase: create table t1(a int, key(a)); insert into t1 values (1), (NULL); select * from t1 where (a <> NULL) and (a <> NULL or a <= NULL);
[15 Oct 2009 11:49]
Bugs System
Pushed into 5.1.41 (revid:joro@sun.com-20091015114812-i3gm8km6gfruny5x) (version source revid:alexey.kopytov@sun.com-20091015104251-0sjkte1joim4pfns) (merge vers: 5.1.41) (pib:13)
[15 Oct 2009 23:38]
Paul DuBois
Noted in 5.1.41 changelog. Incorrect handling of predicates involving NULL by the range optimizer could lead to to an infinite loop during query execution. Setting report to NDI pending push into 5.5.x+.
[16 Oct 2009 8:45]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/87079 3175 Georgi Kodinov 2009-10-16 Revert the fix for bug #47123 until test suite failures are resolved.
[16 Oct 2009 20:20]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/87197 3181 Alexey Kopytov 2009-10-17 Bug #47123: Endless 100% CPU loop with STRAIGHT_JOIN The problem was in incorrect handling of predicates involving NULL as a constant value by the range optimizer. For example, when creating a SEL_ARG node from a condition of the form "field < const" (which would normally result in the "NULL < field < const" SEL_ARG), the special case when "const" is NULL was not taken into account, so "NULL < field < NULL" was produced for the "field < NULL" condition. As a result, SEL_ARG structures of this form could not be further optimized which in turn could lead to incorrectly constructed SEL_ARG trees. In particular, code assuming SEL_ARG structures to always form a sequence of ordered disjoint intervals could enter an infinite loop under some circumstances. Fixed by changing get_mm_leaf() so that for any sargable predicate except "<=>" involving NULL as a constant, "empty" SEL_ARG is returned, since such a predicate is always false. @ mysql-test/r/partition_pruning.result Fixed a broken test case. @ mysql-test/r/range.result Added a test case for bug #47123. @ mysql-test/r/subselect.result Fixed a broken test cases. @ mysql-test/t/range.test Added a test case for bug #47123. @ sql/opt_range.cc Fixed get_mm_leaf() so that for any sargable predicate except "<=>" involving NULL as a constant, "empty" SEL_ARG is returned, since such a predicate is always false.
[22 Oct 2009 6:32]
Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20091022063126-l0qzirh9xyhp0bpc) (version source revid:alik@sun.com-20091019135554-s1pvptt6i750lfhv) (merge vers: 6.0.14-alpha) (pib:13)
[22 Oct 2009 7:05]
Bugs System
Pushed into 5.5.0-beta (revid:alik@sun.com-20091022060553-znkmxm0g0gm6ckvw) (version source revid:alik@sun.com-20091019132831-5j6xs19ld16m7r8j) (merge vers: 5.5.0-beta) (pib:13)
[22 Oct 2009 19:18]
Paul DuBois
Noted in 5.5.0, 6.0.14 changelogs.
[4 Nov 2009 9:24]
Bugs System
Pushed into 5.1.41 (revid:joro@sun.com-20091104092152-qz96bzlf2o1japwc) (version source revid:alexey.kopytov@sun.com-20091016201951-fsht0wm8xn8vkzsx) (merge vers: 5.1.41) (pib:13)
[11 Nov 2009 6:48]
Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20091110093407-rw5g8dys2baqkt67) (version source revid:alik@sun.com-20091109080109-7dxapd5y5pxlu08w) (merge vers: 6.0.14-alpha) (pib:13)
[11 Nov 2009 6:56]
Bugs System
Pushed into 5.5.0-beta (revid:alik@sun.com-20091109115615-nuohp02h8mdrz8m2) (version source revid:alik@sun.com-20091105090203-cls5j6k3ohu04xpt) (merge vers: 5.5.0-beta) (pib:13)
[1 Dec 2009 5:27]
Igor Babaev
Alexey, After your patch, for your test case, we have: mysql> EXPLAIN SELECT * FROM t1 WHERE a <> NULL; +----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+ | 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE noticed after reading const tables | +----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+ 1 row in set (10.68 sec) Yet, if we drop the index we get: mysql > drop index a on t1; Query OK, 4 rows affected (0.03 sec) Records: 4 Duplicates: 0 Warnings: 0 (I've added two extra records to t1 with values '2' and '3'). mysql> EXPLAIN SELECT * FROM t1 WHERE a <> NULL; +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | t1 | ALL | NULL | NULL | NULL | NULL | 4 | Using where | +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ This seems to me to be counter-intuitive. I would expect to get "Impossible where" in this case too. I think it happens because the null-rejecting predicates returning always UNKNOWN must be caught much earlier, somewhere in optimize_cond(). In this case for the following query: mysql> EXPLAIN SELECT * FROM t1, t1 t2 WHERE t1.a <> NULL or t2.a <> NULL; +----+-------------+-------+-------+---------------+------+---------+------+------+---------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+------+---------+------+------+---------------------------------------------+ | 1 | SIMPLE | t1 | index | a | a | 5 | NULL | 4 | Using index | | 1 | SIMPLE | t2 | index | a | a | 5 | NULL | 4 | Using where; Using index; Using join buffer | +----+-------------+-------+-------+---------------+------+---------+------+------+---------------------------------------------+ 2 rows in set (9.85 sec) you also would get "Impossible where".
[3 Dec 2009 13:19]
Alexey Kopytov
Igor, I agree that the inconsistency with indexed vs. non-indexed column must be fixed. However, I think this should be done in addition to the patch for this bug, not instead of it. If we catch null-rejecting predicates only in optimize_cond(), then the following query will still trigger the bug (i.e. the endless loop in the range optimizer): SELECT * FROM t1, t1 t2 WHERE (t2.a <> t1.a) AND (t2.a <> t1.a or t2.a <= t1.a); So I think we still must catch such predicates in get_mm_leaf() as done in my patch, and do the same in optimize_cond() to be consistent in the non-indexed column case. I have a draft version of the patch for optimize_cond() ready. Please let me know if you agree, I will then apply it as a fix for a separate bug.
[7 Dec 2009 12:55]
Alexey Kopytov
Reported the inconsistency with indexed vs. non-indexed columns separately, bug #49504.
[7 Dec 2009 16:41]
Paul DuBois
Noted in 5.1.40sp1 changelog.
[8 Dec 2009 9:30]
Bugs System
Pushed into 5.1.43 (revid:build@mysql.com-20091208092611-pbno5awyb0v38hs7) (version source revid:build@mysql.com-20091208092611-pbno5awyb0v38hs7) (merge vers: 5.1.43) (pib:13)
[16 Dec 2009 8:34]
Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20091216083311-xorsasf5kopjxshf) (version source revid:alik@sun.com-20091215065750-5m04ogppd5l0pol5) (merge vers: 6.0.14-alpha) (pib:14)
[16 Dec 2009 8:42]
Bugs System
Pushed into 5.5.0-beta (revid:alik@sun.com-20091216082430-s0gtzibcgkv4pqul) (version source revid:alik@sun.com-20091211070127-kl8uvlrv9cr11kva) (merge vers: 5.5.0-beta) (pib:14)
[16 Dec 2009 8:48]
Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20091216083231-rp8ecpnvkkbhtb27) (version source revid:alik@sun.com-20091212203859-fx4rx5uab47wwuzd) (merge vers: 5.6.0-beta) (pib:14)
[18 Dec 2009 10:26]
Bugs System
Pushed into 5.1.41-ndb-7.1.0 (revid:jonas@mysql.com-20091218102229-64tk47xonu3dv6r6) (version source revid:jonas@mysql.com-20091218095730-26gwjidfsdw45dto) (merge vers: 5.1.41-ndb-7.1.0) (pib:15)
[18 Dec 2009 10:42]
Bugs System
Pushed into 5.1.41-ndb-6.2.19 (revid:jonas@mysql.com-20091218100224-vtzr0fahhsuhjsmt) (version source revid:jonas@mysql.com-20091217101452-qwzyaig50w74xmye) (merge vers: 5.1.41-ndb-6.2.19) (pib:15)
[18 Dec 2009 10:57]
Bugs System
Pushed into 5.1.41-ndb-6.3.31 (revid:jonas@mysql.com-20091218100616-75d9tek96o6ob6k0) (version source revid:jonas@mysql.com-20091217154335-290no45qdins5bwo) (merge vers: 5.1.41-ndb-6.3.31) (pib:15)
[18 Dec 2009 11:12]
Bugs System
Pushed into 5.1.41-ndb-7.0.11 (revid:jonas@mysql.com-20091218101303-ga32mrnr15jsa606) (version source revid:jonas@mysql.com-20091218064304-ezreonykd9f4kelk) (merge vers: 5.1.41-ndb-7.0.11) (pib:15)
[12 Mar 2010 14:06]
Bugs System
Pushed into 5.1.44-ndb-7.0.14 (revid:jonas@mysql.com-20100312135944-t0z8s1da2orvl66x) (version source revid:jonas@mysql.com-20100312115609-woou0te4a6s4ae9y) (merge vers: 5.1.44-ndb-7.0.14) (pib:16)
[12 Mar 2010 14:22]
Bugs System
Pushed into 5.1.44-ndb-6.2.19 (revid:jonas@mysql.com-20100312134846-tuqhd9w3tv4xgl3d) (version source revid:jonas@mysql.com-20100312060623-mx6407w2vx76h3by) (merge vers: 5.1.44-ndb-6.2.19) (pib:16)
[12 Mar 2010 14:36]
Bugs System
Pushed into 5.1.44-ndb-6.3.33 (revid:jonas@mysql.com-20100312135724-xcw8vw2lu3mijrhn) (version source revid:jonas@mysql.com-20100312103652-snkltsd197l7q2yg) (merge vers: 5.1.44-ndb-6.3.33) (pib:16)