Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-8779

mysqld got signal 11 in sql/opt_range_mrr.cc:100(step_down_to)

Details

    • Bug
    • Status: Closed (View Workflow)
    • Critical
    • Resolution: Fixed
    • 10.0(EOL), 10.1(EOL)
    • 10.0.22, 10.1.8
    • Optimizer
    • DISTRIB_ID=Ubuntu
      DISTRIB_RELEASE=14.04
      DISTRIB_CODENAME=trusty
      DISTRIB_DESCRIPTION="Ubuntu 14.04.2 LTS"
    • 10.1.8-2

    Description

      Config

      histogram_size=255
      optimizer_use_condition_selectivity=5
      use_stat_tables='preferably'
      optimizer_selectivity_sampling_limit=97
      query_cache_type=1
      optimizer_switch='index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=off,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on'
      mrr_buffer_size=32M
      join_buffer_space_limit=32M
      join_cache_level=5
      tmp_table_size=448M
      max_heap_table_size=448M
      sort_buffer_size=32M
      join_buffer_size=32M

      Using either tokudb or inndob, I have at query that can reliably trigger:

      stack_bottom = 0x7f91b7f27e10 thread_stack 0x48000
      mysys/stacktrace.c:247(my_print_stacktrace)[0x7f91b7997efb]
      sql/signal_handler.cc:153(handle_fatal_signal)[0x7f91b752ff05]
      /lib/x86_64-linux-gnu/libpthread.so.0(+0x10340)[0x7f91b60c1340]
      sql/opt_range_mrr.cc:100(step_down_to)[0x7f91b731fb49]
      sql/opt_range_mrr.cc:196(sel_arg_range_seq_next(void*, st_key_multi_range*))[0x7f91b732303b]
      sql/opt_range.cc:3426(records_in_column_ranges)[0x7f91b732405d]

      I have rebuilt the table several times, including rounds of optimize & analyze table, anayzle table persistent for all, etc.

      CREATE TABLE `f` (
        `i` int(10) unsigned NOT NULL AUTO_INCREMENT,
        `u` varchar(2048) NOT NULL,
        `n` varchar(2048) NOT NULL,
        `e` tinyint(1) unsigned NOT NULL DEFAULT '1',
        `d` tinyint(1) unsigned NOT NULL,
        `c` datetime DEFAULT NULL,
        `p` int(10) unsigned NOT NULL,
        `g` tinyint(1) unsigned NOT NULL DEFAULT '0',
        `ur` varchar(2048) NOT NULL,
        `r` bigint(20) unsigned DEFAULT NULL,
        `cl` tinyint(1) unsigned NOT NULL DEFAULT '0',
        PRIMARY KEY (`i`),
        UNIQUE KEY (`i`,`d`,`p`),
        KEY (`p`),
        KEY (`d`,`p`),
        KEY (`e`,`d`,`p`),
        KEY (`r`)
      ) ENGINE=tokudb DEFAULT CHARSET=utf8 /* `compression`=tokudb_quicklz */;
       
      MariaDB [test]> SELECT   f.i,   f.u,   f.n,   f.e,   f.d,   f.c,   f.p,   f.g,   f.ur,   f.r,   f.cl FROM   f WHERE   (f.d = 0 AND     f.p = '1' AND     f.i != '-1' AND     f.n = 'some text' );
      ERROR 2013 (HY000): Lost connection to MySQL server during query

      Attachments

        Issue Links

          Activity

            fimbulvetr
            Thanks for the report and the test case, and also for providing your mysqld options right away, it helped to save time.

            The crash is reproducible on 10.0 and 10.1 with InnoDB or TokuDB; not reproducible with MyISAM.

            MTR test case

            --source include/have_innodb.inc
             
            set optimizer_use_condition_selectivity=5;
            CREATE TABLE `f` (
            `i` int(10) unsigned NOT NULL AUTO_INCREMENT,
            `n` varchar(2048) NOT NULL,
            `d` tinyint(1) unsigned NOT NULL,
            `p` int(10) unsigned NOT NULL,
            PRIMARY KEY (`i`)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
            SELECT * FROM f WHERE f.d = 0 AND f.p = '1' AND f.i != '-1' AND f.n = 'some text';

            I am getting a broken (or incomplete) stack trace both on 10.0 and 10.1, on two different machines, although it looks somewhat different. As I understand, it was broken for fimbulvetr as well.

            Examples:

            Wheezy, 10.0 commit 0ce0b88080fd39f6841206b64d8723af9779e849

            Thread 1 (Thread 0x7fe9a6c3e700 (LWP 28276)):
            #0  __pthread_kill (threadid=<optimized out>, signo=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/pthread_kill.c:63
            #1  0x0000000000e594ab in my_write_core (sig=11) at 10.0/mysys/stacktrace.c:457
            #2  0x000000000086d33d in handle_fatal_signal (sig=11) at 10.0/sql/signal_handler.cc:262
            #3  <signal handler called>
            #4  0x0000000000981e1b in calculate_cond_selectivity_for_table (thd=0x7fe99941a070, table=0x7fe991c9e470, cond=0x7fe991f44f50) at 10.0/sql/opt_range.cc:3658
            #5  0x0000000000000000 in ?? ()

            Wheezy, 10.1 commit 4cb6edba780085cbb82ef5fce2298f7df5fa0169

            Thread 1 (Thread 0x7ff247469700 (LWP 28362)):
            #0  __pthread_kill (threadid=<optimized out>, signo=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/pthread_kill.c:63
            #1  0x00007ff24825d026 in my_write_core (sig=11) at 10.1/mysys/stacktrace.c:456
            #2  0x00007ff247c02bbe in handle_fatal_signal (sig=11) at 10.1/sql/signal_handler.cc:273
            #3  <signal handler called>
            #4  0x00007ff247d1ea9a in step_down_to (arg=0x7ff2474640a0, key_tree=0x7ff22f10e8f0) at 10.1/sql/opt_range_mrr.cc:100
            #5  0x00007ff247d1ef29 in sel_arg_range_seq_next (rseq=0x7ff2474640a0, range=0x7ff247464050) at 10.1/sql/opt_range_mrr.cc:236
            #6  0x00007ff247d244f1 in records_in_column_ranges (param=0x7ff247464750, idx=2, tree=0x7ff22f10e8f0) at 10.1/sql/opt_range.cc:2818
            #7  0x00007ff247d24e17 in calculate_cond_selectivity_for_table (thd=0x7ff23b9dd070, table=0x7ff22f0ad870, cond=0x7ff22f197b68) at 10.1/sql/opt_range.cc:3061
            #8  0x0000000000000000 in ?? ()

            Trusty 10.0 commit 0ce0b88080fd39f6841206b64d8723af9779e849

            Thread 1 (Thread 0x7fe1b332f700 (LWP 14135)):
            #0  0x00007fe1b24dcf8c in pthread_kill () from /lib/x86_64-linux-gnu/libpthread.so.0
            #1  0x0000000000e6c6ec in my_write_core (sig=11) at 10.0/mysys/stacktrace.c:457
            #2  0x000000000085bd6b in handle_fatal_signal (sig=11) at 10.0/sql/signal_handler.cc:262
            #3  <signal handler called>
            #4  0x0000000000970092 in step_down_to (arg=0x7fe1b332a530, key_tree=0x7fe19e7fe8f0) at 10.0/sql/opt_range_mrr.cc:100
            #5  0x0000000000970506 in sel_arg_range_seq_next (rseq=0x7fe1b332a530, range=0x7fe1b332a4e0) at 10.0/sql/opt_range_mrr.cc:236
            #6  0x0000000000975958 in records_in_column_ranges (param=0x7fe1b332abd0, idx=2, tree=0x7fe19e7fe8f0) at 10.0/sql/opt_range.cc:3415
            #7  0x000000000097624a in calculate_cond_selectivity_for_table (thd=0x7fe1ab1ac070, table=0x7fe19e49e470, cond=0x7fe19e5a8f50) at 10.0/sql/opt_range.cc:3656
            #8  0x0000000000000000 in ?? ()

            Apart from fixing the crash, it is also very important to investigate what's going on with the stack trace. As discussed, assigning to svoj for a preliminary analysis.

            elenst Elena Stepanova added a comment - fimbulvetr Thanks for the report and the test case, and also for providing your mysqld options right away, it helped to save time. The crash is reproducible on 10.0 and 10.1 with InnoDB or TokuDB; not reproducible with MyISAM. MTR test case --source include/have_innodb.inc   set optimizer_use_condition_selectivity=5; CREATE TABLE `f` ( `i` int (10) unsigned NOT NULL AUTO_INCREMENT, `n` varchar (2048) NOT NULL , `d` tinyint(1) unsigned NOT NULL , `p` int (10) unsigned NOT NULL , PRIMARY KEY (`i`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; SELECT * FROM f WHERE f.d = 0 AND f.p = '1' AND f.i != '-1' AND f.n = 'some text' ; I am getting a broken (or incomplete) stack trace both on 10.0 and 10.1, on two different machines, although it looks somewhat different. As I understand, it was broken for fimbulvetr as well. Examples: Wheezy, 10.0 commit 0ce0b88080fd39f6841206b64d8723af9779e849 Thread 1 (Thread 0x7fe9a6c3e700 (LWP 28276)): #0 __pthread_kill (threadid=<optimized out>, signo=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/pthread_kill.c:63 #1 0x0000000000e594ab in my_write_core (sig=11) at 10.0/mysys/stacktrace.c:457 #2 0x000000000086d33d in handle_fatal_signal (sig=11) at 10.0/sql/signal_handler.cc:262 #3 <signal handler called> #4 0x0000000000981e1b in calculate_cond_selectivity_for_table (thd=0x7fe99941a070, table=0x7fe991c9e470, cond=0x7fe991f44f50) at 10.0/sql/opt_range.cc:3658 #5 0x0000000000000000 in ?? () Wheezy, 10.1 commit 4cb6edba780085cbb82ef5fce2298f7df5fa0169 Thread 1 (Thread 0x7ff247469700 (LWP 28362)): #0 __pthread_kill (threadid=<optimized out>, signo=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/pthread_kill.c:63 #1 0x00007ff24825d026 in my_write_core (sig=11) at 10.1/mysys/stacktrace.c:456 #2 0x00007ff247c02bbe in handle_fatal_signal (sig=11) at 10.1/sql/signal_handler.cc:273 #3 <signal handler called> #4 0x00007ff247d1ea9a in step_down_to (arg=0x7ff2474640a0, key_tree=0x7ff22f10e8f0) at 10.1/sql/opt_range_mrr.cc:100 #5 0x00007ff247d1ef29 in sel_arg_range_seq_next (rseq=0x7ff2474640a0, range=0x7ff247464050) at 10.1/sql/opt_range_mrr.cc:236 #6 0x00007ff247d244f1 in records_in_column_ranges (param=0x7ff247464750, idx=2, tree=0x7ff22f10e8f0) at 10.1/sql/opt_range.cc:2818 #7 0x00007ff247d24e17 in calculate_cond_selectivity_for_table (thd=0x7ff23b9dd070, table=0x7ff22f0ad870, cond=0x7ff22f197b68) at 10.1/sql/opt_range.cc:3061 #8 0x0000000000000000 in ?? () Trusty 10.0 commit 0ce0b88080fd39f6841206b64d8723af9779e849 Thread 1 (Thread 0x7fe1b332f700 (LWP 14135)): #0 0x00007fe1b24dcf8c in pthread_kill () from /lib/x86_64-linux-gnu/libpthread.so.0 #1 0x0000000000e6c6ec in my_write_core (sig=11) at 10.0/mysys/stacktrace.c:457 #2 0x000000000085bd6b in handle_fatal_signal (sig=11) at 10.0/sql/signal_handler.cc:262 #3 <signal handler called> #4 0x0000000000970092 in step_down_to (arg=0x7fe1b332a530, key_tree=0x7fe19e7fe8f0) at 10.0/sql/opt_range_mrr.cc:100 #5 0x0000000000970506 in sel_arg_range_seq_next (rseq=0x7fe1b332a530, range=0x7fe1b332a4e0) at 10.0/sql/opt_range_mrr.cc:236 #6 0x0000000000975958 in records_in_column_ranges (param=0x7fe1b332abd0, idx=2, tree=0x7fe19e7fe8f0) at 10.0/sql/opt_range.cc:3415 #7 0x000000000097624a in calculate_cond_selectivity_for_table (thd=0x7fe1ab1ac070, table=0x7fe19e49e470, cond=0x7fe19e5a8f50) at 10.0/sql/opt_range.cc:3656 #8 0x0000000000000000 in ?? () Apart from fixing the crash, it is also very important to investigate what's going on with the stack trace. As discussed, assigning to svoj for a preliminary analysis.
            svoj Sergey Vojtovich added a comment - - edited

            In create_key_parts_for_pseudo_indexes() we remember field->key_length() for every used field. For "`n` varchar(2048) NOT NULL" we get 6144 (2048 * mbmaxlen of UTF-8, which is 3).

            Later we do step_down_to()/SEL_ARG::store_max(), which does memcpy(*max_key,max_value,length). IIUC max_key was allocated as: RANGE_OPT_PARAM::max_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH], in other words 3072 + 255 * 3 + 1= 3838.

            So we actually do memcpy(max_key[3838], max_value, 6144). This statement effectively breaks stack trace, crash happens later as an outcome of this overwrite.

            svoj Sergey Vojtovich added a comment - - edited In create_key_parts_for_pseudo_indexes() we remember field->key_length() for every used field. For "`n` varchar(2048) NOT NULL" we get 6144 (2048 * mbmaxlen of UTF-8, which is 3). Later we do step_down_to()/SEL_ARG::store_max(), which does memcpy(*max_key,max_value,length). IIUC max_key was allocated as: RANGE_OPT_PARAM::max_key [MAX_KEY_LENGTH+MAX_FIELD_WIDTH] , in other words 3072 + 255 * 3 + 1= 3838. So we actually do memcpy(max_key [3838] , max_value, 6144). This statement effectively breaks stack trace, crash happens later as an outcome of this overwrite.

            I was wondering if partition pruning is affected by this problem. It turns out, no. partition_info::check_partition_field_length() disallows creation of partitioning schemes which have partitioning columns occupy more than MAX_KEY_LENGTH when encoded with KeyTupleFormat.

            psergei Sergei Petrunia added a comment - I was wondering if partition pruning is affected by this problem. It turns out, no. partition_info::check_partition_field_length() disallows creation of partitioning schemes which have partitioning columns occupy more than MAX_KEY_LENGTH when encoded with KeyTupleFormat.

            Looking through opt_range.cc code, RANGE_OPT_PARAM::min_key and max-key seem to be the only places where the code implies that key images do not exceed MAX_KEY_LENGTH in size.

            The steps are:

            • get_mm_leaf() stores field value in table->record[0] (check value->save_in_field_no_warnings() calls)
            • Then, SEL_ARG object is created. It has key part values, for which buffer of appropriate size (key_part->store_length) is allocated on MEM_ROOT.
            • Then, we call sel_arg_range_seq_init/sel_arg_range_seq_next and this is where it attempts to store the key value in RANGE_OPT_PARAM::min_key/max_key.

            Buffer overrun seems to only be possible in #3.

            psergei Sergei Petrunia added a comment - Looking through opt_range.cc code, RANGE_OPT_PARAM::min_key and max-key seem to be the only places where the code implies that key images do not exceed MAX_KEY_LENGTH in size. The steps are: get_mm_leaf() stores field value in table->record [0] (check value->save_in_field_no_warnings() calls) Then, SEL_ARG object is created. It has key part values, for which buffer of appropriate size (key_part->store_length) is allocated on MEM_ROOT. Then, we call sel_arg_range_seq_init/sel_arg_range_seq_next and this is where it attempts to store the key value in RANGE_OPT_PARAM::min_key/max_key. Buffer overrun seems to only be possible in #3.
            psergei Sergei Petrunia added a comment - http://lists.askmonty.org/pipermail/commits/2015-September/008419.html

            Following svoj 's advice, debugged a few queries. new alloc_root calls do not cause calls to malloc()

            psergei Sergei Petrunia added a comment - Following svoj 's advice, debugged a few queries. new alloc_root calls do not cause calls to malloc()

            The patch had a typo which caused MDEV-8826. This is now fixed and pushed in both 10.0 and 10.1

            psergei Sergei Petrunia added a comment - The patch had a typo which caused MDEV-8826 . This is now fixed and pushed in both 10.0 and 10.1

            People

              psergei Sergei Petrunia
              fimbulvetr Dan Vande More
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.