[MDEV-30786] SIGFPE in cost_group_min_max on EXPLAIN Created: 2023-03-04  Updated: 2023-05-17  Resolved: 2023-05-17

Status: Closed
Project: MariaDB Server
Component/s: Optimizer
Affects Version/s: 11.0
Fix Version/s: 11.0.2

Type: Bug Priority: Critical
Reporter: Roel Van de Paar Assignee: Michael Widenius
Resolution: Fixed Votes: 0
Labels: regression-11.0


 Description   

SET use_stat_tables='preferably';
CREATE TABLE t (a INT,b INT,KEY i1 (a),KEY i2 (b)) ENGINE=MRG_MyISAM;
ANALYZE LOCAL TABLE t;
EXPLAIN SELECT DISTINCT a FROM t;

Leads to:

11.0.1 f2dc4d4c10ac36a73b5c1eb765352d3aee808d66 (Debug)

Core was generated by `/test/MD180223-mariadb-11.0.1-linux-x86_64-dbg/bin/mariadbd --no-defaults --cor'.
Program terminated with signal SIGFPE, Arithmetic exception.
#0  0x0000559999752099 in cost_group_min_max (out_records=<synthetic pointer>, 
    read_cost=<synthetic pointer>, have_max=false, have_min=false, 
    quick_prefix_records=0, index_tree=0x0, range_tree=0x0, group_key_parts=1, 
    used_key_parts=1, index_info=0x14d104024a50, table=0x14d10401ea88)
    at /test/11.0_dbg/sql/opt_range.cc:15275
15275	               INDEX_BLOCK_FILL_FACTOR_MUL) / file->stats.block_size + 1;
[Current thread is 1 (Thread 0x14d158966640 (LWP 2308294))]
(gdb) bt
#0  0x0000559999752099 in cost_group_min_max (out_records=<synthetic pointer>, read_cost=<synthetic pointer>, have_max=false, have_min=false, quick_prefix_records=0, index_tree=0x0, range_tree=0x0, group_key_parts=1, used_key_parts=1, index_info=0x14d104024a50, table=0x14d10401ea88) at /test/11.0_dbg/sql/opt_range.cc:15275
#1  get_best_group_min_max (param=param@entry=0x14d158963c40, tree=tree@entry=0x0, read_time=<optimized out>) at /test/11.0_dbg/sql/opt_range.cc:14540
#2  0x000055999975484f in SQL_SELECT::test_quick_select (this=this@entry=0x14d1040164e0, thd=thd@entry=0x14d104000d58, keys_to_use=<optimized out>, prev_tables=prev_tables@entry=0, limit=limit@entry=18446744073709551615, force_quick_range=force_quick_range@entry=false, ordered_output=<optimized out>, remove_false_parts_of_where=<optimized out>, only_single_index_range_scan=<optimized out>) at /test/11.0_dbg/sql/opt_range.cc:3072
#3  0x00005599998c9b4f in get_quick_record_count (limit=18446744073709551615, keys=0x14d104015950, table=0x14d10401ea88, select=0x14d1040164e0, thd=0x14d104000d58) at /test/11.0_dbg/sql/sql_select.cc:5190
#4  make_join_statistics (join=join@entry=0x14d104014f50, tables_list=@0x14d1040133f8: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x14d104015718, last = 0x14d104015718, elements = 1}, <No data fields>}, keyuse_array=keyuse_array@entry=0x14d1040152b8) at /test/11.0_dbg/sql/sql_select.cc:5947
#5  0x00005599998d14b9 in JOIN::optimize_inner (this=this@entry=0x14d104014f50) at /test/11.0_dbg/sql/sql_select.cc:2569
#6  0x00005599998d19bc in JOIN::optimize (this=this@entry=0x14d104014f50) at /test/11.0_dbg/sql/sql_select.cc:1897
#7  0x00005599998d1ac5 in mysql_select (thd=thd@entry=0x14d104000d58, tables=0x14d104013800, fields=@0x14d104013498: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x14d1040137b8, last = 0x14d1040137b8, elements = 1}, <No data fields>}, conds=0x0, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=2164525829, result=0x14d1040148b0, unit=0x14d104004fa0, select_lex=0x14d1040131e0) at /test/11.0_dbg/sql/sql_select.cc:5132
#8  0x00005599998d2526 in mysql_explain_union (thd=thd@entry=0x14d104000d58, unit=unit@entry=0x14d104004fa0, result=result@entry=0x14d1040148b0) at /test/11.0_dbg/sql/sql_select.cc:29596
#9  0x0000559999837bd7 in execute_sqlcom_select (thd=thd@entry=0x14d104000d58, all_tables=0x14d104013800) at /test/11.0_dbg/sql/sql_parse.cc:6205
#10 0x00005599998434af in mysql_execute_command (thd=thd@entry=0x14d104000d58, is_called_from_prepared_stmt=is_called_from_prepared_stmt@entry=false) at /test/11.0_dbg/sql/sql_parse.cc:3949
#11 0x000055999984a7cf in mysql_parse (thd=thd@entry=0x14d104000d58, rawbuf=<optimized out>, length=<optimized out>, parser_state=parser_state@entry=0x14d1589652c0) at /test/11.0_dbg/sql/sql_parse.cc:8002
#12 0x000055999984c963 in dispatch_command (command=command@entry=COM_QUERY, thd=thd@entry=0x14d104000d58, packet=packet@entry=0x14d10400ae19 "", packet_length=packet_length@entry=32, blocking=blocking@entry=true) at /test/11.0_dbg/sql/sql_class.h:242
#13 0x000055999984e7bc in do_command (thd=0x14d104000d58, blocking=blocking@entry=true) at /test/11.0_dbg/sql/sql_parse.cc:1407
#14 0x000055999999f6e2 in do_handle_one_connection (connect=<optimized out>, connect@entry=0x55999cb199f8, put_in_cache=put_in_cache@entry=true) at /test/11.0_dbg/sql/sql_connect.cc:1416
#15 0x000055999999f941 in handle_one_connection (arg=0x55999cb199f8) at /test/11.0_dbg/sql/sql_connect.cc:1318
#16 0x000014d172461b43 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#17 0x000014d1724f3a00 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

15273	  /* Calculate the number of blocks we will touch for the table or range scan */
15274	  num_blocks= (records * key_length / INDEX_BLOCK_FILL_FACTOR_DIV *
15275	               INDEX_BLOCK_FILL_FACTOR_MUL) / file->stats.block_size + 1;
(gdb) p file->stats.block_size
$2 = 0

Bug confirmed present in:
MariaDB: 11.0.1 (dbg), 11.0.1 (opt)

Bug (or feature/syntax) confirmed not present in:
MariaDB: 10.3.38 (dbg), 10.3.38 (opt), 10.4.29 (dbg), 10.4.29 (opt), 10.5.20 (dbg), 10.5.20 (opt), 10.6.13 (dbg), 10.6.13 (opt), 10.7.8 (dbg), 10.7.8 (opt), 10.8.8 (dbg), 10.8.8 (opt), 10.9.6 (dbg), 10.9.6 (opt), 10.10.4 (dbg), 10.10.4 (opt), 10.11.2 (dbg), 10.11.2 (opt)
MySQL: 5.5.62 (dbg), 5.5.62 (opt), 5.6.51 (dbg), 5.6.51 (opt), 5.7.40 (dbg), 5.7.40 (opt), 8.0.31 (dbg), 8.0.31 (opt)



 Comments   
Comment by Roel Van de Paar [ 2023-03-04 ]

First failing commit

commit b66cdbd1eaeed7e96317a03a190c496fd062ec71
Author: Monty <monty@mariadb.org>
Date:   Thu Aug 11 13:05:23 2022 +0300

Comment by Roel Van de Paar [ 2023-04-07 ]

Additional, shorter, testcase

SET use_stat_tables=preferably;
CREATE TABLE t (a INT,INDEX (a)) ENGINE=MRG_MyISAM;
ANALYZE TABLE t;
EXPLAIN SELECT 1 FROM t GROUP BY a;

Comment by Michael Widenius [ 2023-05-03 ]

The problem was that for merge tables without any underlaying tables the
block size was 0, which the code could not handle.

Fixed by ensuring that MERGE tables never have a block size of 0.
Fixed also a wrong assumption of number of seeks needed to scan
merge tables.

Comment by Sergei Petrunia [ 2023-05-17 ]

commit 0099c2fc1aefaf2ed18b18567a9c641eb6a51518
Author: Monty <monty@mariadb.org>
Date:   Mon Mar 27 17:15:59 2023 +0300
 
    MDEV-30786 SIGFPE in cost_group_min_max on EXP
    
    The problem was that for merge tables without any underlaying tables the
    block size was 0, which the code could not handle.
    
    Fixed by ensuring that MERGE tables never have a block size of 0.
    Fixed also a wrong assumption of number of seeks needed to scan
    merge tables.

Generated at Thu Feb 08 10:18:53 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.