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

SIGSEGV in dict_index_t::reconstruct_fields()

    XMLWordPrintable

    Details

      Description

      The following crash was observed on 10.8:

      10.8 a635c40648519fd6c3729c9657872a16a0a20821

      #0  0x000055635ccef651 in dict_index_t::reconstruct_fields()::{lambda(dict_field_t const&)#1}::operator()(dict_field_t const&) const (o=
            @0x61a00000a9e0: {col = 0xbebebebebebebebe, name = {m_name = 0xbebebebebebebebe <error: Cannot access memory at address 0xbebebebebebebebe>}, prefix_len = 3774, fixed_len = 1003, descending = 0}, __closure=0x7fffda7bcbf0)
          at /mariadb/10.8/storage/innobase/dict/dict0mem.cc:1209
      1209					{ return o.col->ind == c.ind(); });
      

      One column has been instantly dropped, and some columns have been reordered. I tried to guess a test case, but I failed.

      diff --git a/mysql-test/suite/innodb/t/instant_alter_crash.test b/mysql-test/suite/innodb/t/instant_alter_crash.test
      index 43db8f619f3..75f26a80559 100644
      --- a/mysql-test/suite/innodb/t/instant_alter_crash.test
      +++ b/mysql-test/suite/innodb/t/instant_alter_crash.test
      @@ -184,6 +184,12 @@ CREATE TABLE t3(id INT PRIMARY KEY, c2 INT, v2 INT AS(c2) VIRTUAL, UNIQUE(v2))
       ENGINE=InnoDB;
       INSERT INTO t3 SET id=1,c2=1;
       
      +CREATE TABLE t4(id INT PRIMARY KEY,c2 INT,c3 INT,c4 INT,c5 INT,c6 INT,c7 INT)
      +ENGINE=InnoDB;
      +INSERT INTO t4 SET id=1;
      +ALTER TABLE t4 DROP c4, MODIFY c5 INT AFTER c2, ADD (c8 INT, c9 INT),
      +ALGORITHM=INSTANT;
      +
       SET DEBUG_SYNC='innodb_alter_inplace_before_commit SIGNAL ddl WAIT_FOR ever';
       --send
       ALTER TABLE t3 ADD COLUMN c3 TEXT NOT NULL DEFAULT 'sic transit gloria mundi';
      @@ -198,10 +204,12 @@ INSERT INTO t1 VALUES(0,0);
       disconnect ddl;
       --source include/start_mysqld.inc
       
      +SELECT * FROM t4;
       SHOW CREATE TABLE t1;
       SHOW CREATE TABLE t2;
       SHOW CREATE TABLE t3;
      -DROP TABLE t1,t2,t3;
      +SHOW CREATE TABLE t4;
      +DROP TABLE t1,t2,t3,t4;
       
       --remove_files_wildcard $MYSQLD_DATADIR/test #sql*.frm
       --list_files $MYSQLD_DATADIR/test
      

      The following should fix the failure by preventing the out-of-bounds access:

      diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc
      index 8d53f646131..37cf7dc687f 100644
      --- a/storage/innobase/dict/dict0mem.cc
      +++ b/storage/innobase/dict/dict0mem.cc
      @@ -1177,6 +1177,8 @@ inline bool dict_index_t::reconstruct_fields()
       {
       	DBUG_ASSERT(is_primary());
       
      +	const auto old_n_fields{n_fields};
      +
       	n_fields = (n_fields + table->instant->n_dropped)
       		& dict_index_t::MAX_N_FIELDS;
       	n_def = (n_def + table->instant->n_dropped)
      @@ -1204,11 +1206,11 @@ inline bool dict_index_t::reconstruct_fields()
       		} else {
       			DBUG_ASSERT(!c.is_not_null());
       			const auto old = std::find_if(
      -				fields + n_first, fields + n_fields,
      +				fields + n_first, fields + old_n_fields,
       				[c](const dict_field_t& o)
       				{ return o.col->ind == c.ind(); });
       
      -			if (old >= fields + n_fields
      +			if (old >= fields + old_n_fields
       			    || old->prefix_len
       			    || old->col != &table->cols[c.ind()]) {
       				return true;
      

      I hope that Matthias Leich can come up with a test case for this.

        Attachments

          Activity

            People

            Assignee:
            marko Marko Mäkelä
            Reporter:
            marko Marko Mäkelä
            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.