[MDEV-27554] Server crashes in handler::check_duplicate_long_entry_key after ALTER Created: 2022-01-20  Updated: 2022-04-23  Resolved: 2022-04-23

Status: Closed
Project: MariaDB Server
Component/s: Data Definition - Alter Table, GIS, Storage Engine - InnoDB
Affects Version/s: None
Fix Version/s: N/A

Type: Bug Priority: Major
Reporter: Alice Sherepa Assignee: Oleksandr Byelkin
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to MDEV-22847 Server crashes in handler::check_dupl... Closed

 Description   

--source include/have_innodb.inc
 
CREATE TABLE t1 (k varchar(10), c varchar(10), a1 linestring, KEY (k(10)), KEY (c)) engine=innodb;
INSERT INTO t1 VALUES('','j',''), ('','','');
 
ALTER TABLE t1 change COLUMN IF EXISTS n a1 SERIAL;

preview-10.8-MDEV-11675-rpl-lag-free-alter c0e3a6cabed6ddb0c84f929

220120 15:38:39 [ERROR] mysqld got signal 11 ;
 
Server version: 10.8.0-MariaDB-debug-log
 
sigaction.c:0(__restore_rt)[0x7f60841fb3c0]
sql/handler.cc:7173(handler::check_duplicate_long_entry_key(unsigned char const*, unsigned int))[0x560caf4e7a82]
sql/handler.cc:7248(handler::check_duplicate_long_entries(unsigned char const*))[0x560caf4e912f]
sql/handler.cc:7509(handler::ha_write_row(unsigned char const*))[0x560caf4eb31c]
sql/sql_table.cc:11553(copy_data_between_tables(THD*, TABLE*, TABLE*, List<Create_field>&, bool, unsigned int, st_order*, unsigned long long*, unsigned long long*, Alter_info::enum_enable_or_disable, Alter_table_ctx*))[0x560caeef9daf]
sql/sql_table.cc:10800(mysql_alter_table(THD*, st_mysql_const_lex_string const*, st_mysql_const_lex_string const*, HA_CREATE_INFO*, TABLE_LIST*, Alter_info*, unsigned int, st_order*, bool, bool))[0x560caeef36ba]
sql/sql_alter.cc:543(Sql_cmd_alter_table::execute(THD*))[0x560caf0b1c1b]
sql/sql_parse.cc:5989(mysql_execute_command(THD*, bool))[0x560caec0f27e]
sql/sql_parse.cc:8028(mysql_parse(THD*, char*, unsigned int, Parser_state*))[0x560caec1caae]
sql/sql_parse.cc:1896(dispatch_command(enum_server_command, THD*, char*, unsigned int, bool))[0x560caebf2b88]
sql/sql_parse.cc:1402(do_command(THD*, bool))[0x560caebef8ac]
sql/sql_connect.cc:1418(do_handle_one_connection(CONNECT*, bool))[0x560caf093e4d]
sql/sql_connect.cc:1314(handle_one_connection)[0x560caf0936d9]
perfschema/pfs.cc:2203(pfs_spawn_thread)[0x560cafd43d3d]
nptl/pthread_create.c:478(start_thread)[0x7f60841ef609]
??:0(clone)[0x7f6083dc2293]
 
Query (0x6290003072a8): ALTER TABLE t1 change COLUMN IF EXISTS n a1 SERIAL

if use blob instead of linesting :

