mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merged following change from MySQL 5.6 to MariaDB 10.1 XtraDB
including the test case: https://github.com/mysql/mysql-server/commit/520aedfe INNODB: "DATA DIRECTORY" OPTION OF CREATE TABLE FAILS WITH PWRITE() OS ERROR 22 Fix for version mysql-5.6 PROBLEM ======== For version mysql-5.6.27 onwards InnoDB fails to create a table with explicit 'data directory' option when Innodb_flush_method is set to O_DIRECT.While creating link file we get a a pwrite error 22 due to the alignment restrictions imposed by O_DIRECT flag which is being set for the link file created. FIX === Fixed the above issue by making use of file IO functions while creating the link file that wouldn't let the O_DIRECT flag restrictions arise. Reviewed-by: Kevin Lewis <kevin.lewis@oracle.com> Reviewed-by: Shaohua Wang <shaohua.wang@oracle.com> RB: 11387
This commit is contained in:
10
mysql-test/suite/innodb/r/create_isl_with_direct.result
Normal file
10
mysql-test/suite/innodb/r/create_isl_with_direct.result
Normal file
@ -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;
|
1
mysql-test/suite/innodb/t/create_isl_with_direct.opt
Normal file
1
mysql-test/suite/innodb/t/create_isl_with_direct.opt
Normal file
@ -0,0 +1 @@
|
|||||||
|
--innodb_flush_method=O_DIRECT
|
28
mysql-test/suite/innodb/t/create_isl_with_direct.test
Normal file
28
mysql-test/suite/innodb/t/create_isl_with_direct.test
Normal file
@ -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;
|
||||||
|
|
@ -3225,8 +3225,6 @@ fil_create_link_file(
|
|||||||
const char* tablename, /*!< in: tablename */
|
const char* tablename, /*!< in: tablename */
|
||||||
const char* filepath) /*!< in: pathname of tablespace */
|
const char* filepath) /*!< in: pathname of tablespace */
|
||||||
{
|
{
|
||||||
os_file_t file;
|
|
||||||
ibool success;
|
|
||||||
dberr_t err = DB_SUCCESS;
|
dberr_t err = DB_SUCCESS;
|
||||||
char* link_filepath;
|
char* link_filepath;
|
||||||
char* prev_filepath = fil_read_link_file(tablename);
|
char* prev_filepath = fil_read_link_file(tablename);
|
||||||
@ -3245,16 +3243,24 @@ fil_create_link_file(
|
|||||||
|
|
||||||
link_filepath = fil_make_isl_name(tablename);
|
link_filepath = fil_make_isl_name(tablename);
|
||||||
|
|
||||||
/* Note that OS_FILE_READ_WRITE_CACHED used here to avoid
|
/** Check if the file already exists. */
|
||||||
unnecessary errors on O_DIRECT, link files are not really
|
FILE* file = NULL;
|
||||||
a data files. */
|
ibool exists;
|
||||||
file = os_file_create_simple_no_error_handling(
|
os_file_type_t ftype;
|
||||||
innodb_file_data_key, link_filepath,
|
|
||||||
OS_FILE_CREATE, OS_FILE_READ_WRITE_CACHED, &success, 0);
|
|
||||||
|
|
||||||
if (!success) {
|
bool success = os_file_status(link_filepath, &exists, &ftype);
|
||||||
/* The following call will print an error message */
|
|
||||||
ulint error = os_file_get_last_error(true);
|
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);
|
ut_print_timestamp(stderr);
|
||||||
fputs(" InnoDB: Cannot create file ", stderr);
|
fputs(" InnoDB: Cannot create file ", stderr);
|
||||||
@ -3266,10 +3272,8 @@ fil_create_link_file(
|
|||||||
ut_print_filename(stderr, filepath);
|
ut_print_filename(stderr, filepath);
|
||||||
fputs(" already exists.\n", stderr);
|
fputs(" already exists.\n", stderr);
|
||||||
err = DB_TABLESPACE_EXISTS;
|
err = DB_TABLESPACE_EXISTS;
|
||||||
|
|
||||||
} else if (error == OS_FILE_DISK_FULL) {
|
} else if (error == OS_FILE_DISK_FULL) {
|
||||||
err = DB_OUT_OF_FILE_SPACE;
|
err = DB_OUT_OF_FILE_SPACE;
|
||||||
|
|
||||||
} else if (error == OS_FILE_OPERATION_NOT_SUPPORTED) {
|
} else if (error == OS_FILE_OPERATION_NOT_SUPPORTED) {
|
||||||
err = DB_UNSUPPORTED;
|
err = DB_UNSUPPORTED;
|
||||||
} else {
|
} else {
|
||||||
@ -3281,13 +3285,17 @@ fil_create_link_file(
|
|||||||
return(err);
|
return(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!os_file_write(link_filepath, file, filepath, 0,
|
ulint rbytes = fwrite(filepath, 1, strlen(filepath), file);
|
||||||
strlen(filepath))) {
|
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;
|
err = DB_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close the file, we only need it at startup */
|
/* Close the file, we only need it at startup */
|
||||||
os_file_close(file);
|
fclose(file);
|
||||||
|
|
||||||
mem_free(link_filepath);
|
mem_free(link_filepath);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user