[MDEV-13788] Server crash when issuing bad SQL partition syntax Created: 2017-09-12  Updated: 2020-08-25  Resolved: 2017-11-20

Status: Closed
Project: MariaDB Server
Component/s: Parser, Partitioning
Affects Version/s: 5.5, 10.0, 10.1, 10.1.26, 10.2
Fix Version/s: 5.5.59, 10.0.34, 10.1.30, 10.2.12, 10.3.4

Type: Bug Priority: Major
Reporter: Geoff Montee (Inactive) Assignee: Alexander Barkov
Resolution: Fixed Votes: 1
Labels: crash, partitioning

Issue Links:
Relates
relates to MDEV-22112 Assertion `tab_part_info->part_type =... Closed
Sprint: 10.2.11

 Description   

Invalid syntax in a partition-related ALTER TABLE statement can cause the server to crash. To reproduce, you can execute:

drop table if exists t;
CREATE TABLE `t` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`d` date NOT NULL,
PRIMARY KEY (`id`,`d`)
) ENGINE=InnoDB
/*!50500 PARTITION BY RANGE COLUMNS(d)
(PARTITION p20171016 VALUES LESS THAN ('2017-10-17') ENGINE = InnoDB,
PARTITION p20171017 VALUES LESS THAN ('2017-10-18') ENGINE = InnoDB,
PARTITION p99991231 VALUES LESS THAN (MAXVALUE) ENGINE = InnoDB) */;
 
alter table t reorganize partition p99991231 into (
partition p20171018 values less than ('2017-10-19'),
partition p20171126,
PARTITION p99991231 VALUES LESS THAN (MAXVALUE));

Notice that partition p20171126 is not valid in the above statement. The server should reject the statement. Instead, it leads to the following crash:

170912 19:41:23 [ERROR] mysqld got signal 11 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
 
To report this bug, see https://mariadb.com/kb/en/reporting-bugs
 
We will try our best to scrape up some info that will hopefully help
diagnose the problem, but since we have already crashed,
something is definitely wrong and this may fail.
 
Server version: 10.1.26-MariaDB
key_buffer_size=134217728
read_buffer_size=131072
max_used_connections=1
max_threads=153
thread_count=3
It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 467133 K  bytes of memory
Hope that's ok; if not, decrease some variables in the equation.
 
Thread pointer: 0x7fb668a5a008
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 0x7fb6910950b0 thread_stack 0x48400
/usr/sbin/mysqld(my_print_stacktrace+0x2e)[0x7fb69657952e]
/usr/sbin/mysqld(handle_fatal_signal+0x305)[0x7fb69609ced5]
/lib64/libpthread.so.0(+0xf5e0)[0x7fb6956ad5e0]
/usr/sbin/mysqld(_ZN14partition_info21check_range_constantsEP3THD+0xd3)[0x7fb695fd97a3]
/usr/sbin/mysqld(_ZN14partition_info20check_partition_infoEP3THDPP10handlertonP7handlerP14HA_CREATE_INFOb+0x6d1)[0x7fb695fda691]
/usr/sbin/mysqld(_Z21prep_alter_part_tableP3THDP5TABLEP10Alter_infoP14HA_CREATE_INFOP15Alter_table_ctxPbS9_+0xa65)[0x7fb6961d8805]
/usr/sbin/mysqld(_Z17mysql_alter_tableP3THDPcS1_P14HA_CREATE_INFOP10TABLE_LISTP10Alter_infojP8st_orderb+0x891)[0x7fb695fa3e71]
/usr/sbin/mysqld(_ZN19Sql_cmd_alter_table7executeEP3THD+0x60a)[0x7fb695fed6aa]
/usr/sbin/mysqld(_Z21mysql_execute_commandP3THD+0x1327)[0x7fb695f12a17]
/usr/sbin/mysqld(_Z11mysql_parseP3THDPcjP12Parser_state+0x342)[0x7fb695f1ad52]
/usr/sbin/mysqld(+0x43d671)[0x7fb695f1b671]
/usr/sbin/mysqld(_Z16dispatch_command19enum_server_commandP3THDPcj+0x2111)[0x7fb695f1dfc1]
/usr/sbin/mysqld(_Z10do_commandP3THD+0x136)[0x7fb695f1f016]
/usr/sbin/mysqld(_Z24do_handle_one_connectionP3THD+0x18a)[0x7fb695fea9da]
/usr/sbin/mysqld(handle_one_connection+0x40)[0x7fb695feab80]
/lib64/libpthread.so.0(+0x7e25)[0x7fb6956a5e25]
/lib64/libc.so.6(clone+0x6d)[0x7fb693ac934d]
 
Trying to get some variables.
Some pointers may be invalid and cause the dump to abort.
Query (0x7fb668b14020): alter table t reorganize partition p99991231 into ( partition p20171018 values less than ('2017-10-19'), partition p20171126, PARTITION p99991231 VALUES LESS THAN (MAXVALUE))
Connection ID (thread ID): 5
Status: NOT_KILLED



 Comments   
Comment by Alice Sherepa [ 2017-09-13 ]

Thanks for the repport. Reproducible with 5.5-10.3, both myisam and innodb

partition_info.cc:2477: bool partition_info::fix_parser_data(THD*): Assertion `part_type == RANGE_PARTITION ? num_elements == 1U : (1)' failed.

