← Back to team overview

maria-developers team mailing list archive

Re: [Commits] 773ce40: MDEV-10045: Server crashes in Time_and_counter_tracker::incr_loops

 

Hi Sanja,

O the patch fixes the crash. However when I am debugging it, I see the
execution to go like this:

(gdb) wher
  #0  JOIN::optimize_inner (this=0x7fff900087d0) at /home/psergey/dev-git/10.1-dbg6/sql/sql_select.cc:1095
  #1  0x0000555555a8e5f8 in JOIN::optimize (this=0x7fff900087d0) at /home/psergey/dev-git/10.1-dbg6/sql/sql_select.cc:1036
  #2  0x0000555555b277ce in st_select_lex_unit::optimize (this=0x7fff900068a8) at /home/psergey/dev-git/10.1-dbg6/sql/sql_union.cc:747
  #3  0x0000555555b279cb in st_select_lex_unit::exec (this=0x7fff900068a8) at /home/psergey/dev-git/10.1-dbg6/sql/sql_union.cc:780
  #4  0x0000555555d3855f in subselect_union_engine::exec (this=0x7fff90007970) at /home/psergey/dev-git/10.1-dbg6/sql/item_subselect.cc:3785
  #5  0x0000555555d2eb12 in Item_subselect::exec (this=0x7fff9000b028) at /home/psergey/dev-git/10.1-dbg6/sql/item_subselect.cc:684
  #6  0x0000555555d3057e in Item_singlerow_subselect::val_str (this=0x7fff9000b028, str=0x7ffff43b3a40) at /home/psergey/dev-git/10.1-dbg6/sql/item_subselect.cc:1295
  #7  0x0000555555cbca5e in Item_func_conv_charset::Item_func_conv_charset (this=0x7fff90021aa0, thd=0x555557ffda80, a=0x7fff9000b028, cs=0x555556c18b80, cache_if_const=true) at /home/psergey/dev-git/10.1-dbg6/sql/item_strfunc.h:975
  #8  0x0000555555ca1a7b in Item::safe_charset_converter (this=0x7fff9000b028, thd=0x555557ffda80, tocs=0x555556c18b80) at /home/psergey/dev-git/10.1-dbg6/sql/item.cc:1084
  #9  0x0000555555ca4452 in Item_func_or_sum::agg_item_set_converter (this=0x7fff90021828, coll=..., fname=0x555556460377 "<", args=0x7fff900218b0, nargs=2, flags=7, item_sep=1) at /home/psergey/dev-git/10.1-dbg6/sql/item.cc:2141
  #10 0x0000555555cd4106 in Item_func_or_sum::agg_arg_charsets (this=0x7fff90021828, c=..., items=0x7fff900218b0, nitems=2, flags=7, item_sep=1) at /home/psergey/dev-git/10.1-dbg6/sql/item.h:3714
  #11 0x0000555555cd414e in Item_func_or_sum::agg_arg_charsets_for_comparison (this=0x7fff90021828, c=..., items=0x7fff900218b0, nitems=2, item_sep=1) at /home/psergey/dev-git/10.1-dbg6/sql/item.h:3760
  #12 0x0000555555cc10ac in Item_func::setup_args_and_comparator (this=0x7fff90021828, thd=0x555557ffda80, cmp=0x7fff900218e0) at /home/psergey/dev-git/10.1-dbg6/sql/item_cmpfunc.cc:509
  #13 0x0000555555cc11b5 in Item_bool_rowready_func2::fix_length_and_dec (this=0x7fff90021828) at /home/psergey/dev-git/10.1-dbg6/sql/item_cmpfunc.cc:531
  #14 0x0000555555cf022b in Item_func::fix_fields (this=0x7fff90021828, thd=0x555557ffda80, ref=0x7ffff43b3eb0) at /home/psergey/dev-git/10.1-dbg6/sql/item_func.cc:234
  #15 0x0000555555d322fb in Item_allany_subselect::transform_into_max_min (this=0x7fff900077a8, join=0x7fff900087d0) at /home/psergey/dev-git/10.1-dbg6/sql/item_subselect.cc:1969
  #16 0x0000555555bd557d in JOIN::transform_max_min_subquery (this=0x7fff900087d0) at /home/psergey/dev-git/10.1-dbg6/sql/opt_subselect.cc:901
  #17 0x0000555555a8e9c6 in JOIN::optimize_inner (this=0x7fff900087d0) at /home/psergey/dev-git/10.1-dbg6/sql/sql_select.cc:1131
  #18 0x0000555555a8e5f8 in JOIN::optimize (this=0x7fff900087d0) at /home/psergey/dev-git/10.1-dbg6/sql/sql_select.cc:1036
  #19 0x0000555555a44f98 in st_select_lex::optimize_unflattened_subqueries (this=0x555558001b98, const_only=false) at /home/psergey/dev-git/10.1-dbg6/sql/sql_lex.cc:3760
  #20 0x0000555555bdeaee in JOIN::optimize_unflattened_subqueries (this=0x7fff90007ca8) at /home/psergey/dev-git/10.1-dbg6/sql/opt_subselect.cc:5051
  #21 0x0000555555a91dd7 in JOIN::optimize_inner (this=0x7fff90007ca8) at /home/psergey/dev-git/10.1-dbg6/sql/sql_select.cc:2043
  #22 0x0000555555a8e5f8 in JOIN::optimize (this=0x7fff90007ca8) at /home/psergey/dev-git/10.1-dbg6/sql/sql_select.cc:1036
  #23 0x0000555555a96bf2 in mysql_select (thd=0x555557ffda80, rref_pointer_array=0x555558001e10, tables=0x7fff900054b0, wild_num=1, fields=..., conds=0x7fff90007a80, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=2147748608, result=0x7fff90007c88, unit=0x555558001498, select_lex=0x555558001b98) at /home/psergey/dev-git/10.1-dbg6/sql/sql_select.cc:3437
  #24 0x0000555555a8c7fd in handle_select (thd=0x555557ffda80, lex=0x5555580013d0, result=0x7fff90007c88, setup_tables_done_option=0) at /home/psergey/dev-git/10.1-dbg6/sql/sql_select.cc:384
  #25 0x0000555555a5cd61 in execute_sqlcom_select (thd=0x555557ffda80, all_tables=0x7fff900054b0) at /home/psergey/dev-git/10.1-dbg6/sql/sql_parse.cc:5894
  #26 0x0000555555a52a21 in mysql_execute_command (thd=0x555557ffda80) at /home/psergey/dev-git/10.1-dbg6/sql/sql_parse.cc:2960
  #27 0x0000555555a604b1 in mysql_parse (thd=0x555557ffda80, rawbuf=0x7fff90005258 "SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo' UNION SELECT 'bar' )", length=83, parser_state=0x7ffff43b54f0) at /home/psergey/dev-git/10.1-dbg6/sql/sql_parse.cc:7314
  #28 0x0000555555a4ec23 in dispatch_command (command=COM_QUERY, thd=0x555557ffda80, packet=0x555558004031 "SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo' UNION SELECT 'bar' )", packet_length=83) at /home/psergey/dev-git/10.1-dbg6/sql/sql_parse.cc:1486
  #29 0x0000555555a4d944 in do_command (thd=0x555557ffda80) at /home/psergey/dev-git/10.1-dbg6/sql/sql_parse.cc:1107


