[MDEV-18016] Assertion failure in dict_table_check_for_dup_indexes / ha_innobase::commit_inplace_alter_table upon ADD FOREIGN KEY or ADD FULLTEXT Created: 2018-12-15  Updated: 2019-10-30  Resolved: 2019-01-29

Status: Closed
Project: MariaDB Server
Component/s: Full-text Search, Storage Engine - InnoDB, Storage Engine - XtraDB
Affects Version/s: 10.0, 10.1, 10.2, 10.3, 10.4
Fix Version/s: 10.4.3, 10.1.38, 10.0.38, 10.2.22, 10.3.13

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

Issue Links:
Duplicate
duplicates MDEV-15329 [Draft] InnoDB: Assertion failure in ... Closed
is duplicated by MDEV-16654 InnoDB: dict_load_foreigns() returned... Closed
is duplicated by MDEV-18321 Server crash or Failing assertion: 0 ... Closed
Relates
relates to MDEV-18047 Crash in dict_foreign_qualify_index o... Confirmed
relates to MDEV-18017 Assertion `!index->to_be_dropped' or ... Closed
relates to MDEV-18020 Failing assertion: !prebuilt->trx->ch... Closed

 Description   

Note: See also MDEV-15329, MDEV-18017, MDEV-18020

--source include/have_innodb.inc
 
CREATE TABLE t1 (f VARCHAR(256)) ENGINE=InnoDB;
SET SESSION FOREIGN_KEY_CHECKS= OFF ;
ALTER TABLE t1 ADD FOREIGN KEY (f) REFERENCES non_existing_table (x);
ALTER TABLE t1 ADD FULLTEXT INDEX ft1 (f);
ALTER TABLE t1 ADD FULLTEXT INDEX ft2 (f);
 
# Cleanup
DROP TABLE t1;

On 10.2+ debug builds:

10.2 0a2edddbf4

2018-12-16 20:41:54 0x7ff6a84ff700  InnoDB: Assertion failure in file /data/src/10.2/storage/innobase/dict/dict0dict.cc line 6346
 
#6  0x000055acb002a1f2 in ut_dbg_assertion_failed (expr=0x0, file=0x55acb061a290 "/data/src/10.2/storage/innobase/dict/dict0dict.cc", line=6346) at /data/src/10.2/storage/innobase/ut/ut0dbg.cc:60
#7  0x000055acb00deff9 in dict_table_check_for_dup_indexes (table=0x7ff65009aa78, check=CHECK_ALL_COMPLETE) at /data/src/10.2/storage/innobase/dict/dict0dict.cc:6346
#8  0x000055acafe5cf98 in ha_innobase::commit_inplace_alter_table (this=0x7ff6500a9368, altered_table=0x7ff650038620, ha_alter_info=0x7ff6a84fb5d0, commit=true) at /data/src/10.2/storage/innobase/handler/handler0alter.cc:9015
#9  0x000055acafc181e6 in handler::ha_commit_inplace_alter_table (this=0x7ff6500a9368, altered_table=0x7ff650038620, ha_alter_info=0x7ff6a84fb5d0, commit=true) at /data/src/10.2/sql/handler.cc:4231
#10 0x000055acafa67818 in mysql_inplace_alter_table (thd=0x7ff650000d60, table_list=0x7ff6500127a8, table=0x7ff65009ee00, altered_table=0x7ff650038620, ha_alter_info=0x7ff6a84fb5d0, inplace_supported=HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE, target_mdl_request=0x7ff6a84fb640, alter_ctx=0x7ff6a84fc200) at /data/src/10.2/sql/sql_table.cc:7391
#11 0x000055acafa6cd14 in mysql_alter_table (thd=0x7ff650000d60, new_db=0x7ff650012db8 "test", new_name=0x0, create_info=0x7ff6a84fce20, table_list=0x7ff6500127a8, alter_info=0x7ff6a84fcd70, order_num=0, order=0x0, ignore=false) at /data/src/10.2/sql/sql_table.cc:9390
#12 0x000055acafae753a in Sql_cmd_alter_table::execute (this=0x7ff650012e88, thd=0x7ff650000d60) at /data/src/10.2/sql/sql_alter.cc:323
#13 0x000055acaf99fd22 in mysql_execute_command (thd=0x7ff650000d60) at /data/src/10.2/sql/sql_parse.cc:6227
#14 0x000055acaf9a4e6e in mysql_parse (thd=0x7ff650000d60, rawbuf=0x7ff6500126a8 "ALTER TABLE t1 ADD FULLTEXT INDEX ft2 (f)", length=41, parser_state=0x7ff6a84fe1e0, is_com_multi=false, is_next_command=false) at /data/src/10.2/sql/sql_parse.cc:8014
#15 0x000055acaf9924ef in dispatch_command (command=COM_QUERY, thd=0x7ff650000d60, packet=0x7ff650008b01 "ALTER TABLE t1 ADD FULLTEXT INDEX ft2 (f)", packet_length=41, is_com_multi=false, is_next_command=false) at /data/src/10.2/sql/sql_parse.cc:1824
#16 0x000055acaf990e8d in do_command (thd=0x7ff650000d60) at /data/src/10.2/sql/sql_parse.cc:1378
#17 0x000055acafae2201 in do_handle_one_connection (connect=0x55acb2483ec0) at /data/src/10.2/sql/sql_connect.cc:1335
#18 0x000055acafae1f81 in handle_one_connection (arg=0x55acb2483ec0) at /data/src/10.2/sql/sql_connect.cc:1241
#19 0x000055acb03139db in pfs_spawn_thread (arg=0x55acb278e1d0) at /data/src/10.2/storage/perfschema/pfs.cc:1862
#20 0x00007ff6aec1b6db in start_thread (arg=0x7ff6a84ff700) at pthread_create.c:463
#21 0x00007ff6ae00588f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Non-debug build doesn't crash, it produces errors:

10.3 non-debug 5fefcb0a21

2018-12-16 20:49:53 9 [ERROR] Cannot find index ft2 in InnoDB index dictionary.
2018-12-16 20:49:53 9 [ERROR] InnoDB indexes are inconsistent with what defined in .frm for table ./test/t1
2018-12-16 20:49:53 9 [ERROR] InnoDB could not find key no 1 with name ft2 from dict cache for table test/t1
2018-12-16 20:49:53 9 [ERROR] InnoDB: Table test/t1 contains 2 indexes inside InnoDB, which is different from the number of indexes 2 defined in the MariaDB  Have you mixed up .frm files from different installations? See http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting.html

On 10.0 and 10.1 the failure looks a bit different, it happens on the first ADD INDEX already:

10.0 1a7158b88a1

181216 20:47:30 [ERROR] InnoDB: dict_load_foreigns() returned 38 for ALTER TABLE t1 ADD FULLTEXT INDEX ft1 (f)
2018-12-16 20:47:30 7fa9d47c7700  InnoDB: Assertion failure in thread 140367391127296 in file handler0alter.cc line 6047
InnoDB: Failing assertion: 0
 
#5  0x00007fa9d2e39801 in __GI_abort () at abort.c:79
#6  0x00005638084084a0 in ha_innobase::commit_inplace_alter_table (this=0x7fa9be880088, altered_table=0x7fa9beba0070, ha_alter_info=0x7fa9d47c3a00, commit=true) at /data/src/10.0/storage/xtradb/handler/handler0alter.cc:6047
#7  0x000056380809b6f8 in handler::ha_commit_inplace_alter_table (this=0x7fa9be880088, altered_table=0x7fa9beba0070, ha_alter_info=0x7fa9d47c3a00, commit=true) at /data/src/10.0/sql/handler.cc:4228
#8  0x0000563807f4570c in mysql_inplace_alter_table (thd=0x7fa9c7a0c070, table_list=0x7fa9be9a2188, table=0x7fa9be89e470, altered_table=0x7fa9beba0070, ha_alter_info=0x7fa9d47c3a00, inplace_supported=HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE, target_mdl_request=0x7fa9d47c3a70, alter_ctx=0x7fa9d47c4200) at /data/src/10.0/sql/sql_table.cc:7176
#9  0x0000563807f4a118 in mysql_alter_table (thd=0x7fa9c7a0c070, new_db=0x7fa9be9a2768 "test", new_name=0x0, create_info=0x7fa9d47c52c0, table_list=0x7fa9be9a2188, alter_info=0x7fa9d47c5230, order_num=0, order=0x0, ignore=false) at /data/src/10.0/sql/sql_table.cc:8980
#10 0x0000563807fbb1e6 in Sql_cmd_alter_table::execute (this=0x7fa9be9a2838, thd=0x7fa9c7a0c070) at /data/src/10.0/sql/sql_alter.cc:306
#11 0x0000563807e8b622 in mysql_execute_command (thd=0x7fa9c7a0c070) at /data/src/10.0/sql/sql_parse.cc:5118
#12 0x0000563807e8f21b in mysql_parse (thd=0x7fa9c7a0c070, rawbuf=0x7fa9be9a2088 "ALTER TABLE t1 ADD FULLTEXT INDEX ft1 (f)", length=41, parser_state=0x7fa9d47c6660) at /data/src/10.0/sql/sql_parse.cc:6637
#13 0x0000563807e8111f in dispatch_command (command=COM_QUERY, thd=0x7fa9c7a0c070, packet=0x7fa9cc91e071 "ALTER TABLE t1 ADD FULLTEXT INDEX ft1 (f)", packet_length=41) at /data/src/10.0/sql/sql_parse.cc:1300
#14 0x0000563807e803d3 in do_command (thd=0x7fa9c7a0c070) at /data/src/10.0/sql/sql_parse.cc:1003
#15 0x0000563807fb63be in do_handle_one_connection (thd_arg=0x7fa9c7a0c070) at /data/src/10.0/sql/sql_connect.cc:1377
#16 0x0000563807fb610d in handle_one_connection (arg=0x7fa9c7a0c070) at /data/src/10.0/sql/sql_connect.cc:1292
#17 0x00005638083c6304 in pfs_spawn_thread (arg=0x7fa9c773cf70) at /data/src/10.0/storage/perfschema/pfs.cc:1861
#18 0x00007fa9d39186db in start_thread (arg=0x7fa9d47c7700) at pthread_create.c:463
#19 0x00007fa9d2f1a88f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95



 Comments   
Comment by Marko Mäkelä [ 2019-01-29 ]

The assertion ut_ad(0) that fails in 10.0 was added by me in
Bug#15989081 INNODB ALTER TABLE IS NOT ATOMIC
which claims the following:

Revert the work-around and really fix
Bug#14105491 ADD FOREIGN KEY ON COLUMNS BEING RENAMED DOES NOT WORK CORRECTLY

Refactor ha_innobase::commit_inplace_alter_table() as follows:

First, update the data dictionary definitions in the persistent data
dictionary within a single data dictionary transaction. If any step
fails, roll back the dictionary transaction. Update the foreign key
constraints in the same data dictionary transaction with everything
else.

Only if the definitions were successfully updated, perform the
corresponding modifications in the data dictionary cache. In this way,
there is no need to implement any logic for rolling back any changes
in the data dictionary cache. (Adding an index is the most notable
exception to this, as we will allocate a placeholder for the index.)

When adding the assertion, I did not take into account the fact that malformed FOREIGN KEY constraints may be added when foreign_key_checks=0. I think that we must change this code to only output a warning, and no error:

				/* The data dictionary cache
				should be corrupted now.  The
				best solution should be to
				kill and restart the server,
				but the *.frm file has not
				been replaced yet. */
				my_error(ER_CANNOT_ADD_FOREIGN,
					 MYF(0));
				sql_print_error(
					"InnoDB: dict_load_foreigns()"
					" returned %u for %s",
					(unsigned) error,
					thd_query_string(user_thd)
					->str);
				ut_ad(0);

In MariaDB 10.2, it looks like we have gotten a change from MySQL 5.7, causing an assertion failure in a different place.

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