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

Operating system errors in file operations after failed CREATE

Details

    Description

      Note: the test case fails for me every time on a non-debug build, but there is still some concurrency involved in the scenario, so it can be different on other machines. I couldn't so far reproduce the problem on a debug or ASAN-debug build.

      --source include/have_innodb.inc
       
      CREATE SEQUENCE s1 ENGINE=InnoDB;
      CREATE TABLE t1 (i INT) ENGINE=InnoDB;
       
      --connect (con1,localhost,root,,test)
       
      BEGIN;
      SELECT * FROM mysql.innodb_table_stats;
       
      --connection default
      CREATE SEQUENCE s2 ENGINE=InnoDB;
       
      --connection con1
      --send
        SELECT * FROM INFORMATION_SCHEMA.CHECK_CONSTRAINTS;
       
      --connection default
      FLUSH TABLES;
       
      --connection con1
      --reap
       
      --connection default
       
      --error ER_TABLE_EXISTS_ERROR,ER_TABLESPACE_EXISTS
      CREATE TABLE s2 LIKE t1;
      --error ER_TABLE_EXISTS_ERROR
      CREATE TABLE s2 LIKE s1;
       
      --connection con1
      SELECT * FROM t1;
       
      --connection default
      SET lock_wait_timeout= 1;
      --error ER_LOCK_WAIT_TIMEOUT
      ALTER TABLE t1 ADD COLUMN a INTEGER;
       
      # Cleanup
      --disconnect con1
      DROP SEQUENCE s1, s2;
      DROP TABLE t1;
      

      10.3 RelWithDebInfo babb000a36f7

      2018-11-28 10:37:14 9 [ERROR] InnoDB: Operating system error number 17 in a file operation.
      2018-11-28 10:37:14 9 [ERROR] InnoDB: Error number 17 means 'File exists'
      2018-11-28 10:37:14 9 [Note] InnoDB: Some operating system error numbers are described at https://mariadb.com/kb/en/library/operating-system-error-codes/
      2018-11-28 10:37:14 9 [Note] InnoDB: The file './test/s2.ibd' already exists though the corresponding table did not exist in the InnoDB data dictionary. You can resolve the problem by removing the file.
      2018-11-28 10:37:14 9 [ERROR] InnoDB: Cannot create file './test/s2.ibd'
      2018-11-28 10:37:14 9 [ERROR] InnoDB: Failed to find tablespace for table `test`.`s2` in the cache. Attempting to load the tablespace with space id 7
      2018-11-28 10:37:14 9 [ERROR] InnoDB: Refusing to load './test/s2.ibd' (id=9, flags=0x21); dictionary contains id=7, flags=0x21
      2018-11-28 10:37:14 9 [ERROR] InnoDB: Operating system error number 2 in a file operation.
      2018-11-28 10:37:14 9 [ERROR] InnoDB: The error means the system cannot find the path specified.
      2018-11-28 10:37:14 9 [ERROR] InnoDB: Could not find a valid tablespace file for ``test`.`s2``. Please refer to http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting-datadict.html for how to resolve the issue.
      2018-11-28 10:37:14 9 [Note] InnoDB: Deleting ./test/s2.ibd
      2018-11-28 10:37:14 0 [ERROR] InnoDB: Operating system error number 2 in a file operation.
      2018-11-28 10:37:14 0 [ERROR] InnoDB: The error means the system cannot find the path specified.
      2018-11-28 10:37:14 0 [ERROR] InnoDB: File ./test/s2.ibd: 'open' returned OS error 71.
      2018-11-28 10:37:14 0x7f8dae7fc700  InnoDB: Assertion failure in file /data/src/10.3/storage/innobase/fil/fil0fil.cc line 671
      InnoDB: Failing assertion: success
       
      #5  0x000055ace8148000 in ut_dbg_assertion_failed (expr=expr@entry=0x55ace8a52d29 "success", file=file@entry=0x55ace8a74828 "/data/src/10.3/storage/innobase/fil/fil0fil.cc", line=line@entry=671) at /data/src/10.3/storage/innobase/ut/ut0dbg.cc:60
      #6  0x000055ace87c8448 in fil_node_open_file (node=node@entry=0x7f8d68073de0) at /data/src/10.3/storage/innobase/fil/fil0fil.cc:671
      #7  0x000055ace87c898f in fil_node_prepare_for_io (node=node@entry=0x7f8d68073de0, space=space@entry=0x7f8d680907e0) at /data/src/10.3/storage/innobase/fil/fil0fil.cc:4080
      #8  0x000055ace87c9f13 in fil_io (type=..., sync=sync@entry=false, page_id=..., page_size=..., byte_offset=byte_offset@entry=0, len=16384, buf=0x7f8db6670000, message=0x7f8db6150a68, ignore_missing_space=false) at /data/src/10.3/storage/innobase/fil/fil0fil.cc:4335
      #9  0x000055ace876c039 in buf_dblwr_write_block_to_datafile (bpage=0x7f8db6150a68, sync=sync@entry=false) at /data/src/10.3/storage/innobase/buf/buf0dblwr.cc:929
      #10 0x000055ace876dd8d in buf_dblwr_flush_buffered_writes () at /data/src/10.3/storage/innobase/buf/buf0dblwr.cc:1075
      #11 0x000055ace87784cf in buf_flush_end (flush_type=<optimized out>, buf_pool=0x55aceb005f90) at /data/src/10.3/storage/innobase/buf/buf0flu.cc:1972
      #12 buf_flush_do_batch (buf_pool=<optimized out>, type=<optimized out>, min_n=<optimized out>, lsn_limit=<optimized out>, n=<optimized out>) at /data/src/10.3/storage/innobase/buf/buf0flu.cc:2041
      #13 0x000055ace87788db in buf_flush_lists (min_n=200, lsn_limit=lsn_limit@entry=18446744073709551615, n_processed=0x7f8dae7fbc90) at /data/src/10.3/storage/innobase/buf/buf0flu.cc:2145
      #14 0x000055ace877bbb7 in buf_flush_page_cleaner_coordinator () at /data/src/10.3/storage/innobase/buf/buf0flu.cc:3297
      #15 0x00007f8dc2601494 in start_thread (arg=0x7f8dae7fc700) at pthread_create.c:333
      #16 0x00007f8dc0c0293f in clone () from /lib/x86_64-linux-gnu/libc.so.6
      

      The scenario is not applicable to 10.2 because sequences are involved.

      Attachments

        Issue Links

          Activity

            With the following tentative follow-up fix to MDEV-17816, the test no longer crashes for me:

            diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
            index 9725375ebbb..80fa8e6d7dd 100644
            --- a/storage/innobase/handler/ha_innodb.cc
            +++ b/storage/innobase/handler/ha_innodb.cc
            @@ -12358,9 +12358,11 @@ int create_table_info_t::create_table(bool create_fk)
             			so that rollback can possibly rename back a table
             			that could have been renamed before
             			the failed creation. */
            -			m_trx->error_state = DB_SUCCESS;
            -			row_drop_table_for_mysql(m_table_name, m_trx,
            -						 SQLCOM_TRUNCATE);
            +			if (m_table->cached) {
            +				m_trx->error_state = DB_SUCCESS;
            +				row_drop_table_for_mysql(m_table_name, m_trx,
            +							 SQLCOM_TRUNCATE);
            +			}
             			trx_rollback_to_savepoint(m_trx, NULL);
             
             			m_trx->error_state = DB_SUCCESS;
            @@ -12590,9 +12592,11 @@ ha_innobase::create(
             		/* Drop the being-created table before rollback,
             		so that rollback can possibly rename back a table
             		that could have been renamed before the failed creation. */
            -		trx->error_state = DB_SUCCESS;
            -		row_drop_table_for_mysql(info.table_name(), trx,
            -					 SQLCOM_TRUNCATE, true);
            +		if (info.table() && info.table()->cached) {
            +			trx->error_state = DB_SUCCESS;
            +			row_drop_table_for_mysql(info.table_name(), trx,
            +						 SQLCOM_TRUNCATE, true);
            +		}
             		trx_rollback_for_mysql(trx);
             		row_mysql_unlock_data_dictionary(trx);
             		if (own_trx) {
            diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
            index 7bec858b5af..cb3de206890 100644
            --- a/storage/innobase/handler/ha_innodb.h
            +++ b/storage/innobase/handler/ha_innodb.h
            @@ -729,6 +729,9 @@ class create_table_info_t
             	const char* table_name() const
             	{ return(m_table_name); }
             
            +	/** @return the created table */
            +	const dict_table_t* table() const { return m_table; }
            +
             	THD* thd() const
             	{ return(m_thd); }
             
            

            marko Marko Mäkelä added a comment - With the following tentative follow-up fix to MDEV-17816 , the test no longer crashes for me: diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 9725375ebbb..80fa8e6d7dd 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -12358,9 +12358,11 @@ int create_table_info_t::create_table(bool create_fk) so that rollback can possibly rename back a table that could have been renamed before the failed creation. */ - m_trx->error_state = DB_SUCCESS; - row_drop_table_for_mysql(m_table_name, m_trx, - SQLCOM_TRUNCATE); + if (m_table->cached) { + m_trx->error_state = DB_SUCCESS; + row_drop_table_for_mysql(m_table_name, m_trx, + SQLCOM_TRUNCATE); + } trx_rollback_to_savepoint(m_trx, NULL); m_trx->error_state = DB_SUCCESS; @@ -12590,9 +12592,11 @@ ha_innobase::create( /* Drop the being-created table before rollback, so that rollback can possibly rename back a table that could have been renamed before the failed creation. */ - trx->error_state = DB_SUCCESS; - row_drop_table_for_mysql(info.table_name(), trx, - SQLCOM_TRUNCATE, true); + if (info.table() && info.table()->cached) { + trx->error_state = DB_SUCCESS; + row_drop_table_for_mysql(info.table_name(), trx, + SQLCOM_TRUNCATE, true); + } trx_rollback_for_mysql(trx); row_mysql_unlock_data_dictionary(trx); if (own_trx) { diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 7bec858b5af..cb3de206890 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -729,6 +729,9 @@ class create_table_info_t const char* table_name() const { return(m_table_name); } + /** @return the created table */ + const dict_table_t* table() const { return m_table; } + THD* thd() const { return(m_thd); }

            The problem was that in MDEV-17816, the error handling of CREATE TABLE was changed so that the table by that name would be dropped. This is obviously wrong if such a table already existed in InnoDB.

            The solution is to drop the incompletely created table only if the table was actually created.

            A proper solution would be to write undo log for table creation, so that normal rollback would take care of dropping the table.

            marko Marko Mäkelä added a comment - The problem was that in MDEV-17816 , the error handling of CREATE TABLE was changed so that the table by that name would be dropped. This is obviously wrong if such a table already existed in InnoDB. The solution is to drop the incompletely created table only if the table was actually created. A proper solution would be to write undo log for table creation, so that normal rollback would take care of dropping the table.

            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.