1. MariaDB Server
  2. MDEV-36038

ALTER TABLE…SEQUENCE does not work correctly with InnoDB

    XMLWordPrintable

Details

    Description

      The following change to our regression test suite demonstrates several problems:

      diff --git a/mysql-test/suite/sql_sequence/alter.opt b/mysql-test/suite/sql_sequence/alter.opt
      new file mode 100644
      index 00000000000..c5eebd75ce5
      --- /dev/null
      +++ b/mysql-test/suite/sql_sequence/alter.opt
      @@ -0,0 +1 @@
      +--innodb-sys-tables
      diff --git a/mysql-test/suite/sql_sequence/alter.result b/mysql-test/suite/sql_sequence/alter.result
      index 15b3ed72af6..8f9035f19d0 100644
      --- a/mysql-test/suite/sql_sequence/alter.result
      +++ b/mysql-test/suite/sql_sequence/alter.result
      @@ -166,6 +166,25 @@ next_not_cached_value	minimum_value	maximum_value	start_value	increment	cache_si
       select next value for t1;
       next value for t1
       11
      +$check_innodb_flags;
      +is_sequence
      +12288
      +alter table t1 sequence=0;
      +$check_innodb_flags;
      +is_sequence
      +0
      +alter table t1 sequence=1;
      +$check_innodb_flags;
      +is_sequence
      +12288
      +alter table t1 sequence=0, algorithm=copy;
      +$check_innodb_flags;
      +is_sequence
      +0
      +alter table t1 sequence=1, algorithm=copy;
      +$check_innodb_flags;
      +is_sequence
      +12288
       drop sequence t1;
       #
       # ALTER TABLE
      diff --git a/mysql-test/suite/sql_sequence/alter.test b/mysql-test/suite/sql_sequence/alter.test
      index 9ee2f222312..f68d7d5456f 100644
      --- a/mysql-test/suite/sql_sequence/alter.test
      +++ b/mysql-test/suite/sql_sequence/alter.test
      @@ -80,6 +80,18 @@ alter sequence t1 start=100;
       show create sequence t1;
       select * from t1;
       select next value for t1;
      +let $check_innodb_flags =
      +select flag & 12288 is_sequence from information_schema.innodb_sys_tables
      +where name='test/t1';
      +evalp $check_innodb_flags;
      +alter table t1 sequence=0;
      +evalp $check_innodb_flags;
      +alter table t1 sequence=1;
      +evalp $check_innodb_flags;
      +alter table t1 sequence=0, algorithm=copy;
      +evalp $check_innodb_flags;
      +alter table t1 sequence=1, algorithm=copy;
      +evalp $check_innodb_flags;
       drop sequence t1;
       
       --echo #
      

      This would crash as follows:

      10.6 6e6fcf4d43e9f5812e1870821968a77c9f826b62

      CURRENT_TEST: sql_sequence.alter
      mysqltest: At line 91: query 'alter table t1 sequence=0, algorithm=copy' failed: <Unknown> (2013): Lost connection to server during query
       
      The result from queries just before the failure was:
      < snip >
      Table	Create Table
      t1	CREATE SEQUENCE `t1` start with 100 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 10 nocycle ENGINE=InnoDB
      select * from t1;
      next_not_cached_value	minimum_value	maximum_value	start_value	increment	cache_size	cycle_option	cycle_count
      11	1	9223372036854775806	100	1	10	0	0
      select next value for t1;
      next value for t1
      11
      $check_innodb_flags;
      is_sequence
      12288
      alter table t1 sequence=0;
      $check_innodb_flags;
      is_sequence
      12288
      alter table t1 sequence=1;
      $check_innodb_flags;
      is_sequence
      12288
      alter table t1 sequence=0, algorithm=copy;
      mariadbd: /mariadb/10.6/storage/innobase/row/row0mysql.cc:2685: dberr_t row_rename_table_for_mysql(const char*, const char*, trx_t*, rename_fk): Assertion `err != DB_DUPLICATE_KEY' failed.
      

      The reason for the assertion failure is that mysql_alter_table() wrongly omitted a call to ha_innobase::rename_table() and therefore the InnoDB data dictionary would get out of sync with the TABLE_SHARE and the .frm file. That would be fixed by the following:

      diff --git a/sql/sql_table.cc b/sql/sql_table.cc
      index c20fb8d9bc4..455a771361b 100644
      --- a/sql/sql_table.cc
      +++ b/sql/sql_table.cc
      @@ -11111,7 +11111,8 @@ do_continue:;
           - Neither old or new engine uses files from another engine
             The above is mainly true for the sequence and the partition engine.
         */
      -  engine_changed= ((new_table->file->ht != table->file->ht) &&
      +  engine_changed= ((new_table->file->storage_ht() !=
      +                    table->file->storage_ht()) &&
                          ((!(new_table->file->ha_table_flags() & HA_FILE_BASED) ||
                            !(table->file->ha_table_flags() & HA_FILE_BASED))) &&
                          !(table->file->ha_table_flags() & HA_REUSES_FILE_NAMES) &&
      

      The rest (failure to change the InnoDB dict_table_t::no_rollback() related flags between 0 and 12288) is due to some omissions in handler::check_if_supported_inplace_alter().

      Attachments

        Issue Links

          Activity

            People

              Marko Mäkelä
              Marko Mäkelä
              Votes:
              0 Vote for this issue
              Watchers:
              4 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.