[MDEV-23295] Assertion `fields[i].same(instant.fields[i])' failed in dict_index_t::instant_add_field #2 Created: 2020-07-26  Updated: 2022-06-27  Resolved: 2020-07-27

Status: Closed
Project: MariaDB Server
Component/s: Storage Engine - InnoDB
Affects Version/s: 10.4, 10.5
Fix Version/s: 10.4.14, 10.5.5

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

Issue Links:
Relates
relates to MDEV-17831 Assertion `supports_instant()' failed... Closed
relates to MDEV-22771 Assertion `fields[i].same(instant.fie... Closed
relates to MDEV-23345 Assertion `not_redundant() == old.not... Closed
relates to MDEV-24758 ASAN use-after-poison in ut_memcpy / ... Closed
relates to MDEV-26577 InnoDB: Failing assertion: dict_tf2_i... Closed

 Description   

The fix for MDEV-22771 is already in the branch.

--source include/have_innodb.inc
 
SET @row_format.save= @@innodb_default_row_format;
 
CREATE TABLE t1 (a char(8)) ENGINE=InnoDB DEFAULT CHARSET utf8;
SET GLOBAL innodb_default_row_format= REDUNDANT;
ALTER TABLE t1 ADD b INT;
 
# Cleanup
DROP TABLE t1;
SET GLOBAL innodb_default_row_format= @row_format.save;

10.4 05d62518

