summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <tsmith@siva.hindu.god>2007-04-18 19:36:22 -0600
committerunknown <tsmith@siva.hindu.god>2007-04-18 19:36:22 -0600
commit726d27ee374750f18e9e50edf437453881d08604 (patch)
tree7fd5232164d4d977b7e80c86d7b6ec14cf88bd05
parent6ff11d70a82c293b8bfba594f0ca744736257c76 (diff)
downloadmariadb-git-726d27ee374750f18e9e50edf437453881d08604.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. innobase/configure.in: Apply innodb-5.0-ss1405 snapshot Revision r1396: branches/5.0: Merge r1395 from trunk: * 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(). innobase/os/os0file.c: Apply innodb-5.0-ss1405 snapshot Revision r1394: branches/5.0: Merge r1391 from trunk: 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() Revision r1396: branches/5.0: Merge r1395 from trunk: * 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(). mysql-test/r/innodb.result: Apply innodb-5.0-ss1405 snapshot Revision r1405: branches/5.0: Merge r1404 from trunk: 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: Apply innodb-5.0-ss1405 snapshot Revision r1405: branches/5.0: Merge r1404 from trunk: 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. sql/ha_innodb.cc: Apply innodb-5.0-ss1405 snapshot Revision r1405: branches/5.0: Merge r1404 from trunk: 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. sql/ha_innodb.h: Apply innodb-5.0-ss1405 snapshot Revision r1405: branches/5.0: Merge r1404 from trunk: 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.
-rw-r--r--innobase/configure.in2
-rw-r--r--innobase/os/os0file.c207
-rw-r--r--mysql-test/r/innodb.result25
-rw-r--r--mysql-test/t/innodb.test20
-rw-r--r--sql/ha_innodb.cc14
-rw-r--r--sql/ha_innodb.h1
6 files changed, 176 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__ */
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 0638152ba42..9f327ca1901 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -2986,3 +2986,28 @@ SELECT * FROM t1;
a
DDD
DROP TABLE t1;
+CREATE TABLE t1 (id int PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB
+AUTO_INCREMENT=42;
+INSERT INTO t1 VALUES (0),(347),(0);
+SELECT * FROM t1;
+id
+42
+347
+348
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL auto_increment,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=349 DEFAULT CHARSET=latin1
+CREATE TABLE t2 (id int PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t2 VALUES(42),(347),(348);
+ALTER TABLE t1 ADD CONSTRAINT t1_t2 FOREIGN KEY (id) REFERENCES t2(id);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL auto_increment,
+ PRIMARY KEY (`id`),
+ CONSTRAINT `t1_t2` FOREIGN KEY (`id`) REFERENCES `t2` (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=349 DEFAULT CHARSET=latin1
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index e762d740d66..f7fa7366101 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -2004,6 +2004,26 @@ INSERT INTO t1 VALUES ('DDD');
SELECT * FROM t1;
DROP TABLE t1;
+#
+# Bug #23313 (AUTO_INCREMENT=# not reported back for InnoDB tables)
+# Bug #21404 (AUTO_INCREMENT value reset when Adding FKEY (or ALTER?))
+#
+
+CREATE TABLE t1 (id int PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB
+AUTO_INCREMENT=42;
+
+INSERT INTO t1 VALUES (0),(347),(0);
+SELECT * FROM t1;
+
+SHOW CREATE TABLE t1;
+
+CREATE TABLE t2 (id int PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t2 VALUES(42),(347),(348);
+ALTER TABLE t1 ADD CONSTRAINT t1_t2 FOREIGN KEY (id) REFERENCES t2(id);
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1,t2;
+
#######################################################################
# #
# Please, DO NOT TOUCH this file as well as the innodb.result file. #
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 217f59d4b7e..14103310b6a 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -4552,6 +4552,20 @@ create_clustered_index_when_no_primary(
}
/*********************************************************************
+Update create_info. Used in SHOW CREATE TABLE et al. */
+
+void
+ha_innobase::update_create_info(
+/*============================*/
+ HA_CREATE_INFO* create_info) /* in/out: create info */
+{
+ if (!(create_info->used_fields & HA_CREATE_USED_AUTO)) {
+ ha_innobase::info(HA_STATUS_AUTO);
+ create_info->auto_increment_value = auto_increment_value;
+ }
+}
+
+/*********************************************************************
Creates a new table to an InnoDB database. */
int
diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h
index 9d18e22cc77..585bc75fa36 100644
--- a/sql/ha_innodb.h
+++ b/sql/ha_innodb.h
@@ -153,6 +153,7 @@ class ha_innobase: public handler
*max_key);
ha_rows estimate_rows_upper_bound();
+ void update_create_info(HA_CREATE_INFO* create_info);
int create(const char *name, register TABLE *form,
HA_CREATE_INFO *create_info);
int delete_all_rows();