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

Table gets fatally corrupted if server crashes during ALTER TABLE, "table doesn't exist" is reported

    XMLWordPrintable

    Details

      Description

      If server crashes when a table is being altered, the table might end up in a half-existing state: table files are in place, the table is present in I_S and SHOW TABLES output, but it cannot be accessed.
      Sometimes the table just completely disappears.

      The provided test case uses an InnoDB table. It is not strictly necessary, the problem is reproducible with MyISAM and Aria too, with InnoDB it just happens considerably faster.
      Depending on timing, the test might show that table files still exist, or that they disappeared too.

      Reproducible on all of MariaDB 5.1-5.5, and on MySQL also.

      Test case:

       
      --source include/have_innodb.inc
       
      --enable_reconnect
      --let $run = 50
      --connect (con1,localhost,root,,)
      --enable_reconnect
       
      --connection default
       
      --delimiter //
      CREATE PROCEDURE pr ()
      BEGIN
              DECLARE i INT DEFAULT 1;
              wl_loop: WHILE i <= 10000 DO
                      ALTER TABLE t1 CHARACTER SET utf8;
                      ALTER TABLE t1 CHARACTER SET latin1;
                      SET i = i + 1;
              END WHILE wl_loop;
      END //
      --delimiter ;
       
      --disable_warnings
      DROP TABLE IF EXISTS t1;
      --enable_warnings
       
      while ($run)
      {
              --connection default
              --append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
      restart
      EOF
              CREATE TABLE t1 (a INT) ENGINE=InnoDB;
       
              --connection con1
              --send CALL pr
       
              --connection default
              --sleep 1
              --shutdown_server 0
              --source include/wait_until_disconnected.inc
              --source include/wait_until_connected_again.inc
       
              --echo # Existing t1* files:
              --list_files $MYSQLTEST_VARDIR/mysqld.1/data/test t1*
              SHOW TABLES;
              SHOW CREATE TABLE t1;
       
              --connection con1
              --error 0,2013
              --reap
              --dec $run
              DROP TABLE t1;
              REPAIR TABLE mysql.proc;
      }
      

      Variants of the failure:

      1. No table files, DROP says there is no table, but CREATE says it already exists:

      # Existing t1* files:
      SHOW TABLES;
      Tables_in_test
      DROP TABLE IF EXISTS t1;
      Warnings:
      Note	1051	Unknown table 't1'
      CREATE TABLE t1 (a INT) ENGINE=InnoDB;
      query 'CREATE TABLE t1 (a INT) ENGINE=InnoDB' failed: 1050: Table '`test`.`t1`' already exists
      

      2. frm file in place, but SHOW CREATE TABLE says the table doesn't exist:

      CREATE TABLE t1 (a INT) ENGINE=InnoDB;
      CALL pr;
      # Existing t1* files:
      t1.frm
      SHOW TABLES;
      Tables_in_test
      t1
      SHOW CREATE TABLE t1;
      query 'SHOW CREATE TABLE t1' failed: 1146: Table 'test.t1' doesn't exist
      

        Attachments

          Issue Links

            Activity

              People

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

                Dates

                Created:
                Updated:
                Resolved:

                  Git Integration