[MDEV-18609] Assertion `!is_string || (*af)->charset() == cf->charset' failed in innobase_rename_or_enlarge_columns_cache upon CHANGE COLUMN Created: 2019-02-18  Updated: 2019-02-18  Resolved: 2019-02-18

Status: Closed
Project: MariaDB Server
Component/s: Data Definition - Alter Table, Storage Engine - InnoDB
Affects Version/s: 10.4
Fix Version/s: 10.4.3

Type: Bug Priority: Major
Reporter: Elena Stepanova Assignee: Marko Mäkelä
Resolution: Fixed Votes: 0
Labels: None


 Description   

--source include/have_innodb.inc
 
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
ALTER TABLE t1 ADD COLUMN b BIT NOT NULL;
ALTER TABLE t1 CHANGE b c BIT NOT NULL;
 
# Cleanup
DROP TABLE t1;

10.4 790b6f5a

mysqld: /data/src/10.4/storage/innobase/handler/handler0alter.cc:9212: void innobase_rename_or_enlarge_columns_cache(Alter_inplace_info*, const TABLE*, const TABLE*, dict_table_t*): Assertion `!is_string || (*af)->charset() == cf->charset' failed.
190218  3:01:47 [ERROR] mysqld got signal 6 ;
 
#7  0x00007f03e2807ee2 in __assert_fail () from /lib/x86_64-linux-gnu/libc.so.6
#8  0x000056210acade2f in innobase_rename_or_enlarge_columns_cache (ha_alter_info=0x7f03dc37daa0, altered_table=0x7f0388059900, table=0x7f038817d720, user_table=0x7f038819b5c8) at /data/src/10.4/storage/innobase/handler/handler0alter.cc:9211
#9  0x000056210acbfbdc in commit_cache_norebuild (ha_alter_info=0x7f03dc37daa0, ctx=0x7f03880167e0, altered_table=0x7f0388059900, table=0x7f038817d720, trx=0x7f03dc618268) at /data/src/10.4/storage/innobase/handler/handler0alter.cc:10346
#10 0x000056210acb15aa in ha_innobase::commit_inplace_alter_table (this=0x7f038814bae8, altered_table=0x7f0388059900, ha_alter_info=0x7f03dc37daa0, commit=true) at /data/src/10.4/storage/innobase/handler/handler0alter.cc:11029
#11 0x000056210a92f5a6 in handler::ha_commit_inplace_alter_table (this=0x7f038814bae8, altered_table=0x7f0388059900, ha_alter_info=0x7f03dc37daa0, commit=true) at /data/src/10.4/sql/handler.cc:4673
#12 0x000056210a6caa41 in mysql_inplace_alter_table (thd=0x7f0388000b00, table_list=0x7f03880152f0, table=0x7f038817d720, altered_table=0x7f0388059900, ha_alter_info=0x7f03dc37daa0, inplace_supported=HA_ALTER_INPLACE_INSTANT, target_mdl_request=0x7f03dc37dcd0, alter_ctx=0x7f03dc37e280) at /data/src/10.4/sql/sql_table.cc:7605
#13 0x000056210a6d0897 in mysql_alter_table (thd=0x7f0388000b00, new_db=0x7f03880051f8, new_name=0x7f03880055e0, create_info=0x7f03dc37ee70, table_list=0x7f03880152f0, alter_info=0x7f03dc37edb0, order_num=0, order=0x0, ignore=false) at /data/src/10.4/sql/sql_table.cc:9705
#14 0x000056210a75c332 in Sql_cmd_alter_table::execute (this=0x7f0388015a48, thd=0x7f0388000b00) at /data/src/10.4/sql/sql_alter.cc:499
#15 0x000056210a5f1df8 in mysql_execute_command (thd=0x7f0388000b00) at /data/src/10.4/sql/sql_parse.cc:6318
#16 0x000056210a5f6fa0 in mysql_parse (thd=0x7f0388000b00, rawbuf=0x7f03880151f8 "ALTER TABLE t1 CHANGE b c BIT NOT NULL", length=38, parser_state=0x7f03dc3801f0, is_com_multi=false, is_next_command=false) at /data/src/10.4/sql/sql_parse.cc:8129
#17 0x000056210a5e26da in dispatch_command (command=COM_QUERY, thd=0x7f0388000b00, packet=0x7f038800a4c1 "ALTER TABLE t1 CHANGE b c BIT NOT NULL", packet_length=38, is_com_multi=false, is_next_command=false) at /data/src/10.4/sql/sql_parse.cc:1808
#18 0x000056210a5e0fe4 in do_command (thd=0x7f0388000b00) at /data/src/10.4/sql/sql_parse.cc:1358
#19 0x000056210a756247 in do_handle_one_connection (connect=0x56210d2dd6d0) at /data/src/10.4/sql/sql_connect.cc:1399
#20 0x000056210a755fb8 in handle_one_connection (arg=0x56210d2dd6d0) at /data/src/10.4/sql/sql_connect.cc:1302
#21 0x000056210ac49753 in pfs_spawn_thread (arg=0x56210d3d29c0) at /data/src/10.4/storage/perfschema/pfs.cc:1862
#22 0x00007f03e44de494 in start_thread (arg=0x7f03dc381700) at pthread_create.c:333
#23 0x00007f03e28c493f in clone () from /lib/x86_64-linux-gnu/libc.so.6

Not reproducible on 10.4 a081a998.
No visible immediate effect on a non-debug build.



 Comments   
Comment by Marko Mäkelä [ 2019-02-18 ]

This is a tricky bug. The character set should not matter for BIT, but for InnoDB it can matter because of mbminlen and mbmaxlen. For this test case, the character set is changing from my_charset_bin to  my_charset_latin1. It gets worse when the mbminlen or mbmaxlen can change:

--source include/have_innodb.inc
CREATE TABLE t1 (a INT) ENGINE=InnoDB DEFAULT CHARSET utf16;
ALTER TABLE t1 ADD COLUMN b BIT NOT NULL;
ALTER TABLE t1 CHANGE b c BIT NOT NULL;
DROP TABLE t1;

This would trigger another assertion failure in innobase_rename_or_enlarge_column_try():

	DBUG_ASSERT(!dtype_is_string_type(col->mtype)
		    || col->mbminlen == cf.charset->mbminlen);

It turns out that the cf.charset is garbage for types that do not use a character set. Luckily, altered_table->field[]->charset() is correct my_charset_bin, and at this point we do have it available to us. So, we must replace the unreliable Create_field::charset references.

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