Note frame #0 and frame #17: JOIN::optimize_inner()  has invoked a few
functions which in turn invoked JOIN::optimize (and JOIN::optimize_inner()) for
the same join.

Before your patch this didn't happen, as the inner call to JOIN::optimize would
find join->optimized= true and return immediately.

In this particular example, the double-optimized join a degenerate 
"SELECT 'foo'", double-optimization has no effect.

I tried to create an example with a non-degenerate join but didn't succeed. 
Looking at the code, I have no certainity that it's impossible to have two
JOIN::optimize calls nest for a non-degenerate join.
If you can explain why this is not possible, please do.

If you can't prove this, I would suggest adding JOIN::inside_optimize_call and
have 
"if (inside_optimize_call) return 0;"
as the first line of JOIN::optimize.





On Wed, Jun 22, 2016 at 11:17:44AM +0200, Oleksandr Byelkin wrote:
> revision-id: 773ce408762b5f8256d4053b6d0d418d15657b92 (mariadb-10.1.14-24-g773ce40)
> parent(s): 63120090f994cc78876944e9f7a76f53337fa46e
> committer: Oleksandr Byelkin
> timestamp: 2016-06-22 11:17:44 +0200
> message:
> 
> MDEV-10045: Server crashes in Time_and_counter_tracker::incr_loops
> 
> Do not set 'optimized' flag until whole optimization procedure is finished.
> 
> ---
>  mysql-test/r/subselect.result                 | 11 +++++++++++
>  mysql-test/r/subselect_no_exists_to_in.result | 11 +++++++++++
>  mysql-test/r/subselect_no_mat.result          | 11 +++++++++++
>  mysql-test/r/subselect_no_opts.result         | 11 +++++++++++
>  mysql-test/r/subselect_no_scache.result       | 11 +++++++++++
>  mysql-test/r/subselect_no_semijoin.result     | 11 +++++++++++
>  mysql-test/t/subselect.test                   | 15 +++++++++++++++
>  sql/sql_select.cc                             |  6 +++---
>  8 files changed, 84 insertions(+), 3 deletions(-)
> 
> diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
> index 6a53199..1ea7000 100644
> --- a/mysql-test/r/subselect.result
> +++ b/mysql-test/r/subselect.result
> @@ -7159,3 +7159,14 @@ f
>  foo
>  drop table t1;
>  SET NAMES default;
> +#
> +# MDEV-10045: Server crashes in Time_and_counter_tracker::incr_loops
> +#
> +SET NAMES utf8;
> +CREATE TABLE t1 (f1 VARCHAR(3), f2 INT UNSIGNED) ENGINE=MyISAM;
> +CREATE TABLE t2 (f3 INT) ENGINE=MyISAM;
> +SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo' UNION SELECT 'bar' );
> +f1	f2	f3
> +DROP TABLE t1, t2;
> +SET NAMES default;
> +End of 10.1 tests
> diff --git a/mysql-test/r/subselect_no_exists_to_in.result b/mysql-test/r/subselect_no_exists_to_in.result
> index aa68434..be5e5b6 100644
> --- a/mysql-test/r/subselect_no_exists_to_in.result
> +++ b/mysql-test/r/subselect_no_exists_to_in.result
> @@ -7159,6 +7159,17 @@ f
>  foo
>  drop table t1;
>  SET NAMES default;
> +#
> +# MDEV-10045: Server crashes in Time_and_counter_tracker::incr_loops
> +#
> +SET NAMES utf8;
> +CREATE TABLE t1 (f1 VARCHAR(3), f2 INT UNSIGNED) ENGINE=MyISAM;
> +CREATE TABLE t2 (f3 INT) ENGINE=MyISAM;
> +SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo' UNION SELECT 'bar' );
> +f1	f2	f3
> +DROP TABLE t1, t2;
> +SET NAMES default;
> +End of 10.1 tests
>  set optimizer_switch=default;
>  select @@optimizer_switch like '%exists_to_in=off%';
>  @@optimizer_switch like '%exists_to_in=off%'
> diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result
> index 754aec1..6dd227c 100644
> --- a/mysql-test/r/subselect_no_mat.result
> +++ b/mysql-test/r/subselect_no_mat.result
> @@ -7152,6 +7152,17 @@ f
>  foo
>  drop table t1;
>  SET NAMES default;
> +#
> +# MDEV-10045: Server crashes in Time_and_counter_tracker::incr_loops
> +#
> +SET NAMES utf8;
> +CREATE TABLE t1 (f1 VARCHAR(3), f2 INT UNSIGNED) ENGINE=MyISAM;
> +CREATE TABLE t2 (f3 INT) ENGINE=MyISAM;
> +SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo' UNION SELECT 'bar' );
> +f1	f2	f3
> +DROP TABLE t1, t2;
> +SET NAMES default;
> +End of 10.1 tests
>  set optimizer_switch=default;
>  select @@optimizer_switch like '%materialization=on%';
>  @@optimizer_switch like '%materialization=on%'
> diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result
> index e05dd4d..389c0f5 100644
> --- a/mysql-test/r/subselect_no_opts.result
> +++ b/mysql-test/r/subselect_no_opts.result
> @@ -7150,4 +7150,15 @@ f
>  foo
>  drop table t1;
>  SET NAMES default;
> +#
> +# MDEV-10045: Server crashes in Time_and_counter_tracker::incr_loops
> +#
> +SET NAMES utf8;
> +CREATE TABLE t1 (f1 VARCHAR(3), f2 INT UNSIGNED) ENGINE=MyISAM;
> +CREATE TABLE t2 (f3 INT) ENGINE=MyISAM;
> +SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo' UNION SELECT 'bar' );
> +f1	f2	f3
> +DROP TABLE t1, t2;
> +SET NAMES default;
> +End of 10.1 tests
>  set @optimizer_switch_for_subselect_test=null;
> diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result
> index 71ade62..a90278c 100644
> --- a/mysql-test/r/subselect_no_scache.result
> +++ b/mysql-test/r/subselect_no_scache.result
> @@ -7165,6 +7165,17 @@ f
>  foo
>  drop table t1;
>  SET NAMES default;
> +#
> +# MDEV-10045: Server crashes in Time_and_counter_tracker::incr_loops
> +#
> +SET NAMES utf8;
> +CREATE TABLE t1 (f1 VARCHAR(3), f2 INT UNSIGNED) ENGINE=MyISAM;
> +CREATE TABLE t2 (f3 INT) ENGINE=MyISAM;
> +SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo' UNION SELECT 'bar' );
> +f1	f2	f3
> +DROP TABLE t1, t2;
> +SET NAMES default;
> +End of 10.1 tests
>  set optimizer_switch=default;
>  select @@optimizer_switch like '%subquery_cache=on%';
>  @@optimizer_switch like '%subquery_cache=on%'
> diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result
> index 43d191b..16aa7b8 100644
> --- a/mysql-test/r/subselect_no_semijoin.result
> +++ b/mysql-test/r/subselect_no_semijoin.result
> @@ -7150,5 +7150,16 @@ f
>  foo
>  drop table t1;
>  SET NAMES default;
> +#
> +# MDEV-10045: Server crashes in Time_and_counter_tracker::incr_loops
> +#
> +SET NAMES utf8;
> +CREATE TABLE t1 (f1 VARCHAR(3), f2 INT UNSIGNED) ENGINE=MyISAM;
> +CREATE TABLE t2 (f3 INT) ENGINE=MyISAM;
> +SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo' UNION SELECT 'bar' );
> +f1	f2	f3
> +DROP TABLE t1, t2;
> +SET NAMES default;
> +End of 10.1 tests
>  set @optimizer_switch_for_subselect_test=null;
>  set @join_cache_level_for_subselect_test=NULL;
> diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
> index 3599b52..c9c89a2 100644
> --- a/mysql-test/t/subselect.test
> +++ b/mysql-test/t/subselect.test
> @@ -6011,3 +6011,18 @@ INSERT INTO t1 VALUES ('foo');
>  SELECT f FROM t1 WHERE f > ALL ( SELECT 'bar' UNION SELECT 'baz' );
>  drop table t1;
>  SET NAMES default;
> +
> +--echo #
> +--echo # MDEV-10045: Server crashes in Time_and_counter_tracker::incr_loops
> +--echo #
> +SET NAMES utf8;
> +
> +CREATE TABLE t1 (f1 VARCHAR(3), f2 INT UNSIGNED) ENGINE=MyISAM;
> +CREATE TABLE t2 (f3 INT) ENGINE=MyISAM;
> +
> +SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo' UNION SELECT 'bar' );
> +
> +DROP TABLE t1, t2;
> +SET NAMES default;
> +
> +--echo End of 10.1 tests
> diff --git a/sql/sql_select.cc b/sql/sql_select.cc
> index 4825726..ded59eb 100644
> --- a/sql/sql_select.cc
> +++ b/sql/sql_select.cc
> @@ -1040,7 +1040,7 @@ int JOIN::optimize()
>      and deleted. The second call will not produce a valid query plan, it will
>      short-circuit because optimized==TRUE.
>  
> -    "was_optimized != optimized" is here to handle this case:
> +    "!was_optimized" is here to handle this case:
>        - first optimization starts, gets an error (from a const. cheap
>          subquery), returns 1
>        - another JOIN::optimize() call made, and now join->optimize() will
> @@ -1049,7 +1049,7 @@ int JOIN::optimize()
>      Can have QEP_NOT_PRESENT_YET for degenerate queries (for example,
>      SELECT * FROM tbl LIMIT 0)
>    */
> -  if (was_optimized != optimized && !res && have_query_plan != QEP_DELETED)
> +  if (!was_optimized && !res && have_query_plan != QEP_DELETED)
>    {
>      create_explain_query_if_not_exists(thd->lex, thd->mem_root);
>      have_query_plan= QEP_AVAILABLE;
> @@ -1058,6 +1058,7 @@ int JOIN::optimize()
>                        !skip_sort_order && !no_order && (order || group_list),
>                        select_distinct);
>    }
> +  optimized= 1;
>    return res;
>  }
>  
> @@ -1086,7 +1087,6 @@ JOIN::optimize_inner()
>    // to prevent double initialization on EXPLAIN
>    if (optimized)
>      DBUG_RETURN(0);
> -  optimized= 1;
>    DEBUG_SYNC(thd, "before_join_optimize");
>  
>    THD_STAGE_INFO(thd, stage_optimizing);
> _______________________________________________
> commits mailing list
> commits@xxxxxxxxxxx
> https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits

-- 
BR
 Sergei
-- 
Sergei Petrunia, Software Developer
MariaDB Corporation | Skype: sergefp | Blog: http://s.petrunia.net/blog