=================================================================
==620238==ERROR: AddressSanitizer: use-after-poison on address 0x61a00015b203 at pc 0x5643040f8338 bp 0x7faf7f5c3150 sp 0x7faf7f5c3140
READ of size 1 at 0x61a00015b203 thread T16
    #0 0x5643040f8337 in key_copy(unsigned char*, unsigned char const*, st_key const*, unsigned int, bool) /10.8/sql/key.cc:127
    #1 0x564303df77e0 in handler::check_duplicate_long_entry_key(unsigned char const*, unsigned int) /10.8/sql/handler.cc:7161
    #2 0x564303df912e in handler::check_duplicate_long_entries(unsigned char const*) /10.8/sql/handler.cc:7248
    #3 0x564303dfb31b in handler::ha_write_row(unsigned char const*) /10.8/sql/handler.cc:7509
    #4 0x564303809dae in copy_data_between_tables /10.8/sql/sql_table.cc:11553
    #5 0x5643038036b9 in mysql_alter_table(THD*, st_mysql_const_lex_string const*, st_mysql_const_lex_string const*, HA_CREATE_INFO*, TABLE_LIST*, Alter_info*, unsigned int, st_order*, bool, bool) /10.8/sql/sql_table.cc:10800
    #6 0x5643039c1c1a in Sql_cmd_alter_table::execute(THD*) /10.8/sql/sql_alter.cc:543
    #7 0x56430351f27d in mysql_execute_command(THD*, bool) /10.8/sql/sql_parse.cc:5989
    #8 0x56430352caad in mysql_parse(THD*, char*, unsigned int, Parser_state*) /10.8/sql/sql_parse.cc:8028
    #9 0x564303502b87 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /10.8/sql/sql_parse.cc:1894
    #10 0x5643034ff8ab in do_command(THD*, bool) /10.8/sql/sql_parse.cc:1402
    #11 0x5643039a3e4c in do_handle_one_connection(CONNECT*, bool) /10.8/sql/sql_connect.cc:1418
    #12 0x5643039a36d8 in handle_one_connection /10.8/sql/sql_connect.cc:1312
    #13 0x564304653d3c in pfs_spawn_thread /10.8/storage/perfschema/pfs.cc:2201
    #14 0x7faf8ed03608 in start_thread /build/glibc-eX1tMB/glibc-2.31/nptl/pthread_create.c:477
    #15 0x7faf8e8d6292 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x122292)
 
0x61a00015b203 is located 899 bytes inside of 1156-byte region [0x61a00015ae80,0x61a00015b304)
allocated by thread T16 here:
    #0 0x7faf8f1febc8 in malloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8)
    #1 0x5643052b1e4d in sf_malloc /10.8/mysys/safemalloc.c:126
    #2 0x56430527f073 in my_malloc /10.8/mysys/my_malloc.c:90
    #3 0x564305259d0f in root_alloc /10.8/mysys/my_alloc.c:66
    #4 0x56430525b4c5 in alloc_root /10.8/mysys/my_alloc.c:332
    #5 0x56430525bcb2 in multi_alloc_root /10.8/mysys/my_alloc.c:402
    #6 0x5643038bfde6 in copy_keys_from_share(TABLE*, st_mem_root*) /10.8/sql/table.cc:3925
    #7 0x5643038c1bde in open_table_from_share(THD*, TABLE_SHARE*, st_mysql_const_lex_string const*, unsigned int, unsigned int, unsigned int, TABLE*, bool, List<String>*) /10.8/sql/table.cc:4140
    #8 0x564303c0b31c in THD::open_temporary_table(TMP_TABLE_SHARE*, char const*) /10.8/sql/temporary_tables.cc:1126
    #9 0x564303c04676 in THD::create_and_open_tmp_table(st_mysql_const_unsigned_lex_string*, char const*, char const*, char const*, bool) /10.8/sql/temporary_tables.cc:74
    #10 0x564303802d60 in mysql_alter_table(THD*, st_mysql_const_lex_string const*, st_mysql_const_lex_string const*, HA_CREATE_INFO*, TABLE_LIST*, Alter_info*, unsigned int, st_order*, bool, bool) /10.8/sql/sql_table.cc:10727
    #11 0x5643039c1c1a in Sql_cmd_alter_table::execute(THD*) /10.8/sql/sql_alter.cc:543
    #12 0x56430351f27d in mysql_execute_command(THD*, bool) /10.8/sql/sql_parse.cc:5989
    #13 0x56430352caad in mysql_parse(THD*, char*, unsigned int, Parser_state*) /10.8/sql/sql_parse.cc:8028
    #14 0x564303502b87 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /10.8/sql/sql_parse.cc:1894
    #15 0x5643034ff8ab in do_command(THD*, bool) /10.8/sql/sql_parse.cc:1402
    #16 0x5643039a3e4c in do_handle_one_connection(CONNECT*, bool) /10.8/sql/sql_connect.cc:1418
    #17 0x5643039a36d8 in handle_one_connection /10.8/sql/sql_connect.cc:1312
    #18 0x564304653d3c in pfs_spawn_thread /10.8/storage/perfschema/pfs.cc:2201
    #19 0x7faf8ed03608 in start_thread /build/glibc-eX1tMB/glibc-2.31/nptl/pthread_create.c:477
 
