Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-18016

Assertion failure in dict_table_check_for_dup_indexes / ha_innobase::commit_inplace_alter_table upon ADD FOREIGN KEY or ADD FULLTEXT

Details

    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
      

      Attachments

        Issue Links

          Activity

            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.

            marko Marko Mäkelä added a comment - 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.

            People

              marko Marko Mäkelä
              elenst Elena Stepanova
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.