summaryrefslogtreecommitdiff
path: root/innobase
diff options
context:
space:
mode:
authortsmith@siva.hindu.god <>2007-04-18 19:36:22 -0600
committertsmith@siva.hindu.god <>2007-04-18 19:36:22 -0600
commitd232cead7b133488e33fcb5e07abe32fe7fde6e8 (patch)
tree7fd5232164d4d977b7e80c86d7b6ec14cf88bd05 /innobase
parent39496731a20accc694260ff5d156b49914b5c24d (diff)
downloadmariadb-git-d232cead7b133488e33fcb5e07abe32fe7fde6e8.tar.gz
Apply innodb-5.0-ss1405 snapshot
NULL MERGE: this ChangeSet will be null merged into mysql-5.1 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.
Diffstat (limited to 'innobase')
-rw-r--r--innobase/configure.in2
-rw-r--r--innobase/os/os0file.c207
2 files changed, 116 insertions, 93 deletions
diff --git a/innobase/configure.in b/innobase/configure.in
index c56bd8274c4..99c8c91dbf3 100644
--- a/innobase/configure.in
+++ b/innobase/configure.in
@@ -102,6 +102,8 @@ case "$target_os" in
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
osf*)
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
+ *solaris*|*SunOS*)
+ CFLAGS="$CFLAGS -DUNIV_SOLARIS";;
sysv5uw7*)
# Problem when linking on SCO
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c
index 72f1f837fee..7133b28ecb2 100644
--- a/innobase/os/os0file.c
+++ b/innobase/os/os0file.c
@@ -301,7 +301,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) {
@@ -320,15 +320,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;
@@ -357,11 +362,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) {
@@ -373,16 +376,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__)
@@ -425,66 +461,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
@@ -1117,6 +1093,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
@@ -1294,21 +1315,8 @@ try_again:
create_flag = create_flag | O_SYNC;
}
#endif
-#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) {
-
-/* fprintf(stderr, "Using O_DIRECT for file %s\n", name); */
- create_flag = create_flag | O_DIRECT;
- }
-#endif
- 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;
@@ -1318,11 +1326,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);
@@ -1339,12 +1360,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__ */