Thread T16 created by T0 here:
    #0 0x7faf8f12b805 in pthread_create (/lib/x86_64-linux-gnu/libasan.so.5+0x3a805)
    #1 0x56430464ecf2 in my_thread_create /10.8/storage/perfschema/my_thread.h:48
    #2 0x56430465412f in pfs_spawn_thread_v1 /10.8/storage/perfschema/pfs.cc:2252
    #3 0x564303147b68 in inline_mysql_thread_create /10.8/include/mysql/psi/mysql_thread.h:1139
    #4 0x56430315f8d0 in create_thread_to_handle_connection(CONNECT*) /10.8/sql/mysqld.cc:5969
    #5 0x56430315ff4c in create_new_thread(CONNECT*) /10.8/sql/mysqld.cc:6028
    #6 0x5643031602b9 in handle_accepted_socket(st_mysql_socket, st_mysql_socket) /10.8/sql/mysqld.cc:6090
    #7 0x564303160c8e in handle_connections_sockets() /10.8/sql/mysqld.cc:6214
    #8 0x56430315f0dd in mysqld_main(int, char**) /10.8/sql/mysqld.cc:5864
    #9 0x564303146e8c in main /10.8/sql/main.cc:34
    #10 0x7faf8e7db0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
 
SUMMARY: AddressSanitizer: use-after-poison /10.8/sql/key.cc:127 in key_copy(unsigned char*, unsigned char const*, st_key const*, unsigned int, bool)



 Comments   
Comment by Elena Stepanova [ 2022-02-23 ]

It looks like the bug either never made it to the main branch, or was fixed in it already. Is it right?

Comment by Andrei Elkin [ 2022-02-24 ]

I've just verified an actual fixed status of what alice found herself at examining a later a855d6d93acf0af 10.8 revision.
This server ALTER bug then was fixed somewhere in between 6208228b789..a855d6d93acf0af of 10.8.

Apparently it just needs closing with Can't-repeat. I am leaving that out to alice.

Comment by Roel Van de Paar [ 2022-03-09 ]

There seem to be various unresolved issues here; consider the differences and issues between these testcase variations;

CREATE TABLE t (c LINESTRING) ENGINE=InnoDB;
INSERT INTO t VALUES (''), ('');
ALTER TABLE t CHANGE COLUMN IF EXISTS n c SERIAL;

10.9.0 4a2a9c02cd6611ef36bbb735c2b483dbc83580d4 (Debug)

10.9.0-dbg>INSERT INTO t VALUES (''), ('');
Query OK, 2 rows affected (0.003 sec)
Records: 2  Duplicates: 0  Warnings: 0
 
10.9.0-dbg>ALTER TABLE t CHANGE COLUMN IF EXISTS n c SERIAL;
ERROR 1062 (23000): Duplicate entry '' for key 'c'

CREATE TABLE t (c SERIAL) ENGINE=InnoDB;
INSERT INTO t VALUES (''), ('');

10.9.0 4a2a9c02cd6611ef36bbb735c2b483dbc83580d4 (Debug)

10.9.0-dbg>INSERT INTO t VALUES (''), ('');
ERROR 1366 (22007): Incorrect integer value: '' for column `test`.`t`.`c` at row 1

CREATE TABLE t (c LINESTRING) ENGINE=InnoDB;
INSERT INTO t VALUES (''), ('');
ALTER TABLE t CHANGE COLUMN n c SERIAL;

10.9.0 4a2a9c02cd6611ef36bbb735c2b483dbc83580d4 (Debug)

10.9.0-dbg>ALTER TABLE t CHANGE COLUMN n c SERIAL;
ERROR 1054 (42S22): Unknown column 'n' in 't'

