diff --git a/mysql-test/suite/innodb/r/create_isl_with_direct.result b/mysql-test/suite/innodb/r/create_isl_with_direct.result new file mode 100644 index 0000000000000..87544e6dcdf3a --- /dev/null +++ b/mysql-test/suite/innodb/r/create_isl_with_direct.result @@ -0,0 +1,10 @@ +SHOW VARIABLES LIKE 'innodb_flush_method'; +Variable_name Value +innodb_flush_method O_DIRECT +CREATE TABLE t1 (x INT) ENGINE=INNODB, DATA DIRECTORY='MYSQL_TMP_DIR'; +# Contents of tmp/test directory containing .ibd file +t1.ibd +# Contents of the 'test' database directory containing .isl and .frm files +t1.frm +t1.isl +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/create_isl_with_direct.opt b/mysql-test/suite/innodb/t/create_isl_with_direct.opt new file mode 100644 index 0000000000000..8f80f02e35914 --- /dev/null +++ b/mysql-test/suite/innodb/t/create_isl_with_direct.opt @@ -0,0 +1 @@ +--innodb_flush_method=O_DIRECT diff --git a/mysql-test/suite/innodb/t/create_isl_with_direct.test b/mysql-test/suite/innodb/t/create_isl_with_direct.test new file mode 100644 index 0000000000000..34ea9c77703c9 --- /dev/null +++ b/mysql-test/suite/innodb/t/create_isl_with_direct.test @@ -0,0 +1,28 @@ +--source include/not_embedded.inc +--source include/have_innodb.inc +--source include/not_windows.inc + +--disable_query_log +CALL mtr.add_suppression("\\[Warning\\] InnoDB: Failed to set O_DIRECT on file ./ibdata1: OPEN: Invalid argument, continuing anyway. O_DIRECT is known to result in 'Invalid argument' on Linux on tmpfs, see MySQL Bug#26662."); + +# The below mtr suppression to avoid failure in solaris platform. +CALL mtr.add_suppression("\\[ERROR\\] InnoDB: Failed to set DIRECTIO_ON on file.*"); +--enable_query_log + +SHOW VARIABLES LIKE 'innodb_flush_method'; + +let MYSQLD_DATADIR=`SELECT @@datadir`; + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR + +# Create a table with explicit data directory option. +EVAL CREATE TABLE t1 (x INT) ENGINE=INNODB, DATA DIRECTORY='$MYSQL_TMP_DIR'; + +--echo # Contents of tmp/test directory containing .ibd file +--list_files $MYSQL_TMP_DIR/test + +--echo # Contents of the 'test' database directory containing .isl and .frm files +--list_files $MYSQLD_DATADIR/test + +DROP TABLE t1; + \ No newline at end of file diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index e77c97ead5b62..9fad34257b831 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -3225,8 +3225,6 @@ fil_create_link_file( const char* tablename, /*!< in: tablename */ const char* filepath) /*!< in: pathname of tablespace */ { - os_file_t file; - ibool success; dberr_t err = DB_SUCCESS; char* link_filepath; char* prev_filepath = fil_read_link_file(tablename); @@ -3245,16 +3243,24 @@ fil_create_link_file( link_filepath = fil_make_isl_name(tablename); - /* Note that OS_FILE_READ_WRITE_CACHED used here to avoid - unnecessary errors on O_DIRECT, link files are not really - a data files. */ - file = os_file_create_simple_no_error_handling( - innodb_file_data_key, link_filepath, - OS_FILE_CREATE, OS_FILE_READ_WRITE_CACHED, &success, 0); + /** Check if the file already exists. */ + FILE* file = NULL; + ibool exists; + os_file_type_t ftype; - if (!success) { - /* The following call will print an error message */ - ulint error = os_file_get_last_error(true); + bool success = os_file_status(link_filepath, &exists, &ftype); + + ulint error = 0; + if (success && !exists) { + file = fopen(link_filepath, "w"); + if (file == NULL) { + /* This call will print its own error message */ + error = os_file_get_last_error(true); + } + } else { + error = OS_FILE_ALREADY_EXISTS; + } + if (error != 0) { ut_print_timestamp(stderr); fputs(" InnoDB: Cannot create file ", stderr); @@ -3266,10 +3272,8 @@ fil_create_link_file( ut_print_filename(stderr, filepath); fputs(" already exists.\n", stderr); err = DB_TABLESPACE_EXISTS; - } else if (error == OS_FILE_DISK_FULL) { err = DB_OUT_OF_FILE_SPACE; - } else if (error == OS_FILE_OPERATION_NOT_SUPPORTED) { err = DB_UNSUPPORTED; } else { @@ -3281,13 +3285,17 @@ fil_create_link_file( return(err); } - if (!os_file_write(link_filepath, file, filepath, 0, - strlen(filepath))) { + ulint rbytes = fwrite(filepath, 1, strlen(filepath), file); + if (rbytes != strlen(filepath)) { + os_file_get_last_error(true); + ib_logf(IB_LOG_LEVEL_ERROR, + "cannot write link file " + "%s",filepath); err = DB_ERROR; } /* Close the file, we only need it at startup */ - os_file_close(file); + fclose(file); mem_free(link_filepath);