mysqld: /data/src/10.4/storage/innobase/handler/handler0alter.cc:466: void dict_index_t::instant_add_field(const dict_index_t&): Assertion `fields[i].same(instant.fields[i])' failed.
200727  1:03:56 [ERROR] mysqld got signal 6 ;
 
#7  0x00007fcdde30af12 in __GI___assert_fail (assertion=0x55fc5f086c98 "fields[i].same(instant.fields[i])", file=0x55fc5f086348 "/data/src/10.4/storage/innobase/handler/handler0alter.cc", line=466, function=0x55fc5f08f300 <dict_index_t::instant_add_field(dict_index_t const&)::__PRETTY_FUNCTION__> "void dict_index_t::instant_add_field(const dict_index_t&)") at assert.c:101
#8  0x000055fc5e76ca90 in dict_index_t::instant_add_field (this=0x7fcd8c1583a0, instant=...) at /data/src/10.4/storage/innobase/handler/handler0alter.cc:466
#9  0x000055fc5e76e9ec in dict_table_t::instant_column (this=0x7fcd8c19ff10, table=..., col_map=0x7fcd8c16b340) at /data/src/10.4/storage/innobase/handler/handler0alter.cc:636
#10 0x000055fc5e771129 in ha_innobase_inplace_ctx::instant_column (this=0x7fcd8c014800) at /data/src/10.4/storage/innobase/handler/handler0alter.cc:1086
#11 0x000055fc5e74f28c in innobase_instant_try (ha_alter_info=0x7fcdd36afd50, ctx=0x7fcd8c014800, altered_table=0x7fcdd36afdf0, table=0x7fcd8c158be0, trx=0x7fcdd814d268) at /data/src/10.4/storage/innobase/handler/handler0alter.cc:5708
#12 0x000055fc5e774b93 in commit_try_norebuild (ha_alter_info=0x7fcdd36afd50, ctx=0x7fcd8c014800, altered_table=0x7fcdd36afdf0, old_table=0x7fcd8c158be0, trx=0x7fcdd814d268, table_name=0x7fcd8c1a17c5 "t1") at /data/src/10.4/storage/innobase/handler/handler0alter.cc:10254
#13 0x000055fc5e762399 in ha_innobase::commit_inplace_alter_table (this=0x7fcd8c19f718, altered_table=0x7fcdd36afdf0, ha_alter_info=0x7fcdd36afd50, commit=true) at /data/src/10.4/storage/innobase/handler/handler0alter.cc:11006
#14 0x000055fc5e4cd429 in handler::ha_commit_inplace_alter_table (this=0x7fcd8c19f718, altered_table=0x7fcdd36afdf0, ha_alter_info=0x7fcdd36afd50, commit=true) at /data/src/10.4/sql/handler.cc:4616
#15 0x000055fc5e25511f in mysql_inplace_alter_table (thd=0x7fcd8c000af0, table_list=0x7fcd8c013278, table=0x7fcd8c158be0, altered_table=0x7fcdd36afdf0, ha_alter_info=0x7fcdd36afd50, inplace_supported=HA_ALTER_INPLACE_INSTANT, target_mdl_request=0x7fcdd36b0bc0, alter_ctx=0x7fcdd36b1700) at /data/src/10.4/sql/sql_table.cc:7797
#16 0x000055fc5e25bdce in mysql_alter_table (thd=0x7fcd8c000af0, new_db=0x7fcd8c0052b0, new_name=0x7fcd8c0056b8, create_info=0x7fcdd36b22f0, table_list=0x7fcd8c013278, alter_info=0x7fcdd36b2230, order_num=0, order=0x0, ignore=false) at /data/src/10.4/sql/sql_table.cc:10156
#17 0x000055fc5e2f40f1 in Sql_cmd_alter_table::execute (this=0x7fcd8c013a60, thd=0x7fcd8c000af0) at /data/src/10.4/sql/sql_alter.cc:520
#18 0x000055fc5e1717a0 in mysql_execute_command (thd=0x7fcd8c000af0) at /data/src/10.4/sql/sql_parse.cc:6098
#19 0x000055fc5e176c91 in mysql_parse (thd=0x7fcd8c000af0, rawbuf=0x7fcd8c013198 "ALTER TABLE t1 ADD b INT", length=24, parser_state=0x7fcdd36b3570, is_com_multi=false, is_next_command=false) at /data/src/10.4/sql/sql_parse.cc:7896
#20 0x000055fc5e1631c6 in dispatch_command (command=COM_QUERY, thd=0x7fcd8c000af0, packet=0x7fcd8c0083a1 "ALTER TABLE t1 ADD b INT", packet_length=24, is_com_multi=false, is_next_command=false) at /data/src/10.4/sql/sql_parse.cc:1835
#21 0x000055fc5e161968 in do_command (thd=0x7fcd8c000af0) at /data/src/10.4/sql/sql_parse.cc:1353
#22 0x000055fc5e2eab0c in do_handle_one_connection (connect=0x55fc61035760) at /data/src/10.4/sql/sql_connect.cc:1412
#23 0x000055fc5e2ea85b in handle_one_connection (arg=0x55fc61035760) at /data/src/10.4/sql/sql_connect.cc:1316
#24 0x000055fc5ecea879 in pfs_spawn_thread (arg=0x55fc610515f0) at /data/src/10.4/storage/perfschema/pfs.cc:1869
#25 0x00007fcde02934a4 in start_thread (arg=0x7fcdd36b4700) at pthread_create.c:456
#26 0x00007fcdde3c7d0f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:97

Not reproducible on 10.3.
No obvious problem on a non-debug build.



 Comments   
Comment by Marko Mäkelä [ 2020-07-27 ]

The problem seems to be that the dummy table object instant.table was created in ROW_FORMAT=REDUNDANT instead of the current ROW_FORMAT of the table. There are two possible fixes:

  • Ignore the global parameter and preserve the table in the original ROW_FORMAT.
  • Refuse the ALGORITHM=INSTANT operation because the ROW_FORMAT would change.

This bug demonstrates how problematic it is to introduce global parameters that affect DDL operations. We also face the challenge that the global parameter could be modified between the time we checked it in ha_innobase::check_if_supported_inplace_alter() and again in prepare_inplace_alter_table_dict(). We might first confirm that an ALGORITHM=INSTANT operation is possible, but then find out that the ROW_FORMAT change actually requires that the table be rebuilt.

Comment by Marko Mäkelä [ 2020-07-27 ]

It would be consistent with the MDEV-17831 fix to preserve the existing ROW_FORMAT in dict_table_t::prepare_instant().

Comment by Marko Mäkelä [ 2020-07-27 ]

In dict_table_t::prepare_instant() we definitely do not support changing the ROW_FORMAT between REDUNDANT and DYNAMIC or COMPACT. Some assertions will be needed.

I think that it is most consistent to remember the return value of handler::check_if_supported_inplace_alter() and to preserve the ROW_FORMAT in ha_innobase::prepare_inplace_alter_table() if ALGORITHM=INSTANT had been promised.

I used the following test case to test my fix. It is returning the correct ROW_FORMAT for all 3 combinations in 10.3:

--source include/have_innodb.inc
--source include/innodb_row_format.inc
SET @row_format.save= @@innodb_default_row_format;
CREATE TABLE t1 (a char(8)) ENGINE=InnoDB DEFAULT CHARSET utf8;
SET GLOBAL innodb_default_row_format= COMPACT;
ALTER TABLE t1 ADD b INT;
SELECT ROW_FORMAT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1';
DROP TABLE t1;
SET GLOBAL innodb_default_row_format= @row_format.save;

If I omit my actual fix, the 2 added assertions in dict_table_t::prepare_instant() would fail.

Comment by Nikita Malyavin [ 2020-07-27 ]

the sql-side changes are fine, now it's Thiru's turn

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