CREATE TABLE `t` (
`id` int,
`d` date
) ENGINE=myisam
PARTITION BY RANGE COLUMNS(d)
(PARTITION p1 VALUES LESS THAN (MAXVALUE));
 
ALTER TABLE  t reorganize PARTITION p1 INTO (
PARTITION p2,
PARTITION p3 VALUES LESS THAN (MAXVALUE));

error log

Version: '10.2.9-MariaDB-debug'  socket: '/tmp/mysql.sock'  port: 3322  Source distribution
mysqld: /home/alice/git/10.2/sql/partition_info.cc:2477: bool partition_info::fix_parser_data(THD*): Assertion `part_type == RANGE_PARTITION ? num_elements == 1U : (1)' failed.
170913 12:24:06 [ERROR] mysqld got signal 6 ;
 
Server version: 10.2.9-MariaDB-debug
Thread pointer: 0x7f6b54000a98
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 0x7f6bb1891ec0 thread_stack 0x49000
/data/bld/10.2/bin/mysqld(my_print_stacktrace+0x38)[0xc34b8cd4b]
/data/bld/10.2/bin/mysqld(handle_fatal_signal+0x3a3)[0xc3441901a]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x11390)[0x7f6bc7bb4390]
/lib/x86_64-linux-gnu/libc.so.6(gsignal+0x38)[0x7f6bc6f6d428]
/lib/x86_64-linux-gnu/libc.so.6(abort+0x16a)[0x7f6bc6f6f02a]
/lib/x86_64-linux-gnu/libc.so.6(+0x2dbd7)[0x7f6bc6f65bd7]
/lib/x86_64-linux-gnu/libc.so.6(+0x2dc82)[0x7f6bc6f65c82]
mysys/stacktrace.c:267(my_print_stacktrace)[0xc342d6967]
sql/sql_partition.cc:4639(prep_alter_part_table(THD*, TABLE*, Alter_info*, HA_CREATE_INFO*, Alter_table_ctx*, bool*, bool*))[0xc345cd279]
sql/sql_table.cc:8975(mysql_alter_table(THD*, char*, char*, HA_CREATE_INFO*, TABLE_LIST*, Alter_info*, unsigned int, st_order*, bool))[0xc3427e051]
sql/sql_alter.cc:324(Sql_cmd_alter_table::execute(THD*))[0xc342f7839]
sql/sql_parse.cc:6203(mysql_execute_command(THD*))[0xc341b474c]
sql/sql_parse.cc:7875(mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool))[0xc341b92dd]
sql/sql_parse.cc:1814(dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool))[0xc341a6c7b]
sql/sql_parse.cc:1360(do_command(THD*))[0xc341a55ee]
sql/sql_connect.cc:1354(do_handle_one_connection(CONNECT*))[0xc342f2542]
sql/sql_connect.cc:1261(handle_one_connection)[0xc342f22c2]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x76ba)[0x7f6bc7baa6ba]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7f6bc703f3dd]
 
Trying to get some variables.
Some pointers may be invalid and cause the dump to abort.
Query (0x7f6b54046a60): alter table t reorganize partition p1 into ( partition p2, PARTITION p3 VALUES LESS THAN (MAXVALUE))
Connection ID (thread ID): 8
Status: NOT_KILLED

stack trace 10.2.9-MariaDB-debug (commit a237a920991f417e9a4567957f4fc7aa5b538270)

Thread 1 (Thread 0x7f6bb1892700 (LWP 26335)):
#0  0x00007f6bc6f6d428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
#1  0x00007f6bc6f6f02a in __GI_abort () at abort.c:89
#2  0x00007f6bc6f65bd7 in __assert_fail_base (fmt=<optimized out>, assertion=assertion@entry=0xc34c44508 "part_type == RANGE_PARTITION ? num_elements == 1U : (1)", file=file@entry=0xc34c43ae0 "/home/alice/git/10.2/sql/partition_info.cc", line=line@entry=2477, function=function@entry=0xc34c448c0 <partition_info::fix_parser_data(THD*)::__PRETTY_FUNCTION__> "bool partition_info::fix_parser_data(THD*)") at assert.c:92
#3  0x00007f6bc6f65c82 in __GI___assert_fail (assertion=0xc34c44508 "part_type == RANGE_PARTITION ? num_elements == 1U : (1)", file=0xc34c43ae0 "/home/alice/git/10.2/sql/partition_info.cc", line=2477, function=0xc34c448c0 <partition_info::fix_parser_data(THD*)::__PRETTY_FUNCTION__> "bool partition_info::fix_parser_data(THD*)") at assert.c:101
#4  0x0000000c342d6967 in partition_info::fix_parser_data (this=0x7f6b540726b0, thd=0x7f6b54000a98) at /home/alice/git/10.2/sql/partition_info.cc:2476
#5  0x0000000c345cd279 in prep_alter_part_table (thd=0x7f6b54000a98, table=0x7f6b5406cd28, alter_info=0x7f6bb188fd80, create_info=0x7f6bb188fe60, alter_ctx=0x7f6bb188f220, partition_changed=0x7f6bb188e520, fast_alter_table=0x7f6bb188e521) at /home/alice/git/10.2/sql/sql_partition.cc:4639
#6  0x0000000c3427e051 in mysql_alter_table (thd=0x7f6b54000a98, new_db=0x7f6b5402d700 "test", new_name=0x0, create_info=0x7f6bb188fe60, table_list=0x7f6b5403e880, alter_info=0x7f6bb188fd80, order_num=0, order=0x0, ignore=false) at /home/alice/git/10.2/sql/sql_table.cc:8975
#7  0x0000000c342f7839 in Sql_cmd_alter_table::execute (this=0x7f6b54065f80, thd=0x7f6b54000a98) at /home/alice/git/10.2/sql/sql_alter.cc:324
#8  0x0000000c341b474c in mysql_execute_command (thd=0x7f6b54000a98) at /home/alice/git/10.2/sql/sql_parse.cc:6203
#9  0x0000000c341b92dd in mysql_parse (thd=0x7f6b54000a98, rawbuf=0x7f6b54046a60 "alter table t reorganize partition p1 into (\npartition p2,\nPARTITION p3 VALUES LESS THAN (MAXVALUE))", length=100, parser_state=0x7f6bb1891240, is_com_multi=false, is_next_command=false) at /home/alice/git/10.2/sql/sql_parse.cc:7875
#10 0x0000000c341a6c7b in dispatch_command (command=COM_QUERY, thd=0x7f6b54000a98, packet=0x7f6b54007e99 "alter table t reorganize partition p1 into (\npartition p2,\nPARTITION p3 VALUES LESS THAN (MAXVALUE))", packet_length=100, is_com_multi=false, is_next_command=false) at /home/alice/git/10.2/sql/sql_parse.cc:1812
#11 0x0000000c341a55ee in do_command (thd=0x7f6b54000a98) at /home/alice/git/10.2/sql/sql_parse.cc:1360
#12 0x0000000c342f2542 in do_handle_one_connection (connect=0xc3832c3a8) at /home/alice/git/10.2/sql/sql_connect.cc:1354
#13 0x0000000c342f22c2 in handle_one_connection (arg=0xc3832c3a8) at /home/alice/git/10.2/sql/sql_connect.cc:1260
#14 0x00007f6bc7baa6ba in start_thread (arg=0x7f6bb1892700) at pthread_create.c:333
#15 0x00007f6bc703f3dd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Comment by Alexander Barkov [ 2017-11-15 ]

A similar crash happens with LIST partitioning:

DROP TABLE IF EXISTS t1;
 
CREATE TABLE t1 (
  id int,
  d date
) ENGINE=MyISAM
PARTITION BY LIST (id) (PARTITION p1 VALUES IN (1,2,3));
 
ALTER TABLE  t1 REORGANIZE PARTITION p1 INTO (
PARTITION p2,
PARTITION p3 VALUES IN (4,5,6));

Comment by Alexander Barkov [ 2017-11-15 ]

The same problem is repeatable if I change ENGINE=MyISAM to ENGINE=InnoDB in the above scripts.

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