mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
MDEV-6070: FusionIO: Failure to create a table with ATOMIC_WRITES
option leaves the database in inconsistent state, Analysis: Problem was that atomic writes variable had incorrect type on same places leading to fact that e.g. OFF option was not regognized. Furthermore, some error check code was missing from both InnoDB and XtraDB engines. Finally, when table is created we have already created the .ibd file and if we can't set atomic writes it stays there. Fix: Fix atomic writes variable type to ulint as it should be. Fix: Add proper error code checking on os errors on both InnoDB and XtraDB Fix: Remove the .idb file when atomic writes can't be enabled to a new table.
This commit is contained in:
parent
13c73c31c3
commit
2f46e5b9fc
4 changed files with 146 additions and 39 deletions
|
@ -745,7 +745,7 @@ fil_node_open_file(
|
|||
ulint space_id;
|
||||
ulint flags=0;
|
||||
ulint page_size;
|
||||
ibool atomic_writes=FALSE;
|
||||
ulint atomic_writes=0;
|
||||
|
||||
ut_ad(mutex_own(&(system->mutex)));
|
||||
ut_a(node->n_pending == 0);
|
||||
|
@ -3425,7 +3425,7 @@ fil_create_new_single_table_tablespace(
|
|||
/* TRUE if a table is created with CREATE TEMPORARY TABLE */
|
||||
bool is_temp = !!(flags2 & DICT_TF2_TEMPORARY);
|
||||
bool has_data_dir = FSP_FLAGS_HAS_DATA_DIR(flags);
|
||||
bool atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(flags);
|
||||
ulint atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(flags);
|
||||
|
||||
ut_a(space_id > 0);
|
||||
ut_ad(!srv_read_only_mode);
|
||||
|
@ -3720,7 +3720,7 @@ fil_open_single_table_tablespace(
|
|||
fsp_open_info remote;
|
||||
ulint tablespaces_found = 0;
|
||||
ulint valid_tablespaces_found = 0;
|
||||
ibool atomic_writes = FALSE;
|
||||
ulint atomic_writes = 0;
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
ut_ad(!fix_dict || rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
|
||||
|
|
|
@ -399,9 +399,8 @@ os_file_set_atomic_writes(
|
|||
|
||||
if (ioctl(file, DFS_IOCTL_ATOMIC_WRITE_SET, &atomic_option)) {
|
||||
|
||||
fprintf(stderr, "InnoDB: Error: trying to enable atomic writes on "
|
||||
"file %s on non-supported platform! Please restart with "
|
||||
"innodb_use_atomic_writes disabled.\n", name);
|
||||
fprintf(stderr, "InnoDB: Warning:Trying to enable atomic writes on "
|
||||
"file %s on non-supported platform!\n", name);
|
||||
os_file_handle_error_no_exit(name, "ioctl", FALSE, __FILE__, __LINE__);
|
||||
return(FALSE);
|
||||
}
|
||||
|
@ -409,8 +408,7 @@ os_file_set_atomic_writes(
|
|||
return(TRUE);
|
||||
#else
|
||||
fprintf(stderr, "InnoDB: Error: trying to enable atomic writes on "
|
||||
"non-supported platform! Please restart with "
|
||||
"innodb_use_atomic_writes disabled.\n");
|
||||
"file %s on non-supported platform!\n", name);
|
||||
return(FALSE);
|
||||
#endif
|
||||
}
|
||||
|
@ -561,6 +559,19 @@ os_file_get_last_error_low(
|
|||
"InnoDB: because of either a thread exit"
|
||||
" or an application request.\n"
|
||||
"InnoDB: Retry attempt is made.\n");
|
||||
} else if (err == ECANCELED || err == ENOTTY) {
|
||||
if (strerror(err) != NULL) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error number %d"
|
||||
" means '%s'.\n",
|
||||
err, strerror(err));
|
||||
}
|
||||
|
||||
if(srv_use_atomic_writes) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error trying to enable atomic writes on "
|
||||
"non-supported destination!\n");
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Some operating system error numbers"
|
||||
|
@ -620,11 +631,14 @@ os_file_get_last_error_low(
|
|||
fprintf(stderr,
|
||||
"InnoDB: The error means mysqld does not have"
|
||||
" the access rights to\n"
|
||||
"InnoDECANCELEDB: the directory.\n");
|
||||
} else if (err == ECANCELED) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Operation canceled (%d):%s\n",
|
||||
err, strerror(err));
|
||||
"InnoDB: the directory.\n");
|
||||
} else if (err == ECANCELED || err == ENOTTY) {
|
||||
if (strerror(err) != NULL) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error number %d"
|
||||
" means '%s'.\n",
|
||||
err, strerror(err));
|
||||
}
|
||||
|
||||
if(srv_use_atomic_writes) {
|
||||
fprintf(stderr,
|
||||
|
@ -663,6 +677,7 @@ os_file_get_last_error_low(
|
|||
case EISDIR:
|
||||
return(OS_FILE_PATH_ERROR);
|
||||
case ECANCELED:
|
||||
case ENOTTY:
|
||||
return(OS_FILE_OPERATION_NOT_SUPPORTED);
|
||||
case EAGAIN:
|
||||
if (srv_use_native_aio) {
|
||||
|
@ -1521,13 +1536,21 @@ os_file_create_simple_no_error_handling_func(
|
|||
attributes,
|
||||
NULL); // No template file
|
||||
|
||||
/* If we have proper file handle and atomic writes should be used,
|
||||
try to set atomic writes and if that fails when creating a new
|
||||
table, produce a error. If atomic writes are used on existing
|
||||
file, ignore error and use traditional writes for that file */
|
||||
if (file != INVALID_HANDLE_VALUE
|
||||
&& (awrites == ATOMIC_WRITES_ON ||
|
||||
(srv_use_atomic_writes && awrites == ATOMIC_WRITES_DEFAULT))
|
||||
&& !os_file_set_atomic_writes(name, file)) {
|
||||
CloseHandle(file);
|
||||
if (create_mode == OS_FILE_CREATE) {
|
||||
fprintf(stderr, "InnoDB: Error: Can't create file using atomic writes\n");
|
||||
CloseHandle(file);
|
||||
os_file_delete_if_exists_func(name);
|
||||
*success = FALSE;
|
||||
file = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
*success = (file != INVALID_HANDLE_VALUE);
|
||||
|
@ -1590,13 +1613,21 @@ os_file_create_simple_no_error_handling_func(
|
|||
}
|
||||
#endif /* USE_FILE_LOCK */
|
||||
|
||||
/* If we have proper file handle and atomic writes should be used,
|
||||
try to set atomic writes and if that fails when creating a new
|
||||
table, produce a error. If atomic writes are used on existing
|
||||
file, ignore error and use traditional writes for that file */
|
||||
if (file != -1
|
||||
&& (awrites == ATOMIC_WRITES_ON ||
|
||||
(srv_use_atomic_writes && awrites == ATOMIC_WRITES_DEFAULT))
|
||||
&& !os_file_set_atomic_writes(name, file)) {
|
||||
*success = FALSE;
|
||||
close(file);
|
||||
file = -1;
|
||||
if (create_mode == OS_FILE_CREATE) {
|
||||
fprintf(stderr, "InnoDB: Error: Can't create file using atomic writes\n");
|
||||
close(file);
|
||||
os_file_delete_if_exists_func(name);
|
||||
*success = FALSE;
|
||||
file = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1836,13 +1867,21 @@ os_file_create_func(
|
|||
|
||||
} while (retry);
|
||||
|
||||
/* If we have proper file handle and atomic writes should be used,
|
||||
try to set atomic writes and if that fails when creating a new
|
||||
table, produce a error. If atomic writes are used on existing
|
||||
file, ignore error and use traditional writes for that file */
|
||||
if (file != INVALID_HANDLE_VALUE
|
||||
&& (awrites == ATOMIC_WRITES_ON ||
|
||||
(srv_use_atomic_writes && awrites == ATOMIC_WRITES_DEFAULT))
|
||||
&& !os_file_set_atomic_writes(name, file)) {
|
||||
CloseHandle(file);
|
||||
if (create_mode == OS_FILE_CREATE) {
|
||||
fprintf(stderr, "InnoDB: Error: Can't create file using atomic writes\n");
|
||||
CloseHandle(file);
|
||||
os_file_delete_if_exists_func(name);
|
||||
*success = FALSE;
|
||||
file = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
#else /* __WIN__ */
|
||||
int create_flag;
|
||||
|
@ -1972,13 +2011,21 @@ os_file_create_func(
|
|||
}
|
||||
#endif /* USE_FILE_LOCK */
|
||||
|
||||
/* If we have proper file handle and atomic writes should be used,
|
||||
try to set atomic writes and if that fails when creating a new
|
||||
table, produce a error. If atomic writes are used on existing
|
||||
file, ignore error and use traditional writes for that file */
|
||||
if (file != -1
|
||||
&& (awrites == ATOMIC_WRITES_ON ||
|
||||
(srv_use_atomic_writes && awrites == ATOMIC_WRITES_DEFAULT))
|
||||
&& !os_file_set_atomic_writes(name, file)) {
|
||||
*success = FALSE;
|
||||
close(file);
|
||||
file = -1;
|
||||
if (create_mode == OS_FILE_CREATE) {
|
||||
fprintf(stderr, "InnoDB: Error: Can't create file using atomic writes\n");
|
||||
close(file);
|
||||
os_file_delete_if_exists_func(name);
|
||||
*success = FALSE;
|
||||
file = -1;
|
||||
}
|
||||
}
|
||||
#endif /* __WIN__ */
|
||||
|
||||
|
|
|
@ -746,7 +746,7 @@ fil_node_open_file(
|
|||
ulint space_id;
|
||||
ulint flags=0;
|
||||
ulint page_size;
|
||||
ibool atomic_writes=FALSE;
|
||||
ulint atomic_writes=0;
|
||||
|
||||
ut_ad(mutex_own(&(system->mutex)));
|
||||
ut_a(node->n_pending == 0);
|
||||
|
@ -3288,6 +3288,8 @@ fil_create_link_file(
|
|||
} 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 {
|
||||
err = DB_ERROR;
|
||||
}
|
||||
|
@ -3448,7 +3450,7 @@ fil_create_new_single_table_tablespace(
|
|||
/* TRUE if a table is created with CREATE TEMPORARY TABLE */
|
||||
bool is_temp = !!(flags2 & DICT_TF2_TEMPORARY);
|
||||
bool has_data_dir = FSP_FLAGS_HAS_DATA_DIR(flags);
|
||||
bool atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(flags);
|
||||
ulint atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(flags);
|
||||
|
||||
ut_a(space_id > 0);
|
||||
ut_ad(!srv_read_only_mode);
|
||||
|
@ -3509,6 +3511,11 @@ fil_create_new_single_table_tablespace(
|
|||
goto error_exit_3;
|
||||
}
|
||||
|
||||
if (error == OS_FILE_OPERATION_NOT_SUPPORTED) {
|
||||
err = DB_UNSUPPORTED;
|
||||
goto error_exit_3;
|
||||
}
|
||||
|
||||
if (error == OS_FILE_DISK_FULL) {
|
||||
err = DB_OUT_OF_FILE_SPACE;
|
||||
goto error_exit_3;
|
||||
|
@ -3735,7 +3742,7 @@ fil_open_single_table_tablespace(
|
|||
fsp_open_info remote;
|
||||
ulint tablespaces_found = 0;
|
||||
ulint valid_tablespaces_found = 0;
|
||||
ibool atomic_writes = FALSE;
|
||||
ulint atomic_writes = 0;
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
ut_ad(!fix_dict || rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
|
||||
|
@ -3746,6 +3753,8 @@ fil_open_single_table_tablespace(
|
|||
return(DB_CORRUPTION);
|
||||
}
|
||||
|
||||
atomic_writes = fsp_flags_get_atomic_writes(flags);
|
||||
|
||||
/* If the tablespace was relocated, we do not
|
||||
compare the DATA_DIR flag */
|
||||
ulint mod_flags = flags & ~FSP_FLAGS_MASK_DATA_DIR;
|
||||
|
|
|
@ -628,10 +628,13 @@ os_file_get_last_error_low(
|
|||
"InnoDB: because of either a thread exit"
|
||||
" or an application request.\n"
|
||||
"InnoDB: Retry attempt is made.\n");
|
||||
} else if (err == ECANCELED) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Operation canceled (%d):%s\n",
|
||||
err, strerror(err));
|
||||
} else if (err == ECANCELED || err == ENOTTY) {
|
||||
if (strerror(err) != NULL) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error number %d"
|
||||
" means '%s'.\n",
|
||||
err, strerror(err));
|
||||
}
|
||||
|
||||
if(srv_use_atomic_writes) {
|
||||
fprintf(stderr,
|
||||
|
@ -698,6 +701,20 @@ os_file_get_last_error_low(
|
|||
"InnoDB: The error means mysqld does not have"
|
||||
" the access rights to\n"
|
||||
"InnoDB: the directory.\n");
|
||||
} else if (err == ECANCELED || err == ENOTTY) {
|
||||
if (strerror(err) != NULL) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error number %d"
|
||||
" means '%s'.\n",
|
||||
err, strerror(err));
|
||||
}
|
||||
|
||||
|
||||
if(srv_use_atomic_writes) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error trying to enable atomic writes on "
|
||||
"non-supported destination!\n");
|
||||
}
|
||||
} else {
|
||||
if (strerror(err) != NULL) {
|
||||
fprintf(stderr,
|
||||
|
@ -735,6 +752,7 @@ os_file_get_last_error_low(
|
|||
}
|
||||
break;
|
||||
case ECANCELED:
|
||||
case ENOTTY:
|
||||
return(OS_FILE_OPERATION_NOT_SUPPORTED);
|
||||
case EINTR:
|
||||
if (srv_use_native_aio) {
|
||||
|
@ -1591,13 +1609,21 @@ os_file_create_simple_no_error_handling_func(
|
|||
attributes,
|
||||
NULL); // No template file
|
||||
|
||||
/* If we have proper file handle and atomic writes should be used,
|
||||
try to set atomic writes and if that fails when creating a new
|
||||
table, produce a error. If atomic writes are used on existing
|
||||
file, ignore error and use traditional writes for that file */
|
||||
if (file != INVALID_HANDLE_VALUE
|
||||
&& (awrites == ATOMIC_WRITES_ON ||
|
||||
(srv_use_atomic_writes && awrites == ATOMIC_WRITES_DEFAULT))
|
||||
&& !os_file_set_atomic_writes(name, file)) {
|
||||
CloseHandle(file);
|
||||
if (create_mode == OS_FILE_CREATE) {
|
||||
fprintf(stderr, "InnoDB: Error: Can't create file using atomic writes\n");
|
||||
CloseHandle(file);
|
||||
os_file_delete_if_exists_func(name);
|
||||
*success = FALSE;
|
||||
file = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
*success = (file != INVALID_HANDLE_VALUE);
|
||||
|
@ -1660,13 +1686,21 @@ os_file_create_simple_no_error_handling_func(
|
|||
}
|
||||
#endif /* USE_FILE_LOCK */
|
||||
|
||||
/* If we have proper file handle and atomic writes should be used,
|
||||
try to set atomic writes and if that fails when creating a new
|
||||
table, produce a error. If atomic writes are used on existing
|
||||
file, ignore error and use traditional writes for that file */
|
||||
if (file != -1
|
||||
&& (awrites == ATOMIC_WRITES_ON ||
|
||||
(srv_use_atomic_writes && awrites == ATOMIC_WRITES_DEFAULT))
|
||||
&& !os_file_set_atomic_writes(name, file)) {
|
||||
*success = FALSE;
|
||||
close(file);
|
||||
file = -1;
|
||||
if (create_mode == OS_FILE_CREATE) {
|
||||
fprintf(stderr, "InnoDB: Error: Can't create file using atomic writes\n");
|
||||
close(file);
|
||||
os_file_delete_if_exists_func(name);
|
||||
*success = FALSE;
|
||||
file = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __WIN__ */
|
||||
|
@ -1752,15 +1786,16 @@ os_file_set_atomic_writes(
|
|||
|
||||
if (ioctl(file, DFS_IOCTL_ATOMIC_WRITE_SET, &atomic_option)) {
|
||||
|
||||
fprintf(stderr, "InnoDB: Warning:Trying to enable atomic writes on "
|
||||
"file %s on non-supported platform!\n", name);
|
||||
os_file_handle_error_no_exit(name, "ioctl(DFS_IOCTL_ATOMIC_WRITE_SET)", FALSE, __FILE__, __LINE__);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
#else
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"trying to enable atomic writes on non-supported platform! "
|
||||
"Please restart with innodb_use_atomic_writes disabled.\n");
|
||||
fprintf(stderr, "InnoDB: Error: trying to enable atomic writes on "
|
||||
"file %s on non-supported platform!\n", name);
|
||||
return(FALSE);
|
||||
#endif
|
||||
}
|
||||
|
@ -1951,13 +1986,21 @@ os_file_create_func(
|
|||
|
||||
} while (retry);
|
||||
|
||||
/* If we have proper file handle and atomic writes should be used,
|
||||
try to set atomic writes and if that fails when creating a new
|
||||
table, produce a error. If atomic writes are used on existing
|
||||
file, ignore error and use traditional writes for that file */
|
||||
if (file != INVALID_HANDLE_VALUE
|
||||
&& (awrites == ATOMIC_WRITES_ON ||
|
||||
(srv_use_atomic_writes && awrites == ATOMIC_WRITES_DEFAULT))
|
||||
&& !os_file_set_atomic_writes(name, file)) {
|
||||
CloseHandle(file);
|
||||
if (create_mode == OS_FILE_CREATE) {
|
||||
fprintf(stderr, "InnoDB: Error: Can't create file using atomic writes\n");
|
||||
CloseHandle(file);
|
||||
os_file_delete_if_exists_func(name);
|
||||
*success = FALSE;
|
||||
file = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* __WIN__ */
|
||||
|
@ -2090,13 +2133,21 @@ os_file_create_func(
|
|||
}
|
||||
#endif /* USE_FILE_LOCK */
|
||||
|
||||
/* If we have proper file handle and atomic writes should be used,
|
||||
try to set atomic writes and if that fails when creating a new
|
||||
table, produce a error. If atomic writes are used on existing
|
||||
file, ignore error and use traditional writes for that file */
|
||||
if (file != -1
|
||||
&& (awrites == ATOMIC_WRITES_ON ||
|
||||
(srv_use_atomic_writes && awrites == ATOMIC_WRITES_DEFAULT))
|
||||
&& !os_file_set_atomic_writes(name, file)) {
|
||||
*success = FALSE;
|
||||
close(file);
|
||||
file = -1;
|
||||
if (create_mode == OS_FILE_CREATE) {
|
||||
fprintf(stderr, "InnoDB: Error: Can't create file using atomic writes\n");
|
||||
close(file);
|
||||
os_file_delete_if_exists_func(name);
|
||||
*success = FALSE;
|
||||
file = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue