summaryrefslogtreecommitdiff
path: root/storage/innobase/os
diff options
context:
space:
mode:
authorunknown <tsmith@siva.hindu.god>2007-04-18 19:53:28 -0600
committerunknown <tsmith@siva.hindu.god>2007-04-18 19:53:28 -0600
commit619c11cbe29689792231f6b3f7a553b8b4598102 (patch)
tree88c526ef1ea9dc9e21869a6d5bc725d57c86b924 /storage/innobase/os
parent4177856a56bae216184595f5c18987e2abe31957 (diff)
downloadmariadb-git-619c11cbe29689792231f6b3f7a553b8b4598102.tar.gz
Applied innodb-5.1-ss1404 snapshot
Fixes: - Bug #26662: mysqld assertion when creating temporary (InnoDB) table on a tmpfs filesystem Fix by not open(2)ing with O_DIRECT but rather calling fcntl(2) to set this flag immediately after open(2)ing. This way an error caused by O_DIRECT not being supported can easily be ignored. - Bug #23313: AUTO_INCREMENT=# not reported back for InnoDB tables - Bug #21404: AUTO_INCREMENT value reset when Adding FKEY (or ALTER?) Report the current value of the AUTO_INCREMENT counter to MySQL. mysql-test/r/innodb.result: Applied innodb-5.1-ss1404 snapshot Revision r1404: Report the current value of the AUTO_INCREMENT counter to MySQL. (Bug #23313, Bug #21404) ha_innobase::update_create_info(): New function, to report the auto_increment_value. mysql-test/t/innodb.test: Applied innodb-5.1-ss1404 snapshot Revision r1404: Report the current value of the AUTO_INCREMENT counter to MySQL. (Bug #23313, Bug #21404) ha_innobase::update_create_info(): New function, to report the auto_increment_value. storage/innobase/handler/ha_innodb.cc: Applied innodb-5.1-ss1404 snapshot Revision r1404: Report the current value of the AUTO_INCREMENT counter to MySQL. (Bug #23313, Bug #21404) ha_innobase::update_create_info(): New function, to report the auto_increment_value. storage/innobase/handler/ha_innodb.h: Applied innodb-5.1-ss1404 snapshot Revision r1404: Report the current value of the AUTO_INCREMENT counter to MySQL. (Bug #23313, Bug #21404) ha_innobase::update_create_info(): New function, to report the auto_increment_value. storage/innobase/os/os0file.c: Applied innodb-5.1-ss1404 snapshot Revision r1395: * Fix Bug#26662 by not open(2)ing with O_DIRECT but rather calling fcntl(2) to set this flag immediately after open(2)ing. This way an error caused by O_DIRECT not being supported can easily be ignored. * Add support for skipping the OS caching on Solaris by calling directio() instead of fcntl(). Approved by: Heikki Revision r1391: Merge the bodies of os_file_handle_error() and os_file_handle_error_no_exit() into a generic function which is called from both os_file_handle_error() and os_file_handle_error_no_exit() Approved by: Marko storage/innobase/plug.in: Applied innodb-5.1-ss1404 snapshot Revision r1395: * Fix Bug#26662 by not open(2)ing with O_DIRECT but rather calling fcntl(2) to set this flag immediately after open(2)ing. This way an error caused by O_DIRECT not being supported can easily be ignored. * Add support for skipping the OS caching on Solaris by calling directio() instead of fcntl(). Approved by: Heikki
Diffstat (limited to 'storage/innobase/os')
-rw-r--r--storage/innobase/os/os0file.c211
1 files changed, 115 insertions, 96 deletions
diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c
index 60ba941dbbf..c18ba047d4e 100644
--- a/storage/innobase/os/os0file.c
+++ b/storage/innobase/os/os0file.c
@@ -318,7 +318,7 @@ os_file_get_last_error(
fflush(stderr);
- if (err == ENOSPC ) {
+ if (err == ENOSPC) {
return(OS_FILE_DISK_FULL);
#ifdef POSIX_ASYNC_IO
} else if (err == EAGAIN) {
@@ -337,15 +337,20 @@ os_file_get_last_error(
}
/********************************************************************
-Does error handling when a file operation fails. */
+Does error handling when a file operation fails.
+Conditionally exits (calling exit(3)) based on should_exit value and the
+error type */
+
static
ibool
-os_file_handle_error(
-/*=================*/
- /* out: TRUE if we should retry the
- operation */
- const char* name, /* in: name of a file or NULL */
- const char* operation)/* in: operation */
+os_file_handle_error_cond_exit(
+/*===========================*/
+ /* out: TRUE if we should retry the
+ operation */
+ const char* name, /* in: name of a file or NULL */
+ const char* operation, /* in: operation */
+ ibool should_exit) /* in: call exit(3) if unknown error
+ and this parameter is TRUE */
{
ulint err;
@@ -376,11 +381,9 @@ os_file_handle_error(
fflush(stderr);
return(FALSE);
-
} else if (err == OS_FILE_AIO_RESOURCES_RESERVED) {
return(TRUE);
-
} else if (err == OS_FILE_ALREADY_EXISTS
|| err == OS_FILE_PATH_ERROR) {
@@ -392,16 +395,49 @@ os_file_handle_error(
fprintf(stderr, "InnoDB: File operation call: '%s'.\n",
operation);
- fprintf(stderr, "InnoDB: Cannot continue operation.\n");
- fflush(stderr);
+ if (should_exit) {
+ fprintf(stderr, "InnoDB: Cannot continue operation.\n");
- exit(1);
+ fflush(stderr);
+
+ exit(1);
+ }
}
return(FALSE);
}
+/********************************************************************
+Does error handling when a file operation fails. */
+static
+ibool
+os_file_handle_error(
+/*=================*/
+ /* out: TRUE if we should retry the
+ operation */
+ const char* name, /* in: name of a file or NULL */
+ const char* operation)/* in: operation */
+{
+ /* exit in case of unknown error */
+ return(os_file_handle_error_cond_exit(name, operation, TRUE));
+}
+
+/********************************************************************
+Does error handling when a file operation fails. */
+static
+ibool
+os_file_handle_error_no_exit(
+/*=========================*/
+ /* out: TRUE if we should retry the
+ operation */
+ const char* name, /* in: name of a file or NULL */
+ const char* operation)/* in: operation */
+{
+ /* don't exit in case of unknown error */
+ return(os_file_handle_error_cond_exit(name, operation, FALSE));
+}
+
#undef USE_FILE_LOCK
#define USE_FILE_LOCK
#if defined(UNIV_HOTBACKUP) || defined(__WIN__) || defined(__FreeBSD__) || defined(__NETWARE__)
@@ -446,68 +482,6 @@ os_file_lock(
#endif /* USE_FILE_LOCK */
/********************************************************************
-Does error handling when a file operation fails. */
-static
-ibool
-os_file_handle_error_no_exit(
-/*=========================*/
- /* out: TRUE if we should retry the
- operation */
- const char* name, /* in: name of a file or NULL */
- const char* operation)/* in: operation */
-{
- ulint err;
-
- err = os_file_get_last_error(FALSE);
-
- if (err == OS_FILE_DISK_FULL) {
- /* We only print a warning about disk full once */
-
- if (os_has_said_disk_full) {
-
- return(FALSE);
- }
-
- if (name) {
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Encountered a problem with"
- " file %s\n", name);
- }
-
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Disk is full. Try to clean the disk"
- " to free space.\n");
-
- os_has_said_disk_full = TRUE;
-
- fflush(stderr);
-
- return(FALSE);
-
- } else if (err == OS_FILE_AIO_RESOURCES_RESERVED) {
-
- return(TRUE);
-
- } else if (err == OS_FILE_ALREADY_EXISTS
- || err == OS_FILE_PATH_ERROR) {
-
- return(FALSE);
- } else {
- if (name) {
- fprintf(stderr, "InnoDB: File name %s\n", name);
- }
-
- fprintf(stderr, "InnoDB: File operation call: '%s'.\n",
- operation);
- return (FALSE);
- }
-
- return(FALSE); /* not reached */
-}
-
-/********************************************************************
Creates the seek mutexes used in positioned reads and writes. */
void
@@ -1125,6 +1099,51 @@ os_file_create_simple_no_error_handling(
}
/********************************************************************
+Tries to disable OS caching on an opened file descriptor. */
+
+void
+os_file_set_nocache(
+/*================*/
+ int fd, /* in: file descriptor to alter */
+ const char* file_name, /* in: used in the diagnostic message */
+ const char* operation_name) /* in: used in the diagnostic message,
+ we call os_file_set_nocache()
+ immediately after opening or creating
+ a file, so this is either "open" or
+ "create" */
+{
+ /* some versions of Solaris may not have DIRECTIO_ON */
+#if defined(UNIV_SOLARIS) && defined(DIRECTIO_ON)
+ if (directio(fd, DIRECTIO_ON) == -1) {
+ int errno_save;
+ errno_save = (int)errno;
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Failed to set DIRECTIO_ON "
+ "on file %s: %s: %s, continuing anyway\n",
+ file_name, operation_name, strerror(errno_save));
+ }
+#elif defined(O_DIRECT)
+ if (fcntl(fd, F_SETFL, O_DIRECT) == -1) {
+ int errno_save;
+ errno_save = (int)errno;
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Failed to set O_DIRECT "
+ "on file %s: %s: %s, continuing anyway\n",
+ file_name, operation_name, strerror(errno_save));
+ if (errno_save == EINVAL) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: O_DIRECT is known to result in "
+ "'Invalid argument' on Linux on tmpfs, "
+ "see MySQL Bug#26662\n");
+ }
+ }
+#endif
+}
+
+/********************************************************************
Opens an existing file or creates a new. */
os_file_t
@@ -1306,21 +1325,8 @@ try_again:
create_flag = create_flag | O_SYNC;
}
#endif /* O_SYNC */
-#ifdef O_DIRECT
- /* We let O_DIRECT only affect data files */
- if (type != OS_LOG_FILE
- && srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
-# if 0
- fprintf(stderr, "Using O_DIRECT for file %s\n", name);
-# endif
- create_flag = create_flag | O_DIRECT;
- }
-#endif /* O_DIRECT */
- if (create_mode == OS_FILE_CREATE) {
- file = open(name, create_flag, os_innodb_umask);
- } else {
- file = open(name, create_flag);
- }
+
+ file = open(name, create_flag, os_innodb_umask);
if (file == -1) {
*success = FALSE;
@@ -1330,11 +1336,24 @@ try_again:
"create" : "open");
if (retry) {
goto try_again;
+ } else {
+ return(file /* -1 */);
}
+ }
+ /* else */
+
+ *success = TRUE;
+
+ /* We disable OS caching (O_DIRECT) only on data files */
+ if (type != OS_LOG_FILE
+ && srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
+
+ os_file_set_nocache(file, name, mode_str);
+ }
+
#ifdef USE_FILE_LOCK
- } else if (create_mode != OS_FILE_OPEN_RAW
- && os_file_lock(file, name)) {
- *success = FALSE;
+ if (create_mode != OS_FILE_OPEN_RAW && os_file_lock(file, name)) {
+
if (create_mode == OS_FILE_OPEN_RETRY) {
int i;
ut_print_timestamp(stderr);
@@ -1352,12 +1371,12 @@ try_again:
fputs(" InnoDB: Unable to open the first data file\n",
stderr);
}
+
+ *success = FALSE;
close(file);
file = -1;
-#endif
- } else {
- *success = TRUE;
}
+#endif /* USE_FILE_LOCK */
return(file);
#endif /* __WIN__ */