CREATE TABLE t (c SERIAL) ENGINE=InnoDB;
ALTER TABLE t CHANGE COLUMN c n LINESTRING;
INSERT INTO t VALUES (''), ('');

10.9.0 4a2a9c02cd6611ef36bbb735c2b483dbc83580d4 (Debug)

10.9.0-dbg>ALTER TABLE t CHANGE COLUMN c n LINESTRING;
Query OK, 0 rows affected (0.029 sec)              
Records: 0  Duplicates: 0  Warnings: 0
 
10.9.0-dbg>INSERT INTO t VALUES (''), ('');
ERROR 1062 (23000): Duplicate entry '' for key 'c'

Comment by Andrei Elkin [ 2022-03-09 ]

sanja, howdy. In the light of Roel further exploits the issue apparently was not resolved unlike I guessed in my comments. The stack was seen at versions before MDEV-11675 Alter 2 phase replication, so I am not looking into it. Maybe this one fits to Nikita's interests. Leaving this to you.

Comment by Sergei Golubchik [ 2022-03-21 ]

Roel, what versions are affected?

Comment by Roel Van de Paar [ 2022-03-22 ]

Tested on debug builds.

Revisions:

10.2.44 unknown, build 16-03-2022. Other versions build on same day.
10.3.35 6a2d88c132221ea07dd322060089c85ff5e469b5
10.4.25 9c6135e81f29b3e3286d6b864c0fdafc2fea16ce 
10.5.16 73fee39ea62037780c59161507e89dd76c10b7a3
10.6.8  b2c81e06b042025663ea01fa98dac0ff536c7706
10.7.4  dc4b7f382baa9ef7fb6259d32c18f6a7e6564790
10.8.3  9f5a3e568913e0810109554608c56c93f3ec24f8
10.9.0  5be92887c2caacb45af87b1131db952ce627e83a

CREATE TABLE t (c LINESTRING) ENGINE=InnoDB;
INSERT INTO t VALUES (''), ('');
ALTER TABLE t CHANGE COLUMN IF EXISTS n c SERIAL;

Leads to (last command):

10.2: ERROR 1170 (42000): BLOB/TEXT column 'c' used in key specification without a key length
10.3: ERROR 1170 (42000): BLOB/TEXT column 'c' used in key specification without a key length
10.4: ERROR 1062 (23000): Duplicate entry '' for key 'c'
10.5: ERROR 1062 (23000): Duplicate entry '' for key 'c'
10.6: ERROR 1062 (23000): Duplicate entry '' for key 'c'
10.7: ERROR 1062 (23000): Duplicate entry '' for key 'c'
10.8: ERROR 1062 (23000): Duplicate entry '' for key 'c'
10.9: ERROR 1062 (23000): Duplicate entry '' for key 'c'

CREATE TABLE t (c SERIAL) ENGINE=InnoDB;
INSERT INTO t VALUES (''), ('');

Leads to (last command):

10.2: ERROR 1366 (22007): Incorrect integer value: '' for column `test`.`t`.`c` at row 1
10.3: ERROR 1366 (22007): Incorrect integer value: '' for column `test`.`t`.`c` at row 1
10.4: ERROR 1366 (22007): Incorrect integer value: '' for column `test`.`t`.`c` at row 1
10.5: ERROR 1366 (22007): Incorrect integer value: '' for column `test`.`t`.`c` at row 1
10.6: ERROR 1366 (22007): Incorrect integer value: '' for column `test`.`t`.`c` at row 1
10.7: ERROR 1366 (22007): Incorrect integer value: '' for column `test`.`t`.`c` at row 1
10.8: ERROR 1366 (22007): Incorrect integer value: '' for column `test`.`t`.`c` at row 1
10.9: ERROR 1366 (22007): Incorrect integer value: '' for column `test`.`t`.`c` at row 1

CREATE TABLE t (c LINESTRING) ENGINE=InnoDB;
INSERT INTO t VALUES (''), ('');
ALTER TABLE t CHANGE COLUMN n c SERIAL;

Leads to (last command):

