diff options
author | tsmith@siva.hindu.god <> | 2007-04-18 19:36:22 -0600 |
---|---|---|
committer | tsmith@siva.hindu.god <> | 2007-04-18 19:36:22 -0600 |
commit | d232cead7b133488e33fcb5e07abe32fe7fde6e8 (patch) | |
tree | 7fd5232164d4d977b7e80c86d7b6ec14cf88bd05 /innobase | |
parent | 39496731a20accc694260ff5d156b49914b5c24d (diff) | |
download | mariadb-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.in | 2 | ||||
-rw-r--r-- | innobase/os/os0file.c | 207 |
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__ */ |