[MDEV-13205] InnoDB: Failing assertion: !dict_index_is_online_ddl(index) upon ALTER TABLE Created: 2017-06-29  Updated: 2018-08-15  Resolved: 2018-01-08

Status: Closed
Project: MariaDB Server
Component/s: Data Definition - Alter Table, Storage Engine - InnoDB, Storage Engine - XtraDB
Affects Version/s: 10.0, 10.1, 10.2, 10.3
Fix Version/s: 10.0.34, 10.3.4, 10.1.31, 10.2.13

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

Issue Links:
Relates
relates to MDEV-13200 Assertion `index->id == btr_page_get_... Closed
Sprint: 10.2.12

 Description   

Run the test with repeat=N. So far repeat=5 has always been enough for me.

--source include/have_innodb.inc
 
CREATE TABLE t1 (c VARCHAR(64)) ENGINE=InnoDB;
INSERT INTO t1 VALUES  ('foo'),('bar');
 
CREATE TABLE t2 ENGINE = InnoDB AS SELECT * FROM t1;
CREATE TABLE t3 ENGINE = InnoDB AS SELECT * FROM t1;
 
--send
ALTER TABLE t2 ADD UNIQUE (c);
--connect (con2,127.0.0.1,root,,test)
--error 0,ER_DUP_ENTRY
INSERT INTO t2 SELECT * FROM t1;
ALTER TABLE t3 ADD FOREIGN KEY (c) REFERENCES t2 (c);
 
# Cleanup
--disconnect con2
--connection default
--error 0,ER_DUP_ENTRY
--reap
DROP TABLE t3, t2, t1;

10.0 a02ba9c1c96f8245b2fd5c8b555c74204af421e3

2017-06-29 03:38:52 7f0cf2866700  InnoDB: Assertion failure in thread 139693585229568 in file lock0lock.cc line 6460
InnoDB: Failing assertion: !dict_index_is_online_ddl(index)
InnoDB: We intentionally generate a memory trap.
InnoDB: Submit a detailed bug report to http://bugs.mysql.com.
InnoDB: If you get repeated assertion failures or crashes, even
InnoDB: immediately after the mysqld startup, there may be
InnoDB: corruption in the InnoDB tablespace. Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.6/en/forcing-innodb-recovery.html
InnoDB: about forcing recovery.
170629  3:38:52 [ERROR] mysqld got signal 6 ;

#5  0x00007f0cf05833fa in abort () from /lib/x86_64-linux-gnu/libc.so.6
#6  0x00007f0ce8fa07b7 in lock_sec_rec_read_check_and_lock (flags=0, block=0x7f0ce85bf980, rec=0x7f0ce88c408f "foo", index=0x7f0cdc7538f8, offsets=0x7f0cf2861610, mode=LOCK_S, gap_mode=1024, thr=0x7f0cdc88f390) at /data/src/10.0/storage/innobase/lock/lock0lock.cc:6460
#7  0x00007f0ce901e706 in row_ins_set_shared_rec_lock (type=1024, block=0x7f0ce85bf980, rec=0x7f0ce88c408f "foo", index=0x7f0cdc7538f8, offsets=0x7f0cf2861610, thr=0x7f0cdc88f390) at /data/src/10.0/storage/innobase/row/row0ins.cc:1366
#8  0x00007f0ce901ee33 in row_ins_check_foreign_constraint (check_ref=1, foreign=0x7f0cdc8c0418, table=0x7f0cdc8dd0f8, entry=0x7f0cdc8dd690, thr=0x7f0cdc88f390) at /data/src/10.0/storage/innobase/row/row0ins.cc:1605
#9  0x00007f0ce901f325 in row_ins_check_foreign_constraints (table=0x7f0cdc8dd0f8, index=0x7f0cdc8ddd78, entry=0x7f0cdc8dd690, thr=0x7f0cdc88f390) at /data/src/10.0/storage/innobase/row/row0ins.cc:1817
#10 0x00007f0ce90215fd in row_ins_sec_index_entry (index=0x7f0cdc8ddd78, entry=0x7f0cdc8dd690, thr=0x7f0cdc88f390) at /data/src/10.0/storage/innobase/row/row0ins.cc:2922
#11 0x00007f0ce90217d1 in row_ins_index_entry (index=0x7f0cdc8ddd78, entry=0x7f0cdc8dd690, thr=0x7f0cdc88f390) at /data/src/10.0/storage/innobase/row/row0ins.cc:2978
#12 0x00007f0ce9021a7b in row_ins_index_entry_step (node=0x7f0cdc88f130, thr=0x7f0cdc88f390) at /data/src/10.0/storage/innobase/row/row0ins.cc:3053
#13 0x00007f0ce9021d8e in row_ins (node=0x7f0cdc88f130, thr=0x7f0cdc88f390) at /data/src/10.0/storage/innobase/row/row0ins.cc:3193
#14 0x00007f0ce90220f5 in row_ins_step (thr=0x7f0cdc88f390) at /data/src/10.0/storage/innobase/row/row0ins.cc:3318
#15 0x00007f0ce9037ae9 in row_insert_for_mysql (mysql_rec=0x7f0cdc8c5088 "\376\003foo", prebuilt=0x7f0cdc88ec78) at /data/src/10.0/storage/innobase/row/row0mysql.cc:1367
#16 0x00007f0ce8f466b2 in ha_innodb::write_row (this=0x7f0cdc86b888, record=0x7f0cdc8c5088 "\376\003foo") at /data/src/10.0/storage/innobase/handler/ha_innodb.cc:7257
#17 0x0000000000843fbb in handler::ha_write_row (this=0x7f0cdc86b888, buf=0x7f0cdc8c5088 "\376\003foo") at /data/src/10.0/sql/handler.cc:6015
#18 0x00000000007055e0 in copy_data_between_tables (thd=0x7f0ce4b6f070, from=0x7f0cdc49fc70, to=0x7f0cdc8f1070, create=..., ignore=false, order_num=0, order=0x0, copied=0x7f0cf2864340, deleted=0x7f0cf2864338, keys_onoff=Alter_info::LEAVE_AS_IS, alter_ctx=0x7f0cf2863850) at /data/src/10.0/sql/sql_table.cc:9538
#19 0x0000000000703db8 in mysql_alter_table (thd=0x7f0ce4b6f070, new_db=0x7f0cdc822780 "test", new_name=0x0, create_info=0x7f0cf28644f0, table_list=0x7f0cdc8221a0, alter_info=0x7f0cf2864460, order_num=0, order=0x0, ignore=false) at /data/src/10.0/sql/sql_table.cc:9026
#20 0x000000000076baaf in Sql_cmd_alter_table::execute (this=0x7f0cdc822980, thd=0x7f0ce4b6f070) at /data/src/10.0/sql/sql_alter.cc:312
#21 0x00000000006529d3 in mysql_execute_command (thd=0x7f0ce4b6f070) at /data/src/10.0/sql/sql_parse.cc:5124
#22 0x0000000000655e0a in mysql_parse (thd=0x7f0ce4b6f070, rawbuf=0x7f0cdc822088 "ALTER TABLE t3 ADD FOREIGN KEY (c) REFERENCES t2 (c)", length=52, parser_state=0x7f0cf2865650) at /data/src/10.0/sql/sql_parse.cc:6579
#23 0x000000000064896a in dispatch_command (command=COM_QUERY, thd=0x7f0ce4b6f070, packet=0x7f0ce4b75071 "ALTER TABLE t3 ADD FOREIGN KEY (c) REFERENCES t2 (c)", packet_length=52) at /data/src/10.0/sql/sql_parse.cc:1309
#24 0x0000000000647c2d in do_command (thd=0x7f0ce4b6f070) at /data/src/10.0/sql/sql_parse.cc:999
#25 0x0000000000767202 in do_handle_one_connection (thd_arg=0x7f0ce4b6f070) at /data/src/10.0/sql/sql_connect.cc:1377
#26 0x0000000000766f74 in handle_one_connection (arg=0x7f0ce4b6f070) at /data/src/10.0/sql/sql_connect.cc:1292
#27 0x0000000000ac6bee in pfs_spawn_thread (arg=0x7f0ce4b19b70) at /data/src/10.0/storage/perfschema/pfs.cc:1860
#28 0x00007f0cf24ec494 in start_thread (arg=0x7f0cf2866700) at pthread_create.c:333
#29 0x00007f0cf063793f in clone () from /lib/x86_64-linux-gnu/libc.so.6



 Comments   
Comment by Marko Mäkelä [ 2017-07-05 ]

The ALTER TABLE t2 ADD UNIQUE(c) is aborted due to a duplicate key error, but the index stub cannot be dropped. So, the dict_table_t::drop_aborted flag was set. Normally this flag would be handled by the next ALGORITHM=INPLACE operation (if any).

Normally, DML operations would skip aborted indexes. However, FOREIGN KEY operations use a different code path. The ALTER TABLE t3 ADD FOREIGN KEY (c) REFERENCES t2 (c); is wrongly choosing the above-mentioned index stub for check_index, and it is ultimately tripping the assertion.

The root cause of this failure would seem to be that dict_foreign_t::referenced_index is wrongly set to point to an invalid index stub. The following patch is a step to the right direction, but it needs more work because the supplied test case would (with enough repetitions) occasionally fail in a different way:

CURRENT_TEST: innodb.mdev13205
mysqltest: At line 11: query 'ALTER TABLE t3 ADD FOREIGN KEY (c) REFERENCES t2 (c)' failed: 1005: Can't create table `test`.`#sql-4cb8_4` (errno: 150 "Foreign key constraint is incorrectly formed")

diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index e2ee13234ad..1bd8fa2a0c8 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -3459,6 +3459,7 @@ dict_foreign_find_index(
 		if (types_idx != index
 		    && !(index->type & DICT_FTS)
 		    && !index->to_be_dropped
+		    && !dict_index_is_online_ddl(index)
 		    && dict_foreign_qualify_index(
 			    table, col_names, columns, n_cols,
 			    index, types_idx,

Comment by Marko Mäkelä [ 2018-01-08 ]

It turns out that my fix is good for this, and the error for the ADD FOREIGN KEY is to be expected when the ADD UNIQUE INDEX failed earlier. I added a DEBUG_SYNC test to innodb.innodb-index-online.

Comment by Marko Mäkelä [ 2018-07-30 ]

For the record, MySQL 5.6.41 and 5.7.23, which were just published on 2018-07-27, contain a similar fix, dated 2018-05-23. Coincidence? Also my MDEV-13899 fix was ‘copied’ to 5.6.40.

Comment by Marko Mäkelä [ 2018-08-14 ]

Some race condition remains, causing a freed dict_index_t to be accessed, because I just repeated MDEV-13200 in 10.2 and 10.0, even with an initial fix for MDEV-16465 applied.

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