10.2: ERROR 1054 (42S22): Unknown column 'n' in 't'
10.3: ERROR 1054 (42S22): Unknown column 'n' in 't'
10.4: ERROR 1054 (42S22): Unknown column 'n' in 't'
10.5: ERROR 1054 (42S22): Unknown column 'n' in 't'
10.6: ERROR 1054 (42S22): Unknown column 'n' in 't'
10.7: ERROR 1054 (42S22): Unknown column 'n' in 't'
10.8: ERROR 1054 (42S22): Unknown column 'n' in 't'
10.9: ERROR 1054 (42S22): Unknown column 'n' in 't'

CREATE TABLE t (c SERIAL) ENGINE=InnoDB;
ALTER TABLE t CHANGE COLUMN c n LINESTRING;
INSERT INTO t VALUES (''), ('');

Leads to (last command):

10.2: ERROR 1366 (22007): Incorrect integer value: '' for column `test`.`t`.`c` at row 1 (with prior ERROR 1170 (42000): BLOB/TEXT column 'n' used in key specification without a key length)
10.3: ERROR 1366 (22007): Incorrect integer value: '' for column `test`.`t`.`c` at row 1 (with prior ERROR 1170 (42000): BLOB/TEXT column 'n' used in key specification without a key length)
10.4: ERROR 1062 (23000): Duplicate entry '' for key 'c'
10.5: ERROR 1062 (23000): Duplicate entry '' for key 'c'
10.6: ERROR 1062 (23000): Duplicate entry '' for key 'c'
10.7: ERROR 1062 (23000): Duplicate entry '' for key 'c'
10.8: ERROR 1062 (23000): Duplicate entry '' for key 'c'
10.9: ERROR 1062 (23000): Duplicate entry '' for key 'c'

Comment by Roel Van de Paar [ 2022-03-22 ]

Unclear on how to deduce affected versions from this. It seems to depends on whether 10.2/10.3 is seen as correct or not and/or the correct priority of errors (if any).

Comment by Elena Stepanova [ 2022-04-19 ]

what versions are affected?

serg, Elkin,
Which part of the comments did you consider a bug? I don't see anything wrong in the above at a quick glance, maybe I'm missing something.

Comment by Andrei Elkin [ 2022-04-20 ]

elenst, in my latest comments I wrote 'not fixed bug' under impression Roel's followups confirm/comply-with the description stack.
Now I don't see it this way.

Comment by Sergei Golubchik [ 2022-04-23 ]

why

create table t (c linestring);
insert into t values (''), ('');
alter table t change column if exists n c serial;

changes (or tries to change before 10.4) the table structure? The column n does not exist, so change column if exists should not change anything, should it?

Comment by Elena Stepanova [ 2022-04-23 ]

serg,

If you mean the general case, then of course all 10.0+ versions are affected, ever since IF [NOT] EXISTS was introduced in ALTER. The basic non-complicated example is

create table t (c int);
alter table t add column if not exists c bigint unique;
Warnings:
Note	1060	Duplicate column name 'c'
show create table t;
Table	Create Table
t	CREATE TABLE `t` (
  `c` int(11) DEFAULT NULL,
  UNIQUE KEY `c` (`c`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

Same for PRIMARY KEY and such. I would guess that when MDEV-318 was being implemented, it was treated, maybe wrongly, as a case of

If the ALTER TABLE command consists of multiple operations, it's not interrupted in the IF [NOT] EXISTS case, but succeedes with the appropriate
amount of warnings.

(quote from MDEV-318 description).

For the special case of SERIAL however, while it also has this UNIQUE under the hood, the ALTER_ADD_INDEX flag wasn't set and the above wouldn't happen until https://github.com/MariaDB/server/commit/3fd80d08740d3ad2426bfb8eb9debc40d96e2a20 was added in 10.3+.

So, depending on which part of it (if any) you want to fix, the affected versions are either 10.2+ or 10.3+, the fix version is a more difficult question.
But anyway it seems unrelated to the originally reported failure, so probably needs a new report if something is to be done about it.

Comment by Sergei Golubchik [ 2022-04-23 ]

Yes, I mean the behavior of IF NOT EXISTS. I agree it should be a new bug report. MDEV-28401

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